\""
+ }`)))
+ })
+}
diff --git a/cmd/actions.go b/cmd/actions.go
index 10ae6243c3..54b5154cfa 100644
--- a/cmd/actions.go
+++ b/cmd/actions.go
@@ -6,8 +6,8 @@ package cmd
import (
"fmt"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin.go b/cmd/admin.go
index 6c9480e76e..e04a5bc530 100644
--- a/cmd/admin.go
+++ b/cmd/admin.go
@@ -8,12 +8,12 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- repo_module "code.gitea.io/gitea/modules/repository"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ repo_module "forgejo.org/modules/repository"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin_auth.go b/cmd/admin_auth.go
index 4777a92908..b5e0212df7 100644
--- a/cmd/admin_auth.go
+++ b/cmd/admin_auth.go
@@ -9,9 +9,9 @@ import (
"os"
"text/tabwriter"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- auth_service "code.gitea.io/gitea/services/auth"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ auth_service "forgejo.org/services/auth"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin_auth_ldap.go b/cmd/admin_auth_ldap.go
index e3c81809f8..637769b153 100644
--- a/cmd/admin_auth_ldap.go
+++ b/cmd/admin_auth_ldap.go
@@ -8,8 +8,8 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/services/auth/source/ldap"
+ "forgejo.org/models/auth"
+ "forgejo.org/services/auth/source/ldap"
"github.com/urfave/cli/v2"
)
@@ -386,7 +386,7 @@ func (a *authService) addLdapSimpleAuth(c *cli.Context) error {
return a.createAuthSource(ctx, authSource)
}
-// updateLdapBindDn updates a new LDAP (simple auth) authentication source.
+// updateLdapSimpleAuth updates a new LDAP (simple auth) authentication source.
func (a *authService) updateLdapSimpleAuth(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
diff --git a/cmd/admin_auth_ldap_test.go b/cmd/admin_auth_ldap_test.go
index 7791f3a9cc..269af55d96 100644
--- a/cmd/admin_auth_ldap_test.go
+++ b/cmd/admin_auth_ldap_test.go
@@ -7,10 +7,11 @@ import (
"context"
"testing"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/services/auth/source/ldap"
+ "forgejo.org/models/auth"
+ "forgejo.org/services/auth/source/ldap"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
)
@@ -234,7 +235,7 @@ func TestAddLdapBindDn(t *testing.T) {
if c.errMsg != "" {
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
} else {
- assert.NoError(t, err, "case %d: should have no errors", n)
+ require.NoError(t, err, "case %d: should have no errors", n)
assert.Equal(t, c.source, createdAuthSource, "case %d: wrong authSource", n)
}
}
@@ -465,7 +466,7 @@ func TestAddLdapSimpleAuth(t *testing.T) {
if c.errMsg != "" {
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
} else {
- assert.NoError(t, err, "case %d: should have no errors", n)
+ require.NoError(t, err, "case %d: should have no errors", n)
assert.Equal(t, c.authSource, createdAuthSource, "case %d: wrong authSource", n)
}
}
@@ -928,7 +929,7 @@ func TestUpdateLdapBindDn(t *testing.T) {
if c.errMsg != "" {
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
} else {
- assert.NoError(t, err, "case %d: should have no errors", n)
+ require.NoError(t, err, "case %d: should have no errors", n)
assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n)
}
}
@@ -1318,7 +1319,7 @@ func TestUpdateLdapSimpleAuth(t *testing.T) {
if c.errMsg != "" {
assert.EqualError(t, err, c.errMsg, "case %d: error should match", n)
} else {
- assert.NoError(t, err, "case %d: should have no errors", n)
+ require.NoError(t, err, "case %d: should have no errors", n)
assert.Equal(t, c.authSource, updatedAuthSource, "case %d: wrong authSource", n)
}
}
diff --git a/cmd/admin_auth_oauth.go b/cmd/admin_auth_oauth.go
index 8e6239ac33..58238794b8 100644
--- a/cmd/admin_auth_oauth.go
+++ b/cmd/admin_auth_oauth.go
@@ -8,8 +8,8 @@ import (
"fmt"
"net/url"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/services/auth/source/oauth2"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/services/auth/source/oauth2"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin_auth_stmp.go b/cmd/admin_auth_stmp.go
index d724746905..e166cc38cd 100644
--- a/cmd/admin_auth_stmp.go
+++ b/cmd/admin_auth_stmp.go
@@ -7,9 +7,9 @@ import (
"errors"
"strings"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/auth/source/smtp"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/auth/source/smtp"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin_regenerate.go b/cmd/admin_regenerate.go
index 0db505ff9c..4e7f685843 100644
--- a/cmd/admin_regenerate.go
+++ b/cmd/admin_regenerate.go
@@ -4,9 +4,9 @@
package cmd
import (
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/modules/graceful"
- repo_service "code.gitea.io/gitea/services/repository"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/modules/graceful"
+ repo_service "forgejo.org/services/repository"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin_user_change_password.go b/cmd/admin_user_change_password.go
index bd9063a8e4..563ad96afd 100644
--- a/cmd/admin_user_change_password.go
+++ b/cmd/admin_user_change_password.go
@@ -7,11 +7,11 @@ import (
"errors"
"fmt"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/password"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- user_service "code.gitea.io/gitea/services/user"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/password"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ user_service "forgejo.org/services/user"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin_user_create.go b/cmd/admin_user_create.go
index dfc484aeb2..33e61c0753 100644
--- a/cmd/admin_user_create.go
+++ b/cmd/admin_user_create.go
@@ -7,12 +7,12 @@ import (
"errors"
"fmt"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- pwd "code.gitea.io/gitea/modules/auth/password"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ pwd "forgejo.org/modules/auth/password"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
@@ -69,6 +69,10 @@ var microcmdUserCreate = &cli.Command{
}
func runCreateUser(c *cli.Context) error {
+ // this command highly depends on the many setting options (create org, visibility, etc.), so it must have a full setting load first
+ // duplicate setting loading should be safe at the moment, but it should be refactored & improved in the future.
+ setting.LoadSettings()
+
if err := argsSet(c, "email"); err != nil {
return err
}
diff --git a/cmd/admin_user_delete.go b/cmd/admin_user_delete.go
index 520557554a..9a4cc22a77 100644
--- a/cmd/admin_user_delete.go
+++ b/cmd/admin_user_delete.go
@@ -8,9 +8,9 @@ import (
"fmt"
"strings"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/storage"
- user_service "code.gitea.io/gitea/services/user"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/storage"
+ user_service "forgejo.org/services/user"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin_user_generate_access_token.go b/cmd/admin_user_generate_access_token.go
index 6c2c10494e..abb874bd5f 100644
--- a/cmd/admin_user_generate_access_token.go
+++ b/cmd/admin_user_generate_access_token.go
@@ -7,8 +7,8 @@ import (
"errors"
"fmt"
- auth_model "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
+ auth_model "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin_user_list.go b/cmd/admin_user_list.go
index 4c2b26d1df..6044ce7c3f 100644
--- a/cmd/admin_user_list.go
+++ b/cmd/admin_user_list.go
@@ -8,7 +8,7 @@ import (
"os"
"text/tabwriter"
- user_model "code.gitea.io/gitea/models/user"
+ user_model "forgejo.org/models/user"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/admin_user_must_change_password.go b/cmd/admin_user_must_change_password.go
index 2794414259..920f5c7b21 100644
--- a/cmd/admin_user_must_change_password.go
+++ b/cmd/admin_user_must_change_password.go
@@ -7,7 +7,7 @@ import (
"errors"
"fmt"
- user_model "code.gitea.io/gitea/models/user"
+ user_model "forgejo.org/models/user"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/cmd.go b/cmd/cmd.go
index 423dce2674..c887d0ed52 100644
--- a/cmd/cmd.go
+++ b/cmd/cmd.go
@@ -15,10 +15,10 @@ import (
"strings"
"syscall"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/doctor.go b/cmd/doctor.go
index 9957053365..b3420982f5 100644
--- a/cmd/doctor.go
+++ b/cmd/doctor.go
@@ -11,13 +11,13 @@ import (
"strings"
"text/tabwriter"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/migrations"
- migrate_base "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/doctor"
+ "forgejo.org/models/db"
+ "forgejo.org/models/migrations"
+ migrate_base "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/doctor"
"github.com/urfave/cli/v2"
"xorm.io/xorm"
diff --git a/cmd/doctor_convert.go b/cmd/doctor_convert.go
index 190b2fc2ef..06883264a3 100644
--- a/cmd/doctor_convert.go
+++ b/cmd/doctor_convert.go
@@ -6,9 +6,9 @@ package cmd
import (
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/doctor_test.go b/cmd/doctor_test.go
index 3e1ff299c5..bfb4b9d803 100644
--- a/cmd/doctor_test.go
+++ b/cmd/doctor_test.go
@@ -7,10 +7,10 @@ import (
"context"
"testing"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/doctor"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/doctor"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
)
@@ -25,9 +25,9 @@ func TestDoctorRun(t *testing.T) {
app := cli.NewApp()
app.Commands = []*cli.Command{cmdDoctorCheck}
err := app.Run([]string{"./gitea", "check", "--run", "test-check"})
- assert.NoError(t, err)
+ require.NoError(t, err)
err = app.Run([]string{"./gitea", "check", "--run", "no-such"})
- assert.ErrorContains(t, err, `unknown checks: "no-such"`)
+ require.ErrorContains(t, err, `unknown checks: "no-such"`)
err = app.Run([]string{"./gitea", "check", "--run", "test-check,no-such"})
- assert.ErrorContains(t, err, `unknown checks: "no-such"`)
+ require.ErrorContains(t, err, `unknown checks: "no-such"`)
}
diff --git a/cmd/dump.go b/cmd/dump.go
index 0a18adb27d..ac72a2bb18 100644
--- a/cmd/dump.go
+++ b/cmd/dump.go
@@ -13,14 +13,14 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/util"
- "gitea.com/go-chi/session"
+ "code.forgejo.org/go-chi/session"
"github.com/mholt/archiver/v3"
"github.com/urfave/cli/v2"
)
@@ -133,12 +133,12 @@ It can be used for backup and capture Forgejo server image to send to maintainer
&cli.BoolFlag{
Name: "skip-repository",
Aliases: []string{"R"},
- Usage: "Skip the repository dumping",
+ Usage: "Skip repositories",
},
&cli.BoolFlag{
Name: "skip-log",
Aliases: []string{"L"},
- Usage: "Skip the log dumping",
+ Usage: "Skip logs",
},
&cli.BoolFlag{
Name: "skip-custom-dir",
@@ -160,6 +160,10 @@ It can be used for backup and capture Forgejo server image to send to maintainer
Name: "skip-index",
Usage: "Skip bleve index data",
},
+ &cli.BoolFlag{
+ Name: "skip-repo-archives",
+ Usage: "Skip repository archives",
+ },
&cli.GenericFlag{
Name: "type",
Value: outputTypeEnum,
@@ -233,7 +237,7 @@ func runDump(ctx *cli.Context) error {
if file == nil {
file, err = os.Create(fileName)
if err != nil {
- fatal("Unable to open %s: %v", fileName, err)
+ fatal("Failed to open %s: %v", fileName, err)
}
}
defer file.Close()
@@ -250,7 +254,7 @@ func runDump(ctx *cli.Context) error {
iface, err = archiver.ByExtension(fileName)
}
if err != nil {
- fatal("Unable to get archiver for extension: %v", err)
+ fatal("Failed to get archiver for extension: %v", err)
}
w, _ := iface.(archiver.Writer)
@@ -260,7 +264,7 @@ func runDump(ctx *cli.Context) error {
defer w.Close()
if ctx.IsSet("skip-repository") && ctx.Bool("skip-repository") {
- log.Info("Skip dumping local repositories")
+ log.Info("Skipping local repositories")
} else {
log.Info("Dumping local repositories... %s", setting.RepoRootPath)
if err := addRecursiveExclude(w, "repos", setting.RepoRootPath, []string{absFileName}, verbose); err != nil {
@@ -268,9 +272,9 @@ func runDump(ctx *cli.Context) error {
}
if ctx.IsSet("skip-lfs-data") && ctx.Bool("skip-lfs-data") {
- log.Info("Skip dumping LFS data")
+ log.Info("Skipping LFS data")
} else if !setting.LFS.StartServer {
- log.Info("LFS isn't enabled. Skip dumping LFS data")
+ log.Info("LFS not enabled - skipping")
} else if err := storage.LFS.IterateObjects("", func(objPath string, object storage.Object) error {
info, err := object.Stat()
if err != nil {
@@ -295,7 +299,7 @@ func runDump(ctx *cli.Context) error {
defer func() {
_ = dbDump.Close()
if err := util.Remove(dbDump.Name()); err != nil {
- log.Warn("Unable to remove temporary file: %s: Error: %v", dbDump.Name(), err)
+ log.Warn("Failed to remove temporary file: %s: Error: %v", dbDump.Name(), err)
}
}()
@@ -331,16 +335,16 @@ func runDump(ctx *cli.Context) error {
fatal("Failed to include custom: %v", err)
}
} else {
- log.Info("Custom dir %s is inside data dir %s, skipped", setting.CustomPath, setting.AppDataPath)
+ log.Info("Custom dir %s is inside data dir %s, skipping", setting.CustomPath, setting.AppDataPath)
}
} else {
- log.Info("Custom dir %s doesn't exist, skipped", setting.CustomPath)
+ log.Info("Custom dir %s does not exist, skipping", setting.CustomPath)
}
}
isExist, err := util.IsExist(setting.AppDataPath)
if err != nil {
- log.Error("Unable to check if %s exists. Error: %v", setting.AppDataPath, err)
+ log.Error("Failed to check if %s exists: %v", setting.AppDataPath, err)
}
if isExist {
log.Info("Packing data directory...%s", setting.AppDataPath)
@@ -355,10 +359,16 @@ func runDump(ctx *cli.Context) error {
}
if ctx.IsSet("skip-index") && ctx.Bool("skip-index") {
+ log.Info("Skipping bleve index data")
excludes = append(excludes, setting.Indexer.RepoPath)
excludes = append(excludes, setting.Indexer.IssuePath)
}
+ if ctx.IsSet("skip-repo-archives") && ctx.Bool("skip-repo-archives") {
+ log.Info("Skipping repository archives data")
+ excludes = append(excludes, setting.RepoArchive.Storage.Path)
+ }
+
excludes = append(excludes, setting.RepoRootPath)
excludes = append(excludes, setting.LFS.Storage.Path)
excludes = append(excludes, setting.Attachment.Storage.Path)
@@ -371,7 +381,7 @@ func runDump(ctx *cli.Context) error {
}
if ctx.IsSet("skip-attachment-data") && ctx.Bool("skip-attachment-data") {
- log.Info("Skip dumping attachment data")
+ log.Info("Skipping attachment data")
} else if err := storage.Attachments.IterateObjects("", func(objPath string, object storage.Object) error {
info, err := object.Stat()
if err != nil {
@@ -384,9 +394,9 @@ func runDump(ctx *cli.Context) error {
}
if ctx.IsSet("skip-package-data") && ctx.Bool("skip-package-data") {
- log.Info("Skip dumping package data")
+ log.Info("Skipping package data")
} else if !setting.Packages.Enabled {
- log.Info("Packages isn't enabled. Skip dumping package data")
+ log.Info("Package registry not enabled - skipping")
} else if err := storage.Packages.IterateObjects("", func(objPath string, object storage.Object) error {
info, err := object.Stat()
if err != nil {
@@ -402,11 +412,11 @@ func runDump(ctx *cli.Context) error {
// ensuring that it's clear the dump is skipped whether the directory's initialized
// yet or not.
if ctx.IsSet("skip-log") && ctx.Bool("skip-log") {
- log.Info("Skip dumping log files")
+ log.Info("Skipping log files")
} else {
isExist, err := util.IsExist(setting.Log.RootPath)
if err != nil {
- log.Error("Unable to check if %s exists. Error: %v", setting.Log.RootPath, err)
+ log.Error("Failed to check if %s exists: %v", setting.Log.RootPath, err)
}
if isExist {
if err := addRecursiveExclude(w, "log", setting.Log.RootPath, []string{absFileName}, verbose); err != nil {
@@ -456,7 +466,7 @@ func addRecursiveExclude(w archiver.Writer, insidePath, absPath string, excludeA
currentInsidePath := path.Join(insidePath, file.Name())
if util.SliceContainsString(excludeAbsPath, currentAbsPath) {
- log.Debug("Skipping %q because matched an excluded path.", currentAbsPath)
+ log.Debug("Skipping %q (matched an excluded path)", currentAbsPath)
continue
}
diff --git a/cmd/dump_repo.go b/cmd/dump_repo.go
index 3a24cf6c5f..197445f908 100644
--- a/cmd/dump_repo.go
+++ b/cmd/dump_repo.go
@@ -10,14 +10,14 @@ import (
"os"
"strings"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/migrations"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/migrations"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/dump_test.go b/cmd/dump_test.go
index d33619bab8..459386318f 100644
--- a/cmd/dump_test.go
+++ b/cmd/dump_test.go
@@ -10,6 +10,7 @@ import (
"github.com/mholt/archiver/v3"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
type mockArchiver struct {
@@ -35,20 +36,20 @@ func TestAddRecursiveExclude(t *testing.T) {
archiver := &mockArchiver{}
err := addRecursiveExclude(archiver, "", dir, []string{}, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, archiver.addedFiles)
})
t.Run("Single file", func(t *testing.T) {
dir := t.TempDir()
err := os.WriteFile(dir+"/example", nil, 0o666)
- assert.NoError(t, err)
+ require.NoError(t, err)
t.Run("No exclude", func(t *testing.T) {
archiver := &mockArchiver{}
err = addRecursiveExclude(archiver, "", dir, nil, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, archiver.addedFiles, 1)
assert.Contains(t, archiver.addedFiles, "example")
})
@@ -57,7 +58,7 @@ func TestAddRecursiveExclude(t *testing.T) {
archiver := &mockArchiver{}
err = addRecursiveExclude(archiver, "", dir, []string{dir + "/example"}, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, archiver.addedFiles)
})
})
@@ -65,17 +66,17 @@ func TestAddRecursiveExclude(t *testing.T) {
t.Run("File inside directory", func(t *testing.T) {
dir := t.TempDir()
err := os.MkdirAll(dir+"/deep/nested/folder", 0o750)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = os.WriteFile(dir+"/deep/nested/folder/example", nil, 0o666)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = os.WriteFile(dir+"/deep/nested/folder/another-file", nil, 0o666)
- assert.NoError(t, err)
+ require.NoError(t, err)
t.Run("No exclude", func(t *testing.T) {
archiver := &mockArchiver{}
err = addRecursiveExclude(archiver, "", dir, nil, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, archiver.addedFiles, 5)
assert.Contains(t, archiver.addedFiles, "deep")
assert.Contains(t, archiver.addedFiles, "deep/nested")
@@ -88,7 +89,7 @@ func TestAddRecursiveExclude(t *testing.T) {
archiver := &mockArchiver{}
err = addRecursiveExclude(archiver, "", dir, []string{dir + "/deep"}, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, archiver.addedFiles)
})
@@ -96,7 +97,7 @@ func TestAddRecursiveExclude(t *testing.T) {
archiver := &mockArchiver{}
err = addRecursiveExclude(archiver, "", dir, []string{dir + "/deep/nested/folder"}, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, archiver.addedFiles, 2)
assert.Contains(t, archiver.addedFiles, "deep")
assert.Contains(t, archiver.addedFiles, "deep/nested")
@@ -106,7 +107,7 @@ func TestAddRecursiveExclude(t *testing.T) {
archiver := &mockArchiver{}
err = addRecursiveExclude(archiver, "", dir, []string{dir + "/deep/nested/folder/example"}, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, archiver.addedFiles, 4)
assert.Contains(t, archiver.addedFiles, "deep")
assert.Contains(t, archiver.addedFiles, "deep/nested")
diff --git a/cmd/embedded.go b/cmd/embedded.go
index 9f03f7be7c..c8b9d13d25 100644
--- a/cmd/embedded.go
+++ b/cmd/embedded.go
@@ -10,13 +10,13 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/modules/assetfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/options"
- "code.gitea.io/gitea/modules/public"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/assetfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/options"
+ "forgejo.org/modules/public"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/util"
"github.com/gobwas/glob"
"github.com/urfave/cli/v2"
diff --git a/cmd/forgejo/actions.go b/cmd/forgejo/actions.go
index 70f9452cb8..dbe7398bcf 100644
--- a/cmd/forgejo/actions.go
+++ b/cmd/forgejo/actions.go
@@ -11,10 +11,10 @@ import (
"os"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
- private_routers "code.gitea.io/gitea/routers/private"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
+ private_routers "forgejo.org/routers/private"
"github.com/urfave/cli/v2"
)
@@ -86,6 +86,11 @@ func SubcmdActionsRegister(ctx context.Context) *cli.Command {
Value: "",
Usage: "comma separated list of labels supported by the runner (e.g. docker,ubuntu-latest,self-hosted) (not required since v1.21)",
},
+ &cli.BoolFlag{
+ Name: "keep-labels",
+ Value: false,
+ Usage: "do not affect the labels when updating an existing runner",
+ },
&cli.StringFlag{
Name: "name",
Value: "runner",
@@ -133,6 +138,17 @@ func validateSecret(secret string) error {
return nil
}
+func getLabels(cliCtx *cli.Context) (*[]string, error) {
+ if !cliCtx.Bool("keep-labels") {
+ lblValue := strings.Split(cliCtx.String("labels"), ",")
+ return &lblValue, nil
+ }
+ if cliCtx.String("labels") != "" {
+ return nil, fmt.Errorf("--labels and --keep-labels should not be used together")
+ }
+ return nil, nil
+}
+
func RunRegister(ctx context.Context, cliCtx *cli.Context) error {
var cancel context.CancelFunc
if !ContextGetNoInit(ctx) {
@@ -153,9 +169,12 @@ func RunRegister(ctx context.Context, cliCtx *cli.Context) error {
return err
}
scope := cliCtx.String("scope")
- labels := cliCtx.String("labels")
name := cliCtx.String("name")
version := cliCtx.String("version")
+ labels, err := getLabels(cliCtx)
+ if err != nil {
+ return err
+ }
//
// There are two kinds of tokens
@@ -179,7 +198,7 @@ func RunRegister(ctx context.Context, cliCtx *cli.Context) error {
return err
}
- runner, err := actions_model.RegisterRunner(ctx, owner, repo, secret, strings.Split(labels, ","), name, version)
+ runner, err := actions_model.RegisterRunner(ctx, owner, repo, secret, labels, name, version)
if err != nil {
return fmt.Errorf("error while registering runner: %v", err)
}
diff --git a/cmd/forgejo/actions_test.go b/cmd/forgejo/actions_test.go
new file mode 100644
index 0000000000..b58f52184c
--- /dev/null
+++ b/cmd/forgejo/actions_test.go
@@ -0,0 +1,88 @@
+// Copyright The Forgejo Authors.
+// SPDX-License-Identifier: MIT
+
+package forgejo
+
+import (
+ "fmt"
+ "testing"
+
+ "forgejo.org/services/context"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "github.com/urfave/cli/v2"
+)
+
+func TestActions_getLabels(t *testing.T) {
+ type testCase struct {
+ args []string
+ hasLabels bool
+ hasError bool
+ labels []string
+ }
+ type resultType struct {
+ labels *[]string
+ err error
+ }
+
+ cases := []testCase{
+ {
+ args: []string{"x"},
+ hasLabels: true,
+ hasError: false,
+ labels: []string{""},
+ }, {
+ args: []string{"x", "--labels", "a,b"},
+ hasLabels: true,
+ hasError: false,
+ labels: []string{"a", "b"},
+ }, {
+ args: []string{"x", "--keep-labels"},
+ hasLabels: false,
+ hasError: false,
+ }, {
+ args: []string{"x", "--keep-labels", "--labels", "a,b"},
+ hasLabels: false,
+ hasError: true,
+ }, {
+ // this edge-case exists because that's what actually happens
+ // when no '--labels ...' options are present
+ args: []string{"x", "--keep-labels", "--labels", ""},
+ hasLabels: false,
+ hasError: false,
+ },
+ }
+
+ flags := SubcmdActionsRegister(context.Context{}).Flags
+ for _, c := range cases {
+ t.Run(fmt.Sprintf("args: %v", c.args), func(t *testing.T) {
+ // Create a copy of command to test
+ var result *resultType
+ app := cli.NewApp()
+ app.Flags = flags
+ app.Action = func(ctx *cli.Context) error {
+ labels, err := getLabels(ctx)
+ result = &resultType{labels, err}
+ return nil
+ }
+
+ // Run it
+ _ = app.Run(c.args)
+
+ // Test the results
+ require.NotNil(t, result)
+ if c.hasLabels {
+ assert.NotNil(t, result.labels)
+ assert.Equal(t, c.labels, *result.labels)
+ } else {
+ assert.Nil(t, result.labels)
+ }
+ if c.hasError {
+ require.Error(t, result.err)
+ } else {
+ assert.NoError(t, result.err)
+ }
+ })
+ }
+}
diff --git a/cmd/forgejo/f3.go b/cmd/forgejo/f3.go
index 5a0d0ac036..bfd14cd1a4 100644
--- a/cmd/forgejo/f3.go
+++ b/cmd/forgejo/f3.go
@@ -8,14 +8,14 @@ import (
"context"
"errors"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/services/f3/util"
+ "forgejo.org/models"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/services/f3/util"
- _ "code.gitea.io/gitea/services/f3/driver" // register the driver
+ _ "forgejo.org/services/f3/driver" // register the driver
f3_cmd "code.forgejo.org/f3/gof3/v3/cmd"
f3_logger "code.forgejo.org/f3/gof3/v3/logger"
diff --git a/cmd/forgejo/forgejo.go b/cmd/forgejo/forgejo.go
index 1b7e16ca8f..3b95c80991 100644
--- a/cmd/forgejo/forgejo.go
+++ b/cmd/forgejo/forgejo.go
@@ -11,10 +11,10 @@ import (
"os/signal"
"syscall"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/generate.go b/cmd/generate.go
index 806946244b..8d3c221ec5 100644
--- a/cmd/generate.go
+++ b/cmd/generate.go
@@ -8,7 +8,7 @@ import (
"fmt"
"os"
- "code.gitea.io/gitea/modules/generate"
+ "forgejo.org/modules/generate"
"github.com/mattn/go-isatty"
"github.com/urfave/cli/v2"
diff --git a/cmd/hook.go b/cmd/hook.go
index f8184f9697..1630c41edd 100644
--- a/cmd/hook.go
+++ b/cmd/hook.go
@@ -14,11 +14,12 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/git/pushoptions"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
@@ -192,7 +193,7 @@ Forgejo or set your environment appropriately.`, "")
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
- GitPushOptions: pushOptions(),
+ GitPushOptions: pushoptions.New().ReadEnv().Map(),
PullRequestID: prID,
DeployKeyID: deployKeyID,
ActionPerm: int(actionPerm),
@@ -321,7 +322,8 @@ func runHookUpdate(c *cli.Context) error {
return fail(ctx, fmt.Sprintf("The deletion of %s is skipped as it's an internal reference.", refFullName), "")
}
- return nil
+ // If the new comment isn't empty it means modification.
+ return fail(ctx, fmt.Sprintf("The modification of %s is skipped as it's an internal reference.", refFullName), "")
}
func runHookPostReceive(c *cli.Context) error {
@@ -375,7 +377,7 @@ Forgejo or set your environment appropriately.`, "")
GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
- GitPushOptions: pushOptions(),
+ GitPushOptions: pushoptions.New().ReadEnv().Map(),
PullRequestID: prID,
PushTrigger: repo_module.PushTrigger(os.Getenv(repo_module.EnvPushTrigger)),
}
@@ -488,21 +490,6 @@ func hookPrintResults(results []private.HookPostReceiveBranchResult) {
}
}
-func pushOptions() map[string]string {
- opts := make(map[string]string)
- if pushCount, err := strconv.Atoi(os.Getenv(private.GitPushOptionCount)); err == nil {
- for idx := 0; idx < pushCount; idx++ {
- opt := os.Getenv(fmt.Sprintf("GIT_PUSH_OPTION_%d", idx))
- key, value, found := strings.Cut(opt, "=")
- if !found {
- value = "true"
- }
- opts[key] = value
- }
- }
- return opts
-}
-
func runHookProcReceive(c *cli.Context) error {
ctx, cancel := installSignals()
defer cancel()
@@ -549,14 +536,14 @@ Forgejo or set your environment appropriately.`, "")
index := bytes.IndexByte(rs.Data, byte(0))
if index >= len(rs.Data) {
- return fail(ctx, "Protocol: format error", "pkt-line: format error "+fmt.Sprint(rs.Data))
+ return fail(ctx, "Protocol: format error", "pkt-line: format error %s", rs.Data)
}
if index < 0 {
if len(rs.Data) == 10 && rs.Data[9] == '\n' {
index = 9
} else {
- return fail(ctx, "Protocol: format error", "pkt-line: format error "+fmt.Sprint(rs.Data))
+ return fail(ctx, "Protocol: format error", "pkt-line: format error %s", rs.Data)
}
}
@@ -627,6 +614,7 @@ Forgejo or set your environment appropriately.`, "")
hookOptions.GitPushOptions = make(map[string]string)
if hasPushOptions {
+ pushOptions := pushoptions.NewFromMap(&hookOptions.GitPushOptions)
for {
rs, err = readPktLine(ctx, reader, pktLineTypeUnknown)
if err != nil {
@@ -636,12 +624,7 @@ Forgejo or set your environment appropriately.`, "")
if rs.Type == pktLineTypeFlush {
break
}
-
- key, value, found := strings.Cut(string(rs.Data), "=")
- if !found {
- value = "true"
- }
- hookOptions.GitPushOptions[key] = value
+ pushOptions.Parse(string(rs.Data))
}
}
diff --git a/cmd/hook_test.go b/cmd/hook_test.go
index 91731f77c0..89bd3cf737 100644
--- a/cmd/hook_test.go
+++ b/cmd/hook_test.go
@@ -6,7 +6,6 @@ package cmd
import (
"bufio"
"bytes"
- "context"
"io"
"net/http"
"net/http/httptest"
@@ -15,9 +14,8 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -43,72 +41,72 @@ func captureOutput(t *testing.T, stdFD *os.File) (finish func() (output string))
}
func TestPktLine(t *testing.T) {
- ctx := context.Background()
+ ctx := t.Context()
t.Run("Read", func(t *testing.T) {
s := strings.NewReader("0000")
r := bufio.NewReader(s)
result, err := readPktLine(ctx, r, pktLineTypeFlush)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, pktLineTypeFlush, result.Type)
s = strings.NewReader("0006a\n")
r = bufio.NewReader(s)
result, err = readPktLine(ctx, r, pktLineTypeData)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, pktLineTypeData, result.Type)
assert.Equal(t, []byte("a\n"), result.Data)
s = strings.NewReader("0004")
r = bufio.NewReader(s)
result, err = readPktLine(ctx, r, pktLineTypeData)
- assert.Error(t, err)
+ require.Error(t, err)
assert.Nil(t, result)
data := strings.Repeat("x", 65516)
r = bufio.NewReader(strings.NewReader("fff0" + data))
result, err = readPktLine(ctx, r, pktLineTypeData)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, pktLineTypeData, result.Type)
assert.Equal(t, []byte(data), result.Data)
r = bufio.NewReader(strings.NewReader("fff1a"))
result, err = readPktLine(ctx, r, pktLineTypeData)
- assert.Error(t, err)
+ require.Error(t, err)
assert.Nil(t, result)
})
t.Run("Write", func(t *testing.T) {
w := bytes.NewBuffer([]byte{})
err := writeFlushPktLine(ctx, w)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("0000"), w.Bytes())
w.Reset()
err = writeDataPktLine(ctx, w, []byte("a\nb"))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("0007a\nb"), w.Bytes())
w.Reset()
data := bytes.Repeat([]byte{0x05}, 288)
err = writeDataPktLine(ctx, w, data)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, append([]byte("0124"), data...), w.Bytes())
w.Reset()
err = writeDataPktLine(ctx, w, nil)
- assert.Error(t, err)
+ require.Error(t, err)
assert.Empty(t, w.Bytes())
w.Reset()
data = bytes.Repeat([]byte{0x64}, 65516)
err = writeDataPktLine(ctx, w, data)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, append([]byte("fff0"), data...), w.Bytes())
w.Reset()
err = writeDataPktLine(ctx, w, bytes.Repeat([]byte{0x64}, 65516+1))
- assert.Error(t, err)
+ require.Error(t, err)
assert.Empty(t, w.Bytes())
})
}
@@ -118,7 +116,7 @@ func TestDelayWriter(t *testing.T) {
defer test.MockVariableValue(&setting.InternalToken, "Random")()
defer test.MockVariableValue(&setting.InstallLock, true)()
defer test.MockVariableValue(&setting.Git.VerbosePush, true)()
- require.NoError(t, os.Setenv("SSH_ORIGINAL_COMMAND", "true"))
+ t.Setenv("SSH_ORIGINAL_COMMAND", "true")
// Setup the Stdin.
f, err := os.OpenFile(t.TempDir()+"/stdin", os.O_RDWR|os.O_CREATE|os.O_EXCL, 0o666)
@@ -164,20 +162,6 @@ func TestDelayWriter(t *testing.T) {
})
}
-func TestPushOptions(t *testing.T) {
- require.NoError(t, os.Setenv(private.GitPushOptionCount, "3"))
- require.NoError(t, os.Setenv("GIT_PUSH_OPTION_0", "force-push"))
- require.NoError(t, os.Setenv("GIT_PUSH_OPTION_1", "option=value"))
- require.NoError(t, os.Setenv("GIT_PUSH_OPTION_2", "option-double=another=value"))
- require.NoError(t, os.Setenv("GIT_PUSH_OPTION_3", "not=valid"))
-
- assert.Equal(t, map[string]string{
- "force-push": "true",
- "option": "value",
- "option-double": "another=value",
- }, pushOptions())
-}
-
func TestRunHookUpdate(t *testing.T) {
app := cli.NewApp()
app.Commands = []*cli.Command{subcmdHookUpdate}
@@ -189,23 +173,30 @@ func TestRunHookUpdate(t *testing.T) {
err := app.Run([]string{"./forgejo", "update", "refs/pull/1/head", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000000"})
out := finish()
- assert.Error(t, err)
+ require.Error(t, err)
assert.Contains(t, out, "The deletion of refs/pull/1/head is skipped as it's an internal reference.")
})
t.Run("Update of internal reference", func(t *testing.T) {
+ defer test.MockVariableValue(&cli.OsExiter, func(code int) {})()
+ defer test.MockVariableValue(&setting.IsProd, false)()
+ finish := captureOutput(t, os.Stderr)
+
err := app.Run([]string{"./forgejo", "update", "refs/pull/1/head", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000001"})
- assert.NoError(t, err)
+ out := finish()
+ require.Error(t, err)
+
+ assert.Contains(t, out, "The modification of refs/pull/1/head is skipped as it's an internal reference.")
})
t.Run("Removal of branch", func(t *testing.T) {
err := app.Run([]string{"./forgejo", "update", "refs/head/main", "0a51ae26bc73c47e2f754560c40904cf14ed51a9", "0000000000000000000000000000000000000000"})
- assert.NoError(t, err)
+ require.NoError(t, err)
})
t.Run("Not enough arguments", func(t *testing.T) {
err := app.Run([]string{"./forgejo", "update"})
- assert.NoError(t, err)
+ require.NoError(t, err)
})
}
diff --git a/cmd/keys.go b/cmd/keys.go
index 81425a5722..b12daee1bc 100644
--- a/cmd/keys.go
+++ b/cmd/keys.go
@@ -8,8 +8,8 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/mailer.go b/cmd/mailer.go
index 0c5f2c8c8d..cddebd6d36 100644
--- a/cmd/mailer.go
+++ b/cmd/mailer.go
@@ -6,8 +6,8 @@ package cmd
import (
"fmt"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/main.go b/cmd/main.go
index b48a6143d7..5f48814cd0 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -10,9 +10,9 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/cmd/forgejo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/cmd/forgejo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
@@ -206,6 +206,7 @@ func innerNewMainApp(version, versionExtra string, subCmdsStandaloneArgs, subCmd
app.Commands = append(app.Commands, subCmdWithConfig...)
app.Commands = append(app.Commands, subCmdStandalone...)
+ setting.InitGiteaEnvVars()
return app
}
diff --git a/cmd/main_test.go b/cmd/main_test.go
index a916c61f85..5e0b36d028 100644
--- a/cmd/main_test.go
+++ b/cmd/main_test.go
@@ -6,16 +6,16 @@ package cmd
import (
"fmt"
"io"
- "os"
"path/filepath"
"strings"
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"github.com/urfave/cli/v2"
)
@@ -113,65 +113,45 @@ func TestCliCmd(t *testing.T) {
_, _ = fmt.Fprint(ctx.App.Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
return nil
})
- var envBackup []string
- for _, s := range os.Environ() {
- if strings.HasPrefix(s, "GITEA_") && strings.Contains(s, "=") {
- envBackup = append(envBackup, s)
- }
- }
- clearGiteaEnv := func() {
- for _, s := range os.Environ() {
- if strings.HasPrefix(s, "GITEA_") {
- _ = os.Unsetenv(s)
- }
- }
- }
- defer func() {
- clearGiteaEnv()
- for _, s := range envBackup {
- k, v, _ := strings.Cut(s, "=")
- _ = os.Setenv(k, v)
- }
- }()
-
for _, c := range cases {
- clearGiteaEnv()
- for k, v := range c.env {
- _ = os.Setenv(k, v)
- }
- args := strings.Split(c.cmd, " ") // for test only, "split" is good enough
- r, err := runTestApp(app, args...)
- assert.NoError(t, err, c.cmd)
- assert.NotEmpty(t, c.exp, c.cmd)
- assert.Contains(t, r.Stdout, c.exp, c.cmd)
+ t.Run(c.cmd, func(t *testing.T) {
+ for k, v := range c.env {
+ t.Setenv(k, v)
+ }
+ args := strings.Split(c.cmd, " ") // for test only, "split" is good enough
+ r, err := runTestApp(app, args...)
+ require.NoError(t, err, c.cmd)
+ assert.NotEmpty(t, c.exp, c.cmd)
+ assert.Contains(t, r.Stdout, c.exp, c.cmd)
+ })
}
}
func TestCliCmdError(t *testing.T) {
app := newTestApp(func(ctx *cli.Context) error { return fmt.Errorf("normal error") })
r, err := runTestApp(app, "./gitea", "test-cmd")
- assert.Error(t, err)
+ require.Error(t, err)
assert.Equal(t, 1, r.ExitCode)
assert.Equal(t, "", r.Stdout)
assert.Equal(t, "Command error: normal error\n", r.Stderr)
app = newTestApp(func(ctx *cli.Context) error { return cli.Exit("exit error", 2) })
r, err = runTestApp(app, "./gitea", "test-cmd")
- assert.Error(t, err)
+ require.Error(t, err)
assert.Equal(t, 2, r.ExitCode)
assert.Equal(t, "", r.Stdout)
assert.Equal(t, "exit error\n", r.Stderr)
app = newTestApp(func(ctx *cli.Context) error { return nil })
r, err = runTestApp(app, "./gitea", "test-cmd", "--no-such")
- assert.Error(t, err)
+ require.Error(t, err)
assert.Equal(t, 1, r.ExitCode)
assert.Equal(t, "Incorrect Usage: flag provided but not defined: -no-such\n\n", r.Stdout)
assert.Equal(t, "", r.Stderr) // the cli package's strange behavior, the error message is not in stderr ....
app = newTestApp(func(ctx *cli.Context) error { return nil })
r, err = runTestApp(app, "./gitea", "test-cmd")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, -1, r.ExitCode) // the cli.OsExiter is not called
assert.Equal(t, "", r.Stdout)
assert.Equal(t, "", r.Stderr)
diff --git a/cmd/manager.go b/cmd/manager.go
index b74771e53d..0cb1e60f73 100644
--- a/cmd/manager.go
+++ b/cmd/manager.go
@@ -7,7 +7,7 @@ import (
"os"
"time"
- "code.gitea.io/gitea/modules/private"
+ "forgejo.org/modules/private"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/manager_logging.go b/cmd/manager_logging.go
index 6049b00d5e..ac2c1eb418 100644
--- a/cmd/manager_logging.go
+++ b/cmd/manager_logging.go
@@ -8,8 +8,8 @@ import (
"fmt"
"os"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/migrate.go b/cmd/migrate.go
index 4e4dd45af3..ab291cfb66 100644
--- a/cmd/migrate.go
+++ b/cmd/migrate.go
@@ -6,10 +6,10 @@ package cmd
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/migrations"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/models/migrations"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
@@ -18,7 +18,7 @@ import (
var CmdMigrate = &cli.Command{
Name: "migrate",
Usage: "Migrate the database",
- Description: "This is a command for migrating the database, so that you can run gitea admin create-user before starting the server.",
+ Description: "This is a command for migrating the database, so that you can run 'forgejo admin user create' before starting the server.",
Action: runMigrate,
}
diff --git a/cmd/migrate_storage.go b/cmd/migrate_storage.go
index 3a69b555e0..1b839e7169 100644
--- a/cmd/migrate_storage.go
+++ b/cmd/migrate_storage.go
@@ -10,17 +10,17 @@ import (
"io/fs"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/migrations"
- packages_model "code.gitea.io/gitea/models/packages"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/migrations"
+ packages_model "forgejo.org/models/packages"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/migrate_storage_test.go b/cmd/migrate_storage_test.go
index fa7067f97b..28af63f4c8 100644
--- a/cmd/migrate_storage_test.go
+++ b/cmd/migrate_storage_test.go
@@ -4,22 +4,21 @@
package cmd
import (
- "context"
"io"
"os"
"strings"
"testing"
- "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- packages_module "code.gitea.io/gitea/modules/packages"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/test"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/models/packages"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ packages_module "forgejo.org/modules/packages"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/test"
+ packages_service "forgejo.org/services/packages"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -31,7 +30,7 @@ func createLocalStorage(t *testing.T) (storage.ObjectStorage, string) {
p := t.TempDir()
storage, err := storage.NewLocalStorage(
- context.Background(),
+ t.Context(),
&setting.Storage{
Path: p,
})
@@ -41,13 +40,13 @@ func createLocalStorage(t *testing.T) (storage.ObjectStorage, string) {
}
func TestMigratePackages(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
creator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
content := "package main\n\nfunc main() {\nfmt.Println(\"hi\")\n}\n"
buf, err := packages_module.CreateHashedBufferFromReaderWithSize(strings.NewReader(content), 1024)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer buf.Close()
v, f, err := packages_service.CreatePackageAndAddFile(db.DefaultContext, &packages_service.PackageCreationInfo{
@@ -68,30 +67,30 @@ func TestMigratePackages(t *testing.T) {
Data: buf,
IsLead: true,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, v)
assert.NotNil(t, f)
- ctx := context.Background()
+ ctx := t.Context()
dstStorage, p := createLocalStorage(t)
err = migratePackages(ctx, dstStorage)
- assert.NoError(t, err)
+ require.NoError(t, err)
entries, err := os.ReadDir(p)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, entries, 2)
assert.EqualValues(t, "01", entries[0].Name())
assert.EqualValues(t, "tmp", entries[1].Name())
}
func TestMigrateActionsArtifacts(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
srcStorage, _ := createLocalStorage(t)
defer test.MockVariableValue(&storage.ActionsArtifacts, srcStorage)()
- id := int64(0)
+ id := int64(42)
addArtifact := func(storagePath string, status actions.ArtifactStatus) {
id++
@@ -118,17 +117,17 @@ func TestMigrateActionsArtifacts(t *testing.T) {
dstStorage, _ := createLocalStorage(t)
- assert.NoError(t, migrateActionsArtifacts(db.DefaultContext, dstStorage))
+ require.NoError(t, migrateActionsArtifacts(db.DefaultContext, dstStorage))
object, err := dstStorage.Open(exists)
- assert.NoError(t, err)
+ require.NoError(t, err)
buf, err := io.ReadAll(object)
require.NoError(t, err)
assert.Equal(t, exists, string(buf))
_, err = dstStorage.Stat(expired)
- assert.Error(t, err)
+ require.Error(t, err)
_, err = dstStorage.Stat(notFound)
- assert.Error(t, err)
+ require.Error(t, err)
}
diff --git a/cmd/restore_repo.go b/cmd/restore_repo.go
index 37b32aa304..1e53ce26ba 100644
--- a/cmd/restore_repo.go
+++ b/cmd/restore_repo.go
@@ -6,8 +6,8 @@ package cmd
import (
"strings"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
diff --git a/cmd/serv.go b/cmd/serv.go
index 0e3006b36b..e20c885a94 100644
--- a/cmd/serv.go
+++ b/cmd/serv.go
@@ -18,18 +18,18 @@ import (
"time"
"unicode"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/pprof"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/process"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/lfs"
+ asymkey_model "forgejo.org/models/asymkey"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/perm"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/pprof"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/process"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/lfs"
"github.com/golang-jwt/jwt/v5"
"github.com/kballard/go-shellquote"
@@ -38,6 +38,7 @@ import (
const (
lfsAuthenticateVerb = "git-lfs-authenticate"
+ gitAnnexShellVerb = "git-annex-shell"
)
// CmdServ represents the available serv sub-command.
@@ -79,6 +80,7 @@ var (
"git-upload-archive": perm.AccessModeRead,
"git-receive-pack": perm.AccessModeWrite,
lfsAuthenticateVerb: perm.AccessModeNone,
+ gitAnnexShellVerb: perm.AccessModeRead, // annex permissions are enforced by GIT_ANNEX_SHELL_READONLY, rather than the Gitea API, but read permissions are required at a minimum
}
alphaDashDotPattern = regexp.MustCompile(`[^\w-\.]`)
)
@@ -147,6 +149,12 @@ func runServ(c *cli.Context) error {
return nil
}
+ defer func() {
+ if err := recover(); err != nil {
+ _ = fail(ctx, "Internal Server Error", "Panic: %v\n%s", err, log.Stack(2))
+ }
+ }()
+
keys := strings.Split(c.Args().First(), "-")
if len(keys) != 2 || keys[0] != "key" {
return fail(ctx, "Key ID format error", "Invalid key argument: %s", c.Args().First())
@@ -193,10 +201,7 @@ func runServ(c *cli.Context) error {
}
verb := words[0]
- repoPath := words[1]
- if repoPath[0] == '/' {
- repoPath = repoPath[1:]
- }
+ repoPath := strings.TrimPrefix(words[1], "/")
var lfsVerb string
if verb == lfsAuthenticateVerb {
@@ -209,6 +214,28 @@ func runServ(c *cli.Context) error {
}
}
+ if verb == gitAnnexShellVerb {
+ if !setting.Annex.Enabled {
+ return fail(ctx, "Unknown git command", "git-annex request over SSH denied, git-annex support is disabled")
+ }
+
+ if len(words) < 3 {
+ return fail(ctx, "Too few arguments", "Too few arguments in cmd: %s", cmd)
+ }
+
+ // git-annex always puts the repo in words[2], unlike most other
+ // git subcommands; and it sometimes names repos like /~/, as if
+ // $HOME should get expanded while also being rooted. e.g.:
+ // git-annex-shell 'configlist' '/~/user/repo'
+ // git-annex-shell 'sendkey' '/user/repo 'key'
+ repoPath = words[2]
+ repoPath = strings.TrimPrefix(repoPath, "/")
+ repoPath = strings.TrimPrefix(repoPath, "~/")
+ }
+
+ // prevent directory traversal attacks
+ repoPath = filepath.Clean("/" + repoPath)[1:]
+
rr := strings.SplitN(repoPath, "/", 2)
if len(rr) != 2 {
return fail(ctx, "Invalid repository path", "Invalid repository path: %v", repoPath)
@@ -222,6 +249,18 @@ func runServ(c *cli.Context) error {
// so that username and reponame are not affected.
repoPath = strings.ToLower(strings.TrimSpace(repoPath))
+ // put the sanitized repoPath back into the argument list for later
+ if verb == gitAnnexShellVerb {
+ // git-annex-shell demands an absolute path
+ absRepoPath, err := filepath.Abs(filepath.Join(setting.RepoRootPath, repoPath))
+ if err != nil {
+ return fail(ctx, "Error locating repoPath", "%v", err)
+ }
+ words[2] = absRepoPath
+ } else {
+ words[1] = repoPath
+ }
+
if alphaDashDotPattern.MatchString(reponame) {
return fail(ctx, "Invalid repo name", "Invalid repo name: %s", reponame)
}
@@ -300,21 +339,45 @@ func runServ(c *cli.Context) error {
return nil
}
- var gitcmd *exec.Cmd
- gitBinPath := filepath.Dir(git.GitExecutable) // e.g. /usr/bin
- gitBinVerb := filepath.Join(gitBinPath, verb) // e.g. /usr/bin/git-upload-pack
- if _, err := os.Stat(gitBinVerb); err != nil {
+ gitBinVerb, err := exec.LookPath(verb)
+ if err != nil {
// if the command "git-upload-pack" doesn't exist, try to split "git-upload-pack" to use the sub-command with git
// ps: Windows only has "git.exe" in the bin path, so Windows always uses this way
+ // ps: git-annex-shell and other extensions may not necessarily be in gitBinPath,
+ // but '{gitBinPath}/git annex-shell' should be able to find them on $PATH.
verbFields := strings.SplitN(verb, "-", 2)
if len(verbFields) == 2 {
// use git binary with the sub-command part: "C:\...\bin\git.exe", "upload-pack", ...
- gitcmd = exec.CommandContext(ctx, git.GitExecutable, verbFields[1], repoPath)
+ gitBinVerb = git.GitExecutable
+ words = append([]string{verbFields[1]}, words...)
}
}
- if gitcmd == nil {
- // by default, use the verb (it has been checked above by allowedCommands)
- gitcmd = exec.CommandContext(ctx, gitBinVerb, repoPath)
+
+ // by default, use the verb (it has been checked above by allowedCommands)
+ gitcmd := exec.CommandContext(ctx, gitBinVerb, words[1:]...)
+
+ if verb == gitAnnexShellVerb {
+ // This doesn't get its own isolated section like LFS does, because LFS
+ // is handled by internal Gitea routines, but git-annex has to be shelled out
+ // to like other git subcommands, so we need to build up gitcmd.
+
+ // TODO: does this work on Windows?
+ gitcmd.Env = append(gitcmd.Env,
+ // "If set, disallows running git-shell to handle unknown commands."
+ // - git-annex-shell(1)
+ "GIT_ANNEX_SHELL_LIMITED=True",
+ // "If set, git-annex-shell will refuse to run commands
+ // that do not operate on the specified directory."
+ // - git-annex-shell(1)
+ fmt.Sprintf("GIT_ANNEX_SHELL_DIRECTORY=%s", words[2]),
+ )
+ if results.UserMode < perm.AccessModeWrite {
+ // "If set, disallows any action that could modify the git-annex repository."
+ // - git-annex-shell(1)
+ // We set this when the backend API has told us that we don't have write permission to this repo.
+ log.Debug("Setting GIT_ANNEX_SHELL_READONLY=True")
+ gitcmd.Env = append(gitcmd.Env, "GIT_ANNEX_SHELL_READONLY=True")
+ }
}
process.SetSysProcAttribute(gitcmd)
diff --git a/cmd/web.go b/cmd/web.go
index 44babd51c5..4e89153ab4 100644
--- a/cmd/web.go
+++ b/cmd/web.go
@@ -9,20 +9,22 @@ import (
"net"
"net/http"
"os"
+ "os/exec"
"path/filepath"
"strconv"
"strings"
+ "time"
_ "net/http/pprof" // Used for debugging if enabled and a web server is running
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/public"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/routers"
- "code.gitea.io/gitea/routers/install"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/public"
+ "forgejo.org/modules/setting"
+ "forgejo.org/routers"
+ "forgejo.org/routers/install"
"github.com/felixge/fgprof"
"github.com/urfave/cli/v2"
@@ -115,6 +117,16 @@ func showWebStartupMessage(msg string) {
log.Info("* CustomPath: %s", setting.CustomPath)
log.Info("* ConfigFile: %s", setting.CustomConf)
log.Info("%s", msg) // show startup message
+
+ if setting.CORSConfig.Enabled {
+ log.Info("CORS Service Enabled")
+ }
+ if setting.DefaultUILocation != time.Local {
+ log.Info("Default UI Location is %v", setting.DefaultUILocation.String())
+ }
+ if setting.MailService != nil {
+ log.Info("Mail Service Enabled: RegisterEmailConfirm=%v, Service.EnableNotifyMail=%v", setting.Service.RegisterEmailConfirm, setting.Service.EnableNotifyMail)
+ }
}
func serveInstall(ctx *cli.Context) error {
@@ -184,7 +196,7 @@ func serveInstalled(ctx *cli.Context) error {
publicFilesSet.Remove(".well-known")
publicFilesSet.Remove("assets")
publicFilesSet.Remove("robots.txt")
- for _, fn := range publicFilesSet.Values() {
+ for fn := range publicFilesSet.Seq() {
log.Error("Found legacy public asset %q in CustomPath. Please move it to %s/public/assets/%s", fn, setting.CustomPath, fn)
}
if _, err := os.Stat(filepath.Join(setting.CustomPath, "robots.txt")); err == nil {
@@ -247,6 +259,12 @@ func runWeb(ctx *cli.Context) error {
createPIDFile(ctx.String("pid"))
}
+ if setting.Annex.Enabled {
+ if _, err := exec.LookPath("git-annex"); err != nil {
+ log.Fatal("You have enabled git-annex support but git-annex is not installed. Please make sure that Forgejo's PATH contains the git-annex executable.")
+ }
+ }
+
if !setting.InstallLock {
if err := serveInstall(ctx); err != nil {
return err
@@ -311,6 +329,10 @@ func listen(m http.Handler, handleRedirector bool) error {
log.Info("LFS server enabled")
}
+ if setting.Annex.Enabled {
+ log.Info("git-annex enabled")
+ }
+
var err error
switch setting.Protocol {
case setting.HTTP:
diff --git a/cmd/web_acme.go b/cmd/web_acme.go
index 90e4a02764..b2d7435be2 100644
--- a/cmd/web_acme.go
+++ b/cmd/web_acme.go
@@ -12,10 +12,10 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
"github.com/caddyserver/certmagic"
)
diff --git a/cmd/web_graceful.go b/cmd/web_graceful.go
index 996537be3b..b0145d4fc7 100644
--- a/cmd/web_graceful.go
+++ b/cmd/web_graceful.go
@@ -9,9 +9,9 @@ import (
"net/http/fcgi"
"strings"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
func runHTTP(network, listenAddr, name string, m http.Handler, useProxyProtocol bool) error {
diff --git a/cmd/web_https.go b/cmd/web_https.go
index 70d35cd40d..bebc5f7c8f 100644
--- a/cmd/web_https.go
+++ b/cmd/web_https.go
@@ -9,9 +9,9 @@ import (
"os"
"strings"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"github.com/klauspost/cpuid/v2"
)
diff --git a/contrib/backport/backport.go b/contrib/backport/backport.go
index 820c0702b7..dd6b4129df 100644
--- a/contrib/backport/backport.go
+++ b/contrib/backport/backport.go
@@ -17,7 +17,7 @@ import (
"strings"
"syscall"
- "github.com/google/go-github/v57/github"
+ "github.com/google/go-github/v64/github"
"github.com/urfave/cli/v2"
"gopkg.in/yaml.v3"
)
diff --git a/contrib/environment-to-ini/environment-to-ini.go b/contrib/environment-to-ini/environment-to-ini.go
index f8593e49c3..95f34527ac 100644
--- a/contrib/environment-to-ini/environment-to-ini.go
+++ b/contrib/environment-to-ini/environment-to-ini.go
@@ -6,8 +6,8 @@ package main
import (
"os"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"github.com/urfave/cli/v2"
)
diff --git a/contrib/fixtures/fixture_generation.go b/contrib/fixtures/fixture_generation.go
deleted file mode 100644
index 31797cc800..0000000000
--- a/contrib/fixtures/fixture_generation.go
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//nolint:forbidigo
-package main
-
-import (
- "context"
- "fmt"
- "os"
- "path/filepath"
-
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/unittest"
-)
-
-// To generate derivative fixtures, execute the following from Gitea's repository base dir:
-// go run -tags 'sqlite sqlite_unlock_notify' contrib/fixtures/fixture_generation.go [fixture...]
-
-var (
- generators = []struct {
- gen func(ctx context.Context) (string, error)
- name string
- }{
- {
- models.GetYamlFixturesAccess, "access",
- },
- }
- fixturesDir string
-)
-
-func main() {
- pathToGiteaRoot := "."
- fixturesDir = filepath.Join(pathToGiteaRoot, "models", "fixtures")
- if err := unittest.CreateTestEngine(unittest.FixturesOptions{
- Dir: fixturesDir,
- }); err != nil {
- fmt.Printf("CreateTestEngine: %+v", err)
- os.Exit(1)
- }
- if err := unittest.PrepareTestDatabase(); err != nil {
- fmt.Printf("PrepareTestDatabase: %+v\n", err)
- os.Exit(1)
- }
- ctx := context.Background()
- if len(os.Args) == 0 {
- for _, r := range os.Args {
- if err := generate(ctx, r); err != nil {
- fmt.Printf("generate '%s': %+v\n", r, err)
- os.Exit(1)
- }
- }
- } else {
- for _, g := range generators {
- if err := generate(ctx, g.name); err != nil {
- fmt.Printf("generate '%s': %+v\n", g.name, err)
- os.Exit(1)
- }
- }
- }
-}
-
-func generate(ctx context.Context, name string) error {
- for _, g := range generators {
- if g.name == name {
- data, err := g.gen(ctx)
- if err != nil {
- return err
- }
- path := filepath.Join(fixturesDir, name+".yml")
- if err := os.WriteFile(path, []byte(data), 0o644); err != nil {
- return fmt.Errorf("%s: %+v", path, err)
- }
- fmt.Printf("%s created.\n", path)
- return nil
- }
- }
-
- return fmt.Errorf("generator not found")
-}
diff --git a/contrib/ide/vscode/settings.json b/contrib/ide/vscode/settings.json
index 2ec666f3c1..7f7de43622 100644
--- a/contrib/ide/vscode/settings.json
+++ b/contrib/ide/vscode/settings.json
@@ -1,4 +1,6 @@
{
- "go.buildTags": "sqlite,sqlite_unlock_notify",
- "go.testFlags": ["-v"]
+ "go.buildTags": "sqlite,sqlite_unlock_notify",
+ "go.testFlags": ["-v"],
+ "go.lintTool": "golangci-lint",
+ "go.lintFlags": ["--fast"]
}
diff --git a/contrib/legal/privacy.html.sample b/contrib/legal/privacy.html.sample
index adb3ea7ad4..34a9a5142f 100644
--- a/contrib/legal/privacy.html.sample
+++ b/contrib/legal/privacy.html.sample
@@ -7,11 +7,11 @@
Privacy Policy
- Last updated: January 29, 2020
+ Last updated: December 19, 2024
Who We Are?
- Your Gitea Instance
+ Your Forgejo Instance
What Personal Data We Collect?
@@ -37,19 +37,19 @@
With your Consent
- We share your User Personal Information, if you consent, after letting you know what information will be shared, with whom, and why. For example, if you allow third party applications to access your Account using OAuth2 providers , we share all information associated with your Account, including private repos and organizations. You may also direct us through your action on Your Gitea Instance to share your User Personal Information, such as when joining an Organization.
+ We share your User Personal Information, if you consent, after letting you know what information will be shared, with whom, and why. For example, if you allow third party applications to access your Account using OAuth2 providers , we share all information associated with your Account, including private repos and organizations. You may also direct us through your action on Your Forgejo Instance to share your User Personal Information, such as when joining an Organization.
With Service Providers
- We share User Personal Information with a limited number of service providers who process it on our behalf to provide or improve our Service, and who have agreed to privacy restrictions similar to the ones in our Privacy Statement by signing data protection agreements or making similar commitments. Our service providers perform payment processing, customer support ticketing, network data transmission, security, and other similar services. While Your Gitea Instance processes all User Personal Information in the (country/state where Gitea is deployed), our service providers may process data outside of (country/state where Gitea is deployed), the United States or the European Union.
+ We share User Personal Information with a limited number of service providers who process it on our behalf to provide or improve our Service, and who have agreed to privacy restrictions similar to the ones in our Privacy Statement by signing data protection agreements or making similar commitments. Our service providers perform payment processing, customer support ticketing, network data transmission, security, and other similar services. While Your Forgejo Instance processes all User Personal Information in the (country/state where Forgejo is deployed), our service providers may process data outside of (country/state where Forgejo is deployed), the United States or the European Union.
For Security Purposes
- If you are a member of an Organization, Your Gitea Instance may share your username, Usage Information, and Device Information associated with that Organization with an owner and/or administrator of the Organization who has agreed to the Corporate Terms of Service or applicable customer agreements, to the extent that such information is provided only to investigate or respond to a security incident that affects or compromises the security of that particular Organization.
+ If you are a member of an Organization, Your Forgejo Instance may share your username, Usage Information, and Device Information associated with that Organization with an owner and/or administrator of the Organization who has agreed to the Corporate Terms of Service or applicable customer agreements, to the extent that such information is provided only to investigate or respond to a security incident that affects or compromises the security of that particular Organization.
For Legal Disclosure
- Your Gitea Instance strives for transparency in complying with legal process and legal obligations. Unless prevented from doing so by law or court order, or in rare, exigent circumstances, we make a reasonable effort to notify users of any legally compelled or required disclosure of their information. Your Gitea Instance may disclose User Personal Information or other information we collect about you to law enforcement if required in response to a valid subpoena, court order, search warrant, a similar government order, or when we believe in good faith that disclosure is necessary to comply with our legal obligations, to protect our property or rights, or those of third parties or the public at large.
+ Your Forgejo Instance strives for transparency in complying with legal process and legal obligations. Unless prevented from doing so by law or court order, or in rare, exigent circumstances, we make a reasonable effort to notify users of any legally compelled or required disclosure of their information. Your Forgejo Instance may disclose User Personal Information or other information we collect about you to law enforcement if required in response to a valid subpoena, court order, search warrant, a similar government order, or when we believe in good faith that disclosure is necessary to comply with our legal obligations, to protect our property or rights, or those of third parties or the public at large.
Change in Control or Sale
@@ -57,7 +57,7 @@
Aggregate, Non-Personally Identifying Information
- We share certain aggregated, non-personally identifying information with others about how our users, collectively, use Your Gitea Instance, or how our users respond to our other offerings, such as our conferences or events. For example, we may compile statistics on the open source activity across Your Gitea Instance.
+ We share certain aggregated, non-personally identifying information with others about how our users, collectively, use Your Forgejo Instance, or how our users respond to our other offerings, such as our conferences or events. For example, we may compile statistics on the open source activity across Your Forgejo Instance.
We don't sell your User Personal Information for monetary or other consideration.
@@ -67,34 +67,34 @@
We use your Registration Information to create your account, and to provide you the Service.
- We use your User Personal Information, specifically your username, to identify you on Your Gitea Instance.
+ We use your User Personal Information, specifically your username, to identify you on Your Forgejo Instance.
We use your Profile Information to fill out your Account profile and to share that profile with other users if you ask us to.
We use your email address to communicate with you, if you've said that's okay, and only for the reasons youโve said thatโs okay.
- We use User Personal Information and other data to make recommendations for you, such as to suggest projects you may want to follow or contribute to. We learn from your public behavior on Your Gitea Instanceโsuch as the projects you starโto determine your coding interests, and we recommend similar projects. These recommendations are automated decisions, but they have no legal impact on your rights.
- We use Usage Information and Device Information to better understand how our Users use Your Gitea Instance and to improve our Website and Service.
- We may use your User Personal Information if it is necessary for security purposes or to investigate possible fraud or attempts to harm Your Gitea Instance or our Users.
+ We use User Personal Information and other data to make recommendations for you, such as to suggest projects you may want to follow or contribute to. We learn from your public behavior on Your Forgejo Instanceโsuch as the projects you starโto determine your coding interests, and we recommend similar projects. These recommendations are automated decisions, but they have no legal impact on your rights.
+ We use Usage Information and Device Information to better understand how our Users use Your Forgejo Instance and to improve our Website and Service.
+ We may use your User Personal Information if it is necessary for security purposes or to investigate possible fraud or attempts to harm Your Forgejo Instance or our Users.
We may use your User Personal Information to comply with our legal obligations, protect our intellectual property, and enforce our Terms of Service.
We limit our use of your User Personal Information to the purposes listed in this Privacy Statement. If we need to use your User Personal Information for other purposes, we will ask your permission first. You can always see what information we have, how we're using it, and what permissions you have given us in your user profile.
- How Your Gitea Instance Secures Your Information?
+ How Your Forgejo Instance Secures Your Information?
- Your Gitea Instance takes all measures reasonably necessary to protect User Personal Information from unauthorized access, alteration, or destruction; maintain data accuracy; and help ensure the appropriate use of User Personal Information.
+ Your Forgejo Instance takes all measures reasonably necessary to protect User Personal Information from unauthorized access, alteration, or destruction; maintain data accuracy; and help ensure the appropriate use of User Personal Information.
To the extent above, we enforce a written security information program, which:
aligns with industry recognized frameworks;
includes security safeguards reasonably designed to protect the confidentiality, integrity, availability, and resilience of our Users' data;
- is appropriate to the nature, size, and complexity of Your Gitea Instanceโs business operations;
+ is appropriate to the nature, size, and complexity of Your Forgejo Instanceโs business operations;
includes incident response and data breach notification processes; and
- complies with applicable information security-related laws and regulations in the geographic regions where Your Gitea Instance does business.
+ complies with applicable information security-related laws and regulations in the geographic regions where Your Forgejo Instance does business.
In the event of a data breach that affects your User Personal Information, we will act promptly to mitigate the impact of a breach and notify any affected Users without undue delay.
- Transmission of data on Your Gitea Instance is encrypted using SSH, HTTPS (TLS), and git repository content is encrypted at rest. We host Your Gitea Instance at our hosting partner, which they provide data centers with high level of physical and network security.
+ Transmission of data on Your Forgejo Instance is encrypted using SSH, HTTPS (TLS), and git repository content is encrypted at rest. We host Your Forgejo Instance at our hosting partner, which they provide data centers with high level of physical and network security.
Disclaimer: No method of transmission, or method of electronic storage, is 100% secure, therefore, we cannot guarantee absolute security.
@@ -102,13 +102,13 @@
Cookies
- We uses cookies to make interactions with our service easy and meaningful. Cookies are small text files that websites often store on computer hard drives or mobile devices of visitors. We use cookies (and similar technologies, like HTML5 localStorage) to keep you logged in, remember your preferences, and provide information for future development of Your Gitea Instance. For security purposes, we use cookies to identify a device. By using our Website, you agree that we can place these types of cookies on your computer or device. If you disable your browser or deviceโs ability to accept these cookies, you will not be able to log in or use our services.
+ We uses cookies to make interactions with our service easy and meaningful. Cookies are small text files that websites often store on computer hard drives or mobile devices of visitors. We use cookies (and similar technologies, like HTML5 localStorage) to keep you logged in, remember your preferences, and provide information for future development of Your Forgejo Instance. For security purposes, we use cookies to identify a device. By using our Website, you agree that we can place these types of cookies on your computer or device. If you disable your browser or deviceโs ability to accept these cookies, you will not be able to log in or use our services.
Tracking and Analytics
- Out of the box, Gitea doesn't use third-party analytics. In case when we opt in to their usage, we do that to help us evaluate our Users' use of Your Gitea Instance, compile statistical reports on activity, and improve our content and Website performance. We only use these third-party analytics providers on certain areas of our Website, and all of them have signed data protection agreements with us that limit the type of User Personal Information they can collect and the purpose for which they can process the information. In addition, we may also deploy internal analytics software to provide similar functionality.
+ Out of the box, Forgejo doesn't use third-party analytics. In case when we opt in to their usage, we do that to help us evaluate our Users' use of Your Forgejo Instance, compile statistical reports on activity, and improve our content and Website performance. We only use these third-party analytics providers on certain areas of our Website, and all of them have signed data protection agreements with us that limit the type of User Personal Information they can collect and the purpose for which they can process the information. In addition, we may also deploy internal analytics software to provide similar functionality.
- Some browsers have incorporated "Do Not Track" (DNT) features that can send a signal to the websites you visit indicating you do not wish to be tracked. Your Gitea Instance responds to browser DNT signals and follows the W3C standard for responding to DNT signals . If you have not enabled DNT on a browser that supports it, cookies on some parts of our Website will track your online browsing activity on other online services over time, though we do not permit third parties other than our analytics and service providers to track Your Gitea Instance Users' activity over time on Your Gitea Instance.
+ Some browsers have incorporated "Do Not Track" (DNT) features that can send a signal to the websites you visit indicating you do not wish to be tracked. Your Forgejo Instance responds to browser DNT signals and follows the W3C standard for responding to DNT signals . If you have not enabled DNT on a browser that supports it, cookies on some parts of our Website will track your online browsing activity on other online services over time, though we do not permit third parties other than our analytics and service providers to track Your Forgejo Instance Users' activity over time on Your Forgejo Instance.
Repository Contents
@@ -118,19 +118,19 @@
Public Information
- Many of our services and feature are public-facing. If your content is public-facing, third parties may access and use it in compliance with our Terms of Service, such as by viewing your profile or repositories or pulling data via our API. We do not sell that content; it is yours. However, we do allow third parties, such as research organizations or archives, to compile public-facing Your Gitea Instance information. Other third parties, such as data brokers, have been known to scrape Your Gitea Instance and compile data as well.
+ Many of our services and feature are public-facing. If your content is public-facing, third parties may access and use it in compliance with our Terms of Service, such as by viewing your profile or repositories or pulling data via our API. We do not sell that content; it is yours. However, we do allow third parties, such as research organizations or archives, to compile public-facing Your Forgejo Instance information. Other third parties, such as data brokers, have been known to scrape Your Forgejo Instance and compile data as well.
- Your User Personal Information associated with your content could be gathered by third parties in these compilations of Your Gitea Instance data. If you do not want your User Personal Information to appear in third partiesโ compilations of Your Gitea Instance data, please do not make your User Personal Information publicly available and be sure to configure your email address to be private in your user profile and in your git commit settings.
+ Your User Personal Information associated with your content could be gathered by third parties in these compilations of Your Forgejo Instance data. If you do not want your User Personal Information to appear in third partiesโ compilations of Your Forgejo Instance data, please do not make your User Personal Information publicly available and be sure to configure your email address to be private in your user profile and in your git commit settings.
- If you would like to compile Your Gitea Instance data, you must comply with our Terms of Service regarding scraping and privacy, and you may only use any public-facing User Personal Information you gather for the purpose for which our user authorized it. For example, where a Your Gitea Instance user has made an email address public-facing for the purpose of identification and attribution, do not use that email address for commercial advertising. We expect you to reasonably secure any User Personal Information you have gathered from Your Gitea Instance, and to respond promptly to complaints, removal requests, and "do not contact" requests from Your Gitea Instance or Your Gitea Instance users.
+ If you would like to compile Your Forgejo Instance data, you must comply with our Terms of Service regarding scraping and privacy, and you may only use any public-facing User Personal Information you gather for the purpose for which our user authorized it. For example, where a Your Forgejo Instance user has made an email address public-facing for the purpose of identification and attribution, do not use that email address for commercial advertising. We expect you to reasonably secure any User Personal Information you have gathered from Your Forgejo Instance, and to respond promptly to complaints, removal requests, and "do not contact" requests from Your Forgejo Instance or Your Forgejo Instance users.
- In similar fashion, projects on Your Gitea Instance may include publicly available User Personal Information collected as part of the collaborative events.
+ In similar fashion, projects on Your Forgejo Instance may include publicly available User Personal Information collected as part of the collaborative events.
Organizations
If you collaborate on or become a member of an Organization, then its Account owners may receive your User Personal Information. When you accept an invitation to an Organization, you will be notified of the types of information owners may be able to see. If you accept an invitation to an Organization with a verified domain, then the owners of that Organization will be able to see your full email address(es) within that Organization's verified domain(s).
- Please note, Your Gitea Instance may share your username, Usage Information, and Device Information with the owner of the Organization you are a member of, to the extent that your User Personal Information is provided only to investigate or respond to a security incident that affects or compromises the security of that particular Organization.
+ Please note, Your Forgejo Instance may share your username, Usage Information, and Device Information with the owner of the Organization you are a member of, to the extent that your User Personal Information is provided only to investigate or respond to a security incident that affects or compromises the security of that particular Organization.
If you collaborate with or become a member of an Account that has agreed to a Data Protection Addendum (DPA) to this Privacy Policy, then that DPA governs in the event of conflicts between this Privacy Policy and DPA with respect to your activity in the Account.
@@ -138,17 +138,17 @@
How You Can Access and Control the Information We Collect?
- If you're already a Your Gitea Instance user, you may access, update, alter, or delete your basic user information by editing your user profile. You can control the information we collect about you by limiting what information is in your profile, or by keeping your information current.
+ If you're already a Your Forgejo Instance user, you may access, update, alter, or delete your basic user information by editing your user profile. You can control the information we collect about you by limiting what information is in your profile, or by keeping your information current.
- If Your Gitea Instance processes information about you, such as information receives from third parties, and you do not have an account, then you may, subject to applicable law, access, update, alter, delete, or object to the processing of your personal information by contacting our support.
+ If Your Forgejo Instance processes information about you, such as information receives from third parties, and you do not have an account, then you may, subject to applicable law, access, update, alter, delete, or object to the processing of your personal information by contacting our support.
Data Portability
- As a Your Gitea Instance User, you can always take your data with you. You can clone your repositories to your computer, or you can perform migrations using the provided interfaces , for example.
+ As a Your Forgejo Instance User, you can always take your data with you. You can clone your repositories to your computer, or you can perform migrations using the provided interfaces , for example.
Data Retention and Deletion of Data
- In general, Your Gitea Instance retains User Personal Information for as long as your account is active, or as needed to provide you service.
+ In general, Your Forgejo Instance retains User Personal Information for as long as your account is active, or as needed to provide you service.
If you would like to cancel your account or delete your User Personal Information, you may do so in your user profile. We retain and use your information as necessary to comply with our legal obligations, resolve disputes, and enforce our agreements, but barring legal requirements, we will delete your full profile (within reason) within 90 days of your request. Feel free to contact our support to request erasure of the data we process on the basis of consent within 30 days.
@@ -158,14 +158,14 @@
Our Global Privacy Practices
- We store and process the information that we collect in the (country/state where Gitea is deployed) in accordance with this Privacy Statement though our service providers may store and process data outside the (country/state where Gitea is deployed). However, we understand that we have Users from different countries and regions with different privacy expectations, and we try to meet those needs even when the (country/state where Gitea is deployed) does not have the same privacy framework as other countries.
+ We store and process the information that we collect in the (country/state where Forgejo is deployed) in accordance with this Privacy Statement though our service providers may store and process data outside the (country/state where Forgejo is deployed). However, we understand that we have Users from different countries and regions with different privacy expectations, and we try to meet those needs even when the (country/state where Forgejo is deployed) does not have the same privacy framework as other countries.
We provide a high standard of privacy protectionโas described in this Privacy Statementโto all our users around the world, regardless of their country of origin or location, and we are proud of the levels of notice, choice, accountability, security, data integrity, access, and recourse we provide. We work hard to comply with the applicable data privacy laws wherever we do business, working with our Data Protection Officer as part of a cross-functional team that oversees our privacy compliance efforts. Additionally, if our vendors or affiliates have access to User Personal Information, they must sign agreements that require them to comply with our privacy policies and with applicable data privacy laws.
In particular:
- Your Gitea Instance provides clear methods of unambiguous, informed, specific, and freely given consent at the time of data collection, when we collect your User Personal Information using consent as a basis.
+ Your Forgejo Instance provides clear methods of unambiguous, informed, specific, and freely given consent at the time of data collection, when we collect your User Personal Information using consent as a basis.
We collect only the minimum amount of User Personal Information necessary for our purposes, unless you choose to provide more. We encourage you to only give us the amount of data you are comfortable sharing.
We offer you simple methods of accessing, altering, or deleting the User Personal Information we have collected, where legally permitted.
We provide our Users notice, choice, accountability, security, and access regarding their User Personal Information, and we limit the purpose for processing it. We also provide our Users a method of recourse and enforcement. These are the Privacy Shield Principles, but they are also just good practices.
@@ -173,21 +173,21 @@
How We Communicate with You?
- We use your email address to communicate with you, if you've said that's okay, and only for the reasons youโve said thatโs okay. For example, if you contact our support with a request, we respond to you via email. You have a lot of control over how your email address is used and shared on and through Your Gitea instance. You may manage your communication preferences in your user profile.
+ We use your email address to communicate with you, if you've said that's okay, and only for the reasons youโve said thatโs okay. For example, if you contact our support with a request, we respond to you via email. You have a lot of control over how your email address is used and shared on and through Your Forgejo instance. You may manage your communication preferences in your user profile.
By design, the Git version control system associates many actions with a User's email address, such as commit messages. We are not able to change many aspects of the Git system. If you would like your email address to remain private, even when youโre commenting on public repositories, you can create a private email address in your user profile. You should also update your local Git configuration to use your private email address. This will not change how we contact you, but it will affect how others see you.
- Depending on your email settings, Your Gitea instance may occasionally send notification emails about changes in a repository youโre watching, new features, requests for feedback, important policy changes, or to offer customer support. We also send marketing emails, based on your choices and in accordance with applicable laws and regulations. There's an โunsubscribeโ link located at the bottom of each of the marketing emails we send you. Note that you can opt out of any communications with us, except the important ones (like from our support and system emails).
+ Depending on your email settings, Your Forgejo instance may occasionally send notification emails about changes in a repository youโre watching, new features, requests for feedback, important policy changes, or to offer customer support. We also send marketing emails, based on your choices and in accordance with applicable laws and regulations. There's an โunsubscribeโ link located at the bottom of each of the marketing emails we send you. Note that you can opt out of any communications with us, except the important ones (like from our support and system emails).
Our emails may contain a pixel tag, which is a small, clear image that can tell us whether or not you have opened an email and what your IP address is. We use this pixel tag to make our email more effective for you and to make sure weโre not sending you unwanted email.
Changes to this Privacy Policy
- Although most changes are likely to be minor, Your Gitea Instance may change our Privacy Statement from time to time. We will provide notification to Users of material changes to this Privacy Statement through our Website at least 30 days prior to the change taking effect by posting a notice on our home page or sending email to the primary email address specified in your account.
+ Although most changes are likely to be minor, Your Forgejo Instance may change our Privacy Statement from time to time. We will provide notification to Users of material changes to this Privacy Statement through our Website at least 30 days prior to the change taking effect by posting a notice on our home page or sending email to the primary email address specified in your account.
Contact
- If you have any concerns about privacy, please contact us at privacy@your-gitea-instance . We will respond promptly, within 45 days.
+ If you have any concerns about privacy, please contact us at privacy@your-forgejo-instance . We will respond promptly, within 45 days.
COPYING
diff --git a/contrib/legal/tos.html.sample b/contrib/legal/tos.html.sample
index d39082909f..73ee0899ef 100644
--- a/contrib/legal/tos.html.sample
+++ b/contrib/legal/tos.html.sample
@@ -7,26 +7,26 @@
Terms of Service
- Last updated: January 29, 2020
+ Last updated: December 19, 2024
- Thank you for choosing Your Gitea Instance! Before you use it, please read this Terms of Service agreement carefully, which contains important contract between us and our users.
+ Thank you for choosing Your Forgejo Instance! Before you use it, please read this Terms of Service agreement carefully, which contains important contract between us and our users.
Definitions
- An "Account" represents your legal relationship with Your Gitea Instance. A โUser Accountโ represents an individual Userโs authorization to log in to and use the Service and serves as a Userโs identity on Your Gitea Instance. โOrganizationsโ are shared workspaces that may be associated with a single entity or with one or more Users where multiple Users can collaborate across many projects at once. A User Account can be a member of any number of Organizations.
+ An "Account" represents your legal relationship with Your Forgejo Instance. A โUser Accountโ represents an individual Userโs authorization to log in to and use the Service and serves as a Userโs identity on Your Forgejo Instance. โOrganizationsโ are shared workspaces that may be associated with a single entity or with one or more Users where multiple Users can collaborate across many projects at once. A User Account can be a member of any number of Organizations.
The "Agreement" collectively refers to all terms, conditions, and notices referenced or contained in this document and other operating rules, policies (including Privacy Policy) and procedures that we may publish from time to time on this Website.
โContentโ refers to content featured or displayed through the Website, including without limitation code, text, data, articles, images, photographs, graphics, software, applications, packages, designs, features, and other materials that are available on the Website or otherwise available through the Service. "Content" also includes Services. โUser-Generated Contentโ is Content, written or otherwise, created or uploaded by our Users. "Your Content" is Content that you create or own.
- "Your Gitea Instance", "We", and "Us" refers to Your Gitea Instance, as well as our affiliates, directors, subsidiaries, contractors, licensors, officers, agents, and employees.
+ "Your Forgejo Instance", "We", and "Us" refers to Your Forgejo Instance, as well as our affiliates, directors, subsidiaries, contractors, licensors, officers, agents, and employees.
- The "Service" refers to applications/software, products, and services provided by Your Gitea Instance.
+ The "Service" refers to applications/software, products, and services provided by Your Forgejo Instance.
The "User", "You", and "Your" refers to individual person or institution (organizations or company) that has visited or using the Service; that have access or use any part of the Account; or that directs to use the Account to perform its function. Please note that additional terms may apply for Accounts related to business or government.
- The "Website" refers to Your Gitea Instance's website at your-gitea-instance , including its subdomains and other websites owned by Your Gitea Instance.
+ The "Website" refers to Your Forgejo Instance's website at your-forgejo-instance , including its subdomains and other websites owned by Your Forgejo Instance.
Account Terms
@@ -48,7 +48,7 @@
You must be a human to create an Account. Accounts registered by "bots" or other automated methods are not permitted. We do permit machine accounts:
A machine account is an Account set up by an individual human who accepts the Terms on behalf of the Account, provides a valid email address, and is responsible for its actions. A machine account is used exclusively for performing automated tasks. Multiple users may direct the actions of a machine account, but the owner of the Account is ultimately responsible for the machine's actions.
- You must be age 13 or older. If we learn of any User under that age, we will immediately terminate that User's Account. Different countries may have different minimum age; in such cases you are responsible for complying with your country's regulation. By using Your Gitea Instance, you agree to comply with COPPA and/or similar law in your country.
+ You must be age 13 or older. If we learn of any User under that age, we will immediately terminate that User's Account. Different countries may have different minimum age; in such cases you are responsible for complying with your country's regulation. By using Your Forgejo Instance, you agree to comply with COPPA and/or similar law in your country.
User Account Security
@@ -57,7 +57,7 @@
Additional Terms
- In some situations, third parties' terms may apply to your use of Your Gitea Instance. For example, you may be a member of an organization on Your Gitea Instance with its own terms or license agreements; you may download an application that integrates with Your Gitea Instance; or you may use Your Gitea Instance to authenticate to another service. Please be aware that while these Terms are our full agreement with you, other parties' terms govern their relationships with you.
+ In some situations, third parties' terms may apply to your use of Your Forgejo Instance. For example, you may be a member of an organization on Your Forgejo Instance with its own terms or license agreements; you may download an application that integrates with Your Forgejo Instance; or you may use Your Forgejo Instance to authenticate to another service. Please be aware that while these Terms are our full agreement with you, other parties' terms govern their relationships with you.
Acceptable Use
@@ -73,19 +73,19 @@
You retain ownership of and responsibility for Your Content. If you're posting anything you did not create yourself or do not own the rights to, you agree that you are responsible for any Content you post; that you will only submit Content that you have the right to post; and that you will fully comply with any third party licenses relating to Content you post.
- Because of above, we need you to grant us -- and other Your Gitea Instance users -- certain legal permissions, listed below in this section. If you upload Content that already comes with a license granting Your Gitea Instance the permissions we need to run our Service, no additional license is required. You understand that you will not receive any payment for any of the rights granted below. The licenses you grant to us will end when you remove Your Content from our servers, unless other Users have forked it.
+ Because of above, we need you to grant us -- and other Your Forgejo Instance users -- certain legal permissions, listed below in this section. If you upload Content that already comes with a license granting Your Forgejo Instance the permissions we need to run our Service, no additional license is required. You understand that you will not receive any payment for any of the rights granted below. The licenses you grant to us will end when you remove Your Content from our servers, unless other Users have forked it.
We need the legal right to do things like host Your Content, publish it, and share it. You grant us and our legal successors the right to store, parse, and display Your Content, and make incidental copies as necessary to render the Website and provide the Service. This includes the right to do things like copy it to our database and make backups; show it to you and other users; parse it into a search index or otherwise analyze it on our servers; share it with other users; and perform it, in case Your Content is something like music or video.
- This license, however, doesn't grant Your Gitea Instance the right to sell Your Content or otherwise distribute or use it outside of our provision of the Service.
+ This license, however, doesn't grant Your Forgejo Instance the right to sell Your Content or otherwise distribute or use it outside of our provision of the Service.
Any User-Generated Content you post publicly, including issues, comments, and contributions to other Users' repositories, may be viewed by others. By setting your repositories to be viewed publicly, you agree to allow others to view and "fork" your repositories (this means that others may make their own copies of Content from your repositories in repositories they control).
- If you set your pages and repositories to be viewed publicly, you grant each User of Your Gitea Instance a nonexclusive, worldwide license to use, display, and perform Your Content through the Your Gitea Instance Service and to reproduce Your Content solely on Your Gitea Instance as permitted through Your Gitea Instance's functionality (for example, through forking). You may grant further rights if you adopt a license. If you are uploading Content you did not create or own, you are responsible for ensuring that the Content you upload is licensed under terms that grant these permissions to other Your Gitea Instance Users.
+ If you set your pages and repositories to be viewed publicly, you grant each User of Your Forgejo Instance a nonexclusive, worldwide license to use, display, and perform Your Content through the Your Forgejo Instance Service and to reproduce Your Content solely on Your Forgejo Instance as permitted through Your Forgejo Instance's functionality (for example, through forking). You may grant further rights if you adopt a license. If you are uploading Content you did not create or own, you are responsible for ensuring that the Content you upload is licensed under terms that grant these permissions to other Your Forgejo Instance Users.
@@ -97,7 +97,7 @@
You retain all moral rights to Your Content that you upload, publish, or submit to any part of the Service, including the rights of integrity and attribution. However, you waive these rights and agree not to assert them against us, to enable us to reasonably exercise the rights granted above, but not otherwise.
- To the extent this agreement is not enforceable by applicable law, you grant Your Gitea Instance the rights we need to use Your Content without attribution and to make reasonable adaptations of Your Content as necessary to render the Website and provide the Service.
+ To the extent this agreement is not enforceable by applicable law, you grant Your Forgejo Instance the rights we need to use Your Content without attribution and to make reasonable adaptations of Your Content as necessary to render the Website and provide the Service.
@@ -106,27 +106,27 @@
Some Accounts may have private repositories, which allow the User to control access to Content.
- Your Gitea Instance considers the contents of private repositories to be confidential to you. Your Gitea Instance will protect the contents of private repositories from unauthorized use, access, or disclosure in the same manner that we would use to protect our own confidential information of a similar nature and in no event with less than a reasonable degree of care.
+ Your Forgejo Instance considers the contents of private repositories to be confidential to you. Your Forgejo Instance will protect the contents of private repositories from unauthorized use, access, or disclosure in the same manner that we would use to protect our own confidential information of a similar nature and in no event with less than a reasonable degree of care.
- Your Gitea Instance employees may only access the content of your private repositories in the following situations:
+ Your Forgejo Instance employees may only access the content of your private repositories in the following situations:
- With your consent and knowledge, for support reasons. If Your Gitea Instance accesses a private repository for support reasons, we will only do so with the ownerโs consent and knowledge.
- When access is required for security reasons, including when access is required to maintain ongoing confidentiality, integrity, availability and resilience of Your Gitea Instance's systems and Service.
+ With your consent and knowledge, for support reasons. If Your Forgejo Instance accesses a private repository for support reasons, we will only do so with the ownerโs consent and knowledge.
+ When access is required for security reasons, including when access is required to maintain ongoing confidentiality, integrity, availability and resilience of Your Forgejo Instance's systems and Service.
- You may choose to enable additional access to your private repositories. For example: You may enable various Your Gitea Instance services or features that require additional rights to Your Content in private repositories. These rights may vary depending on the service or feature, but Your Gitea Instance will continue to treat your private repository Content as confidential. If those services or features require rights in addition to those we need to provide the Your Gitea Instance Service, we will provide an explanation of those rights.
+ You may choose to enable additional access to your private repositories. For example: You may enable various Your Forgejo Instance services or features that require additional rights to Your Content in private repositories. These rights may vary depending on the service or feature, but Your Forgejo Instance will continue to treat your private repository Content as confidential. If those services or features require rights in addition to those we need to provide the Your Forgejo Instance Service, we will provide an explanation of those rights.
Copyright Infringement and DMCA Policy
- If you are copyright owner and believe that content on our website violates your copyright, please contact us at copyright@your-gitea-instance . Please note that before sending a takedown notice, consider legal uses (such as fair use and licensed use); and legal consequences for sending false notices.
+ If you are copyright owner and believe that content on our website violates your copyright, please contact us at copyright@your-forgejo-instance . Please note that before sending a takedown notice, consider legal uses (such as fair use and licensed use); and legal consequences for sending false notices.
Intellectual Properties and COPYING
- Your Gitea Instance and our licensors, vendors, agents, and/or our content providers retain ownership of all intellectual property rights of any kind related to the Website and Service. We reserve all rights that are not expressly granted to you under this Agreement or by law. The look and feel of the Website and Service is copyright ยฉ Your Gitea Instance. All rights reserved.
+ Your Forgejo Instance and our licensors, vendors, agents, and/or our content providers retain ownership of all intellectual property rights of any kind related to the Website and Service. We reserve all rights that are not expressly granted to you under this Agreement or by law. The look and feel of the Website and Service is copyright ยฉ Your Forgejo Instance. All rights reserved.
If you'd like to use our trademarks, you must follow all of our trademark guidelines.
@@ -134,13 +134,13 @@
API Terms
- Abuse or excessively frequent requests to Your Gitea Instance via the API may result in the temporary or permanent suspension of your Account's access to the API. Your Gitea Instance, in our sole discretion, will determine abuse or excessive usage of the API. We will make a reasonable attempt to warn you via email prior to suspension.
+ Abuse or excessively frequent requests to Your Forgejo Instance via the API may result in the temporary or permanent suspension of your Account's access to the API. Your Forgejo Instance, in our sole discretion, will determine abuse or excessive usage of the API. We will make a reasonable attempt to warn you via email prior to suspension.
- You may not share API tokens to exceed Your Gitea Instance's rate limitations.
+ You may not share API tokens to exceed Your Forgejo Instance's rate limitations.
- You may not use the API to download data or Content from Your Gitea Instance for spamming purposes, including for the purposes of selling Your Gitea Instance users' personal information, such as to recruiters, headhunters, and job boards.
+ You may not use the API to download data or Content from Your Forgejo Instance for spamming purposes, including for the purposes of selling Your Forgejo Instance users' personal information, such as to recruiters, headhunters, and job boards.
- All use of the Your Gitea Instance API is subject to these Terms of Service and the Your Gitea Instance Privacy Statement.
+ All use of the Your Forgejo Instance API is subject to these Terms of Service and the Your Forgejo Instance Privacy Statement.
However, we may provide subscription-based access to our API for Users who need high-throughput access or reselling our Service.
@@ -149,7 +149,7 @@
Account Cancellation
- It is your responsibility to properly cancel your Account with Your Gitea Instance. You can cancel your Account at any time by going into your Settings in the global navigation bar at the top of the screen. The Account screen provides a simple, no questions asked cancellation link. We are not able to cancel Accounts in response to an email or phone request.
+ It is your responsibility to properly cancel your Account with Your Forgejo Instance. You can cancel your Account at any time by going into your Settings in the global navigation bar at the top of the screen. The Account screen provides a simple, no questions asked cancellation link. We are not able to cancel Accounts in response to an email or phone request.
Upon Cancellation
@@ -161,7 +161,7 @@
We May Terminate
- Your Gitea Instance has the right to suspend or terminate your access to all or any part of the Website at any time, with or without cause, with or without notice, effective immediately. Your Gitea Instance reserves the right to refuse service to anyone for any reason at any time.
+ Your Forgejo Instance has the right to suspend or terminate your access to all or any part of the Website at any time, with or without cause, with or without notice, effective immediately. Your Forgejo Instance reserves the right to refuse service to anyone for any reason at any time.
Survival
@@ -175,7 +175,7 @@
Legal Notices to Us Must Be in Writing
- Communications made through email or Your Gitea Instance Support's messaging system will not constitute legal notice to Your Gitea Instance or any of its officers, employees, agents or representatives in any situation where notice to Your Gitea Instance is required by contract or any law or regulation. Legal notice to Your Gitea Instance must be in writing and served on Your Gitea Instance's legal agent.
+ Communications made through email or Your Forgejo Instance Support's messaging system will not constitute legal notice to Your Forgejo Instance or any of its officers, employees, agents or representatives in any situation where notice to Your Forgejo Instance is required by contract or any law or regulation. Legal notice to Your Forgejo Instance must be in writing and served on Your Forgejo Instance's legal agent.
No Phone Support
@@ -183,9 +183,9 @@
Disclaimer of Warranties
- Your Gitea Instance provides the Website and the Service โas isโ and โas available,โ without warranty of any kind. Without limiting this, we expressly disclaim all warranties, whether express, implied or statutory, regarding the Website and the Service including without limitation any warranty of merchantability, fitness for a particular purpose, title, security, accuracy and non-infringement.
+ Your Forgejo Instance provides the Website and the Service โas isโ and โas available,โ without warranty of any kind. Without limiting this, we expressly disclaim all warranties, whether express, implied or statutory, regarding the Website and the Service including without limitation any warranty of merchantability, fitness for a particular purpose, title, security, accuracy and non-infringement.
- Your Gitea Instance does not warrant that the Service will meet your requirements; that the Service will be uninterrupted, timely, secure, or error-free; that the information provided through the Service is accurate, reliable or correct; that any defects or errors will be corrected; that the Service will be available at any particular time or location; or that the Service is free of viruses or other harmful components. You assume full responsibility and risk of loss resulting from your downloading and/or use of files, information, content or other material obtained from the Service.
+ Your Forgejo Instance does not warrant that the Service will meet your requirements; that the Service will be uninterrupted, timely, secure, or error-free; that the information provided through the Service is accurate, reliable or correct; that any defects or errors will be corrected; that the Service will be available at any particular time or location; or that the Service is free of viruses or other harmful components. You assume full responsibility and risk of loss resulting from your downloading and/or use of files, information, content or other material obtained from the Service.
Limitation of Liability
@@ -212,9 +212,9 @@
Release and Indemnification
- If you have a dispute with one or more Users, you agree to release Your Gitea Instance from any and all claims, demands and damages (actual and consequential) of every kind and nature, known and unknown, arising out of or in any way connected with such disputes.
+ If you have a dispute with one or more Users, you agree to release Your Forgejo Instance from any and all claims, demands and damages (actual and consequential) of every kind and nature, known and unknown, arising out of or in any way connected with such disputes.
- You agree to indemnify us, defend us, and hold us harmless from and against any and all claims, liabilities, and expenses, including attorneysโ fees, arising out of your use of the Website and the Service, including but not limited to your violation of this Agreement, provided that Your Gitea Instance (1) promptly gives you written notice of the claim, demand, suit or proceeding; (2) gives you sole control of the defense and settlement of the claim, demand, suit or proceeding (provided that you may not settle any claim, demand, suit or proceeding unless the settlement unconditionally releases Your Gitea Instance of all liability); and (3) provides to you all reasonable assistance, at your expense.
+ You agree to indemnify us, defend us, and hold us harmless from and against any and all claims, liabilities, and expenses, including attorneysโ fees, arising out of your use of the Website and the Service, including but not limited to your violation of this Agreement, provided that Your Forgejo Instance (1) promptly gives you written notice of the claim, demand, suit or proceeding; (2) gives you sole control of the defense and settlement of the claim, demand, suit or proceeding (provided that you may not settle any claim, demand, suit or proceeding unless the settlement unconditionally releases Your Forgejo Instance of all liability); and (3) provides to you all reasonable assistance, at your expense.
Changes to These Terms
@@ -224,22 +224,22 @@
Governing Law
- Except to the extent applicable law provides otherwise, this Agreement between you and us and any access to or use of the Website or the Service are governed by (national laws of country/state where Gitea is deployed) and (regional laws of locality where Gitea is deployed), without regard to conflict of law provisions. You and Your Gitea Instance agree to submit to the exclusive jurisdiction and venue of the courts located in (locality where Gitea is deployed).
+ Except to the extent applicable law provides otherwise, this Agreement between you and us and any access to or use of the Website or the Service are governed by (national laws of country/state where Forgejo is deployed) and (regional laws of locality where Forgejo is deployed), without regard to conflict of law provisions. You and Your Forgejo Instance agree to submit to the exclusive jurisdiction and venue of the courts located in (locality where Forgejo is deployed).
Non-Assignability
- Your Gitea Instance may assign or delegate these Terms of Service and/or our Privacy Policy in whole or in part, to any person or entity at any time with or without your consent, including the license granted in User-Generated Content . You may not assign or delegate any rights or obligations under the Terms of Service or Privacy Statement without our prior written consent, and any unauthorized assignment and delegation by you is void.
+ Your Forgejo Instance may assign or delegate these Terms of Service and/or our Privacy Policy in whole or in part, to any person or entity at any time with or without your consent, including the license granted in User-Generated Content . You may not assign or delegate any rights or obligations under the Terms of Service or Privacy Statement without our prior written consent, and any unauthorized assignment and delegation by you is void.
Severablity, No Waiver, and Survival
- If any part of this Agreement is held invalid or unenforceable, that portion of the Agreement will be construed to reflect the partiesโ original intent. The remaining portions will remain in full force and effect. Any failure on the part of Your Gitea Instance to enforce any provision of this Agreement will not be considered a waiver of our right to enforce such provision. Our rights under this Agreement will survive any termination of this Agreement.
+ If any part of this Agreement is held invalid or unenforceable, that portion of the Agreement will be construed to reflect the partiesโ original intent. The remaining portions will remain in full force and effect. Any failure on the part of Your Forgejo Instance to enforce any provision of this Agreement will not be considered a waiver of our right to enforce such provision. Our rights under this Agreement will survive any termination of this Agreement.
Amendments and Complete Agreement
- This Agreement may only be modified by a written amendment signed by an authorized representative of Your Gitea Instance, or by the posting by Your Gitea Instance of a revised version in accordance with Changes to These Terms . These Terms of Service, together with the Your Gitea Instance Privacy Policy, represent the complete and exclusive statement of the agreement between you and us. This Agreement supersedes any proposal or prior agreement oral or written, and any other communications between you and Your Gitea Instance relating to the subject matter of these terms including any confidentiality or nondisclosure agreements.
+ This Agreement may only be modified by a written amendment signed by an authorized representative of Your Forgejo Instance, or by the posting by Your Forgejo Instance of a revised version in accordance with Changes to These Terms . These Terms of Service, together with the Your Forgejo Instance Privacy Policy, represent the complete and exclusive statement of the agreement between you and us. This Agreement supersedes any proposal or prior agreement oral or written, and any other communications between you and Your Forgejo Instance relating to the subject matter of these terms including any confidentiality or nondisclosure agreements.
Contact
- If you have questions about these Terms of Service, you can contact our support .
+ If you have questions about these Terms of Service, you can contact our support .
diff --git a/contrib/systemd/forgejo.service b/contrib/systemd/forgejo.service
index 04ef69adc0..ee019e11ea 100644
--- a/contrib/systemd/forgejo.service
+++ b/contrib/systemd/forgejo.service
@@ -61,7 +61,7 @@ WorkingDirectory=/var/lib/forgejo/
#RuntimeDirectory=forgejo
ExecStart=/usr/local/bin/forgejo web --config /etc/forgejo/app.ini
Restart=always
-Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/forgejo
+Environment=USER=git HOME=/home/git FORGEJO_WORK_DIR=/var/lib/forgejo
# If you install Git to directory prefix other than default PATH (which happens
# for example if you install other versions of Git side-to-side with
# distribution version), uncomment below line and add that prefix to PATH
diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini
index cdb7629887..b76cf7df80 100644
--- a/custom/conf/app.example.ini
+++ b/custom/conf/app.example.ini
@@ -328,6 +328,10 @@ RUN_USER = ; git
;; Maximum number of locks returned per page
;LFS_LOCKS_PAGING_NUM = 50
;;
+;; When clients make lfs batch requests, reject them if there are more pointers than this number
+;; zero means 'unlimited'
+;LFS_MAX_BATCH_SIZE = 0
+;;
;; Allow graceful restarts using SIGHUP to fork
;ALLOW_GRACEFUL_RESTARTS = true
;;
@@ -349,16 +353,25 @@ RUN_USER = ; git
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
-;; Database to use. Either "mysql", "postgres", "mssql" or "sqlite3".
+;; Database to use. Either "sqlite3", "mySQL" or "postgres".
+;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; SQLite Configuration
+;;
+DB_TYPE = sqlite3
+;PATH= ; defaults to data/forgejo.db
+;SQLITE_TIMEOUT = ; Query timeout defaults to: 500
+;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; MySQL Configuration
;;
-DB_TYPE = mysql
-HOST = 127.0.0.1:3306 ; can use socket e.g. /var/run/mysqld/mysqld.sock
-NAME = gitea
-USER = root
+;DB_TYPE = mysql
+;HOST = 127.0.0.1:3306 ; can use socket e.g. /var/run/mysqld/mysqld.sock
+;NAME = gitea
+;USER = root
;PASSWD = ;Use PASSWD = `your password` for quoting if you use special characters in the password.
;SSL_MODE = false ; either "false" (default), "true", or "skip-verify"
;CHARSET_COLLATION = ; Empty as default, Gitea will try to find a case-sensitive collation. Don't change it unless you clearly know what you need.
@@ -377,26 +390,6 @@ USER = root
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
-;; SQLite Configuration
-;;
-;DB_TYPE = sqlite3
-;PATH= ; defaults to data/forgejo.db
-;SQLITE_TIMEOUT = ; Query timeout defaults to: 500
-;SQLITE_JOURNAL_MODE = ; defaults to sqlite database default (often DELETE), can be used to enable WAL mode. https://www.sqlite.org/pragma.html#pragma_journal_mode
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; MSSQL Configuration
-;;
-;DB_TYPE = mssql
-;HOST = 172.17.0.2:1433
-;NAME = gitea
-;USER = SA
-;PASSWD = MwantsaSecurePassword1
-;CHARSET_COLLATION = ; Empty as default, Gitea will try to find a case-sensitive collation. Don't change it unless you clearly know what you need.
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
;; Other settings
;;
;; For iterate buffer, default is 50
@@ -529,7 +522,8 @@ INTERNAL_TOKEN =
;; HMAC to encode urls with, it **is required** if camo is enabled.
;HMAC_KEY =
;; Set to true to use camo for https too lese only non https urls are proxyed
-;ALLWAYS = false
+;; ALLWAYS is deprecated and will be removed in the future
+;ALWAYS = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -635,7 +629,7 @@ LEVEL = Info
;[log.%(WriterMode)]
;MODE=console/file/conn/...
;LEVEL=
-;FLAGS = stdflags
+;FLAGS = stdflags or journald
;EXPRESSION =
;PREFIX =
;COLORIZE = false
@@ -732,6 +726,7 @@ LEVEL = Info
;CLONE = 300
;PULL = 300
;GC = 60
+;GREP = 2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Git config options
@@ -906,6 +901,9 @@ LEVEL = Info
;; Show Registration button
;SHOW_REGISTRATION_BUTTON = true
;;
+;; Whether to allow internal signin
+; ENABLE_INTERNAL_SIGNIN = true
+;;
;; Show milestones dashboard page - a view of all the user's milestones
;SHOW_MILESTONES_DASHBOARD_PAGE = true
;;
@@ -923,6 +921,24 @@ LEVEL = Info
;; Valid site url schemes for user profiles
;VALID_SITE_URL_SCHEMES=http,https
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;[service.explore]
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Only allow signed in users to view the explore pages.
+;REQUIRE_SIGNIN_VIEW = false
+;;
+;; Disable the users explore page.
+;DISABLE_USERS_PAGE = false
+;;
+;; Disable the organizations explore page.
+;DISABLE_ORGANIZATIONS_PAGE = false
+;;
+;; Disable the code explore page.
+;DISABLE_CODE_PAGE = false
+;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -1727,6 +1743,10 @@ LEVEL = Info
;; Sometimes it is helpful to use a different address on the envelope. Set this to use ENVELOPE_FROM as the from on the envelope. Set to `<>` to send an empty address.
;ENVELOPE_FROM =
;;
+;; If gitea sends mails on behave of users, it will just use the name also displayed in the WebUI. If you want e.g. `Mister X (by CodeIt) `,
+;; set it to `{{ .DisplayName }} (by {{ .AppName }})`. Available Variables: `.DisplayName`, `.AppName` and `.Domain`.
+;FROM_DISPLAY_NAME_FORMAT = {{ .DisplayName }}
+;;
;; Mailer user name and password, if required by provider.
;USER =
;;
@@ -1921,7 +1941,7 @@ LEVEL = Info
;ENABLED = true
;;
;; Comma-separated list of allowed file extensions (`.zip`), mime types (`text/plain`) or wildcard type (`image/*`, `audio/*`, `video/*`). Empty value or `*/*` allows all types.
-;ALLOWED_TYPES = .cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.xls,.xlsx,.zip
+;ALLOWED_TYPES = .avif,.cpuprofile,.csv,.dmp,.docx,.fodg,.fodp,.fods,.fodt,.gif,.gz,.jpeg,.jpg,.json,.jsonc,.log,.md,.mov,.mp4,.odf,.odg,.odp,.ods,.odt,.patch,.pdf,.png,.pptx,.svg,.tgz,.txt,.webm,.webp,.xls,.xlsx,.zip
;;
;; Max size of each file. Defaults to 2048MB
;MAX_SIZE = 2048
@@ -1959,7 +1979,7 @@ LEVEL = Info
;; Url lookup for the minio bucket only available when STORAGE_TYPE is `minio`
;; Available values: auto, dns, path
;; If empty, it behaves the same as "auto" was set
-;MINIO_BUCKET_LOOKUP =
+;MINIO_BUCKET_LOOKUP =
;;
;; Minio location to create bucket only available when STORAGE_TYPE is `minio`
;MINIO_LOCATION = us-east-1
@@ -2290,7 +2310,7 @@ LEVEL = Info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Delete all old actions from database
+;; Delete all old activities from database
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;[cron.delete_old_actions]
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2387,8 +2407,8 @@ LEVEL = Info
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The first locale will be used as the default if user browser's language doesn't match any locale in the list.
-;LANGS = en-US,zh-CN,zh-HK,zh-TW,de-DE,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg-BG,it-IT,fi-FI,tr-TR,cs-CZ,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID,ml-IN
-;NAMES = English,็ฎไฝไธญๆ,็น้ซไธญๆ๏ผ้ฆๆธฏ๏ผ,็น้ซไธญๆ๏ผๅฐ็ฃ๏ผ,Deutsch,Franรงais,Nederlands,Latvieลกu,ะ ัััะบะธะน,ะฃะบัะฐัะฝััะบะฐ,ๆฅๆฌ่ช,Espaรฑol,Portuguรชs do Brasil,Portuguรชs de Portugal,Polski,ะัะปะณะฐััะบะธ,Italiano,Suomi,Tรผrkรงe,ฤeลกtina,ะกัะฟัะบะธ,Svenska,ํ๊ตญ์ด,ฮฮปฮปฮทฮฝฮนฮบฮฌ,ูุงุฑุณ,Magyar nyelv,Bahasa Indonesia,เดฎเดฒเดฏเดพเดณเด
+;LANGS = en-US,zh-CN,zh-HK,zh-TW,da,de-DE,nds,fr-FR,nl-NL,lv-LV,ru-RU,uk-UA,ja-JP,es-ES,pt-BR,pt-PT,pl-PL,bg,it-IT,fi-FI,fil,eo,tr-TR,cs-CZ,sl,sv-SE,ko-KR,el-GR,fa-IR,hu-HU,id-ID
+;NAMES = English,็ฎไฝไธญๆ,็น้ซไธญๆ๏ผ้ฆๆธฏ๏ผ,็น้ซไธญๆ๏ผๅฐ็ฃ๏ผ,Dansk,Deutsch,Plattdรผรผtsch,Franรงais,Nederlands,Latvieลกu,ะ ัััะบะธะน,ะฃะบัะฐัะฝััะบะฐ,ๆฅๆฌ่ช,Espaรฑol,Portuguรชs do Brasil,Portuguรชs de Portugal,Polski,ะัะปะณะฐััะบะธ,Italiano,Suomi,Filipino,Esperanto,Tรผrkรงe,ฤeลกtina,Slovenลกฤina,Svenska,ํ๊ตญ์ด,ฮฮปฮปฮทฮฝฮนฮบฮฌ,ูุงุฑุณ,Magyar nyelv,Bahasa Indonesia
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2599,6 +2619,8 @@ LEVEL = Info
;LIMIT_SIZE_SWIFT = -1
;; Maximum size of a Vagrant upload (`-1` means no limits, format `1000`, `1 MB`, `1 GiB`)
;LIMIT_SIZE_VAGRANT = -1
+;; Enable RPM re-signing by default. (It will overwrite the old signature ,using v4 format, not compatible with CentOS 6 or older)
+;DEFAULT_RPM_SIGN_ENABLED = false
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -2646,6 +2668,27 @@ LEVEL = Info
;; override the minio base path if storage type is minio
;MINIO_BASE_PATH = lfs/
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; settings for Gitea's LFS client (eg: mirroring an upstream lfs endpoint)
+;;
+;[lfs_client]
+;; Limit the number of pointers in each batch request to this number
+;BATCH_SIZE = 20
+;; Limit the number of concurrent upload/download operations within a batch
+;BATCH_OPERATION_CONCURRENCY = 8
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;[annex]
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;
+;; Whether git-annex is enabled; defaults to false
+;ENABLED = false
+;; Whether to disable p2phttp support; default is the same as repository.DISABLE_HTTP_GIT
+;DISABLE_P2PHTTP = false
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; settings for packages, will override storage setting
@@ -2680,7 +2723,7 @@ LEVEL = Info
;; Url lookup for the minio bucket only available when STORAGE_TYPE is `minio`
;; Available values: auto, dns, path
;; If empty, it behaves the same as "auto" was set
-;MINIO_BUCKET_LOOKUP =
+;MINIO_BUCKET_LOOKUP =
;;
;; Minio location to create bucket only available when STORAGE_TYPE is `minio`
;MINIO_LOCATION = us-east-1
@@ -2704,7 +2747,15 @@ LEVEL = Info
;ENABLED = true
;; Default address to get action plugins, e.g. the default value means downloading from "https://code.forgejo.org/actions/checkout" for "uses: actions/checkout@v3"
;DEFAULT_ACTIONS_URL = https://code.forgejo.org
-;; Default artifact retention time in days, default is 90 days
+;; Logs retention time in days. Old logs will be deleted after this period.
+;LOG_RETENTION_DAYS = 365
+;; Log compression type, `none` for no compression, `zstd` for zstd compression.
+;; Other compression types like `gzip` are NOT supported, since seekable stream is required for log view.
+;; It's always recommended to use compression when using local disk as log storage if CPU or memory is not a bottleneck.
+;; And for object storage services like S3, which is billed for requests, it would cause extra 2 times of get requests for each log view.
+;; But it will save storage space and network bandwidth, so it's still recommended to use compression.
+;LOG_COMPRESSION = zstd
+;; Default artifact retention time in days. Artifacts could have their own retention periods by setting the `retention-days` option in `actions/upload-artifact` step.
;ARTIFACT_RETENTION_DAYS = 90
;; Timeout to stop the task which have running status, but haven't been updated for a long time
;ZOMBIE_TASK_TIMEOUT = 10m
diff --git a/docker/root/usr/bin/entrypoint b/docker/root/usr/bin/entrypoint
index d9dbb3ebe0..08587fc4f4 100755
--- a/docker/root/usr/bin/entrypoint
+++ b/docker/root/usr/bin/entrypoint
@@ -37,5 +37,5 @@ done
if [ $# -gt 0 ]; then
exec "$@"
else
- exec /bin/s6-svscan /etc/s6
+ exec /usr/bin/s6-svscan /etc/s6
fi
diff --git a/eslint.config.mjs b/eslint.config.mjs
new file mode 100644
index 0000000000..17f461a8f4
--- /dev/null
+++ b/eslint.config.mjs
@@ -0,0 +1,1174 @@
+import eslintCommunityEslintPluginEslintComments from '@eslint-community/eslint-plugin-eslint-comments';
+import stylisticEslintPluginJs from '@stylistic/eslint-plugin-js';
+import vitest from '@vitest/eslint-plugin';
+import arrayFunc from 'eslint-plugin-array-func';
+import eslintPluginImportX from 'eslint-plugin-import-x';
+import noJquery from 'eslint-plugin-no-jquery';
+import noUseExtendNative from 'eslint-plugin-no-use-extend-native';
+import regexp from 'eslint-plugin-regexp';
+import sonarjs from 'eslint-plugin-sonarjs';
+import unicorn from 'eslint-plugin-unicorn';
+import playwright from 'eslint-plugin-playwright';
+import vitestGlobals from 'eslint-plugin-vitest-globals';
+import wc from 'eslint-plugin-wc';
+import globals from 'globals';
+import vue from 'eslint-plugin-vue';
+import vueScopedCss from 'eslint-plugin-vue-scoped-css';
+import toml from 'eslint-plugin-toml';
+import tseslint from 'typescript-eslint';
+
+export default tseslint.config(
+ ...tseslint.configs.recommended,
+ eslintPluginImportX.flatConfigs.typescript,
+ {
+ ignores: ['web_src/js/vendor', 'web_src/fomantic', 'public/assets/js', 'tests/e2e/reports/'],
+ },
+ {
+ plugins: {
+ '@eslint-community/eslint-comments': eslintCommunityEslintPluginEslintComments,
+ '@stylistic/js': stylisticEslintPluginJs,
+ '@vitest': vitest,
+ 'array-func': arrayFunc,
+ 'no-jquery': noJquery,
+ 'no-use-extend-native': noUseExtendNative,
+ regexp,
+ sonarjs,
+ unicorn,
+ playwright,
+ toml,
+ 'vitest-globals': vitestGlobals,
+ vue,
+ 'vue-scoped-css': vueScopedCss,
+ wc,
+ },
+
+ linterOptions: {
+ reportUnusedDisableDirectives: true,
+ },
+
+ languageOptions: {
+ globals: {
+ ...globals.node,
+ },
+ parserOptions: {
+ ecmaVersion: 'latest',
+ },
+
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ },
+ rules: {
+ '@typescript-eslint/no-unused-vars': 'off', // TODO: enable this rule again
+
+ '@eslint-community/eslint-comments/disable-enable-pair': [2],
+ '@eslint-community/eslint-comments/no-aggregating-enable': [2],
+ '@eslint-community/eslint-comments/no-duplicate-disable': [2],
+ '@eslint-community/eslint-comments/no-restricted-disable': [0],
+ '@eslint-community/eslint-comments/no-unlimited-disable': [2],
+ '@eslint-community/eslint-comments/no-unused-disable': [2],
+ '@eslint-community/eslint-comments/no-unused-enable': [2],
+ '@eslint-community/eslint-comments/no-use': [0],
+ '@eslint-community/eslint-comments/require-description': [0],
+ '@stylistic/js/array-bracket-newline': [0],
+ '@stylistic/js/array-bracket-spacing': [2, 'never'],
+ '@stylistic/js/array-element-newline': [0],
+ '@stylistic/js/arrow-parens': [2, 'always'],
+
+ '@stylistic/js/arrow-spacing': [2, {
+ before: true,
+ after: true,
+ }],
+
+ '@stylistic/js/block-spacing': [0],
+
+ '@stylistic/js/brace-style': [2, '1tbs', {
+ allowSingleLine: true,
+ }],
+
+ '@stylistic/js/comma-dangle': [2, 'always-multiline'],
+
+ '@stylistic/js/comma-spacing': [2, {
+ before: false,
+ after: true,
+ }],
+
+ '@stylistic/js/comma-style': [2, 'last'],
+ '@stylistic/js/computed-property-spacing': [2, 'never'],
+ '@stylistic/js/dot-location': [2, 'property'],
+ '@stylistic/js/eol-last': [2],
+ '@stylistic/js/function-call-spacing': [2, 'never'],
+ '@stylistic/js/function-call-argument-newline': [0],
+ '@stylistic/js/function-paren-newline': [0],
+ '@stylistic/js/generator-star-spacing': [0],
+ '@stylistic/js/implicit-arrow-linebreak': [0],
+
+ '@stylistic/js/indent': [2, 2, {
+ ignoreComments: true,
+ SwitchCase: 1,
+ }],
+
+ '@stylistic/js/key-spacing': [2],
+ '@stylistic/js/keyword-spacing': [2],
+ '@stylistic/js/linebreak-style': [2, 'unix'],
+ '@stylistic/js/lines-around-comment': [0],
+ '@stylistic/js/lines-between-class-members': [0],
+ '@stylistic/js/max-len': [0],
+ '@stylistic/js/max-statements-per-line': [0],
+ '@stylistic/js/multiline-ternary': [0],
+ '@stylistic/js/new-parens': [2],
+ '@stylistic/js/newline-per-chained-call': [0],
+ '@stylistic/js/no-confusing-arrow': [0],
+ '@stylistic/js/no-extra-parens': [0],
+ '@stylistic/js/no-extra-semi': [2],
+ '@stylistic/js/no-floating-decimal': [0],
+ '@stylistic/js/no-mixed-operators': [0],
+ '@stylistic/js/no-mixed-spaces-and-tabs': [2],
+
+ '@stylistic/js/no-multi-spaces': [2, {
+ ignoreEOLComments: true,
+
+ exceptions: {
+ Property: true,
+ },
+ }],
+
+ '@stylistic/js/no-multiple-empty-lines': [2, {
+ max: 1,
+ maxEOF: 0,
+ maxBOF: 0,
+ }],
+
+ '@stylistic/js/no-tabs': [2],
+ '@stylistic/js/no-trailing-spaces': [2],
+ '@stylistic/js/no-whitespace-before-property': [2],
+ '@stylistic/js/nonblock-statement-body-position': [2],
+ '@stylistic/js/object-curly-newline': [0],
+ '@stylistic/js/object-curly-spacing': [2, 'never'],
+ '@stylistic/js/object-property-newline': [0],
+ '@stylistic/js/one-var-declaration-per-line': [0],
+ '@stylistic/js/operator-linebreak': [2, 'after'],
+ '@stylistic/js/padded-blocks': [2, 'never'],
+ '@stylistic/js/padding-line-between-statements': [0],
+ '@stylistic/js/quote-props': [0],
+
+ '@stylistic/js/quotes': [2, 'single', {
+ avoidEscape: true,
+ allowTemplateLiterals: true,
+ }],
+
+ '@stylistic/js/rest-spread-spacing': [2, 'never'],
+
+ '@stylistic/js/semi': [2, 'always', {
+ omitLastInOneLineBlock: true,
+ }],
+
+ '@stylistic/js/semi-spacing': [2, {
+ before: false,
+ after: true,
+ }],
+
+ '@stylistic/js/semi-style': [2, 'last'],
+ '@stylistic/js/space-before-blocks': [2, 'always'],
+
+ '@stylistic/js/space-before-function-paren': [2, {
+ anonymous: 'ignore',
+ named: 'never',
+ asyncArrow: 'always',
+ }],
+
+ '@stylistic/js/space-in-parens': [2, 'never'],
+ '@stylistic/js/space-infix-ops': [2],
+ '@stylistic/js/space-unary-ops': [2],
+ '@stylistic/js/spaced-comment': [2, 'always'],
+ '@stylistic/js/switch-colon-spacing': [2],
+ '@stylistic/js/template-curly-spacing': [2, 'never'],
+ '@stylistic/js/template-tag-spacing': [2, 'never'],
+ '@stylistic/js/wrap-iife': [2, 'inside'],
+ '@stylistic/js/wrap-regex': [0],
+ '@stylistic/js/yield-star-spacing': [2, 'after'],
+ 'accessor-pairs': [2],
+
+ 'array-callback-return': [2, {
+ checkForEach: true,
+ }],
+
+ 'array-func/avoid-reverse': [2],
+ 'array-func/from-map': [2],
+ 'array-func/no-unnecessary-this-arg': [2],
+ 'array-func/prefer-array-from': [2],
+ 'array-func/prefer-flat-map': [0],
+ 'array-func/prefer-flat': [0],
+ 'arrow-body-style': [0],
+ 'block-scoped-var': [2],
+ camelcase: [0],
+ 'capitalized-comments': [0],
+ 'class-methods-use-this': [0],
+ complexity: [0],
+ 'consistent-return': [0],
+ 'consistent-this': [0],
+ 'constructor-super': [2],
+ curly: [0],
+ 'default-case-last': [2],
+ 'default-case': [0],
+ 'default-param-last': [0],
+ 'dot-notation': [0],
+ eqeqeq: [2],
+ 'for-direction': [2],
+ 'func-name-matching': [2],
+ 'func-names': [0],
+ 'func-style': [0],
+ 'getter-return': [2],
+ 'grouped-accessor-pairs': [2],
+ 'guard-for-in': [0],
+ 'id-blacklist': [0],
+ 'id-length': [0],
+ 'id-match': [0],
+ 'init-declarations': [0],
+ 'line-comment-position': [0],
+ 'logical-assignment-operators': [0],
+ 'max-classes-per-file': [0],
+ 'max-depth': [0],
+ 'max-lines-per-function': [0],
+ 'max-lines': [0],
+ 'max-nested-callbacks': [0],
+ 'max-params': [0],
+ 'max-statements': [0],
+ 'multiline-comment-style': [2, 'separate-lines'],
+ 'new-cap': [0],
+ 'no-alert': [0],
+ 'no-array-constructor': [2],
+ 'no-async-promise-executor': [0],
+ 'no-await-in-loop': [0],
+ 'no-bitwise': [0],
+ 'no-buffer-constructor': [0],
+ 'no-caller': [2],
+ 'no-case-declarations': [2],
+ 'no-class-assign': [2],
+ 'no-compare-neg-zero': [2],
+ 'no-cond-assign': [2, 'except-parens'],
+
+ 'no-console': [1, {
+ allow: ['debug', 'info', 'warn', 'error'],
+ }],
+
+ 'no-const-assign': [2],
+ 'no-constant-binary-expression': [2],
+ 'no-constant-condition': [0],
+ 'no-constructor-return': [2],
+ 'no-continue': [0],
+ 'no-control-regex': [0],
+ 'no-debugger': [1],
+ 'no-delete-var': [2],
+ 'no-div-regex': [0],
+ 'no-dupe-args': [2],
+ 'no-dupe-class-members': [2],
+ 'no-dupe-else-if': [2],
+ 'no-dupe-keys': [2],
+ 'no-duplicate-case': [2],
+ 'no-duplicate-imports': [2],
+ 'no-else-return': [2],
+ 'no-empty-character-class': [2],
+ 'no-empty-function': [0],
+ 'no-empty-pattern': [2],
+ 'no-empty-static-block': [2],
+
+ 'no-empty': [2, {
+ allowEmptyCatch: true,
+ }],
+
+ 'no-eq-null': [2],
+ 'no-eval': [2],
+ 'no-ex-assign': [2],
+ 'no-extend-native': [2],
+ 'no-extra-bind': [2],
+ 'no-extra-boolean-cast': [2],
+ 'no-extra-label': [0],
+ 'no-fallthrough': [2],
+ 'no-func-assign': [2],
+ 'no-global-assign': [2],
+ 'no-implicit-coercion': [2],
+ 'no-implicit-globals': [0],
+ 'no-implied-eval': [2],
+ 'no-import-assign': [2],
+ 'no-inline-comments': [0],
+ 'no-inner-declarations': [2],
+ 'no-invalid-regexp': [2],
+ 'no-invalid-this': [0],
+ 'no-irregular-whitespace': [2],
+ 'no-iterator': [2],
+ 'no-jquery/no-ajax-events': [2],
+ 'no-jquery/no-ajax': [2],
+ 'no-jquery/no-and-self': [2],
+ 'no-jquery/no-animate-toggle': [2],
+ 'no-jquery/no-animate': [2],
+ 'no-jquery/no-append-html': [2],
+ 'no-jquery/no-attr': [2],
+ 'no-jquery/no-bind': [2],
+ 'no-jquery/no-box-model': [2],
+ 'no-jquery/no-browser': [2],
+ 'no-jquery/no-camel-case': [2],
+ 'no-jquery/no-class-state': [2],
+ 'no-jquery/no-class': [0],
+ 'no-jquery/no-clone': [2],
+ 'no-jquery/no-closest': [0],
+ 'no-jquery/no-constructor-attributes': [2],
+ 'no-jquery/no-contains': [2],
+ 'no-jquery/no-context-prop': [2],
+ 'no-jquery/no-css': [2],
+ 'no-jquery/no-data': [0],
+ 'no-jquery/no-deferred': [2],
+ 'no-jquery/no-delegate': [2],
+ 'no-jquery/no-each-collection': [0],
+ 'no-jquery/no-each-util': [0],
+ 'no-jquery/no-each': [0],
+ 'no-jquery/no-error-shorthand': [2],
+ 'no-jquery/no-error': [2],
+ 'no-jquery/no-escape-selector': [2],
+ 'no-jquery/no-event-shorthand': [2],
+ 'no-jquery/no-extend': [2],
+ 'no-jquery/no-fade': [2],
+ 'no-jquery/no-filter': [0],
+ 'no-jquery/no-find-collection': [0],
+ 'no-jquery/no-find-util': [2],
+ 'no-jquery/no-find': [0],
+ 'no-jquery/no-fx-interval': [2],
+ 'no-jquery/no-global-eval': [2],
+ 'no-jquery/no-global-selector': [0],
+ 'no-jquery/no-grep': [2],
+ 'no-jquery/no-has': [2],
+ 'no-jquery/no-hold-ready': [2],
+ 'no-jquery/no-html': [0],
+ 'no-jquery/no-in-array': [2],
+ 'no-jquery/no-is-array': [2],
+ 'no-jquery/no-is-empty-object': [2],
+ 'no-jquery/no-is-function': [2],
+ 'no-jquery/no-is-numeric': [2],
+ 'no-jquery/no-is-plain-object': [2],
+ 'no-jquery/no-is-window': [2],
+ 'no-jquery/no-is': [2],
+ 'no-jquery/no-jquery-constructor': [0],
+ 'no-jquery/no-live': [2],
+ 'no-jquery/no-load-shorthand': [2],
+ 'no-jquery/no-load': [2],
+ 'no-jquery/no-map-collection': [0],
+ 'no-jquery/no-map-util': [2],
+ 'no-jquery/no-map': [2],
+ 'no-jquery/no-merge': [2],
+ 'no-jquery/no-node-name': [2],
+ 'no-jquery/no-noop': [2],
+ 'no-jquery/no-now': [2],
+ 'no-jquery/no-on-ready': [2],
+ 'no-jquery/no-other-methods': [0],
+ 'no-jquery/no-other-utils': [2],
+ 'no-jquery/no-param': [2],
+ 'no-jquery/no-parent': [0],
+ 'no-jquery/no-parents': [2],
+ 'no-jquery/no-parse-html-literal': [2],
+ 'no-jquery/no-parse-html': [2],
+ 'no-jquery/no-parse-json': [2],
+ 'no-jquery/no-parse-xml': [2],
+ 'no-jquery/no-prop': [2],
+ 'no-jquery/no-proxy': [2],
+ 'no-jquery/no-ready-shorthand': [2],
+ 'no-jquery/no-ready': [2],
+ 'no-jquery/no-selector-prop': [2],
+ 'no-jquery/no-serialize': [2],
+ 'no-jquery/no-size': [2],
+ 'no-jquery/no-sizzle': [0],
+ 'no-jquery/no-slide': [2],
+ 'no-jquery/no-sub': [2],
+ 'no-jquery/no-support': [2],
+ 'no-jquery/no-text': [0],
+ 'no-jquery/no-trigger': [0],
+ 'no-jquery/no-trim': [2],
+ 'no-jquery/no-type': [2],
+ 'no-jquery/no-unique': [2],
+ 'no-jquery/no-unload-shorthand': [2],
+ 'no-jquery/no-val': [0],
+ 'no-jquery/no-visibility': [2],
+ 'no-jquery/no-when': [2],
+ 'no-jquery/no-wrap': [2],
+ 'no-jquery/variable-pattern': [2],
+ 'no-label-var': [2],
+ 'no-labels': [0],
+ 'no-lone-blocks': [2],
+ 'no-lonely-if': [0],
+ 'no-loop-func': [0],
+ 'no-loss-of-precision': [2],
+ 'no-magic-numbers': [0],
+ 'no-misleading-character-class': [2],
+ 'no-multi-assign': [0],
+ 'no-multi-str': [2],
+ 'no-negated-condition': [0],
+ 'no-nested-ternary': [0],
+ 'no-new-func': [2],
+ 'no-new-native-nonconstructor': [2],
+ 'no-new-object': [2],
+ 'no-new-symbol': [2],
+ 'no-new-wrappers': [2],
+ 'no-new': [0],
+ 'no-nonoctal-decimal-escape': [2],
+ 'no-obj-calls': [2],
+ 'no-octal-escape': [2],
+ 'no-octal': [2],
+ 'no-param-reassign': [0],
+ 'no-plusplus': [0],
+ 'no-promise-executor-return': [0],
+ 'no-proto': [2],
+ 'no-prototype-builtins': [2],
+ 'no-redeclare': [2],
+ 'no-regex-spaces': [2],
+ 'no-restricted-exports': [0],
+
+ 'no-restricted-globals': [
+ 2,
+ 'addEventListener',
+ 'blur',
+ 'close',
+ 'closed',
+ 'confirm',
+ 'defaultStatus',
+ 'defaultstatus',
+ 'error',
+ 'event',
+ 'external',
+ 'find',
+ 'focus',
+ 'frameElement',
+ 'frames',
+ 'history',
+ 'innerHeight',
+ 'innerWidth',
+ 'isFinite',
+ 'isNaN',
+ 'length',
+ 'location',
+ 'locationbar',
+ 'menubar',
+ 'moveBy',
+ 'moveTo',
+ 'name',
+ 'onblur',
+ 'onerror',
+ 'onfocus',
+ 'onload',
+ 'onresize',
+ 'onunload',
+ 'open',
+ 'opener',
+ 'opera',
+ 'outerHeight',
+ 'outerWidth',
+ 'pageXOffset',
+ 'pageYOffset',
+ 'parent',
+ 'print',
+ 'removeEventListener',
+ 'resizeBy',
+ 'resizeTo',
+ 'screen',
+ 'screenLeft',
+ 'screenTop',
+ 'screenX',
+ 'screenY',
+ 'scroll',
+ 'scrollbars',
+ 'scrollBy',
+ 'scrollTo',
+ 'scrollX',
+ 'scrollY',
+ 'self',
+ 'status',
+ 'statusbar',
+ 'stop',
+ 'toolbar',
+ 'top',
+ '__dirname',
+ '__filename',
+ ],
+
+ 'no-restricted-imports': [0],
+
+ 'no-restricted-syntax': [
+ 2,
+ 'WithStatement',
+ 'ForInStatement',
+ 'LabeledStatement',
+ 'SequenceExpression',
+ {
+ selector: "CallExpression[callee.name='fetch']",
+ message: 'use modules/fetch.js instead',
+ },
+ ],
+
+ 'no-return-assign': [0],
+ 'no-script-url': [2],
+
+ 'no-self-assign': [2, {
+ props: true,
+ }],
+
+ 'no-self-compare': [2],
+ 'no-sequences': [2],
+ 'no-setter-return': [2],
+ 'no-shadow-restricted-names': [2],
+ 'no-shadow': [0],
+ 'no-sparse-arrays': [2],
+ 'no-template-curly-in-string': [2],
+ 'no-ternary': [0],
+ 'no-this-before-super': [2],
+ 'no-throw-literal': [2],
+ 'no-undef-init': [2],
+
+ 'no-undef': [2, {
+ typeof: true,
+ }],
+
+ 'no-undefined': [0],
+ 'no-underscore-dangle': [0],
+ 'no-unexpected-multiline': [2],
+ 'no-unmodified-loop-condition': [2],
+ 'no-unneeded-ternary': [2],
+ 'no-unreachable-loop': [2],
+ 'no-unreachable': [2],
+ 'no-unsafe-finally': [2],
+ 'no-unsafe-negation': [2],
+ 'no-unused-expressions': [2],
+ 'no-unused-labels': [2],
+ 'no-unused-private-class-members': [2],
+
+ 'no-unused-vars': [2, {
+ args: 'all',
+ argsIgnorePattern: '^_',
+ varsIgnorePattern: '^_',
+ caughtErrorsIgnorePattern: '^_',
+ destructuredArrayIgnorePattern: '^_',
+ ignoreRestSiblings: false,
+ }],
+
+ 'no-use-before-define': [2, {
+ functions: false,
+ classes: true,
+ variables: true,
+ allowNamedExports: true,
+ }],
+
+ 'no-use-extend-native/no-use-extend-native': [2],
+ 'no-useless-backreference': [2],
+ 'no-useless-call': [2],
+ 'no-useless-catch': [2],
+ 'no-useless-computed-key': [2],
+ 'no-useless-concat': [2],
+ 'no-useless-constructor': [2],
+ 'no-useless-escape': [2],
+ 'no-useless-rename': [2],
+ 'no-useless-return': [2],
+ 'no-var': [2],
+ 'no-void': [2],
+ 'no-warning-comments': [0],
+ 'no-with': [0],
+ 'object-shorthand': [2, 'always'],
+ 'one-var-declaration-per-line': [0],
+ 'one-var': [0],
+ 'operator-assignment': [2, 'always'],
+ 'operator-linebreak': [2, 'after'],
+
+ 'prefer-arrow-callback': [2, {
+ allowNamedFunctions: true,
+ allowUnboundThis: true,
+ }],
+
+ 'prefer-const': [2, {
+ destructuring: 'all',
+ ignoreReadBeforeAssign: true,
+ }],
+
+ 'prefer-destructuring': [0],
+ 'prefer-exponentiation-operator': [2],
+ 'prefer-named-capture-group': [0],
+ 'prefer-numeric-literals': [2],
+ 'prefer-object-has-own': [2],
+ 'prefer-object-spread': [2],
+
+ 'prefer-promise-reject-errors': [2, {
+ allowEmptyReject: false,
+ }],
+
+ 'prefer-regex-literals': [2],
+ 'prefer-rest-params': [2],
+ 'prefer-spread': [2],
+ 'prefer-template': [2],
+ radix: [2, 'as-needed'],
+ 'regexp/confusing-quantifier': [2],
+ 'regexp/control-character-escape': [2],
+ 'regexp/hexadecimal-escape': [0],
+ 'regexp/letter-case': [0],
+ 'regexp/match-any': [2],
+ 'regexp/negation': [2],
+ 'regexp/no-contradiction-with-assertion': [0],
+ 'regexp/no-control-character': [0],
+ 'regexp/no-dupe-characters-character-class': [2],
+ 'regexp/no-dupe-disjunctions': [2],
+ 'regexp/no-empty-alternative': [2],
+ 'regexp/no-empty-capturing-group': [2],
+ 'regexp/no-empty-character-class': [0],
+ 'regexp/no-empty-group': [2],
+ 'regexp/no-empty-lookarounds-assertion': [2],
+ 'regexp/no-empty-string-literal': [2],
+ 'regexp/no-escape-backspace': [2],
+ 'regexp/no-extra-lookaround-assertions': [0],
+ 'regexp/no-invalid-regexp': [2],
+ 'regexp/no-invisible-character': [2],
+ 'regexp/no-lazy-ends': [2],
+ 'regexp/no-legacy-features': [2],
+ 'regexp/no-misleading-capturing-group': [0],
+ 'regexp/no-misleading-unicode-character': [0],
+ 'regexp/no-missing-g-flag': [2],
+ 'regexp/no-non-standard-flag': [2],
+ 'regexp/no-obscure-range': [2],
+ 'regexp/no-octal': [2],
+ 'regexp/no-optional-assertion': [2],
+ 'regexp/no-potentially-useless-backreference': [2],
+ 'regexp/no-standalone-backslash': [2],
+ 'regexp/no-super-linear-backtracking': [0],
+ 'regexp/no-super-linear-move': [0],
+ 'regexp/no-trivially-nested-assertion': [2],
+ 'regexp/no-trivially-nested-quantifier': [2],
+ 'regexp/no-unused-capturing-group': [0],
+ 'regexp/no-useless-assertions': [2],
+ 'regexp/no-useless-backreference': [2],
+ 'regexp/no-useless-character-class': [2],
+ 'regexp/no-useless-dollar-replacements': [2],
+ 'regexp/no-useless-escape': [2],
+ 'regexp/no-useless-flag': [2],
+ 'regexp/no-useless-lazy': [2],
+ 'regexp/no-useless-non-capturing-group': [2],
+ 'regexp/no-useless-quantifier': [2],
+ 'regexp/no-useless-range': [2],
+ 'regexp/no-useless-set-operand': [2],
+ 'regexp/no-useless-string-literal': [2],
+ 'regexp/no-useless-two-nums-quantifier': [2],
+ 'regexp/no-zero-quantifier': [2],
+ 'regexp/optimal-lookaround-quantifier': [2],
+ 'regexp/optimal-quantifier-concatenation': [0],
+ 'regexp/prefer-character-class': [0],
+ 'regexp/prefer-d': [0],
+ 'regexp/prefer-escape-replacement-dollar-char': [0],
+ 'regexp/prefer-lookaround': [0],
+ 'regexp/prefer-named-backreference': [0],
+ 'regexp/prefer-named-capture-group': [0],
+ 'regexp/prefer-named-replacement': [0],
+ 'regexp/prefer-plus-quantifier': [2],
+ 'regexp/prefer-predefined-assertion': [2],
+ 'regexp/prefer-quantifier': [0],
+ 'regexp/prefer-question-quantifier': [2],
+ 'regexp/prefer-range': [2],
+ 'regexp/prefer-regexp-exec': [2],
+ 'regexp/prefer-regexp-test': [2],
+ 'regexp/prefer-result-array-groups': [0],
+ 'regexp/prefer-set-operation': [2],
+ 'regexp/prefer-star-quantifier': [2],
+ 'regexp/prefer-unicode-codepoint-escapes': [2],
+ 'regexp/prefer-w': [0],
+ 'regexp/require-unicode-regexp': [0],
+ 'regexp/simplify-set-operations': [2],
+ 'regexp/sort-alternatives': [0],
+ 'regexp/sort-character-class-elements': [0],
+ 'regexp/sort-flags': [0],
+ 'regexp/strict': [2],
+ 'regexp/unicode-escape': [0],
+ 'regexp/use-ignore-case': [0],
+ 'require-atomic-updates': [0],
+ 'require-await': [0],
+ 'require-unicode-regexp': [0],
+ 'require-yield': [2],
+ 'sonarjs/cognitive-complexity': [0],
+ 'sonarjs/elseif-without-else': [0],
+ 'sonarjs/max-switch-cases': [0],
+ 'sonarjs/no-all-duplicated-branches': [2],
+ 'sonarjs/no-collapsible-if': [0],
+ 'sonarjs/no-collection-size-mischeck': [2],
+ 'sonarjs/no-duplicate-string': [0],
+ 'sonarjs/no-duplicated-branches': [0],
+ 'sonarjs/no-element-overwrite': [2],
+ 'sonarjs/no-empty-collection': [2],
+ 'sonarjs/no-extra-arguments': [2],
+ 'sonarjs/no-gratuitous-expressions': [2],
+ 'sonarjs/no-identical-conditions': [2],
+ 'sonarjs/no-identical-expressions': [2],
+ 'sonarjs/no-identical-functions': [2, 5],
+ 'sonarjs/no-ignored-return': [2],
+ 'sonarjs/no-inverted-boolean-check': [2],
+ 'sonarjs/no-nested-switch': [0],
+ 'sonarjs/no-nested-template-literals': [0],
+ 'sonarjs/no-one-iteration-loop': [2],
+ 'sonarjs/no-redundant-boolean': [2],
+ 'sonarjs/no-redundant-jump': [2],
+ 'sonarjs/no-same-line-conditional': [2],
+ 'sonarjs/no-small-switch': [0],
+ 'sonarjs/no-unused-collection': [2],
+ 'sonarjs/no-use-of-empty-return-value': [2],
+ 'sonarjs/no-useless-catch': [2],
+ 'sonarjs/non-existent-operator': [2],
+ 'sonarjs/prefer-immediate-return': [0],
+ 'sonarjs/prefer-object-literal': [0],
+ 'sonarjs/prefer-single-boolean-return': [0],
+ 'sonarjs/prefer-while': [2],
+ 'sort-imports': [0],
+ 'sort-keys': [0],
+ 'sort-vars': [0],
+ strict: [0],
+ 'symbol-description': [2],
+ 'unicode-bom': [2, 'never'],
+ 'unicorn/better-regex': [0],
+ 'unicorn/catch-error-name': [0],
+ 'unicorn/consistent-assert': [0],
+ 'unicorn/consistent-date-clone': [2],
+ 'unicorn/consistent-destructuring': [2],
+ 'unicorn/consistent-empty-array-spread': [2],
+ 'unicorn/consistent-existence-index-check': [2],
+ 'unicorn/consistent-function-scoping': [2],
+ 'unicorn/custom-error-definition': [0],
+ 'unicorn/empty-brace-spaces': [2],
+ 'unicorn/error-message': [0],
+ 'unicorn/escape-case': [0],
+ 'unicorn/expiring-todo-comments': [0],
+ 'unicorn/explicit-length-check': [0],
+ 'unicorn/filename-case': [0],
+ 'unicorn/import-index': [0],
+ 'unicorn/import-style': [0],
+ 'unicorn/new-for-builtins': [2],
+ 'unicorn/no-accessor-recursion': [2],
+ 'unicorn/no-abusive-eslint-disable': [0],
+ 'unicorn/no-anonymous-default-export': [0],
+ 'unicorn/no-array-callback-reference': [0],
+ 'unicorn/no-array-for-each': [2],
+ 'unicorn/no-array-method-this-argument': [2],
+ 'unicorn/no-array-push-push': [2],
+ 'unicorn/no-array-reduce': [2],
+ 'unicorn/no-await-expression-member': [0],
+ 'unicorn/no-await-in-promise-methods': [2],
+ 'unicorn/no-console-spaces': [0],
+ 'unicorn/no-document-cookie': [2],
+ 'unicorn/no-empty-file': [2],
+ 'unicorn/no-for-loop': [0],
+ 'unicorn/no-hex-escape': [0],
+ 'unicorn/no-instanceof-builtins': [0],
+ 'unicorn/no-invalid-fetch-options': [2],
+ 'unicorn/no-invalid-remove-event-listener': [2],
+ 'unicorn/no-keyword-prefix': [0],
+ 'unicorn/no-length-as-slice-end': [2],
+ 'unicorn/no-lonely-if': [2],
+ 'unicorn/no-magic-array-flat-depth': [0],
+ 'unicorn/no-named-default': [2],
+ 'unicorn/no-negated-condition': [0],
+ 'unicorn/no-negation-in-equality-check': [2],
+ 'unicorn/no-nested-ternary': [0],
+ 'unicorn/no-new-array': [0],
+ 'unicorn/no-new-buffer': [0],
+ 'unicorn/no-null': [0],
+ 'unicorn/no-object-as-default-parameter': [0],
+ 'unicorn/no-process-exit': [0],
+ 'unicorn/no-single-promise-in-promise-methods': [2],
+ 'unicorn/no-static-only-class': [2],
+ 'unicorn/no-thenable': [2],
+ 'unicorn/no-this-assignment': [2],
+ 'unicorn/no-typeof-undefined': [2],
+ 'unicorn/no-unnecessary-await': [2],
+ 'unicorn/no-unnecessary-polyfills': [2],
+ 'unicorn/no-unreadable-array-destructuring': [0],
+ 'unicorn/no-unreadable-iife': [2],
+ 'unicorn/no-unused-properties': [2],
+ 'unicorn/no-useless-fallback-in-spread': [2],
+ 'unicorn/no-useless-length-check': [2],
+ 'unicorn/no-useless-promise-resolve-reject': [2],
+ 'unicorn/no-useless-spread': [2],
+ 'unicorn/no-useless-switch-case': [2],
+ 'unicorn/no-useless-undefined': [0],
+ 'unicorn/no-zero-fractions': [2],
+ 'unicorn/number-literal-case': [0],
+ 'unicorn/numeric-separators-style': [0],
+ 'unicorn/prefer-add-event-listener': [2],
+ 'unicorn/prefer-array-find': [2],
+ 'unicorn/prefer-array-flat-map': [2],
+ 'unicorn/prefer-array-flat': [2],
+ 'unicorn/prefer-array-index-of': [2],
+ 'unicorn/prefer-array-some': [2],
+ 'unicorn/prefer-at': [0],
+ 'unicorn/prefer-blob-reading-methods': [2],
+ 'unicorn/prefer-code-point': [0],
+ 'unicorn/prefer-date-now': [2],
+ 'unicorn/prefer-default-parameters': [0],
+ 'unicorn/prefer-dom-node-append': [2],
+ 'unicorn/prefer-dom-node-dataset': [0],
+ 'unicorn/prefer-dom-node-remove': [2],
+ 'unicorn/prefer-dom-node-text-content': [2],
+ 'unicorn/prefer-event-target': [2],
+ 'unicorn/prefer-export-from': [0],
+ 'unicorn/prefer-global-this': [0],
+ 'unicorn/prefer-includes': [2],
+ 'unicorn/prefer-json-parse-buffer': [0],
+ 'unicorn/prefer-keyboard-event-key': [2],
+ 'unicorn/prefer-logical-operator-over-ternary': [2],
+ 'unicorn/prefer-math-min-max': [2],
+ 'unicorn/prefer-math-trunc': [2],
+ 'unicorn/prefer-modern-dom-apis': [0],
+ 'unicorn/prefer-modern-math-apis': [2],
+ 'unicorn/prefer-module': [2],
+ 'unicorn/prefer-native-coercion-functions': [2],
+ 'unicorn/prefer-negative-index': [2],
+ 'unicorn/prefer-node-protocol': [2],
+ 'unicorn/prefer-number-properties': [0],
+ 'unicorn/prefer-object-from-entries': [2],
+ 'unicorn/prefer-object-has-own': [0],
+ 'unicorn/prefer-optional-catch-binding': [2],
+ 'unicorn/prefer-prototype-methods': [0],
+ 'unicorn/prefer-query-selector': [0],
+ 'unicorn/prefer-reflect-apply': [0],
+ 'unicorn/prefer-regexp-test': [2],
+ 'unicorn/prefer-set-has': [0],
+ 'unicorn/prefer-set-size': [2],
+ 'unicorn/prefer-spread': [0],
+ 'unicorn/prefer-string-raw': [0],
+ 'unicorn/prefer-string-replace-all': [0],
+ 'unicorn/prefer-string-slice': [0],
+ 'unicorn/prefer-string-starts-ends-with': [2],
+ 'unicorn/prefer-string-trim-start-end': [2],
+ 'unicorn/prefer-structured-clone': [2],
+ 'unicorn/prefer-switch': [0],
+ 'unicorn/prefer-ternary': [0],
+ 'unicorn/prefer-top-level-await': [0],
+ 'unicorn/prefer-type-error': [0],
+ 'unicorn/prevent-abbreviations': [0],
+ 'unicorn/relative-url-style': [2],
+ 'unicorn/require-array-join-separator': [2],
+ 'unicorn/require-number-to-fixed-digits-argument': [2],
+ 'unicorn/require-post-message-target-origin': [0],
+ 'unicorn/string-content': [0],
+ 'unicorn/switch-case-braces': [0],
+ 'unicorn/template-indent': [2],
+ 'unicorn/text-encoding-identifier-case': [0],
+ 'unicorn/throw-new-error': [2],
+ 'use-isnan': [2],
+
+ 'valid-typeof': [2, {
+ requireStringLiterals: true,
+ }],
+
+ 'vars-on-top': [0],
+ 'wc/attach-shadow-constructor': [2],
+ 'wc/define-tag-after-class-definition': [0],
+ 'wc/expose-class-on-global': [0],
+ 'wc/file-name-matches-element': [2],
+ 'wc/guard-define-call': [0],
+ 'wc/guard-super-call': [2],
+ 'wc/max-elements-per-file': [0],
+ 'wc/no-child-traversal-in-attributechangedcallback': [2],
+ 'wc/no-child-traversal-in-connectedcallback': [2],
+ 'wc/no-closed-shadow-root': [2],
+ 'wc/no-constructor-attributes': [2],
+ 'wc/no-constructor-params': [2],
+ 'wc/no-constructor': [2],
+ 'wc/no-customized-built-in-elements': [2],
+ 'wc/no-exports-with-element': [0],
+ 'wc/no-invalid-element-name': [2],
+ 'wc/no-invalid-extends': [2],
+ 'wc/no-method-prefixed-with-on': [2],
+ 'wc/no-self-class': [2],
+ 'wc/no-typos': [2],
+ 'wc/require-listener-teardown': [2],
+ 'wc/tag-name-matches-class': [2],
+ yoda: [2, 'never'],
+ },
+ },
+ {
+ ignores: ['*.vue', '**/*.vue'],
+ rules: {
+ 'import-x/consistent-type-specifier-style': [0],
+ 'import-x/default': [0],
+ 'import-x/dynamic-import-chunkname': [0],
+ 'import-x/export': [2],
+ 'import-x/exports-last': [0],
+
+ 'import-x/extensions': [2, 'always', {
+ ignorePackages: true,
+ }],
+
+ 'import-x/first': [2],
+ 'import-x/group-exports': [0],
+ 'import-x/max-dependencies': [0],
+ 'import-x/named': [2],
+ 'import-x/namespace': [0],
+ 'import-x/newline-after-import': [0],
+ 'import-x/no-absolute-path': [0],
+ 'import-x/no-amd': [2],
+ 'import-x/no-anonymous-default-export': [0],
+ 'import-x/no-commonjs': [2],
+
+ 'import-x/no-cycle': [2, {
+ ignoreExternal: true,
+ maxDepth: 1,
+ }],
+
+ 'import-x/no-default-export': [0],
+ 'import-x/no-deprecated': [0],
+ 'import-x/no-dynamic-require': [0],
+ 'import-x/no-empty-named-blocks': [2],
+ 'import-x/no-extraneous-dependencies': [2],
+ 'import-x/no-import-module-exports': [0],
+ 'import-x/no-internal-modules': [0],
+ 'import-x/no-mutable-exports': [0],
+ 'import-x/no-named-as-default-member': [0],
+ 'import-x/no-named-as-default': [2],
+ 'import-x/no-named-default': [0],
+ 'import-x/no-named-export': [0],
+ 'import-x/no-namespace': [0],
+ 'import-x/no-nodejs-modules': [0],
+ 'import-x/no-relative-packages': [0],
+ 'import-x/no-relative-parent-imports': [0],
+ 'import-x/no-restricted-paths': [0],
+ 'import-x/no-self-import': [2],
+ 'import-x/no-unassigned-import': [0],
+
+ 'import-x/no-unresolved': [2, {
+ commonjs: true,
+ ignore: ['\\?.+$', '^vitest/'],
+ }],
+
+ 'import-x/no-useless-path-segments': [2, {
+ commonjs: true,
+ }],
+
+ 'import-x/no-webpack-loader-syntax': [2],
+ 'import-x/order': [0],
+ 'import-x/prefer-default-export': [0],
+ 'import-x/unambiguous': [0],
+ },
+ },
+ {
+ files: ['web_src/**/*'],
+ languageOptions: {
+ globals: {
+ __webpack_public_path__: true,
+ process: false,
+ },
+ },
+ }, {
+ files: ['web_src/**/*', 'docs/**/*'],
+
+ languageOptions: {
+ globals: {
+ ...globals.browser,
+ },
+ },
+ }, {
+ files: ['web_src/**/*worker.*'],
+
+ languageOptions: {
+ globals: {
+ ...globals.worker,
+ },
+ },
+
+ rules: {
+ 'no-restricted-globals': [
+ 2,
+ 'addEventListener',
+ 'blur',
+ 'close',
+ 'closed',
+ 'confirm',
+ 'defaultStatus',
+ 'defaultstatus',
+ 'error',
+ 'event',
+ 'external',
+ 'find',
+ 'focus',
+ 'frameElement',
+ 'frames',
+ 'history',
+ 'innerHeight',
+ 'innerWidth',
+ 'isFinite',
+ 'isNaN',
+ 'length',
+ 'locationbar',
+ 'menubar',
+ 'moveBy',
+ 'moveTo',
+ 'name',
+ 'onblur',
+ 'onerror',
+ 'onfocus',
+ 'onload',
+ 'onresize',
+ 'onunload',
+ 'open',
+ 'opener',
+ 'opera',
+ 'outerHeight',
+ 'outerWidth',
+ 'pageXOffset',
+ 'pageYOffset',
+ 'parent',
+ 'print',
+ 'removeEventListener',
+ 'resizeBy',
+ 'resizeTo',
+ 'screen',
+ 'screenLeft',
+ 'screenTop',
+ 'screenX',
+ 'screenY',
+ 'scroll',
+ 'scrollbars',
+ 'scrollBy',
+ 'scrollTo',
+ 'scrollX',
+ 'scrollY',
+ 'status',
+ 'statusbar',
+ 'stop',
+ 'toolbar',
+ 'top',
+ ],
+ },
+ }, {
+ files: ['**/*.config.*'],
+ languageOptions: {
+ ecmaVersion: 'latest',
+ },
+ rules: {
+ 'import-x/no-unused-modules': [0],
+ 'import-x/no-unresolved': [0],
+ 'import-x/no-named-as-default': [0],
+ },
+ }, {
+ files: ['**/*.test.*', 'web_src/js/test/setup.js'],
+ languageOptions: {
+ globals: {
+ ...vitestGlobals.environments.env.globals,
+ },
+ },
+
+ rules: {
+ '@vitest/consistent-test-filename': [0],
+ '@vitest/consistent-test-it': [0],
+ '@vitest/expect-expect': [0],
+ '@vitest/max-expects': [0],
+ '@vitest/max-nested-describe': [0],
+ '@vitest/no-alias-methods': [0],
+ '@vitest/no-commented-out-tests': [0],
+ '@vitest/no-conditional-expect': [0],
+ '@vitest/no-conditional-in-test': [0],
+ '@vitest/no-conditional-tests': [0],
+ '@vitest/no-disabled-tests': [0],
+ '@vitest/no-done-callback': [0],
+ '@vitest/no-duplicate-hooks': [0],
+ '@vitest/no-focused-tests': [0],
+ '@vitest/no-hooks': [0],
+ '@vitest/no-identical-title': [2],
+ '@vitest/no-interpolation-in-snapshots': [0],
+ '@vitest/no-large-snapshots': [0],
+ '@vitest/no-mocks-import': [0],
+ '@vitest/no-restricted-matchers': [0],
+ '@vitest/no-restricted-vi-methods': [0],
+ '@vitest/no-standalone-expect': [0],
+ '@vitest/no-test-prefixes': [0],
+ '@vitest/no-test-return-statement': [0],
+ '@vitest/prefer-called-with': [0],
+ '@vitest/prefer-comparison-matcher': [0],
+ '@vitest/prefer-each': [0],
+ '@vitest/prefer-equality-matcher': [0],
+ '@vitest/prefer-expect-resolves': [0],
+ '@vitest/prefer-hooks-in-order': [0],
+ '@vitest/prefer-hooks-on-top': [2],
+ '@vitest/prefer-lowercase-title': [0],
+ '@vitest/prefer-mock-promise-shorthand': [0],
+ '@vitest/prefer-snapshot-hint': [0],
+ '@vitest/prefer-spy-on': [0],
+ '@vitest/prefer-strict-equal': [0],
+ '@vitest/prefer-to-be': [0],
+ '@vitest/prefer-to-be-falsy': [0],
+ '@vitest/prefer-to-be-object': [0],
+ '@vitest/prefer-to-be-truthy': [0],
+ '@vitest/prefer-to-contain': [0],
+ '@vitest/prefer-to-have-length': [0],
+ '@vitest/prefer-todo': [0],
+ '@vitest/require-hook': [0],
+ '@vitest/require-to-throw-message': [0],
+ '@vitest/require-top-level-describe': [0],
+ '@vitest/valid-describe-callback': [2],
+ '@vitest/valid-expect': [2],
+ '@vitest/valid-title': [2],
+ },
+ }, {
+ files: ['web_src/js/modules/fetch.js', 'web_src/js/standalone/**/*'],
+
+ rules: {
+ 'no-restricted-syntax': [
+ 2,
+ 'WithStatement',
+ 'ForInStatement',
+ 'LabeledStatement',
+ 'SequenceExpression',
+ ],
+ },
+ }, {
+ files: ['tests/e2e/**/*.ts'],
+ languageOptions: {
+ globals: {
+ ...globals.browser,
+ },
+
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ },
+ rules: {
+ ...playwright.configs['flat/recommended'].rules,
+ 'playwright/no-conditional-in-test': [0],
+ 'playwright/no-conditional-expect': [0],
+ // allow grouping helper functions with tests
+ 'unicorn/consistent-function-scoping': [0],
+
+ 'playwright/no-skipped-test': [
+ 2,
+ {
+ allowConditional: true,
+ },
+ ],
+ 'playwright/no-useless-await': [2],
+
+ 'playwright/prefer-comparison-matcher': [2],
+ 'playwright/prefer-equality-matcher': [2],
+ 'playwright/prefer-native-locators': [2],
+ 'playwright/prefer-to-contain': [2],
+ 'playwright/prefer-to-have-length': [2],
+ 'playwright/require-to-throw-message': [2],
+ },
+ },
+ ...vue.configs['flat/recommended'],
+ {
+ files: ['web_src/js/components/*.vue'],
+ languageOptions: {
+ globals: {
+ ...globals.browser,
+ },
+
+ ecmaVersion: 'latest',
+ sourceType: 'module',
+ },
+ rules: {
+ 'vue/attributes-order': [0],
+ 'vue/html-closing-bracket-spacing': [2, {
+ startTag: 'never',
+ endTag: 'never',
+ selfClosingTag: 'never',
+ }],
+ 'vue/max-attributes-per-line': [0],
+ 'vue-scoped-css/enforce-style-type': [0],
+ },
+ },
+ ...toml.configs['flat/recommended'],
+);
diff --git a/flake.lock b/flake.lock
index 606f8836c1..90672733d5 100644
--- a/flake.lock
+++ b/flake.lock
@@ -5,11 +5,11 @@
"systems": "systems"
},
"locked": {
- "lastModified": 1710146030,
- "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
+ "lastModified": 1731533236,
+ "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
- "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
+ "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
- "lastModified": 1717974879,
- "narHash": "sha256-GTO3C88+5DX171F/gVS3Qga/hOs/eRMxPFpiHq2t+D8=",
+ "lastModified": 1733392399,
+ "narHash": "sha256-kEsTJTUQfQFIJOcLYFt/RvNxIK653ZkTBIs4DG+cBns=",
"owner": "nixos",
"repo": "nixpkgs",
- "rev": "c7b821ba2e1e635ba5a76d299af62821cbcb09f3",
+ "rev": "d0797a04b81caeae77bcff10a9dde78bc17f5661",
"type": "github"
},
"original": {
diff --git a/flake.nix b/flake.nix
index 22354663dd..9f858541df 100644
--- a/flake.nix
+++ b/flake.nix
@@ -3,14 +3,15 @@
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
- outputs =
- { nixpkgs, flake-utils, ... }:
+ outputs = {
+ nixpkgs,
+ flake-utils,
+ ...
+ }:
flake-utils.lib.eachDefaultSystem (
- system:
- let
+ system: let
pkgs = nixpkgs.legacyPackages.${system};
- in
- {
+ in {
devShells.default = pkgs.mkShell {
buildInputs = with pkgs; [
# generic
@@ -29,8 +30,10 @@
poetry
# backend
- go_1_22
gofumpt
+ sqlite
+ go
+ gopls
];
};
}
diff --git a/go.mod b/go.mod
index 2791a7f5a4..cbeed64369 100644
--- a/go.mod
+++ b/go.mod
@@ -1,315 +1,257 @@
-module code.gitea.io/gitea
+module forgejo.org
-go 1.22.0
+go 1.24
-toolchain go1.22.4
+toolchain go1.24.3
require (
- code.forgejo.org/f3/gof3/v3 v3.4.0
+ code.forgejo.org/f3/gof3/v3 v3.10.6
+ code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251
+ code.forgejo.org/forgejo/levelqueue v1.0.0
code.forgejo.org/forgejo/reply v1.0.2
+ code.forgejo.org/go-chi/binding v1.0.0
+ code.forgejo.org/go-chi/cache v1.0.0
+ code.forgejo.org/go-chi/captcha v1.0.1
+ code.forgejo.org/go-chi/session v1.0.1
code.gitea.io/actions-proto-go v0.4.0
- code.gitea.io/gitea-vet v0.2.3
- code.gitea.io/sdk/gitea v0.17.1
+ code.gitea.io/sdk/gitea v0.20.0
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570
- connectrpc.com/connect v1.16.2
- gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed
- gitea.com/go-chi/cache v0.2.0
- gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098
- gitea.com/go-chi/session v0.0.0-20240316035857-16768d98ec96
- gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4
+ connectrpc.com/connect v1.17.0
+ github.com/42wim/httpsig v1.2.2
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358
- github.com/ProtonMail/go-crypto v1.0.0
- github.com/PuerkitoBio/goquery v1.9.2
- github.com/alecthomas/chroma/v2 v2.14.0
+ github.com/ProtonMail/go-crypto v1.1.6
+ github.com/PuerkitoBio/goquery v1.10.2
+ github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2
+ github.com/alecthomas/chroma/v2 v2.15.0
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb
- github.com/blevesearch/bleve/v2 v2.4.0
- github.com/buildkite/terminal-to-html/v3 v3.10.1
- github.com/caddyserver/certmagic v0.21.0
+ github.com/blevesearch/bleve/v2 v2.5.2
+ github.com/buildkite/terminal-to-html/v3 v3.16.8
+ github.com/caddyserver/certmagic v0.22.2
github.com/chi-middleware/proxy v1.1.1
github.com/djherbis/buffer v1.2.0
github.com/djherbis/nio/v3 v3.0.1
- github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5
+ github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707
github.com/dustin/go-humanize v1.0.1
- github.com/editorconfig/editorconfig-core-go/v2 v2.6.2
+ github.com/editorconfig/editorconfig-core-go/v2 v2.6.3
github.com/emersion/go-imap v1.2.1
- github.com/emirpasic/gods v1.18.1
- github.com/felixge/fgprof v0.9.4
- github.com/fsnotify/fsnotify v1.7.0
- github.com/gliderlabs/ssh v0.3.7
+ github.com/felixge/fgprof v0.9.5
+ github.com/fsnotify/fsnotify v1.8.0
+ github.com/gliderlabs/ssh v0.3.8
github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9
github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73
- github.com/go-chi/chi/v5 v5.0.14
+ github.com/go-chi/chi/v5 v5.2.0
github.com/go-chi/cors v1.2.1
github.com/go-co-op/gocron v1.37.0
- github.com/go-enry/go-enry/v2 v2.8.8
- github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e
- github.com/go-git/go-billy/v5 v5.5.0
- github.com/go-git/go-git/v5 v5.11.0
+ github.com/go-enry/go-enry/v2 v2.9.2
+ github.com/go-git/go-git/v5 v5.13.2
github.com/go-ldap/ldap/v3 v3.4.6
- github.com/go-sql-driver/mysql v1.8.1
- github.com/go-swagger/go-swagger v0.30.5
- github.com/go-testfixtures/testfixtures/v3 v3.11.0
- github.com/go-webauthn/webauthn v0.10.0
+ github.com/go-openapi/spec v0.20.14
+ github.com/go-sql-driver/mysql v1.9.1
+ github.com/go-webauthn/webauthn v0.12.2
github.com/gobwas/glob v0.2.3
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85
- github.com/golang-jwt/jwt/v5 v5.2.0
- github.com/google/go-github/v57 v57.0.0
- github.com/google/pprof v0.0.0-20240528025155-186aa0362fba
+ github.com/golang-jwt/jwt/v5 v5.2.2
+ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
+ github.com/google/go-github/v64 v64.0.0
+ github.com/google/pprof v0.0.0-20241017200806-017d972448fc
github.com/google/uuid v1.6.0
github.com/gorilla/feeds v1.2.0
- github.com/gorilla/sessions v1.2.2
- github.com/h2non/gock v1.2.0
- github.com/hashicorp/go-version v1.6.0
+ github.com/gorilla/sessions v1.4.0
+ github.com/hashicorp/go-version v1.7.0
github.com/hashicorp/golang-lru/v2 v2.0.7
github.com/huandu/xstrings v1.5.0
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056
- github.com/jhillyerd/enmime v1.2.0
+ github.com/jhillyerd/enmime/v2 v2.1.0
github.com/json-iterator/go v1.1.12
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
- github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4
- github.com/klauspost/compress v1.17.9
- github.com/klauspost/cpuid/v2 v2.2.7
+ github.com/klauspost/compress v1.17.11
+ github.com/klauspost/cpuid/v2 v2.2.10
github.com/lib/pq v1.10.9
github.com/markbates/goth v1.80.0
github.com/mattn/go-isatty v0.0.20
- github.com/mattn/go-sqlite3 v1.14.22
- github.com/meilisearch/meilisearch-go v0.26.1
+ github.com/mattn/go-sqlite3 v1.14.28
+ github.com/meilisearch/meilisearch-go v0.31.0
github.com/mholt/archiver/v3 v3.5.1
- github.com/microcosm-cc/bluemonday v1.0.26
- github.com/minio/minio-go/v7 v7.0.70
- github.com/msteinert/pam v1.2.0
+ github.com/microcosm-cc/bluemonday v1.0.27
+ github.com/minio/minio-go/v7 v7.0.88
+ github.com/msteinert/pam/v2 v2.1.0
github.com/nektos/act v0.2.52
github.com/niklasfasching/go-org v1.7.0
github.com/olivere/elastic/v7 v7.0.32
github.com/opencontainers/go-digest v1.0.0
- github.com/opencontainers/image-spec v1.1.0
+ github.com/opencontainers/image-spec v1.1.1
github.com/pquerna/otp v1.4.0
- github.com/prometheus/client_golang v1.18.0
- github.com/quasoft/websspi v1.1.2
- github.com/redis/go-redis/v9 v9.5.2
+ github.com/prometheus/client_golang v1.21.1
+ github.com/redis/go-redis/v9 v9.7.3
github.com/robfig/cron/v3 v3.0.1
- github.com/santhosh-tekuri/jsonschema/v5 v5.3.1
- github.com/sassoftware/go-rpmutils v0.2.1-0.20240124161140-277b154961dd
- github.com/sergi/go-diff v1.3.1
+ github.com/santhosh-tekuri/jsonschema/v6 v6.0.1
+ github.com/sassoftware/go-rpmutils v0.4.0
+ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92
- github.com/stretchr/testify v1.9.0
+ github.com/stretchr/testify v1.10.0
github.com/syndtr/goleveldb v1.0.0
- github.com/ulikunitz/xz v0.5.11
- github.com/urfave/cli/v2 v2.27.2
+ github.com/ulikunitz/xz v0.5.12
+ github.com/urfave/cli/v2 v2.27.6
github.com/valyala/fastjson v1.6.4
- github.com/xanzy/go-gitlab v0.96.0
github.com/yohcop/openid-go v1.0.1
- github.com/yuin/goldmark v1.7.4
+ github.com/yuin/goldmark v1.7.8
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc
- github.com/yuin/goldmark-meta v1.1.0
- go.uber.org/mock v0.4.0
- golang.org/x/crypto v0.24.0
- golang.org/x/image v0.18.0
- golang.org/x/net v0.26.0
- golang.org/x/oauth2 v0.21.0
- golang.org/x/sys v0.21.0
- golang.org/x/text v0.16.0
- golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d
- google.golang.org/grpc v1.60.1
- google.golang.org/protobuf v1.33.0
+ gitlab.com/gitlab-org/api/client-go v0.126.0
+ go.uber.org/mock v0.5.0
+ golang.org/x/crypto v0.36.0
+ golang.org/x/image v0.25.0
+ golang.org/x/net v0.38.0
+ golang.org/x/oauth2 v0.28.0
+ golang.org/x/sync v0.12.0
+ golang.org/x/sys v0.31.0
+ golang.org/x/text v0.23.0
+ google.golang.org/protobuf v1.36.4
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
gopkg.in/ini.v1 v1.67.0
gopkg.in/yaml.v3 v3.0.1
mvdan.cc/xurls/v2 v2.5.0
- strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251
xorm.io/builder v0.3.13
- xorm.io/xorm v1.3.7
+ xorm.io/xorm v1.3.9
)
require (
- cloud.google.com/go/compute/metadata v0.3.0 // indirect
+ cloud.google.com/go/compute/metadata v0.6.0 // indirect
dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 // indirect
- github.com/ClickHouse/ch-go v0.61.5 // indirect
- github.com/ClickHouse/clickhouse-go/v2 v2.24.0 // indirect
github.com/DataDog/zstd v1.5.5 // indirect
- github.com/Masterminds/goutils v1.1.1 // indirect
- github.com/Masterminds/semver/v3 v3.2.1 // indirect
- github.com/Masterminds/sprig/v3 v3.2.3 // indirect
- github.com/Microsoft/go-winio v0.6.1 // indirect
- github.com/RoaringBitmap/roaring v1.7.0 // indirect
- github.com/andybalholm/brotli v1.1.0 // indirect
- github.com/andybalholm/cascadia v1.3.2 // indirect
+ github.com/Microsoft/go-winio v0.6.2 // indirect
+ github.com/RoaringBitmap/roaring/v2 v2.4.5 // indirect
+ github.com/andybalholm/brotli v1.1.1 // indirect
+ github.com/andybalholm/cascadia v1.3.3 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
- github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/aymerick/douceur v0.2.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
- github.com/bits-and-blooms/bitset v1.13.0 // indirect
- github.com/blevesearch/bleve_index_api v1.1.6 // indirect
- github.com/blevesearch/geo v0.1.20 // indirect
- github.com/blevesearch/go-faiss v1.0.13 // indirect
+ github.com/bits-and-blooms/bitset v1.22.0 // indirect
+ github.com/blevesearch/bleve_index_api v1.2.8 // indirect
+ github.com/blevesearch/geo v0.2.3 // indirect
+ github.com/blevesearch/go-faiss v1.0.25 // indirect
github.com/blevesearch/go-porterstemmer v1.0.3 // indirect
github.com/blevesearch/gtreap v0.1.1 // indirect
github.com/blevesearch/mmap-go v1.0.4 // indirect
- github.com/blevesearch/scorch_segment_api/v2 v2.2.9 // indirect
+ github.com/blevesearch/scorch_segment_api/v2 v2.3.10 // indirect
github.com/blevesearch/segment v0.9.1 // indirect
github.com/blevesearch/snowballstem v0.9.0 // indirect
github.com/blevesearch/upsidedown_store_api v1.0.2 // indirect
- github.com/blevesearch/vellum v1.0.10 // indirect
- github.com/blevesearch/zapx/v11 v11.3.10 // indirect
- github.com/blevesearch/zapx/v12 v12.3.10 // indirect
- github.com/blevesearch/zapx/v13 v13.3.10 // indirect
- github.com/blevesearch/zapx/v14 v14.3.10 // indirect
- github.com/blevesearch/zapx/v15 v15.3.13 // indirect
- github.com/blevesearch/zapx/v16 v16.0.12 // indirect
+ github.com/blevesearch/vellum v1.1.0 // indirect
+ github.com/blevesearch/zapx/v11 v11.4.2 // indirect
+ github.com/blevesearch/zapx/v12 v12.4.2 // indirect
+ github.com/blevesearch/zapx/v13 v13.4.2 // indirect
+ github.com/blevesearch/zapx/v14 v14.4.2 // indirect
+ github.com/blevesearch/zapx/v15 v15.4.2 // indirect
+ github.com/blevesearch/zapx/v16 v16.2.4 // indirect
github.com/boombuler/barcode v1.0.1 // indirect
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
- github.com/caddyserver/zerossl v0.1.2 // indirect
+ github.com/caddyserver/zerossl v0.1.3 // indirect
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a // indirect
- github.com/cespare/xxhash/v2 v2.2.0 // indirect
- github.com/cloudflare/circl v1.3.7 // indirect
- github.com/couchbase/go-couchbase v0.1.1 // indirect
- github.com/couchbase/gomemcached v0.3.0 // indirect
- github.com/couchbase/goutils v0.1.2 // indirect
- github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
- github.com/cyphar/filepath-securejoin v0.2.4 // indirect
+ github.com/cespare/xxhash/v2 v2.3.0 // indirect
+ github.com/cloudflare/circl v1.6.1 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect
+ github.com/cyphar/filepath-securejoin v0.3.6 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/davidmz/go-pageant v1.0.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
- github.com/dlclark/regexp2 v1.11.0 // indirect
+ github.com/dlclark/regexp2 v1.11.4 // indirect
github.com/emersion/go-sasl v0.0.0-20231106173351-e73c9f7bad43 // indirect
+ github.com/emirpasic/gods v1.18.1 // indirect
github.com/fatih/color v1.16.0 // indirect
- github.com/felixge/httpsnoop v1.0.4 // indirect
- github.com/fxamacker/cbor/v2 v2.5.0 // indirect
+ github.com/fxamacker/cbor/v2 v2.8.0 // indirect
github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-enry/go-oniguruma v1.2.1 // indirect
- github.com/go-faster/city v1.0.1 // indirect
- github.com/go-faster/errors v0.7.1 // indirect
+ github.com/go-fed/httpsig v1.1.0 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
- github.com/go-openapi/analysis v0.22.2 // indirect
- github.com/go-openapi/errors v0.21.0 // indirect
- github.com/go-openapi/inflect v0.19.0 // indirect
+ github.com/go-git/go-billy/v5 v5.6.2 // indirect
+ github.com/go-ini/ini v1.67.0 // indirect
github.com/go-openapi/jsonpointer v0.20.2 // indirect
github.com/go-openapi/jsonreference v0.20.4 // indirect
- github.com/go-openapi/loads v0.21.5 // indirect
- github.com/go-openapi/runtime v0.26.2 // indirect
- github.com/go-openapi/spec v0.20.14 // indirect
- github.com/go-openapi/strfmt v0.22.0 // indirect
github.com/go-openapi/swag v0.22.7 // indirect
- github.com/go-openapi/validate v0.22.6 // indirect
- github.com/go-webauthn/x v0.1.6 // indirect
- github.com/goccy/go-json v0.10.2 // indirect
- github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
- github.com/golang/geo v0.0.0-20230421003525-6adc56603217 // indirect
+ github.com/go-webauthn/x v0.1.20 // indirect
+ github.com/goccy/go-json v0.10.5 // indirect
+ github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
- github.com/golang/protobuf v1.5.3 // indirect
+ github.com/golang/protobuf v1.5.4 // indirect
github.com/golang/snappy v0.0.4 // indirect
- github.com/google/go-cmp v0.6.0 // indirect
+ github.com/google/btree v1.1.2 // indirect
+ github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
- github.com/google/go-tpm v0.9.0 // indirect
- github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 // indirect
+ github.com/google/go-tpm v0.9.3 // indirect
github.com/gorilla/css v1.0.1 // indirect
- github.com/gorilla/handlers v1.5.2 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
- github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
- github.com/hashicorp/hcl v1.0.0 // indirect
- github.com/imdario/mergo v0.3.16 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
- github.com/jessevdk/go-flags v1.5.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
- github.com/kr/pretty v0.3.1 // indirect
- github.com/kr/text v0.2.0 // indirect
- github.com/libdns/libdns v0.2.2 // indirect
- github.com/magiconair/properties v1.8.7 // indirect
- github.com/mailru/easyjson v0.7.7 // indirect
+ github.com/libdns/libdns v0.2.3 // indirect
+ github.com/mailru/easyjson v0.9.0 // indirect
github.com/markbates/going v1.0.3 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
- github.com/mattn/go-runewidth v0.0.15 // indirect
- github.com/mholt/acmez/v2 v2.0.1 // indirect
- github.com/miekg/dns v1.1.59 // indirect
+ github.com/mattn/go-runewidth v0.0.16 // indirect
+ github.com/mholt/acmez/v3 v3.1.1 // indirect
+ github.com/miekg/dns v1.1.63 // indirect
+ github.com/minio/crc64nvme v1.0.1 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
- github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
- github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 // indirect
github.com/mschoch/smat v0.2.0 // indirect
+ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/nwaples/rardecode v1.1.3 // indirect
- github.com/oklog/ulid v1.3.1 // indirect
github.com/olekukonko/tablewriter v0.0.5 // indirect
github.com/onsi/ginkgo v1.16.5 // indirect
- github.com/paulmach/orb v0.11.1 // indirect
- github.com/pelletier/go-toml/v2 v2.1.1 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
- github.com/pjbgf/sha1cd v0.3.0 // indirect
+ github.com/pjbgf/sha1cd v0.3.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
- github.com/prometheus/client_model v0.5.0 // indirect
- github.com/prometheus/common v0.46.0 // indirect
- github.com/prometheus/procfs v0.12.0 // indirect
+ github.com/prometheus/client_model v0.6.1 // indirect
+ github.com/prometheus/common v0.62.0 // indirect
+ github.com/prometheus/procfs v0.15.1 // indirect
github.com/rhysd/actionlint v1.6.27 // indirect
github.com/rivo/uniseg v0.4.7 // indirect
- github.com/rogpeppe/go-internal v1.12.0 // indirect
- github.com/rs/xid v1.5.0 // indirect
+ github.com/rogpeppe/go-internal v1.13.1 // indirect
+ github.com/rs/xid v1.6.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/sagikazarmark/locafero v0.4.0 // indirect
- github.com/sagikazarmark/slog-shim v0.1.0 // indirect
- github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect
- github.com/segmentio/asm v1.2.0 // indirect
- github.com/shopspring/decimal v1.4.0 // indirect
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
- github.com/skeema/knownhosts v1.2.1 // indirect
- github.com/sourcegraph/conc v0.3.0 // indirect
- github.com/spf13/afero v1.11.0 // indirect
- github.com/spf13/cast v1.6.0 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
- github.com/spf13/viper v1.18.2 // indirect
+ github.com/skeema/knownhosts v1.3.0 // indirect
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf // indirect
- github.com/subosito/gotenv v1.6.0 // indirect
- github.com/toqueteos/webbrowser v1.2.0 // indirect
- github.com/unknwon/com v1.0.1 // indirect
- github.com/valyala/bytebufferpool v1.0.0 // indirect
- github.com/valyala/fasthttp v1.51.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
- github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect
- github.com/zeebo/blake3 v0.2.3 // indirect
- go.etcd.io/bbolt v1.3.9 // indirect
- go.mongodb.org/mongo-driver v1.13.1 // indirect
- go.opentelemetry.io/otel v1.26.0 // indirect
- go.opentelemetry.io/otel/trace v1.26.0 // indirect
+ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
+ github.com/zeebo/assert v1.3.0 // indirect
+ github.com/zeebo/blake3 v0.2.4 // indirect
+ go.etcd.io/bbolt v1.4.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
- golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
- golang.org/x/mod v0.17.0 // indirect
- golang.org/x/sync v0.7.0 // indirect
- golang.org/x/time v0.5.0 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac // indirect
+ go.uber.org/zap/exp v0.3.0 // indirect
+ golang.org/x/mod v0.24.0 // indirect
+ golang.org/x/time v0.10.0 // indirect
+ golang.org/x/tools v0.31.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
- gopkg.in/yaml.v2 v2.4.0 // indirect
)
replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1
replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0
-replace github.com/nektos/act => gitea.com/gitea/act v0.261.1
-
-exclude github.com/gofrs/uuid v3.2.0+incompatible
-
-exclude github.com/gofrs/uuid v4.0.0+incompatible
-
-exclude github.com/goccy/go-json v0.4.11
-
-exclude github.com/satori/go.uuid v1.2.0
+replace github.com/nektos/act => code.forgejo.org/forgejo/act v1.25.1
replace github.com/mholt/archiver/v3 => code.forgejo.org/forgejo/archiver/v3 v3.5.1
+
+replace github.com/gliderlabs/ssh => code.forgejo.org/forgejo/ssh v0.0.0-20241211213324-5fc306ca0616
+
+replace git.sr.ht/~mariusor/go-xsd-duration => code.forgejo.org/forgejo/go-xsd-duration v0.0.0-20220703122237-02e73435a078
diff --git a/go.sum b/go.sum
index df7c7ccf02..1a285735a0 100644
--- a/go.sum
+++ b/go.sum
@@ -1,159 +1,147 @@
-cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
-cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
-code.forgejo.org/f3/gof3/v3 v3.4.0 h1:60LOo47tAKvr9nVu2qqNjbgRnCKeKx68mRMRBo/hIuA=
-code.forgejo.org/f3/gof3/v3 v3.4.0/go.mod h1:9v7foN46KlEr5gywOSQPn1k5BVpPeuBozsLKlgOQ3YM=
+cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I=
+cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg=
+code.forgejo.org/f3/gof3/v3 v3.10.6 h1:Ru/Iz+pqM8IPi7atUHE7+q7v3O3DRbYgMFqrFTsO1m8=
+code.forgejo.org/f3/gof3/v3 v3.10.6/go.mod h1:K6lQCWQIyN/5rjP/OJL9fMA6fd++satndE20w/I6Kss=
+code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251 h1:HTZl3CBk3ABNYtFI6TPLvJgGKFIhKT5CBk0sbOtkDKU=
+code.forgejo.org/forgejo-contrib/go-libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:PphB88CPbx601QrWPMZATeorACeVmQlyv3u+uUMbSaM=
+code.forgejo.org/forgejo/act v1.25.1 h1:T0CsN9iEWIyJzIbmMHMM9pl1KHzmI41q8mtepqVqdCc=
+code.forgejo.org/forgejo/act v1.25.1/go.mod h1:tSg5CAHnXp4WLNkMa2e9AEDSujMxKzNM4bF2pvvRCYQ=
code.forgejo.org/forgejo/archiver/v3 v3.5.1 h1:UmmbA7D5550uf71SQjarmrn6yKwOGxtEjb3jaYYtmSE=
code.forgejo.org/forgejo/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
+code.forgejo.org/forgejo/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:RArF5AsF9LH4nEoJxqRxcP5r8hhRfWcId84G82YbqzA=
+code.forgejo.org/forgejo/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
+code.forgejo.org/forgejo/levelqueue v1.0.0 h1:9krYpU6BM+j/1Ntj6m+VCAIu0UNnne1/UfU/XgPpLuE=
+code.forgejo.org/forgejo/levelqueue v1.0.0/go.mod h1:fmG6zhVuqim2rxSFOoasgXO8V2W/k9U31VVYqLIRLhQ=
code.forgejo.org/forgejo/reply v1.0.2 h1:dMhQCHV6/O3L5CLWNTol+dNzDAuyCK88z4J/lCdgFuQ=
code.forgejo.org/forgejo/reply v1.0.2/go.mod h1:RyZUfzQLc+fuLIGjTSQWDAJWPiL4WtKXB/FifT5fM7U=
+code.forgejo.org/forgejo/ssh v0.0.0-20241211213324-5fc306ca0616 h1:kEZL84+02jY9RxXM4zHBWZ3Fml0B09cmP1LGkDsCfIA=
+code.forgejo.org/forgejo/ssh v0.0.0-20241211213324-5fc306ca0616/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
+code.forgejo.org/go-chi/binding v1.0.0 h1:EIDJtk9brK7WsT7rvS/D4cxX8XlnhY3LMy8ex1jeHu0=
+code.forgejo.org/go-chi/binding v1.0.0/go.mod h1:fWwqaHj0H1/KeCpBqdvKunflq8pYfciEHI5v3UUeE2E=
+code.forgejo.org/go-chi/cache v1.0.0 h1:akLfGxNlHcacmtutovNtYFSTMsbdcp5MGjAEsP4pxnE=
+code.forgejo.org/go-chi/cache v1.0.0/go.mod h1:OVlZ/TqDYJ+RUJ+R+J+OLxtlyjo3pbjBeK7LAWAB+Vk=
+code.forgejo.org/go-chi/captcha v1.0.1 h1:/oe1fvGOpdyyeGijg3oMYNOYLvEovNvp79Y3gLe3qbk=
+code.forgejo.org/go-chi/captcha v1.0.1/go.mod h1:6EbjSVVa7WoZFENgwK/hLAJZq+HBXtgRsjnIngILC8Y=
+code.forgejo.org/go-chi/session v1.0.1 h1:RNkcJQZJBqlvJoIFXSth87b3kMFZLDBA18VcitD+Z0Y=
+code.forgejo.org/go-chi/session v1.0.1/go.mod h1:y69sjS984wc7k4xyu77yNE5HKeSlBoQW8VSGdsK7RAs=
code.gitea.io/actions-proto-go v0.4.0 h1:OsPBPhodXuQnsspG1sQ4eRE1PeoZyofd7+i73zCwnsU=
code.gitea.io/actions-proto-go v0.4.0/go.mod h1:mn7Wkqz6JbnTOHQpot3yDeHx+O5C9EGhMEE+htvHBas=
-code.gitea.io/gitea-vet v0.2.3 h1:gdFmm6WOTM65rE8FUBTRzeQZYzXePKSSB1+r574hWwI=
-code.gitea.io/gitea-vet v0.2.3/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
-code.gitea.io/sdk/gitea v0.17.1 h1:3jCPOG2ojbl8AcfaUCRYLT5MUcBMFwS0OSK2mA5Zok8=
-code.gitea.io/sdk/gitea v0.17.1/go.mod h1:aCnBqhHpoEWA180gMbaCtdX9Pl6BWBAuuP2miadoTNM=
+code.gitea.io/sdk/gitea v0.20.0 h1:Zm/QDwwZK1awoM4AxdjeAQbxolzx2rIP8dDfmKu+KoU=
+code.gitea.io/sdk/gitea v0.20.0/go.mod h1:faouBHC/zyx5wLgjmRKR62ydyvMzwWf3QnU0bH7Cw6U=
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 h1:TXbikPqa7YRtfU9vS6QJBg77pUvbEb6StRdZO8t1bEY=
codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM=
-connectrpc.com/connect v1.16.2 h1:ybd6y+ls7GOlb7Bh5C8+ghA6SvCBajHwxssO2CGFjqE=
-connectrpc.com/connect v1.16.2/go.mod h1:n2kgwskMHXC+lVqb18wngEpF95ldBHXjZYJussz5FRc=
+connectrpc.com/connect v1.17.0 h1:W0ZqMhtVzn9Zhn2yATuUokDLO5N+gIuBWMOnsQrfmZk=
+connectrpc.com/connect v1.17.0/go.mod h1:0292hj1rnx8oFrStN7cB4jjVBeqs+Yx5yDIC2prWDO8=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
-git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg=
-git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs=
-gitea.com/gitea/act v0.261.1 h1:iACWLc/k8wct9fCF2WdYKqn2Hxx6NjW9zbOP79HF4H4=
-gitea.com/gitea/act v0.261.1/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok=
-gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed h1:EZZBtilMLSZNWtHHcgq2mt6NSGhJSZBuduAlinMEmso=
-gitea.com/go-chi/binding v0.0.0-20240430071103-39a851e106ed/go.mod h1:E3i3cgB04dDx0v3CytCgRTTn9Z/9x891aet3r456RVw=
-gitea.com/go-chi/cache v0.2.0 h1:E0npuTfDW6CT1yD8NMDVc1SK6IeRjfmRL2zlEsCEd7w=
-gitea.com/go-chi/cache v0.2.0/go.mod h1:iQlVK2aKTZ/rE9UcHyz9pQWGvdP9i1eI2spOpzgCrtE=
-gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098 h1:p2ki+WK0cIeNQuqjR98IP2KZQKRzJJiV7aTeMAFwaWo=
-gitea.com/go-chi/captcha v0.0.0-20240315150714-fb487f629098/go.mod h1:LjzIOHlRemuUyO7WR12fmm18VZIlCAaOt9L3yKw40pk=
-gitea.com/go-chi/session v0.0.0-20240316035857-16768d98ec96 h1:IFDiMBObsP6CZIRaDLd54SR6zPYAffPXiXck5Xslu0Q=
-gitea.com/go-chi/session v0.0.0-20240316035857-16768d98ec96/go.mod h1:0iEpFKnwO5dG0aF98O4eq6FMsAiXkNBaDIlUOlq4BtM=
-gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4 h1:IFT+hup2xejHqdhS7keYWioqfmxdnfblFDTGoOwcZ+o=
-gitea.com/lunny/levelqueue v0.4.2-0.20230414023320-3c0159fe0fe4/go.mod h1:HBqmLbz56JWpfEGG0prskAV97ATNRoj5LDmPicD22hU=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a h1:lSA0F4e9A2NcQSqGqTOXqu2aRi/XEQxDCBwM8yJtE6s=
gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0pAQhH8yz+DNjUbjppKQzKFAn28TMYPB6IU=
+github.com/42wim/httpsig v1.2.2 h1:ofAYoHUNs/MJOLqQ8hIxeyz2QxOz8qdSVvp3PX/oPgA=
+github.com/42wim/httpsig v1.2.2/go.mod h1:P/UYo7ytNBFwc+dg35IubuAUIs8zj5zzFIgUCEl55WY=
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121 h1:r3qt8PCHnfjOv9PN3H+XXKmDA1dfFMIN1AislhlA/ps=
github.com/42wim/sshsig v0.0.0-20211121163825-841cf5bbc121/go.mod h1:Ock8XgA7pvULhIaHGAk/cDnRfNrF9Jey81nPcc403iU=
github.com/6543/go-version v1.3.1 h1:HvOp+Telns7HWJ2Xo/05YXQSB2bE0WmVgbHqwMPZT4U=
github.com/6543/go-version v1.3.1/go.mod h1:oqFAHCwtLVUTLdhQmVZWYvaHXTdsbB4SY85at64SQEo=
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/ClickHouse/ch-go v0.61.5 h1:zwR8QbYI0tsMiEcze/uIMK+Tz1D3XZXLdNrlaOpeEI4=
-github.com/ClickHouse/ch-go v0.61.5/go.mod h1:s1LJW/F/LcFs5HJnuogFMta50kKDO0lf9zzfrbl0RQg=
-github.com/ClickHouse/clickhouse-go/v2 v2.24.0 h1:L/n/pVVpk95KtkHOiKuSnO7cu2ckeW4gICbbOh5qs74=
-github.com/ClickHouse/clickhouse-go/v2 v2.24.0/go.mod h1:iDTViXk2Fgvf1jn2dbJd1ys+fBkdD1UMRnXlwmhijhQ=
-github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo=
github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ=
github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
-github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
-github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
-github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
-github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
-github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
-github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
-github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
-github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
-github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78=
-github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
-github.com/PuerkitoBio/goquery v1.9.2 h1:4/wZksC3KgkQw7SQgkKotmKljk0M6V8TUvA8Wb4yPeE=
-github.com/PuerkitoBio/goquery v1.9.2/go.mod h1:GHPCaP0ODyyxqcNoFGYlAprUFH81NuRPd0GX3Zu2Mvk=
-github.com/RoaringBitmap/roaring v1.7.0 h1:OZF303tJCER1Tj3x+aArx/S5X7hrT186ri6JjrGvG68=
-github.com/RoaringBitmap/roaring v1.7.0/go.mod h1:6AXUsoIEzDTFFQCe1RbGA6uFONMhvejWj5rqITANK90=
-github.com/alecthomas/assert/v2 v2.7.0 h1:QtqSACNS3tF7oasA8CU6A6sXZSBDqnm7RfpLl9bZqbE=
-github.com/alecthomas/assert/v2 v2.7.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
+github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
+github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
+github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw=
+github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
+github.com/PuerkitoBio/goquery v1.10.2 h1:7fh2BdHcG6VFZsK7toXBT/Bh1z5Wmy8Q9MV9HqT2AM8=
+github.com/PuerkitoBio/goquery v1.10.2/go.mod h1:0guWGjcLu9AYC7C1GHnpysHy056u9aEkUHwhdnePMCU=
+github.com/RoaringBitmap/roaring/v2 v2.4.5 h1:uGrrMreGjvAtTBobc0g5IrW1D5ldxDQYe2JW2gggRdg=
+github.com/RoaringBitmap/roaring/v2 v2.4.5/go.mod h1:FiJcsfkGje/nZBZgCu0ZxCPOKD/hVXDS2dXi7/eUFE0=
+github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2 h1:cSXom2MoKJ9KPPw29RoZtHvUETY4F4n/kXl8m9btnQ0=
+github.com/SaveTheRbtz/zstd-seekable-format-go/pkg v0.7.2/go.mod h1:JitQWJ8JuV4Y87l8VsHiiwhb3cgdyn68mX40s7NT6PA=
+github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
+github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
github.com/alecthomas/chroma/v2 v2.2.0/go.mod h1:vf4zrexSH54oEjJ7EdB65tGNHmH3pGZmVkgTP5RHvAs=
-github.com/alecthomas/chroma/v2 v2.14.0 h1:R3+wzpnUArGcQz7fCETQBzO5n9IMNi13iIs46aU4V9E=
-github.com/alecthomas/chroma/v2 v2.14.0/go.mod h1:QolEbTfmUHIMVpBqxeDnNBj2uoeI4EbYP4i6n68SG4I=
+github.com/alecthomas/chroma/v2 v2.15.0 h1:LxXTQHFoYrstG2nnV9y2X5O94sOBzf0CIUpSTbpxvMc=
+github.com/alecthomas/chroma/v2 v2.15.0/go.mod h1:gUhVLrPDXPtp/f+L1jo9xepo9gL4eLwRuGAunSZMkio=
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA=
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
-github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
-github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M=
-github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY=
-github.com/andybalholm/cascadia v1.3.2 h1:3Xi6Dw5lHF15JtdcmAHD3i1+T8plmv7BQ/nsViSLyss=
-github.com/andybalholm/cascadia v1.3.2/go.mod h1:7gtRlve5FxPPgIgX36uWBX58OdBsSS6lUvCFb+h7KvU=
+github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
+github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
+github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
+github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
-github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
-github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bits-and-blooms/bitset v1.12.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
-github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE=
-github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
+github.com/bits-and-blooms/bitset v1.22.0 h1:Tquv9S8+SGaS3EhyA+up3FXzmkhxPGjQQCkcs2uw7w4=
+github.com/bits-and-blooms/bitset v1.22.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb h1:m935MPodAbYS46DG4pJSv7WO+VECIWUQ7OJYSoTrMh4=
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
-github.com/blevesearch/bleve/v2 v2.4.0 h1:2xyg+Wv60CFHYccXc+moGxbL+8QKT/dZK09AewHgKsg=
-github.com/blevesearch/bleve/v2 v2.4.0/go.mod h1:IhQHoFAbHgWKYavb9rQgQEJJVMuY99cKdQ0wPpst2aY=
-github.com/blevesearch/bleve_index_api v1.1.6 h1:orkqDFCBuNU2oHW9hN2YEJmet+TE9orml3FCGbl1cKk=
-github.com/blevesearch/bleve_index_api v1.1.6/go.mod h1:PbcwjIcRmjhGbkS/lJCpfgVSMROV6TRubGGAODaK1W8=
-github.com/blevesearch/geo v0.1.20 h1:paaSpu2Ewh/tn5DKn/FB5SzvH0EWupxHEIwbCk/QPqM=
-github.com/blevesearch/geo v0.1.20/go.mod h1:DVG2QjwHNMFmjo+ZgzrIq2sfCh6rIHzy9d9d0B59I6w=
-github.com/blevesearch/go-faiss v1.0.13 h1:zfFs7ZYD0NqXVSY37j0JZjZT1BhE9AE4peJfcx/NB4A=
-github.com/blevesearch/go-faiss v1.0.13/go.mod h1:jrxHrbl42X/RnDPI+wBoZU8joxxuRwedrxqswQ3xfU8=
+github.com/blevesearch/bleve/v2 v2.5.2 h1:Ab0r0MODV2C5A6BEL87GqLBySqp/s9xFgceCju6BQk8=
+github.com/blevesearch/bleve/v2 v2.5.2/go.mod h1:5Dj6dUQxZM6aqYT3eutTD/GpWKGFSsV8f7LDidFbwXo=
+github.com/blevesearch/bleve_index_api v1.2.8 h1:Y98Pu5/MdlkRyLM0qDHostYo7i+Vv1cDNhqTeR4Sy6Y=
+github.com/blevesearch/bleve_index_api v1.2.8/go.mod h1:rKQDl4u51uwafZxFrPD1R7xFOwKnzZW7s/LSeK4lgo0=
+github.com/blevesearch/geo v0.2.3 h1:K9/vbGI9ehlXdxjxDRJtoAMt7zGAsMIzc6n8zWcwnhg=
+github.com/blevesearch/geo v0.2.3/go.mod h1:K56Q33AzXt2YExVHGObtmRSFYZKYGv0JEN5mdacJJR8=
+github.com/blevesearch/go-faiss v1.0.25 h1:lel1rkOUGbT1CJ0YgzKwC7k+XH0XVBHnCVWahdCXk4U=
+github.com/blevesearch/go-faiss v1.0.25/go.mod h1:OMGQwOaRRYxrmeNdMrXJPvVx8gBnvE5RYrr0BahNnkk=
github.com/blevesearch/go-porterstemmer v1.0.3 h1:GtmsqID0aZdCSNiY8SkuPJ12pD4jI+DdXTAn4YRcHCo=
github.com/blevesearch/go-porterstemmer v1.0.3/go.mod h1:angGc5Ht+k2xhJdZi511LtmxuEf0OVpvUUNrwmM1P7M=
github.com/blevesearch/gtreap v0.1.1 h1:2JWigFrzDMR+42WGIN/V2p0cUvn4UP3C4Q5nmaZGW8Y=
github.com/blevesearch/gtreap v0.1.1/go.mod h1:QaQyDRAT51sotthUWAH4Sj08awFSSWzgYICSZ3w0tYk=
github.com/blevesearch/mmap-go v1.0.4 h1:OVhDhT5B/M1HNPpYPBKIEJaD0F3Si+CrEKULGCDPWmc=
github.com/blevesearch/mmap-go v1.0.4/go.mod h1:EWmEAOmdAS9z/pi/+Toxu99DnsbhG1TIxUoRmJw/pSs=
-github.com/blevesearch/scorch_segment_api/v2 v2.2.9 h1:3nBaSBRFokjE4FtPW3eUDgcAu3KphBg1GP07zy/6Uyk=
-github.com/blevesearch/scorch_segment_api/v2 v2.2.9/go.mod h1:ckbeb7knyOOvAdZinn/ASbB7EA3HoagnJkmEV3J7+sg=
+github.com/blevesearch/scorch_segment_api/v2 v2.3.10 h1:Yqk0XD1mE0fDZAJXTjawJ8If/85JxnLd8v5vG/jWE/s=
+github.com/blevesearch/scorch_segment_api/v2 v2.3.10/go.mod h1:Z3e6ChN3qyN35yaQpl00MfI5s8AxUJbpTR/DL8QOQ+8=
github.com/blevesearch/segment v0.9.1 h1:+dThDy+Lvgj5JMxhmOVlgFfkUtZV2kw49xax4+jTfSU=
github.com/blevesearch/segment v0.9.1/go.mod h1:zN21iLm7+GnBHWTao9I+Au/7MBiL8pPFtJBJTsk6kQw=
github.com/blevesearch/snowballstem v0.9.0 h1:lMQ189YspGP6sXvZQ4WZ+MLawfV8wOmPoD/iWeNXm8s=
github.com/blevesearch/snowballstem v0.9.0/go.mod h1:PivSj3JMc8WuaFkTSRDW2SlrulNWPl4ABg1tC/hlgLs=
github.com/blevesearch/upsidedown_store_api v1.0.2 h1:U53Q6YoWEARVLd1OYNc9kvhBMGZzVrdmaozG2MfoB+A=
github.com/blevesearch/upsidedown_store_api v1.0.2/go.mod h1:M01mh3Gpfy56Ps/UXHjEO/knbqyQ1Oamg8If49gRwrQ=
-github.com/blevesearch/vellum v1.0.10 h1:HGPJDT2bTva12hrHepVT3rOyIKFFF4t7Gf6yMxyMIPI=
-github.com/blevesearch/vellum v1.0.10/go.mod h1:ul1oT0FhSMDIExNjIxHqJoGpVrBpKCdgDQNxfqgJt7k=
-github.com/blevesearch/zapx/v11 v11.3.10 h1:hvjgj9tZ9DeIqBCxKhi70TtSZYMdcFn7gDb71Xo/fvk=
-github.com/blevesearch/zapx/v11 v11.3.10/go.mod h1:0+gW+FaE48fNxoVtMY5ugtNHHof/PxCqh7CnhYdnMzQ=
-github.com/blevesearch/zapx/v12 v12.3.10 h1:yHfj3vXLSYmmsBleJFROXuO08mS3L1qDCdDK81jDl8s=
-github.com/blevesearch/zapx/v12 v12.3.10/go.mod h1:0yeZg6JhaGxITlsS5co73aqPtM04+ycnI6D1v0mhbCs=
-github.com/blevesearch/zapx/v13 v13.3.10 h1:0KY9tuxg06rXxOZHg3DwPJBjniSlqEgVpxIqMGahDE8=
-github.com/blevesearch/zapx/v13 v13.3.10/go.mod h1:w2wjSDQ/WBVeEIvP0fvMJZAzDwqwIEzVPnCPrz93yAk=
-github.com/blevesearch/zapx/v14 v14.3.10 h1:SG6xlsL+W6YjhX5N3aEiL/2tcWh3DO75Bnz77pSwwKU=
-github.com/blevesearch/zapx/v14 v14.3.10/go.mod h1:qqyuR0u230jN1yMmE4FIAuCxmahRQEOehF78m6oTgns=
-github.com/blevesearch/zapx/v15 v15.3.13 h1:6EkfaZiPlAxqXz0neniq35my6S48QI94W/wyhnpDHHQ=
-github.com/blevesearch/zapx/v15 v15.3.13/go.mod h1:Turk/TNRKj9es7ZpKK95PS7f6D44Y7fAFy8F4LXQtGg=
-github.com/blevesearch/zapx/v16 v16.0.12 h1:Uccxvjmn+hQ6ywQP+wIiTpdq9LnAviGoryJOmGwAo/I=
-github.com/blevesearch/zapx/v16 v16.0.12/go.mod h1:MYnOshRfSm4C4drxx1LGRI+MVFByykJ2anDY1fxdk9Q=
+github.com/blevesearch/vellum v1.1.0 h1:CinkGyIsgVlYf8Y2LUQHvdelgXr6PYuvoDIajq6yR9w=
+github.com/blevesearch/vellum v1.1.0/go.mod h1:QgwWryE8ThtNPxtgWJof5ndPfx0/YMBh+W2weHKPw8Y=
+github.com/blevesearch/zapx/v11 v11.4.2 h1:l46SV+b0gFN+Rw3wUI1YdMWdSAVhskYuvxlcgpQFljs=
+github.com/blevesearch/zapx/v11 v11.4.2/go.mod h1:4gdeyy9oGa/lLa6D34R9daXNUvfMPZqUYjPwiLmekwc=
+github.com/blevesearch/zapx/v12 v12.4.2 h1:fzRbhllQmEMUuAQ7zBuMvKRlcPA5ESTgWlDEoB9uQNE=
+github.com/blevesearch/zapx/v12 v12.4.2/go.mod h1:TdFmr7afSz1hFh/SIBCCZvcLfzYvievIH6aEISCte58=
+github.com/blevesearch/zapx/v13 v13.4.2 h1:46PIZCO/ZuKZYgxI8Y7lOJqX3Irkc3N8W82QTK3MVks=
+github.com/blevesearch/zapx/v13 v13.4.2/go.mod h1:knK8z2NdQHlb5ot/uj8wuvOq5PhDGjNYQQy0QDnopZk=
+github.com/blevesearch/zapx/v14 v14.4.2 h1:2SGHakVKd+TrtEqpfeq8X+So5PShQ5nW6GNxT7fWYz0=
+github.com/blevesearch/zapx/v14 v14.4.2/go.mod h1:rz0XNb/OZSMjNorufDGSpFpjoFKhXmppH9Hi7a877D8=
+github.com/blevesearch/zapx/v15 v15.4.2 h1:sWxpDE0QQOTjyxYbAVjt3+0ieu8NCE0fDRaFxEsp31k=
+github.com/blevesearch/zapx/v15 v15.4.2/go.mod h1:1pssev/59FsuWcgSnTa0OeEpOzmhtmr/0/11H0Z8+Nw=
+github.com/blevesearch/zapx/v16 v16.2.4 h1:tGgfvleXTAkwsD5mEzgM3zCS/7pgocTCnO1oyAUjlww=
+github.com/blevesearch/zapx/v16 v16.2.4/go.mod h1:Rti/REtuuMmzwsI8/C/qIzRaEoSK/wiFYw5e5ctUKKs=
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
-github.com/bradfitz/gomemcache v0.0.0-20190329173943-551aad21a668/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA=
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
-github.com/buildkite/terminal-to-html/v3 v3.10.1 h1:znT9eD26LQ59dDJJEpMCwkP4wEptEAPi74hsTBuHdEo=
-github.com/buildkite/terminal-to-html/v3 v3.10.1/go.mod h1:qtuRyYs6/Sw3FS9jUyVEaANHgHGqZsGqMknPLyau5cQ=
-github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
-github.com/caddyserver/certmagic v0.21.0 h1:yDoifClc4hIxhHer3AxUj4buhF+NzRR6torw/AOnuUE=
-github.com/caddyserver/certmagic v0.21.0/go.mod h1:OgUZNXYV/ylYoFJNmoYVR5nntydLNMQISePPgqZTyhc=
-github.com/caddyserver/zerossl v0.1.2 h1:tlEu1VzWGoqcCpivs9liKAKhfpJWYJkHEMmlxRbVAxE=
-github.com/caddyserver/zerossl v0.1.2/go.mod h1:wtiJEHbdvunr40ZzhXlnIkOB8Xj4eKtBKizCcZitJiQ=
+github.com/buildkite/terminal-to-html/v3 v3.16.8 h1:QN/daUob6cmK8GcdKnwn9+YTlPr1vNj+oeAIiJK6fPc=
+github.com/buildkite/terminal-to-html/v3 v3.16.8/go.mod h1:+k1KVKROZocrTLsEQ9PEf9A+8+X8uaVV5iO1ZIOwKYM=
+github.com/caddyserver/certmagic v0.22.2 h1:qzZURXlrxwR5m25/jpvVeEyJHeJJMvAwe5zlMufOTQk=
+github.com/caddyserver/certmagic v0.22.2/go.mod h1:hbqE7BnkjhX5IJiFslPmrSeobSeZvI6ux8tyxhsd6qs=
+github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA=
+github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4=
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a h1:MISbI8sU/PSK/ztvmWKFcI7UGb5/HQT7B+i3a2myKgI=
github.com/cention-sany/utf7 v0.0.0-20170124080048-26cad61bd60a/go.mod h1:2GxOXOlEPAMFPfp014mK1SWq8G8BN8o7/dfYqJrVGn8=
-github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
-github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
+github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chi-middleware/proxy v1.1.1 h1:4HaXUp8o2+bhHr1OhVy+VjN0+L7/07JDcn6v7YrTjrQ=
github.com/chi-middleware/proxy v1.1.1/go.mod h1:jQwMEJct2tz9VmtCELxvnXoMfa+SOdikvbVJVHv/M+0=
github.com/chromedp/cdproto v0.0.0-20230802225258-3cf4e6d46a89/go.mod h1:GKljq0VrfU4D5yc+2qA6OVr8pmO/MBbPEWqWQ/oqGEs=
@@ -162,29 +150,19 @@ github.com/chromedp/sysutil v1.0.0/go.mod h1:kgWmDdq8fTzXYcKIBqIYvRRTnYb9aNS9moA
github.com/chzyer/logex v1.2.1/go.mod h1:JLbx6lG2kDbNRFnfkgvh4eRJRPX1QCoOIWomwysCBrQ=
github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8=
-github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
-github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
-github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
-github.com/couchbase/go-couchbase v0.1.1 h1:ClFXELcKj/ojyoTYbsY34QUrrYCBi/1G749sXSCkdhk=
-github.com/couchbase/go-couchbase v0.1.1/go.mod h1:+/bddYDxXsf9qt0xpDUtRR47A2GjaXmGGAqQ/k3GJ8A=
-github.com/couchbase/gomemcached v0.3.0 h1:XkMDdP6w7rtvLijDE0/RhcccX+XvAk5cboyBv1YcI0U=
-github.com/couchbase/gomemcached v0.3.0/go.mod h1:mxliKQxOv84gQ0bJWbI+w9Wxdpt9HjDvgW9MjCym5Vo=
-github.com/couchbase/goutils v0.1.2 h1:gWr8B6XNWPIhfalHNog3qQKfGiYyh4K4VhO3P2o9BCs=
-github.com/couchbase/goutils v0.1.2/go.mod h1:h89Ek/tiOxxqjz30nPPlwZdQbdB8BwgnuBxeoUe/ViE=
-github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
-github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0=
+github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
+github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc=
+github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/cupcake/rdb v0.0.0-20161107195141-43ba34106c76/go.mod h1:vYwsqCOLxGiisLwp9rITslkFNpZD5rz43tf41QFkTWY=
-github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
-github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
+github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM=
+github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davidmz/go-pageant v1.0.2 h1:bPblRCh5jGU+Uptpz6LgMZGD5hJoOt7otgT454WvHn0=
github.com/davidmz/go-pageant v1.0.2/go.mod h1:P2EDDnMqIwG5Rrp05dTRITj9z2zpGcD9efWSkTNKLIE=
-github.com/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+8Y+8shw=
-github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/djherbis/buffer v1.1.0/go.mod h1:VwN8VdFkMY0DCALdY8o00d3IZ6Amz/UNVMWcSaJT44o=
@@ -195,18 +173,18 @@ github.com/djherbis/nio/v3 v3.0.1/go.mod h1:Ng4h80pbZFMla1yKzm61cF0tqqilXZYrogmW
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
-github.com/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
-github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
-github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5 h1:iFaUwBSo5Svw6L7HYpRu/0lE3e0BaElwnNO1qkNQxBY=
+github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
+github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dsnet/compress v0.0.2-0.20210315054119-f66993602bf5/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
+github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707 h1:2tV76y6Q9BB+NEBasnqvs7e49aEBFI8ejC89PSnWH+4=
+github.com/dsnet/compress v0.0.2-0.20230904184137-39efe44ab707/go.mod h1:qssHWj60/X5sZFNxpG4HBPDHVqxNm4DfnCKgrbZOT+s=
github.com/dsnet/golib v0.0.0-20171103203638-1ea166775780/go.mod h1:Lj+Z9rebOhdfkVLjJ8T6VcRQv3SXugXy999NBtR9aFY=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
-github.com/editorconfig/editorconfig-core-go/v2 v2.6.2 h1:dKG8sc7n321deIVRcQtwlMNoBEra7j0qQ8RwxO8RN0w=
-github.com/editorconfig/editorconfig-core-go/v2 v2.6.2/go.mod h1:7dvD3GCm7eBw53xZ/lsiq72LqobdMg3ITbMBxnmJmqY=
-github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
-github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU=
-github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/editorconfig/editorconfig-core-go/v2 v2.6.3 h1:XVUp6qW3BIkmM3/1EkrHpa6bL56APOynfXcZEmIgOhs=
+github.com/editorconfig/editorconfig-core-go/v2 v2.6.3/go.mod h1:ThHVc+hqbUsmE1wmK/MASpQEhCleWu1JDJDNhUOMy0c=
+github.com/elazarl/goproxy v1.4.0 h1:4GyuSbFa+s26+3rmYNSuUVsx+HgPrV1bk1jXI0l9wjM=
+github.com/elazarl/goproxy v1.4.0/go.mod h1:X/5W/t+gzDyLfHW4DrMdpjqYjpXsURlBt9lpBDxZZZQ=
github.com/emersion/go-imap v1.2.1 h1:+s9ZjMEjOB8NzZMVTM3cCenz2JrQIGGo5j1df19WjTA=
github.com/emersion/go-imap v1.2.1/go.mod h1:Qlx1FSx2FTxjnjWpIlVNEuX+ylerZQNFE5NsmKFSejY=
github.com/emersion/go-message v0.15.0/go.mod h1:wQUEfE+38+7EW8p8aZ96ptg6bAb1iwdgej19uXASlE4=
@@ -218,22 +196,16 @@ github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
-github.com/felixge/fgprof v0.9.4 h1:ocDNwMFlnA0NU0zSB3I52xkO4sFXk80VK9lXjLClu88=
-github.com/felixge/fgprof v0.9.4/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM=
-github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
-github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY=
+github.com/felixge/fgprof v0.9.5/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
-github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
-github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
-github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
-github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
-github.com/fxamacker/cbor/v2 v2.5.0 h1:oHsG0V/Q6E/wqTS2O1Cozzsy69nqCiguo5Q1a1ADivE=
-github.com/fxamacker/cbor/v2 v2.5.0/go.mod h1:TA1xS00nchWmaBnEIxPSE5oHLuJBAVvqrtAnWBwBCVo=
-github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE=
-github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8=
+github.com/fsnotify/fsnotify v1.8.0 h1:dAwr6QBTBZIkG8roQaJjGof0pp0EeF+tNV7YBP3F/8M=
+github.com/fsnotify/fsnotify v1.8.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
+github.com/fxamacker/cbor/v2 v2.8.0 h1:fFtUGXUzXPHTIUdne5+zzMPTfffl3RD5qYnkY40vtxU=
+github.com/fxamacker/cbor/v2 v2.8.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9 h1:j2TrkUG/NATGi/EQS+MvEoF79CxiRUmT16ErFroNcKI=
github.com/go-ap/activitypub v0.0.0-20231114162308-e219254dc5c9/go.mod h1:cJ9Ye0ZNSMN7RzZDBRY3E+8M3Bpf/R1JX22Ir9yX6WI=
github.com/go-ap/errors v0.0.0-20231003111023-183eef4b31b7 h1:I2nuhyVI/48VXoRCCZR2hYBgnSXa+EuDJf/VyX06TC0=
@@ -243,162 +215,119 @@ github.com/go-ap/jsonld v0.0.0-20221030091449-f2a191312c73/go.mod h1:jyveZeGw5La
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-chi/chi/v5 v5.0.1/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
-github.com/go-chi/chi/v5 v5.0.14 h1:PyEwo2Vudraa0x/Wl6eDRRW2NXBvekgfxyydcM0WGE0=
-github.com/go-chi/chi/v5 v5.0.14/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0=
+github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4=
github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
github.com/go-co-op/gocron v1.37.0 h1:ZYDJGtQ4OMhTLKOKMIch+/CY70Brbb1dGdooLEhh7b0=
github.com/go-co-op/gocron v1.37.0/go.mod h1:3L/n6BkO7ABj+TrfSVXLRzsP26zmikL4ISkLQ0O8iNY=
-github.com/go-enry/go-enry/v2 v2.8.8 h1:EhfxWpw4DQ3WEFB1Y77X8vKqZL0D0EDUUWYDUAIv9/4=
-github.com/go-enry/go-enry/v2 v2.8.8/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
+github.com/go-enry/go-enry/v2 v2.9.2 h1:giOQAtCgBX08kosrX818DCQJTCNtKwoPBGu0qb6nKTY=
+github.com/go-enry/go-enry/v2 v2.9.2/go.mod h1:9yrj4ES1YrbNb1Wb7/PWYr2bpaCXUGRt0uafN0ISyG8=
github.com/go-enry/go-oniguruma v1.2.1 h1:k8aAMuJfMrqm/56SG2lV9Cfti6tC4x8673aHCcBk+eo=
github.com/go-enry/go-oniguruma v1.2.1/go.mod h1:bWDhYP+S6xZQgiRL7wlTScFYBe023B6ilRZbCAD5Hf4=
-github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
-github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw=
-github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg=
-github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo=
+github.com/go-fed/httpsig v1.1.0 h1:9M+hb0jkEICD8/cAiNqEB66R87tTINszBRTjwjQzWcI=
github.com/go-fed/httpsig v1.1.0/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
-github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e h1:oRq/fiirun5HqlEWMLIcDmLpIELlG4iGbd0s8iqgPi8=
-github.com/go-fed/httpsig v1.1.1-0.20201223112313-55836744818e/go.mod h1:RCMrTZvN1bJYtofsG4rd5NaO5obxQ5xBkdiS7xsT7bM=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
-github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
-github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow=
+github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM=
+github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
-github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4=
-github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY=
+github.com/go-git/go-git/v5 v5.13.2 h1:7O7xvsK7K+rZPKW6AQR1YyNhfywkv7B8/FsP3ki6Zv0=
+github.com/go-git/go-git/v5 v5.13.2/go.mod h1:hWdW5P4YZRjmpGHwRH2v3zkWcNl6HeXaXQEMGb3NJ9A=
+github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
+github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A=
github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc=
-github.com/go-openapi/analysis v0.22.2 h1:ZBmNoP2h5omLKr/srIC9bfqrUGzT6g6gNv03HE9Vpj0=
-github.com/go-openapi/analysis v0.22.2/go.mod h1:pDF4UbZsQTo/oNuRfAWWd4dAh4yuYf//LYorPTjrpvo=
-github.com/go-openapi/errors v0.21.0 h1:FhChC/duCnfoLj1gZ0BgaBmzhJC2SL/sJr8a2vAobSY=
-github.com/go-openapi/errors v0.21.0/go.mod h1:jxNTMUxRCKj65yb/okJGEtahVd7uvWnuWfj53bse4ho=
-github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
-github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q=
github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs=
github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU=
github.com/go-openapi/jsonreference v0.20.4/go.mod h1:5pZJyJP2MnYCpoeoMAql78cCHauHj0V9Lhc506VOpw4=
-github.com/go-openapi/loads v0.21.5 h1:jDzF4dSoHw6ZFADCGltDb2lE4F6De7aWSpe+IcsRzT0=
-github.com/go-openapi/loads v0.21.5/go.mod h1:PxTsnFBoBe+z89riT+wYt3prmSBP6GDAQh2l9H1Flz8=
-github.com/go-openapi/runtime v0.26.2 h1:elWyB9MacRzvIVgAZCBJmqTi7hBzU0hlKD4IvfX0Zl0=
-github.com/go-openapi/runtime v0.26.2/go.mod h1:O034jyRZ557uJKzngbMDJXkcKJVzXJiymdSfgejrcRw=
github.com/go-openapi/spec v0.20.14 h1:7CBlRnw+mtjFGlPDRZmAMnq35cRzI91xj03HVyUi/Do=
github.com/go-openapi/spec v0.20.14/go.mod h1:8EOhTpBoFiask8rrgwbLC3zmJfz4zsCUueRuPM6GNkw=
-github.com/go-openapi/strfmt v0.22.0 h1:Ew9PnEYc246TwrEspvBdDHS4BVKXy/AOVsfqGDgAcaI=
-github.com/go-openapi/strfmt v0.22.0/go.mod h1:HzJ9kokGIju3/K6ap8jL+OlGAbjpSv27135Yr9OivU4=
github.com/go-openapi/swag v0.22.7 h1:JWrc1uc/P9cSomxfnsFSVWoE1FW6bNbrVPmpQYpCcR8=
github.com/go-openapi/swag v0.22.7/go.mod h1:Gl91UqO+btAM0plGGxHqJcQZ1ZTy6jbmridBTsDy8A0=
-github.com/go-openapi/validate v0.22.6 h1:+NhuwcEYpWdO5Nm4bmvhGLW0rt1Fcc532Mu3wpypXfo=
-github.com/go-openapi/validate v0.22.6/go.mod h1:eaddXSqKeTg5XpSmj1dYyFTK/95n/XHwcOY+BMxKMyM=
-github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
-github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
-github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
-github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
-github.com/go-swagger/go-swagger v0.30.5 h1:SQ2+xSonWjjoEMOV5tcOnZJVlfyUfCBhGQGArS1b9+U=
-github.com/go-swagger/go-swagger v0.30.5/go.mod h1:cWUhSyCNqV7J1wkkxfr5QmbcnCewetCdvEXqgPvbc/Q=
-github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
-github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
+github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtSb/iI=
+github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
-github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
-github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
-github.com/go-testfixtures/testfixtures/v3 v3.11.0 h1:XxQr8AnPORcZkyNd7go5UNLPD3dULN8ixYISlzrlfEQ=
-github.com/go-testfixtures/testfixtures/v3 v3.11.0/go.mod h1:THmudHF1Ixq++J2/UodcJpxUphfyEd77m83TvDtryqE=
-github.com/go-webauthn/webauthn v0.10.0 h1:yuW2e1tXnRAwAvKrR4q4LQmc6XtCMH639/ypZGhZCwk=
-github.com/go-webauthn/webauthn v0.10.0/go.mod h1:l0NiauXhL6usIKqNLCUM3Qir43GK7ORg8ggold0Uv/Y=
-github.com/go-webauthn/x v0.1.6 h1:QNAX+AWeqRt9loE8mULeWJCqhVG5D/jvdmJ47fIWCkQ=
-github.com/go-webauthn/x v0.1.6/go.mod h1:W8dFVZ79o4f+nY1eOUICy/uq5dhrRl7mxQkYhXTo0FA=
+github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
+github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
+github.com/go-webauthn/webauthn v0.12.2 h1:yLaNPgBUEXDQtWnOjhsGhMMCEWbXwjg/aNkC8riJQI8=
+github.com/go-webauthn/webauthn v0.12.2/go.mod h1:Q8SZPPj4sZ469fNTcQXxRpzJOdb30jQrn/36FX8jilA=
+github.com/go-webauthn/x v0.1.20 h1:brEBDqfiPtNNCdS/peu8gARtq8fIPsHz0VzpPjGvgiw=
+github.com/go-webauthn/x v0.1.20/go.mod h1:n/gAc8ssZJGATM0qThE+W+vfgXiMedsWi3wf/C4lld0=
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/gobwas/httphead v0.1.0/go.mod h1:O/RXo79gxV8G+RqlR/otEwx4Q36zl9rqC5u12GKvMCM=
github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw=
github.com/gobwas/ws v1.2.1/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/KY=
-github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
-github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
-github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
+github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
+github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f h1:3BSP1Tbs2djlpprl7wCLuiqMaUh5SJkkzI2gDs+FgLs=
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f/go.mod h1:Pcatq5tYkCW2Q6yrR2VRHlbHpZ/R4/7qyL1TCF7vl14=
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85 h1:UjoPNDAQ5JPCjlxoJd6K8ALZqSDDhk2ymieAZOVaDg0=
github.com/gogs/go-gogs-client v0.0.0-20210131175652-1d7215cd8d85/go.mod h1:fR6z1Ie6rtF7kl/vBYMfgD5/G5B1blui7z426/sj2DU=
-github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
-github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
-github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
-github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
-github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA=
-github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
-github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A=
-github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI=
-github.com/golang/geo v0.0.0-20230421003525-6adc56603217 h1:HKlyj6in2JV6wVkmQ4XmG/EIm+SCYlPZ+V4GWit7Z+I=
-github.com/golang/geo v0.0.0-20230421003525-6adc56603217/go.mod h1:8wI0hitZ3a1IxZfeH3/5I97CI8i5cLGsYe7xNhQGs9U=
+github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
+github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
+github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
+github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
-github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
-github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
+github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
-github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
+github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
+github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-github/v57 v57.0.0 h1:L+Y3UPTY8ALM8x+TV0lg+IEBI+upibemtBD8Q9u7zHs=
-github.com/google/go-github/v57 v57.0.0/go.mod h1:s0omdnye0hvK/ecLvpsGfJMiRt85PimQh4oygmLIxHw=
+github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
+github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+github.com/google/go-github/v64 v64.0.0 h1:4G61sozmY3eiPAjjoOHponXDBONm+utovTKbyUb2Qdg=
+github.com/google/go-github/v64 v64.0.0/go.mod h1:xB3vqMQNdHzilXBiO2I+M7iEFtHf+DP/omBOv6tQzVo=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
-github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk=
-github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU=
+github.com/google/go-tpm v0.9.3 h1:+yx0/anQuGzi+ssRqeD6WpXjW2L/V0dItUayO0i9sRc=
+github.com/google/go-tpm v0.9.3/go.mod h1:h9jEsEECg7gtLis0upRBQU+GhYVH6jMjrFxI8u6bVUY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20240227163752-401108e1b7e7/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
-github.com/google/pprof v0.0.0-20240528025155-186aa0362fba h1:ql1qNgCyOB7iAEk8JTNM+zJrgIbnyCKX/wdlyPufP5g=
-github.com/google/pprof v0.0.0-20240528025155-186aa0362fba/go.mod h1:K1liHPHnj73Fdn/EKuT8nrFqBihUSKXoLYU0BuatOYo=
-github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs=
+github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw=
-github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
github.com/gorilla/feeds v1.2.0 h1:O6pBiXJ5JHhPvqy53NsjKOThq+dNFm8+DFrxBEdzSCc=
github.com/gorilla/feeds v1.2.0/go.mod h1:WMib8uJP3BbY+X8Szd1rA5Pzhdfh+HCCAYT2z7Fza6Y=
-github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
-github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1 h1:LqbZZ9sNMWVjeXS4NN5oVvhMjDyLhmA1LG86oSo+IqY=
github.com/gorilla/pat v0.0.0-20180118222023-199c85a7f6d1/go.mod h1:YeAe0gNeiNT5hoiZRI4yiOky6jVdNvfO2N6Kav/HmxY=
-github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
-github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
-github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
-github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
-github.com/h2non/gock v1.2.0 h1:K6ol8rfrRkUOefooBC8elXoaNGYkpp7y2qcxGG6BzUE=
-github.com/h2non/gock v1.2.0/go.mod h1:tNhoxHYW2W42cYkYb1WqzdbYIieALC99kpYr7rH/BQk=
-github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
-github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
+github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
+github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
@@ -407,72 +336,34 @@ github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISH
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
-github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
-github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI=
github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20230524184225-eabc099b10ab/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
-github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
-github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
-github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
-github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk=
-github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w=
-github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM=
-github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
-github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8=
-github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
-github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
-github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag=
-github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA=
-github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
-github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
-github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw=
-github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4=
-github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA=
-github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw=
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056 h1:iCHtR9CQyktQ5+f3dMVZfwD2KWJUgm7M0gdL9NGr8KA=
github.com/jaytaylor/html2text v0.0.0-20230321000545-74c2419ad056/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
-github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
-github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
-github.com/jhillyerd/enmime v1.2.0 h1:dIu1IPEymQgoT2dzuB//ttA/xcV40NMPpQtmd4wslHk=
-github.com/jhillyerd/enmime v1.2.0/go.mod h1:FRFuUPCLh8PByQv+8xRcLO9QHqaqTqreYhopv5eyk4I=
-github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
-github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
+github.com/jhillyerd/enmime/v2 v2.1.0 h1:c8Qwi5Xq5EdtMN6byQWoZ/8I2RMTo6OJ7Xay+s1oPO0=
+github.com/jhillyerd/enmime/v2 v2.1.0/go.mod h1:EJ74dcRbBcqHSP2TBu08XRoy6y3Yx0cevwb1YkGMEmQ=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
-github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
-github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
-github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
-github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4 h1:cTxwSmnaqLoo+4tLukHoB9iqHOu3LmLhRmgUxZo6Vp4=
-github.com/keybase/go-crypto v0.0.0-20200123153347-de78d2cb44f4/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
-github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
-github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A=
github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
-github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
-github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
+github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
+github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
-github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
-github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
-github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
+github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
+github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
@@ -485,20 +376,18 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
+github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
-github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
-github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
-github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
-github.com/lunny/log v0.0.0-20160921050905-7887c61bf0de/go.mod h1:3q8WtuPQsoRbatJuy3nvq/hRSvuBJrHHr+ybPPiNvHQ=
-github.com/lunny/nodb v0.0.0-20160621015157-fc1ef06ad4af/go.mod h1:Cqz6pqow14VObJ7peltM+2n3PWOz7yTrfUuGbVFkzN0=
+github.com/libdns/libdns v0.2.3 h1:ba30K4ObwMGB/QTmqUxf3H4/GmUrCAIkMWejeGl12v8=
+github.com/libdns/libdns v0.2.3/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 h1:F/3FfGmKdiKFa8kL3YrpZ7pe9H4l4AzA1pbaOUnRvPI=
github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0/go.mod h1:JEfTc3+2DF9Z4PXhLLvXL42zexJyh8rIq3OzUj/0rAk=
-github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
-github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
-github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
+github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
github.com/markbates/going v1.0.3 h1:mY45T5TvW+Xz5A6jY7lf4+NLg9D8+iuStIHyR7M8qsE=
github.com/markbates/going v1.0.3/go.mod h1:fQiT6v6yQar9UD6bd/D4Z5Afbk9J6BBVBtLiyY4gp2o=
github.com/markbates/goth v1.80.0 h1:NnvatczZDzOs1hn9Ug+dVYf2Viwwkp/ZDX5K+GLjan8=
@@ -509,45 +398,39 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
-github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
-github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
-github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
-github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
-github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
-github.com/meilisearch/meilisearch-go v0.26.1 h1:3bmo2uLijX7kvBmiZ9LupVfC95TFcRJDgrRTzbOoE4A=
-github.com/meilisearch/meilisearch-go v0.26.1/go.mod h1:SxuSqDcPBIykjWz1PX+KzsYzArNLSCadQodWs8extS0=
-github.com/mholt/acmez/v2 v2.0.1 h1:3/3N0u1pLjMK4sNEAFSI+bcvzbPhRpY383sy1kLHJ6k=
-github.com/mholt/acmez/v2 v2.0.1/go.mod h1:fX4c9r5jYwMyMsC+7tkYRxHibkOTgta5DIFGoe67e1U=
-github.com/microcosm-cc/bluemonday v1.0.26 h1:xbqSvqzQMeEHCqMi64VAs4d8uy6Mequs3rQ0k/Khz58=
-github.com/microcosm-cc/bluemonday v1.0.26/go.mod h1:JyzOCs9gkyQyjs+6h10UEVSe02CGwkhd72Xdqh78TWs=
-github.com/miekg/dns v1.1.59 h1:C9EXc/UToRwKLhK5wKU/I4QVsBUc8kE6MkHBkeypWZs=
-github.com/miekg/dns v1.1.59/go.mod h1:nZpewl5p6IvctfgrckopVx2OlSEHPRO/U4SYkRklrEk=
+github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
+github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-sqlite3 v1.14.28 h1:ThEiQrnbtumT+QMknw63Befp/ce/nUPgBPMlRFEum7A=
+github.com/mattn/go-sqlite3 v1.14.28/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
+github.com/meilisearch/meilisearch-go v0.31.0 h1:yZRhY1qJqdH8h6GFZALGtkDLyj8f9v5aJpsNMyrUmnY=
+github.com/meilisearch/meilisearch-go v0.31.0/go.mod h1:aNtyuwurDg/ggxQIcKqWH6G9g2ptc8GyY7PLY4zMn/g=
+github.com/mholt/acmez/v3 v3.1.1 h1:Jh+9uKHkPxUJdxM16q5mOr+G2V0aqkuFtNA28ihCxhQ=
+github.com/mholt/acmez/v3 v3.1.1/go.mod h1:L1wOU06KKvq7tswuMDwKdcHeKpFFgkppZy/y0DFxagQ=
+github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk=
+github.com/microcosm-cc/bluemonday v1.0.27/go.mod h1:jFi9vgW+H7c3V0lb6nR74Ib/DIB5OBs92Dimizgw2cA=
+github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
+github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
+github.com/minio/crc64nvme v1.0.1 h1:DHQPrYPdqK7jQG/Ls5CTBZWeex/2FMS3G5XGkycuFrY=
+github.com/minio/crc64nvme v1.0.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
-github.com/minio/minio-go/v7 v7.0.70 h1:1u9NtMgfK1U42kUxcsl5v0yj6TEOPR497OAQxpJnn2g=
-github.com/minio/minio-go/v7 v7.0.70/go.mod h1:4yBA8v80xGA30cfM3fz0DKYMXunWl/AV/6tWEs9ryzo=
-github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
-github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
-github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
+github.com/minio/minio-go/v7 v7.0.88 h1:v8MoIJjwYxOkehp+eiLIuvXk87P2raUtoU5klrAAshs=
+github.com/minio/minio-go/v7 v7.0.88/go.mod h1:33+O8h0tO7pCeCWwBVa07RhVVfB/3vS4kEX7rwYKmIg=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
-github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
-github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450 h1:j2kD3MT1z4PXCiUllUJF9mWUESr9TWKS7iEKsQ/IipM=
github.com/mrjones/oauth v0.0.0-20190623134757-126b35219450/go.mod h1:skjdDftzkFALcuGzYSklqYd8gvat6F1gZJ4YPVbkZpM=
github.com/mschoch/smat v0.2.0 h1:8imxQsjDm8yFEAVBe7azKmKSgzSkZXDuKkSq9374khM=
github.com/mschoch/smat v0.2.0/go.mod h1:kc9mz7DoBKqDyiRL7VZN8KvXQMWeTaVnttLRXOlotKw=
-github.com/msteinert/pam v1.2.0 h1:mYfjlvN2KYs2Pb9G6nb/1f/nPfAttT/Jee5Sq9r3bGE=
-github.com/msteinert/pam v1.2.0/go.mod h1:d2n0DCUK8rGecChV3JzvmsDjOY4R7AYbsNxAT+ftQl0=
-github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy/FJl/rCYT0+EuS8+Z0z4=
-github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
+github.com/msteinert/pam/v2 v2.1.0 h1:er5F9TKV5nGFuTt12ubtqPHEUdeBwReP7vd3wovidGY=
+github.com/msteinert/pam/v2 v2.1.0/go.mod h1:KT28NNIcDFf3PcBmNI2mIGO4zZJ+9RSs/At2PB3IDVc=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
+github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/niklasfasching/go-org v1.7.0 h1:vyMdcMWWTe/XmANk19F4k8XGBYg0GQ/gJGMimOjGMek=
github.com/niklasfasching/go-org v1.7.0/go.mod h1:WuVm4d45oePiE0eX25GqTDQIt/qPW1T9DGkRscqLW5o=
github.com/nwaples/rardecode v1.1.0/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWkRpHbbfGS0=
@@ -556,40 +439,30 @@ github.com/nwaples/rardecode v1.1.3/go.mod h1:5DzqNKiOdpKKBH87u8VlvAnPZMXcGRhxWk
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
-github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
-github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/olivere/elastic/v7 v7.0.32 h1:R7CXvbu8Eq+WlsLgxmKVKPox0oOwAE/2T9Si5BnvK6E=
github.com/olivere/elastic/v7 v7.0.32/go.mod h1:c7PVmLe3Fxq77PIfY/bZmxY/TAamBhCzZ8xDOE09a9k=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
-github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
-github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
-github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
+github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k=
+github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
-github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
-github.com/opencontainers/image-spec v1.1.0/go.mod h1:W4s4sFTMaBeK1BQLXbG4AdM2szdn85PY75RI83NrTrM=
+github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
+github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
-github.com/paulmach/orb v0.11.1 h1:3koVegMC4X/WeiXYz9iswopaTwMem53NzTJuTF20JzU=
-github.com/paulmach/orb v0.11.1/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
-github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
-github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
-github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
-github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
-github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
-github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
+github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4=
+github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -598,18 +471,16 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/otp v1.4.0 h1:wZvl1TIVxKRThZIBiwOOHOGP/1+nZyWBil9Y2XNEDzg=
github.com/pquerna/otp v1.4.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
-github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
-github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
-github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
-github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
-github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqScV0Y=
-github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ=
-github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
-github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
-github.com/quasoft/websspi v1.1.2 h1:/mA4w0LxWlE3novvsoEL6BBA1WnjJATbjkh1kFrTidw=
-github.com/quasoft/websspi v1.1.2/go.mod h1:HmVdl939dQ0WIXZhyik+ARdI03M6bQzaSEKcgpFmewk=
-github.com/redis/go-redis/v9 v9.5.2 h1:L0L3fcSNReTRGyZ6AqAEN0K56wYeYAwapBIhkvh0f3E=
-github.com/redis/go-redis/v9 v9.5.2/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
+github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
+github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
+github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
+github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
+github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
+github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
+github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
+github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
+github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0wM=
+github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rhysd/actionlint v1.6.27 h1:xxwe8YmveBcC8lydW6GoHMGmB6H/MTqUU60F2p10wjw=
@@ -621,60 +492,26 @@ github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
-github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
-github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
-github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
-github.com/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
-github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
+github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
+github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
+github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
+github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
-github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
-github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
-github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
-github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4=
-github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 h1:PKK9DyHxif4LZo+uQSgXNqs0jj5+xZwwfKHgph2lxBw=
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1/go.mod h1:JXeL+ps8p7/KNMjDQk3TCwPpBy0wYklyWTfbkIzdIFU=
-github.com/sassoftware/go-rpmutils v0.2.1-0.20240124161140-277b154961dd h1:KpbqRPDwcAQTyaP+L+YudTRb3CnJlQ64Hfn1SF/zHBA=
-github.com/sassoftware/go-rpmutils v0.2.1-0.20240124161140-277b154961dd/go.mod h1:TJJQYtLe/BeEmEjelI3b7xNZjzAukEkeWKmoakvaOoI=
-github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
-github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
+github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg=
+github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI=
github.com/serenize/snaker v0.0.0-20171204205717-a683aaf2d516/go.mod h1:Yow6lPLSAXx2ifx470yD/nUe22Dv5vBvxK/UK9UUTVs=
-github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
-github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
-github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
-github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k=
-github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8=
+github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
-github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726/go.mod h1:3yhqj7WBBfRhbBlzyOC3gUxftwsU0u8gqevxwIHQpMw=
-github.com/siddontang/go-snappy v0.0.0-20140704025258-d8f7bb82a96d/go.mod h1:vq0tzqLRu6TS7Id0wMo2N5QzJoKedVeovOpHjnykSzY=
-github.com/siddontang/ledisdb v0.0.0-20190202134119-8ceb77e66a92/go.mod h1:mF1DpOSOUiJRMR+FDqaqu3EBqrybQtrDDszLUZ6oxPg=
-github.com/siddontang/rdb v0.0.0-20150307021120-fc89ed2e418d/go.mod h1:AMEsy7v5z92TR1JKMkLLoaOQk++LVnOKL3ScbJ8GNGA=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
-github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ=
-github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/assertions v0.0.0-20190116191733-b6c0e53d7304/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/assertions v1.1.1 h1:T/YLemO5Yp7KPzS+lVtu+WsHn8yoSwTfItdAd1r3cck=
-github.com/smartystreets/assertions v1.1.1/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
-github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s=
-github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8=
-github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
-github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
-github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
-github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
-github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
-github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
-github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
-github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
+github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY=
+github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf h1:pvbZ0lM0XWPBqUKqFU8cmavspvIl9nulOYwdy6IFRRo=
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -684,162 +521,124 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
-github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
-github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
-github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
-github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
-github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
+github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
+github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ=
-github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
-github.com/toqueteos/webbrowser v1.2.0 h1:tVP/gpK69Fx+qMJKsLE7TD8LuGWPnEV71wBN9rrstGQ=
-github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM=
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
github.com/ulikunitz/xz v0.5.9/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
-github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8=
-github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
-github.com/unknwon/com v0.0.0-20190804042917-757f69c95f3e/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
-github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
-github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
-github.com/urfave/cli/v2 v2.27.2 h1:6e0H+AkS+zDckwPCUrZkKX38mRaau4nL2uipkJpbkcI=
-github.com/urfave/cli/v2 v2.27.2/go.mod h1:g0+79LmHHATl7DAcHO99smiR/T7uGLw84w8Y42x+4eM=
-github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
-github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
-github.com/valyala/fasthttp v1.51.0 h1:8b30A5JlZ6C7AS81RsWjYMQmrZG6feChmgAolCl1SqA=
-github.com/valyala/fasthttp v1.51.0/go.mod h1:oI2XroL+lI7vdXyYoQk03bXBThfFl2cVdIA3Xl7cH8g=
+github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc=
+github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
+github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
+github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/valyala/fastjson v1.6.4 h1:uAUNq9Z6ymTgGhcm0UynUAB6tlbakBrz6CQFax3BXVQ=
github.com/valyala/fastjson v1.6.4/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
-github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
-github.com/xanzy/go-gitlab v0.96.0 h1:LGkZ+wSNMRtHIBaYE4Hq3dZVjprwHv3Y1+rhKU3WETs=
-github.com/xanzy/go-gitlab v0.96.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
-github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
-github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g=
-github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
-github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
-github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
-github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 h1:+qGGcbkzsfDQNPPe9UDgpxAWQrhbbBXOYJFQDq/dtJw=
-github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913/go.mod h1:4aEEwZQutDLsQv2Deui4iYQ6DWTxR14g6m8Wv88+Xqk=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
+github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
+github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
+github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js=
github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBzPCRjkCNs=
-github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
-github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yuin/goldmark v1.4.15/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/yuin/goldmark v1.7.4 h1:BDXOHExt+A7gwPCJgPIIq7ENvceR7we7rOS9TNoLZeg=
-github.com/yuin/goldmark v1.7.4/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
+github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
+github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc h1:+IAOyRda+RLrxa1WC7umKOZRsGq4QrFFMYApOeHzQwQ=
github.com/yuin/goldmark-highlighting/v2 v2.0.0-20230729083705-37449abec8cc/go.mod h1:ovIvrum6DQJA4QsJSovrkC4saKHQVs7TvcaeO8AIl5I=
-github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
-github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
-github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
-github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
-github.com/zeebo/blake3 v0.2.3 h1:TFoLXsjeXqRNFxSbk35Dk4YtszE/MQQGK10BH4ptoTg=
-github.com/zeebo/blake3 v0.2.3/go.mod h1:mjJjZpnsyIVtVgTOSpJ9vmRE4wgDeyt2HU3qXvvKCaQ=
+github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
+github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
+github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI=
+github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE=
github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo=
github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
-go.etcd.io/bbolt v1.3.9 h1:8x7aARPEXiXbHmtUwAIv7eV2fQFHrLLavdiJ3uzJXoI=
-go.etcd.io/bbolt v1.3.9/go.mod h1:zaO32+Ti0PK1ivdPtgMESzuzL2VPoIG1PCQNvOdo/dE=
-go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
-go.mongodb.org/mongo-driver v1.13.1 h1:YIc7HTYsKndGK4RFzJ3covLz1byri52x0IoMB0Pt/vk=
-go.mongodb.org/mongo-driver v1.13.1/go.mod h1:wcDf1JBCXy2mOW0bWHwO/IOYqdca1MPCwDtFu/Z9+eo=
-go.opentelemetry.io/otel v1.26.0 h1:LQwgL5s/1W7YiiRwxf03QGnWLb2HW4pLiAhaA5cZXBs=
-go.opentelemetry.io/otel v1.26.0/go.mod h1:UmLkJHUAidDval2EICqBMbnAd0/m2vmpf/dAM+fvFs4=
-go.opentelemetry.io/otel/trace v1.26.0 h1:1ieeAUb4y0TE26jUFrCIXKpTuVK7uJGN9/Z/2LP5sQA=
-go.opentelemetry.io/otel/trace v1.26.0/go.mod h1:4iDxvGDQuUkHve82hJJ8UqrwswHYsZuWCBllGV2U2y0=
+gitlab.com/gitlab-org/api/client-go v0.126.0 h1:VV5TdkF6pMbEdFGvbR2CwEgJwg6qdg1u3bj5eD2tiWk=
+gitlab.com/gitlab-org/api/client-go v0.126.0/go.mod h1:bYC6fPORKSmtuPRyD9Z2rtbAjE7UeNatu2VWHRf4/LE=
+go.etcd.io/bbolt v1.4.0 h1:TU77id3TnN/zKr7CO/uk+fBCwF2jGcMuw2B/FMAzYIk=
+go.etcd.io/bbolt v1.4.0/go.mod h1:AsD+OCi/qPN1giOX1aiLAha3o1U8rAz65bvN4j0sRuk=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
-go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
-go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
-go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
+go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
+go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
+go.uber.org/zap/exp v0.3.0 h1:6JYzdifzYkGmTdRR59oYH+Ng7k49H9qVpWwNSsGJj3U=
+go.uber.org/zap/exp v0.3.0/go.mod h1:5I384qq7XGxYyByIhHm6jg5CHkGY0nsTfbDLgDDlgJQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
-golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
-golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
-golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
-golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
-golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
-golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
-golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
-golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
-golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
-golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
+golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
+golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
+golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
+golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8=
+golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY=
+golang.org/x/image v0.25.0 h1:Y6uW6rH1y5y/LK1J8BPWZtr6yZ7hrsy6hFrXjgsc2fQ=
+golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
+golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
-golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
-golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
-golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs=
-golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
+golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
+golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
+golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
+golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
+golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190730183949-1393eb018365/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -847,88 +646,68 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
-golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
+golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
+golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
-golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0=
-golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
-golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
+golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
+golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
+golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
+golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
-golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
-golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
-golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
-golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
+golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
+golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
+golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
+golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
-golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
-golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
-golang.org/x/tools v0.0.0-20200325010219-a49f79bcc224/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
-golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
-golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
+golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
+golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac h1:nUQEQmH/csSvFECKYRv6HWEyypysidKl2I6Qpsglq/0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20240116215550-a9fa1716bcac/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
-google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
-google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
-google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
-google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
-google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
-google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
+google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM=
+google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -940,7 +719,6 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AWRXxgwEyPp2z+p0+hgMuE=
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
-gopkg.in/ini.v1 v1.44.2/go.mod h1:M3Cogqpuv0QCi3ExAY5V4uOt4qb/R3xZubo9m8lK5wg=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
@@ -952,9 +730,9 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
@@ -979,9 +757,7 @@ modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
mvdan.cc/xurls/v2 v2.5.0 h1:lyBNOm8Wo71UknhUs4QTFUNNMyxy2JEIaKKo0RWOh+8=
mvdan.cc/xurls/v2 v2.5.0/go.mod h1:yQgaGQ1rFtJUzkmKiHYSSfuQxqfYmd//X6PxvholpeE=
-strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 h1:mUcz5b3FJbP5Cvdq7Khzn6J9OCUQJaBwgBkCR+MOwSs=
-strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251/go.mod h1:FJGmPh3vz9jSos1L/F91iAgnC/aejc0wIIrF2ZwJxdY=
xorm.io/builder v0.3.13 h1:a3jmiVVL19psGeXx8GIurTp7p0IIgqeDmwhcR6BAOAo=
xorm.io/builder v0.3.13/go.mod h1:aUW0S9eb9VCaPohFCH3j7czOx1PMW3i1HrSzbLYGBSE=
-xorm.io/xorm v1.3.7 h1:mLceAGu0b87r9pD4qXyxGHxifOXIIrAdVcA6k95/osw=
-xorm.io/xorm v1.3.7/go.mod h1:LsCCffeeYp63ssk0pKumP6l96WZcHix7ChpurcLNuMw=
+xorm.io/xorm v1.3.9 h1:TUovzS0ko+IQ1XnNLfs5dqK1cJl1H5uHpWbWqAQ04nU=
+xorm.io/xorm v1.3.9/go.mod h1:LsCCffeeYp63ssk0pKumP6l96WZcHix7ChpurcLNuMw=
diff --git a/main.go b/main.go
index b8cc5668e1..3f0283db7f 100644
--- a/main.go
+++ b/main.go
@@ -10,16 +10,16 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/cmd"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/cmd"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
// register supported doc types
- _ "code.gitea.io/gitea/modules/markup/asciicast"
- _ "code.gitea.io/gitea/modules/markup/console"
- _ "code.gitea.io/gitea/modules/markup/csv"
- _ "code.gitea.io/gitea/modules/markup/markdown"
- _ "code.gitea.io/gitea/modules/markup/orgmode"
+ _ "forgejo.org/modules/markup/asciicast"
+ _ "forgejo.org/modules/markup/console"
+ _ "forgejo.org/modules/markup/csv"
+ _ "forgejo.org/modules/markup/markdown"
+ _ "forgejo.org/modules/markup/orgmode"
"github.com/urfave/cli/v2"
)
diff --git a/models/actions/artifact.go b/models/actions/artifact.go
index 3d0a288e62..10cd3868a1 100644
--- a/models/actions/artifact.go
+++ b/models/actions/artifact.go
@@ -11,9 +11,9 @@ import (
"errors"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -69,7 +69,7 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa
OwnerID: t.OwnerID,
CommitSHA: t.CommitSHA,
Status: int64(ArtifactStatusUploadPending),
- ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + 3600*24*expiredDays),
+ ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays),
}
if _, err := db.GetEngine(ctx).Insert(artifact); err != nil {
return nil, err
@@ -78,6 +78,13 @@ func CreateArtifact(ctx context.Context, t *ActionTask, artifactName, artifactPa
} else if err != nil {
return nil, err
}
+
+ if _, err := db.GetEngine(ctx).ID(artifact.ID).Cols("expired_unix").Update(&ActionArtifact{
+ ExpiredUnix: timeutil.TimeStamp(time.Now().Unix() + timeutil.Day*expiredDays),
+ }); err != nil {
+ return nil, err
+ }
+
return artifact, nil
}
diff --git a/models/actions/forgejo.go b/models/actions/forgejo.go
index 243262facd..ce3f8b0c8b 100644
--- a/models/actions/forgejo.go
+++ b/models/actions/forgejo.go
@@ -4,17 +4,17 @@ package actions
import (
"context"
- "encoding/hex"
+ "crypto/subtle"
"fmt"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/util"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/util"
gouuid "github.com/google/uuid"
)
-func RegisterRunner(ctx context.Context, ownerID, repoID int64, token string, labels []string, name, version string) (*ActionRunner, error) {
+func RegisterRunner(ctx context.Context, ownerID, repoID int64, token string, labels *[]string, name, version string) (*ActionRunner, error) {
uuid, err := gouuid.FromBytes([]byte(token[:16]))
if err != nil {
return nil, fmt.Errorf("gouuid.FromBytes %v", err)
@@ -26,22 +26,28 @@ func RegisterRunner(ctx context.Context, ownerID, repoID int64, token string, la
has, err := db.GetEngine(ctx).Where("uuid=?", uuidString).Get(&runner)
if err != nil {
return nil, fmt.Errorf("GetRunner %v", err)
- } else if !has {
+ }
+
+ var mustUpdateSecret bool
+ if has {
+ //
+ // The runner exists, check if the rest of the token has changed.
+ //
+ mustUpdateSecret = subtle.ConstantTimeCompare(
+ []byte(runner.TokenHash),
+ []byte(auth_model.HashToken(token, runner.TokenSalt)),
+ ) != 1
+ } else {
//
// The runner does not exist yet, create it
//
- saltBytes, err := util.CryptoRandomBytes(16)
- if err != nil {
- return nil, fmt.Errorf("CryptoRandomBytes %v", err)
- }
- salt := hex.EncodeToString(saltBytes)
-
- hash := auth_model.HashToken(token, salt)
-
runner = ActionRunner{
- UUID: uuidString,
- TokenHash: hash,
- TokenSalt: salt,
+ UUID: uuidString,
+ AgentLabels: []string{},
+ }
+
+ if err := runner.UpdateSecret(token); err != nil {
+ return &runner, fmt.Errorf("can't set new runner's secret: %w", err)
}
if err := CreateRunner(ctx, &runner); err != nil {
@@ -54,13 +60,23 @@ func RegisterRunner(ctx context.Context, ownerID, repoID int64, token string, la
//
name, _ = util.SplitStringAtByteN(name, 255)
+ cols := []string{"name", "owner_id", "repo_id", "version"}
runner.Name = name
runner.OwnerID = ownerID
runner.RepoID = repoID
runner.Version = version
- runner.AgentLabels = labels
+ if labels != nil {
+ runner.AgentLabels = *labels
+ cols = append(cols, "agent_labels")
+ }
+ if mustUpdateSecret {
+ if err := runner.UpdateSecret(token); err != nil {
+ return &runner, fmt.Errorf("can't change runner's secret: %w", err)
+ }
+ cols = append(cols, "token_hash", "token_salt")
+ }
- if err := UpdateRunner(ctx, &runner, "name", "owner_id", "repo_id", "version", "agent_labels"); err != nil {
+ if err := UpdateRunner(ctx, &runner, cols...); err != nil {
return &runner, fmt.Errorf("can't update the runner %+v %w", runner, err)
}
diff --git a/models/actions/forgejo_test.go b/models/actions/forgejo_test.go
index a8583c3d00..fc4ccfa628 100644
--- a/models/actions/forgejo_test.go
+++ b/models/actions/forgejo_test.go
@@ -6,24 +6,173 @@ import (
"crypto/subtle"
"testing"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
-func TestActions_RegisterRunner(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+func TestActions_RegisterRunner_Token(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
ownerID := int64(0)
repoID := int64(0)
token := "0123456789012345678901234567890123456789"
labels := []string{}
name := "runner"
version := "v1.2.3"
- runner, err := RegisterRunner(db.DefaultContext, ownerID, repoID, token, labels, name, version)
- assert.NoError(t, err)
+ runner, err := RegisterRunner(db.DefaultContext, ownerID, repoID, token, &labels, name, version)
+ require.NoError(t, err)
assert.EqualValues(t, name, runner.Name)
assert.EqualValues(t, 1, subtle.ConstantTimeCompare([]byte(runner.TokenHash), []byte(auth_model.HashToken(token, runner.TokenSalt))), "the token cannot be verified with the same method as routers/api/actions/runner/interceptor.go as of 8228751c55d6a4263f0fec2932ca16181c09c97d")
}
+
+// TestActions_RegisterRunner_TokenUpdate tests that a token's secret is updated
+// when a runner already exists and RegisterRunner is called with a token
+// parameter whose first 16 bytes match that record but where the last 24 bytes
+// do not match.
+func TestActions_RegisterRunner_TokenUpdate(t *testing.T) {
+ const recordID = 12345678
+ oldToken := "7e577e577e577e57feedfacefeedfacefeedface"
+ newToken := "7e577e577e577e57deadbeefdeadbeefdeadbeef"
+ require.NoError(t, unittest.PrepareTestDatabase())
+ before := unittest.AssertExistsAndLoadBean(t, &ActionRunner{ID: recordID})
+ require.Equal(t,
+ before.TokenHash, auth_model.HashToken(oldToken, before.TokenSalt),
+ "the initial token should match the runner's secret",
+ )
+
+ RegisterRunner(db.DefaultContext, before.OwnerID, before.RepoID, newToken, nil, before.Name, before.Version)
+
+ after := unittest.AssertExistsAndLoadBean(t, &ActionRunner{ID: recordID})
+
+ assert.Equal(t, before.UUID, after.UUID)
+ assert.NotEqual(t,
+ after.TokenHash, auth_model.HashToken(oldToken, after.TokenSalt),
+ "the old token can still be verified",
+ )
+ assert.Equal(t,
+ after.TokenHash, auth_model.HashToken(newToken, after.TokenSalt),
+ "the new token cannot be verified",
+ )
+}
+
+func TestActions_RegisterRunner_CreateWithLabels(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ ownerID := int64(0)
+ repoID := int64(0)
+ token := "0123456789012345678901234567890123456789"
+ name := "runner"
+ version := "v1.2.3"
+ labels := []string{"woop", "doop"}
+ labelsCopy := labels // labels may be affected by the tested function so we copy them
+
+ runner, err := RegisterRunner(db.DefaultContext, ownerID, repoID, token, &labels, name, version)
+ require.NoError(t, err)
+
+ // Check that the returned record has been updated, except for the labels
+ assert.EqualValues(t, ownerID, runner.OwnerID)
+ assert.EqualValues(t, repoID, runner.RepoID)
+ assert.EqualValues(t, name, runner.Name)
+ assert.EqualValues(t, version, runner.Version)
+ assert.EqualValues(t, labelsCopy, runner.AgentLabels)
+
+ // Check that whatever is in the DB has been updated, except for the labels
+ after := unittest.AssertExistsAndLoadBean(t, &ActionRunner{ID: runner.ID})
+ assert.EqualValues(t, ownerID, after.OwnerID)
+ assert.EqualValues(t, repoID, after.RepoID)
+ assert.EqualValues(t, name, after.Name)
+ assert.EqualValues(t, version, after.Version)
+ assert.EqualValues(t, labelsCopy, after.AgentLabels)
+}
+
+func TestActions_RegisterRunner_CreateWithoutLabels(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ ownerID := int64(0)
+ repoID := int64(0)
+ token := "0123456789012345678901234567890123456789"
+ name := "runner"
+ version := "v1.2.3"
+
+ runner, err := RegisterRunner(db.DefaultContext, ownerID, repoID, token, nil, name, version)
+ require.NoError(t, err)
+
+ // Check that the returned record has been updated, except for the labels
+ assert.EqualValues(t, ownerID, runner.OwnerID)
+ assert.EqualValues(t, repoID, runner.RepoID)
+ assert.EqualValues(t, name, runner.Name)
+ assert.EqualValues(t, version, runner.Version)
+ assert.EqualValues(t, []string{}, runner.AgentLabels)
+
+ // Check that whatever is in the DB has been updated, except for the labels
+ after := unittest.AssertExistsAndLoadBean(t, &ActionRunner{ID: runner.ID})
+ assert.EqualValues(t, ownerID, after.OwnerID)
+ assert.EqualValues(t, repoID, after.RepoID)
+ assert.EqualValues(t, name, after.Name)
+ assert.EqualValues(t, version, after.Version)
+ assert.EqualValues(t, []string{}, after.AgentLabels)
+}
+
+func TestActions_RegisterRunner_UpdateWithLabels(t *testing.T) {
+ const recordID = 12345678
+ token := "7e577e577e577e57feedfacefeedfacefeedface"
+ require.NoError(t, unittest.PrepareTestDatabase())
+ unittest.AssertExistsAndLoadBean(t, &ActionRunner{ID: recordID})
+
+ newOwnerID := int64(1)
+ newRepoID := int64(1)
+ newName := "rennur"
+ newVersion := "v4.5.6"
+ newLabels := []string{"warp", "darp"}
+ labelsCopy := newLabels // labels may be affected by the tested function so we copy them
+
+ runner, err := RegisterRunner(db.DefaultContext, newOwnerID, newRepoID, token, &newLabels, newName, newVersion)
+ require.NoError(t, err)
+
+ // Check that the returned record has been updated
+ assert.EqualValues(t, newOwnerID, runner.OwnerID)
+ assert.EqualValues(t, newRepoID, runner.RepoID)
+ assert.EqualValues(t, newName, runner.Name)
+ assert.EqualValues(t, newVersion, runner.Version)
+ assert.EqualValues(t, labelsCopy, runner.AgentLabels)
+
+ // Check that whatever is in the DB has been updated
+ after := unittest.AssertExistsAndLoadBean(t, &ActionRunner{ID: recordID})
+ assert.EqualValues(t, newOwnerID, after.OwnerID)
+ assert.EqualValues(t, newRepoID, after.RepoID)
+ assert.EqualValues(t, newName, after.Name)
+ assert.EqualValues(t, newVersion, after.Version)
+ assert.EqualValues(t, labelsCopy, after.AgentLabels)
+}
+
+func TestActions_RegisterRunner_UpdateWithoutLabels(t *testing.T) {
+ const recordID = 12345678
+ token := "7e577e577e577e57feedfacefeedfacefeedface"
+ require.NoError(t, unittest.PrepareTestDatabase())
+ before := unittest.AssertExistsAndLoadBean(t, &ActionRunner{ID: recordID})
+
+ newOwnerID := int64(1)
+ newRepoID := int64(1)
+ newName := "rennur"
+ newVersion := "v4.5.6"
+
+ runner, err := RegisterRunner(db.DefaultContext, newOwnerID, newRepoID, token, nil, newName, newVersion)
+ require.NoError(t, err)
+
+ // Check that the returned record has been updated, except for the labels
+ assert.EqualValues(t, newOwnerID, runner.OwnerID)
+ assert.EqualValues(t, newRepoID, runner.RepoID)
+ assert.EqualValues(t, newName, runner.Name)
+ assert.EqualValues(t, newVersion, runner.Version)
+ assert.EqualValues(t, before.AgentLabels, runner.AgentLabels)
+
+ // Check that whatever is in the DB has been updated, except for the labels
+ after := unittest.AssertExistsAndLoadBean(t, &ActionRunner{ID: recordID})
+ assert.EqualValues(t, newOwnerID, after.OwnerID)
+ assert.EqualValues(t, newRepoID, after.RepoID)
+ assert.EqualValues(t, newName, after.Name)
+ assert.EqualValues(t, newVersion, after.Version)
+ assert.EqualValues(t, before.AgentLabels, after.AgentLabels)
+}
diff --git a/models/actions/main_test.go b/models/actions/main_test.go
index 3cfb395e62..27916f29ac 100644
--- a/models/actions/main_test.go
+++ b/models/actions/main_test.go
@@ -6,7 +6,7 @@ package actions
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/models/actions/run.go b/models/actions/run.go
index 8b40cb7ba8..671177a892 100644
--- a/models/actions/run.go
+++ b/models/actions/run.go
@@ -10,15 +10,15 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/json"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ webhook_module "forgejo.org/modules/webhook"
"github.com/nektos/act/pkg/jobparser"
"xorm.io/builder"
@@ -37,6 +37,7 @@ type ActionRun struct {
TriggerUser *user_model.User `xorm:"-"`
ScheduleID int64
Ref string `xorm:"index"` // the commit/tag/โฆ that caused the run
+ IsRefDeleted bool `xorm:"-"`
CommitSHA string
IsForkPullRequest bool // If this is triggered by a PR from a forked repository or an untrusted user, we need to check if it is approved and limit permissions when running the workflow.
NeedApproval bool // may need approval if it's a fork pull request
@@ -146,7 +147,11 @@ func (run *ActionRun) GetPushEventPayload() (*api.PushPayload, error) {
}
func (run *ActionRun) GetPullRequestEventPayload() (*api.PullRequestPayload, error) {
- if run.Event == webhook_module.HookEventPullRequest || run.Event == webhook_module.HookEventPullRequestSync {
+ if run.Event == webhook_module.HookEventPullRequest ||
+ run.Event == webhook_module.HookEventPullRequestSync ||
+ run.Event == webhook_module.HookEventPullRequestAssign ||
+ run.Event == webhook_module.HookEventPullRequestMilestone ||
+ run.Event == webhook_module.HookEventPullRequestLabel {
var payload api.PullRequestPayload
if err := json.Unmarshal([]byte(run.EventPayload), &payload); err != nil {
return nil, err
@@ -250,6 +255,7 @@ func CancelPreviousJobs(ctx context.Context, repoID int64, ref, workflowID strin
}
// InsertRun inserts a run
+// The title will be cut off at 255 characters if it's longer than 255 characters.
func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWorkflow) error {
ctx, commiter, err := db.TxContext(ctx)
if err != nil {
@@ -262,6 +268,7 @@ func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWork
return err
}
run.Index = index
+ run.Title, _ = util.SplitStringAtByteN(run.Title, 255)
if err := db.Insert(ctx, run); err != nil {
return err
@@ -387,6 +394,7 @@ func UpdateRun(ctx context.Context, run *ActionRun, cols ...string) error {
if len(cols) > 0 {
sess.Cols(cols...)
}
+ run.Title, _ = util.SplitStringAtByteN(run.Title, 255)
affected, err := sess.Update(run)
if err != nil {
return err
diff --git a/models/actions/run_job.go b/models/actions/run_job.go
index 4b8664077d..fffbb6670b 100644
--- a/models/actions/run_job.go
+++ b/models/actions/run_job.go
@@ -9,9 +9,10 @@ import (
"slices"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -71,6 +72,15 @@ func (job *ActionRunJob) LoadAttributes(ctx context.Context) error {
return job.Run.LoadAttributes(ctx)
}
+func (job *ActionRunJob) ItRunsOn(labels []string) bool {
+ if len(labels) == 0 || len(job.RunsOn) == 0 {
+ return false
+ }
+ labelSet := make(container.Set[string])
+ labelSet.AddMultiple(labels...)
+ return labelSet.IsSubset(job.RunsOn)
+}
+
func GetRunJobByID(ctx context.Context, id int64) (*ActionRunJob, error) {
var job ActionRunJob
has, err := db.GetEngine(ctx).Where("id=?", id).Get(&job)
@@ -137,7 +147,7 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
if err != nil {
return 0, err
}
- run.Status = aggregateJobStatus(jobs)
+ run.Status = AggregateJobStatus(jobs)
if run.Started.IsZero() && run.Status.IsRunning() {
run.Started = timeutil.TimeStampNow()
}
@@ -152,29 +162,35 @@ func UpdateRunJob(ctx context.Context, job *ActionRunJob, cond builder.Cond, col
return affected, nil
}
-func aggregateJobStatus(jobs []*ActionRunJob) Status {
- allDone := true
- allWaiting := true
- hasFailure := false
+func AggregateJobStatus(jobs []*ActionRunJob) Status {
+ allSuccessOrSkipped := len(jobs) != 0
+ allSkipped := len(jobs) != 0
+ var hasFailure, hasCancelled, hasWaiting, hasRunning, hasBlocked bool
for _, job := range jobs {
- if !job.Status.IsDone() {
- allDone = false
- }
- if job.Status != StatusWaiting && !job.Status.IsDone() {
- allWaiting = false
- }
- if job.Status == StatusFailure || job.Status == StatusCancelled {
- hasFailure = true
- }
+ allSuccessOrSkipped = allSuccessOrSkipped && (job.Status == StatusSuccess || job.Status == StatusSkipped)
+ allSkipped = allSkipped && job.Status == StatusSkipped
+ hasFailure = hasFailure || job.Status == StatusFailure
+ hasCancelled = hasCancelled || job.Status == StatusCancelled
+ hasWaiting = hasWaiting || job.Status == StatusWaiting
+ hasRunning = hasRunning || job.Status == StatusRunning
+ hasBlocked = hasBlocked || job.Status == StatusBlocked
}
- if allDone {
- if hasFailure {
- return StatusFailure
- }
+ switch {
+ case allSkipped:
+ return StatusSkipped
+ case allSuccessOrSkipped:
return StatusSuccess
- }
- if allWaiting {
+ case hasCancelled:
+ return StatusCancelled
+ case hasFailure:
+ return StatusFailure
+ case hasRunning:
+ return StatusRunning
+ case hasWaiting:
return StatusWaiting
+ case hasBlocked:
+ return StatusBlocked
+ default:
+ return StatusUnknown // it shouldn't happen
}
- return StatusRunning
}
diff --git a/models/actions/run_job_list.go b/models/actions/run_job_list.go
index 6c5d3b3252..cbcb4beb8e 100644
--- a/models/actions/run_job_list.go
+++ b/models/actions/run_job_list.go
@@ -6,9 +6,9 @@ package actions
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
)
diff --git a/models/actions/run_job_status_test.go b/models/actions/run_job_status_test.go
new file mode 100644
index 0000000000..04fd9ceba7
--- /dev/null
+++ b/models/actions/run_job_status_test.go
@@ -0,0 +1,85 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package actions
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAggregateJobStatus(t *testing.T) {
+ testStatuses := func(expected Status, statuses []Status) {
+ t.Helper()
+ var jobs []*ActionRunJob
+ for _, v := range statuses {
+ jobs = append(jobs, &ActionRunJob{Status: v})
+ }
+ actual := AggregateJobStatus(jobs)
+ if !assert.Equal(t, expected, actual) {
+ var statusStrings []string
+ for _, s := range statuses {
+ statusStrings = append(statusStrings, s.String())
+ }
+ t.Errorf("AggregateJobStatus(%v) = %v, want %v", statusStrings, statusNames[actual], statusNames[expected])
+ }
+ }
+
+ cases := []struct {
+ statuses []Status
+ expected Status
+ }{
+ // unknown cases, maybe it shouldn't happen in real world
+ {[]Status{}, StatusUnknown},
+ {[]Status{StatusUnknown, StatusSuccess}, StatusUnknown},
+ {[]Status{StatusUnknown, StatusSkipped}, StatusUnknown},
+ {[]Status{StatusUnknown, StatusFailure}, StatusFailure},
+ {[]Status{StatusUnknown, StatusCancelled}, StatusCancelled},
+ {[]Status{StatusUnknown, StatusWaiting}, StatusWaiting},
+ {[]Status{StatusUnknown, StatusRunning}, StatusRunning},
+ {[]Status{StatusUnknown, StatusBlocked}, StatusBlocked},
+
+ // success with other status
+ {[]Status{StatusSuccess}, StatusSuccess},
+ {[]Status{StatusSuccess, StatusSkipped}, StatusSuccess}, // skipped doesn't affect success
+ {[]Status{StatusSuccess, StatusFailure}, StatusFailure},
+ {[]Status{StatusSuccess, StatusCancelled}, StatusCancelled},
+ {[]Status{StatusSuccess, StatusWaiting}, StatusWaiting},
+ {[]Status{StatusSuccess, StatusRunning}, StatusRunning},
+ {[]Status{StatusSuccess, StatusBlocked}, StatusBlocked},
+
+ // any cancelled, then cancelled
+ {[]Status{StatusCancelled}, StatusCancelled},
+ {[]Status{StatusCancelled, StatusSuccess}, StatusCancelled},
+ {[]Status{StatusCancelled, StatusSkipped}, StatusCancelled},
+ {[]Status{StatusCancelled, StatusFailure}, StatusCancelled},
+ {[]Status{StatusCancelled, StatusWaiting}, StatusCancelled},
+ {[]Status{StatusCancelled, StatusRunning}, StatusCancelled},
+ {[]Status{StatusCancelled, StatusBlocked}, StatusCancelled},
+
+ // failure with other status, fail fast
+ // Should "running" win? Maybe no: old code does make "running" win, but GitHub does fail fast.
+ {[]Status{StatusFailure}, StatusFailure},
+ {[]Status{StatusFailure, StatusSuccess}, StatusFailure},
+ {[]Status{StatusFailure, StatusSkipped}, StatusFailure},
+ {[]Status{StatusFailure, StatusCancelled}, StatusCancelled},
+ {[]Status{StatusFailure, StatusWaiting}, StatusFailure},
+ {[]Status{StatusFailure, StatusRunning}, StatusFailure},
+ {[]Status{StatusFailure, StatusBlocked}, StatusFailure},
+
+ // skipped with other status
+ // TODO: need to clarify whether a PR with "skipped" job status is considered as "mergeable" or not.
+ {[]Status{StatusSkipped}, StatusSkipped},
+ {[]Status{StatusSkipped, StatusSuccess}, StatusSuccess},
+ {[]Status{StatusSkipped, StatusFailure}, StatusFailure},
+ {[]Status{StatusSkipped, StatusCancelled}, StatusCancelled},
+ {[]Status{StatusSkipped, StatusWaiting}, StatusWaiting},
+ {[]Status{StatusSkipped, StatusRunning}, StatusRunning},
+ {[]Status{StatusSkipped, StatusBlocked}, StatusBlocked},
+ }
+
+ for _, c := range cases {
+ testStatuses(c.expected, c.statuses)
+ }
+}
diff --git a/models/actions/run_job_test.go b/models/actions/run_job_test.go
new file mode 100644
index 0000000000..50a4ba10d8
--- /dev/null
+++ b/models/actions/run_job_test.go
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: MIT
+
+package actions
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestActionRunJob_ItRunsOn(t *testing.T) {
+ actionJob := ActionRunJob{RunsOn: []string{"ubuntu"}}
+ agentLabels := []string{"ubuntu", "node-20"}
+
+ assert.True(t, actionJob.ItRunsOn(agentLabels))
+ assert.False(t, actionJob.ItRunsOn([]string{}))
+
+ actionJob.RunsOn = append(actionJob.RunsOn, "node-20")
+
+ assert.True(t, actionJob.ItRunsOn(agentLabels))
+
+ agentLabels = []string{"ubuntu"}
+
+ assert.False(t, actionJob.ItRunsOn(agentLabels))
+
+ actionJob.RunsOn = []string{}
+
+ assert.False(t, actionJob.ItRunsOn(agentLabels))
+}
diff --git a/models/actions/run_list.go b/models/actions/run_list.go
index 4046c7d369..92be510569 100644
--- a/models/actions/run_list.go
+++ b/models/actions/run_list.go
@@ -6,11 +6,12 @@ package actions
import (
"context"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/translation"
+ webhook_module "forgejo.org/modules/webhook"
"xorm.io/builder"
)
@@ -112,14 +113,14 @@ type StatusInfo struct {
}
// GetStatusInfoList returns a slice of StatusInfo
-func GetStatusInfoList(ctx context.Context) []StatusInfo {
+func GetStatusInfoList(ctx context.Context, lang translation.Locale) []StatusInfo {
// same as those in aggregateJobStatus
allStatus := []Status{StatusSuccess, StatusFailure, StatusWaiting, StatusRunning}
statusInfoList := make([]StatusInfo, 0, 4)
for _, s := range allStatus {
statusInfoList = append(statusInfoList, StatusInfo{
Status: int(s),
- DisplayedStatus: s.String(),
+ DisplayedStatus: s.LocaleString(lang),
})
}
return statusInfoList
diff --git a/models/actions/runner.go b/models/actions/runner.go
index cfe936c495..99173000fb 100644
--- a/models/actions/runner.go
+++ b/models/actions/runner.go
@@ -6,32 +6,45 @@ package actions
import (
"context"
"encoding/binary"
+ "encoding/hex"
"fmt"
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/shared/types"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/util"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/shared/types"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/util"
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
"xorm.io/builder"
)
// ActionRunner represents runner machines
+//
+// It can be:
+// 1. global runner, OwnerID is 0 and RepoID is 0
+// 2. org/user level runner, OwnerID is org/user ID and RepoID is 0
+// 3. repo level runner, OwnerID is 0 and RepoID is repo ID
+//
+// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero,
+// or it will be complicated to find runners belonging to a specific owner.
+// For example, conditions like `OwnerID = 1` will also return runner {OwnerID: 1, RepoID: 1},
+// but it's a repo level runner, not an org/user level runner.
+// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level runners.
type ActionRunner struct {
ID int64
UUID string `xorm:"CHAR(36) UNIQUE"`
Name string `xorm:"VARCHAR(255)"`
Version string `xorm:"VARCHAR(64)"`
- OwnerID int64 `xorm:"index"` // org level runner, 0 means system
+ OwnerID int64 `xorm:"index"`
Owner *user_model.User `xorm:"-"`
- RepoID int64 `xorm:"index"` // repo level runner, if OwnerID also is zero, then it's a global
+ RepoID int64 `xorm:"index"`
Repo *repo_model.Repository `xorm:"-"`
Description string `xorm:"TEXT"`
Base int // 0 native 1 docker 2 virtual machine
@@ -151,6 +164,22 @@ func (r *ActionRunner) GenerateToken() (err error) {
return err
}
+// UpdateSecret updates the hash based on the specified token. It does not
+// ensure that the runner's UUID matches the first 16 bytes of the token.
+func (r *ActionRunner) UpdateSecret(token string) error {
+ saltBytes, err := util.CryptoRandomBytes(16)
+ if err != nil {
+ return fmt.Errorf("CryptoRandomBytes %v", err)
+ }
+
+ salt := hex.EncodeToString(saltBytes)
+
+ r.Token = token
+ r.TokenSalt = salt
+ r.TokenHash = auth_model.HashToken(token, salt)
+ return nil
+}
+
func init() {
db.RegisterModel(&ActionRunner{})
}
@@ -158,7 +187,7 @@ func init() {
type FindRunnerOptions struct {
db.ListOptions
RepoID int64
- OwnerID int64
+ OwnerID int64 // it will be ignored if RepoID is set
Sort string
Filter string
IsOnline optional.Option[bool]
@@ -175,8 +204,7 @@ func (opts FindRunnerOptions) ToConds() builder.Cond {
c = c.Or(builder.Eq{"repo_id": 0, "owner_id": 0})
}
cond = cond.And(c)
- }
- if opts.OwnerID > 0 {
+ } else if opts.OwnerID > 0 { // OwnerID is ignored if RepoID is set
c := builder.NewCond().And(builder.Eq{"owner_id": opts.OwnerID})
if opts.WithAvailable {
c = c.Or(builder.Eq{"repo_id": 0, "owner_id": 0})
@@ -243,6 +271,7 @@ func GetRunnerByID(ctx context.Context, id int64) (*ActionRunner, error) {
// UpdateRunner updates runner's information.
func UpdateRunner(ctx context.Context, r *ActionRunner, cols ...string) error {
e := db.GetEngine(ctx)
+ r.Name, _ = util.SplitStringAtByteN(r.Name, 255)
var err error
if len(cols) == 0 {
_, err = e.ID(r.ID).AllCols().Update(r)
@@ -253,32 +282,33 @@ func UpdateRunner(ctx context.Context, r *ActionRunner, cols ...string) error {
}
// DeleteRunner deletes a runner by given ID.
-func DeleteRunner(ctx context.Context, id int64) error {
- runner, err := GetRunnerByID(ctx, id)
- if err != nil {
- return err
- }
-
+func DeleteRunner(ctx context.Context, r *ActionRunner) error {
// Replace the UUID, which was either based on the secret's first 16 bytes or an UUIDv4,
// with a sequence of 8 0xff bytes followed by the little-endian version of the record's
// identifier. This will prevent the deleted record's identifier from colliding with any
// new record.
b := make([]byte, 8)
- binary.LittleEndian.PutUint64(b, uint64(id))
- runner.UUID = fmt.Sprintf("ffffffff-ffff-ffff-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x",
+ binary.LittleEndian.PutUint64(b, uint64(r.ID))
+ r.UUID = fmt.Sprintf("ffffffff-ffff-ffff-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x",
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7])
- err = UpdateRunner(ctx, runner, "UUID")
+ err := UpdateRunner(ctx, r, "UUID")
if err != nil {
return err
}
- _, err = db.DeleteByID[ActionRunner](ctx, id)
+ _, err = db.DeleteByID[ActionRunner](ctx, r.ID)
return err
}
// CreateRunner creates new runner.
func CreateRunner(ctx context.Context, t *ActionRunner) error {
+ if t.OwnerID != 0 && t.RepoID != 0 {
+ // It's trying to create a runner that belongs to a repository, but OwnerID has been set accidentally.
+ // Remove OwnerID to avoid confusion; it's not worth returning an error here.
+ t.OwnerID = 0
+ }
+ t.Name, _ = util.SplitStringAtByteN(t.Name, 255)
return db.Insert(ctx, t)
}
diff --git a/models/actions/runner_list.go b/models/actions/runner_list.go
index 3ef8ebb254..6a64c46596 100644
--- a/models/actions/runner_list.go
+++ b/models/actions/runner_list.go
@@ -6,10 +6,10 @@ package actions
import (
"context"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
)
type RunnerList []*ActionRunner
diff --git a/models/actions/runner_test.go b/models/actions/runner_test.go
index a71f5f0044..0623e66046 100644
--- a/models/actions/runner_test.go
+++ b/models/actions/runner_test.go
@@ -7,23 +7,39 @@ import (
"fmt"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
+// TestUpdateSecret checks that ActionRunner.UpdateSecret() sets the Token,
+// TokenSalt and TokenHash fields based on the specified token.
+func TestUpdateSecret(t *testing.T) {
+ runner := ActionRunner{}
+ token := "0123456789012345678901234567890123456789"
+
+ err := runner.UpdateSecret(token)
+
+ require.NoError(t, err)
+ assert.Equal(t, token, runner.Token)
+ assert.Regexp(t, "^[0-9a-f]{32}$", runner.TokenSalt)
+ assert.Equal(t, runner.TokenHash, auth_model.HashToken(token, runner.TokenSalt))
+}
+
func TestDeleteRunner(t *testing.T) {
const recordID = 12345678
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
before := unittest.AssertExistsAndLoadBean(t, &ActionRunner{ID: recordID})
- err := DeleteRunner(db.DefaultContext, recordID)
- assert.NoError(t, err)
+ err := DeleteRunner(db.DefaultContext, &ActionRunner{ID: recordID})
+ require.NoError(t, err)
var after ActionRunner
found, err := db.GetEngine(db.DefaultContext).ID(recordID).Unscoped().Get(&after)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, found)
// Most fields (namely Name, Version, OwnerID, RepoID, Description, Base, RepoRange,
diff --git a/models/actions/runner_token.go b/models/actions/runner_token.go
index ccd9bbccb3..a59304d8e8 100644
--- a/models/actions/runner_token.go
+++ b/models/actions/runner_token.go
@@ -7,20 +7,31 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
)
// ActionRunnerToken represents runner tokens
+//
+// It can be:
+// 1. global token, OwnerID is 0 and RepoID is 0
+// 2. org/user level token, OwnerID is org/user ID and RepoID is 0
+// 3. repo level token, OwnerID is 0 and RepoID is repo ID
+//
+// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero,
+// or it will be complicated to find tokens belonging to a specific owner.
+// For example, conditions like `OwnerID = 1` will also return token {OwnerID: 1, RepoID: 1},
+// but it's a repo level token, not an org/user level token.
+// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level tokens.
type ActionRunnerToken struct {
ID int64
Token string `xorm:"UNIQUE"`
- OwnerID int64 `xorm:"index"` // org level runner, 0 means system
+ OwnerID int64 `xorm:"index"`
Owner *user_model.User `xorm:"-"`
- RepoID int64 `xorm:"index"` // repo level runner, if orgid also is zero, then it's a global
+ RepoID int64 `xorm:"index"`
Repo *repo_model.Repository `xorm:"-"`
IsActive bool // true means it can be used
@@ -58,7 +69,14 @@ func UpdateRunnerToken(ctx context.Context, r *ActionRunnerToken, cols ...string
}
// NewRunnerToken creates a new active runner token and invalidate all old tokens
+// ownerID will be ignored and treated as 0 if repoID is non-zero.
func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
+ if ownerID != 0 && repoID != 0 {
+ // It's trying to create a runner token that belongs to a repository, but OwnerID has been set accidentally.
+ // Remove OwnerID to avoid confusion; it's not worth returning an error here.
+ ownerID = 0
+ }
+
token, err := util.CryptoRandomString(40)
if err != nil {
return nil, err
@@ -84,6 +102,12 @@ func NewRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerTo
// GetLatestRunnerToken returns the latest runner token
func GetLatestRunnerToken(ctx context.Context, ownerID, repoID int64) (*ActionRunnerToken, error) {
+ if ownerID != 0 && repoID != 0 {
+ // It's trying to get a runner token that belongs to a repository, but OwnerID has been set accidentally.
+ // Remove OwnerID to avoid confusion; it's not worth returning an error here.
+ ownerID = 0
+ }
+
var runnerToken ActionRunnerToken
has, err := db.GetEngine(ctx).Where("owner_id=? AND repo_id=?", ownerID, repoID).
OrderBy("id DESC").Get(&runnerToken)
diff --git a/models/actions/runner_token_test.go b/models/actions/runner_token_test.go
index e85e99abe5..65d83a8fd0 100644
--- a/models/actions/runner_token_test.go
+++ b/models/actions/runner_token_test.go
@@ -6,35 +6,36 @@ package actions
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetLatestRunnerToken(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
token := unittest.AssertExistsAndLoadBean(t, &ActionRunnerToken{ID: 3})
expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0)
- assert.NoError(t, err)
- assert.EqualValues(t, token, expectedToken)
+ require.NoError(t, err)
+ assert.EqualValues(t, expectedToken, token)
}
func TestNewRunnerToken(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
token, err := NewRunnerToken(db.DefaultContext, 1, 0)
- assert.NoError(t, err)
+ require.NoError(t, err)
expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0)
- assert.NoError(t, err)
- assert.EqualValues(t, token, expectedToken)
+ require.NoError(t, err)
+ assert.EqualValues(t, expectedToken, token)
}
func TestUpdateRunnerToken(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
token := unittest.AssertExistsAndLoadBean(t, &ActionRunnerToken{ID: 3})
token.IsActive = true
- assert.NoError(t, UpdateRunnerToken(db.DefaultContext, token))
+ require.NoError(t, UpdateRunnerToken(db.DefaultContext, token))
expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0)
- assert.NoError(t, err)
- assert.EqualValues(t, token, expectedToken)
+ require.NoError(t, err)
+ assert.EqualValues(t, expectedToken, token)
}
diff --git a/models/actions/schedule.go b/models/actions/schedule.go
index 3646a046a0..633582e017 100644
--- a/models/actions/schedule.go
+++ b/models/actions/schedule.go
@@ -8,13 +8,14 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ webhook_module "forgejo.org/modules/webhook"
- "github.com/robfig/cron/v3"
+ "xorm.io/builder"
)
// ActionSchedule represents a schedule of a workflow file
@@ -44,17 +45,12 @@ func init() {
// GetSchedulesMapByIDs returns the schedules by given id slice.
func GetSchedulesMapByIDs(ctx context.Context, ids []int64) (map[int64]*ActionSchedule, error) {
schedules := make(map[int64]*ActionSchedule, len(ids))
+ if len(ids) == 0 {
+ return schedules, nil
+ }
return schedules, db.GetEngine(ctx).In("id", ids).Find(&schedules)
}
-// GetReposMapByIDs returns the repos by given id slice.
-func GetReposMapByIDs(ctx context.Context, ids []int64) (map[int64]*repo_model.Repository, error) {
- repos := make(map[int64]*repo_model.Repository, len(ids))
- return repos, db.GetEngine(ctx).In("id", ids).Find(&repos)
-}
-
-var cronParser = cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
-
// CreateScheduleTask creates new schedule task.
func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error {
// Return early if there are no rows to insert
@@ -71,6 +67,7 @@ func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error {
// Loop through each schedule row
for _, row := range rows {
+ row.Title, _ = util.SplitStringAtByteN(row.Title, 255)
// Create new schedule row
if err = db.Insert(ctx, row); err != nil {
return err
@@ -80,19 +77,21 @@ func CreateScheduleTask(ctx context.Context, rows []*ActionSchedule) error {
now := time.Now()
for _, spec := range row.Specs {
+ specRow := &ActionScheduleSpec{
+ RepoID: row.RepoID,
+ ScheduleID: row.ID,
+ Spec: spec,
+ }
// Parse the spec and check for errors
- schedule, err := cronParser.Parse(spec)
+ schedule, err := specRow.Parse()
if err != nil {
continue // skip to the next spec if there's an error
}
+ specRow.Next = timeutil.TimeStamp(schedule.Next(now).Unix())
+
// Insert the new schedule spec row
- if err = db.Insert(ctx, &ActionScheduleSpec{
- RepoID: row.RepoID,
- ScheduleID: row.ID,
- Spec: spec,
- Next: timeutil.TimeStamp(schedule.Next(now).Unix()),
- }); err != nil {
+ if err = db.Insert(ctx, specRow); err != nil {
return err
}
}
@@ -120,21 +119,45 @@ func DeleteScheduleTaskByRepo(ctx context.Context, id int64) error {
return committer.Commit()
}
-func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository) error {
+func CleanRepoScheduleTasks(ctx context.Context, repo *repo_model.Repository, cancelPreviousJobs bool) error {
// If actions disabled when there is schedule task, this will remove the outdated schedule tasks
// There is no other place we can do this because the app.ini will be changed manually
if err := DeleteScheduleTaskByRepo(ctx, repo.ID); err != nil {
return fmt.Errorf("DeleteCronTaskByRepo: %v", err)
}
- // cancel running cron jobs of this repository and delete old schedules
- if err := CancelPreviousJobs(
- ctx,
- repo.ID,
- repo.DefaultBranch,
- "",
- webhook_module.HookEventSchedule,
- ); err != nil {
- return fmt.Errorf("CancelPreviousJobs: %v", err)
+ if cancelPreviousJobs {
+ // cancel running cron jobs of this repository and delete old schedules
+ if err := CancelPreviousJobs(
+ ctx,
+ repo.ID,
+ repo.DefaultBranch,
+ "",
+ webhook_module.HookEventSchedule,
+ ); err != nil {
+ return fmt.Errorf("CancelPreviousJobs: %v", err)
+ }
}
return nil
}
+
+type FindScheduleOptions struct {
+ db.ListOptions
+ RepoID int64
+ OwnerID int64
+}
+
+func (opts FindScheduleOptions) ToConds() builder.Cond {
+ cond := builder.NewCond()
+ if opts.RepoID > 0 {
+ cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
+ }
+ if opts.OwnerID > 0 {
+ cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
+ }
+
+ return cond
+}
+
+func (opts FindScheduleOptions) ToOrders() string {
+ return "`id` DESC"
+}
diff --git a/models/actions/schedule_list.go b/models/actions/schedule_list.go
deleted file mode 100644
index 5361b94801..0000000000
--- a/models/actions/schedule_list.go
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2023 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package actions
-
-import (
- "context"
-
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
-
- "xorm.io/builder"
-)
-
-type ScheduleList []*ActionSchedule
-
-// GetUserIDs returns a slice of user's id
-func (schedules ScheduleList) GetUserIDs() []int64 {
- return container.FilterSlice(schedules, func(schedule *ActionSchedule) (int64, bool) {
- return schedule.TriggerUserID, true
- })
-}
-
-func (schedules ScheduleList) GetRepoIDs() []int64 {
- return container.FilterSlice(schedules, func(schedule *ActionSchedule) (int64, bool) {
- return schedule.RepoID, true
- })
-}
-
-func (schedules ScheduleList) LoadTriggerUser(ctx context.Context) error {
- userIDs := schedules.GetUserIDs()
- users := make(map[int64]*user_model.User, len(userIDs))
- if err := db.GetEngine(ctx).In("id", userIDs).Find(&users); err != nil {
- return err
- }
- for _, schedule := range schedules {
- if schedule.TriggerUserID == user_model.ActionsUserID {
- schedule.TriggerUser = user_model.NewActionsUser()
- } else {
- schedule.TriggerUser = users[schedule.TriggerUserID]
- if schedule.TriggerUser == nil {
- schedule.TriggerUser = user_model.NewGhostUser()
- }
- }
- }
- return nil
-}
-
-func (schedules ScheduleList) LoadRepos(ctx context.Context) error {
- repoIDs := schedules.GetRepoIDs()
- repos, err := repo_model.GetRepositoriesMapByIDs(ctx, repoIDs)
- if err != nil {
- return err
- }
- for _, schedule := range schedules {
- schedule.Repo = repos[schedule.RepoID]
- }
- return nil
-}
-
-type FindScheduleOptions struct {
- db.ListOptions
- RepoID int64
- OwnerID int64
-}
-
-func (opts FindScheduleOptions) ToConds() builder.Cond {
- cond := builder.NewCond()
- if opts.RepoID > 0 {
- cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
- }
- if opts.OwnerID > 0 {
- cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
- }
-
- return cond
-}
-
-func (opts FindScheduleOptions) ToOrders() string {
- return "`id` DESC"
-}
diff --git a/models/actions/schedule_spec.go b/models/actions/schedule_spec.go
index 91240459a0..83bdceb850 100644
--- a/models/actions/schedule_spec.go
+++ b/models/actions/schedule_spec.go
@@ -5,10 +5,12 @@ package actions
import (
"context"
+ "strings"
+ "time"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/timeutil"
"github.com/robfig/cron/v3"
)
@@ -32,8 +34,29 @@ type ActionScheduleSpec struct {
Updated timeutil.TimeStamp `xorm:"updated"`
}
+// Parse parses the spec and returns a cron.Schedule
+// Unlike the default cron parser, Parse uses UTC timezone as the default if none is specified.
func (s *ActionScheduleSpec) Parse() (cron.Schedule, error) {
- return cronParser.Parse(s.Spec)
+ parser := cron.NewParser(cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.Dow | cron.Descriptor)
+ schedule, err := parser.Parse(s.Spec)
+ if err != nil {
+ return nil, err
+ }
+
+ // If the spec has specified a timezone, use it
+ if strings.HasPrefix(s.Spec, "TZ=") || strings.HasPrefix(s.Spec, "CRON_TZ=") {
+ return schedule, nil
+ }
+
+ specSchedule, ok := schedule.(*cron.SpecSchedule)
+ // If it's not a spec schedule, like "@every 5m", timezone is not relevant
+ if !ok {
+ return schedule, nil
+ }
+
+ // Set the timezone to UTC
+ specSchedule.Location = time.UTC
+ return specSchedule, nil
}
func init() {
diff --git a/models/actions/schedule_spec_list.go b/models/actions/schedule_spec_list.go
index f7dac72f8b..0a09a60acb 100644
--- a/models/actions/schedule_spec_list.go
+++ b/models/actions/schedule_spec_list.go
@@ -6,9 +6,9 @@ package actions
import (
"context"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/container"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/container"
"xorm.io/builder"
)
@@ -22,6 +22,10 @@ func (specs SpecList) GetScheduleIDs() []int64 {
}
func (specs SpecList) LoadSchedules(ctx context.Context) error {
+ if len(specs) == 0 {
+ return nil
+ }
+
scheduleIDs := specs.GetScheduleIDs()
schedules, err := GetSchedulesMapByIDs(ctx, scheduleIDs)
if err != nil {
@@ -32,7 +36,7 @@ func (specs SpecList) LoadSchedules(ctx context.Context) error {
}
repoIDs := specs.GetRepoIDs()
- repos, err := GetReposMapByIDs(ctx, repoIDs)
+ repos, err := repo_model.GetRepositoriesMapByIDs(ctx, repoIDs)
if err != nil {
return err
}
@@ -50,6 +54,10 @@ func (specs SpecList) GetRepoIDs() []int64 {
}
func (specs SpecList) LoadRepos(ctx context.Context) error {
+ if len(specs) == 0 {
+ return nil
+ }
+
repoIDs := specs.GetRepoIDs()
repos, err := repo_model.GetRepositoriesMapByIDs(ctx, repoIDs)
if err != nil {
diff --git a/models/actions/schedule_spec_test.go b/models/actions/schedule_spec_test.go
new file mode 100644
index 0000000000..0c26fce4b2
--- /dev/null
+++ b/models/actions/schedule_spec_test.go
@@ -0,0 +1,71 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package actions
+
+import (
+ "testing"
+ "time"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestActionScheduleSpec_Parse(t *testing.T) {
+ // Mock the local timezone is not UTC
+ local := time.Local
+ tz, err := time.LoadLocation("Asia/Shanghai")
+ require.NoError(t, err)
+ defer func() {
+ time.Local = local
+ }()
+ time.Local = tz
+
+ now, err := time.Parse(time.RFC3339, "2024-07-31T15:47:55+08:00")
+ require.NoError(t, err)
+
+ tests := []struct {
+ name string
+ spec string
+ want string
+ wantErr assert.ErrorAssertionFunc
+ }{
+ {
+ name: "regular",
+ spec: "0 10 * * *",
+ want: "2024-07-31T10:00:00Z",
+ wantErr: assert.NoError,
+ },
+ {
+ name: "invalid",
+ spec: "0 10 * *",
+ want: "",
+ wantErr: assert.Error,
+ },
+ {
+ name: "with timezone",
+ spec: "TZ=America/New_York 0 10 * * *",
+ want: "2024-07-31T14:00:00Z",
+ wantErr: assert.NoError,
+ },
+ {
+ name: "timezone irrelevant",
+ spec: "@every 5m",
+ want: "2024-07-31T07:52:55Z",
+ wantErr: assert.NoError,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ s := &ActionScheduleSpec{
+ Spec: tt.spec,
+ }
+ got, err := s.Parse()
+ tt.wantErr(t, err)
+
+ if err == nil {
+ assert.Equal(t, tt.want, got.Next(now).UTC().Format(time.RFC3339))
+ }
+ })
+ }
+}
diff --git a/models/actions/status.go b/models/actions/status.go
index eda2234137..f4357af731 100644
--- a/models/actions/status.go
+++ b/models/actions/status.go
@@ -4,7 +4,7 @@
package actions
import (
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/translation"
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
)
diff --git a/models/actions/task.go b/models/actions/task.go
index 9946cf5233..63cbc6e586 100644
--- a/models/actions/task.go
+++ b/models/actions/task.go
@@ -9,14 +9,13 @@ import (
"fmt"
"time"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
lru "github.com/hashicorp/golang-lru/v2"
@@ -35,7 +34,7 @@ type ActionTask struct {
RunnerID int64 `xorm:"index"`
Status Status `xorm:"index"`
Started timeutil.TimeStamp `xorm:"index"`
- Stopped timeutil.TimeStamp
+ Stopped timeutil.TimeStamp `xorm:"index(stopped_log_expired)"`
RepoID int64 `xorm:"index"`
OwnerID int64 `xorm:"index"`
@@ -51,8 +50,8 @@ type ActionTask struct {
LogInStorage bool // read log from database or from storage
LogLength int64 // lines count
LogSize int64 // blob size
- LogIndexes LogIndexes `xorm:"LONGBLOB"` // line number to offset
- LogExpired bool // files that are too old will be deleted
+ LogIndexes LogIndexes `xorm:"LONGBLOB"` // line number to offset
+ LogExpired bool `xorm:"index(stopped_log_expired)"` // files that are too old will be deleted
Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated index"`
@@ -245,7 +244,7 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask
var job *ActionRunJob
log.Trace("runner labels: %v", runner.AgentLabels)
for _, v := range jobs {
- if isSubset(runner.AgentLabels, v.RunsOn) {
+ if v.ItRunsOn(runner.AgentLabels) {
job = v
break
}
@@ -341,7 +340,7 @@ func UpdateTask(ctx context.Context, task *ActionTask, cols ...string) error {
// UpdateTaskByState updates the task by the state.
// It will always update the task if the state is not final, even there is no change.
// So it will update ActionTask.Updated to avoid the task being judged as a zombie task.
-func UpdateTaskByState(ctx context.Context, state *runnerv1.TaskState) (*ActionTask, error) {
+func UpdateTaskByState(ctx context.Context, runnerID int64, state *runnerv1.TaskState) (*ActionTask, error) {
stepStates := map[int64]*runnerv1.StepState{}
for _, v := range state.Steps {
stepStates[v.Id] = v
@@ -360,6 +359,8 @@ func UpdateTaskByState(ctx context.Context, state *runnerv1.TaskState) (*ActionT
return nil, err
} else if !has {
return nil, util.ErrNotExist
+ } else if runnerID != task.RunnerID {
+ return nil, fmt.Errorf("invalid runner for task")
}
if task.Status.IsDone() {
@@ -470,18 +471,14 @@ func StopTask(ctx context.Context, taskID int64, status Status) error {
return nil
}
-func isSubset(set, subset []string) bool {
- m := make(container.Set[string], len(set))
- for _, v := range set {
- m.Add(v)
- }
+func FindOldTasksToExpire(ctx context.Context, olderThan timeutil.TimeStamp, limit int) ([]*ActionTask, error) {
+ e := db.GetEngine(ctx)
- for _, v := range subset {
- if !m.Contains(v) {
- return false
- }
- }
- return true
+ tasks := make([]*ActionTask, 0, limit)
+ // Check "stopped > 0" to avoid deleting tasks that are still running
+ return tasks, e.Where("stopped > 0 AND stopped < ? AND log_expired = ?", olderThan, false).
+ Limit(limit).
+ Find(&tasks)
}
func convertTimestamp(timestamp *timestamppb.Timestamp) timeutil.TimeStamp {
@@ -492,7 +489,13 @@ func convertTimestamp(timestamp *timestamppb.Timestamp) timeutil.TimeStamp {
}
func logFileName(repoFullName string, taskID int64) string {
- return fmt.Sprintf("%s/%02x/%d.log", repoFullName, taskID%256, taskID)
+ ret := fmt.Sprintf("%s/%02x/%d.log", repoFullName, taskID%256, taskID)
+
+ if setting.Actions.LogCompression.IsZstd() {
+ ret += ".zst"
+ }
+
+ return ret
}
func getTaskIDFromCache(token string) int64 {
diff --git a/models/actions/task_list.go b/models/actions/task_list.go
index df4b43c5ef..fe4c028c2c 100644
--- a/models/actions/task_list.go
+++ b/models/actions/task_list.go
@@ -6,9 +6,9 @@ package actions
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
)
@@ -50,7 +50,7 @@ type FindTaskOptions struct {
RepoID int64
OwnerID int64
CommitSHA string
- Status Status
+ Status []Status
UpdatedBefore timeutil.TimeStamp
StartedBefore timeutil.TimeStamp
RunnerID int64
@@ -67,8 +67,8 @@ func (opts FindTaskOptions) ToConds() builder.Cond {
if opts.CommitSHA != "" {
cond = cond.And(builder.Eq{"commit_sha": opts.CommitSHA})
}
- if opts.Status > StatusUnknown {
- cond = cond.And(builder.Eq{"status": opts.Status})
+ if opts.Status != nil {
+ cond = cond.And(builder.In("status", opts.Status))
}
if opts.UpdatedBefore > 0 {
cond = cond.And(builder.Lt{"updated": opts.UpdatedBefore})
diff --git a/models/actions/task_output.go b/models/actions/task_output.go
index eab5b93118..fa13cadd53 100644
--- a/models/actions/task_output.go
+++ b/models/actions/task_output.go
@@ -6,7 +6,7 @@ package actions
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
// ActionTaskOutput represents an output of ActionTask.
diff --git a/models/actions/task_step.go b/models/actions/task_step.go
index 3af1fe3f5a..1f20157271 100644
--- a/models/actions/task_step.go
+++ b/models/actions/task_step.go
@@ -7,8 +7,8 @@ import (
"context"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
)
// ActionTaskStep represents a step of ActionTask
diff --git a/models/actions/tasks_version.go b/models/actions/tasks_version.go
index d8df353593..a5c357888f 100644
--- a/models/actions/tasks_version.go
+++ b/models/actions/tasks_version.go
@@ -6,9 +6,9 @@ package actions
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
)
// ActionTasksVersion
diff --git a/models/actions/utils.go b/models/actions/utils.go
index 12657942fc..7dd3f7ec12 100644
--- a/models/actions/utils.go
+++ b/models/actions/utils.go
@@ -12,9 +12,9 @@ import (
"io"
"time"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
)
func generateSaltedToken() (string, string, string, string, error) {
diff --git a/models/actions/utils_test.go b/models/actions/utils_test.go
index 98c048d4ef..af6fd04a6a 100644
--- a/models/actions/utils_test.go
+++ b/models/actions/utils_test.go
@@ -8,7 +8,7 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
diff --git a/models/actions/variable.go b/models/actions/variable.go
index 8aff844659..203065487c 100644
--- a/models/actions/variable.go
+++ b/models/actions/variable.go
@@ -5,16 +5,27 @@ package actions
import (
"context"
- "errors"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
)
+// ActionVariable represents a variable that can be used in actions
+//
+// It can be:
+// 1. global variable, OwnerID is 0 and RepoID is 0
+// 2. org/user level variable, OwnerID is org/user ID and RepoID is 0
+// 3. repo level variable, OwnerID is 0 and RepoID is repo ID
+//
+// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero,
+// or it will be complicated to find variables belonging to a specific owner.
+// For example, conditions like `OwnerID = 1` will also return variable {OwnerID: 1, RepoID: 1},
+// but it's a repo level variable, not an org/user level variable.
+// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level variables.
type ActionVariable struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(owner_repo_name)"`
@@ -29,30 +40,26 @@ func init() {
db.RegisterModel(new(ActionVariable))
}
-func (v *ActionVariable) Validate() error {
- if v.OwnerID != 0 && v.RepoID != 0 {
- return errors.New("a variable should not be bound to an owner and a repository at the same time")
- }
- return nil
-}
-
func InsertVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*ActionVariable, error) {
+ if ownerID != 0 && repoID != 0 {
+ // It's trying to create a variable that belongs to a repository, but OwnerID has been set accidentally.
+ // Remove OwnerID to avoid confusion; it's not worth returning an error here.
+ ownerID = 0
+ }
+
variable := &ActionVariable{
OwnerID: ownerID,
RepoID: repoID,
Name: strings.ToUpper(name),
Data: data,
}
- if err := variable.Validate(); err != nil {
- return variable, err
- }
return variable, db.Insert(ctx, variable)
}
type FindVariablesOpts struct {
db.ListOptions
- OwnerID int64
RepoID int64
+ OwnerID int64 // it will be ignored if RepoID is set
Name string
}
@@ -60,8 +67,13 @@ func (opts FindVariablesOpts) ToConds() builder.Cond {
cond := builder.NewCond()
// Since we now support instance-level variables,
// there is no need to check for null values for `owner_id` and `repo_id`
- cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
+ if opts.RepoID != 0 { // if RepoID is set
+ // ignore OwnerID and treat it as 0
+ cond = cond.And(builder.Eq{"owner_id": 0})
+ } else {
+ cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
+ }
if opts.Name != "" {
cond = cond.And(builder.Eq{"name": strings.ToUpper(opts.Name)})
@@ -74,7 +86,7 @@ func FindVariables(ctx context.Context, opts FindVariablesOpts) ([]*ActionVariab
}
func UpdateVariable(ctx context.Context, variable *ActionVariable) (bool, error) {
- count, err := db.GetEngine(ctx).ID(variable.ID).Cols("name", "data").
+ count, err := db.GetEngine(ctx).ID(variable.ID).Where("owner_id = ? AND repo_id = ?", variable.OwnerID, variable.RepoID).Cols("name", "data").
Update(&ActionVariable{
Name: variable.Name,
Data: variable.Data,
@@ -82,11 +94,9 @@ func UpdateVariable(ctx context.Context, variable *ActionVariable) (bool, error)
return count != 0, err
}
-func DeleteVariable(ctx context.Context, id int64) error {
- if _, err := db.DeleteByID[ActionVariable](ctx, id); err != nil {
- return err
- }
- return nil
+func DeleteVariable(ctx context.Context, variableID, ownerID, repoID int64) (bool, error) {
+ count, err := db.GetEngine(ctx).Table("action_variable").Where("id = ? AND owner_id = ? AND repo_id = ?", variableID, ownerID, repoID).Delete()
+ return count != 0, err
}
func GetVariablesOfRun(ctx context.Context, run *ActionRun) (map[string]string, error) {
diff --git a/models/activities/action.go b/models/activities/action.go
index b6c816f096..ef99132e6c 100644
--- a/models/activities/action.go
+++ b/models/activities/action.go
@@ -14,20 +14,20 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
"xorm.io/xorm/schemas"
@@ -250,6 +250,9 @@ func (a *Action) GetActDisplayNameTitle(ctx context.Context) string {
// GetRepoUserName returns the name of the action repository owner.
func (a *Action) GetRepoUserName(ctx context.Context) string {
a.loadRepo(ctx)
+ if a.Repo == nil {
+ return "(non-existing-repo)"
+ }
return a.Repo.OwnerName
}
@@ -262,6 +265,9 @@ func (a *Action) ShortRepoUserName(ctx context.Context) string {
// GetRepoName returns the name of the action repository.
func (a *Action) GetRepoName(ctx context.Context) string {
a.loadRepo(ctx)
+ if a.Repo == nil {
+ return "(non-existing-repo)"
+ }
return a.Repo.Name
}
diff --git a/models/activities/action_list.go b/models/activities/action_list.go
index aafb7f8a26..64b92bbda1 100644
--- a/models/activities/action_list.go
+++ b/models/activities/action_list.go
@@ -8,12 +8,12 @@ import (
"fmt"
"strconv"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/activities/action_test.go b/models/activities/action_test.go
index 5467bd35fb..ebc40cffa5 100644
--- a/models/activities/action_test.go
+++ b/models/activities/action_test.go
@@ -8,19 +8,20 @@ import (
"path"
"testing"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- issue_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ issue_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestAction_GetRepoPath(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
action := &activities_model.Action{RepoID: repo.ID}
@@ -28,7 +29,7 @@ func TestAction_GetRepoPath(t *testing.T) {
}
func TestAction_GetRepoLink(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
comment := unittest.AssertExistsAndLoadBean(t, &issue_model.Comment{ID: 2})
@@ -42,7 +43,7 @@ func TestAction_GetRepoLink(t *testing.T) {
func TestGetFeeds(t *testing.T) {
// test with an individual user
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
actions, count, err := activities_model.GetFeeds(db.DefaultContext, activities_model.GetFeedsOptions{
@@ -52,7 +53,7 @@ func TestGetFeeds(t *testing.T) {
OnlyPerformedBy: false,
IncludeDeleted: true,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, actions, 1) {
assert.EqualValues(t, 1, actions[0].ID)
assert.EqualValues(t, user.ID, actions[0].UserID)
@@ -65,13 +66,13 @@ func TestGetFeeds(t *testing.T) {
IncludePrivate: false,
OnlyPerformedBy: false,
})
- assert.NoError(t, err)
- assert.Len(t, actions, 0)
+ require.NoError(t, err)
+ assert.Empty(t, actions)
assert.Equal(t, int64(0), count)
}
func TestGetFeedsForRepos(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
privRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8})
@@ -81,8 +82,8 @@ func TestGetFeedsForRepos(t *testing.T) {
RequestedRepo: privRepo,
IncludePrivate: true,
})
- assert.NoError(t, err)
- assert.Len(t, actions, 0)
+ require.NoError(t, err)
+ assert.Empty(t, actions)
assert.Equal(t, int64(0), count)
// public repo & no login
@@ -90,7 +91,7 @@ func TestGetFeedsForRepos(t *testing.T) {
RequestedRepo: pubRepo,
IncludePrivate: true,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, actions, 1)
assert.Equal(t, int64(1), count)
@@ -100,7 +101,7 @@ func TestGetFeedsForRepos(t *testing.T) {
IncludePrivate: true,
Actor: user,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, actions, 1)
assert.Equal(t, int64(1), count)
@@ -110,14 +111,14 @@ func TestGetFeedsForRepos(t *testing.T) {
IncludePrivate: true,
Actor: user,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, actions, 1)
assert.Equal(t, int64(1), count)
}
func TestGetFeeds2(t *testing.T) {
// test with an organization user
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -128,7 +129,7 @@ func TestGetFeeds2(t *testing.T) {
OnlyPerformedBy: false,
IncludeDeleted: true,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, actions, 1)
if assert.Len(t, actions, 1) {
assert.EqualValues(t, 2, actions[0].ID)
@@ -143,8 +144,8 @@ func TestGetFeeds2(t *testing.T) {
OnlyPerformedBy: false,
IncludeDeleted: true,
})
- assert.NoError(t, err)
- assert.Len(t, actions, 0)
+ require.NoError(t, err)
+ assert.Empty(t, actions)
assert.Equal(t, int64(0), count)
}
@@ -189,14 +190,14 @@ func TestActivityReadable(t *testing.T) {
}
func TestNotifyWatchers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
action := &activities_model.Action{
ActUserID: 8,
RepoID: 1,
OpType: activities_model.ActionStarRepo,
}
- assert.NoError(t, activities_model.NotifyWatchers(db.DefaultContext, action))
+ require.NoError(t, activities_model.NotifyWatchers(db.DefaultContext, action))
// One watchers are inactive, thus action is only created for user 8, 1, 4, 11
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
@@ -226,7 +227,7 @@ func TestNotifyWatchers(t *testing.T) {
}
func TestGetFeedsCorrupted(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
ID: 8,
@@ -238,8 +239,8 @@ func TestGetFeedsCorrupted(t *testing.T) {
Actor: user,
IncludePrivate: true,
})
- assert.NoError(t, err)
- assert.Len(t, actions, 0)
+ require.NoError(t, err)
+ assert.Empty(t, actions)
assert.Equal(t, int64(0), count)
}
@@ -247,47 +248,46 @@ func TestConsistencyUpdateAction(t *testing.T) {
if !setting.Database.Type.IsSQLite3() {
t.Skip("Test is only for SQLite database.")
}
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
id := 8
unittest.AssertExistsAndLoadBean(t, &activities_model.Action{
ID: int64(id),
})
_, err := db.GetEngine(db.DefaultContext).Exec(`UPDATE action SET created_unix = "" WHERE id = ?`, id)
- assert.NoError(t, err)
+ require.NoError(t, err)
actions := make([]*activities_model.Action, 0, 1)
//
// XORM returns an error when created_unix is a string
//
err = db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions)
- if assert.Error(t, err) {
- assert.Contains(t, err.Error(), "type string to a int64: invalid syntax")
- }
+ require.ErrorContains(t, err, "type string to a int64: invalid syntax")
+
//
// Get rid of incorrectly set created_unix
//
count, err := activities_model.CountActionCreatedUnixString(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, count)
count, err = activities_model.FixActionCreatedUnixString(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, count)
count, err = activities_model.CountActionCreatedUnixString(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, count)
count, err = activities_model.FixActionCreatedUnixString(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, count)
//
// XORM must be happy now
//
- assert.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions))
+ require.NoError(t, db.GetEngine(db.DefaultContext).Where("id = ?", id).Find(&actions))
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestDeleteIssueActions(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// load an issue
issue := unittest.AssertExistsAndLoadBean(t, &issue_model.Issue{ID: 4})
@@ -295,26 +295,26 @@ func TestDeleteIssueActions(t *testing.T) {
// insert a comment
err := db.Insert(db.DefaultContext, &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID})
- assert.NoError(t, err)
+ require.NoError(t, err)
comment := unittest.AssertExistsAndLoadBean(t, &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID})
// truncate action table and insert some actions
err = db.TruncateBeans(db.DefaultContext, &activities_model.Action{})
- assert.NoError(t, err)
+ require.NoError(t, err)
err = db.Insert(db.DefaultContext, &activities_model.Action{
OpType: activities_model.ActionCommentIssue,
CommentID: comment.ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
err = db.Insert(db.DefaultContext, &activities_model.Action{
OpType: activities_model.ActionCreateIssue,
RepoID: issue.RepoID,
Content: fmt.Sprintf("%d|content...", issue.Index),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
// assert that the actions exist, then delete them
unittest.AssertCount(t, &activities_model.Action{}, 2)
- assert.NoError(t, activities_model.DeleteIssueActions(db.DefaultContext, issue.RepoID, issue.ID, issue.Index))
+ require.NoError(t, activities_model.DeleteIssueActions(db.DefaultContext, issue.RepoID, issue.ID, issue.Index))
unittest.AssertCount(t, &activities_model.Action{}, 0)
}
diff --git a/models/activities/main_test.go b/models/activities/main_test.go
index 43afb84ef1..a5245ab1d3 100644
--- a/models/activities/main_test.go
+++ b/models/activities/main_test.go
@@ -6,10 +6,11 @@ package activities_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/models/activities/notification.go b/models/activities/notification.go
index 8e2b6d6937..4d13900459 100644
--- a/models/activities/notification.go
+++ b/models/activities/notification.go
@@ -9,14 +9,14 @@ import (
"net/url"
"strconv"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -287,13 +287,14 @@ type UserIDCount struct {
Count int64
}
-// GetUIDsAndNotificationCounts between the two provided times
+// GetUIDsAndNotificationCounts returns the unread counts for every user between the two provided times.
+// It must return all user IDs which appear during the period, including count=0 for users who have read all.
func GetUIDsAndNotificationCounts(ctx context.Context, since, until timeutil.TimeStamp) ([]UserIDCount, error) {
- sql := `SELECT user_id, count(*) AS count FROM notification ` +
+ sql := `SELECT user_id, sum(case when status= ? then 1 else 0 end) AS count FROM notification ` +
`WHERE user_id IN (SELECT user_id FROM notification WHERE updated_unix >= ? AND ` +
- `updated_unix < ?) AND status = ? GROUP BY user_id`
+ `updated_unix < ?) GROUP BY user_id`
var res []UserIDCount
- return res, db.GetEngine(ctx).SQL(sql, since, until, NotificationStatusUnread).Find(&res)
+ return res, db.GetEngine(ctx).SQL(sql, NotificationStatusUnread, since, until).Find(&res)
}
// SetIssueReadBy sets issue to be read by given user.
diff --git a/models/activities/notification_list.go b/models/activities/notification_list.go
index 32d2a5c051..9b09dde7ab 100644
--- a/models/activities/notification_list.go
+++ b/models/activities/notification_list.go
@@ -6,14 +6,14 @@ package activities
import (
"context"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
"xorm.io/builder"
)
diff --git a/models/activities/notification_test.go b/models/activities/notification_test.go
index 52f0eacba1..305a2ae430 100644
--- a/models/activities/notification_test.go
+++ b/models/activities/notification_test.go
@@ -7,20 +7,21 @@ import (
"context"
"testing"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCreateOrUpdateIssueNotifications(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
- assert.NoError(t, activities_model.CreateOrUpdateIssueNotifications(db.DefaultContext, issue.ID, 0, 2, 0))
+ require.NoError(t, activities_model.CreateOrUpdateIssueNotifications(db.DefaultContext, issue.ID, 0, 2, 0))
// User 9 is inactive, thus notifications for user 1 and 4 are created
notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{UserID: 1, IssueID: issue.ID})
@@ -32,7 +33,7 @@ func TestCreateOrUpdateIssueNotifications(t *testing.T) {
}
func TestNotificationsForUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
notfs, err := db.Find[activities_model.Notification](db.DefaultContext, activities_model.FindNotificationOptions{
UserID: user.ID,
@@ -41,7 +42,7 @@ func TestNotificationsForUser(t *testing.T) {
activities_model.NotificationStatusUnread,
},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, notfs, 3) {
assert.EqualValues(t, 5, notfs[0].ID)
assert.EqualValues(t, user.ID, notfs[0].UserID)
@@ -53,25 +54,25 @@ func TestNotificationsForUser(t *testing.T) {
}
func TestNotification_GetRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{RepoID: 1})
repo, err := notf.GetRepo(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, repo, notf.Repository)
assert.EqualValues(t, notf.RepoID, repo.ID)
}
func TestNotification_GetIssue(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
notf := unittest.AssertExistsAndLoadBean(t, &activities_model.Notification{RepoID: 1})
issue, err := notf.GetIssue(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, issue, notf.Issue)
assert.EqualValues(t, notf.IssueID, issue.ID)
}
func TestGetNotificationCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
cnt, err := db.Count[activities_model.Notification](db.DefaultContext, activities_model.FindNotificationOptions{
UserID: user.ID,
@@ -79,7 +80,7 @@ func TestGetNotificationCount(t *testing.T) {
activities_model.NotificationStatusRead,
},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, cnt)
cnt, err = db.Count[activities_model.Notification](db.DefaultContext, activities_model.FindNotificationOptions{
@@ -88,28 +89,28 @@ func TestGetNotificationCount(t *testing.T) {
activities_model.NotificationStatusUnread,
},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, cnt)
}
func TestSetNotificationStatus(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
notf := unittest.AssertExistsAndLoadBean(t,
&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead})
_, err := activities_model.SetNotificationStatus(db.DefaultContext, notf.ID, user, activities_model.NotificationStatusPinned)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t,
&activities_model.Notification{ID: notf.ID, Status: activities_model.NotificationStatusPinned})
_, err = activities_model.SetNotificationStatus(db.DefaultContext, 1, user, activities_model.NotificationStatusRead)
- assert.Error(t, err)
+ require.Error(t, err)
_, err = activities_model.SetNotificationStatus(db.DefaultContext, unittest.NonexistentID, user, activities_model.NotificationStatusRead)
- assert.Error(t, err)
+ require.Error(t, err)
}
func TestUpdateNotificationStatuses(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
notfUnread := unittest.AssertExistsAndLoadBean(t,
&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusUnread})
@@ -117,7 +118,7 @@ func TestUpdateNotificationStatuses(t *testing.T) {
&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusRead})
notfPinned := unittest.AssertExistsAndLoadBean(t,
&activities_model.Notification{UserID: user.ID, Status: activities_model.NotificationStatusPinned})
- assert.NoError(t, activities_model.UpdateNotificationStatuses(db.DefaultContext, user, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead))
+ require.NoError(t, activities_model.UpdateNotificationStatuses(db.DefaultContext, user, activities_model.NotificationStatusUnread, activities_model.NotificationStatusRead))
unittest.AssertExistsAndLoadBean(t,
&activities_model.Notification{ID: notfUnread.ID, Status: activities_model.NotificationStatusRead})
unittest.AssertExistsAndLoadBean(t,
@@ -127,14 +128,14 @@ func TestUpdateNotificationStatuses(t *testing.T) {
}
func TestSetIssueReadBy(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
- assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
+ require.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
return activities_model.SetIssueReadBy(ctx, issue.ID, user.ID)
}))
nt, err := activities_model.GetIssueNotification(db.DefaultContext, user.ID, issue.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, activities_model.NotificationStatusRead, nt.Status)
}
diff --git a/models/activities/repo_activity.go b/models/activities/repo_activity.go
index ba5e4959f0..3d15c22e19 100644
--- a/models/activities/repo_activity.go
+++ b/models/activities/repo_activity.go
@@ -9,12 +9,12 @@ import (
"sort"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
"xorm.io/xorm"
)
@@ -34,6 +34,7 @@ type ActivityStats struct {
OpenedPRAuthorCount int64
MergedPRs issues_model.PullRequestList
MergedPRAuthorCount int64
+ ActiveIssues issues_model.IssueList
OpenedIssues issues_model.IssueList
OpenedIssueAuthorCount int64
ClosedIssues issues_model.IssueList
@@ -172,7 +173,7 @@ func (stats *ActivityStats) MergedPRPerc() int {
// ActiveIssueCount returns total active issue count
func (stats *ActivityStats) ActiveIssueCount() int {
- return stats.OpenedIssueCount() + stats.ClosedIssueCount()
+ return len(stats.ActiveIssues)
}
// OpenedIssueCount returns open issue count
@@ -285,13 +286,21 @@ func (stats *ActivityStats) FillIssues(ctx context.Context, repoID int64, fromTi
stats.ClosedIssueAuthorCount = count
// New issues
- sess = issuesForActivityStatement(ctx, repoID, fromTime, false, false)
+ sess = newlyCreatedIssues(ctx, repoID, fromTime)
sess.OrderBy("issue.created_unix ASC")
stats.OpenedIssues = make(issues_model.IssueList, 0)
if err = sess.Find(&stats.OpenedIssues); err != nil {
return err
}
+ // Active issues
+ sess = activeIssues(ctx, repoID, fromTime)
+ sess.OrderBy("issue.created_unix ASC")
+ stats.ActiveIssues = make(issues_model.IssueList, 0)
+ if err = sess.Find(&stats.ActiveIssues); err != nil {
+ return err
+ }
+
// Opened issue authors
sess = issuesForActivityStatement(ctx, repoID, fromTime, false, false)
if _, err = sess.Select("count(distinct issue.poster_id) as `count`").Table("issue").Get(&count); err != nil {
@@ -317,6 +326,22 @@ func (stats *ActivityStats) FillUnresolvedIssues(ctx context.Context, repoID int
return sess.Find(&stats.UnresolvedIssues)
}
+func newlyCreatedIssues(ctx context.Context, repoID int64, fromTime time.Time) *xorm.Session {
+ sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID).
+ And("issue.is_pull = ?", false). // Retain the is_pull check to exclude pull requests
+ And("issue.created_unix >= ?", fromTime.Unix()) // Include all issues created after fromTime
+
+ return sess
+}
+
+func activeIssues(ctx context.Context, repoID int64, fromTime time.Time) *xorm.Session {
+ sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID).
+ And("issue.is_pull = ?", false).
+ And("issue.created_unix >= ? OR issue.closed_unix >= ?", fromTime.Unix(), fromTime.Unix())
+
+ return sess
+}
+
func issuesForActivityStatement(ctx context.Context, repoID int64, fromTime time.Time, closed, unresolved bool) *xorm.Session {
sess := db.GetEngine(ctx).Where("issue.repo_id = ?", repoID).
And("issue.is_closed = ?", closed)
diff --git a/models/activities/repo_activity_test.go b/models/activities/repo_activity_test.go
new file mode 100644
index 0000000000..c111c50208
--- /dev/null
+++ b/models/activities/repo_activity_test.go
@@ -0,0 +1,30 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package activities
+
+import (
+ "testing"
+ "time"
+
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestGetActivityStats(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+
+ stats, err := GetActivityStats(db.DefaultContext, repo, time.Unix(0, 0), true, true, true, true)
+ require.NoError(t, err)
+
+ assert.EqualValues(t, 2, stats.ActiveIssueCount())
+ assert.EqualValues(t, 2, stats.OpenedIssueCount())
+ assert.EqualValues(t, 0, stats.ClosedIssueCount())
+ assert.EqualValues(t, 3, stats.ActivePRCount())
+}
diff --git a/models/activities/statistic.go b/models/activities/statistic.go
index ff81ad78a1..4c15cb2898 100644
--- a/models/activities/statistic.go
+++ b/models/activities/statistic.go
@@ -6,18 +6,18 @@ package activities
import (
"context"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- project_model "code.gitea.io/gitea/models/project"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/setting"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ project_model "forgejo.org/models/project"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/models/webhook"
+ "forgejo.org/modules/setting"
)
// Statistic contains the database statistics
diff --git a/models/activities/user_heatmap.go b/models/activities/user_heatmap.go
index 080075d793..0cc3f759c6 100644
--- a/models/activities/user_heatmap.go
+++ b/models/activities/user_heatmap.go
@@ -6,11 +6,11 @@ package activities
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
)
// UserHeatmapData represents the data needed to create a heatmap
diff --git a/models/activities/user_heatmap_test.go b/models/activities/user_heatmap_test.go
index b7babcbde1..d922f9a78b 100644
--- a/models/activities/user_heatmap_test.go
+++ b/models/activities/user_heatmap_test.go
@@ -4,18 +4,18 @@
package activities_test
import (
- "fmt"
"testing"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/timeutil"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetUserHeatmapDataByUser(t *testing.T) {
@@ -56,7 +56,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
},
}
// Prepare
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Mock time
timeutil.MockSet(time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC))
@@ -67,7 +67,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
doer := &user_model.User{ID: tc.doerID}
_, err := unittest.LoadBeanIfExists(doer)
- assert.NoError(t, err)
+ require.NoError(t, err)
if tc.doerID == 0 {
doer = nil
}
@@ -80,7 +80,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
OnlyPerformedBy: true,
IncludeDeleted: true,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
// Get the heatmap and compare
heatmap, err := activities_model.GetUserHeatmapDataByUser(db.DefaultContext, user, doer)
@@ -88,14 +88,14 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
for _, hm := range heatmap {
contributions += int(hm.Contributions)
}
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, actions, contributions, "invalid action count: did the test data became too old?")
assert.Equal(t, count, int64(contributions))
- assert.Equal(t, tc.CountResult, contributions, fmt.Sprintf("testcase '%s'", tc.desc))
+ assert.Equal(t, tc.CountResult, contributions, tc.desc)
// Test JSON rendering
jsonData, err := json.Marshal(heatmap)
- assert.NoError(t, err)
- assert.Equal(t, tc.JSONResult, string(jsonData))
+ require.NoError(t, err)
+ assert.JSONEq(t, tc.JSONResult, string(jsonData))
}
}
diff --git a/models/admin/task.go b/models/admin/task.go
index c8bc95f981..b4e1ac0134 100644
--- a/models/admin/task.go
+++ b/models/admin/task.go
@@ -7,16 +7,16 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/secret"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/migration"
+ "forgejo.org/modules/secret"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
)
// Task represents a task
@@ -44,7 +44,7 @@ func init() {
// TranslatableMessage represents JSON struct that can be translated with a Locale
type TranslatableMessage struct {
Format string
- Args []any `json:"omitempty"`
+ Args []any `json:",omitempty"`
}
// LoadRepo loads repository of the task
diff --git a/models/asymkey/error.go b/models/asymkey/error.go
index 03bc82302f..fc0dd88232 100644
--- a/models/asymkey/error.go
+++ b/models/asymkey/error.go
@@ -6,7 +6,7 @@ package asymkey
import (
"fmt"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
// ErrKeyUnableVerify represents a "KeyUnableVerify" kind of error.
@@ -192,28 +192,6 @@ func (err ErrGPGKeyIDAlreadyUsed) Unwrap() error {
return util.ErrAlreadyExist
}
-// ErrGPGKeyAccessDenied represents a "GPGKeyAccessDenied" kind of Error.
-type ErrGPGKeyAccessDenied struct {
- UserID int64
- KeyID int64
-}
-
-// IsErrGPGKeyAccessDenied checks if an error is a ErrGPGKeyAccessDenied.
-func IsErrGPGKeyAccessDenied(err error) bool {
- _, ok := err.(ErrGPGKeyAccessDenied)
- return ok
-}
-
-// Error pretty-prints an error of type ErrGPGKeyAccessDenied.
-func (err ErrGPGKeyAccessDenied) Error() string {
- return fmt.Sprintf("user does not have access to the key [user_id: %d, key_id: %d]",
- err.UserID, err.KeyID)
-}
-
-func (err ErrGPGKeyAccessDenied) Unwrap() error {
- return util.ErrPermissionDenied
-}
-
// ErrKeyAccessDenied represents a "KeyAccessDenied" kind of error.
type ErrKeyAccessDenied struct {
UserID int64
diff --git a/models/asymkey/gpg_key.go b/models/asymkey/gpg_key.go
index 5236b2d450..b7e10ce85c 100644
--- a/models/asymkey/gpg_key.go
+++ b/models/asymkey/gpg_key.go
@@ -9,12 +9,12 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
- "github.com/keybase/go-crypto/openpgp"
- "github.com/keybase/go-crypto/openpgp/packet"
+ "github.com/ProtonMail/go-crypto/openpgp"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
"xorm.io/builder"
)
@@ -141,7 +141,12 @@ func parseGPGKey(ctx context.Context, ownerID int64, e *openpgp.Entity, verified
// Parse Subkeys
subkeys := make([]*GPGKey, len(e.Subkeys))
for i, k := range e.Subkeys {
- subs, err := parseSubGPGKey(ownerID, pubkey.KeyIdString(), k.PublicKey, expiry)
+ subKeyExpiry := expiry
+ if k.Sig.KeyLifetimeSecs != nil {
+ subKeyExpiry = k.PublicKey.CreationTime.Add(time.Duration(*k.Sig.KeyLifetimeSecs) * time.Second)
+ }
+
+ subs, err := parseSubGPGKey(ownerID, pubkey.KeyIdString(), k.PublicKey, subKeyExpiry)
if err != nil {
return nil, ErrGPGKeyParsing{ParseError: err}
}
@@ -156,7 +161,8 @@ func parseGPGKey(ctx context.Context, ownerID int64, e *openpgp.Entity, verified
emails := make([]*user_model.EmailAddress, 0, len(e.Identities))
for _, ident := range e.Identities {
- if ident.Revocation != nil {
+ // Check if the identity is revoked.
+ if ident.Revoked(time.Now()) {
continue
}
email := strings.ToLower(strings.TrimSpace(ident.UserId.Email))
diff --git a/models/asymkey/gpg_key_add.go b/models/asymkey/gpg_key_add.go
index 11124b1366..06cfd09a3e 100644
--- a/models/asymkey/gpg_key_add.go
+++ b/models/asymkey/gpg_key_add.go
@@ -7,10 +7,10 @@ import (
"context"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
- "github.com/keybase/go-crypto/openpgp"
+ "github.com/ProtonMail/go-crypto/openpgp"
)
// __________________ ________ ____ __.
@@ -83,12 +83,12 @@ func AddGPGKey(ctx context.Context, ownerID int64, content, token, signature str
verified := false
// Handle provided signature
if signature != "" {
- signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(signature))
+ signer, err := openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token), strings.NewReader(signature), nil)
if err != nil {
- signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\n"), strings.NewReader(signature))
+ signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\n"), strings.NewReader(signature), nil)
}
if err != nil {
- signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature))
+ signer, err = openpgp.CheckArmoredDetachedSignature(ekeys, strings.NewReader(token+"\r\n"), strings.NewReader(signature), nil)
}
if err != nil {
log.Error("Unable to validate token signature. Error: %v", err)
diff --git a/models/asymkey/gpg_key_commit_verification.go b/models/asymkey/gpg_key_commit_verification.go
index 9aa606405e..73b066b17c 100644
--- a/models/asymkey/gpg_key_commit_verification.go
+++ b/models/asymkey/gpg_key_commit_verification.go
@@ -6,9 +6,9 @@ package asymkey
import (
"context"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
)
// __________________ ________ ____ __.
diff --git a/models/asymkey/gpg_key_common.go b/models/asymkey/gpg_key_common.go
index 9c015582f1..db1912c316 100644
--- a/models/asymkey/gpg_key_common.go
+++ b/models/asymkey/gpg_key_common.go
@@ -13,9 +13,9 @@ import (
"strings"
"time"
- "github.com/keybase/go-crypto/openpgp"
- "github.com/keybase/go-crypto/openpgp/armor"
- "github.com/keybase/go-crypto/openpgp/packet"
+ "github.com/ProtonMail/go-crypto/openpgp"
+ "github.com/ProtonMail/go-crypto/openpgp/armor"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
)
// __________________ ________ ____ __.
@@ -88,7 +88,7 @@ func getExpiryTime(e *openpgp.Entity) time.Time {
for _, ident := range e.Identities {
if selfSig == nil {
selfSig = ident.SelfSignature
- } else if ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
+ } else if ident.SelfSignature != nil && ident.SelfSignature.IsPrimaryId != nil && *ident.SelfSignature.IsPrimaryId {
selfSig = ident.SelfSignature
break
}
@@ -114,7 +114,7 @@ func readArmoredSign(r io.Reader) (body io.Reader, err error) {
return nil, err
}
if block.Type != openpgp.SignatureType {
- return nil, fmt.Errorf("expected '" + openpgp.SignatureType + "', got: " + block.Type)
+ return nil, fmt.Errorf("expected %q, got: %s", openpgp.SignatureType, block.Type)
}
return block.Body, nil
}
@@ -139,7 +139,7 @@ func tryGetKeyIDFromSignature(sig *packet.Signature) string {
if sig.IssuerKeyId != nil && (*sig.IssuerKeyId) != 0 {
return fmt.Sprintf("%016X", *sig.IssuerKeyId)
}
- if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) > 0 {
+ if len(sig.IssuerFingerprint) > 0 {
return fmt.Sprintf("%016X", sig.IssuerFingerprint[12:20])
}
return ""
diff --git a/models/asymkey/gpg_key_import.go b/models/asymkey/gpg_key_import.go
index c9d46d29e5..8a63ea4a35 100644
--- a/models/asymkey/gpg_key_import.go
+++ b/models/asymkey/gpg_key_import.go
@@ -6,7 +6,7 @@ package asymkey
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
// __________________ ________ ____ __.
diff --git a/models/asymkey/gpg_key_list.go b/models/asymkey/gpg_key_list.go
index 89548e495e..b2d4fb11f6 100644
--- a/models/asymkey/gpg_key_list.go
+++ b/models/asymkey/gpg_key_list.go
@@ -6,7 +6,7 @@ package asymkey
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
type GPGKeyList []*GPGKey
diff --git a/models/asymkey/gpg_key_object_verification.go b/models/asymkey/gpg_key_object_verification.go
index e5c31a74a7..407a29c221 100644
--- a/models/asymkey/gpg_key_object_verification.go
+++ b/models/asymkey/gpg_key_object_verification.go
@@ -10,14 +10,14 @@ import (
"hash"
"strings"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
- "github.com/keybase/go-crypto/openpgp/packet"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
)
// This file provides functions related to object (commit, tag) verification
diff --git a/models/asymkey/gpg_key_tag_verification.go b/models/asymkey/gpg_key_tag_verification.go
index 5fd3983e54..f054525e8f 100644
--- a/models/asymkey/gpg_key_tag_verification.go
+++ b/models/asymkey/gpg_key_tag_verification.go
@@ -6,7 +6,7 @@ package asymkey
import (
"context"
- "code.gitea.io/gitea/modules/git"
+ "forgejo.org/modules/git"
)
func ParseTagWithSignature(ctx context.Context, gitRepo *git.Repository, t *git.Tag) *ObjectVerification {
diff --git a/models/asymkey/gpg_key_test.go b/models/asymkey/gpg_key_test.go
index d3fbb01d82..4db07b84c2 100644
--- a/models/asymkey/gpg_key_test.go
+++ b/models/asymkey/gpg_key_test.go
@@ -7,14 +7,15 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
- "github.com/keybase/go-crypto/openpgp/packet"
+ "github.com/ProtonMail/go-crypto/openpgp/packet"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCheckArmoredGPGKeyString(t *testing.T) {
@@ -50,7 +51,7 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg==
-----END PGP PUBLIC KEY BLOCK-----`
key, err := checkArmoredGPGKeyString(testGPGArmor)
- assert.NoError(t, err, "Could not parse a valid GPG public armored rsa key", key)
+ require.NoError(t, err, "Could not parse a valid GPG public armored rsa key", key)
// TODO verify value of key
}
@@ -71,7 +72,7 @@ OyjLLnFQiVmq7kEA/0z0CQe3ZQiQIq5zrs7Nh1XRkFAo8GlU/SGC9XFFi722
-----END PGP PUBLIC KEY BLOCK-----`
key, err := checkArmoredGPGKeyString(testGPGArmor)
- assert.NoError(t, err, "Could not parse a valid GPG public armored brainpoolP256r1 key", key)
+ require.NoError(t, err, "Could not parse a valid GPG public armored brainpoolP256r1 key", key)
// TODO verify value of key
}
@@ -111,11 +112,11 @@ MkM/fdpyc2hY7Dl/+qFmN5MG5yGmMpQcX+RNNR222ibNC1D3wg==
return
}
ekey := keys[0]
- assert.NoError(t, err, "Could not parse a valid GPG armored key", ekey)
+ require.NoError(t, err, "Could not parse a valid GPG armored key", ekey)
pubkey := ekey.PrimaryKey
content, err := base64EncPubKey(pubkey)
- assert.NoError(t, err, "Could not base64 encode a valid PublicKey content", ekey)
+ require.NoError(t, err, "Could not base64 encode a valid PublicKey content", ekey)
key := &GPGKey{
KeyID: pubkey.KeyIdString(),
@@ -176,27 +177,27 @@ Unknown GPG key with good email
`
// Reading Sign
goodSig, err := extractSignature(testGoodSigArmor)
- assert.NoError(t, err, "Could not parse a valid GPG armored signature", testGoodSigArmor)
+ require.NoError(t, err, "Could not parse a valid GPG armored signature", testGoodSigArmor)
badSig, err := extractSignature(testBadSigArmor)
- assert.NoError(t, err, "Could not parse a valid GPG armored signature", testBadSigArmor)
+ require.NoError(t, err, "Could not parse a valid GPG armored signature", testBadSigArmor)
// Generating hash of commit
goodHash, err := populateHash(goodSig.Hash, []byte(testGoodPayload))
- assert.NoError(t, err, "Could not generate a valid hash of payload", testGoodPayload)
+ require.NoError(t, err, "Could not generate a valid hash of payload", testGoodPayload)
badHash, err := populateHash(badSig.Hash, []byte(testBadPayload))
- assert.NoError(t, err, "Could not generate a valid hash of payload", testBadPayload)
+ require.NoError(t, err, "Could not generate a valid hash of payload", testBadPayload)
// Verify
err = verifySign(goodSig, goodHash, key)
- assert.NoError(t, err, "Could not validate a good signature")
+ require.NoError(t, err, "Could not validate a good signature")
err = verifySign(badSig, badHash, key)
- assert.Error(t, err, "Validate a bad signature")
+ require.Error(t, err, "Validate a bad signature")
err = verifySign(goodSig, goodHash, cannotsignkey)
- assert.Error(t, err, "Validate a bad signature with a kay that can not sign")
+ require.Error(t, err, "Validate a bad signature with a kay that can not sign")
}
func TestCheckGPGUserEmail(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
_ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -232,7 +233,7 @@ Q0KHb+QcycSgbDx0ZAvdIacuKvBBcbxrsmFUI4LR+oIup0G9gUc0roPvr014jYQL
-----END PGP PUBLIC KEY BLOCK-----`
keys, err := AddGPGKey(db.DefaultContext, 1, testEmailWithUpperCaseLetters, "", "")
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.NotEmpty(t, keys) {
key := keys[0]
if assert.Len(t, key.Emails, 1) {
@@ -241,6 +242,66 @@ Q0KHb+QcycSgbDx0ZAvdIacuKvBBcbxrsmFUI4LR+oIup0G9gUc0roPvr014jYQL
}
}
+func TestCheckGPGRevokedIdentity(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ require.NoError(t, db.Insert(db.DefaultContext, &user_model.EmailAddress{UID: 1, Email: "no-reply@golang.com", IsActivated: true}))
+ require.NoError(t, db.Insert(db.DefaultContext, &user_model.EmailAddress{UID: 1, Email: "revoked@golang.com", IsActivated: true}))
+ _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+
+ revokedUserKey := `-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+mQENBFsgO5EBCADhREPmcjsPkXe1z7ctvyWL0S7oa9JaoGZ9oPDHFDlQxd0qlX2e
+DZJZDg0qYvVixmaULIulApq1puEsaJCn3lHUbHlb4PYKwLEywYXM28JN91KtLsz/
+uaEX2KC5WqeP40utmzkNLq+oRX/xnRMgwbO7yUNVG2UlEa6eI+xOXO3YtLdmJMBW
+ClQ066ZnOIzEo1JxnIwha1CDBMWLLfOLrg6l8InUqaXbtEBbnaIYO6fXVXELUjkx
+nmk7t/QOk0tXCy8muH9UDqJkwDUESY2l79XwBAcx9riX8vY7vwC34pm22fAUVLCJ
+x1SJx0J8bkeNp38jKM2Zd9SUQqSbfBopQ4pPABEBAAG0I0dvbGFuZyBHb3BoZXIg
+PG5vLXJlcGx5QGdvbGFuZy5jb20+iQFUBBMBCgA+FiEE5Ik5JLcNx6l6rZfw1oFy
+9I6cUoMFAlsgO5ECGwMFCQPCZwAFCwkIBwMFFQoJCAsFFgIDAQACHgECF4AACgkQ
+1oFy9I6cUoMIkwf8DNPeD23i4jRwd/pylbvxwZintZl1fSwTJW1xcOa1emXaEtX2
+depuqhP04fjlRQGfsYAQh7X9jOJxAHjTmhqFBi5sD7QvKU00cPFYbJ/JTx0B41bl
+aXnSbGhRPh63QtEZL7ACAs+shwvvojJqysx7kyVRu0EW2wqjXdHwR/SJO6nhNBa2
+DXzSiOU/SUA42mmG+5kjF8Aabq9wPwT9wjraHShEweNerNMmOqJExBOy3yFeyDpa
+XwEZFzBfOKoxFNkIaVf5GSdIUGhFECkGvBMB935khftmgR8APxdU4BE7XrXexFJU
+8RCuPXonm4WQOwTWR0vQg64pb2WKAzZ8HhwTGbQiR29sYW5nIEdvcGhlciA8cmV2
+b2tlZEBnb2xhbmcuY29tPokBNgQwAQoAIBYhBOSJOSS3Dcepeq2X8NaBcvSOnFKD
+BQJbIDv3Ah0AAAoJENaBcvSOnFKDfWMIAKhI/Tvu3h8fSUxp/gSAcduT6bC1JttG
+0lYQ5ilKB/58lBUA5CO3ZrKDKlzW3M8VEcvohVaqeTMKeoQd5rCZq8KxHn/KvN6N
+s85REfXfniCKfAbnGgVXX3kDmZ1g63pkxrFu0fDZjVDXC6vy+I0sGyI/Inro0Pzb
+tvn0QCsxjapKK15BtmSrpgHgzVqVg0cUp8vqZeKFxarYbYB2idtGRci4b9tObOK0
+BSTVFy26+I/mrFGaPrySYiy2Kz5NMEcRhjmTxJ8jSwEr2O2sUR0yjbgUAXbTxDVE
+/jg5fQZ1ACvBRQnB7LvMHcInbzjyeTM3FazkkSYQD6b97+dkWwb1iWG5AQ0EWyA7
+kQEIALkg04REDZo1JgdYV4x8HJKFS4xAYWbIva1ZPqvDNmZRUbQZR2+gpJGEwn7z
+VofGvnOYiGW56AS5j31SFf5kro1+1bZQ5iOONBng08OOo58/l1hRseIIVGB5TGSa
+PCdChKKHreJI6hS3mShxH6hdfFtiZuB45rwoaArMMsYcjaezLwKeLc396cpUwwcZ
+snLUNd1Xu5EWEF2OdFkZ2a1qYdxBvAYdQf4+1Nr+NRIx1u1NS9c8jp3PuMOkrQEi
+bNtc1v6v0Jy52mKLG4y7mC/erIkvkQBYJdxPaP7LZVaPYc3/xskcyijrJ/5ufoD8
+K71/ShtsZUXSQn9jlRaYR0EbojMAEQEAAYkBPAQYAQoAJhYhBOSJOSS3Dcepeq2X
+8NaBcvSOnFKDBQJbIDuRAhsMBQkDwmcAAAoJENaBcvSOnFKDkFMIAIt64bVZ8x7+
+TitH1bR4pgcNkaKmgKoZz6FXu80+SnbuEt2NnDyf1cLOSimSTILpwLIuv9Uft5Pb
+OraQbYt3xi9yrqdKqGLv80bxqK0NuryNkvh9yyx5WoG1iKqMj9/FjGghuPrRaT4l
+QinNAghGVkEy1+aXGFrG2DsOC1FFI51CC2WVTzZ5RwR2GpiNRfESsU1rZAUqf/2V
+yJl9bD5R4SUNy8oQmhOxi+gbhD4Ao34e4W0ilibslI/uawvCiOwlu5NGd8zv5n+U
+heiQvzkApQup5c+BhH5zFDFdKJ2CBByxw9+7QjMFI/wgLixKuE0Ob2kAokXf7RlB
+7qTZOahrETw=
+=IKnw
+-----END PGP PUBLIC KEY BLOCK-----
+`
+
+ keys, err := AddGPGKey(db.DefaultContext, 1, revokedUserKey, "", "")
+ require.NoError(t, err)
+ assert.Len(t, keys, 1)
+ assert.Len(t, keys[0].Emails, 1)
+ assert.EqualValues(t, "no-reply@golang.com", keys[0].Emails[0].Email)
+
+ primaryKeyID := "D68172F48E9C5283"
+ // Assert primary key
+ unittest.AssertExistsAndLoadBean(t, &GPGKey{OwnerID: 1, KeyID: primaryKeyID, Content: "xsBNBFsgO5EBCADhREPmcjsPkXe1z7ctvyWL0S7oa9JaoGZ9oPDHFDlQxd0qlX2eDZJZDg0qYvVixmaULIulApq1puEsaJCn3lHUbHlb4PYKwLEywYXM28JN91KtLsz/uaEX2KC5WqeP40utmzkNLq+oRX/xnRMgwbO7yUNVG2UlEa6eI+xOXO3YtLdmJMBWClQ066ZnOIzEo1JxnIwha1CDBMWLLfOLrg6l8InUqaXbtEBbnaIYO6fXVXELUjkxnmk7t/QOk0tXCy8muH9UDqJkwDUESY2l79XwBAcx9riX8vY7vwC34pm22fAUVLCJx1SJx0J8bkeNp38jKM2Zd9SUQqSbfBopQ4pPABEBAAE="})
+ // Assert subkey
+ unittest.AssertExistsAndLoadBean(t, &GPGKey{OwnerID: 1, KeyID: "2C56900BE5486AF8", PrimaryKeyID: primaryKeyID, Content: "zsBNBFsgO5EBCAC5INOERA2aNSYHWFeMfByShUuMQGFmyL2tWT6rwzZmUVG0GUdvoKSRhMJ+81aHxr5zmIhluegEuY99UhX+ZK6NftW2UOYjjjQZ4NPDjqOfP5dYUbHiCFRgeUxkmjwnQoSih63iSOoUt5kocR+oXXxbYmbgeOa8KGgKzDLGHI2nsy8Cni3N/enKVMMHGbJy1DXdV7uRFhBdjnRZGdmtamHcQbwGHUH+PtTa/jUSMdbtTUvXPI6dz7jDpK0BImzbXNb+r9CcudpiixuMu5gv3qyJL5EAWCXcT2j+y2VWj2HN/8bJHMoo6yf+bn6A/Cu9f0obbGVF0kJ/Y5UWmEdBG6IzABEBAAE="})
+}
+
func TestCheckGParseGPGExpire(t *testing.T) {
testIssue6599 := `-----BEGIN PGP PUBLIC KEY BLOCK-----
@@ -386,7 +447,7 @@ epiDVQ==
-----END PGP PUBLIC KEY BLOCK-----
`
keys, err := checkArmoredGPGKeyString(testIssue6599)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.NotEmpty(t, keys) {
ekey := keys[0]
expire := getExpiryTime(ekey)
diff --git a/models/asymkey/gpg_key_verify.go b/models/asymkey/gpg_key_verify.go
index 01812a2d54..2b5ea7a1ac 100644
--- a/models/asymkey/gpg_key_verify.go
+++ b/models/asymkey/gpg_key_verify.go
@@ -8,10 +8,10 @@ import (
"strconv"
"time"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
)
// __________________ ________ ____ __.
diff --git a/models/asymkey/main_test.go b/models/asymkey/main_test.go
index 87b5c22c4a..316e8f1d54 100644
--- a/models/asymkey/main_test.go
+++ b/models/asymkey/main_test.go
@@ -6,7 +6,7 @@ package asymkey
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/models/asymkey/ssh_key.go b/models/asymkey/ssh_key.go
index a409d8e841..7f76009e7f 100644
--- a/models/asymkey/ssh_key.go
+++ b/models/asymkey/ssh_key.go
@@ -10,13 +10,13 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"golang.org/x/crypto/ssh"
"xorm.io/builder"
@@ -229,35 +229,26 @@ func UpdatePublicKeyUpdated(ctx context.Context, id int64) error {
// PublicKeysAreExternallyManaged returns whether the provided KeyID represents an externally managed Key
func PublicKeysAreExternallyManaged(ctx context.Context, keys []*PublicKey) ([]bool, error) {
- sources := make([]*auth.Source, 0, 5)
+ sourceCache := make(map[int64]*auth.Source, len(keys))
externals := make([]bool, len(keys))
-keyloop:
+
for i, key := range keys {
if key.LoginSourceID == 0 {
externals[i] = false
- continue keyloop
+ continue
}
- var source *auth.Source
-
- sourceloop:
- for _, s := range sources {
- if s.ID == key.LoginSourceID {
- source = s
- break sourceloop
- }
- }
-
- if source == nil {
+ source, ok := sourceCache[key.LoginSourceID]
+ if !ok {
var err error
source, err = auth.GetSourceByID(ctx, key.LoginSourceID)
if err != nil {
if auth.IsErrSourceNotExist(err) {
externals[i] = false
- sources[i] = &auth.Source{
+ sourceCache[key.LoginSourceID] = &auth.Source{
ID: key.LoginSourceID,
}
- continue keyloop
+ continue
}
return nil, err
}
diff --git a/models/asymkey/ssh_key_authorized_keys.go b/models/asymkey/ssh_key_authorized_keys.go
index d3f9f3f3be..d3bf6fe886 100644
--- a/models/asymkey/ssh_key_authorized_keys.go
+++ b/models/asymkey/ssh_key_authorized_keys.go
@@ -14,10 +14,10 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
// _____ __ .__ .__ .___
@@ -87,19 +87,16 @@ func appendAuthorizedKeysToFile(keys ...*PublicKey) error {
}
defer f.Close()
- // Note: chmod command does not support in Windows.
- if !setting.IsWindows {
- fi, err := f.Stat()
- if err != nil {
- return err
- }
+ fi, err := f.Stat()
+ if err != nil {
+ return err
+ }
- // .ssh directory should have mode 700, and authorized_keys file should have mode 600.
- if fi.Mode().Perm() > 0o600 {
- log.Error("authorized_keys file has unusual permission flags: %s - setting to -rw-------", fi.Mode().Perm().String())
- if err = f.Chmod(0o600); err != nil {
- return err
- }
+ // .ssh directory should have mode 700, and authorized_keys file should have mode 600.
+ if fi.Mode().Perm() > 0o600 {
+ log.Error("authorized_keys file has unusual permission flags: %s - setting to -rw-------", fi.Mode().Perm().String())
+ if err = f.Chmod(0o600); err != nil {
+ return err
}
}
diff --git a/models/asymkey/ssh_key_authorized_principals.go b/models/asymkey/ssh_key_authorized_principals.go
index f85de12aae..0b4fe13ba7 100644
--- a/models/asymkey/ssh_key_authorized_principals.go
+++ b/models/asymkey/ssh_key_authorized_principals.go
@@ -13,10 +13,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
// _____ __ .__ .__ .___
diff --git a/models/asymkey/ssh_key_deploy.go b/models/asymkey/ssh_key_deploy.go
index 923c5020ed..22e80840af 100644
--- a/models/asymkey/ssh_key_deploy.go
+++ b/models/asymkey/ssh_key_deploy.go
@@ -8,9 +8,9 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
)
@@ -105,14 +105,6 @@ func addDeployKey(ctx context.Context, keyID, repoID int64, name, fingerprint st
return key, db.Insert(ctx, key)
}
-// HasDeployKey returns true if public key is a deploy key of given repository.
-func HasDeployKey(ctx context.Context, keyID, repoID int64) bool {
- has, _ := db.GetEngine(ctx).
- Where("key_id = ? AND repo_id = ?", keyID, repoID).
- Get(new(DeployKey))
- return has
-}
-
// AddDeployKey add new deploy key to database and authorized_keys file.
func AddDeployKey(ctx context.Context, repoID int64, name, content string, readOnly bool) (*DeployKey, error) {
fingerprint, err := CalcFingerprint(content)
diff --git a/models/asymkey/ssh_key_fingerprint.go b/models/asymkey/ssh_key_fingerprint.go
index 1ed3b5df2a..11112e4bc3 100644
--- a/models/asymkey/ssh_key_fingerprint.go
+++ b/models/asymkey/ssh_key_fingerprint.go
@@ -8,11 +8,11 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"golang.org/x/crypto/ssh"
"xorm.io/builder"
diff --git a/models/asymkey/ssh_key_object_verification.go b/models/asymkey/ssh_key_object_verification.go
index 5ad6fdb0a9..e0476fe5a8 100644
--- a/models/asymkey/ssh_key_object_verification.go
+++ b/models/asymkey/ssh_key_object_verification.go
@@ -9,9 +9,9 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
"github.com/42wim/sshsig"
)
diff --git a/models/asymkey/ssh_key_object_verification_test.go b/models/asymkey/ssh_key_object_verification_test.go
index 4e229c9b13..5d1b7edc27 100644
--- a/models/asymkey/ssh_key_object_verification_test.go
+++ b/models/asymkey/ssh_key_object_verification_test.go
@@ -6,18 +6,19 @@ package asymkey
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestParseCommitWithSSHSignature(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
sshKey := unittest.AssertExistsAndLoadBean(t, &PublicKey{ID: 1000, OwnerID: 2})
diff --git a/models/asymkey/ssh_key_parse.go b/models/asymkey/ssh_key_parse.go
index 94b1cf112b..305e464b4b 100644
--- a/models/asymkey/ssh_key_parse.go
+++ b/models/asymkey/ssh_key_parse.go
@@ -16,10 +16,10 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"golang.org/x/crypto/ssh"
)
@@ -219,8 +219,13 @@ func SSHNativeParsePublicKey(keyLine string) (string, int, error) {
return "", 0, fmt.Errorf("ParsePublicKey: %w", err)
}
+ pkeyType := pkey.Type()
+ if certPkey, ok := pkey.(*ssh.Certificate); ok {
+ pkeyType = certPkey.Key.Type()
+ }
+
// The ssh library can parse the key, so next we find out what key exactly we have.
- switch pkey.Type() {
+ switch pkeyType {
case ssh.KeyAlgoDSA:
rawPub := struct {
Name string
diff --git a/models/asymkey/ssh_key_principals.go b/models/asymkey/ssh_key_principals.go
index 4e7dee2c91..ba2a1a8c7d 100644
--- a/models/asymkey/ssh_key_principals.go
+++ b/models/asymkey/ssh_key_principals.go
@@ -8,11 +8,11 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
// AddPrincipalKey adds new principal to database and authorized_principals file.
diff --git a/models/asymkey/ssh_key_test.go b/models/asymkey/ssh_key_test.go
index d3e886b97f..f3c3e41955 100644
--- a/models/asymkey/ssh_key_test.go
+++ b/models/asymkey/ssh_key_test.go
@@ -12,10 +12,13 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
"github.com/42wim/sshsig"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_SSHParsePublicKey(t *testing.T) {
@@ -26,20 +29,20 @@ func Test_SSHParsePublicKey(t *testing.T) {
length int
content string
}{
- {"dsa-1024", false, "dsa", 1024, "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment"},
{"rsa-1024", false, "rsa", 1024, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAu7tvIvX6ZHrRXuZNfkR3XLHSsuCK9Zn3X58lxBcQzuo5xZgB6vRwwm/QtJuF+zZPtY5hsQILBLmF+BZ5WpKZp1jBeSjH2G7lxet9kbcH+kIVj0tPFEoyKI9wvWqIwC4prx/WVk2wLTJjzBAhyNxfEq7C9CeiX9pQEbEqJfkKCQ== nocomment\n"},
{"rsa-2048", false, "rsa", 2048, "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMZXh+1OBUwSH9D45wTaxErQIN9IoC9xl7MKJkqvTvv6O5RR9YW/IK9FbfjXgXsppYGhsCZo1hFOOsXHMnfOORqu/xMDx4yPuyvKpw4LePEcg4TDipaDFuxbWOqc/BUZRZcXu41QAWfDLrInwsltWZHSeG7hjhpacl4FrVv9V1pS6Oc5Q1NxxEzTzuNLS/8diZrTm/YAQQ/+B+mzWI3zEtF4miZjjAljWd1LTBPvU23d29DcBmmFahcZ441XZsTeAwGxG/Q6j8NgNXj9WxMeWwxXV2jeAX/EBSpZrCVlCQ1yJswT6xCp8TuBnTiGWYMBNTbOZvPC4e0WI2/yZW/s5F nocomment"},
{"ecdsa-256", false, "ecdsa", 256, "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFQacN3PrOll7PXmN5B/ZNVahiUIqI05nbBlZk1KXsO3d06ktAWqbNflv2vEmA38bTFTfJ2sbn2B5ksT52cDDbA= nocomment"},
{"ecdsa-384", false, "ecdsa", 384, "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBINmioV+XRX1Fm9Qk2ehHXJ2tfVxW30ypUWZw670Zyq5GQfBAH6xjygRsJ5wWsHXBsGYgFUXIHvMKVAG1tpw7s6ax9oA+dJOJ7tj+vhn8joFqT+sg3LYHgZkHrfqryRasQ== nocomment"},
{"ecdsa-sk", true, "ecdsa-sk", 256, "sk-ecdsa-sha2-nistp256@openssh.com AAAAInNrLWVjZHNhLXNoYTItbmlzdHAyNTZAb3BlbnNzaC5jb20AAAAIbmlzdHAyNTYAAABBBGXEEzWmm1dxb+57RoK5KVCL0w2eNv9cqJX2AGGVlkFsVDhOXHzsadS3LTK4VlEbbrDMJdoti9yM8vclA8IeRacAAAAEc3NoOg== nocomment"},
{"ed25519-sk", true, "ed25519-sk", 256, "sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIE7kM1R02+4ertDKGKEDcKG0s+2vyDDcIvceJ0Gqv5f1AAAABHNzaDo= nocomment"},
+ {"ed25519-cert-v01", true, "ed25519", 256, "ssh-ed25519-cert-v01@openssh.com AAAAIHNzaC1lZDI1NTE5LWNlcnQtdjAxQG9wZW5zc2guY29tAAAAIAlIAPlEj0mYQzQo8Ks0Nm/Ct8ceNkyJSf4DLuF5l7+5AAAAIEuWAoaBo2tT29/oMNnoDfdAPRCIdM2RGapKUhY4nDfLRgPQwfnRoc0AAAABAAAAcHZhdWx0LW9pZGMtNmRhYjdiZDgtNDg5YS00MDFkLTg3ZmItNjdjNTlhMDZkZDkxLTNjNTk2M2YyMGRmMDM3MDkyMzc1YmNiYmNiNzkxY2EyZWIxM2I0NGZhMzc2NTcwMWI0MjMwODU0MWFmNjhkNTgAAAALAAAAB2Zvcmdlam8AAAAAZ6/RUQAAAABn115vAAAAAAAAAAAAAAAAAAACFwAAAAdzc2gtcnNhAAAAAwEAAQAAAgEAySnM/TvD117GyKgOgMatDB2t+fCHORFaWVmH5SaadAzNJ2DfDAauRSLfnim1xdgAOMTzsPEEHH47zyYMjE85o2AiJxrfUBMw3O/7AbNc6+HyLr/txH4+vD9tWQknKnpVWM+3Z9wiHDcOdKRoXCmFZKJH1vxs16GNWjwbrfNiimv7Oi0fadgvTDKX603gpLTuVDXqs9eQFLCONptei86JYBAJqaHvg51k8YUCKt9WFqKAj7BJUWmrDvhv5VFMOsnZieJjqxkoxnpsQNlXfPzxK0vIpJofbYfWwscv/g9WZypHwO1ZR2PqzKm99YrSdr8w5256l0f44vsF0NSP0N7bDQEfYYnRGj8zWTYCBFD+uYF7AxIeaRUpZoTQO8MvCHOLMIDinNgEeCUvNA2v9zHl4BGq+PQjzUKAgJiKj0MZeiCDAmQ22g83ggQlB6BOrBb1fNa/S1cmTbGHQ2oAN358aqkmHVCBhPOyA2Rf65D2M2vzDlUdOsNDUIWAHk7GbwSNGDgcYfTWqtR5fTzp2MJovMh1dDUDXjOvojbhzjJtSy9+rzUYIv18aXdOitzVBgPMWdeVCZFZv4OKF+5MiqxQvedUvfiSjsdxZWLxyT1CJ88G3MzxNMS/Djm86T8h/Oa55bdvFtqpsLfvpIqq0pnXq1V/vF2j1MWwRB5z5Xh/HtEAAAIUAAAADHJzYS1zaGEyLTI1NgAAAgB2I2gzqemQl8/ETxtakALlm/2BpUcbhADcFWuoH6BCPnWHuTSwf3OayM6KXv1PQfL3YFRoi9Afrp8kVFL6DePsmKH+0BUEMz71sZ7v1ty7pwfzibItGnpTbQXhzbEiNYAFoz77rl7oaXF7pV6JNZhj3DVAB5gVA2oN5KRNVxijz+6uyuFJEw1HIl1C7GworvGwZcN7BThTEh3i72/Vntejy9Z8uGVjSFjS0rjRo2oXK1LKN0rVt66p3TmCWHouLkVnOTk0qrhLGlL2HVyo24OYHbkAAObD9b6aMDYlmluk6NsaiTKsSTsvMrbIbjtFQlh7nNyoPhZ0VMwaT1l10pDQ5uxWWZjKGIkz4xM1ZfpBszjJNPo+ivYQnTSjj9LwkbLAT9a/5LawSj80TGcLEMO+0eyPdJsP0wYmOVRFAZeRiBgwb3HrzcF6Wqr8icj1EjYkKSy9YFHGTnFBGknpdh3HGwghRXrCUwAnSM76db9pv4/qowT8LthtJ3dY5Epe0OJ1Tqm+q8bkGH4gB+7uqLSqM5pIHSKLp7lfHQBt1J6xa7H2saiweaWjU+QGTgQ2Lg+uUC5DXJrmm60CeFJ4BoGhUenDlgijbQpjH/l6330PbwefgjWtUK/pqaEA4lCoPyvJ+eF2DbYfPiAIBAFQnhVJJae4AH+XoCt29nb2j30ztg== nocomment"},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
t.Run("Native", func(t *testing.T) {
keyTypeN, lengthN, err := SSHNativeParsePublicKey(tc.content)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, tc.keyType, keyTypeN)
assert.EqualValues(t, tc.length, lengthN)
})
@@ -75,7 +78,6 @@ func Test_CheckPublicKeyString(t *testing.T) {
for _, test := range []struct {
content string
}{
- {"ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment"},
{"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAu7tvIvX6ZHrRXuZNfkR3XLHSsuCK9Zn3X58lxBcQzuo5xZgB6vRwwm/QtJuF+zZPtY5hsQILBLmF+BZ5WpKZp1jBeSjH2G7lxet9kbcH+kIVj0tPFEoyKI9wvWqIwC4prx/WVk2wLTJjzBAhyNxfEq7C9CeiX9pQEbEqJfkKCQ== nocomment\n"},
{"ssh-rsa AAAAB3NzaC1yc2EA\r\nAAADAQABAAAAgQDAu7tvIvX6ZHrRXuZNfkR3XLHSsuCK9Zn3X58lxBcQzuo5xZgB6vRwwm/QtJuF+zZPtY5hsQILBLmF+\r\nBZ5WpKZp1jBeSjH2G7lxet9kbcH+kIVj0tPFEoyKI9wvWqIwC4prx/WVk2wLTJjzBAhyNx\r\nfEq7C9CeiX9pQEbEqJfkKCQ== nocomment\r\n\r\n"},
{"ssh-rsa AAAAB3NzaC1yc2EA\r\nAAADAQABAAAAgQDAu7tvI\nvX6ZHrRXuZNfkR3XLHSsuCK9Zn3X58lxBcQzuo5xZgB6vRwwm/QtJuF+zZPtY5hsQILBLmF+\r\nBZ5WpKZp1jBeSjH2G7lxet9kbcH+kIVj0tPFEoyKI9wvW\nqIwC4prx/WVk2wLTJjzBAhyNx\r\nfEq7C9CeiX9pQEbEqJfkKCQ== nocomment\r\n\r\n"},
@@ -146,7 +148,7 @@ AAAAC3NzaC1lZDI1NTE5AAAAICV0MGX/W9IvLA4FXpIuUcdDcbj5KX4syHgsTy7soVgf
`},
} {
_, err := CheckPublicKeyString(test.content)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
setting.SSH.MinimumKeySizeCheck = oldValue
for _, invalidKeys := range []struct {
@@ -159,7 +161,7 @@ AAAAC3NzaC1lZDI1NTE5AAAAICV0MGX/W9IvLA4FXpIuUcdDcbj5KX4syHgsTy7soVgf
{"\r\ntest \r\ngitea\r\n\r\n"},
} {
_, err := CheckPublicKeyString(invalidKeys.content)
- assert.Error(t, err)
+ require.Error(t, err)
}
}
@@ -170,7 +172,6 @@ func Test_calcFingerprint(t *testing.T) {
fp string
content string
}{
- {"dsa-1024", false, "SHA256:fSIHQlpKMDsGPVAXI8BPYfRp+e2sfvSt1sMrPsFiXrc", "ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ibZ2OkQ3S0SqDIa0HXSEJ1zaExQdmbO+Ux/wsytWZmCczWOVsaszBZSl90q8UnWlSH6P+/YA+RWJm5SFtuV9PtGIhyZgoNuz5kBQ7K139wuQsecdKktISwTakzAAAAFQCzKsO2JhNKlL+wwwLGOcLffoAmkwAAAIBpK7/3xvduajLBD/9vASqBQIHrgK2J+wiQnIb/Wzy0UsVmvfn8A+udRbBo+csM8xrSnlnlJnjkJS3qiM5g+eTwsLIV1IdKPEwmwB+VcP53Cw6lSyWyJcvhFb0N6s08NZysLzvj0N+ZC/FnhKTLzIyMtkHf/IrPCwlM+pV/M/96YgAAAIEAqQcGn9CKgzgPaguIZooTAOQdvBLMI5y0bQjOW6734XOpqQGf/Kra90wpoasLKZjSYKNPjE+FRUOrStLrxcNs4BeVKhy2PYTRnybfYVk1/dmKgH6P1YSRONsGKvTsH6c5IyCRG0ncCgYeF8tXppyd642982daopE7zQ/NPAnJfag= nocomment"},
{"rsa-1024", false, "SHA256:vSnDkvRh/xM6kMxPidLgrUhq3mCN7CDaronCEm2joyQ", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDAu7tvIvX6ZHrRXuZNfkR3XLHSsuCK9Zn3X58lxBcQzuo5xZgB6vRwwm/QtJuF+zZPtY5hsQILBLmF+BZ5WpKZp1jBeSjH2G7lxet9kbcH+kIVj0tPFEoyKI9wvWqIwC4prx/WVk2wLTJjzBAhyNxfEq7C9CeiX9pQEbEqJfkKCQ== nocomment\n"},
{"rsa-2048", false, "SHA256:ZHD//a1b9VuTq9XSunAeYjKeU1xDa2tBFZYrFr2Okkg", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMZXh+1OBUwSH9D45wTaxErQIN9IoC9xl7MKJkqvTvv6O5RR9YW/IK9FbfjXgXsppYGhsCZo1hFOOsXHMnfOORqu/xMDx4yPuyvKpw4LePEcg4TDipaDFuxbWOqc/BUZRZcXu41QAWfDLrInwsltWZHSeG7hjhpacl4FrVv9V1pS6Oc5Q1NxxEzTzuNLS/8diZrTm/YAQQ/+B+mzWI3zEtF4miZjjAljWd1LTBPvU23d29DcBmmFahcZ441XZsTeAwGxG/Q6j8NgNXj9WxMeWwxXV2jeAX/EBSpZrCVlCQ1yJswT6xCp8TuBnTiGWYMBNTbOZvPC4e0WI2/yZW/s5F nocomment"},
{"ecdsa-256", false, "SHA256:Bqx/xgWqRKLtkZ0Lr4iZpgb+5lYsFpSwXwVZbPwuTRw", "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBFQacN3PrOll7PXmN5B/ZNVahiUIqI05nbBlZk1KXsO3d06ktAWqbNflv2vEmA38bTFTfJ2sbn2B5ksT52cDDbA= nocomment"},
@@ -183,7 +184,7 @@ func Test_calcFingerprint(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
t.Run("Native", func(t *testing.T) {
fpN, err := calcFingerprintNative(tc.content)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, tc.fp, fpN)
})
if tc.skipSSHKeygen {
@@ -191,7 +192,7 @@ func Test_calcFingerprint(t *testing.T) {
}
t.Run("SSHKeygen", func(t *testing.T) {
fpK, err := calcFingerprintSSHKeygen(tc.content)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, tc.fp, fpK)
})
})
@@ -503,3 +504,11 @@ func runErr(t *testing.T, stdin []byte, args ...string) {
t.Fatal("expected error")
}
}
+
+func Test_PublicKeysAreExternallyManaged(t *testing.T) {
+ key1 := unittest.AssertExistsAndLoadBean(t, &PublicKey{ID: 1})
+ externals, err := PublicKeysAreExternallyManaged(db.DefaultContext, []*PublicKey{key1})
+ require.NoError(t, err)
+ assert.Len(t, externals, 1)
+ assert.False(t, externals[0])
+}
diff --git a/models/asymkey/ssh_key_verify.go b/models/asymkey/ssh_key_verify.go
index 208288c77b..5dd26ccc9a 100644
--- a/models/asymkey/ssh_key_verify.go
+++ b/models/asymkey/ssh_key_verify.go
@@ -7,8 +7,8 @@ import (
"bytes"
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
"github.com/42wim/sshsig"
)
diff --git a/models/auth/TestOrphanedOAuth2Applications/oauth2_application.yaml b/models/auth/TestOrphanedOAuth2Applications/oauth2_application.yaml
index b188770a30..cccb404ab1 100644
--- a/models/auth/TestOrphanedOAuth2Applications/oauth2_application.yaml
+++ b/models/auth/TestOrphanedOAuth2Applications/oauth2_application.yaml
@@ -23,3 +23,11 @@
redirect_uris: '["http://127.0.0.1", "https://127.0.0.1"]'
created_unix: 1712358091
updated_unix: 1712358091
+-
+ id: 1003
+ uid: 0
+ name: "Global Auth source that should be kept"
+ client_id: "2f3467c1-7b3b-463d-ab04-2ae2b2712826"
+ redirect_uris: '["http://example.com/globalapp", "https://example.com/globalapp"]'
+ created_unix: 1732387292
+ updated_unix: 1732387292
diff --git a/models/auth/access_token.go b/models/auth/access_token.go
index 63331b4841..31d88c6b20 100644
--- a/models/auth/access_token.go
+++ b/models/auth/access_token.go
@@ -11,10 +11,10 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
lru "github.com/hashicorp/golang-lru/v2"
"xorm.io/builder"
@@ -98,6 +98,15 @@ func init() {
// NewAccessToken creates new access token.
func NewAccessToken(ctx context.Context, t *AccessToken) error {
+ err := generateAccessToken(t)
+ if err != nil {
+ return err
+ }
+ _, err = db.GetEngine(ctx).Insert(t)
+ return err
+}
+
+func generateAccessToken(t *AccessToken) error {
salt, err := util.CryptoRandomString(10)
if err != nil {
return err
@@ -110,8 +119,7 @@ func NewAccessToken(ctx context.Context, t *AccessToken) error {
t.Token = hex.EncodeToString(token)
t.TokenHash = HashToken(t.Token, t.TokenSalt)
t.TokenLastEight = t.Token[len(t.Token)-8:]
- _, err = db.GetEngine(ctx).Insert(t)
- return err
+ return nil
}
// DisplayPublicOnly whether to display this as a public-only token.
@@ -234,3 +242,25 @@ func DeleteAccessTokenByID(ctx context.Context, id, userID int64) error {
}
return nil
}
+
+// RegenerateAccessTokenByID regenerates access token by given ID.
+// It regenerates token and salt, as well as updates the creation time.
+func RegenerateAccessTokenByID(ctx context.Context, id, userID int64) (*AccessToken, error) {
+ t := &AccessToken{}
+ found, err := db.GetEngine(ctx).Where("id = ? AND uid = ?", id, userID).Get(t)
+ if err != nil {
+ return nil, err
+ } else if !found {
+ return nil, ErrAccessTokenNotExist{}
+ }
+
+ err = generateAccessToken(t)
+ if err != nil {
+ return nil, err
+ }
+
+ // Reset the creation time, token is unused
+ t.UpdatedUnix = timeutil.TimeStampNow()
+
+ return t, UpdateAccessToken(ctx, t)
+}
diff --git a/models/auth/access_token_scope.go b/models/auth/access_token_scope.go
index 003ca5c9ab..802ad5aa07 100644
--- a/models/auth/access_token_scope.go
+++ b/models/auth/access_token_scope.go
@@ -7,7 +7,7 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/perm"
+ "forgejo.org/models/perm"
)
// AccessTokenScopeCategory represents the scope category for an access token
diff --git a/models/auth/access_token_test.go b/models/auth/access_token_test.go
index 4360f1a214..913118433c 100644
--- a/models/auth/access_token_test.go
+++ b/models/auth/access_token_test.go
@@ -6,20 +6,21 @@ package auth_test
import (
"testing"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestNewAccessToken(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
token := &auth_model.AccessToken{
UID: 3,
Name: "Token C",
}
- assert.NoError(t, auth_model.NewAccessToken(db.DefaultContext, token))
+ require.NoError(t, auth_model.NewAccessToken(db.DefaultContext, token))
unittest.AssertExistsAndLoadBean(t, token)
invalidToken := &auth_model.AccessToken{
@@ -27,13 +28,13 @@ func TestNewAccessToken(t *testing.T) {
UID: 2,
Name: "Token F",
}
- assert.Error(t, auth_model.NewAccessToken(db.DefaultContext, invalidToken))
+ require.Error(t, auth_model.NewAccessToken(db.DefaultContext, invalidToken))
}
func TestAccessTokenByNameExists(t *testing.T) {
name := "Token Gitea"
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
token := &auth_model.AccessToken{
UID: 3,
Name: name,
@@ -41,16 +42,16 @@ func TestAccessTokenByNameExists(t *testing.T) {
// Check to make sure it doesn't exists already
exist, err := auth_model.AccessTokenByNameExists(db.DefaultContext, token)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, exist)
// Save it to the database
- assert.NoError(t, auth_model.NewAccessToken(db.DefaultContext, token))
+ require.NoError(t, auth_model.NewAccessToken(db.DefaultContext, token))
unittest.AssertExistsAndLoadBean(t, token)
// This token must be found by name in the DB now
exist, err = auth_model.AccessTokenByNameExists(db.DefaultContext, token)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
user4Token := &auth_model.AccessToken{
@@ -61,32 +62,32 @@ func TestAccessTokenByNameExists(t *testing.T) {
// Name matches but different user ID, this shouldn't exists in the
// database
exist, err = auth_model.AccessTokenByNameExists(db.DefaultContext, user4Token)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, exist)
}
func TestGetAccessTokenBySHA(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
token, err := auth_model.GetAccessTokenBySHA(db.DefaultContext, "d2c6c1ba3890b309189a8e618c72a162e4efbf36")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), token.UID)
assert.Equal(t, "Token A", token.Name)
assert.Equal(t, "2b3668e11cb82d3af8c6e4524fc7841297668f5008d1626f0ad3417e9fa39af84c268248b78c481daa7e5dc437784003494f", token.TokenHash)
assert.Equal(t, "e4efbf36", token.TokenLastEight)
_, err = auth_model.GetAccessTokenBySHA(db.DefaultContext, "notahash")
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, auth_model.IsErrAccessTokenNotExist(err))
_, err = auth_model.GetAccessTokenBySHA(db.DefaultContext, "")
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, auth_model.IsErrAccessTokenEmpty(err))
}
func TestListAccessTokens(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
tokens, err := db.Find[auth_model.AccessToken](db.DefaultContext, auth_model.ListAccessTokensOptions{UserID: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, tokens, 2) {
assert.Equal(t, int64(1), tokens[0].UID)
assert.Equal(t, int64(1), tokens[1].UID)
@@ -95,38 +96,63 @@ func TestListAccessTokens(t *testing.T) {
}
tokens, err = db.Find[auth_model.AccessToken](db.DefaultContext, auth_model.ListAccessTokensOptions{UserID: 2})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, tokens, 1) {
assert.Equal(t, int64(2), tokens[0].UID)
assert.Equal(t, "Token A", tokens[0].Name)
}
tokens, err = db.Find[auth_model.AccessToken](db.DefaultContext, auth_model.ListAccessTokensOptions{UserID: 100})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, tokens)
}
func TestUpdateAccessToken(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
token, err := auth_model.GetAccessTokenBySHA(db.DefaultContext, "4c6f36e6cf498e2a448662f915d932c09c5a146c")
- assert.NoError(t, err)
+ require.NoError(t, err)
token.Name = "Token Z"
- assert.NoError(t, auth_model.UpdateAccessToken(db.DefaultContext, token))
+ require.NoError(t, auth_model.UpdateAccessToken(db.DefaultContext, token))
unittest.AssertExistsAndLoadBean(t, token)
}
func TestDeleteAccessTokenByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
token, err := auth_model.GetAccessTokenBySHA(db.DefaultContext, "4c6f36e6cf498e2a448662f915d932c09c5a146c")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), token.UID)
- assert.NoError(t, auth_model.DeleteAccessTokenByID(db.DefaultContext, token.ID, 1))
+ require.NoError(t, auth_model.DeleteAccessTokenByID(db.DefaultContext, token.ID, 1))
unittest.AssertNotExistsBean(t, token)
err = auth_model.DeleteAccessTokenByID(db.DefaultContext, 100, 100)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, auth_model.IsErrAccessTokenNotExist(err))
}
+
+func TestRegenerateAccessTokenByID(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ token, err := auth_model.GetAccessTokenBySHA(db.DefaultContext, "4c6f36e6cf498e2a448662f915d932c09c5a146c")
+ require.NoError(t, err)
+
+ newToken, err := auth_model.RegenerateAccessTokenByID(db.DefaultContext, token.ID, 1)
+ require.NoError(t, err)
+ unittest.AssertNotExistsBean(t, &auth_model.AccessToken{ID: token.ID, UID: token.UID, TokenHash: token.TokenHash})
+ newToken = &auth_model.AccessToken{
+ ID: newToken.ID,
+ UID: newToken.UID,
+ TokenHash: newToken.TokenHash,
+ }
+ unittest.AssertExistsAndLoadBean(t, newToken)
+
+ // Token has been recreated, new salt and hash, but should retain the same ID, UID, Name and Scope
+ assert.Equal(t, token.ID, newToken.ID)
+ assert.NotEqual(t, token.TokenHash, newToken.TokenHash)
+ assert.NotEqual(t, token.TokenSalt, newToken.TokenSalt)
+ assert.Equal(t, token.UID, newToken.UID)
+ assert.Equal(t, token.Name, newToken.Name)
+ assert.Equal(t, token.Scope, newToken.Scope)
+}
diff --git a/models/auth/auth_token.go b/models/auth/auth_token.go
index 2c3ca90734..a3ac9c4c1a 100644
--- a/models/auth/auth_token.go
+++ b/models/auth/auth_token.go
@@ -10,17 +10,36 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
)
+type AuthorizationPurpose string
+
+var (
+ // Used to store long term authorization tokens.
+ LongTermAuthorization AuthorizationPurpose = "long_term_authorization"
+
+ // Used to activate a user account.
+ UserActivation AuthorizationPurpose = "user_activation"
+
+ // Used to reset the password.
+ PasswordReset AuthorizationPurpose = "password_reset"
+)
+
+// Used to activate the specified email address for a user.
+func EmailActivation(email string) AuthorizationPurpose {
+ return AuthorizationPurpose("email_activation:" + email)
+}
+
// AuthorizationToken represents a authorization token to a user.
type AuthorizationToken struct {
ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"INDEX"`
LookupKey string `xorm:"INDEX UNIQUE"`
HashedValidator string
+ Purpose AuthorizationPurpose `xorm:"NOT NULL DEFAULT 'long_term_authorization'"`
Expiry timeutil.TimeStamp
}
@@ -41,7 +60,7 @@ func (authToken *AuthorizationToken) IsExpired() bool {
// GenerateAuthToken generates a new authentication token for the given user.
// It returns the lookup key and validator values that should be passed to the
// user via a long-term cookie.
-func GenerateAuthToken(ctx context.Context, userID int64, expiry timeutil.TimeStamp) (lookupKey, validator string, err error) {
+func GenerateAuthToken(ctx context.Context, userID int64, expiry timeutil.TimeStamp, purpose AuthorizationPurpose) (lookupKey, validator string, err error) {
// Request 64 random bytes. The first 32 bytes will be used for the lookupKey
// and the other 32 bytes will be used for the validator.
rBytes, err := util.CryptoRandomBytes(64)
@@ -56,14 +75,15 @@ func GenerateAuthToken(ctx context.Context, userID int64, expiry timeutil.TimeSt
Expiry: expiry,
LookupKey: lookupKey,
HashedValidator: HashValidator(rBytes[32:]),
+ Purpose: purpose,
})
return lookupKey, validator, err
}
// FindAuthToken will find a authorization token via the lookup key.
-func FindAuthToken(ctx context.Context, lookupKey string) (*AuthorizationToken, error) {
+func FindAuthToken(ctx context.Context, lookupKey string, purpose AuthorizationPurpose) (*AuthorizationToken, error) {
var authToken AuthorizationToken
- has, err := db.GetEngine(ctx).Where("lookup_key = ?", lookupKey).Get(&authToken)
+ has, err := db.GetEngine(ctx).Where("lookup_key = ? AND purpose = ?", lookupKey, purpose).Get(&authToken)
if err != nil {
return nil, err
} else if !has {
diff --git a/models/auth/main_test.go b/models/auth/main_test.go
index d772ea6b1c..b30db24483 100644
--- a/models/auth/main_test.go
+++ b/models/auth/main_test.go
@@ -6,13 +6,14 @@ package auth_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
- _ "code.gitea.io/gitea/models/auth"
- _ "code.gitea.io/gitea/models/perm/access"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/auth"
+ _ "forgejo.org/models/forgefed"
+ _ "forgejo.org/models/perm/access"
)
func TestMain(m *testing.M) {
diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go
index 125d64b36f..fb0a451566 100644
--- a/models/auth/oauth2.go
+++ b/models/auth/oauth2.go
@@ -14,11 +14,11 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
uuid "github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
@@ -657,6 +657,7 @@ func CountOrphanedOAuth2Applications(ctx context.Context) (int64, error) {
Table("`oauth2_application`").
Join("LEFT", "`user`", "`oauth2_application`.`uid` = `user`.`id`").
Where(builder.IsNull{"`user`.id"}).
+ Where(builder.Neq{"uid": 0}). // exclude instance-wide admin applications
Where(builder.NotIn("`oauth2_application`.`client_id`", BuiltinApplicationsClientIDs())).
Select("COUNT(`oauth2_application`.`id`)").
Count()
@@ -668,6 +669,7 @@ func DeleteOrphanedOAuth2Applications(ctx context.Context) (int64, error) {
From("`oauth2_application`").
Join("LEFT", "`user`", "`oauth2_application`.`uid` = `user`.`id`").
Where(builder.IsNull{"`user`.id"}).
+ Where(builder.Neq{"uid": 0}). // exclude instance-wide admin applications
Where(builder.NotIn("`oauth2_application`.`client_id`", BuiltinApplicationsClientIDs()))
b := builder.Delete(builder.In("id", subQuery)).From("`oauth2_application`")
diff --git a/models/auth/oauth2_list.go b/models/auth/oauth2_list.go
index c55f10b3c8..6f508833a0 100644
--- a/models/auth/oauth2_list.go
+++ b/models/auth/oauth2_list.go
@@ -4,7 +4,7 @@
package auth
import (
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
"xorm.io/builder"
)
diff --git a/models/auth/oauth2_test.go b/models/auth/oauth2_test.go
index a6fbcdaa4f..65865c6d31 100644
--- a/models/auth/oauth2_test.go
+++ b/models/auth/oauth2_test.go
@@ -4,29 +4,28 @@
package auth_test
import (
- "path/filepath"
"slices"
"testing"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestOAuth2Application_GenerateClientSecret(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
secret, err := app.GenerateClientSecret(db.DefaultContext)
- assert.NoError(t, err)
- assert.True(t, len(secret) > 0)
+ require.NoError(t, err)
+ assert.NotEmpty(t, secret)
unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1, ClientSecret: app.ClientSecret})
}
func BenchmarkOAuth2Application_GenerateClientSecret(b *testing.B) {
- assert.NoError(b, unittest.PrepareTestDatabase())
+ require.NoError(b, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(b, &auth_model.OAuth2Application{ID: 1})
for i := 0; i < b.N; i++ {
_, _ = app.GenerateClientSecret(db.DefaultContext)
@@ -77,29 +76,29 @@ func TestOAuth2Application_ContainsRedirect_Slash(t *testing.T) {
}
func TestOAuth2Application_ValidateClientSecret(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
secret, err := app.GenerateClientSecret(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, app.ValidateClientSecret([]byte(secret)))
assert.False(t, app.ValidateClientSecret([]byte("fewijfowejgfiowjeoifew")))
}
func TestGetOAuth2ApplicationByClientID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
app, err := auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "da7da3ba-9a13-4167-856f-3899de0b0138")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "da7da3ba-9a13-4167-856f-3899de0b0138", app.ClientID)
app, err = auth_model.GetOAuth2ApplicationByClientID(db.DefaultContext, "invalid client id")
- assert.Error(t, err)
+ require.Error(t, err)
assert.Nil(t, app)
}
func TestCreateOAuth2Application(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
app, err := auth_model.CreateOAuth2Application(db.DefaultContext, auth_model.CreateOAuth2ApplicationOptions{Name: "newapp", UserID: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "newapp", app.Name)
assert.Len(t, app.ClientID, 36)
unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{Name: "newapp"})
@@ -110,22 +109,22 @@ func TestOAuth2Application_TableName(t *testing.T) {
}
func TestOAuth2Application_GetGrantByUserID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
grant, err := app.GetGrantByUserID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), grant.UserID)
grant, err = app.GetGrantByUserID(db.DefaultContext, 34923458)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Nil(t, grant)
}
func TestOAuth2Application_CreateGrant(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: 1})
grant, err := app.CreateGrant(db.DefaultContext, 2, "")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, grant)
assert.Equal(t, int64(2), grant.UserID)
assert.Equal(t, int64(1), grant.ApplicationID)
@@ -135,26 +134,26 @@ func TestOAuth2Application_CreateGrant(t *testing.T) {
//////////////////// Grant
func TestGetOAuth2GrantByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
grant, err := auth_model.GetOAuth2GrantByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), grant.ID)
grant, err = auth_model.GetOAuth2GrantByID(db.DefaultContext, 34923458)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Nil(t, grant)
}
func TestOAuth2Grant_IncreaseCounter(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 1})
- assert.NoError(t, grant.IncreaseCounter(db.DefaultContext))
+ require.NoError(t, grant.IncreaseCounter(db.DefaultContext))
assert.Equal(t, int64(2), grant.Counter)
unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Counter: 2})
}
func TestOAuth2Grant_ScopeContains(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1, Scope: "openid profile"})
assert.True(t, grant.ScopeContains("openid"))
assert.True(t, grant.ScopeContains("profile"))
@@ -163,12 +162,12 @@ func TestOAuth2Grant_ScopeContains(t *testing.T) {
}
func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
grant := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Grant{ID: 1})
code, err := grant.GenerateNewAuthorizationCode(db.DefaultContext, "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, code)
- assert.True(t, len(code.Code) > 32) // secret length > 32
+ assert.Greater(t, len(code.Code), 32) // secret length > 32
}
func TestOAuth2Grant_TableName(t *testing.T) {
@@ -176,36 +175,36 @@ func TestOAuth2Grant_TableName(t *testing.T) {
}
func TestGetOAuth2GrantsByUserID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
result, err := auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, result, 1)
assert.Equal(t, int64(1), result[0].ID)
assert.Equal(t, result[0].ApplicationID, result[0].Application.ID)
result, err = auth_model.GetOAuth2GrantsByUserID(db.DefaultContext, 34134)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, result)
}
func TestRevokeOAuth2Grant(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
- assert.NoError(t, auth_model.RevokeOAuth2Grant(db.DefaultContext, 1, 1))
+ require.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, auth_model.RevokeOAuth2Grant(db.DefaultContext, 1, 1))
unittest.AssertNotExistsBean(t, &auth_model.OAuth2Grant{ID: 1, UserID: 1})
}
//////////////////// Authorization Code
func TestGetOAuth2AuthorizationByCode(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
code, err := auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "authcode")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, code)
assert.Equal(t, "authcode", code.Code)
assert.Equal(t, int64(1), code.ID)
code, err = auth_model.GetOAuth2AuthorizationByCode(db.DefaultContext, "does not exist")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Nil(t, code)
}
@@ -248,18 +247,18 @@ func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) {
}
redirect, err := code.GenerateRedirectURI("thestate")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "https://example.com/callback?code=thecode&state=thestate", redirect.String())
redirect, err = code.GenerateRedirectURI("")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "https://example.com/callback?code=thecode", redirect.String())
}
func TestOAuth2AuthorizationCode_Invalidate(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
code := unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"})
- assert.NoError(t, code.Invalidate(db.DefaultContext))
+ require.NoError(t, code.Invalidate(db.DefaultContext))
unittest.AssertNotExistsBean(t, &auth_model.OAuth2AuthorizationCode{Code: "authcode"})
}
@@ -274,25 +273,20 @@ func TestBuiltinApplicationsClientIDs(t *testing.T) {
}
func TestOrphanedOAuth2Applications(t *testing.T) {
- defer unittest.OverrideFixtures(
- unittest.FixturesOptions{
- Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
- Base: setting.AppWorkPath,
- Dirs: []string{"models/auth/TestOrphanedOAuth2Applications/"},
- },
- )()
- assert.NoError(t, unittest.PrepareTestDatabase())
+ defer unittest.OverrideFixtures("models/auth/TestOrphanedOAuth2Applications")()
+ require.NoError(t, unittest.PrepareTestDatabase())
count, err := auth_model.CountOrphanedOAuth2Applications(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, count)
unittest.AssertExistsIf(t, true, &auth_model.OAuth2Application{ID: 1002})
_, err = auth_model.DeleteOrphanedOAuth2Applications(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
count, err = auth_model.CountOrphanedOAuth2Applications(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, count)
unittest.AssertExistsIf(t, false, &auth_model.OAuth2Application{ID: 1002})
+ unittest.AssertExistsIf(t, true, &auth_model.OAuth2Application{ID: 1003})
}
diff --git a/models/auth/session.go b/models/auth/session.go
index 75a205f702..b3724dafb6 100644
--- a/models/auth/session.go
+++ b/models/auth/session.go
@@ -7,8 +7,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
)
diff --git a/models/auth/session_test.go b/models/auth/session_test.go
index 8cc0abc737..ab6415f289 100644
--- a/models/auth/session_test.go
+++ b/models/auth/session_test.go
@@ -7,16 +7,17 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestAuthSession(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
defer timeutil.MockUnset()
key := "I-Like-Free-Software"
@@ -24,30 +25,30 @@ func TestAuthSession(t *testing.T) {
t.Run("Create Session", func(t *testing.T) {
// Ensure it doesn't exist.
ok, err := auth.ExistSession(db.DefaultContext, key)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, ok)
preCount, err := auth.CountSessions(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
now := time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC)
timeutil.MockSet(now)
// New session is created.
sess, err := auth.ReadSession(db.DefaultContext, key)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, key, sess.Key)
assert.Empty(t, sess.Data)
assert.EqualValues(t, now.Unix(), sess.Expiry)
// Ensure it exists.
ok, err = auth.ExistSession(db.DefaultContext, key)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, ok)
// Ensure the session is taken into account for count..
postCount, err := auth.CountSessions(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Greater(t, postCount, preCount)
})
@@ -58,14 +59,14 @@ func TestAuthSession(t *testing.T) {
// Update session.
err := auth.UpdateSession(db.DefaultContext, key, data)
- assert.NoError(t, err)
+ require.NoError(t, err)
timeutil.MockSet(time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC))
// Read updated session.
// Ensure data is updated and expiry is set from the update session call.
sess, err := auth.ReadSession(db.DefaultContext, key)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, key, sess.Key)
assert.EqualValues(t, data, sess.Data)
assert.EqualValues(t, now.Unix(), sess.Expiry)
@@ -76,23 +77,23 @@ func TestAuthSession(t *testing.T) {
t.Run("Delete session", func(t *testing.T) {
// Ensure it't exist.
ok, err := auth.ExistSession(db.DefaultContext, key)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, ok)
preCount, err := auth.CountSessions(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = auth.DestroySession(db.DefaultContext, key)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Ensure it doesn't exists.
ok, err = auth.ExistSession(db.DefaultContext, key)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, ok)
// Ensure the session is taken into account for count..
postCount, err := auth.CountSessions(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Less(t, postCount, preCount)
})
@@ -100,43 +101,43 @@ func TestAuthSession(t *testing.T) {
timeutil.MockSet(time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC))
_, err := auth.ReadSession(db.DefaultContext, "sess-1")
- assert.NoError(t, err)
+ require.NoError(t, err)
// One minute later.
timeutil.MockSet(time.Date(2023, 1, 1, 0, 1, 0, 0, time.UTC))
_, err = auth.ReadSession(db.DefaultContext, "sess-2")
- assert.NoError(t, err)
+ require.NoError(t, err)
// 5 minutes, shouldn't clean up anything.
err = auth.CleanupSessions(db.DefaultContext, 5*60)
- assert.NoError(t, err)
+ require.NoError(t, err)
ok, err := auth.ExistSession(db.DefaultContext, "sess-1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, ok)
ok, err = auth.ExistSession(db.DefaultContext, "sess-2")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, ok)
// 1 minute, should clean up sess-1.
err = auth.CleanupSessions(db.DefaultContext, 60)
- assert.NoError(t, err)
+ require.NoError(t, err)
ok, err = auth.ExistSession(db.DefaultContext, "sess-1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, ok)
ok, err = auth.ExistSession(db.DefaultContext, "sess-2")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, ok)
// Now, should clean up sess-2.
err = auth.CleanupSessions(db.DefaultContext, 0)
- assert.NoError(t, err)
+ require.NoError(t, err)
ok, err = auth.ExistSession(db.DefaultContext, "sess-2")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, ok)
})
}
diff --git a/models/auth/source.go b/models/auth/source.go
index d03d4975dc..ecd3abc39d 100644
--- a/models/auth/source.go
+++ b/models/auth/source.go
@@ -9,11 +9,11 @@ import (
"fmt"
"reflect"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
"xorm.io/xorm"
@@ -32,7 +32,7 @@ const (
PAM // 4
DLDAP // 5
OAuth2 // 6
- SSPI // 7
+ _ // 7 (was SSPI)
Remote // 8
)
@@ -53,7 +53,6 @@ var Names = map[Type]string{
SMTP: "SMTP",
PAM: "PAM",
OAuth2: "OAuth2",
- SSPI: "SPNEGO with SSPI",
Remote: "Remote",
}
@@ -178,11 +177,6 @@ func (source *Source) IsOAuth2() bool {
return source.Type == OAuth2
}
-// IsSSPI returns true of this source is of the SSPI type.
-func (source *Source) IsSSPI() bool {
- return source.Type == SSPI
-}
-
func (source *Source) IsRemote() bool {
return source.Type == Remote
}
@@ -265,20 +259,6 @@ func (opts FindSourcesOptions) ToConds() builder.Cond {
return conds
}
-// IsSSPIEnabled returns true if there is at least one activated login
-// source of type LoginSSPI
-func IsSSPIEnabled(ctx context.Context) bool {
- exist, err := db.Exist[Source](ctx, FindSourcesOptions{
- IsActive: optional.Some(true),
- LoginType: SSPI,
- }.ToConds())
- if err != nil {
- log.Error("IsSSPIEnabled: failed to query active SSPI sources: %v", err)
- return false
- }
- return exist
-}
-
// GetSourceByID returns login source by given ID.
func GetSourceByID(ctx context.Context, id int64) (*Source, error) {
source := new(Source)
@@ -299,17 +279,6 @@ func GetSourceByID(ctx context.Context, id int64) (*Source, error) {
return source, nil
}
-func GetSourceByName(ctx context.Context, name string) (*Source, error) {
- source := &Source{}
- has, err := db.GetEngine(ctx).Where("name = ?", name).Get(source)
- if err != nil {
- return nil, err
- } else if !has {
- return nil, ErrSourceNotExist{}
- }
- return source, nil
-}
-
// UpdateSource updates a Source record in DB.
func UpdateSource(ctx context.Context, source *Source) error {
var originalSource *Source
diff --git a/models/auth/source_test.go b/models/auth/source_test.go
index 36e76d5e28..ed21aef253 100644
--- a/models/auth/source_test.go
+++ b/models/auth/source_test.go
@@ -7,12 +7,13 @@ import (
"strings"
"testing"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/json"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/json"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/xorm/schemas"
)
@@ -35,10 +36,10 @@ func (source *TestSource) ToDB() ([]byte, error) {
}
func TestDumpAuthSource(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
authSourceSchema, err := db.TableInfo(new(auth_model.Source))
- assert.NoError(t, err)
+ require.NoError(t, err)
auth_model.RegisterTypeConfig(auth_model.OAuth2, new(TestSource))
diff --git a/models/auth/two_factor.go b/models/auth/two_factor.go
new file mode 100644
index 0000000000..e8f19c33cc
--- /dev/null
+++ b/models/auth/two_factor.go
@@ -0,0 +1,21 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+package auth
+
+import (
+ "context"
+)
+
+// HasTwoFactorByUID returns true if the user has TOTP or WebAuthn enabled for
+// their account.
+func HasTwoFactorByUID(ctx context.Context, userID int64) (bool, error) {
+ hasTOTP, err := HasTOTPByUID(ctx, userID)
+ if err != nil {
+ return false, err
+ }
+ if hasTOTP {
+ return true, nil
+ }
+
+ return HasWebAuthnRegistrationsByUID(ctx, userID)
+}
diff --git a/models/auth/two_factor_test.go b/models/auth/two_factor_test.go
new file mode 100644
index 0000000000..36e0404ae2
--- /dev/null
+++ b/models/auth/two_factor_test.go
@@ -0,0 +1,34 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+package auth
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestHasTwoFactorByUID(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ t.Run("No twofactor", func(t *testing.T) {
+ ok, err := HasTwoFactorByUID(t.Context(), 2)
+ require.NoError(t, err)
+ assert.False(t, ok)
+ })
+
+ t.Run("WebAuthn credential", func(t *testing.T) {
+ ok, err := HasTwoFactorByUID(t.Context(), 32)
+ require.NoError(t, err)
+ assert.True(t, ok)
+ })
+
+ t.Run("TOTP", func(t *testing.T) {
+ ok, err := HasTwoFactorByUID(t.Context(), 24)
+ require.NoError(t, err)
+ assert.True(t, ok)
+ })
+}
diff --git a/models/auth/twofactor.go b/models/auth/twofactor.go
index d0c341a192..edff471836 100644
--- a/models/auth/twofactor.go
+++ b/models/auth/twofactor.go
@@ -5,19 +5,16 @@ package auth
import (
"context"
- "crypto/md5"
"crypto/sha256"
"crypto/subtle"
"encoding/base32"
- "encoding/base64"
"encoding/hex"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/secret"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/keying"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"github.com/pquerna/otp/totp"
"golang.org/x/crypto/pbkdf2"
@@ -49,9 +46,9 @@ func (err ErrTwoFactorNotEnrolled) Unwrap() error {
// TwoFactor represents a two-factor authentication token.
type TwoFactor struct {
- ID int64 `xorm:"pk autoincr"`
- UID int64 `xorm:"UNIQUE"`
- Secret string
+ ID int64 `xorm:"pk autoincr"`
+ UID int64 `xorm:"UNIQUE"`
+ Secret []byte `xorm:"BLOB"`
ScratchSalt string
ScratchHash string
LastUsedPasscode string `xorm:"VARCHAR(10)"`
@@ -92,39 +89,35 @@ func (t *TwoFactor) VerifyScratchToken(token string) bool {
return subtle.ConstantTimeCompare([]byte(t.ScratchHash), []byte(tempHash)) == 1
}
-func (t *TwoFactor) getEncryptionKey() []byte {
- k := md5.Sum([]byte(setting.SecretKey))
- return k[:]
-}
-
// SetSecret sets the 2FA secret.
-func (t *TwoFactor) SetSecret(secretString string) error {
- secretBytes, err := secret.AesEncrypt(t.getEncryptionKey(), []byte(secretString))
- if err != nil {
- return err
- }
- t.Secret = base64.StdEncoding.EncodeToString(secretBytes)
- return nil
+func (t *TwoFactor) SetSecret(secretString string) {
+ key := keying.DeriveKey(keying.ContextTOTP)
+ t.Secret = key.Encrypt([]byte(secretString), keying.ColumnAndID("secret", t.ID))
}
// ValidateTOTP validates the provided passcode.
func (t *TwoFactor) ValidateTOTP(passcode string) (bool, error) {
- decodedStoredSecret, err := base64.StdEncoding.DecodeString(t.Secret)
+ key := keying.DeriveKey(keying.ContextTOTP)
+ secret, err := key.Decrypt(t.Secret, keying.ColumnAndID("secret", t.ID))
if err != nil {
return false, err
}
- secretBytes, err := secret.AesDecrypt(t.getEncryptionKey(), decodedStoredSecret)
- if err != nil {
- return false, err
- }
- secretStr := string(secretBytes)
- return totp.Validate(passcode, secretStr), nil
+ return totp.Validate(passcode, string(secret)), nil
}
// NewTwoFactor creates a new two-factor authentication token.
-func NewTwoFactor(ctx context.Context, t *TwoFactor) error {
- _, err := db.GetEngine(ctx).Insert(t)
- return err
+func NewTwoFactor(ctx context.Context, t *TwoFactor, secret string) error {
+ return db.WithTx(ctx, func(ctx context.Context) error {
+ sess := db.GetEngine(ctx)
+ _, err := sess.Insert(t)
+ if err != nil {
+ return err
+ }
+
+ t.SetSecret(secret)
+ _, err = sess.Cols("secret").ID(t.ID).Update(t)
+ return err
+ })
}
// UpdateTwoFactor updates a two-factor authentication token.
@@ -146,9 +139,9 @@ func GetTwoFactorByUID(ctx context.Context, uid int64) (*TwoFactor, error) {
return twofa, nil
}
-// HasTwoFactorByUID returns the two-factor authentication token associated with
-// the user, if any.
-func HasTwoFactorByUID(ctx context.Context, uid int64) (bool, error) {
+// HasTOTPByUID returns the TOTP authentication token associated with
+// the user, if the user has TOTP enabled for their account.
+func HasTOTPByUID(ctx context.Context, uid int64) (bool, error) {
return db.GetEngine(ctx).Where("uid=?", uid).Exist(&TwoFactor{})
}
diff --git a/models/auth/webauthn.go b/models/auth/webauthn.go
index a65d2e1e34..5b86a6e6f2 100644
--- a/models/auth/webauthn.go
+++ b/models/auth/webauthn.go
@@ -8,9 +8,9 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"github.com/go-webauthn/webauthn/webauthn"
)
@@ -40,7 +40,7 @@ func IsErrWebAuthnCredentialNotExist(err error) bool {
}
// WebAuthnCredential represents the WebAuthn credential data for a public-key
-// credential conformant to WebAuthn Level 1
+// credential conformant to WebAuthn Level 3
type WebAuthnCredential struct {
ID int64 `xorm:"pk autoincr"`
Name string
@@ -52,8 +52,12 @@ type WebAuthnCredential struct {
AAGUID []byte
SignCount uint32 `xorm:"BIGINT"`
CloneWarning bool
- CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
- UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
+ BackupEligible bool `xorm:"NOT NULL DEFAULT false"`
+ BackupState bool `xorm:"NOT NULL DEFAULT false"`
+ // If legacy is set to true, backup_eligible and backup_state isn't set.
+ Legacy bool `xorm:"NOT NULL DEFAULT true"`
+ CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
}
func init() {
@@ -71,6 +75,12 @@ func (cred *WebAuthnCredential) UpdateSignCount(ctx context.Context) error {
return err
}
+// UpdateFromLegacy update the values that aren't present on legacy credentials.
+func (cred *WebAuthnCredential) UpdateFromLegacy(ctx context.Context) error {
+ _, err := db.GetEngine(ctx).ID(cred.ID).Cols("legacy", "backup_eligible", "backup_state").Update(cred)
+ return err
+}
+
// BeforeInsert will be invoked by XORM before updating a record
func (cred *WebAuthnCredential) BeforeInsert() {
cred.LowerName = strings.ToLower(cred.Name)
@@ -97,6 +107,10 @@ func (list WebAuthnCredentialList) ToCredentials() []webauthn.Credential {
ID: cred.CredentialID,
PublicKey: cred.PublicKey,
AttestationType: cred.AttestationType,
+ Flags: webauthn.CredentialFlags{
+ BackupEligible: cred.BackupEligible,
+ BackupState: cred.BackupState,
+ },
Authenticator: webauthn.Authenticator{
AAGUID: cred.AAGUID,
SignCount: cred.SignCount,
@@ -167,6 +181,9 @@ func CreateCredential(ctx context.Context, userID int64, name string, cred *weba
AAGUID: cred.Authenticator.AAGUID,
SignCount: cred.Authenticator.SignCount,
CloneWarning: false,
+ BackupEligible: cred.Flags.BackupEligible,
+ BackupState: cred.Flags.BackupState,
+ Legacy: false,
}
if err := db.Insert(ctx, c); err != nil {
diff --git a/models/auth/webauthn_test.go b/models/auth/webauthn_test.go
index f1cf398adf..abf8e34408 100644
--- a/models/auth/webauthn_test.go
+++ b/models/auth/webauthn_test.go
@@ -6,31 +6,32 @@ package auth_test
import (
"testing"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/go-webauthn/webauthn/webauthn"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetWebAuthnCredentialByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
res, err := auth_model.GetWebAuthnCredentialByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "WebAuthn credential", res.Name)
_, err = auth_model.GetWebAuthnCredentialByID(db.DefaultContext, 342432)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, auth_model.IsErrWebAuthnCredentialNotExist(err))
}
func TestGetWebAuthnCredentialsByUID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
res, err := auth_model.GetWebAuthnCredentialsByUID(db.DefaultContext, 32)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, res, 1)
assert.Equal(t, "WebAuthn credential", res[0].Name)
}
@@ -40,28 +41,38 @@ func TestWebAuthnCredential_TableName(t *testing.T) {
}
func TestWebAuthnCredential_UpdateSignCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1})
cred.SignCount = 1
- assert.NoError(t, cred.UpdateSignCount(db.DefaultContext))
+ require.NoError(t, cred.UpdateSignCount(db.DefaultContext))
unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{ID: 1, SignCount: 1})
}
func TestWebAuthnCredential_UpdateLargeCounter(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1})
cred.SignCount = 0xffffffff
- assert.NoError(t, cred.UpdateSignCount(db.DefaultContext))
+ require.NoError(t, cred.UpdateSignCount(db.DefaultContext))
unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{ID: 1, SignCount: 0xffffffff})
}
-func TestCreateCredential(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+func TestWebAuthenCredential_UpdateFromLegacy(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ cred := unittest.AssertExistsAndLoadBean(t, &auth_model.WebAuthnCredential{ID: 1, Legacy: true})
+ cred.Legacy = false
+ cred.BackupEligible = true
+ cred.BackupState = true
+ require.NoError(t, cred.UpdateFromLegacy(db.DefaultContext))
+ unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{ID: 1, BackupEligible: true, BackupState: true}, "legacy = false")
+}
- res, err := auth_model.CreateCredential(db.DefaultContext, 1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test")})
- assert.NoError(t, err)
+func TestCreateCredential(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ res, err := auth_model.CreateCredential(db.DefaultContext, 1, "WebAuthn Created Credential", &webauthn.Credential{ID: []byte("Test"), Flags: webauthn.CredentialFlags{BackupEligible: true, BackupState: true}})
+ require.NoError(t, err)
assert.Equal(t, "WebAuthn Created Credential", res.Name)
assert.Equal(t, []byte("Test"), res.CredentialID)
- unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1})
+ unittest.AssertExistsIf(t, true, &auth_model.WebAuthnCredential{Name: "WebAuthn Created Credential", UserID: 1, BackupEligible: true, BackupState: true}, "legacy = false")
}
diff --git a/models/avatars/avatar.go b/models/avatars/avatar.go
index 9c56e0f9a0..ad59bd8769 100644
--- a/models/avatars/avatar.go
+++ b/models/avatars/avatar.go
@@ -14,12 +14,12 @@ import (
"strings"
"sync/atomic"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
- "strk.kbt.io/projects/go/libravatar"
+ "code.forgejo.org/forgejo-contrib/go-libravatar"
)
const (
diff --git a/models/avatars/avatar_test.go b/models/avatars/avatar_test.go
index c8f7a6574b..7850d2c096 100644
--- a/models/avatars/avatar_test.go
+++ b/models/avatars/avatar_test.go
@@ -6,27 +6,28 @@ package avatars_test
import (
"testing"
- avatars_model "code.gitea.io/gitea/models/avatars"
- "code.gitea.io/gitea/models/db"
- system_model "code.gitea.io/gitea/models/system"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/setting/config"
+ avatars_model "forgejo.org/models/avatars"
+ "forgejo.org/models/db"
+ system_model "forgejo.org/models/system"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/setting/config"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
const gravatarSource = "https://secure.gravatar.com/avatar/"
func disableGravatar(t *testing.T) {
err := system_model.SetSettings(db.DefaultContext, map[string]string{setting.Config().Picture.EnableFederatedAvatar.DynKey(): "false"})
- assert.NoError(t, err)
+ require.NoError(t, err)
err = system_model.SetSettings(db.DefaultContext, map[string]string{setting.Config().Picture.DisableGravatar.DynKey(): "true"})
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func enableGravatar(t *testing.T) {
err := system_model.SetSettings(db.DefaultContext, map[string]string{setting.Config().Picture.DisableGravatar.DynKey(): "false"})
- assert.NoError(t, err)
+ require.NoError(t, err)
setting.GravatarSource = gravatarSource
}
diff --git a/models/avatars/main_test.go b/models/avatars/main_test.go
index c721a7dc2a..bdc66954b1 100644
--- a/models/avatars/main_test.go
+++ b/models/avatars/main_test.go
@@ -6,11 +6,11 @@ package avatars_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/activities"
- _ "code.gitea.io/gitea/models/perm/access"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/perm/access"
)
func TestMain(m *testing.M) {
diff --git a/models/db/collation.go b/models/db/collation.go
index 39d28fa2ff..768ada89e6 100644
--- a/models/db/collation.go
+++ b/models/db/collation.go
@@ -8,9 +8,9 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
diff --git a/models/db/common.go b/models/db/common.go
index f3fd3e72ae..c9b012597c 100644
--- a/models/db/common.go
+++ b/models/db/common.go
@@ -6,8 +6,8 @@ package db
import (
"strings"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/db/context.go b/models/db/context.go
index 43f612518a..35526936af 100644
--- a/models/db/context.go
+++ b/models/db/context.go
@@ -269,6 +269,9 @@ func FindIDs(ctx context.Context, tableName, idCol string, cond builder.Cond) ([
// DecrByIDs decreases the given column for entities of the "bean" type with one of the given ids by one
// Timestamps of the entities won't be updated
func DecrByIDs(ctx context.Context, ids []int64, decrCol string, bean any) error {
+ if len(ids) == 0 {
+ return nil
+ }
_, err := GetEngine(ctx).Decr(decrCol).In("id", ids).NoAutoCondition().NoAutoTime().Update(bean)
return err
}
diff --git a/models/db/context_committer_test.go b/models/db/context_committer_test.go
index 38e91f22ed..849c5dea41 100644
--- a/models/db/context_committer_test.go
+++ b/models/db/context_committer_test.go
@@ -4,7 +4,7 @@
package db // it's not db_test, because this file is for testing the private type halfCommitter
import (
- "fmt"
+ "errors"
"testing"
"github.com/stretchr/testify/assert"
@@ -80,7 +80,7 @@ func Test_halfCommitter(t *testing.T) {
testWithCommitter(mockCommitter, func(committer Committer) error {
defer committer.Close()
if true {
- return fmt.Errorf("error")
+ return errors.New("error")
}
return committer.Commit()
})
@@ -94,7 +94,7 @@ func Test_halfCommitter(t *testing.T) {
testWithCommitter(mockCommitter, func(committer Committer) error {
committer.Close()
committer.Commit()
- return fmt.Errorf("error")
+ return errors.New("error")
})
mockCommitter.Assert(t)
diff --git a/models/db/context_test.go b/models/db/context_test.go
index 95a01d4a26..7ab327b7e9 100644
--- a/models/db/context_test.go
+++ b/models/db/context_test.go
@@ -7,78 +7,79 @@ import (
"context"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestInTransaction(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.False(t, db.InTransaction(db.DefaultContext))
- assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
+ require.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
assert.True(t, db.InTransaction(ctx))
return nil
}))
ctx, committer, err := db.TxContext(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer committer.Close()
assert.True(t, db.InTransaction(ctx))
- assert.NoError(t, db.WithTx(ctx, func(ctx context.Context) error {
+ require.NoError(t, db.WithTx(ctx, func(ctx context.Context) error {
assert.True(t, db.InTransaction(ctx))
return nil
}))
}
func TestTxContext(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
{ // create new transaction
ctx, committer, err := db.TxContext(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, db.InTransaction(ctx))
- assert.NoError(t, committer.Commit())
+ require.NoError(t, committer.Commit())
}
{ // reuse the transaction created by TxContext and commit it
ctx, committer, err := db.TxContext(db.DefaultContext)
engine := db.GetEngine(ctx)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, db.InTransaction(ctx))
{
ctx, committer, err := db.TxContext(ctx)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, db.InTransaction(ctx))
assert.Equal(t, engine, db.GetEngine(ctx))
- assert.NoError(t, committer.Commit())
+ require.NoError(t, committer.Commit())
}
- assert.NoError(t, committer.Commit())
+ require.NoError(t, committer.Commit())
}
{ // reuse the transaction created by TxContext and close it
ctx, committer, err := db.TxContext(db.DefaultContext)
engine := db.GetEngine(ctx)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, db.InTransaction(ctx))
{
ctx, committer, err := db.TxContext(ctx)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, db.InTransaction(ctx))
assert.Equal(t, engine, db.GetEngine(ctx))
- assert.NoError(t, committer.Close())
+ require.NoError(t, committer.Close())
}
- assert.NoError(t, committer.Close())
+ require.NoError(t, committer.Close())
}
{ // reuse the transaction created by WithTx
- assert.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
+ require.NoError(t, db.WithTx(db.DefaultContext, func(ctx context.Context) error {
assert.True(t, db.InTransaction(ctx))
{
ctx, committer, err := db.TxContext(ctx)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, db.InTransaction(ctx))
- assert.NoError(t, committer.Commit())
+ require.NoError(t, committer.Commit())
}
return nil
}))
diff --git a/models/db/convert.go b/models/db/convert.go
index b8b15382e7..1f37e49176 100644
--- a/models/db/convert.go
+++ b/models/db/convert.go
@@ -6,9 +6,10 @@ package db
import (
"fmt"
"strconv"
+ "strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
@@ -25,7 +26,8 @@ func ConvertDatabaseTable() error {
return err
}
- _, err = x.Exec(fmt.Sprintf("ALTER DATABASE `%s` CHARACTER SET utf8mb4 COLLATE %s", setting.Database.Name, r.ExpectedCollation))
+ databaseName := strings.SplitN(setting.Database.Name, "?", 2)[0]
+ _, err = x.Exec(fmt.Sprintf("ALTER DATABASE `%s` CHARACTER SET utf8mb4 COLLATE %s", databaseName, r.ExpectedCollation))
if err != nil {
return err
}
@@ -56,6 +58,7 @@ func Cell2Int64(val xorm.Cell) int64 {
v, _ := strconv.ParseInt(string((*val).([]uint8)), 10, 64)
return v
+ default:
+ return (*val).(int64)
}
- return (*val).(int64)
}
diff --git a/models/db/engine.go b/models/db/engine.go
index 61649592e7..ca6576da8a 100755
--- a/models/db/engine.go
+++ b/models/db/engine.go
@@ -11,11 +11,12 @@ import (
"fmt"
"io"
"reflect"
+ "runtime/trace"
"strings"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
"xorm.io/xorm/contexts"
@@ -163,6 +164,8 @@ func InitEngine(ctx context.Context) error {
Logger: errorLogger,
})
+ xormEngine.AddHook(&TracingHook{})
+
SetDefaultEngine(ctx, xormEngine)
return nil
}
@@ -318,6 +321,25 @@ func SetLogSQL(ctx context.Context, on bool) {
}
}
+type TracingHook struct{}
+
+var _ contexts.Hook = &TracingHook{}
+
+type sqlTask struct{}
+
+func (TracingHook) BeforeProcess(c *contexts.ContextHook) (context.Context, error) {
+ ctx, task := trace.NewTask(c.Ctx, "sql")
+ ctx = context.WithValue(ctx, sqlTask{}, task)
+ trace.Log(ctx, "query", c.SQL)
+ trace.Logf(ctx, "args", "%v", c.Args)
+ return ctx, nil
+}
+
+func (TracingHook) AfterProcess(c *contexts.ContextHook) error {
+ c.Ctx.Value(sqlTask{}).(*trace.Task).End()
+ return nil
+}
+
type SlowQueryHook struct {
Treshold time.Duration
Logger log.Logger
diff --git a/models/db/engine_test.go b/models/db/engine_test.go
index f050c5ca28..5d20e3d602 100644
--- a/models/db/engine_test.go
+++ b/models/db/engine_test.go
@@ -8,21 +8,22 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
- _ "code.gitea.io/gitea/cmd" // for TestPrimaryKeys
+ _ "forgejo.org/cmd" // for TestPrimaryKeys
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/xorm"
)
func TestDumpDatabase(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
dir := t.TempDir()
@@ -30,31 +31,31 @@ func TestDumpDatabase(t *testing.T) {
ID int64 `xorm:"pk autoincr"`
Version int64
}
- assert.NoError(t, db.GetEngine(db.DefaultContext).Sync(new(Version)))
+ require.NoError(t, db.GetEngine(db.DefaultContext).Sync(new(Version)))
for _, dbType := range setting.SupportedDatabaseTypes {
- assert.NoError(t, db.DumpDatabase(filepath.Join(dir, dbType+".sql"), dbType))
+ require.NoError(t, db.DumpDatabase(filepath.Join(dir, dbType+".sql"), dbType))
}
}
func TestDeleteOrphanedObjects(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
countBefore, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = db.GetEngine(db.DefaultContext).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003})
- assert.NoError(t, err)
+ require.NoError(t, err)
orphaned, err := db.CountOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, orphaned)
err = db.DeleteOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
- assert.NoError(t, err)
+ require.NoError(t, err)
countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, countBefore, countAfter)
}
@@ -63,7 +64,7 @@ func TestPrimaryKeys(t *testing.T) {
// https://github.com/go-gitea/gitea/issues/21086
// https://github.com/go-gitea/gitea/issues/16802
// To avoid creating tables without primary key again, this test will check them.
- // Import "code.gitea.io/gitea/cmd" to make sure each db.RegisterModel in init functions has been called.
+ // Import "forgejo.org/cmd" to make sure each db.RegisterModel in init functions has been called.
beans, err := db.NamesToBean()
if err != nil {
diff --git a/models/db/error.go b/models/db/error.go
index 665e970e17..6b70c40eb3 100644
--- a/models/db/error.go
+++ b/models/db/error.go
@@ -6,7 +6,7 @@ package db
import (
"fmt"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
// ErrCancelled represents an error due to context cancellation
diff --git a/models/db/index.go b/models/db/index.go
index 259ddd6ade..4c15dbe8a1 100644
--- a/models/db/index.go
+++ b/models/db/index.go
@@ -9,7 +9,7 @@ import (
"fmt"
"strconv"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
// ResourceIndex represents a resource index which could be used as issue/release and others
diff --git a/models/db/index_test.go b/models/db/index_test.go
index 5fce0a6012..929e514329 100644
--- a/models/db/index_test.go
+++ b/models/db/index_test.go
@@ -9,10 +9,11 @@ import (
"fmt"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
type TestIndex db.ResourceIndex
@@ -31,96 +32,96 @@ func getCurrentResourceIndex(ctx context.Context, tableName string, groupID int6
}
func TestSyncMaxResourceIndex(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
xe := unittest.GetXORMEngine()
- assert.NoError(t, xe.Sync(&TestIndex{}))
+ require.NoError(t, xe.Sync(&TestIndex{}))
err := db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 51)
- assert.NoError(t, err)
+ require.NoError(t, err)
// sync new max index
maxIndex, err := getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 51, maxIndex)
// smaller index doesn't change
err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 30)
- assert.NoError(t, err)
+ require.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 51, maxIndex)
// larger index changes
err = db.SyncMaxResourceIndex(db.DefaultContext, "test_index", 10, 62)
- assert.NoError(t, err)
+ require.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 62, maxIndex)
// commit transaction
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 73)
- assert.NoError(t, err)
+ require.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 73, maxIndex)
return nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 73, maxIndex)
// rollback transaction
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
err = db.SyncMaxResourceIndex(ctx, "test_index", 10, 84)
maxIndex, err = getCurrentResourceIndex(ctx, "test_index", 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 84, maxIndex)
return errors.New("test rollback")
})
- assert.Error(t, err)
+ require.Error(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 73, maxIndex) // the max index doesn't change because the transaction was rolled back
}
func TestGetNextResourceIndex(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
xe := unittest.GetXORMEngine()
- assert.NoError(t, xe.Sync(&TestIndex{}))
+ require.NoError(t, xe.Sync(&TestIndex{}))
// create a new record
maxIndex, err := db.GetNextResourceIndex(db.DefaultContext, "test_index", 20)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, maxIndex)
// increase the existing record
maxIndex, err = db.GetNextResourceIndex(db.DefaultContext, "test_index", 20)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 2, maxIndex)
// commit transaction
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, maxIndex)
return nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, maxIndex)
// rollback transaction
err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
maxIndex, err = db.GetNextResourceIndex(ctx, "test_index", 20)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 4, maxIndex)
return errors.New("test rollback")
})
- assert.Error(t, err)
+ require.Error(t, err)
maxIndex, err = getCurrentResourceIndex(db.DefaultContext, "test_index", 20)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, maxIndex) // the max index doesn't change because the transaction was rolled back
}
diff --git a/models/db/install/db.go b/models/db/install/db.go
index d4c1139637..104a7a8e39 100644
--- a/models/db/install/db.go
+++ b/models/db/install/db.go
@@ -4,8 +4,8 @@
package install
import (
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/db/iterate.go b/models/db/iterate.go
index e1caefa72b..450c7d3389 100644
--- a/models/db/iterate.go
+++ b/models/db/iterate.go
@@ -6,7 +6,7 @@ package db
import (
"context"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/builder"
)
diff --git a/models/db/iterate_test.go b/models/db/iterate_test.go
index 0f6ba2cc94..47b6a956f4 100644
--- a/models/db/iterate_test.go
+++ b/models/db/iterate_test.go
@@ -7,27 +7,28 @@ import (
"context"
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIterate(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
xe := unittest.GetXORMEngine()
- assert.NoError(t, xe.Sync(&repo_model.RepoUnit{}))
+ require.NoError(t, xe.Sync(&repo_model.RepoUnit{}))
cnt, err := db.GetEngine(db.DefaultContext).Count(&repo_model.RepoUnit{})
- assert.NoError(t, err)
+ require.NoError(t, err)
var repoUnitCnt int
err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repo *repo_model.RepoUnit) error {
repoUnitCnt++
return nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, cnt, repoUnitCnt)
err = db.Iterate(db.DefaultContext, nil, func(ctx context.Context, repoUnit *repo_model.RepoUnit) error {
@@ -38,9 +39,7 @@ func TestIterate(t *testing.T) {
if !has {
return db.ErrNotExist{Resource: "repo_unit", ID: repoUnit.ID}
}
- assert.EqualValues(t, repoUnit.RepoID, repoUnit.RepoID)
- assert.EqualValues(t, repoUnit.CreatedUnix, repoUnit.CreatedUnix)
return nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
}
diff --git a/models/db/list.go b/models/db/list.go
index 5c005a0350..057221936c 100644
--- a/models/db/list.go
+++ b/models/db/list.go
@@ -6,7 +6,7 @@ package db
import (
"context"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/builder"
"xorm.io/xorm"
diff --git a/models/db/list_test.go b/models/db/list_test.go
index 45194611f8..f13958496a 100644
--- a/models/db/list_test.go
+++ b/models/db/list_test.go
@@ -6,11 +6,12 @@ package db_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/builder"
)
@@ -27,26 +28,26 @@ func (opts mockListOptions) ToConds() builder.Cond {
}
func TestFind(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
xe := unittest.GetXORMEngine()
- assert.NoError(t, xe.Sync(&repo_model.RepoUnit{}))
+ require.NoError(t, xe.Sync(&repo_model.RepoUnit{}))
var repoUnitCount int
_, err := db.GetEngine(db.DefaultContext).SQL("SELECT COUNT(*) FROM repo_unit").Get(&repoUnitCount)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotEmpty(t, repoUnitCount)
opts := mockListOptions{}
repoUnits, err := db.Find[repo_model.RepoUnit](db.DefaultContext, opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, repoUnits, repoUnitCount)
cnt, err := db.Count[repo_model.RepoUnit](db.DefaultContext, opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, repoUnitCount, cnt)
repoUnits, newCnt, err := db.FindAndCount[repo_model.RepoUnit](db.DefaultContext, opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, cnt, newCnt)
assert.Len(t, repoUnits, repoUnitCount)
}
diff --git a/models/db/log.go b/models/db/log.go
index 307788ea2e..387709cc50 100644
--- a/models/db/log.go
+++ b/models/db/log.go
@@ -7,7 +7,7 @@ import (
"fmt"
"sync/atomic"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
xormlog "xorm.io/xorm/log"
)
@@ -67,8 +67,11 @@ func (l *XORMLogBridge) Warn(v ...any) {
l.Log(stackLevel, log.WARN, "%s", fmt.Sprint(v...))
}
-// Warnf show warnning log
+// Warnf show warning log
func (l *XORMLogBridge) Warnf(format string, v ...any) {
+ if format == "Table %s Column %s db default is %s, struct default is %s" || format == "Table %s Column %s db nullable is %v, struct nullable is %v" {
+ return
+ }
l.Log(stackLevel, log.WARN, format, v...)
}
diff --git a/models/db/main_test.go b/models/db/main_test.go
index 7d80b400fe..4b06923950 100644
--- a/models/db/main_test.go
+++ b/models/db/main_test.go
@@ -6,10 +6,10 @@ package db_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/repo"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/repo"
)
func TestMain(m *testing.M) {
diff --git a/models/db/name.go b/models/db/name.go
index 51be33a8bc..29b60b2373 100644
--- a/models/db/name.go
+++ b/models/db/name.go
@@ -9,7 +9,7 @@ import (
"strings"
"unicode/utf8"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
var (
diff --git a/models/db/paginator/main_test.go b/models/db/paginator/main_test.go
index 47993aed6b..e2528be121 100644
--- a/models/db/paginator/main_test.go
+++ b/models/db/paginator/main_test.go
@@ -6,7 +6,7 @@ package paginator
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/models/db/paginator/paginator_test.go b/models/db/paginator/paginator_test.go
index 20602212d9..c6d0569aaa 100644
--- a/models/db/paginator/paginator_test.go
+++ b/models/db/paginator/paginator_test.go
@@ -6,8 +6,8 @@ package paginator
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
)
diff --git a/models/db/sequence.go b/models/db/sequence.go
index f49ad935de..1740e74c52 100644
--- a/models/db/sequence.go
+++ b/models/db/sequence.go
@@ -8,7 +8,7 @@ import (
"fmt"
"regexp"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
// CountBadSequences looks for broken sequences from recreate-table mistakes
diff --git a/models/db/sql_postgres_with_schema.go b/models/db/sql_postgres_with_schema.go
index ec63447f6f..376f984dc6 100644
--- a/models/db/sql_postgres_with_schema.go
+++ b/models/db/sql_postgres_with_schema.go
@@ -8,7 +8,7 @@ import (
"database/sql/driver"
"sync"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/lib/pq"
"xorm.io/xorm/dialects"
diff --git a/models/dbfs/dbfile.go b/models/dbfs/dbfile.go
index dd27b5c36b..12c0398abc 100644
--- a/models/dbfs/dbfile.go
+++ b/models/dbfs/dbfile.go
@@ -14,7 +14,7 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
var defaultFileBlockSize int64 = 32 * 1024
diff --git a/models/dbfs/dbfs.go b/models/dbfs/dbfs.go
index f68b4a2b70..ba57e50151 100644
--- a/models/dbfs/dbfs.go
+++ b/models/dbfs/dbfs.go
@@ -10,7 +10,7 @@ import (
"path"
"time"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
/*
diff --git a/models/dbfs/dbfs_test.go b/models/dbfs/dbfs_test.go
index 96cb1014c7..8e42c54f31 100644
--- a/models/dbfs/dbfs_test.go
+++ b/models/dbfs/dbfs_test.go
@@ -9,9 +9,10 @@ import (
"os"
"testing"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func changeDefaultFileBlockSize(n int64) (restore func()) {
@@ -27,102 +28,102 @@ func TestDbfsBasic(t *testing.T) {
// test basic write/read
f, err := OpenFile(db.DefaultContext, "test.txt", os.O_RDWR|os.O_CREATE)
- assert.NoError(t, err)
+ require.NoError(t, err)
n, err := f.Write([]byte("0123456789")) // blocks: 0123 4567 89
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 10, n)
_, err = f.Seek(0, io.SeekStart)
- assert.NoError(t, err)
+ require.NoError(t, err)
buf, err := io.ReadAll(f)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 10, n)
assert.EqualValues(t, "0123456789", string(buf))
// write some new data
_, err = f.Seek(1, io.SeekStart)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Write([]byte("bcdefghi")) // blocks: 0bcd efgh i9
- assert.NoError(t, err)
+ require.NoError(t, err)
// read from offset
buf, err = io.ReadAll(f)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "9", string(buf))
// read all
_, err = f.Seek(0, io.SeekStart)
- assert.NoError(t, err)
+ require.NoError(t, err)
buf, err = io.ReadAll(f)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "0bcdefghi9", string(buf))
// write to new size
_, err = f.Seek(-1, io.SeekEnd)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Write([]byte("JKLMNOP")) // blocks: 0bcd efgh iJKL MNOP
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Seek(0, io.SeekStart)
- assert.NoError(t, err)
+ require.NoError(t, err)
buf, err = io.ReadAll(f)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "0bcdefghiJKLMNOP", string(buf))
// write beyond EOF and fill with zero
_, err = f.Seek(5, io.SeekCurrent)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Write([]byte("xyzu")) // blocks: 0bcd efgh iJKL MNOP 0000 0xyz u
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Seek(0, io.SeekStart)
- assert.NoError(t, err)
+ require.NoError(t, err)
buf, err = io.ReadAll(f)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "0bcdefghiJKLMNOP\x00\x00\x00\x00\x00xyzu", string(buf))
// write to the block with zeros
_, err = f.Seek(-6, io.SeekCurrent)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Write([]byte("ABCD")) // blocks: 0bcd efgh iJKL MNOP 000A BCDz u
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Seek(0, io.SeekStart)
- assert.NoError(t, err)
+ require.NoError(t, err)
buf, err = io.ReadAll(f)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "0bcdefghiJKLMNOP\x00\x00\x00ABCDzu", string(buf))
- assert.NoError(t, f.Close())
+ require.NoError(t, f.Close())
// test rename
err = Rename(db.DefaultContext, "test.txt", "test2.txt")
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = OpenFile(db.DefaultContext, "test.txt", os.O_RDONLY)
- assert.Error(t, err)
+ require.Error(t, err)
f, err = OpenFile(db.DefaultContext, "test2.txt", os.O_RDONLY)
- assert.NoError(t, err)
- assert.NoError(t, f.Close())
+ require.NoError(t, err)
+ require.NoError(t, f.Close())
// test remove
err = Remove(db.DefaultContext, "test2.txt")
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = OpenFile(db.DefaultContext, "test2.txt", os.O_RDONLY)
- assert.Error(t, err)
+ require.Error(t, err)
// test stat
f, err = OpenFile(db.DefaultContext, "test/test.txt", os.O_RDWR|os.O_CREATE)
- assert.NoError(t, err)
+ require.NoError(t, err)
stat, err := f.Stat()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "test.txt", stat.Name())
assert.EqualValues(t, 0, stat.Size())
_, err = f.Write([]byte("0123456789"))
- assert.NoError(t, err)
+ require.NoError(t, err)
stat, err = f.Stat()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 10, stat.Size())
}
@@ -130,61 +131,61 @@ func TestDbfsReadWrite(t *testing.T) {
defer changeDefaultFileBlockSize(4)()
f1, err := OpenFile(db.DefaultContext, "test.log", os.O_RDWR|os.O_CREATE)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer f1.Close()
f2, err := OpenFile(db.DefaultContext, "test.log", os.O_RDONLY)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer f2.Close()
_, err = f1.Write([]byte("line 1\n"))
- assert.NoError(t, err)
+ require.NoError(t, err)
f2r := bufio.NewReader(f2)
line, err := f2r.ReadString('\n')
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "line 1\n", line)
_, err = f2r.ReadString('\n')
- assert.ErrorIs(t, err, io.EOF)
+ require.ErrorIs(t, err, io.EOF)
_, err = f1.Write([]byte("line 2\n"))
- assert.NoError(t, err)
+ require.NoError(t, err)
line, err = f2r.ReadString('\n')
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "line 2\n", line)
_, err = f2r.ReadString('\n')
- assert.ErrorIs(t, err, io.EOF)
+ require.ErrorIs(t, err, io.EOF)
}
func TestDbfsSeekWrite(t *testing.T) {
defer changeDefaultFileBlockSize(4)()
f, err := OpenFile(db.DefaultContext, "test2.log", os.O_RDWR|os.O_CREATE)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer f.Close()
n, err := f.Write([]byte("111"))
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Seek(int64(n), io.SeekStart)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Write([]byte("222"))
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Seek(int64(n), io.SeekStart)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = f.Write([]byte("333"))
- assert.NoError(t, err)
+ require.NoError(t, err)
fr, err := OpenFile(db.DefaultContext, "test2.log", os.O_RDONLY)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer f.Close()
buf, err := io.ReadAll(fr)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "111333", string(buf))
}
diff --git a/models/dbfs/main_test.go b/models/dbfs/main_test.go
index 537ba0935d..3d4b2bc235 100644
--- a/models/dbfs/main_test.go
+++ b/models/dbfs/main_test.go
@@ -6,7 +6,7 @@ package dbfs
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/models/error.go b/models/error.go
index 75c53245de..e8962f386b 100644
--- a/models/error.go
+++ b/models/error.go
@@ -7,9 +7,9 @@ package models
import (
"fmt"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/util"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/util"
)
// ErrUserOwnRepos represents a "UserOwnRepos" kind of error.
@@ -151,25 +151,6 @@ func (err *ErrInvalidCloneAddr) Unwrap() error {
return util.ErrInvalidArgument
}
-// ErrUpdateTaskNotExist represents a "UpdateTaskNotExist" kind of error.
-type ErrUpdateTaskNotExist struct {
- UUID string
-}
-
-// IsErrUpdateTaskNotExist checks if an error is a ErrUpdateTaskNotExist.
-func IsErrUpdateTaskNotExist(err error) bool {
- _, ok := err.(ErrUpdateTaskNotExist)
- return ok
-}
-
-func (err ErrUpdateTaskNotExist) Error() string {
- return fmt.Sprintf("update task does not exist [uuid: %s]", err.UUID)
-}
-
-func (err ErrUpdateTaskNotExist) Unwrap() error {
- return util.ErrNotExist
-}
-
// ErrInvalidTagName represents a "InvalidTagName" kind of error.
type ErrInvalidTagName struct {
TagName string
diff --git a/models/fixture_generation.go b/models/fixture_generation.go
deleted file mode 100644
index 6234caefad..0000000000
--- a/models/fixture_generation.go
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package models
-
-import (
- "context"
- "fmt"
- "strings"
-
- "code.gitea.io/gitea/models/db"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
-)
-
-// GetYamlFixturesAccess returns a string containing the contents
-// for the access table, as recalculated using repo.RecalculateAccesses()
-func GetYamlFixturesAccess(ctx context.Context) (string, error) {
- repos := make([]*repo_model.Repository, 0, 50)
- if err := db.GetEngine(ctx).Find(&repos); err != nil {
- return "", err
- }
-
- for _, repo := range repos {
- repo.MustOwner(ctx)
- if err := access_model.RecalculateAccesses(ctx, repo); err != nil {
- return "", err
- }
- }
-
- var b strings.Builder
-
- accesses := make([]*access_model.Access, 0, 200)
- if err := db.GetEngine(ctx).OrderBy("user_id, repo_id").Find(&accesses); err != nil {
- return "", err
- }
-
- for i, a := range accesses {
- fmt.Fprintf(&b, "-\n")
- fmt.Fprintf(&b, " id: %d\n", i+1)
- fmt.Fprintf(&b, " user_id: %d\n", a.UserID)
- fmt.Fprintf(&b, " repo_id: %d\n", a.RepoID)
- fmt.Fprintf(&b, " mode: %d\n", a.Mode)
- if i < len(accesses)-1 {
- fmt.Fprintf(&b, "\n")
- }
- }
-
- return b.String(), nil
-}
diff --git a/models/fixture_test.go b/models/fixture_test.go
deleted file mode 100644
index de5f412388..0000000000
--- a/models/fixture_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package models
-
-import (
- "context"
- "os"
- "path/filepath"
- "testing"
-
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/util"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestFixtureGeneration(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
-
- test := func(ctx context.Context, gen func(ctx context.Context) (string, error), name string) {
- expected, err := gen(ctx)
- if !assert.NoError(t, err) {
- return
- }
- p := filepath.Join(unittest.FixturesDir(), name+".yml")
- bytes, err := os.ReadFile(p)
- if !assert.NoError(t, err) {
- return
- }
- data := string(util.NormalizeEOL(bytes))
- assert.EqualValues(t, expected, data, "Differences detected for %s", p)
- }
-
- test(db.DefaultContext, GetYamlFixturesAccess, "access")
-}
diff --git a/models/fixtures/PrivateIssueProjects/project.yml b/models/fixtures/PrivateIssueProjects/project.yml
new file mode 100644
index 0000000000..8950b33606
--- /dev/null
+++ b/models/fixtures/PrivateIssueProjects/project.yml
@@ -0,0 +1,23 @@
+-
+ id: 1001
+ title: Org project that contains private and public issues
+ owner_id: 3
+ repo_id: 0
+ is_closed: false
+ creator_id: 2
+ board_type: 1
+ type: 3
+ created_unix: 1738000000
+ updated_unix: 1738000000
+
+-
+ id: 1002
+ title: User project that contains private and public issues
+ owner_id: 2
+ repo_id: 0
+ is_closed: false
+ creator_id: 2
+ board_type: 1
+ type: 1
+ created_unix: 1738000000
+ updated_unix: 1738000000
diff --git a/models/fixtures/PrivateIssueProjects/project_board.yml b/models/fixtures/PrivateIssueProjects/project_board.yml
new file mode 100644
index 0000000000..3f1fe1e705
--- /dev/null
+++ b/models/fixtures/PrivateIssueProjects/project_board.yml
@@ -0,0 +1,17 @@
+-
+ id: 1001
+ project_id: 1001
+ title: Triage
+ creator_id: 2
+ default: true
+ created_unix: 1738000000
+ updated_unix: 1738000000
+
+-
+ id: 1002
+ project_id: 1002
+ title: Triage
+ creator_id: 2
+ default: true
+ created_unix: 1738000000
+ updated_unix: 1738000000
diff --git a/models/fixtures/PrivateIssueProjects/project_issue.yml b/models/fixtures/PrivateIssueProjects/project_issue.yml
new file mode 100644
index 0000000000..0245fb47f3
--- /dev/null
+++ b/models/fixtures/PrivateIssueProjects/project_issue.yml
@@ -0,0 +1,23 @@
+-
+ id: 1001
+ issue_id: 6
+ project_id: 1001
+ project_board_id: 1001
+
+-
+ id: 1002
+ issue_id: 7
+ project_id: 1002
+ project_board_id: 1002
+
+-
+ id: 1003
+ issue_id: 16
+ project_id: 1001
+ project_board_id: 1001
+
+-
+ id: 1004
+ issue_id: 1
+ project_id: 1002
+ project_board_id: 1002
diff --git a/models/fixtures/TestGetUsedForUser/action_artifact.yaml b/models/fixtures/TestGetUsedForUser/action_artifact.yaml
new file mode 100644
index 0000000000..db5392126d
--- /dev/null
+++ b/models/fixtures/TestGetUsedForUser/action_artifact.yaml
@@ -0,0 +1,17 @@
+-
+ id: 1001
+ run_id: 792
+ runner_id: 1
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ storage_path: "27/5/1730330775594233150.chunk"
+ file_size: 693147180559
+ file_compressed_size: 693147180559
+ content_encoding: "application/zip"
+ artifact_path: "big-file.zip"
+ artifact_name: "big-file"
+ status: 4
+ created_unix: 1730330775
+ updated_unix: 1730330775
+ expired_unix: 1738106775
diff --git a/models/fixtures/TestPackagesGetOrInsertBlob/package_blob.yml b/models/fixtures/TestPackagesGetOrInsertBlob/package_blob.yml
new file mode 100644
index 0000000000..ec90787c43
--- /dev/null
+++ b/models/fixtures/TestPackagesGetOrInsertBlob/package_blob.yml
@@ -0,0 +1,17 @@
+-
+ id: 1
+ size: 10
+ hash_md5: HASHMD5_1
+ hash_sha1: HASHSHA1_1
+ hash_sha256: HASHSHA256_1
+ hash_sha512: HASHSHA512_1
+ hash_blake2b: HASHBLAKE2B_1
+ created_unix: 946687980
+-
+ id: 2
+ size: 20
+ hash_md5: HASHMD5_2
+ hash_sha1: HASHSHA1_2
+ hash_sha256: HASHSHA256_2
+ hash_sha512: HASHSHA512_2
+ created_unix: 946687980
diff --git a/models/fixtures/TestPrivateRepoProjects/access.yml b/models/fixtures/TestPrivateRepoProjects/access.yml
new file mode 100644
index 0000000000..4149e34b0b
--- /dev/null
+++ b/models/fixtures/TestPrivateRepoProjects/access.yml
@@ -0,0 +1,5 @@
+-
+ id: 1001
+ user_id: 29
+ repo_id: 3
+ mode: 1
diff --git a/models/fixtures/TestPrivateRepoProjects/project.yml b/models/fixtures/TestPrivateRepoProjects/project.yml
new file mode 100644
index 0000000000..f66e4c8676
--- /dev/null
+++ b/models/fixtures/TestPrivateRepoProjects/project.yml
@@ -0,0 +1,11 @@
+-
+ id: 1001
+ title: Org project that contains private issues
+ owner_id: 3
+ repo_id: 0
+ is_closed: false
+ creator_id: 2
+ board_type: 1
+ type: 3
+ created_unix: 1738000000
+ updated_unix: 1738000000
diff --git a/models/fixtures/TestPrivateRepoProjects/project_board.yml b/models/fixtures/TestPrivateRepoProjects/project_board.yml
new file mode 100644
index 0000000000..9829cf7e27
--- /dev/null
+++ b/models/fixtures/TestPrivateRepoProjects/project_board.yml
@@ -0,0 +1,8 @@
+-
+ id: 1001
+ project_id: 1001
+ title: Triage
+ creator_id: 2
+ default: true
+ created_unix: 1738000000
+ updated_unix: 1738000000
diff --git a/models/fixtures/TestPrivateRepoProjects/project_issue.yml b/models/fixtures/TestPrivateRepoProjects/project_issue.yml
new file mode 100644
index 0000000000..3e8c1dca9e
--- /dev/null
+++ b/models/fixtures/TestPrivateRepoProjects/project_issue.yml
@@ -0,0 +1,11 @@
+-
+ id: 1001
+ issue_id: 6
+ project_id: 1001
+ project_board_id: 1001
+
+-
+ id: 1002
+ issue_id: 15
+ project_id: 1001
+ project_board_id: 1001
diff --git a/models/fixtures/action_artifact.yml b/models/fixtures/action_artifact.yml
new file mode 100644
index 0000000000..2c51c11ebd
--- /dev/null
+++ b/models/fixtures/action_artifact.yml
@@ -0,0 +1,71 @@
+-
+ id: 1
+ run_id: 791
+ runner_id: 1
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ storage_path: "26/1/1712166500347189545.chunk"
+ file_size: 1024
+ file_compressed_size: 1024
+ content_encoding: ""
+ artifact_path: "abc.txt"
+ artifact_name: "artifact-download"
+ status: 1
+ created_unix: 1712338649
+ updated_unix: 1712338649
+ expired_unix: 1720114649
+
+-
+ id: 19
+ run_id: 791
+ runner_id: 1
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ storage_path: "26/19/1712348022422036662.chunk"
+ file_size: 1024
+ file_compressed_size: 1024
+ content_encoding: ""
+ artifact_path: "abc.txt"
+ artifact_name: "multi-file-download"
+ status: 2
+ created_unix: 1712348022
+ updated_unix: 1712348022
+ expired_unix: 1720124022
+
+-
+ id: 20
+ run_id: 791
+ runner_id: 1
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ storage_path: "26/20/1712348022423431524.chunk"
+ file_size: 1024
+ file_compressed_size: 1024
+ content_encoding: ""
+ artifact_path: "xyz/def.txt"
+ artifact_name: "multi-file-download"
+ status: 2
+ created_unix: 1712348022
+ updated_unix: 1712348022
+ expired_unix: 1720124022
+
+-
+ id: 22
+ run_id: 792
+ runner_id: 1
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ storage_path: "27/5/1730330775594233150.chunk"
+ file_size: 1024
+ file_compressed_size: 1024
+ content_encoding: "application/zip"
+ artifact_path: "artifact-v4-download.zip"
+ artifact_name: "artifact-v4-download"
+ status: 2
+ created_unix: 1730330775
+ updated_unix: 1730330775
+ expired_unix: 1738106775
diff --git a/models/fixtures/action_run.yml b/models/fixtures/action_run.yml
index 9c60b352f9..7a7bf34197 100644
--- a/models/fixtures/action_run.yml
+++ b/models/fixtures/action_run.yml
@@ -413,6 +413,44 @@
},
"total_commits": 0
}
+-
+ id: 793
+ title: "job output"
+ repo_id: 4
+ owner_id: 1
+ workflow_id: "test.yaml"
+ index: 189
+ trigger_user_id: 1
+ ref: "refs/heads/master"
+ commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0"
+ event: "push"
+ is_fork_pull_request: 0
+ status: 1
+ started: 1683636528
+ stopped: 1683636626
+ created: 1683636108
+ updated: 1683636626
+ need_approval: 0
+ approved_by: 0
+-
+ id: 794
+ title: "job output"
+ repo_id: 4
+ owner_id: 1
+ workflow_id: "test.yaml"
+ index: 190
+ trigger_user_id: 1
+ ref: "refs/heads/test"
+ commit_sha: "c2d72f548424103f01ee1dc02889c1e2bff816b0"
+ event: "push"
+ is_fork_pull_request: 0
+ status: 1
+ started: 1683636528
+ stopped: 1683636626
+ created: 1683636108
+ updated: 1683636626
+ need_approval: 0
+ approved_by: 0
-
id: 891
title: "update actions"
diff --git a/models/fixtures/action_run_job.yml b/models/fixtures/action_run_job.yml
index 0b02d0e17e..702c6bc832 100644
--- a/models/fixtures/action_run_job.yml
+++ b/models/fixtures/action_run_job.yml
@@ -26,6 +26,49 @@
status: 1
started: 1683636528
stopped: 1683636626
+-
+ id: 194
+ run_id: 793
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ is_fork_pull_request: 0
+ name: job1 (1)
+ attempt: 1
+ job_id: job1
+ task_id: 49
+ status: 1
+ started: 1683636528
+ stopped: 1683636626
+-
+ id: 195
+ run_id: 793
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ is_fork_pull_request: 0
+ name: job1 (2)
+ attempt: 1
+ job_id: job1
+ task_id: 50
+ status: 1
+ started: 1683636528
+ stopped: 1683636626
+-
+ id: 196
+ run_id: 793
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ is_fork_pull_request: 0
+ name: job2
+ attempt: 1
+ job_id: job2
+ needs: [job1]
+ task_id: 51
+ status: 5
+ started: 1683636528
+ stopped: 1683636626
-
id: 292
run_id: 891
@@ -40,3 +83,48 @@
status: 1
started: 1683636528
stopped: 1683636626
+-
+ id: 393
+ run_id: 891
+ repo_id: 1
+ owner_id: 1
+ commit_sha: 985f0301dba5e7b34be866819cd15ad3d8f508ee
+ is_fork_pull_request: 0
+ name: job_2
+ attempt: 1
+ job_id: job_2
+ task_id: 47
+ status: 5
+ runs_on: '["ubuntu-latest"]'
+ started: 1683636528
+ stopped: 1683636626
+-
+ id: 394
+ run_id: 891
+ repo_id: 1
+ owner_id: 2
+ commit_sha: 985f0301dba5e7b34be866819cd15ad3d8f508ee
+ is_fork_pull_request: 0
+ name: job_2
+ attempt: 1
+ job_id: job_2
+ task_id: 47
+ status: 5
+ runs_on: '["debian-latest"]'
+ started: 1683636528
+ stopped: 1683636626
+-
+ id: 395
+ run_id: 891
+ repo_id: 1
+ owner_id: 3
+ commit_sha: 985f0301dba5e7b34be866819cd15ad3d8f508ee
+ is_fork_pull_request: 0
+ name: job_2
+ attempt: 1
+ job_id: job_2
+ task_id: 47
+ status: 5
+ runs_on: '["fedora"]'
+ started: 1683636528
+ stopped: 1683636626
diff --git a/models/fixtures/action_runner.yml b/models/fixtures/action_runner.yml
index d2615f08eb..94deac998e 100644
--- a/models/fixtures/action_runner.yml
+++ b/models/fixtures/action_runner.yml
@@ -14,7 +14,7 @@
token_salt: "832f8529db6151a1c3c605dd7570b58f"
last_online: 0
last_active: 0
- agent_labels: '[""]'
+ agent_labels: '["woop", "doop"]'
created: 1716104432
updated: 1716104432
deleted: ~
diff --git a/models/fixtures/action_task.yml b/models/fixtures/action_task.yml
index 443effe08c..506a47d8a0 100644
--- a/models/fixtures/action_task.yml
+++ b/models/fixtures/action_task.yml
@@ -1,3 +1,22 @@
+-
+ id: 46
+ attempt: 3
+ runner_id: 1
+ status: 3 # 3 is the status code for "cancelled"
+ started: 1683636528
+ stopped: 1683636626
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ is_fork_pull_request: 0
+ token_hash: 6d8ef48297195edcc8e22c70b3020eaa06c52976db67d39b4260c64a69a2cc1508825121b7b8394e48e00b1bf8718b2aaaaa
+ token_salt: eeeeeeee
+ token_last_eight: eeeeeeee
+ log_filename: artifact-test2/2f/47.log
+ log_in_storage: 1
+ log_length: 707
+ log_size: 90179
+ log_expired: 0
-
id: 47
job_id: 192
@@ -38,3 +57,63 @@
log_length: 707
log_size: 90179
log_expired: 0
+-
+ id: 49
+ job_id: 194
+ attempt: 1
+ runner_id: 1
+ status: 1 # success
+ started: 1683636528
+ stopped: 1683636626
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ is_fork_pull_request: 0
+ token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784220
+ token_salt: ffffffffff
+ token_last_eight: ffffffff
+ log_filename: artifact-test2/2f/47.log
+ log_in_storage: 1
+ log_length: 707
+ log_size: 90179
+ log_expired: 0
+-
+ id: 50
+ job_id: 195
+ attempt: 1
+ runner_id: 1
+ status: 1 # success
+ started: 1683636528
+ stopped: 1683636626
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ is_fork_pull_request: 0
+ token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784221
+ token_salt: ffffffffff
+ token_last_eight: ffffffff
+ log_filename: artifact-test2/2f/47.log
+ log_in_storage: 1
+ log_length: 707
+ log_size: 90179
+ log_expired: 0
+-
+ id: 51
+ job_id: 196
+ attempt: 1
+ runner_id: 1
+ status: 6 # running
+ started: 1683636528
+ stopped: 1683636626
+ repo_id: 4
+ owner_id: 1
+ commit_sha: c2d72f548424103f01ee1dc02889c1e2bff816b0
+ is_fork_pull_request: 0
+ token_hash: b8d3962425466b6709b9ac51446f93260c54afe8e7b6d3686e34f991fb8a8953822b0deed86fe41a103f34bc48dbc4784222
+ token_salt: ffffffffff
+ token_last_eight: ffffffff
+ log_filename: artifact-test2/2f/47.log
+ log_in_storage: 1
+ log_length: 707
+ log_size: 90179
+ log_expired: 0
diff --git a/models/fixtures/action_task_output.yml b/models/fixtures/action_task_output.yml
new file mode 100644
index 0000000000..314e9f7115
--- /dev/null
+++ b/models/fixtures/action_task_output.yml
@@ -0,0 +1,20 @@
+-
+ id: 1
+ task_id: 49
+ output_key: output_a
+ output_value: abc
+-
+ id: 2
+ task_id: 49
+ output_key: output_b
+ output_value: ''
+-
+ id: 3
+ task_id: 50
+ output_key: output_a
+ output_value: ''
+-
+ id: 4
+ task_id: 50
+ output_key: output_b
+ output_value: bbb
diff --git a/models/fixtures/branch.yml b/models/fixtures/branch.yml
index 93003049c6..2a9e3105e6 100644
--- a/models/fixtures/branch.yml
+++ b/models/fixtures/branch.yml
@@ -45,3 +45,27 @@
is_deleted: false
deleted_by_id: 0
deleted_unix: 0
+
+-
+ id: 15
+ repo_id: 4
+ name: 'master'
+ commit_id: 'c7cd3cd144e6d23c9d6f3d07e52b2c1a956e0338'
+ commit_message: 'add Readme'
+ commit_time: 1588147171
+ pusher_id: 13
+ is_deleted: false
+ deleted_by_id: 0
+ deleted_unix: 0
+
+-
+ id: 16
+ repo_id: 62
+ name: 'main'
+ commit_id: '774f93df12d14931ea93259ae93418da4482fcc1'
+ commit_message: 'Add workflow test-dispatch.yml'
+ commit_time: 1717317522
+ pusher_id: 1
+ is_deleted: false
+ deleted_by_id: 0
+ deleted_unix: 0
diff --git a/models/fixtures/comment.yml b/models/fixtures/comment.yml
index fdf8908206..f4121284a6 100644
--- a/models/fixtures/comment.yml
+++ b/models/fixtures/comment.yml
@@ -14,6 +14,7 @@
content: "good work!"
created_unix: 946684811
updated_unix: 946684811
+ content_version: 1
-
id: 3
type: 0 # comment
@@ -33,6 +34,7 @@
tree_path: "README.md"
created_unix: 946684812
invalidated: false
+ content_version: 1
-
id: 5
type: 21 # code comment
@@ -92,3 +94,22 @@
content: "test markup light/dark-mode-only "
created_unix: 946684813
updated_unix: 946684813
+
+-
+ id: 11
+ type: 22 # review
+ poster_id: 5
+ issue_id: 3 # in repo_id 1
+ content: "reviewed by user5"
+ review_id: 21
+ created_unix: 946684816
+
+-
+ id: 12
+ type: 27 # review request
+ poster_id: 2
+ issue_id: 3 # in repo_id 1
+ content: "review request for user5"
+ review_id: 22
+ assignee_id: 5
+ created_unix: 946684817
diff --git a/models/fixtures/commit_status.yml b/models/fixtures/commit_status.yml
index 6b82e3fd67..c568e89cea 100644
--- a/models/fixtures/commit_status.yml
+++ b/models/fixtures/commit_status.yml
@@ -7,6 +7,7 @@
target_url: https://example.com/builds/
description: My awesome CI-service
context: ci/awesomeness
+ context_hash: c65f4d64a3b14a3eced0c9b36799e66e1bd5ced7
creator_id: 2
-
@@ -18,6 +19,7 @@
target_url: https://example.com/coverage/
description: My awesome Coverage service
context: cov/awesomeness
+ context_hash: 3929ac7bccd3fa1bf9b38ddedb77973b1b9a8cfe
creator_id: 2
-
@@ -29,6 +31,7 @@
target_url: https://example.com/coverage/
description: My awesome Coverage service
context: cov/awesomeness
+ context_hash: 3929ac7bccd3fa1bf9b38ddedb77973b1b9a8cfe
creator_id: 2
-
@@ -40,6 +43,7 @@
target_url: https://example.com/builds/
description: My awesome CI-service
context: ci/awesomeness
+ context_hash: c65f4d64a3b14a3eced0c9b36799e66e1bd5ced7
creator_id: 2
-
@@ -51,4 +55,41 @@
target_url: https://example.com/builds/
description: My awesome deploy service
context: deploy/awesomeness
+ context_hash: ae9547713a6665fc4261d0756904932085a41cf2
+ creator_id: 2
+
+-
+ id: 6
+ index: 1
+ repo_id: 62
+ state: "failure"
+ sha: "774f93df12d14931ea93259ae93418da4482fcc1"
+ target_url: "/user2/test_workflows/actions"
+ description: My awesome deploy service
+ context: deploy/awesomeness
+ context_hash: ae9547713a6665fc4261d0756904932085a41cf2
+ creator_id: 2
+
+-
+ id: 7
+ index: 6
+ repo_id: 1
+ state: "pending"
+ sha: "1234123412341234123412341234123412341234"
+ target_url: https://example.com/builds/
+ description: My awesome deploy service
+ context: deploy/awesomeness
+ context_hash: ae9547713a6665fc4261d0756904932085a41cf2
+ creator_id: 2
+
+-
+ id: 8
+ index: 2
+ repo_id: 62
+ state: "error"
+ sha: "774f93df12d14931ea93259ae93418da4482fcc1"
+ target_url: "/user2/test_workflows/actions"
+ description: "My awesome deploy service - v2"
+ context: deploy/awesomeness
+ context_hash: ae9547713a6665fc4261d0756904932085a41cf2
creator_id: 2
diff --git a/models/fixtures/federated_user.yml b/models/fixtures/federated_user.yml
new file mode 100644
index 0000000000..ca780a73aa
--- /dev/null
+++ b/models/fixtures/federated_user.yml
@@ -0,0 +1 @@
+[] # empty
diff --git a/models/fixtures/federation_host.yml b/models/fixtures/federation_host.yml
new file mode 100644
index 0000000000..ca780a73aa
--- /dev/null
+++ b/models/fixtures/federation_host.yml
@@ -0,0 +1 @@
+[] # empty
diff --git a/models/fixtures/label.yml b/models/fixtures/label.yml
index 2242b90dcd..acfac74968 100644
--- a/models/fixtures/label.yml
+++ b/models/fixtures/label.yml
@@ -96,3 +96,14 @@
num_issues: 0
num_closed_issues: 0
archived_unix: 0
+
+-
+ id: 10
+ repo_id: 3
+ org_id: 0
+ name: repo3label1
+ color: '#112233'
+ exclusive: false
+ num_issues: 0
+ num_closed_issues: 0
+ archived_unix: 0
diff --git a/models/fixtures/pull_request.yml b/models/fixtures/pull_request.yml
index 9a16316e5a..79051ffb6c 100644
--- a/models/fixtures/pull_request.yml
+++ b/models/fixtures/pull_request.yml
@@ -64,6 +64,8 @@
base_branch: branch2
merge_base: 985f0301dba5e7b34be866819cd15ad3d8f508ee
has_merged: false
+ allow_maintainer_edit: true
+ commits_behind: 1
-
id: 6
diff --git a/models/fixtures/repo_unit.yml b/models/fixtures/repo_unit.yml
index 6dac78f588..cd49a51796 100644
--- a/models/fixtures/repo_unit.yml
+++ b/models/fixtures/repo_unit.yml
@@ -788,3 +788,10 @@
type: 10
config: "{}"
created_unix: 946684810
+
+-
+ id: 114
+ repo_id: 4
+ type: 10
+ config: "{}"
+ created_unix: 946684810
diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml
index 845dae7fc1..0ba4d06e14 100644
--- a/models/fixtures/repository.yml
+++ b/models/fixtures/repository.yml
@@ -26,10 +26,11 @@
fork_id: 0
is_template: false
template_id: 0
- size: 7320
+ size: 7597
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
-
+ created_unix: 1731254961
+ updated_unix: 1731254961
-
id: 2
owner_id: 2
@@ -91,6 +92,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
+ created_unix: 1700000001
+ updated_unix: 1700000001
-
id: 4
@@ -129,6 +132,7 @@
owner_name: org3
lower_name: repo5
name: repo5
+ default_branch: master
num_watches: 0
num_stars: 0
num_forks: 0
@@ -152,6 +156,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
+ created_unix: 1700000002
+ updated_unix: 1700000002
-
id: 6
@@ -182,6 +188,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
+ created_unix: 1710000001
+ updated_unix: 1710000001
-
id: 7
@@ -212,6 +220,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
+ created_unix: 1710000003
+ updated_unix: 1710000003
-
id: 8
@@ -242,6 +252,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
+ created_unix: 1710000002
+ updated_unix: 1710000002
-
id: 9
@@ -968,6 +980,8 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
+ created_unix: 1700000003
+ updated_unix: 1700000003
-
id: 33
@@ -1811,4 +1825,4 @@
template_id: 0
size: 0
is_fsck_enabled: true
- close_issues_via_commit_in_any_branch: false
\ No newline at end of file
+ close_issues_via_commit_in_any_branch: false
diff --git a/models/fixtures/review.yml b/models/fixtures/review.yml
index ac97e24c2b..0438ceadae 100644
--- a/models/fixtures/review.yml
+++ b/models/fixtures/review.yml
@@ -179,3 +179,22 @@
content: "Review Comment"
updated_unix: 946684810
created_unix: 946684810
+
+-
+ id: 21
+ type: 2
+ reviewer_id: 5
+ issue_id: 3
+ content: "reviewed by user5"
+ commit_id: 4a357436d925b5c974181ff12a994538ddc5a269
+ updated_unix: 946684816
+ created_unix: 946684816
+
+-
+ id: 22
+ type: 4
+ reviewer_id: 5
+ issue_id: 3
+ content: "review request for user5"
+ updated_unix: 946684817
+ created_unix: 946684817
diff --git a/models/fixtures/secret.yml b/models/fixtures/secret.yml
new file mode 100644
index 0000000000..ca780a73aa
--- /dev/null
+++ b/models/fixtures/secret.yml
@@ -0,0 +1 @@
+[] # empty
diff --git a/models/fixtures/system_setting.yml b/models/fixtures/system_setting.yml
index 30542bc82a..dcad176c89 100644
--- a/models/fixtures/system_setting.yml
+++ b/models/fixtures/system_setting.yml
@@ -1,7 +1,7 @@
-
id: 1
setting_key: 'picture.disable_gravatar'
- setting_value: 'false'
+ setting_value: 'true'
version: 1
created: 1653533198
updated: 1653533198
diff --git a/models/fixtures/team_unit.yml b/models/fixtures/team_unit.yml
index de0e8d738b..e8f8d0e422 100644
--- a/models/fixtures/team_unit.yml
+++ b/models/fixtures/team_unit.yml
@@ -1,42 +1,49 @@
-
id: 1
team_id: 1
+ org_id: 3
type: 1
access_mode: 4
-
id: 2
team_id: 1
+ org_id: 3
type: 2
access_mode: 4
-
id: 3
team_id: 1
+ org_id: 3
type: 3
access_mode: 4
-
id: 4
team_id: 1
+ org_id: 3
type: 4
access_mode: 4
-
id: 5
team_id: 1
+ org_id: 3
type: 5
access_mode: 4
-
id: 6
team_id: 1
+ org_id: 3
type: 6
access_mode: 4
-
id: 7
team_id: 1
+ org_id: 3
type: 7
access_mode: 4
diff --git a/models/fixtures/two_factor.yml b/models/fixtures/two_factor.yml
index d8cb85274b..bca1109ea8 100644
--- a/models/fixtures/two_factor.yml
+++ b/models/fixtures/two_factor.yml
@@ -1,9 +1,9 @@
-
- id: 1
- uid: 24
- secret: KlDporn6Ile4vFcKI8z7Z6sqK1Scj2Qp0ovtUzCZO6jVbRW2lAoT7UDxDPtrab8d2B9zKOocBRdBJnS8orsrUNrsyETY+jJHb79M82uZRioKbRUz15sfOpmJmEzkFeSg6S4LicUBQos=
- scratch_salt: Qb5bq2DyR2
- scratch_hash: 068eb9b8746e0bcfe332fac4457693df1bda55800eb0f6894d14ebb736ae6a24e0fc8fc5333c19f57f81599788f0b8e51ec1
- last_used_passcode:
- created_unix: 1564253724
- updated_unix: 1564253724
+ id: 1
+ uid: 24
+ secret: MrAed+7K+fKQKu1l3aU45oTDSWK/i5Ugtgk8CmORrKWTMwa2w97rniLU+h+2xq8ZF+16uuXGLzjWa0bOV5xg4NY6w5Ec/tkwQ5rEecOTvc/JZV5lrrlDi48B7Y5/lNcjAWBmH2nEUlM=
+ scratch_salt: Qb5bq2DyR2
+ scratch_hash: 068eb9b8746e0bcfe332fac4457693df1bda55800eb0f6894d14ebb736ae6a24e0fc8fc5333c19f57f81599788f0b8e51ec1
+ last_used_passcode:
+ created_unix: 1564253724
+ updated_unix: 1564253724
diff --git a/models/fixtures/user.yml b/models/fixtures/user.yml
index 8e216fbc7d..630505b8b4 100644
--- a/models/fixtures/user.yml
+++ b/models/fixtures/user.yml
@@ -23,9 +23,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar1
+ avatar: ""
avatar_email: user1@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -36,6 +36,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578000
-
id: 2
@@ -44,6 +45,7 @@
full_name: ' < Ur Tw >< '
email: user2@example.com
keep_email_private: true
+ keep_pronouns_private: true
email_notifications_preference: enabled
passwd: ZogKvWdyEx:password
passwd_hash_algo: dummy
@@ -60,8 +62,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar2
+ avatar: ""
avatar_email: user2@example.com
+ # cause a random avatar to be generated when referenced for test purposes
use_custom_avatar: false
num_followers: 2
num_following: 1
@@ -73,6 +76,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578010
-
id: 3
@@ -97,9 +101,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar3
+ avatar: ""
avatar_email: org3@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -110,6 +114,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578020
-
id: 4
@@ -134,9 +139,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar4
+ avatar: ""
avatar_email: user4@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 1
num_stars: 0
@@ -147,6 +152,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578030
-
id: 5
@@ -171,9 +177,9 @@
allow_import_local: false
allow_create_organization: false
prohibit_login: false
- avatar: avatar5
+ avatar: ""
avatar_email: user5@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -184,6 +190,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578040
-
id: 6
@@ -208,9 +215,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar6
+ avatar: ""
avatar_email: org6@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -221,6 +228,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578050
-
id: 7
@@ -245,9 +253,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar7
+ avatar: ""
avatar_email: org7@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -258,6 +266,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578060
-
id: 8
@@ -282,9 +291,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar8
+ avatar: ""
avatar_email: user8@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 1
num_following: 1
num_stars: 0
@@ -295,6 +304,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578070
-
id: 9
@@ -319,9 +329,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar9
+ avatar: ""
avatar_email: user9@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -332,6 +342,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578080
-
id: 10
@@ -340,6 +351,7 @@
full_name: User Ten
email: user10@example.com
keep_email_private: false
+ keep_pronouns_private: true
email_notifications_preference: enabled
passwd: ZogKvWdyEx:password
passwd_hash_algo: dummy
@@ -356,9 +368,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar10
+ avatar: ""
avatar_email: user10@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -369,6 +381,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578090
-
id: 11
@@ -393,9 +406,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar11
+ avatar: ""
avatar_email: user11@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -406,6 +419,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578100
-
id: 12
@@ -430,9 +444,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar12
+ avatar: ""
avatar_email: user12@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -443,6 +457,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578110
-
id: 13
@@ -467,9 +482,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar13
+ avatar: ""
avatar_email: user13@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -480,6 +495,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578120
-
id: 14
@@ -504,9 +520,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar14
+ avatar: ""
avatar_email: user13@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -517,6 +533,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578130
-
id: 15
@@ -541,9 +558,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar15
+ avatar: ""
avatar_email: user15@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -554,6 +571,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578140
-
id: 16
@@ -578,9 +596,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar16
+ avatar: ""
avatar_email: user16@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -591,6 +609,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578150
-
id: 17
@@ -615,9 +634,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar17
+ avatar: ""
avatar_email: org17@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -628,6 +647,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578160
-
id: 18
@@ -652,9 +672,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar18
+ avatar: ""
avatar_email: user18@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -665,6 +685,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578170
-
id: 19
@@ -689,9 +710,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar19
+ avatar: ""
avatar_email: org19@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -702,6 +723,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578180
-
id: 20
@@ -726,9 +748,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar20
+ avatar: ""
avatar_email: user20@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -739,6 +761,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578190
-
id: 21
@@ -763,9 +786,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar21
+ avatar: ""
avatar_email: user21@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -776,6 +799,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578200
-
id: 22
@@ -800,9 +824,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar22
+ avatar: ""
avatar_email: limited_org@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -813,6 +837,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578210
-
id: 23
@@ -837,9 +862,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar23
+ avatar: ""
avatar_email: privated_org@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -850,6 +875,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578220
-
id: 24
@@ -874,9 +900,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar24
+ avatar: ""
avatar_email: user24@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -887,6 +913,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578230
-
id: 25
@@ -911,9 +938,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar25
+ avatar: ""
avatar_email: org25@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -924,6 +951,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578240
-
id: 26
@@ -948,9 +976,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar26
+ avatar: ""
avatar_email: org26@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -961,6 +989,7 @@
repo_admin_change_team_access: true
theme: ""
keep_activity_private: false
+ created_unix: 1672578250
-
id: 27
@@ -985,9 +1014,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar27
+ avatar: ""
avatar_email: user27@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -998,6 +1027,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578260
-
id: 28
@@ -1022,9 +1052,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar28
+ avatar: ""
avatar_email: user28@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1035,6 +1065,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578270
-
id: 29
@@ -1059,9 +1090,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar29
+ avatar: ""
avatar_email: user29@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1072,6 +1103,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578280
-
id: 30
@@ -1096,9 +1128,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar29
+ avatar: ""
avatar_email: user30@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1109,6 +1141,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578290
-
id: 31
@@ -1133,9 +1166,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar31
+ avatar: ""
avatar_email: user31@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 1
num_stars: 0
@@ -1146,6 +1179,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578300
-
id: 32
@@ -1170,9 +1204,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar32
+ avatar: ""
avatar_email: user30@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1183,6 +1217,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578310
-
id: 33
@@ -1207,9 +1242,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar33
+ avatar: ""
avatar_email: user33@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 1
num_following: 0
num_stars: 0
@@ -1220,6 +1255,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578320
-
id: 34
@@ -1245,7 +1281,7 @@
allow_import_local: false
allow_create_organization: false
prohibit_login: false
- avatar: avatar34
+ avatar: ""
avatar_email: user34@example.com
use_custom_avatar: true
num_followers: 0
@@ -1258,6 +1294,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578330
-
id: 35
@@ -1282,9 +1319,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar35
+ avatar: ""
avatar_email: private_org35@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1295,6 +1332,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578340
-
id: 36
@@ -1319,9 +1357,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar22
+ avatar: ""
avatar_email: abcde@gitea.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1332,6 +1370,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578350
-
id: 37
@@ -1356,9 +1395,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: true
- avatar: avatar29
+ avatar: ""
avatar_email: user37@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1369,6 +1408,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578360
-
id: 38
@@ -1393,9 +1433,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar38
+ avatar: ""
avatar_email: user38@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1406,6 +1446,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578370
-
id: 39
@@ -1430,9 +1471,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar39
+ avatar: ""
avatar_email: user39@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1443,6 +1484,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578380
-
id: 40
@@ -1467,9 +1509,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar40
+ avatar: ""
avatar_email: user40@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1480,6 +1522,7 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578390
-
id: 41
@@ -1504,9 +1547,9 @@
allow_import_local: false
allow_create_organization: true
prohibit_login: false
- avatar: avatar41
+ avatar: ""
avatar_email: org41@example.com
- use_custom_avatar: false
+ use_custom_avatar: true
num_followers: 0
num_following: 0
num_stars: 0
@@ -1517,3 +1560,4 @@
repo_admin_change_team_access: false
theme: ""
keep_activity_private: false
+ created_unix: 1672578400
diff --git a/models/fixtures/user_redirect.yml b/models/fixtures/user_redirect.yml
index 8ff7993398..f471e94511 100644
--- a/models/fixtures/user_redirect.yml
+++ b/models/fixtures/user_redirect.yml
@@ -2,3 +2,4 @@
id: 1
lower_name: olduser1
redirect_user_id: 1
+ created_unix: 1730000000
diff --git a/models/fixtures/webauthn_credential.yml b/models/fixtures/webauthn_credential.yml
index bc43127fcd..edf9935ebf 100644
--- a/models/fixtures/webauthn_credential.yml
+++ b/models/fixtures/webauthn_credential.yml
@@ -5,5 +5,6 @@
attestation_type: none
sign_count: 0
clone_warning: false
+ legacy: true
created_unix: 946684800
updated_unix: 946684800
diff --git a/models/forgefed/federationhost.go b/models/forgefed/federationhost.go
index b60c0c39cf..00f13ea399 100644
--- a/models/forgefed/federationhost.go
+++ b/models/forgefed/federationhost.go
@@ -8,8 +8,8 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/validation"
)
// FederationHost data type
diff --git a/models/forgefed/federationhost_repository.go b/models/forgefed/federationhost_repository.go
index 03d8741c58..b04a5cd882 100644
--- a/models/forgefed/federationhost_repository.go
+++ b/models/forgefed/federationhost_repository.go
@@ -8,8 +8,8 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/validation"
)
func init() {
diff --git a/models/forgefed/federationhost_test.go b/models/forgefed/federationhost_test.go
index ea5494c6e9..7e48a41d3b 100644
--- a/models/forgefed/federationhost_test.go
+++ b/models/forgefed/federationhost_test.go
@@ -8,7 +8,7 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
)
func Test_FederationHostValidation(t *testing.T) {
diff --git a/models/forgefed/nodeinfo.go b/models/forgefed/nodeinfo.go
index 66d2eca7aa..2461b5e499 100644
--- a/models/forgefed/nodeinfo.go
+++ b/models/forgefed/nodeinfo.go
@@ -6,7 +6,7 @@ package forgefed
import (
"net/url"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
"github.com/valyala/fastjson"
)
diff --git a/models/forgefed/nodeinfo_test.go b/models/forgefed/nodeinfo_test.go
index 4c73bb44d8..9e37e77100 100644
--- a/models/forgefed/nodeinfo_test.go
+++ b/models/forgefed/nodeinfo_test.go
@@ -9,7 +9,7 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
)
func Test_NodeInfoWellKnownUnmarshalJSON(t *testing.T) {
diff --git a/models/forgejo/semver/main_test.go b/models/forgejo/semver/main_test.go
index fa56182627..dcc9d588cd 100644
--- a/models/forgejo/semver/main_test.go
+++ b/models/forgejo/semver/main_test.go
@@ -5,11 +5,12 @@ package semver
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/models/forgejo/semver/semver.go b/models/forgejo/semver/semver.go
index 7f122d2301..24a3db9181 100644
--- a/models/forgejo/semver/semver.go
+++ b/models/forgejo/semver/semver.go
@@ -5,7 +5,7 @@ package semver
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
"github.com/hashicorp/go-version"
)
diff --git a/models/forgejo/semver/semver_test.go b/models/forgejo/semver/semver_test.go
index 8aca7bee57..2d055e86bb 100644
--- a/models/forgejo/semver/semver_test.go
+++ b/models/forgejo/semver/semver_test.go
@@ -5,42 +5,43 @@ package semver
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/hashicorp/go-version"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestForgejoSemVerSetGet(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
ctx := db.DefaultContext
newVersion, err := version.NewVersion("v1.2.3")
- assert.NoError(t, err)
- assert.NoError(t, SetVersionString(ctx, newVersion.String()))
+ require.NoError(t, err)
+ require.NoError(t, SetVersionString(ctx, newVersion.String()))
databaseVersion, err := GetVersion(ctx)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, newVersion.String(), databaseVersion.String())
assert.True(t, newVersion.Equal(databaseVersion))
}
func TestForgejoSemVerMissing(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
ctx := db.DefaultContext
e := db.GetEngine(ctx)
_, err := e.Exec("delete from forgejo_sem_ver")
- assert.NoError(t, err)
+ require.NoError(t, err)
v, err := GetVersion(ctx)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "1.0.0", v.String())
_, err = e.Exec("drop table forgejo_sem_ver")
- assert.NoError(t, err)
+ require.NoError(t, err)
v, err = GetVersion(ctx)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "1.0.0", v.String())
}
diff --git a/models/forgejo_migrations/main_test.go b/models/forgejo_migrations/main_test.go
index 42579f8194..031fe8090d 100644
--- a/models/forgejo_migrations/main_test.go
+++ b/models/forgejo_migrations/main_test.go
@@ -6,9 +6,9 @@ package forgejo_migrations //nolint:revive
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/forgejo_migrations/migrate.go b/models/forgejo_migrations/migrate.go
index 78c13f33a0..a4cbca70c1 100644
--- a/models/forgejo_migrations/migrate.go
+++ b/models/forgejo_migrations/migrate.go
@@ -8,12 +8,12 @@ import (
"fmt"
"os"
- "code.gitea.io/gitea/models/forgejo/semver"
- forgejo_v1_20 "code.gitea.io/gitea/models/forgejo_migrations/v1_20"
- forgejo_v1_22 "code.gitea.io/gitea/models/forgejo_migrations/v1_22"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/forgejo/semver"
+ forgejo_v1_20 "forgejo.org/models/forgejo_migrations/v1_20"
+ forgejo_v1_22 "forgejo.org/models/forgejo_migrations/v1_22"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
"xorm.io/xorm/names"
@@ -58,22 +58,42 @@ var migrations = []*Migration{
NewMigration("Add the `apply_to_admins` column to the `protected_branch` table", forgejo_v1_22.AddApplyToAdminsSetting),
// v9 -> v10
NewMigration("Add pronouns to user", forgejo_v1_22.AddPronounsToUser),
- // v11 -> v12
+ // v10 -> v11
NewMigration("Add the `created` column to the `issue` table", forgejo_v1_22.AddCreatedToIssue),
- // v12 -> v13
+ // v11 -> v12
NewMigration("Add repo_archive_download_count table", forgejo_v1_22.AddRepoArchiveDownloadCount),
- // v13 -> v14
+ // v12 -> v13
NewMigration("Add `hide_archive_links` column to `release` table", AddHideArchiveLinksToRelease),
- // v14 -> v15
+ // v13 -> v14
NewMigration("Remove Gitea-specific columns from the repository and badge tables", RemoveGiteaSpecificColumnsFromRepositoryAndBadge),
- // v15 -> v16
+ // v14 -> v15
NewMigration("Create the `federation_host` table", CreateFederationHostTable),
- // v16 -> v17
+ // v15 -> v16
NewMigration("Create the `federated_user` table", CreateFederatedUserTable),
- // v17 -> v18
+ // v16 -> v17
NewMigration("Add `normalized_federated_uri` column to `user` table", AddNormalizedFederatedURIToUser),
- // v18 -> v19
+ // v17 -> v18
NewMigration("Create the `following_repo` table", CreateFollowingRepoTable),
+ // v18 -> v19
+ NewMigration("Add external_url to attachment table", AddExternalURLColumnToAttachmentTable),
+ // v19 -> v20
+ NewMigration("Creating Quota-related tables", CreateQuotaTables),
+ // v20 -> v21
+ NewMigration("Add SSH keypair to `pull_mirror` table", AddSSHKeypairToPushMirror),
+ // v21 -> v22
+ NewMigration("Add `legacy` to `web_authn_credential` table", AddLegacyToWebAuthnCredential),
+ // v22 -> v23
+ NewMigration("Add `delete_branch_after_merge` to `auto_merge` table", AddDeleteBranchAfterMergeToAutoMerge),
+ // v23 -> v24
+ NewMigration("Add `purpose` column to `forgejo_auth_token` table", AddPurposeToForgejoAuthToken),
+ // v24 -> v25
+ NewMigration("Migrate `secret` column to store keying material", MigrateTwoFactorToKeying),
+ // v25 -> v26
+ NewMigration("Add `hash_blake2b` column to `package_blob` table", AddHashBlake2bToPackageBlob),
+ // v26 -> v27
+ NewMigration("Add `created_unix` column to `user_redirect` table", AddCreatedUnixToRedirect),
+ // v27 -> v28
+ NewMigration("Add pronoun privacy settings to user", AddHidePronounsOptionToUser),
}
// GetCurrentDBVersion returns the current Forgejo database version.
diff --git a/models/forgejo_migrations/migrate_test.go b/models/forgejo_migrations/migrate_test.go
index 2ae3c39fce..20653929a3 100644
--- a/models/forgejo_migrations/migrate_test.go
+++ b/models/forgejo_migrations/migrate_test.go
@@ -6,14 +6,14 @@ package forgejo_migrations //nolint:revive
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
// TestEnsureUpToDate tests the behavior of EnsureUpToDate.
func TestEnsureUpToDate(t *testing.T) {
- x, deferable := base.PrepareTestEnv(t, 0, new(ForgejoVersion))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(ForgejoVersion))
defer deferable()
if x == nil || t.Failed() {
return
@@ -21,19 +21,19 @@ func TestEnsureUpToDate(t *testing.T) {
// Ensure error if there's no row in Forgejo Version.
err := EnsureUpToDate(x)
- assert.Error(t, err)
+ require.Error(t, err)
// Insert 'good' Forgejo Version row.
_, err = x.InsertOne(&ForgejoVersion{ID: 1, Version: ExpectedVersion()})
- assert.NoError(t, err)
+ require.NoError(t, err)
err = EnsureUpToDate(x)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Modify forgejo version to have a lower version.
_, err = x.Exec("UPDATE `forgejo_version` SET version = ? WHERE id = 1", ExpectedVersion()-1)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = EnsureUpToDate(x)
- assert.Error(t, err)
+ require.Error(t, err)
}
diff --git a/models/forgejo_migrations/v14.go b/models/forgejo_migrations/v14.go
index f6dd35ecf0..53f1ef2223 100644
--- a/models/forgejo_migrations/v14.go
+++ b/models/forgejo_migrations/v14.go
@@ -4,7 +4,7 @@
package forgejo_migrations //nolint:revive
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/forgejo_migrations/v15.go b/models/forgejo_migrations/v15.go
index d7ed19ca7c..5e5588dd05 100644
--- a/models/forgejo_migrations/v15.go
+++ b/models/forgejo_migrations/v15.go
@@ -6,7 +6,7 @@ package forgejo_migrations //nolint:revive
import (
"time"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/forgejo_migrations/v18.go b/models/forgejo_migrations/v18.go
index afccfbfe15..e6c1493f0e 100644
--- a/models/forgejo_migrations/v18.go
+++ b/models/forgejo_migrations/v18.go
@@ -14,5 +14,5 @@ type FollowingRepo struct {
}
func CreateFollowingRepoTable(x *xorm.Engine) error {
- return x.Sync(new(FederatedUser))
+ return x.Sync(new(FollowingRepo))
}
diff --git a/models/forgejo_migrations/v19.go b/models/forgejo_migrations/v19.go
new file mode 100644
index 0000000000..69b7746eb1
--- /dev/null
+++ b/models/forgejo_migrations/v19.go
@@ -0,0 +1,14 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import "xorm.io/xorm"
+
+func AddExternalURLColumnToAttachmentTable(x *xorm.Engine) error {
+ type Attachment struct {
+ ID int64 `xorm:"pk autoincr"`
+ ExternalURL string
+ }
+ return x.Sync(new(Attachment))
+}
diff --git a/models/forgejo_migrations/v1_20/v1.go b/models/forgejo_migrations/v1_20/v1.go
index 1097613655..72beaf23de 100644
--- a/models/forgejo_migrations/v1_20/v1.go
+++ b/models/forgejo_migrations/v1_20/v1.go
@@ -4,7 +4,7 @@
package forgejo_v1_20 //nolint:revive
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/forgejo_migrations/v1_20/v3.go b/models/forgejo_migrations/v1_20/v3.go
index caa4f1aa99..cce227e6eb 100644
--- a/models/forgejo_migrations/v1_20/v3.go
+++ b/models/forgejo_migrations/v1_20/v3.go
@@ -4,7 +4,7 @@
package forgejo_v1_20 //nolint:revive
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/forgejo_migrations/v1_22/main_test.go b/models/forgejo_migrations/v1_22/main_test.go
index 8ca5395a26..03c4c5272c 100644
--- a/models/forgejo_migrations/v1_22/main_test.go
+++ b/models/forgejo_migrations/v1_22/main_test.go
@@ -6,9 +6,9 @@ package v1_22 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/forgejo_migrations/v1_22/v11.go b/models/forgejo_migrations/v1_22/v11.go
index c693993565..17bb592379 100644
--- a/models/forgejo_migrations/v1_22/v11.go
+++ b/models/forgejo_migrations/v1_22/v11.go
@@ -4,7 +4,7 @@
package v1_22 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/forgejo_migrations/v1_22/v8_test.go b/models/forgejo_migrations/v1_22/v8_test.go
index b8cd478daa..2af9e431b1 100644
--- a/models/forgejo_migrations/v1_22/v8_test.go
+++ b/models/forgejo_migrations/v1_22/v8_test.go
@@ -6,9 +6,10 @@ package v1_22 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_RemoveSSHSignaturesFromReleaseNotes(t *testing.T) {
@@ -18,14 +19,14 @@ func Test_RemoveSSHSignaturesFromReleaseNotes(t *testing.T) {
Note string `xorm:"TEXT"`
}
- x, deferable := base.PrepareTestEnv(t, 0, new(Release))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(Release))
defer deferable()
- assert.NoError(t, RemoveSSHSignaturesFromReleaseNotes(x))
+ require.NoError(t, RemoveSSHSignaturesFromReleaseNotes(x))
var releases []Release
err := x.Table("release").OrderBy("id ASC").Find(&releases)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, releases, 3)
assert.Equal(t, "", releases[0].Note)
diff --git a/models/forgejo_migrations/v20.go b/models/forgejo_migrations/v20.go
new file mode 100644
index 0000000000..8ca9e91f73
--- /dev/null
+++ b/models/forgejo_migrations/v20.go
@@ -0,0 +1,52 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import "xorm.io/xorm"
+
+type (
+ QuotaLimitSubject int
+ QuotaLimitSubjects []QuotaLimitSubject
+
+ QuotaKind int
+)
+
+type QuotaRule struct {
+ Name string `xorm:"pk not null"`
+ Limit int64 `xorm:"NOT NULL"`
+ Subjects QuotaLimitSubjects
+}
+
+type QuotaGroup struct {
+ Name string `xorm:"pk NOT NULL"`
+}
+
+type QuotaGroupRuleMapping struct {
+ ID int64 `xorm:"pk autoincr"`
+ GroupName string `xorm:"index unique(qgrm_gr) not null"`
+ RuleName string `xorm:"unique(qgrm_gr) not null"`
+}
+
+type QuotaGroupMapping struct {
+ ID int64 `xorm:"pk autoincr"`
+ Kind QuotaKind `xorm:"unique(qgm_kmg) not null"`
+ MappedID int64 `xorm:"unique(qgm_kmg) not null"`
+ GroupName string `xorm:"index unique(qgm_kmg) not null"`
+}
+
+func CreateQuotaTables(x *xorm.Engine) error {
+ if err := x.Sync(new(QuotaRule)); err != nil {
+ return err
+ }
+
+ if err := x.Sync(new(QuotaGroup)); err != nil {
+ return err
+ }
+
+ if err := x.Sync(new(QuotaGroupRuleMapping)); err != nil {
+ return err
+ }
+
+ return x.Sync(new(QuotaGroupMapping))
+}
diff --git a/models/forgejo_migrations/v21.go b/models/forgejo_migrations/v21.go
new file mode 100644
index 0000000000..53f141b2ab
--- /dev/null
+++ b/models/forgejo_migrations/v21.go
@@ -0,0 +1,16 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import "xorm.io/xorm"
+
+func AddSSHKeypairToPushMirror(x *xorm.Engine) error {
+ type PushMirror struct {
+ ID int64 `xorm:"pk autoincr"`
+ PublicKey string `xorm:"VARCHAR(100)"`
+ PrivateKey []byte `xorm:"BLOB"`
+ }
+
+ return x.Sync(&PushMirror{})
+}
diff --git a/models/forgejo_migrations/v22.go b/models/forgejo_migrations/v22.go
new file mode 100644
index 0000000000..eeb738799c
--- /dev/null
+++ b/models/forgejo_migrations/v22.go
@@ -0,0 +1,17 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import "xorm.io/xorm"
+
+func AddLegacyToWebAuthnCredential(x *xorm.Engine) error {
+ type WebauthnCredential struct {
+ ID int64 `xorm:"pk autoincr"`
+ BackupEligible bool `xorm:"NOT NULL DEFAULT false"`
+ BackupState bool `xorm:"NOT NULL DEFAULT false"`
+ Legacy bool `xorm:"NOT NULL DEFAULT true"`
+ }
+
+ return x.Sync(&WebauthnCredential{})
+}
diff --git a/models/forgejo_migrations/v23.go b/models/forgejo_migrations/v23.go
new file mode 100644
index 0000000000..20a916a716
--- /dev/null
+++ b/models/forgejo_migrations/v23.go
@@ -0,0 +1,16 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import "xorm.io/xorm"
+
+// AddDeleteBranchAfterMergeToAutoMerge: add DeleteBranchAfterMerge column, setting existing rows to false
+func AddDeleteBranchAfterMergeToAutoMerge(x *xorm.Engine) error {
+ type AutoMerge struct {
+ ID int64 `xorm:"pk autoincr"`
+ DeleteBranchAfterMerge bool `xorm:"NOT NULL DEFAULT false"`
+ }
+
+ return x.Sync(&AutoMerge{})
+}
diff --git a/models/forgejo_migrations/v24.go b/models/forgejo_migrations/v24.go
new file mode 100644
index 0000000000..ebfb5fc1c4
--- /dev/null
+++ b/models/forgejo_migrations/v24.go
@@ -0,0 +1,19 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import "xorm.io/xorm"
+
+func AddPurposeToForgejoAuthToken(x *xorm.Engine) error {
+ type ForgejoAuthToken struct {
+ ID int64 `xorm:"pk autoincr"`
+ Purpose string `xorm:"NOT NULL DEFAULT 'long_term_authorization'"`
+ }
+ if err := x.Sync(new(ForgejoAuthToken)); err != nil {
+ return err
+ }
+
+ _, err := x.Exec("UPDATE `forgejo_auth_token` SET purpose = 'long_term_authorization' WHERE purpose = ''")
+ return err
+}
diff --git a/models/forgejo_migrations/v25.go b/models/forgejo_migrations/v25.go
new file mode 100644
index 0000000000..8e3032a40c
--- /dev/null
+++ b/models/forgejo_migrations/v25.go
@@ -0,0 +1,96 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import (
+ "context"
+ "crypto/md5"
+ "encoding/base64"
+ "fmt"
+
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/secret"
+ "forgejo.org/modules/setting"
+
+ "xorm.io/xorm"
+ "xorm.io/xorm/schemas"
+)
+
+func MigrateTwoFactorToKeying(x *xorm.Engine) error {
+ var err error
+
+ // When upgrading from Forgejo v9 to v10, this migration will already be
+ // called from models/migrations/migrations.go migration 304 and must not
+ // be run twice.
+ var version int
+ _, err = x.Table("version").Where("`id` = 1").Select("version").Get(&version)
+ if err != nil {
+ // the version table does not exist when a test environment only applies Forgejo migrations
+ } else if version > 304 {
+ return nil
+ }
+
+ switch x.Dialect().URI().DBType {
+ case schemas.MYSQL:
+ _, err = x.Exec("ALTER TABLE `two_factor` MODIFY `secret` BLOB")
+ case schemas.SQLITE:
+ _, err = x.Exec("ALTER TABLE `two_factor` RENAME COLUMN `secret` TO `secret_backup`")
+ if err != nil {
+ return err
+ }
+ _, err = x.Exec("ALTER TABLE `two_factor` ADD COLUMN `secret` BLOB")
+ if err != nil {
+ return err
+ }
+ _, err = x.Exec("UPDATE `two_factor` SET `secret` = `secret_backup`")
+ if err != nil {
+ return err
+ }
+ _, err = x.Exec("ALTER TABLE `two_factor` DROP COLUMN `secret_backup`")
+ case schemas.POSTGRES:
+ _, err = x.Exec("ALTER TABLE `two_factor` ALTER COLUMN `secret` SET DATA TYPE bytea USING secret::text::bytea")
+ }
+ if err != nil {
+ return err
+ }
+
+ oldEncryptionKey := md5.Sum([]byte(setting.SecretKey))
+
+ messages := make([]string, 0, 100)
+ ids := make([]int64, 0, 100)
+
+ err = db.Iterate(context.Background(), nil, func(ctx context.Context, bean *auth.TwoFactor) error {
+ decodedStoredSecret, err := base64.StdEncoding.DecodeString(string(bean.Secret))
+ if err != nil {
+ messages = append(messages, fmt.Sprintf("two_factor.id=%d, two_factor.uid=%d: base64.StdEncoding.DecodeString: %v", bean.ID, bean.UID, err))
+ ids = append(ids, bean.ID)
+ return nil
+ }
+
+ secretBytes, err := secret.AesDecrypt(oldEncryptionKey[:], decodedStoredSecret)
+ if err != nil {
+ messages = append(messages, fmt.Sprintf("two_factor.id=%d, two_factor.uid=%d: secret.AesDecrypt: %v", bean.ID, bean.UID, err))
+ ids = append(ids, bean.ID)
+ return nil
+ }
+
+ bean.SetSecret(string(secretBytes))
+ _, err = db.GetEngine(ctx).Cols("secret").ID(bean.ID).Update(bean)
+ return err
+ })
+ if err == nil {
+ if len(ids) > 0 {
+ log.Error("Forgejo migration[25]: The following TOTP secrets were found to be corrupted and removed from the database. TOTP is no longer required to login with the associated users. They should be informed because they will need to visit their security settings and configure TOTP again. No other action is required. See https://codeberg.org/forgejo/forgejo/issues/6637 for more context on the various causes for such a corruption.")
+ for _, message := range messages {
+ log.Error("Forgejo migration[25]: %s", message)
+ }
+
+ _, err = db.GetEngine(context.Background()).In("id", ids).NoAutoCondition().NoAutoTime().Delete(&auth.TwoFactor{})
+ }
+ }
+
+ return err
+}
diff --git a/models/forgejo_migrations/v25_test.go b/models/forgejo_migrations/v25_test.go
new file mode 100644
index 0000000000..e7402fd021
--- /dev/null
+++ b/models/forgejo_migrations/v25_test.go
@@ -0,0 +1,54 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import (
+ "testing"
+
+ "forgejo.org/models/auth"
+ migration_tests "forgejo.org/models/migrations/test"
+ "forgejo.org/modules/keying"
+ "forgejo.org/modules/timeutil"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func Test_MigrateTwoFactorToKeying(t *testing.T) {
+ type TwoFactor struct { //revive:disable-line:exported
+ ID int64 `xorm:"pk autoincr"`
+ UID int64 `xorm:"UNIQUE"`
+ Secret string
+ ScratchSalt string
+ ScratchHash string
+ LastUsedPasscode string `xorm:"VARCHAR(10)"`
+ CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"`
+ UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
+ }
+
+ // Prepare and load the testing database
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(TwoFactor))
+ defer deferable()
+ if x == nil || t.Failed() {
+ return
+ }
+
+ cnt, err := x.Table("two_factor").Count()
+ require.NoError(t, err)
+ assert.EqualValues(t, 2, cnt)
+
+ require.NoError(t, MigrateTwoFactorToKeying(x))
+
+ cnt, err = x.Table("two_factor").Count()
+ require.NoError(t, err)
+ assert.EqualValues(t, 1, cnt)
+
+ var twofactor auth.TwoFactor
+ _, err = x.Table("two_factor").ID(1).Get(&twofactor)
+ require.NoError(t, err)
+
+ secretBytes, err := keying.DeriveKey(keying.ContextTOTP).Decrypt(twofactor.Secret, keying.ColumnAndID("secret", twofactor.ID))
+ require.NoError(t, err)
+ assert.Equal(t, []byte("AVDYS32OPIAYSNBG2NKYV4AHBVEMKKKIGBQ46OXTLMJO664G4TIECOGEANMSNBLS"), secretBytes)
+}
diff --git a/models/forgejo_migrations/v26.go b/models/forgejo_migrations/v26.go
new file mode 100644
index 0000000000..3292d93ffd
--- /dev/null
+++ b/models/forgejo_migrations/v26.go
@@ -0,0 +1,14 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import "xorm.io/xorm"
+
+func AddHashBlake2bToPackageBlob(x *xorm.Engine) error {
+ type PackageBlob struct {
+ ID int64 `xorm:"pk autoincr"`
+ HashBlake2b string `xorm:"hash_blake2b char(128) UNIQUE(blake2b) INDEX"`
+ }
+ return x.Sync(&PackageBlob{})
+}
diff --git a/models/forgejo_migrations/v27.go b/models/forgejo_migrations/v27.go
new file mode 100644
index 0000000000..2efa3485a8
--- /dev/null
+++ b/models/forgejo_migrations/v27.go
@@ -0,0 +1,18 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package forgejo_migrations //nolint:revive
+
+import (
+ "forgejo.org/modules/timeutil"
+
+ "xorm.io/xorm"
+)
+
+func AddCreatedUnixToRedirect(x *xorm.Engine) error {
+ type UserRedirect struct {
+ ID int64 `xorm:"pk autoincr"`
+ CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL DEFAULT 0"`
+ }
+ return x.Sync(new(UserRedirect))
+}
diff --git a/models/forgejo_migrations/v28.go b/models/forgejo_migrations/v28.go
new file mode 100644
index 0000000000..cba888d2ec
--- /dev/null
+++ b/models/forgejo_migrations/v28.go
@@ -0,0 +1,15 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgejo_migrations //nolint:revive
+
+import "xorm.io/xorm"
+
+func AddHidePronounsOptionToUser(x *xorm.Engine) error {
+ type User struct {
+ ID int64 `xorm:"pk autoincr"`
+ KeepPronounsPrivate bool `xorm:"NOT NULL DEFAULT false"`
+ }
+
+ return x.Sync(&User{})
+}
diff --git a/models/git/branch.go b/models/git/branch.go
index 7e1c96d769..a73a0f2a20 100644
--- a/models/git/branch.go
+++ b/models/git/branch.go
@@ -8,13 +8,14 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -162,9 +163,22 @@ func GetBranch(ctx context.Context, repoID int64, branchName string) (*Branch, e
return &branch, nil
}
-func GetBranches(ctx context.Context, repoID int64, branchNames []string) ([]*Branch, error) {
+func GetBranches(ctx context.Context, repoID int64, branchNames []string, includeDeleted bool) ([]*Branch, error) {
branches := make([]*Branch, 0, len(branchNames))
- return branches, db.GetEngine(ctx).Where("repo_id=?", repoID).In("name", branchNames).Find(&branches)
+
+ sess := db.GetEngine(ctx).Where("repo_id=?", repoID).In("name", branchNames)
+ if !includeDeleted {
+ sess.And("is_deleted=?", false)
+ }
+ return branches, sess.Find(&branches)
+}
+
+func BranchesToNamesSet(branches []*Branch) container.Set[string] {
+ names := make(container.Set[string], len(branches))
+ for _, branch := range branches {
+ names.Add(branch.Name)
+ }
+ return names
}
func AddBranches(ctx context.Context, branches []*Branch) error {
@@ -385,6 +399,13 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, from, to str
return err
}
+ // 4.1 Update all not merged pull request head branch name
+ if _, err = sess.Table("pull_request").Where("head_repo_id=? AND head_branch=? AND has_merged=?",
+ repo.ID, from, false).
+ Update(map[string]any{"head_branch": to}); err != nil {
+ return err
+ }
+
// 5. insert renamed branch record
renamedBranch := &RenamedBranch{
RepoID: repo.ID,
@@ -410,15 +431,18 @@ func FindRecentlyPushedNewBranches(ctx context.Context, repoID, userID int64, ex
branches := make(BranchList, 0, 2)
subQuery := builder.Select("head_branch").From("pull_request").
InnerJoin("issue", "issue.id = pull_request.issue_id").
- Where(builder.Eq{
- "pull_request.head_repo_id": repoID,
- "issue.is_closed": false,
- })
+ Where(builder.And(
+ builder.Eq{"pull_request.head_repo_id": repoID},
+ builder.Or(
+ builder.Eq{"pull_request.has_merged": true},
+ builder.Eq{"issue.is_closed": false},
+ ),
+ ))
err := db.GetEngine(ctx).
Where("pusher_id=? AND is_deleted=?", userID, false).
And("name <> ?", excludeBranchName).
And("repo_id = ?", repoID).
- And("commit_time >= ?", time.Now().Add(-time.Hour*6).Unix()).
+ And("commit_time >= ?", time.Now().Add(-time.Minute*30).Unix()).
NotIn("name", subQuery).
OrderBy("branch.commit_time DESC").
Limit(2).
diff --git a/models/git/branch_list.go b/models/git/branch_list.go
index 81a43eaea3..4b678f15c0 100644
--- a/models/git/branch_list.go
+++ b/models/git/branch_list.go
@@ -6,10 +6,10 @@ package git
import (
"context"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/optional"
"xorm.io/builder"
)
diff --git a/models/git/branch_test.go b/models/git/branch_test.go
index 3aa578f44b..5c1762750e 100644
--- a/models/git/branch_test.go
+++ b/models/git/branch_test.go
@@ -7,26 +7,27 @@ import (
"context"
"testing"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/optional"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestAddDeletedBranch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.EqualValues(t, git.Sha1ObjectFormat.Name(), repo.ObjectFormatName)
firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 1})
assert.True(t, firstBranch.IsDeleted)
- assert.NoError(t, git_model.AddDeletedBranch(db.DefaultContext, repo.ID, firstBranch.Name, firstBranch.DeletedByID))
- assert.NoError(t, git_model.AddDeletedBranch(db.DefaultContext, repo.ID, "branch2", int64(1)))
+ require.NoError(t, git_model.AddDeletedBranch(db.DefaultContext, repo.ID, firstBranch.Name, firstBranch.DeletedByID))
+ require.NoError(t, git_model.AddDeletedBranch(db.DefaultContext, repo.ID, "branch2", int64(1)))
secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{RepoID: repo.ID, Name: "branch2"})
assert.True(t, secondBranch.IsDeleted)
@@ -40,11 +41,11 @@ func TestAddDeletedBranch(t *testing.T) {
}
_, err := git_model.UpdateBranch(db.DefaultContext, repo.ID, secondBranch.PusherID, secondBranch.Name, commit)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func TestGetDeletedBranches(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
branches, err := db.Find[git_model.Branch](db.DefaultContext, git_model.FindBranchOptions{
@@ -52,19 +53,19 @@ func TestGetDeletedBranches(t *testing.T) {
RepoID: repo.ID,
IsDeletedBranch: optional.Some(true),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, branches, 2)
}
func TestGetDeletedBranch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 1})
assert.NotNil(t, getDeletedBranch(t, firstBranch))
}
func TestDeletedBranchLoadUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 1})
secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 2})
@@ -83,13 +84,13 @@ func TestDeletedBranchLoadUser(t *testing.T) {
}
func TestRemoveDeletedBranch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 1})
err := git_model.RemoveDeletedBranchByID(db.DefaultContext, repo.ID, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertNotExistsBean(t, firstBranch)
unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 2})
}
@@ -98,7 +99,7 @@ func getDeletedBranch(t *testing.T, branch *git_model.Branch) *git_model.Branch
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
deletedBranch, err := git_model.GetDeletedBranchByID(db.DefaultContext, repo.ID, branch.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, branch.ID, deletedBranch.ID)
assert.Equal(t, branch.Name, deletedBranch.Name)
assert.Equal(t, branch.CommitID, deletedBranch.CommitID)
@@ -108,32 +109,32 @@ func getDeletedBranch(t *testing.T, branch *git_model.Branch) *git_model.Branch
}
func TestFindRenamedBranch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
branch, exist, err := git_model.FindRenamedBranch(db.DefaultContext, 1, "dev")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
assert.Equal(t, "master", branch.To)
_, exist, err = git_model.FindRenamedBranch(db.DefaultContext, 1, "unknow")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, exist)
}
func TestRenameBranch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
_isDefault := false
ctx, committer, err := db.TxContext(db.DefaultContext)
defer committer.Close()
- assert.NoError(t, err)
- assert.NoError(t, git_model.UpdateProtectBranch(ctx, repo1, &git_model.ProtectedBranch{
+ require.NoError(t, err)
+ require.NoError(t, git_model.UpdateProtectBranch(ctx, repo1, &git_model.ProtectedBranch{
RepoID: repo1.ID,
RuleName: "master",
}, git_model.WhitelistOptions{}))
- assert.NoError(t, committer.Commit())
+ require.NoError(t, committer.Commit())
- assert.NoError(t, git_model.RenameBranch(db.DefaultContext, repo1, "master", "main", func(ctx context.Context, isDefault bool) error {
+ require.NoError(t, git_model.RenameBranch(db.DefaultContext, repo1, "master", "main", func(ctx context.Context, isDefault bool) error {
_isDefault = isDefault
return nil
}))
@@ -160,7 +161,7 @@ func TestRenameBranch(t *testing.T) {
}
func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Get deletedBranch with ID of 1 on repo with ID 2.
// This should return a nil branch as this deleted branch
@@ -170,7 +171,7 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) {
deletedBranch, err := git_model.GetDeletedBranchByID(db.DefaultContext, repo2.ID, 1)
// Expect error, and the returned branch is nil.
- assert.Error(t, err)
+ require.Error(t, err)
assert.Nil(t, deletedBranch)
// Now get the deletedBranch with ID of 1 on repo with ID 1.
@@ -180,15 +181,15 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) {
deletedBranch, err = git_model.GetDeletedBranchByID(db.DefaultContext, repo1.ID, 1)
// Expect no error, and the returned branch to be not nil.
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, deletedBranch)
}
func TestFindBranchesByRepoAndBranchName(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// With no repos or branches given, we find no branches.
branches, err := git_model.FindBranchesByRepoAndBranchName(db.DefaultContext, map[int64]string{})
- assert.NoError(t, err)
- assert.Len(t, branches, 0)
+ require.NoError(t, err)
+ assert.Empty(t, branches)
}
diff --git a/models/git/commit_status.go b/models/git/commit_status.go
index d975f0572c..a679703ffd 100644
--- a/models/git/commit_status.go
+++ b/models/git/commit_status.go
@@ -13,16 +13,16 @@ import (
"strings"
"time"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/translation"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/translation"
"xorm.io/builder"
"xorm.io/xorm"
@@ -141,13 +141,17 @@ func GetNextCommitStatusIndex(ctx context.Context, repoID int64, sha string) (in
return newIdx, nil
}
-func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) {
+func (status *CommitStatus) loadRepository(ctx context.Context) (err error) {
if status.Repo == nil {
status.Repo, err = repo_model.GetRepositoryByID(ctx, status.RepoID)
if err != nil {
return fmt.Errorf("getRepositoryByID [%d]: %w", status.RepoID, err)
}
}
+ return nil
+}
+
+func (status *CommitStatus) loadCreator(ctx context.Context) (err error) {
if status.Creator == nil && status.CreatorID > 0 {
status.Creator, err = user_model.GetUserByID(ctx, status.CreatorID)
if err != nil {
@@ -157,6 +161,13 @@ func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) {
return nil
}
+func (status *CommitStatus) loadAttributes(ctx context.Context) (err error) {
+ if err := status.loadRepository(ctx); err != nil {
+ return err
+ }
+ return status.loadCreator(ctx)
+}
+
// APIURL returns the absolute APIURL to this commit-status.
func (status *CommitStatus) APIURL(ctx context.Context) string {
_ = status.loadAttributes(ctx)
@@ -168,6 +179,25 @@ func (status *CommitStatus) LocaleString(lang translation.Locale) string {
return lang.TrString("repo.commitstatus." + status.State.String())
}
+// HideActionsURL set `TargetURL` to an empty string if the status comes from Gitea Actions
+func (status *CommitStatus) HideActionsURL(ctx context.Context) {
+ if status.RepoID == 0 {
+ return
+ }
+
+ if status.Repo == nil {
+ if err := status.loadRepository(ctx); err != nil {
+ log.Error("loadRepository: %v", err)
+ return
+ }
+ }
+
+ prefix := fmt.Sprintf("%s/actions", status.Repo.Link())
+ if strings.HasPrefix(status.TargetURL, prefix) {
+ status.TargetURL = ""
+ }
+}
+
// CalcCommitStatus returns commit status state via some status, the commit statues should order by id desc
func CalcCommitStatus(statuses []*CommitStatus) *CommitStatus {
if len(statuses) == 0 {
@@ -258,16 +288,12 @@ func GetLatestCommitStatus(ctx context.Context, repoID int64, sha string, listOp
// GetLatestCommitStatusForPairs returns all statuses with a unique context for a given list of repo-sha pairs
func GetLatestCommitStatusForPairs(ctx context.Context, repoSHAs []RepoSHA) (map[int64][]*CommitStatus, error) {
- type result struct {
- Index int64
- RepoID int64
- SHA string
- }
+ results := []*CommitStatus{}
+ repoStatuses := make(map[int64][]*CommitStatus)
- results := make([]result, 0, len(repoSHAs))
-
- getBase := func() *xorm.Session {
- return db.GetEngine(ctx).Table(&CommitStatus{})
+ if len(repoSHAs) == 0 {
+ // Avoid performing query when there will be no query conditions added.
+ return repoStatuses, nil
}
// Create a disjunction of conditions for each repoID and SHA pair
@@ -275,38 +301,30 @@ func GetLatestCommitStatusForPairs(ctx context.Context, repoSHAs []RepoSHA) (map
for _, repoSHA := range repoSHAs {
conds = append(conds, builder.Eq{"repo_id": repoSHA.RepoID, "sha": repoSHA.SHA})
}
- sess := getBase().Where(builder.Or(conds...)).
- Select("max( `index` ) as `index`, repo_id, sha").
- GroupBy("context_hash, repo_id, sha").OrderBy("max( `index` ) desc")
+ subquery := builder.Dialect(db.BuilderDialect()).
+ Select("context_hash, repo_id, sha, MAX(`index`) AS max_index").
+ From("commit_status").
+ Where(builder.Or(conds...)).
+ GroupBy("context_hash, repo_id, sha")
+
+ sess := db.GetEngine(ctx).
+ Table(&CommitStatus{}).
+ Alias("c").
+ Join(
+ "INNER",
+ subquery,
+ "c.context_hash = commit_status.context_hash AND c.repo_id = commit_status.repo_id AND c.sha = commit_status.sha AND c.`index` = commit_status.max_index",
+ ).
+ OrderBy("c.`index` DESC")
err := sess.Find(&results)
if err != nil {
return nil, err
}
- repoStatuses := make(map[int64][]*CommitStatus)
-
- if len(results) > 0 {
- statuses := make([]*CommitStatus, 0, len(results))
-
- conds = make([]builder.Cond, 0, len(results))
- for _, result := range results {
- cond := builder.Eq{
- "`index`": result.Index,
- "repo_id": result.RepoID,
- "sha": result.SHA,
- }
- conds = append(conds, cond)
- }
- err = getBase().Where(builder.Or(conds...)).Find(&statuses)
- if err != nil {
- return nil, err
- }
-
- // Group the statuses by repo ID
- for _, status := range statuses {
- repoStatuses[status.RepoID] = append(repoStatuses[status.RepoID], status)
- }
+ // Group the statuses by repo ID
+ for _, status := range results {
+ repoStatuses[status.RepoID] = append(repoStatuses[status.RepoID], status)
}
return repoStatuses, nil
@@ -318,6 +336,12 @@ func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, co
Index int64
SHA string
}
+ repoStatuses := make(map[string][]*CommitStatus)
+
+ if len(commitIDs) == 0 {
+ // Avoid performing query when there will be no `sha` query conditions added.
+ return repoStatuses, nil
+ }
getBase := func() *xorm.Session {
return db.GetEngine(ctx).Table(&CommitStatus{}).Where("repo_id = ?", repoID)
@@ -337,8 +361,6 @@ func GetLatestCommitStatusForRepoCommitIDs(ctx context.Context, repoID int64, co
return nil, err
}
- repoStatuses := make(map[string][]*CommitStatus)
-
if len(results) > 0 {
statuses := make([]*CommitStatus, 0, len(results))
@@ -471,3 +493,19 @@ func ConvertFromGitCommit(ctx context.Context, commits []*git.Commit, repo *repo
repo,
)
}
+
+// CommitStatusesHideActionsURL hide Gitea Actions urls
+func CommitStatusesHideActionsURL(ctx context.Context, statuses []*CommitStatus) {
+ idToRepos := make(map[int64]*repo_model.Repository)
+ for _, status := range statuses {
+ if status == nil {
+ continue
+ }
+
+ if status.Repo == nil {
+ status.Repo = idToRepos[status.RepoID]
+ }
+ status.HideActionsURL(ctx)
+ idToRepos[status.RepoID] = status.Repo
+ }
+}
diff --git a/models/git/commit_status_summary.go b/models/git/commit_status_summary.go
index 7603e7aa65..448aa5aed7 100644
--- a/models/git/commit_status_summary.go
+++ b/models/git/commit_status_summary.go
@@ -6,9 +6,9 @@ package git
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
"xorm.io/builder"
)
diff --git a/models/git/commit_status_test.go b/models/git/commit_status_test.go
index 2ada8b3724..c062bbbbb9 100644
--- a/models/git/commit_status_test.go
+++ b/models/git/commit_status_test.go
@@ -4,23 +4,26 @@
package git_test
import (
+ "fmt"
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/structs"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/structs"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetCommitStatuses(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
@@ -31,9 +34,9 @@ func TestGetCommitStatuses(t *testing.T) {
RepoID: repo1.ID,
SHA: sha1,
})
- assert.NoError(t, err)
- assert.Equal(t, int(maxResults), 5)
- assert.Len(t, statuses, 5)
+ require.NoError(t, err)
+ assert.EqualValues(t, 6, maxResults)
+ assert.Len(t, statuses, 6)
assert.Equal(t, "ci/awesomeness", statuses[0].Context)
assert.Equal(t, structs.CommitStatusPending, statuses[0].State)
@@ -55,13 +58,17 @@ func TestGetCommitStatuses(t *testing.T) {
assert.Equal(t, structs.CommitStatusError, statuses[4].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[4].APIURL(db.DefaultContext))
+ assert.Equal(t, "deploy/awesomeness", statuses[5].Context)
+ assert.Equal(t, structs.CommitStatusPending, statuses[5].State)
+ assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[5].APIURL(db.DefaultContext))
+
statuses, maxResults, err = db.FindAndCount[git_model.CommitStatus](db.DefaultContext, &git_model.CommitStatusOptions{
ListOptions: db.ListOptions{Page: 2, PageSize: 50},
RepoID: repo1.ID,
SHA: sha1,
})
- assert.NoError(t, err)
- assert.Equal(t, int(maxResults), 5)
+ require.NoError(t, err)
+ assert.EqualValues(t, 6, maxResults)
assert.Empty(t, statuses)
}
@@ -189,16 +196,16 @@ func Test_CalcCommitStatus(t *testing.T) {
}
func TestFindRepoRecentCommitStatusContexts(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
gitRepo, err := gitrepo.OpenRepository(git.DefaultContext, repo2)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer gitRepo.Close()
commit, err := gitRepo.GetBranchCommit(repo2.DefaultBranch)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer func() {
_, err := db.DeleteByBean(db.DefaultContext, &git_model.CommitStatus{
@@ -206,7 +213,7 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) {
CreatorID: user2.ID,
SHA: commit.ID.String(),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
}()
err = git_model.NewCommitStatus(db.DefaultContext, git_model.NewCommitStatusOptions{
@@ -219,7 +226,7 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) {
Context: "compliance/lint-backend",
},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
err = git_model.NewCommitStatus(db.DefaultContext, git_model.NewCommitStatusOptions{
Repo: repo2,
@@ -231,11 +238,34 @@ func TestFindRepoRecentCommitStatusContexts(t *testing.T) {
Context: "compliance/lint-backend",
},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
contexts, err := git_model.FindRepoRecentCommitStatusContexts(db.DefaultContext, repo2.ID, time.Hour)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, contexts, 1) {
assert.Equal(t, "compliance/lint-backend", contexts[0])
}
}
+
+func TestCommitStatusesHideActionsURL(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
+ run := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{ID: 791, RepoID: repo.ID})
+ require.NoError(t, run.LoadAttributes(db.DefaultContext))
+
+ statuses := []*git_model.CommitStatus{
+ {
+ RepoID: repo.ID,
+ TargetURL: fmt.Sprintf("%s/jobs/%d", run.Link(), run.Index),
+ },
+ {
+ RepoID: repo.ID,
+ TargetURL: "https://mycicd.org/1",
+ },
+ }
+
+ git_model.CommitStatusesHideActionsURL(db.DefaultContext, statuses)
+ assert.Empty(t, statuses[0].TargetURL)
+ assert.Equal(t, "https://mycicd.org/1", statuses[1].TargetURL)
+}
diff --git a/models/git/lfs.go b/models/git/lfs.go
index 44b741c4c8..9ec1ca7d8a 100644
--- a/models/git/lfs.go
+++ b/models/git/lfs.go
@@ -7,16 +7,16 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -136,8 +136,6 @@ var ErrLFSObjectNotExist = db.ErrNotExist{Resource: "LFS Meta object"}
// NewLFSMetaObject stores a given populated LFSMetaObject structure in the database
// if it is not already present.
func NewLFSMetaObject(ctx context.Context, repoID int64, p lfs.Pointer) (*LFSMetaObject, error) {
- var err error
-
ctx, committer, err := db.TxContext(ctx)
if err != nil {
return nil, err
diff --git a/models/git/lfs_lock.go b/models/git/lfs_lock.go
index 2f65833fe3..9dc0a947c3 100644
--- a/models/git/lfs_lock.go
+++ b/models/git/lfs_lock.go
@@ -6,26 +6,28 @@ package git
import (
"context"
"errors"
+ "fmt"
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
// LFSLock represents a git lfs lock of repository.
type LFSLock struct {
- ID int64 `xorm:"pk autoincr"`
- RepoID int64 `xorm:"INDEX NOT NULL"`
- OwnerID int64 `xorm:"INDEX NOT NULL"`
- Path string `xorm:"TEXT"`
- Created time.Time `xorm:"created"`
+ ID int64 `xorm:"pk autoincr"`
+ RepoID int64 `xorm:"INDEX NOT NULL"`
+ OwnerID int64 `xorm:"INDEX NOT NULL"`
+ Owner *user_model.User `xorm:"-"`
+ Path string `xorm:"TEXT"`
+ Created time.Time `xorm:"created"`
}
func init() {
@@ -37,6 +39,35 @@ func (l *LFSLock) BeforeInsert() {
l.Path = util.PathJoinRel(l.Path)
}
+// LoadAttributes loads attributes of the lock.
+func (l *LFSLock) LoadAttributes(ctx context.Context) error {
+ // Load owner
+ if err := l.LoadOwner(ctx); err != nil {
+ return fmt.Errorf("load owner: %w", err)
+ }
+
+ return nil
+}
+
+// LoadOwner loads owner of the lock.
+func (l *LFSLock) LoadOwner(ctx context.Context) error {
+ if l.Owner != nil {
+ return nil
+ }
+
+ owner, err := user_model.GetUserByID(ctx, l.OwnerID)
+ if err != nil {
+ if user_model.IsErrUserNotExist(err) {
+ l.Owner = user_model.NewGhostUser()
+ return nil
+ }
+ return err
+ }
+ l.Owner = owner
+
+ return nil
+}
+
// CreateLFSLock creates a new lock.
func CreateLFSLock(ctx context.Context, repo *repo_model.Repository, lock *LFSLock) (*LFSLock, error) {
dbCtx, committer, err := db.TxContext(ctx)
@@ -94,7 +125,7 @@ func GetLFSLockByID(ctx context.Context, id int64) (*LFSLock, error) {
}
// GetLFSLockByRepoID returns a list of locks of repository.
-func GetLFSLockByRepoID(ctx context.Context, repoID int64, page, pageSize int) ([]*LFSLock, error) {
+func GetLFSLockByRepoID(ctx context.Context, repoID int64, page, pageSize int) (LFSLockList, error) {
e := db.GetEngine(ctx)
if page >= 0 && pageSize > 0 {
start := 0
@@ -103,7 +134,7 @@ func GetLFSLockByRepoID(ctx context.Context, repoID int64, page, pageSize int) (
}
e.Limit(pageSize, start)
}
- lfsLocks := make([]*LFSLock, 0, pageSize)
+ lfsLocks := make(LFSLockList, 0, pageSize)
return lfsLocks, e.Find(&lfsLocks, &LFSLock{RepoID: repoID})
}
diff --git a/models/git/lfs_lock_list.go b/models/git/lfs_lock_list.go
new file mode 100644
index 0000000000..ffa4db21c4
--- /dev/null
+++ b/models/git/lfs_lock_list.go
@@ -0,0 +1,54 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package git
+
+import (
+ "context"
+ "fmt"
+
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+)
+
+// LFSLockList is a list of LFSLock
+type LFSLockList []*LFSLock
+
+// LoadAttributes loads the attributes for the given locks
+func (locks LFSLockList) LoadAttributes(ctx context.Context) error {
+ if len(locks) == 0 {
+ return nil
+ }
+
+ if err := locks.LoadOwner(ctx); err != nil {
+ return fmt.Errorf("load owner: %w", err)
+ }
+
+ return nil
+}
+
+// LoadOwner loads the owner of the locks
+func (locks LFSLockList) LoadOwner(ctx context.Context) error {
+ if len(locks) == 0 {
+ return nil
+ }
+
+ usersIDs := container.FilterSlice(locks, func(lock *LFSLock) (int64, bool) {
+ return lock.OwnerID, true
+ })
+ users := make(map[int64]*user_model.User, len(usersIDs))
+ if err := db.GetEngine(ctx).
+ In("id", usersIDs).
+ Find(&users); err != nil {
+ return fmt.Errorf("find users: %w", err)
+ }
+ for _, v := range locks {
+ v.Owner = users[v.OwnerID]
+ if v.Owner == nil { // not exist
+ v.Owner = user_model.NewGhostUser()
+ }
+ }
+
+ return nil
+}
diff --git a/models/git/lfs_test.go b/models/git/lfs_test.go
index 565b2e9303..af5e1abd90 100644
--- a/models/git/lfs_test.go
+++ b/models/git/lfs_test.go
@@ -5,26 +5,20 @@ package git
import (
"context"
- "path/filepath"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIterateRepositoryIDsWithLFSMetaObjects(t *testing.T) {
- defer unittest.OverrideFixtures(
- unittest.FixturesOptions{
- Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
- Base: setting.AppWorkPath,
- Dirs: []string{"models/git/TestIterateRepositoryIDsWithLFSMetaObjects/"},
- },
- )()
- assert.NoError(t, unittest.PrepareTestDatabase())
+ defer unittest.OverrideFixtures("models/git/TestIterateRepositoryIDsWithLFSMetaObjects")()
+ require.NoError(t, unittest.PrepareTestDatabase())
type repocount struct {
repoid int64
@@ -40,7 +34,7 @@ func TestIterateRepositoryIDsWithLFSMetaObjects(t *testing.T) {
cases = append(cases, repocount{repoID, count})
return nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, expected, cases)
})
@@ -52,13 +46,13 @@ func TestIterateRepositoryIDsWithLFSMetaObjects(t *testing.T) {
cases = append(cases, repocount{repoID, count})
return nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, expected, cases)
})
}
func TestIterateLFSMetaObjectsForRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
expectedIDs := []int64{1, 2, 3, 4}
@@ -70,7 +64,7 @@ func TestIterateLFSMetaObjectsForRepo(t *testing.T) {
actualIDs = append(actualIDs, lo.ID)
return nil
}, &IterateLFSMetaObjectsForRepoOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, expectedIDs, actualIDs)
})
@@ -82,7 +76,7 @@ func TestIterateLFSMetaObjectsForRepo(t *testing.T) {
actualIDs = append(actualIDs, lo.ID)
return nil
}, &IterateLFSMetaObjectsForRepoOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, expectedIDs, actualIDs)
t.Run("Batch handles updates", func(t *testing.T) {
@@ -91,10 +85,10 @@ func TestIterateLFSMetaObjectsForRepo(t *testing.T) {
err := IterateLFSMetaObjectsForRepo(db.DefaultContext, 54, func(ctx context.Context, lo *LFSMetaObject) error {
actualIDs = append(actualIDs, lo.ID)
_, err := db.DeleteByID[LFSMetaObject](ctx, lo.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
return nil
}, &IterateLFSMetaObjectsForRepoOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, expectedIDs, actualIDs)
})
})
diff --git a/models/git/main_test.go b/models/git/main_test.go
index aab1fa9a26..63a3c363ab 100644
--- a/models/git/main_test.go
+++ b/models/git/main_test.go
@@ -6,11 +6,12 @@ package git_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/models/git/protected_branch.go b/models/git/protected_branch.go
index a8b8c81bbe..c1eb750230 100644
--- a/models/git/protected_branch.go
+++ b/models/git/protected_branch.go
@@ -10,16 +10,16 @@ import (
"slices"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"github.com/gobwas/glob"
"github.com/gobwas/glob/syntax"
@@ -79,14 +79,20 @@ func IsRuleNameSpecial(ruleName string) bool {
}
func (protectBranch *ProtectedBranch) loadGlob() {
- if protectBranch.globRule == nil {
- var err error
- protectBranch.globRule, err = glob.Compile(protectBranch.RuleName, '/')
- if err != nil {
- log.Warn("Invalid glob rule for ProtectedBranch[%d]: %s %v", protectBranch.ID, protectBranch.RuleName, err)
- protectBranch.globRule = glob.MustCompile(glob.QuoteMeta(protectBranch.RuleName), '/')
- }
- protectBranch.isPlainName = !IsRuleNameSpecial(protectBranch.RuleName)
+ if protectBranch.isPlainName || protectBranch.globRule != nil {
+ return
+ }
+ // detect if it is not glob
+ if !IsRuleNameSpecial(protectBranch.RuleName) {
+ protectBranch.isPlainName = true
+ return
+ }
+ // now we load the glob
+ var err error
+ protectBranch.globRule, err = glob.Compile(protectBranch.RuleName, '/')
+ if err != nil {
+ log.Warn("Invalid glob rule for ProtectedBranch[%d]: %s %v", protectBranch.ID, protectBranch.RuleName, err)
+ protectBranch.globRule = glob.MustCompile(glob.QuoteMeta(protectBranch.RuleName), '/')
}
}
diff --git a/models/git/protected_branch_list.go b/models/git/protected_branch_list.go
index 613333a5a2..c7a3154884 100644
--- a/models/git/protected_branch_list.go
+++ b/models/git/protected_branch_list.go
@@ -7,8 +7,8 @@ import (
"context"
"sort"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/optional"
"github.com/gobwas/glob"
)
diff --git a/models/git/protected_banch_list_test.go b/models/git/protected_branch_list_test.go
similarity index 73%
rename from models/git/protected_banch_list_test.go
rename to models/git/protected_branch_list_test.go
index 4bb3136d58..db7e54f685 100644
--- a/models/git/protected_banch_list_test.go
+++ b/models/git/protected_branch_list_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestBranchRuleMatchPriority(t *testing.T) {
@@ -67,10 +68,39 @@ func TestBranchRuleMatchPriority(t *testing.T) {
matchedPB := pbs.GetFirstMatched(kase.BranchName)
if matchedPB == nil {
if kase.ExpectedMatchIdx >= 0 {
- assert.Error(t, fmt.Errorf("no matched rules but expected %s[%d]", kase.Rules[kase.ExpectedMatchIdx], kase.ExpectedMatchIdx))
+ require.Error(t, fmt.Errorf("no matched rules but expected %s[%d]", kase.Rules[kase.ExpectedMatchIdx], kase.ExpectedMatchIdx))
}
} else {
assert.EqualValues(t, kase.Rules[kase.ExpectedMatchIdx], matchedPB.RuleName)
}
}
}
+
+func TestBranchRuleSort(t *testing.T) {
+ in := []*ProtectedBranch{{
+ RuleName: "b",
+ CreatedUnix: 1,
+ }, {
+ RuleName: "b/*",
+ CreatedUnix: 3,
+ }, {
+ RuleName: "a/*",
+ CreatedUnix: 2,
+ }, {
+ RuleName: "c",
+ CreatedUnix: 0,
+ }, {
+ RuleName: "a",
+ CreatedUnix: 4,
+ }}
+ expect := []string{"c", "b", "a", "a/*", "b/*"}
+
+ pbr := ProtectedBranchRules(in)
+ pbr.sort()
+
+ var got []string
+ for i := range pbr {
+ got = append(got, pbr[i].RuleName)
+ }
+ assert.Equal(t, expect, got)
+}
diff --git a/models/git/protected_branch_test.go b/models/git/protected_branch_test.go
index 1962859a8c..278fa9fee4 100644
--- a/models/git/protected_branch_test.go
+++ b/models/git/protected_branch_test.go
@@ -4,7 +4,6 @@
package git
import (
- "fmt"
"testing"
"github.com/stretchr/testify/assert"
@@ -65,14 +64,6 @@ func TestBranchRuleMatch(t *testing.T) {
for _, kase := range kases {
pb := ProtectedBranch{RuleName: kase.Rule}
- var should, infact string
- if !kase.ExpectedMatch {
- should = " not"
- } else {
- infact = " not"
- }
- assert.EqualValues(t, kase.ExpectedMatch, pb.Match(kase.BranchName),
- fmt.Sprintf("%s should%s match %s but it is%s", kase.BranchName, should, kase.Rule, infact),
- )
+ assert.EqualValues(t, kase.ExpectedMatch, pb.Match(kase.BranchName), "%s - %s", kase.BranchName, kase.Rule)
}
}
diff --git a/models/git/protected_tag.go b/models/git/protected_tag.go
index 9a6646c742..eeaae41868 100644
--- a/models/git/protected_tag.go
+++ b/models/git/protected_tag.go
@@ -9,9 +9,9 @@ import (
"slices"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/modules/timeutil"
"github.com/gobwas/glob"
)
diff --git a/models/git/protected_tag_test.go b/models/git/protected_tag_test.go
index 164c33e28f..eec13fdc1f 100644
--- a/models/git/protected_tag_test.go
+++ b/models/git/protected_tag_test.go
@@ -6,41 +6,42 @@ package git_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIsUserAllowed(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pt := &git_model.ProtectedTag{}
allowed, err := git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, allowed)
pt = &git_model.ProtectedTag{
AllowlistUserIDs: []int64{1},
}
allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, allowed)
allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, allowed)
pt = &git_model.ProtectedTag{
AllowlistTeamIDs: []int64{1},
}
allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, allowed)
allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, allowed)
pt = &git_model.ProtectedTag{
@@ -48,11 +49,11 @@ func TestIsUserAllowed(t *testing.T) {
AllowlistTeamIDs: []int64{1},
}
allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, allowed)
allowed, err = git_model.IsUserAllowedModifyTag(db.DefaultContext, pt, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, allowed)
}
@@ -136,7 +137,7 @@ func TestIsUserAllowedToControlTag(t *testing.T) {
for n, c := range cases {
isAllowed, err := git_model.IsUserAllowedToControlTag(db.DefaultContext, protectedTags, c.name, c.userid)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, c.allowed, isAllowed, "case %d: error should match", n)
}
})
@@ -158,7 +159,7 @@ func TestIsUserAllowedToControlTag(t *testing.T) {
for n, c := range cases {
isAllowed, err := git_model.IsUserAllowedToControlTag(db.DefaultContext, protectedTags, c.name, c.userid)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, c.allowed, isAllowed, "case %d: error should match", n)
}
})
diff --git a/models/issues/TestGetUIDsAndStopwatch/stopwatch.yml b/models/issues/TestGetUIDsAndStopwatch/stopwatch.yml
new file mode 100644
index 0000000000..f564e4b389
--- /dev/null
+++ b/models/issues/TestGetUIDsAndStopwatch/stopwatch.yml
@@ -0,0 +1,11 @@
+-
+ id: 3
+ user_id: 1
+ issue_id: 2
+ created_unix: 1500988004
+
+-
+ id: 4
+ user_id: 3
+ issue_id: 0
+ created_unix: 1500988003
diff --git a/models/issues/action_aggregator.go b/models/issues/action_aggregator.go
new file mode 100644
index 0000000000..cf5be753f1
--- /dev/null
+++ b/models/issues/action_aggregator.go
@@ -0,0 +1,375 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package issues
+
+import (
+ "slices"
+
+ "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+)
+
+type ActionAggregator struct {
+ StartUnix int64
+ AggAge int64
+ PosterID int64
+ StartInd int
+ EndInd int
+
+ PrevClosed bool
+ IsClosed bool
+
+ AddedLabels []*Label
+ RemovedLabels []*Label
+
+ AddedRequestReview []RequestReviewTarget
+ RemovedRequestReview []RequestReviewTarget
+}
+
+// Get the time threshold for aggregation of multiple actions together
+func (agg *ActionAggregator) timeThreshold() int64 {
+ if agg.AggAge > (60 * 60 * 24 * 30) { // Age > 1 month, aggregate by day
+ return 60 * 60 * 24
+ } else if agg.AggAge > (60 * 60 * 24) { // Age > 1 day, aggregate by hour
+ return 60 * 60
+ } else if agg.AggAge > (60 * 60) { // Age > 1 hour, aggregate by 10 mins
+ return 60 * 10
+ }
+ // Else, aggregate by minute
+ return 60
+}
+
+// TODO Aggregate also
+// - Dependency added / removed
+// - Added / Removed due date
+// - Milestone Added / Removed
+func (agg *ActionAggregator) aggregateAction(c *Comment, index int) {
+ if agg.StartInd == -1 {
+ agg.StartInd = index
+ }
+ agg.EndInd = index
+
+ if c.Type == CommentTypeClose {
+ agg.IsClosed = true
+ } else if c.Type == CommentTypeReopen {
+ agg.IsClosed = false
+ } else if c.Type == CommentTypeReviewRequest {
+ if c.AssigneeID > 0 {
+ req := RequestReviewTarget{User: c.Assignee}
+ if c.RemovedAssignee {
+ agg.delReviewRequest(req)
+ } else {
+ agg.addReviewRequest(req)
+ }
+ } else if c.AssigneeTeamID > 0 {
+ req := RequestReviewTarget{Team: c.AssigneeTeam}
+ if c.RemovedAssignee {
+ agg.delReviewRequest(req)
+ } else {
+ agg.addReviewRequest(req)
+ }
+ }
+
+ for _, r := range c.RemovedRequestReview {
+ agg.delReviewRequest(r)
+ }
+
+ for _, r := range c.AddedRequestReview {
+ agg.addReviewRequest(r)
+ }
+ } else if c.Type == CommentTypeLabel {
+ if c.Content == "1" {
+ agg.addLabel(c.Label)
+ } else {
+ agg.delLabel(c.Label)
+ }
+ } else if c.Type == CommentTypeAggregator {
+ agg.Merge(c.Aggregator)
+ }
+}
+
+// Merge a past CommentAggregator with the next one in the issue comments list
+func (agg *ActionAggregator) Merge(next *ActionAggregator) {
+ agg.IsClosed = next.IsClosed
+
+ for _, l := range next.AddedLabels {
+ agg.addLabel(l)
+ }
+
+ for _, l := range next.RemovedLabels {
+ agg.delLabel(l)
+ }
+
+ for _, r := range next.AddedRequestReview {
+ agg.addReviewRequest(r)
+ }
+
+ for _, r := range next.RemovedRequestReview {
+ agg.delReviewRequest(r)
+ }
+}
+
+// Check if a comment can be aggregated or not depending on its type
+func (agg *ActionAggregator) IsAggregated(t *CommentType) bool {
+ switch *t {
+ case CommentTypeAggregator, CommentTypeClose, CommentTypeReopen, CommentTypeLabel, CommentTypeReviewRequest:
+ {
+ return true
+ }
+ default:
+ {
+ return false
+ }
+ }
+}
+
+// Add a label to the aggregated list
+func (agg *ActionAggregator) addLabel(lbl *Label) {
+ for l, agglbl := range agg.RemovedLabels {
+ if agglbl.ID == lbl.ID {
+ agg.RemovedLabels = slices.Delete(agg.RemovedLabels, l, l+1)
+ return
+ }
+ }
+
+ if !slices.ContainsFunc(agg.AddedLabels, func(l *Label) bool { return l.ID == lbl.ID }) {
+ agg.AddedLabels = append(agg.AddedLabels, lbl)
+ }
+}
+
+// Remove a label from the aggregated list
+func (agg *ActionAggregator) delLabel(lbl *Label) {
+ for l, agglbl := range agg.AddedLabels {
+ if agglbl.ID == lbl.ID {
+ agg.AddedLabels = slices.Delete(agg.AddedLabels, l, l+1)
+ return
+ }
+ }
+
+ if !slices.ContainsFunc(agg.RemovedLabels, func(l *Label) bool { return l.ID == lbl.ID }) {
+ agg.RemovedLabels = append(agg.RemovedLabels, lbl)
+ }
+}
+
+// Add a review request to the aggregated list
+func (agg *ActionAggregator) addReviewRequest(req RequestReviewTarget) {
+ reqid := req.ID()
+ reqty := req.Type()
+ for r, aggreq := range agg.RemovedRequestReview {
+ if (aggreq.ID() == reqid) && (aggreq.Type() == reqty) {
+ agg.RemovedRequestReview = slices.Delete(agg.RemovedRequestReview, r, r+1)
+ return
+ }
+ }
+
+ if !slices.ContainsFunc(agg.AddedRequestReview, func(r RequestReviewTarget) bool { return (r.ID() == reqid) && (r.Type() == reqty) }) {
+ agg.AddedRequestReview = append(agg.AddedRequestReview, req)
+ }
+}
+
+// Delete a review request from the aggregated list
+func (agg *ActionAggregator) delReviewRequest(req RequestReviewTarget) {
+ reqid := req.ID()
+ reqty := req.Type()
+ for r, aggreq := range agg.AddedRequestReview {
+ if (aggreq.ID() == reqid) && (aggreq.Type() == reqty) {
+ agg.AddedRequestReview = slices.Delete(agg.AddedRequestReview, r, r+1)
+ return
+ }
+ }
+
+ if !slices.ContainsFunc(agg.RemovedRequestReview, func(r RequestReviewTarget) bool { return (r.ID() == reqid) && (r.Type() == reqty) }) {
+ agg.RemovedRequestReview = append(agg.RemovedRequestReview, req)
+ }
+}
+
+// Check if anything has changed with this aggregated list of comments
+func (agg *ActionAggregator) Changed() bool {
+ return (agg.IsClosed != agg.PrevClosed) ||
+ (len(agg.AddedLabels) > 0) ||
+ (len(agg.RemovedLabels) > 0) ||
+ (len(agg.AddedRequestReview) > 0) ||
+ (len(agg.RemovedRequestReview) > 0)
+}
+
+func (agg *ActionAggregator) OnlyLabelsChanged() bool {
+ return ((len(agg.AddedLabels) > 0) || (len(agg.RemovedLabels) > 0)) &&
+ (len(agg.AddedRequestReview) == 0) && (len(agg.RemovedRequestReview) == 0) &&
+ (agg.PrevClosed == agg.IsClosed)
+}
+
+func (agg *ActionAggregator) OnlyRequestReview() bool {
+ return ((len(agg.AddedRequestReview) > 0) || (len(agg.RemovedRequestReview) > 0)) &&
+ (len(agg.AddedLabels) == 0) && (len(agg.RemovedLabels) == 0) &&
+ (agg.PrevClosed == agg.IsClosed)
+}
+
+func (agg *ActionAggregator) OnlyClosedReopened() bool {
+ return (agg.IsClosed != agg.PrevClosed) &&
+ (len(agg.AddedLabels) == 0) && (len(agg.RemovedLabels) == 0) &&
+ (len(agg.AddedRequestReview) == 0) && (len(agg.RemovedRequestReview) == 0)
+}
+
+// Reset the aggregator to start a new aggregating context
+func (agg *ActionAggregator) Reset(cur *Comment, now int64) {
+ agg.StartUnix = int64(cur.CreatedUnix)
+ agg.AggAge = now - agg.StartUnix
+ agg.PosterID = cur.PosterID
+
+ agg.PrevClosed = agg.IsClosed
+
+ agg.StartInd = -1
+ agg.EndInd = -1
+ agg.AddedLabels = []*Label{}
+ agg.RemovedLabels = []*Label{}
+ agg.AddedRequestReview = []RequestReviewTarget{}
+ agg.RemovedRequestReview = []RequestReviewTarget{}
+}
+
+// Function that replaces all the comments aggregated with a single one
+// Its CommentType depend on whether multiple type of comments are been aggregated or not
+// If nothing has changed, we remove all the comments that get nullified
+//
+// The function returns how many comments has been removed, in order for the "for" loop
+// of the main algorithm to change its index
+func (agg *ActionAggregator) createAggregatedComment(issue *Issue, final bool) int {
+ // If the aggregation of comments make the whole thing null, erase all the comments
+ if !agg.Changed() {
+ if final {
+ issue.Comments = issue.Comments[:agg.StartInd]
+ } else {
+ issue.Comments = slices.Replace(issue.Comments, agg.StartInd, agg.EndInd+1)
+ }
+ return (agg.EndInd - agg.StartInd) + 1
+ }
+
+ newAgg := *agg // Trigger a memory allocation, get a COPY of the aggregator
+
+ // Keep the same author, time, etc... But reset the parts we may want to use
+ comment := issue.Comments[agg.StartInd]
+ comment.Content = ""
+ comment.Label = nil
+ comment.Aggregator = nil
+ comment.Assignee = nil
+ comment.AssigneeID = 0
+ comment.AssigneeTeam = nil
+ comment.AssigneeTeamID = 0
+ comment.RemovedAssignee = false
+ comment.AddedLabels = nil
+ comment.RemovedLabels = nil
+
+ // In case there's only a single change, create a comment of this type
+ // instead of an aggregator
+ if agg.OnlyLabelsChanged() {
+ comment.Type = CommentTypeLabel
+ } else if agg.OnlyClosedReopened() {
+ if agg.IsClosed {
+ comment.Type = CommentTypeClose
+ } else {
+ comment.Type = CommentTypeReopen
+ }
+ } else if agg.OnlyRequestReview() {
+ comment.Type = CommentTypeReviewRequest
+ } else {
+ comment.Type = CommentTypeAggregator
+ comment.Aggregator = &newAgg
+ }
+
+ if len(newAgg.AddedLabels) > 0 {
+ comment.AddedLabels = newAgg.AddedLabels
+ }
+
+ if len(newAgg.RemovedLabels) > 0 {
+ comment.RemovedLabels = newAgg.RemovedLabels
+ }
+
+ if len(newAgg.AddedRequestReview) > 0 {
+ comment.AddedRequestReview = newAgg.AddedRequestReview
+ }
+
+ if len(newAgg.RemovedRequestReview) > 0 {
+ comment.RemovedRequestReview = newAgg.RemovedRequestReview
+ }
+
+ if final {
+ issue.Comments = append(issue.Comments[:agg.StartInd], comment)
+ } else {
+ issue.Comments = slices.Replace(issue.Comments, agg.StartInd, agg.EndInd+1, comment)
+ }
+ return agg.EndInd - agg.StartInd
+}
+
+// combineCommentsHistory combines nearby elements in the history as one
+func CombineCommentsHistory(issue *Issue, now int64) {
+ if len(issue.Comments) < 1 {
+ return
+ }
+
+ // Initialise a new empty aggregator, ready to combine comments
+ var agg ActionAggregator
+ agg.Reset(issue.Comments[0], now)
+
+ for i := 0; i < len(issue.Comments); i++ {
+ cur := issue.Comments[i]
+ // If the comment we encounter is not accepted inside an aggregator
+ if !agg.IsAggregated(&cur.Type) {
+ // If we aggregated some data, create the resulting comment for it
+ if agg.StartInd != -1 {
+ i -= agg.createAggregatedComment(issue, false)
+ }
+
+ agg.StartInd = -1
+ if i+1 < len(issue.Comments) {
+ agg.Reset(issue.Comments[i+1], now)
+ }
+
+ // Do not need to continue the aggregation loop, skip to next comment
+ continue
+ }
+
+ // If the comment we encounter cannot be aggregated with the current aggregator,
+ // we create a new empty aggregator
+ threshold := agg.timeThreshold()
+ if ((int64(cur.CreatedUnix) - agg.StartUnix) > threshold) || (cur.PosterID != agg.PosterID) {
+ // First, create the aggregated comment if there's data in it
+ if agg.StartInd != -1 {
+ i -= agg.createAggregatedComment(issue, false)
+ }
+ agg.Reset(cur, now)
+ }
+
+ agg.aggregateAction(cur, i)
+ }
+
+ // Create the aggregated comment if there's data in it
+ if agg.StartInd != -1 {
+ agg.createAggregatedComment(issue, true)
+ }
+}
+
+type RequestReviewTarget struct {
+ User *user_model.User
+ Team *organization.Team
+}
+
+func (t *RequestReviewTarget) ID() int64 {
+ if t.User != nil {
+ return t.User.ID
+ }
+ return t.Team.ID
+}
+
+func (t *RequestReviewTarget) Name() string {
+ if t.User != nil {
+ return t.User.GetDisplayName()
+ }
+ return t.Team.Name
+}
+
+func (t *RequestReviewTarget) Type() string {
+ if t.User != nil {
+ return "user"
+ }
+ return "team"
+}
diff --git a/models/issues/assignees.go b/models/issues/assignees.go
index a83cb250fa..b1099b6b63 100644
--- a/models/issues/assignees.go
+++ b/models/issues/assignees.go
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/issues/assignees_test.go b/models/issues/assignees_test.go
index 2c33efd99e..a5e8f0cb09 100644
--- a/models/issues/assignees_test.go
+++ b/models/issues/assignees_test.go
@@ -6,48 +6,49 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestUpdateAssignee(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Fake issue with assignees
issue, err := issues_model.GetIssueByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = issue.LoadAttributes(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Assign multiple users
user2, err := user_model.GetUserByID(db.DefaultContext, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, _, err = issues_model.ToggleIssueAssignee(db.DefaultContext, issue, &user_model.User{ID: 1}, user2.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
org3, err := user_model.GetUserByID(db.DefaultContext, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, _, err = issues_model.ToggleIssueAssignee(db.DefaultContext, issue, &user_model.User{ID: 1}, org3.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
user1, err := user_model.GetUserByID(db.DefaultContext, 1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him
- assert.NoError(t, err)
+ require.NoError(t, err)
_, _, err = issues_model.ToggleIssueAssignee(db.DefaultContext, issue, &user_model.User{ID: 1}, user1.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Check if he got removed
isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, isAssigned)
// Check if they're all there
err = issue.LoadAssignees(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
var expectedAssignees []*user_model.User
expectedAssignees = append(expectedAssignees, user2, org3)
@@ -58,37 +59,37 @@ func TestUpdateAssignee(t *testing.T) {
// Check if the user is assigned
isAssigned, err = issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, isAssigned)
// This user should not be assigned
isAssigned, err = issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, &user_model.User{ID: 4})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, isAssigned)
}
func TestMakeIDsFromAPIAssigneesToAdd(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
_ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
_ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
IDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "", []string{""})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []int64{}, IDs)
_, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "", []string{"none_existing_user"})
- assert.Error(t, err)
+ require.Error(t, err)
IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "user1", []string{"user1"})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []int64{1}, IDs)
IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "user2", []string{""})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []int64{2}, IDs)
IDs, err = issues_model.MakeIDsFromAPIAssigneesToAdd(db.DefaultContext, "", []string{"user1", "user2"})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []int64{1, 2}, IDs)
}
diff --git a/models/issues/comment.go b/models/issues/comment.go
index d53e5f5949..1b9b259a30 100644
--- a/models/issues/comment.go
+++ b/models/issues/comment.go
@@ -12,22 +12,22 @@ import (
"strconv"
"unicode/utf8"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/organization"
- project_model "code.gitea.io/gitea/models/project"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/references"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/organization"
+ project_model "forgejo.org/models/project"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/references"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -114,6 +114,8 @@ const (
CommentTypePin // 36 pin Issue
CommentTypeUnpin // 37 unpin Issue
+
+ CommentTypeAggregator // 38 Aggregator of comments
)
var commentStrings = []string{
@@ -155,6 +157,7 @@ var commentStrings = []string{
"pull_cancel_scheduled_merge",
"pin",
"unpin",
+ "action_aggregator",
}
func (t CommentType) String() string {
@@ -194,6 +197,20 @@ func (t CommentType) HasMailReplySupport() bool {
return false
}
+func (t CommentType) CountedAsConversation() bool {
+ for _, ct := range ConversationCountedCommentType() {
+ if t == ct {
+ return true
+ }
+ }
+ return false
+}
+
+// ConversationCountedCommentType returns the comment types that are counted as a conversation
+func ConversationCountedCommentType() []CommentType {
+ return []CommentType{CommentTypeComment, CommentTypeReview}
+}
+
// RoleInRepo presents the user's participation in the repo
type RoleInRepo string
@@ -224,41 +241,44 @@ func (r RoleInRepo) LocaleHelper(lang translation.Locale) string {
// Comment represents a comment in commit and issue page.
type Comment struct {
- ID int64 `xorm:"pk autoincr"`
- Type CommentType `xorm:"INDEX"`
- PosterID int64 `xorm:"INDEX"`
- Poster *user_model.User `xorm:"-"`
- OriginalAuthor string
- OriginalAuthorID int64
- IssueID int64 `xorm:"INDEX"`
- Issue *Issue `xorm:"-"`
- LabelID int64
- Label *Label `xorm:"-"`
- AddedLabels []*Label `xorm:"-"`
- RemovedLabels []*Label `xorm:"-"`
- OldProjectID int64
- ProjectID int64
- OldProject *project_model.Project `xorm:"-"`
- Project *project_model.Project `xorm:"-"`
- OldMilestoneID int64
- MilestoneID int64
- OldMilestone *Milestone `xorm:"-"`
- Milestone *Milestone `xorm:"-"`
- TimeID int64
- Time *TrackedTime `xorm:"-"`
- AssigneeID int64
- RemovedAssignee bool
- Assignee *user_model.User `xorm:"-"`
- AssigneeTeamID int64 `xorm:"NOT NULL DEFAULT 0"`
- AssigneeTeam *organization.Team `xorm:"-"`
- ResolveDoerID int64
- ResolveDoer *user_model.User `xorm:"-"`
- OldTitle string
- NewTitle string
- OldRef string
- NewRef string
- DependentIssueID int64 `xorm:"index"` // This is used by issue_service.deleteIssue
- DependentIssue *Issue `xorm:"-"`
+ ID int64 `xorm:"pk autoincr"`
+ Type CommentType `xorm:"INDEX"`
+ PosterID int64 `xorm:"INDEX"`
+ Poster *user_model.User `xorm:"-"`
+ OriginalAuthor string
+ OriginalAuthorID int64
+ IssueID int64 `xorm:"INDEX"`
+ Issue *Issue `xorm:"-"`
+ LabelID int64
+ Label *Label `xorm:"-"`
+ Aggregator *ActionAggregator `xorm:"-"`
+ AddedLabels []*Label `xorm:"-"`
+ RemovedLabels []*Label `xorm:"-"`
+ AddedRequestReview []RequestReviewTarget `xorm:"-"`
+ RemovedRequestReview []RequestReviewTarget `xorm:"-"`
+ OldProjectID int64
+ ProjectID int64
+ OldProject *project_model.Project `xorm:"-"`
+ Project *project_model.Project `xorm:"-"`
+ OldMilestoneID int64
+ MilestoneID int64
+ OldMilestone *Milestone `xorm:"-"`
+ Milestone *Milestone `xorm:"-"`
+ TimeID int64
+ Time *TrackedTime `xorm:"-"`
+ AssigneeID int64
+ RemovedAssignee bool
+ Assignee *user_model.User `xorm:"-"`
+ AssigneeTeamID int64 `xorm:"NOT NULL DEFAULT 0"`
+ AssigneeTeam *organization.Team `xorm:"-"`
+ ResolveDoerID int64
+ ResolveDoer *user_model.User `xorm:"-"`
+ OldTitle string
+ NewTitle string
+ OldRef string
+ NewRef string
+ DependentIssueID int64 `xorm:"index"` // This is used by issue_service.deleteIssue
+ DependentIssue *Issue `xorm:"-"`
CommitID int64
Line int64 // - previous line / + proposed line
@@ -629,8 +649,11 @@ func (c *Comment) LoadAssigneeUserAndTeam(ctx context.Context) error {
if c.Issue.Repo.Owner.IsOrganization() {
c.AssigneeTeam, err = organization.GetTeamByID(ctx, c.AssigneeTeamID)
- if err != nil && !organization.IsErrTeamNotExist(err) {
- return err
+ if err != nil {
+ if !organization.IsErrTeamNotExist(err) {
+ return err
+ }
+ c.AssigneeTeam = organization.NewGhostTeam()
}
}
}
@@ -879,7 +902,7 @@ func updateCommentInfos(ctx context.Context, opts *CreateCommentOptions, comment
}
fallthrough
case CommentTypeComment:
- if _, err = db.Exec(ctx, "UPDATE `issue` SET num_comments=num_comments+1 WHERE id=?", opts.Issue.ID); err != nil {
+ if err := UpdateIssueNumComments(ctx, opts.Issue.ID); err != nil {
return err
}
fallthrough
@@ -1094,7 +1117,7 @@ func FindComments(ctx context.Context, opts *FindCommentsOptions) (CommentList,
sess.Join("INNER", "issue", "issue.id = comment.issue_id")
}
- if opts.Page != 0 {
+ if opts.Page > 0 {
sess = db.SetSessionPagination(sess, opts)
}
@@ -1174,8 +1197,8 @@ func DeleteComment(ctx context.Context, comment *Comment) error {
return err
}
- if comment.Type == CommentTypeComment {
- if _, err := e.ID(comment.IssueID).Decr("num_comments").Update(new(Issue)); err != nil {
+ if comment.Type.CountedAsConversation() {
+ if err := UpdateIssueNumComments(ctx, comment.IssueID); err != nil {
return err
}
}
@@ -1292,6 +1315,21 @@ func (c *Comment) HasOriginalAuthor() bool {
return c.OriginalAuthor != "" && c.OriginalAuthorID != 0
}
+func UpdateIssueNumCommentsBuilder(issueID int64) *builder.Builder {
+ subQuery := builder.Select("COUNT(*)").From("`comment`").Where(
+ builder.Eq{"issue_id": issueID}.And(
+ builder.In("`type`", ConversationCountedCommentType()),
+ ))
+
+ return builder.Update(builder.Eq{"num_comments": subQuery}).
+ From("`issue`").Where(builder.Eq{"id": issueID})
+}
+
+func UpdateIssueNumComments(ctx context.Context, issueID int64) error {
+ _, err := db.GetEngine(ctx).Exec(UpdateIssueNumCommentsBuilder(issueID))
+ return err
+}
+
// InsertIssueComments inserts many comments of issues.
func InsertIssueComments(ctx context.Context, comments []*Comment) error {
if len(comments) == 0 {
@@ -1324,8 +1362,7 @@ func InsertIssueComments(ctx context.Context, comments []*Comment) error {
}
for _, issueID := range issueIDs {
- if _, err := db.Exec(ctx, "UPDATE issue set num_comments = (SELECT count(*) FROM comment WHERE issue_id = ? AND `type`=?) WHERE id = ?",
- issueID, CommentTypeComment, issueID); err != nil {
+ if err := UpdateIssueNumComments(ctx, issueID); err != nil {
return err
}
}
diff --git a/models/issues/comment_code.go b/models/issues/comment_code.go
index 2f6f57e0da..3c87a1b41a 100644
--- a/models/issues/comment_code.go
+++ b/models/issues/comment_code.go
@@ -6,10 +6,10 @@ package issues
import (
"context"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
"xorm.io/builder"
)
diff --git a/models/issues/comment_list.go b/models/issues/comment_list.go
index 61ac1c8f56..7285e347b4 100644
--- a/models/issues/comment_list.go
+++ b/models/issues/comment_list.go
@@ -6,11 +6,11 @@ package issues
import (
"context"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
)
// CommentList defines a list of comments
@@ -23,7 +23,7 @@ func (comments CommentList) LoadPosters(ctx context.Context) error {
}
posterIDs := container.FilterSlice(comments, func(c *Comment) (int64, bool) {
- return c.PosterID, c.Poster == nil && c.PosterID > 0
+ return c.PosterID, c.Poster == nil && user_model.IsValidUserID(c.PosterID)
})
posterMaps, err := getPostersByIDs(ctx, posterIDs)
@@ -33,7 +33,7 @@ func (comments CommentList) LoadPosters(ctx context.Context) error {
for _, comment := range comments {
if comment.Poster == nil {
- comment.Poster = getPoster(comment.PosterID, posterMaps)
+ comment.PosterID, comment.Poster = user_model.GetUserFromMap(comment.PosterID, posterMaps)
}
}
return nil
@@ -165,7 +165,7 @@ func (comments CommentList) loadOldMilestones(ctx context.Context) error {
func (comments CommentList) getAssigneeIDs() []int64 {
return container.FilterSlice(comments, func(comment *Comment) (int64, bool) {
- return comment.AssigneeID, comment.AssigneeID > 0
+ return comment.AssigneeID, user_model.IsValidUserID(comment.AssigneeID)
})
}
@@ -206,11 +206,7 @@ func (comments CommentList) loadAssignees(ctx context.Context) error {
}
for _, comment := range comments {
- comment.Assignee = assignees[comment.AssigneeID]
- if comment.Assignee == nil {
- comment.AssigneeID = user_model.GhostUserID
- comment.Assignee = user_model.NewGhostUser()
- }
+ comment.AssigneeID, comment.Assignee = user_model.GetUserFromMap(comment.AssigneeID, assignees)
}
return nil
}
diff --git a/models/issues/comment_list_test.go b/models/issues/comment_list_test.go
new file mode 100644
index 0000000000..062a710b84
--- /dev/null
+++ b/models/issues/comment_list_test.go
@@ -0,0 +1,86 @@
+// Copyright 2024 The Forgejo Authors
+// SPDX-License-Identifier: MIT
+
+package issues
+
+import (
+ "testing"
+
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestCommentListLoadUser(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ issue := unittest.AssertExistsAndLoadBean(t, &Issue{})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
+
+ for _, testCase := range []struct {
+ poster int64
+ assignee int64
+ user *user_model.User
+ }{
+ {
+ poster: user_model.ActionsUserID,
+ assignee: user_model.ActionsUserID,
+ user: user_model.NewActionsUser(),
+ },
+ {
+ poster: user_model.GhostUserID,
+ assignee: user_model.GhostUserID,
+ user: user_model.NewGhostUser(),
+ },
+ {
+ poster: doer.ID,
+ assignee: doer.ID,
+ user: doer,
+ },
+ {
+ poster: 0,
+ assignee: 0,
+ user: user_model.NewGhostUser(),
+ },
+ {
+ poster: -200,
+ assignee: -200,
+ user: user_model.NewGhostUser(),
+ },
+ {
+ poster: 200,
+ assignee: 200,
+ user: user_model.NewGhostUser(),
+ },
+ } {
+ t.Run(testCase.user.Name, func(t *testing.T) {
+ comment, err := CreateComment(db.DefaultContext, &CreateCommentOptions{
+ Type: CommentTypeComment,
+ Doer: testCase.user,
+ Repo: repo,
+ Issue: issue,
+ Content: "Hello",
+ })
+ assert.NoError(t, err)
+
+ list := CommentList{comment}
+
+ comment.PosterID = testCase.poster
+ comment.Poster = nil
+ assert.NoError(t, list.LoadPosters(db.DefaultContext))
+ require.NotNil(t, comment.Poster)
+ assert.Equal(t, testCase.user.ID, comment.Poster.ID)
+
+ comment.AssigneeID = testCase.assignee
+ comment.Assignee = nil
+ require.NoError(t, list.loadAssignees(db.DefaultContext))
+ require.NotNil(t, comment.Assignee)
+ assert.Equal(t, testCase.user.ID, comment.Assignee.ID)
+ })
+ }
+}
diff --git a/models/issues/comment_test.go b/models/issues/comment_test.go
index e7ceee4298..0e257f533c 100644
--- a/models/issues/comment_test.go
+++ b/models/issues/comment_test.go
@@ -7,18 +7,19 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/structs"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCreateComment(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
@@ -32,7 +33,7 @@ func TestCreateComment(t *testing.T) {
Issue: issue,
Content: "Hello",
})
- assert.NoError(t, err)
+ require.NoError(t, err)
then := time.Now().Unix()
assert.EqualValues(t, issues_model.CommentTypeComment, comment.Type)
@@ -47,12 +48,12 @@ func TestCreateComment(t *testing.T) {
}
func TestFetchCodeConversations(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
res, err := issues_model.FetchCodeConversations(db.DefaultContext, issue, user, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Contains(t, res, "README.md")
assert.Contains(t, res["README.md"], int64(4))
assert.Len(t, res["README.md"][4], 1)
@@ -60,12 +61,12 @@ func TestFetchCodeConversations(t *testing.T) {
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
res, err = issues_model.FetchCodeConversations(db.DefaultContext, issue, user2, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, res, 1)
}
func TestAsCommentType(t *testing.T) {
- assert.Equal(t, issues_model.CommentType(0), issues_model.CommentTypeComment)
+ assert.Equal(t, issues_model.CommentTypeComment, issues_model.CommentType(0))
assert.Equal(t, issues_model.CommentTypeUndefined, issues_model.AsCommentType(""))
assert.Equal(t, issues_model.CommentTypeUndefined, issues_model.AsCommentType("nonsense"))
assert.Equal(t, issues_model.CommentTypeComment, issues_model.AsCommentType("comment"))
@@ -73,7 +74,7 @@ func TestAsCommentType(t *testing.T) {
}
func TestMigrate_InsertIssueComments(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
_ = issue.LoadRepo(db.DefaultContext)
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
@@ -91,7 +92,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) {
}
err := issues_model.InsertIssueComments(db.DefaultContext, []*issues_model.Comment{comment})
- assert.NoError(t, err)
+ require.NoError(t, err)
issueModified := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
assert.EqualValues(t, issue.NumComments+1, issueModified.NumComments)
@@ -100,7 +101,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) {
}
func TestUpdateCommentsMigrationsByType(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
@@ -115,12 +116,21 @@ func TestUpdateCommentsMigrationsByType(t *testing.T) {
comment.OriginalAuthorID = 1
comment.PosterID = 0
_, err := db.GetEngine(db.DefaultContext).ID(comment.ID).Cols("original_author", "original_author_id", "poster_id").Update(comment)
- assert.NoError(t, err)
+ require.NoError(t, err)
- assert.NoError(t, issues_model.UpdateCommentsMigrationsByType(db.DefaultContext, structs.GiteaService, "1", 513))
+ require.NoError(t, issues_model.UpdateCommentsMigrationsByType(db.DefaultContext, structs.GiteaService, "1", 513))
comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 1, IssueID: issue.ID})
assert.Empty(t, comment.OriginalAuthor)
assert.Empty(t, comment.OriginalAuthorID)
assert.EqualValues(t, 513, comment.PosterID)
}
+
+func Test_UpdateIssueNumComments(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+
+ require.NoError(t, issues_model.UpdateIssueNumComments(db.DefaultContext, issue2.ID))
+ issue2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ assert.EqualValues(t, 1, issue2.NumComments)
+}
diff --git a/models/issues/content_history.go b/models/issues/content_history.go
index cd3e217b21..476c6e0f90 100644
--- a/models/issues/content_history.go
+++ b/models/issues/content_history.go
@@ -7,11 +7,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/avatars"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/avatars"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/issues/content_history_test.go b/models/issues/content_history_test.go
index 89d77a1df3..4e158da1cc 100644
--- a/models/issues/content_history_test.go
+++ b/models/issues/content_history_test.go
@@ -6,16 +6,17 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestContentHistory(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
dbCtx := db.DefaultContext
timeStampNow := timeutil.TimeStampNow()
@@ -80,7 +81,7 @@ func TestContentHistory(t *testing.T) {
}
func TestHasIssueContentHistory(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Ensures that comment_id is into taken account even if it's zero.
_ = issues_model.SaveIssueContentHistory(db.DefaultContext, 1, 11, 100, timeutil.TimeStampNow(), "c-a", true)
diff --git a/models/issues/dependency.go b/models/issues/dependency.go
index 146dd1887d..fab35dad12 100644
--- a/models/issues/dependency.go
+++ b/models/issues/dependency.go
@@ -7,10 +7,10 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
)
// ErrDependencyExists represents a "DependencyAlreadyExists" kind of error.
diff --git a/models/issues/dependency_test.go b/models/issues/dependency_test.go
index 6eed483cc9..46f3ad10e5 100644
--- a/models/issues/dependency_test.go
+++ b/models/issues/dependency_test.go
@@ -6,57 +6,58 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCreateIssueDependency(t *testing.T) {
// Prepare
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1, err := user_model.GetUserByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Create a dependency and check if it was successful
err = issues_model.CreateIssueDependency(db.DefaultContext, user1, issue1, issue2)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Do it again to see if it will check if the dependency already exists
err = issues_model.CreateIssueDependency(db.DefaultContext, user1, issue1, issue2)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrDependencyExists(err))
// Check for circular dependencies
err = issues_model.CreateIssueDependency(db.DefaultContext, user1, issue2, issue1)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrCircularDependency(err))
_ = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddDependency, PosterID: user1.ID, IssueID: issue1.ID})
// Check if dependencies left is correct
left, err := issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, left)
// Close #2 and check again
_, err = issues_model.ChangeIssueStatus(db.DefaultContext, issue2, user1, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, left)
// Test removing the dependency
err = issues_model.RemoveIssueDependency(db.DefaultContext, user1, issue1, issue2, issues_model.DependencyTypeBlockedBy)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
diff --git a/models/issues/issue.go b/models/issues/issue.go
index f04a4ad5c7..142f2de182 100644
--- a/models/issues/issue.go
+++ b/models/issues/issue.go
@@ -11,16 +11,16 @@ import (
"regexp"
"slices"
- "code.gitea.io/gitea/models/db"
- project_model "code.gitea.io/gitea/models/project"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ project_model "forgejo.org/models/project"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -63,21 +63,6 @@ func (err ErrIssueIsClosed) Error() string {
return fmt.Sprintf("issue is closed [id: %d, repo_id: %d, index: %d]", err.ID, err.RepoID, err.Index)
}
-// ErrNewIssueInsert is used when the INSERT statement in newIssue fails
-type ErrNewIssueInsert struct {
- OriginalError error
-}
-
-// IsErrNewIssueInsert checks if an error is a ErrNewIssueInsert.
-func IsErrNewIssueInsert(err error) bool {
- _, ok := err.(ErrNewIssueInsert)
- return ok
-}
-
-func (err ErrNewIssueInsert) Error() string {
- return err.OriginalError.Error()
-}
-
// ErrIssueWasClosed is used when close a closed issue
type ErrIssueWasClosed struct {
ID int64
@@ -153,8 +138,8 @@ type Issue struct {
}
var (
- issueTasksPat = regexp.MustCompile(`(^\s*[-*]\s\[[\sxX]\]\s.)|(\n\s*[-*]\s\[[\sxX]\]\s.)`)
- issueTasksDonePat = regexp.MustCompile(`(^\s*[-*]\s\[[xX]\]\s.)|(\n\s*[-*]\s\[[xX]\]\s.)`)
+ issueTasksPat = regexp.MustCompile(`(^|\n)\s*[-*]\s*\[[\sxX]\]`)
+ issueTasksDonePat = regexp.MustCompile(`(^|\n)\s*[-*]\s*\[[xX]\]`)
)
// IssueIndex represents the issue index table
@@ -268,6 +253,9 @@ func (issue *Issue) loadCommentsByType(ctx context.Context, tp CommentType) (err
IssueID: issue.ID,
Type: tp,
})
+ for _, comment := range issue.Comments {
+ comment.Issue = issue
+ }
return err
}
@@ -411,6 +399,11 @@ func (issue *Issue) HTMLURL() string {
return fmt.Sprintf("%s/%s/%d", issue.Repo.HTMLURL(), path, issue.Index)
}
+// SummaryCardURL returns the absolute URL to an image providing a summary of the issue
+func (issue *Issue) SummaryCardURL() string {
+ return fmt.Sprintf("%s/summary-card", issue.HTMLURL())
+}
+
// Link returns the issue's relative URL.
func (issue *Issue) Link() string {
var path string
@@ -553,6 +546,9 @@ func GetIssueByID(ctx context.Context, id int64) (*Issue, error) {
// If keepOrder is true, the order of the returned issues will be the same as the given IDs.
func GetIssuesByIDs(ctx context.Context, issueIDs []int64, keepOrder ...bool) (IssueList, error) {
issues := make([]*Issue, 0, len(issueIDs))
+ if len(issueIDs) == 0 {
+ return issues, nil
+ }
if err := db.GetEngine(ctx).In("id", issueIDs).Find(&issues); err != nil {
return nil, err
@@ -644,7 +640,7 @@ func (issue *Issue) BlockedByDependencies(ctx context.Context, opts db.ListOptio
Where("issue_id = ?", issue.ID).
// sort by repo id then created date, with the issues of the same repo at the beginning of the list
OrderBy("CASE WHEN issue.repo_id = ? THEN 0 ELSE issue.repo_id END, issue.created_unix DESC", issue.RepoID)
- if opts.Page != 0 {
+ if opts.Page > 0 {
sess = db.SetSessionPagination(sess, &opts)
}
err = sess.Find(&issueDeps)
@@ -875,7 +871,7 @@ func GetPinnedIssues(ctx context.Context, repoID int64, isPull bool) (IssueList,
return issues, nil
}
-// IsNewPinnedAllowed returns if a new Issue or Pull request can be pinned
+// IsNewPinAllowed returns if a new Issue or Pull request can be pinned
func IsNewPinAllowed(ctx context.Context, repoID int64, isPull bool) (bool, error) {
var maxPin int
_, err := db.GetEngine(ctx).SQL("SELECT COUNT(pin_order) FROM issue WHERE repo_id = ? AND is_pull = ? AND pin_order > 0", repoID, isPull).Get(&maxPin)
diff --git a/models/issues/issue_index.go b/models/issues/issue_index.go
index 9386027f74..5012067d70 100644
--- a/models/issues/issue_index.go
+++ b/models/issues/issue_index.go
@@ -6,7 +6,7 @@ package issues
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
func GetMaxIssueIndexForRepo(ctx context.Context, repoID int64) (int64, error) {
diff --git a/models/issues/issue_index_test.go b/models/issues/issue_index_test.go
index 9937aac70e..6de3f0bc95 100644
--- a/models/issues/issue_index_test.go
+++ b/models/issues/issue_index_test.go
@@ -6,33 +6,34 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetMaxIssueIndexForRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
maxPR, err := issues_model.GetMaxIssueIndexForRepo(db.DefaultContext, repo.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue := testCreateIssue(t, repo.ID, repo.OwnerID, "title1", "content1", false)
assert.Greater(t, issue.Index, maxPR)
maxPR, err = issues_model.GetMaxIssueIndexForRepo(db.DefaultContext, repo.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
pull := testCreateIssue(t, repo.ID, repo.OwnerID, "title2", "content2", true)
assert.Greater(t, pull.Index, maxPR)
maxPR, err = issues_model.GetMaxIssueIndexForRepo(db.DefaultContext, repo.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, maxPR, pull.Index)
}
diff --git a/models/issues/issue_label.go b/models/issues/issue_label.go
index 10fc821454..c9e792ed0f 100644
--- a/models/issues/issue_label.go
+++ b/models/issues/issue_label.go
@@ -8,9 +8,9 @@ import (
"fmt"
"sort"
- "code.gitea.io/gitea/models/db"
- access_model "code.gitea.io/gitea/models/perm/access"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ access_model "forgejo.org/models/perm/access"
+ user_model "forgejo.org/models/user"
"xorm.io/builder"
)
@@ -111,9 +111,7 @@ func NewIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *user_m
return err
}
- issue.isLabelsLoaded = false
- issue.Labels = nil
- if err = issue.LoadLabels(ctx); err != nil {
+ if err = issue.ReloadLabels(ctx); err != nil {
return err
}
@@ -161,10 +159,7 @@ func NewIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer *us
return err
}
- // reload all labels
- issue.isLabelsLoaded = false
- issue.Labels = nil
- if err = issue.LoadLabels(ctx); err != nil {
+ if err = issue.ReloadLabels(ctx); err != nil {
return err
}
@@ -205,8 +200,7 @@ func DeleteIssueLabel(ctx context.Context, issue *Issue, label *Label, doer *use
return err
}
- issue.Labels = nil
- return issue.LoadLabels(ctx)
+ return issue.ReloadLabels(ctx)
}
// DeleteLabelsByRepoID deletes labels of some repository
@@ -326,14 +320,23 @@ func FixIssueLabelWithOutsideLabels(ctx context.Context) (int64, error) {
return res.RowsAffected()
}
-// LoadLabels loads labels
+// LoadLabels only if they are not already set
func (issue *Issue) LoadLabels(ctx context.Context) (err error) {
- if !issue.isLabelsLoaded && issue.Labels == nil && issue.ID != 0 {
+ if !issue.isLabelsLoaded && issue.Labels == nil {
+ if err := issue.ReloadLabels(ctx); err != nil {
+ return err
+ }
+ issue.isLabelsLoaded = true
+ }
+ return nil
+}
+
+func (issue *Issue) ReloadLabels(ctx context.Context) (err error) {
+ if issue.ID != 0 {
issue.Labels, err = GetLabelsByIssueID(ctx, issue.ID)
if err != nil {
return fmt.Errorf("getLabelsByIssueID [%d]: %w", issue.ID, err)
}
- issue.isLabelsLoaded = true
}
return nil
}
@@ -496,8 +499,7 @@ func ReplaceIssueLabels(ctx context.Context, issue *Issue, labels []*Label, doer
}
}
- issue.Labels = nil
- if err = issue.LoadLabels(ctx); err != nil {
+ if err = issue.ReloadLabels(ctx); err != nil {
return err
}
diff --git a/models/issues/issue_label_test.go b/models/issues/issue_label_test.go
index 0470b99e24..753e389c7b 100644
--- a/models/issues/issue_label_test.go
+++ b/models/issues/issue_label_test.go
@@ -6,23 +6,132 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
+func TestIssueNewIssueLabels(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
+ label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 4})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ label3 := &issues_model.Label{RepoID: 1, Name: "label3", Color: "#123"}
+ require.NoError(t, issues_model.NewLabel(db.DefaultContext, label3))
+
+ // label1 is already set, do nothing
+ // label3 is new, add it
+ require.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label3}, doer))
+
+ assert.Len(t, issue.Labels, 3)
+ // check that the pre-existing label1 is still present
+ assert.Equal(t, label1.ID, issue.Labels[0].ID)
+ // check that new label3 was added
+ assert.Equal(t, label3.ID, issue.Labels[1].ID)
+ // check that pre-existing label2 was not removed
+ assert.Equal(t, label2.ID, issue.Labels[2].ID)
+}
+
+func TestIssueNewIssueLabel(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ label := &issues_model.Label{RepoID: 1, Name: "label3", Color: "#123"}
+ require.NoError(t, issues_model.NewLabel(db.DefaultContext, label))
+
+ require.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, label, doer))
+
+ assert.Len(t, issue.Labels, 1)
+ assert.Equal(t, label.ID, issue.Labels[0].ID)
+}
+
+func TestIssueReplaceIssueLabels(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
+ label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 4})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ label3 := &issues_model.Label{RepoID: 1, Name: "label3", Color: "#123"}
+ require.NoError(t, issues_model.NewLabel(db.DefaultContext, label3))
+
+ issue.LoadLabels(db.DefaultContext)
+ assert.Len(t, issue.Labels, 2)
+ assert.Equal(t, label1.ID, issue.Labels[0].ID)
+ assert.Equal(t, label2.ID, issue.Labels[1].ID)
+
+ // label1 is already set, do nothing
+ // label3 is new, add it
+ // label2 is not in the list but already set, remove it
+ require.NoError(t, issues_model.ReplaceIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label3}, doer))
+
+ assert.Len(t, issue.Labels, 2)
+ assert.Equal(t, label1.ID, issue.Labels[0].ID)
+ assert.Equal(t, label3.ID, issue.Labels[1].ID)
+}
+
+func TestIssueDeleteIssueLabel(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
+ label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 4})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ issue.LoadLabels(db.DefaultContext)
+ assert.Len(t, issue.Labels, 2)
+ assert.Equal(t, label1.ID, issue.Labels[0].ID)
+ assert.Equal(t, label2.ID, issue.Labels[1].ID)
+
+ require.NoError(t, issues_model.DeleteIssueLabel(db.DefaultContext, issue, label2, doer))
+
+ assert.Len(t, issue.Labels, 1)
+ assert.Equal(t, label1.ID, issue.Labels[0].ID)
+}
+
+func TestIssueLoadLabels(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
+ label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 4})
+
+ assert.Empty(t, issue.Labels)
+ issue.LoadLabels(db.DefaultContext)
+ assert.Len(t, issue.Labels, 2)
+ assert.Equal(t, label1.ID, issue.Labels[0].ID)
+ assert.Equal(t, label2.ID, issue.Labels[1].ID)
+
+ unittest.AssertSuccessfulDelete(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label2.ID})
+
+ // the database change is not noticed because the labels are cached
+ issue.LoadLabels(db.DefaultContext)
+ assert.Len(t, issue.Labels, 2)
+
+ issue.ReloadLabels(db.DefaultContext)
+ assert.Len(t, issue.Labels, 1)
+ assert.Equal(t, label1.ID, issue.Labels[0].ID)
+}
+
func TestNewIssueLabelsScope(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 18})
label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 7})
label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 8})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
- assert.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label2}, doer))
+ require.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label2}, doer))
assert.Len(t, issue.Labels, 1)
assert.Equal(t, label2.ID, issue.Labels[0].ID)
diff --git a/models/issues/issue_list.go b/models/issues/issue_list.go
index fbfa7584a0..5a02baa428 100644
--- a/models/issues/issue_list.go
+++ b/models/issues/issue_list.go
@@ -7,11 +7,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- project_model "code.gitea.io/gitea/models/project"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
+ "forgejo.org/models/db"
+ project_model "forgejo.org/models/project"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
"xorm.io/builder"
)
@@ -79,7 +79,7 @@ func (issues IssueList) LoadPosters(ctx context.Context) error {
}
posterIDs := container.FilterSlice(issues, func(issue *Issue) (int64, bool) {
- return issue.PosterID, issue.Poster == nil && issue.PosterID > 0
+ return issue.PosterID, issue.Poster == nil && user_model.IsValidUserID(issue.PosterID)
})
posterMaps, err := getPostersByIDs(ctx, posterIDs)
@@ -89,7 +89,7 @@ func (issues IssueList) LoadPosters(ctx context.Context) error {
for _, issue := range issues {
if issue.Poster == nil {
- issue.Poster = getPoster(issue.PosterID, posterMaps)
+ issue.PosterID, issue.Poster = user_model.GetUserFromMap(issue.PosterID, posterMaps)
}
}
return nil
@@ -115,20 +115,6 @@ func getPostersByIDs(ctx context.Context, posterIDs []int64) (map[int64]*user_mo
return posterMaps, nil
}
-func getPoster(posterID int64, posterMaps map[int64]*user_model.User) *user_model.User {
- if posterID == user_model.ActionsUserID {
- return user_model.NewActionsUser()
- }
- if posterID <= 0 {
- return nil
- }
- poster, ok := posterMaps[posterID]
- if !ok {
- return user_model.NewGhostUser()
- }
- return poster
-}
-
func (issues IssueList) getIssueIDs() []int64 {
ids := make([]int64, 0, len(issues))
for _, issue := range issues {
diff --git a/models/issues/issue_list_test.go b/models/issues/issue_list_test.go
index 10ba38a64b..7aa5222958 100644
--- a/models/issues/issue_list_test.go
+++ b/models/issues/issue_list_test.go
@@ -6,16 +6,18 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIssueList_LoadRepositories(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issueList := issues_model.IssueList{
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}),
@@ -24,7 +26,7 @@ func TestIssueList_LoadRepositories(t *testing.T) {
}
repos, err := issueList.LoadRepositories(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, repos, 2)
for _, issue := range issueList {
assert.EqualValues(t, issue.RepoID, issue.Repo.ID)
@@ -32,14 +34,14 @@ func TestIssueList_LoadRepositories(t *testing.T) {
}
func TestIssueList_LoadAttributes(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
setting.Service.EnableTimetracking = true
issueList := issues_model.IssueList{
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}),
unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}),
}
- assert.NoError(t, issueList.LoadAttributes(db.DefaultContext))
+ require.NoError(t, issueList.LoadAttributes(db.DefaultContext))
for _, issue := range issueList {
assert.EqualValues(t, issue.RepoID, issue.Repo.ID)
for _, label := range issue.Labels {
@@ -73,8 +75,55 @@ func TestIssueList_LoadAttributes(t *testing.T) {
}
}
- assert.NoError(t, issueList.LoadIsRead(db.DefaultContext, 1))
+ require.NoError(t, issueList.LoadIsRead(db.DefaultContext, 1))
for _, issue := range issueList {
assert.Equal(t, issue.ID == 1, issue.IsRead, "unexpected is_read value for issue[%d]", issue.ID)
}
}
+
+func TestIssueListLoadUser(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+
+ for _, testCase := range []struct {
+ poster int64
+ user *user_model.User
+ }{
+ {
+ poster: user_model.ActionsUserID,
+ user: user_model.NewActionsUser(),
+ },
+ {
+ poster: user_model.GhostUserID,
+ user: user_model.NewGhostUser(),
+ },
+ {
+ poster: doer.ID,
+ user: doer,
+ },
+ {
+ poster: 0,
+ user: user_model.NewGhostUser(),
+ },
+ {
+ poster: -200,
+ user: user_model.NewGhostUser(),
+ },
+ {
+ poster: 200,
+ user: user_model.NewGhostUser(),
+ },
+ } {
+ t.Run(testCase.user.Name, func(t *testing.T) {
+ list := issues_model.IssueList{issue}
+
+ issue.PosterID = testCase.poster
+ issue.Poster = nil
+ require.NoError(t, list.LoadPosters(db.DefaultContext))
+ require.NotNil(t, issue.Poster)
+ assert.Equal(t, testCase.user.ID, issue.Poster.ID)
+ })
+ }
+}
diff --git a/models/issues/issue_lock.go b/models/issues/issue_lock.go
index b21629b529..1e4a5906d9 100644
--- a/models/issues/issue_lock.go
+++ b/models/issues/issue_lock.go
@@ -6,8 +6,8 @@ package issues
import (
"context"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
)
// IssueLockOptions defines options for locking and/or unlocking an issue/PR
diff --git a/models/issues/issue_project.go b/models/issues/issue_project.go
index 835ea1db52..3c6ce0ca1c 100644
--- a/models/issues/issue_project.go
+++ b/models/issues/issue_project.go
@@ -6,10 +6,12 @@ package issues
import (
"context"
- "code.gitea.io/gitea/models/db"
- project_model "code.gitea.io/gitea/models/project"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ org_model "forgejo.org/models/organization"
+ project_model "forgejo.org/models/project"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/util"
)
// LoadProject load the project the issue was assigned to
@@ -48,22 +50,28 @@ func (issue *Issue) ProjectColumnID(ctx context.Context) int64 {
}
// LoadIssuesFromColumn load issues assigned to this column
-func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column) (IssueList, error) {
- issueList, err := Issues(ctx, &IssuesOptions{
+func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column, doer *user_model.User, org *org_model.Organization, isClosed optional.Option[bool]) (IssueList, error) {
+ issueOpts := &IssuesOptions{
ProjectColumnID: b.ID,
ProjectID: b.ProjectID,
SortType: "project-column-sorting",
- })
+ IsClosed: isClosed,
+ AllPublic: true,
+ }
+ if doer != nil {
+ issueOpts.User = doer
+ issueOpts.Org = org
+ }
+
+ issueList, err := Issues(ctx, issueOpts)
if err != nil {
return nil, err
}
if b.Default {
- issues, err := Issues(ctx, &IssuesOptions{
- ProjectColumnID: db.NoConditionID,
- ProjectID: b.ProjectID,
- SortType: "project-column-sorting",
- })
+ issueOpts.ProjectColumnID = db.NoConditionID
+
+ issues, err := Issues(ctx, issueOpts)
if err != nil {
return nil, err
}
@@ -78,10 +86,10 @@ func LoadIssuesFromColumn(ctx context.Context, b *project_model.Column) (IssueLi
}
// LoadIssuesFromColumnList load issues assigned to the columns
-func LoadIssuesFromColumnList(ctx context.Context, bs project_model.ColumnList) (map[int64]IssueList, error) {
+func LoadIssuesFromColumnList(ctx context.Context, bs project_model.ColumnList, doer *user_model.User, org *org_model.Organization, isClosed optional.Option[bool]) (map[int64]IssueList, error) {
issuesMap := make(map[int64]IssueList, len(bs))
for i := range bs {
- il, err := LoadIssuesFromColumn(ctx, bs[i])
+ il, err := LoadIssuesFromColumn(ctx, bs[i], doer, org, isClosed)
if err != nil {
return nil, err
}
@@ -160,3 +168,36 @@ func IssueAssignOrRemoveProject(ctx context.Context, issue *Issue, doer *user_mo
})
})
}
+
+// NumIssuesInProjects returns the amount of issues assigned to one of the project
+// in the list which the doer can access.
+func NumIssuesInProjects(ctx context.Context, pl []*project_model.Project, doer *user_model.User, org *org_model.Organization, isClosed optional.Option[bool]) (map[int64]int, error) {
+ numMap := make(map[int64]int, len(pl))
+ for _, p := range pl {
+ num, err := NumIssuesInProject(ctx, p, doer, org, isClosed)
+ if err != nil {
+ return nil, err
+ }
+ numMap[p.ID] = num
+ }
+
+ return numMap, nil
+}
+
+// NumIssuesInProject returns the amount of issues assigned to the project which
+// the doer can access.
+func NumIssuesInProject(ctx context.Context, p *project_model.Project, doer *user_model.User, org *org_model.Organization, isClosed optional.Option[bool]) (int, error) {
+ numIssuesInProject := int(0)
+ bs, err := p.GetColumns(ctx)
+ if err != nil {
+ return 0, err
+ }
+ im, err := LoadIssuesFromColumnList(ctx, bs, doer, org, isClosed)
+ if err != nil {
+ return 0, err
+ }
+ for _, il := range im {
+ numIssuesInProject += len(il)
+ }
+ return numIssuesInProject, nil
+}
diff --git a/models/issues/issue_project_test.go b/models/issues/issue_project_test.go
new file mode 100644
index 0000000000..099679a8c7
--- /dev/null
+++ b/models/issues/issue_project_test.go
@@ -0,0 +1,173 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package issues_test
+
+import (
+ "testing"
+
+ "forgejo.org/models/db"
+ "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/project"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ "forgejo.org/tests"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestPrivateIssueProjects(t *testing.T) {
+ defer unittest.OverrideFixtures("models/fixtures/PrivateIssueProjects")()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ t.Run("Organization project", func(t *testing.T) {
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
+ orgProject := unittest.AssertExistsAndLoadBean(t, &project.Project{ID: 1001, OwnerID: org.ID})
+ column := unittest.AssertExistsAndLoadBean(t, &project.Column{ID: 1001, ProjectID: orgProject.ID})
+
+ t.Run("Authenticated user", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+ issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, user2, org, optional.None[bool]())
+ require.NoError(t, err)
+ assert.Len(t, issueList, 2)
+ assert.EqualValues(t, 16, issueList[0].ID)
+ assert.EqualValues(t, 6, issueList[1].ID)
+
+ issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.None[bool]())
+ require.NoError(t, err)
+ assert.EqualValues(t, 2, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.Some(true))
+ require.NoError(t, err)
+ assert.EqualValues(t, 0, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.Some(false))
+ require.NoError(t, err)
+ assert.EqualValues(t, 2, issuesNum)
+ })
+
+ t.Run("Anonymous user", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+ issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, nil, org, optional.None[bool]())
+ require.NoError(t, err)
+ assert.Len(t, issueList, 1)
+ assert.EqualValues(t, 16, issueList[0].ID)
+
+ issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, orgProject, nil, org, optional.None[bool]())
+ require.NoError(t, err)
+ assert.EqualValues(t, 1, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, nil, org, optional.Some(true))
+ require.NoError(t, err)
+ assert.EqualValues(t, 0, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, nil, org, optional.Some(false))
+ require.NoError(t, err)
+ assert.EqualValues(t, 1, issuesNum)
+ })
+ })
+
+ t.Run("User project", func(t *testing.T) {
+ userProject := unittest.AssertExistsAndLoadBean(t, &project.Project{ID: 1002, OwnerID: user2.ID})
+ column := unittest.AssertExistsAndLoadBean(t, &project.Column{ID: 1002, ProjectID: userProject.ID})
+
+ t.Run("Authenticated user", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+ issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, user2, nil, optional.None[bool]())
+ require.NoError(t, err)
+ assert.Len(t, issueList, 2)
+ assert.EqualValues(t, 7, issueList[0].ID)
+ assert.EqualValues(t, 1, issueList[1].ID)
+
+ issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, userProject, user2, nil, optional.None[bool]())
+ require.NoError(t, err)
+ assert.EqualValues(t, 2, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, userProject, user2, nil, optional.Some(true))
+ require.NoError(t, err)
+ assert.EqualValues(t, 0, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, userProject, user2, nil, optional.Some(false))
+ require.NoError(t, err)
+ assert.EqualValues(t, 2, issuesNum)
+ })
+
+ t.Run("Anonymous user", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+ issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, nil, nil, optional.None[bool]())
+ require.NoError(t, err)
+ assert.Len(t, issueList, 1)
+ assert.EqualValues(t, 1, issueList[0].ID)
+
+ issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, userProject, nil, nil, optional.None[bool]())
+ require.NoError(t, err)
+ assert.EqualValues(t, 1, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, userProject, nil, nil, optional.Some(true))
+ require.NoError(t, err)
+ assert.EqualValues(t, 0, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, userProject, nil, nil, optional.Some(false))
+ require.NoError(t, err)
+ assert.EqualValues(t, 1, issuesNum)
+ })
+ })
+}
+
+func TestPrivateRepoProjects(t *testing.T) {
+ defer unittest.OverrideFixtures("models/fixtures/TestPrivateRepoProjects")()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
+ orgProject := unittest.AssertExistsAndLoadBean(t, &project.Project{ID: 1001, OwnerID: org.ID})
+ column := unittest.AssertExistsAndLoadBean(t, &project.Column{ID: 1001, ProjectID: orgProject.ID})
+
+ t.Run("Partial access", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+ user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29})
+
+ issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, user29, org, optional.None[bool]())
+ require.NoError(t, err)
+ assert.Len(t, issueList, 1)
+ assert.EqualValues(t, 6, issueList[0].ID)
+
+ issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, orgProject, user29, org, optional.None[bool]())
+ require.NoError(t, err)
+ assert.EqualValues(t, 1, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user29, org, optional.Some(true))
+ require.NoError(t, err)
+ assert.EqualValues(t, 0, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user29, org, optional.Some(false))
+ require.NoError(t, err)
+ assert.EqualValues(t, 1, issuesNum)
+ })
+
+ t.Run("Full access", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ issueList, err := issues.LoadIssuesFromColumn(db.DefaultContext, column, user2, org, optional.None[bool]())
+ require.NoError(t, err)
+ assert.Len(t, issueList, 2)
+ assert.EqualValues(t, 15, issueList[0].ID)
+ assert.EqualValues(t, 6, issueList[1].ID)
+
+ issuesNum, err := issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.None[bool]())
+ require.NoError(t, err)
+ assert.EqualValues(t, 2, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.Some(true))
+ require.NoError(t, err)
+ assert.EqualValues(t, 0, issuesNum)
+
+ issuesNum, err = issues.NumIssuesInProject(db.DefaultContext, orgProject, user2, org, optional.Some(false))
+ require.NoError(t, err)
+ assert.EqualValues(t, 2, issuesNum)
+ })
+}
diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go
index e9f116bfc6..bf4b89ee0b 100644
--- a/models/issues/issue_search.go
+++ b/models/issues/issue_search.go
@@ -9,13 +9,13 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/optional"
"xorm.io/builder"
"xorm.io/xorm"
@@ -49,9 +49,13 @@ type IssuesOptions struct { //nolint
// prioritize issues from this repo
PriorityRepoID int64
IsArchived optional.Option[bool]
- Org *organization.Organization // issues permission scope
- Team *organization.Team // issues permission scope
- User *user_model.User // issues permission scope
+
+ // If combined with AllPublic, then private as well as public issues
+ // that matches the criteria will be returned, if AllPublic is false
+ // only the private issues will be returned.
+ Org *organization.Organization // issues permission scope
+ Team *organization.Team // issues permission scope
+ User *user_model.User // issues permission scope
}
// applySorts sort an issues-related session based on the provided
@@ -196,7 +200,8 @@ func applyRepoConditions(sess *xorm.Session, opts *IssuesOptions) {
} else if len(opts.RepoIDs) > 1 {
opts.RepoCond = builder.In("issue.repo_id", opts.RepoIDs)
}
- if opts.AllPublic {
+ // If permission scoping is set, then we set this condition at a later stage.
+ if opts.AllPublic && opts.User == nil {
if opts.RepoCond == nil {
opts.RepoCond = builder.NewCond()
}
@@ -268,7 +273,14 @@ func applyConditions(sess *xorm.Session, opts *IssuesOptions) {
applyLabelsCondition(sess, opts)
if opts.User != nil {
- sess.And(issuePullAccessibleRepoCond("issue.repo_id", opts.User.ID, opts.Org, opts.Team, opts.IsPull.Value()))
+ cond := issuePullAccessibleRepoCond("issue.repo_id", opts.User.ID, opts.Org, opts.Team, opts.IsPull.Value())
+ // If AllPublic was set, then also consider all issues in public
+ // repositories in addition to the private repositories the user has access
+ // to.
+ if opts.AllPublic {
+ cond = cond.Or(builder.In("issue.repo_id", builder.Select("id").From("repository").Where(builder.Eq{"is_private": false})))
+ }
+ sess.And(cond)
}
}
@@ -329,6 +341,9 @@ func issuePullAccessibleRepoCond(repoIDstr string, userID int64, org *organizati
builder.Or(
repo_model.UserOrgUnitRepoCond(repoIDstr, userID, org.ID, unitType), // team member repos
repo_model.UserOrgPublicUnitRepoCond(userID, org.ID), // user org public non-member repos, TODO: check repo has issues
+ builder.And(
+ builder.In("issue.repo_id", builder.Select("id").From("repository").Where(builder.Eq{"owner_id": org.ID})),
+ repo_model.UserAccessRepoCond(repoIDstr, userID)), // user can access org repo in a unit independent way
),
)
}
diff --git a/models/issues/issue_stats.go b/models/issues/issue_stats.go
index dc634cf00e..eee8760b9f 100644
--- a/models/issues/issue_stats.go
+++ b/models/issues/issue_stats.go
@@ -7,7 +7,7 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
"xorm.io/builder"
"xorm.io/xorm"
@@ -15,13 +15,13 @@ import (
// IssueStats represents issue statistic information.
type IssueStats struct {
- OpenCount, ClosedCount int64
- YourRepositoriesCount int64
- AssignCount int64
- CreateCount int64
- MentionCount int64
- ReviewRequestedCount int64
- ReviewedCount int64
+ OpenCount, ClosedCount, AllCount int64
+ YourRepositoriesCount int64
+ AssignCount int64
+ CreateCount int64
+ MentionCount int64
+ ReviewRequestedCount int64
+ ReviewedCount int64
}
// Filter modes.
@@ -104,6 +104,7 @@ func GetIssueStats(ctx context.Context, opts *IssuesOptions) (*IssueStats, error
}
accum.OpenCount += stats.OpenCount
accum.ClosedCount += stats.ClosedCount
+ accum.AllCount += stats.AllCount
accum.YourRepositoriesCount += stats.YourRepositoriesCount
accum.AssignCount += stats.AssignCount
accum.CreateCount += stats.CreateCount
@@ -131,7 +132,13 @@ func getIssueStatsChunk(ctx context.Context, opts *IssuesOptions, issueIDs []int
stats.ClosedCount, err = applyIssuesOptions(sess, opts, issueIDs).
And("issue.is_closed = ?", true).
Count(new(Issue))
- return stats, err
+ if err != nil {
+ return stats, err
+ }
+
+ stats.AllCount = stats.OpenCount + stats.ClosedCount
+
+ return stats, nil
}
func applyIssuesOptions(sess *xorm.Session, opts *IssuesOptions, issueIDs []int64) *xorm.Session {
diff --git a/models/issues/issue_stats_test.go b/models/issues/issue_stats_test.go
index fda75a6b47..549dc04433 100644
--- a/models/issues/issue_stats_test.go
+++ b/models/issues/issue_stats_test.go
@@ -6,9 +6,9 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -25,6 +25,7 @@ func TestGetIssueStats(t *testing.T) {
assert.Equal(t, int64(4), stats.OpenCount)
assert.Equal(t, int64(1), stats.ClosedCount)
+ assert.Equal(t, int64(5), stats.AllCount)
assert.Equal(t, int64(0), stats.YourRepositoriesCount)
assert.Equal(t, int64(0), stats.AssignCount)
assert.Equal(t, int64(0), stats.CreateCount)
diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go
index bdab6bddc4..afca27dfcf 100644
--- a/models/issues/issue_test.go
+++ b/models/issues/issue_test.go
@@ -4,26 +4,26 @@
package issues_test
import (
- "context"
"fmt"
"sort"
"sync"
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/builder"
)
func TestIssue_ReplaceLabels(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(issueID int64, labelIDs, expectedLabelIDs []int64) {
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID})
@@ -34,7 +34,7 @@ func TestIssue_ReplaceLabels(t *testing.T) {
for i, labelID := range labelIDs {
labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID, RepoID: repo.ID})
}
- assert.NoError(t, issues_model.ReplaceIssueLabels(db.DefaultContext, issue, labels, doer))
+ require.NoError(t, issues_model.ReplaceIssueLabels(db.DefaultContext, issue, labels, doer))
unittest.AssertCount(t, &issues_model.IssueLabel{IssueID: issueID}, len(expectedLabelIDs))
for _, labelID := range expectedLabelIDs {
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID})
@@ -52,27 +52,27 @@ func TestIssue_ReplaceLabels(t *testing.T) {
}
func Test_GetIssueIDsByRepoID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
ids, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, ids, 5)
}
func TestIssueAPIURL(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
err := issue.LoadAttributes(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/issues/1", issue.APIURL(db.DefaultContext))
}
func TestGetIssuesByIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(expectedIssueIDs, nonExistentIssueIDs []int64) {
issues, err := issues_model.GetIssuesByIDs(db.DefaultContext, append(expectedIssueIDs, nonExistentIssueIDs...), true)
- assert.NoError(t, err)
+ require.NoError(t, err)
actualIssueIDs := make([]int64, len(issues))
for i, issue := range issues {
actualIssueIDs[i] = issue.ID
@@ -85,21 +85,22 @@ func TestGetIssuesByIDs(t *testing.T) {
}
func TestGetParticipantIDsByIssue(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
checkParticipants := func(issueID int64, userIDs []int) {
issue, err := issues_model.GetIssueByID(db.DefaultContext, issueID)
- assert.NoError(t, err)
+ require.NoError(t, err)
+
participants, err := issue.GetParticipantIDsByIssue(db.DefaultContext)
- if assert.NoError(t, err) {
- participantsIDs := make([]int, len(participants))
- for i, uid := range participants {
- participantsIDs[i] = int(uid)
- }
- sort.Ints(participantsIDs)
- sort.Ints(userIDs)
- assert.Equal(t, userIDs, participantsIDs)
+ require.NoError(t, err)
+
+ participantsIDs := make([]int, len(participants))
+ for i, uid := range participants {
+ participantsIDs[i] = int(uid)
}
+ sort.Ints(participantsIDs)
+ sort.Ints(userIDs)
+ assert.Equal(t, userIDs, participantsIDs)
}
// User 1 is issue1 poster (see fixtures/issue.yml)
@@ -119,16 +120,16 @@ func TestIssue_ClearLabels(t *testing.T) {
{3, 2}, // pull-request, has no labels
}
for _, test := range tests {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID})
- assert.NoError(t, issues_model.ClearIssueLabels(db.DefaultContext, issue, doer))
+ require.NoError(t, issues_model.ClearIssueLabels(db.DefaultContext, issue, doer))
unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: test.issueID})
}
}
func TestUpdateIssueCols(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{})
const newTitle = "New Title for unit test"
@@ -138,7 +139,7 @@ func TestUpdateIssueCols(t *testing.T) {
issue.Content = "This should have no effect"
now := time.Now().Unix()
- assert.NoError(t, issues_model.UpdateIssueCols(db.DefaultContext, issue, "name"))
+ require.NoError(t, issues_model.UpdateIssueCols(db.DefaultContext, issue, "name"))
then := time.Now().Unix()
updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID})
@@ -148,7 +149,7 @@ func TestUpdateIssueCols(t *testing.T) {
}
func TestIssues(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
for _, test := range []struct {
Opts issues_model.IssuesOptions
ExpectedIssueIDs []int64
@@ -212,7 +213,7 @@ func TestIssues(t *testing.T) {
},
} {
issues, err := issues_model.Issues(db.DefaultContext, &test.Opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, issues, len(test.ExpectedIssueIDs)) {
for i, issue := range issues {
assert.EqualValues(t, test.ExpectedIssueIDs[i], issue.ID)
@@ -222,10 +223,10 @@ func TestIssues(t *testing.T) {
}
func TestIssue_loadTotalTimes(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
ms, err := issues_model.GetIssueByID(db.DefaultContext, 2)
- assert.NoError(t, err)
- assert.NoError(t, ms.LoadTotalTimes(db.DefaultContext))
+ require.NoError(t, err)
+ require.NoError(t, ms.LoadTotalTimes(db.DefaultContext))
assert.Equal(t, int64(3682), ms.TotalTrackedTime)
}
@@ -243,10 +244,10 @@ func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *is
Content: content,
}
err := issues_model.NewIssue(db.DefaultContext, repo, &issue, nil, nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
has, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Get(&newIssue)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
assert.EqualValues(t, issue.Title, newIssue.Title)
assert.EqualValues(t, issue.Content, newIssue.Content)
@@ -258,20 +259,20 @@ func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *is
}
func TestIssue_InsertIssue(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// there are 5 issues and max index is 5 on repository 1, so this one should 6
issue := testInsertIssue(t, "my issue1", "special issue's comments?", 6)
_, err := db.DeleteByID[issues_model.Issue](db.DefaultContext, issue.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue = testInsertIssue(t, `my issue2, this is my son's love \n \r \ `, "special issue's '' comments?", 7)
_, err = db.DeleteByID[issues_model.Issue](db.DefaultContext, issue.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func TestIssue_ResolveMentions(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(owner, repo, doer string, mentions []string, expected []int64) {
o := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: owner})
@@ -279,7 +280,7 @@ func TestIssue_ResolveMentions(t *testing.T) {
issue := &issues_model.Issue{RepoID: r.ID}
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: doer})
resolved, err := issues_model.ResolveIssueMentionsByVisibility(db.DefaultContext, issue, d, mentions)
- assert.NoError(t, err)
+ require.NoError(t, err)
ids := make([]int64, len(resolved))
for i, user := range resolved {
ids[i] = user.ID
@@ -305,21 +306,33 @@ func TestIssue_ResolveMentions(t *testing.T) {
}
func TestResourceIndex(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ beforeCount, err := issues_model.CountIssues(t.Context(), &issues_model.IssuesOptions{})
+ require.NoError(t, err)
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
- go func(i int) {
+ t.Run(fmt.Sprintf("issue %d", i+1), func(t *testing.T) {
+ t.Parallel()
testInsertIssue(t, fmt.Sprintf("issue %d", i+1), "my issue", 0)
wg.Done()
- }(i)
+ })
}
- wg.Wait()
+
+ t.Run("Check the count", func(t *testing.T) {
+ t.Parallel()
+
+ wg.Wait()
+ afterCount, err := issues_model.CountIssues(t.Context(), &issues_model.IssuesOptions{})
+ require.NoError(t, err)
+ assert.EqualValues(t, 100, afterCount-beforeCount)
+ })
}
func TestCorrectIssueStats(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Because the condition is to have chunked database look-ups,
// We have to more issues than `maxQueryParameters`, we will insert.
@@ -340,7 +353,7 @@ func TestCorrectIssueStats(t *testing.T) {
wg.Wait()
// Now we will get all issueID's that match the "Bugs are nasty" query.
- issues, err := issues_model.Issues(context.TODO(), &issues_model.IssuesOptions{
+ issues, err := issues_model.Issues(t.Context(), &issues_model.IssuesOptions{
Paginator: &db.ListOptions{
PageSize: issueAmount,
},
@@ -355,7 +368,7 @@ func TestCorrectIssueStats(t *testing.T) {
}
// Just to be sure.
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, issueAmount, total)
// Now we will call the GetIssueStats with these IDs and if working,
@@ -366,39 +379,39 @@ func TestCorrectIssueStats(t *testing.T) {
})
// Now check the values.
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, issueStats.OpenCount, issueAmount)
}
func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
miles := issues_model.MilestoneList{
unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}),
}
- assert.NoError(t, miles.LoadTotalTrackedTimes(db.DefaultContext))
+ require.NoError(t, miles.LoadTotalTrackedTimes(db.DefaultContext))
assert.Equal(t, int64(3682), miles[0].TotalTrackedTime)
}
func TestLoadTotalTrackedTime(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
- assert.NoError(t, milestone.LoadTotalTrackedTime(db.DefaultContext))
+ require.NoError(t, milestone.LoadTotalTrackedTime(db.DefaultContext))
assert.Equal(t, int64(3682), milestone.TotalTrackedTime)
}
func TestCountIssues(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
count, err := issues_model.CountIssues(db.DefaultContext, &issues_model.IssuesOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 22, count)
}
func TestIssueLoadAttributes(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
setting.Service.EnableTimetracking = true
issueList := issues_model.IssueList{
@@ -407,7 +420,7 @@ func TestIssueLoadAttributes(t *testing.T) {
}
for _, issue := range issueList {
- assert.NoError(t, issue.LoadAttributes(db.DefaultContext))
+ require.NoError(t, issue.LoadAttributes(db.DefaultContext))
assert.EqualValues(t, issue.RepoID, issue.Repo.ID)
for _, label := range issue.Labels {
assert.EqualValues(t, issue.RepoID, label.RepoID)
@@ -442,13 +455,13 @@ func TestIssueLoadAttributes(t *testing.T) {
}
func assertCreateIssues(t *testing.T, isPull bool) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
reponame := "repo1"
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
- assert.EqualValues(t, milestone.ID, 1)
+ assert.EqualValues(t, 1, milestone.ID)
reaction := &issues_model.Reaction{
Type: "heart",
UserID: owner.ID,
@@ -469,7 +482,7 @@ func assertCreateIssues(t *testing.T, isPull bool) {
Reactions: []*issues_model.Reaction{reaction},
}
err := issues_model.InsertIssues(db.DefaultContext, is)
- assert.NoError(t, err)
+ require.NoError(t, err)
i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: title})
unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: owner.ID, IssueID: i.ID})
diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go
index dbfd2fc91b..9d0bc84454 100644
--- a/models/issues/issue_update.go
+++ b/models/issues/issue_update.go
@@ -8,19 +8,20 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- project_model "code.gitea.io/gitea/models/project"
- repo_model "code.gitea.io/gitea/models/repo"
- system_model "code.gitea.io/gitea/models/system"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/references"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ project_model "forgejo.org/models/project"
+ repo_model "forgejo.org/models/repo"
+ system_model "forgejo.org/models/system"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/references"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -63,6 +64,10 @@ func changeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User,
}
func doChangeIssueStatus(ctx context.Context, issue *Issue, doer *user_model.User, isMergePull bool) (*Comment, error) {
+ if user_model.IsBlockedMultiple(ctx, []int64{issue.Repo.OwnerID, issue.PosterID}, doer.ID) {
+ return nil, user_model.ErrBlockedByUser
+ }
+
// Check for open dependencies
if issue.IsClosed && issue.Repo.IsDependenciesEnabled(ctx) {
// only check if dependencies are enabled and we're about to close an issue, otherwise reopening an issue would fail when there are unsatisfied dependencies
@@ -154,6 +159,7 @@ func ChangeIssueTitle(ctx context.Context, issue *Issue, doer *user_model.User,
}
defer committer.Close()
+ issue.Title, _ = util.SplitStringAtByteN(issue.Title, 255)
if err = UpdateIssueCols(ctx, issue, "name"); err != nil {
return fmt.Errorf("updateIssueCols: %w", err)
}
@@ -409,6 +415,7 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue
}
// NewIssue creates new issue with labels for repository.
+// The title will be cut off at 255 characters if it's longer than 255 characters.
func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string) (err error) {
ctx, committer, err := db.TxContext(ctx)
if err != nil {
@@ -422,6 +429,7 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, la
}
issue.Index = idx
+ issue.Title, _ = util.SplitStringAtByteN(issue.Title, 255)
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
Repo: repo,
@@ -429,7 +437,7 @@ func NewIssue(ctx context.Context, repo *repo_model.Repository, issue *Issue, la
LabelIDs: labelIDs,
Attachments: uuids,
}); err != nil {
- if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) {
+ if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
return err
}
return fmt.Errorf("newIssue: %w", err)
diff --git a/models/issues/issue_user.go b/models/issues/issue_user.go
index 6b59e0725e..70e162411f 100644
--- a/models/issues/issue_user.go
+++ b/models/issues/issue_user.go
@@ -7,8 +7,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
)
// IssueUser represents an issue-user relation.
diff --git a/models/issues/issue_user_test.go b/models/issues/issue_user_test.go
index ce47adb53a..77e6c5bc5a 100644
--- a/models/issues/issue_user_test.go
+++ b/models/issues/issue_user_test.go
@@ -6,16 +6,16 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_NewIssueUsers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
newIssue := &issues_model.Issue{
@@ -29,7 +29,7 @@ func Test_NewIssueUsers(t *testing.T) {
// artificially insert new issue
unittest.AssertSuccessfulInsert(t, newIssue)
- assert.NoError(t, issues_model.NewIssueUsers(db.DefaultContext, repo, newIssue))
+ require.NoError(t, issues_model.NewIssueUsers(db.DefaultContext, repo, newIssue))
// issue_user table should now have entries for new issue
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: newIssue.ID, UID: newIssue.PosterID})
@@ -37,24 +37,24 @@ func Test_NewIssueUsers(t *testing.T) {
}
func TestUpdateIssueUserByRead(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
- assert.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, 4, issue.ID))
+ require.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, 4, issue.ID))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1")
- assert.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, 4, issue.ID))
+ require.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, 4, issue.ID))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1")
- assert.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID))
+ require.NoError(t, issues_model.UpdateIssueUserByRead(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID))
}
func TestUpdateIssueUsersByMentions(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
uids := []int64{2, 5}
- assert.NoError(t, issues_model.UpdateIssueUsersByMentions(db.DefaultContext, issue.ID, uids))
+ require.NoError(t, issues_model.UpdateIssueUsersByMentions(db.DefaultContext, issue.ID, uids))
for _, uid := range uids {
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: uid}, "is_mentioned=1")
}
diff --git a/models/issues/issue_watch.go b/models/issues/issue_watch.go
index 9e616a0eb1..ecc09e1e81 100644
--- a/models/issues/issue_watch.go
+++ b/models/issues/issue_watch.go
@@ -6,10 +6,10 @@ package issues
import (
"context"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
)
// IssueWatch is connection request for receiving issue notification.
@@ -105,7 +105,7 @@ func GetIssueWatchers(ctx context.Context, issueID int64, listOptions db.ListOpt
And("`user`.prohibit_login = ?", false).
Join("INNER", "`user`", "`user`.id = `issue_watch`.user_id")
- if listOptions.Page != 0 {
+ if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
watches := make([]*IssueWatch, 0, listOptions.PageSize)
return watches, sess.Find(&watches)
diff --git a/models/issues/issue_watch_test.go b/models/issues/issue_watch_test.go
index d4ce8d8d3d..a5c01693fa 100644
--- a/models/issues/issue_watch_test.go
+++ b/models/issues/issue_watch_test.go
@@ -6,62 +6,63 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCreateOrUpdateIssueWatch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
- assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(db.DefaultContext, 3, 1, true))
+ require.NoError(t, issues_model.CreateOrUpdateIssueWatch(db.DefaultContext, 3, 1, true))
iw := unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 3, IssueID: 1})
assert.True(t, iw.IsWatching)
- assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(db.DefaultContext, 1, 1, false))
+ require.NoError(t, issues_model.CreateOrUpdateIssueWatch(db.DefaultContext, 1, 1, false))
iw = unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 1, IssueID: 1})
assert.False(t, iw.IsWatching)
}
func TestGetIssueWatch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
_, exists, err := issues_model.GetIssueWatch(db.DefaultContext, 9, 1)
assert.True(t, exists)
- assert.NoError(t, err)
+ require.NoError(t, err)
iw, exists, err := issues_model.GetIssueWatch(db.DefaultContext, 2, 2)
assert.True(t, exists)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, iw.IsWatching)
_, exists, err = issues_model.GetIssueWatch(db.DefaultContext, 3, 1)
assert.False(t, exists)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func TestGetIssueWatchers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
iws, err := issues_model.GetIssueWatchers(db.DefaultContext, 1, db.ListOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// Watcher is inactive, thus 0
- assert.Len(t, iws, 0)
+ assert.Empty(t, iws)
iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 2, db.ListOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// Watcher is explicit not watching
- assert.Len(t, iws, 0)
+ assert.Empty(t, iws)
iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 5, db.ListOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// Issue has no Watchers
- assert.Len(t, iws, 0)
+ assert.Empty(t, iws)
iws, err = issues_model.GetIssueWatchers(db.DefaultContext, 7, db.ListOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// Issue has one watcher
assert.Len(t, iws, 1)
}
diff --git a/models/issues/issue_xref.go b/models/issues/issue_xref.go
index 9c9d5d66cd..4c753a58eb 100644
--- a/models/issues/issue_xref.go
+++ b/models/issues/issue_xref.go
@@ -7,12 +7,12 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/references"
+ "forgejo.org/models/db"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/references"
)
type crossReference struct {
diff --git a/models/issues/issue_xref_test.go b/models/issues/issue_xref_test.go
index f1b1bb2a6b..e74717be1e 100644
--- a/models/issues/issue_xref_test.go
+++ b/models/issues/issue_xref_test.go
@@ -7,18 +7,19 @@ import (
"fmt"
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/references"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/references"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestXRef_AddCrossReferences(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Issue #1 to test against
itarget := testCreateIssue(t, 1, 2, "title1", "content1", false)
@@ -69,7 +70,7 @@ func TestXRef_AddCrossReferences(t *testing.T) {
}
func TestXRef_NeuterCrossReferences(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Issue #1 to test against
itarget := testCreateIssue(t, 1, 2, "title1", "content1", false)
@@ -83,7 +84,7 @@ func TestXRef_NeuterCrossReferences(t *testing.T) {
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
i.Title = "title2, no mentions"
- assert.NoError(t, issues_model.ChangeIssueTitle(db.DefaultContext, i, d, title))
+ require.NoError(t, issues_model.ChangeIssueTitle(db.DefaultContext, i, d, title))
ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0})
assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type)
@@ -91,7 +92,7 @@ func TestXRef_NeuterCrossReferences(t *testing.T) {
}
func TestXRef_ResolveCrossReferences(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -99,7 +100,7 @@ func TestXRef_ResolveCrossReferences(t *testing.T) {
i2 := testCreateIssue(t, 1, 2, "title2", "content2", false)
i3 := testCreateIssue(t, 1, 2, "title3", "content3", false)
_, err := issues_model.ChangeIssueStatus(db.DefaultContext, i3, d, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index))
rp := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0})
@@ -119,7 +120,7 @@ func TestXRef_ResolveCrossReferences(t *testing.T) {
r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID})
refs, err := pr.ResolveCrossReferences(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, refs, 3)
assert.Equal(t, rp.ID, refs[0].ID, "bad ref rp: %+v", refs[0])
assert.Equal(t, r1.ID, refs[1].ID, "bad ref r1: %+v", refs[1])
@@ -131,11 +132,11 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer})
ctx, committer, err := db.TxContext(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer committer.Close()
idx, err := db.GetNextResourceIndex(ctx, "issue_index", r.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
i := &issues_model.Issue{
RepoID: r.ID,
PosterID: d.ID,
@@ -150,11 +151,11 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu
Repo: r,
Issue: i,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
i, err = issues_model.GetIssueByID(ctx, i.ID)
- assert.NoError(t, err)
- assert.NoError(t, i.AddCrossReferences(ctx, d, false))
- assert.NoError(t, committer.Commit())
+ require.NoError(t, err)
+ require.NoError(t, i.AddCrossReferences(ctx, d, false))
+ require.NoError(t, committer.Commit())
return i
}
@@ -163,7 +164,7 @@ func testCreatePR(t *testing.T, repo, doer int64, title, content string) *issues
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer})
i := &issues_model.Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true}
pr := &issues_model.PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: issues_model.PullRequestStatusMergeable}
- assert.NoError(t, issues_model.NewPullRequest(db.DefaultContext, r, i, nil, nil, pr))
+ require.NoError(t, issues_model.NewPullRequest(db.DefaultContext, r, i, nil, nil, pr))
pr.Issue = i
return pr
}
@@ -174,11 +175,11 @@ func testCreateComment(t *testing.T, doer, issue int64, content string) *issues_
c := &issues_model.Comment{Type: issues_model.CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content}
ctx, committer, err := db.TxContext(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer committer.Close()
err = db.Insert(ctx, c)
- assert.NoError(t, err)
- assert.NoError(t, c.AddCrossReferences(ctx, d, false))
- assert.NoError(t, committer.Commit())
+ require.NoError(t, err)
+ require.NoError(t, c.AddCrossReferences(ctx, d, false))
+ require.NoError(t, committer.Commit())
return c
}
diff --git a/models/issues/label.go b/models/issues/label.go
index 61478e17ac..264ca8cc3d 100644
--- a/models/issues/label.go
+++ b/models/issues/label.go
@@ -11,11 +11,11 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/label"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/label"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -303,6 +303,9 @@ func GetLabelByID(ctx context.Context, labelID int64) (*Label, error) {
// GetLabelsByIDs returns a list of labels by IDs
func GetLabelsByIDs(ctx context.Context, labelIDs []int64, cols ...string) ([]*Label, error) {
labels := make([]*Label, 0, len(labelIDs))
+ if len(labelIDs) == 0 {
+ return labels, nil
+ }
return labels, db.GetEngine(ctx).Table("label").
In("id", labelIDs).
Asc("name").
@@ -353,6 +356,17 @@ func GetLabelIDsInRepoByNames(ctx context.Context, repoID int64, labelNames []st
Find(&labelIDs)
}
+// GetLabelIDsInOrgByNames returns a list of labelIDs by names in a given org.
+func GetLabelIDsInOrgByNames(ctx context.Context, orgID int64, labelNames []string) ([]int64, error) {
+ labelIDs := make([]int64, 0, len(labelNames))
+ return labelIDs, db.GetEngine(ctx).Table("label").
+ Where("org_id = ?", orgID).
+ In("name", labelNames).
+ Asc("name").
+ Cols("id").
+ Find(&labelIDs)
+}
+
// BuildLabelNamesIssueIDsCondition returns a builder where get issue ids match label names
func BuildLabelNamesIssueIDsCondition(labelNames []string) *builder.Builder {
return builder.Select("issue_label.issue_id").
@@ -368,6 +382,9 @@ func BuildLabelNamesIssueIDsCondition(labelNames []string) *builder.Builder {
// it silently ignores label IDs that do not belong to the repository.
func GetLabelsInRepoByIDs(ctx context.Context, repoID int64, labelIDs []int64) ([]*Label, error) {
labels := make([]*Label, 0, len(labelIDs))
+ if len(labelIDs) == 0 {
+ return labels, nil
+ }
return labels, db.GetEngine(ctx).
Where("repo_id = ?", repoID).
In("id", labelIDs).
@@ -394,7 +411,7 @@ func GetLabelsByRepoID(ctx context.Context, repoID int64, sortType string, listO
sess.Asc("name")
}
- if listOptions.Page != 0 {
+ if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
}
@@ -440,6 +457,9 @@ func GetLabelInOrgByID(ctx context.Context, orgID, labelID int64) (*Label, error
// it silently ignores label IDs that do not belong to the organization.
func GetLabelsInOrgByIDs(ctx context.Context, orgID int64, labelIDs []int64) ([]*Label, error) {
labels := make([]*Label, 0, len(labelIDs))
+ if len(labelIDs) == 0 {
+ return labels, nil
+ }
return labels, db.GetEngine(ctx).
Where("org_id = ?", orgID).
In("id", labelIDs).
@@ -466,7 +486,7 @@ func GetLabelsByOrgID(ctx context.Context, orgID int64, sortType string, listOpt
sess.Asc("name")
}
- if listOptions.Page != 0 {
+ if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
}
diff --git a/models/issues/label_test.go b/models/issues/label_test.go
index 9934429748..f2ba28a6d2 100644
--- a/models/issues/label_test.go
+++ b/models/issues/label_test.go
@@ -6,25 +6,26 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestLabel_CalOpenIssues(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
label.CalOpenIssues()
assert.EqualValues(t, 2, label.NumOpenIssues)
}
func TestLabel_LoadSelectedLabelsAfterClick(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Loading the label id:8 (scope/label2) which have a scope and an
// exclusivity with id:7 (scope/label1)
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 8})
@@ -32,12 +33,12 @@ func TestLabel_LoadSelectedLabelsAfterClick(t *testing.T) {
// First test : with negative and scope
label.LoadSelectedLabelsAfterClick([]int64{1, -8}, []string{"", "scope"})
assert.Equal(t, "1", label.QueryString)
- assert.Equal(t, true, label.IsSelected)
+ assert.True(t, label.IsSelected)
// Second test : with duplicates
label.LoadSelectedLabelsAfterClick([]int64{1, 7, 1, 7, 7}, []string{"", "scope", "", "scope", "scope"})
assert.Equal(t, "1,8", label.QueryString)
- assert.Equal(t, false, label.IsSelected)
+ assert.False(t, label.IsSelected)
// Third test : empty set
label.LoadSelectedLabelsAfterClick([]int64{}, []string{})
@@ -46,7 +47,7 @@ func TestLabel_LoadSelectedLabelsAfterClick(t *testing.T) {
}
func TestLabel_ExclusiveScope(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 7})
assert.Equal(t, "scope", label.ExclusiveScope())
@@ -55,22 +56,22 @@ func TestLabel_ExclusiveScope(t *testing.T) {
}
func TestNewLabels(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
labels := []*issues_model.Label{
{RepoID: 2, Name: "labelName2", Color: "#123456"},
{RepoID: 3, Name: "labelName3", Color: "#123"},
{RepoID: 4, Name: "labelName4", Color: "ABCDEF"},
{RepoID: 5, Name: "labelName5", Color: "DEF"},
}
- assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: ""}))
- assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#45G"}))
- assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"}))
- assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "45G"}))
- assert.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "12345G"}))
+ require.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: ""}))
+ require.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#45G"}))
+ require.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "#12345G"}))
+ require.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "45G"}))
+ require.Error(t, issues_model.NewLabel(db.DefaultContext, &issues_model.Label{RepoID: 3, Name: "invalid Color", Color: "12345G"}))
for _, label := range labels {
unittest.AssertNotExistsBean(t, label)
}
- assert.NoError(t, issues_model.NewLabels(db.DefaultContext, labels...))
+ require.NoError(t, issues_model.NewLabels(db.DefaultContext, labels...))
for _, label := range labels {
unittest.AssertExistsAndLoadBean(t, label, unittest.Cond("id = ?", label.ID))
}
@@ -78,9 +79,9 @@ func TestNewLabels(t *testing.T) {
}
func TestGetLabelByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label, err := issues_model.GetLabelByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, label.ID)
_, err = issues_model.GetLabelByID(db.DefaultContext, unittest.NonexistentID)
@@ -88,9 +89,9 @@ func TestGetLabelByID(t *testing.T) {
}
func TestGetLabelInRepoByName(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label, err := issues_model.GetLabelInRepoByName(db.DefaultContext, 1, "label1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, label.ID)
assert.Equal(t, "label1", label.Name)
@@ -102,9 +103,9 @@ func TestGetLabelInRepoByName(t *testing.T) {
}
func TestGetLabelInRepoByNames(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
labelIDs, err := issues_model.GetLabelIDsInRepoByNames(db.DefaultContext, 1, []string{"label1", "label2"})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, labelIDs, 2)
@@ -113,22 +114,22 @@ func TestGetLabelInRepoByNames(t *testing.T) {
}
func TestGetLabelInRepoByNamesDiscardsNonExistentLabels(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// label3 doesn't exists.. See labels.yml
labelIDs, err := issues_model.GetLabelIDsInRepoByNames(db.DefaultContext, 1, []string{"label1", "label2", "label3"})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, labelIDs, 2)
assert.Equal(t, int64(1), labelIDs[0])
assert.Equal(t, int64(2), labelIDs[1])
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func TestGetLabelInRepoByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label, err := issues_model.GetLabelInRepoByID(db.DefaultContext, 1, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, label.ID)
_, err = issues_model.GetLabelInRepoByID(db.DefaultContext, 1, -1)
@@ -139,9 +140,9 @@ func TestGetLabelInRepoByID(t *testing.T) {
}
func TestGetLabelsInRepoByIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
labels, err := issues_model.GetLabelsInRepoByIDs(db.DefaultContext, 1, []int64{1, 2, unittest.NonexistentID})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, labels, 2) {
assert.EqualValues(t, 1, labels[0].ID)
assert.EqualValues(t, 2, labels[1].ID)
@@ -149,10 +150,10 @@ func TestGetLabelsInRepoByIDs(t *testing.T) {
}
func TestGetLabelsByRepoID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(repoID int64, sortType string, expectedIssueIDs []int64) {
labels, err := issues_model.GetLabelsByRepoID(db.DefaultContext, repoID, sortType, db.ListOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, labels, len(expectedIssueIDs))
for i, label := range labels {
assert.EqualValues(t, expectedIssueIDs[i], label.ID)
@@ -167,9 +168,9 @@ func TestGetLabelsByRepoID(t *testing.T) {
// Org versions
func TestGetLabelInOrgByName(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label, err := issues_model.GetLabelInOrgByName(db.DefaultContext, 3, "orglabel3")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, label.ID)
assert.Equal(t, "orglabel3", label.Name)
@@ -187,9 +188,9 @@ func TestGetLabelInOrgByName(t *testing.T) {
}
func TestGetLabelInOrgByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label, err := issues_model.GetLabelInOrgByID(db.DefaultContext, 3, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, label.ID)
_, err = issues_model.GetLabelInOrgByID(db.DefaultContext, 3, -1)
@@ -206,9 +207,9 @@ func TestGetLabelInOrgByID(t *testing.T) {
}
func TestGetLabelsInOrgByIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
labels, err := issues_model.GetLabelsInOrgByIDs(db.DefaultContext, 3, []int64{3, 4, unittest.NonexistentID})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, labels, 2) {
assert.EqualValues(t, 3, labels[0].ID)
assert.EqualValues(t, 4, labels[1].ID)
@@ -216,10 +217,10 @@ func TestGetLabelsInOrgByIDs(t *testing.T) {
}
func TestGetLabelsByOrgID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(orgID int64, sortType string, expectedIssueIDs []int64) {
labels, err := issues_model.GetLabelsByOrgID(db.DefaultContext, orgID, sortType, db.ListOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, labels, len(expectedIssueIDs))
for i, label := range labels {
assert.EqualValues(t, expectedIssueIDs[i], label.ID)
@@ -230,8 +231,7 @@ func TestGetLabelsByOrgID(t *testing.T) {
testSuccess(3, "reversealphabetically", []int64{4, 3})
testSuccess(3, "default", []int64{3, 4})
- var err error
- _, err = issues_model.GetLabelsByOrgID(db.DefaultContext, 0, "leastissues", db.ListOptions{})
+ _, err := issues_model.GetLabelsByOrgID(db.DefaultContext, 0, "leastissues", db.ListOptions{})
assert.True(t, issues_model.IsErrOrgLabelNotExist(err))
_, err = issues_model.GetLabelsByOrgID(db.DefaultContext, -1, "leastissues", db.ListOptions{})
@@ -241,20 +241,20 @@ func TestGetLabelsByOrgID(t *testing.T) {
//
func TestGetLabelsByIssueID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
labels, err := issues_model.GetLabelsByIssueID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, labels, 1) {
assert.EqualValues(t, 1, labels[0].ID)
}
labels, err = issues_model.GetLabelsByIssueID(db.DefaultContext, unittest.NonexistentID)
- assert.NoError(t, err)
- assert.Len(t, labels, 0)
+ require.NoError(t, err)
+ assert.Empty(t, labels)
}
func TestUpdateLabel(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
// make sure update won't overwrite it
update := &issues_model.Label{
@@ -267,45 +267,45 @@ func TestUpdateLabel(t *testing.T) {
}
label.Color = update.Color
label.Name = update.Name
- assert.NoError(t, issues_model.UpdateLabel(db.DefaultContext, update))
+ require.NoError(t, issues_model.UpdateLabel(db.DefaultContext, update))
newLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
assert.EqualValues(t, label.ID, newLabel.ID)
assert.EqualValues(t, label.Color, newLabel.Color)
assert.EqualValues(t, label.Name, newLabel.Name)
assert.EqualValues(t, label.Description, newLabel.Description)
- assert.EqualValues(t, newLabel.ArchivedUnix, 0)
+ assert.EqualValues(t, 0, newLabel.ArchivedUnix)
unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{})
}
func TestDeleteLabel(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
- assert.NoError(t, issues_model.DeleteLabel(db.DefaultContext, label.RepoID, label.ID))
+ require.NoError(t, issues_model.DeleteLabel(db.DefaultContext, label.RepoID, label.ID))
unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID, RepoID: label.RepoID})
- assert.NoError(t, issues_model.DeleteLabel(db.DefaultContext, label.RepoID, label.ID))
+ require.NoError(t, issues_model.DeleteLabel(db.DefaultContext, label.RepoID, label.ID))
unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID})
- assert.NoError(t, issues_model.DeleteLabel(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID))
+ require.NoError(t, issues_model.DeleteLabel(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID))
unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{})
}
func TestHasIssueLabel(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.True(t, issues_model.HasIssueLabel(db.DefaultContext, 1, 1))
assert.False(t, issues_model.HasIssueLabel(db.DefaultContext, 1, 2))
assert.False(t, issues_model.HasIssueLabel(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID))
}
func TestNewIssueLabel(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2})
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// add new IssueLabel
prevNumIssues := label.NumIssues
- assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, label, doer))
+ require.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, label, doer))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID})
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{
Type: issues_model.CommentTypeLabel,
@@ -318,12 +318,12 @@ func TestNewIssueLabel(t *testing.T) {
assert.EqualValues(t, prevNumIssues+1, label.NumIssues)
// re-add existing IssueLabel
- assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, label, doer))
+ require.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, label, doer))
unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{})
}
func TestNewIssueExclusiveLabel(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 18})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -332,32 +332,32 @@ func TestNewIssueExclusiveLabel(t *testing.T) {
exclusiveLabelB := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 8})
// coexisting regular and exclusive label
- assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, otherLabel, doer))
- assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, exclusiveLabelA, doer))
+ require.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, otherLabel, doer))
+ require.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, exclusiveLabelA, doer))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: otherLabel.ID})
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelA.ID})
// exclusive label replaces existing one
- assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, exclusiveLabelB, doer))
+ require.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, exclusiveLabelB, doer))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: otherLabel.ID})
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelB.ID})
unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelA.ID})
// exclusive label replaces existing one again
- assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, exclusiveLabelA, doer))
+ require.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, exclusiveLabelA, doer))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: otherLabel.ID})
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelA.ID})
unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: exclusiveLabelB.ID})
}
func TestNewIssueLabels(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2})
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 5})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
- assert.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label2}, doer))
+ require.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{label1, label2}, doer))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID})
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{
Type: issues_model.CommentTypeLabel,
@@ -375,13 +375,13 @@ func TestNewIssueLabels(t *testing.T) {
assert.EqualValues(t, 1, label2.NumClosedIssues)
// corner case: test empty slice
- assert.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{}, doer))
+ require.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{}, doer))
unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.Label{})
}
func TestDeleteIssueLabel(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(labelID, issueID, doerID int64) {
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID})
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID})
@@ -398,9 +398,9 @@ func TestDeleteIssueLabel(t *testing.T) {
ctx, committer, err := db.TxContext(db.DefaultContext)
defer committer.Close()
- assert.NoError(t, err)
- assert.NoError(t, issues_model.DeleteIssueLabel(ctx, issue, label, doer))
- assert.NoError(t, committer.Commit())
+ require.NoError(t, err)
+ require.NoError(t, issues_model.DeleteIssueLabel(ctx, issue, label, doer))
+ require.NoError(t, committer.Commit())
unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: labelID})
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{
diff --git a/models/issues/main_test.go b/models/issues/main_test.go
index ba83ca5552..05d854c964 100644
--- a/models/issues/main_test.go
+++ b/models/issues/main_test.go
@@ -6,20 +6,20 @@ package issues_test
import (
"testing"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
- _ "code.gitea.io/gitea/models/repo"
- _ "code.gitea.io/gitea/models/user"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/repo"
+ _ "forgejo.org/models/user"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestFixturesAreConsistent(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
unittest.CheckConsistencyFor(t,
&issues_model.Issue{},
&issues_model.PullRequest{},
diff --git a/models/issues/milestone.go b/models/issues/milestone.go
index 4b3cb0e858..52433e735d 100644
--- a/models/issues/milestone.go
+++ b/models/issues/milestone.go
@@ -9,12 +9,12 @@ import (
"html/template"
"strings"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/optional"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/optional"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -251,21 +251,6 @@ func ChangeMilestoneStatusByRepoIDAndID(ctx context.Context, repoID, milestoneID
return committer.Commit()
}
-// ChangeMilestoneStatus changes the milestone open/closed status.
-func ChangeMilestoneStatus(ctx context.Context, m *Milestone, isClosed bool) (err error) {
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err := changeMilestoneStatus(ctx, m, isClosed); err != nil {
- return err
- }
-
- return committer.Commit()
-}
-
func changeMilestoneStatus(ctx context.Context, m *Milestone, isClosed bool) error {
m.IsClosed = isClosed
if isClosed {
diff --git a/models/issues/milestone_list.go b/models/issues/milestone_list.go
index d1b3f0301b..e2079fb324 100644
--- a/models/issues/milestone_list.go
+++ b/models/issues/milestone_list.go
@@ -7,8 +7,8 @@ import (
"context"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/optional"
"xorm.io/builder"
)
@@ -70,8 +70,10 @@ func (opts FindMilestoneOptions) ToOrders() string {
return "num_issues DESC"
case "id":
return "id ASC"
+ case "name":
+ return "name DESC"
default:
- return "deadline_unix ASC, id ASC"
+ return "deadline_unix ASC, name ASC"
}
}
diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go
index e5f6f15ca2..bfb4f38ad0 100644
--- a/models/issues/milestone_test.go
+++ b/models/issues/milestone_test.go
@@ -7,16 +7,17 @@ import (
"sort"
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestMilestone_State(t *testing.T) {
@@ -25,10 +26,10 @@ func TestMilestone_State(t *testing.T) {
}
func TestGetMilestoneByRepoID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
milestone, err := issues_model.GetMilestoneByRepoID(db.DefaultContext, 1, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, milestone.ID)
assert.EqualValues(t, 1, milestone.RepoID)
@@ -37,7 +38,7 @@ func TestGetMilestoneByRepoID(t *testing.T) {
}
func TestGetMilestonesByRepoID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64, state api.StateType) {
var isClosed optional.Option[bool]
switch state {
@@ -49,7 +50,7 @@ func TestGetMilestonesByRepoID(t *testing.T) {
RepoID: repo.ID,
IsClosed: isClosed,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
var n int
@@ -86,12 +87,12 @@ func TestGetMilestonesByRepoID(t *testing.T) {
RepoID: unittest.NonexistentID,
IsClosed: optional.Some(false),
})
- assert.NoError(t, err)
- assert.Len(t, milestones, 0)
+ require.NoError(t, err)
+ assert.Empty(t, milestones)
}
func TestGetMilestones(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
test := func(sortType string, sortCond func(*issues_model.Milestone) int) {
for _, page := range []int{0, 1} {
@@ -104,7 +105,7 @@ func TestGetMilestones(t *testing.T) {
IsClosed: optional.Some(false),
SortType: sortType,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, milestones, repo.NumMilestones-repo.NumClosedMilestones)
values := make([]int, len(milestones))
for i, milestone := range milestones {
@@ -122,7 +123,7 @@ func TestGetMilestones(t *testing.T) {
Name: "",
SortType: sortType,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, milestones, repo.NumClosedMilestones)
values = make([]int, len(milestones))
for i, milestone := range milestones {
@@ -152,13 +153,13 @@ func TestGetMilestones(t *testing.T) {
}
func TestCountRepoMilestones(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{
RepoID: repoID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, repo.NumMilestones, count)
}
test(1)
@@ -168,19 +169,19 @@ func TestCountRepoMilestones(t *testing.T) {
count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{
RepoID: unittest.NonexistentID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, count)
}
func TestCountRepoClosedMilestones(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
count, err := db.Count[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{
RepoID: repoID,
IsClosed: optional.Some(true),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, repo.NumClosedMilestones, count)
}
test(1)
@@ -191,12 +192,12 @@ func TestCountRepoClosedMilestones(t *testing.T) {
RepoID: unittest.NonexistentID,
IsClosed: optional.Some(true),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, count)
}
func TestCountMilestonesByRepoIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
milestonesCount := func(repoID int64) (int, int) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
return repo.NumOpenMilestones, repo.NumClosedMilestones
@@ -208,7 +209,7 @@ func TestCountMilestonesByRepoIDs(t *testing.T) {
RepoIDs: []int64{1, 2},
IsClosed: optional.Some(false),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, repo1OpenCount, openCounts[1])
assert.EqualValues(t, repo2OpenCount, openCounts[2])
@@ -217,13 +218,13 @@ func TestCountMilestonesByRepoIDs(t *testing.T) {
RepoIDs: []int64{1, 2},
IsClosed: optional.Some(true),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, repo1ClosedCount, closedCounts[1])
assert.EqualValues(t, repo2ClosedCount, closedCounts[2])
}
func TestGetMilestonesByRepoIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
test := func(sortType string, sortCond func(*issues_model.Milestone) int) {
@@ -237,7 +238,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) {
IsClosed: optional.Some(false),
SortType: sortType,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, openMilestones, repo1.NumOpenMilestones+repo2.NumOpenMilestones)
values := make([]int, len(openMilestones))
for i, milestone := range openMilestones {
@@ -255,7 +256,7 @@ func TestGetMilestonesByRepoIDs(t *testing.T) {
IsClosed: optional.Some(true),
SortType: sortType,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, closedMilestones, repo1.NumClosedMilestones+repo2.NumClosedMilestones)
values = make([]int, len(closedMilestones))
for i, milestone := range closedMilestones {
@@ -285,74 +286,73 @@ func TestGetMilestonesByRepoIDs(t *testing.T) {
}
func TestNewMilestone(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
milestone := &issues_model.Milestone{
RepoID: 1,
Name: "milestoneName",
Content: "milestoneContent",
}
- assert.NoError(t, issues_model.NewMilestone(db.DefaultContext, milestone))
+ require.NoError(t, issues_model.NewMilestone(db.DefaultContext, milestone))
unittest.AssertExistsAndLoadBean(t, milestone)
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{})
}
-func TestChangeMilestoneStatus(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
- milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
+func TestChangeMilestoneStatusByRepoIDAndID(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
- assert.NoError(t, issues_model.ChangeMilestoneStatus(db.DefaultContext, milestone, true))
- unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=1")
- unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{})
+ require.NoError(t, issues_model.ChangeMilestoneStatusByRepoIDAndID(db.DefaultContext, 1, 1, true))
+ unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1, IsClosed: true})
+ unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}, &issues_model.Milestone{})
- assert.NoError(t, issues_model.ChangeMilestoneStatus(db.DefaultContext, milestone, false))
+ require.NoError(t, issues_model.ChangeMilestoneStatusByRepoIDAndID(db.DefaultContext, 1, 1, false))
unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=0")
- unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: milestone.RepoID}, &issues_model.Milestone{})
+ unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1}, &issues_model.Milestone{})
}
func TestDeleteMilestoneByRepoID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
- assert.NoError(t, issues_model.DeleteMilestoneByRepoID(db.DefaultContext, 1, 1))
+ require.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, issues_model.DeleteMilestoneByRepoID(db.DefaultContext, 1, 1))
unittest.AssertNotExistsBean(t, &issues_model.Milestone{ID: 1})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: 1})
- assert.NoError(t, issues_model.DeleteMilestoneByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID))
+ require.NoError(t, issues_model.DeleteMilestoneByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID))
}
func TestUpdateMilestone(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
milestone.Name = " newMilestoneName "
milestone.Content = "newMilestoneContent"
- assert.NoError(t, issues_model.UpdateMilestone(db.DefaultContext, milestone, milestone.IsClosed))
+ require.NoError(t, issues_model.UpdateMilestone(db.DefaultContext, milestone, milestone.IsClosed))
milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
assert.EqualValues(t, "newMilestoneName", milestone.Name)
unittest.CheckConsistencyFor(t, &issues_model.Milestone{})
}
func TestUpdateMilestoneCounters(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{MilestoneID: 1},
"is_closed=0")
issue.IsClosed = true
issue.ClosedUnix = timeutil.TimeStampNow()
_, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue)
- assert.NoError(t, err)
- assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID))
+ require.NoError(t, err)
+ require.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID))
unittest.CheckConsistencyFor(t, &issues_model.Milestone{})
issue.IsClosed = false
issue.ClosedUnix = 0
_, err = db.GetEngine(db.DefaultContext).ID(issue.ID).Cols("is_closed", "closed_unix").Update(issue)
- assert.NoError(t, err)
- assert.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID))
+ require.NoError(t, err)
+ require.NoError(t, issues_model.UpdateMilestoneCounters(db.DefaultContext, issue.MilestoneID))
unittest.CheckConsistencyFor(t, &issues_model.Milestone{})
}
func TestMigrate_InsertMilestones(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
reponame := "repo1"
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame})
name := "milestonetest1"
@@ -361,7 +361,7 @@ func TestMigrate_InsertMilestones(t *testing.T) {
Name: name,
}
err := issues_model.InsertMilestones(db.DefaultContext, ms)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, ms)
repoModified := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID})
assert.EqualValues(t, repo.NumMilestones+1, repoModified.NumMilestones)
diff --git a/models/issues/pull.go b/models/issues/pull.go
index ef49a51045..c46961447c 100644
--- a/models/issues/pull.go
+++ b/models/issues/pull.go
@@ -12,17 +12,17 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- org_model "code.gitea.io/gitea/models/organization"
- pull_model "code.gitea.io/gitea/models/pull"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ org_model "forgejo.org/models/organization"
+ pull_model "forgejo.org/models/pull"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -163,6 +163,7 @@ type PullRequest struct {
Issue *Issue `xorm:"-"`
Index int64
RequestedReviewers []*user_model.User `xorm:"-"`
+ RequestedReviewersTeams []*org_model.Team `xorm:"-"`
isRequestedReviewersLoaded bool `xorm:"-"`
HeadRepoID int64 `xorm:"INDEX"`
@@ -303,7 +304,28 @@ func (pr *PullRequest) LoadRequestedReviewers(ctx context.Context) error {
}
pr.isRequestedReviewersLoaded = true
for _, review := range reviews {
- pr.RequestedReviewers = append(pr.RequestedReviewers, review.Reviewer)
+ if review.ReviewerID != 0 {
+ pr.RequestedReviewers = append(pr.RequestedReviewers, review.Reviewer)
+ }
+ }
+
+ return nil
+}
+
+// LoadRequestedReviewersTeams loads the requested reviewers teams.
+func (pr *PullRequest) LoadRequestedReviewersTeams(ctx context.Context) error {
+ reviews, err := GetReviewsByIssueID(ctx, pr.Issue.ID)
+ if err != nil {
+ return err
+ }
+ if err = reviews.LoadReviewersTeams(ctx); err != nil {
+ return err
+ }
+
+ for _, review := range reviews {
+ if review.ReviewerTeamID != 0 {
+ pr.RequestedReviewersTeams = append(pr.RequestedReviewersTeams, review.ReviewerTeam)
+ }
}
return nil
@@ -386,7 +408,7 @@ func (pr *PullRequest) getReviewedByLines(ctx context.Context, writer io.Writer)
// Note: This doesn't page as we only expect a very limited number of reviews
reviews, err := FindLatestReviews(ctx, FindReviewOptions{
- Type: ReviewTypeApprove,
+ Types: []ReviewType{ReviewTypeApprove},
IssueID: pr.IssueID,
OfficialOnly: setting.Repository.PullRequest.DefaultMergeMessageOfficialApproversOnly,
})
@@ -544,6 +566,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *Iss
}
issue.Index = idx
+ issue.Title, _ = util.SplitStringAtByteN(issue.Title, 255)
if err = NewIssueWithIndex(ctx, issue.Poster, NewIssueOptions{
Repo: repo,
@@ -552,7 +575,7 @@ func NewPullRequest(ctx context.Context, repo *repo_model.Repository, issue *Iss
Attachments: uuids,
IsPull: true,
}); err != nil {
- if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) || IsErrNewIssueInsert(err) {
+ if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
return err
}
return fmt.Errorf("newIssue: %w", err)
@@ -667,7 +690,7 @@ func GetPullRequestByIssueID(ctx context.Context, issueID int64) (*PullRequest,
return pr, pr.LoadAttributes(ctx)
}
-// GetPullRequestsByBaseHeadInfo returns the pull request by given base and head
+// GetPullRequestByBaseHeadInfo returns the pull request by given base and head
func GetPullRequestByBaseHeadInfo(ctx context.Context, baseID, headID int64, base, head string) (*PullRequest, error) {
pr := &PullRequest{}
sess := db.GetEngine(ctx).
diff --git a/models/issues/pull_list.go b/models/issues/pull_list.go
index f3970fa93b..a448673454 100644
--- a/models/issues/pull_list.go
+++ b/models/issues/pull_list.go
@@ -7,14 +7,14 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
"xorm.io/xorm"
)
@@ -26,6 +26,7 @@ type PullRequestsOptions struct {
SortType string
Labels []int64
MilestoneID int64
+ PosterID int64
}
func listPullRequestStatement(ctx context.Context, baseRepoID int64, opts *PullRequestsOptions) *xorm.Session {
@@ -46,6 +47,10 @@ func listPullRequestStatement(ctx context.Context, baseRepoID int64, opts *PullR
sess.And("issue.milestone_id=?", opts.MilestoneID)
}
+ if opts.PosterID > 0 {
+ sess.And("issue.poster_id=?", opts.PosterID)
+ }
+
return sess
}
diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go
index a9d4edc8a5..e85b626c83 100644
--- a/models/issues/pull_test.go
+++ b/models/issues/pull_test.go
@@ -8,51 +8,51 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/tests"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestPullRequest_LoadAttributes(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
- assert.NoError(t, pr.LoadAttributes(db.DefaultContext))
+ require.NoError(t, pr.LoadAttributes(db.DefaultContext))
assert.NotNil(t, pr.Merger)
assert.Equal(t, pr.MergerID, pr.Merger.ID)
}
func TestPullRequest_LoadIssue(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
- assert.NoError(t, pr.LoadIssue(db.DefaultContext))
+ require.NoError(t, pr.LoadIssue(db.DefaultContext))
assert.NotNil(t, pr.Issue)
assert.Equal(t, int64(2), pr.Issue.ID)
- assert.NoError(t, pr.LoadIssue(db.DefaultContext))
+ require.NoError(t, pr.LoadIssue(db.DefaultContext))
assert.NotNil(t, pr.Issue)
assert.Equal(t, int64(2), pr.Issue.ID)
}
func TestPullRequest_LoadBaseRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
- assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
+ require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
assert.NotNil(t, pr.BaseRepo)
assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID)
- assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
+ require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
assert.NotNil(t, pr.BaseRepo)
assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID)
}
func TestPullRequest_LoadHeadRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
- assert.NoError(t, pr.LoadHeadRepo(db.DefaultContext))
+ require.NoError(t, pr.LoadHeadRepo(db.DefaultContext))
assert.NotNil(t, pr.HeadRepo)
assert.Equal(t, pr.HeadRepoID, pr.HeadRepo.ID)
}
@@ -62,7 +62,7 @@ func TestPullRequest_LoadHeadRepo(t *testing.T) {
// TODO TestNewPullRequest
func TestPullRequestsNewest(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
prs, count, err := issues_model.PullRequests(db.DefaultContext, 1, &issues_model.PullRequestsOptions{
ListOptions: db.ListOptions{
Page: 1,
@@ -70,7 +70,7 @@ func TestPullRequestsNewest(t *testing.T) {
State: "open",
SortType: "newest",
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, count)
if assert.Len(t, prs, 3) {
assert.EqualValues(t, 5, prs[0].ID)
@@ -80,35 +80,35 @@ func TestPullRequestsNewest(t *testing.T) {
}
func TestLoadRequestedReviewers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
- assert.NoError(t, pull.LoadIssue(db.DefaultContext))
+ require.NoError(t, pull.LoadIssue(db.DefaultContext))
issue := pull.Issue
- assert.NoError(t, issue.LoadRepo(db.DefaultContext))
- assert.Len(t, pull.RequestedReviewers, 0)
+ require.NoError(t, issue.LoadRepo(db.DefaultContext))
+ assert.Empty(t, pull.RequestedReviewers)
user1, err := user_model.GetUserByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
comment, err := issues_model.AddReviewRequest(db.DefaultContext, issue, user1, &user_model.User{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, comment)
- assert.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext))
+ require.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext))
assert.Len(t, pull.RequestedReviewers, 1)
comment, err = issues_model.RemoveReviewRequest(db.DefaultContext, issue, user1, &user_model.User{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, comment)
pull.RequestedReviewers = nil
- assert.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext))
+ require.NoError(t, pull.LoadRequestedReviewers(db.DefaultContext))
assert.Empty(t, pull.RequestedReviewers)
}
func TestPullRequestsOldest(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
prs, count, err := issues_model.PullRequests(db.DefaultContext, 1, &issues_model.PullRequestsOptions{
ListOptions: db.ListOptions{
Page: 1,
@@ -116,7 +116,7 @@ func TestPullRequestsOldest(t *testing.T) {
State: "open",
SortType: "oldest",
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, count)
if assert.Len(t, prs, 3) {
assert.EqualValues(t, 1, prs[0].ID)
@@ -126,32 +126,32 @@ func TestPullRequestsOldest(t *testing.T) {
}
func TestGetUnmergedPullRequest(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr, err := issues_model.GetUnmergedPullRequest(db.DefaultContext, 1, 1, "branch2", "master", issues_model.PullRequestFlowGithub)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(2), pr.ID)
_, err = issues_model.GetUnmergedPullRequest(db.DefaultContext, 1, 9223372036854775807, "branch1", "master", issues_model.PullRequestFlowGithub)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrPullRequestNotExist(err))
}
func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "branch2")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exist)
exist, err = issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "not_exist_branch")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, exist)
}
func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "branch2")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, prs, 1)
for _, pr := range prs {
assert.Equal(t, int64(1), pr.HeadRepoID)
@@ -160,26 +160,26 @@ func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) {
}
func TestGetUnmergedPullRequestsByHeadInfoMax(t *testing.T) {
- defer tests.AddFixtures("models/fixtures/TestGetUnmergedPullRequestsByHeadInfoMax/")()
- assert.NoError(t, unittest.PrepareTestDatabase())
+ defer unittest.OverrideFixtures("models/fixtures/TestGetUnmergedPullRequestsByHeadInfoMax")()
+ require.NoError(t, unittest.PrepareTestDatabase())
repoID := int64(1)
olderThan := int64(0)
// for NULL created field the olderThan condition is ignored
prs, err := issues_model.GetUnmergedPullRequestsByHeadInfoMax(db.DefaultContext, repoID, olderThan, "branch2")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), prs[0].HeadRepoID)
// test for when the created field is set
branch := "branchmax"
prs, err = issues_model.GetUnmergedPullRequestsByHeadInfoMax(db.DefaultContext, repoID, olderThan, branch)
- assert.NoError(t, err)
- assert.Len(t, prs, 0)
+ require.NoError(t, err)
+ assert.Empty(t, prs)
olderThan = time.Now().UnixNano()
- assert.NoError(t, err)
+ require.NoError(t, err)
prs, err = issues_model.GetUnmergedPullRequestsByHeadInfoMax(db.DefaultContext, repoID, olderThan, branch)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, prs, 1)
for _, pr := range prs {
assert.Equal(t, int64(1), pr.HeadRepoID)
@@ -235,16 +235,16 @@ func TestGetUnmergedPullRequestsByHeadInfoMax(t *testing.T) {
// expect no match
_, err = db.GetEngine(db.DefaultContext).Exec(update, testCase.nomatch, testCase.id)
- assert.NoError(t, err)
+ require.NoError(t, err)
prs, err = issues_model.GetUnmergedPullRequestsByHeadInfoMax(db.DefaultContext, repoID, olderThan, branch)
- assert.NoError(t, err)
- assert.Len(t, prs, 0)
+ require.NoError(t, err)
+ assert.Empty(t, prs)
// expect one match
_, err = db.GetEngine(db.DefaultContext).Exec(update, testCase.match, testCase.id)
- assert.NoError(t, err)
+ require.NoError(t, err)
prs, err = issues_model.GetUnmergedPullRequestsByHeadInfoMax(db.DefaultContext, repoID, olderThan, branch)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, prs, 1)
// identical to the known PR
@@ -254,9 +254,9 @@ func TestGetUnmergedPullRequestsByHeadInfoMax(t *testing.T) {
}
func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
prs, err := issues_model.GetUnmergedPullRequestsByBaseInfo(db.DefaultContext, 1, "master")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, prs, 1)
pr := prs[0]
assert.Equal(t, int64(2), pr.ID)
@@ -265,46 +265,46 @@ func TestGetUnmergedPullRequestsByBaseInfo(t *testing.T) {
}
func TestGetPullRequestByIndex(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr, err := issues_model.GetPullRequestByIndex(db.DefaultContext, 1, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), pr.BaseRepoID)
assert.Equal(t, int64(2), pr.Index)
_, err = issues_model.GetPullRequestByIndex(db.DefaultContext, 9223372036854775807, 9223372036854775807)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrPullRequestNotExist(err))
_, err = issues_model.GetPullRequestByIndex(db.DefaultContext, 1, 0)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrPullRequestNotExist(err))
}
func TestGetPullRequestByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr, err := issues_model.GetPullRequestByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), pr.ID)
assert.Equal(t, int64(2), pr.IssueID)
_, err = issues_model.GetPullRequestByID(db.DefaultContext, 9223372036854775807)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrPullRequestNotExist(err))
}
func TestGetPullRequestByIssueID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(2), pr.IssueID)
_, err = issues_model.GetPullRequestByIssueID(db.DefaultContext, 9223372036854775807)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrPullRequestNotExist(err))
}
func TestPullRequest_Update(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
pr.BaseBranch = "baseBranch"
pr.HeadBranch = "headBranch"
@@ -317,13 +317,13 @@ func TestPullRequest_Update(t *testing.T) {
}
func TestPullRequest_UpdateCols(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr := &issues_model.PullRequest{
ID: 1,
BaseBranch: "baseBranch",
HeadBranch: "headBranch",
}
- assert.NoError(t, pr.UpdateCols(db.DefaultContext, "head_branch"))
+ require.NoError(t, pr.UpdateCols(db.DefaultContext, "head_branch"))
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
assert.Equal(t, "master", pr.BaseBranch)
@@ -332,25 +332,25 @@ func TestPullRequest_UpdateCols(t *testing.T) {
}
func TestPullRequestList_LoadAttributes(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
prs := []*issues_model.PullRequest{
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}),
unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}),
}
- assert.NoError(t, issues_model.PullRequestList(prs).LoadAttributes(db.DefaultContext))
+ require.NoError(t, issues_model.PullRequestList(prs).LoadAttributes(db.DefaultContext))
for _, pr := range prs {
assert.NotNil(t, pr.Issue)
assert.Equal(t, pr.IssueID, pr.Issue.ID)
}
- assert.NoError(t, issues_model.PullRequestList([]*issues_model.PullRequest{}).LoadAttributes(db.DefaultContext))
+ require.NoError(t, issues_model.PullRequestList([]*issues_model.PullRequest{}).LoadAttributes(db.DefaultContext))
}
// TODO TestAddTestPullRequestTask
func TestPullRequest_IsWorkInProgress(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
pr.LoadIssue(db.DefaultContext)
@@ -365,7 +365,7 @@ func TestPullRequest_IsWorkInProgress(t *testing.T) {
}
func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
pr.LoadIssue(db.DefaultContext)
@@ -381,23 +381,23 @@ func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) {
}
func TestDeleteOrphanedObjects(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
countBefore, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = db.GetEngine(db.DefaultContext).Insert(&issues_model.PullRequest{IssueID: 1000}, &issues_model.PullRequest{IssueID: 1001}, &issues_model.PullRequest{IssueID: 1003})
- assert.NoError(t, err)
+ require.NoError(t, err)
orphaned, err := db.CountOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, orphaned)
err = db.DeleteOrphanedObjects(db.DefaultContext, "pull_request", "issue", "pull_request.issue_id=issue.id")
- assert.NoError(t, err)
+ require.NoError(t, err)
countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, countBefore, countAfter)
}
@@ -424,7 +424,7 @@ func TestParseCodeOwnersLine(t *testing.T) {
}
func TestGetApprovers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 5})
// Official reviews are already deduplicated. Allow unofficial reviews
// to assert that there are no duplicated approvers.
@@ -435,19 +435,19 @@ func TestGetApprovers(t *testing.T) {
}
func TestGetPullRequestByMergedCommit(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr, err := issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 1, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, pr.ID)
_, err = issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 0, "1a8823cd1a9549fde083f992f6b9b87a7ab74fb3")
- assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{})
+ require.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{})
_, err = issues_model.GetPullRequestByMergedCommit(db.DefaultContext, 1, "")
- assert.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{})
+ require.ErrorAs(t, err, &issues_model.ErrPullRequestNotExist{})
}
func TestMigrate_InsertPullRequests(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
reponame := "repo1"
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame})
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
@@ -467,7 +467,7 @@ func TestMigrate_InsertPullRequests(t *testing.T) {
}
err := issues_model.InsertPullRequests(db.DefaultContext, p)
- assert.NoError(t, err)
+ require.NoError(t, err)
_ = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: i.ID})
diff --git a/models/issues/reaction.go b/models/issues/reaction.go
index eb7faefc79..522040c022 100644
--- a/models/issues/reaction.go
+++ b/models/issues/reaction.go
@@ -8,13 +8,13 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -163,7 +163,7 @@ func FindReactions(ctx context.Context, opts FindReactionsOptions) (ReactionList
Where(opts.toConds()).
In("reaction.`type`", setting.UI.Reactions).
Asc("reaction.issue_id", "reaction.comment_id", "reaction.created_unix", "reaction.id")
- if opts.Page != 0 {
+ if opts.Page > 0 {
sess = db.SetSessionPagination(sess, &opts)
reactions := make([]*Reaction, 0, opts.PageSize)
diff --git a/models/issues/reaction_test.go b/models/issues/reaction_test.go
index eb59e36ecd..0ae201c500 100644
--- a/models/issues/reaction_test.go
+++ b/models/issues/reaction_test.go
@@ -6,14 +6,15 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func addReaction(t *testing.T, doerID, issueID, commentID int64, content string) {
@@ -27,12 +28,12 @@ func addReaction(t *testing.T, doerID, issueID, commentID int64, content string)
Type: content,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, reaction)
}
func TestIssueAddReaction(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -44,7 +45,7 @@ func TestIssueAddReaction(t *testing.T) {
}
func TestIssueAddDuplicateReaction(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -57,7 +58,7 @@ func TestIssueAddDuplicateReaction(t *testing.T) {
IssueID: issue1ID,
Type: "heart",
})
- assert.Error(t, err)
+ require.Error(t, err)
assert.Equal(t, issues_model.ErrReactionAlreadyExist{Reaction: "heart"}, err)
existingR := unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID})
@@ -65,7 +66,7 @@ func TestIssueAddDuplicateReaction(t *testing.T) {
}
func TestIssueDeleteReaction(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -74,13 +75,13 @@ func TestIssueDeleteReaction(t *testing.T) {
addReaction(t, user1.ID, issue1ID, 0, "heart")
err := issues_model.DeleteIssueReaction(db.DefaultContext, user1.ID, issue1ID, "heart")
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID})
}
func TestIssueReactionCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
setting.UI.ReactionMaxUserNum = 2
@@ -104,10 +105,10 @@ func TestIssueReactionCount(t *testing.T) {
reactionsList, _, err := issues_model.FindReactions(db.DefaultContext, issues_model.FindReactionsOptions{
IssueID: issueID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, reactionsList, 7)
_, err = reactionsList.LoadUsers(db.DefaultContext, repo)
- assert.NoError(t, err)
+ require.NoError(t, err)
reactions := reactionsList.GroupByType()
assert.Len(t, reactions["heart"], 4)
@@ -122,7 +123,7 @@ func TestIssueReactionCount(t *testing.T) {
}
func TestIssueCommentAddReaction(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -135,7 +136,7 @@ func TestIssueCommentAddReaction(t *testing.T) {
}
func TestIssueCommentDeleteReaction(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -154,7 +155,7 @@ func TestIssueCommentDeleteReaction(t *testing.T) {
IssueID: issue1ID,
CommentID: comment1ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, reactionsList, 4)
reactions := reactionsList.GroupByType()
@@ -163,7 +164,7 @@ func TestIssueCommentDeleteReaction(t *testing.T) {
}
func TestIssueCommentReactionCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -171,7 +172,7 @@ func TestIssueCommentReactionCount(t *testing.T) {
var comment1ID int64 = 1
addReaction(t, user1.ID, issue1ID, comment1ID, "heart")
- assert.NoError(t, issues_model.DeleteCommentReaction(db.DefaultContext, user1.ID, issue1ID, comment1ID, "heart"))
+ require.NoError(t, issues_model.DeleteCommentReaction(db.DefaultContext, user1.ID, issue1ID, comment1ID, "heart"))
unittest.AssertNotExistsBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID, CommentID: comment1ID})
}
diff --git a/models/issues/review.go b/models/issues/review.go
index ca6fd6035b..db5cd65e2e 100644
--- a/models/issues/review.go
+++ b/models/issues/review.go
@@ -9,16 +9,16 @@ import (
"slices"
"strings"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -364,7 +364,7 @@ func GetCurrentReview(ctx context.Context, reviewer *user_model.User, issue *Iss
return nil, nil
}
reviews, err := FindReviews(ctx, FindReviewOptions{
- Type: ReviewTypePending,
+ Types: []ReviewType{ReviewTypePending},
IssueID: issue.ID,
ReviewerID: reviewer.ID,
})
@@ -614,6 +614,10 @@ func InsertReviews(ctx context.Context, reviews []*Review) error {
return err
}
}
+
+ if err := UpdateIssueNumComments(ctx, review.IssueID); err != nil {
+ return err
+ }
}
return committer.Commit()
diff --git a/models/issues/review_list.go b/models/issues/review_list.go
index 7b8c3d319c..45480832d8 100644
--- a/models/issues/review_list.go
+++ b/models/issues/review_list.go
@@ -6,10 +6,11 @@ package issues
import (
"context"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ organization_model "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/optional"
"xorm.io/builder"
)
@@ -37,6 +38,34 @@ func (reviews ReviewList) LoadReviewers(ctx context.Context) error {
return nil
}
+// LoadReviewersTeams loads reviewers teams
+func (reviews ReviewList) LoadReviewersTeams(ctx context.Context) error {
+ reviewersTeamsIDs := make([]int64, 0)
+ for _, review := range reviews {
+ if review.ReviewerTeamID != 0 {
+ reviewersTeamsIDs = append(reviewersTeamsIDs, review.ReviewerTeamID)
+ }
+ }
+
+ teamsMap := make(map[int64]*organization_model.Team, 0)
+ for _, teamID := range reviewersTeamsIDs {
+ team, err := organization_model.GetTeamByID(ctx, teamID)
+ if err != nil {
+ return err
+ }
+
+ teamsMap[teamID] = team
+ }
+
+ for _, review := range reviews {
+ if review.ReviewerTeamID != 0 {
+ review.ReviewerTeam = teamsMap[review.ReviewerTeamID]
+ }
+ }
+
+ return nil
+}
+
func (reviews ReviewList) LoadIssues(ctx context.Context) error {
issueIDs := container.FilterSlice(reviews, func(review *Review) (int64, bool) {
return review.IssueID, true
@@ -63,7 +92,7 @@ func (reviews ReviewList) LoadIssues(ctx context.Context) error {
// FindReviewOptions represent possible filters to find reviews
type FindReviewOptions struct {
db.ListOptions
- Type ReviewType
+ Types []ReviewType
IssueID int64
ReviewerID int64
OfficialOnly bool
@@ -78,8 +107,8 @@ func (opts *FindReviewOptions) toCond() builder.Cond {
if opts.ReviewerID > 0 {
cond = cond.And(builder.Eq{"reviewer_id": opts.ReviewerID})
}
- if opts.Type != ReviewTypeUnknown {
- cond = cond.And(builder.Eq{"type": opts.Type})
+ if len(opts.Types) > 0 {
+ cond = cond.And(builder.In("type", opts.Types))
}
if opts.OfficialOnly {
cond = cond.And(builder.Eq{"official": true})
diff --git a/models/issues/review_test.go b/models/issues/review_test.go
index ac1b84adeb..33d131c225 100644
--- a/models/issues/review_test.go
+++ b/models/issues/review_test.go
@@ -6,47 +6,48 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetReviewByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
review, err := issues_model.GetReviewByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "Demo Review", review.Content)
assert.Equal(t, issues_model.ReviewTypeApprove, review.Type)
_, err = issues_model.GetReviewByID(db.DefaultContext, 23892)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrReviewNotExist(err), "IsErrReviewNotExist")
}
func TestReview_LoadAttributes(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 1})
- assert.NoError(t, review.LoadAttributes(db.DefaultContext))
+ require.NoError(t, review.LoadAttributes(db.DefaultContext))
assert.NotNil(t, review.Issue)
assert.NotNil(t, review.Reviewer)
invalidReview1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 2})
- assert.Error(t, invalidReview1.LoadAttributes(db.DefaultContext))
+ require.Error(t, invalidReview1.LoadAttributes(db.DefaultContext))
invalidReview2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 3})
- assert.Error(t, invalidReview2.LoadAttributes(db.DefaultContext))
+ require.Error(t, invalidReview2.LoadAttributes(db.DefaultContext))
}
func TestReview_LoadCodeComments(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 4})
- assert.NoError(t, review.LoadAttributes(db.DefaultContext))
- assert.NoError(t, review.LoadCodeComments(db.DefaultContext))
+ require.NoError(t, review.LoadAttributes(db.DefaultContext))
+ require.NoError(t, review.LoadCodeComments(db.DefaultContext))
assert.Len(t, review.CodeComments, 1)
assert.Equal(t, int64(4), review.CodeComments["README.md"][int64(4)][0].Line)
}
@@ -61,49 +62,49 @@ func TestReviewType_Icon(t *testing.T) {
}
func TestFindReviews(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
reviews, err := issues_model.FindReviews(db.DefaultContext, issues_model.FindReviewOptions{
- Type: issues_model.ReviewTypeApprove,
+ Types: []issues_model.ReviewType{issues_model.ReviewTypeApprove},
IssueID: 2,
ReviewerID: 1,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, reviews, 1)
assert.Equal(t, "Demo Review", reviews[0].Content)
}
func TestFindLatestReviews(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
reviews, err := issues_model.FindLatestReviews(db.DefaultContext, issues_model.FindReviewOptions{
- Type: issues_model.ReviewTypeApprove,
+ Types: []issues_model.ReviewType{issues_model.ReviewTypeApprove},
IssueID: 11,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, reviews, 2)
assert.Equal(t, "duplicate review from user5 (latest)", reviews[0].Content)
assert.Equal(t, "singular review from org6 and final review for this pr", reviews[1].Content)
}
func TestGetCurrentReview(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
review, err := issues_model.GetCurrentReview(db.DefaultContext, user, issue)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, review)
assert.Equal(t, issues_model.ReviewTypePending, review.Type)
assert.Equal(t, "Pending Review", review.Content)
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 7})
review2, err := issues_model.GetCurrentReview(db.DefaultContext, user2, issue)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrReviewNotExist(err))
assert.Nil(t, review2)
}
func TestCreateReview(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -114,13 +115,13 @@ func TestCreateReview(t *testing.T) {
Issue: issue,
Reviewer: user,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "New Review", review.Content)
unittest.AssertExistsAndLoadBean(t, &issues_model.Review{Content: "New Review"})
}
func TestGetReviewersByIssueID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -146,9 +147,9 @@ func TestGetReviewersByIssueID(t *testing.T) {
})
allReviews, err := issues_model.GetReviewsByIssueID(db.DefaultContext, issue.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, review := range allReviews {
- assert.NoError(t, review.LoadReviewer(db.DefaultContext))
+ require.NoError(t, review.LoadReviewer(db.DefaultContext))
}
if assert.Len(t, allReviews, 3) {
for i, review := range allReviews {
@@ -159,8 +160,8 @@ func TestGetReviewersByIssueID(t *testing.T) {
}
allReviews, err = issues_model.GetReviewsByIssueID(db.DefaultContext, issue.ID)
- assert.NoError(t, err)
- assert.NoError(t, allReviews.LoadReviewers(db.DefaultContext))
+ require.NoError(t, err)
+ require.NoError(t, allReviews.LoadReviewers(db.DefaultContext))
if assert.Len(t, allReviews, 3) {
for i, review := range allReviews {
assert.Equal(t, expectedReviews[i].Reviewer, review.Reviewer)
@@ -171,7 +172,7 @@ func TestGetReviewersByIssueID(t *testing.T) {
}
func TestDismissReview(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
rejectReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
requestReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
@@ -180,53 +181,53 @@ func TestDismissReview(t *testing.T) {
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
- assert.NoError(t, issues_model.DismissReview(db.DefaultContext, rejectReviewExample, true))
+ require.NoError(t, issues_model.DismissReview(db.DefaultContext, rejectReviewExample, true))
rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
- assert.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, true))
+ require.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, true))
rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
- assert.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, true))
+ require.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, true))
rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
- assert.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, false))
+ require.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, false))
rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
- assert.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, false))
+ require.NoError(t, issues_model.DismissReview(db.DefaultContext, requestReviewExample, false))
rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
- assert.NoError(t, issues_model.DismissReview(db.DefaultContext, rejectReviewExample, false))
+ require.NoError(t, issues_model.DismissReview(db.DefaultContext, rejectReviewExample, false))
assert.False(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
- assert.NoError(t, issues_model.DismissReview(db.DefaultContext, approveReviewExample, true))
+ require.NoError(t, issues_model.DismissReview(db.DefaultContext, approveReviewExample, true))
assert.False(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.True(t, approveReviewExample.Dismissed)
}
func TestDeleteReview(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -238,7 +239,7 @@ func TestDeleteReview(t *testing.T) {
Issue: issue,
Reviewer: user,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
review2, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{
Content: "Official approval",
@@ -247,21 +248,21 @@ func TestDeleteReview(t *testing.T) {
Issue: issue,
Reviewer: user,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
- assert.NoError(t, issues_model.DeleteReview(db.DefaultContext, review2))
+ require.NoError(t, issues_model.DeleteReview(db.DefaultContext, review2))
_, err = issues_model.GetReviewByID(db.DefaultContext, review2.ID)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrReviewNotExist(err), "IsErrReviewNotExist")
review1, err = issues_model.GetReviewByID(db.DefaultContext, review1.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, review1.Official)
}
func TestDeleteDismissedReview(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
@@ -273,8 +274,8 @@ func TestDeleteDismissedReview(t *testing.T) {
Issue: issue,
Reviewer: user,
})
- assert.NoError(t, err)
- assert.NoError(t, issues_model.DismissReview(db.DefaultContext, review, true))
+ require.NoError(t, err)
+ require.NoError(t, issues_model.DismissReview(db.DefaultContext, review, true))
comment, err := issues_model.CreateComment(db.DefaultContext, &issues_model.CreateCommentOptions{
Type: issues_model.CommentTypeDismissReview,
Doer: user,
@@ -283,19 +284,19 @@ func TestDeleteDismissedReview(t *testing.T) {
ReviewID: review.ID,
Content: "dismiss",
})
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID})
- assert.NoError(t, issues_model.DeleteReview(db.DefaultContext, review))
+ require.NoError(t, issues_model.DeleteReview(db.DefaultContext, review))
unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID})
}
func TestAddReviewRequest(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
- assert.NoError(t, pull.LoadIssue(db.DefaultContext))
+ require.NoError(t, pull.LoadIssue(db.DefaultContext))
issue := pull.Issue
- assert.NoError(t, issue.LoadRepo(db.DefaultContext))
+ require.NoError(t, issue.LoadRepo(db.DefaultContext))
reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
_, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{
Issue: issue,
@@ -303,18 +304,18 @@ func TestAddReviewRequest(t *testing.T) {
Type: issues_model.ReviewTypeReject,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
pull.HasMerged = false
- assert.NoError(t, pull.UpdateCols(db.DefaultContext, "has_merged"))
+ require.NoError(t, pull.UpdateCols(db.DefaultContext, "has_merged"))
issue.IsClosed = true
_, err = issues_model.AddReviewRequest(db.DefaultContext, issue, reviewer, &user_model.User{})
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrReviewRequestOnClosedPR(err))
pull.HasMerged = true
- assert.NoError(t, pull.UpdateCols(db.DefaultContext, "has_merged"))
+ require.NoError(t, pull.UpdateCols(db.DefaultContext, "has_merged"))
issue.IsClosed = false
_, err = issues_model.AddReviewRequest(db.DefaultContext, issue, reviewer, &user_model.User{})
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, issues_model.IsErrReviewRequestOnClosedPR(err))
}
diff --git a/models/issues/stopwatch.go b/models/issues/stopwatch.go
index fd9c7d7875..2ff2a17d92 100644
--- a/models/issues/stopwatch.go
+++ b/models/issues/stopwatch.go
@@ -8,11 +8,11 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
)
// ErrIssueStopwatchNotExist represents an error that stopwatch is not exist
@@ -60,34 +60,19 @@ func getStopwatch(ctx context.Context, userID, issueID int64) (sw *Stopwatch, ex
return sw, exists, err
}
-// UserIDCount is a simple coalition of UserID and Count
-type UserStopwatch struct {
- UserID int64
- StopWatches []*Stopwatch
-}
-
// GetUIDsAndNotificationCounts between the two provided times
-func GetUIDsAndStopwatch(ctx context.Context) ([]*UserStopwatch, error) {
+func GetUIDsAndStopwatch(ctx context.Context) (map[int64][]*Stopwatch, error) {
sws := []*Stopwatch{}
if err := db.GetEngine(ctx).Where("issue_id != 0").Find(&sws); err != nil {
return nil, err
}
+ res := map[int64][]*Stopwatch{}
if len(sws) == 0 {
- return []*UserStopwatch{}, nil
+ return res, nil
}
- lastUserID := int64(-1)
- res := []*UserStopwatch{}
for _, sw := range sws {
- if lastUserID == sw.UserID {
- lastUserStopwatch := res[len(res)-1]
- lastUserStopwatch.StopWatches = append(lastUserStopwatch.StopWatches, sw)
- } else {
- res = append(res, &UserStopwatch{
- UserID: sw.UserID,
- StopWatches: []*Stopwatch{sw},
- })
- }
+ res[sw.UserID] = append(res[sw.UserID], sw)
}
return res, nil
}
@@ -96,7 +81,7 @@ func GetUIDsAndStopwatch(ctx context.Context) ([]*UserStopwatch, error) {
func GetUserStopwatches(ctx context.Context, userID int64, listOptions db.ListOptions) ([]*Stopwatch, error) {
sws := make([]*Stopwatch, 0, 8)
sess := db.GetEngine(ctx).Where("stopwatch.user_id = ?", userID)
- if listOptions.Page != 0 {
+ if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
}
diff --git a/models/issues/stopwatch_test.go b/models/issues/stopwatch_test.go
index 39958a7f36..3334ffea7d 100644
--- a/models/issues/stopwatch_test.go
+++ b/models/issues/stopwatch_test.go
@@ -6,73 +6,106 @@ package issues_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCancelStopwatch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1, err := user_model.GetUserByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = issues_model.CancelStopwatch(db.DefaultContext, user1, issue1)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: user1.ID, IssueID: issue1.ID})
_ = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeCancelTracking, PosterID: user1.ID, IssueID: issue1.ID})
- assert.Nil(t, issues_model.CancelStopwatch(db.DefaultContext, user1, issue2))
+ require.NoError(t, issues_model.CancelStopwatch(db.DefaultContext, user1, issue2))
}
func TestStopwatchExists(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.True(t, issues_model.StopwatchExists(db.DefaultContext, 1, 1))
assert.False(t, issues_model.StopwatchExists(db.DefaultContext, 1, 2))
}
func TestHasUserStopwatch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
exists, sw, _, err := issues_model.HasUserStopwatch(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists)
assert.Equal(t, int64(1), sw.ID)
exists, _, _, err = issues_model.HasUserStopwatch(db.DefaultContext, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, exists)
}
func TestCreateOrStopIssueStopwatch(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user2, err := user_model.GetUserByID(db.DefaultContext, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
org3, err := user_model.GetUserByID(db.DefaultContext, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
- assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(db.DefaultContext, org3, issue1))
+ require.NoError(t, issues_model.CreateOrStopIssueStopwatch(db.DefaultContext, org3, issue1))
sw := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: 3, IssueID: 1})
assert.LessOrEqual(t, sw.CreatedUnix, timeutil.TimeStampNow())
- assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(db.DefaultContext, user2, issue2))
+ require.NoError(t, issues_model.CreateOrStopIssueStopwatch(db.DefaultContext, user2, issue2))
unittest.AssertNotExistsBean(t, &issues_model.Stopwatch{UserID: 2, IssueID: 2})
unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 2, IssueID: 2})
}
+
+func TestGetUIDsAndStopwatch(t *testing.T) {
+ defer unittest.OverrideFixtures("models/issues/TestGetUIDsAndStopwatch")()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ uidStopwatches, err := issues_model.GetUIDsAndStopwatch(db.DefaultContext)
+ require.NoError(t, err)
+ assert.EqualValues(t, map[int64][]*issues_model.Stopwatch{
+ 1: {
+ {
+ ID: 1,
+ UserID: 1,
+ IssueID: 1,
+ CreatedUnix: timeutil.TimeStamp(1500988001),
+ },
+ {
+ ID: 3,
+ UserID: 1,
+ IssueID: 2,
+ CreatedUnix: timeutil.TimeStamp(1500988004),
+ },
+ },
+ 2: {
+ {
+ ID: 2,
+ UserID: 2,
+ IssueID: 2,
+ CreatedUnix: timeutil.TimeStamp(1500988002),
+ },
+ },
+ }, uidStopwatches)
+}
diff --git a/models/issues/tracked_time.go b/models/issues/tracked_time.go
index caa582a9fc..05d7b15815 100644
--- a/models/issues/tracked_time.go
+++ b/models/issues/tracked_time.go
@@ -9,11 +9,11 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"xorm.io/builder"
"xorm.io/xorm"
@@ -139,7 +139,7 @@ func (opts *FindTrackedTimesOptions) toSession(e db.Engine) db.Engine {
sess = sess.Where(opts.ToConds())
- if opts.Page != 0 {
+ if opts.Page > 0 {
sess = db.SetSessionPagination(sess, opts)
}
diff --git a/models/issues/tracked_time_test.go b/models/issues/tracked_time_test.go
index d82bff967a..770b43abd7 100644
--- a/models/issues/tracked_time_test.go
+++ b/models/issues/tracked_time_test.go
@@ -7,27 +7,28 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestAddTime(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org3, err := user_model.GetUserByID(db.DefaultContext, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
// 3661 = 1h 1min 1s
trackedTime, err := issues_model.AddTime(db.DefaultContext, org3, issue1, 3661, time.Now())
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(3), trackedTime.UserID)
assert.Equal(t, int64(1), trackedTime.IssueID)
assert.Equal(t, int64(3661), trackedTime.Time)
@@ -40,51 +41,51 @@ func TestAddTime(t *testing.T) {
}
func TestGetTrackedTimes(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// by Issue
times, err := issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, times, 1)
assert.Equal(t, int64(400), times[0].Time)
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: -1})
- assert.NoError(t, err)
- assert.Len(t, times, 0)
+ require.NoError(t, err)
+ assert.Empty(t, times)
// by User
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, times, 3)
assert.Equal(t, int64(400), times[0].Time)
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{UserID: 3})
- assert.NoError(t, err)
- assert.Len(t, times, 0)
+ require.NoError(t, err)
+ assert.Empty(t, times)
// by Repo
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 2})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, times, 3)
assert.Equal(t, int64(1), times[0].Time)
issue, err := issues_model.GetIssueByID(db.DefaultContext, times[0].IssueID)
- assert.NoError(t, err)
- assert.Equal(t, issue.RepoID, int64(2))
+ require.NoError(t, err)
+ assert.Equal(t, int64(2), issue.RepoID)
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, times, 5)
times, err = issues_model.GetTrackedTimes(db.DefaultContext, &issues_model.FindTrackedTimesOptions{RepositoryID: 10})
- assert.NoError(t, err)
- assert.Len(t, times, 0)
+ require.NoError(t, err)
+ assert.Empty(t, times)
}
func TestTotalTimesForEachUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
total, err := issues_model.TotalTimesForEachUser(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, total, 1)
for user, time := range total {
assert.EqualValues(t, 1, user.ID)
@@ -92,7 +93,7 @@ func TestTotalTimesForEachUser(t *testing.T) {
}
total, err = issues_model.TotalTimesForEachUser(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 2})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, total, 2)
for user, time := range total {
if user.ID == 2 {
@@ -100,12 +101,12 @@ func TestTotalTimesForEachUser(t *testing.T) {
} else if user.ID == 1 {
assert.EqualValues(t, 20, time)
} else {
- assert.Error(t, assert.AnError)
+ require.Error(t, assert.AnError)
}
}
total, err = issues_model.TotalTimesForEachUser(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 5})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, total, 1)
for user, time := range total {
assert.EqualValues(t, 2, user.ID)
@@ -113,22 +114,22 @@ func TestTotalTimesForEachUser(t *testing.T) {
}
total, err = issues_model.TotalTimesForEachUser(db.DefaultContext, &issues_model.FindTrackedTimesOptions{IssueID: 4})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, total, 2)
}
func TestGetIssueTotalTrackedTime(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
ttt, err := issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, optional.Some(false))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3682, ttt)
ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, optional.Some(true))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, ttt)
ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, optional.None[bool]())
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3682, ttt)
}
diff --git a/models/main_test.go b/models/main_test.go
index 600dcc889b..0edcf8f49d 100644
--- a/models/main_test.go
+++ b/models/main_test.go
@@ -6,21 +6,22 @@ package models
import (
"testing"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/system"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/forgefed"
+ _ "forgejo.org/models/system"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
// TestFixturesAreConsistent assert that test fixtures are consistent
func TestFixturesAreConsistent(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
unittest.CheckConsistencyFor(t,
&user_model.User{},
&repo_model.Repository{},
diff --git a/models/migrations/base/db.go b/models/migrations/base/db.go
index e584793385..897ad016ab 100644
--- a/models/migrations/base/db.go
+++ b/models/migrations/base/db.go
@@ -4,22 +4,14 @@
package base
import (
- "context"
- "database/sql"
"errors"
"fmt"
- "os"
- "path"
"reflect"
"regexp"
"strings"
- "time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
@@ -442,99 +434,3 @@ func ModifyColumn(x *xorm.Engine, tableName string, col *schemas.Column) error {
}
return nil
}
-
-func removeAllWithRetry(dir string) error {
- var err error
- for i := 0; i < 20; i++ {
- err = os.RemoveAll(dir)
- if err == nil {
- break
- }
- time.Sleep(100 * time.Millisecond)
- }
- return err
-}
-
-func newXORMEngine() (*xorm.Engine, error) {
- if err := db.InitEngine(context.Background()); err != nil {
- return nil, err
- }
- x := unittest.GetXORMEngine()
- return x, nil
-}
-
-func deleteDB() error {
- switch {
- case setting.Database.Type.IsSQLite3():
- if err := util.Remove(setting.Database.Path); err != nil {
- return err
- }
- return os.MkdirAll(path.Dir(setting.Database.Path), os.ModePerm)
-
- case setting.Database.Type.IsMySQL():
- db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/",
- setting.Database.User, setting.Database.Passwd, setting.Database.Host))
- if err != nil {
- return err
- }
- defer db.Close()
-
- if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil {
- return err
- }
-
- if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", setting.Database.Name)); err != nil {
- return err
- }
- return nil
- case setting.Database.Type.IsPostgreSQL():
- db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/?sslmode=%s",
- setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.SSLMode))
- if err != nil {
- return err
- }
- defer db.Close()
-
- if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil {
- return err
- }
-
- if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", setting.Database.Name)); err != nil {
- return err
- }
- db.Close()
-
- // Check if we need to setup a specific schema
- if len(setting.Database.Schema) != 0 {
- db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
- setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode))
- if err != nil {
- return err
- }
- defer db.Close()
-
- schrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s'", setting.Database.Schema))
- if err != nil {
- return err
- }
- defer schrows.Close()
-
- if !schrows.Next() {
- // Create and setup a DB schema
- _, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s", setting.Database.Schema))
- if err != nil {
- return err
- }
- }
-
- // Make the user's default search path the created schema; this will affect new connections
- _, err = db.Exec(fmt.Sprintf(`ALTER USER "%s" SET search_path = %s`, setting.Database.User, setting.Database.Schema))
- if err != nil {
- return err
- }
- return nil
- }
- }
-
- return nil
-}
diff --git a/models/migrations/base/db_test.go b/models/migrations/base/db_test.go
index 80bf00b22a..4a610e065d 100644
--- a/models/migrations/base/db_test.go
+++ b/models/migrations/base/db_test.go
@@ -6,13 +6,14 @@ package base
import (
"testing"
- "code.gitea.io/gitea/modules/timeutil"
+ migrations_tests "forgejo.org/models/migrations/test"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm/names"
)
func Test_DropTableColumns(t *testing.T) {
- x, deferable := PrepareTestEnv(t, 0)
+ x, deferable := migrations_tests.PrepareTestEnv(t, 0)
if x == nil || t.Failed() {
defer deferable()
return
diff --git a/models/migrations/base/main_test.go b/models/migrations/base/main_test.go
index c1c789150f..2b3889441a 100644
--- a/models/migrations/base/main_test.go
+++ b/models/migrations/base/main_test.go
@@ -5,8 +5,10 @@ package base
import (
"testing"
+
+ migrations_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- MainTest(m)
+ migrations_tests.MainTest(m)
}
diff --git a/models/migrations/fixtures/Test_MigrateTwoFactorToKeying/two_factor.yml b/models/migrations/fixtures/Test_MigrateTwoFactorToKeying/two_factor.yml
new file mode 100644
index 0000000000..91aa420340
--- /dev/null
+++ b/models/migrations/fixtures/Test_MigrateTwoFactorToKeying/two_factor.yml
@@ -0,0 +1,18 @@
+-
+ id: 1
+ uid: 24
+ secret: MrAed+7K+fKQKu1l3aU45oTDSWK/i5Ugtgk8CmORrKWTMwa2w97rniLU+h+2xq8ZF+16uuXGLzjWa0bOV5xg4NY6w5Ec/tkwQ5rEecOTvc/JZV5lrrlDi48B7Y5/lNcjAWBmH2nEUlM=
+ scratch_salt: Qb5bq2DyR2
+ scratch_hash: 068eb9b8746e0bcfe332fac4457693df1bda55800eb0f6894d14ebb736ae6a24e0fc8fc5333c19f57f81599788f0b8e51ec1
+ last_used_passcode:
+ created_unix: 1564253724
+ updated_unix: 1564253724
+-
+ id: 2
+ uid: 23
+ secret: badbad
+ scratch_salt: badbad
+ scratch_hash: badbad
+ last_used_passcode:
+ created_unix: 1564253724
+ updated_unix: 1564253724
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 2e095c05a4..11933014d7 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -8,29 +8,29 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/forgejo_migrations"
- "code.gitea.io/gitea/models/migrations/v1_10"
- "code.gitea.io/gitea/models/migrations/v1_11"
- "code.gitea.io/gitea/models/migrations/v1_12"
- "code.gitea.io/gitea/models/migrations/v1_13"
- "code.gitea.io/gitea/models/migrations/v1_14"
- "code.gitea.io/gitea/models/migrations/v1_15"
- "code.gitea.io/gitea/models/migrations/v1_16"
- "code.gitea.io/gitea/models/migrations/v1_17"
- "code.gitea.io/gitea/models/migrations/v1_18"
- "code.gitea.io/gitea/models/migrations/v1_19"
- "code.gitea.io/gitea/models/migrations/v1_20"
- "code.gitea.io/gitea/models/migrations/v1_21"
- "code.gitea.io/gitea/models/migrations/v1_22"
- "code.gitea.io/gitea/models/migrations/v1_23"
- "code.gitea.io/gitea/models/migrations/v1_6"
- "code.gitea.io/gitea/models/migrations/v1_7"
- "code.gitea.io/gitea/models/migrations/v1_8"
- "code.gitea.io/gitea/models/migrations/v1_9"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- forgejo_services "code.gitea.io/gitea/services/forgejo"
+ "forgejo.org/models/forgejo_migrations"
+ "forgejo.org/models/migrations/v1_10"
+ "forgejo.org/models/migrations/v1_11"
+ "forgejo.org/models/migrations/v1_12"
+ "forgejo.org/models/migrations/v1_13"
+ "forgejo.org/models/migrations/v1_14"
+ "forgejo.org/models/migrations/v1_15"
+ "forgejo.org/models/migrations/v1_16"
+ "forgejo.org/models/migrations/v1_17"
+ "forgejo.org/models/migrations/v1_18"
+ "forgejo.org/models/migrations/v1_19"
+ "forgejo.org/models/migrations/v1_20"
+ "forgejo.org/models/migrations/v1_21"
+ "forgejo.org/models/migrations/v1_22"
+ "forgejo.org/models/migrations/v1_23"
+ "forgejo.org/models/migrations/v1_6"
+ "forgejo.org/models/migrations/v1_7"
+ "forgejo.org/models/migrations/v1_8"
+ "forgejo.org/models/migrations/v1_9"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ forgejo_services "forgejo.org/services/forgejo"
"xorm.io/xorm"
"xorm.io/xorm/names"
@@ -38,25 +38,15 @@ import (
const minDBVersion = 70 // Gitea 1.5.3
-// Migration describes on migration from lower version to high version
-type Migration interface {
- Description() string
- Migrate(*xorm.Engine) error
-}
-
type migration struct {
+ idNumber int64 // DB version is "the last migration's idNumber" + 1
description string
migrate func(*xorm.Engine) error
}
-// NewMigration creates a new migration
-func NewMigration(desc string, fn func(*xorm.Engine) error) Migration {
- return &migration{desc, fn}
-}
-
-// Description returns the migration's description
-func (m *migration) Description() string {
- return m.description
+// newMigration creates a new migration
+func newMigration(idNumber int64, desc string, fn func(*xorm.Engine) error) *migration {
+ return &migration{idNumber, desc, fn}
}
// Migrate executes the migration
@@ -67,532 +57,317 @@ func (m *migration) Migrate(x *xorm.Engine) error {
// Version describes the version table. Should have only one row with id==1
type Version struct {
ID int64 `xorm:"pk autoincr"`
- Version int64
+ Version int64 // DB version is "the last migration's idNumber" + 1
}
// Use noopMigration when there is a migration that has been no-oped
var noopMigration = func(_ *xorm.Engine) error { return nil }
+var preparedMigrations []*migration
+
// This is a sequence of migrations. Add new migrations to the bottom of the list.
// If you want to "retire" a migration, remove it from the top of the list and
// update minDBVersion accordingly
-var migrations = []Migration{
- // Gitea 1.5.0 ends at v69
+func prepareMigrationTasks() []*migration {
+ if preparedMigrations != nil {
+ return preparedMigrations
+ }
+ preparedMigrations = []*migration{
+ // Gitea 1.5.0 ends at database version 69
- // v70 -> v71
- NewMigration("add issue_dependencies", v1_6.AddIssueDependencies),
- // v71 -> v72
- NewMigration("protect each scratch token", v1_6.AddScratchHash),
- // v72 -> v73
- NewMigration("add review", v1_6.AddReview),
+ newMigration(70, "add issue_dependencies", v1_6.AddIssueDependencies),
+ newMigration(71, "protect each scratch token", v1_6.AddScratchHash),
+ newMigration(72, "add review", v1_6.AddReview),
- // Gitea 1.6.0 ends at v73
+ // Gitea 1.6.0 ends at database version 73
- // v73 -> v74
- NewMigration("add must_change_password column for users table", v1_7.AddMustChangePassword),
- // v74 -> v75
- NewMigration("add approval whitelists to protected branches", v1_7.AddApprovalWhitelistsToProtectedBranches),
- // v75 -> v76
- NewMigration("clear nonused data which not deleted when user was deleted", v1_7.ClearNonusedData),
+ newMigration(73, "add must_change_password column for users table", v1_7.AddMustChangePassword),
+ newMigration(74, "add approval whitelists to protected branches", v1_7.AddApprovalWhitelistsToProtectedBranches),
+ newMigration(75, "clear nonused data which not deleted when user was deleted", v1_7.ClearNonusedData),
- // Gitea 1.7.0 ends at v76
+ // Gitea 1.7.0 ends at database version 76
- // v76 -> v77
- NewMigration("add pull request rebase with merge commit", v1_8.AddPullRequestRebaseWithMerge),
- // v77 -> v78
- NewMigration("add theme to users", v1_8.AddUserDefaultTheme),
- // v78 -> v79
- NewMigration("rename repo is_bare to repo is_empty", v1_8.RenameRepoIsBareToIsEmpty),
- // v79 -> v80
- NewMigration("add can close issues via commit in any branch", v1_8.AddCanCloseIssuesViaCommitInAnyBranch),
- // v80 -> v81
- NewMigration("add is locked to issues", v1_8.AddIsLockedToIssues),
- // v81 -> v82
- NewMigration("update U2F counter type", v1_8.ChangeU2FCounterType),
+ newMigration(76, "add pull request rebase with merge commit", v1_8.AddPullRequestRebaseWithMerge),
+ newMigration(77, "add theme to users", v1_8.AddUserDefaultTheme),
+ newMigration(78, "rename repo is_bare to repo is_empty", v1_8.RenameRepoIsBareToIsEmpty),
+ newMigration(79, "add can close issues via commit in any branch", v1_8.AddCanCloseIssuesViaCommitInAnyBranch),
+ newMigration(80, "add is locked to issues", v1_8.AddIsLockedToIssues),
+ newMigration(81, "update U2F counter type", v1_8.ChangeU2FCounterType),
- // Gitea 1.8.0 ends at v82
+ // Gitea 1.8.0 ends at database version 82
- // v82 -> v83
- NewMigration("hot fix for wrong release sha1 on release table", v1_9.FixReleaseSha1OnReleaseTable),
- // v83 -> v84
- NewMigration("add uploader id for table attachment", v1_9.AddUploaderIDForAttachment),
- // v84 -> v85
- NewMigration("add table to store original imported gpg keys", v1_9.AddGPGKeyImport),
- // v85 -> v86
- NewMigration("hash application token", v1_9.HashAppToken),
- // v86 -> v87
- NewMigration("add http method to webhook", v1_9.AddHTTPMethodToWebhook),
- // v87 -> v88
- NewMigration("add avatar field to repository", v1_9.AddAvatarFieldToRepository),
+ newMigration(82, "hot fix for wrong release sha1 on release table", v1_9.FixReleaseSha1OnReleaseTable),
+ newMigration(83, "add uploader id for table attachment", v1_9.AddUploaderIDForAttachment),
+ newMigration(84, "add table to store original imported gpg keys", v1_9.AddGPGKeyImport),
+ newMigration(85, "hash application token", v1_9.HashAppToken),
+ newMigration(86, "add http method to webhook", v1_9.AddHTTPMethodToWebhook),
+ newMigration(87, "add avatar field to repository", v1_9.AddAvatarFieldToRepository),
- // Gitea 1.9.0 ends at v88
+ // Gitea 1.9.0 ends at database version 88
- // v88 -> v89
- NewMigration("add commit status context field to commit_status", v1_10.AddCommitStatusContext),
- // v89 -> v90
- NewMigration("add original author/url migration info to issues, comments, and repo ", v1_10.AddOriginalMigrationInfo),
- // v90 -> v91
- NewMigration("change length of some repository columns", v1_10.ChangeSomeColumnsLengthOfRepo),
- // v91 -> v92
- NewMigration("add index on owner_id of repository and type, review_id of comment", v1_10.AddIndexOnRepositoryAndComment),
- // v92 -> v93
- NewMigration("remove orphaned repository index statuses", v1_10.RemoveLingeringIndexStatus),
- // v93 -> v94
- NewMigration("add email notification enabled preference to user", v1_10.AddEmailNotificationEnabledToUser),
- // v94 -> v95
- NewMigration("add enable_status_check, status_check_contexts to protected_branch", v1_10.AddStatusCheckColumnsForProtectedBranches),
- // v95 -> v96
- NewMigration("add table columns for cross referencing issues", v1_10.AddCrossReferenceColumns),
- // v96 -> v97
- NewMigration("delete orphaned attachments", v1_10.DeleteOrphanedAttachments),
- // v97 -> v98
- NewMigration("add repo_admin_change_team_access to user", v1_10.AddRepoAdminChangeTeamAccessColumnForUser),
- // v98 -> v99
- NewMigration("add original author name and id on migrated release", v1_10.AddOriginalAuthorOnMigratedReleases),
- // v99 -> v100
- NewMigration("add task table and status column for repository table", v1_10.AddTaskTable),
- // v100 -> v101
- NewMigration("update migration repositories' service type", v1_10.UpdateMigrationServiceTypes),
- // v101 -> v102
- NewMigration("change length of some external login users columns", v1_10.ChangeSomeColumnsLengthOfExternalLoginUser),
+ newMigration(88, "add commit status context field to commit_status", v1_10.AddCommitStatusContext),
+ newMigration(89, "add original author/url migration info to issues, comments, and repo ", v1_10.AddOriginalMigrationInfo),
+ newMigration(90, "change length of some repository columns", v1_10.ChangeSomeColumnsLengthOfRepo),
+ newMigration(91, "add index on owner_id of repository and type, review_id of comment", v1_10.AddIndexOnRepositoryAndComment),
+ newMigration(92, "remove orphaned repository index statuses", v1_10.RemoveLingeringIndexStatus),
+ newMigration(93, "add email notification enabled preference to user", v1_10.AddEmailNotificationEnabledToUser),
+ newMigration(94, "add enable_status_check, status_check_contexts to protected_branch", v1_10.AddStatusCheckColumnsForProtectedBranches),
+ newMigration(95, "add table columns for cross referencing issues", v1_10.AddCrossReferenceColumns),
+ newMigration(96, "delete orphaned attachments", v1_10.DeleteOrphanedAttachments),
+ newMigration(97, "add repo_admin_change_team_access to user", v1_10.AddRepoAdminChangeTeamAccessColumnForUser),
+ newMigration(98, "add original author name and id on migrated release", v1_10.AddOriginalAuthorOnMigratedReleases),
+ newMigration(99, "add task table and status column for repository table", v1_10.AddTaskTable),
+ newMigration(100, "update migration repositories' service type", v1_10.UpdateMigrationServiceTypes),
+ newMigration(101, "change length of some external login users columns", v1_10.ChangeSomeColumnsLengthOfExternalLoginUser),
- // Gitea 1.10.0 ends at v102
+ // Gitea 1.10.0 ends at database version 102
- // v102 -> v103
- NewMigration("update migration repositories' service type", v1_11.DropColumnHeadUserNameOnPullRequest),
- // v103 -> v104
- NewMigration("Add WhitelistDeployKeys to protected branch", v1_11.AddWhitelistDeployKeysToBranches),
- // v104 -> v105
- NewMigration("remove unnecessary columns from label", v1_11.RemoveLabelUneededCols),
- // v105 -> v106
- NewMigration("add includes_all_repositories to teams", v1_11.AddTeamIncludesAllRepositories),
- // v106 -> v107
- NewMigration("add column `mode` to table watch", v1_11.AddModeColumnToWatch),
- // v107 -> v108
- NewMigration("Add template options to repository", v1_11.AddTemplateToRepo),
- // v108 -> v109
- NewMigration("Add comment_id on table notification", v1_11.AddCommentIDOnNotification),
- // v109 -> v110
- NewMigration("add can_create_org_repo to team", v1_11.AddCanCreateOrgRepoColumnForTeam),
- // v110 -> v111
- NewMigration("change review content type to text", v1_11.ChangeReviewContentToText),
- // v111 -> v112
- NewMigration("update branch protection for can push and whitelist enable", v1_11.AddBranchProtectionCanPushAndEnableWhitelist),
- // v112 -> v113
- NewMigration("remove release attachments which repository deleted", v1_11.RemoveAttachmentMissedRepo),
- // v113 -> v114
- NewMigration("new feature: change target branch of pull requests", v1_11.FeatureChangeTargetBranch),
- // v114 -> v115
- NewMigration("Remove authentication credentials from stored URL", v1_11.SanitizeOriginalURL),
- // v115 -> v116
- NewMigration("add user_id prefix to existing user avatar name", v1_11.RenameExistingUserAvatarName),
- // v116 -> v117
- NewMigration("Extend TrackedTimes", v1_11.ExtendTrackedTimes),
+ newMigration(102, "update migration repositories' service type", v1_11.DropColumnHeadUserNameOnPullRequest),
+ newMigration(103, "Add WhitelistDeployKeys to protected branch", v1_11.AddWhitelistDeployKeysToBranches),
+ newMigration(104, "remove unnecessary columns from label", v1_11.RemoveLabelUneededCols),
+ newMigration(105, "add includes_all_repositories to teams", v1_11.AddTeamIncludesAllRepositories),
+ newMigration(106, "add column `mode` to table watch", v1_11.AddModeColumnToWatch),
+ newMigration(107, "Add template options to repository", v1_11.AddTemplateToRepo),
+ newMigration(108, "Add comment_id on table notification", v1_11.AddCommentIDOnNotification),
+ newMigration(109, "add can_create_org_repo to team", v1_11.AddCanCreateOrgRepoColumnForTeam),
+ newMigration(110, "change review content type to text", v1_11.ChangeReviewContentToText),
+ newMigration(111, "update branch protection for can push and whitelist enable", v1_11.AddBranchProtectionCanPushAndEnableWhitelist),
+ newMigration(112, "remove release attachments which repository deleted", v1_11.RemoveAttachmentMissedRepo),
+ newMigration(113, "new feature: change target branch of pull requests", v1_11.FeatureChangeTargetBranch),
+ newMigration(114, "Remove authentication credentials from stored URL", v1_11.SanitizeOriginalURL),
+ newMigration(115, "add user_id prefix to existing user avatar name", v1_11.RenameExistingUserAvatarName),
+ newMigration(116, "Extend TrackedTimes", v1_11.ExtendTrackedTimes),
- // Gitea 1.11.0 ends at v117
+ // Gitea 1.11.0 ends at database version 117
- // v117 -> v118
- NewMigration("Add block on rejected reviews branch protection", v1_12.AddBlockOnRejectedReviews),
- // v118 -> v119
- NewMigration("Add commit id and stale to reviews", v1_12.AddReviewCommitAndStale),
- // v119 -> v120
- NewMigration("Fix migrated repositories' git service type", v1_12.FixMigratedRepositoryServiceType),
- // v120 -> v121
- NewMigration("Add owner_name on table repository", v1_12.AddOwnerNameOnRepository),
- // v121 -> v122
- NewMigration("add is_restricted column for users table", v1_12.AddIsRestricted),
- // v122 -> v123
- NewMigration("Add Require Signed Commits to ProtectedBranch", v1_12.AddRequireSignedCommits),
- // v123 -> v124
- NewMigration("Add original information for reactions", v1_12.AddReactionOriginals),
- // v124 -> v125
- NewMigration("Add columns to user and repository", v1_12.AddUserRepoMissingColumns),
- // v125 -> v126
- NewMigration("Add some columns on review for migration", v1_12.AddReviewMigrateInfo),
- // v126 -> v127
- NewMigration("Fix topic repository count", v1_12.FixTopicRepositoryCount),
- // v127 -> v128
- NewMigration("add repository code language statistics", v1_12.AddLanguageStats),
- // v128 -> v129
- NewMigration("fix merge base for pull requests", v1_12.FixMergeBase),
- // v129 -> v130
- NewMigration("remove dependencies from deleted repositories", v1_12.PurgeUnusedDependencies),
- // v130 -> v131
- NewMigration("Expand webhooks for more granularity", v1_12.ExpandWebhooks),
- // v131 -> v132
- NewMigration("Add IsSystemWebhook column to webhooks table", v1_12.AddSystemWebhookColumn),
- // v132 -> v133
- NewMigration("Add Branch Protection Protected Files Column", v1_12.AddBranchProtectionProtectedFilesColumn),
- // v133 -> v134
- NewMigration("Add EmailHash Table", v1_12.AddEmailHashTable),
- // v134 -> v135
- NewMigration("Refix merge base for merged pull requests", v1_12.RefixMergeBase),
- // v135 -> v136
- NewMigration("Add OrgID column to Labels table", v1_12.AddOrgIDLabelColumn),
- // v136 -> v137
- NewMigration("Add CommitsAhead and CommitsBehind Column to PullRequest Table", v1_12.AddCommitDivergenceToPulls),
- // v137 -> v138
- NewMigration("Add Branch Protection Block Outdated Branch", v1_12.AddBlockOnOutdatedBranch),
- // v138 -> v139
- NewMigration("Add ResolveDoerID to Comment table", v1_12.AddResolveDoerIDCommentColumn),
- // v139 -> v140
- NewMigration("prepend refs/heads/ to issue refs", v1_12.PrependRefsHeadsToIssueRefs),
+ newMigration(117, "Add block on rejected reviews branch protection", v1_12.AddBlockOnRejectedReviews),
+ newMigration(118, "Add commit id and stale to reviews", v1_12.AddReviewCommitAndStale),
+ newMigration(119, "Fix migrated repositories' git service type", v1_12.FixMigratedRepositoryServiceType),
+ newMigration(120, "Add owner_name on table repository", v1_12.AddOwnerNameOnRepository),
+ newMigration(121, "add is_restricted column for users table", v1_12.AddIsRestricted),
+ newMigration(122, "Add Require Signed Commits to ProtectedBranch", v1_12.AddRequireSignedCommits),
+ newMigration(123, "Add original information for reactions", v1_12.AddReactionOriginals),
+ newMigration(124, "Add columns to user and repository", v1_12.AddUserRepoMissingColumns),
+ newMigration(125, "Add some columns on review for migration", v1_12.AddReviewMigrateInfo),
+ newMigration(126, "Fix topic repository count", v1_12.FixTopicRepositoryCount),
+ newMigration(127, "add repository code language statistics", v1_12.AddLanguageStats),
+ newMigration(128, "fix merge base for pull requests", v1_12.FixMergeBase),
+ newMigration(129, "remove dependencies from deleted repositories", v1_12.PurgeUnusedDependencies),
+ newMigration(130, "Expand webhooks for more granularity", v1_12.ExpandWebhooks),
+ newMigration(131, "Add IsSystemWebhook column to webhooks table", v1_12.AddSystemWebhookColumn),
+ newMigration(132, "Add Branch Protection Protected Files Column", v1_12.AddBranchProtectionProtectedFilesColumn),
+ newMigration(133, "Add EmailHash Table", v1_12.AddEmailHashTable),
+ newMigration(134, "Refix merge base for merged pull requests", v1_12.RefixMergeBase),
+ newMigration(135, "Add OrgID column to Labels table", v1_12.AddOrgIDLabelColumn),
+ newMigration(136, "Add CommitsAhead and CommitsBehind Column to PullRequest Table", v1_12.AddCommitDivergenceToPulls),
+ newMigration(137, "Add Branch Protection Block Outdated Branch", v1_12.AddBlockOnOutdatedBranch),
+ newMigration(138, "Add ResolveDoerID to Comment table", v1_12.AddResolveDoerIDCommentColumn),
+ newMigration(139, "prepend refs/heads/ to issue refs", v1_12.PrependRefsHeadsToIssueRefs),
- // Gitea 1.12.0 ends at v140
+ // Gitea 1.12.0 ends at database version 140
- // v140 -> v141
- NewMigration("Save detected language file size to database instead of percent", v1_13.FixLanguageStatsToSaveSize),
- // v141 -> v142
- NewMigration("Add KeepActivityPrivate to User table", v1_13.AddKeepActivityPrivateUserColumn),
- // v142 -> v143
- NewMigration("Ensure Repository.IsArchived is not null", v1_13.SetIsArchivedToFalse),
- // v143 -> v144
- NewMigration("recalculate Stars number for all user", v1_13.RecalculateStars),
- // v144 -> v145
- NewMigration("update Matrix Webhook http method to 'PUT'", v1_13.UpdateMatrixWebhookHTTPMethod),
- // v145 -> v146
- NewMigration("Increase Language field to 50 in LanguageStats", v1_13.IncreaseLanguageField),
- // v146 -> v147
- NewMigration("Add projects info to repository table", v1_13.AddProjectsInfo),
- // v147 -> v148
- NewMigration("create review for 0 review id code comments", v1_13.CreateReviewsForCodeComments),
- // v148 -> v149
- NewMigration("remove issue dependency comments who refer to non existing issues", v1_13.PurgeInvalidDependenciesComments),
- // v149 -> v150
- NewMigration("Add Created and Updated to Milestone table", v1_13.AddCreatedAndUpdatedToMilestones),
- // v150 -> v151
- NewMigration("add primary key to repo_topic", v1_13.AddPrimaryKeyToRepoTopic),
- // v151 -> v152
- NewMigration("set default password algorithm to Argon2", v1_13.SetDefaultPasswordToArgon2),
- // v152 -> v153
- NewMigration("add TrustModel field to Repository", v1_13.AddTrustModelToRepository),
- // v153 > v154
- NewMigration("add Team review request support", v1_13.AddTeamReviewRequestSupport),
- // v154 > v155
- NewMigration("add timestamps to Star, Label, Follow, Watch and Collaboration", v1_13.AddTimeStamps),
+ newMigration(140, "Save detected language file size to database instead of percent", v1_13.FixLanguageStatsToSaveSize),
+ newMigration(141, "Add KeepActivityPrivate to User table", v1_13.AddKeepActivityPrivateUserColumn),
+ newMigration(142, "Ensure Repository.IsArchived is not null", v1_13.SetIsArchivedToFalse),
+ newMigration(143, "recalculate Stars number for all user", v1_13.RecalculateStars),
+ newMigration(144, "update Matrix Webhook http method to 'PUT'", v1_13.UpdateMatrixWebhookHTTPMethod),
+ newMigration(145, "Increase Language field to 50 in LanguageStats", v1_13.IncreaseLanguageField),
+ newMigration(146, "Add projects info to repository table", v1_13.AddProjectsInfo),
+ newMigration(147, "create review for 0 review id code comments", v1_13.CreateReviewsForCodeComments),
+ newMigration(148, "remove issue dependency comments who refer to non existing issues", v1_13.PurgeInvalidDependenciesComments),
+ newMigration(149, "Add Created and Updated to Milestone table", v1_13.AddCreatedAndUpdatedToMilestones),
+ newMigration(150, "add primary key to repo_topic", v1_13.AddPrimaryKeyToRepoTopic),
+ newMigration(151, "set default password algorithm to Argon2", v1_13.SetDefaultPasswordToArgon2),
+ newMigration(152, "add TrustModel field to Repository", v1_13.AddTrustModelToRepository),
+ newMigration(153, "add Team review request support", v1_13.AddTeamReviewRequestSupport),
+ newMigration(154, "add timestamps to Star, Label, Follow, Watch and Collaboration", v1_13.AddTimeStamps),
- // Gitea 1.13.0 ends at v155
+ // Gitea 1.13.0 ends at database version 155
- // v155 -> v156
- NewMigration("add changed_protected_files column for pull_request table", v1_14.AddChangedProtectedFilesPullRequestColumn),
- // v156 -> v157
- NewMigration("fix publisher ID for tag releases", v1_14.FixPublisherIDforTagReleases),
- // v157 -> v158
- NewMigration("ensure repo topics are up-to-date", v1_14.FixRepoTopics),
- // v158 -> v159
- NewMigration("code comment replies should have the commitID of the review they are replying to", v1_14.UpdateCodeCommentReplies),
- // v159 -> v160
- NewMigration("update reactions constraint", v1_14.UpdateReactionConstraint),
- // v160 -> v161
- NewMigration("Add block on official review requests branch protection", v1_14.AddBlockOnOfficialReviewRequests),
- // v161 -> v162
- NewMigration("Convert task type from int to string", v1_14.ConvertTaskTypeToString),
- // v162 -> v163
- NewMigration("Convert webhook task type from int to string", v1_14.ConvertWebhookTaskTypeToString),
- // v163 -> v164
- NewMigration("Convert topic name from 25 to 50", v1_14.ConvertTopicNameFrom25To50),
- // v164 -> v165
- NewMigration("Add scope and nonce columns to oauth2_grant table", v1_14.AddScopeAndNonceColumnsToOAuth2Grant),
- // v165 -> v166
- NewMigration("Convert hook task type from char(16) to varchar(16) and trim the column", v1_14.ConvertHookTaskTypeToVarcharAndTrim),
- // v166 -> v167
- NewMigration("Where Password is Valid with Empty String delete it", v1_14.RecalculateUserEmptyPWD),
- // v167 -> v168
- NewMigration("Add user redirect", v1_14.AddUserRedirect),
- // v168 -> v169
- NewMigration("Recreate user table to fix default values", v1_14.RecreateUserTableToFixDefaultValues),
- // v169 -> v170
- NewMigration("Update DeleteBranch comments to set the old_ref to the commit_sha", v1_14.CommentTypeDeleteBranchUseOldRef),
- // v170 -> v171
- NewMigration("Add Dismissed to Review table", v1_14.AddDismissedReviewColumn),
- // v171 -> v172
- NewMigration("Add Sorting to ProjectBoard table", v1_14.AddSortingColToProjectBoard),
- // v172 -> v173
- NewMigration("Add sessions table for go-chi/session", v1_14.AddSessionTable),
- // v173 -> v174
- NewMigration("Add time_id column to Comment", v1_14.AddTimeIDCommentColumn),
- // v174 -> v175
- NewMigration("Create repo transfer table", v1_14.AddRepoTransfer),
- // v175 -> v176
- NewMigration("Fix Postgres ID Sequences broken by recreate-table", v1_14.FixPostgresIDSequences),
- // v176 -> v177
- NewMigration("Remove invalid labels from comments", v1_14.RemoveInvalidLabels),
- // v177 -> v178
- NewMigration("Delete orphaned IssueLabels", v1_14.DeleteOrphanedIssueLabels),
+ newMigration(155, "add changed_protected_files column for pull_request table", v1_14.AddChangedProtectedFilesPullRequestColumn),
+ newMigration(156, "fix publisher ID for tag releases", v1_14.FixPublisherIDforTagReleases),
+ newMigration(157, "ensure repo topics are up-to-date", v1_14.FixRepoTopics),
+ newMigration(158, "code comment replies should have the commitID of the review they are replying to", v1_14.UpdateCodeCommentReplies),
+ newMigration(159, "update reactions constraint", v1_14.UpdateReactionConstraint),
+ newMigration(160, "Add block on official review requests branch protection", v1_14.AddBlockOnOfficialReviewRequests),
+ newMigration(161, "Convert task type from int to string", v1_14.ConvertTaskTypeToString),
+ newMigration(162, "Convert webhook task type from int to string", v1_14.ConvertWebhookTaskTypeToString),
+ newMigration(163, "Convert topic name from 25 to 50", v1_14.ConvertTopicNameFrom25To50),
+ newMigration(164, "Add scope and nonce columns to oauth2_grant table", v1_14.AddScopeAndNonceColumnsToOAuth2Grant),
+ newMigration(165, "Convert hook task type from char(16) to varchar(16) and trim the column", v1_14.ConvertHookTaskTypeToVarcharAndTrim),
+ newMigration(166, "Where Password is Valid with Empty String delete it", v1_14.RecalculateUserEmptyPWD),
+ newMigration(167, "Add user redirect", v1_14.AddUserRedirect),
+ newMigration(168, "Recreate user table to fix default values", v1_14.RecreateUserTableToFixDefaultValues),
+ newMigration(169, "Update DeleteBranch comments to set the old_ref to the commit_sha", v1_14.CommentTypeDeleteBranchUseOldRef),
+ newMigration(170, "Add Dismissed to Review table", v1_14.AddDismissedReviewColumn),
+ newMigration(171, "Add Sorting to ProjectBoard table", v1_14.AddSortingColToProjectBoard),
+ newMigration(172, "Add sessions table for go-chi/session", v1_14.AddSessionTable),
+ newMigration(173, "Add time_id column to Comment", v1_14.AddTimeIDCommentColumn),
+ newMigration(174, "Create repo transfer table", v1_14.AddRepoTransfer),
+ newMigration(175, "Fix Postgres ID Sequences broken by recreate-table", v1_14.FixPostgresIDSequences),
+ newMigration(176, "Remove invalid labels from comments", v1_14.RemoveInvalidLabels),
+ newMigration(177, "Delete orphaned IssueLabels", v1_14.DeleteOrphanedIssueLabels),
- // Gitea 1.14.0 ends at v178
+ // Gitea 1.14.0 ends at database version 178
- // v178 -> v179
- NewMigration("Add LFS columns to Mirror", v1_15.AddLFSMirrorColumns),
- // v179 -> v180
- NewMigration("Convert avatar url to text", v1_15.ConvertAvatarURLToText),
- // v180 -> v181
- NewMigration("Delete credentials from past migrations", v1_15.DeleteMigrationCredentials),
- // v181 -> v182
- NewMigration("Always save primary email on email address table", v1_15.AddPrimaryEmail2EmailAddress),
- // v182 -> v183
- NewMigration("Add issue resource index table", v1_15.AddIssueResourceIndexTable),
- // v183 -> v184
- NewMigration("Create PushMirror table", v1_15.CreatePushMirrorTable),
- // v184 -> v185
- NewMigration("Rename Task errors to message", v1_15.RenameTaskErrorsToMessage),
- // v185 -> v186
- NewMigration("Add new table repo_archiver", v1_15.AddRepoArchiver),
- // v186 -> v187
- NewMigration("Create protected tag table", v1_15.CreateProtectedTagTable),
- // v187 -> v188
- NewMigration("Drop unneeded webhook related columns", v1_15.DropWebhookColumns),
- // v188 -> v189
- NewMigration("Add key is verified to gpg key", v1_15.AddKeyIsVerified),
+ newMigration(178, "Add LFS columns to Mirror", v1_15.AddLFSMirrorColumns),
+ newMigration(179, "Convert avatar url to text", v1_15.ConvertAvatarURLToText),
+ newMigration(180, "Delete credentials from past migrations", v1_15.DeleteMigrationCredentials),
+ newMigration(181, "Always save primary email on email address table", v1_15.AddPrimaryEmail2EmailAddress),
+ newMigration(182, "Add issue resource index table", v1_15.AddIssueResourceIndexTable),
+ newMigration(183, "Create PushMirror table", v1_15.CreatePushMirrorTable),
+ newMigration(184, "Rename Task errors to message", v1_15.RenameTaskErrorsToMessage),
+ newMigration(185, "Add new table repo_archiver", v1_15.AddRepoArchiver),
+ newMigration(186, "Create protected tag table", v1_15.CreateProtectedTagTable),
+ newMigration(187, "Drop unneeded webhook related columns", v1_15.DropWebhookColumns),
+ newMigration(188, "Add key is verified to gpg key", v1_15.AddKeyIsVerified),
- // Gitea 1.15.0 ends at v189
+ // Gitea 1.15.0 ends at database version 189
- // v189 -> v190
- NewMigration("Unwrap ldap.Sources", v1_16.UnwrapLDAPSourceCfg),
- // v190 -> v191
- NewMigration("Add agit flow pull request support", v1_16.AddAgitFlowPullRequest),
- // v191 -> v192
- NewMigration("Alter issue/comment table TEXT fields to LONGTEXT", v1_16.AlterIssueAndCommentTextFieldsToLongText),
- // v192 -> v193
- NewMigration("RecreateIssueResourceIndexTable to have a primary key instead of an unique index", v1_16.RecreateIssueResourceIndexTable),
- // v193 -> v194
- NewMigration("Add repo id column for attachment table", v1_16.AddRepoIDForAttachment),
- // v194 -> v195
- NewMigration("Add Branch Protection Unprotected Files Column", v1_16.AddBranchProtectionUnprotectedFilesColumn),
- // v195 -> v196
- NewMigration("Add table commit_status_index", v1_16.AddTableCommitStatusIndex),
- // v196 -> v197
- NewMigration("Add Color to ProjectBoard table", v1_16.AddColorColToProjectBoard),
- // v197 -> v198
- NewMigration("Add renamed_branch table", v1_16.AddRenamedBranchTable),
- // v198 -> v199
- NewMigration("Add issue content history table", v1_16.AddTableIssueContentHistory),
- // v199 -> v200
- NewMigration("No-op (remote version is using AppState now)", noopMigration),
- // v200 -> v201
- NewMigration("Add table app_state", v1_16.AddTableAppState),
- // v201 -> v202
- NewMigration("Drop table remote_version (if exists)", v1_16.DropTableRemoteVersion),
- // v202 -> v203
- NewMigration("Create key/value table for user settings", v1_16.CreateUserSettingsTable),
- // v203 -> v204
- NewMigration("Add Sorting to ProjectIssue table", v1_16.AddProjectIssueSorting),
- // v204 -> v205
- NewMigration("Add key is verified to ssh key", v1_16.AddSSHKeyIsVerified),
- // v205 -> v206
- NewMigration("Migrate to higher varchar on user struct", v1_16.MigrateUserPasswordSalt),
- // v206 -> v207
- NewMigration("Add authorize column to team_unit table", v1_16.AddAuthorizeColForTeamUnit),
- // v207 -> v208
- NewMigration("Add webauthn table and migrate u2f data to webauthn - NO-OPED", v1_16.AddWebAuthnCred),
- // v208 -> v209
- NewMigration("Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED", v1_16.UseBase32HexForCredIDInWebAuthnCredential),
- // v209 -> v210
- NewMigration("Increase WebAuthentication CredentialID size to 410 - NO-OPED", v1_16.IncreaseCredentialIDTo410),
- // v210 -> v211
- NewMigration("v208 was completely broken - remigrate", v1_16.RemigrateU2FCredentials),
+ newMigration(189, "Unwrap ldap.Sources", v1_16.UnwrapLDAPSourceCfg),
+ newMigration(190, "Add agit flow pull request support", v1_16.AddAgitFlowPullRequest),
+ newMigration(191, "Alter issue/comment table TEXT fields to LONGTEXT", v1_16.AlterIssueAndCommentTextFieldsToLongText),
+ newMigration(192, "RecreateIssueResourceIndexTable to have a primary key instead of an unique index", v1_16.RecreateIssueResourceIndexTable),
+ newMigration(193, "Add repo id column for attachment table", v1_16.AddRepoIDForAttachment),
+ newMigration(194, "Add Branch Protection Unprotected Files Column", v1_16.AddBranchProtectionUnprotectedFilesColumn),
+ newMigration(195, "Add table commit_status_index", v1_16.AddTableCommitStatusIndex),
+ newMigration(196, "Add Color to ProjectBoard table", v1_16.AddColorColToProjectBoard),
+ newMigration(197, "Add renamed_branch table", v1_16.AddRenamedBranchTable),
+ newMigration(198, "Add issue content history table", v1_16.AddTableIssueContentHistory),
+ newMigration(199, "No-op (remote version is using AppState now)", noopMigration),
+ newMigration(200, "Add table app_state", v1_16.AddTableAppState),
+ newMigration(201, "Drop table remote_version (if exists)", v1_16.DropTableRemoteVersion),
+ newMigration(202, "Create key/value table for user settings", v1_16.CreateUserSettingsTable),
+ newMigration(203, "Add Sorting to ProjectIssue table", v1_16.AddProjectIssueSorting),
+ newMigration(204, "Add key is verified to ssh key", v1_16.AddSSHKeyIsVerified),
+ newMigration(205, "Migrate to higher varchar on user struct", v1_16.MigrateUserPasswordSalt),
+ newMigration(206, "Add authorize column to team_unit table", v1_16.AddAuthorizeColForTeamUnit),
+ newMigration(207, "Add webauthn table and migrate u2f data to webauthn - NO-OPED", v1_16.AddWebAuthnCred),
+ newMigration(208, "Use base32.HexEncoding instead of base64 encoding for cred ID as it is case insensitive - NO-OPED", v1_16.UseBase32HexForCredIDInWebAuthnCredential),
+ newMigration(209, "Increase WebAuthentication CredentialID size to 410 - NO-OPED", v1_16.IncreaseCredentialIDTo410),
+ newMigration(210, "v208 was completely broken - remigrate", v1_16.RemigrateU2FCredentials),
- // Gitea 1.16.2 ends at v211
+ // Gitea 1.16.2 ends at database version 211
- // v211 -> v212
- NewMigration("Create ForeignReference table", v1_17.CreateForeignReferenceTable),
- // v212 -> v213
- NewMigration("Add package tables", v1_17.AddPackageTables),
- // v213 -> v214
- NewMigration("Add allow edits from maintainers to PullRequest table", v1_17.AddAllowMaintainerEdit),
- // v214 -> v215
- NewMigration("Add auto merge table", v1_17.AddAutoMergeTable),
- // v215 -> v216
- NewMigration("allow to view files in PRs", v1_17.AddReviewViewedFiles),
- // v216 -> v217
- NewMigration("No-op (Improve Action table indices v1)", noopMigration),
- // v217 -> v218
- NewMigration("Alter hook_task table TEXT fields to LONGTEXT", v1_17.AlterHookTaskTextFieldsToLongText),
- // v218 -> v219
- NewMigration("Improve Action table indices v2", v1_17.ImproveActionTableIndices),
- // v219 -> v220
- NewMigration("Add sync_on_commit column to push_mirror table", v1_17.AddSyncOnCommitColForPushMirror),
- // v220 -> v221
- NewMigration("Add container repository property", v1_17.AddContainerRepositoryProperty),
- // v221 -> v222
- NewMigration("Store WebAuthentication CredentialID as bytes and increase size to at least 1024", v1_17.StoreWebauthnCredentialIDAsBytes),
- // v222 -> v223
- NewMigration("Drop old CredentialID column", v1_17.DropOldCredentialIDColumn),
- // v223 -> v224
- NewMigration("Rename CredentialIDBytes column to CredentialID", v1_17.RenameCredentialIDBytes),
+ newMigration(211, "Create ForeignReference table", v1_17.CreateForeignReferenceTable),
+ newMigration(212, "Add package tables", v1_17.AddPackageTables),
+ newMigration(213, "Add allow edits from maintainers to PullRequest table", v1_17.AddAllowMaintainerEdit),
+ newMigration(214, "Add auto merge table", v1_17.AddAutoMergeTable),
+ newMigration(215, "allow to view files in PRs", v1_17.AddReviewViewedFiles),
+ newMigration(216, "No-op (Improve Action table indices v1)", noopMigration),
+ newMigration(217, "Alter hook_task table TEXT fields to LONGTEXT", v1_17.AlterHookTaskTextFieldsToLongText),
+ newMigration(218, "Improve Action table indices v2", v1_17.ImproveActionTableIndices),
+ newMigration(219, "Add sync_on_commit column to push_mirror table", v1_17.AddSyncOnCommitColForPushMirror),
+ newMigration(220, "Add container repository property", v1_17.AddContainerRepositoryProperty),
+ newMigration(221, "Store WebAuthentication CredentialID as bytes and increase size to at least 1024", v1_17.StoreWebauthnCredentialIDAsBytes),
+ newMigration(222, "Drop old CredentialID column", v1_17.DropOldCredentialIDColumn),
+ newMigration(223, "Rename CredentialIDBytes column to CredentialID", v1_17.RenameCredentialIDBytes),
- // Gitea 1.17.0 ends at v224
+ // Gitea 1.17.0 ends at database version 224
- // v224 -> v225
- NewMigration("Add badges to users", v1_18.CreateUserBadgesTable),
- // v225 -> v226
- NewMigration("Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", v1_18.AlterPublicGPGKeyContentFieldsToMediumText),
- // v226 -> v227
- NewMigration("Conan and generic packages do not need to be semantically versioned", v1_18.FixPackageSemverField),
- // v227 -> v228
- NewMigration("Create key/value table for system settings", v1_18.CreateSystemSettingsTable),
- // v228 -> v229
- NewMigration("Add TeamInvite table", v1_18.AddTeamInviteTable),
- // v229 -> v230
- NewMigration("Update counts of all open milestones", v1_18.UpdateOpenMilestoneCounts),
- // v230 -> v231
- NewMigration("Add ConfidentialClient column (default true) to OAuth2Application table", v1_18.AddConfidentialClientColumnToOAuth2ApplicationTable),
+ newMigration(224, "Add badges to users", v1_18.CreateUserBadgesTable),
+ newMigration(225, "Alter gpg_key/public_key content TEXT fields to MEDIUMTEXT", v1_18.AlterPublicGPGKeyContentFieldsToMediumText),
+ newMigration(226, "Conan and generic packages do not need to be semantically versioned", v1_18.FixPackageSemverField),
+ newMigration(227, "Create key/value table for system settings", v1_18.CreateSystemSettingsTable),
+ newMigration(228, "Add TeamInvite table", v1_18.AddTeamInviteTable),
+ newMigration(229, "Update counts of all open milestones", v1_18.UpdateOpenMilestoneCounts),
+ newMigration(230, "Add ConfidentialClient column (default true) to OAuth2Application table", v1_18.AddConfidentialClientColumnToOAuth2ApplicationTable),
- // Gitea 1.18.0 ends at v231
+ // Gitea 1.18.0 ends at database version 231
- // v231 -> v232
- NewMigration("Add index for hook_task", v1_19.AddIndexForHookTask),
- // v232 -> v233
- NewMigration("Alter package_version.metadata_json to LONGTEXT", v1_19.AlterPackageVersionMetadataToLongText),
- // v233 -> v234
- NewMigration("Add header_authorization_encrypted column to webhook table", v1_19.AddHeaderAuthorizationEncryptedColWebhook),
- // v234 -> v235
- NewMigration("Add package cleanup rule table", v1_19.CreatePackageCleanupRuleTable),
- // v235 -> v236
- NewMigration("Add index for access_token", v1_19.AddIndexForAccessToken),
- // v236 -> v237
- NewMigration("Create secrets table", v1_19.CreateSecretsTable),
- // v237 -> v238
- NewMigration("Drop ForeignReference table", v1_19.DropForeignReferenceTable),
- // v238 -> v239
- NewMigration("Add updated unix to LFSMetaObject", v1_19.AddUpdatedUnixToLFSMetaObject),
- // v239 -> v240
- NewMigration("Add scope for access_token", v1_19.AddScopeForAccessTokens),
- // v240 -> v241
- NewMigration("Add actions tables", v1_19.AddActionsTables),
- // v241 -> v242
- NewMigration("Add card_type column to project table", v1_19.AddCardTypeToProjectTable),
- // v242 -> v243
- NewMigration("Alter gpg_key_import content TEXT field to MEDIUMTEXT", v1_19.AlterPublicGPGKeyImportContentFieldToMediumText),
- // v243 -> v244
- NewMigration("Add exclusive label", v1_19.AddExclusiveLabel),
+ newMigration(231, "Add index for hook_task", v1_19.AddIndexForHookTask),
+ newMigration(232, "Alter package_version.metadata_json to LONGTEXT", v1_19.AlterPackageVersionMetadataToLongText),
+ newMigration(233, "Add header_authorization_encrypted column to webhook table", v1_19.AddHeaderAuthorizationEncryptedColWebhook),
+ newMigration(234, "Add package cleanup rule table", v1_19.CreatePackageCleanupRuleTable),
+ newMigration(235, "Add index for access_token", v1_19.AddIndexForAccessToken),
+ newMigration(236, "Create secrets table", v1_19.CreateSecretsTable),
+ newMigration(237, "Drop ForeignReference table", v1_19.DropForeignReferenceTable),
+ newMigration(238, "Add updated unix to LFSMetaObject", v1_19.AddUpdatedUnixToLFSMetaObject),
+ newMigration(239, "Add scope for access_token", v1_19.AddScopeForAccessTokens),
+ newMigration(240, "Add actions tables", v1_19.AddActionsTables),
+ newMigration(241, "Add card_type column to project table", v1_19.AddCardTypeToProjectTable),
+ newMigration(242, "Alter gpg_key_import content TEXT field to MEDIUMTEXT", v1_19.AlterPublicGPGKeyImportContentFieldToMediumText),
+ newMigration(243, "Add exclusive label", v1_19.AddExclusiveLabel),
- // Gitea 1.19.0 ends at v244
+ // Gitea 1.19.0 ends at database version 244
- // v244 -> v245
- NewMigration("Add NeedApproval to actions tables", v1_20.AddNeedApprovalToActionRun),
- // v245 -> v246
- NewMigration("Rename Webhook org_id to owner_id", v1_20.RenameWebhookOrgToOwner),
- // v246 -> v247
- NewMigration("Add missed column owner_id for project table", v1_20.AddNewColumnForProject),
- // v247 -> v248
- NewMigration("Fix incorrect project type", v1_20.FixIncorrectProjectType),
- // v248 -> v249
- NewMigration("Add version column to action_runner table", v1_20.AddVersionToActionRunner),
- // v249 -> v250
- NewMigration("Improve Action table indices v3", v1_20.ImproveActionTableIndices),
- // v250 -> v251
- NewMigration("Change Container Metadata", v1_20.ChangeContainerMetadataMultiArch),
- // v251 -> v252
- NewMigration("Fix incorrect owner team unit access mode", v1_20.FixIncorrectOwnerTeamUnitAccessMode),
- // v252 -> v253
- NewMigration("Fix incorrect admin team unit access mode", v1_20.FixIncorrectAdminTeamUnitAccessMode),
- // v253 -> v254
- NewMigration("Fix ExternalTracker and ExternalWiki accessMode in owner and admin team", v1_20.FixExternalTrackerAndExternalWikiAccessModeInOwnerAndAdminTeam),
- // v254 -> v255
- NewMigration("Add ActionTaskOutput table", v1_20.AddActionTaskOutputTable),
- // v255 -> v256
- NewMigration("Add ArchivedUnix Column", v1_20.AddArchivedUnixToRepository),
- // v256 -> v257
- NewMigration("Add is_internal column to package", v1_20.AddIsInternalColumnToPackage),
- // v257 -> v258
- NewMigration("Add Actions Artifact table", v1_20.CreateActionArtifactTable),
- // v258 -> v259
- NewMigration("Add PinOrder Column", v1_20.AddPinOrderToIssue),
- // v259 -> v260
- NewMigration("Convert scoped access tokens", v1_20.ConvertScopedAccessTokens),
+ newMigration(244, "Add NeedApproval to actions tables", v1_20.AddNeedApprovalToActionRun),
+ newMigration(245, "Rename Webhook org_id to owner_id", v1_20.RenameWebhookOrgToOwner),
+ newMigration(246, "Add missed column owner_id for project table", v1_20.AddNewColumnForProject),
+ newMigration(247, "Fix incorrect project type", v1_20.FixIncorrectProjectType),
+ newMigration(248, "Add version column to action_runner table", v1_20.AddVersionToActionRunner),
+ newMigration(249, "Improve Action table indices v3", v1_20.ImproveActionTableIndices),
+ newMigration(250, "Change Container Metadata", v1_20.ChangeContainerMetadataMultiArch),
+ newMigration(251, "Fix incorrect owner team unit access mode", v1_20.FixIncorrectOwnerTeamUnitAccessMode),
+ newMigration(252, "Fix incorrect admin team unit access mode", v1_20.FixIncorrectAdminTeamUnitAccessMode),
+ newMigration(253, "Fix ExternalTracker and ExternalWiki accessMode in owner and admin team", v1_20.FixExternalTrackerAndExternalWikiAccessModeInOwnerAndAdminTeam),
+ newMigration(254, "Add ActionTaskOutput table", v1_20.AddActionTaskOutputTable),
+ newMigration(255, "Add ArchivedUnix Column", v1_20.AddArchivedUnixToRepository),
+ newMigration(256, "Add is_internal column to package", v1_20.AddIsInternalColumnToPackage),
+ newMigration(257, "Add Actions Artifact table", v1_20.CreateActionArtifactTable),
+ newMigration(258, "Add PinOrder Column", v1_20.AddPinOrderToIssue),
+ newMigration(259, "Convert scoped access tokens", v1_20.ConvertScopedAccessTokens),
- // Gitea 1.20.0 ends at 260
+ // Gitea 1.20.0 ends at database version 260
- // v260 -> v261
- NewMigration("Drop custom_labels column of action_runner table", v1_21.DropCustomLabelsColumnOfActionRunner),
- // v261 -> v262
- NewMigration("Add variable table", v1_21.CreateVariableTable),
- // v262 -> v263
- NewMigration("Add TriggerEvent to action_run table", v1_21.AddTriggerEventToActionRun),
- // v263 -> v264
- NewMigration("Add git_size and lfs_size columns to repository table", v1_21.AddGitSizeAndLFSSizeToRepositoryTable),
- // v264 -> v265
- NewMigration("Add branch table", v1_21.AddBranchTable),
- // v265 -> v266
- NewMigration("Alter Actions Artifact table", v1_21.AlterActionArtifactTable),
- // v266 -> v267
- NewMigration("Reduce commit status", v1_21.ReduceCommitStatus),
- // v267 -> v268
- NewMigration("Add action_tasks_version table", v1_21.CreateActionTasksVersionTable),
- // v268 -> v269
- NewMigration("Update Action Ref", v1_21.UpdateActionsRefIndex),
- // v269 -> v270
- NewMigration("Drop deleted branch table", v1_21.DropDeletedBranchTable),
- // v270 -> v271
- NewMigration("Fix PackageProperty typo", v1_21.FixPackagePropertyTypo),
- // v271 -> v272
- NewMigration("Allow archiving labels", v1_21.AddArchivedUnixColumInLabelTable),
- // v272 -> v273
- NewMigration("Add Version to ActionRun table", v1_21.AddVersionToActionRunTable),
- // v273 -> v274
- NewMigration("Add Action Schedule Table", v1_21.AddActionScheduleTable),
- // v274 -> v275
- NewMigration("Add Actions artifacts expiration date", v1_21.AddExpiredUnixColumnInActionArtifactTable),
- // v275 -> v276
- NewMigration("Add ScheduleID for ActionRun", v1_21.AddScheduleIDForActionRun),
- // v276 -> v277
- NewMigration("Add RemoteAddress to mirrors", v1_21.AddRemoteAddressToMirrors),
- // v277 -> v278
- NewMigration("Add Index to issue_user.issue_id", v1_21.AddIndexToIssueUserIssueID),
- // v278 -> v279
- NewMigration("Add Index to comment.dependent_issue_id", v1_21.AddIndexToCommentDependentIssueID),
- // v279 -> v280
- NewMigration("Add Index to action.user_id", v1_21.AddIndexToActionUserID),
+ newMigration(260, "Drop custom_labels column of action_runner table", v1_21.DropCustomLabelsColumnOfActionRunner),
+ newMigration(261, "Add variable table", v1_21.CreateVariableTable),
+ newMigration(262, "Add TriggerEvent to action_run table", v1_21.AddTriggerEventToActionRun),
+ newMigration(263, "Add git_size and lfs_size columns to repository table", v1_21.AddGitSizeAndLFSSizeToRepositoryTable),
+ newMigration(264, "Add branch table", v1_21.AddBranchTable),
+ newMigration(265, "Alter Actions Artifact table", v1_21.AlterActionArtifactTable),
+ newMigration(266, "Reduce commit status", v1_21.ReduceCommitStatus),
+ newMigration(267, "Add action_tasks_version table", v1_21.CreateActionTasksVersionTable),
+ newMigration(268, "Update Action Ref", v1_21.UpdateActionsRefIndex),
+ newMigration(269, "Drop deleted branch table", v1_21.DropDeletedBranchTable),
+ newMigration(270, "Fix PackageProperty typo", v1_21.FixPackagePropertyTypo),
+ newMigration(271, "Allow archiving labels", v1_21.AddArchivedUnixColumInLabelTable),
+ newMigration(272, "Add Version to ActionRun table", v1_21.AddVersionToActionRunTable),
+ newMigration(273, "Add Action Schedule Table", v1_21.AddActionScheduleTable),
+ newMigration(274, "Add Actions artifacts expiration date", v1_21.AddExpiredUnixColumnInActionArtifactTable),
+ newMigration(275, "Add ScheduleID for ActionRun", v1_21.AddScheduleIDForActionRun),
+ newMigration(276, "Add RemoteAddress to mirrors", v1_21.AddRemoteAddressToMirrors),
+ newMigration(277, "Add Index to issue_user.issue_id", v1_21.AddIndexToIssueUserIssueID),
+ newMigration(278, "Add Index to comment.dependent_issue_id", v1_21.AddIndexToCommentDependentIssueID),
+ newMigration(279, "Add Index to action.user_id", v1_21.AddIndexToActionUserID),
- // Gitea 1.21.0 ends at 280
+ // Gitea 1.21.0 ends at database version 280
- // v280 -> v281
- NewMigration("Rename user themes", v1_22.RenameUserThemes),
- // v281 -> v282
- NewMigration("Add auth_token table", v1_22.CreateAuthTokenTable),
- // v282 -> v283
- NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID),
- // v283 -> v284
- NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser),
- // v284 -> v285
- NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable),
- // v285 -> v286
- NewMigration("Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun),
- // v286 -> v287
- NewMigration("Add support for SHA256 git repositories", v1_22.AdjustDBForSha256),
- // v287 -> v288
- NewMigration("Use Slug instead of ID for Badges", v1_22.UseSlugInsteadOfIDForBadges),
- // v288 -> v289
- NewMigration("Add user_blocking table", v1_22.AddUserBlockingTable),
- // v289 -> v290
- NewMigration("Add default_wiki_branch to repository table", v1_22.AddDefaultWikiBranch),
- // v290 -> v291
- NewMigration("Add PayloadVersion to HookTask", v1_22.AddPayloadVersionToHookTaskTable),
- // v291 -> v292
- NewMigration("Add Index to attachment.comment_id", v1_22.AddCommentIDIndexofAttachment),
- // v292 -> v293
- NewMigration("Ensure every project has exactly one default column - No Op", noopMigration),
- // v293 -> v294
- NewMigration("Ensure every project has exactly one default column", v1_22.CheckProjectColumnsConsistency),
+ newMigration(280, "Rename user themes", v1_22.RenameUserThemes),
+ newMigration(281, "Add auth_token table", v1_22.CreateAuthTokenTable),
+ newMigration(282, "Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID),
+ newMigration(283, "Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser),
+ newMigration(284, "Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable),
+ newMigration(285, "Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun),
+ newMigration(286, "Add support for SHA256 git repositories", v1_22.AdjustDBForSha256),
+ newMigration(287, "Use Slug instead of ID for Badges", v1_22.UseSlugInsteadOfIDForBadges),
+ newMigration(288, "Add user_blocking table", v1_22.AddUserBlockingTable),
+ newMigration(289, "Add default_wiki_branch to repository table", v1_22.AddDefaultWikiBranch),
+ newMigration(290, "Add PayloadVersion to HookTask", v1_22.AddPayloadVersionToHookTaskTable),
+ newMigration(291, "Add Index to attachment.comment_id", v1_22.AddCommentIDIndexofAttachment),
+ newMigration(292, "Ensure every project has exactly one default column - No Op", noopMigration),
+ newMigration(293, "Ensure every project has exactly one default column", v1_22.CheckProjectColumnsConsistency),
- // Gitea 1.22.0-rc0 ends at 294
+ // Gitea 1.22.0-rc0 ends at database version 294
- // v294 -> v295
- NewMigration("Add unique index for project issue table", v1_22.AddUniqueIndexForProjectIssue),
- // v295 -> v296
- NewMigration("Add commit status summary table", v1_22.AddCommitStatusSummary),
- // v296 -> v297
- NewMigration("Add missing field of commit status summary table", v1_22.AddCommitStatusSummary2),
- // v297 -> v298
- NewMigration("Add everyone_access_mode for repo_unit", noopMigration),
- // v298 -> v299
- NewMigration("Drop wrongly created table o_auth2_application", v1_22.DropWronglyCreatedTable),
+ newMigration(294, "Add unique index for project issue table", v1_22.AddUniqueIndexForProjectIssue),
+ newMigration(295, "Add commit status summary table", v1_22.AddCommitStatusSummary),
+ newMigration(296, "Add missing field of commit status summary table", v1_22.AddCommitStatusSummary2),
+ newMigration(297, "Add everyone_access_mode for repo_unit", noopMigration),
+ newMigration(298, "Drop wrongly created table o_auth2_application", v1_22.DropWronglyCreatedTable),
- // Gitea 1.22.0-rc1 ends at 299
+ // Gitea 1.22.0-rc1 ends at migration ID number 298 (database version 299)
- // v299 -> v300
- NewMigration("Add content version to issue and comment table", v1_23.AddContentVersionToIssueAndComment),
+ newMigration(299, "Add content version to issue and comment table", v1_23.AddContentVersionToIssueAndComment),
+ newMigration(300, "Add force-push branch protection support", v1_23.AddForcePushBranchProtection),
+ newMigration(301, "Add skip_secondary_authorization option to oauth2 application table", v1_23.AddSkipSecondaryAuthColumnToOAuth2ApplicationTable),
+ newMigration(302, "Add index to action_task stopped log_expired", v1_23.AddIndexToActionTaskStoppedLogExpired),
+
+ // Migration to Forgejo v10
+ newMigration(303, "Gitea last drop", v1_23.GiteaLastDrop),
+ newMigration(304, "Migrate `secret` column to store keying material", forgejo_migrations.MigrateTwoFactorToKeying),
+ }
+ return preparedMigrations
}
// GetCurrentDBVersion returns the current db version
@@ -612,9 +387,20 @@ func GetCurrentDBVersion(x *xorm.Engine) (int64, error) {
return currentVersion.Version, nil
}
-// ExpectedVersion returns the expected db version
-func ExpectedVersion() int64 {
- return int64(minDBVersion + len(migrations))
+func calcDBVersion(migrations []*migration) int64 {
+ dbVer := int64(minDBVersion + len(migrations))
+ if migrations[0].idNumber != minDBVersion {
+ panic("migrations should start at minDBVersion")
+ }
+ if dbVer != migrations[len(migrations)-1].idNumber+1 {
+ panic("migrations are not in order")
+ }
+ return dbVer
+}
+
+// ExpectedDBVersion returns the expected db version
+func ExpectedDBVersion() int64 {
+ return calcDBVersion(prepareMigrationTasks())
}
// EnsureUpToDate will check if the db is at the correct version
@@ -625,24 +411,35 @@ func EnsureUpToDate(x *xorm.Engine) error {
}
if currentDB < 0 {
- return fmt.Errorf("Database has not been initialized")
+ return fmt.Errorf("database has not been initialized")
}
if minDBVersion > currentDB {
return fmt.Errorf("DB version %d (<= %d) is too old for auto-migration. Upgrade to Gitea 1.6.4 first then upgrade to this version", currentDB, minDBVersion)
}
- expected := ExpectedVersion()
+ expectedDB := ExpectedDBVersion()
- if currentDB != expected {
- return fmt.Errorf(`Current database version %d is not equal to the expected version %d. Please run "forgejo [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expected)
+ if currentDB != expectedDB {
+ return fmt.Errorf(`current database version %d is not equal to the expected version %d. Please run "forgejo [--config /path/to/app.ini] migrate" to update the database version`, currentDB, expectedDB)
}
return forgejo_migrations.EnsureUpToDate(x)
}
+func getPendingMigrations(curDBVer int64, migrations []*migration) []*migration {
+ return migrations[curDBVer-minDBVersion:]
+}
+
+func migrationIDNumberToDBVersion(idNumber int64) int64 {
+ return idNumber + 1
+}
+
// Migrate database to current version
func Migrate(x *xorm.Engine) error {
+ migrations := prepareMigrationTasks()
+ maxDBVer := calcDBVersion(migrations)
+
// Set a new clean the default mapper to GonicMapper as that is the default for Gitea.
x.SetMapper(names.GonicMapper{})
if err := x.Sync(new(Version)); err != nil {
@@ -655,11 +452,10 @@ func Migrate(x *xorm.Engine) error {
if err != nil {
return fmt.Errorf("get: %w", err)
} else if !has {
- // If the version record does not exist we think
- // it is a fresh installation and we can skip all migrations.
+ // If the version record does not exist, it is a fresh installation, and we can skip all migrations.
+ // XORM model framework will create all tables when initializing.
currentVersion.ID = 0
- currentVersion.Version = int64(minDBVersion + len(migrations))
-
+ currentVersion.Version = maxDBVer
if _, err = x.InsertOne(currentVersion); err != nil {
return fmt.Errorf("insert: %w", err)
}
@@ -667,19 +463,20 @@ func Migrate(x *xorm.Engine) error {
previousVersion = currentVersion.Version
}
- v := currentVersion.Version
- if minDBVersion > v {
+ curDBVer := currentVersion.Version
+ // Outdated Forgejo database version is not supported
+ if curDBVer < minDBVersion {
log.Fatal(`Forgejo no longer supports auto-migration from your previously installed version.
Please try upgrading to a lower version first (suggested v1.6.4), then upgrade to this version.`)
return nil
}
- // Downgrading Forgejo database version is not supported
- if int(v-minDBVersion) > len(migrations) {
- msg := fmt.Sprintf("Your database (migration version: %d) is for a newer Forgejo, you can not use the newer database for this old Forgejo release (%d).", v, minDBVersion+len(migrations))
+ // Downgrading Forgejo's database version not supported
+ if maxDBVer < curDBVer {
+ msg := fmt.Sprintf("Your database (migration version: %d) is for a newer Forgejo, you can not use the newer database for this old Forgejo release (%d).", curDBVer, maxDBVer)
msg += "\nForgejo will exit to keep your database safe and unchanged. Please use the correct Forgejo release, do not change the migration version manually (incorrect manual operation may lose data)."
if !setting.IsProd {
- msg += fmt.Sprintf("\nIf you are in development and really know what you're doing, you can force changing the migration version by executing: UPDATE version SET version=%d WHERE id=1;", minDBVersion+len(migrations))
+ msg += fmt.Sprintf("\nIf you are in development and really know what you're doing, you can force changing the migration version by executing: UPDATE version SET version=%d WHERE id=1;", maxDBVer)
}
log.Fatal("Migration Error: %s", msg)
return nil
@@ -697,14 +494,14 @@ Please try upgrading to a lower version first (suggested v1.6.4), then upgrade t
}
// Migrate
- for i, m := range migrations[v-minDBVersion:] {
- log.Info("Migration[%d]: %s", v+int64(i), m.Description())
+ for _, m := range getPendingMigrations(curDBVer, migrations) {
+ log.Info("Migration[%d]: %s", m.idNumber, m.description)
// Reset the mapper between each migration - migrations are not supposed to depend on each other
x.SetMapper(names.GonicMapper{})
if err = m.Migrate(x); err != nil {
- return fmt.Errorf("migration[%d]: %s failed: %w", v+int64(i), m.Description(), err)
+ return fmt.Errorf("migration[%d]: %s failed: %w", m.idNumber, m.description, err)
}
- currentVersion.Version = v + int64(i) + 1
+ currentVersion.Version = migrationIDNumberToDBVersion(m.idNumber)
if _, err = x.ID(1).Update(currentVersion); err != nil {
return err
}
diff --git a/models/migrations/migrations_test.go b/models/migrations/migrations_test.go
new file mode 100644
index 0000000000..ea941b9a09
--- /dev/null
+++ b/models/migrations/migrations_test.go
@@ -0,0 +1,27 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package migrations
+
+import (
+ "testing"
+
+ "forgejo.org/modules/test"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestMigrations(t *testing.T) {
+ defer test.MockVariableValue(&preparedMigrations, []*migration{
+ {idNumber: 70},
+ {idNumber: 71},
+ })()
+ assert.EqualValues(t, 72, calcDBVersion(preparedMigrations))
+ assert.EqualValues(t, 72, ExpectedDBVersion())
+
+ assert.EqualValues(t, 71, migrationIDNumberToDBVersion(70))
+
+ assert.EqualValues(t, []*migration{{idNumber: 70}, {idNumber: 71}}, getPendingMigrations(70, preparedMigrations))
+ assert.EqualValues(t, []*migration{{idNumber: 71}}, getPendingMigrations(71, preparedMigrations))
+ assert.EqualValues(t, []*migration{}, getPendingMigrations(72, preparedMigrations))
+}
diff --git a/models/migrations/base/tests.go b/models/migrations/test/tests.go
similarity index 57%
rename from models/migrations/base/tests.go
rename to models/migrations/test/tests.go
index 0989902a65..07487cf58a 100644
--- a/models/migrations/base/tests.go
+++ b/models/migrations/test/tests.go
@@ -2,30 +2,32 @@
// SPDX-License-Identifier: MIT
//nolint:forbidigo
-package base
+package test
import (
"context"
+ "database/sql"
"fmt"
"os"
"path"
"path/filepath"
- "runtime"
+ "strings"
"testing"
+ "time"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/testlogger"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/testlogger"
+ "forgejo.org/modules/util"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/xorm"
)
-// FIXME: this file shouldn't be in a normal package, it should only be compiled for tests
-
// PrepareTestEnv prepares the test environment and reset the database. The skip parameter should usually be 0.
// Provide models to be sync'd with the database - in particular any models you expect fixtures to be loaded from.
//
@@ -35,11 +37,11 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu
ourSkip := 2
ourSkip += skip
deferFn := testlogger.PrintCurrentTest(t, ourSkip)
- assert.NoError(t, os.RemoveAll(setting.RepoRootPath))
- assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath))
+ require.NoError(t, os.RemoveAll(setting.RepoRootPath))
+ require.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath))
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil {
- assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
+ require.NoError(t, err, "unable to read the new repo root: %v\n", err)
}
for _, ownerDir := range ownerDirs {
if !ownerDir.Type().IsDir() {
@@ -47,7 +49,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu
}
repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name()))
if err != nil {
- assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
+ require.NoError(t, err, "unable to read the new repo root: %v\n", err)
}
for _, repoDir := range repoDirs {
_ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0o755)
@@ -63,7 +65,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...any) (*xorm.Engine, fu
}
x, err := newXORMEngine()
- assert.NoError(t, err)
+ require.NoError(t, err)
if x != nil {
oldDefer := deferFn
deferFn = func() {
@@ -120,9 +122,6 @@ func MainTest(m *testing.M) {
os.Exit(1)
}
giteaBinary := "gitea"
- if runtime.GOOS == "windows" {
- giteaBinary += ".exe"
- }
setting.AppPath = path.Join(giteaRoot, giteaBinary)
if _, err := os.Stat(setting.AppPath); err != nil {
fmt.Printf("Could not find gitea binary at %s\n", setting.AppPath)
@@ -171,3 +170,101 @@ func MainTest(m *testing.M) {
}
os.Exit(exitStatus)
}
+
+func newXORMEngine() (*xorm.Engine, error) {
+ if err := db.InitEngine(context.Background()); err != nil {
+ return nil, err
+ }
+ x := unittest.GetXORMEngine()
+ return x, nil
+}
+
+func deleteDB() error {
+ switch {
+ case setting.Database.Type.IsSQLite3():
+ if err := util.Remove(setting.Database.Path); err != nil {
+ return err
+ }
+ return os.MkdirAll(path.Dir(setting.Database.Path), os.ModePerm)
+
+ case setting.Database.Type.IsMySQL():
+ db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s)/",
+ setting.Database.User, setting.Database.Passwd, setting.Database.Host))
+ if err != nil {
+ return err
+ }
+ defer db.Close()
+
+ databaseName := strings.SplitN(setting.Database.Name, "?", 2)[0]
+
+ if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", databaseName)); err != nil {
+ return err
+ }
+
+ if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", databaseName)); err != nil {
+ return err
+ }
+ return nil
+ case setting.Database.Type.IsPostgreSQL():
+ db, err := sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/?sslmode=%s",
+ setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.SSLMode))
+ if err != nil {
+ return err
+ }
+ defer db.Close()
+
+ if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil {
+ return err
+ }
+
+ if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", setting.Database.Name)); err != nil {
+ return err
+ }
+ db.Close()
+
+ // Check if we need to setup a specific schema
+ if len(setting.Database.Schema) != 0 {
+ db, err = sql.Open("postgres", fmt.Sprintf("postgres://%s:%s@%s/%s?sslmode=%s",
+ setting.Database.User, setting.Database.Passwd, setting.Database.Host, setting.Database.Name, setting.Database.SSLMode))
+ if err != nil {
+ return err
+ }
+ defer db.Close()
+
+ schrows, err := db.Query(fmt.Sprintf("SELECT 1 FROM information_schema.schemata WHERE schema_name = '%s'", setting.Database.Schema))
+ if err != nil {
+ return err
+ }
+ defer schrows.Close()
+
+ if !schrows.Next() {
+ // Create and setup a DB schema
+ _, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s", setting.Database.Schema))
+ if err != nil {
+ return err
+ }
+ }
+
+ // Make the user's default search path the created schema; this will affect new connections
+ _, err = db.Exec(fmt.Sprintf(`ALTER USER "%s" SET search_path = %s`, setting.Database.User, setting.Database.Schema))
+ if err != nil {
+ return err
+ }
+ return nil
+ }
+ }
+
+ return nil
+}
+
+func removeAllWithRetry(dir string) error {
+ var err error
+ for i := 0; i < 20; i++ {
+ err = os.RemoveAll(dir)
+ if err == nil {
+ break
+ }
+ time.Sleep(100 * time.Millisecond)
+ }
+ return err
+}
diff --git a/models/migrations/v1_10/v96.go b/models/migrations/v1_10/v96.go
index 34c8240031..3bfb770f24 100644
--- a/models/migrations/v1_10/v96.go
+++ b/models/migrations/v1_10/v96.go
@@ -6,8 +6,8 @@ package v1_10 //nolint
import (
"path/filepath"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_10/v99.go b/models/migrations/v1_10/v99.go
index ebe6597f7c..7f287b77aa 100644
--- a/models/migrations/v1_10/v99.go
+++ b/models/migrations/v1_10/v99.go
@@ -4,7 +4,7 @@
package v1_10 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_11/v102.go b/models/migrations/v1_11/v102.go
index 9358e4cef3..a585d9c423 100644
--- a/models/migrations/v1_11/v102.go
+++ b/models/migrations/v1_11/v102.go
@@ -4,7 +4,7 @@
package v1_11 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_11/v104.go b/models/migrations/v1_11/v104.go
index 3e8ee64bc1..af3578ca4a 100644
--- a/models/migrations/v1_11/v104.go
+++ b/models/migrations/v1_11/v104.go
@@ -4,7 +4,7 @@
package v1_11 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_11/v112.go b/models/migrations/v1_11/v112.go
index 0857663119..6112ab51a5 100644
--- a/models/migrations/v1_11/v112.go
+++ b/models/migrations/v1_11/v112.go
@@ -7,8 +7,8 @@ import (
"fmt"
"path/filepath"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"xorm.io/builder"
"xorm.io/xorm"
diff --git a/models/migrations/v1_11/v115.go b/models/migrations/v1_11/v115.go
index 8c631cfd0b..3d4b41017b 100644
--- a/models/migrations/v1_11/v115.go
+++ b/models/migrations/v1_11/v115.go
@@ -12,10 +12,10 @@ import (
"path/filepath"
"time"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_12/v127.go b/models/migrations/v1_12/v127.go
index 00e391dc87..11a4042973 100644
--- a/models/migrations/v1_12/v127.go
+++ b/models/migrations/v1_12/v127.go
@@ -6,7 +6,7 @@ package v1_12 //nolint
import (
"fmt"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_12/v128.go b/models/migrations/v1_12/v128.go
index 6eea1337ef..6d7307f470 100644
--- a/models/migrations/v1_12/v128.go
+++ b/models/migrations/v1_12/v128.go
@@ -10,9 +10,9 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_12/v130.go b/models/migrations/v1_12/v130.go
index 391810c7ca..bfa856796a 100644
--- a/models/migrations/v1_12/v130.go
+++ b/models/migrations/v1_12/v130.go
@@ -4,8 +4,8 @@
package v1_12 //nolint
import (
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_12/v134.go b/models/migrations/v1_12/v134.go
index 23c2916ba8..bba996fd40 100644
--- a/models/migrations/v1_12/v134.go
+++ b/models/migrations/v1_12/v134.go
@@ -10,9 +10,9 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_12/v136.go b/models/migrations/v1_12/v136.go
index d91ff92feb..db6fc6dea1 100644
--- a/models/migrations/v1_12/v136.go
+++ b/models/migrations/v1_12/v136.go
@@ -10,10 +10,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_12/v139.go b/models/migrations/v1_12/v139.go
index 5b6576951d..cd7963524e 100644
--- a/models/migrations/v1_12/v139.go
+++ b/models/migrations/v1_12/v139.go
@@ -4,7 +4,7 @@
package v1_12 //nolint
import (
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_13/v140.go b/models/migrations/v1_13/v140.go
index 2d3337012d..d74f808e9f 100644
--- a/models/migrations/v1_13/v140.go
+++ b/models/migrations/v1_13/v140.go
@@ -6,8 +6,8 @@ package v1_13 //nolint
import (
"fmt"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_13/v142.go b/models/migrations/v1_13/v142.go
index 7c7c01ad47..7490e0f3b4 100644
--- a/models/migrations/v1_13/v142.go
+++ b/models/migrations/v1_13/v142.go
@@ -4,7 +4,7 @@
package v1_13 //nolint
import (
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"xorm.io/builder"
"xorm.io/xorm"
diff --git a/models/migrations/v1_13/v143.go b/models/migrations/v1_13/v143.go
index 885768dff3..1f9120e2ba 100644
--- a/models/migrations/v1_13/v143.go
+++ b/models/migrations/v1_13/v143.go
@@ -4,7 +4,7 @@
package v1_13 //nolint
import (
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_13/v144.go b/models/migrations/v1_13/v144.go
index f5a0bc5751..7e801eab8a 100644
--- a/models/migrations/v1_13/v144.go
+++ b/models/migrations/v1_13/v144.go
@@ -4,7 +4,7 @@
package v1_13 //nolint
import (
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"xorm.io/builder"
"xorm.io/xorm"
diff --git a/models/migrations/v1_13/v145.go b/models/migrations/v1_13/v145.go
index 5b38f1cd80..a01f577ed1 100644
--- a/models/migrations/v1_13/v145.go
+++ b/models/migrations/v1_13/v145.go
@@ -6,7 +6,7 @@ package v1_13 //nolint
import (
"fmt"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_13/v146.go b/models/migrations/v1_13/v146.go
index 7d9a878704..a1b54ee3aa 100644
--- a/models/migrations/v1_13/v146.go
+++ b/models/migrations/v1_13/v146.go
@@ -4,7 +4,7 @@
package v1_13 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_13/v147.go b/models/migrations/v1_13/v147.go
index 510ef39b28..cc57504c74 100644
--- a/models/migrations/v1_13/v147.go
+++ b/models/migrations/v1_13/v147.go
@@ -4,7 +4,7 @@
package v1_13 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_13/v149.go b/models/migrations/v1_13/v149.go
index 2a1db04cbb..3a0c5909d5 100644
--- a/models/migrations/v1_13/v149.go
+++ b/models/migrations/v1_13/v149.go
@@ -6,7 +6,7 @@ package v1_13 //nolint
import (
"fmt"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_13/v150.go b/models/migrations/v1_13/v150.go
index d5ba489566..be14fd130c 100644
--- a/models/migrations/v1_13/v150.go
+++ b/models/migrations/v1_13/v150.go
@@ -4,8 +4,8 @@
package v1_13 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_13/v151.go b/models/migrations/v1_13/v151.go
index ea4a8eae31..60339962cb 100644
--- a/models/migrations/v1_13/v151.go
+++ b/models/migrations/v1_13/v151.go
@@ -8,8 +8,8 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
diff --git a/models/migrations/v1_13/v154.go b/models/migrations/v1_13/v154.go
index 60cc56713e..cf31190781 100644
--- a/models/migrations/v1_13/v154.go
+++ b/models/migrations/v1_13/v154.go
@@ -4,7 +4,7 @@
package v1_13 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_14/main_test.go b/models/migrations/v1_14/main_test.go
index 7a091b9b9a..c01faedc35 100644
--- a/models/migrations/v1_14/main_test.go
+++ b/models/migrations/v1_14/main_test.go
@@ -6,9 +6,9 @@ package v1_14 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_14/v156.go b/models/migrations/v1_14/v156.go
index 2cf4954a15..b6dc91a054 100644
--- a/models/migrations/v1_14/v156.go
+++ b/models/migrations/v1_14/v156.go
@@ -8,9 +8,9 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_14/v158.go b/models/migrations/v1_14/v158.go
index 2d688b1706..9849d5a9ea 100644
--- a/models/migrations/v1_14/v158.go
+++ b/models/migrations/v1_14/v158.go
@@ -7,8 +7,8 @@ import (
"fmt"
"strconv"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_14/v159.go b/models/migrations/v1_14/v159.go
index 149ae0f6a8..fdd7e12449 100644
--- a/models/migrations/v1_14/v159.go
+++ b/models/migrations/v1_14/v159.go
@@ -4,8 +4,8 @@
package v1_14 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_14/v161.go b/models/migrations/v1_14/v161.go
index ac7e821a80..6e904cfab6 100644
--- a/models/migrations/v1_14/v161.go
+++ b/models/migrations/v1_14/v161.go
@@ -6,7 +6,7 @@ package v1_14 //nolint
import (
"context"
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_14/v162.go b/models/migrations/v1_14/v162.go
index 2e4e0b8eb0..5d6d7c2e3f 100644
--- a/models/migrations/v1_14/v162.go
+++ b/models/migrations/v1_14/v162.go
@@ -4,7 +4,7 @@
package v1_14 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_14/v163.go b/models/migrations/v1_14/v163.go
index 0cd8ba68c8..60fc98c0a4 100644
--- a/models/migrations/v1_14/v163.go
+++ b/models/migrations/v1_14/v163.go
@@ -4,7 +4,7 @@
package v1_14 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_14/v165.go b/models/migrations/v1_14/v165.go
index 5b1a779294..9315e44197 100644
--- a/models/migrations/v1_14/v165.go
+++ b/models/migrations/v1_14/v165.go
@@ -4,7 +4,7 @@
package v1_14 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
diff --git a/models/migrations/v1_14/v172.go b/models/migrations/v1_14/v172.go
index 0f9bef902a..d49b70f5ad 100644
--- a/models/migrations/v1_14/v172.go
+++ b/models/migrations/v1_14/v172.go
@@ -4,7 +4,7 @@
package v1_14 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_14/v175.go b/models/migrations/v1_14/v175.go
index 70d72b2600..3cda5772a0 100644
--- a/models/migrations/v1_14/v175.go
+++ b/models/migrations/v1_14/v175.go
@@ -7,8 +7,8 @@ import (
"fmt"
"regexp"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_14/v176_test.go b/models/migrations/v1_14/v176_test.go
index ea3e750d7f..d88ff207e7 100644
--- a/models/migrations/v1_14/v176_test.go
+++ b/models/migrations/v1_14/v176_test.go
@@ -6,7 +6,7 @@ package v1_14 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
)
@@ -47,7 +47,7 @@ func Test_RemoveInvalidLabels(t *testing.T) {
}
// load and prepare the test database
- x, deferable := base.PrepareTestEnv(t, 0, new(Comment), new(Issue), new(Repository), new(IssueLabel), new(Label))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(Comment), new(Issue), new(Repository), new(IssueLabel), new(Label))
if x == nil || t.Failed() {
defer deferable()
return
diff --git a/models/migrations/v1_14/v177_test.go b/models/migrations/v1_14/v177_test.go
index 5568a18fec..199a71186a 100644
--- a/models/migrations/v1_14/v177_test.go
+++ b/models/migrations/v1_14/v177_test.go
@@ -6,10 +6,11 @@ package v1_14 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/timeutil"
+ migration_tests "forgejo.org/models/migrations/test"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_DeleteOrphanedIssueLabels(t *testing.T) {
@@ -34,7 +35,7 @@ func Test_DeleteOrphanedIssueLabels(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(IssueLabel), new(Label))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(IssueLabel), new(Label))
if x == nil || t.Failed() {
defer deferable()
return
@@ -47,7 +48,7 @@ func Test_DeleteOrphanedIssueLabels(t *testing.T) {
// Load issue labels that exist in the database pre-migration
if err := x.Find(&issueLabels); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
for _, issueLabel := range issueLabels {
@@ -56,14 +57,14 @@ func Test_DeleteOrphanedIssueLabels(t *testing.T) {
// Run the migration
if err := DeleteOrphanedIssueLabels(x); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
// Load the remaining issue-labels
issueLabels = issueLabels[:0]
if err := x.Find(&issueLabels); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
for _, issueLabel := range issueLabels {
diff --git a/models/migrations/v1_15/main_test.go b/models/migrations/v1_15/main_test.go
index 366f19788e..6c04d3f5ee 100644
--- a/models/migrations/v1_15/main_test.go
+++ b/models/migrations/v1_15/main_test.go
@@ -6,9 +6,9 @@ package v1_15 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_15/v179.go b/models/migrations/v1_15/v179.go
index f6b142eb42..b990583303 100644
--- a/models/migrations/v1_15/v179.go
+++ b/models/migrations/v1_15/v179.go
@@ -4,7 +4,7 @@
package v1_15 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
diff --git a/models/migrations/v1_15/v180.go b/models/migrations/v1_15/v180.go
index c71e771861..02fbd57cdb 100644
--- a/models/migrations/v1_15/v180.go
+++ b/models/migrations/v1_15/v180.go
@@ -4,8 +4,8 @@
package v1_15 //nolint
import (
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/util"
"xorm.io/builder"
"xorm.io/xorm"
diff --git a/models/migrations/v1_15/v181_test.go b/models/migrations/v1_15/v181_test.go
index 1b075be7a0..4544ca6520 100644
--- a/models/migrations/v1_15/v181_test.go
+++ b/models/migrations/v1_15/v181_test.go
@@ -7,9 +7,10 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_AddPrimaryEmail2EmailAddress(t *testing.T) {
@@ -20,7 +21,7 @@ func Test_AddPrimaryEmail2EmailAddress(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(User))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(User))
if x == nil || t.Failed() {
defer deferable()
return
@@ -28,7 +29,7 @@ func Test_AddPrimaryEmail2EmailAddress(t *testing.T) {
defer deferable()
err := AddPrimaryEmail2EmailAddress(x)
- assert.NoError(t, err)
+ require.NoError(t, err)
type EmailAddress struct {
ID int64 `xorm:"pk autoincr"`
@@ -41,12 +42,12 @@ func Test_AddPrimaryEmail2EmailAddress(t *testing.T) {
users := make([]User, 0, 20)
err = x.Find(&users)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, user := range users {
var emailAddress EmailAddress
has, err := x.Where("lower_email=?", strings.ToLower(user.Email)).Get(&emailAddress)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
assert.True(t, emailAddress.IsPrimary)
assert.EqualValues(t, user.IsActive, emailAddress.IsActivated)
diff --git a/models/migrations/v1_15/v182_test.go b/models/migrations/v1_15/v182_test.go
index 75ef8e1cd8..6865cafac4 100644
--- a/models/migrations/v1_15/v182_test.go
+++ b/models/migrations/v1_15/v182_test.go
@@ -6,9 +6,10 @@ package v1_15 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_AddIssueResourceIndexTable(t *testing.T) {
@@ -20,7 +21,7 @@ func Test_AddIssueResourceIndexTable(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(Issue))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(Issue))
if x == nil || t.Failed() {
defer deferable()
return
@@ -29,7 +30,7 @@ func Test_AddIssueResourceIndexTable(t *testing.T) {
// Run the migration
if err := AddIssueResourceIndexTable(x); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
@@ -43,12 +44,12 @@ func Test_AddIssueResourceIndexTable(t *testing.T) {
for {
indexes := make([]ResourceIndex, 0, batchSize)
err := x.Table("issue_index").Limit(batchSize, start).Find(&indexes)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, idx := range indexes {
var maxIndex int
has, err := x.SQL("SELECT max(`index`) FROM issue WHERE repo_id = ?", idx.GroupID).Get(&maxIndex)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
assert.EqualValues(t, maxIndex, idx.MaxIndex)
}
diff --git a/models/migrations/v1_15/v183.go b/models/migrations/v1_15/v183.go
index effad1b467..aaad64c220 100644
--- a/models/migrations/v1_15/v183.go
+++ b/models/migrations/v1_15/v183.go
@@ -7,7 +7,7 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_15/v184.go b/models/migrations/v1_15/v184.go
index 871c9db18a..41b64d4743 100644
--- a/models/migrations/v1_15/v184.go
+++ b/models/migrations/v1_15/v184.go
@@ -7,8 +7,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_15/v186.go b/models/migrations/v1_15/v186.go
index 01aab3add5..ad75822de5 100644
--- a/models/migrations/v1_15/v186.go
+++ b/models/migrations/v1_15/v186.go
@@ -4,7 +4,7 @@
package v1_15 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_15/v187.go b/models/migrations/v1_15/v187.go
index 21cd6772b7..b573fc52ef 100644
--- a/models/migrations/v1_15/v187.go
+++ b/models/migrations/v1_15/v187.go
@@ -4,7 +4,7 @@
package v1_15 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_16/main_test.go b/models/migrations/v1_16/main_test.go
index 817a0c13a4..6f891f3e94 100644
--- a/models/migrations/v1_16/main_test.go
+++ b/models/migrations/v1_16/main_test.go
@@ -6,9 +6,9 @@ package v1_16 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_16/v189.go b/models/migrations/v1_16/v189.go
index afd93b0eac..1ee72d9c39 100644
--- a/models/migrations/v1_16/v189.go
+++ b/models/migrations/v1_16/v189.go
@@ -7,8 +7,8 @@ import (
"encoding/binary"
"fmt"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/json"
"xorm.io/xorm"
)
@@ -83,7 +83,7 @@ func UnwrapLDAPSourceCfg(x *xorm.Engine) error {
if err != nil {
return fmt.Errorf("failed to unmarshal %s: %w", source.Cfg, err)
}
- if wrapped.Source != nil && len(wrapped.Source) > 0 {
+ if len(wrapped.Source) > 0 {
bs, err := json.Marshal(wrapped.Source)
if err != nil {
return err
diff --git a/models/migrations/v1_16/v189_test.go b/models/migrations/v1_16/v189_test.go
index 32ef821d27..e72c385168 100644
--- a/models/migrations/v1_16/v189_test.go
+++ b/models/migrations/v1_16/v189_test.go
@@ -6,10 +6,11 @@ package v1_16 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/json"
+ migration_tests "forgejo.org/models/migrations/test"
+ "forgejo.org/modules/json"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
// LoginSource represents an external way for authorizing users.
@@ -27,7 +28,7 @@ func (ls *LoginSourceOriginalV189) TableName() string {
func Test_UnwrapLDAPSourceCfg(t *testing.T) {
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(LoginSourceOriginalV189))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(LoginSourceOriginalV189))
if x == nil || t.Failed() {
defer deferable()
return
@@ -45,7 +46,7 @@ func Test_UnwrapLDAPSourceCfg(t *testing.T) {
// Run the migration
if err := UnwrapLDAPSourceCfg(x); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
@@ -53,7 +54,7 @@ func Test_UnwrapLDAPSourceCfg(t *testing.T) {
for start := 0; ; start += batchSize {
sources := make([]*LoginSource, 0, batchSize)
if err := x.Table("login_source").Limit(batchSize, start).Find(&sources); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
@@ -66,12 +67,12 @@ func Test_UnwrapLDAPSourceCfg(t *testing.T) {
expected := map[string]any{}
if err := json.Unmarshal([]byte(source.Cfg), &converted); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
if err := json.Unmarshal([]byte(source.Expected), &expected); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
diff --git a/models/migrations/v1_16/v191.go b/models/migrations/v1_16/v191.go
index c618783c08..567f88d6d1 100644
--- a/models/migrations/v1_16/v191.go
+++ b/models/migrations/v1_16/v191.go
@@ -4,7 +4,7 @@
package v1_16 //nolint
import (
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_16/v192.go b/models/migrations/v1_16/v192.go
index 2d5d158a09..731b9fb43a 100644
--- a/models/migrations/v1_16/v192.go
+++ b/models/migrations/v1_16/v192.go
@@ -4,7 +4,7 @@
package v1_16 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_16/v193_test.go b/models/migrations/v1_16/v193_test.go
index d99bbc2962..ab39bcd98c 100644
--- a/models/migrations/v1_16/v193_test.go
+++ b/models/migrations/v1_16/v193_test.go
@@ -6,9 +6,10 @@ package v1_16 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_AddRepoIDForAttachment(t *testing.T) {
@@ -31,7 +32,7 @@ func Test_AddRepoIDForAttachment(t *testing.T) {
}
// Prepare and load the testing database
- x, deferrable := base.PrepareTestEnv(t, 0, new(Attachment), new(Issue), new(Release))
+ x, deferrable := migration_tests.PrepareTestEnv(t, 0, new(Attachment), new(Issue), new(Release))
defer deferrable()
if x == nil || t.Failed() {
return
@@ -39,7 +40,7 @@ func Test_AddRepoIDForAttachment(t *testing.T) {
// Run the migration
if err := AddRepoIDForAttachment(x); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
@@ -54,26 +55,26 @@ func Test_AddRepoIDForAttachment(t *testing.T) {
var issueAttachments []*NewAttachment
err := x.Table("attachment").Where("issue_id > 0").Find(&issueAttachments)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, attach := range issueAttachments {
- assert.Greater(t, attach.RepoID, int64(0))
- assert.Greater(t, attach.IssueID, int64(0))
+ assert.Positive(t, attach.RepoID)
+ assert.Positive(t, attach.IssueID)
var issue Issue
has, err := x.ID(attach.IssueID).Get(&issue)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
assert.EqualValues(t, attach.RepoID, issue.RepoID)
}
var releaseAttachments []*NewAttachment
err = x.Table("attachment").Where("release_id > 0").Find(&releaseAttachments)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, attach := range releaseAttachments {
- assert.Greater(t, attach.RepoID, int64(0))
- assert.Greater(t, attach.ReleaseID, int64(0))
+ assert.Positive(t, attach.RepoID)
+ assert.Positive(t, attach.ReleaseID)
var release Release
has, err := x.ID(attach.ReleaseID).Get(&release)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
assert.EqualValues(t, attach.RepoID, release.RepoID)
}
diff --git a/models/migrations/v1_16/v195_test.go b/models/migrations/v1_16/v195_test.go
index 742397bf32..71234a6fb3 100644
--- a/models/migrations/v1_16/v195_test.go
+++ b/models/migrations/v1_16/v195_test.go
@@ -6,9 +6,10 @@ package v1_16 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_AddTableCommitStatusIndex(t *testing.T) {
@@ -21,7 +22,7 @@ func Test_AddTableCommitStatusIndex(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(CommitStatus))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(CommitStatus))
if x == nil || t.Failed() {
defer deferable()
return
@@ -30,7 +31,7 @@ func Test_AddTableCommitStatusIndex(t *testing.T) {
// Run the migration
if err := AddTableCommitStatusIndex(x); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
@@ -46,12 +47,12 @@ func Test_AddTableCommitStatusIndex(t *testing.T) {
for {
indexes := make([]CommitStatusIndex, 0, batchSize)
err := x.Table("commit_status_index").Limit(batchSize, start).Find(&indexes)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, idx := range indexes {
var maxIndex int
has, err := x.SQL("SELECT max(`index`) FROM commit_status WHERE repo_id = ? AND sha = ?", idx.RepoID, idx.SHA).Get(&maxIndex)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
assert.EqualValues(t, maxIndex, idx.MaxIndex)
}
diff --git a/models/migrations/v1_16/v198.go b/models/migrations/v1_16/v198.go
index 115bb313a0..8b3c73addc 100644
--- a/models/migrations/v1_16/v198.go
+++ b/models/migrations/v1_16/v198.go
@@ -6,7 +6,7 @@ package v1_16 //nolint
import (
"fmt"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_16/v205.go b/models/migrations/v1_16/v205.go
index d6c577083c..a064b9830d 100644
--- a/models/migrations/v1_16/v205.go
+++ b/models/migrations/v1_16/v205.go
@@ -4,7 +4,7 @@
package v1_16 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
diff --git a/models/migrations/v1_16/v210.go b/models/migrations/v1_16/v210.go
index db45b11aed..375a008e18 100644
--- a/models/migrations/v1_16/v210.go
+++ b/models/migrations/v1_16/v210.go
@@ -10,7 +10,7 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
diff --git a/models/migrations/v1_16/v210_test.go b/models/migrations/v1_16/v210_test.go
index b39646545a..010cd8a770 100644
--- a/models/migrations/v1_16/v210_test.go
+++ b/models/migrations/v1_16/v210_test.go
@@ -7,10 +7,11 @@ import (
"encoding/hex"
"testing"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/timeutil"
+ migration_tests "forgejo.org/models/migrations/test"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/xorm/schemas"
)
@@ -20,9 +21,9 @@ func TestParseU2FRegistration(t *testing.T) {
const testRegRespHex = "0504b174bc49c7ca254b70d2e5c207cee9cf174820ebd77ea3c65508c26da51b657c1cc6b952f8621697936482da0a6d3d3826a59095daf6cd7c03e2e60385d2f6d9402a552dfdb7477ed65fd84133f86196010b2215b57da75d315b7b9e8fe2e3925a6019551bab61d16591659cbaf00b4950f7abfe6660e2e006f76868b772d70c253082013c3081e4a003020102020a47901280001155957352300a06082a8648ce3d0403023017311530130603550403130c476e756262792050696c6f74301e170d3132303831343138323933325a170d3133303831343138323933325a3031312f302d0603550403132650696c6f74476e756262792d302e342e312d34373930313238303030313135353935373335323059301306072a8648ce3d020106082a8648ce3d030107034200048d617e65c9508e64bcc5673ac82a6799da3c1446682c258c463fffdf58dfd2fa3e6c378b53d795c4a4dffb4199edd7862f23abaf0203b4b8911ba0569994e101300a06082a8648ce3d0403020347003044022060cdb6061e9c22262d1aac1d96d8c70829b2366531dda268832cb836bcd30dfa0220631b1459f09e6330055722c8d89b7f48883b9089b88d60d1d9795902b30410df304502201471899bcc3987e62e8202c9b39c33c19033f7340352dba80fcab017db9230e402210082677d673d891933ade6f617e5dbde2e247e70423fd5ad7804a6d3d3961ef871"
regResp, err := hex.DecodeString(testRegRespHex)
- assert.NoError(t, err)
+ require.NoError(t, err)
pubKey, keyHandle, err := parseU2FRegistration(regResp)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "04b174bc49c7ca254b70d2e5c207cee9cf174820ebd77ea3c65508c26da51b657c1cc6b952f8621697936482da0a6d3d3826a59095daf6cd7c03e2e60385d2f6d9", hex.EncodeToString(pubKey.Bytes()))
assert.Equal(t, "2a552dfdb7477ed65fd84133f86196010b2215b57da75d315b7b9e8fe2e3925a6019551bab61d16591659cbaf00b4950f7abfe6660e2e006f76868b772d70c25", hex.EncodeToString(keyHandle))
}
@@ -58,7 +59,7 @@ func Test_RemigrateU2FCredentials(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(WebauthnCredential), new(U2fRegistration), new(ExpectedWebauthnCredential))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(WebauthnCredential), new(U2fRegistration), new(ExpectedWebauthnCredential))
if x == nil || t.Failed() {
defer deferable()
return
@@ -71,19 +72,17 @@ func Test_RemigrateU2FCredentials(t *testing.T) {
// Run the migration
if err := RemigrateU2FCredentials(x); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
expected := []ExpectedWebauthnCredential{}
- if err := x.Table("expected_webauthn_credential").Asc("id").Find(&expected); !assert.NoError(t, err) {
- return
- }
+ err := x.Table("expected_webauthn_credential").Asc("id").Find(&expected)
+ require.NoError(t, err)
got := []ExpectedWebauthnCredential{}
- if err := x.Table("webauthn_credential").Select("id, credential_id").Asc("id").Find(&got); !assert.NoError(t, err) {
- return
- }
+ err = x.Table("webauthn_credential").Select("id, credential_id").Asc("id").Find(&got)
+ require.NoError(t, err)
assert.EqualValues(t, expected, got)
}
diff --git a/models/migrations/v1_17/main_test.go b/models/migrations/v1_17/main_test.go
index 79cb3fa078..0a8e05ab5f 100644
--- a/models/migrations/v1_17/main_test.go
+++ b/models/migrations/v1_17/main_test.go
@@ -6,9 +6,9 @@ package v1_17 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_17/v212.go b/models/migrations/v1_17/v212.go
index e3f9437121..2337adcc80 100644
--- a/models/migrations/v1_17/v212.go
+++ b/models/migrations/v1_17/v212.go
@@ -4,7 +4,7 @@
package v1_17 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_17/v215.go b/models/migrations/v1_17/v215.go
index b338f85417..5aae798562 100644
--- a/models/migrations/v1_17/v215.go
+++ b/models/migrations/v1_17/v215.go
@@ -4,8 +4,8 @@
package v1_17 //nolint
import (
- "code.gitea.io/gitea/models/pull"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/pull"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_17/v217.go b/models/migrations/v1_17/v217.go
index 3f970b68a5..5f096d4824 100644
--- a/models/migrations/v1_17/v217.go
+++ b/models/migrations/v1_17/v217.go
@@ -4,7 +4,7 @@
package v1_17 //nolint
import (
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_17/v218.go b/models/migrations/v1_17/v218.go
index 4c05a9b539..5e3dcd0841 100644
--- a/models/migrations/v1_17/v218.go
+++ b/models/migrations/v1_17/v218.go
@@ -4,8 +4,8 @@
package v1_17 //nolint
import (
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
diff --git a/models/migrations/v1_17/v219.go b/models/migrations/v1_17/v219.go
index d266029fd9..e90656090f 100644
--- a/models/migrations/v1_17/v219.go
+++ b/models/migrations/v1_17/v219.go
@@ -6,8 +6,8 @@ package v1_17 //nolint
import (
"time"
- "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/repo"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_17/v220.go b/models/migrations/v1_17/v220.go
index d4007163ab..61bbf19725 100644
--- a/models/migrations/v1_17/v220.go
+++ b/models/migrations/v1_17/v220.go
@@ -4,8 +4,8 @@
package v1_17 //nolint
import (
- packages_model "code.gitea.io/gitea/models/packages"
- container_module "code.gitea.io/gitea/modules/packages/container"
+ packages_model "forgejo.org/models/packages"
+ container_module "forgejo.org/modules/packages/container"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
diff --git a/models/migrations/v1_17/v221.go b/models/migrations/v1_17/v221.go
index 9e159388bd..84e9a238af 100644
--- a/models/migrations/v1_17/v221.go
+++ b/models/migrations/v1_17/v221.go
@@ -7,7 +7,7 @@ import (
"encoding/base32"
"fmt"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_17/v221_test.go b/models/migrations/v1_17/v221_test.go
index 9ca54142e2..02607d6b32 100644
--- a/models/migrations/v1_17/v221_test.go
+++ b/models/migrations/v1_17/v221_test.go
@@ -7,9 +7,10 @@ import (
"encoding/base32"
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_StoreWebauthnCredentialIDAsBytes(t *testing.T) {
@@ -38,26 +39,22 @@ func Test_StoreWebauthnCredentialIDAsBytes(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(WebauthnCredential), new(ExpectedWebauthnCredential))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(WebauthnCredential), new(ExpectedWebauthnCredential))
defer deferable()
if x == nil || t.Failed() {
return
}
- if err := StoreWebauthnCredentialIDAsBytes(x); err != nil {
- assert.NoError(t, err)
- return
- }
+ err := StoreWebauthnCredentialIDAsBytes(x)
+ require.NoError(t, err)
expected := []ExpectedWebauthnCredential{}
- if err := x.Table("expected_webauthn_credential").Asc("id").Find(&expected); !assert.NoError(t, err) {
- return
- }
+ err = x.Table("expected_webauthn_credential").Asc("id").Find(&expected)
+ require.NoError(t, err)
got := []ConvertedWebauthnCredential{}
- if err := x.Table("webauthn_credential").Select("id, credential_id_bytes").Asc("id").Find(&got); !assert.NoError(t, err) {
- return
- }
+ err = x.Table("webauthn_credential").Select("id, credential_id_bytes").Asc("id").Find(&got)
+ require.NoError(t, err)
for i, e := range expected {
credIDBytes, _ := base32.HexEncoding.DecodeString(e.CredentialID)
diff --git a/models/migrations/v1_17/v222.go b/models/migrations/v1_17/v222.go
index 2ffb94eb1c..c9a33f007d 100644
--- a/models/migrations/v1_17/v222.go
+++ b/models/migrations/v1_17/v222.go
@@ -7,8 +7,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_17/v223.go b/models/migrations/v1_17/v223.go
index 3592eb1be6..7d92dcf5ae 100644
--- a/models/migrations/v1_17/v223.go
+++ b/models/migrations/v1_17/v223.go
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_18/main_test.go b/models/migrations/v1_18/main_test.go
index f71a21d1fb..33f5c51222 100644
--- a/models/migrations/v1_18/main_test.go
+++ b/models/migrations/v1_18/main_test.go
@@ -6,9 +6,9 @@ package v1_18 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_18/v225.go b/models/migrations/v1_18/v225.go
index b0ac3777fc..86bcb1323d 100644
--- a/models/migrations/v1_18/v225.go
+++ b/models/migrations/v1_18/v225.go
@@ -4,7 +4,7 @@
package v1_18 //nolint
import (
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_18/v227.go b/models/migrations/v1_18/v227.go
index 5fe5dcd0c9..b6250fb76c 100644
--- a/models/migrations/v1_18/v227.go
+++ b/models/migrations/v1_18/v227.go
@@ -4,7 +4,7 @@
package v1_18 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_18/v228.go b/models/migrations/v1_18/v228.go
index 3e7a36de15..1161c8a4c9 100644
--- a/models/migrations/v1_18/v228.go
+++ b/models/migrations/v1_18/v228.go
@@ -4,7 +4,7 @@
package v1_18 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_18/v229.go b/models/migrations/v1_18/v229.go
index 10d9f35097..f96dde9840 100644
--- a/models/migrations/v1_18/v229.go
+++ b/models/migrations/v1_18/v229.go
@@ -6,7 +6,7 @@ package v1_18 //nolint
import (
"fmt"
- "code.gitea.io/gitea/models/issues"
+ "forgejo.org/models/issues"
"xorm.io/builder"
"xorm.io/xorm"
diff --git a/models/migrations/v1_18/v229_test.go b/models/migrations/v1_18/v229_test.go
index d489328c00..ac5e726a79 100644
--- a/models/migrations/v1_18/v229_test.go
+++ b/models/migrations/v1_18/v229_test.go
@@ -6,36 +6,35 @@ package v1_18 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/issues"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_UpdateOpenMilestoneCounts(t *testing.T) {
type ExpectedMilestone issues.Milestone
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(issues.Milestone), new(ExpectedMilestone), new(issues.Issue))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(issues.Milestone), new(ExpectedMilestone), new(issues.Issue))
defer deferable()
if x == nil || t.Failed() {
return
}
if err := UpdateOpenMilestoneCounts(x); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
expected := []ExpectedMilestone{}
- if err := x.Table("expected_milestone").Asc("id").Find(&expected); !assert.NoError(t, err) {
- return
- }
+ err := x.Table("expected_milestone").Asc("id").Find(&expected)
+ require.NoError(t, err)
got := []issues.Milestone{}
- if err := x.Table("milestone").Asc("id").Find(&got); !assert.NoError(t, err) {
- return
- }
+ err = x.Table("milestone").Asc("id").Find(&got)
+ require.NoError(t, err)
for i, e := range expected {
got := got[i]
diff --git a/models/migrations/v1_18/v230_test.go b/models/migrations/v1_18/v230_test.go
index 40db4c2ffe..7dd6675673 100644
--- a/models/migrations/v1_18/v230_test.go
+++ b/models/migrations/v1_18/v230_test.go
@@ -6,9 +6,10 @@ package v1_18 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_AddConfidentialClientColumnToOAuth2ApplicationTable(t *testing.T) {
@@ -18,14 +19,14 @@ func Test_AddConfidentialClientColumnToOAuth2ApplicationTable(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(oauth2Application))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(oauth2Application))
defer deferable()
if x == nil || t.Failed() {
return
}
if err := AddConfidentialClientColumnToOAuth2ApplicationTable(x); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
@@ -36,9 +37,8 @@ func Test_AddConfidentialClientColumnToOAuth2ApplicationTable(t *testing.T) {
}
got := []ExpectedOAuth2Application{}
- if err := x.Table("oauth2_application").Select("id, confidential_client").Find(&got); !assert.NoError(t, err) {
- return
- }
+ err := x.Table("oauth2_application").Select("id, confidential_client").Find(&got)
+ require.NoError(t, err)
assert.NotEmpty(t, got)
for _, e := range got {
diff --git a/models/migrations/v1_19/main_test.go b/models/migrations/v1_19/main_test.go
index 59f42af111..7c56926f4c 100644
--- a/models/migrations/v1_19/main_test.go
+++ b/models/migrations/v1_19/main_test.go
@@ -6,9 +6,9 @@ package v1_19 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_19/v232.go b/models/migrations/v1_19/v232.go
index 9caf587c1e..7fb4a5ac8d 100644
--- a/models/migrations/v1_19/v232.go
+++ b/models/migrations/v1_19/v232.go
@@ -4,7 +4,7 @@
package v1_19 //nolint
import (
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_19/v233.go b/models/migrations/v1_19/v233.go
index ba4cd8e20b..191afd4868 100644
--- a/models/migrations/v1_19/v233.go
+++ b/models/migrations/v1_19/v233.go
@@ -6,10 +6,10 @@ package v1_19 //nolint
import (
"fmt"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/secret"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/secret"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
"xorm.io/builder"
"xorm.io/xorm"
diff --git a/models/migrations/v1_19/v233_test.go b/models/migrations/v1_19/v233_test.go
index 32c10ab0f4..de025ca2b7 100644
--- a/models/migrations/v1_19/v233_test.go
+++ b/models/migrations/v1_19/v233_test.go
@@ -6,13 +6,14 @@ package v1_19 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/secret"
- "code.gitea.io/gitea/modules/setting"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ migration_tests "forgejo.org/models/migrations/test"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/secret"
+ "forgejo.org/modules/setting"
+ webhook_module "forgejo.org/modules/webhook"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_AddHeaderAuthorizationEncryptedColWebhook(t *testing.T) {
@@ -39,26 +40,24 @@ func Test_AddHeaderAuthorizationEncryptedColWebhook(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(Webhook), new(ExpectedWebhook), new(HookTask))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(Webhook), new(ExpectedWebhook), new(HookTask))
defer deferable()
if x == nil || t.Failed() {
return
}
if err := AddHeaderAuthorizationEncryptedColWebhook(x); err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
expected := []ExpectedWebhook{}
- if err := x.Table("expected_webhook").Asc("id").Find(&expected); !assert.NoError(t, err) {
- return
- }
+ err := x.Table("expected_webhook").Asc("id").Find(&expected)
+ require.NoError(t, err)
got := []Webhook{}
- if err := x.Table("webhook").Select("id, meta, header_authorization_encrypted").Asc("id").Find(&got); !assert.NoError(t, err) {
- return
- }
+ err = x.Table("webhook").Select("id, meta, header_authorization_encrypted").Asc("id").Find(&got)
+ require.NoError(t, err)
for i, e := range expected {
assert.Equal(t, e.Meta, got[i].Meta)
@@ -68,20 +67,20 @@ func Test_AddHeaderAuthorizationEncryptedColWebhook(t *testing.T) {
} else {
cipherhex := got[i].HeaderAuthorizationEncrypted
cleartext, err := secret.DecryptSecret(setting.SecretKey, cipherhex)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, e.HeaderAuthorization, cleartext)
}
}
// ensure that no hook_task has some remaining "access_token"
hookTasks := []HookTask{}
- if err := x.Table("hook_task").Select("id, payload_content").Asc("id").Find(&hookTasks); !assert.NoError(t, err) {
- return
- }
+ err = x.Table("hook_task").Select("id, payload_content").Asc("id").Find(&hookTasks)
+ require.NoError(t, err)
+
for _, h := range hookTasks {
var m map[string]any
err := json.Unmarshal([]byte(h.PayloadContent), &m)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Nil(t, m["access_token"])
}
}
diff --git a/models/migrations/v1_19/v234.go b/models/migrations/v1_19/v234.go
index 728a580807..c610a423dd 100644
--- a/models/migrations/v1_19/v234.go
+++ b/models/migrations/v1_19/v234.go
@@ -4,7 +4,7 @@
package v1_19 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_19/v236.go b/models/migrations/v1_19/v236.go
index f172a85b1f..fa01a6ab80 100644
--- a/models/migrations/v1_19/v236.go
+++ b/models/migrations/v1_19/v236.go
@@ -4,7 +4,7 @@
package v1_19 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_19/v238.go b/models/migrations/v1_19/v238.go
index 266e6cea58..7c912a8341 100644
--- a/models/migrations/v1_19/v238.go
+++ b/models/migrations/v1_19/v238.go
@@ -4,7 +4,7 @@
package v1_19 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_19/v240.go b/models/migrations/v1_19/v240.go
index 4505f86299..4ca5becede 100644
--- a/models/migrations/v1_19/v240.go
+++ b/models/migrations/v1_19/v240.go
@@ -4,8 +4,8 @@
package v1_19 //nolint
import (
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_19/v242.go b/models/migrations/v1_19/v242.go
index 4470835214..bbf227ef77 100644
--- a/models/migrations/v1_19/v242.go
+++ b/models/migrations/v1_19/v242.go
@@ -4,7 +4,7 @@
package v1_19 //nolint
import (
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/main_test.go b/models/migrations/v1_20/main_test.go
index 92a1a9f622..f870dca429 100644
--- a/models/migrations/v1_20/main_test.go
+++ b/models/migrations/v1_20/main_test.go
@@ -6,9 +6,9 @@ package v1_20 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_20/v245.go b/models/migrations/v1_20/v245.go
index b0d4c21502..7e6585388b 100644
--- a/models/migrations/v1_20/v245.go
+++ b/models/migrations/v1_20/v245.go
@@ -7,8 +7,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/v247.go b/models/migrations/v1_20/v247.go
index 59fc5c46b5..9ed810a623 100644
--- a/models/migrations/v1_20/v247.go
+++ b/models/migrations/v1_20/v247.go
@@ -4,7 +4,7 @@
package v1_20 //nolint
import (
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/v249.go b/models/migrations/v1_20/v249.go
index 02951a74d6..d2b096bf58 100644
--- a/models/migrations/v1_20/v249.go
+++ b/models/migrations/v1_20/v249.go
@@ -4,7 +4,7 @@
package v1_20 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
diff --git a/models/migrations/v1_20/v250.go b/models/migrations/v1_20/v250.go
index 86388ef0b8..cfcde2fc9b 100644
--- a/models/migrations/v1_20/v250.go
+++ b/models/migrations/v1_20/v250.go
@@ -6,7 +6,7 @@ package v1_20 //nolint
import (
"strings"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/v251.go b/models/migrations/v1_20/v251.go
index 7743248a3f..c8665ba7eb 100644
--- a/models/migrations/v1_20/v251.go
+++ b/models/migrations/v1_20/v251.go
@@ -4,7 +4,7 @@
package v1_20 //nolint
import (
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/v252.go b/models/migrations/v1_20/v252.go
index ab61cd9b8b..bb85c78309 100644
--- a/models/migrations/v1_20/v252.go
+++ b/models/migrations/v1_20/v252.go
@@ -4,7 +4,7 @@
package v1_20 //nolint
import (
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/v253.go b/models/migrations/v1_20/v253.go
index 96c494bd8d..5f4057e9d9 100644
--- a/models/migrations/v1_20/v253.go
+++ b/models/migrations/v1_20/v253.go
@@ -4,7 +4,7 @@
package v1_20 //nolint
import (
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/v255.go b/models/migrations/v1_20/v255.go
index 14b70f8f96..49b0ecf220 100644
--- a/models/migrations/v1_20/v255.go
+++ b/models/migrations/v1_20/v255.go
@@ -4,7 +4,7 @@
package v1_20 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/v257.go b/models/migrations/v1_20/v257.go
index 6c6ca4c748..70f229d73f 100644
--- a/models/migrations/v1_20/v257.go
+++ b/models/migrations/v1_20/v257.go
@@ -4,7 +4,7 @@
package v1_20 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/v259.go b/models/migrations/v1_20/v259.go
index 5b8ced4ad7..f10b94fa9c 100644
--- a/models/migrations/v1_20/v259.go
+++ b/models/migrations/v1_20/v259.go
@@ -7,7 +7,7 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_20/v259_test.go b/models/migrations/v1_20/v259_test.go
index 5bc9a71391..d67cc9dd81 100644
--- a/models/migrations/v1_20/v259_test.go
+++ b/models/migrations/v1_20/v259_test.go
@@ -8,9 +8,10 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
type testCase struct {
@@ -66,7 +67,7 @@ func Test_ConvertScopedAccessTokens(t *testing.T) {
})
}
- x, deferable := base.PrepareTestEnv(t, 0, new(AccessToken))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(AccessToken))
defer deferable()
if x == nil || t.Failed() {
t.Skip()
@@ -75,27 +76,27 @@ func Test_ConvertScopedAccessTokens(t *testing.T) {
// verify that no fixtures were loaded
count, err := x.Count(&AccessToken{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(0), count)
for _, tc := range tests {
_, err = x.Insert(&AccessToken{
Scope: string(tc.Old),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
}
// migrate the scopes
err = ConvertScopedAccessTokens(x)
- assert.NoError(t, err)
+ require.NoError(t, err)
// migrate the scopes again (migration should be idempotent)
err = ConvertScopedAccessTokens(x)
- assert.NoError(t, err)
+ require.NoError(t, err)
tokens := make([]AccessToken, 0)
err = x.Find(&tokens)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, len(tests), len(tokens))
// sort the tokens (insertion order by auto-incrementing primary key)
diff --git a/models/migrations/v1_21/main_test.go b/models/migrations/v1_21/main_test.go
index 9afdea1677..7104887afb 100644
--- a/models/migrations/v1_21/main_test.go
+++ b/models/migrations/v1_21/main_test.go
@@ -6,9 +6,9 @@ package v1_21 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_21/v260.go b/models/migrations/v1_21/v260.go
index 6ca52c5998..245f3011ab 100644
--- a/models/migrations/v1_21/v260.go
+++ b/models/migrations/v1_21/v260.go
@@ -4,7 +4,7 @@
package v1_21 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_21/v261.go b/models/migrations/v1_21/v261.go
index 4ec1160d0b..743bef152d 100644
--- a/models/migrations/v1_21/v261.go
+++ b/models/migrations/v1_21/v261.go
@@ -4,7 +4,7 @@
package v1_21 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_21/v264.go b/models/migrations/v1_21/v264.go
index e81a17ad6d..88eaf0d918 100644
--- a/models/migrations/v1_21/v264.go
+++ b/models/migrations/v1_21/v264.go
@@ -7,8 +7,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_21/v267.go b/models/migrations/v1_21/v267.go
index bc0e954bdc..f94696a22b 100644
--- a/models/migrations/v1_21/v267.go
+++ b/models/migrations/v1_21/v267.go
@@ -4,7 +4,7 @@
package v1_21 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_21/v271.go b/models/migrations/v1_21/v271.go
index 098f6499d5..f45c113c1f 100644
--- a/models/migrations/v1_21/v271.go
+++ b/models/migrations/v1_21/v271.go
@@ -3,7 +3,7 @@
package v1_21 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_21/v273.go b/models/migrations/v1_21/v273.go
index 61c79f4a76..1ec6ade566 100644
--- a/models/migrations/v1_21/v273.go
+++ b/models/migrations/v1_21/v273.go
@@ -3,7 +3,7 @@
package v1_21 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_21/v274.go b/models/migrations/v1_21/v274.go
index df5994f159..b74e5fed51 100644
--- a/models/migrations/v1_21/v274.go
+++ b/models/migrations/v1_21/v274.go
@@ -5,7 +5,7 @@ package v1_21 //nolint
import (
"time"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_21/v276.go b/models/migrations/v1_21/v276.go
index 67e950177d..0830c3bd92 100644
--- a/models/migrations/v1_21/v276.go
+++ b/models/migrations/v1_21/v276.go
@@ -4,8 +4,8 @@
package v1_21 //nolint
import (
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/setting"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_21/v279.go b/models/migrations/v1_21/v279.go
index 19647225c9..2abd1bbe84 100644
--- a/models/migrations/v1_21/v279.go
+++ b/models/migrations/v1_21/v279.go
@@ -12,5 +12,9 @@ func AddIndexToActionUserID(x *xorm.Engine) error {
UserID int64 `xorm:"INDEX"`
}
- return x.Sync(new(Action))
+ _, err := x.SyncWithOptions(xorm.SyncOptions{
+ IgnoreDropIndices: true,
+ IgnoreConstrains: true,
+ }, new(Action))
+ return err
}
diff --git a/models/migrations/v1_22/main_test.go b/models/migrations/v1_22/main_test.go
index efd8dbaa8c..dc991b78fe 100644
--- a/models/migrations/v1_22/main_test.go
+++ b/models/migrations/v1_22/main_test.go
@@ -6,9 +6,9 @@ package v1_22 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_22/v281.go b/models/migrations/v1_22/v281.go
index fc1866aa83..5271c786be 100644
--- a/models/migrations/v1_22/v281.go
+++ b/models/migrations/v1_22/v281.go
@@ -4,7 +4,7 @@
package v1_22 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_22/v283_test.go b/models/migrations/v1_22/v283_test.go
index e89a7cbfc2..d8e147a131 100644
--- a/models/migrations/v1_22/v283_test.go
+++ b/models/migrations/v1_22/v283_test.go
@@ -6,9 +6,9 @@ package v1_22 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_AddCombinedIndexToIssueUser(t *testing.T) {
@@ -21,8 +21,8 @@ func Test_AddCombinedIndexToIssueUser(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(IssueUser))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(IssueUser))
defer deferable()
- assert.NoError(t, AddCombinedIndexToIssueUser(x))
+ require.NoError(t, AddCombinedIndexToIssueUser(x))
}
diff --git a/models/migrations/v1_22/v284.go b/models/migrations/v1_22/v284.go
index 1a4c786964..2b95078980 100644
--- a/models/migrations/v1_22/v284.go
+++ b/models/migrations/v1_22/v284.go
@@ -10,5 +10,9 @@ func AddIgnoreStaleApprovalsColumnToProtectedBranchTable(x *xorm.Engine) error {
type ProtectedBranch struct {
IgnoreStaleApprovals bool `xorm:"NOT NULL DEFAULT false"`
}
- return x.Sync(new(ProtectedBranch))
+ _, err := x.SyncWithOptions(xorm.SyncOptions{
+ IgnoreIndices: true,
+ IgnoreConstrains: true,
+ }, new(ProtectedBranch))
+ return err
}
diff --git a/models/migrations/v1_22/v285.go b/models/migrations/v1_22/v285.go
index c0dacd40bc..a55cc17c04 100644
--- a/models/migrations/v1_22/v285.go
+++ b/models/migrations/v1_22/v285.go
@@ -14,5 +14,9 @@ func AddPreviousDurationToActionRun(x *xorm.Engine) error {
PreviousDuration time.Duration
}
- return x.Sync(&ActionRun{})
+ _, err := x.SyncWithOptions(xorm.SyncOptions{
+ IgnoreIndices: true,
+ IgnoreConstrains: true,
+ }, &ActionRun{})
+ return err
}
diff --git a/models/migrations/v1_22/v286.go b/models/migrations/v1_22/v286.go
index 6a5f45122a..d0489e7aeb 100644
--- a/models/migrations/v1_22/v286.go
+++ b/models/migrations/v1_22/v286.go
@@ -5,8 +5,8 @@ package v1_22 //nolint
import (
"fmt"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
@@ -54,7 +54,10 @@ func addObjectFormatNameToRepository(x *xorm.Engine) error {
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
}
- if err := x.Sync(new(Repository)); err != nil {
+ if _, err := x.SyncWithOptions(xorm.SyncOptions{
+ IgnoreIndices: true,
+ IgnoreConstrains: true,
+ }, new(Repository)); err != nil {
return err
}
diff --git a/models/migrations/v1_22/v286_test.go b/models/migrations/v1_22/v286_test.go
index a19c9396e2..e6f8d4096e 100644
--- a/models/migrations/v1_22/v286_test.go
+++ b/models/migrations/v1_22/v286_test.go
@@ -6,9 +6,10 @@ package v1_22 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/xorm"
)
@@ -64,7 +65,7 @@ func PrepareOldRepository(t *testing.T) (*xorm.Engine, func()) {
}
// Prepare and load the testing database
- return base.PrepareTestEnv(t, 0,
+ return migration_tests.PrepareTestEnv(t, 0,
new(Repository),
new(CommitStatus),
new(RepoArchiver),
@@ -81,7 +82,7 @@ func Test_RepositoryFormat(t *testing.T) {
x, deferable := PrepareOldRepository(t)
defer deferable()
- assert.NoError(t, AdjustDBForSha256(x))
+ require.NoError(t, AdjustDBForSha256(x))
type Repository struct {
ID int64 `xorm:"pk autoincr"`
@@ -92,27 +93,27 @@ func Test_RepositoryFormat(t *testing.T) {
// check we have some records to migrate
count, err := x.Count(new(Repository))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 4, count)
repo.ObjectFormatName = "sha256"
_, err = x.Insert(repo)
- assert.NoError(t, err)
+ require.NoError(t, err)
id := repo.ID
count, err = x.Count(new(Repository))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 5, count)
repo = new(Repository)
ok, err := x.ID(2).Get(repo)
- assert.NoError(t, err)
- assert.EqualValues(t, true, ok)
+ require.NoError(t, err)
+ assert.True(t, ok)
assert.EqualValues(t, "sha1", repo.ObjectFormatName)
repo = new(Repository)
ok, err = x.ID(id).Get(repo)
- assert.NoError(t, err)
- assert.EqualValues(t, true, ok)
+ require.NoError(t, err)
+ assert.True(t, ok)
assert.EqualValues(t, "sha256", repo.ObjectFormatName)
}
diff --git a/models/migrations/v1_22/v288.go b/models/migrations/v1_22/v288.go
index 7c93bfcc66..44e4991851 100644
--- a/models/migrations/v1_22/v288.go
+++ b/models/migrations/v1_22/v288.go
@@ -4,7 +4,7 @@
package v1_22 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_22/v289.go b/models/migrations/v1_22/v289.go
index e2dfc48715..b9941aadd9 100644
--- a/models/migrations/v1_22/v289.go
+++ b/models/migrations/v1_22/v289.go
@@ -10,7 +10,10 @@ func AddDefaultWikiBranch(x *xorm.Engine) error {
ID int64
DefaultWikiBranch string
}
- if err := x.Sync(&Repository{}); err != nil {
+ if _, err := x.SyncWithOptions(xorm.SyncOptions{
+ IgnoreIndices: true,
+ IgnoreConstrains: true,
+ }, &Repository{}); err != nil {
return err
}
_, err := x.Exec("UPDATE `repository` SET default_wiki_branch = 'master' WHERE (default_wiki_branch IS NULL) OR (default_wiki_branch = '')")
diff --git a/models/migrations/v1_22/v290.go b/models/migrations/v1_22/v290.go
index e9c471b3dd..594e417644 100644
--- a/models/migrations/v1_22/v290.go
+++ b/models/migrations/v1_22/v290.go
@@ -4,8 +4,8 @@
package v1_22 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ "forgejo.org/modules/timeutil"
+ webhook_module "forgejo.org/modules/webhook"
"xorm.io/xorm"
)
@@ -35,5 +35,12 @@ type HookTask struct {
func AddPayloadVersionToHookTaskTable(x *xorm.Engine) error {
// create missing column
- return x.Sync(new(HookTask))
+ if _, err := x.SyncWithOptions(xorm.SyncOptions{
+ IgnoreIndices: true,
+ IgnoreConstrains: true,
+ }, new(HookTask)); err != nil {
+ return err
+ }
+ _, err := x.Exec("UPDATE hook_task SET payload_version = 1 WHERE payload_version IS NULL")
+ return err
}
diff --git a/models/migrations/v1_22/v290_test.go b/models/migrations/v1_22/v290_test.go
index 24a1c0b0a5..569d77bc16 100644
--- a/models/migrations/v1_22/v290_test.go
+++ b/models/migrations/v1_22/v290_test.go
@@ -7,11 +7,12 @@ import (
"strconv"
"testing"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/timeutil"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ migration_tests "forgejo.org/models/migrations/test"
+ "forgejo.org/modules/timeutil"
+ webhook_module "forgejo.org/modules/webhook"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_AddPayloadVersionToHookTaskTable(t *testing.T) {
@@ -34,20 +35,20 @@ func Test_AddPayloadVersionToHookTaskTable(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(HookTask), new(HookTaskMigrated))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(HookTask), new(HookTaskMigrated))
defer deferable()
if x == nil || t.Failed() {
return
}
- assert.NoError(t, AddPayloadVersionToHookTaskTable(x))
+ require.NoError(t, AddPayloadVersionToHookTaskTable(x))
expected := []HookTaskMigrated{}
- assert.NoError(t, x.Table("hook_task_migrated").Asc("id").Find(&expected))
+ require.NoError(t, x.Table("hook_task_migrated").Asc("id").Find(&expected))
assert.Len(t, expected, 2)
got := []HookTaskMigrated{}
- assert.NoError(t, x.Table("hook_task").Asc("id").Find(&got))
+ require.NoError(t, x.Table("hook_task").Asc("id").Find(&got))
for i, expected := range expected {
expected, got := expected, got[i]
diff --git a/models/migrations/v1_22/v291.go b/models/migrations/v1_22/v291.go
index 0bfffe5d05..74726fae96 100644
--- a/models/migrations/v1_22/v291.go
+++ b/models/migrations/v1_22/v291.go
@@ -10,5 +10,9 @@ func AddCommentIDIndexofAttachment(x *xorm.Engine) error {
CommentID int64 `xorm:"INDEX"`
}
- return x.Sync(&Attachment{})
+ _, err := x.SyncWithOptions(xorm.SyncOptions{
+ IgnoreDropIndices: true,
+ IgnoreConstrains: true,
+ }, &Attachment{})
+ return err
}
diff --git a/models/migrations/v1_22/v293.go b/models/migrations/v1_22/v293.go
index 53cc719294..9f38c3db56 100644
--- a/models/migrations/v1_22/v293.go
+++ b/models/migrations/v1_22/v293.go
@@ -4,8 +4,8 @@
package v1_22 //nolint
import (
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_22/v293_test.go b/models/migrations/v1_22/v293_test.go
index cfe4345143..444146737d 100644
--- a/models/migrations/v1_22/v293_test.go
+++ b/models/migrations/v1_22/v293_test.go
@@ -6,39 +6,40 @@ package v1_22 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/models/project"
+ "forgejo.org/models/db"
+ migration_tests "forgejo.org/models/migrations/test"
+ "forgejo.org/models/project"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_CheckProjectColumnsConsistency(t *testing.T) {
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(project.Project), new(project.Column))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(project.Project), new(project.Column))
defer deferable()
if x == nil || t.Failed() {
return
}
- assert.NoError(t, CheckProjectColumnsConsistency(x))
+ require.NoError(t, CheckProjectColumnsConsistency(x))
// check if default column was added
var defaultColumn project.Column
has, err := x.Where("project_id=? AND `default` = ?", 1, true).Get(&defaultColumn)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
assert.Equal(t, int64(1), defaultColumn.ProjectID)
assert.True(t, defaultColumn.Default)
// check if multiple defaults, previous were removed and last will be kept
expectDefaultColumn, err := project.GetColumn(db.DefaultContext, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(2), expectDefaultColumn.ProjectID)
assert.False(t, expectDefaultColumn.Default)
expectNonDefaultColumn, err := project.GetColumn(db.DefaultContext, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(2), expectNonDefaultColumn.ProjectID)
assert.True(t, expectNonDefaultColumn.Default)
}
diff --git a/models/migrations/v1_22/v294_test.go b/models/migrations/v1_22/v294_test.go
index 82a3bcd602..ef7b67ca5b 100644
--- a/models/migrations/v1_22/v294_test.go
+++ b/models/migrations/v1_22/v294_test.go
@@ -7,9 +7,10 @@ import (
"slices"
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/xorm/schemas"
)
@@ -21,25 +22,25 @@ func Test_AddUniqueIndexForProjectIssue(t *testing.T) {
}
// Prepare and load the testing database
- x, deferable := base.PrepareTestEnv(t, 0, new(ProjectIssue))
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(ProjectIssue))
defer deferable()
if x == nil || t.Failed() {
return
}
cnt, err := x.Table("project_issue").Where("project_id=1 AND issue_id=1").Count()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 2, cnt)
- assert.NoError(t, AddUniqueIndexForProjectIssue(x))
+ require.NoError(t, AddUniqueIndexForProjectIssue(x))
cnt, err = x.Table("project_issue").Where("project_id=1 AND issue_id=1").Count()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, cnt)
tables, err := x.DBMetas()
- assert.NoError(t, err)
- assert.EqualValues(t, 1, len(tables))
+ require.NoError(t, err)
+ assert.Len(t, tables, 1)
found := false
for _, index := range tables[0].Indexes {
if index.Type == schemas.UniqueType {
diff --git a/models/migrations/v1_23/main_test.go b/models/migrations/v1_23/main_test.go
index b7948bd4dd..0fd90a4a67 100644
--- a/models/migrations/v1_23/main_test.go
+++ b/models/migrations/v1_23/main_test.go
@@ -6,9 +6,9 @@ package v1_23 //nolint
import (
"testing"
- "code.gitea.io/gitea/models/migrations/base"
+ migration_tests "forgejo.org/models/migrations/test"
)
func TestMain(m *testing.M) {
- base.MainTest(m)
+ migration_tests.MainTest(m)
}
diff --git a/models/migrations/v1_23/v300.go b/models/migrations/v1_23/v300.go
new file mode 100644
index 0000000000..f1f1cccdbf
--- /dev/null
+++ b/models/migrations/v1_23/v300.go
@@ -0,0 +1,17 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_23 //nolint
+
+import "xorm.io/xorm"
+
+func AddForcePushBranchProtection(x *xorm.Engine) error {
+ type ProtectedBranch struct {
+ CanForcePush bool `xorm:"NOT NULL DEFAULT false"`
+ EnableForcePushAllowlist bool `xorm:"NOT NULL DEFAULT false"`
+ ForcePushAllowlistUserIDs []int64 `xorm:"JSON TEXT"`
+ ForcePushAllowlistTeamIDs []int64 `xorm:"JSON TEXT"`
+ ForcePushAllowlistDeployKeys bool `xorm:"NOT NULL DEFAULT false"`
+ }
+ return x.Sync(new(ProtectedBranch))
+}
diff --git a/models/migrations/v1_23/v301.go b/models/migrations/v1_23/v301.go
new file mode 100644
index 0000000000..b7797f6c6b
--- /dev/null
+++ b/models/migrations/v1_23/v301.go
@@ -0,0 +1,14 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_23 //nolint
+
+import "xorm.io/xorm"
+
+// AddSkipSeconderyAuthToOAuth2ApplicationTable: add SkipSecondaryAuthorization column, setting existing rows to false
+func AddSkipSecondaryAuthColumnToOAuth2ApplicationTable(x *xorm.Engine) error {
+ type oauth2Application struct {
+ SkipSecondaryAuthorization bool `xorm:"NOT NULL DEFAULT FALSE"`
+ }
+ return x.Sync(new(oauth2Application))
+}
diff --git a/models/migrations/v1_23/v302.go b/models/migrations/v1_23/v302.go
new file mode 100644
index 0000000000..c8ed786d63
--- /dev/null
+++ b/models/migrations/v1_23/v302.go
@@ -0,0 +1,18 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_23 //nolint
+
+import (
+ "forgejo.org/modules/timeutil"
+
+ "xorm.io/xorm"
+)
+
+func AddIndexToActionTaskStoppedLogExpired(x *xorm.Engine) error {
+ type ActionTask struct {
+ Stopped timeutil.TimeStamp `xorm:"index(stopped_log_expired)"`
+ LogExpired bool `xorm:"index(stopped_log_expired)"`
+ }
+ return x.Sync(new(ActionTask))
+}
diff --git a/models/migrations/v1_23/v303.go b/models/migrations/v1_23/v303.go
new file mode 100644
index 0000000000..fae0131bdd
--- /dev/null
+++ b/models/migrations/v1_23/v303.go
@@ -0,0 +1,60 @@
+// Copyright 2025 The Forgejo Authors.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package v1_23 //nolint
+
+import (
+ "forgejo.org/models/migrations/base"
+
+ "xorm.io/xorm"
+ "xorm.io/xorm/schemas"
+)
+
+func GiteaLastDrop(x *xorm.Engine) error {
+ tables, err := x.DBMetas()
+ if err != nil {
+ return err
+ }
+
+ sess := x.NewSession()
+ defer sess.Close()
+
+ for _, drop := range []struct {
+ table string
+ column string
+ }{
+ {"badge", "slug"},
+ {"oauth2_application", "skip_secondary_authorization"},
+ {"repository", "default_wiki_branch"},
+ {"repo_unit", "everyone_access_mode"},
+ {"protected_branch", "can_force_push"},
+ {"protected_branch", "enable_force_push_allowlist"},
+ {"protected_branch", "force_push_allowlist_user_i_ds"},
+ {"protected_branch", "force_push_allowlist_team_i_ds"},
+ {"protected_branch", "force_push_allowlist_deploy_keys"},
+ } {
+ var table *schemas.Table
+ found := false
+
+ for _, table = range tables {
+ if table.Name == drop.table {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ continue
+ }
+
+ if table.GetColumn(drop.column) == nil {
+ continue
+ }
+
+ if err := base.DropTableColumns(sess, drop.table, drop.column); err != nil {
+ return err
+ }
+ }
+
+ return sess.Commit()
+}
diff --git a/models/migrations/v1_23/v303_test.go b/models/migrations/v1_23/v303_test.go
new file mode 100644
index 0000000000..f105d11830
--- /dev/null
+++ b/models/migrations/v1_23/v303_test.go
@@ -0,0 +1,41 @@
+// Copyright 2025 The Forgejo Authors.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package v1_23 //nolint
+
+import (
+ "testing"
+
+ migration_tests "forgejo.org/models/migrations/test"
+
+ "github.com/stretchr/testify/require"
+ "xorm.io/xorm/schemas"
+)
+
+func Test_GiteaLastDrop(t *testing.T) {
+ type Badge struct {
+ ID int64 `xorm:"pk autoincr"`
+ Slug string
+ }
+
+ x, deferable := migration_tests.PrepareTestEnv(t, 0, new(Badge))
+ defer deferable()
+ if x == nil || t.Failed() {
+ return
+ }
+
+ getColumn := func() *schemas.Column {
+ tables, err := x.DBMetas()
+ require.NoError(t, err)
+ require.Len(t, tables, 1)
+ table := tables[0]
+ require.Equal(t, "badge", table.Name)
+ return table.GetColumn("slug")
+ }
+
+ require.NotNil(t, getColumn(), "slug column exists")
+ require.NoError(t, GiteaLastDrop(x))
+ require.Nil(t, getColumn(), "slug column was deleted")
+ // idempotent
+ require.NoError(t, GiteaLastDrop(x))
+}
diff --git a/models/migrations/v1_6/v70.go b/models/migrations/v1_6/v70.go
index 74434a84a1..ec6bd09bb5 100644
--- a/models/migrations/v1_6/v70.go
+++ b/models/migrations/v1_6/v70.go
@@ -7,7 +7,7 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_6/v71.go b/models/migrations/v1_6/v71.go
index 586187228b..3706ad4406 100644
--- a/models/migrations/v1_6/v71.go
+++ b/models/migrations/v1_6/v71.go
@@ -6,9 +6,9 @@ package v1_6 //nolint
import (
"fmt"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_6/v72.go b/models/migrations/v1_6/v72.go
index 04cef9a170..4df2a0f6e9 100644
--- a/models/migrations/v1_6/v72.go
+++ b/models/migrations/v1_6/v72.go
@@ -6,7 +6,7 @@ package v1_6 //nolint
import (
"fmt"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_8/v76.go b/models/migrations/v1_8/v76.go
index d3fbd94deb..61ad006a47 100644
--- a/models/migrations/v1_8/v76.go
+++ b/models/migrations/v1_8/v76.go
@@ -6,7 +6,7 @@ package v1_8 //nolint
import (
"fmt"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_8/v78.go b/models/migrations/v1_8/v78.go
index 8f041c1484..8102b19335 100644
--- a/models/migrations/v1_8/v78.go
+++ b/models/migrations/v1_8/v78.go
@@ -4,7 +4,7 @@
package v1_8 //nolint
import (
- "code.gitea.io/gitea/models/migrations/base"
+ "forgejo.org/models/migrations/base"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_8/v79.go b/models/migrations/v1_8/v79.go
index eb3a9ed0f4..f7d2d68f96 100644
--- a/models/migrations/v1_8/v79.go
+++ b/models/migrations/v1_8/v79.go
@@ -4,7 +4,7 @@
package v1_8 //nolint
import (
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_9/v82.go b/models/migrations/v1_9/v82.go
index 26806dd645..78a90bdde9 100644
--- a/models/migrations/v1_9/v82.go
+++ b/models/migrations/v1_9/v82.go
@@ -8,8 +8,8 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_9/v83.go b/models/migrations/v1_9/v83.go
index 10e6c45875..fa24a92d28 100644
--- a/models/migrations/v1_9/v83.go
+++ b/models/migrations/v1_9/v83.go
@@ -4,7 +4,7 @@
package v1_9 //nolint
import (
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"xorm.io/xorm"
)
diff --git a/models/migrations/v1_9/v85.go b/models/migrations/v1_9/v85.go
index a23d7c5d6e..d8e9d91840 100644
--- a/models/migrations/v1_9/v85.go
+++ b/models/migrations/v1_9/v85.go
@@ -6,10 +6,10 @@ package v1_9 //nolint
import (
"fmt"
- "code.gitea.io/gitea/models/migrations/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/migrations/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/xorm"
)
diff --git a/models/org.go b/models/org.go
index 5f61f05b16..6e191acff0 100644
--- a/models/org.go
+++ b/models/org.go
@@ -8,10 +8,10 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
)
// RemoveOrgUser removes user from given organization.
diff --git a/models/org_team.go b/models/org_team.go
index 1a452436c3..ecda43f0a9 100644
--- a/models/org_team.go
+++ b/models/org_team.go
@@ -9,16 +9,16 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/org_team_test.go b/models/org_team_test.go
index e4b7b917e8..dc1fdb4b3b 100644
--- a/models/org_team_test.go
+++ b/models/org_team_test.go
@@ -7,23 +7,24 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestTeam_AddMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID, userID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
- assert.NoError(t, AddTeamMember(db.DefaultContext, team, userID))
+ require.NoError(t, AddTeamMember(db.DefaultContext, team, userID))
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID})
}
@@ -33,11 +34,11 @@ func TestTeam_AddMember(t *testing.T) {
}
func TestTeam_RemoveMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(teamID, userID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
- assert.NoError(t, RemoveTeamMember(db.DefaultContext, team, userID))
+ require.NoError(t, RemoveTeamMember(db.DefaultContext, team, userID))
unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID})
}
@@ -52,30 +53,30 @@ func TestTeam_RemoveMember(t *testing.T) {
}
func TestIsUsableTeamName(t *testing.T) {
- assert.NoError(t, organization.IsUsableTeamName("usable"))
+ require.NoError(t, organization.IsUsableTeamName("usable"))
assert.True(t, db.IsErrNameReserved(organization.IsUsableTeamName("new")))
}
func TestNewTeam(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
const teamName = "newTeamName"
team := &organization.Team{Name: teamName, OrgID: 3}
- assert.NoError(t, NewTeam(db.DefaultContext, team))
+ require.NoError(t, NewTeam(db.DefaultContext, team))
unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: teamName})
unittest.CheckConsistencyFor(t, &organization.Team{}, &user_model.User{ID: team.OrgID})
}
func TestUpdateTeam(t *testing.T) {
// successful update
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
team.LowerName = "newname"
team.Name = "newName"
team.Description = strings.Repeat("A long description!", 100)
team.AccessMode = perm.AccessModeAdmin
- assert.NoError(t, UpdateTeam(db.DefaultContext, team, true, false))
+ require.NoError(t, UpdateTeam(db.DefaultContext, team, true, false))
team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"})
assert.True(t, strings.HasPrefix(team.Description, "A long description!"))
@@ -88,7 +89,7 @@ func TestUpdateTeam(t *testing.T) {
func TestUpdateTeam2(t *testing.T) {
// update to already-existing team
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
team.LowerName = "owners"
@@ -101,10 +102,10 @@ func TestUpdateTeam2(t *testing.T) {
}
func TestDeleteTeam(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
- assert.NoError(t, DeleteTeam(db.DefaultContext, team))
+ require.NoError(t, DeleteTeam(db.DefaultContext, team))
unittest.AssertNotExistsBean(t, &organization.Team{ID: team.ID})
unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: team.ID})
unittest.AssertNotExistsBean(t, &organization.TeamUser{TeamID: team.ID})
@@ -113,16 +114,16 @@ func TestDeleteTeam(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
accessMode, err := access_model.AccessLevel(db.DefaultContext, user, repo)
- assert.NoError(t, err)
- assert.True(t, accessMode < perm.AccessModeWrite)
+ require.NoError(t, err)
+ assert.Less(t, accessMode, perm.AccessModeWrite)
}
func TestAddTeamMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID, userID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
- assert.NoError(t, AddTeamMember(db.DefaultContext, team, userID))
+ require.NoError(t, AddTeamMember(db.DefaultContext, team, userID))
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID})
}
@@ -132,11 +133,11 @@ func TestAddTeamMember(t *testing.T) {
}
func TestRemoveTeamMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(teamID, userID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
- assert.NoError(t, RemoveTeamMember(db.DefaultContext, team, userID))
+ require.NoError(t, RemoveTeamMember(db.DefaultContext, team, userID))
unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID})
}
@@ -151,19 +152,19 @@ func TestRemoveTeamMember(t *testing.T) {
}
func TestRepository_RecalculateAccesses3(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
team5 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5})
user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29})
has, err := db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 29, RepoID: 23})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, has)
// adding user29 to team5 should add an explicit access row for repo 23
// even though repo 23 is public
- assert.NoError(t, AddTeamMember(db.DefaultContext, team5, user29.ID))
+ require.NoError(t, AddTeamMember(db.DefaultContext, team5, user29.ID))
has, err = db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 29, RepoID: 23})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
}
diff --git a/models/org_test.go b/models/org_test.go
index d10a1dc218..45e21da0e0 100644
--- a/models/org_test.go
+++ b/models/org_test.go
@@ -6,22 +6,23 @@ package models
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestUser_RemoveMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
// remove a user that is a member
unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{UID: 4, OrgID: 3})
prevNumMembers := org.NumMembers
- assert.NoError(t, RemoveOrgUser(db.DefaultContext, org.ID, 4))
+ require.NoError(t, RemoveOrgUser(db.DefaultContext, org.ID, 4))
unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: 4, OrgID: 3})
org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
assert.Equal(t, prevNumMembers-1, org.NumMembers)
@@ -29,7 +30,7 @@ func TestUser_RemoveMember(t *testing.T) {
// remove a user that is not a member
unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: 5, OrgID: 3})
prevNumMembers = org.NumMembers
- assert.NoError(t, RemoveOrgUser(db.DefaultContext, org.ID, 5))
+ require.NoError(t, RemoveOrgUser(db.DefaultContext, org.ID, 5))
unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: 5, OrgID: 3})
org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
assert.Equal(t, prevNumMembers, org.NumMembers)
@@ -38,14 +39,14 @@ func TestUser_RemoveMember(t *testing.T) {
}
func TestRemoveOrgUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(orgID, userID int64) {
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID})
expectedNumMembers := org.NumMembers
if unittest.BeanExists(t, &organization.OrgUser{OrgID: orgID, UID: userID}) {
expectedNumMembers--
}
- assert.NoError(t, RemoveOrgUser(db.DefaultContext, orgID, userID))
+ require.NoError(t, RemoveOrgUser(db.DefaultContext, orgID, userID))
unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: orgID, UID: userID})
org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID})
assert.EqualValues(t, expectedNumMembers, org.NumMembers)
@@ -54,7 +55,7 @@ func TestRemoveOrgUser(t *testing.T) {
testSuccess(3, 4)
err := RemoveOrgUser(db.DefaultContext, 7, 5)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, organization.IsErrLastOrgOwner(err))
unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{OrgID: 7, UID: 5})
unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{})
diff --git a/models/organization/TestFindOrgs/org_user.yml b/models/organization/TestFindOrgs/org_user.yml
new file mode 100644
index 0000000000..79b6fc613e
--- /dev/null
+++ b/models/organization/TestFindOrgs/org_user.yml
@@ -0,0 +1,5 @@
+-
+ id: 1000
+ uid: 4
+ org_id: 22
+ is_public: true
diff --git a/models/organization/TestInconsistentOwnerTeam/team.yml b/models/organization/TestInconsistentOwnerTeam/team.yml
new file mode 100644
index 0000000000..90e3ad43b0
--- /dev/null
+++ b/models/organization/TestInconsistentOwnerTeam/team.yml
@@ -0,0 +1,10 @@
+-
+ id: 1000
+ org_id: 1000
+ lower_name: owners
+ name: Owners
+ authorize: 4 # owner
+ num_repos: 0
+ num_members: 0
+ includes_all_repositories: true
+ can_create_org_repo: true
diff --git a/models/organization/TestInconsistentOwnerTeam/team_unit.yml b/models/organization/TestInconsistentOwnerTeam/team_unit.yml
new file mode 100644
index 0000000000..91e03d6a9a
--- /dev/null
+++ b/models/organization/TestInconsistentOwnerTeam/team_unit.yml
@@ -0,0 +1,59 @@
+-
+ id: 1000
+ team_id: 1000
+ type: 1
+ access_mode: 0 # None
+
+-
+ id: 1001
+ team_id: 1000
+ type: 2
+ access_mode: 0
+
+-
+ id: 1002
+ team_id: 1000
+ type: 3
+ access_mode: 0
+
+-
+ id: 1003
+ team_id: 1000
+ type: 4
+ access_mode: 0
+
+-
+ id: 1004
+ team_id: 1000
+ type: 5
+ access_mode: 0
+
+-
+ id: 1005
+ team_id: 1000
+ type: 6
+ access_mode: 0
+
+-
+ id: 1006
+ team_id: 1000
+ type: 7
+ access_mode: 0
+
+-
+ id: 1007
+ team_id: 1000
+ type: 8
+ access_mode: 0
+
+-
+ id: 1008
+ team_id: 1000
+ type: 9
+ access_mode: 0
+
+-
+ id: 1009
+ team_id: 1000
+ type: 10
+ access_mode: 0
diff --git a/models/organization/main_test.go b/models/organization/main_test.go
index c35898a465..dd10b60d30 100644
--- a/models/organization/main_test.go
+++ b/models/organization/main_test.go
@@ -6,14 +6,15 @@ package organization_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
- _ "code.gitea.io/gitea/models/organization"
- _ "code.gitea.io/gitea/models/repo"
- _ "code.gitea.io/gitea/models/user"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
+ _ "forgejo.org/models/organization"
+ _ "forgejo.org/models/repo"
+ _ "forgejo.org/models/user"
)
func TestMain(m *testing.M) {
diff --git a/models/organization/mini_org.go b/models/organization/mini_org.go
deleted file mode 100644
index b1b24624c5..0000000000
--- a/models/organization/mini_org.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package organization
-
-import (
- "context"
- "fmt"
- "strings"
-
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
-
- "xorm.io/builder"
-)
-
-// MinimalOrg represents a simple organization with only the needed columns
-type MinimalOrg = Organization
-
-// GetUserOrgsList returns all organizations the given user has access to
-func GetUserOrgsList(ctx context.Context, user *user_model.User) ([]*MinimalOrg, error) {
- schema, err := db.TableInfo(new(user_model.User))
- if err != nil {
- return nil, err
- }
-
- outputCols := []string{
- "id",
- "name",
- "full_name",
- "visibility",
- "avatar",
- "avatar_email",
- "use_custom_avatar",
- }
-
- groupByCols := &strings.Builder{}
- for _, col := range outputCols {
- fmt.Fprintf(groupByCols, "`%s`.%s,", schema.Name, col)
- }
- groupByStr := groupByCols.String()
- groupByStr = groupByStr[0 : len(groupByStr)-1]
-
- sess := db.GetEngine(ctx)
- sess = sess.Select(groupByStr+", count(distinct repo_id) as org_count").
- Table("user").
- Join("INNER", "team", "`team`.org_id = `user`.id").
- Join("INNER", "team_user", "`team`.id = `team_user`.team_id").
- Join("LEFT", builder.
- Select("id as repo_id, owner_id as repo_owner_id").
- From("repository").
- Where(repo_model.AccessibleRepositoryCondition(user, unit.TypeInvalid)), "`repository`.repo_owner_id = `team`.org_id").
- Where("`team_user`.uid = ?", user.ID).
- GroupBy(groupByStr)
-
- type OrgCount struct {
- Organization `xorm:"extends"`
- OrgCount int
- }
-
- orgCounts := make([]*OrgCount, 0, 10)
-
- if err := sess.
- Asc("`user`.name").
- Find(&orgCounts); err != nil {
- return nil, err
- }
-
- orgs := make([]*MinimalOrg, len(orgCounts))
- for i, orgCount := range orgCounts {
- orgCount.Organization.NumRepos = orgCount.OrgCount
- orgs[i] = &orgCount.Organization
- }
-
- return orgs, nil
-}
diff --git a/models/organization/org.go b/models/organization/org.go
index 45f19c7696..1339f7415d 100644
--- a/models/organization/org.go
+++ b/models/organization/org.go
@@ -9,28 +9,21 @@ import (
"fmt"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- secret_model "code.gitea.io/gitea/models/secret"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ secret_model "forgejo.org/models/secret"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
-// ________ .__ __ .__
-// \_____ \_______ _________ ____ |__|____________ _/ |_|__| ____ ____
-// / | \_ __ \/ ___\__ \ / \| \___ /\__ \\ __\ |/ _ \ / \
-// / | \ | \/ /_/ > __ \| | \ |/ / / __ \| | | ( <_> ) | \
-// \_______ /__| \___ (____ /___| /__/_____ \(____ /__| |__|\____/|___| /
-// \/ /_____/ \/ \/ \/ \/ \/
-
// ErrOrgNotExist represents a "OrgNotExist" kind of error.
type ErrOrgNotExist struct {
ID int64
@@ -141,8 +134,9 @@ func (org *Organization) LoadTeams(ctx context.Context) ([]*Team, error) {
}
// GetMembers returns all members of organization.
-func (org *Organization) GetMembers(ctx context.Context) (user_model.UserList, map[int64]bool, error) {
+func (org *Organization) GetMembers(ctx context.Context, doer *user_model.User) (user_model.UserList, map[int64]bool, error) {
return FindOrgMembers(ctx, &FindOrgMembersOpts{
+ Doer: doer,
OrgID: org.ID,
})
}
@@ -195,16 +189,22 @@ func (org *Organization) CanCreateRepo() bool {
// FindOrgMembersOpts represensts find org members conditions
type FindOrgMembersOpts struct {
db.ListOptions
- OrgID int64
- PublicOnly bool
+ Doer *user_model.User
+ IsDoerMember bool
+ OrgID int64
+}
+
+func (opts FindOrgMembersOpts) PublicOnly() bool {
+ return opts.Doer == nil || !(opts.IsDoerMember || opts.Doer.IsAdmin)
}
// CountOrgMembers counts the organization's members
func CountOrgMembers(ctx context.Context, opts *FindOrgMembersOpts) (int64, error) {
sess := db.GetEngine(ctx).Where("org_id=?", opts.OrgID)
- if opts.PublicOnly {
+ if opts.PublicOnly() {
sess.And("is_public = ?", true)
}
+
return sess.Count(new(OrgUser))
}
@@ -264,7 +264,7 @@ func (org *Organization) UnitPermission(ctx context.Context, doer *user_model.Us
}
}
- if org.Visibility.IsPublic() {
+ if org.Visibility.IsPublic() || (org.Visibility.IsLimited() && doer != nil) {
return perm.AccessModeRead
}
@@ -439,42 +439,6 @@ func GetUsersWhoCanCreateOrgRepo(ctx context.Context, orgID int64) (map[int64]*u
And("team_user.org_id = ?", orgID).Find(&users)
}
-// SearchOrganizationsOptions options to filter organizations
-type SearchOrganizationsOptions struct {
- db.ListOptions
- All bool
-}
-
-// FindOrgOptions finds orgs options
-type FindOrgOptions struct {
- db.ListOptions
- UserID int64
- IncludePrivate bool
-}
-
-func queryUserOrgIDs(userID int64, includePrivate bool) *builder.Builder {
- cond := builder.Eq{"uid": userID}
- if !includePrivate {
- cond["is_public"] = true
- }
- return builder.Select("org_id").From("org_user").Where(cond)
-}
-
-func (opts FindOrgOptions) ToConds() builder.Cond {
- var cond builder.Cond = builder.Eq{"`user`.`type`": user_model.UserTypeOrganization}
- if opts.UserID > 0 {
- cond = cond.And(builder.In("`user`.`id`", queryUserOrgIDs(opts.UserID, opts.IncludePrivate)))
- }
- if !opts.IncludePrivate {
- cond = cond.And(builder.Eq{"`user`.visibility": structs.VisibleTypePublic})
- }
- return cond
-}
-
-func (opts FindOrgOptions) ToOrders() string {
- return "`user`.name ASC"
-}
-
// HasOrgOrUserVisible tells if the given user can see the given org or user
func HasOrgOrUserVisible(ctx context.Context, orgOrUser, user *user_model.User) bool {
// If user is nil, it's an anonymous user/request.
@@ -507,26 +471,13 @@ func HasOrgsVisible(ctx context.Context, orgs []*Organization, user *user_model.
return false
}
-// GetOrgsCanCreateRepoByUserID returns a list of organizations where given user ID
-// are allowed to create repos.
-func GetOrgsCanCreateRepoByUserID(ctx context.Context, userID int64) ([]*Organization, error) {
- orgs := make([]*Organization, 0, 10)
-
- return orgs, db.GetEngine(ctx).Where(builder.In("id", builder.Select("`user`.id").From("`user`").
- Join("INNER", "`team_user`", "`team_user`.org_id = `user`.id").
- Join("INNER", "`team`", "`team`.id = `team_user`.team_id").
- Where(builder.Eq{"`team_user`.uid": userID}).
- And(builder.Eq{"`team`.authorize": perm.AccessModeOwner}.Or(builder.Eq{"`team`.can_create_org_repo": true})))).
- Asc("`user`.name").
- Find(&orgs)
-}
-
// GetOrgUsersByOrgID returns all organization-user relations by organization ID.
func GetOrgUsersByOrgID(ctx context.Context, opts *FindOrgMembersOpts) ([]*OrgUser, error) {
sess := db.GetEngine(ctx).Where("org_id=?", opts.OrgID)
- if opts.PublicOnly {
+ if opts.PublicOnly() {
sess.And("is_public = ?", true)
}
+
if opts.ListOptions.PageSize > 0 {
sess = db.SetSessionPagination(sess, opts)
diff --git a/models/organization/org_list.go b/models/organization/org_list.go
new file mode 100644
index 0000000000..e387936473
--- /dev/null
+++ b/models/organization/org_list.go
@@ -0,0 +1,144 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package organization
+
+import (
+ "context"
+ "fmt"
+ "strings"
+
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/structs"
+
+ "xorm.io/builder"
+)
+
+// SearchOrganizationsOptions options to filter organizations
+type SearchOrganizationsOptions struct {
+ db.ListOptions
+ All bool
+}
+
+// FindOrgOptions finds orgs options
+type FindOrgOptions struct {
+ db.ListOptions
+ UserID int64
+ IncludeLimited bool
+ IncludePrivate bool
+}
+
+func queryUserOrgIDs(userID int64, includePrivate bool) *builder.Builder {
+ cond := builder.Eq{"uid": userID}
+ if !includePrivate {
+ cond["is_public"] = true
+ }
+ return builder.Select("org_id").From("org_user").Where(cond)
+}
+
+func (opts FindOrgOptions) ToConds() builder.Cond {
+ var cond builder.Cond = builder.Eq{"`user`.`type`": user_model.UserTypeOrganization}
+ if opts.UserID > 0 {
+ cond = cond.And(builder.In("`user`.`id`", queryUserOrgIDs(opts.UserID, opts.IncludePrivate)))
+ }
+ if !opts.IncludePrivate {
+ if !opts.IncludeLimited {
+ cond = cond.And(builder.Eq{"`user`.visibility": structs.VisibleTypePublic})
+ } else {
+ cond = cond.And(builder.In("`user`.visibility", structs.VisibleTypePublic, structs.VisibleTypeLimited))
+ }
+ }
+ return cond
+}
+
+func (opts FindOrgOptions) ToOrders() string {
+ return "`user`.lower_name ASC"
+}
+
+// GetOrgsCanCreateRepoByUserID returns a list of organizations where given user ID
+// are allowed to create repos.
+func GetOrgsCanCreateRepoByUserID(ctx context.Context, userID int64) ([]*Organization, error) {
+ orgs := make([]*Organization, 0, 10)
+
+ return orgs, db.GetEngine(ctx).Select("DISTINCT `user`.id, `user`.*").Table("`user`").
+ Join("INNER", "`team_user`", "`team_user`.org_id = `user`.id").
+ Join("INNER", "`team`", "`team`.id = `team_user`.team_id").
+ Where(builder.Eq{"`team_user`.uid": userID}).
+ And(builder.Eq{"`team`.authorize": perm.AccessModeOwner}.Or(builder.Eq{"`team`.can_create_org_repo": true})).
+ Asc("`user`.name").
+ Find(&orgs)
+}
+
+// MinimalOrg represents a simple organization with only the needed columns
+type MinimalOrg = Organization
+
+// GetUserOrgsList returns all organizations the given user has access to
+func GetUserOrgsList(ctx context.Context, user *user_model.User) ([]*MinimalOrg, error) {
+ schema, err := db.TableInfo(new(user_model.User))
+ if err != nil {
+ return nil, err
+ }
+
+ outputCols := []string{
+ "id",
+ "name",
+ "full_name",
+ "visibility",
+ "avatar",
+ "avatar_email",
+ "use_custom_avatar",
+ }
+
+ selectColumns := &strings.Builder{}
+ for i, col := range outputCols {
+ fmt.Fprintf(selectColumns, "`%s`.%s", schema.Name, col)
+ if i < len(outputCols)-1 {
+ selectColumns.WriteString(", ")
+ }
+ }
+ columnsStr := selectColumns.String()
+
+ var orgs []*MinimalOrg
+ if err := db.GetEngine(ctx).Select(columnsStr).
+ Table("user").
+ Where(builder.In("`user`.`id`", queryUserOrgIDs(user.ID, true))).
+ OrderBy("`user`.lower_name ASC").
+ Find(&orgs); err != nil {
+ return nil, err
+ }
+
+ type orgCount struct {
+ OrgID int64
+ RepoCount int
+ }
+ var orgCounts []orgCount
+ if err := db.GetEngine(ctx).
+ Select("owner_id AS org_id, COUNT(DISTINCT(repository.id)) as repo_count").
+ Table("repository").
+ Join("INNER", "org_user", "owner_id = org_user.org_id").
+ Where("org_user.uid = ?", user.ID).
+ And(builder.Or(
+ builder.Eq{"repository.is_private": false},
+ builder.In("repository.id", builder.Select("repo_id").From("team_repo").
+ InnerJoin("team_user", "team_user.team_id = team_repo.team_id").
+ Where(builder.Eq{"team_user.uid": user.ID})),
+ builder.In("repository.id", builder.Select("repo_id").From("collaboration").
+ Where(builder.Eq{"user_id": user.ID})),
+ )).
+ GroupBy("owner_id").Find(&orgCounts); err != nil {
+ return nil, err
+ }
+
+ orgCountMap := make(map[int64]int, len(orgCounts))
+ for _, orgCount := range orgCounts {
+ orgCountMap[orgCount.OrgID] = orgCount.RepoCount
+ }
+
+ for _, org := range orgs {
+ org.NumRepos = orgCountMap[org.ID]
+ }
+
+ return orgs, nil
+}
diff --git a/models/organization/org_list_test.go b/models/organization/org_list_test.go
new file mode 100644
index 0000000000..619427a719
--- /dev/null
+++ b/models/organization/org_list_test.go
@@ -0,0 +1,105 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package organization_test
+
+import (
+ "slices"
+ "strings"
+ "testing"
+
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestCountOrganizations(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ expected, err := db.GetEngine(db.DefaultContext).Where("type=?", user_model.UserTypeOrganization).Count(&organization.Organization{})
+ require.NoError(t, err)
+ cnt, err := db.Count[organization.Organization](db.DefaultContext, organization.FindOrgOptions{IncludePrivate: true})
+ require.NoError(t, err)
+ assert.Equal(t, expected, cnt)
+}
+
+func TestFindOrgs(t *testing.T) {
+ defer unittest.OverrideFixtures("models/organization/TestFindOrgs")()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ orgs, err := db.Find[organization.Organization](db.DefaultContext, organization.FindOrgOptions{
+ UserID: 4,
+ IncludePrivate: true,
+ })
+ require.NoError(t, err)
+ if assert.Len(t, orgs, 2) {
+ if orgs[0].ID == 22 {
+ assert.EqualValues(t, 22, orgs[0].ID)
+ assert.EqualValues(t, 3, orgs[1].ID)
+ } else {
+ assert.EqualValues(t, 3, orgs[0].ID)
+ assert.EqualValues(t, 22, orgs[1].ID)
+ }
+ }
+
+ orgs, err = db.Find[organization.Organization](db.DefaultContext, organization.FindOrgOptions{
+ UserID: 4,
+ IncludePrivate: false,
+ })
+ require.NoError(t, err)
+ assert.Empty(t, orgs)
+
+ total, err := db.Count[organization.Organization](db.DefaultContext, organization.FindOrgOptions{
+ UserID: 4,
+ IncludePrivate: true,
+ })
+ require.NoError(t, err)
+ assert.EqualValues(t, 2, total)
+
+ total, err = db.Count[organization.Organization](db.DefaultContext, organization.FindOrgOptions{
+ UserID: 4,
+ IncludePrivate: false,
+ IncludeLimited: true,
+ })
+ require.NoError(t, err)
+ assert.EqualValues(t, 1, total)
+}
+
+func TestGetOrgsCanCreateRepoByUserID(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ orgs, err := organization.GetOrgsCanCreateRepoByUserID(db.DefaultContext, 2)
+ require.NoError(t, err)
+ assert.Len(t, orgs, 1)
+ assert.EqualValues(t, 3, orgs[0].ID)
+ orgs, err = organization.GetOrgsCanCreateRepoByUserID(db.DefaultContext, 1)
+ require.NoError(t, err)
+ assert.Len(t, orgs, 2)
+ assert.EqualValues(t, 36, orgs[0].ID)
+ assert.EqualValues(t, 35, orgs[1].ID)
+}
+
+func TestGetUserOrgsList(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ orgs, err := organization.GetUserOrgsList(db.DefaultContext, &user_model.User{ID: 4})
+ require.NoError(t, err)
+ if assert.Len(t, orgs, 1) {
+ assert.EqualValues(t, 3, orgs[0].ID)
+ // repo_id: 3 is in the team, 32 is public, 5 is private with no team
+ assert.EqualValues(t, 2, orgs[0].NumRepos)
+ }
+}
+
+func TestGetUserOrgsListSorting(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ orgs, err := organization.GetUserOrgsList(db.DefaultContext, &user_model.User{ID: 1})
+ require.NoError(t, err)
+
+ isSorted := slices.IsSortedFunc(orgs, func(a, b *organization.MinimalOrg) int {
+ return strings.Compare(strings.ToLower(a.Name), strings.ToLower(b.Name))
+ })
+
+ assert.True(t, isSorted)
+}
diff --git a/models/organization/org_repo.go b/models/organization/org_repo.go
index f7e59928f4..f190a38bda 100644
--- a/models/organization/org_repo.go
+++ b/models/organization/org_repo.go
@@ -6,8 +6,8 @@ package organization
import (
"context"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
)
// GetOrgRepositories get repos belonging to the given organization
diff --git a/models/organization/org_test.go b/models/organization/org_test.go
index 23ef22e2fb..212b893a42 100644
--- a/models/organization/org_test.go
+++ b/models/organization/org_test.go
@@ -4,20 +4,24 @@
package organization_test
import (
+ "sort"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/structs"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestUser_IsOwnedBy(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
for _, testCase := range []struct {
OrgID int64
UserID int64
@@ -32,13 +36,13 @@ func TestUser_IsOwnedBy(t *testing.T) {
} {
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID})
isOwner, err := org.IsOwnedBy(db.DefaultContext, testCase.UserID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testCase.ExpectedOwner, isOwner)
}
}
func TestUser_IsOrgMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
for _, testCase := range []struct {
OrgID int64
UserID int64
@@ -53,16 +57,16 @@ func TestUser_IsOrgMember(t *testing.T) {
} {
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID})
isMember, err := org.IsOrgMember(db.DefaultContext, testCase.UserID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testCase.ExpectedMember, isMember)
}
}
func TestUser_GetTeam(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
team, err := org.GetTeam(db.DefaultContext, "team1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, org.ID, team.OrgID)
assert.Equal(t, "team1", team.LowerName)
@@ -75,10 +79,10 @@ func TestUser_GetTeam(t *testing.T) {
}
func TestUser_GetOwnerTeam(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
team, err := org.GetOwnerTeam(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, org.ID, team.OrgID)
nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2})
@@ -87,10 +91,10 @@ func TestUser_GetOwnerTeam(t *testing.T) {
}
func TestUser_GetTeams(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
teams, err := org.LoadTeams(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, teams, 5) {
assert.Equal(t, int64(1), teams[0].ID)
assert.Equal(t, int64(2), teams[1].ID)
@@ -101,10 +105,10 @@ func TestUser_GetTeams(t *testing.T) {
}
func TestUser_GetMembers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
- members, _, err := org.GetMembers(db.DefaultContext)
- assert.NoError(t, err)
+ members, _, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true})
+ require.NoError(t, err)
if assert.Len(t, members, 3) {
assert.Equal(t, int64(2), members[0].ID)
assert.Equal(t, int64(28), members[1].ID)
@@ -113,10 +117,10 @@ func TestUser_GetMembers(t *testing.T) {
}
func TestGetOrgByName(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org, err := organization.GetOrgByName(db.DefaultContext, "org3")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, org.ID)
assert.Equal(t, "org3", org.Name)
@@ -127,20 +131,11 @@ func TestGetOrgByName(t *testing.T) {
assert.True(t, organization.IsErrOrgNotExist(err))
}
-func TestCountOrganizations(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
- expected, err := db.GetEngine(db.DefaultContext).Where("type=?", user_model.UserTypeOrganization).Count(&organization.Organization{})
- assert.NoError(t, err)
- cnt, err := db.Count[organization.Organization](db.DefaultContext, organization.FindOrgOptions{IncludePrivate: true})
- assert.NoError(t, err)
- assert.Equal(t, expected, cnt)
-}
-
func TestIsOrganizationOwner(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(orgID, userID int64, expected bool) {
isOwner, err := organization.IsOrganizationOwner(db.DefaultContext, orgID, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, expected, isOwner)
}
test(3, 2, true)
@@ -151,10 +146,10 @@ func TestIsOrganizationOwner(t *testing.T) {
}
func TestIsOrganizationMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(orgID, userID int64, expected bool) {
isMember, err := organization.IsOrganizationMember(db.DefaultContext, orgID, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, expected, isMember)
}
test(3, 2, true)
@@ -166,10 +161,10 @@ func TestIsOrganizationMember(t *testing.T) {
}
func TestIsPublicMembership(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(orgID, userID int64, expected bool) {
isMember, err := organization.IsPublicMembership(db.DefaultContext, orgID, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, expected, isMember)
}
test(3, 2, true)
@@ -180,77 +175,55 @@ func TestIsPublicMembership(t *testing.T) {
test(unittest.NonexistentID, unittest.NonexistentID, false)
}
-func TestFindOrgs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
-
- orgs, err := db.Find[organization.Organization](db.DefaultContext, organization.FindOrgOptions{
- UserID: 4,
- IncludePrivate: true,
- })
- assert.NoError(t, err)
- if assert.Len(t, orgs, 1) {
- assert.EqualValues(t, 3, orgs[0].ID)
- }
-
- orgs, err = db.Find[organization.Organization](db.DefaultContext, organization.FindOrgOptions{
- UserID: 4,
- IncludePrivate: false,
- })
- assert.NoError(t, err)
- assert.Len(t, orgs, 0)
-
- total, err := db.Count[organization.Organization](db.DefaultContext, organization.FindOrgOptions{
- UserID: 4,
- IncludePrivate: true,
- })
- assert.NoError(t, err)
- assert.EqualValues(t, 1, total)
-}
-
func TestGetOrgUsersByOrgID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
- orgUsers, err := organization.GetOrgUsersByOrgID(db.DefaultContext, &organization.FindOrgMembersOpts{
- ListOptions: db.ListOptions{},
- OrgID: 3,
- PublicOnly: false,
- })
- assert.NoError(t, err)
- if assert.Len(t, orgUsers, 3) {
- assert.Equal(t, organization.OrgUser{
- ID: orgUsers[0].ID,
- OrgID: 3,
- UID: 2,
- IsPublic: true,
- }, *orgUsers[0])
- assert.Equal(t, organization.OrgUser{
- ID: orgUsers[1].ID,
- OrgID: 3,
- UID: 4,
- IsPublic: false,
- }, *orgUsers[1])
- assert.Equal(t, organization.OrgUser{
- ID: orgUsers[2].ID,
- OrgID: 3,
- UID: 28,
- IsPublic: true,
- }, *orgUsers[2])
+ opts := &organization.FindOrgMembersOpts{
+ Doer: &user_model.User{IsAdmin: true},
+ OrgID: 3,
}
+ assert.False(t, opts.PublicOnly())
+ orgUsers, err := organization.GetOrgUsersByOrgID(db.DefaultContext, opts)
+ require.NoError(t, err)
+ sort.Slice(orgUsers, func(i, j int) bool {
+ return orgUsers[i].ID < orgUsers[j].ID
+ })
+ assert.EqualValues(t, []*organization.OrgUser{{
+ ID: 1,
+ OrgID: 3,
+ UID: 2,
+ IsPublic: true,
+ }, {
+ ID: 2,
+ OrgID: 3,
+ UID: 4,
+ IsPublic: false,
+ }, {
+ ID: 9,
+ OrgID: 3,
+ UID: 28,
+ IsPublic: true,
+ }}, orgUsers)
+
+ opts = &organization.FindOrgMembersOpts{OrgID: 3}
+ assert.True(t, opts.PublicOnly())
+ orgUsers, err = organization.GetOrgUsersByOrgID(db.DefaultContext, opts)
+ require.NoError(t, err)
+ assert.Len(t, orgUsers, 2)
orgUsers, err = organization.GetOrgUsersByOrgID(db.DefaultContext, &organization.FindOrgMembersOpts{
ListOptions: db.ListOptions{},
OrgID: unittest.NonexistentID,
- PublicOnly: false,
})
- assert.NoError(t, err)
- assert.Len(t, orgUsers, 0)
+ require.NoError(t, err)
+ assert.Empty(t, orgUsers)
}
func TestChangeOrgUserStatus(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(orgID, userID int64, public bool) {
- assert.NoError(t, organization.ChangeOrgUserStatus(db.DefaultContext, orgID, userID, public))
+ require.NoError(t, organization.ChangeOrgUserStatus(db.DefaultContext, orgID, userID, public))
orgUser := unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{OrgID: orgID, UID: userID})
assert.Equal(t, public, orgUser.IsPublic)
}
@@ -258,15 +231,15 @@ func TestChangeOrgUserStatus(t *testing.T) {
testSuccess(3, 2, false)
testSuccess(3, 2, false)
testSuccess(3, 4, true)
- assert.NoError(t, organization.ChangeOrgUserStatus(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID, true))
+ require.NoError(t, organization.ChangeOrgUserStatus(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID, true))
}
func TestUser_GetUserTeamIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID int64, expected []int64) {
teamIDs, err := org.GetUserTeamIDs(db.DefaultContext, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, teamIDs)
}
testSuccess(2, []int64{1, 2, 14})
@@ -275,13 +248,13 @@ func TestUser_GetUserTeamIDs(t *testing.T) {
}
func TestAccessibleReposEnv_CountRepos(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID, expectedCount int64) {
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
count, err := env.CountRepos()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, expectedCount, count)
}
testSuccess(2, 3)
@@ -289,27 +262,27 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) {
}
func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID int64, expectedRepoIDs []int64) {
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
repoIDs, err := env.RepoIDs(1, 100)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expectedRepoIDs, repoIDs)
}
- testSuccess(2, []int64{3, 5, 32})
- testSuccess(4, []int64{3, 32})
+ testSuccess(2, []int64{32, 5, 3})
+ testSuccess(4, []int64{32, 3})
}
func TestAccessibleReposEnv_Repos(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID int64, expectedRepoIDs []int64) {
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
repos, err := env.Repos(1, 100)
- assert.NoError(t, err)
+ require.NoError(t, err)
expectedRepos := make(repo_model.RepositoryList, len(expectedRepoIDs))
for i, repoID := range expectedRepoIDs {
expectedRepos[i] = unittest.AssertExistsAndLoadBean(t,
@@ -317,18 +290,18 @@ func TestAccessibleReposEnv_Repos(t *testing.T) {
}
assert.Equal(t, expectedRepos, repos)
}
- testSuccess(2, []int64{3, 5, 32})
- testSuccess(4, []int64{3, 32})
+ testSuccess(2, []int64{32, 5, 3})
+ testSuccess(4, []int64{32, 3})
}
func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID int64, expectedRepoIDs []int64) {
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
repos, err := env.MirrorRepos()
- assert.NoError(t, err)
+ require.NoError(t, err)
expectedRepos := make(repo_model.RepositoryList, len(expectedRepoIDs))
for i, repoID := range expectedRepoIDs {
expectedRepos[i] = unittest.AssertExistsAndLoadBean(t,
@@ -341,7 +314,7 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
}
func TestHasOrgVisibleTypePublic(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
@@ -352,7 +325,7 @@ func TestHasOrgVisibleTypePublic(t *testing.T) {
}
unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization})
- assert.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner))
+ require.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner))
org = unittest.AssertExistsAndLoadBean(t,
&organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization})
test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner)
@@ -364,7 +337,7 @@ func TestHasOrgVisibleTypePublic(t *testing.T) {
}
func TestHasOrgVisibleTypeLimited(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
@@ -375,7 +348,7 @@ func TestHasOrgVisibleTypeLimited(t *testing.T) {
}
unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization})
- assert.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner))
+ require.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner))
org = unittest.AssertExistsAndLoadBean(t,
&organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization})
test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner)
@@ -387,7 +360,7 @@ func TestHasOrgVisibleTypeLimited(t *testing.T) {
}
func TestHasOrgVisibleTypePrivate(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
@@ -398,7 +371,7 @@ func TestHasOrgVisibleTypePrivate(t *testing.T) {
}
unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization})
- assert.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner))
+ require.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner))
org = unittest.AssertExistsAndLoadBean(t,
&organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization})
test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner)
@@ -410,10 +383,10 @@ func TestHasOrgVisibleTypePrivate(t *testing.T) {
}
func TestGetUsersWhoCanCreateOrgRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
users, err := organization.GetUsersWhoCanCreateOrgRepo(db.DefaultContext, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, users, 2)
var ids []int64
for i := range users {
@@ -422,27 +395,27 @@ func TestGetUsersWhoCanCreateOrgRepo(t *testing.T) {
assert.ElementsMatch(t, ids, []int64{2, 28})
users, err = organization.GetUsersWhoCanCreateOrgRepo(db.DefaultContext, 7)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, users, 1)
assert.NotNil(t, users[5])
}
func TestUser_RemoveOrgRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: org.ID})
// remove a repo that does belong to org
unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{RepoID: repo.ID, OrgID: org.ID})
- assert.NoError(t, organization.RemoveOrgRepo(db.DefaultContext, org.ID, repo.ID))
+ require.NoError(t, organization.RemoveOrgRepo(db.DefaultContext, org.ID, repo.ID))
unittest.AssertNotExistsBean(t, &organization.TeamRepo{RepoID: repo.ID, OrgID: org.ID})
unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID}) // repo should still exist
// remove a repo that does not belong to org
- assert.NoError(t, organization.RemoveOrgRepo(db.DefaultContext, org.ID, repo.ID))
+ require.NoError(t, organization.RemoveOrgRepo(db.DefaultContext, org.ID, repo.ID))
unittest.AssertNotExistsBean(t, &organization.TeamRepo{RepoID: repo.ID, OrgID: org.ID})
- assert.NoError(t, organization.RemoveOrgRepo(db.DefaultContext, org.ID, unittest.NonexistentID))
+ require.NoError(t, organization.RemoveOrgRepo(db.DefaultContext, org.ID, unittest.NonexistentID))
unittest.CheckConsistencyFor(t,
&user_model.User{ID: org.ID},
@@ -452,7 +425,7 @@ func TestUser_RemoveOrgRepo(t *testing.T) {
func TestCreateOrganization(t *testing.T) {
// successful creation of org
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
const newOrgName = "neworg"
@@ -461,7 +434,7 @@ func TestCreateOrganization(t *testing.T) {
}
unittest.AssertNotExistsBean(t, &user_model.User{Name: newOrgName, Type: user_model.UserTypeOrganization})
- assert.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner))
+ require.NoError(t, organization.CreateOrganization(db.DefaultContext, org, owner))
org = unittest.AssertExistsAndLoadBean(t,
&organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization})
ownerTeam := unittest.AssertExistsAndLoadBean(t,
@@ -472,7 +445,7 @@ func TestCreateOrganization(t *testing.T) {
func TestCreateOrganization2(t *testing.T) {
// unauthorized creation of org
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
const newOrgName = "neworg"
@@ -482,7 +455,7 @@ func TestCreateOrganization2(t *testing.T) {
unittest.AssertNotExistsBean(t, &organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization})
err := organization.CreateOrganization(db.DefaultContext, org, owner)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, organization.IsErrUserNotAllowedCreateOrg(err))
unittest.AssertNotExistsBean(t, &organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization})
unittest.CheckConsistencyFor(t, &organization.Organization{}, &organization.Team{})
@@ -490,24 +463,56 @@ func TestCreateOrganization2(t *testing.T) {
func TestCreateOrganization3(t *testing.T) {
// create org with same name as existent org
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org := &organization.Organization{Name: "org3"} // should already exist
unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: org.Name}) // sanity check
err := organization.CreateOrganization(db.DefaultContext, org, owner)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, user_model.IsErrUserAlreadyExist(err))
unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{})
}
func TestCreateOrganization4(t *testing.T) {
// create org with unusable name
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
err := organization.CreateOrganization(db.DefaultContext, &organization.Organization{Name: "assets"}, owner)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, db.IsErrNameReserved(err))
unittest.CheckConsistencyFor(t, &organization.Organization{}, &organization.Team{})
}
+
+func TestUnitPermission(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ publicOrg := &organization.Organization{ID: 1001, Visibility: structs.VisibleTypePublic}
+ limitedOrg := &organization.Organization{ID: 1001, Visibility: structs.VisibleTypeLimited}
+ privateOrg := &organization.Organization{ID: 1001, Visibility: structs.VisibleTypePrivate}
+ user := &user_model.User{ID: 1001}
+ t.Run("Anonymous", func(t *testing.T) {
+ t.Run("Public", func(t *testing.T) {
+ assert.EqualValues(t, perm.AccessModeRead, publicOrg.UnitPermission(db.DefaultContext, nil, unit.TypeCode))
+ })
+ t.Run("Limited", func(t *testing.T) {
+ assert.EqualValues(t, perm.AccessModeNone, limitedOrg.UnitPermission(db.DefaultContext, nil, unit.TypeCode))
+ })
+ t.Run("Private", func(t *testing.T) {
+ assert.EqualValues(t, perm.AccessModeNone, privateOrg.UnitPermission(db.DefaultContext, nil, unit.TypeCode))
+ })
+ })
+
+ t.Run("Logged in", func(t *testing.T) {
+ t.Run("Public", func(t *testing.T) {
+ assert.EqualValues(t, perm.AccessModeRead, publicOrg.UnitPermission(db.DefaultContext, user, unit.TypeCode))
+ })
+ t.Run("Limited", func(t *testing.T) {
+ assert.EqualValues(t, perm.AccessModeRead, limitedOrg.UnitPermission(db.DefaultContext, user, unit.TypeCode))
+ })
+ t.Run("Private", func(t *testing.T) {
+ assert.EqualValues(t, perm.AccessModeNone, privateOrg.UnitPermission(db.DefaultContext, user, unit.TypeCode))
+ })
+ })
+}
diff --git a/models/organization/org_user.go b/models/organization/org_user.go
index 5fe3a178d2..81671c5cf5 100644
--- a/models/organization/org_user.go
+++ b/models/organization/org_user.go
@@ -7,10 +7,10 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
"xorm.io/builder"
)
diff --git a/models/organization/org_user_test.go b/models/organization/org_user_test.go
index 7924517f31..3f6799e8a1 100644
--- a/models/organization/org_user_test.go
+++ b/models/organization/org_user_test.go
@@ -7,17 +7,18 @@ import (
"fmt"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestUserIsPublicMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
tt := []struct {
uid int64
@@ -38,14 +39,14 @@ func TestUserIsPublicMember(t *testing.T) {
func testUserIsPublicMember(t *testing.T, uid, orgID int64, expected bool) {
user, err := user_model.GetUserByID(db.DefaultContext, uid)
- assert.NoError(t, err)
+ require.NoError(t, err)
is, err := organization.IsPublicMembership(db.DefaultContext, orgID, user.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, is)
}
func TestIsUserOrgOwner(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
tt := []struct {
uid int64
@@ -66,14 +67,14 @@ func TestIsUserOrgOwner(t *testing.T) {
func testIsUserOrgOwner(t *testing.T, uid, orgID int64, expected bool) {
user, err := user_model.GetUserByID(db.DefaultContext, uid)
- assert.NoError(t, err)
+ require.NoError(t, err)
is, err := organization.IsOrganizationOwner(db.DefaultContext, orgID, user.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, is)
}
func TestUserListIsPublicMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
tt := []struct {
orgid int64
expected map[int64]bool
@@ -93,14 +94,14 @@ func TestUserListIsPublicMember(t *testing.T) {
func testUserListIsPublicMember(t *testing.T, orgID int64, expected map[int64]bool) {
org, err := organization.GetOrgByID(db.DefaultContext, orgID)
- assert.NoError(t, err)
- _, membersIsPublic, err := org.GetMembers(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
+ _, membersIsPublic, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true})
+ require.NoError(t, err)
assert.Equal(t, expected, membersIsPublic)
}
func TestUserListIsUserOrgOwner(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
tt := []struct {
orgid int64
expected map[int64]bool
@@ -120,21 +121,21 @@ func TestUserListIsUserOrgOwner(t *testing.T) {
func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]bool) {
org, err := organization.GetOrgByID(db.DefaultContext, orgID)
- assert.NoError(t, err)
- members, _, err := org.GetMembers(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
+ members, _, err := org.GetMembers(db.DefaultContext, &user_model.User{IsAdmin: true})
+ require.NoError(t, err)
assert.Equal(t, expected, organization.IsUserOrgOwner(db.DefaultContext, members, orgID))
}
func TestAddOrgUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(orgID, userID int64, isPublic bool) {
org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID})
expectedNumMembers := org.NumMembers
if !unittest.BeanExists(t, &organization.OrgUser{OrgID: orgID, UID: userID}) {
expectedNumMembers++
}
- assert.NoError(t, organization.AddOrgUser(db.DefaultContext, orgID, userID))
+ require.NoError(t, organization.AddOrgUser(db.DefaultContext, orgID, userID))
ou := &organization.OrgUser{OrgID: orgID, UID: userID}
unittest.AssertExistsAndLoadBean(t, ou)
assert.Equal(t, isPublic, ou.IsPublic)
diff --git a/models/organization/team.go b/models/organization/team.go
index 1b737c2d3d..c78eff39fb 100644
--- a/models/organization/team.go
+++ b/models/organization/team.go
@@ -9,13 +9,13 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -247,24 +247,56 @@ func GetTeamByID(ctx context.Context, teamID int64) (*Team, error) {
return t, nil
}
-// GetTeamNamesByID returns team's lower name from a list of team ids.
-func GetTeamNamesByID(ctx context.Context, teamIDs []int64) ([]string, error) {
- if len(teamIDs) == 0 {
- return []string{}, nil
- }
-
- var teamNames []string
- err := db.GetEngine(ctx).Table("team").
- Select("lower_name").
- In("id", teamIDs).
- Asc("name").
- Find(&teamNames)
-
- return teamNames, err
-}
-
// IncrTeamRepoNum increases the number of repos for the given team by 1
func IncrTeamRepoNum(ctx context.Context, teamID int64) error {
_, err := db.GetEngine(ctx).Incr("num_repos").ID(teamID).Update(new(Team))
return err
}
+
+// CountInconsistentOwnerTeams returns the amount of owner teams that have all of
+// their access modes set to "None".
+func CountInconsistentOwnerTeams(ctx context.Context) (int64, error) {
+ return db.GetEngine(ctx).Table("team").
+ Join("INNER", "team_unit", "`team`.id = `team_unit`.team_id").
+ Where("`team`.lower_name = ?", strings.ToLower(OwnerTeamName)).
+ GroupBy("`team_unit`.team_id").
+ Having("SUM(`team_unit`.access_mode) = 0").
+ Count()
+}
+
+// FixInconsistentOwnerTeams fixes inconsistent owner teams that have all of
+// their access modes set to "None", it sets it back to "Owner".
+func FixInconsistentOwnerTeams(ctx context.Context) (int64, error) {
+ teamIDs := []int64{}
+ if err := db.GetEngine(ctx).Table("team").
+ Select("`team`.id").
+ Join("INNER", "team_unit", "`team`.id = `team_unit`.team_id").
+ Where("`team`.lower_name = ?", strings.ToLower(OwnerTeamName)).
+ GroupBy("`team_unit`.team_id").
+ Having("SUM(`team_unit`.access_mode) = 0").
+ Find(&teamIDs); err != nil {
+ return 0, err
+ }
+
+ if err := db.Iterate(ctx, builder.In("team_id", teamIDs), func(ctx context.Context, bean *TeamUnit) error {
+ if bean.Type == unit.TypeExternalTracker || bean.Type == unit.TypeExternalWiki {
+ bean.AccessMode = perm.AccessModeRead
+ } else {
+ bean.AccessMode = perm.AccessModeOwner
+ }
+ _, err := db.GetEngine(ctx).ID(bean.ID).Table("team_unit").Cols("access_mode").Update(bean)
+ return err
+ }); err != nil {
+ return 0, err
+ }
+
+ return int64(len(teamIDs)), nil
+}
+
+func NewGhostTeam() *Team {
+ return &Team{
+ ID: -1,
+ Name: "Ghost team",
+ LowerName: "ghost team",
+ }
+}
diff --git a/models/organization/team_invite.go b/models/organization/team_invite.go
index 17f6c59610..45be6c4c64 100644
--- a/models/organization/team_invite.go
+++ b/models/organization/team_invite.go
@@ -7,10 +7,10 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/organization/team_invite_test.go b/models/organization/team_invite_test.go
index 45db8494e8..8d55864237 100644
--- a/models/organization/team_invite_test.go
+++ b/models/organization/team_invite_test.go
@@ -6,16 +6,17 @@ package organization_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestTeamInvite(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
@@ -24,7 +25,7 @@ func TestTeamInvite(t *testing.T) {
// user 2 already added to team 2, should result in error
_, err := organization.CreateTeamInvite(db.DefaultContext, user2, team, user2.Email)
- assert.Error(t, err)
+ require.Error(t, err)
})
t.Run("CreateAndRemove", func(t *testing.T) {
@@ -32,17 +33,17 @@ func TestTeamInvite(t *testing.T) {
invite, err := organization.CreateTeamInvite(db.DefaultContext, user1, team, "org3@example.com")
assert.NotNil(t, invite)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Shouldn't allow duplicate invite
_, err = organization.CreateTeamInvite(db.DefaultContext, user1, team, "org3@example.com")
- assert.Error(t, err)
+ require.Error(t, err)
// should remove invite
- assert.NoError(t, organization.RemoveInviteByID(db.DefaultContext, invite.ID, invite.TeamID))
+ require.NoError(t, organization.RemoveInviteByID(db.DefaultContext, invite.ID, invite.TeamID))
// invite should not exist
_, err = organization.GetInviteByToken(db.DefaultContext, invite.Token)
- assert.Error(t, err)
+ require.Error(t, err)
})
}
diff --git a/models/organization/team_list.go b/models/organization/team_list.go
index 5b45429acf..573fd4ef96 100644
--- a/models/organization/team_list.go
+++ b/models/organization/team_list.go
@@ -7,10 +7,10 @@ import (
"context"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
"xorm.io/builder"
)
diff --git a/models/organization/team_repo.go b/models/organization/team_repo.go
index 1184e39263..334b139808 100644
--- a/models/organization/team_repo.go
+++ b/models/organization/team_repo.go
@@ -6,9 +6,9 @@ package organization
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
"xorm.io/builder"
)
diff --git a/models/organization/team_test.go b/models/organization/team_test.go
index 23a6affe24..1be96b6a01 100644
--- a/models/organization/team_test.go
+++ b/models/organization/team_test.go
@@ -6,15 +6,17 @@ package organization_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestTeam_IsOwnerTeam(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
assert.True(t, team.IsOwnerTeam())
@@ -24,7 +26,7 @@ func TestTeam_IsOwnerTeam(t *testing.T) {
}
func TestTeam_IsMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
assert.True(t, team.IsMember(db.DefaultContext, 2))
@@ -38,11 +40,11 @@ func TestTeam_IsMember(t *testing.T) {
}
func TestTeam_GetRepositories(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
- assert.NoError(t, team.LoadRepositories(db.DefaultContext))
+ require.NoError(t, team.LoadRepositories(db.DefaultContext))
assert.Len(t, team.Repos, team.NumRepos)
for _, repo := range team.Repos {
unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repo.ID})
@@ -53,11 +55,11 @@ func TestTeam_GetRepositories(t *testing.T) {
}
func TestTeam_GetMembers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
- assert.NoError(t, team.LoadMembers(db.DefaultContext))
+ require.NoError(t, team.LoadMembers(db.DefaultContext))
assert.Len(t, team.Members, team.NumMembers)
for _, member := range team.Members {
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: member.ID, TeamID: teamID})
@@ -68,11 +70,11 @@ func TestTeam_GetMembers(t *testing.T) {
}
func TestGetTeam(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(orgID int64, name string) {
team, err := organization.GetTeam(db.DefaultContext, orgID, name)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, orgID, team.OrgID)
assert.Equal(t, name, team.Name)
}
@@ -80,17 +82,17 @@ func TestGetTeam(t *testing.T) {
testSuccess(3, "team1")
_, err := organization.GetTeam(db.DefaultContext, 3, "nonexistent")
- assert.Error(t, err)
+ require.Error(t, err)
_, err = organization.GetTeam(db.DefaultContext, unittest.NonexistentID, "Owners")
- assert.Error(t, err)
+ require.Error(t, err)
}
func TestGetTeamByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(teamID int64) {
team, err := organization.GetTeamByID(db.DefaultContext, teamID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, teamID, team.ID)
}
testSuccess(1)
@@ -99,14 +101,14 @@ func TestGetTeamByID(t *testing.T) {
testSuccess(4)
_, err := organization.GetTeamByID(db.DefaultContext, unittest.NonexistentID)
- assert.Error(t, err)
+ require.Error(t, err)
}
func TestIsTeamMember(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(orgID, teamID, userID int64, expected bool) {
isMember, err := organization.IsTeamMember(db.DefaultContext, orgID, teamID, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, isMember)
}
@@ -122,14 +124,14 @@ func TestIsTeamMember(t *testing.T) {
}
func TestGetTeamMembers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID int64) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
members, err := organization.GetTeamMembers(db.DefaultContext, &organization.SearchMembersOptions{
TeamID: teamID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, members, team.NumMembers)
for _, member := range members {
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: member.ID, TeamID: teamID})
@@ -140,10 +142,10 @@ func TestGetTeamMembers(t *testing.T) {
}
func TestGetUserTeams(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(userID int64) {
teams, _, err := organization.SearchTeam(db.DefaultContext, &organization.SearchTeamOptions{UserID: userID})
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, team := range teams {
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{TeamID: team.ID, UID: userID})
}
@@ -154,10 +156,10 @@ func TestGetUserTeams(t *testing.T) {
}
func TestGetUserOrgTeams(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(orgID, userID int64) {
teams, err := organization.GetUserOrgTeams(db.DefaultContext, orgID, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, team := range teams {
assert.EqualValues(t, orgID, team.OrgID)
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{TeamID: team.ID, UID: userID})
@@ -169,7 +171,7 @@ func TestGetUserOrgTeams(t *testing.T) {
}
func TestHasTeamRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID, repoID int64, expected bool) {
team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
@@ -184,16 +186,43 @@ func TestHasTeamRepo(t *testing.T) {
test(2, 5, false)
}
-func TestUsersInTeamsCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+func TestInconsistentOwnerTeam(t *testing.T) {
+ defer unittest.OverrideFixtures("models/organization/TestInconsistentOwnerTeam")()
+ require.NoError(t, unittest.PrepareTestDatabase())
- test := func(teamIDs, userIDs []int64, expected int64) {
- count, err := organization.UsersInTeamsCount(db.DefaultContext, teamIDs, userIDs)
- assert.NoError(t, err)
- assert.Equal(t, expected, count)
- }
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1000, TeamID: 1000, AccessMode: perm.AccessModeNone})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1001, TeamID: 1000, AccessMode: perm.AccessModeNone})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1002, TeamID: 1000, AccessMode: perm.AccessModeNone})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1003, TeamID: 1000, AccessMode: perm.AccessModeNone})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1004, TeamID: 1000, AccessMode: perm.AccessModeNone})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1005, TeamID: 1000, AccessMode: perm.AccessModeNone})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1006, TeamID: 1000, AccessMode: perm.AccessModeNone})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1007, TeamID: 1000, AccessMode: perm.AccessModeNone})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1008, TeamID: 1000, AccessMode: perm.AccessModeNone})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1009, TeamID: 1000, AccessMode: perm.AccessModeNone})
- test([]int64{2}, []int64{1, 2, 3, 4}, 1) // only userid 2
- test([]int64{1, 2, 3, 4, 5}, []int64{2, 5}, 2) // userid 2,4
- test([]int64{1, 2, 3, 4, 5}, []int64{2, 3, 5}, 3) // userid 2,4,5
+ count, err := organization.CountInconsistentOwnerTeams(db.DefaultContext)
+ require.NoError(t, err)
+ require.EqualValues(t, 1, count)
+
+ count, err = organization.FixInconsistentOwnerTeams(db.DefaultContext)
+ require.NoError(t, err)
+ require.EqualValues(t, 1, count)
+
+ count, err = organization.CountInconsistentOwnerTeams(db.DefaultContext)
+ require.NoError(t, err)
+ require.EqualValues(t, 0, count)
+
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1000, AccessMode: perm.AccessModeOwner})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1001, AccessMode: perm.AccessModeOwner})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1002, AccessMode: perm.AccessModeOwner})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1003, AccessMode: perm.AccessModeOwner})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1004, AccessMode: perm.AccessModeOwner})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1007, AccessMode: perm.AccessModeOwner})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1008, AccessMode: perm.AccessModeOwner})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1009, AccessMode: perm.AccessModeOwner})
+
+ // External wiki and issue
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1005, AccessMode: perm.AccessModeRead})
+ unittest.AssertExistsAndLoadBean(t, &organization.TeamUnit{ID: 1006, AccessMode: perm.AccessModeRead})
}
diff --git a/models/organization/team_unit.go b/models/organization/team_unit.go
index 3087b70770..b45ac2fc07 100644
--- a/models/organization/team_unit.go
+++ b/models/organization/team_unit.go
@@ -6,9 +6,9 @@ package organization
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/unit"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/unit"
)
// TeamUnit describes all units of a repository
@@ -28,24 +28,3 @@ func (t *TeamUnit) Unit() unit.Unit {
func getUnitsByTeamID(ctx context.Context, teamID int64) (units []*TeamUnit, err error) {
return units, db.GetEngine(ctx).Where("team_id = ?", teamID).Find(&units)
}
-
-// UpdateTeamUnits updates a teams's units
-func UpdateTeamUnits(ctx context.Context, team *Team, units []TeamUnit) (err error) {
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if _, err = db.GetEngine(ctx).Where("team_id = ?", team.ID).Delete(new(TeamUnit)); err != nil {
- return err
- }
-
- if len(units) > 0 {
- if err = db.Insert(ctx, units); err != nil {
- return err
- }
- }
-
- return committer.Commit()
-}
diff --git a/models/organization/team_user.go b/models/organization/team_user.go
index ab767db200..a954e94767 100644
--- a/models/organization/team_user.go
+++ b/models/organization/team_user.go
@@ -6,8 +6,8 @@ package organization
import (
"context"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
"xorm.io/builder"
)
@@ -76,14 +76,3 @@ func GetTeamMembers(ctx context.Context, opts *SearchMembersOptions) ([]*user_mo
func IsUserInTeams(ctx context.Context, userID int64, teamIDs []int64) (bool, error) {
return db.GetEngine(ctx).Where("uid=?", userID).In("team_id", teamIDs).Exist(new(TeamUser))
}
-
-// UsersInTeamsCount counts the number of users which are in userIDs and teamIDs
-func UsersInTeamsCount(ctx context.Context, userIDs, teamIDs []int64) (int64, error) {
- var ids []int64
- if err := db.GetEngine(ctx).In("uid", userIDs).In("team_id", teamIDs).
- Table("team_user").
- Cols("uid").GroupBy("uid").Find(&ids); err != nil {
- return 0, err
- }
- return int64(len(ids)), nil
-}
diff --git a/models/packages/alpine/search.go b/models/packages/alpine/search.go
index 77eccb90ed..1cc808d18d 100644
--- a/models/packages/alpine/search.go
+++ b/models/packages/alpine/search.go
@@ -6,8 +6,8 @@ package alpine
import (
"context"
- packages_model "code.gitea.io/gitea/models/packages"
- alpine_module "code.gitea.io/gitea/modules/packages/alpine"
+ packages_model "forgejo.org/models/packages"
+ alpine_module "forgejo.org/modules/packages/alpine"
)
// GetBranches gets all available branches
diff --git a/models/packages/alt/search.go b/models/packages/alt/search.go
new file mode 100644
index 0000000000..0bfba77e0e
--- /dev/null
+++ b/models/packages/alt/search.go
@@ -0,0 +1,29 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package alt
+
+import (
+ "context"
+
+ packages_model "forgejo.org/models/packages"
+ rpm_module "forgejo.org/modules/packages/rpm"
+)
+
+type PackageSearchOptions struct {
+ OwnerID int64
+ GroupID int64
+ Architecture string
+}
+
+// GetGroups gets all available groups
+func GetGroups(ctx context.Context, ownerID int64) ([]string, error) {
+ return packages_model.GetDistinctPropertyValues(
+ ctx,
+ packages_model.TypeAlt,
+ ownerID,
+ packages_model.PropertyTypeFile,
+ rpm_module.PropertyGroup,
+ nil,
+ )
+}
diff --git a/models/packages/conan/references.go b/models/packages/conan/references.go
index 0d888a1ec8..5e09c4b63f 100644
--- a/models/packages/conan/references.go
+++ b/models/packages/conan/references.go
@@ -8,11 +8,11 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/packages"
- conan_module "code.gitea.io/gitea/modules/packages/conan"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/packages"
+ conan_module "forgejo.org/modules/packages/conan"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/packages/conan/search.go b/models/packages/conan/search.go
index ab0bff5968..3ef8b4cceb 100644
--- a/models/packages/conan/search.go
+++ b/models/packages/conan/search.go
@@ -9,10 +9,10 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/container"
- conan_module "code.gitea.io/gitea/modules/packages/conan"
+ "forgejo.org/models/db"
+ "forgejo.org/models/packages"
+ "forgejo.org/modules/container"
+ conan_module "forgejo.org/modules/packages/conan"
"xorm.io/builder"
)
diff --git a/models/packages/conda/search.go b/models/packages/conda/search.go
index 887441e3b2..147de1aa02 100644
--- a/models/packages/conda/search.go
+++ b/models/packages/conda/search.go
@@ -7,9 +7,9 @@ import (
"context"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/packages"
- conda_module "code.gitea.io/gitea/modules/packages/conda"
+ "forgejo.org/models/db"
+ "forgejo.org/models/packages"
+ conda_module "forgejo.org/modules/packages/conda"
"xorm.io/builder"
)
diff --git a/models/packages/container/search.go b/models/packages/container/search.go
index 5df35117ce..1dab7c7b79 100644
--- a/models/packages/container/search.go
+++ b/models/packages/container/search.go
@@ -8,11 +8,11 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/packages"
- user_model "code.gitea.io/gitea/models/user"
- container_module "code.gitea.io/gitea/modules/packages/container"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/packages"
+ user_model "forgejo.org/models/user"
+ container_module "forgejo.org/modules/packages/container"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/packages/cran/search.go b/models/packages/cran/search.go
index 8a8b52a35e..35525dfd55 100644
--- a/models/packages/cran/search.go
+++ b/models/packages/cran/search.go
@@ -8,9 +8,9 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/packages"
- cran_module "code.gitea.io/gitea/modules/packages/cran"
+ "forgejo.org/models/db"
+ "forgejo.org/models/packages"
+ cran_module "forgejo.org/modules/packages/cran"
"xorm.io/builder"
)
diff --git a/models/packages/debian/search.go b/models/packages/debian/search.go
index 77c4a18462..a434a06d2a 100644
--- a/models/packages/debian/search.go
+++ b/models/packages/debian/search.go
@@ -7,9 +7,10 @@ import (
"context"
"strconv"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/packages"
- debian_module "code.gitea.io/gitea/modules/packages/debian"
+ "forgejo.org/models/db"
+ "forgejo.org/models/packages"
+ debian_module "forgejo.org/modules/packages/debian"
+ "forgejo.org/modules/setting"
"xorm.io/builder"
)
@@ -76,25 +77,41 @@ func ExistPackages(ctx context.Context, opts *PackageSearchOptions) (bool, error
// SearchPackages gets the packages matching the search options
func SearchPackages(ctx context.Context, opts *PackageSearchOptions, iter func(*packages.PackageFileDescriptor)) error {
- return db.GetEngine(ctx).
- Table("package_file").
- Select("package_file.*").
- Join("INNER", "package_version", "package_version.id = package_file.version_id").
- Join("INNER", "package", "package.id = package_version.package_id").
- Where(opts.toCond()).
- Asc("package.lower_name", "package_version.created_unix").
- Iterate(new(packages.PackageFile), func(_ int, bean any) error {
- pf := bean.(*packages.PackageFile)
+ var start int
+ batchSize := setting.Database.IterateBufferSize
+ for {
+ select {
+ case <-ctx.Done():
+ return ctx.Err()
+ default:
+ beans := make([]*packages.PackageFile, 0, batchSize)
- pfd, err := packages.GetPackageFileDescriptor(ctx, pf)
- if err != nil {
+ if err := db.GetEngine(ctx).
+ Table("package_file").
+ Select("package_file.*").
+ Join("INNER", "package_version", "package_version.id = package_file.version_id").
+ Join("INNER", "package", "package.id = package_version.package_id").
+ Where(opts.toCond()).
+ Asc("package.lower_name", "package_version.created_unix").
+ Limit(batchSize, start).
+ Find(&beans); err != nil {
return err
}
+ if len(beans) == 0 {
+ return nil
+ }
+ start += len(beans)
- iter(pfd)
+ for _, bean := range beans {
+ pfd, err := packages.GetPackageFileDescriptor(ctx, bean)
+ if err != nil {
+ return err
+ }
- return nil
- })
+ iter(pfd)
+ }
+ }
+ }
}
// GetDistributions gets all available distributions
diff --git a/models/packages/debian/search_test.go b/models/packages/debian/search_test.go
new file mode 100644
index 0000000000..b8ed98d8fa
--- /dev/null
+++ b/models/packages/debian/search_test.go
@@ -0,0 +1,94 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package debian
+
+import (
+ "strings"
+ "testing"
+
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/packages"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
+ packages_service "forgejo.org/services/packages"
+
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m)
+}
+
+func preparePackage(t *testing.T, owner *user_model.User, name string) {
+ t.Helper()
+
+ data, err := packages.CreateHashedBufferFromReader(strings.NewReader("data"))
+ require.NoError(t, err)
+
+ _, _, err = packages_service.CreatePackageOrAddFileToExisting(
+ db.DefaultContext,
+ &packages_service.PackageCreationInfo{
+ PackageInfo: packages_service.PackageInfo{
+ Owner: owner,
+ PackageType: packages_model.TypeDebian,
+ Name: name,
+ },
+ Creator: owner,
+ },
+ &packages_service.PackageFileCreationInfo{
+ PackageFileInfo: packages_service.PackageFileInfo{
+ Filename: name,
+ },
+ Data: data,
+ Creator: owner,
+ IsLead: true,
+ },
+ )
+
+ require.NoError(t, err)
+}
+
+func TestSearchPackages(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ defer test.MockVariableValue(&setting.Database.IterateBufferSize, 1)()
+
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
+
+ preparePackage(t, user2, "debian-1")
+ preparePackage(t, user2, "debian-2")
+ preparePackage(t, user3, "debian-1")
+
+ packageFiles := []string{}
+ require.NoError(t, SearchPackages(db.DefaultContext, &PackageSearchOptions{
+ OwnerID: user2.ID,
+ }, func(pfd *packages_model.PackageFileDescriptor) {
+ assert.NotNil(t, pfd)
+ packageFiles = append(packageFiles, pfd.File.Name)
+ }))
+
+ assert.Len(t, packageFiles, 2)
+ assert.Contains(t, packageFiles, "debian-1")
+ assert.Contains(t, packageFiles, "debian-2")
+
+ packageFiles = []string{}
+ require.NoError(t, SearchPackages(db.DefaultContext, &PackageSearchOptions{
+ OwnerID: user3.ID,
+ }, func(pfd *packages_model.PackageFileDescriptor) {
+ assert.NotNil(t, pfd)
+ packageFiles = append(packageFiles, pfd.File.Name)
+ }))
+
+ assert.Len(t, packageFiles, 1)
+ assert.Contains(t, packageFiles, "debian-1")
+}
diff --git a/models/packages/descriptor.go b/models/packages/descriptor.go
index b8ef698d38..19e0e8f5d5 100644
--- a/models/packages/descriptor.go
+++ b/models/packages/descriptor.go
@@ -9,29 +9,30 @@ import (
"fmt"
"net/url"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/packages/alpine"
- "code.gitea.io/gitea/modules/packages/cargo"
- "code.gitea.io/gitea/modules/packages/chef"
- "code.gitea.io/gitea/modules/packages/composer"
- "code.gitea.io/gitea/modules/packages/conan"
- "code.gitea.io/gitea/modules/packages/conda"
- "code.gitea.io/gitea/modules/packages/container"
- "code.gitea.io/gitea/modules/packages/cran"
- "code.gitea.io/gitea/modules/packages/debian"
- "code.gitea.io/gitea/modules/packages/helm"
- "code.gitea.io/gitea/modules/packages/maven"
- "code.gitea.io/gitea/modules/packages/npm"
- "code.gitea.io/gitea/modules/packages/nuget"
- "code.gitea.io/gitea/modules/packages/pub"
- "code.gitea.io/gitea/modules/packages/pypi"
- "code.gitea.io/gitea/modules/packages/rpm"
- "code.gitea.io/gitea/modules/packages/rubygems"
- "code.gitea.io/gitea/modules/packages/swift"
- "code.gitea.io/gitea/modules/packages/vagrant"
- "code.gitea.io/gitea/modules/util"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/packages/alpine"
+ "forgejo.org/modules/packages/arch"
+ "forgejo.org/modules/packages/cargo"
+ "forgejo.org/modules/packages/chef"
+ "forgejo.org/modules/packages/composer"
+ "forgejo.org/modules/packages/conan"
+ "forgejo.org/modules/packages/conda"
+ "forgejo.org/modules/packages/container"
+ "forgejo.org/modules/packages/cran"
+ "forgejo.org/modules/packages/debian"
+ "forgejo.org/modules/packages/helm"
+ "forgejo.org/modules/packages/maven"
+ "forgejo.org/modules/packages/npm"
+ "forgejo.org/modules/packages/nuget"
+ "forgejo.org/modules/packages/pub"
+ "forgejo.org/modules/packages/pypi"
+ "forgejo.org/modules/packages/rpm"
+ "forgejo.org/modules/packages/rubygems"
+ "forgejo.org/modules/packages/swift"
+ "forgejo.org/modules/packages/vagrant"
+ "forgejo.org/modules/util"
"github.com/hashicorp/go-version"
)
@@ -109,9 +110,12 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc
if err != nil {
return nil, err
}
- repository, err := repo_model.GetRepositoryByID(ctx, p.RepoID)
- if err != nil && !repo_model.IsErrRepoNotExist(err) {
- return nil, err
+ var repository *repo_model.Repository
+ if p.RepoID > 0 {
+ repository, err = repo_model.GetRepositoryByID(ctx, p.RepoID)
+ if err != nil && !repo_model.IsErrRepoNotExist(err) {
+ return nil, err
+ }
}
creator, err := user_model.GetUserByID(ctx, pv.CreatorID)
if err != nil {
@@ -150,6 +154,8 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc
switch p.Type {
case TypeAlpine:
metadata = &alpine.VersionMetadata{}
+ case TypeArch:
+ metadata = &arch.VersionMetadata{}
case TypeCargo:
metadata = &cargo.Metadata{}
case TypeChef:
@@ -184,6 +190,8 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc
metadata = &pypi.Metadata{}
case TypeRpm:
metadata = &rpm.VersionMetadata{}
+ case TypeAlt:
+ metadata = &rpm.VersionMetadata{}
case TypeRubyGems:
metadata = &rubygems.Metadata{}
case TypeSwift:
diff --git a/models/packages/main_test.go b/models/packages/main_test.go
new file mode 100644
index 0000000000..f9083d705d
--- /dev/null
+++ b/models/packages/main_test.go
@@ -0,0 +1,19 @@
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package packages
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
+)
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m)
+}
diff --git a/models/packages/nuget/search.go b/models/packages/nuget/search.go
index 7a505ff08f..af83c27c66 100644
--- a/models/packages/nuget/search.go
+++ b/models/packages/nuget/search.go
@@ -7,8 +7,8 @@ import (
"context"
"strings"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
"xorm.io/builder"
)
diff --git a/models/packages/package.go b/models/packages/package.go
index 65a2574150..3b01d0b1ea 100644
--- a/models/packages/package.go
+++ b/models/packages/package.go
@@ -1,4 +1,5 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package packages
@@ -8,10 +9,11 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/util"
"xorm.io/builder"
+ "xorm.io/xorm"
)
func init() {
@@ -31,6 +33,7 @@ type Type string
// List of supported packages
const (
TypeAlpine Type = "alpine"
+ TypeArch Type = "arch"
TypeCargo Type = "cargo"
TypeChef Type = "chef"
TypeComposer Type = "composer"
@@ -48,6 +51,7 @@ const (
TypePub Type = "pub"
TypePyPI Type = "pypi"
TypeRpm Type = "rpm"
+ TypeAlt Type = "alt"
TypeRubyGems Type = "rubygems"
TypeSwift Type = "swift"
TypeVagrant Type = "vagrant"
@@ -55,6 +59,7 @@ const (
var TypeList = []Type{
TypeAlpine,
+ TypeArch,
TypeCargo,
TypeChef,
TypeComposer,
@@ -72,6 +77,7 @@ var TypeList = []Type{
TypePub,
TypePyPI,
TypeRpm,
+ TypeAlt,
TypeRubyGems,
TypeSwift,
TypeVagrant,
@@ -82,6 +88,8 @@ func (pt Type) Name() string {
switch pt {
case TypeAlpine:
return "Alpine"
+ case TypeArch:
+ return "Arch"
case TypeCargo:
return "Cargo"
case TypeChef:
@@ -116,6 +124,8 @@ func (pt Type) Name() string {
return "PyPI"
case TypeRpm:
return "RPM"
+ case TypeAlt:
+ return "Alt"
case TypeRubyGems:
return "RubyGems"
case TypeSwift:
@@ -131,6 +141,8 @@ func (pt Type) SVGName() string {
switch pt {
case TypeAlpine:
return "gitea-alpine"
+ case TypeArch:
+ return "gitea-arch"
case TypeCargo:
return "gitea-cargo"
case TypeChef:
@@ -165,6 +177,8 @@ func (pt Type) SVGName() string {
return "gitea-python"
case TypeRpm:
return "gitea-rpm"
+ case TypeAlt:
+ return "gitea-alt"
case TypeRubyGems:
return "gitea-rubygems"
case TypeSwift:
@@ -212,13 +226,24 @@ func TryInsertPackage(ctx context.Context, p *Package) (*Package, error) {
// DeletePackageByID deletes a package by id
func DeletePackageByID(ctx context.Context, packageID int64) error {
- _, err := db.GetEngine(ctx).ID(packageID).Delete(&Package{})
+ n, err := db.GetEngine(ctx).ID(packageID).Delete(&Package{})
+ if n == 0 && err == nil {
+ return ErrPackageNotExist
+ }
return err
}
// SetRepositoryLink sets the linked repository
func SetRepositoryLink(ctx context.Context, packageID, repoID int64) error {
- _, err := db.GetEngine(ctx).ID(packageID).Cols("repo_id").Update(&Package{RepoID: repoID})
+ n, err := db.GetEngine(ctx).ID(packageID).Cols("repo_id").Update(&Package{RepoID: repoID})
+ if n == 0 && err == nil {
+ return ErrPackageNotExist
+ }
+ return err
+}
+
+func UnlinkRepository(ctx context.Context, packageID int64) error {
+ _, err := db.GetEngine(ctx).ID(packageID).Cols("repo_id").Update(&Package{RepoID: 0})
return err
}
@@ -280,34 +305,58 @@ func GetPackagesByType(ctx context.Context, ownerID int64, packageType Type) ([]
}
// FindUnreferencedPackages gets all packages without associated versions
-func FindUnreferencedPackages(ctx context.Context) ([]*Package, error) {
- in := builder.
+func FindUnreferencedPackages(ctx context.Context) ([]int64, error) {
+ var pIDs []int64
+ if err := db.GetEngine(ctx).
Select("package.id").
- From("package").
- LeftJoin("package_version", "package_version.package_id = package.id").
- Where(builder.Expr("package_version.id IS NULL"))
+ Table("package").
+ Join("LEFT", "package_version", "package_version.package_id = package.id").
+ Where("package_version.id IS NULL").
+ Find(&pIDs); err != nil {
+ return nil, err
+ }
+ return pIDs, nil
+}
- ps := make([]*Package, 0, 10)
- return ps, db.GetEngine(ctx).
- // double select workaround for MySQL
- // https://stackoverflow.com/questions/4471277/mysql-delete-from-with-subquery-as-condition
- Where(builder.In("package.id", builder.Select("id").From(in, "temp"))).
- Find(&ps)
+func getPackages(ctx context.Context) *xorm.Session {
+ return db.GetEngine(ctx).
+ Table("package_version").
+ Join("INNER", "package", "package.id = package_version.package_id").
+ Where("package_version.is_internal = ?", false)
+}
+
+func getOwnerPackages(ctx context.Context, ownerID int64) *xorm.Session {
+ return getPackages(ctx).
+ Where("package.owner_id = ?", ownerID)
}
// HasOwnerPackages tests if a user/org has accessible packages
func HasOwnerPackages(ctx context.Context, ownerID int64) (bool, error) {
- return db.GetEngine(ctx).
- Table("package_version").
- Join("INNER", "package", "package.id = package_version.package_id").
- Where(builder.Eq{
- "package_version.is_internal": false,
- "package.owner_id": ownerID,
- }).
- Exist(&PackageVersion{})
+ return getOwnerPackages(ctx, ownerID).
+ Exist(&Package{})
+}
+
+// CountOwnerPackages counts user/org accessible packages
+func CountOwnerPackages(ctx context.Context, ownerID int64) (int64, error) {
+ return getOwnerPackages(ctx, ownerID).
+ Distinct("package.id").
+ Count(&Package{})
+}
+
+func getRepositoryPackages(ctx context.Context, repositoryID int64) *xorm.Session {
+ return getPackages(ctx).
+ Where("package.repo_id = ?", repositoryID)
}
// HasRepositoryPackages tests if a repository has packages
func HasRepositoryPackages(ctx context.Context, repositoryID int64) (bool, error) {
- return db.GetEngine(ctx).Where("repo_id = ?", repositoryID).Exist(&Package{})
+ return getRepositoryPackages(ctx, repositoryID).
+ Exist(&PackageVersion{})
+}
+
+// CountRepositoryPackages counts packages of a repository
+func CountRepositoryPackages(ctx context.Context, repositoryID int64) (int64, error) {
+ return getRepositoryPackages(ctx, repositoryID).
+ Distinct("package.id").
+ Count(&Package{})
}
diff --git a/models/packages/package_blob.go b/models/packages/package_blob.go
index d9c30b6533..0de4434ef8 100644
--- a/models/packages/package_blob.go
+++ b/models/packages/package_blob.go
@@ -8,13 +8,13 @@ import (
"strconv"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -34,6 +34,7 @@ type PackageBlob struct {
HashSHA1 string `xorm:"hash_sha1 char(40) UNIQUE(sha1) INDEX NOT NULL"`
HashSHA256 string `xorm:"hash_sha256 char(64) UNIQUE(sha256) INDEX NOT NULL"`
HashSHA512 string `xorm:"hash_sha512 char(128) UNIQUE(sha512) INDEX NOT NULL"`
+ HashBlake2b string `xorm:"hash_blake2b char(128) UNIQUE(blake2b) INDEX"`
CreatedUnix timeutil.TimeStamp `xorm:"created INDEX NOT NULL"`
}
@@ -43,13 +44,19 @@ func GetOrInsertBlob(ctx context.Context, pb *PackageBlob) (*PackageBlob, bool,
existing := &PackageBlob{}
- has, err := e.Where(builder.Eq{
- "size": pb.Size,
- "hash_md5": pb.HashMD5,
- "hash_sha1": pb.HashSHA1,
- "hash_sha256": pb.HashSHA256,
- "hash_sha512": pb.HashSHA512,
- }).Get(existing)
+ has, err := e.Where(builder.And(
+ builder.Eq{
+ "size": pb.Size,
+ "hash_md5": pb.HashMD5,
+ "hash_sha1": pb.HashSHA1,
+ "hash_sha256": pb.HashSHA256,
+ "hash_sha512": pb.HashSHA512,
+ },
+ builder.Or(
+ builder.Eq{"hash_blake2b": pb.HashBlake2b},
+ builder.IsNull{"hash_blake2b"},
+ ),
+ )).Get(existing)
if err != nil {
return nil, false, err
}
diff --git a/models/packages/package_blob_test.go b/models/packages/package_blob_test.go
new file mode 100644
index 0000000000..664dfa4d81
--- /dev/null
+++ b/models/packages/package_blob_test.go
@@ -0,0 +1,64 @@
+// Copyright 2025 The Forgejo Authors.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package packages
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestPackagesGetOrInsertBlob(t *testing.T) {
+ defer unittest.OverrideFixtures("models/fixtures/TestPackagesGetOrInsertBlob")()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ blake2bIsSet := unittest.AssertExistsAndLoadBean(t, &PackageBlob{ID: 1})
+ blake2bNotSet := unittest.AssertExistsAndLoadBean(t, &PackageBlob{ID: 2})
+
+ blake2bSetToRandom := *blake2bNotSet
+ blake2bSetToRandom.HashBlake2b = "SOMETHING RANDOM"
+
+ for _, testCase := range []struct {
+ name string
+ exists bool
+ packageBlob *PackageBlob
+ }{
+ {
+ name: "exists and blake2b is not null in the database",
+ exists: true,
+ packageBlob: blake2bIsSet,
+ },
+ {
+ name: "exists and blake2b is null in the database",
+ exists: true,
+ packageBlob: &blake2bSetToRandom,
+ },
+ {
+ name: "does not exists",
+ exists: false,
+ packageBlob: &PackageBlob{
+ Size: 30,
+ HashMD5: "HASHMD5_3",
+ HashSHA1: "HASHSHA1_3",
+ HashSHA256: "HASHSHA256_3",
+ HashSHA512: "HASHSHA512_3",
+ HashBlake2b: "HASHBLAKE2B_3",
+ },
+ },
+ } {
+ t.Run(testCase.name, func(t *testing.T) {
+ found, has, _ := GetOrInsertBlob(t.Context(), testCase.packageBlob)
+ assert.Equal(t, testCase.exists, has)
+ require.NotNil(t, found)
+ if testCase.exists {
+ assert.Equal(t, found.ID, testCase.packageBlob.ID)
+ } else {
+ unittest.BeanExists(t, &PackageBlob{ID: found.ID})
+ }
+ })
+ }
+}
diff --git a/models/packages/package_blob_upload.go b/models/packages/package_blob_upload.go
index 4b0e789221..ddffb6c305 100644
--- a/models/packages/package_blob_upload.go
+++ b/models/packages/package_blob_upload.go
@@ -8,9 +8,9 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
)
// ErrPackageBlobUploadNotExist indicates a package blob upload not exist error
diff --git a/models/packages/package_cleanup_rule.go b/models/packages/package_cleanup_rule.go
index fa12dec406..d0765c8492 100644
--- a/models/packages/package_cleanup_rule.go
+++ b/models/packages/package_cleanup_rule.go
@@ -8,9 +8,9 @@ import (
"fmt"
"regexp"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/packages/package_file.go b/models/packages/package_file.go
index 1bb6b57a34..d4bcc2859a 100644
--- a/models/packages/package_file.go
+++ b/models/packages/package_file.go
@@ -9,9 +9,9 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/packages/package_property.go b/models/packages/package_property.go
index e0170016cf..c4e7be342b 100644
--- a/models/packages/package_property.go
+++ b/models/packages/package_property.go
@@ -6,7 +6,7 @@ package packages
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
"xorm.io/builder"
)
diff --git a/models/packages/package_test.go b/models/packages/package_test.go
index 7f03151e77..3c1ec413fd 100644
--- a/models/packages/package_test.go
+++ b/models/packages/package_test.go
@@ -1,4 +1,5 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package packages_test
@@ -6,62 +7,305 @@ package packages_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
-
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
-func TestMain(m *testing.M) {
- unittest.MainTest(m)
+func prepareExamplePackage(t *testing.T) *packages_model.Package {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
+
+ p0 := &packages_model.Package{
+ OwnerID: owner.ID,
+ RepoID: repo.ID,
+ LowerName: "package",
+ Type: packages_model.TypeGeneric,
+ }
+
+ p, err := packages_model.TryInsertPackage(db.DefaultContext, p0)
+ require.NotNil(t, p)
+ require.NoError(t, err)
+ require.Equal(t, *p0, *p)
+ return p
}
-func TestHasOwnerPackages(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+func deletePackage(t *testing.T, p *packages_model.Package) {
+ err := packages_model.DeletePackageByID(db.DefaultContext, p.ID)
+ require.NoError(t, err)
+}
+
+func TestTryInsertPackage(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ p0 := &packages_model.Package{
+ OwnerID: owner.ID,
+ LowerName: "package",
+ }
+
+ // Insert package should return the package and yield no error
+ p, err := packages_model.TryInsertPackage(db.DefaultContext, p0)
+ require.NotNil(t, p)
+ require.NoError(t, err)
+ require.Equal(t, *p0, *p)
+
+ // Insert same package again should return the same package and yield ErrDuplicatePackage
+ p, err = packages_model.TryInsertPackage(db.DefaultContext, p0)
+ require.NotNil(t, p)
+ require.IsType(t, packages_model.ErrDuplicatePackage, err)
+ require.Equal(t, *p0, *p)
+
+ err = packages_model.DeletePackageByID(db.DefaultContext, p0.ID)
+ require.NoError(t, err)
+}
+
+func TestGetPackageByID(t *testing.T) {
+ p0 := prepareExamplePackage(t)
+
+ // Get package should return package and yield no error
+ p, err := packages_model.GetPackageByID(db.DefaultContext, p0.ID)
+ require.NotNil(t, p)
+ require.Equal(t, *p0, *p)
+ require.NoError(t, err)
+
+ // Get package with non-existng ID should yield ErrPackageNotExist
+ p, err = packages_model.GetPackageByID(db.DefaultContext, 999)
+ require.Nil(t, p)
+ require.Error(t, err)
+ require.IsType(t, packages_model.ErrPackageNotExist, err)
+
+ deletePackage(t, p0)
+}
+
+func TestDeletePackageByID(t *testing.T) {
+ p0 := prepareExamplePackage(t)
+
+ // Delete existing package should yield no error
+ err := packages_model.DeletePackageByID(db.DefaultContext, p0.ID)
+ require.NoError(t, err)
+
+ // Delete (now) non-existing package should yield ErrPackageNotExist
+ err = packages_model.DeletePackageByID(db.DefaultContext, p0.ID)
+ require.Error(t, err)
+ require.IsType(t, packages_model.ErrPackageNotExist, err)
+}
+
+func TestSetRepositoryLink(t *testing.T) {
+ p0 := prepareExamplePackage(t)
+
+ // Set repository link to package should yield no error and package RepoID should be updated
+ err := packages_model.SetRepositoryLink(db.DefaultContext, p0.ID, 5)
+ require.NoError(t, err)
+
+ p, err := packages_model.GetPackageByID(db.DefaultContext, p0.ID)
+ require.NoError(t, err)
+ require.EqualValues(t, 5, p.RepoID)
+
+ // Set repository link to non-existing package should yied ErrPackageNotExist
+ err = packages_model.SetRepositoryLink(db.DefaultContext, 999, 5)
+ require.Error(t, err)
+ require.IsType(t, packages_model.ErrPackageNotExist, err)
+
+ deletePackage(t, p0)
+}
+
+func TestUnlinkRepositoryFromAllPackages(t *testing.T) {
+ p0 := prepareExamplePackage(t)
+
+ // Unlink repository from all packages should yield no error and package with p0.ID should have RepoID 0
+ err := packages_model.UnlinkRepositoryFromAllPackages(db.DefaultContext, p0.RepoID)
+ require.NoError(t, err)
+
+ p, err := packages_model.GetPackageByID(db.DefaultContext, p0.ID)
+ require.NoError(t, err)
+ require.EqualValues(t, 0, p.RepoID)
+
+ // Unlink repository again from all packages should also yield no error
+ err = packages_model.UnlinkRepositoryFromAllPackages(db.DefaultContext, p0.RepoID)
+ require.NoError(t, err)
+
+ deletePackage(t, p0)
+}
+
+func TestGetPackageByName(t *testing.T) {
+ p0 := prepareExamplePackage(t)
+
+ // Get package should return package and yield no error
+ p, err := packages_model.GetPackageByName(db.DefaultContext, p0.OwnerID, p0.Type, p0.LowerName)
+ require.NotNil(t, p)
+ require.Equal(t, *p0, *p)
+ require.NoError(t, err)
+
+ // Get package with uppercase name should return package and yield no error
+ p, err = packages_model.GetPackageByName(db.DefaultContext, p0.OwnerID, p0.Type, "Package")
+ require.NotNil(t, p)
+ require.Equal(t, *p0, *p)
+ require.NoError(t, err)
+
+ // Get package with wrong owner ID, type or name should return no package and yield ErrPackageNotExist
+ p, err = packages_model.GetPackageByName(db.DefaultContext, 999, p0.Type, p0.LowerName)
+ require.Nil(t, p)
+ require.Error(t, err)
+ require.IsType(t, packages_model.ErrPackageNotExist, err)
+ p, err = packages_model.GetPackageByName(db.DefaultContext, p0.OwnerID, packages_model.TypeDebian, p0.LowerName)
+ require.Nil(t, p)
+ require.Error(t, err)
+ require.IsType(t, packages_model.ErrPackageNotExist, err)
+ p, err = packages_model.GetPackageByName(db.DefaultContext, p0.OwnerID, p0.Type, "package1")
+ require.Nil(t, p)
+ require.Error(t, err)
+ require.IsType(t, packages_model.ErrPackageNotExist, err)
+
+ deletePackage(t, p0)
+}
+
+func TestHasCountPackages(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
p, err := packages_model.TryInsertPackage(db.DefaultContext, &packages_model.Package{
OwnerID: owner.ID,
+ RepoID: repo.ID,
LowerName: "package",
})
- assert.NotNil(t, p)
- assert.NoError(t, err)
+ require.NotNil(t, p)
+ require.NoError(t, err)
- // A package without package versions gets automatically cleaned up and should return false
+ // A package without package versions gets automatically cleaned up and should return false for owner
has, err := packages_model.HasOwnerPackages(db.DefaultContext, owner.ID)
- assert.False(t, has)
- assert.NoError(t, err)
+ require.False(t, has)
+ require.NoError(t, err)
+ count, err := packages_model.CountOwnerPackages(db.DefaultContext, owner.ID)
+ require.EqualValues(t, 0, count)
+ require.NoError(t, err)
+
+ // A package without package versions gets automatically cleaned up and should return false for repository
+ has, err = packages_model.HasRepositoryPackages(db.DefaultContext, repo.ID)
+ require.False(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountRepositoryPackages(db.DefaultContext, repo.ID)
+ require.EqualValues(t, 0, count)
+ require.NoError(t, err)
pv, err := packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{
PackageID: p.ID,
LowerVersion: "internal",
IsInternal: true,
})
- assert.NotNil(t, pv)
- assert.NoError(t, err)
+ require.NotNil(t, pv)
+ require.NoError(t, err)
// A package with an internal package version gets automatically cleaned up and should return false
has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID)
- assert.False(t, has)
- assert.NoError(t, err)
+ require.False(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountOwnerPackages(db.DefaultContext, owner.ID)
+ require.EqualValues(t, 0, count)
+ require.NoError(t, err)
+ has, err = packages_model.HasRepositoryPackages(db.DefaultContext, repo.ID)
+ require.False(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountRepositoryPackages(db.DefaultContext, repo.ID)
+ require.EqualValues(t, 0, count)
+ require.NoError(t, err)
pv, err = packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{
PackageID: p.ID,
LowerVersion: "normal",
IsInternal: false,
})
- assert.NotNil(t, pv)
- assert.NoError(t, err)
+ require.NotNil(t, pv)
+ require.NoError(t, err)
// A package with a normal package version should return true
has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID)
- assert.True(t, has)
- assert.NoError(t, err)
+ require.True(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountOwnerPackages(db.DefaultContext, owner.ID)
+ require.EqualValues(t, 1, count)
+ require.NoError(t, err)
+ has, err = packages_model.HasRepositoryPackages(db.DefaultContext, repo.ID)
+ require.True(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountRepositoryPackages(db.DefaultContext, repo.ID)
+ require.EqualValues(t, 1, count)
+ require.NoError(t, err)
+
+ pv2, err := packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{
+ PackageID: p.ID,
+ LowerVersion: "normal2",
+ IsInternal: false,
+ })
+ require.NotNil(t, pv2)
+ require.NoError(t, err)
+
+ // A package withmultiple package versions should be counted only once
+ has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID)
+ require.True(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountOwnerPackages(db.DefaultContext, owner.ID)
+ require.EqualValues(t, 1, count)
+ require.NoError(t, err)
+ has, err = packages_model.HasRepositoryPackages(db.DefaultContext, repo.ID)
+ require.True(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountRepositoryPackages(db.DefaultContext, repo.ID)
+ require.EqualValues(t, 1, count)
+ require.NoError(t, err)
+
+ // For owner ID 0 there should be no packages
+ has, err = packages_model.HasOwnerPackages(db.DefaultContext, 0)
+ require.False(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountOwnerPackages(db.DefaultContext, 0)
+ require.EqualValues(t, 0, count)
+ require.NoError(t, err)
+
+ // For repo ID 0 there should be no packages
+ has, err = packages_model.HasRepositoryPackages(db.DefaultContext, 0)
+ require.False(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountRepositoryPackages(db.DefaultContext, 0)
+ require.EqualValues(t, 0, count)
+ require.NoError(t, err)
+
+ p1, err := packages_model.TryInsertPackage(db.DefaultContext, &packages_model.Package{
+ OwnerID: owner.ID,
+ LowerName: "package0",
+ })
+ require.NotNil(t, p1)
+ require.NoError(t, err)
+ p1v, err := packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{
+ PackageID: p1.ID,
+ LowerVersion: "normal",
+ IsInternal: false,
+ })
+ require.NotNil(t, p1v)
+ require.NoError(t, err)
+
+ // Owner owner.ID should have two packages now
+ has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID)
+ require.True(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountOwnerPackages(db.DefaultContext, owner.ID)
+ require.EqualValues(t, 2, count)
+ require.NoError(t, err)
+
+ // For repo ID 0 there should be now one package, because p1 is not assigned to a repo
+ has, err = packages_model.HasRepositoryPackages(db.DefaultContext, 0)
+ require.True(t, has)
+ require.NoError(t, err)
+ count, err = packages_model.CountRepositoryPackages(db.DefaultContext, 0)
+ require.EqualValues(t, 1, count)
+ require.NoError(t, err)
}
diff --git a/models/packages/package_version.go b/models/packages/package_version.go
index 278e8e3a86..79086ff1ad 100644
--- a/models/packages/package_version.go
+++ b/models/packages/package_version.go
@@ -8,10 +8,10 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/packages/rpm/search.go b/models/packages/rpm/search.go
index e697421b49..d4f065a89e 100644
--- a/models/packages/rpm/search.go
+++ b/models/packages/rpm/search.go
@@ -6,8 +6,8 @@ package rpm
import (
"context"
- packages_model "code.gitea.io/gitea/models/packages"
- rpm_module "code.gitea.io/gitea/modules/packages/rpm"
+ packages_model "forgejo.org/models/packages"
+ rpm_module "forgejo.org/modules/packages/rpm"
)
// GetGroups gets all available groups
diff --git a/models/perm/access/access.go b/models/perm/access/access.go
index 3e2568b4b4..76b547f772 100644
--- a/models/perm/access/access.go
+++ b/models/perm/access/access.go
@@ -8,11 +8,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
"xorm.io/builder"
)
diff --git a/models/perm/access/access_test.go b/models/perm/access/access_test.go
index 79b131fe89..00939bced6 100644
--- a/models/perm/access/access_test.go
+++ b/models/perm/access/access_test.go
@@ -6,18 +6,19 @@ package access_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- perm_model "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ perm_model "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestAccessLevel(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
@@ -36,39 +37,39 @@ func TestAccessLevel(t *testing.T) {
repo24 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24})
level, err := access_model.AccessLevel(db.DefaultContext, user2, repo1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, perm_model.AccessModeOwner, level)
level, err = access_model.AccessLevel(db.DefaultContext, user2, repo3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, perm_model.AccessModeOwner, level)
level, err = access_model.AccessLevel(db.DefaultContext, user5, repo1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, perm_model.AccessModeRead, level)
level, err = access_model.AccessLevel(db.DefaultContext, user5, repo3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, perm_model.AccessModeNone, level)
// restricted user has no access to a public repo
level, err = access_model.AccessLevel(db.DefaultContext, user29, repo1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, perm_model.AccessModeNone, level)
// ... unless he's a collaborator
level, err = access_model.AccessLevel(db.DefaultContext, user29, repo4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, perm_model.AccessModeWrite, level)
// ... or a team member
level, err = access_model.AccessLevel(db.DefaultContext, user29, repo24)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, perm_model.AccessModeRead, level)
}
func TestHasAccess(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
@@ -80,47 +81,47 @@ func TestHasAccess(t *testing.T) {
assert.True(t, repo2.IsPrivate)
has, err := access_model.HasAccess(db.DefaultContext, user1.ID, repo1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
_, err = access_model.HasAccess(db.DefaultContext, user1.ID, repo2)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = access_model.HasAccess(db.DefaultContext, user2.ID, repo1)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = access_model.HasAccess(db.DefaultContext, user2.ID, repo2)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func TestRepository_RecalculateAccesses(t *testing.T) {
// test with organization repo
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
- assert.NoError(t, repo1.LoadOwner(db.DefaultContext))
+ require.NoError(t, repo1.LoadOwner(db.DefaultContext))
_, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 2, RepoID: 3})
- assert.NoError(t, err)
- assert.NoError(t, access_model.RecalculateAccesses(db.DefaultContext, repo1))
+ require.NoError(t, err)
+ require.NoError(t, access_model.RecalculateAccesses(db.DefaultContext, repo1))
access := &access_model.Access{UserID: 2, RepoID: 3}
has, err := db.GetEngine(db.DefaultContext).Get(access)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, has)
assert.Equal(t, perm_model.AccessModeOwner, access.Mode)
}
func TestRepository_RecalculateAccesses2(t *testing.T) {
// test with non-organization repo
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
- assert.NoError(t, repo1.LoadOwner(db.DefaultContext))
+ require.NoError(t, repo1.LoadOwner(db.DefaultContext))
_, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 4, RepoID: 4})
- assert.NoError(t, err)
- assert.NoError(t, access_model.RecalculateAccesses(db.DefaultContext, repo1))
+ require.NoError(t, err)
+ require.NoError(t, access_model.RecalculateAccesses(db.DefaultContext, repo1))
has, err := db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 4, RepoID: 4})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, has)
}
diff --git a/models/perm/access/main_test.go b/models/perm/access/main_test.go
index 0a350dc41e..0c27d022e0 100644
--- a/models/perm/access/main_test.go
+++ b/models/perm/access/main_test.go
@@ -6,13 +6,14 @@ package access_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
- _ "code.gitea.io/gitea/models/repo"
- _ "code.gitea.io/gitea/models/user"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
+ _ "forgejo.org/models/repo"
+ _ "forgejo.org/models/user"
)
func TestMain(m *testing.M) {
diff --git a/models/perm/access/repo_permission.go b/models/perm/access/repo_permission.go
index 7e39627a75..ce9963b83a 100644
--- a/models/perm/access/repo_permission.go
+++ b/models/perm/access/repo_permission.go
@@ -7,13 +7,13 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- perm_model "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ perm_model "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
)
// Permission contains all the permissions related variables to a repository for a user
diff --git a/models/project/column.go b/models/project/column.go
index 222f448599..52917cb9fd 100644
--- a/models/project/column.go
+++ b/models/project/column.go
@@ -9,10 +9,10 @@ import (
"fmt"
"regexp"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -57,20 +57,6 @@ func (Column) TableName() string {
return "project_board" // TODO: the legacy table name should be project_column
}
-// NumIssues return counter of all issues assigned to the column
-func (c *Column) NumIssues(ctx context.Context) int {
- total, err := db.GetEngine(ctx).Table("project_issue").
- Where("project_id=?", c.ProjectID).
- And("project_board_id=?", c.ID).
- GroupBy("issue_id").
- Cols("issue_id").
- Count()
- if err != nil {
- return 0
- }
- return int(total)
-}
-
func (c *Column) GetIssues(ctx context.Context) ([]*ProjectIssue, error) {
issues := make([]*ProjectIssue, 0, 5)
if err := db.GetEngine(ctx).Where("project_id=?", c.ProjectID).
@@ -305,22 +291,11 @@ func SetDefaultColumn(ctx context.Context, projectID, columnID int64) error {
})
}
-// UpdateColumnSorting update project column sorting
-func UpdateColumnSorting(ctx context.Context, cl ColumnList) error {
- return db.WithTx(ctx, func(ctx context.Context) error {
- for i := range cl {
- if _, err := db.GetEngine(ctx).ID(cl[i].ID).Cols(
- "sorting",
- ).Update(cl[i]); err != nil {
- return err
- }
- }
- return nil
- })
-}
-
func GetColumnsByIDs(ctx context.Context, projectID int64, columnsIDs []int64) (ColumnList, error) {
columns := make([]*Column, 0, 5)
+ if len(columnsIDs) == 0 {
+ return columns, nil
+ }
if err := db.GetEngine(ctx).
Where("project_id =?", projectID).
In("id", columnsIDs).
diff --git a/models/project/column_test.go b/models/project/column_test.go
index 911649fb72..2ef27de3b5 100644
--- a/models/project/column_test.go
+++ b/models/project/column_test.go
@@ -5,71 +5,71 @@ package project
import (
"fmt"
- "strings"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetDefaultColumn(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
projectWithoutDefault, err := GetProjectByID(db.DefaultContext, 5)
- assert.NoError(t, err)
+ require.NoError(t, err)
// check if default column was added
column, err := projectWithoutDefault.GetDefaultColumn(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(5), column.ProjectID)
assert.Equal(t, "Uncategorized", column.Title)
projectWithMultipleDefaults, err := GetProjectByID(db.DefaultContext, 6)
- assert.NoError(t, err)
+ require.NoError(t, err)
// check if multiple defaults were removed
column, err = projectWithMultipleDefaults.GetDefaultColumn(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(6), column.ProjectID)
assert.Equal(t, int64(9), column.ID)
// set 8 as default column
- assert.NoError(t, SetDefaultColumn(db.DefaultContext, column.ProjectID, 8))
+ require.NoError(t, SetDefaultColumn(db.DefaultContext, column.ProjectID, 8))
// then 9 will become a non-default column
column, err = GetColumn(db.DefaultContext, 9)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(6), column.ProjectID)
assert.False(t, column.Default)
}
func Test_moveIssuesToAnotherColumn(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
column1 := unittest.AssertExistsAndLoadBean(t, &Column{ID: 1, ProjectID: 1})
issues, err := column1.GetIssues(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, issues, 1)
assert.EqualValues(t, 1, issues[0].ID)
column2 := unittest.AssertExistsAndLoadBean(t, &Column{ID: 2, ProjectID: 1})
issues, err = column2.GetIssues(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, issues, 1)
assert.EqualValues(t, 3, issues[0].ID)
err = column1.moveIssuesToAnotherColumn(db.DefaultContext, column2)
- assert.NoError(t, err)
+ require.NoError(t, err)
issues, err = column1.GetIssues(db.DefaultContext)
- assert.NoError(t, err)
- assert.Len(t, issues, 0)
+ require.NoError(t, err)
+ assert.Empty(t, issues)
issues, err = column2.GetIssues(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, issues, 2)
assert.EqualValues(t, 3, issues[0].ID)
assert.EqualValues(t, 0, issues[0].Sorting)
@@ -78,11 +78,11 @@ func Test_moveIssuesToAnotherColumn(t *testing.T) {
}
func Test_MoveColumnsOnProject(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
project1 := unittest.AssertExistsAndLoadBean(t, &Project{ID: 1})
columns, err := project1.GetColumns(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, columns, 3)
assert.EqualValues(t, 0, columns[0].Sorting) // even if there is no default sorting, the code should also work
assert.EqualValues(t, 0, columns[1].Sorting)
@@ -93,10 +93,10 @@ func Test_MoveColumnsOnProject(t *testing.T) {
1: columns[2].ID,
2: columns[0].ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
columnsAfter, err := project1.GetColumns(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, columnsAfter, 3)
assert.EqualValues(t, columns[1].ID, columnsAfter[0].ID)
assert.EqualValues(t, columns[2].ID, columnsAfter[1].ID)
@@ -104,11 +104,11 @@ func Test_MoveColumnsOnProject(t *testing.T) {
}
func Test_NewColumn(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
project1 := unittest.AssertExistsAndLoadBean(t, &Project{ID: 1})
columns, err := project1.GetColumns(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, columns, 3)
for i := 0; i < maxProjectColumns-3; i++ {
@@ -116,12 +116,12 @@ func Test_NewColumn(t *testing.T) {
Title: fmt.Sprintf("column-%d", i+4),
ProjectID: project1.ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
}
err = NewColumn(db.DefaultContext, &Column{
Title: "column-21",
ProjectID: project1.ID,
})
- assert.Error(t, err)
- assert.True(t, strings.Contains(err.Error(), "maximum number of columns reached"))
+ require.Error(t, err)
+ assert.Contains(t, err.Error(), "maximum number of columns reached")
}
diff --git a/models/project/issue.go b/models/project/issue.go
index 3361b533b9..9e9db19004 100644
--- a/models/project/issue.go
+++ b/models/project/issue.go
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
// ProjectIssue saves relation from issue to a project
@@ -34,20 +34,6 @@ func deleteProjectIssuesByProjectID(ctx context.Context, projectID int64) error
return err
}
-// NumIssues return counter of all issues assigned to a project
-func (p *Project) NumIssues(ctx context.Context) int {
- c, err := db.GetEngine(ctx).Table("project_issue").
- Where("project_id=?", p.ID).
- GroupBy("issue_id").
- Cols("issue_id").
- Count()
- if err != nil {
- log.Error("NumIssues: %v", err)
- return 0
- }
- return int(c)
-}
-
// NumClosedIssues return counter of closed issues assigned to a project
func (p *Project) NumClosedIssues(ctx context.Context) int {
c, err := db.GetEngine(ctx).Table("project_issue").
diff --git a/models/project/main_test.go b/models/project/main_test.go
index f4b2d6feda..eaa13bf309 100644
--- a/models/project/main_test.go
+++ b/models/project/main_test.go
@@ -6,9 +6,9 @@ package project
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models/repo"
+ _ "forgejo.org/models/repo"
)
func TestMain(m *testing.M) {
diff --git a/models/project/project.go b/models/project/project.go
index fe5d408f64..b9813fda91 100644
--- a/models/project/project.go
+++ b/models/project/project.go
@@ -8,14 +8,14 @@ import (
"fmt"
"html/template"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -103,6 +103,13 @@ type Project struct {
ClosedDateUnix timeutil.TimeStamp
}
+// Ghost Project is a project which has been deleted
+const GhostProjectID = -1
+
+func (p *Project) IsGhost() bool {
+ return p.ID == GhostProjectID
+}
+
func (p *Project) LoadOwner(ctx context.Context) (err error) {
if p.Owner != nil {
return nil
@@ -119,6 +126,14 @@ func (p *Project) LoadRepo(ctx context.Context) (err error) {
return err
}
+func ProjectLinkForOrg(org *user_model.User, projectID int64) string { //nolint
+ return fmt.Sprintf("%s/-/projects/%d", org.HomeLink(), projectID)
+}
+
+func ProjectLinkForRepo(repo *repo_model.Repository, projectID int64) string { //nolint
+ return fmt.Sprintf("%s/projects/%d", repo.Link(), projectID)
+}
+
// Link returns the project's relative URL.
func (p *Project) Link(ctx context.Context) string {
if p.OwnerID > 0 {
@@ -127,7 +142,7 @@ func (p *Project) Link(ctx context.Context) string {
log.Error("LoadOwner: %v", err)
return ""
}
- return fmt.Sprintf("%s/-/projects/%d", p.Owner.HomeLink(), p.ID)
+ return ProjectLinkForOrg(p.Owner, p.ID)
}
if p.RepoID > 0 {
err := p.LoadRepo(ctx)
@@ -135,7 +150,7 @@ func (p *Project) Link(ctx context.Context) string {
log.Error("LoadRepo: %v", err)
return ""
}
- return fmt.Sprintf("%s/projects/%d", p.Repo.Link(), p.ID)
+ return ProjectLinkForRepo(p.Repo, p.ID)
}
return ""
}
@@ -235,6 +250,7 @@ func GetSearchOrderByBySortType(sortType string) db.SearchOrderBy {
}
// NewProject creates a new Project
+// The title will be cut off at 255 characters if it's longer than 255 characters.
func NewProject(ctx context.Context, p *Project) error {
if !IsTemplateTypeValid(p.TemplateType) {
p.TemplateType = TemplateTypeNone
@@ -248,6 +264,8 @@ func NewProject(ctx context.Context, p *Project) error {
return util.NewInvalidArgumentErrorf("project type is not valid")
}
+ p.Title, _ = util.SplitStringAtByteN(p.Title, 255)
+
return db.WithTx(ctx, func(ctx context.Context) error {
if err := db.Insert(ctx, p); err != nil {
return err
@@ -295,6 +313,7 @@ func UpdateProject(ctx context.Context, p *Project) error {
p.CardType = CardTypeTextOnly
}
+ p.Title, _ = util.SplitStringAtByteN(p.Title, 255)
_, err := db.GetEngine(ctx).ID(p.ID).Cols(
"title",
"description",
@@ -349,21 +368,6 @@ func ChangeProjectStatusByRepoIDAndID(ctx context.Context, repoID, projectID int
return committer.Commit()
}
-// ChangeProjectStatus toggle a project between opened and closed
-func ChangeProjectStatus(ctx context.Context, p *Project, isClosed bool) error {
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
-
- if err := changeProjectStatus(ctx, p, isClosed); err != nil {
- return err
- }
-
- return committer.Commit()
-}
-
func changeProjectStatus(ctx context.Context, p *Project, isClosed bool) error {
p.IsClosed = isClosed
p.ClosedDateUnix = timeutil.TimeStampNow()
diff --git a/models/project/project_test.go b/models/project/project_test.go
index dd421b4659..ee9fdaa2e2 100644
--- a/models/project/project_test.go
+++ b/models/project/project_test.go
@@ -6,11 +6,12 @@ package project
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIsProjectTypeValid(t *testing.T) {
@@ -32,23 +33,23 @@ func TestIsProjectTypeValid(t *testing.T) {
}
func TestGetProjects(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
projects, err := db.Find[Project](db.DefaultContext, SearchOptions{RepoID: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
// 1 value for this repo exists in the fixtures
assert.Len(t, projects, 1)
projects, err = db.Find[Project](db.DefaultContext, SearchOptions{RepoID: 3})
- assert.NoError(t, err)
+ require.NoError(t, err)
// 1 value for this repo exists in the fixtures
assert.Len(t, projects, 1)
}
func TestProject(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
project := &Project{
Type: TypeRepository,
@@ -60,31 +61,31 @@ func TestProject(t *testing.T) {
CreatorID: 2,
}
- assert.NoError(t, NewProject(db.DefaultContext, project))
+ require.NoError(t, NewProject(db.DefaultContext, project))
_, err := GetProjectByID(db.DefaultContext, project.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Update project
project.Title = "Updated title"
- assert.NoError(t, UpdateProject(db.DefaultContext, project))
+ require.NoError(t, UpdateProject(db.DefaultContext, project))
projectFromDB, err := GetProjectByID(db.DefaultContext, project.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, project.Title, projectFromDB.Title)
- assert.NoError(t, ChangeProjectStatus(db.DefaultContext, project, true))
+ require.NoError(t, ChangeProjectStatusByRepoIDAndID(db.DefaultContext, project.RepoID, project.ID, true))
// Retrieve from DB afresh to check if it is truly closed
projectFromDB, err = GetProjectByID(db.DefaultContext, project.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, projectFromDB.IsClosed)
}
func TestProjectsSort(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
tests := []struct {
sortType string
@@ -112,7 +113,7 @@ func TestProjectsSort(t *testing.T) {
projects, count, err := db.FindAndCount[Project](db.DefaultContext, SearchOptions{
OrderBy: GetSearchOrderByBySortType(tt.sortType),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, int64(6), count)
if assert.Len(t, projects, 6) {
for i := range projects {
diff --git a/models/pull/automerge.go b/models/pull/automerge.go
index f31159a8d8..63f572309b 100644
--- a/models/pull/automerge.go
+++ b/models/pull/automerge.go
@@ -7,21 +7,22 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
)
// AutoMerge represents a pull request scheduled for merging when checks succeed
type AutoMerge struct {
- ID int64 `xorm:"pk autoincr"`
- PullID int64 `xorm:"UNIQUE"`
- DoerID int64 `xorm:"INDEX NOT NULL"`
- Doer *user_model.User `xorm:"-"`
- MergeStyle repo_model.MergeStyle `xorm:"varchar(30)"`
- Message string `xorm:"LONGTEXT"`
- CreatedUnix timeutil.TimeStamp `xorm:"created"`
+ ID int64 `xorm:"pk autoincr"`
+ PullID int64 `xorm:"UNIQUE"`
+ DoerID int64 `xorm:"INDEX NOT NULL"`
+ Doer *user_model.User `xorm:"-"`
+ MergeStyle repo_model.MergeStyle `xorm:"varchar(30)"`
+ Message string `xorm:"LONGTEXT"`
+ DeleteBranchAfterMerge bool `xorm:"NOT NULL DEFAULT false"`
+ CreatedUnix timeutil.TimeStamp `xorm:"created"`
}
// TableName return database table name for xorm
@@ -49,7 +50,7 @@ func IsErrAlreadyScheduledToAutoMerge(err error) bool {
}
// ScheduleAutoMerge schedules a pull request to be merged when all checks succeed
-func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pullID int64, style repo_model.MergeStyle, message string) error {
+func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pullID int64, style repo_model.MergeStyle, message string, deleteBranch bool) error {
// Check if we already have a merge scheduled for that pull request
if exists, _, err := GetScheduledMergeByPullID(ctx, pullID); err != nil {
return err
@@ -58,10 +59,11 @@ func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pullID int64,
}
_, err := db.GetEngine(ctx).Insert(&AutoMerge{
- DoerID: doer.ID,
- PullID: pullID,
- MergeStyle: style,
- Message: message,
+ DoerID: doer.ID,
+ PullID: pullID,
+ MergeStyle: style,
+ Message: message,
+ DeleteBranchAfterMerge: deleteBranch,
})
return err
}
diff --git a/models/pull/review_state.go b/models/pull/review_state.go
index e46a22a49d..2702d5d5a1 100644
--- a/models/pull/review_state.go
+++ b/models/pull/review_state.go
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
)
// ViewedState stores for a file in which state it is currently viewed
diff --git a/models/quota/default.go b/models/quota/default.go
new file mode 100644
index 0000000000..9f655d7847
--- /dev/null
+++ b/models/quota/default.go
@@ -0,0 +1,25 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package quota
+
+import (
+ "forgejo.org/modules/setting"
+)
+
+func EvaluateDefault(used Used, forSubject LimitSubject) (bool, int64) {
+ groups := GroupList{
+ &Group{
+ Name: "builtin-default-group",
+ Rules: []Rule{
+ {
+ Name: "builtin-default-rule",
+ Limit: setting.Quota.Default.Total,
+ Subjects: LimitSubjects{LimitSubjectSizeAll},
+ },
+ },
+ },
+ }
+
+ return groups.Evaluate(used, forSubject)
+}
diff --git a/models/quota/errors.go b/models/quota/errors.go
new file mode 100644
index 0000000000..962c8b1cca
--- /dev/null
+++ b/models/quota/errors.go
@@ -0,0 +1,127 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package quota
+
+import "fmt"
+
+type ErrRuleAlreadyExists struct {
+ Name string
+}
+
+func IsErrRuleAlreadyExists(err error) bool {
+ _, ok := err.(ErrRuleAlreadyExists)
+ return ok
+}
+
+func (err ErrRuleAlreadyExists) Error() string {
+ return fmt.Sprintf("rule already exists: [name: %s]", err.Name)
+}
+
+type ErrRuleNotFound struct {
+ Name string
+}
+
+func IsErrRuleNotFound(err error) bool {
+ _, ok := err.(ErrRuleNotFound)
+ return ok
+}
+
+func (err ErrRuleNotFound) Error() string {
+ return fmt.Sprintf("rule not found: [name: %s]", err.Name)
+}
+
+type ErrGroupAlreadyExists struct {
+ Name string
+}
+
+func IsErrGroupAlreadyExists(err error) bool {
+ _, ok := err.(ErrGroupAlreadyExists)
+ return ok
+}
+
+func (err ErrGroupAlreadyExists) Error() string {
+ return fmt.Sprintf("group already exists: [name: %s]", err.Name)
+}
+
+type ErrGroupNotFound struct {
+ Name string
+}
+
+func IsErrGroupNotFound(err error) bool {
+ _, ok := err.(ErrGroupNotFound)
+ return ok
+}
+
+func (err ErrGroupNotFound) Error() string {
+ return fmt.Sprintf("group not found: [group: %s]", err.Name)
+}
+
+type ErrUserAlreadyInGroup struct {
+ GroupName string
+ UserID int64
+}
+
+func IsErrUserAlreadyInGroup(err error) bool {
+ _, ok := err.(ErrUserAlreadyInGroup)
+ return ok
+}
+
+func (err ErrUserAlreadyInGroup) Error() string {
+ return fmt.Sprintf("user already in group: [group: %s, userID: %d]", err.GroupName, err.UserID)
+}
+
+type ErrUserNotInGroup struct {
+ GroupName string
+ UserID int64
+}
+
+func IsErrUserNotInGroup(err error) bool {
+ _, ok := err.(ErrUserNotInGroup)
+ return ok
+}
+
+func (err ErrUserNotInGroup) Error() string {
+ return fmt.Sprintf("user not in group: [group: %s, userID: %d]", err.GroupName, err.UserID)
+}
+
+type ErrRuleAlreadyInGroup struct {
+ GroupName string
+ RuleName string
+}
+
+func IsErrRuleAlreadyInGroup(err error) bool {
+ _, ok := err.(ErrRuleAlreadyInGroup)
+ return ok
+}
+
+func (err ErrRuleAlreadyInGroup) Error() string {
+ return fmt.Sprintf("rule already in group: [group: %s, rule: %s]", err.GroupName, err.RuleName)
+}
+
+type ErrRuleNotInGroup struct {
+ GroupName string
+ RuleName string
+}
+
+func IsErrRuleNotInGroup(err error) bool {
+ _, ok := err.(ErrRuleNotInGroup)
+ return ok
+}
+
+func (err ErrRuleNotInGroup) Error() string {
+ return fmt.Sprintf("rule not in group: [group: %s, rule: %s]", err.GroupName, err.RuleName)
+}
+
+type ErrParseLimitSubjectUnrecognized struct {
+ Subject string
+}
+
+func IsErrParseLimitSubjectUnrecognized(err error) bool {
+ _, ok := err.(ErrParseLimitSubjectUnrecognized)
+ return ok
+}
+
+func (err ErrParseLimitSubjectUnrecognized) Error() string {
+ return fmt.Sprintf("unrecognized quota limit subject: [subject: %s]", err.Subject)
+}
diff --git a/models/quota/group.go b/models/quota/group.go
new file mode 100644
index 0000000000..7ddc20b2d6
--- /dev/null
+++ b/models/quota/group.go
@@ -0,0 +1,410 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package quota
+
+import (
+ "context"
+ "math"
+
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+
+ "xorm.io/builder"
+)
+
+type (
+ GroupList []*Group
+ Group struct {
+ // Name of the quota group
+ Name string `json:"name" xorm:"pk NOT NULL" binding:"Required"`
+ Rules []Rule `json:"rules" xorm:"-"`
+ }
+)
+
+type GroupRuleMapping struct {
+ ID int64 `xorm:"pk autoincr" json:"-"`
+ GroupName string `xorm:"index unique(qgrm_gr) not null" json:"group_name"`
+ RuleName string `xorm:"unique(qgrm_gr) not null" json:"rule_name"`
+}
+
+type Kind int
+
+const (
+ KindUser Kind = iota
+)
+
+type GroupMapping struct {
+ ID int64 `xorm:"pk autoincr"`
+ Kind Kind `xorm:"unique(qgm_kmg) not null"`
+ MappedID int64 `xorm:"unique(qgm_kmg) not null"`
+ GroupName string `xorm:"index unique(qgm_kmg) not null"`
+}
+
+func (g *Group) TableName() string {
+ return "quota_group"
+}
+
+func (grm *GroupRuleMapping) TableName() string {
+ return "quota_group_rule_mapping"
+}
+
+func (ugm *GroupMapping) TableName() string {
+ return "quota_group_mapping"
+}
+
+func (g *Group) LoadRules(ctx context.Context) error {
+ return db.GetEngine(ctx).Select("`quota_rule`.*").
+ Table("quota_rule").
+ Join("INNER", "`quota_group_rule_mapping`", "`quota_group_rule_mapping`.rule_name = `quota_rule`.name").
+ Where("`quota_group_rule_mapping`.group_name = ?", g.Name).
+ Find(&g.Rules)
+}
+
+func (g *Group) isUserInGroup(ctx context.Context, userID int64) (bool, error) {
+ return db.GetEngine(ctx).
+ Where("kind = ? AND mapped_id = ? AND group_name = ?", KindUser, userID, g.Name).
+ Get(&GroupMapping{})
+}
+
+func (g *Group) AddUserByID(ctx context.Context, userID int64) error {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ exists, err := g.isUserInGroup(ctx, userID)
+ if err != nil {
+ return err
+ } else if exists {
+ return ErrUserAlreadyInGroup{GroupName: g.Name, UserID: userID}
+ }
+
+ _, err = db.GetEngine(ctx).Insert(&GroupMapping{
+ Kind: KindUser,
+ MappedID: userID,
+ GroupName: g.Name,
+ })
+ if err != nil {
+ return err
+ }
+ return committer.Commit()
+}
+
+func (g *Group) RemoveUserByID(ctx context.Context, userID int64) error {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ exists, err := g.isUserInGroup(ctx, userID)
+ if err != nil {
+ return err
+ } else if !exists {
+ return ErrUserNotInGroup{GroupName: g.Name, UserID: userID}
+ }
+
+ _, err = db.GetEngine(ctx).Delete(&GroupMapping{
+ Kind: KindUser,
+ MappedID: userID,
+ GroupName: g.Name,
+ })
+ if err != nil {
+ return err
+ }
+ return committer.Commit()
+}
+
+func (g *Group) isRuleInGroup(ctx context.Context, ruleName string) (bool, error) {
+ return db.GetEngine(ctx).
+ Where("group_name = ? AND rule_name = ?", g.Name, ruleName).
+ Get(&GroupRuleMapping{})
+}
+
+func (g *Group) AddRuleByName(ctx context.Context, ruleName string) error {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ exists, err := DoesRuleExist(ctx, ruleName)
+ if err != nil {
+ return err
+ } else if !exists {
+ return ErrRuleNotFound{Name: ruleName}
+ }
+
+ has, err := g.isRuleInGroup(ctx, ruleName)
+ if err != nil {
+ return err
+ } else if has {
+ return ErrRuleAlreadyInGroup{GroupName: g.Name, RuleName: ruleName}
+ }
+
+ _, err = db.GetEngine(ctx).Insert(&GroupRuleMapping{
+ GroupName: g.Name,
+ RuleName: ruleName,
+ })
+ if err != nil {
+ return err
+ }
+ return committer.Commit()
+}
+
+func (g *Group) RemoveRuleByName(ctx context.Context, ruleName string) error {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ exists, err := g.isRuleInGroup(ctx, ruleName)
+ if err != nil {
+ return err
+ } else if !exists {
+ return ErrRuleNotInGroup{GroupName: g.Name, RuleName: ruleName}
+ }
+
+ _, err = db.GetEngine(ctx).Delete(&GroupRuleMapping{
+ GroupName: g.Name,
+ RuleName: ruleName,
+ })
+ if err != nil {
+ return err
+ }
+ return committer.Commit()
+}
+
+var affectsMap = map[LimitSubject]LimitSubjects{
+ LimitSubjectSizeAll: {
+ LimitSubjectSizeReposAll,
+ LimitSubjectSizeGitLFS,
+ LimitSubjectSizeAssetsAll,
+ },
+ LimitSubjectSizeReposAll: {
+ LimitSubjectSizeReposPublic,
+ LimitSubjectSizeReposPrivate,
+ },
+ LimitSubjectSizeAssetsAll: {
+ LimitSubjectSizeAssetsAttachmentsAll,
+ LimitSubjectSizeAssetsArtifacts,
+ LimitSubjectSizeAssetsPackagesAll,
+ },
+ LimitSubjectSizeAssetsAttachmentsAll: {
+ LimitSubjectSizeAssetsAttachmentsIssues,
+ LimitSubjectSizeAssetsAttachmentsReleases,
+ },
+}
+
+// Evaluate returns whether the size used is acceptable for the topic if a rule
+// was found, and returns the smallest limit of all applicable rules or the
+// first limit found to be unacceptable for the size used.
+func (g *Group) Evaluate(used Used, forSubject LimitSubject) (bool, bool, int64) {
+ var found bool
+ foundLimit := int64(math.MaxInt64)
+ for _, rule := range g.Rules {
+ ok, has := rule.Evaluate(used, forSubject)
+ if has {
+ if !ok {
+ return false, true, rule.Limit
+ }
+ found = true
+ foundLimit = min(foundLimit, rule.Limit)
+ }
+ }
+
+ if !found {
+ // If Evaluation for forSubject did not succeed, try evaluating against
+ // subjects below
+
+ for _, subject := range affectsMap[forSubject] {
+ ok, has, limit := g.Evaluate(used, subject)
+ if has {
+ if !ok {
+ return false, true, limit
+ }
+ found = true
+ foundLimit = min(foundLimit, limit)
+ }
+ }
+ }
+
+ return true, found, foundLimit
+}
+
+// Evaluate returns if the used size is acceptable for the subject and the
+// lowest limit that is acceptable for the subject.
+func (gl *GroupList) Evaluate(used Used, forSubject LimitSubject) (bool, int64) {
+ // If there are no groups, use the configured defaults:
+ if gl == nil || len(*gl) == 0 {
+ return EvaluateDefault(used, forSubject)
+ }
+
+ for _, group := range *gl {
+ ok, has, limit := group.Evaluate(used, forSubject)
+ if has && ok {
+ return true, limit
+ }
+ }
+ return false, 0
+}
+
+func GetGroupByName(ctx context.Context, name string) (*Group, error) {
+ var group Group
+ has, err := db.GetEngine(ctx).Where("name = ?", name).Get(&group)
+ if has {
+ if err = group.LoadRules(ctx); err != nil {
+ return nil, err
+ }
+ return &group, nil
+ }
+ return nil, err
+}
+
+func ListGroups(ctx context.Context) (GroupList, error) {
+ var groups GroupList
+ err := db.GetEngine(ctx).Find(&groups)
+ return groups, err
+}
+
+func doesGroupExist(ctx context.Context, name string) (bool, error) {
+ return db.GetEngine(ctx).Where("name = ?", name).Get(&Group{})
+}
+
+func CreateGroup(ctx context.Context, name string) (*Group, error) {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer committer.Close()
+
+ exists, err := doesGroupExist(ctx, name)
+ if err != nil {
+ return nil, err
+ } else if exists {
+ return nil, ErrGroupAlreadyExists{Name: name}
+ }
+
+ group := Group{Name: name}
+ _, err = db.GetEngine(ctx).Insert(group)
+ if err != nil {
+ return nil, err
+ }
+ return &group, committer.Commit()
+}
+
+func ListUsersInGroup(ctx context.Context, name string) ([]*user_model.User, error) {
+ group, err := GetGroupByName(ctx, name)
+ if err != nil {
+ return nil, err
+ }
+
+ var users []*user_model.User
+ err = db.GetEngine(ctx).Select("`user`.*").
+ Table("user").
+ Join("INNER", "`quota_group_mapping`", "`quota_group_mapping`.mapped_id = `user`.id").
+ Where("`quota_group_mapping`.kind = ? AND `quota_group_mapping`.group_name = ?", KindUser, group.Name).
+ Find(&users)
+ return users, err
+}
+
+func DeleteGroupByName(ctx context.Context, name string) error {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ _, err = db.GetEngine(ctx).Delete(GroupMapping{
+ GroupName: name,
+ })
+ if err != nil {
+ return err
+ }
+ _, err = db.GetEngine(ctx).Delete(GroupRuleMapping{
+ GroupName: name,
+ })
+ if err != nil {
+ return err
+ }
+
+ _, err = db.GetEngine(ctx).Delete(Group{Name: name})
+ if err != nil {
+ return err
+ }
+ return committer.Commit()
+}
+
+func SetUserGroups(ctx context.Context, userID int64, groups *[]string) error {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ // First: remove the user from any groups
+ _, err = db.GetEngine(ctx).Where("kind = ? AND mapped_id = ?", KindUser, userID).Delete(GroupMapping{})
+ if err != nil {
+ return err
+ }
+
+ if groups == nil {
+ return nil
+ }
+
+ // Then add the user to each group listed
+ for _, groupName := range *groups {
+ group, err := GetGroupByName(ctx, groupName)
+ if err != nil {
+ return err
+ }
+ if group == nil {
+ return ErrGroupNotFound{Name: groupName}
+ }
+ err = group.AddUserByID(ctx, userID)
+ if err != nil {
+ return err
+ }
+ }
+
+ return committer.Commit()
+}
+
+func GetGroupsForUser(ctx context.Context, userID int64) (GroupList, error) {
+ var groups GroupList
+ err := db.GetEngine(ctx).
+ Where(builder.In("name",
+ builder.Select("group_name").
+ From("quota_group_mapping").
+ Where(builder.And(
+ builder.Eq{"kind": KindUser},
+ builder.Eq{"mapped_id": userID}),
+ ))).
+ Find(&groups)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(groups) == 0 {
+ err = db.GetEngine(ctx).Where(builder.In("name", setting.Quota.DefaultGroups)).Find(&groups)
+ if err != nil {
+ return nil, err
+ }
+ if len(groups) == 0 {
+ return nil, nil
+ }
+ }
+
+ for _, group := range groups {
+ err = group.LoadRules(ctx)
+ if err != nil {
+ return nil, err
+ }
+ }
+
+ return groups, nil
+}
diff --git a/models/quota/limit_subject.go b/models/quota/limit_subject.go
new file mode 100644
index 0000000000..4a49d33575
--- /dev/null
+++ b/models/quota/limit_subject.go
@@ -0,0 +1,69 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package quota
+
+import "fmt"
+
+type (
+ LimitSubject int
+ LimitSubjects []LimitSubject
+)
+
+const (
+ LimitSubjectNone LimitSubject = iota
+ LimitSubjectSizeAll
+ LimitSubjectSizeReposAll
+ LimitSubjectSizeReposPublic
+ LimitSubjectSizeReposPrivate
+ LimitSubjectSizeGitAll
+ LimitSubjectSizeGitLFS
+ LimitSubjectSizeAssetsAll
+ LimitSubjectSizeAssetsAttachmentsAll
+ LimitSubjectSizeAssetsAttachmentsIssues
+ LimitSubjectSizeAssetsAttachmentsReleases
+ LimitSubjectSizeAssetsArtifacts
+ LimitSubjectSizeAssetsPackagesAll
+ LimitSubjectSizeWiki
+
+ LimitSubjectFirst = LimitSubjectSizeAll
+ LimitSubjectLast = LimitSubjectSizeWiki
+)
+
+var limitSubjectRepr = map[string]LimitSubject{
+ "none": LimitSubjectNone,
+ "size:all": LimitSubjectSizeAll,
+ "size:repos:all": LimitSubjectSizeReposAll,
+ "size:repos:public": LimitSubjectSizeReposPublic,
+ "size:repos:private": LimitSubjectSizeReposPrivate,
+ "size:git:all": LimitSubjectSizeGitAll,
+ "size:git:lfs": LimitSubjectSizeGitLFS,
+ "size:assets:all": LimitSubjectSizeAssetsAll,
+ "size:assets:attachments:all": LimitSubjectSizeAssetsAttachmentsAll,
+ "size:assets:attachments:issues": LimitSubjectSizeAssetsAttachmentsIssues,
+ "size:assets:attachments:releases": LimitSubjectSizeAssetsAttachmentsReleases,
+ "size:assets:artifacts": LimitSubjectSizeAssetsArtifacts,
+ "size:assets:packages:all": LimitSubjectSizeAssetsPackagesAll,
+ "size:assets:wiki": LimitSubjectSizeWiki,
+}
+
+func (subject LimitSubject) String() string {
+ for repr, limit := range limitSubjectRepr {
+ if limit == subject {
+ return repr
+ }
+ }
+ return ""
+}
+
+func (subjects LimitSubjects) GoString() string {
+ return fmt.Sprintf("%T{%+v}", subjects, subjects)
+}
+
+func ParseLimitSubject(repr string) (LimitSubject, error) {
+ result, has := limitSubjectRepr[repr]
+ if !has {
+ return LimitSubjectNone, ErrParseLimitSubjectUnrecognized{Subject: repr}
+ }
+ return result, nil
+}
diff --git a/models/quota/main_test.go b/models/quota/main_test.go
new file mode 100644
index 0000000000..ec0a0e0013
--- /dev/null
+++ b/models/quota/main_test.go
@@ -0,0 +1,19 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package quota
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
+)
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m)
+}
diff --git a/models/quota/quota.go b/models/quota/quota.go
new file mode 100644
index 0000000000..9f1c3ca949
--- /dev/null
+++ b/models/quota/quota.go
@@ -0,0 +1,37 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package quota
+
+import (
+ "context"
+
+ "forgejo.org/models/db"
+ "forgejo.org/modules/setting"
+)
+
+func init() {
+ db.RegisterModel(new(Rule))
+ db.RegisterModel(new(Group))
+ db.RegisterModel(new(GroupRuleMapping))
+ db.RegisterModel(new(GroupMapping))
+}
+
+func EvaluateForUser(ctx context.Context, userID int64, subject LimitSubject) (bool, error) {
+ if !setting.Quota.Enabled {
+ return true, nil
+ }
+
+ groups, err := GetGroupsForUser(ctx, userID)
+ if err != nil {
+ return false, err
+ }
+
+ used, err := GetUsedForUser(ctx, userID)
+ if err != nil {
+ return false, err
+ }
+
+ acceptable, _ := groups.Evaluate(*used, subject)
+ return acceptable, nil
+}
diff --git a/models/quota/quota_group_test.go b/models/quota/quota_group_test.go
new file mode 100644
index 0000000000..7f693b391b
--- /dev/null
+++ b/models/quota/quota_group_test.go
@@ -0,0 +1,221 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package quota_test
+
+import (
+ "math"
+ "testing"
+
+ quota_model "forgejo.org/models/quota"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestQuotaGroupAllRulesMustPass(t *testing.T) {
+ unlimitedRule := quota_model.Rule{
+ Limit: -1,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+ denyRule := quota_model.Rule{
+ Limit: 0,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+ group := quota_model.Group{
+ Rules: []quota_model.Rule{
+ unlimitedRule,
+ denyRule,
+ },
+ }
+
+ used := quota_model.Used{}
+ used.Size.Repos.Public = 1024
+
+ // Within a group, *all* rules must pass. Thus, if we have a deny-all rule,
+ // and an unlimited rule, that will always fail.
+ ok, has, limit := group.Evaluate(used, quota_model.LimitSubjectSizeAll)
+ assert.True(t, has)
+ assert.False(t, ok)
+ assert.EqualValues(t, 0, limit)
+}
+
+func TestQuotaGroupRuleScenario1(t *testing.T) {
+ group := quota_model.Group{
+ Rules: []quota_model.Rule{
+ {
+ Limit: 1024,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAssetsAttachmentsReleases,
+ quota_model.LimitSubjectSizeGitLFS,
+ quota_model.LimitSubjectSizeAssetsPackagesAll,
+ },
+ },
+ {
+ Limit: 0,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeGitLFS,
+ },
+ },
+ },
+ }
+
+ used := quota_model.Used{}
+ used.Size.Assets.Attachments.Releases = 512
+ used.Size.Assets.Packages.All = 256
+ used.Size.Git.LFS = 16
+
+ ok, has, limit := group.Evaluate(used, quota_model.LimitSubjectSizeAssetsAttachmentsReleases)
+ assert.True(t, has, "size:assets:attachments:releases is covered")
+ assert.True(t, ok, "size:assets:attachments:releases passes")
+ assert.EqualValues(t, 1024, limit)
+
+ ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeAssetsPackagesAll)
+ assert.True(t, has, "size:assets:packages:all is covered")
+ assert.True(t, ok, "size:assets:packages:all passes")
+ assert.EqualValues(t, 1024, limit)
+
+ ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeGitLFS)
+ assert.True(t, has, "size:git:lfs is covered")
+ assert.False(t, ok, "size:git:lfs fails")
+ assert.EqualValues(t, 0, limit)
+
+ ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeAll)
+ assert.True(t, has, "size:all is covered")
+ assert.False(t, ok, "size:all fails")
+ assert.EqualValues(t, 0, limit)
+}
+
+func TestQuotaGroupRuleCombination(t *testing.T) {
+ repoRule := quota_model.Rule{
+ Limit: 4096,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeReposAll,
+ },
+ }
+ packagesRule := quota_model.Rule{
+ Limit: 0,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAssetsPackagesAll,
+ },
+ }
+
+ used := quota_model.Used{}
+ used.Size.Repos.Public = 1024
+ used.Size.Assets.Packages.All = 1024
+
+ group := quota_model.Group{
+ Rules: []quota_model.Rule{
+ repoRule,
+ packagesRule,
+ },
+ }
+
+ // Git LFS isn't covered by any rule
+ _, has, limit := group.Evaluate(used, quota_model.LimitSubjectSizeGitLFS)
+ assert.False(t, has)
+ assert.EqualValues(t, math.MaxInt, limit)
+
+ // repos:all is covered, and is passing
+ ok, has, limit := group.Evaluate(used, quota_model.LimitSubjectSizeReposAll)
+ assert.True(t, has)
+ assert.True(t, ok)
+ assert.EqualValues(t, 4096, limit)
+
+ // packages:all is covered, and is failing
+ ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeAssetsPackagesAll)
+ assert.True(t, has)
+ assert.False(t, ok)
+ assert.EqualValues(t, 0, limit)
+
+ // size:all is covered, and is failing (due to packages:all being over quota)
+ ok, has, limit = group.Evaluate(used, quota_model.LimitSubjectSizeAll)
+ assert.True(t, has, "size:all should be covered")
+ assert.False(t, ok, "size:all should fail")
+ assert.EqualValues(t, 0, limit)
+}
+
+func TestQuotaGroupListsRequireOnlyOnePassing(t *testing.T) {
+ unlimitedRule := quota_model.Rule{
+ Limit: -1,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+ denyRule := quota_model.Rule{
+ Limit: 0,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+
+ denyGroup := quota_model.Group{
+ Rules: []quota_model.Rule{
+ denyRule,
+ },
+ }
+ unlimitedGroup := quota_model.Group{
+ Rules: []quota_model.Rule{
+ unlimitedRule,
+ },
+ }
+
+ groups := quota_model.GroupList{&denyGroup, &unlimitedGroup}
+
+ used := quota_model.Used{}
+ used.Size.Repos.Public = 1024
+
+ // In a group list, if any group passes, the entire evaluation passes.
+ ok, limit := groups.Evaluate(used, quota_model.LimitSubjectSizeAll)
+ assert.True(t, ok)
+ assert.EqualValues(t, -1, limit)
+}
+
+func TestQuotaGroupListAllFailing(t *testing.T) {
+ denyRule := quota_model.Rule{
+ Limit: 0,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+ limitedRule := quota_model.Rule{
+ Limit: 1024,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+
+ denyGroup := quota_model.Group{
+ Rules: []quota_model.Rule{
+ denyRule,
+ },
+ }
+ limitedGroup := quota_model.Group{
+ Rules: []quota_model.Rule{
+ limitedRule,
+ },
+ }
+
+ groups := quota_model.GroupList{&denyGroup, &limitedGroup}
+
+ used := quota_model.Used{}
+ used.Size.Repos.Public = 2048
+
+ ok, limit := groups.Evaluate(used, quota_model.LimitSubjectSizeAll)
+ assert.False(t, ok)
+ assert.EqualValues(t, 0, limit)
+}
+
+func TestQuotaGroupListEmpty(t *testing.T) {
+ groups := quota_model.GroupList{}
+
+ used := quota_model.Used{}
+ used.Size.Repos.Public = 2048
+
+ ok, limit := groups.Evaluate(used, quota_model.LimitSubjectSizeAll)
+ assert.True(t, ok)
+ assert.EqualValues(t, -1, limit)
+}
diff --git a/models/quota/quota_rule_test.go b/models/quota/quota_rule_test.go
new file mode 100644
index 0000000000..59c05563f0
--- /dev/null
+++ b/models/quota/quota_rule_test.go
@@ -0,0 +1,304 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package quota_test
+
+import (
+ "testing"
+
+ quota_model "forgejo.org/models/quota"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func makeFullyUsed() quota_model.Used {
+ return quota_model.Used{
+ Size: quota_model.UsedSize{
+ Repos: quota_model.UsedSizeRepos{
+ Public: 1024,
+ Private: 1024,
+ },
+ Git: quota_model.UsedSizeGit{
+ LFS: 1024,
+ },
+ Assets: quota_model.UsedSizeAssets{
+ Attachments: quota_model.UsedSizeAssetsAttachments{
+ Issues: 1024,
+ Releases: 1024,
+ },
+ Artifacts: 1024,
+ Packages: quota_model.UsedSizeAssetsPackages{
+ All: 1024,
+ },
+ },
+ },
+ }
+}
+
+func makePartiallyUsed() quota_model.Used {
+ return quota_model.Used{
+ Size: quota_model.UsedSize{
+ Repos: quota_model.UsedSizeRepos{
+ Public: 1024,
+ },
+ Assets: quota_model.UsedSizeAssets{
+ Attachments: quota_model.UsedSizeAssetsAttachments{
+ Releases: 1024,
+ },
+ },
+ },
+ }
+}
+
+func setUsed(used quota_model.Used, subject quota_model.LimitSubject, value int64) *quota_model.Used {
+ switch subject {
+ case quota_model.LimitSubjectSizeReposPublic:
+ used.Size.Repos.Public = value
+ return &used
+ case quota_model.LimitSubjectSizeReposPrivate:
+ used.Size.Repos.Private = value
+ return &used
+ case quota_model.LimitSubjectSizeGitLFS:
+ used.Size.Git.LFS = value
+ return &used
+ case quota_model.LimitSubjectSizeAssetsAttachmentsIssues:
+ used.Size.Assets.Attachments.Issues = value
+ return &used
+ case quota_model.LimitSubjectSizeAssetsAttachmentsReleases:
+ used.Size.Assets.Attachments.Releases = value
+ return &used
+ case quota_model.LimitSubjectSizeAssetsArtifacts:
+ used.Size.Assets.Artifacts = value
+ return &used
+ case quota_model.LimitSubjectSizeAssetsPackagesAll:
+ used.Size.Assets.Packages.All = value
+ return &used
+ case quota_model.LimitSubjectSizeWiki:
+ }
+
+ return nil
+}
+
+func assertEvaluation(t *testing.T, rule quota_model.Rule, used quota_model.Used, subject quota_model.LimitSubject, expected bool) {
+ t.Helper()
+
+ t.Run(subject.String(), func(t *testing.T) {
+ ok, has := rule.Evaluate(used, subject)
+ assert.True(t, has)
+ assert.Equal(t, expected, ok)
+ })
+}
+
+func TestQuotaRuleNoEvaluation(t *testing.T) {
+ rule := quota_model.Rule{
+ Limit: 1024,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAssetsAttachmentsAll,
+ },
+ }
+ used := quota_model.Used{}
+ used.Size.Repos.Public = 4096
+
+ _, has := rule.Evaluate(used, quota_model.LimitSubjectSizeReposAll)
+
+ // We have a rule for "size:assets:attachments:all", and query for
+ // "size:repos:all". We don't cover that subject, so the evaluation returns
+ // with no rules found.
+ assert.False(t, has)
+}
+
+func TestQuotaRuleDirectEvaluation(t *testing.T) {
+ // This function is meant to test direct rule evaluation: cases where we set
+ // a rule for a subject, and we evaluate against the same subject.
+
+ runTest := func(t *testing.T, subject quota_model.LimitSubject, limit, used int64, expected bool) {
+ t.Helper()
+
+ rule := quota_model.Rule{
+ Limit: limit,
+ Subjects: quota_model.LimitSubjects{
+ subject,
+ },
+ }
+ usedObj := setUsed(quota_model.Used{}, subject, used)
+ if usedObj == nil {
+ return
+ }
+
+ assertEvaluation(t, rule, *usedObj, subject, expected)
+ }
+
+ t.Run("limit:0", func(t *testing.T) {
+ // With limit:0, nothing used is fine.
+ t.Run("used:0", func(t *testing.T) {
+ for subject := quota_model.LimitSubjectFirst; subject <= quota_model.LimitSubjectLast; subject++ {
+ runTest(t, subject, 0, 0, true)
+ }
+ })
+ // With limit:0, any usage will fail evaluation
+ t.Run("used:512", func(t *testing.T) {
+ for subject := quota_model.LimitSubjectFirst; subject <= quota_model.LimitSubjectLast; subject++ {
+ runTest(t, subject, 0, 512, false)
+ }
+ })
+ })
+
+ t.Run("limit:unlimited", func(t *testing.T) {
+ // With no limits, any usage will succeed evaluation
+ t.Run("used:512", func(t *testing.T) {
+ for subject := quota_model.LimitSubjectFirst; subject <= quota_model.LimitSubjectLast; subject++ {
+ runTest(t, subject, -1, 512, true)
+ }
+ })
+ })
+
+ t.Run("limit:1024", func(t *testing.T) {
+ // With a set limit, usage below the limit succeeds
+ t.Run("used:512", func(t *testing.T) {
+ for subject := quota_model.LimitSubjectFirst; subject <= quota_model.LimitSubjectLast; subject++ {
+ runTest(t, subject, 1024, 512, true)
+ }
+ })
+
+ // With a set limit, usage above the limit fails
+ t.Run("used:2048", func(t *testing.T) {
+ for subject := quota_model.LimitSubjectFirst; subject <= quota_model.LimitSubjectLast; subject++ {
+ runTest(t, subject, 1024, 2048, false)
+ }
+ })
+ })
+}
+
+func TestQuotaRuleCombined(t *testing.T) {
+ rule := quota_model.Rule{
+ Limit: 1024,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeGitLFS,
+ quota_model.LimitSubjectSizeAssetsAttachmentsReleases,
+ quota_model.LimitSubjectSizeAssetsPackagesAll,
+ },
+ }
+ used := quota_model.Used{
+ Size: quota_model.UsedSize{
+ Repos: quota_model.UsedSizeRepos{
+ Public: 4096,
+ },
+ Git: quota_model.UsedSizeGit{
+ LFS: 256,
+ },
+ Assets: quota_model.UsedSizeAssets{
+ Attachments: quota_model.UsedSizeAssetsAttachments{
+ Issues: 2048,
+ Releases: 256,
+ },
+ Packages: quota_model.UsedSizeAssetsPackages{
+ All: 2560,
+ },
+ },
+ },
+ }
+
+ expectationMap := map[quota_model.LimitSubject]bool{
+ quota_model.LimitSubjectSizeGitLFS: false,
+ quota_model.LimitSubjectSizeAssetsAttachmentsReleases: false,
+ quota_model.LimitSubjectSizeAssetsPackagesAll: false,
+ }
+
+ for subject := quota_model.LimitSubjectFirst; subject <= quota_model.LimitSubjectLast; subject++ {
+ t.Run(subject.String(), func(t *testing.T) {
+ evalOk, evalHas := rule.Evaluate(used, subject)
+ expected, expectedHas := expectationMap[subject]
+
+ assert.Equal(t, expectedHas, evalHas)
+ if expectedHas {
+ assert.Equal(t, expected, evalOk)
+ }
+ })
+ }
+}
+
+func TestQuotaRuleSizeAll(t *testing.T) {
+ runTests := func(t *testing.T, rule quota_model.Rule, expected bool) {
+ t.Helper()
+
+ subject := quota_model.LimitSubjectSizeAll
+
+ t.Run("used:0", func(t *testing.T) {
+ used := quota_model.Used{}
+
+ assertEvaluation(t, rule, used, subject, true)
+ })
+
+ t.Run("used:some-each", func(t *testing.T) {
+ used := makeFullyUsed()
+
+ assertEvaluation(t, rule, used, subject, expected)
+ })
+
+ t.Run("used:some", func(t *testing.T) {
+ used := makePartiallyUsed()
+
+ assertEvaluation(t, rule, used, subject, expected)
+ })
+ }
+
+ // With all limits set to 0, evaluation always fails if usage > 0
+ t.Run("rule:0", func(t *testing.T) {
+ rule := quota_model.Rule{
+ Limit: 0,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+
+ runTests(t, rule, false)
+ })
+
+ // With no limits, evaluation always succeeds
+ t.Run("rule:unlimited", func(t *testing.T) {
+ rule := quota_model.Rule{
+ Limit: -1,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+
+ runTests(t, rule, true)
+ })
+
+ // With a specific, very generous limit, evaluation succeeds if the limit isn't exhausted
+ t.Run("rule:generous", func(t *testing.T) {
+ rule := quota_model.Rule{
+ Limit: 102400,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+
+ runTests(t, rule, true)
+
+ t.Run("limit exhaustion", func(t *testing.T) {
+ used := quota_model.Used{
+ Size: quota_model.UsedSize{
+ Repos: quota_model.UsedSizeRepos{
+ Public: 204800,
+ },
+ },
+ }
+
+ assertEvaluation(t, rule, used, quota_model.LimitSubjectSizeAll, false)
+ })
+ })
+
+ // With a specific, small limit, evaluation fails
+ t.Run("rule:limited", func(t *testing.T) {
+ rule := quota_model.Rule{
+ Limit: 512,
+ Subjects: quota_model.LimitSubjects{
+ quota_model.LimitSubjectSizeAll,
+ },
+ }
+
+ runTests(t, rule, false)
+ })
+}
diff --git a/models/quota/rule.go b/models/quota/rule.go
new file mode 100644
index 0000000000..89cb57cace
--- /dev/null
+++ b/models/quota/rule.go
@@ -0,0 +1,139 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package quota
+
+import (
+ "context"
+ "slices"
+
+ "forgejo.org/models/db"
+)
+
+type Rule struct {
+ Name string `xorm:"pk not null" json:"name,omitempty"`
+ Limit int64 `xorm:"NOT NULL" binding:"Required" json:"limit"`
+ Subjects LimitSubjects `json:"subjects,omitempty"`
+}
+
+func (r *Rule) TableName() string {
+ return "quota_rule"
+}
+
+func (r Rule) Acceptable(used Used) bool {
+ if r.Limit == -1 {
+ return true
+ }
+
+ return r.Sum(used) <= r.Limit
+}
+
+func (r Rule) Sum(used Used) int64 {
+ var sum int64
+ for _, subject := range r.Subjects {
+ sum += used.CalculateFor(subject)
+ }
+ return sum
+}
+
+func (r Rule) Evaluate(used Used, forSubject LimitSubject) (bool, bool) {
+ // If there's no limit, short circuit out
+ if r.Limit == -1 {
+ return true, true
+ }
+
+ // If the rule does not cover forSubject, bail out early
+ if !slices.Contains(r.Subjects, forSubject) {
+ return false, false
+ }
+
+ return r.Sum(used) <= r.Limit, true
+}
+
+func (r *Rule) Edit(ctx context.Context, limit *int64, subjects *LimitSubjects) (*Rule, error) {
+ cols := []string{}
+
+ if limit != nil {
+ r.Limit = *limit
+ cols = append(cols, "limit")
+ }
+ if subjects != nil {
+ r.Subjects = *subjects
+ cols = append(cols, "subjects")
+ }
+
+ _, err := db.GetEngine(ctx).Where("name = ?", r.Name).Cols(cols...).Update(r)
+ return r, err
+}
+
+func GetRuleByName(ctx context.Context, name string) (*Rule, error) {
+ var rule Rule
+ has, err := db.GetEngine(ctx).Where("name = ?", name).Get(&rule)
+ if err != nil {
+ return nil, err
+ }
+ if !has {
+ return nil, nil
+ }
+ return &rule, err
+}
+
+func ListRules(ctx context.Context) ([]Rule, error) {
+ var rules []Rule
+ err := db.GetEngine(ctx).Find(&rules)
+ return rules, err
+}
+
+func DoesRuleExist(ctx context.Context, name string) (bool, error) {
+ return db.GetEngine(ctx).
+ Where("name = ?", name).
+ Get(&Rule{})
+}
+
+func CreateRule(ctx context.Context, name string, limit int64, subjects LimitSubjects) (*Rule, error) {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer committer.Close()
+
+ exists, err := DoesRuleExist(ctx, name)
+ if err != nil {
+ return nil, err
+ } else if exists {
+ return nil, ErrRuleAlreadyExists{Name: name}
+ }
+
+ rule := Rule{
+ Name: name,
+ Limit: limit,
+ Subjects: subjects,
+ }
+ _, err = db.GetEngine(ctx).Insert(rule)
+ if err != nil {
+ return nil, err
+ }
+
+ return &rule, committer.Commit()
+}
+
+func DeleteRuleByName(ctx context.Context, name string) error {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ _, err = db.GetEngine(ctx).Delete(GroupRuleMapping{
+ RuleName: name,
+ })
+ if err != nil {
+ return err
+ }
+
+ _, err = db.GetEngine(ctx).Delete(Rule{Name: name})
+ if err != nil {
+ return err
+ }
+ return committer.Commit()
+}
diff --git a/models/quota/used.go b/models/quota/used.go
new file mode 100644
index 0000000000..22815165f6
--- /dev/null
+++ b/models/quota/used.go
@@ -0,0 +1,253 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package quota
+
+import (
+ "context"
+
+ action_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ package_model "forgejo.org/models/packages"
+ repo_model "forgejo.org/models/repo"
+
+ "xorm.io/builder"
+)
+
+type Used struct {
+ Size UsedSize
+}
+
+type UsedSize struct {
+ Repos UsedSizeRepos
+ Git UsedSizeGit
+ Assets UsedSizeAssets
+}
+
+func (u UsedSize) All() int64 {
+ return u.Repos.All() + u.Git.All(u.Repos) + u.Assets.All()
+}
+
+type UsedSizeRepos struct {
+ Public int64
+ Private int64
+}
+
+func (u UsedSizeRepos) All() int64 {
+ return u.Public + u.Private
+}
+
+type UsedSizeGit struct {
+ LFS int64
+}
+
+func (u UsedSizeGit) All(r UsedSizeRepos) int64 {
+ return u.LFS + r.All()
+}
+
+type UsedSizeAssets struct {
+ Attachments UsedSizeAssetsAttachments
+ Artifacts int64
+ Packages UsedSizeAssetsPackages
+}
+
+func (u UsedSizeAssets) All() int64 {
+ return u.Attachments.All() + u.Artifacts + u.Packages.All
+}
+
+type UsedSizeAssetsAttachments struct {
+ Issues int64
+ Releases int64
+}
+
+func (u UsedSizeAssetsAttachments) All() int64 {
+ return u.Issues + u.Releases
+}
+
+type UsedSizeAssetsPackages struct {
+ All int64
+}
+
+func (u Used) CalculateFor(subject LimitSubject) int64 {
+ switch subject {
+ case LimitSubjectNone:
+ return 0
+ case LimitSubjectSizeAll:
+ return u.Size.All()
+ case LimitSubjectSizeReposAll:
+ return u.Size.Repos.All()
+ case LimitSubjectSizeReposPublic:
+ return u.Size.Repos.Public
+ case LimitSubjectSizeReposPrivate:
+ return u.Size.Repos.Private
+ case LimitSubjectSizeGitAll:
+ return u.Size.Git.All(u.Size.Repos)
+ case LimitSubjectSizeGitLFS:
+ return u.Size.Git.LFS
+ case LimitSubjectSizeAssetsAll:
+ return u.Size.Assets.All()
+ case LimitSubjectSizeAssetsAttachmentsAll:
+ return u.Size.Assets.Attachments.All()
+ case LimitSubjectSizeAssetsAttachmentsIssues:
+ return u.Size.Assets.Attachments.Issues
+ case LimitSubjectSizeAssetsAttachmentsReleases:
+ return u.Size.Assets.Attachments.Releases
+ case LimitSubjectSizeAssetsArtifacts:
+ return u.Size.Assets.Artifacts
+ case LimitSubjectSizeAssetsPackagesAll:
+ return u.Size.Assets.Packages.All
+ case LimitSubjectSizeWiki:
+ return 0
+ }
+ return 0
+}
+
+func makeUserOwnedCondition(q string, userID int64) builder.Cond {
+ switch q {
+ case "repositories", "attachments", "artifacts":
+ return builder.Eq{"`repository`.owner_id": userID}
+ case "packages":
+ return builder.Or(
+ builder.Eq{"`repository`.owner_id": userID},
+ builder.And(
+ builder.Eq{"`package`.repo_id": 0},
+ builder.Eq{"`package`.owner_id": userID},
+ ),
+ )
+ }
+ return builder.NewCond()
+}
+
+func createQueryFor(ctx context.Context, userID int64, q string) db.Engine {
+ session := db.GetEngine(ctx)
+
+ switch q {
+ case "repositories":
+ session = session.Table("repository")
+ case "attachments":
+ session = session.
+ Table("attachment").
+ Join("INNER", "`repository`", "`attachment`.repo_id = `repository`.id")
+ case "artifacts":
+ session = session.
+ Table("action_artifact").
+ Join("INNER", "`repository`", "`action_artifact`.repo_id = `repository`.id").
+ Where("`action_artifact`.status != ?", action_model.ArtifactStatusExpired)
+ case "packages":
+ session = session.
+ Table("package_version").
+ Join("INNER", "`package_file`", "`package_file`.version_id = `package_version`.id").
+ Join("INNER", "`package_blob`", "`package_file`.blob_id = `package_blob`.id").
+ Join("INNER", "`package`", "`package_version`.package_id = `package`.id").
+ Join("LEFT OUTER", "`repository`", "`package`.repo_id = `repository`.id")
+ }
+
+ return session.Where(makeUserOwnedCondition(q, userID))
+}
+
+func GetQuotaAttachmentsForUser(ctx context.Context, userID int64, opts db.ListOptions) (int64, *[]*repo_model.Attachment, error) {
+ var attachments []*repo_model.Attachment
+
+ sess := createQueryFor(ctx, userID, "attachments").
+ OrderBy("`attachment`.size DESC")
+ if opts.PageSize > 0 {
+ sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
+ }
+ count, err := sess.FindAndCount(&attachments)
+ if err != nil {
+ return 0, nil, err
+ }
+
+ return count, &attachments, nil
+}
+
+func GetQuotaPackagesForUser(ctx context.Context, userID int64, opts db.ListOptions) (int64, *[]*package_model.PackageVersion, error) {
+ var pkgs []*package_model.PackageVersion
+
+ sess := createQueryFor(ctx, userID, "packages").
+ OrderBy("`package_blob`.size DESC")
+ if opts.PageSize > 0 {
+ sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
+ }
+ count, err := sess.FindAndCount(&pkgs)
+ if err != nil {
+ return 0, nil, err
+ }
+
+ return count, &pkgs, nil
+}
+
+func GetQuotaArtifactsForUser(ctx context.Context, userID int64, opts db.ListOptions) (int64, *[]*action_model.ActionArtifact, error) {
+ var artifacts []*action_model.ActionArtifact
+
+ sess := createQueryFor(ctx, userID, "artifacts").
+ OrderBy("`action_artifact`.file_compressed_size DESC")
+ if opts.PageSize > 0 {
+ sess = sess.Limit(opts.PageSize, (opts.Page-1)*opts.PageSize)
+ }
+ count, err := sess.FindAndCount(&artifacts)
+ if err != nil {
+ return 0, nil, err
+ }
+
+ return count, &artifacts, nil
+}
+
+func GetUsedForUser(ctx context.Context, userID int64) (*Used, error) {
+ var used Used
+
+ _, err := createQueryFor(ctx, userID, "repositories").
+ Where("`repository`.is_private = ?", true).
+ Select("SUM(git_size) AS code").
+ Get(&used.Size.Repos.Private)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = createQueryFor(ctx, userID, "repositories").
+ Where("`repository`.is_private = ?", false).
+ Select("SUM(git_size) AS code").
+ Get(&used.Size.Repos.Public)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = createQueryFor(ctx, userID, "repositories").
+ Select("SUM(lfs_size) AS lfs").
+ Get(&used.Size.Git.LFS)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = createQueryFor(ctx, userID, "attachments").
+ Select("SUM(`attachment`.size) AS size").
+ Where("`attachment`.release_id != 0").
+ Get(&used.Size.Assets.Attachments.Releases)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = createQueryFor(ctx, userID, "attachments").
+ Select("SUM(`attachment`.size) AS size").
+ Where("`attachment`.release_id = 0").
+ Get(&used.Size.Assets.Attachments.Issues)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = createQueryFor(ctx, userID, "artifacts").
+ Select("SUM(file_compressed_size) AS size").
+ Get(&used.Size.Assets.Artifacts)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = createQueryFor(ctx, userID, "packages").
+ Select("SUM(package_blob.size) AS size").
+ Get(&used.Size.Assets.Packages.All)
+ if err != nil {
+ return nil, err
+ }
+
+ return &used, nil
+}
diff --git a/models/quota/used_test.go b/models/quota/used_test.go
new file mode 100644
index 0000000000..82cc5b9bcc
--- /dev/null
+++ b/models/quota/used_test.go
@@ -0,0 +1,23 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package quota
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestGetUsedForUser(t *testing.T) {
+ defer unittest.OverrideFixtures("models/fixtures/TestGetUsedForUser/")()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ used, err := GetUsedForUser(t.Context(), 5)
+ require.NoError(t, err)
+
+ assert.EqualValues(t, 4096, used.Size.Assets.Artifacts)
+}
diff --git a/models/repo.go b/models/repo.go
index 0dc8ee5df3..6f7ae25615 100644
--- a/models/repo.go
+++ b/models/repo.go
@@ -11,14 +11,16 @@ import (
_ "image/jpeg" // Needed for jpeg support
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+
+ "xorm.io/builder"
)
// Init initialize model
@@ -27,7 +29,7 @@ func Init(ctx context.Context) error {
}
type repoChecker struct {
- querySQL func(ctx context.Context) ([]map[string][]byte, error)
+ querySQL func(ctx context.Context) ([]int64, error)
correctSQL func(ctx context.Context, id int64) error
desc string
}
@@ -38,8 +40,7 @@ func repoStatsCheck(ctx context.Context, checker *repoChecker) {
log.Error("Select %s: %v", checker.desc, err)
return
}
- for _, result := range results {
- id, _ := strconv.ParseInt(string(result["id"]), 10, 64)
+ for _, id := range results {
select {
case <-ctx.Done():
log.Warn("CheckRepoStats: Cancelled before checking %s for with id=%d", checker.desc, id)
@@ -54,21 +55,23 @@ func repoStatsCheck(ctx context.Context, checker *repoChecker) {
}
}
-func StatsCorrectSQL(ctx context.Context, sql string, id int64) error {
- _, err := db.GetEngine(ctx).Exec(sql, id, id)
+func StatsCorrectSQL(ctx context.Context, sql any, ids ...any) error {
+ args := []any{sql}
+ args = append(args, ids...)
+ _, err := db.GetEngine(ctx).Exec(args...)
return err
}
func repoStatsCorrectNumWatches(ctx context.Context, id int64) error {
- return StatsCorrectSQL(ctx, "UPDATE `repository` SET num_watches=(SELECT COUNT(*) FROM `watch` WHERE repo_id=? AND mode<>2) WHERE id=?", id)
+ return StatsCorrectSQL(ctx, "UPDATE `repository` SET num_watches=(SELECT COUNT(*) FROM `watch` WHERE repo_id=? AND mode<>2) WHERE id=?", id, id)
}
func repoStatsCorrectNumStars(ctx context.Context, id int64) error {
- return StatsCorrectSQL(ctx, "UPDATE `repository` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE repo_id=?) WHERE id=?", id)
+ return StatsCorrectSQL(ctx, "UPDATE `repository` SET num_stars=(SELECT COUNT(*) FROM `star` WHERE repo_id=?) WHERE id=?", id, id)
}
func labelStatsCorrectNumIssues(ctx context.Context, id int64) error {
- return StatsCorrectSQL(ctx, "UPDATE `label` SET num_issues=(SELECT COUNT(*) FROM `issue_label` WHERE label_id=?) WHERE id=?", id)
+ return StatsCorrectSQL(ctx, "UPDATE `label` SET num_issues=(SELECT COUNT(*) FROM `issue_label` WHERE label_id=?) WHERE id=?", id, id)
}
func labelStatsCorrectNumIssuesRepo(ctx context.Context, id int64) error {
@@ -105,11 +108,11 @@ func milestoneStatsCorrectNumIssuesRepo(ctx context.Context, id int64) error {
}
func userStatsCorrectNumRepos(ctx context.Context, id int64) error {
- return StatsCorrectSQL(ctx, "UPDATE `user` SET num_repos=(SELECT COUNT(*) FROM `repository` WHERE owner_id=?) WHERE id=?", id)
+ return StatsCorrectSQL(ctx, "UPDATE `user` SET num_repos=(SELECT COUNT(*) FROM `repository` WHERE owner_id=?) WHERE id=?", id, id)
}
func repoStatsCorrectIssueNumComments(ctx context.Context, id int64) error {
- return StatsCorrectSQL(ctx, "UPDATE `issue` SET num_comments=(SELECT COUNT(*) FROM `comment` WHERE issue_id=? AND type=0) WHERE id=?", id)
+ return StatsCorrectSQL(ctx, issues_model.UpdateIssueNumCommentsBuilder(id))
}
func repoStatsCorrectNumIssues(ctx context.Context, id int64) error {
@@ -128,9 +131,12 @@ func repoStatsCorrectNumClosedPulls(ctx context.Context, id int64) error {
return repo_model.UpdateRepoIssueNumbers(ctx, id, true, true)
}
-func statsQuery(args ...any) func(context.Context) ([]map[string][]byte, error) {
- return func(ctx context.Context) ([]map[string][]byte, error) {
- return db.GetEngine(ctx).Query(args...)
+// statsQuery returns a function that queries the database for a list of IDs
+// sql could be a string or a *builder.Builder
+func statsQuery(sql any, args ...any) func(context.Context) ([]int64, error) {
+ return func(ctx context.Context) ([]int64, error) {
+ var ids []int64
+ return ids, db.GetEngine(ctx).SQL(sql, args...).Find(&ids)
}
}
@@ -201,7 +207,16 @@ func CheckRepoStats(ctx context.Context) error {
},
// Issue.NumComments
{
- statsQuery("SELECT `issue`.id FROM `issue` WHERE `issue`.num_comments!=(SELECT COUNT(*) FROM `comment` WHERE issue_id=`issue`.id AND type=0)"),
+ statsQuery(builder.Select("`issue`.id").From("`issue`").Where(
+ builder.Neq{
+ "`issue`.num_comments": builder.Select("COUNT(*)").From("`comment`").Where(
+ builder.Expr("issue_id = `issue`.id").And(
+ builder.In("type", issues_model.ConversationCountedCommentType()),
+ ),
+ ),
+ },
+ ),
+ ),
repoStatsCorrectIssueNumComments,
"issue count 'num_comments'",
},
diff --git a/models/repo/TestSearchRepositoryIDsByCondition/repository.yml b/models/repo/TestSearchRepositoryIDsByCondition/repository.yml
new file mode 100644
index 0000000000..9ce830783d
--- /dev/null
+++ b/models/repo/TestSearchRepositoryIDsByCondition/repository.yml
@@ -0,0 +1,30 @@
+-
+ id: 1001
+ owner_id: 33
+ owner_name: user33
+ lower_name: repo1001
+ name: repo1001
+ default_branch: main
+ num_watches: 0
+ num_stars: 0
+ num_forks: 0
+ num_issues: 0
+ num_closed_issues: 0
+ num_pulls: 0
+ num_closed_pulls: 0
+ num_milestones: 0
+ num_closed_milestones: 0
+ num_projects: 0
+ num_closed_projects: 0
+ is_private: false
+ is_empty: false
+ is_archived: false
+ is_mirror: false
+ status: 0
+ is_fork: false
+ fork_id: 0
+ is_template: false
+ template_id: 0
+ size: 0
+ is_fsck_enabled: true
+ close_issues_via_commit_in_any_branch: false
diff --git a/models/repo/archive_download_count.go b/models/repo/archive_download_count.go
index 31f0399d53..8e2df21198 100644
--- a/models/repo/archive_download_count.go
+++ b/models/repo/archive_download_count.go
@@ -6,9 +6,9 @@ package repo
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/git"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/git"
+ api "forgejo.org/modules/structs"
)
// RepoArchiveDownloadCount counts all archive downloads for a tag
@@ -24,7 +24,7 @@ func init() {
db.RegisterModel(new(RepoArchiveDownloadCount))
}
-// CountArchiveDownload adds one download the the given archive
+// CountArchiveDownload adds one download the given archive
func CountArchiveDownload(ctx context.Context, repoID, releaseID int64, tp git.ArchiveType) error {
updateCount, err := db.GetEngine(ctx).Where("repo_id = ?", repoID).And("release_id = ?", releaseID).And("`type` = ?", tp).Incr("count").Update(new(RepoArchiveDownloadCount))
if err != nil {
diff --git a/models/repo/archive_download_count_test.go b/models/repo/archive_download_count_test.go
index 53bdf9a1e0..0faf515284 100644
--- a/models/repo/archive_download_count_test.go
+++ b/models/repo/archive_download_count_test.go
@@ -6,17 +6,17 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/git"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestRepoArchiveDownloadCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
release, err := repo_model.GetReleaseByID(db.DefaultContext, 1)
require.NoError(t, err)
diff --git a/models/repo/archiver.go b/models/repo/archiver.go
index 3f05fcf752..2d0172a163 100644
--- a/models/repo/archiver.go
+++ b/models/repo/archiver.go
@@ -10,10 +10,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/repo/attachment.go b/models/repo/attachment.go
index 546e409de7..3bf51e80ca 100644
--- a/models/repo/attachment.go
+++ b/models/repo/attachment.go
@@ -9,11 +9,12 @@ import (
"net/url"
"path"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/validation"
)
// Attachment represent a attachment of issue/comment/release.
@@ -31,6 +32,7 @@ type Attachment struct {
NoAutoTime bool `xorm:"-"`
CreatedUnix timeutil.TimeStamp `xorm:"created"`
CustomDownloadURL string `xorm:"-"`
+ ExternalURL string
}
func init() {
@@ -59,6 +61,10 @@ func (a *Attachment) RelativePath() string {
// DownloadURL returns the download url of the attached file
func (a *Attachment) DownloadURL() string {
+ if a.ExternalURL != "" {
+ return a.ExternalURL
+ }
+
if a.CustomDownloadURL != "" {
return a.CustomDownloadURL
}
@@ -86,6 +92,23 @@ func (err ErrAttachmentNotExist) Unwrap() error {
return util.ErrNotExist
}
+type ErrInvalidExternalURL struct {
+ ExternalURL string
+}
+
+func IsErrInvalidExternalURL(err error) bool {
+ _, ok := err.(ErrInvalidExternalURL)
+ return ok
+}
+
+func (err ErrInvalidExternalURL) Error() string {
+ return fmt.Sprintf("invalid external URL: '%s'", err.ExternalURL)
+}
+
+func (err ErrInvalidExternalURL) Unwrap() error {
+ return util.ErrPermissionDenied
+}
+
// GetAttachmentByID returns attachment by given id
func GetAttachmentByID(ctx context.Context, id int64) (*Attachment, error) {
attach := &Attachment{}
@@ -196,16 +219,6 @@ func DeleteAttachments(ctx context.Context, attachments []*Attachment, remove bo
return int(cnt), nil
}
-// DeleteAttachmentsByIssue deletes all attachments associated with the given issue.
-func DeleteAttachmentsByIssue(ctx context.Context, issueID int64, remove bool) (int, error) {
- attachments, err := GetAttachmentsByIssueID(ctx, issueID)
- if err != nil {
- return 0, err
- }
-
- return DeleteAttachments(ctx, attachments, remove)
-}
-
// DeleteAttachmentsByComment deletes all attachments associated with the given comment.
func DeleteAttachmentsByComment(ctx context.Context, commentID int64, remove bool) (int, error) {
attachments, err := GetAttachmentsByCommentID(ctx, commentID)
@@ -221,12 +234,18 @@ func UpdateAttachmentByUUID(ctx context.Context, attach *Attachment, cols ...str
if attach.UUID == "" {
return fmt.Errorf("attachment uuid should be not blank")
}
+ if attach.ExternalURL != "" && !validation.IsValidExternalURL(attach.ExternalURL) {
+ return ErrInvalidExternalURL{ExternalURL: attach.ExternalURL}
+ }
_, err := db.GetEngine(ctx).Where("uuid=?", attach.UUID).Cols(cols...).Update(attach)
return err
}
// UpdateAttachment updates the given attachment in database
func UpdateAttachment(ctx context.Context, atta *Attachment) error {
+ if atta.ExternalURL != "" && !validation.IsValidExternalURL(atta.ExternalURL) {
+ return ErrInvalidExternalURL{ExternalURL: atta.ExternalURL}
+ }
sess := db.GetEngine(ctx).Cols("name", "issue_id", "release_id", "comment_id", "download_count")
if atta.ID != 0 && atta.UUID == "" {
sess = sess.ID(atta.ID)
diff --git a/models/repo/attachment_test.go b/models/repo/attachment_test.go
index c059ffd39a..23f4b3799f 100644
--- a/models/repo/attachment_test.go
+++ b/models/repo/attachment_test.go
@@ -6,67 +6,64 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIncreaseDownloadCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(0), attachment.DownloadCount)
// increase download count
err = attachment.IncreaseDownloadCount(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
attachment, err = repo_model.GetAttachmentByUUID(db.DefaultContext, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), attachment.DownloadCount)
}
func TestGetByCommentOrIssueID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// count of attachments from issue ID
attachments, err := repo_model.GetAttachmentsByIssueID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, attachments, 1)
attachments, err = repo_model.GetAttachmentsByCommentID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, attachments, 2)
}
func TestDeleteAttachments(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
- count, err := repo_model.DeleteAttachmentsByIssue(db.DefaultContext, 4, false)
- assert.NoError(t, err)
- assert.Equal(t, 2, count)
-
- count, err = repo_model.DeleteAttachmentsByComment(db.DefaultContext, 2, false)
- assert.NoError(t, err)
+ count, err := repo_model.DeleteAttachmentsByComment(db.DefaultContext, 2, false)
+ require.NoError(t, err)
assert.Equal(t, 2, count)
err = repo_model.DeleteAttachment(db.DefaultContext, &repo_model.Attachment{ID: 8}, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a18")
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, repo_model.IsErrAttachmentNotExist(err))
assert.Nil(t, attachment)
}
func TestGetAttachmentByID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
attach, err := repo_model.GetAttachmentByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", attach.UUID)
}
@@ -79,23 +76,23 @@ func TestAttachment_DownloadURL(t *testing.T) {
}
func TestUpdateAttachment(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
attach, err := repo_model.GetAttachmentByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", attach.UUID)
attach.Name = "new_name"
- assert.NoError(t, repo_model.UpdateAttachment(db.DefaultContext, attach))
+ require.NoError(t, repo_model.UpdateAttachment(db.DefaultContext, attach))
unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{Name: "new_name"})
}
func TestGetAttachmentsByUUIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
attachList, err := repo_model.GetAttachmentsByUUIDs(db.DefaultContext, []string{"a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17", "not-existing-uuid"})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, attachList, 2)
assert.Equal(t, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11", attachList[0].UUID)
assert.Equal(t, "a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a17", attachList[1].UUID)
diff --git a/models/repo/avatar.go b/models/repo/avatar.go
index 72ee938ada..a108fda62d 100644
--- a/models/repo/avatar.go
+++ b/models/repo/avatar.go
@@ -11,11 +11,11 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/avatar"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/avatar"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
)
// CustomAvatarRelativePath returns repository custom avatar file path.
diff --git a/models/repo/collaboration.go b/models/repo/collaboration.go
index cb66cb56a6..16d10d38b6 100644
--- a/models/repo/collaboration.go
+++ b/models/repo/collaboration.go
@@ -7,11 +7,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
)
diff --git a/models/repo/collaboration_test.go b/models/repo/collaboration_test.go
index 0bfe60801c..783091ba9e 100644
--- a/models/repo/collaboration_test.go
+++ b/models/repo/collaboration_test.go
@@ -6,24 +6,25 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepository_GetCollaborators(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
collaborators, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
expectedLen, err := db.GetEngine(db.DefaultContext).Count(&repo_model.Collaboration{RepoID: repoID})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, collaborators, int(expectedLen))
for _, collaborator := range collaborators {
assert.EqualValues(t, collaborator.User.ID, collaborator.Collaboration.UserID)
@@ -39,23 +40,23 @@ func TestRepository_GetCollaborators(t *testing.T) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
collaborators1, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{PageSize: 1, Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, collaborators1, 1)
collaborators2, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{PageSize: 1, Page: 2})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, collaborators2, 1)
assert.NotEqualValues(t, collaborators1[0].ID, collaborators2[0].ID)
}
func TestRepository_IsCollaborator(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID, userID int64, expected bool) {
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
actual, err := repo_model.IsCollaborator(db.DefaultContext, repo.ID, userID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, actual)
}
test(3, 2, true)
@@ -65,10 +66,10 @@ func TestRepository_IsCollaborator(t *testing.T) {
}
func TestRepository_ChangeCollaborationAccessMode(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
- assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessModeAdmin))
+ require.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessModeAdmin))
collaboration := unittest.AssertExistsAndLoadBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4})
assert.EqualValues(t, perm.AccessModeAdmin, collaboration.Mode)
@@ -76,109 +77,109 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) {
access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: repo.ID})
assert.EqualValues(t, perm.AccessModeAdmin, access.Mode)
- assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessModeAdmin))
+ require.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessModeAdmin))
- assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, unittest.NonexistentID, perm.AccessModeAdmin))
+ require.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, unittest.NonexistentID, perm.AccessModeAdmin))
// Disvard invalid input.
- assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessMode(unittest.NonexistentID)))
+ require.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessMode(unittest.NonexistentID)))
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repo.ID})
}
func TestRepository_CountCollaborators(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
count, err := db.Count[repo_model.Collaboration](db.DefaultContext, repo_model.FindCollaborationOptions{
RepoID: repo1.ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 2, count)
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 22})
count, err = db.Count[repo_model.Collaboration](db.DefaultContext, repo_model.FindCollaborationOptions{
RepoID: repo2.ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 2, count)
// Non-existent repository.
count, err = db.Count[repo_model.Collaboration](db.DefaultContext, repo_model.FindCollaborationOptions{
RepoID: unittest.NonexistentID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, count)
}
func TestRepository_IsOwnerMemberCollaborator(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
// Organisation owner.
actual, err := repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo1, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, actual)
// Team member.
actual, err = repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo1, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, actual)
// Normal user.
actual, err = repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo1, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, actual)
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
// Collaborator.
actual, err = repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo2, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, actual)
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15})
// Repository owner.
actual, err = repo_model.IsOwnerMemberCollaborator(db.DefaultContext, repo3, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, actual)
}
func TestRepo_GetCollaboration(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
// Existing collaboration.
collab, err := repo_model.GetCollaboration(db.DefaultContext, repo.ID, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, collab)
assert.EqualValues(t, 4, collab.UserID)
assert.EqualValues(t, 4, collab.RepoID)
// Non-existing collaboration.
collab, err = repo_model.GetCollaboration(db.DefaultContext, repo.ID, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Nil(t, collab)
}
func TestGetCollaboratorWithUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user16 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 16})
user15 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15})
user18 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 18})
collabs, err := repo_model.GetCollaboratorWithUser(db.DefaultContext, user16.ID, user15.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, collabs, 2)
assert.EqualValues(t, 5, collabs[0])
assert.EqualValues(t, 7, collabs[1])
collabs, err = repo_model.GetCollaboratorWithUser(db.DefaultContext, user16.ID, user18.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, collabs, 2)
assert.EqualValues(t, 6, collabs[0])
assert.EqualValues(t, 8, collabs[1])
diff --git a/models/repo/following_repo.go b/models/repo/following_repo.go
index 85b96aa147..f9b9bf5e5e 100644
--- a/models/repo/following_repo.go
+++ b/models/repo/following_repo.go
@@ -4,7 +4,7 @@
package repo
import (
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
)
// FollowingRepo represents a federated Repository Actor connected with a local Repo
diff --git a/models/repo/following_repo_test.go b/models/repo/following_repo_test.go
index d0dd0a31a7..cff125dabe 100644
--- a/models/repo/following_repo_test.go
+++ b/models/repo/following_repo_test.go
@@ -6,7 +6,7 @@ package repo
import (
"testing"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
)
func Test_FollowingRepoValidation(t *testing.T) {
diff --git a/models/repo/fork.go b/models/repo/fork.go
index 07cd31c269..ed8b488738 100644
--- a/models/repo/fork.go
+++ b/models/repo/fork.go
@@ -6,8 +6,9 @@ package repo
import (
"context"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
"xorm.io/builder"
)
@@ -54,9 +55,9 @@ func GetUserFork(ctx context.Context, repoID, userID int64) (*Repository, error)
return &forkedRepo, nil
}
-// GetForks returns all the forks of the repository
-func GetForks(ctx context.Context, repo *Repository, listOptions db.ListOptions) ([]*Repository, error) {
- sess := db.GetEngine(ctx)
+// GetForks returns all the forks of the repository that are visible to the user.
+func GetForks(ctx context.Context, repo *Repository, user *user_model.User, listOptions db.ListOptions) ([]*Repository, int64, error) {
+ sess := db.GetEngine(ctx).Where(AccessibleRepositoryCondition(user, unit.TypeInvalid))
var forks []*Repository
if listOptions.Page == 0 {
@@ -66,7 +67,8 @@ func GetForks(ctx context.Context, repo *Repository, listOptions db.ListOptions)
sess = db.SetSessionPagination(sess, &listOptions)
}
- return forks, sess.Find(&forks, &Repository{ForkID: repo.ID})
+ count, err := sess.FindAndCount(&forks, &Repository{ForkID: repo.ID})
+ return forks, count, err
}
// IncrementRepoForkNum increment repository fork number
diff --git a/models/repo/fork_test.go b/models/repo/fork_test.go
index e8dca204cc..d567081ee6 100644
--- a/models/repo/fork_test.go
+++ b/models/repo/fork_test.go
@@ -6,28 +6,29 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetUserFork(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// User13 has repo 11 forked from repo10
repo, err := repo_model.GetRepositoryByID(db.DefaultContext, 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, repo)
repo, err = repo_model.GetUserFork(db.DefaultContext, repo.ID, 13)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, repo)
repo, err = repo_model.GetRepositoryByID(db.DefaultContext, 9)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, repo)
repo, err = repo_model.GetUserFork(db.DefaultContext, repo.ID, 13)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Nil(t, repo)
}
diff --git a/models/repo/git.go b/models/repo/git.go
index 388bf86522..692176c8f6 100644
--- a/models/repo/git.go
+++ b/models/repo/git.go
@@ -6,7 +6,7 @@ package repo
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
// MergeStyle represents the approach to merge commits into base branch.
@@ -29,6 +29,15 @@ const (
MergeStyleRebaseUpdate MergeStyle = "rebase-update-only"
)
+type UpdateStyle string
+
+const (
+ // UpdateStyleMerge create merge commit to update
+ UpdateStyleMerge UpdateStyle = "merge"
+ // UpdateStyleRebase rebase to update
+ UpdateStyleRebase UpdateStyle = "rebase"
+)
+
// UpdateDefaultBranch updates the default branch
func UpdateDefaultBranch(ctx context.Context, repo *Repository) error {
_, err := db.GetEngine(ctx).ID(repo.ID).Cols("default_branch").Update(repo)
diff --git a/models/repo/issue.go b/models/repo/issue.go
index 0dd4fd5ed4..35453f109f 100644
--- a/models/repo/issue.go
+++ b/models/repo/issue.go
@@ -6,9 +6,9 @@ package repo
import (
"context"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
// ___________.__ ___________ __
diff --git a/models/repo/language_stats.go b/models/repo/language_stats.go
index 0bc0f1fb40..1b619c80cc 100644
--- a/models/repo/language_stats.go
+++ b/models/repo/language_stats.go
@@ -4,13 +4,14 @@
package repo
import (
+ "cmp"
"context"
"math"
- "sort"
+ "slices"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
"github.com/go-enry/go-enry/v2"
)
@@ -67,34 +68,37 @@ func (stats LanguageStatList) getLanguagePercentages() map[string]float32 {
return langPerc
}
-// Rounds to 1 decimal point, target should be the expected sum of percs
+// Use the quota method to round the percentages to one decimal place while
+// keeping the sum of the percentages at 100%.
func roundByLargestRemainder(percs map[string]float32, target float32) {
+ // Tracks the difference between the sum of percentage and 100%.
leftToDistribute := int(target * 10)
- keys := make([]string, 0, len(percs))
+ type key struct {
+ language string
+ remainder float64
+ }
+ keys := make([]key, 0, len(percs))
for k, v := range percs {
- percs[k] = v * 10
- floored := math.Floor(float64(percs[k]))
+ floored, frac := math.Modf(float64(v * 10))
+ percs[k] = float32(floored)
leftToDistribute -= int(floored)
- keys = append(keys, k)
+ keys = append(keys, key{language: k, remainder: frac})
}
- // Sort the keys by the largest remainder
- sort.SliceStable(keys, func(i, j int) bool {
- _, remainderI := math.Modf(float64(percs[keys[i]]))
- _, remainderJ := math.Modf(float64(percs[keys[j]]))
- return remainderI > remainderJ
+ // Sort the fractional part in an ascending order.
+ slices.SortFunc(keys, func(b, a key) int {
+ return cmp.Compare(a.remainder, b.remainder)
})
- // Increment the values in order of largest remainder
+ // As long as the sum of 100% is not reached, add 0.1% percentage.
for _, k := range keys {
- percs[k] = float32(math.Floor(float64(percs[k])))
if leftToDistribute > 0 {
- percs[k]++
+ percs[k.language]++
leftToDistribute--
}
- percs[k] /= 10
+ percs[k.language] /= 10
}
}
diff --git a/models/repo/language_stats_test.go b/models/repo/language_stats_test.go
new file mode 100644
index 0000000000..dcfaeee6c9
--- /dev/null
+++ b/models/repo/language_stats_test.go
@@ -0,0 +1,66 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package repo
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestLanguagePercentages(t *testing.T) {
+ testCases := []struct {
+ input LanguageStatList
+ output map[string]float32
+ }{
+ {
+ []*LanguageStat{{Language: "Go", Size: 500}, {Language: "Rust", Size: 501}},
+ map[string]float32{
+ "Go": 50.0,
+ "Rust": 50.0,
+ },
+ },
+ {
+ []*LanguageStat{{Language: "Go", Size: 10}, {Language: "Rust", Size: 91}},
+ map[string]float32{
+ "Go": 9.9,
+ "Rust": 90.1,
+ },
+ },
+ {
+ []*LanguageStat{{Language: "Go", Size: 1}, {Language: "Rust", Size: 2}},
+ map[string]float32{
+ "Go": 33.3,
+ "Rust": 66.7,
+ },
+ },
+ {
+ []*LanguageStat{{Language: "Go", Size: 1}, {Language: "Rust", Size: 2}, {Language: "Shell", Size: 3}, {Language: "C#", Size: 4}, {Language: "Zig", Size: 5}, {Language: "Coq", Size: 6}, {Language: "Haskell", Size: 7}},
+ map[string]float32{
+ "Go": 3.6,
+ "Rust": 7.1,
+ "Shell": 10.7,
+ "C#": 14.3,
+ "Zig": 17.9,
+ "Coq": 21.4,
+ "Haskell": 25,
+ },
+ },
+ {
+ []*LanguageStat{{Language: "Go", Size: 1000}, {Language: "PHP", Size: 1}, {Language: "Java", Size: 1}},
+ map[string]float32{
+ "Go": 99.8,
+ "other": 0.2,
+ },
+ },
+ {
+ []*LanguageStat{},
+ map[string]float32{},
+ },
+ }
+
+ for _, testCase := range testCases {
+ assert.Equal(t, testCase.output, testCase.input.getLanguagePercentages())
+ }
+}
diff --git a/models/repo/main_test.go b/models/repo/main_test.go
index b49855f2c8..9fd1cacc97 100644
--- a/models/repo/main_test.go
+++ b/models/repo/main_test.go
@@ -6,14 +6,15 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models" // register table model
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
- _ "code.gitea.io/gitea/models/perm/access" // register table model
- _ "code.gitea.io/gitea/models/repo" // register table model
- _ "code.gitea.io/gitea/models/user" // register table model
+ _ "forgejo.org/models" // register table model
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
+ _ "forgejo.org/models/perm/access" // register table model
+ _ "forgejo.org/models/repo" // register table model
+ _ "forgejo.org/models/user" // register table model
)
func TestMain(m *testing.M) {
diff --git a/models/repo/mirror.go b/models/repo/mirror.go
index be7b785612..1fe9afd8e9 100644
--- a/models/repo/mirror.go
+++ b/models/repo/mirror.go
@@ -8,10 +8,10 @@ import (
"context"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
)
// ErrMirrorNotExist mirror does not exist error
diff --git a/models/repo/pushmirror.go b/models/repo/pushmirror.go
index 3cf54facae..d6d0d1135a 100644
--- a/models/repo/pushmirror.go
+++ b/models/repo/pushmirror.go
@@ -10,13 +10,14 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/git"
- giturl "code.gitea.io/gitea/modules/git/url"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/git"
+ giturl "forgejo.org/modules/git/url"
+ "forgejo.org/modules/keying"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -32,6 +33,10 @@ type PushMirror struct {
RemoteName string
RemoteAddress string `xorm:"VARCHAR(2048)"`
+ // A keypair formatted in OpenSSH format.
+ PublicKey string `xorm:"VARCHAR(100)"`
+ PrivateKey []byte `xorm:"BLOB"`
+
SyncOnCommit bool `xorm:"NOT NULL DEFAULT true"`
Interval time.Duration
CreatedUnix timeutil.TimeStamp `xorm:"created"`
@@ -82,6 +87,29 @@ func (m *PushMirror) GetRemoteName() string {
return m.RemoteName
}
+// GetPublicKey returns a sanitized version of the public key.
+// This should only be used when displaying the public key to the user, not for actual code.
+func (m *PushMirror) GetPublicKey() string {
+ return strings.TrimSuffix(m.PublicKey, "\n")
+}
+
+// SetPrivatekey encrypts the given private key and store it in the database.
+// The ID of the push mirror must be known, so this should be done after the
+// push mirror is inserted.
+func (m *PushMirror) SetPrivatekey(ctx context.Context, privateKey []byte) error {
+ key := keying.DeriveKey(keying.ContextPushMirror)
+ m.PrivateKey = key.Encrypt(privateKey, keying.ColumnAndID("private_key", m.ID))
+
+ _, err := db.GetEngine(ctx).ID(m.ID).Cols("private_key").Update(m)
+ return err
+}
+
+// Privatekey retrieves the encrypted private key and decrypts it.
+func (m *PushMirror) Privatekey() ([]byte, error) {
+ key := keying.DeriveKey(keying.ContextPushMirror)
+ return key.Decrypt(m.PrivateKey, keying.ColumnAndID("private_key", m.ID))
+}
+
// UpdatePushMirror updates the push-mirror
func UpdatePushMirror(ctx context.Context, m *PushMirror) error {
_, err := db.GetEngine(ctx).ID(m.ID).AllCols().Update(m)
diff --git a/models/repo/pushmirror_test.go b/models/repo/pushmirror_test.go
index e19749d93a..de6c9b0a41 100644
--- a/models/repo/pushmirror_test.go
+++ b/models/repo/pushmirror_test.go
@@ -7,16 +7,17 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestPushMirrorsIterate(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
now := timeutil.TimeStampNow()
@@ -49,3 +50,30 @@ func TestPushMirrorsIterate(t *testing.T) {
return nil
})
}
+
+func TestPushMirrorPrivatekey(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ m := &repo_model.PushMirror{
+ RemoteName: "test-privatekey",
+ }
+ require.NoError(t, db.Insert(db.DefaultContext, m))
+
+ privateKey := []byte{0x00, 0x01, 0x02, 0x04, 0x08, 0x10}
+ t.Run("Set privatekey", func(t *testing.T) {
+ require.NoError(t, m.SetPrivatekey(db.DefaultContext, privateKey))
+ })
+
+ t.Run("Normal retrieval", func(t *testing.T) {
+ actualPrivateKey, err := m.Privatekey()
+ require.NoError(t, err)
+ assert.EqualValues(t, privateKey, actualPrivateKey)
+ })
+
+ t.Run("Incorrect retrieval", func(t *testing.T) {
+ m.ID++
+ actualPrivateKey, err := m.Privatekey()
+ require.Error(t, err)
+ assert.Empty(t, actualPrivateKey)
+ })
+}
diff --git a/models/repo/redirect.go b/models/repo/redirect.go
index 61789ebefa..9c44a255d0 100644
--- a/models/repo/redirect.go
+++ b/models/repo/redirect.go
@@ -8,8 +8,8 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/util"
)
// ErrRedirectNotExist represents a "RedirectNotExist" kind of error.
diff --git a/models/repo/redirect_test.go b/models/repo/redirect_test.go
index 24cf7e89fb..d84cbbed54 100644
--- a/models/repo/redirect_test.go
+++ b/models/repo/redirect_test.go
@@ -6,18 +6,19 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestLookupRedirect(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repoID, err := repo_model.LookupRedirect(db.DefaultContext, 2, "oldrepo1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, repoID)
_, err = repo_model.LookupRedirect(db.DefaultContext, unittest.NonexistentID, "doesnotexist")
@@ -26,10 +27,10 @@ func TestLookupRedirect(t *testing.T) {
func TestNewRedirect(t *testing.T) {
// redirect to a completely new name
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
- assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame"))
+ require.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame"))
unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{
OwnerID: repo.OwnerID,
@@ -45,10 +46,10 @@ func TestNewRedirect(t *testing.T) {
func TestNewRedirect2(t *testing.T) {
// redirect to previously used name
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
- assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "oldrepo1"))
+ require.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "oldrepo1"))
unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{
OwnerID: repo.OwnerID,
@@ -64,10 +65,10 @@ func TestNewRedirect2(t *testing.T) {
func TestNewRedirect3(t *testing.T) {
// redirect for a previously-unredirected repo
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
- assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame"))
+ require.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame"))
unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{
OwnerID: repo.OwnerID,
diff --git a/models/repo/release.go b/models/repo/release.go
index 075e287174..10e9bb259f 100644
--- a/models/repo/release.go
+++ b/models/repo/release.go
@@ -13,13 +13,13 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -97,13 +97,11 @@ func init() {
// LoadAttributes load repo and publisher attributes for a release
func (r *Release) LoadAttributes(ctx context.Context) error {
- var err error
- if r.Repo == nil {
- r.Repo, err = GetRepositoryByID(ctx, r.RepoID)
- if err != nil {
- return err
- }
+ err := r.LoadRepo(ctx)
+ if err != nil {
+ return err
}
+
if r.Publisher == nil {
r.Publisher, err = user_model.GetUserByID(ctx, r.PublisherID)
if err != nil {
@@ -123,6 +121,18 @@ func (r *Release) LoadAttributes(ctx context.Context) error {
return GetReleaseAttachments(ctx, r)
}
+// LoadRepo load repo attribute for release
+func (r *Release) LoadRepo(ctx context.Context) error {
+ if r.Repo != nil {
+ return nil
+ }
+
+ var err error
+ r.Repo, err = GetRepositoryByID(ctx, r.RepoID)
+
+ return err
+}
+
// LoadArchiveDownloadCount loads the download count for the source archives
func (r *Release) LoadArchiveDownloadCount(ctx context.Context) error {
var err error
@@ -130,6 +140,25 @@ func (r *Release) LoadArchiveDownloadCount(ctx context.Context) error {
return err
}
+// GetTotalDownloadCount returns the summary of all download count of files attached to the release
+func (r *Release) GetTotalDownloadCount(ctx context.Context) (int64, error) {
+ var archiveCount int64
+ if !r.HideArchiveLinks {
+ _, err := db.GetEngine(ctx).SQL("SELECT SUM(count) FROM repo_archive_download_count WHERE release_id = ?", r.ID).Get(&archiveCount)
+ if err != nil {
+ return 0, err
+ }
+ }
+
+ var attachmentCount int64
+ _, err := db.GetEngine(ctx).SQL("SELECT SUM(download_count) FROM attachment WHERE release_id = ?", r.ID).Get(&attachmentCount)
+ if err != nil {
+ return 0, err
+ }
+
+ return archiveCount + attachmentCount, nil
+}
+
// APIURL the api url for a release. release must have attributes loaded
func (r *Release) APIURL() string {
return r.Repo.APIURL() + "/releases/" + strconv.FormatInt(r.ID, 10)
@@ -160,6 +189,20 @@ func (r *Release) Link() string {
return r.Repo.Link() + "/releases/tag/" + util.PathEscapeSegments(r.TagName)
}
+// SummaryCardURL returns the absolute URL to an image providing a summary of the release
+func (r *Release) SummaryCardURL() string {
+ return fmt.Sprintf("%s/releases/summary-card/%s", r.Repo.HTMLURL(), util.PathEscapeSegments(r.TagName))
+}
+
+// DisplayName returns the name of the release
+func (r *Release) DisplayName() string {
+ if r.IsTag && r.Title == "" {
+ return r.TagName
+ }
+
+ return r.Title
+}
+
// IsReleaseExist returns true if release with given tag name already exists.
func IsReleaseExist(ctx context.Context, repoID int64, tagName string) (bool, error) {
if len(tagName) == 0 {
@@ -171,6 +214,7 @@ func IsReleaseExist(ctx context.Context, repoID int64, tagName string) (bool, er
// UpdateRelease updates all columns of a release
func UpdateRelease(ctx context.Context, rel *Release) error {
+ rel.Title, _ = util.SplitStringAtByteN(rel.Title, 255)
_, err := db.GetEngine(ctx).ID(rel.ID).AllCols().Update(rel)
return err
}
@@ -249,6 +293,7 @@ type FindReleasesOptions struct {
IsDraft optional.Option[bool]
TagNames []string
HasSha1 optional.Option[bool] // useful to find draft releases which are created with existing tags
+ Keyword string
}
func (opts FindReleasesOptions) ToConds() builder.Cond {
@@ -276,6 +321,15 @@ func (opts FindReleasesOptions) ToConds() builder.Cond {
cond = cond.And(builder.Eq{"sha1": ""})
}
}
+
+ if opts.Keyword != "" {
+ keywordCond := builder.NewCond()
+ keywordCond = keywordCond.Or(builder.Like{"lower_tag_name", strings.ToLower(opts.Keyword)})
+ keywordCond = keywordCond.Or(db.BuildCaseInsensitiveLike("title", opts.Keyword))
+ keywordCond = keywordCond.Or(db.BuildCaseInsensitiveLike("note", opts.Keyword))
+ cond = cond.And(keywordCond)
+ }
+
return cond
}
@@ -413,32 +467,6 @@ func GetReleaseAttachments(ctx context.Context, rels ...*Release) (err error) {
return err
}
-type releaseSorter struct {
- rels []*Release
-}
-
-func (rs *releaseSorter) Len() int {
- return len(rs.rels)
-}
-
-func (rs *releaseSorter) Less(i, j int) bool {
- diffNum := rs.rels[i].NumCommits - rs.rels[j].NumCommits
- if diffNum != 0 {
- return diffNum > 0
- }
- return rs.rels[i].CreatedUnix > rs.rels[j].CreatedUnix
-}
-
-func (rs *releaseSorter) Swap(i, j int) {
- rs.rels[i], rs.rels[j] = rs.rels[j], rs.rels[i]
-}
-
-// SortReleases sorts releases by number of commits and created time.
-func SortReleases(rels []*Release) {
- sorter := &releaseSorter{rels: rels}
- sort.Sort(sorter)
-}
-
// UpdateReleasesMigrationsByType updates all migrated repositories' releases from gitServiceType to replace originalAuthorID to posterID
func UpdateReleasesMigrationsByType(ctx context.Context, gitServiceType structs.GitServiceType, originalAuthorID string, posterID int64) error {
_, err := db.GetEngine(ctx).Table("release").
diff --git a/models/repo/release_list.go b/models/repo/release_list.go
new file mode 100644
index 0000000000..4ec955adf3
--- /dev/null
+++ b/models/repo/release_list.go
@@ -0,0 +1,45 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package repo
+
+import (
+ "context"
+
+ user_model "forgejo.org/models/user"
+)
+
+type ReleaseList []*Release
+
+// LoadAttributes loads the repository and publisher for the releases.
+func (r ReleaseList) LoadAttributes(ctx context.Context) error {
+ repoCache := make(map[int64]*Repository)
+ userCache := make(map[int64]*user_model.User)
+
+ for _, release := range r {
+ var err error
+ repo, ok := repoCache[release.RepoID]
+ if !ok {
+ repo, err = GetRepositoryByID(ctx, release.RepoID)
+ if err != nil {
+ return err
+ }
+ repoCache[release.RepoID] = repo
+ }
+ release.Repo = repo
+
+ publisher, ok := userCache[release.PublisherID]
+ if !ok {
+ publisher, err = user_model.GetUserByID(ctx, release.PublisherID)
+ if err != nil {
+ if !user_model.IsErrUserNotExist(err) {
+ return err
+ }
+ publisher = user_model.NewGhostUser()
+ }
+ userCache[release.PublisherID] = publisher
+ }
+ release.Publisher = publisher
+ }
+ return nil
+}
diff --git a/models/repo/release_list_test.go b/models/repo/release_list_test.go
new file mode 100644
index 0000000000..2b494cb179
--- /dev/null
+++ b/models/repo/release_list_test.go
@@ -0,0 +1,42 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package repo
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestReleaseListLoadAttributes(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ releases := ReleaseList{&Release{
+ RepoID: 1,
+ PublisherID: 1,
+ }, &Release{
+ RepoID: 2,
+ PublisherID: 2,
+ }, &Release{
+ RepoID: 1,
+ PublisherID: 2,
+ }, &Release{
+ RepoID: 2,
+ PublisherID: 1,
+ }}
+
+ require.NoError(t, releases.LoadAttributes(t.Context()))
+
+ assert.EqualValues(t, 1, releases[0].Repo.ID)
+ assert.EqualValues(t, 1, releases[0].Publisher.ID)
+ assert.EqualValues(t, 2, releases[1].Repo.ID)
+ assert.EqualValues(t, 2, releases[1].Publisher.ID)
+ assert.EqualValues(t, 1, releases[2].Repo.ID)
+ assert.EqualValues(t, 2, releases[2].Publisher.ID)
+ assert.EqualValues(t, 2, releases[3].Repo.ID)
+ assert.EqualValues(t, 1, releases[3].Publisher.ID)
+}
diff --git a/models/repo/release_test.go b/models/repo/release_test.go
index 3643bff7f1..94dbd6d9d5 100644
--- a/models/repo/release_test.go
+++ b/models/repo/release_test.go
@@ -6,14 +6,15 @@ package repo
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestMigrate_InsertReleases(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
a := &Attachment{
UUID: "a0eebc91-9c0c-4ef7-bb6e-6bb9bd380a12",
@@ -23,5 +24,28 @@ func TestMigrate_InsertReleases(t *testing.T) {
}
err := InsertReleases(db.DefaultContext, r)
- assert.NoError(t, err)
+ require.NoError(t, err)
+}
+
+func TestReleaseLoadRepo(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ release := unittest.AssertExistsAndLoadBean(t, &Release{ID: 1})
+ assert.Nil(t, release.Repo)
+
+ require.NoError(t, release.LoadRepo(db.DefaultContext))
+
+ assert.EqualValues(t, 1, release.Repo.ID)
+}
+
+func TestReleaseDisplayName(t *testing.T) {
+ release := Release{TagName: "TagName"}
+
+ assert.Empty(t, release.DisplayName())
+
+ release.IsTag = true
+ assert.Equal(t, "TagName", release.DisplayName())
+
+ release.Title = "Title"
+ assert.Equal(t, "Title", release.DisplayName())
}
diff --git a/models/repo/repo.go b/models/repo/repo.go
index 6db7c30513..8d204d5594 100644
--- a/models/repo/repo.go
+++ b/models/repo/repo.go
@@ -14,18 +14,18 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
@@ -327,6 +327,11 @@ func (repo *Repository) HTMLURL() string {
return setting.AppURL + url.PathEscape(repo.OwnerName) + "/" + url.PathEscape(repo.Name)
}
+// SummaryCardURL returns the absolute URL to an image providing a summary of the repo
+func (repo *Repository) SummaryCardURL() string {
+ return fmt.Sprintf("%s/-/summary-card", repo.HTMLURL())
+}
+
// CommitLink make link to by commit full ID
// note: won't check whether it's an right id
func (repo *Repository) CommitLink(commitID string) (result string) {
@@ -524,7 +529,6 @@ func (repo *Repository) ComposeMetas(ctx context.Context) map[string]string {
Join("INNER", "team", "team.id = team_repo.team_id").
Where("team_repo.repo_id = ?", repo.ID).
Select("team.lower_name").
- OrderBy("team.lower_name").
Find(&teams)
metas["teams"] = "," + strings.Join(teams, ",") + ","
metas["org"] = strings.ToLower(repo.OwnerName)
@@ -766,17 +770,18 @@ func GetRepositoryByOwnerAndName(ctx context.Context, ownerName, repoName string
// GetRepositoryByName returns the repository by given name under user if exists.
func GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*Repository, error) {
- repo := &Repository{
- OwnerID: ownerID,
- LowerName: strings.ToLower(name),
- }
- has, err := db.GetEngine(ctx).Get(repo)
+ var repo Repository
+ has, err := db.GetEngine(ctx).
+ Where("`owner_id`=?", ownerID).
+ And("`lower_name`=?", strings.ToLower(name)).
+ NoAutoCondition().
+ Get(&repo)
if err != nil {
return nil, err
} else if !has {
return nil, ErrRepoNotExist{0, ownerID, "", name}
}
- return repo, err
+ return &repo, err
}
// getRepositoryURLPathSegments returns segments (owner, reponame) extracted from a url
diff --git a/models/repo/repo_flags.go b/models/repo/repo_flags.go
index de76ed2b37..247a588cdf 100644
--- a/models/repo/repo_flags.go
+++ b/models/repo/repo_flags.go
@@ -6,7 +6,7 @@ package repo
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
"xorm.io/builder"
)
diff --git a/models/repo/repo_flags_test.go b/models/repo/repo_flags_test.go
index 0e4f5c1ba9..bd92b18208 100644
--- a/models/repo/repo_flags_test.go
+++ b/models/repo/repo_flags_test.go
@@ -6,15 +6,16 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepositoryFlags(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
// ********************
@@ -23,7 +24,7 @@ func TestRepositoryFlags(t *testing.T) {
// Unless we add flags, the repo has none
flags, err := repo.ListFlags(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, flags)
// If the repo has no flags, it is not flagged
@@ -36,12 +37,12 @@ func TestRepositoryFlags(t *testing.T) {
// Trying to retrieve a non-existent flag indicates not found
has, _, err = repo.GetFlag(db.DefaultContext, "foo")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, has)
// Deleting a non-existent flag fails
deleted, err := repo.DeleteFlag(db.DefaultContext, "no-such-flag")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(0), deleted)
// ********************
@@ -50,15 +51,15 @@ func TestRepositoryFlags(t *testing.T) {
// Adding a flag works
err = repo.AddFlag(db.DefaultContext, "foo")
- assert.NoError(t, err)
+ require.NoError(t, err)
// Adding it again fails
err = repo.AddFlag(db.DefaultContext, "foo")
- assert.Error(t, err)
+ require.Error(t, err)
// Listing flags includes the one we added
flags, err = repo.ListFlags(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, flags, 1)
assert.Equal(t, "foo", flags[0].Name)
@@ -72,22 +73,22 @@ func TestRepositoryFlags(t *testing.T) {
// Added flag can be retrieved
_, flag, err := repo.GetFlag(db.DefaultContext, "foo")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "foo", flag.Name)
// Deleting a flag works
deleted, err = repo.DeleteFlag(db.DefaultContext, "foo")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), deleted)
// The list is now empty
flags, err = repo.ListFlags(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, flags)
// Replacing an empty list works
err = repo.ReplaceAllFlags(db.DefaultContext, []string{"bar"})
- assert.NoError(t, err)
+ require.NoError(t, err)
// The repo is now flagged with "bar"
has = repo.HasFlag(db.DefaultContext, "bar")
@@ -95,18 +96,18 @@ func TestRepositoryFlags(t *testing.T) {
// Replacing a tag set with another works
err = repo.ReplaceAllFlags(db.DefaultContext, []string{"baz", "quux"})
- assert.NoError(t, err)
+ require.NoError(t, err)
// The repo now has two tags
flags, err = repo.ListFlags(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, flags, 2)
assert.Equal(t, "baz", flags[0].Name)
assert.Equal(t, "quux", flags[1].Name)
// Replacing flags with an empty set deletes all flags
err = repo.ReplaceAllFlags(db.DefaultContext, []string{})
- assert.NoError(t, err)
+ require.NoError(t, err)
// The repo is now unflagged
flagged = repo.IsFlagged(db.DefaultContext)
diff --git a/models/repo/repo_indexer.go b/models/repo/repo_indexer.go
index 6e19d8f937..e95517bb07 100644
--- a/models/repo/repo_indexer.go
+++ b/models/repo/repo_indexer.go
@@ -7,7 +7,7 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
"xorm.io/builder"
)
diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go
index 6cce2d33a3..ac7d2b69e3 100644
--- a/models/repo/repo_list.go
+++ b/models/repo/repo_list.go
@@ -8,24 +8,19 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
-// FindReposMapByIDs find repos as map
-func FindReposMapByIDs(ctx context.Context, repoIDs []int64, res map[int64]*Repository) error {
- return db.GetEngine(ctx).In("id", repoIDs).Find(&res)
-}
-
// RepositoryListDefaultPageSize is the default number of repositories
// to load in memory when running administrative tasks on all (or almost
// all) of them.
@@ -36,18 +31,6 @@ const RepositoryListDefaultPageSize = 64
// RepositoryList contains a list of repositories
type RepositoryList []*Repository
-func (repos RepositoryList) Len() int {
- return len(repos)
-}
-
-func (repos RepositoryList) Less(i, j int) bool {
- return repos[i].FullName() < repos[j].FullName()
-}
-
-func (repos RepositoryList) Swap(i, j int) {
- repos[i], repos[j] = repos[j], repos[i]
-}
-
// ValuesRepository converts a repository map to a list
// FIXME: Remove in favor of maps.values when MIN_GO_VERSION >= 1.18
func ValuesRepository(m map[int64]*Repository) []*Repository {
@@ -641,12 +624,9 @@ func AccessibleRepositoryCondition(user *user_model.User, unitType unit.Type) bu
// 1. Be able to see all non-private repositories that either:
cond = cond.Or(builder.And(
builder.Eq{"`repository`.is_private": false},
- // 2. Aren't in an private organisation or limited organisation if we're not logged in
+ // 2. Aren't in an private organisation/user or limited organisation/user if the doer is not logged in.
builder.NotIn("`repository`.owner_id", builder.Select("id").From("`user`").Where(
- builder.And(
- builder.Eq{"type": user_model.UserTypeOrganization},
- builder.In("visibility", orgVisibilityLimit)),
- ))))
+ builder.In("visibility", orgVisibilityLimit)))))
}
if user != nil {
@@ -743,7 +723,7 @@ func GetUserRepositories(ctx context.Context, opts *SearchRepoOptions) (Reposito
cond = cond.And(builder.Eq{"is_private": false})
}
- if opts.LowerNames != nil && len(opts.LowerNames) > 0 {
+ if len(opts.LowerNames) > 0 {
cond = cond.And(builder.In("lower_name", opts.LowerNames))
}
diff --git a/models/repo/repo_list_test.go b/models/repo/repo_list_test.go
index 6b1bb39b85..c654d1b602 100644
--- a/models/repo/repo_list_test.go
+++ b/models/repo/repo_list_test.go
@@ -4,15 +4,19 @@
package repo_test
import (
+ "slices"
"strings"
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/structs"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func getTestCases() []struct {
@@ -181,7 +185,7 @@ func getTestCases() []struct {
}
func TestSearchRepository(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// test search public repository on explore page
repos, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{
@@ -193,7 +197,7 @@ func TestSearchRepository(t *testing.T) {
Collaborate: optional.Some(false),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, repos, 1) {
assert.Equal(t, "test_repo_12", repos[0].Name)
}
@@ -208,7 +212,7 @@ func TestSearchRepository(t *testing.T) {
Collaborate: optional.Some(false),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(2), count)
assert.Len(t, repos, 2)
@@ -223,7 +227,7 @@ func TestSearchRepository(t *testing.T) {
Collaborate: optional.Some(false),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, repos, 1) {
assert.Equal(t, "test_repo_13", repos[0].Name)
}
@@ -239,14 +243,14 @@ func TestSearchRepository(t *testing.T) {
Collaborate: optional.Some(false),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(3), count)
assert.Len(t, repos, 3)
// Test non existing owner
repos, count, err = repo_model.SearchRepositoryByName(db.DefaultContext, &repo_model.SearchRepoOptions{OwnerID: unittest.NonexistentID})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, repos)
assert.Equal(t, int64(0), count)
@@ -261,7 +265,7 @@ func TestSearchRepository(t *testing.T) {
IncludeDescription: true,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, repos, 1) {
assert.Equal(t, "test_repo_14", repos[0].Name)
}
@@ -278,7 +282,7 @@ func TestSearchRepository(t *testing.T) {
IncludeDescription: false,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, repos)
assert.Equal(t, int64(0), count)
@@ -288,7 +292,7 @@ func TestSearchRepository(t *testing.T) {
t.Run(testCase.name, func(t *testing.T) {
repos, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, testCase.opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(testCase.count), count)
page := testCase.opts.Page
@@ -355,7 +359,7 @@ func TestSearchRepository(t *testing.T) {
}
func TestCountRepository(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testCases := getTestCases()
@@ -363,14 +367,14 @@ func TestCountRepository(t *testing.T) {
t.Run(testCase.name, func(t *testing.T) {
count, err := repo_model.CountRepository(db.DefaultContext, testCase.opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(testCase.count), count)
})
}
}
func TestSearchRepositoryByTopicName(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testCases := []struct {
name string
@@ -397,8 +401,42 @@ func TestSearchRepositoryByTopicName(t *testing.T) {
for _, testCase := range testCases {
t.Run(testCase.name, func(t *testing.T) {
_, count, err := repo_model.SearchRepositoryByName(db.DefaultContext, testCase.opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(testCase.count), count)
})
}
}
+
+func TestSearchRepositoryIDsByCondition(t *testing.T) {
+ defer unittest.OverrideFixtures("models/repo/TestSearchRepositoryIDsByCondition")()
+ require.NoError(t, unittest.PrepareTestDatabase())
+ // Sanity check of the database
+ limitedUser := unittest.AssertExistsAndLoadBean(t, &user.User{ID: 33, Visibility: structs.VisibleTypeLimited})
+ unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1001, OwnerID: limitedUser.ID})
+
+ testCases := []struct {
+ user *user.User
+ repoIDs []int64
+ }{
+ {
+ user: nil,
+ repoIDs: []int64{1, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 1059},
+ },
+ {
+ user: unittest.AssertExistsAndLoadBean(t, &user.User{ID: 4}),
+ repoIDs: []int64{1, 3, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 38, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 1001, 1059},
+ },
+ {
+ user: unittest.AssertExistsAndLoadBean(t, &user.User{ID: 5}),
+ repoIDs: []int64{1, 4, 8, 9, 10, 11, 12, 14, 17, 18, 21, 23, 25, 27, 29, 32, 33, 34, 35, 36, 37, 38, 40, 42, 44, 45, 46, 47, 48, 49, 50, 51, 53, 57, 58, 60, 61, 62, 1001, 1059},
+ },
+ }
+
+ for _, testCase := range testCases {
+ repoIDs, err := repo_model.FindUserCodeAccessibleRepoIDs(db.DefaultContext, testCase.user)
+ require.NoError(t, err)
+
+ slices.Sort(repoIDs)
+ assert.EqualValues(t, testCase.repoIDs, repoIDs)
+ }
+}
diff --git a/models/repo/repo_repository.go b/models/repo/repo_repository.go
index 6780165a38..0ba50e6614 100644
--- a/models/repo/repo_repository.go
+++ b/models/repo/repo_repository.go
@@ -5,8 +5,8 @@ package repo
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/validation"
)
func init() {
diff --git a/models/repo/repo_test.go b/models/repo/repo_test.go
index a279478177..a9591a357b 100644
--- a/models/repo/repo_test.go
+++ b/models/repo/repo_test.go
@@ -7,17 +7,18 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var (
@@ -27,58 +28,58 @@ var (
)
func TestGetRepositoryCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
ctx := db.DefaultContext
count, err1 := repo_model.CountRepositories(ctx, countRepospts)
privateCount, err2 := repo_model.CountRepositories(ctx, countReposptsPrivate)
publicCount, err3 := repo_model.CountRepositories(ctx, countReposptsPublic)
- assert.NoError(t, err1)
- assert.NoError(t, err2)
- assert.NoError(t, err3)
+ require.NoError(t, err1)
+ require.NoError(t, err2)
+ require.NoError(t, err3)
assert.Equal(t, int64(3), count)
assert.Equal(t, privateCount+publicCount, count)
}
func TestGetPublicRepositoryCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
count, err := repo_model.CountRepositories(db.DefaultContext, countReposptsPublic)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), count)
}
func TestGetPrivateRepositoryCount(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
count, err := repo_model.CountRepositories(db.DefaultContext, countReposptsPrivate)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(2), count)
}
func TestRepoAPIURL(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL())
}
func TestWatchRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
const repoID = 3
const userID = 2
- assert.NoError(t, repo_model.WatchRepo(db.DefaultContext, userID, repoID, true))
+ require.NoError(t, repo_model.WatchRepo(db.DefaultContext, userID, repoID, true))
unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{RepoID: repoID, UserID: userID})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID})
- assert.NoError(t, repo_model.WatchRepo(db.DefaultContext, userID, repoID, false))
+ require.NoError(t, repo_model.WatchRepo(db.DefaultContext, userID, repoID, false))
unittest.AssertNotExistsBean(t, &repo_model.Watch{RepoID: repoID, UserID: userID})
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID})
}
func TestMetas(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := &repo_model.Repository{Name: "testRepo"}
repo.Owner = &user_model.User{Name: "testOwner"}
@@ -119,7 +120,7 @@ func TestMetas(t *testing.T) {
testSuccess(markup.IssueNameStyleRegexp)
repo, err := repo_model.GetRepositoryByID(db.DefaultContext, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
metas = repo.ComposeMetas(db.DefaultContext)
assert.Contains(t, metas, "org")
@@ -129,13 +130,13 @@ func TestMetas(t *testing.T) {
}
func TestGetRepositoryByURL(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
t.Run("InvalidPath", func(t *testing.T) {
repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, "something")
assert.Nil(t, repo)
- assert.Error(t, err)
+ require.Error(t, err)
})
t.Run("ValidHttpURL", func(t *testing.T) {
@@ -143,10 +144,10 @@ func TestGetRepositoryByURL(t *testing.T) {
repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, url)
assert.NotNil(t, repo)
- assert.NoError(t, err)
+ require.NoError(t, err)
- assert.Equal(t, repo.ID, int64(2))
- assert.Equal(t, repo.OwnerID, int64(2))
+ assert.Equal(t, int64(2), repo.ID)
+ assert.Equal(t, int64(2), repo.OwnerID)
}
test(t, "https://try.gitea.io/user2/repo2")
@@ -158,10 +159,10 @@ func TestGetRepositoryByURL(t *testing.T) {
repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, url)
assert.NotNil(t, repo)
- assert.NoError(t, err)
+ require.NoError(t, err)
- assert.Equal(t, repo.ID, int64(2))
- assert.Equal(t, repo.OwnerID, int64(2))
+ assert.Equal(t, int64(2), repo.ID)
+ assert.Equal(t, int64(2), repo.OwnerID)
}
test(t, "git+ssh://sshuser@try.gitea.io/user2/repo2")
@@ -176,10 +177,10 @@ func TestGetRepositoryByURL(t *testing.T) {
repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, url)
assert.NotNil(t, repo)
- assert.NoError(t, err)
+ require.NoError(t, err)
- assert.Equal(t, repo.ID, int64(2))
- assert.Equal(t, repo.OwnerID, int64(2))
+ assert.Equal(t, int64(2), repo.ID)
+ assert.Equal(t, int64(2), repo.OwnerID)
}
test(t, "sshuser@try.gitea.io:user2/repo2")
diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go
index ca82d54cb7..c11ad70627 100644
--- a/models/repo/repo_unit.go
+++ b/models/repo/repo_unit.go
@@ -9,13 +9,13 @@ import (
"slices"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/xorm"
"xorm.io/xorm/convert"
@@ -159,6 +159,7 @@ type PullRequestsConfig struct {
AllowRebaseUpdate bool
DefaultDeleteBranchAfterMerge bool
DefaultMergeStyle MergeStyle
+ DefaultUpdateStyle UpdateStyle
DefaultAllowMaintainerEdit bool
}
@@ -197,6 +198,25 @@ func (cfg *PullRequestsConfig) GetDefaultMergeStyle() MergeStyle {
return MergeStyleMerge
}
+// IsUpdateStyleAllowed returns if update style is allowed
+func (cfg *PullRequestsConfig) IsUpdateStyleAllowed(updateStyle UpdateStyle) bool {
+ return updateStyle == UpdateStyleMerge ||
+ updateStyle == UpdateStyleRebase && cfg.AllowRebaseUpdate
+}
+
+// GetDefaultUpdateStyle returns the default update style for this pull request
+func (cfg *PullRequestsConfig) GetDefaultUpdateStyle() UpdateStyle {
+ if len(cfg.DefaultUpdateStyle) != 0 {
+ return cfg.DefaultUpdateStyle
+ }
+
+ if setting.Repository.PullRequest.DefaultUpdateStyle != "" {
+ return UpdateStyle(setting.Repository.PullRequest.DefaultUpdateStyle)
+ }
+
+ return UpdateStyleMerge
+}
+
type ActionsConfig struct {
DisabledWorkflows []string
}
@@ -235,8 +255,7 @@ func (cfg *ActionsConfig) ToDB() ([]byte, error) {
// BeforeSet is invoked from XORM before setting the value of a field of this object.
func (r *RepoUnit) BeforeSet(colName string, val xorm.Cell) {
- switch colName {
- case "type":
+ if colName == "type" {
switch unit.Type(db.Cell2Int64(val)) {
case unit.TypeExternalWiki:
r.Config = new(ExternalWikiConfig)
diff --git a/models/repo/repo_unit_test.go b/models/repo/repo_unit_test.go
index 27a34fd0eb..210b830d02 100644
--- a/models/repo/repo_unit_test.go
+++ b/models/repo/repo_unit_test.go
@@ -6,7 +6,9 @@ package repo
import (
"testing"
- "code.gitea.io/gitea/models/perm"
+ "forgejo.org/models/perm"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
)
@@ -32,8 +34,55 @@ func TestActionsConfig(t *testing.T) {
}
func TestRepoUnitAccessMode(t *testing.T) {
- assert.Equal(t, UnitAccessModeNone.ToAccessMode(perm.AccessModeAdmin), perm.AccessModeNone)
- assert.Equal(t, UnitAccessModeRead.ToAccessMode(perm.AccessModeAdmin), perm.AccessModeRead)
- assert.Equal(t, UnitAccessModeWrite.ToAccessMode(perm.AccessModeAdmin), perm.AccessModeWrite)
- assert.Equal(t, UnitAccessModeUnset.ToAccessMode(perm.AccessModeRead), perm.AccessModeRead)
+ assert.Equal(t, perm.AccessModeNone, UnitAccessModeNone.ToAccessMode(perm.AccessModeAdmin))
+ assert.Equal(t, perm.AccessModeRead, UnitAccessModeRead.ToAccessMode(perm.AccessModeAdmin))
+ assert.Equal(t, perm.AccessModeWrite, UnitAccessModeWrite.ToAccessMode(perm.AccessModeAdmin))
+ assert.Equal(t, perm.AccessModeRead, UnitAccessModeUnset.ToAccessMode(perm.AccessModeRead))
+}
+
+func TestRepoPRIsUpdateStyleAllowed(t *testing.T) {
+ var cfg PullRequestsConfig
+ cfg = PullRequestsConfig{
+ AllowRebaseUpdate: true,
+ }
+ assert.True(t, cfg.IsUpdateStyleAllowed(UpdateStyleMerge))
+ assert.True(t, cfg.IsUpdateStyleAllowed(UpdateStyleRebase))
+
+ cfg = PullRequestsConfig{
+ AllowRebaseUpdate: false,
+ }
+ assert.True(t, cfg.IsUpdateStyleAllowed(UpdateStyleMerge))
+ assert.False(t, cfg.IsUpdateStyleAllowed(UpdateStyleRebase))
+}
+
+func TestRepoPRGetDefaultUpdateStyle(t *testing.T) {
+ defer test.MockVariableValue(&setting.Repository.PullRequest.DefaultUpdateStyle, "merge")()
+
+ var cfg PullRequestsConfig
+ cfg = PullRequestsConfig{
+ DefaultUpdateStyle: "",
+ }
+ assert.Equal(t, UpdateStyleMerge, cfg.GetDefaultUpdateStyle())
+ cfg = PullRequestsConfig{
+ DefaultUpdateStyle: "rebase",
+ }
+ assert.Equal(t, UpdateStyleRebase, cfg.GetDefaultUpdateStyle())
+ cfg = PullRequestsConfig{
+ DefaultUpdateStyle: "merge",
+ }
+ assert.Equal(t, UpdateStyleMerge, cfg.GetDefaultUpdateStyle())
+
+ setting.Repository.PullRequest.DefaultUpdateStyle = "rebase"
+ cfg = PullRequestsConfig{
+ DefaultUpdateStyle: "",
+ }
+ assert.Equal(t, UpdateStyleRebase, cfg.GetDefaultUpdateStyle())
+ cfg = PullRequestsConfig{
+ DefaultUpdateStyle: "rebase",
+ }
+ assert.Equal(t, UpdateStyleRebase, cfg.GetDefaultUpdateStyle())
+ cfg = PullRequestsConfig{
+ DefaultUpdateStyle: "merge",
+ }
+ assert.Equal(t, UpdateStyleMerge, cfg.GetDefaultUpdateStyle())
}
diff --git a/models/repo/search.go b/models/repo/search.go
index a73d9fc215..c16bfa4922 100644
--- a/models/repo/search.go
+++ b/models/repo/search.go
@@ -3,7 +3,7 @@
package repo
-import "code.gitea.io/gitea/models/db"
+import "forgejo.org/models/db"
// OrderByMap represents all possible search order
var OrderByMap = map[string]map[string]db.SearchOrderBy{
@@ -36,6 +36,7 @@ var OrderByMap = map[string]map[string]db.SearchOrderBy{
var OrderByFlatMap = map[string]db.SearchOrderBy{
"newest": OrderByMap["desc"]["created"],
"oldest": OrderByMap["asc"]["created"],
+ "recentupdate": OrderByMap["desc"]["updated"],
"leastupdate": OrderByMap["asc"]["updated"],
"reversealphabetically": OrderByMap["desc"]["alpha"],
"alphabetically": OrderByMap["asc"]["alpha"],
diff --git a/models/repo/star.go b/models/repo/star.go
index 60737149da..25c039a50b 100644
--- a/models/repo/star.go
+++ b/models/repo/star.go
@@ -6,9 +6,9 @@ package repo
import (
"context"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
)
// Star represents a starred repo by an user.
diff --git a/models/repo/star_test.go b/models/repo/star_test.go
index 62eac4e29a..cbaa21db64 100644
--- a/models/repo/star_test.go
+++ b/models/repo/star_test.go
@@ -6,38 +6,39 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestStarRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
const userID = 2
const repoID = 1
unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID, RepoID: repoID})
- assert.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, true))
+ require.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, true))
unittest.AssertExistsAndLoadBean(t, &repo_model.Star{UID: userID, RepoID: repoID})
- assert.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, true))
+ require.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, true))
unittest.AssertExistsAndLoadBean(t, &repo_model.Star{UID: userID, RepoID: repoID})
- assert.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, false))
+ require.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, false))
unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID, RepoID: repoID})
}
func TestIsStaring(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.True(t, repo_model.IsStaring(db.DefaultContext, 2, 4))
assert.False(t, repo_model.IsStaring(db.DefaultContext, 3, 4))
}
func TestRepository_GetStargazers(t *testing.T) {
// repo with stargazers
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
gazers, err := repo_model.GetStargazers(db.DefaultContext, repo, db.ListOptions{Page: 0})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, gazers, 1) {
assert.Equal(t, int64(2), gazers[0].ID)
}
@@ -45,27 +46,27 @@ func TestRepository_GetStargazers(t *testing.T) {
func TestRepository_GetStargazers2(t *testing.T) {
// repo with stargazers
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
gazers, err := repo_model.GetStargazers(db.DefaultContext, repo, db.ListOptions{Page: 0})
- assert.NoError(t, err)
- assert.Len(t, gazers, 0)
+ require.NoError(t, err)
+ assert.Empty(t, gazers)
}
func TestClearRepoStars(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
const userID = 2
const repoID = 1
unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID, RepoID: repoID})
- assert.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, true))
+ require.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, true))
unittest.AssertExistsAndLoadBean(t, &repo_model.Star{UID: userID, RepoID: repoID})
- assert.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, false))
+ require.NoError(t, repo_model.StarRepo(db.DefaultContext, userID, repoID, false))
unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID, RepoID: repoID})
- assert.NoError(t, repo_model.ClearRepoStars(db.DefaultContext, repoID))
+ require.NoError(t, repo_model.ClearRepoStars(db.DefaultContext, repoID))
unittest.AssertNotExistsBean(t, &repo_model.Star{UID: userID, RepoID: repoID})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
gazers, err := repo_model.GetStargazers(db.DefaultContext, repo, db.ListOptions{Page: 0})
- assert.NoError(t, err)
- assert.Len(t, gazers, 0)
+ require.NoError(t, err)
+ assert.Empty(t, gazers)
}
diff --git a/models/repo/topic.go b/models/repo/topic.go
index 6db6c8aef8..4a3bdc7d8c 100644
--- a/models/repo/topic.go
+++ b/models/repo/topic.go
@@ -5,14 +5,12 @@ package repo
import (
"context"
- "fmt"
"regexp"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
)
@@ -39,26 +37,6 @@ type RepoTopic struct { //revive:disable-line:exported
TopicID int64 `xorm:"pk"`
}
-// ErrTopicNotExist represents an error that a topic is not exist
-type ErrTopicNotExist struct {
- Name string
-}
-
-// IsErrTopicNotExist checks if an error is an ErrTopicNotExist.
-func IsErrTopicNotExist(err error) bool {
- _, ok := err.(ErrTopicNotExist)
- return ok
-}
-
-// Error implements error interface
-func (err ErrTopicNotExist) Error() string {
- return fmt.Sprintf("topic is not exist [name: %s]", err.Name)
-}
-
-func (err ErrTopicNotExist) Unwrap() error {
- return util.ErrNotExist
-}
-
// ValidateTopic checks a topic by length and match pattern rules
func ValidateTopic(topic string) bool {
return len(topic) <= 35 && topicPattern.MatchString(topic)
@@ -91,17 +69,6 @@ func SanitizeAndValidateTopics(topics []string) (validTopics, invalidTopics []st
return validTopics, invalidTopics
}
-// GetTopicByName retrieves topic by name
-func GetTopicByName(ctx context.Context, name string) (*Topic, error) {
- var topic Topic
- if has, err := db.GetEngine(ctx).Where("name = ?", name).Get(&topic); err != nil {
- return nil, err
- } else if !has {
- return nil, ErrTopicNotExist{name}
- }
- return &topic, nil
-}
-
// addTopicByNameToRepo adds a topic name to a repo and increments the topic count.
// Returns topic after the addition
func addTopicByNameToRepo(ctx context.Context, repoID int64, topicName string) (*Topic, error) {
diff --git a/models/repo/topic_test.go b/models/repo/topic_test.go
index 2b609e6d66..26ad27896e 100644
--- a/models/repo/topic_test.go
+++ b/models/repo/topic_test.go
@@ -6,63 +6,63 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestAddTopic(t *testing.T) {
totalNrOfTopics := 6
repo1NrOfTopics := 3
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
topics, _, err := repo_model.FindTopics(db.DefaultContext, &repo_model.FindTopicOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, topics, totalNrOfTopics)
topics, total, err := repo_model.FindTopics(db.DefaultContext, &repo_model.FindTopicOptions{
ListOptions: db.ListOptions{Page: 1, PageSize: 2},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, topics, 2)
assert.EqualValues(t, 6, total)
topics, _, err = repo_model.FindTopics(db.DefaultContext, &repo_model.FindTopicOptions{
RepoID: 1,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, topics, repo1NrOfTopics)
- assert.NoError(t, repo_model.SaveTopics(db.DefaultContext, 2, "golang"))
+ require.NoError(t, repo_model.SaveTopics(db.DefaultContext, 2, "golang"))
repo2NrOfTopics := 1
topics, _, err = repo_model.FindTopics(db.DefaultContext, &repo_model.FindTopicOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, topics, totalNrOfTopics)
topics, _, err = repo_model.FindTopics(db.DefaultContext, &repo_model.FindTopicOptions{
RepoID: 2,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, topics, repo2NrOfTopics)
- assert.NoError(t, repo_model.SaveTopics(db.DefaultContext, 2, "golang", "gitea"))
+ require.NoError(t, repo_model.SaveTopics(db.DefaultContext, 2, "golang", "gitea"))
repo2NrOfTopics = 2
totalNrOfTopics++
- topic, err := repo_model.GetTopicByName(db.DefaultContext, "gitea")
- assert.NoError(t, err)
+ topic := unittest.AssertExistsAndLoadBean(t, &repo_model.Topic{Name: "gitea"})
assert.EqualValues(t, 1, topic.RepoCount)
topics, _, err = repo_model.FindTopics(db.DefaultContext, &repo_model.FindTopicOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, topics, totalNrOfTopics)
topics, _, err = repo_model.FindTopics(db.DefaultContext, &repo_model.FindTopicOptions{
RepoID: 2,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, topics, repo2NrOfTopics)
}
diff --git a/models/repo/update.go b/models/repo/update.go
index e7ca224028..0222d09de5 100644
--- a/models/repo/update.go
+++ b/models/repo/update.go
@@ -8,10 +8,10 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
// UpdateRepositoryOwnerNames updates repository owner_names (this should only be used when the ownerName has changed case)
diff --git a/models/repo/upload.go b/models/repo/upload.go
index 18834f6b83..49152db7fd 100644
--- a/models/repo/upload.go
+++ b/models/repo/upload.go
@@ -12,10 +12,10 @@ import (
"os"
"path"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
gouuid "github.com/google/uuid"
)
diff --git a/models/repo/user_repo.go b/models/repo/user_repo.go
index 6790ee1da9..309bfee18f 100644
--- a/models/repo/user_repo.go
+++ b/models/repo/user_repo.go
@@ -6,12 +6,12 @@ package repo
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ api "forgejo.org/modules/structs"
"xorm.io/builder"
)
@@ -75,26 +75,28 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us
return nil, err
}
- additionalUserIDs := make([]int64, 0, 10)
- if err = e.Table("team_user").
- Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id").
- Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id").
- Where("`team_repo`.repo_id = ? AND (`team_unit`.access_mode >= ? OR (`team_unit`.access_mode = ? AND `team_unit`.`type` = ?))",
- repo.ID, perm.AccessModeWrite, perm.AccessModeRead, unit.TypePullRequests).
- Distinct("`team_user`.uid").
- Select("`team_user`.uid").
- Find(&additionalUserIDs); err != nil {
- return nil, err
- }
-
uniqueUserIDs := make(container.Set[int64])
uniqueUserIDs.AddMultiple(userIDs...)
- uniqueUserIDs.AddMultiple(additionalUserIDs...)
+
+ if repo.Owner.IsOrganization() {
+ additionalUserIDs := make([]int64, 0, 10)
+ if err = e.Table("team_user").
+ Join("INNER", "team_repo", "`team_repo`.team_id = `team_user`.team_id").
+ Join("INNER", "team_unit", "`team_unit`.team_id = `team_user`.team_id").
+ Where("`team_repo`.repo_id = ? AND (`team_unit`.access_mode >= ? OR (`team_unit`.access_mode = ? AND `team_unit`.`type` = ?))",
+ repo.ID, perm.AccessModeWrite, perm.AccessModeRead, unit.TypePullRequests).
+ Distinct("`team_user`.uid").
+ Select("`team_user`.uid").
+ Find(&additionalUserIDs); err != nil {
+ return nil, err
+ }
+ uniqueUserIDs.AddMultiple(additionalUserIDs...)
+ }
// Leave a seat for owner itself to append later, but if owner is an organization
// and just waste 1 unit is cheaper than re-allocate memory once.
users := make([]*user_model.User, 0, len(uniqueUserIDs)+1)
- if len(userIDs) > 0 {
+ if len(uniqueUserIDs) > 0 {
if err = e.In("id", uniqueUserIDs.Values()).
Where(builder.Eq{"`user`.is_active": true}).
OrderBy(user_model.GetOrderByName()).
@@ -164,9 +166,9 @@ func GetReviewers(ctx context.Context, repo *Repository, doerID, posterID int64)
// If isShowFullName is set to true, also include full name prefix search
func GetIssuePostersWithSearch(ctx context.Context, repo *Repository, isPull bool, search string, isShowFullName bool) ([]*user_model.User, error) {
users := make([]*user_model.User, 0, 30)
- var prefixCond builder.Cond = builder.Like{"name", search + "%"}
+ prefixCond := db.BuildCaseInsensitiveLike("name", search+"%")
if isShowFullName {
- prefixCond = prefixCond.Or(builder.Like{"full_name", "%" + search + "%"})
+ prefixCond = db.BuildCaseInsensitiveLike("full_name", "%"+search+"%")
}
cond := builder.In("`user`.id",
diff --git a/models/repo/user_repo_test.go b/models/repo/user_repo_test.go
index 0433ff83d8..2912986cd1 100644
--- a/models/repo/user_repo_test.go
+++ b/models/repo/user_repo_test.go
@@ -6,90 +6,91 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepoAssignees(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
users, err := repo_model.GetRepoAssignees(db.DefaultContext, repo2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, users, 1)
- assert.Equal(t, users[0].ID, int64(2))
+ assert.Equal(t, int64(2), users[0].ID)
repo21 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21})
users, err = repo_model.GetRepoAssignees(db.DefaultContext, repo21)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, users, 3) {
assert.ElementsMatch(t, []int64{15, 16, 18}, []int64{users[0].ID, users[1].ID, users[2].ID})
}
// do not return deactivated users
- assert.NoError(t, user_model.UpdateUserCols(db.DefaultContext, &user_model.User{ID: 15, IsActive: false}, "is_active"))
+ require.NoError(t, user_model.UpdateUserCols(db.DefaultContext, &user_model.User{ID: 15, IsActive: false}, "is_active"))
users, err = repo_model.GetRepoAssignees(db.DefaultContext, repo21)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, users, 2) {
assert.NotContains(t, []int64{users[0].ID, users[1].ID}, 15)
}
}
func TestRepoGetReviewers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// test public repo
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
ctx := db.DefaultContext
reviewers, err := repo_model.GetReviewers(ctx, repo1, 2, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, reviewers, 3) {
assert.ElementsMatch(t, []int64{1, 4, 11}, []int64{reviewers[0].ID, reviewers[1].ID, reviewers[2].ID})
}
// should include doer if doer is not PR poster.
reviewers, err = repo_model.GetReviewers(ctx, repo1, 11, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, reviewers, 3)
// should not include PR poster, if PR poster would be otherwise eligible
reviewers, err = repo_model.GetReviewers(ctx, repo1, 11, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, reviewers, 2)
// test private user repo
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
reviewers, err = repo_model.GetReviewers(ctx, repo2, 2, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, reviewers, 1)
- assert.EqualValues(t, reviewers[0].ID, 2)
+ assert.EqualValues(t, 2, reviewers[0].ID)
// test private org repo
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
reviewers, err = repo_model.GetReviewers(ctx, repo3, 2, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, reviewers, 2)
reviewers, err = repo_model.GetReviewers(ctx, repo3, 2, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, reviewers, 1)
}
func GetWatchedRepoIDsOwnedBy(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 9})
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
repoIDs, err := repo_model.GetWatchedRepoIDsOwnedBy(db.DefaultContext, user1.ID, user2.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, repoIDs, 1)
assert.EqualValues(t, 1, repoIDs[0])
}
diff --git a/models/repo/watch.go b/models/repo/watch.go
index 6974d893df..3fd915e1e7 100644
--- a/models/repo/watch.go
+++ b/models/repo/watch.go
@@ -6,10 +6,10 @@ package repo
import (
"context"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
)
// WatchMode specifies what kind of watch the user has on a repository
diff --git a/models/repo/watch_test.go b/models/repo/watch_test.go
index 4dd9234f3b..059489afbf 100644
--- a/models/repo/watch_test.go
+++ b/models/repo/watch_test.go
@@ -6,16 +6,17 @@ package repo_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIsWatching(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.True(t, repo_model.IsWatching(db.DefaultContext, 1, 1))
assert.True(t, repo_model.IsWatching(db.DefaultContext, 4, 1))
@@ -27,11 +28,11 @@ func TestIsWatching(t *testing.T) {
}
func TestGetWatchers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
watches, err := repo_model.GetWatchers(db.DefaultContext, repo.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
// One watchers are inactive, thus minus 1
assert.Len(t, watches, repo.NumWatches-1)
for _, watch := range watches {
@@ -39,16 +40,16 @@ func TestGetWatchers(t *testing.T) {
}
watches, err = repo_model.GetWatchers(db.DefaultContext, unittest.NonexistentID)
- assert.NoError(t, err)
- assert.Len(t, watches, 0)
+ require.NoError(t, err)
+ assert.Empty(t, watches)
}
func TestRepository_GetWatchers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
watchers, err := repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, watchers, repo.NumWatches)
for _, watcher := range watchers {
unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: watcher.ID, RepoID: repo.ID})
@@ -56,16 +57,16 @@ func TestRepository_GetWatchers(t *testing.T) {
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 9})
watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
- assert.Len(t, watchers, 0)
+ require.NoError(t, err)
+ assert.Empty(t, watchers)
}
func TestWatchIfAuto(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
watchers, err := repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, watchers, repo.NumWatches)
setting.Service.AutoWatchOnChanges = false
@@ -73,79 +74,79 @@ func TestWatchIfAuto(t *testing.T) {
prevCount := repo.NumWatches
// Must not add watch
- assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 8, 1, true))
+ require.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 8, 1, true))
watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, watchers, prevCount)
// Should not add watch
- assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 10, 1, true))
+ require.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 10, 1, true))
watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, watchers, prevCount)
setting.Service.AutoWatchOnChanges = true
// Must not add watch
- assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 8, 1, true))
+ require.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 8, 1, true))
watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, watchers, prevCount)
// Should not add watch
- assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 12, 1, false))
+ require.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 12, 1, false))
watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, watchers, prevCount)
// Should add watch
- assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 12, 1, true))
+ require.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 12, 1, true))
watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, watchers, prevCount+1)
// Should remove watch, inhibit from adding auto
- assert.NoError(t, repo_model.WatchRepo(db.DefaultContext, 12, 1, false))
+ require.NoError(t, repo_model.WatchRepo(db.DefaultContext, 12, 1, false))
watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, watchers, prevCount)
// Must not add watch
- assert.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 12, 1, true))
+ require.NoError(t, repo_model.WatchIfAuto(db.DefaultContext, 12, 1, true))
watchers, err = repo_model.GetRepoWatchers(db.DefaultContext, repo.ID, db.ListOptions{Page: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, watchers, prevCount)
}
func TestWatchRepoMode(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertCount(t, &repo_model.Watch{UserID: 12, RepoID: 1}, 0)
- assert.NoError(t, repo_model.WatchRepoMode(db.DefaultContext, 12, 1, repo_model.WatchModeAuto))
+ require.NoError(t, repo_model.WatchRepoMode(db.DefaultContext, 12, 1, repo_model.WatchModeAuto))
unittest.AssertCount(t, &repo_model.Watch{UserID: 12, RepoID: 1}, 1)
unittest.AssertCount(t, &repo_model.Watch{UserID: 12, RepoID: 1, Mode: repo_model.WatchModeAuto}, 1)
- assert.NoError(t, repo_model.WatchRepoMode(db.DefaultContext, 12, 1, repo_model.WatchModeNormal))
+ require.NoError(t, repo_model.WatchRepoMode(db.DefaultContext, 12, 1, repo_model.WatchModeNormal))
unittest.AssertCount(t, &repo_model.Watch{UserID: 12, RepoID: 1}, 1)
unittest.AssertCount(t, &repo_model.Watch{UserID: 12, RepoID: 1, Mode: repo_model.WatchModeNormal}, 1)
- assert.NoError(t, repo_model.WatchRepoMode(db.DefaultContext, 12, 1, repo_model.WatchModeDont))
+ require.NoError(t, repo_model.WatchRepoMode(db.DefaultContext, 12, 1, repo_model.WatchModeDont))
unittest.AssertCount(t, &repo_model.Watch{UserID: 12, RepoID: 1}, 1)
unittest.AssertCount(t, &repo_model.Watch{UserID: 12, RepoID: 1, Mode: repo_model.WatchModeDont}, 1)
- assert.NoError(t, repo_model.WatchRepoMode(db.DefaultContext, 12, 1, repo_model.WatchModeNone))
+ require.NoError(t, repo_model.WatchRepoMode(db.DefaultContext, 12, 1, repo_model.WatchModeNone))
unittest.AssertCount(t, &repo_model.Watch{UserID: 12, RepoID: 1}, 0)
}
func TestUnwatchRepos(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: 4, RepoID: 1})
unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: 4, RepoID: 2})
err := repo_model.UnwatchRepos(db.DefaultContext, 4, []int64{1, 2})
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertNotExistsBean(t, &repo_model.Watch{UserID: 4, RepoID: 1})
unittest.AssertNotExistsBean(t, &repo_model.Watch{UserID: 4, RepoID: 2})
diff --git a/models/repo/wiki.go b/models/repo/wiki.go
index b378666a20..f0dd945a72 100644
--- a/models/repo/wiki.go
+++ b/models/repo/wiki.go
@@ -9,9 +9,9 @@ import (
"path/filepath"
"strings"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
// ErrWikiAlreadyExist represents a "WikiAlreadyExist" kind of error.
diff --git a/models/repo/wiki_test.go b/models/repo/wiki_test.go
index 629986f741..bf35a4c610 100644
--- a/models/repo/wiki_test.go
+++ b/models/repo/wiki_test.go
@@ -7,15 +7,16 @@ import (
"path/filepath"
"testing"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepository_WikiCloneLink(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
cloneLink := repo.WikiCloneLink()
@@ -24,13 +25,13 @@ func TestRepository_WikiCloneLink(t *testing.T) {
}
func TestWikiPath(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
expected := filepath.Join(setting.RepoRootPath, "user2/repo1.wiki.git")
assert.Equal(t, expected, repo_model.WikiPath("user2", "repo1"))
}
func TestRepository_WikiPath(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
expected := filepath.Join(setting.RepoRootPath, "user2/repo1.wiki.git")
assert.Equal(t, expected, repo.WikiPath())
diff --git a/models/repo_test.go b/models/repo_test.go
index 2a8a4a743e..6fbef8edf6 100644
--- a/models/repo_test.go
+++ b/models/repo_test.go
@@ -6,19 +6,34 @@ package models
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCheckRepoStats(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
- assert.NoError(t, CheckRepoStats(db.DefaultContext))
+ require.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, CheckRepoStats(db.DefaultContext))
}
func TestDoctorUserStarNum(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
- assert.NoError(t, DoctorUserStarNum(db.DefaultContext))
+ require.NoError(t, DoctorUserStarNum(db.DefaultContext))
+}
+
+func Test_repoStatsCorrectIssueNumComments(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ assert.NotNil(t, issue2)
+ assert.EqualValues(t, 0, issue2.NumComments) // the fixture data is wrong, but we don't fix it here
+
+ require.NoError(t, repoStatsCorrectIssueNumComments(db.DefaultContext, 2))
+ // reload the issue
+ issue2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ assert.EqualValues(t, 1, issue2.NumComments)
}
diff --git a/models/repo_transfer.go b/models/repo_transfer.go
index 0c23d759f9..f515f1bcf0 100644
--- a/models/repo_transfer.go
+++ b/models/repo_transfer.go
@@ -8,12 +8,12 @@ import (
"errors"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
)
// RepoTransfer is used to manage repository transfers
diff --git a/models/repo_transfer_test.go b/models/repo_transfer_test.go
index 7ef29fae1f..6449e40fce 100644
--- a/models/repo_transfer_test.go
+++ b/models/repo_transfer_test.go
@@ -6,21 +6,22 @@ package models
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetPendingTransferIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
reciepient := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
pendingTransfer := unittest.AssertExistsAndLoadBean(t, &RepoTransfer{RecipientID: reciepient.ID, DoerID: doer.ID})
pendingTransferIDs, err := GetPendingTransferIDs(db.DefaultContext, reciepient.ID, doer.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, pendingTransferIDs, 1) {
assert.EqualValues(t, pendingTransfer.ID, pendingTransferIDs[0])
}
diff --git a/models/secret/secret.go b/models/secret/secret.go
index 35bed500b9..7be7f454a1 100644
--- a/models/secret/secret.go
+++ b/models/secret/secret.go
@@ -5,23 +5,35 @@ package secret
import (
"context"
- "errors"
"fmt"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- actions_module "code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/log"
- secret_module "code.gitea.io/gitea/modules/secret"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ actions_module "forgejo.org/modules/actions"
+ "forgejo.org/modules/log"
+ secret_module "forgejo.org/modules/secret"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
// Secret represents a secret
+//
+// It can be:
+// 1. org/user level secret, OwnerID is org/user ID and RepoID is 0
+// 2. repo level secret, OwnerID is 0 and RepoID is repo ID
+//
+// Please note that it's not acceptable to have both OwnerID and RepoID to be non-zero,
+// or it will be complicated to find secrets belonging to a specific owner.
+// For example, conditions like `OwnerID = 1` will also return secret {OwnerID: 1, RepoID: 1},
+// but it's a repo level secret, not an org/user level secret.
+// To avoid this, make it clear with {OwnerID: 0, RepoID: 1} for repo level secrets.
+//
+// Please note that it's not acceptable to have both OwnerID and RepoID to zero, global secrets are not supported.
+// It's for security reasons, admin may be not aware of that the secrets could be stolen by any user when setting them as global.
type Secret struct {
ID int64
OwnerID int64 `xorm:"INDEX UNIQUE(owner_repo_name) NOT NULL"`
@@ -46,6 +58,15 @@ func (err ErrSecretNotFound) Unwrap() error {
// InsertEncryptedSecret Creates, encrypts, and validates a new secret with yet unencrypted data and insert into database
func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, data string) (*Secret, error) {
+ if ownerID != 0 && repoID != 0 {
+ // It's trying to create a secret that belongs to a repository, but OwnerID has been set accidentally.
+ // Remove OwnerID to avoid confusion; it's not worth returning an error here.
+ ownerID = 0
+ }
+ if ownerID == 0 && repoID == 0 {
+ return nil, fmt.Errorf("%w: ownerID and repoID cannot be both zero, global secrets are not supported", util.ErrInvalidArgument)
+ }
+
encrypted, err := secret_module.EncryptSecret(setting.SecretKey, data)
if err != nil {
return nil, err
@@ -56,9 +77,6 @@ func InsertEncryptedSecret(ctx context.Context, ownerID, repoID int64, name, dat
Name: strings.ToUpper(name),
Data: encrypted,
}
- if err := secret.Validate(); err != nil {
- return secret, err
- }
return secret, db.Insert(ctx, secret)
}
@@ -66,29 +84,25 @@ func init() {
db.RegisterModel(new(Secret))
}
-func (s *Secret) Validate() error {
- if s.OwnerID == 0 && s.RepoID == 0 {
- return errors.New("the secret is not bound to any scope")
- }
- return nil
-}
-
type FindSecretsOptions struct {
db.ListOptions
- OwnerID int64
RepoID int64
+ OwnerID int64 // it will be ignored if RepoID is set
SecretID int64
Name string
}
func (opts FindSecretsOptions) ToConds() builder.Cond {
cond := builder.NewCond()
- if opts.OwnerID > 0 {
+
+ cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
+ if opts.RepoID != 0 { // if RepoID is set
+ // ignore OwnerID and treat it as 0
+ cond = cond.And(builder.Eq{"owner_id": 0})
+ } else {
cond = cond.And(builder.Eq{"owner_id": opts.OwnerID})
}
- if opts.RepoID > 0 {
- cond = cond.And(builder.Eq{"repo_id": opts.RepoID})
- }
+
if opts.SecretID != 0 {
cond = cond.And(builder.Eq{"id": opts.SecretID})
}
@@ -121,9 +135,10 @@ func GetSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) (map[
secrets["GITHUB_TOKEN"] = task.Token
secrets["GITEA_TOKEN"] = task.Token
+ secrets["FORGEJO_TOKEN"] = task.Token
if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget {
- // ignore secrets for fork pull request, except GITHUB_TOKEN and GITEA_TOKEN which are automatically generated.
+ // ignore secrets for fork pull request, except GITHUB_TOKEN, GITEA_TOKEN and FORGEJO_TOKEN which are automatically generated.
// for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch
// see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target
return secrets, nil
diff --git a/models/shared/types/ownertype.go b/models/shared/types/ownertype.go
index a1d46c986f..62ca1bb9cc 100644
--- a/models/shared/types/ownertype.go
+++ b/models/shared/types/ownertype.go
@@ -3,7 +3,7 @@
package types
-import "code.gitea.io/gitea/modules/translation"
+import "forgejo.org/modules/translation"
type OwnerType string
diff --git a/models/system/appstate.go b/models/system/appstate.go
index 01faa1a5be..31274b4c34 100644
--- a/models/system/appstate.go
+++ b/models/system/appstate.go
@@ -6,7 +6,7 @@ package system
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
// AppState represents a state record in database
diff --git a/models/system/main_test.go b/models/system/main_test.go
index 6bc27a7cff..ca2846527a 100644
--- a/models/system/main_test.go
+++ b/models/system/main_test.go
@@ -6,12 +6,13 @@ package system_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models" // register models
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
- _ "code.gitea.io/gitea/models/system" // register models of system
+ _ "forgejo.org/models" // register models
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
+ _ "forgejo.org/models/system" // register models of system
)
func TestMain(m *testing.M) {
diff --git a/models/system/notice.go b/models/system/notice.go
index e7ec6a9693..b1fdd2e4f2 100644
--- a/models/system/notice.go
+++ b/models/system/notice.go
@@ -8,11 +8,11 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
)
// NoticeType describes the notice type
diff --git a/models/system/notice_test.go b/models/system/notice_test.go
index 599b2fb65c..4862160755 100644
--- a/models/system/notice_test.go
+++ b/models/system/notice_test.go
@@ -6,11 +6,12 @@ package system_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/system"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/system"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestNotice_TrStr(t *testing.T) {
@@ -22,48 +23,48 @@ func TestNotice_TrStr(t *testing.T) {
}
func TestCreateNotice(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
noticeBean := &system.Notice{
Type: system.NoticeRepository,
Description: "test description",
}
unittest.AssertNotExistsBean(t, noticeBean)
- assert.NoError(t, system.CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description))
+ require.NoError(t, system.CreateNotice(db.DefaultContext, noticeBean.Type, noticeBean.Description))
unittest.AssertExistsAndLoadBean(t, noticeBean)
}
func TestCreateRepositoryNotice(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
noticeBean := &system.Notice{
Type: system.NoticeRepository,
Description: "test description",
}
unittest.AssertNotExistsBean(t, noticeBean)
- assert.NoError(t, system.CreateRepositoryNotice(noticeBean.Description))
+ require.NoError(t, system.CreateRepositoryNotice(noticeBean.Description))
unittest.AssertExistsAndLoadBean(t, noticeBean)
}
// TODO TestRemoveAllWithNotice
func TestCountNotices(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.Equal(t, int64(3), system.CountNotices(db.DefaultContext))
}
func TestNotices(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
notices, err := system.Notices(db.DefaultContext, 1, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, notices, 2) {
assert.Equal(t, int64(3), notices[0].ID)
assert.Equal(t, int64(2), notices[1].ID)
}
notices, err = system.Notices(db.DefaultContext, 2, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, notices, 1) {
assert.Equal(t, int64(1), notices[0].ID)
}
@@ -71,12 +72,12 @@ func TestNotices(t *testing.T) {
func TestDeleteNotices(t *testing.T) {
// delete a non-empty range
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
- assert.NoError(t, system.DeleteNotices(db.DefaultContext, 1, 2))
+ require.NoError(t, system.DeleteNotices(db.DefaultContext, 1, 2))
unittest.AssertNotExistsBean(t, &system.Notice{ID: 1})
unittest.AssertNotExistsBean(t, &system.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
@@ -84,25 +85,25 @@ func TestDeleteNotices(t *testing.T) {
func TestDeleteNotices2(t *testing.T) {
// delete an empty range
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
- assert.NoError(t, system.DeleteNotices(db.DefaultContext, 3, 2))
+ require.NoError(t, system.DeleteNotices(db.DefaultContext, 3, 2))
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
}
func TestDeleteNoticesByIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 3})
err := db.DeleteByIDs[system.Notice](db.DefaultContext, 1, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertNotExistsBean(t, &system.Notice{ID: 1})
unittest.AssertExistsAndLoadBean(t, &system.Notice{ID: 2})
unittest.AssertNotExistsBean(t, &system.Notice{ID: 3})
diff --git a/models/system/setting.go b/models/system/setting.go
index 4472b4c228..a57602688a 100644
--- a/models/system/setting.go
+++ b/models/system/setting.go
@@ -9,19 +9,19 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting/config"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting/config"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
)
type Setting struct {
- ID int64 `xorm:"pk autoincr"`
- SettingKey string `xorm:"varchar(255) unique"` // key should be lowercase
- SettingValue string `xorm:"text"`
- Version int `xorm:"version"`
+ ID int64 `xorm:"pk autoincr"`
+ SettingKey string `xorm:"varchar(255) unique"` // key should be lowercase
+ SettingValue string `xorm:"text"`
+ Version int
Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"`
}
diff --git a/models/system/setting_test.go b/models/system/setting_test.go
index 8f04412fb4..1abaf2f16b 100644
--- a/models/system/setting_test.go
+++ b/models/system/setting_test.go
@@ -6,46 +6,47 @@ package system_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/system"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/system"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestSettings(t *testing.T) {
keyName := "test.key"
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
- assert.NoError(t, db.TruncateBeans(db.DefaultContext, &system.Setting{}))
+ require.NoError(t, db.TruncateBeans(db.DefaultContext, &system.Setting{}))
rev, settings, err := system.GetAllSettings(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, rev)
assert.Len(t, settings, 1) // there is only one "revision" key
err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "true"})
- assert.NoError(t, err)
+ require.NoError(t, err)
rev, settings, err = system.GetAllSettings(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 2, rev)
assert.Len(t, settings, 2)
assert.EqualValues(t, "true", settings[keyName])
err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "false"})
- assert.NoError(t, err)
+ require.NoError(t, err)
rev, settings, err = system.GetAllSettings(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 3, rev)
assert.Len(t, settings, 2)
assert.EqualValues(t, "false", settings[keyName])
// setting the same value should not trigger DuplicateKey error, and the "version" should be increased
err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "false"})
- assert.NoError(t, err)
+ require.NoError(t, err)
rev, settings, err = system.GetAllSettings(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, settings, 2)
assert.EqualValues(t, 4, rev)
}
diff --git a/models/unit/unit.go b/models/unit/unit.go
index 3beee6a572..6251d44c9b 100644
--- a/models/unit/unit.go
+++ b/models/unit/unit.go
@@ -9,10 +9,10 @@ import (
"strings"
"sync/atomic"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/perm"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
// Type is Unit's Type
@@ -245,6 +245,7 @@ func (u *Type) CanBeDefault() bool {
// Unit is a section of one repository
type Unit struct {
Type Type
+ Name string
NameKey string
URI string
DescKey string
@@ -272,6 +273,7 @@ func (u Unit) MaxPerm() perm.AccessMode {
var (
UnitCode = Unit{
TypeCode,
+ "code",
"repo.code",
"/",
"repo.code.desc",
@@ -281,6 +283,7 @@ var (
UnitIssues = Unit{
TypeIssues,
+ "issues",
"repo.issues",
"/issues",
"repo.issues.desc",
@@ -290,6 +293,7 @@ var (
UnitExternalTracker = Unit{
TypeExternalTracker,
+ "ext_issues",
"repo.ext_issues",
"/issues",
"repo.ext_issues.desc",
@@ -299,6 +303,7 @@ var (
UnitPullRequests = Unit{
TypePullRequests,
+ "pulls",
"repo.pulls",
"/pulls",
"repo.pulls.desc",
@@ -308,6 +313,7 @@ var (
UnitReleases = Unit{
TypeReleases,
+ "releases",
"repo.releases",
"/releases",
"repo.releases.desc",
@@ -317,6 +323,7 @@ var (
UnitWiki = Unit{
TypeWiki,
+ "wiki",
"repo.wiki",
"/wiki",
"repo.wiki.desc",
@@ -326,6 +333,7 @@ var (
UnitExternalWiki = Unit{
TypeExternalWiki,
+ "ext_wiki",
"repo.ext_wiki",
"/wiki",
"repo.ext_wiki.desc",
@@ -335,6 +343,7 @@ var (
UnitProjects = Unit{
TypeProjects,
+ "projects",
"repo.projects",
"/projects",
"repo.projects.desc",
@@ -344,6 +353,7 @@ var (
UnitPackages = Unit{
TypePackages,
+ "packages",
"repo.packages",
"/packages",
"packages.desc",
@@ -353,6 +363,7 @@ var (
UnitActions = Unit{
TypeActions,
+ "actions",
"repo.actions",
"/actions",
"actions.unit.desc",
diff --git a/models/unit/unit_test.go b/models/unit/unit_test.go
index 7bf6326145..efcad4a405 100644
--- a/models/unit/unit_test.go
+++ b/models/unit/unit_test.go
@@ -6,9 +6,10 @@ package unit
import (
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestLoadUnitConfig(t *testing.T) {
@@ -27,7 +28,7 @@ func TestLoadUnitConfig(t *testing.T) {
setting.Repository.DisabledRepoUnits = []string{"repo.issues"}
setting.Repository.DefaultRepoUnits = []string{"repo.code", "repo.releases", "repo.issues", "repo.pulls"}
setting.Repository.DefaultForkRepoUnits = []string{"repo.releases"}
- assert.NoError(t, LoadUnitConfig())
+ require.NoError(t, LoadUnitConfig())
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnitsGet())
assert.Equal(t, []Type{TypeCode, TypeReleases, TypePullRequests}, DefaultRepoUnits)
assert.Equal(t, []Type{TypeReleases}, DefaultForkRepoUnits)
@@ -47,7 +48,7 @@ func TestLoadUnitConfig(t *testing.T) {
setting.Repository.DisabledRepoUnits = []string{"repo.issues", "invalid.1"}
setting.Repository.DefaultRepoUnits = []string{"repo.code", "invalid.2", "repo.releases", "repo.issues", "repo.pulls"}
setting.Repository.DefaultForkRepoUnits = []string{"invalid.3", "repo.releases"}
- assert.NoError(t, LoadUnitConfig())
+ require.NoError(t, LoadUnitConfig())
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnitsGet())
assert.Equal(t, []Type{TypeCode, TypeReleases, TypePullRequests}, DefaultRepoUnits)
assert.Equal(t, []Type{TypeReleases}, DefaultForkRepoUnits)
@@ -67,7 +68,7 @@ func TestLoadUnitConfig(t *testing.T) {
setting.Repository.DisabledRepoUnits = []string{"repo.issues", "repo.issues"}
setting.Repository.DefaultRepoUnits = []string{"repo.code", "repo.releases", "repo.issues", "repo.pulls", "repo.code"}
setting.Repository.DefaultForkRepoUnits = []string{"repo.releases", "repo.releases"}
- assert.NoError(t, LoadUnitConfig())
+ require.NoError(t, LoadUnitConfig())
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnitsGet())
assert.Equal(t, []Type{TypeCode, TypeReleases, TypePullRequests}, DefaultRepoUnits)
assert.Equal(t, []Type{TypeReleases}, DefaultForkRepoUnits)
@@ -87,7 +88,7 @@ func TestLoadUnitConfig(t *testing.T) {
setting.Repository.DisabledRepoUnits = []string{"repo.issues", "repo.issues"}
setting.Repository.DefaultRepoUnits = []string{}
setting.Repository.DefaultForkRepoUnits = []string{"repo.releases", "repo.releases"}
- assert.NoError(t, LoadUnitConfig())
+ require.NoError(t, LoadUnitConfig())
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnitsGet())
assert.ElementsMatch(t, []Type{TypeCode, TypePullRequests, TypeReleases, TypeWiki, TypePackages, TypeProjects, TypeActions}, DefaultRepoUnits)
assert.Equal(t, []Type{TypeReleases}, DefaultForkRepoUnits)
diff --git a/models/unittest/consistency.go b/models/unittest/consistency.go
index 71839001be..fd2d4b7d75 100644
--- a/models/unittest/consistency.go
+++ b/models/unittest/consistency.go
@@ -7,10 +7,12 @@ import (
"reflect"
"strconv"
"strings"
+ "testing"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/builder"
)
@@ -21,10 +23,10 @@ const (
modelsCommentTypeComment = 0
)
-var consistencyCheckMap = make(map[string]func(t assert.TestingT, bean any))
+var consistencyCheckMap = make(map[string]func(t *testing.T, bean any))
// CheckConsistencyFor test that all matching database entries are consistent
-func CheckConsistencyFor(t assert.TestingT, beansToCheck ...any) {
+func CheckConsistencyFor(t *testing.T, beansToCheck ...any) {
for _, bean := range beansToCheck {
sliceType := reflect.SliceOf(reflect.TypeOf(bean))
sliceValue := reflect.MakeSlice(sliceType, 0, 10)
@@ -32,7 +34,7 @@ func CheckConsistencyFor(t assert.TestingT, beansToCheck ...any) {
ptrToSliceValue := reflect.New(sliceType)
ptrToSliceValue.Elem().Set(sliceValue)
- assert.NoError(t, db.GetEngine(db.DefaultContext).Table(bean).Find(ptrToSliceValue.Interface()))
+ require.NoError(t, db.GetEngine(db.DefaultContext).Table(bean).Find(ptrToSliceValue.Interface()))
sliceValue = ptrToSliceValue.Elem()
for i := 0; i < sliceValue.Len(); i++ {
@@ -42,9 +44,9 @@ func CheckConsistencyFor(t assert.TestingT, beansToCheck ...any) {
}
}
-func checkForConsistency(t assert.TestingT, bean any) {
+func checkForConsistency(t *testing.T, bean any) {
tb, err := db.TableInfo(bean)
- assert.NoError(t, err)
+ require.NoError(t, err)
f := consistencyCheckMap[tb.Name]
if f == nil {
assert.FailNow(t, "unknown bean type: %#v", bean)
@@ -62,7 +64,7 @@ func init() {
return i
}
- checkForUserConsistency := func(t assert.TestingT, bean any) {
+ checkForUserConsistency := func(t *testing.T, bean any) {
user := reflectionWrap(bean)
AssertCountByCond(t, "repository", builder.Eq{"owner_id": user.int("ID")}, user.int("NumRepos"))
AssertCountByCond(t, "star", builder.Eq{"uid": user.int("ID")}, user.int("NumStars"))
@@ -76,7 +78,7 @@ func init() {
}
}
- checkForRepoConsistency := func(t assert.TestingT, bean any) {
+ checkForRepoConsistency := func(t *testing.T, bean any) {
repo := reflectionWrap(bean)
assert.Equal(t, repo.str("LowerName"), strings.ToLower(repo.str("Name")), "repo: %+v", repo)
AssertCountByCond(t, "star", builder.Eq{"repo_id": repo.int("ID")}, repo.int("NumStars"))
@@ -112,7 +114,7 @@ func init() {
"Unexpected number of closed milestones for repo id: %d", repo.int("ID"))
}
- checkForIssueConsistency := func(t assert.TestingT, bean any) {
+ checkForIssueConsistency := func(t *testing.T, bean any) {
issue := reflectionWrap(bean)
typeComment := modelsCommentTypeComment
actual := GetCountByCond(t, "comment", builder.Eq{"`type`": typeComment, "issue_id": issue.int("ID")})
@@ -123,14 +125,14 @@ func init() {
}
}
- checkForPullRequestConsistency := func(t assert.TestingT, bean any) {
+ checkForPullRequestConsistency := func(t *testing.T, bean any) {
pr := reflectionWrap(bean)
issueRow := AssertExistsAndLoadMap(t, "issue", builder.Eq{"id": pr.int("IssueID")})
assert.True(t, parseBool(issueRow["is_pull"]))
assert.EqualValues(t, parseInt(issueRow["index"]), pr.int("Index"), "Unexpected index for pull request id: %d", pr.int("ID"))
}
- checkForMilestoneConsistency := func(t assert.TestingT, bean any) {
+ checkForMilestoneConsistency := func(t *testing.T, bean any) {
milestone := reflectionWrap(bean)
AssertCountByCond(t, "issue", builder.Eq{"milestone_id": milestone.int("ID")}, milestone.int("NumIssues"))
@@ -144,12 +146,12 @@ func init() {
assert.Equal(t, completeness, milestone.int("Completeness"))
}
- checkForLabelConsistency := func(t assert.TestingT, bean any) {
+ checkForLabelConsistency := func(t *testing.T, bean any) {
label := reflectionWrap(bean)
issueLabels, err := db.GetEngine(db.DefaultContext).Table("issue_label").
Where(builder.Eq{"label_id": label.int("ID")}).
Query()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, issueLabels, label.int("NumIssues"), "Unexpected number of issue for label id: %d", label.int("ID"))
@@ -165,13 +167,13 @@ func init() {
assert.EqualValues(t, expected, label.int("NumClosedIssues"), "Unexpected number of closed issues for label id: %d", label.int("ID"))
}
- checkForTeamConsistency := func(t assert.TestingT, bean any) {
+ checkForTeamConsistency := func(t *testing.T, bean any) {
team := reflectionWrap(bean)
AssertCountByCond(t, "team_user", builder.Eq{"team_id": team.int("ID")}, team.int("NumMembers"))
AssertCountByCond(t, "team_repo", builder.Eq{"team_id": team.int("ID")}, team.int("NumRepos"))
}
- checkForActionConsistency := func(t assert.TestingT, bean any) {
+ checkForActionConsistency := func(t *testing.T, bean any) {
action := reflectionWrap(bean)
if action.int("RepoID") != 1700 { // dangling intentional
repoRow := AssertExistsAndLoadMap(t, "repository", builder.Eq{"id": action.int("RepoID")})
diff --git a/models/unittest/fixture_loader.go b/models/unittest/fixture_loader.go
new file mode 100644
index 0000000000..67ef1b28df
--- /dev/null
+++ b/models/unittest/fixture_loader.go
@@ -0,0 +1,198 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package unittest
+
+import (
+ "database/sql"
+ "encoding/hex"
+ "encoding/json" //nolint:depguard
+ "fmt"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "gopkg.in/yaml.v3"
+)
+
+type insertSQL struct {
+ statement string
+ values []any
+}
+
+type fixtureFile struct {
+ name string
+ insertSQLs []insertSQL
+}
+
+type loader struct {
+ db *sql.DB
+ dialect string
+
+ fixtureFiles []*fixtureFile
+}
+
+func newFixtureLoader(db *sql.DB, dialect string, fixturePaths []string) (*loader, error) {
+ l := &loader{
+ db: db,
+ dialect: dialect,
+ fixtureFiles: []*fixtureFile{},
+ }
+
+ // Load fixtures
+ for _, fixturePath := range fixturePaths {
+ stat, err := os.Stat(fixturePath)
+ if err != nil {
+ return nil, err
+ }
+
+ // If fixture path is a directory, then read read the files of the directory
+ // and use those as fixture files.
+ if stat.IsDir() {
+ files, err := os.ReadDir(fixturePath)
+ if err != nil {
+ return nil, err
+ }
+ for _, file := range files {
+ if !file.IsDir() {
+ fixtureFile, err := l.buildFixtureFile(filepath.Join(fixturePath, file.Name()))
+ if err != nil {
+ return nil, err
+ }
+ l.fixtureFiles = append(l.fixtureFiles, fixtureFile)
+ }
+ }
+ } else {
+ fixtureFile, err := l.buildFixtureFile(fixturePath)
+ if err != nil {
+ return nil, err
+ }
+ l.fixtureFiles = append(l.fixtureFiles, fixtureFile)
+ }
+ }
+
+ return l, nil
+}
+
+// quoteKeyword returns the quoted string of keyword.
+func (l *loader) quoteKeyword(keyword string) string {
+ switch l.dialect {
+ case "sqlite3":
+ return `"` + keyword + `"`
+ case "mysql":
+ return "`" + keyword + "`"
+ case "postgres":
+ parts := strings.Split(keyword, ".")
+ for i, p := range parts {
+ parts[i] = `"` + p + `"`
+ }
+ return strings.Join(parts, ".")
+ default:
+ return "invalid"
+ }
+}
+
+// placeholder returns the placeholder string.
+func (l *loader) placeholder(index int) string {
+ if l.dialect == "postgres" {
+ return fmt.Sprintf("$%d", index)
+ }
+ return "?"
+}
+
+func (l *loader) buildFixtureFile(fixturePath string) (*fixtureFile, error) {
+ f, err := os.Open(fixturePath)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+
+ var records []map[string]any
+ if err := yaml.NewDecoder(f).Decode(&records); err != nil {
+ return nil, err
+ }
+
+ fixture := &fixtureFile{
+ name: filepath.Base(strings.TrimSuffix(f.Name(), filepath.Ext(f.Name()))),
+ insertSQLs: []insertSQL{},
+ }
+
+ for _, record := range records {
+ columns := []string{}
+ sqlValues := []string{}
+ values := []any{}
+ i := 1
+
+ for key, value := range record {
+ columns = append(columns, l.quoteKeyword(key))
+
+ switch v := value.(type) {
+ case string:
+ // Try to decode hex.
+ if strings.HasPrefix(v, "0x") {
+ value, err = hex.DecodeString(strings.TrimPrefix(v, "0x"))
+ if err != nil {
+ return nil, err
+ }
+ }
+ case []any:
+ // Decode array.
+ var bytes []byte
+ bytes, err = json.Marshal(v)
+ if err != nil {
+ return nil, err
+ }
+ value = string(bytes)
+ }
+
+ values = append(values, value)
+
+ sqlValues = append(sqlValues, l.placeholder(i))
+ i++
+ }
+
+ // Construct the insert SQL.
+ fixture.insertSQLs = append(fixture.insertSQLs, insertSQL{
+ statement: fmt.Sprintf(
+ "INSERT INTO %s (%s) VALUES (%s)",
+ l.quoteKeyword(fixture.name),
+ strings.Join(columns, ", "),
+ strings.Join(sqlValues, ", "),
+ ),
+ values: values,
+ })
+ }
+
+ return fixture, nil
+}
+
+func (l *loader) Load() error {
+ // Start transaction.
+ tx, err := l.db.Begin()
+ if err != nil {
+ return err
+ }
+
+ defer func() {
+ _ = tx.Rollback()
+ }()
+
+ // Clean the table and re-insert the fixtures.
+ tableDeleted := map[string]struct{}{}
+ for _, fixture := range l.fixtureFiles {
+ if _, ok := tableDeleted[fixture.name]; !ok {
+ if _, err := tx.Exec(fmt.Sprintf("DELETE FROM %s", l.quoteKeyword(fixture.name))); err != nil {
+ return fmt.Errorf("cannot delete table %s: %w", fixture.name, err)
+ }
+ tableDeleted[fixture.name] = struct{}{}
+ }
+
+ for _, insertSQL := range fixture.insertSQLs {
+ if _, err := tx.Exec(insertSQL.statement, insertSQL.values...); err != nil {
+ return fmt.Errorf("cannot insert %q with values %q: %w", insertSQL.statement, insertSQL.values, err)
+ }
+ }
+ }
+
+ return tx.Commit()
+}
diff --git a/models/unittest/fixtures.go b/models/unittest/fixtures.go
index 63b26a0af7..495f9a2aac 100644
--- a/models/unittest/fixtures.go
+++ b/models/unittest/fixtures.go
@@ -6,20 +6,18 @@ package unittest
import (
"fmt"
- "os"
"path/filepath"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/auth/password/hash"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/auth/password/hash"
+ "forgejo.org/modules/setting"
- "github.com/go-testfixtures/testfixtures/v3"
"xorm.io/xorm"
"xorm.io/xorm/schemas"
)
-var fixturesLoader *testfixtures.Loader
+var fixturesLoader *loader
// GetXORMEngine gets the XORM engine
func GetXORMEngine(engine ...*xorm.Engine) (x *xorm.Engine) {
@@ -29,11 +27,18 @@ func GetXORMEngine(engine ...*xorm.Engine) (x *xorm.Engine) {
return db.DefaultContext.(*db.Context).Engine().(*xorm.Engine)
}
-func OverrideFixtures(opts FixturesOptions, engine ...*xorm.Engine) func() {
+func OverrideFixtures(dir string) func() {
old := fixturesLoader
- if err := InitFixtures(opts, engine...); err != nil {
+
+ opts := FixturesOptions{
+ Dir: filepath.Join(setting.AppWorkPath, "models/fixtures/"),
+ Base: setting.AppWorkPath,
+ Dirs: []string{dir},
+ }
+ if err := InitFixtures(opts); err != nil {
panic(err)
}
+
return func() {
fixturesLoader = old
}
@@ -42,19 +47,19 @@ func OverrideFixtures(opts FixturesOptions, engine ...*xorm.Engine) func() {
// InitFixtures initialize test fixtures for a test database
func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
e := GetXORMEngine(engine...)
- var fixtureOptionFiles func(*testfixtures.Loader) error
+ fixturePaths := []string{}
if opts.Dir != "" {
- fixtureOptionFiles = testfixtures.Directory(opts.Dir)
+ fixturePaths = append(fixturePaths, opts.Dir)
} else {
- fixtureOptionFiles = testfixtures.Files(opts.Files...)
+ fixturePaths = append(fixturePaths, opts.Files...)
}
- var fixtureOptionDirs []func(*testfixtures.Loader) error
if opts.Dirs != nil {
for _, dir := range opts.Dirs {
- fixtureOptionDirs = append(fixtureOptionDirs, testfixtures.Directory(filepath.Join(opts.Base, dir)))
+ fixturePaths = append(fixturePaths, filepath.Join(opts.Base, dir))
}
}
- dialect := "unknown"
+
+ var dialect string
switch e.Dialect().URI().DBType {
case schemas.POSTGRES:
dialect = "postgres"
@@ -63,22 +68,10 @@ func InitFixtures(opts FixturesOptions, engine ...*xorm.Engine) (err error) {
case schemas.SQLITE:
dialect = "sqlite3"
default:
- fmt.Println("Unsupported RDBMS for integration tests")
- os.Exit(1)
- }
- loaderOptions := []func(loader *testfixtures.Loader) error{
- testfixtures.Database(e.DB().DB),
- testfixtures.Dialect(dialect),
- testfixtures.DangerousSkipTestDatabaseCheck(),
- fixtureOptionFiles,
- }
- loaderOptions = append(loaderOptions, fixtureOptionDirs...)
-
- if e.Dialect().URI().DBType == schemas.POSTGRES {
- loaderOptions = append(loaderOptions, testfixtures.SkipResetSequences())
+ panic("Unsupported RDBMS for test")
}
- fixturesLoader, err = testfixtures.New(loaderOptions...)
+ fixturesLoader, err = newFixtureLoader(e.DB().DB, dialect, fixturePaths)
if err != nil {
return err
}
diff --git a/models/unittest/fscopy.go b/models/unittest/fscopy.go
index 74b12d5057..5cd871ced6 100644
--- a/models/unittest/fscopy.go
+++ b/models/unittest/fscopy.go
@@ -4,99 +4,12 @@
package unittest
import (
- "errors"
- "io"
"os"
- "path"
- "strings"
-
- "code.gitea.io/gitea/modules/util"
)
-// Copy copies file from source to target path.
-func Copy(src, dest string) error {
- // Gather file information to set back later.
- si, err := os.Lstat(src)
- if err != nil {
- return err
- }
-
- // Handle symbolic link.
- if si.Mode()&os.ModeSymlink != 0 {
- target, err := os.Readlink(src)
- if err != nil {
- return err
- }
- // NOTE: os.Chmod and os.Chtimes don't recognize symbolic link,
- // which will lead "no such file or directory" error.
- return os.Symlink(target, dest)
- }
-
- sr, err := os.Open(src)
- if err != nil {
- return err
- }
- defer sr.Close()
-
- dw, err := os.Create(dest)
- if err != nil {
- return err
- }
- defer dw.Close()
-
- if _, err = io.Copy(dw, sr); err != nil {
- return err
- }
-
- // Set back file information.
- if err = os.Chtimes(dest, si.ModTime(), si.ModTime()); err != nil {
- return err
- }
- return os.Chmod(dest, si.Mode())
-}
-
// CopyDir copy files recursively from source to target directory.
//
-// The filter accepts a function that process the path info.
-// and should return true for need to filter.
-//
// It returns error when error occurs in underlying functions.
-func CopyDir(srcPath, destPath string, filters ...func(filePath string) bool) error {
- // Check if target directory exists.
- if _, err := os.Stat(destPath); !errors.Is(err, os.ErrNotExist) {
- return util.NewAlreadyExistErrorf("file or directory already exists: %s", destPath)
- }
-
- err := os.MkdirAll(destPath, os.ModePerm)
- if err != nil {
- return err
- }
-
- // Gather directory info.
- infos, err := util.StatDir(srcPath, true)
- if err != nil {
- return err
- }
-
- var filter func(filePath string) bool
- if len(filters) > 0 {
- filter = filters[0]
- }
-
- for _, info := range infos {
- if filter != nil && filter(info) {
- continue
- }
-
- curPath := path.Join(destPath, info)
- if strings.HasSuffix(info, "/") {
- err = os.MkdirAll(curPath, os.ModePerm)
- } else {
- err = Copy(path.Join(srcPath, info), curPath)
- }
- if err != nil {
- return err
- }
- }
- return nil
+func CopyDir(srcPath, destPath string) error {
+ return os.CopyFS(destPath, os.DirFS(srcPath))
}
diff --git a/models/unittest/mock_http.go b/models/unittest/mock_http.go
index e2c181408b..e749275282 100644
--- a/models/unittest/mock_http.go
+++ b/models/unittest/mock_http.go
@@ -15,9 +15,10 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
// Mocks HTTP responses of a third-party service (such as GitHub, GitLabโฆ)
@@ -32,6 +33,11 @@ func NewMockWebServer(t *testing.T, liveServerBaseURL, testDataDir string, liveM
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
path := NormalizedFullPath(r.URL)
+ isGh := liveServerBaseURL == "https://api.github.com"
+ if isGh {
+ // Workaround for GitHub: trim `/api/v3` from the path
+ path = strings.TrimPrefix(path, "/api/v3")
+ }
log.Info("Mock HTTP Server: got request for path %s", r.URL.Path)
// TODO check request method (support POST?)
fixturePath := fmt.Sprintf("%s/%s_%s", testDataDir, r.Method, url.PathEscape(path))
@@ -39,7 +45,7 @@ func NewMockWebServer(t *testing.T, liveServerBaseURL, testDataDir string, liveM
liveURL := fmt.Sprintf("%s%s", liveServerBaseURL, path)
request, err := http.NewRequest(r.Method, liveURL, nil)
- assert.NoError(t, err, "constructing an HTTP request to %s failed", liveURL)
+ require.NoError(t, err, "constructing an HTTP request to %s failed", liveURL)
for headerName, headerValues := range r.Header {
// do not pass on the encoding: let the Transport of the HTTP client handle that for us
if strings.ToLower(headerName) != "accept-encoding" {
@@ -50,11 +56,11 @@ func NewMockWebServer(t *testing.T, liveServerBaseURL, testDataDir string, liveM
}
response, err := http.DefaultClient.Do(request)
- assert.NoError(t, err, "HTTP request to %s failed: %s", liveURL)
+ require.NoError(t, err, "HTTP request to %s failed: %s", liveURL)
assert.Less(t, response.StatusCode, 400, "unexpected status code for %s", liveURL)
fixture, err := os.Create(fixturePath)
- assert.NoError(t, err, "failed to open the fixture file %s for writing", fixturePath)
+ require.NoError(t, err, "failed to open the fixture file %s for writing", fixturePath)
defer fixture.Close()
fixtureWriter := bufio.NewWriter(fixture)
@@ -62,29 +68,33 @@ func NewMockWebServer(t *testing.T, liveServerBaseURL, testDataDir string, liveM
for _, headerValue := range headerValues {
if !slices.Contains(ignoredHeaders, strings.ToLower(headerName)) {
_, err := fixtureWriter.WriteString(fmt.Sprintf("%s: %s\n", headerName, headerValue))
- assert.NoError(t, err, "writing the header of the HTTP response to the fixture file failed")
+ require.NoError(t, err, "writing the header of the HTTP response to the fixture file failed")
}
}
}
_, err = fixtureWriter.WriteString("\n")
- assert.NoError(t, err, "writing the header of the HTTP response to the fixture file failed")
+ require.NoError(t, err, "writing the header of the HTTP response to the fixture file failed")
fixtureWriter.Flush()
log.Info("Mock HTTP Server: writing response to %s", fixturePath)
_, err = io.Copy(fixture, response.Body)
- assert.NoError(t, err, "writing the body of the HTTP response to %s failed", liveURL)
+ require.NoError(t, err, "writing the body of the HTTP response to %s failed", liveURL)
err = fixture.Sync()
- assert.NoError(t, err, "writing the body of the HTTP response to the fixture file failed")
+ require.NoError(t, err, "writing the body of the HTTP response to the fixture file failed")
}
fixture, err := os.ReadFile(fixturePath)
- assert.NoError(t, err, "missing mock HTTP response: "+fixturePath)
+ require.NoError(t, err, "missing mock HTTP response: "+fixturePath)
w.WriteHeader(http.StatusOK)
// replace any mention of the live HTTP service by the mocked host
stringFixture := strings.ReplaceAll(string(fixture), liveServerBaseURL, mockServerBaseURL)
+ if isGh {
+ // Workaround for GitHub: replace github.com by the mock server's base URL
+ stringFixture = strings.ReplaceAll(stringFixture, "https://github.com", mockServerBaseURL)
+ }
// parse back the fixture file into a series of HTTP headers followed by response body
lines := strings.Split(stringFixture, "\n")
for idx, line := range lines {
@@ -95,7 +105,7 @@ func NewMockWebServer(t *testing.T, liveServerBaseURL, testDataDir string, liveM
// we reached the end of the headers (empty line), so what follows is the body
responseBody := strings.Join(lines[idx+1:], "\n")
_, err := w.Write([]byte(responseBody))
- assert.NoError(t, err, "writing the body of the HTTP response failed")
+ require.NoError(t, err, "writing the body of the HTTP response failed")
break
}
}
diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go
index af5c31f157..d34c9e9a0a 100644
--- a/models/unittest/testdb.go
+++ b/models/unittest/testdb.go
@@ -12,17 +12,17 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/system"
- "code.gitea.io/gitea/modules/auth/password/hash"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/setting/config"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/models/system"
+ "forgejo.org/modules/auth/password/hash"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/setting/config"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/util"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/xorm"
"xorm.io/xorm/names"
)
@@ -59,6 +59,13 @@ func InitSettings() {
_ = hash.Register("dummy", hash.NewDummyHasher)
setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
+ setting.InitGiteaEnvVars()
+
+ // Avoid loading the git's system config.
+ // On macOS, system config sets the osxkeychain credential helper, which will cause tests to freeze with a dialog.
+ // But we do not set it in production at the moment, because it might be a "breaking" change,
+ // more details are in "modules/git.commonBaseEnvs".
+ _ = os.Setenv("GIT_CONFIG_NOSYSTEM", "true")
}
// TestOptions represents test options
@@ -243,18 +250,18 @@ func PrepareTestDatabase() error {
// PrepareTestEnv prepares the environment for unit tests. Can only be called
// by tests that use the above MainTest(..) function.
func PrepareTestEnv(t testing.TB) {
- assert.NoError(t, PrepareTestDatabase())
- assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
+ require.NoError(t, PrepareTestDatabase())
+ require.NoError(t, util.RemoveAll(setting.RepoRootPath))
metaPath := filepath.Join(giteaRoot, "tests", "gitea-repositories-meta")
- assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath))
+ require.NoError(t, CopyDir(metaPath, setting.RepoRootPath))
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, ownerDir := range ownerDirs {
if !ownerDir.Type().IsDir() {
continue
}
repoDirs, err := os.ReadDir(filepath.Join(setting.RepoRootPath, ownerDir.Name()))
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, repoDir := range repoDirs {
_ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "pack"), 0o755)
_ = os.MkdirAll(filepath.Join(setting.RepoRootPath, ownerDir.Name(), repoDir.Name(), "objects", "info"), 0o755)
diff --git a/models/unittest/unit_tests.go b/models/unittest/unit_tests.go
index 75898436fc..a7c8e9c2fa 100644
--- a/models/unittest/unit_tests.go
+++ b/models/unittest/unit_tests.go
@@ -5,10 +5,12 @@ package unittest
import (
"math"
+ "testing"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
"xorm.io/builder"
)
@@ -57,16 +59,16 @@ func LoadBeanIfExists(bean any, conditions ...any) (bool, error) {
}
// BeanExists for testing, check if a bean exists
-func BeanExists(t assert.TestingT, bean any, conditions ...any) bool {
+func BeanExists(t testing.TB, bean any, conditions ...any) bool {
exists, err := LoadBeanIfExists(bean, conditions...)
- assert.NoError(t, err)
+ require.NoError(t, err)
return exists
}
// AssertExistsAndLoadBean assert that a bean exists and load it from the test database
-func AssertExistsAndLoadBean[T any](t assert.TestingT, bean T, conditions ...any) T {
+func AssertExistsAndLoadBean[T any](t testing.TB, bean T, conditions ...any) T {
exists, err := LoadBeanIfExists(bean, conditions...)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists,
"Expected to find %+v (of type %T, with conditions %+v), but did not",
bean, bean, conditions)
@@ -74,11 +76,11 @@ func AssertExistsAndLoadBean[T any](t assert.TestingT, bean T, conditions ...any
}
// AssertExistsAndLoadMap assert that a row exists and load it from the test database
-func AssertExistsAndLoadMap(t assert.TestingT, table string, conditions ...any) map[string]string {
+func AssertExistsAndLoadMap(t testing.TB, table string, conditions ...any) map[string]string {
e := db.GetEngine(db.DefaultContext).Table(table)
res, err := whereOrderConditions(e, conditions).Query()
- assert.NoError(t, err)
- assert.True(t, len(res) == 1,
+ require.NoError(t, err)
+ assert.Len(t, res, 1,
"Expected to find one row in %s (with conditions %+v), but found %d",
table, conditions, len(res),
)
@@ -94,7 +96,7 @@ func AssertExistsAndLoadMap(t assert.TestingT, table string, conditions ...any)
}
// GetCount get the count of a bean
-func GetCount(t assert.TestingT, bean any, conditions ...any) int {
+func GetCount(t testing.TB, bean any, conditions ...any) int {
e := db.GetEngine(db.DefaultContext)
for _, condition := range conditions {
switch cond := condition.(type) {
@@ -105,52 +107,58 @@ func GetCount(t assert.TestingT, bean any, conditions ...any) int {
}
}
count, err := e.Count(bean)
- assert.NoError(t, err)
+ require.NoError(t, err)
return int(count)
}
// AssertNotExistsBean assert that a bean does not exist in the test database
-func AssertNotExistsBean(t assert.TestingT, bean any, conditions ...any) {
+func AssertNotExistsBean(t testing.TB, bean any, conditions ...any) {
exists, err := LoadBeanIfExists(bean, conditions...)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, exists)
}
// AssertExistsIf asserts that a bean exists or does not exist, depending on
// what is expected.
-func AssertExistsIf(t assert.TestingT, expected bool, bean any, conditions ...any) {
+func AssertExistsIf(t testing.TB, expected bool, bean any, conditions ...any) {
exists, err := LoadBeanIfExists(bean, conditions...)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, exists)
}
// AssertSuccessfulInsert assert that beans is successfully inserted
-func AssertSuccessfulInsert(t assert.TestingT, beans ...any) {
+func AssertSuccessfulInsert(t testing.TB, beans ...any) {
err := db.Insert(db.DefaultContext, beans...)
- assert.NoError(t, err)
+ require.NoError(t, err)
+}
+
+// AssertSuccessfulDelete assert that beans is successfully deleted
+func AssertSuccessfulDelete(t require.TestingT, beans ...any) {
+ err := db.DeleteBeans(db.DefaultContext, beans...)
+ require.NoError(t, err)
}
// AssertCount assert the count of a bean
-func AssertCount(t assert.TestingT, bean, expected any) bool {
+func AssertCount(t testing.TB, bean, expected any) bool {
return assert.EqualValues(t, expected, GetCount(t, bean))
}
// AssertInt64InRange assert value is in range [low, high]
-func AssertInt64InRange(t assert.TestingT, low, high, value int64) {
+func AssertInt64InRange(t testing.TB, low, high, value int64) {
assert.True(t, value >= low && value <= high,
"Expected value in range [%d, %d], found %d", low, high, value)
}
// GetCountByCond get the count of database entries matching bean
-func GetCountByCond(t assert.TestingT, tableName string, cond builder.Cond) int64 {
+func GetCountByCond(t testing.TB, tableName string, cond builder.Cond) int64 {
e := db.GetEngine(db.DefaultContext)
count, err := e.Table(tableName).Where(cond).Count()
- assert.NoError(t, err)
+ require.NoError(t, err)
return count
}
// AssertCountByCond test the count of database entries matching bean
-func AssertCountByCond(t assert.TestingT, tableName string, cond builder.Cond, expected int) bool {
+func AssertCountByCond(t testing.TB, tableName string, cond builder.Cond, expected int) bool {
return assert.EqualValues(t, expected, GetCountByCond(t, tableName, cond),
"Failed consistency test, the counted bean (of table %s) was %+v", tableName, cond)
}
diff --git a/models/user/avatar.go b/models/user/avatar.go
index c6937d7b51..27af7f774d 100644
--- a/models/user/avatar.go
+++ b/models/user/avatar.go
@@ -11,12 +11,12 @@ import (
"io"
"strings"
- "code.gitea.io/gitea/models/avatars"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/avatar"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
+ "forgejo.org/models/avatars"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/avatar"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
)
// CustomAvatarRelativePath returns user custom avatar relative path.
@@ -38,14 +38,18 @@ func GenerateRandomAvatar(ctx context.Context, u *User) error {
u.Avatar = avatars.HashEmail(seed)
- // Don't share the images so that we can delete them easily
- if err := storage.SaveFrom(storage.Avatars, u.CustomAvatarRelativePath(), func(w io.Writer) error {
- if err := png.Encode(w, img); err != nil {
- log.Error("Encode: %v", err)
+ _, err = storage.Avatars.Stat(u.CustomAvatarRelativePath())
+ if err != nil {
+ // If unable to Stat the avatar file (usually it means non-existing), then try to save a new one
+ // Don't share the images so that we can delete them easily
+ if err := storage.SaveFrom(storage.Avatars, u.CustomAvatarRelativePath(), func(w io.Writer) error {
+ if err := png.Encode(w, img); err != nil {
+ log.Error("Encode: %v", err)
+ }
+ return nil
+ }); err != nil {
+ return fmt.Errorf("failed to save avatar %s: %w", u.CustomAvatarRelativePath(), err)
}
- return err
- }); err != nil {
- return fmt.Errorf("Failed to create dir %s: %w", u.CustomAvatarRelativePath(), err)
}
if _, err := db.GetEngine(ctx).ID(u.ID).Cols("avatar").Update(u); err != nil {
diff --git a/models/user/avatar_test.go b/models/user/avatar_test.go
new file mode 100644
index 0000000000..d3a164142d
--- /dev/null
+++ b/models/user/avatar_test.go
@@ -0,0 +1,67 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package user
+
+import (
+ "io"
+ "strings"
+ "testing"
+
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/test"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestUserAvatarLink(t *testing.T) {
+ defer test.MockVariableValue(&setting.AppURL, "https://localhost/")()
+ defer test.MockVariableValue(&setting.AppSubURL, "")()
+
+ u := &User{ID: 1, Avatar: "avatar.png"}
+ link := u.AvatarLink(db.DefaultContext)
+ assert.Equal(t, "https://localhost/avatars/avatar.png", link)
+
+ setting.AppURL = "https://localhost/sub-path/"
+ setting.AppSubURL = "/sub-path"
+ link = u.AvatarLink(db.DefaultContext)
+ assert.Equal(t, "https://localhost/sub-path/avatars/avatar.png", link)
+}
+
+func TestUserAvatarGenerate(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ var err error
+ tmpDir := t.TempDir()
+ storage.Avatars, err = storage.NewLocalStorage(t.Context(), &setting.Storage{Path: tmpDir})
+ require.NoError(t, err)
+
+ u := unittest.AssertExistsAndLoadBean(t, &User{ID: 2})
+
+ // there was no avatar, generate a new one
+ assert.Empty(t, u.Avatar)
+ err = GenerateRandomAvatar(db.DefaultContext, u)
+ require.NoError(t, err)
+ assert.NotEmpty(t, u.Avatar)
+
+ // make sure the generated one exists
+ oldAvatarPath := u.CustomAvatarRelativePath()
+ _, err = storage.Avatars.Stat(u.CustomAvatarRelativePath())
+ require.NoError(t, err)
+ // and try to change its content
+ _, err = storage.Avatars.Save(u.CustomAvatarRelativePath(), strings.NewReader("abcd"), 4)
+ require.NoError(t, err)
+
+ // try to generate again
+ err = GenerateRandomAvatar(db.DefaultContext, u)
+ require.NoError(t, err)
+ assert.Equal(t, oldAvatarPath, u.CustomAvatarRelativePath())
+ f, err := storage.Avatars.Open(u.CustomAvatarRelativePath())
+ require.NoError(t, err)
+ defer f.Close()
+ content, _ := io.ReadAll(f)
+ assert.Equal(t, "abcd", string(content))
+}
diff --git a/models/user/badge.go b/models/user/badge.go
index ee52b44cf5..e54c993a37 100644
--- a/models/user/badge.go
+++ b/models/user/badge.go
@@ -6,7 +6,7 @@ package user
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
// Badge represents a user badge
diff --git a/models/user/block.go b/models/user/block.go
index 189cacc2a2..2e3cfc2fa3 100644
--- a/models/user/block.go
+++ b/models/user/block.go
@@ -7,8 +7,8 @@ import (
"context"
"errors"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
)
// ErrBlockedByUser defines an error stating that the user is not allowed to perform the action because they are blocked.
diff --git a/models/user/block_test.go b/models/user/block_test.go
index 629c0c975a..b1674bf2ff 100644
--- a/models/user/block_test.go
+++ b/models/user/block_test.go
@@ -6,15 +6,16 @@ package user_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIsBlocked(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.True(t, user_model.IsBlocked(db.DefaultContext, 4, 1))
// Simple test cases to ensure the function can also respond with false.
@@ -23,7 +24,7 @@ func TestIsBlocked(t *testing.T) {
}
func TestIsBlockedMultiple(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.True(t, user_model.IsBlockedMultiple(db.DefaultContext, []int64{4}, 1))
assert.True(t, user_model.IsBlockedMultiple(db.DefaultContext, []int64{4, 3, 4, 5}, 1))
@@ -33,20 +34,20 @@ func TestIsBlockedMultiple(t *testing.T) {
}
func TestUnblockUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.True(t, user_model.IsBlocked(db.DefaultContext, 4, 1))
- assert.NoError(t, user_model.UnblockUser(db.DefaultContext, 4, 1))
+ require.NoError(t, user_model.UnblockUser(db.DefaultContext, 4, 1))
// Simple test cases to ensure the function can also respond with false.
assert.False(t, user_model.IsBlocked(db.DefaultContext, 4, 1))
}
func TestListBlockedUsers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
blockedUsers, err := user_model.ListBlockedUsers(db.DefaultContext, 4, db.ListOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, blockedUsers, 1) {
assert.EqualValues(t, 1, blockedUsers[0].ID)
// The function returns the created Unix of the block, not that of the user.
@@ -55,23 +56,23 @@ func TestListBlockedUsers(t *testing.T) {
}
func TestListBlockedByUsersID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
blockedByUserIDs, err := user_model.ListBlockedByUsersID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, blockedByUserIDs, 1) {
assert.EqualValues(t, 4, blockedByUserIDs[0])
}
}
func TestCountBlockedUsers(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
count, err := user_model.CountBlockedUsers(db.DefaultContext, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, count)
count, err = user_model.CountBlockedUsers(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, count)
}
diff --git a/models/user/email_address.go b/models/user/email_address.go
index 18bf6d0b89..f9eaec56c9 100644
--- a/models/user/email_address.go
+++ b/models/user/email_address.go
@@ -7,64 +7,17 @@ package user
import (
"context"
"fmt"
- "net/mail"
- "regexp"
"strings"
- "time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
-// ErrEmailNotActivated e-mail address has not been activated error
-var ErrEmailNotActivated = util.NewInvalidArgumentErrorf("e-mail address has not been activated")
-
-// ErrEmailCharIsNotSupported e-mail address contains unsupported character
-type ErrEmailCharIsNotSupported struct {
- Email string
-}
-
-// IsErrEmailCharIsNotSupported checks if an error is an ErrEmailCharIsNotSupported
-func IsErrEmailCharIsNotSupported(err error) bool {
- _, ok := err.(ErrEmailCharIsNotSupported)
- return ok
-}
-
-func (err ErrEmailCharIsNotSupported) Error() string {
- return fmt.Sprintf("e-mail address contains unsupported character [email: %s]", err.Email)
-}
-
-func (err ErrEmailCharIsNotSupported) Unwrap() error {
- return util.ErrInvalidArgument
-}
-
-// ErrEmailInvalid represents an error where the email address does not comply with RFC 5322
-// or has a leading '-' character
-type ErrEmailInvalid struct {
- Email string
-}
-
-// IsErrEmailInvalid checks if an error is an ErrEmailInvalid
-func IsErrEmailInvalid(err error) bool {
- _, ok := err.(ErrEmailInvalid)
- return ok
-}
-
-func (err ErrEmailInvalid) Error() string {
- return fmt.Sprintf("e-mail invalid [email: %s]", err.Email)
-}
-
-func (err ErrEmailInvalid) Unwrap() error {
- return util.ErrInvalidArgument
-}
-
// ErrEmailAlreadyUsed represents a "EmailAlreadyUsed" kind of error.
type ErrEmailAlreadyUsed struct {
Email string
@@ -156,22 +109,6 @@ func UpdateEmailAddress(ctx context.Context, email *EmailAddress) error {
return err
}
-var emailRegexp = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
-
-// ValidateEmail check if email is a valid & allowed address
-func ValidateEmail(email string) error {
- if err := validateEmailBasic(email); err != nil {
- return err
- }
- return validateEmailDomain(email)
-}
-
-// ValidateEmailForAdmin check if email is a valid address when admins manually add or edit users
-func ValidateEmailForAdmin(email string) error {
- return validateEmailBasic(email)
- // In this case we do not need to check the email domain
-}
-
func GetEmailAddressByEmail(ctx context.Context, email string) (*EmailAddress, error) {
ea := &EmailAddress{}
if has, err := db.GetEngine(ctx).Where("lower_email=?", strings.ToLower(email)).Get(ea); err != nil {
@@ -202,6 +139,38 @@ func GetPrimaryEmailAddressOfUser(ctx context.Context, uid int64) (*EmailAddress
return ea, nil
}
+// Deletes the primary email address of the user
+// This is only allowed if the user is a organization
+func DeletePrimaryEmailAddressOfUser(ctx context.Context, uid int64) error {
+ user, err := GetUserByID(ctx, uid)
+ if err != nil {
+ return err
+ }
+
+ if user.Type != UserTypeOrganization {
+ return fmt.Errorf("%s is not a organization", user.Name)
+ }
+
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return err
+ }
+ defer committer.Close()
+
+ _, err = db.GetEngine(ctx).Exec("DELETE FROM email_address WHERE uid = ? AND is_primary = true", uid)
+ if err != nil {
+ return err
+ }
+
+ user.Email = ""
+ err = UpdateUserCols(ctx, user, "email")
+ if err != nil {
+ return err
+ }
+
+ return committer.Commit()
+}
+
// GetEmailAddresses returns all email addresses belongs to given user.
func GetEmailAddresses(ctx context.Context, uid int64) ([]*EmailAddress, error) {
emails := make([]*EmailAddress, 0, 5)
@@ -307,77 +276,6 @@ func updateActivation(ctx context.Context, email *EmailAddress, activate bool) e
return UpdateUserCols(ctx, user, "rands")
}
-func MakeEmailPrimaryWithUser(ctx context.Context, user *User, email *EmailAddress) error {
- ctx, committer, err := db.TxContext(ctx)
- if err != nil {
- return err
- }
- defer committer.Close()
- sess := db.GetEngine(ctx)
-
- // 1. Update user table
- user.Email = email.Email
- if _, err = sess.ID(user.ID).Cols("email").Update(user); err != nil {
- return err
- }
-
- // 2. Update old primary email
- if _, err = sess.Where("uid=? AND is_primary=?", email.UID, true).Cols("is_primary").Update(&EmailAddress{
- IsPrimary: false,
- }); err != nil {
- return err
- }
-
- // 3. update new primary email
- email.IsPrimary = true
- if _, err = sess.ID(email.ID).Cols("is_primary").Update(email); err != nil {
- return err
- }
-
- return committer.Commit()
-}
-
-// MakeEmailPrimary sets primary email address of given user.
-func MakeEmailPrimary(ctx context.Context, email *EmailAddress) error {
- has, err := db.GetEngine(ctx).Get(email)
- if err != nil {
- return err
- } else if !has {
- return ErrEmailAddressNotExist{Email: email.Email}
- }
-
- if !email.IsActivated {
- return ErrEmailNotActivated
- }
-
- user := &User{}
- has, err = db.GetEngine(ctx).ID(email.UID).Get(user)
- if err != nil {
- return err
- } else if !has {
- return ErrUserNotExist{UID: email.UID}
- }
-
- return MakeEmailPrimaryWithUser(ctx, user, email)
-}
-
-// VerifyActiveEmailCode verifies active email code when active account
-func VerifyActiveEmailCode(ctx context.Context, code, email string) *EmailAddress {
- if user := GetVerifyUser(ctx, code); user != nil {
- // time limit code
- prefix := code[:base.TimeLimitCodeLength]
- data := fmt.Sprintf("%d%s%s%s%s", user.ID, email, user.LowerName, user.Passwd, user.Rands)
-
- if base.VerifyTimeLimitCode(time.Now(), data, setting.Service.ActiveCodeLives, prefix) {
- emailAddress := &EmailAddress{UID: user.ID, Email: email}
- if has, _ := db.GetEngine(ctx).Get(emailAddress); has {
- return emailAddress
- }
- }
- }
- return nil
-}
-
// SearchEmailOrderBy is used to sort the results from SearchEmails()
type SearchEmailOrderBy string
@@ -404,6 +302,7 @@ type SearchEmailOptions struct {
// SearchEmailResult is an e-mail address found in the user or email_address table
type SearchEmailResult struct {
+ ID int64
UID int64
Email string
IsActivated bool
@@ -515,41 +414,3 @@ func ActivateUserEmail(ctx context.Context, userID int64, email string, activate
return committer.Commit()
}
-
-// validateEmailBasic checks whether the email complies with the rules
-func validateEmailBasic(email string) error {
- if len(email) == 0 {
- return ErrEmailInvalid{email}
- }
-
- if !emailRegexp.MatchString(email) {
- return ErrEmailCharIsNotSupported{email}
- }
-
- if email[0] == '-' {
- return ErrEmailInvalid{email}
- }
-
- if _, err := mail.ParseAddress(email); err != nil {
- return ErrEmailInvalid{email}
- }
-
- return nil
-}
-
-// validateEmailDomain checks whether the email domain is allowed or blocked
-func validateEmailDomain(email string) error {
- if !IsEmailDomainAllowed(email) {
- return ErrEmailInvalid{email}
- }
-
- return nil
-}
-
-func IsEmailDomainAllowed(email string) bool {
- if len(setting.Service.EmailDomainAllowList) == 0 {
- return !validation.IsEmailDomainListed(setting.Service.EmailDomainBlockList, email)
- }
-
- return validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, email)
-}
diff --git a/models/user/email_address_test.go b/models/user/email_address_test.go
index 65befa5660..1801f57a23 100644
--- a/models/user/email_address_test.go
+++ b/models/user/email_address_test.go
@@ -7,16 +7,17 @@ import (
"fmt"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetEmailAddresses(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1))
if assert.Len(t, emails, 3) {
@@ -33,7 +34,7 @@ func TestGetEmailAddresses(t *testing.T) {
}
func TestIsEmailUsed(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
isExist, _ := user_model.IsEmailUsed(db.DefaultContext, "")
assert.True(t, isExist)
@@ -43,49 +44,15 @@ func TestIsEmailUsed(t *testing.T) {
assert.False(t, isExist)
}
-func TestMakeEmailPrimary(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
-
- email := &user_model.EmailAddress{
- Email: "user567890@example.com",
- }
- err := user_model.MakeEmailPrimary(db.DefaultContext, email)
- assert.Error(t, err)
- assert.EqualError(t, err, user_model.ErrEmailAddressNotExist{Email: email.Email}.Error())
-
- email = &user_model.EmailAddress{
- Email: "user11@example.com",
- }
- err = user_model.MakeEmailPrimary(db.DefaultContext, email)
- assert.Error(t, err)
- assert.EqualError(t, err, user_model.ErrEmailNotActivated.Error())
-
- email = &user_model.EmailAddress{
- Email: "user9999999@example.com",
- }
- err = user_model.MakeEmailPrimary(db.DefaultContext, email)
- assert.Error(t, err)
- assert.True(t, user_model.IsErrUserNotExist(err))
-
- email = &user_model.EmailAddress{
- Email: "user101@example.com",
- }
- err = user_model.MakeEmailPrimary(db.DefaultContext, email)
- assert.NoError(t, err)
-
- user, _ := user_model.GetUserByID(db.DefaultContext, int64(10))
- assert.Equal(t, "user101@example.com", user.Email)
-}
-
func TestActivate(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
email := &user_model.EmailAddress{
ID: int64(1),
UID: int64(1),
Email: "user11@example.com",
}
- assert.NoError(t, user_model.ActivateEmail(db.DefaultContext, email))
+ require.NoError(t, user_model.ActivateEmail(db.DefaultContext, email))
emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1))
assert.Len(t, emails, 3)
@@ -97,7 +64,7 @@ func TestActivate(t *testing.T) {
}
func TestListEmails(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Must find all users and their emails
opts := &user_model.SearchEmailOptions{
@@ -106,9 +73,8 @@ func TestListEmails(t *testing.T) {
},
}
emails, count, err := user_model.SearchEmails(db.DefaultContext, opts)
- assert.NoError(t, err)
- assert.NotEqual(t, int64(0), count)
- assert.True(t, count > 5)
+ require.NoError(t, err)
+ assert.Greater(t, count, int64(5))
contains := func(match func(s *user_model.SearchEmailResult) bool) bool {
for _, v := range emails {
@@ -126,13 +92,13 @@ func TestListEmails(t *testing.T) {
// Must find no records
opts = &user_model.SearchEmailOptions{Keyword: "NOTFOUND"}
emails, count, err = user_model.SearchEmails(db.DefaultContext, opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(0), count)
// Must find users 'user2', 'user28', etc.
opts = &user_model.SearchEmailOptions{Keyword: "user2"}
emails, count, err = user_model.SearchEmails(db.DefaultContext, opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotEqual(t, int64(0), count)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 2 }))
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 27 }))
@@ -140,14 +106,14 @@ func TestListEmails(t *testing.T) {
// Must find only primary addresses (i.e. from the `user` table)
opts = &user_model.SearchEmailOptions{IsPrimary: optional.Some(true)}
emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary }))
assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary }))
// Must find only inactive addresses (i.e. not validated)
opts = &user_model.SearchEmailOptions{IsActivated: optional.Some(false)}
emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated }))
assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsActivated }))
@@ -159,70 +125,13 @@ func TestListEmails(t *testing.T) {
},
}
emails, count, err = user_model.SearchEmails(db.DefaultContext, opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, emails, 5)
assert.Greater(t, count, int64(len(emails)))
}
-func TestEmailAddressValidate(t *testing.T) {
- kases := map[string]error{
- "abc@gmail.com": nil,
- "132@hotmail.com": nil,
- "1-3-2@test.org": nil,
- "1.3.2@test.org": nil,
- "a_123@test.org.cn": nil,
- `first.last@iana.org`: nil,
- `first!last@iana.org`: nil,
- `first#last@iana.org`: nil,
- `first$last@iana.org`: nil,
- `first%last@iana.org`: nil,
- `first&last@iana.org`: nil,
- `first'last@iana.org`: nil,
- `first*last@iana.org`: nil,
- `first+last@iana.org`: nil,
- `first/last@iana.org`: nil,
- `first=last@iana.org`: nil,
- `first?last@iana.org`: nil,
- `first^last@iana.org`: nil,
- "first`last@iana.org": nil,
- `first{last@iana.org`: nil,
- `first|last@iana.org`: nil,
- `first}last@iana.org`: nil,
- `first~last@iana.org`: nil,
- `first;last@iana.org`: user_model.ErrEmailCharIsNotSupported{`first;last@iana.org`},
- ".233@qq.com": user_model.ErrEmailInvalid{".233@qq.com"},
- "!233@qq.com": nil,
- "#233@qq.com": nil,
- "$233@qq.com": nil,
- "%233@qq.com": nil,
- "&233@qq.com": nil,
- "'233@qq.com": nil,
- "*233@qq.com": nil,
- "+233@qq.com": nil,
- "-233@qq.com": user_model.ErrEmailInvalid{"-233@qq.com"},
- "/233@qq.com": nil,
- "=233@qq.com": nil,
- "?233@qq.com": nil,
- "^233@qq.com": nil,
- "_233@qq.com": nil,
- "`233@qq.com": nil,
- "{233@qq.com": nil,
- "|233@qq.com": nil,
- "}233@qq.com": nil,
- "~233@qq.com": nil,
- ";233@qq.com": user_model.ErrEmailCharIsNotSupported{";233@qq.com"},
- "Foo ": user_model.ErrEmailCharIsNotSupported{"Foo "},
- string([]byte{0xE2, 0x84, 0xAA}): user_model.ErrEmailCharIsNotSupported{string([]byte{0xE2, 0x84, 0xAA})},
- }
- for kase, err := range kases {
- t.Run(kase, func(t *testing.T) {
- assert.EqualValues(t, err, user_model.ValidateEmail(kase))
- })
- }
-}
-
func TestGetActivatedEmailAddresses(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testCases := []struct {
UID int64
@@ -249,8 +158,26 @@ func TestGetActivatedEmailAddresses(t *testing.T) {
for _, testCase := range testCases {
t.Run(fmt.Sprintf("User %d", testCase.UID), func(t *testing.T) {
emails, err := user_model.GetActivatedEmailAddresses(db.DefaultContext, testCase.UID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testCase.expected, emails)
})
}
}
+
+func TestDeletePrimaryEmailAddressOfUser(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ user, err := user_model.GetUserByName(db.DefaultContext, "org3")
+ require.NoError(t, err)
+ assert.Equal(t, "org3@example.com", user.Email)
+
+ require.NoError(t, user_model.DeletePrimaryEmailAddressOfUser(db.DefaultContext, user.ID))
+
+ user, err = user_model.GetUserByName(db.DefaultContext, "org3")
+ require.NoError(t, err)
+ assert.Empty(t, user.Email)
+
+ email, err := user_model.GetPrimaryEmailAddressOfUser(db.DefaultContext, user.ID)
+ assert.True(t, user_model.IsErrEmailAddressNotExist(err))
+ assert.Nil(t, email)
+}
diff --git a/models/user/error.go b/models/user/error.go
index cbf19998d1..a0fc1af2bd 100644
--- a/models/user/error.go
+++ b/models/user/error.go
@@ -6,7 +6,7 @@ package user
import (
"fmt"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
// ErrUserAlreadyExist represents a "user already exists" error.
@@ -71,27 +71,6 @@ func (err ErrUserProhibitLogin) Unwrap() error {
return util.ErrPermissionDenied
}
-// ErrUserInactive represents a "ErrUserInactive" kind of error.
-type ErrUserInactive struct {
- UID int64
- Name string
-}
-
-// IsErrUserInactive checks if an error is a ErrUserInactive
-func IsErrUserInactive(err error) bool {
- _, ok := err.(ErrUserInactive)
- return ok
-}
-
-func (err ErrUserInactive) Error() string {
- return fmt.Sprintf("user is inactive [uid: %d, name: %s]", err.UID, err.Name)
-}
-
-// Unwrap unwraps this error as a ErrPermission error
-func (err ErrUserInactive) Unwrap() error {
- return util.ErrPermissionDenied
-}
-
// ErrUserIsNotLocal represents a "ErrUserIsNotLocal" kind of error.
type ErrUserIsNotLocal struct {
UID int64
diff --git a/models/user/external_login_user.go b/models/user/external_login_user.go
index 965b7a5ed1..f13454c38a 100644
--- a/models/user/external_login_user.go
+++ b/models/user/external_login_user.go
@@ -8,8 +8,8 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/user/federated_user.go b/models/user/federated_user.go
index 1fc42c3c32..fc07836408 100644
--- a/models/user/federated_user.go
+++ b/models/user/federated_user.go
@@ -4,7 +4,7 @@
package user
import (
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
)
type FederatedUser struct {
diff --git a/models/user/federated_user_test.go b/models/user/federated_user_test.go
index 6a2112666f..374236f6d3 100644
--- a/models/user/federated_user_test.go
+++ b/models/user/federated_user_test.go
@@ -6,7 +6,7 @@ package user
import (
"testing"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
)
func Test_FederatedUserValidation(t *testing.T) {
diff --git a/models/user/follow.go b/models/user/follow.go
index 9c3283b888..5be0f73c35 100644
--- a/models/user/follow.go
+++ b/models/user/follow.go
@@ -6,8 +6,8 @@ package user
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/timeutil"
)
// Follow represents relations of user and their followers.
diff --git a/models/user/follow_test.go b/models/user/follow_test.go
index c327d935ae..976225a4a8 100644
--- a/models/user/follow_test.go
+++ b/models/user/follow_test.go
@@ -6,15 +6,16 @@ package user_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIsFollowing(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
assert.True(t, user_model.IsFollowing(db.DefaultContext, 4, 2))
assert.False(t, user_model.IsFollowing(db.DefaultContext, 2, 4))
assert.False(t, user_model.IsFollowing(db.DefaultContext, 5, unittest.NonexistentID))
diff --git a/models/user/list.go b/models/user/list.go
index ca589d1e02..71c96c8565 100644
--- a/models/user/list.go
+++ b/models/user/list.go
@@ -7,8 +7,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
)
// UserList is a list of user.
diff --git a/models/user/main_test.go b/models/user/main_test.go
index a626d323a7..f0dae086e0 100644
--- a/models/user/main_test.go
+++ b/models/user/main_test.go
@@ -6,12 +6,13 @@ package user_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
- _ "code.gitea.io/gitea/models/user"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
+ _ "forgejo.org/models/user"
)
func TestMain(m *testing.M) {
diff --git a/models/user/must_change_password.go b/models/user/must_change_password.go
index 7eab08de89..5503f503b5 100644
--- a/models/user/must_change_password.go
+++ b/models/user/must_change_password.go
@@ -7,8 +7,8 @@ import (
"context"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/user/openid.go b/models/user/openid.go
index ee4ecabae0..96b00255a3 100644
--- a/models/user/openid.go
+++ b/models/user/openid.go
@@ -7,8 +7,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/util"
)
// ErrOpenIDNotExist openid is not known
diff --git a/models/user/openid_test.go b/models/user/openid_test.go
index 27e6edd1e0..3c55891c1f 100644
--- a/models/user/openid_test.go
+++ b/models/user/openid_test.go
@@ -6,18 +6,21 @@ package user_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetUserOpenIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
oids, err := user_model.GetUserOpenIDs(db.DefaultContext, int64(1))
- if assert.NoError(t, err) && assert.Len(t, oids, 2) {
+ require.NoError(t, err)
+
+ if assert.Len(t, oids, 2) {
assert.Equal(t, "https://user1.domain1.tld/", oids[0].URI)
assert.False(t, oids[0].Show)
assert.Equal(t, "http://user1.domain2.tld/", oids[1].URI)
@@ -25,39 +28,40 @@ func TestGetUserOpenIDs(t *testing.T) {
}
oids, err = user_model.GetUserOpenIDs(db.DefaultContext, int64(2))
- if assert.NoError(t, err) && assert.Len(t, oids, 1) {
+ require.NoError(t, err)
+
+ if assert.Len(t, oids, 1) {
assert.Equal(t, "https://domain1.tld/user2/", oids[0].URI)
assert.True(t, oids[0].Show)
}
}
func TestToggleUserOpenIDVisibility(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
oids, err := user_model.GetUserOpenIDs(db.DefaultContext, int64(2))
- if !assert.NoError(t, err) || !assert.Len(t, oids, 1) {
+ require.NoError(t, err)
+
+ if !assert.Len(t, oids, 1) {
return
}
assert.True(t, oids[0].Show)
err = user_model.ToggleUserOpenIDVisibility(db.DefaultContext, oids[0].ID)
- if !assert.NoError(t, err) {
- return
- }
+ require.NoError(t, err)
oids, err = user_model.GetUserOpenIDs(db.DefaultContext, int64(2))
- if !assert.NoError(t, err) || !assert.Len(t, oids, 1) {
+ require.NoError(t, err)
+
+ if !assert.Len(t, oids, 1) {
return
}
assert.False(t, oids[0].Show)
err = user_model.ToggleUserOpenIDVisibility(db.DefaultContext, oids[0].ID)
- if !assert.NoError(t, err) {
- return
- }
+ require.NoError(t, err)
oids, err = user_model.GetUserOpenIDs(db.DefaultContext, int64(2))
- if !assert.NoError(t, err) {
- return
- }
+ require.NoError(t, err)
+
if assert.Len(t, oids, 1) {
assert.True(t, oids[0].Show)
}
diff --git a/models/user/redirect.go b/models/user/redirect.go
index 5a40d4df3b..75876f17d2 100644
--- a/models/user/redirect.go
+++ b/models/user/redirect.go
@@ -6,10 +6,17 @@ package user
import (
"context"
"fmt"
+ "slices"
+ "strconv"
"strings"
+ "time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+
+ "xorm.io/builder"
)
// ErrUserRedirectNotExist represents a "UserRedirectNotExist" kind of error.
@@ -31,11 +38,25 @@ func (err ErrUserRedirectNotExist) Unwrap() error {
return util.ErrNotExist
}
+type ErrCooldownPeriod struct {
+ ExpireTime time.Time
+}
+
+func IsErrCooldownPeriod(err error) bool {
+ _, ok := err.(ErrCooldownPeriod)
+ return ok
+}
+
+func (err ErrCooldownPeriod) Error() string {
+ return fmt.Sprintf("cooldown period for claiming this username has not yet expired: the cooldown period ends at %s", err.ExpireTime)
+}
+
// Redirect represents that a user name should be redirected to another
type Redirect struct {
- ID int64 `xorm:"pk autoincr"`
- LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
- RedirectUserID int64 // userID to redirect to
+ ID int64 `xorm:"pk autoincr"`
+ LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
+ RedirectUserID int64 // userID to redirect to
+ CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL DEFAULT 0"`
}
// TableName provides the real table name
@@ -47,14 +68,24 @@ func init() {
db.RegisterModel(new(Redirect))
}
-// LookupUserRedirect look up userID if a user has a redirect name
-func LookupUserRedirect(ctx context.Context, userName string) (int64, error) {
+// GetUserRedirect returns the redirect for a given username, this is a
+// case-insensitive operation.
+func GetUserRedirect(ctx context.Context, userName string) (*Redirect, error) {
userName = strings.ToLower(userName)
redirect := &Redirect{LowerName: userName}
if has, err := db.GetEngine(ctx).Get(redirect); err != nil {
- return 0, err
+ return nil, err
} else if !has {
- return 0, ErrUserRedirectNotExist{Name: userName}
+ return nil, ErrUserRedirectNotExist{Name: userName}
+ }
+ return redirect, nil
+}
+
+// LookupUserRedirect look up userID if a user has a redirect name
+func LookupUserRedirect(ctx context.Context, userName string) (int64, error) {
+ redirect, err := GetUserRedirect(ctx, userName)
+ if err != nil {
+ return 0, err
}
return redirect.RedirectUserID, nil
}
@@ -78,6 +109,19 @@ func NewUserRedirect(ctx context.Context, ID int64, oldUserName, newUserName str
})
}
+// LimitUserRedirects deletes the oldest entries in user_redirect of the user,
+// such that the amount of user_redirects is at most `n` amount of entries.
+func LimitUserRedirects(ctx context.Context, userID, n int64) error {
+ // NOTE: It's not possible to combine these two queries into one due to a limitation of MySQL.
+ keepIDs := make([]int64, n)
+ if err := db.GetEngine(ctx).SQL("SELECT id FROM user_redirect WHERE redirect_user_id = ? ORDER BY created_unix DESC LIMIT "+strconv.FormatInt(n, 10), userID).Find(&keepIDs); err != nil {
+ return err
+ }
+
+ _, err := db.GetEngine(ctx).Exec(builder.Delete(builder.And(builder.Eq{"redirect_user_id": userID}, builder.NotIn("id", keepIDs))).From("user_redirect"))
+ return err
+}
+
// DeleteUserRedirect delete any redirect from the specified user name to
// anything else
func DeleteUserRedirect(ctx context.Context, userName string) error {
@@ -85,3 +129,46 @@ func DeleteUserRedirect(ctx context.Context, userName string) error {
_, err := db.GetEngine(ctx).Delete(&Redirect{LowerName: userName})
return err
}
+
+// CanClaimUsername returns if its possible to claim the given username,
+// it checks if the cooldown period for claiming an existing username is over.
+// If there's a cooldown period, the second argument returns the time when
+// that cooldown period is over.
+// In the scenario of renaming, the doerID can be specified to allow the original
+// user of the username to reclaim it within the cooldown period.
+func CanClaimUsername(ctx context.Context, username string, doerID int64) (bool, time.Time, error) {
+ // Only check for a cooldown period if UsernameCooldownPeriod is a positive number.
+ if setting.Service.UsernameCooldownPeriod <= 0 {
+ return true, time.Time{}, nil
+ }
+
+ userRedirect, err := GetUserRedirect(ctx, username)
+ if err != nil {
+ if IsErrUserRedirectNotExist(err) {
+ return true, time.Time{}, nil
+ }
+ return false, time.Time{}, err
+ }
+
+ // Allow reclaiming of user's own username.
+ if userRedirect.RedirectUserID == doerID {
+ return true, time.Time{}, nil
+ }
+
+ // We do not know if the redirect user id was for an organization, so
+ // unconditionally execute the following query to retrieve all users that
+ // are part of the "Owner" team. If the redirect user ID is not an organization
+ // the returned list would be empty.
+ ownerTeamUIDs := []int64{}
+ if err := db.GetEngine(ctx).SQL("SELECT uid FROM team_user INNER JOIN team ON team_user.`team_id` = team.`id` WHERE team.`org_id` = ? AND team.`name` = 'Owners'", userRedirect.RedirectUserID).Find(&ownerTeamUIDs); err != nil {
+ return false, time.Time{}, err
+ }
+
+ if slices.Contains(ownerTeamUIDs, doerID) {
+ return true, time.Time{}, nil
+ }
+
+ // Multiply the value of UsernameCooldownPeriod by the amount of seconds in a day.
+ expireTime := userRedirect.CreatedUnix.Add(86400 * setting.Service.UsernameCooldownPeriod).AsLocalTime()
+ return time.Until(expireTime) <= 0, expireTime, nil
+}
diff --git a/models/user/redirect_test.go b/models/user/redirect_test.go
index 484c5a663f..c598fb045f 100644
--- a/models/user/redirect_test.go
+++ b/models/user/redirect_test.go
@@ -6,18 +6,19 @@ package user_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestLookupUserRedirect(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
userID, err := user_model.LookupUserRedirect(db.DefaultContext, "olduser1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, userID)
_, err = user_model.LookupUserRedirect(db.DefaultContext, "doesnotexist")
diff --git a/models/user/search.go b/models/user/search.go
index 04c434e4fa..d2b9901823 100644
--- a/models/user/search.go
+++ b/models/user/search.go
@@ -8,10 +8,10 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/structs"
"xorm.io/builder"
"xorm.io/xorm"
@@ -24,8 +24,8 @@ type SearchUserOptions struct {
Keyword string
Type UserType
UID int64
- LoginName string // this option should be used only for admin user
- SourceID int64 // this option should be used only for admin user
+ LoginName string // this option should be used only for admin user
+ SourceID optional.Option[int64] // this option should be used only for admin user
OrderBy db.SearchOrderBy
Visible []structs.VisibleType
Actor *User // The user doing the search
@@ -40,6 +40,7 @@ type SearchUserOptions struct {
IsProhibitLogin optional.Option[bool]
IncludeReserved bool
+ Load2FAStatus bool
ExtraParamStrings map[string]string
}
@@ -69,7 +70,19 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess
builder.Like{"LOWER(full_name)", lowerKeyword},
)
if opts.SearchByEmail {
- keywordCond = keywordCond.Or(builder.Like{"LOWER(email)", lowerKeyword})
+ var emailCond builder.Cond
+ emailCond = builder.Like{"LOWER(email)", lowerKeyword}
+ if opts.Actor == nil {
+ emailCond = emailCond.And(builder.Eq{"keep_email_private": false})
+ } else if !opts.Actor.IsAdmin {
+ emailCond = emailCond.And(
+ builder.Or(
+ builder.Eq{"keep_email_private": false},
+ builder.Eq{"id": opts.Actor.ID},
+ ),
+ )
+ }
+ keywordCond = keywordCond.Or(emailCond)
}
cond = cond.And(keywordCond)
@@ -86,8 +99,8 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess
cond = cond.And(builder.Eq{"id": opts.UID})
}
- if opts.SourceID > 0 {
- cond = cond.And(builder.Eq{"login_source": opts.SourceID})
+ if opts.SourceID.Has() {
+ cond = cond.And(builder.Eq{"login_source": opts.SourceID.Value()})
}
if opts.LoginName != "" {
cond = cond.And(builder.Eq{"login_name": opts.LoginName})
@@ -114,17 +127,15 @@ func (opts *SearchUserOptions) toSearchQueryBase(ctx context.Context) *xorm.Sess
return e.Where(cond)
}
- // 2fa filter uses LEFT JOIN to check whether a user has a 2fa record
- // While using LEFT JOIN, sometimes the performance might not be good, but it won't be a problem now, such SQL is seldom executed.
- // There are some possible methods to refactor this SQL in future when we really need to optimize the performance (but not now):
- // (1) add a column in user table (2) add a setting value in user_setting table (3) use search engines (bleve/elasticsearch)
+ // Check if the user has two factor enabled, which is TOTP or Webauthn.
if opts.IsTwoFactorEnabled.Value() {
- cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL"))
+ cond = cond.And(builder.Expr("two_factor.uid IS NOT NULL OR webauthn_credential.user_id IS NOT NULL"))
} else {
- cond = cond.And(builder.Expr("two_factor.uid IS NULL"))
+ cond = cond.And(builder.Expr("two_factor.uid IS NULL AND webauthn_credential.user_id IS NULL"))
}
return e.Join("LEFT OUTER", "two_factor", "two_factor.uid = `user`.id").
+ Join("LEFT OUTER", "webauthn_credential", "webauthn_credential.user_id = `user`.id").
Where(cond)
}
diff --git a/models/user/setting.go b/models/user/setting.go
index b4af0e5ccd..a915119ad2 100644
--- a/models/user/setting.go
+++ b/models/user/setting.go
@@ -8,10 +8,10 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/cache"
- setting_module "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/cache"
+ setting_module "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"xorm.io/builder"
)
diff --git a/models/user/setting_test.go b/models/user/setting_test.go
index c56fe93075..7b6658041f 100644
--- a/models/user/setting_test.go
+++ b/models/user/setting_test.go
@@ -6,55 +6,56 @@ package user_test
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestSettings(t *testing.T) {
keyName := "test_user_setting"
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
newSetting := &user_model.Setting{UserID: 99, SettingKey: keyName, SettingValue: "Gitea User Setting Test"}
// create setting
err := user_model.SetUserSetting(db.DefaultContext, newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue)
- assert.NoError(t, err)
+ require.NoError(t, err)
// test about saving unchanged values
err = user_model.SetUserSetting(db.DefaultContext, newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue)
- assert.NoError(t, err)
+ require.NoError(t, err)
// get specific setting
settings, err := user_model.GetSettings(db.DefaultContext, 99, []string{keyName})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, settings, 1)
assert.EqualValues(t, newSetting.SettingValue, settings[keyName].SettingValue)
settingValue, err := user_model.GetUserSetting(db.DefaultContext, 99, keyName)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, newSetting.SettingValue, settingValue)
settingValue, err = user_model.GetUserSetting(db.DefaultContext, 99, "no_such")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "", settingValue)
// updated setting
updatedSetting := &user_model.Setting{UserID: 99, SettingKey: keyName, SettingValue: "Updated"}
err = user_model.SetUserSetting(db.DefaultContext, updatedSetting.UserID, updatedSetting.SettingKey, updatedSetting.SettingValue)
- assert.NoError(t, err)
+ require.NoError(t, err)
// get all settings
settings, err = user_model.GetUserAllSettings(db.DefaultContext, 99)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, settings, 1)
assert.EqualValues(t, updatedSetting.SettingValue, settings[updatedSetting.SettingKey].SettingValue)
// delete setting
err = user_model.DeleteUserSetting(db.DefaultContext, 99, keyName)
- assert.NoError(t, err)
+ require.NoError(t, err)
settings, err = user_model.GetUserAllSettings(db.DefaultContext, 99)
- assert.NoError(t, err)
- assert.Len(t, settings, 0)
+ require.NoError(t, err)
+ assert.Empty(t, settings)
}
diff --git a/models/user/user.go b/models/user/user.go
index 6d8c5fa2b5..a0ee1e81b4 100644
--- a/models/user/user.go
+++ b/models/user/user.go
@@ -7,8 +7,11 @@ package user
import (
"context"
+ "crypto/subtle"
"encoding/hex"
+ "errors"
"fmt"
+ "net/mail"
"net/url"
"path/filepath"
"regexp"
@@ -18,20 +21,20 @@ import (
_ "image/jpeg" // Needed for jpeg support
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/auth/openid"
- "code.gitea.io/gitea/modules/auth/password/hash"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/auth/openid"
+ "forgejo.org/modules/auth/password/hash"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/validation"
"golang.org/x/text/runes"
"golang.org/x/text/transform"
@@ -47,19 +50,19 @@ const (
UserTypeIndividual UserType = iota // Historic reason to make it starts at 0.
// UserTypeOrganization defines an organization
- UserTypeOrganization
+ UserTypeOrganization // 1
// UserTypeUserReserved reserves a (non-existing) user, i.e. to prevent a spam user from re-registering after being deleted, or to reserve the name until the user is actually created later on
- UserTypeUserReserved
+ UserTypeUserReserved // 2
// UserTypeOrganizationReserved reserves a (non-existing) organization, to be used in combination with UserTypeUserReserved
- UserTypeOrganizationReserved
+ UserTypeOrganizationReserved // 3
// UserTypeBot defines a bot user
- UserTypeBot
+ UserTypeBot // 4
// UserTypeRemoteUser defines a remote user for federated users
- UserTypeRemoteUser
+ UserTypeRemoteUser // 5
)
const (
@@ -151,6 +154,7 @@ type User struct {
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
Theme string `xorm:"NOT NULL DEFAULT ''"`
KeepActivityPrivate bool `xorm:"NOT NULL DEFAULT false"`
+ KeepPronounsPrivate bool `xorm:"NOT NULL DEFAULT false"`
EnableRepoUnitHints bool `xorm:"NOT NULL DEFAULT true"`
}
@@ -317,15 +321,14 @@ func (u *User) OrganisationLink() string {
return setting.AppSubURL + "/org/" + url.PathEscape(u.Name)
}
-// GenerateEmailActivateCode generates an activate code based on user information and given e-mail.
-func (u *User) GenerateEmailActivateCode(email string) string {
- code := base.CreateTimeLimitCode(
- fmt.Sprintf("%d%s%s%s%s", u.ID, email, u.LowerName, u.Passwd, u.Rands),
- setting.Service.ActiveCodeLives, time.Now(), nil)
-
- // Add tail hex username
- code += hex.EncodeToString([]byte(u.LowerName))
- return code
+// GenerateEmailAuthorizationCode generates an activation code based for the user for the specified purpose.
+// The standard expiry is ActiveCodeLives minutes.
+func (u *User) GenerateEmailAuthorizationCode(ctx context.Context, purpose auth.AuthorizationPurpose) (string, error) {
+ lookup, validator, err := auth.GenerateAuthToken(ctx, u.ID, timeutil.TimeStampNow().Add(int64(setting.Service.ActiveCodeLives)*60), purpose)
+ if err != nil {
+ return "", err
+ }
+ return lookup + ":" + validator, nil
}
// GetUserFollowers returns range of user's followers.
@@ -337,7 +340,7 @@ func GetUserFollowers(ctx context.Context, u, viewer *User, listOptions db.ListO
And("`user`.type=?", UserTypeIndividual).
And(isUserVisibleToViewerCond(viewer))
- if listOptions.Page != 0 {
+ if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
users := make([]*User, 0, listOptions.PageSize)
@@ -359,7 +362,7 @@ func GetUserFollowing(ctx context.Context, u, viewer *User, listOptions db.ListO
And("`user`.type IN (?, ?)", UserTypeIndividual, UserTypeOrganization).
And(isUserVisibleToViewerCond(viewer))
- if listOptions.Page != 0 {
+ if listOptions.Page > 0 {
sess = db.SetSessionPagination(sess, &listOptions)
users := make([]*User, 0, listOptions.PageSize)
@@ -420,6 +423,10 @@ func (u *User) IsIndividual() bool {
return u.Type == UserTypeIndividual
}
+func (u *User) IsUser() bool {
+ return u.Type == UserTypeIndividual || u.Type == UserTypeBot
+}
+
// IsBot returns whether or not the user is of type bot
func (u *User) IsBot() bool {
return u.Type == UserTypeBot
@@ -439,6 +446,38 @@ func (u *User) DisplayName() string {
return u.Name
}
+var emailToReplacer = strings.NewReplacer(
+ "\n", "",
+ "\r", "",
+ "<", "",
+ ">", "",
+ ",", "",
+ ":", "",
+ ";", "",
+)
+
+// EmailTo returns a string suitable to be put into a e-mail `To:` header.
+func (u *User) EmailTo(overrideMail ...string) string {
+ sanitizedDisplayName := emailToReplacer.Replace(u.DisplayName())
+
+ email := u.Email
+ if len(overrideMail) > 0 {
+ email = overrideMail[0]
+ }
+
+ // should be an edge case but nice to have
+ if sanitizedDisplayName == email {
+ return email
+ }
+
+ address, err := mail.ParseAddress(fmt.Sprintf("%s <%s>", sanitizedDisplayName, email))
+ if err != nil {
+ return email
+ }
+
+ return address.String()
+}
+
// GetDisplayName returns full name if it's not empty and DEFAULT_SHOW_FULL_NAME is set,
// returns username otherwise.
func (u *User) GetDisplayName() string {
@@ -462,6 +501,16 @@ func (u *User) GetCompleteName() string {
return u.Name
}
+// GetPronouns returns an empty string, if the user has set to keep his
+// pronouns private from non-logged in users, otherwise the pronouns
+// are returned.
+func (u *User) GetPronouns(signed bool) string {
+ if u.KeepPronounsPrivate && !signed {
+ return ""
+ }
+ return u.Pronouns
+}
+
func gitSafeName(name string) string {
return strings.TrimSpace(strings.NewReplacer("\n", "", "<", "", ">", "").Replace(name))
}
@@ -527,7 +576,7 @@ func GetUserSalt() (string, error) {
// Note: The set of characters here can safely expand without a breaking change,
// but characters removed from this set can cause user account linking to break
var (
- customCharsReplacement = strings.NewReplacer("ร", "AE")
+ customCharsReplacement = strings.NewReplacer("ร", "AE", "ร", "ss")
removeCharsRE = regexp.MustCompile(`['ยด\x60]`)
removeDiacriticsTransform = transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
replaceCharsHyphenRE = regexp.MustCompile(`[\s~+]`)
@@ -548,44 +597,48 @@ var (
reservedUsernames = []string{
".",
"..",
+ "-", // used by certain web routes
".well-known",
- "admin",
- "api",
- "assets",
- "attachments",
- "avatar",
- "avatars",
- "captcha",
- "commits",
- "debug",
- "error",
- "explore",
- "favicon.ico",
- "ghost",
- "issues",
- "login",
- "manifest.json",
- "metrics",
- "milestones",
- "new",
- "notifications",
- "org",
- "pulls",
- "raw",
- "repo",
+
+ "api", // gitea api
+ "metrics", // prometheus metrics api
+ "v2", // container registry api
+
+ "assets", // static asset files
+ "attachments", // issue attachments
+
+ "avatar", // avatar by email hash
+ "avatars", // user avatars by file name
"repo-avatars",
- "robots.txt",
- "search",
- "serviceworker.js",
- "ssh_info",
+
+ "captcha",
+ "login", // oauth2 login
+ "org", // org create/manage, or "/org/{org}", BUT if an org is named as "invite" then it goes wrong
+ "repo", // repo create/migrate, etc
+ "user", // user login/activate/settings, etc
+
+ "admin",
+ "devtest",
+ "explore",
+ "issues",
+ "pulls",
+ "milestones",
+ "notifications",
+
+ "favicon.ico",
+ "manifest.json", // web app manifests
+ "robots.txt", // search engine robots
+ "sitemap.xml", // search engine sitemap
+ "ssh_info", // agit info
"swagger.v1.json",
- "user",
- "v2",
- "gitea-actions",
- "forgejo-actions",
+
+ "ghost", // reserved name for deleted users (id: -1)
+ "gitea-actions", // gitea builtin user (id: -2)
+ "forgejo-actions", // forgejo builtin user (id: -2)
}
- // DON'T ADD ANY NEW STUFF, WE SOLVE THIS WITH `/user/{obj}` PATHS!
+ // These names are reserved for user accounts: user's keys, user's rss feed, user's avatar, etc.
+ // DO NOT add any new stuff! The paths with these names are processed by `/{username}` handler (UsernameSubRoute) manually.
reservedUserPatterns = []string{"*.keys", "*.gpg", "*.rss", "*.atom", "*.png"}
)
@@ -627,6 +680,18 @@ func createUser(ctx context.Context, u *User, createdByAdmin bool, overwriteDefa
return err
}
+ // Check if the new username can be claimed.
+ // Skip this check if done by an admin.
+ if !createdByAdmin {
+ if ok, expireTime, err := CanClaimUsername(ctx, u.Name, -1); err != nil {
+ return err
+ } else if !ok {
+ return ErrCooldownPeriod{
+ ExpireTime: expireTime,
+ }
+ }
+ }
+
// set system defaults
u.KeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate
u.Visibility = setting.Service.DefaultUserVisibilityMode
@@ -677,11 +742,11 @@ func createUser(ctx context.Context, u *User, createdByAdmin bool, overwriteDefa
}
if createdByAdmin {
- if err := ValidateEmailForAdmin(u.Email); err != nil {
+ if err := validation.ValidateEmailForAdmin(u.Email); err != nil {
return err
}
} else {
- if err := ValidateEmail(u.Email); err != nil {
+ if err := validation.ValidateEmail(u.Email); err != nil {
return err
}
}
@@ -798,35 +863,48 @@ func countUsers(ctx context.Context, opts *CountUserFilter) int64 {
return count
}
-// GetVerifyUser get user by verify code
-func GetVerifyUser(ctx context.Context, code string) (user *User) {
- if len(code) <= base.TimeLimitCodeLength {
- return nil
+// VerifyUserActiveCode verifies that the code is valid for the given purpose for this user.
+// If delete is specified, the token will be deleted.
+func VerifyUserAuthorizationToken(ctx context.Context, code string, purpose auth.AuthorizationPurpose) (user *User, deleteToken func() error, err error) {
+ lookupKey, validator, found := strings.Cut(code, ":")
+ if !found {
+ return nil, nil, nil
}
- // use tail hex username query user
- hexStr := code[base.TimeLimitCodeLength:]
- if b, err := hex.DecodeString(hexStr); err == nil {
- if user, err = GetUserByName(ctx, string(b)); user != nil {
- return user
+ authToken, err := auth.FindAuthToken(ctx, lookupKey, purpose)
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ return nil, nil, nil
}
- log.Error("user.getVerifyUser: %v", err)
+ return nil, nil, err
}
- return nil
-}
+ if authToken.IsExpired() {
+ return nil, nil, auth.DeleteAuthToken(ctx, authToken)
+ }
-// VerifyUserActiveCode verifies active code when active account
-func VerifyUserActiveCode(ctx context.Context, code string) (user *User) {
- if user = GetVerifyUser(ctx, code); user != nil {
- // time limit code
- prefix := code[:base.TimeLimitCodeLength]
- data := fmt.Sprintf("%d%s%s%s%s", user.ID, user.Email, user.LowerName, user.Passwd, user.Rands)
- if base.VerifyTimeLimitCode(time.Now(), data, setting.Service.ActiveCodeLives, prefix) {
- return user
+ rawValidator, err := hex.DecodeString(validator)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ if subtle.ConstantTimeCompare([]byte(authToken.HashedValidator), []byte(auth.HashValidator(rawValidator))) == 0 {
+ return nil, nil, errors.New("validator doesn't match")
+ }
+
+ u, err := GetUserByID(ctx, authToken.UID)
+ if err != nil {
+ if IsErrUserNotExist(err) {
+ return nil, nil, nil
}
+ return nil, nil, err
}
- return nil
+
+ deleteToken = func() error {
+ return auth.DeleteAuthToken(ctx, authToken)
+ }
+
+ return u, deleteToken, nil
}
// ValidateUser check if user is valid to insert / update into database
@@ -845,7 +923,7 @@ func (u User) Validate() []string {
if err := ValidateUser(&u); err != nil {
result = append(result, err.Error())
}
- if err := ValidateEmail(u.Email); err != nil {
+ if err := validation.ValidateEmail(u.Email); err != nil {
result = append(result, err.Error())
}
return result
@@ -863,7 +941,13 @@ func UpdateUserCols(ctx context.Context, u *User, cols ...string) error {
// GetInactiveUsers gets all inactive users
func GetInactiveUsers(ctx context.Context, olderThan time.Duration) ([]*User, error) {
- var cond builder.Cond = builder.Eq{"is_active": false}
+ cond := builder.And(
+ builder.Eq{"is_active": false},
+ builder.Or( // only plain user
+ builder.Eq{"`type`": UserTypeIndividual},
+ builder.Eq{"`type`": UserTypeUserReserved},
+ ),
+ )
if olderThan > 0 {
cond = cond.And(builder.Lt{"created_unix": time.Now().Add(-olderThan).Unix()})
@@ -905,6 +989,20 @@ func GetUserByIDs(ctx context.Context, ids []int64) ([]*User, error) {
return users, err
}
+func IsValidUserID(id int64) bool {
+ return id > 0 || id == GhostUserID || id == ActionsUserID
+}
+
+func GetUserFromMap(id int64, idMap map[int64]*User) (int64, *User) {
+ if user, ok := idMap[id]; ok {
+ return id, user
+ }
+ if id == ActionsUserID {
+ return ActionsUserID, NewActionsUser()
+ }
+ return GhostUserID, NewGhostUser()
+}
+
// GetPossibleUserByID returns the user if id > 0 or return system usrs if id < 0
func GetPossibleUserByID(ctx context.Context, id int64) (*User, error) {
switch id {
@@ -954,22 +1052,6 @@ func GetUserByName(ctx context.Context, name string) (*User, error) {
return u, nil
}
-// GetUserEmailsByNames returns a list of e-mails corresponds to names of users
-// that have their email notifications set to enabled or onmention.
-func GetUserEmailsByNames(ctx context.Context, names []string) []string {
- mails := make([]string, 0, len(names))
- for _, name := range names {
- u, err := GetUserByName(ctx, name)
- if err != nil {
- continue
- }
- if u.IsMailable() && u.EmailNotificationsPreference != EmailNotificationsDisabled {
- mails = append(mails, u.Email)
- }
- }
- return mails
-}
-
// GetMaileableUsersByIDs gets users from ids, but only if they can receive mails
func GetMaileableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([]*User, error) {
if len(ids) == 0 {
@@ -996,17 +1078,6 @@ func GetMaileableUsersByIDs(ctx context.Context, ids []int64, isMention bool) ([
Find(&ous)
}
-// GetUserNamesByIDs returns usernames for all resolved users from a list of Ids.
-func GetUserNamesByIDs(ctx context.Context, ids []int64) ([]string, error) {
- unames := make([]string, 0, len(ids))
- err := db.GetEngine(ctx).In("id", ids).
- Table("user").
- Asc("name").
- Cols("name").
- Find(&unames)
- return unames, err
-}
-
// GetUserNameByID returns username for the id
func GetUserNameByID(ctx context.Context, id int64) (string, error) {
var name string
diff --git a/models/user/user_repository.go b/models/user/user_repository.go
index c06441b5c8..172bf7c8b4 100644
--- a/models/user/user_repository.go
+++ b/models/user/user_repository.go
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/validation"
)
func init() {
diff --git a/models/user/user_system.go b/models/user/user_system.go
index ac2505dd14..f1585b512a 100644
--- a/models/user/user_system.go
+++ b/models/user/user_system.go
@@ -1,12 +1,15 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package user
import (
+ "net/url"
"strings"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
)
const (
@@ -68,3 +71,32 @@ func NewActionsUser() *User {
func (u *User) IsActions() bool {
return u != nil && u.ID == ActionsUserID
}
+
+const (
+ APActorUserID = -3
+ APActorUserName = "actor"
+ APActorEmail = "noreply@forgejo.org"
+)
+
+func NewAPActorUser() *User {
+ return &User{
+ ID: APActorUserID,
+ Name: APActorUserName,
+ LowerName: APActorUserName,
+ IsActive: true,
+ Email: APActorEmail,
+ KeepEmailPrivate: true,
+ LoginName: APActorUserName,
+ Type: UserTypeIndividual,
+ Visibility: structs.VisibleTypePublic,
+ }
+}
+
+func APActorUserAPActorID() string {
+ path, _ := url.JoinPath(setting.AppURL, "/api/v1/activitypub/actor")
+ return path
+}
+
+func (u *User) IsAPActor() bool {
+ return u != nil && u.ID == APActorUserID
+}
diff --git a/models/user/user_test.go b/models/user/user_test.go
index 7457256017..7c89337510 100644
--- a/models/user/user_test.go
+++ b/models/user/user_test.go
@@ -5,39 +5,75 @@
package user_test
import (
- "context"
"crypto/rand"
+ "encoding/hex"
"fmt"
"strings"
"testing"
"time"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/password/hash"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/tests"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/password/hash"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/test"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/validation"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestOAuth2Application_LoadUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: 1})
user, err := user_model.GetUserByID(db.DefaultContext, app.UID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, user)
}
+func TestIsValidUserID(t *testing.T) {
+ assert.False(t, user_model.IsValidUserID(-30))
+ assert.False(t, user_model.IsValidUserID(0))
+ assert.True(t, user_model.IsValidUserID(user_model.GhostUserID))
+ assert.True(t, user_model.IsValidUserID(user_model.ActionsUserID))
+ assert.True(t, user_model.IsValidUserID(200))
+}
+
+func TestGetUserFromMap(t *testing.T) {
+ id := int64(200)
+ idMap := map[int64]*user_model.User{
+ id: {ID: id},
+ }
+
+ ghostID := int64(user_model.GhostUserID)
+ actionsID := int64(user_model.ActionsUserID)
+ actualID, actualUser := user_model.GetUserFromMap(-20, idMap)
+ assert.Equal(t, ghostID, actualID)
+ assert.Equal(t, ghostID, actualUser.ID)
+
+ actualID, actualUser = user_model.GetUserFromMap(0, idMap)
+ assert.Equal(t, ghostID, actualID)
+ assert.Equal(t, ghostID, actualUser.ID)
+
+ actualID, actualUser = user_model.GetUserFromMap(ghostID, idMap)
+ assert.Equal(t, ghostID, actualID)
+ assert.Equal(t, ghostID, actualUser.ID)
+
+ actualID, actualUser = user_model.GetUserFromMap(actionsID, idMap)
+ assert.Equal(t, actionsID, actualID)
+ assert.Equal(t, actionsID, actualUser.ID)
+}
+
func TestGetUserByName(t *testing.T) {
- defer tests.AddFixtures("models/user/fixtures/")()
- assert.NoError(t, unittest.PrepareTestDatabase())
+ defer unittest.OverrideFixtures("models/user/fixtures")()
+ require.NoError(t, unittest.PrepareTestDatabase())
{
_, err := user_model.GetUserByName(db.DefaultContext, "")
@@ -49,33 +85,23 @@ func TestGetUserByName(t *testing.T) {
}
{
user, err := user_model.GetUserByName(db.DefaultContext, "USER2")
- assert.NoError(t, err)
- assert.Equal(t, user.Name, "user2")
+ require.NoError(t, err)
+ assert.Equal(t, "user2", user.Name)
}
{
user, err := user_model.GetUserByName(db.DefaultContext, "org3")
- assert.NoError(t, err)
- assert.Equal(t, user.Name, "org3")
+ require.NoError(t, err)
+ assert.Equal(t, "org3", user.Name)
}
{
user, err := user_model.GetUserByName(db.DefaultContext, "remote01")
- assert.NoError(t, err)
- assert.Equal(t, user.Name, "remote01")
+ require.NoError(t, err)
+ assert.Equal(t, "remote01", user.Name)
}
}
-func TestGetUserEmailsByNames(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
-
- // ignore none active user email
- assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user9"}))
- assert.ElementsMatch(t, []string{"user8@example.com", "user5@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user5"}))
-
- assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "org7"}))
-}
-
func TestCanCreateOrganization(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
assert.True(t, admin.CanCreateOrganization())
@@ -93,11 +119,11 @@ func TestCanCreateOrganization(t *testing.T) {
}
func TestGetAllUsers(t *testing.T) {
- defer tests.AddFixtures("models/user/fixtures/")()
- assert.NoError(t, unittest.PrepareTestDatabase())
+ defer unittest.OverrideFixtures("models/user/fixtures")()
+ require.NoError(t, unittest.PrepareTestDatabase())
users, err := user_model.GetAllUsers(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
found := make(map[user_model.UserType]bool, 0)
for _, user := range users {
@@ -118,11 +144,11 @@ func TestAPActorID(t *testing.T) {
}
func TestSearchUsers(t *testing.T) {
- defer tests.AddFixtures("models/user/fixtures/")()
- assert.NoError(t, unittest.PrepareTestDatabase())
+ defer unittest.OverrideFixtures("models/user/fixtures")()
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(opts *user_model.SearchUserOptions, expectedUserOrOrgIDs []int64) {
users, _, err := user_model.SearchUsers(db.DefaultContext, opts)
- assert.NoError(t, err)
+ require.NoError(t, err)
cassText := fmt.Sprintf("ids: %v, opts: %v", expectedUserOrOrgIDs, opts)
if assert.Len(t, users, len(expectedUserOrOrgIDs), "case: %s", cassText) {
for i, expectedID := range expectedUserOrOrgIDs {
@@ -184,11 +210,11 @@ func TestSearchUsers(t *testing.T) {
[]int64{1041, 37})
testUserSuccess(&user_model.SearchUserOptions{ListOptions: db.ListOptions{Page: 1}, IsTwoFactorEnabled: optional.Some(true)},
- []int64{24})
+ []int64{24, 32})
}
func TestEmailNotificationPreferences(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
for _, test := range []struct {
expected string
@@ -248,21 +274,21 @@ func BenchmarkHashPassword(b *testing.B) {
func TestNewGitSig(t *testing.T) {
users := make([]*user_model.User, 0, 20)
err := db.GetEngine(db.DefaultContext).Find(&users)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, user := range users {
sig := user.NewGitSig()
assert.NotContains(t, sig.Name, "<")
assert.NotContains(t, sig.Name, ">")
assert.NotContains(t, sig.Name, "\n")
- assert.NotEqual(t, len(strings.TrimSpace(sig.Name)), 0)
+ assert.NotEmpty(t, strings.TrimSpace(sig.Name))
}
}
func TestDisplayName(t *testing.T) {
users := make([]*user_model.User, 0, 20)
err := db.GetEngine(db.DefaultContext).Find(&users)
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, user := range users {
displayName := user.DisplayName()
@@ -270,7 +296,7 @@ func TestDisplayName(t *testing.T) {
if len(strings.TrimSpace(user.FullName)) == 0 {
assert.Equal(t, user.Name, displayName)
}
- assert.NotEqual(t, len(strings.TrimSpace(displayName)), 0)
+ assert.NotEmpty(t, strings.TrimSpace(displayName))
}
}
@@ -285,12 +311,12 @@ func TestCreateUserInvalidEmail(t *testing.T) {
}
err := user_model.CreateUser(db.DefaultContext, user)
- assert.Error(t, err)
- assert.True(t, user_model.IsErrEmailCharIsNotSupported(err))
+ require.Error(t, err)
+ assert.True(t, validation.IsErrEmailCharIsNotSupported(err))
}
func TestCreateUserEmailAlreadyUsed(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -299,12 +325,12 @@ func TestCreateUserEmailAlreadyUsed(t *testing.T) {
user.LowerName = strings.ToLower(user.Name)
user.ID = 0
err := user_model.CreateUser(db.DefaultContext, user)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, user_model.IsErrEmailAlreadyUsed(err))
}
func TestCreateUserCustomTimestamps(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -316,16 +342,16 @@ func TestCreateUserCustomTimestamps(t *testing.T) {
user.Email = "unique@example.com"
user.CreatedUnix = creationTimestamp
err := user_model.CreateUser(db.DefaultContext, user)
- assert.NoError(t, err)
+ require.NoError(t, err)
- fetched, err := user_model.GetUserByID(context.Background(), user.ID)
- assert.NoError(t, err)
+ fetched, err := user_model.GetUserByID(t.Context(), user.ID)
+ require.NoError(t, err)
assert.Equal(t, creationTimestamp, fetched.CreatedUnix)
assert.Equal(t, creationTimestamp, fetched.UpdatedUnix)
}
func TestCreateUserWithoutCustomTimestamps(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -341,12 +367,12 @@ func TestCreateUserWithoutCustomTimestamps(t *testing.T) {
user.CreatedUnix = 0
user.UpdatedUnix = 0
err := user_model.CreateUser(db.DefaultContext, user)
- assert.NoError(t, err)
+ require.NoError(t, err)
timestampEnd := time.Now().Unix()
- fetched, err := user_model.GetUserByID(context.Background(), user.ID)
- assert.NoError(t, err)
+ fetched, err := user_model.GetUserByID(t.Context(), user.ID)
+ require.NoError(t, err)
assert.LessOrEqual(t, timestampStart, fetched.CreatedUnix)
assert.LessOrEqual(t, fetched.CreatedUnix, timestampEnd)
@@ -355,45 +381,70 @@ func TestCreateUserWithoutCustomTimestamps(t *testing.T) {
assert.LessOrEqual(t, fetched.UpdatedUnix, timestampEnd)
}
+func TestCreateUserClaimingUsername(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ defer test.MockVariableValue(&setting.Service.UsernameCooldownPeriod, 1)()
+
+ _, err := db.GetEngine(db.DefaultContext).NoAutoTime().Insert(&user_model.Redirect{RedirectUserID: 1, LowerName: "redirecting", CreatedUnix: timeutil.TimeStampNow()})
+ require.NoError(t, err)
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ user.Name = "redirecting"
+ user.LowerName = strings.ToLower(user.Name)
+ user.ID = 0
+ user.Email = "unique@example.com"
+
+ t.Run("Normal creation", func(t *testing.T) {
+ err = user_model.CreateUser(db.DefaultContext, user)
+ assert.True(t, user_model.IsErrCooldownPeriod(err))
+ })
+
+ t.Run("Creation as admin", func(t *testing.T) {
+ err = user_model.AdminCreateUser(db.DefaultContext, user)
+ require.NoError(t, err)
+ })
+}
+
func TestGetUserIDsByNames(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// ignore non existing
IDs, err := user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "user2", "none_existing_user"}, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []int64{1, 2}, IDs)
// ignore non existing
IDs, err = user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "do_not_exist"}, false)
- assert.Error(t, err)
+ require.Error(t, err)
assert.Equal(t, []int64(nil), IDs)
}
func TestGetMaileableUsersByIDs(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
results, err := user_model.GetMaileableUsersByIDs(db.DefaultContext, []int64{1, 4}, false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, results, 1)
if len(results) > 1 {
- assert.Equal(t, results[0].ID, 1)
+ assert.Equal(t, 1, results[0].ID)
}
results, err = user_model.GetMaileableUsersByIDs(db.DefaultContext, []int64{1, 4}, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, results, 2)
if len(results) > 2 {
- assert.Equal(t, results[0].ID, 1)
- assert.Equal(t, results[1].ID, 4)
+ assert.Equal(t, 1, results[0].ID)
+ assert.Equal(t, 4, results[1].ID)
}
}
func TestNewUserRedirect(t *testing.T) {
// redirect to a completely new name
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
+ require.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
LowerName: user.LowerName,
@@ -407,10 +458,10 @@ func TestNewUserRedirect(t *testing.T) {
func TestNewUserRedirect2(t *testing.T) {
// redirect to previously used name
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "olduser1"))
+ require.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "olduser1"))
unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
LowerName: user.LowerName,
@@ -424,10 +475,10 @@ func TestNewUserRedirect2(t *testing.T) {
func TestNewUserRedirect3(t *testing.T) {
// redirect for a previously-unredirected user
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
- assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
+ require.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
LowerName: user.LowerName,
@@ -436,7 +487,7 @@ func TestNewUserRedirect3(t *testing.T) {
}
func TestGetUserByOpenID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
_, err := user_model.GetUserByOpenID(db.DefaultContext, "https://unknown")
if assert.Error(t, err) {
@@ -444,31 +495,31 @@ func TestGetUserByOpenID(t *testing.T) {
}
user, err := user_model.GetUserByOpenID(db.DefaultContext, "https://user1.domain1.tld")
- if assert.NoError(t, err) {
- assert.Equal(t, int64(1), user.ID)
- }
+ require.NoError(t, err)
+
+ assert.Equal(t, int64(1), user.ID)
user, err = user_model.GetUserByOpenID(db.DefaultContext, "https://domain1.tld/user2/")
- if assert.NoError(t, err) {
- assert.Equal(t, int64(2), user.ID)
- }
+ require.NoError(t, err)
+
+ assert.Equal(t, int64(2), user.ID)
}
func TestFollowUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(followerID, followedID int64) {
- assert.NoError(t, user_model.FollowUser(db.DefaultContext, followerID, followedID))
+ require.NoError(t, user_model.FollowUser(db.DefaultContext, followerID, followedID))
unittest.AssertExistsAndLoadBean(t, &user_model.Follow{UserID: followerID, FollowID: followedID})
}
testSuccess(4, 2)
testSuccess(5, 2)
- assert.NoError(t, user_model.FollowUser(db.DefaultContext, 2, 2))
+ require.NoError(t, user_model.FollowUser(db.DefaultContext, 2, 2))
// Blocked user.
- assert.ErrorIs(t, user_model.ErrBlockedByUser, user_model.FollowUser(db.DefaultContext, 1, 4))
- assert.ErrorIs(t, user_model.ErrBlockedByUser, user_model.FollowUser(db.DefaultContext, 4, 1))
+ require.ErrorIs(t, user_model.ErrBlockedByUser, user_model.FollowUser(db.DefaultContext, 1, 4))
+ require.ErrorIs(t, user_model.ErrBlockedByUser, user_model.FollowUser(db.DefaultContext, 4, 1))
unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: 1, FollowID: 4})
unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: 4, FollowID: 1})
@@ -476,10 +527,10 @@ func TestFollowUser(t *testing.T) {
}
func TestUnfollowUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(followerID, followedID int64) {
- assert.NoError(t, user_model.UnfollowUser(db.DefaultContext, followerID, followedID))
+ require.NoError(t, user_model.UnfollowUser(db.DefaultContext, followerID, followedID))
unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: followerID, FollowID: followedID})
}
testSuccess(4, 2)
@@ -490,7 +541,7 @@ func TestUnfollowUser(t *testing.T) {
}
func TestIsUserVisibleToViewer(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) // admin, public
user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // normal, public
@@ -543,10 +594,10 @@ func TestIsUserVisibleToViewer(t *testing.T) {
}
func TestGetAllAdmins(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
admins, err := user_model.GetAllAdmins(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, admins, 1)
assert.Equal(t, int64(1), admins[0].ID)
@@ -564,7 +615,7 @@ func Test_ValidateUser(t *testing.T) {
{ID: 2, Visibility: structs.VisibleTypePrivate}: true,
}
for kase, expected := range kases {
- assert.EqualValues(t, expected, nil == user_model.ValidateUser(kase), fmt.Sprintf("case: %+v", kase))
+ assert.EqualValues(t, expected, nil == user_model.ValidateUser(kase))
}
}
@@ -582,6 +633,7 @@ func Test_NormalizeUserFromEmail(t *testing.T) {
{"test", "test", true},
{"Sinรฉad.O'Connor", "Sinead.OConnor", true},
{"รsir", "AEsir", true},
+ {"Fluรpferd", "Flusspferd", true},
// \u00e9\u0065\u0301
{"รฉeฬ", "ee", true},
{"Awareness Hub", "Awareness-Hub", true},
@@ -591,18 +643,49 @@ func Test_NormalizeUserFromEmail(t *testing.T) {
}
for _, testCase := range testCases {
normalizedName, err := user_model.NormalizeUserName(testCase.Input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, testCase.Expected, normalizedName)
if testCase.IsNormalizedValid {
- assert.NoError(t, user_model.IsUsableUsername(normalizedName))
+ require.NoError(t, user_model.IsUsableUsername(normalizedName))
} else {
- assert.Error(t, user_model.IsUsableUsername(normalizedName))
+ require.Error(t, user_model.IsUsableUsername(normalizedName))
}
}
}
+func TestEmailTo(t *testing.T) {
+ testCases := []struct {
+ fullName string
+ mail string
+ result string
+ }{
+ {"Awareness Hub", "awareness@hub.net", `"Awareness Hub" `},
+ {"name@example.com", "name@example.com", "name@example.com"},
+ {"Hi Its ", "ee@mail.box", `"Hi Its Mee" `},
+ {"Sinรฉad.O'Connor", "sinead.oconnor@gmail.com", "=?utf-8?b?U2luw6lhZC5PJ0Nvbm5vcg==?= "},
+ {"รsir", "aesir@gmx.de", "=?utf-8?q?=C3=86sir?= "},
+ {"new๐user", "new.user@alo.com", "=?utf-8?q?new=F0=9F=98=80user?= "}, // codespell:ignore
+ {`"quoted"`, "quoted@test.com", `"quoted" `},
+ {`gusted`, "gusted@test.com", `"gusted" `},
+ {`Joe Q. Public`, "john.q.public@example.com", `"Joe Q. Public" `},
+ {`Who?`, "one@y.test", `"Who?" `},
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.result, func(t *testing.T) {
+ testUser := &user_model.User{FullName: testCase.fullName, Email: testCase.mail}
+ assert.EqualValues(t, testCase.result, testUser.EmailTo())
+ })
+ }
+
+ t.Run("Override user's email", func(t *testing.T) {
+ testUser := &user_model.User{FullName: "Christine Jorgensen", Email: "christine@test.com"}
+ assert.EqualValues(t, `"Christine Jorgensen" `, testUser.EmailTo("christine@example.org"))
+ })
+}
+
func TestDisabledUserFeatures(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
testValues := container.SetOf(setting.UserFeatureDeletion,
setting.UserFeatureManageSSHKeys,
@@ -616,12 +699,12 @@ func TestDisabledUserFeatures(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- assert.Len(t, setting.Admin.UserDisabledFeatures.Values(), 0)
+ assert.Empty(t, setting.Admin.UserDisabledFeatures.Values())
// no features should be disabled with a plain login type
assert.LessOrEqual(t, user.LoginType, auth.Plain)
- assert.Len(t, user_model.DisabledFeaturesWithLoginType(user).Values(), 0)
- for _, f := range testValues.Values() {
+ assert.Empty(t, user_model.DisabledFeaturesWithLoginType(user).Values())
+ for f := range testValues.Seq() {
assert.False(t, user_model.IsFeatureDisabledWithLoginType(user, f))
}
@@ -630,7 +713,124 @@ func TestDisabledUserFeatures(t *testing.T) {
// all features should be disabled
assert.NotEmpty(t, user_model.DisabledFeaturesWithLoginType(user).Values())
- for _, f := range testValues.Values() {
+ for f := range testValues.Seq() {
assert.True(t, user_model.IsFeatureDisabledWithLoginType(user, f))
}
}
+
+func TestGenerateEmailAuthorizationCode(t *testing.T) {
+ defer test.MockVariableValue(&setting.Service.ActiveCodeLives, 2)()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ code, err := user.GenerateEmailAuthorizationCode(db.DefaultContext, auth.UserActivation)
+ require.NoError(t, err)
+
+ lookupKey, validator, ok := strings.Cut(code, ":")
+ assert.True(t, ok)
+
+ rawValidator, err := hex.DecodeString(validator)
+ require.NoError(t, err)
+
+ authToken, err := auth.FindAuthToken(db.DefaultContext, lookupKey, auth.UserActivation)
+ require.NoError(t, err)
+ assert.False(t, authToken.IsExpired())
+ assert.EqualValues(t, authToken.HashedValidator, auth.HashValidator(rawValidator))
+
+ authToken.Expiry = authToken.Expiry.Add(-int64(setting.Service.ActiveCodeLives) * 60)
+ assert.True(t, authToken.IsExpired())
+}
+
+func TestVerifyUserAuthorizationToken(t *testing.T) {
+ defer test.MockVariableValue(&setting.Service.ActiveCodeLives, 2)()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ code, err := user.GenerateEmailAuthorizationCode(db.DefaultContext, auth.UserActivation)
+ require.NoError(t, err)
+
+ lookupKey, _, ok := strings.Cut(code, ":")
+ assert.True(t, ok)
+
+ t.Run("Wrong purpose", func(t *testing.T) {
+ u, _, err := user_model.VerifyUserAuthorizationToken(db.DefaultContext, code, auth.PasswordReset)
+ require.NoError(t, err)
+ assert.Nil(t, u)
+ })
+
+ t.Run("No delete", func(t *testing.T) {
+ u, _, err := user_model.VerifyUserAuthorizationToken(db.DefaultContext, code, auth.UserActivation)
+ require.NoError(t, err)
+ assert.EqualValues(t, user.ID, u.ID)
+
+ authToken, err := auth.FindAuthToken(db.DefaultContext, lookupKey, auth.UserActivation)
+ require.NoError(t, err)
+ assert.NotNil(t, authToken)
+ })
+
+ t.Run("Delete", func(t *testing.T) {
+ u, deleteToken, err := user_model.VerifyUserAuthorizationToken(db.DefaultContext, code, auth.UserActivation)
+ require.NoError(t, err)
+ assert.EqualValues(t, user.ID, u.ID)
+ require.NoError(t, deleteToken())
+
+ authToken, err := auth.FindAuthToken(db.DefaultContext, lookupKey, auth.UserActivation)
+ require.ErrorIs(t, err, util.ErrNotExist)
+ assert.Nil(t, authToken)
+ })
+}
+
+func TestGetInactiveUsers(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ // all inactive users
+ // user1's createdunix is 1672578000
+ users, err := user_model.GetInactiveUsers(db.DefaultContext, 0)
+ require.NoError(t, err)
+ assert.Len(t, users, 1)
+ interval := time.Now().Unix() - 1672578000 + 3600*24
+ users, err = user_model.GetInactiveUsers(db.DefaultContext, time.Duration(interval*int64(time.Second)))
+ require.NoError(t, err)
+ require.Empty(t, users)
+}
+
+func TestPronounsPrivacy(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ t.Run("EmptyPronounsIfNoneSet", func(t *testing.T) {
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user.Pronouns = ""
+ user.KeepPronounsPrivate = false
+
+ assert.Equal(t, "", user.GetPronouns(false))
+ })
+ t.Run("EmptyPronounsIfSetButPrivateAndNotLoggedIn", func(t *testing.T) {
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user.Pronouns = "any"
+ user.KeepPronounsPrivate = true
+
+ assert.Equal(t, "", user.GetPronouns(false))
+ })
+ t.Run("ReturnPronounsIfSetAndNotPrivateAndNotLoggedIn", func(t *testing.T) {
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user.Pronouns = "any"
+ user.KeepPronounsPrivate = false
+
+ assert.Equal(t, "any", user.GetPronouns(false))
+ })
+ t.Run("ReturnPronounsIfSetAndPrivateAndLoggedIn", func(t *testing.T) {
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user.Pronouns = "any"
+ user.KeepPronounsPrivate = false
+
+ assert.Equal(t, "any", user.GetPronouns(true))
+ })
+ t.Run("ReturnPronounsIfSetAndNotPrivateAndLoggedIn", func(t *testing.T) {
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user.Pronouns = "any"
+ user.KeepPronounsPrivate = true
+
+ assert.Equal(t, "any", user.GetPronouns(true))
+ })
+}
diff --git a/models/user/user_update.go b/models/user/user_update.go
index 66702e2a14..bf258811e4 100644
--- a/models/user/user_update.go
+++ b/models/user/user_update.go
@@ -6,7 +6,7 @@ package user
import (
"context"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
func IncrUserRepoNum(ctx context.Context, userID int64) error {
diff --git a/models/webhook/hooktask.go b/models/webhook/hooktask.go
index 8734feb2e1..58600cb8bf 100644
--- a/models/webhook/hooktask.go
+++ b/models/webhook/hooktask.go
@@ -8,12 +8,12 @@ import (
"errors"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ webhook_module "forgejo.org/modules/webhook"
gouuid "github.com/google/uuid"
"xorm.io/builder"
diff --git a/models/webhook/main_test.go b/models/webhook/main_test.go
index f19465d505..fac998e8cd 100644
--- a/models/webhook/main_test.go
+++ b/models/webhook/main_test.go
@@ -6,7 +6,7 @@ package webhook
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/models/webhook/webhook.go b/models/webhook/webhook.go
index f3370f3db5..0691f231b2 100644
--- a/models/webhook/webhook.go
+++ b/models/webhook/webhook.go
@@ -9,15 +9,15 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/secret"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/secret"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ webhook_module "forgejo.org/modules/webhook"
"xorm.io/builder"
)
diff --git a/models/webhook/webhook_system.go b/models/webhook/webhook_system.go
index 62e8286205..b63346635c 100644
--- a/models/webhook/webhook_system.go
+++ b/models/webhook/webhook_system.go
@@ -7,7 +7,7 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
+ "forgejo.org/models/db"
)
// GetDefaultWebhooks returns all admin-default webhooks.
diff --git a/models/webhook/webhook_test.go b/models/webhook/webhook_test.go
index b4f6ffa189..7f0abbd8bb 100644
--- a/models/webhook/webhook_test.go
+++ b/models/webhook/webhook_test.go
@@ -4,18 +4,18 @@
package webhook
import (
- "context"
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/timeutil"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/timeutil"
+ webhook_module "forgejo.org/modules/webhook"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestHookContentType_Name(t *testing.T) {
@@ -30,10 +30,10 @@ func TestIsValidHookContentType(t *testing.T) {
}
func TestWebhook_History(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1})
tasks, err := webhook.History(db.DefaultContext, 0)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, tasks, 3) {
assert.Equal(t, int64(3), tasks[0].ID)
assert.Equal(t, int64(2), tasks[1].ID)
@@ -42,12 +42,12 @@ func TestWebhook_History(t *testing.T) {
webhook = unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2})
tasks, err = webhook.History(db.DefaultContext, 0)
- assert.NoError(t, err)
- assert.Len(t, tasks, 0)
+ require.NoError(t, err)
+ assert.Empty(t, tasks)
}
func TestWebhook_UpdateEvent(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1})
hookEvent := &webhook_module.HookEvent{
PushOnly: true,
@@ -60,10 +60,10 @@ func TestWebhook_UpdateEvent(t *testing.T) {
},
}
webhook.HookEvent = hookEvent
- assert.NoError(t, webhook.UpdateEvent())
+ require.NoError(t, webhook.UpdateEvent())
assert.NotEmpty(t, webhook.Events)
actualHookEvent := &webhook_module.HookEvent{}
- assert.NoError(t, json.Unmarshal([]byte(webhook.Events), actualHookEvent))
+ require.NoError(t, json.Unmarshal([]byte(webhook.Events), actualHookEvent))
assert.Equal(t, *hookEvent, *actualHookEvent)
}
@@ -96,39 +96,39 @@ func TestCreateWebhook(t *testing.T) {
Events: `{"push_only":false,"send_everything":false,"choose_events":false,"events":{"create":false,"push":true,"pull_request":true}}`,
}
unittest.AssertNotExistsBean(t, hook)
- assert.NoError(t, CreateWebhook(db.DefaultContext, hook))
+ require.NoError(t, CreateWebhook(db.DefaultContext, hook))
unittest.AssertExistsAndLoadBean(t, hook)
}
func TestGetWebhookByRepoID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hook, err := GetWebhookByRepoID(db.DefaultContext, 1, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(1), hook.ID)
_, err = GetWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, IsErrWebhookNotExist(err))
}
func TestGetWebhookByOwnerID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hook, err := GetWebhookByOwnerID(db.DefaultContext, 3, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(3), hook.ID)
_, err = GetWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, IsErrWebhookNotExist(err))
}
func TestGetActiveWebhooksByRepoID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
activateWebhook(t, 1)
hooks, err := db.Find[Webhook](db.DefaultContext, ListWebhookOptions{RepoID: 1, IsActive: optional.Some(true)})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, hooks, 1) {
assert.Equal(t, int64(1), hooks[0].ID)
assert.True(t, hooks[0].IsActive)
@@ -136,9 +136,9 @@ func TestGetActiveWebhooksByRepoID(t *testing.T) {
}
func TestGetWebhooksByRepoID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hooks, err := db.Find[Webhook](db.DefaultContext, ListWebhookOptions{RepoID: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, hooks, 2) {
assert.Equal(t, int64(1), hooks[0].ID)
assert.Equal(t, int64(2), hooks[1].ID)
@@ -146,12 +146,12 @@ func TestGetWebhooksByRepoID(t *testing.T) {
}
func TestGetActiveWebhooksByOwnerID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
activateWebhook(t, 3)
hooks, err := db.Find[Webhook](db.DefaultContext, ListWebhookOptions{OwnerID: 3, IsActive: optional.Some(true)})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, hooks, 1) {
assert.Equal(t, int64(3), hooks[0].ID)
assert.True(t, hooks[0].IsActive)
@@ -162,16 +162,16 @@ func activateWebhook(t *testing.T, hookID int64) {
t.Helper()
updated, err := db.GetEngine(db.DefaultContext).ID(hookID).Cols("is_active").Update(Webhook{IsActive: true})
assert.Equal(t, int64(1), updated)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func TestGetWebhooksByOwnerID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
activateWebhook(t, 3)
hooks, err := db.Find[Webhook](db.DefaultContext, ListWebhookOptions{OwnerID: 3})
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, hooks, 1) {
assert.Equal(t, int64(3), hooks[0].ID)
assert.True(t, hooks[0].IsActive)
@@ -179,41 +179,41 @@ func TestGetWebhooksByOwnerID(t *testing.T) {
}
func TestUpdateWebhook(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2})
hook.IsActive = true
hook.ContentType = ContentTypeForm
unittest.AssertNotExistsBean(t, hook)
- assert.NoError(t, UpdateWebhook(db.DefaultContext, hook))
+ require.NoError(t, UpdateWebhook(db.DefaultContext, hook))
unittest.AssertExistsAndLoadBean(t, hook)
}
func TestDeleteWebhookByRepoID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2, RepoID: 1})
- assert.NoError(t, DeleteWebhookByRepoID(db.DefaultContext, 1, 2))
+ require.NoError(t, DeleteWebhookByRepoID(db.DefaultContext, 1, 2))
unittest.AssertNotExistsBean(t, &Webhook{ID: 2, RepoID: 1})
err := DeleteWebhookByRepoID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, IsErrWebhookNotExist(err))
}
func TestDeleteWebhookByOwnerID(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 3, OwnerID: 3})
- assert.NoError(t, DeleteWebhookByOwnerID(db.DefaultContext, 3, 3))
+ require.NoError(t, DeleteWebhookByOwnerID(db.DefaultContext, 3, 3))
unittest.AssertNotExistsBean(t, &Webhook{ID: 3, OwnerID: 3})
err := DeleteWebhookByOwnerID(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, IsErrWebhookNotExist(err))
}
func TestHookTasks(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hookTasks, err := HookTasks(db.DefaultContext, 1, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, hookTasks, 3) {
assert.Equal(t, int64(3), hookTasks[0].ID)
assert.Equal(t, int64(2), hookTasks[1].ID)
@@ -221,35 +221,35 @@ func TestHookTasks(t *testing.T) {
}
hookTasks, err = HookTasks(db.DefaultContext, unittest.NonexistentID, 1)
- assert.NoError(t, err)
- assert.Len(t, hookTasks, 0)
+ require.NoError(t, err)
+ assert.Empty(t, hookTasks)
}
func TestCreateHookTask(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hookTask := &HookTask{
HookID: 3,
PayloadVersion: 2,
}
unittest.AssertNotExistsBean(t, hookTask)
_, err := CreateHookTask(db.DefaultContext, hookTask)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, hookTask)
}
func TestUpdateHookTask(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hook := unittest.AssertExistsAndLoadBean(t, &HookTask{ID: 1})
hook.PayloadContent = "new payload content"
hook.IsDelivered = true
unittest.AssertNotExistsBean(t, hook)
- assert.NoError(t, UpdateHookTask(db.DefaultContext, hook))
+ require.NoError(t, UpdateHookTask(db.DefaultContext, hook))
unittest.AssertExistsAndLoadBean(t, hook)
}
func TestCleanupHookTaskTable_PerWebhook_DeletesDelivered(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hookTask := &HookTask{
HookID: 3,
IsDelivered: true,
@@ -258,15 +258,15 @@ func TestCleanupHookTaskTable_PerWebhook_DeletesDelivered(t *testing.T) {
}
unittest.AssertNotExistsBean(t, hookTask)
_, err := CreateHookTask(db.DefaultContext, hookTask)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, hookTask)
- assert.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 0))
+ require.NoError(t, CleanupHookTaskTable(t.Context(), PerWebhook, 168*time.Hour, 0))
unittest.AssertNotExistsBean(t, hookTask)
}
func TestCleanupHookTaskTable_PerWebhook_LeavesUndelivered(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hookTask := &HookTask{
HookID: 4,
IsDelivered: false,
@@ -274,15 +274,15 @@ func TestCleanupHookTaskTable_PerWebhook_LeavesUndelivered(t *testing.T) {
}
unittest.AssertNotExistsBean(t, hookTask)
_, err := CreateHookTask(db.DefaultContext, hookTask)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, hookTask)
- assert.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 0))
+ require.NoError(t, CleanupHookTaskTable(t.Context(), PerWebhook, 168*time.Hour, 0))
unittest.AssertExistsAndLoadBean(t, hookTask)
}
func TestCleanupHookTaskTable_PerWebhook_LeavesMostRecentTask(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hookTask := &HookTask{
HookID: 4,
IsDelivered: true,
@@ -291,15 +291,15 @@ func TestCleanupHookTaskTable_PerWebhook_LeavesMostRecentTask(t *testing.T) {
}
unittest.AssertNotExistsBean(t, hookTask)
_, err := CreateHookTask(db.DefaultContext, hookTask)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, hookTask)
- assert.NoError(t, CleanupHookTaskTable(context.Background(), PerWebhook, 168*time.Hour, 1))
+ require.NoError(t, CleanupHookTaskTable(t.Context(), PerWebhook, 168*time.Hour, 1))
unittest.AssertExistsAndLoadBean(t, hookTask)
}
func TestCleanupHookTaskTable_OlderThan_DeletesDelivered(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hookTask := &HookTask{
HookID: 3,
IsDelivered: true,
@@ -308,15 +308,15 @@ func TestCleanupHookTaskTable_OlderThan_DeletesDelivered(t *testing.T) {
}
unittest.AssertNotExistsBean(t, hookTask)
_, err := CreateHookTask(db.DefaultContext, hookTask)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, hookTask)
- assert.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0))
+ require.NoError(t, CleanupHookTaskTable(t.Context(), OlderThan, 168*time.Hour, 0))
unittest.AssertNotExistsBean(t, hookTask)
}
func TestCleanupHookTaskTable_OlderThan_LeavesUndelivered(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hookTask := &HookTask{
HookID: 4,
IsDelivered: false,
@@ -324,15 +324,15 @@ func TestCleanupHookTaskTable_OlderThan_LeavesUndelivered(t *testing.T) {
}
unittest.AssertNotExistsBean(t, hookTask)
_, err := CreateHookTask(db.DefaultContext, hookTask)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, hookTask)
- assert.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0))
+ require.NoError(t, CleanupHookTaskTable(t.Context(), OlderThan, 168*time.Hour, 0))
unittest.AssertExistsAndLoadBean(t, hookTask)
}
func TestCleanupHookTaskTable_OlderThan_LeavesTaskEarlierThanAgeToDelete(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
hookTask := &HookTask{
HookID: 4,
IsDelivered: true,
@@ -341,9 +341,9 @@ func TestCleanupHookTaskTable_OlderThan_LeavesTaskEarlierThanAgeToDelete(t *test
}
unittest.AssertNotExistsBean(t, hookTask)
_, err := CreateHookTask(db.DefaultContext, hookTask)
- assert.NoError(t, err)
+ require.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, hookTask)
- assert.NoError(t, CleanupHookTaskTable(context.Background(), OlderThan, 168*time.Hour, 0))
+ require.NoError(t, CleanupHookTaskTable(t.Context(), OlderThan, 168*time.Hour, 0))
unittest.AssertExistsAndLoadBean(t, hookTask)
}
diff --git a/modules/actions/github.go b/modules/actions/github.go
index c27d4edf53..111537c913 100644
--- a/modules/actions/github.go
+++ b/modules/actions/github.go
@@ -4,7 +4,7 @@
package actions
import (
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ webhook_module "forgejo.org/modules/webhook"
)
const (
diff --git a/modules/actions/github_test.go b/modules/actions/github_test.go
index 6652ff6eac..2a5d8a19b8 100644
--- a/modules/actions/github_test.go
+++ b/modules/actions/github_test.go
@@ -6,7 +6,7 @@ package actions
import (
"testing"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ webhook_module "forgejo.org/modules/webhook"
"github.com/stretchr/testify/assert"
)
diff --git a/modules/actions/log.go b/modules/actions/log.go
index c38082b5dc..78b1196f87 100644
--- a/modules/actions/log.go
+++ b/modules/actions/log.go
@@ -12,9 +12,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/dbfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/storage"
+ "forgejo.org/models/dbfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/zstd"
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
"google.golang.org/protobuf/types/known/timestamppb"
@@ -28,6 +29,9 @@ const (
defaultBufSize = MaxLineSize
)
+// WriteLogs appends logs to DBFS file for temporary storage.
+// It doesn't respect the file format in the filename like ".zst", since it's difficult to reopen a closed compressed file and append new content.
+// Why doesn't it store logs in object storage directly? Because it's not efficient to append content to object storage.
func WriteLogs(ctx context.Context, filename string, offset int64, rows []*runnerv1.LogRow) ([]int, error) {
flag := os.O_WRONLY
if offset == 0 {
@@ -106,6 +110,17 @@ func ReadLogs(ctx context.Context, inStorage bool, filename string, offset, limi
return rows, nil
}
+const (
+ // logZstdBlockSize is the block size for zstd compression.
+ // 128KB leads the compression ratio to be close to the regular zstd compression.
+ // And it means each read from the underlying object storage will be at least 128KB*(compression ratio).
+ // The compression ratio is about 30% for text files, so the actual read size is about 38KB, which should be acceptable.
+ logZstdBlockSize = 128 * 1024 // 128KB
+)
+
+// TransferLogs transfers logs from DBFS to object storage.
+// It happens when the file is complete and no more logs will be appended.
+// It respects the file format in the filename like ".zst", and compresses the content if needed.
func TransferLogs(ctx context.Context, filename string) (func(), error) {
name := DBFSPrefix + filename
remove := func() {
@@ -119,7 +134,26 @@ func TransferLogs(ctx context.Context, filename string) (func(), error) {
}
defer f.Close()
- if _, err := storage.Actions.Save(filename, f, -1); err != nil {
+ var reader io.Reader = f
+ if strings.HasSuffix(filename, ".zst") {
+ r, w := io.Pipe()
+ reader = r
+ zstdWriter, err := zstd.NewSeekableWriter(w, logZstdBlockSize)
+ if err != nil {
+ return nil, fmt.Errorf("zstd NewSeekableWriter: %w", err)
+ }
+ go func() {
+ defer func() {
+ _ = w.CloseWithError(zstdWriter.Close())
+ }()
+ if _, err := io.Copy(zstdWriter, f); err != nil {
+ _ = w.CloseWithError(err)
+ return
+ }
+ }()
+ }
+
+ if _, err := storage.Actions.Save(filename, reader, -1); err != nil {
return nil, fmt.Errorf("storage save %q: %w", filename, err)
}
return remove, nil
@@ -150,11 +184,22 @@ func OpenLogs(ctx context.Context, inStorage bool, filename string) (io.ReadSeek
}
return f, nil
}
+
f, err := storage.Actions.Open(filename)
if err != nil {
return nil, fmt.Errorf("storage open %q: %w", filename, err)
}
- return f, nil
+
+ var reader io.ReadSeekCloser = f
+ if strings.HasSuffix(filename, ".zst") {
+ r, err := zstd.NewSeekableReader(f)
+ if err != nil {
+ return nil, fmt.Errorf("zstd NewSeekableReader: %w", err)
+ }
+ reader = r
+ }
+
+ return reader, nil
}
func FormatLog(timestamp time.Time, content string) string {
diff --git a/modules/actions/task_state.go b/modules/actions/task_state.go
index 31a74be3fd..77bfc747ee 100644
--- a/modules/actions/task_state.go
+++ b/modules/actions/task_state.go
@@ -4,7 +4,7 @@
package actions
import (
- actions_model "code.gitea.io/gitea/models/actions"
+ actions_model "forgejo.org/models/actions"
)
const (
@@ -18,8 +18,32 @@ func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep {
return fullStepsOfEmptySteps(task)
}
- firstStep := task.Steps[0]
+ // firstStep is the first step that has run or running, not include preStep.
+ // For example,
+ // 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): firstStep is step1.
+ // 2. preStep(Success) -> step1(Skipped) -> step2(Success) -> postStep(Success): firstStep is step2.
+ // 3. preStep(Success) -> step1(Running) -> step2(Waiting) -> postStep(Waiting): firstStep is step1.
+ // 4. preStep(Success) -> step1(Skipped) -> step2(Skipped) -> postStep(Skipped): firstStep is nil.
+ // 5. preStep(Success) -> step1(Cancelled) -> step2(Cancelled) -> postStep(Cancelled): firstStep is nil.
+ var firstStep *actions_model.ActionTaskStep
+ // lastHasRunStep is the last step that has run.
+ // For example,
+ // 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): lastHasRunStep is step1.
+ // 2. preStep(Success) -> step1(Success) -> step2(Success) -> step3(Success) -> postStep(Success): lastHasRunStep is step3.
+ // 3. preStep(Success) -> step1(Success) -> step2(Failure) -> step3 -> postStep(Waiting): lastHasRunStep is step2.
+ // So its Stopped is the Started of postStep when there are no more steps to run.
+ var lastHasRunStep *actions_model.ActionTaskStep
+
var logIndex int64
+ for _, step := range task.Steps {
+ if firstStep == nil && (step.Status.HasRun() || step.Status.IsRunning()) {
+ firstStep = step
+ }
+ if step.Status.HasRun() {
+ lastHasRunStep = step
+ }
+ logIndex += step.LogLength
+ }
preStep := &actions_model.ActionTaskStep{
Name: preStepName,
@@ -28,32 +52,17 @@ func FullSteps(task *actions_model.ActionTask) []*actions_model.ActionTaskStep {
Status: actions_model.StatusRunning,
}
- if firstStep.Status.HasRun() || firstStep.Status.IsRunning() {
+ // No step has run or is running, so preStep is equal to the task
+ if firstStep == nil {
+ preStep.Stopped = task.Stopped
+ preStep.Status = task.Status
+ } else {
preStep.LogLength = firstStep.LogIndex
preStep.Stopped = firstStep.Started
preStep.Status = actions_model.StatusSuccess
- } else if task.Status.IsDone() {
- preStep.Stopped = task.Stopped
- preStep.Status = actions_model.StatusFailure
- if task.Status.IsSkipped() {
- preStep.Status = actions_model.StatusSkipped
- }
}
logIndex += preStep.LogLength
- // lastHasRunStep is the last step that has run.
- // For example,
- // 1. preStep(Success) -> step1(Success) -> step2(Running) -> step3(Waiting) -> postStep(Waiting): lastHasRunStep is step1.
- // 2. preStep(Success) -> step1(Success) -> step2(Success) -> step3(Success) -> postStep(Success): lastHasRunStep is step3.
- // 3. preStep(Success) -> step1(Success) -> step2(Failure) -> step3 -> postStep(Waiting): lastHasRunStep is step2.
- // So its Stopped is the Started of postStep when there are no more steps to run.
- var lastHasRunStep *actions_model.ActionTaskStep
- for _, step := range task.Steps {
- if step.Status.HasRun() {
- lastHasRunStep = step
- }
- logIndex += step.LogLength
- }
if lastHasRunStep == nil {
lastHasRunStep = preStep
}
diff --git a/modules/actions/task_state_test.go b/modules/actions/task_state_test.go
index 28213d781b..e18de4573f 100644
--- a/modules/actions/task_state_test.go
+++ b/modules/actions/task_state_test.go
@@ -6,7 +6,7 @@ package actions
import (
"testing"
- actions_model "code.gitea.io/gitea/models/actions"
+ actions_model "forgejo.org/models/actions"
"github.com/stretchr/testify/assert"
)
@@ -137,6 +137,25 @@ func TestFullSteps(t *testing.T) {
{Name: postStepName, Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0},
},
},
+ {
+ name: "first step is skipped",
+ task: &actions_model.ActionTask{
+ Steps: []*actions_model.ActionTaskStep{
+ {Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0},
+ {Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090},
+ },
+ Status: actions_model.StatusSuccess,
+ Started: 10000,
+ Stopped: 10100,
+ LogLength: 100,
+ },
+ want: []*actions_model.ActionTaskStep{
+ {Name: preStepName, Status: actions_model.StatusSuccess, LogIndex: 0, LogLength: 10, Started: 10000, Stopped: 10010},
+ {Status: actions_model.StatusSkipped, LogIndex: 0, LogLength: 0, Started: 0, Stopped: 0},
+ {Status: actions_model.StatusSuccess, LogIndex: 10, LogLength: 80, Started: 10010, Stopped: 10090},
+ {Name: postStepName, Status: actions_model.StatusSuccess, LogIndex: 90, LogLength: 10, Started: 10090, Stopped: 10100},
+ },
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go
index 9319c05119..43948cce5c 100644
--- a/modules/actions/workflows.go
+++ b/modules/actions/workflows.go
@@ -8,10 +8,10 @@ import (
"io"
"strings"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
+ webhook_module "forgejo.org/modules/webhook"
"github.com/gobwas/glob"
"github.com/nektos/act/pkg/jobparser"
@@ -649,8 +649,7 @@ func matchReleaseEvent(payload *api.ReleasePayload, evt *jobparser.Event) bool {
// unpublished, created, deleted, prereleased, released
action := payload.Action
- switch action {
- case api.HookReleaseUpdated:
+ if action == api.HookReleaseUpdated {
action = "edited"
}
for _, val := range vals {
@@ -686,8 +685,7 @@ func matchPackageEvent(payload *api.PackagePayload, evt *jobparser.Event) bool {
// updated
action := payload.Action
- switch action {
- case api.HookPackageCreated:
+ if action == api.HookPackageCreated {
action = "published"
}
for _, val := range vals {
diff --git a/modules/actions/workflows_test.go b/modules/actions/workflows_test.go
index dca0c2924c..b85ed7fd56 100644
--- a/modules/actions/workflows_test.go
+++ b/modules/actions/workflows_test.go
@@ -6,67 +6,77 @@ package actions
import (
"testing"
- "code.gitea.io/gitea/modules/git"
- api "code.gitea.io/gitea/modules/structs"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ "forgejo.org/modules/git"
+ api "forgejo.org/modules/structs"
+ webhook_module "forgejo.org/modules/webhook"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestDetectMatched(t *testing.T) {
testCases := []struct {
- desc string
- commit *git.Commit
- triggedEvent webhook_module.HookEventType
- payload api.Payloader
- yamlOn string
- expected bool
+ desc string
+ commit *git.Commit
+ triggeredEvent webhook_module.HookEventType
+ payload api.Payloader
+ yamlOn string
+ expected bool
}{
{
- desc: "HookEventCreate(create) matches GithubEventCreate(create)",
- triggedEvent: webhook_module.HookEventCreate,
- payload: nil,
- yamlOn: "on: create",
- expected: true,
+ desc: "HookEventCreate(create) matches GithubEventCreate(create)",
+ triggeredEvent: webhook_module.HookEventCreate,
+ payload: nil,
+ yamlOn: "on: create",
+ expected: true,
},
{
- desc: "HookEventIssues(issues) `opened` action matches GithubEventIssues(issues)",
- triggedEvent: webhook_module.HookEventIssues,
- payload: &api.IssuePayload{Action: api.HookIssueOpened},
- yamlOn: "on: issues",
- expected: true,
+ desc: "HookEventIssues(issues) `opened` action matches GithubEventIssues(issues)",
+ triggeredEvent: webhook_module.HookEventIssues,
+ payload: &api.IssuePayload{Action: api.HookIssueOpened},
+ yamlOn: "on: issues",
+ expected: true,
},
{
- desc: "HookEventIssues(issues) `milestoned` action matches GithubEventIssues(issues)",
- triggedEvent: webhook_module.HookEventIssues,
- payload: &api.IssuePayload{Action: api.HookIssueMilestoned},
- yamlOn: "on: issues",
- expected: true,
+ desc: "HookEventIssueComment(issue_comment) `created` action matches GithubEventIssueComment(issue_comment)",
+ triggeredEvent: webhook_module.HookEventIssueComment,
+ payload: &api.IssueCommentPayload{Action: api.HookIssueCommentCreated},
+ yamlOn: "on:\n issue_comment:\n types: [created]",
+ expected: true,
+ },
+
+ {
+ desc: "HookEventIssues(issues) `milestoned` action matches GithubEventIssues(issues)",
+ triggeredEvent: webhook_module.HookEventIssues,
+ payload: &api.IssuePayload{Action: api.HookIssueMilestoned},
+ yamlOn: "on: issues",
+ expected: true,
+ },
+
+ {
+ desc: "HookEventPullRequestSync(pull_request_sync) matches GithubEventPullRequest(pull_request)",
+ triggeredEvent: webhook_module.HookEventPullRequestSync,
+ payload: &api.PullRequestPayload{Action: api.HookIssueSynchronized},
+ yamlOn: "on: pull_request",
+ expected: true,
},
{
- desc: "HookEventPullRequestSync(pull_request_sync) matches GithubEventPullRequest(pull_request)",
- triggedEvent: webhook_module.HookEventPullRequestSync,
- payload: &api.PullRequestPayload{Action: api.HookIssueSynchronized},
- yamlOn: "on: pull_request",
- expected: true,
+ desc: "HookEventPullRequest(pull_request) `label_updated` action doesn't match GithubEventPullRequest(pull_request) with no activity type",
+ triggeredEvent: webhook_module.HookEventPullRequest,
+ payload: &api.PullRequestPayload{Action: api.HookIssueLabelUpdated},
+ yamlOn: "on: pull_request",
+ expected: false,
},
{
- desc: "HookEventPullRequest(pull_request) `label_updated` action doesn't match GithubEventPullRequest(pull_request) with no activity type",
- triggedEvent: webhook_module.HookEventPullRequest,
- payload: &api.PullRequestPayload{Action: api.HookIssueLabelUpdated},
- yamlOn: "on: pull_request",
- expected: false,
+ desc: "HookEventPullRequest(pull_request) `closed` action doesn't match GithubEventPullRequest(pull_request) with no activity type",
+ triggeredEvent: webhook_module.HookEventPullRequest,
+ payload: &api.PullRequestPayload{Action: api.HookIssueClosed},
+ yamlOn: "on: pull_request",
+ expected: false,
},
{
- desc: "HookEventPullRequest(pull_request) `closed` action doesn't match GithubEventPullRequest(pull_request) with no activity type",
- triggedEvent: webhook_module.HookEventPullRequest,
- payload: &api.PullRequestPayload{Action: api.HookIssueClosed},
- yamlOn: "on: pull_request",
- expected: false,
- },
- {
- desc: "HookEventPullRequest(pull_request) `closed` action doesn't match GithubEventPullRequest(pull_request) with branches",
- triggedEvent: webhook_module.HookEventPullRequest,
+ desc: "HookEventPullRequest(pull_request) `closed` action doesn't match GithubEventPullRequest(pull_request) with branches",
+ triggeredEvent: webhook_module.HookEventPullRequest,
payload: &api.PullRequestPayload{
Action: api.HookIssueClosed,
PullRequest: &api.PullRequest{
@@ -77,69 +87,77 @@ func TestDetectMatched(t *testing.T) {
expected: false,
},
{
- desc: "HookEventPullRequest(pull_request) `label_updated` action matches GithubEventPullRequest(pull_request) with `label` activity type",
- triggedEvent: webhook_module.HookEventPullRequest,
- payload: &api.PullRequestPayload{Action: api.HookIssueLabelUpdated},
- yamlOn: "on:\n pull_request:\n types: [labeled]",
- expected: true,
+ desc: "HookEventPullRequest(pull_request) `label_updated` action matches GithubEventPullRequest(pull_request) with `label` activity type",
+ triggeredEvent: webhook_module.HookEventPullRequest,
+ payload: &api.PullRequestPayload{Action: api.HookIssueLabelUpdated},
+ yamlOn: "on:\n pull_request:\n types: [labeled]",
+ expected: true,
},
{
- desc: "HookEventPullRequestReviewComment(pull_request_review_comment) matches GithubEventPullRequestReviewComment(pull_request_review_comment)",
- triggedEvent: webhook_module.HookEventPullRequestReviewComment,
- payload: &api.PullRequestPayload{Action: api.HookIssueReviewed},
- yamlOn: "on:\n pull_request_review_comment:\n types: [created]",
- expected: true,
+ desc: "HookEventPullRequestReviewComment(pull_request_review_comment) matches GithubEventPullRequestReviewComment(pull_request_review_comment)",
+ triggeredEvent: webhook_module.HookEventPullRequestReviewComment,
+ payload: &api.PullRequestPayload{Action: api.HookIssueReviewed},
+ yamlOn: "on:\n pull_request_review_comment:\n types: [created]",
+ expected: true,
},
{
- desc: "HookEventPullRequestReviewRejected(pull_request_review_rejected) doesn't match GithubEventPullRequestReview(pull_request_review) with `dismissed` activity type (we don't support `dismissed` at present)",
- triggedEvent: webhook_module.HookEventPullRequestReviewRejected,
- payload: &api.PullRequestPayload{Action: api.HookIssueReviewed},
- yamlOn: "on:\n pull_request_review:\n types: [dismissed]",
- expected: false,
+ desc: "HookEventPullRequestReviewRejected(pull_request_review_rejected) doesn't match GithubEventPullRequestReview(pull_request_review) with `dismissed` activity type (we don't support `dismissed` at present)",
+ triggeredEvent: webhook_module.HookEventPullRequestReviewRejected,
+ payload: &api.PullRequestPayload{Action: api.HookIssueReviewed},
+ yamlOn: "on:\n pull_request_review:\n types: [dismissed]",
+ expected: false,
},
{
- desc: "HookEventRelease(release) `published` action matches GithubEventRelease(release) with `published` activity type",
- triggedEvent: webhook_module.HookEventRelease,
- payload: &api.ReleasePayload{Action: api.HookReleasePublished},
- yamlOn: "on:\n release:\n types: [published]",
- expected: true,
+ desc: "HookEventRelease(release) `published` action matches GithubEventRelease(release) with `published` activity type",
+ triggeredEvent: webhook_module.HookEventRelease,
+ payload: &api.ReleasePayload{Action: api.HookReleasePublished},
+ yamlOn: "on:\n release:\n types: [published]",
+ expected: true,
},
{
- desc: "HookEventPackage(package) `created` action doesn't match GithubEventRegistryPackage(registry_package) with `updated` activity type",
- triggedEvent: webhook_module.HookEventPackage,
- payload: &api.PackagePayload{Action: api.HookPackageCreated},
- yamlOn: "on:\n registry_package:\n types: [updated]",
- expected: false,
+ desc: "HookEventRelease(updated) `updated` action matches GithubEventRelease(edited) with `edited` activity type",
+ triggeredEvent: webhook_module.HookEventRelease,
+ payload: &api.ReleasePayload{Action: api.HookReleaseUpdated},
+ yamlOn: "on:\n release:\n types: [edited]",
+ expected: true,
+ },
+
+ {
+ desc: "HookEventPackage(package) `created` action doesn't match GithubEventRegistryPackage(registry_package) with `updated` activity type",
+ triggeredEvent: webhook_module.HookEventPackage,
+ payload: &api.PackagePayload{Action: api.HookPackageCreated},
+ yamlOn: "on:\n registry_package:\n types: [updated]",
+ expected: false,
},
{
- desc: "HookEventWiki(wiki) matches GithubEventGollum(gollum)",
- triggedEvent: webhook_module.HookEventWiki,
- payload: nil,
- yamlOn: "on: gollum",
- expected: true,
+ desc: "HookEventWiki(wiki) matches GithubEventGollum(gollum)",
+ triggeredEvent: webhook_module.HookEventWiki,
+ payload: nil,
+ yamlOn: "on: gollum",
+ expected: true,
},
{
- desc: "HookEventSchedue(schedule) matches GithubEventSchedule(schedule)",
- triggedEvent: webhook_module.HookEventSchedule,
- payload: nil,
- yamlOn: "on: schedule",
- expected: true,
+ desc: "HookEventSchedule(schedule) matches GithubEventSchedule(schedule)",
+ triggeredEvent: webhook_module.HookEventSchedule,
+ payload: nil,
+ yamlOn: "on: schedule",
+ expected: true,
},
{
- desc: "HookEventWorkflowDispatch(workflow_dispatch) matches GithubEventWorkflowDispatch(workflow_dispatch)",
- triggedEvent: webhook_module.HookEventWorkflowDispatch,
- payload: nil,
- yamlOn: "on: workflow_dispatch",
- expected: true,
+ desc: "HookEventWorkflowDispatch(workflow_dispatch) matches GithubEventWorkflowDispatch(workflow_dispatch)",
+ triggeredEvent: webhook_module.HookEventWorkflowDispatch,
+ payload: nil,
+ yamlOn: "on: workflow_dispatch",
+ expected: true,
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
evts, err := GetEventsFromContent([]byte(tc.yamlOn))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, evts, 1)
- assert.Equal(t, tc.expected, detectMatched(nil, tc.commit, tc.triggedEvent, tc.payload, evts[0]))
+ assert.Equal(t, tc.expected, detectMatched(nil, tc.commit, tc.triggeredEvent, tc.payload, evts[0]))
})
}
}
diff --git a/modules/activitypub/client.go b/modules/activitypub/client.go
index 38ccc58eb5..d43e9c2bb0 100644
--- a/modules/activitypub/client.go
+++ b/modules/activitypub/client.go
@@ -17,12 +17,12 @@ import (
"strings"
"time"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/proxy"
- "code.gitea.io/gitea/modules/setting"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/proxy"
+ "forgejo.org/modules/setting"
- "github.com/go-fed/httpsig"
+ "github.com/42wim/httpsig"
)
const (
@@ -36,22 +36,61 @@ func CurrentTime() string {
}
func containsRequiredHTTPHeaders(method string, headers []string) error {
- var hasRequestTarget, hasDate, hasDigest bool
+ var hasRequestTarget, hasDate, hasDigest, hasHost bool
for _, header := range headers {
hasRequestTarget = hasRequestTarget || header == httpsig.RequestTarget
hasDate = hasDate || header == "Date"
hasDigest = hasDigest || header == "Digest"
+ hasHost = hasHost || header == "Host"
}
if !hasRequestTarget {
return fmt.Errorf("missing http header for %s: %s", method, httpsig.RequestTarget)
} else if !hasDate {
return fmt.Errorf("missing http header for %s: Date", method)
+ } else if !hasHost {
+ return fmt.Errorf("missing http header for %s: Host", method)
} else if !hasDigest && method != http.MethodGet {
return fmt.Errorf("missing http header for %s: Digest", method)
}
return nil
}
+// Client struct
+type ClientFactory struct {
+ client *http.Client
+ algs []httpsig.Algorithm
+ digestAlg httpsig.DigestAlgorithm
+ getHeaders []string
+ postHeaders []string
+}
+
+// NewClient function
+func NewClientFactory() (c *ClientFactory, err error) {
+ if err = containsRequiredHTTPHeaders(http.MethodGet, setting.Federation.GetHeaders); err != nil {
+ return nil, err
+ } else if err = containsRequiredHTTPHeaders(http.MethodPost, setting.Federation.PostHeaders); err != nil {
+ return nil, err
+ }
+
+ c = &ClientFactory{
+ client: &http.Client{
+ Transport: &http.Transport{
+ Proxy: proxy.Proxy(),
+ },
+ Timeout: 5 * time.Second,
+ },
+ algs: setting.HttpsigAlgs,
+ digestAlg: httpsig.DigestAlgorithm(setting.Federation.DigestAlgorithm),
+ getHeaders: setting.Federation.GetHeaders,
+ postHeaders: setting.Federation.PostHeaders,
+ }
+ return c, err
+}
+
+type APClientFactory interface {
+ WithKeys(ctx context.Context, user *user_model.User, pubID string) (APClient, error)
+}
+
// Client struct
type Client struct {
client *http.Client
@@ -63,14 +102,8 @@ type Client struct {
pubID string
}
-// NewClient function
-func NewClient(ctx context.Context, user *user_model.User, pubID string) (c *Client, err error) {
- if err = containsRequiredHTTPHeaders(http.MethodGet, setting.Federation.GetHeaders); err != nil {
- return nil, err
- } else if err = containsRequiredHTTPHeaders(http.MethodPost, setting.Federation.PostHeaders); err != nil {
- return nil, err
- }
-
+// NewRequest function
+func (cf *ClientFactory) WithKeys(ctx context.Context, user *user_model.User, pubID string) (APClient, error) {
priv, err := GetPrivateKey(ctx, user)
if err != nil {
return nil, err
@@ -81,47 +114,49 @@ func NewClient(ctx context.Context, user *user_model.User, pubID string) (c *Cli
return nil, err
}
- c = &Client{
- client: &http.Client{
- Transport: &http.Transport{
- Proxy: proxy.Proxy(),
- },
- Timeout: 5 * time.Second,
- },
- algs: setting.HttpsigAlgs,
- digestAlg: httpsig.DigestAlgorithm(setting.Federation.DigestAlgorithm),
- getHeaders: setting.Federation.GetHeaders,
- postHeaders: setting.Federation.PostHeaders,
+ c := Client{
+ client: cf.client,
+ algs: cf.algs,
+ digestAlg: cf.digestAlg,
+ getHeaders: cf.getHeaders,
+ postHeaders: cf.postHeaders,
priv: privParsed,
pubID: pubID,
}
- return c, err
+ return &c, nil
}
// NewRequest function
-func (c *Client) NewRequest(method string, b []byte, to string) (req *http.Request, err error) {
+func (c *Client) newRequest(method string, b []byte, to string) (req *http.Request, err error) {
buf := bytes.NewBuffer(b)
req, err = http.NewRequest(method, to, buf)
if err != nil {
return nil, err
}
- req.Header.Add("Content-Type", ActivityStreamsContentType)
+ req.Header.Add("Accept", "application/json, "+ActivityStreamsContentType)
req.Header.Add("Date", CurrentTime())
+ req.Header.Add("Host", req.URL.Host)
req.Header.Add("User-Agent", "Gitea/"+setting.AppVer)
- signer, _, err := httpsig.NewSigner(c.algs, c.digestAlg, c.postHeaders, httpsig.Signature, httpsigExpirationTime)
- if err != nil {
- return nil, err
- }
- err = signer.SignRequest(c.priv, c.pubID, req, b)
+ req.Header.Add("Content-Type", ActivityStreamsContentType)
+
return req, err
}
// Post function
func (c *Client) Post(b []byte, to string) (resp *http.Response, err error) {
var req *http.Request
- if req, err = c.NewRequest(http.MethodPost, b, to); err != nil {
+ if req, err = c.newRequest(http.MethodPost, b, to); err != nil {
return nil, err
}
+
+ signer, _, err := httpsig.NewSigner(c.algs, c.digestAlg, c.postHeaders, httpsig.Signature, httpsigExpirationTime)
+ if err != nil {
+ return nil, err
+ }
+ if err := signer.SignRequest(c.priv, c.pubID, req, b); err != nil {
+ return nil, err
+ }
+
resp, err = c.client.Do(req)
return resp, err
}
@@ -129,10 +164,17 @@ func (c *Client) Post(b []byte, to string) (resp *http.Response, err error) {
// Create an http GET request with forgejo/gitea specific headers
func (c *Client) Get(to string) (resp *http.Response, err error) {
var req *http.Request
- emptyBody := []byte{0}
- if req, err = c.NewRequest(http.MethodGet, emptyBody, to); err != nil {
+ if req, err = c.newRequest(http.MethodGet, nil, to); err != nil {
return nil, err
}
+ signer, _, err := httpsig.NewSigner(c.algs, c.digestAlg, c.getHeaders, httpsig.Signature, httpsigExpirationTime)
+ if err != nil {
+ return nil, err
+ }
+ if err := signer.SignRequest(c.priv, c.pubID, req, nil); err != nil {
+ return nil, err
+ }
+
resp, err = c.client.Do(req)
return resp, err
}
@@ -168,3 +210,64 @@ func charLimiter(s string, limit int) string {
}
return s
}
+
+type APClient interface {
+ newRequest(method string, b []byte, to string) (req *http.Request, err error)
+ Post(b []byte, to string) (resp *http.Response, err error)
+ Get(to string) (resp *http.Response, err error)
+ GetBody(uri string) ([]byte, error)
+}
+
+// contextKey is a value for use with context.WithValue.
+type contextKey struct {
+ name string
+}
+
+// clientFactoryContextKey is a context key. It is used with context.Value() to get the current Food for the context
+var (
+ clientFactoryContextKey = &contextKey{"clientFactory"}
+ _ APClientFactory = &ClientFactory{}
+)
+
+// Context represents an activitypub client factory context
+type Context struct {
+ context.Context
+ e APClientFactory
+}
+
+func NewContext(ctx context.Context, e APClientFactory) *Context {
+ return &Context{
+ Context: ctx,
+ e: e,
+ }
+}
+
+// APClientFactory represents an activitypub client factory
+func (ctx *Context) APClientFactory() APClientFactory {
+ return ctx.e
+}
+
+// provides APClientFactory
+type GetAPClient interface {
+ GetClientFactory() APClientFactory
+}
+
+// GetClientFactory will get an APClientFactory from this context or returns the default implementation
+func GetClientFactory(ctx context.Context) (APClientFactory, error) {
+ if e := getClientFactory(ctx); e != nil {
+ return e, nil
+ }
+ return NewClientFactory()
+}
+
+// getClientFactory will get an APClientFactory from this context or return nil
+func getClientFactory(ctx context.Context) APClientFactory {
+ if clientFactory, ok := ctx.(APClientFactory); ok {
+ return clientFactory
+ }
+ clientFactoryInterface := ctx.Value(clientFactoryContextKey)
+ if clientFactoryInterface != nil {
+ return clientFactoryInterface.(GetAPClient).GetClientFactory()
+ }
+ return nil
+}
diff --git a/modules/activitypub/client_test.go b/modules/activitypub/client_test.go
index 7f84634941..e63d4859be 100644
--- a/modules/activitypub/client_test.go
+++ b/modules/activitypub/client_test.go
@@ -9,26 +9,24 @@ import (
"io"
"net/http"
"net/http/httptest"
- "regexp"
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
-
- _ "github.com/mattn/go-sqlite3"
+ "github.com/stretchr/testify/require"
)
func TestCurrentTime(t *testing.T) {
date := CurrentTime()
_, err := time.Parse(http.TimeFormat, date)
- assert.NoError(t, err)
- assert.Equal(t, date[len(date)-3:], "GMT")
+ require.NoError(t, err)
+ assert.Equal(t, "GMT", date[len(date)-3:])
}
/* ToDo: Set Up tests for http get requests
@@ -63,23 +61,28 @@ Set up a user called "me" for all tests
*/
-func TestNewClientReturnsClient(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+func TestClientCtx(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
pubID := "myGpgId"
- c, err := NewClient(db.DefaultContext, user, pubID)
+ cf, err := NewClientFactory()
+ log.Debug("ClientFactory: %v\nError: %v", cf, err)
+ require.NoError(t, err)
+
+ c, err := cf.WithKeys(db.DefaultContext, user, pubID)
log.Debug("Client: %v\nError: %v", c, err)
- assert.NoError(t, err)
+ require.NoError(t, err)
+ _ = NewContext(db.DefaultContext, cf)
}
/* TODO: bring this test to work or delete
func TestActivityPubSignedGet(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1, Name: "me"})
pubID := "myGpgId"
c, err := NewClient(db.DefaultContext, user, pubID)
- assert.NoError(t, err)
+ require.NoError(t, err)
expected := "TestActivityPubSignedGet"
@@ -88,45 +91,47 @@ func TestActivityPubSignedGet(t *testing.T) {
assert.Contains(t, r.Header.Get("Signature"), pubID)
assert.Equal(t, r.Header.Get("Content-Type"), ActivityStreamsContentType)
body, err := io.ReadAll(r.Body)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, string(body))
fmt.Fprint(w, expected)
}))
defer srv.Close()
r, err := c.Get(srv.URL)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer r.Body.Close()
body, err := io.ReadAll(r.Body)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, string(body))
}
*/
func TestActivityPubSignedPost(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
pubID := "https://example.com/pubID"
- c, err := NewClient(db.DefaultContext, user, pubID)
- assert.NoError(t, err)
+ cf, err := NewClientFactory()
+ require.NoError(t, err)
+ c, err := cf.WithKeys(db.DefaultContext, user, pubID)
+ require.NoError(t, err)
expected := "BODY"
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- assert.Regexp(t, regexp.MustCompile("^"+setting.Federation.DigestAlgorithm), r.Header.Get("Digest"))
+ assert.Regexp(t, "^"+setting.Federation.DigestAlgorithm, r.Header.Get("Digest"))
assert.Contains(t, r.Header.Get("Signature"), pubID)
- assert.Equal(t, r.Header.Get("Content-Type"), ActivityStreamsContentType)
+ assert.Equal(t, ActivityStreamsContentType, r.Header.Get("Content-Type"))
body, err := io.ReadAll(r.Body)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, string(body))
fmt.Fprint(w, expected)
}))
defer srv.Close()
r, err := c.Post([]byte(expected), srv.URL)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer r.Body.Close()
body, err := io.ReadAll(r.Body)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, string(body))
}
diff --git a/modules/activitypub/main_test.go b/modules/activitypub/main_test.go
index 4591f1fa55..4895c85d6b 100644
--- a/modules/activitypub/main_test.go
+++ b/modules/activitypub/main_test.go
@@ -6,11 +6,12 @@ package activitypub
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/modules/activitypub/user_settings.go b/modules/activitypub/user_settings.go
index 7f939af352..77c11d5ae3 100644
--- a/modules/activitypub/user_settings.go
+++ b/modules/activitypub/user_settings.go
@@ -6,8 +6,8 @@ package activitypub
import (
"context"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/util"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/util"
)
const rsaBits = 3072
diff --git a/modules/activitypub/user_settings_test.go b/modules/activitypub/user_settings_test.go
index 2d77906521..f1a779855c 100644
--- a/modules/activitypub/user_settings_test.go
+++ b/modules/activitypub/user_settings_test.go
@@ -6,24 +6,25 @@ package activitypub
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
- _ "code.gitea.io/gitea/models" // https://discourse.gitea.io/t/testfixtures-could-not-clean-table-access-no-such-table-access/4137/4
+ _ "forgejo.org/models" // https://forum.gitea.com/t/testfixtures-could-not-clean-table-access-no-such-table-access/4137/4
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestUserSettings(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
pub, priv, err := GetKeyPair(db.DefaultContext, user1)
- assert.NoError(t, err)
+ require.NoError(t, err)
pub1, err := GetPublicKey(db.DefaultContext, user1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, pub, pub1)
priv1, err := GetPrivateKey(db.DefaultContext, user1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, priv, priv1)
}
diff --git a/modules/annex/annex.go b/modules/annex/annex.go
new file mode 100644
index 0000000000..52c6134d72
--- /dev/null
+++ b/modules/annex/annex.go
@@ -0,0 +1,240 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+// Unlike modules/lfs, which operates mainly on git.Blobs, this operates on git.TreeEntrys.
+// The motivation for this is that TreeEntrys have an easy pointer to the on-disk repo path,
+// while blobs do not (in fact, if building with TAGS=gogit, blobs might exist only in a mock
+// filesystem, living only in process RAM). We must have the on-disk path to do anything
+// useful with git-annex because all of its interesting data is on-disk under .git/annex/.
+
+package annex
+
+import (
+ "bytes"
+ "context"
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "path"
+ "path/filepath"
+ "strings"
+ "sync"
+ "time"
+
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/typesniffer"
+
+ "gopkg.in/ini.v1" //nolint:depguard // This import is forbidden in favor of using the setting module, but we need ini parsing for something other than Forgejo settings
+)
+
+// ErrBlobIsNotAnnexed occurs if a blob does not contain a valid annex key
+var ErrBlobIsNotAnnexed = errors.New("not a git-annex pointer")
+
+func PrivateInit(ctx context.Context, repoPath string) error {
+ if _, _, err := git.NewCommand(ctx, "config", "annex.private", "true").RunStdString(&git.RunOpts{Dir: repoPath}); err != nil {
+ return err
+ }
+ if _, _, err := git.NewCommand(ctx, "annex", "init").RunStdString(&git.RunOpts{Dir: repoPath}); err != nil {
+ return err
+ }
+ return nil
+}
+
+func LookupKey(blob *git.Blob) (string, error) {
+ stdout, _, err := git.NewCommand(git.DefaultContext, "annex", "lookupkey", "--ref").AddDynamicArguments(blob.ID.String()).RunStdString(&git.RunOpts{Dir: blob.Repo().Path})
+ if err != nil {
+ return "", ErrBlobIsNotAnnexed
+ }
+ key := strings.TrimSpace(stdout)
+ return key, nil
+}
+
+// LookupKeyBatch runs git annex lookupkey --batch --ref
+func LookupKeyBatch(ctx context.Context, shasToBatchReader *io.PipeReader, lookupKeyBatchWriter *io.PipeWriter, wg *sync.WaitGroup, repoPath string) {
+ defer wg.Done()
+ defer shasToBatchReader.Close()
+ defer lookupKeyBatchWriter.Close()
+
+ stderr := new(bytes.Buffer)
+ var errbuf strings.Builder
+ if err := git.NewCommand(ctx, "annex", "lookupkey", "--batch", "--ref").Run(&git.RunOpts{
+ Dir: repoPath,
+ Stdout: lookupKeyBatchWriter,
+ Stdin: shasToBatchReader,
+ Stderr: stderr,
+ }); err != nil {
+ _ = lookupKeyBatchWriter.CloseWithError(fmt.Errorf("git annex lookupkey --batch --ref [%s]: %w - %s", repoPath, err, errbuf.String()))
+ }
+}
+
+// CopyFromToBatch runs git -c annex.hardlink=true annex copy --batch-keys --from --to
+func CopyFromToBatch(ctx context.Context, from, to string, keysToCopyReader *io.PipeReader, wg *sync.WaitGroup, repoPath string) {
+ defer wg.Done()
+ defer keysToCopyReader.Close()
+
+ stdout := new(bytes.Buffer)
+ stderr := new(bytes.Buffer)
+ var errbuf strings.Builder
+ if err := git.NewCommand(ctx, "-c", "annex.hardlink=true", "annex", "copy", "--batch-keys", "--from").AddDynamicArguments(from).AddArguments("--to").AddDynamicArguments(to).Run(&git.RunOpts{
+ Dir: repoPath,
+ Stdout: stdout,
+ Stdin: keysToCopyReader,
+ Stderr: stderr,
+ }); err != nil {
+ _ = keysToCopyReader.CloseWithError(fmt.Errorf("git annex copy --batch-keys --from --to [%s]: %w - %s", repoPath, err, errbuf.String()))
+ }
+}
+
+func ContentLocationFromKey(repoPath, key string) (string, error) {
+ contentLocation, _, err := git.NewCommandContextNoGlobals(git.DefaultContext, "annex", "contentlocation").AddDynamicArguments(key).RunStdString(&git.RunOpts{Dir: repoPath})
+ if err != nil {
+ return "", fmt.Errorf("in %s: %s does not seem to be a valid annexed file: %w", repoPath, key, err)
+ }
+ contentLocation = strings.TrimSpace(contentLocation)
+ contentLocation = path.Clean("/" + contentLocation)[1:] // prevent directory traversals
+ contentLocation = path.Join(repoPath, contentLocation)
+
+ return contentLocation, nil
+}
+
+// return the absolute path of the content pointed to by the annex pointer stored in the git object
+// errors if the content is not found in this repo
+func ContentLocation(blob *git.Blob) (string, error) {
+ key, err := LookupKey(blob)
+ if err != nil {
+ return "", err
+ }
+ return ContentLocationFromKey(blob.Repo().Path, key)
+}
+
+// returns a stream open to the annex content
+func Content(blob *git.Blob) (*os.File, error) {
+ contentLocation, err := ContentLocation(blob)
+ if err != nil {
+ return nil, err
+ }
+
+ return os.Open(contentLocation)
+}
+
+// whether the object appears to be a valid annex pointer
+// does *not* verify if the content is actually in this repo;
+// for that, use ContentLocation()
+func IsAnnexed(blob *git.Blob) (bool, error) {
+ if !setting.Annex.Enabled {
+ return false, nil
+ }
+
+ // LookupKey is written to only return well-formed keys
+ // so the test is just to see if it errors
+ _, err := LookupKey(blob)
+ if err != nil {
+ if errors.Is(err, ErrBlobIsNotAnnexed) {
+ return false, nil
+ }
+ return false, err
+ }
+ return true, nil
+}
+
+// PathIsAnnexRepo determines if repoPath is a git-annex enabled repository
+func PathIsAnnexRepo(repoPath string) bool {
+ _, _, err := git.NewCommand(git.DefaultContext, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: repoPath})
+ return err == nil
+}
+
+// IsAnnexRepo determines if repo is a git-annex enabled repository
+func IsAnnexRepo(repo *git.Repository) bool {
+ _, _, err := git.NewCommand(repo.Ctx, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: repo.Path})
+ return err == nil
+}
+
+var uuid2repoPathCache = make(map[string]string)
+
+func Init() error {
+ if !setting.Annex.Enabled {
+ return nil
+ }
+ if !setting.Annex.DisableP2PHTTP {
+ log.Info("Populating the git-annex UUID cache with existing repositories")
+ start := time.Now()
+ if err := updateUUID2RepoPathCache(); err != nil {
+ return err
+ }
+ log.Info("Populating the git-annex UUID cache took %v", time.Since(start))
+ }
+ return nil
+}
+
+func updateUUID2RepoPathCache() error {
+ configFiles, err := filepath.Glob(filepath.Join(setting.RepoRootPath, "*", "*", "config"))
+ if err != nil {
+ return err
+ }
+ for _, configFile := range configFiles {
+ repoPath := strings.TrimSuffix(configFile, "/config")
+ config, err := ini.Load(configFile)
+ if err != nil {
+ continue
+ }
+ repoUUID := config.Section("annex").Key("uuid").Value()
+ if repoUUID != "" {
+ uuid2repoPathCache[repoUUID] = repoPath
+ }
+ }
+ return nil
+}
+
+func repoPathFromUUIDCache(uuid string) (string, error) {
+ if repoPath, ok := uuid2repoPathCache[uuid]; ok {
+ return repoPath, nil
+ }
+ // If the cache didn't contain an entry for the UUID then update the cache and try again
+ if err := updateUUID2RepoPathCache(); err != nil {
+ return "", err
+ }
+ if repoPath, ok := uuid2repoPathCache[uuid]; ok {
+ return repoPath, nil
+ }
+ return "", fmt.Errorf("no repository known for UUID '%s'", uuid)
+}
+
+func checkValidity(uuid, repoPath string) (bool, error) {
+ stdout, _, err := git.NewCommand(git.DefaultContext, "config", "annex.uuid").RunStdString(&git.RunOpts{Dir: repoPath})
+ if err != nil {
+ return false, err
+ }
+ repoUUID := strings.TrimSpace(stdout)
+ return uuid == repoUUID, nil
+}
+
+func UUID2RepoPath(uuid string) (string, error) {
+ // Get the current cache entry for the UUID
+ repoPath, err := repoPathFromUUIDCache(uuid)
+ if err != nil {
+ return "", err
+ }
+ // Check if it is still up-to-date
+ valid, _ := checkValidity(uuid, repoPath)
+ if !valid {
+ // If it isn't, remove the cache entry and try again
+ delete(uuid2repoPathCache, uuid)
+ return UUID2RepoPath(uuid)
+ }
+ // Otherwise just return the cached entry
+ return repoPath, nil
+}
+
+// GuessContentType guesses the content type of the annexed blob.
+func GuessContentType(blob *git.Blob) (typesniffer.SniffedType, error) {
+ r, err := Content(blob)
+ if err != nil {
+ return typesniffer.SniffedType{}, err
+ }
+ defer r.Close()
+
+ return typesniffer.DetectContentTypeFromReader(r)
+}
diff --git a/modules/assetfs/layered.go b/modules/assetfs/layered.go
index 9678d23ad6..8d54ae5e4a 100644
--- a/modules/assetfs/layered.go
+++ b/modules/assetfs/layered.go
@@ -11,13 +11,13 @@ import (
"net/http"
"os"
"path/filepath"
- "sort"
+ "slices"
"time"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/util"
"github.com/fsnotify/fsnotify"
)
@@ -143,8 +143,7 @@ func (l *LayeredFS) ListFiles(name string, fileMode ...bool) ([]string, error) {
}
}
}
- files := fileSet.Values()
- sort.Strings(files)
+ files := slices.Sorted(fileSet.Seq())
return files, nil
}
@@ -184,8 +183,7 @@ func listAllFiles(layers []*Layer, name string, fileMode ...bool) ([]string, err
if err := list(name); err != nil {
return nil, err
}
- files := fileSet.Values()
- sort.Strings(files)
+ files := slices.Sorted(fileSet.Seq())
return files, nil
}
diff --git a/modules/assetfs/layered_test.go b/modules/assetfs/layered_test.go
index b82111e745..58876d9be2 100644
--- a/modules/assetfs/layered_test.go
+++ b/modules/assetfs/layered_test.go
@@ -11,6 +11,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestLayered(t *testing.T) {
@@ -19,10 +20,10 @@ func TestLayered(t *testing.T) {
dir2 := filepath.Join(dir, "l2")
mkdir := func(elems ...string) {
- assert.NoError(t, os.MkdirAll(filepath.Join(elems...), 0o755))
+ require.NoError(t, os.MkdirAll(filepath.Join(elems...), 0o755))
}
write := func(content string, elems ...string) {
- assert.NoError(t, os.WriteFile(filepath.Join(elems...), []byte(content), 0o644))
+ require.NoError(t, os.WriteFile(filepath.Join(elems...), []byte(content), 0o644))
}
// d1 & f1: only in "l1"; d2 & f2: only in "l2"
@@ -49,18 +50,18 @@ func TestLayered(t *testing.T) {
assets := Layered(Local("l1", dir1), Local("l2", dir2))
f, err := assets.Open("f1")
- assert.NoError(t, err)
+ require.NoError(t, err)
bs, err := io.ReadAll(f)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, "f1", string(bs))
_ = f.Close()
assertRead := func(expected string, expectedErr error, elems ...string) {
bs, err := assets.ReadFile(elems...)
if err != nil {
- assert.ErrorAs(t, err, &expectedErr)
+ require.ErrorIs(t, err, expectedErr)
} else {
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, string(bs))
}
}
@@ -75,27 +76,27 @@ func TestLayered(t *testing.T) {
assertRead("", fs.ErrNotExist, "no-such")
files, err := assets.ListFiles(".", true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []string{"f1", "f2", "fa"}, files)
files, err = assets.ListFiles(".", false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []string{"d1", "d2", "da"}, files)
files, err = assets.ListFiles(".")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []string{"d1", "d2", "da", "f1", "f2", "fa"}, files)
files, err = assets.ListAllFiles(".", true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []string{"d1/f", "d2/f", "da/f", "f1", "f2", "fa"}, files)
files, err = assets.ListAllFiles(".", false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []string{"d1", "d2", "da", "da/sub1", "da/sub2"}, files)
files, err = assets.ListAllFiles(".")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []string{
"d1", "d1/f",
"d2", "d2/f",
diff --git a/modules/auth/common.go b/modules/auth/common.go
index 77361f6561..0f36fd942f 100644
--- a/modules/auth/common.go
+++ b/modules/auth/common.go
@@ -4,8 +4,8 @@
package auth
import (
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
)
func UnmarshalGroupTeamMapping(raw string) (map[string]map[string][]string, error) {
diff --git a/modules/auth/pam/pam.go b/modules/auth/pam/pam.go
index cca1482b1d..a8b608e6be 100644
--- a/modules/auth/pam/pam.go
+++ b/modules/auth/pam/pam.go
@@ -8,7 +8,7 @@ package pam
import (
"errors"
- "github.com/msteinert/pam"
+ "github.com/msteinert/pam/v2"
)
// Supported is true when built with PAM
@@ -28,6 +28,7 @@ func Auth(serviceName, userName, passwd string) (string, error) {
if err != nil {
return "", err
}
+ defer t.End()
if err = t.Authenticate(0); err != nil {
return "", err
diff --git a/modules/auth/pam/pam_test.go b/modules/auth/pam/pam_test.go
index c277d59c41..e9b844e955 100644
--- a/modules/auth/pam/pam_test.go
+++ b/modules/auth/pam/pam_test.go
@@ -9,11 +9,12 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestPamAuth(t *testing.T) {
result, err := Auth("gitea", "user1", "false-pwd")
- assert.Error(t, err)
+ require.Error(t, err)
assert.EqualError(t, err, "Authentication failure")
assert.Len(t, result, 0)
}
diff --git a/modules/auth/password/hash/argon2.go b/modules/auth/password/hash/argon2.go
index 0cd6472fa1..0f65d60c66 100644
--- a/modules/auth/password/hash/argon2.go
+++ b/modules/auth/password/hash/argon2.go
@@ -7,7 +7,7 @@ import (
"encoding/hex"
"strings"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"golang.org/x/crypto/argon2"
)
diff --git a/modules/auth/password/hash/common.go b/modules/auth/password/hash/common.go
index 487c0738f4..618ebfd15b 100644
--- a/modules/auth/password/hash/common.go
+++ b/modules/auth/password/hash/common.go
@@ -6,7 +6,7 @@ package hash
import (
"strconv"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
)
func parseIntParam(value, param, algorithmName, config string, previousErr error) (int, error) {
diff --git a/modules/auth/password/hash/dummy_test.go b/modules/auth/password/hash/dummy_test.go
index f3b36df625..35d1249999 100644
--- a/modules/auth/password/hash/dummy_test.go
+++ b/modules/auth/password/hash/dummy_test.go
@@ -7,6 +7,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestDummyHasher(t *testing.T) {
@@ -18,7 +19,7 @@ func TestDummyHasher(t *testing.T) {
password, salt := "password", "ZogKvWdyEx"
hash, err := dummy.Hash(password, salt)
- assert.Nil(t, err)
+ require.NoError(t, err)
assert.Equal(t, hash, salt+":"+password)
assert.True(t, dummy.VerifyPassword(password, hash, salt))
diff --git a/modules/auth/password/hash/hash.go b/modules/auth/password/hash/hash.go
index 459320e1b0..eb79db1b9e 100644
--- a/modules/auth/password/hash/hash.go
+++ b/modules/auth/password/hash/hash.go
@@ -10,7 +10,7 @@ import (
"strings"
"sync/atomic"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
)
// This package takes care of hashing passwords, verifying passwords, defining
diff --git a/modules/auth/password/hash/hash_test.go b/modules/auth/password/hash/hash_test.go
index 7aa051733f..03d08a8a36 100644
--- a/modules/auth/password/hash/hash_test.go
+++ b/modules/auth/password/hash/hash_test.go
@@ -10,6 +10,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
type testSaltHasher string
@@ -29,7 +30,7 @@ func Test_registerHasher(t *testing.T) {
})
})
- assert.Error(t, Register("Test_registerHasher", func(config string) testSaltHasher {
+ require.Error(t, Register("Test_registerHasher", func(config string) testSaltHasher {
return testSaltHasher(config)
}))
@@ -76,10 +77,10 @@ func TestHashing(t *testing.T) {
t.Run(algorithmName, func(t *testing.T) {
output, err := Parse(algorithmName).Hash(password, salt)
if shouldPass {
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotEmpty(t, output, "output for %s was empty", algorithmName)
} else {
- assert.Error(t, err)
+ require.Error(t, err)
}
assert.Equal(t, Parse(algorithmName).VerifyPassword(password, output, salt), shouldPass)
diff --git a/modules/auth/password/hash/pbkdf2.go b/modules/auth/password/hash/pbkdf2.go
index 27382fedb8..0dff5e5134 100644
--- a/modules/auth/password/hash/pbkdf2.go
+++ b/modules/auth/password/hash/pbkdf2.go
@@ -8,7 +8,7 @@ import (
"encoding/hex"
"strings"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"golang.org/x/crypto/pbkdf2"
)
diff --git a/modules/auth/password/hash/scrypt.go b/modules/auth/password/hash/scrypt.go
index f3d38f751a..668b69cb9e 100644
--- a/modules/auth/password/hash/scrypt.go
+++ b/modules/auth/password/hash/scrypt.go
@@ -7,7 +7,7 @@ import (
"encoding/hex"
"strings"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"golang.org/x/crypto/scrypt"
)
diff --git a/modules/auth/password/password.go b/modules/auth/password/password.go
index 85f9780709..fdbc4ff291 100644
--- a/modules/auth/password/password.go
+++ b/modules/auth/password/password.go
@@ -13,8 +13,8 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
)
var (
diff --git a/modules/auth/password/password_test.go b/modules/auth/password/password_test.go
index 6c35dc86bd..1fe3fb5ce1 100644
--- a/modules/auth/password/password_test.go
+++ b/modules/auth/password/password_test.go
@@ -7,6 +7,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestComplexity_IsComplexEnough(t *testing.T) {
@@ -52,7 +53,7 @@ func TestComplexity_Generate(t *testing.T) {
testComplextity(modes)
for i := 0; i < maxCount; i++ {
pwd, err := Generate(pwdLen)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, pwd, pwdLen)
assert.True(t, IsComplexEnough(pwd), "Failed complexities with modes %+v for generated: %s", modes, pwd)
}
diff --git a/modules/auth/password/pwn.go b/modules/auth/password/pwn.go
index e00205ea19..239a25f11c 100644
--- a/modules/auth/password/pwn.go
+++ b/modules/auth/password/pwn.go
@@ -8,8 +8,8 @@ import (
"errors"
"fmt"
- "code.gitea.io/gitea/modules/auth/password/pwn"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/auth/password/pwn"
+ "forgejo.org/modules/setting"
)
var ErrIsPwned = errors.New("password has been pwned")
diff --git a/modules/auth/password/pwn/pwn.go b/modules/auth/password/pwn/pwn.go
index f77ce9f40b..10693ec663 100644
--- a/modules/auth/password/pwn/pwn.go
+++ b/modules/auth/password/pwn/pwn.go
@@ -14,7 +14,7 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
const passwordURL = "https://api.pwnedpasswords.com/range/"
diff --git a/modules/auth/password/pwn/pwn_test.go b/modules/auth/password/pwn/pwn_test.go
index b3e7734c3f..bdfc0f6a51 100644
--- a/modules/auth/password/pwn/pwn_test.go
+++ b/modules/auth/password/pwn/pwn_test.go
@@ -4,47 +4,81 @@
package pwn
import (
+ "errors"
+ "io"
"net/http"
+ "strings"
"testing"
"time"
- "github.com/h2non/gock"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
+type mockTransport struct{}
+
+func (mockTransport) RoundTrip(req *http.Request) (*http.Response, error) {
+ if req.URL.Host != "api.pwnedpasswords.com" {
+ return nil, errors.New("unexpected host")
+ }
+
+ res := &http.Response{
+ ProtoMajor: 1,
+ ProtoMinor: 1,
+ Proto: "HTTP/1.1",
+ Request: req,
+ Header: make(http.Header),
+ StatusCode: 200,
+ }
+
+ switch req.URL.Path {
+ case "/range/5c1d8":
+ res.Body = io.NopCloser(strings.NewReader("EAF2F254732680E8AC339B84F3266ECCBB5:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2"))
+ return res, nil
+ case "/range/ba189":
+ res.Body = io.NopCloser(strings.NewReader("FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4"))
+ return res, nil
+ case "/range/a1733":
+ res.Body = io.NopCloser(strings.NewReader("C4CE0F1F0062B27B9E2F41AF0C08218017C:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2\r\nFE81480327C992FE62065A827429DD1318B:0"))
+ return res, nil
+ case "/range/5617b":
+ res.Body = io.NopCloser(strings.NewReader("FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0"))
+ return res, nil
+ case "/range/79082":
+ res.Body = io.NopCloser(strings.NewReader("FDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0\r\nAFEF386F56EB0B4BE314E07696E5E6E6536:0"))
+ return res, nil
+ }
+
+ return nil, errors.New("unexpected path")
+}
+
var client = New(WithHTTP(&http.Client{
- Timeout: time.Second * 2,
+ Timeout: time.Second * 2,
+ Transport: mockTransport{},
}))
func TestPassword(t *testing.T) {
- defer gock.Off()
-
count, err := client.CheckPassword("", false)
- assert.ErrorIs(t, err, ErrEmptyPassword, "blank input should return ErrEmptyPassword")
+ require.ErrorIs(t, err, ErrEmptyPassword, "blank input should return ErrEmptyPassword")
assert.Equal(t, -1, count)
- gock.New("https://api.pwnedpasswords.com").Get("/range/5c1d8").Times(1).Reply(200).BodyString("EAF2F254732680E8AC339B84F3266ECCBB5:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2")
count, err = client.CheckPassword("pwned", false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, 1, count)
- gock.New("https://api.pwnedpasswords.com").Get("/range/ba189").Times(1).Reply(200).BodyString("FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4")
count, err = client.CheckPassword("notpwned", false)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, 0, count)
- gock.New("https://api.pwnedpasswords.com").Get("/range/a1733").Times(1).Reply(200).BodyString("C4CE0F1F0062B27B9E2F41AF0C08218017C:1\r\nFC446EB88938834178CB9322C1EE273C2A7:2\r\nFE81480327C992FE62065A827429DD1318B:0")
count, err = client.CheckPassword("paddedpwned", true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, 1, count)
- gock.New("https://api.pwnedpasswords.com").Get("/range/5617b").Times(1).Reply(200).BodyString("FD4CB34F0378BCB15D23F6FFD28F0775C9E:3\r\nFDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0")
count, err = client.CheckPassword("paddednotpwned", true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, 0, count)
- gock.New("https://api.pwnedpasswords.com").Get("/range/79082").Times(1).Reply(200).BodyString("FDF342FCD8C3611DAE4D76E8A992A3E4169:4\r\nFE81480327C992FE62065A827429DD1318B:0\r\nAFEF386F56EB0B4BE314E07696E5E6E6536:0")
count, err = client.CheckPassword("paddednotpwnedzero", true)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, 0, count)
}
diff --git a/modules/auth/webauthn/webauthn.go b/modules/auth/webauthn/webauthn.go
index 189d197333..a26dc89545 100644
--- a/modules/auth/webauthn/webauthn.go
+++ b/modules/auth/webauthn/webauthn.go
@@ -7,10 +7,10 @@ import (
"encoding/binary"
"encoding/gob"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/webauthn"
diff --git a/modules/auth/webauthn/webauthn_test.go b/modules/auth/webauthn/webauthn_test.go
index 15a8d71828..552b698984 100644
--- a/modules/auth/webauthn/webauthn_test.go
+++ b/modules/auth/webauthn/webauthn_test.go
@@ -6,7 +6,7 @@ package webauthn
import (
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
)
diff --git a/modules/avatar/avatar.go b/modules/avatar/avatar.go
index 106215ec0b..33af60a3b8 100644
--- a/modules/avatar/avatar.go
+++ b/modules/avatar/avatar.go
@@ -14,8 +14,8 @@ import (
_ "image/gif" // for processing gif images
_ "image/jpeg" // for processing jpeg images
- "code.gitea.io/gitea/modules/avatar/identicon"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/avatar/identicon"
+ "forgejo.org/modules/setting"
"golang.org/x/image/draw"
diff --git a/modules/avatar/avatar_test.go b/modules/avatar/avatar_test.go
index a721c77868..2166ca51b0 100644
--- a/modules/avatar/avatar_test.go
+++ b/modules/avatar/avatar_test.go
@@ -10,22 +10,23 @@ import (
"os"
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_RandomImageSize(t *testing.T) {
_, err := RandomImageSize(0, []byte("gitea@local"))
- assert.Error(t, err)
+ require.Error(t, err)
_, err = RandomImageSize(64, []byte("gitea@local"))
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_RandomImage(t *testing.T) {
_, err := RandomImage([]byte("gitea@local"))
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_ProcessAvatarPNG(t *testing.T) {
@@ -33,10 +34,10 @@ func Test_ProcessAvatarPNG(t *testing.T) {
setting.Avatar.MaxHeight = 4096
data, err := os.ReadFile("testdata/avatar.png")
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = processAvatarImage(data, 262144)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_ProcessAvatarJPEG(t *testing.T) {
@@ -44,10 +45,10 @@ func Test_ProcessAvatarJPEG(t *testing.T) {
setting.Avatar.MaxHeight = 4096
data, err := os.ReadFile("testdata/avatar.jpeg")
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = processAvatarImage(data, 262144)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func Test_ProcessAvatarInvalidData(t *testing.T) {
@@ -63,7 +64,7 @@ func Test_ProcessAvatarInvalidImageSize(t *testing.T) {
setting.Avatar.MaxHeight = 5
data, err := os.ReadFile("testdata/avatar.png")
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = processAvatarImage(data, 12800)
assert.EqualError(t, err, "image width is too large: 10 > 5")
@@ -83,54 +84,54 @@ func Test_ProcessAvatarImage(t *testing.T) {
img := image.NewRGBA(image.Rect(0, 0, width, height))
bs := bytes.Buffer{}
err := png.Encode(&bs, img)
- assert.NoError(t, err)
+ require.NoError(t, err)
return bs.Bytes()
}
// if origin image canvas is too large, crop and resize it
origin := newImgData(500, 600)
result, err := processAvatarImage(origin, 0)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotEqual(t, origin, result)
decoded, err := png.Decode(bytes.NewReader(result))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, scaledSize, decoded.Bounds().Max.X)
assert.EqualValues(t, scaledSize, decoded.Bounds().Max.Y)
// if origin image is smaller than the default size, use the origin image
origin = newImgData(1)
result, err = processAvatarImage(origin, 0)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, origin, result)
// use the origin image if the origin is smaller
origin = newImgData(scaledSize + 100)
result, err = processAvatarImage(origin, 0)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Less(t, len(result), len(origin))
// still use the origin image if the origin doesn't exceed the max-origin-size
origin = newImgData(scaledSize + 100)
result, err = processAvatarImage(origin, 262144)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, origin, result)
// allow to use known image format (eg: webp) if it is small enough
origin, err = os.ReadFile("testdata/animated.webp")
- assert.NoError(t, err)
+ require.NoError(t, err)
result, err = processAvatarImage(origin, 262144)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, origin, result)
// do not support unknown image formats, eg: SVG may contain embedded JS
origin = []byte(" ")
_, err = processAvatarImage(origin, 262144)
- assert.ErrorContains(t, err, "image: unknown format")
+ require.ErrorContains(t, err, "image: unknown format")
// make sure the canvas size limit works
setting.Avatar.MaxWidth = 5
setting.Avatar.MaxHeight = 5
origin = newImgData(10)
_, err = processAvatarImage(origin, 262144)
- assert.ErrorContains(t, err, "image width is too large: 10 > 5")
+ require.ErrorContains(t, err, "image width is too large: 10 > 5")
}
diff --git a/modules/avatar/hash_test.go b/modules/avatar/hash_test.go
index 1b8249c696..0a2db53ad4 100644
--- a/modules/avatar/hash_test.go
+++ b/modules/avatar/hash_test.go
@@ -9,7 +9,7 @@ import (
"image/png"
"testing"
- "code.gitea.io/gitea/modules/avatar"
+ "forgejo.org/modules/avatar"
"github.com/stretchr/testify/assert"
)
diff --git a/modules/avatar/identicon/identicon_test.go b/modules/avatar/identicon/identicon_test.go
index 23bcc73e2e..88702b0f38 100644
--- a/modules/avatar/identicon/identicon_test.go
+++ b/modules/avatar/identicon/identicon_test.go
@@ -12,7 +12,7 @@ import (
"strconv"
"testing"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGenerate(t *testing.T) {
@@ -24,17 +24,16 @@ func TestGenerate(t *testing.T) {
backColor := color.White
imgMaker, err := New(64, backColor, DarkColors...)
- assert.NoError(t, err)
+ require.NoError(t, err)
for i := 0; i < 100; i++ {
s := strconv.Itoa(i)
img := imgMaker.Make([]byte(s))
f, err := os.Create(dir + "/" + s + ".png")
- if !assert.NoError(t, err) {
- continue
- }
+ require.NoError(t, err)
+
defer f.Close()
err = png.Encode(f, img)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
}
diff --git a/modules/base/tool.go b/modules/base/tool.go
index c4c0ec2dfc..38201c5919 100644
--- a/modules/base/tool.go
+++ b/modules/base/tool.go
@@ -4,26 +4,21 @@
package base
import (
- "crypto/hmac"
- "crypto/sha1"
"crypto/sha256"
- "crypto/subtle"
"encoding/base64"
"encoding/hex"
"errors"
"fmt"
- "hash"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
- "time"
"unicode/utf8"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/annex"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
"github.com/dustin/go-humanize"
)
@@ -48,73 +43,10 @@ func BasicAuthDecode(encoded string) (string, string, error) {
return "", "", err
}
- auth := strings.SplitN(string(s), ":", 2)
-
- if len(auth) != 2 {
- return "", "", errors.New("invalid basic authentication")
+ if username, password, ok := strings.Cut(string(s), ":"); ok {
+ return username, password, nil
}
-
- return auth[0], auth[1], nil
-}
-
-// VerifyTimeLimitCode verify time limit code
-func VerifyTimeLimitCode(now time.Time, data string, minutes int, code string) bool {
- if len(code) <= 18 {
- return false
- }
-
- startTimeStr := code[:12]
- aliveTimeStr := code[12:18]
- aliveTime, _ := strconv.Atoi(aliveTimeStr) // no need to check err, if anything wrong, the following code check will fail soon
-
- // check code
- retCode := CreateTimeLimitCode(data, aliveTime, startTimeStr, nil)
- if subtle.ConstantTimeCompare([]byte(retCode), []byte(code)) != 1 {
- retCode = CreateTimeLimitCode(data, aliveTime, startTimeStr, sha1.New()) // TODO: this is only for the support of legacy codes, remove this in/after 1.23
- if subtle.ConstantTimeCompare([]byte(retCode), []byte(code)) != 1 {
- return false
- }
- }
-
- // check time is expired or not: startTime <= now && now < startTime + minutes
- startTime, _ := time.ParseInLocation("200601021504", startTimeStr, time.Local)
- return (startTime.Before(now) || startTime.Equal(now)) && now.Before(startTime.Add(time.Minute*time.Duration(minutes)))
-}
-
-// TimeLimitCodeLength default value for time limit code
-const TimeLimitCodeLength = 12 + 6 + 40
-
-// CreateTimeLimitCode create a time-limited code.
-// Format: 12 length date time string + 6 minutes string (not used) + 40 hash string, some other code depends on this fixed length
-// If h is nil, then use the default hmac hash.
-func CreateTimeLimitCode[T time.Time | string](data string, minutes int, startTimeGeneric T, h hash.Hash) string {
- const format = "200601021504"
-
- var start time.Time
- var startTimeAny any = startTimeGeneric
- if t, ok := startTimeAny.(time.Time); ok {
- start = t
- } else {
- var err error
- start, err = time.ParseInLocation(format, startTimeAny.(string), time.Local)
- if err != nil {
- return "" // return an invalid code because the "parse" failed
- }
- }
- startStr := start.Format(format)
- end := start.Add(time.Minute * time.Duration(minutes))
-
- if h == nil {
- h = hmac.New(sha1.New, setting.GetGeneralTokenSigningSecret())
- }
- _, _ = fmt.Fprintf(h, "%s%s%s%s%d", data, hex.EncodeToString(setting.GetGeneralTokenSigningSecret()), startStr, end.Format(format), minutes)
- encoded := hex.EncodeToString(h.Sum(nil))
-
- code := fmt.Sprintf("%s%06d%s", startStr, minutes, encoded)
- if len(code) != TimeLimitCodeLength {
- panic("there is a hard requirement for the length of time-limited code") // it shouldn't happen
- }
- return code
+ return "", "", errors.New("invalid basic authentication")
}
// FileSize calculates the file size and generate user-friendly string.
@@ -170,6 +102,12 @@ func Int64sToStrings(ints []int64) []string {
// EntryIcon returns the octicon class for displaying files/directories
func EntryIcon(entry *git.TreeEntry) string {
+ isAnnexed, _ := annex.IsAnnexed(entry.Blob())
+ if isAnnexed {
+ // Show git-annex files as binary files to differentiate them from non-annexed files
+ // TODO: find a more suitable icon, maybe something related to git-annex
+ return "file-binary"
+ }
switch {
case entry.IsLink():
te, _, err := entry.FollowLink()
diff --git a/modules/base/tool_test.go b/modules/base/tool_test.go
index 62de7229ac..ed1b469161 100644
--- a/modules/base/tool_test.go
+++ b/modules/base/tool_test.go
@@ -4,16 +4,10 @@
package base
import (
- "crypto/sha1"
- "fmt"
- "os"
"testing"
- "time"
-
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestEncodeSha256(t *testing.T) {
@@ -32,66 +26,18 @@ func TestBasicAuthDecode(t *testing.T) {
assert.Equal(t, "illegal base64 data at input byte 0", err.Error())
user, pass, err := BasicAuthDecode("Zm9vOmJhcg==")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "foo", user)
assert.Equal(t, "bar", pass)
_, _, err = BasicAuthDecode("aW52YWxpZA==")
- assert.Error(t, err)
+ require.Error(t, err)
_, _, err = BasicAuthDecode("invalid")
- assert.Error(t, err)
-}
+ require.Error(t, err)
-func TestVerifyTimeLimitCode(t *testing.T) {
- defer test.MockVariableValue(&setting.InstallLock, true)()
- initGeneralSecret := func(secret string) {
- setting.InstallLock = true
- setting.CfgProvider, _ = setting.NewConfigProviderFromData(fmt.Sprintf(`
-[oauth2]
-JWT_SECRET = %s
-`, secret))
- setting.LoadCommonSettings()
- }
-
- initGeneralSecret("KZb_QLUd4fYVyxetjxC4eZkrBgWM2SndOOWDNtgUUko")
- now := time.Now()
-
- t.Run("TestGenericParameter", func(t *testing.T) {
- time2000 := time.Date(2000, 1, 2, 3, 4, 5, 0, time.Local)
- assert.Equal(t, "2000010203040000026fa5221b2731b7cf80b1b506f5e39e38c115fee5", CreateTimeLimitCode("test-sha1", 2, time2000, sha1.New()))
- assert.Equal(t, "2000010203040000026fa5221b2731b7cf80b1b506f5e39e38c115fee5", CreateTimeLimitCode("test-sha1", 2, "200001020304", sha1.New()))
- assert.Equal(t, "2000010203040000024842227a2f87041ff82025199c0187410a9297bf", CreateTimeLimitCode("test-hmac", 2, time2000, nil))
- assert.Equal(t, "2000010203040000024842227a2f87041ff82025199c0187410a9297bf", CreateTimeLimitCode("test-hmac", 2, "200001020304", nil))
- })
-
- t.Run("TestInvalidCode", func(t *testing.T) {
- assert.False(t, VerifyTimeLimitCode(now, "data", 2, ""))
- assert.False(t, VerifyTimeLimitCode(now, "data", 2, "invalid code"))
- })
-
- t.Run("TestCreateAndVerify", func(t *testing.T) {
- code := CreateTimeLimitCode("data", 2, now, nil)
- assert.False(t, VerifyTimeLimitCode(now.Add(-time.Minute), "data", 2, code)) // not started yet
- assert.True(t, VerifyTimeLimitCode(now, "data", 2, code))
- assert.True(t, VerifyTimeLimitCode(now.Add(time.Minute), "data", 2, code))
- assert.False(t, VerifyTimeLimitCode(now.Add(time.Minute), "DATA", 2, code)) // invalid data
- assert.False(t, VerifyTimeLimitCode(now.Add(2*time.Minute), "data", 2, code)) // expired
- })
-
- t.Run("TestDifferentSecret", func(t *testing.T) {
- // use another secret to ensure the code is invalid for different secret
- verifyDataCode := func(c string) bool {
- return VerifyTimeLimitCode(now, "data", 2, c)
- }
- code1 := CreateTimeLimitCode("data", 2, now, sha1.New())
- code2 := CreateTimeLimitCode("data", 2, now, nil)
- assert.True(t, verifyDataCode(code1))
- assert.True(t, verifyDataCode(code2))
- initGeneralSecret("000_QLUd4fYVyxetjxC4eZkrBgWM2SndOOWDNtgUUko")
- assert.False(t, verifyDataCode(code1))
- assert.False(t, verifyDataCode(code2))
- })
+ _, _, err = BasicAuthDecode("YWxpY2U=") // "alice", no colon
+ require.Error(t, err)
}
func TestFileSize(t *testing.T) {
@@ -144,7 +90,7 @@ func TestTruncateString(t *testing.T) {
func TestStringsToInt64s(t *testing.T) {
testSuccess := func(input []string, expected []int64) {
result, err := StringsToInt64s(input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, result)
}
testSuccess(nil, nil)
@@ -153,8 +99,8 @@ func TestStringsToInt64s(t *testing.T) {
testSuccess([]string{"1", "4", "16", "64", "256"}, []int64{1, 4, 16, 64, 256})
ints, err := StringsToInt64s([]string{"-1", "a"})
- assert.Len(t, ints, 0)
- assert.Error(t, err)
+ assert.Empty(t, ints)
+ require.Error(t, err)
}
func TestInt64sToStrings(t *testing.T) {
@@ -168,9 +114,9 @@ func TestInt64sToStrings(t *testing.T) {
// TODO: Test EntryIcon
func TestSetupGiteaRoot(t *testing.T) {
- _ = os.Setenv("GITEA_ROOT", "test")
+ t.Setenv("GITEA_ROOT", "test")
assert.Equal(t, "test", SetupGiteaRoot())
- _ = os.Setenv("GITEA_ROOT", "")
+ t.Setenv("GITEA_ROOT", "")
assert.NotEqual(t, "test", SetupGiteaRoot())
}
diff --git a/modules/cache/cache.go b/modules/cache/cache.go
index 546c54dfe1..9ad4b5cd90 100644
--- a/modules/cache/cache.go
+++ b/modules/cache/cache.go
@@ -8,11 +8,11 @@ import (
"strconv"
"time"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
- mc "gitea.com/go-chi/cache"
+ mc "code.forgejo.org/go-chi/cache"
- _ "gitea.com/go-chi/cache/memcache" // memcache plugin for cache
+ _ "code.forgejo.org/go-chi/cache/memcache" // memcache plugin for cache
)
var conn mc.Cache
diff --git a/modules/cache/cache_redis.go b/modules/cache/cache_redis.go
index 6c358b0a78..489a585b04 100644
--- a/modules/cache/cache_redis.go
+++ b/modules/cache/cache_redis.go
@@ -8,16 +8,15 @@ import (
"strconv"
"time"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/nosql"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/nosql"
- "gitea.com/go-chi/cache"
- "github.com/redis/go-redis/v9"
+ "code.forgejo.org/go-chi/cache"
)
// RedisCacher represents a redis cache adapter implementation.
type RedisCacher struct {
- c redis.UniversalClient
+ c nosql.RedisClient
prefix string
hsetName string
occupyMode bool
diff --git a/modules/cache/cache_test.go b/modules/cache/cache_test.go
index 0e7e7a647c..8e931d5b2c 100644
--- a/modules/cache/cache_test.go
+++ b/modules/cache/cache_test.go
@@ -8,10 +8,10 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func createTestCache() {
@@ -23,7 +23,7 @@ func createTestCache() {
}
func TestNewContext(t *testing.T) {
- assert.NoError(t, Init())
+ require.NoError(t, Init())
setting.CacheService.Cache = setting.Cache{Adapter: "redis", Conn: "some random string"}
con, err := newCache(setting.Cache{
@@ -31,22 +31,10 @@ func TestNewContext(t *testing.T) {
Conn: "false conf",
Interval: 100,
})
- assert.Error(t, err)
+ require.Error(t, err)
assert.Nil(t, con)
}
-func TestTest(t *testing.T) {
- defer test.MockVariableValue(&conn, nil)()
- _, err := Test()
- assert.Error(t, err)
-
- createTestCache()
- elapsed, err := Test()
- assert.NoError(t, err)
- // mem cache should take from 300ns up to 1ms on modern hardware ...
- assert.Less(t, elapsed, SlowCacheThreshold)
-}
-
func TestGetCache(t *testing.T) {
createTestCache()
@@ -59,32 +47,32 @@ func TestGetString(t *testing.T) {
data, err := GetString("key", func() (string, error) {
return "", fmt.Errorf("some error")
})
- assert.Error(t, err)
+ require.Error(t, err)
assert.Equal(t, "", data)
data, err = GetString("key", func() (string, error) {
return "", nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "", data)
data, err = GetString("key", func() (string, error) {
return "some data", nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "", data)
Remove("key")
data, err = GetString("key", func() (string, error) {
return "some data", nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "some data", data)
data, err = GetString("key", func() (string, error) {
return "", fmt.Errorf("some error")
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "some data", data)
Remove("key")
}
@@ -95,32 +83,32 @@ func TestGetInt(t *testing.T) {
data, err := GetInt("key", func() (int, error) {
return 0, fmt.Errorf("some error")
})
- assert.Error(t, err)
+ require.Error(t, err)
assert.Equal(t, 0, data)
data, err = GetInt("key", func() (int, error) {
return 0, nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, 0, data)
data, err = GetInt("key", func() (int, error) {
return 100, nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, 0, data)
Remove("key")
data, err = GetInt("key", func() (int, error) {
return 100, nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, 100, data)
data, err = GetInt("key", func() (int, error) {
return 0, fmt.Errorf("some error")
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, 100, data)
Remove("key")
}
@@ -131,32 +119,32 @@ func TestGetInt64(t *testing.T) {
data, err := GetInt64("key", func() (int64, error) {
return 0, fmt.Errorf("some error")
})
- assert.Error(t, err)
+ require.Error(t, err)
assert.EqualValues(t, 0, data)
data, err = GetInt64("key", func() (int64, error) {
return 0, nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, data)
data, err = GetInt64("key", func() (int64, error) {
return 100, nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0, data)
Remove("key")
data, err = GetInt64("key", func() (int64, error) {
return 100, nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 100, data)
data, err = GetInt64("key", func() (int64, error) {
return 0, fmt.Errorf("some error")
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 100, data)
Remove("key")
}
diff --git a/modules/cache/cache_twoqueue.go b/modules/cache/cache_twoqueue.go
index f9de2563ec..08efe703c6 100644
--- a/modules/cache/cache_twoqueue.go
+++ b/modules/cache/cache_twoqueue.go
@@ -8,9 +8,9 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
- mc "gitea.com/go-chi/cache"
+ mc "code.forgejo.org/go-chi/cache"
lru "github.com/hashicorp/golang-lru/v2"
)
diff --git a/modules/cache/context.go b/modules/cache/context.go
index 62bbf5dcba..457c5c1258 100644
--- a/modules/cache/context.go
+++ b/modules/cache/context.go
@@ -8,7 +8,7 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
)
// cacheContext is a context that can be used to cache data in a request level context
@@ -63,9 +63,9 @@ func (cc *cacheContext) isDiscard() bool {
}
// cacheContextLifetime is the max lifetime of cacheContext.
-// Since cacheContext is used to cache data in a request level context, 10s is enough.
-// If a cacheContext is used more than 10s, it's probably misuse.
-const cacheContextLifetime = 10 * time.Second
+// Since cacheContext is used to cache data in a request level context, 5 minutes is enough.
+// If a cacheContext is used more than 5 minutes, it's probably misuse.
+const cacheContextLifetime = 5 * time.Minute
var timeNow = time.Now
@@ -73,7 +73,9 @@ func (cc *cacheContext) Expired() bool {
return timeNow().Sub(cc.created) > cacheContextLifetime
}
-var cacheContextKey = struct{}{}
+type cacheContextType = struct{ useless struct{} }
+
+var cacheContextKey = cacheContextType{useless: struct{}{}}
/*
Since there are both WithCacheContext and WithNoCacheContext,
@@ -131,7 +133,7 @@ func GetContextData(ctx context.Context, tp, key any) any {
if c.Expired() {
// The warning means that the cache context is misused for long-life task,
// it can be resolved with WithNoCacheContext(ctx).
- log.Warn("cache context is expired, may be misused for long-life tasks: %v", c)
+ log.Warn("cache context is expired, is highly likely to be misused for long-life tasks: %v", c)
return nil
}
return c.Get(tp, key)
@@ -144,7 +146,7 @@ func SetContextData(ctx context.Context, tp, key, value any) {
if c.Expired() {
// The warning means that the cache context is misused for long-life task,
// it can be resolved with WithNoCacheContext(ctx).
- log.Warn("cache context is expired, may be misused for long-life tasks: %v", c)
+ log.Warn("cache context is expired, is highly likely to be misused for long-life tasks: %v", c)
return
}
c.Put(tp, key, value)
@@ -157,7 +159,7 @@ func RemoveContextData(ctx context.Context, tp, key any) {
if c.Expired() {
// The warning means that the cache context is misused for long-life task,
// it can be resolved with WithNoCacheContext(ctx).
- log.Warn("cache context is expired, may be misused for long-life tasks: %v", c)
+ log.Warn("cache context is expired, is highly likely to be misused for long-life tasks: %v", c)
return
}
c.Delete(tp, key)
diff --git a/modules/cache/context_test.go b/modules/cache/context_test.go
index 5315547865..4f0f06f535 100644
--- a/modules/cache/context_test.go
+++ b/modules/cache/context_test.go
@@ -4,15 +4,15 @@
package cache
import (
- "context"
"testing"
"time"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestWithCacheContext(t *testing.T) {
- ctx := WithCacheContext(context.Background())
+ ctx := WithCacheContext(t.Context())
v := GetContextData(ctx, "empty_field", "my_config1")
assert.Nil(t, v)
@@ -34,7 +34,7 @@ func TestWithCacheContext(t *testing.T) {
vInt, err := GetWithContextCache(ctx, field, "my_config1", func() (int, error) {
return 1, nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 1, vInt)
v = GetContextData(ctx, field, "my_config1")
@@ -45,14 +45,14 @@ func TestWithCacheContext(t *testing.T) {
timeNow = now
}()
timeNow = func() time.Time {
- return now().Add(10 * time.Second)
+ return now().Add(5 * time.Minute)
}
v = GetContextData(ctx, field, "my_config1")
assert.Nil(t, v)
}
func TestWithNoCacheContext(t *testing.T) {
- ctx := context.Background()
+ ctx := t.Context()
const field = "system_setting"
diff --git a/modules/card/card.go b/modules/card/card.go
new file mode 100644
index 0000000000..087cd4ec05
--- /dev/null
+++ b/modules/card/card.go
@@ -0,0 +1,343 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package card
+
+import (
+ "bytes"
+ "fmt"
+ "image"
+ "image/color"
+ "io"
+ "math"
+ "net/http"
+ "strings"
+ "sync"
+ "time"
+
+ _ "image/gif" // for processing gif images
+ _ "image/jpeg" // for processing jpeg images
+ _ "image/png" // for processing png images
+
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/proxy"
+ "forgejo.org/modules/setting"
+
+ "github.com/golang/freetype"
+ "github.com/golang/freetype/truetype"
+ "golang.org/x/image/draw"
+ "golang.org/x/image/font"
+ "golang.org/x/image/font/gofont/goregular"
+
+ _ "golang.org/x/image/webp" // for processing webp images
+)
+
+type Card struct {
+ Img *image.RGBA
+ Font *truetype.Font
+ Margin int
+ Width int
+ Height int
+}
+
+var fontCache = sync.OnceValues(func() (*truetype.Font, error) {
+ return truetype.Parse(goregular.TTF)
+})
+
+// DefaultSize returns the default size for a card
+func DefaultSize() (int, int) {
+ return 1200, 600
+}
+
+// NewCard creates a new card with the given dimensions in pixels
+func NewCard(width, height int) (*Card, error) {
+ img := image.NewRGBA(image.Rect(0, 0, width, height))
+ draw.Draw(img, img.Bounds(), image.NewUniform(color.White), image.Point{}, draw.Src)
+
+ font, err := fontCache()
+ if err != nil {
+ return nil, err
+ }
+
+ return &Card{
+ Img: img,
+ Font: font,
+ Margin: 0,
+ Width: width,
+ Height: height,
+ }, nil
+}
+
+// Split splits the card horizontally or vertically by a given percentage; the first card returned has the percentage
+// size, and the second card has the remainder. Both cards draw to a subsection of the same image buffer.
+func (c *Card) Split(vertical bool, percentage int) (*Card, *Card) {
+ bounds := c.Img.Bounds()
+ bounds = image.Rect(bounds.Min.X+c.Margin, bounds.Min.Y+c.Margin, bounds.Max.X-c.Margin, bounds.Max.Y-c.Margin)
+ if vertical {
+ mid := (bounds.Dx() * percentage / 100) + bounds.Min.X
+ subleft := c.Img.SubImage(image.Rect(bounds.Min.X, bounds.Min.Y, mid, bounds.Max.Y)).(*image.RGBA)
+ subright := c.Img.SubImage(image.Rect(mid, bounds.Min.Y, bounds.Max.X, bounds.Max.Y)).(*image.RGBA)
+ return &Card{Img: subleft, Font: c.Font, Width: subleft.Bounds().Dx(), Height: subleft.Bounds().Dy()},
+ &Card{Img: subright, Font: c.Font, Width: subright.Bounds().Dx(), Height: subright.Bounds().Dy()}
+ }
+ mid := (bounds.Dy() * percentage / 100) + bounds.Min.Y
+ subtop := c.Img.SubImage(image.Rect(bounds.Min.X, bounds.Min.Y, bounds.Max.X, mid)).(*image.RGBA)
+ subbottom := c.Img.SubImage(image.Rect(bounds.Min.X, mid, bounds.Max.X, bounds.Max.Y)).(*image.RGBA)
+ return &Card{Img: subtop, Font: c.Font, Width: subtop.Bounds().Dx(), Height: subtop.Bounds().Dy()},
+ &Card{Img: subbottom, Font: c.Font, Width: subbottom.Bounds().Dx(), Height: subbottom.Bounds().Dy()}
+}
+
+// SetMargin sets the margins for the card
+func (c *Card) SetMargin(margin int) {
+ c.Margin = margin
+}
+
+type (
+ VAlign int64
+ HAlign int64
+)
+
+const (
+ Top VAlign = iota
+ Middle
+ Bottom
+)
+
+const (
+ Left HAlign = iota
+ Center
+ Right
+)
+
+// DrawText draws text within the card, respecting margins and alignment
+func (c *Card) DrawText(text string, textColor color.Color, sizePt float64, valign VAlign, halign HAlign) ([]string, error) {
+ ft := freetype.NewContext()
+ ft.SetDPI(72)
+ ft.SetFont(c.Font)
+ ft.SetFontSize(sizePt)
+ ft.SetClip(c.Img.Bounds())
+ ft.SetDst(c.Img)
+ ft.SetSrc(image.NewUniform(textColor))
+
+ face := truetype.NewFace(c.Font, &truetype.Options{Size: sizePt, DPI: 72})
+ fontHeight := ft.PointToFixed(sizePt).Ceil()
+
+ bounds := c.Img.Bounds()
+ bounds = image.Rect(bounds.Min.X+c.Margin, bounds.Min.Y+c.Margin, bounds.Max.X-c.Margin, bounds.Max.Y-c.Margin)
+ boxWidth, boxHeight := bounds.Size().X, bounds.Size().Y
+ // draw.Draw(c.Img, bounds, image.NewUniform(color.Gray{128}), image.Point{}, draw.Src) // Debug draw box
+
+ // Try to apply wrapping to this text; we'll find the most text that will fit into one line, record that line, move
+ // on. We precalculate each line before drawing so that we can support valign="middle" correctly which requires
+ // knowing the total height, which is related to how many lines we'll have.
+ lines := make([]string, 0)
+ textWords := strings.Split(text, " ")
+ currentLine := ""
+ heightTotal := 0
+
+ for {
+ if len(textWords) == 0 {
+ // Ran out of words.
+ if currentLine != "" {
+ heightTotal += fontHeight
+ lines = append(lines, currentLine)
+ }
+ break
+ }
+
+ nextWord := textWords[0]
+ proposedLine := currentLine
+ if proposedLine != "" {
+ proposedLine += " "
+ }
+ proposedLine += nextWord
+
+ proposedLineWidth := font.MeasureString(face, proposedLine)
+ if proposedLineWidth.Ceil() > boxWidth {
+ // no, proposed line is too big; we'll use the last "currentLine"
+ heightTotal += fontHeight
+ if currentLine != "" {
+ lines = append(lines, currentLine)
+ currentLine = ""
+ // leave nextWord in textWords and keep going
+ } else {
+ // just nextWord by itself doesn't fit on a line; well, we can't skip it, but we'll consume it
+ // regardless as a line by itself. It will be clipped by the drawing routine.
+ lines = append(lines, nextWord)
+ textWords = textWords[1:]
+ }
+ } else {
+ // yes, it will fit
+ currentLine = proposedLine
+ textWords = textWords[1:]
+ }
+ }
+
+ textY := 0
+ switch valign {
+ case Top:
+ textY = fontHeight
+ case Bottom:
+ textY = boxHeight - heightTotal + fontHeight
+ case Middle:
+ textY = ((boxHeight - heightTotal) / 2) + fontHeight
+ }
+
+ for _, line := range lines {
+ lineWidth := font.MeasureString(face, line)
+
+ textX := 0
+ switch halign {
+ case Left:
+ textX = 0
+ case Right:
+ textX = boxWidth - lineWidth.Ceil()
+ case Center:
+ textX = (boxWidth - lineWidth.Ceil()) / 2
+ }
+
+ pt := freetype.Pt(bounds.Min.X+textX, bounds.Min.Y+textY)
+ _, err := ft.DrawString(line, pt)
+ if err != nil {
+ return nil, err
+ }
+
+ textY += fontHeight
+ }
+
+ return lines, nil
+}
+
+// DrawImage fills the card with an image, scaled to maintain the original aspect ratio and centered with respect to the non-filled dimension
+func (c *Card) DrawImage(img image.Image) {
+ bounds := c.Img.Bounds()
+ targetRect := image.Rect(bounds.Min.X+c.Margin, bounds.Min.Y+c.Margin, bounds.Max.X-c.Margin, bounds.Max.Y-c.Margin)
+ srcBounds := img.Bounds()
+ srcAspect := float64(srcBounds.Dx()) / float64(srcBounds.Dy())
+ targetAspect := float64(targetRect.Dx()) / float64(targetRect.Dy())
+
+ var scale float64
+ if srcAspect > targetAspect {
+ // Image is wider than target, scale by width
+ scale = float64(targetRect.Dx()) / float64(srcBounds.Dx())
+ } else {
+ // Image is taller or equal, scale by height
+ scale = float64(targetRect.Dy()) / float64(srcBounds.Dy())
+ }
+
+ newWidth := int(math.Round(float64(srcBounds.Dx()) * scale))
+ newHeight := int(math.Round(float64(srcBounds.Dy()) * scale))
+
+ // Center the image within the target rectangle
+ offsetX := (targetRect.Dx() - newWidth) / 2
+ offsetY := (targetRect.Dy() - newHeight) / 2
+
+ scaledRect := image.Rect(targetRect.Min.X+offsetX, targetRect.Min.Y+offsetY, targetRect.Min.X+offsetX+newWidth, targetRect.Min.Y+offsetY+newHeight)
+ draw.CatmullRom.Scale(c.Img, scaledRect, img, srcBounds, draw.Over, nil)
+}
+
+func fallbackImage() image.Image {
+ // can't usage image.Uniform(color.White) because it's infinitely sized causing a panic in the scaler in DrawImage
+ img := image.NewRGBA(image.Rect(0, 0, 1, 1))
+ img.Set(0, 0, color.White)
+ return img
+}
+
+// As defensively as possible, attempt to load an image from a presumed external and untrusted URL
+func (c *Card) fetchExternalImage(url string) (image.Image, bool) {
+ // Use a short timeout; in the event of any failure we'll be logging and returning a placeholder, but we don't want
+ // this rendering process to be slowed down
+ client := &http.Client{
+ Timeout: 1 * time.Second, // 1 second timeout
+ Transport: &http.Transport{
+ Proxy: proxy.Proxy(),
+ },
+ }
+
+ // Go expects a absolute URL, so we must change a relative to an absolute one
+ if !strings.Contains(url, "://") {
+ url = fmt.Sprintf("%s%s", setting.AppURL, strings.TrimPrefix(url, "/"))
+ }
+
+ resp, err := client.Get(url)
+ if err != nil {
+ log.Warn("error when fetching external image from %s: %v", url, err)
+ return nil, false
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ log.Warn("non-OK error code when fetching external image from %s: %s", url, resp.Status)
+ return nil, false
+ }
+
+ contentType := resp.Header.Get("Content-Type")
+ // Support content types are in-sync with the allowed custom avatar file types
+ if contentType != "image/png" && contentType != "image/jpeg" && contentType != "image/gif" && contentType != "image/webp" {
+ log.Warn("fetching external image returned unsupported Content-Type which was ignored: %s", contentType)
+ return nil, false
+ }
+
+ body := io.LimitReader(resp.Body, setting.Avatar.MaxFileSize)
+ bodyBytes, err := io.ReadAll(body)
+ if err != nil {
+ log.Warn("error when fetching external image from %s: %w", url, err)
+ return nil, false
+ }
+ if int64(len(bodyBytes)) == setting.Avatar.MaxFileSize {
+ log.Warn("while fetching external image response size hit MaxFileSize (%d) and was discarded from url %s", setting.Avatar.MaxFileSize, url)
+ return nil, false
+ }
+
+ bodyBuffer := bytes.NewReader(bodyBytes)
+ imgCfg, imgType, err := image.DecodeConfig(bodyBuffer)
+ if err != nil {
+ log.Warn("error when decoding external image from %s: %w", url, err)
+ return nil, false
+ }
+
+ // Verify that we have a match between actual data understood in the image body and the reported Content-Type
+ if (contentType == "image/png" && imgType != "png") ||
+ (contentType == "image/jpeg" && imgType != "jpeg") ||
+ (contentType == "image/gif" && imgType != "gif") ||
+ (contentType == "image/webp" && imgType != "webp") {
+ log.Warn("while fetching external image, mismatched image body (%s) and Content-Type (%s)", imgType, contentType)
+ return nil, false
+ }
+
+ // do not process image which is too large, it would consume too much memory
+ if imgCfg.Width > setting.Avatar.MaxWidth {
+ log.Warn("while fetching external image, width %d exceeds Avatar.MaxWidth %d", imgCfg.Width, setting.Avatar.MaxWidth)
+ return nil, false
+ }
+ if imgCfg.Height > setting.Avatar.MaxHeight {
+ log.Warn("while fetching external image, height %d exceeds Avatar.MaxHeight %d", imgCfg.Height, setting.Avatar.MaxHeight)
+ return nil, false
+ }
+
+ _, err = bodyBuffer.Seek(0, io.SeekStart) // reset for actual decode
+ if err != nil {
+ log.Warn("error w/ bodyBuffer.Seek")
+ return nil, false
+ }
+ img, _, err := image.Decode(bodyBuffer)
+ if err != nil {
+ log.Warn("error when decoding external image from %s: %w", url, err)
+ return nil, false
+ }
+
+ return img, true
+}
+
+func (c *Card) DrawExternalImage(url string) {
+ image, ok := c.fetchExternalImage(url)
+ if !ok {
+ image = fallbackImage()
+ }
+ c.DrawImage(image)
+}
+
+// DrawRect draws a rect with the given color
+func (c *Card) DrawRect(startX, startY, endX, endY int, color color.Color) {
+ draw.Draw(c.Img, image.Rect(startX, startY, endX, endY), &image.Uniform{color}, image.Point{}, draw.Src)
+}
diff --git a/modules/card/card_test.go b/modules/card/card_test.go
new file mode 100644
index 0000000000..ef695b4549
--- /dev/null
+++ b/modules/card/card_test.go
@@ -0,0 +1,244 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package card
+
+import (
+ "bytes"
+ "encoding/base64"
+ "fmt"
+ "image"
+ "image/color"
+ "image/png"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+ "time"
+
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/test"
+
+ "github.com/golang/freetype/truetype"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "golang.org/x/image/font/gofont/goregular"
+)
+
+func TestNewCard(t *testing.T) {
+ width, height := 100, 50
+ card, err := NewCard(width, height)
+ require.NoError(t, err, "No error should occur when creating a new card")
+ assert.NotNil(t, card, "Card should not be nil")
+ assert.Equal(t, width, card.Img.Bounds().Dx(), "Width should match the provided width")
+ assert.Equal(t, height, card.Img.Bounds().Dy(), "Height should match the provided height")
+
+ // Checking default margin
+ assert.Equal(t, 0, card.Margin, "Default margin should be 0")
+
+ // Checking font parsing
+ originalFont, _ := truetype.Parse(goregular.TTF)
+ assert.Equal(t, originalFont, card.Font, "Fonts should be equivalent")
+}
+
+func TestSplit(t *testing.T) {
+ // Note: you normally wouldn't split the same card twice as draw operations would start to overlap each other; but
+ // it's fine for this limited scope test
+ card, _ := NewCard(200, 100)
+
+ // Test vertical split
+ leftCard, rightCard := card.Split(true, 50)
+ assert.Equal(t, 100, leftCard.Img.Bounds().Dx(), "Left card should have half the width of original")
+ assert.Equal(t, 100, leftCard.Img.Bounds().Dy(), "Left card height unchanged by split")
+ assert.Equal(t, 100, rightCard.Img.Bounds().Dx(), "Right card should have half the width of original")
+ assert.Equal(t, 100, rightCard.Img.Bounds().Dy(), "Right card height unchanged by split")
+
+ // Test horizontal split
+ topCard, bottomCard := card.Split(false, 50)
+ assert.Equal(t, 200, topCard.Img.Bounds().Dx(), "Top card width unchanged by split")
+ assert.Equal(t, 50, topCard.Img.Bounds().Dy(), "Top card should have half the height of original")
+ assert.Equal(t, 200, bottomCard.Img.Bounds().Dx(), "Bottom width unchanged by split")
+ assert.Equal(t, 50, bottomCard.Img.Bounds().Dy(), "Bottom card should have half the height of original")
+}
+
+func TestDrawTextSingleLine(t *testing.T) {
+ card, _ := NewCard(300, 100)
+ lines, err := card.DrawText("This is a single line", color.Black, 12, Middle, Center)
+ require.NoError(t, err, "No error should occur when drawing text")
+ assert.Len(t, lines, 1, "Should be exactly one line")
+ assert.Equal(t, "This is a single line", lines[0], "Text should match the input")
+}
+
+func TestDrawTextLongLine(t *testing.T) {
+ card, _ := NewCard(300, 100)
+ text := "This text is definitely too long to fit in three hundred pixels width without wrapping"
+ lines, err := card.DrawText(text, color.Black, 12, Middle, Center)
+ require.NoError(t, err, "No error should occur when drawing text")
+ assert.Len(t, lines, 2, "Text should wrap into multiple lines")
+ assert.Equal(t, "This text is definitely too long to fit in three hundred", lines[0], "Text should match the input")
+ assert.Equal(t, "pixels width without wrapping", lines[1], "Text should match the input")
+}
+
+func TestDrawTextWordTooLong(t *testing.T) {
+ card, _ := NewCard(300, 100)
+ text := "Line 1 Superduperlongwordthatcannotbewrappedbutshouldenduponitsownsingleline Line 3"
+ lines, err := card.DrawText(text, color.Black, 12, Middle, Center)
+ require.NoError(t, err, "No error should occur when drawing text")
+ assert.Len(t, lines, 3, "Text should create two lines despite long word")
+ assert.Equal(t, "Line 1", lines[0], "First line should contain text before the long word")
+ assert.Equal(t, "Superduperlongwordthatcannotbewrappedbutshouldenduponitsownsingleline", lines[1], "Second line couldn't wrap the word so it just overflowed")
+ assert.Equal(t, "Line 3", lines[2], "Third line continued with wrapping")
+}
+
+func TestFetchExternalImageServer(t *testing.T) {
+ blackPng, err := base64.URLEncoding.DecodeString("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVR4AWNgAAAAAgABc3UBGAAAAABJRU5ErkJggg==")
+ if err != nil {
+ t.Error(err)
+ return
+ }
+
+ var tooWideBuf bytes.Buffer
+ imgTooWide := image.NewGray(image.Rect(0, 0, 16001, 10))
+ err = png.Encode(&tooWideBuf, imgTooWide)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ imgTooWidePng := tooWideBuf.Bytes()
+
+ var tooTallBuf bytes.Buffer
+ imgTooTall := image.NewGray(image.Rect(0, 0, 10, 16002))
+ err = png.Encode(&tooTallBuf, imgTooTall)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ imgTooTallPng := tooTallBuf.Bytes()
+
+ server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ switch r.URL.Path {
+ case "/timeout":
+ // Simulate a timeout by taking a long time to respond
+ time.Sleep(8 * time.Second)
+ w.Header().Set("Content-Type", "image/png")
+ w.Write(blackPng)
+ case "/notfound":
+ http.NotFound(w, r)
+ case "/image.png":
+ w.Header().Set("Content-Type", "image/png")
+ w.Write(blackPng)
+ case "/weird-content":
+ w.Header().Set("Content-Type", "text/html")
+ w.Write([]byte(""))
+ case "/giant-response":
+ w.Header().Set("Content-Type", "image/png")
+ w.Write(make([]byte, 10485760))
+ case "/invalid.png":
+ w.Header().Set("Content-Type", "image/png")
+ w.Write(make([]byte, 100))
+ case "/mismatched.jpg":
+ w.Header().Set("Content-Type", "image/jpeg")
+ w.Write(blackPng) // valid png, but wrong content-type
+ case "/too-wide.png":
+ w.Header().Set("Content-Type", "image/png")
+ w.Write(imgTooWidePng)
+ case "/too-tall.png":
+ w.Header().Set("Content-Type", "image/png")
+ w.Write(imgTooTallPng)
+ default:
+ w.WriteHeader(http.StatusInternalServerError)
+ }
+ }))
+ defer server.Close()
+
+ tests := []struct {
+ name string
+ url string
+ expectedSuccess bool
+ expectedLog string
+ }{
+ {
+ name: "timeout error",
+ url: "/timeout",
+ expectedSuccess: false,
+ expectedLog: "error when fetching external image from",
+ },
+ {
+ name: "external fetch success",
+ url: "/image.png",
+ expectedSuccess: true,
+ expectedLog: "",
+ },
+ {
+ name: "404 fallback",
+ url: "/notfound",
+ expectedSuccess: false,
+ expectedLog: "non-OK error code when fetching external image",
+ },
+ {
+ name: "unsupported content type",
+ url: "/weird-content",
+ expectedSuccess: false,
+ expectedLog: "fetching external image returned unsupported Content-Type",
+ },
+ {
+ name: "response too large",
+ url: "/giant-response",
+ expectedSuccess: false,
+ expectedLog: "while fetching external image response size hit MaxFileSize",
+ },
+ {
+ name: "invalid png",
+ url: "/invalid.png",
+ expectedSuccess: false,
+ expectedLog: "error when decoding external image",
+ },
+ {
+ name: "mismatched content type",
+ url: "/mismatched.jpg",
+ expectedSuccess: false,
+ expectedLog: "while fetching external image, mismatched image body",
+ },
+ {
+ name: "too wide",
+ url: "/too-wide.png",
+ expectedSuccess: false,
+ expectedLog: "while fetching external image, width 16001 exceeds Avatar.MaxWidth",
+ },
+ {
+ name: "too tall",
+ url: "/too-tall.png",
+ expectedSuccess: false,
+ expectedLog: "while fetching external image, height 16002 exceeds Avatar.MaxHeight",
+ },
+ }
+
+ for _, testCase := range tests {
+ t.Run(testCase.name, func(t *testing.T) {
+ // stopMark is used as a logging boundary to verify that the expected message (testCase.expectedLog) is
+ // logged during the `fetchExternalImage` operation. This is verified by a combination of checking that the
+ // stopMark message was received, and that the filtered log (logFiltered[0]) was received.
+ stopMark := fmt.Sprintf(">>>>>>>>>>>>>STOP: %s<<<<<<<<<<<<<<<", testCase.name)
+
+ logChecker, cleanup := test.NewLogChecker(log.DEFAULT, log.TRACE)
+ logChecker.Filter(testCase.expectedLog).StopMark(stopMark)
+ defer cleanup()
+
+ card, _ := NewCard(100, 100)
+ img, ok := card.fetchExternalImage(server.URL + testCase.url)
+
+ if testCase.expectedSuccess {
+ assert.True(t, ok, "expected success from fetchExternalImage")
+ assert.NotNil(t, img)
+ } else {
+ assert.False(t, ok, "expected failure from fetchExternalImage")
+ assert.Nil(t, img)
+ }
+
+ log.Info(stopMark)
+
+ logFiltered, logStopped := logChecker.Check(5 * time.Second)
+ assert.True(t, logStopped, "failed to find log stop mark")
+ assert.True(t, logFiltered[0], "failed to find in log: '%s'", testCase.expectedLog)
+ })
+ }
+}
diff --git a/modules/charset/ambiguous.go b/modules/charset/ambiguous.go
index 96e0561e15..a8eacf26a0 100644
--- a/modules/charset/ambiguous.go
+++ b/modules/charset/ambiguous.go
@@ -9,7 +9,7 @@ import (
"strings"
"unicode"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/translation"
)
// AmbiguousTablesForLocale provides the table of ambiguous characters for this locale.
diff --git a/modules/charset/ambiguous/generate.go b/modules/charset/ambiguous/generate.go
index e3fda5be98..bf7c03a16c 100644
--- a/modules/charset/ambiguous/generate.go
+++ b/modules/charset/ambiguous/generate.go
@@ -13,7 +13,7 @@ import (
"text/template"
"unicode"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
"golang.org/x/text/unicode/rangetable"
)
diff --git a/modules/charset/breakwriter.go b/modules/charset/breakwriter.go
deleted file mode 100644
index a87e846466..0000000000
--- a/modules/charset/breakwriter.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package charset
-
-import (
- "bytes"
- "io"
-)
-
-// BreakWriter wraps an io.Writer to always write '\n' as ' '
-type BreakWriter struct {
- io.Writer
-}
-
-// Write writes the provided byte slice transparently replacing '\n' with ' '
-func (b *BreakWriter) Write(bs []byte) (n int, err error) {
- pos := 0
- for pos < len(bs) {
- idx := bytes.IndexByte(bs[pos:], '\n')
- if idx < 0 {
- wn, err := b.Writer.Write(bs[pos:])
- return n + wn, err
- }
-
- if idx > 0 {
- wn, err := b.Writer.Write(bs[pos : pos+idx])
- n += wn
- if err != nil {
- return n, err
- }
- }
-
- if _, err = b.Writer.Write([]byte(" ")); err != nil {
- return n, err
- }
- pos += idx + 1
-
- n++
- }
-
- return n, err
-}
diff --git a/modules/charset/breakwriter_test.go b/modules/charset/breakwriter_test.go
deleted file mode 100644
index 5eeeedc4e2..0000000000
--- a/modules/charset/breakwriter_test.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package charset
-
-import (
- "strings"
- "testing"
-)
-
-func TestBreakWriter_Write(t *testing.T) {
- tests := []struct {
- name string
- kase string
- expect string
- wantErr bool
- }{
- {
- name: "noline",
- kase: "abcdefghijklmnopqrstuvwxyz",
- expect: "abcdefghijklmnopqrstuvwxyz",
- },
- {
- name: "endline",
- kase: "abcdefghijklmnopqrstuvwxyz\n",
- expect: "abcdefghijklmnopqrstuvwxyz ",
- },
- {
- name: "startline",
- kase: "\nabcdefghijklmnopqrstuvwxyz",
- expect: " abcdefghijklmnopqrstuvwxyz",
- },
- {
- name: "onlyline",
- kase: "\n\n\n",
- expect: " ",
- },
- {
- name: "empty",
- kase: "",
- expect: "",
- },
- {
- name: "midline",
- kase: "\nabc\ndefghijkl\nmnopqrstuvwxy\nz",
- expect: " abc defghijkl mnopqrstuvwxy z",
- },
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- buf := &strings.Builder{}
- b := &BreakWriter{
- Writer: buf,
- }
- n, err := b.Write([]byte(tt.kase))
- if (err != nil) != tt.wantErr {
- t.Errorf("BreakWriter.Write() error = %v, wantErr %v", err, tt.wantErr)
- return
- }
- if n != len(tt.kase) {
- t.Errorf("BreakWriter.Write() = %v, want %v", n, len(tt.kase))
- }
- if buf.String() != tt.expect {
- t.Errorf("BreakWriter.Write() wrote %q, want %v", buf.String(), tt.expect)
- }
- })
- }
-}
diff --git a/modules/charset/charset.go b/modules/charset/charset.go
index 1855446a98..cb03deb966 100644
--- a/modules/charset/charset.go
+++ b/modules/charset/charset.go
@@ -10,9 +10,9 @@ import (
"strings"
"unicode/utf8"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"github.com/gogs/chardet"
"golang.org/x/net/html/charset"
@@ -134,7 +134,7 @@ func DetectEncoding(content []byte) (string, error) {
// First we check if the content represents valid utf8 content excepting a truncated character at the end.
// Now we could decode all the runes in turn but this is not necessarily the cheapest thing to do
- // instead we walk backwards from the end to trim off a the incomplete character
+ // instead we walk backwards from the end to trim off the incomplete character
toValidate := content
end := len(toValidate) - 1
diff --git a/modules/charset/charset_test.go b/modules/charset/charset_test.go
index 829844a976..ef0d1565d6 100644
--- a/modules/charset/charset_test.go
+++ b/modules/charset/charset_test.go
@@ -9,9 +9,10 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func resetDefaultCharsetsOrder() {
@@ -40,20 +41,18 @@ func TestMaybeRemoveBOM(t *testing.T) {
func TestToUTF8(t *testing.T) {
resetDefaultCharsetsOrder()
- var res string
- var err error
// Note: golang compiler seems so behave differently depending on the current
// locale, so some conversions might behave differently. For that reason, we don't
// depend on particular conversions but in expected behaviors.
- res, err = ToUTF8([]byte{0x41, 0x42, 0x43}, ConvertOpts{})
- assert.NoError(t, err)
+ res, err := ToUTF8([]byte{0x41, 0x42, 0x43}, ConvertOpts{})
+ require.NoError(t, err)
assert.Equal(t, "ABC", res)
// "รกรฉรญรณรบ"
res, err = ToUTF8([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, ConvertOpts{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, []byte(res))
// "รกรฉรญรณรบ"
@@ -61,14 +60,14 @@ func TestToUTF8(t *testing.T) {
0xef, 0xbb, 0xbf, 0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3,
0xc3, 0xba,
}, ConvertOpts{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}, []byte(res))
res, err = ToUTF8([]byte{
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63,
0xF3, 0x6D, 0x6F, 0x20, 0xF1, 0x6F, 0x73, 0x41, 0x41, 0x41, 0x2e,
}, ConvertOpts{})
- assert.NoError(t, err)
+ require.NoError(t, err)
stringMustStartWith(t, "Hola,", res)
stringMustEndWith(t, "AAA.", res)
@@ -76,7 +75,7 @@ func TestToUTF8(t *testing.T) {
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63,
0xF3, 0x6D, 0x6F, 0x20, 0x07, 0xA4, 0x6F, 0x73, 0x41, 0x41, 0x41, 0x2e,
}, ConvertOpts{})
- assert.NoError(t, err)
+ require.NoError(t, err)
stringMustStartWith(t, "Hola,", res)
stringMustEndWith(t, "AAA.", res)
@@ -84,7 +83,7 @@ func TestToUTF8(t *testing.T) {
0x48, 0x6F, 0x6C, 0x61, 0x2C, 0x20, 0x61, 0x73, 0xED, 0x20, 0x63,
0xF3, 0x6D, 0x6F, 0x20, 0x81, 0xA4, 0x6F, 0x73, 0x41, 0x41, 0x41, 0x2e,
}, ConvertOpts{})
- assert.NoError(t, err)
+ require.NoError(t, err)
stringMustStartWith(t, "Hola,", res)
stringMustEndWith(t, "AAA.", res)
@@ -94,7 +93,7 @@ func TestToUTF8(t *testing.T) {
0x93, 0xFA, 0x91, 0xAE, 0x94, 0xE9, 0x82, 0xBC, 0x82, 0xB5, 0x82,
0xBF, 0x82, 0xE3, 0x81, 0x42,
}, ConvertOpts{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte{
0xE6, 0x97, 0xA5, 0xE5, 0xB1, 0x9E, 0xE7, 0xA7, 0x98, 0xE3,
0x81, 0x9E, 0xE3, 0x81, 0x97, 0xE3, 0x81, 0xA1, 0xE3, 0x82, 0x85, 0xE3, 0x80, 0x82,
@@ -102,7 +101,7 @@ func TestToUTF8(t *testing.T) {
[]byte(res))
res, err = ToUTF8([]byte{0x00, 0x00, 0x00, 0x00}, ConvertOpts{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte{0x00, 0x00, 0x00, 0x00}, []byte(res))
}
@@ -199,7 +198,7 @@ func TestDetectEncoding(t *testing.T) {
resetDefaultCharsetsOrder()
testSuccess := func(b []byte, expected string) {
encoding, err := DetectEncoding(b)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, encoding)
}
// utf-8
@@ -217,7 +216,7 @@ func TestDetectEncoding(t *testing.T) {
// iso-8859-1: dcor
b = []byte{0x44, 0xe9, 0x63, 0x6f, 0x72, 0x0a}
encoding, err := DetectEncoding(b)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Contains(t, encoding, "ISO-8859-1")
old := setting.Repository.AnsiCharset
@@ -230,7 +229,7 @@ func TestDetectEncoding(t *testing.T) {
// invalid bytes
b = []byte{0xfa}
_, err = DetectEncoding(b)
- assert.Error(t, err)
+ require.Error(t, err)
}
func stringMustStartWith(t *testing.T, expected, value string) {
diff --git a/modules/charset/escape.go b/modules/charset/escape.go
index ba0eb73a3a..57b13c1f18 100644
--- a/modules/charset/escape.go
+++ b/modules/charset/escape.go
@@ -13,9 +13,9 @@ import (
"slices"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
)
// RuneNBSP is the codepoint for NBSP
diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go
index 29943eb858..01ebf52a15 100644
--- a/modules/charset/escape_stream.go
+++ b/modules/charset/escape_stream.go
@@ -10,7 +10,7 @@ import (
"unicode"
"unicode/utf8"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/translation"
"golang.org/x/net/html"
)
diff --git a/modules/charset/escape_test.go b/modules/charset/escape_test.go
index 83dda16c53..eec6f102cb 100644
--- a/modules/charset/escape_test.go
+++ b/modules/charset/escape_test.go
@@ -8,11 +8,12 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
+ "forgejo.org/modules/translation"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var testContext = escapeContext("test")
@@ -163,7 +164,7 @@ func TestEscapeControlReader(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
output := &strings.Builder{}
status, err := EscapeControlReader(strings.NewReader(tt.text), output, &translation.MockLocale{}, testContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, tt.status, *status)
assert.Equal(t, tt.result, output.String())
})
diff --git a/modules/container/set.go b/modules/container/set.go
index 15779983fd..70f837bc66 100644
--- a/modules/container/set.go
+++ b/modules/container/set.go
@@ -3,6 +3,11 @@
package container
+import (
+ "iter"
+ "maps"
+)
+
type Set[T comparable] map[T]struct{}
// SetOf creates a set and adds the specified elements to it.
@@ -29,6 +34,15 @@ func (s Set[T]) AddMultiple(values ...T) {
}
}
+func (s Set[T]) IsSubset(subset []T) bool {
+ for _, v := range subset {
+ if !s.Contains(v) {
+ return false
+ }
+ }
+ return true
+}
+
// Contains determines whether a set contains the specified element.
// Returns true if the set contains the specified element; otherwise, false.
func (s Set[T]) Contains(value T) bool {
@@ -54,3 +68,9 @@ func (s Set[T]) Values() []T {
}
return keys
}
+
+// Seq returns a iterator over the elements in the set.
+// It returns a single-use iterator.
+func (s Set[T]) Seq() iter.Seq[T] {
+ return maps.Keys(s)
+}
diff --git a/modules/container/set_test.go b/modules/container/set_test.go
index 1502236034..e54e31a052 100644
--- a/modules/container/set_test.go
+++ b/modules/container/set_test.go
@@ -4,6 +4,7 @@
package container
import (
+ "slices"
"testing"
"github.com/stretchr/testify/assert"
@@ -29,8 +30,21 @@ func TestSet(t *testing.T) {
assert.True(t, s.Contains("key4"))
assert.True(t, s.Contains("key5"))
+ values := s.Values()
+ called := 0
+ for value := range s.Seq() {
+ called++
+ assert.True(t, slices.Contains(values, value))
+ }
+ assert.EqualValues(t, len(values), called)
+
s = SetOf("key6", "key7")
assert.False(t, s.Contains("key1"))
assert.True(t, s.Contains("key6"))
assert.True(t, s.Contains("key7"))
+
+ assert.True(t, s.IsSubset([]string{"key6", "key7"}))
+ assert.False(t, s.IsSubset([]string{"key1"}))
+
+ assert.True(t, s.IsSubset([]string{}))
}
diff --git a/modules/csv/csv.go b/modules/csv/csv.go
index 35c5d6ab67..996a35bdeb 100644
--- a/modules/csv/csv.go
+++ b/modules/csv/csv.go
@@ -11,9 +11,9 @@ import (
"regexp"
"strings"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/util"
)
const (
diff --git a/modules/csv/csv_test.go b/modules/csv/csv_test.go
index f6e782a5a4..6eb3b3056f 100644
--- a/modules/csv/csv_test.go
+++ b/modules/csv/csv_test.go
@@ -11,11 +11,12 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/translation"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCreateReader(t *testing.T) {
@@ -27,7 +28,7 @@ func decodeSlashes(t *testing.T, s string) string {
s = strings.ReplaceAll(s, "\n", "\\n")
s = strings.ReplaceAll(s, "\"", "\\\"")
decoded, err := strconv.Unquote(`"` + s + `"`)
- assert.NoError(t, err, "unable to decode string")
+ require.NoError(t, err, "unable to decode string")
return decoded
}
@@ -99,10 +100,10 @@ j, ,\x20
for n, c := range cases {
rd, err := CreateReaderAndDetermineDelimiter(nil, strings.NewReader(decodeSlashes(t, c.csv)))
- assert.NoError(t, err, "case %d: should not throw error: %v\n", n, err)
+ require.NoError(t, err, "case %d: should not throw error: %v\n", n, err)
assert.EqualValues(t, c.expectedDelimiter, rd.Comma, "case %d: delimiter should be '%c', got '%c'", n, c.expectedDelimiter, rd.Comma)
rows, err := rd.ReadAll()
- assert.NoError(t, err, "case %d: should not throw error: %v\n", n, err)
+ require.NoError(t, err, "case %d: should not throw error: %v\n", n, err)
assert.EqualValues(t, c.expectedRows, rows, "case %d: rows should be equal", n)
}
}
@@ -115,8 +116,8 @@ func (r *mockReader) Read(buf []byte) (int, error) {
func TestDetermineDelimiterShortBufferError(t *testing.T) {
rd, err := CreateReaderAndDetermineDelimiter(nil, &mockReader{})
- assert.Error(t, err, "CreateReaderAndDetermineDelimiter() should throw an error")
- assert.ErrorIs(t, err, io.ErrShortBuffer)
+ require.Error(t, err, "CreateReaderAndDetermineDelimiter() should throw an error")
+ require.ErrorIs(t, err, io.ErrShortBuffer)
assert.Nil(t, rd, "CSV reader should be mnil")
}
@@ -127,11 +128,11 @@ func TestDetermineDelimiterReadAllError(t *testing.T) {
f g
h|i
jkl`))
- assert.NoError(t, err, "CreateReaderAndDetermineDelimiter() shouldn't throw error")
+ require.NoError(t, err, "CreateReaderAndDetermineDelimiter() shouldn't throw error")
assert.NotNil(t, rd, "CSV reader should not be mnil")
rows, err := rd.ReadAll()
- assert.Error(t, err, "RaadAll() should throw error")
- assert.ErrorIs(t, err, csv.ErrFieldCount)
+ require.Error(t, err, "RaadAll() should throw error")
+ require.ErrorIs(t, err, csv.ErrFieldCount)
assert.Empty(t, rows, "rows should be empty")
}
@@ -580,9 +581,9 @@ func TestFormatError(t *testing.T) {
for n, c := range cases {
message, err := FormatError(c.err, &translation.MockLocale{})
if c.expectsError {
- assert.Error(t, err, "case %d: expected an error to be returned", n)
+ require.Error(t, err, "case %d: expected an error to be returned", n)
} else {
- assert.NoError(t, err, "case %d: no error was expected, got error: %v", n, err)
+ require.NoError(t, err, "case %d: no error was expected, got error: %v", n, err)
assert.EqualValues(t, c.expectedMessage, message, "case %d: messages should be equal, expected '%s' got '%s'", n, c.expectedMessage, message)
}
}
diff --git a/modules/eventsource/event.go b/modules/eventsource/event.go
index ebcca50903..0e4dbf6e9c 100644
--- a/modules/eventsource/event.go
+++ b/modules/eventsource/event.go
@@ -10,7 +10,7 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
)
func wrapNewlines(w io.Writer, prefix, value []byte) (sum int64, err error) {
diff --git a/modules/eventsource/manager.go b/modules/eventsource/manager.go
index 7ed2a82903..730cacd940 100644
--- a/modules/eventsource/manager.go
+++ b/modules/eventsource/manager.go
@@ -77,13 +77,3 @@ func (m *Manager) SendMessage(uid int64, message *Event) {
messenger.SendMessage(message)
}
}
-
-// SendMessageBlocking sends a message to a particular user
-func (m *Manager) SendMessageBlocking(uid int64, message *Event) {
- m.mutex.Lock()
- messenger, ok := m.messengers[uid]
- m.mutex.Unlock()
- if ok {
- messenger.SendMessageBlocking(message)
- }
-}
diff --git a/modules/eventsource/manager_run.go b/modules/eventsource/manager_run.go
index f66dc78c7e..0eaee5dc3c 100644
--- a/modules/eventsource/manager_run.go
+++ b/modules/eventsource/manager_run.go
@@ -7,15 +7,15 @@ import (
"context"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/services/convert"
+ activities_model "forgejo.org/models/activities"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/services/convert"
)
// Init starts this eventsource
@@ -90,8 +90,8 @@ loop:
return
}
- for _, userStopwatches := range usersStopwatches {
- apiSWs, err := convert.ToStopWatches(ctx, userStopwatches.StopWatches)
+ for uid, stopwatches := range usersStopwatches {
+ apiSWs, err := convert.ToStopWatches(ctx, stopwatches)
if err != nil {
if !issues_model.IsErrIssueNotExist(err) {
log.Error("Unable to APIFormat stopwatches: %v", err)
@@ -103,7 +103,7 @@ loop:
log.Error("Unable to marshal stopwatches: %v", err)
continue
}
- m.SendMessage(userStopwatches.UserID, &Event{
+ m.SendMessage(uid, &Event{
Name: "stopwatches",
Data: string(dataBs),
})
diff --git a/modules/eventsource/messenger.go b/modules/eventsource/messenger.go
index 6df26716be..378e717126 100644
--- a/modules/eventsource/messenger.go
+++ b/modules/eventsource/messenger.go
@@ -66,12 +66,3 @@ func (m *Messenger) SendMessage(message *Event) {
}
}
}
-
-// SendMessageBlocking sends the message to all registered channels and ensures it gets sent
-func (m *Messenger) SendMessageBlocking(message *Event) {
- m.mutex.Lock()
- defer m.mutex.Unlock()
- for i := range m.channels {
- m.channels[i] <- message
- }
-}
diff --git a/modules/forgefed/activity.go b/modules/forgefed/activity_like.go
similarity index 91%
rename from modules/forgefed/activity.go
rename to modules/forgefed/activity_like.go
index c1ca57c4a8..e52d0a9af6 100644
--- a/modules/forgefed/activity.go
+++ b/modules/forgefed/activity_like.go
@@ -6,7 +6,7 @@ package forgefed
import (
"time"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
ap "github.com/go-ap/activitypub"
)
@@ -21,8 +21,8 @@ type ForgeLike struct {
func NewForgeLike(actorIRI, objectIRI string, startTime time.Time) (ForgeLike, error) {
result := ForgeLike{}
result.Type = ap.LikeType
- result.Actor = ap.IRI(actorIRI) // Thats us, a User
- result.Object = ap.IRI(objectIRI) // Thats them, a Repository
+ result.Actor = ap.IRI(actorIRI)
+ result.Object = ap.IRI(objectIRI)
result.StartTime = startTime
if valid, err := validation.IsValid(result); !valid {
return ForgeLike{}, err
@@ -46,20 +46,23 @@ func (like ForgeLike) Validate() []string {
var result []string
result = append(result, validation.ValidateNotEmpty(string(like.Type), "type")...)
result = append(result, validation.ValidateOneOf(string(like.Type), []any{"Like"}, "type")...)
+
if like.Actor == nil {
result = append(result, "Actor should not be nil.")
} else {
result = append(result, validation.ValidateNotEmpty(like.Actor.GetID().String(), "actor")...)
}
- if like.Object == nil {
- result = append(result, "Object should not be nil.")
- } else {
- result = append(result, validation.ValidateNotEmpty(like.Object.GetID().String(), "object")...)
- }
+
result = append(result, validation.ValidateNotEmpty(like.StartTime.String(), "startTime")...)
if like.StartTime.IsZero() {
result = append(result, "StartTime was invalid.")
}
+ if like.Object == nil {
+ result = append(result, "Object should not be nil.")
+ } else {
+ result = append(result, validation.ValidateNotEmpty(like.Object.GetID().String(), "object")...)
+ }
+
return result
}
diff --git a/modules/forgefed/activity_test.go b/modules/forgefed/activity_like_test.go
similarity index 79%
rename from modules/forgefed/activity_test.go
rename to modules/forgefed/activity_like_test.go
index 9a7979c4e6..815b0e02f3 100644
--- a/modules/forgefed/activity_test.go
+++ b/modules/forgefed/activity_like_test.go
@@ -10,17 +10,17 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
ap "github.com/go-ap/activitypub"
)
func Test_NewForgeLike(t *testing.T) {
+ want := []byte(`{"type":"Like","startTime":"2024-03-07T00:00:00Z","actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1","object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}`)
+
actorIRI := "https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"
objectIRI := "https://codeberg.org/api/v1/activitypub/repository-id/1"
- want := []byte(`{"type":"Like","startTime":"2024-03-27T00:00:00Z","actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1","object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}`)
-
- startTime, _ := time.Parse("2006-Jan-02", "2024-Mar-27")
+ startTime, _ := time.Parse("2006-Jan-02", "2024-Mar-07")
sut, err := NewForgeLike(actorIRI, objectIRI, startTime)
if err != nil {
t.Errorf("unexpected error: %v\n", err)
@@ -84,7 +84,6 @@ func Test_LikeUnmarshalJSON(t *testing.T) {
wantErr error
}
- //revive:disable
tests := map[string]testPair{
"with ID": {
item: []byte(`{"type":"Like","actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1","object":"https://codeberg.org/api/activitypub/repository-id/1"}`),
@@ -100,10 +99,9 @@ func Test_LikeUnmarshalJSON(t *testing.T) {
"invalid": {
item: []byte(`{"type":"Invalid","actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1","object":"https://codeberg.org/api/activitypub/repository-id/1"`),
want: &ForgeLike{},
- wantErr: fmt.Errorf("cannot parse JSON:"),
+ wantErr: fmt.Errorf("cannot parse JSON"),
},
}
- //revive:enable
for name, test := range tests {
t.Run(name, func(t *testing.T) {
@@ -120,7 +118,9 @@ func Test_LikeUnmarshalJSON(t *testing.T) {
}
}
-func TestActivityValidation(t *testing.T) {
+func Test_ForgeLikeValidation(t *testing.T) {
+ // Successful
+
sut := new(ForgeLike)
sut.UnmarshalJSON([]byte(`{"type":"Like",
"actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1",
@@ -130,35 +130,37 @@ func TestActivityValidation(t *testing.T) {
t.Errorf("sut expected to be valid: %v\n", sut.Validate())
}
+ // Errors
+
sut.UnmarshalJSON([]byte(`{"actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1",
"object":"https://codeberg.org/api/activitypub/repository-id/1",
"startTime": "2014-12-31T23:00:00-08:00"}`))
- if sut.Validate()[0] != "type should not be empty" {
- t.Errorf("validation error expected but was: %v\n", sut.Validate()[0])
+ if err := validateAndCheckError(sut, "type should not be empty"); err != nil {
+ t.Error(err)
}
sut.UnmarshalJSON([]byte(`{"type":"bad-type",
"actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1",
"object":"https://codeberg.org/api/activitypub/repository-id/1",
"startTime": "2014-12-31T23:00:00-08:00"}`))
- if sut.Validate()[0] != "Value bad-type is not contained in allowed values [Like]" {
- t.Errorf("validation error expected but was: %v\n", sut.Validate()[0])
+ if err := validateAndCheckError(sut, "Value bad-type is not contained in allowed values [Like]"); err != nil {
+ t.Error(err)
}
sut.UnmarshalJSON([]byte(`{"type":"Like",
"actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1",
- "object":"https://codeberg.org/api/activitypub/repository-id/1",
- "startTime": "not a date"}`))
- if sut.Validate()[0] != "StartTime was invalid." {
- t.Errorf("validation error expected but was: %v\n", sut.Validate())
+ "object":"https://codeberg.org/api/activitypub/repository-id/1",
+ "startTime": "not a date"}`))
+ if err := validateAndCheckError(sut, "StartTime was invalid."); err != nil {
+ t.Error(err)
}
sut.UnmarshalJSON([]byte(`{"type":"Wrong",
"actor":"https://repo.prod.meissa.de/api/activitypub/user-id/1",
- "object":"https://codeberg.org/api/activitypub/repository-id/1",
- "startTime": "2014-12-31T23:00:00-08:00"}`))
- if sut.Validate()[0] != "Value Wrong is not contained in allowed values [Like]" {
- t.Errorf("validation error expected but was: %v\n", sut.Validate())
+ "object":"https://codeberg.org/api/activitypub/repository-id/1",
+ "startTime": "2014-12-31T23:00:00-08:00"}`))
+ if err := validateAndCheckError(sut, "Value Wrong is not contained in allowed values [Like]"); err != nil {
+ t.Error(err)
}
}
@@ -166,6 +168,6 @@ func TestActivityValidation_Attack(t *testing.T) {
sut := new(ForgeLike)
sut.UnmarshalJSON([]byte(`{rubbish}`))
if len(sut.Validate()) != 5 {
- t.Errorf("5 validateion errors expected but was: %v\n", len(sut.Validate()))
+ t.Errorf("5 validation errors expected but was: %v\n", len(sut.Validate()))
}
}
diff --git a/modules/forgefed/activity_undo_like.go b/modules/forgefed/activity_undo_like.go
new file mode 100644
index 0000000000..8b7df582ad
--- /dev/null
+++ b/modules/forgefed/activity_undo_like.go
@@ -0,0 +1,80 @@
+// Copyright 2023, 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgefed
+
+import (
+ "time"
+
+ "forgejo.org/modules/validation"
+
+ ap "github.com/go-ap/activitypub"
+)
+
+// ForgeLike activity data type
+// swagger:model
+type ForgeUndoLike struct {
+ // swagger:ignore
+ ap.Activity
+}
+
+func NewForgeUndoLike(actorIRI, objectIRI string, startTime time.Time) (ForgeUndoLike, error) {
+ result := ForgeUndoLike{}
+ result.Type = ap.UndoType
+ result.Actor = ap.IRI(actorIRI)
+ result.StartTime = startTime
+
+ like := ap.Activity{}
+ like.Type = ap.LikeType
+ like.Actor = ap.IRI(actorIRI)
+ like.Object = ap.IRI(objectIRI)
+ result.Object = &like
+
+ if valid, err := validation.IsValid(result); !valid {
+ return ForgeUndoLike{}, err
+ }
+ return result, nil
+}
+
+func (undo *ForgeUndoLike) UnmarshalJSON(data []byte) error {
+ return undo.Activity.UnmarshalJSON(data)
+}
+
+func (undo ForgeUndoLike) Validate() []string {
+ var result []string
+ result = append(result, validation.ValidateNotEmpty(string(undo.Type), "type")...)
+ result = append(result, validation.ValidateOneOf(string(undo.Type), []any{"Undo"}, "type")...)
+
+ if undo.Actor == nil {
+ result = append(result, "Actor should not be nil.")
+ } else {
+ result = append(result, validation.ValidateNotEmpty(undo.Actor.GetID().String(), "actor")...)
+ }
+
+ result = append(result, validation.ValidateNotEmpty(undo.StartTime.String(), "startTime")...)
+ if undo.StartTime.IsZero() {
+ result = append(result, "StartTime was invalid.")
+ }
+
+ if undo.Object == nil {
+ result = append(result, "object should not be empty.")
+ } else if activity, ok := undo.Object.(*ap.Activity); !ok {
+ result = append(result, "object is not of type Activity")
+ } else {
+ result = append(result, validation.ValidateNotEmpty(string(activity.Type), "type")...)
+ result = append(result, validation.ValidateOneOf(string(activity.Type), []any{"Like"}, "type")...)
+
+ if activity.Actor == nil {
+ result = append(result, "Object.Actor should not be nil.")
+ } else {
+ result = append(result, validation.ValidateNotEmpty(activity.Actor.GetID().String(), "actor")...)
+ }
+
+ if activity.Object == nil {
+ result = append(result, "Object.Object should not be nil.")
+ } else {
+ result = append(result, validation.ValidateNotEmpty(activity.Object.GetID().String(), "object")...)
+ }
+ }
+ return result
+}
diff --git a/modules/forgefed/activity_undo_like_test.go b/modules/forgefed/activity_undo_like_test.go
new file mode 100644
index 0000000000..1b77369b67
--- /dev/null
+++ b/modules/forgefed/activity_undo_like_test.go
@@ -0,0 +1,246 @@
+// Copyright 2023, 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgefed
+
+import (
+ "fmt"
+ "reflect"
+ "strings"
+ "testing"
+ "time"
+
+ "forgejo.org/modules/validation"
+
+ ap "github.com/go-ap/activitypub"
+)
+
+func Test_NewForgeUndoLike(t *testing.T) {
+ actorIRI := "https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"
+ objectIRI := "https://codeberg.org/api/v1/activitypub/repository-id/1"
+ want := []byte(`{"type":"Undo","startTime":"2024-03-27T00:00:00Z",` +
+ `"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
+ `"object":{` +
+ `"type":"Like",` +
+ `"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
+ `"object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`)
+
+ startTime, _ := time.Parse("2006-Jan-02", "2024-Mar-27")
+ sut, err := NewForgeUndoLike(actorIRI, objectIRI, startTime)
+ if err != nil {
+ t.Errorf("unexpected error: %v\n", err)
+ }
+ if valid, _ := validation.IsValid(sut); !valid {
+ t.Errorf("sut expected to be valid: %v\n", sut.Validate())
+ }
+
+ got, err := sut.MarshalJSON()
+ if err != nil {
+ t.Errorf("MarshalJSON() error = \"%v\"", err)
+ return
+ }
+ if !reflect.DeepEqual(got, want) {
+ t.Errorf("MarshalJSON() got = %q, want %q", got, want)
+ }
+}
+
+func Test_UndoLikeMarshalJSON(t *testing.T) {
+ type testPair struct {
+ item ForgeUndoLike
+ want []byte
+ wantErr error
+ }
+
+ startTime, _ := time.Parse("2006-Jan-02", "2024-Mar-27")
+ like, _ := NewForgeLike("https://repo.prod.meissa.de/api/v1/activitypub/user-id/1", "https://codeberg.org/api/v1/activitypub/repository-id/1", startTime)
+ tests := map[string]testPair{
+ "empty": {
+ item: ForgeUndoLike{},
+ want: nil,
+ },
+ "valid": {
+ item: ForgeUndoLike{
+ Activity: ap.Activity{
+ StartTime: startTime,
+ Actor: ap.IRI("https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"),
+ Type: "Undo",
+ Object: like,
+ },
+ },
+ want: []byte(`{"type":"Undo",` +
+ `"startTime":"2024-03-27T00:00:00Z",` +
+ `"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
+ `"object":{` +
+ `"type":"Like",` +
+ `"startTime":"2024-03-27T00:00:00Z",` +
+ `"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
+ `"object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`),
+ },
+ }
+
+ for name, tt := range tests {
+ t.Run(name, func(t *testing.T) {
+ got, err := tt.item.MarshalJSON()
+ if (err != nil || tt.wantErr != nil) && tt.wantErr.Error() != err.Error() {
+ t.Errorf("MarshalJSON() error = \"%v\", wantErr \"%v\"", err, tt.wantErr)
+ return
+ }
+ if !reflect.DeepEqual(got, tt.want) {
+ t.Errorf("MarshalJSON() got = %q\nwant %q", got, tt.want)
+ }
+ })
+ }
+}
+
+func Test_UndoLikeUnmarshalJSON(t *testing.T) {
+ type testPair struct {
+ item []byte
+ want *ForgeUndoLike
+ wantErr error
+ }
+
+ startTime, _ := time.Parse("2006-Jan-02", "2024-Mar-27")
+ like, _ := NewForgeLike("https://repo.prod.meissa.de/api/v1/activitypub/user-id/1", "https://codeberg.org/api/v1/activitypub/repository-id/1", startTime)
+
+ tests := map[string]testPair{
+ "valid": {
+ item: []byte(`{"type":"Undo",` +
+ `"startTime":"2024-03-27T00:00:00Z",` +
+ `"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
+ `"object":{` +
+ `"type":"Like",` +
+ `"startTime":"2024-03-27T00:00:00Z",` +
+ `"actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",` +
+ `"object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`),
+ want: &ForgeUndoLike{
+ Activity: ap.Activity{
+ StartTime: startTime,
+ Actor: ap.IRI("https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"),
+ Type: "Undo",
+ Object: like,
+ },
+ },
+ wantErr: nil,
+ },
+ "invalid": {
+ item: []byte(`invalid JSON`),
+ want: nil,
+ wantErr: fmt.Errorf("cannot parse JSON"),
+ },
+ }
+
+ for name, test := range tests {
+ t.Run(name, func(t *testing.T) {
+ got := new(ForgeUndoLike)
+ err := got.UnmarshalJSON(test.item)
+ if test.wantErr != nil {
+ if err == nil {
+ t.Errorf("UnmarshalJSON() error = nil, wantErr \"%v\"", test.wantErr)
+ } else if !strings.Contains(err.Error(), test.wantErr.Error()) {
+ t.Errorf("UnmarshalJSON() error = \"%v\", wantErr \"%v\"", err, test.wantErr)
+ }
+ return
+ }
+ remarshalledgot, _ := got.MarshalJSON()
+ remarshalledwant, _ := test.want.MarshalJSON()
+ if !reflect.DeepEqual(remarshalledgot, remarshalledwant) {
+ t.Errorf("UnmarshalJSON() got = %#v\nwant %#v", got, test.want)
+ }
+ })
+ }
+}
+
+func TestActivityValidationUndo(t *testing.T) {
+ sut := new(ForgeUndoLike)
+
+ _ = sut.UnmarshalJSON([]byte(`
+ {"type":"Undo",
+ "startTime":"2024-03-27T00:00:00Z",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":{
+ "type":"Like",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
+ if res, _ := validation.IsValid(sut); !res {
+ t.Errorf("sut expected to be valid: %v\n", sut.Validate())
+ }
+
+ _ = sut.UnmarshalJSON([]byte(`
+ {"startTime":"2024-03-27T00:00:00Z",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":{
+ "type":"Like",
+ "startTime":"2024-03-27T00:00:00Z",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
+ if err := validateAndCheckError(sut, "type should not be empty"); err != nil {
+ t.Error(*err)
+ }
+
+ _ = sut.UnmarshalJSON([]byte(`
+ {"type":"Undo",
+ "startTime":"2024-03-27T00:00:00Z",
+ "object":{
+ "type":"Like",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
+ if err := validateAndCheckError(sut, "Actor should not be nil."); err != nil {
+ t.Error(*err)
+ }
+
+ _ = sut.UnmarshalJSON([]byte(`
+ {"type":"Undo",
+ "startTime":"2024-03-27T00:00:00Z",
+ "actor":"string",
+ "object":{
+ "type":"Like",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
+ if err := validateAndCheckError(sut, "Actor should not be nil."); err != nil {
+ t.Error(*err)
+ }
+
+ _ = sut.UnmarshalJSON([]byte(`
+ {"type":"Undo",
+ "startTime":"2024-03-27T00:00:00Z",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"
+ }`))
+ if err := validateAndCheckError(sut, "object should not be empty."); err != nil {
+ t.Error(*err)
+ }
+
+ _ = sut.UnmarshalJSON([]byte(`
+ {"type":"Undo",
+ "startTime":"2024-03-27T00:00:00Z",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":{
+ "startTime":"2024-03-27T00:00:00Z",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":"https://codeberg.org/api/v1/activitypub/repository-id/1"}}`))
+ if err := validateAndCheckError(sut, "object is not of type Activity"); err != nil {
+ t.Error(*err)
+ }
+
+ _ = sut.UnmarshalJSON([]byte(`
+ {"type":"Undo",
+ "startTime":"2024-03-27T00:00:00Z",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":{
+ "type":"Like",
+ "object":""}}`))
+ if err := validateAndCheckError(sut, "Object.Actor should not be nil."); err != nil {
+ t.Error(*err)
+ }
+
+ _ = sut.UnmarshalJSON([]byte(`
+ {"type":"Undo",
+ "startTime":"2024-03-27T00:00:00Z",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1",
+ "object":{
+ "type":"Like",
+ "startTime":"2024-03-27T00:00:00Z",
+ "actor":"https://repo.prod.meissa.de/api/v1/activitypub/user-id/1"}}`))
+ if err := validateAndCheckError(sut, "Object.Object should not be nil."); err != nil {
+ t.Error(*err)
+ }
+}
diff --git a/modules/forgefed/activity_validateandcheckerror_test.go b/modules/forgefed/activity_validateandcheckerror_test.go
new file mode 100644
index 0000000000..c1c9164fd2
--- /dev/null
+++ b/modules/forgefed/activity_validateandcheckerror_test.go
@@ -0,0 +1,23 @@
+// Copyright 2023, 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package forgefed
+
+import (
+ "fmt"
+
+ "forgejo.org/modules/validation"
+)
+
+func validateAndCheckError(subject validation.Validateable, expectedError string) *string {
+ errors := subject.Validate()
+ err := errors[0]
+ if len(errors) < 1 {
+ val := "Validation error should have been returned, but was not."
+ return &val
+ } else if err != expectedError {
+ val := fmt.Sprintf("Validation error should be [%v] but was: %v\n", expectedError, err)
+ return &val
+ }
+ return nil
+}
diff --git a/modules/forgefed/actor.go b/modules/forgefed/actor.go
index 0ef46185d1..c01175f0f6 100644
--- a/modules/forgefed/actor.go
+++ b/modules/forgefed/actor.go
@@ -8,7 +8,7 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/validation"
ap "github.com/go-ap/activitypub"
)
diff --git a/modules/forgefed/actor_test.go b/modules/forgefed/actor_test.go
index a3c01eceb0..e2157a96e4 100644
--- a/modules/forgefed/actor_test.go
+++ b/modules/forgefed/actor_test.go
@@ -8,8 +8,8 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/validation"
ap "github.com/go-ap/activitypub"
)
diff --git a/modules/forgefed/forgefed.go b/modules/forgefed/forgefed.go
index 234aecf3ae..2344dc7a8b 100644
--- a/modules/forgefed/forgefed.go
+++ b/modules/forgefed/forgefed.go
@@ -16,8 +16,9 @@ func GetItemByType(typ ap.ActivityVocabularyType) (ap.Item, error) {
switch typ {
case RepositoryType:
return RepositoryNew(""), nil
+ default:
+ return ap.GetItemByType(typ)
}
- return ap.GetItemByType(typ)
}
// JSONUnmarshalerFn is the function that will load the data from a fastjson.Value into an Item
@@ -28,8 +29,9 @@ func JSONUnmarshalerFn(typ ap.ActivityVocabularyType, val *fastjson.Value, i ap.
return OnRepository(i, func(r *Repository) error {
return JSONLoadRepository(val, r)
})
+ default:
+ return nil
}
- return nil
}
// NotEmpty is the function that checks if an object is empty
@@ -44,6 +46,7 @@ func NotEmpty(i ap.Item) bool {
return false
}
return ap.NotEmpty(r.Actor)
+ default:
+ return ap.NotEmpty(i)
}
- return ap.NotEmpty(i)
}
diff --git a/modules/forgefed/repository_test.go b/modules/forgefed/repository_test.go
index 13a73c10f4..5aebbbc08f 100644
--- a/modules/forgefed/repository_test.go
+++ b/modules/forgefed/repository_test.go
@@ -8,7 +8,7 @@ import (
"reflect"
"testing"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
ap "github.com/go-ap/activitypub"
)
diff --git a/modules/generate/generate.go b/modules/generate/generate.go
index 41a6aa2815..9738195da9 100644
--- a/modules/generate/generate.go
+++ b/modules/generate/generate.go
@@ -11,7 +11,7 @@ import (
"io"
"time"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
"github.com/golang-jwt/jwt/v5"
)
diff --git a/modules/generate/generate_test.go b/modules/generate/generate_test.go
index 7d023b23ad..eb7178af33 100644
--- a/modules/generate/generate_test.go
+++ b/modules/generate/generate_test.go
@@ -9,26 +9,27 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestDecodeJwtSecret(t *testing.T) {
_, err := DecodeJwtSecret("abcd")
- assert.ErrorContains(t, err, "invalid base64 decoded length")
+ require.ErrorContains(t, err, "invalid base64 decoded length")
_, err = DecodeJwtSecret(strings.Repeat("a", 64))
- assert.ErrorContains(t, err, "invalid base64 decoded length")
+ require.ErrorContains(t, err, "invalid base64 decoded length")
str32 := strings.Repeat("x", 32)
encoded32 := base64.RawURLEncoding.EncodeToString([]byte(str32))
decoded32, err := DecodeJwtSecret(encoded32)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, str32, string(decoded32))
}
func TestNewJwtSecret(t *testing.T) {
secret, encoded, err := NewJwtSecret()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, secret, 32)
decoded, err := DecodeJwtSecret(encoded)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, secret, decoded)
}
diff --git a/modules/git/batch.go b/modules/git/batch.go
new file mode 100644
index 0000000000..3ec4f1ddcc
--- /dev/null
+++ b/modules/git/batch.go
@@ -0,0 +1,46 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package git
+
+import (
+ "bufio"
+ "context"
+)
+
+type Batch struct {
+ cancel context.CancelFunc
+ Reader *bufio.Reader
+ Writer WriteCloserError
+}
+
+func (repo *Repository) NewBatch(ctx context.Context) (*Batch, error) {
+ // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
+ if err := ensureValidGitRepository(ctx, repo.Path); err != nil {
+ return nil, err
+ }
+
+ var batch Batch
+ batch.Writer, batch.Reader, batch.cancel = catFileBatch(ctx, repo.Path)
+ return &batch, nil
+}
+
+func (repo *Repository) NewBatchCheck(ctx context.Context) (*Batch, error) {
+ // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
+ if err := ensureValidGitRepository(ctx, repo.Path); err != nil {
+ return nil, err
+ }
+
+ var check Batch
+ check.Writer, check.Reader, check.cancel = catFileBatchCheck(ctx, repo.Path)
+ return &check, nil
+}
+
+func (b *Batch) Close() {
+ if b.cancel != nil {
+ b.cancel()
+ b.Reader = nil
+ b.Writer = nil
+ b.cancel = nil
+ }
+}
diff --git a/modules/git/batch_reader.go b/modules/git/batch_reader.go
index c988d6ab86..1297c7247f 100644
--- a/modules/git/batch_reader.go
+++ b/modules/git/batch_reader.go
@@ -14,7 +14,7 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"github.com/djherbis/buffer"
"github.com/djherbis/nio/v3"
@@ -26,10 +26,10 @@ type WriteCloserError interface {
CloseWithError(err error) error
}
-// EnsureValidGitRepository runs git rev-parse in the repository path - thus ensuring that the repository is a valid repository.
+// ensureValidGitRepository runs git rev-parse in the repository path - thus ensuring that the repository is a valid repository.
// Run before opening git cat-file.
// This is needed otherwise the git cat-file will hang for invalid repositories.
-func EnsureValidGitRepository(ctx context.Context, repoPath string) error {
+func ensureValidGitRepository(ctx context.Context, repoPath string) error {
stderr := strings.Builder{}
err := NewCommand(ctx, "rev-parse").
SetDescription(fmt.Sprintf("%s rev-parse [repo_path: %s]", GitExecutable, repoPath)).
@@ -43,8 +43,8 @@ func EnsureValidGitRepository(ctx context.Context, repoPath string) error {
return nil
}
-// CatFileBatchCheck opens git cat-file --batch-check in the provided repo and returns a stdin pipe, a stdout reader and cancel function
-func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
+// catFileBatchCheck opens git cat-file --batch-check in the provided repo and returns a stdin pipe, a stdout reader and cancel function
+func catFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
batchStdinReader, batchStdinWriter := io.Pipe()
batchStdoutReader, batchStdoutWriter := io.Pipe()
ctx, ctxCancel := context.WithCancel(ctx)
@@ -93,8 +93,8 @@ func CatFileBatchCheck(ctx context.Context, repoPath string) (WriteCloserError,
return batchStdinWriter, batchReader, cancel
}
-// CatFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function
-func CatFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
+// catFileBatch opens git cat-file --batch in the provided repo and returns a stdin pipe, a stdout reader and cancel function
+func catFileBatch(ctx context.Context, repoPath string) (WriteCloserError, *bufio.Reader, func()) {
// We often want to feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
// so let's create a batch stdin and stdout
batchStdinReader, batchStdinWriter := io.Pipe()
diff --git a/modules/git/blame.go b/modules/git/blame.go
index 69e1b08f93..4ff347e31b 100644
--- a/modules/git/blame.go
+++ b/modules/git/blame.go
@@ -11,8 +11,8 @@ import (
"io"
"os"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
// BlamePart represents block of blame - continuous lines with one sha
@@ -139,7 +139,7 @@ func CreateBlameReader(ctx context.Context, objectFormat ObjectFormat, repoPath
cmd := NewCommandContextNoGlobals(ctx, "blame", "--porcelain")
if ignoreRevsFile != nil {
// Possible improvement: use --ignore-revs-file /dev/stdin on unix
- // There is no equivalent on Windows. May be implemented if Gitea uses an external git backend.
+ // This was not done in Gitea because it would not have been compatible with Windows.
cmd.AddOptionValues("--ignore-revs-file", *ignoreRevsFile)
}
cmd.AddDynamicArguments(commit.ID.String()).
diff --git a/modules/git/blame_sha256_test.go b/modules/git/blame_sha256_test.go
index fcb00e2a38..c37f40775b 100644
--- a/modules/git/blame_sha256_test.go
+++ b/modules/git/blame_sha256_test.go
@@ -8,21 +8,22 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestReadingBlameOutputSha256(t *testing.T) {
skipIfSHA256NotSupported(t)
- ctx, cancel := context.WithCancel(context.Background())
+ ctx, cancel := context.WithCancel(t.Context())
defer cancel()
t.Run("Without .git-blame-ignore-revs", func(t *testing.T) {
repo, err := OpenRepository(ctx, "./tests/repos/repo5_pulls_sha256")
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
commit, err := repo.GetCommit("0b69b7bb649b5d46e14cabb6468685e5dd721290acc7ffe604d37cde57927345")
- assert.NoError(t, err)
+ require.NoError(t, err)
parts := []*BlamePart{
{
@@ -42,7 +43,7 @@ func TestReadingBlameOutputSha256(t *testing.T) {
for _, bypass := range []bool{false, true} {
blameReader, err := CreateBlameReader(ctx, Sha256ObjectFormat, "./tests/repos/repo5_pulls_sha256", commit, "README.md", bypass)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, blameReader)
defer blameReader.Close()
@@ -50,20 +51,20 @@ func TestReadingBlameOutputSha256(t *testing.T) {
for _, part := range parts {
actualPart, err := blameReader.NextPart()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, part, actualPart)
}
// make sure all parts have been read
actualPart, err := blameReader.NextPart()
assert.Nil(t, actualPart)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
})
t.Run("With .git-blame-ignore-revs", func(t *testing.T) {
repo, err := OpenRepository(ctx, "./tests/repos/repo6_blame_sha256")
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
full := []*BlamePart{
@@ -121,12 +122,12 @@ func TestReadingBlameOutputSha256(t *testing.T) {
}
objectFormat, err := repo.GetObjectFormat()
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, c := range cases {
commit, err := repo.GetCommit(c.CommitID)
- assert.NoError(t, err)
+ require.NoError(t, err)
blameReader, err := CreateBlameReader(ctx, objectFormat, "./tests/repos/repo6_blame_sha256", commit, "blame.txt", c.Bypass)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, blameReader)
defer blameReader.Close()
@@ -134,14 +135,14 @@ func TestReadingBlameOutputSha256(t *testing.T) {
for _, part := range c.Parts {
actualPart, err := blameReader.NextPart()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, part, actualPart)
}
// make sure all parts have been read
actualPart, err := blameReader.NextPart()
assert.Nil(t, actualPart)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
})
}
diff --git a/modules/git/blame_test.go b/modules/git/blame_test.go
index 4220c85600..b8fc59dd9e 100644
--- a/modules/git/blame_test.go
+++ b/modules/git/blame_test.go
@@ -8,19 +8,20 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestReadingBlameOutput(t *testing.T) {
- ctx, cancel := context.WithCancel(context.Background())
+ ctx, cancel := context.WithCancel(t.Context())
defer cancel()
t.Run("Without .git-blame-ignore-revs", func(t *testing.T) {
repo, err := OpenRepository(ctx, "./tests/repos/repo5_pulls")
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
commit, err := repo.GetCommit("f32b0a9dfd09a60f616f29158f772cedd89942d2")
- assert.NoError(t, err)
+ require.NoError(t, err)
parts := []*BlamePart{
{
@@ -40,7 +41,7 @@ func TestReadingBlameOutput(t *testing.T) {
for _, bypass := range []bool{false, true} {
blameReader, err := CreateBlameReader(ctx, Sha1ObjectFormat, "./tests/repos/repo5_pulls", commit, "README.md", bypass)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, blameReader)
defer blameReader.Close()
@@ -48,20 +49,20 @@ func TestReadingBlameOutput(t *testing.T) {
for _, part := range parts {
actualPart, err := blameReader.NextPart()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, part, actualPart)
}
// make sure all parts have been read
actualPart, err := blameReader.NextPart()
assert.Nil(t, actualPart)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
})
t.Run("With .git-blame-ignore-revs", func(t *testing.T) {
repo, err := OpenRepository(ctx, "./tests/repos/repo6_blame")
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
full := []*BlamePart{
@@ -119,13 +120,13 @@ func TestReadingBlameOutput(t *testing.T) {
}
objectFormat, err := repo.GetObjectFormat()
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, c := range cases {
commit, err := repo.GetCommit(c.CommitID)
- assert.NoError(t, err)
+ require.NoError(t, err)
blameReader, err := CreateBlameReader(ctx, objectFormat, "./tests/repos/repo6_blame", commit, "blame.txt", c.Bypass)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, blameReader)
defer blameReader.Close()
@@ -133,14 +134,14 @@ func TestReadingBlameOutput(t *testing.T) {
for _, part := range c.Parts {
actualPart, err := blameReader.NextPart()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, part, actualPart)
}
// make sure all parts have been read
actualPart, err := blameReader.NextPart()
assert.Nil(t, actualPart)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
})
}
diff --git a/modules/git/blob.go b/modules/git/blob.go
index bcecb42e16..8f912189ed 100644
--- a/modules/git/blob.go
+++ b/modules/git/blob.go
@@ -5,15 +5,130 @@
package git
import (
+ "bufio"
"bytes"
"encoding/base64"
"io"
- "code.gitea.io/gitea/modules/typesniffer"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/typesniffer"
+ "forgejo.org/modules/util"
)
-// This file contains common functions between the gogit and !gogit variants for git Blobs
+// Blob represents a Git object.
+type Blob struct {
+ ID ObjectID
+
+ gotSize bool
+ size int64
+ name string
+ repo *Repository
+}
+
+// DataAsync gets a ReadCloser for the contents of a blob without reading it all.
+// Calling the Close function on the result will discard all unread output.
+func (b *Blob) DataAsync() (io.ReadCloser, error) {
+ wr, rd, cancel, err := b.repo.CatFileBatch(b.repo.Ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = wr.Write([]byte(b.ID.String() + "\n"))
+ if err != nil {
+ cancel()
+ return nil, err
+ }
+ _, _, size, err := ReadBatchLine(rd)
+ if err != nil {
+ cancel()
+ return nil, err
+ }
+ b.gotSize = true
+ b.size = size
+
+ if size < 4096 {
+ bs, err := io.ReadAll(io.LimitReader(rd, size))
+ defer cancel()
+ if err != nil {
+ return nil, err
+ }
+ _, err = rd.Discard(1)
+ return io.NopCloser(bytes.NewReader(bs)), err
+ }
+
+ return &blobReader{
+ rd: rd,
+ n: size,
+ cancel: cancel,
+ }, nil
+}
+
+// Size returns the uncompressed size of the blob
+func (b *Blob) Size() int64 {
+ if b.gotSize {
+ return b.size
+ }
+
+ wr, rd, cancel, err := b.repo.CatFileBatchCheck(b.repo.Ctx)
+ if err != nil {
+ log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
+ return 0
+ }
+ defer cancel()
+ _, err = wr.Write([]byte(b.ID.String() + "\n"))
+ if err != nil {
+ log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
+ return 0
+ }
+ _, _, b.size, err = ReadBatchLine(rd)
+ if err != nil {
+ log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
+ return 0
+ }
+
+ b.gotSize = true
+
+ return b.size
+}
+
+type blobReader struct {
+ rd *bufio.Reader
+ n int64
+ cancel func()
+}
+
+func (b *blobReader) Read(p []byte) (n int, err error) {
+ if b.n <= 0 {
+ return 0, io.EOF
+ }
+ if int64(len(p)) > b.n {
+ p = p[0:b.n]
+ }
+ n, err = b.rd.Read(p)
+ b.n -= int64(n)
+ return n, err
+}
+
+// Close implements io.Closer
+func (b *blobReader) Close() error {
+ if b.rd == nil {
+ return nil
+ }
+
+ defer b.cancel()
+
+ if err := DiscardFull(b.rd, b.n+1); err != nil {
+ return err
+ }
+
+ b.rd = nil
+
+ return nil
+}
+
+func (b *Blob) Repo() *Repository {
+ return b.repo
+}
// Name returns name of the tree entry this blob object was created from (or empty string)
func (b *Blob) Name() string {
@@ -100,3 +215,18 @@ func (b *Blob) GuessContentType() (typesniffer.SniffedType, error) {
return typesniffer.DetectContentTypeFromReader(r)
}
+
+// GetBlob finds the blob object in the repository.
+func (repo *Repository) GetBlob(idStr string) (*Blob, error) {
+ id, err := NewIDFromString(idStr)
+ if err != nil {
+ return nil, err
+ }
+ if id.IsZero() {
+ return nil, ErrNotExist{id.String(), ""}
+ }
+ return &Blob{
+ ID: id,
+ repo: repo,
+ }, nil
+}
diff --git a/modules/git/blob_gogit.go b/modules/git/blob_gogit.go
deleted file mode 100644
index 8c79c067c1..0000000000
--- a/modules/git/blob_gogit.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "io"
-
- "github.com/go-git/go-git/v5/plumbing"
-)
-
-// Blob represents a Git object.
-type Blob struct {
- ID ObjectID
-
- gogitEncodedObj plumbing.EncodedObject
- name string
-}
-
-// DataAsync gets a ReadCloser for the contents of a blob without reading it all.
-// Calling the Close function on the result will discard all unread output.
-func (b *Blob) DataAsync() (io.ReadCloser, error) {
- return b.gogitEncodedObj.Reader()
-}
-
-// Size returns the uncompressed size of the blob
-func (b *Blob) Size() int64 {
- return b.gogitEncodedObj.Size()
-}
diff --git a/modules/git/blob_nogogit.go b/modules/git/blob_nogogit.go
deleted file mode 100644
index 945a6bc432..0000000000
--- a/modules/git/blob_nogogit.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "bufio"
- "bytes"
- "io"
-
- "code.gitea.io/gitea/modules/log"
-)
-
-// Blob represents a Git object.
-type Blob struct {
- ID ObjectID
-
- gotSize bool
- size int64
- name string
- repo *Repository
-}
-
-// DataAsync gets a ReadCloser for the contents of a blob without reading it all.
-// Calling the Close function on the result will discard all unread output.
-func (b *Blob) DataAsync() (io.ReadCloser, error) {
- wr, rd, cancel := b.repo.CatFileBatch(b.repo.Ctx)
-
- _, err := wr.Write([]byte(b.ID.String() + "\n"))
- if err != nil {
- cancel()
- return nil, err
- }
- _, _, size, err := ReadBatchLine(rd)
- if err != nil {
- cancel()
- return nil, err
- }
- b.gotSize = true
- b.size = size
-
- if size < 4096 {
- bs, err := io.ReadAll(io.LimitReader(rd, size))
- defer cancel()
- if err != nil {
- return nil, err
- }
- _, err = rd.Discard(1)
- return io.NopCloser(bytes.NewReader(bs)), err
- }
-
- return &blobReader{
- rd: rd,
- n: size,
- cancel: cancel,
- }, nil
-}
-
-// Size returns the uncompressed size of the blob
-func (b *Blob) Size() int64 {
- if b.gotSize {
- return b.size
- }
-
- wr, rd, cancel := b.repo.CatFileBatchCheck(b.repo.Ctx)
- defer cancel()
- _, err := wr.Write([]byte(b.ID.String() + "\n"))
- if err != nil {
- log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
- return 0
- }
- _, _, b.size, err = ReadBatchLine(rd)
- if err != nil {
- log.Debug("error whilst reading size for %s in %s. Error: %v", b.ID.String(), b.repo.Path, err)
- return 0
- }
-
- b.gotSize = true
-
- return b.size
-}
-
-type blobReader struct {
- rd *bufio.Reader
- n int64
- cancel func()
-}
-
-func (b *blobReader) Read(p []byte) (n int, err error) {
- if b.n <= 0 {
- return 0, io.EOF
- }
- if int64(len(p)) > b.n {
- p = p[0:b.n]
- }
- n, err = b.rd.Read(p)
- b.n -= int64(n)
- return n, err
-}
-
-// Close implements io.Closer
-func (b *blobReader) Close() error {
- if b.rd == nil {
- return nil
- }
-
- defer b.cancel()
-
- if err := DiscardFull(b.rd, b.n+1); err != nil {
- return err
- }
-
- b.rd = nil
-
- return nil
-}
diff --git a/modules/git/blob_test.go b/modules/git/blob_test.go
index 63374384f6..810964b33d 100644
--- a/modules/git/blob_test.go
+++ b/modules/git/blob_test.go
@@ -17,22 +17,21 @@ func TestBlob_Data(t *testing.T) {
output := "file2\n"
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
- if !assert.NoError(t, err) {
- t.Fatal()
- }
+ require.NoError(t, err)
+
defer repo.Close()
testBlob, err := repo.GetBlob("6c493ff740f9380390d5c9ddef4af18697ac9375")
- assert.NoError(t, err)
+ require.NoError(t, err)
r, err := testBlob.DataAsync()
- assert.NoError(t, err)
+ require.NoError(t, err)
require.NotNil(t, r)
data, err := io.ReadAll(r)
- assert.NoError(t, r.Close())
+ require.NoError(t, r.Close())
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, output, string(data))
}
diff --git a/modules/git/command.go b/modules/git/command.go
index 22cb275ab2..fd29ac36e9 100644
--- a/modules/git/command.go
+++ b/modules/git/command.go
@@ -12,14 +12,14 @@ import (
"io"
"os"
"os/exec"
- "runtime"
+ "runtime/trace"
"strings"
"time"
- "code.gitea.io/gitea/modules/git/internal" //nolint:depguard // only this file can use the internal type CmdArg, other files and packages should use AddXxx functions
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/git/internal" //nolint:depguard // only this file can use the internal type CmdArg, other files and packages should use AddXxx functions
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/util"
)
// TrustedCmdArgs returns the trusted arguments for git command.
@@ -153,6 +153,18 @@ func (c *Command) AddOptionValues(opt internal.CmdArg, args ...string) *Command
return c
}
+// AddGitGrepExpression adds an expression option (-e) to git-grep command
+// It is different from AddOptionValues in that it allows the actual expression
+// to not be filtered out for leading dashes (which is otherwise a security feature
+// of AddOptionValues).
+func (c *Command) AddGitGrepExpression(exp string) *Command {
+ if c.args[len(globalCommandArgs)] != "grep" {
+ panic("function called on a non-grep git program: " + c.args[0])
+ }
+ c.args = append(c.args, "-e", exp)
+ return c
+}
+
// AddOptionFormat adds a new option with a format string and arguments
// For example: AddOptionFormat("--opt=%s %s", val1, val2) means 1 argument: {"--opt=val1 val2"}.
func (c *Command) AddOptionFormat(opt string, args ...any) *Command {
@@ -305,12 +317,13 @@ func (c *Command) Run(opts *RunOpts) error {
var finished context.CancelFunc
if opts.UseContextTimeout {
- ctx, cancel, finished = process.GetManager().AddContext(c.parentContext, desc)
+ ctx, cancel, finished = process.GetManager().AddTypedContext(c.parentContext, desc, process.GitProcessType, true)
} else {
- ctx, cancel, finished = process.GetManager().AddContextTimeout(c.parentContext, timeout, desc)
+ ctx, cancel, finished = process.GetManager().AddTypedContextTimeout(c.parentContext, timeout, desc, process.GitProcessType, true)
}
defer finished()
+ trace.Log(ctx, "command", desc)
startTime := time.Now()
cmd := exec.CommandContext(ctx, c.prog, c.args...)
@@ -345,17 +358,6 @@ func (c *Command) Run(opts *RunOpts) error {
log.Debug("slow git.Command.Run: %s (%s)", c, elapsed)
}
- // We need to check if the context is canceled by the program on Windows.
- // This is because Windows does not have signal checking when terminating the process.
- // It always returns exit code 1, unlike Linux, which has many exit codes for signals.
- if runtime.GOOS == "windows" &&
- err != nil &&
- err.Error() == "" &&
- cmd.ProcessState.ExitCode() == 1 &&
- ctx.Err() == context.Canceled {
- return ctx.Err()
- }
-
if err != nil && ctx.Err() != context.DeadlineExceeded {
return err
}
@@ -445,12 +447,13 @@ func (c *Command) RunStdBytes(opts *RunOpts) (stdout, stderr []byte, runErr RunS
}
// AllowLFSFiltersArgs return globalCommandArgs with lfs filter, it should only be used for tests
+// It also re-enables git-credential(1), which is used to test git-annex's HTTP support
func AllowLFSFiltersArgs() TrustedCmdArgs {
// Now here we should explicitly allow lfs filters to run
filteredLFSGlobalArgs := make(TrustedCmdArgs, len(globalCommandArgs))
j := 0
for _, arg := range globalCommandArgs {
- if strings.Contains(string(arg), "lfs") {
+ if strings.Contains(string(arg), "lfs") || strings.Contains(string(arg), "credential") {
j--
} else {
filteredLFSGlobalArgs[j] = arg
diff --git a/modules/git/command_test.go b/modules/git/command_test.go
index 9a6228c9ad..ace43598fc 100644
--- a/modules/git/command_test.go
+++ b/modules/git/command_test.go
@@ -4,20 +4,20 @@
package git
import (
- "context"
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRunWithContextStd(t *testing.T) {
- cmd := NewCommand(context.Background(), "--version")
+ cmd := NewCommand(t.Context(), "--version")
stdout, stderr, err := cmd.RunStdString(&RunOpts{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, stderr)
assert.Contains(t, stdout, "git version")
- cmd = NewCommand(context.Background(), "--no-such-arg")
+ cmd = NewCommand(t.Context(), "--no-such-arg")
stdout, stderr, err = cmd.RunStdString(&RunOpts{})
if assert.Error(t, err) {
assert.Equal(t, stderr, err.Stderr())
@@ -26,18 +26,18 @@ func TestRunWithContextStd(t *testing.T) {
assert.Empty(t, stdout)
}
- cmd = NewCommand(context.Background())
+ cmd = NewCommand(t.Context())
cmd.AddDynamicArguments("-test")
- assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
+ require.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
- cmd = NewCommand(context.Background())
+ cmd = NewCommand(t.Context())
cmd.AddDynamicArguments("--test")
- assert.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
+ require.ErrorIs(t, cmd.Run(&RunOpts{}), ErrBrokenCommand)
subCmd := "version"
- cmd = NewCommand(context.Background()).AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production
+ cmd = NewCommand(t.Context()).AddDynamicArguments(subCmd) // for test purpose only, the sub-command should never be dynamic for production
stdout, stderr, err = cmd.RunStdString(&RunOpts{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, stderr)
assert.Contains(t, stdout, "git version")
}
@@ -54,9 +54,16 @@ func TestGitArgument(t *testing.T) {
}
func TestCommandString(t *testing.T) {
- cmd := NewCommandContextNoGlobals(context.Background(), "a", "-m msg", "it's a test", `say "hello"`)
+ cmd := NewCommandContextNoGlobals(t.Context(), "a", "-m msg", "it's a test", `say "hello"`)
assert.EqualValues(t, cmd.prog+` a "-m msg" "it's a test" "say \"hello\""`, cmd.String())
- cmd = NewCommandContextNoGlobals(context.Background(), "url: https://a:b@c/")
+ cmd = NewCommandContextNoGlobals(t.Context(), "url: https://a:b@c/")
assert.EqualValues(t, cmd.prog+` "url: https://sanitized-credential@c/"`, cmd.toString(true))
}
+
+func TestGrepOnlyFunction(t *testing.T) {
+ cmd := NewCommand(t.Context(), "anything-but-grep")
+ assert.Panics(t, func() {
+ cmd.AddGitGrepExpression("whatever")
+ })
+}
diff --git a/modules/git/commit.go b/modules/git/commit.go
index b5ae2e0e52..baefe3820d 100644
--- a/modules/git/commit.go
+++ b/modules/git/commit.go
@@ -15,8 +15,10 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
+
+ "github.com/go-git/go-git/v5/config"
)
// Commit represents a git commit.
@@ -365,53 +367,48 @@ func (c *Commit) GetSubModules() (*ObjectCache, error) {
return nil, err
}
- rd, err := entry.Blob().DataAsync()
+ content, err := entry.Blob().GetBlobContent(10 * 1024)
if err != nil {
return nil, err
}
- defer rd.Close()
- scanner := bufio.NewScanner(rd)
- c.submoduleCache = newObjectCache()
- var ismodule bool
- var path string
- for scanner.Scan() {
- if strings.HasPrefix(scanner.Text(), "[submodule") {
- ismodule = true
- continue
- }
- if ismodule {
- fields := strings.Split(scanner.Text(), "=")
- k := strings.TrimSpace(fields[0])
- if k == "path" {
- path = strings.TrimSpace(fields[1])
- } else if k == "url" {
- c.submoduleCache.Set(path, &SubModule{path, strings.TrimSpace(fields[1])})
- ismodule = false
- }
- }
+ c.submoduleCache, err = parseSubmoduleContent([]byte(content))
+ if err != nil {
+ return nil, err
}
- if err = scanner.Err(); err != nil {
- return nil, fmt.Errorf("GetSubModules scan: %w", err)
- }
-
return c.submoduleCache, nil
}
-// GetSubModule get the sub module according entryname
-func (c *Commit) GetSubModule(entryname string) (*SubModule, error) {
+func parseSubmoduleContent(bs []byte) (*ObjectCache, error) {
+ cfg := config.NewModules()
+ if err := cfg.Unmarshal(bs); err != nil {
+ return nil, err
+ }
+ submoduleCache := newObjectCache()
+ if len(cfg.Submodules) == 0 {
+ return nil, fmt.Errorf("no submodules found")
+ }
+ for _, subModule := range cfg.Submodules {
+ submoduleCache.Set(subModule.Path, subModule.URL)
+ }
+
+ return submoduleCache, nil
+}
+
+// GetSubModule returns the URL to the submodule according entryname
+func (c *Commit) GetSubModule(entryname string) (string, error) {
modules, err := c.GetSubModules()
if err != nil {
- return nil, err
+ return "", err
}
if modules != nil {
module, has := modules.Get(entryname)
if has {
- return module.(*SubModule), nil
+ return module.(string), nil
}
}
- return nil, nil
+ return "", nil
}
// GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only')
diff --git a/modules/git/commit_convert_gogit.go b/modules/git/commit_convert_gogit.go
deleted file mode 100644
index c413465656..0000000000
--- a/modules/git/commit_convert_gogit.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "fmt"
- "strings"
-
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-func convertPGPSignature(c *object.Commit) *ObjectSignature {
- if c.PGPSignature == "" {
- return nil
- }
-
- var w strings.Builder
- var err error
-
- if _, err = fmt.Fprintf(&w, "tree %s\n", c.TreeHash.String()); err != nil {
- return nil
- }
-
- for _, parent := range c.ParentHashes {
- if _, err = fmt.Fprintf(&w, "parent %s\n", parent.String()); err != nil {
- return nil
- }
- }
-
- if _, err = fmt.Fprint(&w, "author "); err != nil {
- return nil
- }
-
- if err = c.Author.Encode(&w); err != nil {
- return nil
- }
-
- if _, err = fmt.Fprint(&w, "\ncommitter "); err != nil {
- return nil
- }
-
- if err = c.Committer.Encode(&w); err != nil {
- return nil
- }
-
- if c.Encoding != "" && c.Encoding != "UTF-8" {
- if _, err = fmt.Fprintf(&w, "\nencoding %s\n", c.Encoding); err != nil {
- return nil
- }
- }
-
- if _, err = fmt.Fprintf(&w, "\n\n%s", c.Message); err != nil {
- return nil
- }
-
- return &ObjectSignature{
- Signature: c.PGPSignature,
- Payload: w.String(),
- }
-}
-
-func convertCommit(c *object.Commit) *Commit {
- return &Commit{
- ID: ParseGogitHash(c.Hash),
- CommitMessage: c.Message,
- Committer: &c.Committer,
- Author: &c.Author,
- Signature: convertPGPSignature(c),
- Parents: ParseGogitHashArray(c.ParentHashes),
- }
-}
diff --git a/modules/git/commit_info.go b/modules/git/commit_info.go
index c740a4e13e..8d9142d362 100644
--- a/modules/git/commit_info.go
+++ b/modules/git/commit_info.go
@@ -3,9 +3,174 @@
package git
+import (
+ "context"
+ "fmt"
+ "io"
+ "path"
+ "sort"
+
+ "forgejo.org/modules/log"
+)
+
// CommitInfo describes the first commit with the provided entry
type CommitInfo struct {
Entry *TreeEntry
Commit *Commit
SubModuleFile *SubModuleFile
}
+
+// GetCommitsInfo gets information of all commits that are corresponding to these entries
+func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) {
+ entryPaths := make([]string, len(tes)+1)
+ // Get the commit for the treePath itself
+ entryPaths[0] = ""
+ for i, entry := range tes {
+ entryPaths[i+1] = entry.Name()
+ }
+
+ var err error
+
+ var revs map[string]*Commit
+ if commit.repo.LastCommitCache != nil {
+ var unHitPaths []string
+ revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, commit.repo.LastCommitCache)
+ if err != nil {
+ return nil, nil, err
+ }
+ if len(unHitPaths) > 0 {
+ sort.Strings(unHitPaths)
+ commits, err := GetLastCommitForPaths(ctx, commit, treePath, unHitPaths)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ for pth, found := range commits {
+ revs[pth] = found
+ }
+ }
+ } else {
+ sort.Strings(entryPaths)
+ revs, err = GetLastCommitForPaths(ctx, commit, treePath, entryPaths)
+ }
+ if err != nil {
+ return nil, nil, err
+ }
+
+ commitsInfo := make([]CommitInfo, len(tes))
+ for i, entry := range tes {
+ commitsInfo[i] = CommitInfo{
+ Entry: entry,
+ }
+
+ // Check if we have found a commit for this entry in time
+ if entryCommit, ok := revs[entry.Name()]; ok {
+ commitsInfo[i].Commit = entryCommit
+ } else {
+ log.Debug("missing commit for %s", entry.Name())
+ }
+
+ // If the entry if a submodule add a submodule file for this
+ if entry.IsSubModule() {
+ var fullPath string
+ if len(treePath) > 0 {
+ fullPath = treePath + "/" + entry.Name()
+ } else {
+ fullPath = entry.Name()
+ }
+ subModuleURL, err := commit.GetSubModule(fullPath)
+ if err != nil {
+ return nil, nil, err
+ }
+ subModuleFile := NewSubModuleFile(commitsInfo[i].Commit, subModuleURL, entry.ID.String())
+ commitsInfo[i].SubModuleFile = subModuleFile
+ }
+ }
+
+ // Retrieve the commit for the treePath itself (see above). We basically
+ // get it for free during the tree traversal and it's used for listing
+ // pages to display information about newest commit for a given path.
+ var treeCommit *Commit
+ var ok bool
+ if treePath == "" {
+ treeCommit = commit
+ } else if treeCommit, ok = revs[""]; ok {
+ treeCommit.repo = commit.repo
+ }
+ return commitsInfo, treeCommit, nil
+}
+
+func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) {
+ var unHitEntryPaths []string
+ results := make(map[string]*Commit)
+ for _, p := range paths {
+ lastCommit, err := cache.Get(commitID, path.Join(treePath, p))
+ if err != nil {
+ return nil, nil, err
+ }
+ if lastCommit != nil {
+ results[p] = lastCommit
+ continue
+ }
+
+ unHitEntryPaths = append(unHitEntryPaths, p)
+ }
+
+ return results, unHitEntryPaths, nil
+}
+
+// GetLastCommitForPaths returns last commit information
+func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, paths []string) (map[string]*Commit, error) {
+ // We read backwards from the commit to obtain all of the commits
+ revs, err := WalkGitLog(ctx, commit.repo, commit, treePath, paths...)
+ if err != nil {
+ return nil, err
+ }
+
+ batchStdinWriter, batchReader, cancel, err := commit.repo.CatFileBatch(ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer cancel()
+
+ commitsMap := map[string]*Commit{}
+ commitsMap[commit.ID.String()] = commit
+
+ commitCommits := map[string]*Commit{}
+ for path, commitID := range revs {
+ c, ok := commitsMap[commitID]
+ if ok {
+ commitCommits[path] = c
+ continue
+ }
+
+ if len(commitID) == 0 {
+ continue
+ }
+
+ _, err := batchStdinWriter.Write([]byte(commitID + "\n"))
+ if err != nil {
+ return nil, err
+ }
+ _, typ, size, err := ReadBatchLine(batchReader)
+ if err != nil {
+ return nil, err
+ }
+ if typ != "commit" {
+ if err := DiscardFull(batchReader, size+1); err != nil {
+ return nil, err
+ }
+ return nil, fmt.Errorf("unexpected type: %s for commit id: %s", typ, commitID)
+ }
+ c, err = CommitFromReader(commit.repo, MustIDFromString(commitID), io.LimitReader(batchReader, size))
+ if err != nil {
+ return nil, err
+ }
+ if _, err := batchReader.Discard(1); err != nil {
+ return nil, err
+ }
+ commitCommits[path] = c
+ }
+
+ return commitCommits, nil
+}
diff --git a/modules/git/commit_info_gogit.go b/modules/git/commit_info_gogit.go
deleted file mode 100644
index 31ffc9aec1..0000000000
--- a/modules/git/commit_info_gogit.go
+++ /dev/null
@@ -1,304 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "context"
- "path"
-
- "github.com/emirpasic/gods/trees/binaryheap"
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/object"
- cgobject "github.com/go-git/go-git/v5/plumbing/object/commitgraph"
-)
-
-// GetCommitsInfo gets information of all commits that are corresponding to these entries
-func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) {
- entryPaths := make([]string, len(tes)+1)
- // Get the commit for the treePath itself
- entryPaths[0] = ""
- for i, entry := range tes {
- entryPaths[i+1] = entry.Name()
- }
-
- commitNodeIndex, commitGraphFile := commit.repo.CommitNodeIndex()
- if commitGraphFile != nil {
- defer commitGraphFile.Close()
- }
-
- c, err := commitNodeIndex.Get(plumbing.Hash(commit.ID.RawValue()))
- if err != nil {
- return nil, nil, err
- }
-
- var revs map[string]*Commit
- if commit.repo.LastCommitCache != nil {
- var unHitPaths []string
- revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, commit.repo.LastCommitCache)
- if err != nil {
- return nil, nil, err
- }
- if len(unHitPaths) > 0 {
- revs2, err := GetLastCommitForPaths(ctx, commit.repo.LastCommitCache, c, treePath, unHitPaths)
- if err != nil {
- return nil, nil, err
- }
-
- for k, v := range revs2 {
- revs[k] = v
- }
- }
- } else {
- revs, err = GetLastCommitForPaths(ctx, nil, c, treePath, entryPaths)
- }
- if err != nil {
- return nil, nil, err
- }
-
- commit.repo.gogitStorage.Close()
-
- commitsInfo := make([]CommitInfo, len(tes))
- for i, entry := range tes {
- commitsInfo[i] = CommitInfo{
- Entry: entry,
- }
-
- // Check if we have found a commit for this entry in time
- if entryCommit, ok := revs[entry.Name()]; ok {
- commitsInfo[i].Commit = entryCommit
- }
-
- // If the entry if a submodule add a submodule file for this
- if entry.IsSubModule() {
- subModuleURL := ""
- var fullPath string
- if len(treePath) > 0 {
- fullPath = treePath + "/" + entry.Name()
- } else {
- fullPath = entry.Name()
- }
- if subModule, err := commit.GetSubModule(fullPath); err != nil {
- return nil, nil, err
- } else if subModule != nil {
- subModuleURL = subModule.URL
- }
- subModuleFile := NewSubModuleFile(commitsInfo[i].Commit, subModuleURL, entry.ID.String())
- commitsInfo[i].SubModuleFile = subModuleFile
- }
- }
-
- // Retrieve the commit for the treePath itself (see above). We basically
- // get it for free during the tree traversal and it's used for listing
- // pages to display information about newest commit for a given path.
- var treeCommit *Commit
- var ok bool
- if treePath == "" {
- treeCommit = commit
- } else if treeCommit, ok = revs[""]; ok {
- treeCommit.repo = commit.repo
- }
- return commitsInfo, treeCommit, nil
-}
-
-type commitAndPaths struct {
- commit cgobject.CommitNode
- // Paths that are still on the branch represented by commit
- paths []string
- // Set of hashes for the paths
- hashes map[string]plumbing.Hash
-}
-
-func getCommitTree(c cgobject.CommitNode, treePath string) (*object.Tree, error) {
- tree, err := c.Tree()
- if err != nil {
- return nil, err
- }
-
- // Optimize deep traversals by focusing only on the specific tree
- if treePath != "" {
- tree, err = tree.Tree(treePath)
- if err != nil {
- return nil, err
- }
- }
-
- return tree, nil
-}
-
-func getFileHashes(c cgobject.CommitNode, treePath string, paths []string) (map[string]plumbing.Hash, error) {
- tree, err := getCommitTree(c, treePath)
- if err == object.ErrDirectoryNotFound {
- // The whole tree didn't exist, so return empty map
- return make(map[string]plumbing.Hash), nil
- }
- if err != nil {
- return nil, err
- }
-
- hashes := make(map[string]plumbing.Hash)
- for _, path := range paths {
- if path != "" {
- entry, err := tree.FindEntry(path)
- if err == nil {
- hashes[path] = entry.Hash
- }
- } else {
- hashes[path] = tree.Hash
- }
- }
-
- return hashes, nil
-}
-
-func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) {
- var unHitEntryPaths []string
- results := make(map[string]*Commit)
- for _, p := range paths {
- lastCommit, err := cache.Get(commitID, path.Join(treePath, p))
- if err != nil {
- return nil, nil, err
- }
- if lastCommit != nil {
- results[p] = lastCommit
- continue
- }
-
- unHitEntryPaths = append(unHitEntryPaths, p)
- }
-
- return results, unHitEntryPaths, nil
-}
-
-// GetLastCommitForPaths returns last commit information
-func GetLastCommitForPaths(ctx context.Context, cache *LastCommitCache, c cgobject.CommitNode, treePath string, paths []string) (map[string]*Commit, error) {
- refSha := c.ID().String()
-
- // We do a tree traversal with nodes sorted by commit time
- heap := binaryheap.NewWith(func(a, b any) int {
- if a.(*commitAndPaths).commit.CommitTime().Before(b.(*commitAndPaths).commit.CommitTime()) {
- return 1
- }
- return -1
- })
-
- resultNodes := make(map[string]cgobject.CommitNode)
- initialHashes, err := getFileHashes(c, treePath, paths)
- if err != nil {
- return nil, err
- }
-
- // Start search from the root commit and with full set of paths
- heap.Push(&commitAndPaths{c, paths, initialHashes})
-heaploop:
- for {
- select {
- case <-ctx.Done():
- if ctx.Err() == context.DeadlineExceeded {
- break heaploop
- }
- return nil, ctx.Err()
- default:
- }
- cIn, ok := heap.Pop()
- if !ok {
- break
- }
- current := cIn.(*commitAndPaths)
-
- // Load the parent commits for the one we are currently examining
- numParents := current.commit.NumParents()
- var parents []cgobject.CommitNode
- for i := 0; i < numParents; i++ {
- parent, err := current.commit.ParentNode(i)
- if err != nil {
- break
- }
- parents = append(parents, parent)
- }
-
- // Examine the current commit and set of interesting paths
- pathUnchanged := make([]bool, len(current.paths))
- parentHashes := make([]map[string]plumbing.Hash, len(parents))
- for j, parent := range parents {
- parentHashes[j], err = getFileHashes(parent, treePath, current.paths)
- if err != nil {
- break
- }
-
- for i, path := range current.paths {
- if parentHashes[j][path] == current.hashes[path] {
- pathUnchanged[i] = true
- }
- }
- }
-
- var remainingPaths []string
- for i, pth := range current.paths {
- // The results could already contain some newer change for the same path,
- // so don't override that and bail out on the file early.
- if resultNodes[pth] == nil {
- if pathUnchanged[i] {
- // The path existed with the same hash in at least one parent so it could
- // not have been changed in this commit directly.
- remainingPaths = append(remainingPaths, pth)
- } else {
- // There are few possible cases how can we get here:
- // - The path didn't exist in any parent, so it must have been created by
- // this commit.
- // - The path did exist in the parent commit, but the hash of the file has
- // changed.
- // - We are looking at a merge commit and the hash of the file doesn't
- // match any of the hashes being merged. This is more common for directories,
- // but it can also happen if a file is changed through conflict resolution.
- resultNodes[pth] = current.commit
- if err := cache.Put(refSha, path.Join(treePath, pth), current.commit.ID().String()); err != nil {
- return nil, err
- }
- }
- }
- }
-
- if len(remainingPaths) > 0 {
- // Add the parent nodes along with remaining paths to the heap for further
- // processing.
- for j, parent := range parents {
- // Combine remainingPath with paths available on the parent branch
- // and make union of them
- remainingPathsForParent := make([]string, 0, len(remainingPaths))
- newRemainingPaths := make([]string, 0, len(remainingPaths))
- for _, path := range remainingPaths {
- if parentHashes[j][path] == current.hashes[path] {
- remainingPathsForParent = append(remainingPathsForParent, path)
- } else {
- newRemainingPaths = append(newRemainingPaths, path)
- }
- }
-
- if remainingPathsForParent != nil {
- heap.Push(&commitAndPaths{parent, remainingPathsForParent, parentHashes[j]})
- }
-
- if len(newRemainingPaths) == 0 {
- break
- } else {
- remainingPaths = newRemainingPaths
- }
- }
- }
- }
-
- // Post-processing
- result := make(map[string]*Commit)
- for path, commitNode := range resultNodes {
- commit, err := commitNode.Commit()
- if err != nil {
- return nil, err
- }
- result[path] = convertCommit(commit)
- }
-
- return result, nil
-}
diff --git a/modules/git/commit_info_nogogit.go b/modules/git/commit_info_nogogit.go
deleted file mode 100644
index 7c369b07f9..0000000000
--- a/modules/git/commit_info_nogogit.go
+++ /dev/null
@@ -1,170 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "context"
- "fmt"
- "io"
- "path"
- "sort"
-
- "code.gitea.io/gitea/modules/log"
-)
-
-// GetCommitsInfo gets information of all commits that are corresponding to these entries
-func (tes Entries) GetCommitsInfo(ctx context.Context, commit *Commit, treePath string) ([]CommitInfo, *Commit, error) {
- entryPaths := make([]string, len(tes)+1)
- // Get the commit for the treePath itself
- entryPaths[0] = ""
- for i, entry := range tes {
- entryPaths[i+1] = entry.Name()
- }
-
- var err error
-
- var revs map[string]*Commit
- if commit.repo.LastCommitCache != nil {
- var unHitPaths []string
- revs, unHitPaths, err = getLastCommitForPathsByCache(commit.ID.String(), treePath, entryPaths, commit.repo.LastCommitCache)
- if err != nil {
- return nil, nil, err
- }
- if len(unHitPaths) > 0 {
- sort.Strings(unHitPaths)
- commits, err := GetLastCommitForPaths(ctx, commit, treePath, unHitPaths)
- if err != nil {
- return nil, nil, err
- }
-
- for pth, found := range commits {
- revs[pth] = found
- }
- }
- } else {
- sort.Strings(entryPaths)
- revs, err = GetLastCommitForPaths(ctx, commit, treePath, entryPaths)
- }
- if err != nil {
- return nil, nil, err
- }
-
- commitsInfo := make([]CommitInfo, len(tes))
- for i, entry := range tes {
- commitsInfo[i] = CommitInfo{
- Entry: entry,
- }
-
- // Check if we have found a commit for this entry in time
- if entryCommit, ok := revs[entry.Name()]; ok {
- commitsInfo[i].Commit = entryCommit
- } else {
- log.Debug("missing commit for %s", entry.Name())
- }
-
- // If the entry if a submodule add a submodule file for this
- if entry.IsSubModule() {
- subModuleURL := ""
- var fullPath string
- if len(treePath) > 0 {
- fullPath = treePath + "/" + entry.Name()
- } else {
- fullPath = entry.Name()
- }
- if subModule, err := commit.GetSubModule(fullPath); err != nil {
- return nil, nil, err
- } else if subModule != nil {
- subModuleURL = subModule.URL
- }
- subModuleFile := NewSubModuleFile(commitsInfo[i].Commit, subModuleURL, entry.ID.String())
- commitsInfo[i].SubModuleFile = subModuleFile
- }
- }
-
- // Retrieve the commit for the treePath itself (see above). We basically
- // get it for free during the tree traversal and it's used for listing
- // pages to display information about newest commit for a given path.
- var treeCommit *Commit
- var ok bool
- if treePath == "" {
- treeCommit = commit
- } else if treeCommit, ok = revs[""]; ok {
- treeCommit.repo = commit.repo
- }
- return commitsInfo, treeCommit, nil
-}
-
-func getLastCommitForPathsByCache(commitID, treePath string, paths []string, cache *LastCommitCache) (map[string]*Commit, []string, error) {
- var unHitEntryPaths []string
- results := make(map[string]*Commit)
- for _, p := range paths {
- lastCommit, err := cache.Get(commitID, path.Join(treePath, p))
- if err != nil {
- return nil, nil, err
- }
- if lastCommit != nil {
- results[p] = lastCommit
- continue
- }
-
- unHitEntryPaths = append(unHitEntryPaths, p)
- }
-
- return results, unHitEntryPaths, nil
-}
-
-// GetLastCommitForPaths returns last commit information
-func GetLastCommitForPaths(ctx context.Context, commit *Commit, treePath string, paths []string) (map[string]*Commit, error) {
- // We read backwards from the commit to obtain all of the commits
- revs, err := WalkGitLog(ctx, commit.repo, commit, treePath, paths...)
- if err != nil {
- return nil, err
- }
-
- batchStdinWriter, batchReader, cancel := commit.repo.CatFileBatch(ctx)
- defer cancel()
-
- commitsMap := map[string]*Commit{}
- commitsMap[commit.ID.String()] = commit
-
- commitCommits := map[string]*Commit{}
- for path, commitID := range revs {
- c, ok := commitsMap[commitID]
- if ok {
- commitCommits[path] = c
- continue
- }
-
- if len(commitID) == 0 {
- continue
- }
-
- _, err := batchStdinWriter.Write([]byte(commitID + "\n"))
- if err != nil {
- return nil, err
- }
- _, typ, size, err := ReadBatchLine(batchReader)
- if err != nil {
- return nil, err
- }
- if typ != "commit" {
- if err := DiscardFull(batchReader, size+1); err != nil {
- return nil, err
- }
- return nil, fmt.Errorf("unexpected type: %s for commit id: %s", typ, commitID)
- }
- c, err = CommitFromReader(commit.repo, MustIDFromString(commitID), io.LimitReader(batchReader, size))
- if err != nil {
- return nil, err
- }
- if _, err := batchReader.Discard(1); err != nil {
- return nil, err
- }
- commitCommits[path] = c
- }
-
- return commitCommits, nil
-}
diff --git a/modules/git/commit_info_test.go b/modules/git/commit_info_test.go
index 1e331fac00..898ac6b13a 100644
--- a/modules/git/commit_info_test.go
+++ b/modules/git/commit_info_test.go
@@ -4,12 +4,12 @@
package git
import (
- "context"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
const (
@@ -57,7 +57,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
for _, testCase := range testCases {
commit, err := repo1.GetCommit(testCase.CommitID)
if err != nil {
- assert.NoError(t, err, "Unable to get commit: %s from testcase due to error: %v", testCase.CommitID, err)
+ require.NoError(t, err, "Unable to get commit: %s from testcase due to error: %v", testCase.CommitID, err)
// no point trying to do anything else for this test.
continue
}
@@ -67,7 +67,7 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
tree, err := commit.Tree.SubTree(testCase.Path)
if err != nil {
- assert.NoError(t, err, "Unable to get subtree: %s of commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
+ require.NoError(t, err, "Unable to get subtree: %s of commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
// no point trying to do anything else for this test.
continue
}
@@ -77,14 +77,14 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
entries, err := tree.ListEntries()
if err != nil {
- assert.NoError(t, err, "Unable to get entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
+ require.NoError(t, err, "Unable to get entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
// no point trying to do anything else for this test.
continue
}
// FIXME: Context.TODO() - if graceful has started we should use its Shutdown context otherwise use install signals in TestMain.
- commitsInfo, treeCommit, err := entries.GetCommitsInfo(context.TODO(), commit, testCase.Path)
- assert.NoError(t, err, "Unable to get commit information for entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
+ commitsInfo, treeCommit, err := entries.GetCommitsInfo(t.Context(), commit, testCase.Path)
+ require.NoError(t, err, "Unable to get commit information for entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
if err != nil {
t.FailNow()
}
@@ -105,18 +105,18 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
func TestEntries_GetCommitsInfo(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
testGetCommitsInfo(t, bareRepo1)
clonedPath, err := cloneRepo(t, bareRepo1Path)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
}
clonedRepo1, err := openRepositoryWithDefaultContext(clonedPath)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
}
defer clonedRepo1.Close()
@@ -160,7 +160,7 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
b.ResetTimer()
b.Run(benchmark.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
- _, _, err := entries.GetCommitsInfo(context.Background(), commit, "")
+ _, _, err := entries.GetCommitsInfo(b.Context(), commit, "")
if err != nil {
b.Fatal(err)
}
diff --git a/modules/git/commit_reader.go b/modules/git/commit_reader.go
index 8e2523d7fb..ec8989f5a7 100644
--- a/modules/git/commit_reader.go
+++ b/modules/git/commit_reader.go
@@ -85,6 +85,8 @@ readLoop:
_, _ = payloadSB.Write(line)
case "encoding":
_, _ = payloadSB.Write(line)
+ case "change-id": // jj-vcs specific header.
+ _, _ = payloadSB.Write(line)
case "gpgsig":
fallthrough
case "gpgsig-sha256": // FIXME: no intertop, so only 1 exists at present.
diff --git a/modules/git/commit_sha256_test.go b/modules/git/commit_sha256_test.go
index a4309519cf..9e56829f45 100644
--- a/modules/git/commit_sha256_test.go
+++ b/modules/git/commit_sha256_test.go
@@ -1,8 +1,6 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !gogit
-
package git
import (
@@ -11,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCommitsCountSha256(t *testing.T) {
@@ -24,7 +23,7 @@ func TestCommitsCountSha256(t *testing.T) {
Revision: []string{"f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc"},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(3), commitsCount)
}
@@ -40,7 +39,7 @@ func TestCommitsCountWithoutBaseSha256(t *testing.T) {
Revision: []string{"branch1"},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(2), commitsCount)
}
@@ -50,7 +49,7 @@ func TestGetFullCommitIDSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "f004f4")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc", id)
}
@@ -98,12 +97,12 @@ signed commit`
0x5d, 0x3e, 0x69, 0xd3, 0x1b, 0x78, 0x60, 0x87, 0x77, 0x5e, 0x28, 0xc6, 0xb6, 0x39, 0x9d, 0xf0,
}
gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare_sha256"))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString))
- assert.NoError(t, err)
+ require.NoError(t, err)
if !assert.NotNil(t, commitFromReader) {
return
}
@@ -134,7 +133,7 @@ signed commit`, commitFromReader.Signature.Payload)
assert.EqualValues(t, "Adam Majer ", commitFromReader.Author.String())
commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n"))
- assert.NoError(t, err)
+ require.NoError(t, err)
commitFromReader.CommitMessage += "\n\n"
commitFromReader.Signature.Payload += "\n\n"
assert.EqualValues(t, commitFromReader, commitFromReader2)
@@ -146,30 +145,30 @@ func TestHasPreviousCommitSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare_sha256")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
commit, err := repo.GetCommit("f004f41359117d319dedd0eaab8c5259ee2263da839dcba33637997458627fdc")
- assert.NoError(t, err)
+ require.NoError(t, err)
objectFormat, err := repo.GetObjectFormat()
- assert.NoError(t, err)
+ require.NoError(t, err)
parentSHA := MustIDFromString("b0ec7af4547047f12d5093e37ef8f1b3b5415ed8ee17894d43a34d7d34212e9c")
notParentSHA := MustIDFromString("42e334efd04cd36eea6da0599913333c26116e1a537ca76e5b6e4af4dda00236")
- assert.Equal(t, objectFormat, parentSHA.Type())
- assert.Equal(t, objectFormat.Name(), "sha256")
+ assert.Equal(t, parentSHA.Type(), objectFormat)
+ assert.Equal(t, "sha256", objectFormat.Name())
haz, err := commit.HasPreviousCommit(parentSHA)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, haz)
hazNot, err := commit.HasPreviousCommit(notParentSHA)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, hazNot)
selfNot, err := commit.HasPreviousCommit(commit.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, selfNot)
}
@@ -179,7 +178,7 @@ func TestGetCommitFileStatusMergesSha256(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo6_merge_sha256")
commitFileStatus, err := GetCommitFileStatus(DefaultContext, bareRepo1Path, "d2e5609f630dd8db500f5298d05d16def282412e3e66ed68cc7d0833b29129a1")
- assert.NoError(t, err)
+ require.NoError(t, err)
expected := CommitFileStatus{
[]string{
@@ -204,7 +203,7 @@ func TestGetCommitFileStatusMergesSha256(t *testing.T) {
}
commitFileStatus, err = GetCommitFileStatus(DefaultContext, bareRepo1Path, "da1ded40dc8e5b7c564171f4bf2fc8370487decfb1cb6a99ef28f3ed73d09172")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected.Added, commitFileStatus.Added)
assert.Equal(t, expected.Removed, commitFileStatus.Removed)
diff --git a/modules/git/commit_test.go b/modules/git/commit_test.go
index 01c628fb80..6b3a364d22 100644
--- a/modules/git/commit_test.go
+++ b/modules/git/commit_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCommitsCount(t *testing.T) {
@@ -20,7 +21,7 @@ func TestCommitsCount(t *testing.T) {
Revision: []string{"8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(3), commitsCount)
}
@@ -34,7 +35,7 @@ func TestCommitsCountWithoutBase(t *testing.T) {
Revision: []string{"branch1"},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(2), commitsCount)
}
@@ -42,7 +43,7 @@ func TestGetFullCommitID(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
id, err := GetFullCommitID(DefaultContext, bareRepo1Path, "8006ff9a")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0", id)
}
@@ -83,15 +84,13 @@ empty commit`
sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2}
gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString))
- assert.NoError(t, err)
- if !assert.NotNil(t, commitFromReader) {
- return
- }
+ require.NoError(t, err)
+ require.NotNil(t, commitFromReader)
assert.EqualValues(t, sha, commitFromReader.ID)
assert.EqualValues(t, `-----BEGIN PGP SIGNATURE-----
@@ -119,7 +118,7 @@ empty commit`, commitFromReader.Signature.Payload)
assert.EqualValues(t, "silverwind ", commitFromReader.Author.String())
commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n"))
- assert.NoError(t, err)
+ require.NoError(t, err)
commitFromReader.CommitMessage += "\n\n"
commitFromReader.Signature.Payload += "\n\n"
assert.EqualValues(t, commitFromReader, commitFromReader2)
@@ -133,7 +132,7 @@ author KN4CK3R 1711702962 +0100
committer KN4CK3R 1711702962 +0100
encoding ISO-8859-1
gpgsig -----BEGIN PGP SIGNATURE-----
-
+` + " " + `
iQGzBAABCgAdFiEE9HRrbqvYxPT8PXbefPSEkrowAa8FAmYGg7IACgkQfPSEkrow
Aa9olwv+P0HhtCM6CRvlUmPaqswRsDPNR4i66xyXGiSxdI9V5oJL7HLiQIM7KrFR
gizKa2COiGtugv8fE+TKqXKaJx6uJUJEjaBd8E9Af9PrAzjWj+A84lU6/PgPS8hq
@@ -151,15 +150,13 @@ ISO-8859-1`
sha := &Sha1Hash{0xfe, 0xaf, 0x4b, 0xa6, 0xbc, 0x63, 0x5f, 0xec, 0x44, 0x2f, 0x46, 0xdd, 0xd4, 0x51, 0x24, 0x16, 0xec, 0x43, 0xc2, 0xc2}
gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, gitRepo)
defer gitRepo.Close()
commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString))
- assert.NoError(t, err)
- if !assert.NotNil(t, commitFromReader) {
- return
- }
+ require.NoError(t, err)
+ require.NotNil(t, commitFromReader)
assert.EqualValues(t, sha, commitFromReader.ID)
assert.EqualValues(t, `-----BEGIN PGP SIGNATURE-----
@@ -186,35 +183,84 @@ ISO-8859-1`, commitFromReader.Signature.Payload)
assert.EqualValues(t, "KN4CK3R ", commitFromReader.Author.String())
commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n"))
- assert.NoError(t, err)
+ require.NoError(t, err)
commitFromReader.CommitMessage += "\n\n"
commitFromReader.Signature.Payload += "\n\n"
assert.EqualValues(t, commitFromReader, commitFromReader2)
}
+func TestCommitWithChangeIDFromReader(t *testing.T) {
+ commitString := `e66911914414b0daa85d4a428c8d607b9b249a2c commit 611
+tree efd3cbedfc360ce9f60e5f92d51221be5afb4bf0
+author Nicole Patricia Mazzuca 1746965490 +0200
+committer Nicole Patricia Mazzuca 1746965630 +0200
+change-id psyxzzozmuvvwrwnpqpvmtwntqsnwzpu
+gpgsig -----BEGIN PGP SIGNATURE-----
+` + " " + `
+ iHUEABYKAB0WIQT/T2ISZ7rMF2EbKVdDm0tNAL/2MgUCaCCUfgAKCRBDm0tNAL/2
+ Mmu/AQC0OWWHsSlfDKIArdALjDLgd00OQVbP+6iYVE9e+rorFwEA5qYVAXD60EHB
+ +7UVcfwZ2jKajkk3q01VyT/CDo3LLQE=
+ =yq2Y
+ -----END PGP SIGNATURE-----
+
+views: first commit!
+
+includes a basic month view, and prints a nice view of an imaginary
+January where the year starts on a Monday :)`
+
+ sha := &Sha1Hash{0xe6, 0x69, 0x11, 0x91, 0x44, 0x14, 0xb0, 0xda, 0xa8, 0x5d, 0x4a, 0x42, 0x8c, 0x8d, 0x60, 0x7b, 0x9b, 0x24, 0x9a, 0x2c}
+ gitRepo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
+ require.NoError(t, err)
+ assert.NotNil(t, gitRepo)
+ defer gitRepo.Close()
+
+ commitFromReader, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString))
+ require.NoError(t, err)
+ require.NotNil(t, commitFromReader)
+ assert.EqualValues(t, sha, commitFromReader.ID)
+ assert.Equal(t, `-----BEGIN PGP SIGNATURE-----
+
+iHUEABYKAB0WIQT/T2ISZ7rMF2EbKVdDm0tNAL/2MgUCaCCUfgAKCRBDm0tNAL/2
+Mmu/AQC0OWWHsSlfDKIArdALjDLgd00OQVbP+6iYVE9e+rorFwEA5qYVAXD60EHB
++7UVcfwZ2jKajkk3q01VyT/CDo3LLQE=
+=yq2Y
+-----END PGP SIGNATURE-----
+`, commitFromReader.Signature.Signature)
+ assert.Equal(t, `tree efd3cbedfc360ce9f60e5f92d51221be5afb4bf0
+author Nicole Patricia Mazzuca 1746965490 +0200
+committer Nicole Patricia Mazzuca 1746965630 +0200
+change-id psyxzzozmuvvwrwnpqpvmtwntqsnwzpu
+
+views: first commit!
+
+includes a basic month view, and prints a nice view of an imaginary
+January where the year starts on a Monday :)`, commitFromReader.Signature.Payload)
+ assert.Equal(t, "Nicole Patricia Mazzuca ", commitFromReader.Author.String())
+}
+
func TestHasPreviousCommit(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
commit, err := repo.GetCommit("8006ff9adbf0cb94da7dad9e537e53817f9fa5c0")
- assert.NoError(t, err)
+ require.NoError(t, err)
parentSHA := MustIDFromString("8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2")
notParentSHA := MustIDFromString("2839944139e0de9737a044f78b0e4b40d989a9e3")
haz, err := commit.HasPreviousCommit(parentSHA)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, haz)
hazNot, err := commit.HasPreviousCommit(notParentSHA)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, hazNot)
selfNot, err := commit.HasPreviousCommit(commit.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, selfNot)
}
@@ -327,7 +373,7 @@ func TestGetCommitFileStatusMerges(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo6_merge")
commitFileStatus, err := GetCommitFileStatus(DefaultContext, bareRepo1Path, "022f4ce6214973e018f02bf363bf8a2e3691f699")
- assert.NoError(t, err)
+ require.NoError(t, err)
expected := CommitFileStatus{
[]string{
@@ -341,9 +387,9 @@ func TestGetCommitFileStatusMerges(t *testing.T) {
},
}
- assert.Equal(t, commitFileStatus.Added, expected.Added)
- assert.Equal(t, commitFileStatus.Removed, expected.Removed)
- assert.Equal(t, commitFileStatus.Modified, expected.Modified)
+ assert.Equal(t, expected.Added, commitFileStatus.Added)
+ assert.Equal(t, expected.Removed, commitFileStatus.Removed)
+ assert.Equal(t, expected.Modified, commitFileStatus.Modified)
}
func TestParseCommitRenames(t *testing.T) {
@@ -372,3 +418,33 @@ func TestParseCommitRenames(t *testing.T) {
assert.Equal(t, testcase.renames, renames)
}
}
+
+func Test_parseSubmoduleContent(t *testing.T) {
+ submoduleFiles := []struct {
+ fileContent string
+ expectedPath string
+ expectedURL string
+ }{
+ {
+ fileContent: `[submodule "jakarta-servlet"]
+url = ../../ALP-pool/jakarta-servlet
+path = jakarta-servlet`,
+ expectedPath: "jakarta-servlet",
+ expectedURL: "../../ALP-pool/jakarta-servlet",
+ },
+ {
+ fileContent: `[submodule "jakarta-servlet"]
+path = jakarta-servlet
+url = ../../ALP-pool/jakarta-servlet`,
+ expectedPath: "jakarta-servlet",
+ expectedURL: "../../ALP-pool/jakarta-servlet",
+ },
+ }
+ for _, kase := range submoduleFiles {
+ submodule, err := parseSubmoduleContent([]byte(kase.fileContent))
+ require.NoError(t, err)
+ v, ok := submodule.Get(kase.expectedPath)
+ assert.True(t, ok)
+ assert.Equal(t, kase.expectedURL, v)
+ }
+}
diff --git a/modules/git/diff.go b/modules/git/diff.go
index 10ef3d83fb..0ba9c60912 100644
--- a/modules/git/diff.go
+++ b/modules/git/diff.go
@@ -14,7 +14,7 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
)
// RawDiffType type of a raw diff.
@@ -64,7 +64,10 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff
} else if commit.ParentCount() == 0 {
cmd.AddArguments("show").AddDynamicArguments(endCommit).AddDashesAndList(files...)
} else {
- c, _ := commit.Parent(0)
+ c, err := commit.Parent(0)
+ if err != nil {
+ return err
+ }
cmd.AddArguments("diff", "-M").AddDynamicArguments(c.ID.String(), endCommit).AddDashesAndList(files...)
}
case RawDiffPatch:
@@ -74,7 +77,10 @@ func GetRepoRawDiffForFile(repo *Repository, startCommit, endCommit string, diff
} else if commit.ParentCount() == 0 {
cmd.AddArguments("format-patch", "--no-signature", "--stdout", "--root").AddDynamicArguments(endCommit).AddDashesAndList(files...)
} else {
- c, _ := commit.Parent(0)
+ c, err := commit.Parent(0)
+ if err != nil {
+ return err
+ }
query := fmt.Sprintf("%s...%s", endCommit, c.ID.String())
cmd.AddArguments("format-patch", "--no-signature", "--stdout").AddDynamicArguments(query).AddDashesAndList(files...)
}
@@ -272,6 +278,17 @@ func CutDiffAroundLine(originalDiff io.Reader, line int64, old bool, numbersOfLi
// GetAffectedFiles returns the affected files between two commits
func GetAffectedFiles(repo *Repository, oldCommitID, newCommitID string, env []string) ([]string, error) {
+ objectFormat, err := repo.GetObjectFormat()
+ if err != nil {
+ return nil, err
+ }
+
+ // If the oldCommitID is empty, then we must assume its a new branch, so diff
+ // against the empty tree. So all changes of this new branch are included.
+ if oldCommitID == objectFormat.EmptyObjectID().String() {
+ oldCommitID = objectFormat.EmptyTree().String()
+ }
+
stdoutReader, stdoutWriter, err := os.Pipe()
if err != nil {
log.Error("Unable to create os.Pipe for %s", repo.Path)
diff --git a/modules/git/diff_test.go b/modules/git/diff_test.go
index 8fa47a943c..0855a7de1c 100644
--- a/modules/git/diff_test.go
+++ b/modules/git/diff_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
const exampleDiff = `diff --git a/README.md b/README.md
@@ -81,7 +82,7 @@ index d46c152..a7d2d55 100644
func TestCutDiffAroundLineIssue17875(t *testing.T) {
result, err := CutDiffAroundLine(strings.NewReader(issue17875Diff), 23, false, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
expected := `diff --git a/Geschรคftsordnung.md b/Geschรคftsordnung.md
--- a/Geschรคftsordnung.md
+++ b/Geschรคftsordnung.md
@@ -94,7 +95,7 @@ func TestCutDiffAroundLineIssue17875(t *testing.T) {
func TestCutDiffAroundLine(t *testing.T) {
result, err := CutDiffAroundLine(strings.NewReader(exampleDiff), 4, false, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
resultByLine := strings.Split(result, "\n")
assert.Len(t, resultByLine, 7)
// Check if headers got transferred
@@ -108,25 +109,25 @@ func TestCutDiffAroundLine(t *testing.T) {
// Must be same result as before since old line 3 == new line 5
newResult, err := CutDiffAroundLine(strings.NewReader(exampleDiff), 3, true, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, result, newResult, "Must be same result as before since old line 3 == new line 5")
newResult, err = CutDiffAroundLine(strings.NewReader(exampleDiff), 6, false, 300)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, exampleDiff, newResult)
emptyResult, err := CutDiffAroundLine(strings.NewReader(exampleDiff), 6, false, 0)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, emptyResult)
// Line is out of scope
emptyResult, err = CutDiffAroundLine(strings.NewReader(exampleDiff), 434, false, 0)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, emptyResult)
// Handle minus diffs properly
minusDiff, err := CutDiffAroundLine(strings.NewReader(breakingDiff), 2, false, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
expected := `diff --git a/aaa.sql b/aaa.sql
--- a/aaa.sql
@@ -139,7 +140,7 @@ func TestCutDiffAroundLine(t *testing.T) {
// Handle minus diffs properly
minusDiff, err = CutDiffAroundLine(strings.NewReader(breakingDiff), 3, false, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
expected = `diff --git a/aaa.sql b/aaa.sql
--- a/aaa.sql
diff --git a/modules/git/error.go b/modules/git/error.go
index 91d25eca69..427eb4a5b9 100644
--- a/modules/git/error.go
+++ b/modules/git/error.go
@@ -4,28 +4,14 @@
package git
import (
+ "context"
+ "errors"
"fmt"
"strings"
- "time"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
-// ErrExecTimeout error when exec timed out
-type ErrExecTimeout struct {
- Duration time.Duration
-}
-
-// IsErrExecTimeout if some error is ErrExecTimeout
-func IsErrExecTimeout(err error) bool {
- _, ok := err.(ErrExecTimeout)
- return ok
-}
-
-func (err ErrExecTimeout) Error() string {
- return fmt.Sprintf("execution is timeout [duration: %v]", err.Duration)
-}
-
// ErrNotExist commit not exist error
type ErrNotExist struct {
ID string
@@ -62,21 +48,6 @@ func IsErrBadLink(err error) bool {
return ok
}
-// ErrUnsupportedVersion error when required git version not matched
-type ErrUnsupportedVersion struct {
- Required string
-}
-
-// IsErrUnsupportedVersion if some error is ErrUnsupportedVersion
-func IsErrUnsupportedVersion(err error) bool {
- _, ok := err.(ErrUnsupportedVersion)
- return ok
-}
-
-func (err ErrUnsupportedVersion) Error() string {
- return fmt.Sprintf("Operation requires higher version [required: %s]", err.Required)
-}
-
// ErrBranchNotExist represents a "BranchNotExist" kind of error.
type ErrBranchNotExist struct {
Name string
@@ -185,3 +156,10 @@ func IsErrMoreThanOne(err error) bool {
func (err *ErrMoreThanOne) Error() string {
return fmt.Sprintf("ErrMoreThanOne Error: %v: %s\n%s", err.Err, err.StdErr, err.StdOut)
}
+
+func IsErrCanceledOrKilled(err error) bool {
+ // When "cancel()" a git command's context, the returned error of "Run()" could be one of them:
+ // - context.Canceled
+ // - *exec.ExitError: "signal: killed"
+ return err != nil && (errors.Is(err, context.Canceled) || err.Error() == "signal: killed")
+}
diff --git a/modules/git/foreachref/format_test.go b/modules/git/foreachref/format_test.go
index 8ff239323c..99b8207168 100644
--- a/modules/git/foreachref/format_test.go
+++ b/modules/git/foreachref/format_test.go
@@ -6,7 +6,7 @@ package foreachref_test
import (
"testing"
- "code.gitea.io/gitea/modules/git/foreachref"
+ "forgejo.org/modules/git/foreachref"
"github.com/stretchr/testify/require"
)
diff --git a/modules/git/foreachref/parser_test.go b/modules/git/foreachref/parser_test.go
index 7a37ced356..1febab80c7 100644
--- a/modules/git/foreachref/parser_test.go
+++ b/modules/git/foreachref/parser_test.go
@@ -10,8 +10,8 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/git/foreachref"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/git/foreachref"
+ "forgejo.org/modules/json"
"github.com/stretchr/testify/require"
)
diff --git a/modules/git/git.go b/modules/git/git.go
index 70232c86a0..c7d5a31b31 100644
--- a/modules/git/git.go
+++ b/modules/git/git.go
@@ -16,8 +16,8 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"github.com/hashicorp/go-version"
)
@@ -38,6 +38,8 @@ var (
InvertedGitFlushEnv bool // 2.43.1
SupportCheckAttrOnBare bool // >= 2.40
+ HasSSHExecutable bool
+
gitVersion *version.Version
)
@@ -57,15 +59,7 @@ func loadGitVersion() error {
return fmt.Errorf("invalid git version output: %s", stdout)
}
- var versionString string
-
- // Handle special case on Windows.
- i := strings.Index(fields[2], "windows")
- if i >= 1 {
- versionString = fields[2][:i-1]
- } else {
- versionString = fields[2]
- }
+ versionString := fields[2]
var err error
gitVersion, err = version.NewVersion(versionString)
@@ -95,12 +89,12 @@ func SetExecutablePath(path string) error {
}
if gitVersion.LessThan(versionRequired) {
- moreHint := "get git: https://git-scm.com/download/"
+ moreHint := "get git: https://git-scm.com/downloads"
if runtime.GOOS == "linux" {
// there are a lot of CentOS/RHEL users using old git, so we add a special hint for them
if _, err = os.Stat("/etc/redhat-release"); err == nil {
// ius.io is the recommended official(git-scm.com) method to install git
- moreHint = "get git: https://git-scm.com/download/linux and https://ius.io"
+ moreHint = "get git: https://git-scm.com/downloads/linux and https://ius.io"
}
}
return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", gitVersion.Original(), RequiredVersion, moreHint)
@@ -186,12 +180,12 @@ func InitFull(ctx context.Context) (err error) {
globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
}
SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
- SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil && !isGogit
+ SupportHashSha256 = CheckGitVersionAtLeast("2.42") == nil
SupportCheckAttrOnBare = CheckGitVersionAtLeast("2.40") == nil
if SupportHashSha256 {
SupportedObjectFormats = append(SupportedObjectFormats, Sha256ObjectFormat)
} else {
- log.Warn("sha256 hash support is disabled - requires Git >= 2.42. Gogit is currently unsupported")
+ log.Warn("sha256 hash support is disabled - requires Git >= 2.42")
}
InvertedGitFlushEnv = CheckGitVersionEqual("2.43.1") == nil
@@ -203,6 +197,10 @@ func InitFull(ctx context.Context) (err error) {
globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=", "-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
}
+ // Detect the presence of the ssh executable in $PATH.
+ _, err = exec.LookPath("ssh")
+ HasSSHExecutable = err == nil
+
return syncGitConfig()
}
@@ -274,24 +272,11 @@ func syncGitConfig() (err error) {
// Thus the owner uid/gid for files on these filesystems will be marked as root.
// As Gitea now always use its internal git config file, and access to the git repositories is managed through Gitea,
// it is now safe to set "safe.directory=*" for internal usage only.
- // Please note: the wildcard "*" is only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later
- // Although only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later - this setting is tolerated by earlier versions
+ // Please note: the wildcard "*" is only supported by Git 2.30.4/2.31.3/2.32.2/2.33.3/2.34.3/2.35.3/2.36 and later,
+ // but is tolerated by earlier versions
if err := configAddNonExist("safe.directory", "*"); err != nil {
return err
}
- if runtime.GOOS == "windows" {
- if err := configSet("core.longpaths", "true"); err != nil {
- return err
- }
- if setting.Git.DisableCoreProtectNTFS {
- err = configSet("core.protectNTFS", "false")
- } else {
- err = configUnsetAll("core.protectNTFS", "false")
- }
- if err != nil {
- return err
- }
- }
// By default partial clones are disabled, enable them from git v2.22
if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil {
diff --git a/modules/git/git_test.go b/modules/git/git_test.go
index 37ab669ea4..bb07367e3b 100644
--- a/modules/git/git_test.go
+++ b/modules/git/git_test.go
@@ -10,10 +10,11 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func testRun(m *testing.M) error {
@@ -52,33 +53,33 @@ func gitConfigContains(sub string) bool {
func TestGitConfig(t *testing.T) {
assert.False(t, gitConfigContains("key-a"))
- assert.NoError(t, configSetNonExist("test.key-a", "val-a"))
+ require.NoError(t, configSetNonExist("test.key-a", "val-a"))
assert.True(t, gitConfigContains("key-a = val-a"))
- assert.NoError(t, configSetNonExist("test.key-a", "val-a-changed"))
+ require.NoError(t, configSetNonExist("test.key-a", "val-a-changed"))
assert.False(t, gitConfigContains("key-a = val-a-changed"))
- assert.NoError(t, configSet("test.key-a", "val-a-changed"))
+ require.NoError(t, configSet("test.key-a", "val-a-changed"))
assert.True(t, gitConfigContains("key-a = val-a-changed"))
- assert.NoError(t, configAddNonExist("test.key-b", "val-b"))
+ require.NoError(t, configAddNonExist("test.key-b", "val-b"))
assert.True(t, gitConfigContains("key-b = val-b"))
- assert.NoError(t, configAddNonExist("test.key-b", "val-2b"))
+ require.NoError(t, configAddNonExist("test.key-b", "val-2b"))
assert.True(t, gitConfigContains("key-b = val-b"))
assert.True(t, gitConfigContains("key-b = val-2b"))
- assert.NoError(t, configUnsetAll("test.key-b", "val-b"))
+ require.NoError(t, configUnsetAll("test.key-b", "val-b"))
assert.False(t, gitConfigContains("key-b = val-b"))
assert.True(t, gitConfigContains("key-b = val-2b"))
- assert.NoError(t, configUnsetAll("test.key-b", "val-2b"))
+ require.NoError(t, configUnsetAll("test.key-b", "val-2b"))
assert.False(t, gitConfigContains("key-b = val-2b"))
- assert.NoError(t, configSet("test.key-x", "*"))
+ require.NoError(t, configSet("test.key-x", "*"))
assert.True(t, gitConfigContains("key-x = *"))
- assert.NoError(t, configSetNonExist("test.key-x", "*"))
- assert.NoError(t, configUnsetAll("test.key-x", "*"))
+ require.NoError(t, configSetNonExist("test.key-x", "*"))
+ require.NoError(t, configUnsetAll("test.key-x", "*"))
assert.False(t, gitConfigContains("key-x = *"))
}
@@ -89,7 +90,7 @@ func TestSyncConfig(t *testing.T) {
}()
setting.GitConfig.Options["sync-test.cfg-key-a"] = "CfgValA"
- assert.NoError(t, syncGitConfig())
+ require.NoError(t, syncGitConfig())
assert.True(t, gitConfigContains("[sync-test]"))
assert.True(t, gitConfigContains("cfg-key-a = CfgValA"))
}
diff --git a/modules/git/grep.go b/modules/git/grep.go
index 7cd1a96da6..117b09fc83 100644
--- a/modules/git/grep.go
+++ b/modules/git/grep.go
@@ -1,4 +1,5 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package git
@@ -14,23 +15,49 @@ import (
"os"
"strconv"
"strings"
+ "time"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
type GrepResult struct {
- Filename string
- LineNumbers []int
- LineCodes []string
+ Filename string
+ LineNumbers []int
+ LineCodes []string
+ HighlightedRanges [][3]int
}
+type GrepMode int
+
+const (
+ FixedGrepMode GrepMode = iota
+ FixedAnyGrepMode
+ RegExpGrepMode
+)
+
+var GrepSearchOptions = [3]string{"exact", "union", "regexp"}
+
type GrepOptions struct {
RefName string
MaxResultLimit int
- MatchesPerFile int
+ MatchesPerFile int // >= git 2.38
ContextLineNumber int
- IsFuzzy bool
- PathSpec []setting.Glob
+ Mode GrepMode
+ Filename string
+}
+
+func (opts *GrepOptions) ensureDefaults() {
+ opts.RefName = cmp.Or(opts.RefName, "HEAD")
+ opts.MaxResultLimit = cmp.Or(opts.MaxResultLimit, 50)
+ opts.MatchesPerFile = cmp.Or(opts.MatchesPerFile, 20)
+}
+
+func hasPrefixFold(s, t string) bool {
+ if len(s) < len(t) {
+ return false
+ }
+ return strings.EqualFold(s[:len(t)], t)
}
func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepOptions) ([]*GrepResult, error) {
@@ -43,46 +70,92 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
_ = stdoutWriter.Close()
}()
+ opts.ensureDefaults()
+
/*
- The output is like this ( "^@" means \x00):
+ The output is like this ("^@" means \x00; the first number denotes the line,
+ the second number denotes the column of the first match in line):
HEAD:.air.toml
- 6^@bin = "gitea"
+ 6^@8^@bin = "gitea"
HEAD:.changelog.yml
- 2^@repo: go-gitea/gitea
+ 2^@10^@repo: go-gitea/gitea
*/
var results []*GrepResult
- cmd := NewCommand(ctx, "grep", "--null", "--break", "--heading", "--fixed-strings", "--line-number", "--ignore-case", "--full-name")
- cmd.AddOptionValues("--context", fmt.Sprint(opts.ContextLineNumber))
- if opts.MatchesPerFile > 0 {
- cmd.AddOptionValues("--max-count", fmt.Sprint(opts.MatchesPerFile))
- }
- if opts.IsFuzzy {
- words := strings.Fields(search)
- for _, word := range words {
- cmd.AddOptionValues("-e", strings.TrimLeft(word, "-"))
- }
+ // -I skips binary files
+ cmd := NewCommand(ctx, "grep",
+ "-I", "--null", "--break", "--heading",
+ "--line-number", "--ignore-case", "--full-name")
+ if opts.Mode == RegExpGrepMode {
+ // No `--column` -- regexp mode does not support highlighting in the
+ // current implementation as the length of the match is unknown from
+ // `grep` but required for highlighting.
+ cmd.AddArguments("--perl-regexp")
} else {
- cmd.AddOptionValues("-e", strings.TrimLeft(search, "-"))
+ cmd.AddArguments("--fixed-strings", "--column")
+ }
+
+ cmd.AddOptionValues("--context", fmt.Sprint(opts.ContextLineNumber))
+
+ // --max-count requires at least git 2.38
+ if CheckGitVersionAtLeast("2.38.0") == nil {
+ cmd.AddOptionValues("--max-count", fmt.Sprint(opts.MatchesPerFile))
+ } else {
+ log.Warn("git-grep: --max-count requires at least git 2.38")
+ }
+
+ words := []string{search}
+ if opts.Mode == FixedAnyGrepMode {
+ words = strings.Fields(search)
+ }
+ for _, word := range words {
+ cmd.AddGitGrepExpression(word)
}
// pathspec
- files := make([]string, 0,
- len(setting.Indexer.IncludePatterns)+
- len(setting.Indexer.ExcludePatterns)+
- len(opts.PathSpec))
- for _, expr := range append(setting.Indexer.IncludePatterns, opts.PathSpec...) {
- files = append(files, ":"+expr.Pattern())
+ includeLen := len(setting.Indexer.IncludePatterns)
+ if len(opts.Filename) > 0 {
+ includeLen = 1
+ }
+ files := make([]string, 0, len(setting.Indexer.ExcludePatterns)+includeLen)
+ if len(opts.Filename) > 0 && len(setting.Indexer.IncludePatterns) > 0 {
+ // if the both a global include pattern and the per search path is defined
+ // we only include results where the path matches the globally set pattern
+ // (eg, global pattern = "src/**" and path = "node_modules/")
+
+ // FIXME: this is a bit too restrictive, and fails to consider cases where the
+ // globally set include pattern refers to a file than a directory
+ // (eg, global pattern = "**.go" and path = "modules/git")
+ exprMatched := false
+ for _, expr := range setting.Indexer.IncludePatterns {
+ if expr.Match(opts.Filename) {
+ files = append(files, ":(literal)"+opts.Filename)
+ exprMatched = true
+ break
+ }
+ }
+ if !exprMatched {
+ log.Warn("git-grep: filepath %s does not match any include pattern", opts.Filename)
+ }
+ } else if len(opts.Filename) > 0 {
+ // if the path is only set we just include results that matches it
+ files = append(files, ":(literal)"+opts.Filename)
+ } else {
+ // otherwise if global include patterns are set include results that strictly match them
+ for _, expr := range setting.Indexer.IncludePatterns {
+ files = append(files, ":"+expr.Pattern())
+ }
}
for _, expr := range setting.Indexer.ExcludePatterns {
files = append(files, ":^"+expr.Pattern())
}
- cmd.AddDynamicArguments(cmp.Or(opts.RefName, "HEAD")).AddDashesAndList(files...)
+ cmd.AddDynamicArguments(opts.RefName).AddDashesAndList(files...)
- opts.MaxResultLimit = cmp.Or(opts.MaxResultLimit, 50)
stderr := bytes.Buffer{}
err = cmd.Run(&RunOpts{
+ Timeout: time.Duration(setting.Git.Timeout.Grep) * time.Second,
+
Dir: repo.Path,
Stdout: stdoutWriter,
Stderr: &stderr,
@@ -128,6 +201,25 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
if lineNum, lineCode, ok := strings.Cut(line, "\x00"); ok {
lineNumInt, _ := strconv.Atoi(lineNum)
res.LineNumbers = append(res.LineNumbers, lineNumInt)
+ // We support highlighting only when `--column` parameter is used.
+ if lineCol, lineCode2, ok := strings.Cut(lineCode, "\x00"); ok {
+ lineColInt, _ := strconv.Atoi(lineCol)
+ start := lineColInt - 1
+ matchLen := len(lineCode2)
+ for _, word := range words {
+ if hasPrefixFold(lineCode2[start:], word) {
+ matchLen = len(word)
+ break
+ }
+ }
+ res.HighlightedRanges = append(res.HighlightedRanges, [3]int{
+ len(res.LineCodes),
+ start,
+ start + matchLen,
+ })
+ res.LineCodes = append(res.LineCodes, lineCode2)
+ continue
+ }
res.LineCodes = append(res.LineCodes, lineCode)
}
}
diff --git a/modules/git/grep_test.go b/modules/git/grep_test.go
index d2ed7300c1..534468e268 100644
--- a/modules/git/grep_test.go
+++ b/modules/git/grep_test.go
@@ -5,99 +5,182 @@ package git
import (
"bytes"
- "context"
"os"
"path"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGrepSearch(t *testing.T) {
repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "language_stats_repo"))
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
- res, err := GrepSearch(context.Background(), repo, "void", GrepOptions{})
- assert.NoError(t, err)
+ res, err := GrepSearch(t.Context(), repo, "public", GrepOptions{})
+ require.NoError(t, err)
assert.Equal(t, []*GrepResult{
{
Filename: "java-hello/main.java",
- LineNumbers: []int{3},
- LineCodes: []string{" public static void main(String[] args)"},
+ LineNumbers: []int{1, 3},
+ LineCodes: []string{
+ "public class HelloWorld",
+ " public static void main(String[] args)",
+ },
+ HighlightedRanges: [][3]int{{0, 0, 6}, {1, 1, 7}},
},
{
Filename: "main.vendor.java",
- LineNumbers: []int{3},
- LineCodes: []string{" public static void main(String[] args)"},
+ LineNumbers: []int{1, 3},
+ LineCodes: []string{
+ "public class HelloWorld",
+ " public static void main(String[] args)",
+ },
+ HighlightedRanges: [][3]int{{0, 0, 6}, {1, 1, 7}},
},
}, res)
- res, err = GrepSearch(context.Background(), repo, "void", GrepOptions{MaxResultLimit: 1})
- assert.NoError(t, err)
+ res, err = GrepSearch(t.Context(), repo, "void", GrepOptions{MaxResultLimit: 1, ContextLineNumber: 2})
+ require.NoError(t, err)
assert.Equal(t, []*GrepResult{
{
Filename: "java-hello/main.java",
- LineNumbers: []int{3},
- LineCodes: []string{" public static void main(String[] args)"},
+ LineNumbers: []int{1, 2, 3, 4, 5},
+ LineCodes: []string{
+ "public class HelloWorld",
+ "{",
+ " public static void main(String[] args)",
+ " {",
+ " System.out.println(\"Hello world!\");",
+ },
+ HighlightedRanges: [][3]int{{2, 15, 19}},
},
}, res)
- res, err = GrepSearch(context.Background(), repo, "world", GrepOptions{MatchesPerFile: 1})
- assert.NoError(t, err)
+ res, err = GrepSearch(t.Context(), repo, "world", GrepOptions{MatchesPerFile: 1})
+ require.NoError(t, err)
assert.Equal(t, []*GrepResult{
{
- Filename: "i-am-a-python.p",
- LineNumbers: []int{1},
- LineCodes: []string{"## This is a simple file to do a hello world"},
+ Filename: "i-am-a-python.p",
+ LineNumbers: []int{1},
+ LineCodes: []string{"## This is a simple file to do a hello world"},
+ HighlightedRanges: [][3]int{{0, 39, 44}},
},
{
- Filename: "java-hello/main.java",
- LineNumbers: []int{1},
- LineCodes: []string{"public class HelloWorld"},
+ Filename: "java-hello/main.java",
+ LineNumbers: []int{1},
+ LineCodes: []string{"public class HelloWorld"},
+ HighlightedRanges: [][3]int{{0, 18, 23}},
},
{
- Filename: "main.vendor.java",
- LineNumbers: []int{1},
- LineCodes: []string{"public class HelloWorld"},
+ Filename: "main.vendor.java",
+ LineNumbers: []int{1},
+ LineCodes: []string{"public class HelloWorld"},
+ HighlightedRanges: [][3]int{{0, 18, 23}},
},
{
- Filename: "python-hello/hello.py",
- LineNumbers: []int{1},
- LineCodes: []string{"## This is a simple file to do a hello world"},
+ Filename: "python-hello/hello.py",
+ LineNumbers: []int{1},
+ LineCodes: []string{"## This is a simple file to do a hello world"},
+ HighlightedRanges: [][3]int{{0, 39, 44}},
},
}, res)
- res, err = GrepSearch(context.Background(), repo, "no-such-content", GrepOptions{})
- assert.NoError(t, err)
- assert.Len(t, res, 0)
+ res, err = GrepSearch(t.Context(), repo, "world", GrepOptions{
+ MatchesPerFile: 1,
+ Filename: "java-hello/",
+ })
+ require.NoError(t, err)
+ assert.Equal(t, []*GrepResult{
+ {
+ Filename: "java-hello/main.java",
+ LineNumbers: []int{1},
+ LineCodes: []string{"public class HelloWorld"},
+ HighlightedRanges: [][3]int{{0, 18, 23}},
+ },
+ }, res)
- res, err = GrepSearch(context.Background(), &Repository{Path: "no-such-git-repo"}, "no-such-content", GrepOptions{})
- assert.Error(t, err)
- assert.Len(t, res, 0)
+ res, err = GrepSearch(t.Context(), repo, "no-such-content", GrepOptions{})
+ require.NoError(t, err)
+ assert.Empty(t, res)
+
+ res, err = GrepSearch(t.Context(), &Repository{Path: "no-such-git-repo"}, "no-such-content", GrepOptions{})
+ require.Error(t, err)
+ assert.Empty(t, res)
+}
+
+func TestGrepDashesAreFine(t *testing.T) {
+ tmpDir := t.TempDir()
+
+ err := InitRepository(DefaultContext, tmpDir, false, Sha1ObjectFormat.Name())
+ require.NoError(t, err)
+
+ gitRepo, err := openRepositoryWithDefaultContext(tmpDir)
+ require.NoError(t, err)
+ defer gitRepo.Close()
+
+ require.NoError(t, os.WriteFile(path.Join(tmpDir, "with-dashes"), []byte("--"), 0o666))
+ require.NoError(t, os.WriteFile(path.Join(tmpDir, "without-dashes"), []byte(".."), 0o666))
+
+ err = AddChanges(tmpDir, true)
+ require.NoError(t, err)
+
+ err = CommitChanges(tmpDir, CommitChangesOptions{Message: "Dashes are cool sometimes"})
+ require.NoError(t, err)
+
+ res, err := GrepSearch(t.Context(), gitRepo, "--", GrepOptions{})
+ require.NoError(t, err)
+ assert.Len(t, res, 1)
+ assert.Equal(t, "with-dashes", res[0].Filename)
+}
+
+func TestGrepNoBinary(t *testing.T) {
+ tmpDir := t.TempDir()
+
+ err := InitRepository(DefaultContext, tmpDir, false, Sha1ObjectFormat.Name())
+ require.NoError(t, err)
+
+ gitRepo, err := openRepositoryWithDefaultContext(tmpDir)
+ require.NoError(t, err)
+ defer gitRepo.Close()
+
+ require.NoError(t, os.WriteFile(path.Join(tmpDir, "BINARY"), []byte("I AM BINARY\n\x00\nYOU WON'T SEE ME"), 0o666))
+ require.NoError(t, os.WriteFile(path.Join(tmpDir, "TEXT"), []byte("I AM NOT BINARY\nYOU WILL SEE ME"), 0o666))
+
+ err = AddChanges(tmpDir, true)
+ require.NoError(t, err)
+
+ err = CommitChanges(tmpDir, CommitChangesOptions{Message: "Binary and text files"})
+ require.NoError(t, err)
+
+ res, err := GrepSearch(t.Context(), gitRepo, "BINARY", GrepOptions{})
+ require.NoError(t, err)
+ assert.Len(t, res, 1)
+ assert.Equal(t, "TEXT", res[0].Filename)
}
func TestGrepLongFiles(t *testing.T) {
tmpDir := t.TempDir()
err := InitRepository(DefaultContext, tmpDir, false, Sha1ObjectFormat.Name())
- assert.NoError(t, err)
+ require.NoError(t, err)
gitRepo, err := openRepositoryWithDefaultContext(tmpDir)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer gitRepo.Close()
- assert.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), bytes.Repeat([]byte{'a'}, 65*1024), 0o666))
+ require.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), bytes.Repeat([]byte{'a'}, 65*1024), 0o666))
err = AddChanges(tmpDir, true)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "Long file"})
- assert.NoError(t, err)
+ require.NoError(t, err)
- res, err := GrepSearch(context.Background(), gitRepo, "a", GrepOptions{})
- assert.NoError(t, err)
+ res, err := GrepSearch(t.Context(), gitRepo, "a", GrepOptions{})
+ require.NoError(t, err)
assert.Len(t, res, 1)
assert.Len(t, res[0].LineCodes[0], 65*1024)
}
@@ -106,28 +189,59 @@ func TestGrepRefs(t *testing.T) {
tmpDir := t.TempDir()
err := InitRepository(DefaultContext, tmpDir, false, Sha1ObjectFormat.Name())
- assert.NoError(t, err)
+ require.NoError(t, err)
gitRepo, err := openRepositoryWithDefaultContext(tmpDir)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer gitRepo.Close()
- assert.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), []byte{'A'}, 0o666))
- assert.NoError(t, AddChanges(tmpDir, true))
+ require.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), []byte{'A'}, 0o666))
+ require.NoError(t, AddChanges(tmpDir, true))
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "add A"})
- assert.NoError(t, err)
+ require.NoError(t, err)
- assert.NoError(t, gitRepo.CreateTag("v1", "HEAD"))
+ require.NoError(t, gitRepo.CreateTag("v1", "HEAD"))
- assert.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), []byte{'A', 'B', 'C', 'D'}, 0o666))
- assert.NoError(t, AddChanges(tmpDir, true))
+ require.NoError(t, os.WriteFile(path.Join(tmpDir, "README.md"), []byte{'A', 'B', 'C', 'D'}, 0o666))
+ require.NoError(t, AddChanges(tmpDir, true))
err = CommitChanges(tmpDir, CommitChangesOptions{Message: "add BCD"})
- assert.NoError(t, err)
+ require.NoError(t, err)
- res, err := GrepSearch(context.Background(), gitRepo, "a", GrepOptions{RefName: "v1"})
- assert.NoError(t, err)
+ res, err := GrepSearch(t.Context(), gitRepo, "a", GrepOptions{RefName: "v1"})
+ require.NoError(t, err)
assert.Len(t, res, 1)
- assert.Equal(t, res[0].LineCodes[0], "A")
+ assert.Equal(t, "A", res[0].LineCodes[0])
+}
+
+func TestGrepCanHazRegexOnDemand(t *testing.T) {
+ tmpDir := t.TempDir()
+
+ err := InitRepository(DefaultContext, tmpDir, false, Sha1ObjectFormat.Name())
+ require.NoError(t, err)
+
+ gitRepo, err := openRepositoryWithDefaultContext(tmpDir)
+ require.NoError(t, err)
+ defer gitRepo.Close()
+
+ require.NoError(t, os.WriteFile(path.Join(tmpDir, "matching"), []byte("It's a match!"), 0o666))
+ require.NoError(t, os.WriteFile(path.Join(tmpDir, "not-matching"), []byte("Orisitamatch?"), 0o666))
+
+ err = AddChanges(tmpDir, true)
+ require.NoError(t, err)
+
+ err = CommitChanges(tmpDir, CommitChangesOptions{Message: "Add fixtures for regexp test"})
+ require.NoError(t, err)
+
+ // should find nothing by default...
+ res, err := GrepSearch(t.Context(), gitRepo, "\\bmatch\\b", GrepOptions{})
+ require.NoError(t, err)
+ assert.Empty(t, res)
+
+ // ... unless configured explicitly
+ res, err = GrepSearch(t.Context(), gitRepo, "\\bmatch\\b", GrepOptions{Mode: RegExpGrepMode})
+ require.NoError(t, err)
+ assert.Len(t, res, 1)
+ assert.Equal(t, "matching", res[0].Filename)
}
diff --git a/modules/git/hook.go b/modules/git/hook.go
index 46f93ce13e..bef4d024c8 100644
--- a/modules/git/hook.go
+++ b/modules/git/hook.go
@@ -11,8 +11,8 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
// hookNames is a list of Git server hooks' name that are supported.
diff --git a/modules/git/last_commit_cache.go b/modules/git/last_commit_cache.go
index 5b62b90b27..1d7e74a0d7 100644
--- a/modules/git/last_commit_cache.go
+++ b/modules/git/last_commit_cache.go
@@ -4,11 +4,12 @@
package git
import (
+ "context"
"crypto/sha256"
"fmt"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
// Cache represents a caching interface
@@ -112,3 +113,47 @@ func (c *LastCommitCache) GetCommitByPath(commitID, entryPath string) (*Commit,
return lastCommit, nil
}
+
+// CacheCommit will cache the commit from the gitRepository
+func (c *Commit) CacheCommit(ctx context.Context) error {
+ if c.repo.LastCommitCache == nil {
+ return nil
+ }
+ return c.recursiveCache(ctx, &c.Tree, "", 1)
+}
+
+func (c *Commit) recursiveCache(ctx context.Context, tree *Tree, treePath string, level int) error {
+ if level == 0 {
+ return nil
+ }
+
+ entries, err := tree.ListEntries()
+ if err != nil {
+ return err
+ }
+
+ entryPaths := make([]string, len(entries))
+ for i, entry := range entries {
+ entryPaths[i] = entry.Name()
+ }
+
+ _, err = WalkGitLog(ctx, c.repo, c, treePath, entryPaths...)
+ if err != nil {
+ return err
+ }
+
+ for _, treeEntry := range entries {
+ // entryMap won't contain "" therefore skip this.
+ if treeEntry.IsDir() {
+ subTree, err := tree.SubTree(treeEntry.Name())
+ if err != nil {
+ return err
+ }
+ if err := c.recursiveCache(ctx, subTree, treeEntry.Name(), level-1); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
diff --git a/modules/git/last_commit_cache_gogit.go b/modules/git/last_commit_cache_gogit.go
deleted file mode 100644
index 3afc213094..0000000000
--- a/modules/git/last_commit_cache_gogit.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "context"
-
- "github.com/go-git/go-git/v5/plumbing"
- cgobject "github.com/go-git/go-git/v5/plumbing/object/commitgraph"
-)
-
-// CacheCommit will cache the commit from the gitRepository
-func (c *Commit) CacheCommit(ctx context.Context) error {
- if c.repo.LastCommitCache == nil {
- return nil
- }
- commitNodeIndex, _ := c.repo.CommitNodeIndex()
-
- index, err := commitNodeIndex.Get(plumbing.Hash(c.ID.RawValue()))
- if err != nil {
- return err
- }
-
- return c.recursiveCache(ctx, index, &c.Tree, "", 1)
-}
-
-func (c *Commit) recursiveCache(ctx context.Context, index cgobject.CommitNode, tree *Tree, treePath string, level int) error {
- if level == 0 {
- return nil
- }
-
- entries, err := tree.ListEntries()
- if err != nil {
- return err
- }
-
- entryPaths := make([]string, len(entries))
- entryMap := make(map[string]*TreeEntry)
- for i, entry := range entries {
- entryPaths[i] = entry.Name()
- entryMap[entry.Name()] = entry
- }
-
- commits, err := GetLastCommitForPaths(ctx, c.repo.LastCommitCache, index, treePath, entryPaths)
- if err != nil {
- return err
- }
-
- for entry := range commits {
- if entryMap[entry].IsDir() {
- subTree, err := tree.SubTree(entry)
- if err != nil {
- return err
- }
- if err := c.recursiveCache(ctx, index, subTree, entry, level-1); err != nil {
- return err
- }
- }
- }
-
- return nil
-}
diff --git a/modules/git/last_commit_cache_nogogit.go b/modules/git/last_commit_cache_nogogit.go
deleted file mode 100644
index 155cb3cb7c..0000000000
--- a/modules/git/last_commit_cache_nogogit.go
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "context"
-)
-
-// CacheCommit will cache the commit from the gitRepository
-func (c *Commit) CacheCommit(ctx context.Context) error {
- if c.repo.LastCommitCache == nil {
- return nil
- }
- return c.recursiveCache(ctx, &c.Tree, "", 1)
-}
-
-func (c *Commit) recursiveCache(ctx context.Context, tree *Tree, treePath string, level int) error {
- if level == 0 {
- return nil
- }
-
- entries, err := tree.ListEntries()
- if err != nil {
- return err
- }
-
- entryPaths := make([]string, len(entries))
- for i, entry := range entries {
- entryPaths[i] = entry.Name()
- }
-
- _, err = WalkGitLog(ctx, c.repo, c, treePath, entryPaths...)
- if err != nil {
- return err
- }
-
- for _, treeEntry := range entries {
- // entryMap won't contain "" therefore skip this.
- if treeEntry.IsDir() {
- subTree, err := tree.SubTree(treeEntry.Name())
- if err != nil {
- return err
- }
- if err := c.recursiveCache(ctx, subTree, treeEntry.Name(), level-1); err != nil {
- return err
- }
- }
- }
-
- return nil
-}
diff --git a/modules/git/log_name_status.go b/modules/git/log_name_status.go
index 9e345f3ee0..e98e8c19a3 100644
--- a/modules/git/log_name_status.go
+++ b/modules/git/log_name_status.go
@@ -13,7 +13,7 @@ import (
"sort"
"strings"
- "code.gitea.io/gitea/modules/container"
+ "forgejo.org/modules/container"
"github.com/djherbis/buffer"
"github.com/djherbis/nio/v3"
@@ -114,7 +114,7 @@ type LogNameStatusCommitData struct {
// Next returns the next LogStatusCommitData
func (g *LogNameStatusRepoParser) Next(treepath string, paths2ids map[string]int, changed []bool, maxpathlen int) (*LogNameStatusCommitData, error) {
var err error
- if g.next == nil || len(g.next) == 0 {
+ if len(g.next) == 0 {
g.buffull = false
g.next, err = g.rd.ReadSlice('\x00')
if err != nil {
diff --git a/modules/git/notes.go b/modules/git/notes.go
index 63539cb3a2..c36ab87fbd 100644
--- a/modules/git/notes.go
+++ b/modules/git/notes.go
@@ -3,6 +3,15 @@
package git
+import (
+ "context"
+ "io"
+ "os"
+ "strings"
+
+ "forgejo.org/modules/log"
+)
+
// NotesRef is the git ref where Gitea will look for git-notes data.
// The value ("refs/notes/commits") is the default ref used by git-notes.
const NotesRef = "refs/notes/commits"
@@ -12,3 +21,118 @@ type Note struct {
Message []byte
Commit *Commit
}
+
+// GetNote retrieves the git-notes data for a given commit.
+// FIXME: Add LastCommitCache support
+func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error {
+ log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
+ notes, err := repo.GetCommit(NotesRef)
+ if err != nil {
+ if IsErrNotExist(err) {
+ return err
+ }
+ log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
+ return err
+ }
+
+ path := ""
+
+ tree := ¬es.Tree
+ log.Trace("Found tree with ID %q while searching for git note corresponding to the commit %q", tree.ID, commitID)
+
+ var entry *TreeEntry
+ originalCommitID := commitID
+ for len(commitID) > 2 {
+ entry, err = tree.GetTreeEntryByPath(commitID)
+ if err == nil {
+ path += commitID
+ break
+ }
+ if IsErrNotExist(err) {
+ tree, err = tree.SubTree(commitID[0:2])
+ path += commitID[0:2] + "/"
+ commitID = commitID[2:]
+ }
+ if err != nil {
+ // Err may have been updated by the SubTree we need to recheck if it's again an ErrNotExist
+ if !IsErrNotExist(err) {
+ log.Error("Unable to find git note corresponding to the commit %q. Error: %v", originalCommitID, err)
+ }
+ return err
+ }
+ }
+
+ blob := entry.Blob()
+ dataRc, err := blob.DataAsync()
+ if err != nil {
+ log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
+ return err
+ }
+ closed := false
+ defer func() {
+ if !closed {
+ _ = dataRc.Close()
+ }
+ }()
+ d, err := io.ReadAll(dataRc)
+ if err != nil {
+ log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
+ return err
+ }
+ _ = dataRc.Close()
+ closed = true
+ note.Message = d
+
+ treePath := ""
+ if idx := strings.LastIndex(path, "/"); idx > -1 {
+ treePath = path[:idx]
+ path = path[idx+1:]
+ }
+
+ lastCommits, err := GetLastCommitForPaths(ctx, notes, treePath, []string{path})
+ if err != nil {
+ log.Error("Unable to get the commit for the path %q. Error: %v", treePath, err)
+ return err
+ }
+ note.Commit = lastCommits[path]
+
+ return nil
+}
+
+func SetNote(ctx context.Context, repo *Repository, commitID, notes, doerName, doerEmail string) error {
+ _, err := repo.GetCommit(commitID)
+ if err != nil {
+ return err
+ }
+
+ env := append(os.Environ(),
+ "GIT_AUTHOR_NAME="+doerName,
+ "GIT_AUTHOR_EMAIL="+doerEmail,
+ "GIT_COMMITTER_NAME="+doerName,
+ "GIT_COMMITTER_EMAIL="+doerEmail,
+ )
+
+ cmd := NewCommand(ctx, "notes", "add", "-f", "-m")
+ cmd.AddDynamicArguments(notes, commitID)
+
+ _, stderr, err := cmd.RunStdString(&RunOpts{Dir: repo.Path, Env: env})
+ if err != nil {
+ log.Error("Error while running git notes add: %s", stderr)
+ return err
+ }
+
+ return nil
+}
+
+func RemoveNote(ctx context.Context, repo *Repository, commitID string) error {
+ cmd := NewCommand(ctx, "notes", "remove")
+ cmd.AddDynamicArguments(commitID)
+
+ _, stderr, err := cmd.RunStdString(&RunOpts{Dir: repo.Path})
+ if err != nil {
+ log.Error("Error while running git notes remove: %s", stderr)
+ return err
+ }
+
+ return nil
+}
diff --git a/modules/git/notes_gogit.go b/modules/git/notes_gogit.go
deleted file mode 100644
index f802443b00..0000000000
--- a/modules/git/notes_gogit.go
+++ /dev/null
@@ -1,89 +0,0 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "context"
- "io"
-
- "code.gitea.io/gitea/modules/log"
-
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// GetNote retrieves the git-notes data for a given commit.
-// FIXME: Add LastCommitCache support
-func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error {
- log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
- notes, err := repo.GetCommit(NotesRef)
- if err != nil {
- if IsErrNotExist(err) {
- return err
- }
- log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
- return err
- }
-
- remainingCommitID := commitID
- path := ""
- currentTree := notes.Tree.gogitTree
- log.Trace("Found tree with ID %q while searching for git note corresponding to the commit %q", currentTree.Entries[0].Name, commitID)
- var file *object.File
- for len(remainingCommitID) > 2 {
- file, err = currentTree.File(remainingCommitID)
- if err == nil {
- path += remainingCommitID
- break
- }
- if err == object.ErrFileNotFound {
- currentTree, err = currentTree.Tree(remainingCommitID[0:2])
- path += remainingCommitID[0:2] + "/"
- remainingCommitID = remainingCommitID[2:]
- }
- if err != nil {
- if err == object.ErrDirectoryNotFound {
- return ErrNotExist{ID: remainingCommitID, RelPath: path}
- }
- log.Error("Unable to find git note corresponding to the commit %q. Error: %v", commitID, err)
- return err
- }
- }
-
- blob := file.Blob
- dataRc, err := blob.Reader()
- if err != nil {
- log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
- return err
- }
-
- defer dataRc.Close()
- d, err := io.ReadAll(dataRc)
- if err != nil {
- log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
- return err
- }
- note.Message = d
-
- commitNodeIndex, commitGraphFile := repo.CommitNodeIndex()
- if commitGraphFile != nil {
- defer commitGraphFile.Close()
- }
-
- commitNode, err := commitNodeIndex.Get(plumbing.Hash(notes.ID.RawValue()))
- if err != nil {
- return err
- }
-
- lastCommits, err := GetLastCommitForPaths(ctx, nil, commitNode, "", []string{path})
- if err != nil {
- log.Error("Unable to get the commit for the path %q. Error: %v", path, err)
- return err
- }
- note.Commit = lastCommits[path]
-
- return nil
-}
diff --git a/modules/git/notes_nogogit.go b/modules/git/notes_nogogit.go
deleted file mode 100644
index 4da375c321..0000000000
--- a/modules/git/notes_nogogit.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "context"
- "io"
- "strings"
-
- "code.gitea.io/gitea/modules/log"
-)
-
-// GetNote retrieves the git-notes data for a given commit.
-// FIXME: Add LastCommitCache support
-func GetNote(ctx context.Context, repo *Repository, commitID string, note *Note) error {
- log.Trace("Searching for git note corresponding to the commit %q in the repository %q", commitID, repo.Path)
- notes, err := repo.GetCommit(NotesRef)
- if err != nil {
- if IsErrNotExist(err) {
- return err
- }
- log.Error("Unable to get commit from ref %q. Error: %v", NotesRef, err)
- return err
- }
-
- path := ""
-
- tree := ¬es.Tree
- log.Trace("Found tree with ID %q while searching for git note corresponding to the commit %q", tree.ID, commitID)
-
- var entry *TreeEntry
- originalCommitID := commitID
- for len(commitID) > 2 {
- entry, err = tree.GetTreeEntryByPath(commitID)
- if err == nil {
- path += commitID
- break
- }
- if IsErrNotExist(err) {
- tree, err = tree.SubTree(commitID[0:2])
- path += commitID[0:2] + "/"
- commitID = commitID[2:]
- }
- if err != nil {
- // Err may have been updated by the SubTree we need to recheck if it's again an ErrNotExist
- if !IsErrNotExist(err) {
- log.Error("Unable to find git note corresponding to the commit %q. Error: %v", originalCommitID, err)
- }
- return err
- }
- }
-
- blob := entry.Blob()
- dataRc, err := blob.DataAsync()
- if err != nil {
- log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
- return err
- }
- closed := false
- defer func() {
- if !closed {
- _ = dataRc.Close()
- }
- }()
- d, err := io.ReadAll(dataRc)
- if err != nil {
- log.Error("Unable to read blob with ID %q. Error: %v", blob.ID, err)
- return err
- }
- _ = dataRc.Close()
- closed = true
- note.Message = d
-
- treePath := ""
- if idx := strings.LastIndex(path, "/"); idx > -1 {
- treePath = path[:idx]
- path = path[idx+1:]
- }
-
- lastCommits, err := GetLastCommitForPaths(ctx, notes, treePath, []string{path})
- if err != nil {
- log.Error("Unable to get the commit for the path %q. Error: %v", treePath, err)
- return err
- }
- note.Commit = lastCommits[path]
-
- return nil
-}
diff --git a/modules/git/notes_test.go b/modules/git/notes_test.go
index 267671d8fa..c7fb433ecf 100644
--- a/modules/git/notes_test.go
+++ b/modules/git/notes_test.go
@@ -1,25 +1,37 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package git
+package git_test
import (
- "context"
"path/filepath"
"testing"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/git"
+
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
+const (
+ testReposDir = "tests/repos/"
+)
+
+// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
+func openRepositoryWithDefaultContext(repoPath string) (*git.Repository, error) {
+ return git.OpenRepository(git.DefaultContext, repoPath)
+}
+
func TestGetNotes(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
- note := Note{}
- err = GetNote(context.Background(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
- assert.NoError(t, err)
+ note := git.Note{}
+ err = git.GetNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
+ require.NoError(t, err)
assert.Equal(t, []byte("Note contents\n"), note.Message)
assert.Equal(t, "Vladimir Panteleev", note.Commit.Author.Name)
}
@@ -27,26 +39,64 @@ func TestGetNotes(t *testing.T) {
func TestGetNestedNotes(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo3_notes")
repo, err := openRepositoryWithDefaultContext(repoPath)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
- note := Note{}
- err = GetNote(context.Background(), repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e)
- assert.NoError(t, err)
+ note := git.Note{}
+ err = git.GetNote(t.Context(), repo, "3e668dbfac39cbc80a9ff9c61eb565d944453ba4", ¬e)
+ require.NoError(t, err)
assert.Equal(t, []byte("Note 2"), note.Message)
- err = GetNote(context.Background(), repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", ¬e)
- assert.NoError(t, err)
+ err = git.GetNote(t.Context(), repo, "ba0a96fa63532d6c5087ecef070b0250ed72fa47", ¬e)
+ require.NoError(t, err)
assert.Equal(t, []byte("Note 1"), note.Message)
}
func TestGetNonExistentNotes(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
- note := Note{}
- err = GetNote(context.Background(), bareRepo1, "non_existent_sha", ¬e)
- assert.Error(t, err)
- assert.IsType(t, ErrNotExist{}, err)
+ note := git.Note{}
+ err = git.GetNote(t.Context(), bareRepo1, "non_existent_sha", ¬e)
+ require.Error(t, err)
+ assert.IsType(t, git.ErrNotExist{}, err)
+}
+
+func TestSetNote(t *testing.T) {
+ bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
+
+ tempDir := t.TempDir()
+ require.NoError(t, unittest.CopyDir(bareRepo1Path, filepath.Join(tempDir, "repo1")))
+
+ bareRepo1, err := openRepositoryWithDefaultContext(filepath.Join(tempDir, "repo1"))
+ require.NoError(t, err)
+ defer bareRepo1.Close()
+
+ require.NoError(t, git.SetNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", "This is a new note", "Test", "test@test.com"))
+
+ note := git.Note{}
+ err = git.GetNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
+ require.NoError(t, err)
+ assert.Equal(t, []byte("This is a new note\n"), note.Message)
+ assert.Equal(t, "Test", note.Commit.Author.Name)
+}
+
+func TestRemoveNote(t *testing.T) {
+ bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
+
+ tempDir := t.TempDir()
+
+ require.NoError(t, unittest.CopyDir(bareRepo1Path, filepath.Join(tempDir, "repo1")))
+
+ bareRepo1, err := openRepositoryWithDefaultContext(filepath.Join(tempDir, "repo1"))
+ require.NoError(t, err)
+ defer bareRepo1.Close()
+
+ require.NoError(t, git.RemoveNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653"))
+
+ note := git.Note{}
+ err = git.GetNote(t.Context(), bareRepo1, "95bb4d39648ee7e325106df01a621c530863a653", ¬e)
+ require.Error(t, err)
+ assert.IsType(t, git.ErrNotExist{}, err)
}
diff --git a/modules/git/object_id_gogit.go b/modules/git/object_id_gogit.go
deleted file mode 100644
index db4c4ae0bd..0000000000
--- a/modules/git/object_id_gogit.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2023 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-//go:build gogit
-
-package git
-
-import (
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/hash"
-)
-
-func ParseGogitHash(h plumbing.Hash) ObjectID {
- switch hash.Size {
- case 20:
- return Sha1ObjectFormat.MustID(h[:])
- case 32:
- return Sha256ObjectFormat.MustID(h[:])
- }
-
- return nil
-}
-
-func ParseGogitHashArray(objectIDs []plumbing.Hash) []ObjectID {
- ret := make([]ObjectID, len(objectIDs))
- for i, h := range objectIDs {
- ret[i] = ParseGogitHash(h)
- }
-
- return ret
-}
diff --git a/modules/git/parse_nogogit.go b/modules/git/parse.go
similarity index 98%
rename from modules/git/parse_nogogit.go
rename to modules/git/parse.go
index 546b38be37..6bc32057a7 100644
--- a/modules/git/parse_nogogit.go
+++ b/modules/git/parse.go
@@ -1,8 +1,6 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !gogit
-
package git
import (
@@ -13,7 +11,7 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
)
// ParseTreeEntries parses the output of a `git ls-tree -l` command.
diff --git a/modules/git/parse_gogit.go b/modules/git/parse_gogit.go
deleted file mode 100644
index 74d258de8e..0000000000
--- a/modules/git/parse_gogit.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "bytes"
- "fmt"
- "strconv"
- "strings"
-
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/filemode"
- "github.com/go-git/go-git/v5/plumbing/hash"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// ParseTreeEntries parses the output of a `git ls-tree -l` command.
-func ParseTreeEntries(data []byte) ([]*TreeEntry, error) {
- return parseTreeEntries(data, nil)
-}
-
-func parseTreeEntries(data []byte, ptree *Tree) ([]*TreeEntry, error) {
- entries := make([]*TreeEntry, 0, 10)
- for pos := 0; pos < len(data); {
- // expect line to be of the form " \t"
- entry := new(TreeEntry)
- entry.gogitTreeEntry = &object.TreeEntry{}
- entry.ptree = ptree
- if pos+6 > len(data) {
- return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data))
- }
- switch string(data[pos : pos+6]) {
- case "100644":
- entry.gogitTreeEntry.Mode = filemode.Regular
- pos += 12 // skip over "100644 blob "
- case "100755":
- entry.gogitTreeEntry.Mode = filemode.Executable
- pos += 12 // skip over "100755 blob "
- case "120000":
- entry.gogitTreeEntry.Mode = filemode.Symlink
- pos += 12 // skip over "120000 blob "
- case "160000":
- entry.gogitTreeEntry.Mode = filemode.Submodule
- pos += 14 // skip over "160000 object "
- case "040000":
- entry.gogitTreeEntry.Mode = filemode.Dir
- pos += 12 // skip over "040000 tree "
- default:
- return nil, fmt.Errorf("unknown type: %v", string(data[pos:pos+6]))
- }
-
- // in hex format, not byte format ....
- if pos+hash.Size*2 > len(data) {
- return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data))
- }
- var err error
- entry.ID, err = NewIDFromString(string(data[pos : pos+hash.Size*2]))
- if err != nil {
- return nil, fmt.Errorf("invalid ls-tree output: %w", err)
- }
- entry.gogitTreeEntry.Hash = plumbing.Hash(entry.ID.RawValue())
- pos += 41 // skip over sha and trailing space
-
- end := pos + bytes.IndexByte(data[pos:], '\t')
- if end < pos {
- return nil, fmt.Errorf("Invalid ls-tree -l output: %s", string(data))
- }
- entry.size, _ = strconv.ParseInt(strings.TrimSpace(string(data[pos:end])), 10, 64)
- entry.sized = true
-
- pos = end + 1
-
- end = pos + bytes.IndexByte(data[pos:], '\n')
- if end < pos {
- return nil, fmt.Errorf("Invalid ls-tree output: %s", string(data))
- }
-
- // In case entry name is surrounded by double quotes(it happens only in git-shell).
- if data[pos] == '"' {
- var err error
- entry.gogitTreeEntry.Name, err = strconv.Unquote(string(data[pos:end]))
- if err != nil {
- return nil, fmt.Errorf("Invalid ls-tree output: %w", err)
- }
- } else {
- entry.gogitTreeEntry.Name = string(data[pos:end])
- }
-
- pos = end + 1
- entries = append(entries, entry)
- }
- return entries, nil
-}
diff --git a/modules/git/parse_gogit_test.go b/modules/git/parse_gogit_test.go
deleted file mode 100644
index 3e171d7e56..0000000000
--- a/modules/git/parse_gogit_test.go
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "fmt"
- "testing"
-
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/filemode"
- "github.com/go-git/go-git/v5/plumbing/object"
- "github.com/stretchr/testify/assert"
-)
-
-func TestParseTreeEntries(t *testing.T) {
- testCases := []struct {
- Input string
- Expected []*TreeEntry
- }{
- {
- Input: "",
- Expected: []*TreeEntry{},
- },
- {
- Input: "100644 blob 61ab7345a1a3bbc590068ccae37b8515cfc5843c 1022\texample/file2.txt\n",
- Expected: []*TreeEntry{
- {
- ID: MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"),
- gogitTreeEntry: &object.TreeEntry{
- Hash: plumbing.Hash(MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()),
- Name: "example/file2.txt",
- Mode: filemode.Regular,
- },
- size: 1022,
- sized: true,
- },
- },
- },
- {
- Input: "120000 blob 61ab7345a1a3bbc590068ccae37b8515cfc5843c 234131\t\"example/\\n.txt\"\n" +
- "040000 tree 1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8 -\texample\n",
- Expected: []*TreeEntry{
- {
- ID: MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c"),
- gogitTreeEntry: &object.TreeEntry{
- Hash: plumbing.Hash(MustIDFromString("61ab7345a1a3bbc590068ccae37b8515cfc5843c").RawValue()),
- Name: "example/\n.txt",
- Mode: filemode.Symlink,
- },
- size: 234131,
- sized: true,
- },
- {
- ID: MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8"),
- sized: true,
- gogitTreeEntry: &object.TreeEntry{
- Hash: plumbing.Hash(MustIDFromString("1d01fb729fb0db5881daaa6030f9f2d3cd3d5ae8").RawValue()),
- Name: "example",
- Mode: filemode.Dir,
- },
- },
- },
- },
- }
-
- for _, testCase := range testCases {
- entries, err := ParseTreeEntries([]byte(testCase.Input))
- assert.NoError(t, err)
- if len(entries) > 1 {
- fmt.Println(testCase.Expected[0].ID)
- fmt.Println(entries[0].ID)
- }
- assert.EqualValues(t, testCase.Expected, entries)
- }
-}
diff --git a/modules/git/parse_nogogit_test.go b/modules/git/parse_test.go
similarity index 95%
rename from modules/git/parse_nogogit_test.go
rename to modules/git/parse_test.go
index 23fddb014c..89c6e0399b 100644
--- a/modules/git/parse_nogogit_test.go
+++ b/modules/git/parse_test.go
@@ -1,14 +1,13 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !gogit
-
package git
import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestParseTreeEntriesLong(t *testing.T) {
@@ -55,7 +54,7 @@ func TestParseTreeEntriesLong(t *testing.T) {
}
for _, testCase := range testCases {
entries, err := ParseTreeEntries([]byte(testCase.Input))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, entries, len(testCase.Expected))
for i, entry := range entries {
assert.EqualValues(t, testCase.Expected[i], entry)
@@ -88,7 +87,7 @@ func TestParseTreeEntriesShort(t *testing.T) {
}
for _, testCase := range testCases {
entries, err := ParseTreeEntries([]byte(testCase.Input))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, entries, len(testCase.Expected))
for i, entry := range entries {
assert.EqualValues(t, testCase.Expected[i], entry)
@@ -99,6 +98,6 @@ func TestParseTreeEntriesShort(t *testing.T) {
func TestParseTreeEntriesInvalid(t *testing.T) {
// there was a panic: "runtime error: slice bounds out of range" when the input was invalid: #20315
entries, err := ParseTreeEntries([]byte("100644 blob ea0d83c9081af9500ac9f804101b3fd0a5c293af"))
- assert.Error(t, err)
- assert.Len(t, entries, 0)
+ require.Error(t, err)
+ assert.Empty(t, entries)
}
diff --git a/modules/git/pipeline/catfile.go b/modules/git/pipeline/catfile.go
index 4677218150..6ada51ae82 100644
--- a/modules/git/pipeline/catfile.go
+++ b/modules/git/pipeline/catfile.go
@@ -13,8 +13,8 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
)
// CatFileBatchCheck runs cat-file with --batch-check
@@ -106,3 +106,36 @@ func BlobsLessThan1024FromCatFileBatchCheck(catFileCheckReader *io.PipeReader, s
}
}
}
+
+// BlobsLessThanOrEqual32KiBFromCatFileBatchCheck reads a pipeline from cat-file --batch-check and returns the blobs <=32KiB in size
+func BlobsLessThanOrEqual32KiBFromCatFileBatchCheck(catFileCheckReader *io.PipeReader, shasToBatchWriter *io.PipeWriter, wg *sync.WaitGroup) {
+ defer wg.Done()
+ defer catFileCheckReader.Close()
+ scanner := bufio.NewScanner(catFileCheckReader)
+ defer func() {
+ _ = shasToBatchWriter.CloseWithError(scanner.Err())
+ }()
+ for scanner.Scan() {
+ line := scanner.Text()
+ if len(line) == 0 {
+ continue
+ }
+ fields := strings.Split(line, " ")
+ if len(fields) < 3 || fields[1] != "blob" {
+ continue
+ }
+ size, _ := strconv.Atoi(fields[2])
+ if size > 32*1024 {
+ continue
+ }
+ toWrite := []byte(fields[0] + "\n")
+ for len(toWrite) > 0 {
+ n, err := shasToBatchWriter.Write(toWrite)
+ if err != nil {
+ _ = catFileCheckReader.CloseWithError(err)
+ break
+ }
+ toWrite = toWrite[n:]
+ }
+ }
+}
diff --git a/modules/git/pipeline/lfs_nogogit.go b/modules/git/pipeline/lfs.go
similarity index 88%
rename from modules/git/pipeline/lfs_nogogit.go
rename to modules/git/pipeline/lfs.go
index 349cfbd9ce..4395e25bd7 100644
--- a/modules/git/pipeline/lfs_nogogit.go
+++ b/modules/git/pipeline/lfs.go
@@ -1,21 +1,42 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !gogit
-
package pipeline
import (
"bufio"
"bytes"
+ "fmt"
"io"
"sort"
"strings"
"sync"
+ "time"
- "code.gitea.io/gitea/modules/git"
+ "forgejo.org/modules/git"
)
+// LFSResult represents commits found using a provided pointer file hash
+type LFSResult struct {
+ Name string
+ SHA string
+ Summary string
+ When time.Time
+ ParentHashes []git.ObjectID
+ BranchName string
+ FullCommitName string
+}
+
+type lfsResultSlice []*LFSResult
+
+func (a lfsResultSlice) Len() int { return len(a) }
+func (a lfsResultSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
+func (a lfsResultSlice) Less(i, j int) bool { return a[j].When.After(a[i].When) }
+
+func lfsError(msg string, err error) error {
+ return fmt.Errorf("LFS error occurred, %s: err: %w", msg, err)
+}
+
// FindLFSFile finds commits that contain a provided pointer file hash
func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, error) {
resultsMap := map[string]*LFSResult{}
@@ -46,7 +67,10 @@ func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, err
// Next feed the commits in order into cat-file --batch, followed by their trees and sub trees as necessary.
// so let's create a batch stdin and stdout
- batchStdinWriter, batchReader, cancel := repo.CatFileBatch(repo.Ctx)
+ batchStdinWriter, batchReader, cancel, err := repo.CatFileBatch(repo.Ctx)
+ if err != nil {
+ return nil, err
+ }
defer cancel()
// We'll use a scanner for the revList because it's simpler than a bufio.Reader
diff --git a/modules/git/pipeline/lfs_common.go b/modules/git/pipeline/lfs_common.go
deleted file mode 100644
index 188e7d4d65..0000000000
--- a/modules/git/pipeline/lfs_common.go
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2024 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package pipeline
-
-import (
- "fmt"
- "time"
-
- "code.gitea.io/gitea/modules/git"
-)
-
-// LFSResult represents commits found using a provided pointer file hash
-type LFSResult struct {
- Name string
- SHA string
- Summary string
- When time.Time
- ParentHashes []git.ObjectID
- BranchName string
- FullCommitName string
-}
-
-type lfsResultSlice []*LFSResult
-
-func (a lfsResultSlice) Len() int { return len(a) }
-func (a lfsResultSlice) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
-func (a lfsResultSlice) Less(i, j int) bool { return a[j].When.After(a[i].When) }
-
-func lfsError(msg string, err error) error {
- return fmt.Errorf("LFS error occurred, %s: err: %w", msg, err)
-}
diff --git a/modules/git/pipeline/lfs_gogit.go b/modules/git/pipeline/lfs_gogit.go
deleted file mode 100644
index adcf8ed09c..0000000000
--- a/modules/git/pipeline/lfs_gogit.go
+++ /dev/null
@@ -1,146 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package pipeline
-
-import (
- "bufio"
- "io"
- "sort"
- "strings"
- "sync"
-
- "code.gitea.io/gitea/modules/git"
-
- gogit "github.com/go-git/go-git/v5"
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// FindLFSFile finds commits that contain a provided pointer file hash
-func FindLFSFile(repo *git.Repository, objectID git.ObjectID) ([]*LFSResult, error) {
- resultsMap := map[string]*LFSResult{}
- results := make([]*LFSResult, 0)
-
- basePath := repo.Path
- gogitRepo := repo.GoGitRepo()
-
- commitsIter, err := gogitRepo.Log(&gogit.LogOptions{
- Order: gogit.LogOrderCommitterTime,
- All: true,
- })
- if err != nil {
- return nil, lfsError("failed to get GoGit CommitsIter", err)
- }
-
- err = commitsIter.ForEach(func(gitCommit *object.Commit) error {
- tree, err := gitCommit.Tree()
- if err != nil {
- return err
- }
- treeWalker := object.NewTreeWalker(tree, true, nil)
- defer treeWalker.Close()
- for {
- name, entry, err := treeWalker.Next()
- if err == io.EOF {
- break
- }
- if entry.Hash == plumbing.Hash(objectID.RawValue()) {
- parents := make([]git.ObjectID, len(gitCommit.ParentHashes))
- for i, parentCommitID := range gitCommit.ParentHashes {
- parents[i] = git.ParseGogitHash(parentCommitID)
- }
-
- result := LFSResult{
- Name: name,
- SHA: gitCommit.Hash.String(),
- Summary: strings.Split(strings.TrimSpace(gitCommit.Message), "\n")[0],
- When: gitCommit.Author.When,
- ParentHashes: parents,
- }
- resultsMap[gitCommit.Hash.String()+":"+name] = &result
- }
- }
- return nil
- })
- if err != nil && err != io.EOF {
- return nil, lfsError("failure in CommitIter.ForEach", err)
- }
-
- for _, result := range resultsMap {
- hasParent := false
- for _, parentHash := range result.ParentHashes {
- if _, hasParent = resultsMap[parentHash.String()+":"+result.Name]; hasParent {
- break
- }
- }
- if !hasParent {
- results = append(results, result)
- }
- }
-
- sort.Sort(lfsResultSlice(results))
-
- // Should really use a go-git function here but name-rev is not completed and recapitulating it is not simple
- shasToNameReader, shasToNameWriter := io.Pipe()
- nameRevStdinReader, nameRevStdinWriter := io.Pipe()
- errChan := make(chan error, 1)
- wg := sync.WaitGroup{}
- wg.Add(3)
-
- go func() {
- defer wg.Done()
- scanner := bufio.NewScanner(nameRevStdinReader)
- i := 0
- for scanner.Scan() {
- line := scanner.Text()
- if len(line) == 0 {
- continue
- }
- result := results[i]
- result.FullCommitName = line
- result.BranchName = strings.Split(line, "~")[0]
- i++
- }
- }()
- go NameRevStdin(repo.Ctx, shasToNameReader, nameRevStdinWriter, &wg, basePath)
- go func() {
- defer wg.Done()
- defer shasToNameWriter.Close()
- for _, result := range results {
- i := 0
- if i < len(result.SHA) {
- n, err := shasToNameWriter.Write([]byte(result.SHA)[i:])
- if err != nil {
- errChan <- err
- break
- }
- i += n
- }
- n := 0
- for n < 1 {
- n, err = shasToNameWriter.Write([]byte{'\n'})
- if err != nil {
- errChan <- err
- break
- }
-
- }
-
- }
- }()
-
- wg.Wait()
-
- select {
- case err, has := <-errChan:
- if has {
- return nil, lfsError("unable to obtain name for LFS files", err)
- }
- default:
- }
-
- return results, nil
-}
diff --git a/modules/git/pipeline/namerev.go b/modules/git/pipeline/namerev.go
index ad583a7479..70840edf19 100644
--- a/modules/git/pipeline/namerev.go
+++ b/modules/git/pipeline/namerev.go
@@ -11,7 +11,7 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/modules/git"
+ "forgejo.org/modules/git"
)
// NameRevStdin runs name-rev --stdin
diff --git a/modules/git/pipeline/revlist.go b/modules/git/pipeline/revlist.go
index d88ebe78ef..f39b7113bb 100644
--- a/modules/git/pipeline/revlist.go
+++ b/modules/git/pipeline/revlist.go
@@ -12,8 +12,8 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
)
// RevListAllObjects runs rev-list --objects --all and writes to a pipewriter
diff --git a/modules/git/pushoptions/pushoptions.go b/modules/git/pushoptions/pushoptions.go
new file mode 100644
index 0000000000..9709a8be79
--- /dev/null
+++ b/modules/git/pushoptions/pushoptions.go
@@ -0,0 +1,113 @@
+// Copyright twenty-panda
+// SPDX-License-Identifier: MIT
+
+package pushoptions
+
+import (
+ "fmt"
+ "os"
+ "strconv"
+ "strings"
+)
+
+type Key string
+
+const (
+ RepoPrivate = Key("repo.private")
+ RepoTemplate = Key("repo.template")
+ AgitTopic = Key("topic")
+ AgitForcePush = Key("force-push")
+ AgitTitle = Key("title")
+ AgitDescription = Key("description")
+
+ envPrefix = "GIT_PUSH_OPTION"
+ EnvCount = envPrefix + "_COUNT"
+ EnvFormat = envPrefix + "_%d"
+)
+
+type Interface interface {
+ ReadEnv() Interface
+ Parse(string) bool
+ Map() map[string]string
+
+ ChangeRepoSettings() bool
+
+ Empty() bool
+
+ GetBool(key Key, def bool) bool
+ GetString(key Key) (val string, ok bool)
+}
+
+type gitPushOptions map[string]string
+
+func New() Interface {
+ pushOptions := gitPushOptions(make(map[string]string))
+ return &pushOptions
+}
+
+func NewFromMap(o *map[string]string) Interface {
+ return (*gitPushOptions)(o)
+}
+
+func (o *gitPushOptions) ReadEnv() Interface {
+ if pushCount, err := strconv.Atoi(os.Getenv(EnvCount)); err == nil {
+ for idx := 0; idx < pushCount; idx++ {
+ _ = o.Parse(os.Getenv(fmt.Sprintf(EnvFormat, idx)))
+ }
+ }
+ return o
+}
+
+func (o *gitPushOptions) Parse(data string) bool {
+ key, value, found := strings.Cut(data, "=")
+ if !found {
+ value = "true"
+ }
+ switch Key(key) {
+ case RepoPrivate:
+ case RepoTemplate:
+ case AgitTopic:
+ case AgitForcePush:
+ case AgitTitle:
+ case AgitDescription:
+ default:
+ return false
+ }
+ (*o)[key] = value
+ return true
+}
+
+func (o gitPushOptions) Map() map[string]string {
+ return o
+}
+
+func (o gitPushOptions) ChangeRepoSettings() bool {
+ if o.Empty() {
+ return false
+ }
+ for _, key := range []Key{RepoPrivate, RepoTemplate} {
+ _, ok := o[string(key)]
+ if ok {
+ return true
+ }
+ }
+ return false
+}
+
+func (o gitPushOptions) Empty() bool {
+ return len(o) == 0
+}
+
+func (o gitPushOptions) GetBool(key Key, def bool) bool {
+ if val, ok := o[string(key)]; ok {
+ if b, err := strconv.ParseBool(val); err == nil {
+ return b
+ }
+ }
+ return def
+}
+
+func (o gitPushOptions) GetString(key Key) (string, bool) {
+ val, ok := o[string(key)]
+ return val, ok
+}
diff --git a/modules/git/pushoptions/pushoptions_test.go b/modules/git/pushoptions/pushoptions_test.go
new file mode 100644
index 0000000000..49bf2d275b
--- /dev/null
+++ b/modules/git/pushoptions/pushoptions_test.go
@@ -0,0 +1,125 @@
+// Copyright twenty-panda
+// SPDX-License-Identifier: MIT
+
+package pushoptions
+
+import (
+ "fmt"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestEmpty(t *testing.T) {
+ options := New()
+ assert.True(t, options.Empty())
+ options.Parse(fmt.Sprintf("%v", RepoPrivate))
+ assert.False(t, options.Empty())
+}
+
+func TestToAndFromMap(t *testing.T) {
+ options := New()
+ options.Parse(fmt.Sprintf("%v", RepoPrivate))
+ actual := options.Map()
+ expected := map[string]string{string(RepoPrivate): "true"}
+ assert.EqualValues(t, expected, actual)
+ assert.EqualValues(t, expected, NewFromMap(&actual).Map())
+}
+
+func TestChangeRepositorySettings(t *testing.T) {
+ options := New()
+ assert.False(t, options.ChangeRepoSettings())
+ assert.True(t, options.Parse(fmt.Sprintf("%v=description", AgitDescription)))
+ assert.False(t, options.ChangeRepoSettings())
+
+ options.Parse(fmt.Sprintf("%v", RepoPrivate))
+ assert.True(t, options.ChangeRepoSettings())
+
+ options = New()
+ options.Parse(fmt.Sprintf("%v", RepoTemplate))
+ assert.True(t, options.ChangeRepoSettings())
+}
+
+func TestParse(t *testing.T) {
+ t.Run("no key", func(t *testing.T) {
+ options := New()
+
+ val, ok := options.GetString(RepoPrivate)
+ assert.False(t, ok)
+ assert.Equal(t, "", val)
+
+ assert.True(t, options.GetBool(RepoPrivate, true))
+ assert.False(t, options.GetBool(RepoPrivate, false))
+ })
+
+ t.Run("key=value", func(t *testing.T) {
+ options := New()
+
+ topic := "TOPIC"
+ assert.True(t, options.Parse(fmt.Sprintf("%v=%s", AgitTopic, topic)))
+ val, ok := options.GetString(AgitTopic)
+ assert.True(t, ok)
+ assert.Equal(t, topic, val)
+ })
+
+ t.Run("key=true", func(t *testing.T) {
+ options := New()
+
+ assert.True(t, options.Parse(fmt.Sprintf("%v=true", RepoPrivate)))
+ assert.True(t, options.GetBool(RepoPrivate, false))
+ assert.True(t, options.Parse(fmt.Sprintf("%v=TRUE", RepoTemplate)))
+ assert.True(t, options.GetBool(RepoTemplate, false))
+ })
+
+ t.Run("key=false", func(t *testing.T) {
+ options := New()
+
+ assert.True(t, options.Parse(fmt.Sprintf("%v=false", RepoPrivate)))
+ assert.False(t, options.GetBool(RepoPrivate, true))
+ })
+
+ t.Run("key", func(t *testing.T) {
+ options := New()
+
+ assert.True(t, options.Parse(fmt.Sprintf("%v", RepoPrivate)))
+ assert.True(t, options.GetBool(RepoPrivate, false))
+ })
+
+ t.Run("unknown keys are ignored", func(t *testing.T) {
+ options := New()
+
+ assert.True(t, options.Empty())
+ assert.False(t, options.Parse("unknown=value"))
+ assert.True(t, options.Empty())
+ })
+}
+
+func TestReadEnv(t *testing.T) {
+ t.Setenv(envPrefix+"_0", fmt.Sprintf("%v=true", AgitForcePush))
+ t.Setenv(envPrefix+"_1", fmt.Sprintf("%v", RepoPrivate))
+ t.Setenv(envPrefix+"_2", fmt.Sprintf("%v=equal=in string", AgitTitle))
+ t.Setenv(envPrefix+"_3", "not=valid")
+ t.Setenv(envPrefix+"_4", fmt.Sprintf("%v=description", AgitDescription))
+ t.Setenv(EnvCount, "5")
+
+ options := New().ReadEnv()
+
+ assert.True(t, options.GetBool(AgitForcePush, false))
+ assert.True(t, options.GetBool(RepoPrivate, false))
+ assert.False(t, options.GetBool(RepoTemplate, false))
+
+ {
+ val, ok := options.GetString(AgitTitle)
+ assert.True(t, ok)
+ assert.Equal(t, "equal=in string", val)
+ }
+ {
+ val, ok := options.GetString(AgitDescription)
+ assert.True(t, ok)
+ assert.Equal(t, "description", val)
+ }
+ {
+ _, ok := options.GetString(AgitTopic)
+ assert.False(t, ok)
+ }
+}
diff --git a/modules/git/ref.go b/modules/git/ref.go
index 2db630e2ea..1475d4dc5a 100644
--- a/modules/git/ref.go
+++ b/modules/git/ref.go
@@ -7,7 +7,7 @@ import (
"regexp"
"strings"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
const (
diff --git a/modules/git/ref_test.go b/modules/git/ref_test.go
index 58f679b7d6..1fd33b5163 100644
--- a/modules/git/ref_test.go
+++ b/modules/git/ref_test.go
@@ -20,6 +20,8 @@ func TestRefName(t *testing.T) {
// Test pull names
assert.Equal(t, "1", RefName("refs/pull/1/head").PullName())
+ assert.True(t, RefName("refs/pull/1/head").IsPull())
+ assert.True(t, RefName("refs/pull/1/merge").IsPull())
assert.Equal(t, "my/pull", RefName("refs/pull/my/pull/head").PullName())
// Test for branch names
diff --git a/modules/git/remote.go b/modules/git/remote.go
index 3585313f6a..fb66d76ff0 100644
--- a/modules/git/remote.go
+++ b/modules/git/remote.go
@@ -5,8 +5,9 @@ package git
import (
"context"
+ "strings"
- giturl "code.gitea.io/gitea/modules/git/url"
+ giturl "forgejo.org/modules/git/url"
)
// GetRemoteAddress returns remote url of git repository in the repoPath with special remote name
@@ -37,3 +38,12 @@ func GetRemoteURL(ctx context.Context, repoPath, remoteName string) (*giturl.Git
}
return giturl.Parse(addr)
}
+
+// IsRemoteNotExistError checks the prefix of the error message to see whether a remote does not exist.
+func IsRemoteNotExistError(err error) bool {
+ // see: https://github.com/go-gitea/gitea/issues/32889#issuecomment-2571848216
+ // Should not add space in the end, sometimes git will add a `:`
+ prefix1 := "exit status 128 - fatal: No such remote" // git < 2.30
+ prefix2 := "exit status 2 - error: No such remote" // git >= 2.30
+ return strings.HasPrefix(err.Error(), prefix1) || strings.HasPrefix(err.Error(), prefix2)
+}
diff --git a/modules/git/repo.go b/modules/git/repo.go
index 857424fcd4..0f4d1f5afa 100644
--- a/modules/git/repo.go
+++ b/modules/git/repo.go
@@ -1,5 +1,6 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package git
@@ -17,8 +18,9 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/proxy"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/proxy"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
// GPGSettings represents the default GPG settings for this repository
@@ -190,17 +192,39 @@ func CloneWithArgs(ctx context.Context, args TrustedCmdArgs, from, to string, op
// PushOptions options when push to remote
type PushOptions struct {
- Remote string
- Branch string
- Force bool
- Mirror bool
- Env []string
- Timeout time.Duration
+ Remote string
+ Branch string
+ Force bool
+ Mirror bool
+ Env []string
+ Timeout time.Duration
+ PrivateKeyPath string
}
// Push pushs local commits to given remote branch.
func Push(ctx context.Context, repoPath string, opts PushOptions) error {
cmd := NewCommand(ctx, "push")
+
+ if opts.PrivateKeyPath != "" {
+ // Preserve the behavior that existing environments are used if no
+ // environments are passed.
+ if len(opts.Env) == 0 {
+ opts.Env = os.Environ()
+ }
+
+ // Use environment because it takes precedence over using -c core.sshcommand
+ // and it's possible that a system might have an existing GIT_SSH_COMMAND
+ // environment set.
+ opts.Env = append(opts.Env, "GIT_SSH_COMMAND=ssh"+
+ fmt.Sprintf(` -i %s`, opts.PrivateKeyPath)+
+ " -o IdentitiesOnly=yes"+
+ // This will store new SSH host keys and verify connections to existing
+ // host keys, but it doesn't allow replacement of existing host keys. This
+ // means TOFU is used for Git over SSH pushes.
+ " -o StrictHostKeyChecking=accept-new"+
+ " -o UserKnownHostsFile="+filepath.Join(setting.SSH.RootPath, "known_hosts"))
+ }
+
if opts.Force {
cmd.AddArguments("-f")
}
diff --git a/modules/git/repo_attribute.go b/modules/git/repo_attribute.go
index 3ccc1b84a6..2154467332 100644
--- a/modules/git/repo_attribute.go
+++ b/modules/git/repo_attribute.go
@@ -13,7 +13,7 @@ import (
"strings"
"sync/atomic"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/modules/optional"
)
var LinguistAttributes = []string{"linguist-vendored", "linguist-generated", "linguist-language", "gitlab-language", "linguist-documentation", "linguist-detectable"}
@@ -250,7 +250,7 @@ func (repo *Repository) GitAttributeChecker(treeish string, attributes ...string
err = e
}
- if err != nil { // decorate the returned error
+ if err != nil && !IsErrCanceledOrKilled(err) { // decorate the returned error
err = fmt.Errorf("git check-attr (stderr: %q): %w", strings.TrimSpace(stdErr.String()), err)
ac.err.Store(err)
}
diff --git a/modules/git/repo_attribute_test.go b/modules/git/repo_attribute_test.go
index e9f7454413..ee89373b90 100644
--- a/modules/git/repo_attribute_test.go
+++ b/modules/git/repo_attribute_test.go
@@ -15,7 +15,7 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -30,14 +30,14 @@ func TestNewCheckAttrStdoutReader(t *testing.T) {
// first read
attr, err := read()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, map[string]GitAttribute{
"linguist-vendored": GitAttribute("unspecified"),
}, attr)
// second read
attr, err = read()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, map[string]GitAttribute{
"linguist-vendored": GitAttribute("specified"),
}, attr)
@@ -59,21 +59,21 @@ func TestNewCheckAttrStdoutReader(t *testing.T) {
// first read
attr, err := read()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, map[string]GitAttribute{
"linguist-vendored": GitAttribute("set"),
}, attr)
// second read
attr, err = read()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, map[string]GitAttribute{
"linguist-generated": GitAttribute("unspecified"),
}, attr)
// third read
attr, err = read()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, map[string]GitAttribute{
"linguist-language": GitAttribute("unspecified"),
}, attr)
@@ -95,32 +95,32 @@ func TestGitAttributeBareNonBare(t *testing.T) {
"341fca5b5ea3de596dc483e54c2db28633cd2f97",
} {
bareStats, err := gitRepo.GitAttributes(commitID, "i-am-a-python.p", LinguistAttributes...)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer test.MockVariableValue(&SupportCheckAttrOnBare, false)()
cloneStats, err := gitRepo.GitAttributes(commitID, "i-am-a-python.p", LinguistAttributes...)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, cloneStats, bareStats)
refStats := cloneStats
t.Run("GitAttributeChecker/"+commitID+"/SupportBare", func(t *testing.T) {
bareChecker, err := gitRepo.GitAttributeChecker(commitID, LinguistAttributes...)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareChecker.Close()
bareStats, err := bareChecker.CheckPath("i-am-a-python.p")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, refStats, bareStats)
})
t.Run("GitAttributeChecker/"+commitID+"/NoBareSupport", func(t *testing.T) {
defer test.MockVariableValue(&SupportCheckAttrOnBare, false)()
cloneChecker, err := gitRepo.GitAttributeChecker(commitID, LinguistAttributes...)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer cloneChecker.Close()
cloneStats, err := cloneChecker.CheckPath("i-am-a-python.p")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, refStats, cloneStats)
})
@@ -134,7 +134,7 @@ func TestGitAttributes(t *testing.T) {
defer gitRepo.Close()
attr, err := gitRepo.GitAttributes("8fee858da5796dfb37704761701bb8e800ad9ef3", "i-am-a-python.p", LinguistAttributes...)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, map[string]GitAttribute{
"gitlab-language": "unspecified",
"linguist-detectable": "unspecified",
@@ -145,7 +145,7 @@ func TestGitAttributes(t *testing.T) {
}, attr)
attr, err = gitRepo.GitAttributes("341fca5b5ea3de596dc483e54c2db28633cd2f97", "i-am-a-python.p", LinguistAttributes...)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, map[string]GitAttribute{
"gitlab-language": "unspecified",
"linguist-detectable": "unspecified",
@@ -164,19 +164,19 @@ func TestGitAttributeFirst(t *testing.T) {
t.Run("first is specified", func(t *testing.T) {
language, err := gitRepo.GitAttributeFirst("8fee858da5796dfb37704761701bb8e800ad9ef3", "i-am-a-python.p", "linguist-language", "gitlab-language")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "Python", language.String())
})
t.Run("second is specified", func(t *testing.T) {
language, err := gitRepo.GitAttributeFirst("8fee858da5796dfb37704761701bb8e800ad9ef3", "i-am-a-python.p", "gitlab-language", "linguist-language")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "Python", language.String())
})
t.Run("none is specified", func(t *testing.T) {
language, err := gitRepo.GitAttributeFirst("8fee858da5796dfb37704761701bb8e800ad9ef3", "i-am-a-python.p", "linguist-detectable", "gitlab-language", "non-existing")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "", language.String())
})
}
@@ -208,13 +208,13 @@ func TestGitAttributeCheckerError(t *testing.T) {
gitRepo := prepareRepo(t)
defer gitRepo.Close()
- assert.NoError(t, os.RemoveAll(gitRepo.Path))
+ require.NoError(t, os.RemoveAll(gitRepo.Path))
ac, err := gitRepo.GitAttributeChecker("", "linguist-language")
require.NoError(t, err)
_, err = ac.CheckPath("i-am-a-python.p")
- assert.Error(t, err)
+ require.Error(t, err)
assert.Contains(t, err.Error(), `git check-attr (stderr: ""):`)
})
@@ -226,7 +226,7 @@ func TestGitAttributeCheckerError(t *testing.T) {
require.NoError(t, err)
// calling CheckPath before would allow git to cache part of it and successfully return later
- assert.NoError(t, os.RemoveAll(gitRepo.Path))
+ require.NoError(t, os.RemoveAll(gitRepo.Path))
_, err = ac.CheckPath("i-am-a-python.p")
if err == nil {
@@ -254,7 +254,7 @@ func TestGitAttributeCheckerError(t *testing.T) {
require.NoError(t, err)
_, err = ac.CheckPath("i-am-a-python.p")
- assert.ErrorIs(t, err, context.Canceled)
+ require.Error(t, err)
})
t.Run("Cancelled/DuringRun", func(t *testing.T) {
@@ -268,7 +268,7 @@ func TestGitAttributeCheckerError(t *testing.T) {
require.NoError(t, err)
attr, err := ac.CheckPath("i-am-a-python.p")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "Python", attr["linguist-language"].String())
errCh := make(chan error)
@@ -286,7 +286,7 @@ func TestGitAttributeCheckerError(t *testing.T) {
case <-time.After(time.Second):
t.Error("CheckPath did not complete within 1s")
case err = <-errCh:
- assert.ErrorIs(t, err, context.Canceled)
+ require.ErrorIs(t, err, context.Canceled)
}
})
@@ -297,10 +297,10 @@ func TestGitAttributeCheckerError(t *testing.T) {
ac, err := gitRepo.GitAttributeChecker("8fee858da5796dfb37704761701bb8e800ad9ef3", "linguist-language")
require.NoError(t, err)
- assert.NoError(t, ac.Close())
+ require.NoError(t, ac.Close())
_, err = ac.CheckPath("i-am-a-python.p")
- assert.ErrorIs(t, err, fs.ErrClosed)
+ require.ErrorIs(t, err, fs.ErrClosed)
})
t.Run("Closed/DuringRun", func(t *testing.T) {
@@ -311,13 +311,13 @@ func TestGitAttributeCheckerError(t *testing.T) {
require.NoError(t, err)
attr, err := ac.CheckPath("i-am-a-python.p")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "Python", attr["linguist-language"].String())
- assert.NoError(t, ac.Close())
+ require.NoError(t, ac.Close())
_, err = ac.CheckPath("i-am-a-python.p")
- assert.ErrorIs(t, err, fs.ErrClosed)
+ require.ErrorIs(t, err, fs.ErrClosed)
})
}
diff --git a/modules/git/repo_base.go b/modules/git/repo_base.go
index 6c148d9af5..a82d59af3c 100644
--- a/modules/git/repo_base.go
+++ b/modules/git/repo_base.go
@@ -1,6 +1,124 @@
-// Copyright 2021 The Gitea Authors. All rights reserved.
+// Copyright 2015 The Gogs Authors. All rights reserved.
+// Copyright 2017 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package git
-var isGogit bool
+import (
+ "bufio"
+ "context"
+ "errors"
+ "path/filepath"
+
+ "forgejo.org/modules/log"
+)
+
+// Repository represents a Git repository.
+type Repository struct {
+ Path string
+
+ tagCache *ObjectCache
+
+ gpgSettings *GPGSettings
+
+ batchInUse bool
+ batch *Batch
+
+ checkInUse bool
+ check *Batch
+
+ Ctx context.Context
+ LastCommitCache *LastCommitCache
+
+ objectFormat ObjectFormat
+}
+
+// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
+func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) {
+ return OpenRepository(DefaultContext, repoPath)
+}
+
+// OpenRepository opens the repository at the given path with the provided context.
+func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
+ repoPath, err := filepath.Abs(repoPath)
+ if err != nil {
+ return nil, err
+ } else if !isDir(repoPath) {
+ return nil, errors.New("no such file or directory")
+ }
+
+ return &Repository{
+ Path: repoPath,
+ tagCache: newObjectCache(),
+ Ctx: ctx,
+ }, nil
+}
+
+// CatFileBatch obtains a CatFileBatch for this repository
+func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func(), error) {
+ if repo.batch == nil {
+ var err error
+ repo.batch, err = repo.NewBatch(ctx)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ }
+
+ if !repo.batchInUse {
+ repo.batchInUse = true
+ return repo.batch.Writer, repo.batch.Reader, func() {
+ repo.batchInUse = false
+ }, nil
+ }
+
+ log.Debug("Opening temporary cat file batch for: %s", repo.Path)
+ tempBatch, err := repo.NewBatch(ctx)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ return tempBatch.Writer, tempBatch.Reader, tempBatch.Close, nil
+}
+
+// CatFileBatchCheck obtains a CatFileBatchCheck for this repository
+func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func(), error) {
+ if repo.check == nil {
+ var err error
+ repo.check, err = repo.NewBatchCheck(ctx)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ }
+
+ if !repo.checkInUse {
+ repo.checkInUse = true
+ return repo.check.Writer, repo.check.Reader, func() {
+ repo.checkInUse = false
+ }, nil
+ }
+
+ log.Debug("Opening temporary cat file batch-check for: %s", repo.Path)
+ tempBatchCheck, err := repo.NewBatchCheck(ctx)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ return tempBatchCheck.Writer, tempBatchCheck.Reader, tempBatchCheck.Close, nil
+}
+
+func (repo *Repository) Close() error {
+ if repo == nil {
+ return nil
+ }
+ if repo.batch != nil {
+ repo.batch.Close()
+ repo.batch = nil
+ repo.batchInUse = false
+ }
+ if repo.check != nil {
+ repo.check.Close()
+ repo.check = nil
+ repo.checkInUse = false
+ }
+ repo.LastCommitCache = nil
+ repo.tagCache = nil
+ return nil
+}
diff --git a/modules/git/repo_base_gogit.go b/modules/git/repo_base_gogit.go
deleted file mode 100644
index 3ca5eb36c6..0000000000
--- a/modules/git/repo_base_gogit.go
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "context"
- "errors"
- "path/filepath"
-
- gitealog "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
-
- "github.com/go-git/go-billy/v5"
- "github.com/go-git/go-billy/v5/osfs"
- gogit "github.com/go-git/go-git/v5"
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/cache"
- "github.com/go-git/go-git/v5/storage/filesystem"
-)
-
-func init() {
- isGogit = true
-}
-
-// Repository represents a Git repository.
-type Repository struct {
- Path string
-
- tagCache *ObjectCache
-
- gogitRepo *gogit.Repository
- gogitStorage *filesystem.Storage
- gpgSettings *GPGSettings
-
- Ctx context.Context
- LastCommitCache *LastCommitCache
- objectFormat ObjectFormat
-}
-
-// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
-func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) {
- return OpenRepository(DefaultContext, repoPath)
-}
-
-// OpenRepository opens the repository at the given path within the context.Context
-func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
- repoPath, err := filepath.Abs(repoPath)
- if err != nil {
- return nil, err
- } else if !isDir(repoPath) {
- return nil, errors.New("no such file or directory")
- }
-
- fs := osfs.New(repoPath)
- _, err = fs.Stat(".git")
- if err == nil {
- fs, err = fs.Chroot(".git")
- if err != nil {
- return nil, err
- }
- }
- // the "clone --shared" repo doesn't work well with go-git AlternativeFS, https://github.com/go-git/go-git/issues/1006
- // so use "/" for AlternatesFS, I guess it is the same behavior as current nogogit (no limitation or check for the "objects/info/alternates" paths), trust the "clone" command executed by the server.
- var altFs billy.Filesystem
- if setting.IsWindows {
- altFs = osfs.New(filepath.VolumeName(setting.RepoRootPath) + "\\") // TODO: does it really work for Windows? Need some time to check.
- } else {
- altFs = osfs.New("/")
- }
- storage := filesystem.NewStorageWithOptions(fs, cache.NewObjectLRUDefault(), filesystem.Options{KeepDescriptors: true, LargeObjectThreshold: setting.Git.LargeObjectThreshold, AlternatesFS: altFs})
- gogitRepo, err := gogit.Open(storage, fs)
- if err != nil {
- return nil, err
- }
-
- return &Repository{
- Path: repoPath,
- gogitRepo: gogitRepo,
- gogitStorage: storage,
- tagCache: newObjectCache(),
- Ctx: ctx,
- objectFormat: ParseGogitHash(plumbing.ZeroHash).Type(),
- }, nil
-}
-
-// Close this repository, in particular close the underlying gogitStorage if this is not nil
-func (repo *Repository) Close() error {
- if repo == nil || repo.gogitStorage == nil {
- return nil
- }
- if err := repo.gogitStorage.Close(); err != nil {
- gitealog.Error("Error closing storage: %v", err)
- }
- repo.gogitStorage = nil
- repo.LastCommitCache = nil
- repo.tagCache = nil
- return nil
-}
-
-// GoGitRepo gets the go-git repo representation
-func (repo *Repository) GoGitRepo() *gogit.Repository {
- return repo.gogitRepo
-}
diff --git a/modules/git/repo_base_nogogit.go b/modules/git/repo_base_nogogit.go
deleted file mode 100644
index 50a0a975b8..0000000000
--- a/modules/git/repo_base_nogogit.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "bufio"
- "context"
- "errors"
- "path/filepath"
-
- "code.gitea.io/gitea/modules/log"
-)
-
-func init() {
- isGogit = false
-}
-
-// Repository represents a Git repository.
-type Repository struct {
- Path string
-
- tagCache *ObjectCache
-
- gpgSettings *GPGSettings
-
- batchInUse bool
- batchCancel context.CancelFunc
- batchReader *bufio.Reader
- batchWriter WriteCloserError
-
- checkInUse bool
- checkCancel context.CancelFunc
- checkReader *bufio.Reader
- checkWriter WriteCloserError
-
- Ctx context.Context
- LastCommitCache *LastCommitCache
-
- objectFormat ObjectFormat
-}
-
-// openRepositoryWithDefaultContext opens the repository at the given path with DefaultContext.
-func openRepositoryWithDefaultContext(repoPath string) (*Repository, error) {
- return OpenRepository(DefaultContext, repoPath)
-}
-
-// OpenRepository opens the repository at the given path with the provided context.
-func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) {
- repoPath, err := filepath.Abs(repoPath)
- if err != nil {
- return nil, err
- } else if !isDir(repoPath) {
- return nil, errors.New("no such file or directory")
- }
-
- // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
- if err := EnsureValidGitRepository(ctx, repoPath); err != nil {
- return nil, err
- }
-
- repo := &Repository{
- Path: repoPath,
- tagCache: newObjectCache(),
- Ctx: ctx,
- }
-
- repo.batchWriter, repo.batchReader, repo.batchCancel = CatFileBatch(ctx, repoPath)
- repo.checkWriter, repo.checkReader, repo.checkCancel = CatFileBatchCheck(ctx, repoPath)
-
- return repo, nil
-}
-
-// CatFileBatch obtains a CatFileBatch for this repository
-func (repo *Repository) CatFileBatch(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
- if repo.batchCancel == nil || repo.batchInUse {
- log.Debug("Opening temporary cat file batch for: %s", repo.Path)
- return CatFileBatch(ctx, repo.Path)
- }
- repo.batchInUse = true
- return repo.batchWriter, repo.batchReader, func() {
- repo.batchInUse = false
- }
-}
-
-// CatFileBatchCheck obtains a CatFileBatchCheck for this repository
-func (repo *Repository) CatFileBatchCheck(ctx context.Context) (WriteCloserError, *bufio.Reader, func()) {
- if repo.checkCancel == nil || repo.checkInUse {
- log.Debug("Opening temporary cat file batch-check for: %s", repo.Path)
- return CatFileBatchCheck(ctx, repo.Path)
- }
- repo.checkInUse = true
- return repo.checkWriter, repo.checkReader, func() {
- repo.checkInUse = false
- }
-}
-
-func (repo *Repository) Close() error {
- if repo == nil {
- return nil
- }
- if repo.batchCancel != nil {
- repo.batchCancel()
- repo.batchReader = nil
- repo.batchWriter = nil
- repo.batchCancel = nil
- repo.batchInUse = false
- }
- if repo.checkCancel != nil {
- repo.checkCancel()
- repo.checkCancel = nil
- repo.checkReader = nil
- repo.checkWriter = nil
- repo.checkInUse = false
- }
- repo.LastCommitCache = nil
- repo.tagCache = nil
- return nil
-}
diff --git a/modules/git/repo_base_test.go b/modules/git/repo_base_test.go
new file mode 100644
index 0000000000..c9ac6a8559
--- /dev/null
+++ b/modules/git/repo_base_test.go
@@ -0,0 +1,163 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package git
+
+import (
+ "bufio"
+ "context"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// This unit test relies on the implementation detail of CatFileBatch.
+func TestCatFileBatch(t *testing.T) {
+ ctx, cancel := context.WithCancel(t.Context())
+ defer cancel()
+
+ repo, err := OpenRepository(ctx, "./tests/repos/repo1_bare")
+ require.NoError(t, err)
+ defer repo.Close()
+
+ var wr WriteCloserError
+ var r *bufio.Reader
+ var cancel1 func()
+ t.Run("Request cat file batch", func(t *testing.T) {
+ assert.Nil(t, repo.batch)
+ wr, r, cancel1, err = repo.CatFileBatch(ctx)
+ require.NoError(t, err)
+ assert.NotNil(t, repo.batch)
+ assert.Equal(t, repo.batch.Writer, wr)
+ assert.True(t, repo.batchInUse)
+ })
+
+ t.Run("Request temporary cat file batch", func(t *testing.T) {
+ wr, r, cancel, err := repo.CatFileBatch(ctx)
+ require.NoError(t, err)
+ assert.NotEqual(t, repo.batch.Writer, wr)
+
+ t.Run("Check temporary cat file batch", func(t *testing.T) {
+ _, err = wr.Write([]byte("95bb4d39648ee7e325106df01a621c530863a653" + "\n"))
+ require.NoError(t, err)
+
+ sha, typ, size, err := ReadBatchLine(r)
+ require.NoError(t, err)
+ assert.Equal(t, "commit", typ)
+ assert.EqualValues(t, []byte("95bb4d39648ee7e325106df01a621c530863a653"), sha)
+ assert.EqualValues(t, 144, size)
+ })
+
+ cancel()
+ assert.True(t, repo.batchInUse)
+ })
+
+ t.Run("Check cached cat file batch", func(t *testing.T) {
+ _, err = wr.Write([]byte("95bb4d39648ee7e325106df01a621c530863a653" + "\n"))
+ require.NoError(t, err)
+
+ sha, typ, size, err := ReadBatchLine(r)
+ require.NoError(t, err)
+ assert.Equal(t, "commit", typ)
+ assert.EqualValues(t, []byte("95bb4d39648ee7e325106df01a621c530863a653"), sha)
+ assert.EqualValues(t, 144, size)
+ })
+
+ t.Run("Cancel cached cat file batch", func(t *testing.T) {
+ cancel1()
+ assert.False(t, repo.batchInUse)
+ assert.NotNil(t, repo.batch)
+ })
+
+ t.Run("Request cached cat file batch", func(t *testing.T) {
+ wr, _, _, err := repo.CatFileBatch(ctx)
+ require.NoError(t, err)
+ assert.NotNil(t, repo.batch)
+ assert.Equal(t, repo.batch.Writer, wr)
+ assert.True(t, repo.batchInUse)
+
+ t.Run("Close git repo", func(t *testing.T) {
+ require.NoError(t, repo.Close())
+ assert.Nil(t, repo.batch)
+ })
+
+ _, err = wr.Write([]byte("95bb4d39648ee7e325106df01a621c530863a653" + "\n"))
+ require.Error(t, err)
+ })
+}
+
+// This unit test relies on the implementation detail of CatFileBatchCheck.
+func TestCatFileBatchCheck(t *testing.T) {
+ ctx, cancel := context.WithCancel(t.Context())
+ defer cancel()
+
+ repo, err := OpenRepository(ctx, "./tests/repos/repo1_bare")
+ require.NoError(t, err)
+ defer repo.Close()
+
+ var wr WriteCloserError
+ var r *bufio.Reader
+ var cancel1 func()
+ t.Run("Request cat file batch check", func(t *testing.T) {
+ assert.Nil(t, repo.check)
+ wr, r, cancel1, err = repo.CatFileBatchCheck(ctx)
+ require.NoError(t, err)
+ assert.NotNil(t, repo.check)
+ assert.Equal(t, repo.check.Writer, wr)
+ assert.True(t, repo.checkInUse)
+ })
+
+ t.Run("Request temporary cat file batch check", func(t *testing.T) {
+ wr, r, cancel, err := repo.CatFileBatchCheck(ctx)
+ require.NoError(t, err)
+ assert.NotEqual(t, repo.check.Writer, wr)
+
+ t.Run("Check temporary cat file batch check", func(t *testing.T) {
+ _, err = wr.Write([]byte("test" + "\n"))
+ require.NoError(t, err)
+
+ sha, typ, size, err := ReadBatchLine(r)
+ require.NoError(t, err)
+ assert.Equal(t, "tag", typ)
+ assert.EqualValues(t, []byte("3ad28a9149a2864384548f3d17ed7f38014c9e8a"), sha)
+ assert.EqualValues(t, 807, size)
+ })
+
+ cancel()
+ assert.True(t, repo.checkInUse)
+ })
+
+ t.Run("Check cached cat file batch check", func(t *testing.T) {
+ _, err = wr.Write([]byte("test" + "\n"))
+ require.NoError(t, err)
+
+ sha, typ, size, err := ReadBatchLine(r)
+ require.NoError(t, err)
+ assert.Equal(t, "tag", typ)
+ assert.EqualValues(t, []byte("3ad28a9149a2864384548f3d17ed7f38014c9e8a"), sha)
+ assert.EqualValues(t, 807, size)
+ })
+
+ t.Run("Cancel cached cat file batch check", func(t *testing.T) {
+ cancel1()
+ assert.False(t, repo.checkInUse)
+ assert.NotNil(t, repo.check)
+ })
+
+ t.Run("Request cached cat file batch check", func(t *testing.T) {
+ wr, _, _, err := repo.CatFileBatchCheck(ctx)
+ require.NoError(t, err)
+ assert.NotNil(t, repo.check)
+ assert.Equal(t, repo.check.Writer, wr)
+ assert.True(t, repo.checkInUse)
+
+ t.Run("Close git repo", func(t *testing.T) {
+ require.NoError(t, repo.Close())
+ assert.Nil(t, repo.check)
+ })
+
+ _, err = wr.Write([]byte("test" + "\n"))
+ require.Error(t, err)
+ })
+}
diff --git a/modules/git/repo_blob.go b/modules/git/repo_blob.go
deleted file mode 100644
index 698b6c7074..0000000000
--- a/modules/git/repo_blob.go
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package git
-
-// GetBlob finds the blob object in the repository.
-func (repo *Repository) GetBlob(idStr string) (*Blob, error) {
- id, err := NewIDFromString(idStr)
- if err != nil {
- return nil, err
- }
- return repo.getBlob(id)
-}
diff --git a/modules/git/repo_blob_gogit.go b/modules/git/repo_blob_gogit.go
deleted file mode 100644
index 66c8c2775c..0000000000
--- a/modules/git/repo_blob_gogit.go
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "github.com/go-git/go-git/v5/plumbing"
-)
-
-func (repo *Repository) getBlob(id ObjectID) (*Blob, error) {
- encodedObj, err := repo.gogitRepo.Storer.EncodedObject(plumbing.AnyObject, plumbing.Hash(id.RawValue()))
- if err != nil {
- return nil, ErrNotExist{id.String(), ""}
- }
-
- return &Blob{
- ID: id,
- gogitEncodedObj: encodedObj,
- }, nil
-}
diff --git a/modules/git/repo_blob_nogogit.go b/modules/git/repo_blob_nogogit.go
deleted file mode 100644
index 04b0fb00ff..0000000000
--- a/modules/git/repo_blob_nogogit.go
+++ /dev/null
@@ -1,16 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-func (repo *Repository) getBlob(id ObjectID) (*Blob, error) {
- if id.IsZero() {
- return nil, ErrNotExist{id.String(), ""}
- }
- return &Blob{
- ID: id,
- repo: repo,
- }, nil
-}
diff --git a/modules/git/repo_blob_test.go b/modules/git/repo_blob_test.go
index 8a5f5fcd5b..b01847955f 100644
--- a/modules/git/repo_blob_test.go
+++ b/modules/git/repo_blob_test.go
@@ -10,12 +10,13 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepository_GetBlob_Found(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := openRepositoryWithDefaultContext(repoPath)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer r.Close()
testCases := []struct {
@@ -28,14 +29,14 @@ func TestRepository_GetBlob_Found(t *testing.T) {
for _, testCase := range testCases {
blob, err := r.GetBlob(testCase.OID)
- assert.NoError(t, err)
+ require.NoError(t, err)
dataReader, err := blob.DataAsync()
- assert.NoError(t, err)
+ require.NoError(t, err)
data, err := io.ReadAll(dataReader)
- assert.NoError(t, dataReader.Close())
- assert.NoError(t, err)
+ require.NoError(t, dataReader.Close())
+ require.NoError(t, err)
assert.Equal(t, testCase.Data, data)
}
}
@@ -43,7 +44,7 @@ func TestRepository_GetBlob_Found(t *testing.T) {
func TestRepository_GetBlob_NotExist(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := openRepositoryWithDefaultContext(repoPath)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer r.Close()
testCase := "0000000000000000000000000000000000000000"
@@ -57,7 +58,7 @@ func TestRepository_GetBlob_NotExist(t *testing.T) {
func TestRepository_GetBlob_NoId(t *testing.T) {
repoPath := filepath.Join(testReposDir, "repo1_bare")
r, err := openRepositoryWithDefaultContext(repoPath)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer r.Close()
testCase := ""
diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go
index 552ae2bb8c..1992060351 100644
--- a/modules/git/repo_branch.go
+++ b/modules/git/repo_branch.go
@@ -5,10 +5,15 @@
package git
import (
+ "bufio"
+ "bytes"
"context"
"errors"
"fmt"
+ "io"
"strings"
+
+ "forgejo.org/modules/log"
)
// BranchPrefix base dir of the branch information file store on git
@@ -157,3 +162,188 @@ func (repo *Repository) RenameBranch(from, to string) error {
_, _, err := NewCommand(repo.Ctx, "branch", "-m").AddDynamicArguments(from, to).RunStdString(&RunOpts{Dir: repo.Path})
return err
}
+
+// IsObjectExist returns true if given reference exists in the repository.
+func (repo *Repository) IsObjectExist(name string) bool {
+ if name == "" {
+ return false
+ }
+
+ wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
+ if err != nil {
+ log.Debug("Error writing to CatFileBatchCheck %v", err)
+ return false
+ }
+ defer cancel()
+ _, err = wr.Write([]byte(name + "\n"))
+ if err != nil {
+ log.Debug("Error writing to CatFileBatchCheck %v", err)
+ return false
+ }
+ sha, _, _, err := ReadBatchLine(rd)
+ return err == nil && bytes.HasPrefix(sha, []byte(strings.TrimSpace(name)))
+}
+
+// IsReferenceExist returns true if given reference exists in the repository.
+func (repo *Repository) IsReferenceExist(name string) bool {
+ if name == "" {
+ return false
+ }
+
+ wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
+ if err != nil {
+ log.Debug("Error writing to CatFileBatchCheck %v", err)
+ return false
+ }
+ defer cancel()
+ _, err = wr.Write([]byte(name + "\n"))
+ if err != nil {
+ log.Debug("Error writing to CatFileBatchCheck %v", err)
+ return false
+ }
+ _, _, _, err = ReadBatchLine(rd)
+ return err == nil
+}
+
+// IsBranchExist returns true if given branch exists in current repository.
+func (repo *Repository) IsBranchExist(name string) bool {
+ if repo == nil || name == "" {
+ return false
+ }
+
+ return repo.IsReferenceExist(BranchPrefix + name)
+}
+
+// GetBranchNames returns branches from the repository, skipping "skip" initial branches and
+// returning at most "limit" branches, or all branches if "limit" is 0.
+func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
+ return callShowRef(repo.Ctx, repo.Path, BranchPrefix, TrustedCmdArgs{BranchPrefix, "--sort=-committerdate"}, skip, limit)
+}
+
+// WalkReferences walks all the references from the repository
+// refType should be empty, ObjectTag or ObjectBranch. All other values are equivalent to empty.
+func (repo *Repository) WalkReferences(refType ObjectType, skip, limit int, walkfn func(sha1, refname string) error) (int, error) {
+ var args TrustedCmdArgs
+ switch refType {
+ case ObjectTag:
+ args = TrustedCmdArgs{TagPrefix, "--sort=-taggerdate"}
+ case ObjectBranch:
+ args = TrustedCmdArgs{BranchPrefix, "--sort=-committerdate"}
+ }
+
+ return WalkShowRef(repo.Ctx, repo.Path, args, skip, limit, walkfn)
+}
+
+// callShowRef return refs, if limit = 0 it will not limit
+func callShowRef(ctx context.Context, repoPath, trimPrefix string, extraArgs TrustedCmdArgs, skip, limit int) (branchNames []string, countAll int, err error) {
+ countAll, err = WalkShowRef(ctx, repoPath, extraArgs, skip, limit, func(_, branchName string) error {
+ branchName = strings.TrimPrefix(branchName, trimPrefix)
+ branchNames = append(branchNames, branchName)
+
+ return nil
+ })
+ return branchNames, countAll, err
+}
+
+func WalkShowRef(ctx context.Context, repoPath string, extraArgs TrustedCmdArgs, skip, limit int, walkfn func(sha1, refname string) error) (countAll int, err error) {
+ stdoutReader, stdoutWriter := io.Pipe()
+ defer func() {
+ _ = stdoutReader.Close()
+ _ = stdoutWriter.Close()
+ }()
+
+ go func() {
+ stderrBuilder := &strings.Builder{}
+ args := TrustedCmdArgs{"for-each-ref", "--format=%(objectname) %(refname)"}
+ args = append(args, extraArgs...)
+ err := NewCommand(ctx, args...).Run(&RunOpts{
+ Dir: repoPath,
+ Stdout: stdoutWriter,
+ Stderr: stderrBuilder,
+ })
+ if err != nil {
+ if stderrBuilder.Len() == 0 {
+ _ = stdoutWriter.Close()
+ return
+ }
+ _ = stdoutWriter.CloseWithError(ConcatenateError(err, stderrBuilder.String()))
+ } else {
+ _ = stdoutWriter.Close()
+ }
+ }()
+
+ i := 0
+ bufReader := bufio.NewReader(stdoutReader)
+ for i < skip {
+ _, isPrefix, err := bufReader.ReadLine()
+ if err == io.EOF {
+ return i, nil
+ }
+ if err != nil {
+ return 0, err
+ }
+ if !isPrefix {
+ i++
+ }
+ }
+ for limit == 0 || i < skip+limit {
+ // The output of show-ref is simply a list:
+ // SP [ LF
+ sha, err := bufReader.ReadString(' ')
+ if err == io.EOF {
+ return i, nil
+ }
+ if err != nil {
+ return 0, err
+ }
+
+ branchName, err := bufReader.ReadString('\n')
+ if err == io.EOF {
+ // This shouldn't happen... but we'll tolerate it for the sake of peace
+ return i, nil
+ }
+ if err != nil {
+ return i, err
+ }
+
+ if len(branchName) > 0 {
+ branchName = branchName[:len(branchName)-1]
+ }
+
+ if len(sha) > 0 {
+ sha = sha[:len(sha)-1]
+ }
+
+ err = walkfn(sha, branchName)
+ if err != nil {
+ return i, err
+ }
+ i++
+ }
+ // count all refs
+ for limit != 0 {
+ _, isPrefix, err := bufReader.ReadLine()
+ if err == io.EOF {
+ return i, nil
+ }
+ if err != nil {
+ return 0, err
+ }
+ if !isPrefix {
+ i++
+ }
+ }
+ return i, nil
+}
+
+// GetRefsBySha returns all references filtered with prefix that belong to a sha commit hash
+func (repo *Repository) GetRefsBySha(sha, prefix string) ([]string, error) {
+ var revList []string
+ _, err := WalkShowRef(repo.Ctx, repo.Path, nil, 0, 0, func(walkSha, refname string) error {
+ if walkSha == sha && strings.HasPrefix(refname, prefix) {
+ revList = append(revList, refname)
+ }
+ return nil
+ })
+ return revList, err
+}
diff --git a/modules/git/repo_branch_gogit.go b/modules/git/repo_branch_gogit.go
deleted file mode 100644
index d1ec14d811..0000000000
--- a/modules/git/repo_branch_gogit.go
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "sort"
- "strings"
-
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/storer"
-)
-
-// IsObjectExist returns true if given reference exists in the repository.
-func (repo *Repository) IsObjectExist(name string) bool {
- if name == "" {
- return false
- }
-
- _, err := repo.gogitRepo.ResolveRevision(plumbing.Revision(name))
-
- return err == nil
-}
-
-// IsReferenceExist returns true if given reference exists in the repository.
-func (repo *Repository) IsReferenceExist(name string) bool {
- if name == "" {
- return false
- }
-
- reference, err := repo.gogitRepo.Reference(plumbing.ReferenceName(name), true)
- if err != nil {
- return false
- }
- return reference.Type() != plumbing.InvalidReference
-}
-
-// IsBranchExist returns true if given branch exists in current repository.
-func (repo *Repository) IsBranchExist(name string) bool {
- if name == "" {
- return false
- }
- reference, err := repo.gogitRepo.Reference(plumbing.ReferenceName(BranchPrefix+name), true)
- if err != nil {
- return false
- }
- return reference.Type() != plumbing.InvalidReference
-}
-
-// GetBranches returns branches from the repository, skipping "skip" initial branches and
-// returning at most "limit" branches, or all branches if "limit" is 0.
-// Branches are returned with sort of `-commiterdate` as the nogogit
-// implementation. This requires full fetch, sort and then the
-// skip/limit applies later as gogit returns in undefined order.
-func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
- type BranchData struct {
- name string
- committerDate int64
- }
- var branchData []BranchData
-
- branchIter, err := repo.gogitRepo.Branches()
- if err != nil {
- return nil, 0, err
- }
-
- _ = branchIter.ForEach(func(branch *plumbing.Reference) error {
- obj, err := repo.gogitRepo.CommitObject(branch.Hash())
- if err != nil {
- // skip branch if can't find commit
- return nil
- }
-
- branchData = append(branchData, BranchData{strings.TrimPrefix(branch.Name().String(), BranchPrefix), obj.Committer.When.Unix()})
- return nil
- })
-
- sort.Slice(branchData, func(i, j int) bool {
- return !(branchData[i].committerDate < branchData[j].committerDate)
- })
-
- var branchNames []string
- maxPos := len(branchData)
- if limit > 0 {
- maxPos = min(skip+limit, maxPos)
- }
- for i := skip; i < maxPos; i++ {
- branchNames = append(branchNames, branchData[i].name)
- }
-
- return branchNames, len(branchData), nil
-}
-
-// WalkReferences walks all the references from the repository
-func (repo *Repository) WalkReferences(arg ObjectType, skip, limit int, walkfn func(sha1, refname string) error) (int, error) {
- i := 0
- var iter storer.ReferenceIter
- var err error
- switch arg {
- case ObjectTag:
- iter, err = repo.gogitRepo.Tags()
- case ObjectBranch:
- iter, err = repo.gogitRepo.Branches()
- default:
- iter, err = repo.gogitRepo.References()
- }
- if err != nil {
- return i, err
- }
- defer iter.Close()
-
- err = iter.ForEach(func(ref *plumbing.Reference) error {
- if i < skip {
- i++
- return nil
- }
- err := walkfn(ref.Hash().String(), string(ref.Name()))
- i++
- if err != nil {
- return err
- }
- if limit != 0 && i >= skip+limit {
- return storer.ErrStop
- }
- return nil
- })
- return i, err
-}
-
-// GetRefsBySha returns all references filtered with prefix that belong to a sha commit hash
-func (repo *Repository) GetRefsBySha(sha, prefix string) ([]string, error) {
- var revList []string
- iter, err := repo.gogitRepo.References()
- if err != nil {
- return nil, err
- }
- err = iter.ForEach(func(ref *plumbing.Reference) error {
- if ref.Hash().String() == sha && strings.HasPrefix(string(ref.Name()), prefix) {
- revList = append(revList, string(ref.Name()))
- }
- return nil
- })
- return revList, err
-}
diff --git a/modules/git/repo_branch_nogogit.go b/modules/git/repo_branch_nogogit.go
deleted file mode 100644
index 470faebe25..0000000000
--- a/modules/git/repo_branch_nogogit.go
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "bufio"
- "bytes"
- "context"
- "io"
- "strings"
-
- "code.gitea.io/gitea/modules/log"
-)
-
-// IsObjectExist returns true if given reference exists in the repository.
-func (repo *Repository) IsObjectExist(name string) bool {
- if name == "" {
- return false
- }
-
- wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
- defer cancel()
- _, err := wr.Write([]byte(name + "\n"))
- if err != nil {
- log.Debug("Error writing to CatFileBatchCheck %v", err)
- return false
- }
- sha, _, _, err := ReadBatchLine(rd)
- return err == nil && bytes.HasPrefix(sha, []byte(strings.TrimSpace(name)))
-}
-
-// IsReferenceExist returns true if given reference exists in the repository.
-func (repo *Repository) IsReferenceExist(name string) bool {
- if name == "" {
- return false
- }
-
- wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
- defer cancel()
- _, err := wr.Write([]byte(name + "\n"))
- if err != nil {
- log.Debug("Error writing to CatFileBatchCheck %v", err)
- return false
- }
- _, _, _, err = ReadBatchLine(rd)
- return err == nil
-}
-
-// IsBranchExist returns true if given branch exists in current repository.
-func (repo *Repository) IsBranchExist(name string) bool {
- if repo == nil || name == "" {
- return false
- }
-
- return repo.IsReferenceExist(BranchPrefix + name)
-}
-
-// GetBranchNames returns branches from the repository, skipping "skip" initial branches and
-// returning at most "limit" branches, or all branches if "limit" is 0.
-func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
- return callShowRef(repo.Ctx, repo.Path, BranchPrefix, TrustedCmdArgs{BranchPrefix, "--sort=-committerdate"}, skip, limit)
-}
-
-// WalkReferences walks all the references from the repository
-// refType should be empty, ObjectTag or ObjectBranch. All other values are equivalent to empty.
-func (repo *Repository) WalkReferences(refType ObjectType, skip, limit int, walkfn func(sha1, refname string) error) (int, error) {
- var args TrustedCmdArgs
- switch refType {
- case ObjectTag:
- args = TrustedCmdArgs{TagPrefix, "--sort=-taggerdate"}
- case ObjectBranch:
- args = TrustedCmdArgs{BranchPrefix, "--sort=-committerdate"}
- }
-
- return WalkShowRef(repo.Ctx, repo.Path, args, skip, limit, walkfn)
-}
-
-// callShowRef return refs, if limit = 0 it will not limit
-func callShowRef(ctx context.Context, repoPath, trimPrefix string, extraArgs TrustedCmdArgs, skip, limit int) (branchNames []string, countAll int, err error) {
- countAll, err = WalkShowRef(ctx, repoPath, extraArgs, skip, limit, func(_, branchName string) error {
- branchName = strings.TrimPrefix(branchName, trimPrefix)
- branchNames = append(branchNames, branchName)
-
- return nil
- })
- return branchNames, countAll, err
-}
-
-func WalkShowRef(ctx context.Context, repoPath string, extraArgs TrustedCmdArgs, skip, limit int, walkfn func(sha1, refname string) error) (countAll int, err error) {
- stdoutReader, stdoutWriter := io.Pipe()
- defer func() {
- _ = stdoutReader.Close()
- _ = stdoutWriter.Close()
- }()
-
- go func() {
- stderrBuilder := &strings.Builder{}
- args := TrustedCmdArgs{"for-each-ref", "--format=%(objectname) %(refname)"}
- args = append(args, extraArgs...)
- err := NewCommand(ctx, args...).Run(&RunOpts{
- Dir: repoPath,
- Stdout: stdoutWriter,
- Stderr: stderrBuilder,
- })
- if err != nil {
- if stderrBuilder.Len() == 0 {
- _ = stdoutWriter.Close()
- return
- }
- _ = stdoutWriter.CloseWithError(ConcatenateError(err, stderrBuilder.String()))
- } else {
- _ = stdoutWriter.Close()
- }
- }()
-
- i := 0
- bufReader := bufio.NewReader(stdoutReader)
- for i < skip {
- _, isPrefix, err := bufReader.ReadLine()
- if err == io.EOF {
- return i, nil
- }
- if err != nil {
- return 0, err
- }
- if !isPrefix {
- i++
- }
- }
- for limit == 0 || i < skip+limit {
- // The output of show-ref is simply a list:
- // ] SP [ LF
- sha, err := bufReader.ReadString(' ')
- if err == io.EOF {
- return i, nil
- }
- if err != nil {
- return 0, err
- }
-
- branchName, err := bufReader.ReadString('\n')
- if err == io.EOF {
- // This shouldn't happen... but we'll tolerate it for the sake of peace
- return i, nil
- }
- if err != nil {
- return i, err
- }
-
- if len(branchName) > 0 {
- branchName = branchName[:len(branchName)-1]
- }
-
- if len(sha) > 0 {
- sha = sha[:len(sha)-1]
- }
-
- err = walkfn(sha, branchName)
- if err != nil {
- return i, err
- }
- i++
- }
- // count all refs
- for limit != 0 {
- _, isPrefix, err := bufReader.ReadLine()
- if err == io.EOF {
- return i, nil
- }
- if err != nil {
- return 0, err
- }
- if !isPrefix {
- i++
- }
- }
- return i, nil
-}
-
-// GetRefsBySha returns all references filtered with prefix that belong to a sha commit hash
-func (repo *Repository) GetRefsBySha(sha, prefix string) ([]string, error) {
- var revList []string
- _, err := WalkShowRef(repo.Ctx, repo.Path, nil, 0, 0, func(walkSha, refname string) error {
- if walkSha == sha && strings.HasPrefix(refname, prefix) {
- revList = append(revList, refname)
- }
- return nil
- })
- return revList, err
-}
diff --git a/modules/git/repo_branch_test.go b/modules/git/repo_branch_test.go
index fe788946e5..610c8457d9 100644
--- a/modules/git/repo_branch_test.go
+++ b/modules/git/repo_branch_test.go
@@ -8,32 +8,33 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepository_GetBranches(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
branches, countAll, err := bareRepo1.GetBranchNames(0, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, branches, 2)
assert.EqualValues(t, 3, countAll)
assert.ElementsMatch(t, []string{"master", "branch2"}, branches)
branches, countAll, err = bareRepo1.GetBranchNames(0, 0)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, branches, 3)
assert.EqualValues(t, 3, countAll)
assert.ElementsMatch(t, []string{"master", "branch2", "branch1"}, branches)
branches, countAll, err = bareRepo1.GetBranchNames(5, 1)
- assert.NoError(t, err)
- assert.Len(t, branches, 0)
+ require.NoError(t, err)
+ assert.Empty(t, branches)
assert.EqualValues(t, 3, countAll)
assert.ElementsMatch(t, []string{}, branches)
}
@@ -64,20 +65,20 @@ func TestGetRefsBySha(t *testing.T) {
// do not exist
branches, err := bareRepo5.GetRefsBySha("8006ff9adbf0cb94da7dad9e537e53817f9fa5c0", "")
- assert.NoError(t, err)
- assert.Len(t, branches, 0)
+ require.NoError(t, err)
+ assert.Empty(t, branches)
// refs/pull/1/head
branches, err = bareRepo5.GetRefsBySha("c83380d7056593c51a699d12b9c00627bd5743e9", PullPrefix)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []string{"refs/pull/1/head"}, branches)
branches, err = bareRepo5.GetRefsBySha("d8e0bbb45f200e67d9a784ce55bd90821af45ebd", BranchPrefix)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []string{"refs/heads/master", "refs/heads/master-clone"}, branches)
branches, err = bareRepo5.GetRefsBySha("58a4bcc53ac13e7ff76127e0fb518b5262bf09af", BranchPrefix)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []string{"refs/heads/test-patch-1"}, branches)
}
@@ -94,3 +95,103 @@ func BenchmarkGetRefsBySha(b *testing.B) {
_, _ = bareRepo5.GetRefsBySha("c83380d7056593c51a699d12b9c00627bd5743e9", "")
_, _ = bareRepo5.GetRefsBySha("58a4bcc53ac13e7ff76127e0fb518b5262bf09af", "")
}
+
+func TestRepository_IsObjectExist(t *testing.T) {
+ repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
+ require.NoError(t, err)
+ defer repo.Close()
+
+ supportShortHash := true
+
+ tests := []struct {
+ name string
+ arg string
+ want bool
+ }{
+ {
+ name: "empty",
+ arg: "",
+ want: false,
+ },
+ {
+ name: "branch",
+ arg: "master",
+ want: false,
+ },
+ {
+ name: "commit hash",
+ arg: "ce064814f4a0d337b333e646ece456cd39fab612",
+ want: true,
+ },
+ {
+ name: "short commit hash",
+ arg: "ce06481",
+ want: supportShortHash,
+ },
+ {
+ name: "blob hash",
+ arg: "153f451b9ee7fa1da317ab17a127e9fd9d384310",
+ want: true,
+ },
+ {
+ name: "short blob hash",
+ arg: "153f451",
+ want: supportShortHash,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ assert.Equal(t, tt.want, repo.IsObjectExist(tt.arg))
+ })
+ }
+}
+
+func TestRepository_IsReferenceExist(t *testing.T) {
+ repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
+ require.NoError(t, err)
+ defer repo.Close()
+
+ supportBlobHash := true
+
+ tests := []struct {
+ name string
+ arg string
+ want bool
+ }{
+ {
+ name: "empty",
+ arg: "",
+ want: false,
+ },
+ {
+ name: "branch",
+ arg: "master",
+ want: true,
+ },
+ {
+ name: "commit hash",
+ arg: "ce064814f4a0d337b333e646ece456cd39fab612",
+ want: true,
+ },
+ {
+ name: "short commit hash",
+ arg: "ce06481",
+ want: true,
+ },
+ {
+ name: "blob hash",
+ arg: "153f451b9ee7fa1da317ab17a127e9fd9d384310",
+ want: supportBlobHash,
+ },
+ {
+ name: "short blob hash",
+ arg: "153f451",
+ want: supportBlobHash,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ assert.Equal(t, tt.want, repo.IsReferenceExist(tt.arg))
+ })
+ }
+}
diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go
index f9168bef7e..65ab6fd3fd 100644
--- a/modules/git/repo_commit.go
+++ b/modules/git/repo_commit.go
@@ -5,13 +5,16 @@
package git
import (
+ "bufio"
"bytes"
+ "errors"
"io"
"strconv"
"strings"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
// GetBranchCommitID returns last commit ID string of given branch.
@@ -19,7 +22,9 @@ func (repo *Repository) GetBranchCommitID(name string) (string, error) {
return repo.GetRefCommitID(BranchPrefix + name)
}
-// GetTagCommitID returns last commit ID string of given tag.
+// GetTagCommitID returns last commit ID string of given tag. If the tag is an
+// annotated tag it will return the objectID of that tag instead of the commitID
+// the tag is pointing to. `GetTagCommit` handles annotated tags correctly.
func (repo *Repository) GetTagCommitID(name string) (string, error) {
return repo.GetRefCommitID(TagPrefix + name)
}
@@ -225,7 +230,7 @@ func (repo *Repository) CommitsByFileAndRange(opts CommitsByFileAndRangeOptions)
go func() {
stderr := strings.Builder{}
gitCmd := NewCommand(repo.Ctx, "rev-list").
- AddOptionFormat("--max-count=%d", setting.Git.CommitsRangeSize*opts.Page).
+ AddOptionFormat("--max-count=%d", setting.Git.CommitsRangeSize).
AddOptionFormat("--skip=%d", skip)
gitCmd.AddDynamicArguments(opts.Revision)
@@ -513,3 +518,162 @@ func (repo *Repository) AddLastCommitCache(cacheKey, fullName, sha string) error
}
return nil
}
+
+// ResolveReference resolves a name to a reference
+func (repo *Repository) ResolveReference(name string) (string, error) {
+ stdout, _, err := NewCommand(repo.Ctx, "show-ref", "--hash").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
+ if err != nil {
+ if strings.Contains(err.Error(), "not a valid ref") {
+ return "", ErrNotExist{name, ""}
+ }
+ return "", err
+ }
+ stdout = strings.TrimSpace(stdout)
+ if stdout == "" {
+ return "", ErrNotExist{name, ""}
+ }
+
+ return stdout, nil
+}
+
+// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
+func (repo *Repository) GetRefCommitID(name string) (string, error) {
+ wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
+ if err != nil {
+ return "", err
+ }
+ defer cancel()
+ _, err = wr.Write([]byte(name + "\n"))
+ if err != nil {
+ return "", err
+ }
+ shaBs, _, _, err := ReadBatchLine(rd)
+ if IsErrNotExist(err) {
+ return "", ErrNotExist{name, ""}
+ }
+
+ return string(shaBs), nil
+}
+
+// SetReference sets the commit ID string of given reference (e.g. branch or tag).
+func (repo *Repository) SetReference(name, commitID string) error {
+ _, _, err := NewCommand(repo.Ctx, "update-ref").AddDynamicArguments(name, commitID).RunStdString(&RunOpts{Dir: repo.Path})
+ return err
+}
+
+// RemoveReference removes the given reference (e.g. branch or tag).
+func (repo *Repository) RemoveReference(name string) error {
+ _, _, err := NewCommand(repo.Ctx, "update-ref", "--no-deref", "-d").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
+ return err
+}
+
+// IsCommitExist returns true if given commit exists in current repository.
+func (repo *Repository) IsCommitExist(name string) bool {
+ if err := ensureValidGitRepository(repo.Ctx, repo.Path); err != nil {
+ log.Error("IsCommitExist: %v", err)
+ return false
+ }
+ _, _, err := NewCommand(repo.Ctx, "cat-file", "-e").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
+ return err == nil
+}
+
+func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
+ wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer cancel()
+
+ _, _ = wr.Write([]byte(id.String() + "\n"))
+
+ return repo.getCommitFromBatchReader(rd, id)
+}
+
+func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID) (*Commit, error) {
+ _, typ, size, err := ReadBatchLine(rd)
+ if err != nil {
+ if errors.Is(err, io.EOF) || IsErrNotExist(err) {
+ return nil, ErrNotExist{ID: id.String()}
+ }
+ return nil, err
+ }
+
+ switch typ {
+ case "missing":
+ return nil, ErrNotExist{ID: id.String()}
+ case "tag":
+ // then we need to parse the tag
+ // and load the commit
+ data, err := io.ReadAll(io.LimitReader(rd, size))
+ if err != nil {
+ return nil, err
+ }
+ _, err = rd.Discard(1)
+ if err != nil {
+ return nil, err
+ }
+ tag, err := parseTagData(id.Type(), data)
+ if err != nil {
+ return nil, err
+ }
+
+ commit, err := tag.Commit(repo)
+ if err != nil {
+ return nil, err
+ }
+
+ return commit, nil
+ case "commit":
+ commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
+ if err != nil {
+ return nil, err
+ }
+ _, err = rd.Discard(1)
+ if err != nil {
+ return nil, err
+ }
+
+ return commit, nil
+ default:
+ log.Debug("Unknown typ: %s", typ)
+ if err := DiscardFull(rd, size+1); err != nil {
+ return nil, err
+ }
+ return nil, ErrNotExist{
+ ID: id.String(),
+ }
+ }
+}
+
+// ConvertToGitID returns a GitHash object from a potential ID string
+func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) {
+ objectFormat, err := repo.GetObjectFormat()
+ if err != nil {
+ return nil, err
+ }
+ if len(commitID) == objectFormat.FullLength() && objectFormat.IsValid(commitID) {
+ ID, err := NewIDFromString(commitID)
+ if err == nil {
+ return ID, nil
+ }
+ }
+
+ wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer cancel()
+ _, err = wr.Write([]byte(commitID + "\n"))
+ if err != nil {
+ return nil, err
+ }
+ sha, _, _, err := ReadBatchLine(rd)
+ if err != nil {
+ if IsErrNotExist(err) {
+ return nil, ErrNotExist{commitID, ""}
+ }
+ return nil, err
+ }
+
+ return MustIDFromString(string(sha)), nil
+}
diff --git a/modules/git/repo_commit_gogit.go b/modules/git/repo_commit_gogit.go
deleted file mode 100644
index 84580be9a5..0000000000
--- a/modules/git/repo_commit_gogit.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "strings"
-
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/hash"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
-func (repo *Repository) GetRefCommitID(name string) (string, error) {
- ref, err := repo.gogitRepo.Reference(plumbing.ReferenceName(name), true)
- if err != nil {
- if err == plumbing.ErrReferenceNotFound {
- return "", ErrNotExist{
- ID: name,
- }
- }
- return "", err
- }
-
- return ref.Hash().String(), nil
-}
-
-// SetReference sets the commit ID string of given reference (e.g. branch or tag).
-func (repo *Repository) SetReference(name, commitID string) error {
- return repo.gogitRepo.Storer.SetReference(plumbing.NewReferenceFromStrings(name, commitID))
-}
-
-// RemoveReference removes the given reference (e.g. branch or tag).
-func (repo *Repository) RemoveReference(name string) error {
- return repo.gogitRepo.Storer.RemoveReference(plumbing.ReferenceName(name))
-}
-
-// ConvertToHash returns a Hash object from a potential ID string
-func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) {
- objectFormat, err := repo.GetObjectFormat()
- if err != nil {
- return nil, err
- }
- if len(commitID) == hash.HexSize && objectFormat.IsValid(commitID) {
- ID, err := NewIDFromString(commitID)
- if err == nil {
- return ID, nil
- }
- }
-
- actualCommitID, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(commitID).RunStdString(&RunOpts{Dir: repo.Path})
- actualCommitID = strings.TrimSpace(actualCommitID)
- if err != nil {
- if strings.Contains(err.Error(), "unknown revision or path") ||
- strings.Contains(err.Error(), "fatal: Needed a single revision") {
- return objectFormat.EmptyObjectID(), ErrNotExist{commitID, ""}
- }
- return objectFormat.EmptyObjectID(), err
- }
-
- return NewIDFromString(actualCommitID)
-}
-
-// IsCommitExist returns true if given commit exists in current repository.
-func (repo *Repository) IsCommitExist(name string) bool {
- hash, err := repo.ConvertToGitID(name)
- if err != nil {
- return false
- }
- _, err = repo.gogitRepo.CommitObject(plumbing.Hash(hash.RawValue()))
- return err == nil
-}
-
-func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
- var tagObject *object.Tag
-
- commitID := plumbing.Hash(id.RawValue())
- gogitCommit, err := repo.gogitRepo.CommitObject(commitID)
- if err == plumbing.ErrObjectNotFound {
- tagObject, err = repo.gogitRepo.TagObject(commitID)
- if err == plumbing.ErrObjectNotFound {
- return nil, ErrNotExist{
- ID: id.String(),
- }
- }
- if err == nil {
- gogitCommit, err = repo.gogitRepo.CommitObject(tagObject.Target)
- }
- // if we get a plumbing.ErrObjectNotFound here then the repository is broken and it should be 500
- }
- if err != nil {
- return nil, err
- }
-
- commit := convertCommit(gogitCommit)
- commit.repo = repo
-
- tree, err := gogitCommit.Tree()
- if err != nil {
- return nil, err
- }
-
- commit.Tree.ID = ParseGogitHash(tree.Hash)
- commit.Tree.gogitTree = tree
-
- return commit, nil
-}
diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go
deleted file mode 100644
index ae4c21aaa3..0000000000
--- a/modules/git/repo_commit_nogogit.go
+++ /dev/null
@@ -1,161 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "bufio"
- "errors"
- "io"
- "strings"
-
- "code.gitea.io/gitea/modules/log"
-)
-
-// ResolveReference resolves a name to a reference
-func (repo *Repository) ResolveReference(name string) (string, error) {
- stdout, _, err := NewCommand(repo.Ctx, "show-ref", "--hash").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
- if err != nil {
- if strings.Contains(err.Error(), "not a valid ref") {
- return "", ErrNotExist{name, ""}
- }
- return "", err
- }
- stdout = strings.TrimSpace(stdout)
- if stdout == "" {
- return "", ErrNotExist{name, ""}
- }
-
- return stdout, nil
-}
-
-// GetRefCommitID returns the last commit ID string of given reference (branch or tag).
-func (repo *Repository) GetRefCommitID(name string) (string, error) {
- wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
- defer cancel()
- _, err := wr.Write([]byte(name + "\n"))
- if err != nil {
- return "", err
- }
- shaBs, _, _, err := ReadBatchLine(rd)
- if IsErrNotExist(err) {
- return "", ErrNotExist{name, ""}
- }
-
- return string(shaBs), nil
-}
-
-// SetReference sets the commit ID string of given reference (e.g. branch or tag).
-func (repo *Repository) SetReference(name, commitID string) error {
- _, _, err := NewCommand(repo.Ctx, "update-ref").AddDynamicArguments(name, commitID).RunStdString(&RunOpts{Dir: repo.Path})
- return err
-}
-
-// RemoveReference removes the given reference (e.g. branch or tag).
-func (repo *Repository) RemoveReference(name string) error {
- _, _, err := NewCommand(repo.Ctx, "update-ref", "--no-deref", "-d").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
- return err
-}
-
-// IsCommitExist returns true if given commit exists in current repository.
-func (repo *Repository) IsCommitExist(name string) bool {
- _, _, err := NewCommand(repo.Ctx, "cat-file", "-e").AddDynamicArguments(name).RunStdString(&RunOpts{Dir: repo.Path})
- return err == nil
-}
-
-func (repo *Repository) getCommit(id ObjectID) (*Commit, error) {
- wr, rd, cancel := repo.CatFileBatch(repo.Ctx)
- defer cancel()
-
- _, _ = wr.Write([]byte(id.String() + "\n"))
-
- return repo.getCommitFromBatchReader(rd, id)
-}
-
-func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID) (*Commit, error) {
- _, typ, size, err := ReadBatchLine(rd)
- if err != nil {
- if errors.Is(err, io.EOF) || IsErrNotExist(err) {
- return nil, ErrNotExist{ID: id.String()}
- }
- return nil, err
- }
-
- switch typ {
- case "missing":
- return nil, ErrNotExist{ID: id.String()}
- case "tag":
- // then we need to parse the tag
- // and load the commit
- data, err := io.ReadAll(io.LimitReader(rd, size))
- if err != nil {
- return nil, err
- }
- _, err = rd.Discard(1)
- if err != nil {
- return nil, err
- }
- tag, err := parseTagData(id.Type(), data)
- if err != nil {
- return nil, err
- }
-
- commit, err := tag.Commit(repo)
- if err != nil {
- return nil, err
- }
-
- return commit, nil
- case "commit":
- commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
- if err != nil {
- return nil, err
- }
- _, err = rd.Discard(1)
- if err != nil {
- return nil, err
- }
-
- return commit, nil
- default:
- log.Debug("Unknown typ: %s", typ)
- if err := DiscardFull(rd, size+1); err != nil {
- return nil, err
- }
- return nil, ErrNotExist{
- ID: id.String(),
- }
- }
-}
-
-// ConvertToGitID returns a GitHash object from a potential ID string
-func (repo *Repository) ConvertToGitID(commitID string) (ObjectID, error) {
- objectFormat, err := repo.GetObjectFormat()
- if err != nil {
- return nil, err
- }
- if len(commitID) == objectFormat.FullLength() && objectFormat.IsValid(commitID) {
- ID, err := NewIDFromString(commitID)
- if err == nil {
- return ID, nil
- }
- }
-
- wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
- defer cancel()
- _, err = wr.Write([]byte(commitID + "\n"))
- if err != nil {
- return nil, err
- }
- sha, _, _, err := ReadBatchLine(rd)
- if err != nil {
- if IsErrNotExist(err) {
- return nil, ErrNotExist{commitID, ""}
- }
- return nil, err
- }
-
- return MustIDFromString(string(sha)), nil
-}
diff --git a/modules/git/repo_commit_test.go b/modules/git/repo_commit_test.go
index fee145e924..9cbc40eee7 100644
--- a/modules/git/repo_commit_test.go
+++ b/modules/git/repo_commit_test.go
@@ -7,13 +7,17 @@ import (
"path/filepath"
"testing"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
+
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepository_GetCommitBranches(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
// these test case are specific to the repo1_bare test repo
@@ -30,9 +34,9 @@ func TestRepository_GetCommitBranches(t *testing.T) {
}
for _, testCase := range testCases {
commit, err := bareRepo1.GetCommit(testCase.CommitID)
- assert.NoError(t, err)
+ require.NoError(t, err)
branches, err := bareRepo1.getBranches(commit, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testCase.ExpectedBranches, branches)
}
}
@@ -40,12 +44,12 @@ func TestRepository_GetCommitBranches(t *testing.T) {
func TestGetTagCommitWithSignature(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
// both the tag and the commit are signed here, this validates only the commit signature
commit, err := bareRepo1.GetCommit("28b55526e7100924d864dd89e35c1ea62e7a5a32")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, commit)
assert.NotNil(t, commit.Signature)
// test that signature is not in message
@@ -55,34 +59,34 @@ func TestGetTagCommitWithSignature(t *testing.T) {
func TestGetCommitWithBadCommitID(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
commit, err := bareRepo1.GetCommit("bad_branch")
assert.Nil(t, commit)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, IsErrNotExist(err))
}
func TestIsCommitInBranch(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
result, err := bareRepo1.IsCommitInBranch("2839944139e0de9737a044f78b0e4b40d989a9e3", "branch1")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, result)
result, err = bareRepo1.IsCommitInBranch("2839944139e0de9737a044f78b0e4b40d989a9e3", "branch2")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, result)
}
func TestRepository_CommitsBetweenIDs(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo4_commitsbetween")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
cases := []struct {
@@ -96,7 +100,102 @@ func TestRepository_CommitsBetweenIDs(t *testing.T) {
}
for i, c := range cases {
commits, err := bareRepo1.CommitsBetweenIDs(c.NewID, c.OldID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, commits, c.ExpectedCommits, "case %d", i)
}
}
+
+func TestGetTagCommit(t *testing.T) {
+ t.Setenv("GIT_COMMITTER_DATE", "2006-01-01 13:37")
+ bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
+
+ clonedPath, err := cloneRepo(t, bareRepo1Path)
+ require.NoError(t, err)
+
+ bareRepo1, err := openRepositoryWithDefaultContext(clonedPath)
+ require.NoError(t, err)
+ defer bareRepo1.Close()
+
+ lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1"
+ lTagName := "lightweightTag"
+ bareRepo1.CreateTag(lTagName, lTagCommitID)
+
+ aTagCommitID := "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"
+ aTagName := "annotatedTag"
+ aTagMessage := "my annotated message"
+ bareRepo1.CreateAnnotatedTag(aTagName, aTagMessage, aTagCommitID)
+
+ aTagID, err := bareRepo1.GetTagCommitID(aTagName)
+ require.NoError(t, err)
+ assert.NotEqualValues(t, aTagCommitID, aTagID)
+
+ lTagID, err := bareRepo1.GetTagCommitID(lTagName)
+ require.NoError(t, err)
+ assert.EqualValues(t, lTagCommitID, lTagID)
+
+ aTag, err := bareRepo1.GetTagCommit(aTagName)
+ require.NoError(t, err)
+ assert.EqualValues(t, aTagCommitID, aTag.ID.String())
+
+ lTag, err := bareRepo1.GetTagCommit(lTagName)
+ require.NoError(t, err)
+ assert.EqualValues(t, lTagCommitID, lTag.ID.String())
+}
+
+func TestCommitsByRange(t *testing.T) {
+ bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
+ bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
+ require.NoError(t, err)
+ defer bareRepo1.Close()
+
+ baseCommit, err := bareRepo1.GetBranchCommit("master")
+ require.NoError(t, err)
+
+ testCases := []struct {
+ Page int
+ ExpectedCommitCount int
+ }{
+ {1, 3},
+ {2, 3},
+ {3, 1},
+ {4, 0},
+ }
+ for _, testCase := range testCases {
+ commits, err := baseCommit.CommitsByRange(testCase.Page, 3, "")
+ require.NoError(t, err)
+ assert.Len(t, commits, testCase.ExpectedCommitCount, "page: %d", testCase.Page)
+ }
+}
+
+func TestCommitsByFileAndRange(t *testing.T) {
+ bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
+ bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
+ require.NoError(t, err)
+ defer bareRepo1.Close()
+ defer test.MockVariableValue(&setting.Git.CommitsRangeSize, 2)()
+
+ testCases := []struct {
+ File string
+ Page int
+ ExpectedCommitCount int
+ }{
+ {"file1.txt", 1, 1},
+ {"file2.txt", 1, 1},
+ {"file*.txt", 1, 2},
+ {"foo", 1, 2},
+ {"foo", 2, 1},
+ {"foo", 3, 0},
+ {"f*", 1, 2},
+ {"f*", 2, 2},
+ {"f*", 3, 1},
+ }
+ for _, testCase := range testCases {
+ commits, err := bareRepo1.CommitsByFileAndRange(CommitsByFileAndRangeOptions{
+ Revision: "master",
+ File: testCase.File,
+ Page: testCase.Page,
+ })
+ require.NoError(t, err)
+ assert.Len(t, commits, testCase.ExpectedCommitCount, "file: '%s', page: %d", testCase.File, testCase.Page)
+ }
+}
diff --git a/modules/git/repo_commitgraph_gogit.go b/modules/git/repo_commitgraph_gogit.go
deleted file mode 100644
index d3182f15c6..0000000000
--- a/modules/git/repo_commitgraph_gogit.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2019 The Gitea Authors.
-// All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "os"
- "path"
-
- gitealog "code.gitea.io/gitea/modules/log"
-
- commitgraph "github.com/go-git/go-git/v5/plumbing/format/commitgraph/v2"
- cgobject "github.com/go-git/go-git/v5/plumbing/object/commitgraph"
-)
-
-// CommitNodeIndex returns the index for walking commit graph
-func (r *Repository) CommitNodeIndex() (cgobject.CommitNodeIndex, *os.File) {
- indexPath := path.Join(r.Path, "objects", "info", "commit-graph")
-
- file, err := os.Open(indexPath)
- if err == nil {
- var index commitgraph.Index
- index, err = commitgraph.OpenFileIndex(file)
- if err == nil {
- return cgobject.NewGraphCommitNodeIndex(index, r.gogitRepo.Storer), file
- }
- }
-
- if !os.IsNotExist(err) {
- gitealog.Warn("Unable to read commit-graph for %s: %v", r.Path, err)
- }
-
- return cgobject.NewObjectCommitNodeIndex(r.gogitRepo.Storer), nil
-}
diff --git a/modules/git/repo_compare.go b/modules/git/repo_compare.go
index b6e9d2b44a..373b5befb5 100644
--- a/modules/git/repo_compare.go
+++ b/modules/git/repo_compare.go
@@ -18,7 +18,7 @@ import (
"strings"
"time"
- logger "code.gitea.io/gitea/modules/log"
+ logger "forgejo.org/modules/log"
)
// CompareInfo represents needed information for comparing references.
diff --git a/modules/git/repo_compare_test.go b/modules/git/repo_compare_test.go
index 9983873186..86bd6855a7 100644
--- a/modules/git/repo_compare_test.go
+++ b/modules/git/repo_compare_test.go
@@ -10,19 +10,20 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetFormatPatch(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
clonedPath, err := cloneRepo(t, bareRepo1Path)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
repo, err := openRepositoryWithDefaultContext(clonedPath)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
defer repo.Close()
@@ -30,13 +31,13 @@ func TestGetFormatPatch(t *testing.T) {
rd := &bytes.Buffer{}
err = repo.GetPatch("8d92fc95^", "8d92fc95", rd)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
patchb, err := io.ReadAll(rd)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
@@ -50,29 +51,29 @@ func TestReadPatch(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
defer repo.Close()
// This patch doesn't exist
noFile, err := repo.ReadPatchCommit(0)
- assert.Error(t, err)
+ require.Error(t, err)
// This patch is an empty one (sometimes it's a 404)
noCommit, err := repo.ReadPatchCommit(1)
- assert.Error(t, err)
+ require.Error(t, err)
// This patch is legit and should return a commit
oldCommit, err := repo.ReadPatchCommit(2)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
assert.Empty(t, noFile)
assert.Empty(t, noCommit)
assert.Len(t, oldCommit, 40)
- assert.True(t, oldCommit == "6e8e2a6f9efd71dbe6917816343ed8415ad696c3")
+ assert.Equal(t, "6e8e2a6f9efd71dbe6917816343ed8415ad696c3", oldCommit)
}
func TestReadWritePullHead(t *testing.T) {
@@ -82,52 +83,52 @@ func TestReadWritePullHead(t *testing.T) {
// As we are writing we should clone the repository first
clonedPath, err := cloneRepo(t, bareRepo1Path)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
repo, err := openRepositoryWithDefaultContext(clonedPath)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
defer repo.Close()
// Try to open non-existing Pull
_, err = repo.GetRefCommitID(PullPrefix + "0/head")
- assert.Error(t, err)
+ require.Error(t, err)
// Write a fake sha1 with only 40 zeros
newCommit := "feaf4ba6bc635fec442f46ddd4512416ec43c2c2"
err = repo.SetReference(PullPrefix+"1/head", newCommit)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
// Read the file created
headContents, err := repo.GetRefCommitID(PullPrefix + "1/head")
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
assert.Len(t, headContents, 40)
- assert.True(t, headContents == newCommit)
+ assert.Equal(t, newCommit, headContents)
// Remove file after the test
err = repo.RemoveReference(PullPrefix + "1/head")
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func TestGetCommitFilesChanged(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
repo, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
objectFormat, err := repo.GetObjectFormat()
- assert.NoError(t, err)
+ require.NoError(t, err)
testCases := []struct {
base, head string
@@ -157,7 +158,7 @@ func TestGetCommitFilesChanged(t *testing.T) {
for _, tc := range testCases {
changedFiles, err := repo.GetFilesChangedBetween(tc.base, tc.head)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.ElementsMatch(t, tc.files, changedFiles)
}
}
diff --git a/modules/git/repo_gpg.go b/modules/git/repo_gpg.go
index e2b45064fd..2c94234017 100644
--- a/modules/git/repo_gpg.go
+++ b/modules/git/repo_gpg.go
@@ -8,7 +8,7 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/modules/process"
+ "forgejo.org/modules/process"
)
// LoadPublicKeyContent will load the key from gpg
diff --git a/modules/git/repo_index.go b/modules/git/repo_index.go
index 6aaab242c1..f58757a9a2 100644
--- a/modules/git/repo_index.go
+++ b/modules/git/repo_index.go
@@ -10,8 +10,8 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
// ReadTreeToIndex reads a treeish to the index
@@ -50,25 +50,35 @@ func (repo *Repository) readTreeToIndex(id ObjectID, indexFilename ...string) er
}
// ReadTreeToTemporaryIndex reads a treeish to a temporary index file
-func (repo *Repository) ReadTreeToTemporaryIndex(treeish string) (filename, tmpDir string, cancel context.CancelFunc, err error) {
- tmpDir, err = os.MkdirTemp("", "index")
- if err != nil {
- return filename, tmpDir, cancel, err
- }
+func (repo *Repository) ReadTreeToTemporaryIndex(treeish string) (tmpIndexFilename, tmpDir string, cancel context.CancelFunc, err error) {
+ defer func() {
+ // if error happens and there is a cancel function, do clean up
+ if err != nil && cancel != nil {
+ cancel()
+ cancel = nil
+ }
+ }()
- filename = filepath.Join(tmpDir, ".tmp-index")
- cancel = func() {
- err := util.RemoveAll(tmpDir)
- if err != nil {
- log.Error("failed to remove tmp index file: %v", err)
+ removeDirFn := func(dir string) func() { // it can't use the return value "tmpDir" directly because it is empty when error occurs
+ return func() {
+ if err := util.RemoveAll(dir); err != nil {
+ log.Error("failed to remove tmp index dir: %v", err)
+ }
}
}
- err = repo.ReadTreeToIndex(treeish, filename)
+
+ tmpDir, err = os.MkdirTemp("", "index")
if err != nil {
- defer cancel()
- return "", "", func() {}, err
+ return "", "", nil, err
}
- return filename, tmpDir, cancel, err
+
+ tmpIndexFilename = filepath.Join(tmpDir, ".tmp-index")
+ cancel = removeDirFn(tmpDir)
+ err = repo.ReadTreeToIndex(treeish, tmpIndexFilename)
+ if err != nil {
+ return "", "", cancel, err
+ }
+ return tmpIndexFilename, tmpDir, cancel, err
}
// EmptyIndex empties the index
@@ -104,11 +114,8 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error {
buffer := new(bytes.Buffer)
for _, file := range filenames {
if file != "" {
- buffer.WriteString("0 ")
- buffer.WriteString(objectFormat.EmptyObjectID().String())
- buffer.WriteByte('\t')
- buffer.WriteString(file)
- buffer.WriteByte('\000')
+ // using format: mode SP type SP sha1 TAB path
+ buffer.WriteString("0 blob " + objectFormat.EmptyObjectID().String() + "\t" + file + "\000")
}
}
return cmd.Run(&RunOpts{
@@ -119,11 +126,33 @@ func (repo *Repository) RemoveFilesFromIndex(filenames ...string) error {
})
}
+type IndexObjectInfo struct {
+ Mode string
+ Object ObjectID
+ Filename string
+}
+
+// AddObjectsToIndex adds the provided object hashes to the index at the provided filenames
+func (repo *Repository) AddObjectsToIndex(objects ...IndexObjectInfo) error {
+ cmd := NewCommand(repo.Ctx, "update-index", "--add", "--replace", "-z", "--index-info")
+ stdout := new(bytes.Buffer)
+ stderr := new(bytes.Buffer)
+ buffer := new(bytes.Buffer)
+ for _, object := range objects {
+ // using format: mode SP type SP sha1 TAB path
+ buffer.WriteString(object.Mode + " blob " + object.Object.String() + "\t" + object.Filename + "\000")
+ }
+ return cmd.Run(&RunOpts{
+ Dir: repo.Path,
+ Stdin: bytes.NewReader(buffer.Bytes()),
+ Stdout: stdout,
+ Stderr: stderr,
+ })
+}
+
// AddObjectToIndex adds the provided object hash to the index at the provided filename
func (repo *Repository) AddObjectToIndex(mode string, object ObjectID, filename string) error {
- cmd := NewCommand(repo.Ctx, "update-index", "--add", "--replace", "--cacheinfo").AddDynamicArguments(mode, object.String(), filename)
- _, _, err := cmd.RunStdString(&RunOpts{Dir: repo.Path})
- return err
+ return repo.AddObjectsToIndex(IndexObjectInfo{Mode: mode, Object: object, Filename: filename})
}
// WriteTree writes the current index as a tree to the object db and returns its hash
diff --git a/modules/git/repo_language_stats.go b/modules/git/repo_language_stats.go
index c40d6937b5..7b76c7bcc7 100644
--- a/modules/git/repo_language_stats.go
+++ b/modules/git/repo_language_stats.go
@@ -4,8 +4,17 @@
package git
import (
+ "bytes"
+ "cmp"
+ "io"
"strings"
"unicode"
+
+ "forgejo.org/modules/analyze"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+
+ "github.com/go-enry/go-enry/v2"
)
const (
@@ -46,3 +55,203 @@ func mergeLanguageStats(stats map[string]int64) map[string]int64 {
}
return res
}
+
+// GetLanguageStats calculates language stats for git repository at specified commit
+func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, error) {
+ // We will feed the commit IDs in order into cat-file --batch, followed by blobs as necessary.
+ // so let's create a batch stdin and stdout
+ batchStdinWriter, batchReader, cancel, err := repo.CatFileBatch(repo.Ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer cancel()
+
+ writeID := func(id string) error {
+ _, err := batchStdinWriter.Write([]byte(id + "\n"))
+ return err
+ }
+
+ if err := writeID(commitID); err != nil {
+ return nil, err
+ }
+ shaBytes, typ, size, err := ReadBatchLine(batchReader)
+ if typ != "commit" {
+ log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
+ return nil, ErrNotExist{commitID, ""}
+ }
+
+ sha, err := NewIDFromString(string(shaBytes))
+ if err != nil {
+ log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
+ return nil, ErrNotExist{commitID, ""}
+ }
+
+ commit, err := CommitFromReader(repo, sha, io.LimitReader(batchReader, size))
+ if err != nil {
+ log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
+ return nil, err
+ }
+ if _, err = batchReader.Discard(1); err != nil {
+ return nil, err
+ }
+
+ tree := commit.Tree
+
+ entries, err := tree.ListEntriesRecursiveWithSize()
+ if err != nil {
+ return nil, err
+ }
+
+ checker, err := repo.GitAttributeChecker(commitID, LinguistAttributes...)
+ if err != nil {
+ return nil, err
+ }
+ defer checker.Close()
+
+ contentBuf := bytes.Buffer{}
+ var content []byte
+
+ // sizes contains the current calculated size of all files by language
+ sizes := make(map[string]int64)
+ // by default we will only count the sizes of programming languages or markup languages
+ // unless they are explicitly set using linguist-language
+ includedLanguage := map[string]bool{}
+ // or if there's only one language in the repository
+ firstExcludedLanguage := ""
+ firstExcludedLanguageSize := int64(0)
+
+ isTrue := func(v optional.Option[bool]) bool {
+ return v.ValueOrDefault(false)
+ }
+ isFalse := func(v optional.Option[bool]) bool {
+ return !v.ValueOrDefault(true)
+ }
+
+ for _, f := range entries {
+ select {
+ case <-repo.Ctx.Done():
+ return sizes, repo.Ctx.Err()
+ default:
+ }
+
+ contentBuf.Reset()
+ content = contentBuf.Bytes()
+
+ if f.Size() == 0 {
+ continue
+ }
+
+ isVendored := optional.None[bool]()
+ isGenerated := optional.None[bool]()
+ isDocumentation := optional.None[bool]()
+ isDetectable := optional.None[bool]()
+
+ attrs, err := checker.CheckPath(f.Name())
+ if err == nil {
+ isVendored = attrs["linguist-vendored"].Bool()
+ isGenerated = attrs["linguist-generated"].Bool()
+ isDocumentation = attrs["linguist-documentation"].Bool()
+ isDetectable = attrs["linguist-detectable"].Bool()
+ if language := cmp.Or(
+ attrs["linguist-language"].String(),
+ attrs["gitlab-language"].Prefix(),
+ ); language != "" {
+ // group languages, such as Pug -> HTML; SCSS -> CSS
+ group := enry.GetLanguageGroup(language)
+ if len(group) != 0 {
+ language = group
+ }
+
+ // this language will always be added to the size
+ sizes[language] += f.Size()
+ continue
+ }
+ }
+
+ if isFalse(isDetectable) || isTrue(isVendored) || isTrue(isDocumentation) ||
+ (!isFalse(isVendored) && analyze.IsVendor(f.Name())) ||
+ enry.IsDotFile(f.Name()) ||
+ enry.IsConfiguration(f.Name()) ||
+ (!isFalse(isDocumentation) && enry.IsDocumentation(f.Name())) {
+ continue
+ }
+
+ // If content can not be read or file is too big just do detection by filename
+
+ if f.Size() <= bigFileSize {
+ if err := writeID(f.ID.String()); err != nil {
+ return nil, err
+ }
+ _, _, size, err := ReadBatchLine(batchReader)
+ if err != nil {
+ log.Debug("Error reading blob: %s Err: %v", f.ID.String(), err)
+ return nil, err
+ }
+
+ sizeToRead := size
+ discard := int64(1)
+ if size > fileSizeLimit {
+ sizeToRead = fileSizeLimit
+ discard = size - fileSizeLimit + 1
+ }
+
+ _, err = contentBuf.ReadFrom(io.LimitReader(batchReader, sizeToRead))
+ if err != nil {
+ return nil, err
+ }
+ content = contentBuf.Bytes()
+ if err := DiscardFull(batchReader, discard); err != nil {
+ return nil, err
+ }
+ }
+
+ // We consider three cases:
+ // 1. linguist-generated=true, then we ignore the file.
+ // 2. linguist-generated=false, we don't ignore the file.
+ // 3. linguist-generated is not set, then `enry.IsGenerated` determines if the file is generated.
+ if isTrue(isGenerated) || !isFalse(isGenerated) && enry.IsGenerated(f.Name(), content) {
+ log.Trace("Ignore %q for language stats, because it is generated", f.Name())
+ continue
+ }
+
+ // FIXME: Why can't we split this and the IsGenerated tests to avoid reading the blob unless absolutely necessary?
+ // - eg. do the all the detection tests using filename first before reading content.
+ language := analyze.GetCodeLanguage(f.Name(), content)
+ if language == "" {
+ continue
+ }
+
+ // group languages, such as Pug -> HTML; SCSS -> CSS
+ group := enry.GetLanguageGroup(language)
+ if group != "" {
+ language = group
+ }
+
+ included, checked := includedLanguage[language]
+ langType := enry.GetLanguageType(language)
+ if !checked {
+ included = langType == enry.Programming || langType == enry.Markup
+ if !included && (isTrue(isDetectable) || (langType == enry.Prose && isFalse(isDocumentation))) {
+ included = true
+ }
+ includedLanguage[language] = included
+ }
+ if included {
+ sizes[language] += f.Size()
+ } else if len(sizes) == 0 && (firstExcludedLanguage == "" || firstExcludedLanguage == language) {
+ // Only consider Programming or Markup languages as fallback
+ if !(langType == enry.Programming || langType == enry.Markup) {
+ continue
+ }
+ firstExcludedLanguage = language
+ firstExcludedLanguageSize += f.Size()
+ }
+ }
+
+ // If there are no included languages add the first excluded language
+ if len(sizes) == 0 && firstExcludedLanguage != "" {
+ sizes[firstExcludedLanguage] = firstExcludedLanguageSize
+ }
+
+ return mergeLanguageStats(sizes), nil
+}
diff --git a/modules/git/repo_language_stats_gogit.go b/modules/git/repo_language_stats_gogit.go
deleted file mode 100644
index 1276ce1a44..0000000000
--- a/modules/git/repo_language_stats_gogit.go
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "bytes"
- "io"
- "strings"
-
- "code.gitea.io/gitea/modules/analyze"
- "code.gitea.io/gitea/modules/optional"
-
- "github.com/go-enry/go-enry/v2"
- "github.com/go-git/go-git/v5"
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// GetLanguageStats calculates language stats for git repository at specified commit
-func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, error) {
- r, err := git.PlainOpen(repo.Path)
- if err != nil {
- return nil, err
- }
-
- rev, err := r.ResolveRevision(plumbing.Revision(commitID))
- if err != nil {
- return nil, err
- }
-
- commit, err := r.CommitObject(*rev)
- if err != nil {
- return nil, err
- }
-
- tree, err := commit.Tree()
- if err != nil {
- return nil, err
- }
-
- checker, deferable := repo.CheckAttributeReader(commitID)
- defer deferable()
-
- // sizes contains the current calculated size of all files by language
- sizes := make(map[string]int64)
- // by default we will only count the sizes of programming languages or markup languages
- // unless they are explicitly set using linguist-language
- includedLanguage := map[string]bool{}
- // or if there's only one language in the repository
- firstExcludedLanguage := ""
- firstExcludedLanguageSize := int64(0)
-
- isTrue := func(v optional.Option[bool]) bool {
- return v.ValueOrDefault(false)
- }
- isFalse := func(v optional.Option[bool]) bool {
- return !v.ValueOrDefault(true)
- }
-
- err = tree.Files().ForEach(func(f *object.File) error {
- if f.Size == 0 {
- return nil
- }
-
- isVendored := optional.None[bool]()
- isGenerated := optional.None[bool]()
- isDocumentation := optional.None[bool]()
- isDetectable := optional.None[bool]()
-
- if checker != nil {
- attrs, err := checker.CheckPath(f.Name)
- if err == nil {
- isVendored = attributeToBool(attrs, "linguist-vendored")
- isGenerated = attributeToBool(attrs, "linguist-generated")
- isDocumentation = attributeToBool(attrs, "linguist-documentation")
- isDetectable = attributeToBool(attrs, "linguist-detectable")
- if language, has := attrs["linguist-language"]; has && language != "unspecified" && language != "" {
- // group languages, such as Pug -> HTML; SCSS -> CSS
- group := enry.GetLanguageGroup(language)
- if len(group) != 0 {
- language = group
- }
-
- // this language will always be added to the size
- sizes[language] += f.Size
- return nil
- } else if language, has := attrs["gitlab-language"]; has && language != "unspecified" && language != "" {
- // strip off a ? if present
- if idx := strings.IndexByte(language, '?'); idx >= 0 {
- language = language[:idx]
- }
- if len(language) != 0 {
- // group languages, such as Pug -> HTML; SCSS -> CSS
- group := enry.GetLanguageGroup(language)
- if len(group) != 0 {
- language = group
- }
-
- // this language will always be added to the size
- sizes[language] += f.Size
- return nil
- }
- }
- }
- }
-
- if isFalse(isDetectable) || isTrue(isVendored) || isTrue(isDocumentation) ||
- (!isFalse(isVendored) && analyze.IsVendor(f.Name)) ||
- enry.IsDotFile(f.Name) ||
- enry.IsConfiguration(f.Name) ||
- (!isFalse(isDocumentation) && enry.IsDocumentation(f.Name)) {
- return nil
- }
-
- // If content can not be read or file is too big just do detection by filename
- var content []byte
- if f.Size <= bigFileSize {
- content, _ = readFile(f, fileSizeLimit)
- }
- if !isTrue(isGenerated) && enry.IsGenerated(f.Name, content) {
- return nil
- }
-
- // TODO: Use .gitattributes file for linguist overrides
- language := analyze.GetCodeLanguage(f.Name, content)
- if language == enry.OtherLanguage || language == "" {
- return nil
- }
-
- // group languages, such as Pug -> HTML; SCSS -> CSS
- group := enry.GetLanguageGroup(language)
- if group != "" {
- language = group
- }
-
- included, checked := includedLanguage[language]
- langType := enry.GetLanguageType(language)
- if !checked {
- included = langType == enry.Programming || langType == enry.Markup
- if !included && (isTrue(isDetectable) || (langType == enry.Prose && isFalse(isDocumentation))) {
- included = true
- }
- includedLanguage[language] = included
- }
- if included {
- sizes[language] += f.Size
- } else if len(sizes) == 0 && (firstExcludedLanguage == "" || firstExcludedLanguage == language) {
- // Only consider Programming or Markup languages as fallback
- if !(langType == enry.Programming || langType == enry.Markup) {
- return nil
- }
-
- firstExcludedLanguage = language
- firstExcludedLanguageSize += f.Size
- }
-
- return nil
- })
- if err != nil {
- return nil, err
- }
-
- // If there are no included languages add the first excluded language
- if len(sizes) == 0 && firstExcludedLanguage != "" {
- sizes[firstExcludedLanguage] = firstExcludedLanguageSize
- }
-
- return mergeLanguageStats(sizes), nil
-}
-
-func readFile(f *object.File, limit int64) ([]byte, error) {
- r, err := f.Reader()
- if err != nil {
- return nil, err
- }
- defer r.Close()
-
- if limit <= 0 {
- return io.ReadAll(r)
- }
-
- size := f.Size
- if limit > 0 && size > limit {
- size = limit
- }
- buf := bytes.NewBuffer(nil)
- buf.Grow(int(size))
- _, err = io.Copy(buf, io.LimitReader(r, limit))
- return buf.Bytes(), err
-}
diff --git a/modules/git/repo_language_stats_nogogit.go b/modules/git/repo_language_stats_nogogit.go
deleted file mode 100644
index 672f7571d9..0000000000
--- a/modules/git/repo_language_stats_nogogit.go
+++ /dev/null
@@ -1,210 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// Copyright 2024 The Forgejo Authors c/o Codeberg e.V.. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "bytes"
- "cmp"
- "io"
-
- "code.gitea.io/gitea/modules/analyze"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
-
- "github.com/go-enry/go-enry/v2"
-)
-
-// GetLanguageStats calculates language stats for git repository at specified commit
-func (repo *Repository) GetLanguageStats(commitID string) (map[string]int64, error) {
- // We will feed the commit IDs in order into cat-file --batch, followed by blobs as necessary.
- // so let's create a batch stdin and stdout
- batchStdinWriter, batchReader, cancel := repo.CatFileBatch(repo.Ctx)
- defer cancel()
-
- writeID := func(id string) error {
- _, err := batchStdinWriter.Write([]byte(id + "\n"))
- return err
- }
-
- if err := writeID(commitID); err != nil {
- return nil, err
- }
- shaBytes, typ, size, err := ReadBatchLine(batchReader)
- if typ != "commit" {
- log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
- return nil, ErrNotExist{commitID, ""}
- }
-
- sha, err := NewIDFromString(string(shaBytes))
- if err != nil {
- log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
- return nil, ErrNotExist{commitID, ""}
- }
-
- commit, err := CommitFromReader(repo, sha, io.LimitReader(batchReader, size))
- if err != nil {
- log.Debug("Unable to get commit for: %s. Err: %v", commitID, err)
- return nil, err
- }
- if _, err = batchReader.Discard(1); err != nil {
- return nil, err
- }
-
- tree := commit.Tree
-
- entries, err := tree.ListEntriesRecursiveWithSize()
- if err != nil {
- return nil, err
- }
-
- checker, err := repo.GitAttributeChecker(commitID, LinguistAttributes...)
- if err != nil {
- return nil, err
- }
- defer checker.Close()
-
- contentBuf := bytes.Buffer{}
- var content []byte
-
- // sizes contains the current calculated size of all files by language
- sizes := make(map[string]int64)
- // by default we will only count the sizes of programming languages or markup languages
- // unless they are explicitly set using linguist-language
- includedLanguage := map[string]bool{}
- // or if there's only one language in the repository
- firstExcludedLanguage := ""
- firstExcludedLanguageSize := int64(0)
-
- isTrue := func(v optional.Option[bool]) bool {
- return v.ValueOrDefault(false)
- }
- isFalse := func(v optional.Option[bool]) bool {
- return !v.ValueOrDefault(true)
- }
-
- for _, f := range entries {
- select {
- case <-repo.Ctx.Done():
- return sizes, repo.Ctx.Err()
- default:
- }
-
- contentBuf.Reset()
- content = contentBuf.Bytes()
-
- if f.Size() == 0 {
- continue
- }
-
- isVendored := optional.None[bool]()
- isGenerated := optional.None[bool]()
- isDocumentation := optional.None[bool]()
- isDetectable := optional.None[bool]()
-
- attrs, err := checker.CheckPath(f.Name())
- if err == nil {
- isVendored = attrs["linguist-vendored"].Bool()
- isGenerated = attrs["linguist-generated"].Bool()
- isDocumentation = attrs["linguist-documentation"].Bool()
- isDetectable = attrs["linguist-detectable"].Bool()
- if language := cmp.Or(
- attrs["linguist-language"].String(),
- attrs["gitlab-language"].Prefix(),
- ); language != "" {
- // group languages, such as Pug -> HTML; SCSS -> CSS
- group := enry.GetLanguageGroup(language)
- if len(group) != 0 {
- language = group
- }
-
- // this language will always be added to the size
- sizes[language] += f.Size()
- continue
- }
- }
-
- if isFalse(isDetectable) || isTrue(isVendored) || isTrue(isDocumentation) ||
- (!isFalse(isVendored) && analyze.IsVendor(f.Name())) ||
- enry.IsDotFile(f.Name()) ||
- enry.IsConfiguration(f.Name()) ||
- (!isFalse(isDocumentation) && enry.IsDocumentation(f.Name())) {
- continue
- }
-
- // If content can not be read or file is too big just do detection by filename
-
- if f.Size() <= bigFileSize {
- if err := writeID(f.ID.String()); err != nil {
- return nil, err
- }
- _, _, size, err := ReadBatchLine(batchReader)
- if err != nil {
- log.Debug("Error reading blob: %s Err: %v", f.ID.String(), err)
- return nil, err
- }
-
- sizeToRead := size
- discard := int64(1)
- if size > fileSizeLimit {
- sizeToRead = fileSizeLimit
- discard = size - fileSizeLimit + 1
- }
-
- _, err = contentBuf.ReadFrom(io.LimitReader(batchReader, sizeToRead))
- if err != nil {
- return nil, err
- }
- content = contentBuf.Bytes()
- if err := DiscardFull(batchReader, discard); err != nil {
- return nil, err
- }
- }
- if !isTrue(isGenerated) && enry.IsGenerated(f.Name(), content) {
- continue
- }
-
- // FIXME: Why can't we split this and the IsGenerated tests to avoid reading the blob unless absolutely necessary?
- // - eg. do the all the detection tests using filename first before reading content.
- language := analyze.GetCodeLanguage(f.Name(), content)
- if language == "" {
- continue
- }
-
- // group languages, such as Pug -> HTML; SCSS -> CSS
- group := enry.GetLanguageGroup(language)
- if group != "" {
- language = group
- }
-
- included, checked := includedLanguage[language]
- langType := enry.GetLanguageType(language)
- if !checked {
- included = langType == enry.Programming || langType == enry.Markup
- if !included && (isTrue(isDetectable) || (langType == enry.Prose && isFalse(isDocumentation))) {
- included = true
- }
- includedLanguage[language] = included
- }
- if included {
- sizes[language] += f.Size()
- } else if len(sizes) == 0 && (firstExcludedLanguage == "" || firstExcludedLanguage == language) {
- // Only consider Programming or Markup languages as fallback
- if !(langType == enry.Programming || langType == enry.Markup) {
- continue
- }
- firstExcludedLanguage = language
- firstExcludedLanguageSize += f.Size()
- }
- }
-
- // If there are no included languages add the first excluded language
- if len(sizes) == 0 && firstExcludedLanguage != "" {
- sizes[firstExcludedLanguage] = firstExcludedLanguageSize
- }
-
- return mergeLanguageStats(sizes), nil
-}
diff --git a/modules/git/repo_language_stats_test.go b/modules/git/repo_language_stats_test.go
index da3871e909..ccd7301f81 100644
--- a/modules/git/repo_language_stats_test.go
+++ b/modules/git/repo_language_stats_test.go
@@ -1,8 +1,6 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !gogit
-
package git
import (
@@ -10,25 +8,32 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepository_GetLanguageStats(t *testing.T) {
repoPath := filepath.Join(testReposDir, "language_stats_repo")
gitRepo, err := openRepositoryWithDefaultContext(repoPath)
- if !assert.NoError(t, err) {
- t.Fatal()
- }
+ require.NoError(t, err)
+
defer gitRepo.Close()
stats, err := gitRepo.GetLanguageStats("8fee858da5796dfb37704761701bb8e800ad9ef3")
- if !assert.NoError(t, err) {
- t.Fatal()
- }
+ require.NoError(t, err)
assert.EqualValues(t, map[string]int64{
"Python": 134,
"Java": 112,
}, stats)
+
+ stats, err = gitRepo.GetLanguageStats("95d3505f2db273e40be79f84416051ae85e9ea0d")
+ require.NoError(t, err)
+
+ assert.Equal(t, map[string]int64{
+ "Cobra": 67,
+ "Python": 67,
+ "Java": 112,
+ }, stats)
}
func TestMergeLanguageStats(t *testing.T) {
diff --git a/modules/git/repo_ref.go b/modules/git/repo_ref.go
index b0c602c6a5..3c8b863f75 100644
--- a/modules/git/repo_ref.go
+++ b/modules/git/repo_ref.go
@@ -4,11 +4,13 @@
package git
import (
+ "bufio"
"context"
"fmt"
+ "io"
"strings"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
// GetRefs returns all references of the repository.
@@ -78,3 +80,78 @@ func (repo *Repository) ExpandRef(ref string) (string, error) {
}
return "", fmt.Errorf("could not expand reference '%s'", ref)
}
+
+// GetRefsFiltered returns all references of the repository that matches patterm exactly or starting with.
+func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) {
+ stdoutReader, stdoutWriter := io.Pipe()
+ defer func() {
+ _ = stdoutReader.Close()
+ _ = stdoutWriter.Close()
+ }()
+
+ go func() {
+ stderrBuilder := &strings.Builder{}
+ err := NewCommand(repo.Ctx, "for-each-ref").Run(&RunOpts{
+ Dir: repo.Path,
+ Stdout: stdoutWriter,
+ Stderr: stderrBuilder,
+ })
+ if err != nil {
+ _ = stdoutWriter.CloseWithError(ConcatenateError(err, stderrBuilder.String()))
+ } else {
+ _ = stdoutWriter.Close()
+ }
+ }()
+
+ refs := make([]*Reference, 0)
+ bufReader := bufio.NewReader(stdoutReader)
+ for {
+ // The output of for-each-ref is simply a list:
+ // ] SP TAB [ LF
+ sha, err := bufReader.ReadString(' ')
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+ sha = sha[:len(sha)-1]
+
+ typ, err := bufReader.ReadString('\t')
+ if err == io.EOF {
+ // This should not happen, but we'll tolerate it
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+ typ = typ[:len(typ)-1]
+
+ refName, err := bufReader.ReadString('\n')
+ if err == io.EOF {
+ // This should not happen, but we'll tolerate it
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+ refName = refName[:len(refName)-1]
+
+ // refName cannot be HEAD but can be remotes or stash
+ if strings.HasPrefix(refName, RemotePrefix) || refName == "/refs/stash" {
+ continue
+ }
+
+ if pattern == "" || strings.HasPrefix(refName, pattern) {
+ r := &Reference{
+ Name: refName,
+ Object: MustIDFromString(sha),
+ Type: typ,
+ repo: repo,
+ }
+ refs = append(refs, r)
+ }
+ }
+
+ return refs, nil
+}
diff --git a/modules/git/repo_ref_gogit.go b/modules/git/repo_ref_gogit.go
deleted file mode 100644
index fc43ce5545..0000000000
--- a/modules/git/repo_ref_gogit.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2018 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "strings"
-
- "github.com/go-git/go-git/v5"
- "github.com/go-git/go-git/v5/plumbing"
-)
-
-// GetRefsFiltered returns all references of the repository that matches patterm exactly or starting with.
-func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) {
- r, err := git.PlainOpen(repo.Path)
- if err != nil {
- return nil, err
- }
-
- refsIter, err := r.References()
- if err != nil {
- return nil, err
- }
- refs := make([]*Reference, 0)
- if err = refsIter.ForEach(func(ref *plumbing.Reference) error {
- if ref.Name() != plumbing.HEAD && !ref.Name().IsRemote() &&
- (pattern == "" || strings.HasPrefix(ref.Name().String(), pattern)) {
- refType := string(ObjectCommit)
- if ref.Name().IsTag() {
- // tags can be of type `commit` (lightweight) or `tag` (annotated)
- if tagType, _ := repo.GetTagType(ParseGogitHash(ref.Hash())); err == nil {
- refType = tagType
- }
- }
- r := &Reference{
- Name: ref.Name().String(),
- Object: ParseGogitHash(ref.Hash()),
- Type: refType,
- repo: repo,
- }
- refs = append(refs, r)
- }
- return nil
- }); err != nil {
- return nil, err
- }
-
- return refs, nil
-}
diff --git a/modules/git/repo_ref_nogogit.go b/modules/git/repo_ref_nogogit.go
deleted file mode 100644
index ac53d661b5..0000000000
--- a/modules/git/repo_ref_nogogit.go
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "bufio"
- "io"
- "strings"
-)
-
-// GetRefsFiltered returns all references of the repository that matches patterm exactly or starting with.
-func (repo *Repository) GetRefsFiltered(pattern string) ([]*Reference, error) {
- stdoutReader, stdoutWriter := io.Pipe()
- defer func() {
- _ = stdoutReader.Close()
- _ = stdoutWriter.Close()
- }()
-
- go func() {
- stderrBuilder := &strings.Builder{}
- err := NewCommand(repo.Ctx, "for-each-ref").Run(&RunOpts{
- Dir: repo.Path,
- Stdout: stdoutWriter,
- Stderr: stderrBuilder,
- })
- if err != nil {
- _ = stdoutWriter.CloseWithError(ConcatenateError(err, stderrBuilder.String()))
- } else {
- _ = stdoutWriter.Close()
- }
- }()
-
- refs := make([]*Reference, 0)
- bufReader := bufio.NewReader(stdoutReader)
- for {
- // The output of for-each-ref is simply a list:
- // ] SP TAB [ LF
- sha, err := bufReader.ReadString(' ')
- if err == io.EOF {
- break
- }
- if err != nil {
- return nil, err
- }
- sha = sha[:len(sha)-1]
-
- typ, err := bufReader.ReadString('\t')
- if err == io.EOF {
- // This should not happen, but we'll tolerate it
- break
- }
- if err != nil {
- return nil, err
- }
- typ = typ[:len(typ)-1]
-
- refName, err := bufReader.ReadString('\n')
- if err == io.EOF {
- // This should not happen, but we'll tolerate it
- break
- }
- if err != nil {
- return nil, err
- }
- refName = refName[:len(refName)-1]
-
- // refName cannot be HEAD but can be remotes or stash
- if strings.HasPrefix(refName, RemotePrefix) || refName == "/refs/stash" {
- continue
- }
-
- if pattern == "" || strings.HasPrefix(refName, pattern) {
- r := &Reference{
- Name: refName,
- Object: MustIDFromString(sha),
- Type: typ,
- repo: repo,
- }
- refs = append(refs, r)
- }
- }
-
- return refs, nil
-}
diff --git a/modules/git/repo_ref_test.go b/modules/git/repo_ref_test.go
index c08ea12760..609bef585d 100644
--- a/modules/git/repo_ref_test.go
+++ b/modules/git/repo_ref_test.go
@@ -8,17 +8,18 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepository_GetRefs(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
refs, err := bareRepo1.GetRefs()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, refs, 6)
expectedRefs := []string{
@@ -38,12 +39,12 @@ func TestRepository_GetRefs(t *testing.T) {
func TestRepository_GetRefsFiltered(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
refs, err := bareRepo1.GetRefsFiltered(TagPrefix)
- assert.NoError(t, err)
+ require.NoError(t, err)
if assert.Len(t, refs, 2) {
assert.Equal(t, TagPrefix+"signed-tag", refs[0].Name)
assert.Equal(t, "tag", refs[0].Type)
diff --git a/modules/git/repo_stats.go b/modules/git/repo_stats.go
index 83220104bd..ef0865e3d3 100644
--- a/modules/git/repo_stats.go
+++ b/modules/git/repo_stats.go
@@ -13,7 +13,7 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/container"
+ "forgejo.org/modules/container"
)
// CodeActivityStats represents git statistics data
diff --git a/modules/git/repo_stats_test.go b/modules/git/repo_stats_test.go
index 3d032385ee..2a15b6f1b7 100644
--- a/modules/git/repo_stats_test.go
+++ b/modules/git/repo_stats_test.go
@@ -9,19 +9,20 @@ import (
"time"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRepository_GetCodeActivityStats(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer bareRepo1.Close()
timeFrom, err := time.Parse(time.RFC3339, "2016-01-01T00:00:00+00:00")
- assert.NoError(t, err)
+ require.NoError(t, err)
code, err := bareRepo1.GetCodeActivityStats(timeFrom, "")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, code)
assert.EqualValues(t, 10, code.CommitCount)
diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go
index 638c508e4b..f7f04e1f10 100644
--- a/modules/git/repo_tag.go
+++ b/modules/git/repo_tag.go
@@ -5,23 +5,20 @@
package git
import (
- "context"
+ "errors"
"fmt"
"io"
+ "slices"
"strings"
- "code.gitea.io/gitea/modules/git/foreachref"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/git/foreachref"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
// TagPrefix tags prefix path on the repository
const TagPrefix = "refs/tags/"
-// IsTagExist returns true if given tag exists in the repository.
-func IsTagExist(ctx context.Context, repoPath, name string) bool {
- return IsReferenceExist(ctx, repoPath, TagPrefix+name)
-}
-
// CreateTag create one tag in the repository
func (repo *Repository) CreateTag(name, revision string) error {
_, _, err := NewCommand(repo.Ctx, "tag").AddDashesAndList(name, revision).RunStdString(&RunOpts{Dir: repo.Path})
@@ -151,7 +148,9 @@ func (repo *Repository) GetTagInfos(page, pageSize int) ([]*Tag, int, error) {
return nil, 0, fmt.Errorf("GetTagInfos: parse output: %w", err)
}
- sortTagsByTime(tags)
+ slices.SortFunc(tags, func(b, a *Tag) int {
+ return a.Tagger.When.Compare(b.Tagger.When)
+ })
tagsTotal := len(tags)
if page != 0 {
tags = util.PaginateSlice(tags, page, pageSize).([]*Tag)
@@ -236,3 +235,129 @@ func (repo *Repository) GetAnnotatedTag(sha string) (*Tag, error) {
}
return tag, nil
}
+
+// IsTagExist returns true if given tag exists in the repository.
+func (repo *Repository) IsTagExist(name string) bool {
+ if repo == nil || name == "" {
+ return false
+ }
+
+ return repo.IsReferenceExist(TagPrefix + name)
+}
+
+// GetTags returns all tags of the repository.
+// returning at most limit tags, or all if limit is 0.
+func (repo *Repository) GetTags(skip, limit int) (tags []string, err error) {
+ tags, _, err = callShowRef(repo.Ctx, repo.Path, TagPrefix, TrustedCmdArgs{TagPrefix, "--sort=-taggerdate"}, skip, limit)
+ return tags, err
+}
+
+// GetTagType gets the type of the tag, either commit (simple) or tag (annotated)
+func (repo *Repository) GetTagType(id ObjectID) (string, error) {
+ wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
+ if err != nil {
+ return "", err
+ }
+ defer cancel()
+ _, err = wr.Write([]byte(id.String() + "\n"))
+ if err != nil {
+ return "", err
+ }
+ _, typ, _, err := ReadBatchLine(rd)
+ if IsErrNotExist(err) {
+ return "", ErrNotExist{ID: id.String()}
+ }
+ return typ, nil
+}
+
+func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) {
+ t, ok := repo.tagCache.Get(tagID.String())
+ if ok {
+ log.Debug("Hit cache: %s", tagID)
+ tagClone := *t.(*Tag)
+ tagClone.Name = name // This is necessary because lightweight tags may have same id
+ return &tagClone, nil
+ }
+
+ tp, err := repo.GetTagType(tagID)
+ if err != nil {
+ return nil, err
+ }
+
+ // Get the commit ID and tag ID (may be different for annotated tag) for the returned tag object
+ commitIDStr, err := repo.GetTagCommitID(name)
+ if err != nil {
+ // every tag should have a commit ID so return all errors
+ return nil, err
+ }
+ commitID, err := NewIDFromString(commitIDStr)
+ if err != nil {
+ return nil, err
+ }
+
+ // If type is "commit, the tag is a lightweight tag
+ if ObjectType(tp) == ObjectCommit {
+ commit, err := repo.GetCommit(commitIDStr)
+ if err != nil {
+ return nil, err
+ }
+ tag := &Tag{
+ Name: name,
+ ID: tagID,
+ Object: commitID,
+ Type: tp,
+ Tagger: commit.Committer,
+ Message: commit.Message(),
+ }
+
+ repo.tagCache.Set(tagID.String(), tag)
+ return tag, nil
+ }
+
+ // The tag is an annotated tag with a message.
+ wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer cancel()
+
+ if _, err := wr.Write([]byte(tagID.String() + "\n")); err != nil {
+ return nil, err
+ }
+ _, typ, size, err := ReadBatchLine(rd)
+ if err != nil {
+ if errors.Is(err, io.EOF) || IsErrNotExist(err) {
+ return nil, ErrNotExist{ID: tagID.String()}
+ }
+ return nil, err
+ }
+ if typ != "tag" {
+ if err := DiscardFull(rd, size+1); err != nil {
+ return nil, err
+ }
+ return nil, ErrNotExist{ID: tagID.String()}
+ }
+
+ // then we need to parse the tag
+ // and load the commit
+ data, err := io.ReadAll(io.LimitReader(rd, size))
+ if err != nil {
+ return nil, err
+ }
+ _, err = rd.Discard(1)
+ if err != nil {
+ return nil, err
+ }
+
+ tag, err := parseTagData(tagID.Type(), data)
+ if err != nil {
+ return nil, err
+ }
+
+ tag.Name = name
+ tag.ID = tagID
+ tag.Type = tp
+
+ repo.tagCache.Set(tagID.String(), tag)
+ return tag, nil
+}
diff --git a/modules/git/repo_tag_gogit.go b/modules/git/repo_tag_gogit.go
deleted file mode 100644
index 4a7a06e9bd..0000000000
--- a/modules/git/repo_tag_gogit.go
+++ /dev/null
@@ -1,135 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "strings"
-
- "code.gitea.io/gitea/modules/log"
-
- "github.com/go-git/go-git/v5/plumbing"
-)
-
-// IsTagExist returns true if given tag exists in the repository.
-func (repo *Repository) IsTagExist(name string) bool {
- _, err := repo.gogitRepo.Reference(plumbing.ReferenceName(TagPrefix+name), true)
- return err == nil
-}
-
-// GetTags returns all tags of the repository.
-// returning at most limit tags, or all if limit is 0.
-func (repo *Repository) GetTags(skip, limit int) ([]string, error) {
- var tagNames []string
-
- tags, err := repo.gogitRepo.Tags()
- if err != nil {
- return nil, err
- }
-
- _ = tags.ForEach(func(tag *plumbing.Reference) error {
- tagNames = append(tagNames, strings.TrimPrefix(tag.Name().String(), TagPrefix))
- return nil
- })
-
- // Reverse order
- for i := 0; i < len(tagNames)/2; i++ {
- j := len(tagNames) - i - 1
- tagNames[i], tagNames[j] = tagNames[j], tagNames[i]
- }
-
- // since we have to reverse order we can paginate only afterwards
- if len(tagNames) < skip {
- tagNames = []string{}
- } else {
- tagNames = tagNames[skip:]
- }
- if limit != 0 && len(tagNames) > limit {
- tagNames = tagNames[:limit]
- }
-
- return tagNames, nil
-}
-
-// GetTagType gets the type of the tag, either commit (simple) or tag (annotated)
-func (repo *Repository) GetTagType(id ObjectID) (string, error) {
- // Get tag type
- obj, err := repo.gogitRepo.Object(plumbing.AnyObject, plumbing.Hash(id.RawValue()))
- if err != nil {
- if err == plumbing.ErrReferenceNotFound {
- return "", &ErrNotExist{ID: id.String()}
- }
- return "", err
- }
-
- return obj.Type().String(), nil
-}
-
-func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) {
- t, ok := repo.tagCache.Get(tagID.String())
- if ok {
- log.Debug("Hit cache: %s", tagID)
- tagClone := *t.(*Tag)
- tagClone.Name = name // This is necessary because lightweight tags may have same id
- return &tagClone, nil
- }
-
- tp, err := repo.GetTagType(tagID)
- if err != nil {
- return nil, err
- }
-
- // Get the commit ID and tag ID (may be different for annotated tag) for the returned tag object
- commitIDStr, err := repo.GetTagCommitID(name)
- if err != nil {
- // every tag should have a commit ID so return all errors
- return nil, err
- }
- commitID, err := NewIDFromString(commitIDStr)
- if err != nil {
- return nil, err
- }
-
- // If type is "commit, the tag is a lightweight tag
- if ObjectType(tp) == ObjectCommit {
- commit, err := repo.GetCommit(commitIDStr)
- if err != nil {
- return nil, err
- }
- tag := &Tag{
- Name: name,
- ID: tagID,
- Object: commitID,
- Type: tp,
- Tagger: commit.Committer,
- Message: commit.Message(),
- }
-
- repo.tagCache.Set(tagID.String(), tag)
- return tag, nil
- }
-
- gogitTag, err := repo.gogitRepo.TagObject(plumbing.Hash(tagID.RawValue()))
- if err != nil {
- if err == plumbing.ErrReferenceNotFound {
- return nil, &ErrNotExist{ID: tagID.String()}
- }
-
- return nil, err
- }
-
- tag := &Tag{
- Name: name,
- ID: tagID,
- Object: commitID.Type().MustID(gogitTag.Target[:]),
- Type: tp,
- Tagger: &gogitTag.Tagger,
- Message: gogitTag.Message,
- }
-
- repo.tagCache.Set(tagID.String(), tag)
- return tag, nil
-}
diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go
deleted file mode 100644
index cbab39f8c5..0000000000
--- a/modules/git/repo_tag_nogogit.go
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "errors"
- "io"
-
- "code.gitea.io/gitea/modules/log"
-)
-
-// IsTagExist returns true if given tag exists in the repository.
-func (repo *Repository) IsTagExist(name string) bool {
- if repo == nil || name == "" {
- return false
- }
-
- return repo.IsReferenceExist(TagPrefix + name)
-}
-
-// GetTags returns all tags of the repository.
-// returning at most limit tags, or all if limit is 0.
-func (repo *Repository) GetTags(skip, limit int) (tags []string, err error) {
- tags, _, err = callShowRef(repo.Ctx, repo.Path, TagPrefix, TrustedCmdArgs{TagPrefix, "--sort=-taggerdate"}, skip, limit)
- return tags, err
-}
-
-// GetTagType gets the type of the tag, either commit (simple) or tag (annotated)
-func (repo *Repository) GetTagType(id ObjectID) (string, error) {
- wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx)
- defer cancel()
- _, err := wr.Write([]byte(id.String() + "\n"))
- if err != nil {
- return "", err
- }
- _, typ, _, err := ReadBatchLine(rd)
- if IsErrNotExist(err) {
- return "", ErrNotExist{ID: id.String()}
- }
- return typ, nil
-}
-
-func (repo *Repository) getTag(tagID ObjectID, name string) (*Tag, error) {
- t, ok := repo.tagCache.Get(tagID.String())
- if ok {
- log.Debug("Hit cache: %s", tagID)
- tagClone := *t.(*Tag)
- tagClone.Name = name // This is necessary because lightweight tags may have same id
- return &tagClone, nil
- }
-
- tp, err := repo.GetTagType(tagID)
- if err != nil {
- return nil, err
- }
-
- // Get the commit ID and tag ID (may be different for annotated tag) for the returned tag object
- commitIDStr, err := repo.GetTagCommitID(name)
- if err != nil {
- // every tag should have a commit ID so return all errors
- return nil, err
- }
- commitID, err := NewIDFromString(commitIDStr)
- if err != nil {
- return nil, err
- }
-
- // If type is "commit, the tag is a lightweight tag
- if ObjectType(tp) == ObjectCommit {
- commit, err := repo.GetCommit(commitIDStr)
- if err != nil {
- return nil, err
- }
- tag := &Tag{
- Name: name,
- ID: tagID,
- Object: commitID,
- Type: tp,
- Tagger: commit.Committer,
- Message: commit.Message(),
- }
-
- repo.tagCache.Set(tagID.String(), tag)
- return tag, nil
- }
-
- // The tag is an annotated tag with a message.
- wr, rd, cancel := repo.CatFileBatch(repo.Ctx)
- defer cancel()
-
- if _, err := wr.Write([]byte(tagID.String() + "\n")); err != nil {
- return nil, err
- }
- _, typ, size, err := ReadBatchLine(rd)
- if err != nil {
- if errors.Is(err, io.EOF) || IsErrNotExist(err) {
- return nil, ErrNotExist{ID: tagID.String()}
- }
- return nil, err
- }
- if typ != "tag" {
- if err := DiscardFull(rd, size+1); err != nil {
- return nil, err
- }
- return nil, ErrNotExist{ID: tagID.String()}
- }
-
- // then we need to parse the tag
- // and load the commit
- data, err := io.ReadAll(io.LimitReader(rd, size))
- if err != nil {
- return nil, err
- }
- _, err = rd.Discard(1)
- if err != nil {
- return nil, err
- }
-
- tag, err := parseTagData(tagID.Type(), data)
- if err != nil {
- return nil, err
- }
-
- tag.Name = name
- tag.ID = tagID
- tag.Type = tp
-
- repo.tagCache.Set(tagID.String(), tag)
- return tag, nil
-}
diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go
index 8f0875c60d..a4b13bf03d 100644
--- a/modules/git/repo_tag_test.go
+++ b/modules/git/repo_tag_test.go
@@ -6,6 +6,7 @@ package git
import (
"path/filepath"
"testing"
+ "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -15,14 +16,14 @@ func TestRepository_GetTags(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
bareRepo1, err := openRepositoryWithDefaultContext(bareRepo1Path)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
defer bareRepo1.Close()
tags, total, err := bareRepo1.GetTagInfos(0, 0)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
assert.Len(t, tags, 2)
@@ -30,9 +31,11 @@ func TestRepository_GetTags(t *testing.T) {
assert.EqualValues(t, "signed-tag", tags[0].Name)
assert.EqualValues(t, "36f97d9a96457e2bab511db30fe2db03893ebc64", tags[0].ID.String())
assert.EqualValues(t, "tag", tags[0].Type)
+ assert.EqualValues(t, time.Date(2022, time.November, 13, 16, 40, 20, 0, time.FixedZone("", 3600)), tags[0].Tagger.When)
assert.EqualValues(t, "test", tags[1].Name)
assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[1].ID.String())
assert.EqualValues(t, "tag", tags[1].Type)
+ assert.EqualValues(t, time.Date(2018, time.June, 16, 20, 13, 18, 0, time.FixedZone("", -25200)), tags[1].Tagger.When)
}
func TestRepository_GetTag(t *testing.T) {
@@ -40,13 +43,13 @@ func TestRepository_GetTag(t *testing.T) {
clonedPath, err := cloneRepo(t, bareRepo1Path)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
bareRepo1, err := openRepositoryWithDefaultContext(clonedPath)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
defer bareRepo1.Close()
@@ -58,14 +61,14 @@ func TestRepository_GetTag(t *testing.T) {
// Create the lightweight tag
err = bareRepo1.CreateTag(lTagName, lTagCommitID)
if err != nil {
- assert.NoError(t, err, "Unable to create the lightweight tag: %s for ID: %s. Error: %v", lTagName, lTagCommitID, err)
+ require.NoError(t, err, "Unable to create the lightweight tag: %s for ID: %s. Error: %v", lTagName, lTagCommitID, err)
return
}
// and try to get the Tag for lightweight tag
lTag, err := bareRepo1.GetTag(lTagName)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
if lTag == nil {
@@ -85,20 +88,20 @@ func TestRepository_GetTag(t *testing.T) {
// Create the annotated tag
err = bareRepo1.CreateAnnotatedTag(aTagName, aTagMessage, aTagCommitID)
if err != nil {
- assert.NoError(t, err, "Unable to create the annotated tag: %s for ID: %s. Error: %v", aTagName, aTagCommitID, err)
+ require.NoError(t, err, "Unable to create the annotated tag: %s for ID: %s. Error: %v", aTagName, aTagCommitID, err)
return
}
// Now try to get the tag for the annotated Tag
aTagID, err := bareRepo1.GetTagID(aTagName)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
aTag, err := bareRepo1.GetTag(aTagName)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
if aTag == nil {
@@ -118,20 +121,20 @@ func TestRepository_GetTag(t *testing.T) {
err = bareRepo1.CreateTag(rTagName, rTagCommitID)
if err != nil {
- assert.NoError(t, err, "Unable to create the tag: %s for ID: %s. Error: %v", rTagName, rTagCommitID, err)
+ require.NoError(t, err, "Unable to create the tag: %s for ID: %s. Error: %v", rTagName, rTagCommitID, err)
return
}
rTagID, err := bareRepo1.GetTagID(rTagName)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
assert.EqualValues(t, rTagCommitID, rTagID)
oTagID, err := bareRepo1.GetTagID(lTagName)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
assert.EqualValues(t, lTagCommitID, oTagID)
@@ -142,13 +145,13 @@ func TestRepository_GetAnnotatedTag(t *testing.T) {
clonedPath, err := cloneRepo(t, bareRepo1Path)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
bareRepo1, err := openRepositoryWithDefaultContext(clonedPath)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
defer bareRepo1.Close()
@@ -166,7 +169,7 @@ func TestRepository_GetAnnotatedTag(t *testing.T) {
// Try an annotated tag
tag, err := bareRepo1.GetAnnotatedTag(aTagID)
if err != nil {
- assert.NoError(t, err)
+ require.NoError(t, err)
return
}
assert.NotNil(t, tag)
@@ -176,19 +179,19 @@ func TestRepository_GetAnnotatedTag(t *testing.T) {
// Annotated tag's Commit ID should fail
tag2, err := bareRepo1.GetAnnotatedTag(aTagCommitID)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, IsErrNotExist(err))
assert.Nil(t, tag2)
// Annotated tag's name should fail
tag3, err := bareRepo1.GetAnnotatedTag(aTagName)
- assert.Error(t, err)
- assert.Errorf(t, err, "Length must be 40: %d", len(aTagName))
+ require.Error(t, err)
+ require.Errorf(t, err, "Length must be 40: %d", len(aTagName))
assert.Nil(t, tag3)
// Lightweight Tag should fail
tag4, err := bareRepo1.GetAnnotatedTag(lTagCommitID)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, IsErrNotExist(err))
assert.Nil(t, tag4)
}
diff --git a/modules/git/repo_test.go b/modules/git/repo_test.go
index 9db78153a1..c4ef9dbe96 100644
--- a/modules/git/repo_test.go
+++ b/modules/git/repo_test.go
@@ -4,17 +4,17 @@
package git
import (
- "context"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetLatestCommitTime(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
lct, err := GetLatestCommitTime(DefaultContext, bareRepo1Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Time is Sun Nov 13 16:40:14 2022 +0100
// which is the time of commit
// ce064814f4a0d337b333e646ece456cd39fab612 (refs/heads/master)
@@ -24,31 +24,31 @@ func TestGetLatestCommitTime(t *testing.T) {
func TestRepoIsEmpty(t *testing.T) {
emptyRepo2Path := filepath.Join(testReposDir, "repo2_empty")
repo, err := openRepositoryWithDefaultContext(emptyRepo2Path)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
isEmpty, err := repo.IsEmpty()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, isEmpty)
}
func TestRepoGetDivergingCommits(t *testing.T) {
bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
- do, err := GetDivergingCommits(context.Background(), bareRepo1Path, "master", "branch2")
- assert.NoError(t, err)
+ do, err := GetDivergingCommits(t.Context(), bareRepo1Path, "master", "branch2")
+ require.NoError(t, err)
assert.Equal(t, DivergeObject{
Ahead: 1,
Behind: 5,
}, do)
- do, err = GetDivergingCommits(context.Background(), bareRepo1Path, "master", "master")
- assert.NoError(t, err)
+ do, err = GetDivergingCommits(t.Context(), bareRepo1Path, "master", "master")
+ require.NoError(t, err)
assert.Equal(t, DivergeObject{
Ahead: 0,
Behind: 0,
}, do)
- do, err = GetDivergingCommits(context.Background(), bareRepo1Path, "master", "test")
- assert.NoError(t, err)
+ do, err = GetDivergingCommits(t.Context(), bareRepo1Path, "master", "test")
+ require.NoError(t, err)
assert.Equal(t, DivergeObject{
Ahead: 0,
Behind: 2,
diff --git a/modules/git/repo_tree.go b/modules/git/repo_tree.go
index ab48d47d13..53d94d9d7d 100644
--- a/modules/git/repo_tree.go
+++ b/modules/git/repo_tree.go
@@ -6,6 +6,7 @@ package git
import (
"bytes"
+ "io"
"os"
"strings"
"time"
@@ -65,3 +66,91 @@ func (repo *Repository) CommitTree(author, committer *Signature, tree *Tree, opt
}
return NewIDFromString(strings.TrimSpace(stdout.String()))
}
+
+func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
+ wr, rd, cancel, err := repo.CatFileBatch(repo.Ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer cancel()
+
+ _, _ = wr.Write([]byte(id.String() + "\n"))
+
+ // ignore the SHA
+ _, typ, size, err := ReadBatchLine(rd)
+ if err != nil {
+ return nil, err
+ }
+
+ switch typ {
+ case "tag":
+ resolvedID := id
+ data, err := io.ReadAll(io.LimitReader(rd, size))
+ if err != nil {
+ return nil, err
+ }
+ tag, err := parseTagData(id.Type(), data)
+ if err != nil {
+ return nil, err
+ }
+ commit, err := tag.Commit(repo)
+ if err != nil {
+ return nil, err
+ }
+ commit.Tree.ResolvedID = resolvedID
+ return &commit.Tree, nil
+ case "commit":
+ commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
+ if err != nil {
+ return nil, err
+ }
+ if _, err := rd.Discard(1); err != nil {
+ return nil, err
+ }
+ commit.Tree.ResolvedID = commit.ID
+ return &commit.Tree, nil
+ case "tree":
+ tree := NewTree(repo, id)
+ tree.ResolvedID = id
+ objectFormat, err := repo.GetObjectFormat()
+ if err != nil {
+ return nil, err
+ }
+ tree.entries, err = catBatchParseTreeEntries(objectFormat, tree, rd, size)
+ if err != nil {
+ return nil, err
+ }
+ tree.entriesParsed = true
+ return tree, nil
+ default:
+ if err := DiscardFull(rd, size+1); err != nil {
+ return nil, err
+ }
+ return nil, ErrNotExist{
+ ID: id.String(),
+ }
+ }
+}
+
+// GetTree find the tree object in the repository.
+func (repo *Repository) GetTree(idStr string) (*Tree, error) {
+ objectFormat, err := repo.GetObjectFormat()
+ if err != nil {
+ return nil, err
+ }
+ if len(idStr) != objectFormat.FullLength() {
+ res, err := repo.GetRefCommitID(idStr)
+ if err != nil {
+ return nil, err
+ }
+ if len(res) > 0 {
+ idStr = res
+ }
+ }
+ id, err := NewIDFromString(idStr)
+ if err != nil {
+ return nil, err
+ }
+
+ return repo.getTree(id)
+}
diff --git a/modules/git/repo_tree_gogit.go b/modules/git/repo_tree_gogit.go
deleted file mode 100644
index dc97ce1344..0000000000
--- a/modules/git/repo_tree_gogit.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import "github.com/go-git/go-git/v5/plumbing"
-
-func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
- gogitTree, err := repo.gogitRepo.TreeObject(plumbing.Hash(id.RawValue()))
- if err != nil {
- return nil, err
- }
-
- tree := NewTree(repo, id)
- tree.gogitTree = gogitTree
- return tree, nil
-}
-
-// GetTree find the tree object in the repository.
-func (repo *Repository) GetTree(idStr string) (*Tree, error) {
- objectFormat, err := repo.GetObjectFormat()
- if err != nil {
- return nil, err
- }
-
- if len(idStr) != objectFormat.FullLength() {
- res, _, err := NewCommand(repo.Ctx, "rev-parse", "--verify").AddDynamicArguments(idStr).RunStdString(&RunOpts{Dir: repo.Path})
- if err != nil {
- return nil, err
- }
- if len(res) > 0 {
- idStr = res[:len(res)-1]
- }
- }
- id, err := NewIDFromString(idStr)
- if err != nil {
- return nil, err
- }
- resolvedID := id
- commitObject, err := repo.gogitRepo.CommitObject(plumbing.Hash(id.RawValue()))
- if err == nil {
- id = ParseGogitHash(commitObject.TreeHash)
- }
- treeObject, err := repo.getTree(id)
- if err != nil {
- return nil, err
- }
- treeObject.ResolvedID = resolvedID
- return treeObject, nil
-}
diff --git a/modules/git/repo_tree_nogogit.go b/modules/git/repo_tree_nogogit.go
deleted file mode 100644
index e82012de6f..0000000000
--- a/modules/git/repo_tree_nogogit.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "io"
-)
-
-func (repo *Repository) getTree(id ObjectID) (*Tree, error) {
- wr, rd, cancel := repo.CatFileBatch(repo.Ctx)
- defer cancel()
-
- _, _ = wr.Write([]byte(id.String() + "\n"))
-
- // ignore the SHA
- _, typ, size, err := ReadBatchLine(rd)
- if err != nil {
- return nil, err
- }
-
- switch typ {
- case "tag":
- resolvedID := id
- data, err := io.ReadAll(io.LimitReader(rd, size))
- if err != nil {
- return nil, err
- }
- tag, err := parseTagData(id.Type(), data)
- if err != nil {
- return nil, err
- }
- commit, err := tag.Commit(repo)
- if err != nil {
- return nil, err
- }
- commit.Tree.ResolvedID = resolvedID
- return &commit.Tree, nil
- case "commit":
- commit, err := CommitFromReader(repo, id, io.LimitReader(rd, size))
- if err != nil {
- return nil, err
- }
- if _, err := rd.Discard(1); err != nil {
- return nil, err
- }
- commit.Tree.ResolvedID = commit.ID
- return &commit.Tree, nil
- case "tree":
- tree := NewTree(repo, id)
- tree.ResolvedID = id
- objectFormat, err := repo.GetObjectFormat()
- if err != nil {
- return nil, err
- }
- tree.entries, err = catBatchParseTreeEntries(objectFormat, tree, rd, size)
- if err != nil {
- return nil, err
- }
- tree.entriesParsed = true
- return tree, nil
- default:
- if err := DiscardFull(rd, size+1); err != nil {
- return nil, err
- }
- return nil, ErrNotExist{
- ID: id.String(),
- }
- }
-}
-
-// GetTree find the tree object in the repository.
-func (repo *Repository) GetTree(idStr string) (*Tree, error) {
- objectFormat, err := repo.GetObjectFormat()
- if err != nil {
- return nil, err
- }
- if len(idStr) != objectFormat.FullLength() {
- res, err := repo.GetRefCommitID(idStr)
- if err != nil {
- return nil, err
- }
- if len(res) > 0 {
- idStr = res
- }
- }
- id, err := NewIDFromString(idStr)
- if err != nil {
- return nil, err
- }
-
- return repo.getTree(id)
-}
diff --git a/modules/git/signature.go b/modules/git/signature.go
index f50a097758..bd9aebbdd6 100644
--- a/modules/git/signature.go
+++ b/modules/git/signature.go
@@ -5,13 +5,31 @@
package git
import (
+ "fmt"
"strconv"
"strings"
"time"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
+// Signature represents the Author, Committer or Tagger information.
+type Signature struct {
+ Name string // the committer name, it can be anything
+ Email string // the committer email, it can be anything
+ When time.Time // the timestamp of the signature
+}
+
+func (s *Signature) String() string {
+ return fmt.Sprintf("%s <%s>", s.Name, s.Email)
+}
+
+// Decode decodes a byte array representing a signature to signature
+func (s *Signature) Decode(b []byte) {
+ *s = *parseSignatureFromCommitLine(util.UnsafeBytesToString(b))
+}
+
// Helper to get a signature from the commit line, which looks like:
//
// full name ] 1378823654 +0200
diff --git a/modules/git/signature_gogit.go b/modules/git/signature_gogit.go
deleted file mode 100644
index 1fc6aabceb..0000000000
--- a/modules/git/signature_gogit.go
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// Signature represents the Author or Committer information.
-type Signature = object.Signature
diff --git a/modules/git/signature_nogogit.go b/modules/git/signature_nogogit.go
deleted file mode 100644
index 0d19c0abdc..0000000000
--- a/modules/git/signature_nogogit.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "fmt"
- "time"
-
- "code.gitea.io/gitea/modules/util"
-)
-
-// Signature represents the Author, Committer or Tagger information.
-type Signature struct {
- Name string // the committer name, it can be anything
- Email string // the committer email, it can be anything
- When time.Time // the timestamp of the signature
-}
-
-func (s *Signature) String() string {
- return fmt.Sprintf("%s <%s>", s.Name, s.Email)
-}
-
-// Decode decodes a byte array representing a signature to signature
-func (s *Signature) Decode(b []byte) {
- *s = *parseSignatureFromCommitLine(util.UnsafeBytesToString(b))
-}
diff --git a/modules/git/tag.go b/modules/git/tag.go
index 04f50e8db8..64f1b952ad 100644
--- a/modules/git/tag.go
+++ b/modules/git/tag.go
@@ -5,11 +5,10 @@ package git
import (
"bytes"
- "sort"
"strings"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
)
const (
@@ -107,23 +106,3 @@ l:
return tag, nil
}
-
-type tagSorter []*Tag
-
-func (ts tagSorter) Len() int {
- return len([]*Tag(ts))
-}
-
-func (ts tagSorter) Less(i, j int) bool {
- return []*Tag(ts)[i].Tagger.When.After([]*Tag(ts)[j].Tagger.When)
-}
-
-func (ts tagSorter) Swap(i, j int) {
- []*Tag(ts)[i], []*Tag(ts)[j] = []*Tag(ts)[j], []*Tag(ts)[i]
-}
-
-// sortTagsByTime
-func sortTagsByTime(tags []*Tag) {
- sorter := tagSorter(tags)
- sort.Sort(sorter)
-}
diff --git a/modules/git/tag_test.go b/modules/git/tag_test.go
index 79796bbdc2..8279066b2f 100644
--- a/modules/git/tag_test.go
+++ b/modules/git/tag_test.go
@@ -8,6 +8,7 @@ import (
"time"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_parseTagData(t *testing.T) {
@@ -85,7 +86,7 @@ v0
for _, test := range testData {
tag, err := parseTagData(Sha1ObjectFormat, test.data)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, test.tag.ID, tag.ID)
assert.EqualValues(t, test.tag.Object, tag.Object)
assert.EqualValues(t, test.tag.Name, tag.Name)
diff --git a/modules/git/tests/repos/language_stats_repo/index b/modules/git/tests/repos/language_stats_repo/index
deleted file mode 100644
index e6c0223171..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/index and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/logs/HEAD b/modules/git/tests/repos/language_stats_repo/logs/HEAD
deleted file mode 100644
index 9cedbb66a9..0000000000
--- a/modules/git/tests/repos/language_stats_repo/logs/HEAD
+++ /dev/null
@@ -1,2 +0,0 @@
-0000000000000000000000000000000000000000 8fee858da5796dfb37704761701bb8e800ad9ef3 Andrew Thornton 1632140318 +0100 commit (initial): Add some test files for GetLanguageStats
-8fee858da5796dfb37704761701bb8e800ad9ef3 341fca5b5ea3de596dc483e54c2db28633cd2f97 oliverpool 1711278775 +0100 push
diff --git a/modules/git/tests/repos/language_stats_repo/logs/refs/heads/master b/modules/git/tests/repos/language_stats_repo/logs/refs/heads/master
deleted file mode 100644
index 9cedbb66a9..0000000000
--- a/modules/git/tests/repos/language_stats_repo/logs/refs/heads/master
+++ /dev/null
@@ -1,2 +0,0 @@
-0000000000000000000000000000000000000000 8fee858da5796dfb37704761701bb8e800ad9ef3 Andrew Thornton 1632140318 +0100 commit (initial): Add some test files for GetLanguageStats
-8fee858da5796dfb37704761701bb8e800ad9ef3 341fca5b5ea3de596dc483e54c2db28633cd2f97 oliverpool 1711278775 +0100 push
diff --git a/modules/git/tests/repos/language_stats_repo/objects/1e/ea60592b55dcb45c36029cc1202132e9fb756c b/modules/git/tests/repos/language_stats_repo/objects/1e/ea60592b55dcb45c36029cc1202132e9fb756c
deleted file mode 100644
index 3c55bab91e..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/1e/ea60592b55dcb45c36029cc1202132e9fb756c and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/22/b6aa0588563508d8879f062470c8cbc7b2f2bb b/modules/git/tests/repos/language_stats_repo/objects/22/b6aa0588563508d8879f062470c8cbc7b2f2bb
deleted file mode 100644
index 947feecea9..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/22/b6aa0588563508d8879f062470c8cbc7b2f2bb and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/34/1fca5b5ea3de596dc483e54c2db28633cd2f97 b/modules/git/tests/repos/language_stats_repo/objects/34/1fca5b5ea3de596dc483e54c2db28633cd2f97
deleted file mode 100644
index 9ce337e070..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/34/1fca5b5ea3de596dc483e54c2db28633cd2f97 and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/42/25ecfaf6bafbcfa31ea5cbd8121c36d9457085 b/modules/git/tests/repos/language_stats_repo/objects/42/25ecfaf6bafbcfa31ea5cbd8121c36d9457085
deleted file mode 100644
index ff3b642734..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/42/25ecfaf6bafbcfa31ea5cbd8121c36d9457085 and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/4a/c803638e4b8995146e329a05e096fa2c77a03d b/modules/git/tests/repos/language_stats_repo/objects/4a/c803638e4b8995146e329a05e096fa2c77a03d
deleted file mode 100644
index b71abc120c..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/4a/c803638e4b8995146e329a05e096fa2c77a03d and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/64/4c37ad7fe64ac012df7e59d27a92e3137c640e b/modules/git/tests/repos/language_stats_repo/objects/64/4c37ad7fe64ac012df7e59d27a92e3137c640e
deleted file mode 100644
index 5c2485d82f..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/64/4c37ad7fe64ac012df7e59d27a92e3137c640e and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/6c/633a0067b463e459ae952716b17ae36aa30adc b/modules/git/tests/repos/language_stats_repo/objects/6c/633a0067b463e459ae952716b17ae36aa30adc
deleted file mode 100644
index 873cb7187d..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/6c/633a0067b463e459ae952716b17ae36aa30adc and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/8e/b563dc106e3dfd3ad0fa81f7a0c5e2604f80cd b/modules/git/tests/repos/language_stats_repo/objects/8e/b563dc106e3dfd3ad0fa81f7a0c5e2604f80cd
deleted file mode 100644
index f89ecb7d60..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/8e/b563dc106e3dfd3ad0fa81f7a0c5e2604f80cd and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/8f/ee858da5796dfb37704761701bb8e800ad9ef3 b/modules/git/tests/repos/language_stats_repo/objects/8f/ee858da5796dfb37704761701bb8e800ad9ef3
deleted file mode 100644
index 0219c2d565..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/8f/ee858da5796dfb37704761701bb8e800ad9ef3 and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/aa/a21bf84c8b2304608d3fc83b747840f2456299 b/modules/git/tests/repos/language_stats_repo/objects/aa/a21bf84c8b2304608d3fc83b747840f2456299
deleted file mode 100644
index adc50f2bce..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/aa/a21bf84c8b2304608d3fc83b747840f2456299 and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/da/a5abe3c5f42cae598e362e8a8db6284565d6bb b/modules/git/tests/repos/language_stats_repo/objects/da/a5abe3c5f42cae598e362e8a8db6284565d6bb
deleted file mode 100644
index 9d4d4b1a04..0000000000
Binary files a/modules/git/tests/repos/language_stats_repo/objects/da/a5abe3c5f42cae598e362e8a8db6284565d6bb and /dev/null differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/pack/pack-371b1f6c24df14da4898b22c00ff8fb55303ac76.idx b/modules/git/tests/repos/language_stats_repo/objects/pack/pack-371b1f6c24df14da4898b22c00ff8fb55303ac76.idx
new file mode 100644
index 0000000000..186136cb12
Binary files /dev/null and b/modules/git/tests/repos/language_stats_repo/objects/pack/pack-371b1f6c24df14da4898b22c00ff8fb55303ac76.idx differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/pack/pack-371b1f6c24df14da4898b22c00ff8fb55303ac76.pack b/modules/git/tests/repos/language_stats_repo/objects/pack/pack-371b1f6c24df14da4898b22c00ff8fb55303ac76.pack
new file mode 100644
index 0000000000..046061c688
Binary files /dev/null and b/modules/git/tests/repos/language_stats_repo/objects/pack/pack-371b1f6c24df14da4898b22c00ff8fb55303ac76.pack differ
diff --git a/modules/git/tests/repos/language_stats_repo/objects/pack/pack-371b1f6c24df14da4898b22c00ff8fb55303ac76.rev b/modules/git/tests/repos/language_stats_repo/objects/pack/pack-371b1f6c24df14da4898b22c00ff8fb55303ac76.rev
new file mode 100644
index 0000000000..7d8c6f3562
Binary files /dev/null and b/modules/git/tests/repos/language_stats_repo/objects/pack/pack-371b1f6c24df14da4898b22c00ff8fb55303ac76.rev differ
diff --git a/modules/git/tests/repos/language_stats_repo/packed-refs b/modules/git/tests/repos/language_stats_repo/packed-refs
new file mode 100644
index 0000000000..63e01583a4
--- /dev/null
+++ b/modules/git/tests/repos/language_stats_repo/packed-refs
@@ -0,0 +1,2 @@
+# pack-refs with: peeled fully-peeled sorted
+95d3505f2db273e40be79f84416051ae85e9ea0d refs/heads/master
diff --git a/modules/git/tests/repos/language_stats_repo/refs/heads/.gitkeep b/modules/git/tests/repos/language_stats_repo/refs/heads/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/modules/git/tests/repos/language_stats_repo/refs/heads/master b/modules/git/tests/repos/language_stats_repo/refs/heads/master
deleted file mode 100644
index e89143e56b..0000000000
--- a/modules/git/tests/repos/language_stats_repo/refs/heads/master
+++ /dev/null
@@ -1 +0,0 @@
-341fca5b5ea3de596dc483e54c2db28633cd2f97
diff --git a/modules/git/tests/repos/language_stats_repo/refs/tags/.gitkeep b/modules/git/tests/repos/language_stats_repo/refs/tags/.gitkeep
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/modules/git/tree.go b/modules/git/tree.go
index 1da4a9fa5d..f6201f6cc9 100644
--- a/modules/git/tree.go
+++ b/modules/git/tree.go
@@ -6,9 +6,26 @@ package git
import (
"bytes"
+ "io"
"strings"
)
+// Tree represents a flat directory listing.
+type Tree struct {
+ ID ObjectID
+ ResolvedID ObjectID
+ repo *Repository
+
+ // parent tree
+ ptree *Tree
+
+ entries Entries
+ entriesParsed bool
+
+ entriesRecursive Entries
+ entriesRecursiveParsed bool
+}
+
// NewTree create a new tree according the repository and tree id
func NewTree(repo *Repository, id ObjectID) *Tree {
return &Tree{
@@ -17,6 +34,103 @@ func NewTree(repo *Repository, id ObjectID) *Tree {
}
}
+// ListEntries returns all entries of current tree.
+func (t *Tree) ListEntries() (Entries, error) {
+ if t.entriesParsed {
+ return t.entries, nil
+ }
+
+ if t.repo != nil {
+ wr, rd, cancel, err := t.repo.CatFileBatch(t.repo.Ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer cancel()
+
+ _, _ = wr.Write([]byte(t.ID.String() + "\n"))
+ _, typ, sz, err := ReadBatchLine(rd)
+ if err != nil {
+ return nil, err
+ }
+ if typ == "commit" {
+ treeID, err := ReadTreeID(rd, sz)
+ if err != nil && err != io.EOF {
+ return nil, err
+ }
+ _, _ = wr.Write([]byte(treeID + "\n"))
+ _, typ, sz, err = ReadBatchLine(rd)
+ if err != nil {
+ return nil, err
+ }
+ }
+ if typ == "tree" {
+ t.entries, err = catBatchParseTreeEntries(t.ID.Type(), t, rd, sz)
+ if err != nil {
+ return nil, err
+ }
+ t.entriesParsed = true
+ return t.entries, nil
+ }
+
+ // Not a tree just use ls-tree instead
+ if err := DiscardFull(rd, sz+1); err != nil {
+ return nil, err
+ }
+ }
+
+ stdout, _, runErr := NewCommand(t.repo.Ctx, "ls-tree", "-l").AddDynamicArguments(t.ID.String()).RunStdBytes(&RunOpts{Dir: t.repo.Path})
+ if runErr != nil {
+ if strings.Contains(runErr.Error(), "fatal: Not a valid object name") || strings.Contains(runErr.Error(), "fatal: not a tree object") {
+ return nil, ErrNotExist{
+ ID: t.ID.String(),
+ }
+ }
+ return nil, runErr
+ }
+
+ var err error
+ t.entries, err = parseTreeEntries(stdout, t)
+ if err == nil {
+ t.entriesParsed = true
+ }
+
+ return t.entries, err
+}
+
+// listEntriesRecursive returns all entries of current tree recursively including all subtrees
+// extraArgs could be "-l" to get the size, which is slower
+func (t *Tree) listEntriesRecursive(extraArgs TrustedCmdArgs) (Entries, error) {
+ if t.entriesRecursiveParsed {
+ return t.entriesRecursive, nil
+ }
+
+ stdout, _, runErr := NewCommand(t.repo.Ctx, "ls-tree", "-t", "-r").
+ AddArguments(extraArgs...).
+ AddDynamicArguments(t.ID.String()).
+ RunStdBytes(&RunOpts{Dir: t.repo.Path})
+ if runErr != nil {
+ return nil, runErr
+ }
+
+ var err error
+ t.entriesRecursive, err = parseTreeEntries(stdout, t)
+ if err == nil {
+ t.entriesRecursiveParsed = true
+ }
+
+ return t.entriesRecursive, err
+}
+
+// ListEntriesRecursiveFast returns all entries of current tree recursively including all subtrees, no size
+func (t *Tree) ListEntriesRecursiveFast() (Entries, error) {
+ return t.listEntriesRecursive(nil)
+}
+
+// ListEntriesRecursiveWithSize returns all entries of current tree recursively including all subtrees, with size
+func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) {
+ return t.listEntriesRecursive(TrustedCmdArgs{"--long"})
+}
+
// SubTree get a sub tree by the sub dir path
func (t *Tree) SubTree(rpath string) (*Tree, error) {
if len(rpath) == 0 {
@@ -62,3 +176,14 @@ func (repo *Repository) LsTree(ref string, filenames ...string) ([]string, error
return filelist, err
}
+
+// GetTreePathLatestCommitID returns the latest commit of a tree path
+func (repo *Repository) GetTreePathLatestCommit(refName, treePath string) (*Commit, error) {
+ stdout, _, err := NewCommand(repo.Ctx, "rev-list", "-1").
+ AddDynamicArguments(refName).AddDashesAndList(treePath).
+ RunStdString(&RunOpts{Dir: repo.Path})
+ if err != nil {
+ return nil, err
+ }
+ return repo.GetCommit(strings.TrimSpace(stdout))
+}
diff --git a/modules/git/tree_blob.go b/modules/git/tree_blob.go
index e60c1f915b..df339f64b1 100644
--- a/modules/git/tree_blob.go
+++ b/modules/git/tree_blob.go
@@ -5,7 +5,48 @@
package git
-import "strings"
+import (
+ "path"
+ "strings"
+)
+
+// GetTreeEntryByPath get the tree entries according the sub dir
+func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
+ if len(relpath) == 0 {
+ return &TreeEntry{
+ ptree: t,
+ ID: t.ID,
+ name: "",
+ fullName: "",
+ entryMode: EntryModeTree,
+ }, nil
+ }
+
+ // FIXME: This should probably use git cat-file --batch to be a bit more efficient
+ relpath = path.Clean(relpath)
+ parts := strings.Split(relpath, "/")
+ var err error
+ tree := t
+ for i, name := range parts {
+ if i == len(parts)-1 {
+ entries, err := tree.ListEntries()
+ if err != nil {
+ return nil, err
+ }
+ for _, v := range entries {
+ if v.Name() == name {
+ return v, nil
+ }
+ }
+ } else {
+ tree, err = tree.SubTree(name)
+ if err != nil {
+ return nil, err
+ }
+ }
+ }
+ return nil, ErrNotExist{"", relpath}
+}
// GetBlobByPath get the blob object according the path
func (t *Tree) GetBlobByPath(relpath string) (*Blob, error) {
diff --git a/modules/git/tree_blob_gogit.go b/modules/git/tree_blob_gogit.go
deleted file mode 100644
index 92c25cb92c..0000000000
--- a/modules/git/tree_blob_gogit.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "path"
- "strings"
-
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/filemode"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// GetTreeEntryByPath get the tree entries according the sub dir
-func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
- if len(relpath) == 0 {
- return &TreeEntry{
- ID: t.ID,
- // Type: ObjectTree,
- gogitTreeEntry: &object.TreeEntry{
- Name: "",
- Mode: filemode.Dir,
- Hash: plumbing.Hash(t.ID.RawValue()),
- },
- }, nil
- }
-
- relpath = path.Clean(relpath)
- parts := strings.Split(relpath, "/")
- var err error
- tree := t
- for i, name := range parts {
- if i == len(parts)-1 {
- entries, err := tree.ListEntries()
- if err != nil {
- if err == plumbing.ErrObjectNotFound {
- return nil, ErrNotExist{
- RelPath: relpath,
- }
- }
- return nil, err
- }
- for _, v := range entries {
- if v.Name() == name {
- return v, nil
- }
- }
- } else {
- tree, err = tree.SubTree(name)
- if err != nil {
- if err == plumbing.ErrObjectNotFound {
- return nil, ErrNotExist{
- RelPath: relpath,
- }
- }
- return nil, err
- }
- }
- }
- return nil, ErrNotExist{"", relpath}
-}
diff --git a/modules/git/tree_blob_nogogit.go b/modules/git/tree_blob_nogogit.go
deleted file mode 100644
index 92d3d107a7..0000000000
--- a/modules/git/tree_blob_nogogit.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "path"
- "strings"
-)
-
-// GetTreeEntryByPath get the tree entries according the sub dir
-func (t *Tree) GetTreeEntryByPath(relpath string) (*TreeEntry, error) {
- if len(relpath) == 0 {
- return &TreeEntry{
- ptree: t,
- ID: t.ID,
- name: "",
- fullName: "",
- entryMode: EntryModeTree,
- }, nil
- }
-
- // FIXME: This should probably use git cat-file --batch to be a bit more efficient
- relpath = path.Clean(relpath)
- parts := strings.Split(relpath, "/")
- var err error
- tree := t
- for i, name := range parts {
- if i == len(parts)-1 {
- entries, err := tree.ListEntries()
- if err != nil {
- return nil, err
- }
- for _, v := range entries {
- if v.Name() == name {
- return v, nil
- }
- }
- } else {
- tree, err = tree.SubTree(name)
- if err != nil {
- return nil, err
- }
- }
- }
- return nil, ErrNotExist{"", relpath}
-}
diff --git a/modules/git/tree_entry.go b/modules/git/tree_entry.go
index 2c47c8858c..d51b7992fe 100644
--- a/modules/git/tree_entry.go
+++ b/modules/git/tree_entry.go
@@ -8,8 +8,102 @@ import (
"io"
"sort"
"strings"
+
+ "forgejo.org/modules/log"
)
+// TreeEntry the leaf in the git tree
+type TreeEntry struct {
+ ID ObjectID
+
+ ptree *Tree
+
+ entryMode EntryMode
+ name string
+
+ size int64
+ sized bool
+ fullName string
+}
+
+// Name returns the name of the entry
+func (te *TreeEntry) Name() string {
+ if te.fullName != "" {
+ return te.fullName
+ }
+ return te.name
+}
+
+// Mode returns the mode of the entry
+func (te *TreeEntry) Mode() EntryMode {
+ return te.entryMode
+}
+
+// Size returns the size of the entry
+func (te *TreeEntry) Size() int64 {
+ if te.IsDir() {
+ return 0
+ } else if te.sized {
+ return te.size
+ }
+
+ wr, rd, cancel, err := te.ptree.repo.CatFileBatchCheck(te.ptree.repo.Ctx)
+ if err != nil {
+ log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
+ return 0
+ }
+ defer cancel()
+ _, err = wr.Write([]byte(te.ID.String() + "\n"))
+ if err != nil {
+ log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
+ return 0
+ }
+ _, _, te.size, err = ReadBatchLine(rd)
+ if err != nil {
+ log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
+ return 0
+ }
+
+ te.sized = true
+ return te.size
+}
+
+// IsSubModule if the entry is a sub module
+func (te *TreeEntry) IsSubModule() bool {
+ return te.entryMode == EntryModeCommit
+}
+
+// IsDir if the entry is a sub dir
+func (te *TreeEntry) IsDir() bool {
+ return te.entryMode == EntryModeTree
+}
+
+// IsLink if the entry is a symlink
+func (te *TreeEntry) IsLink() bool {
+ return te.entryMode == EntryModeSymlink
+}
+
+// IsRegular if the entry is a regular file
+func (te *TreeEntry) IsRegular() bool {
+ return te.entryMode == EntryModeBlob
+}
+
+// IsExecutable if the entry is an executable file (not necessarily binary)
+func (te *TreeEntry) IsExecutable() bool {
+ return te.entryMode == EntryModeExec
+}
+
+// Blob returns the blob object the entry
+func (te *TreeEntry) Blob() *Blob {
+ return &Blob{
+ ID: te.ID,
+ name: te.Name(),
+ size: te.size,
+ gotSize: te.sized,
+ repo: te.ptree.repo,
+ }
+}
+
// Type returns the type of the entry (commit, tree, blob)
func (te *TreeEntry) Type() string {
switch te.Mode() {
diff --git a/modules/git/tree_entry_gogit.go b/modules/git/tree_entry_gogit.go
deleted file mode 100644
index eb9b012681..0000000000
--- a/modules/git/tree_entry_gogit.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/filemode"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// TreeEntry the leaf in the git tree
-type TreeEntry struct {
- ID ObjectID
-
- gogitTreeEntry *object.TreeEntry
- ptree *Tree
-
- size int64
- sized bool
- fullName string
-}
-
-// Name returns the name of the entry
-func (te *TreeEntry) Name() string {
- if te.fullName != "" {
- return te.fullName
- }
- return te.gogitTreeEntry.Name
-}
-
-// Mode returns the mode of the entry
-func (te *TreeEntry) Mode() EntryMode {
- return EntryMode(te.gogitTreeEntry.Mode)
-}
-
-// Size returns the size of the entry
-func (te *TreeEntry) Size() int64 {
- if te.IsDir() {
- return 0
- } else if te.sized {
- return te.size
- }
-
- file, err := te.ptree.gogitTree.TreeEntryFile(te.gogitTreeEntry)
- if err != nil {
- return 0
- }
-
- te.sized = true
- te.size = file.Size
- return te.size
-}
-
-// IsSubModule if the entry is a sub module
-func (te *TreeEntry) IsSubModule() bool {
- return te.gogitTreeEntry.Mode == filemode.Submodule
-}
-
-// IsDir if the entry is a sub dir
-func (te *TreeEntry) IsDir() bool {
- return te.gogitTreeEntry.Mode == filemode.Dir
-}
-
-// IsLink if the entry is a symlink
-func (te *TreeEntry) IsLink() bool {
- return te.gogitTreeEntry.Mode == filemode.Symlink
-}
-
-// IsRegular if the entry is a regular file
-func (te *TreeEntry) IsRegular() bool {
- return te.gogitTreeEntry.Mode == filemode.Regular
-}
-
-// IsExecutable if the entry is an executable file (not necessarily binary)
-func (te *TreeEntry) IsExecutable() bool {
- return te.gogitTreeEntry.Mode == filemode.Executable
-}
-
-// Blob returns the blob object the entry
-func (te *TreeEntry) Blob() *Blob {
- encodedObj, err := te.ptree.repo.gogitRepo.Storer.EncodedObject(plumbing.AnyObject, te.gogitTreeEntry.Hash)
- if err != nil {
- return nil
- }
-
- return &Blob{
- ID: ParseGogitHash(te.gogitTreeEntry.Hash),
- gogitEncodedObj: encodedObj,
- name: te.Name(),
- }
-}
diff --git a/modules/git/tree_entry_nogogit.go b/modules/git/tree_entry_nogogit.go
deleted file mode 100644
index 89244e27ee..0000000000
--- a/modules/git/tree_entry_nogogit.go
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import "code.gitea.io/gitea/modules/log"
-
-// TreeEntry the leaf in the git tree
-type TreeEntry struct {
- ID ObjectID
-
- ptree *Tree
-
- entryMode EntryMode
- name string
-
- size int64
- sized bool
- fullName string
-}
-
-// Name returns the name of the entry
-func (te *TreeEntry) Name() string {
- if te.fullName != "" {
- return te.fullName
- }
- return te.name
-}
-
-// Mode returns the mode of the entry
-func (te *TreeEntry) Mode() EntryMode {
- return te.entryMode
-}
-
-// Size returns the size of the entry
-func (te *TreeEntry) Size() int64 {
- if te.IsDir() {
- return 0
- } else if te.sized {
- return te.size
- }
-
- wr, rd, cancel := te.ptree.repo.CatFileBatchCheck(te.ptree.repo.Ctx)
- defer cancel()
- _, err := wr.Write([]byte(te.ID.String() + "\n"))
- if err != nil {
- log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
- return 0
- }
- _, _, te.size, err = ReadBatchLine(rd)
- if err != nil {
- log.Debug("error whilst reading size for %s in %s. Error: %v", te.ID.String(), te.ptree.repo.Path, err)
- return 0
- }
-
- te.sized = true
- return te.size
-}
-
-// IsSubModule if the entry is a sub module
-func (te *TreeEntry) IsSubModule() bool {
- return te.entryMode == EntryModeCommit
-}
-
-// IsDir if the entry is a sub dir
-func (te *TreeEntry) IsDir() bool {
- return te.entryMode == EntryModeTree
-}
-
-// IsLink if the entry is a symlink
-func (te *TreeEntry) IsLink() bool {
- return te.entryMode == EntryModeSymlink
-}
-
-// IsRegular if the entry is a regular file
-func (te *TreeEntry) IsRegular() bool {
- return te.entryMode == EntryModeBlob
-}
-
-// IsExecutable if the entry is an executable file (not necessarily binary)
-func (te *TreeEntry) IsExecutable() bool {
- return te.entryMode == EntryModeExec
-}
-
-// Blob returns the blob object the entry
-func (te *TreeEntry) Blob() *Blob {
- return &Blob{
- ID: te.ID,
- name: te.Name(),
- size: te.size,
- gotSize: te.sized,
- repo: te.ptree.repo,
- }
-}
diff --git a/modules/git/tree_entry_test.go b/modules/git/tree_entry_test.go
deleted file mode 100644
index 30eee13669..0000000000
--- a/modules/git/tree_entry_test.go
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2017 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "testing"
-
- "github.com/go-git/go-git/v5/plumbing/filemode"
- "github.com/go-git/go-git/v5/plumbing/object"
- "github.com/stretchr/testify/assert"
-)
-
-func getTestEntries() Entries {
- return Entries{
- &TreeEntry{gogitTreeEntry: &object.TreeEntry{Name: "v1.0", Mode: filemode.Dir}},
- &TreeEntry{gogitTreeEntry: &object.TreeEntry{Name: "v2.0", Mode: filemode.Dir}},
- &TreeEntry{gogitTreeEntry: &object.TreeEntry{Name: "v2.1", Mode: filemode.Dir}},
- &TreeEntry{gogitTreeEntry: &object.TreeEntry{Name: "v2.12", Mode: filemode.Dir}},
- &TreeEntry{gogitTreeEntry: &object.TreeEntry{Name: "v2.2", Mode: filemode.Dir}},
- &TreeEntry{gogitTreeEntry: &object.TreeEntry{Name: "v12.0", Mode: filemode.Dir}},
- &TreeEntry{gogitTreeEntry: &object.TreeEntry{Name: "abc", Mode: filemode.Regular}},
- &TreeEntry{gogitTreeEntry: &object.TreeEntry{Name: "bcd", Mode: filemode.Regular}},
- }
-}
-
-func TestEntriesSort(t *testing.T) {
- entries := getTestEntries()
- entries.Sort()
- assert.Equal(t, "v1.0", entries[0].Name())
- assert.Equal(t, "v12.0", entries[1].Name())
- assert.Equal(t, "v2.0", entries[2].Name())
- assert.Equal(t, "v2.1", entries[3].Name())
- assert.Equal(t, "v2.12", entries[4].Name())
- assert.Equal(t, "v2.2", entries[5].Name())
- assert.Equal(t, "abc", entries[6].Name())
- assert.Equal(t, "bcd", entries[7].Name())
-}
-
-func TestEntriesCustomSort(t *testing.T) {
- entries := getTestEntries()
- entries.CustomSort(func(s1, s2 string) bool {
- return s1 > s2
- })
- assert.Equal(t, "v2.2", entries[0].Name())
- assert.Equal(t, "v2.12", entries[1].Name())
- assert.Equal(t, "v2.1", entries[2].Name())
- assert.Equal(t, "v2.0", entries[3].Name())
- assert.Equal(t, "v12.0", entries[4].Name())
- assert.Equal(t, "v1.0", entries[5].Name())
- assert.Equal(t, "bcd", entries[6].Name())
- assert.Equal(t, "abc", entries[7].Name())
-}
-
-func TestFollowLink(t *testing.T) {
- r, err := openRepositoryWithDefaultContext("tests/repos/repo1_bare")
- assert.NoError(t, err)
- defer r.Close()
-
- commit, err := r.GetCommit("37991dec2c8e592043f47155ce4808d4580f9123")
- assert.NoError(t, err)
-
- // get the symlink
- lnk, err := commit.Tree.GetTreeEntryByPath("foo/bar/link_to_hello")
- assert.NoError(t, err)
- assert.True(t, lnk.IsLink())
-
- // should be able to dereference to target
- target, err := lnk.FollowLink()
- assert.NoError(t, err)
- assert.Equal(t, "hello", target.Name())
- assert.False(t, target.IsLink())
- assert.Equal(t, "b14df6442ea5a1b382985a6549b85d435376c351", target.ID.String())
-
- // should error when called on normal file
- target, err = commit.Tree.GetTreeEntryByPath("file1.txt")
- assert.NoError(t, err)
- _, err = target.FollowLink()
- assert.EqualError(t, err, "file1.txt: not a symlink")
-
- // should error for broken links
- target, err = commit.Tree.GetTreeEntryByPath("foo/broken_link")
- assert.NoError(t, err)
- assert.True(t, target.IsLink())
- _, err = target.FollowLink()
- assert.EqualError(t, err, "broken_link: broken link")
-
- // should error for external links
- target, err = commit.Tree.GetTreeEntryByPath("foo/outside_repo")
- assert.NoError(t, err)
- assert.True(t, target.IsLink())
- _, err = target.FollowLink()
- assert.EqualError(t, err, "outside_repo: points outside of repo")
-
- // testing fix for short link bug
- target, err = commit.Tree.GetTreeEntryByPath("foo/link_short")
- assert.NoError(t, err)
- _, err = target.FollowLink()
- assert.EqualError(t, err, "link_short: broken link")
-}
diff --git a/modules/git/tree_gogit.go b/modules/git/tree_gogit.go
deleted file mode 100644
index 421b0ecb0f..0000000000
--- a/modules/git/tree_gogit.go
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2015 The Gogs Authors. All rights reserved.
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package git
-
-import (
- "io"
-
- "github.com/go-git/go-git/v5/plumbing"
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// Tree represents a flat directory listing.
-type Tree struct {
- ID ObjectID
- ResolvedID ObjectID
- repo *Repository
-
- gogitTree *object.Tree
-
- // parent tree
- ptree *Tree
-}
-
-func (t *Tree) loadTreeObject() error {
- gogitTree, err := t.repo.gogitRepo.TreeObject(plumbing.Hash(t.ID.RawValue()))
- if err != nil {
- return err
- }
-
- t.gogitTree = gogitTree
- return nil
-}
-
-// ListEntries returns all entries of current tree.
-func (t *Tree) ListEntries() (Entries, error) {
- if t.gogitTree == nil {
- err := t.loadTreeObject()
- if err != nil {
- return nil, err
- }
- }
-
- entries := make([]*TreeEntry, len(t.gogitTree.Entries))
- for i, entry := range t.gogitTree.Entries {
- entries[i] = &TreeEntry{
- ID: ParseGogitHash(entry.Hash),
- gogitTreeEntry: &t.gogitTree.Entries[i],
- ptree: t,
- }
- }
-
- return entries, nil
-}
-
-// ListEntriesRecursiveWithSize returns all entries of current tree recursively including all subtrees
-func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) {
- if t.gogitTree == nil {
- err := t.loadTreeObject()
- if err != nil {
- return nil, err
- }
- }
-
- var entries []*TreeEntry
- seen := map[plumbing.Hash]bool{}
- walker := object.NewTreeWalker(t.gogitTree, true, seen)
- for {
- fullName, entry, err := walker.Next()
- if err == io.EOF {
- break
- }
- if err != nil {
- return nil, err
- }
- if seen[entry.Hash] {
- continue
- }
-
- convertedEntry := &TreeEntry{
- ID: ParseGogitHash(entry.Hash),
- gogitTreeEntry: &entry,
- ptree: t,
- fullName: fullName,
- }
- entries = append(entries, convertedEntry)
- }
-
- return entries, nil
-}
-
-// ListEntriesRecursiveFast is the alias of ListEntriesRecursiveWithSize for the gogit version
-func (t *Tree) ListEntriesRecursiveFast() (Entries, error) {
- return t.ListEntriesRecursiveWithSize()
-}
diff --git a/modules/git/tree_nogogit.go b/modules/git/tree_nogogit.go
deleted file mode 100644
index e0a72de5b8..0000000000
--- a/modules/git/tree_nogogit.go
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !gogit
-
-package git
-
-import (
- "io"
- "strings"
-)
-
-// Tree represents a flat directory listing.
-type Tree struct {
- ID ObjectID
- ResolvedID ObjectID
- repo *Repository
-
- // parent tree
- ptree *Tree
-
- entries Entries
- entriesParsed bool
-
- entriesRecursive Entries
- entriesRecursiveParsed bool
-}
-
-// ListEntries returns all entries of current tree.
-func (t *Tree) ListEntries() (Entries, error) {
- if t.entriesParsed {
- return t.entries, nil
- }
-
- if t.repo != nil {
- wr, rd, cancel := t.repo.CatFileBatch(t.repo.Ctx)
- defer cancel()
-
- _, _ = wr.Write([]byte(t.ID.String() + "\n"))
- _, typ, sz, err := ReadBatchLine(rd)
- if err != nil {
- return nil, err
- }
- if typ == "commit" {
- treeID, err := ReadTreeID(rd, sz)
- if err != nil && err != io.EOF {
- return nil, err
- }
- _, _ = wr.Write([]byte(treeID + "\n"))
- _, typ, sz, err = ReadBatchLine(rd)
- if err != nil {
- return nil, err
- }
- }
- if typ == "tree" {
- t.entries, err = catBatchParseTreeEntries(t.ID.Type(), t, rd, sz)
- if err != nil {
- return nil, err
- }
- t.entriesParsed = true
- return t.entries, nil
- }
-
- // Not a tree just use ls-tree instead
- if err := DiscardFull(rd, sz+1); err != nil {
- return nil, err
- }
- }
-
- stdout, _, runErr := NewCommand(t.repo.Ctx, "ls-tree", "-l").AddDynamicArguments(t.ID.String()).RunStdBytes(&RunOpts{Dir: t.repo.Path})
- if runErr != nil {
- if strings.Contains(runErr.Error(), "fatal: Not a valid object name") || strings.Contains(runErr.Error(), "fatal: not a tree object") {
- return nil, ErrNotExist{
- ID: t.ID.String(),
- }
- }
- return nil, runErr
- }
-
- var err error
- t.entries, err = parseTreeEntries(stdout, t)
- if err == nil {
- t.entriesParsed = true
- }
-
- return t.entries, err
-}
-
-// listEntriesRecursive returns all entries of current tree recursively including all subtrees
-// extraArgs could be "-l" to get the size, which is slower
-func (t *Tree) listEntriesRecursive(extraArgs TrustedCmdArgs) (Entries, error) {
- if t.entriesRecursiveParsed {
- return t.entriesRecursive, nil
- }
-
- stdout, _, runErr := NewCommand(t.repo.Ctx, "ls-tree", "-t", "-r").
- AddArguments(extraArgs...).
- AddDynamicArguments(t.ID.String()).
- RunStdBytes(&RunOpts{Dir: t.repo.Path})
- if runErr != nil {
- return nil, runErr
- }
-
- var err error
- t.entriesRecursive, err = parseTreeEntries(stdout, t)
- if err == nil {
- t.entriesRecursiveParsed = true
- }
-
- return t.entriesRecursive, err
-}
-
-// ListEntriesRecursiveFast returns all entries of current tree recursively including all subtrees, no size
-func (t *Tree) ListEntriesRecursiveFast() (Entries, error) {
- return t.listEntriesRecursive(nil)
-}
-
-// ListEntriesRecursiveWithSize returns all entries of current tree recursively including all subtrees, with size
-func (t *Tree) ListEntriesRecursiveWithSize() (Entries, error) {
- return t.listEntriesRecursive(TrustedCmdArgs{"--long"})
-}
diff --git a/modules/git/tree_test.go b/modules/git/tree_test.go
index 6d2b5c84d5..7e439628f2 100644
--- a/modules/git/tree_test.go
+++ b/modules/git/tree_test.go
@@ -8,20 +8,36 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestSubTree_Issue29101(t *testing.T) {
repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo1_bare"))
- assert.NoError(t, err)
+ require.NoError(t, err)
defer repo.Close()
commit, err := repo.GetCommit("ce064814f4a0d337b333e646ece456cd39fab612")
- assert.NoError(t, err)
+ require.NoError(t, err)
// old code could produce a different error if called multiple times
for i := 0; i < 10; i++ {
_, err = commit.SubTree("file1.txt")
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, IsErrNotExist(err))
}
}
+
+func Test_GetTreePathLatestCommit(t *testing.T) {
+ repo, err := openRepositoryWithDefaultContext(filepath.Join(testReposDir, "repo6_blame"))
+ require.NoError(t, err)
+ defer repo.Close()
+
+ commitID, err := repo.GetBranchCommitID("master")
+ require.NoError(t, err)
+ assert.EqualValues(t, "544d8f7a3b15927cddf2299b4b562d6ebd71b6a7", commitID)
+
+ commit, err := repo.GetTreePathLatestCommit("master", "blame.txt")
+ require.NoError(t, err)
+ assert.NotNil(t, commit)
+ assert.EqualValues(t, "45fb6cbc12f970b04eacd5cd4165edd11c8d7376", commit.ID.String())
+}
diff --git a/modules/git/url/url_test.go b/modules/git/url/url_test.go
index da820ed889..e1e52c0ed5 100644
--- a/modules/git/url/url_test.go
+++ b/modules/git/url/url_test.go
@@ -8,6 +8,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestParseGitURLs(t *testing.T) {
@@ -158,7 +159,7 @@ func TestParseGitURLs(t *testing.T) {
for _, kase := range kases {
t.Run(kase.kase, func(t *testing.T) {
u, err := Parse(kase.kase)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, kase.expected.extraMark, u.extraMark)
assert.EqualValues(t, *kase.expected, *u)
})
diff --git a/modules/git/utils.go b/modules/git/utils.go
index 53211c6451..b84df47916 100644
--- a/modules/git/utils.go
+++ b/modules/git/utils.go
@@ -7,7 +7,6 @@ import (
"crypto/sha1"
"encoding/hex"
"fmt"
- "io"
"os"
"strconv"
"strings"
@@ -105,32 +104,6 @@ func ParseBool(value string) (result, valid bool) {
return intValue != 0, true
}
-// LimitedReaderCloser is a limited reader closer
-type LimitedReaderCloser struct {
- R io.Reader
- C io.Closer
- N int64
-}
-
-// Read implements io.Reader
-func (l *LimitedReaderCloser) Read(p []byte) (n int, err error) {
- if l.N <= 0 {
- _ = l.C.Close()
- return 0, io.EOF
- }
- if int64(len(p)) > l.N {
- p = p[0:l.N]
- }
- n, err = l.R.Read(p)
- l.N -= int64(n)
- return n, err
-}
-
-// Close implements io.Closer
-func (l *LimitedReaderCloser) Close() error {
- return l.C.Close()
-}
-
func HashFilePathForWebUI(s string) string {
h := sha1.New()
_, _ = h.Write([]byte(s))
diff --git a/modules/git/utils_test.go b/modules/git/utils_test.go
index a3c2b7f8eb..a8c3fe38f6 100644
--- a/modules/git/utils_test.go
+++ b/modules/git/utils_test.go
@@ -13,7 +13,7 @@ import (
// but not in production code.
func skipIfSHA256NotSupported(t *testing.T) {
- if isGogit || CheckGitVersionAtLeast("2.42") != nil {
+ if CheckGitVersionAtLeast("2.42") != nil {
t.Skip("skipping because installed Git version doesn't support SHA256")
}
}
diff --git a/modules/gitrepo/branch.go b/modules/gitrepo/branch.go
index e13a4c82e1..a46e2e6bb7 100644
--- a/modules/gitrepo/branch.go
+++ b/modules/gitrepo/branch.go
@@ -6,7 +6,7 @@ package gitrepo
import (
"context"
- "code.gitea.io/gitea/modules/git"
+ "forgejo.org/modules/git"
)
// GetBranchesByPath returns a branch by its path
diff --git a/modules/gitrepo/gitrepo.go b/modules/gitrepo/gitrepo.go
index d89f8f9c0c..a9c920d564 100644
--- a/modules/gitrepo/gitrepo.go
+++ b/modules/gitrepo/gitrepo.go
@@ -9,8 +9,8 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
)
type Repository interface {
diff --git a/modules/gitrepo/walk_nogogit.go b/modules/gitrepo/walk.go
similarity index 87%
rename from modules/gitrepo/walk_nogogit.go
rename to modules/gitrepo/walk.go
index ff9555996d..8349835ff8 100644
--- a/modules/gitrepo/walk_nogogit.go
+++ b/modules/gitrepo/walk.go
@@ -1,14 +1,12 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !gogit
-
package gitrepo
import (
"context"
- "code.gitea.io/gitea/modules/git"
+ "forgejo.org/modules/git"
)
// WalkReferences walks all the references from the repository
diff --git a/modules/gitrepo/walk_gogit.go b/modules/gitrepo/walk_gogit.go
deleted file mode 100644
index 6370faf08e..0000000000
--- a/modules/gitrepo/walk_gogit.go
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2024 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package gitrepo
-
-import (
- "context"
-
- "github.com/go-git/go-git/v5/plumbing"
-)
-
-// WalkReferences walks all the references from the repository
-// refname is empty, ObjectTag or ObjectBranch. All other values should be treated as equivalent to empty.
-func WalkReferences(ctx context.Context, repo Repository, walkfn func(sha1, refname string) error) (int, error) {
- gitRepo := repositoryFromContext(ctx, repo)
- if gitRepo == nil {
- var err error
- gitRepo, err = OpenRepository(ctx, repo)
- if err != nil {
- return 0, err
- }
- defer gitRepo.Close()
- }
-
- i := 0
- iter, err := gitRepo.GoGitRepo().References()
- if err != nil {
- return i, err
- }
- defer iter.Close()
-
- err = iter.ForEach(func(ref *plumbing.Reference) error {
- err := walkfn(ref.Hash().String(), string(ref.Name()))
- i++
- return err
- })
- return i, err
-}
diff --git a/modules/graceful/manager.go b/modules/graceful/manager.go
index 077eac64f3..db5738c94c 100644
--- a/modules/graceful/manager.go
+++ b/modules/graceful/manager.go
@@ -9,9 +9,9 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
)
type state uint8
diff --git a/modules/graceful/manager_unix.go b/modules/graceful/manager_unix.go
index 931b0f1b62..37edf79075 100644
--- a/modules/graceful/manager_unix.go
+++ b/modules/graceful/manager_unix.go
@@ -1,8 +1,6 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !windows
-
package graceful
import (
@@ -15,10 +13,10 @@ import (
"syscall"
"time"
- "code.gitea.io/gitea/modules/graceful/releasereopen"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/graceful/releasereopen"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
)
func pidMsg() systemdNotifyMsg {
diff --git a/modules/graceful/manager_windows.go b/modules/graceful/manager_windows.go
deleted file mode 100644
index bee44381db..0000000000
--- a/modules/graceful/manager_windows.go
+++ /dev/null
@@ -1,190 +0,0 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
-
-//go:build windows
-
-package graceful
-
-import (
- "os"
- "runtime/pprof"
- "strconv"
- "time"
-
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
-
- "golang.org/x/sys/windows/svc"
- "golang.org/x/sys/windows/svc/debug"
-)
-
-// WindowsServiceName is the name of the Windows service
-var WindowsServiceName = "gitea"
-
-const (
- hammerCode = 128
- hammerCmd = svc.Cmd(hammerCode)
- acceptHammerCode = svc.Accepted(hammerCode)
-)
-
-func (g *Manager) start() {
- // Now label this and all goroutines created by this goroutine with the gracefulLifecycle manager
- pprof.SetGoroutineLabels(g.managerCtx)
- defer pprof.SetGoroutineLabels(g.ctx)
-
- if skip, _ := strconv.ParseBool(os.Getenv("SKIP_MINWINSVC")); skip {
- log.Trace("Skipping SVC check as SKIP_MINWINSVC is set")
- return
- }
-
- // Make SVC process
- run := svc.Run
-
- //lint:ignore SA1019 We use IsAnInteractiveSession because IsWindowsService has a different permissions profile
- isAnInteractiveSession, err := svc.IsAnInteractiveSession() //nolint:staticcheck
- if err != nil {
- log.Error("Unable to ascertain if running as an Windows Service: %v", err)
- return
- }
- if isAnInteractiveSession {
- log.Trace("Not running a service ... using the debug SVC manager")
- run = debug.Run
- }
- go func() {
- _ = run(WindowsServiceName, g)
- }()
-}
-
-// Execute makes Manager implement svc.Handler
-func (g *Manager) Execute(args []string, changes <-chan svc.ChangeRequest, status chan<- svc.Status) (svcSpecificEC bool, exitCode uint32) {
- if setting.StartupTimeout > 0 {
- status <- svc.Status{State: svc.StartPending, WaitHint: uint32(setting.StartupTimeout / time.Millisecond)}
- } else {
- status <- svc.Status{State: svc.StartPending}
- }
-
- log.Trace("Awaiting server start-up")
- // Now need to wait for everything to start...
- if !g.awaitServer(setting.StartupTimeout) {
- log.Trace("... start-up failed ... Stopped")
- return false, 1
- }
-
- log.Trace("Sending Running state to SVC")
-
- // We need to implement some way of svc.AcceptParamChange/svc.ParamChange
- status <- svc.Status{
- State: svc.Running,
- Accepts: svc.AcceptStop | svc.AcceptShutdown | acceptHammerCode,
- }
-
- log.Trace("Started")
-
- waitTime := 30 * time.Second
-
-loop:
- for {
- select {
- case <-g.ctx.Done():
- log.Trace("Shutting down")
- g.DoGracefulShutdown()
- waitTime += setting.GracefulHammerTime
- break loop
- case <-g.shutdownRequested:
- log.Trace("Shutting down")
- waitTime += setting.GracefulHammerTime
- break loop
- case change := <-changes:
- switch change.Cmd {
- case svc.Interrogate:
- log.Trace("SVC sent interrogate")
- status <- change.CurrentStatus
- case svc.Stop, svc.Shutdown:
- log.Trace("SVC requested shutdown - shutting down")
- g.DoGracefulShutdown()
- waitTime += setting.GracefulHammerTime
- break loop
- case hammerCode:
- log.Trace("SVC requested hammer - shutting down and hammering immediately")
- g.DoGracefulShutdown()
- g.DoImmediateHammer()
- break loop
- default:
- log.Debug("Unexpected control request: %v", change.Cmd)
- }
- }
- }
-
- log.Trace("Sending StopPending state to SVC")
- status <- svc.Status{
- State: svc.StopPending,
- WaitHint: uint32(waitTime / time.Millisecond),
- }
-
-hammerLoop:
- for {
- select {
- case change := <-changes:
- switch change.Cmd {
- case svc.Interrogate:
- log.Trace("SVC sent interrogate")
- status <- change.CurrentStatus
- case svc.Stop, svc.Shutdown, hammerCmd:
- log.Trace("SVC requested hammer - hammering immediately")
- g.DoImmediateHammer()
- break hammerLoop
- default:
- log.Debug("Unexpected control request: %v", change.Cmd)
- }
- case <-g.hammerCtx.Done():
- break hammerLoop
- }
- }
-
- log.Trace("Stopped")
- return false, 0
-}
-
-func (g *Manager) awaitServer(limit time.Duration) bool {
- c := make(chan struct{})
- go func() {
- g.createServerCond.L.Lock()
- for {
- if g.createdServer >= numberOfServersToCreate {
- g.createServerCond.L.Unlock()
- close(c)
- return
- }
- select {
- case <-g.IsShutdown():
- g.createServerCond.L.Unlock()
- return
- default:
- }
- g.createServerCond.Wait()
- }
- }()
-
- var tc <-chan time.Time
- if limit > 0 {
- tc = time.After(limit)
- }
- select {
- case <-c:
- return true // completed normally
- case <-tc:
- return false // timed out
- case <-g.IsShutdown():
- g.createServerCond.Signal()
- return false
- }
-}
-
-func (g *Manager) notify(msg systemdNotifyMsg) {
- // Windows doesn't use systemd to notify
-}
-
-func KillParent() {
- // Windows doesn't need to "kill parent" because there is no graceful restart
-}
diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go
index 796e00507c..dc38b02d82 100644
--- a/modules/graceful/net_unix.go
+++ b/modules/graceful/net_unix.go
@@ -3,22 +3,21 @@
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
-//go:build !windows
-
package graceful
import (
"fmt"
"net"
"os"
+ "path/filepath"
"strconv"
"strings"
"sync"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
const (
@@ -237,9 +236,11 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener,
return nil, err
}
- fileMode := os.FileMode(setting.UnixSocketPermission)
- if err = os.Chmod(address.Name, fileMode); err != nil {
- return nil, fmt.Errorf("Failed to set permission of unix socket to %s: %w", fileMode.String(), err)
+ if filepath.IsAbs(address.Name) {
+ fileMode := os.FileMode(setting.UnixSocketPermission)
+ if err = os.Chmod(address.Name, fileMode); err != nil {
+ return nil, fmt.Errorf("Failed to set permission of unix socket to %s: %w", fileMode.String(), err)
+ }
}
activeListeners = append(activeListeners, l)
diff --git a/modules/graceful/net_unix_linux_test.go b/modules/graceful/net_unix_linux_test.go
new file mode 100644
index 0000000000..144e5a4881
--- /dev/null
+++ b/modules/graceful/net_unix_linux_test.go
@@ -0,0 +1,15 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package graceful
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestAbstractUnixSocket(t *testing.T) {
+ _, err := DefaultGetListener("unix", "@abc")
+ require.NoError(t, err)
+}
diff --git a/modules/graceful/net_windows.go b/modules/graceful/net_windows.go
deleted file mode 100644
index 9667bd4d13..0000000000
--- a/modules/graceful/net_windows.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
-
-//go:build windows
-
-package graceful
-
-import "net"
-
-// DefaultGetListener obtains a listener for the local network address.
-// On windows this is basically just a shim around net.Listen.
-func DefaultGetListener(network, address string) (net.Listener, error) {
- // Add a deferral to say that we've tried to grab a listener
- defer GetManager().InformCleanup()
-
- return net.Listen(network, address)
-}
diff --git a/modules/graceful/releasereopen/releasereopen_test.go b/modules/graceful/releasereopen/releasereopen_test.go
index 0e8b48257d..6ab9f955f6 100644
--- a/modules/graceful/releasereopen/releasereopen_test.go
+++ b/modules/graceful/releasereopen/releasereopen_test.go
@@ -7,6 +7,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
type testReleaseReopener struct {
@@ -29,14 +30,14 @@ func TestManager(t *testing.T) {
c2 := m.Register(t2)
_ = m.Register(t3)
- assert.NoError(t, m.ReleaseReopen())
+ require.NoError(t, m.ReleaseReopen())
assert.EqualValues(t, 1, t1.count)
assert.EqualValues(t, 1, t2.count)
assert.EqualValues(t, 1, t3.count)
c2()
- assert.NoError(t, m.ReleaseReopen())
+ require.NoError(t, m.ReleaseReopen())
assert.EqualValues(t, 2, t1.count)
assert.EqualValues(t, 1, t2.count)
assert.EqualValues(t, 2, t3.count)
diff --git a/modules/graceful/restart_unix.go b/modules/graceful/restart_unix.go
index 98d5c5cc20..a0f3147ec6 100644
--- a/modules/graceful/restart_unix.go
+++ b/modules/graceful/restart_unix.go
@@ -3,8 +3,6 @@
// This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
-//go:build !windows
-
package graceful
import (
diff --git a/modules/graceful/server.go b/modules/graceful/server.go
index 2525a83e77..121bbed364 100644
--- a/modules/graceful/server.go
+++ b/modules/graceful/server.go
@@ -15,9 +15,9 @@ import (
"syscall"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/proxyprotocol"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/proxyprotocol"
+ "forgejo.org/modules/setting"
)
// GetListener returns a net listener
diff --git a/modules/graceful/server_hooks.go b/modules/graceful/server_hooks.go
index 9b67589571..06be783361 100644
--- a/modules/graceful/server_hooks.go
+++ b/modules/graceful/server_hooks.go
@@ -7,7 +7,7 @@ import (
"os"
"runtime"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
)
// awaitShutdown waits for the shutdown signal from the Manager
diff --git a/modules/hcaptcha/hcaptcha.go b/modules/hcaptcha/hcaptcha.go
index b970d491c5..7f5df9af5a 100644
--- a/modules/hcaptcha/hcaptcha.go
+++ b/modules/hcaptcha/hcaptcha.go
@@ -10,8 +10,8 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
)
const verifyURL = "https://hcaptcha.com/siteverify"
diff --git a/modules/highlight/highlight.go b/modules/highlight/highlight.go
index 4ee47b7a13..ba3ba479d5 100644
--- a/modules/highlight/highlight.go
+++ b/modules/highlight/highlight.go
@@ -15,10 +15,10 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/modules/analyze"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/analyze"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"github.com/alecthomas/chroma/v2"
"github.com/alecthomas/chroma/v2/formatters/html"
@@ -96,7 +96,7 @@ func Code(fileName, language, code string) (output template.HTML, lexerName stri
}
if lexer == nil {
- lexer = lexers.Match(fileName)
+ lexer = lexers.Match(strings.ToLower(fileName))
if lexer == nil {
lexer = lexers.Fallback
}
@@ -134,6 +134,13 @@ func CodeFromLexer(lexer chroma.Lexer, code string) template.HTML {
return template.HTML(strings.TrimSuffix(htmlbuf.String(), "\n"))
}
+// For the case where Enry recognizes the language, but doesn't use the naming
+// that Chroma expects.
+var normalizeEnryToChroma = map[string]string{
+ "F#": "FSharp",
+ "Gradle Kotlin DSL": "Kotlin",
+}
+
// File returns a slice of chroma syntax highlighted HTML lines of code and the matched lexer name
func File(fileName, language string, code []byte) ([]template.HTML, string, error) {
NewContext()
@@ -162,10 +169,13 @@ func File(fileName, language string, code []byte) ([]template.HTML, string, erro
if lexer == nil {
guessLanguage := analyze.GetCodeLanguage(fileName, code)
+ if normalizedGuessLanguage, ok := normalizeEnryToChroma[guessLanguage]; ok {
+ guessLanguage = normalizedGuessLanguage
+ }
lexer = lexers.Get(guessLanguage)
if lexer == nil {
- lexer = lexers.Match(fileName)
+ lexer = lexers.Match(strings.ToLower(fileName))
if lexer == nil {
lexer = lexers.Fallback
}
diff --git a/modules/highlight/highlight_test.go b/modules/highlight/highlight_test.go
index dd15b97847..6464999033 100644
--- a/modules/highlight/highlight_test.go
+++ b/modules/highlight/highlight_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func lines(s string) (out []template.HTML) {
@@ -108,12 +109,30 @@ c=2
),
lexerName: "Python",
},
+ {
+ name: "DOS.PAS",
+ code: "",
+ want: lines(""),
+ lexerName: "ObjectPascal",
+ },
+ {
+ name: "test.fs",
+ code: "module Crypt = let generateCryptTable: array =",
+ want: lines(`module Crypt = let generateCryptTable : array < uint32 > = `),
+ lexerName: "FSharp",
+ },
+ {
+ name: "test.gradle.kts",
+ code: "@file:Suppress(\"UnstableApiUsage\")",
+ want: lines("@file : Suppress ( " UnstableApiUsage " ) "), // codespell:ignore
+ lexerName: "Kotlin",
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
out, lexerName, err := File(tt.name, "", []byte(tt.code))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, tt.want, out)
assert.Equal(t, tt.lexerName, lexerName)
})
diff --git a/modules/hostmatcher/http.go b/modules/hostmatcher/http.go
index c743f6efb3..8828902034 100644
--- a/modules/hostmatcher/http.go
+++ b/modules/hostmatcher/http.go
@@ -13,11 +13,7 @@ import (
)
// NewDialContext returns a DialContext for Transport, the DialContext will do allow/block list check
-func NewDialContext(usage string, allowList, blockList *HostMatchList) func(ctx context.Context, network, addr string) (net.Conn, error) {
- return NewDialContextWithProxy(usage, allowList, blockList, nil)
-}
-
-func NewDialContextWithProxy(usage string, allowList, blockList *HostMatchList, proxy *url.URL) func(ctx context.Context, network, addr string) (net.Conn, error) {
+func NewDialContext(usage string, allowList, blockList *HostMatchList, proxy *url.URL) func(ctx context.Context, network, addr string) (net.Conn, error) {
// How Go HTTP Client works with redirection:
// transport.RoundTrip URL=http://domain.com, Host=domain.com
// transport.DialContext addrOrHost=domain.com:80
diff --git a/modules/httpcache/httpcache.go b/modules/httpcache/httpcache.go
index b4af371541..7978fc38a1 100644
--- a/modules/httpcache/httpcache.go
+++ b/modules/httpcache/httpcache.go
@@ -10,7 +10,7 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
// SetCacheControlInHeader sets suitable cache-control headers in the response
@@ -76,7 +76,8 @@ func HandleGenericETagTimeCache(req *http.Request, w http.ResponseWriter, etag s
w.Header().Set("Etag", etag)
}
if lastModified != nil && !lastModified.IsZero() {
- w.Header().Set("Last-Modified", lastModified.Format(http.TimeFormat))
+ // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat
+ w.Header().Set("Last-Modified", lastModified.UTC().Format(http.TimeFormat))
}
if len(etag) > 0 {
diff --git a/modules/httplib/serve.go b/modules/httplib/serve.go
index 6e147d76f5..cd35367bc9 100644
--- a/modules/httplib/serve.go
+++ b/modules/httplib/serve.go
@@ -16,13 +16,13 @@ import (
"strings"
"time"
- charsetModule "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/typesniffer"
- "code.gitea.io/gitea/modules/util"
+ charsetModule "forgejo.org/modules/charset"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/typesniffer"
+ "forgejo.org/modules/util"
"github.com/klauspost/compress/gzhttp"
)
@@ -79,6 +79,7 @@ func ServeSetHeaders(w http.ResponseWriter, opts *ServeHeaderOptions) {
httpcache.SetCacheControlInHeader(header, duration)
if !opts.LastModified.IsZero() {
+ // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat
header.Set("Last-Modified", opts.LastModified.UTC().Format(http.TimeFormat))
}
}
diff --git a/modules/httplib/serve_test.go b/modules/httplib/serve_test.go
index c2229dffe9..fe609e1672 100644
--- a/modules/httplib/serve_test.go
+++ b/modules/httplib/serve_test.go
@@ -13,6 +13,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestServeContentByReader(t *testing.T) {
@@ -61,7 +62,7 @@ func TestServeContentByReadSeeker(t *testing.T) {
data := "0123456789abcdef"
tmpFile := t.TempDir() + "/test"
err := os.WriteFile(tmpFile, []byte(data), 0o644)
- assert.NoError(t, err)
+ require.NoError(t, err)
test := func(t *testing.T, expectedStatusCode int, expectedContent string) {
_, rangeStr, _ := strings.Cut(t.Name(), "_range_")
@@ -71,9 +72,8 @@ func TestServeContentByReadSeeker(t *testing.T) {
}
seekReader, err := os.OpenFile(tmpFile, os.O_RDONLY, 0o644)
- if !assert.NoError(t, err) {
- return
- }
+ require.NoError(t, err)
+
defer seekReader.Close()
w := httptest.NewRecorder()
diff --git a/modules/httplib/url.go b/modules/httplib/url.go
index 14b95898f5..32a02e3277 100644
--- a/modules/httplib/url.go
+++ b/modules/httplib/url.go
@@ -7,7 +7,7 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
// IsRiskyRedirectURL returns true if the URL is considered risky for redirects
diff --git a/modules/httplib/url_test.go b/modules/httplib/url_test.go
index 2842edd514..cd2ceac267 100644
--- a/modules/httplib/url_test.go
+++ b/modules/httplib/url_test.go
@@ -6,8 +6,8 @@ package httplib
import (
"testing"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
)
diff --git a/modules/indexer/code/bleve/bleve.go b/modules/indexer/code/bleve/bleve.go
index 66724a3445..5428a9d313 100644
--- a/modules/indexer/code/bleve/bleve.go
+++ b/modules/indexer/code/bleve/bleve.go
@@ -12,17 +12,18 @@ import (
"strings"
"time"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/analyze"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/indexer/code/internal"
- indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
- inner_bleve "code.gitea.io/gitea/modules/indexer/internal/bleve"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/typesniffer"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/analyze"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ tokenizer_hierarchy "forgejo.org/modules/indexer/code/bleve/tokenizer/hierarchy"
+ "forgejo.org/modules/indexer/code/internal"
+ indexer_internal "forgejo.org/modules/indexer/internal"
+ inner_bleve "forgejo.org/modules/indexer/internal/bleve"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/typesniffer"
"github.com/blevesearch/bleve/v2"
analyzer_custom "github.com/blevesearch/bleve/v2/analysis/analyzer/custom"
@@ -39,10 +40,6 @@ import (
const (
unicodeNormalizeName = "unicodeNormalize"
maxBatchSize = 16
- // fuzzyDenominator determines the levenshtein distance per each character of a keyword
- fuzzyDenominator = 4
- // see https://github.com/blevesearch/bleve/issues/1563#issuecomment-786822311
- maxFuzziness = 2
)
func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error {
@@ -56,6 +53,7 @@ func addUnicodeNormalizeTokenFilter(m *mapping.IndexMappingImpl) error {
type RepoIndexerData struct {
RepoID int64
CommitID string
+ Filename string
Content string
Language string
UpdatedAt time.Time
@@ -69,7 +67,8 @@ func (d *RepoIndexerData) Type() string {
const (
repoIndexerAnalyzer = "repoIndexerAnalyzer"
repoIndexerDocType = "repoIndexerDocType"
- repoIndexerLatestVersion = 6
+ pathHierarchyAnalyzer = "pathHierarchyAnalyzer"
+ repoIndexerLatestVersion = 7
)
// generateBleveIndexMapping generates a bleve index mapping for the repo indexer
@@ -89,6 +88,11 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
docMapping.AddFieldMappingsAt("Language", termFieldMapping)
docMapping.AddFieldMappingsAt("CommitID", termFieldMapping)
+ pathFieldMapping := bleve.NewTextFieldMapping()
+ pathFieldMapping.IncludeInAll = false
+ pathFieldMapping.Analyzer = pathHierarchyAnalyzer
+ docMapping.AddFieldMappingsAt("Filename", pathFieldMapping)
+
timeFieldMapping := bleve.NewDateTimeFieldMapping()
timeFieldMapping.IncludeInAll = false
docMapping.AddFieldMappingsAt("UpdatedAt", timeFieldMapping)
@@ -103,6 +107,13 @@ func generateBleveIndexMapping() (mapping.IndexMapping, error) {
"token_filters": []string{unicodeNormalizeName, camelcase.Name, lowercase.Name},
}); err != nil {
return nil, err
+ } else if err := mapping.AddCustomAnalyzer(pathHierarchyAnalyzer, map[string]any{
+ "type": analyzer_custom.Name,
+ "char_filters": []string{},
+ "tokenizer": tokenizer_hierarchy.Name,
+ "token_filters": []string{unicodeNormalizeName},
+ }); err != nil {
+ return nil, err
}
mapping.DefaultAnalyzer = repoIndexerAnalyzer
mapping.AddDocumentMapping(repoIndexerDocType, docMapping)
@@ -178,6 +189,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
return batch.Index(id, &RepoIndexerData{
RepoID: repo.ID,
CommitID: commitSha,
+ Filename: update.Filename,
Content: string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})),
Language: analyze.GetCodeLanguage(update.Filename, fileContents),
UpdatedAt: time.Now().UTC(),
@@ -193,21 +205,23 @@ func (b *Indexer) addDelete(filename string, repo *repo_model.Repository, batch
func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha string, changes *internal.RepoChanges) error {
batch := inner_bleve.NewFlushingBatch(b.inner.Indexer, maxBatchSize)
if len(changes.Updates) > 0 {
- // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
- if err := git.EnsureValidGitRepository(ctx, repo.RepoPath()); err != nil {
- log.Error("Unable to open git repo: %s for %-v: %v", repo.RepoPath(), repo, err)
+ r, err := gitrepo.OpenRepository(ctx, repo)
+ if err != nil {
return err
}
-
- batchWriter, batchReader, cancel := git.CatFileBatch(ctx, repo.RepoPath())
- defer cancel()
+ defer r.Close()
+ gitBatch, err := r.NewBatch(ctx)
+ if err != nil {
+ return err
+ }
+ defer gitBatch.Close()
for _, update := range changes.Updates {
- if err := b.addUpdate(ctx, batchWriter, batchReader, sha, update, repo, batch); err != nil {
+ if err := b.addUpdate(ctx, gitBatch.Writer, gitBatch.Reader, sha, update, repo, batch); err != nil {
return err
}
}
- cancel()
+ gitBatch.Close()
}
for _, filename := range changes.RemovedFilenames {
if err := b.addDelete(filename, repo, batch); err != nil {
@@ -242,12 +256,14 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
keywordQuery query.Query
)
- phraseQuery := bleve.NewMatchPhraseQuery(opts.Keyword)
- phraseQuery.FieldVal = "Content"
- phraseQuery.Analyzer = repoIndexerAnalyzer
- keywordQuery = phraseQuery
- if opts.IsKeywordFuzzy {
- phraseQuery.Fuzziness = min(maxFuzziness, len(opts.Keyword)/fuzzyDenominator)
+ if opts.Mode == internal.CodeSearchModeUnion {
+ query := bleve.NewDisjunctionQuery()
+ for _, field := range strings.Fields(opts.Keyword) {
+ query.AddQuery(inner_bleve.MatchPhraseQuery(field, "Content", repoIndexerAnalyzer, false))
+ }
+ keywordQuery = query
+ } else {
+ keywordQuery = inner_bleve.MatchPhraseQuery(opts.Keyword, "Content", repoIndexerAnalyzer, false)
}
if len(opts.RepoIDs) > 0 {
@@ -264,28 +280,38 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
indexerQuery = keywordQuery
}
+ opts.Filename = strings.Trim(opts.Filename, "/")
+ if len(opts.Filename) > 0 {
+ // we use a keyword analyzer for the query than path hierarchy analyzer
+ // to match only the exact path
+ // eg, a query for modules/indexer/code
+ // should not provide results for modules/ nor modules/indexer
+ indexerQuery = bleve.NewConjunctionQuery(
+ indexerQuery,
+ inner_bleve.MatchQuery(opts.Filename, "Filename", analyzer_keyword.Name, 0),
+ )
+ }
+
// Save for reuse without language filter
facetQuery := indexerQuery
if len(opts.Language) > 0 {
- languageQuery := bleve.NewMatchQuery(opts.Language)
- languageQuery.FieldVal = "Language"
- languageQuery.Analyzer = analyzer_keyword.Name
-
indexerQuery = bleve.NewConjunctionQuery(
indexerQuery,
- languageQuery,
+ inner_bleve.MatchQuery(opts.Language, "Language", analyzer_keyword.Name, 0),
)
}
from, pageSize := opts.GetSkipTake()
searchRequest := bleve.NewSearchRequestOptions(indexerQuery, pageSize, from, false)
- searchRequest.Fields = []string{"Content", "RepoID", "Language", "CommitID", "UpdatedAt"}
+ searchRequest.Fields = []string{"Content", "RepoID", "Filename", "Language", "CommitID", "UpdatedAt"}
searchRequest.IncludeLocations = true
if len(opts.Language) == 0 {
searchRequest.AddFacet("languages", bleve.NewFacetRequest("Language", 10))
}
+ searchRequest.SortBy([]string{"-_score", "UpdatedAt"})
+
result, err := b.inner.Indexer.SearchInContext(ctx, searchRequest)
if err != nil {
return 0, nil, nil, err
@@ -297,13 +323,16 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
for i, hit := range result.Hits {
startIndex, endIndex := -1, -1
for _, locations := range hit.Locations["Content"] {
+ if startIndex != -1 && endIndex != -1 {
+ break
+ }
location := locations[0]
locationStart := int(location.Start)
locationEnd := int(location.End)
if startIndex < 0 || locationStart < startIndex {
startIndex = locationStart
}
- if endIndex < 0 || locationEnd > endIndex {
+ if endIndex < 0 && locationEnd > endIndex {
endIndex = locationEnd
}
}
@@ -316,7 +345,7 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
RepoID: int64(hit.Fields["RepoID"].(float64)),
StartIndex: startIndex,
EndIndex: endIndex,
- Filename: internal.FilenameOfIndexerID(hit.ID),
+ Filename: hit.Fields["Filename"].(string),
Content: hit.Fields["Content"].(string),
CommitID: hit.Fields["CommitID"].(string),
UpdatedUnix: updatedUnix,
@@ -329,7 +358,7 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
if len(opts.Language) > 0 {
// Use separate query to go get all language counts
facetRequest := bleve.NewSearchRequestOptions(facetQuery, 1, 0, false)
- facetRequest.Fields = []string{"Content", "RepoID", "Language", "CommitID", "UpdatedAt"}
+ facetRequest.Fields = []string{"Content", "RepoID", "Filename", "Language", "CommitID", "UpdatedAt"}
facetRequest.IncludeLocations = true
facetRequest.AddFacet("languages", bleve.NewFacetRequest("Language", 10))
diff --git a/modules/indexer/code/bleve/tokenizer/hierarchy/hierarchy.go b/modules/indexer/code/bleve/tokenizer/hierarchy/hierarchy.go
new file mode 100644
index 0000000000..c44aa78c46
--- /dev/null
+++ b/modules/indexer/code/bleve/tokenizer/hierarchy/hierarchy.go
@@ -0,0 +1,71 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package hierarchy
+
+import (
+ "bytes"
+
+ "github.com/blevesearch/bleve/v2/analysis"
+ "github.com/blevesearch/bleve/v2/registry"
+)
+
+const Name = "path_hierarchy"
+
+type PathHierarchyTokenizer struct{}
+
+// Similar to elastic's path_hierarchy tokenizer
+// This tokenizes a given path into all the possible hierarchies
+// For example,
+// modules/indexer/code/search.go =>
+//
+// modules/
+// modules/indexer
+// modules/indexer/code
+// modules/indexer/code/search.go
+func (t *PathHierarchyTokenizer) Tokenize(input []byte) analysis.TokenStream {
+ // trim any extra slashes
+ input = bytes.Trim(input, "/")
+
+ // zero allocations until the nested directories exceed a depth of 8 (which is unlikely)
+ rv := make(analysis.TokenStream, 0, 8)
+ count, off := 1, 0
+
+ // iterate till all directory separators
+ for i := bytes.IndexRune(input[off:], '/'); i != -1; i = bytes.IndexRune(input[off:], '/') {
+ // the index is relative to input[offset...]
+ // add this index to the accumulated offset to get the index of the current separator in input[0...]
+ off += i
+ rv = append(rv, &analysis.Token{
+ Term: input[:off], // take the slice, input[0...index of separator]
+ Start: 0,
+ End: off,
+ Position: count,
+ Type: analysis.AlphaNumeric,
+ })
+ // increment the offset after considering the separator
+ off++
+ count++
+ }
+
+ // the entire file path should always be the last token
+ rv = append(rv, &analysis.Token{
+ Term: input,
+ Start: 0,
+ End: len(input),
+ Position: count,
+ Type: analysis.AlphaNumeric,
+ })
+
+ return rv
+}
+
+func TokenizerConstructor(config map[string]any, cache *registry.Cache) (analysis.Tokenizer, error) {
+ return &PathHierarchyTokenizer{}, nil
+}
+
+func init() {
+ if err := registry.RegisterTokenizer(Name, TokenizerConstructor); err != nil {
+ panic(err)
+ }
+}
diff --git a/modules/indexer/code/bleve/tokenizer/hierarchy/hierarchy_test.go b/modules/indexer/code/bleve/tokenizer/hierarchy/hierarchy_test.go
new file mode 100644
index 0000000000..0ca3c2941d
--- /dev/null
+++ b/modules/indexer/code/bleve/tokenizer/hierarchy/hierarchy_test.go
@@ -0,0 +1,59 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package hierarchy
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestIndexerBleveHierarchyTokenizer(t *testing.T) {
+ tokenizer := &PathHierarchyTokenizer{}
+ keywords := []struct {
+ Term string
+ Results []string
+ }{
+ {
+ Term: "modules/indexer/code/search.go",
+ Results: []string{
+ "modules",
+ "modules/indexer",
+ "modules/indexer/code",
+ "modules/indexer/code/search.go",
+ },
+ },
+ {
+ Term: "/tmp/forgejo/",
+ Results: []string{
+ "tmp",
+ "tmp/forgejo",
+ },
+ },
+ {
+ Term: "a/b/c/d/e/f/g/h/i/j",
+ Results: []string{
+ "a",
+ "a/b",
+ "a/b/c",
+ "a/b/c/d",
+ "a/b/c/d/e",
+ "a/b/c/d/e/f",
+ "a/b/c/d/e/f/g",
+ "a/b/c/d/e/f/g/h",
+ "a/b/c/d/e/f/g/h/i",
+ "a/b/c/d/e/f/g/h/i/j",
+ },
+ },
+ }
+
+ for _, kw := range keywords {
+ tokens := tokenizer.Tokenize([]byte(kw.Term))
+ assert.Len(t, tokens, len(kw.Results))
+ for i, token := range tokens {
+ assert.Equal(t, i+1, token.Position)
+ assert.Equal(t, kw.Results[i], string(token.Term))
+ }
+ }
+}
diff --git a/modules/indexer/code/elasticsearch/elasticsearch.go b/modules/indexer/code/elasticsearch/elasticsearch.go
index e4622fd66e..3903d77fe0 100644
--- a/modules/indexer/code/elasticsearch/elasticsearch.go
+++ b/modules/indexer/code/elasticsearch/elasticsearch.go
@@ -11,29 +11,30 @@ import (
"strconv"
"strings"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/analyze"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/indexer/code/internal"
- indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
- inner_elasticsearch "code.gitea.io/gitea/modules/indexer/internal/elasticsearch"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/typesniffer"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/analyze"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/indexer/code/internal"
+ indexer_internal "forgejo.org/modules/indexer/internal"
+ inner_elasticsearch "forgejo.org/modules/indexer/internal/elasticsearch"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/typesniffer"
"github.com/go-enry/go-enry/v2"
"github.com/olivere/elastic/v7"
)
const (
- esRepoIndexerLatestVersion = 1
+ esRepoIndexerLatestVersion = 2
// multi-match-types, currently only 2 types are used
// Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types
- esMultiMatchTypeBestFields = "best_fields"
- esMultiMatchTypePhrasePrefix = "phrase_prefix"
+ esMultiMatchTypeBestFields = "best_fields"
+ esMultiMatchTypePhrase = "phrase"
)
var _ internal.Indexer = &Indexer{}
@@ -56,6 +57,21 @@ func NewIndexer(url, indexerName string) *Indexer {
const (
defaultMapping = `{
+ "settings": {
+ "analysis": {
+ "analyzer": {
+ "custom_path_tree": {
+ "tokenizer": "custom_hierarchy"
+ }
+ },
+ "tokenizer": {
+ "custom_hierarchy": {
+ "type": "path_hierarchy",
+ "delimiter": "/"
+ }
+ }
+ }
+ },
"mappings": {
"properties": {
"repo_id": {
@@ -71,6 +87,15 @@ const (
"type": "keyword",
"index": true
},
+ "filename": {
+ "type": "text",
+ "fields": {
+ "tree": {
+ "type": "text",
+ "analyzer": "custom_path_tree"
+ }
+ }
+ },
"language": {
"type": "keyword",
"index": true
@@ -137,6 +162,7 @@ func (b *Indexer) addUpdate(ctx context.Context, batchWriter git.WriteCloserErro
"repo_id": repo.ID,
"content": string(charset.ToUTF8DropErrors(fileContents, charset.ConvertOpts{})),
"commit_id": sha,
+ "filename": update.Filename,
"language": analyze.GetCodeLanguage(update.Filename, fileContents),
"updated_at": timeutil.TimeStampNow(),
}),
@@ -154,17 +180,19 @@ func (b *Indexer) addDelete(filename string, repo *repo_model.Repository) elasti
func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha string, changes *internal.RepoChanges) error {
reqs := make([]elastic.BulkableRequest, 0)
if len(changes.Updates) > 0 {
- // Now because of some insanity with git cat-file not immediately failing if not run in a valid git directory we need to run git rev-parse first!
- if err := git.EnsureValidGitRepository(ctx, repo.RepoPath()); err != nil {
- log.Error("Unable to open git repo: %s for %-v: %v", repo.RepoPath(), repo, err)
+ r, err := gitrepo.OpenRepository(ctx, repo)
+ if err != nil {
return err
}
-
- batchWriter, batchReader, cancel := git.CatFileBatch(ctx, repo.RepoPath())
- defer cancel()
+ defer r.Close()
+ batch, err := r.NewBatch(ctx)
+ if err != nil {
+ return err
+ }
+ defer batch.Close()
for _, update := range changes.Updates {
- updateReqs, err := b.addUpdate(ctx, batchWriter, batchReader, sha, update, repo)
+ updateReqs, err := b.addUpdate(ctx, batch.Writer, batch.Reader, sha, update, repo)
if err != nil {
return err
}
@@ -172,7 +200,7 @@ func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha st
reqs = append(reqs, updateReqs...)
}
}
- cancel()
+ batch.Close()
}
for _, filename := range changes.RemovedFilenames {
@@ -195,8 +223,33 @@ func (b *Indexer) Index(ctx context.Context, repo *repo_model.Repository, sha st
return nil
}
-// Delete deletes indexes by ids
+// Delete entries by repoId
func (b *Indexer) Delete(ctx context.Context, repoID int64) error {
+ if err := b.doDelete(ctx, repoID); err != nil {
+ // Maybe there is a conflict during the delete operation, so we should retry after a refresh
+ log.Warn("Deletion of entries of repo %v within index %v was erroneous. Trying to refresh index before trying again", repoID, b.inner.VersionedIndexName(), err)
+ if err := b.refreshIndex(ctx); err != nil {
+ return err
+ }
+ if err := b.doDelete(ctx, repoID); err != nil {
+ log.Error("Could not delete entries of repo %v within index %v", repoID, b.inner.VersionedIndexName())
+ return err
+ }
+ }
+ return nil
+}
+
+func (b *Indexer) refreshIndex(ctx context.Context) error {
+ if _, err := b.inner.Client.Refresh(b.inner.VersionedIndexName()).Do(ctx); err != nil {
+ log.Error("Error while trying to refresh index %v", b.inner.VersionedIndexName(), err)
+ return err
+ }
+
+ return nil
+}
+
+// Delete entries by repoId
+func (b *Indexer) doDelete(ctx context.Context, repoID int64) error {
_, err := b.inner.Client.DeleteByQuery(b.inner.VersionedIndexName()).
Query(elastic.NewTermsQuery("repo_id", repoID)).
Do(ctx)
@@ -239,7 +292,6 @@ func convertResult(searchResult *elastic.SearchResult, kw string, pageSize int)
panic(fmt.Sprintf("2===%#v", hit.Highlight))
}
- repoID, fileName := internal.ParseIndexerID(hit.Id)
res := make(map[string]any)
if err := json.Unmarshal(hit.Source, &res); err != nil {
return 0, nil, nil, err
@@ -248,8 +300,8 @@ func convertResult(searchResult *elastic.SearchResult, kw string, pageSize int)
language := res["language"].(string)
hits = append(hits, &internal.SearchResult{
- RepoID: repoID,
- Filename: fileName,
+ RepoID: int64(res["repo_id"].(float64)),
+ Filename: res["filename"].(string),
CommitID: res["commit_id"].(string),
Content: res["content"].(string),
UpdatedUnix: timeutil.TimeStamp(res["updated_at"].(float64)),
@@ -282,8 +334,8 @@ func extractAggs(searchResult *elastic.SearchResult) []*internal.SearchResultLan
// Search searches for codes and language stats by given conditions.
func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int64, []*internal.SearchResult, []*internal.SearchResultLanguages, error) {
- searchType := esMultiMatchTypePhrasePrefix
- if opts.IsKeywordFuzzy {
+ searchType := esMultiMatchTypePhrase
+ if opts.Mode == internal.CodeSearchModeUnion {
searchType = esMultiMatchTypeBestFields
}
@@ -298,6 +350,9 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
repoQuery := elastic.NewTermsQuery("repo_id", repoStrs...)
query = query.Must(repoQuery)
}
+ if len(opts.Filename) > 0 {
+ query = query.Filter(elastic.NewTermsQuery("filename.tree", opts.Filename))
+ }
var (
start, pageSize = opts.GetSkipTake()
@@ -316,7 +371,8 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
NumOfFragments(0). // return all highting content on fragments
HighlighterType("fvh"),
).
- Sort("repo_id", true).
+ Sort("_score", false).
+ Sort("updated_at", true).
From(start).Size(pageSize).
Do(ctx)
if err != nil {
@@ -347,7 +403,8 @@ func (b *Indexer) Search(ctx context.Context, opts *internal.SearchOptions) (int
NumOfFragments(0). // return all highting content on fragments
HighlighterType("fvh"),
).
- Sort("repo_id", true).
+ Sort("_score", false).
+ Sort("updated_at", true).
From(start).Size(pageSize).
Do(ctx)
if err != nil {
diff --git a/modules/indexer/code/git.go b/modules/indexer/code/git.go
index c5dfe43836..14a43cf3be 100644
--- a/modules/indexer/code/git.go
+++ b/modules/indexer/code/git.go
@@ -8,11 +8,11 @@ import (
"strconv"
"strings"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/indexer/code/internal"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/indexer/code/internal"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
func getDefaultBranchSha(ctx context.Context, repo *repo_model.Repository) (string, error) {
@@ -113,7 +113,24 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio
var changes internal.RepoChanges
var err error
updatedFilenames := make([]string, 0, 10)
- for _, line := range strings.Split(stdout, "\n") {
+
+ updateChanges := func() error {
+ cmd := git.NewCommand(ctx, "ls-tree", "--full-tree", "-l").AddDynamicArguments(revision).
+ AddDashesAndList(updatedFilenames...)
+ lsTreeStdout, _, err := cmd.RunStdBytes(&git.RunOpts{Dir: repo.RepoPath()})
+ if err != nil {
+ return err
+ }
+
+ updates, err1 := parseGitLsTreeOutput(lsTreeStdout)
+ if err1 != nil {
+ return err1
+ }
+ changes.Updates = append(changes.Updates, updates...)
+ return nil
+ }
+ lines := strings.Split(stdout, "\n")
+ for _, line := range lines {
line = strings.TrimSpace(line)
if len(line) == 0 {
continue
@@ -161,15 +178,22 @@ func nonGenesisChanges(ctx context.Context, repo *repo_model.Repository, revisio
default:
log.Warn("Unrecognized status: %c (line=%s)", status, line)
}
+
+ // According to https://learn.microsoft.com/en-us/troubleshoot/windows-client/shell-experience/command-line-string-limitation#more-information
+ // the command line length should less than 8191 characters, assume filepath is 256, then 8191/256 = 31, so we use 30
+ if len(updatedFilenames) >= 30 {
+ if err := updateChanges(); err != nil {
+ return nil, err
+ }
+ updatedFilenames = updatedFilenames[0:0]
+ }
}
- cmd := git.NewCommand(ctx, "ls-tree", "--full-tree", "-l").AddDynamicArguments(revision).
- AddDashesAndList(updatedFilenames...)
- lsTreeStdout, _, err := cmd.RunStdBytes(&git.RunOpts{Dir: repo.RepoPath()})
- if err != nil {
- return nil, err
+ if len(updatedFilenames) > 0 {
+ if err := updateChanges(); err != nil {
+ return nil, err
+ }
}
- changes.Updates, err = parseGitLsTreeOutput(lsTreeStdout)
return &changes, err
}
diff --git a/modules/indexer/code/indexer.go b/modules/indexer/code/indexer.go
index 0a8ce27907..c32b637ab4 100644
--- a/modules/indexer/code/indexer.go
+++ b/modules/indexer/code/indexer.go
@@ -11,16 +11,16 @@ import (
"sync/atomic"
"time"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/indexer/code/bleve"
- "code.gitea.io/gitea/modules/indexer/code/elasticsearch"
- "code.gitea.io/gitea/modules/indexer/code/internal"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/queue"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/indexer/code/bleve"
+ "forgejo.org/modules/indexer/code/elasticsearch"
+ "forgejo.org/modules/indexer/code/internal"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/setting"
)
var (
diff --git a/modules/indexer/code/indexer_test.go b/modules/indexer/code/indexer_test.go
index 2d013e08ed..29b2936fa1 100644
--- a/modules/indexer/code/indexer_test.go
+++ b/modules/indexer/code/indexer_test.go
@@ -4,22 +4,23 @@
package code
import (
- "context"
"os"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/indexer/code/bleve"
- "code.gitea.io/gitea/modules/indexer/code/elasticsearch"
- "code.gitea.io/gitea/modules/indexer/code/internal"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/indexer/code/bleve"
+ "forgejo.org/modules/indexer/code/elasticsearch"
+ "forgejo.org/modules/indexer/code/internal"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
@@ -30,12 +31,13 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
t.Run(name, func(t *testing.T) {
var repoID int64 = 1
err := index(git.DefaultContext, indexer, repoID)
- assert.NoError(t, err)
+ require.NoError(t, err)
keywords := []struct {
- RepoIDs []int64
- Keyword string
- IDs []int64
- Langs int
+ RepoIDs []int64
+ Keyword string
+ IDs []int64
+ Langs int
+ Filename string
}{
{
RepoIDs: nil,
@@ -49,6 +51,20 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
IDs: []int64{},
Langs: 0,
},
+ {
+ RepoIDs: nil,
+ Keyword: "Description",
+ IDs: []int64{},
+ Langs: 0,
+ Filename: "NOT-README.md",
+ },
+ {
+ RepoIDs: nil,
+ Keyword: "Description",
+ IDs: []int64{repoID},
+ Langs: 1,
+ Filename: "README.md",
+ },
{
RepoIDs: nil,
Keyword: "Description for",
@@ -77,16 +93,17 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
for _, kw := range keywords {
t.Run(kw.Keyword, func(t *testing.T) {
- total, res, langs, err := indexer.Search(context.TODO(), &internal.SearchOptions{
+ total, res, langs, err := indexer.Search(t.Context(), &internal.SearchOptions{
RepoIDs: kw.RepoIDs,
Keyword: kw.Keyword,
Paginator: &db.ListOptions{
Page: 1,
PageSize: 10,
},
- IsKeywordFuzzy: true,
+ Filename: kw.Filename,
+ Mode: SearchModeUnion,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, kw.IDs, int(total))
assert.Len(t, langs, kw.Langs)
@@ -99,7 +116,7 @@ func testIndexer(name string, t *testing.T, indexer internal.Indexer) {
})
}
- assert.NoError(t, indexer.Delete(context.Background(), repoID))
+ require.NoError(t, indexer.Delete(t.Context(), repoID))
})
}
@@ -109,7 +126,7 @@ func TestBleveIndexAndSearch(t *testing.T) {
dir := t.TempDir()
idx := bleve.NewIndexer(dir)
- _, err := idx.Init(context.Background())
+ _, err := idx.Init(t.Context())
if err != nil {
if idx != nil {
idx.Close()
@@ -118,7 +135,7 @@ func TestBleveIndexAndSearch(t *testing.T) {
}
defer idx.Close()
- testIndexer("beleve", t, idx)
+ testIndexer("bleve", t, idx)
}
func TestESIndexAndSearch(t *testing.T) {
@@ -131,7 +148,7 @@ func TestESIndexAndSearch(t *testing.T) {
}
indexer := elasticsearch.NewIndexer(u, "gitea_codes")
- if _, err := indexer.Init(context.Background()); err != nil {
+ if _, err := indexer.Init(t.Context()); err != nil {
if indexer != nil {
indexer.Close()
}
diff --git a/modules/indexer/code/internal/indexer.go b/modules/indexer/code/internal/indexer.go
index c259fcd26e..cc2c2aaf06 100644
--- a/modules/indexer/code/internal/indexer.go
+++ b/modules/indexer/code/internal/indexer.go
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/indexer/internal"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/indexer/internal"
)
// Indexer defines an interface to index and search code contents
@@ -20,12 +20,27 @@ type Indexer interface {
Search(ctx context.Context, opts *SearchOptions) (int64, []*SearchResult, []*SearchResultLanguages, error)
}
+type CodeSearchMode int
+
+const (
+ CodeSearchModeExact CodeSearchMode = iota
+ CodeSearchModeUnion
+)
+
+func (mode CodeSearchMode) String() string {
+ if mode == CodeSearchModeUnion {
+ return "union"
+ }
+ return "exact"
+}
+
type SearchOptions struct {
RepoIDs []int64
Keyword string
Language string
+ Filename string
- IsKeywordFuzzy bool
+ Mode CodeSearchMode
db.Paginator
}
diff --git a/modules/indexer/code/internal/model.go b/modules/indexer/code/internal/model.go
index f75263c83c..ad0a7934d9 100644
--- a/modules/indexer/code/internal/model.go
+++ b/modules/indexer/code/internal/model.go
@@ -3,7 +3,7 @@
package internal
-import "code.gitea.io/gitea/modules/timeutil"
+import "forgejo.org/modules/timeutil"
type FileUpdate struct {
Filename string
diff --git a/modules/indexer/code/internal/util.go b/modules/indexer/code/internal/util.go
index 689c4f4584..f5a4ec8e4e 100644
--- a/modules/indexer/code/internal/util.go
+++ b/modules/indexer/code/internal/util.go
@@ -3,30 +3,8 @@
package internal
-import (
- "strings"
-
- "code.gitea.io/gitea/modules/indexer/internal"
- "code.gitea.io/gitea/modules/log"
-)
+import "forgejo.org/modules/indexer/internal"
func FilenameIndexerID(repoID int64, filename string) string {
return internal.Base36(repoID) + "_" + filename
}
-
-func ParseIndexerID(indexerID string) (int64, string) {
- index := strings.IndexByte(indexerID, '_')
- if index == -1 {
- log.Error("Unexpected ID in repo indexer: %s", indexerID)
- }
- repoID, _ := internal.ParseBase36(indexerID[:index])
- return repoID, indexerID[index+1:]
-}
-
-func FilenameOfIndexerID(indexerID string) string {
- index := strings.IndexByte(indexerID, '_')
- if index == -1 {
- log.Error("Unexpected ID in repo indexer: %s", indexerID)
- }
- return indexerID[index+1:]
-}
diff --git a/modules/indexer/code/search.go b/modules/indexer/code/search.go
index 5f35e8073b..adf51a76d7 100644
--- a/modules/indexer/code/search.go
+++ b/modules/indexer/code/search.go
@@ -9,9 +9,10 @@ import (
"html/template"
"strings"
- "code.gitea.io/gitea/modules/highlight"
- "code.gitea.io/gitea/modules/indexer/code/internal"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/highlight"
+ "forgejo.org/modules/indexer/code/internal"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/services/gitdiff"
)
// Result a search result to display
@@ -34,6 +35,15 @@ type SearchResultLanguages = internal.SearchResultLanguages
type SearchOptions = internal.SearchOptions
+var CodeSearchOptions = [2]string{"exact", "union"}
+
+type SearchMode = internal.CodeSearchMode
+
+const (
+ SearchModeExact = internal.CodeSearchModeExact
+ SearchModeUnion = internal.CodeSearchModeUnion
+)
+
func indices(content string, selectionStartIndex, selectionEndIndex int) (int, int) {
startIndex := selectionStartIndex
numLinesBefore := 0
@@ -70,11 +80,85 @@ func writeStrings(buf *bytes.Buffer, strs ...string) error {
return nil
}
-func HighlightSearchResultCode(filename string, lineNums []int, code string) []ResultLine {
+const (
+ highlightTagStart = ""
+ highlightTagEnd = " "
+)
+
+func HighlightSearchResultCode(filename string, lineNums []int, highlightRanges [][3]int, code string) []ResultLine {
+ hcd := gitdiff.NewHighlightCodeDiff()
+ hcd.CollectUsedRunes(code)
+ startTag, endTag := hcd.NextPlaceholder(), hcd.NextPlaceholder()
+ hcd.PlaceholderTokenMap[startTag] = highlightTagStart
+ hcd.PlaceholderTokenMap[endTag] = highlightTagEnd
+
// we should highlight the whole code block first, otherwise it doesn't work well with multiple line highlighting
hl, _ := highlight.Code(filename, "", code)
- highlightedLines := strings.Split(string(hl), "\n")
+ conv := hcd.ConvertToPlaceholders(string(hl))
+ convLines := strings.Split(conv, "\n")
+ // each highlightRange is of the form [line number, start pos, end pos]
+ for _, highlightRange := range highlightRanges {
+ ln, start, end := highlightRange[0], highlightRange[1], highlightRange[2]
+ line := convLines[ln]
+ if line == "" || len(line) <= start || len(line) < end {
+ continue
+ }
+
+ sb := strings.Builder{}
+ count := -1
+ isOpen := false
+ for _, r := range line {
+ if token, ok := hcd.PlaceholderTokenMap[r];
+ // token was not found
+ !ok ||
+ // token was marked as used
+ token == "" ||
+ // the token is not an valid html tag emitted by chroma
+ !(len(token) > 6 && (token[0:5] == " 0 || options.AllPublic {
diff --git a/modules/indexer/issues/bleve/bleve_test.go b/modules/indexer/issues/bleve/bleve_test.go
index 908514a01a..ead57b572f 100644
--- a/modules/indexer/issues/bleve/bleve_test.go
+++ b/modules/indexer/issues/bleve/bleve_test.go
@@ -6,7 +6,7 @@ package bleve
import (
"testing"
- "code.gitea.io/gitea/modules/indexer/issues/internal/tests"
+ "forgejo.org/modules/indexer/issues/internal/tests"
)
func TestBleveIndexer(t *testing.T) {
diff --git a/modules/indexer/issues/db/db.go b/modules/indexer/issues/db/db.go
index 05ec548435..9dd026e74f 100644
--- a/modules/indexer/issues/db/db.go
+++ b/modules/indexer/issues/db/db.go
@@ -6,11 +6,11 @@ package db
import (
"context"
- "code.gitea.io/gitea/models/db"
- issue_model "code.gitea.io/gitea/models/issues"
- indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
- inner_db "code.gitea.io/gitea/modules/indexer/internal/db"
- "code.gitea.io/gitea/modules/indexer/issues/internal"
+ "forgejo.org/models/db"
+ issue_model "forgejo.org/models/issues"
+ indexer_internal "forgejo.org/modules/indexer/internal"
+ inner_db "forgejo.org/modules/indexer/internal/db"
+ "forgejo.org/modules/indexer/issues/internal"
"xorm.io/builder"
)
diff --git a/modules/indexer/issues/db/options.go b/modules/indexer/issues/db/options.go
index 875a4ca279..4411cc1c37 100644
--- a/modules/indexer/issues/db/options.go
+++ b/modules/indexer/issues/db/options.go
@@ -7,11 +7,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issue_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/indexer/issues/internal"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ issue_model "forgejo.org/models/issues"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/indexer/issues/internal"
+ "forgejo.org/modules/optional"
)
func ToDBOptions(ctx context.Context, options *internal.SearchOptions) (*issue_model.IssuesOptions, error) {
diff --git a/modules/indexer/issues/dboptions.go b/modules/indexer/issues/dboptions.go
index 50916024af..d67dc68bfc 100644
--- a/modules/indexer/issues/dboptions.go
+++ b/modules/indexer/issues/dboptions.go
@@ -4,9 +4,9 @@
package issues
import (
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/optional"
)
func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOptions {
@@ -44,6 +44,12 @@ func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOp
searchOpt.ProjectID = optional.Some[int64](0) // Those issues with no project(projectid==0)
}
+ if opts.AssigneeID > 0 {
+ searchOpt.AssigneeID = optional.Some(opts.AssigneeID)
+ } else if opts.AssigneeID == -1 { // FIXME: this is inconsistent from other places
+ searchOpt.AssigneeID = optional.Some[int64](0)
+ }
+
// See the comment of issues_model.SearchOptions for the reason why we need to convert
convertID := func(id int64) optional.Option[int64] {
if id > 0 {
@@ -57,7 +63,6 @@ func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOp
searchOpt.ProjectColumnID = convertID(opts.ProjectColumnID)
searchOpt.PosterID = convertID(opts.PosterID)
- searchOpt.AssigneeID = convertID(opts.AssigneeID)
searchOpt.MentionID = convertID(opts.MentionedID)
searchOpt.ReviewedID = convertID(opts.ReviewedID)
searchOpt.ReviewRequestedID = convertID(opts.ReviewRequestedID)
@@ -73,7 +78,9 @@ func ToSearchOptions(keyword string, opts *issues_model.IssuesOptions) *SearchOp
searchOpt.Paginator = opts.Paginator
switch opts.SortType {
- case "", "latest":
+ case "", "relevance":
+ searchOpt.SortBy = SortByScore
+ case "latest":
searchOpt.SortBy = SortByCreatedDesc
case "oldest":
searchOpt.SortBy = SortByCreatedAsc
diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go
index 42e709a5e8..1bf0145796 100644
--- a/modules/indexer/issues/elasticsearch/elasticsearch.go
+++ b/modules/indexer/issues/elasticsearch/elasticsearch.go
@@ -9,10 +9,10 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/graceful"
- indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
- inner_elasticsearch "code.gitea.io/gitea/modules/indexer/internal/elasticsearch"
- "code.gitea.io/gitea/modules/indexer/issues/internal"
+ "forgejo.org/modules/graceful"
+ indexer_internal "forgejo.org/modules/indexer/internal"
+ inner_elasticsearch "forgejo.org/modules/indexer/internal/elasticsearch"
+ "forgejo.org/modules/indexer/issues/internal"
"github.com/olivere/elastic/v7"
)
@@ -23,6 +23,10 @@ const (
// Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/query-dsl-multi-match-query.html#multi-match-types
esMultiMatchTypeBestFields = "best_fields"
esMultiMatchTypePhrasePrefix = "phrase_prefix"
+
+ // fuzziness options
+ // Reference: https://www.elastic.co/guide/en/elasticsearch/reference/7.0/common-options.html#fuzziness
+ esFuzzyAuto = "AUTO"
)
var _ internal.Indexer = &Indexer{}
@@ -145,12 +149,30 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
query := elastic.NewBoolQuery()
if options.Keyword != "" {
- searchType := esMultiMatchTypePhrasePrefix
- if options.IsFuzzyKeyword {
- searchType = esMultiMatchTypeBestFields
+ q := elastic.NewBoolQuery()
+ tokens, err := options.Tokens()
+ if err != nil {
+ return nil, err
}
+ for _, token := range tokens {
+ innerQ := elastic.NewMultiMatchQuery(token.Term, "title", "content", "comments")
+ if token.Fuzzy {
+ // If the term is not a phrase use fuzziness set to AUTO
+ innerQ = innerQ.Type(esMultiMatchTypeBestFields).Fuzziness(esFuzzyAuto)
+ } else {
+ innerQ = innerQ.Type(esMultiMatchTypePhrasePrefix)
+ }
- query.Must(elastic.NewMultiMatchQuery(options.Keyword, "title", "content", "comments").Type(searchType))
+ switch token.Kind {
+ case internal.BoolOptMust:
+ q.Must(innerQ)
+ case internal.BoolOptShould:
+ q.Should(innerQ)
+ case internal.BoolOptNot:
+ q.MustNot(innerQ)
+ }
+ }
+ query.Must(q)
}
if len(options.RepoIDs) > 0 {
@@ -236,7 +258,7 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
}
if options.SortBy == "" {
- options.SortBy = internal.SortByCreatedAsc
+ options.SortBy = internal.SortByScore
}
sortBy := []elastic.Sorter{
parseSortBy(options.SortBy),
diff --git a/modules/indexer/issues/elasticsearch/elasticsearch_test.go b/modules/indexer/issues/elasticsearch/elasticsearch_test.go
index 4ed0b84442..f8cd4e02f6 100644
--- a/modules/indexer/issues/elasticsearch/elasticsearch_test.go
+++ b/modules/indexer/issues/elasticsearch/elasticsearch_test.go
@@ -10,7 +10,7 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/indexer/issues/internal/tests"
+ "forgejo.org/modules/indexer/issues/internal/tests"
)
func TestElasticsearchIndexer(t *testing.T) {
diff --git a/modules/indexer/issues/indexer.go b/modules/indexer/issues/indexer.go
index d7310529fc..446e714735 100644
--- a/modules/indexer/issues/indexer.go
+++ b/modules/indexer/issues/indexer.go
@@ -8,22 +8,23 @@ import (
"fmt"
"os"
"runtime/pprof"
+ "strings"
"sync/atomic"
"time"
- db_model "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/indexer/issues/bleve"
- "code.gitea.io/gitea/modules/indexer/issues/db"
- "code.gitea.io/gitea/modules/indexer/issues/elasticsearch"
- "code.gitea.io/gitea/modules/indexer/issues/internal"
- "code.gitea.io/gitea/modules/indexer/issues/meilisearch"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/queue"
- "code.gitea.io/gitea/modules/setting"
+ db_model "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/indexer/issues/bleve"
+ "forgejo.org/modules/indexer/issues/db"
+ "forgejo.org/modules/indexer/issues/elasticsearch"
+ "forgejo.org/modules/indexer/issues/internal"
+ "forgejo.org/modules/indexer/issues/meilisearch"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/setting"
)
// IndexerMetadata is used to send data to the queue, so it contains only the ids.
@@ -269,6 +270,7 @@ func IsAvailable(ctx context.Context) bool {
type SearchOptions = internal.SearchOptions
const (
+ SortByScore = internal.SortByScore
SortByCreatedDesc = internal.SortByCreatedDesc
SortByUpdatedDesc = internal.SortByUpdatedDesc
SortByCommentsDesc = internal.SortByCommentsDesc
@@ -279,6 +281,33 @@ const (
SortByDeadlineAsc = internal.SortByDeadlineAsc
)
+// ParseSortBy parses the `sortBy` string and returns the associated `SortBy`
+// value, if one exists. Otherwise return `defaultSortBy`.
+func ParseSortBy(sortBy string, defaultSortBy internal.SortBy) internal.SortBy {
+ switch strings.ToLower(sortBy) {
+ case "relevance":
+ return SortByScore
+ case "latest":
+ return SortByCreatedDesc
+ case "oldest":
+ return SortByCreatedAsc
+ case "recentupdate":
+ return SortByUpdatedDesc
+ case "leastupdate":
+ return SortByUpdatedAsc
+ case "mostcomment":
+ return SortByCommentsDesc
+ case "leastcomment":
+ return SortByCommentsAsc
+ case "nearduedate":
+ return SortByDeadlineAsc
+ case "farduedate":
+ return SortByDeadlineDesc
+ default:
+ return defaultSortBy
+ }
+}
+
// SearchIssues search issues by options.
func SearchIssues(ctx context.Context, opts *SearchOptions) ([]int64, int64, error) {
indexer := *globalIndexer.Load()
diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go
index e426229f78..d3b3494672 100644
--- a/modules/indexer/issues/indexer_test.go
+++ b/modules/indexer/issues/indexer_test.go
@@ -4,20 +4,22 @@
package issues
import (
- "context"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/indexer/issues/internal"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/indexer/issues/internal"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
@@ -25,7 +27,7 @@ func TestMain(m *testing.M) {
}
func TestDBSearchIssues(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
setting.Indexer.IssueType = "db"
InitIssueIndexer(true)
@@ -79,10 +81,9 @@ func searchIssueWithKeyword(t *testing.T) {
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
+
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -125,10 +126,9 @@ func searchIssueInRepo(t *testing.T) {
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
+
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -150,6 +150,11 @@ func searchIssueByID(t *testing.T) {
},
expectedIDs: []int64{6, 1},
},
+ {
+ // NOTE: This tests no assignees filtering and also ToSearchOptions() to ensure it will set AssigneeID to 0 when it is passed as -1.
+ opts: *ToSearchOptions("", &issues.IssuesOptions{AssigneeID: -1}),
+ expectedIDs: []int64{22, 21, 16, 15, 14, 13, 12, 11, 20, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2},
+ },
{
opts: SearchOptions{
MentionID: optional.Some(int64(4)),
@@ -192,10 +197,8 @@ func searchIssueByID(t *testing.T) {
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -219,10 +222,9 @@ func searchIssueIsPull(t *testing.T) {
},
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
+
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -246,10 +248,8 @@ func searchIssueIsClosed(t *testing.T) {
},
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -273,10 +273,9 @@ func searchIssueByMilestoneID(t *testing.T) {
},
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
+
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -306,10 +305,9 @@ func searchIssueByLabelID(t *testing.T) {
},
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
+
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -327,10 +325,9 @@ func searchIssueByTime(t *testing.T) {
},
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
+
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -348,10 +345,9 @@ func searchIssueWithOrder(t *testing.T) {
},
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
+
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -381,10 +377,9 @@ func searchIssueInProject(t *testing.T) {
},
}
for _, test := range tests {
- issueIDs, _, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, _, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
+
assert.Equal(t, test.expectedIDs, issueIDs)
}
}
@@ -406,10 +401,9 @@ func searchIssueWithPaginator(t *testing.T) {
},
}
for _, test := range tests {
- issueIDs, total, err := SearchIssues(context.TODO(), &test.opts)
- if !assert.NoError(t, err) {
- return
- }
+ issueIDs, total, err := SearchIssues(t.Context(), &test.opts)
+ require.NoError(t, err)
+
assert.Equal(t, test.expectedIDs, issueIDs)
assert.Equal(t, test.expectedTotal, total)
}
diff --git a/modules/indexer/issues/internal/indexer.go b/modules/indexer/issues/internal/indexer.go
index 95740bc598..2f3b4029dc 100644
--- a/modules/indexer/issues/internal/indexer.go
+++ b/modules/indexer/issues/internal/indexer.go
@@ -7,7 +7,7 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/modules/indexer/internal"
+ "forgejo.org/modules/indexer/internal"
)
// Indexer defines an interface to indexer issues contents
diff --git a/modules/indexer/issues/internal/model.go b/modules/indexer/issues/internal/model.go
index 2dfee8b72e..03f5595a5b 100644
--- a/modules/indexer/issues/internal/model.go
+++ b/modules/indexer/issues/internal/model.go
@@ -4,9 +4,9 @@
package internal
import (
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/timeutil"
)
// IndexerData data stored in the issue indexer
@@ -74,8 +74,6 @@ type SearchResult struct {
type SearchOptions struct {
Keyword string // keyword to search
- IsFuzzyKeyword bool // if false the levenshtein distance is 0
-
RepoIDs []int64 // repository IDs which the issues belong to
AllPublic bool // if include all public repositories
@@ -127,6 +125,7 @@ func (o *SearchOptions) Copy(edit ...func(options *SearchOptions)) *SearchOption
type SortBy string
const (
+ SortByScore SortBy = "-_score"
SortByCreatedDesc SortBy = "-created_unix"
SortByUpdatedDesc SortBy = "-updated_unix"
SortByCommentsDesc SortBy = "-comment_count"
diff --git a/modules/indexer/issues/internal/qstring.go b/modules/indexer/issues/internal/qstring.go
new file mode 100644
index 0000000000..fdb89b09e9
--- /dev/null
+++ b/modules/indexer/issues/internal/qstring.go
@@ -0,0 +1,112 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package internal
+
+import (
+ "io"
+ "strings"
+)
+
+type BoolOpt int
+
+const (
+ BoolOptMust BoolOpt = iota
+ BoolOptShould
+ BoolOptNot
+)
+
+type Token struct {
+ Term string
+ Kind BoolOpt
+ Fuzzy bool
+}
+
+type Tokenizer struct {
+ in *strings.Reader
+}
+
+func (t *Tokenizer) next() (tk Token, err error) {
+ var (
+ sb strings.Builder
+ r rune
+ )
+ tk.Kind = BoolOptShould
+ tk.Fuzzy = true
+
+ // skip all leading white space
+ for {
+ if r, _, err = t.in.ReadRune(); err == nil && r == ' ' {
+ //nolint:staticcheck,wastedassign // SA4006 the variable is used after the loop
+ r, _, err = t.in.ReadRune()
+ continue
+ }
+ break
+ }
+ if err != nil {
+ return tk, err
+ }
+
+ // check for +/- op, increment to the next rune in both cases
+ switch r {
+ case '+':
+ tk.Kind = BoolOptMust
+ r, _, err = t.in.ReadRune()
+ case '-':
+ tk.Kind = BoolOptNot
+ r, _, err = t.in.ReadRune()
+ }
+ if err != nil {
+ return tk, err
+ }
+
+ // parse the string, escaping special characters
+ for esc := false; err == nil; r, _, err = t.in.ReadRune() {
+ if esc {
+ if !strings.ContainsRune("+-\\\"", r) {
+ sb.WriteRune('\\')
+ }
+ sb.WriteRune(r)
+ esc = false
+ continue
+ }
+ switch r {
+ case '\\':
+ esc = true
+ case '"':
+ if !tk.Fuzzy {
+ goto nextEnd
+ }
+ tk.Fuzzy = false
+ case ' ', '\t':
+ if tk.Fuzzy {
+ goto nextEnd
+ }
+ sb.WriteRune(r)
+ default:
+ sb.WriteRune(r)
+ }
+ }
+nextEnd:
+
+ tk.Term = sb.String()
+ if err == io.EOF {
+ err = nil
+ } // do not consider EOF as an error at the end
+ return tk, err
+}
+
+// Tokenize the keyword
+func (o *SearchOptions) Tokens() (tokens []Token, err error) {
+ in := strings.NewReader(o.Keyword)
+ it := Tokenizer{in: in}
+
+ for token, err := it.next(); err == nil; token, err = it.next() {
+ tokens = append(tokens, token)
+ }
+ if err != nil && err != io.EOF {
+ return nil, err
+ }
+
+ return tokens, nil
+}
diff --git a/modules/indexer/issues/internal/qstring_test.go b/modules/indexer/issues/internal/qstring_test.go
new file mode 100644
index 0000000000..a911b86e2f
--- /dev/null
+++ b/modules/indexer/issues/internal/qstring_test.go
@@ -0,0 +1,171 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package internal
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+type testIssueQueryStringOpt struct {
+ Keyword string
+ Results []Token
+}
+
+var testOpts = []testIssueQueryStringOpt{
+ {
+ Keyword: "Hello",
+ Results: []Token{
+ {
+ Term: "Hello",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "Hello World",
+ Results: []Token{
+ {
+ Term: "Hello",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ {
+ Term: "World",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "+Hello +World",
+ Results: []Token{
+ {
+ Term: "Hello",
+ Fuzzy: true,
+ Kind: BoolOptMust,
+ },
+ {
+ Term: "World",
+ Fuzzy: true,
+ Kind: BoolOptMust,
+ },
+ },
+ },
+ {
+ Keyword: "+Hello World",
+ Results: []Token{
+ {
+ Term: "Hello",
+ Fuzzy: true,
+ Kind: BoolOptMust,
+ },
+ {
+ Term: "World",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "+Hello -World",
+ Results: []Token{
+ {
+ Term: "Hello",
+ Fuzzy: true,
+ Kind: BoolOptMust,
+ },
+ {
+ Term: "World",
+ Fuzzy: true,
+ Kind: BoolOptNot,
+ },
+ },
+ },
+ {
+ Keyword: "\"Hello World\"",
+ Results: []Token{
+ {
+ Term: "Hello World",
+ Fuzzy: false,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "+\"Hello World\"",
+ Results: []Token{
+ {
+ Term: "Hello World",
+ Fuzzy: false,
+ Kind: BoolOptMust,
+ },
+ },
+ },
+ {
+ Keyword: "-\"Hello World\"",
+ Results: []Token{
+ {
+ Term: "Hello World",
+ Fuzzy: false,
+ Kind: BoolOptNot,
+ },
+ },
+ },
+ {
+ Keyword: "\"+Hello -World\"",
+ Results: []Token{
+ {
+ Term: "+Hello -World",
+ Fuzzy: false,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "\\+Hello", // \+Hello => +Hello
+ Results: []Token{
+ {
+ Term: "+Hello",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "\\\\Hello", // \\Hello => \Hello
+ Results: []Token{
+ {
+ Term: "\\Hello",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+ {
+ Keyword: "\\\"Hello", // \"Hello => "Hello
+ Results: []Token{
+ {
+ Term: "\"Hello",
+ Fuzzy: true,
+ Kind: BoolOptShould,
+ },
+ },
+ },
+}
+
+func TestIssueQueryString(t *testing.T) {
+ var opt SearchOptions
+ for _, res := range testOpts {
+ t.Run(opt.Keyword, func(t *testing.T) {
+ opt.Keyword = res.Keyword
+ tokens, err := opt.Tokens()
+ require.NoError(t, err)
+ assert.Equal(t, res.Results, tokens)
+ })
+ }
+}
diff --git a/modules/indexer/issues/internal/tests/tests.go b/modules/indexer/issues/internal/tests/tests.go
index 5f2488a06e..8308cb7f60 100644
--- a/modules/indexer/issues/internal/tests/tests.go
+++ b/modules/indexer/issues/internal/tests/tests.go
@@ -14,20 +14,20 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/indexer/issues/internal"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/indexer/issues/internal"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestIndexer(t *testing.T, indexer internal.Indexer) {
- _, err := indexer.Init(context.Background())
+ _, err := indexer.Init(t.Context())
require.NoError(t, err)
- require.NoError(t, indexer.Ping(context.Background()))
+ require.NoError(t, indexer.Ping(t.Context()))
var (
ids []int64
@@ -39,32 +39,32 @@ func TestIndexer(t *testing.T, indexer internal.Indexer) {
ids = append(ids, v.ID)
data[v.ID] = v
}
- require.NoError(t, indexer.Index(context.Background(), d...))
+ require.NoError(t, indexer.Index(t.Context(), d...))
require.NoError(t, waitData(indexer, int64(len(data))))
}
defer func() {
- require.NoError(t, indexer.Delete(context.Background(), ids...))
+ require.NoError(t, indexer.Delete(t.Context(), ids...))
}()
for _, c := range cases {
t.Run(c.Name, func(t *testing.T) {
if len(c.ExtraData) > 0 {
- require.NoError(t, indexer.Index(context.Background(), c.ExtraData...))
+ require.NoError(t, indexer.Index(t.Context(), c.ExtraData...))
for _, v := range c.ExtraData {
data[v.ID] = v
}
require.NoError(t, waitData(indexer, int64(len(data))))
defer func() {
for _, v := range c.ExtraData {
- require.NoError(t, indexer.Delete(context.Background(), v.ID))
+ require.NoError(t, indexer.Delete(t.Context(), v.ID))
delete(data, v.ID)
}
require.NoError(t, waitData(indexer, int64(len(data))))
}()
}
- result, err := indexer.Search(context.Background(), c.SearchOptions)
+ result, err := indexer.Search(t.Context(), c.SearchOptions)
require.NoError(t, err)
if c.Expected != nil {
@@ -80,7 +80,7 @@ func TestIndexer(t *testing.T, indexer internal.Indexer) {
// test counting
c.SearchOptions.Paginator = &db.ListOptions{PageSize: 0}
- countResult, err := indexer.Search(context.Background(), c.SearchOptions)
+ countResult, err := indexer.Search(t.Context(), c.SearchOptions)
require.NoError(t, err)
assert.Empty(t, countResult.Hits)
assert.Equal(t, result.Total, countResult.Total)
@@ -113,7 +113,7 @@ var cases = []*testIndexerCase{
},
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
assert.Equal(t, len(data), int(result.Total))
},
},
@@ -126,10 +126,25 @@ var cases = []*testIndexerCase{
},
SearchOptions: &internal.SearchOptions{
Keyword: "hello",
+ SortBy: internal.SortByCreatedDesc,
},
ExpectedIDs: []int64{1002, 1001, 1000},
ExpectedTotal: 3,
},
+ {
+ Name: "Keyword Exclude",
+ ExtraData: []*internal.IndexerData{
+ {ID: 1000, Title: "hi hello world"},
+ {ID: 1001, Content: "hi hello world"},
+ {ID: 1002, Comments: []string{"hello", "hello world"}},
+ },
+ SearchOptions: &internal.SearchOptions{
+ Keyword: "hello world -hi",
+ SortBy: internal.SortByCreatedDesc,
+ },
+ ExpectedIDs: []int64{1002},
+ ExpectedTotal: 1,
+ },
{
Name: "Keyword Fuzzy",
ExtraData: []*internal.IndexerData{
@@ -138,8 +153,8 @@ var cases = []*testIndexerCase{
{ID: 1002, Comments: []string{"hi", "hello world"}},
},
SearchOptions: &internal.SearchOptions{
- Keyword: "hello world",
- IsFuzzyKeyword: true,
+ Keyword: "hello world",
+ SortBy: internal.SortByCreatedDesc,
},
ExpectedIDs: []int64{1002, 1001, 1000},
ExpectedTotal: 3,
@@ -157,6 +172,7 @@ var cases = []*testIndexerCase{
},
SearchOptions: &internal.SearchOptions{
Keyword: "hello",
+ SortBy: internal.SortByCreatedDesc,
RepoIDs: []int64{1, 4},
},
ExpectedIDs: []int64{1006, 1002, 1001},
@@ -175,6 +191,7 @@ var cases = []*testIndexerCase{
},
SearchOptions: &internal.SearchOptions{
Keyword: "hello",
+ SortBy: internal.SortByCreatedDesc,
RepoIDs: []int64{1, 4},
AllPublic: true,
},
@@ -190,7 +207,7 @@ var cases = []*testIndexerCase{
IsPull: optional.Some(false),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.False(t, data[v.ID].IsPull)
}
@@ -206,7 +223,7 @@ var cases = []*testIndexerCase{
IsPull: optional.Some(true),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.True(t, data[v.ID].IsPull)
}
@@ -222,7 +239,7 @@ var cases = []*testIndexerCase{
IsClosed: optional.Some(false),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.False(t, data[v.ID].IsClosed)
}
@@ -238,7 +255,7 @@ var cases = []*testIndexerCase{
IsClosed: optional.Some(true),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.True(t, data[v.ID].IsClosed)
}
@@ -288,7 +305,7 @@ var cases = []*testIndexerCase{
MilestoneIDs: []int64{1, 2, 6},
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Contains(t, []int64{1, 2, 6}, data[v.ID].MilestoneID)
}
@@ -306,7 +323,7 @@ var cases = []*testIndexerCase{
MilestoneIDs: []int64{0},
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Equal(t, int64(0), data[v.ID].MilestoneID)
}
@@ -324,7 +341,7 @@ var cases = []*testIndexerCase{
ProjectID: optional.Some(int64(1)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Equal(t, int64(1), data[v.ID].ProjectID)
}
@@ -342,7 +359,7 @@ var cases = []*testIndexerCase{
ProjectID: optional.Some(int64(0)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Equal(t, int64(0), data[v.ID].ProjectID)
}
@@ -360,7 +377,7 @@ var cases = []*testIndexerCase{
ProjectColumnID: optional.Some(int64(1)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Equal(t, int64(1), data[v.ID].ProjectColumnID)
}
@@ -378,7 +395,7 @@ var cases = []*testIndexerCase{
ProjectColumnID: optional.Some(int64(0)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Equal(t, int64(0), data[v.ID].ProjectColumnID)
}
@@ -396,7 +413,7 @@ var cases = []*testIndexerCase{
PosterID: optional.Some(int64(1)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Equal(t, int64(1), data[v.ID].PosterID)
}
@@ -414,7 +431,7 @@ var cases = []*testIndexerCase{
AssigneeID: optional.Some(int64(1)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Equal(t, int64(1), data[v.ID].AssigneeID)
}
@@ -432,7 +449,7 @@ var cases = []*testIndexerCase{
AssigneeID: optional.Some(int64(0)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Equal(t, int64(0), data[v.ID].AssigneeID)
}
@@ -450,7 +467,7 @@ var cases = []*testIndexerCase{
MentionID: optional.Some(int64(1)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Contains(t, data[v.ID].MentionIDs, int64(1))
}
@@ -468,7 +485,7 @@ var cases = []*testIndexerCase{
ReviewedID: optional.Some(int64(1)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Contains(t, data[v.ID].ReviewedIDs, int64(1))
}
@@ -486,7 +503,7 @@ var cases = []*testIndexerCase{
ReviewRequestedID: optional.Some(int64(1)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Contains(t, data[v.ID].ReviewRequestedIDs, int64(1))
}
@@ -504,7 +521,7 @@ var cases = []*testIndexerCase{
SubscriberID: optional.Some(int64(1)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.Contains(t, data[v.ID].SubscriberIDs, int64(1))
}
@@ -523,7 +540,7 @@ var cases = []*testIndexerCase{
UpdatedBeforeUnix: optional.Some(int64(30)),
},
Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
- assert.Equal(t, 5, len(result.Hits))
+ assert.Len(t, result.Hits, 5)
for _, v := range result.Hits {
assert.GreaterOrEqual(t, data[v.ID].UpdatedUnix, int64(20))
assert.LessOrEqual(t, data[v.ID].UpdatedUnix, int64(30))
@@ -597,6 +614,22 @@ var cases = []*testIndexerCase{
}
},
},
+ {
+ Name: "SortByScore",
+ SearchOptions: &internal.SearchOptions{
+ Paginator: &db.ListOptionsAll,
+ SortBy: internal.SortByScore,
+ },
+ Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) {
+ assert.Equal(t, len(data), len(result.Hits))
+ assert.Equal(t, len(data), int(result.Total))
+ for i, v := range result.Hits {
+ if i < len(result.Hits)-1 {
+ assert.GreaterOrEqual(t, v.Score, result.Hits[i+1].Score)
+ }
+ }
+ },
+ },
{
Name: "SortByCreatedAsc",
SearchOptions: &internal.SearchOptions{
diff --git a/modules/indexer/issues/meilisearch/meilisearch.go b/modules/indexer/issues/meilisearch/meilisearch.go
index 9332319339..17a8ba2452 100644
--- a/modules/indexer/issues/meilisearch/meilisearch.go
+++ b/modules/indexer/issues/meilisearch/meilisearch.go
@@ -10,9 +10,9 @@ import (
"strconv"
"strings"
- indexer_internal "code.gitea.io/gitea/modules/indexer/internal"
- inner_meilisearch "code.gitea.io/gitea/modules/indexer/internal/meilisearch"
- "code.gitea.io/gitea/modules/indexer/issues/internal"
+ indexer_internal "forgejo.org/modules/indexer/internal"
+ inner_meilisearch "forgejo.org/modules/indexer/internal/meilisearch"
+ "forgejo.org/modules/indexer/issues/internal"
"github.com/meilisearch/meilisearch-go"
)
@@ -208,12 +208,18 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
query.And(inner_meilisearch.NewFilterLte("updated_unix", options.UpdatedBeforeUnix.Value()))
}
- if options.SortBy == "" {
- options.SortBy = internal.SortByCreatedAsc
- }
- sortBy := []string{
- parseSortBy(options.SortBy),
- "id:desc",
+ var sortBy []string
+ switch options.SortBy {
+ // sort by relevancy (no explicit sorting)
+ case internal.SortByScore:
+ fallthrough
+ case "":
+ sortBy = []string{}
+ default:
+ sortBy = []string{
+ parseSortBy(options.SortBy),
+ "id:desc",
+ }
}
skip, limit := indexer_internal.ParsePaginator(options.Paginator, maxTotalHits)
@@ -226,20 +232,36 @@ func (b *Indexer) Search(ctx context.Context, options *internal.SearchOptions) (
limit = 1
}
- keyword := options.Keyword
- if !options.IsFuzzyKeyword {
- // to make it non fuzzy ("typo tolerance" in meilisearch terms), we have to quote the keyword(s)
- // https://www.meilisearch.com/docs/reference/api/search#phrase-search
- keyword = doubleQuoteKeyword(keyword)
+ var keywords []string
+ if options.Keyword != "" {
+ tokens, err := options.Tokens()
+ if err != nil {
+ return nil, err
+ }
+ for _, token := range tokens {
+ if !token.Fuzzy {
+ // to make it a phrase search, we have to quote the keyword(s)
+ // https://www.meilisearch.com/docs/reference/api/search#phrase-search
+ token.Term = doubleQuoteKeyword(token.Term)
+ }
+
+ // internal.BoolOptShould (Default, requires no modifications)
+ // internal.BoolOptMust (Not supported by meilisearch)
+ if token.Kind == internal.BoolOptNot {
+ token.Term = "-" + token.Term
+ }
+ keywords = append(keywords, token.Term)
+ }
}
- searchRes, err := b.inner.Client.Index(b.inner.VersionedIndexName()).Search(keyword, &meilisearch.SearchRequest{
- Filter: query.Statement(),
- Limit: int64(limit),
- Offset: int64(skip),
- Sort: sortBy,
- MatchingStrategy: "all",
- })
+ searchRes, err := b.inner.Client.Index(b.inner.VersionedIndexName()).
+ Search(strings.Join(keywords, " "), &meilisearch.SearchRequest{
+ Filter: query.Statement(),
+ Limit: int64(limit),
+ Offset: int64(skip),
+ Sort: sortBy,
+ MatchingStrategy: meilisearch.All,
+ })
if err != nil {
return nil, err
}
diff --git a/modules/indexer/issues/meilisearch/meilisearch_test.go b/modules/indexer/issues/meilisearch/meilisearch_test.go
index 3c19ac85b3..01160a5240 100644
--- a/modules/indexer/issues/meilisearch/meilisearch_test.go
+++ b/modules/indexer/issues/meilisearch/meilisearch_test.go
@@ -10,11 +10,12 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/indexer/issues/internal"
- "code.gitea.io/gitea/modules/indexer/issues/internal/tests"
+ "forgejo.org/modules/indexer/issues/internal"
+ "forgejo.org/modules/indexer/issues/internal/tests"
"github.com/meilisearch/meilisearch-go"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestMeilisearchIndexer(t *testing.T) {
@@ -58,7 +59,7 @@ func TestConvertHits(t *testing.T) {
_, err := convertHits(&meilisearch.SearchResponse{
Hits: []any{"aa", "bb", "cc", "dd"},
})
- assert.ErrorIs(t, err, ErrMalformedResponse)
+ require.ErrorIs(t, err, ErrMalformedResponse)
validResponse := &meilisearch.SearchResponse{
Hits: []any{
@@ -83,7 +84,7 @@ func TestConvertHits(t *testing.T) {
},
}
hits, err := convertHits(validResponse)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, []internal.Match{{ID: 11}, {ID: 22}, {ID: 33}}, hits)
}
diff --git a/modules/indexer/issues/util.go b/modules/indexer/issues/util.go
index e752ae6f24..3e6c8babe4 100644
--- a/modules/indexer/issues/util.go
+++ b/modules/indexer/issues/util.go
@@ -8,12 +8,12 @@ import (
"errors"
"fmt"
- "code.gitea.io/gitea/models/db"
- issue_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/indexer/issues/internal"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/queue"
+ "forgejo.org/models/db"
+ issue_model "forgejo.org/models/issues"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/indexer/issues/internal"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/queue"
)
// getIssueIndexerData returns the indexer data of an issue and a bool value indicating whether the issue exists.
diff --git a/modules/indexer/stats/db.go b/modules/indexer/stats/db.go
index 98a977c700..0d25192e3c 100644
--- a/modules/indexer/stats/db.go
+++ b/modules/indexer/stats/db.go
@@ -6,13 +6,13 @@ package stats
import (
"fmt"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
)
// DBIndexer implements Indexer interface to use database's like search
diff --git a/modules/indexer/stats/indexer.go b/modules/indexer/stats/indexer.go
index 7ec89e2afb..482c4b2ab4 100644
--- a/modules/indexer/stats/indexer.go
+++ b/modules/indexer/stats/indexer.go
@@ -6,10 +6,10 @@ package stats
import (
"context"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
)
// Indexer defines an interface to index repository stats
diff --git a/modules/indexer/stats/indexer_test.go b/modules/indexer/stats/indexer_test.go
index 5be45d7a3b..a5899d2506 100644
--- a/modules/indexer/stats/indexer_test.go
+++ b/modules/indexer/stats/indexer_test.go
@@ -4,21 +4,22 @@
package stats
import (
- "context"
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/queue"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/setting"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
@@ -26,26 +27,26 @@ func TestMain(m *testing.M) {
}
func TestRepoStatsIndex(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
setting.CfgProvider, _ = setting.NewConfigProviderFromData("")
setting.LoadQueueSettings()
err := Init()
- assert.NoError(t, err)
+ require.NoError(t, err)
repo, err := repo_model.GetRepositoryByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = UpdateRepoIndexer(repo)
- assert.NoError(t, err)
+ require.NoError(t, err)
- assert.NoError(t, queue.GetManager().FlushAll(context.Background(), 5*time.Second))
+ require.NoError(t, queue.GetManager().FlushAll(t.Context(), 5*time.Second))
status, err := repo_model.GetIndexerStatus(db.DefaultContext, repo, repo_model.RepoIndexerTypeStats)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "65f1bf27bc3bf70f64657658635e66094edbcb4d", status.CommitSha)
langs, err := repo_model.GetTopLanguageStats(db.DefaultContext, repo, 5)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, langs)
}
diff --git a/modules/indexer/stats/queue.go b/modules/indexer/stats/queue.go
index d002bd57cf..2403eb8dca 100644
--- a/modules/indexer/stats/queue.go
+++ b/modules/indexer/stats/queue.go
@@ -6,11 +6,11 @@ package stats
import (
"fmt"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/queue"
- "code.gitea.io/gitea/modules/setting"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/setting"
)
// statsQueue represents a queue to handle repository stats updates
diff --git a/modules/issue/template/template.go b/modules/issue/template/template.go
index cf5fcf28e5..8e07cbecd8 100644
--- a/modules/issue/template/template.go
+++ b/modules/issue/template/template.go
@@ -10,10 +10,10 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/container"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/container"
+ api "forgejo.org/modules/structs"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// Validate checks whether an IssueTemplate is considered valid, and returns the first error
@@ -88,6 +88,9 @@ func validateYaml(template *api.IssueTemplate) error {
if err := validateBoolItem(position, field.Attributes, "multiple"); err != nil {
return err
}
+ if err := validateBoolItem(position, field.Attributes, "list"); err != nil {
+ return err
+ }
if err := validateOptions(field, idx); err != nil {
return err
}
@@ -340,7 +343,13 @@ func (f *valuedField) WriteTo(builder *strings.Builder) {
}
}
if len(checkeds) > 0 {
- _, _ = fmt.Fprintf(builder, "%s\n", strings.Join(checkeds, ", "))
+ if list, ok := f.Attributes["list"].(bool); ok && list {
+ for _, check := range checkeds {
+ _, _ = fmt.Fprintf(builder, "- %s\n", check)
+ }
+ } else {
+ _, _ = fmt.Fprintf(builder, "%s\n", strings.Join(checkeds, ", "))
+ }
} else {
_, _ = fmt.Fprint(builder, blankPlaceholder)
}
@@ -392,7 +401,7 @@ func (f *valuedField) Render() string {
}
func (f *valuedField) Value() string {
- return strings.TrimSpace(f.Get(fmt.Sprintf("form-field-" + f.ID)))
+ return strings.TrimSpace(f.Get("form-field-" + f.ID))
}
func (f *valuedField) Options() []*valuedOption {
diff --git a/modules/issue/template/template_test.go b/modules/issue/template/template_test.go
index 481058754d..89e8924e95 100644
--- a/modules/issue/template/template_test.go
+++ b/modules/issue/template/template_test.go
@@ -7,8 +7,8 @@ import (
"net/url"
"testing"
- "code.gitea.io/gitea/modules/json"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/json"
+ api "forgejo.org/modules/structs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -216,6 +216,20 @@ body:
`,
wantErr: "body[0](dropdown): 'multiple' should be a bool",
},
+ {
+ name: "dropdown invalid list",
+ content: `
+name: "test"
+about: "this is about"
+body:
+ - type: "dropdown"
+ id: "1"
+ attributes:
+ label: "a"
+ list: "on"
+`,
+ wantErr: "body[0](dropdown): 'list' should be a bool",
+ },
{
name: "checkboxes invalid description",
content: `
@@ -807,7 +821,7 @@ body:
- type: dropdown
id: id5
attributes:
- label: Label of dropdown
+ label: Label of dropdown (one line)
description: Description of dropdown
multiple: true
options:
@@ -816,8 +830,21 @@ body:
- Option 3 of dropdown
validations:
required: true
- - type: checkboxes
+ - type: dropdown
id: id6
+ attributes:
+ label: Label of dropdown (list)
+ description: Description of dropdown
+ multiple: true
+ list: true
+ options:
+ - Option 1 of dropdown
+ - Option 2 of dropdown
+ - Option 3 of dropdown
+ validations:
+ required: true
+ - type: checkboxes
+ id: id7
attributes:
label: Label of checkboxes
description: Description of checkboxes
@@ -836,8 +863,9 @@ body:
"form-field-id3": {"Value of id3"},
"form-field-id4": {"Value of id4"},
"form-field-id5": {"0,1"},
- "form-field-id6-0": {"on"},
- "form-field-id6-2": {"on"},
+ "form-field-id6": {"1,2"},
+ "form-field-id7-0": {"on"},
+ "form-field-id7-2": {"on"},
},
},
@@ -849,10 +877,15 @@ body:
Value of id4
-### Label of dropdown
+### Label of dropdown (one line)
Option 1 of dropdown, Option 2 of dropdown
+### Label of dropdown (list)
+
+- Option 2 of dropdown
+- Option 3 of dropdown
+
### Label of checkboxes
- [x] Option 1 of checkboxes
diff --git a/modules/issue/template/unmarshal.go b/modules/issue/template/unmarshal.go
index 0fc13d7ddf..8df71a3299 100644
--- a/modules/issue/template/unmarshal.go
+++ b/modules/issue/template/unmarshal.go
@@ -9,11 +9,11 @@ import (
"path"
"strconv"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
"gopkg.in/yaml.v3"
)
diff --git a/modules/keying/keying.go b/modules/keying/keying.go
new file mode 100644
index 0000000000..30c664180c
--- /dev/null
+++ b/modules/keying/keying.go
@@ -0,0 +1,133 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+// Keying is a module that allows for subkeys to be deterministically generated
+// from the same master key. It allows for domain separation to take place by
+// using new keys for new subsystems/domains. These subkeys are provided with
+// an API to encrypt and decrypt data. The module panics if a bad interaction
+// happened, the panic should be seen as an non-recoverable error.
+//
+// HKDF (per RFC 5869) is used to derive new subkeys in a safe manner. It
+// provides a KDF security property, which is required for Forgejo, as the
+// secret key would be an ASCII string and isn't a random uniform bit string.
+// XChaCha-Poly1305 (per draft-irtf-cfrg-xchacha-01) is used as AEAD to encrypt
+// and decrypt messages. A new fresh random nonce is generated for every
+// encryption. The nonce gets prepended to the ciphertext.
+package keying
+
+import (
+ "crypto/hkdf"
+ "crypto/rand"
+ "crypto/sha256"
+ "encoding/binary"
+
+ "golang.org/x/crypto/chacha20poly1305"
+)
+
+var (
+ // The hash used for HKDF.
+ hash = sha256.New
+ // The AEAD used for encryption/decryption.
+ aead = chacha20poly1305.NewX
+ // The pseudorandom key generated by HKDF-Extract.
+ prk []byte
+)
+
+const (
+ aeadKeySize = chacha20poly1305.KeySize
+ aeadNonceSize = chacha20poly1305.NonceSizeX
+)
+
+// Set the main IKM for this module.
+func Init(ikm []byte) {
+ // Salt is intentionally left empty, it's not useful to Forgejo's use case.
+ var err error
+ prk, err = hkdf.Extract(hash, ikm, nil)
+ if err != nil {
+ panic(err)
+ }
+}
+
+// Specifies the context for which a subkey should be derived for.
+// This must be a hardcoded string and must not be arbitrarily constructed.
+type Context string
+
+var (
+ // Used for the `push_mirror` table.
+ ContextPushMirror Context = "pushmirror"
+ // Used for the `two_factor` table.
+ ContextTOTP Context = "totp"
+)
+
+// Derive *the* key for a given context, this is a deterministic function.
+// The same key will be provided for the same context.
+func DeriveKey(context Context) *Key {
+ if len(prk) != sha256.Size {
+ panic("keying: not initialized")
+ }
+
+ key, err := hkdf.Expand(hash, prk, string(context), aeadKeySize)
+ if err != nil {
+ panic(err)
+ }
+
+ return &Key{key}
+}
+
+type Key struct {
+ key []byte
+}
+
+// Encrypts the specified plaintext with some additional data that is tied to
+// this plaintext. The additional data can be seen as the context in which the
+// data is being encrypted for, this is different than the context for which the
+// key was derived; this allows for more granularity without deriving new keys.
+// Avoid any user-generated data to be passed into the additional data. The most
+// common usage of this would be to encrypt a database field, in that case use
+// the ID and database column name as additional data. The additional data isn't
+// appended to the ciphertext and may be publicly known, it must be available
+// when decryping the ciphertext.
+func (k *Key) Encrypt(plaintext, additionalData []byte) []byte {
+ // Construct a new AEAD with the key.
+ e, err := aead(k.key)
+ if err != nil {
+ panic(err)
+ }
+
+ // Generate a random nonce.
+ nonce := make([]byte, aeadNonceSize)
+ if n, err := rand.Read(nonce); err != nil || n != aeadNonceSize {
+ panic(err)
+ }
+
+ // Returns the ciphertext of this plaintext.
+ return e.Seal(nonce, nonce, plaintext, additionalData)
+}
+
+// Decrypts the ciphertext and authenticates it against the given additional
+// data that was given when it was encrypted. It returns an error if the
+// authentication failed.
+func (k *Key) Decrypt(ciphertext, additionalData []byte) ([]byte, error) {
+ if len(ciphertext) <= aeadNonceSize {
+ panic("keying: ciphertext is too short")
+ }
+
+ e, err := aead(k.key)
+ if err != nil {
+ panic(err)
+ }
+
+ nonce, ciphertext := ciphertext[:aeadNonceSize], ciphertext[aeadNonceSize:]
+
+ return e.Open(nil, nonce, ciphertext, additionalData)
+}
+
+// ColumnAndID generates a context that can be used as additional context for
+// encrypting and decrypting data. It requires the column name and the row ID
+// (this requires to be known beforehand). Be careful when using this, as the
+// table name isn't part of this context. This means it's not bound to a
+// particular table. The table should be part of the context that the key was
+// derived for, in which case it binds through that.
+func ColumnAndID(column string, id int64) []byte {
+ return binary.BigEndian.AppendUint64(append([]byte(column), ':'), uint64(id))
+}
diff --git a/modules/keying/keying_test.go b/modules/keying/keying_test.go
new file mode 100644
index 0000000000..87dce0a566
--- /dev/null
+++ b/modules/keying/keying_test.go
@@ -0,0 +1,111 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package keying_test
+
+import (
+ "math"
+ "testing"
+
+ "forgejo.org/modules/keying"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "golang.org/x/crypto/chacha20poly1305"
+)
+
+func TestKeying(t *testing.T) {
+ t.Run("Not initialized", func(t *testing.T) {
+ assert.Panics(t, func() {
+ keying.DeriveKey(keying.Context("TESTING"))
+ })
+ })
+
+ t.Run("Initialization", func(t *testing.T) {
+ keying.Init([]byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07})
+ })
+
+ t.Run("Context separation", func(t *testing.T) {
+ key1 := keying.DeriveKey(keying.Context("TESTING"))
+ key2 := keying.DeriveKey(keying.Context("TESTING2"))
+
+ ciphertext := key1.Encrypt([]byte("This is for context TESTING"), nil)
+
+ plaintext, err := key2.Decrypt(ciphertext, nil)
+ require.Error(t, err)
+ assert.Empty(t, plaintext)
+
+ plaintext, err = key1.Decrypt(ciphertext, nil)
+ require.NoError(t, err)
+ assert.EqualValues(t, "This is for context TESTING", plaintext)
+ })
+
+ context := keying.Context("TESTING PURPOSES")
+ plainText := []byte("Forgejo is run by [Redacted]")
+ var cipherText []byte
+ t.Run("Encrypt", func(t *testing.T) {
+ key := keying.DeriveKey(context)
+
+ cipherText = key.Encrypt(plainText, []byte{0x05, 0x06})
+ cipherText2 := key.Encrypt(plainText, []byte{0x05, 0x06})
+
+ // Ensure ciphertexts don't have an deterministic output.
+ assert.NotEqualValues(t, cipherText, cipherText2)
+ })
+
+ t.Run("Decrypt", func(t *testing.T) {
+ key := keying.DeriveKey(context)
+
+ t.Run("Successful", func(t *testing.T) {
+ convertedPlainText, err := key.Decrypt(cipherText, []byte{0x05, 0x06})
+ require.NoError(t, err)
+ assert.EqualValues(t, plainText, convertedPlainText)
+ })
+
+ t.Run("Not enough additional data", func(t *testing.T) {
+ plainText, err := key.Decrypt(cipherText, []byte{0x05})
+ require.Error(t, err)
+ assert.Empty(t, plainText)
+ })
+
+ t.Run("Too much additional data", func(t *testing.T) {
+ plainText, err := key.Decrypt(cipherText, []byte{0x05, 0x06, 0x07})
+ require.Error(t, err)
+ assert.Empty(t, plainText)
+ })
+
+ t.Run("Incorrect nonce", func(t *testing.T) {
+ // Flip the first byte of the nonce.
+ cipherText[0] = ^cipherText[0]
+
+ plainText, err := key.Decrypt(cipherText, []byte{0x05, 0x06})
+ require.Error(t, err)
+ assert.Empty(t, plainText)
+ })
+
+ t.Run("Incorrect ciphertext", func(t *testing.T) {
+ assert.Panics(t, func() {
+ key.Decrypt(nil, nil)
+ })
+
+ assert.Panics(t, func() {
+ cipherText := make([]byte, chacha20poly1305.NonceSizeX)
+ key.Decrypt(cipherText, nil)
+ })
+ })
+ })
+}
+
+func TestKeyingColumnAndID(t *testing.T) {
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, keying.ColumnAndID("table", math.MinInt64))
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, keying.ColumnAndID("table", -1))
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, keying.ColumnAndID("table", 0))
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, keying.ColumnAndID("table", 1))
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, keying.ColumnAndID("table", math.MaxInt64))
+
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x32, 0x3a, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, keying.ColumnAndID("table2", math.MinInt64))
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x32, 0x3a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, keying.ColumnAndID("table2", -1))
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x32, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, keying.ColumnAndID("table2", 0))
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x32, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, keying.ColumnAndID("table2", 1))
+ assert.EqualValues(t, []byte{0x74, 0x61, 0x62, 0x6c, 0x65, 0x32, 0x3a, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, keying.ColumnAndID("table2", math.MaxInt64))
+}
diff --git a/modules/label/parser.go b/modules/label/parser.go
index 511bac823f..558ae68def 100644
--- a/modules/label/parser.go
+++ b/modules/label/parser.go
@@ -8,7 +8,7 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/modules/options"
+ "forgejo.org/modules/options"
"gopkg.in/yaml.v3"
)
diff --git a/modules/lfs/content_store.go b/modules/lfs/content_store.go
index 0d9c0c98ac..ba23cec2be 100644
--- a/modules/lfs/content_store.go
+++ b/modules/lfs/content_store.go
@@ -11,8 +11,8 @@ import (
"io"
"os"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/storage"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/storage"
)
var (
diff --git a/modules/lfs/endpoint.go b/modules/lfs/endpoint.go
index 2931defcd9..b8df4be3ee 100644
--- a/modules/lfs/endpoint.go
+++ b/modules/lfs/endpoint.go
@@ -10,8 +10,8 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
// DetermineEndpoint determines an endpoint from the clone url or uses the specified LFS url.
@@ -60,6 +60,10 @@ func endpointFromURL(rawurl string) *url.URL {
case "git":
u.Scheme = "https"
return u
+ case "ssh":
+ u.Scheme = "https"
+ u.User = nil
+ return u
case "file":
return u
default:
diff --git a/modules/lfs/filesystem_client.go b/modules/lfs/filesystem_client.go
index 71bef5c899..164dfa0011 100644
--- a/modules/lfs/filesystem_client.go
+++ b/modules/lfs/filesystem_client.go
@@ -10,7 +10,7 @@ import (
"os"
"path/filepath"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
// FilesystemClient is used to read LFS data from a filesystem path
diff --git a/modules/lfs/http_client.go b/modules/lfs/http_client.go
index f5ddd38b09..e531e2c1fe 100644
--- a/modules/lfs/http_client.go
+++ b/modules/lfs/http_client.go
@@ -13,12 +13,13 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/proxy"
-)
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/proxy"
+ "forgejo.org/modules/setting"
-const httpBatchSize = 20
+ "golang.org/x/sync/errgroup"
+)
// HTTPClient is used to communicate with the LFS server
// https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md
@@ -30,7 +31,7 @@ type HTTPClient struct {
// BatchSize returns the preferred size of batchs to process
func (c *HTTPClient) BatchSize() int {
- return httpBatchSize
+ return setting.LFSClient.BatchSize
}
func newHTTPClient(endpoint *url.URL, httpTransport *http.Transport) *HTTPClient {
@@ -71,7 +72,14 @@ func (c *HTTPClient) batch(ctx context.Context, operation string, objects []Poin
url := fmt.Sprintf("%s/objects/batch", c.endpoint)
+ // Original: In some lfs server implementations, they require the ref attribute. #32838
+ // `ref` is an "optional object describing the server ref that the objects belong to"
+ // but some (incorrect) lfs servers like aliyun require it, so maybe adding an empty ref here doesn't break the correct ones.
+ // https://github.com/git-lfs/git-lfs/blob/a32a02b44bf8a511aa14f047627c49e1a7fd5021/docs/api/batch.md?plain=1#L37
+ //
+ // UPDATE: it can't use "empty ref" here because it breaks others like https://github.com/go-gitea/gitea/issues/33453
request := &BatchRequest{operation, c.transferNames(), nil, objects}
+
payload := new(bytes.Buffer)
err := json.NewEncoder(payload).Encode(request)
if err != nil {
@@ -114,6 +122,7 @@ func (c *HTTPClient) Upload(ctx context.Context, objects []Pointer, callback Upl
return c.performOperation(ctx, objects, nil, callback)
}
+// performOperation takes a slice of LFS object pointers, batches them, and performs the upload/download operations concurrently in each batch
func (c *HTTPClient) performOperation(ctx context.Context, objects []Pointer, dc DownloadCallback, uc UploadCallback) error {
if len(objects) == 0 {
return nil
@@ -134,68 +143,90 @@ func (c *HTTPClient) performOperation(ctx context.Context, objects []Pointer, dc
return fmt.Errorf("TransferAdapter not found: %s", result.Transfer)
}
+ if setting.LFSClient.BatchOperationConcurrency <= 0 {
+ panic("BatchOperationConcurrency must be greater than 0, forgot to init?")
+ }
+ errGroup, groupCtx := errgroup.WithContext(ctx)
+ errGroup.SetLimit(setting.LFSClient.BatchOperationConcurrency)
for _, object := range result.Objects {
- if object.Error != nil {
- objectError := errors.New(object.Error.Message)
- log.Trace("Error on object %v: %v", object.Pointer, objectError)
- if uc != nil {
- if _, err := uc(object.Pointer, objectError); err != nil {
- return err
- }
- } else {
- if err := dc(object.Pointer, nil, objectError); err != nil {
- return err
- }
- }
- continue
- }
-
- if uc != nil {
- if len(object.Actions) == 0 {
- log.Trace("%v already present on server", object.Pointer)
- continue
- }
-
- link, ok := object.Actions["upload"]
- if !ok {
- log.Debug("%+v", object)
- return errors.New("missing action 'upload'")
- }
-
- content, err := uc(object.Pointer, nil)
- if err != nil {
- return err
- }
-
- err = transferAdapter.Upload(ctx, link, object.Pointer, content)
- if err != nil {
- return err
- }
-
- link, ok = object.Actions["verify"]
- if ok {
- if err := transferAdapter.Verify(ctx, link, object.Pointer); err != nil {
- return err
- }
- }
- } else {
- link, ok := object.Actions["download"]
- if !ok {
- log.Debug("%+v", object)
- return errors.New("missing action 'download'")
- }
-
- content, err := transferAdapter.Download(ctx, link)
- if err != nil {
- return err
- }
-
- if err := dc(object.Pointer, content, nil); err != nil {
- return err
- }
- }
+ errGroup.Go(func() error {
+ return performSingleOperation(groupCtx, object, dc, uc, transferAdapter)
+ })
}
+ // only the first error is returned, preserving legacy behavior before concurrency
+ return errGroup.Wait()
+}
+
+// performSingleOperation performs an LFS upload or download operation on a single object
+func performSingleOperation(ctx context.Context, object *ObjectResponse, dc DownloadCallback, uc UploadCallback, transferAdapter TransferAdapter) error {
+ // the response from a lfs batch api request for this specific object id contained an error
+ if object.Error != nil {
+ log.Trace("Error on object %v: %v", object.Pointer, object.Error)
+
+ // this was an 'upload' request inside the batch request
+ if uc != nil {
+ if _, err := uc(object.Pointer, object.Error); err != nil {
+ return err
+ }
+ } else {
+ // this was NOT an 'upload' request inside the batch request, meaning it must be a 'download' request
+ if err := dc(object.Pointer, nil, object.Error); err != nil {
+ return err
+ }
+ }
+ // if the callback returns no err, then the error could be ignored, and the operations should continue
+ return nil
+ }
+
+ // the response from an lfs batch api request contained necessary upload/download fields to act upon
+ if uc != nil {
+ if len(object.Actions) == 0 {
+ log.Trace("%v already present on server", object.Pointer)
+ return nil
+ }
+
+ link, ok := object.Actions["upload"]
+ if !ok {
+ return errors.New("missing action 'upload'")
+ }
+
+ content, err := uc(object.Pointer, nil)
+ if err != nil {
+ return err
+ }
+
+ err = transferAdapter.Upload(ctx, link, object.Pointer, content)
+ if err != nil {
+ return err
+ }
+
+ link, ok = object.Actions["verify"]
+ if ok {
+ if err := transferAdapter.Verify(ctx, link, object.Pointer); err != nil {
+ return err
+ }
+ }
+ } else {
+ link, ok := object.Actions["download"]
+ if !ok {
+ // no actions block in response, try legacy response schema
+ link, ok = object.Links["download"]
+ }
+ if !ok {
+ log.Debug("%+v", object)
+ return errors.New("missing action 'download'")
+ }
+
+ content, err := transferAdapter.Download(ctx, link)
+ if err != nil {
+ return err
+ }
+
+ if err := dc(object.Pointer, content, nil); err != nil {
+ return err
+ }
+ }
return nil
}
@@ -212,6 +243,7 @@ func createRequest(ctx context.Context, method, url string, headers map[string]s
req.Header.Set(key, value)
}
req.Header.Set("Accept", AcceptHeader)
+ req.Header.Set("User-Agent", UserAgentHeader)
return req, nil
}
diff --git a/modules/lfs/http_client_test.go b/modules/lfs/http_client_test.go
index 7431132f76..f825d95951 100644
--- a/modules/lfs/http_client_test.go
+++ b/modules/lfs/http_client_test.go
@@ -11,9 +11,12 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
type RoundTripFunc func(req *http.Request) *http.Response
@@ -59,6 +62,17 @@ func lfsTestRoundtripHandler(req *http.Request) *http.Response {
},
},
}
+ } else if strings.Contains(url, "legacy-batch-request-download") {
+ batchResponse = &BatchResponse{
+ Transfer: "dummy",
+ Objects: []*ObjectResponse{
+ {
+ Links: map[string]*Link{
+ "download": {},
+ },
+ },
+ },
+ }
} else if strings.Contains(url, "valid-batch-request-upload") {
batchResponse = &BatchResponse{
Transfer: "dummy",
@@ -159,7 +173,7 @@ func TestHTTPClientDownload(t *testing.T) {
var batchRequest BatchRequest
err := json.NewDecoder(req.Body).Decode(&batchRequest)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "download", batchRequest.Operation)
assert.Len(t, batchRequest.Objects, 1)
@@ -172,88 +186,84 @@ func TestHTTPClientDownload(t *testing.T) {
cases := []struct {
endpoint string
- expectederror string
+ expectedError string
}{
- // case 0
{
endpoint: "https://status-not-ok.io",
- expectederror: io.ErrUnexpectedEOF.Error(),
+ expectedError: io.ErrUnexpectedEOF.Error(),
},
- // case 1
{
endpoint: "https://invalid-json-response.io",
- expectederror: "invalid json",
+ expectedError: "invalid json",
},
- // case 2
{
endpoint: "https://valid-batch-request-download.io",
- expectederror: "",
+ expectedError: "",
},
- // case 3
{
endpoint: "https://response-no-objects.io",
- expectederror: "",
+ expectedError: "",
},
- // case 4
{
endpoint: "https://unknown-transfer-adapter.io",
- expectederror: "TransferAdapter not found: ",
+ expectedError: "TransferAdapter not found: ",
},
- // case 5
{
endpoint: "https://error-in-response-objects.io",
- expectederror: "Object not found",
+ expectedError: "Object not found",
},
- // case 6
{
endpoint: "https://empty-actions-map.io",
- expectederror: "missing action 'download'",
+ expectedError: "missing action 'download'",
},
- // case 7
{
endpoint: "https://download-actions-map.io",
- expectederror: "",
+ expectedError: "",
},
- // case 8
{
endpoint: "https://upload-actions-map.io",
- expectederror: "missing action 'download'",
+ expectedError: "missing action 'download'",
},
- // case 9
{
endpoint: "https://verify-actions-map.io",
- expectederror: "missing action 'download'",
+ expectedError: "missing action 'download'",
},
- // case 10
{
endpoint: "https://unknown-actions-map.io",
- expectederror: "missing action 'download'",
+ expectedError: "missing action 'download'",
+ },
+ {
+ endpoint: "https://legacy-batch-request-download.io",
+ expectedError: "",
},
}
- for n, c := range cases {
- client := &HTTPClient{
- client: hc,
- endpoint: c.endpoint,
- transfers: map[string]TransferAdapter{
- "dummy": dummy,
- },
- }
-
- err := client.Download(context.Background(), []Pointer{p}, func(p Pointer, content io.ReadCloser, objectError error) error {
- if objectError != nil {
- return objectError
+ defer test.MockVariableValue(&setting.LFSClient.BatchOperationConcurrency, 8)()
+ for _, c := range cases {
+ t.Run(c.endpoint, func(t *testing.T) {
+ client := &HTTPClient{
+ client: hc,
+ endpoint: c.endpoint,
+ transfers: map[string]TransferAdapter{
+ "dummy": dummy,
+ },
+ }
+
+ err := client.Download(t.Context(), []Pointer{p}, func(p Pointer, content io.ReadCloser, objectError error) error {
+ if objectError != nil {
+ return objectError
+ }
+ b, err := io.ReadAll(content)
+ require.NoError(t, err)
+ assert.Equal(t, []byte("dummy"), b)
+ return nil
+ })
+ if c.expectedError != "" {
+ assert.ErrorContains(t, err, c.expectedError)
+ } else {
+ require.NoError(t, err)
}
- b, err := io.ReadAll(content)
- assert.NoError(t, err)
- assert.Equal(t, []byte("dummy"), b)
- return nil
})
- if len(c.expectederror) > 0 {
- assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
- } else {
- assert.NoError(t, err, "case %d", n)
- }
}
}
@@ -267,7 +277,7 @@ func TestHTTPClientUpload(t *testing.T) {
var batchRequest BatchRequest
err := json.NewDecoder(req.Body).Decode(&batchRequest)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "upload", batchRequest.Operation)
assert.Len(t, batchRequest.Objects, 1)
@@ -280,81 +290,73 @@ func TestHTTPClientUpload(t *testing.T) {
cases := []struct {
endpoint string
- expectederror string
+ expectedError string
}{
- // case 0
{
endpoint: "https://status-not-ok.io",
- expectederror: io.ErrUnexpectedEOF.Error(),
+ expectedError: io.ErrUnexpectedEOF.Error(),
},
- // case 1
{
endpoint: "https://invalid-json-response.io",
- expectederror: "invalid json",
+ expectedError: "invalid json",
},
- // case 2
{
endpoint: "https://valid-batch-request-upload.io",
- expectederror: "",
+ expectedError: "",
},
- // case 3
{
endpoint: "https://response-no-objects.io",
- expectederror: "",
+ expectedError: "",
},
- // case 4
{
endpoint: "https://unknown-transfer-adapter.io",
- expectederror: "TransferAdapter not found: ",
+ expectedError: "TransferAdapter not found: ",
},
- // case 5
{
endpoint: "https://error-in-response-objects.io",
- expectederror: "Object not found",
+ expectedError: "Object not found",
},
- // case 6
{
endpoint: "https://empty-actions-map.io",
- expectederror: "",
+ expectedError: "",
},
- // case 7
{
endpoint: "https://download-actions-map.io",
- expectederror: "missing action 'upload'",
+ expectedError: "missing action 'upload'",
},
- // case 8
{
endpoint: "https://upload-actions-map.io",
- expectederror: "",
+ expectedError: "",
},
- // case 9
{
endpoint: "https://verify-actions-map.io",
- expectederror: "missing action 'upload'",
+ expectedError: "missing action 'upload'",
},
- // case 10
{
endpoint: "https://unknown-actions-map.io",
- expectederror: "missing action 'upload'",
+ expectedError: "missing action 'upload'",
},
}
- for n, c := range cases {
- client := &HTTPClient{
- client: hc,
- endpoint: c.endpoint,
- transfers: map[string]TransferAdapter{
- "dummy": dummy,
- },
- }
+ defer test.MockVariableValue(&setting.LFSClient.BatchOperationConcurrency, 8)()
+ for _, c := range cases {
+ t.Run(c.endpoint, func(t *testing.T) {
+ client := &HTTPClient{
+ client: hc,
+ endpoint: c.endpoint,
+ transfers: map[string]TransferAdapter{
+ "dummy": dummy,
+ },
+ }
- err := client.Upload(context.Background(), []Pointer{p}, func(p Pointer, objectError error) (io.ReadCloser, error) {
- return io.NopCloser(new(bytes.Buffer)), objectError
+ err := client.Upload(t.Context(), []Pointer{p}, func(p Pointer, objectError error) (io.ReadCloser, error) {
+ return io.NopCloser(new(bytes.Buffer)), objectError
+ })
+ if c.expectedError != "" {
+ assert.ErrorContains(t, err, c.expectedError)
+ } else {
+ require.NoError(t, err)
+ }
})
- if len(c.expectederror) > 0 {
- assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
- } else {
- assert.NoError(t, err, "case %d", n)
- }
}
}
diff --git a/modules/lfs/pointer_scanner_nogogit.go b/modules/lfs/pointer_scanner.go
similarity index 96%
rename from modules/lfs/pointer_scanner_nogogit.go
rename to modules/lfs/pointer_scanner.go
index 658b98feab..632ecd19ae 100644
--- a/modules/lfs/pointer_scanner_nogogit.go
+++ b/modules/lfs/pointer_scanner.go
@@ -1,8 +1,6 @@
// Copyright 2021 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !gogit
-
package lfs
import (
@@ -13,8 +11,8 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/git/pipeline"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/git/pipeline"
)
// SearchPointerBlobs scans the whole repository for LFS pointer files
diff --git a/modules/lfs/pointer_scanner_gogit.go b/modules/lfs/pointer_scanner_gogit.go
deleted file mode 100644
index f4302c23bc..0000000000
--- a/modules/lfs/pointer_scanner_gogit.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2021 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build gogit
-
-package lfs
-
-import (
- "context"
- "fmt"
-
- "code.gitea.io/gitea/modules/git"
-
- "github.com/go-git/go-git/v5/plumbing/object"
-)
-
-// SearchPointerBlobs scans the whole repository for LFS pointer files
-func SearchPointerBlobs(ctx context.Context, repo *git.Repository, pointerChan chan<- PointerBlob, errChan chan<- error) {
- gitRepo := repo.GoGitRepo()
-
- err := func() error {
- blobs, err := gitRepo.BlobObjects()
- if err != nil {
- return fmt.Errorf("lfs.SearchPointerBlobs BlobObjects: %w", err)
- }
-
- return blobs.ForEach(func(blob *object.Blob) error {
- select {
- case <-ctx.Done():
- return ctx.Err()
- default:
- }
-
- if blob.Size > blobSizeCutoff {
- return nil
- }
-
- reader, err := blob.Reader()
- if err != nil {
- return fmt.Errorf("lfs.SearchPointerBlobs blob.Reader: %w", err)
- }
- defer reader.Close()
-
- pointer, _ := ReadPointer(reader)
- if pointer.IsValid() {
- pointerChan <- PointerBlob{Hash: blob.Hash.String(), Pointer: pointer}
- }
-
- return nil
- })
- }()
- if err != nil {
- select {
- case <-ctx.Done():
- default:
- errChan <- err
- }
- }
-
- close(pointerChan)
- close(errChan)
-}
diff --git a/modules/lfs/pointer_test.go b/modules/lfs/pointer_test.go
index 41b5459fef..9299a8a832 100644
--- a/modules/lfs/pointer_test.go
+++ b/modules/lfs/pointer_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestStringContent(t *testing.T) {
@@ -45,7 +46,7 @@ func TestIsValid(t *testing.T) {
func TestGeneratePointer(t *testing.T) {
p, err := GeneratePointer(strings.NewReader("Gitea"))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, p.IsValid())
assert.Equal(t, "94cb57646c54a297c9807697e80a30946f79a4b82cb079d2606847825b1812cc", p.Oid)
assert.Equal(t, int64(5), p.Size)
@@ -53,41 +54,41 @@ func TestGeneratePointer(t *testing.T) {
func TestReadPointerFromBuffer(t *testing.T) {
p, err := ReadPointerFromBuffer([]byte{})
- assert.ErrorIs(t, err, ErrMissingPrefix)
+ require.ErrorIs(t, err, ErrMissingPrefix)
assert.False(t, p.IsValid())
p, err = ReadPointerFromBuffer([]byte("test"))
- assert.ErrorIs(t, err, ErrMissingPrefix)
+ require.ErrorIs(t, err, ErrMissingPrefix)
assert.False(t, p.IsValid())
p, err = ReadPointerFromBuffer([]byte("version https://git-lfs.github.com/spec/v1\n"))
- assert.ErrorIs(t, err, ErrInvalidStructure)
+ require.ErrorIs(t, err, ErrInvalidStructure)
assert.False(t, p.IsValid())
p, err = ReadPointerFromBuffer([]byte("version https://git-lfs.github.com/spec/v1\noid sha256:4d7a\nsize 1234\n"))
- assert.ErrorIs(t, err, ErrInvalidOIDFormat)
+ require.ErrorIs(t, err, ErrInvalidOIDFormat)
assert.False(t, p.IsValid())
p, err = ReadPointerFromBuffer([]byte("version https://git-lfs.github.com/spec/v1\noid sha256:4d7a2146z4ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393\nsize 1234\n"))
- assert.ErrorIs(t, err, ErrInvalidOIDFormat)
+ require.ErrorIs(t, err, ErrInvalidOIDFormat)
assert.False(t, p.IsValid())
p, err = ReadPointerFromBuffer([]byte("version https://git-lfs.github.com/spec/v1\noid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393\ntest 1234\n"))
- assert.Error(t, err)
+ require.Error(t, err)
assert.False(t, p.IsValid())
p, err = ReadPointerFromBuffer([]byte("version https://git-lfs.github.com/spec/v1\noid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393\nsize test\n"))
- assert.Error(t, err)
+ require.Error(t, err)
assert.False(t, p.IsValid())
p, err = ReadPointerFromBuffer([]byte("version https://git-lfs.github.com/spec/v1\noid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393\nsize 1234\n"))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, p.IsValid())
assert.Equal(t, "4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393", p.Oid)
assert.Equal(t, int64(1234), p.Size)
p, err = ReadPointerFromBuffer([]byte("version https://git-lfs.github.com/spec/v1\noid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393\nsize 1234\ntest"))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, p.IsValid())
assert.Equal(t, "4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393", p.Oid)
assert.Equal(t, int64(1234), p.Size)
@@ -95,7 +96,7 @@ func TestReadPointerFromBuffer(t *testing.T) {
func TestReadPointer(t *testing.T) {
p, err := ReadPointer(strings.NewReader("version https://git-lfs.github.com/spec/v1\noid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393\nsize 1234\n"))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, p.IsValid())
assert.Equal(t, "4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393", p.Oid)
assert.Equal(t, int64(1234), p.Size)
diff --git a/modules/lfs/shared.go b/modules/lfs/shared.go
index 80f4fed00d..504a726bce 100644
--- a/modules/lfs/shared.go
+++ b/modules/lfs/shared.go
@@ -4,14 +4,22 @@
package lfs
import (
+ "errors"
+ "fmt"
"time"
+
+ "forgejo.org/modules/util"
)
const (
// MediaType contains the media type for LFS server requests
MediaType = "application/vnd.git-lfs+json"
- // Some LFS servers offer content with other types, so fallback to '*/*' if application/vnd.git-lfs+json cannot be served
+ // AcceptHeader Some LFS servers offer content with other types, so fallback to '*/*' if application/vnd.git-lfs+json cannot be served
AcceptHeader = "application/vnd.git-lfs+json;q=0.9, */*;q=0.8"
+ // UserAgentHeader Add User-Agent for gitea's self-implemented lfs client,
+ // and the version is consistent with the latest version of git lfs can be avoided incompatibilities.
+ // Some lfs servers will check this
+ UserAgentHeader = "git-lfs/3.6.0 (Forgejo)"
)
// BatchRequest contains multiple requests processed in one batch operation.
@@ -47,6 +55,7 @@ type BatchResponse struct {
type ObjectResponse struct {
Pointer
Actions map[string]*Link `json:"actions,omitempty"`
+ Links map[string]*Link `json:"_links,omitempty"`
Error *ObjectError `json:"error,omitempty"`
}
@@ -63,6 +72,39 @@ type ObjectError struct {
Message string `json:"message"`
}
+var (
+ // See https://github.com/git-lfs/git-lfs/blob/main/docs/api/batch.md#successful-responses
+ // LFS object error codes should match HTTP status codes where possible:
+ // 404 - The object does not exist on the server.
+ // 409 - The specified hash algorithm disagrees with the server's acceptable options.
+ // 410 - The object was removed by the owner.
+ // 422 - Validation error.
+
+ ErrObjectNotExist = util.ErrNotExist // the object does not exist on the server
+ ErrObjectHashMismatch = errors.New("the specified hash algorithm disagrees with the server's acceptable options")
+ ErrObjectRemoved = errors.New("the object was removed by the owner")
+ ErrObjectValidation = errors.New("validation error")
+)
+
+func (e *ObjectError) Error() string {
+ return fmt.Sprintf("[%d] %s", e.Code, e.Message)
+}
+
+func (e *ObjectError) Unwrap() error {
+ switch e.Code {
+ case 404:
+ return ErrObjectNotExist
+ case 409:
+ return ErrObjectHashMismatch
+ case 410:
+ return ErrObjectRemoved
+ case 422:
+ return ErrObjectValidation
+ default:
+ return errors.New(e.Message)
+ }
+}
+
// PointerBlob associates a Git blob with a Pointer.
type PointerBlob struct {
Hash string
diff --git a/modules/lfs/transferadapter.go b/modules/lfs/transferadapter.go
index fbc3a3ad8c..98ac8b9a49 100644
--- a/modules/lfs/transferadapter.go
+++ b/modules/lfs/transferadapter.go
@@ -9,8 +9,8 @@ import (
"io"
"net/http"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
)
// TransferAdapter represents an adapter for downloading/uploading LFS objects.
diff --git a/modules/lfs/transferadapter_test.go b/modules/lfs/transferadapter_test.go
index 7fec137efe..aa87d2e01a 100644
--- a/modules/lfs/transferadapter_test.go
+++ b/modules/lfs/transferadapter_test.go
@@ -5,15 +5,15 @@ package lfs
import (
"bytes"
- "context"
"io"
"net/http"
"strings"
"testing"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestBasicTransferAdapterName(t *testing.T) {
@@ -39,7 +39,7 @@ func TestBasicTransferAdapter(t *testing.T) {
assert.Equal(t, "application/octet-stream", req.Header.Get("Content-Type"))
b, err := io.ReadAll(req.Body)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "dummy", string(b))
return &http.Response{StatusCode: http.StatusOK}
@@ -49,7 +49,7 @@ func TestBasicTransferAdapter(t *testing.T) {
var vp Pointer
err := json.NewDecoder(req.Body).Decode(&vp)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, p.Oid, vp.Oid)
assert.Equal(t, p.Size, vp.Size)
@@ -94,11 +94,11 @@ func TestBasicTransferAdapter(t *testing.T) {
}
for n, c := range cases {
- _, err := a.Download(context.Background(), c.link)
+ _, err := a.Download(t.Context(), c.link)
if len(c.expectederror) > 0 {
- assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
+ assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
} else {
- assert.NoError(t, err, "case %d", n)
+ require.NoError(t, err, "case %d", n)
}
}
})
@@ -127,11 +127,11 @@ func TestBasicTransferAdapter(t *testing.T) {
}
for n, c := range cases {
- err := a.Upload(context.Background(), c.link, p, bytes.NewBufferString("dummy"))
+ err := a.Upload(t.Context(), c.link, p, bytes.NewBufferString("dummy"))
if len(c.expectederror) > 0 {
- assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
+ assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
} else {
- assert.NoError(t, err, "case %d", n)
+ require.NoError(t, err, "case %d", n)
}
}
})
@@ -160,11 +160,11 @@ func TestBasicTransferAdapter(t *testing.T) {
}
for n, c := range cases {
- err := a.Verify(context.Background(), c.link, p)
+ err := a.Verify(t.Context(), c.link, p)
if len(c.expectederror) > 0 {
- assert.True(t, strings.Contains(err.Error(), c.expectederror), "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
+ assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror)
} else {
- assert.NoError(t, err, "case %d", n)
+ require.NoError(t, err, "case %d", n)
}
}
})
diff --git a/modules/locale/utils.go b/modules/locale/utils.go
new file mode 100644
index 0000000000..726dc92adc
--- /dev/null
+++ b/modules/locale/utils.go
@@ -0,0 +1,74 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+// extracted from `/build/lint-locale.go`, `/build/lint-locale-usage.go`
+
+package locale
+
+import (
+ "encoding/json" //nolint:depguard
+ "fmt"
+
+ "gopkg.in/ini.v1" //nolint:depguard
+)
+
+func IterateMessagesContent(localeContent []byte, onMsgid func(string, string) error) error {
+ // Same configuration as Forgejo uses.
+ cfg := ini.Empty(ini.LoadOptions{
+ IgnoreContinuation: true,
+ })
+ cfg.NameMapper = ini.SnackCase
+
+ if err := cfg.Append(localeContent); err != nil {
+ return err
+ }
+
+ for _, section := range cfg.Sections() {
+ for _, key := range section.Keys() {
+ var trKey string
+ if section.Name() == "" || section.Name() == "DEFAULT" || section.Name() == "common" {
+ trKey = key.Name()
+ } else {
+ trKey = section.Name() + "." + key.Name()
+ }
+ if err := onMsgid(trKey, key.Value()); err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
+func iterateMessagesNextInner(onMsgid func(string, string) error, data map[string]any, trKey ...string) error {
+ for key, value := range data {
+ currentKey := key
+ if len(trKey) == 1 {
+ currentKey = trKey[0] + "." + key
+ }
+
+ switch value := value.(type) {
+ case string:
+ if err := onMsgid(currentKey, value); err != nil {
+ return err
+ }
+ case map[string]any:
+ if err := iterateMessagesNextInner(onMsgid, value, currentKey); err != nil {
+ return err
+ }
+ default:
+ return fmt.Errorf("unexpected type: %s - %T", currentKey, value)
+ }
+ }
+
+ return nil
+}
+
+func IterateMessagesNextContent(localeContent []byte, onMsgid func(string, string) error) error {
+ var localeData map[string]any
+ if err := json.Unmarshal(localeContent, &localeData); err != nil {
+ return err
+ }
+ return iterateMessagesNextInner(onMsgid, localeData)
+}
diff --git a/modules/log/color_console.go b/modules/log/color_console.go
index 2658652ec6..82b5ce18f8 100644
--- a/modules/log/color_console.go
+++ b/modules/log/color_console.go
@@ -4,11 +4,14 @@
package log
-// CanColorStdout reports if we can color the Stdout
-// Although we could do terminal sniffing and the like - in reality
-// most tools on *nix are happy to display ansi colors.
-// We will terminal sniff on Windows in console_windows.go
+// CanColorStdout reports if we can use ANSI escape sequences on stdout
var CanColorStdout = true
-// CanColorStderr reports if we can color the Stderr
+// CanColorStderr reports if we can use ANSI escape sequences on stderr
var CanColorStderr = true
+
+// JournaldOnStdout reports whether stdout is attached to journald
+var JournaldOnStdout = false
+
+// JournaldOnStderr reports whether stderr is attached to journald
+var JournaldOnStderr = false
diff --git a/modules/log/color_console_other.go b/modules/log/color_console_other.go
index c30be41544..6573d093a5 100644
--- a/modules/log/color_console_other.go
+++ b/modules/log/color_console_other.go
@@ -1,20 +1,67 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !windows
-
package log
import (
"os"
+ "strconv"
+ "strings"
+ "syscall"
"github.com/mattn/go-isatty"
)
+func journaldDevIno() (uint64, uint64, bool) {
+ journaldStream := os.Getenv("JOURNAL_STREAM")
+ if len(journaldStream) == 0 {
+ return 0, 0, false
+ }
+ deviceStr, inodeStr, ok := strings.Cut(journaldStream, ":")
+ device, err1 := strconv.ParseUint(deviceStr, 10, 64)
+ inode, err2 := strconv.ParseUint(inodeStr, 10, 64)
+ if !ok || err1 != nil || err2 != nil {
+ return 0, 0, false
+ }
+ return device, inode, true
+}
+
+func fileStatDevIno(file *os.File) (uint64, uint64, bool) {
+ info, err := file.Stat()
+ if err != nil {
+ return 0, 0, false
+ }
+
+ stat, ok := info.Sys().(*syscall.Stat_t)
+ if !ok {
+ return 0, 0, false
+ }
+
+ // Do a type conversion to uint64, because Dev isn't always uint64
+ // on every operating system + architecture combination.
+ return uint64(stat.Dev), stat.Ino, true //nolint:unconvert
+}
+
+func fileIsDevIno(file *os.File, dev, ino uint64) bool {
+ fileDev, fileIno, ok := fileStatDevIno(file)
+ return ok && dev == fileDev && ino == fileIno
+}
+
func init() {
- // when running gitea as a systemd unit with logging set to console, the output can not be colorized,
- // otherwise it spams the journal / syslog with escape sequences like "#033[0m#033[32mcmd/web.go:102:#033[32m"
- // this file covers non-windows platforms.
+ // When forgejo is running under service supervisor (e.g. systemd) with logging
+ // set to console, the output streams are typically captured into some logging
+ // system (e.g. journald or syslog) instead of going to the terminal. Disable
+ // usage of ANSI escape sequences if that's the case to avoid spamming
+ // the journal or syslog with garbled mess e.g. `#033[0m#033[32mcmd/web.go:102:#033[32m`.
CanColorStdout = isatty.IsTerminal(os.Stdout.Fd())
CanColorStderr = isatty.IsTerminal(os.Stderr.Fd())
+
+ // Furthermore, check if we are running under journald specifically so that
+ // further output adjustments can be applied. Specifically, this changes
+ // the console logger defaults to disable duplication of date/time info and
+ // enable emission of special control sequences understood by journald
+ // instead of ANSI colors.
+ journalDev, journalIno, ok := journaldDevIno()
+ JournaldOnStdout = ok && !CanColorStdout && fileIsDevIno(os.Stdout, journalDev, journalIno)
+ JournaldOnStderr = ok && !CanColorStderr && fileIsDevIno(os.Stderr, journalDev, journalIno)
}
diff --git a/modules/log/color_console_windows.go b/modules/log/color_console_windows.go
deleted file mode 100644
index 3f59e934da..0000000000
--- a/modules/log/color_console_windows.go
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package log
-
-import (
- "os"
-
- "github.com/mattn/go-isatty"
- "golang.org/x/sys/windows"
-)
-
-func enableVTMode(console windows.Handle) bool {
- mode := uint32(0)
- err := windows.GetConsoleMode(console, &mode)
- if err != nil {
- return false
- }
-
- // EnableVirtualTerminalProcessing is the console mode to allow ANSI code
- // interpretation on the console. See:
- // https://docs.microsoft.com/en-us/windows/console/setconsolemode
- // It only works on Windows 10. Earlier terminals will fail with an err which we will
- // handle to say don't color
- mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
- err = windows.SetConsoleMode(console, mode)
- return err == nil
-}
-
-func init() {
- if isatty.IsTerminal(os.Stdout.Fd()) {
- CanColorStdout = enableVTMode(windows.Stdout)
- } else {
- CanColorStdout = isatty.IsCygwinTerminal(os.Stderr.Fd())
- }
-
- if isatty.IsTerminal(os.Stderr.Fd()) {
- CanColorStderr = enableVTMode(windows.Stderr)
- } else {
- CanColorStderr = isatty.IsCygwinTerminal(os.Stderr.Fd())
- }
-}
diff --git a/modules/log/event_format.go b/modules/log/event_format.go
index 583ddf66dd..df6b083a92 100644
--- a/modules/log/event_format.go
+++ b/modules/log/event_format.go
@@ -90,9 +90,17 @@ func colorSprintf(colorize bool, format string, args ...any) string {
// EventFormatTextMessage makes the log message for a writer with its mode. This function is a copy of the original package
func EventFormatTextMessage(mode *WriterMode, event *Event, msgFormat string, msgArgs ...any) []byte {
buf := make([]byte, 0, 1024)
- buf = append(buf, mode.Prefix...)
t := event.Time
flags := mode.Flags.Bits()
+
+ // if log level prefixes are enabled, the message must begin with the prefix, see sd_daemon(3)
+ // "A line that is not prefixed will be logged at the default log level SD_INFO"
+ if flags&Llevelprefix != 0 {
+ prefix := event.Level.JournalPrefix()
+ buf = append(buf, prefix...)
+ }
+
+ buf = append(buf, mode.Prefix...)
if flags&(Ldate|Ltime|Lmicroseconds) != 0 {
if mode.Colorize {
buf = append(buf, fgCyanBytes...)
diff --git a/modules/log/event_format_test.go b/modules/log/event_format_test.go
index 7c299a607d..0c6061eaea 100644
--- a/modules/log/event_format_test.go
+++ b/modules/log/event_format_test.go
@@ -35,7 +35,7 @@ func TestEventFormatTextMessage(t *testing.T) {
"msg format: %v %v", "arg0", NewColoredValue("arg1", FgBlue),
)
- assert.Equal(t, `[PREFIX] 2020/01/02 03:04:05.000000 filename:123:caller [E] [pid] msg format: arg0 arg1
+ assert.Equal(t, `<3>[PREFIX] 2020/01/02 03:04:05.000000 filename:123:caller [E] [pid] msg format: arg0 arg1
stacktrace
`, string(res))
@@ -53,5 +53,62 @@ func TestEventFormatTextMessage(t *testing.T) {
"msg format: %v %v", "arg0", NewColoredValue("arg1", FgBlue),
)
- assert.Equal(t, "[PREFIX] \x1b[36m2020/01/02 03:04:05.000000 \x1b[0m\x1b[32mfilename:123:\x1b[32mcaller\x1b[0m \x1b[1;31m[E]\x1b[0m [\x1b[93mpid\x1b[0m] msg format: arg0 \x1b[34marg1\x1b[0m\n\tstacktrace\n\n", string(res))
+ assert.Equal(t, "<3>[PREFIX] \x1b[36m2020/01/02 03:04:05.000000 \x1b[0m\x1b[32mfilename:123:\x1b[32mcaller\x1b[0m \x1b[1;31m[E]\x1b[0m [\x1b[93mpid\x1b[0m] msg format: arg0 \x1b[34marg1\x1b[0m\n\tstacktrace\n\n", string(res))
+}
+
+func TestEventFormatTextMessageStd(t *testing.T) {
+ res := EventFormatTextMessage(&WriterMode{Prefix: "[PREFIX] ", Colorize: false, Flags: Flags{defined: true, flags: LstdFlags}},
+ &Event{
+ Time: time.Date(2020, 1, 2, 3, 4, 5, 6, time.UTC),
+ Caller: "caller",
+ Filename: "filename",
+ Line: 123,
+ GoroutinePid: "pid",
+ Level: ERROR,
+ Stacktrace: "stacktrace",
+ },
+ "msg format: %v %v", "arg0", NewColoredValue("arg1", FgBlue),
+ )
+
+ assert.Equal(t, `[PREFIX] 2020/01/02 03:04:05 filename:123:caller [E] msg format: arg0 arg1
+ stacktrace
+
+`, string(res))
+
+ res = EventFormatTextMessage(&WriterMode{Prefix: "[PREFIX] ", Colorize: true, Flags: Flags{defined: true, flags: LstdFlags}},
+ &Event{
+ Time: time.Date(2020, 1, 2, 3, 4, 5, 6, time.UTC),
+ Caller: "caller",
+ Filename: "filename",
+ Line: 123,
+ GoroutinePid: "pid",
+ Level: ERROR,
+ Stacktrace: "stacktrace",
+ },
+ "msg format: %v %v", "arg0", NewColoredValue("arg1", FgBlue),
+ )
+
+ assert.Equal(t, "[PREFIX] \x1b[36m2020/01/02 03:04:05 \x1b[0m\x1b[32mfilename:123:\x1b[32mcaller\x1b[0m \x1b[1;31m[E]\x1b[0m msg format: arg0 \x1b[34marg1\x1b[0m\n\tstacktrace\n\n", string(res))
+}
+
+func TestEventFormatTextMessageJournal(t *testing.T) {
+ // TODO: it makes no sense to emit \n-containing messages to journal as they will get mangled
+ // the proper way here is to attach the backtrace as structured metadata, but we can't do that via stderr
+ res := EventFormatTextMessage(&WriterMode{Prefix: "[PREFIX] ", Colorize: false, Flags: Flags{defined: true, flags: LjournaldFlags}},
+ &Event{
+ Time: time.Date(2020, 1, 2, 3, 4, 5, 6, time.UTC),
+ Caller: "caller",
+ Filename: "filename",
+ Line: 123,
+ GoroutinePid: "pid",
+ Level: ERROR,
+ Stacktrace: "stacktrace",
+ },
+ "msg format: %v %v", "arg0", NewColoredValue("arg1", FgBlue),
+ )
+
+ assert.Equal(t, `<3>[PREFIX] msg format: arg0 arg1
+ stacktrace
+
+`, string(res))
}
diff --git a/modules/log/event_writer_buffer.go b/modules/log/event_writer_buffer.go
new file mode 100644
index 0000000000..28857c2189
--- /dev/null
+++ b/modules/log/event_writer_buffer.go
@@ -0,0 +1,22 @@
+// Copyright 2025 The Forgejo Authors.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package log
+
+import (
+ "bytes"
+)
+
+type EventWriterBuffer struct {
+ *EventWriterBaseImpl
+ Buffer *bytes.Buffer
+}
+
+var _ EventWriter = (*EventWriterBuffer)(nil)
+
+func NewEventWriterBuffer(name string, mode WriterMode) *EventWriterBuffer {
+ w := &EventWriterBuffer{EventWriterBaseImpl: NewEventWriterBase(name, "buffer", mode)}
+ w.Buffer = new(bytes.Buffer)
+ w.OutputWriteCloser = nopCloser{w.Buffer}
+ return w
+}
diff --git a/modules/log/event_writer_buffer_test.go b/modules/log/event_writer_buffer_test.go
new file mode 100644
index 0000000000..ba9455ba69
--- /dev/null
+++ b/modules/log/event_writer_buffer_test.go
@@ -0,0 +1,33 @@
+// Copyright 2025 The Forgejo Authors.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package log_test
+
+import (
+ "testing"
+
+ "forgejo.org/modules/log"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestBufferLogger(t *testing.T) {
+ prefix := "TestPrefix "
+ level := log.INFO
+ expected := "something"
+
+ bufferWriter := log.NewEventWriterBuffer("test-buffer", log.WriterMode{
+ Level: level,
+ Prefix: prefix,
+ Expression: expected,
+ })
+
+ logger := log.NewLoggerWithWriters(t.Context(), "test", bufferWriter)
+
+ logger.SendLogEvent(&log.Event{
+ Level: log.INFO,
+ MsgSimpleText: expected,
+ })
+ logger.Close()
+ assert.Contains(t, bufferWriter.Buffer.String(), expected)
+}
diff --git a/modules/log/event_writer_conn_test.go b/modules/log/event_writer_conn_test.go
index 69e87aa8c4..0cf447149a 100644
--- a/modules/log/event_writer_conn_test.go
+++ b/modules/log/event_writer_conn_test.go
@@ -4,7 +4,6 @@
package log
import (
- "context"
"fmt"
"io"
"net"
@@ -14,15 +13,16 @@ import (
"time"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func listenReadAndClose(t *testing.T, l net.Listener, expected string) {
conn, err := l.Accept()
- assert.NoError(t, err)
+ require.NoError(t, err)
defer conn.Close()
written, err := io.ReadAll(conn)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, string(written))
}
@@ -40,7 +40,7 @@ func TestConnLogger(t *testing.T) {
level := INFO
flags := LstdFlags | LUTC | Lfuncname
- logger := NewLoggerWithWriters(context.Background(), "test", NewEventWriterConn("test-conn", WriterMode{
+ logger := NewLoggerWithWriters(t.Context(), "test", NewEventWriterConn("test-conn", WriterMode{
Level: level,
Prefix: prefix,
Flags: FlagsFromBits(flags),
diff --git a/modules/log/event_writer_file.go b/modules/log/event_writer_file.go
index fd73d7d30a..fd7189e2df 100644
--- a/modules/log/event_writer_file.go
+++ b/modules/log/event_writer_file.go
@@ -6,7 +6,7 @@ package log
import (
"io"
- "code.gitea.io/gitea/modules/util/rotatingfilewriter"
+ "forgejo.org/modules/util/rotatingfilewriter"
)
type WriterFileOption struct {
diff --git a/modules/log/flags.go b/modules/log/flags.go
index f025159d53..afce30680d 100644
--- a/modules/log/flags.go
+++ b/modules/log/flags.go
@@ -7,7 +7,7 @@ import (
"sort"
"strings"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
)
// These flags define which text to prefix to each log entry generated
@@ -31,9 +31,11 @@ const (
Llevelinitial // Initial character of the provided level in brackets, eg. [I] for info
Llevel // Provided level in brackets [INFO]
Lgopid // the Goroutine-PID of the context
+ Llevelprefix // printk-style logging prefixes as documented in sd-daemon(3), used by journald
- Lmedfile = Lshortfile | Llongfile // last 20 characters of the filename
- LstdFlags = Ldate | Ltime | Lmedfile | Lshortfuncname | Llevelinitial // default
+ Lmedfile = Lshortfile | Llongfile // last 20 characters of the filename
+ LstdFlags = Ldate | Ltime | Lmedfile | Lshortfuncname | Llevelinitial // default
+ LjournaldFlags = Llevelprefix
)
const Ldefault = LstdFlags
@@ -54,10 +56,12 @@ var flagFromString = map[string]uint32{
"utc": LUTC,
"levelinitial": Llevelinitial,
"level": Llevel,
+ "levelprefix": Llevelprefix,
"gopid": Lgopid,
- "medfile": Lmedfile,
- "stdflags": LstdFlags,
+ "medfile": Lmedfile,
+ "stdflags": LstdFlags,
+ "journaldflags": LjournaldFlags,
}
var flagComboToString = []struct {
diff --git a/modules/log/flags_test.go b/modules/log/flags_test.go
index 03972a9fb0..1ee322c630 100644
--- a/modules/log/flags_test.go
+++ b/modules/log/flags_test.go
@@ -6,9 +6,10 @@ package log
import (
"testing"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestFlags(t *testing.T) {
@@ -22,9 +23,9 @@ func TestFlags(t *testing.T) {
assert.EqualValues(t, "medfile", FlagsFromString("medfile").String())
bs, err := json.Marshal(FlagsFromString("utc,level"))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, `"level,utc"`, string(bs))
var flags Flags
- assert.NoError(t, json.Unmarshal(bs, &flags))
+ require.NoError(t, json.Unmarshal(bs, &flags))
assert.EqualValues(t, LUTC|Llevel, flags.Bits())
}
diff --git a/modules/log/groutinelabel.go b/modules/log/groutinelabel.go
index 56d7af42da..cd5fb96d52 100644
--- a/modules/log/groutinelabel.go
+++ b/modules/log/groutinelabel.go
@@ -1,3 +1,5 @@
+//go:build !go1.24
+
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
diff --git a/modules/log/groutinelabel_go1.24.go b/modules/log/groutinelabel_go1.24.go
new file mode 100644
index 0000000000..e849811bc2
--- /dev/null
+++ b/modules/log/groutinelabel_go1.24.go
@@ -0,0 +1,38 @@
+//go:build go1.24
+
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package log
+
+import "unsafe"
+
+//go:linkname runtime_getProfLabel runtime/pprof.runtime_getProfLabel
+func runtime_getProfLabel() unsafe.Pointer //nolint
+
+// Struct definitions copied from: https://github.com/golang/go/blob/ca63101df47a4467bc80faa654fc19d68e583952/src/runtime/pprof/label.go
+type label struct {
+ key string
+ value string
+}
+
+type LabelSet struct {
+ list []label
+}
+
+type labelMap struct {
+ LabelSet
+}
+
+func getGoroutineLabels() map[string]string {
+ l := (*labelMap)(runtime_getProfLabel())
+ if l == nil {
+ return nil
+ }
+
+ m := make(map[string]string, len(l.list))
+ for _, label := range l.list {
+ m[label.key] = label.value
+ }
+ return m
+}
diff --git a/modules/log/groutinelabel_test.go b/modules/log/groutinelabel_test.go
index 34e99653d6..df8c1e9259 100644
--- a/modules/log/groutinelabel_test.go
+++ b/modules/log/groutinelabel_test.go
@@ -12,7 +12,7 @@ import (
)
func Test_getGoroutineLabels(t *testing.T) {
- pprof.Do(context.Background(), pprof.Labels(), func(ctx context.Context) {
+ pprof.Do(t.Context(), pprof.Labels(), func(ctx context.Context) {
currentLabels := getGoroutineLabels()
pprof.ForLabels(ctx, func(key, value string) bool {
assert.EqualValues(t, value, currentLabels[key])
diff --git a/modules/log/init.go b/modules/log/init.go
index 3fb5200ad7..4c6b7b5f82 100644
--- a/modules/log/init.go
+++ b/modules/log/init.go
@@ -8,8 +8,8 @@ import (
"runtime"
"strings"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/util/rotatingfilewriter"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/util/rotatingfilewriter"
)
var projectPackagePrefix string
diff --git a/modules/log/level.go b/modules/log/level.go
index 01fa3f5e46..2ad1d67f1a 100644
--- a/modules/log/level.go
+++ b/modules/log/level.go
@@ -7,7 +7,7 @@ import (
"bytes"
"strings"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
)
// Level is the level of the logger
@@ -39,6 +39,22 @@ var toString = map[Level]string{
NONE: "none",
}
+// Machine-readable log level prefixes as defined in sd-daemon(3).
+//
+// "If a systemd service definition file is configured with StandardError=journal
+// or StandardError=kmsg (and similar with StandardOutput=), these prefixes can
+// be used to encode a log level in lines printed. <...> To use these prefixes
+// simply prefix every line with one of these strings. A line that is not prefixed
+// will be logged at the default log level SD_INFO."
+var toJournalPrefix = map[Level]string{
+ TRACE: "<7>", // SD_DEBUG
+ DEBUG: "<6>", // SD_INFO
+ INFO: "<5>", // SD_NOTICE
+ WARN: "<4>", // SD_WARNING
+ ERROR: "<3>", // SD_ERR
+ FATAL: "<2>", // SD_CRIT
+}
+
var toLevel = map[string]Level{
"undefined": UNDEFINED,
@@ -71,6 +87,10 @@ func (l Level) String() string {
return "info"
}
+func (l Level) JournalPrefix() string {
+ return toJournalPrefix[l]
+}
+
func (l Level) ColorAttributes() []ColorAttribute {
color, ok := levelToColor[l]
if ok {
diff --git a/modules/log/level_test.go b/modules/log/level_test.go
index cd18a807d8..e6cacc723b 100644
--- a/modules/log/level_test.go
+++ b/modules/log/level_test.go
@@ -7,9 +7,10 @@ import (
"fmt"
"testing"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
type testLevel struct {
@@ -20,34 +21,34 @@ func TestLevelMarshalUnmarshalJSON(t *testing.T) {
levelBytes, err := json.Marshal(testLevel{
Level: INFO,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, string(makeTestLevelBytes(INFO.String())), string(levelBytes))
var testLevel testLevel
err = json.Unmarshal(levelBytes, &testLevel)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, INFO, testLevel.Level)
err = json.Unmarshal(makeTestLevelBytes(`FOFOO`), &testLevel)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, INFO, testLevel.Level)
err = json.Unmarshal([]byte(fmt.Sprintf(`{"level":%d}`, 2)), &testLevel)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, INFO, testLevel.Level)
err = json.Unmarshal([]byte(fmt.Sprintf(`{"level":%d}`, 10012)), &testLevel)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, INFO, testLevel.Level)
err = json.Unmarshal([]byte(`{"level":{}}`), &testLevel)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, INFO, testLevel.Level)
assert.Equal(t, INFO.String(), Level(1001).String())
err = json.Unmarshal([]byte(`{"level":{}`), &testLevel.Level)
- assert.Error(t, err)
+ require.Error(t, err)
}
func makeTestLevelBytes(level string) []byte {
diff --git a/modules/log/logger_impl.go b/modules/log/logger_impl.go
index d38c6516ed..b21e800f52 100644
--- a/modules/log/logger_impl.go
+++ b/modules/log/logger_impl.go
@@ -11,8 +11,8 @@ import (
"sync/atomic"
"time"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/util"
)
type LoggerImpl struct {
@@ -191,7 +191,7 @@ func (l *LoggerImpl) Log(skip int, level Level, format string, logArgs ...any) {
if ok {
fn := runtime.FuncForPC(pc)
if fn != nil {
- event.Caller = fn.Name() + "()"
+ event.Caller = strings.TrimSuffix(fn.Name(), "[...]") + "()"
}
}
event.Filename, event.Line = strings.TrimPrefix(filename, projectPackagePrefix), line
diff --git a/modules/log/logger_impl_test.go b/modules/log/logger_impl_test.go
new file mode 100644
index 0000000000..59276a83f4
--- /dev/null
+++ b/modules/log/logger_impl_test.go
@@ -0,0 +1,27 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package log
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func testGeneric[T any](log *LoggerImpl, t T) {
+ log.Log(0, INFO, "Just testing the logging of a generic function %v", t)
+}
+
+func TestLog(t *testing.T) {
+ bufferWriter := NewEventWriterBuffer("test-buffer", WriterMode{
+ Level: INFO,
+ })
+
+ logger := NewLoggerWithWriters(t.Context(), "test", bufferWriter)
+
+ testGeneric(logger, "I'm the generic value!")
+ logger.Close()
+
+ assert.Contains(t, bufferWriter.Buffer.String(), ".../logger_impl_test.go:13:testGeneric() [I] Just testing the logging of a generic function I'm the generic value!")
+}
diff --git a/modules/log/logger_test.go b/modules/log/logger_test.go
index 70222f64f5..e04c9da8b0 100644
--- a/modules/log/logger_test.go
+++ b/modules/log/logger_test.go
@@ -4,7 +4,6 @@
package log
import (
- "context"
"sync"
"testing"
"time"
@@ -53,10 +52,10 @@ func newDummyWriter(name string, level Level, delay time.Duration) *dummyWriter
}
func TestLogger(t *testing.T) {
- logger := NewLoggerWithWriters(context.Background(), "test")
+ logger := NewLoggerWithWriters(t.Context(), "test")
dump := logger.DumpWriters()
- assert.EqualValues(t, 0, len(dump))
+ assert.Empty(t, dump)
assert.EqualValues(t, NONE, logger.GetLevel())
assert.False(t, logger.IsEnabled())
@@ -69,7 +68,7 @@ func TestLogger(t *testing.T) {
assert.EqualValues(t, DEBUG, logger.GetLevel())
dump = logger.DumpWriters()
- assert.EqualValues(t, 2, len(dump))
+ assert.Len(t, dump, 2)
logger.Trace("trace-level") // this level is not logged
logger.Debug("debug-level")
@@ -88,7 +87,7 @@ func TestLogger(t *testing.T) {
}
func TestLoggerPause(t *testing.T) {
- logger := NewLoggerWithWriters(context.Background(), "test")
+ logger := NewLoggerWithWriters(t.Context(), "test")
w1 := newDummyWriter("dummy-1", DEBUG, 0)
logger.AddWriters(w1)
@@ -117,7 +116,7 @@ func (t testLogString) LogString() string {
}
func TestLoggerLogString(t *testing.T) {
- logger := NewLoggerWithWriters(context.Background(), "test")
+ logger := NewLoggerWithWriters(t.Context(), "test")
w1 := newDummyWriter("dummy-1", DEBUG, 0)
w1.Mode.Colorize = true
@@ -130,7 +129,7 @@ func TestLoggerLogString(t *testing.T) {
}
func TestLoggerExpressionFilter(t *testing.T) {
- logger := NewLoggerWithWriters(context.Background(), "test")
+ logger := NewLoggerWithWriters(t.Context(), "test")
w1 := newDummyWriter("dummy-1", DEBUG, 0)
w1.Mode.Expression = "foo.*"
diff --git a/modules/log/manager_test.go b/modules/log/manager_test.go
index b8fbf84613..3839080172 100644
--- a/modules/log/manager_test.go
+++ b/modules/log/manager_test.go
@@ -7,6 +7,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestSharedWorker(t *testing.T) {
@@ -16,7 +17,7 @@ func TestSharedWorker(t *testing.T) {
m := NewManager()
_, err := m.NewSharedWriter("dummy-1", "dummy", WriterMode{Level: DEBUG, Flags: FlagsFromBits(0)})
- assert.NoError(t, err)
+ require.NoError(t, err)
w := m.GetSharedWriter("dummy-1")
assert.NotNil(t, w)
diff --git a/modules/markup/asciicast/asciicast.go b/modules/markup/asciicast/asciicast.go
index 0678062340..739a035977 100644
--- a/modules/markup/asciicast/asciicast.go
+++ b/modules/markup/asciicast/asciicast.go
@@ -9,8 +9,8 @@ import (
"net/url"
"regexp"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/setting"
)
func init() {
@@ -39,7 +39,7 @@ const (
// SanitizerRules implements markup.Renderer
func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
return []setting.MarkupSanitizerRule{
- {Element: "div", AllowAttr: "class", Regexp: regexp.MustCompile(playerClassName)},
+ {Element: "div", AllowAttr: "class", Regexp: regexp.MustCompile("^" + playerClassName + "$")},
{Element: "div", AllowAttr: playerSrcAttr},
}
}
diff --git a/modules/markup/camo.go b/modules/markup/camo.go
index e93797de2b..8380f79280 100644
--- a/modules/markup/camo.go
+++ b/modules/markup/camo.go
@@ -10,8 +10,8 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
// CamoEncode encodes a lnk to fit with the go-camo and camo proxy links. The purposes of camo-proxy are:
@@ -38,7 +38,7 @@ func camoHandleLink(link string) string {
if setting.Camo.Enabled {
lnkURL, err := url.Parse(link)
if err == nil && lnkURL.IsAbs() && !strings.HasPrefix(link, setting.AppURL) &&
- (setting.Camo.Allways || lnkURL.Scheme != "https") {
+ (setting.Camo.Always || lnkURL.Scheme != "https") {
return CamoEncode(link)
}
}
diff --git a/modules/markup/camo_test.go b/modules/markup/camo_test.go
index ba58835221..d5600996c9 100644
--- a/modules/markup/camo_test.go
+++ b/modules/markup/camo_test.go
@@ -6,7 +6,7 @@ package markup
import (
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
)
@@ -28,7 +28,7 @@ func TestCamoHandleLink(t *testing.T) {
"https://image.proxy/eivin43gJwGVIjR9MiYYtFIk0mw/aHR0cDovL3Rlc3RpbWFnZXMub3JnL2ltZy5qcGc",
camoHandleLink("http://testimages.org/img.jpg"))
- setting.Camo.Allways = true
+ setting.Camo.Always = true
assert.Equal(t,
"https://gitea.com/img.jpg",
camoHandleLink("https://gitea.com/img.jpg"))
diff --git a/modules/markup/console/console.go b/modules/markup/console/console.go
index cf42c9cceb..c61b6495d3 100644
--- a/modules/markup/console/console.go
+++ b/modules/markup/console/console.go
@@ -10,8 +10,8 @@ import (
"regexp"
"strings"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/setting"
trend "github.com/buildkite/terminal-to-html/v3"
"github.com/go-enry/go-enry/v2"
@@ -58,13 +58,16 @@ func (Renderer) CanRender(filename string, input io.Reader) bool {
// Render renders terminal colors to HTML with all specific handling stuff.
func (Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error {
- buf, err := io.ReadAll(input)
+ screen, err := trend.NewScreen()
if err != nil {
return err
}
- buf = trend.Render(buf)
- buf = bytes.ReplaceAll(buf, []byte("\n"), []byte(` `))
- _, err = output.Write(buf)
+ if _, err := io.Copy(screen, input); err != nil {
+ return err
+ }
+ buf := screen.AsHTML()
+ buf = strings.ReplaceAll(buf, "\n", ` `)
+ _, err = output.Write([]byte(buf))
return err
}
diff --git a/modules/markup/console/console_test.go b/modules/markup/console/console_test.go
index 2337d91ac5..11e0a54e5d 100644
--- a/modules/markup/console/console_test.go
+++ b/modules/markup/console/console_test.go
@@ -7,10 +7,11 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/markup"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/markup"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRenderConsole(t *testing.T) {
@@ -26,7 +27,7 @@ func TestRenderConsole(t *testing.T) {
err := render.Render(&markup.RenderContext{Ctx: git.DefaultContext},
strings.NewReader(k), &buf)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, v, buf.String())
}
}
diff --git a/modules/markup/csv/csv.go b/modules/markup/csv/csv.go
index 3d952b0de4..6a05088ae1 100644
--- a/modules/markup/csv/csv.go
+++ b/modules/markup/csv/csv.go
@@ -10,11 +10,11 @@ import (
"regexp"
"strconv"
- "code.gitea.io/gitea/modules/csv"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/csv"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/util"
)
func init() {
@@ -37,9 +37,9 @@ func (Renderer) Extensions() []string {
// SanitizerRules implements markup.Renderer
func (Renderer) SanitizerRules() []setting.MarkupSanitizerRule {
return []setting.MarkupSanitizerRule{
- {Element: "table", AllowAttr: "class", Regexp: regexp.MustCompile(`data-table`)},
- {Element: "th", AllowAttr: "class", Regexp: regexp.MustCompile(`line-num`)},
- {Element: "td", AllowAttr: "class", Regexp: regexp.MustCompile(`line-num`)},
+ {Element: "table", AllowAttr: "class", Regexp: regexp.MustCompile(`^data-table$`)},
+ {Element: "th", AllowAttr: "class", Regexp: regexp.MustCompile(`^line-num$`)},
+ {Element: "td", AllowAttr: "class", Regexp: regexp.MustCompile(`^line-num$`)},
}
}
diff --git a/modules/markup/csv/csv_test.go b/modules/markup/csv/csv_test.go
index 8c07184b21..008a899c05 100644
--- a/modules/markup/csv/csv_test.go
+++ b/modules/markup/csv/csv_test.go
@@ -7,10 +7,11 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/markup"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/markup"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRenderCSV(t *testing.T) {
@@ -26,7 +27,7 @@ func TestRenderCSV(t *testing.T) {
var buf strings.Builder
err := render.Render(&markup.RenderContext{Ctx: git.DefaultContext},
strings.NewReader(k), &buf)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, v, buf.String())
}
}
diff --git a/modules/markup/external/external.go b/modules/markup/external/external.go
index 122517ed11..950da6e828 100644
--- a/modules/markup/external/external.go
+++ b/modules/markup/external/external.go
@@ -9,15 +9,15 @@ import (
"io"
"os"
"os/exec"
- "runtime"
"strings"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/annex"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
// RegisterRenderers registers all supported third part renderers according settings
@@ -70,9 +70,6 @@ func (p *Renderer) DisplayInIFrame() bool {
}
func envMark(envName string) string {
- if runtime.GOOS == "windows" {
- return "%" + envName + "%"
- }
return "$" + envName
}
@@ -86,8 +83,22 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
commands = strings.Fields(command)
args = commands[1:]
)
-
- if p.IsInputFile {
+ isAnnexed, _ := annex.IsAnnexed(ctx.Blob)
+ // if a renderer wants to read a file, and we have annexed content, we can
+ // provide the annex key file location directly to the renderer. git-annex
+ // takes care of having that location be read-only, so no critical
+ // protection layer is needed. Moreover, the file readily exists, and
+ // expensive temporary files can be avoided, also allowing an operator
+ // to raise MAX_DISPLAY_FILE_SIZE without much negative impact.
+ if p.IsInputFile && isAnnexed {
+ // look for annexed content, will be empty, if there is none
+ annexContentLocation, _ := annex.ContentLocation(ctx.Blob)
+ // we call the renderer, even if there is no annex content present.
+ // showing the pointer file content is not much use, and a topical
+ // renderer might be able to produce something useful from the
+ // filename alone (present in ENV)
+ args = append(args, annexContentLocation)
+ } else if p.IsInputFile {
// write to temp file
f, err := os.CreateTemp("", "gitea_input")
if err != nil {
@@ -130,6 +141,12 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.
os.Environ(),
"GITEA_PREFIX_SRC="+ctx.Links.SrcLink(),
"GITEA_PREFIX_RAW="+ctx.Links.RawLink(),
+ // also communicate the relative path of the to-be-rendered item.
+ // this enables the renderer to make use of the original file name
+ // and path, e.g., to make rendering or dtype-detection decisions
+ // that go beyond the originally matched extension. Even if the
+ // content is directly streamed to STDIN
+ "GITEA_RELATIVE_PATH="+ctx.RelativePath,
)
if !p.IsInputFile {
cmd.Stdin = input
diff --git a/modules/markup/file_preview.go b/modules/markup/file_preview.go
index 993df717e1..5499eff18c 100644
--- a/modules/markup/file_preview.go
+++ b/modules/markup/file_preview.go
@@ -7,16 +7,18 @@ import (
"bufio"
"bytes"
"html/template"
+ "io"
+ "net/url"
"regexp"
"slices"
"strconv"
"strings"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/highlight"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/highlight"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
"golang.org/x/net/html"
"golang.org/x/net/html/atom"
@@ -76,6 +78,16 @@ func newFilePreview(ctx *RenderContext, node *html.Node, locale translation.Loca
commitSha := node.Data[m[4]:m[5]]
filePath := node.Data[m[6]:m[7]]
+ urlFullSource := urlFull
+ if strings.HasSuffix(filePath, "?display=source") {
+ filePath = strings.TrimSuffix(filePath, "?display=source")
+ } else if Type(filePath) != "" {
+ urlFullSource = node.Data[m[0]:m[6]] + filePath + "?display=source#" + node.Data[m[8]:m[1]]
+ }
+ filePath, err := url.QueryUnescape(filePath)
+ if err != nil {
+ return nil
+ }
hash := node.Data[m[8]:m[9]]
preview.start = m[0]
@@ -112,7 +124,7 @@ func newFilePreview(ctx *RenderContext, node *html.Node, locale translation.Loca
titleBuffer.WriteString(" – ")
}
- err = html.Render(titleBuffer, createLink(urlFull, filePath, "muted"))
+ err = html.Render(titleBuffer, createLink(urlFullSource, filePath, "muted"))
if err != nil {
log.Error("failed to render filepathLink: %v", err)
}
@@ -184,10 +196,12 @@ func newFilePreview(ctx *RenderContext, node *html.Node, locale translation.Loca
lineBuffer := new(bytes.Buffer)
for i := 0; i < lineCount; i++ {
buf, err := reader.ReadBytes('\n')
+ if err == nil || err == io.EOF {
+ lineBuffer.Write(buf)
+ }
if err != nil {
break
}
- lineBuffer.Write(buf)
}
// highlight the file...
diff --git a/modules/markup/html.go b/modules/markup/html.go
index b5c0e405ae..e7be453ea3 100644
--- a/modules/markup/html.go
+++ b/modules/markup/html.go
@@ -1,4 +1,5 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
+// Copyright 2025 The Forgejo Authors.
// SPDX-License-Identifier: MIT
package markup
@@ -13,17 +14,17 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/emoji"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup/common"
- "code.gitea.io/gitea/modules/references"
- "code.gitea.io/gitea/modules/regexplru"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates/vars"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/emoji"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup/common"
+ "forgejo.org/modules/references"
+ "forgejo.org/modules/regexplru"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates/vars"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/util"
"golang.org/x/net/html"
"golang.org/x/net/html/atom"
@@ -48,13 +49,13 @@ var (
// hashCurrentPattern matches string that represents a commit SHA, e.g. d8a994ef243349f321568f9e36d5c3f444b99cae
// Although SHA1 hashes are 40 chars long, SHA256 are 64, the regex matches the hash from 7 to 64 chars in length
// so that abbreviated hash links can be used as well. This matches git and GitHub usability.
- hashCurrentPattern = regexp.MustCompile(`(?:\s|^|\(|\[)([0-9a-f]{7,64})(?:\s|$|\)|\]|[.,:](\s|$))`)
+ hashCurrentPattern = regexp.MustCompile(`(?:^|\s)[^\w\d]{0,2}([0-9a-f]{7,64})[^\w\d]{0,2}(?:\s|$)`)
// shortLinkPattern matches short but difficult to parse [[name|link|arg=test]] syntax
shortLinkPattern = regexp.MustCompile(`\[\[(.*?)\]\](\w*)`)
- // anySHA1Pattern splits url containing SHA into parts
- anyHashPattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{40,64})(/[-+~_%.a-zA-Z0-9/]+)?(\?[-+~_%\.a-zA-Z0-9=&]+)?(#[-+~_%.a-zA-Z0-9]+)?`)
+ // anyHashPattern splits url containing SHA into parts
+ anyHashPattern = regexp.MustCompile(`https?://(?:(?:\S+/){3,4}(?:commit|tree|blob)/)([0-9a-f]{7,64})(/[-+~_%.a-zA-Z0-9/]+)?(\?[-+~_%\.a-zA-Z0-9=&]+)?(#[-+~_%.a-zA-Z0-9]+)?`)
// comparePattern matches "http://domain/org/repo/compare/COMMIT1...COMMIT2#hash"
comparePattern = regexp.MustCompile(`https?://(?:\S+/){4,5}([0-9a-f]{7,64})(\.\.\.?)([0-9a-f]{7,64})?(#[-+~_%.a-zA-Z0-9]+)?`)
@@ -73,6 +74,8 @@ var (
// EmojiShortCodeRegex find emoji by alias like :smile:
EmojiShortCodeRegex = regexp.MustCompile(`:[-+\w]+:`)
+
+ InlineCodeBlockRegex = regexp.MustCompile("`[^`]+`")
)
// CSS class for action keywords (e.g. "closes: #1")
@@ -93,30 +96,15 @@ var issueFullPattern *regexp.Regexp
// Once for to prevent races
var issueFullPatternOnce sync.Once
-// regexp for full links to hash comment in pull request files changed tab
-var filesChangedFullPattern *regexp.Regexp
-
-// Once for to prevent races
-var filesChangedFullPatternOnce sync.Once
-
func getIssueFullPattern() *regexp.Regexp {
issueFullPatternOnce.Do(func() {
// example: https://domain/org/repo/pulls/27#hash
issueFullPattern = regexp.MustCompile(regexp.QuoteMeta(setting.AppURL) +
- `[\w_.-]+/[\w_.-]+/(?:issues|pulls)/((?:\w{1,10}-)?[1-9][0-9]*)([\?|#](\S+)?)?\b`)
+ `(?P[\w_.-]+)\/(?P[\w_.-]+)\/(?:issues|pulls)\/(?P(?:\w{1,10}-)?[1-9][0-9]*)(?P\/[\w_.-]+)?(?:(?P#(?:issue|issuecomment)-\d+)|(?:[\?#](?:\S+)?))?\b`)
})
return issueFullPattern
}
-func getFilesChangedFullPattern() *regexp.Regexp {
- filesChangedFullPatternOnce.Do(func() {
- // example: https://domain/org/repo/pulls/27/files#hash
- filesChangedFullPattern = regexp.MustCompile(regexp.QuoteMeta(setting.AppURL) +
- `[\w_.-]+/[\w_.-]+/pulls/((?:\w{1,10}-)?[1-9][0-9]*)/files([\?|#](\S+)?)?\b`)
- })
- return filesChangedFullPattern
-}
-
// CustomLinkURLSchemes allows for additional schemes to be detected when parsing links within text
func CustomLinkURLSchemes(schemes []string) {
schemes = append(schemes, "http", "https")
@@ -258,6 +246,7 @@ func RenderIssueTitle(
title string,
) (string, error) {
return renderProcessString(ctx, []processor{
+ inlineCodeBlockProcessor,
issueIndexPatternProcessor,
commitCrossReferencePatternProcessor,
hashCurrentPatternProcessor,
@@ -266,6 +255,19 @@ func RenderIssueTitle(
}, title)
}
+// RenderRefIssueTitle to process title on places where an issue is referenced
+func RenderRefIssueTitle(
+ ctx *RenderContext,
+ title string,
+) (string, error) {
+ return renderProcessString(ctx, []processor{
+ inlineCodeBlockProcessor,
+ issueIndexPatternProcessor,
+ emojiShortCodeProcessor,
+ emojiProcessor,
+ }, title)
+}
+
func renderProcessString(ctx *RenderContext, procs []processor, content string) (string, error) {
var buf strings.Builder
if err := postProcess(ctx, procs, strings.NewReader(content), &buf); err != nil {
@@ -453,7 +455,25 @@ func createKeyword(content string) *html.Node {
return span
}
-func createEmoji(content, class, name string) *html.Node {
+func createInlineCode(content string) *html.Node {
+ code := &html.Node{
+ Type: html.ElementNode,
+ Data: atom.Code.String(),
+ Attr: []html.Attribute{},
+ }
+
+ code.Attr = append(code.Attr, html.Attribute{Key: "class", Val: "inline-code-block"})
+
+ text := &html.Node{
+ Type: html.TextNode,
+ Data: content,
+ }
+
+ code.AppendChild(text)
+ return code
+}
+
+func createEmoji(content, class, name, alias string) *html.Node {
span := &html.Node{
Type: html.ElementNode,
Data: atom.Span.String(),
@@ -465,6 +485,9 @@ func createEmoji(content, class, name string) *html.Node {
if name != "" {
span.Attr = append(span.Attr, html.Attribute{Key: "aria-label", Val: name})
}
+ if alias != "" {
+ span.Attr = append(span.Attr, html.Attribute{Key: "data-alias", Val: alias})
+ }
text := &html.Node{
Type: html.TextNode,
@@ -483,6 +506,7 @@ func createCustomEmoji(alias string) *html.Node {
}
span.Attr = append(span.Attr, html.Attribute{Key: "class", Val: "emoji"})
span.Attr = append(span.Attr, html.Attribute{Key: "aria-label", Val: alias})
+ span.Attr = append(span.Attr, html.Attribute{Key: "data-alias", Val: alias})
img := &html.Node{
Type: html.ElementNode,
@@ -736,9 +760,6 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
title = path.Base(name)
}
alt := props["alt"]
- if alt == "" {
- alt = name
- }
// make the childNode an image - if we can, we also place the alt
childNode.Type = html.ElementNode
@@ -749,9 +770,6 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) {
{Key: "title", Val: title},
{Key: "alt", Val: alt},
}
- if alt == "" {
- childNode.Attr = childNode.Attr[:2]
- }
} else {
if !absoluteLink {
if ctx.IsWiki {
@@ -775,22 +793,16 @@ func fullIssuePatternProcessor(ctx *RenderContext, node *html.Node) {
}
next := node.NextSibling
for node != nil && node != next {
- m := getIssueFullPattern().FindStringSubmatchIndex(node.Data)
- if m == nil {
+ re := getIssueFullPattern()
+ linkIndex, m := re.FindStringIndex(node.Data), re.FindStringSubmatch(node.Data)
+ if linkIndex == nil || m == nil {
return
}
- mDiffView := getFilesChangedFullPattern().FindStringSubmatchIndex(node.Data)
- // leave it as it is if the link is from "Files Changed" tab in PR Diff View https://domain/org/repo/pulls/27/files
- if mDiffView != nil {
- return
- }
+ link := node.Data[linkIndex[0]:linkIndex[1]]
+ text := "#" + m[re.SubexpIndex("num")] + m[re.SubexpIndex("subpath")]
- link := node.Data[m[0]:m[1]]
- text := "#" + node.Data[m[2]:m[3]]
- // if m[4] and m[5] is not -1, then link is to a comment
- // indicate that in the text by appending (comment)
- if m[4] != -1 && m[5] != -1 {
+ if len(m[re.SubexpIndex("comment")]) > 0 {
if locale, ok := ctx.Ctx.Value(translation.ContextKey).(translation.Locale); ok {
text += " " + locale.TrString("repo.from_comment")
} else {
@@ -798,17 +810,14 @@ func fullIssuePatternProcessor(ctx *RenderContext, node *html.Node) {
}
}
- // extract repo and org name from matched link like
- // http://localhost:3000/gituser/myrepo/issues/1
- linkParts := strings.Split(link, "/")
- matchOrg := linkParts[len(linkParts)-4]
- matchRepo := linkParts[len(linkParts)-3]
+ matchUser := m[re.SubexpIndex("user")]
+ matchRepo := m[re.SubexpIndex("repo")]
- if matchOrg == ctx.Metas["user"] && matchRepo == ctx.Metas["repo"] {
- replaceContent(node, m[0], m[1], createLink(link, text, "ref-issue"))
+ if matchUser == ctx.Metas["user"] && matchRepo == ctx.Metas["repo"] {
+ replaceContent(node, linkIndex[0], linkIndex[1], createLink(link, text, "ref-issue"))
} else {
- text = matchOrg + "/" + matchRepo + text
- replaceContent(node, m[0], m[1], createLink(link, text, "ref-issue"))
+ text = matchUser + "/" + matchRepo + text
+ replaceContent(node, linkIndex[0], linkIndex[1], createLink(link, text, "ref-issue"))
}
node = node.NextSibling.NextSibling
}
@@ -867,7 +876,7 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) {
var link *html.Node
reftext := node.Data[ref.RefLocation.Start:ref.RefLocation.End]
- if hasExtTrackFormat && !ref.IsPull {
+ if hasExtTrackFormat && !ref.IsPull && ref.Owner == "" {
ctx.Metas["index"] = ref.Issue
res, err := vars.Expand(ctx.Metas["format"], ctx.Metas)
@@ -1094,6 +1103,21 @@ func filePreviewPatternProcessor(ctx *RenderContext, node *html.Node) {
}
}
+func inlineCodeBlockProcessor(ctx *RenderContext, node *html.Node) {
+ start := 0
+ next := node.NextSibling
+ for node != nil && node != next && start < len(node.Data) {
+ m := InlineCodeBlockRegex.FindStringSubmatchIndex(node.Data[start:])
+ if m == nil {
+ return
+ }
+
+ code := node.Data[m[0]+1 : m[1]-1]
+ replaceContent(node, m[0], m[1], createInlineCode(code))
+ node = node.NextSibling.NextSibling
+ }
+}
+
// emojiShortCodeProcessor for rendering text like :smile: into emoji
func emojiShortCodeProcessor(ctx *RenderContext, node *html.Node) {
start := 0
@@ -1122,7 +1146,7 @@ func emojiShortCodeProcessor(ctx *RenderContext, node *html.Node) {
continue
}
- replaceContent(node, m[0], m[1], createEmoji(converted.Emoji, "emoji", converted.Description))
+ replaceContent(node, m[0], m[1], createEmoji(converted.Emoji, "emoji", converted.Description, alias))
node = node.NextSibling.NextSibling
start = 0
}
@@ -1144,14 +1168,14 @@ func emojiProcessor(ctx *RenderContext, node *html.Node) {
start = m[1]
val := emoji.FromCode(codepoint)
if val != nil {
- replaceContent(node, m[0], m[1], createEmoji(codepoint, "emoji", val.Description))
+ replaceContent(node, m[0], m[1], createEmoji(codepoint, "emoji", val.Description, val.Aliases[0]))
node = node.NextSibling.NextSibling
start = 0
}
}
}
-// hashCurrentPatternProcessor renders SHA1 strings to corresponding links that
+// hashCurrentPatternProcessor renders SHA1/SHA256 strings to corresponding links that
// are assumed to be in the same repository.
func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
if ctx.Metas == nil || ctx.Metas["user"] == "" || ctx.Metas["repo"] == "" || ctx.Metas["repoPath"] == "" {
@@ -1197,7 +1221,7 @@ func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) {
})
}
- exist = ctx.GitRepo.IsObjectExist(hash)
+ exist = ctx.GitRepo.IsReferenceExist(hash)
ctx.ShaExistCache[hash] = exist
}
diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go
index 18088af0ca..08b1fed505 100644
--- a/modules/markup/html_internal_test.go
+++ b/modules/markup/html_internal_test.go
@@ -1,4 +1,5 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
+// Copyright 2025 The Forgejo Authors.
// SPDX-License-Identifier: MIT
package markup
@@ -9,11 +10,12 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
const (
@@ -294,7 +296,7 @@ func testRenderIssueIndexPattern(t *testing.T, input, expected string, ctx *Rend
var buf strings.Builder
err := postProcess(ctx, []processor{issueIndexPatternProcessor}, strings.NewReader(input), &buf)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, buf.String(), "input=%q", input)
}
@@ -310,7 +312,7 @@ func TestRender_AutoLink(t *testing.T) {
},
Metas: localMetas,
}, strings.NewReader(input), &buffer)
- assert.Equal(t, err, nil)
+ require.NoError(t, err, nil)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer.String()))
buffer.Reset()
@@ -322,7 +324,7 @@ func TestRender_AutoLink(t *testing.T) {
Metas: localMetas,
IsWiki: true,
}, strings.NewReader(input), &buffer)
- assert.Equal(t, err, nil)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer.String()))
}
@@ -341,6 +343,22 @@ func TestRender_AutoLink(t *testing.T) {
test(tmp, "d8a994ef24 (diff-2)
")
}
+func TestRender_IssueIndexPatternRef(t *testing.T) {
+ setting.AppURL = TestAppURL
+
+ test := func(input, expected string) {
+ var buf strings.Builder
+ err := postProcess(&RenderContext{
+ Ctx: git.DefaultContext,
+ Metas: numericMetas,
+ }, []processor{issueIndexPatternProcessor}, strings.NewReader(input), &buf)
+ require.NoError(t, err)
+ assert.Equal(t, expected, buf.String(), "input=%q", input)
+ }
+
+ test("alan-turin/Enigma-cryptanalysis#1", `alan-turin/Enigma-cryptanalysis#1 `)
+}
+
func TestRender_FullIssueURLs(t *testing.T) {
setting.AppURL = TestAppURL
@@ -353,7 +371,7 @@ func TestRender_FullIssueURLs(t *testing.T) {
},
Metas: localMetas,
}, []processor{fullIssuePatternProcessor}, strings.NewReader(input), &result)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, result.String())
}
test("Here is a link https://git.osgeo.org/gogs/postgis/postgis/pulls/6",
@@ -366,15 +384,15 @@ func TestRender_FullIssueURLs(t *testing.T) {
`#4 `)
test("http://localhost:3000/gogits/gogs/issues/4 test",
`#4 test`)
- test("http://localhost:3000/gogits/gogs/issues/4?a=1&b=2#comment-123 test",
- `#4 (comment) test`)
+ test("http://localhost:3000/gogits/gogs/issues/4?a=1&b=2#comment-form test",
+ `#4 test`)
test("http://localhost:3000/testOrg/testOrgRepo/pulls/2/files#issuecomment-24",
- "http://localhost:3000/testOrg/testOrgRepo/pulls/2/files#issuecomment-24")
- test("http://localhost:3000/testOrg/testOrgRepo/pulls/2/files",
- "http://localhost:3000/testOrg/testOrgRepo/pulls/2/files")
+ `testOrg/testOrgRepo#2/files (comment) `)
+ test("http://localhost:3000/testOrg/testOrgRepo/pulls/2/commits",
+ `testOrg/testOrgRepo#2/commits `)
}
-func TestRegExp_sha1CurrentPattern(t *testing.T) {
+func TestRegExp_hashCurrentPattern(t *testing.T) {
trueTestCases := []string{
"d8a994ef243349f321568f9e36d5c3f444b99cae",
"abcdefabcdefabcdefabcdefabcdefabcdefabcd",
@@ -382,6 +400,13 @@ func TestRegExp_sha1CurrentPattern(t *testing.T) {
"[abcdefabcdefabcdefabcdefabcdefabcdefabcd]",
"abcdefabcdefabcdefabcdefabcdefabcdefabcd.",
"abcdefabcdefabcdefabcdefabcdefabcdefabcd:",
+ "d8a994ef243349f321568f9e36d5c3f444b99cae12424fa123391042fbae2319",
+ "abcdefd?",
+ "abcdefd!",
+ "!abcd3ef",
+ ":abcd3ef",
+ ".abcd3ef",
+ " (abcd3ef). ",
}
falseTestCases := []string{
"test",
@@ -389,6 +414,8 @@ func TestRegExp_sha1CurrentPattern(t *testing.T) {
"e59ff077-2d03-4e6b-964d-63fbaea81f",
"abcdefghijklmnopqrstuvwxyzabcdefghijklmn",
"abcdefghijklmnopqrstuvwxyzabcdefghijklmO",
+ "commit/abcdefd",
+ "abcd3ef...defabcd",
}
for _, testCase := range trueTestCases {
@@ -442,6 +469,10 @@ func TestRegExp_anySHA1Pattern(t *testing.T) {
for k, v := range testCases {
assert.Equal(t, anyHashPattern.FindStringSubmatch(k)[1:], v)
}
+
+ for _, v := range []string{"https://codeberg.org/forgejo/forgejo/attachments/774421a1-b0ae-4501-8fba-983874b76811"} {
+ assert.False(t, anyHashPattern.MatchString(v))
+ }
}
func TestRegExp_shortLinkPattern(t *testing.T) {
diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go
index fa49e60a16..d503796eb6 100644
--- a/modules/markup/html_test.go
+++ b/modules/markup/html_test.go
@@ -1,4 +1,5 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
+// Copyright 2025 The Forgejo Authors.
// SPDX-License-Identifier: MIT
package markup_test
@@ -10,16 +11,16 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/emoji"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/emoji"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/util"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@@ -51,7 +52,7 @@ func TestRender_Commits(t *testing.T) {
},
Metas: localMetas,
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
}
@@ -105,7 +106,7 @@ func TestRender_CrossReferences(t *testing.T) {
},
Metas: localMetas,
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
}
@@ -146,7 +147,7 @@ func TestRender_links(t *testing.T) {
Base: markup.TestRepoURL,
},
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
}
// Text that should be turned into URL
@@ -248,7 +249,7 @@ func TestRender_email(t *testing.T) {
Base: markup.TestRepoURL,
},
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(res))
}
// Text that should be turned into email link
@@ -321,7 +322,7 @@ func TestRender_emoji(t *testing.T) {
Base: markup.TestRepoURL,
},
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
}
@@ -329,42 +330,42 @@ func TestRender_emoji(t *testing.T) {
for i := range emoji.GemojiData {
test(
emoji.GemojiData[i].Emoji,
- ``+emoji.GemojiData[i].Emoji+`
`)
+ ``+emoji.GemojiData[i].Emoji+`
`)
}
for i := range emoji.GemojiData {
test(
":"+emoji.GemojiData[i].Aliases[0]+":",
- ``+emoji.GemojiData[i].Emoji+`
`)
+ ``+emoji.GemojiData[i].Emoji+`
`)
}
// Text that should be turned into or recognized as emoji
test(
":gitea:",
- `
`)
+ `
`)
test(
":custom-emoji:",
`:custom-emoji:
`)
setting.UI.CustomEmojisMap["custom-emoji"] = ":custom-emoji:"
test(
":custom-emoji:",
- `
`)
+ `
`)
test(
"่ฟๆฏๅญ็ฌฆ:1::+1: some๐ \U0001f44d:custom-emoji: :gitea:",
- `่ฟๆฏๅญ็ฌฆ:1:๐ some๐ `+
- `๐ `+
- `
`)
+ `่ฟๆฏๅญ็ฌฆ:1:๐ some๐ `+
+ `๐ `+
+ `
`)
test(
"Some text with ๐ in the middle",
- `Some text with ๐ in the middle
`)
+ `Some text with ๐ in the middle
`)
test(
"Some text with :smile: in the middle",
- `Some text with ๐ in the middle
`)
+ `Some text with ๐ in the middle
`)
test(
"Some text with ๐๐ 2 emoji next to each other",
- `Some text with ๐ ๐ 2 emoji next to each other
`)
+ `Some text with ๐ ๐ 2 emoji next to each other
`)
test(
"๐๐คช๐๐คโ",
- `๐ ๐คช ๐ ๐ค โ
`)
+ `๐ ๐คช ๐ ๐ค โ
`)
// should match nothing
test(
@@ -387,7 +388,7 @@ func TestRender_ShortLinks(t *testing.T) {
BranchPath: "master",
},
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
buffer, err = markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
@@ -397,7 +398,7 @@ func TestRender_ShortLinks(t *testing.T) {
Metas: localMetas,
IsWiki: true,
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
}
@@ -416,7 +417,7 @@ func TestRender_ShortLinks(t *testing.T) {
otherImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "Link+Other.jpg")
encodedImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "Link+%23.jpg")
notencodedImgurlWiki := util.URLJoin(markup.TestRepoURL, "wiki", "raw", "some", "path", "Link+#.jpg")
- favicon := "http://google.com/favicon.ico"
+ favicon := "https://forgejo.org/favicon.ico"
test(
"[[Link]]",
@@ -424,28 +425,28 @@ func TestRender_ShortLinks(t *testing.T) {
`Link
`)
test(
"[[Link.jpg]]",
- `
`,
- `
`)
+ `
`,
+ `
`)
test(
"[["+favicon+"]]",
- `
`,
- `
`)
+ `
`,
+ `
`)
test(
"[[Name|Link]]",
`Name
`,
`Name
`)
test(
"[[Name|Link.jpg]]",
- `
`,
- `
`)
+ `
`,
+ `
`)
test(
"[[Name|Link.jpg|alt=AltName]]",
`
`,
`
`)
test(
"[[Name|Link.jpg|title=Title]]",
- `
`,
- `
`)
+ `
`,
+ `
`)
test(
"[[Name|Link.jpg|alt=AltName|title=Title]]",
`
`,
@@ -472,16 +473,16 @@ func TestRender_ShortLinks(t *testing.T) {
`Link Other Link Link?
`)
test(
"[[Link #.jpg]]",
- `
`,
- `
`)
+ `
`,
+ `
`)
test(
"[[Name|Link #.jpg|alt=\"AltName\"|title='Title']]",
`
`,
`
`)
test(
"[[some/path/Link #.jpg]]",
- `
`,
- `
`)
+ `
`,
+ `
`)
test(
"[[foobar]]
",
`[[foobar]]
`,
@@ -500,7 +501,7 @@ func TestRender_RelativeImages(t *testing.T) {
},
Metas: localMetas,
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
buffer, err = markdown.RenderString(&markup.RenderContext{
Ctx: git.DefaultContext,
@@ -510,7 +511,7 @@ func TestRender_RelativeImages(t *testing.T) {
Metas: localMetas,
IsWiki: true,
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
}
@@ -546,7 +547,7 @@ func Test_ParseClusterFuzz(t *testing.T) {
},
Metas: localMetas,
}, strings.NewReader(data), &res)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotContains(t, res.String(), " `)
+ ` `)
test(
"Some text with ๐ in the middle",
- `Some text with ๐ in the middle`)
+ `Some text with ๐ in the middle`)
test("http://localhost:3000/person/repo/issues/4#issuecomment-1234",
`person/repo#4 (comment) `)
}
@@ -624,7 +625,7 @@ func TestIssue16020(t *testing.T) {
Ctx: git.DefaultContext,
Metas: localMetas,
}, strings.NewReader(data), &res)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, data, res.String())
}
@@ -640,7 +641,7 @@ func BenchmarkEmojiPostprocess(b *testing.B) {
Ctx: git.DefaultContext,
Metas: localMetas,
}, strings.NewReader(data), &res)
- assert.NoError(b, err)
+ require.NoError(b, err)
}
}
@@ -659,7 +660,7 @@ func TestFuzz(t *testing.T) {
err := markup.PostProcess(&renderContext, strings.NewReader(s), io.Discard)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
func TestIssue18471(t *testing.T) {
@@ -671,7 +672,7 @@ func TestIssue18471(t *testing.T) {
Metas: localMetas,
}, strings.NewReader(data), &res)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "783b039...da951ce
", res.String())
}
@@ -679,7 +680,7 @@ func TestRender_FilePreview(t *testing.T) {
defer test.MockVariableValue(&setting.StaticRootPath, "../../")()
defer test.MockVariableValue(&setting.Names, []string{"english"})()
defer test.MockVariableValue(&setting.Langs, []string{"en-US"})()
- translation.InitLocales(context.Background())
+ translation.InitLocales(t.Context())
setting.AppURL = markup.TestAppURL
markup.Init(&markup.ProcessorHelper{
@@ -688,10 +689,10 @@ func TestRender_FilePreview(t *testing.T) {
require.NoError(t, err)
defer gitRepo.Close()
- commit, err := gitRepo.GetCommit("HEAD")
+ commit, err := gitRepo.GetCommit(commitSha)
require.NoError(t, err)
- blob, err := commit.GetBlobByPath("path/to/file.go")
+ blob, err := commit.GetBlobByPath(filePath)
require.NoError(t, err)
return blob, nil
@@ -707,7 +708,7 @@ func TestRender_FilePreview(t *testing.T) {
RelativePath: ".md",
Metas: metas,
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer))
}
@@ -780,6 +781,38 @@ func TestRender_FilePreview(t *testing.T) {
},
)
})
+ t.Run("single-line", func(t *testing.T) {
+ testRender(
+ util.URLJoin(markup.TestRepoURL, "src", "commit", "4c1aaf56bcb9f39dcf65f3f250726850aed13cd6", "single-line.txt")+"#L1",
+ `
`+
+ ``+
+ ``+
+ `
`+
+ `
`+
+ ``+
+ ``+
+ ` `+
+ `A`+`
`+
+ ` `+
+ ` `+
+ `
`+
+ `
`+
+ `
`+
+ `
`,
+ map[string]string{
+ "user": "gogits",
+ "repo": "gogs2",
+ },
+ )
+ })
t.Run("AppSubURL", func(t *testing.T) {
urlWithSub := util.URLJoin(markup.TestAppURL, "sub", markup.TestOrgRepo, "src", "commit", sha, "path", "to", "file.go") + "#L2-L3"
@@ -994,4 +1027,138 @@ func TestRender_FilePreview(t *testing.T) {
localMetas,
)
})
+
+ commitFileURL := util.URLJoin(markup.TestRepoURL, "src", "commit", "c9913120ed2c1e27c1d7752ecdb7a504dc7cf6be", "path", "to", "file.md")
+
+ t.Run("rendered file with ?display=source", func(t *testing.T) {
+ testRender(
+ commitFileURL+"?display=source"+"#L1-L2",
+ `
`+
+ ``+
+ ``+
+ `
`+
+ `
`+
+ ``+
+ ``+
+ ` `+
+ `# A`+"\n"+`
`+
+ ` `+
+ ``+
+ ` `+
+ ` B`+"\n"+`
`+
+ ` `+
+ ` `+
+ `
`+
+ `
`+
+ `
`+
+ `
`,
+ localMetas,
+ )
+ })
+
+ t.Run("rendered file without ?display=source", func(t *testing.T) {
+ testRender(
+ commitFileURL+"#L1-L2",
+ `
`+
+ ``+
+ ``+
+ `
`+
+ `
`+
+ ``+
+ ``+
+ ` `+
+ `# A`+"\n"+`
`+
+ ` `+
+ ``+
+ ` `+
+ ` B`+"\n"+`
`+
+ ` `+
+ ` `+
+ `
`+
+ `
`+
+ `
`+
+ `
`,
+ localMetas,
+ )
+ })
+
+ commitFileURL = util.URLJoin(markup.TestRepoURL, "src", "commit", "190d9492934af498c3f669d6a2431dc5459e5b20", "path", "to", "file.go")
+
+ t.Run("normal file with ?display=source", func(t *testing.T) {
+ testRender(
+ commitFileURL+"?display=source"+"#L2-L3",
+ `
`+
+ ``+
+ ``+
+ `
`+
+ `
`+
+ ``+
+ ``+
+ ` `+
+ `B `+"\n"+`
`+
+ ` `+
+ ``+
+ ` `+
+ `C `+"\n"+`
`+
+ ` `+
+ ` `+
+ `
`+
+ `
`+
+ `
`+
+ `
`,
+ localMetas,
+ )
+ })
+
+ commitFileURL = util.URLJoin(markup.TestRepoURL, "src", "commit", "eeb243c3395e1921c5d90e73bd739827251fc99d", "path", "to", "file%20%23.txt")
+
+ t.Run("file with strange characters in name", func(t *testing.T) {
+ testRender(
+ commitFileURL+"#L1",
+ `
`+
+ ``+
+ ``+
+ `
`+
+ `
`+
+ ``+
+ ``+
+ ` `+
+ `A`+"\n"+`
`+
+ ` `+
+ ` `+
+ `
`+
+ `
`+
+ `
`+
+ `
`,
+ localMetas,
+ )
+ })
}
diff --git a/modules/markup/markdown/ast.go b/modules/markup/markdown/ast.go
index 7f0ac6a92c..c2fbbe6692 100644
--- a/modules/markup/markdown/ast.go
+++ b/modules/markup/markdown/ast.go
@@ -34,13 +34,6 @@ func NewDetails() *Details {
}
}
-// IsDetails returns true if the given node implements the Details interface,
-// otherwise false.
-func IsDetails(node ast.Node) bool {
- _, ok := node.(*Details)
- return ok
-}
-
// Summary is a block that contains the summary of details block
type Summary struct {
ast.BaseBlock
@@ -66,13 +59,6 @@ func NewSummary() *Summary {
}
}
-// IsSummary returns true if the given node implements the Summary interface,
-// otherwise false.
-func IsSummary(node ast.Node) bool {
- _, ok := node.(*Summary)
- return ok
-}
-
// TaskCheckBoxListItem is a block that represents a list item of a markdown block with a checkbox
type TaskCheckBoxListItem struct {
*ast.ListItem
@@ -103,13 +89,6 @@ func NewTaskCheckBoxListItem(listItem *ast.ListItem) *TaskCheckBoxListItem {
}
}
-// IsTaskCheckBoxListItem returns true if the given node implements the TaskCheckBoxListItem interface,
-// otherwise false.
-func IsTaskCheckBoxListItem(node ast.Node) bool {
- _, ok := node.(*TaskCheckBoxListItem)
- return ok
-}
-
// Icon is an inline for a fomantic icon
type Icon struct {
ast.BaseInline
@@ -139,13 +118,6 @@ func NewIcon(name string) *Icon {
}
}
-// IsIcon returns true if the given node implements the Icon interface,
-// otherwise false.
-func IsIcon(node ast.Node) bool {
- _, ok := node.(*Icon)
- return ok
-}
-
// ColorPreview is an inline for a color preview
type ColorPreview struct {
ast.BaseInline
diff --git a/modules/markup/markdown/callout/github.go b/modules/markup/markdown/callout/github.go
index 443f6fe2a3..49ad249696 100644
--- a/modules/markup/markdown/callout/github.go
+++ b/modules/markup/markdown/callout/github.go
@@ -7,7 +7,7 @@ package callout
import (
"strings"
- "code.gitea.io/gitea/modules/svg"
+ "forgejo.org/modules/svg"
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
@@ -34,8 +34,11 @@ func (g *GitHubCalloutTransformer) Transform(node *ast.Document, reader text.Rea
return ast.WalkContinue, nil
}
- switch v := n.(type) {
- case *ast.Blockquote:
+ if v, ok := n.(*ast.Blockquote); ok {
+ if v.ChildCount() == 0 {
+ return ast.WalkContinue, nil
+ }
+
// We only want attention blockquotes when the AST looks like:
// Text: "["
// Text: "!TYPE"
@@ -47,7 +50,7 @@ func (g *GitHubCalloutTransformer) Transform(node *ast.Document, reader text.Rea
return ast.WalkContinue, nil
}
firstTextNode, ok := firstParagraph.FirstChild().(*ast.Text)
- if !ok || string(firstTextNode.Text(reader.Source())) != "[" {
+ if !ok || string(firstTextNode.Value(reader.Source())) != "[" {
return ast.WalkContinue, nil
}
secondTextNode, ok := firstTextNode.NextSibling().(*ast.Text)
@@ -56,14 +59,14 @@ func (g *GitHubCalloutTransformer) Transform(node *ast.Document, reader text.Rea
}
// If the second node's text isn't one of the supported attention
// types, continue walking.
- secondTextNodeText := secondTextNode.Text(reader.Source())
+ secondTextNodeText := secondTextNode.Value(reader.Source())
attentionType := strings.ToLower(strings.TrimPrefix(string(secondTextNodeText), "!"))
if _, has := supportedAttentionTypes[attentionType]; !has {
return ast.WalkContinue, nil
}
thirdTextNode, ok := secondTextNode.NextSibling().(*ast.Text)
- if !ok || string(thirdTextNode.Text(reader.Source())) != "]" {
+ if !ok || string(thirdTextNode.Value(reader.Source())) != "]" {
return ast.WalkContinue, nil
}
diff --git a/modules/markup/markdown/callout/github_legacy.go b/modules/markup/markdown/callout/github_legacy.go
index e9aaecccfb..e77da73dd9 100644
--- a/modules/markup/markdown/callout/github_legacy.go
+++ b/modules/markup/markdown/callout/github_legacy.go
@@ -7,6 +7,8 @@ package callout
import (
"strings"
+ "forgejo.org/modules/markup/markdown/util"
+
"github.com/yuin/goldmark/ast"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/text"
@@ -23,8 +25,11 @@ func (g *GitHubLegacyCalloutTransformer) Transform(node *ast.Document, reader te
return ast.WalkContinue, nil
}
- switch v := n.(type) {
- case *ast.Blockquote:
+ if v, ok := n.(*ast.Blockquote); ok {
+ if v.ChildCount() == 0 {
+ return ast.WalkContinue, nil
+ }
+
// The first paragraph contains the callout type.
firstParagraph := v.FirstChild()
if firstParagraph.ChildCount() < 1 {
@@ -37,7 +42,7 @@ func (g *GitHubLegacyCalloutTransformer) Transform(node *ast.Document, reader te
if !ok {
return ast.WalkContinue, nil
}
- calloutText := string(calloutNode.Text(reader.Source()))
+ calloutText := string(util.Text(calloutNode, reader.Source()))
calloutType := strings.ToLower(calloutText)
// We only support "Note" and "Warning" callouts in legacy mode,
// match only those.
@@ -60,6 +65,14 @@ func (g *GitHubLegacyCalloutTransformer) Transform(node *ast.Document, reader te
attentionParagraph.AppendChild(attentionParagraph, calloutNode)
firstParagraph.Parent().InsertBefore(firstParagraph.Parent(), firstParagraph, attentionParagraph)
firstParagraph.RemoveChild(firstParagraph, calloutNode)
+
+ // Remove softbreak line if there's one.
+ if firstParagraph.ChildCount() >= 1 {
+ softBreakNode, ok := firstParagraph.FirstChild().(*ast.Text)
+ if ok && softBreakNode.SoftLineBreak() {
+ firstParagraph.RemoveChild(firstParagraph, softBreakNode)
+ }
+ }
}
return ast.WalkContinue, nil
diff --git a/modules/markup/markdown/color_util.go b/modules/markup/markdown/color_util.go
index 355fef3fc0..efbde6b730 100644
--- a/modules/markup/markdown/color_util.go
+++ b/modules/markup/markdown/color_util.go
@@ -6,7 +6,7 @@ package markdown
import "regexp"
var (
- hexRGB = regexp.MustCompile(`^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$`)
+ hexRGB = regexp.MustCompile(`^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$`)
hsl = regexp.MustCompile(`^hsl\([ ]*([012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%\)$`)
hsla = regexp.MustCompile(`^hsla\(([ ]*[012]?[0-9]{1,2}|3[0-5][0-9]|360),[ ]*([0-9]{0,2}|100)\%,[ ]*([0-9]{0,2}|100)\%,[ ]*(1|1\.0|0|(0\.[0-9]+))\)$`)
rgb = regexp.MustCompile(`^rgb\(([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))),){2}([ ]*((([0-9]{1,2}|100)\%)|(([01]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))))\)$`)
diff --git a/modules/markup/markdown/color_util_test.go b/modules/markup/markdown/color_util_test.go
index c6e0555a35..9f6448cf8c 100644
--- a/modules/markup/markdown/color_util_test.go
+++ b/modules/markup/markdown/color_util_test.go
@@ -17,6 +17,7 @@ func TestMatchColor(t *testing.T) {
{"#ddeeffa0", true},
{"#ddeefe", true},
{"#abcdef", true},
+ {"#fffa", true},
{"#abcdeg", false},
{"#abcdefg0", false},
{"black", false},
diff --git a/modules/markup/markdown/goldmark.go b/modules/markup/markdown/goldmark.go
index 0290e1312d..9a901a2287 100644
--- a/modules/markup/markdown/goldmark.go
+++ b/modules/markup/markdown/goldmark.go
@@ -8,8 +8,8 @@ import (
"regexp"
"strings"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/setting"
"github.com/yuin/goldmark/ast"
east "github.com/yuin/goldmark/extension/ast"
@@ -203,8 +203,7 @@ func (r *HTMLRenderer) renderIcon(w util.BufWriter, source []byte, node ast.Node
return ast.WalkContinue, nil
}
- var err error
- _, err = w.WriteString(fmt.Sprintf(` `, name))
+ _, err := w.WriteString(fmt.Sprintf(` `, name))
if err != nil {
return ast.WalkStop, err
}
diff --git a/modules/markup/markdown/markdown.go b/modules/markup/markdown/markdown.go
index 77c876dfff..db92631acc 100644
--- a/modules/markup/markdown/markdown.go
+++ b/modules/markup/markdown/markdown.go
@@ -11,18 +11,17 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/common"
- "code.gitea.io/gitea/modules/markup/markdown/callout"
- "code.gitea.io/gitea/modules/markup/markdown/math"
- "code.gitea.io/gitea/modules/setting"
- giteautil "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/common"
+ "forgejo.org/modules/markup/markdown/callout"
+ "forgejo.org/modules/markup/markdown/math"
+ "forgejo.org/modules/setting"
+ giteautil "forgejo.org/modules/util"
chromahtml "github.com/alecthomas/chroma/v2/formatters/html"
"github.com/yuin/goldmark"
highlighting "github.com/yuin/goldmark-highlighting/v2"
- meta "github.com/yuin/goldmark-meta"
"github.com/yuin/goldmark/extension"
"github.com/yuin/goldmark/parser"
"github.com/yuin/goldmark/renderer"
@@ -121,7 +120,6 @@ func SpecializedMarkdown() goldmark.Markdown {
math.NewExtension(
math.Enabled(setting.Markdown.EnableMath),
),
- meta.Meta,
),
goldmark.WithParserOptions(
parser.WithAttribute(),
@@ -182,7 +180,7 @@ func actualRender(ctx *markup.RenderContext, input io.Reader, output io.Writer)
bufWithMetadataLength := len(buf)
rc := &RenderConfig{
- Meta: renderMetaModeFromString(string(ctx.RenderMetaAs)),
+ Meta: markup.RenderMetaAsDetails,
Icon: "table",
Lang: "",
}
diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go
index 68428552c4..e229ee4c65 100644
--- a/modules/markup/markdown/markdown_test.go
+++ b/modules/markup/markdown/markdown_test.go
@@ -10,16 +10,17 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
+ "forgejo.org/modules/util"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
const (
@@ -57,7 +58,7 @@ func TestRender_StandardLinks(t *testing.T) {
Base: FullURL,
},
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
buffer, err = markdown.RenderString(&markup.RenderContext{
@@ -67,7 +68,7 @@ func TestRender_StandardLinks(t *testing.T) {
},
IsWiki: true,
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expectedWiki), strings.TrimSpace(string(buffer)))
}
@@ -91,7 +92,7 @@ func TestRender_Images(t *testing.T) {
Base: FullURL,
},
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
}
@@ -107,7 +108,7 @@ func TestRender_Images(t *testing.T) {
test(
"[["+title+"|"+url+"]]",
- `
`)
+ `
`)
test(
"[]("+href+")",
`
`)
@@ -118,7 +119,7 @@ func TestRender_Images(t *testing.T) {
test(
"[["+title+"|"+url+"]]",
- `
`)
+ `
`)
test(
"[]("+href+")",
`
`)
@@ -134,8 +135,8 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
See commit 65f1bf27bc
Ideas and codes
-Bezier widget (by @r-lyeh ) ocornut/imgui#786
-Bezier widget (by @r-lyeh ) #786
+Bezier widget (by @r-lyeh ) ocornut/imgui#786
+Bezier widget (by @r-lyeh ) #786
Node graph editors https://github.com/ocornut/imgui/issues/306
Memory Editor
Plot var helper
@@ -148,13 +149,13 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
-
+
Installation
-
+
Usage
@@ -163,9 +164,9 @@ func testAnswers(baseURLContent, baseURLImages string) []string {
`Excelsior JET allows you to create native executables for Windows, Linux and Mac OS X.
Package your libGDX application
-
+
Perform a test run by hitting the Run! button.
-
+
More tests
(from https://www.markdownguide.org/extended-syntax/ )
@@ -300,7 +301,7 @@ func TestTotal_RenderWiki(t *testing.T) {
Metas: localMetas,
IsWiki: true,
}, sameCases[i])
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, template.HTML(answers[i]), line)
}
@@ -325,7 +326,7 @@ func TestTotal_RenderWiki(t *testing.T) {
},
IsWiki: true,
}, testCases[i])
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, template.HTML(testCases[i+1]), line)
}
}
@@ -344,7 +345,7 @@ func TestTotal_RenderString(t *testing.T) {
},
Metas: localMetas,
}, sameCases[i])
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, template.HTML(answers[i]), line)
}
@@ -357,7 +358,7 @@ func TestTotal_RenderString(t *testing.T) {
Base: FullURL,
},
}, testCases[i])
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, template.HTML(testCases[i+1]), line)
}
}
@@ -365,17 +366,17 @@ func TestTotal_RenderString(t *testing.T) {
func TestRender_RenderParagraphs(t *testing.T) {
test := func(t *testing.T, str string, cnt int) {
res, err := markdown.RenderRawString(&markup.RenderContext{Ctx: git.DefaultContext}, str)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, cnt, strings.Count(res, "
`
res, err := markdown.RenderRawString(&markup.RenderContext{Ctx: git.DefaultContext}, testcase)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, expected, res)
}
func TestRenderEmojiInLinks_Issue12331(t *testing.T) {
testcase := `[Link with emoji :moon: in text](https://gitea.io)`
- expected := `Link with emoji ๐ in text
+ expected := `Link with emoji ๐ in text
`
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, testcase)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, template.HTML(expected), res)
}
@@ -458,7 +459,7 @@ func TestColorPreview(t *testing.T) {
for _, test := range positiveTests {
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase)
- assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
+ require.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase)
}
@@ -470,14 +471,14 @@ func TestColorPreview(t *testing.T) {
// no backticks
"rgb(166, 32, 64)",
// typo
- "`hsI(0, 100%, 50%)`", // codespell-ignore
+ "`hsI(0, 100%, 50%)`", // codespell:ignore
// looks like a color but not really
"`hsl(40, 60, 80)`",
}
for _, test := range negativeTests {
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test)
- assert.NoError(t, err, "Unexpected error in testcase: %q", test)
+ require.NoError(t, err, "Unexpected error in testcase: %q", test)
assert.NotContains(t, res, `a
(b
) [$c$] {$d$}` + nl,
},
+ {
+ "$$a$$ test",
+ `a
test
` + nl,
+ },
+ {
+ "test $$a$$",
+ `test a
` + nl,
+ },
}
for _, test := range testcases {
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase)
- assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
+ require.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase)
}
}
@@ -754,7 +763,7 @@ Citation needed[^0].`,
}
for _, test := range testcases {
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase)
- assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
+ require.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
assert.Equal(t, test.expected, string(res), "Unexpected result in testcase %q", test.testcase)
}
}
@@ -791,7 +800,7 @@ foo: bar
for _, test := range testcases {
res, err := markdown.RenderString(&markup.RenderContext{Ctx: git.DefaultContext}, test.testcase)
- assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
+ require.NoError(t, err, "Unexpected error in testcase: %q", test.testcase)
assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase)
}
}
@@ -840,13 +849,13 @@ mail@domain.com
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -867,13 +876,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -896,13 +905,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -925,13 +934,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -954,13 +963,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -983,13 +992,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -1013,13 +1022,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -1043,13 +1052,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -1073,13 +1082,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -1103,13 +1112,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -1134,13 +1143,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -1165,13 +1174,13 @@ space
-
-
+
+
https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
@@ -1181,8 +1190,8 @@ space
}
for i, c := range cases {
- result, err := markdown.RenderString(&markup.RenderContext{Ctx: context.Background(), Links: c.Links, IsWiki: c.IsWiki}, input)
- assert.NoError(t, err, "Unexpected error in testcase: %v", i)
+ result, err := markdown.RenderString(&markup.RenderContext{Ctx: t.Context(), Links: c.Links, IsWiki: c.IsWiki}, input)
+ require.NoError(t, err, "Unexpected error in testcase: %v", i)
assert.Equal(t, template.HTML(c.Expected), result, "Unexpected result in testcase %v", i)
}
}
@@ -1199,7 +1208,7 @@ func TestCustomMarkdownURL(t *testing.T) {
BranchPath: "branch/main",
},
}, input)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
}
@@ -1210,3 +1219,147 @@ func TestCustomMarkdownURL(t *testing.T) {
test("[test](abp)",
`test
`)
}
+
+func TestYAMLMeta(t *testing.T) {
+ setting.AppURL = AppURL
+
+ test := func(input, expected string) {
+ buffer, err := markdown.RenderString(&markup.RenderContext{
+ Ctx: git.DefaultContext,
+ }, input)
+ require.NoError(t, err)
+ assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
+ }
+
+ test(`---
+include_toc: true
+---
+## Header`,
+ `
+
+
+include_toc
+
+
+
+
+true
+
+
+
+toc
+ `)
+
+ test(`---
+key: value
+---`,
+ `
+
+
+key
+
+
+
+
+value
+
+
+
+ `)
+
+ test("---\n---\n",
+ `
+ `)
+
+ test(`---
+gitea:
+ details_icon: smiley
+ include_toc: true
+---
+# Another header`,
+ `
+
+
+gitea
+
+
+
+
+
+
+
+details_icon
+include_toc
+
+
+
+
+smiley
+true
+
+
+
+
+
+
+
+toc
+ `)
+
+ test(`---
+gitea:
+ meta: table
+key: value
+---`, `
+
+
+gitea
+key
+
+
+
+
+
+
+
+meta
+
+
+
+
+table
+
+
+
+
+value
+
+
+
`)
+}
+
+func TestCallout(t *testing.T) {
+ setting.AppURL = AppURL
+
+ test := func(input, expected string) {
+ buffer, err := markdown.RenderString(&markup.RenderContext{
+ Ctx: git.DefaultContext,
+ }, input)
+ require.NoError(t, err)
+ assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(buffer)))
+ }
+
+ test(">\n0", "\n \n0
")
+ test("> **Warning**\n> Bad stuff is brewing here", ``)
+ test("> [!WARNING]\n> Bad stuff is brewing here", ``)
+}
diff --git a/modules/markup/markdown/math/block_parser.go b/modules/markup/markdown/math/block_parser.go
index f3262c82c0..527df84975 100644
--- a/modules/markup/markdown/math/block_parser.go
+++ b/modules/markup/markdown/math/block_parser.go
@@ -47,6 +47,12 @@ func (b *blockParser) Open(parent ast.Node, reader text.Reader, pc parser.Contex
}
idx := bytes.Index(line[pos+2:], endBytes)
if idx >= 0 {
+ // for case $$ ... $$ any other text
+ for i := pos + idx + 4; i < len(line); i++ {
+ if line[i] != ' ' && line[i] != '\n' {
+ return nil, parser.NoChildren
+ }
+ }
segment.Stop = segment.Start + idx + 2
reader.Advance(segment.Len() - 1)
segment.Start += 2
diff --git a/modules/markup/markdown/math/inline_block_node.go b/modules/markup/markdown/math/inline_block_node.go
new file mode 100644
index 0000000000..c92d0c8d84
--- /dev/null
+++ b/modules/markup/markdown/math/inline_block_node.go
@@ -0,0 +1,31 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package math
+
+import (
+ "github.com/yuin/goldmark/ast"
+)
+
+// InlineBlock represents inline math e.g. $$...$$
+type InlineBlock struct {
+ Inline
+}
+
+// InlineBlock implements InlineBlock.
+func (n *InlineBlock) InlineBlock() {}
+
+// KindInlineBlock is the kind for math inline block
+var KindInlineBlock = ast.NewNodeKind("MathInlineBlock")
+
+// Kind returns KindInlineBlock
+func (n *InlineBlock) Kind() ast.NodeKind {
+ return KindInlineBlock
+}
+
+// NewInlineBlock creates a new ast math inline block node
+func NewInlineBlock() *InlineBlock {
+ return &InlineBlock{
+ Inline{},
+ }
+}
diff --git a/modules/markup/markdown/math/inline_parser.go b/modules/markup/markdown/math/inline_parser.go
index 614cf329af..b11195d551 100644
--- a/modules/markup/markdown/math/inline_parser.go
+++ b/modules/markup/markdown/math/inline_parser.go
@@ -21,11 +21,20 @@ var defaultInlineDollarParser = &inlineParser{
end: []byte{'$'},
}
+var defaultDualDollarParser = &inlineParser{
+ start: []byte{'$', '$'},
+ end: []byte{'$', '$'},
+}
+
// NewInlineDollarParser returns a new inline parser
func NewInlineDollarParser() parser.InlineParser {
return defaultInlineDollarParser
}
+func NewInlineDualDollarParser() parser.InlineParser {
+ return defaultDualDollarParser
+}
+
var defaultInlineBracketParser = &inlineParser{
start: []byte{'\\', '('},
end: []byte{'\\', ')'},
@@ -38,7 +47,7 @@ func NewInlineBracketParser() parser.InlineParser {
// Trigger triggers this parser on $ or \
func (parser *inlineParser) Trigger() []byte {
- return parser.start[0:1]
+ return parser.start
}
func isPunctuation(b byte) bool {
@@ -88,7 +97,11 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser.
break
}
suceedingCharacter := line[pos]
- if !isPunctuation(suceedingCharacter) && !(suceedingCharacter == ' ') && !isBracket(suceedingCharacter) {
+ // check valid ending character
+ if !isPunctuation(suceedingCharacter) &&
+ !(suceedingCharacter == ' ') &&
+ !(suceedingCharacter == '\n') &&
+ !isBracket(suceedingCharacter) {
return nil
}
if line[ender-1] != '\\' {
@@ -101,12 +114,21 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser.
block.Advance(opener)
_, pos := block.Position()
- node := NewInline()
+ var node ast.Node
+ if parser == defaultDualDollarParser {
+ node = NewInlineBlock()
+ } else {
+ node = NewInline()
+ }
segment := pos.WithStop(pos.Start + ender - opener)
node.AppendChild(node, ast.NewRawTextSegment(segment))
block.Advance(ender - opener + len(parser.end))
- trimBlock(node, block)
+ if parser == defaultDualDollarParser {
+ trimBlock(&(node.(*InlineBlock)).Inline, block)
+ } else {
+ trimBlock(node.(*Inline), block)
+ }
return node
}
diff --git a/modules/markup/markdown/math/inline_renderer.go b/modules/markup/markdown/math/inline_renderer.go
index b4e9ade0ae..96848099cc 100644
--- a/modules/markup/markdown/math/inline_renderer.go
+++ b/modules/markup/markdown/math/inline_renderer.go
@@ -21,7 +21,11 @@ func NewInlineRenderer() renderer.NodeRenderer {
func (r *InlineRenderer) renderInline(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) {
if entering {
- _, _ = w.WriteString(``)
+ extraClass := ""
+ if _, ok := n.(*InlineBlock); ok {
+ extraClass = "display "
+ }
+ _, _ = w.WriteString(`
"
return template.HTML(htmlCode)
}
+
+func RenderReviewRequest(users []issues_model.RequestReviewTarget) template.HTML {
+ usernames := make([]string, 0, len(users))
+ for _, user := range users {
+ usernames = append(usernames, template.HTMLEscapeString(user.Name()))
+ }
+
+ htmlCode := ``
+ htmlCode += strings.Join(usernames, ", ")
+ htmlCode += " "
+ return template.HTML(htmlCode)
+}
diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go
index ea01612ac3..20c39eb417 100644
--- a/modules/templates/util_render_test.go
+++ b/modules/templates/util_render_test.go
@@ -8,10 +8,10 @@ import (
"html/template"
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/translation"
"github.com/stretchr/testify/assert"
)
@@ -35,8 +35,8 @@ com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
mail@domain.com
@mention-user test
#123
- space
-`
+ space
+` + "`code :+1: #123 code`\n"
var testMetas = map[string]string{
"user": "user13",
@@ -46,13 +46,13 @@ var testMetas = map[string]string{
}
func TestApostrophesInMentions(t *testing.T) {
- rendered := RenderMarkdownToHtml(context.Background(), "@mention-user's comment")
- assert.EqualValues(t, template.HTML("@mention-user 's comment
\n"), rendered)
+ rendered := RenderMarkdownToHtml(t.Context(), "@mention-user's comment")
+ assert.EqualValues(t, template.HTML("@mention-user 's comment
\n"), rendered)
}
func TestNonExistantUserMention(t *testing.T) {
- rendered := RenderMarkdownToHtml(context.Background(), "@ThisUserDoesNotExist @mention-user")
- assert.EqualValues(t, template.HTML("@ThisUserDoesNotExist @mention-user
\n"), rendered)
+ rendered := RenderMarkdownToHtml(t.Context(), "@ThisUserDoesNotExist @mention-user")
+ assert.EqualValues(t, template.HTML("@ThisUserDoesNotExist @mention-user
\n"), rendered)
}
func TestRenderCommitBody(t *testing.T) {
@@ -69,7 +69,7 @@ func TestRenderCommitBody(t *testing.T) {
{
name: "multiple lines",
args: args{
- ctx: context.Background(),
+ ctx: t.Context(),
msg: "first line\nsecond line",
},
want: "second line",
@@ -77,7 +77,7 @@ func TestRenderCommitBody(t *testing.T) {
{
name: "multiple lines with leading newlines",
args: args{
- ctx: context.Background(),
+ ctx: t.Context(),
msg: "\n\n\n\nfirst line\nsecond line",
},
want: "second line",
@@ -85,7 +85,7 @@ func TestRenderCommitBody(t *testing.T) {
{
name: "multiple lines with trailing newlines",
args: args{
- ctx: context.Background(),
+ ctx: t.Context(),
msg: "first line\nsecond line\n\n\n",
},
want: "second line",
@@ -111,25 +111,25 @@ func TestRenderCommitBody(t *testing.T) {
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
88fc37a3c0
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
- space`
-
- assert.EqualValues(t, expected, RenderCommitBody(context.Background(), testInput, testMetas))
+ space
+` + "`code ๐ #123 code`"
+ assert.EqualValues(t, expected, RenderCommitBody(t.Context(), testInput, testMetas))
}
func TestRenderCommitMessage(t *testing.T) {
expected := `space @mention-user `
- assert.EqualValues(t, expected, RenderCommitMessage(context.Background(), testInput, testMetas))
+ assert.EqualValues(t, expected, RenderCommitMessage(t.Context(), testInput, testMetas))
}
func TestRenderCommitMessageLinkSubject(t *testing.T) {
expected := `space @mention-user `
- assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(context.Background(), testInput, "https://example.com/link", testMetas))
+ assert.EqualValues(t, expected, RenderCommitMessageLinkSubject(t.Context(), testInput, "https://example.com/link", testMetas))
}
func TestRenderIssueTitle(t *testing.T) {
@@ -148,17 +148,44 @@ https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb..
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
@mention-user test
#123
- space
+ space
+code :+1: #123 code
`
- assert.EqualValues(t, expected, RenderIssueTitle(context.Background(), testInput, testMetas))
+ assert.EqualValues(t, expected, RenderIssueTitle(t.Context(), testInput, testMetas))
+}
+
+func TestRenderRefIssueTitle(t *testing.T) {
+ expected := ` space @mention-user
+/just/a/path.bin
+https://example.com/file.bin
+[local link](file.bin)
+[remote link](https://example.com)
+[[local link|file.bin]]
+[[remote link|https://example.com]]
+
+
+[[local image|image.jpg]]
+[[remote link|https://example.com/image.jpg]]
+https://example.com/user/repo/compare/88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb#hash
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
+https://example.com/user/repo/commit/88fc37a3c0a4dda553bdcfc80c178a58247f42fb
+com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
+๐
+mail@domain.com
+@mention-user test
+#123
+ space
+code :+1: #123 code
+`
+ assert.EqualValues(t, expected, RenderRefIssueTitle(t.Context(), testInput))
}
func TestRenderMarkdownToHtml(t *testing.T) {
- expected := `space @mention-user
+ expected := `
space @mention-user
/just/a/path.bin
https://example.com/file.bin
local link
@@ -167,19 +194,20 @@ func TestRenderMarkdownToHtml(t *testing.T) {
remote link
-
-
+
+
88fc37a3c0...12fc37a3c0 (hash)
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare
88fc37a3c0
com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit
-๐
+๐
mail@domain.com
-@mention-user test
+@mention-user test
#123
-space
+space
+code :+1: #123 code
`
- assert.EqualValues(t, expected, RenderMarkdownToHtml(context.Background(), testInput))
+ assert.EqualValues(t, expected, RenderMarkdownToHtml(t.Context(), testInput))
}
func TestRenderLabels(t *testing.T) {
diff --git a/modules/templates/util_string.go b/modules/templates/util_string.go
index f23b74786a..2d255e54a7 100644
--- a/modules/templates/util_string.go
+++ b/modules/templates/util_string.go
@@ -8,7 +8,7 @@ import (
"html/template"
"strings"
- "code.gitea.io/gitea/modules/base"
+ "forgejo.org/modules/base"
)
type StringUtils struct{}
@@ -19,6 +19,10 @@ func NewStringUtils() *StringUtils {
return &stringUtils
}
+func (su *StringUtils) Make(arr ...string) []string {
+ return arr
+}
+
func (su *StringUtils) HasPrefix(s any, prefix string) bool {
switch v := s.(type) {
case string:
diff --git a/modules/templates/util_test.go b/modules/templates/util_test.go
index febaf7fa88..79aaba4a0e 100644
--- a/modules/templates/util_test.go
+++ b/modules/templates/util_test.go
@@ -10,6 +10,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestDict(t *testing.T) {
@@ -27,9 +28,8 @@ func TestDict(t *testing.T) {
for _, c := range cases {
got, err := dict(c.args...)
- if assert.NoError(t, err) {
- assert.EqualValues(t, c.want, got)
- }
+ require.NoError(t, err)
+ assert.EqualValues(t, c.want, got)
}
bads := []struct {
@@ -41,7 +41,7 @@ func TestDict(t *testing.T) {
}
for _, c := range bads {
_, err := dict(c.args...)
- assert.Error(t, err)
+ require.Error(t, err)
}
}
@@ -51,7 +51,7 @@ func TestUtils(t *testing.T) {
tmpl.Funcs(template.FuncMap{"SliceUtils": NewSliceUtils, "StringUtils": NewStringUtils})
template.Must(tmpl.Parse(code))
w := &strings.Builder{}
- assert.NoError(t, tmpl.Execute(w, data))
+ require.NoError(t, tmpl.Execute(w, data))
return w.String()
}
@@ -75,5 +75,5 @@ func TestUtils(t *testing.T) {
template.Must(tmpl.Parse("{{SliceUtils.Contains .Slice .Value}}"))
// error is like this: `template: test:1:12: executing "test" at : error calling Contains: ...`
err := tmpl.Execute(io.Discard, map[string]any{"Slice": struct{}{}})
- assert.ErrorContains(t, err, "invalid type, expected slice or array")
+ require.ErrorContains(t, err, "invalid type, expected slice or array")
}
diff --git a/modules/templates/vars/vars_test.go b/modules/templates/vars/vars_test.go
index 8f421d9e4b..c54342204d 100644
--- a/modules/templates/vars/vars_test.go
+++ b/modules/templates/vars/vars_test.go
@@ -7,6 +7,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestExpandVars(t *testing.T) {
@@ -62,9 +63,9 @@ func TestExpandVars(t *testing.T) {
res, err := Expand(kase.tmpl, kase.data)
assert.EqualValues(t, kase.out, res)
if kase.error {
- assert.Error(t, err)
+ require.Error(t, err)
} else {
- assert.NoError(t, err)
+ require.NoError(t, err)
}
})
}
diff --git a/modules/test/distant_federation_server_mock.go b/modules/test/distant_federation_server_mock.go
new file mode 100644
index 0000000000..fd68c88a40
--- /dev/null
+++ b/modules/test/distant_federation_server_mock.go
@@ -0,0 +1,117 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package test
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+ "testing"
+)
+
+type FederationServerMockPerson struct {
+ ID int64
+ Name string
+ PubKey string
+}
+type FederationServerMockRepository struct {
+ ID int64
+}
+type FederationServerMock struct {
+ Persons []FederationServerMockPerson
+ Repositories []FederationServerMockRepository
+ LastPost string
+}
+
+func NewFederationServerMockPerson(id int64, name string) FederationServerMockPerson {
+ return FederationServerMockPerson{
+ ID: id,
+ Name: name,
+ PubKey: `"-----BEGIN PUBLIC KEY-----\nMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEA18H5s7N6ItZUAh9tneII\nIuZdTTa3cZlLa/9ejWAHTkcp3WLW+/zbsumlMrWYfBy2/yTm56qasWt38iY4D6ul\n` +
+ `CPiwhAqX3REvVq8tM79a2CEqZn9ka6vuXoDgBg/sBf/BUWqf7orkjUXwk/U0Egjf\nk5jcurF4vqf1u+rlAHH37dvSBaDjNj6Qnj4OP12bjfaY/yvs7+jue/eNXFHjzN4E\n` +
+ `T2H4B/yeKTJ4UuAwTlLaNbZJul2baLlHelJPAsxiYaziVuV5P+IGWckY6RSerRaZ\nAkc4mmGGtjAyfN9aewe+lNVfwS7ElFx546PlLgdQgjmeSwLX8FWxbPE5A/PmaXCs\n` +
+ `nx+nou+3dD7NluULLtdd7K+2x02trObKXCAzmi5/Dc+yKTzpFqEz+hLNCz7TImP/\ncK//NV9Q+X67J9O27baH9R9ZF4zMw8rv2Pg0WLSw1z7lLXwlgIsDapeMCsrxkVO4\n` +
+ `LXX5AQ1xQNtlssnVoUBqBrvZsX2jUUKUocvZqMGuE4hfAgMBAAE=\n-----END PUBLIC KEY-----\n"`,
+ }
+}
+
+func NewFederationServerMockRepository(id int64) FederationServerMockRepository {
+ return FederationServerMockRepository{
+ ID: id,
+ }
+}
+
+func (p FederationServerMockPerson) marshal(host string) string {
+ return fmt.Sprintf(`{"@context":["https://www.w3.org/ns/activitystreams","https://w3id.org/security/v1"],`+
+ `"id":"http://%[1]v/api/activitypub/user-id/%[2]v",`+
+ `"type":"Person",`+
+ `"icon":{"type":"Image","mediaType":"image/png","url":"http://%[1]v/avatars/1bb05d9a5f6675ed0272af9ea193063c"},`+
+ `"url":"http://%[1]v/%[2]v",`+
+ `"inbox":"http://%[1]v/api/activitypub/user-id/%[2]v/inbox",`+
+ `"outbox":"http://%[1]v/api/activitypub/user-id/%[2]v/outbox",`+
+ `"preferredUsername":"%[3]v",`+
+ `"publicKey":{"id":"http://%[1]v/api/activitypub/user-id/%[2]v#main-key",`+
+ `"owner":"http://%[1]v/api/activitypub/user-id/%[2]v",`+
+ `"publicKeyPem":%[4]v}}`, host, p.ID, p.Name, p.PubKey)
+}
+
+func NewFederationServerMock() *FederationServerMock {
+ return &FederationServerMock{
+ Persons: []FederationServerMockPerson{
+ NewFederationServerMockPerson(15, "stargoose1"),
+ NewFederationServerMockPerson(30, "stargoose2"),
+ },
+ Repositories: []FederationServerMockRepository{
+ NewFederationServerMockRepository(1),
+ },
+ LastPost: "",
+ }
+}
+
+func (mock *FederationServerMock) DistantServer(t *testing.T) *httptest.Server {
+ federatedRoutes := http.NewServeMux()
+ federatedRoutes.HandleFunc("/.well-known/nodeinfo",
+ func(res http.ResponseWriter, req *http.Request) {
+ // curl -H "Accept: application/json" https://federated-repo.prod.meissa.de/.well-known/nodeinfo
+ // TODO: as soon as content-type will become important: content-type: application/json;charset=utf-8
+ fmt.Fprintf(res, `{"links":[{"href":"http://%s/api/v1/nodeinfo","rel":"http://nodeinfo.diaspora.software/ns/schema/2.1"}]}`, req.Host)
+ })
+ federatedRoutes.HandleFunc("/api/v1/nodeinfo",
+ func(res http.ResponseWriter, req *http.Request) {
+ // curl -H "Accept: application/json" https://federated-repo.prod.meissa.de/api/v1/nodeinfo
+ fmt.Fprint(res, `{"version":"2.1","software":{"name":"forgejo","version":"1.20.0+dev-3183-g976d79044",`+
+ `"repository":"https://codeberg.org/forgejo/forgejo.git","homepage":"https://forgejo.org/"},`+
+ `"protocols":["activitypub"],"services":{"inbound":[],"outbound":["rss2.0"]},`+
+ `"openRegistrations":true,"usage":{"users":{"total":14,"activeHalfyear":2}},"metadata":{}}`)
+ })
+ for _, person := range mock.Persons {
+ federatedRoutes.HandleFunc(fmt.Sprintf("/api/v1/activitypub/user-id/%v", person.ID),
+ func(res http.ResponseWriter, req *http.Request) {
+ // curl -H "Accept: application/json" https://federated-repo.prod.meissa.de/api/v1/activitypub/user-id/2
+ fmt.Fprint(res, person.marshal(req.Host))
+ })
+ }
+ for _, repository := range mock.Repositories {
+ federatedRoutes.HandleFunc(fmt.Sprintf("/api/v1/activitypub/repository-id/%v/inbox/", repository.ID),
+ func(res http.ResponseWriter, req *http.Request) {
+ if req.Method != "POST" {
+ t.Errorf("POST expected at: %q", req.URL.EscapedPath())
+ }
+ buf := new(strings.Builder)
+ _, err := io.Copy(buf, req.Body)
+ if err != nil {
+ t.Errorf("Error reading body: %q", err)
+ }
+ mock.LastPost = buf.String()
+ })
+ }
+ federatedRoutes.HandleFunc("/",
+ func(res http.ResponseWriter, req *http.Request) {
+ t.Errorf("Unhandled request: %q", req.URL.EscapedPath())
+ })
+ federatedSrv := httptest.NewServer(federatedRoutes)
+ return federatedSrv
+}
diff --git a/modules/test/logchecker.go b/modules/test/logchecker.go
index 0f12257f3e..8e8fc32216 100644
--- a/modules/test/logchecker.go
+++ b/modules/test/logchecker.go
@@ -11,7 +11,7 @@ import (
"sync/atomic"
"time"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
)
type LogChecker struct {
diff --git a/modules/test/logchecker_test.go b/modules/test/logchecker_test.go
index 0f410fed12..d81142bf1c 100644
--- a/modules/test/logchecker_test.go
+++ b/modules/test/logchecker_test.go
@@ -7,7 +7,7 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
"github.com/stretchr/testify/assert"
)
diff --git a/modules/test/utils.go b/modules/test/utils.go
index 3d884b6cbe..f60bad022e 100644
--- a/modules/test/utils.go
+++ b/modules/test/utils.go
@@ -8,7 +8,7 @@ import (
"net/http/httptest"
"strings"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/modules/json"
)
// RedirectURL returns the redirect URL of a http response.
diff --git a/modules/testlogger/testlogger.go b/modules/testlogger/testlogger.go
index 95cbb86591..b5f196ad4b 100644
--- a/modules/testlogger/testlogger.go
+++ b/modules/testlogger/testlogger.go
@@ -16,8 +16,9 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/queue"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/util"
)
var (
@@ -131,6 +132,8 @@ var ignoredErrorMessage = []string{
`:SSHLog() [E] ssh: Not allowed to push to protected branch protected. HookPreReceive(last) failed: internal API error response, status=403`,
// TestGit/HTTP/BranchProtectMerge
`:SSHLog() [E] ssh: branch protected is protected from force push. HookPreReceive(last) failed: internal API error response, status=403`,
+ // TestGit/HTTP/BranchProtect
+ `:SSHLog() [E] ssh: branch before-create-2 is protected from changing file protected-file-data-`,
// TestGit/HTTP/MergeFork/CreatePRAndMerge
`:DeleteBranchPost() [E] DeleteBranch: GetBranch: branch does not exist [repo_id: 1099 name: user2:master]`, // sqlite
"s/web/repo/branch.go:108:DeleteBranchPost() [E] DeleteBranch: GetBranch: branch does not exist [repo_id: 10000 name: user2:master]", // mysql
@@ -443,10 +446,7 @@ func (w *testLoggerWriterCloser) Reset() error {
func PrintCurrentTest(t testing.TB, skip ...int) func() {
t.Helper()
start := time.Now()
- actualSkip := 1
- if len(skip) > 0 {
- actualSkip = skip[0] + 1
- }
+ actualSkip := util.OptionalArg(skip) + 1
_, filename, line, _ := runtime.Caller(actualSkip)
if log.CanColorStdout {
@@ -471,7 +471,7 @@ func PrintCurrentTest(t testing.TB, skip ...int) func() {
_, _ = fmt.Fprintf(os.Stdout, "+++ %s ... still flushing after %v ...\n", t.Name(), SlowFlush)
}
})
- if err := queue.GetManager().FlushAll(context.Background(), time.Minute); err != nil {
+ if err := queue.GetManager().FlushAll(t.Context(), time.Minute); err != nil {
t.Errorf("Flushing queues failed with error %v", err)
}
timer.Stop()
@@ -486,7 +486,7 @@ func PrintCurrentTest(t testing.TB, skip ...int) func() {
if err := WriterCloser.popT(); err != nil {
// disable test failure for now (too flacky)
- _, _ = fmt.Fprintf(os.Stdout, "testlogger.go:recordError() FATAL ERROR: log.Error has been called: %v", err)
+ _, _ = fmt.Fprintf(os.Stdout, "testlogger.go:recordError() FATAL ERROR: log.Error has been called: %v\n", err)
// t.Errorf("testlogger.go:recordError() FATAL ERROR: log.Error has been called: %v", err)
}
}
diff --git a/modules/timeutil/datetime.go b/modules/timeutil/datetime.go
deleted file mode 100644
index c089173560..0000000000
--- a/modules/timeutil/datetime.go
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2023 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package timeutil
-
-import (
- "fmt"
- "html"
- "html/template"
- "strings"
- "time"
-)
-
-// DateTime renders an absolute time HTML element by datetime.
-func DateTime(format string, datetime any, extraAttrs ...string) template.HTML {
- // TODO: remove the extraAttrs argument, it's not used in any call to DateTime
-
- if p, ok := datetime.(*time.Time); ok {
- datetime = *p
- }
- if p, ok := datetime.(*TimeStamp); ok {
- datetime = *p
- }
- switch v := datetime.(type) {
- case TimeStamp:
- datetime = v.AsTime()
- case int:
- datetime = TimeStamp(v).AsTime()
- case int64:
- datetime = TimeStamp(v).AsTime()
- }
-
- var datetimeEscaped, textEscaped string
- switch v := datetime.(type) {
- case nil:
- return "-"
- case string:
- datetimeEscaped = html.EscapeString(v)
- textEscaped = datetimeEscaped
- case time.Time:
- if v.IsZero() || v.Unix() == 0 {
- return "-"
- }
- datetimeEscaped = html.EscapeString(v.Format(time.RFC3339))
- if format == "full" {
- textEscaped = html.EscapeString(v.Format("2006-01-02 15:04:05 -07:00"))
- } else {
- textEscaped = html.EscapeString(v.Format("2006-01-02"))
- }
- default:
- panic(fmt.Sprintf("Unsupported time type %T", datetime))
- }
-
- attrs := make([]string, 0, 10+len(extraAttrs))
- attrs = append(attrs, extraAttrs...)
- attrs = append(attrs, `weekday=""`, `year="numeric"`)
-
- switch format {
- case "short", "long": // date only
- attrs = append(attrs, `month="`+format+`"`, `day="numeric"`)
- return template.HTML(fmt.Sprintf(`%s `, strings.Join(attrs, " "), datetimeEscaped, textEscaped))
- case "full": // full date including time
- attrs = append(attrs, `format="datetime"`, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`, `data-tooltip-content`, `data-tooltip-interactive="true"`)
- return template.HTML(fmt.Sprintf(`%s `, strings.Join(attrs, " "), datetimeEscaped, textEscaped))
- default:
- panic(fmt.Sprintf("Unsupported format %s", format))
- }
-}
diff --git a/modules/timeutil/datetime_test.go b/modules/timeutil/datetime_test.go
deleted file mode 100644
index ac2ce35ba2..0000000000
--- a/modules/timeutil/datetime_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2023 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package timeutil
-
-import (
- "testing"
- "time"
-
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestDateTime(t *testing.T) {
- testTz, _ := time.LoadLocation("America/New_York")
- defer test.MockVariableValue(&setting.DefaultUILocation, testTz)()
-
- refTimeStr := "2018-01-01T00:00:00Z"
- refDateStr := "2018-01-01"
- refTime, _ := time.Parse(time.RFC3339, refTimeStr)
- refTimeStamp := TimeStamp(refTime.Unix())
-
- assert.EqualValues(t, "-", DateTime("short", nil))
- assert.EqualValues(t, "-", DateTime("short", 0))
- assert.EqualValues(t, "-", DateTime("short", time.Time{}))
- assert.EqualValues(t, "-", DateTime("short", TimeStamp(0)))
-
- actual := DateTime("short", "invalid")
- assert.EqualValues(t, `invalid `, actual)
-
- actual = DateTime("short", refTimeStr)
- assert.EqualValues(t, `2018-01-01T00:00:00Z `, actual)
-
- actual = DateTime("short", refTime)
- assert.EqualValues(t, `2018-01-01 `, actual)
-
- actual = DateTime("short", refDateStr)
- assert.EqualValues(t, `2018-01-01 `, actual)
-
- actual = DateTime("short", refTimeStamp)
- assert.EqualValues(t, `2017-12-31 `, actual)
-
- actual = DateTime("full", refTimeStamp)
- assert.EqualValues(t, `2017-12-31 19:00:00 -05:00 `, actual)
-}
diff --git a/modules/timeutil/executable.go b/modules/timeutil/executable.go
index 57ae8b2a9d..7b30176df0 100644
--- a/modules/timeutil/executable.go
+++ b/modules/timeutil/executable.go
@@ -9,7 +9,7 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
)
var (
diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go
index dba42c793a..b0bbe25f98 100644
--- a/modules/timeutil/since.go
+++ b/modules/timeutil/since.go
@@ -4,13 +4,10 @@
package timeutil
import (
- "fmt"
- "html/template"
"strings"
"time"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/translation"
)
// Seconds-based time units
@@ -81,16 +78,11 @@ func computeTimeDiffFloor(diff int64, lang translation.Locale) (int64, string) {
return diff, diffStr
}
-// MinutesToFriendly returns a user friendly string with number of minutes
+// MinutesToFriendly returns a user-friendly string with number of minutes
// converted to hours and minutes.
func MinutesToFriendly(minutes int, lang translation.Locale) string {
duration := time.Duration(minutes) * time.Minute
- return TimeSincePro(time.Now().Add(-duration), lang)
-}
-
-// TimeSincePro calculates the time interval and generate full user-friendly string.
-func TimeSincePro(then time.Time, lang translation.Locale) string {
- return timeSincePro(then, time.Now(), lang)
+ return timeSincePro(time.Now().Add(-duration), time.Now(), lang)
}
func timeSincePro(then, now time.Time, lang translation.Locale) string {
@@ -114,32 +106,3 @@ func timeSincePro(then, now time.Time, lang translation.Locale) string {
}
return strings.TrimPrefix(timeStr, ", ")
}
-
-func timeSinceUnix(then, now time.Time, _ translation.Locale) template.HTML {
- friendlyText := then.Format("2006-01-02 15:04:05 -07:00")
-
- // document: https://github.com/github/relative-time-element
- attrs := `tense="past"`
- isFuture := now.Before(then)
- if isFuture {
- attrs = `tense="future"`
- }
-
- // declare data-tooltip-content attribute to switch from "title" tooltip to "tippy" tooltip
- htm := fmt.Sprintf(`%s `,
- attrs, then.Format(time.RFC3339), friendlyText)
- return template.HTML(htm)
-}
-
-// TimeSince renders relative time HTML given a time.Time
-func TimeSince(then time.Time, lang translation.Locale) template.HTML {
- if setting.UI.PreferredTimestampTense == "absolute" {
- return DateTime("full", then)
- }
- return timeSinceUnix(then, time.Now(), lang)
-}
-
-// TimeSinceUnix renders relative time HTML given a TimeStamp
-func TimeSinceUnix(then TimeStamp, lang translation.Locale) template.HTML {
- return TimeSince(then.AsLocalTime(), lang)
-}
diff --git a/modules/timeutil/since_test.go b/modules/timeutil/since_test.go
index 40fefe8700..b47b2c76dd 100644
--- a/modules/timeutil/since_test.go
+++ b/modules/timeutil/since_test.go
@@ -9,8 +9,8 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
"github.com/stretchr/testify/assert"
)
diff --git a/modules/timeutil/timestamp.go b/modules/timeutil/timestamp.go
index 27a80b6682..783ccba30b 100644
--- a/modules/timeutil/timestamp.go
+++ b/modules/timeutil/timestamp.go
@@ -6,7 +6,7 @@ package timeutil
import (
"time"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
// TimeStamp defines a timestamp
diff --git a/modules/timeutil/timestampnano.go b/modules/timeutil/timestampnano.go
index 4a9f7955b9..e2e86b863f 100644
--- a/modules/timeutil/timestampnano.go
+++ b/modules/timeutil/timestampnano.go
@@ -6,7 +6,7 @@ package timeutil
import (
"time"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
// TimeStampNano is for nano time in database, do not use it unless there is a real requirement.
diff --git a/modules/translation/i18n/dummy.go b/modules/translation/i18n/dummy.go
new file mode 100644
index 0000000000..861672c619
--- /dev/null
+++ b/modules/translation/i18n/dummy.go
@@ -0,0 +1,58 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package i18n
+
+import (
+ "fmt"
+ "html/template"
+ "reflect"
+ "slices"
+ "strings"
+)
+
+type KeyLocale struct{}
+
+var _ Locale = (*KeyLocale)(nil)
+
+// HasKey implements Locale.
+func (k *KeyLocale) HasKey(trKey string) bool {
+ return true
+}
+
+// TrHTML implements Locale.
+func (k *KeyLocale) TrHTML(trKey string, trArgs ...any) template.HTML {
+ return template.HTML(k.TrString(trKey, PrepareArgsForHTML(trArgs...)...))
+}
+
+// TrString implements Locale.
+func (k *KeyLocale) TrString(trKey string, trArgs ...any) string {
+ return FormatDummy(trKey, trArgs...)
+}
+
+// TrPluralString implements Locale.
+func (k *KeyLocale) TrPluralString(count any, trKey string, trArgs ...any) template.HTML {
+ return template.HTML(FormatDummy(trKey, PrepareArgsForHTML(trArgs...)...))
+}
+
+func FormatDummy(trKey string, args ...any) string {
+ if len(args) == 0 {
+ return fmt.Sprintf("(%s)", trKey)
+ }
+
+ fmtArgs := make([]any, 0, len(args)+1)
+ fmtArgs = append(fmtArgs, trKey)
+ for _, arg := range args {
+ val := reflect.ValueOf(arg)
+ if val.Kind() == reflect.Slice {
+ for i := 0; i < val.Len(); i++ {
+ fmtArgs = append(fmtArgs, val.Index(i).Interface())
+ }
+ } else {
+ fmtArgs = append(fmtArgs, arg)
+ }
+ }
+
+ template := fmt.Sprintf("(%%s: %s)", strings.Join(slices.Repeat([]string{"%v"}, len(fmtArgs)-1), ", "))
+ return fmt.Sprintf(template, fmtArgs...)
+}
diff --git a/modules/translation/i18n/dummy_test.go b/modules/translation/i18n/dummy_test.go
new file mode 100644
index 0000000000..1df3d0c348
--- /dev/null
+++ b/modules/translation/i18n/dummy_test.go
@@ -0,0 +1,19 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package i18n_test
+
+import (
+ "testing"
+
+ "forgejo.org/modules/translation/i18n"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestFormatDummy(t *testing.T) {
+ assert.Equal(t, "(admin.config.git_max_diff_lines)", i18n.FormatDummy("admin.config.git_max_diff_lines"))
+ assert.Equal(t, "(dashboard)", i18n.FormatDummy("dashboard"))
+ assert.Equal(t, "(branch.create_branch: main)", i18n.FormatDummy("branch.create_branch", "main"))
+ assert.Equal(t, "(test.test: a, 1, true)", i18n.FormatDummy("test.test", "a", 1, true))
+}
diff --git a/modules/translation/i18n/errors.go b/modules/translation/i18n/errors.go
index 7f64ccf908..63a5f48dfa 100644
--- a/modules/translation/i18n/errors.go
+++ b/modules/translation/i18n/errors.go
@@ -4,10 +4,12 @@
package i18n
import (
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
var (
- ErrLocaleAlreadyExist = util.SilentWrap{Message: "lang already exists", Err: util.ErrAlreadyExist}
- ErrUncertainArguments = util.SilentWrap{Message: "arguments to i18n should not contain uncertain slices", Err: util.ErrInvalidArgument}
+ ErrLocaleAlreadyExist = util.SilentWrap{Message: "lang already exists", Err: util.ErrAlreadyExist}
+ ErrLocaleDoesNotExist = util.SilentWrap{Message: "lang does not exist", Err: util.ErrNotExist}
+ ErrTranslationDoesNotExist = util.SilentWrap{Message: "translation does not exist", Err: util.ErrNotExist}
+ ErrUncertainArguments = util.SilentWrap{Message: "arguments to i18n should not contain uncertain slices", Err: util.ErrInvalidArgument}
)
diff --git a/modules/translation/i18n/i18n.go b/modules/translation/i18n/i18n.go
index 1555cd961e..e447502a3b 100644
--- a/modules/translation/i18n/i18n.go
+++ b/modules/translation/i18n/i18n.go
@@ -8,11 +8,28 @@ import (
"io"
)
+type (
+ PluralFormIndex uint8
+ PluralFormRule func(int64) PluralFormIndex
+)
+
+const (
+ PluralFormZero PluralFormIndex = iota
+ PluralFormOne
+ PluralFormTwo
+ PluralFormFew
+ PluralFormMany
+ PluralFormOther
+)
+
var DefaultLocales = NewLocaleStore()
type Locale interface {
// TrString translates a given key and arguments for a language
TrString(trKey string, trArgs ...any) string
+ // TrPluralString translates a given pluralized key and arguments for a language.
+ // This function returns an error if new-style support for the given key is not available.
+ TrPluralString(count any, trKey string, trArgs ...any) template.HTML
// TrHTML translates a given key and arguments for a language, string arguments are escaped to HTML
TrHTML(trKey string, trArgs ...any) template.HTML
// HasKey reports if a locale has a translation for a given key
@@ -31,8 +48,10 @@ type LocaleStore interface {
Locale(langName string) (Locale, bool)
// HasLang returns whether a given language is present in the store
HasLang(langName string) bool
- // AddLocaleByIni adds a new language to the store
- AddLocaleByIni(langName, langDesc string, source, moreSource []byte) error
+ // AddLocaleByIni adds a new old-style language to the store
+ AddLocaleByIni(langName, langDesc string, pluralRule PluralFormRule, source, moreSource []byte) error
+ // AddLocaleByJSON adds new-style content to an existing language to the store
+ AddToLocaleFromJSON(langName string, source []byte) error
}
// ResetDefaultLocales resets the current default locales
diff --git a/modules/translation/i18n/i18n_test.go b/modules/translation/i18n/i18n_test.go
index b364992dfe..a0458f0b8e 100644
--- a/modules/translation/i18n/i18n_test.go
+++ b/modules/translation/i18n/i18n_test.go
@@ -9,8 +9,29 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
+var MockPluralRule PluralFormRule = func(n int64) PluralFormIndex {
+ if n == 0 {
+ return PluralFormZero
+ }
+ if n == 1 {
+ return PluralFormOne
+ }
+ if n >= 2 && n <= 4 {
+ return PluralFormFew
+ }
+ return PluralFormOther
+}
+
+var MockPluralRuleEnglish PluralFormRule = func(n int64) PluralFormIndex {
+ if n == 1 {
+ return PluralFormOne
+ }
+ return PluralFormOther
+}
+
func TestLocaleStore(t *testing.T) {
testData1 := []byte(`
.dot.name = Dot Name
@@ -26,11 +47,48 @@ fmt = %[2]s %[1]s
[section]
sub = Changed Sub String
+commits = fallback value for commits
+`)
+
+ testDataJSON2 := []byte(`
+{
+ "section.json": "the JSON is %s",
+ "section.commits": {
+ "one": "one %d commit",
+ "few": "some %d commits",
+ "other": "lots of %d commits"
+ },
+ "section.incomplete": {
+ "few": "some %d objects (translated)"
+ },
+ "nested": {
+ "outer": {
+ "inner": {
+ "json": "Hello World",
+ "issue": {
+ "one": "one %d issue",
+ "few": "some %d issues",
+ "other": "lots of %d issues"
+ }
+ }
+ }
+ }
+}
+`)
+ testDataJSON1 := []byte(`
+{
+ "section.incomplete": {
+ "one": "[untranslated] some %d object",
+ "other": "[untranslated] some %d objects"
+ }
+}
`)
ls := NewLocaleStore()
- assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1, nil))
- assert.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", testData2, nil))
+ require.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", MockPluralRuleEnglish, testData1, nil))
+ require.NoError(t, ls.AddLocaleByIni("lang2", "Lang2", MockPluralRule, testData2, nil))
+ require.NoError(t, ls.AddToLocaleFromJSON("lang1", testDataJSON1))
+ require.NoError(t, ls.AddToLocaleFromJSON("lang2", testDataJSON2))
ls.SetDefaultLang("lang1")
lang1, _ := ls.Locale("lang1")
@@ -55,13 +113,61 @@ sub = Changed Sub String
result2 := lang2.TrHTML("section.mixed", "a&b")
assert.EqualValues(t, `test value; a&b `, result2)
+ result = lang2.TrString("section.json", "valid")
+ assert.Equal(t, "the JSON is valid", result)
+
+ result = lang2.TrString("nested.outer.inner.json")
+ assert.Equal(t, "Hello World", result)
+
+ result = lang2.TrString("section.commits")
+ assert.Equal(t, "lots of %d commits", result)
+
+ result2 = lang2.TrPluralString(1, "section.commits", 1)
+ assert.EqualValues(t, "one 1 commit", result2)
+
+ result2 = lang2.TrPluralString(3, "section.commits", 3)
+ assert.EqualValues(t, "some 3 commits", result2)
+
+ result2 = lang2.TrPluralString(8, "section.commits", 8)
+ assert.EqualValues(t, "lots of 8 commits", result2)
+
+ result2 = lang2.TrPluralString(0, "section.commits")
+ assert.EqualValues(t, "section.commits", result2)
+
+ result2 = lang2.TrPluralString(1, "nested.outer.inner.issue", 1)
+ assert.EqualValues(t, "one 1 issue", result2)
+
+ result2 = lang2.TrPluralString(3, "nested.outer.inner.issue", 3)
+ assert.EqualValues(t, "some 3 issues", result2)
+
+ result2 = lang2.TrPluralString(9, "nested.outer.inner.issue", 9)
+ assert.EqualValues(t, "lots of 9 issues", result2)
+
+ result2 = lang2.TrPluralString(3, "section.incomplete", 3)
+ assert.EqualValues(t, "some 3 objects (translated)", result2)
+
+ result2 = lang2.TrPluralString(1, "section.incomplete", 1)
+ assert.EqualValues(t, "[untranslated] some 1 object", result2)
+
+ result2 = lang2.TrPluralString(7, "section.incomplete", 7)
+ assert.EqualValues(t, "[untranslated] some 7 objects", result2)
+
langs, descs := ls.ListLangNameDesc()
assert.ElementsMatch(t, []string{"lang1", "lang2"}, langs)
assert.ElementsMatch(t, []string{"Lang1", "Lang2"}, descs)
- found := lang1.HasKey("no-such")
+ // Test HasKey for JSON
+ found := lang2.HasKey("section.json")
+ assert.True(t, found)
+
+ // Test HasKey for INI
+ found = lang2.HasKey("section.sub")
+ assert.True(t, found)
+
+ found = lang1.HasKey("no-such")
assert.False(t, found)
- assert.NoError(t, ls.Close())
+ assert.EqualValues(t, "no-such", lang1.TrString("no-such"))
+ require.NoError(t, ls.Close())
}
func TestLocaleStoreMoreSource(t *testing.T) {
@@ -76,7 +182,7 @@ c=22
`)
ls := NewLocaleStore()
- assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", testData1, testData2))
+ require.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", MockPluralRule, testData1, testData2))
lang1, _ := ls.Locale("lang1")
assert.Equal(t, "11", lang1.TrString("a"))
assert.Equal(t, "21", lang1.TrString("b"))
@@ -117,7 +223,7 @@ func (e *errorPointerReceiver) Error() string {
func TestLocaleWithTemplate(t *testing.T) {
ls := NewLocaleStore()
- assert.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", []byte(`key=%s `), nil))
+ require.NoError(t, ls.AddLocaleByIni("lang1", "Lang1", MockPluralRule, []byte(`key=%s `), nil))
lang1, _ := ls.Locale("lang1")
tmpl := template.New("test").Funcs(template.FuncMap{"tr": lang1.TrHTML})
@@ -143,7 +249,7 @@ func TestLocaleWithTemplate(t *testing.T) {
buf := &strings.Builder{}
for _, c := range cases {
buf.Reset()
- assert.NoError(t, tmpl.Execute(buf, map[string]any{"var": c.in}))
+ require.NoError(t, tmpl.Execute(buf, map[string]any{"var": c.in}))
assert.Equal(t, c.want, buf.String())
}
}
@@ -180,11 +286,11 @@ func TestLocaleStoreQuirks(t *testing.T) {
for _, testData := range testDataList {
ls := NewLocaleStore()
- err := ls.AddLocaleByIni("lang1", "Lang1", []byte("a="+testData.in), nil)
+ err := ls.AddLocaleByIni("lang1", "Lang1", nil, []byte("a="+testData.in), nil)
lang1, _ := ls.Locale("lang1")
- assert.NoError(t, err, testData.hint)
+ require.NoError(t, err, testData.hint)
assert.Equal(t, testData.out, lang1.TrString("a"), testData.hint)
- assert.NoError(t, ls.Close())
+ require.NoError(t, ls.Close())
}
// TODO: Crowdin needs the strings to be quoted correctly and doesn't like incomplete quotes
diff --git a/modules/translation/i18n/localestore.go b/modules/translation/i18n/localestore.go
index 0e6ddab401..1b64139690 100644
--- a/modules/translation/i18n/localestore.go
+++ b/modules/translation/i18n/localestore.go
@@ -1,4 +1,5 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package i18n
@@ -8,8 +9,10 @@ import (
"html/template"
"slices"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
// This file implements the static LocaleStore that will not watch for changes
@@ -18,6 +21,9 @@ type locale struct {
store *localeStore
langName string
idxToMsgMap map[int]string // the map idx is generated by store's trKeyToIdxMap
+
+ newStyleMessages map[string]string
+ pluralRule PluralFormRule
}
var _ Locale = (*locale)(nil)
@@ -38,8 +44,19 @@ func NewLocaleStore() LocaleStore {
return &localeStore{localeMap: make(map[string]*locale), trKeyToIdxMap: make(map[string]int)}
}
+const (
+ PluralFormSeparator string = "\036"
+)
+
+// A note about pluralization rules.
+// go-i18n supports plural rules in theory.
+// In practice, it relies on another library that hardcodes a list of common languages
+// and their plural rules, and does not support languages not hardcoded there.
+// So we pretend that all languages are English and use our own function to extract
+// the correct plural form for a given count and language.
+
// AddLocaleByIni adds locale by ini into the store
-func (store *localeStore) AddLocaleByIni(langName, langDesc string, source, moreSource []byte) error {
+func (store *localeStore) AddLocaleByIni(langName, langDesc string, pluralRule PluralFormRule, source, moreSource []byte) error {
if _, ok := store.localeMap[langName]; ok {
return ErrLocaleAlreadyExist
}
@@ -47,7 +64,7 @@ func (store *localeStore) AddLocaleByIni(langName, langDesc string, source, more
store.langNames = append(store.langNames, langName)
store.langDescs = append(store.langDescs, langDesc)
- l := &locale{store: store, langName: langName, idxToMsgMap: make(map[int]string)}
+ l := &locale{store: store, langName: langName, idxToMsgMap: make(map[int]string), pluralRule: pluralRule, newStyleMessages: make(map[string]string)}
store.localeMap[l.langName] = l
iniFile, err := setting.NewConfigProviderForLocale(source, moreSource)
@@ -78,6 +95,98 @@ func (store *localeStore) AddLocaleByIni(langName, langDesc string, source, more
return nil
}
+func RecursivelyAddTranslationsFromJSON(locale *locale, object map[string]any, prefix string) error {
+ for key, value := range object {
+ var fullkey string
+ if prefix != "" {
+ fullkey = prefix + "." + key
+ } else {
+ fullkey = key
+ }
+
+ switch v := value.(type) {
+ case string:
+ // Check whether we are adding a plural form to the parent object, or a new nested JSON object.
+
+ if key == "zero" || key == "one" || key == "two" || key == "few" || key == "many" {
+ locale.newStyleMessages[prefix+PluralFormSeparator+key] = v
+ } else if key == "other" {
+ locale.newStyleMessages[prefix] = v
+ } else {
+ locale.newStyleMessages[fullkey] = v
+ }
+
+ case map[string]any:
+ err := RecursivelyAddTranslationsFromJSON(locale, v, fullkey)
+ if err != nil {
+ return err
+ }
+
+ case nil:
+ default:
+ return fmt.Errorf("Unrecognized JSON value '%s'", value)
+ }
+ }
+
+ return nil
+}
+
+func (store *localeStore) AddToLocaleFromJSON(langName string, source []byte) error {
+ locale, ok := store.localeMap[langName]
+ if !ok {
+ return ErrLocaleDoesNotExist
+ }
+
+ var result map[string]any
+ if err := json.Unmarshal(source, &result); err != nil {
+ return err
+ }
+
+ return RecursivelyAddTranslationsFromJSON(locale, result, "")
+}
+
+func (l *locale) LookupNewStyleMessage(trKey string) string {
+ if msg, ok := l.newStyleMessages[trKey]; ok {
+ return msg
+ }
+ return ""
+}
+
+func (l *locale) LookupPlural(trKey string, count any) string {
+ n, err := util.ToInt64(count)
+ if err != nil {
+ log.Error("Invalid plural count '%s'", count)
+ return ""
+ }
+
+ pluralForm := l.pluralRule(n)
+ suffix := ""
+ switch pluralForm {
+ case PluralFormZero:
+ suffix = PluralFormSeparator + "zero"
+ case PluralFormOne:
+ suffix = PluralFormSeparator + "one"
+ case PluralFormTwo:
+ suffix = PluralFormSeparator + "two"
+ case PluralFormFew:
+ suffix = PluralFormSeparator + "few"
+ case PluralFormMany:
+ suffix = PluralFormSeparator + "many"
+ case PluralFormOther:
+ // No suffix for the "other" string.
+ default:
+ log.Error("Invalid plural form index %d for count %d", pluralForm, count)
+ return ""
+ }
+
+ if result, ok := l.newStyleMessages[trKey+suffix]; ok {
+ return result
+ }
+
+ log.Error("Missing translation for plural form index %d for count %d", pluralForm, count)
+ return ""
+}
+
func (store *localeStore) HasLang(langName string) bool {
_, ok := store.localeMap[langName]
return ok
@@ -113,22 +222,38 @@ func (store *localeStore) Close() error {
func (l *locale) TrString(trKey string, trArgs ...any) string {
format := trKey
- idx, ok := l.store.trKeyToIdxMap[trKey]
- found := false
- if ok {
- if msg, ok := l.idxToMsgMap[idx]; ok {
- format = msg // use the found translation
- found = true
- } else if def, ok := l.store.localeMap[l.store.defaultLang]; ok {
- // try to use default locale's translation
- if msg, ok := def.idxToMsgMap[idx]; ok {
- format = msg
+ if msg := l.LookupNewStyleMessage(trKey); msg != "" {
+ format = msg
+ } else {
+ // First fallback: old-style translation
+ idx, foundIndex := l.store.trKeyToIdxMap[trKey]
+ found := false
+ if foundIndex {
+ if msg, ok := l.idxToMsgMap[idx]; ok {
+ format = msg // use the found translation
found = true
}
}
- }
- if !found {
- log.Error("Missing translation %q", trKey)
+
+ if !found {
+ // Second fallback: new-style default language
+ if defaultLang, ok := l.store.localeMap[l.store.defaultLang]; ok {
+ if msg := defaultLang.LookupNewStyleMessage(trKey); msg != "" {
+ format = msg
+ found = true
+ } else if foundIndex {
+ // Third fallback: old-style default language
+ if msg, ok := defaultLang.idxToMsgMap[idx]; ok {
+ format = msg
+ found = true
+ }
+ }
+ }
+
+ if !found {
+ log.Error("Missing translation %q", trKey)
+ }
+ }
}
msg, err := Format(format, trArgs...)
@@ -138,7 +263,7 @@ func (l *locale) TrString(trKey string, trArgs ...any) string {
return msg
}
-func (l *locale) TrHTML(trKey string, trArgs ...any) template.HTML {
+func PrepareArgsForHTML(trArgs ...any) []any {
args := slices.Clone(trArgs)
for i, v := range args {
switch v := v.(type) {
@@ -152,11 +277,38 @@ func (l *locale) TrHTML(trKey string, trArgs ...any) template.HTML {
args[i] = template.HTMLEscapeString(fmt.Sprint(v))
}
}
- return template.HTML(l.TrString(trKey, args...))
+ return args
+}
+
+func (l *locale) TrHTML(trKey string, trArgs ...any) template.HTML {
+ return template.HTML(l.TrString(trKey, PrepareArgsForHTML(trArgs...)...))
+}
+
+func (l *locale) TrPluralString(count any, trKey string, trArgs ...any) template.HTML {
+ message := l.LookupPlural(trKey, count)
+
+ if message == "" {
+ if defaultLang, ok := l.store.localeMap[l.store.defaultLang]; ok {
+ message = defaultLang.LookupPlural(trKey, count)
+ }
+ if message == "" {
+ message = trKey
+ }
+ }
+
+ message, err := Format(message, PrepareArgsForHTML(trArgs...)...)
+ if err != nil {
+ log.Error("Error whilst formatting %q in %s: %v", trKey, l.langName, err)
+ }
+ return template.HTML(message)
}
// HasKey returns whether a key is present in this locale or not
func (l *locale) HasKey(trKey string) bool {
+ _, ok := l.newStyleMessages[trKey]
+ if ok {
+ return true
+ }
idx, ok := l.store.trKeyToIdxMap[trKey]
if !ok {
return false
diff --git a/modules/translation/mock.go b/modules/translation/mock.go
index fe3a1502ea..72a15b7438 100644
--- a/modules/translation/mock.go
+++ b/modules/translation/mock.go
@@ -31,10 +31,18 @@ func (l MockLocale) TrN(cnt any, key1, keyN string, args ...any) template.HTML {
return template.HTML(key1)
}
+func (l MockLocale) TrPluralString(count any, trKey string, trArgs ...any) template.HTML {
+ return template.HTML(trKey)
+}
+
func (l MockLocale) TrSize(s int64) ReadableSize {
return ReadableSize{fmt.Sprint(s), ""}
}
+func (l MockLocale) HasKey(key string) bool {
+ return true
+}
+
func (l MockLocale) PrettyNumber(v any) string {
return fmt.Sprint(v)
}
diff --git a/modules/translation/plural_rules.go b/modules/translation/plural_rules.go
new file mode 100644
index 0000000000..7e9ae39111
--- /dev/null
+++ b/modules/translation/plural_rules.go
@@ -0,0 +1,253 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+// Some useful links:
+// https://www.unicode.org/cldr/charts/46/supplemental/language_plural_rules.html
+// https://translate.codeberg.org/languages/$LANGUAGE_CODE/#information
+// https://github.com/WeblateOrg/language-data/blob/main/languages.csv
+// Note that in some cases there is ambiguity about the correct form for a given language. In this case, ask the locale's translators.
+
+package translation
+
+import (
+ "strings"
+
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/translation/i18n"
+)
+
+// The constants refer to indices below in `PluralRules` and also in i18n.js, keep them in sync!
+const (
+ PluralRuleDefault = 0
+ PluralRuleBengali = 1
+ PluralRuleIcelandic = 2
+ PluralRuleFilipino = 3
+ PluralRuleOneForm = 4
+ PluralRuleCzech = 5
+ PluralRuleRussian = 6
+ PluralRulePolish = 7
+ PluralRuleLatvian = 8
+ PluralRuleLithuanian = 9
+ PluralRuleFrench = 10
+ PluralRuleCatalan = 11
+ PluralRuleSlovenian = 12
+ PluralRuleArabic = 13
+)
+
+func GetPluralRuleImpl(langName string) int {
+ // First, check for languages with country-specific plural rules.
+ switch langName {
+ case "pt-BR":
+ return PluralRuleFrench
+
+ case "pt-PT":
+ return PluralRuleCatalan
+
+ default:
+ break
+ }
+
+ // Remove the country portion of the locale name.
+ langName = strings.Split(strings.Split(langName, "_")[0], "-")[0]
+
+ // When adding a new language not in the list, add its plural rule definition here.
+ switch langName {
+ case "en", "aa", "ab", "abr", "ada", "ae", "aeb", "af", "afh", "aii", "ain", "akk", "ale", "aln", "alt", "ami", "an", "ang", "anp", "apc", "arc", "arp", "arq", "arw", "arz", "asa", "ast", "av", "avk", "awa", "ayc", "az", "azb", "ba", "bal", "ban", "bar", "bas", "bbc", "bci", "bej", "bem", "ber", "bew", "bez", "bg", "bgc", "bgn", "bhb", "bhi", "bi", "bik", "bin", "bjj", "bjn", "bla", "bnt", "bqi", "bra", "brb", "brh", "brx", "bua", "bug", "bum", "byn", "cad", "cak", "car", "ce", "cgg", "ch", "chb", "chg", "chk", "chm", "chn", "cho", "chp", "chr", "chy", "ckb", "co", "cop", "cpe", "cpf", "cr", "crp", "cu", "cv", "da", "dak", "dar", "dcc", "de", "del", "den", "dgr", "din", "dje", "dnj", "dnk", "dru", "dry", "dua", "dum", "dv", "dyu", "ee", "efi", "egl", "egy", "eka", "el", "elx", "enm", "eo", "et", "eu", "ewo", "ext", "fan", "fat", "fbl", "ffm", "fi", "fj", "fo", "fon", "frk", "frm", "fro", "frr", "frs", "fuq", "fur", "fuv", "fvr", "fy", "gaa", "gay", "gba", "gbm", "gez", "gil", "gl", "glk", "gmh", "gn", "goh", "gom", "gon", "gor", "got", "grb", "gsw", "guc", "gum", "gur", "guz", "gwi", "ha", "hai", "haw", "haz", "hil", "hit", "hmn", "hnd", "hne", "hno", "ho", "hoc", "hoj", "hrx", "ht", "hu", "hup", "hus", "hz", "ia", "iba", "ibb", "ie", "ik", "ilo", "inh", "io", "jam", "jgo", "jmc", "jpr", "jrb", "ka", "kaa", "kac", "kaj", "kam", "kaw", "kbd", "kcg", "kfr", "kfy", "kg", "kha", "khn", "kho", "ki", "kj", "kk", "kkj", "kl", "kln", "kmb", "kmr", "kok", "kpe", "kr", "krc", "kri", "krl", "kru", "ks", "ksb", "ku", "kum", "kut", "kv", "kxm", "ky", "la", "lad", "laj", "lam", "lb", "lez", "lfn", "lg", "li", "lij", "ljp", "lki", "lmn", "lmo", "lol", "loz", "lrc", "lu", "lua", "lui", "lun", "luo", "lus", "luy", "luz", "mad", "mag", "mai", "mak", "man", "mas", "mdf", "mdh", "mdr", "men", "mer", "mfa", "mga", "mgh", "mgo", "mh", "mhr", "mic", "min", "mjw", "ml", "mn", "mnc", "mni", "mnw", "moe", "moh", "mos", "mr", "mrh", "mtr", "mus", "mwk", "mwl", "mwr", "mxc", "myv", "myx", "mzn", "na", "nah", "nap", "nb", "nd", "ndc", "nds", "ne", "new", "ng", "ngl", "nia", "nij", "niu", "nl", "nn", "nnh", "nod", "noe", "nog", "non", "nr", "nuk", "nv", "nwc", "ny", "nym", "nyn", "nyo", "nzi", "oj", "om", "or", "os", "ota", "otk", "ovd", "pag", "pal", "pam", "pap", "pau", "pbb", "pdt", "peo", "phn", "pi", "pms", "pon", "pro", "ps", "pwn", "qu", "quc", "qug", "qya", "raj", "rap", "rar", "rcf", "rej", "rhg", "rif", "rkt", "rm", "rmt", "rn", "rng", "rof", "rom", "rue", "rup", "rw", "rwk", "sad", "sai", "sam", "saq", "sas", "sc", "sck", "sco", "sd", "sdh", "sef", "seh", "sel", "sga", "sgn", "sgs", "shn", "sid", "sjd", "skr", "sm", "sml", "sn", "snk", "so", "sog", "sou", "sq", "srn", "srr", "ss", "ssy", "st", "suk", "sus", "sux", "sv", "sw", "swg", "swv", "sxu", "syc", "syl", "syr", "szy", "ta", "tay", "tcy", "te", "tem", "teo", "ter", "tet", "tig", "tiv", "tk", "tkl", "tli", "tly", "tmh", "tn", "tog", "tr", "trv", "ts", "tsg", "tsi", "tsj", "tts", "tum", "tvl", "tw", "ty", "tyv", "tzj", "tzl", "udm", "ug", "uga", "umb", "und", "unr", "ur", "uz", "vai", "ve", "vls", "vmf", "vmw", "vo", "vot", "vro", "vun", "wae", "wal", "war", "was", "wbq", "wbr", "wep", "wtm", "xal", "xh", "xnr", "xog", "yao", "yap", "yi", "yua", "za", "zap", "zbl", "zen", "zgh", "zun", "zza":
+ return PluralRuleDefault
+
+ case "ach", "ady", "ak", "am", "arn", "as", "bh", "bho", "bn", "csw", "doi", "fa", "ff", "frc", "frp", "gu", "gug", "gun", "guw", "hi", "hy", "kab", "kn", "ln", "mfe", "mg", "mi", "mia", "nso", "oc", "pa", "pcm", "pt", "qdt", "qtp", "si", "tg", "ti", "wa", "zu":
+ return PluralRuleBengali
+
+ case "is":
+ return PluralRuleIcelandic
+
+ case "fil":
+ return PluralRuleFilipino
+
+ case "ace", "ay", "bm", "bo", "cdo", "cpx", "crh", "dz", "gan", "hak", "hnj", "hsn", "id", "ig", "ii", "ja", "jbo", "jv", "kde", "kea", "km", "ko", "kos", "lkt", "lo", "lzh", "ms", "my", "nan", "nqo", "osa", "sah", "ses", "sg", "son", "su", "th", "tlh", "to", "tok", "tpi", "tt", "vi", "wo", "wuu", "yo", "yue", "zh":
+ return PluralRuleOneForm
+
+ case "cpp", "cs", "sk":
+ return PluralRuleCzech
+
+ case "be", "bs", "cnr", "hr", "ru", "sr", "uk", "wen":
+ return PluralRuleRussian
+
+ case "csb", "pl", "szl":
+ return PluralRulePolish
+
+ case "lv", "prg":
+ return PluralRuleLatvian
+
+ case "lt":
+ return PluralRuleLithuanian
+
+ case "fr":
+ return PluralRuleFrench
+
+ case "ca", "es", "it":
+ return PluralRuleCatalan
+
+ case "sl":
+ return PluralRuleSlovenian
+
+ case "ar":
+ return PluralRuleArabic
+
+ default:
+ break
+ }
+
+ log.Error("No plural rule defined for language %s", langName)
+ return PluralRuleDefault
+}
+
+var PluralRules = []i18n.PluralFormRule{
+ // [ 0] Common 2-form, e.g. English, German
+ func(n int64) i18n.PluralFormIndex {
+ if n != 1 {
+ return i18n.PluralFormOther
+ }
+ return i18n.PluralFormOne
+ },
+
+ // [ 1] Bengali
+ func(n int64) i18n.PluralFormIndex {
+ if n > 1 {
+ return i18n.PluralFormOther
+ }
+ return i18n.PluralFormOne
+ },
+
+ // [ 2] Icelandic
+ func(n int64) i18n.PluralFormIndex {
+ if n%10 != 1 || n%100 == 11 {
+ return i18n.PluralFormOther
+ }
+ return i18n.PluralFormOne
+ },
+
+ // [ 3] Filipino
+ func(n int64) i18n.PluralFormIndex {
+ if n != 1 && n != 2 && n != 3 && (n%10 == 4 || n%10 == 6 || n%10 == 9) {
+ return i18n.PluralFormOther
+ }
+ return i18n.PluralFormOne
+ },
+
+ // [ 4] OneForm
+ func(n int64) i18n.PluralFormIndex {
+ return i18n.PluralFormOther
+ },
+
+ // [ 5] Czech
+ func(n int64) i18n.PluralFormIndex {
+ if n == 1 {
+ return i18n.PluralFormOne
+ }
+ if n >= 2 && n <= 4 {
+ return i18n.PluralFormFew
+ }
+ return i18n.PluralFormOther
+ },
+
+ // [ 6] Russian
+ func(n int64) i18n.PluralFormIndex {
+ if n%10 == 1 && n%100 != 11 {
+ return i18n.PluralFormOne
+ }
+ if n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20) {
+ return i18n.PluralFormFew
+ }
+ return i18n.PluralFormMany
+ },
+
+ // [ 7] Polish
+ func(n int64) i18n.PluralFormIndex {
+ if n == 1 {
+ return i18n.PluralFormOne
+ }
+ if n%10 >= 2 && n%10 <= 4 && (n%100 < 10 || n%100 >= 20) {
+ return i18n.PluralFormFew
+ }
+ return i18n.PluralFormMany
+ },
+
+ // [ 8] Latvian
+ func(n int64) i18n.PluralFormIndex {
+ if n%10 == 0 || n%100 >= 11 && n%100 <= 19 {
+ return i18n.PluralFormZero
+ }
+ if n%10 == 1 && n%100 != 11 {
+ return i18n.PluralFormOne
+ }
+ return i18n.PluralFormOther
+ },
+
+ // [ 9] Lithuanian
+ func(n int64) i18n.PluralFormIndex {
+ if n%10 == 1 && (n%100 < 11 || n%100 > 19) {
+ return i18n.PluralFormOne
+ }
+ if n%10 >= 2 && n%10 <= 9 && (n%100 < 11 || n%100 > 19) {
+ return i18n.PluralFormFew
+ }
+ return i18n.PluralFormMany
+ },
+
+ // [10] French
+ func(n int64) i18n.PluralFormIndex {
+ if n == 0 || n == 1 {
+ return i18n.PluralFormOne
+ }
+ if n != 0 && n%1000000 == 0 {
+ return i18n.PluralFormMany
+ }
+ return i18n.PluralFormOther
+ },
+
+ // [11] Catalan
+ func(n int64) i18n.PluralFormIndex {
+ if n == 1 {
+ return i18n.PluralFormOne
+ }
+ if n != 0 && n%1000000 == 0 {
+ return i18n.PluralFormMany
+ }
+ return i18n.PluralFormOther
+ },
+
+ // [12] Slovenian
+ func(n int64) i18n.PluralFormIndex {
+ if n%100 == 1 {
+ return i18n.PluralFormOne
+ }
+ if n%100 == 2 {
+ return i18n.PluralFormTwo
+ }
+ if n%100 == 3 || n%100 == 4 {
+ return i18n.PluralFormFew
+ }
+ return i18n.PluralFormOther
+ },
+
+ // [13] Arabic
+ func(n int64) i18n.PluralFormIndex {
+ if n == 0 {
+ return i18n.PluralFormZero
+ }
+ if n == 1 {
+ return i18n.PluralFormOne
+ }
+ if n == 2 {
+ return i18n.PluralFormTwo
+ }
+ if n%100 >= 3 && n%100 <= 10 {
+ return i18n.PluralFormFew
+ }
+ if n%100 >= 11 {
+ return i18n.PluralFormMany
+ }
+ return i18n.PluralFormOther
+ },
+}
diff --git a/modules/translation/translation.go b/modules/translation/translation.go
index 16eb55e28e..1b763764f1 100644
--- a/modules/translation/translation.go
+++ b/modules/translation/translation.go
@@ -10,11 +10,11 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/options"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation/i18n"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/options"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation/i18n"
+ "forgejo.org/modules/util"
"github.com/dustin/go-humanize"
"golang.org/x/text/language"
@@ -32,10 +32,15 @@ type Locale interface {
TrString(string, ...any) string
Tr(key string, args ...any) template.HTML
+ // New-style pluralized strings
+ TrPluralString(count any, trKey string, trArgs ...any) template.HTML
+ // Old-style pseudo-pluralized strings, deprecated
TrN(cnt any, key1, keyN string, args ...any) template.HTML
TrSize(size int64) ReadableSize
+ HasKey(trKey string) bool
+
PrettyNumber(v any) string
}
@@ -100,8 +105,17 @@ func InitLocales(ctx context.Context) {
}
key := "locale_" + setting.Langs[i] + ".ini"
- if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], localeDataBase, localeData[key]); err != nil {
- log.Error("Failed to set messages to %s: %v", setting.Langs[i], err)
+ if err = i18n.DefaultLocales.AddLocaleByIni(setting.Langs[i], setting.Names[i], PluralRules[GetPluralRuleImpl(setting.Langs[i])], localeDataBase, localeData[key]); err != nil {
+ log.Error("Failed to set old-style messages to %s: %v", setting.Langs[i], err)
+ }
+
+ key = "locale_next/locale_" + setting.Langs[i] + ".json"
+ if bytes, err := options.AssetFS().ReadFile(key); err == nil {
+ if err = i18n.DefaultLocales.AddToLocaleFromJSON(setting.Langs[i], bytes); err != nil {
+ log.Error("Failed to add new-style messages to %s: %v", setting.Langs[i], err)
+ }
+ } else {
+ log.Error("Failed to open new-style messages for %s: %v", setting.Langs[i], err)
}
}
if len(setting.Langs) != 0 {
@@ -160,6 +174,16 @@ func NewLocale(lang string) Locale {
defer lock.RUnlock()
}
+ if lang == "dummy" {
+ l := &locale{
+ Locale: &i18n.KeyLocale{},
+ Lang: lang,
+ LangName: lang,
+ msgPrinter: message.NewPrinter(language.English),
+ }
+ return l
+ }
+
langName := "unknown"
if l, ok := allLangMap[lang]; ok {
langName = l.Name
diff --git a/modules/translation/translation_test.go b/modules/translation/translation_test.go
index bffbb155ca..356b85f946 100644
--- a/modules/translation/translation_test.go
+++ b/modules/translation/translation_test.go
@@ -8,7 +8,7 @@ package translation
import (
"testing"
- "code.gitea.io/gitea/modules/translation/i18n"
+ "forgejo.org/modules/translation/i18n"
"github.com/stretchr/testify/assert"
)
@@ -48,3 +48,111 @@ func TestPrettyNumber(t *testing.T) {
assert.EqualValues(t, "1,000,000", l.PrettyNumber(1000000))
assert.EqualValues(t, "1,000,000.1", l.PrettyNumber(1000000.1))
}
+
+func TestGetPluralRule(t *testing.T) {
+ assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("en"))
+ assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("en-US"))
+ assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("en_UK"))
+ assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("nds"))
+ assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("de-DE"))
+
+ assert.Equal(t, PluralRuleOneForm, GetPluralRuleImpl("zh"))
+ assert.Equal(t, PluralRuleOneForm, GetPluralRuleImpl("ja"))
+
+ assert.Equal(t, PluralRuleBengali, GetPluralRuleImpl("bn"))
+
+ assert.Equal(t, PluralRuleIcelandic, GetPluralRuleImpl("is"))
+
+ assert.Equal(t, PluralRuleFilipino, GetPluralRuleImpl("fil"))
+
+ assert.Equal(t, PluralRuleCzech, GetPluralRuleImpl("cs"))
+
+ assert.Equal(t, PluralRuleRussian, GetPluralRuleImpl("ru"))
+
+ assert.Equal(t, PluralRulePolish, GetPluralRuleImpl("pl"))
+
+ assert.Equal(t, PluralRuleLatvian, GetPluralRuleImpl("lv"))
+
+ assert.Equal(t, PluralRuleLithuanian, GetPluralRuleImpl("lt"))
+
+ assert.Equal(t, PluralRuleFrench, GetPluralRuleImpl("fr"))
+
+ assert.Equal(t, PluralRuleCatalan, GetPluralRuleImpl("ca"))
+
+ assert.Equal(t, PluralRuleSlovenian, GetPluralRuleImpl("sl"))
+
+ assert.Equal(t, PluralRuleArabic, GetPluralRuleImpl("ar"))
+
+ assert.Equal(t, PluralRuleCatalan, GetPluralRuleImpl("pt-PT"))
+ assert.Equal(t, PluralRuleFrench, GetPluralRuleImpl("pt-BR"))
+
+ assert.Equal(t, PluralRuleDefault, GetPluralRuleImpl("invalid"))
+}
+
+func TestApplyPluralRule(t *testing.T) {
+ testCases := []struct {
+ expect i18n.PluralFormIndex
+ pluralRule int
+ values []int64
+ }{
+ {i18n.PluralFormOne, PluralRuleDefault, []int64{1}},
+ {i18n.PluralFormOther, PluralRuleDefault, []int64{0, 2, 10, 256}},
+
+ {i18n.PluralFormOther, PluralRuleOneForm, []int64{0, 1, 2}},
+
+ {i18n.PluralFormOne, PluralRuleBengali, []int64{0, 1}},
+ {i18n.PluralFormOther, PluralRuleBengali, []int64{2, 10, 256}},
+
+ {i18n.PluralFormOne, PluralRuleIcelandic, []int64{1, 21, 31}},
+ {i18n.PluralFormOther, PluralRuleIcelandic, []int64{0, 2, 11, 15, 256}},
+
+ {i18n.PluralFormOne, PluralRuleFilipino, []int64{0, 1, 2, 3, 5, 7, 8, 10, 11, 12, 257}},
+ {i18n.PluralFormOther, PluralRuleFilipino, []int64{4, 6, 9, 14, 16, 19, 256}},
+
+ {i18n.PluralFormOne, PluralRuleCzech, []int64{1}},
+ {i18n.PluralFormFew, PluralRuleCzech, []int64{2, 3, 4}},
+ {i18n.PluralFormOther, PluralRuleCzech, []int64{5, 0, 12, 78, 254}},
+
+ {i18n.PluralFormOne, PluralRuleRussian, []int64{1, 21, 31}},
+ {i18n.PluralFormFew, PluralRuleRussian, []int64{2, 23, 34}},
+ {i18n.PluralFormMany, PluralRuleRussian, []int64{0, 5, 11, 37, 111, 256}},
+
+ {i18n.PluralFormOne, PluralRulePolish, []int64{1}},
+ {i18n.PluralFormFew, PluralRulePolish, []int64{2, 23, 34}},
+ {i18n.PluralFormMany, PluralRulePolish, []int64{0, 5, 11, 21, 37, 256}},
+
+ {i18n.PluralFormZero, PluralRuleLatvian, []int64{0, 10, 11, 17}},
+ {i18n.PluralFormOne, PluralRuleLatvian, []int64{1, 21, 71}},
+ {i18n.PluralFormOther, PluralRuleLatvian, []int64{2, 7, 22, 23, 256}},
+
+ {i18n.PluralFormOne, PluralRuleLithuanian, []int64{1, 21, 31}},
+ {i18n.PluralFormFew, PluralRuleLithuanian, []int64{2, 5, 9, 23, 34, 256}},
+ {i18n.PluralFormMany, PluralRuleLithuanian, []int64{0, 10, 11, 18}},
+
+ {i18n.PluralFormOne, PluralRuleFrench, []int64{0, 1}},
+ {i18n.PluralFormMany, PluralRuleFrench, []int64{1000000, 2000000}},
+ {i18n.PluralFormOther, PluralRuleFrench, []int64{2, 4, 10, 256}},
+
+ {i18n.PluralFormOne, PluralRuleCatalan, []int64{1}},
+ {i18n.PluralFormMany, PluralRuleCatalan, []int64{1000000, 2000000}},
+ {i18n.PluralFormOther, PluralRuleCatalan, []int64{0, 2, 4, 10, 256}},
+
+ {i18n.PluralFormOne, PluralRuleSlovenian, []int64{1, 101, 201, 501}},
+ {i18n.PluralFormTwo, PluralRuleSlovenian, []int64{2, 102, 202, 502}},
+ {i18n.PluralFormFew, PluralRuleSlovenian, []int64{3, 103, 203, 503, 4, 104, 204, 504}},
+ {i18n.PluralFormOther, PluralRuleSlovenian, []int64{0, 5, 11, 12, 20, 256}},
+
+ {i18n.PluralFormZero, PluralRuleArabic, []int64{0}},
+ {i18n.PluralFormOne, PluralRuleArabic, []int64{1}},
+ {i18n.PluralFormTwo, PluralRuleArabic, []int64{2}},
+ {i18n.PluralFormFew, PluralRuleArabic, []int64{3, 4, 9, 10, 103, 104}},
+ {i18n.PluralFormMany, PluralRuleArabic, []int64{11, 12, 13, 14, 17, 111, 256}},
+ {i18n.PluralFormOther, PluralRuleArabic, []int64{100, 101, 102}},
+ }
+
+ for _, tc := range testCases {
+ for _, n := range tc.values {
+ assert.Equal(t, tc.expect, PluralRules[tc.pluralRule](n), "Testcase for plural rule %d, value %d", tc.pluralRule, n)
+ }
+ }
+}
diff --git a/modules/turnstile/turnstile.go b/modules/turnstile/turnstile.go
index 38d0233446..31ba256195 100644
--- a/modules/turnstile/turnstile.go
+++ b/modules/turnstile/turnstile.go
@@ -11,8 +11,8 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
)
// Response is the structure of JSON returned from API
diff --git a/modules/typesniffer/typesniffer.go b/modules/typesniffer/typesniffer.go
index 6aec5c285e..a8fc70e54c 100644
--- a/modules/typesniffer/typesniffer.go
+++ b/modules/typesniffer/typesniffer.go
@@ -11,7 +11,7 @@ import (
"regexp"
"strings"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/util"
)
// Use at most this many bytes to determine Content Type.
@@ -20,6 +20,8 @@ const sniffLen = 1024
const (
// SvgMimeType MIME type of SVG images.
SvgMimeType = "image/svg+xml"
+ // AvifMimeType MIME type of AVIF images
+ AvifMimeType = "image/avif"
// ApplicationOctetStream MIME type of binary files.
ApplicationOctetStream = "application/octet-stream"
)
@@ -106,6 +108,12 @@ func DetectContentType(data []byte) SniffedType {
}
}
+ // AVIF is unsupported by http.DetectContentType
+ // Signature taken from https://stackoverflow.com/a/68322450
+ if bytes.Index(data, []byte("ftypavif")) == 4 {
+ ct = AvifMimeType
+ }
+
if strings.HasPrefix(ct, "audio/") && bytes.HasPrefix(data, []byte("ID3")) {
// The MP3 detection is quite inaccurate, any content with "ID3" prefix will result in "audio/mpeg".
// So remove the "ID3" prefix and detect again, if result is text, then it must be text content.
diff --git a/modules/typesniffer/typesniffer_test.go b/modules/typesniffer/typesniffer_test.go
index da662ab99d..8d80b4ddb4 100644
--- a/modules/typesniffer/typesniffer_test.go
+++ b/modules/typesniffer/typesniffer_test.go
@@ -11,6 +11,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestDetectContentTypeLongerThanSniffLen(t *testing.T) {
@@ -119,18 +120,28 @@ func TestIsAudio(t *testing.T) {
func TestDetectContentTypeFromReader(t *testing.T) {
mp3, _ := base64.StdEncoding.DecodeString("SUQzBAAAAAABAFRYWFgAAAASAAADbWFqb3JfYnJhbmQAbXA0MgBUWFhYAAAAEQAAA21pbm9yX3Zl")
st, err := DetectContentTypeFromReader(bytes.NewReader(mp3))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, st.IsAudio())
}
func TestDetectContentTypeOgg(t *testing.T) {
oggAudio, _ := hex.DecodeString("4f67675300020000000000000000352f0000000000007dc39163011e01766f72626973000000000244ac0000000000000071020000000000b8014f6767530000")
st, err := DetectContentTypeFromReader(bytes.NewReader(oggAudio))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, st.IsAudio())
oggVideo, _ := hex.DecodeString("4f676753000200000000000000007d9747ef000000009b59daf3012a807468656f7261030201001e00110001e000010e00020000001e00000001000001000001")
st, err = DetectContentTypeFromReader(bytes.NewReader(oggVideo))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, st.IsVideo())
}
+
+func TestDetectContentTypeAvif(t *testing.T) {
+ avifImage, err := hex.DecodeString("000000206674797061766966")
+ require.NoError(t, err)
+
+ st, err := DetectContentTypeFromReader(bytes.NewReader(avifImage))
+ require.NoError(t, err)
+
+ assert.True(t, st.IsImage())
+}
diff --git a/modules/updatechecker/update_checker.go b/modules/updatechecker/update_checker.go
index 0c93f08d21..b0932ba663 100644
--- a/modules/updatechecker/update_checker.go
+++ b/modules/updatechecker/update_checker.go
@@ -11,10 +11,10 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/proxy"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/system"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/proxy"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/system"
"github.com/hashicorp/go-version"
)
diff --git a/modules/updatechecker/update_checker_test.go b/modules/updatechecker/update_checker_test.go
index 301afd95e4..5ac2603ca1 100644
--- a/modules/updatechecker/update_checker_test.go
+++ b/modules/updatechecker/update_checker_test.go
@@ -7,10 +7,11 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestDNSUpdate(t *testing.T) {
version, err := getVersionDNS("release.forgejo.org")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotEmpty(t, version)
}
diff --git a/modules/uri/uri_test.go b/modules/uri/uri_test.go
index 11b915c261..71a8985cd7 100644
--- a/modules/uri/uri_test.go
+++ b/modules/uri/uri_test.go
@@ -7,13 +7,13 @@ import (
"path/filepath"
"testing"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestReadURI(t *testing.T) {
p, err := filepath.Abs("./uri.go")
- assert.NoError(t, err)
+ require.NoError(t, err)
f, err := Open("file://" + p)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer f.Close()
}
diff --git a/modules/user/user.go b/modules/user/user.go
index eee401a23f..d153413c70 100644
--- a/modules/user/user.go
+++ b/modules/user/user.go
@@ -6,8 +6,6 @@ package user
import (
"os"
"os/user"
- "runtime"
- "strings"
)
// CurrentUsername return current login OS user name
@@ -16,12 +14,7 @@ func CurrentUsername() string {
if err != nil {
return fallbackCurrentUsername()
}
- username := userinfo.Username
- if runtime.GOOS == "windows" {
- parts := strings.Split(username, "\\")
- username = parts[len(parts)-1]
- }
- return username
+ return userinfo.Username
}
// Old method, used if new method doesn't work on your OS for some reason
diff --git a/modules/user/user_test.go b/modules/user/user_test.go
index 9129ae79a1..c7eff85c90 100644
--- a/modules/user/user_test.go
+++ b/modules/user/user_test.go
@@ -4,9 +4,7 @@
package user
import (
- "os"
"os/exec"
- "runtime"
"strings"
"testing"
)
@@ -24,10 +22,6 @@ func TestCurrentUsername(t *testing.T) {
if len(user) == 0 {
t.Errorf("expected non-empty user, got: %s", user)
}
- // Windows whoami is weird, so just skip remaining tests
- if runtime.GOOS == "windows" {
- t.Skip("skipped test because of weird whoami on Windows")
- }
whoami, err := getWhoamiOutput()
if err != nil {
t.Errorf("failed to run whoami to test current user: %f", err)
@@ -36,7 +30,7 @@ func TestCurrentUsername(t *testing.T) {
if user != whoami {
t.Errorf("expected %s as user, got: %s", whoami, user)
}
- os.Setenv("USER", "spoofed")
+ t.Setenv("USER", "spoofed")
user = CurrentUsername()
if user != whoami {
t.Errorf("expected %s as user, got: %s", whoami, user)
diff --git a/modules/util/color_test.go b/modules/util/color_test.go
index be6e6b122a..abd5551218 100644
--- a/modules/util/color_test.go
+++ b/modules/util/color_test.go
@@ -27,9 +27,9 @@ func Test_HexToRBGColor(t *testing.T) {
}
for n, c := range cases {
r, g, b := HexToRBGColor(c.colorString)
- assert.Equal(t, c.expectedR, r, "case %d: error R should match: expected %f, but get %f", n, c.expectedR, r)
- assert.Equal(t, c.expectedG, g, "case %d: error G should match: expected %f, but get %f", n, c.expectedG, g)
- assert.Equal(t, c.expectedB, b, "case %d: error B should match: expected %f, but get %f", n, c.expectedB, b)
+ assert.InDelta(t, c.expectedR, r, 0, "case %d: error R should match: expected %f, but get %f", n, c.expectedR, r)
+ assert.InDelta(t, c.expectedG, g, 0, "case %d: error G should match: expected %f, but get %f", n, c.expectedG, g)
+ assert.InDelta(t, c.expectedB, b, 0, "case %d: error B should match: expected %f, but get %f", n, c.expectedB, b)
}
}
diff --git a/modules/util/file_unix.go b/modules/util/file_unix.go
index 79a29c8b3b..b722eee97d 100644
--- a/modules/util/file_unix.go
+++ b/modules/util/file_unix.go
@@ -1,8 +1,6 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !windows
-
package util
import (
diff --git a/modules/util/file_unix_test.go b/modules/util/file_unix_test.go
index 87d6c2f09a..228c64f980 100644
--- a/modules/util/file_unix_test.go
+++ b/modules/util/file_unix_test.go
@@ -1,8 +1,6 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !windows
-
package util
import (
@@ -10,16 +8,17 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestApplyUmask(t *testing.T) {
f, err := os.CreateTemp(t.TempDir(), "test-filemode-")
- assert.NoError(t, err)
+ require.NoError(t, err)
err = os.Chmod(f.Name(), 0o777)
- assert.NoError(t, err)
+ require.NoError(t, err)
st, err := os.Stat(f.Name())
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0o777, st.Mode().Perm()&0o777)
oldDefaultUmask := defaultUmask
@@ -28,8 +27,8 @@ func TestApplyUmask(t *testing.T) {
defaultUmask = oldDefaultUmask
}()
err = ApplyUmask(f.Name(), os.ModePerm)
- assert.NoError(t, err)
+ require.NoError(t, err)
st, err = os.Stat(f.Name())
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, 0o740, st.Mode().Perm()&0o777)
}
diff --git a/modules/util/file_windows.go b/modules/util/file_windows.go
deleted file mode 100644
index 77a33d3c49..0000000000
--- a/modules/util/file_windows.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build windows
-
-package util
-
-import (
- "os"
-)
-
-func ApplyUmask(f string, newMode os.FileMode) error {
- // do nothing for Windows, because Windows doesn't use umask
- return nil
-}
diff --git a/modules/util/filebuffer/file_backed_buffer_test.go b/modules/util/filebuffer/file_backed_buffer_test.go
index 16d5a1965f..c56c1c64e9 100644
--- a/modules/util/filebuffer/file_backed_buffer_test.go
+++ b/modules/util/filebuffer/file_backed_buffer_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestFileBackedBuffer(t *testing.T) {
@@ -22,14 +23,14 @@ func TestFileBackedBuffer(t *testing.T) {
for _, c := range cases {
buf, err := CreateFromReader(strings.NewReader(c.Data), c.MaxMemorySize)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, len(c.Data), buf.Size())
data, err := io.ReadAll(buf)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, c.Data, string(data))
- assert.NoError(t, buf.Close())
+ require.NoError(t, buf.Close())
}
}
diff --git a/modules/util/io_test.go b/modules/util/io_test.go
index 275575463a..870e713646 100644
--- a/modules/util/io_test.go
+++ b/modules/util/io_test.go
@@ -9,6 +9,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
type readerWithError struct {
@@ -27,40 +28,40 @@ func TestReadWithLimit(t *testing.T) {
// normal test
buf, err := readWithLimit(bytes.NewBuffer(bs), 5, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("01"), buf)
buf, err = readWithLimit(bytes.NewBuffer(bs), 5, 5)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("01234"), buf)
buf, err = readWithLimit(bytes.NewBuffer(bs), 5, 6)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("012345"), buf)
buf, err = readWithLimit(bytes.NewBuffer(bs), 5, len(bs))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("0123456789abcdef"), buf)
buf, err = readWithLimit(bytes.NewBuffer(bs), 5, 100)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("0123456789abcdef"), buf)
// test with error
buf, err = readWithLimit(&readerWithError{bytes.NewBuffer(bs)}, 5, 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("0123456789"), buf)
buf, err = readWithLimit(&readerWithError{bytes.NewBuffer(bs)}, 5, 100)
- assert.ErrorContains(t, err, "test error")
+ require.ErrorContains(t, err, "test error")
assert.Empty(t, buf)
// test public function
buf, err = ReadWithLimit(bytes.NewBuffer(bs), 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("01"), buf)
buf, err = ReadWithLimit(bytes.NewBuffer(bs), 9999999)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, []byte("0123456789abcdef"), buf)
}
diff --git a/modules/util/keypair_test.go b/modules/util/keypair_test.go
index c6f68c845a..6c05db779a 100644
--- a/modules/util/keypair_test.go
+++ b/modules/util/keypair_test.go
@@ -10,26 +10,26 @@ import (
"crypto/sha256"
"crypto/x509"
"encoding/pem"
- "regexp"
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestKeygen(t *testing.T) {
priv, pub, err := GenerateKeyPair(2048)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotEmpty(t, priv)
assert.NotEmpty(t, pub)
- assert.Regexp(t, regexp.MustCompile("^-----BEGIN RSA PRIVATE KEY-----.*"), priv)
- assert.Regexp(t, regexp.MustCompile("^-----BEGIN PUBLIC KEY-----.*"), pub)
+ assert.Regexp(t, "^-----BEGIN RSA PRIVATE KEY-----.*", priv)
+ assert.Regexp(t, "^-----BEGIN PUBLIC KEY-----.*", pub)
}
func TestSignUsingKeys(t *testing.T) {
priv, pub, err := GenerateKeyPair(2048)
- assert.NoError(t, err)
+ require.NoError(t, err)
privPem, _ := pem.Decode([]byte(priv))
if privPem == nil || privPem.Type != "RSA PRIVATE KEY" {
@@ -37,7 +37,7 @@ func TestSignUsingKeys(t *testing.T) {
}
privParsed, err := x509.ParsePKCS1PrivateKey(privPem.Bytes)
- assert.NoError(t, err)
+ require.NoError(t, err)
pubPem, _ := pem.Decode([]byte(pub))
if pubPem == nil || pubPem.Type != "PUBLIC KEY" {
@@ -45,7 +45,7 @@ func TestSignUsingKeys(t *testing.T) {
}
pubParsed, err := x509.ParsePKIXPublicKey(pubPem.Bytes)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Sign
msg := "activity pub is great!"
@@ -53,9 +53,9 @@ func TestSignUsingKeys(t *testing.T) {
h.Write([]byte(msg))
d := h.Sum(nil)
sig, err := rsa.SignPKCS1v15(rand.Reader, privParsed, crypto.SHA256, d)
- assert.NoError(t, err)
+ require.NoError(t, err)
// Verify
err = rsa.VerifyPKCS1v15(pubParsed.(*rsa.PublicKey), crypto.SHA256, d, sig)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
diff --git a/modules/util/legacy_test.go b/modules/util/legacy_test.go
index b7991bd365..62c2f8af16 100644
--- a/modules/util/legacy_test.go
+++ b/modules/util/legacy_test.go
@@ -10,6 +10,7 @@ import (
"time"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCopyFile(t *testing.T) {
@@ -28,10 +29,10 @@ func TestCopyFile(t *testing.T) {
}()
err := os.WriteFile(srcFile, testContent, 0o777)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = CopyFile(srcFile, dstFile)
- assert.NoError(t, err)
+ require.NoError(t, err)
dstContent, err := os.ReadFile(dstFile)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, testContent, dstContent)
}
diff --git a/modules/util/pack_test.go b/modules/util/pack_test.go
index 592c69cd0a..42ada89b81 100644
--- a/modules/util/pack_test.go
+++ b/modules/util/pack_test.go
@@ -6,7 +6,7 @@ package util
import (
"testing"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestPackAndUnpackData(t *testing.T) {
@@ -19,10 +19,10 @@ func TestPackAndUnpackData(t *testing.T) {
var f2 float32
data, err := PackData(s, i, f)
- assert.NoError(t, err)
+ require.NoError(t, err)
- assert.NoError(t, UnpackData(data, &s2, &i2, &f2))
- assert.NoError(t, UnpackData(data, &s2))
- assert.Error(t, UnpackData(data, &i2))
- assert.Error(t, UnpackData(data, &s2, &f2))
+ require.NoError(t, UnpackData(data, &s2, &i2, &f2))
+ require.NoError(t, UnpackData(data, &s2))
+ require.Error(t, UnpackData(data, &i2))
+ require.Error(t, UnpackData(data, &s2, &f2))
}
diff --git a/modules/util/path.go b/modules/util/path.go
index 185e7cf882..9039f27cbf 100644
--- a/modules/util/path.go
+++ b/modules/util/path.go
@@ -10,8 +10,6 @@ import (
"os"
"path"
"path/filepath"
- "regexp"
- "runtime"
"strings"
)
@@ -78,11 +76,7 @@ func FilePathJoinAbs(base string, sub ...string) string {
// POSIX filesystem can have `\` in file names. Windows: `\` and `/` are both used for path separators
// to keep the behavior consistent, we do not allow `\` in file names, replace all `\` with `/`
- if isOSWindows() {
- elems[0] = filepath.Clean(base)
- } else {
- elems[0] = filepath.Clean(strings.ReplaceAll(base, "\\", pathSeparator))
- }
+ elems[0] = filepath.Clean(strings.ReplaceAll(base, "\\", pathSeparator))
if !filepath.IsAbs(elems[0]) {
// This shouldn't happen. If there is really necessary to pass in relative path, return the full path with filepath.Abs() instead
panic(fmt.Sprintf("FilePathJoinAbs: %q (for path %v) is not absolute, do not guess a relative path based on current working directory", elems[0], elems))
@@ -91,11 +85,7 @@ func FilePathJoinAbs(base string, sub ...string) string {
if s == "" {
continue
}
- if isOSWindows() {
- elems = append(elems, filepath.Clean(pathSeparator+s))
- } else {
- elems = append(elems, filepath.Clean(pathSeparator+strings.ReplaceAll(s, "\\", pathSeparator)))
- }
+ elems = append(elems, filepath.Clean(pathSeparator+strings.ReplaceAll(s, "\\", pathSeparator)))
}
// the elems[0] must be an absolute path, just join them together
return filepath.Join(elems...)
@@ -217,12 +207,6 @@ func StatDir(rootPath string, includeDir ...bool) ([]string, error) {
return statDir(rootPath, "", isIncludeDir, false, false)
}
-func isOSWindows() bool {
- return runtime.GOOS == "windows"
-}
-
-var driveLetterRegexp = regexp.MustCompile("/[A-Za-z]:/")
-
// FileURLToPath extracts the path information from a file://... url.
// It returns an error only if the URL is not a file URL.
func FileURLToPath(u *url.URL) (string, error) {
@@ -230,17 +214,7 @@ func FileURLToPath(u *url.URL) (string, error) {
return "", errors.New("URL scheme is not 'file': " + u.String())
}
- path := u.Path
-
- if !isOSWindows() {
- return path, nil
- }
-
- // If it looks like there's a Windows drive letter at the beginning, strip off the leading slash.
- if driveLetterRegexp.MatchString(path) {
- return path[1:], nil
- }
- return path, nil
+ return u.Path, nil
}
// HomeDir returns path of '~'(in Linux) on Windows,
@@ -249,14 +223,7 @@ func HomeDir() (home string, err error) {
// TODO: some users run Gitea with mismatched uid and "HOME=xxx" (they set HOME=xxx by environment manually)
// TODO: when running gitea as a sub command inside git, the HOME directory is not the user's home directory
// so at the moment we can not use `user.Current().HomeDir`
- if isOSWindows() {
- home = os.Getenv("USERPROFILE")
- if home == "" {
- home = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
- }
- } else {
- home = os.Getenv("HOME")
- }
+ home = os.Getenv("HOME")
if home == "" {
return "", errors.New("cannot get home directory")
diff --git a/modules/util/path_test.go b/modules/util/path_test.go
index 6a38bf4ace..b912b76f6e 100644
--- a/modules/util/path_test.go
+++ b/modules/util/path_test.go
@@ -5,10 +5,10 @@ package util
import (
"net/url"
- "runtime"
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestFileURLToPath(t *testing.T) {
@@ -16,7 +16,6 @@ func TestFileURLToPath(t *testing.T) {
url string
expected string
haserror bool
- windows bool
}{
// case 0
{
@@ -33,24 +32,15 @@ func TestFileURLToPath(t *testing.T) {
url: "file:///path",
expected: "/path",
},
- // case 3
- {
- url: "file:///C:/path",
- expected: "C:/path",
- windows: true,
- },
}
for n, c := range cases {
- if c.windows && runtime.GOOS != "windows" {
- continue
- }
u, _ := url.Parse(c.url)
p, err := FileURLToPath(u)
if c.haserror {
- assert.Error(t, err, "case %d: should return error", n)
+ require.Error(t, err, "case %d: should return error", n)
} else {
- assert.NoError(t, err, "case %d: should not return error", n)
+ require.NoError(t, err, "case %d: should not return error", n)
assert.Equal(t, c.expected, p, "case %d: should be equal", n)
}
}
@@ -176,35 +166,18 @@ func TestCleanPath(t *testing.T) {
assert.Equal(t, c.expected, PathJoinRelX(c.elems...), "case: %v", c.elems)
}
- // for POSIX only, but the result is similar on Windows, because the first element must be an absolute path
- if isOSWindows() {
- cases = []struct {
- elems []string
- expected string
- }{
- {[]string{`C:\..`}, `C:\`},
- {[]string{`C:\a`}, `C:\a`},
- {[]string{`C:\a/`}, `C:\a`},
- {[]string{`C:\..\a\`, `../b`, `c\..`, `d`}, `C:\a\b\d`},
- {[]string{`C:\a/..\b`}, `C:\b`},
- {[]string{`C:\a`, ``, `b`}, `C:\a\b`},
- {[]string{`C:\a`, `..`, `b`}, `C:\a\b`},
- {[]string{`C:\lfs`, `repo/..`, `user/../path`}, `C:\lfs\path`},
- }
- } else {
- cases = []struct {
- elems []string
- expected string
- }{
- {[]string{`/..`}, `/`},
- {[]string{`/a`}, `/a`},
- {[]string{`/a/`}, `/a`},
- {[]string{`/../a/`, `../b`, `c/..`, `d`}, `/a/b/d`},
- {[]string{`/a\..\b`}, `/b`},
- {[]string{`/a`, ``, `b`}, `/a/b`},
- {[]string{`/a`, `..`, `b`}, `/a/b`},
- {[]string{`/lfs`, `repo/..`, `user/../path`}, `/lfs/path`},
- }
+ cases = []struct {
+ elems []string
+ expected string
+ }{
+ {[]string{`/..`}, `/`},
+ {[]string{`/a`}, `/a`},
+ {[]string{`/a/`}, `/a`},
+ {[]string{`/../a/`, `../b`, `c/..`, `d`}, `/a/b/d`},
+ {[]string{`/a\..\b`}, `/b`},
+ {[]string{`/a`, ``, `b`}, `/a/b`},
+ {[]string{`/a`, `..`, `b`}, `/a/b`},
+ {[]string{`/lfs`, `repo/..`, `user/../path`}, `/lfs/path`},
}
for _, c := range cases {
assert.Equal(t, c.expected, FilePathJoinAbs(c.elems[0], c.elems[1:]...), "case: %v", c.elems)
diff --git a/modules/util/remove.go b/modules/util/remove.go
index d1e38faf5f..b07a48bee4 100644
--- a/modules/util/remove.go
+++ b/modules/util/remove.go
@@ -4,14 +4,13 @@
package util
import (
+ "io/fs"
"os"
- "runtime"
+ "path/filepath"
"syscall"
"time"
)
-const windowsSharingViolationError syscall.Errno = 32
-
// Remove removes the named file or (empty) directory with at most 5 attempts.
func Remove(name string) error {
var err error
@@ -27,12 +26,6 @@ func Remove(name string) error {
continue
}
- if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
- // try again
- <-time.After(100 * time.Millisecond)
- continue
- }
-
if unwrapped == syscall.ENOENT {
// it's already gone
return nil
@@ -41,10 +34,48 @@ func Remove(name string) error {
return err
}
-// RemoveAll removes the named file or (empty) directory with at most 5 attempts.
+// MakeWritable recursively makes the named directory writable.
+func MakeWritable(name string) error {
+ return filepath.WalkDir(name, func(path string, d fs.DirEntry, err error) error {
+ // NB: this is called WalkDir but it works on a single file too
+ if err == nil {
+ info, err := d.Info()
+ if err != nil {
+ return err
+ }
+
+ // Don't try chmod'ing symlinks (will fail with broken symlinks)
+ if info.Mode()&os.ModeSymlink != os.ModeSymlink {
+ // 0200 == u+w, in octal unix permission notation
+ err = os.Chmod(path, info.Mode()|0o200)
+ if err != nil {
+ return err
+ }
+ }
+ }
+ return nil
+ })
+}
+
+// RemoveAll removes the named file or directory with at most 5 attempts.
func RemoveAll(name string) error {
var err error
+
for i := 0; i < 5; i++ {
+ // Do chmod -R +w to help ensure the removal succeeds.
+ // In particular, in the git-annex case, this handles
+ // https://git-annex.branchable.com/internals/lockdown/ :
+ //
+ // > (The only bad consequence of this is that rm -rf .git
+ // > doesn't work unless you first run chmod -R +w .git)
+
+ err = MakeWritable(name)
+ if err != nil {
+ // try again
+ <-time.After(100 * time.Millisecond)
+ continue
+ }
+
err = os.RemoveAll(name)
if err == nil {
break
@@ -56,12 +87,6 @@ func RemoveAll(name string) error {
continue
}
- if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
- // try again
- <-time.After(100 * time.Millisecond)
- continue
- }
-
if unwrapped == syscall.ENOENT {
// it's already gone
return nil
@@ -85,12 +110,6 @@ func Rename(oldpath, newpath string) error {
continue
}
- if unwrapped == windowsSharingViolationError && runtime.GOOS == "windows" {
- // try again
- <-time.After(100 * time.Millisecond)
- continue
- }
-
if i == 0 && os.IsNotExist(err) {
return err
}
diff --git a/modules/util/rotatingfilewriter/writer.go b/modules/util/rotatingfilewriter/writer.go
index c595f49c49..ff234eea93 100644
--- a/modules/util/rotatingfilewriter/writer.go
+++ b/modules/util/rotatingfilewriter/writer.go
@@ -14,8 +14,8 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/modules/graceful/releasereopen"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/graceful/releasereopen"
+ "forgejo.org/modules/util"
)
type Options struct {
diff --git a/modules/util/rotatingfilewriter/writer_test.go b/modules/util/rotatingfilewriter/writer_test.go
index 88392797b3..5b3b351667 100644
--- a/modules/util/rotatingfilewriter/writer_test.go
+++ b/modules/util/rotatingfilewriter/writer_test.go
@@ -11,6 +11,7 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCompressOldFile(t *testing.T) {
@@ -19,9 +20,9 @@ func TestCompressOldFile(t *testing.T) {
nonGzip := filepath.Join(tmpDir, "test-nonGzip")
f, err := os.OpenFile(fname, os.O_CREATE|os.O_WRONLY, 0o660)
- assert.NoError(t, err)
+ require.NoError(t, err)
ng, err := os.OpenFile(nonGzip, os.O_CREATE|os.O_WRONLY, 0o660)
- assert.NoError(t, err)
+ require.NoError(t, err)
for i := 0; i < 999; i++ {
f.WriteString("This is a test file\n")
@@ -31,18 +32,18 @@ func TestCompressOldFile(t *testing.T) {
ng.Close()
err = compressOldFile(fname, gzip.DefaultCompression)
- assert.NoError(t, err)
+ require.NoError(t, err)
_, err = os.Lstat(fname + ".gz")
- assert.NoError(t, err)
+ require.NoError(t, err)
f, err = os.Open(fname + ".gz")
- assert.NoError(t, err)
+ require.NoError(t, err)
zr, err := gzip.NewReader(f)
- assert.NoError(t, err)
+ require.NoError(t, err)
data, err := io.ReadAll(zr)
- assert.NoError(t, err)
+ require.NoError(t, err)
original, err := os.ReadFile(nonGzip)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, original, data)
}
diff --git a/modules/util/slice.go b/modules/util/slice.go
index 9c878c24be..80c8e62f6f 100644
--- a/modules/util/slice.go
+++ b/modules/util/slice.go
@@ -4,7 +4,6 @@
package util
import (
- "cmp"
"slices"
"strings"
)
@@ -47,13 +46,6 @@ func SliceRemoveAll[T comparable](slice []T, target T) []T {
return slices.DeleteFunc(slice, func(t T) bool { return t == target })
}
-// Sorted returns the sorted slice
-// Note: The parameter is sorted inline.
-func Sorted[S ~[]E, E cmp.Ordered](values S) S {
- slices.Sort(values)
- return values
-}
-
// TODO: Replace with "maps.Values" once available, current it only in golang.org/x/exp/maps but not in standard library
func ValuesOfMap[K comparable, V any](m map[K]V) []V {
values := make([]V, 0, len(m))
diff --git a/modules/util/truncate.go b/modules/util/truncate.go
index 77b116eeff..f2edbdc673 100644
--- a/modules/util/truncate.go
+++ b/modules/util/truncate.go
@@ -41,6 +41,8 @@ func SplitStringAtByteN(input string, n int) (left, right string) {
// SplitTrimSpace splits the string at given separator and trims leading and trailing space
func SplitTrimSpace(input, sep string) []string {
+ // Trim initial leading & trailing space
+ input = strings.TrimSpace(input)
// replace CRLF with LF
input = strings.ReplaceAll(input, "\r\n", "\n")
diff --git a/modules/util/util.go b/modules/util/util.go
index b6ea283551..da405c9c4b 100644
--- a/modules/util/util.go
+++ b/modules/util/util.go
@@ -1,18 +1,22 @@
// Copyright 2017 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package util
import (
"bytes"
+ "crypto/ed25519"
"crypto/rand"
+ "encoding/pem"
"fmt"
"math/big"
"strconv"
"strings"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/modules/optional"
+ "golang.org/x/crypto/ssh"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
@@ -221,6 +225,34 @@ func Iif[T any](condition bool, trueVal, falseVal T) T {
return falseVal
}
+// IfZero returns "def" if "v" is a zero value, otherwise "v"
+func IfZero[T comparable](v, def T) T {
+ var zero T
+ if v == zero {
+ return def
+ }
+ return v
+}
+
+// OptionalArg helps the "optional argument" in Golang:
+//
+// func foo(optArg ...int) { return OptionalArg(optArg) }
+// calling `foo()` gets zero value 0, calling `foo(100)` gets 100
+// func bar(optArg ...int) { return OptionalArg(optArg, 42) }
+// calling `bar()` gets default value 42, calling `bar(100)` gets 100
+//
+// Passing more than 1 item to `optArg` or `defaultValue` is undefined behavior.
+// At the moment only the first item is used.
+func OptionalArg[T any](optArg []T, defaultValue ...T) (ret T) {
+ if len(optArg) >= 1 {
+ return optArg[0]
+ }
+ if len(defaultValue) >= 1 {
+ return defaultValue[0]
+ }
+ return ret
+}
+
func ReserveLineBreakForTextarea(input string) string {
// Since the content is from a form which is a textarea, the line endings are \r\n.
// It's a standard behavior of HTML.
@@ -229,3 +261,23 @@ func ReserveLineBreakForTextarea(input string) string {
// Other than this, we should respect the original content, even leading or trailing spaces.
return strings.ReplaceAll(input, "\r\n", "\n")
}
+
+// GenerateSSHKeypair generates a ed25519 SSH-compatible keypair.
+func GenerateSSHKeypair() (publicKey, privateKey []byte, err error) {
+ public, private, err := ed25519.GenerateKey(nil)
+ if err != nil {
+ return nil, nil, fmt.Errorf("ed25519.GenerateKey: %w", err)
+ }
+
+ privPEM, err := ssh.MarshalPrivateKey(private, "")
+ if err != nil {
+ return nil, nil, fmt.Errorf("ssh.MarshalPrivateKey: %w", err)
+ }
+
+ sshPublicKey, err := ssh.NewPublicKey(public)
+ if err != nil {
+ return nil, nil, fmt.Errorf("ssh.NewPublicKey: %w", err)
+ }
+
+ return ssh.MarshalAuthorizedKey(sshPublicKey), pem.EncodeToMemory(privPEM), nil
+}
diff --git a/modules/util/util_test.go b/modules/util/util_test.go
index de8f065cad..5e0c4a9a0b 100644
--- a/modules/util/util_test.go
+++ b/modules/util/util_test.go
@@ -1,16 +1,22 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-package util
+package util_test
import (
+ "bytes"
+ "crypto/rand"
"regexp"
"strings"
"testing"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/test"
+ "forgejo.org/modules/util"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestURLJoin(t *testing.T) {
@@ -42,7 +48,7 @@ func TestURLJoin(t *testing.T) {
newTest("/a/b/c#hash",
"/a", "b/c#hash"),
} {
- assert.Equal(t, test.Expected, URLJoin(test.Base, test.Elements...))
+ assert.Equal(t, test.Expected, util.URLJoin(test.Base, test.Elements...))
}
}
@@ -58,7 +64,7 @@ func TestIsEmptyString(t *testing.T) {
}
for _, v := range cases {
- assert.Equal(t, v.expected, IsEmptyString(v.s))
+ assert.Equal(t, v.expected, util.IsEmptyString(v.s))
}
}
@@ -99,93 +105,93 @@ func Test_NormalizeEOL(t *testing.T) {
unix := buildEOLData(data1, "\n")
mac := buildEOLData(data1, "\r")
- assert.Equal(t, unix, NormalizeEOL(dos))
- assert.Equal(t, unix, NormalizeEOL(mac))
- assert.Equal(t, unix, NormalizeEOL(unix))
+ assert.Equal(t, unix, util.NormalizeEOL(dos))
+ assert.Equal(t, unix, util.NormalizeEOL(mac))
+ assert.Equal(t, unix, util.NormalizeEOL(unix))
dos = buildEOLData(data2, "\r\n")
unix = buildEOLData(data2, "\n")
mac = buildEOLData(data2, "\r")
- assert.Equal(t, unix, NormalizeEOL(dos))
- assert.Equal(t, unix, NormalizeEOL(mac))
- assert.Equal(t, unix, NormalizeEOL(unix))
+ assert.Equal(t, unix, util.NormalizeEOL(dos))
+ assert.Equal(t, unix, util.NormalizeEOL(mac))
+ assert.Equal(t, unix, util.NormalizeEOL(unix))
- assert.Equal(t, []byte("one liner"), NormalizeEOL([]byte("one liner")))
- assert.Equal(t, []byte("\n"), NormalizeEOL([]byte("\n")))
- assert.Equal(t, []byte("\ntwo liner"), NormalizeEOL([]byte("\ntwo liner")))
- assert.Equal(t, []byte("two liner\n"), NormalizeEOL([]byte("two liner\n")))
- assert.Equal(t, []byte{}, NormalizeEOL([]byte{}))
+ assert.Equal(t, []byte("one liner"), util.NormalizeEOL([]byte("one liner")))
+ assert.Equal(t, []byte("\n"), util.NormalizeEOL([]byte("\n")))
+ assert.Equal(t, []byte("\ntwo liner"), util.NormalizeEOL([]byte("\ntwo liner")))
+ assert.Equal(t, []byte("two liner\n"), util.NormalizeEOL([]byte("two liner\n")))
+ assert.Equal(t, []byte{}, util.NormalizeEOL([]byte{}))
- assert.Equal(t, []byte("mix\nand\nmatch\n."), NormalizeEOL([]byte("mix\r\nand\rmatch\n.")))
+ assert.Equal(t, []byte("mix\nand\nmatch\n."), util.NormalizeEOL([]byte("mix\r\nand\rmatch\n.")))
}
func Test_RandomInt(t *testing.T) {
- randInt, err := CryptoRandomInt(255)
- assert.True(t, randInt >= 0)
- assert.True(t, randInt <= 255)
- assert.NoError(t, err)
+ randInt, err := util.CryptoRandomInt(255)
+ assert.GreaterOrEqual(t, randInt, int64(0))
+ assert.LessOrEqual(t, randInt, int64(255))
+ require.NoError(t, err)
}
func Test_RandomString(t *testing.T) {
- str1, err := CryptoRandomString(32)
- assert.NoError(t, err)
+ str1, err := util.CryptoRandomString(32)
+ require.NoError(t, err)
matches, err := regexp.MatchString(`^[a-zA-Z0-9]{32}$`, str1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, matches)
- str2, err := CryptoRandomString(32)
- assert.NoError(t, err)
+ str2, err := util.CryptoRandomString(32)
+ require.NoError(t, err)
matches, err = regexp.MatchString(`^[a-zA-Z0-9]{32}$`, str1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, matches)
assert.NotEqual(t, str1, str2)
- str3, err := CryptoRandomString(256)
- assert.NoError(t, err)
+ str3, err := util.CryptoRandomString(256)
+ require.NoError(t, err)
matches, err = regexp.MatchString(`^[a-zA-Z0-9]{256}$`, str3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, matches)
- str4, err := CryptoRandomString(256)
- assert.NoError(t, err)
+ str4, err := util.CryptoRandomString(256)
+ require.NoError(t, err)
matches, err = regexp.MatchString(`^[a-zA-Z0-9]{256}$`, str4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, matches)
assert.NotEqual(t, str3, str4)
}
func Test_RandomBytes(t *testing.T) {
- bytes1, err := CryptoRandomBytes(32)
- assert.NoError(t, err)
+ bytes1, err := util.CryptoRandomBytes(32)
+ require.NoError(t, err)
- bytes2, err := CryptoRandomBytes(32)
- assert.NoError(t, err)
+ bytes2, err := util.CryptoRandomBytes(32)
+ require.NoError(t, err)
assert.NotEqual(t, bytes1, bytes2)
- bytes3, err := CryptoRandomBytes(256)
- assert.NoError(t, err)
+ bytes3, err := util.CryptoRandomBytes(256)
+ require.NoError(t, err)
- bytes4, err := CryptoRandomBytes(256)
- assert.NoError(t, err)
+ bytes4, err := util.CryptoRandomBytes(256)
+ require.NoError(t, err)
assert.NotEqual(t, bytes3, bytes4)
}
func TestOptionalBoolParse(t *testing.T) {
- assert.Equal(t, optional.None[bool](), OptionalBoolParse(""))
- assert.Equal(t, optional.None[bool](), OptionalBoolParse("x"))
+ assert.Equal(t, optional.None[bool](), util.OptionalBoolParse(""))
+ assert.Equal(t, optional.None[bool](), util.OptionalBoolParse("x"))
- assert.Equal(t, optional.Some(false), OptionalBoolParse("0"))
- assert.Equal(t, optional.Some(false), OptionalBoolParse("f"))
- assert.Equal(t, optional.Some(false), OptionalBoolParse("False"))
+ assert.Equal(t, optional.Some(false), util.OptionalBoolParse("0"))
+ assert.Equal(t, optional.Some(false), util.OptionalBoolParse("f"))
+ assert.Equal(t, optional.Some(false), util.OptionalBoolParse("False"))
- assert.Equal(t, optional.Some(true), OptionalBoolParse("1"))
- assert.Equal(t, optional.Some(true), OptionalBoolParse("t"))
- assert.Equal(t, optional.Some(true), OptionalBoolParse("True"))
+ assert.Equal(t, optional.Some(true), util.OptionalBoolParse("1"))
+ assert.Equal(t, optional.Some(true), util.OptionalBoolParse("t"))
+ assert.Equal(t, optional.Some(true), util.OptionalBoolParse("True"))
}
// Test case for any function which accepts and returns a single string.
@@ -208,7 +214,7 @@ var upperTests = []StringTest{
func TestToUpperASCII(t *testing.T) {
for _, tc := range upperTests {
- assert.Equal(t, ToUpperASCII(tc.in), tc.out)
+ assert.Equal(t, util.ToUpperASCII(tc.in), tc.out)
}
}
@@ -216,27 +222,69 @@ func BenchmarkToUpper(b *testing.B) {
for _, tc := range upperTests {
b.Run(tc.in, func(b *testing.B) {
for i := 0; i < b.N; i++ {
- ToUpperASCII(tc.in)
+ util.ToUpperASCII(tc.in)
}
})
}
}
func TestToTitleCase(t *testing.T) {
- assert.Equal(t, ToTitleCase(`foo bar baz`), `Foo Bar Baz`)
- assert.Equal(t, ToTitleCase(`FOO BAR BAZ`), `Foo Bar Baz`)
+ assert.Equal(t, `Foo Bar Baz`, util.ToTitleCase(`foo bar baz`))
+ assert.Equal(t, `Foo Bar Baz`, util.ToTitleCase(`FOO BAR BAZ`))
}
func TestToPointer(t *testing.T) {
- assert.Equal(t, "abc", *ToPointer("abc"))
- assert.Equal(t, 123, *ToPointer(123))
+ assert.Equal(t, "abc", *util.ToPointer("abc"))
+ assert.Equal(t, 123, *util.ToPointer(123))
abc := "abc"
- assert.False(t, &abc == ToPointer(abc))
+ assert.NotSame(t, &abc, util.ToPointer(abc))
val123 := 123
- assert.False(t, &val123 == ToPointer(val123))
+ assert.NotSame(t, &val123, util.ToPointer(val123))
}
func TestReserveLineBreakForTextarea(t *testing.T) {
- assert.Equal(t, ReserveLineBreakForTextarea("test\r\ndata"), "test\ndata")
- assert.Equal(t, ReserveLineBreakForTextarea("test\r\ndata\r\n"), "test\ndata\n")
+ assert.Equal(t, "test\ndata", util.ReserveLineBreakForTextarea("test\r\ndata"))
+ assert.Equal(t, "test\ndata\n", util.ReserveLineBreakForTextarea("test\r\ndata\r\n"))
+}
+
+const (
+ testPublicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAOhB7/zzhC+HXDdGOdLwJln5NYwm6UNXx3chmQSVTG4\n"
+ testPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtz
+c2gtZWQyNTUxOQAAACADoQe/884Qvh1w3RjnS8CZZ+TWMJulDV8d3IZkElUxuAAA
+AIggISIjICEiIwAAAAtzc2gtZWQyNTUxOQAAACADoQe/884Qvh1w3RjnS8CZZ+TW
+MJulDV8d3IZkElUxuAAAAEAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0e
+HwOhB7/zzhC+HXDdGOdLwJln5NYwm6UNXx3chmQSVTG4AAAAAAECAwQF
+-----END OPENSSH PRIVATE KEY-----` + "\n"
+)
+
+func TestGeneratingEd25519Keypair(t *testing.T) {
+ defer test.MockProtect(&rand.Reader)()
+
+ // Only 32 bytes needs to be provided to generate a ed25519 keypair.
+ // And another 32 bytes are required, which is included as random value
+ // in the OpenSSH format.
+ b := make([]byte, 64)
+ for i := 0; i < 64; i++ {
+ b[i] = byte(i)
+ }
+ rand.Reader = bytes.NewReader(b)
+
+ publicKey, privateKey, err := util.GenerateSSHKeypair()
+ require.NoError(t, err)
+ assert.EqualValues(t, testPublicKey, string(publicKey))
+ assert.EqualValues(t, testPrivateKey, string(privateKey))
+}
+
+func TestOptionalArg(t *testing.T) {
+ foo := func(other any, optArg ...int) int {
+ return util.OptionalArg(optArg)
+ }
+ bar := func(other any, optArg ...int) int {
+ return util.OptionalArg(optArg, 42)
+ }
+ assert.Equal(t, 0, foo(nil))
+ assert.Equal(t, 100, foo(nil, 100))
+ assert.Equal(t, 42, bar(nil))
+ assert.Equal(t, 100, bar(nil, 100))
}
diff --git a/modules/validation/binding.go b/modules/validation/binding.go
index cb0a5063e5..f4f82278bd 100644
--- a/modules/validation/binding.go
+++ b/modules/validation/binding.go
@@ -8,10 +8,11 @@ import (
"regexp"
"strings"
- "code.gitea.io/gitea/modules/auth"
- "code.gitea.io/gitea/modules/git"
+ "forgejo.org/modules/auth"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/util"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
"github.com/gobwas/glob"
)
@@ -26,11 +27,14 @@ const (
ErrUsername = "UsernameError"
// ErrInvalidGroupTeamMap is returned when a group team mapping is invalid
ErrInvalidGroupTeamMap = "InvalidGroupTeamMap"
+ // ErrEmail is returned when an email address is invalid
+ ErrEmail = "Email"
)
// AddBindingRules adds additional binding rules
func AddBindingRules() {
addGitRefNameBindingRule()
+ addValidURLListBindingRule()
addValidURLBindingRule()
addValidSiteURLBindingRule()
addGlobPatternRule()
@@ -38,13 +42,14 @@ func AddBindingRules() {
addGlobOrRegexPatternRule()
addUsernamePatternRule()
addValidGroupTeamMapRule()
+ addEmailBindingRules()
}
func addGitRefNameBindingRule() {
// Git refname validation rule
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
- return strings.HasPrefix(rule, "GitRefName")
+ return rule == "GitRefName"
},
IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
str := fmt.Sprintf("%v", val)
@@ -58,11 +63,38 @@ func addGitRefNameBindingRule() {
})
}
+func addValidURLListBindingRule() {
+ // URL validation rule
+ binding.AddRule(&binding.Rule{
+ IsMatch: func(rule string) bool {
+ return rule == "ValidUrlList"
+ },
+ IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
+ str := fmt.Sprintf("%v", val)
+ if len(str) == 0 {
+ errs.Add([]string{name}, binding.ERR_URL, "Url")
+ return false, errs
+ }
+
+ ok := true
+ urls := util.SplitTrimSpace(str, "\n")
+ for _, u := range urls {
+ if !IsValidURL(u) {
+ ok = false
+ errs.Add([]string{name}, binding.ERR_URL, u)
+ }
+ }
+
+ return ok, errs
+ },
+ })
+}
+
func addValidURLBindingRule() {
// URL validation rule
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
- return strings.HasPrefix(rule, "ValidUrl")
+ return rule == "ValidUrl"
},
IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
str := fmt.Sprintf("%v", val)
@@ -80,7 +112,7 @@ func addValidSiteURLBindingRule() {
// URL validation rule
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
- return strings.HasPrefix(rule, "ValidSiteUrl")
+ return rule == "ValidSiteUrl"
},
IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
str := fmt.Sprintf("%v", val)
@@ -171,7 +203,7 @@ func addUsernamePatternRule() {
func addValidGroupTeamMapRule() {
binding.AddRule(&binding.Rule{
IsMatch: func(rule string) bool {
- return strings.HasPrefix(rule, "ValidGroupTeamMap")
+ return rule == "ValidGroupTeamMap"
},
IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
_, err := auth.UnmarshalGroupTeamMapping(fmt.Sprintf("%v", val))
@@ -185,6 +217,34 @@ func addValidGroupTeamMapRule() {
})
}
+func addEmailBindingRules() {
+ binding.AddRule(&binding.Rule{
+ IsMatch: func(rule string) bool {
+ return strings.HasPrefix(rule, "EmailWithAllowedDomain")
+ },
+ IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
+ if err := ValidateEmail(fmt.Sprintf("%v", val)); err != nil {
+ errs.Add([]string{name}, ErrEmail, err.Error())
+ return false, errs
+ }
+ return true, errs
+ },
+ })
+
+ binding.AddRule(&binding.Rule{
+ IsMatch: func(rule string) bool {
+ return strings.HasPrefix(rule, "EmailForAdmin")
+ },
+ IsValid: func(errs binding.Errors, name string, val any) (bool, binding.Errors) {
+ if err := ValidateEmailForAdmin(fmt.Sprintf("%v", val)); err != nil {
+ errs.Add([]string{name}, ErrEmail, err.Error())
+ return false, errs
+ }
+ return true, errs
+ },
+ })
+}
+
func portOnly(hostport string) string {
colon := strings.IndexByte(hostport, ':')
if colon == -1 {
diff --git a/modules/validation/binding_test.go b/modules/validation/binding_test.go
index 01ff4e3435..5adcdf0289 100644
--- a/modules/validation/binding_test.go
+++ b/modules/validation/binding_test.go
@@ -8,7 +8,7 @@ import (
"net/http/httptest"
"testing"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
chi "github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
)
@@ -27,6 +27,7 @@ type (
TestForm struct {
BranchName string `form:"BranchName" binding:"GitRefName"`
URL string `form:"ValidUrl" binding:"ValidUrl"`
+ URLs string `form:"ValidUrls" binding:"ValidUrlList"`
GlobPattern string `form:"GlobPattern" binding:"GlobPattern"`
RegexPattern string `form:"RegexPattern" binding:"RegexPattern"`
}
diff --git a/modules/validation/email.go b/modules/validation/email.go
new file mode 100644
index 0000000000..fb563c2b81
--- /dev/null
+++ b/modules/validation/email.go
@@ -0,0 +1,146 @@
+// Copyright 2016 The Gogs Authors. All rights reserved.
+// Copyright 2020 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved
+// SPDX-License-Identifier: MIT
+
+package validation
+
+import (
+ "fmt"
+ "net/mail"
+ "regexp"
+ "strings"
+
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+
+ "github.com/gobwas/glob"
+)
+
+// ErrEmailNotActivated e-mail address has not been activated error
+var ErrEmailNotActivated = util.NewInvalidArgumentErrorf("e-mail address has not been activated")
+
+// ErrEmailCharIsNotSupported e-mail address contains unsupported character
+type ErrEmailCharIsNotSupported struct {
+ Email string
+}
+
+// IsErrEmailCharIsNotSupported checks if an error is an ErrEmailCharIsNotSupported
+func IsErrEmailCharIsNotSupported(err error) bool {
+ _, ok := err.(ErrEmailCharIsNotSupported)
+ return ok
+}
+
+func (err ErrEmailCharIsNotSupported) Error() string {
+ return fmt.Sprintf("e-mail address contains unsupported character [email: %s]", err.Email)
+}
+
+// ErrEmailInvalid represents an error where the email address does not comply with RFC 5322
+// or has a leading '-' character
+type ErrEmailInvalid struct {
+ Email string
+}
+
+// IsErrEmailInvalid checks if an error is an ErrEmailInvalid
+func IsErrEmailInvalid(err error) bool {
+ _, ok := err.(ErrEmailInvalid)
+ return ok
+}
+
+func (err ErrEmailInvalid) Error() string {
+ return fmt.Sprintf("e-mail invalid [email: %s]", err.Email)
+}
+
+func (err ErrEmailInvalid) Unwrap() error {
+ return util.ErrInvalidArgument
+}
+
+var emailRegexp = regexp.MustCompile("^[a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$")
+
+// check if email is a valid address with allowed domain
+func ValidateEmail(email string) error {
+ if err := validateEmailBasic(email); err != nil {
+ return err
+ }
+ return validateEmailDomain(email)
+}
+
+// check if email is a valid address when admins manually add or edit users
+func ValidateEmailForAdmin(email string) error {
+ return validateEmailBasic(email)
+ // In this case we do not need to check the email domain
+}
+
+// validateEmailBasic checks whether the email complies with the rules
+func validateEmailBasic(email string) error {
+ if len(email) == 0 {
+ return ErrEmailInvalid{email}
+ }
+
+ if !emailRegexp.MatchString(email) {
+ return ErrEmailCharIsNotSupported{email}
+ }
+
+ if email[0] == '-' {
+ return ErrEmailInvalid{email}
+ }
+
+ if _, err := mail.ParseAddress(email); err != nil {
+ return ErrEmailInvalid{email}
+ }
+
+ return nil
+}
+
+func validateEmailDomain(email string) error {
+ if !IsEmailDomainAllowed(email) {
+ return ErrEmailInvalid{email}
+ }
+
+ return nil
+}
+
+func IsEmailDomainAllowed(email string) bool {
+ return isEmailDomainAllowedInternal(
+ email,
+ setting.Service.EmailDomainAllowList,
+ setting.Service.EmailDomainBlockList)
+}
+
+func isEmailDomainAllowedInternal(
+ email string,
+ emailDomainAllowList []glob.Glob,
+ emailDomainBlockList []glob.Glob,
+) bool {
+ var result bool
+
+ if len(emailDomainAllowList) == 0 {
+ result = !isEmailDomainListed(emailDomainBlockList, email)
+ } else {
+ result = isEmailDomainListed(emailDomainAllowList, email)
+ }
+ return result
+}
+
+// isEmailDomainListed checks whether the domain of an email address
+// matches a list of domains
+func isEmailDomainListed(globs []glob.Glob, email string) bool {
+ if len(globs) == 0 {
+ return false
+ }
+
+ n := strings.LastIndex(email, "@")
+ if n <= 0 {
+ return false
+ }
+
+ domain := strings.ToLower(email[n+1:])
+
+ for _, g := range globs {
+ if g.Match(domain) {
+ return true
+ }
+ }
+
+ return false
+}
diff --git a/modules/validation/email_test.go b/modules/validation/email_test.go
new file mode 100644
index 0000000000..ffdc6fd4ee
--- /dev/null
+++ b/modules/validation/email_test.go
@@ -0,0 +1,73 @@
+// Copyright 2017 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved
+// SPDX-License-Identifier: MIT
+
+package validation
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestEmailAddressValidate(t *testing.T) {
+ kases := map[string]error{
+ "abc@gmail.com": nil,
+ "132@hotmail.com": nil,
+ "1-3-2@test.org": nil,
+ "1.3.2@test.org": nil,
+ "a_123@test.org.cn": nil,
+ `first.last@iana.org`: nil,
+ `first!last@iana.org`: nil,
+ `first#last@iana.org`: nil,
+ `first$last@iana.org`: nil,
+ `first%last@iana.org`: nil,
+ `first&last@iana.org`: nil,
+ `first'last@iana.org`: nil,
+ `first*last@iana.org`: nil,
+ `first+last@iana.org`: nil,
+ `first/last@iana.org`: nil,
+ `first=last@iana.org`: nil,
+ `first?last@iana.org`: nil,
+ `first^last@iana.org`: nil,
+ "first`last@iana.org": nil,
+ `first{last@iana.org`: nil,
+ `first|last@iana.org`: nil,
+ `first}last@iana.org`: nil,
+ `first~last@iana.org`: nil,
+ `first;last@iana.org`: ErrEmailCharIsNotSupported{`first;last@iana.org`},
+ ".233@qq.com": ErrEmailInvalid{".233@qq.com"},
+ "!233@qq.com": nil,
+ "#233@qq.com": nil,
+ "$233@qq.com": nil,
+ "%233@qq.com": nil,
+ "&233@qq.com": nil,
+ "'233@qq.com": nil,
+ "*233@qq.com": nil,
+ "+233@qq.com": nil,
+ "-233@qq.com": ErrEmailInvalid{"-233@qq.com"},
+ "/233@qq.com": nil,
+ "=233@qq.com": nil,
+ "?233@qq.com": nil,
+ "^233@qq.com": nil,
+ "_233@qq.com": nil,
+ "`233@qq.com": nil,
+ "{233@qq.com": nil,
+ "|233@qq.com": nil,
+ "}233@qq.com": nil,
+ "~233@qq.com": nil,
+ ";233@qq.com": ErrEmailCharIsNotSupported{";233@qq.com"},
+ "Foo ": ErrEmailCharIsNotSupported{"Foo "},
+ string([]byte{0xE2, 0x84, 0xAA}): ErrEmailCharIsNotSupported{string([]byte{0xE2, 0x84, 0xAA})},
+ }
+ for kase, err := range kases {
+ t.Run(kase, func(t *testing.T) {
+ assert.EqualValues(t, err, ValidateEmail(kase))
+ })
+ }
+}
+
+func TestEmailDomainAllowList(t *testing.T) {
+ res := IsEmailDomainAllowed("someuser@localhost.localdomain")
+ assert.True(t, res)
+}
diff --git a/modules/validation/glob_pattern_test.go b/modules/validation/glob_pattern_test.go
index 1bf622e61d..42d86754e1 100644
--- a/modules/validation/glob_pattern_test.go
+++ b/modules/validation/glob_pattern_test.go
@@ -6,7 +6,7 @@ package validation
import (
"testing"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
"github.com/gobwas/glob"
)
diff --git a/modules/validation/helpers.go b/modules/validation/helpers.go
index 567ad867fe..1f573564e6 100644
--- a/modules/validation/helpers.go
+++ b/modules/validation/helpers.go
@@ -9,9 +9,7 @@ import (
"regexp"
"strings"
- "code.gitea.io/gitea/modules/setting"
-
- "github.com/gobwas/glob"
+ "forgejo.org/modules/setting"
)
var externalTrackerRegex = regexp.MustCompile(`({?)(?:user|repo|index)+?(}?)`)
@@ -50,29 +48,6 @@ func IsValidSiteURL(uri string) bool {
return false
}
-// IsEmailDomainListed checks whether the domain of an email address
-// matches a list of domains
-func IsEmailDomainListed(globs []glob.Glob, email string) bool {
- if len(globs) == 0 {
- return false
- }
-
- n := strings.LastIndex(email, "@")
- if n <= 0 {
- return false
- }
-
- domain := strings.ToLower(email[n+1:])
-
- for _, g := range globs {
- if g.Match(domain) {
- return true
- }
- }
-
- return false
-}
-
// IsAPIURL checks if URL is current Gitea instance API URL
func IsAPIURL(uri string) bool {
return strings.HasPrefix(strings.ToLower(uri), strings.ToLower(setting.AppURL+"api"))
diff --git a/modules/validation/helpers_test.go b/modules/validation/helpers_test.go
index a1bdf2a29c..01a17f0d6b 100644
--- a/modules/validation/helpers_test.go
+++ b/modules/validation/helpers_test.go
@@ -6,7 +6,7 @@ package validation
import (
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
)
diff --git a/modules/validation/refname_test.go b/modules/validation/refname_test.go
index 3af7387c47..bb64cab51e 100644
--- a/modules/validation/refname_test.go
+++ b/modules/validation/refname_test.go
@@ -6,7 +6,7 @@ package validation
import (
"testing"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
var gitRefNameValidationTestCases = []validationTestCase{
diff --git a/modules/validation/regex_pattern_test.go b/modules/validation/regex_pattern_test.go
index efcb276734..90bd969c4f 100644
--- a/modules/validation/regex_pattern_test.go
+++ b/modules/validation/regex_pattern_test.go
@@ -7,7 +7,7 @@ import (
"regexp"
"testing"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
func getRegexPatternErrorString(pattern string) string {
diff --git a/modules/validation/validatable.go b/modules/validation/validatable.go
index 94b5cc135c..bc565bd194 100644
--- a/modules/validation/validatable.go
+++ b/modules/validation/validatable.go
@@ -10,7 +10,7 @@ import (
"strings"
"unicode/utf8"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
)
// ErrNotValid represents an validation error
diff --git a/modules/validation/validatable_test.go b/modules/validation/validatable_test.go
index 919f5a3183..0802d5cc92 100644
--- a/modules/validation/validatable_test.go
+++ b/modules/validation/validatable_test.go
@@ -6,7 +6,7 @@ package validation
import (
"testing"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
)
type Sut struct {
diff --git a/modules/validation/validurl_test.go b/modules/validation/validurl_test.go
index 39f7fa5d65..77fa7aa097 100644
--- a/modules/validation/validurl_test.go
+++ b/modules/validation/validurl_test.go
@@ -6,7 +6,7 @@ package validation
import (
"testing"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
var urlValidationTestCases = []validationTestCase{
diff --git a/modules/validation/validurllist_test.go b/modules/validation/validurllist_test.go
new file mode 100644
index 0000000000..506f96da69
--- /dev/null
+++ b/modules/validation/validurllist_test.go
@@ -0,0 +1,157 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package validation
+
+import (
+ "testing"
+
+ "code.forgejo.org/go-chi/binding"
+)
+
+// This is a copy of all the URL tests cases, plus additional ones to
+// account for multiple URLs
+var urlListValidationTestCases = []validationTestCase{
+ {
+ description: "Empty URL",
+ data: TestForm{
+ URLs: "",
+ },
+ expectedErrors: binding.Errors{},
+ },
+ {
+ description: "URL without port",
+ data: TestForm{
+ URLs: "http://test.lan/",
+ },
+ expectedErrors: binding.Errors{},
+ },
+ {
+ description: "URL with port",
+ data: TestForm{
+ URLs: "http://test.lan:3000/",
+ },
+ expectedErrors: binding.Errors{},
+ },
+ {
+ description: "URL with IPv6 address without port",
+ data: TestForm{
+ URLs: "http://[::1]/",
+ },
+ expectedErrors: binding.Errors{},
+ },
+ {
+ description: "URL with IPv6 address with port",
+ data: TestForm{
+ URLs: "http://[::1]:3000/",
+ },
+ expectedErrors: binding.Errors{},
+ },
+ {
+ description: "Invalid URL",
+ data: TestForm{
+ URLs: "http//test.lan/",
+ },
+ expectedErrors: binding.Errors{
+ binding.Error{
+ FieldNames: []string{"URLs"},
+ Classification: binding.ERR_URL,
+ Message: "http//test.lan/",
+ },
+ },
+ },
+ {
+ description: "Invalid schema",
+ data: TestForm{
+ URLs: "ftp://test.lan/",
+ },
+ expectedErrors: binding.Errors{
+ binding.Error{
+ FieldNames: []string{"URLs"},
+ Classification: binding.ERR_URL,
+ Message: "ftp://test.lan/",
+ },
+ },
+ },
+ {
+ description: "Invalid port",
+ data: TestForm{
+ URLs: "http://test.lan:3x4/",
+ },
+ expectedErrors: binding.Errors{
+ binding.Error{
+ FieldNames: []string{"URLs"},
+ Classification: binding.ERR_URL,
+ Message: "http://test.lan:3x4/",
+ },
+ },
+ },
+ {
+ description: "Invalid port with IPv6 address",
+ data: TestForm{
+ URLs: "http://[::1]:3x4/",
+ },
+ expectedErrors: binding.Errors{
+ binding.Error{
+ FieldNames: []string{"URLs"},
+ Classification: binding.ERR_URL,
+ Message: "http://[::1]:3x4/",
+ },
+ },
+ },
+ {
+ description: "Multi URLs",
+ data: TestForm{
+ URLs: "http://test.lan:3000/\nhttp://test.local/",
+ },
+ expectedErrors: binding.Errors{},
+ },
+ {
+ description: "Multi URLs with newline",
+ data: TestForm{
+ URLs: "http://test.lan:3000/\nhttp://test.local/\n",
+ },
+ expectedErrors: binding.Errors{},
+ },
+ {
+ description: "List with invalid entry",
+ data: TestForm{
+ URLs: "http://test.lan:3000/\nhttp://[::1]:3x4/",
+ },
+ expectedErrors: binding.Errors{
+ binding.Error{
+ FieldNames: []string{"URLs"},
+ Classification: binding.ERR_URL,
+ Message: "http://[::1]:3x4/",
+ },
+ },
+ },
+ {
+ description: "List with two invalid entries",
+ data: TestForm{
+ URLs: "ftp://test.lan:3000/\nhttp://[::1]:3x4/\n",
+ },
+ expectedErrors: binding.Errors{
+ binding.Error{
+ FieldNames: []string{"URLs"},
+ Classification: binding.ERR_URL,
+ Message: "ftp://test.lan:3000/",
+ },
+ binding.Error{
+ FieldNames: []string{"URLs"},
+ Classification: binding.ERR_URL,
+ Message: "http://[::1]:3x4/",
+ },
+ },
+ },
+}
+
+func Test_ValidURLListValidation(t *testing.T) {
+ AddBindingRules()
+
+ for _, testCase := range urlListValidationTestCases {
+ t.Run(testCase.description, func(t *testing.T) {
+ performValidationTest(t, testCase)
+ })
+ }
+}
diff --git a/modules/web/handler.go b/modules/web/handler.go
index 728cc5a160..4a7f28b1fa 100644
--- a/modules/web/handler.go
+++ b/modules/web/handler.go
@@ -9,9 +9,9 @@ import (
"net/http"
"reflect"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/web/routing"
- "code.gitea.io/gitea/modules/web/types"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/web/routing"
+ "forgejo.org/modules/web/types"
)
var responseStatusProviders = map[reflect.Type]func(req *http.Request) types.ResponseStatusProvider{}
diff --git a/modules/web/middleware/binding.go b/modules/web/middleware/binding.go
index 8fa71a81bd..9083e9b485 100644
--- a/modules/web/middleware/binding.go
+++ b/modules/web/middleware/binding.go
@@ -8,12 +8,12 @@ import (
"reflect"
"strings"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/validation"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// Form form binding interface
@@ -143,6 +143,8 @@ func Validate(errs binding.Errors, data map[string]any, f any, l translation.Loc
}
case validation.ErrInvalidGroupTeamMap:
data["ErrorMsg"] = trName + l.TrString("form.invalid_group_team_map_error", errs[0].Message)
+ case validation.ErrEmail:
+ data["ErrorMsg"] = trName + l.TrString("form.email_error")
default:
msg := errs[0].Classification
if msg != "" && errs[0].Message != "" {
diff --git a/modules/web/middleware/cookie.go b/modules/web/middleware/cookie.go
index f2d25f5b1c..3bfaeabe69 100644
--- a/modules/web/middleware/cookie.go
+++ b/modules/web/middleware/cookie.go
@@ -9,8 +9,8 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/modules/session"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/session"
+ "forgejo.org/modules/setting"
)
// SetRedirectToCookie convenience function to set the RedirectTo cookie consistently
diff --git a/modules/web/middleware/data.go b/modules/web/middleware/data.go
index 08d83f94be..4603e64052 100644
--- a/modules/web/middleware/data.go
+++ b/modules/web/middleware/data.go
@@ -7,7 +7,7 @@ import (
"context"
"time"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
// ContextDataStore represents a data store
diff --git a/modules/web/middleware/locale.go b/modules/web/middleware/locale.go
index 34a16f04e7..565fb2f502 100644
--- a/modules/web/middleware/locale.go
+++ b/modules/web/middleware/locale.go
@@ -6,8 +6,8 @@ package middleware
import (
"net/http"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/translation/i18n"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/translation/i18n"
"golang.org/x/text/language"
)
@@ -26,8 +26,10 @@ func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale {
}
}
- // Check again in case someone changes the supported language list.
- if lang != "" && !i18n.DefaultLocales.HasLang(lang) {
+ if lang == "dummy" {
+ changeLang = false
+ } else if lang != "" && !i18n.DefaultLocales.HasLang(lang) {
+ // Check again in case someone changes the supported language list.
lang = ""
changeLang = false
}
@@ -51,9 +53,3 @@ func Locale(resp http.ResponseWriter, req *http.Request) translation.Locale {
func SetLocaleCookie(resp http.ResponseWriter, lang string, maxAge int) {
SetSiteCookie(resp, "lang", lang, maxAge)
}
-
-// DeleteLocaleCookie convenience function to delete the locale cookie consistently
-// Setting the lang cookie will trigger the middleware to reset the language to previous state.
-func DeleteLocaleCookie(resp http.ResponseWriter) {
- SetSiteCookie(resp, "lang", "", -1)
-}
diff --git a/modules/web/route.go b/modules/web/route.go
index 805fcb4411..046c9f4ba7 100644
--- a/modules/web/route.go
+++ b/modules/web/route.go
@@ -7,9 +7,9 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/modules/web/middleware"
+ "forgejo.org/modules/web/middleware"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
"github.com/go-chi/chi/v5"
)
diff --git a/modules/web/route_test.go b/modules/web/route_test.go
index cc0e26a12e..d8015d6e0d 100644
--- a/modules/web/route_test.go
+++ b/modules/web/route_test.go
@@ -12,6 +12,7 @@ import (
chi "github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRoute1(t *testing.T) {
@@ -30,7 +31,7 @@ func TestRoute1(t *testing.T) {
})
req, err := http.NewRequest("GET", "http://localhost:8000/gitea/gitea/issues", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code)
}
@@ -87,25 +88,25 @@ func TestRoute2(t *testing.T) {
})
req, err := http.NewRequest("GET", "http://localhost:8000/gitea/gitea/issues", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code)
assert.EqualValues(t, 0, hit)
req, err = http.NewRequest("GET", "http://localhost:8000/gitea/gitea/issues/1", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code)
assert.EqualValues(t, 1, hit)
req, err = http.NewRequest("GET", "http://localhost:8000/gitea/gitea/issues/1?stop=100", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code)
assert.EqualValues(t, 100, hit)
req, err = http.NewRequest("GET", "http://localhost:8000/gitea/gitea/issues/1/view", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code)
assert.EqualValues(t, 2, hit)
@@ -147,31 +148,31 @@ func TestRoute3(t *testing.T) {
})
req, err := http.NewRequest("GET", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code)
assert.EqualValues(t, 0, hit)
req, err = http.NewRequest("POST", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code, http.StatusOK)
assert.EqualValues(t, 1, hit)
req, err = http.NewRequest("GET", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections/master", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code)
assert.EqualValues(t, 2, hit)
req, err = http.NewRequest("PATCH", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections/master", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code)
assert.EqualValues(t, 3, hit)
req, err = http.NewRequest("DELETE", "http://localhost:8000/api/v1/repos/gitea/gitea/branch_protections/master", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.EqualValues(t, http.StatusOK, recorder.Code)
assert.EqualValues(t, 4, hit)
diff --git a/modules/web/routemock.go b/modules/web/routemock.go
index cb41f63b91..33d2ad06eb 100644
--- a/modules/web/routemock.go
+++ b/modules/web/routemock.go
@@ -6,7 +6,7 @@ package web
import (
"net/http"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
// MockAfterMiddlewares is a general mock point, it's between middlewares and the handler
diff --git a/modules/web/routemock_test.go b/modules/web/routemock_test.go
index 04c6d1d82e..43d4b28830 100644
--- a/modules/web/routemock_test.go
+++ b/modules/web/routemock_test.go
@@ -8,9 +8,10 @@ import (
"net/http/httptest"
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRouteMock(t *testing.T) {
@@ -31,7 +32,7 @@ func TestRouteMock(t *testing.T) {
// normal request
recorder := httptest.NewRecorder()
req, err := http.NewRequest("GET", "http://localhost:8000/foo", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.Len(t, recorder.Header(), 3)
assert.EqualValues(t, "m1", recorder.Header().Get("X-Test-Middleware1"))
@@ -46,7 +47,7 @@ func TestRouteMock(t *testing.T) {
})
recorder = httptest.NewRecorder()
req, err = http.NewRequest("GET", "http://localhost:8000/foo", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.Len(t, recorder.Header(), 2)
assert.EqualValues(t, "m1", recorder.Header().Get("X-Test-Middleware1"))
@@ -60,7 +61,7 @@ func TestRouteMock(t *testing.T) {
})
recorder = httptest.NewRecorder()
req, err = http.NewRequest("GET", "http://localhost:8000/foo", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
r.ServeHTTP(recorder, req)
assert.Len(t, recorder.Header(), 3)
assert.EqualValues(t, "m1", recorder.Header().Get("X-Test-Middleware1"))
diff --git a/modules/web/routing/logger.go b/modules/web/routing/logger.go
index 5f3a7592af..8fd24c9733 100644
--- a/modules/web/routing/logger.go
+++ b/modules/web/routing/logger.go
@@ -8,8 +8,8 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/web/types"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/web/types"
)
// NewLoggerHandler is a handler that will log routing to the router log taking account of
@@ -90,7 +90,7 @@ func logPrinter(logger log.Logger) func(trigger Event, record *requestRecord) {
status = v.WrittenStatus()
}
logf := logger.Info
- if strings.HasPrefix(req.RequestURI, "/assets/") {
+ if strings.HasPrefix(req.RequestURI, "/assets/") || req.RequestURI == "/api/actions/runner.v1.RunnerService/FetchTask" || req.RequestURI == "/api/actions/runner.v1.RunnerService/UpdateLog" {
logf = logger.Trace
}
message := completedMessage
diff --git a/modules/web/routing/logger_manager.go b/modules/web/routing/logger_manager.go
index aa25ec3a27..4b12419b44 100644
--- a/modules/web/routing/logger_manager.go
+++ b/modules/web/routing/logger_manager.go
@@ -9,8 +9,8 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/process"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/process"
)
// Event indicates when the printer is triggered
diff --git a/modules/zstd/option.go b/modules/zstd/option.go
new file mode 100644
index 0000000000..916a390819
--- /dev/null
+++ b/modules/zstd/option.go
@@ -0,0 +1,46 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package zstd
+
+import "github.com/klauspost/compress/zstd"
+
+type WriterOption = zstd.EOption
+
+var (
+ WithEncoderCRC = zstd.WithEncoderCRC
+ WithEncoderConcurrency = zstd.WithEncoderConcurrency
+ WithWindowSize = zstd.WithWindowSize
+ WithEncoderPadding = zstd.WithEncoderPadding
+ WithEncoderLevel = zstd.WithEncoderLevel
+ WithZeroFrames = zstd.WithZeroFrames
+ WithAllLitEntropyCompression = zstd.WithAllLitEntropyCompression
+ WithNoEntropyCompression = zstd.WithNoEntropyCompression
+ WithSingleSegment = zstd.WithSingleSegment
+ WithLowerEncoderMem = zstd.WithLowerEncoderMem
+ WithEncoderDict = zstd.WithEncoderDict
+ WithEncoderDictRaw = zstd.WithEncoderDictRaw
+)
+
+type EncoderLevel = zstd.EncoderLevel
+
+const (
+ SpeedFastest EncoderLevel = zstd.SpeedFastest
+ SpeedDefault EncoderLevel = zstd.SpeedDefault
+ SpeedBetterCompression EncoderLevel = zstd.SpeedBetterCompression
+ SpeedBestCompression EncoderLevel = zstd.SpeedBestCompression
+)
+
+type ReaderOption = zstd.DOption
+
+var (
+ WithDecoderLowmem = zstd.WithDecoderLowmem
+ WithDecoderConcurrency = zstd.WithDecoderConcurrency
+ WithDecoderMaxMemory = zstd.WithDecoderMaxMemory
+ WithDecoderDicts = zstd.WithDecoderDicts
+ WithDecoderDictRaw = zstd.WithDecoderDictRaw
+ WithDecoderMaxWindow = zstd.WithDecoderMaxWindow
+ WithDecodeAllCapLimit = zstd.WithDecodeAllCapLimit
+ WithDecodeBuffersBelow = zstd.WithDecodeBuffersBelow
+ IgnoreChecksum = zstd.IgnoreChecksum
+)
diff --git a/modules/zstd/zstd.go b/modules/zstd/zstd.go
new file mode 100644
index 0000000000..d2249447d6
--- /dev/null
+++ b/modules/zstd/zstd.go
@@ -0,0 +1,163 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+// Package zstd provides a high-level API for reading and writing zstd-compressed data.
+// It supports both regular and seekable zstd streams.
+// It's not a new wheel, but a wrapper around the zstd and zstd-seekable-format-go packages.
+package zstd
+
+import (
+ "errors"
+ "io"
+
+ seekable "github.com/SaveTheRbtz/zstd-seekable-format-go/pkg"
+ "github.com/klauspost/compress/zstd"
+)
+
+type Writer zstd.Encoder
+
+var _ io.WriteCloser = (*Writer)(nil)
+
+// NewWriter returns a new zstd writer.
+func NewWriter(w io.Writer, opts ...WriterOption) (*Writer, error) {
+ zstdW, err := zstd.NewWriter(w, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return (*Writer)(zstdW), nil
+}
+
+func (w *Writer) Write(p []byte) (int, error) {
+ return (*zstd.Encoder)(w).Write(p)
+}
+
+func (w *Writer) Close() error {
+ return (*zstd.Encoder)(w).Close()
+}
+
+type Reader zstd.Decoder
+
+var _ io.ReadCloser = (*Reader)(nil)
+
+// NewReader returns a new zstd reader.
+func NewReader(r io.Reader, opts ...ReaderOption) (*Reader, error) {
+ zstdR, err := zstd.NewReader(r, opts...)
+ if err != nil {
+ return nil, err
+ }
+ return (*Reader)(zstdR), nil
+}
+
+func (r *Reader) Read(p []byte) (int, error) {
+ return (*zstd.Decoder)(r).Read(p)
+}
+
+func (r *Reader) Close() error {
+ (*zstd.Decoder)(r).Close() // no error returned
+ return nil
+}
+
+type SeekableWriter struct {
+ buf []byte
+ n int
+ w seekable.Writer
+}
+
+var _ io.WriteCloser = (*SeekableWriter)(nil)
+
+// NewSeekableWriter returns a zstd writer to compress data to seekable format.
+// blockSize is an important parameter, it should be decided according to the actual business requirements.
+// If it's too small, the compression ratio could be very bad, even no compression at all.
+// If it's too large, it could cost more traffic when reading the data partially from underlying storage.
+func NewSeekableWriter(w io.Writer, blockSize int, opts ...WriterOption) (*SeekableWriter, error) {
+ zstdW, err := zstd.NewWriter(nil, opts...)
+ if err != nil {
+ return nil, err
+ }
+
+ seekableW, err := seekable.NewWriter(w, zstdW)
+ if err != nil {
+ return nil, err
+ }
+
+ return &SeekableWriter{
+ buf: make([]byte, blockSize),
+ w: seekableW,
+ }, nil
+}
+
+func (w *SeekableWriter) Write(p []byte) (int, error) {
+ written := 0
+ for len(p) > 0 {
+ n := copy(w.buf[w.n:], p)
+ w.n += n
+ written += n
+ p = p[n:]
+
+ if w.n == len(w.buf) {
+ if _, err := w.w.Write(w.buf); err != nil {
+ return written, err
+ }
+ w.n = 0
+ }
+ }
+ return written, nil
+}
+
+func (w *SeekableWriter) Close() error {
+ if w.n > 0 {
+ if _, err := w.w.Write(w.buf[:w.n]); err != nil {
+ return err
+ }
+ }
+ return w.w.Close()
+}
+
+type SeekableReader struct {
+ r seekable.Reader
+ c func() error
+}
+
+var _ io.ReadSeekCloser = (*SeekableReader)(nil)
+
+// NewSeekableReader returns a zstd reader to decompress data from seekable format.
+func NewSeekableReader(r io.ReadSeeker, opts ...ReaderOption) (*SeekableReader, error) {
+ zstdR, err := zstd.NewReader(nil, opts...)
+ if err != nil {
+ return nil, err
+ }
+
+ seekableR, err := seekable.NewReader(r, zstdR)
+ if err != nil {
+ return nil, err
+ }
+
+ ret := &SeekableReader{
+ r: seekableR,
+ }
+ if closer, ok := r.(io.Closer); ok {
+ ret.c = closer.Close
+ }
+
+ return ret, nil
+}
+
+func (r *SeekableReader) Read(p []byte) (int, error) {
+ return r.r.Read(p)
+}
+
+func (r *SeekableReader) Seek(offset int64, whence int) (int64, error) {
+ return r.r.Seek(offset, whence)
+}
+
+func (r *SeekableReader) Close() error {
+ return errors.Join(
+ func() error {
+ if r.c != nil {
+ return r.c()
+ }
+ return nil
+ }(),
+ r.r.Close(),
+ )
+}
diff --git a/modules/zstd/zstd_test.go b/modules/zstd/zstd_test.go
new file mode 100644
index 0000000000..9284ab0eb2
--- /dev/null
+++ b/modules/zstd/zstd_test.go
@@ -0,0 +1,304 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package zstd
+
+import (
+ "bytes"
+ "io"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestWriterReader(t *testing.T) {
+ testData := prepareTestData(t, 15_000_000)
+
+ result := bytes.NewBuffer(nil)
+
+ t.Run("regular", func(t *testing.T) {
+ result.Reset()
+ writer, err := NewWriter(result)
+ require.NoError(t, err)
+
+ _, err = io.Copy(writer, bytes.NewReader(testData))
+ require.NoError(t, err)
+ require.NoError(t, writer.Close())
+
+ t.Logf("original size: %d, compressed size: %d, rate: %.2f%%", len(testData), result.Len(), float64(result.Len())/float64(len(testData))*100)
+
+ reader, err := NewReader(result)
+ require.NoError(t, err)
+
+ data, err := io.ReadAll(reader)
+ require.NoError(t, err)
+ require.NoError(t, reader.Close())
+
+ assert.Equal(t, testData, data)
+ })
+
+ t.Run("with options", func(t *testing.T) {
+ result.Reset()
+ writer, err := NewWriter(result, WithEncoderLevel(SpeedBestCompression))
+ require.NoError(t, err)
+
+ _, err = io.Copy(writer, bytes.NewReader(testData))
+ require.NoError(t, err)
+ require.NoError(t, writer.Close())
+
+ t.Logf("original size: %d, compressed size: %d, rate: %.2f%%", len(testData), result.Len(), float64(result.Len())/float64(len(testData))*100)
+
+ reader, err := NewReader(result, WithDecoderLowmem(true))
+ require.NoError(t, err)
+
+ data, err := io.ReadAll(reader)
+ require.NoError(t, err)
+ require.NoError(t, reader.Close())
+
+ assert.Equal(t, testData, data)
+ })
+}
+
+func TestSeekableWriterReader(t *testing.T) {
+ testData := prepareTestData(t, 15_000_000)
+
+ result := bytes.NewBuffer(nil)
+
+ t.Run("regular", func(t *testing.T) {
+ result.Reset()
+ blockSize := 100_000
+
+ writer, err := NewSeekableWriter(result, blockSize)
+ require.NoError(t, err)
+
+ _, err = io.Copy(writer, bytes.NewReader(testData))
+ require.NoError(t, err)
+ require.NoError(t, writer.Close())
+
+ t.Logf("original size: %d, compressed size: %d, rate: %.2f%%", len(testData), result.Len(), float64(result.Len())/float64(len(testData))*100)
+
+ reader, err := NewSeekableReader(bytes.NewReader(result.Bytes()))
+ require.NoError(t, err)
+
+ data, err := io.ReadAll(reader)
+ require.NoError(t, err)
+ require.NoError(t, reader.Close())
+
+ assert.Equal(t, testData, data)
+ })
+
+ t.Run("seek read", func(t *testing.T) {
+ result.Reset()
+ blockSize := 100_000
+
+ writer, err := NewSeekableWriter(result, blockSize)
+ require.NoError(t, err)
+
+ _, err = io.Copy(writer, bytes.NewReader(testData))
+ require.NoError(t, err)
+ require.NoError(t, writer.Close())
+
+ t.Logf("original size: %d, compressed size: %d, rate: %.2f%%", len(testData), result.Len(), float64(result.Len())/float64(len(testData))*100)
+
+ assertReader := &assertReadSeeker{r: bytes.NewReader(result.Bytes())}
+
+ reader, err := NewSeekableReader(assertReader)
+ require.NoError(t, err)
+
+ _, err = reader.Seek(10_000_000, io.SeekStart)
+ require.NoError(t, err)
+
+ data := make([]byte, 1000)
+ _, err = io.ReadFull(reader, data)
+ require.NoError(t, err)
+ require.NoError(t, reader.Close())
+
+ assert.Equal(t, testData[10_000_000:10_000_000+1000], data)
+
+ // Should seek 3 times,
+ // the first two times are for getting the index,
+ // and the third time is for reading the data.
+ assert.Equal(t, 3, assertReader.SeekTimes)
+ // Should read less than 2 blocks,
+ // even if the compression ratio is not good and the data is not in the same block.
+ assert.Less(t, assertReader.ReadBytes, blockSize*2)
+ // Should close the underlying reader if it is Closer.
+ assert.True(t, assertReader.Closed)
+ })
+
+ t.Run("tidy data", func(t *testing.T) {
+ testData := prepareTestData(t, 1000) // data size is less than a block
+
+ result.Reset()
+ blockSize := 100_000
+
+ writer, err := NewSeekableWriter(result, blockSize)
+ require.NoError(t, err)
+
+ _, err = io.Copy(writer, bytes.NewReader(testData))
+ require.NoError(t, err)
+ require.NoError(t, writer.Close())
+
+ t.Logf("original size: %d, compressed size: %d, rate: %.2f%%", len(testData), result.Len(), float64(result.Len())/float64(len(testData))*100)
+
+ reader, err := NewSeekableReader(bytes.NewReader(result.Bytes()))
+ require.NoError(t, err)
+
+ data, err := io.ReadAll(reader)
+ require.NoError(t, err)
+ require.NoError(t, reader.Close())
+
+ assert.Equal(t, testData, data)
+ })
+
+ t.Run("tidy block", func(t *testing.T) {
+ result.Reset()
+ blockSize := 100
+
+ writer, err := NewSeekableWriter(result, blockSize)
+ require.NoError(t, err)
+
+ _, err = io.Copy(writer, bytes.NewReader(testData))
+ require.NoError(t, err)
+ require.NoError(t, writer.Close())
+
+ t.Logf("original size: %d, compressed size: %d, rate: %.2f%%", len(testData), result.Len(), float64(result.Len())/float64(len(testData))*100)
+ // A too small block size will cause a bad compression rate,
+ // even the compressed data is larger than the original data.
+ assert.Greater(t, result.Len(), len(testData))
+
+ reader, err := NewSeekableReader(bytes.NewReader(result.Bytes()))
+ require.NoError(t, err)
+
+ data, err := io.ReadAll(reader)
+ require.NoError(t, err)
+ require.NoError(t, reader.Close())
+
+ assert.Equal(t, testData, data)
+ })
+
+ t.Run("compatible reader", func(t *testing.T) {
+ result.Reset()
+ blockSize := 100_000
+
+ writer, err := NewSeekableWriter(result, blockSize)
+ require.NoError(t, err)
+
+ _, err = io.Copy(writer, bytes.NewReader(testData))
+ require.NoError(t, err)
+ require.NoError(t, writer.Close())
+
+ t.Logf("original size: %d, compressed size: %d, rate: %.2f%%", len(testData), result.Len(), float64(result.Len())/float64(len(testData))*100)
+
+ // It should be able to read the data with a regular reader.
+ reader, err := NewReader(bytes.NewReader(result.Bytes()))
+ require.NoError(t, err)
+
+ data, err := io.ReadAll(reader)
+ require.NoError(t, err)
+ require.NoError(t, reader.Close())
+
+ assert.Equal(t, testData, data)
+ })
+
+ t.Run("wrong reader", func(t *testing.T) {
+ result.Reset()
+
+ // Use a regular writer to compress the data.
+ writer, err := NewWriter(result)
+ require.NoError(t, err)
+
+ _, err = io.Copy(writer, bytes.NewReader(testData))
+ require.NoError(t, err)
+ require.NoError(t, writer.Close())
+
+ t.Logf("original size: %d, compressed size: %d, rate: %.2f%%", len(testData), result.Len(), float64(result.Len())/float64(len(testData))*100)
+
+ // But use a seekable reader to read the data, it should fail.
+ _, err = NewSeekableReader(bytes.NewReader(result.Bytes()))
+ require.Error(t, err)
+ })
+}
+
+// prepareTestData prepares test data to test compression.
+// Random data is not suitable for testing compression,
+// so it collects code files from the project to get enough data.
+func prepareTestData(t *testing.T, size int) []byte {
+ // .../gitea/modules/zstd
+ dir, err := os.Getwd()
+ require.NoError(t, err)
+ // .../gitea/
+ dir = filepath.Join(dir, "../../")
+
+ textExt := []string{".go", ".tmpl", ".ts", ".yml", ".css"} // add more if not enough data collected
+ isText := func(info os.FileInfo) bool {
+ if info.Size() == 0 {
+ return false
+ }
+ for _, ext := range textExt {
+ if strings.HasSuffix(info.Name(), ext) {
+ return true
+ }
+ }
+ return false
+ }
+
+ ret := make([]byte, size)
+ n := 0
+ count := 0
+
+ queue := []string{dir}
+ for len(queue) > 0 && n < size {
+ file := queue[0]
+ queue = queue[1:]
+ info, err := os.Stat(file)
+ require.NoError(t, err)
+ if info.IsDir() {
+ entries, err := os.ReadDir(file)
+ require.NoError(t, err)
+ for _, entry := range entries {
+ queue = append(queue, filepath.Join(file, entry.Name()))
+ }
+ continue
+ }
+ if !isText(info) { // text file only
+ continue
+ }
+ data, err := os.ReadFile(file)
+ require.NoError(t, err)
+ n += copy(ret[n:], data)
+ count++
+ }
+
+ if n < size {
+ require.Failf(t, "Not enough data", "Only %d bytes collected from %d files", n, count)
+ }
+ return ret
+}
+
+type assertReadSeeker struct {
+ r io.ReadSeeker
+ SeekTimes int
+ ReadBytes int
+ Closed bool
+}
+
+func (a *assertReadSeeker) Read(p []byte) (int, error) {
+ n, err := a.r.Read(p)
+ a.ReadBytes += n
+ return n, err
+}
+
+func (a *assertReadSeeker) Seek(offset int64, whence int) (int64, error) {
+ a.SeekTimes++
+ return a.r.Seek(offset, whence)
+}
+
+func (a *assertReadSeeker) Close() error {
+ a.Closed = true
+ return nil
+}
diff --git a/options/gitignore/Flutter b/options/gitignore/Flutter
new file mode 100644
index 0000000000..39b8814aec
--- /dev/null
+++ b/options/gitignore/Flutter
@@ -0,0 +1,119 @@
+# Miscellaneous
+*.class
+*.lock
+*.log
+*.pyc
+*.swp
+.buildlog/
+.history
+
+
+
+# Flutter repo-specific
+/bin/cache/
+/bin/internal/bootstrap.bat
+/bin/internal/bootstrap.sh
+/bin/mingit/
+/dev/benchmarks/mega_gallery/
+/dev/bots/.recipe_deps
+/dev/bots/android_tools/
+/dev/devicelab/ABresults*.json
+/dev/docs/doc/
+/dev/docs/flutter.docs.zip
+/dev/docs/lib/
+/dev/docs/pubspec.yaml
+/dev/integration_tests/**/xcuserdata
+/dev/integration_tests/**/Pods
+/packages/flutter/coverage/
+version
+analysis_benchmark.json
+
+# packages file containing multi-root paths
+.packages.generated
+
+# Flutter/Dart/Pub related
+**/doc/api/
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+**/generated_plugin_registrant.dart
+.packages
+.pub-preload-cache/
+.pub/
+build/
+flutter_*.png
+linked_*.ds
+unlinked.ds
+unlinked_spec.ds
+
+# Android related
+**/android/**/gradle-wrapper.jar
+.gradle/
+**/android/captures/
+**/android/gradlew
+**/android/gradlew.bat
+**/android/local.properties
+**/android/**/GeneratedPluginRegistrant.java
+**/android/key.properties
+*.jks
+
+# iOS/XCode related
+**/ios/**/*.mode1v3
+**/ios/**/*.mode2v3
+**/ios/**/*.moved-aside
+**/ios/**/*.pbxuser
+**/ios/**/*.perspectivev3
+**/ios/**/*sync/
+**/ios/**/.sconsign.dblite
+**/ios/**/.tags*
+**/ios/**/.vagrant/
+**/ios/**/DerivedData/
+**/ios/**/Icon?
+**/ios/**/Pods/
+**/ios/**/.symlinks/
+**/ios/**/profile
+**/ios/**/xcuserdata
+**/ios/.generated/
+**/ios/Flutter/.last_build_id
+**/ios/Flutter/App.framework
+**/ios/Flutter/Flutter.framework
+**/ios/Flutter/Flutter.podspec
+**/ios/Flutter/Generated.xcconfig
+**/ios/Flutter/ephemeral
+**/ios/Flutter/app.flx
+**/ios/Flutter/app.zip
+**/ios/Flutter/flutter_assets/
+**/ios/Flutter/flutter_export_environment.sh
+**/ios/ServiceDefinitions.json
+**/ios/Runner/GeneratedPluginRegistrant.*
+
+# macOS
+**/Flutter/ephemeral/
+**/Pods/
+**/macos/Flutter/GeneratedPluginRegistrant.swift
+**/macos/Flutter/ephemeral
+**/xcuserdata/
+
+# Windows
+**/windows/flutter/generated_plugin_registrant.cc
+**/windows/flutter/generated_plugin_registrant.h
+**/windows/flutter/generated_plugins.cmake
+
+# Linux
+**/linux/flutter/generated_plugin_registrant.cc
+**/linux/flutter/generated_plugin_registrant.h
+**/linux/flutter/generated_plugins.cmake
+
+# Coverage
+coverage/
+
+# Symbols
+app.*.symbols
+
+# Exceptions to above rules.
+!**/ios/**/default.mode1v3
+!**/ios/**/default.mode2v3
+!**/ios/**/default.pbxuser
+!**/ios/**/default.perspectivev3
+!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
+!/dev/ci/**/Gemfile.lock
\ No newline at end of file
diff --git a/options/gitignore/Hexo b/options/gitignore/Hexo
new file mode 100644
index 0000000000..570a5e7b5d
--- /dev/null
+++ b/options/gitignore/Hexo
@@ -0,0 +1,14 @@
+# gitignore template for Hexo sites
+# website: https://hexo.io/
+# Recommended: Node.gitignore
+
+# Ignore generated directory
+public/
+
+# Ignore temp files
+tmp/
+.tmp*
+
+# additional files
+db.json
+.deploy*/
diff --git a/options/gitignore/Nix b/options/gitignore/Nix
index 1fd04ef1f6..912e6700f4 100644
--- a/options/gitignore/Nix
+++ b/options/gitignore/Nix
@@ -1,3 +1,6 @@
# Ignore build outputs from performing a nix-build or `nix build` command
result
result-*
+
+# Ignore automatically generated direnv output
+.direnv
diff --git a/options/gitignore/NotesAndCoreConfiguration b/options/gitignore/NotesAndCoreConfiguration
new file mode 100644
index 0000000000..4eff01dae1
--- /dev/null
+++ b/options/gitignore/NotesAndCoreConfiguration
@@ -0,0 +1,16 @@
+# Excludes Obsidian workspace cache and plugins. All notes and core obsidian
+# configuration files are tracked by Git.
+
+# The current application UI state (DOM layout, recently-opened files, etc.) is
+# stored in these files (separate for desktop and mobile) so you can resume
+# your session seamlessly after a restart. If you want to track UI state, use
+# the Workspaces core plugin instead of relying on these files.
+.obsidian/workspace.json
+.obsidian/workspace-mobile.json
+
+# Obsidian plugins are stored under .obsidian/plugins/$plugin_name. They
+# contain metadata (manifest.json), application code (main.js), stylesheets
+# (styles.css), and user-configuration data (data.json).
+# We want to exclude all plugin-related files, so we can exclude everything
+# under this directory.
+.obsidian/plugins/**/*
diff --git a/options/gitignore/NotesAndExtendedConfiguration b/options/gitignore/NotesAndExtendedConfiguration
new file mode 100644
index 0000000000..3e0804f299
--- /dev/null
+++ b/options/gitignore/NotesAndExtendedConfiguration
@@ -0,0 +1,38 @@
+# Excludes Obsidian workspace cache and plugin code, but retains plugin
+# configuration. All notes and user-controlled configuration files are tracked
+# by Git.
+#
+# !!! WARNING !!!
+#
+# Community plugins may store sensitive secrets in their data.json files. By
+# including these files, those secrets may be tracked in your Git repository.
+#
+# To ignore configurations for specific plugins, add a line like this after the
+# contents of this file (order is important):
+# .obsidian/plugins/{{plugin_name}}/data.json
+#
+# Alternatively, ensure that you are treating your entire Git repository as
+# sensitive data, since it may contain secrets, or may have contained them in
+# past commits. Understand your threat profile, and make the decision
+# appropriate for yourself. If in doubt, err on the side of not including
+# plugin configuration. Use one of the alternative gitignore files instead:
+# * NotesOnly.gitignore
+# * NotesAndCoreConfiguration.gitignore
+
+# The current application UI state (DOM layout, recently-opened files, etc.) is
+# stored in these files (separate for desktop and mobile) so you can resume
+# your session seamlessly after a restart. If you want to track UI state, use
+# the Workspaces core plugin instead of relying on these files.
+.obsidian/workspace.json
+.obsidian/workspace-mobile.json
+
+# Obsidian plugins are stored under .obsidian/plugins/$plugin_name. They
+# contain metadata (manifest.json), application code (main.js), stylesheets
+# (styles.css), and user-configuration data (data.json).
+# We only want to track data.json, so we:
+# 1. exclude everything under the plugins directory recursively,
+# 2. unignore the plugin directories themselves, which then allows us to
+# 3. unignore the data.json files
+.obsidian/plugins/**/*
+!.obsidian/plugins/*/
+!.obsidian/plugins/*/data.json
diff --git a/options/gitignore/NotesOnly b/options/gitignore/NotesOnly
new file mode 100644
index 0000000000..2b3b76ee0e
--- /dev/null
+++ b/options/gitignore/NotesOnly
@@ -0,0 +1,4 @@
+# Excludes all Obsidian-related configuration. All notes are tracked by Git.
+
+# All Obsidian configuration and runtime state is stored here
+.obsidian/**/*
diff --git a/options/gitignore/ReScript b/options/gitignore/ReScript
new file mode 100644
index 0000000000..b7364c932a
--- /dev/null
+++ b/options/gitignore/ReScript
@@ -0,0 +1,3 @@
+/node_modules/
+/lib/
+.bsb.lock
diff --git a/options/gitignore/Terragrunt b/options/gitignore/Terragrunt
new file mode 100644
index 0000000000..ea4808637f
--- /dev/null
+++ b/options/gitignore/Terragrunt
@@ -0,0 +1,3 @@
+# Ignore the default terragrunt cache directory
+# https://terragrunt.gruntwork.io/docs/features/caching/
+.terragrunt-cache
diff --git a/options/gitignore/Zig b/options/gitignore/Zig
index 236ae6be8c..748837a058 100644
--- a/options/gitignore/Zig
+++ b/options/gitignore/Zig
@@ -1,4 +1,4 @@
-zig-cache/
+.zig-cache/
zig-out/
build/
build-*/
diff --git a/options/license/DocBook-Stylesheet b/options/license/DocBook-Stylesheet
new file mode 100644
index 0000000000..e986ed4235
--- /dev/null
+++ b/options/license/DocBook-Stylesheet
@@ -0,0 +1,13 @@
+Copyright 2005 Norman Walsh, Sun Microsystems,
+Inc., and the Organization for the Advancement
+of Structured Information Standards (OASIS).
+
+Release: $Id: db4-upgrade.xsl 8905 2010-09-12 11:47:07Z bobstayton $
+
+Permission to use, copy, modify and distribute this stylesheet
+and its accompanying documentation for any purpose and
+without fee is hereby granted in perpetuity, provided that
+the above copyright notice and this paragraph appear in
+all copies. The copyright holders make no representation
+about the suitability of the schema for any purpose. It
+is provided "as is" without expressed or implied warranty.
diff --git a/options/license/GPL-3.0-389-ds-base-exception b/options/license/GPL-3.0-389-ds-base-exception
new file mode 100644
index 0000000000..52be470c10
--- /dev/null
+++ b/options/license/GPL-3.0-389-ds-base-exception
@@ -0,0 +1,10 @@
+Additional permission under GPLv3 section 7:
+
+If you modify this Program, or any covered work, by
+linking or combining it with OpenSSL, or a modified
+version of OpenSSL licensed under the OpenSSL license
+(https://www.openssl.org/source/license.html), the licensors of this
+Program grant you additional permission to convey the resulting work.
+Corresponding Source for a non-source form of such a combination
+shall include the source code for the parts that are licensed
+under the OpenSSL license as well as that of the covered work.
diff --git a/options/license/MIT-Click b/options/license/MIT-Click
new file mode 100644
index 0000000000..82054edc39
--- /dev/null
+++ b/options/license/MIT-Click
@@ -0,0 +1,30 @@
+Portions of this software are subject to the license below. The relevant
+source files are clearly marked; they refer to this file using the phrase
+"the Click LICENSE file". This license is an MIT license, plus a clause
+(taken from the W3C license) requiring prior written permission to use our
+names in publicity.
+
+===========================================================================
+
+Permission is hereby granted, free of charge, to any person obtaining a
+copy of this software and associated documentation files (the "Software"),
+to deal in the Software without restriction, including without limitation
+the rights to use, copy, modify, merge, publish, distribute, sublicense,
+and/or sell copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+The name and trademarks of copyright holders may NOT be used in advertising
+or publicity pertaining to the Software without specific, written prior
+permission. Title to copyright in this Software and any associated
+documentation will at all times remain with copyright holders.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/options/license/TrustedQSL b/options/license/TrustedQSL
new file mode 100644
index 0000000000..982d4269f6
--- /dev/null
+++ b/options/license/TrustedQSL
@@ -0,0 +1,58 @@
+Copyright (C) 2001-2015 American Radio Relay League, Inc. All rights
+reserved.
+
+Portions (C) 2003-2023 The TrustedQSL Developers. Please see the AUTHORS.txt
+file for contributors.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Any redistribution of source code must retain the above copyright
+notice, this list of conditions and the disclaimer shown in
+Paragraph 5 (below).
+
+2. Redistribution in binary form must reproduce the above copyright
+notice, this list of conditions and the disclaimer shown in
+Paragraph 5 (below) in the documentation and/or other materials
+provided with the distribution.
+
+3. Products derived from or including this software may not use
+"Logbook of the World" or "LoTW" or any other American Radio Relay
+League, Incorporated trademarks or servicemarks in their names
+without prior written permission of the ARRL. See Paragraph 6
+(below) for contact information.
+
+4. Use of this software does not imply endorsement by ARRL of
+products derived from or including this software and vendors may not
+claim such endorsement.
+
+5. Disclaimer: This software is provided "as-is" without
+representation, guarantee or warranty of any kind, either express or
+implied, including but not limited to the implied warranties of
+merchantability or of fitness for a particular purpose. The entire
+risk as to the quality and performance of the software is solely
+with you. Should the software prove defective, you (and not the
+American Radio Relay League, its officers, directors, employees or
+agents) assume the entire cost of all necessary servicing, repair or
+correction. In no event will ARRL be liable to you or to any third
+party for any damages, whether direct or indirect, including lost
+profits, lost savings, or other incidental or consequential damages
+arising out of the use or inability to use such software, regardless
+of whether ARRL has been advised of the possibility of such damages.
+
+6. Contact information:
+
+American Radio Relay League, Inc.
+Attn: Logbook of the World Manager
+225 Main St
+Newington, CT 06111
+voice: 860-594-0200
+fax: 860-594-0259
+email: logbook@arrl.org
+Worldwide Web: www.arrl.org
+
+This software consists of voluntary contributions made by many
+individuals on behalf of the ARRL. More information on the "Logbook
+of The World" project and the ARRL is available from the ARRL Web
+site at www.arrl.org.
diff --git a/options/locale/locale_ar.ini b/options/locale/locale_ar.ini
index 7387bca2a4..b7b3a0c883 100644
--- a/options/locale/locale_ar.ini
+++ b/options/locale/locale_ar.ini
@@ -1,6 +1,3 @@
-
-
-
[common]
language = ูุบุฉ
passcode = ุฑู
ุฒ ุงูู
ุฑูุฑ
@@ -142,6 +139,11 @@ filter.not_fork = ููุณุช ุงุดุชูุงูุงุช
filter.not_archived = ููุณ ู
ุคุฑุดู
filter.public = ุนููู
filter.private = ุฎุงุต
+new_repo.title = ู
ุณุชูุฏุน ุฌุฏูุฏ
+new_migrate.title = ุงูุชูุงู ุฌุฏูุฏ
+new_org.title = ู
ูุธู
ุฉ ุฌุฏูุฏุฉ
+new_repo.link = ู
ุณุชูุฏุน ุฌุฏูุฏ
+new_migrate.link = ุงูุชูุงู ุฌุฏูุฏ
[install]
db_name = ุงุณู
ูุงุนุฏุฉ ุงูุจูุงูุงุช
@@ -668,7 +670,7 @@ issues.unlock.notice_1 = - ูุณุชุทูุน ุฃู ู
ุณุชุฎุฏู
ุนูุฏุฆุฐู ุฃู ูุน
issues.remove_assignee_at = `ุฃูุบู ุชููููู %s %s`
branch.warning_rename_default_branch = ุฅูู ุชุบููุฑ ุงุณู
ุงููุฑุน ุงูู
ุจุฏุฆู.
trust_model_helper_default = ุงูู
ุจุฏุฆู: ุงุฎุชุฑ ูู
ูุฐุฌ ุงูุซูุฉ ุงูู
ุจุฏุฆู ููุฐุง ุงูู
ููุน
-tag.create_tag = ุฃูุดุฆ ุงููุณู
%s
+tag.create_tag = ุฃูุดุฆ ุงููุณู
%s
release.title_empty = ูุง ูู
ูู ุชุฑู ุงูุนููุงู ูุงุฑุบุง.
tag.create_tag_operation = ุฃูุดุฆ ูุณู
ูุง
issues.remove_request_review = ุฃูุบ ุทูุจ ุงูู
ุฑุงุฌุนุฉ
@@ -774,7 +776,7 @@ issues.save = ุงุญูุธ
migrate_items_labels = ุชุตูููุงุช
issues.add_assignee_at = `ููููู %s ุจูุง %s`
milestones.filter_sort.least_complete = ุงูุฃูู ุงูุชู
ุงูุง
-branch.create_branch = ุฃูุดุฆ ุงููุฑุน %s
+branch.create_branch = ุฃูุดุฆ ุงููุฑุน %s
issues.remove_self_assignment = `ุฃูุบู ุชูููู ููุณู %s`
issues.label_edit = ุนุฏูู
release.download_count = ุงูุชูุฒููุงุช: %s
@@ -955,7 +957,7 @@ settings.recent_deliveries = ุงูุชูุตูู ุงูุฃุฎูุฑุฉ
projects.new = ู
ุดุฑูุน ุฌุฏูุฏ
file_history = ุชุงุฑูุฎ
editor.directory_is_a_file = ุงุณู
ุงูู
ุฌูุฏ "%s" ู
ุณุชุฎุฏู
ูุนูุง ูุงุณู
ู
ูู ูู ูุฐุง ุงูู
ุณุชูุฏุน.
-editor.commit_directly_to_this_branch = ุฃูุฏุน ู
ุจุงุดุฑุฉู ุฅูู ูุฑุน %s .
+editor.commit_directly_to_this_branch = ุฃูุฏุน ู
ุจุงุดุฑุฉู ุฅูู ูุฑุน %[1]s .
editor.unable_to_upload_files = ุชุนุฐุฑ ุฑูุน ุงูู
ููุงุช ุฅูู "%s" ุจุฑุณุงูุฉ ุงูุฎุทุฃ: %v
settings.webhook.payload = ุงูู
ุญุชูู
invisible_runes_header = `ูุญุชูู ูุฐุง ุงูู
ูู ุนูู ู
ุญุงุฑู ููููููุฏ ุบูุฑ ู
ุฑุฆูุฉ`
@@ -1015,7 +1017,7 @@ commit.revert-header = ุฅุฑุฌุงุน: %s
editor.file_already_exists = ููุฌุฏ ูุนูุง ูู ูุฐุง ุงูู
ุณุชูุฏุน ู
ูู ุจุงุณู
"%s".
settings.web_hook_name_matrix = ู
ุชุฑูุณ
editor.filename_cannot_be_empty = ูุง ูู
ูู ุชุฑู ุงุณู
ุงูู
ูู ูุงุฑุบุง.
-editor.add_tmpl = ุฃุถู ''
+editor.add_tmpl = ุฃุถู '<%s>'
editor.new_branch_name_desc = ุงุณู
ุงููุฑุน ุงูุฌุฏูุฏโฆ
release = ุฅุตุฏุงุฑ
editor.delete_this_file = ุงุญุฐู ุงูู
ูู
@@ -1100,7 +1102,7 @@ activity.git_stats_pushed_1 = ุฏูุน
activity.git_stats_pushed_n = ุฏูุนูุง
activity.git_stats_commit_1 = %d ุฅูุฏุงุน
activity.git_stats_commit_n = %d ุฅูุฏุงุนุง
-activity.git_stats_push_to_branch = ุฅูู %s ู
+activity.git_stats_push_to_branch = `ุฅูู %s ู"`
activity.git_stats_push_to_all_branches = ุฅูู ูู ุงููุฑูุน.
activity.git_stats_on_default_branch = ูู %sุ
activity.git_stats_file_1 = %d ู
ูู
@@ -1110,7 +1112,7 @@ activity.git_stats_files_changed_n = ุชุบููุฑูุง
activity.git_stats_additions = ูุญุฏุซุช
activity.git_stats_addition_1 = %d ุฅุถุงูุฉ
activity.git_stats_addition_n = %d ุฅุถุงูุฉ
-activity.git_stats_and_deletions = ู
+activity.git_stats_and_deletions = `ู"`
activity.git_stats_deletion_1 = %d ุฅุฒุงูุฉ
activity.git_stats_deletion_n = %d ุฅุฒุงูุฉ
settings.mirror_settings.direction = ุงูุงุชุฌุงู
@@ -1165,7 +1167,7 @@ pulls.status_checks_failure = ุจุนุถ ุงููุญูุต ูุดูุช
pulls.status_checks_success = ุฌู
ูุน ุงููุญูุต ูุงุฌุญุฉ
pulls.status_checks_warning = ุจุนุถ ุงููุญูุต ุชุนุทู ุชุญุฐูุฑุงุช
pulls.commit_ref_at = `ุฃุดุงุฑ ุฅูู ุทูุจ ุงูุฏู
ุฌ ู
ู ุฅูุฏุงุน %[2]s `
-pulls.cmd_instruction_hint = `ุฃุธูุฑ ุดุฑุญ ุงุณุชุฎุฏุงู
ุณุทุฑ ุงูุฃูุงู
ุฑ .`
+pulls.cmd_instruction_hint = `ุฃุธูุฑ ุดุฑุญ ุงุณุชุฎุฏุงู
ุณุทุฑ ุงูุฃูุงู
ุฑ.`
pulls.cmd_instruction_checkout_title = ุงุณุญุจ
pulls.cmd_instruction_checkout_desc = ู
ู ู
ุณุชูุฏุน ู
ุดุฑูุนูุ ุงุณุญุจ (check out) ูุฑุนุง ุฌุฏูุฏุง ูุงุฎุชุจุฑ ุงูุชุบููุฑุงุช.
pulls.cmd_instruction_merge_title = ุงุฏู
ุฌ
@@ -1386,7 +1388,7 @@ issue.action.review_dismissed = @%[1]s ุฃุณุชุจุนุฏ ุขุฎุฑ ู
ุฑุงุฌุนุฉ
[error]
not_found = ุชุนุฐุฑ ุงูุนุซูุฑ ุนูู ุงููุฏู.
-report_message = ุฅู ููุช ู
ุชููููููุง ุฃู ูุฐู ุนูุฉ ูู ููุฑุฌููุ ุฑุฌุงุกู ุงุจุญุซ ูู ููุฏุจูุฑุฌ ุฃู ุงูุชุญ ู
ุณุฃูู ุฌุฏูุฏุฉ ุฅุฐุง ูุฒู
ุงูุฃู
ุฑ.
+report_message = ุฅู ููุช ู
ุชููููููุง ุฃู ูุฐู ุนูุฉ ูู ููุฑุฌููุ ุฑุฌุงุกู ุงุจุญุซ ูู ููุฏุจูุฑุฌ ุฃู ุงูุชุญ ู
ุณุฃูู ุฌุฏูุฏุฉ ุฅุฐุง ูุฒู
ุงูุฃู
ุฑ.
network_error = ุฎุทุฃ ูู ุงูุดุจูุฉ
invalid_csrf = ุทูุจ ุณูุฆ: ุฑู
ุฒ CSRF ุบูุฑ ุตุงูุญ
occurred = ุญุฏุซ ุฎุทุฃ
@@ -1397,10 +1399,10 @@ server_internal = ุฎุทุฃ ุฏุงุฎูู ูู ุงูุฎุงุฏู
install = ุณููุฉ ุงูุชุซุจูุช
lightweight = ุฎููู
license = ู
ูุชูุญ ุงูู
ุตุฏุฑ
-platform_desc = ููุฑุฌูู ูุนู
ู ูู ุฃู ู
ูุงู ุฌู ูุนู
ู ุนูู ูููุฏูุฒุ ู
ุงูุ ููููุณุ ARMุ ุฅูุฎ. ุงุฎุชุฑ ู
ุง ุชุญุจ!
-install_desc = ุจุจุณุงุทุฉ ุดุบู ุงูู
ูู ุงูู
ูุงุฆู
ูู
ูุตุชูุ ุฃู ุฃุณุชุฎุฏู
ุฏููุฑ ุ ุงู ูุฒูู ูุญุฒู
ุฉ .
+platform_desc = ููุฑุฌูู ูุนู
ู ูู ุฃู ู
ูุงู ุฌู ูุนู
ู ุนูู ูููุฏูุฒุ ู
ุงูุ ููููุณุ ARMุ ุฅูุฎ. ุงุฎุชุฑ ู
ุง ุชุญุจ!
+install_desc = ุจุจุณุงุทุฉ ุดุบู ุงูู
ูู ุงูู
ูุงุฆู
ูู
ูุตุชูุ ุฃู ุฃุณุชุฎุฏู
ุฏููุฑ ุ ุงู ูุฒูู ูุญุฒู
ุฉ .
lightweight_desc = ููุฑุฌูู ูุฏูู ู
ุชุทูุจุงุช ู
ูุฎูุถุฉ ููู
ูู ุฃู ูุนู
ู ุนูู ุฃุฌูุฒุฉ Raspberry Pi ุงูุบูุฑ ู
ูููุฉ. ุงุญูุธ ู
ูุงุฑุฏ ุฌูุงุฒู!
-license_desc = ุงุญุตู ุนูู ููุฑุฌูู ! ุฅูุถู
ููุง ุนู ุทุฑูู ุงูู
ุณุงูู
ุฉ ูุชุญุณูู ุงูู
ุดุฑูุน. ูุง ุชูู ุฎุฌููุงู ููู
ุณุงูู
ุฉ!
+license_desc = ุงุญุตู ุนูู ููุฑุฌูู ! ุฅูุถู
ููุง ุนู ุทุฑูู ุงูู
ุณุงูู
ุฉ ูุชุญุณูู ุงูู
ุดุฑูุน. ูุง ุชูู ุฎุฌููุงู ููู
ุณุงูู
ุฉ!
app_desc = ุฎุฏู
ุฉ ุฌูุช ุบูุฑ ู
ุคูู
ุฉ ู
ุณุชุถุงูุฉ ุฐุงุชูุงู
platform = ู
ุชุนุฏุฏ ุงูู
ูุตุงุช
@@ -1499,7 +1501,7 @@ prohibit_login = ุชุณุฌูู ุงูุฏุฎูู ู
ู
ููุน
prohibit_login_desc = ุญุณุงุจู ู
ู
ููุน ู
ู ุชุณุฌูู ุงูุฏุฎููุ ูุฑุฌู ุงูุชูุงุตู ู
ุน ู
ุฏูุฑ ุงูู
ููุน.
disable_forgot_password_mail_admin = ุงุณุชุฑุฏุงุฏ ุงูุญุณุงุจ ู
ุชุงุญ ููุท ุนูุฏ ุฅุนุฏุงุฏ ุงูุจุฑูุฏ ุงูุฅููุชุฑููู. ููุฑุฌู ุฅุนุฏุงุฏ ุงูุจุฑูุฏ ุงูุฅููุชุฑููู ูุชูุนูู ุงุณุชุฑุฏุงุฏ ุงูุญุณุงุจ.
password_pwned_err = ุชุนุฐุฑ ุงููุตูู ุฅูู HaveIBeenPwned
-password_pwned = ุงูููู
ุฉ ุงูู
ุฑูุฑ ุงูู
ูุฎุชุงุฑุฉ ูู ุนูู ูุงุฆู
ุฉ ููู
ุงุช ู
ุฑูุฑ ู
ุณุฑููุฉ ุชู
ูุดููุง ูู ุชุณุฑูุจุงุช ุนุงู
ุฉ ููุจูุงูุงุช. ููุฑุฌู ุงูู
ุญุงููุฉ ู
ุฑุฉ ุฃุฎุฑู ุจููู
ุฉ ู
ุฑูุฑ ุฃุฎุฑูุ ูุถุน ูู ุงุนุชุจุงุฑู ุชุบููุฑ ุชูู ุงูููู
ุฉ ูู ุงูุฃู
ุงูู ุงูุฃุฎุฑู.
+password_pwned = ุงูููู
ุฉ ุงูู
ุฑูุฑ ุงูู
ูุฎุชุงุฑุฉ ูู ุนูู ูุงุฆู
ุฉ ููู
ุงุช ู
ุฑูุฑ ู
ุณุฑููุฉ ุชู
ูุดููุง ูู ุชุณุฑูุจุงุช ุนุงู
ุฉ ููุจูุงูุงุช. ููุฑุฌู ุงูู
ุญุงููุฉ ู
ุฑุฉ ุฃุฎุฑู ุจููู
ุฉ ู
ุฑูุฑ ุฃุฎุฑูุ ูุถุน ูู ุงุนุชุจุงุฑู ุชุบููุฑ ุชูู ุงูููู
ุฉ ูู ุงูุฃู
ุงูู ุงูุฃุฎุฑู.
authorization_failed = ูุดู ุงูุฅุฐู
authorize_redirect_notice = ุณุชุชู
ุฅุนุงุฏุฉ ุชูุฌููู ุฅูู %s ุฅุฐุง ุฃุฐูุช ููุชุทุจูู.
authorize_application = ุงุฆุฐู ููุชุทุจูู
@@ -1982,4 +1984,10 @@ match_tooltip = ูู
ุจุชุถู
ูู ุงููุชุงุฆุฌ ุงูุชู ุชุทุงุจู ู
ุตุทูุญ
repo_kind = ุจุญุซ ูู ุงูู
ุณุชูุฏุนุงุช...
user_kind = ุจุญุซ ุนู ุงูู
ุณุชุฎุฏู
ูู...
team_kind = ุจุญุซ ุนู ุงููุฑู ...
-code_kind = ุจุญุซ ูู ุงูููุฏ...
\ No newline at end of file
+code_kind = ุจุญุซ ูู ุงูููุฏ...
+project_kind = ุงูุจุญุซ ุถู
ู ุงูู
ุดุงุฑูุน...
+branch_kind = ุงูุจุญุซ ุถู
ู ุงููุฑูุน...
+no_results = ูุง ุชูุฌุฏ ูุชุงุฆุฌ ู
ุทุงุจูุฉ.
+issue_kind = ุงูุจุญุซ ุถู
ู ุงูุฃุนุทุงู...
+pull_kind = ุงูุจุญุซ ุถู
ู ุทูุจุงุช ุงูุณุญุจ...
+keyword_search_unavailable = ุงูุจุญุซ ู
ู ุฎูุงู ุงูููู
ุงุช ุงูู
ูุชุงุญูุฉ ููุณ ู
ุชููุฑ ุญุงููุงู. ุฑุฌุงุกุงู ุชูุงุตู ู
ุน ู
ุดุฑู ุงูู
ููุน.
diff --git a/options/locale/locale_be.ini b/options/locale/locale_be.ini
index f9d8e738c3..fe04dadc3e 100644
--- a/options/locale/locale_be.ini
+++ b/options/locale/locale_be.ini
@@ -1,6 +1,3 @@
-
-
-
[common]
dashboard = ะะฐะฝัะปั ะบััะฐะฒะฐะฝะฝั
explore = ะะณะปัะด
diff --git a/options/locale/locale_bg.ini b/options/locale/locale_bg.ini
index 4e03808c38..6fc4b55eae 100644
--- a/options/locale/locale_bg.ini
+++ b/options/locale/locale_bg.ini
@@ -1,188 +1,3 @@
-
-
-
-[settings]
-ui = ะขะตะผะฐ
-delete_key = ะัะตะผะฐั
ะฒะฐะฝะต
-applications = ะัะธะปะพะถะตะฝะธั
-visibility = ะะธะดะธะผะพัั ะฝะฐ ะฟะพััะตะฑะธัะตะปั
-location = ะะตััะพะฟะพะปะพะถะตะฝะธะต
-password = ะะฐัะพะปะฐ
-appearance = ะะฑะปะธะบ
-new_password = ะะพะฒะฐ ะฟะฐัะพะปะฐ
-oauth2_application_edit = ะ ะตะดะฐะบัะธัะฐะฝะต
-repos = ะฅัะฐะฝะธะปะธัะฐ
-can_write_info = ะะธัะฐะฝะต
-delete = ะะทััะธะฒะฐะฝะต ะฝะฐ ะฐะบะฐัะฝัะฐ
-social = ะกะพัะธะฐะปะฝะธ ะฐะบะฐัะฝัะธ
-twofa = ะะฒััะฐะบัะพัะฝะพ ัะดะพััะพะฒะตััะฒะฐะฝะต (TOTP)
-update_theme = ะัะพะผัะฝะฐ ะฝะฐ ัะตะผะฐัะฐ
-can_read_info = ะงะตัะตะฝะต
-access_token_deletion_confirm_action = ะะทััะธะฒะฐะฝะต
-website = ะฃะตะฑัะฐะนั
-cancel = ะัะบะฐะท
-delete_token = ะะทััะธะฒะฐะฝะต
-uid = UID
-language = ะะทะธะบ
-save_application = ะะฐะฟะฐะทะฒะฐะฝะต
-privacy = ะะพะฒะตัะธัะตะปะฝะพัั
-avatar = ะัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ
-add_key = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะบะปัั
-account_link = ะกะฒััะทะฐะฝะธ ะฐะบะฐัะฝัะธ
-delete_email = ะัะตะผะฐั
ะฒะฐะฝะต
-update_language = ะัะพะผัะฝะฐ ะฝะฐ ะตะทะธะบะฐ
-organization = ะัะณะฐะฝะธะทะฐัะธะธ
-link_account = ะกะฒััะทะฒะฐะฝะต ะฝะฐ ะฐะบะฐัะฝั
-add_new_gpg_key = ะะพะฑะฐะฒัะฝะต ะฝะฐ GPG ะบะปัั
-manage_gpg_keys = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ GPG ะบะปััะพะฒะตัะต
-manage_ssh_keys = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ SSH ะบะปััะพะฒะตัะต
-old_password = ะขะตะบััะฐ ะฟะฐัะพะปะฐ
-public_profile = ะัะฑะปะธัะตะฝ ะฟัะพัะธะป
-full_name = ะัะปะฝะพ ะธะผะต
-security = ะกะธะณััะฝะพัั
-add_new_key = ะะพะฑะฐะฒัะฝะต ะฝะฐ SSH ะบะปัั
-account = ะะบะฐัะฝั
-update_avatar = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะฟัะพัะธะปะฝะฐัะฐ ัะฝะธะผะบะฐ
-ssh_gpg_keys = SSH / GPG ะบะปััะพะฒะต
-comment_type_group_milestone = ะัะฐะฟ
-manage_emails = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ ะฐะดัะตัะธัะต ะฝะฐ ะตะป. ะฟะพัะฐ
-permission_read = ะงะตัะตะฝะต
-update_password = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะฟะฐัะพะปะฐัะฐ
-biography_placeholder = ะ ะฐะทะบะฐะถะตัะต ะฝะธ ะผะฐะปะบะพ ะทะฐ ัะตะฑะต ัะธ! (ะะพะถะตัะต ะดะฐ ะธะทะฟะพะปะทะฒะฐัะต Markdown)
-orgs = ะัะณะฐะฝะธะทะฐัะธะธ
-continue = ะัะพะดัะปะถะฐะฒะฐะฝะต
-blocked_users = ะะปะพะบะธัะฐะฝะธ ะฟะพััะตะฑะธัะตะปะธ
-emails = ะะดัะตัะธ ะฝะฐ ะตะป. ะฟะพัะฐ
-update_profile = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะฟัะพัะธะปะฐ
-profile = ะัะพัะธะป
-change_password = ะัะพะผัะฝะฐ ะฝะฐ ะฟะฐัะพะปะฐัะฐ
-retype_new_password = ะะพัะฒััะดะตัะต ะฝะพะฒะฐัะฐ ะฟะฐัะพะปะฐ
-choose_new_avatar = ะะทะฑะตัะตัะต ะฝะพะฒะฐ ะฟัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ
-delete_current_avatar = ะะทััะธะฒะฐะฝะต ะฝะฐ ัะตะบััะฐัะฐ ะฟัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ
-gpg_key_deletion_success = GPG ะบะปัััั ะต ะฟัะตะผะฐั
ะฝะฐั.
-permission_no_access = ะะตะท ะดะพัััะฟ
-ssh_key_deletion_success = SSH ะบะปัััั ะต ะฟัะตะผะฐั
ะฝะฐั.
-comment_type_group_project = ะัะพะตะบั
-update_language_success = ะะทะธะบัั ะต ะพะฑะฝะพะฒะตะฝ.
-add_key_success = SSH ะบะปัััั "%s" ะต ะดะพะฑะฐะฒะตะฝ.
-add_gpg_key_success = GPG ะบะปัััั "%s" ะต ะดะพะฑะฐะฒะตะฝ.
-user_unblock_success = ะะพััะตะฑะธัะตะปัั ะต ะพัะฑะปะพะบะธัะฐะฝ ััะฟะตัะฝะพ.
-user_block_success = ะะพััะตะฑะธัะตะปัั ะต ะฑะปะพะบะธัะฐะฝ ััะฟะตัะฝะพ.
-update_profile_success = ะัะพัะธะปัั ะฒะธ ะต ะพะฑะฝะพะฒะตะฝ.
-update_user_avatar_success = ะัะพัะธะปะฝะฐัะฐ ัะฝะธะผะบะฐ ะฝะฐ ะฟะพััะตะฑะธัะตะปั ะต ะพะฑะฝะพะฒะตะฝะฐ.
-remove_oauth2_application_success = ะัะธะปะพะถะตะฝะธะตัะพ ะต ะธะทััะธัะพ.
-email_deletion_success = ะะดัะตััั ะฝะฐ ะตะป. ะฟะพัะฐ ะต ะฟัะตะผะฐั
ะฝะฐั.
-update_avatar_success = ะัะพัะธะปะฝะฐัะฐ ะฒะธ ัะฝะธะผะบะฐ ะต ะพะฑะฝะพะฒะตะฝะฐ.
-change_username = ะะพััะตะฑะธัะตะปัะบะพัะพ ะฒะธ ะธะผะต ะต ะฟัะพะผะตะฝะตะฝะพ.
-comment_type_group_assignee = ะะทะฟัะปะฝะธัะตะป
-enable_custom_avatar = ะะทะฟะพะปะทะฒะฐะฝะต ะฝะฐ ะฟะตััะพะฝะฐะปะธะทะธัะฐะฝะฐ ะฟัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ
-requires_activation = ะะทะธัะบะฒะฐ ะฐะบัะธะฒะธัะฐะฝะต
-activated = ะะบัะธะฒะธัะฐะฝ
-primary = ะัะฝะพะฒะตะฝ
-email_deletion = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ ะฐะดัะตัะฐ ะฝะฐ ะตะป. ะฟะพัะฐ
-add_new_email = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะฝะพะฒ ะฐะดัะตั ะฝะฐ ะตะป. ะฟะพัะฐ
-add_email = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะฐะดัะตั ะฝะฐ ะตะป. ะฟะพัะฐ
-key_content_gpg_placeholder = ะะฐะฟะพัะฒะฐ ั "-----BEGIN PGP PUBLIC KEY BLOCK-----"
-comment_type_group_title = ะะฐะณะปะฐะฒะธะต
-comment_type_group_label = ะัะธะบะตั
-change_username_prompt = ะะฐะฑะตะปะตะถะบะฐ: ะัะพะผัะฝะฐัะฐ ะฝะฐ ะฟะพััะตะฑะธัะตะปัะบะพัะพ ะฒะธ ะธะผะต ะฟัะพะผะตะฝั ัััะพ URL ะฝะฐ ะฒะฐัะธั ะฐะบะฐัะฝั.
-update_language_not_found = ะะทะธะบัั "%s" ะฝะต ะต ะฝะฐะปะธัะตะฝ.
-keep_activity_private_popup = ะะฐัะฐัะฐ ะดะตะนะฝะพัั ัะต ะฑัะดะต ะฒะธะดะธะผะฐ ัะฐะผะพ ะทะฐ ะฒะฐั ะธ ะฐะดะผะธะฝะธัััะฐัะพัะธัะต ะฝะฐ ัะฐะนัะฐ
-uploaded_avatar_not_a_image = ะะฐัะตะฝะธัั ัะฐะนะป ะฝะต ะต ะธะทะพะฑัะฐะถะตะฝะธะต.
-uploaded_avatar_is_too_big = ะ ะฐะทะผะตััั ะฝะฐ ะบะฐัะตะฝะธั ัะฐะนะป (%d KiB) ะฝะฐะดะฒะธัะฐะฒะฐ ะผะฐะบัะธะผะฐะปะฝะธั ัะฐะทะผะตั (%d KiB).
-change_password_success = ะะฐัะพะปะฐัะฐ ะฒะธ ะต ะพะฑะฝะพะฒะตะฝะฐ. ะะปะธะทะฐะนัะต ั ะฝะพะฒะฐัะฐ ัะธ ะฟะฐัะพะปะฐ ะพั ัะตะณะฐ ะฝะฐัะฐััะบ.
-manage_themes = ะขะตะผะฐ ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต
-manage_openid = OpenID ะฐะดัะตัะธ
-primary_email = ะะฐ ะต ะพัะฝะพะฒะตะฝ
-keep_email_private = ะกะบัะธะฒะฐะฝะต ะฝะฐ ะฐะดัะตัะฐ ะฝะฐ ะตะป. ะฟะพัะฐ
-theme_update_error = ะะทะฑัะฐะฝะฐัะฐ ัะตะผะฐ ะฝะต ัััะตััะฒัะฒะฐ.
-theme_update_success = ะขะตะผะฐัะฐ ะฒะธ ะต ะพะฑะฝะพะฒะตะฝะฐ.
-key_content_ssh_placeholder = ะะฐะฟะพัะฒะฐ ั "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", ะธะปะธ "sk-ssh-ed25519@openssh.com"
-hide_openid = ะกะบัะธะฒะฐะฝะต ะพั ะฟัะพัะธะปะฐ
-key_content = ะกัะดััะถะฐะฝะธะต
-ssh_key_deletion = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ SSH ะบะปัั
-gpg_key_deletion = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ GPG ะบะปัั
-key_name = ะะผะต ะฝะฐ ะบะปััะฐ
-key_id = ID ะฝะฐ ะบะปััะฐ
-show_openid = ะะพะบะฐะทะฒะฐะฝะต ะฒ ะฟัะพัะธะปะฐ
-visibility.public = ะัะฑะปะธัะฝะฐ
-visibility.limited = ะะณัะฐะฝะธัะตะฝะฐ
-visibility.private = ะงะฐััะฝะฐ
-location_placeholder = ะกะฟะพะดะตะปะตัะต ะฟัะธะฑะปะธะทะธัะตะปะฝะพัะพ ัะธ ะผะตััะพะฟะพะปะพะถะตะฝะธะต ั ะดััะณะธัะต
-key_signature_gpg_placeholder = ะะฐะฟะพัะฒะฐ ั "-----BEGIN PGP SIGNATURE-----"
-key_signature_ssh_placeholder = ะะฐะฟะพัะฒะฐ ั "-----BEGIN SSH SIGNATURE-----"
-saved_successfully = ะะฐัััะพะนะบะธัะต ะฑัั
ะฐ ะทะฐะฟะฐะทะตะฝะธ ััะฟะตัะฝะพ.
-no_activity = ะัะผะฐ ัะบะพัะพัะฝะฐ ะดะตะนะฝะพัั
-theme_desc = ะขะพะฒะฐ ัะต ะฑัะดะต ะฒะฐัะฐัะฐ ัะตะผะฐ ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต ะฒ ัะตะปะธั ัะฐะนั.
-keep_activity_private = ะกะบัะธะฒะฐะฝะต ะฝะฐ ะดะตะนะฝะพัััะฐ ะพั ะฟัะพัะธะปะฝะฐัะฐ ัััะฐะฝะธัะฐ
-lookup_avatar_by_mail = ะขัััะตะฝะต ะฝะฐ ะฟัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ ะฟะพ ะฐะดัะตัะฐ ะฝะฐ ะตะป. ะฟะพัะฐ
-password_incorrect = ะขะตะบััะฐัะฐ ะฟะฐัะพะปะฐ ะต ะฝะตะฟัะฐะฒะธะปะฝะฐ.
-change_username_redirect_prompt = ะกัะฐัะพัะพ ะฟะพััะตะฑะธัะตะปัะบะพ ะธะผะต ัะต ัะต ะฟัะตะฝะฐัะพัะฒะฐ, ะดะพะบะฐัะพ ะฝัะบะพะน ะฝะต ะณะพ ะฒะทะตะผะต.
-principal_content = ะกัะดััะถะฐะฝะธะต
-manage_ssh_principals = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ SSH Certificate Principals
-twofa_disabled = ะะฒััะฐะบัะพัะฝะพัะพ ัะดะพััะพะฒะตััะฒะฐะฝะต ะต ะธะทะบะปััะตะฝะพ.
-orgs_none = ะะต ััะต ััะฐััะฝะธะบ ะฒ ะฝะธะบะฐะบะฒะธ ะพัะณะฐะฝะธะทะฐัะธะธ.
-repos_none = ะะต ะฟัะธัะตะถะฐะฒะฐัะต ะฝะธะบะฐะบะฒะธ ั
ัะฐะฝะธะปะธัะฐ.
-blocked_users_none = ะัะผะฐ ะฑะปะพะบะธัะฐะฝะธ ะฟะพััะตะฑะธัะตะปะธ.
-profile_desc = ะะพะฝััะพะปะธัะฐะนัะต ะบะฐะบ ะฒะฐัะธัั ะฟัะพัะธะป ัะต ะฟะพะบะฐะทะฒะฐ ะฝะฐ ะดััะณะธัะต ะฟะพััะตะฑะธัะตะปะธ. ะะฐัะธัั ะพัะฝะพะฒะตะฝ ะฐะดัะตั ะฝะฐ ะตะป. ะฟะพัะฐ ัะต ัะต ะธะทะฟะพะปะทะฒะฐ ะทะฐ ะธะทะฒะตััะธั, ะฒัะทััะฐะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะฟะฐัะพะปะฐัะฐ ะธ ัะตะฑ ะฑะฐะทะธัะฐะฝะธ Git ะพะฟะตัะฐัะธะธ.
-permission_write = ะงะตัะตะฝะต ะธ ะฟะธัะฐะฝะต
-twofa_disable = ะะทะบะปััะฒะฐะฝะต ะฝะฐ ะดะฒััะฐะบัะพัะฝะพัะพ ัะดะพััะพะฒะตััะฒะฐะฝะต
-twofa_enroll = ะะบะปััะฒะฐะฝะต ะฝะฐ ะดะฒััะฐะบัะพัะฝะพ ัะดะพััะพะฒะตััะฒะฐะฝะต
-ssh_key_name_used = ะะตัะต ัััะตััะฒัะฒะฐ SSH ะบะปัั ััั ัััะพัะพ ะธะผะต ะฒัะฒ ะฒะฐัะธั ะฐะบะฐัะฝั.
-email_notifications.enable = ะะบะปััะฒะฐะฝะต ะฝะฐ ะธะทะฒะตััะธััะฐ ะฟะพ ะตะป. ะฟะพัะฐ
-delete_prompt = ะขะฐะทะธ ะพะฟะตัะฐัะธั ัะต ะธะทััะธะต ะฟะตัะผะฐะฝะตะฝัะฝะพ ะฟะพััะตะฑะธัะตะปัะบะธั ะฒะธ ะฐะบะฐัะฝั. ะขะพะฒะฐ ะะ ะะะะ ะดะฐ ะฑัะดะต ะพัะผะตะฝะตะฝะพ.
-email_notifications.disable = ะะทะบะปััะฒะฐะฝะต ะฝะฐ ะธะทะฒะตััะธััะฐ ะฟะพ ะตะป. ะฟะพัะฐ
-delete_account = ะะทััะธะฒะฐะฝะต ะฝะฐ ะฐะบะฐัะฝัะฐ ะฒะธ
-confirm_delete_account = ะะพัะฒััะถะดะฐะฒะฐะฝะต ะฝะฐ ะธะทััะธะฒะฐะฝะตัะพ
-email_notifications.onmention = ะะป. ะฟะพัะฐ ัะฐะผะพ ะฟัะธ ัะฟะพะผะตะฝะฐะฒะฐะฝะต
-pronouns_unspecified = ะะตะฟะพัะพัะตะฝะธ
-pronouns = ะะตััะพะธะผะตะฝะธั
-gpg_token_code = echo "%s" | gpg -a --default-key %s --detach-sig
-language.title = ะะทะธะบ ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต
-
-[packages]
-container.labels.value = ะกัะพะนะฝะพัั
-alpine.repository.repositories = ะฅัะฐะฝะธะปะธัะฐ
-dependency.version = ะะตััะธั
-title = ะะฐะบะตัะธ
-empty = ะัะต ะพัะต ะฝัะผะฐ ะฟะฐะบะตัะธ.
-empty.documentation = ะะฐ ะฟะพะฒะตัะต ะธะฝัะพัะผะฐัะธั ะพัะฝะพัะฝะพ ัะตะณะธััััะฐ ะฝะฐ ะฟะฐะบะตัะธัะต ะฒะธะถัะต ะดะพะบัะผะตะฝัะฐัะธััะฐ .
-container.labels.key = ะะปัั
-requirements = ะะทะธัะบะฒะฐะฝะธั
-details = ะะพะดัะพะฑะฝะพััะธ
-details.license = ะะธัะตะฝะท
-container.labels = ะัะธะบะตัะธ
-versions = ะะตััะธะธ
-empty.repo = ะะฐัะธั
ัะต ะปะธ ะฟะฐะบะตั, ะฝะพ ัะพะน ะฝะต ัะต ะฟะพะบะฐะทะฒะฐ ััะบ? ะัะธะดะตัะต ะฒ ะฝะฐัััะพะนะบะธัะต ะทะฐ ะฟะฐะบะตัะธ ะธ ะณะพ ัะฒััะถะตัะต ะบัะผ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
-keywords = ะะปััะพะฒะธ ะดัะผะธ
-details.author = ะะฒัะพั
-about = ะัะฝะพัะฝะพ ัะพะทะธ ะฟะฐะบะตั
-settings.delete.success = ะะฐะบะตััั ะต ะธะทััะธั.
-settings.delete = ะะทััะธะฒะฐะฝะต ะฝะฐ ะฟะฐะบะตัะฐ
-container.details.platform = ะะปะฐััะพัะผะฐ
-settings.delete.error = ะะตััะฟะตัะฝะพ ะธะทััะธะฒะฐะฝะต ะฝะฐ ะฟะฐะบะตั.
-installation = ะะฝััะฐะปะฐัะธั
-
-[tool]
-hours = %d ัะฐัะฐ
-now = ัะตะณะฐ
-raw_seconds = ัะตะบัะฝะดะธ
-1m = 1 ะผะธะฝััะฐ
-1s = 1 ัะตะบัะฝะดะฐ
-months = %d ะผะตัะตัะฐ
-weeks = %d ัะตะดะผะธัะธ
-1w = 1 ัะตะดะผะธัะฐ
-years = %d ะณะพะดะธะฝะธ
-seconds = %d ัะตะบัะฝะดะธ
-days = %d ะดะฝะธ
-1d = 1 ะดะตะฝ
-minutes = %d ะผะธะฝััะธ
-1mon = 1 ะผะตัะตั
-1h = 1 ัะฐั
-1y = 1 ะณะพะดะธะฝะฐ
-future = ะฑัะดะตัะต
-raw_minutes = ะผะธะฝััะธ
-
[common]
language = ะะทะธะบ
cancel = ะัะบะฐะท
@@ -193,7 +8,7 @@ disabled = ะะทะบะปััะตะฝะพ
licenses = ะะธัะตะฝะทะธ
sign_in = ะั
ะพะด
copy_content = ะะพะฟะธัะฐะฝะต ะฝะฐ ััะดััะถะฐะฝะธะตัะพ
-user_profile_and_more = ะัะพัะธะป ะธ ะะฐัััะพะนะบะธโฆ
+user_profile_and_more = ะัะพัะธะป ะธ ะฝะฐัััะพะนะบะธโฆ
view = ะัะตะณะปะตะด
your_settings = ะะฐัััะพะนะบะธ
mirrors = ะะณะปะตะดะฐะปะฐ
@@ -227,7 +42,7 @@ copy = ะะพะฟะธัะฐะฝะต
enabled = ะะบะปััะตะฝะพ
new_org = ะะพะฒะฐ ะพัะณะฐะฝะธะทะฐัะธั
milestones = ะัะฐะฟะธ
-rss_feed = RSS ะะผะธัะธั
+rss_feed = RSS ะตะผะธัะธั
never = ะะธะบะพะณะฐ
new_project = ะะพะฒ ะฟัะพะตะบั
your_starred = ะัะฑะตะปัะทะฐะฝะธ
@@ -283,6 +98,215 @@ filter.not_mirror = ะะต ะพะณะปะตะดะฐะปะฐ
copy_hash = ะะพะฟะธัะฐะฝะต ะฝะฐ ะบะพะฝััะพะปะฝะฐัะฐ ััะผะฐ
artifacts = ะััะตัะฐะบัะธ
show_log_seconds = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ัะตะบัะฝะดะธัะต
+remove_all = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ ะฒัะธัะบะพ
+test = ะัะพะฑะฐ
+remove_label_str = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ ะตะปะตะผะตะฝัะฐ โ%sโ
+copy_branch = ะะพะฟะธัะฐะฝะต ะฝะฐ ะธะผะตัะพ ะฝะฐ ะบะปะพะฝะฐ
+error404 = ะกััะฐะฝะธัะฐัะฐ, ะบะพััะพ ัะต ะพะฟะธัะฒะฐัะต ะดะฐ ะพัะฒะพัะธัะต, ะธะปะธ ะฝะต ัััะตััะฒัะฒะฐ ะธะปะธ ะฝะต ััะต ัะฟัะปะฝะพะผะพัะตะฝะธ ะดะฐ ั ะฒะธะดะธัะต.
+new_repo.link = ะะพะฒะพ ั
ัะฐะฝะธะปะธัะต
+new_migrate.title = ะะพะฒะฐ ะผะธะณัะฐัะธั
+new_repo.title = ะะพะฒะพ ั
ัะฐะฝะธะปะธัะต
+new_org.title = ะะพะฒะฐ ะพัะณะฐะฝะธะทะฐัะธั
+new_migrate.link = ะะพะฒะฐ ะผะธะณัะฐัะธั
+new_org.link = ะะพะฒะฐ ะพัะณะฐะฝะธะทะฐัะธั
+copy_generic = ะะพะฟะธัะฐะฝะต ะฒ ะบะปะธะฟะฑะพัะดะฐ
+copy_error = ะะตััะฟะตัะฝะพ ะบะพะฟะธัะฐะฝะต
+copy_path = ะะพะฟะธัะฐะฝะต ะฝะฐ ะฟััั
+
+[settings]
+ui = ะขะตะผะฐ
+delete_key = ะัะตะผะฐั
ะฒะฐะฝะต
+applications = ะัะธะปะพะถะตะฝะธั
+visibility = ะะธะดะธะผะพัั ะฝะฐ ะฟะพััะตะฑะธัะตะปั
+location = ะะตััะพะฟะพะปะพะถะตะฝะธะต
+password = ะะฐัะพะปะฐ
+appearance = ะะฑะปะธะบ
+new_password = ะะพะฒะฐ ะฟะฐัะพะปะฐ
+oauth2_application_edit = ะ ะตะดะฐะบัะธัะฐะฝะต
+repos = ะฅัะฐะฝะธะปะธัะฐ
+can_write_info = ะะธัะฐะฝะต
+delete = ะะทััะธะฒะฐะฝะต ะฝะฐ ะฐะบะฐัะฝัะฐ
+social = ะกะพัะธะฐะปะฝะธ ะฐะบะฐัะฝัะธ
+twofa = ะะฒััะฐะบัะพัะฝะพ ัะดะพััะพะฒะตััะฒะฐะฝะต (TOTP)
+update_theme = ะัะพะผัะฝะฐ ะฝะฐ ัะตะผะฐัะฐ
+can_read_info = ะงะตัะตะฝะต
+access_token_deletion_confirm_action = ะะทััะธะฒะฐะฝะต
+website = ะฃะตะฑัะฐะนั
+cancel = ะัะบะฐะท
+delete_token = ะะทััะธะฒะฐะฝะต
+uid = UID
+language = ะะทะธะบ
+save_application = ะะฐะฟะฐะทะฒะฐะฝะต
+privacy = ะะพะฒะตัะธัะตะปะฝะพัั
+avatar = ะัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ
+add_key = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะบะปัั
+account_link = ะกะฒััะทะฐะฝะธ ะฐะบะฐัะฝัะธ
+delete_email = ะัะตะผะฐั
ะฒะฐะฝะต
+update_language = ะัะพะผัะฝะฐ ะฝะฐ ะตะทะธะบะฐ
+organization = ะัะณะฐะฝะธะทะฐัะธะธ
+link_account = ะกะฒััะทะฒะฐะฝะต ะฝะฐ ะฐะบะฐัะฝั
+add_new_gpg_key = ะะพะฑะฐะฒัะฝะต ะฝะฐ GPG ะบะปัั
+manage_gpg_keys = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ GPG ะบะปััะพะฒะตัะต
+manage_ssh_keys = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ SSH ะบะปััะพะฒะตัะต
+old_password = ะขะตะบััะฐ ะฟะฐัะพะปะฐ
+public_profile = ะัะฑะปะธัะตะฝ ะฟัะพัะธะป
+full_name = ะัะปะฝะพ ะธะผะต
+security = ะกะธะณััะฝะพัั
+add_new_key = ะะพะฑะฐะฒัะฝะต ะฝะฐ SSH ะบะปัั
+account = ะะบะฐัะฝั
+update_avatar = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะฟัะพัะธะปะฝะฐัะฐ ัะฝะธะผะบะฐ
+ssh_gpg_keys = SSH / GPG ะบะปััะพะฒะต
+comment_type_group_milestone = ะัะฐะฟ
+manage_emails = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ ะฐะดัะตัะธัะต ะฝะฐ ะตะป. ะฟะพัะฐ
+permission_read = ะงะตัะตะฝะต
+update_password = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะฟะฐัะพะปะฐัะฐ
+biography_placeholder = ะ ะฐะทะบะฐะถะตัะต ะฝะฐ ะดััะณะธัะต ะผะฐะปะบะพ ะทะฐ ัะตะฑะต ัะธ! (ะะพะถะตัะต ะดะฐ ะธะทะฟะพะปะทะฒะฐัะต ะะฐัะบะดะฐัะฝ)
+orgs = ะัะณะฐะฝะธะทะฐัะธะธ
+continue = ะัะพะดัะปะถะฐะฒะฐะฝะต
+blocked_users = ะะปะพะบะธัะฐะฝะธ ะฟะพััะตะฑะธัะตะปะธ
+emails = ะะดัะตัะธ ะฝะฐ ะตะป. ะฟะพัะฐ
+update_profile = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะฟัะพัะธะปะฐ
+profile = ะัะพัะธะป
+change_password = ะัะพะผัะฝะฐ ะฝะฐ ะฟะฐัะพะปะฐัะฐ
+retype_new_password = ะะพัะฒััะดะตัะต ะฝะพะฒะฐัะฐ ะฟะฐัะพะปะฐ
+choose_new_avatar = ะะทะฑะตัะตัะต ะฝะพะฒะฐ ะฟัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ
+delete_current_avatar = ะะทััะธะฒะฐะฝะต ะฝะฐ ัะตะบััะฐัะฐ ะฟัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ
+gpg_key_deletion_success = GPG ะบะปัััั ะต ะฟัะตะผะฐั
ะฝะฐั.
+permission_no_access = ะะตะท ะดะพัััะฟ
+ssh_key_deletion_success = SSH ะบะปัััั ะต ะฟัะตะผะฐั
ะฝะฐั.
+comment_type_group_project = ะัะพะตะบั
+update_language_success = ะะทะธะบัั ะต ะพะฑะฝะพะฒะตะฝ.
+add_key_success = SSH ะบะปัััั โ%sโ ะต ะดะพะฑะฐะฒะตะฝ.
+add_gpg_key_success = GPG ะบะปัััั โ%sโ ะต ะดะพะฑะฐะฒะตะฝ.
+user_unblock_success = ะะพััะตะฑะธัะตะปัั ะต ะพัะฑะปะพะบะธัะฐะฝ ััะฟะตัะฝะพ.
+user_block_success = ะะพััะตะฑะธัะตะปัั ะต ะฑะปะพะบะธัะฐะฝ ััะฟะตัะฝะพ.
+update_profile_success = ะัะพัะธะปัั ะฒะธ ะต ะพะฑะฝะพะฒะตะฝ.
+update_user_avatar_success = ะัะพัะธะปะฝะฐัะฐ ัะฝะธะผะบะฐ ะฝะฐ ะฟะพััะตะฑะธัะตะปั ะต ะพะฑะฝะพะฒะตะฝะฐ.
+remove_oauth2_application_success = ะัะธะปะพะถะตะฝะธะตัะพ ะต ะธะทััะธัะพ.
+email_deletion_success = ะะดัะตััั ะฝะฐ ะตะป. ะฟะพัะฐ ะต ะฟัะตะผะฐั
ะฝะฐั.
+update_avatar_success = ะัะพัะธะปะฝะฐัะฐ ะฒะธ ัะฝะธะผะบะฐ ะต ะพะฑะฝะพะฒะตะฝะฐ.
+change_username = ะะพััะตะฑะธัะตะปัะบะพัะพ ะฒะธ ะธะผะต ะต ะฟัะพะผะตะฝะตะฝะพ.
+comment_type_group_assignee = ะะทะฟัะปะฝะธัะตะป
+enable_custom_avatar = ะะทะฟะพะปะทะฒะฐะฝะต ะฝะฐ ะฟะตััะพะฝะฐะปะธะทะธัะฐะฝะฐ ะฟัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ
+requires_activation = ะะทะธัะบะฒะฐ ะฐะบัะธะฒะธัะฐะฝะต
+activated = ะะบัะธะฒะธัะฐะฝ
+primary = ะัะฝะพะฒะตะฝ
+email_deletion = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ ะฐะดัะตัะฐ ะฝะฐ ะตะป. ะฟะพัะฐ
+add_new_email = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะฝะพะฒ ะฐะดัะตั ะฝะฐ ะตะป. ะฟะพัะฐ
+add_email = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะฐะดัะตั ะฝะฐ ะตะป. ะฟะพัะฐ
+key_content_gpg_placeholder = ะะฐะฟะพัะฒะฐ ั โ-----BEGIN PGP PUBLIC KEY BLOCK-----โ
+comment_type_group_title = ะะฐะณะปะฐะฒะธะต
+comment_type_group_label = ะัะธะบะตั
+change_username_prompt = ะะฐะฑะตะปะตะถะบะฐ: ะัะพะผัะฝะฐัะฐ ะฝะฐ ะฟะพััะตะฑะธัะตะปัะบะพัะพ ะฒะธ ะธะผะต ะฟัะพะผะตะฝั ัััะพ URL ะฝะฐ ะฒะฐัะธั ะฐะบะฐัะฝั.
+update_language_not_found = ะะทะธะบัั โ%sโ ะฝะต ะต ะฝะฐะปะธัะตะฝ.
+keep_activity_private_popup = ะะฐัะฐัะฐ ะดะตะนะฝะพัั ัะต ะฑัะดะต ะฒะธะดะธะผะฐ ัะฐะผะพ ะทะฐ ะฒะฐั ะธ ะฐะดะผะธะฝะธัััะฐัะพัะธัะต ะฝะฐ ัะฐะนัะฐ
+uploaded_avatar_not_a_image = ะะฐัะตะฝะธัั ัะฐะนะป ะฝะต ะต ะธะทะพะฑัะฐะถะตะฝะธะต.
+uploaded_avatar_is_too_big = ะ ะฐะทะผะตััั ะฝะฐ ะบะฐัะตะฝะธั ัะฐะนะป (%d KiB) ะฝะฐะดะฒะธัะฐะฒะฐ ะผะฐะบัะธะผะฐะปะฝะธั ัะฐะทะผะตั (%d KiB).
+change_password_success = ะะฐัะพะปะฐัะฐ ะฒะธ ะต ะพะฑะฝะพะฒะตะฝะฐ. ะะปะธะทะฐะนัะต ั ะฝะพะฒะฐัะฐ ัะธ ะฟะฐัะพะปะฐ ะพั ัะตะณะฐ ะฝะฐัะฐััะบ.
+manage_themes = ะขะตะผะฐ ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต
+manage_openid = OpenID ะฐะดัะตัะธ
+primary_email = ะะฐ ะต ะพัะฝะพะฒะตะฝ
+keep_email_private = ะกะบัะธะฒะฐะฝะต ะฝะฐ ะฐะดัะตัะฐ ะฝะฐ ะตะป. ะฟะพัะฐ
+theme_update_error = ะะทะฑัะฐะฝะฐัะฐ ัะตะผะฐ ะฝะต ัััะตััะฒัะฒะฐ.
+theme_update_success = ะขะตะผะฐัะฐ ะฒะธ ะต ะพะฑะฝะพะฒะตะฝะฐ.
+key_content_ssh_placeholder = ะะฐะฟะพัะฒะฐ ั โssh-ed25519โ, โssh-rsaโ, โecdsa-sha2-nistp256โ, โecdsa-sha2-nistp384โ, โecdsa-sha2-nistp521โ, โsk-ecdsa-sha2-nistp256@openssh.comโ, ะธะปะธ โsk-ssh-ed25519@openssh.comโ
+hide_openid = ะกะบัะธะฒะฐะฝะต ะพั ะฟัะพัะธะปะฐ
+key_content = ะกัะดััะถะฐะฝะธะต
+ssh_key_deletion = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ SSH ะบะปัั
+gpg_key_deletion = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ GPG ะบะปัั
+key_name = ะะผะต ะฝะฐ ะบะปััะฐ
+key_id = ID ะฝะฐ ะบะปััะฐ
+show_openid = ะะพะบะฐะทะฒะฐะฝะต ะฒ ะฟัะพัะธะปะฐ
+visibility.public = ะัะฑะปะธัะฝะฐ
+visibility.limited = ะะณัะฐะฝะธัะตะฝะฐ
+visibility.private = ะงะฐััะฝะฐ
+location_placeholder = ะกะฟะพะดะตะปะตัะต ะฟัะธะฑะปะธะทะธัะตะปะฝะพัะพ ัะธ ะผะตััะพะฟะพะปะพะถะตะฝะธะต ั ะดััะณะธัะต
+key_signature_gpg_placeholder = ะะฐะฟะพัะฒะฐ ั โ-----BEGIN PGP SIGNATURE-----โ
+key_signature_ssh_placeholder = ะะฐะฟะพัะฒะฐ ั โ-----BEGIN SSH SIGNATURE-----โ
+saved_successfully = ะะฐัััะพะนะบะธัะต ะฑัั
ะฐ ะทะฐะฟะฐะทะตะฝะธ ััะฟะตัะฝะพ.
+no_activity = ะัะผะฐ ัะบะพัะพัะฝะฐ ะดะตะนะฝะพัั
+theme_desc = ะขะฐะทะธ ัะตะผะฐ ัะต ัะต ะธะทะฟะพะปะทะฒะฐ ะทะฐ ัะตะฑ ะธะฝัะตััะตะนัะฐ, ะบะพะณะฐัะพ ััะต ะฒะปะตะทะปะธ.
+keep_activity_private = ะกะบัะธะฒะฐะฝะต ะฝะฐ ะดะตะนะฝะพัััะฐ ะพั ะฟัะพัะธะปะฝะฐัะฐ ัััะฐะฝะธัะฐ
+lookup_avatar_by_mail = ะขัััะตะฝะต ะฝะฐ ะฟัะพัะธะปะฝะฐ ัะฝะธะผะบะฐ ะฟะพ ะฐะดัะตัะฐ ะฝะฐ ะตะป. ะฟะพัะฐ
+password_incorrect = ะขะตะบััะฐัะฐ ะฟะฐัะพะปะฐ ะต ะฝะตะฟัะฐะฒะธะปะฝะฐ.
+change_username_redirect_prompt = ะกัะฐัะพัะพ ะฟะพััะตะฑะธัะตะปัะบะพ ะธะผะต ัะต ัะต ะฟัะตะฝะฐัะพัะฒะฐ, ะดะพะบะฐัะพ ะฝัะบะพะน ะฝะต ะณะพ ะฒะทะตะผะต.
+principal_content = ะกัะดััะถะฐะฝะธะต
+manage_ssh_principals = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ SSH Certificate Principals
+twofa_disabled = ะะฒััะฐะบัะพัะฝะพัะพ ัะดะพััะพะฒะตััะฒะฐะฝะต ะต ะธะทะบะปััะตะฝะพ.
+orgs_none = ะะต ััะต ััะฐััะฝะธะบ ะฒ ะฝะธะบะฐะบะฒะธ ะพัะณะฐะฝะธะทะฐัะธะธ.
+repos_none = ะะต ะฟัะธัะตะถะฐะฒะฐัะต ะฝะธะบะฐะบะฒะธ ั
ัะฐะฝะธะปะธัะฐ.
+blocked_users_none = ะัะผะฐ ะฑะปะพะบะธัะฐะฝะธ ะฟะพััะตะฑะธัะตะปะธ.
+profile_desc = ะะฐัะธัั ะฟัะพัะธะป
+permission_write = ะงะตัะตะฝะต ะธ ะฟะธัะฐะฝะต
+twofa_disable = ะะทะบะปััะฒะฐะฝะต ะฝะฐ ะดะฒััะฐะบัะพัะฝะพัะพ ัะดะพััะพะฒะตััะฒะฐะฝะต
+twofa_enroll = ะะบะปััะฒะฐะฝะต ะฝะฐ ะดะฒััะฐะบัะพัะฝะพ ัะดะพััะพะฒะตััะฒะฐะฝะต
+ssh_key_name_used = ะะตัะต ัััะตััะฒัะฒะฐ SSH ะบะปัั ััั ัััะพัะพ ะธะผะต ะฒัะฒ ะฒะฐัะธั ะฐะบะฐัะฝั.
+email_notifications.enable = ะะบะปััะฒะฐะฝะต ะฝะฐ ะธะทะฒะตััะธััะฐ ะฟะพ ะตะป. ะฟะพัะฐ
+delete_prompt = ะขะฐะทะธ ะพะฟะตัะฐัะธั ัะต ะธะทััะธะต ะฟะตัะผะฐะฝะตะฝัะฝะพ ะฟะพััะตะฑะธัะตะปัะบะธั ะฒะธ ะฐะบะฐัะฝั. ะขะพะฒะฐ ะะ ะะะะ ะดะฐ ะฑัะดะต ะพัะผะตะฝะตะฝะพ.
+email_notifications.disable = ะะทะบะปััะฒะฐะฝะต ะฝะฐ ะธะทะฒะตััะธััะฐ ะฟะพ ะตะป. ะฟะพัะฐ
+delete_account = ะะทััะธะฒะฐะฝะต ะฝะฐ ะฐะบะฐัะฝัะฐ ะฒะธ
+confirm_delete_account = ะะพัะฒััะถะดะฐะฒะฐะฝะต ะฝะฐ ะธะทััะธะฒะฐะฝะตัะพ
+email_notifications.onmention = ะะป. ะฟะพัะฐ ัะฐะผะพ ะฟัะธ ัะฟะพะผะตะฝะฐะฒะฐะฝะต
+pronouns_unspecified = ะะตะฟะพัะพัะตะฝะธ
+pronouns = ะะตััะพะธะผะตะฝะธั
+gpg_token_code = echo "%s" | gpg -a --default-key %s --detach-sig
+language.title = ะะทะธะบ ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต
+language.localization_project = ะะพะผะพะณะฝะตัะต ะฝะธ ะดะฐ ะฟัะตะฒะตะดะตะผ Forgejo ะฝะฐ ะฒะฐัะธั ะตะทะธะบ! ะะฐััะตัะต ะฟะพะฒะตัะต .
+language.description = ะขะพะทะธ ะตะทะธะบ ัะต ะฑัะดะต ะทะฐะฟะฐะทะตะฝ ะฒัะฒ ะฒะฐัะธั ะฐะบะฐัะฝั ะธ ัะต ัะต ะธะทะฟะพะปะทะฒะฐ ะบะฐัะพ ะตะทะธะบ ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต, ัะปะตะด ะบะฐัะพ ะฒะปะตะทะตัะต.
+pronouns_custom = ะะตััะพะฝะฐะปะธะทะธัะฐะฝะธ
+visibility.limited_tooltip = ะะธะดะธะผะพ ัะฐะผะพ ะทะฐ ะฒะปะตะทะปะธ ะฟะพััะตะฑะธัะตะปะธ
+pronouns_custom_label = ะะตััะพะฝะฐะปะธะทะธัะฐะฝะธ ะผะตััะพะธะผะตะฝะธั
+
+[packages]
+container.labels.value = ะกัะพะนะฝะพัั
+alpine.repository.repositories = ะฅัะฐะฝะธะปะธัะฐ
+dependency.version = ะะตััะธั
+title = ะะฐะบะตัะธ
+empty = ะัะต ะพัะต ะฝัะผะฐ ะฟะฐะบะตัะธ.
+empty.documentation = ะะฐ ะฟะพะฒะตัะต ะธะฝัะพัะผะฐัะธั ะพัะฝะพัะฝะพ ัะตะณะธััััะฐ ะฝะฐ ะฟะฐะบะตัะธัะต ะฒะธะถัะต ะดะพะบัะผะตะฝัะฐัะธััะฐ .
+container.labels.key = ะะปัั
+requirements = ะะทะธัะบะฒะฐะฝะธั
+details = ะะพะดัะพะฑะฝะพััะธ
+details.license = ะะธัะตะฝะท
+container.labels = ะัะธะบะตัะธ
+versions = ะะตััะธะธ
+empty.repo = ะะฐัะธั
ัะต ะปะธ ะฟะฐะบะตั, ะฝะพ ัะพะน ะฝะต ัะต ะฟะพะบะฐะทะฒะฐ ััะบ? ะัะธะดะตัะต ะฒ ะฝะฐัััะพะนะบะธัะต ะทะฐ ะฟะฐะบะตัะธ ะธ ะณะพ ัะฒััะถะตัะต ะบัะผ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
+keywords = ะะปััะพะฒะธ ะดัะผะธ
+details.author = ะะฒัะพั
+about = ะัะฝะพัะฝะพ ัะพะทะธ ะฟะฐะบะตั
+settings.delete.success = ะะฐะบะตััั ะต ะธะทััะธั.
+settings.delete = ะะทััะธะฒะฐะฝะต ะฝะฐ ะฟะฐะบะตัะฐ
+container.details.platform = ะะปะฐััะพัะผะฐ
+settings.delete.error = ะะตััะฟะตัะฝะพ ะธะทััะธะฒะฐะฝะต ะฝะฐ ะฟะฐะบะตั.
+installation = ะะฝััะฐะปะฐัะธั
+versions.view_all = ะะธะถัะต ะฒัะธัะบะธ
+dependencies = ะะฐะฒะธัะธะผะพััะธ
+published_by_in = ะัะฑะปะธะบัะฒะฐะฝ %[1]s ะพั %[3]s ะฒ %[5]s
+published_by = ะัะฑะปะธะบัะฒะฐะฝ %[1]s ะพั %[3]s
+generic.download = ะะทัะตะณะปะตัะต ะฟะฐะบะตัะฐ ะพั ะบะพะผะฐะฝะดะฝะธั ัะตะด:
+container.details.type = ะขะธะฟ ะพะฑัะฐะท
+alpine.repository = ะะฐ ั
ัะฐะฝะธะปะธัะตัะพ
+container.images.title = ะะฑัะฐะทะธ
+
+[tool]
+hours = %d ัะฐัะฐ
+now = ัะตะณะฐ
+raw_seconds = ัะตะบัะฝะดะธ
+1m = 1 ะผะธะฝััะฐ
+1s = 1 ัะตะบัะฝะดะฐ
+months = %d ะผะตัะตัะฐ
+weeks = %d ัะตะดะผะธัะธ
+1w = 1 ัะตะดะผะธัะฐ
+years = %d ะณะพะดะธะฝะธ
+seconds = %d ัะตะบัะฝะดะธ
+days = %d ะดะฝะธ
+1d = 1 ะดะตะฝ
+minutes = %d ะผะธะฝััะธ
+1mon = 1 ะผะตัะตั
+1h = 1 ัะฐั
+1y = 1 ะณะพะดะธะฝะฐ
+future = ะฑัะดะตัะต
+raw_minutes = ะผะธะฝััะธ
[repo]
issues.context.edit = ะ ะตะดะฐะบัะธัะฐะฝะต
@@ -380,15 +404,15 @@ issues.keyword_search_unavailable = ะ ะผะพะผะตะฝัะฐ ััััะตะฝะตัะพ ะฟะพ ะบ
repo_desc_helper = ะัะฒะตะดะตัะต ะบัะฐัะบะพ ะพะฟะธัะฐะฝะธะต (ะพะฟัะธะพะฝะฐะปะฝะพ)
mirror_address = ะะปะพะฝะธัะฐะฝะต ะพั URL
owner_helper = ะัะบะพะธ ะพัะณะฐะฝะธะทะฐัะธะธ ะผะพะถะต ะดะฐ ะฝะต ัะต ะฟะพะบะฐะทะฒะฐั ะฒ ะฟะฐะดะฐัะพัะพ ะผะตะฝั ะฟะพัะฐะดะธ ะพะณัะฐะฝะธัะตะฝะธะต ะทะฐ ะผะฐะบัะธะผะฐะปะตะฝ ะฑัะพะน ั
ัะฐะฝะธะปะธัะฐ.
-new_repo_helper = ะฅัะฐะฝะธะปะธัะตัะพ ััะดััะถะฐ ะฒัะธัะบะธ ัะฐะนะปะพะฒะต ะฝะฐ ะฟัะพะตะบัะฐ, ะฒะบะปััะธัะตะปะฝะพ ั
ัะพะฝะพะปะพะณะธััะฐ ะฝะฐ ัะตะฒะธะทะธะธัะต. ะะตัะต ั
ะพััะฒะฐัะต ั
ัะฐะฝะธะปะธัะต ะดััะณะฐะดะต? ะะธะณัะธัะฐะนัะต ั
ัะฐะฝะธะปะธัะต.
+new_repo_helper = ะฅัะฐะฝะธะปะธัะตัะพ ััะดััะถะฐ ะฒัะธัะบะธ ัะฐะนะปะพะฒะต ะฝะฐ ะฟัะพะตะบัะฐ, ะฒะบะปััะธัะตะปะฝะพ ั
ัะพะฝะพะปะพะณะธััะฐ ะฝะฐ ัะตะฒะธะทะธะธัะต. ะะตัะต ั
ะพััะฒะฐัะต ั
ัะฐะฝะธะปะธัะต ะดััะณะฐะดะต? ะะธะณัะธัะฐะนัะต ั
ัะฐะฝะธะปะธัะต .
repo_name_helper = ะะพะฑัะธัะต ะธะผะตะฝะฐ ะฝะฐ ั
ัะฐะฝะธะปะธัะฐ ะธะทะฟะพะปะทะฒะฐั ะบัะฐัะบะธ, ะทะฐะฟะพะผะฝััะธ ัะต ะธ ัะฝะธะบะฐะปะฝะธ ะบะปััะพะฒะธ ะดัะผะธ.
migrated_from = ะะธะณัะธัะฐะฝะพ ะพั %[2]s
visibility_description = ะกะฐะผะพ ะฟัะธัะตะถะฐัะตะปัั ะธะปะธ ััะฐััะฝะธัะธัะต ะฒ ะพัะณะฐะฝะธะทะฐัะธััะฐ, ะฐะบะพ ะธะผะฐั ะฟัะฐะฒะฐ, ัะต ะผะพะณะฐั ะดะฐ ะณะพ ะฒะธะดัั.
projects.description = ะะฟะธัะฐะฝะธะต (ะพะฟัะธะพะฝะฐะปะฝะพ)
-template_select = ะะทะฑะตัะตัะต ัะฐะฑะปะพะฝ.
+template_select = ะะทะฑะตัะตัะต ัะฐะฑะปะพะฝ
visibility_helper = ะฅัะฐะฝะธะปะธัะตัะพ ะดะฐ ะต ัะฐััะฝะพ
license = ะะธัะตะฝะท
-license_helper = ะะทะฑะตัะตัะต ะปะธัะตะฝะทะธะพะฝะตะฝ ัะฐะนะป.
+license_helper = ะะทะฑะตัะตัะต ะปะธัะตะฝะทะธะพะฝะตะฝ ัะฐะนะป
readme = README
migrate.clone_address = ะะธะณัะธัะฐะฝะต / ะะปะพะฝะธัะฐะฝะต ะพั URL
migrated_from_fake = ะะธะณัะธัะฐะฝะพ ะพั %[1]s
@@ -405,16 +429,16 @@ milestones.filter_sort.least_issues = ะะฐะน-ะผะฐะปะบะพ ะทะฐะดะฐัะธ
milestones.filter_sort.most_issues = ะะฐะน-ะผะฝะพะณะพ ะทะฐะดะฐัะธ
settings.add_webhook = ะะพะฑะฐะฒัะฝะต ะฝะฐ ัะตะฑ-ะบัะบะฐ
template.webhooks = ะฃะตะฑ-ะบัะบะธ
-issues.label_templates.info = ะัะต ะพัะต ะฝัะผะฐ ะตัะธะบะตัะธ. ะกัะทะดะฐะนัะต ะตัะธะบะตั ั "ะะพะฒ ะตัะธะบะตั" ะธะปะธ ะธะทะฟะพะปะทะฒะฐะนัะต ะฟัะตะดะฒะฐัะธัะตะปะฝะพ ะทะฐะดะฐะดะตะฝ ะฝะฐะฑะพั ะพั ะตัะธะบะตัะธ:
+issues.label_templates.info = ะัะต ะพัะต ะฝัะผะฐ ะตัะธะบะตัะธ. ะกัะทะดะฐะนัะต ะตัะธะบะตั ั โะะพะฒ ะตัะธะบะตัโ ะธะปะธ ะธะทะฟะพะปะทะฒะฐะนัะต ะฟัะตะดะฒะฐัะธัะตะปะฝะพ ะทะฐะดะฐะดะตะฝ ะฝะฐะฑะพั ะพั ะตัะธะบะตัะธ:
labels = ะัะธะบะตัะธ
-license_helper_desc = ะะธัะตะฝะทัั ะพะฟัะตะดะตะปั ะบะฐะบะฒะพ ะผะพะณะฐั ะธ ะบะฐะบะฒะพ ะฝะต ะผะพะณะฐั ะดะฐ ะฟัะฐะฒัั ะดััะณะธัะต ั ะฒะฐัะธั ะบะพะด. ะะต ััะต ัะธะณััะฝะธ ะบะพะน ะต ะฟะพะดั
ะพะดัั ะทะฐ ะฒะฐัะธั ะฟัะพะตะบั? ะะธะถัะต ะะทะฑะธัะฐะฝะต ะฝะฐ ะปะธัะตะฝะท.
+license_helper_desc = ะะธัะตะฝะทัั ะพะฟัะตะดะตะปั ะบะฐะบะฒะพ ะผะพะณะฐั ะธ ะบะฐะบะฒะพ ะฝะต ะผะพะณะฐั ะดะฐ ะฟัะฐะฒัั ะดััะณะธัะต ั ะฒะฐัะธั ะบะพะด. ะะต ััะต ัะธะณััะฝะธ ะบะพะน ะต ะฟะพะดั
ะพะดัั ะทะฐ ะฒะฐัะธั ะฟัะพะตะบั? ะะธะถัะต ะะทะฑะธัะฐะฝะต ะฝะฐ ะปะธัะตะฝะท .
issues.choose.blank = ะะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต
settings.hooks = ะฃะตะฑ-ะบัะบะธ
-issue_labels = ะัะธะบะตัะธ ะทะฐ ะทะฐะดะฐัะธัะต
-issue_labels_helper = ะะทะฑะตัะตัะต ะฝะฐะฑะพั ะพั ะตัะธะบะตัะธ ะทะฐ ะทะฐะดะฐัะธัะต.
+issue_labels = ะัะธะบะตัะธ
+issue_labels_helper = ะะทะฑะตัะตัะต ะฝะฐะฑะพั ะพั ะตัะธะบะตัะธ
readme_helper_desc = ะขะพะฒะฐ ะต ะผัััะพัะพ, ะบัะดะตัะพ ะผะพะถะตัะต ะดะฐ ะฝะฐะฟะธัะตัะต ะฟัะปะฝะพ ะพะฟะธัะฐะฝะธะต ะฝะฐ ะฒะฐัะธั ะฟัะพะตะบั.
-repo_gitignore_helper = ะะทะฑะตัะตัะต .gitignore ัะฐะฑะปะพะฝะธ.
-auto_init = ะะฐ ัะต ะธะฝะธัะธะฐะปะธะทะธัะฐ ั
ัะฐะฝะธะปะธัะต (ะะพะฑะฐะฒั .gitignore, License ะธ README)
+repo_gitignore_helper = ะะทะฑะตัะตัะต .gitignore ัะฐะฑะปะพะฝะธ
+auto_init = ะะฐ ัะต ะธะฝะธัะธะฐะปะธะทะธัะฐ ั
ัะฐะฝะธะปะธัะต
template.issue_labels = ะัะธะบะตัะธ ะทะฐ ะทะฐะดะฐัะธัะต
migrate_items_labels = ะัะธะบะตัะธ
issues.label_templates.title = ะะฐัะตะถะดะฐะฝะต ะฝะฐ ะฟัะตะดะฒ. ะทะฐะดะฐะดะตะฝ ะฝะฐะฑะพั ะพั ะตัะธะบะตัะธ
@@ -429,7 +453,7 @@ editor.upload_file = ะะฐัะฒะฐะฝะต ะฝะฐ ัะฐะนะป
projects.column.color = ะฆะฒัั
editor.cancel_lower = ะัะบะฐะท
pulls = ะะฐัะฒะบะธ ะทะฐ ัะปะธะฒะฐะฝะต
-editor.upload_files_to_dir = ะะฐัะฒะฐะฝะต ะฝะฐ ัะฐะนะปะพะฒะต ะฒ "%s"
+editor.upload_files_to_dir = ะะฐัะฒะฐะฝะต ะฝะฐ ัะฐะนะปะพะฒะต ะฒ โ%sโ
settings.slack_color = ะฆะฒัั
issues.label_color = ะฆะฒัั
create_new_repo_command = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะฝะพะฒะพ ั
ัะฐะฝะธะปะธัะต ะฒ ะบะพะผะฐะฝะดะฝะธั ัะตะด
@@ -441,7 +465,7 @@ issues.cancel = ะัะบะฐะท
settings.transfer_owner = ะะพะฒ ะฟัะธัะตะถะฐัะตะป
wiki.new_page_button = ะะพะฒะฐ ัััะฐะฝะธัะฐ
commit_graph.color = ะฆะฒัั
-projects.create_success = ะัะพะตะบััั "%s" ะต ััะทะดะฐะดะตะฝ.
+projects.create_success = ะัะพะตะบััั โ%sโ ะต ััะทะดะฐะดะตะฝ.
projects.type.none = ะัะผะฐ
projects.new_subheader = ะะพะพัะดะธะฝะธัะฐะนัะต, ะฟัะพัะปะตะดัะฒะฐะนัะต ะธ ะพะฑะฝะพะฒัะฒะฐะนัะต ัะฐะฑะพัะฐัะฐ ัะธ ะฝะฐ ะตะดะฝะพ ะผัััะพ, ัะฐะบะฐ ัะต ะฟัะพะตะบัะธัะต ะดะฐ ะพััะฐะฝะฐั ะฟัะพะทัะฐัะฝะธ ะธ ะฟะพ ะณัะฐัะธะบ.
projects.open = ะัะฒะฐััะฝะต
@@ -512,10 +536,10 @@ wiki.back_to_wiki = ะะฑัะฐัะฝะพ ะบัะผ ัะธะบะธ ัััะฐะฝะธัะฐัะฐ
wiki.wiki_page_revisions = ะ ะตะฒะธะทะธะธ ะฝะฐ ัััะฐะฝะธัะฐัะฐ
wiki.file_revision = ะ ะตะฒะธะทะธั ะฝะฐ ัััะฐะฝะธัะฐัะฐ
activity.title.issues_created_by = %s ััะทะดะฐะดะตะฝะธ ะพั %s
-wiki.delete_page_notice_1 = ะะทััะธะฒะฐะฝะตัะพ ะฝะฐ ัะธะบะธ ัััะฐะฝะธัะฐัะฐ "%s" ะฝะต ะผะพะถะต ะดะฐ ะฑัะดะต ะพัะผะตะฝะตะฝะพ. ะัะพะดัะปะถะฐะฒะฐะฝะต?
+wiki.delete_page_notice_1 = ะะทััะธะฒะฐะฝะตัะพ ะฝะฐ ัะธะบะธ ัััะฐะฝะธัะฐัะฐ โ%sโ ะฝะต ะผะพะถะต ะดะฐ ะฑัะดะต ะพัะผะตะฝะตะฝะพ. ะัะพะดัะปะถะฐะฒะฐะฝะต?
wiki.page_name_desc = ะัะฒะตะดะตัะต ะธะผะต ะทะฐ ัะฐะทะธ ัะธะบะธ ัััะฐะฝะธัะฐ. ะัะบะพะธ ัะฟะตัะธะฐะปะฝะธ ะธะผะตะฝะฐ ัะฐ: "Home", "_Sidebar" ะธ "_Footer".
wiki.page_already_exists = ะะตัะต ัััะตััะฒัะฒะฐ ัะธะบะธ ัััะฐะฝะธัะฐ ััั ัััะพัะพ ะธะผะต.
-wiki.reserved_page = ะะผะตัะพ ะฝะฐ ัะธะบะธ ัััะฐะฝะธัะฐัะฐ "%s" ะต ัะตะทะตัะฒะธัะฐะฝะพ.
+wiki.reserved_page = ะะผะตัะพ ะฝะฐ ัะธะบะธ ัััะฐะฝะธัะฐัะฐ โ%sโ ะต ัะตะทะตัะฒะธัะฐะฝะพ.
wiki.last_updated = ะะพัะปะตะดะฝะพ ะพะฑะฝะพะฒัะฒะฐะฝะต %s
settings.event_release = ะะทะดะฐะฝะธะต
wiki.desc = ะะธัะตัะต ะธ ัะฟะพะดะตะปัะนัะต ะดะพะบัะผะตะฝัะฐัะธั ััั ัััััะดะฝะธัะธ.
@@ -605,17 +629,17 @@ projects.column.edit = ะ ะตะดะฐะบัะธัะฐะฝะต ะฝะฐ ะบะพะปะพะฝะฐัะฐ
issues.close = ะะฐัะฒะฐััะฝะต ะฝะฐ ะทะฐะดะฐัะฐัะฐ
issues.ref_reopened_from = `ะพัะฒะพัะธ ะฝะฐะฝะพะฒะพ ัะฐะทะธ ะทะฐะดะฐัะฐ %[4]s %[2]s `
projects.deletion = ะะทััะธะฒะฐะฝะต ะฝะฐ ะฟัะพะตะบัะฐ
-projects.edit_success = ะัะพะตะบััั "%s" ะต ะพะฑะฝะพะฒะตะฝ.
+projects.edit_success = ะัะพะตะบััั โ%sโ ะต ะพะฑะฝะพะฒะตะฝ.
projects.deletion_success = ะัะพะตะบััั ะต ะธะทััะธั.
issues.create_comment = ะะพะผะตะฝัะธัะฐะฝะต
unescape_control_characters = ะัะตะบัะฐะฝะธัะฐะฝะต
-editor.file_delete_success = ะคะฐะนะปัั "%s" ะต ะธะทััะธั.
+editor.file_delete_success = ะคะฐะนะปัั โ%sโ ะต ะธะทััะธั.
projects.type.uncategorized = ะะตะบะฐัะตะณะพัะธะทะธัะฐะฝะพ
projects.column.set_default = ะะฐะดะฐะฒะฐะฝะต ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต
projects.column.assigned_to = ะัะทะปะพะถะตะฝะพ ะฝะฐ
-issues.reopen_comment_issue = ะะพะผะตะฝัะธัะฐะฝะต ะธ ะพัะฒะฐััะฝะต
+issues.reopen_comment_issue = ะัะฒะฐััะฝะต ะฝะฐะฝะพะฒะพ ั ะบะพะผะตะฝัะฐั
issues.reopen_issue = ะัะฒะฐััะฝะต ะฝะฐะฝะพะฒะพ
-issues.close_comment_issue = ะะพะผะตะฝัะธัะฐะฝะต ะธ ะะฐัะฒะฐััะฝะต
+issues.close_comment_issue = ะะฐัะฒะฐััะฝะต ั ะบะพะผะตะฝัะฐั
milestones.filter_sort.latest_due_date = ะะฐะน-ะดะฐะปะตัะตะฝ ะบัะฐะตะฝ ััะพะบ
diff.view_file = ะัะตะณะปะตะด ะฝะฐ ัะฐะนะปะฐ
release.deletion_success = ะะทะดะฐะฝะธะตัะพ ะต ะธะทััะธัะพ.
@@ -663,11 +687,11 @@ activity.title.prs_opened_by = %s ะฟัะตะดะปะพะถะตะฝะธ ะพั %s
issues.action_milestone_no_select = ะะตะท ะตัะฐะฟ
issues.action_assignee_no_select = ะะตะท ะธะทะฟัะปะฝะธัะตะป
milestones.edit = ะ ะตะดะฐะบัะธัะฐะฝะต ะฝะฐ ะตัะฐะฟะฐ
-milestones.create_success = ะัะฐะฟัั "%s" ะต ััะทะดะฐะดะตะฝ.
+milestones.create_success = ะัะฐะฟัั โ%sโ ะต ััะทะดะฐะดะตะฝ.
milestones.create = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะตัะฐะฟ
milestones.clear = ะะทัะธััะฒะฐะฝะต
milestones.deletion = ะะทััะธะฒะฐะฝะต ะฝะฐ ะตัะฐะฟะฐ
-milestones.edit_success = ะัะฐะฟัั "%s" ะต ะพะฑะฝะพะฒะตะฝ.
+milestones.edit_success = ะัะฐะฟัั โ%sโ ะต ะพะฑะฝะพะฒะตะฝ.
milestones.modify = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะตัะฐะฟะฐ
milestones.deletion_success = ะัะฐะฟัั ะต ะธะทััะธั.
milestones.filter_sort.most_complete = ะะฐะน-ะผะฝะพะณะพ ะทะฐะฒัััะตะฝ
@@ -750,7 +774,7 @@ pulls.compare_changes = ะะพะฒะฐ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต
activity.title.releases_published_by = %s ะฟัะฑะปะธะบัะฒะฐะฝะธ ะพั %s
topic.manage_topics = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ ัะตะผะธัะต
topic.done = ะะพัะพะฒะพ
-find_file.go_to_file = ะัะธะฒะฐะฝะต ะบัะผ ัะฐะนะป
+find_file.go_to_file = ะะฐะผะธัะฐะฝะต ะฝะฐ ัะฐะนะป
reactions_more = ะธ ะพัะต %d
issues.unpin_comment = ะพัะบะฐัะธ ัะพะฒะฐ %s
lines = ัะตะดะฐ
@@ -760,7 +784,7 @@ editor.preview_changes = ะัะตะณะปะตะถะดะฐะฝะต ะฝะฐ ะฟัะพะผะตะฝะธัะต
default_branch = ะกัะฐะฝะดะฐััะตะฝ ะบะปะพะฝ
default_branch_label = ััะฐะฝะดะฐััะตะฝ
template.topics = ะขะตะผะธ
-editor.branch_does_not_exist = ะะปะพะฝัั "%s" ะฝะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
+editor.branch_does_not_exist = ะะปะพะฝัั โ%sโ ะฝะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
editor.no_changes_to_show = ะัะผะฐ ะฟัะพะผะตะฝะธ ะทะฐ ะฟะพะบะฐะทะฒะฐะฝะต.
issues.choose.get_started = ะััะฒะธ ัััะฟะบะธ
issues.change_milestone_at = `ะฟัะพะผะตะฝะธ ะตัะฐะฟะฐ ะพั %s ะฝะฐ %s %s`
@@ -791,18 +815,18 @@ file_view_source = ะัะตะณะปะตะด ะฝะฐ ะธะทั
ะพะดะฝะธั ะบะพะด
diff.parent = ัะพะดะธัะตะป
issues.unlock_comment = ะพัะบะปััะธ ัะพะฒะฐ ะพะฑััะถะดะฐะฝะต %s
release.edit_subheader = ะะทะดะฐะฝะธััะฐ ะฒะธ ะฟะพะทะฒะพะปัะฒะฐั ะดะฐ ัะฟัะฐะฒะปัะฒะฐัะต ะฒะตััะธะธัะต ะฝะฐ ะฟัะพะตะบัะฐ.
-branch.already_exists = ะะตัะต ัััะตััะฒัะฒะฐ ะบะปะพะฝ ะฝะฐ ะธะผะต "%s".
+branch.already_exists = ะะตัะต ัััะตััะฒัะฒะฐ ะบะปะพะฝ ะฝะฐ ะธะผะต โ%sโ.
contributors.contribution_type.deletions = ะะทััะธะฒะฐะฝะธั
contributors.contribution_type.additions = ะะพะฑะฐะฒัะฝะธั
diff.browse_source = ะ ะฐะทะณะปะตะถะดะฐะฝะต ะฝะฐ ะธะทั
ะพะดะฝะธั ะบะพะด
file_view_rendered = ะัะตะณะปะตะด ะฝะฐ ะฒะธะทัะฐะปะธะทะฐัะธั
issues.lock_with_reason = ะทะฐะบะปััะธ ะบะฐัะพ %s ะธ ะพะณัะฐะฝะธัะธ ะพะฑััะถะดะฐะฝะตัะพ ะดะพ ัััััะดะฝะธัะธ %s
milestones.new_subheader = ะัะฐะฟะธัะต ะฒะธ ะฟะพะผะฐะณะฐั ะดะฐ ัะฟัะฐะฒะปัะฒะฐัะต ะทะฐะดะฐัะธัะต ะธ ะดะฐ ะฟัะพัะปะตะดัะฒะฐัะต ะฝะฐะฟัะตะดัะบะฐ ะธะผ.
-release.edit = ัะตะดะฐะบัะธัะฐะฝะต
-activity.published_release_label = ะัะฑะปะธะบัะฒะฐะฝะพ
+release.edit = ะ ะตะดะฐะบัะธัะฐะฝะต
+activity.published_release_label = ะะทะดะฐะฝะธะต
activity.navbar.contributors = ะะพะฟัะธะฝะตัะปะธ
pulls.recently_pushed_new_branches = ะะทัะปะฐัะบะฐั
ัะต ะฒ ะบะปะพะฝะฐ %[1]s %[2]s
-branch.branch_name_conflict = ะะผะตัะพ ะฝะฐ ะบะปะพะฝ "%s" ะต ะฒ ะบะพะฝัะปะธะบั ั ะฒะตัะต ัััะตััะฒัะฒะฐัะธั ะบะปะพะฝ "%s".
+branch.branch_name_conflict = ะะผะตัะพ ะฝะฐ ะบะปะพะฝะฐ โ%sโ ะต ะฒ ะบะพะฝัะปะธะบั ั ะฒะตัะต ัััะตััะฒัะฒะฐัะธั ะบะปะพะฝ โ%sโ.
all_branches = ะัะธัะบะธ ะบะปะพะฝะพะฒะต
file_raw = ะะธัะตะบัะฝะพ
file_history = ะััะพัะธั
@@ -814,7 +838,8 @@ file_too_large = ะคะฐะนะปัั ะต ัะฒััะดะต ะณะพะปัะผ, ะทะฐ ะดะฐ ะฑัะดะต ะฟ
commits = ะะพะดะฐะฒะฐะฝะธั
commit = ะะพะดะฐะฒะฐะฝะต
editor.commit_changes = ะะพะดะฐะฒะฐะฝะต ะฝะฐ ะฟัะพะผะตะฝะธัะต
-editor.add_tmpl = ะะพะฑะฐะฒัะฝะต ะฝะฐ "<ะธะผะต ะฝะฐ ัะฐะนะปะฐ>"
+editor.add_tmpl = ะะพะฑะฐะฒัะฝะต ะฝะฐ "<%s>"
+editor.add_tmpl.filename = ะธะผะต ะฝะฐ ัะฐะนะปะฐ
editor.add = ะะพะฑะฐะฒัะฝะต ะฝะฐ %s
editor.delete = ะะทััะธะฒะฐะฝะต ะฝะฐ %s
editor.update = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ %s
@@ -825,14 +850,14 @@ editor.new_branch_name_desc = ะะผะต ะฝะฐ ะฝะพะฒะธั ะบะปะพะฝโฆ
editor.propose_file_change = ะัะตะดะปะฐะณะฐะฝะต ะฝะฐ ะฟัะพะผัะฝะฐ ะฝะฐ ัะฐะนะปะฐ
editor.create_new_branch = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะฝะพะฒ ะบะปะพะฝ ะทะฐ ัะพะฒะฐ ะฟะพะดะฐะฒะฐะฝะต ะธ ะทะฐะฟะพัะฒะฐะฝะต ะฝะฐ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต.
editor.create_new_branch_np = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะฝะพะฒ ะบะปะพะฝ ะทะฐ ัะพะฒะฐ ะฟะพะดะฐะฒะฐะฝะต.
-editor.filename_is_invalid = ะะผะตัะพ ะฝะฐ ัะฐะนะปะฐ ะต ะฝะตะฒะฐะปะธะดะฝะพ: "%s".
-editor.commit_directly_to_this_branch = ะะพะดะฐะฒะฐะฝะต ะดะธัะตะบัะฝะพ ะบัะผ ะบะปะพะฝะฐ %s .
-editor.branch_already_exists = ะะปะพะฝัั "%s" ะฒะตัะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
-editor.file_already_exists = ะคะฐะนะป ั ะธะผะต "%s" ะฒะตัะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
+editor.filename_is_invalid = ะะผะตัะพ ะฝะฐ ัะฐะนะปะฐ ะต ะฝะตะฒะฐะปะธะดะฝะพ: โ%sโ.
+editor.commit_directly_to_this_branch = ะะพะดะฐะฒะฐะฝะต ะดะธัะตะบัะฝะพ ะบัะผ ะบะปะพะฝะฐ %[1]s .
+editor.branch_already_exists = ะะปะพะฝัั โ%sโ ะฒะตัะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
+editor.file_already_exists = ะคะฐะนะป ั ะธะผะต โ%sโ ะฒะตัะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
editor.commit_empty_file_header = ะะพะดะฐะฒะฐะฝะต ะฝะฐ ะฟัะฐะทะตะฝ ัะฐะนะป
editor.commit_empty_file_text = ะคะฐะนะปัั, ะบะพะนัะพ ััะต ะฝะฐ ะฟัั ะดะฐ ะฟะพะดะฐะดะตัะต, ะต ะฟัะฐะทะตะฝ. ะัะพะดัะปะถะฐะฒะฐะฝะต?
editor.fail_to_update_file_summary = ะกัะพะฑัะตะฝะธะต ะทะฐ ะณัะตัะบะฐ:
-editor.fail_to_update_file = ะะตััะฟะตัะฝะพ ะพะฑะฝะพะฒัะฒะฐะฝะต/ััะทะดะฐะฒะฐะฝะต ะฝะฐ ัะฐะนะป "%s".
+editor.fail_to_update_file = ะะตััะฟะตัะฝะพ ะพะฑะฝะพะฒัะฒะฐะฝะต/ััะทะดะฐะฒะฐะฝะต ะฝะฐ ัะฐะนะป โ%sโ.
editor.add_subdir = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะดะธัะตะบัะพัะธัโฆ
commits.commits = ะะพะดะฐะฒะฐะฝะธั
commits.find = ะขัััะตะฝะต
@@ -870,7 +895,7 @@ release.download_count = ะะทัะตะณะปัะฝะธั: %s
release.tag_name_invalid = ะะผะตัะพ ะฝะฐ ะผะฐัะบะตัะฐ ะฝะต ะต ะฒะฐะปะธะดะฝะพ.
diff.stats_desc = %d ะฟัะพะผะตะฝะตะฝะธ ัะฐะนะปะฐ ั %d ะดะพะฑะฐะฒัะฝะธั ะธ %d ะธะทััะธะฒะฐะฝะธั
release.tag_name_already_exist = ะะตัะต ัััะตััะฒัะฒะฐ ะธะทะดะฐะฝะธะต ั ัะพะฒะฐ ะธะผะต ะฝะฐ ะผะฐัะบะตั.
-branch.branch_already_exists = ะะปะพะฝัั "%s" ะฒะตัะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
+branch.branch_already_exists = ะะปะพะฝัั โ%sโ ะฒะตัะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
diff.download_patch = ะะทัะตะณะปัะฝะต ะฝะฐ ัะฐะนะป-ะบััะฟะบะฐ
diff.show_diff_stats = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ััะฐัะธััะธะบะฐ
diff.commit = ะฟะพะดะฐะฒะฐะฝะต
@@ -921,22 +946,22 @@ pulls.approve_count_1 = %d ะพะดะพะฑัะตะฝะธะต
pulls.can_auto_merge_desc = ะขะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต ะผะพะถะต ะดะฐ ะฑัะดะต ัะปััะฐ ะฐะฒัะพะผะฐัะธัะฝะพ.
pulls.num_conflicting_files_1 = %d ะบะพะฝัะปะธะบัะตะฝ ัะฐะนะป
activity.git_stats_commit_n = %d ะฟะพะดะฐะฒะฐะฝะธั
-settings.event_issues = ะะฐะดะฐัะธ
+settings.event_issues = ะะทะผะตะฝะตะฝะธะต
branch.delete_head = ะะทััะธะฒะฐะฝะต
-branch.delete = ะะทััะธะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ "%s"
+branch.delete = ะะทััะธะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ โ%sโ
branch.delete_html = ะะทััะธะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ
-tag.create_success = ะะฐัะบะตััั "%s" ะต ััะทะดะฐะดะตะฝ.
-branch.new_branch_from = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะฝะพะฒ ะบะปะพะฝ ะพั "%s"
+tag.create_success = ะะฐัะบะตััั โ%sโ ะต ััะทะดะฐะดะตะฝ.
+branch.new_branch_from = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะฝะพะฒ ะบะปะพะฝ ะพั โ%sโ
branch.new_branch = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะฝะพะฒ ะบะปะพะฝ
branch.confirm_rename_branch = ะัะตะธะผะตะฝัะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ
-branch.create_from = ะพั "%s"
+branch.create_from = ะพั โ%sโ
settings.add_team_duplicate = ะะบะธะฟัั ะฒะตัะต ัะฐะทะฟะพะปะฐะณะฐ ั ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต
settings.slack_domain = ะะพะผะตะนะฝ
-editor.directory_is_a_file = ะะผะตัะพ ะฝะฐ ะดะธัะตะบัะพัะธััะฐ "%s" ะฒะตัะต ัะต ะธะทะฟะพะปะทะฒะฐ ะบะฐัะพ ะธะผะต ะฝะฐ ัะฐะนะป ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
-editor.filename_is_a_directory = ะะผะตัะพ ะฝะฐ ัะฐะนะปะฐ "%s" ะฒะตัะต ัะต ะธะทะฟะพะปะทะฒะฐ ะบะฐัะพ ะธะผะต ะฝะฐ ะดะธัะตะบัะพัะธั ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
-editor.file_editing_no_longer_exists = ะคะฐะนะปัั, ะบะพะนัะพ ัะต ัะตะดะฐะบัะธัะฐ, "%s", ะฒะตัะต ะฝะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
-editor.file_deleting_no_longer_exists = ะคะฐะนะปัั, ะบะพะนัะพ ัะต ะธะทััะธะฒะฐ, "%s", ะฒะตัะต ะฝะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
-editor.unable_to_upload_files = ะะตััะฟะตัะฝะพ ะบะฐัะฒะฐะฝะต ะฝะฐ ัะฐะนะปะพะฒะต ะฒ "%s" ั ะณัะตัะบะฐ: %v
+editor.directory_is_a_file = ะะผะตัะพ ะฝะฐ ะดะธัะตะบัะพัะธััะฐ โ%sโ ะฒะตัะต ัะต ะธะทะฟะพะปะทะฒะฐ ะบะฐัะพ ะธะผะต ะฝะฐ ัะฐะนะป ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
+editor.filename_is_a_directory = ะะผะตัะพ ะฝะฐ ัะฐะนะปะฐ โ%sโ ะฒะตัะต ัะต ะธะทะฟะพะปะทะฒะฐ ะบะฐัะพ ะธะผะต ะฝะฐ ะดะธัะตะบัะพัะธั ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
+editor.file_editing_no_longer_exists = ะคะฐะนะปัั, ะบะพะนัะพ ัะต ัะตะดะฐะบัะธัะฐ, โ%sโ, ะฒะตัะต ะฝะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
+editor.file_deleting_no_longer_exists = ะคะฐะนะปัั, ะบะพะนัะพ ัะต ะธะทััะธะฒะฐ, โ%sโ, ะฒะตัะต ะฝะต ัััะตััะฒัะฒะฐ ะฒ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต.
+editor.unable_to_upload_files = ะะตััะฟะตัะฝะพ ะบะฐัะฒะฐะฝะต ะฝะฐ ัะฐะนะปะพะฒะต ะฒ โ%sโ ั ะณัะตัะบะฐ: %v
settings.web_hook_name_slack = Slack
settings.web_hook_name_discord = Discord
settings.web_hook_name_telegram = Telegram
@@ -948,10 +973,10 @@ settings.web_hook_name_larksuite_only = Lark Suite
settings.web_hook_name_wechatwork = WeCom (Wechat Work)
settings.web_hook_name_packagist = Packagist
diff.file_byte_size = ะ ะฐะทะผะตั
-branch.create_success = ะะปะพะฝัั "%s" ะต ััะทะดะฐะดะตะฝ.
-branch.deletion_success = ะะปะพะฝัั "%s" ะต ะธะทััะธั.
-branch.deletion_failed = ะะตััะฟะตัะฝะพ ะธะทััะธะฒะฐะฝะต ะฝะฐ ะบะปะพะฝ "%s".
-branch.rename_branch_to = ะัะตะธะผะตะฝัะฒะฐะฝะต ะพั "%s" ะฝะฐ:
+branch.create_success = ะะปะพะฝัั โ%sโ ะต ััะทะดะฐะดะตะฝ.
+branch.deletion_success = ะะปะพะฝัั โ%sโ ะต ะธะทััะธั.
+branch.deletion_failed = ะะตััะฟะตัะฝะพ ะธะทััะธะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ โ%sโ.
+branch.rename_branch_to = ะัะตะธะผะตะฝัะฒะฐะฝะต ะพั โ%sโ ะฝะฐ:
settings.web_hook_name_msteams = Microsoft Teams
settings.web_hook_name_dingtalk = DingTalk
issues.error_removing_due_date = ะะตััะฟะตัะฝะพ ะฟัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ ะบัะฐะนะฝะธั ััะพะบ.
@@ -963,9 +988,9 @@ settings.web_hook_name_forgejo = Forgejo
release.tag_already_exist = ะะตัะต ัััะตััะฒัะฒะฐ ะผะฐัะบะตั ั ัะพะฒะฐ ะธะผะต.
branch.name = ะะผะต ะฝะฐ ะบะปะพะฝะฐ
settings.rename_branch = ะัะตะธะผะตะฝัะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ
-branch.restore_failed = ะะตััะฟะตัะฝะพ ะฒัะทััะฐะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะบะปะพะฝ "%s".
-branch.download = ะะทัะตะณะปัะฝะต ะฝะฐ ะบะปะพะฝะฐ "%s"
-branch.rename = ะัะตะธะผะตะฝัะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ "%s"
+branch.restore_failed = ะะตััะฟะตัะฝะพ ะฒัะทััะฐะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ โ%sโ.
+branch.download = ะะทัะตะณะปัะฝะต ะฝะฐ ะบะปะพะฝะฐ โ%sโ
+branch.rename = ะัะตะธะผะตะฝัะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ โ%sโ
empty_message = ะ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต ะฝัะผะฐ ััะดััะถะฐะฝะธะต.
open_with_editor = ะัะฒะฐััะฝะต ั %s
search.search_repo = ะขัััะตะฝะต ะฒ ั
ัะฐะฝะธะปะธัะตัะพ
@@ -973,11 +998,11 @@ search.results = ะ ะตะทัะปัะฐัะธ ะพั ััััะตะฝะตัะพ ะฝะฐ "%s" ะฒ ะธะฝััััะบัะธะธัะต ะทะฐ ะบะพะผะฐะฝะดะฝะธั ัะตะด .`
+pulls.cmd_instruction_hint = ะะธะถัะต ะธะฝััััะบัะธะธัะต ะทะฐ ะบะพะผะฐะฝะดะฝะธั ัะตะด
pulls.showing_only_single_commit = ะะพะบะฐะทะฐะฝะธ ัะฐ ัะฐะผะพ ะฟัะพะผะตะฝะธัะต ะฒ ะฟะพะดะฐะฒะฐะฝะต %[1]s
issues.lock_no_reason = ะทะฐะบะปััะธ ะธ ะพะณัะฐะฝะธัะธ ะพะฑััะถะดะฐะฝะตัะพ ะดะพ ัััััะดะฝะธัะธ %s
pulls.expand_files = ะ ะฐะทะณัะฒะฐะฝะต ะฝะฐ ะฒัะธัะบะธ ัะฐะนะปะพะฒะต
-pulls.title_desc_few = ะธัะบะฐ ะดะฐ ัะปะตะต %[1]d ะฟะพะดะฐะฒะฐะฝะธั ะพั %[2]s
ะฒ %[3]s
+pulls.title_desc_few = ะธัะบะฐ ะดะฐ ัะปะตะต %[1]d ะฟะพะดะฐะฒะฐะฝะธั ะพั %[2]s
ะฒ %[3]s
issues.content_history.deleted = ะธะทััะธัะพ
activity.git_stats_exclude_merges = ะก ะธะทะบะปััะตะฝะธะต ะฝะฐ ัะปะธะฒะฐะฝะธััะฐ,
activity.navbar.pulse = ะะพัะปะตะดะฝะฐ ะดะตะนะฝะพัั
@@ -997,11 +1022,11 @@ pulls.collapse_files = ะกะฒะธะฒะฐะฝะต ะฝะฐ ะฒัะธัะบะธ ัะฐะนะปะพะฒะต
pulls.show_all_commits = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะฒัะธัะบะธ ะฟะพะดะฐะฒะฐะฝะธั
diff.whitespace_button = ะัะฐะทะฝะธ ะทะฝะฐัะธ
issues.content_history.edited = ัะตะดะฐะบัะธัะฐะฝะพ
-pulls.title_desc_one = ะธัะบะฐ ะดะฐ ัะปะตะต %[1]d ะฟะพะดะฐะฒะฐะฝะต ะพั %[2]s
ะฒ %[3]s
+pulls.title_desc_one = ะธัะบะฐ ะดะฐ ัะปะตะต %[1]d ะฟะพะดะฐะฒะฐะฝะต ะพั %[2]s
ะฒ %[3]s
pulls.showing_specified_commit_range = ะะพะบะฐะทะฐะฝะธ ัะฐ ัะฐะผะพ ะฟัะพะผะตะฝะธัะต ะผะตะถะดั %[1]s..%[2]s
pulls.merged_title_desc_one = ัะปั %[1]d ะฟะพะดะฐะฒะฐะฝะต ะพั %[2]s
ะฒ %[3]s
%[4]s
pulls.no_merge_access = ะะต ััะต ัะฟัะปะฝะพะผะพัะตะฝะธ ะทะฐ ัะปะธะฒะฐะฝะต ะฝะฐ ัะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต.
-activity.navbar.code_frequency = ะงะตััะพัะฐ ะฝะฐ ะบะพะดะฐ
+activity.navbar.code_frequency = ะงะตััะพัะฐ ะฝะฐ ะฟัะพะผะตะฝะธัะต
activity.git_stats_pushed_1 = ะต ะธะทัะปะฐัะบะฐะป
activity.git_stats_push_to_branch = ะบัะผ %s ะธ
contributors.contribution_type.commits = ะะพะดะฐะฒะฐะฝะธั
@@ -1062,11 +1087,11 @@ pulls.commit_ref_at = `ัะฟะพะผะตะฝะฐ ัะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต
issues.change_ref_at = `ะฟัะพะผะตะฝะธ ะฟัะตะฟัะฐัะบะฐัะฐ ะพั %s ะฝะฐ %s %s`
diff.review.reject = ะะพะธัะบะฒะฐะฝะต ะฝะฐ ะฟัะพะผะตะฝะธ
diff.bin_not_shown = ะะฒะพะธัะฝะธัั ัะฐะนะป ะฝะต ะต ะฟะพะบะฐะทะฐะฝ.
-settings.units.units = ะะปะตะผะตะฝัะธ ะฝะฐ ั
ัะฐะฝะธะปะธัะตัะพ
+settings.units.units = ะะปะตะผะตะฝัะธ
settings.delete_notices_fork_1 = - ะ ะฐะทะบะปะพะฝะตะฝะธััะฐ ะฝะฐ ัะพะฒะฐ ั
ัะฐะฝะธะปะธัะต ัะต ััะฐะฝะฐั ะฝะตะทะฐะฒะธัะธะผะธ ัะปะตะด ะธะทััะธะฒะฐะฝะต.
-settings.actions_desc = ะะบะปััะฒะฐะฝะต ะฝะฐ ะธะฝัะตะณัะธัะฐะฝะธัะต CI/CD pipelines ั Forgejo ะะตะนััะฒะธั
+settings.actions_desc = ะะบะปััะฒะฐะฝะต ะฝะฐ ะธะฝัะตะณัะธัะฐะฝะธัะต CI/CD pipelines ั Forgejo Actions
settings.packages_desc = ะะบะปััะฒะฐะฝะต ะฝะฐ ัะตะณะธััััะฐ ะฝะฐ ะฟะฐะบะตัะธัะต ะทะฐ ั
ัะฐะฝะธะปะธัะตัะพ
-settings.units.add_more = ะะพะฑะฐะฒัะฝะต...
+settings.units.add_more = ะะบะปััะฒะฐะฝะต ะฝะฐ ะฟะพะฒะตัะต
settings.use_external_issue_tracker = ะะทะฟะพะปะทะฒะฐะฝะต ะฝะฐ ะฒัะฝัะตะฝ ััะฐะบะตั ะทะฐ ะทะฐะดะฐัะธ
settings.releases_desc = ะะบะปััะฒะฐะฝะต ะฝะฐ ะธะทะดะฐะฝะธััะฐ ะทะฐ ั
ัะฐะฝะธะปะธัะตัะพ
settings.projects_desc = ะะบะปััะฒะฐะฝะต ะฝะฐ ะฟัะพะตะบัะธัะต ะทะฐ ั
ัะฐะฝะธะปะธัะตัะพ
@@ -1095,7 +1120,7 @@ pulls.reject_count_1 = %d ะฟะพะธัะบะฐะฝะฐ ะฟัะพะผัะฝะฐ
issues.review.show_resolved = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ัะตัะตะฝะพ
issues.review.hide_resolved = ะกะบัะธะฒะฐะฝะต ะฝะฐ ัะตัะตะฝะพ
issues.review.resolve_conversation = ะ ะตัะฐะฒะฐะฝะต ะฝะฐ ะพะฑััะถะดะฐะฝะตัะพ
-diff.comment.markdown_info = ะะพะดะดััะถะฐ ัะต ััะธะปะธะทะธัะฐะฝะต ั markdown.
+diff.comment.markdown_info = ะะพะดะดััะถะฐ ัะต ััะธะปะธะทะธัะฐะฝะต ั ะะฐัะบะดะฐัะฝ.
diff.file_suppressed = ะ ะฐะทะปะธะบะธัะต ะฝะต ัะฐ ะฟะพะบะฐะทะฐะฝะธ, ะทะฐัะพัะพ ัะฐ ัะฒััะดะต ะผะฝะพะณะพ
pulls.reject_count_n = %d ะฟะพะธัะบะฐะฝะธ ะฟัะพะผะตะฝะธ
settings.pulls.default_allow_edits_from_maintainers = ะะพะทะฒะพะปัะฒะฐะฝะต ะฝะฐ ัะตะดะฐะบัะธะธ ะพั ะฟะพะดะดััะถะฐัะธัะต ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต
@@ -1113,19 +1138,19 @@ issues.filter_type.review_requested = ะะพะธัะบะฐะฝะธ ัะตัะตะฝะทะธะธ
issues.review.review = ะ ะตัะตะฝะทะธั
issues.review.comment = ัะตัะตะฝะทะธัะฐ %s
branch.deleted_by = ะะทััะธั ะพั %s
-branch.restore = ะัะทััะฐะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ "%s"
+branch.restore = ะัะทััะฐะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ โ%sโ
archive.title_date = ะขะพะฒะฐ ั
ัะฐะฝะธะปะธัะต ะต ะฐัั
ะธะฒะธัะฐะฝะพ ะฝะฐ %s. ะะพะถะตัะต ะดะฐ ะฟัะตะณะปะตะถะดะฐัะต ัะฐะนะปะพะฒะต ะธ ะดะฐ ะณะพ ะบะปะพะฝะธัะฐัะต, ะฝะพ ะฝะต ะผะพะถะตัะต ะดะฐ ะธะทัะปะฐัะบะฒะฐัะต ะธะปะธ ะพัะฒะฐัััะต ะทะฐะดะฐัะธ ะธะปะธ ะทะฐัะฒะบะธ ะทะฐ ัะปะธะฒะฐะฝะต.
release.download_count_one = %s ะธะทัะตะณะปัะฝะต
release.download_count_few = %s ะธะทัะตะณะปัะฝะธั
-branch.restore_success = ะะปะพะฝัั "%s" ะต ะฒัะทััะฐะฝะพะฒะตะฝ.
-tag.create_tag_from = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะฝะพะฒ ะผะฐัะบะตั ะพั "%s"
+branch.restore_success = ะะปะพะฝัั โ%sโ ะต ะฒัะทััะฐะฝะพะฒะตะฝ.
+tag.create_tag_from = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะฝะพะฒ ะผะฐัะบะตั ะพั โ%sโ
branch.create_new_branch = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะบะปะพะฝ ะพั ะบะปะพะฝ:
pulls.status_checks_show_all = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะฒัะธัะบะธ ะฟัะพะฒะตัะบะธ
size_format = %[1]s: %[2]s; %[3]s: %[4]s
pulls.filter_changes_by_commit = ะคะธะปััะธัะฐะฝะต ะฟะพ ะฟะพะดะฐะฒะฐะฝะต
-issues.ref_closing_from = `ัะฟะพะผะตะฝะฐ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต %[4]s, ะบะพััะพ ัะต ะทะฐัะฒะพัะธ ัะฐะทะธ ะทะฐะดะฐัะฐ %[2]s `
+issues.ref_closing_from = `ัะฟะพะผะตะฝะฐ ัะฐะทะธ ะทะฐะดะฐัะฐ ะฒ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต %[4]s, ะบะพััะพ ัะต ั ะทะฐัะฒะพัะธ , %[2]s `
issues.ref_from = `ะพั %[1]s`
-issues.ref_reopening_from = `ัะฟะพะผะตะฝะฐ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต %[4]s, ะบะพััะพ ัะต ะพัะฒะพัะธ ะฝะฐะฝะพะฒะพ ัะฐะทะธ ะทะฐะดะฐัะฐ %[2]s `
+issues.ref_reopening_from = `ัะฟะพะผะตะฝะฐ ัะฐะทะธ ะทะฐะดะฐัะฐ ะฒ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต %[4]s, ะบะพััะพ ัะต ั ะพัะฒะพัะธ ะฝะฐะฝะพะฒะพ , %[2]s `
issues.draft_title = ะงะตัะฝะพะฒะฐ
pulls.reopen_to_merge = ะะพะปั, ะพัะฒะพัะตัะต ะฝะฐะฝะพะฒะพ ัะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต, ะทะฐ ะดะฐ ะธะทะฒัััะธัะต ัะปะธะฒะฐะฝะต.
pulls.cant_reopen_deleted_branch = ะขะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต ะฝะต ะผะพะถะต ะดะฐ ะฑัะดะต ะพัะฒะพัะตะฝะฐ ะฝะฐะฝะพะฒะพ, ะทะฐัะพัะพ ะบะปะพะฝัั ะต ะธะทััะธั.
@@ -1134,6 +1159,137 @@ pulls.status_checks_failure = ะัะบะพะธ ะฟัะพะฒะตัะบะธ ัะฐ ะฝะตััะฟะตัะฝ
issues.review.add_review_request = ะฟะพะธัะบะฐ ัะตัะตะฝะทะธั ะพั %s %s
wiki.no_search_results = ะัะผะฐ ัะตะทัะปัะฐัะธ
wiki.search = ะขัััะตะฝะต ะฒ ัะธะบะธัะพ
+issues.author.tooltip.pr = ะขะพะทะธ ะฟะพััะตะฑะธัะตะป ะต ะฐะฒัะพััั ะฝะฐ ัะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต.
+issues.author.tooltip.issue = ะขะพะทะธ ะฟะพััะตะฑะธัะตะป ะต ะฐะฒัะพััั ะฝะฐ ัะฐะทะธ ะทะฐะดะฐัะฐ.
+issues.review.option.hide_outdated_comments = ะกะบัะธะฒะฐะฝะต ะฝะฐ ะพััะฐัะตะปะธ ะบะพะผะตะฝัะฐัะธ
+file.title = %s ะฒ %s
+issues.review.option.show_outdated_comments = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะพััะฐัะตะปะธ ะบะพะผะตะฝัะฐัะธ
+issues.content_history.delete_from_history_confirm = ะะฐ ัะต ะธะทััะธะต ะปะธ ะพั ะธััะพัะธััะฐ?
+project = ะัะพะตะบัะธ
+issues.content_history.delete_from_history = ะะทััะธะฒะฐะฝะต ะพั ะธััะพัะธััะฐ
+n_release_few = %s ะธะทะดะฐะฝะธั
+n_release_one = %s ะธะทะดะฐะฝะธะต
+editor.cannot_edit_non_text_files = ะะฒะพะธัะฝะธ ัะฐะนะปะพะฒะต ะฝะต ะผะพะณะฐั ะดะฐ ัะต ัะตะดะฐะบัะธัะฐั ะฟัะตะท ัะตะฑ ะธะฝัะตััะตะนัะฐ.
+settings.mirror_settings.push_mirror.copy_public_key = ะะพะฟะธัะฐะฝะต ะฝะฐ ะฟัะฑะปะธัะฝะธั ะบะปัั
+activity.published_tag_label = ะะฐัะบะตั
+activity.published_prerelease_label = ะัะตะดะฒ. ะธะทะดะฐะฝะธะต
+branch.create_branch = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะบะปะพะฝ %s
+no_eol.text = ะะธะฟัะฒะฐ EOL
+no_eol.tooltip = ะขะพะทะธ ัะฐะนะป ะฝะต ััะดััะถะฐ ัะธะฝะฐะปะตะฝ ะทะฝะฐะบ ะทะฐ ะบัะฐะน ะฝะฐ ัะตะดะฐ.
+tag.create_tag = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะผะฐัะบะตั %s
+milestones.filter_sort.name = ะะผะต
+mirror_public_key = ะัะฑะปะธัะตะฝ SSH ะบะปัั
+diff.file_after = ะกะปะตะด
+find_tag = ะะฐะผะธัะฐะฝะต ะฝะฐ ะผะฐัะบะตั
+diff.file_before = ะัะตะดะธ
+diff.file_image_height = ะะธัะพัะธะฝะฐ
+contributors.contribution_type.filter_label = ะขะธะฟ ะฟัะธะฝะพั:
+diff.show_file_tree = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ัะฐะนะปะพะฒะพัะพ ะดััะฒะพ
+diff.hide_file_tree = ะกะบัะธะฒะฐะฝะต ะฝะฐ ัะฐะนะปะพะฒะพัะพ ะดััะฒะพ
+tag.ahead.target = ะฒ %s ัะปะตะด ัะพะทะธ ะผะฐัะบะตั
+diff.file_image_width = ะจะธัะพัะธะฝะฐ
+activity.unresolved_conv_label = ะัะฒะพัะตะฝะพ
+invisible_runes_line = `ะขะพะทะธ ัะตะด ััะดััะถะฐ ะฝะตะฒะธะดะธะผะธ ะฃะฝะธะบะพะด ะทะฝะฐัะธ`
+code.desc = ะะพัััะฟ ะดะพ ะฟัะพะณัะฐะผะฝะธั ะบะพะด, ัะฐะนะปะพะฒะตัะต, ะฟะพะดะฐะฒะฐะฝะธััะฐ ะธ ะบะปะพะฝะพะฒะตัะต.
+settings.branches.update_default_branch = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ ััะฐะฝะดะฐััะฝะธั ะบะปะพะฝ
+settings.default_branch_desc = ะะทะฑะตัะตัะต ััะฐะฝะดะฐััะตะฝ ะบะปะพะฝ ะทะฐ ั
ัะฐะฝะธะปะธัะตัะพ, ะทะฐ ะทะฐัะฒะบะธ ะทะฐ ัะปะธะฒะฐะฝะต ะธ ะฟะพะดะฐะฒะฐะฝะธั ะฝะฐ ะบะพะด:
+settings.transfer.button = ะัะตั
ะฒััะปัะฝะต ะฝะฐ ะฟัะธัะตะถะฐะฝะธะตัะพ
+settings.transfer.modal.title = ะัะตั
ะฒััะปัะฝะต ะฝะฐ ะฟัะธัะตะถะฐะฝะธะตัะพ
+ambiguous_runes_line = `ะขะพะทะธ ัะตะด ััะดััะถะฐ ะดะฒััะผะธัะปะตะฝะธ ะฃะฝะธะบะพะด ะทะฝะฐัะธ`
+ambiguous_character = `%[1]c [U+%04[1]X] ะผะพะถะต ะดะฐ ะฑัะดะต ะพะฑััะบะฐะฝ ั %[2]c [U+%04[2]X]`
+invisible_runes_header = `ะขะพะทะธ ัะฐะนะป ััะดััะถะฐ ะฝะตะฒะธะดะธะผะธ ะฃะฝะธะบะพะด ะทะฝะฐัะธ`
+issues.all_title = ะะฑัะพ
+issues.new.assign_to_me = ะัะทะปะฐะณะฐะฝะต ะฝะฐ ะผะตะฝ
+ext_wiki = ะัะฝัะฝะพ ัะธะบะธ
+ext_issues = ะัะฝัะฝะธ ะทะฐะดะฐัะธ
+readme_helper = ะะทะฑะตัะตัะต ัะฐะฑะปะพะฝ ะทะฐ ัะฐะนะป README
+settings.event_pull_request_review_desc = ะะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต ะต ะพะดะพะฑัะตะฝะฐ, ะพัั
ะฒััะปะตะฝะฐ ะธะปะธ ัะฐ ะดะพะฑะฐะฒะตะฝะธ ัะตัะตะฝะทะธะพะฝะฝะธ ะบะพะผะตะฝัะฐัะธ.
+settings.event_pull_request_review = ะ ะตัะตะฝะทะธะธ
+issues.filter_sort.relevance = ะกัะพัะฒะตัััะฒะธะต
+settings.confirm_wiki_branch_rename = ะัะตะธะผะตะฝัะฒะฐะฝะต ะฝะฐ ะบะปะพะฝะฐ ะฝะฐ ัะธะบะธัะพ
+settings.webhook.request = ะะฐัะฒะบะฐ
+settings.webhook.response = ะัะณะพะฒะพั
+settings.event_create = ะกัะทะดะฐะฒะฐะฝะต
+settings.event_push_only = ะกัะฑะธัะธั ะฟัะธ ะธะทัะปะฐัะบะฒะฐะฝะต
+settings.event_delete = ะะทััะธะฒะฐะฝะต
+settings.event_header_repository = ะกัะฑะธัะธั ะทะฐ ั
ัะฐะฝะธะปะธัะตัะพ
+settings.event_fork_desc = ะฅัะฐะฝะธะปะธัะต ะต ัะฐะทะบะปะพะฝะตะฝะพ.
+settings.event_fork = ะ ะฐะทะบะปะพะฝัะฒะฐะฝะต
+settings.event_wiki_desc = ะฃะธะบะธ ัััะฐะฝะธัะฐ ะต ััะทะดะฐะดะตะฝะฐ, ะฟัะตะธะผะตะฝัะฒะฐะฝะฐ, ัะตะดะฐะบัะธัะฐะฝะฐ ะธะปะธ ะธะทััะธัะฐ.
+settings.event_issue_milestone = ะัะฐะฟะธ
+settings.event_pull_request_milestone_desc = ะัะฐะฟ ะต ะดะพะฑะฐะฒะตะฝ, ะฟัะตะผะฐั
ะฝะฐั ะธะปะธ ะธะทะผะตะฝะตะฝ.
+settings.event_pull_request_label_desc = ะัะธะบะตัะธ ะฝะฐ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต ัะฐ ะดะพะฑะฐะฒะตะฝะธ ะธะปะธ ะฟัะตะผะฐั
ะฝะฐัะธ.
+settings.event_pull_request_merge = ะกะปะธะฒะฐะฝะต ะฝะฐ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต
+settings.archive.tagsettings_unavailable = ะะฐัััะพะนะบะธัะต ะทะฐ ะผะฐัะบะตัะธ ะฝะต ัะฐ ะฝะฐะปะธัะฝะธ ะฒ ะฐัั
ะธะฒะธัะฐะฝะธ ั
ัะฐะฝะธะปะธัะฐ.
+settings.event_desc = ะะฐะดะตะนััะฒะฐะฝะต ะฟัะธ:
+settings.event_create_desc = ะะปะพะฝ ะธะปะธ ะผะฐัะบะตั ะต ััะทะดะฐะดะตะฝ.
+generate_from = ะะตะฝะตัะธัะฐะฝะต ะพั
+settings.event_push_desc = Git ะธะทัะปะฐัะบะฒะฐะฝะต ะบัะผ ั
ัะฐะฝะธะปะธัะต.
+settings.event_package = ะะฐะบะตั
+settings.event_pull_request_label = ะัะธะบะตัะธ
+settings.event_pull_request_assign_desc = ะะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต ะต ะฒัะทะปะพะถะตะฝะฐ ะธะปะธ ะพัะฒัะทะปะพะถะตะฝะฐ.
+settings.event_choose = ะะตััะพะฝะฐะปะธะทะธัะฐะฝะธ ััะฑะธัะธัโฆ
+settings.event_header_issue = ะกัะฑะธัะธั ะฟัะธ ะทะฐะดะฐัะธ
+fork_no_valid_owners = ะขะพะฒะฐ ั
ัะฐะฝะธะปะธัะต ะฝะต ะผะพะถะต ะดะฐ ะฑัะดะต ัะฐะทะบะปะพะฝะตะฝะพ, ะทะฐัะพัะพ ะฝัะผะฐ ะฒะฐะปะธะดะฝะธ ะฟัะธัะตะถะฐัะตะปะธ.
+settings.unarchive.text = ะ ะฐะทะฐัั
ะธะฒะธัะฐะฝะตัะพ ะฝะฐ ั
ัะฐะฝะธะปะธัะต ัะต ะฒัะทััะฐะฝะพะฒะธ ัะฟะพัะพะฑะฝะพัััะฐ ะผั ะดะฐ ะฟะพะปััะฐะฒะฐ ะฟะพะดะฐะฒะฐะฝะธั ะธ ะธะทัะปะฐัะบะฒะฐะฝะธั, ะบะฐะบัะพ ะธ ะฝะพะฒะธ ะทะฐะดะฐัะธ ะธ ะทะฐัะฒะบะธ ะทะฐ ัะปะธะฒะฐะฝะต.
+settings.archive.branchsettings_unavailable = ะะฐัััะพะนะบะธัะต ะทะฐ ะบะปะพะฝะพะฒะต ะฝะต ัะฐ ะฝะฐะปะธัะฝะธ ะฒ ะฐัั
ะธะฒะธัะฐะฝะธ ั
ัะฐะฝะธะปะธัะฐ.
+settings.event_send_everything = ะัะธัะบะธ ััะฑะธัะธั
+settings.event_pull_request_approvals = ะะดะพะฑัะตะฝะธั ะฝะฐ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต
+release.invalid_external_url = ะะตะฒะฐะปะธะดะตะฝ ะฒัะฝัะตะฝ URL ะฐะดัะตั: "%s"
+settings.event_delete_desc = ะะปะพะฝ ะธะปะธ ะผะฐัะบะตั ะต ะธะทััะธั.
+settings.discord_icon_url = URL ะฐะดัะตั ะฝะฐ ะธะบะพะฝะบะฐ
+settings.discord_icon_url.exceeds_max_length = URL ะฐะดัะตััั ะฝะฐ ะธะบะพะฝะบะฐัะฐ ัััะฑะฒะฐ ะดะฐ ะต ะฟะพ-ะผะฐะปัะบ ะธะปะธ ัะฐะฒะตะฝ ะฝะฐ 2048 ะทะฝะฐะบะฐ
+settings.event_push = ะะทัะปะฐัะบะฒะฐะฝะต
+settings.event_repository_desc = ะฅัะฐะฝะธะปะธัะต ะต ััะทะดะฐะดะตะฝะพ ะธะปะธ ะธะทััะธัะพ.
+settings.slack_icon_url = URL ะฐะดัะตั ะฝะฐ ะธะบะพะฝะบะฐ
+settings.event_issue_comment = ะะพะผะตะฝัะฐัะธ
+settings.event_pull_request_desc = ะะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต ะต ะพัะฒะพัะตะฝะฐ, ะทะฐัะฒะพัะตะฝะฐ, ะพัะฒะพัะตะฝะฐ ะฝะฐะฝะพะฒะพ ะธะปะธ ัะตะดะฐะบัะธัะฐะฝะฐ.
+settings.event_issue_comment_desc = ะะพะผะตะฝัะฐั ะฝะฐ ะทะฐะดะฐัะฐ ะต ััะทะดะฐะดะตะฝ, ัะตะดะฐะบัะธัะฐะฝ ะธะปะธ ะธะทััะธั.
+settings.event_release_desc = ะะทะดะฐะฝะธะต ะต ะฟัะฑะปะธะบัะฒะฐะฝะพ, ะพะฑะฝะพะฒะตะฝะพ ะธะปะธ ะธะทััะธัะพ ะฒ ั
ัะฐะฝะธะปะธัะต.
+settings.event_pull_request_review_request = ะัะบะฐะฝะธั ะทะฐ ัะตัะตะฝะทะธั
+settings.event_pull_request_enforcement = ะัะธะฝัะดะธัะตะปะฝะพ ะธะทะฟัะปะฝะตะฝะธะต
+diff.git-notes.remove-header = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ ะฑะตะปะตะถะบะฐัะฐ
+diff.git-notes.add = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะฑะตะปะตะถะบะฐ
+settings.event_pull_request_assign = ะัะทะปะฐะณะฐะฝะต
+new_advanced_expand = ะฉัะฐะบะฝะตัะต ะทะฐ ัะฐะทะณัะฒะฐะฝะต
+new_advanced = ะ ะฐะทัะธัะตะฝะธ ะฝะฐัััะพะนะบะธ
+new_from_template = ะะทะฟะพะปะทะฒะฐะฝะต ะฝะฐ ัะฐะฑะปะพะฝ
+new_from_template_description = ะะพะถะตัะต ะดะฐ ะธะทะฑะตัะตัะต ัััะตััะฒัะฒะฐัะพ ัะฐะฑะปะพะฝะฝะพ ั
ัะฐะฝะธะปะธัะต ะฒ ัะฐะทะธ ะธะฝััะฐะฝัะธั ะธ ะดะฐ ะฟัะธะปะพะถะธัะต ะฝะตะณะพะฒะธัะต ะฝะฐัััะพะนะบะธ.
+settings.event_pull_request_comment = ะะพะผะตะฝัะฐัะธ
+repo_gitignore_helper_desc = ะะทะฑะตัะตัะต ะบะพะธ ัะฐะนะปะพะฒะต ะดะฐ ะฝะต ัะต ะฟัะพัะปะตะดัะฒะฐั ะพั ัะฟะธััะบ ั ัะฐะฑะปะพะฝะธ ะทะฐ ะพะฑะธัะฐะนะฝะธัะต ะตะทะธัะธ. ะขะธะฟะธัะฝะธัะต ะฐััะตัะฐะบัะธ, ะณะตะฝะตัะธัะฐะฝะธ ะพั ะธะฝััััะผะตะฝัะธัะต ะทะฐ ะธะทะณัะฐะถะดะฐะฝะต, ัะฐ ะฒะบะปััะตะฝะธ ะฒ .gitignore ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต.
+object_format_helper = ะคะพัะผะฐั ะฝะฐ ะพะฑะตะบัะธัะต ะฝะฐ ั
ัะฐะฝะธะปะธัะตัะพ. ะะต ะผะพะถะต ะดะฐ ัะต ะฟัะพะผะตะฝั ะฟะพ-ะบััะฝะพ. SHA1 ะต ะฝะฐะน-ััะฒะผะตััะธะผ.
+issues.num_reviews_one = %d ัะตัะตะฝะทะธั
+settings.event_pull_request = ะะทะผะตะฝะตะฝะธะต
+settings.event_issue_label = ะัะธะบะตัะธ
+settings.event_issue_assign = ะัะทะปะฐะณะฐะฝะต
+settings.event_header_pull_request = ะกัะฑะธัะธั ะฟัะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต
+settings.event_issue_milestone_desc = ะัะฐะฟ ะต ะดะพะฑะฐะฒะตะฝ, ะฟัะตะผะฐั
ะฝะฐั ะธะปะธ ะธะทะผะตะฝะตะฝ.
+settings.event_issue_label_desc = ะัะธะบะตัะธ ะฝะฐ ะทะฐะดะฐัะฐ ัะฐ ะดะพะฑะฐะฒะตะฝะธ ะธะปะธ ะฟัะตะผะฐั
ะฝะฐัะธ.
+settings.event_issues_desc = ะะฐะดะฐัะฐ ะต ะพัะฒะพัะตะฝะฐ, ะทะฐัะฒะพัะตะฝะฐ, ะพัะฒะพัะตะฝะฐ ะฝะฐะฝะพะฒะพ ะธะปะธ ัะตะดะฐะบัะธัะฐะฝะฐ.
+settings.webhook.headers = ะะฐะณะปะฐะฒะบะธ
+settings.webhook.body = ะขัะปะพ
+settings.event_pull_request_sync = ะกะธะฝั
ัะพะฝะธะทะธัะฐะฝะพ
+settings.event_pull_request_sync_desc = ะะปะพะฝัั ะต ะพะฑะฝะพะฒะตะฝ ะฐะฒัะพะผะฐัะธัะฝะพ ั ัะตะปะตะฒะธั ะบะปะพะฝ.
+settings.event_package_desc = ะะฐะบะตั ะต ััะทะดะฐะดะตะฝ ะธะปะธ ะธะทััะธั ะฒ ั
ัะฐะฝะธะปะธัะต.
+template_description = ะจะฐะฑะปะพะฝะฝะธัะต ั
ัะฐะฝะธะปะธัะฐ ะฟะพะทะฒะพะปัะฒะฐั ะฝะฐ ะฟะพััะตะฑะธัะตะปะธัะต ะดะฐ ะณะตะฝะตัะธัะฐั ะฝะพะฒะธ ั
ัะฐะฝะธะปะธัะฐ ััั ัััะฐัะฐ ััััะบัััะฐ ะฝะฐ ะดะธัะตะบัะพัะธะธัะต, ัะฐะนะปะพะฒะต ะธ ะพะฟัะธะพะฝะฐะปะฝะธ ะฝะฐัััะพะนะบะธ.
+auto_init_description = ะะพััะฐะฒะตัะต ะฝะฐัะฐะปะพัะพ ะฝะฐ Git ะธััะพัะธััะฐ ั README ะธ ะฟะพ ะธะทะฑะพั ะดะพะฑะฐะฒะตัะต ัะฐะนะปะพะฒะต License ะธ .gitignore.
+pulls.sign_in_require = ะะปะตะทัะต , ะทะฐ ะดะฐ ััะทะดะฐะดะตัะต ะฝะพะฒะฐ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต.
+issues.num_reviews_few = %d ัะตัะตะฝะทะธะธ
+diff.git-notes.remove-body = ะขะฐะทะธ ะฑะตะปะตะถะบะฐ ัะต ะฑัะดะต ะฟัะตะผะฐั
ะฝะฐัะฐ.
+issues.review.add_remove_review_requests = ะฟะพะธัะบะฐ ัะตัะตะฝะทะธะธ ะพั %[1]s ะธ ะฟัะตะผะฐั
ะฝะฐ ะทะฐัะฒะบะธ ะทะฐ ัะตัะตะฝะทะธั ะทะฐ %[2]s %[3]s
+form.name_pattern_not_allowed = ะจะฐะฑะปะพะฝัั "%s" ะฝะต ะต ัะฐะทัะตัะตะฝ ะฒ ะธะผะต ะฝะฐ ั
ัะฐะฝะธะปะธัะต.
+settings.wiki_rename_branch_main_notices_2 = ะขะพะฒะฐ ัะต ะฟัะตะธะผะตะฝัะฒะฐ ะฟะตัะผะฐะฝะตะฝัะฝะพ ะฒัััะตัะฝะธั ะบะปะพะฝ ะฝะฐ ัะธะบะธัะพ ะฝะฐ ั
ัะฐะฝะธะปะธัะตัะพ %s. ะกััะตััะฒัะฒะฐัะธัะต ะธะทัะตะณะปัะฝะธั ัะต ัััะฑะฒะฐ ะดะฐ ะฑัะดะฐั ะพะฑะฝะพะฒะตะฝะธ.
+settings.event_pull_request_milestone = ะัะฐะฟะธ
+settings.event_pull_request_comment_desc = ะะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต ะต ััะทะดะฐะดะตะฝะฐ, ัะตะดะฐะบัะธัะฐะฝะฐ ะธะปะธ ะธะทััะธัะฐ.
+settings.event_issue_assign_desc = ะะฐะดะฐัะฐ ะต ะฒัะทะปะพะถะตะฝะฐ ะธะปะธ ะพัะฒัะทะปะพะถะตะฝะฐ.
+settings.event_pull_request_review_request_desc = ะ ะตัะตะฝะทะธั ะฝะฐ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต ะต ะฟะพะธัะบะฐะฝะฐ ะธะปะธ ะต ะฟัะตะผะฐั
ะฝะฐัะฐ.
+generate_repo = ะะตะฝะตัะธัะฐะฝะต ะฝะฐ ั
ัะฐะฝะธะปะธัะต
+default_branch_helper = ะกัะฐะฝะดะฐััะฝะธัั ะบะปะพะฝ ะต ะพัะฝะพะฒะฝะธั ะบะปะพะฝ ะทะฐ ะทะฐัะฒะบะธ ะทะฐ ัะปะธะฒะฐะฝะต ะธ ะฟะพะดะฐะฒะฐะฝะธั ะฝะฐ ะบะพะด.
+issues.reaction.add = ะะพะฑะฐะฒัะฝะต ะฝะฐ ัะตะฐะบัะธั
+issues.reaction.alt_few = %[1]s ัะตะฐะณะธัะฐ ั %[2]s.
+issues.reaction.alt_many = %[1]s ะธ ะพัะต %[2]d ัะตะฐะณะธัะฐั
ะฐ ั %[3]s.
+issues.reaction.alt_add = ะะพะฑะฐะฒัะฝะต ะฝะฐ ัะตะฐะบัะธั %[1]s ะบัะผ ะบะพะผะตะฝัะฐัะฐ.
+issues.reaction.alt_remove = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ ัะตะฐะบัะธั %[1]s ะพั ะบะพะผะตะฝัะฐัะฐ.
[modal]
confirm = ะะพัะฒััะถะดะฐะฒะฐะฝะต
@@ -1157,6 +1313,12 @@ buttons.italic.tooltip = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะบัััะธะฒ ัะตะบัั
buttons.link.tooltip = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะฒััะทะบะฐ
buttons.disable_monospace_font = ะะทะบะปััะฒะฐะฝะต ะฝะฐ ัะฐะฒะฝะพัะธัะพะบะธั ััะธัั
buttons.ref.tooltip = ะัะตะฟัะฐัะบะฐ ะบัะผ ะทะฐะดะฐัะฐ ะธะปะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต
+table_modal.label.columns = ะะพะปะพะฝะธ
+table_modal.label.rows = ะ ะตะดะพะฒะต
+table_modal.placeholder.content = ะกัะดััะถะฐะฝะธะต
+table_modal.placeholder.header = ะะฐะณะปะฐะฒะบะฐ
+buttons.new_table.tooltip = ะะพะฑะฐะฒัะฝะต ะฝะฐ ัะฐะฑะปะธัะฐ
+table_modal.header = ะะพะฑะฐะฒัะฝะต ะฝะฐ ัะฐะฑะปะธัะฐ
[org]
teams.write_access = ะะธัะฐะฝะต
@@ -1170,7 +1332,7 @@ settings = ะะฐัััะพะนะบะธ
members.remove.detail = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ %[1]s ะพั %[2]s?
settings.visibility = ะะธะดะธะผะพัั
settings.options = ะัะณะฐะฝะธะทะฐัะธั
-teams.leave.detail = ะะฐะฟััะบะฐะฝะต ะฝะฐ %s?
+teams.leave.detail = ะกะธะณััะฝะธ ะปะธ ััะต, ัะต ะธัะบะฐัะต ะดะฐ ะฝะฐะฟััะฝะตัะต ะตะบะธะฟะฐ โ%sโ?
teams.can_create_org_repo = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ั
ัะฐะฝะธะปะธัะฐ
teams.settings = ะะฐัััะพะนะบะธ
settings.website = ะฃะตะฑัะฐะนั
@@ -1180,7 +1342,7 @@ teams.all_repositories = ะัะธัะบะธ ั
ัะฐะฝะธะปะธัะฐ
teams.update_settings = ะะฑะฝะพะฒัะฒะฐะฝะต ะฝะฐ ะฝะฐัััะพะนะบะธัะต
settings.full_name = ะัะปะฝะพ ะธะผะต
members.leave = ะะฐะฟััะบะฐะฝะต
-members.leave.detail = ะะฐะฟััะบะฐะฝะต ะฝะฐ %s?
+members.leave.detail = ะกะธะณััะฝะธ ะปะธ ััะต, ัะต ะธัะบะฐัะต ะดะฐ ะฝะฐะฟััะฝะตัะต ะพัะณะฐะฝะธะทะฐัะธััะฐ โ%sโ?
teams.read_access = ะงะตัะตะฝะต
org_name_holder = ะะผะต ะฝะฐ ะพัะณะฐะฝะธะทะฐัะธััะฐ
create_org = ะกัะทะดะฐะฒะฐะฝะต ะฝะฐ ะพัะณะฐะฝะธะทะฐัะธั
@@ -1188,7 +1350,7 @@ settings.visibility.public = ะัะฑะปะธัะฝะฐ
settings.visibility.limited_shortname = ะะณัะฐะฝะธัะตะฝะฐ
settings.visibility.private_shortname = ะงะฐััะฝะฐ
settings.permission = ะ ะฐะทัะตัะตะฝะธั
-settings.visibility.limited = ะะณัะฐะฝะธัะตะฝะฐ (ะฒะธะดะธะผะฐ ัะฐะผะพ ะทะฐ ัะดะพััะพะฒะตัะตะฝะธ ะฟะพััะตะฑะธัะตะปะธ)
+settings.visibility.limited = ะะณัะฐะฝะธัะตะฝะฐ (ะฒะธะดะธะผะฐ ัะฐะผะพ ะทะฐ ะฒะปะตะทะปะธ ะฟะพััะตะฑะธัะตะปะธ)
settings.visibility.private = ะงะฐััะฝะฐ (ะฒะธะดะธะผะฐ ัะฐะผะพ ะทะฐ ััะฐััะฝะธัะธัะต ะฒ ะพัะณะฐะฝะธะทะฐัะธััะฐ)
org_name_helper = ะะผะตะฝะฐัะฐ ะฝะฐ ะพัะณะฐะฝะธะทะฐัะธะธัะต ะต ะดะพะฑัะต ะดะฐ ัะฐ ะบัะฐัะบะธ ะธ ะทะฐะฟะพะผะฝััะธ ัะต.
org_full_name_holder = ะัะปะฝะพ ะธะผะต ะฝะฐ ะพัะณะฐะฝะธะทะฐัะธััะฐ
@@ -1230,6 +1392,7 @@ members.member = ะฃัะฐััะฝะธะบ
members.private_helper = ะะฐ ะต ะฒะธะดะธะผ
teams.no_desc = ะขะพะทะธ ะตะบะธะฟ ะฝัะผะฐ ะพะฟะธัะฐะฝะธะต
settings.delete_org_desc = ะขะฐะทะธ ะพัะณะฐะฝะธะทะฐัะธั ัะต ะฑัะดะต ะธะทััะธัะฐ ะฟะตัะผะฐะฝะตะฝัะฝะพ. ะัะพะดัะปะถะฐะฒะฐะฝะต?
+open_dashboard = ะัะฒะฐััะฝะต ะฝะฐ ัะฐะฑะปะพัะพ
[install]
admin_password = ะะฐัะพะปะฐ
@@ -1259,7 +1422,7 @@ mailer_password = SMTP ะฟะฐัะพะปะฐ
disable_gravatar = ะะทะบะปััะฒะฐะฝะต ะฝะฐ Gravatar
smtp_addr = SMTP ั
ะพัั
smtp_port = SMTP ะฟะพัั
-app_name_helper = ะะพะถะตัะต ะดะฐ ะฒัะฒะตะดะตัะต ะธะผะตัะพ ะฝะฐ ะบะพะผะฟะฐะฝะธััะฐ ัะธ ััะบ.
+app_name_helper = ะัะฒะตะดะตัะต ะธะผะตัะพ ะฝะฐ ะธะฝััะฐะฝัะธััะฐ ัะธ ััะบ. ะฉะต ัะต ะฟะพะบะฐะทะฒะฐ ะฝะฐ ะฒััะบะฐ ัััะฐะฝะธัะฐ.
admin_title = ะะฐัััะพะนะบะธ ะฝะฐ ะฐะดะผะธะฝะธัััะฐัะพััะบะธั ะฐะบะฐัะฝั
err_empty_admin_password = ะะดะผะธะฝะธัััะฐัะพััะบะฐัะฐ ะฟะฐัะพะปะฐ ะฝะต ะผะพะถะต ะดะฐ ะฑัะดะต ะฟัะฐะทะฝะฐ.
docker_helper = ะะบะพ ััะฐััะธัะฐัะต Forgejo ะฒ Docker, ะผะพะปั, ะฟัะพัะตัะตัะต ะดะพะบัะผะตะฝัะฐัะธััะฐ ะฟัะตะดะธ ะดะฐ ะฟัะพะผะตะฝะธัะต ะฝะฐัััะพะนะบะธ.
@@ -1268,6 +1431,9 @@ err_empty_admin_email = ะะดะผะธะฝะธัััะฐัะพััะบะธัั ะฐะดัะตั ะฝะฐ ะต
password_algorithm = ะะปะณะพัะธััะผ ะทะฐ ั
ะตั. ะฝะฐ ะฟะฐัะพะปะธัะต
default_keep_email_private = ะกะบัะธะฒะฐะฝะต ะฝะฐ ะฐะดัะตัะธัะต ะฝะฐ ะตะป. ะฟะพัะฐ ะฟะพ ะฟะพะดัะฐะทะฑะธัะฐะฝะต
invalid_password_algorithm = ะะตะฒะฐะปะธะดะตะฝ ะฐะปะณะพัะธััะผ ะทะฐ ั
ะตั. ะฝะฐ ะฟะฐัะพะปะธัะต
+err_admin_name_is_reserved = ะะพััะตะฑะธัะตะปัะบะพัะพ ะธะผะต ะฝะฐ ะฐะดะผะธะฝะธัััะฐัะพัะฐ ะต ะฝะตะฒะฐะปะธะดะฝะพ, ะฟะพััะตะฑะธัะตะปัะบะพัะพ ะธะผะต ะต ัะตะทะตัะฒะธัะฐะฝะพ
+err_admin_name_pattern_not_allowed = ะะพััะตะฑะธัะตะปัะบะพัะพ ะธะผะต ะฝะฐ ะฐะดะผะธะฝะธัััะฐัะพัะฐ ะต ะฝะตะฒะฐะปะธะดะฝะพ, ะฟะพััะตะฑะธัะตะปัะบะพัะพ ะธะผะต ััะพัะฒะตัััะฒะฐ ั ัะตะทะตัะฒะธัะฐะฝ ัะฐะฑะปะพะฝ
+err_admin_name_is_invalid = ะะพััะตะฑะธัะตะปัะบะพัะพ ะธะผะต ะฝะฐ ะฐะดะผะธะฝะธัััะฐัะพัะฐ ะต ะฝะตะฒะฐะปะธะดะฝะพ
[filter]
string.asc = ะ - ะฏ
@@ -1285,13 +1451,28 @@ issue.in_tree_path = ะ %s:
release.note = ะะตะปะตะถะบะฐ:
hi_user_x = ะะดัะฐะฒะตะนัะต %s ,
admin.new_user.user_info = ะะฝัะพัะผะฐัะธั ะทะฐ ะฟะพััะตะฑะธัะตะปั
-register_notify = ะะพะฑัะต ะดะพัะปะธ ะฒัะฒ Forgejo
+register_notify = ะะพะฑัะต ะดะพัะปะธ ะฒัะฒ %s
issue.action.new = @%[1]s ััะทะดะฐะดะต #%[2]d.
issue.action.review = @%[1]s ะบะพะผะตะฝัะธัะฐ ะฒ ัะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต.
issue.action.reopen = @%[1]s ะพัะฒะพัะธ ะฝะฐะฝะพะฒะพ #%[2]d.
issue.action.approve = @%[1]s ะพะดะพะฑัะธ ัะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต.
issue.action.reject = @%[1]s ะฟะพะธัะบะฐ ะฟัะพะผะตะฝะธ ะฒ ัะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต.
register_notify.title = %[1]s, ะดะพะฑัะต ะดะพัะปะธ ะฒ %[2]s
+link_not_working_do_paste = ะะบะพ ะฒััะทะบะฐัะฐ ะฝะต ัะฐะฑะพัะธ, ะพะฟะธัะฐะนัะต ะดะฐ ั ะบะพะฟะธัะฐัะต ะธ ะฟะพััะฐะฒะธัะต ะฒ URL ะปะตะฝัะฐัะฐ ะฝะฐ ะฒะฐัะธั ะฑัะฐัะทัั.
+activate_account = ะะพะปั, ะฐะบัะธะฒะธัะฐะนัะต ัะฒะพั ะฐะบะฐัะฝั
+admin.new_user.subject = ะะพะฒ ะฟะพััะตะฑะธัะตะป %s ัะพะบั-ัะพ ัะต ัะตะณะธัััะธัะฐ
+activate_account.text_1 = ะะดัะฐะฒะตะนัะต, %[1]s , ะฑะปะฐะณะพะดะฐัะธะผ ะฒะธ ะทะฐ ัะตะณะธัััะฐัะธััะฐ ะฒ %[2]s!
+activate_email.text = ะะพะปั, ััะฐะบะฝะตัะต ะฒััั
ั ัะปะตะดะฝะฐัะฐ ะฒััะทะบะฐ, ะทะฐ ะดะฐ ะฟะพัะฒััะดะธัะต ัะฒะพั ะฐะดัะตั ะฝะฐ ะตะป. ะฟะพัะฐ ะฒ ัะฐะผะบะธัะต ะฝะฐ %s :
+activate_email = ะะพัะฒััะดะตัะต ัะฒะพั ะฐะดัะตั ะฝะฐ ะตะป. ะฟะพัะฐ
+activate_account.text_2 = ะะพะปั, ััะฐะบะฝะตัะต ะฒััั
ั ัะปะตะดะฝะฐัะฐ ะฒััะทะบะฐ, ะทะฐ ะดะฐ ะฐะบัะธะฒะธัะฐัะต ัะฒะพั ะฐะบะฐัะฝั ะฒ ัะฐะผะบะธัะต ะฝะฐ %s :
+issue_assigned.issue = @%[1]s ะฒะธ ะฒัะทะปะพะถะธ ะทะฐะดะฐัะฐ %[2]s ะฒ ั
ัะฐะฝะธะปะธัะต %[3]s.
+issue.action.push_n = @%[1]s ะธะทัะปะฐัะบะฐ %[3]d ะฟะพะดะฐะฒะฐะฝะธั ะบัะผ %[2]s
+issue.action.push_1 = @%[1]s ะธะทัะปะฐัะบะฐ %[3]d ะฟะพะดะฐะฒะฐะฝะต ะบัะผ %[2]s
+repo.transfer.subject_to_you = %s ะธัะบะฐ ะดะฐ ะฟัะตั
ะฒััะปะธ ั
ัะฐะฝะธะปะธัะต "%s" ะบัะผ ะฒะฐั
+issue.action.merge = @%[1]s ัะปั #%[2]d ะฒ %[3]s.
+issue_assigned.pull = @%[1]s ะฒะธ ะฒัะทะปะพะถะธ ะทะฐัะฒะบะฐัะฐ ะทะฐ ัะปะธะฒะฐะฝะต %[2]s ะฒ ั
ัะฐะฝะธะปะธัะต %[3]s.
+issue.action.ready_for_review = @%[1]s ะพัะฑะตะปัะทะฐ ัะฐะทะธ ะทะฐัะฒะบะฐ ะทะฐ ัะปะธะฒะฐะฝะต ะบะฐัะพ ะณะพัะพะฒะฐ ะทะฐ ัะตัะตะฝะทะธัะฐะฝะต.
+repo.transfer.subject_to = %s ะธัะบะฐ ะดะฐ ะฟัะตั
ะฒััะปะธ ั
ัะฐะฝะธะปะธัะต "%s" ะบัะผ %s
[user]
joined_on = ะัะธััะตะดะธะฝะตะฝะธ ะฝะฐ %s
@@ -1318,16 +1499,24 @@ email_visibility.private = ะะฐัะธัั ะฐะดัะตั ะฝะฐ ะตะป. ะฟะพัะฐ ะต ะฒะธะด
show_on_map = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ัะพะฒะฐ ะผัััะพ ะฝะฐ ะบะฐััะฐัะฐ
followers_one = %d ะฟะพัะปะตะดะพะฒะฐัะตะป
following_one = %d ัะปะตะดะฒะฐะฝ
+followers.title.few = ะะพัะปะตะดะพะฒะฐัะตะปะธ
+followers.title.one = ะะพัะปะตะดะพะฒะฐัะตะป
+following.title.one = ะกะปะตะดะฒะฐะฝ
+following.title.few = ะกะปะตะดะฒะฐะฝะธ
+public_activity.visibility_hint.self_public = ะะฐัะฐัะฐ ะดะตะนะฝะพัั ะต ะฒะธะดะธะผะฐ ะทะฐ ะฒัะธัะบะธ, ั ะธะทะบะปััะตะฝะธะต ะฝะฐ ะฒะทะฐะธะผะพะดะตะนััะฒะธััะฐ ะฒ ัะฐััะฝะธ ะฟัะพัััะฐะฝััะฒะฐ. ะะพะฝัะธะณััะธัะฐะฝะต .
+form.name_pattern_not_allowed = ะจะฐะฑะปะพะฝัั "%s" ะฝะต ะต ัะฐะทัะตัะตะฝ ะฒ ะฟะพััะตะฑะธัะตะปัะบะพ ะธะผะต.
+form.name_reserved = ะะพััะตะฑะธัะตะปัะบะพัะพ ะธะผะต "%s" ะต ัะตะทะตัะฒะธัะฐะฝะพ.
+public_activity.visibility_hint.self_private_profile = ะะฐัะฐัะฐ ะดะตะนะฝะพัั ะต ะฒะธะดะธะผะฐ ัะฐะผะพ ะทะฐ ะฒะฐั ะธ ะฐะดะผะธะฝะธัััะฐัะพัะธัะต ะฝะฐ ะธะฝััะฐะฝัะธััะฐ, ััะน ะบะฐัะพ ะฒะฐัะธัั ะฟัะพัะธะป ะต ัะฐััะตะฝ. ะะพะฝัะธะณััะธัะฐะฝะต .
[home]
filter = ะััะณะธ ัะธะปััะธ
show_archived = ะัั
ะธะฒะธัะฐะฝะธ
search_repos = ะะฐะผะธัะฐะฝะต ะฝะฐ ั
ัะฐะฝะธะปะธัะตโฆ
my_orgs = ะัะณะฐะฝะธะทะฐัะธะธ
-uname_holder = ะะพััะตะฑ. ะธะผะต ะธะปะธ ะะดัะตั ะฝะฐ ะตะป. ะฟะพัะฐ
+uname_holder = ะะพััะตะฑะธัะตะปัะบะพ ะธะผะต ะธะปะธ ะตะป. ะฟะพัะฐ
my_repos = ะฅัะฐะฝะธะปะธัะฐ
show_both_archived_unarchived = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะธ ะฐัั
ะธะฒะธัะฐะฝะธ ะธ ะฝะตะฐัั
ะธะฒะธัะฐะฝะธ
-feed_of = ะะผะธัะธั ะฝะฐ "%s"
+feed_of = ะะผะธัะธั ะฝะฐ โ%sโ
issues.in_your_repos = ะัะฒ ะฒะฐัะธัะต ั
ัะฐะฝะธะปะธัะฐ
show_both_private_public = ะะพะบะฐะทะฒะฐะฝะต ะฝะฐ ะธ ะฟัะฑะปะธัะฝะธ ะธ ัะฐััะฝะธ
show_only_private = ะะพะบะฐะทะฒะฐะฝะต ัะฐะผะพ ะฝะฐ ัะฐััะฝะธ
@@ -1371,7 +1560,7 @@ systemhooks = ะกะธััะตะผะฝะธ ัะตะฑ-ะบัะบะธ
orgs.new_orga = ะะพะฒะฐ ะพัะณะฐะฝะธะทะฐัะธั
config.https_only = ะกะฐะผะพ HTTPS
users.update_profile_success = ะะพััะตะฑะธัะตะปัะบะธัั ะฐะบะฐัะฝั ะต ะพะฑะฝะพะฒะตะฝ.
-users.new_success = ะะพััะตะฑะธัะตะปัะบะธัั ะฐะบะฐัะฝั "%s" ะต ััะทะดะฐะดะตะฝ.
+users.new_success = ะะพััะตะฑะธัะตะปัะบะธัั ะฐะบะฐัะฝั โ%sโ ะต ััะทะดะฐะดะตะฝ.
users.deletion_success = ะะพััะตะฑะธัะตะปัะบะธัั ะฐะบะฐัะฝั ะต ะธะทััะธั.
last_page = ะะพัะปะตะดะฝะฐ
config.test_email_placeholder = ะะป. ะฟะพัะฐ (ะฝะฐะฟั. test@example.com)
@@ -1414,10 +1603,13 @@ orgs.teams = ะะบะธะฟะธ
orgs.members = ะฃัะฐััะฝะธัะธ
config_settings = ะะฐัััะพะนะบะธ
users.details = ะะพััะตะฑะธัะตะปัะบะธ ะดะฐะฝะฝะธ
+packages.total_size = ะะฑั ัะฐะทะผะตั: %s
+dashboard.new_version_hint = Forgejo %s ะฒะตัะต ะต ะฝะฐะปะธัะตะฝ, ะฒะธะต ะธะทะฟัะปะฝัะฒะฐัะต %s. ะัะพะฒะตัะตัะต ะฑะปะพะณะฐ ะทะฐ ะฟะพะฒะตัะต ะฟะพะดัะพะฑะฝะพััะธ.
+total = ะะฑัะพ: %d
[error]
not_found = ะฆะตะปัะฐ ะฝะต ะผะพะถะต ะดะฐ ะฑัะดะต ะฝะฐะผะตัะตะฝะฐ.
-report_message = ะะบะพ ัะผััะฐัะต, ัะต ัะพะฒะฐ ะต ะณัะตัะบะฐ ะฝะฐ Forgejo, ะผะพะปั, ะฟะพััััะตัะต ะฒ ะทะฐะดะฐัะธัะต ะฝะฐ Codeberg ะธะปะธ ะพัะฒะพัะตัะต ะฝะพะฒะฐ ะทะฐะดะฐัะฐ, ะฐะบะพ ะต ะฝะตะพะฑั
ะพะดะธะผะพ.
+report_message = ะะบะพ ัะผััะฐัะต, ัะต ัะพะฒะฐ ะต ะณัะตัะบะฐ ะฝะฐ Forgejo, ะผะพะปั, ะฟะพััััะตัะต ะฒ ะทะฐะดะฐัะธัะต ะฝะฐ Codeberg ะธะปะธ ะพัะฒะพัะตัะต ะฝะพะฒะฐ ะทะฐะดะฐัะฐ, ะฐะบะพ ะต ะฝะตะพะฑั
ะพะดะธะผะพ.
network_error = ะัะตะถะพะฒะฐ ะณัะตัะบะฐ
occurred = ะัะทะฝะธะบะฝะฐ ะณัะตัะบะฐ
@@ -1437,7 +1629,7 @@ lang_select_error = ะะทะฑะตัะตัะต ะตะทะธะบ ะพั ัะฟะธััะบะฐ.
HttpsUrl = HTTPS URL
require_error = ` ะฝะต ะผะพะถะต ะดะฐ ะฑัะดะต ะฟัะฐะทะฝะพ.`
Retype = ะะพัะฒััะดะตัะต ะฟะฐัะพะปะฐัะฐ
-url_error = `"%s" ะฝะต ะต ะฒะฐะปะธะดะตะฝ URL.`
+url_error = `โ%sโ ะฝะต ะต ะฒะฐะปะธะดะตะฝ URL.`
Content = ะกัะดััะถะฐะฝะธะต
team_not_exist = ะะบะธะฟัั ะฝะต ัััะตััะฒัะฒะฐ.
TeamName = ะะผะต ะฝะฐ ะตะบะธะฟะฐ
@@ -1481,6 +1673,8 @@ push_tag = ะธะทัะปะฐัะบะฐ ะผะฐัะบะตั %[3]s ะบัะผ %[3]s#%[2]s `
reject_pull_request = `ะฟัะตะดะปะพะถะธ ะฟัะพะผะตะฝะธ ะทะฐ %[3]s#%[2]s `
compare_branch = ะกัะฐะฒะฝัะฒะฐะฝะต
+compare_commits_general = ะกัะฐะฒะฝัะฒะฐะฝะต ะฝะฐ ะฟะพะดะฐะฒะฐะฝะธั
+compare_commits = ะกัะฐะฒะฝะตัะต %d ะฟะพะดะฐะฒะฐะฝะธั
[auth]
tab_openid = OpenID
@@ -1507,9 +1701,17 @@ must_change_password = ะะฑะฝะพะฒะตัะต ะฟะฐัะพะปะฐัะฐ ัะธ
password_too_short = ะัะปะถะธะฝะฐัะฐ ะฝะฐ ะฟะฐัะพะปะฐัะฐ ะฝะต ะผะพะถะต ะดะฐ ะฑัะดะต ะฟะพ-ะผะฐะปะบะฐ ะพั %d ะทะฝะฐะบะฐ.
tab_signin = ะะปะธะทะฐะฝะต
tab_signup = ะ ะตะณะธัััะธัะฐะฝะต
+password_pwned = ะะฐัะพะปะฐัะฐ, ะบะพััะพ ััะต ะธะทะฑัะฐะปะธ, ะต ะฒ ัะฟะธััะบ ั ะพัะบัะฐะดะฝะฐัะธ ะฟะฐัะพะปะธ , ัะฐะทะบัะธัะธ ะฟัะตะดะธ ัะพะฒะฐ ะฟัะธ ะฟัะฑะปะธัะฝะธ ะฟัะพะฑะธะฒะธ ะฝะฐ ะดะฐะฝะฝะธ. ะะพะปั, ะพะฟะธัะฐะนัะต ะพัะฝะพะฒะพ ั ัะฐะทะปะธัะฝะฐ ะฟะฐัะพะปะฐ.
+confirmation_mail_sent_prompt = ะะพะฒะพ ะตะป. ะฟะธัะผะพ ะทะฐ ะฟะพัะฒััะถะดะตะฝะธะต ะต ะธะทะฟัะฐัะตะฝะพ ะดะพ %s . ะะฐ ะดะฐ ะทะฐะฒัััะธัะต ะฟัะพัะตัะฐ ะฝะฐ ัะตะณะธัััะฐัะธั, ะผะพะปั, ะฟัะพะฒะตัะตัะต ะฒั
ะพะดััะฐัะฐ ัะธ ะบััะธั ะธ ะฟะพัะปะตะดะฒะฐะนัะต ะฟัะตะดะพััะฐะฒะตะฝะฐัะฐ ะฒััะทะบะฐ ะฒ ัะฐะผะบะธัะต ะฝะฐ ัะปะตะดะฒะฐัะธัะต %s. ะะบะพ ะฐะดัะตััั ะทะฐ ะตะป. ะฟะพัะฐ ะต ะฝะตะฟัะฐะฒะธะปะตะฝ, ะผะพะถะตัะต ะดะฐ ะฒะปะตะทะตัะต ะธ ะดะฐ ะฟะพะธัะบะฐัะต ะดััะณะพ ะตะป. ะฟะธัะผะพ ะทะฐ ะฟะพัะฒััะถะดะตะฝะธะต ะดะฐ ะฑัะดะต ะธะทะฟัะฐัะตะฝะพ ะฝะฐ ัะฐะทะปะธัะตะฝ ะฐะดัะตั.
+hint_login = ะะตัะต ะธะผะฐัะต ะฐะบะฐัะฝั? ะะปะตะทัะต!
+hint_register = ะัะถะดะฐะตัะต ัะต ะพั ะฐะบะฐัะฝั? ะ ะตะณะธัััะธัะฐะนัะต ัะต.
+sign_up_button = ะ ะตะณะธัััะธัะฐะนัะต ัะต.
+back_to_sign_in = ะะฐะทะฐะด ะบัะผ ะั
ะพะด
+sign_in_openid = ะัะพะดัะปะถะฐะฒะฐะฝะต ั OpenID
+send_reset_mail = ะะทะฟัะฐัะฐะฝะต ะฝะฐ ะตะป. ะฟะธัะผะพ ะทะฐ ะฒัะทััะฐะฝะพะฒัะฒะฐะฝะต
[aria]
-footer.software = ะัะฝะพัะฝะพ ัะพัััะตัะฐ
+footer.software = ะัะฝะพัะฝะพ ัะพะทะธ ัะพัััะตั
footer.links = ะััะทะบะธ
footer = ะะพะปะตะฝ ะบะพะปะพะฝัะธััะป
@@ -1517,12 +1719,12 @@ footer = ะะพะปะตะฝ ะบะพะปะพะฝัะธััะป
install = ะะตัะตะฝ ะทะฐ ะธะฝััะฐะปะธัะฐะฝะต
lightweight = ะะตะบ
license = ะัะฒะพัะตะฝ ะบะพะด
-install_desc = ะัะพััะพ ััะฐััะธัะฐะนัะต ะดะฒะพะธัะฝะธั ัะฐะนะป ะทะฐ ะฒะฐัะฐัะฐ ะฟะปะฐััะพัะผะฐ, ะธะทะฟะพะปะทะฒะฐะนัะต Docker , ะธะปะธ ะณะพ ะฟะพะปััะตัะต ะฟะฐะบะตัะธัะฐะฝะพ .
+install_desc = ะัะพััะพ ััะฐััะธัะฐะนัะต ะดะฒะพะธัะฝะธั ัะฐะนะป ะทะฐ ะฒะฐัะฐัะฐ ะฟะปะฐััะพัะผะฐ, ะธะทะฟะพะปะทะฒะฐะนัะต Docker , ะธะปะธ ะณะพ ะฟะพะปััะตัะต ะฟะฐะบะตัะธัะฐะฝ .
app_desc = ะะตะทะฟัะพะฑะปะตะผะฝะฐ Git ััะปัะณะฐ ััั ัะฐะผะพััะพััะตะปะตะฝ ั
ะพััะธะฝะณ
platform = ะะตะถะดัะฟะปะฐััะพัะผะตะฝ
lightweight_desc = Forgejo ะธะผะฐ ะฝะธัะบะธ ะผะธะฝะธะผะฐะปะฝะธ ะธะทะธัะบะฒะฐะฝะธั ะธ ะผะพะถะต ะดะฐ ัะฐะฑะพัะธ ะฝะฐ ะธะบะพะฝะพะผะธัะตะฝ Raspberry Pi. ะกะฟะตััะตัะต ะตะฝะตัะณะธััะฐ ะฝะฐ ะฒะฐัะฐัะฐ ะผะฐัะธะฝะฐ!
-platform_desc = Forgejo ัะฐะฑะพัะธ ะฝะฐะฒััะบัะดะต, ะบัะดะตัะพ Go ะผะพะถะต ะดะฐ ัะต ะบะพะผะฟะธะปะธัะฐ: Windows, macOS, Linux, ARM, ะธ ั.ะฝ. ะะทะฑะตัะตัะต, ะบะพะตัะพ ั
ะฐัะตัะฒะฐัะต!
-license_desc = ะะทะตะผะตัะต Forgejo ! ะัะธััะตะดะธะฝะตัะต ัะต ะบัะผ ะฝะฐั, ะดะพะฟัะธะฝะฐััะนะบะธ , ะทะฐ ะดะฐ ะฝะฐะฟัะฐะฒะธัะต ัะพะทะธ ะฟัะพะตะบั ะพัะต ะฟะพ-ะดะพะฑัั. ะะต ัะต ะบะพะปะตะฑะฐะนัะต ะดะฐ ัััััะดะฝะธัะธัะต!
+platform_desc = Forgejo ัะฐะฑะพัะธ ะฝะฐ ัะฒะพะฑะพะดะฝะธ ะพะฟะตัะฐัะธะพะฝะฝะธ ัะธััะตะผะธ ะบะฐัะพ Linux ะธ FreeBSD, ะบะฐะบัะพ ะธ ะฝะฐ ัะฐะทะปะธัะฝะธ CPU ะฐัั
ะธัะตะบัััะธ. ะะทะฑะตัะตัะต ัะฐะทะธ, ะบะพััะพ ะฟัะตะดะฟะพัะธัะฐัะต!
+license_desc = ะะทะตะผะตัะต Forgejo ! ะัะธััะตะดะธะฝะตัะต ัะต ะบัะผ ะฝะฐั, ะดะพะฟัะธะฝะฐััะนะบะธ , ะทะฐ ะดะฐ ะฝะฐะฟัะฐะฒะธัะต ัะพะทะธ ะฟัะพะตะบั ะพัะต ะฟะพ-ะดะพะฑัั. ะะต ัะต ะบะพะปะตะฑะฐะนัะต ะดะฐ ัััััะดะฝะธัะธัะต!
[notification]
subscriptions = ะะฑะพะฝะฐะผะตะฝัะธ
@@ -1565,7 +1767,7 @@ actions = ะะตะนััะฒะธั
variables.none = ะัะต ะพัะต ะฝัะผะฐ ะฟัะพะผะตะฝะปะธะฒะธ.
variables.creation.failed = ะะตััะฟะตัะฝะพ ะดะพะฑะฐะฒัะฝะต ะฝะฐ ะฟัะพะผะตะฝะปะธะฒะฐ.
variables.update.failed = ะะตััะฟะตัะฝะพ ัะตะดะฐะบัะธัะฐะฝะต ะฝะฐ ะฟัะพะผะตะฝะปะธะฒะฐ.
-variables.creation.success = ะัะพะผะตะฝะปะธะฒะฐัะฐ "%s" ะต ะดะพะฑะฐะฒะตะฝะฐ.
+variables.creation.success = ะัะพะผะตะฝะปะธะฒะฐัะฐ โ%sโ ะต ะดะพะฑะฐะฒะตะฝะฐ.
variables.deletion.success = ะัะพะผะตะฝะปะธะฒะฐัะฐ ะต ะฟัะตะผะฐั
ะฝะฐัะฐ.
variables.edit = ะ ะตะดะฐะบัะธัะฐะฝะต ะฝะฐ ะฟัะพะผะตะฝะปะธะฒะฐัะฐ
variables.deletion = ะัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ ะฟัะพะผะตะฝะปะธะฒะฐัะฐ
@@ -1574,6 +1776,10 @@ variables.creation = ะะพะฑะฐะฒัะฝะต ะฝะฐ ะฟัะพะผะตะฝะปะธะฒะฐ
variables.deletion.failed = ะะตััะฟะตัะฝะพ ะฟัะตะผะฐั
ะฒะฐะฝะต ะฝะฐ ะฟัะพะผะตะฝะปะธะฒะฐ.
runners.task_list.repository = ะฅัะฐะฝะธะปะธัะต
runners.description = ะะฟะธัะฐะฝะธะต
+runs.no_workflows.help_no_write_access = ะะฐ ะดะฐ ะฝะฐััะธัะต ะฟะพะฒะตัะต ะทะฐ Forgejo Actions, ะฒะธะถัะต ะดะพะบัะผะตะฝัะฐัะธััะฐ .
+variables.management = ะฃะฟัะฐะฒะปะตะฝะธะต ะฝะฐ ะฟัะพะผะตะฝะปะธะฒะธ
+variables.not_found = ะัะพะผะตะฝะปะธะฒะฐัะฐ ะฝะต ะต ะพัะบัะธัะฐ.
+variables.id_not_exist = ะัะพะผะตะฝะปะธะฒะฐ ั ะธะดะตะฝัะธัะธะบะฐัะพั %d ะฝะต ัััะตััะฒัะฒะฐ.
[heatmap]
less = ะะพ-ะผะฐะปะบะพ
@@ -1605,9 +1811,11 @@ contributors.what = ะฟัะธะฝะพัะธ
recent_commits.what = ัะบะพัะพัะฝะธ ะฟะพะดะฐะฒะฐะฝะธั
component_loading = ะะฐัะตะถะดะฐะฝะต ะฝะฐ %s...
component_loading_info = ะขะพะฒะฐ ะผะพะถะต ะดะฐ ะพัะฝะตะผะต ะธะทะฒะตััะฝะพ ะฒัะตะผะตโฆ
+code_frequency.what = ัะตััะพัะฐ ะฝะฐ ะฟัะพะผะตะฝะธัะต
[projects]
type-1.display_name = ะะฝะดะธะฒะธะดัะฐะปะตะฝ ะฟัะพะตะบั
+deleted.display_name = ะะทััะธั ะฟัะพะตะบั
[search]
@@ -1622,6 +1830,10 @@ project_kind = ะขัััะตะฝะต ะฝะฐ ะฟัะพะตะบัะธ...
package_kind = ะขัััะตะฝะต ะฝะฐ ะฟะฐะบะตัะธ...
search = ะขัััะตะฝะต...
branch_kind = ะขัััะตะฝะต ะฝะฐ ะบะปะพะฝะพะฒะต...
+pull_kind = ะขัััะตะฝะต ะฝะฐ ะทะฐัะฒะบะธ ะทะฐ ัะปะธะฒะฐะฝะต...
+issue_kind = ะขัััะตะฝะต ะฝะฐ ะทะฐะดะฐัะธ...
+fuzzy = ะัะธะฑะปะธะทะธัะตะปะฝะพ
+exact = ะัะตัะธะทะฝะพ
[markup]
filepreview.lines = ะ ะตะดะพะฒะต ะพั %[1]d ะดะพ %[2]d ะฒ %[3]s
@@ -1635,3 +1847,7 @@ gib = ะะธะ
tib = ะขะธะ
pib = ะะธะ
eib = ะะธะ
+
+
+[translation_meta]
+test = ะพะบะตะน
diff --git a/options/locale/locale_bn.ini b/options/locale/locale_bn.ini
index 8741fee98c..2155f9073c 100644
--- a/options/locale/locale_bn.ini
+++ b/options/locale/locale_bn.ini
@@ -1,6 +1,8 @@
-
-
-
[common]
help = เฆธเฆพเฆนเฆพเฆฏเงเฆฏ
-dashboard = เฆกเงเฆฏเฆพเฆถเฆฌเงเฆฐเงเฆก
\ No newline at end of file
+dashboard = เฆกเงเฆฏเฆพเฆถเฆฌเงเฆฐเงเฆก
+home = เฆฌเฆพเฆกเฆผเฆฟ
+explore = เฆฆเงเฆเงเฆฃ
+logo = เฆฒเงเฆเง
+sign_in = เฆธเฆพเฆเฆฃ เฆเฆฃ
+sign_in_or = เฆฌเฆพ
\ No newline at end of file
diff --git a/options/locale/locale_bs.ini b/options/locale/locale_bs.ini
index bec7a65005..78eb7daa33 100644
--- a/options/locale/locale_bs.ini
+++ b/options/locale/locale_bs.ini
@@ -1,6 +1,3 @@
-
-
-
[common]
tracked_time_summary = Saลพetak praฤenog vremena bazirano na filterima liste problema
language = Jezik
diff --git a/options/locale/locale_ca.ini b/options/locale/locale_ca.ini
index e917e214ac..9cb7d5e50c 100644
--- a/options/locale/locale_ca.ini
+++ b/options/locale/locale_ca.ini
@@ -1,13 +1,10 @@
-
-
-
[common]
-home = inici
+home = Inici
dashboard = Panell de control
explore = Explorar
help = Ajuda
logo = Logo
-sign_in = Entrar
+sign_in = Iniciar sessiรณ
sign_in_with_provider = Entra amb %s
sign_in_or = o
sign_out = Sortir
@@ -18,9 +15,9 @@ page = Pร gina
template = Plantilla
language = Idioma
notifications = Notificacions
-active_stopwatch = Registre de Temps Actiu
+active_stopwatch = Registre de temps actiu
create_new = Crearโฆ
-user_profile_and_more = Perfil i configuraciรณโฆ
+user_profile_and_more = Perfil i Configuraciรณโฆ
signed_in_as = Entrat com
enable_javascript = Aquest lloc web requereix Javascript.
toc = Taula de Continguts
@@ -28,4 +25,462 @@ licenses = Llicรจncies
sign_up = Registrar-se
link_account = Vincular un compte
tracked_time_summary = Resum del temps registrat basat en filtres del llistat de temes
-return_to_forgejo = Tornar a Forgejo
\ No newline at end of file
+return_to_forgejo = Tornar a Forgejo
+toggle_menu = Commuta el menรบ
+more_items = Mรฉs elements
+username = Nom d'usuari
+email = Direcciรณ de correu
+password = Contrasenya
+access_token = Testimoni d'accรฉs
+re_type = Confirmar contrasenya
+captcha = CAPTCHA
+twofa = Autenticaciรณ de doble factor
+twofa_scratch = Codi de rascar de doble-factor
+passcode = Codi de pas
+webauthn_insert_key = Inseriu la vostra clau de seguretat
+webauthn_sign_in = Premeu el botรณ a la vostra clau de seguretat. Si no en tรฉ, torneu-la a inserir.
+webauthn_press_button = Siusplau, premeu el botรณ a la vostra clau de seguretatโฆ
+webauthn_use_twofa = Utilitza un codi de doble factor des del teu mรฒbil
+webauthn_error = No s'ha pogut llegir la clau de seguretat.
+webauthn_unsupported_browser = El teu navegador no suprta WebAuthn.
+webauthn_error_unknown = Hi ha hagut un error desconegut. Si us plau torneu-ho a intentar.
+webauthn_error_insecure = WebAuthn nomรฉs suporta connexions segures. Per provar sobre HTTP, podeu utilitzar l'origen "localhost" o "127.0.0.1"
+webauthn_error_unable_to_process = El servidor no ha pogut processar la vostra peticiรณ.
+webauthn_error_duplicated = La clau de seguretat no รฉs permesa per aquesta peticiรณ. Si us plau, assegureu-vos que la clau encara no ha estat registrada.
+webauthn_error_empty = S'ha d'anomenar aquesta clau.
+webauthn_reload = Recarrega
+repository = Repositori
+organization = Organitzaciรณ
+mirror = Mirall
+new_repo = Nou repositori
+new_migrate = Nova migraciรณ
+new_mirror = Nou mirall
+new_fork = Nou fork d'un repositori
+new_org = Nova organitzaciรณ
+new_project = Nou projecte
+new_project_column = Nova columna
+admin_panel = Administraciรณ del lloc
+settings = Configuraciรณ
+your_profile = Perfil
+your_starred = Preferits
+your_settings = Configuraciรณ
+all = Tots
+sources = Fonts
+mirrors = Miralls
+collaborative = Coลlaboratiu
+forks = Forks
+activities = Activitats
+pull_requests = Pull requests
+issues = Problemes
+milestones = Fites
+ok = OK
+retry = Reintentar
+rerun = Torna a executar
+rerun_all = Torna a executar tots els treballs
+save = Guardar
+add = Afegir
+add_all = Afegeix-los tots
+remove = Esborrar
+remove_all = Esborral's tots
+edit = Editar
+view = Mirar
+enabled = Habilitat
+disabled = Deshabilitat
+filter.public = Pรบblic
+filter.private = Privat
+show_full_screen = Mostra a pantalla completa
+webauthn_error_timeout = Temps d'espera finalitzar abans que la seva clau poguรฉs ser llegida. Siusplau recarregueu la pร gina i torneu-ho a intentar.
+remove_label_str = Esborra l'element "%s"
+error413 = Ha exhaurit la quota.
+cancel = Canceลlar
+download_logs = Baixa els registres
+never = Mai
+concept_user_individual = Individual
+concept_code_repository = Repositori
+concept_user_organization = Organitzaciรณ
+show_timestamps = Mostra les marques temporals
+show_log_seconds = Mostra els segons
+test = Test
+locked = Bloquejat
+copy = Copiar
+copy_generic = Copiar al porta-retalls
+copy_url = Copiar l'URL
+copy_hash = Copiar l'empremta
+copy_content = Copiar continguts
+copy_branch = Copiar el nom de la branca
+copy_success = Copiat!
+copy_error = Ha fallat el copiar
+copy_type_unsupported = Aquest tipus de fitxer no pot ser copiat
+write = Escriure
+preview = Previsualitzar
+loading = Carregantโฆ
+error = Error
+error404 = La pร gina a la qual estร s intentant arribar no existeix , ha sigut eliminada o no estร s autoritzat a veure-la.
+go_back = Tornar Enrere
+invalid_data = Dades invalides: %v
+unknown = Desconegut
+rss_feed = Agregador RSS
+pin = Fixar
+unpin = Desfixar
+artifacts = Artefactes
+confirm_delete_artifact = Estร segur de voler esborrar l'artefacte "%s"?
+archived = Arxivat
+concept_system_global = Global
+confirm_delete_selected = Confirmar esborrar tots els elements seleccionats?
+name = Nom
+value = Valor
+filter.is_mirror = รs mirall
+filter.not_mirror = No รฉs mirall
+filter.is_template = รs plantilla
+filter.not_template = No รฉs plantilla
+filter = Filtre
+filter.clear = Netejar filtes
+filter.is_archived = Arxivats
+filter.not_archived = No arxivats
+filter.not_fork = No รฉs fork
+filter.is_fork = Sรณn forks
+copy_path = Copiar ruta
+new_repo.title = Nou repositori
+new_migrate.title = Nova migraciรณ
+new_org.title = Nova organitzaciรณ
+new_repo.link = Nou repositori
+new_migrate.link = Nova migraciรณ
+new_org.link = Nova organitzaciรณ
+
+[search]
+milestone_kind = Cerca fites...
+fuzzy = Difusa
+search = Cerca...
+type_tooltip = Tipus de cerca
+fuzzy_tooltip = Inclou resultats que s'assemblen al terme de la cerca
+repo_kind = Cerca repos...
+user_kind = Cerca usuaris...
+code_search_unavailable = La cerca de codi no estร disponible actualment. Si us plau concteu amb l'administrador del lloc.
+code_search_by_git_grep = Els resultats actuals de la cerca de codi sรณn proporcionats per "git grep". Podrรญen haver-hi millors resultats si l'administrador del lloc habilita l'indexador de codi.
+package_kind = Cerca paquets...
+project_kind = Cerca projectes...
+branch_kind = Cerca branques...
+commit_kind = Cerca commits...
+runner_kind = Cerca executors...
+no_results = Cap resultat coincident trobat.
+keyword_search_unavailable = La cerca per paraula clau no estร disponible ara mateix. Si us plau contacteu amb l'administrador del lloc.
+union = Paraules clau
+union_tooltip = Inclou resultats que encaixen amb qualsevol paraula clau separada per espais
+org_kind = Cerca organitzacions...
+team_kind = Cerca teams...
+code_kind = Cerca codi...
+pull_kind = Cerca "pulls"...
+exact = Exacte
+exact_tooltip = Inclou nomรฉs resultats que sรณn exactament el terme de cerca
+issue_kind = Cerca problemes...
+regexp = RegExp
+regexp_tooltip = Interpreta el terme de cerca com una expressiรณ regular
+
+[heatmap]
+number_of_contributions_in_the_last_12_months = %s contribucions en els รบltims 12 mesos
+contributions_zero = Cap contribuciรณ
+contributions_format = {contribucions} a {day} de {month} de {year}
+contributions_one = contribuciรณ
+contributions_few = contribucions
+less = Menys
+more = Mรฉs
+
+[filter]
+string.asc = A - Z
+string.desc = Z - A
+
+[error]
+occurred = Hi ha hagut un error
+report_message = Si creus que aixรฒ es un bug de Forgejo, si us plau cerca problemes a Codeberg i obre'n un de nou si cal.
+not_found = L'objectiu no s'ha pogut trobar.
+server_internal = Error intern del servidor
+missing_csrf = Peticiรณ Dolenta: falta el testimoni CSRF
+invalid_csrf = Peticiรณ Dolenta: testimoni CSRF invร lid
+network_error = Error de xarxa
+
+[install]
+title = Configuraciรณ inicial
+docker_helper = Si executes Forgejo a Docker, si us plau llegeis la documentaciรณ abans de canviar qualsevol configuraciรณ.
+require_db_desc = Forgejo requereix de MySQL, PostreSQL, SQLite3 o TiDB (protocol MySQL).
+db_title = Configuraciรณ de la base de dades
+path = Ruta
+sqlite_helper = Ruta al fitxer de la base de dades SQLite3. Introduex la ruta absoluta si executes Forgejo com a servei.
+user = Nom d'usuari
+db_schema = Esquema
+ssl_mode = SSL
+err_empty_admin_email = El correu de l'administrador no pot ser buit.
+reinstall_error = Estas intentant instaลlar sobre una base de dades existent de Forgejo
+reinstall_confirm_message = Reinstaลlar amb una base de dades existent de Forgejo pot causar diferents problemes. En la majoria de casos, s'hauria d'utilitzar l'"app.ini" existent per executar Forgejo. Si saps el que estร s fent, confirma el seguent:
+no_admin_and_disable_registration = No pot deshabilitar l'autoregistre d'usuaris sense crear un compte d'administrador.
+err_admin_name_is_reserved = El nom d'usuari "Administrador" no es vร lid: estร reservat
+smtp_addr = Hoste SMTP
+smtp_port = Port SMPT
+smtp_from = Enviar correu com a
+mailer_user = Nom d'usuari SMTP
+err_admin_name_pattern_not_allowed = El nom d'usuari de l'administrador no es vร lid: coincideix amb un patrรณ reservat
+err_admin_name_is_invalid = El nom d'usuari "Administrador" no รฉs vร lid
+general_title = Configuraciรณ general
+app_name = Tรญtol de la instร ncia
+app_url = URL base
+email_title = Configuraciรณ del correu
+server_service_title = Configuracions del servidor i de serveis de tercers
+offline_mode = Habilitar el mode local
+mail_notify = Habilita les notificacions per correu
+federated_avatar_lookup = Habilitar avatars federats
+admin_title = Configuraciรณ del compte d'administrador
+invalid_admin_setting = Configuraciรณ del compte d'administrador invalida: %v
+invalid_log_root_path = La ruta dels registres es invalida: %v
+save_config_failed = Error al guardar la confifuraciรณ: %v
+enable_update_checker_helper_forgejo = Comprovarร periodicament si hi ha una nova versiรณ de Forgejo comprovant un registre DNS TXT a release.forgejo.org.
+password_algorithm = Funciรณ resum per a contrasenyes
+install = Instaลlaciรณ
+db_schema_helper = Deixa en blanc per la base de dades per defecte ("public").
+domain = Domini del servidor
+mailer_password = Contrasenya SMTP
+admin_email = Direcciรณ de correu
+invalid_db_setting = La configuraciรณ de la base de dades รฉs invalida: %v
+run_user_not_match = El nom d'usuari a executar com no รฉs l'actual: %s -> %s
+internal_token_failed = Error al generar testimoni intern: %v
+secret_key_failed = Error al generar clau secreta: %v
+test_git_failed = No s'ha pogut provar l'ordre "git": %v
+sqlite3_not_available = Aquesta versiรณรณ de Forgejo no suporta SQLite3. Si us plau baixeu el binari de la versiรณ oficial de %s (no la versiรณ "gobuild").
+invalid_db_table = La taula "%s" de la base de dades es invalida: %v
+invalid_repo_path = L'arrel del repositori es invalida: %v
+invalid_app_data_path = La ruta de dades de l'aplicaciรณ es invalida: %v
+env_config_keys_prompt = Les seguents variables d'entorns tambe s'aplicarร n al teu fitxer de configuraciรณ:
+offline_mode.description = Deshabilitar les CDNs de tercers i servir tot el contingut de forma local.
+disable_registration.description = Nomรฉs els administradors de la instร ncia podrร n crear nous usuaris. รs altament recomanat deixar el registre deshabilitat excepte si s'estร hostatjant una instร ncia pรบblica per a tothom i estร llesta per a assolir grans quantitats de comptes spam.
+admin_password = Contrasenya
+err_empty_admin_password = La contrasenya de l'administrador no por ser buida.
+ssh_port = Por del servidor SSH
+disable_gravatar = Deshabilitar Gravatar
+disable_registration = Deshabilitar l'auto-registre
+openid_signin = Habilita l'inici de sessiรณ amb OpenID
+enable_captcha = Habilita el CAPTCHA al registre
+default_keep_email_private = Amaga les direccions de correu per defecte
+app_slogan = Eslogan de la instร ncia
+app_slogan_helper = Escriu l'eslogan de la teva instร ncia aquรญ. Deixa buit per deshabilitar.
+repo_path = Ruta de l'arrel del repositori
+log_root_path_helper = Els arxius dels registres es s'escriuran en aquest directori.
+optional_title = Configuracions opcionals
+host = Hoste
+lfs_path = Ruta arreal de Git LFS
+run_user = Executar com a usuari
+domain_helper = Domini o adreรงa de l'hosta per al servidor.
+http_port = Port d'escolta HTTP
+app_url_helper = Adreces base per a clonaciรณ HTTP(S) i notificacions per correu.
+log_root_path = Ruta dels registres
+smtp_from_invalid = L'adreรงa d'"Enviar correu com a" รฉs invalida
+smtp_from_helper = L'adreรงa de correu que Forgejo utilitzarร . Entri el correu en pla o en format "Nom" .
+register_confirm = Requereix confirmaciรณ de correu per a registrar-se
+disable_gravatar.description = Deshabilitar l'รบs de Gravatar o d'altres serveis d'avatars de tercers. S'utilitzaran imatges per defecte per als avatars dels uauris fins que pujin el seu propi a la instร ncia.
+federated_avatar_lookup.description = Cerca d'avatars amb Libravatar.
+allow_only_external_registration = Permet el registre nomรฉs amb serveis externs
+allow_only_external_registration.description = Els usuaris nomes podrร n crear nous comptes utilitzant els serveis externs configurats.
+enable_captcha.description = Requereix als usuaris passar el CAPTCHA per a poder-se crear comptes.
+require_sign_in_view = Requereix inciar sessiรณ per a veure el contingut de la instร ncia
+default_keep_email_private.description = Habilita l'ocultament de les direccions de correu per a nous usuaris per defecte, amb tal que aquesta informaciรณ no sigui filtrada immediatament despres de registrar-se.
+default_allow_create_organization = Per defecte permet crear organitzacions
+default_enable_timetracking = Per defecta habilita el seguiment de temps
+default_enable_timetracking.description = Per defecte activa el de seguiment de temps als nous repositoris.
+admin_name = Nom d'usuari de l'administrador
+install_btn_confirm = Instaลlar Forgejo
+allow_dots_in_usernames = Permet als usuaris utilitzar punts en els seus noms d'usuari. No afecta als comptes existents.
+no_reply_address = Domini del correu ocult
+no_reply_address_helper = Nom del domini per a usuaris amb l'adreรงa de correu oculta. Per exemple, el nom d'usuari "pep" tindrร la sessiรณ inciada com a "pep@noreply.example.org" si el domini per a adreces ocultes es configurat a "noreply.example.org".
+password_algorithm_helper = Configura la funciรณ resum per a contrasenyes. Els algorismes difereixen en requeriments i seguretat. L'algorisme "argon2" es bastant segur, perรฒ utilitza molta memรฒria i podrรญa ser inapropiat per a sistemes petits.
+invalid_password_algorithm = Funciรณ resum invalida per a contrasenyes
+enable_update_checker = Habilita la comprovaciรณ d'actualitzacions
+env_config_keys = configuraciรณ de l'entorn
+db_type = Tipus de base de dades
+lfs_path_helper = Els arxius seguits per Git LFS es desaran en aquest directory. Deixa buit per deshabilitar.
+http_port_helper = Numero de port que utilitzarร el servidor web de Forgejo.
+repo_path_helper = Els repositoris Git remotes es desaran en aquest diectori.
+run_user_helper = El nom d'usuari del sistema operatiu sota el que Forgejo s'executa. Notis que aquest usuari ha de tenir accรฉs a la ruta arrel del repositori.
+ssh_port_helper = Numero del port que utilitzarร el servidor SSH. Deixa buit per deshablitar el servidor SSH.
+require_sign_in_view.description = Limita l'accรจs al contingut per als usuaris connectats. Els visitatnts nomรฉs podran veure les pร gines d'autenticaciรณ.
+default_allow_create_organization.description = Per defecte permet als nous usuaris crear organitzacions. Quan aquesta opciรณ estร deshabilitada, un administrador haurร de concedir permisos per a crear organitzacions als nous usuaris.
+reinstall_confirm_check_3 = Confirma que estร completament segur que Forgejo s'estร executant amb l'app.ini correcte i que estร segur que ha de tornar a instaลlar. Confirma que coneix els riscos anteriors.
+err_empty_db_path = La ruta a la base de dades SQLite3 no por ser buida.
+reinstall_confirm_check_1 = Les dades xifrades per la SECRET_KEY a l'app.ini podrien perdre's: es posible que els usuaris no puguin iniciar sessiรณ amb 2FA/OTP i que els miralls no funcionin correctament. Marcant aquesta casella confirmes que l'arxiu app.ini contรฉ la SECRET_KEY correcta.
+reinstall_confirm_check_2 = รs possibles que els repositoris i les configuracions hagin de tornar-se a sincronitzar. Marcant aquesta casella confirmes que resincronitzaras els ganxos dels respositoris i l'arxiu authorized_keys manualment. Confirma que comprovarร que les configuracions dels repositoris i els miralls sรณn correctes.
+openid_signin.description = Permet als usuaris iniciar sessiรณ amb OpenID.
+openid_signup = Habilita l'auto-registre amb OpenID
+openid_signup.description = Permet als usuaris crear-se comptes amb OpenID si l'auto-registre estร habilitat.
+config_location_hint = Aquestes opcions de configuraciรณ es desarร n a:
+admin_setting.description = Crear un compte d'aministrador รฉs opcional. El primer usuari registrat automร ticament serร un adminstrador.
+confirm_password = Confirmar contrasenya
+password = Contrasenya
+db_name = Nom de la base de dades
+app_name_helper = Escriu el nom de la teva instร ncia aquรญ. Es mostrarร a totes les pร gines.
+
+[startpage]
+license_desc = Aconsegueix Forgejo ! Uneix-te contribuint per a millorar aquest projecte. No et fagi vergonya ser un contribuent!
+platform_desc = Estร confirmat que Forgejo s'executa en sistemes operatius lliures com Linux o FreeBSD, aixรญ com diferentes arquitectures de CPU. Tria la que mรฉs t'agradi!
+lightweight_desc = Forgejo te uns requeriments minims baixos i pot executar-se en una Raspberry Pi. Estalvia energia a la teva mร quina!
+license = Codi Obert
+app_desc = Un servei de Git autohostatjat i indolor
+install = Fร cil d'instaลlar
+platform = Multiplataforma
+lightweight = Lleuger
+install_desc = Simplement executa el binari per a la teva plataforma, carrega'l amb Docker , o aconsegueix-lo empaquetat .
+
+[explore]
+code_last_indexed_at = Indexat oer รบltim cop a %s
+relevant_repositories_tooltip = Els repositoris que sรณn forks o que no tenen tรฒpic, icona o descripciรณ estร n amagats.
+relevant_repositories = Nomรฉs รฉs mostren repositoris rellevants, mostra resultats sense filtrar .
+repos = Repositoris
+organizations = Organitzacions
+code = Codi
+stars_few = %d estrelles
+forks_one = %d fork
+forks_few = %d forks
+go_to = Ves a
+users = Usuaris
+stars_one = %d estrella
+
+[auth]
+disable_register_prompt = El registre estร deshabilitat. Si us plau contacti l'administrador del lloc.
+disable_register_mail = Registre amb confirmaciรณ per correu deshabilitat.
+manual_activation_only = Contacti amb l'administrador de lloc per a completar l'activaciรณ.
+remember_me = Recordar aquest dispositiu
+create_new_account = Registrar compte
+reset_password = Recuperaciรณ del compte
+reset_password_wrong_user = Heu iniciat sessiรณ com a %s, perรฒ l'enllaรง de recuperaciรณ pertany a %s
+allow_password_change = Requereix a l'usuari canviar la contrasenya (recomanat)
+invalid_code_forgot_password = El codi de confirmaciรณ รฉs invร lid o ha caducat. Feu click aquรญ per a iniciar una sessiรณ nova.
+twofa_scratch_used = Ja heu utilitzat el vostre codi de recuperaciรณ. Se us ha redirigit a la pร gina de configuraciรณ de l'autenticaciรณ de doble factor per tal d'eliminar el dispositiu o generar un codi de recuperaciรณ nou.
+login_userpass = Entra
+oauth.signin.error.temporarily_unavailable = Ha fallat l'autoritzaciรณ perquรจ el servidor d'autenticaciรณ no estร disponible temporalment. Intenteu-ho de nou mรฉs tard.
+authorization_failed_desc = Ha fallat l'autoritzaciรณ perquรจ s'ha detectat una solยทlicitud invร lida. Si us plau, contacteu amb el responsable de l'aplicaciรณ que heu intentat autoritzar.
+authorization_failed = Ha fallat l'autoritzaciรณ
+last_admin = No podeu eliminar l'รบltim usuari administrador. Com a mรญnim n'hi ha d'haver un.
+password_pwned_err = No s'ha pogut completar la solยทlicitud a HaveIBeenPwned
+forgot_password = Contrasenya oblidada?
+reset_password_mail_sent_prompt = S'ha enviat un correu electrรฒnic de confirmaciรณ a %s . Per tal de completar el procรฉs de recuperaciรณ del compte, reviseu la safata d'entrada i seguiu l'enllaรง que se us ha enviat en els segรผents %s.
+prohibit_login = El compte estร en suspensiรณ
+resent_limit_prompt = Fa poc que heu solยทlicitat un correu electrรฒnic d'activaciรณ. Si us plau, espereu 3 minuts i torneu a intentar-ho.
+has_unconfirmed_mail = Hola %s, la vostra adreรงa de correu no s'ha confirmat (%s ). Si no heu rebut un correu de confirmaciรณ o necessiteu que l'enviem de nou, feu clic al botรณ segรผent.
+change_unconfirmed_email_summary = Canvieu l'adreรงa de correu on s'envia el correu d'activaciรณ.
+invalid_code = El codi de confirmaciรณ no รฉs vร lid o ha caducat.
+invalid_password = La contrasenya no coincideix amb la que es va utilitzar per a crear el compte.
+reset_password_helper = Recuperar compte
+verify = Verificar
+unauthorized_credentials = Les credencials sรณn incorrectes o han caducat. Torneu a executar l'ordre o visiteu %s per a mรฉs informaciรณ
+scratch_code = Codi de recuperaciรณ
+use_scratch_code = Utilitzar un codi de recuperaciรณ
+twofa_scratch_token_incorrect = El codi de recuperaciรณ รฉs incorrecte.
+oauth_signup_title = Completar compte nou
+oauth_signup_submit = Completar compte
+oauth.signin.error.access_denied = S'ha denegat la solยทlicitud d'autoritzaciรณ.
+openid_connect_submit = Connectar
+openid_connect_title = Entreu a un compte existent
+openid_register_title = Crear un compte nou
+authorize_application = Autoritzar aplicaciรณ
+authorize_redirect_notice = Sereu redirigits a %s si autoritzeu aquesta aplicaciรณ.
+authorize_application_description = Si li concediu l'accรฉs podrร accedir i escriure a tota la informaciรณ del vostre compte, inclรฒs repositoris privats i organitzacions.
+authorize_title = Autoritzeu "%s" a accedir al vostre compte?
+active_your_account = Activeu el compte
+sign_up_successful = S'ha creat el compte correctament. Benvingut!
+account_activated = El compte s'ha activat
+send_reset_mail = Enviar correu electrรฒnic de recuperaciรณ del compte
+password_too_short = La longitud de la contrasenya no pot ser inferior a %d carร cters.
+oauth_signin_title = Entreu per a autoritzar el compte vinculat
+oauth_signin_submit = Vincular compte
+disable_forgot_password_mail = La recuperaciรณ de comptes estร deshabilitada perquรจ no hi ha configuraciรณ de correu electrรฒnic. Si us plau, contacteu amb l'administrador del lloc.
+email_domain_blacklisted = No podeu registrar-vos amb el correu electrรฒnic.
+hint_login = Ja tens compte? Entra ara!
+hint_register = Necessites un compte? Registra't ara.
+sign_up_button = Registra't ara.
+must_change_password = Actualitza la contrasenya
+change_unconfirmed_email_error = No s'ha pogut canviar l'adreรงa de correu: %v
+oauth_signup_tab = Registrar compte nou
+back_to_sign_in = Torneu a entrar
+openid_signin_desc = Introduรฏu la URI OpenID. Per exemple: alice.openid.example.org o https://openid.example.org/alice.
+authorize_application_created_by = Aquesta aplicaciรณ l'ha creat %s.
+password_pwned = La contrasenya que heu introduรฏt es troba en una llista de contrasenyes robades exposades en dades filtrades pรบblicament. Si us plau, intenteu-ho de nou amb una contrasenya diferent i considereu modificar aquesta contrasenya a tot arreu on la utilitzeu.
+use_onetime_code = Utilitzar un codi d'un sol รบs
+forgot_password_title = Contrasenya oblidada
+confirmation_mail_sent_prompt = S'ha enviat un correu electrรฒnic de confirmaciรณ a %s . Per tal de completar el registre, reviseu la safata d'entrada i seguiu l'enllaรง que se us ha enviat en els segรผents %s. Si l'adreรงa de correu รฉs incorrecta, podreu accedir al compte i demanar d'enviar un altre correu de confirmaciรณ a una altra adreรงa.
+prohibit_login_desc = S'ha suspรจs la interacciรณ del vostre compte amb la instร ncia. Contacteu amb l'administrador per a recuperar-ne l'accรฉs.
+change_unconfirmed_email = Si heu proporcionat una direcciรณ de correu incorrecta durant el registre, la podeu canviar aquรญ baix i se us enviarร una confirmaciรณ a l'adreรงa nova.
+resend_mail = Feu clic aquรญ per tornar a enviar el correu electrรฒnic d'activaciรณ
+twofa_passcode_incorrect = El codi d'accรฉs รฉs incorrecte. Si heu perdut el dispositiu, useu el codi de recuperaciรณ per a entrar.
+oauth_signin_tab = Vincular a un compte existent
+oauth.signin.error = Hi ha hagut un error processant la solยทlicitud d'autoritzaciรณ. Si persisteix, poseu-vos en contacte amb l'administrador del lloc.
+disable_forgot_password_mail_admin = La recuperaciรณ de comptes nomรฉs estร disponible quan s'ha configurat el correu electrรฒnic. Si us plau, configureu el correu electrรฒnic per a habilitar la recuperaciรณ de comptes.
+non_local_account = Els usuaris no locals no poden actualitzar la seva contrasenya mitjanรงant l'interfรญcie web de Forgejo
+openid_register_desc = No s'ha reconegut la URI OpenID. Vinculeu-la amb un compte nou aquรญ.
+openid_connect_desc = No s'ha reconegut la URI OpenID. Vinculeu-la amb un compte nou aquรญ.
+sign_in_openid = Accediu amb OpenID
+
+[editor]
+buttons.indent.tooltip = Aniua els elements un nivell
+buttons.unindent.tooltip = Desaniuna els elements un nivell
+buttons.ref.tooltip = Referenciar un problema o una "pull request"
+buttons.heading.tooltip = Afegir capรงalera
+buttons.bold.tooltip = Afegir text ressaltat
+buttons.italic.tooltip = Afegir text en cursiva
+buttons.switch_to_legacy.tooltip = En el seu lloc, utilitzar l'editor de codi antic
+buttons.quote.tooltip = Citar text
+buttons.enable_monospace_font = Habilitar la font monoespai
+buttons.disable_monospace_font = Deshabilita la font monoespai
+buttons.code.tooltip = Afegir codi
+buttons.link.tooltip = Afegir un enllaรง
+buttons.list.unordered.tooltip = Afegir un llista de punts
+buttons.list.ordered.tooltip = Afegir una llista enumerada
+buttons.list.task.tooltip = Afegir una llista de tasques
+buttons.mention.tooltip = Mencionar un usuari o equip
+buttons.new_table.tooltip = Afegir taula
+table_modal.header = Afegir taula
+table_modal.placeholder.header = Capรงalera
+table_modal.placeholder.content = Contingut
+table_modal.label.rows = Files
+table_modal.label.columns = Columnes
+link_modal.header = Afegeix un enllaรง
+link_modal.url = URL
+link_modal.description = Descripciรณ
+link_modal.paste_reminder = Pista: Amb un enllaรง en el teu porta-retalls, pots enganxar-la directament a l'editor per a crear un enllaรง.
+
+[home]
+my_orgs = Organitzacions
+show_more_repos = Mostra mรฉs repositorisโฆ
+show_both_archived_unarchived = Mostrant ambdรณs arxivats i no-arxivats
+show_only_public = Mostrant nomรฉs publics
+issues.in_your_repos = En els teus repositoris
+show_only_unarchived = Mostrant nomรฉs no-arxivats
+show_private = Privat
+show_both_private_public = Mostrant amdรณs publics i privats
+show_only_private = Mostrant nomรฉs privats
+filter_by_team_repositories = Filtra per respostirois d'equip
+feed_of = Canal de "%s"
+collaborative_repos = Respositoris coลlaboratius
+show_archived = Arxivat
+view_home = Veure %s
+password_holder = Contrasenya
+switch_dashboard_context = Commuta el contexte del tauler
+my_repos = Repositoris
+show_only_archived = Mostrant nomรฉs arxivats
+uname_holder = Nom d'usuari o direcciรณ de correu
+filter = Altres filtres
+
+[aria]
+footer.software = Sobre aquest software
+footer.links = Enllaรงos
+navbar = Barra de navegaciรณ
+footer = Peu de pร gina
+
+[mail]
+hi_user_x = Hola %s ,
+view_it_on = Veure a %s
+link_not_working_do_paste = No funciona l'enllaรง? Proveu a copiar-lo i enganxar-lo al navegador web.
+activate_account = Si us plau, activeu el compte
+reply = o responeu directament a aquest correu
+activate_account.text_1 = Hola %[1]s , grร cies per registrar-te a %[2]s!
+register_notify = Benvinguts a %s
+admin.new_user.text = Si us plau, cliqueu aui per administrar aquest usuari des del panell d'administraciรณ.
+admin.new_user.user_info = Informaciรณ d'usuari
+admin.new_user.subject = Nou usuari %s s'acaba d'enregistrar
+activate_email.text = Si us plau, cliqueu el segรผent enllaรง per verificar la vostra adreรงa de correu electrรฒnic en %s
+activate_email = Verifica la teva adreรงa de correu electrรฒnic
+activate_account.text_2 = Si us plau, cliqueu l'enllaรง segรผent per activar el vostre compte en %s :
\ No newline at end of file
diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini
index fbfde28fcd..cd28012f94 100644
--- a/options/locale/locale_cs-CZ.ini
+++ b/options/locale/locale_cs-CZ.ini
@@ -4,8 +4,8 @@ dashboard=Pลehled
explore=Prochรกzet
help=Nรกpovฤda
logo=Logo
-sign_in=Pลihlรกลกenรญ
-sign_in_with_provider=Pลihlรกsit se pomocรญ %s
+sign_in=Pลihlรกsit se
+sign_in_with_provider = Pลihlรกsit se pลes %s
sign_in_or=nebo
sign_out=Odhlรกsit se
sign_up=Registrace
@@ -23,7 +23,7 @@ create_new=Vytvoลitโฆ
user_profile_and_more=Profil a nastavenรญโฆ
signed_in_as=Pลihlรกลกen/a jako
enable_javascript=Tato strรกnka vyลพaduje JavaScript.
-toc=Obsah
+toc=Tabulka obsahu
licenses=Licence
return_to_forgejo=Vrรกtit se do Forgejo
@@ -33,7 +33,7 @@ password=Heslo
access_token=Pลรญstupovรฝ token
re_type=Potvrzenรญ hesla
captcha=CAPTCHA
-twofa=Dvoufaktorovรฉ ovฤลovรกnรญ
+twofa=Dvoufรกzovรฉ ovฤลenรญ
twofa_scratch=Dvoufaktorovรฝ kรณd
passcode=Pลรญstupovรฝ kรณd
@@ -112,7 +112,7 @@ preview=Nรกhled
loading=Naฤรญtรกnรญโฆ
error=Chyba
-error404=Strรกnka, kterou se snaลพรญte zobrazit, buฤ neexistuje , nebo nemรกte oprรกvnฤnรญ ji zobrazit.
+error404=Strรกnka, kterou se snaลพรญte zobrazit, buฤ neexistuje , byla odstranฤna nebo nemรกte oprรกvnฤnรญ ji zobrazit.
go_back=Zpฤt
never=Nikdy
@@ -124,8 +124,7 @@ pin=Pลipnout
unpin=Odepnout
artifacts=Artefakty
-confirm_delete_artifact=Jste si jisti, ลพe chcete odstranit artefakt โ%sโ?
-
+confirm_delete_artifact = Opravdu chcete odstranit artefakt โ%sโ?
archived=Archivovรกno
concept_system_global=Globรกlnรญ
@@ -142,8 +141,6 @@ confirm_delete_selected=Potvrdit odstranฤnรญ vลกech vybranรฝch poloลพek?
name=Nรกzev
value=Hodnota
-sign_in_with_provider = Pลihlรกsit se pลes %s
-confirm_delete_artifact = Opravdu chcete odstranit artefakt โ%sโ?
toggle_menu = Pลepnout nabรญdku
filter = Filtr
filter.is_fork = Forky
@@ -160,6 +157,15 @@ filter.clear = Vymazat filtry
more_items = Dalลกรญ poloลพky
invalid_data = Neplatnรก data: %v
copy_generic = Kopรญrovat do schrรกnky
+test = Test
+error413 = Vyฤerpali jste svou kvรณtu.
+new_repo.title = Novรฝ repozitรกล
+new_migrate.title = Novรก migrace
+new_org.title = Novรก organizace
+new_repo.link = Novรฝ repozitรกล
+new_migrate.link = Novรก migrace
+new_org.link = Novรก organizace
+copy_path = Kopรญrovat cestu
[aria]
navbar=Navigaฤnรญ liลกta
@@ -191,6 +197,18 @@ buttons.ref.tooltip=Odkรกzat na problรฉm nebo ลพรกdost o slouฤenรญ
buttons.switch_to_legacy.tooltip=Pouลพรญt starลกรญ editor
buttons.enable_monospace_font=Zapnout neproporcionรกlnรญ pรญsmo
buttons.disable_monospace_font=Vypnout neproporcionรกlnรญ pรญsmo
+buttons.unindent.tooltip = Zruลกit vnoลenรญ poloลพek pod jednu รบroveล
+buttons.indent.tooltip = Vnoลit poloลพky pod jednu รบroveล
+buttons.new_table.tooltip = Pลidat tabulku
+table_modal.header = Pลidat tabulku
+table_modal.placeholder.header = Zรกhlavรญ
+table_modal.placeholder.content = Obsah
+table_modal.label.rows = ลรกdky
+table_modal.label.columns = Sloupce
+link_modal.header = Pลidat odkaz
+link_modal.url = URL
+link_modal.description = Popis
+link_modal.paste_reminder = Tip: pokud mรกte adresu zkopรญrovanou ve schrรกnce, mลฏลพete vytvoลit odkaz jejรญm vloลพenรญm pลรญmo do editoru.
[filter]
string.asc=A โ Z
@@ -198,7 +216,7 @@ string.desc=Z โ A
[error]
occurred=Doลกlo k chybฤ
-report_message=Pokud jste si jisti, ลพe se jednรก o chybu software Forgejo, vyhledejte prosรญm problรฉmy ve sluลพbฤ Codeberg a v pลรญpadฤ potลeby zaloลพte novรฝ problรฉm.
+report_message=Pokud jste si jisti, ลพe se jednรก o chybu software Forgejo, vyhledejte prosรญm problรฉmy ve sluลพbฤ Codeberg a v pลรญpadฤ potลeby zaloลพte novรฝ problรฉm.
missing_csrf=Nesprรกvnรฝ poลพadavek: nenalezen token CSRF
invalid_csrf=Nesprรกvnรฝ poลพadavek: neplatnรฝ token CSRF
not_found=Cรญl nebyl nalezen.
@@ -206,15 +224,15 @@ network_error=Chyba sรญtฤ
server_internal = Internรญ chyba serveru
[startpage]
-app_desc=Bezproblรฉmovรก samostatnฤ hostovatelnรก sluลพba Git
+app_desc=Jednoduchรก, samostatnฤ hostovatelnรก sluลพba Git
install=Jednoduchรฉ na instalaci
-install_desc=Jednoduลกe spusลฅte binรกrnรญ soubor pro vaลกi platformu, nasaฤte jej pomocรญ Dockeru nebo si jej stรกhnฤte jako balรญฤek .
+install_desc=Jednoduลกe spusลฅte binรกrnรญ soubor pro vaลกi platformu, nasaฤte jej pomocรญ Dockeru nebo si jej stรกhnฤte jako balรญฤek .
platform=Multiplatformnรญ
-platform_desc=Forgejo bฤลพรญ na vลกech platformรกch, na kterรฉ dokรกลพe kompilovat jazyk Go : Windows, macOS, Linux, ARM, atd. Vรฝbฤr je opravdu velkรฝ!
+platform_desc=Forgejo bฤลพรญ na svobodnรฝch operaฤnรญch systรฉmech, jako je Linux a FreeBSD, stejnฤ jako na rลฏznรฝch architekturรกch CPU. Vyberte si takovou kombinaci, jakou mรกte rรกdi!
lightweight=Lehkรฉ
lightweight_desc=Forgejo mรก nรญzkรฉ minimรกlnรญ poลพadavky a dokรกลพe bฤลพet i na levnรฉm Raspberry Pi. ล etลete energii vaลกeho stroje!
license=Open Source
-license_desc=Vyzkouลกejte Forgejo ! Pลipojte se k nรกm, pลispฤjte a vylepลกete tento projekt. Nebojte se pลispฤt!
+license_desc=Vyzkouลกejte Forgejo ! Pลipojte se k nรกm, pลispฤjte a vylepลกete tento projekt. Nebojte se pลispฤt!
[install]
install=Instalace
@@ -241,7 +259,7 @@ err_empty_db_path=Cesta k databรกzi SQLite3 nemลฏลพe bรฝt prรกzdnรก.
no_admin_and_disable_registration=Nelze vypnout registraci รบฤtลฏ bez vytvoลenรญ รบฤtu administrรกtora.
err_empty_admin_password=Heslo administrรกtora nemลฏลพe bรฝt prรกzdnรฉ.
err_empty_admin_email=E-mail administrรกtora nemลฏลพe bรฝt prรกzdnรฝ.
-err_admin_name_is_reserved=Uลพivatelskรฉ jmรฉno administrรกtora nenรญ platnรฉ, uลพivatelskรฉ jmรฉno je rezervovanรฉ
+err_admin_name_is_reserved=Uลพivatelskรฉ jmรฉno administrรกtora nenรญ platnรฉ, jmรฉno je rezervovanรฉ
err_admin_name_pattern_not_allowed=Uลพivatelskรฉ jmรฉno administrรกtora je neplatnรฉ, uลพivatelskรฉ jmรฉno odpovรญdรก vyhrazenรฉmu vzoru
err_admin_name_is_invalid=Uลพivatelskรฉ jmรฉno administrรกtora nenรญ platnรฉ
@@ -400,14 +418,14 @@ forgot_password_title=Zapomenutรฉ heslo
forgot_password=Zapomenutรฉ heslo?
sign_up_now=Nemรกte รบฤet? Zaregistrujte se.
sign_up_successful=รฤet byl รบspฤลกnฤ vytvoลen. Vรญtejte!
-confirmation_mail_sent_prompt=Na adresu %s byl zaslรกn novรฝ potvrzovacรญ e-mail. Zkontrolujte prosรญm vaลกi doruฤenou poลกtu bฤhem nรกsledujรญcรญch %s, abyste dokonฤili proces registrace. Pokud jste zadali nesprรกvnรฝ e-mail, mลฏลพete se pลihlรกsit a poลพรกdat o poslรกnรญ novรฉho potvrzovacรญho e-mailu na jinou adresu.
+confirmation_mail_sent_prompt=Na adresu %s byl zaslรกn novรฝ potvrzovacรญ e-mail. Pro dokonฤenรญ procesu registrace prosรญm zkontrolujte svou schrรกnku a kliknฤte na poskytnutรฝ odkaz do %s. Pokud jste zadali nesprรกvnรฝ e-mail, mลฏลพete se pลihlรกsit a poลพรกdat o poslรกnรญ novรฉho potvrzovacรญho e-mailu na jinou adresu.
must_change_password=Zmฤลte svรฉ heslo
allow_password_change=Vyลพรกdat od uลพivatele zmฤnu hesla (doporuฤeno)
-reset_password_mail_sent_prompt=Na adresu %s byl zaslรกn potvrzovacรญ e-mail. Zkontrolujte prosรญm vaลกi doruฤenou poลกtu bฤhem nรกsledujรญcรญch %s pro dokonฤenรญ procesu obnovenรญ รบฤtu.
+reset_password_mail_sent_prompt=Na adresu %s byl zaslรกn potvrzovacรญ e-mail. Pro dokonฤenรญ procesu obnovy รบฤtu prosรญm zkontrolujte vaลกi schrรกnku a nรกsledujte poskytnutรฝ odkaz bฤhem dalลกรญch %s.
active_your_account=Aktivujte si vรกลก รบฤet
account_activated=รฤet byl aktivovรกn
-prohibit_login=Pลihlaลกovรกnรญ je zakรกzรกno
-prohibit_login_desc=Vaลกemu รบฤtu je zakรกzรกno se pลihlรกsit, kontaktujte prosรญm sprรกvce webu.
+prohibit_login=รฤet je pozastaven
+prohibit_login_desc=Vรกลก รบฤet byl pozastaven z interakcรญ s instancรญ. Pro opฤtovnรฉ zรญskรกnรญ pลรญstupu kontaktujte sprรกvce instance.
resent_limit_prompt=Omlouvรกme se, ale nedรกvno jste jiลพ poลพรกdali o zaslรกnรญ aktivaฤnรญho e-mailu. Poฤkejte prosรญm 3 minuty a zkuste to znovu.
has_unconfirmed_mail=Zdravรญme, %s, mรกte nepotvrzenou e-mailovou adresu (%s ). Pokud jste nedostali e-mail pro potvrzenรญ nebo potลebujete zaslat novรฝ, kliknฤte prosรญm na tlaฤรญtko nรญลพe.
resend_mail=Kliknฤte sem pro opฤtovnรฉ odeslรกnรญ aktivaฤnรญho e-mailu
@@ -424,7 +442,7 @@ non_local_account=Externฤ ovฤลovanรญ uลพivatelรฉ nemohou zmฤnit svรฉ heslo p
verify=Ovฤลit
scratch_code=Zรกloลพnรญ kรณd
use_scratch_code=Pouลพรญt zรกloลพnรญ kรณd
-twofa_scratch_used=Pouลพili jste vรกลก zรกloลพnรญ kรณd. Byli jste pลesmฤrovรกnรญ na strรกnku s nastavenรญm dvoufaktorovรฉho ovฤลovรกnรญ, kde mลฏลพete odstranit registraci vaลกeho zaลรญzenรญ nebo vygenerovat novรฝ zรกloลพnรญ kรณd.
+twofa_scratch_used=Pouลพili jste svลฏj zรกloลพnรญ kรณd. Byli jste pลesmฤrovรกnรญ na strรกnku s nastavenรญm dvoufรกzovรฉho ovฤลenรญ, kde mลฏลพete odstranit registraci vaลกeho zaลรญzenรญ nebo vygenerovat novรฝ zรกloลพnรญ kรณd.
twofa_passcode_incorrect=Vaลกe heslo je neplatnรฉ. Pokud jste ztratili vaลกe zaลรญzenรญ, pouลพijte zรกloลพnรญ kรณd k pลihlรกลกenรญ.
twofa_scratch_token_incorrect=Vรกลก zรกloลพnรญ kรณd nenรญ sprรกvnรฝ.
login_userpass=Pลihlรกsit se
@@ -455,7 +473,7 @@ authorize_title=Autorizovat โ%sโ pro pลรญstup k vaลกemu รบฤtu?
authorization_failed=Autorizace selhala
authorization_failed_desc=Autorizace selhala, protoลพe jsme detekovali neplatnรฝ poลพadavek. Kontaktujte prosรญm sprรกvce aplikace, kterou jste se pokouลกeli autorizovat.
sspi_auth_failed=SSPI autentizace selhala
-password_pwned=Heslo, kterรฉ jste zvolili, je na seznamu odcizenรฝch hesel , kterรก byla dลรญve odhalena pลi naruลกenรญ veลejnรฝch dat. Zkuste to prosรญm znovu s jinรฝm heslem.
+password_pwned=Heslo, kterรฉ jste zvolili, je na seznamu odcizenรฝch hesel , kterรก byla dลรญve odhalena pลi naruลกenรญ veลejnรฝch dat. Zkuste to prosรญm znovu s jinรฝm heslem.
password_pwned_err=Nelze dokonฤit poลพadavek na HaveIBeenPwned
change_unconfirmed_email = Pokud jste pลi registraci zadali nesprรกvnou e-mailovou adresu, mลฏลพete ji zmฤnit nรญลพe. Potvrzovacรญ e-mail bude mรญsto toho odeslรกn na novou adresu.
change_unconfirmed_email_error = Nepodaลilo se zmฤnit e-mailovou adresu: %v
@@ -463,6 +481,13 @@ change_unconfirmed_email_summary = Zmฤna e-mailovรฉ adresy, na kterou bude odes
last_admin=Nelze odstranit poslednรญho sprรกvce. Musรญ existovat alespoล jeden sprรกvce.
tab_signup = Registrace
tab_signin = Pลihlรกลกenรญ
+hint_login = Jiลพ mรกte รบฤet? Pลihlaste se!
+hint_register = Nemรกte รบฤet? Zaregistrujte se nynรญ.
+sign_up_button = Zaregistrujte se nynรญ.
+back_to_sign_in = Zpฤt na pลihlรกลกenรญ
+sign_in_openid = Pokraฤovat s OpenID
+unauthorized_credentials = รdaje jsou nesprรกvnรฉ nebo vyprลกely. Opakujte svลฏj pลรญkaz nebo se podรญvejte na %s pro vรญce informacรญ
+use_onetime_code = Pouลพรญt jednorรกzovรฝ kรณd
[mail]
view_it_on=Zobrazit na %s
@@ -473,13 +498,13 @@ hi_user_x=Ahoj %s ,
activate_account=Prosรญme, aktivujte si vรกลก รบฤet
activate_account.title=%s, prosรญm aktivujte si vรกลก รบฤet
activate_account.text_1=Ahoj %[1]s , dฤkujeme za registraci na %[2]s!
-activate_account.text_2=Pro aktivaci vaลกeho รบฤtu do %s kliknฤte na nรกsledujรญcรญ odkaz:
+activate_account.text_2=Pro aktivaci vaลกeho รบฤtu kliknฤte %s na nรกsledujรญcรญ odkaz :
activate_email=Ovฤลte vaลกi e-mailovou adresu
activate_email.title=%s, prosรญm ovฤลte vaลกi e-mailovou adresu
-activate_email.text=Pro aktivaci vaลกeho รบฤtu do %s kliknฤte na nรกsledujรญcรญ odkaz:
+activate_email.text=Pro ovฤลenรญ vaลกรญ e-mailovรฉ adresy kliknฤte %s na nรกsledujรญcรญ odkaz:
-register_notify=Vรญtejte v Forgejo
+register_notify=Vรญtejte v %s
register_notify.title=%[1]s vรญtejte v %[2]s
register_notify.text_1=toto je vรกลก potvrzovacรญ e-mail pro %s!
register_notify.text_2=Do svรฉho รบฤtu se mลฏลพete pลihlรกsit svรฝm uลพivatelskรฝm jmรฉnem: %s
@@ -496,8 +521,8 @@ issue_assigned.issue=@%[1]s vรกs pลiลadil/a k problรฉmu %[2]s v repozitรกลi %
issue.x_mentioned_you=@%s vรกs zmรญnil/a:
issue.action.force_push=%[1]s vynutil/a nahrรกnรญ %[2]s z %[3]s do %[4]s.
-issue.action.push_1=@%[1]s nahrรกl/a %[3]d commit do %[2]s
-issue.action.push_n=@%[1]s nahrรกl/a %[3]d commity do %[2]s
+issue.action.push_1=Uลพivatel @%[1]s nahrรกl %[3]d revizi do %[2]s
+issue.action.push_n=Uลพivatel @%[1]s nahrรกl %[3]d revizรญ do %[2]s
issue.action.close=@%[1]s uzavลel/a #%[2]d.
issue.action.reopen=@%[1]s znovu otevลel/a #%[2]d.
issue.action.merge=@%[1]s slouฤil/a #%[2]d do %[3]s.
@@ -532,6 +557,21 @@ team_invite.text_3=Poznรกmka: Tato pozvรกnka byla urฤena pro %[1]s. Pokud jste
admin.new_user.user_info = Informace o uลพivateli
admin.new_user.text = Kliknฤte sem pro sprรกvu tohoto uลพivatele z administrรกtorskรฉho panelu.
admin.new_user.subject = Prรกvฤ se zaregistroval novรฝ uลพivatel %s
+totp_disabled.subject = TOTP bylo zakรกzรกno
+password_change.subject = Vaลกe heslo bylo zmฤnฤno
+password_change.text_1 = Heslo vaลกeho รบฤtu bylo prรกvฤ zmฤnฤno.
+primary_mail_change.subject = Vรกลก primรกrnรญ e-mail byl zmฤnฤn
+primary_mail_change.text_1 = Primรกrnรญ e-mail vaลกeho รบฤtu byl prรกvฤ zmฤnฤn na %[1]s. To znamenรก, ลพe tato e-mailovรก adresa jiลพ nebude zรญskรกvat e-mailovรก oznรกmenรญ z vaลกeho รบฤtu.
+totp_disabled.text_1 = ฤasovฤ zaloลพenรฉ jednorรกzovรฉ heslo (TOTP) u vaลกeho รบฤtu bylo prรกvฤ zakรกzรกno.
+totp_disabled.no_2fa = Nemรกte nastavenรฉ ลพรกdnรฉ dalลกรญ 2FA metody, takลพe se jiลพ nemusรญte pลihlaลกovat do svรฉho รบฤtu pomocรญ 2FA.
+removed_security_key.subject = Byl odstranฤn bezpeฤnostnรญ klรญฤ
+removed_security_key.text_1 = Bezpeฤnostnรญ klรญฤ โ%[1]sโ byl prรกvฤ odstranฤn z vaลกeho รบฤtu.
+removed_security_key.no_2fa = Nemรกte nastavenรฉ ลพรกdnรฉ dalลกรญ 2FA metody, takลพe se jiลพ nemusรญte pลihlaลกovat do svรฉho รบฤtu pomocรญ 2FA.
+account_security_caution.text_1 = Pokud jste to byli vy, mลฏลพete tento e-mail v klidu ignorovat.
+account_security_caution.text_2 = Pokud jste to nebyli vy, vรกลก รบฤet byl kompromitovรกn. Kontaktujte prosรญm sprรกvce tohoto webu.
+totp_enrolled.subject = Aktivovali jste TOTP jako metodu 2FA
+totp_enrolled.text_1.no_webauthn = Prรกvฤ jste povolili TOTP u vaลกeho รบฤtu. To znamenรก, ลพe pro vลกechna budoucรญ pลihlรกลกenรญ do vaลกeho รบฤtu budete muset pouลพรญt TOTP jako metodu 2FA.
+totp_enrolled.text_1.has_webauthn = Prรกvฤ jste povolili TOTP u vaลกeho รบฤtu. To znamenรก, ลพe pro vลกechna budoucรญ pลihlรกลกenรญ do vaลกeho รบฤtu mลฏลพete pouลพรญt TOTP jako metodu 2FA nebo pouลพรญt jakรฝkoli z vaลกich bezpeฤnostnรญch klรญฤลฏ.
[modal]
yes=Ano
@@ -554,9 +594,9 @@ AuthName=Nรกzev ovฤลenรญ
AdminEmail=E-mailovรก adresa sprรกvce
NewBranchName=Nรกzev novรฉ vฤtve
-CommitSummary=Shrnutรญ commity
-CommitMessage=Zprรกva commitu
-CommitChoice=Vรฝbฤr commitu
+CommitSummary=Shrnutรญ revize
+CommitMessage=Zprรกva revize
+CommitChoice=Vรฝbฤr revize
TreeName=Cesta k souboru
Content=Obsah
@@ -592,7 +632,7 @@ repository_files_already_exist.adopt=Soubory pro tento repozitรกล jiลพ existuj
repository_files_already_exist.delete=Soubory pro tento repozitรกล jiลพ existujรญ. Musรญte je odstranit.
repository_files_already_exist.adopt_or_delete=Soubory pro tento repozitรกล jiลพ existujรญ. Pลijmฤte je, nebo je odstraลte.
visit_rate_limit=Dosaลพeno limitu rychlosti dotazลฏ pลi vzdรกlenรฉm pลรญstupu.
-2fa_auth_required=Vzdรกlenรฝ pลรญstup vyลพaduje dvoufaktorovรฉ ovฤลovรกnรญ.
+2fa_auth_required=Vzdรกlenรฝ pลรญstup vyลพaduje dvoufรกzovรฉ ovฤลenรญ.
org_name_been_taken=Nรกzev organizace je jiลพ pouลพit.
team_name_been_taken=Nรกzev tรฝmu je jiลพ pouลพit.
team_no_units_error=Povolit pลรญstup alespoล do jednรฉ sekce repozitรกลe.
@@ -616,8 +656,8 @@ cannot_add_org_to_team=Organizace nemลฏลพe bรฝt pลidรกna jako ฤlen tรฝmu.
duplicate_invite_to_team=Uลพivatel byl jiลพ pozvรกn jako ฤlen tรฝmu.
organization_leave_success=รspฤลกnฤ jste opustili organizaci %s.
-invalid_ssh_key=Nelze ovฤลit vรกลก SSH klรญฤ: %s
-invalid_gpg_key=Nelze ovฤลit vรกลก GPG klรญฤ: %s
+invalid_ssh_key=Nepodaลilo se ovฤลit vรกลก klรญฤ SSH: %s
+invalid_gpg_key=Nepodaลilo se ovฤลit vรกลก klรญฤ GPG: %s
invalid_ssh_principal=Neplatnรฝ SSH Principal certifikรกt: %s
must_use_public_key=Zadanรฝ klรญฤ je soukromรฝ klรญฤ. Nenahrรกvejte svลฏj soukromรฝ klรญฤ nikde. Mรญsto toho pouลพijte vรกลก veลejnรฝ klรญฤ.
unable_verify_ssh_key=Nepodaลilo se ovฤลit klรญฤ SSH, zkontrolujte, zda neobsahuje chyby.
@@ -630,10 +670,9 @@ org_still_own_repo=Organizace stรกle vlastnรญ jeden nebo vรญce repozitรกลลฏ. Ne
org_still_own_packages=Organizace stรกle vlastnรญ jeden nebo vรญce balรญฤkลฏ. Nejdลรญve je odstraลte.
target_branch_not_exist=Cรญlovรก vฤtev neexistuje.
-admin_cannot_delete_self = Nemลฏลพete odstranit sami sebe, kdyลพ jste administrรกtorem. Nejprve prosรญm odeberte svรก prรกva administrรกtora.
+admin_cannot_delete_self=Nemลฏลพete se smazat, dokud jste sprรกvce. Nejdลรญve prosรญm odeberte svรก administrรกtorskรก oprรกvnฤnรญ.
username_error_no_dots = ` mลฏลพe obsahovat pouze alfanumerickรฉ znaky (โ0-9โ, โa-zโ, โA-Zโ), pomlฤky (โ-โ) a podtrลพรญtka (โ_โ). Nemลฏลพe zaฤรญnat nebo konฤit nealfanumerickรฝmi znaky. Jsou takรฉ zakรกzรกny po sobฤ jdoucรญ nealfanumerickรฉ znaky.`
-admin_cannot_delete_self=Nemลฏลพete se smazat, dokud jste sprรกvce. Nejdลรญve prosรญm odeberte svรก administrรกtorskรก oprรกvnฤnรญ.
unset_password = Tento uลพivatel nemรก nastavenรฉ heslo.
unsupported_login_type = U tohoto typu รบฤtu nenรญ funkce odstranฤnรญ รบฤtu podporovรกna.
required_prefix = Vstup musรญ zaฤรญnat textem โ%sโ
@@ -645,6 +684,8 @@ Location = Umรญstฤnรญ
To = Nรกzev vฤtve
Biography = ลฝivotopis
AccessToken = Pลรญstupovรฝ token
+username_claiming_cooldown = Uลพivatelskรฉ jmรฉno nelze zรญskat, protoลพe jeลกtฤ neskonฤila doba jeho platnosti. Pลฏjde jej zรญskat %[1]s.
+email_domain_is_not_allowed = Domรฉna uลพivatelskรฉ e-mailovรฉ adresy %s je v rozporu se seznamem EMAIL_DOMAIN_ALLOWLIST nebo EMAIL_DOMAIN_BLOCKLIST. Ujistฤte se, ลพe je vaลกe adresa sprรกvnฤ nastavena.
[user]
change_avatar=Zmฤnit vรกลก avatarโฆ
@@ -657,7 +698,7 @@ watched=Sledovanรฉ repozitรกลe
code=Kรณd
projects=Projekty
overview=Pลehled
-following_few=%d sledovanรญ
+following_few=%d sledovanรฝch
follow=Sledovat
unfollow=Pลestat sledovat
user_bio=ลฝivotopis
@@ -679,7 +720,7 @@ follow_blocked_user = Tohoto uลพivatele nemลฏลพete sledovat, protoลพe jste si je
block = Zablokovat
unblock = Odblokovat
followers_one = %d sledujรญcรญ
-following_one = %d nรกsleduje
+following_one = %d sledovanรฝ
followers.title.one = Sledujรญcรญ
followers.title.few = Sledujรญcรญ
following.title.one = Sleduje
@@ -688,6 +729,7 @@ public_activity.visibility_hint.self_private = Vaลกe aktivita je viditelnรก pouz
public_activity.visibility_hint.admin_private = Tato aktivita je pro vรกs viditelnรก, protoลพe jste administrรกtor, ale uลพivatel chce, aby zลฏstala soukromรก.
public_activity.visibility_hint.self_public = Vaลกe aktivita je viditelnรก vลกem, mimo interakcรญ v soukromรฝch prostorech. Nastavenรญ .
public_activity.visibility_hint.admin_public = Tato aktivita je viditelnรก vลกem, ale jako administrรกtor takรฉ mลฏลพete vidฤt interakce v soukromรฝch prostorech.
+public_activity.visibility_hint.self_private_profile = Vaลกe aktivita je viditelnรก pouze vรกm a sprรกvcลฏm instance, protoลพe vรกลก profil je soukromรฝ. Nastavit .
[settings]
profile=Profil
@@ -702,16 +744,16 @@ applications=Aplikace
orgs=Organizace
repos=Repozitรกลe
delete=Smazat รบฤet
-twofa=Dvoufaktorovรฉ ovฤลovรกnรญ (TOTP)
+twofa=Dvoufรกzovรฉ ovฤลenรญ (TOTP)
account_link=Propojenรฉ รบฤty
organization=Organizace
uid=UID
-webauthn=Dvoufaktorovรฉ ovฤลovรกnรญ (bezpeฤnostnรญ klรญฤe)
+webauthn=Dvoufรกzovรฉ ovฤลenรญ (bezpeฤnostnรญ klรญฤe)
public_profile=Veลejnรฝ profil
-biography_placeholder=ลeknฤte nรกm nฤco o sobฤ! (Mลฏลพete pouลพรญt Markdown)
+biography_placeholder=ลeknฤte ostatnรญm nฤco o sobฤ! (Je podporovรกn Markdown)
location_placeholder=Sdรญlejte svou pลibliลพnou polohu s ostatnรญmi
-profile_desc=Nastavte, jak bude vรกลก profil zobrazen ostatnรญm uลพivatelลฏm. Vaลกe hlavnรญ e-mailovรก adresa bude pouลพita pro oznรกmenรญ, obnovenรญ hesla a operace Git.
+profile_desc=O vรกs
password_username_disabled=Externรญ uลพivatelรฉ nemohou mฤnit svoje uลพivatelskรฉ jmรฉno. Kontaktujte prosรญm svรฉho administrรกtora pro vรญce detailลฏ.
full_name=Celรฉ jmรฉno
website=Web
@@ -731,7 +773,7 @@ language=Jazyk
ui=Motiv vzhledu
hidden_comment_types=Skrytรฉ typy komentรกลลฏ
hidden_comment_types_description=Zde zkontrolovanรฉ typy komentรกลลฏ nebudou zobrazeny na strรกnkรกch problรฉmลฏ. Zaลกkrtnutรญ โล tรญtekโ napลรญklad odstranรญ vลกechny komentรกลe โ pลidal/odstranil โ.
-hidden_comment_types.ref_tooltip=Komentรกลe, kde byl tento problรฉm odkรกzรกn u jinรฉho problรฉmu/commitu/โฆ
+hidden_comment_types.ref_tooltip=Komentรกลe, kde byl tento problรฉm odkรกzรกn z jinรฉho problรฉmu/revize/โฆ
hidden_comment_types.issue_ref_tooltip=Komentรกลe, kde uลพivatel zmฤnรญ vฤtev/znaฤku spojenou s problรฉmem
comment_type_group_reference=Reference
comment_type_group_label=ล tรญtek
@@ -744,7 +786,7 @@ comment_type_group_deadline=Uzรกvฤrka
comment_type_group_dependency=Zรกvislost
comment_type_group_lock=Stav zรกmku
comment_type_group_review_request=ลฝรกdost o posouzenรญ
-comment_type_group_pull_request_push=Pลidanรฉ commity
+comment_type_group_pull_request_push=Pลidanรฉ revize
comment_type_group_project=Projekt
comment_type_group_issue_ref=Referenฤnรญ ฤรญslo problรฉmu
saved_successfully=Vaลกe nastavenรญ bylo รบspฤลกnฤ uloลพeno.
@@ -768,7 +810,7 @@ old_password=Stรกvajรญcรญ heslo
new_password=Novรฉ heslo
retype_new_password=Potvrzenรญ novรฉho hesla
password_incorrect=Zadanรฉ heslo nenรญ sprรกvnรฉ.
-change_password_success=Vaลกe heslo bylo aktualizovรกno. Od teฤ se pลihlaลกujte novรฝm heslem.
+change_password_success=Vaลกe heslo bylo aktualizovรกno. Od nynฤjลกka pouลพรญvejte kpลihlรกลกenรญ novรฉ heslo.
password_change_disabled=Externฤ ovฤลovanรญ uลพivatelรฉ nemohou aktualizovat svรฉ heslo prostลednictvรญm webovรฉho rozhranรญ Forgejo.
emails=E-mailovรฉ adresy
@@ -776,7 +818,7 @@ manage_emails=Sprรกva e-mailovรฝch adres
manage_themes=Vรฝchozรญ motiv
manage_openid=Adresy OpenID
email_desc=Vaลกe hlavnรญ e-mailovรก adresa bude pouลพita pro oznรกmenรญ, obnovenรญ hesla, a pokud nenรญ skrytรก, pro operace Gitu.
-theme_desc=Toto bude vรกลก vรฝchozรญ motiv vzhledu napลรญฤ strรกnkou.
+theme_desc=Tento motiv se pouลพije pro webovรฉ rozhranรญ, kdyลพ jste pลihlรกลกeni.
primary=Hlavnรญ
activated=Aktivovรกn
requires_activation=Vyลพaduje aktivaci
@@ -786,7 +828,7 @@ activations_pending=ฤekajรญcรญ aktivace
can_not_add_email_activations_pending=Existuje ฤekajรญcรญ aktivace, zkuste to znovu za pรกr minut, pokud chcete pลidat novรฝ e-mail.
delete_email=Smazat
email_deletion=Odstranit e-mailovou adresu
-email_deletion_desc=E-mailovรก adresa a pลidruลพenรฉ informace budou z vaลกeho รบฤtu odstranฤny. Commity Gitu s touto e-mailovou adresou zลฏstanou nezmฤnฤny. Pokraฤovat?
+email_deletion_desc=E-mailovรก adresa a pลidruลพenรฉ informace budou z vaลกeho รบฤtu odstranฤny. Revize Gitu s touto e-mailovou adresou zลฏstanou nezmฤnฤny. Pokraฤovat?
email_deletion_success=E-mailovรก adresa byla odstranฤna.
theme_update_success=Vรกลก motiv vzhledu byl aktualizovรกn.
theme_update_error=Vybranรฝ motiv vzhledu neexistuje.
@@ -797,78 +839,78 @@ add_new_email=Pลidat e-mailovou adresu
add_new_openid=Pลidat novou OpenID URI
add_email=Pลidat e-mailovou adresu
add_openid=Pลidat OpenID URI
-add_email_confirmation_sent=Potvrzovacรญ e-mail byl odeslรกn na โ%sโ. Prosรญm zkontrolujte pลรญchozรญ poลกtu bฤhem nรกsledujรญcรญch %s pro potvrzenรญ vaลกรญ e-mailovรฉ adresy.
+add_email_confirmation_sent=Potvrzovacรญ e-mail byl odeslรกn na โ%sโ. Pro potvrzenรญ vaลกรญ e-mailovรฉ adresy prosรญm navลกtivte vaลกi schrรกnku a nรกsledujte poskytnutรฝ odkaz bฤhem dalลกรญch %s.
add_email_success=Novรก e-mailovรก adresa byla pลidรกna.
email_preference_set_success=Nastavenรญ e-mailu bylo รบspฤลกnฤ nastaveno.
add_openid_success=Novรก OpenID adresa byla pลidรกna.
keep_email_private=Skrรฝt e-mailovou adresu
-keep_email_private_popup=Toto skryje vaลกi e-mailovou adresu z vaลกeho profilu, stejnฤ jako pลi vytvoลenรญ pull requestu nebo รบpravฤ souboru pomocรญ webovรฉho rozhranรญ. Odeslanรฉ commity nebudou zmฤnฤny. Pouลพijte %s v commitech pro jejich pลiลazenรญ k vaลกemu รบฤtu.
+keep_email_private_popup=Vaลกe e-mailovรก adresa nebude zobrazena na vaลกem profilu a nebude vรฝchozรญ adresou pro revize provedenรฉ skrze webovรฉ rozhranรญ, jako nahrรกvรกnรญ, รบpravy a sluฤovรกnรญ. Namรญsto toho lze pouลพรญt speciรกlnรญ adresu %s pro propojenรญ revizรญ s vaลกรญm รบฤtem. Tato moลพnost neovlivnรญ existujรญcรญ revize.
openid_desc=OpenID vรกm umoลพnรญ delegovat ovฤลovรกnรญ na externรญho poskytovatele.
manage_ssh_keys=Sprรกva klรญฤลฏ SSH
manage_ssh_principals=Spravovat SSH Principal certifikรกty
manage_gpg_keys=Sprรกva klรญฤลฏ GPG
add_key=Pลidat klรญฤ
-ssh_desc=Tyto veลejnรฉ klรญฤe SSH jsou propojeny s vaลกรญm รบฤtem. Odpovรญdajรญcรญ soukromรฉ klรญฤe umoลพnรญ plnรฝ pลรญstup k vaลกim repozitรกลลฏm. Klรญฤe SSH, kterรฉ byly ovฤลeny, mohou bรฝt pouลพity pro ovฤลenรญ Git commitลฏ podepsanรฝch pลes SSH.
+ssh_desc=Tyto veลejnรฉ klรญฤe SSH jsou propojeny s vaลกรญm รบฤtem. Odpovรญdajรญcรญ soukromรฉ klรญฤe umoลพnรญ plnรฝ pลรญstup k vaลกim repozitรกลลฏm. Klรญฤe SSH, kterรฉ byly ovฤลeny, mohou bรฝt pouลพity pro ovฤลenรญ Git revizรญ podepsanรฝch pลes SSH.
principal_desc=Tyto SSH Principal certifikรกty jsou pลidruลพeny k vaลกemu รบฤtu a umoลพลujรญ plnรฝ pลรญstup do vaลกich repozitรกลลฏ.
-gpg_desc=Tyto veลejnรฉ klรญฤe GPG jsou propojeny s vaลกรญm รบฤtem a pouลพรญvajรญ se k ovฤลenรญ vaลกich commitลฏ. Uloลพte je na bezpeฤnรฉ mรญsto, jelikoลพ umoลพลujรญ podepsat commity vaลกรญ identitou.
-ssh_helper=Potลebujete pomoct? Podรญvejte se do pลรญruฤky GitHubu na to vytvoลenรญ vlastnรญch klรญฤลฏ SSH nebo vyลeลกte bฤลพnรฉ problรฉmy , se kterรฝmi se mลฏลพete potkat pลi pouลพitรญ SSH.
-gpg_helper=Potลebujete pomoct? Podรญvejte se do pลรญruฤky GitHubu o GPG .
+gpg_desc=Tyto veลejnรฉ klรญฤe GPG jsou propojeny s vaลกรญm รบฤtem a pouลพรญvajรญ se k ovฤลenรญ vaลกich revizรญ. Uloลพte je na bezpeฤnรฉ mรญsto, jelikoลพ umoลพลujรญ podepsat revize vaลกรญ identitou.
+ssh_helper=Potลebujete pomoct? Podรญvejte se do pลรญruฤky, jak vytvoลit vlastnรญ klรญฤe SSH nebo vyลeลกte bฤลพnรฉ problรฉmy , se kterรฝmi se mลฏลพete potkat pลi pouลพitรญ SSH.
+gpg_helper=Potลebujete pomoct? Podรญvejte se do pลรญruฤky o GPG .
add_new_key=Pลidat klรญฤ SSH
add_new_gpg_key=Pลidat klรญฤ GPG
key_content_ssh_placeholder=Zaฤรญnรก s โssh-ed25519โ, โssh-rsaโ, โecdsa-sha2-nistp256โ, โecdsa-sha2-nistp384โ, โecdsa-sha2-nistp521โ, โsk-ecdsa-sha2-nistp256@openssh.comโ nebo โsk-ssh-ed25519@openssh.comโ
key_content_gpg_placeholder=Zaฤรญnรก s โ-----BEGIN PGP PUBLIC KEY BLOCK-----โ
add_new_principal=Pลidat principal
-ssh_key_been_used=Tento SSH klรญฤ byl na server jiลพ pลidรกn.
-ssh_key_name_used=SSH klรญฤ se stejnรฝm jmรฉnem jiลพ u vaลกeho รบฤtu existuje.
+ssh_key_been_used=Tento klรญฤ SSH byl na server jiลพ pลidรกn.
+ssh_key_name_used=U vaลกeho รบฤtu jiลพ existuje klรญฤ SSH se stejnรฝm nรกzvem.
ssh_principal_been_used=Tento SSH Principal certifikรกt jiลพ byl pลidรกn na server.
-gpg_key_id_used=Veลejnรฝ GPG klรญฤ se stejnรฝm ID jiลพ existuje.
-gpg_no_key_email_found=Tento GPG klรญฤ neodpovรญdรก ลพรกdnรฉ aktivovanรฉ e-mailovรฉ adrese spojenรฉ s vaลกรญm รบฤtem. Mลฏลพe bรฝt stรกle pลidรกn, pokud podepรญลกete zadanรฝ token.
+gpg_key_id_used=Veลejnรฝ klรญฤ GPG se stejnรฝm ID jiลพ existuje.
+gpg_no_key_email_found=Tento klรญฤ GPG neodpovรญdรก ลพรกdnรฉ aktivovanรฉ e-mailovรฉ adrese spojenรฉ s vaลกรญm รบฤtem. Mลฏลพe bรฝt stรกle pลidรกn, pokud podepรญลกete zadanรฝ token.
gpg_key_matched_identities=Odpovรญdajรญcรญ identity:
-gpg_key_matched_identities_long=Vloลพenรฉ identity v tomto klรญฤi odpovรญdajรญ nรกsledujรญcรญm aktivovanรฝm e-mailovรฝm adresรกm tohoto uลพivatele. Commity odpovรญdajรญcรญ tฤmto e-mailovรฝm adresรกm lze ovฤลit pomocรญ tohoto klรญฤe.
+gpg_key_matched_identities_long=Vloลพenรฉ identity v tomto klรญฤi odpovรญdajรญ nรกsledujรญcรญm aktivovanรฝm e-mailovรฝm adresรกm tohoto uลพivatele. Revize odpovรญdajรญcรญ tฤmto e-mailovรฝm adresรกm lze ovฤลit pomocรญ tohoto klรญฤe.
gpg_key_verified=Ovฤลenรฝ klรญฤ
-gpg_key_verified_long=Klรญฤ byl ovฤลen pomocรญ tokenu a mลฏลพe bรฝt pouลพit k ovฤลenรญ commitลฏ shodujรญcรญch se s libovolnou aktivovanou e-mailovou adresou pro tohoto uลพivatele navรญc k jakรฉkoli odpovรญdajรญcรญ identitฤ tohoto klรญฤe.
+gpg_key_verified_long=Klรญฤ byl ovฤลen pomocรญ tokenu a mลฏลพe bรฝt pouลพit k ovฤลenรญ revizรญ shodujรญcรญch se s libovolnou aktivovanou e-mailovou adresou pro tohoto uลพivatele navรญc k jakรฉkoli odpovรญdajรญcรญ identitฤ tohoto klรญฤe.
gpg_key_verify=Ovฤลit
-gpg_invalid_token_signature=Zadanรฝ GPG klรญฤ, podpis a token se neshodujรญ nebo je token zastaralรฝ.
+gpg_invalid_token_signature=Zadanรฝ klรญฤ GPG, podpis a token se neshodujรญ nebo je token zastaralรฝ.
gpg_token_required=Musรญte zadat podpis pro nรญลพe uvedenรฝ token
gpg_token=Token
gpg_token_help=Podpis mลฏลพete vygenerovat pomocรญ:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=Zakรณdovanรฝ podpis GPG
key_signature_gpg_placeholder=Zaฤรญnรก textem โ-----BEGIN PGP SIGNATURE-----โ
-verify_gpg_key_success=GPG klรญฤ โ%sโ byl ovฤลen.
+verify_gpg_key_success=Klรญฤ GPG โ%sโ byl ovฤลen.
ssh_key_verified=Ovฤลenรฝ klรญฤ
-ssh_key_verified_long=Klรญฤ byl ovฤลen pomocรญ tokenu a mลฏลพe bรฝt pouลพit k ovฤลenรญ commitลฏ shodujรญcรญch se s libovolnou vaลกรญ aktivovanou e-mailovou adresou pro tohoto uลพivatele.
+ssh_key_verified_long=Klรญฤ byl ovฤลen pomocรญ tokenu a mลฏลพe bรฝt pouลพit k ovฤลenรญ revizรญ shodujรญcรญch se s libovolnou vaลกรญ aktivovanou e-mailovou adresou pro tohoto uลพivatele.
ssh_key_verify=Ovฤลit
-ssh_invalid_token_signature=Zadanรฝ SSH klรญฤ, podpis nebo token se neshodujรญ nebo je token zastaralรฝ.
+ssh_invalid_token_signature=Zadanรฝ klรญฤ SSH, podpis nebo token se neshodujรญ nebo je token zastaralรฝ.
ssh_token_required=Musรญte zadat podpis pro nรญลพe uvedenรฝ token
ssh_token=Token
ssh_token_help=Podpis mลฏลพete vygenerovat pomocรญ:
ssh_token_signature=Zakรณdovanรฝ podpis SSH
key_signature_ssh_placeholder=Zaฤรญnรก s โ-----BEGIN SSH SIGNATURE-----โ
-verify_ssh_key_success=SSH klรญฤ โ%sโ byl ovฤลen.
+verify_ssh_key_success=Klรญฤ SSH โ%sโ byl ovฤลen.
subkeys=Podklรญฤe
key_id=ID klรญฤe
key_name=Nรกzev klรญฤe
key_content=Obsah
principal_content=Obsah
add_key_success=SSH klรญฤ โ%sโ byl pลidรกn.
-add_gpg_key_success=GPG klรญฤ โ%sโ byl pลidรกn.
+add_gpg_key_success=Klรญฤ GPG โ%sโ byl pลidรกn.
add_principal_success=Byl pลidรกn SSH Principal certifikรกt โ%sโ.
delete_key=Odstranit
-ssh_key_deletion=Odebrat klรญฤ SSH
-gpg_key_deletion=Odebrat klรญฤ GPG
+ssh_key_deletion=Odstranit klรญฤ SSH
+gpg_key_deletion=Odstranit klรญฤ GPG
ssh_principal_deletion=Odstranit SSH Principal certifikรกt
-ssh_key_deletion_desc=Odstranฤnรญ SSH klรญฤe zruลกรญ jeho pลรญstup k vaลกemu รบฤtu. Pokraฤovat?
-gpg_key_deletion_desc=Odstranฤnรญm klรญฤe GPG zneplatnรญte ovฤลenรญ commitลฏ, kterรฉ jsou jรญm podepsรกny. Pokraฤovat?
+ssh_key_deletion_desc=Odstranฤnรญ klรญฤe SSH zruลกรญ jeho pลรญstup k vaลกemu รบฤtu. Pokraฤovat?
+gpg_key_deletion_desc=Odstranฤnรญm klรญฤe GPG zneplatnรญte ovฤลenรญ revizรญ, kterรฉ jsou jรญm podepsรกny. Pokraฤovat?
ssh_principal_deletion_desc=Odstranฤnรญ SSH Principal certifikรกtu zruลกรญ jeho pลรญstup k vaลกemu รบฤtu. Pokraฤovat?
-ssh_key_deletion_success=SSH klรญฤ byl odstranฤn.
-gpg_key_deletion_success=GPG klรญฤ byl odstranฤn.
+ssh_key_deletion_success=Klรญฤ SSH byl odstranฤn.
+gpg_key_deletion_success=Klรญฤ GPG byl odstranฤn.
ssh_principal_deletion_success=SSH Principal certifikรกt byl odstranฤn.
added_on=Pลidรกno %s
valid_until_date=Platnรฉ do %s
valid_forever=Platnรฉ navลพdy
-last_used=Naposledy pouลพito dne
+last_used=Naposledy pouลพito
no_activity=ลฝรกdnรก aktuรกlnรญ aktivita
can_read_info=ฤtenรญ
can_write_info=Zรกpis
@@ -878,8 +920,8 @@ principal_state_desc=Tento SSH Principal certifikรกt byl pouลพit bฤhem posledn
show_openid=Zobrazit na profilu
hide_openid=Odstranit z profilu
ssh_disabled=SSH je zakรกzรกno
-ssh_signonly=SSH je v souฤasnรฉ dobฤ zakรกzรกno, proto jsou tyto klรญฤe pouลพity pouze pro ovฤลenรญ podpisu.
-ssh_externally_managed=Tento SSH klรญฤ je spravovรกn externฤ pro tohoto uลพivatele
+ssh_signonly=SSH je aktuรกlnฤ zakรกzรกno, proto jsou tyto klรญฤe pouลพity pouze pro ovฤลenรญ podpisu revizรญ.
+ssh_externally_managed=Tento klรญฤ SSH je pro tohoto uลพivatele spravovรกn externฤ
manage_social=Sprรกva propojenรฝch รบฤtลฏ sociรกlnรญch sรญtรญ
social_desc=Tyto รบฤty sociรกlnรญch sรญtรญ lze pouลพรญt k pลihlรกลกenรญ k vaลกemu รบฤtu. Ujistฤte se, ลพe jsou vลกechny vaลกe.
unbind=Odpojit
@@ -890,25 +932,25 @@ generate_new_token=Vygenerovat novรฝ token
tokens_desc=Tyto tokeny umoลพลujรญ pลรญstup k vaลกemu รบฤtu pomocรญ Forgejo API.
token_name=Nรกzev tokenu
generate_token=Vygenerovat token
-generate_token_success=Vรกลก novรฝ token byl vytvoลen. Zkopรญrujte jej nynรญ protoลพe se jiลพ znovu nezobrazรญ.
+generate_token_success=Novรฝ token byl vygenerovรกn. Zkopรญrujte jej nynรญ, jelikoลพ jiลพ nebude znovu zobrazen.
generate_token_name_duplicate=%s byl jiลพ pouลพit jako nรกzev aplikace. Pouลพijte prosรญm novรฝ.
delete_token=Smazat
access_token_deletion=Odstranit pลรญstupovรฝ token
access_token_deletion_cancel_action=Zruลกit
access_token_deletion_confirm_action=Smazat
access_token_deletion_desc=Smazรกnรญ tokenu zruลกรญ pลรญstup k vaลกemu รบฤtu pro aplikace, kterรฉ jej pouลพรญvajรญ. Tuto akci nelze vrรกtit. Pokraฤovat?
-delete_token_success=Token byl odstranฤn. Aplikace, kterรฉ jej pouลพรญvajรญ jiลพ nemajรญ pลรญstup k vaลกemu รบฤtu.
-repo_and_org_access=Repozitรกล a pลรญstup organizace
-permissions_public_only=Pouze veลejnost
+delete_token_success=Token byl odstranฤn. Aplikace, kterรฉ jej pouลพรญvajรญ, jiลพ nemajรญ pลรญstup k vaลกemu รบฤtu.
+repo_and_org_access=Pลรญstup k repozitรกลลฏm a organizacรญm
+permissions_public_only=Pouze veลejnรฉ
permissions_access_all=Vลกe (veลejnรฉ, soukromรฉ a omezenรฉ)
select_permissions=Vyberte oprรกvnฤnรญ
-permission_no_access=Bez pลรญstupu
-permission_read=Pลeฤtenรฉ
+permission_no_access=ลฝรกdnรฝ pลรญstup
+permission_read=ฤtenรญ
permission_write=ฤtenรญ a zรกpis
at_least_one_permission=Musรญte vybrat alespoล jedno oprรกvnฤnรญ pro vytvoลenรญ tokenu
permissions_list=Oprรกvnฤnรญ:
-manage_oauth2_applications=Spravovat aplikace OAuth2
+manage_oauth2_applications=Sprรกva aplikacรญ OAuth2
edit_oauth2_application=Upravit OAuth2 aplikaci
oauth2_applications_desc=OAuth2 aplikace umoลพnรญ aplikacรญm tลetรญch stran bezpeฤnฤ ovฤลit uลพivatele v tรฉto instanci Forgejo.
remove_oauth2_application=Odstranit OAuth2 aplikaci
@@ -919,8 +961,8 @@ create_oauth2_application_button=Vytvoลit aplikaci
create_oauth2_application_success=รspฤลกnฤ jste vytvoลili novou OAuth2 aplikaci.
update_oauth2_application_success=รspฤลกnฤ jste aktualizovali OAuth2 aplikaci.
oauth2_application_name=Nรกzev aplikace
-oauth2_confidential_client=Dลฏvฤrnรฝ klient. Zvolte jej pro aplikace, kterรฉ uklรกdajรญ soubor secret, napลรญklad webovรฉ aplikace. Nevybรญrejte jej pro nativnรญ aplikace vฤetnฤ aplikacรญ pro poฤรญtaฤe a mobilnรญ zaลรญzenรญ.
-oauth2_redirect_uris=Pลesmฤrovรกnรญ URI. Pouลพijte novรฝ ลรกdek pro kaลพdou URI.
+oauth2_confidential_client=Dลฏvฤrnรฝ klient. Vyberte pro aplikace, kterรฉ udrลพujรญ tajnรฝ klรญฤ v bezpeฤรญ, napลรญklad webovรฉ aplikace. Nevybรญrejte pro nativnรญ aplikace vฤetnฤ aplikacรญ pro poฤรญtaฤe a mobilnรญ zaลรญzenรญ.
+oauth2_redirect_uris=Pลesmฤrovรกnรญ URI. Zadejte kaลพdou URI na vlastnรญ ลรกdek.
save_application=Uloลพit
oauth2_client_id=ID klienta
oauth2_client_secret=Tajnรฝ klรญฤ klienta
@@ -928,12 +970,12 @@ oauth2_regenerate_secret=Obnovit tajnรฝ klรญฤ
oauth2_regenerate_secret_hint=Ztratili jste svลฏj tajnรฝ klรญฤ?
oauth2_client_secret_hint=Tajnรฝ klรญฤ se znovu nezobrazรญ po opuลกtฤnรญ nebo obnovenรญ tรฉto strรกnky. Ujistฤte se, ลพe jste si jej uloลพili.
oauth2_application_edit=Upravit
-oauth2_application_create_description=OAuth2 aplikace poskytuje pลรญstup aplikacรญm tลetรญch stran k uลพivatelskรฝm รบฤtลฏm na tรฉto instanci.
+oauth2_application_create_description=Aplikace OAuth2 poskytujรญ pลรญstup vaลกim aplikacรญm tลetรญch stran k uลพivatelskรฝm รบฤtลฏm na tรฉto instanci.
oauth2_application_remove_description=Odebrรกnรญm OAuth2 aplikace zabrรกnรญ pลรญstupu ovฤลenรฝm uลพivatelลฏm na tรฉto instanci. Pokraฤovat?
-oauth2_application_locked=Gitea pลedregistruje nฤkterรฉ OAuth2 aplikace pลi spuลกtฤnรญ, pokud je to povoleno v konfiguraci. Aby se zabrรกnilo neoฤekรกvanรฉmu chovรกnรญ, nelze je upravovat ani odstranit. Vรญce informacรญ naleznete v dokumentaci OAuth2.
+oauth2_application_locked=Forgejo pลedem zaregistruje nฤkterรฉ OAuth2 aplikace pลi spuลกtฤnรญ, pokud je to povoleno v konfiguraci. Aby se zabrรกnilo neoฤekรกvanรฉmu chovรกnรญ, nelze je upravovat ani odstranit. Vรญce informacรญ naleznete v dokumentaci OAuth2.
-authorized_oauth2_applications=Autorizovat aplikaci OAuth2
-authorized_oauth2_applications_description=รspฤลกnฤ jste povolili pลรญstup k vaลกemu osobnรญmu รบฤtu tรฉto aplikaci tลetรญ strany. Zruลกte prosรญm pลรญstup aplikacรญm, kterรฉ jiลพ nejsou pouลพรญvรกny.
+authorized_oauth2_applications=Autorizovanรฉ aplikace OAuth2
+authorized_oauth2_applications_description=Tฤmto aplikacรญm tลetรญch stran jste udฤlili pลรญstup ke svรฉmu osobnรญmu รบฤtu Forgejo. Zruลกte prosรญm pลรญstup aplikacรญm, kterรฉ jiลพ nejsou pouลพรญvรกny.
revoke_key=Zruลกit
revoke_oauth2_grant=Zruลกit pลรญstup
revoke_oauth2_grant_description=Zruลกenรญm pลรญstupu tรฉto aplikaci tลetรญ strany ji zabrรกnรญte v pลรญstupu k vaลกim datลฏm. Jste si jisti?
@@ -941,45 +983,45 @@ revoke_oauth2_grant_success=Pลรญstup byl รบspฤลกnฤ zruลกen.
twofa_desc=Dvoufaktorovรฝ zpลฏsob ovฤลovรกnรญ zvรฝลกรญ zabezpeฤenรญ vaลกeho รบฤtu.
twofa_recovery_tip=Pokud ztratรญte svรฉ zaลรญzenรญ, budete moci pouลพรญt jednorรกzovรฝ obnovovacรญ klรญฤ k zรญskรกnรญ pลรญstupu k vaลกemu รบฤtu.
-twofa_is_enrolled=Vรกลก รบฤet aktuรกlnฤ pouลพรญvรก dvoufaktorovรฉ ovฤลovรกnรญ.
-twofa_not_enrolled=Vรกลก รบฤet aktuรกlnฤ nepouลพรญvรก dvoufaktorovรฉ ovฤลovรกnรญ.
-twofa_disable=Zakรกzat dvoufaktorovรฉ ovฤลovรกnรญ
+twofa_is_enrolled=Vรกลก รบฤet aktuรกlnฤ pouลพรญvรก dvoufรกzovรฉ ovฤลenรญ.
+twofa_not_enrolled=Vรกลก รบฤet aktuรกlnฤ nepouลพรญvรก dvoufรกzovรฉ ovฤลenรญ.
+twofa_disable=Zakรกzat dvoufรกzovรฉ ovฤลenรญ
twofa_scratch_token_regenerate=Znovu vygenerovat jednorรกzovรฝ klรญฤ pro obnovenรญ
twofa_scratch_token_regenerated=Vรกลก jednorรกzovรฝ klรญฤ pro obnovenรญ je nynรญ %s. Uloลพte jej na bezpeฤnรฉ mรญsto, protoลพe se znovu nezobrazรญ.
-twofa_enroll=Povolit dvoufaktorovรฉ ovฤลovรกnรญ
-twofa_disable_note=Dvoufaktorovรฉ ovฤลovรกnรญ mลฏลพete zakรกzat, kdyลพ bude potลeba.
-twofa_disable_desc=Zakรกลพete-li dvoufaktorovรฉ ovฤลovรกnรญ, bude vรกลก รบฤet mรฉnฤ zabezpeฤenรฝ. Pokraฤovat?
+twofa_enroll=Povolit dvoufรกzovรฉ ovฤลenรญ
+twofa_disable_note=Dvoufรกzovรฉ ovฤลenรญ mลฏลพete v pลรญpadฤ potลeby zakรกzat.
+twofa_disable_desc=Zakรกzรกnรญm dvoufรกzovรฉho ovฤลenรญ bude vรกลก รบฤet mรฉnฤ bezpeฤnรฝ. Pokraฤovat?
regenerate_scratch_token_desc=Pokud jste ztratili svลฏj klรญฤ pro obnovenรญ nebo jste jej jiลพ pouลพili k pลihlรกลกenรญ, mลฏลพete jej resetovat zde.
-twofa_disabled=Dvoufaktorovรฉ ovฤลovรกnรญ bylo zakรกzรกno.
+twofa_disabled=Dvoufรกzovรฉ ovฤลenรญ bylo zakรกzรกno.
scan_this_image=Naskenujte tento obrรกzek s vaลกรญ ovฤลovacรญ aplikacรญ:
or_enter_secret=Nebo zadejte tajnรฝ kรณd: %s
then_enter_passcode=A zadejte pลรญstupovรฝ kรณd zobrazenรฝ ve vaลกรญ aplikaci:
passcode_invalid=Pลรญstupovรฝ kรณd nenรญ platnรฝ. Zkuste to znovu.
-twofa_enrolled=Ve vaลกem รบฤtu bylo povoleno dvoufaktorovรฉ ovฤลovรกnรญ. Uloลพte si jednorรกzovรฝ obnovovacรญ klรญฤ (%s) na bezpeฤnรฉ mรญsto, jelikoลพ jiลพ nebude znovu zobrazen.
+twofa_enrolled=Ve vaลกem รบฤtu bylo povoleno dvoufรกzovรฉ ovฤลenรญ. Uloลพte si jednorรกzovรฝ obnovovacรญ klรญฤ (%s) na bezpeฤnรฉ mรญsto, jelikoลพ jiลพ nebude znovu zobrazen.
twofa_failed_get_secret=Nepodaลilo se zรญskat tajemstvรญ.
-webauthn_desc=Bezpeฤnostnรญ klรญฤe jsou hardwarovรก zaลรญzenรญ obsahujรญcรญ kryptografickรฉ klรญฤe. Mohou bรฝt pouลพity pro dvoufaktorovรฉ ovฤลovรกnรญ. Bezpeฤnostnรญ klรญฤe musรญ podporovat WebAuthn Authenticator standard.
+webauthn_desc=Bezpeฤnostnรญ klรญฤe jsou hardwarovรก zaลรญzenรญ obsahujรญcรญ kryptografickรฉ klรญฤe. Mohou bรฝt pouลพity pro dvoufรกzovรฉ ovฤลenรญ. Bezpeฤnostnรญ klรญฤe musรญ podporovat standard WebAuthn Authenticator .
webauthn_register_key=Pลidat bezpeฤnostnรญ klรญฤ
webauthn_nickname=Pลezdรญvka
-webauthn_delete_key=Odebrat bezpeฤnostnรญ klรญฤ
+webauthn_delete_key=Odstranit bezpeฤnostnรญ klรญฤ
webauthn_delete_key_desc=Pokud odstranรญte bezpeฤnostnรญ klรญฤ, jiลพ se s nรญm nebudete moci pลihlรกsit. Pokraฤovat?
webauthn_key_loss_warning=Pokud ztratรญte svรฉ bezpeฤnostnรญ klรญฤe, ztratรญte pลรญstup k vaลกemu รบฤtu.
webauthn_alternative_tip=Moลพnรก budete chtรญt nakonfigurovat dalลกรญ metodu ovฤลovรกnรญ.
manage_account_links=Propojenรฉ รบฤty
-manage_account_links_desc=Tyto externรญ รบฤty jsou propojeny s vaลกรญm Forgejo รบฤtem.
+manage_account_links_desc=Tyto externรญ รบฤty jsou propojeny s vaลกรญm รบฤtem Forgejo.
account_links_not_available=K vaลกemu Forgejo รบฤtu nejsou aktuรกlnฤ pลipojenรฉ ลพรกdnรฉ externรญ รบฤty.
link_account=Propojit รบฤet
remove_account_link=Odstranit propojenรฝ รบฤet
remove_account_link_desc=Odstranฤnรญm propojenรฉho รบฤtu zruลกรญte jeho pลรญstup k vaลกemu Forgejo รบฤtu. Pokraฤovat?
remove_account_link_success=Propojenรฝ รบฤet byl odstranฤn.
-hooks.desc=Pลidat webhooky, kterรฉ budou spouลกtฤny pro vลกechny repozitรกลe vve vaลกem vlastnictvรญ.
+hooks.desc=Pลidejte webhooky, kterรฉ budou spouลกtฤny pro vลกechny repozitรกลe ve vaลกem vlastnictvรญ.
orgs_none=Nejste ฤlenem ลพรกdnรฉ organizace.
repos_none=Nevlastnรญte ลพรกdnรฉ repozitรกลe.
-delete_account=Odstranit svลฏj รบฤet
+delete_account=Odstranit รบฤet
delete_prompt=Tato operace natrvalo odstranรญ vรกลก uลพivatelskรฝ รบฤet. NELZE ji vrรกtit zpฤt.
delete_with_all_comments=Vรกลก รบฤet je mladลกรญ neลพ %s. Pro zabrรกnฤnรญ fantomovรฝm komentรกลลฏm budou spoleฤnฤ s nรญm odstranฤny vลกechny komentรกลe u problรฉmลฏ a ลฝS.
confirm_delete_account=Potvrdit odstranฤnรญ
@@ -996,39 +1038,72 @@ visibility=Viditelnost uลพivatele
visibility.public=Veลejnรฝ
visibility.public_tooltip=Viditelnรฉ pro vลกechny
visibility.limited=Omezenรฝ
-visibility.limited_tooltip=Viditelnรฉ pouze pro ovฤลenรฉ uลพivatele
+visibility.limited_tooltip=Viditelnรฉ pouze pro pลihlรกลกenรฉ uลพivatele
visibility.private=Soukromรฝ
visibility.private_tooltip=Viditelnรฉ pouze pro ฤleny organizacรญ, ke kterรฝm jste se pลipojili
blocked_users = Zablokovanรญ uลพivatelรฉ
change_password = Zmฤnit heslo
user_block_success = Uลพivatel byl รบspฤลกnฤ zablokovรกn.
user_unblock_success = Uลพivatel byl รบspฤลกnฤ odblokovรกn.
-access_token_desc = Oprรกvnฤnรญ vybranรฉho tokenu omezujรญ autorizaci pouze na pลรญsluลกnรฉ cesty API . Pro vรญce informacรญ si pลeฤtฤte dokumentaci .
+access_token_desc = Oprรกvnฤnรญ vybranรฉho tokenu omezujรญ autorizaci pouze na pลรญsluลกnรฉ cesty API . Pro vรญce informacรญ si pลeฤtฤte dokumentaci .
blocked_users_none = Nemรกte ลพรกdnรฉ zablokovanรฉ uลพivatele.
blocked_since = Zablokovรกn od %s
hints = Nรกpovฤdy
-additional_repo_units_hint = Navrhnout povolenรญ dalลกรญch jednotek รบloลพiลกtฤ
+additional_repo_units_hint = Navrhnout povolenรญ dalลกรญch jednotek repozitรกลe
update_hints = Aktualizovat nรกpovฤdy
update_hints_success = Nรกpovฤdy byly aktualizovรกny.
-additional_repo_units_hint_description = Zobrazit tlaฤรญtko โPลidat dalลกรญ jednotky...โ u repozitรกลลฏ, kterรฉ nemajรญ povolenรฉ vลกechny dostupnรฉ jednotky.
+additional_repo_units_hint_description = Zobrazit tip โPovolit dalลกรญโ u repozitรกลลฏ, kterรฉ nemajรญ povolenรฉ vลกechny dostupnรฉ jednotky.
pronouns = Zรกjmena
pronouns_custom = Vlastnรญ
pronouns_unspecified = Neurฤenรก
language.title = Vรฝchozรญ jazyk
+keep_activity_private.description = Vaลกe veลejnรก aktivita bude viditelnรก pouze vรกm a sprรกvcลฏm instance.
+language.description = Tento jazyk bude uloลพen do vaลกeho รบฤtu a po pลihlรกลกenรญ bude pouลพit jako vรฝchozรญ.
+language.localization_project = Pomozte nรกm s pลekladem Forgejo do vaลกeho jazyka! Vรญce informacรญ .
+user_block_yourself = Nemลฏลพete zablokovat sami sebe.
+pronouns_custom_label = Vlastnรญ zรกjmena
+change_username_redirect_prompt.with_cooldown.few = Starรฉ uลพivatelskรฉ jmรฉno bude dostupnรฉ ostatnรญm po %[1]d dnech. Do tรฉ doby budete moci svรฉ starรฉ uลพivatelskรฉ jmรฉno znovu zรญskat.
+change_username_redirect_prompt.with_cooldown.one = Starรฉ uลพivatelskรฉ jmรฉno bude dostupnรฉ ostatnรญm po %[1]d dni. Do tรฉ doby budete moci svรฉ starรฉ uลพivatelskรฉ jmรฉno znovu zรญskat.
+keep_pronouns_private = Zobrazovat zรกjmena pouze pลihlรกลกenรฝm uลพivatelลฏm
+keep_pronouns_private.description = Toto nastavenรญ skryje vaลกe zรกjmena pลed nรกvลกtฤvnรญky, kteลรญ nejsou pลihlรกลกeni.
+quota = Kvรณta
+quota.applies_to_org = Nรกsledujรญcรญ pravidla kvรณty se vztahujรญ na tuto organizaci
+quota.rule.exceeded = Pลekroฤeno
+quota.rule.no_limit = Neomezenรก
+quota.sizes.all = Vลกe
+quota.sizes.repos.all = Repozitรกลe
+quota.sizes.repos.public = Veลejnรฉ repozitรกลe
+quota.sizes.repos.private = Soukromรฉ repozitรกลe
+quota.sizes.git.all = Obsah gitu
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.all = Prostลedky
+quota.sizes.assets.attachments.all = Pลรญlohy
+quota.sizes.assets.attachments.issues = Pลรญlohy problรฉmลฏ
+quota.sizes.assets.artifacts = Artefakty
+quota.sizes.assets.packages.all = Balรญฤky
+quota.sizes.wiki = Wiki
+storage_overview = Pลehled รบloลพiลกtฤ
+quota.applies_to_user = Nรกsledujรญcรญ pravidla kvรณty se vztahujรญ na vรกลก รบฤet
+quota.rule.exceeded.helper = Celkovรก velikost objektลฏ pro toto pravidlo pลesรกhla kvรณtu.
+quota.sizes.assets.attachments.releases = Pลรญlohy vydรกnรญ
+regenerate_token_success = Token byl znovu vygenerovรกn. Aplikace, kterรฉ jej pouลพรญvajรญ, jiลพ nemajรญ pลรญstup k vaลกemu รบฤtu a je tลeba je aktualizovat s novรฝm tokenem.
+regenerate_token = Resetovat
+access_token_regeneration = Znovu vygenerovat pลรญstupovรฝ token
+access_token_regeneration_desc = Opฤtovnรฝm vygenerovรกnรญm tokenu znemoลพnรญte pลรญstup k vaลกemu รบฤtu aplikacรญm, kterรฉ jej pouลพรญvajรญ. Tato akce je nevratnรก. Chcete pokraฤovat?
[repo]
-new_repo_helper=Repozitรกล obsahuje vลกechny projektovรฉ soubory, vฤetnฤ historie revizรญ. Uลพ jej hostujete jinde? Migrovat repozitรกล.
+new_repo_helper=Repozitรกล obsahuje vลกechny soubory projektu, vฤetnฤ historie revizรญ. Uลพ jej hostujete jinde? Migrovat repozitรกล .
owner=Vlastnรญk
-owner_helper=Nฤkterรฉ organizace se nemusejรญ v seznamu zobrazit kvลฏli maximรกlnรญmu dosaลพenรฉmu poฤtu repozitรกลลฏ.
+owner_helper=Nฤkterรฉ organizace se nemusรญ v seznamu zobrazit kvลฏli maximรกlnรญmu dosaลพenรฉmu poฤtu repozitรกลลฏ.
repo_name=Nรกzev repozitรกลe
repo_name_helper=Dobrรฝ nรกzev repozitรกลe vฤtลกinou pouลพรญvรก krรกtkรก, zapamatovatelnรก a unikรกtnรญ klรญฤovรก slova.
repo_size=Velikost repozitรกลe
template=ล ablona
-template_select=Vyberte ลกablonu.
-template_helper=Z repozitรกลe vytvoลit ลกablonu
+template_select=Vyberte ลกablonu
+template_helper=Nastavit repozitรกล jako ลกablonu
template_description=ล ablony repozitรกลลฏ umoลพลujรญ uลพivatelลฏm generovat novรฉ repositรกลe se stejnou strukturou, soubory a volitelnรฝmi nastavenรญmi.
visibility=Viditelnost
-visibility_description=Pouze majitelรฉ nebo ฤlenovรฉ organizace to budou moci vidฤt, pokud majรญ prรกva.
+visibility_description=Budou jej moci vidฤt pouze majitelรฉ nebo ฤlenovรฉ organizace, pokud majรญ prรกva.
visibility_helper=Nastavit repozitรกล jako soukromรฝ
visibility_helper_forced=Vรกลก administrรกtor vynutil, ลพe novรฉ repozitรกลe budou soukromรฉ.
visibility_fork_helper=(Zmฤna tรฉto moลพnosti ovlivnรญ viditelnost vลกech forkลฏ repozitรกลe.)
@@ -1036,7 +1111,7 @@ clone_helper=Potลebujete pomoci s klonovรกnรญm? Navลกtivte Zvolte licenci
-object_format=Formรกt objektu
-object_format_helper=Objektovรฝ formรกt repozitรกลe. Nelze pozdฤji zmฤnit. SHA1 je nejvรญce kompatibilnรญ.
+license_helper=Vyberte soubor licence
+license_helper_desc=Licence ลรญdรญ, co ostatnรญ mohou a nemohou dฤlat s vaลกรญm kรณdem. Nejste si jisti, kterรก je pro vรกลก projekt sprรกvnรก? Podรญvejte se na strรกnku Vรฝbฤr licence .
+object_format = Objektovรฝ formรกt
+object_format_helper = Objektovรฝ formรกt repozitรกลe. Pozdฤji jej nelze zmฤnit. Nejkompatibilnฤjลกรญ je SHA1.
readme=README
-readme_helper=Vyberte ลกablonu souboru README.
-readme_helper_desc=Toto je mรญsto, kde mลฏลพete napsat รบplnรฝ popis vaลกeho projektu.
-auto_init=Inicializovat repozitรกล (pลidรก soubory .gitignore, License a README)
+readme_helper=Vyberte ลกablonu souboru README
+readme_helper_desc=Do tohoto mรญsta mลฏลพete zadat celรฝ popis vaลกeho projektu.
+auto_init=Inicializovat repozitรกล
trust_model_helper=Vyberte model dลฏvฤry pro ovฤลenรญ podpisu. Moลพnosti jsou:
trust_model_helper_collaborator=Spolupracovnรญk: Dลฏvฤลovat podpisลฏm spolupracovnรญkลฏ
trust_model_helper_committer=Pลispฤvatel: Dลฏvฤลovat podpisลฏm, kterรฉ se shodujรญ s pลispฤvateli
@@ -1072,12 +1147,12 @@ trust_model_helper_default=Vรฝchozรญ: Pouลพรญt vรฝchozรญ model dลฏvฤry pro tuto
create_repo=Vytvoลit repozitรกล
default_branch=Vรฝchozรญ vฤtev
default_branch_label=vรฝchozรญ
-default_branch_helper=Vรฝchozรญ vฤtev je zรกkladnรญ vฤtev pro ลพรกdosti o slouฤenรญ a commity kรณdu.
+default_branch_helper=Vรฝchozรญ vฤtev je zรกkladnรญ vฤtev pro ลพรกdosti o slouฤenรญ a revize kรณdu.
mirror_prune=Vyฤistit
mirror_prune_desc=Odstranit zastaralรฉ reference na vzdรกlenรฉ sledovรกnรญ
mirror_interval=Interval zrcadlenรญ (platnรฉ ฤasovรฉ jednotky jsou โhโ, โmโ a โsโ). Nastavenรญm na 0 zakรกลพete periodickou synchronizaci. (Minimรกlnรญ interval: %s)
mirror_interval_invalid=Interval zrcadlenรญ nenรญ platnรฝ.
-mirror_sync_on_commit=Synchronizovat pลi nahrรกvรกnรญ commitลฏ
+mirror_sync_on_commit=Synchronizovat pลi nahrรกvรกnรญ revizรญ
mirror_address=Klonovat z URL
mirror_address_desc=Zadejte poลพadovanรฉ pลรญstupovรฉ รบdaje do sekce Ovฤลenรญ.
mirror_address_url_invalid=Poskytnutรก URL je neplatnรก. Vลกechny ฤรกsti musรญte sprรกvnฤ nahradit escape sekvencรญ.
@@ -1097,7 +1172,7 @@ forks=Forky
reactions_more=a %d dalลกรญch
unit_disabled=Sprรกvce webu zakรกzal tuto sekci repozitรกลe.
language_other=Jinรฝ
-adopt_search=Zadejte uลพivatelskรฉ jmรฉno pro hledรกnรญ nepลijatรฝch repozitรกลลฏ... (ponechte prรกzdnรฉ pro nalezenรญ vลกech)
+adopt_search=Zadejte uลพivatelskรฉ jmรฉno pro hledรกnรญ nepลijatรฝch repozitรกลลฏโฆ (ponechte prรกzdnรฉ pro vyhledรกnรญ vลกech)
adopt_preexisting_label=Pลijmout soubory
adopt_preexisting=Pลijmout jiลพ existujรญcรญ soubory
adopt_preexisting_content=Vytvoลit repozitรกล z %s
@@ -1110,7 +1185,7 @@ blame_prior=Zobrazit blame pลed touto zmฤnou
blame.ignore_revs.failed=Nepodaลilo se ignorovat revize v .git-blame-ignore-revs .
author_search_tooltip=Zobrazรญ maximรกlnฤ 30 uลพivatelลฏ
-tree_path_not_found_commit=Cesta %[1]s v commitu %[2]s neexistuje
+tree_path_not_found_commit=Cesta %[1]s v revizi %[2]s neexistuje
tree_path_not_found_branch=Cesta %[1]s ve vฤtvi %[2]s neexistuje
tree_path_not_found_tag=Cesta %[1]s ve znaฤce %[2]s neexistuje
@@ -1126,21 +1201,20 @@ desc.public=Veลejnรฝ
desc.template=ล ablona
desc.internal=Internรญ
desc.archived=Archivovรกno
-desc.sha256=SHA256
-
+desc.sha256 = SHA256
template.items=Poloลพky ลกablony
template.git_content=Obsah Gitu (vรฝchozรญ vฤtev)
template.git_hooks=Git hooks
template.git_hooks_tooltip=Momentรกlnฤ nemลฏลพete po pลidรกnรญ upravovat nebo odebรญrat Git hooky. Vyberte pouze v pลรญpadฤ, ลพe dลฏvฤลujete ลกablonฤ repozitรกลe.
-template.webhooks=Webovรฉ hรกฤky
+template.webhooks=Webhooky
template.topics=Tรฉmata
template.avatar=Avatar
template.issue_labels=ล tรญtky problรฉmลฏ
template.one_item=Musรญte vybrat alespoล jednu poloลพku ลกablony
template.invalid=Musรญte vybrat repositรกล ลกablony
-archive.title=Tento repozitรกล je archivovanรฝ. Mลฏลพete prohlรญลพet soubory, klonovat, ale nemลฏลพete nahrรกvat a vytvรกลet novรฉ problรฉmy nebo ลพรกdosti o slouฤenรญ.
-archive.title_date=Tento repozitรกล byl archivovรกn %s. Mลฏลพete si prohlรญลพet a klonovat soubory, ale nemลฏลพete nahrรกvat ani otevรญrat problรฉmy nebo ลพรกdosti o slouฤenรญ.
+archive.title=Tento repozitรกล je archivovanรฝ. Mลฏลพete prohlรญลพet soubory, klonovat, ale nemลฏลพete provรกdฤt ลพรกdnรฉ zmฤny jeho stavu, jako nahrรกvรกnรญ a vytvรกลenรญ novรฝch problรฉmลฏ, ลพรกdostรญ nebo komentรกลลฏ.
+archive.title_date=Tento repozitรกล byl archivovรกn %s. Mลฏลพete prohlรญลพet soubory, klonovat, ale nemลฏลพete provรกdฤt ลพรกdnรฉ zmฤny jeho stavu, jako nahrรกvรกnรญ a vytvรกลenรญ novรฝch problรฉmลฏ, ลพรกdostรญ nebo komentรกลลฏ.
archive.issue.nocomment=Tento repozitรกล je archivovanรฝ. Nemลฏลพete komentovat problรฉmy.
archive.pull.nocomment=Tento repozitรกล je archivovanรฝ. Nemลฏลพete komentovat ลพรกdosti o slouฤenรญ.
@@ -1153,7 +1227,7 @@ need_auth=Ovฤลenรญ
migrate_options=Moลพnosti migrace
migrate_service=Migraฤnรญ sluลพba
migrate_options_mirror_helper=Tento repozitรกล bude zrcadlem
-migrate_options_lfs=Migrovat LFS soubory
+migrate_options_lfs=Migrovat soubory LFS
migrate_options_lfs_endpoint.label=Endpoint LFS
migrate_options_lfs_endpoint.description=Migrace se pokusรญ pouลพรญt vรกลก vzdรกlenรฝ Git pro urฤenรญ LFS serveru . Mลฏลพete takรฉ zadat vlastnรญ koncovรฝ bod, pokud jsou data LFS repozitรกลe uloลพena nฤkde jinde.
migrate_options_lfs_endpoint.description.local=Podporovรกna je takรฉ cesta k lokรกlnรญmu serveru.
@@ -1180,7 +1254,7 @@ migrate.migrate_items_options=Pro migraci dalลกรญch poloลพek je vyลพadovรกn pล
migrated_from=Migrovรกno z %[2]s
migrated_from_fake=Migrovรกno z %[1]s
migrate.migrate=Migrovat z %s
-migrate.migrating=Probรญhรก migrace z %s ...
+migrate.migrating=Probรญhรก migrace z %s โฆ
migrate.migrating_failed=Migrace z %s se nezdaลila.
migrate.migrating_failed.error=Nepodaลilo se migrovat: %s
migrate.migrating_failed_no_addr=Migrace se nezdaลila.
@@ -1203,17 +1277,17 @@ migrate.cancel_migrating_title=Zruลกit migraci
migrate.cancel_migrating_confirm=Chcete zruลกit tuto migraci?
mirror_from=zrcadlo
-forked_from=rozลกtฤpen z
+forked_from=forknuto z
generated_from=generovรกno z
-fork_from_self=Nemลฏลพete rozลกtฤpit vรกลก vlastnรญ repozitรกล.
+fork_from_self=Nemลฏลพete vytvoลit fork vaลกeho vlastnรญho repozitรกลe.
fork_guest_user=Pลihlaste se pro vytvoลenรญ forku tohoto repozitรกลe.
watch_guest_user=Pro sledovรกnรญ tohoto repozitรกลe se pลihlaste.
star_guest_user=Pro hodnocenรญ tohoto repozitรกลe se pลihlaste.
unwatch=Pลestat sledovat
watch=Sledovat
-unstar=Odebrat z oblรญbenรฝch
+unstar=Oblรญbenรฉ
star=Oblรญbit
-fork=Rozลกtฤpit
+fork=Fork
download_archive=Stรกhnout repozitรกล
more_operations=Dalลกรญ operace
@@ -1227,7 +1301,7 @@ empty_message=Tento repozitรกล nemรก ลพรกdnรฝ obsah.
broken_message=Data gitu, kterรก jsou zรกkladem tohoto repozitรกลe, nelze ฤรญst. Kontaktujte sprรกvce tรฉto instance nebo smaลพte tento repositรกล.
code=Zdrojovรฝ kรณd
-code.desc=Pลรญstup ke zdrojovรฝm kรณdลฏm, souborลฏm, commitลฏm a vฤtvรญm.
+code.desc=Pลรญstup ke zdrojovรฝm kรณdลฏm, souborลฏm, revizรญm a vฤtvรญm.
branch=Vฤtev
tree=Strom
clear_ref=Vymazat aktuรกlnรญ referenci
@@ -1245,15 +1319,15 @@ org_labels_desc=ล tรญtky na รบrovni organizace, kterรฉ mohou bรฝt pouลพity se โ
+editor.commit_signed_changes=Odeslat podepsanรฉ zmฤny
+editor.commit_changes=Odeslat zmฤny
+editor.add_tmpl=Pลidรกn โ<%s>โ
editor.add=Pลidat %s
editor.update=Aktualizovat %s
editor.delete=Odstranit %s
@@ -1323,12 +1399,12 @@ editor.patching=Zรกplatovรกnรญ:
editor.fail_to_apply_patch=Nelze pouลพรญt zรกplatu โ%sโ
editor.new_patch=Novรก zรกplata
editor.commit_message_desc=Pลidat volitelnรฝ rozลกรญลenรฝ popisโฆ
-editor.signoff_desc=Pลidat Signed-off-by podpis pลispฤvatele na konec zprรกvy o commitu.
-editor.commit_directly_to_this_branch=Odevzdat pลรญmo do vฤtve %s .
-editor.create_new_branch=Vytvoลit novou vฤtev pro tento commit a vytvoลit ลพรกdost o slouฤenรญ.
-editor.create_new_branch_np=Vytvoลte novou vฤtev z tohoto commitu.
+editor.signoff_desc=Pลidat podpis pลispฤvatele โSigned-off-byโ na konec zprรกvy revize.
+editor.commit_directly_to_this_branch=Odeslat pลรญmo do vฤtve %[1]s .
+editor.create_new_branch=Vytvoลit novou vฤtev pro tuto revizi a vytvoลit ลพรกdost o slouฤenรญ.
+editor.create_new_branch_np=Vytvoลit novou vฤtev z tรฉto revize.
editor.propose_file_change=Navrhnout zmฤnu souboru
-editor.new_branch_name=Pojmenujte novou vฤtev pro tento commit
+editor.new_branch_name=Pojmenujte novou vฤtev pro tuto revizi
editor.new_branch_name_desc=Nรกzev novรฉ vฤtveโฆ
editor.cancel=Zruลกit
editor.filename_cannot_be_empty=Jmรฉno nemลฏลพe bรฝt prรกzdnรฉ.
@@ -1340,10 +1416,10 @@ editor.file_is_a_symlink=`โ%sโ je symbolickรฝ odkaz. Symbolickรฉ odkazy nemo
editor.filename_is_a_directory=Jmรฉno souboru โ%sโ je jiลพ pouลพito jako jmรฉno adresรกลe v tomto repozitรกลi.
editor.file_editing_no_longer_exists=Upravovanรฝ soubor โ%sโ jiลพ nenรญ souฤรกstรญ tohoto repozitรกลe.
editor.file_deleting_no_longer_exists=Odstraลovanรฝ soubor โ%sโ jiลพ nenรญ souฤรกstรญ tohoto repozitรกลe.
-editor.file_changed_while_editing=Obsah souboru se od zahรกjenรญ รบprav zmฤnil. Kliknฤte sem pro jejich zobrazenรญ nebo proveฤte commit zmฤn jeลกtฤ jednou pro jejich pลepsรกnรญ.
+editor.file_changed_while_editing=Obsah souboru se od doby, kdy jste ho otevลeli, zmฤnil. Kliknฤte sem pro jeho zobrazenรญ nebo odeลกlete zmฤny jeลกtฤ jednou pro jeho pลepsรกnรญ.
editor.file_already_exists=Soubor โ%sโ jiลพ existuje v tomto repozitรกลi.
-editor.commit_empty_file_header=Odevzdat prรกzdnรฝ soubor
-editor.commit_empty_file_text=Soubor, kterรฝ se chystรกte odevzdat, je prรกzdnรฝ. Pokraฤovat?
+editor.commit_empty_file_header=Odeslat prรกzdnรฝ soubor
+editor.commit_empty_file_text=Soubor, kterรฝ se chystรกte odeslat, je prรกzdnรฝ. Pokraฤovat?
editor.no_changes_to_show=ลฝรกdnรฉ zmฤny k zobrazenรญ.
editor.fail_to_update_file=Nepodaลilo se aktualizovat/vytvoลit soubor โ%sโ.
editor.fail_to_update_file_summary=Chybovรก zprรกva:
@@ -1353,17 +1429,17 @@ editor.push_rejected_summary=รplnรก zprรกva o zamรญtnutรญ:
editor.add_subdir=Pลidat adresรกลโฆ
editor.unable_to_upload_files=Nepodaลilo se nahrรกt soubory do โ%sโ. Chyba: %v
editor.upload_file_is_locked=Soubor โ%sโ je uzamฤen uลพivatelem %s.
-editor.upload_files_to_dir=Nahrรกt soubory do โ%sโ
-editor.cannot_commit_to_protected_branch=Nelze vytvoลit commit v chrรกnฤnรฉ vฤtvi โ%sโ.
-editor.no_commit_to_branch=Nelze odevzdat pลรญmo do vฤtve, protoลพe:
+editor.upload_files_to_dir=Nahrรกny soubory do โ%sโ
+editor.cannot_commit_to_protected_branch=Nelze vytvoลit revizi v chrรกnฤnรฉ vฤtvi โ%sโ.
+editor.no_commit_to_branch=Nepodaลilo se odeslat pลรญmo do vฤtve:
editor.user_no_push_to_branch=Uลพivatel nemลฏลพe nahrรกvat do vฤtve
-editor.require_signed_commit=Vฤtev vyลพaduje podepsanรฝ commit
+editor.require_signed_commit=Vฤtev vyลพaduje podepsanou revizi
editor.cherry_pick=Cherry-pick %s na:
editor.revert=Vrรกtit %s na:
commits.desc=Prochรกzet historii zmฤn zdrojovรฉho kรณdu.
-commits.commits=Commity
-commits.no_commits=ลฝรกdnรฉ spoleฤnรฉ commity. โ%sโ a โ%sโ majรญ zcela odliลกnou historii.
+commits.commits=Revize
+commits.no_commits=ลฝรกdnรฉ spoleฤnรฉ revize. โ%sโ a โ%sโ majรญ zcela odliลกnou historii.
commits.nothing_to_compare=Tyto vฤtve jsou stejnรฉ.
commits.search=Hledรกnรญ commitลฏโฆ
commits.search.tooltip=Mลฏลพete pลedลadit klรญฤovรก slova s โauthor:โ, โcommitter:โ, โafter:โ nebo โbefore:โ, napล. โrevert author:Alice before:2019-01-03โ.
@@ -1376,25 +1452,25 @@ commits.older=Starลกรญ
commits.newer=Novฤjลกรญ
commits.signed_by=Podepsรกno
commits.signed_by_untrusted_user=Podepsรกno nedลฏvฤryhodnรฝm uลพivatelem
-commits.signed_by_untrusted_user_unmatched=Podepsรกno nedลฏvฤryhodnรฝm uลพivatelem, kterรฝ nesouhlasรญ s pลispฤvatelem
+commits.signed_by_untrusted_user_unmatched=Podepsรกno nedลฏvฤryhodnรฝm uลพivatelem, kterรฝ neodpovรญdรก pลispฤvateli
commits.gpg_key_id=ID klรญฤe GPG
commits.ssh_key_fingerprint=Otisk klรญฤe SSH
-commits.view_path=Zobrazit v tomto bodฤ v historii
+commits.view_path=Zobrazit tento bod v historii
commit.operations=Operace
commit.revert=Vrรกtit
commit.revert-header=Vrรกtit: %s
-commit.revert-content=Vyberte vฤtev pro nรกvrat na:
+commit.revert-content=Vyberte vฤtev pro nรกvrat:
commit.cherry-pick=Cherry-pick
commit.cherry-pick-header=Cherry-pick: %s
-commit.cherry-pick-content=Vyberte vฤtev pro Cherry-pick na:
+commit.cherry-pick-content=Vyberte vฤtev pro Cherry-pick:
commitstatus.error=Chyba
-commitstatus.failure=Chyba
+commitstatus.failure=Selhรกnรญ
commitstatus.pending=ฤekajรญcรญ
commitstatus.success=รspฤch
-ext_issues=Pลรญstup k externรญm problรฉmลฏm
+ext_issues=Externรญ problรฉmy
ext_issues.desc=Odkaz na externรญ systรฉm problรฉmลฏ.
projects=Projekty
@@ -1495,7 +1571,7 @@ issues.remove_milestone_at=`odstranil/a toto z milnรญku %s %s`
issues.remove_project_at=`odstranil/a toto z projektu %s %s`
issues.deleted_milestone=`(odstranฤno)`
issues.deleted_project=`(odstranฤno)`
-issues.self_assign_at=`pลiลadil/a sobฤ toto %s`
+issues.self_assign_at=`pลiลadil/a sobฤ tento problรฉm %s`
issues.add_assignee_at=`byl pลiลazen %s %s`
issues.remove_assignee_at=`byl odstranฤn z pลiลazenรญ %s %s`
issues.remove_self_assignment=`odstranil/a jejich pลiลazenรญ %s`
@@ -1573,19 +1649,19 @@ issues.context.edit=Upravit
issues.context.delete=Smazat
issues.no_content=K dispozici nenรญ ลพรกdnรฝ popis.
issues.close=Zavลรญt problรฉm
-issues.comment_pull_merged_at=slouฤenรฝ commit %[1]s do %[2]s %[3]s
-issues.comment_manually_pull_merged_at=ruฤnฤ slouฤenรฝ commit %[1]s do %[2]s %[3]s
-issues.close_comment_issue=Okomentovat a zavลรญt
+issues.comment_pull_merged_at=slouฤena revize %[1]s do %[2]s %[3]s
+issues.comment_manually_pull_merged_at=ruฤnฤ slouฤena revize %[1]s do %[2]s %[3]s
+issues.close_comment_issue=Zavลรญt s komentรกลem
issues.reopen_issue=Znovu otevลรญt
-issues.reopen_comment_issue=Okomentovat a znovu otevลรญt
-issues.create_comment=Okomentovat
+issues.reopen_comment_issue=Znovu otevลรญt s komentรกลem
+issues.create_comment=Komentovat
issues.closed_at=`uzavลel/a tento problรฉm %[2]s `
issues.reopened_at=`znovu otevลel/a tento problรฉm %[2]s `
-issues.commit_ref_at=`odkรกzal/a na tento problรฉm z commitu %[2]s `
+issues.commit_ref_at=`odkรกzal/a na tento problรฉm z revize %[2]s `
issues.ref_issue_from=`odkรกzal/a na tento problรฉm %[4]s %[2]s `
issues.ref_pull_from=`odkรกzal/a na tuto ลพรกdost o slouฤenรญ %[4]s %[2]s `
-issues.ref_closing_from=`odkazoval/a na ลพรกdost o slouฤenรญ %[4]s, kterรก uzavลe tento problรฉm %[2]s `
-issues.ref_reopening_from=`odkazoval/a na ลพรกdost o slouฤenรญ %[4]s, kterรก znovu otevลe tento problรฉm %[2]s `
+issues.ref_closing_from=`odkazoval/a na tento problรฉm ze ลพรกdosti o slouฤenรญ %[4]s, kterรก jej uzavลe , %[2]s `
+issues.ref_reopening_from=`odkazoval/a na tento problรฉm ze ลพรกdosti o slouฤenรญ %[4]s, kterรก jej znovu otevลe , %[2]s `
issues.ref_closed_from=`uzavลel/a tento problรฉm %[4]s %[2]s `
issues.ref_reopened_from=`znovu otevลel/a tento problรฉm %[4]s %[2]s `
issues.ref_from=`z %[1]s`
@@ -1614,11 +1690,11 @@ issues.label_title=Nรกzev ลกtรญtku
issues.label_description=Popis ลกtรญtku
issues.label_color=Barva ลกtรญtku
issues.label_exclusive=Exkluzivnรญ
-issues.label_archive=Archivovat ลกtรญtek
+issues.label_archive = ล tรญtek archivu
issues.label_archived_filter=Zobrazit archivovanรฉ popisky
-issues.label_archive_tooltip=Archivovanรฉ ลกtรญtky jsou ve vรฝchozรญm nastavenรญ vylouฤeny z nรกvrhลฏ pลi hledรกnรญ podle popisku.
-issues.label_exclusive_desc=Pojmenujte ลกtรญtek rozsah/poloลพka
, aby se stal vzรกjemnฤ exkluzivnรญm s jinรฝmi ลกtรญtky rozsah/
.
-issues.label_exclusive_warning=Jakรฉkoliv protichลฏdnรฉ rozsahy ลกtรญtkลฏ budou odstranฤny pลi รบpravฤ ลกtรญtkลฏ u รบkolลฏ nebo u poลพadavku na nataลพenรญ.
+issues.label_archive_tooltip = ล tรญtek Archivovรกno jsou ve vรฝchozรญm nastavenรญ vylouฤeny z nรกvrhลฏ pลi vyhledรกvรกnรญ podle ลกtรญtkลฏ.
+issues.label_exclusive_desc = Pojmenujte ลกtรญtek scope/item
, aby se vzรกjemnฤ vyluฤoval s ostatnรญmi ลกtรญtky scope/
.
+issues.label_exclusive_warning = Pลi รบpravฤ ลกtรญtkลฏ problรฉmu nebo ลพรกdosti o slouฤenรญ budou odstranฤny vลกechny konfliktnรญ ลกtรญtky.
issues.label_count=%d ลกtรญtkลฏ
issues.label_open_issues=%d otevลenรฝch problรฉmลฏ / ลพรกdostรญ o slouฤenรญ
issues.label_edit=Upravit
@@ -1687,9 +1763,9 @@ issues.due_date=Termรญn dokonฤenรญ
issues.invalid_due_date_format=Termรญn dokonฤenรญ musรญ bรฝt ve formรกtu โrrrr-mm-ddโ.
issues.error_modifying_due_date=Zmฤna termรญnu dokonฤenรญ selhala.
issues.error_removing_due_date=Odstranฤnรญ termรญnu dokonฤenรญ selhalo.
-issues.push_commit_1=pลidal/a %d commit %s
-issues.push_commits_n=pลidal/a %d commity %s
-issues.force_push_codes=`vynucenรฉ nahrรกnรญ %[1]s od %[2]s
do %[4]s
%[6]s`
+issues.push_commit_1=pลidal/a %d revizi %s
+issues.push_commits_n=pลidal/a %d revize %s
+issues.force_push_codes=`vynucenรฉ nahrรกnรญ %[1]s od %[2]s
do %[4]s
%[6]s`
issues.force_push_compare=Porovnat
issues.due_date_form=rrrr-mm-dd
issues.due_date_form_add=Pลidat termรญn dokonฤenรญ
@@ -1719,7 +1795,7 @@ issues.dependency.issue_closing_blockedby=Uzavลenรญ tohoto problรฉmu je blokov
issues.dependency.issue_close_blocks=Tento problรฉm blokuje uzavลenรญ nรกsledujรญcรญch problรฉmลฏ
issues.dependency.pr_close_blocks=Tato ลพรกdost o slouฤenรญ blokuje uzavลenรญ nรกsledujรญcรญch problรฉmลฏ
issues.dependency.issue_close_blocked=Aby bylo moลพnรฉ uzavลรญt tento problรฉm, musรญte uzavลรญt vลกechny ostatnรญ problรฉmy, kterรฉ jej blokujรญ.
-issues.dependency.issue_batch_close_blocked=Nelze uzavลรญt รบkoly, kterรฉ jste vybrali, protoลพe รบkol #%d mรก stรกle otevลenรฉ zรกvislosti
+issues.dependency.issue_batch_close_blocked = Nepodaลilo se hromadnฤ zavลรญt vybranรฉ problรฉmy, protoลพe problรฉm #%d mรก stรกle otevลenรฉ zรกvislosti
issues.dependency.pr_close_blocked=Aby bylo moลพnรฉ slouฤit tuto ลพรกdost, musรญte uzavลรญt vลกechny problรฉmy, kterรฉ ji blokujรญ.
issues.dependency.blocks_short=Blokuje
issues.dependency.blocked_by_short=Zรกvisรญ na
@@ -1743,8 +1819,8 @@ issues.review.left_comment=zanechal komentรกล
issues.review.content.empty=Je potลeba zanechat poznรกmku s uvedenรญm poลพadovanรฉ zmฤny (poลพadovanรฝch zmฤn).
issues.review.reject=poลพรกdal/a o zmฤny %s
issues.review.wait=byl/a poลพรกdรกn/a o posouzenรญ %s
-issues.review.add_review_request=poลพรกdal/a o posouzenรญ od %s %s
-issues.review.remove_review_request=odstranil/a ลพรกdost o posouzenรญ na %s %s
+issues.review.add_review_request=poลพรกdal/a o kontrolu od %[1]s %[2]s
+issues.review.remove_review_request=odstranil/a ลพรกdost o kontrolu u %[1]s %[2]s
issues.review.remove_review_request_self=odmรญtl/a posoudit %s
issues.review.pending=ฤekajรญcรญ
issues.review.pending.tooltip=Tento komentรกล nenรญ momentรกlnฤ viditelnรฝ pro ostatnรญ uลพivatele. Chcete-li odeslat Vaลกe ฤekajรญcรญ komentรกลe, vyberte โ%sโ โ โ%s/%s/%sโ v hornรญ ฤรกsti strรกnky.
@@ -1788,28 +1864,28 @@ pulls.viewed_files_label=%[1]d / %[2]d souborลฏ zobrazeno
pulls.expand_files=Rozbalit vลกechny soubory
pulls.collapse_files=Sbalit vลกechny soubory
pulls.compare_base=slouฤit do
-pulls.compare_compare=natรกhnout z
+pulls.compare_compare=slouฤit z
pulls.switch_comparison_type=Pลepnout typ porovnรกnรญ
pulls.switch_head_and_base=Prohodit hlavnรญ a zรกkladnรญ vฤtev
pulls.filter_branch=Filtrovat vฤtev
pulls.no_results=Nebyly nalezeny ลพรกdnรฉ vรฝsledky.
-pulls.show_all_commits=Zobrazit vลกechny commity
+pulls.show_all_commits=Zobrazit vลกechny revize
pulls.show_changes_since_your_last_review=Zobrazit zmฤny od vaลกeho poslednรญho posouzenรญ
-pulls.showing_only_single_commit=Zobrazuji pouze zmฤny commitu %[1]s
+pulls.showing_only_single_commit=Zobrazuji pouze zmฤny revize %[1]s
pulls.showing_specified_commit_range=Zobrazujรญ se pouze zmฤny mezi %[1]s..%[2]s
-pulls.select_commit_hold_shift_for_range=Vyberte commit. Podrลพte klรกvesu shift + klepnฤte pro vรฝbฤr rozsahu
+pulls.select_commit_hold_shift_for_range=Vyberte revizi. Podrลพte klรกvesu Shift a kliknฤte pro vรฝbฤr rozsahu
pulls.review_only_possible_for_full_diff=Posouzenรญ je moลพnรฉ pouze pลi zobrazenรญ plnรฉho rozliลกenรญ
-pulls.filter_changes_by_commit=Filtrovat podle commitu
+pulls.filter_changes_by_commit=Filtrovat podle revize
pulls.nothing_to_compare=Tyto vฤtve jsou stejnรฉ. Nenรญ tลeba vytvรกลet ลพรกdost o slouฤenรญ.
-pulls.nothing_to_compare_have_tag=Vybranรก vฤtev/znaฤka je stejnรก.
+pulls.nothing_to_compare_have_tag = Vybranรก vฤtev a znaฤka jsou shodnรฉ.
pulls.nothing_to_compare_and_allow_empty_pr=Tyto vฤtve jsou stejnรฉ. Tato ลพรกdost o slouฤenรญ bude prรกzdnรก.
pulls.has_pull_request=`ลฝรกdost o slouฤenรญ mezi tฤmito vฤtvemi jiลพ existuje: %[2]s#%[3]d `
pulls.create=Vytvoลit ลพรกdost o slouฤenรญ
-pulls.title_desc_few=chce slouฤit %[1]d commity z vฤtve %[2]s
do %[3]s
+pulls.title_desc_few=chce slouฤit %[1]d commity z vฤtve %[2]s
do %[3]s
pulls.merged_title_desc_few=slouฤil %[1]d commity z vฤtve %[2]s
do vฤtve %[3]s
pลed %[4]s
pulls.change_target_branch_at=`zmฤnil/a cรญlovou vฤtev z %s na %s %s`
pulls.tab_conversation=Konverzace
-pulls.tab_commits=Commity
+pulls.tab_commits=Revize
pulls.tab_files=Zmฤnฤnรฉ soubory
pulls.reopen_to_merge=Otevลete znovu tuto ลพรกdost pro provedenรญ slouฤenรญ.
pulls.cant_reopen_deleted_branch=Tuto ลพรกdost o slouฤenรญ nelze znovu otevลรญt, protoลพe vฤtev byla smazรกna.
@@ -1828,7 +1904,7 @@ pulls.data_broken=Tato ลพรกdost o slouฤenรญ je rozbitรก kvลฏli chybฤjรญcรญm in
pulls.files_conflicted=Tato ลพรกdost o slouฤenรญ obsahuje zmฤny, kterรฉ jsou v rozporu s cรญlovou vฤtvรญ.
pulls.is_checking=Prรกvฤ probรญhรก kontrola konfliktลฏ pลi slouฤenรญ. Zkuste to za chvรญli.
pulls.is_ancestor=Tato vฤtev je jiลพ souฤรกstรญ cรญlovรฉ vฤtve. Nenรญ co slouฤit.
-pulls.is_empty=Zmฤny na tรฉto vฤtvi jsou jiลพ na cรญlovรฉ vฤtvi. Toto bude prรกzdnรฝ commit.
+pulls.is_empty=Zmฤny na tรฉto vฤtvi se jiลพ nachรกzejรญ na cรญlovรฉ vฤtvi. Tato revize bude prรกzdnรก.
pulls.required_status_check_failed=Nฤkterรฉ poลพadovanรฉ kontroly nebyly รบspฤลกnรฉ.
pulls.required_status_check_missing=Nฤkterรฉ poลพadovanรฉ kontroly chybรญ.
pulls.required_status_check_administrator=Jako administrรกtor stรกle mลฏลพete slouฤit tuto ลพรกdost.
@@ -1849,25 +1925,25 @@ pulls.reject_count_1=%d ลพรกdost o zmฤnu
pulls.reject_count_n=%d ลพรกdostรญ o zmฤnu
pulls.waiting_count_1=%d ฤekajรญcรญ posouzenรญ
pulls.waiting_count_n=%d ฤekajรญcรญch posouzenรญ
-pulls.wrong_commit_id=id commitu musรญ bรฝt id commitu v cรญlovรฉ vฤtvi
+pulls.wrong_commit_id=id revize musรญ bรฝt id revize v cรญlovรฉ vฤtvi
pulls.no_merge_desc=Tato ลพรกdost nemลฏลพe bรฝt slouฤena, protoลพe vลกechny moลพnosti repozitรกลe na slouฤenรญ jsou zakรกzรกny.
pulls.no_merge_helper=Povolte moลพnosti slouฤenรญ v nastavenรญ repozitรกลe nebo proveฤte slouฤenรญ ลพรกdosti ruฤnฤ.
pulls.no_merge_wip=Tato ลพรกdost nemลฏลพe bรฝt slouฤena, protoลพe je oznaฤena jako rozpracovanรก.
pulls.no_merge_not_ready=Tento ลพรกdost nenรญ pลipravena na slouฤenรญ, zkontrolujte stav posouzenรญ a kontroly stavu.
pulls.no_merge_access=Nemรกte oprรกvnฤnรญ slouฤit tuto ลพรกdost.
-pulls.merge_pull_request=Vytvoลit sluฤovacรญ commit
-pulls.rebase_merge_pull_request=Rebase pak fast-forward
-pulls.rebase_merge_commit_pull_request=Rebase a potรฉ vytvoลit sluฤovacรญ commit
-pulls.squash_merge_pull_request=Vytvoลit squash commit
+pulls.merge_pull_request=Vytvoลit sluฤovacรญ revizi
+pulls.rebase_merge_pull_request=Provรฉst rebase a potรฉ provรฉst fast-forward
+pulls.rebase_merge_commit_pull_request=Provรฉst rebase a potรฉ vytvoลit sluฤovacรญ revizi
+pulls.squash_merge_pull_request=Vytvoลit squash revizi
pulls.merge_manually=Slouฤeno ruฤnฤ
-pulls.merge_commit_id=ID sluฤovacรญho commitu
-pulls.require_signed_wont_sign=Vฤtev vyลพaduje podepsanรฉ commity, ale toto slouฤenรญ nebude podepsรกno
+pulls.merge_commit_id=ID sluฤovacรญ revize
+pulls.require_signed_wont_sign=Vฤtev vyลพaduje podepsanรฉ revize, ale toto slouฤenรญ nebude podepsรกno
pulls.invalid_merge_option=Pro tuto ลพรกdost nemลฏลพete pouลพรญt tuto moลพnost slouฤenรญ.
pulls.merge_conflict=Slouฤenรญ selhalo: pลi sluฤovรกnรญ doลกlo ke konfliktu. Tip: zkuste jinou strategii
pulls.merge_conflict_summary=Chybovรฉ hlรกลกenรญ
-pulls.rebase_conflict=Slouฤenรญ selhalo: doลกlo ke konfliktu pลi rebase commitu: %[1]s. Tip: zkuste jinou strategii
+pulls.rebase_conflict=Slouฤenรญ selhalo: doลกlo ke konfliktu pลi provรกdฤnรญ rebase revize %[1]s. Tip: zkuste jinou strategii
pulls.rebase_conflict_summary=Chybovรฉ hlรกลกenรญ
pulls.unrelated_histories=Slouฤenรญ selhalo: hlava a zรกklad revize nesdรญlรญ spoleฤnou historii. Tip: zkuste jinou strategii
pulls.merge_out_of_date=Slouฤenรญ selhalo: zรกklad byl aktualizovรกn pลi generovรกnรญ slouฤenรญ. Tip: zkuste to znovu.
@@ -1876,7 +1952,7 @@ pulls.has_merged=Chyba: ลพรกdost byla slouฤena, nelze ji znovu slouฤit nebo zm
pulls.push_rejected=Push selhal: nahrรกnรญ bylo zamรญtnuto. Zkontrolujte Git hooky pro tento repozitรกล.
pulls.push_rejected_summary=รplnรก zprรกva o zamรญtnutรญ
pulls.push_rejected_no_message=Push selhal: nahrรกnรญ bylo odmรญtnuto, ale nebyla nalezena ลพรกdnรก vzdรกlenรก zprรกva. Zkontrolujte Git hooky pro tento repozitรกล
-pulls.open_unmerged_pull_exists=`Nemลฏลพete provรฉst operaci znovuotevลenรญ protoลพe je tu ฤekajรญcรญ poลพadavek na nataลพenรญ (#%d) s identickรฝmi vlastnostmi.`
+pulls.open_unmerged_pull_exists=`Nemลฏลพete provรฉst operaci opฤtovnรฉho otevลenรญ, protoลพe mรกte ฤekajรญcรญ ลพรกdost o slouฤenรญ (#%d) s identickรฝmi vlastnostmi.`
pulls.status_checking=Nฤkterรฉ kontroly jsou nedoลeลกeny
pulls.status_checks_success=Vลกechny kontroly byly รบspฤลกnรฉ
pulls.status_checks_warning=Nฤkterรฉ kontroly nahlรกsily varovรกnรญ
@@ -1892,39 +1968,39 @@ pulls.update_branch_success=Aktualizace vฤtve byla รบspฤลกnรก
pulls.update_not_allowed=Nemรกte oprรกvnฤnรญ aktualizovat vฤtev
pulls.outdated_with_base_branch=Tato vฤtev je zastaralรก oproti zรกkladnรญ vฤtvi
pulls.close=Zavลรญt ลพรกdost o slouฤenรญ
-pulls.closed_at=`uzavลel/a tento poลพadavek na nataลพenรญ %[2]s `
-pulls.reopened_at=`znovuotevลel/a tento poลพadavek na nataลพenรญ %[2]s `
-pulls.cmd_instruction_hint=`Zobrazit instrukce pลรญkazovรฉ ลรกdky .`
+pulls.closed_at=`uzavลel/a tuto ลพรกdost o slouฤenรญ %[2]s `
+pulls.reopened_at=`znovu otevลel/a tuto ลพรกdost o slouฤenรญ %[2]s `
+pulls.cmd_instruction_hint=Zobrazit instrukce pลรญkazovรฉ ลรกdky
pulls.cmd_instruction_checkout_desc=Z vaลกeho repositรกลe projektu se podรญvejte na novou vฤtev a vyzkouลกejte zmฤny.
pulls.cmd_instruction_merge_title=Slouฤit
-pulls.cmd_instruction_merge_desc=Sluฤte zmฤny a aktualizujte je na Gitea.
+pulls.cmd_instruction_merge_desc=Sluฤte zmฤny a aktualizujte je na Forgeju.
pulls.clear_merge_message=Vymazat zprรกvu o slouฤenรญ
pulls.auto_merge_button_when_succeed=(Kdyลพ kontroly uspฤjรญ)
pulls.auto_merge_when_succeed=Automaticky slouฤit, kdyลพ vลกechny kontroly uspฤjรญ
-pulls.auto_merge_newly_scheduled=Poลพadavek na nataลพenรญ byl naplรกnovรกn na slouฤenรญ, jakmile vลกechny kontroly uspฤjรญ.
-pulls.auto_merge_has_pending_schedule=%[1]s naplรกnoval/a tento poลพadavek na nataลพenรญ pro automatickรฉ slouฤenรญ, kdyลพ vลกechny kontroly uspฤjรญ v %[2]s.
+pulls.auto_merge_newly_scheduled=ลฝรกdost o slouฤenรญ bude slouฤena, jakmile budou vลกechny kontroly รบspฤลกnรฉ.
+pulls.auto_merge_has_pending_schedule=%[1]s naplรกnoval/a tuto ลพรกdost o slouฤenรญ na automatickรฉ slouฤenรญ, jakmile budou vลกechny kontroly รบspฤลกnรฉ %[2]s.
pulls.auto_merge_cancel_schedule=Zruลกit automatickรฉ slouฤenรญ
-pulls.auto_merge_not_scheduled=Tento poลพadavek na nataลพenรญ nenรญ naplรกnovรกn na automatickรฉ slouฤenรญ.
-pulls.auto_merge_canceled_schedule=Automatickรฉ slouฤenรญ bylo zruลกeno pro tento poลพadavek na nataลพenรญ.
+pulls.auto_merge_not_scheduled=Tato ลพรกdost o slouฤenรญ nebude automaticky slouฤena.
+pulls.auto_merge_canceled_schedule=Automatickรฉ slouฤenรญ bylo u tรฉto ลพรกdosti o slouฤenรญ zruลกeno.
-pulls.auto_merge_newly_scheduled_comment=`poลพadavek na automatickรฉ slouฤenรญ tohoto poลพadavku na nataลพenรญ je naplรกnovรกn, kdyลพ vลกechny kontroly uspฤjรญ %[1]s`
-pulls.auto_merge_canceled_schedule_comment=`zruลกil/a automatickรฉ slouฤenรญ tohoto poลพadavku na nataลพenรญ, kdyลพ vลกechny kontroly uspฤjรญ %[1]s`
+pulls.auto_merge_newly_scheduled_comment=`naplรกnoval/a tuto ลพรกdost o slouฤenรญ na automatickรฉ slouฤenรญ, jakmile budou vลกechny kontroly รบspฤลกnรฉ %[1]s`
+pulls.auto_merge_canceled_schedule_comment=`zruลกil/a automatickรฉ slouฤenรญ tรฉto ลพรกdosti o slouฤenรญ, jakmile budou vลกechny kontroly รบspฤลกnรฉ %[1]s`
-pulls.delete.title=Odstranit tento poลพadavek na nataลพenรญ?
-pulls.delete.text=Opravdu chcete tento poลพadavek na nataลพenรญ smazat? (Tรญm se trvale odstranรญ veลกkerรฝ obsah. Pokud jej hodlรกte archivovat, zvaลพte radฤji jeho uzavลenรญ.)
+pulls.delete.title=Odstranit tuto ลพรกdost o slouฤenรญ?
+pulls.delete.text=Opravdu chcete odstranit tuto ลพรกdost o slouฤenรญ? (Tรญmto trvale odstranรญte vลกechen obsah. Pokud jej chcete archivovat, zvaลพte radฤji jeho uzavลenรญ)
pull.deleted_branch=(odstranฤno):%s
milestones.new=Novรฝ milnรญk
-milestones.closed=Zavลen dne %s
+milestones.closed=Uzavลeno %s
milestones.update_ago=Aktualizovรกno %s
milestones.no_due_date=Bez lhลฏty dokonฤenรญ
milestones.open=Otevลรญt
milestones.close=Zavลรญt
-milestones.new_subheader=Milnรญky vรกm pomohou organizovat รบkoly a sledovat jejich pokrok.
+milestones.new_subheader = Milnรญky vรกm pomohou zorganizovat problรฉmy a sledovat jejich pokrok.
milestones.completeness=Dokonฤeno %d%%
milestones.create=Vytvoลit milnรญk
milestones.title=Nรกzev
@@ -1948,25 +2024,25 @@ milestones.filter_sort.most_complete=Nejvรญce dokonฤenรฉ
milestones.filter_sort.most_issues=Nejvรญce problรฉmลฏ
milestones.filter_sort.least_issues=Nejmรฉnฤ problรฉmลฏ
-signing.will_sign=Tento commit bude podepsรกna klรญฤem โ%sโ.
-signing.wont_sign.error=Doลกlo k chybฤ pลi kontrole, zda mลฏลพe bรฝt commit podepsรกn.
-signing.wont_sign.nokey=Tato instance nemรก ลพรกdnรฝ klรญฤ k podepsรกnรญ tohoto commitu.
-signing.wont_sign.never=Commity nejsou nikdy podepsรกny.
-signing.wont_sign.always=Commity jsou vลพdy podepsรกny.
-signing.wont_sign.pubkey=Commit nebude podepsรกn, protoลพe nemรกte veลejnรฝ klรญฤ spojenรฝ s vaลกรญm รบฤtem.
-signing.wont_sign.twofa=Pro podepsรกnรญ commitลฏ musรญte mรญt povoleno dvoufaktorovรฉ ovฤลenรญ.
-signing.wont_sign.parentsigned=Commit nebude podepsรกn, protoลพe nadลazenรฝ commit nenรญ podepsรกn.
-signing.wont_sign.basesigned=Slouฤenรญ nebude podepsรกno, protoลพe zรกkladnรญ commit nenรญ podepsanรฝ.
+signing.will_sign=Tato revize bude podepsรกna klรญฤem โ%sโ.
+signing.wont_sign.error=Doลกlo k chybฤ pลi kontrole, zda mลฏลพe bรฝt revize podepsรกna.
+signing.wont_sign.nokey=Tato instance nemรก ลพรกdnรฝ klรญฤ k podepsรกnรญ tรฉto revize.
+signing.wont_sign.never=Revize nebudou nikdy podepsรกny.
+signing.wont_sign.always=Revize budou vลพdy podepsรกny.
+signing.wont_sign.pubkey=Reviz nebude podepsรกna, protoลพe nemรกte veลejnรฝ klรญฤ spojenรฝ s vaลกรญm รบฤtem.
+signing.wont_sign.twofa=Pro podepisovรกnรญ revizรญ musรญte mรญt zapnuto dvoufรกzovรฉ ovฤลenรญ.
+signing.wont_sign.parentsigned=Revize nebude podepsรกna, protoลพe nadลazenรก revize nenรญ podepsรกna.
+signing.wont_sign.basesigned=Revize nebude podepsรกna, protoลพe zรกkladnรญ revize nenรญ podepsรกna.
signing.wont_sign.headsigned=Slouฤenรญ nebude podepsรกno, protoลพe hlavnรญ revize nenรญ podepsรกna.
signing.wont_sign.commitssigned=Slouฤenรญ nebude podepsรกno, protoลพe vลกechny pลidruลพenรฉ revize nejsou podepsรกny.
-signing.wont_sign.approved=Slouฤenรญ nebude podepsรกno, protoลพe poลพadavek na nataลพenรญ nenรญ schvรกlen.
+signing.wont_sign.approved=Slouฤenรญ nebude podepsรกno, protoลพe ลพรกdost o slouฤenรญ nenรญ schvรกlena.
signing.wont_sign.not_signed_in=Nejste pลihlรกลกeni.
-ext_wiki=Pลรญstup k externรญ Wiki
+ext_wiki=Externรญ wiki
ext_wiki.desc=Odkaz do externรญ Wiki.
wiki=Wiki
-wiki.welcome=Vรญtejte ve Wiki.
+wiki.welcome=Vรญtejte ve wiki.
wiki.welcome_desc=Wiki vรกm umoลพnรญ psรกt a sdรญlet dokumentaci se spolupracovnรญky.
wiki.desc=Piลกte a sdรญlejte dokumentaci se spolupracovnรญky.
wiki.create_first_page=Vytvoลte prvnรญ strรกnku
@@ -1975,21 +2051,21 @@ wiki.filter_page=Filtr strรกnky
wiki.new_page=Strรกnka
wiki.page_title=Nรกzev strรกnky
wiki.page_content=Obsah strรกnky
-wiki.default_commit_message=Napiลกte poznรกmku k tรฉto aktualizaci strรกnky (nepovinnรฝ).
+wiki.default_commit_message=Napiลกte poznรกmku k tรฉto aktualizaci strรกnky (nepovinnรฉ).
wiki.save_page=Uloลพit strรกnku
-wiki.last_commit_info=%s upravil tuto strรกnku %s
-wiki.edit_page_button=Zmฤnit strรกnku
+wiki.last_commit_info=Uลพivatel %s upravil tuto strรกnku %s
+wiki.edit_page_button=Upravit
wiki.new_page_button=Novรก strรกnka
wiki.file_revision=Revize strรกnky
wiki.wiki_page_revisions=Revize strรกnky
-wiki.back_to_wiki=Zpฤt na wiki strรกnku
+wiki.back_to_wiki=Zpฤt na strรกnku wiki
wiki.delete_page_button=Smazat strรกnku
-wiki.delete_page_notice_1=Odstranฤnรญ Wiki strรกnky โ%sโ nemลฏลพe bรฝt vrรกceno zpฤt. Pokraฤovat?
-wiki.page_already_exists=Strรกnka Wiki se stejnรฝm nรกzvem jiลพ existuje.
-wiki.reserved_page=Jmรฉno Wiki strรกnky โ%sโ je rezervovรกno.
+wiki.delete_page_notice_1=Odstranฤnรญ strรกnky wiki โ%sโ je nevratnรฉ. Pokraฤovat?
+wiki.page_already_exists=Strรกnka wiki se stejnรฝm nรกzvem jiลพ existuje.
+wiki.reserved_page=Nรกzev strรกnky wiki โ%sโ je rezervovรกn.
wiki.pages=Strรกnky
wiki.last_updated=Naposledy aktualizovรกno: %s
-wiki.page_name_desc=Zadejte nรกzev tรฉto Wiki strรกnky. Nฤkterรฉ speciรกlnรญ nรกzvy jsou: โHomeโ, โ_Sidebarโ a โ_Footerโ.
+wiki.page_name_desc=Zadejte nรกzev tรฉto strรกnky wiki. Nฤkterรฉ speciรกlnรญ nรกzvy jsou: โHomeโ, โ_Sidebarโ a โ_Footerโ.
wiki.original_git_entry_tooltip=Zobrazit originรกlnรญ Git soubor namรญsto pouลพitรญ pลรกtelskรฉho odkazu.
activity=Aktivita
@@ -2007,9 +2083,9 @@ activity.active_prs_count_n=%d aktivnรญch ลพรกdostรญ o slouฤen
activity.merged_prs_count_1=Slouฤenรก ลพรกdost
activity.merged_prs_count_n=Slouฤenรฉ ลพรกdosti
activity.opened_prs_count_1=Navrhovanรก ลพรกdost o slouฤenรญ
-activity.opened_prs_count_n=Navrhovanรฉ ลพรกdosti o slouฤenรญ
-activity.title.user_1=%d uลพivatel
-activity.title.user_n=%d uลพivatelลฏ
+activity.opened_prs_count_n=Navrลพenรฉ ลพรกdosti o slouฤenรญ
+activity.title.user_1=%d uลพivatelem
+activity.title.user_n=%d uลพivateli
activity.title.prs_1=%d ลพรกdost o slouฤenรญ
activity.title.prs_n=%d ลพรกdostรญ o slouฤenรญ
activity.title.prs_merged_by=%s slouฤil %s
@@ -2034,23 +2110,23 @@ activity.unresolved_conv_desc=Tyto nedรกvno zmฤnฤnรฉ problรฉmy a ลพรกdosti o s
activity.unresolved_conv_label=Otevลรญt
activity.title.releases_1=%d vydรกnรญ
activity.title.releases_n=%d vydรกnรญ
-activity.title.releases_published_by=%s publikoval %s
-activity.published_release_label=Publikovรกno
-activity.no_git_activity=V tomto obdobรญ nebyla ลพรกdnรก aktivita pลi odevzdรกnรญ.
-activity.git_stats_exclude_merges=Pลi vylouฤenรญ sluฤovรกnรญ,
+activity.title.releases_published_by=%s zveลejnฤno %s
+activity.published_release_label=Vydรกnรญ
+activity.no_git_activity=V tomto obdobรญ nebyla ลพรกdnรก aktivita pลispฤvatelลฏ.
+activity.git_stats_exclude_merges=S vรฝjimkou sluฤovรกnรญ
activity.git_stats_author_1=%d autor
-activity.git_stats_author_n=%d autoลi
+activity.git_stats_author_n=%d autorลฏ
activity.git_stats_pushed_1=nahrรกl
-activity.git_stats_pushed_n=nahrรกly
-activity.git_stats_commit_1=%d commit
-activity.git_stats_commit_n=%d commity
-activity.git_stats_push_to_branch=do %s a
+activity.git_stats_pushed_n=nahrรกlo
+activity.git_stats_commit_1=%d revize
+activity.git_stats_commit_n=%d revizรญ
+activity.git_stats_push_to_branch=do vฤtve %s a
activity.git_stats_push_to_all_branches=do vลกech vฤtvรญ.
-activity.git_stats_on_default_branch=Na %s,
+activity.git_stats_on_default_branch=Vฤtev %s:
activity.git_stats_file_1=%d soubor
-activity.git_stats_file_n=%d soubory
-activity.git_stats_files_changed_1=se zmฤnil
-activity.git_stats_files_changed_n=se zmฤnily
+activity.git_stats_file_n=%d souborลฏ
+activity.git_stats_files_changed_1=byl zmฤnฤn
+activity.git_stats_files_changed_n=bylo zmฤnฤno
activity.git_stats_additions=a bylo zde
activity.git_stats_addition_1=%d pลidรกnรญ
activity.git_stats_addition_n=%d pลidรกnรญ
@@ -2058,8 +2134,8 @@ activity.git_stats_and_deletions=a
activity.git_stats_deletion_1=%d odebrรกnรญ
activity.git_stats_deletion_n=%d odebrรกnรญ
-contributors.contribution_type.filter_label=Typ pลรญspฤvku:
-contributors.contribution_type.commits=Commity
+contributors.contribution_type.filter_label = Typ pลรญspฤvku:
+contributors.contribution_type.commits=Revize
search=Vyhledat
search.search_repo=Hledat repozitรกล
@@ -2081,21 +2157,21 @@ settings.collaboration.write=Zรกpis
settings.collaboration.read=ฤtenรญ
settings.collaboration.owner=Vlastnรญk
settings.collaboration.undefined=Neurฤeno
-settings.hooks=Webovรฉ hรกฤky
+settings.hooks=Webhooky
settings.githooks=Git hooky
settings.basic_settings=Zรกkladnรญ nastavenรญ
-settings.mirror_settings=Nastavenรญ zrcadla
-settings.mirror_settings.docs=Nastavte repozitรกล pro automatickou synchronizaci commitลฏ, znaฤek a vฤtvรญ s jinรฝm repozitรกลem.
-settings.mirror_settings.docs.disabled_pull_mirror.instructions=Nastavte vรกลก projekt pro automatickรฉ nahrรกvรกnรญ commitลฏ, znaฤek a vฤtvรญ do jinรฉho repozitรกลe. Sprรกvce webu zakรกzal zrcadla pro nataลพenรญ.
-settings.mirror_settings.docs.disabled_push_mirror.instructions=Nastavte svลฏj projekt pro automatickรฉ nataลพenรญ commitลฏ, znaฤek a vฤtvรญ z jinรฉho repozitรกลe.
+settings.mirror_settings=Nastavenรญ zrcadel
+settings.mirror_settings.docs=Nastavte repozitรกล pro automatickou synchronizaci revizรญ, znaฤek a vฤtvรญ s jinรฝm repozitรกลem.
+settings.mirror_settings.docs.disabled_pull_mirror.instructions=Nastavte vรกลก projekt pro automatickรฉ nahrรกvรกnรญ revizรญ, znaฤek a vฤtvรญ do jinรฉho repozitรกลe. Sprรกvce webu zakรกzal nahrรกvรกnรญ ze zrcadel.
+settings.mirror_settings.docs.disabled_push_mirror.instructions=Nastavte svลฏj projekt pro automatickรฉ nahrรกvรกnรญ revizรญ, znaฤek a vฤtvรญ z jinรฉho repozitรกลe.
settings.mirror_settings.docs.no_new_mirrors=Vรกลก repozitรกล zrcadlรญ zmฤny do nebo z jinรฉho repozitรกลe. Mฤjte prosรญm na pamฤti, ลพe v tuto chvรญli nemลฏลพete vytvoลit ลพรกdnรก novรก zrcadla.
settings.mirror_settings.docs.can_still_use=I kdyลพ nemลฏลพete upravit stรกvajรญcรญ zrcadla nebo vytvoลit novรก, stรกle mลฏลพete pouลพรญt svรฉ stรกvajรญcรญ zrcadlo.
settings.mirror_settings.docs.more_information_if_disabled=Vรญce informacรญ o zrcadlech pro nahrรกnรญ a nataลพenรญ naleznete zde:
settings.mirror_settings.docs.doc_link_title=Jak mohu zrcadlit repozitรกลe?
-settings.mirror_settings.docs.pulling_remote_title=Staลพenรญ ze vzdรกlenรฉho รบloลพiลกtฤ
+settings.mirror_settings.docs.pulling_remote_title=Stahovรกnรญ ze vzdรกlenรฉho repozitรกลe
settings.mirror_settings.mirrored_repository=Zrcadlenรฝ repozitรกล
settings.mirror_settings.direction=Smฤr
-settings.mirror_settings.direction.pull=Natรกhnout
+settings.mirror_settings.direction.pull=Slouฤit
settings.mirror_settings.direction.push=Nahrรกt
settings.mirror_settings.last_update=Poslednรญ aktualizace
settings.mirror_settings.push_mirror.none=Nenastavena ลพรกdnรก zrcadla pro nahrรกnรญ
@@ -2115,17 +2191,17 @@ settings.wiki_desc=Povolit wiki repozitรกลe
settings.use_internal_wiki=Pouลพรญvat vestavฤnou wiki
settings.use_external_wiki=Pouลพรญt externรญ wiki
settings.external_wiki_url=Adresa URL externรญ wiki
-settings.external_wiki_url_error=URL externรญ wiki platnรฉ URL.
-settings.external_wiki_url_desc=Kdyลพ nรกvลกtฤvnรญci kliknou na zรกloลพku Wiki, jsou pลesmฤrovรกnรญ na URL externรญ Wiki.
-settings.issues_desc=Povolit systรฉm problรฉmลฏ repozitรกลe
-settings.use_internal_issue_tracker=Pouลพรญt vestavฤnรฝ systรฉm problรฉmลฏ
-settings.use_external_issue_tracker=Pouลพรญt externรญ systรฉm problรฉmลฏ
-settings.external_tracker_url=Adresa URL externรญho systรฉmu problรฉmลฏ
-settings.external_tracker_url_error=Adresa URL externรญho systรฉmu problรฉmลฏ nenรญ platnou adresou URL.
-settings.external_tracker_url_desc=Pokud nรกvลกtฤvnรญci kliknou na zรกloลพku problรฉmลฏ, budou pลesmฤrovรกnรญ na externรญ systรฉm problรฉmลฏ.
-settings.tracker_url_format=Formรกt adresy URL externรญho systรฉmu problรฉmลฏ
-settings.tracker_url_format_error=Formรกt adresy URL externรญho systรฉmu problรฉmลฏ nenรญ platnรก adresa URL.
-settings.tracker_issue_style=Formรกt ฤรญsel externรญho systรฉmu problรฉmลฏ
+settings.external_wiki_url_error=Adresa externรญ wiki nenรญ platnรก adresa URL.
+settings.external_wiki_url_desc=Kdyลพ nรกvลกtฤvnรญci kliknou na zรกloลพku wiki, budou pลesmฤrovรกni na adresu externรญ wiki.
+settings.issues_desc=Povolit systรฉm sledovรกnรญ problรฉmลฏ repozitรกลe
+settings.use_internal_issue_tracker=Pouลพรญt vestavฤnรฝ systรฉm sledovรกnรญ problรฉmลฏ
+settings.use_external_issue_tracker=Pouลพรญt externรญ systรฉm sledovรกnรญ problรฉmลฏ
+settings.external_tracker_url=Adresa URL externรญho systรฉmu sledovรกnรญ problรฉmลฏ
+settings.external_tracker_url_error=Adresa URL externรญho systรฉmu sledovรกnรญ problรฉmลฏ nenรญ platnou adresou URL.
+settings.external_tracker_url_desc=Pokud nรกvลกtฤvnรญci kliknou na zรกloลพku problรฉmลฏ, budou pลesmฤrovรกnรญ na externรญ systรฉm sledovรกnรญ problรฉmลฏ.
+settings.tracker_url_format=Formรกt adresy URL externรญho systรฉmu sledovรกnรญ problรฉmลฏ
+settings.tracker_url_format_error=Formรกt adresy URL externรญho systรฉmu sledovรกnรญ problรฉmลฏ nenรญ platnรก adresa URL.
+settings.tracker_issue_style=Formรกt ฤรญsel externรญho systรฉmu sledovรกnรญ problรฉmลฏ
settings.tracker_issue_style.numeric=ฤรญselnรฝ
settings.tracker_issue_style.alphanumeric=Alfanumerickรฝ
settings.tracker_issue_style.regexp=Regulรกrnรญ vรฝraz
@@ -2136,9 +2212,9 @@ settings.enable_timetracker=Povolit sledovรกnรญ ฤasu
settings.allow_only_contributors_to_track_time=Povolit sledovรกnรญ ฤasu pouze pลispฤvatelลฏm
settings.pulls_desc=Povolit ลพรกdosti o slouฤenรญ
settings.pulls.ignore_whitespace=Ignorovat bรญlรฉ znaky pลi konfliktech
-settings.pulls.enable_autodetect_manual_merge=Povolit autodetekci ruฤnรญch slouฤenรญ (Poznรกmka: V nฤkterรฝch zvlรกลกtnรญch pลรญpadech mลฏลพe dojรญt k nesprรกvnรฉmu rozhodnutรญ)
-settings.pulls.allow_rebase_update=Povolit aktualizaci vฤtve poลพadavku na nataลพenรญ pomocรญ rebase
-settings.pulls.default_delete_branch_after_merge=Ve vรฝchozรญm nastavenรญ mazat vฤtev poลพadavku na nataลพenรญ po jeho slouฤenรญ
+settings.pulls.enable_autodetect_manual_merge=Povolit automatickou detekci ruฤnรญch slouฤenรญ (upozornฤnรญ: v nฤkterรฝch zvlรกลกtnรญch pลรญpadech mลฏลพe dojรญt k nesprรกvnรฉmu rozhodnutรญ)
+settings.pulls.allow_rebase_update=Povolit aktualizaci vฤtve ลพรกdosti o slouฤenรญ pomocรญ rebase
+settings.pulls.default_delete_branch_after_merge=Ve vรฝchozรญm nastavenรญ odstranit vฤtev ลพรกdosti o slouฤenรญ po jejรญm slouฤenรญ
settings.pulls.default_allow_edits_from_maintainers=Ve vรฝchozรญm nastavenรญ povolit รบpravy od sprรกvcลฏ
settings.releases_desc=Povolit vydรกnรญ v repozitรกลi
settings.packages_desc=Povolit registr balรญฤkลฏ repozitรกลe
@@ -2148,11 +2224,11 @@ settings.admin_settings=Administrรกtorskรก nastavenรญ
settings.admin_enable_health_check=Povolit kontrolu stavu repozitรกลe (git fsck)
settings.admin_code_indexer=Indexovรกnรญ kรณdu
settings.admin_stats_indexer=Index statistiky kรณdu
-settings.admin_indexer_commit_sha=Poslednรญ indexovanรฝ commit
+settings.admin_indexer_commit_sha=Poslednรญ indexovanรก revize
settings.admin_indexer_unindexed=Neindexovรกno
settings.reindex_button=Pลidat do fronty reindexace
settings.reindex_requested=Poลพadovรกno reindexovรกnรญ
-settings.admin_enable_close_issues_via_commit_in_any_branch=Zavลรญt problรฉm pomocรญ commitu v jinรฉ neลพ vรฝchozรญ vฤtvi
+settings.admin_enable_close_issues_via_commit_in_any_branch=Zavลรญt problรฉm pomocรญ revize provedenรฉ v jinรฉ neลพ vรฝchozรญ vฤtvi
settings.danger_zone=Nebezpeฤnรก zรณna
settings.new_owner_has_same_repo=Novรฝ vlastnรญk jiลพ repozitรกล se stejnรฝm nรกzvem mรก. Vyberte prosรญm jinรฉ jmรฉno.
settings.convert=Pลevรฉst na bฤลพnรฝ repozitรกล
@@ -2189,20 +2265,20 @@ settings.trust_model.collaborator=Spolupracovnรญk
settings.trust_model.collaborator.long=Spolupracovnรญk: Dลฏvฤลovat podpisลฏm spolupracovnรญkลฏ
settings.trust_model.collaborator.desc=Platnรฉ podpisy spolupracovnรญkลฏ tohoto repozitรกลe budou oznaฤeny jako โdลฏvฤryhodnรฉโ - (aลฅ se shodujรญ s autorem, ฤi nikoli). V opaฤnรฉm pลรญpadฤ budou platnรฉ podpisy oznaฤeny jako โnedลฏvฤryhodnรฉโ, pokud se podpis shoduje s pลispฤvatelem a โneodpovรญdajรญcรญโ, pokud ne.
settings.trust_model.committer=Pลispฤvatel
-settings.trust_model.committer.long=Pลispฤvatel: Dลฏvฤลovat podpisลฏm, kterรฉ odpovรญdajรญ autorลฏm (coลพ odpovรญdรก GitHub a pลinutรญ Giteu nastavit jako tvลฏrce pro Giteou podepsanรฉ revize)
-settings.trust_model.committer.desc=Platnรฉ podpisy budou oznaฤeny jako โdลฏvฤryhodnรฉโ pouze, pokud se shodujรญ s pลispฤvatelem, v opaฤnรฉm pลรญpadฤ budou oznaฤeny jako โneodpovรญdajรญcรญโ. To pลinutรญ Forgejo, aby bylo pลispฤvatelem podepsanรฝch commitลฏ se skuteฤnรฝm pลispฤvatelem oznaฤenรฝm jako Co-authored-by: a Co-committed-by: na konci commitu. Vรฝchozรญ klรญฤ Forgejo musรญ odpovรญdat uลพivateli v databรกzi.
+settings.trust_model.committer.long=Pลispฤvatel: Dลฏvฤลovat podpisลฏm, kterรฉ odpovรญdajรญ autorลฏm (coลพ odpovรญdรก GitHubu a pลinutรญ Forgejo nastavit se jako autora pro Forgejem podepsanรฉ revize)
+settings.trust_model.committer.desc=Platnรฉ podpisy budou oznaฤeny jako โdลฏvฤryhodnรฉโ pouze, pokud se shodujรญ s pลispฤvatelem, v opaฤnรฉm pลรญpadฤ budou oznaฤeny jako โneodpovรญdajรญcรญโ. To pลinutรญ Forgejo, aby bylo pลispฤvatelem podepsanรฝch revizรญ se skuteฤnรฝm pลispฤvatelem oznaฤenรฝm jako Co-authored-by: a Co-committed-by: na konci revize. Vรฝchozรญ klรญฤ Forgejo musรญ odpovรญdat uลพivateli v databรกzi.
settings.trust_model.collaboratorcommitter=Spolupracovnรญk+Pลispฤvatel
settings.trust_model.collaboratorcommitter.long=Spolupracovnรญk+Pลispฤvatel: Dลฏvฤลovat podpisลฏm od spolupracovnรญkลฏ, kterรฉ odpovรญdajรญ tvลฏrci revize
-settings.trust_model.collaboratorcommitter.desc=Platnรฉ podpisy spolupracovnรญkลฏ tohoto repozitรกลe budou oznaฤeny jako โdลฏvฤryhodnรฉโ, pokud se shodujรญ s pลispฤvatelem. V opaฤnรฉm pลรญpadฤ budou platnรฉ podpisy oznaฤeny jako "nedลฏvฤryhodnรฉ", pokud se podpis shoduje s pลispฤvatelem a โneodpovรญdajรญcรญmโ v opaฤnรฉm pลรญpadฤ. To pลinutรญ Giteu, aby byla oznaฤena jako pลispฤvatel podepsanรฝch commitลฏ se skuteฤnรฝm pลispฤvatelem oznaฤenรฝm jako Co-Authored-By: a Co-Committed-By: na konci commitu. Vรฝchozรญ klรญฤ Forgejo musรญ odpovรญdat uลพivateli v databรกzi.
+settings.trust_model.collaboratorcommitter.desc=Platnรฉ podpisy spolupracovnรญkลฏ tohoto repozitรกลe budou oznaฤeny jako โdลฏvฤryhodnรฉโ, pokud se shodujรญ s pลispฤvatelem. V opaฤnรฉm pลรญpadฤ budou platnรฉ podpisy oznaฤeny jako "nedลฏvฤryhodnรฉ", pokud se podpis shoduje s pลispฤvatelem a โneodpovรญdajรญcรญmโ v opaฤnรฉm pลรญpadฤ. To pลinutรญ Forgejo, aby bylo oznaฤeno jako autor podepsanรฝch revizรญ se skuteฤnรฝm pลispฤvatelem oznaฤenรฝm jako Co-Authored-By: a Co-Committed-By: na konci revize. Vรฝchozรญ klรญฤ Forgejo musรญ odpovรญdat uลพivateli v databรกzi.
settings.wiki_delete=Odstranit data wiki
-settings.wiki_delete_desc=Smazรกnรญ Wiki dat repozitรกลe je trvalรฉ a nemลฏลพe bรฝt vrรกceno zpฤt.
+settings.wiki_delete_desc=Smazรกnรญ dat wiki repozitรกลe je trvalรฉ a je nevratnรฉ.
settings.wiki_delete_notices_1=- Natrvalo odstranรญ a zakรกลพe wiki repozitรกลe pro %s.
settings.confirm_wiki_delete=Odstranit data wiki
-settings.wiki_deletion_success=Wiki data repozitรกลe byla odstranฤna.
+settings.wiki_deletion_success=Data wiki repozitรกลe byla odstranฤna.
settings.delete=Odstranit tento repozitรกล
settings.delete_desc=Smazรกnรญ repozitรกลe je trvalรฉ a nemลฏลพe bรฝt vrรกceno zpฤt.
-settings.delete_notices_1=- Tuto operaci nelze zvrรกtit.
-settings.delete_notices_2=- Tato operace trvale smaลพe repozitรกล %s vฤetnฤ kรณdu, problรฉmลฏ, komentรกลลฏ, dat wiki a nastavenรญ spolupracovnรญkลฏ.
+settings.delete_notices_1=- Tato operace je NEVRATNร .
+settings.delete_notices_2=- Tato operace trvale odstranรญ repozitรกล %s vฤetnฤ kรณdu, problรฉmลฏ, komentรกลลฏ, dat wiki a nastavenรญ spolupracovnรญkลฏ.
settings.delete_notices_fork_1=- Fork tohoto repozitรกลe bude po smazรกnรญ nezรกvislรฝ.
settings.deletion_success=Repozitรกล byl odstranฤn.
settings.update_settings_success=Nastavenรญ repozitรกลe bylo aktualizovรกno.
@@ -2231,23 +2307,23 @@ settings.delete_team_tip=Tento tรฝm mรก pลรญstup ke vลกem repositรกลลฏm a nem
settings.remove_team_success=Pลรญstup tรฝmu k repozitรกลi byl odstranฤn.
settings.add_webhook=Pลidat webhook
settings.add_webhook.invalid_channel_name=Kanรกl webovรฉho hรกฤku nemลฏลพe bรฝt prรกzdnรฝ a nemลฏลพe obsahovat pouze znak #.
-settings.hooks_desc=Webovรฉ hรกฤky automaticky vytvรกลejรญ dotazy HTTP POST na server, kdyลพ nastane urฤitรก udรกlost v Forgejo. ฤtฤte vรญce v pลรญruฤce webovรฝch hรกฤkลฏ .
+settings.hooks_desc=Webhooky automaticky vytvรกลejรญ dotazy HTTP POST na server, kdyลพ nastane urฤitรก udรกlost ve Forgejo. Vรญce informacรญ v pลรญruฤce webhookลฏ .
settings.webhook_deletion=Odstranit webhook
settings.webhook_deletion_desc=Odstranฤnรญ webovรฉho hรกฤku smaลพe jeho nastavenรญ a historii doruฤenรญ. Pokraฤovat?
-settings.webhook_deletion_success=Webovรฝ hรกฤek byl smazรกn.
+settings.webhook_deletion_success=Webhook byl smazรกn.
settings.webhook.test_delivery=Test doruฤitelnosti
-settings.webhook.test_delivery_desc=Vyzkouลกet tento webovรฝ hรกฤek pomocรญ faleลกnรฉ udรกlosti.
-settings.webhook.test_delivery_desc_disabled=Chcete-li tento webovรฝ hรกฤek otestovat s faleลกnou udรกlostรญ, aktivujte ho.
+settings.webhook.test_delivery_desc=Otestovat tento webhook pomocรญ faleลกnรฉ udรกlosti.
+settings.webhook.test_delivery_desc_disabled=Chcete-li pomocรญ faleลกnรฉ udรกlosti otestovat tento webhook, aktivujte ho.
settings.webhook.request=Poลพadavek
settings.webhook.response=Odpovฤฤ
settings.webhook.headers=Hlaviฤky
settings.webhook.payload=Obsah
settings.webhook.body=Tฤlo zprรกvy
-settings.webhook.replay.description=Zopakovat tento webovรฝ hรกฤek.
-settings.webhook.replay.description_disabled=Chcete-li znovu spustit tento webovรฝ hรกฤek, aktivujte jej.
+settings.webhook.replay.description=Zopakovat tento webhook.
+settings.webhook.replay.description_disabled=Chcete-li zopakovat tento webhook, aktivujte jej.
settings.webhook.delivery.success=Udรกlost byla pลidรกna do fronty doruฤenรญ. Mลฏลพe to trvat nฤkolik sekund, neลพ se zobrazรญ v historii doruฤenรญ.
settings.githooks_desc=Git hooks jsou spravovรกny samotnรฝm Gitem. Nรญลพe mลฏลพete upravit soubory hookลฏ pro nastavenรญ vlastnรญch operacรญ.
-settings.githook_edit_desc=Je-li hรกฤek neaktivnรญ, bude zobrazen vzorovรฝ obsah. Nebude-li zadรกn ลพรกdnรฝ obsah, hรกฤek bude vypnut.
+settings.githook_edit_desc=Je-li webhook neaktivnรญ, bude zobrazen vzorovรฝ obsah. Ponechte prรกzdnรฉ pro zakรกzรกnรญ tohoto webhooku.
settings.githook_name=Nรกzev hooku
settings.githook_content=Obsah hooku
settings.update_githook=Upravit hook
@@ -2270,10 +2346,10 @@ settings.event_create=Vytvoลit
settings.event_create_desc=Vฤtev nebo znaฤka vytvoลena.
settings.event_delete=Smazat
settings.event_delete_desc=Vฤtev nebo znaฤka smazรกna.
-settings.event_fork=Rozลกtฤpit
+settings.event_fork=Fork
settings.event_fork_desc=Repozitรกล rozลกtฤpen.
settings.event_wiki=Wiki
-settings.event_wiki_desc=Wiki strรกnka vytvoลena, pลejmenovรกna nebo smazรกna.
+settings.event_wiki_desc=Strรกnka wiki vytvoลena, pลejmenovรกna nebo smazรกna.
settings.event_release=Vydรกnรญ
settings.event_release_desc=Vydรกnรญ v tomto repozitรกลi bylo publikovรกno, aktualizovรกno nebo smazรกno.
settings.event_push=Nahrรกt
@@ -2281,43 +2357,43 @@ settings.event_push_desc=Nahrรกnรญ pomocรญ Gitu do repozitรกลe.
settings.event_repository=Repozitรกล
settings.event_repository_desc=Repozitรกล vytvoลen nebo smazรกn.
settings.event_header_issue=Udรกlosti problรฉmลฏ
-settings.event_issues=Problรฉmy
+settings.event_issues=รprava
settings.event_issues_desc=Problรฉm otevลen, uzavลen, znovu otevลen nebo upraven.
-settings.event_issue_assign=Problรฉm pลiลazen
+settings.event_issue_assign=Pลiลazenรญ
settings.event_issue_assign_desc=Problรฉm pลiลazen nebo nepลiลazen.
-settings.event_issue_label=Problรฉm oznaฤen
-settings.event_issue_label_desc=ล tรญtky problรฉmu upraveny nebo vymazรกny.
-settings.event_issue_milestone=K problรฉmu pลidรกn milnรญk
-settings.event_issue_milestone_desc=K problรฉmu pลidรกn nebo odebrรกn milnรญk.
-settings.event_issue_comment=Komentรกล k problรฉmu
+settings.event_issue_label=ล tรญtky
+settings.event_issue_label_desc=ล tรญtky problรฉmu pลidรกny nebo odstranฤny.
+settings.event_issue_milestone=Milnรญky
+settings.event_issue_milestone_desc=Milnรญk pลidรกn, odstranฤn nebo upraven.
+settings.event_issue_comment=Komentรกลe
settings.event_issue_comment_desc=Pลidรกn, upraven nebo smazรกn komentรกล problรฉmu.
settings.event_header_pull_request=Udรกlosti ลพรกdosti o slouฤenรญ
-settings.event_pull_request=ลฝรกdost o slouฤenรญ
+settings.event_pull_request=รprava
settings.event_pull_request_desc=Poลพadavek na nataลพenรญ otevลen, uzavลen, znovu otevลen nebo upraven.
-settings.event_pull_request_assign=ลฝรกdost o slouฤenรญ pลiลazena
+settings.event_pull_request_assign=Pลiลazenรญ
settings.event_pull_request_assign_desc=Poลพadavek na nataลพenรญ pลiลazen nebo nepลiลazen.
-settings.event_pull_request_label=ลฝรกdost o slouฤenรญ oznaฤena
-settings.event_pull_request_label_desc=ล tรญtky poลพadavku na nataลพenรญ aktualizovรกny nebo vymazรกny.
-settings.event_pull_request_milestone=K ลพรกdosti o slouฤenรญ pลidรกn milnรญk
-settings.event_pull_request_milestone_desc=Poลพadavku na nataลพenรญ pลidรกn nebo odebrรกn milnรญk.
-settings.event_pull_request_comment=ลฝรกdost o slouฤenรญ okomentovรกna
+settings.event_pull_request_label=ล tรญtky
+settings.event_pull_request_label_desc=ล tรญtky ลพรกdosti o slouฤenรญ pลidรกny nebo odstranฤny.
+settings.event_pull_request_milestone=Milnรญky
+settings.event_pull_request_milestone_desc=Milnรญk pลidรกn, odstranฤn nebo upraven.
+settings.event_pull_request_comment=Komentรกลe
settings.event_pull_request_comment_desc=Komentรกล poลพadavku na nataลพenรญ vytvoลen, upraven nebo odstranฤn.
-settings.event_pull_request_review=ลฝรกdost o slouฤenรญ zkontrolovรกna
-settings.event_pull_request_review_desc=Poลพadavek na nataลพenรญ schvรกlen, odmรญtnut nebo zkontrolovรกn.
-settings.event_pull_request_sync=ลฝรกdost o slouฤenรญ synchronizovรกna
-settings.event_pull_request_sync_desc=Poลพadavek na nataลพenรญ synchronizovรกn.
-settings.event_pull_request_review_request=Vyลพรกdรกna kontrola ลพรกdosti o slouฤenรญ
+settings.event_pull_request_review=Kontroly
+settings.event_pull_request_review_desc=ลฝรกdost o slouฤenรญ schvรกlena, zamรญtnuta nebo byl pลidรกn komentรกล kontroly.
+settings.event_pull_request_sync=Synchronizovรกno
+settings.event_pull_request_sync_desc=Vฤtev automaticky aktualizovรกna s cรญlovou vฤtvรญ.
+settings.event_pull_request_review_request=ลฝรกdosti o kontrolu
settings.event_package=Balรญฤek
settings.event_package_desc=Balรญฤek vytvoลen nebo odstranฤn v repozitรกลi.
settings.branch_filter=Filtr vฤtvรญ
-settings.branch_filter_desc=Povolenรฉ vฤtve pro udรกlosti nahrรกnรญ, vytvoลenรญ vฤtve a smazรกnรญ vฤtve jsou urฤeny pomocรญ zรกstupnรฉho vzoru. Pokud je prรกzdnรฝ nebo *
, vลกechny udรกlosti jsou ohlรกลกeny. Podรญvejte se na dokumentaci syntaxe na github.com/gobwas/glob . Pลรญklady: master
, {master,release*}
.
+settings.branch_filter_desc=Povolenรฉ vฤtve pro udรกlosti nahrรกnรญ, vytvoลenรญ vฤtve a smazรกnรญ vฤtve jsou urฤeny pomocรญ zรกstupnรฉho vzoru. Pokud je prรกzdnรฝ nebo *
, vลกechny udรกlosti jsou ohlรกลกeny. Podรญvejte se na dokumentaci syntaxe na %[2]s . Pลรญklady: master
, {master,release*}
.
settings.authorization_header=Autorizaฤnรญ hlaviฤka
settings.authorization_header_desc=Pokud vyplnฤno, bude pลipojeno k poลพadavkลฏm jako autorizaฤnรญ hlaviฤka. Pลรญklady: %s.
settings.active=Aktivnรญ
settings.active_helper=Informace o spuลกtฤnรฝch udรกlostech budou odeslรกny na URL webovรฉho hรกฤku.
-settings.add_hook_success=Webovรฝ hรกฤek byl pลidรกn.
+settings.add_hook_success=Webhook byl pลidรกn.
settings.update_webhook=Upravit webhook
-settings.update_hook_success=Webovรฝ hรกฤek byl aktualizovรกn.
+settings.update_hook_success=Webhook byl aktualizovรกn.
settings.delete_webhook=Odstranit webhook
settings.recent_deliveries=Nedรกvnรก doruฤenรญ
settings.hook_type=Typ hooku
@@ -2347,7 +2423,7 @@ settings.add_deploy_key=Pลidat klรญฤ pro nasazenรญ
settings.deploy_key_desc=Klรญฤe pro nasazenรญ majรญ k tomuto repozitรกลi pลรญstup pouze pro ฤtenรญ.
settings.is_writable=Povolit zรกpis
settings.is_writable_info=Povolit tomuto klรญฤi pro nasazenรญ nahrรกvรกnรญ do tohoto repozitรกลe.
-settings.no_deploy_keys=Dosud nejsou ลพรกdnรฉ klรญฤe pro nasazenรญ.
+settings.no_deploy_keys=Zatรญm nebyly vytvoลeny ลพรกdnรฉ klรญฤe pro nasazenรญ.
settings.title=Nรกzev
settings.deploy_key_content=Obsah
settings.key_been_used=Klรญฤ pro nasazenรญ se stejnรฝm obsahem je jiลพ pouลพรญvรกn.
@@ -2357,7 +2433,7 @@ settings.deploy_key_deletion=Odstranit klรญฤ pro nasazenรญ
settings.deploy_key_deletion_desc=Odstranฤnรญ klรญฤe pro nasazenรญ zruลกรญ jeho pลรญstup k repozitรกลi. Pokraฤovat?
settings.deploy_key_deletion_success=Klรญฤ pro nasazenรญ byl odstranฤn.
settings.branches=Vฤtve
-settings.protected_branch=Ochrana vฤtve
+settings.protected_branch=Ochrana vฤtvรญ
settings.protected_branch.save_rule=Uloลพit pravidlo
settings.protected_branch.delete_rule=Odstranit pravidlo
settings.protected_branch_can_push=Povolit nahrรกnรญ?
@@ -2372,40 +2448,40 @@ settings.protect_enable_push=Povolit nahrรกvรกnรญ
settings.protect_enable_push_desc=Kaลพdรฝ, kdo mรก pลรญstup k zรกpisu, bude moci nahrรกvat do tรฉto vฤtve (ale ne vynucenรก nahrรกvรกnรญ).
settings.protect_enable_merge=Povolit slouฤenรญ
settings.protect_whitelist_committers=Povolit omezenรฉ nahrรกnรญ
-settings.protect_whitelist_committers_desc=Pouze povolenรญ uลพivatelรฉ budou moci nahrรกvat do tรฉto vฤtve (ale ne vynucenรญ nahrรกvรกnรญ).
+settings.protect_whitelist_committers_desc=Pouze povolenรญ uลพivatelรฉ budou moci nahrรกvat do tรฉto vฤtve (ale ne vynutit nahrรกnรญ).
settings.protect_whitelist_deploy_keys=Povolit nahrรกnรญ klรญฤลฏm pro nasazenรญ s pลรญstupem pro zรกpis.
-settings.protect_whitelist_users=Povolenรญ uลพivatelรฉ pro nahrรกvรกnรญ:
+settings.protect_whitelist_users=Povolenรญ uลพivatelรฉ pro nahrรกvรกnรญ
settings.protect_whitelist_search_users=Hledat uลพivateleโฆ
-settings.protect_whitelist_teams=Povolenรฉ tรฝmy pro nahrรกvรกnรญ:
+settings.protect_whitelist_teams=Povolenรฉ tรฝmy pro nahrรกvรกnรญ
settings.protect_whitelist_search_teams=Vyhledat tรฝmyโฆ
settings.protect_merge_whitelist_committers=Povolit whitelist pro sluฤovรกnรญ
-settings.protect_merge_whitelist_committers_desc=Povolit pouze vyjmenovanรฝm uลพivatelลฏm nebo tรฝmลฏm sluฤovat poลพadavky na nataลพenรญ do tรฉto vฤtve.
-settings.protect_merge_whitelist_users=Povolenรญ uลพivatelรฉ pro sluฤovรกnรญ:
-settings.protect_merge_whitelist_teams=Povolenรฉ tรฝmy pro sluฤovรกnรญ:
+settings.protect_merge_whitelist_committers_desc=Povolit sluฤovรกnรญ poลพadavkลฏ na slouฤenรญ do tรฉto vฤtve pouze vyjmenovanรฝm uลพivatelลฏm nebo tรฝmลฏm.
+settings.protect_merge_whitelist_users=Povolenรญ uลพivatelรฉ pro sluฤovรกnรญ
+settings.protect_merge_whitelist_teams=Povolenรฉ tรฝmy pro sluฤovรกnรญ
settings.protect_check_status_contexts=Povolit kontrolu stavu
-settings.protect_status_check_patterns=Vzorce kontroly stavu:
+settings.protect_status_check_patterns=Vzorce kontroly stavu
settings.protect_check_status_contexts_desc=Poลพadovat kontrolu stavu pลed slouฤenรญm. Vyberte, jakรฉ kontroly stavu musรญ projรญt pลed tรญm, neลพ je moลพnรฉ vฤtev slouฤit do vฤtve, kterรก vyhovuje tomuto pravidlu. Pokud je povoleno, revize musรญ bรฝt nejprve nahrรกny do jinรฉ vฤtve, projรญt kontrolou stavu, a nรกslednรฉ slouฤeny nebo pลรญmo nahrรกny do vฤtve, kterรก vyhovuje tomuto pravidlu. Pokud nejsou vybrรกny ลพรกdnรฉ kontexty, musรญ bรฝt poslednรญ potvrzenรญ รบspฤลกnรฉ bez ohledu na kontext.
settings.protect_check_status_contexts_list=Kontroly stavu pro tento repozitรกล zjiลกtฤnรฉ bฤhem poslednรญho tรฝdne
settings.protect_status_check_matched=Odpovรญdรก
settings.protect_invalid_status_check_pattern=Neplatnรฝ vzor kontroly stavu: โ%sโ.
settings.protect_no_valid_status_check_patterns=ลฝรกdnรฉ platnรฉ vzory kontroly stavu.
-settings.protect_required_approvals=Poลพadovanรก schvรกlenรญ:
+settings.protect_required_approvals=Poลพadovanรก schvรกlenรญ
settings.protect_required_approvals_desc=Umoลพnit slouฤenรญ pouze poลพadavkลฏm na nataลพenรญ s dostateฤnรฝm pozitivnรญm hodnocenรญm.
settings.protect_approvals_whitelist_enabled=Omezit schvรกlenรญ na povolenรฉ uลพivatele nebo tรฝmy
settings.protect_approvals_whitelist_enabled_desc=Do poลพadovanรฝch schvรกlenรญ se zapoฤรญtajรญ pouze posouzenรญ od povolenรฝch uลพivatelลฏ nebo tรฝmลฏ. Bez seznamu povolenรฝch se zapoฤรญtรกvรก schvรกlenรญ od kohokoli s prรกvem zรกpisu.
-settings.protect_approvals_whitelist_users=Povolenรญ posuzovatelรฉ:
-settings.protect_approvals_whitelist_teams=Povolenรฉ tรฝmy pro posuzovรกnรญ:
+settings.protect_approvals_whitelist_users=Povolenรญ posuzovatelรฉ
+settings.protect_approvals_whitelist_teams=Povolenรฉ tรฝmy pro posuzovรกnรญ
settings.dismiss_stale_approvals=Odmรญtnout nekvalitnรญ schvรกlenรญ
settings.dismiss_stale_approvals_desc=Pokud budou do vฤtve nahrรกny novรฉ revize, kterรฉ mฤnรญ obsah tohoto poลพadavku na nataลพenรญ, vลกechna starรก schvรกlenรญ budou zamรญtnuta.
-settings.require_signed_commits=Vyลพadovat podepsanรฉ commity
-settings.require_signed_commits_desc=Odmรญtnout nahrรกnรญ do tรฉto vฤtve pokud nejsou podepsanรก nebo jsou neovฤลitelnรก.
+settings.require_signed_commits=Vyลพadovat podepsanรฉ revize
+settings.require_signed_commits_desc=Odmรญtnout nahrรกnรญ do tรฉto vฤtve, pokud nejsou podepsanรก nebo jsou neovฤลitelnรก.
settings.protect_branch_name_pattern=Vzor jmรฉna chrรกnฤnรฉ vฤtve
-settings.protect_branch_name_pattern_desc=Vzory nรกzvลฏ chrรกnฤnรฝch vฤtvรญ. Pro vzorovou syntaxi viz dokumentace . Pลรญklady: main, release/**
+settings.protect_branch_name_pattern_desc=Vzory nรกzvลฏ chrรกnฤnรฝch vฤtvรญ. Pro vzorovou syntaxi viz dokumentace . Pลรญklady: main, release/**
settings.protect_patterns=Vzory
-settings.protect_protected_file_patterns=Vzory chrรกnฤnรฝch souborลฏ (oddฤlenรฉ stลednรญkem โ;โ):
-settings.protect_protected_file_patterns_desc=Chrรกnฤnรฉ soubory, kterรฉ nemajรญ povoleno bรฝt mฤnฤny pลรญmo, i kdyลพ uลพivatel mรก prรกvo pลidรกvat, upravovat nebo mazat soubory v tรฉto vฤtvi. Vรญce vzorลฏ lze oddฤlit pomocรญ stลednรญku (โ;โ). Podรญvejte se na github.com/gobwas/glob dokumentaci pro syntaxi vzoru. Pลรญklady: .drone.yml
, /docs/**/*.txt
.
-settings.protect_unprotected_file_patterns=Vzory nechrรกnฤnรฝch souborลฏ (oddฤlenรฉ stลednรญkem โ;โ):
-settings.protect_unprotected_file_patterns_desc=Nechrรกnฤnรฉ soubory, kterรฉ je moลพnรฉ mฤnit pลรญmo, pokud mรก uลพivatel prรกvo zรกpisu, ฤรญmลพ se obejde omezenรญ push. Vรญce vzorลฏ lze oddฤlit pomocรญ stลednรญku (โ;โ). Podรญvejte se na github.com/gobwas/glob dokumentaci pro syntaxi vzoru. Pลรญklady: .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns=Vzory chrรกnฤnรฝch souborลฏ (oddฤlenรฉ stลednรญkem โ;โ)
+settings.protect_protected_file_patterns_desc=Chrรกnฤnรฉ soubory, kterรฉ nemajรญ povoleno bรฝt mฤnฤny pลรญmo, i kdyลพ uลพivatel mรก prรกvo pลidรกvat, upravovat nebo mazat soubory v tรฉto vฤtvi. Vรญce vzorลฏ lze oddฤlit pomocรญ stลednรญku (โ;โ). Podรญvejte se na dokumentaci %[2]s pro syntaxi vzoru. Pลรญklady: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns=Vzory nechrรกnฤnรฝch souborลฏ (oddฤlenรฉ stลednรญkem โ;โ)
+settings.protect_unprotected_file_patterns_desc=Nechrรกnฤnรฉ soubory, kterรฉ je moลพnรฉ mฤnit pลรญmo, pokud mรก uลพivatel prรกvo zรกpisu, ฤรญmลพ se obejde omezenรญ push. Vรญce vzorลฏ lze oddฤlit pomocรญ stลednรญku (โ;โ). Podรญvejte se na %[2]s dokumentaci pro syntaxi vzoru. Pลรญklady: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=Zapnout ochranu
settings.delete_protected_branch=Vypnout ochranu
settings.update_protect_branch_success=Ochrana vฤtvรญ pro vฤtev โ%sโ byla aktualizovรกna.
@@ -2419,11 +2495,11 @@ settings.block_on_official_review_requests=Blokovat slouฤenรญ pลi oficiรกlnรญ
settings.block_on_official_review_requests_desc=Sluฤovรกnรญ nebude moลพnรฉ, pokud majรญ oficiรกlnรญ poลพadavek na posouzenรญ, i kdyลพ majรญ k dispozici dostatek schvรกlenรญ.
settings.block_outdated_branch=Blokovat slouฤenรญ, pokud je poลพadavek na nataลพenรญ zastaralรฝ
settings.block_outdated_branch_desc=Sluฤovรกnรญ nebude moลพnรฉ, pokud je hlavnรญ vฤtev za zรกkladnรญ vฤtvรญ.
-settings.default_branch_desc=Vybrat vรฝchozรญ vฤtev repozitรกลe pro poลพadavky na nataลพenรญ a revize kรณdu:
-settings.merge_style_desc=Slouฤit styly
+settings.default_branch_desc=Vybrat vรฝchozรญ vฤtev repozitรกลe pro ลพรกdosti o slouฤenรญ a pลรญspฤvky kรณdu:
+settings.merge_style_desc=Styly sluฤovรกnรญ
settings.default_merge_style_desc=Vรฝchozรญ styl slouฤenรญ
settings.choose_branch=Vyberte vฤtevโฆ
-settings.no_protected_branch=Nejsou tu ลพรกdnรฉ chrรกnฤnรฉ vฤtve.
+settings.no_protected_branch=Nemรกte ลพรกdnรฉ chrรกnฤnรฉ vฤtve.
settings.edit_protected_branch=Upravit
settings.protected_branch_required_rule_name=Poลพadovanรฝ nรกzev pravidla
settings.protected_branch_duplicate_rule_name=Jiลพ existuje pravidlo pro tuto sadu vฤtvรญ
@@ -2436,8 +2512,8 @@ settings.tags.protection.allowed.users=Povolenรญ uลพivatelรฉ
settings.tags.protection.allowed.teams=Povolenรฉ tรฝmy
settings.tags.protection.allowed.noone=Nikdo
settings.tags.protection.create=Pลidat pravidlo
-settings.tags.protection.none=Neexistujรญ ลพรกdnรฉ chrรกnฤnรฉ znaฤky.
-settings.tags.protection.pattern.description=Mลฏลพete pouลพรญt jedinรฉ jmรฉno nebo vzor glob nebo regulรกrnรญ vรฝraz, kterรฝ bude odpovรญdat vรญce znaฤek. Pลeฤtฤte si vรญce v prลฏvodci chrรกnฤnรฝmi znaฤkami .
+settings.tags.protection.none=Nebyly vytvoลeny ลพรกdnรฉ chrรกnฤnรฉ znaฤky.
+settings.tags.protection.pattern.description=Mลฏลพete pouลพรญt jedinรฉ jmรฉno nebo vzor glob nebo regulรกrnรญ vรฝraz, kterรฝ bude odpovรญdat vรญce znaฤek. Pลeฤtฤte si vรญce v prลฏvodci chrรกnฤnรฝmi znaฤkami .
settings.bot_token=Token bota
settings.chat_id=ID chatu
settings.thread_id=ID vlรกkna
@@ -2446,23 +2522,23 @@ settings.matrix.room_id=ID mรญstnosti
settings.matrix.message_type=Typ zprรกvy
settings.archive.button=Archivovat repozitรกล
settings.archive.header=Archivovat tento repozitรกล
-settings.archive.text=Archivace repozitรกลe zpลฏsobรญ, ลพe bude zcela urฤen pouze pro ฤtenรญ. Bude skryt z ovlรกdacรญho panelu. Nikdo (ani vy!) nebude moci vytvรกลet novรฉ revize ani otevรญrat novรฉ รบkoly nebo ลพรกdosti o nataลพenรญ.
+settings.archive.text = Archivovรกnรญm repozitรกลe jej celรฝ pลevedete do stavu pouze pro ฤtenรญ. Bude skryt z nรกstฤnky. Nikdo (ani vy!) nebude moci vytvรกลet novรฉ revize ani otevรญrat problรฉmy a ลพรกdosti o slouฤenรญ.
settings.archive.success=Repozitรกล byl รบspฤลกnฤ archivovรกn.
settings.archive.error=Nastala chyba pลi archivovรกnรญ repozitรกลe. Prohlรฉdnฤte si zรกznam pro vรญce detailลฏ.
settings.archive.error_ismirror=Nemลฏลพete archivovat zrcadlenรฝ repozitรกล.
-settings.archive.branchsettings_unavailable=Nastavenรญ vฤtvรญ nenรญ dostupnรฉ, pokud je repozitรกล archivovanรฝ.
-settings.archive.tagsettings_unavailable=Nastavenรญ znaฤek nenรญ k dispozici, pokud je repozitรกล archivovรกn.
+settings.archive.branchsettings_unavailable=Nastavenรญ vฤtvรญ nenรญ v archivovanรฝch repozitรกลรญch k dispozici.
+settings.archive.tagsettings_unavailable=Nastavenรญ znaฤek nejsou v archivovanรฝch repozitรกลรญch k dispozici.
settings.unarchive.button=Zruลกit archivaci repozitรกลe
settings.unarchive.header=Obnovit tento repozitรกล
-settings.unarchive.text=Obnovenรญ repozitรกลe vrรกtรญ moลพnost pลijรญmรกnรญ commitลฏ a nahrรกvรกnรญ. Stejnฤ tak se obnovรญ i moลพnost vytvรกลenรญ novรฝch problรฉmลฏ a ลพรกdostรญ o slouฤenรญ.
+settings.unarchive.text=Obnovenรญ repozitรกลe vrรกtรญ moลพnost pลijรญmรกnรญ revizรญ a nahrรกvรกnรญ. Stejnฤ tak se obnovรญ i moลพnost vytvรกลenรญ novรฝch problรฉmลฏ a ลพรกdostรญ o slouฤenรญ.
settings.unarchive.success=Repozitรกล byl รบspฤลกnฤ obnoven.
settings.unarchive.error=Nastala chyba pลi obnovovรกnรญ repozitรกลe. Prohlรฉdnฤte si zรกznam pro vรญce detailลฏ.
settings.update_avatar_success=Avatar repozitรกลe byl aktualizovรกn.
settings.lfs=LFS
-settings.lfs_filelist=LFS soubory uloลพenรฉ v tomto repozitรกลi
-settings.lfs_no_lfs_files=V tomto repozitรกลi nejsou uloลพeny ลพรกdnรฉ LFS soubory
+settings.lfs_filelist=Soubory LFS uloลพenรฉ v tomto repozitรกลi
+settings.lfs_no_lfs_files=V tomto repozitรกลi nejsou uloลพeny ลพรกdnรฉ soubory LFS
settings.lfs_findcommits=Najรญt revize
-settings.lfs_lfs_file_no_commits=Pro tento soubor LFS nebyly nalezeny ลพรกdnรฉ commity
+settings.lfs_lfs_file_no_commits=Pro tento soubor LFS nebyly nalezeny ลพรกdnรฉ revize
settings.lfs_noattribute=Tato cesta nemรก uzamykatelnรฝ atribut ve vรฝchozรญ vฤtvi
settings.lfs_delete=Odstranit LFS soubor s OID %s
settings.lfs_delete_warning=Odstranฤnรญ souboru LFS mลฏลพe pลi kontrole zpลฏsobit chybu โobjekt neexistujeโ. Jste si jisti?
@@ -2472,7 +2548,7 @@ settings.lfs_invalid_locking_path=Neplatnรก cesta: %s
settings.lfs_invalid_lock_directory=Adresรกล nelze uzamknout: %s
settings.lfs_lock_already_exists=Zรกmek jiลพ existuje: %s
settings.lfs_lock=Zรกmek
-settings.lfs_lock_path=Umรญstฤnรญ souboru k zamฤenรญ...
+settings.lfs_lock_path=Umรญstฤnรญ souboru k zamฤenรญโฆ
settings.lfs_locks_no_locks=ลฝรกdnรฉ zรกmky
settings.lfs_lock_file_no_exist=Uzamฤenรฝ soubor neexistuje ve vรฝchozรญ vฤtvi
settings.lfs_force_unlock=Vynutit odemknutรญ
@@ -2506,7 +2582,7 @@ diff.whitespace_show_everything=Zobrazit vลกechny zmฤny
diff.whitespace_ignore_all_whitespace=Ignorovat bรญlรฉ znaky pลi porovnรกvรกnรญ ลรกdkลฏ
diff.whitespace_ignore_amount_changes=Ignorovat zmฤny v mnoลพstvรญ bรญlรฝch znakลฏ
diff.whitespace_ignore_at_eol=Ignorovat zmฤny v bรญlรฝch znacรญch na konci ลรญdku
-diff.stats_desc= %d zmฤnil soubory , kde provedl %d pลidรกnรญ a %d odebrรกnรญ
+diff.stats_desc= %d zmฤnฤnรฝch souborลฏ , kde bylo provedeno %d pลidรกnรญ a %d odebrรกnรญ
diff.stats_desc_file=%d zmฤn: %d pลidรกnรญ a %d smazรกnรญ
diff.bin=binรกrnรญ
diff.bin_not_shown=Binรกrnรญ soubor nebyl zobrazen.
@@ -2525,7 +2601,7 @@ diff.generated=vygenerovรกno
diff.vendored=vendorovรกno
diff.comment.add_line_comment=Pลidat jednoลรกdkovรฝ komentรกล
diff.comment.placeholder=Zanechat komentรกล
-diff.comment.markdown_info=Je podporovรกna รบprava vzhledu pomocรญ markdown.
+diff.comment.markdown_info=Je podporovรกno stylovรกnรญ pomocรญ Markdown.
diff.comment.add_single_comment=Pลidat jeden komentรกล
diff.comment.add_review_comment=Pลidat komentรกล
diff.comment.start_review=Zaฤรญt posuzovรกnรญ
@@ -2533,12 +2609,12 @@ diff.comment.reply=Odpovฤdฤt
diff.review=Dokonฤit posouzenรญ
diff.review.header=Odeslat posouzenรญ
diff.review.placeholder=Posoudit komentรกล
-diff.review.comment=Okomentovat
+diff.review.comment=Komentovat
diff.review.approve=Schvรกlit
diff.review.self_reject=Autoลi poลพadavkลฏ na nataลพenรญ nemohou poลพadovat zmฤny na svรฉm vlastnรญm poลพadavku na nataลพenรญ
diff.review.reject=Poลพadovat zmฤny
diff.review.self_approve=Autoลi poลพadavku na nataลพenรญ nemohou schvรกlit svลฏj vlastnรญ poลพadavek na nataลพenรญ
-diff.committed_by=odevzdal
+diff.committed_by=autor:
diff.protected=Chrรกnฤno
diff.image.side_by_side=Vedle sebe
diff.image.swipe=Posunout
@@ -2549,14 +2625,14 @@ diff.hide_file_tree=Skrรฝt souborovรฝ strom
releases.desc=Sledovรกnรญ verzรญ projektu a souborลฏ ke staลพenรญ.
release.releases=Vydรกnรญ
-release.detail=Podrobnosti vydรกnรญ
+release.detail=Podrobnosti o vydรกnรญ
release.tags=Znaฤky
release.new_release=Novรฉ vydรกnรญ
release.draft=Koncept
release.prerelease=Pลedbฤลพnรก verze
release.stable=Stabilnรญ
release.compare=Porovnat
-release.edit=upravit
+release.edit=Upravit
release.ahead.commits=%d revizรญ
release.ahead.target=do %s od tohoto vydรกnรญ
tag.ahead.target=do %s od tรฉto znaฤky
@@ -2580,7 +2656,7 @@ release.edit_release=Aktualizovat vydรกnรญ
release.delete_release=Smazat vydรกnรญ
release.delete_tag=Smazat znaฤku
release.deletion=Smazat vydรกnรญ
-release.deletion_desc=Smazรกnรญ vydรกnรญ jej pouze odebere z Gitea. Nebude to mรญt vliv na znaฤku Git, obsah vaลกeho repozitรกลe nebo jeho historii. Pokraฤovat?
+release.deletion_desc=Smazรกnรญm vydรกnรญ jej pouze odeberete z Forgeja. Nebude to mรญt vliv na znaฤku Gitu, obsah vaลกeho repozitรกลe nebo jeho historii. Pokraฤovat?
release.deletion_success=Vydรกnรญ bylo odstranฤno.
release.deletion_tag_desc=Odstranรญ tuto znaฤku z repozitรกลe. Obsah repozitรกลe a historie zลฏstanou nezmฤnฤny. Pokraฤovat?
release.deletion_tag_success=Znaฤka byla odstranฤna.
@@ -2603,8 +2679,8 @@ branch.delete_html=Odstranit vฤtev
branch.delete_desc=Smazรกnรญ vฤtve je trvalรฉ. Pลestoลพe zruลกenรก vฤtev mลฏลพe existovat i po krรกtkou dobu, neลพ bude skuteฤnฤ odstranฤna, NELZE ji vฤtลกinou vrรกtit. Pokraฤovat?
branch.deletion_success=Vฤtev โ%sโ byla smazรกna.
branch.deletion_failed=Nepodaลilo se odstranit vฤtev โ%sโ.
-branch.delete_branch_has_new_commits=Vฤtev โ%sโ nemลฏลพe bรฝt smazรกna, protoลพe byly pลidรกny novรฉ commity po slouฤenรญ.
-branch.create_branch=Vytvoลit vฤtev %s
+branch.delete_branch_has_new_commits=Vฤtev โ%sโ nelze odstranit, protoลพe byly po slouฤenรญ pลidรกny novรฉ revize.
+branch.create_branch=Vytvoลit vฤtev %s
branch.create_from=z โ%sโ
branch.create_success=Vฤtev โ%sโ byla vytvoลena.
branch.branch_already_exists=Vฤtev โ%sโ jiลพ existuje v tomto repozitรกลi.
@@ -2631,7 +2707,7 @@ branch.new_branch=Vytvoลit novou vฤtev
branch.new_branch_from=Vytvoลit novou vฤtev z โ%sโ
branch.renamed=Vฤtev %s byla pลejmenovรกna na %s.
-tag.create_tag=Vytvoลit znaฤku %s
+tag.create_tag=Vytvoลit znaฤku %s
tag.create_tag_operation=Vytvoลit znaฤku
tag.confirm_create_tag=Vytvoลit znaฤku
tag.create_tag_from=Vytvoลit novou znaฤku z โ%sโ
@@ -2643,66 +2719,53 @@ topic.done=Hotovo
topic.count_prompt=Nelze vybrat vรญce neลพ 25 tรฉmat
topic.format_prompt=Tรฉma musรญ zaฤรญnat pรญsmenem nebo ฤรญslem, mลฏลพe obsahovat pomlฤky (โ-โ) a teฤky (โ.โ) a mลฏลพe bรฝt dlouhรฉ aลพ 35 znakลฏ. Pรญsmena musรญ bรฝt malรก.
-find_file.go_to_file=Pลejรญt na soubor
+find_file.go_to_file=Najรญt soubor
find_file.no_matching=Nebyl nalezen ลพรกdnรฝ odpovรญdajรญcรญ soubor
error.csv.too_large=Tento soubor nelze vykreslit, protoลพe je pลรญliลก velkรฝ.
error.csv.unexpected=Tento soubor nelze vykreslit, protoลพe obsahuje neoฤekรกvanรฝ znak na ลรกdku %d ve sloupci %d.
error.csv.invalid_field_count=Soubor nelze vykreslit, protoลพe mรก nesprรกvnรฝ poฤet polรญ na ลรกdku %d.
pulls.made_using_agit = AGit
-settings.confirm_wiki_branch_rename = Pลejmenovat vฤtev Wiki
-issues.comment.blocked_by_user = U tohoto problรฉmu nemลฏลพete vytvoลit komentรกล, protoลพe jste byl/a zablokovรกn/a majitelem repozitรกลe nebo autorem problรฉmu.
-contributors.contribution_type.filter_label = Typ pลispฤnรญ:
+settings.confirm_wiki_branch_rename = Pลejmenovat vฤtev wiki
+issues.comment.blocked_by_user = Tento problรฉm nemลฏลพete okomentovat, protoลพe jste byli zablokovรกni majitelem repozitรกลe nebo autorem problรฉmu.
contributors.contribution_type.additions = Pลidรกnรญ
admin.manage_flags = Spravovat vlajky
admin.enabled_flags = Vlajky povolenรฉ v repozitรกลi:
admin.update_flags = Upravit vlajky
admin.failed_to_replace_flags = Nepodaลilo se nahradit vlajky repozitรกลe
admin.flags_replaced = Vlajky repozitรกลe nahrazeny
-desc.sha256 = SHA256
-issues.label_exclusive_warning = Pลi รบpravฤ ลกtรญtkลฏ problรฉmu nebo ลพรกdosti o slouฤenรญ budou odstranฤny vลกechny konfliktnรญ ลกtรญtky.
pulls.cmd_instruction_checkout_title = Kontrola
settings.mirror_settings.docs.disabled_push_mirror.info = Push zrcadla byla zakรกzรกna administrรกtorem vaลกeho webu.
-generated = Generovรกno
clone_in_vscodium = Klonovat do VSCodium
settings.wiki_rename_branch_main_notices_1 = Tato operace je NEVRATNร .
-settings.wiki_branch_rename_success = Nรกzev vฤtve Wiki repozitรกลe byl รบspฤลกnฤ normalizovรกn.
-object_format = Objektovรฝ formรกt
+settings.wiki_branch_rename_success = Nรกzev vฤtve wiki repozitรกลe byl รบspฤลกnฤ normalizovรกn.
rss.must_be_on_branch = Abyste mohli mรญt zdroj RSS, musรญte se nachรกzet ve vฤtvi.
-object_format_helper = Objektovรฝ formรกt repozitรกลe. Pozdฤji jej nelze zmฤnit. Nejkompatibilnฤjลกรญ je SHA1.
-issues.blocked_by_user = V tomto repozitรกลi nemลฏลพete vytvoลit problรฉm, protoลพe jste byl/a jeho majitelem zablokovรกn/a.
+issues.blocked_by_user = V tomto repozitรกลi nemลฏลพete vytvรกลet problรฉmy, protoลพe jste byl/a jeho majitelem zablokovรกn/a.
migrate.forgejo.description = Migrovat data z codeberg.org nebo jinรฝch instancรญ Forgejo.
mirror_sync = synchronizovรกno
blame.ignore_revs = Ignorovรกnรญ revizรญ v souboru .git-blame-ignore-revs . Kliknฤte sem pro udฤlenรญ vรฝjimky a zobrazenรญ normรกlnรญho pลehledu blame.
commits.browse_further = Prochรกzet dรกle
issues.role.first_time_contributor = Prvnรญ pลispฤvatel
-vendored = Vendorovรกno
-editor.invalid_commit_mail = Neplatnรฝ e-mail pro vytvoลenรญ commitu.
+editor.invalid_commit_mail = Neplatnรฝ e-mail pro vytvoลenรญ revize.
commits.renamed_from = Pลejmenovรกno z %s
-issues.label_exclusive_desc = Pojmenujte ลกtรญtek scope/item
, aby se vzรกjemnฤ vyluฤoval s ostatnรญmi ลกtรญtky scope/
.
-issues.label_archive_tooltip = ล tรญtek Archivovรกno jsou ve vรฝchozรญm nastavenรญ vylouฤeny z nรกvrhลฏ pลi vyhledรกvรกnรญ podle ลกtรญtkลฏ.
-issues.label_archive = ล tรญtek archivu
-milestones.new_subheader = Milnรญky vรกm pomohou zorganizovat problรฉmy a sledovat jejich pokrok.
-pulls.nothing_to_compare_have_tag = Vybranรก vฤtev a znaฤka jsou shodnรฉ.
-activity.navbar.recent_commits = Nedรกvnรฉ commity
-settings.units.units = Jednotky repozitรกลe
+activity.navbar.recent_commits = Nedรกvnรฉ revize
+settings.units.units = Jednotky
pulls.blocked_by_user = V tomto repozitรกลi nemลฏลพete vytvoลit ลพรกdost o slouฤenรญ, protoลพe jste byli zablokovรกni jeho majitelem.
-pulls.clear_merge_message_hint = Vymazรกnรญm zprรกvy o slouฤenรญ pouze odstranรญte obsah zprรกvy commitu a ponechรกte vygenerovanรฉ git trailery, jako โCo-Authored-By โฆโ.
+pulls.clear_merge_message_hint = Vymazรกnรญm zprรกvy o slouฤenรญ pouze odstranรญte obsah zprรกvy revize a ponechรกte vygenerovanรฉ git trailery, jako โCo-Authored-By โฆโ.
pulls.agit_explanation = Vytvoลeno pomocรญ workflow AGit. AGit umoลพลuje pลispฤvatelลฏm navrhovat zmฤny pomocรญ โgit pushโ bez vytvรกลenรญ forku nebo novรฉ vฤtve.
contributors.contribution_type.deletions = Odstranฤnรญ
settings.pull_mirror_sync_in_progress = Probรญhรก naฤรญtรกnรญ zmฤn ze vzdรกlenรฉho %s.
-settings.enter_repo_name = Zadejte majitele a repozitรกล pลesnฤ tak, jak je vidรญte nรญลพe:
+settings.enter_repo_name = Zadejte jmรฉno majitele a repozitรกลe pลesnฤ tak, jak je vidรญte:
settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning = Tuto akci lze v souฤasnรฉ chvรญli provรฉst pouze v nabรญdce โNovรก migraceโ. Pro vรญce informacรญ viz:
settings.new_owner_blocked_doer = Novรฝ majitel vรกs zablokoval.
-settings.mirror_settings.pushed_repository = Pushnutรฝ repozitรกล
+settings.mirror_settings.pushed_repository = Odeslanรฝ repozitรกล
settings.add_collaborator_blocked_our = Nepodaลilo se pลidat spolupracovnรญka, jelikoลพ byl zablokovรกn majitelem repozitรกลe.
-pulls.commit_ref_at = `se odkรกzal na tuto ลพรกdost o slouฤenรญ z commitu %[2]s `
-settings.wiki_rename_branch_main = Normalizovat nรกzev vฤtve Wiki
-settings.wiki_rename_branch_main_desc = Pลejmenovat vฤtev internฤ pouลพรญvanou pro Wiki na โ%sโ. Tato zmฤna je trvalรก a nelze ji vrรกtit.
+pulls.commit_ref_at = `se odkรกzal/a na tuto ลพรกdost o slouฤenรญ z revize %[2]s `
+settings.wiki_rename_branch_main = Normalizovat nรกzev vฤtve wiki
+settings.wiki_rename_branch_main_desc = Pลejmenovat vฤtev internฤ pouลพรญvanou pro wiki na โ%sโ. Tato zmฤna je trvalรก a nelze ji vrรกtit.
pulls.fast_forward_only_merge_pull_request = Pouze zrychlenรฉ
pulls.reopen_failed.head_branch = Tuto ลพรกdost o slouฤenรญ nelze znovu otevลรญt, protoลพe hlavnรญ vฤtev jiลพ neexistuje.
pulls.reopen_failed.base_branch = Tuto ลพรกdost o slouฤenรญ nelze znovu otevลรญt, protoลพe zรกkladnรญ vฤtev jiลพ neexistuje.
-issues.dependency.issue_batch_close_blocked = Nepodaลilo se hromadnฤ zavลรญt vybranรฉ problรฉmy, protoลพe problรฉm #%d mรก stรกle otevลenรฉ zรกvislosti
pulls.recently_pushed_new_branches = Pushnuli jste do vฤtve %[1]s %[2]s
wiki.cancel = Zruลกit
activity.navbar.pulse = Pulz
@@ -2711,35 +2774,34 @@ activity.navbar.contributors = Pลispฤvatelรฉ
settings.mirror_settings.docs.pull_mirror_instructions = Pro nastavenรญ pull zrcadla viz:
settings.mirror_settings.docs.doc_link_pull_section = sekci โPulling from a remote repositoryโ v dokumentaci.
settings.units.overview = Pลehled
-settings.units.add_more = Pลidat dalลกรญ...
+settings.units.add_more = Povolit dalลกรญ
settings.push_mirror_sync_in_progress = Probรญhรก odesรญlรกnรญ zmฤn na vzdรกlenรฝ %s.
settings.wiki_globally_editable = Umoลพnit komukoli editovat wiki
-settings.confirmation_string = Potvrzovacรญ ลetฤzec
+settings.confirmation_string = Potvrzenรญ
settings.wiki_rename_branch_main_notices_2 = Touto akcรญ trvale pลejmenujete internรญ vฤtev wiki repozitรกลe %s. Existujรญcรญ kontroly budou muset bรฝt aktualizovรกny.
-settings.wiki_branch_rename_failure = Nepodaลilo se normalizovat nรกzev vฤtve Wiki repozitรกลe.
+settings.wiki_branch_rename_failure = Nepodaลilo se normalizovat nรกzev vฤtve wiki repozitรกลe.
settings.add_collaborator_blocked_them = Nepodaลilo se pลidat spolupracovnรญka, jelikoลพ mรก zablokovanรฉho majitele repozitรกลe.
settings.ignore_stale_approvals = Ignorovat zastaralรก schvรกlenรญ
settings.event_pull_request_merge = Slouฤenรญ ลพรกdosti o slouฤenรญ
settings.event_pull_request_approvals = Schvรกlenรญ ลพรกdostรญ o slouฤenรญ
-settings.ignore_stale_approvals_desc = Nepoฤรญtat schvรกlenรญ udฤlenรก u starลกรญch commitลฏ (zastaralรก schvรกlenรญ) do celkovรฉho poฤtu schvรกlenรญ u ลฝS. Nenรญ relevantnรญ, pokud byla zastaralรก schvรกlenรญ jiลพ zruลกena.
+settings.ignore_stale_approvals_desc = Nepoฤรญtat schvรกlenรญ udฤlenรก u starลกรญch revizรญ (zastaralรก schvรกlenรญ) do celkovรฉho poฤtu schvรกlenรญ u ลพรกdosti o slouฤenรญ. Nenรญ relevantnรญ, pokud byla zastaralรก schvรกlenรญ jiลพ zruลกena.
file_follow = Nรกsledovat symbolickรฝ odkaz
settings.protect_status_check_patterns_desc = Zadejte vzorce pro upลesnฤnรญ kontrol, kterรฉ musรญ projรญt pลed slouฤenรญm vฤtvรญ do vฤtve, kterรก se shoduje s tรญmto pravidlem. Na kaลพdรฝ ลรกdek zadejte jeden vzorec. Vzorce nesmรญ bรฝt prรกzdnรฉ.
-settings.archive.mirrors_unavailable = Zrcadla nejsou dostupnรก, kdyลพ je repozitรกล archivovรกn.
+settings.archive.mirrors_unavailable = Zrcadla nejsou v archivovanรฝch repozitรกลรญch k dispozici.
settings.protect_enable_merge_desc = Kdokoli s pลรญstupem k zรกpisu bude moci sluฤovat ลพรกdosti o slouฤenรญ do tรฉto vฤtve.
-settings.archive.text = Archivovรกnรญm repozitรกลe jej celรฝ pลevedete do stavu pouze pro ฤtenรญ. Bude skryt z nรกstฤnky. Nikdo (ani vy!) nebude moci vytvรกลet novรฉ commity ani otevรญrat problรฉmy a ลพรกdosti o slouฤenรญ.
settings.event_pull_request_review_request_desc = Bylo poลพรกdรกno o posouzenรญ ลพรกdosti o slouฤenรญ nebo bylo toto poลพรกdรกnรญ odstranฤno.
-error.broken_git_hook = Zdรก se, ลพe u tohoto repozitรกลe jsou rozbitรฉ Git hooks. Pro jejich opravenรญ se prosรญm ลiฤte pokyny v dokumentaci a potรฉ odeลกlete nฤkolik commitลฏ pro obnovenรญ stavu.
-pulls.title_desc_one = ลพรกdรก o slouฤenรญ %[1]d commitu z %[2]s
do %[3]s
+error.broken_git_hook = Zdรก se, ลพe u tohoto repozitรกลe jsou rozbitรฉ Git webhooky. Pro jejich opravenรญ se prosรญm ลiฤte pokyny v dokumentaci a potรฉ odeลกlete pรกr revizรญ pro obnovenรญ stavu.
+pulls.title_desc_one = ลพรกdรก o slouฤenรญ %[1]d commitu z %[2]s
do %[3]s
pulls.merged_title_desc_one = slouฤil %[1]d commit z %[2]s
do %[3]s
%[4]s
open_with_editor = Otevลรญt pomocรญ %s
commits.search_branch = Tato vฤtev
-editor.commit_id_not_matching = Tento soubor se bฤhem รบpravy zmฤnil. Proveฤte commit do novรฉ vฤtve a potรฉ je sluฤte.
+editor.commit_id_not_matching = Tento soubor se bฤhem รบpravy zmฤnil. Odeลกlete zmฤny do novรฉ vฤtve a potรฉ je sluฤte.
pulls.ready_for_review = Pลipraveni na posouzenรญ?
settings.rename_branch_failed_protected = Nepodaลilo se pลejmenovat vฤtev %s, jelikoลพ se jednรก o chrรกnฤnou vฤtev.
editor.push_out_of_date = Push je nejspรญลกe zastaralรฝ.
stars = Oblรญbenรญ
-n_commit_one = %s commit
-n_commit_few = %s commitลฏ
+n_commit_one = %s revize
+n_commit_few = %s revizรญ
n_branch_one = %s vฤtev
n_tag_one = %s znaฤka
n_tag_few = %s znaฤek
@@ -2750,8 +2812,8 @@ settings.enforce_on_admins_desc = Sprรกvci repozitรกลe nemohou obejรญt toto pra
issues.num_participants_one = %d รบฤastnรญk
size_format = %[1]s: %[2]s, %[3]s: %[4]s
issues.archived_label_description = (Archivovรกn) %s
-release.download_count_one = %d staลพenรญ
-release.download_count_few = %d staลพenรญ
+release.download_count_one = %s staลพenรญ
+release.download_count_few = %s staลพenรญ
release.system_generated = Tato pลรญloha byla automaticky vygenerovรกna.
settings.add_webhook.invalid_path = Cesta nesmรญ obsahovat ฤรกst, kterรก je โ.โ nebo โ..โ nebo prรกzdnรฝ ลetฤzec. Nesmรญ zaฤรญnat ani konฤit lomรญtkem.
settings.web_hook_name_sourcehut_builds = Sestavenรญ SourceHut
@@ -2783,14 +2845,80 @@ pulls.edit.already_changed = Nepodaลilo se uloลพit zmฤny v ลพรกdosti o slouฤe
comments.edit.already_changed = Nepodaลilo se uloลพit zmฤny v komentรกลi. Obsah byl nejspรญลกe jiลพ zmฤnฤn jinรฝm uลพivatelem. Obnovte prosรญm strรกnku a zkuste jej znovu upravit, abyste zabrรกnili pลepsรกnรญ zmฤn uลพivatele
subscribe.issue.guest.tooltip = Pลihlaste se pro odebรญrรกnรญ tohoto problรฉmu.
subscribe.pull.guest.tooltip = Pลihlaste se pro odebรญrรกnรญ tรฉto ลพรกdosti o slouฤenรญ.
+issues.author.tooltip.pr = Tento uลพivatel je autorem tรฉto ลพรกdosti o slouฤenรญ.
+issues.author.tooltip.issue = Tento uลพivatel je autorem tohoto problรฉmu.
+activity.commit = Aktivita revizรญ
+milestones.filter_sort.name = Nรกzev
+release.type_attachment = Pลรญloha
+release.type_external_asset = Externรญ pลรญloha
+release.asset_external_url = Externรญ URL
+release.add_external_asset = Pลidat externรญ pลรญlohu
+activity.published_prerelease_label = Pลedbฤลพnรฉ vydรกnรญ
+activity.published_tag_label = ล tรญtek
+settings.pull_mirror_sync_quota_exceeded = Kvรณta pลekroฤena, nestahuji zmฤny.
+settings.transfer_quota_exceeded = Novรฝ majitel (%s) pลekroฤil kvรณtu. Repozitรกล nebyl pลeveden.
+release.asset_name = Nรกzev pลรญlohy
+release.invalid_external_url = Neplatnรก externรญ adresa URL: โ%sโ
+no_eol.text = ลฝรกdnรฝ EOL
+no_eol.tooltip = Tento soubor neobsahuje koncovรฝ znak ukonฤenรญ ลรกdku.
+pulls.cmd_instruction_merge_warning = Varovรกnรญ: Nastavenรญ โAutodetekce ruฤnรญho slouฤenรญโ nenรญ u tohoto repozitรกลe povoleno, tuto ลพรกdost o slouฤenรญ budete muset potรฉ oznaฤit jako ruฤnฤ slouฤenou.
+settings.protect_new_rule = Vytvoลit novรฉ pravidlo ochrany vฤtvรญ
+mirror_use_ssh.helper = Pokud zvolรญte tuto moลพnost, Forgejo bude zrcadlit repozitรกล pomocรญ Gitu pลes SSH a vytvoลรญ pro vรกs pรกr klรญฤลฏ. Musรญte zajistit, aby byl vygenerovanรฝ veลejnรฝ klรญฤ autorizovรกn k odeslรกnรญ do cรญlovรฉho repozitรกลe. Pลi vรฝbฤru tรฉto moลพnosti nelze pouลพรญt autorizaci zaloลพenou na hesle.
+settings.mirror_settings.push_mirror.copy_public_key = Kopรญrovat veลejnรฝ klรญฤ
+mirror_use_ssh.text = Pouลพรญt ovฤลovรกnรญ SSH
+mirror_denied_combination = Nelze pouลพรญt kombinaci ovฤลovรกnรญ pomocรญ veลejnรฉho klรญฤe a hesla.
+mirror_public_key = Veลejnรฝ klรญฤ SSH
+settings.mirror_settings.push_mirror.none_ssh = ลฝรกdnรฉ
+mirror_use_ssh.not_available = Ovฤลovรกnรญ SSH nenรญ dostupnรฉ.
+issues.new.assign_to_me = Pลiลadit mnฤ
+issues.all_title = Vลกe
+settings.discord_icon_url.exceeds_max_length = Adresa URL ikony musรญ mรญt mรฉnฤ neลพ 2048 znakลฏ
+issues.review.add_review_requests = poลพรกdal/a o kontroly od %[1]s %[2]s
+issues.review.remove_review_requests = odstranil/a ลพรกdosti o kontrolu u %[1]s %[2]s
+issues.review.add_remove_review_requests = poลพรกdal/a o kontroly od %[1]s a odstranil/a ลพรกdosti u %[2]s %[3]s
+pulls.delete_after_merge.head_branch.is_default = Vฤtev hlavy, kterou chcete odstranit, je vรฝchozรญ vฤtvรญ a nelze ji odstranit.
+pulls.delete_after_merge.head_branch.is_protected = Vฤtev hlavy, kterou chcete odstranit, je chrรกnฤnou vฤtvรญ a nelze ji odstranit.
+pulls.delete_after_merge.head_branch.insufficient_branch = Nemรกte oprรกvnฤnรญ k odstranฤnรญ vฤtve hlavy.
+issues.filter_sort.relevance = Relevance
+diff.git-notes.add = Pลidat poznรกmku
+diff.git-notes.remove-header = Odstranit poznรกmku
+diff.git-notes.remove-body = Tato poznรกmka bude odebrรกna.
+issues.num_reviews_one = %d kontrola
+issues.num_reviews_few = %d kontrol
+issues.summary_card_alt = Souhrn problรฉmu s nรกzvem โ%sโ v repozitรกลi %s
+editor.add_tmpl.filename = nazevsouboru
+settings.default_update_style_desc = Vรฝchozรญ zpลฏsob aktualizacรญ pouลพรญvanรฝ pro aktualizace ลพรกdostรญ o slouฤenรญ, kterรฉ jsou pozadu oproti zรกkladnรญ vฤtvi.
+pulls.sign_in_require = Pลihlaste se pro vytvoลenรญ novรฉ ลพรกdosti o slouฤenรญ.
+new_from_template = Pouลพรญt ลกablonu
+new_from_template_description = Mลฏลพete si vybrat existujรญcรญ ลกablonu repozitรกลe na tรฉto instanci a pouลพรญt jejรญ nastavenรญ.
+new_advanced = Pokroฤilรก nastavenรญ
+new_advanced_expand = Kliknฤte pro rozbalenรญ
+auto_init_description = Vytvoลit historii Gitu se souborem README a volitelnฤ pลidat soubory License a .gitignore.
+summary_card_alt = Karta se souhrnem repozitรกลe %s
+issues.reaction.alt_many = Uลพivatel %[1]s a %[2]d dalลกรญch zareagovali s %[3]s.
+release.summary_card_alt = Karta souhrnu vydรกnรญ s nรกzvem โ%sโ v repozitรกลi %s
+issues.reaction.add = Pลidat reakci
+issues.reaction.alt_few = Uลพivatel %[1]s zareagoval pomocรญ %[2]s.
+issues.context.menu = Nabรญdka komentรกลe
+issues.reaction.alt_remove = Odstranit %[1]s reakci z komentรกลe.
+issues.reaction.alt_add = Pลidat %[1]s reakci na komentรกล.
+archive.pull.noreview = Tento repozitรกล je archivovรกn. Nemลฏลพete kontrolovat ลพรกdosti o slouฤenรญ.
+editor.commit_email = E-mail revize
+commits.view_single_diff = Zobrazit zmฤny tohoto souboru provedenรฉ v tรฉto revizi
+pulls.editable = Upravitelnรฉ
+pulls.editable_explanation = Tato ลพรกdost o slouฤenรญ umoลพลuje รบpravy sprรกvci. Mลฏลพete pลispฤt pลรญmo do nรญ.
+issues.reopen.blocked_by_user = Tento problรฉm nemลฏลพete znovu otevลรญt, protoลพe jste byli zablokovรกni majitelem repozitรกลe nebo autorem tohoto problรฉmu.
+pulls.comment.blocked_by_user = Tuto ลพรกdost o slouฤenรญ nemลฏลพete okomentovat, protoลพe jste byli zablokovรกni majitelem repozitรกลe nebo autorem ลพรกdosti.
+issues.filter_no_results_placeholder = Zkuste upravit filtry vyhledรกvรกnรญ.
+issues.filter_no_results = ลฝรกdnรฉ vรฝsledky
[graphs]
component_loading_info = Tohle mลฏลพe chvรญli trvatโฆ
component_failed_to_load = Doลกlo k neoฤekรกvanรฉ chybฤ.
code_frequency.what = frekvence kรณdu
contributors.what = pลรญspฤvky
-recent_commits.what = nedรกvnรฉ commity
-component_loading = Naฤรญtรกnรญ %s...
+recent_commits.what = nedรกvnรฉ revize
+component_loading = Naฤรญtรกm %sโฆ
component_loading_failed = Nepodaลilo se naฤรญst %s
[org]
@@ -2827,10 +2955,10 @@ settings.email=Kontaktnรญ e-mail
settings.website=Webovรฉ strรกnky
settings.location=Umรญstฤnรญ
settings.permission=Oprรกvnฤnรญ
-settings.repoadminchangeteam=Sprรกvce รบloลพiลกลฅ mลฏลพe tรฝmลฏm pลidรกvat a odebรญrat pลรญstup
+settings.repoadminchangeteam=Sprรกvce repozitรกลลฏ mลฏลพe tรฝmลฏm pลidรกvat a odebรญrat pลรญstup
settings.visibility=Viditelnost
settings.visibility.public=Veลejnรก
-settings.visibility.limited=Omezenรก (viditelnรฉ pouze pro ovฤลenรฉ uลพivatele)
+settings.visibility.limited=Omezenรก (viditelnรฉ pouze pro pลihlรกลกenรฉ uลพivatele)
settings.visibility.limited_shortname=Omezenรฝ
settings.visibility.private=Soukromรก (viditelnรฉ jen ฤlenลฏm organizace)
settings.visibility.private_shortname=Soukromรฝ
@@ -2846,7 +2974,7 @@ settings.delete_prompt=Organizace bude trvale odstranฤna. Tato zmฤna N
settings.confirm_delete_account=Potvrdit odstranฤnรญ
settings.delete_org_title=Odstranit organizaci
settings.delete_org_desc=Tato organizace bude trvale smazรกna. Pokraฤovat?
-settings.hooks_desc=Pลidat webovรฉ hรกฤky, kterรฉ budou spouลกtฤny pro vลกechny repozitรกลe v tรฉto organizaci.
+settings.hooks_desc=Pลidat webhooky, kterรฉ budou spouลกtฤny pro vลกechny repozitรกลe v tรฉto organizaci.
settings.labels_desc=Pลidejte ลกtรญtky, kterรฉ mohou bรฝt pouลพity pro problรฉmy vลกech repozitรกลลฏ v rรกmci tรฉto organizace.
@@ -2861,18 +2989,18 @@ members.member=ฤlen
members.remove=Smazat
members.remove.detail=Odstranit %[1]s z %[2]s?
members.leave=Opustit
-members.leave.detail=Opustit %s?
+members.leave.detail=Opravdu chcete opustit organizaci โ%sโ?
members.invite_desc=Pลidat novรฉho ฤlena do %s:
members.invite_now=Pozvat teฤ
teams.join=Pลipojit
teams.leave=Opustit
-teams.leave.detail=Opustit %s?
+teams.leave.detail=Opravdu chcete opustit tรฝm โ%sโ?
teams.can_create_org_repo=Vytvoลit repozitรกลe
teams.can_create_org_repo_helper=ฤlenovรฉ mohou vytvรกลet novรฉ repozitรกลe v organizaci. Tvลฏrce zรญskรก pลรญstup sprรกvce do novรฉho repozitรกลe.
teams.none_access=Bez pลรญstupu
-teams.none_access_helper=ฤlenovรฉ nemohou prohlรญลพet ani dฤlat ลพรกdnou jinou akci pro tuto jednotku.
-teams.general_access=Obecnรฝ pลรญstup
+teams.none_access_helper=Moลพnost โลพรกdnรฝ pลรญstupโ mรก vliv pouze na soukromรฉ repozitรกลe.
+teams.general_access=Vlastnรญ pลรญstup
teams.general_access_helper=O oprรกvnฤnรญ ฤlenลฏ bude rozhodnuto nรญลพe uvedenou tabulkou oprรกvnฤnรญ.
teams.read_access=ฤtenรญ
teams.read_access_helper=ฤlenovรฉ mohou zobrazit a klonovat repozitรกลe tรฝmu.
@@ -2894,7 +3022,7 @@ teams.delete_team_desc=Smazรกnรญ tรฝmu zruลกรญ pลรญstup jeho ฤlenลฏm. Pokraฤo
teams.delete_team_success=Tรฝm byl odstranฤn.
teams.read_permission_desc=ฤlenstvรญ v tom tรฝmu poskytuje prรกvo ฤtenรญ : ฤlenovรฉ mohou ฤรญst z a vytvรกลet klony repozitรกลลฏ tรฝmu.
teams.write_permission_desc=ฤlenstvรญ v tom tรฝmu poskytuje prรกvo zรกpisu : ฤlenovรฉ mohou ฤรญst z a nahrรกvat do repozitรกลลฏ tรฝmu.
-teams.admin_permission_desc=ฤlenstvรญ v tom tรฝmu poskytuje prรกvo sprรกvce : ฤlenovรฉ mohou ฤรญst z, nahrรกvat do a pลidรกvat spolupracovnรญky do repozitรกลลฏ tรฝmu.
+teams.admin_permission_desc=Tento tรฝm poskytuje pลรญstup Sprรกvce : ฤlenovรฉ mohou ฤรญst, nahrรกvat a pลidรกvat spolupracovnรญky do repozitรกลลฏ tรฝmu.
teams.create_repo_permission_desc=Navรญc tento tรฝm udฤluje oprรกvnฤnรญ vytvoลit repozitรกล : ฤlenovรฉ mohou vytvรกลet novรฉ repozitรกลe v organizaci.
teams.repositories=Repozitรกลe tรฝmu
teams.search_repo_placeholder=Hledat repozitรกลโฆ
@@ -2918,6 +3046,8 @@ teams.invite.by=Pozvรกnรญ od %s
teams.invite.description=Pro pลipojenรญ k tรฝmu kliknฤte na tlaฤรญtko nรญลพe.
follow_blocked_user = Tuto organizaci nemลฏลพete sledovat, protoลพe jste v nรญ zablokovรกni.
open_dashboard = Otevลรญt nรกstฤnku
+settings.change_orgname_redirect_prompt.with_cooldown.one = Starรฝ nรกzev organizace bude dostupnรฝ ostatnรญm po %[1]d dni. Do tรฉ doby budete moci starรฉ jmรฉno znovu zรญskat.
+settings.change_orgname_redirect_prompt.with_cooldown.few = Starรฝ nรกzev organizace bude dostupnรฝ ostatnรญm po %[1]d dnech. Do tรฉ doby budete moci starรฝ nรกzev znovu zรญskat.
[admin]
dashboard=Pลehled
@@ -2925,7 +3055,7 @@ identity_access=Identita a pลรญstup
users=Uลพivatelskรฉ รบฤty
organizations=Organizace
repositories=Repozitรกลe
-hooks=Webovรฉ hรกฤky
+hooks=Webhooky
integrations=Integrace
authentication=Zdroje ovฤลenรญ
emails=Uลพivatelskรฉ e-maily
@@ -2937,7 +3067,7 @@ last_page=Poslednรญ
total=Celkem: %d
settings=Nastavenรญ sprรกvce
-dashboard.new_version_hint=Gitea %s je nynรญ k dispozici, prรกvฤ u vรกs bฤลพi %s. Podรญvej se na blogu pro vรญce informacรญ.
+dashboard.new_version_hint=Forgejo %s je nynรญ k dispozici, aktuรกlnฤ pouลพรญvรกte verzi %s. Pro vรญce informacรญ viz blog .
dashboard.statistic=Souhrn
dashboard.operations=Operace รบdrลพby
dashboard.system_status=Stav systรฉmu
@@ -2964,7 +3094,7 @@ dashboard.delete_repo_archives.started=Spuลกtฤna รบloha smazรกnรญ vลกech archiv
dashboard.delete_missing_repos=Smazat vลกechny repozitรกลe, kterรฉ nemajรญ Git soubory
dashboard.delete_missing_repos.started=Spuลกtฤna รบloha mazรกnรญ vลกech repozitรกลลฏ, kterรฉ nemajรญ Git soubory.
dashboard.delete_generated_repository_avatars=Odstranit vygenerovanรฉ avatary repozitรกลลฏ
-dashboard.sync_repo_tags=Synchronizovat znaฤky z git dat do databรกze
+dashboard.sync_repo_tags = Synchronizovat znaฤky z dat Gitu do databรกze
dashboard.update_mirrors=Upravit zrcadla
dashboard.repo_health_check=Kontrola stavu vลกech repozitรกลลฏ
dashboard.check_repo_stats=Zkontrolovat vลกechny statistiky repositรกลe
@@ -3012,15 +3142,14 @@ dashboard.delete_old_actions=Odstranit vลกechny starรฉ aktivity z databรกze
dashboard.delete_old_actions.started=Spuลกtฤno odstraลovรกnรญ vลกech starรฝch aktivit z databรกze.
dashboard.update_checker=Kontrola aktualizacรญ
dashboard.delete_old_system_notices=Odstranit vลกechna starรก systรฉmovรก upozornฤnรญ z databรกze
-dashboard.gc_lfs=รklid LFS meta objektลฏ
-dashboard.stop_zombie_tasks=Zastavit zombie รบlohy
-dashboard.stop_endless_tasks=Zastavit nekoneฤnรฉ รบlohy
-dashboard.cancel_abandoned_jobs=Zruลกit opuลกtฤnรฉ รบlohy
-dashboard.start_schedule_tasks=Spustit naplรกnovanรฉ รบlohy
+dashboard.gc_lfs = Sbรญrat garbage z LFS meta objektลฏ
+dashboard.stop_zombie_tasks=Zastavit akce zombie รบloh
+dashboard.stop_endless_tasks=Zastavit akce nekoneฤnรฝch รบloh
+dashboard.cancel_abandoned_jobs=Zruลกit akce opuลกtฤnรฝch รบloh
+dashboard.start_schedule_tasks=Spustit akce naplรกnovanรฝch รบloh
dashboard.sync_branch.started=Synchronizace vฤtvรญ spuลกtฤna
-dashboard.sync_tag.started=Synchronizace znaฤek spuลกtฤna
-dashboard.rebuild_issue_indexer=Znovu sestavit index รบkolลฏ
-
+dashboard.sync_tag.started = Synchronizace znaฤek spuลกtฤna
+dashboard.rebuild_issue_indexer = Pลestavit indexer vydรกnรญ
users.user_manage_panel=Sprรกva uลพivatelskรฝch รบฤtลฏ
users.new_account=Vytvoลit uลพivatelskรฝ รบฤet
users.name=Uลพivatelskรฉ jmรฉno
@@ -3047,10 +3176,10 @@ users.update_profile_success=Uลพivatelskรฝ รบฤet byl aktualizovรกn.
users.edit_account=Upravit uลพivatelskรฝ รบฤet
users.max_repo_creation=Maximรกlnรญ poฤet repozitรกลลฏ
users.max_repo_creation_desc=(Nastavte na -1 pro pouลพitรญ vรฝchozรญho systรฉmovรฉho limitu.)
-users.is_activated=Uลพivatelskรฝ รบฤet je aktivovรกn
-users.prohibit_login=Zakรกzat pลihlรกลกenรญ
-users.is_admin=Je sprรกvce
-users.is_restricted=Je omezenรฝ
+users.is_activated=Aktivovanรฝ รบฤet
+users.prohibit_login=Pozastavenรฝ รบฤet
+users.is_admin=รฤet sprรกvce
+users.is_restricted=Omezenรฝ รบฤet
users.allow_git_hook=Mลฏลพe vytvรกลet Git hooks
users.allow_git_hook_tooltip=Git hooks jsou spouลกtฤny jako uลพivatel operaฤnรญho systรฉmu, pod kterรฝm je spuลกtฤno Forgejo, a majรญ stejnou รบroveล pลรญstupu k hostiteli. Vรฝsledkem je, ลพe uลพivatelรฉ s tรญmto speciรกlnรญm oprรกvnฤnรญm Git hooks mohou pลistupovat ke vลกem repozitรกลลฏm Forgejo a upravovat je, stejnฤ jako databรกzi pouลพรญvanou systรฉmem Forgejo. V dลฏsledku toho mohou takรฉ zรญskat oprรกvnฤnรญ sprรกvce systรฉmu Forgejo.
users.allow_import_local=Mลฏลพe importovat lokรกlnรญ repozitรกลe
@@ -3100,7 +3229,7 @@ orgs.new_orga=Novรก organizace
repos.repo_manage_panel=Sprรกva repozitรกลลฏ
repos.unadopted=Nepลijatรฉ repozitรกลe
-repos.unadopted.no_more=Nebyly nalezeny ลพรกdnรฉ dalลกรญ nepลijatรฉ repositรกลe
+repos.unadopted.no_more=Nebyly nalezeny ลพรกdnรฉ nepลijatรฉ repositรกลe.
repos.owner=Vlastnรญk
repos.name=Nรกzev
repos.private=Soukromรฝ
@@ -3125,12 +3254,12 @@ packages.size=Velikost
packages.published=Publikovรกno
defaulthooks=Vรฝchozรญ webhooky
-defaulthooks.add_webhook=Pลidat vรฝchozรญ webovรฝ hรกฤek
-defaulthooks.update_webhook=Aktualizovat vรฝchozรญ webovรฝ hรกฤek
+defaulthooks.add_webhook=Pลidat vรฝchozรญ webhook
+defaulthooks.update_webhook=Aktualizovat vรฝchozรญ webhook
systemhooks=Systรฉmovรฉ webhooky
-systemhooks.add_webhook=Pลidat systรฉmovรฝ webovรฝ hรกฤek
-systemhooks.update_webhook=Aktualizovat systรฉmovรฝ webovรฝ hรกฤek
+systemhooks.add_webhook=Pลidat systรฉmovรฝ webhook
+systemhooks.update_webhook=Aktualizovat systรฉmovรฝ webhook
auths.auth_manage_panel=Sprรกva zdrojลฏ ovฤลovรกnรญ
auths.new=Pลidat zdroj ovฤลovรกnรญ
@@ -3222,18 +3351,18 @@ auths.tips=Tipy
auths.tips.oauth2.general=Ovฤลovรกnรญ OAuth2
auths.tips.oauth2.general.tip=Pลi registraci novรฉ OAuth2 autentizace by URL callbacku/pลesmฤrovรกnรญ mฤla bรฝt:
auths.tip.oauth2_provider=Poskytovatel OAuth2
-auths.tip.bitbucket=Vytvoลte novรฉho OAuth uลพivatele na strรกnce https://bitbucket.org/account/user//oauth-consumers/new a pลidejte oprรกvnฤnรญ โAccountโ - โReadโ
+auths.tip.bitbucket=Vytvoลte novรฉho OAuth uลพivatele na strรกnce %s a pลidejte oprรกvnฤnรญ โรฤetโ โ โฤtenรญโ
auths.tip.nextcloud=Zaregistrujte novรฉho OAuth konzumenta na vaลกรญ instanci pomocรญ nรกsledujรญcรญho menu โNastavenรญ -> Zabezpeฤenรญ -> OAuth 2.0 klientโ
-auths.tip.dropbox=Vytvoลte novou aplikaci na https://www.dropbox.com/developers/apps
-auths.tip.facebook=Registrujte novou aplikaci na https://developers.facebook.com/apps a pลidejte produkt โFacebook Loginโ
-auths.tip.github=Registrujte novou OAuth aplikaci na https://github.com/settings/applications/new
+auths.tip.dropbox=Vytvoลte novou aplikaci na %s
+auths.tip.facebook=Registrujte novou aplikaci na %s a pลidejte produkt โFacebook Loginโ
+auths.tip.github=Registrujte novou OAuth aplikaci na %s
auths.tip.gitlab=Registrujte novou aplikaci na https://gitlab.com/profile/applications
-auths.tip.google_plus=Zรญskejte klientskรฉ povฤลenรญ OAuth2 z Google API konzole na https://console.developers.google.com/
+auths.tip.google_plus=Zรญskejte klientskรฉ povฤลenรญ OAuth2 z Google API konzole na %s
auths.tip.openid_connect=Pouลพijte OpenID URL pro objevovรกnรญ spojenรญ (/.well-known/openid-configuration) k nastavenรญ koncovรฝch bodลฏ
-auths.tip.twitter=Jdฤte na https://dev.twitter.com/apps, vytvoลte aplikaci a ujistฤte se, ลพe volba โAllow this application to be used to Sign in with Twitterโ je povolenรก
-auths.tip.discord=Registrujte novou aplikaci na https://discordapp.com/developers/applications/me
-auths.tip.gitea=Registrovat novou Oauth2 aplikaci. Nรกvod naleznete na https://forgejo.org/docs/latest/user/oauth2-provider
-auths.tip.yandex=Vytvoลte novou aplikaci na https://oauth.yandex.com/client/new. Vyberte nรกsledujรญcรญ oprรกvnฤnรญ z โYandex.Passport APIโ sekce: โPลรญstup k e-mailovรฉ adreseโ, โPลรญstup k uลพivatelskรฉmu avataruโ a โPลรญstup k uลพivatelskรฉmu jmรฉnu, jmรฉnu a pลรญjmenรญ, pohlavรญโ
+auths.tip.twitter=Jdฤte na %s, vytvoลte aplikaci a ujistฤte se, ลพe volba โAllow this application to be used to Sign in with Twitterโ je povolenรก
+auths.tip.discord=Registrujte novou aplikaci na %s
+auths.tip.gitea=Registrovat novou Oauth2 aplikaci. Nรกvod naleznete na %s
+auths.tip.yandex=Vytvoลte novou aplikaci na %s. Vyberte nรกsledujรญcรญ oprรกvnฤnรญ z โYandex.Passport APIโ sekce: โPลรญstup k e-mailovรฉ adreseโ, โPลรญstup k uลพivatelskรฉmu avataruโ a โPลรญstup k uลพivatelskรฉmu jmรฉnu, jmรฉnu a pลรญjmenรญ, pohlavรญโ
auths.tip.mastodon=Vloลพte vlastnรญ URL instance pro mastodon, kterou se chcete autentizovat (nebo pouลพijte vรฝchozรญ)
auths.edit=Upravit zdroj ovฤลovรกnรญ
auths.activated=Tento zdroj ovฤลovรกnรญ je aktivovรกn
@@ -3279,7 +3408,7 @@ config.ssh_root_path=Koลenovรก cesta
config.ssh_key_test_path=Cesta testu klรญฤลฏ
config.ssh_keygen_path=Cesta ke generรกtoru klรญฤลฏ (โssh-keygenโ)
config.ssh_minimum_key_size_check=Kontrola minimรกlnรญ velikosti klรญฤลฏ
-config.ssh_minimum_key_sizes=Minimรกlnรญ velikost klรญฤลฏ
+config.ssh_minimum_key_sizes=Minimรกlnรญ velikosti klรญฤลฏ
config.lfs_config=Nastavenรญ LFS
config.lfs_enabled=Povoleno
@@ -3438,39 +3567,45 @@ notices.desc=Popis
notices.op=Akce
notices.delete_success=Systรฉmovรฉ upozornฤnรญ bylo smazรกno.
dashboard.sync_repo_branches = Synchronizovat vynechanรฉ vฤtve z dat Gitu do databรกze
-dashboard.sync_repo_tags = Synchronizovat znaฤky z dat Gitu do databรกze
-dashboard.gc_lfs = Sbรญrat garbage z LFS meta objektลฏ
monitor.queue.activeworkers = Aktivnรญ workery
-defaulthooks.desc = Webhooky automaticky vytvรกลejรญ ลพรกdosti HTTP POST na server, kde se spustรญ urฤitรฉ udรกlosti Forgejo. Webhooky zde definovanรฉ jsou vรฝchozรญ a budou zkopรญrovรกny do vลกech novรฝch repozitรกลลฏ. Vรญce informacรญ zjistรญte v nรกvodu webhookลฏ .
-systemhooks.desc = Webhooky automaticky vytvรกลejรญ ลพรกdosti HTTP POST na server, kde se spustรญ urฤitรฉ udรกlosti Forgejo. Webhooky zde definovanรฉ budou aktivnรญ u vลกech repozitรกลลฏ v systรฉmu, zvaลพte tedy prosรญm vลกechny vlivy na vรฝkon, kterรฉ mลฏลพe tato funkce zpลฏsobit. Vรญce informacรญ zjistรญte v nรกvodu webhookลฏ .
+defaulthooks.desc = Webhooky automaticky vytvรกลejรญ ลพรกdosti HTTP POST na server, kde se spustรญ urฤitรฉ udรกlosti Forgejo. Webhooky zde definovanรฉ jsou vรฝchozรญ a budou zkopรญrovรกny do vลกech novรฝch repozitรกลลฏ. Vรญce informacรญ zjistรญte v nรกvodu webhookลฏ .
+systemhooks.desc = Webhooky automaticky vytvรกลejรญ ลพรกdosti HTTP POST na server, kde se spustรญ urฤitรฉ udรกlosti Forgejo. Webhooky zde definovanรฉ budou aktivnรญ u vลกech repozitรกลลฏ v systรฉmu, zvaลพte tedy prosรญm vลกechny vlivy na vรฝkon, kterรฉ mลฏลพe tato funkce zpลฏsobit. Vรญce informacรญ zjistรญte v nรกvodu webhookลฏ .
assets = Assety kรณdu
dashboard.cleanup_actions = Vymazat proลกlรฉ protokoly a artefakty z akcรญ
packages.cleanup.success = Proลกlรก data รบspฤลกnฤ vymazรกna
config.logger_name_fmt = Logger: %S
monitor.download_diagnosis_report = Stรกhnout hlรกลกenรญ o diagnรณze
-self_check.no_problem_found = Zatรญm nenalezen ลพรกdnรฝ problรฉm.
-self_check.database_collation_mismatch = Oฤekรกvรก se, ลพe databรกze pouลพije collation: %s
-self_check.database_inconsistent_collation_columns = Databรกze pouลพรญvรก collation %s, tyto sloupce nicmรฉnฤ pouลพรญvajรญ rozdรญlnรฉ collationy. Toto mลฏลพe zpลฏsobit neoฤekรกvanรฉ problรฉmy.
-self_check.database_fix_mysql = Uลพivatelรฉ MySQL/MariaDB mohou pouลพรญt pลรญkaz โgitea doctor convertโ pro automatickรฉ opravenรญ problรฉmลฏ s collation. Problรฉm takรฉ mลฏลพete vyลeลกit ruฤnฤ SQL pลรญkazy โALTER ... COLLATE ...โ.
+self_check.no_problem_found=Zatรญm nebyl nalezen ลพรกdnรฝ problรฉm.
+self_check.database_collation_mismatch=Oฤekรกvejte, ลพe databรกze pouลพije collation: %s
+self_check.database_inconsistent_collation_columns=Databรกze pouลพรญvรก collation %s, ale tyto sloupce pouลพรญvajรญ chybnรฉ collation. To mลฏลพe zpลฏsobit neoฤekรกvanรฉ problรฉmy.
+self_check.database_fix_mysql=Pro uลพivatele MySQL/MariaDB mลฏลพete pouลพรญt pลรญkaz โforgejo doctor convertโ, kterรฝ opravรญ problรฉmy s porovnรกnรญm. Problรฉm takรฉ mลฏลพete ruฤnฤ vyลeลกit pลรญkazem โALTER ... COLLATE ...โ SQL.
self_check = Vlastnรญ kontrola
-dashboard.sync_tag.started = Synchronizace znaฤek spuลกtฤna
-dashboard.rebuild_issue_indexer = Pลestavit indexer vydรกnรญ
-self_check.database_collation_case_insensitive = Databรกze pouลพรญvรก collation %s. Jednรก se o intenzivnรญ collation. Aฤkoli s nรญ Forgejo nejspรญลกe bude pracovat, mohou nastat urฤitรฉ vzรกcnรฉ pลรญpady, kdy nebude pracovat tak, jak mรก.
+self_check.database_collation_case_insensitive=Databรกze pouลพรญvรก collation %s, coลพ je collation nerozliลกujรญcรญ velkรก a malรก pรญsmena. Aฤkoli s nรญ Forgejo mลฏลพe pracovat, mohou se vyskytnout vzรกcnรฉ pลรญpady, kdy nebude fungovat podle oฤekรกvรกnรญ.
auths.oauth2_map_group_to_team = Zmapovat zabranรฉ skupiny u tรฝmลฏ organizacรญ (volitelnรฉ - vyลพaduje nรกzev claimu vรฝลกe)
monitor.queue.settings.desc = Pooly dynamicky rostou podle blokovรกnรญ fronty jejich workerลฏ.
-self_check.no_problem_found=Zatรญm nebyl nalezen ลพรกdnรฝ problรฉm.
-self_check.database_collation_mismatch=Oฤekรกvejte, ลพe databรกze pouลพije collation: %s
-self_check.database_collation_case_insensitive=Databรกze pouลพรญvรก collation %s, coลพ je collation nerozliลกujรญcรญ velkรก a malรก pรญsmena. Aฤkoli s nรญ Gitea mลฏลพe pracovat, mohou se vyskytnout vzรกcnรฉ pลรญpady, kdy nebude fungovat podle oฤekรกvรกnรญ.
-self_check.database_inconsistent_collation_columns=Databรกze pouลพรญvรก collation %s, ale tyto sloupce pouลพรญvajรญ chybnรฉ collation. To mลฏลพe zpลฏsobit neoฤekรกvanรฉ problรฉmy.
-self_check.database_fix_mysql=Pro uลพivatele MySQL/MariaDB mลฏลพete pouลพรญt pลรญkaz "gitea doctor convert", kterรฝ opravรญ problรฉmy s collation, nebo mลฏลพete takรฉ problรฉm vyลeลกit pลรญkazem "ALTER ... COLLATE ..." SQL ruฤnฤ.
auths.tips.gmail_settings = Nastavenรญ sluลพby Gmail:
config_summary = Souhrn
config.open_with_editor_app_help = Editory v nabรญdce โOtevลรญt pomocรญโ v nabรญdce klonovรกnรญ. Ponechte prรกzdnรฉ pro pouลพitรญ vรฝchozรญho editoru (zobrazรญte jej rozลกรญลenรญm).
config_settings = Nastavenรญ
-auths.tip.gitlab_new = Zaregistrujte si novou aplikaci na https://gitlab.com/-/profile/applications
+auths.tip.gitlab_new = Zaregistrujte si novou aplikaci na %s
auths.default_domain_name = Vรฝchozรญ domรฉnovรฉ jmรฉno pouลพitรฉ pro e-mailovou adresu
config.app_slogan = Slogan instance
+config.cache_test_succeeded = Test mezipamฤti byl รบspฤลกnรฝ, odpovฤฤ byla obdrลพena za %s.
+config.cache_test = Otestovat mezipamฤลฅ
+config.cache_test_failed = Nepodaลilo se provฤลit mezipamฤลฅ: %v.
+config.cache_test_slow = Test mezipamฤti byl รบspฤลกnรฝ, ale odpovฤฤ byla pomalรก: %s.
+users.activated.description = Dokonฤenรญ ovฤลenรญ e-mailu. Majitel neaktivovanรฉho รบฤtu se nebude moci pลihlรกsit, dokud nedokonฤรญ ovฤลenรญ e-mailu.
+users.block.description = Zablokovat tomuto uลพivateli interakci s touto sluลพbou prostลednictvรญm jeho รบฤtu a zakรกzat mu pลihlรกลกenรญ.
+users.restricted.description = Povolit interakci pouze s repozitรกลi a organizacemi, kde je uลพivatel pลidรกn jako spolupracovnรญk. Toto zamezรญ pลรญstup k veลejnรฝm repozitรกลลฏm na tรฉto instanci.
+users.organization_creation.description = Povolit vytvรกลenรญ novรฝch organizacรญ.
+users.local_import.description = Povolit importovรกnรญ repozitรกลลฏ z lokรกlnรญho souborovรฉho systรฉmu serveru. Toto mลฏลพe bรฝt bezpeฤnostnรญ problรฉm.
+users.admin.description = Udฤlit tomuto uลพivateli plnรฝ pลรญstup ke vลกem administrativnรญm funkcem dostupnรฝm ve webovรฉm rozhranรญ a v rozhranรญ API.
+emails.delete = Odstranit e-mail
+emails.delete_desc = Opravdu chcete odstranit tuto e-mailovou adresu?
+emails.deletion_success = E-mailovรก adresa byla odstranฤna.
+emails.delete_primary_email_error = Nemลฏลพete odstranit primรกrnรญ e-mail.
+monitor.duration = Trvรกnรญ (s)
[action]
create_repo=vytvoลil/a repozitรกล %s
@@ -3493,7 +3628,7 @@ delete_branch=smazal/a vฤtev %[2]s z %[3]s
compare_branch=Porovnat
compare_commits=Porovnat %d revizรญ
compare_commits_general=Porovnat revize
-mirror_sync_push=synchronizoval/a commity do %[3]s v %[4]s ze zrcadla
+mirror_sync_push=synchronizoval/a revize do %[3]s v %[4]s ze zrcadla
mirror_sync_create=synchronizoval/a novou referenci %[3]s do %[4]s ze zrcadla
mirror_sync_delete=synchronizoval/a a smazal/a referenci %[2]s
v %[3]s ze zrcadla
approve_pull_request=`schvรกlil/a %[3]s#%[2]s `
@@ -3517,7 +3652,7 @@ future=budoucรญ
1y=1 rokem
seconds=%d sekundami
minutes=%d minutami
-hours=%d hodinami
+hours=%d hodin
days=%d dny
weeks=%d tรฝdny
months=%d mฤsรญci
@@ -3548,13 +3683,13 @@ no_subscriptions=ลฝรกdnรฉ odbฤry
[gpg]
default_key=Podepsรกno vรฝchozรญm klรญฤem
error.extract_sign=Selhalo zรญskรกnรญ podpisu
-error.generate_hash=Selhalo vygenerovรกnรญ hash revize
+error.generate_hash=Selhalo vygenerovรกnรญ hashe revize
error.no_committer_account=ลฝรกdnรฝ รบฤet nenรญ propojen s e-mailovou adresou pลispฤvatele
error.no_gpg_keys_found=V databรกzi nebyl nalezen ลพรกdnรฝ znรกmรฝ klรญฤ pro tento podpis
-error.not_signed_commit=Nepodepsanรฝ commit
+error.not_signed_commit=Nepodepsanรก revize
error.failed_retrieval_gpg_keys=Nepodaลilo se zรญskat ลพรกdnรฝ klรญฤ propojenรฝ s รบฤtem pลispฤvatele
-error.probable_bad_signature=VAROVรNร! Pลestoลพe v databรกzi existuje klรญฤ s tรญmto ID, tento commit neovฤลuje! Tento commit je PODEZลELร.
-error.probable_bad_default_signature=VAROVรNร! Aฤkoli vรฝchozรญ klรญฤ mรก toto ID, neovฤลuje tento commit! Tento commit je PODEZลELร.
+error.probable_bad_signature=VAROVรNร! Pลestoลพe v databรกzi existuje klรญฤ s tรญmto ID, tato revize jรญm nenรญ ovฤลena! Tato revize je PODEZลELร.
+error.probable_bad_default_signature=VAROVรNร! Pลestoลพe mรก vรฝchozรญ klรญฤ toto ID, tato revize jรญm nenรญ ovฤลena! Tato revize je PODEZลELร.
[units]
unit=Jednotka
@@ -3564,7 +3699,7 @@ error.unit_not_allowed=Nejste oprรกvnฤni pลistupovat k tรฉto ฤรกsti repozitรก
[packages]
title=Balรญฤky
desc=Sprรกva balรญฤkลฏ repozitรกลe.
-empty=Zatรญm nejsou ลพรกdnรฉ balรญฤky.
+empty=Zatรญm zde nejsou ลพรกdnรฉ balรญฤky.
empty.documentation=Dalลกรญ informace o registru balรญฤkลฏ naleznete v dokumentaci .
empty.repo=Nahrรกli jste balรญฤek, ale nezobrazil se zde? Pลejdฤte na nastavenรญ balรญฤku a propojte jej s tรญmto repozitรกลem.
registry.documentation=Dalลกรญ informace o registru %s naleznete v dokumentaci .
@@ -3614,10 +3749,10 @@ conda.registry=Nastavte tento registr jako Conda repozitรกล ve vaลกem .co
conda.install=Pro instalaci balรญฤku pomocรญ Conda spusลฅte nรกsledujรญcรญ pลรญkaz:
container.details.type=Typ obrazu
container.details.platform=Platforma
-container.pull=Stรกhnฤte obraz z pลรญkazovรฉ ลรกdky:
-container.digest=Vรฝbฤr:
+container.pull=Stรกhnout obraz z pลรญkazovรฉ ลรกdky:
+container.digest=Vรฝbฤr
container.multi_arch=OS/architektura
-container.layers=Vrstvy obrazลฏ
+container.layers=Vrstvy obrazu
container.labels=ล tรญtky
container.labels.key=Klรญฤ
container.labels.value=Hodnota
@@ -3631,7 +3766,7 @@ debian.repository.distributions=Distribuce
debian.repository.components=Komponenty
debian.repository.architectures=Architektury
generic.download=Stรกhnout balรญฤek z pลรญkazovรฉ ลรกdky:
-go.install=Nainstalujte balรญฤek z pลรญkazovรฉ ลรกdky:
+go.install=Nainstalovat balรญฤek z pลรญkazovรฉ ลรกdky:
helm.registry=Nastavte tento registr z pลรญkazovรฉho ลรกdku:
helm.install=Pro instalaci balรญฤku spusลฅte nรกsledujรญcรญ pลรญkaz:
maven.registry=Nastavte tento registr ve vaลกem projektu pom.xml
souboru:
@@ -3658,7 +3793,7 @@ rpm.distros.suse=na distribuce zaloลพenรฉ na SUSE
rpm.install=Pro instalaci balรญฤku spusลฅte nรกsledujรญcรญ pลรญkaz:
rpm.repository=Informace o repozitรกลi
rpm.repository.architectures=Architektury
-rpm.repository.multiple_groups=Tento balรญฤek je k dispozici ve vรญce skupinรกch.
+rpm.repository.multiple_groups = Tento balรญฤek je dostupnรฝ v nฤkolika skupinรกch.
rubygems.install=Pro instalaci balรญฤku pomocรญ gem spusลฅte nรกsledujรญcรญ pลรญkaz:
rubygems.install2=nebo ho pลidejte do Gemfie:
rubygems.dependencies.runtime=Bฤhovรฉ zรกvislosti
@@ -3682,7 +3817,7 @@ settings.delete.success=Balรญฤek byl odstranฤn.
settings.delete.error=Nepodaลilo se odstranit balรญฤek.
owner.settings.cargo.title=Index registru Cargo
owner.settings.cargo.initialize=Inicializovat index
-owner.settings.cargo.initialize.description=Pro pouลพitรญ Cargo registru je zapotลebรญ speciรกlnรญ index Git. Pouลพitรญ tรฉto moลพnosti (znovu)vytvoลรญ repozitรกล a automaticky jej nastavรญ.
+owner.settings.cargo.initialize.description=Pro pouลพitรญ registru Cargo je zapotลebรญ speciรกlnรญ index Git. Pouลพitรญ tรฉto moลพnosti (znovu) vytvoลรญ repozitรกล a automaticky jej nastavรญ.
owner.settings.cargo.initialize.error=Nepodaลilo se inicializovat Cargo index: %v
owner.settings.cargo.initialize.success=Index Cargo byl รบspฤลกnฤ vytvoลen.
owner.settings.cargo.rebuild=Znovu vytvoลit index
@@ -3711,10 +3846,34 @@ owner.settings.cleanuprules.success.delete=Pravidlo pro ฤiลกtฤnรญ bylo odstran
owner.settings.chef.title=Registr Chef
owner.settings.chef.keypair=Generovat pรกr klรญฤลฏ
owner.settings.chef.keypair.description=Pro autentizaci do registru Chef je zapotลebรญ pรกr klรญฤลฏ. Pokud jste pลedtรญm vytvoลili pรกr klรญฤลฏ, novฤ vygenerovanรฝ pรกr klรญฤลฏ vyลadรญ starรฝ pรกr klรญฤลฏ.
-rpm.repository.multiple_groups = Tento balรญฤek je dostupnรฝ v nฤkolika skupinรกch.
owner.settings.cargo.rebuild.description = Opฤtovnรฉ sestavenรญ mลฏลพe bรฝt uลพiteฤnรฉ, pokud nenรญ index synchronizovรกn s uloลพenรฝmi balรญฤky Cargo.
owner.settings.cargo.rebuild.no_index = Opฤtovnรฉ vytvoลenรญ selhalo, nebyl inicializovรกn ลพรกdnรฝ index.
npm.dependencies.bundle = Pลidruลพenรฉ zรกvislosti
+arch.pacman.helper.gpg = Pลidat certifikรกt dลฏvฤryhodnosti do nรกstroje pacman:
+arch.pacman.repo.multi = %s mรก stejnou verzi v rลฏznรฝch distribucรญch.
+arch.pacman.repo.multi.item = Nastavenรญ pro %s
+arch.pacman.conf = Pลidejte server s odpovรญdajรญcรญ distribucรญ a architekturou do /etc/pacman.conf
:
+arch.pacman.sync = Synchronizace balรญฤku nรกstrojem pacman:
+arch.version.properties = Vlastnosti verze
+arch.version.description = Popis
+arch.version.provides = Poskytuje
+arch.version.groups = Skupina
+arch.version.depends = Zรกvislosti
+arch.version.optdepends = Volitelnรฉ zรกvislosti
+arch.version.makedepends = Zรกvislosti Make
+arch.version.checkdepends = Zรกvislosti Check
+arch.version.conflicts = Konflikty
+arch.version.replaces = Nahrazuje
+arch.version.backup = Zรกloha
+container.images.title = Obrรกzky
+search_in_external_registry = Hledat v %s
+alt.install = Instalovat balรญฤek
+alt.setup = Pลidejte repozitรกล do seznamu pลipojenรฝch repozitรกลลฏ (mรญsto โ_arch_โ zvolte potลebnou architekturu):
+alt.repository = Informace o repozitรกลi
+alt.repository.architectures = Architektury
+alt.repository.multiple_groups = Tento balรญฤek je dostupnรฝ v nฤkolika skupinรกch.
+alt.registry = Nastavit tento registr z pลรญkazovรฉ ลรกdky:
+alt.registry.install = Pro instalaci balรญฤku spusลฅte nรกsledujรญcรญ pลรญkaz:
[secrets]
secrets=Tajnรฉ klรญฤe
@@ -3734,7 +3893,7 @@ management=Sprรกva tajnรฝch klรญฤลฏ
[actions]
actions=Akce
-unit.desc=Spravovat integrovanรฉ pipeliny CI/CD pomocรญ funkce Forgejo Actions
+unit.desc=Spravovat integrovanรฉ pipeliny CI/CD pomocรญ funkce Forgejo Actions.
status.unknown=Neznรกmรฝ
status.waiting=ฤekรกnรญ
@@ -3760,7 +3919,7 @@ runners.task_list.no_tasks=Zatรญm zde nejsou ลพรกdnรฉ รบlohy.
runners.task_list.run=Spustit
runners.task_list.status=Status
runners.task_list.repository=Repozitรกล
-runners.task_list.commit=Commit
+runners.task_list.commit=Revize
runners.task_list.done_at=Dokonฤeno v
runners.edit_runner=Upravit Runner
runners.update_runner=Aktualizovat zmฤny
@@ -3780,7 +3939,7 @@ runners.reset_registration_token=Resetovat registraฤnรญ token
runners.reset_registration_token_success=Registraฤnรญ token runneru byl รบspฤลกnฤ obnoven
runs.all_workflows=Vลกechny workflowy
-runs.commit=Commit
+runs.commit=Revize
runs.scheduled=Naplรกnovรกno
runs.invalid_workflow_helper=Konfiguraฤnรญ soubor pracovnรญho postupu je neplatnรฝ. Zkontrolujte prosรญm konfiguraฤnรญ soubor: %s
runs.no_matching_online_runner_helper=ลฝรกdnรฝ odpovรญdajรญcรญ online runner s popiskem: %s
@@ -3789,11 +3948,11 @@ runs.status=Status
runs.actors_no_select=Vลกichni aktรฉลi
runs.status_no_select=Vลกechny stavy
runs.no_results=Nebyly nalezeny ลพรกdnรฉ vรฝsledky.
-runs.no_workflows=Zatรญm neexistujรญ ลพรกdnรฉ pracovnรญ postupy.
-runs.no_workflows.quick_start=Nevรญte jak zaฤรญt s Gitea Actions? Podรญvejte se na prลฏvodce rychlรฝm startem .
-runs.no_workflows.documentation=Dalลกรญ informace o Gitea Actions naleznete v dokumentaci .
+runs.no_workflows=Zatรญm nebyly vytvoลeny ลพรกdnรฉ pracovnรญ postupy.
+runs.no_workflows.quick_start = Nevรญte jak zaฤรญt s Gitea Action? Podรญvejte se na prลฏvodce rychlรฝm startem .
+runs.no_workflows.documentation = Dalลกรญ informace o Gitea Action, viz dokumentace .
runs.no_runs=Pracovnรญ postup zatรญm nebyl spuลกtฤn.
-runs.empty_commit_message=(prรกzdnรก zprรกva commitu)
+runs.empty_commit_message=(prรกzdnรก zprรกva revize)
workflow.disable=Zakรกzat workflow
workflow.disable_success=Workflow โ%sโ byl รบspฤลกnฤ deaktivovรกn.
@@ -3805,11 +3964,11 @@ workflow.disabled=Pracovnรญ postup je zakรกzรกn.
variables=Promฤnnรฉ
variables.management=Sprรกva promฤnnรฝch
variables.creation=Pลidat promฤnnou
-variables.none=Zatรญm nejsou ลพรกdnรฉ promฤnnรฉ.
+variables.none=Zatรญm zde nejsou ลพรกdnรฉ promฤnnรฉ.
variables.deletion=Odstranit promฤnnou
variables.deletion.description=Odstranฤnรญ promฤnnรฉ je trvalรฉ a nelze jej vrรกtit zpฤt. Pokraฤovat?
variables.description=Promฤnnรฉ budou pลedรกny urฤitรฝm akcรญm a nelze je pลeฤรญst jinak.
-variables.id_not_exist=Promฤnnรก s ID %d neexistuje.
+variables.id_not_exist = Promฤnnรก s id %d neexistuje.
variables.edit=Upravit promฤnnou
variables.deletion.failed=Nepodaลilo se odstranit promฤnnou.
variables.deletion.success=Promฤnnรก byla odstranฤna.
@@ -3817,9 +3976,6 @@ variables.creation.failed=Pลidรกnรญ promฤnnรฉ se nezdaลilo.
variables.creation.success=Promฤnnรก โ%sโ byla pลidรกna.
variables.update.failed=รprava promฤnnรฉ se nezdaลila.
variables.update.success=Promฤnnรก byla upravena.
-runs.no_workflows.quick_start = Nevรญte jak zaฤรญt s Gitea Action? Podรญvejte se na prลฏvodce rychlรฝm startem .
-variables.id_not_exist = Promฤnnรก s id %d neexistuje.
-runs.no_workflows.documentation = Dalลกรญ informace o Gitea Action, viz dokumentace .
runners.none = Nejsou dostupnรฉ ลพรกdnรฉ runnery
runs.workflow = Workflow
runners = Runnery
@@ -3828,15 +3984,26 @@ need_approval_desc = Potลebovat schvรกlenรญ pro spouลกtฤnรญ workflowลฏ pro ลพ
runners.runner_manage_panel = Sprรกva runnerลฏ
runs.no_job_without_needs = Workflow musรญ obsahovat alespoล jednu prรกci bez zรกvislostรญ.
runs.no_job = Workflow musรญ obsahovat alespoล jednu รบlohu
+workflow.dispatch.use_from = Pouลพรญt workflow z
+workflow.dispatch.run = Spustit workflow
+workflow.dispatch.input_required = Vyลพadovanรก hodnota pro vstup โ%sโ.
+workflow.dispatch.invalid_input_type = Neplatnรฝ typ vstupu โ%sโ.
+workflow.dispatch.warn_input_limit = Zobrazovรกnรญ prvnรญch %d vstupลฏ.
+workflow.dispatch.trigger_found = Tento workflow mรก spouลกtฤฤ udรกlostรญ workflow_dispatch .
+workflow.dispatch.success = ลฝรกdost o spuลกtฤnรญ workflow byla รบspฤลกnฤ odeslรกna.
+runs.expire_log_message = Protokoly byly smazรกny, protoลพe byly pลรญliลก starรฉ.
+runs.no_workflows.help_no_write_access = Pro vรญce informacรญ o Forgejo Actions se podรญvejte do dokumentace .
+runs.no_workflows.help_write_access = Nevรญte, jak zaฤรญt s Forgejo Actions? Podรญvejte se na rychlรฝ zaฤรกtek v uลพivatelskรฉ dokumentaci pro vytvoลenรญ vaลกeho prvnรญho workflow. Potรฉ nastavte runner Forgejo pro provรกdฤnรญ vaลกich รบloh.
+variables.not_found = Nepodaลilo se najรญt promฤnnou.
[projects]
type-1.display_name=Samostatnรฝ projekt
type-2.display_name=Projekt repozitรญลe
type-3.display_name=Projekt organizace
+deleted.display_name = Smazanรฝ projekt
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=Adresรกล
normal_file=Normรกlnรญ soubor
executable_file=Spustitelnรฝ soubor
@@ -3851,25 +4018,30 @@ type_tooltip = Typ vyhledรกvรกnรญ
fuzzy = Pลibliลพnรฉ
match = Shoda
match_tooltip = Zahrnout pouze vรฝsledky, kterรฉ pลesnฤ odpovรญdajรญ hledanรฉmu vรฝrazu
-repo_kind = Hledat repozitรกลe...
-user_kind = Hledat uลพivatele...
-org_kind = Hledat organizace...
-team_kind = Hledat tรฝmy...
-code_kind = Hledat kรณd...
-package_kind = Hledat balรญฤky...
-project_kind = Hledat projekty...
-branch_kind = Hledat vฤtve...
-commit_kind = Hledat commity...
-runner_kind = Hledat runnery...
+repo_kind = Hledat repozitรกลeโฆ
+user_kind = Hledat uลพivateleโฆ
+org_kind = Hledat organizaceโฆ
+team_kind = Hledat tรฝmyโฆ
+code_kind = Hledat kรณdโฆ
+package_kind = Hledat balรญฤkyโฆ
+project_kind = Hledat projektyโฆ
+branch_kind = Hledat vฤtveโฆ
+commit_kind = Hledat revizeโฆ
+runner_kind = Hledat runneryโฆ
no_results = Nenalezeny ลพรกdnรฉ odpovรญdajรญcรญ vรฝsledky.
fuzzy_tooltip = Zahrnout takรฉ vรฝsledky, kterรฉ รบzce odpovรญdajรญ hledanรฉmu vรฝrazu
-search = Hledat...
+search = Hledatโฆ
keyword_search_unavailable = Hledรกnรญ pomocรญ klรญฤovรฝch slov momentรกlnฤ nenรญ dostupnรฉ. Kontaktujte prosรญm administrรกtora webu.
code_search_by_git_grep = Aktuรกlnรญ vรฝsledky vyhledรกvรกnรญ kรณdu jsou poskytovรกny sluลพbou โgit grepโ. Lepลกรญ vรฝsledky dostanete, kdyลพ administrรกtor webu povolรญ indexovรกnรญ kรณdu.
exact = Pลesnรฉ
exact_tooltip = Zahrnout pouze vรฝsledky, kterรฉ pลesnฤ odpovรญdajรญ hledanรฉmu vรฝrazu
-issue_kind = Hledat problรฉmy...
-pull_kind = Hledat pully...
+issue_kind = Hledat problรฉmyโฆ
+pull_kind = Hledat ลพรกdostiโฆ
+union = Sdruลพenรฉ
+union_tooltip = Zahrnout vรฝsledky, kterรฉ odpovรญdajรญ jakรฉmukoli ze slov oddฤlenรฝch mezerami
+milestone_kind = Hledat milnรญky...
+regexp = RegExp
+regexp_tooltip = Interpretovat hledanรฝ vรฝraz jako regulรกrnรญ vรฝraz
[markup]
filepreview.lines = ลรกdky %[1]d aลพ %[2]d v souboru %[3]s
@@ -3884,3 +4056,27 @@ gib = GiB
tib = TiB
pib = PiB
eib = EiB
+
+
+[translation_meta]
+test = diky vsem za pomoc :)
+
+[repo.permissions]
+pulls.write = Zapisovat: Zavรญrat ลพรกdosti o slouฤenรญ a spravovat metadata jako ลกtรญtky, milnรญky, zpracovatele, data dokonฤenรญ a zรกvislosti.
+packages.write = Zapisovat: Zveลejลovat a mazat balรญฤky pลipojenรฉ k repozitรกลi.
+projects.read = ฤรญst: Pลรญstup k projektovรฝm nรกstฤnkรกm repozitรกลe.
+code.write = Zapisovat: Odesรญlat zmฤny do repozitรกลe, vytvรกลet vฤtve a znaฤky.
+issues.write = Zapisovat: Zavรญrat problรฉmy a spravovat metadata jako ลกtรญtky, milnรญky, zpracovatele, data dokonฤenรญ a zรกvislosti.
+pulls.read = ฤรญst: ฤรญst a vytvรกลet ลพรกdosti o slouฤenรญ.
+releases.read = ฤรญst: Zobrazovat a stahovat vydรกnรญ.
+releases.write = Zapisovat: Zveลejลovat, upravovat a mazat vydรกnรญ a jejich soubory.
+wiki.read = ฤรญst: ฤรญst integrovanou wiki a jejรญ historii.
+wiki.write = Zapisovat: Vytvรกลet, aktualizovat a mazat strรกnky v integrovanรฉ wiki.
+projects.write = Zapisovat: Vytvรกลet projekty a sloupce a upravovat je.
+packages.read = ฤรญst: Zobrazovat a stahovat balรญฤky pลipojenรฉ k repozitรกลi.
+actions.read = ฤรญst: Zobrazovat integrovanรฉ pipeliny CI/CD a jejich protokoly.
+actions.write = Zapisovat: Ruฤnฤ spouลกtฤt, restartovat, ruลกit nebo schvalovat ฤekajรญcรญ pipeliny CI/CD.
+ext_wiki = Pลรญstup k odkazu v externรญ wiki. Oprรกvnฤnรญ jsou spravovรกna externฤ.
+code.read = ฤรญst: Pลรญstup a klonovรกnรญ kรณdu v repozitรกลi.
+issues.read = ฤรญst: ฤรญst a vytvรกลet problรฉmy a komentรกลe.
+ext_issues = Pลรญstup k odkazu v externรญm sledovacรญm systรฉmu problรฉmลฏ. Oprรกvnฤnรญ jsou spravovรกna externฤ.
diff --git a/options/locale/locale_da.ini b/options/locale/locale_da.ini
new file mode 100644
index 0000000000..5d8e6d8791
--- /dev/null
+++ b/options/locale/locale_da.ini
@@ -0,0 +1,3806 @@
+[common]
+home = Hjem
+dashboard = Instrumentpanel
+explore = Udforsk
+help = Hjรฆlp
+logo = Logo
+sign_in = Login
+sign_in_with_provider = Login med %s
+sign_in_or = eller
+sign_out = Logud
+sign_up = Register
+return_to_forgejo = Vend tilbage til Forgejo
+new_repo.title = Ny repository
+retry = Prรธv igen
+link_account = Link konto
+register = Register
+powered_by = Baseret pรฅ %s
+version = Version
+create_new = Opretโฆ
+user_profile_and_more = Profil og indstillingerโฆ
+page = Side
+template = Skabelon
+language = Sprog
+notifications = Notifikationer
+active_stopwatch = Aktiv tidsregistrering
+enable_javascript = Dette websted krรฆver JavaScript.
+toc = Indholdsfortegnelse
+licenses = Licenser
+more_items = Flere genstande
+username = Brugernavn
+email = E-mailadresse
+password = Adgangskode
+access_token = Adgangstoken
+re_type = Bekrรฆft adgangskode
+captcha = CAPTCHA
+twofa = To-faktor autentificering
+twofa_scratch = To-faktor skrabekode
+webauthn_sign_in = Tryk pรฅ knappen pรฅ din sikkerhedsnรธgle. Hvis din sikkerhedsnรธgle ikke har nogen knap, skal du indsรฆtte den igen.
+webauthn_use_twofa = Brug en tofaktorkode fra din telefon
+webauthn_error = Kunne ikke lรฆse din sikkerhedsnรธgle.
+webauthn_unsupported_browser = Din browser understรธtter i รธjeblikket ikke WebAuthn.
+webauthn_error_unknown = Der opstod en ukendt fejl. Prรธv venligst igen.
+webauthn_error_unable_to_process = Serveren kunne ikke behandle din anmodning.
+webauthn_error_duplicated = Sikkerhedsnรธglen er ikke tilladt for denne anmodning. Sรธrg for, at nรธglen ikke allerede er registreret.
+webauthn_error_empty = Du skal angive et navn for denne nรธgle.
+organization = Organisation
+mirror = Mirror
+new_mirror = Ny mirror
+new_fork = Ny repository fork
+new_project = Nyt projekt
+new_project_column = Ny kolonne
+admin_panel = Side administration
+settings = Indstillinger
+your_profile = Profil
+your_starred = Stjernemarkeret
+your_settings = Indstillinger
+passcode = Passcode
+repository = Depot
+new_org.title = Ny organisation
+new_repo.link = Nyt repository
+new_migrate.link = Ny migration
+new_org.link = Ny organisation
+all = Alle
+sources = Kilder
+mirrors = Mirrors
+collaborative = Samarbejdende
+forks = Forks
+activities = Aktiviteter
+pull_requests = Pull anmodninger
+issues = Problemer
+milestones = Milepรฆle
+ok = OK
+cancel = Annuller
+rerun = Kรธr igen
+rerun_all = Kรธr alle jobs igen
+save = Gem
+add = Tilfรธj
+add_all = Tilfรธj alle
+remove = Slet
+remove_all = Slet alle
+remove_label_str = Slet genstand "%s"
+edit = Redigere
+view = Se
+test = Test
+disabled = Deaktiveret
+copy = Kopiรฉr
+copy_generic = Kopiรฉr til udklipsholder
+copy_url = Kopiรฉr URL
+copy_path = Kopiรฉr sti
+copy_content = Kopier indhold
+copy_branch = Kopiรฉr branch navn
+copy_success = Kopieret!
+copy_error = Kopiering mislykkedes
+write = Skriv
+preview = Forhรฅndsvisning
+loading = Indlรฆserโฆ
+error = Fejl
+error413 = Du har opbrugt din kvote.
+go_back = Gรฅ tilbage
+never = Aldrig
+unknown = Ukendt
+rss_feed = RSS feed
+pin = Pin
+unpin = Frigรธr
+artifacts = Artefakter
+archived = Arkiveret
+concept_system_global = Global
+concept_user_individual = Individuel
+concept_code_repository = Depot
+concept_user_organization = Organisation
+show_timestamps = Vis tidsstempler
+show_log_seconds = Vis sekunder
+tracked_time_summary = Opsummering af sporet tid baseret pรฅ filtre af problemliste
+signed_in_as = Logget ind som
+webauthn_error_insecure = WebAuthn understรธtter kun sikre forbindelser. Til test over HTTP kan du bruge oprindelsen "localhost" eller "127.0.0.1"
+invalid_data = Ugyldige data: %v
+webauthn_insert_key = Indsรฆt din sikkerhedsnรธgle
+webauthn_press_button = Tryk venligst pรฅ knappen pรฅ din sikkerhedsnรธgleโฆ
+webauthn_error_timeout = Timeout nรฅet, fรธr din nรธgle kunne lรฆses. Genindlรฆs denne side og prรธv igen.
+enabled = Aktiveret
+locked = Lรฅst
+copy_hash = Kopiรฉr hash
+error404 = Den side, du forsรธger at nรฅ, enten findes ikke , er blevet slettet eller du er ikke autoriseret til at se den.
+confirm_delete_artifact = Er du sikker pรฅ, at du vil slette artefakten "%s"?
+new_migrate.title = Ny migration
+copy_type_unsupported = Denne filtype kan ikke kopieres
+toggle_menu = TIl/Fra menu
+show_full_screen = Vis fuld skรฆrm
+download_logs = Download logs
+confirm_delete_selected = Bekrรฆft at slette alle valgte genstande?
+name = Navn
+value = Vรฆrdi
+filter = Filter
+filter.clear = Ryd filtre
+filter.is_archived = Arkiveret
+filter.not_archived = Ikke arkiveret
+filter.is_fork = Forks
+filter.not_fork = Ikke forks
+filter.is_mirror = Mirrors
+filter.not_mirror = Ikke mirrors
+filter.is_template = Skabeloner
+filter.not_template = Ikke skabeloner
+filter.public = Offentlig
+filter.private = Privat
+
+[search]
+search = Sรธgโฆ
+type_tooltip = Sรธge type
+fuzzy = Fuzzy
+fuzzy_tooltip = Medtag resultater, der ogsรฅ matcher sรธgeordet tรฆt
+union = Almindelig
+union_tooltip = Inkluder resultater, der matcher et hvilket som helst af de mellemrums-adskilte sรธgeord
+exact = Nรธjagtig
+exact_tooltip = Medtag kun resultater, der matcher den nรธjagtige sรธgeterm
+regexp = RegExp
+regexp_tooltip = Fortolk sรธgetermen som et regulรฆrt udtryk
+org_kind = Sรธg i organisationerโฆ
+team_kind = Sรธg efter teamsโฆ
+code_kind = Sรธg kodeโฆ
+code_search_by_git_grep = Aktuelle kodesรธgeresultater leveres af "git grep". Der kan vรฆre bedre resultater, hvis webstedsadministratoren aktiverer kodeindeksering.
+package_kind = Sรธg pakkerโฆ
+project_kind = Sรธg efter projekterโฆ
+commit_kind = Sรธg commitsโฆ
+branch_kind = Sรธg branchesโฆ
+runner_kind = Sรธg runnersโฆ
+issue_kind = Sรธg i problemerโฆ
+milestone_kind = Sรธg milepรฆle...
+pull_kind = Sรธg pullsโฆ
+repo_kind = Sรธg depoterโฆ
+code_search_unavailable = Kodesรธgning er ikke tilgรฆngelig i รธjeblikket. Kontakt venligst webstedets administrator.
+no_results = Ingen matchende resultater fundet.
+user_kind = Sรธg brugereโฆ
+keyword_search_unavailable = Sรธgning efter nรธgleord er ikke tilgรฆngelig i รธjeblikket. Kontakt venligst webstedets administrator.
+
+[aria]
+navbar = Navigationslinje
+footer = Sidefod
+footer.software = Omkring dette software
+footer.links = Links
+
+[heatmap]
+number_of_contributions_in_the_last_12_months = %s bidrag inden for de sidste 12 mรฅneder
+contributions_zero = Ingen bidrag
+contributions_format = {contributions} pรฅ {month} {day}, {year}
+contributions_one = bidrag
+contributions_few = bidrag
+less = Mindre
+more = Mere
+
+[editor]
+buttons.heading.tooltip = Tilfรธj overskrift
+buttons.bold.tooltip = Tilfรธj fed tekst
+buttons.italic.tooltip = Tilfรธj kursiv tekst
+buttons.quote.tooltip = Citat tekst
+buttons.code.tooltip = Tilfรธj kode
+buttons.link.tooltip = Tilfรธj et link
+buttons.list.unordered.tooltip = Tilfรธj en punktliste
+buttons.list.task.tooltip = Tilfรธj en liste over opgaver
+buttons.list.ordered.tooltip = Tilfรธj en nummereret liste
+buttons.mention.tooltip = Nรฆvn en bruger eller et team
+buttons.ref.tooltip = Henvis til et problem eller pull-anmodning
+buttons.enable_monospace_font = Aktiver monospace-skrifttype
+buttons.disable_monospace_font = Deaktiver monospace-skrifttype
+buttons.new_table.tooltip = Tilfรธj tabel
+table_modal.header = Tilfรธj tabel
+table_modal.placeholder.header = Hoved
+table_modal.placeholder.content = Indhold
+table_modal.label.rows = Rรฆkker
+table_modal.label.columns = Kolonner
+buttons.unindent.tooltip = Udsortere genstande med รฉt niveau
+buttons.indent.tooltip = Indlejring af genstande med รฉt niveau
+buttons.switch_to_legacy.tooltip = Brug den gamle editor i stedet
+link_modal.header = Tilfรธj et link
+link_modal.url = Url
+link_modal.description = Beskrivelse
+link_modal.paste_reminder = Tip: Med en URL i dit udklipsholder kan du indsรฆtte direkte i editoren for at oprette et link.
+
+[filter]
+string.asc = A - Z
+string.desc = Z - A
+
+[error]
+occurred = Der opstod en fejl
+not_found = Mรฅlet kunne ikke findes.
+network_error = Netvรฆrksfejl
+server_internal = Intern serverfejl
+report_message = Hvis du mener, at dette er en Forgejo-fejl, skal du sรธge efter problemer pรฅ Codeberg eller รฅbne et nyt problem, hvis det er nรธdvendigt.
+
+[startpage]
+app_desc = En smertefri, selv-hostet Git-tjeneste
+install = Nem at installere
+platform = Pรฅ tvรฆrs af platforme
+platform_desc = Det er bekrรฆftet, at Forgejo kรธrer pรฅ frie operativsystemer som Linux og FreeBSD, samt forskellige CPU-arkitekturer. Vรฆlg den du elsker!
+lightweight = Letvรฆgtig
+lightweight_desc = Forgejo har lave minimale krav og kan kรธre pรฅ en billig Raspberry Pi. Spar din maskines energi!
+license = ร
ben kildekode
+license_desc = Fรฅ Forgejo ! Slut dig til os ved at bidrage til at gรธre dette projekt endnu bedre. Vรฆr ikke genert over at vรฆre en bidragyder!
+install_desc = Du skal blot kรธre binรฆren for din platform, send den med Docker , eller fรฅ det pakket .
+
+[install]
+install = Installation
+title = Indledende konfiguration
+docker_helper = Hvis du kรธrer Forgejo inde i Docker, skal du lรฆse dokumentationen , fรธr du รฆndrer nogen indstillinger.
+require_db_desc = Forgejo krรฆver MySQL, PostgreSQL, SQLite3 eller TiDB (MySQL-protokol).
+db_title = Database indstillinger
+db_type = Database type
+host = Vรฆrt
+user = Brugernavn
+password = Adgangskode
+db_name = Database navn
+db_schema = Schema
+db_schema_helper = Lad stรฅ tom for databasestandard ("offentlig").
+ssl_mode = SSL
+reinstall_error = Du forsรธger at installere i en eksisterende Forgejo-database
+reinstall_confirm_check_1 = Dataene krypteret af SECRET_KEY i app.ini kan gรฅ tabt: brugere kan muligvis ikke logge ind med 2FA/OTP, og mirrors fungerer muligvis ikke korrekt. Ved at markere dette felt bekrรฆfter du, at den aktuelle app.ini-fil indeholder den korrekte SECRET_KEY.
+reinstall_confirm_check_3 = Du bekrรฆfter, at du er helt sikker pรฅ, at denne Forgejo kรธrer med den korrekte app.ini placering, og at du er sikker pรฅ, at du skal gen-installere. Du bekrรฆfter, at du anerkender ovenstรฅende risici.
+err_empty_db_path = SQLite3-databasestien mรฅ ikke vรฆre tom.
+no_admin_and_disable_registration = Du kan ikke deaktivere brugerens selvregistrering uden at oprette en administratorkonto.
+err_empty_admin_password = Administratoradgangskoden mรฅ ikke vรฆre tom.
+err_empty_admin_email = Administrator-e-mailen mรฅ ikke vรฆre tom.
+err_admin_name_is_reserved = Administratorbrugernavnet er ugyldigt, brugernavnet er reserveret
+err_admin_name_pattern_not_allowed = Administratorbrugernavnet er ugyldigt, brugernavnet matcher et reserveret mรธnster
+err_admin_name_is_invalid = Administratorbrugernavnet er ugyldigt
+general_title = Generelle indstillinger
+app_name = Instans titel
+app_slogan_helper = Indtast dit instans slogan her. Lad vรฆre tom for at deaktivere.
+lfs_path_helper = Filer sporet af Git LFS vil blive gemt i denne mappe. Lad vรฆre tom for at deaktivere.
+run_user = Bruger at kรธre som
+lfs_path = Git LFS rodsti
+repo_path = Depot rodsti
+domain = Server domรฆne
+domain_helper = Domรฆne eller vรฆrtsadresse for serveren.
+ssh_port = SSH server port
+ssh_port_helper = Portnummer, der vil blive brugt af SSH-serveren. Lad vรฆre tomt for at deaktivere SSH-serveren.
+http_port = HTTP lytte port
+http_port_helper = Portnummer, der vil blive brugt af Forgejo-webserveren.
+app_url = Base URL
+log_root_path = Log sti
+log_root_path_helper = Logfiler vil blive skrevet til denne mappe.
+optional_title = Valgfrie indstillinger
+email_title = E-mail-indstillinger
+smtp_addr = SMTP vรฆrt
+smtp_port = SMTP port
+smtp_from = Send e-mail som
+smtp_from_invalid = "Send e-mail som"-adressen er ugyldig
+mailer_user = SMTP brugernavn
+mailer_password = SMTP adgangskode
+register_confirm = Krรฆv e-mail-bekrรฆftelse for at registrere
+mail_notify = Aktiver e-mailmeddelelser
+server_service_title = Server- og tredjeparts tjenesteindstillinger
+offline_mode = Aktiver lokal tilstand
+disable_gravatar = Deaktiver Gravatar
+disable_gravatar.description = Deaktiver brug af Gravatar eller andre tredjeparts avatar kilder. Standardbilleder vil blive brugt til bruger avatarer, medmindre de uploader deres egen avatar til instansen.
+federated_avatar_lookup = Aktiver fรธdererede avatarer
+federated_avatar_lookup.description = Slรฅ avatarer op ved hjรฆlp af Libravatar.
+disable_registration = Deaktiver selvregistrering
+allow_only_external_registration = Tillad kun registrering via eksterne tjenester
+allow_only_external_registration.description = Brugere vil kun vรฆre i stand til at oprette nye konti ved at bruge konfigurerede eksterne tjenester.
+openid_signin = Aktiver OpenID-logon
+openid_signin.description = Tillad brugere at logge ind via OpenID.
+app_slogan = Instans slogan
+repo_path_helper = Fjerne Git depoter vil blive gemt i denne mappe.
+smtp_from_helper = E-mailadresse Forgejo vil bruge. Indtast en almindelig e-mailadresse, eller brug formatet "Navn" .
+run_user_helper = Operativsystemets brugernavn, som Forgejo kรธrer som. Bemรฆrk, at denne bruger skal have adgang til depotets rodsti.
+app_name_helper = Indtast dit instans-navn her. Det vil blive vist pรฅ hver side.
+offline_mode.description = Deaktiver tredjeparts indholdsleverings netvรฆrk og server alle ressourcer lokalt.
+disable_registration.description = Kun instans administratoren vil vรฆre i stand til at oprette nye brugerkonti. Det anbefales stรฆrkt at holde registreringen deaktiveret, medmindre du har til hensigt at vรฆre vรฆrt for en offentlig instans for alle og klar til at hรฅndtere store mรฆngder spamkonti.
+openid_signup = Aktiver OpenID-selvregistrering
+sqlite_helper = Filsti til SQLite3-databasen. Indtast en absolut sti, hvis du kรธrer Forgejo som en tjeneste.
+path = Sti
+reinstall_confirm_message = Geninstallation med en eksisterende Forgejo-database kan forรฅrsage flere problemer. I de fleste tilfรฆlde bรธr du bruge din eksisterende "app.ini" til at kรธre Forgejo. Hvis du ved, hvad du laver, skal du bekrรฆfte fรธlgende:
+reinstall_confirm_check_2 = Depoterne og indstillingerne skal muligvis synkroniseres igen. Ved at markere dette felt bekrรฆfter du, at du vil re-synkronisere hooks for depoter og authorized_keys-filen manuelt. Du bekrรฆfter, at du vil sikre dig, at indstillingerne for depoter og mirror er korrekte.
+app_url_helper = Base adresse for HTTP(S)-klone-URL'er og e-mail-meddelelser.
+enable_captcha = Aktiver registrering CAPTCHA
+enable_captcha.description = Krรฆv brugere at bestรฅ CAPTCHA for at oprette konti.
+require_sign_in_view = Krรฆv at logge ind for at se instansindhold
+default_keep_email_private = Skjul e-mailadresser som standard
+default_keep_email_private.description = Aktiver skjulning af e-mail-adresser for nye brugere som standard, sรฅ disse oplysninger ikke lรฆkkes umiddelbart efter tilmelding.
+default_allow_create_organization = Tillad oprettelse af organisationer som standard
+default_enable_timetracking = Aktiver tidsregistrering som standard
+default_enable_timetracking.description = Tillad som standard brug af tidssporings-funktion for nye depoter.
+admin_title = Indstillinger for administratorkonto
+admin_setting.description = Det er valgfrit at oprette en administratorkonto. Den fรธrste registrerede bruger bliver automatisk administrator.
+admin_name = Administrator brugernavn
+admin_password = Adgangskode
+confirm_password = Bekrรฆft adgangskode
+admin_email = E-mailadresse
+config_location_hint = Disse konfigurationsmuligheder vil blive gemt i:
+install_btn_confirm = Installer Forgejo
+invalid_db_setting = Databaseindstillingerne er ugyldige: %v
+invalid_db_table = Databasetabellen "%s" er ugyldig: %v
+invalid_repo_path = Depotets rodsti er ugyldig: %v
+invalid_app_data_path = Appens datasti er ugyldig: %v
+run_user_not_match = Brugernavnet som "bruger det skal kรธres som" er ikke det aktuelle brugernavn: %s -> %s
+internal_token_failed = Kunne ikke generere intern token: %v
+secret_key_failed = Kunne ikke generere hemmelig nรธgle: %v
+save_config_failed = Konfigurationen kunne ikke gemmes: %v
+invalid_admin_setting = Administratorkonto indstillingen er ugyldig: %v
+invalid_log_root_path = Log stien er ugyldig: %v
+allow_dots_in_usernames = Tillad brugere at bruge prikker i deres brugernavne. Pรฅvirker ikke eksisterende konti.
+no_reply_address = Skjult e-mail-domรฆne
+invalid_password_algorithm = Ugyldig hash-algoritme for adgangskode
+enable_update_checker = Aktiver opdateringskontrol
+env_config_keys = Miljรธkonfiguration
+env_config_keys_prompt = Fรธlgende miljรธvariabler vil ogsรฅ blive anvendt pรฅ din konfigurationsfil:
+test_git_failed = Kunne ikke teste "git" kommandoen: %v
+sqlite3_not_available = Denne Forgejo-version understรธtter ikke SQLite3. Download venligst den officielle binรฆre version fra %s (ikke "gobuild"-versionen).
+no_reply_address_helper = Domรฆnenavn til brugere med en skjult e-mailadresse. For eksempel vil brugernavnet "joe" blive logget i Git som "joe@noreply.example.org", hvis det skjulte e-mail-domรฆne er sat til "noreply.example.org".
+require_sign_in_view.description = Begrรฆns indholdsadgang til ind-loggede brugere. Gรฆster vil kun kunne besรธge autentificerings sider..
+default_allow_create_organization.description = Tillad nye brugere at oprette organisationer som standard. Nรฅr denne mulighed er deaktiveret, skal en administrator give tilladelse til at oprette organisationer til nye brugere.
+password_algorithm = Adgangskode hash algoritme
+enable_update_checker_helper_forgejo = Den vil med jรฆvne mellemrum tjekke for nye Forgejo versioner ved at tjekke en TXT DNS-posten pรฅ release.forgejo.org.
+password_algorithm_helper = Indstil adgangskode-hash-algoritmen. Algoritmer har forskellige krav og styrke. Argon2-algoritmen er ret sikker, men bruger meget hukommelse og kan vรฆre upassende til smรฅ systemer.
+openid_signup.description = Tillad brugere at oprette konti via OpenID, hvis selvregistrering er aktiveret.
+
+[home]
+uname_holder = Brugernavn eller e-mailadresse
+switch_dashboard_context = Skift instrumentpanel-kontekst
+my_repos = Depoter
+my_orgs = Organisationer
+view_home = Se %s
+filter = Andre filtre
+filter_by_team_repositories = Filtrer efter team depoter
+feed_of = Feed af "%s"
+show_archived = Arkiveret
+show_both_archived_unarchived = Viser bรฅde arkiveret og ikke-arkiveret
+show_only_archived = Viser kun arkiverede
+show_only_unarchived = Viser kun ikke-arkiveret
+show_private = Privat
+show_only_private = Viser kun privat
+show_only_public = Viser kun offentligt
+issues.in_your_repos = I dine depoter
+show_both_private_public = Viser bรฅde offentlige og private
+
+[explore]
+repos = Depoter
+users = Brugere
+stars_one = %d stjerne
+stars_few = %d stjerner
+forks_one = %d fork
+forks_few = %d forks
+organizations = Organisationer
+code = Kode
+code_last_indexed_at = Sidst indekseret %s
+relevant_repositories = Kun relevante depoter vises, vis ufiltrerede resultater .
+go_to = Gรฅ til
+relevant_repositories_tooltip = Depoter som er forks, eller som ikke har noget emne, intet ikon og ingen beskrivelse, er skjult.
+
+[auth]
+create_new_account = Registrer konto
+disable_register_prompt = Registrering er deaktiveret. Kontakt venligst din side-administrator.
+disable_register_mail = E-mailbekrรฆftelse for registrering er deaktiveret.
+manual_activation_only = Kontakt din side-administrator for at fuldfรธre aktiveringen.
+remember_me = Husk denne enhed
+forgot_password_title = Glemt adgangskode
+forgot_password = Glemt adgangskode?
+hint_register = Har du brug for en konto? Registrer dig nu.
+sign_up_button = Registrer nu.
+sign_up_successful = Kontoen blev oprettet. Velkommen!
+must_change_password = Opdater din adgangskode
+allow_password_change = Krรฆv, at brugeren รฆndrer adgangskode (anbefales)
+reset_password_mail_sent_prompt = En bekrรฆftelses-e-mail er blevet sendt til %s . For at fuldfรธre kontogendannelses-processen skal du tjekke din indbakke og fรธlge det medfรธlgende link inden for de nรฆste %s.
+active_your_account = Aktiver din konto
+account_activated = Kontoen er blevet aktiveret
+prohibit_login = Kontoen er suspenderet
+prohibit_login_desc = Din konto er blevet suspenderet fra interaktion med instansen. Kontakt instans-administratoren for at fรฅ adgang igen.
+change_unconfirmed_email_summary = Skift den e-mailadresse, aktiveringsmail sendes til.
+change_unconfirmed_email_error = Kan ikke รฆndre e-mailadressen: %v
+resend_mail = Klik her for at sende din aktiverings-e-mail igen
+send_reset_mail = Send gendannelses-e-mail
+reset_password = Kontogendannelse
+invalid_code = Din bekrรฆftelseskode er ugyldig eller er udlรธbet.
+invalid_code_forgot_password = Din bekrรฆftelseskode er ugyldig eller er udlรธbet. Klik her for at starte en ny session.
+invalid_password = Din adgangskode stemmer ikke overens med den adgangskode, der blev brugt til at oprette kontoen.
+reset_password_helper = Gendan konto
+resent_limit_prompt = Du har allerede anmodet om en aktiverings-e-mail for nylig. Vent venligst 3 minutter, og prรธv igen.
+reset_password_wrong_user = Du er logget ind som %s, men linket til kontogendannelse er beregnet til %s
+confirmation_mail_sent_prompt = En ny bekrรฆftelses-e-mail er blevet sendt til %s . For at fuldfรธre registreringsprocessen skal du tjekke din indbakke og fรธlge det medfรธlgende link inden for de nรฆste %s. Hvis e-mailen er forkert, kan du logge ind og anmode om, at endnu en bekrรฆftelses-e-mail sendes til en anden adresse.
+change_unconfirmed_email = Hvis du har opgivet den forkerte e-mailadresse under tilmeldingen, kan du รฆndre den nedenfor, og der vil i stedet blive sendt en bekrรฆftelse til den nye adresse.
+hint_login = Har du allerede en konto? Log ind nu!
+has_unconfirmed_mail = Hej %s, du har en ubekrรฆftet e-mailadresse (%s ). Hvis du ikke har modtaget en bekrรฆftelses-e-mail eller har brug for at sende en ny, bedes du klikke pรฅ knappen nedenfor.
+password_too_short = Adgangskodelรฆngden mรฅ ikke vรฆre mindre end %d tegn.
+non_local_account = Ikke-lokale brugere kan ikke opdatere deres adgangskode via Forgejo-webgrรฆnsefladen.
+verify = Verificere
+unauthorized_credentials = Legitimationsoplysningerne er forkerte eller er udlรธbet. Prรธv din kommando igen, eller se %s for at fรฅ flere oplysninger
+scratch_code = Skrabekode
+use_scratch_code = Brug en skrabekode
+use_onetime_code = Brug en engangskode
+twofa_scratch_used = Du har brugt din skrabekode. Du er blevet omdirigeret til siden med to-faktorindstillinger, sรฅ du kan fjerne din enhedstilmelding eller generere en ny skrabekode.
+twofa_passcode_incorrect = Din passcode er forkert. Hvis du har forlagt din enhed, skal du bruge din skrabekode til at logge ind.
+twofa_scratch_token_incorrect = Din skrabekode er forkert.
+login_userpass = Login
+oauth_signup_tab = Registrer ny konto
+oauth_signup_title = Fuldfรธr ny konto
+oauth_signup_submit = Gennemfรธr konto
+oauth_signin_tab = Link til en eksisterende konto
+oauth_signin_title = Log ind for at godkende linket konto
+oauth_signin_submit = Link konto
+oauth.signin.error = Der opstod en fejl under behandling af godkendelsesanmodningen. Hvis denne fejl fortsรฆtter, bedes du kontakte webstedets administrator.
+oauth.signin.error.access_denied = Godkendelsesanmodningen blev afvist.
+oauth.signin.error.temporarily_unavailable = Godkendelse mislykkedes, fordi godkendelsesserveren midlertidigt ikke er tilgรฆngelig. Prรธv venligst igen senere.
+openid_connect_submit = Forbind
+openid_connect_title = Opret forbindelse til en eksisterende konto
+openid_register_title = Opret ny konto
+openid_register_desc = Den valgte OpenID URI er ukendt. Knyt den til en ny konto her.
+disable_forgot_password_mail = Kontogendannelse er deaktiveret, fordi der ikke er konfigureret nogen e-mail. Kontakt venligst din webstedsadministrator.
+email_domain_blacklisted = Du kan ikke registrere dig med din e-mailadresse.
+authorize_application = Godkend Applikation
+authorize_redirect_notice = Du vil blive omdirigeret til %s, hvis du godkender denne applikation.
+authorize_application_created_by = Denne applikation blev oprettet af %s.
+authorize_application_description = Hvis du giver adgangen, vil den vรฆre i stand til at fรฅ adgang til og skrive til alle dine kontooplysninger, inklusive private depoter og organisationer.
+authorize_title = Tillad "%s" at fรฅ adgang til din konto?
+authorization_failed = Godkendelse mislykkedes
+password_pwned_err = Kunne ikke fuldfรธre anmodningen til HaveIBeenPwned
+last_admin = Du kan ikke fjerne den sidste admin. Der skal vรฆre mindst รฉn administrator.
+back_to_sign_in = Tilbage til Log ind
+sign_in_openid = Fortsรฆt med OpenID
+openid_signin_desc = Indtast din OpenID URI. For eksempel: alice.openid.example.org eller https://openid.example.org/alice.
+disable_forgot_password_mail_admin = Kontogendannelse er kun tilgรฆngelig, nรฅr e-mail er konfigureret. Konfigurer venligst e-mail for at aktivere kontogendannelse.
+password_pwned = Den adgangskode, du valgte, er pรฅ en liste over stjรฅlne adgangskoder , der tidligere er blevet afslรธret i forbindelse med offentlige databrud. Prรธv venligst igen med en anden adgangskode, og overvej ogsรฅ at รฆndre denne adgangskode et andet sted.
+openid_connect_desc = Den valgte OpenID URI er ukendt. Knyt den til en ny konto her.
+authorization_failed_desc = Godkendelsen mislykkedes, fordi vi har registreret en ugyldig anmodning. Kontakt venligst vedligeholderen af den app, du har forsรธgt at godkende.
+
+[mail]
+view_it_on = Se det pรฅ %s
+reply = eller svar direkte pรฅ denne e-mail
+link_not_working_do_paste = Virker linket ikke? Prรธv at kopiere og indsรฆtte det i din browsers URL-linje.
+hi_user_x = Hej %s ,
+activate_account = Aktiver venligst din konto
+activate_account.text_1 = Hej %[1]s , tak, fordi du registrerede dig hos %[2]s!
+activate_account.text_2 = Klik venligst pรฅ fรธlgende link for at aktivere din konto inden for %s :
+activate_email = Bekrรฆft din e-mailadresse
+admin.new_user.subject = Ny bruger %s har lige tilmeldt sig
+admin.new_user.user_info = Brugeroplysninger
+admin.new_user.text = Venligst klik her for at administrere denne bruger fra administrationspanelet.
+register_notify = Velkommen til %s
+register_notify.text_1 = dette er din registreringsbekrรฆftelses-e-mail for %s!
+register_notify.text_3 = Hvis en anden har lavet denne konto for dig, skal du fรธrst indstille din adgangskode .
+reset_password = Gendan din konto
+password_change.subject = Din adgangskode er blevet รฆndret
+password_change.text_1 = Adgangskoden til din konto er lige blevet รฆndret.
+primary_mail_change.subject = Din primรฆre mail er blevet รฆndret
+totp_disabled.subject = TOTP er blevet deaktiveret
+totp_disabled.text_1 = Tidsbaseret engangsadgangskode (TOTP) pรฅ din konto er netop blevet deaktiveret.
+totp_disabled.no_2fa = Der er ikke lรฆngere konfigureret andre 2FA-metoder, hvilket betyder, at det ikke lรฆngere er nรธdvendigt at logge ind pรฅ din konto hos 2FA.
+removed_security_key.subject = En sikkerhedsnรธgle er blevet fjernet
+removed_security_key.text_1 = Sikkerhedsnรธglen "%[1]s" er lige blevet fjernet fra din konto.
+account_security_caution.text_1 = Hvis dette var dig, sรฅ kan du roligt ignorere denne mail.
+totp_enrolled.subject = Du har aktiveret TOTP som 2FA-metode
+totp_enrolled.text_1.has_webauthn = Du har lige aktiveret TOTP for din konto. Dette betyder, at du for alle fremtidige login til din konto kan bruge TOTP som en 2FA-metode eller bruge en af dine sikkerhedsnรธgler.
+register_success = Registreringen lykkedes
+issue_assigned.pull = @%[1]s har tildelt dig at trรฆkke anmodning %[2]s i depotet %[3]s.
+issue_assigned.issue = @%[1]s har tildelt dig et problem %[2]s i depotet %[3]s.
+register_notify.text_2 = Du kan logge ind pรฅ din konto med dit brugernavn: %s
+primary_mail_change.text_1 = Din kontos primรฆre mail er lige blevet รฆndret til %[1]s. Det betyder, at denne e-mailadresse ikke lรฆngere vil modtage e-mail-meddelelser for din konto.
+account_security_caution.text_2 = Hvis dette ikke var dig, er din konto kompromitteret. Kontakt venligst administratorerne af dette websted.
+activate_email.text = Klik venligst pรฅ fรธlgende link for at bekrรฆfte din e-mailadresse inden for %s :
+reset_password.text = Hvis dette var dig, skal du klikke pรฅ fรธlgende link for at gendanne din konto inden for %s :
+removed_security_key.no_2fa = Der er ikke lรฆngere konfigureret andre 2FA-metoder, hvilket betyder, at det ikke lรฆngere er nรธdvendigt at logge ind pรฅ din konto hos 2FA.
+totp_enrolled.text_1.no_webauthn = Du har lige aktiveret TOTP for din konto. Det betyder, at du for alle fremtidige login til din konto skal bruge TOTP som 2FA-metode.
+issue.x_mentioned_you = @%s nรฆvnte dig:
+issue.action.force_push = %[1]s tvangs pushed %[2]s fra %[3]s til %[4]s.
+issue.action.push_1 = @%[1]s pushed %[3]d commit til %[2]s
+issue.action.push_n = @%[1]s pushed %[3]d commits til %[2]s
+issue.action.close = @%[1]s lukket #%[2]d.
+issue.action.reopen = @%[1]s genรฅbnet #%[2]d.
+issue.action.merge = @%[1]s merged #%[2]d ind i %[3]s.
+issue.action.approve = @%[1]s godkendte denne pull-anmodning.
+issue.action.reject = @%[1]s anmodede om รฆndringer pรฅ denne pull-anmodning.
+issue.action.review = @%[1]s kommenterede denne pull-anmodning.
+issue.action.review_dismissed = @%[1]s afviste den seneste kontrol fra %[2]s for denne pull-anmodning.
+issue.action.ready_for_review = @%[1]s markerede denne pull-anmodning klar til gennemgang.
+issue.action.new = @%[1]s oprettede #%[2]d.
+issue.in_tree_path = I %s:
+release.new.subject = %s i %s udgivet
+release.new.text = @%[1]s udgivet %[2]s i %[3]s
+release.title = Title: %s
+release.note = Note:
+release.downloads = Downloads:
+release.download.zip = Kildekode (ZIP)
+release.download.targz = Kildekode (TAR.GZ)
+repo.transfer.subject_to = %s รธnsker at overfรธre depotet "%s" til %s
+repo.transfer.subject_to_you = %s รธnsker at overfรธre depotet "%s" til dig
+repo.transfer.to_you = dig
+repo.transfer.body = For at acceptere eller afvise det, besรธg %s eller ignorer det.
+repo.collaborator.added.subject = %s fรธjede dig til %s som samarbejdspartner
+repo.collaborator.added.text = Du er blevet tilfรธjet som samarbejdspartner til depotet:
+team_invite.subject = %[1]s har inviteret dig til at deltage i %[2]s organisationen
+team_invite.text_1 = %[1]s har inviteret dig til at deltage i teamet %[2]s i organisationen %[3]s.
+team_invite.text_2 = Klik venligst pรฅ fรธlgende link for at blive medlem af teamet:
+team_invite.text_3 = Note: Denne invitation var beregnet til %[1]s. Hvis du ikke forventede denne invitation, kan du ignorere denne e-mail.
+
+[modal]
+yes = Ja
+no = Nej
+confirm = Bekรฆrft
+cancel = Annuller
+modify = Updatere
+
+[form]
+UserName = Brugernavn
+FullName = Fulde navn
+Description = Beskrivelse
+Pronouns = Stedord
+Biography = Biografi
+Website = Websted
+Location = Lokation
+RepoName = Depot navn
+Email = E-mailadresse
+Password = Adgangskode
+Retype = Bekrรฆft adgangskode
+PayloadUrl = Payload URL
+TeamName = Team navn
+AuthName = Autorisationsnavn
+AdminEmail = Admin email
+To = Gren navn
+AccessToken = Adgangstoken
+NewBranchName = Nyt gren navn
+CommitSummary = Commit oversigt
+CommitMessage = Commit besked
+CommitChoice = Commit valg
+TreeName = Fil sti
+Content = Indhold
+SSPISeparatorReplacement = Separator
+SSPIDefaultLanguage = Standard sprog
+require_error = ` mรฅ ikke vรฆre tomt.`
+alpha_dash_error = ` bรธr kun indeholde alfanumeriske, bindestreg ("-") og understregningstegn ("_").`
+alpha_dash_dot_error = ` bรธr kun indeholde alfanumeriske tegn, bindestreg ("-"), understregning ("_") og prik ("".").`
+git_ref_name_error = ` skal vรฆre et veludformet Git-referencenavn.`
+size_error = ` skal vรฆre stรธrrelse %s.`
+min_size_error = ` skal indeholde mindst %s tegn.`
+email_error = ` er ikke en gyldig e-mailadresse.`
+url_error = `"%s" er ikke en gyldig URL.`
+include_error = ` skal indeholde understreng "%s".`
+glob_pattern_error = ` globmรธnster er ugyldigt: %s.`
+regex_pattern_error = ` regex-mรธnster er ugyldigt: %s.`
+invalid_group_team_map_error = ` mapping er ugyldig: %s`
+unknown_error = Ukendt fejl:
+captcha_incorrect = CAPTCHA-koden er forkert.
+password_not_match = Adgangskoderne stemmer ikke overens.
+lang_select_error = Vรฆlg et sprog fra listen.
+username_been_taken = Brugernavnet er allerede taget.
+username_change_not_local_user = Ikke-lokale brugere mรฅ ikke รฆndre deres brugernavn.
+repo_name_been_taken = Depotnavnet er allerede brugt.
+repository_force_private = Tving Privat er aktiveret: private depoter kan ikke gรธres offentlige.
+repository_files_already_exist = Der findes allerede filer for dette depot. Kontakt systemadministratoren.
+repository_files_already_exist.delete = Der findes allerede filer for dette depot. Du skal slette dem.
+visit_rate_limit = Fjernbesรธg adresseret takstbegrรฆnsning.
+2fa_auth_required = Fjernbesรธg krรฆvede godkendelse af to faktorer.
+org_name_been_taken = Organisationsnavnet er allerede taget.
+team_name_been_taken = Holdnavnet er allerede taget.
+team_no_units_error = Tillad adgang til mindst รฉn depotsektion.
+email_been_used = E-mailadressen er allerede brugt.
+email_invalid = E-mailadressen er ugyldig.
+openid_been_used = OpenID-adressen "%s" er allerede brugt.
+password_complexity = Adgangskoden opfylder ikke kompleksitetskravene:
+password_lowercase_one = Mindst รฉt lille bogstav
+password_uppercase_one = Mindst รฉt stort tegn
+password_digit_one = Mindst รฉt ciffer
+enterred_invalid_repo_name = Det depotnavn, du indtastede, er forkert.
+enterred_invalid_org_name = Det organisationsnavn, du har indtastet, er forkert.
+enterred_invalid_owner_name = Det nye ejernavn er ikke gyldigt.
+enterred_invalid_password = Den adgangskode, du indtastede, er forkert.
+unset_password = Login-brugeren har ikke angivet adgangskoden.
+user_not_exist = Brugeren eksisterer ikke.
+team_not_exist = Holdet eksisterer ikke.
+last_org_owner = Du kan ikke fjerne den sidste bruger fra "ejere"-teamet. Der skal vรฆre mindst รฉn ejer for en organisation.
+duplicate_invite_to_team = Brugeren var allerede inviteret som et holdmedlem.
+organization_leave_success = Du har forladt organisationen %s.
+invalid_ssh_key = Kan ikke bekrรฆfte din SSH-nรธgle: %s
+invalid_gpg_key = Kan ikke bekrรฆfte din GPG-nรธgle: %s
+invalid_ssh_principal = Ugyldig principal: %s
+unable_verify_ssh_key = Kan ikke bekrรฆfte SSH-nรธglen, dobbelttjek den for fejl.
+auth_failed = Godkendelse mislykkedes: %v
+still_own_repo = Din konto ejer et eller flere depoter, slet eller overfรธr dem fรธrst.
+still_has_org = Din konto er medlem af en eller flere organisationer, forlad dem fรธrst.
+still_own_packages = Din konto ejer en eller flere pakker, slet dem fรธrst.
+org_still_own_packages = Denne organisation ejer stadig en eller flere pakker, slet dem fรธrst.
+target_branch_not_exist = Gren mรฅlet eksisterer ikke.
+admin_cannot_delete_self = Du kan ikke slette dig selv, nรฅr du er administrator. Fjern venligst dine administratorrettigheder fรธrst.
+required_prefix = Input skal starte med "%s"
+username_error = ` kan kun indeholde alfanumeriske tegn ("0-9","a-z","A-Z"), bindestreg ("-"), understregning ("_") og prik ("."). Det kan ikke begynde eller slutte med ikke-alfanumeriske tegn, og pรฅ hinanden fรธlgende ikke-alfanumeriske tegn er ogsรฅ forbudt.`
+max_size_error = ` mรฅ hรธjst indeholde %s tegn.`
+repository_files_already_exist.adopt_or_delete = Der findes allerede filer for dette depot. Enten adopter dem eller slet dem.
+org_still_own_repo = Denne organisation ejer stadig et eller flere depoter, slet eller overfรธr dem fรธrst.
+username_error_no_dots = ` kan kun indeholde alfanumeriske tegn ("0-9","a-z","A-Z"), bindestreg ("-") og understregning ("_"). Det kan ikke begynde eller slutte med ikke-alfanumeriske tegn, og pรฅ hinanden fรธlgende ikke-alfanumeriske tegn er ogsรฅ forbudt.`
+username_password_incorrect = Brugernavn eller adgangskode er forkert.
+repository_files_already_exist.adopt = Filer findes allerede for dette depot og kan kun adopteres.
+password_special_one = Mindst รฉt specialtegn (tegnsรฆtning, parenteser, anfรธrselstegn osv.)
+unsupported_login_type = Login typen understรธttes ikke for at slette kontoen.
+cannot_add_org_to_team = En organisation kan ikke tilfรธjes som et holdmedlem.
+must_use_public_key = Nรธglen du har angivet er en privat nรธgle. Lad vรฆre med at uploade din private nรธgle nogen steder. Brug din offentlige nรธgle i stedet.
+username_claiming_cooldown = Brugernavnet kan ikke gรธres krav pรฅ, fordi dets nedkรธlingsperiode endnu ikke er forbi. Det kan gรธres krav pรฅ %[1]s.
+email_domain_is_not_allowed = Domรฆnet for brugerens e-mailadresse %s er i konflikt med EMAIL_DOMAIN_ALLOWLIST eller EMAIL_DOMAIN_BLOCKLIST. Sรธrg for, at du har indstillet e-mailadressen korrekt.
+
+[user]
+change_avatar = Skift din avatarโฆ
+joined_on = Tilmeldte sig den %s
+repositories = Depoter
+activity = Offentlig aktivitet
+followers.title.one = Fรธlger
+followers.title.few = Fรธlgere
+following.title.one = Fรธlger
+following.title.few = Fรธlger
+followers_one = %d fรธlger
+followers_few = %d fรธlgere
+following_one = %d fรธlger
+following_few = %d fรธlger
+follow = Fรธlg
+unfollow = Fjern fรธlg
+block_user = Bloker bruger
+block_user.detail = Bemรฆrk venligst, at blokering af en bruger har andre effekter, sรฅsom:
+block_user.detail_1 = I vil holde op med at fรธlge hinanden og vil ikke vรฆre i stand til at fรธlge hinanden.
+block_user.detail_2 = Denne bruger vil ikke vรฆre i stand til at interagere med de depoter, du ejer, eller de problemer og kommentarer, du har oprettet.
+block_user.detail_3 = I vil ikke vรฆre i stand til at tilfรธje hinanden som depot-samarbejdspartnere.
+follow_blocked_user = Du kan ikke fรธlge denne bruger, fordi du har blokeret denne bruger, eller denne bruger har blokeret dig.
+starred = Stjernemarkerede depoter
+watched = Overvรฅgede depoter
+code = Kode
+overview = Oversigt
+block = Block
+user_bio = Biografi
+email_visibility.limited = Din e-mailadresse er synlig for alle godkendte brugere
+show_on_map = Vis dette sted pรฅ et kort
+settings = Brugerindstillinger
+public_activity.visibility_hint.admin_public = Denne aktivitet er synlig for alle, men som administrator kan du ogsรฅ se interaktioner i private rum.
+public_activity.visibility_hint.self_private = Din aktivitet er kun synlig for dig og instans-administratorerne. Konfigurer .
+public_activity.visibility_hint.admin_private = Denne aktivitet er synlig for dig, fordi du er administrator, men brugeren รธnsker, at den forbliver privat.
+form.name_reserved = Brugernavnet "%s" er reserveret.
+form.name_pattern_not_allowed = Mรธnsteret "%s" er ikke tilladt i et brugernavn.
+form.name_chars_not_allowed = Brugernavnet "%s" indeholder ugyldige tegn.
+unblock = Fjern blokering
+projects = Projekter
+disabled_public_activity = Denne bruger har deaktiveret den offentlige synlighed af aktiviteten.
+public_activity.visibility_hint.self_public = Din aktivitet er synlig for alle, undtagen interaktioner i private rum. Konfigurer .
+public_activity.visibility_hint.self_private_profile = Din aktivitet er kun synlig for dig og instans-administratorerne, fordi din profil er privat. Konfigurer .
+
+[settings]
+profile = Profil
+account = Konto
+appearance = Udseende
+password = Adgangskode
+security = Sikkerhed
+avatar = Avatar
+ssh_gpg_keys = SSH / GPG nรธgler
+applications = Applikationer
+orgs = Organisationer
+repos = Depoter
+delete = Slet konto
+twofa = To-faktor-godkendelse (TOTP)
+organization = Organisationer
+uid = UID
+webauthn = To-faktor-godkendelse (sikkerhedsnรธgler)
+blocked_users = Blokerede brugere
+public_profile = Offentlig profil
+location_placeholder = Del din omtrentlige placering med andre
+password_username_disabled = Ikke-lokale brugere mรฅ ikke รฆndre deres brugernavn. Kontakt venligst din webstedsadministrator for flere detaljer.
+full_name = Fulde navn
+website = Websted
+location = Lokation
+pronouns = Stedord
+pronouns_custom = Brugerdefineret
+pronouns_unspecified = Uspecificeret
+update_theme = Skift tema
+update_language = Skift sprog
+update_language_success = Sproget er blevet opdateret.
+update_profile_success = Din profil er blevet opdateret.
+change_username = Dit brugernavn er blevet รฆndret.
+change_username_redirect_prompt = Det gamle brugernavn vil omdirigere, indtil nogen gรธr krav pรฅ det.
+continue = Fortsรฆt
+cancel = Annuller
+language = Sprog
+language.title = Standard sprog
+language.description = Dette sprog gemmes pรฅ din konto og bruges som standard, nรฅr du logger ind.
+ui = Tema
+additional_repo_units_hint = Foreslรฅ at aktivere yderligere depotenheder
+additional_repo_units_hint_description = Vis et "Aktiver mere"-tip for depoter, der ikke har alle tilgรฆngelige enheder aktiveret.
+update_hints = Opdater tips
+hints = Tips
+update_hints_success = Tips er blevet opdateret.
+hidden_comment_types = Skjulte kommentartyper
+hidden_comment_types.ref_tooltip = Kommentarer, hvor dette problem blev refereret fra en anden problem/commit/โฆ
+hidden_comment_types.issue_ref_tooltip = Kommentarer, hvor brugeren รฆndrer grenen/taget, der er knyttet til problemet
+comment_type_group_reference = Reference
+comment_type_group_label = Etiket
+comment_type_group_milestone = Milepรฆl
+comment_type_group_assignee = Udpegningsmodtager
+comment_type_group_title = Title
+comment_type_group_branch = Gren
+comment_type_group_time_tracking = Tidsregistrering
+comment_type_group_deadline = Tidsfrist
+comment_type_group_dependency = Dependency
+comment_type_group_lock = Lรฅs status
+comment_type_group_review_request = Gennemgรฅ anmodning
+comment_type_group_pull_request_push = Tilfรธjet commits
+comment_type_group_project = Projekt
+comment_type_group_issue_ref = Problem henvisning
+privacy = Privatliv
+keep_activity_private = Skjul aktivitet fra profilsiden
+lookup_avatar_by_mail = Slรฅ avatar up efter e-mailadresse
+enable_custom_avatar = Brug tilpasset avatar
+delete_current_avatar = Slet nuvรฆrende avatar
+uploaded_avatar_not_a_image = Den uploadede fil er ikke et billede.
+update_avatar_success = Din avatar er blevet opdateret.
+update_user_avatar_success = Brugerens avatar er blevet opdateret.
+change_password = Skift adgangskode
+update_password = Opdater adgangskode
+old_password = Nuvรฆrende adgangskode
+new_password = Ny adgangskode
+retype_new_password = Bekrรฆft ny adgangskode
+password_incorrect = Den aktuelle adgangskode er forkert.
+password_change_disabled = Ikke-lokale brugere kan ikke opdatere deres adgangskode via Forgejo-webgrรฆnsefladen.
+manage_emails = Administrer e-mailadresser
+manage_themes = Standard tema
+manage_openid = OpenID-adresser
+theme_desc = Dette tema vil blive brugt til webgrรฆnsefladen, nรฅr du er logget ind.
+primary = Primรฆr
+activated = Aktiveret
+requires_activation = Krรฆver aktivering
+primary_email = Gรธr til primรฆr
+activate_email = Send aktivering
+activations_pending = Aktiveringer afventer
+can_not_add_email_activations_pending = Der er en afventende aktivering, prรธv igen om et par minutter, hvis du vil tilfรธje en ny e-mail.
+delete_email = Slet
+email_deletion = Fjern e-mailadresse
+email_deletion_success = E-mailadressen er blevet fjernet.
+theme_update_success = Dit tema blev opdateret.
+theme_update_error = Det valgte tema findes ikke.
+openid_deletion = Fjern OpenID-adresse
+openid_deletion_desc = Fjernelse af denne OpenID-adresse fra din konto vil forhindre dig i at logge ind med den. Fortsรฆtte?
+openid_deletion_success = OpenID-adressen er blevet fjernet.
+add_new_email = Tilfรธj e-mailadresse
+add_new_openid = Tilfรธj ny OpenID URI
+language.localization_project = Hjรฆlp os med at oversรฆtte Forgejo til dit sprog! Fรฅ flere oplysninger .
+update_language_not_found = Sprog "%s" er ikke tilgรฆngeligt.
+hidden_comment_types_description = Kommentartyper, der er markeret her, vil ikke blive vist pรฅ problemsider. Hvis du f.eks. markerer "Etiket", fjernes alle " tilfรธjede/fjernede " kommentarer.
+update_profile = Opdater profil
+change_username_prompt = Note: รndring af dit brugernavn รฆndrer ogsรฅ din konto-URL.
+biography_placeholder = Fortรฆl andre lidt om dig selv! (Markdown understรธttes)
+profile_desc = Om dig
+saved_successfully = Dine indstillinger blev gemt.
+keep_activity_private.description = Din offentlige aktivitet vil kun vรฆre synlig for dig og instans-administratorerne.
+email_desc = Din primรฆre e-mailadresse vil blive brugt til meddelelser, gendannelse af adgangskode og, forudsat at den ikke er skjult, webbaserede Git-operationer.
+uploaded_avatar_is_too_big = Den uploadede filstรธrrelse (%d KiB) overstiger den maksimale stรธrrelse (%d KiB).
+email_deletion_desc = E-mailadressen og relaterede oplysninger vil blive fjernet fra din konto. Git commits af denne e-mailadresse forbliver uรฆndret. Fortsรฆtte?
+choose_new_avatar = Vรฆlg ny avatar
+update_avatar = Opdater avatar
+change_password_success = Din adgangskode er blevet opdateret. Fra nu af skal du bruge din nye adgangskode til at logge ind.
+add_email = Tilfรธj e-mailadresse
+add_openid = Tilfรธj OpenID URI
+add_email_confirmation_sent = En bekrรฆftelses-e-mail er blevet sendt til "%s". For at bekrรฆfte din e-mailadresse, tjek venligst din indbakke og fรธlg det medfรธlgende link inden for de nรฆste %s.
+add_openid_success = Den nye OpenID-adresse er blevet tilfรธjet.
+keep_email_private = Skjul e-mailadresse
+openid_desc = OpenID lader dig uddelegere godkendelse til en ekstern udbyder.
+manage_ssh_keys = Administrer SSH-nรธgler
+manage_ssh_principals = Administrer SSH-certifikatprincippere
+manage_gpg_keys = Administrer GPG-nรธgler
+add_key = Tilfรธj nรธgle
+ssh_desc = Disse offentlige SSH-nรธgler er knyttet til din konto. De tilsvarende private nรธgler giver fuld adgang til dine depoter. SSH-nรธgler, der er blevet bekrรฆftet, kan bruges til at bekrรฆfte SSH-signerede Git-commits.
+principal_desc = Disse SSH-certifikatprincipper er knyttet til din konto og giver fuld adgang til dine depoter.
+ssh_helper = Har du brug for hjรฆlp? Se vejledningen til at oprette dine egne SSH-nรธgler eller lรธse almindelige problemer a> du kan stรธde pรฅ nรฅr du bruger SSH.
+gpg_helper = Har du brug for hjรฆlp? Se vejledningen om GPG .
+key_content_gpg_placeholder = Begynder med "-----BEGIN PGP PUBLIC KEY BLOCK-----"
+add_new_principal = Tilfรธj principal
+ssh_key_been_used = Denne SSH-nรธgle er allerede blevet tilfรธjet til serveren.
+ssh_key_name_used = En SSH-nรธgle med samme navn findes allerede pรฅ din konto.
+ssh_principal_been_used = Denne principal er allerede blevet tilfรธjet til serveren.
+gpg_key_id_used = Der findes allerede en offentlig GPG-nรธgle med samme id.
+gpg_no_key_email_found = Denne GPG-nรธgle matcher ikke nogen aktiveret e-mail-adresse tilknyttet din konto. Det kan stadig tilfรธjes, hvis du underskriver det medfรธlgende token.
+gpg_key_matched_identities = Matchede identiteter:
+gpg_key_verified = Verificeret nรธgle
+gpg_key_verified_long = Nรธglen er blevet bekrรฆftet med et token og kan bruges til at bekrรฆfte commits, der matcher alle aktiverede e-mailadresser for denne bruger ud over eventuelle matchede identiteter for denne nรธgle.
+gpg_key_verify = Bekrรฆft
+gpg_invalid_token_signature = Den medfรธlgende GPG-nรธgle, signatur og token stemmer ikke overens, eller token er forรฆldet.
+gpg_token_required = Du skal angive en underskrift for nedenstรฅende token
+gpg_token = Token
+gpg_token_signature = Pansret GPG-signatur
+key_signature_gpg_placeholder = Begynder med "-----BEGIN PGP SIGNATURE-----"
+verify_gpg_key_success = GPG-nรธglen "%s" er blevet bekrรฆftet.
+ssh_key_verified = Verificeret nรธgle
+ssh_token_required = Du skal angive en underskrift for nedenstรฅende token
+ssh_token = Token
+ssh_token_help = Du kan generere en signatur ved at bruge:
+ssh_token_signature = Pansret SSH signatur
+key_signature_ssh_placeholder = Begynder med "-----BEGIN SSH SIGNATURE-----"
+verify_ssh_key_success = SSH-nรธglen "%s" er blevet bekrรฆftet.
+subkeys = Undernรธgler
+key_name = Nรธglenavn
+key_id = Nรธgle ID
+key_content = Indhold
+principal_content = Indhold
+add_key_success = SSH-nรธglen "%s" er blevet tilfรธjet.
+add_principal_success = SSH-certifikatprincippet "%s" er blevet tilfรธjet.
+delete_key = Slet
+ssh_key_deletion = Slet SSH-nรธgle
+gpg_key_deletion = Slet GPG-nรธglen
+ssh_principal_deletion = Slet SSH Certificate Principal
+gpg_key_deletion_desc = Fjernelse af en GPG-nรธgle afbekrรฆfter commits, der er underskrevet af den. Fortsรฆtte?
+ssh_principal_deletion_desc = Fjernelse af en SSH Certificate Principal tilbagekalder dens adgang til din konto. Fortsรฆtte?
+ssh_key_deletion_success = SSH-nรธglen er blevet fjernet.
+ssh_principal_deletion_success = Principal er blevet fjernet.
+added_on = Tilfรธjet den %s
+valid_until_date = Gyldig indtil %s
+last_used = Sidst brugt pรฅ
+no_activity = Ingen nylig aktivitet
+can_read_info = Lรฆs
+can_write_info = Skriv
+token_state_desc = Dette token er blevet brugt inden for de sidste 7 dage
+principal_state_desc = Denne principal er blevet brugt inden for de sidste 7 dage
+show_openid = Vis pรฅ profil
+hide_openid = Skjul fra profil
+ssh_externally_managed = Denne SSH-nรธgle administreres eksternt for denne bruger
+manage_access_token = Adgangstoken
+generate_new_token = Generer nyt token
+tokens_desc = Disse tokens giver adgang til din konto ved hjรฆlp af Forgejo API.
+token_name = Token navn
+generate_token = Generer token
+generate_token_success = Dit nye token er blevet genereret. Kopier den nu, da den ikke vises igen.
+delete_token = Slet
+access_token_deletion = Slet adgangstoken
+access_token_deletion_desc = Sletning af et token vil tilbagekalde adgangen til din konto for applikationer, der bruger den. Dette kan ikke fortrydes. Fortsรฆtte?
+repo_and_org_access = Depot og organisationsadgang
+permissions_public_only = Kun offentlig
+permissions_access_all = Alle (offentlige, private og begrรฆnsede)
+select_permissions = Vรฆlg tilladelser
+permission_no_access = Ingen adgang
+permission_read = Lรฆs
+permission_write = Lรฆs og skriv
+permissions_list = Tilladelser:
+manage_oauth2_applications = Administrer OAuth2-applikationer
+edit_oauth2_application = Rediger OAuth2-applikation
+add_email_success = Den nye e-mailadresse er blevet tilfรธjet.
+key_content_ssh_placeholder = Begynder med "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", eller "sk-ssh-ed25519@openssh.com"
+gpg_key_matched_identities_long = De indlejrede identiteter i denne nรธgle matcher de fรธlgende aktiverede e-mailadresser for denne bruger. Commits, der matcher disse e-mailadresser, kan bekrรฆftes med denne nรธgle.
+gpg_key_deletion_success = GPG-nรธglen er blevet fjernet.
+email_preference_set_success = E-mail-prรฆference er blevet indstillet.
+keep_email_private_popup = Din e-mailadresse vil ikke blive vist pรฅ din profil og vil ikke vรฆre standard for commits foretaget via webgrรฆnsefladen, som f.eks. filupload, redigeringer og merge commits. I stedet kan en speciel adresse %s bruges til at linke commits til din konto. Denne mulighed vil ikke pรฅvirke eksisterende commits.
+gpg_desc = Disse offentlige GPG-nรธgler er knyttet til din konto og bruges til at bekrรฆfte dine commits. Opbevar dine private nรธgler sikkert, da de giver dig mulighed for at underskrive commits med din identitet.
+gpg_token_help = Du kan generere en signatur ved at bruge:
+ssh_key_verified_long = Nรธglen er blevet bekrรฆftet med et token og kan bruges til at bekrรฆfte commits, der matcher enhver aktiveret e-mail-adresse for denne bruger.
+ssh_key_deletion_desc = Fjernelse af en SSH-nรธgle tilbagekalder dens adgang til din konto. Fortsรฆtte?
+ssh_signonly = SSH er i รธjeblikket deaktiveret, sรฅ disse nรธgler bruges kun til bekrรฆftelse af commit signatur.
+at_least_one_permission = Du skal vรฆlge mindst รฉn tilladelse for at oprette et token
+ssh_key_verify = Bekrรฆft
+ssh_invalid_token_signature = Den angivne SSH-nรธgle, signatur eller token stemmer ikke overens, eller token er forรฆldet.
+add_gpg_key_success = GPG-nรธglen "%s" er blevet tilfรธjet.
+valid_forever = Gyldig for evigt
+ssh_disabled = SSH er deaktiveret
+key_state_desc = Denne nรธgle er blevet brugt inden for de sidste 7 dage
+generate_token_name_duplicate = %s er allerede blevet brugt som applikationsnavn. Brug venligst en ny.
+delete_token_success = Tokenet er blevet slettet. Applikationer, der bruger den, har ikke lรฆngere adgang til din konto.
+access_token_desc = Valgte tokentilladelser begrรฆnser kun autorisation til de tilsvarende API -ruter. Lรฆs dokumentationen for at fรฅ flere oplysninger.
+oauth2_applications_desc = OAuth2-applikationer gรธr det muligt for din tredjepartsapplikation at godkende brugere sikkert i denne Forgejo-instans.
+remove_oauth2_application = Slet OAuth2-applikation
+remove_oauth2_application_desc = Sletning af en OAuth2-applikation vil tilbagekalde adgangen til alle signerede adgangstokens. Vil du fortsรฆtte?
+remove_oauth2_application_success = Ansรธgningen er blevet slettet.
+create_oauth2_application = Opret en ny OAuth2-applikation
+create_oauth2_application_button = Opret applikation
+create_oauth2_application_success = Du har oprettet en ny OAuth2-applikation.
+update_oauth2_application_success = Du har opdateret OAuth2-applikationen.
+oauth2_application_name = Applikationsnavn
+oauth2_redirect_uris = Omdiriger URI'er. Brug venligst en ny linje for hver URI.
+save_application = Gem
+oauth2_client_id = Klient ID
+oauth2_client_secret = Klient hemmelighed
+oauth2_regenerate_secret = Genskab hemmeligheden
+oauth2_regenerate_secret_hint = Har du mistet din hemmelighed?
+oauth2_client_secret_hint = Hemmeligheden vil ikke blive vist igen, nรฅr du forlader eller opdaterer denne side. Sรธrg for, at du har gemt den.
+oauth2_application_edit = Redigere
+oauth2_confidential_client = Fortrolig klient. Vรฆlg for apps, der holder hemmeligheden fortrolig, sรฅsom webapps. Vรฆlg ikke for indbyggede apps, herunder desktop- og mobilapps.
+oauth2_application_create_description = OAuth2-applikationer giver din tredjepartsapplikation adgang til brugerkonti pรฅ denne instans.
+oauth2_application_remove_description = Fjernelse af en OAuth2-applikation forhindrer den i at fรฅ adgang til autoriserede brugerkonti pรฅ denne instans. Vil du fortsรฆtte?
+authorized_oauth2_applications = Autoriserede OAuth2-applikationer
+revoke_key = Tilbagekald
+revoke_oauth2_grant = Tilbagekald adgang
+revoke_oauth2_grant_description = Tilbagekaldelse af adgang for denne tredjepartsapplikation forhindrer denne applikation i at fรฅ adgang til dine data. Er du sikker?
+revoke_oauth2_grant_success = Adgangen blev tilbagekaldt.
+twofa_desc = For at beskytte din konto mod adgangskodetyveri kan du bruge en smartphone eller en anden enhed til at modtage tidsbaserede engangsadgangskoder ("TOTP").
+twofa_is_enrolled = Din konto er i รธjeblikket tilmeldt til tofaktorgodkendelse.
+twofa_not_enrolled = Din konto er i รธjeblikket ikke tilmeldt to-faktor-godkendelse.
+twofa_disable = Deaktiver to-faktor-godkendelse
+twofa_scratch_token_regenerate = Gendan engangsgendannelsesnรธgle
+twofa_scratch_token_regenerated = Din gendannelsesnรธgle til engangsbrug er nu %s. Opbevar det et sikkert sted, da det ikke vil blive vist igen.
+twofa_enroll = Tilmeld dig to-faktor-godkendelse
+twofa_recovery_tip = Hvis du mister din enhed, vil du vรฆre i stand til at bruge en gendannelsesnรธgle til engangsbrug for at fรฅ adgang til din konto igen.
+oauth2_application_locked = Forgejo forhรฅndsregistrerer nogle OAuth2-applikationer ved opstart, hvis det er aktiveret i config. For at forhindre uventet adfรฆrd kan disse hverken redigeres eller fjernes. Se venligst OAuth2-dokumentationen for at fรฅ flere oplysninger.
+authorized_oauth2_applications_description = Du har givet adgang til din personlige Forgejo-konto til disse tredjepartsapplikationer. Tilbagekald venligst adgangen for applikationer, der ikke lรฆngere er i brug.
+manage_account_links = Tilknyttede konti
+manage_account_links_desc = Disse eksterne konti er knyttet til din Forgejo-konto.
+link_account = Link konto
+remove_account_link = Slet linket konto
+remove_account_link_desc = Fjernelse af en tilknyttet konto vil tilbagekalde dens adgang til din Forgejo-konto. Vil du fortsรฆtte?
+remove_account_link_success = Den tilknyttede konto er blevet fjernet.
+twofa_disable_note = Du kan deaktivere to-faktor-godkendelse, hvis det er nรธdvendigt.
+twofa_disable_desc = Deaktivering af to-faktor-godkendelse vil gรธre din konto mindre sikker. Vil du fortsรฆtte?
+regenerate_scratch_token_desc = Hvis du har forlagt din gendannelsesnรธgle eller allerede har brugt den til at logge pรฅ, kan du nulstille den her.
+twofa_disabled = To-faktor-godkendelse er blevet deaktiveret.
+scan_this_image = Scan dette billede med din godkendelsesapplikation:
+then_enter_passcode = Og indtast adgangskoden vist i applikationen:
+passcode_invalid = Passkoden er forkert. Prรธv igen.
+twofa_enrolled = Din konto er blevet tilmeldt. Opbevar din gendannelsesnรธgle til engangsbrug (%s) et sikkert sted, da den ikke vil blive vist igen.
+twofa_failed_get_secret = Det lykkedes ikke at fรฅ hemmelig-koden.
+or_enter_secret = Eller indtast hemmelig-koden: %s
+webauthn_desc = Sikkerhedsnรธgler er hardwareenheder, der indeholder kryptografiske nรธgler. De kan bruges til to-faktor-godkendelse. Sikkerhedsnรธgler skal understรธtte WebAuthn Authenticator -standarden.
+webauthn_register_key = Tilfรธj sikkerhedsnรธgle
+webauthn_nickname = Kaldenavn
+webauthn_delete_key = Slet sikkerhedsnรธglen
+webauthn_delete_key_desc = Hvis du sletter en sikkerhedsnรธgle, kan du ikke lรฆngere logge ind med den. Vil du fortsรฆtte?
+webauthn_key_loss_warning = Hvis du mister dine sikkerhedsnรธgler, mister du adgangen til din konto.
+webauthn_alternative_tip = Du vil mรฅske gerne konfigurere en ekstra godkendelsesmetode.
+hooks.desc = Tilfรธj webhooks, som vil blive udlรธst for alle depoter , som du ejer.
+orgs_none = Du er ikke medlem af nogen organisationer.
+repos_none = Du ejer ikke nogen depoter.
+delete_account = Slet din konto
+delete_prompt = Denne handling vil permanent slette din brugerkonto. Det KAN IKKE fortrydes.
+confirm_delete_account = Bekrรฆft sletning
+email_notifications.enable = Aktiver e-mail-notifikationer
+email_notifications.onmention = Kun e-mail ved omtale
+email_notifications.disable = Deaktiver e-mail-notifikationer
+email_notifications.submit = Indstil e-mail-prรฆference
+email_notifications.andyourown = Og dine egne notifikationer
+visibility = Brugersynlighed
+visibility.public = Offentlig
+visibility.public_tooltip = Synlig for alle
+visibility.limited_tooltip = Kun synlig for brugere, der er logget ind
+visibility.private = Privat
+blocked_since = Blokeret siden %s
+user_unblock_success = Blokeringen af brugeren er blevet fjernet.
+user_block_success = Brugeren er blevet blokeret.
+blocked_users_none = Der er ingen blokerede brugere.
+visibility.limited = Begrรฆnset
+delete_account_desc = Er du sikker pรฅ, at du vil slette denne brugerkonto permanent?
+visibility.private_tooltip = Kun synlig for medlemmer af organisationer, du har tilsluttet dig
+delete_with_all_comments = Din konto er yngre end %s. For at undgรฅ spรธgelseskommentarer slettes alle problemer/PR-kommentarer med kontoen.
+delete_account_title = Slet brugerkonto
+user_block_yourself = Du kan ikke blokere dig selv.
+pronouns_custom_label = Brugerdefinerede stedord
+change_username_redirect_prompt.with_cooldown.one = Det gamle brugernavn vil vรฆre tilgรฆngeligt for alle efter en nedkรธlingsperiode pรฅ %[1]d dag, du kan stadig krรฆve det gamle brugernavn tilbage i nedkรธlingsperioden.
+change_username_redirect_prompt.with_cooldown.few = Det gamle brugernavn vil vรฆre tilgรฆngeligt for alle efter en nedkรธlingsperiode pรฅ %[1]d dage, du kan stadig krรฆve det gamle brugernavn tilbage i nedkรธlingsperioden.
+keep_pronouns_private = Vis kun stedord til godkendte brugere
+keep_pronouns_private.description = Dette vil skjule dine stedord for besรธgende, der ikke er logget ind.
+quota.applies_to_user = Fรธlgende kvoteregler gรฆlder for din konto
+quota.rule.exceeded.helper = Den samlede stรธrrelse af objekter for denne regel har overskredet kvoten.
+storage_overview = Opbevaringsoversigt
+quota = Kvote
+quota.applies_to_org = Fรธlgende kontingentregler gรฆlder for denne organisation
+quota.rule.exceeded = Oversteget
+quota.rule.no_limit = Ubegrรฆnset
+quota.sizes.all = Alle
+quota.sizes.repos.all = Depoter
+quota.sizes.repos.public = Offentlige depoter
+quota.sizes.repos.private = Private depoter
+quota.sizes.git.all = Git indhold
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.all = Aktiver
+quota.sizes.assets.attachments.all = Vedhรฆftede filer
+quota.sizes.assets.attachments.issues = Problemets vedhรฆftede filer
+quota.sizes.assets.attachments.releases = Udgivelsens vedhรฆftede filer
+quota.sizes.assets.artifacts = Artefakter
+quota.sizes.assets.packages.all = Pakker
+quota.sizes.wiki = Wiki
+regenerate_token = Regenerer
+regenerate_token_success = Tokenet er blevet regenereret. Programmer, der bruger det, har ikke lรฆngere adgang til din konto og skal opdateres med det nye token.
+access_token_regeneration = Regenerer adgangstoken
+access_token_regeneration_desc = Regenerering af et token vil tilbagekalde adgangen til din konto for programmer, der bruger den. Dette kan ikke fortrydes. Vil du fortsรฆtte?
+
+[repo]
+rss.must_be_on_branch = Du skal vรฆre pรฅ en gren for at have et RSS-feed.
+admin.manage_flags = Administrer flag
+admin.enabled_flags = Flag aktiveret for depotet:
+admin.update_flags = Opdater flag
+admin.flags_replaced = Depot flag udskiftet
+owner = Ejer
+owner_helper = Nogle organisationer vises muligvis ikke i dropdown-menuen pรฅ grund af en maksimal grรฆnse for optรฆlling af depoter.
+repo_name = Depot navn
+repo_name_helper = Gode depotnavne bruger korte, mindevรฆrdige og unikke nรธgleord.
+repo_size = Depotstรธrrelse
+size_format = %[1]s: %[2]s, %[3]s: %[4]s
+template = Skabelon
+template_select = Vรฆlg en skabelon
+template_helper = Gรธr depot til en skabelon
+visibility = Synlighed
+visibility_helper = Gรธr depotet privat
+visibility_helper_forced = Din webstedsadministrator tvinger nye depoter til at vรฆre private.
+clone_helper = Har du brug for hjรฆlp til kloning? Besรธg Hjรฆlp .
+fork_repo = Fork depot
+fork_from = Fork fra
+already_forked = Du har allerede forked %s
+fork_to_different_account = Fork til en anden konto
+fork_branch = Gren, der skal klones til fork
+all_branches = Alle grene
+fork_no_valid_owners = Dette depot kan ikke blive forked, fordi der ikke er nogen gyldige ejere.
+use_template = Brug denne skabelon
+open_with_editor = ร
ben med %s
+download_zip = Download ZIP
+download_tar = Download TAR.GZ
+download_bundle = Download BUNDLE
+generate_repo = Generer depot
+generate_from = Generer fra
+repo_desc = Beskrivelse
+repo_lang = Sprog
+repo_gitignore_helper = Vรฆlg .gitignore skabeloner
+issue_labels = Etiketter
+issue_labels_helper = Vรฆlg et etiketsรฆt
+license = Licens
+object_format = Objektformat
+object_format_helper = Objektformatet for depotet. Kan ikke รฆndres senere. SHA1 er den mest kompatible.
+readme = LรSMIG
+readme_helper = Vรฆlg en LรSMIG-filskabelon
+readme_helper_desc = Dette er stedet, hvor du kan skrive en komplet beskrivelse af dit projekt.
+auto_init = Initialiser depot
+create_repo = Opret depot
+default_branch = Standard gren
+default_branch_label = standard
+default_branch_helper = Standardgrenen er basegrenen for pull-anmodninger og kode-commits.
+mirror_prune = Prune
+mirror_prune_desc = Slet forรฆldede referencer til fjernsporing
+mirror_interval = Spejlinterval (gyldige tidsenheder er "h", "m", "s"). 0 for at deaktivere periodisk synkronisering. (Minimumsinterval: %s)
+mirror_interval_invalid = Spejlintervallet er ikke gyldigt.
+mirror_use_ssh.text = Brug SSH-godkendelse
+mirror_use_ssh.not_available = SSH-godkendelse er ikke tilgรฆngelig.
+mirror_denied_combination = Kan ikke bruge offentlig nรธgle- og adgangskodebaseret godkendelse i kombination.
+mirror_sync = synkroniseret
+mirror_sync_on_commit = Synkroniser nรฅr commits er pushed
+mirror_address = Klon fra URL
+mirror_address_desc = Angiv eventuelle nรธdvendige legitimationsoplysninger i sektionen Autorisation.
+mirror_address_url_invalid = Den angivne URL er ugyldig. Du skal escape alle komponenter i URL'en korrekt.
+mirror_lfs = Stort fillager (LFS)
+mirror_lfs_desc = Aktiver spejling af LFS-data.
+mirror_lfs_endpoint = LFS-endepunkt
+mirror_last_synced = Sidst synkroniseret
+mirror_password_placeholder = (Uรฆndret)
+mirror_password_blank_placeholder = (Usat)
+mirror_password_help = Skift brugernavn for at slette en gemt adgangskode.
+watchers = Observatรธrer
+stargazers = Stjernekiggere
+stars_remove_warning = Dette vil fjerne alle stjerner fra dette depot.
+forks = Forks
+stars = Stjerner
+reactions_more = og %d mere
+unit_disabled = Webstedsadministratoren har deaktiveret denne depotsektion.
+adopt_preexisting_label = Adopter filer
+adopt_preexisting = Adopter allerede eksisterende filer
+adopt_preexisting_content = Opret depot fra %s
+adopt_preexisting_success = Adopterede filer og oprettet depot fra %s
+delete_preexisting_label = Slet
+delete_preexisting = Slet allerede eksisterende filer
+delete_preexisting_content = Slet filer i %s
+delete_preexisting_success = Slettede ikke-adopterede filer i %s
+blame_prior = Se skylden fรธr denne รฆndring
+blame.ignore_revs.failed = Kunne ikke ignorere revisioner i .git-blame-ignore-revs .
+author_search_tooltip = Viser maksimalt 30 brugere
+tree_path_not_found_commit = Sti %[1]s eksisterer ikke i commit %[2]s
+tree_path_not_found_branch = Sti %[1]s findes ikke i gren %[2]s
+tree_path_not_found_tag = Sti %[1]s findes ikke i tag %[2]s
+transfer.accept = Accepter overfรธrsel
+transfer.accept_desc = Overfรธr til "%s"
+transfer.reject = Afvis overfรธrsel
+transfer.no_permission_to_accept = Du har ikke tilladelse til at acceptere denne overfรธrsel.
+transfer.no_permission_to_reject = Du har ikke tilladelse til at afvise denne overfรธrsel.
+desc.private = Privat
+desc.public = Offentlig
+desc.template = Skabelon
+desc.archived = Arkiveret
+desc.sha256 = SHA256
+template.items = Skabelonelementer
+template.git_content = Git-indhold (standardgren)
+template.git_hooks = Git hooks
+template.webhooks = Webhooks
+template.topics = Emner
+template.avatar = Avatar
+template.issue_labels = Problem etiketter
+template.one_item = Skal vรฆlge mindst รฉt skabelonelement
+template.invalid = Skal vรฆlge et skabelondepot
+admin.failed_to_replace_flags = Det lykkedes ikke at erstatte depot flag
+repo_desc_helper = Indtast en kort beskrivelse (valgfrit)
+mirror_use_ssh.helper = Forgejo vil spejle depotet via Git over SSH og oprette et nรธglepar til dig, nรฅr du vรฆlger denne mulighed. Du skal sikre dig, at den genererede offentlige nรธgle er autoriseret til at pushe til destinationsdepotet. Du kan ikke bruge adgangskodebaseret godkendelse, nรฅr du vรฆlger dette.
+adopt_search = Indtast brugernavn for at sรธge efter ikke-adopterede depoterโฆ (lad stรฅ tomt for at finde alle)
+fork_visibility_helper = Synligheden af et forked depot kan ikke รฆndres.
+license_helper = Vรฆlg en licensfil
+language_other = Andre
+desc.internal = Internt
+visibility_description = Kun ejeren eller organisationens medlemmer, hvis de har rettigheder, vil kunne se det.
+new_repo_helper = Et depot indeholder alle projektfiler, inklusive revisionshistorik. Er du allerede vรฆrt for en et andet sted? Migrer depot .
+visibility_fork_helper = (Hvis du รฆndrer dette, vil det pรฅvirke synligheden af alle forks.)
+mirror_lfs_endpoint_desc = Synkronisering vil forsรธge at bruge klon-url'en til at bestemme LFS-serveren . Du kan ogsรฅ angive et brugerdefineret endepunkt, hvis depots LFS-data er gemt et andet sted.
+template_description = Skabelondepoter lader brugere generere nye depoter med samme mappestruktur, filer og valgfri indstillinger.
+repo_gitignore_helper_desc = Vรฆlg, hvilke filer der ikke skal spores, fra en liste over skabeloner til almindelige sprog. Typiske artefakter genereret af hvert sprogs byggevรฆrktรธjer er inkluderet pรฅ .gitignore som standard.
+license_helper_desc = En licens styrer, hvad andre kan og ikke kan gรธre med din kode. Er du i tvivl om, hvilken der passer til dit projekt? Se Vรฆlg en licens .
+template.git_hooks_tooltip = Du er i รธjeblikket ikke i stand til at รฆndre eller fjerne Git hooks, nรฅr fรธrst de er tilfรธjet. Vรฆlg kun dette, hvis du har tillid til skabelondepotet.
+mirror_public_key = Offentlig SSH-nรธgle
+blame.ignore_revs = Ignorerer revisioner i .git-blame-ignore-revs . Klik her for at omgรฅ og se den normale skyldvisning.
+mirror_address_protocol_invalid = Den angivne URL er ugyldig. Kun http(s):// eller git:// placeringer kan bruges til spejling.
+transfer.reject_desc = Annuller overfรธrsel til "%s"
+archive.title = Dette depot er arkiveret. Du kan se filer og klone dem, men du kan ikke pushe eller รฅbne problemer eller pull-anmodninger.
+archive.title_date = Dette depot er blevet arkiveret pรฅ %s. Du kan se filer og klone dem, men du kan ikke pushe eller รฅbne problemer eller pull-anmodninger.
+archive.issue.nocomment = Denne depot er arkiveret. Du kan ikke kommentere pรฅ problemer.
+form.reach_limit_of_creation_1 = Ejeren har allerede nรฅet grรฆnsen pรฅ %d depot.
+form.reach_limit_of_creation_n = Ejeren har allerede nรฅet grรฆnsen pรฅ %d depoterne.
+form.name_reserved = Depotnavnet "%s" er reserveret.
+form.string_too_long = Den givne streng er lรฆngere end %d tegn.
+need_auth = Autorisation
+migrate_options = Migrationsmuligheder
+migrate_options_mirror_helper = Dette depot vil vรฆre et spejl
+migrate_options_lfs = Migrer LFS-filer
+migrate_options_lfs_endpoint.label = LFS endepunkt
+migrate_options_lfs_endpoint.description.local = En lokal serversti understรธttes ogsรฅ.
+migrate_items = Migration Elementer
+migrate_items_wiki = Wiki
+migrate_items_milestones = Milepรฆle
+migrate_items_labels = Etiketter
+migrate_items_issues = Problemmer
+migrate_items_pullrequests = Pull-anmodninger
+migrate_items_merge_requests = Flet anmodninger
+migrate_items_releases = Udgivelser
+migrate_repo = Migrer depot
+migrate.clone_address_desc = HTTP(S) eller Git "klone" URL'en for et eksisterende depot
+migrate.clone_local_path = eller en lokal serversti
+migrate.permission_denied = Du har ikke tilladelse til at importere lokale depoter.
+migrate.permission_denied_blocked = Du kan ikke importere fra ikke-tilladte vรฆrter. Bed venligst administratoren om at kontrollere ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS indstillingerne.
+migrate.invalid_local_path = Den lokale sti er ugyldig. Den eksisterer ikke eller er ikke en mappe.
+migrate.invalid_lfs_endpoint = LFS-endepunktet er ikke gyldigt.
+migrate.failed = Migrering mislykkedes: %v
+migrate.migrate_items_options = Adgangstoken er pรฅkrรฆvet for at migrere yderligere elementer
+migrated_from_fake = Migreret fra %[1]s
+migrate.migrate = Migrer fra %s
+migrate.migrating = Migrerer fra %s โฆ
+migrate.migrating_failed = Migrering fra %s mislykkedes.
+migrate.migrating_failed.error = Kunne ikke migrere: %s
+migrate.migrating_failed_no_addr = Migration mislykkedes.
+migrate.git.description = Migrer kun et depot fra enhver Git-tjeneste.
+migrate.gitlab.description = Migrer data fra gitlab.com eller andre GitLab-instanser.
+migrate.forgejo.description = Migrer data fra codeberg.org eller andre Forgejo-instanser.
+migrate.gogs.description = Migrer data fra notabug.org eller andre Gogs-instanser.
+migrate.codebase.description = Migrer data fra codebasehq.com.
+migrate.migrating_git = Migrering af Git-data
+migrate.migrating_topics = Migrering af emner
+migrate.migrating_milestones = Migrerende milepรฆle
+migrate.migrating_labels = Migrering af etiketter
+migrate.migrating_releases = Migrering af udgivelser
+migrate.migrating_issues = Migrering af problemer
+migrate.migrating_pulls = Migrering af pull-anmodninger
+migrate.cancel_migrating_title = Annuller migrering
+mirror_from = spejl af
+forked_from = forked fra
+generated_from = genereret fra
+fork_from_self = Du kan ikke forke et depot, du ejer.
+migrate.onedev.description = Migrer data fra code.onedev.io eller andre OneDev-instanser.
+archive.pull.nocomment = Denne depot er arkiveret. Du kan ikke kommentere pรฅ pull-anmodninger.
+migrated_from = Migreret fra %[2]s
+migrate.gitea.description = Migrer data fra gitea.com eller andre Gitea-instanser.
+migrate.gitbucket.description = Migrer data fra GitBucket-instanser.
+migrate.github_token_desc = Du kan sรฆtte et eller flere tokens med kommasepareret her for at gรธre migreringen hurtigere pรฅ grund af GitHub API-hastighedsgrรฆnsen. ADVARSEL: Misbrug af denne funktion kan overtrรฆde tjenesteudbyderens politik og fรธre til kontoblokering.
+migrate_options_lfs_endpoint.description = Migration vil forsรธge at bruge din fjern-Git til at bestemme LFS-serveren . Du kan ogsรฅ angive et brugerdefineret slutpunkt, hvis depots LFS-data er gemt et andet sted.
+form.name_pattern_not_allowed = Mรธnsteret "%s" er ikke tilladt i et depotnavn.
+migrate_options_lfs_endpoint.placeholder = Hvis det efterlades tomt, vil endepunktet blive afledt fra klonens URL
+migrate.clone_address = Migrer / Klon fra URL
+migrate.github.description = Migrer data fra github.com eller GitHub Enterprise server.
+migrate.cancel_migrating_confirm = Vil du annullere denne migrering?
+more_operations = Flere operationer
+new_from_template = Brug en skabelon
+new_from_template_description = Du kan vรฆlge en eksisterende depotskabelon pรฅ denne instans og anvende dens indstillinger.
+new_advanced = Avancerede indstillinger
+new_advanced_expand = Klik for at udvide
+auto_init_description = Start Git-historikken med en LรSMIG og tilfรธj eventuelt licens- og .gitignore-filer.
+unwatch = Fjern overvรฅgning
+star = Stjerne
+unstar = Fjern stjerne
+fork = Fork
+download_archive = Download depot
+no_desc = Ingen beskrivelse
+code = Kode
+audio_not_supported_in_browser = Din browser understรธtter ikke HTML5 "audio"-tagget.
+clone_this_repo = Klon dette depot
+create_new_repo_command = Oprettelse af et nyt depot pรฅ kommandolinjen
+push_exist_repo = Push et eksisterende depot fra kommandolinjen
+empty_message = Dette depot indeholder ikke noget indhold.
+code.desc = Fรฅ adgang til kildekode, filer, commits og grene.
+branch = Gren
+tree = Trรฆ
+clear_ref = `Ryd nuvรฆrende reference`
+find_tag = Find tag
+branches = Grene
+tag = Tag
+tags = Tags
+issues = Problemer
+pulls = Pull-anmodninger
+project = Projekter
+file_permalink = Permalink
+file_too_large = Filen er for stor til at blive vist.
+ambiguous_runes_header = `Denne fil indeholder tvetydige Unicode-tegn`
+ambiguous_runes_description = `Denne fil indeholder Unicode-tegn, der kan forveksles med andre tegn. Hvis du tror, at dette er med vilje, kan du roligt ignorere denne advarsel. Brug Escape-knappen til at afslรธre dem.`
+invisible_runes_line = `Denne linje har usynlige Unicode-tegn`
+ambiguous_runes_line = `Denne linje har tvetydige Unicode-tegn`
+ambiguous_character = `%[1]c [U+%04[1]X] kan forveksles med %[2]c [U+%04[2]X]`
+escape_control_characters = Escape
+unescape_control_characters = Unescape
+file_copy_permalink = Kopiรฉr permalink
+view_git_blame = Se git skyld
+video_not_supported_in_browser = Din browser understรธtter ikke HTML5 "video"-tagget.
+stored_lfs = Lagret med Git LFS
+symbolic_link = Symbolsk link
+executable_file = Eksekverbar fil
+vendored = Vendored
+generated = Genereret
+commit_graph = Commit graf
+commit_graph.select = Vรฆlg grene
+commit_graph.hide_pr_refs = Skjul pull-anmodninger
+commit_graph.monochrome = Mono
+commit_graph.color = Farve
+commit.contained_in = Denne commit er indeholdt i:
+commit.contained_in_default_branch = Denne commit er en del af standardgrenen
+commit.load_referencing_branches_and_tags = Indlรฆs grene og tags, der refererer til denne commit
+blame = Skyld
+download_file = Download fil
+normal_view = Normal visning
+line = linje
+lines = linjer
+from_comment = (kommentar)
+no_eol.text = Ingen EOL
+no_eol.tooltip = Denne fil indeholder ikke et afsluttende linjesluttegn.
+editor.add_file = Tilfรธj fil
+editor.new_file = Ny fil
+editor.upload_file = Upload fil
+editor.edit_file = Rediger fil
+editor.preview_changes = Forhรฅndsvisning af รฆndringer
+editor.cannot_edit_lfs_files = LFS-filer kan ikke redigeres i webgrรฆnsefladen.
+editor.cannot_edit_non_text_files = Binรฆre filer kan ikke redigeres i webgrรฆnsefladen.
+editor.edit_this_file = Rediger fil
+editor.this_file_locked = Filen er lรฅst
+editor.must_be_on_a_branch = Du skal vรฆre pรฅ en gren for at foretage eller foreslรฅ รฆndringer til denne fil.
+editor.fork_before_edit = Du skal fork dette depot for at foretage eller foreslรฅ รฆndringer til denne fil.
+editor.delete_this_file = Slet fil
+editor.must_have_write_access = Du skal have skriveadgang for at foretage eller foreslรฅ รฆndringer til denne fil.
+filter_branch_and_tag = Filtrer gren eller tag
+quick_guide = Hurtig guide
+broken_message = Git-dataene, der ligger til grund for dette depot, kan ikke lรฆses. Kontakt administratoren af denne instans eller slet dette depot.
+invisible_runes_header = `Denne fil indeholder usynlige Unicode-tegn`
+cite_this_repo = Citรฉr dette depot
+invisible_runes_description = `Denne fil indeholder usynlige Unicode-tegn, der ikke kan skelnes for mennesker, men som kan behandles anderledes af en computer. Hvis du tror, at dette er med vilje, kan du roligt ignorere denne advarsel. Brug Escape-knappen til at afslรธre dem.`
+fork_guest_user = Log ind for at forke dette depot.
+watch_guest_user = Log ind for at overvรฅge dette depot.
+watch = Overvรฅg
+star_guest_user = Log ind for at stjernemarkere dette depot.
+subscribe.issue.guest.tooltip = Log ind for at abonnere pรฅ dette problem.
+subscribe.pull.guest.tooltip = Log ind for at abonnere pรฅ denne pull-anmodning.
+release = Udgivelse
+releases = Udgivelser
+packages = Pakker
+actions = Handlinger
+labels = Etiketter
+milestones = Milepรฆle
+n_commit_few = %s commits
+n_branch_one = %s gren
+n_branch_few = %s grene
+org_labels_desc_manage = Styr
+commits = Commits
+commit = Commit
+org_labels_desc = Etiketter pรฅ organisationsniveau, der kan bruges med alle depoter under denne organisation
+n_commit_one = %s commit
+n_release_few = %s udgivelser
+released_this = udgivet dette
+file.title = %s ved %s
+file_raw = Rรฅ
+file_follow = Fรธlg symbollink
+editor.or = eller
+editor.fail_to_update_file_summary = Fejlmeddelelse:
+editor.push_rejected_summary = Fuldstรฆndig afvisningsmeddelelse:
+editor.add_subdir = Tilfรธj en mappeโฆ
+editor.unable_to_upload_files = Kunne ikke uploade filer til "%s" med fejl: %v
+n_tag_one = %s tag
+n_tag_few = %s tags
+n_release_one = %s udgivelse
+file_history = Historie
+file_view_source = Se kilde
+file_view_rendered = Vis gengivet
+file_view_raw = Vis rรฅ
+editor.file_delete_success = Filen "%s" er blevet slettet.
+editor.name_your_file = Navngiv din filโฆ
+editor.filename_help = Tilfรธj en mappe ved at skrive dens navn efterfulgt af en skrรฅstreg ("/"). Fjern en mappe ved at skrive backspace i begyndelsen af inputfeltet.
+editor.cancel_lower = Annuller
+editor.commit_signed_changes = Commit underskrevne รฆndringer
+editor.file_is_a_symlink = `"%s" er et symbolsk link. Symbolske links kan ikke redigeres i webeditoren`
+editor.filename_is_a_directory = Filnavnet "%s" er allerede brugt som et mappenavn i dette depot.
+editor.upload_file_is_locked = Filen "%s" er lรฅst af %s.
+editor.upload_files_to_dir = Upload filer til "%s"
+editor.cannot_commit_to_protected_branch = Kan ikke commit til den beskyttede gren "%s".
+editor.no_commit_to_branch = Kan ikke commit direkte til grenen fordi:
+editor.user_no_push_to_branch = Brugeren kan ikke push til gren
+editor.require_signed_commit = Gren krรฆver en underskrevet commit
+editor.cherry_pick = Kirsebรฆr-pluk %s pรฅ:
+editor.revert = Vend %s tilbage til:
+commits.desc = Gennemse kildekodens รฆndringshistorik.
+commits.commits = Commits
+commits.no_commits = Ingen commits til fรฆlles. "%s" og "%s" har helt forskellige historier.
+commits.nothing_to_compare = Disse grene er ens.
+commits.search.tooltip = Du kan prรฆfikse nรธgleord med "forfatter:", "committer:", "efter:" eller "fรธr:", f.eks. "vend forfatter:Alice fรธr:2019-01-13".
+commits.search_branch = Denne gren
+commits.search_all = Alle grene
+commits.author = Forfatter
+commits.gpg_key_id = GPG nรธgle-id
+commits.ssh_key_fingerprint = SSH nรธgle fingeraftryk
+commits.view_path = Se pรฅ dette tidspunkt i historien
+commit.operations = Operationer
+commit.revert = Revert
+commit.revert-header = Revert: %s
+commit.revert-content = Vรฆlg gren for at revert til:
+editor.directory_is_a_file = Katalognavnet "%s" er allerede brugt som et filnavn i dette depot.
+editor.branch_already_exists = Gren "%s" findes allerede i dette depot.
+editor.filename_cannot_be_empty = Filnavnet mรฅ ikke vรฆre tomt.
+editor.commit_changes = Commit รฆndringer
+editor.signoff_desc = Tilfรธj en Signed-off-by trailer af committeren i slutningen af commit log-meddelelsen.
+editor.commit_directly_to_this_branch = Commit direkte til %[1]s -grenen.
+editor.add_tmpl = Tilfรธj "<%s>"
+editor.add_tmpl.filename = filnavn
+editor.add = Tilfรธj %s
+editor.update = Opdater %s
+editor.delete = Slet %s
+editor.patch = Pรฅfรธr patch
+editor.patching = Patching:
+editor.fail_to_apply_patch = Kan ikke anvende patch "%s"
+editor.new_patch = Nyt patch
+editor.commit_message_desc = Tilfรธj en valgfri udvidet beskrivelseโฆ
+editor.create_new_branch = Opret en ny gren til denne commit og start en pull-anmodning.
+editor.create_new_branch_np = Opret en ny gren til denne commit.
+editor.propose_file_change = Foreslรฅ filรฆndring
+editor.new_branch_name = Navngiv den nye gren for denne commit
+editor.new_branch_name_desc = Ny gren navnโฆ
+editor.cancel = Annuller
+commits.signed_by_untrusted_user_unmatched = Signeret af ikke-pรฅlidelig bruger, der ikke matcher committer
+commits.signed_by = Signeret af
+commits.signed_by_untrusted_user = Signeret af en ikke-pรฅlidelig bruger
+commit.cherry-pick = Kirsebรฆr-pluk
+commit.cherry-pick-header = Kirsebรฆrpluk: %s
+commit.cherry-pick-content = Vรฆlg en gren at kirsebรฆr-pluk pรฅ:
+commitstatus.failure = Fiasko
+commitstatus.error = Fejl
+projects.create_success = Projektet "%s" er blevet oprettet.
+projects.title = Titel
+projects.new = Nyt projekt
+projects.new_subheader = Koordiner, spor og opdater dit arbejde รฉt sted, sรฅ projekter forbliver gennemsigtige og planmรฆssigt.
+editor.filename_is_invalid = Filnavnet er ugyldigt: "%s".
+projects.deletion_desc = Sletning af et projekt fjerner det fra alle relaterede problemer. Vil du fortsรฆtte?
+projects.deletion_success = Projektet er blevet slettet.
+projects.modify = Rediger projekt
+projects.type.none = Intet
+projects.type.basic_kanban = Grundlรฆggende kanban
+projects.type.bug_triage = Fejltriage
+projects.template.desc = Skabelon
+projects.template.desc_helper = Vรฆlg en projektskabelon for at komme i gang
+projects.column.edit = Rediger kolonne
+projects.column.set_default_desc = Indstil denne kolonne som standard for ukategoriserede problemer og pulls
+projects.column.delete = Slet kolonne
+projects.column.deletion_desc = Sletning af en projektkolonne flytter alle relaterede problemer til standardkolonnen. Vil du fortsรฆtte?
+projects.column.color = Farve
+projects.open = ร
ben
+projects.close = Luk
+projects.column.assigned_to = Tildelt til
+projects.card_type.desc = Forhรฅndsvisninger af kort
+projects.card_type.images_and_text = Billeder og tekst
+projects.card_type.text_only = Kun tekst
+issues.desc = Organiser fejlrapporter, opgaver og milepรฆle.
+editor.invalid_commit_mail = Ugyldig mail til oprettelse af en commit.
+editor.branch_does_not_exist = Gren "%s" findes ikke i dette depot.
+editor.file_editing_no_longer_exists = Filen, der redigeres, "%s", findes ikke lรฆngere i dette depot.
+projects.column.edit_title = Navn
+projects.column.new_title = Navn
+projects.column.new_submit = Opret kolonne
+projects.column.new = Ny kolonne
+projects.column.set_default = Indstil standard
+editor.file_deleting_no_longer_exists = Filen, der slettes, "%s", eksisterer ikke lรฆngere i dette depot.
+editor.no_changes_to_show = Der er ingen รฆndringer at vise.
+editor.fail_to_update_file = Kunne ikke opdatere/oprette filen "%s".
+editor.push_rejected_no_message = รndringen blev afvist af serveren uden en besked. Tjek venligst Git hooks.
+editor.push_rejected = รndringen blev afvist af serveren. Tjek venligst Git hooks.
+projects.create = Opret projekt
+projects.deletion = Slet projekt
+projects.edit = Rediger projekt
+projects.edit_subheader = Projekter organiserer problemer og sporer fremskridt.
+projects.edit_success = Projekt "%s" er blevet opdateret.
+issues.new.no_label = Ingen etiketter
+issues.new.clear_labels = Tydelige etiketter
+issues.new.projects = Projekter
+issues.new.clear_projects = Ryd projekter
+issues.new.no_projects = Intet projekt
+issues.new.open_projects = ร
ben projekter
+issues.new.closed_projects = Lukkede projekter
+issues.new.no_items = Ingen elementer
+issues.new.milestone = Milepรฆl
+issues.new.no_milestone = Ingen milepรฆl
+issues.filter_assignees = Filter tildelt
+issues.filter_milestones = Filter Milepรฆl
+issues.filter_projects = Filter projekt
+issues.filter_labels = Filter etiket
+issues.filter_reviewers = Filter anmelder
+issues.new = Nyt problem
+issues.new.title_empty = Titel mรฅ ikke vรฆre tom
+issues.new.labels = Etiketter
+issues.new.clear_milestone = Ryd milepรฆl
+issues.new.open_milestone = ร
ben milepรฆle
+issues.new.closed_milestone = Lukkede milepรฆle
+issues.new.assignees = Tilvalgte
+issues.new.clear_assignees = Ryd tildelte
+issues.filter_sort.recentupdate = For nylig opdateret
+issues.filter_sort.leastupdate = Sidst opdateret
+issues.filter_sort.mostcomment = De fleste kommenterede
+issues.filter_sort.leastcomment = Mindst kommenteret
+issues.filter_sort.nearduedate = Nรฆrmeste forfaldsdato
+issues.filter_sort.farduedate = Lรฆngste forfaldsdato
+issues.filter_sort.moststars = Flest stjerner
+editor.file_changed_while_editing = Filens indhold er รฆndret, siden du begyndte at รฅbne den. Klik her for at se dem eller Bekrรฆft รฆndringer igen for at overskrive dem.
+editor.file_already_exists = En fil med navnet "%s" findes allerede i dette depot.
+editor.commit_id_not_matching = Filen blev รฆndret, mens du redigerede den. Forpligt dig til en ny gren og merge derefter.
+editor.push_out_of_date = Pushet ser ud til at vรฆre forรฆldet.
+editor.commit_empty_file_header = Commit en tom fil
+editor.commit_empty_file_text = Den fil, du er ved at commitere, er tom. Vil du fortsรฆtte?
+commits.message = Besked
+commits.browse_further = Gennemse videre
+commits.renamed_from = Omdรธbt fra %s
+commits.date = Dato
+commits.older = รldre
+commits.newer = Nyere
+issues.new.no_assignees = Ingen tildelte
+issues.new.assign_to_me = Tildel mig
+issues.action_assignee_no_select = Ingen tildelt
+issues.action_check = Marker/fjern markeringen
+issues.action_check_all = Marker/fjern markeringen af alle elementer
+issues.opened_by = รฅbnet %[1]s af %[3]s
+pulls.merged_by = af %[3]s blev merged %[1]s
+pulls.merged_by_fake = af %[2]s blev merged %[1]s
+issues.closed_by = af %[3]s blev lukket %[1]s
+projects.desc = Hรฅndtere problemer og pulls i projektboards.
+issues.filter_sort.feweststars = Fรฆrre stjerner
+issues.action_assignee = Tildelte
+commitstatus.success = Succes
+ext_issues = Eksterne problemer
+projects = Projekter
+projects.description = Beskrivelse (valgfrit)
+projects.description_placeholder = Beskrivelse
+issues.new.no_reviewers = Ingen anmeldere
+issues.choose.get_started = Kom godt i gang
+issues.choose.open_external_link = ร
ben
+issues.choose.blank = Standard
+issues.choose.blank_about = Opret et problem fra standardskabelon.
+issues.choose.ignore_invalid_templates = Ugyldige skabeloner er blevet ignoreret
+issues.filter_sort.mostforks = Fleste forks
+issues.filter_sort.fewestforks = Mindste forks
+issues.action_open = ร
ben
+issues.action_close = Luk
+issues.action_label = Etiket
+issues.action_milestone_no_select = Ingen milepรฆl
+commitstatus.pending = Afventer
+issues.edit.already_changed = Kunne ikke gemme รฆndringer af problemet. Det ser ud til, at indholdet allerede er blevet รฆndret af en anden bruger. Opdater siden, og prรธv at redigere igen for at undgรฅ at overskrive deres รฆndringer
+issues.action_milestone = Milepรฆl
+issues.comment_pull_merged_at = merged commit %[1]s ind i %[2]s %[3]s
+issues.comment_manually_pull_merged_at = manuelt merged commit %[1]s into %[2]s %[3]s
+issues.context.edit = Redigere
+issues.context.delete = Slet
+issues.no_content = Ingen beskrivelse angivet.
+issues.close = Luk problem
+summary_card_alt = Oversigtskort for depot %s
+issues.choose.invalid_config = Problemkonfigurationen indeholder fejl:
+issues.no_ref = Ingen gren/tag angivet
+issues.create = Opret problem
+issues.new_label = Ny etiket
+issues.choose.invalid_templates = %v ugyldig(e) skabelon(er) fundet
+issues.new_label_placeholder = Etiketnavn
+issues.new_label_desc_placeholder = Beskrivelse
+issues.create_label = Opret etiket
+issues.label_templates.title = Indlรฆs en etiketforudindstilling
+issues.label_templates.info = Der findes endnu ingen etiketter. Opret en etiket med "Ny etiket", eller brug en etiketforudindstilling:
+issues.label_templates.helper = Vรฆlg en etiketforudindstilling
+issues.label_templates.use = Brug etiketforudindstilling
+issues.label_templates.fail_to_load_file = Kunne ikke indlรฆse etiketskabelonfilen "%s": %v
+issues.add_label = tilfรธjede %s etiketten %s
+issues.add_labels = tilfรธjede %s etiketterne %s
+issues.add_remove_labels = tilfรธjede %s og fjernede %s etiketter %s
+issues.add_milestone_at = `fรธjede dette til %s milepรฆlen %s`
+issues.add_project_at = `fรธjede dette til %s - projektet %s`
+issues.ref_reopening_from = `henviste til dette problem fra en pull-anmodning %[4]s, der vil genรฅbne den , %[2]s `
+issues.ref_closed_from = `lukkede dette problem %[4]s %[2 ]s `
+issues.ref_reopened_from = `genรฅbnede dette problem %[4]s %[2 ]s `
+issues.ref_from = `fra %[1]s`
+issues.author = Forfatter
+issues.commit_ref_at = `henviste til dette problem fra en commit %[2]s `
+issues.ref_issue_from = `henviste til dette problem %[4]s %[2 ]s `
+issues.ref_pull_from = `henviste til denne pull-anmodning %[4]s %[ 2]s `
+issues.ref_closing_from = `henviste til dette problem fra en pull-anmodning %[4]s, der vil lukke det , %[2]s `
+issues.author.tooltip.issue = Denne bruger er forfatteren til dette problem.
+issues.author.tooltip.pr = Denne bruger er forfatteren af denne pull-anmodning.
+issues.role.owner = Ejer
+issues.role.owner_helper = Denne bruger er ejeren af dette depot.
+issues.role.member = Medlem
+issues.filter_label = Etiket
+issues.filter_label_no_select = Alle etiketter
+issues.filter_label_select_no_label = Ingen etiket
+issues.closed_title = Lukket
+issues.all_title = Alle
+issues.draft_title = Udkast
+issues.num_comments_1 = %d kommentar
+issues.num_comments = %d kommentarer
+issues.num_reviews_one = %d gennemgang
+issues.opened_by_fake = รฅbnet %[1]s af %[2]s
+issues.closed_by_fake = af %[2]s var lukket %[1]s
+issues.previous = Tidligere
+issues.next = Nรฆste
+issues.open_title = ร
ben
+issues.num_reviews_few = %d gennemganger
+issues.context.reference_issue = Reference i nyt problem
+issues.close_comment_issue = Luk med kommentar
+issues.reopen_issue = Genรฅben
+issues.commented_at = `kommenterede %s `
+issues.delete_comment_confirm = Er du sikker pรฅ, at du vil slette denne kommentar?
+issues.context.copy_link = Kopiรฉr link
+issues.context.quote_reply = Citat svar
+issues.reaction.add = Tilfรธj reaktion
+issues.reaction.alt_few = %[1]s reagerede %[2]s.
+issues.reaction.alt_many = %[1]s og %[2]d mere reagerede %[3]s.
+issues.reaction.alt_remove = Fjern %[1]s reaktion fra kommentar.
+issues.reaction.alt_add = Tilfรธj %[1]s reaktion til kommentar.
+issues.context.menu = Kommentar menu
+issues.reopen_comment_issue = Genรฅbner med kommentar
+issues.create_comment = Kommentar
+issues.closed_at = `lukkede dette problem %[2]s `
+issues.reopened_at = `genรฅbnede dette problem %[2]s `
+issues.remove_label = fjernede %s etiketten %s
+issues.remove_labels = fjernede %s etiketterne %s
+issues.change_project_at = `modificerede projektet fra %s til %s %s`
+issues.remove_milestone_at = `fjernede dette fra %s milepรฆlen %s`
+issues.remove_project_at = `fjernede dette fra %s -projektet %s`
+issues.deleted_milestone = `(slettet)`
+issues.deleted_project = `(slettet)`
+issues.add_assignee_at = `blev tildelt af %s %s`
+issues.self_assign_at = `selv tildelt denne %s".
+issues.remove_assignee_at = `blev utildelt af %s %s`
+issues.remove_self_assignment = `fjernede deres opgave %s`
+issues.change_title_at = `รฆndret titel fra %s til %s %s`
+issues.change_ref_at = `รฆndret reference fra %s til %s %s`
+issues.remove_ref_at = `fjernet reference %s %s`
+issues.add_ref_at = `tilfรธjet reference %s %s`
+issues.delete_branch_at = `slettet gren %s %s`
+issues.filter_label_exclude = `Brug alt
+ klik/enter
for at ekskludere etiketter`
+issues.filter_milestone = Milepรฆl
+issues.filter_milestone_all = Alle milepรฆle
+issues.filter_milestone_none = Ingen milepรฆle
+issues.filter_milestone_open = ร
bne milepรฆle
+issues.filter_milestone_closed = Lukkede milepรฆle
+issues.filter_project = Projekt
+issues.filter_project_all = Alle projekter
+issues.filter_project_none = Intet projekt
+issues.filter_assignee = Tildelte
+issues.filter_assginee_no_select = Alle tildelte
+issues.filter_assginee_no_assignee = Ingen tildelte
+issues.filter_poster = Forfatter
+issues.filter_poster_no_select = Alle forfattere
+issues.filter_type = Type
+issues.filter_type.all_issues = Alle problemer
+issues.filter_type.assigned_to_you = Tildelt til dig
+issues.filter_type.created_by_you = Oprettet af dig
+issues.filter_type.review_requested = Gennemgang anmodet om
+issues.filter_type.reviewed_by_you = Gennemgรฅet af dig
+issues.filter_sort = Sortere
+issues.filter_sort.relevance = Relevans
+issues.filter_sort.latest = Nyeste
+issues.filter_sort.oldest = รldste
+issues.filter_type.mentioning_you = Nรฆvnte dig
+issues.change_milestone_at = "รฆndrede milepรฆlen fra %s til %s %s"
+issues.role.contributor_helper = Denne bruger har tidligere forpligtet sig i dette depot.
+issues.is_stale = Der er sket รฆndringer i denne PR siden denne gennemgang
+issues.label_exclusive = Eksklusiv
+issues.role.member_helper = Denne bruger er medlem af den organisation, der ejer dette depot.
+issues.role.collaborator = Samarbejdspartner
+issues.role.contributor = Bidragyder
+issues.edit = Redigere
+issues.role.collaborator_helper = Denne bruger er blevet inviteret til at samarbejde om depotet.
+issues.role.first_time_contributor = Fรธrstegangs bidragyder
+issues.role.first_time_contributor_helper = Dette er det fรธrste bidrag fra denne bruger til depotet.
+issues.re_request_review = Anmod om gennemgang igen
+issues.remove_request_review = Fjern anmodning om gennemgang
+issues.remove_request_review_block = Anmodningen om gennemgang kan ikke fjernes
+issues.dismiss_review = Afvis gennemgang
+issues.dismiss_review_warning = Er du sikker pรฅ, at du vil afvise denne gennemgang?
+issues.sign_in_require_desc = Log ind for at deltage i denne samtale.
+issues.cancel = Annuller
+issues.save = Gem
+issues.label_title = Navn
+issues.label_description = Beskrivelse
+issues.label_color = Farve
+issues.label_archive = Arkiver etiketten
+issues.label_modify = Rediger etiket
+issues.label_deletion = Slet etiket
+issues.label_deletion_desc = Sletning af en etiket fjerner den fra alle problemer. Vil du fortsรฆtte?
+issues.label_deletion_success = Etiketten er blevet slettet.
+issues.label_archived_filter = Vis arkiverede etiketter
+issues.label_archive_tooltip = Arkiverede etiketter udelukkes som standard fra forslagene, nรฅr du sรธger efter etiket.
+issues.label_exclusive_desc = Navngiv etiketten omfang/element
for at gรธre den gensidigt udelukkende med andre omfang/
etiketter.
+issues.label_exclusive_warning = Eventuelle modstridende etiketter vil blive fjernet, nรฅr etiketterne for et problem eller pull-anmodning redigeres.
+issues.label_count = %d etiketter
+issues.label_open_issues = %d รฅben problemer/pull-anmodninger
+issues.label_edit = Redigere
+issues.label_delete = Slet
+issues.archived_label_description = (Arkiveret) %s
+issues.label.filter_sort.alphabetically = Alfabetisk
+issues.label.filter_sort.reverse_alphabetically = Omvendt alfabetisk
+issues.label.filter_sort.by_size = Mindste stรธrrelse
+issues.label.filter_sort.reverse_by_size = Stรธrste stรธrrelse
+issues.num_participants_one = %d deltager
+issues.num_participants_few = %d deltagere
+issues.attachment.open_tab = `Klik for at se "%s" i en ny fane`
+issues.attachment.download = `Klik for at downloade "%s"`
+issues.subscribe = Abonner
+issues.unsubscribe = Afmeld
+issues.lock_duplicate = Et problem kan ikke lรฅses to gange.
+issues.unlock_error = Kan ikke lรฅse et problem op, der ikke er lรฅst.
+issues.lock_with_reason = lรฅst som %s og begrรฆnset samtale til samarbejdspartnere %s
+issues.lock_confirm = Lรฅs
+issues.unlock_confirm = Lรฅs op
+issues.lock.notice_1 = - Andre brugere kan ikke tilfรธje nye kommentarer til dette problem.
+issues.lock_no_reason = lรฅst og begrรฆnset samtale til samarbejdspartnere %s
+issues.unlock_comment = lรฅste denne samtale %s op
+issues.add_time_minutes = Minutter
+issues.del_time_history = `slettet brugt tid %s`
+issues.add_time_hours = Timer
+issues.add_time_sum_to_small = Ingen tid blev indtastet.
+issues.time_spent_from_all_authors = `Samlet tid brugt: %s`
+issues.time_spent_total = Samlet tid brugt
+issues.unlock.title = Lรฅs op for samtale om dette problem.
+issues.lock.title = Lรฅs samtale om dette problem.
+issues.comment_on_locked = Du kan ikke kommentere pรฅ et lรฅst problem.
+issues.delete = Slet
+issues.delete.title = Slet dette problem?
+issues.delete.text = Vil du virkelig slette dette problem? (Dette fjerner alt indhold permanent. Overvej at lukke det i stedet, hvis du har til hensigt at holde det arkiveret)
+issues.tracker = Tidsregistrering
+issues.start_tracking_short = Start timer
+issues.start_tracking = Start tidsregistrering
+issues.start_tracking_history = `begyndte at arbejde %s`
+issues.tracker_auto_close = Timeren stoppes automatisk, nรฅr dette problem lukkes
+issues.tracking_already_started = `Du har allerede startet tidsregistrering pรฅ et andet problem !`
+issues.stop_tracking = Stop timer
+issues.stop_tracking_history = "stoppede med at arbejde %s`
+issues.cancel_tracking = Kassรฉr
+issues.cancel_tracking_history = `annulleret tidssporing %s`
+issues.add_time = Tilfรธj tid manuelt
+issues.del_time = Slet denne tidslog
+issues.add_time_cancel = Annuller
+issues.add_time_history = `tilfรธrt brugt tid %s`
+issues.due_date = Forfaldsdato
+issues.push_commit_1 = tilfรธjet %d commit %s
+issues.due_date_added = tilfรธjede forfaldsdatoen %s %s
+issues.due_date_modified = รฆndrede forfaldsdatoen fra %[2]s til %[1]s %[3]s
+issues.due_date_remove = fjernede forfaldsdatoen %s %s
+issues.due_date_overdue = Forfalden
+issues.lock.unknown_reason = Kan ikke lรฅse et problem med en ukendt รฅrsag.
+issues.lock.notice_3 = - Du kan altid lรฅse op for dette problem igen i fremtiden.
+issues.push_commits_n = tilfรธjet %d commits %s
+issues.force_push_codes = `force-pushed %[1]s fra %[2]s
til %[4]s
%[6]s`
+issues.force_push_compare = Sammenlign
+issues.due_date_form = yyyy-mm-dd
+issues.due_date_form_edit = Redigere
+issues.due_date_form_remove = Slet
+issues.due_date_not_set = Ingen forfaldsdato fastsat.
+issues.add_time_short = Tilfรธj tid
+issues.unpin_issue = Frigรธr problemet
+issues.max_pinned = Du kan ikke fastgรธre flere problemer
+issues.pin_comment = fastgjort dette %s
+issues.unpin_comment = frigjorde dette %s
+issues.lock = Lรฅs samtale
+issues.unlock = Lรฅs samtale op
+issues.lock.notice_2 = - Du og andre samarbejdspartnere med adgang til dette depot kan stadig efterlade kommentarer, som andre kan se.
+issues.unlock.notice_1 = - Alle ville kunne udtale sig om dette spรธrgsmรฅl endnu en gang.
+issues.unlock.notice_2 = - Du kan altid lรฅse dette problem igen i fremtiden.
+issues.lock.reason = ร
rsag til lรฅsning
+issues.review.outdated = Forรฆldet
+issues.dependency.no_permission.can_remove = Du har ikke tilladelse til at lรฆse denne afhรฆngighed, men du kan fjerne denne afhรฆngighed
+issues.dependency.add = Tilfรธj afhรฆngighedโฆ
+issues.dependency.cancel = Annuller
+issues.dependency.remove = Slet
+issues.dependency.remove_info = Fjern denne afhรฆngighed
+issues.dependency.added_dependency = `tilfรธjede en ny afhรฆngighed %s`
+issues.due_date_invalid = Forfaldsdatoen er ugyldig eller uden for intervallet. Brug venligst formatet "yyyy-mm-dd".
+issues.dependency.title = Afhรฆngigheder
+issues.dependency.issue_no_dependencies = Ingen afhรฆngigheder angivet.
+issues.dependency.pr_no_dependencies = Ingen afhรฆngigheder angivet.
+issues.dependency.no_permission_1 = Du har ikke tilladelse til at lรฆse %d afhรฆngighed
+issues.dependency.no_permission_n = Du har ikke tilladelse til at lรฆse %d afhรฆngigheder
+issues.dependency.issue_close_blocked = Du skal lukke alle problemer, der blokerer dette problem, fรธr du kan lukke det.
+issues.dependency.issue_batch_close_blocked = Kan ikke batchlukke valgte problemer, fordi problem #%d stadig har รฅbne afhรฆngigheder
+issues.dependency.pr_close_blocked = Du skal lukke alle problemer, der blokerer denne pull-anmodning, fรธr du kan flette den.
+issues.dependency.blocks_short = Blockere
+issues.dependency.blocked_by_short = Afhรฆnger af
+issues.dependency.remove_header = Fjern afhรฆngighed
+issues.dependency.issue_remove_text = Dette vil fjerne afhรฆngigheden af dette problem. Vil du fortsรฆtte?
+issues.review.dismissed = afviste %s's gennemgang %s
+issues.review.content.empty = Du skal efterlade en kommentar, der angiver de รธnskede รฆndringer.
+issues.review.reject = anmodende รฆndringer %s
+issues.review.wait = blev anmodet om gennemgang %s
+issues.review.add_review_request = anmodet om gennemgang fra %[1]s %[2]s
+issues.review.add_review_requests = anmodet om gennemgange fra %[1]s %[2]s
+issues.dependency.removed_dependency = `fjernede en afhรฆngighed %s`
+issues.dependency.pr_closing_blockedby = Lukning af denne pull-anmodning er blokeret af fรธlgende problemer
+issues.dependency.issue_closing_blockedby = Lukning af dette problem er blokeret af fรธlgende problemer
+issues.dependency.issue_close_blocks = Dette problem blokerer for lukning af fรธlgende problemer
+issues.dependency.pr_close_blocks = Denne pull-anmodning blokerer lukning af fรธlgende problemer
+issues.dependency.pr_remove_text = Dette vil fjerne afhรฆngigheden fra denne pull-anmodning. Vil du fortsรฆtte?
+issues.dependency.setting = Aktiver afhรฆngigheder for problemer og pull-anmodninger
+issues.dependency.add_error_same_issue = Du kan ikke fรฅ et problem til at afhรฆnge af sig selv.
+issues.dependency.add_error_dep_issue_not_exist = Afhรฆngigt problem eksisterer ikke.
+issues.dependency.add_error_dep_exists = Afhรฆngighed eksisterer allerede.
+issues.dependency.add_error_cannot_create_circular = Du kan ikke oprette en afhรฆngighed med to problemer, der blokerer hinanden.
+issues.dependency.add_error_dep_not_same_repo = Begge problemer skal vรฆre i samme depot.
+issues.review.self.approval = Du kan ikke godkende din egen pull-anmodning.
+issues.review.self.rejection = Du kan ikke anmode om รฆndringer pรฅ din egen pull-anmodning.
+issues.review.approve = godkendte disse รฆndringer %s
+issues.review.comment = gennemgรฅet %s
+issues.review.dismissed_label = Afvist
+issues.review.left_comment = efterladt en kommentar
+issues.review.remove_review_request = fjernet anmodning om gennemgang for %[1]s %[2]s
+issues.review.remove_review_requests = fjernet anmodning om gennemgange for %[1]s %[2]s
+issues.review.remove_review_request_self = nรฆgtede at gennemgรฅ %s
+issues.review.add_remove_review_requests = anmodede om gennemgang fra %[1]s og fjernede gennemgangsanmodninger for %[2]s %[3]s
+issues.review.pending = Afventer
+issues.dependency.add_error_dep_not_exist = Afhรฆngighed eksisterer ikke.
+issues.review.pending.tooltip = Denne kommentar er i รธjeblikket ikke synlig for andre brugere. For at indsende dine afventende kommentarer, vรฆlg "%s" -> "%s/%s/%s" รธverst pรฅ siden.
+issues.review.review = Gennemgรฅ
+issues.review.outdated_description = Indholdet er รฆndret siden denne kommentar blev lavet
+issues.review.option.show_outdated_comments = Vis forรฆldede kommentarer
+issues.review.reviewers = Gemmengรฅer
+issues.review.option.hide_outdated_comments = Skjul forรฆldede kommentarer
+issues.review.show_outdated = Vis forรฆldet
+issues.review.hide_resolved = Skjul lรธst
+issues.content_history.created = oprettet
+issues.review.hide_outdated = Skjul forรฆldede
+issues.review.resolved_by = markerede denne samtale som lรธst
+issues.reference_issue.body = Body
+issues.content_history.deleted = slettet
+issues.content_history.edited = redigeret
+issues.review.show_resolved = Vis lรธst
+issues.review.resolve_conversation = Lรธs samtale
+issues.review.un_resolve_conversation = Uafklaret samtale
+issues.content_history.delete_from_history = Slet fra historikken
+issues.content_history.delete_from_history_confirm = Slet fra historikken?
+issues.content_history.options = Valgmuligheder
+issues.blocked_by_user = Du kan ikke oprette problemer pรฅ dette depot, fordi du er blokeret af depotes ejer.
+issues.comment.blocked_by_user = Du kan ikke kommentere til dette problem, fordi du er blokeret af depotes ejer eller anmelder af problemet.
+issues.reference_link = Reference: %s
+compare.compare_base = base
+compare.compare_head = sammenlign
+pulls.desc = Aktiver pull-anmodninger og kodegennemgange.
+pulls.new = Ny pull anmodning
+pulls.view = Se pull-anmodning
+pulls.compare_changes = Ny pull-anmodning
+issues.summary_card_alt = Oversigtskort over et problem med titlen "%s" i depotet %s
+pulls.edit.already_changed = Kunne ikke gemme รฆndringer af pull-anmodningen. Det ser ud til, at indholdet allerede er blevet รฆndret af en anden bruger. Opdater siden, og prรธv at redigere igen for at undgรฅ at overskrive deres รฆndringer
+pulls.sign_in_require = Log ind for at oprette en ny pull-anmodning.
+pulls.allow_edits_from_maintainers = Tillad redigeringer fra vedligeholdere
+pulls.allow_edits_from_maintainers_desc = Brugere med skriveadgang til basisgrenen kan ogsรฅ trykke til denne gren
+pulls.allow_edits_from_maintainers_err = Opdatering mislykkedes
+pulls.compare_base = flet ind i
+pulls.compare_compare = pull fra
+pulls.switch_comparison_type = Skift sammenligningstype
+pulls.switch_head_and_base = Skift hoved og base
+pulls.filter_branch = Filter gren
+pulls.compare_changes_desc = Vรฆlg den gren, der skal flettes ind i, og den gren, der skal trรฆkkes fra.
+pulls.has_viewed_file = Set
+pulls.has_changed_since_last_review = รndret siden din sidste gennemgang
+pulls.no_results = Ingen resultater fundet.
+pulls.show_all_commits = Vis alle commits
+pulls.show_changes_since_your_last_review = Vis รฆndringer siden din sidste gennemgang
+pulls.showing_only_single_commit = Viser kun รฆndringer af commit %[1]s
+pulls.showing_specified_commit_range = Viser kun รฆndringer mellem %[1]s..%[2]s
+pulls.select_commit_hold_shift_for_range = Vรฆlg commit. Hold Shift + klik for at vรฆlge et omrรฅde
+pulls.review_only_possible_for_full_diff = Gennemgang er kun mulig, nรฅr du ser den fulde diff
+pulls.filter_changes_by_commit = Filtrer efter commit
+pulls.expand_files = Udvid alle filer
+pulls.collapse_files = Skjul alle filer
+pulls.viewed_files_label = %[1]d / %[2]d filer set
+pulls.ready_for_review = Klar til gennemgang?
+pulls.still_in_progress = Stadig i gang?
+editor.commit_email = Commit email
+pulls.cannot_merge_work_in_progress = Denne pull-anmodning er markeret som et igangvรฆrende arbejde.
+pulls.add_prefix = Tilfรธj %s prรฆfiks
+pulls.remove_prefix = Fjern %s prรฆfiks
+pulls.data_broken = Denne pull-anmodning er รธdelagt pรฅ grund af manglende fork-information.
+pulls.is_checking = Kontrol af fletkonflikt er i gang. Prรธv igen om fรฅ รธjeblikke.
+pulls.merged_success = Pull-anmodning blev flettet og lukket
+pulls.closed = Pull-anmodning lukket
+pulls.manually_merged = Manuelt flettet
+pulls.merged_info_text = Grenen %s kan nu slettes.
+pulls.is_closed = Pull-anmodningen er blevet lukket.
+pulls.nothing_to_compare = Disse grene er lige store. Der er ingen grund til at oprette en pull-anmodning.
+pulls.nothing_to_compare_have_tag = Den valgte gren/tag er ens.
+pulls.nothing_to_compare_and_allow_empty_pr = Disse grene er lige store. Denne PR vil vรฆre tom.
+pulls.has_pull_request = `Der findes allerede en pull-anmodning mellem disse grene: %[2]s#%[3]d `
+pulls.create = Opret pull-anmodning
+pulls.reopen_to_merge = Genรฅbn denne pull-anmodning for at udfรธre en fletning.
+pulls.cant_reopen_deleted_branch = Denne pull-anmodning kan ikke genรฅbnes, fordi grenen blev slettet.
+pulls.merged = Flettet
+pulls.change_target_branch_at = `รฆndrede mรฅlgren fra %s til %s %s`
+pulls.tab_conversation = Samtale
+pulls.tab_commits = Commits
+pulls.tab_files = Filer รฆndret
+pulls.is_ancestor = Denne gren er allerede inkluderet i mรฅlgrenen. Der er ikke noget at flette sammen.
+pulls.is_empty = รndringerne pรฅ denne gren er allerede pรฅ mรฅlgrenen. Dette vil vรฆre en tom commit.
+pulls.required_status_check_failed = Nogle pรฅkrรฆvede checks lykkedes ikke.
+pulls.required_status_check_missing = Nogle pรฅkrรฆvede checks mangler.
+pulls.required_status_check_administrator = Som administrator kan du stadig flette denne pull-anmodning.
+pulls.blocked_by_approvals = Denne pull-anmodning har endnu ikke nok godkendelser. %d af %d godkendte godkendelser.
+pulls.files_conflicted = Denne pull-anmodning har รฆndringer, der er i konflikt med mรฅlgrenen.
+pulls.title_wip_desc = `Start titlen med %s for at forhindre pull-anmodningen i at blive flettet ved et uheld.`
+pulls.blocked_by_official_review_requests = Denne pull-anmodning er blokeret, fordi den mangler godkendelse fra en eller flere officielle anmeldere.
+pulls.blocked_by_rejection = Denne pull-anmodning har รฆndringer anmodet af en officiel anmelder.
+archive.pull.noreview = Dette depot er arkiveret. Du kan ikke gennemgรฅ pull-anmodninger.
+pulls.blocked_by_outdated_branch = Denne pull-anmodning er blokeret, fordi den er forรฆldet.
+pulls.blocked_by_changed_protected_files_1 = Denne pull-anmodning er blokeret, fordi den รฆndrer en beskyttet fil:
+pulls.blocked_by_changed_protected_files_n = Denne pull-anmodning er blokeret, fordi den รฆndrer beskyttede filer:
+pulls.can_auto_merge_desc = Denne pull-anmodning kan flettes automatisk.
+pulls.approve_count_1 = %d godkendelse
+pulls.num_conflicting_files_n = %d modstridende filer
+pulls.num_conflicting_files_1 = %d modstridende fil
+pulls.approve_count_n = %d godkendelser
+pulls.reject_count_1 = %d รฆndringsanmodning
+commits.view_single_diff = Se รฆndringer til denne fil introduceret i denne commit
+pulls.cannot_auto_merge_helper = Flet manuelt for at lรธse konflikterne.
+pulls.cannot_auto_merge_desc = Denne pull-anmodning kan ikke flettes automatisk pรฅ grund af konflikter.
+pulls.reject_count_n = %d รฆndringsanmodninger
+pulls.no_merge_desc = Denne pull-anmodning kan ikke flettes, fordi alle depotsfletningsmuligheder er deaktiveret.
+pulls.no_merge_helper = Aktiver fletteindstillinger i depotindstillingerne, eller flet pull-anmodningen manuelt.
+pulls.no_merge_wip = Denne pull-anmodning kan ikke flettes, fordi den er markeret som vรฆrende et igangvรฆrende arbejde.
+pulls.no_merge_not_ready = Denne pull-anmodning er ikke klar til at blive flettet, tjek gennemgangsstatus og statustjek.
+pulls.squash_merge_pull_request = Opret squash-commit
+pulls.fast_forward_only_merge_pull_request = Spol kun frem
+pulls.merge_manually = Manuel flet
+pulls.merge_commit_id = Flettes commit ID
+pulls.require_signed_wont_sign = Grenen krรฆver underskrevne tilsagn, men denne fletning vil ikke blive underskrevet
+pulls.waiting_count_n = %d venter pรฅ gennemgange
+pulls.wrong_commit_id = commit id skal vรฆre et commit id pรฅ mรฅlgrenen
+pulls.blocked_by_user = Du kan ikke oprette en pull-anmodning pรฅ dette depot, fordi du er blokeret af depotets ejer.
+pulls.no_merge_access = Du er ikke autoriseret til at flette denne pull-anmodning.
+pulls.merge_pull_request = Opret flet commit
+pulls.rebase_merge_pull_request = Rebaser og spole derefter frem
+pulls.rebase_merge_commit_pull_request = Rebase og opret derefter flet commit
+pulls.waiting_count_1 = %d venter pรฅ gennemgang
+pulls.invalid_merge_option = Du kan ikke bruge denne fletteindstilling til denne pull-anmodning.
+pulls.merge_conflict = Fletning mislykkedes: Der var en konflikt under sammenlรฆgningen. Tip: Prรธv en anden strategi
+pulls.merge_conflict_summary = Fejl besked
+pulls.rebase_conflict_summary = Fejl besked
+pulls.unrelated_histories = Fletning mislykkedes: Sammenfletnings-hovedet og -basen deler ikke en fรฆlles historie. Tip: Prรธv en anden strategi
+pulls.head_out_of_date = Fletning mislykkedes: Under genereringen af fletningen blev hovedet opdateret. Tip: Prรธv igen.
+pulls.has_merged = Mislykkedes: Pull-anmodningen er blevet flettet, du kan ikke flette igen eller รฆndre mรฅlgrenen.
+pulls.rebase_conflict = Fletning mislykkedes: Der var en konflikt under re-basering af commit: %[1]s. Tip: Prรธv en anden strategi
+pulls.merge_out_of_date = Fletning mislykkedes: Under genereringen af fletningen blev basen opdateret. Tip: Prรธv igen.
+pulls.push_rejected_summary = Fuld afvisningsmeddelelse
+pulls.push_rejected = Push mislykkedes: Pushet blev afvist. Gennemgรฅ Git-hooks for dette depot.
+pulls.push_rejected_no_message = Push mislykkedes: Pushet blev afvist, men der var ingen fjernmeddelelse. Gennemgรฅ Git-hooks for dette depot
+pulls.status_checks_failure = Nogle kontroller mislykkedes
+issues.reopen.blocked_by_user = Du kan ikke genรฅbne dette problem, fordi du er blokeret af depotes ejer eller aflรฆggeren af dette problem.
+pulls.comment.blocked_by_user = Du kan ikke kommentere denne pull-anmodning, fordi du er blokeret af depotes ejer eller plakaten for pull-anmodningen.
+pulls.open_unmerged_pull_exists = `Du kan ikke udfรธre en genรฅbnings handling, fordi der er en afventende pull-anmodning (#%d) med identiske egenskaber.`
+pulls.status_checking = Nogle kontroller afventer
+pulls.status_checks_warning = Nogle kontroller rapporterede advarsler
+pulls.status_checks_error = Nogle kontroller rapporterede fejl
+pulls.cmd_instruction_merge_desc = Flet รฆndringerne og opdater pรฅ Forgejo.
+pulls.clear_merge_message = Ryd flettemeddelelse
+pulls.cmd_instruction_merge_warning = Advarsel: Indstillingen "Autofind manuel fletning" er ikke aktiveret for dette depot. Du skal efterfรธlgende markere denne pull-anmodning som manuelt flettet.
+pulls.clear_merge_message_hint = Rydning af flettemeddelelsen vil kun fjerne commit-meddelelsens indhold og beholde genererede git-trailere sรฅsom "Co-Authored-By ...".
+pulls.reopen_failed.head_branch = Pull-anmodningen kan ikke genรฅbnes, fordi hovedgrenen ikke eksisterer lรฆngere.
+pulls.editable_explanation = Denne pull-anmodning tillader redigeringer fra vedligeholdere. Du kan bidrage direkte til det.
+pulls.auto_merge_button_when_succeed = (Nรฅr kontroller lykkes)
+pulls.status_checks_requested = Pรฅkrรฆvet
+pulls.close = Luk pull anmodning
+pulls.commit_ref_at = `henviste til denne pull-anmodning fra en commit %[2]s `
+pulls.cmd_instruction_hint = Se instruktionerne pรฅ kommandolinjen
+pulls.reopened_at = `genรฅbnede denne pull-anmodning %[2]s `
+pulls.closed_at = `lukkede denne pull-anmodning %[2]s `
+pulls.cmd_instruction_checkout_desc = Fra dit projektdepot, tjek en ny gren og test รฆndringerne.
+pulls.editable = Redigerbar
+pulls.made_using_agit = AGit
+pulls.agit_explanation = Oprettet ved hjรฆlp af AGit-arbejdsgangen. AGit lader bidragydere foreslรฅ รฆndringer ved hjรฆlp af "git push" uden at oprette en fork eller en ny gren.
+pulls.status_checks_success = Alle kontroller lykkedes
+pulls.cmd_instruction_merge_title = Flet
+pulls.reopen_failed.base_branch = Pull-anmodningen kan ikke genรฅbnes, fordi basisgrenen ikke eksisterer lรฆngere.
+pulls.cmd_instruction_checkout_title = Checkout
+pulls.outdated_with_base_branch = Denne gren er forรฆldet med basisgrenen
+pulls.status_checks_details = Detaljer
+pulls.status_checks_hide_all = Skjul alle kontroller
+pulls.status_checks_show_all = Vis alle kontroller
+pulls.update_branch = Opdater gren ved fletning
+pulls.update_branch_rebase = Opdel gren ved genbase
+pulls.update_branch_success = Grenopdatering var vellykket
+pulls.update_not_allowed = Du har ikke tilladelse til at opdatere grenen
+pulls.auto_merge_has_pending_schedule = %[1]s planlagde denne pull-anmodning til automatisk at flette, nรฅr alle kontroller lykkes %[2]s.
+pulls.auto_merge_cancel_schedule = Annuller automatisk fletning
+pulls.auto_merge_not_scheduled = Denne pull-anmodning er ikke planlagt til automatisk fletning.
+pulls.auto_merge_canceled_schedule = Den automatiske fletning blev annulleret for denne pull-anmodning.
+pulls.auto_merge_newly_scheduled_comment = `planlagde denne pull-anmodning til automatisk at flette, nรฅr alle kontroller lykkes %[1]s.`
+pulls.auto_merge_canceled_schedule_comment = `annullerede automatisk fletning af denne pull-anmodning, nรฅr alle kontroller lykkes %[1]s`
+pulls.delete_after_merge.head_branch.is_default = Den hovedgren, du vil slette, er standardgrenen og kan ikke slettes.
+pulls.delete_after_merge.head_branch.is_protected = Den hovedgren, du vil slette, er en beskyttet gren og kan ikke slettes.
+pulls.delete_after_merge.head_branch.insufficient_branch = Du har ikke tilladelse til at slette hovedgrenen.
+pulls.delete.title = Vil du slette denne pull-anmodning?
+pulls.delete.text = Vil du virkelig slette denne pull-anmodning? (Dette fjerner alt indhold permanent. Overvej at lukke det i stedet, hvis du har til hensigt at beholde det arkiveret)
+pulls.auto_merge_newly_scheduled = Pull-anmodningen var planlagt til at flette, nรฅr alle kontroller lykkes.
+pulls.auto_merge_when_succeed = Automatisk fletning, nรฅr alle kontroller lykkes
+milestones.no_due_date = Ingen forfaldsdato
+milestones.open = ร
ben
+pull.deleted_branch = (slettet):%s
+settings.event_release = Udgivelse
+milestones.closed = Lukket %s
+milestones.update_ago = Opdateret %s
+issues.filter_no_results = Ingen resultater
+issues.filter_no_results_placeholder = Prรธv at justere dine sรธgefiltre.
+activity.published_release_label = Udgivelse
+pulls.recently_pushed_new_branches = Du pushed pรฅ grenen %[1]s %[2]s
+activity.unresolved_conv_label = ร
ben
+activity.title.releases_1 = %d udgivelse
+activity.title.releases_n = %d udgivelser
+activity.title.releases_published_by = %s udgivet af %s
+milestones.new = Ny milepรฆl
+comments.edit.already_changed = Kunne ikke gemme รฆndringer af kommentaren. Det ser ud til, at indholdet allerede er blevet รฆndret af en anden bruger. Opdater siden, og prรธv at redigere igen for at undgรฅ at overskrive deres รฆndringer
+settings.teams = Teams
+milestones.create = Opret milepรฆl
+settings.event_pull_request_label = Etiketter
+milestones.completeness = %d%% Fuldfรธrt
+settings.event_wiki_desc = Wiki-side oprettet, omdรธbt, redigeret eller slettet.
+settings.event_issue_label = Etiketter
+milestones.new_subheader = Milepรฆle kan hjรฆlpe dig med at organisere problemer og spore deres fremskridt.
+settings.secret = Hemmelighed
+settings.content_type = POST indholdstype
+settings.slack_username = Brugernavn
+settings.title = Titel
+settings.http_method = HTTP metode
+milestones.close = Luk
+wiki = Wiki
+settings.webhook.payload = Indhold
+settings.webhook.body = Body
+settings.webhook.replay.description = Gentag denne webhook.
+settings.webhook.replay.description_disabled = For at afspille denne webhook igen, skal du aktivere den.
+settings.webhook.delivery.success = En begivenhed er blevet tilfรธjet til leveringskรธen. Det kan tage et par sekunder, fรธr det dukker op i leveringshistorikken.
+settings.githooks_desc = Git hooks drives af Git selv. Du kan redigere hook-filer nedenfor for at konfigurere brugerdefinerede handlinger.
+settings.githook_edit_desc = Hvis krogen er inaktiv, vil prรธveindhold blive prรฆsenteret. Hvis du overlader indholdet til en tom vรฆrdi, deaktiveres denne hook.
+settings.githook_name = Hook navn
+settings.githook_content = Hook indhold
+settings.add_webhook_desc = Forgejo sender POST
-anmodninger med en specificeret indholdstype til mรฅl-URL'en. Lรฆs mere i webhooks-guiden .
+settings.payload_url = Mรฅl URL
+milestones.title = Titel
+milestones.desc = Beskrivelse
+settings.event_wiki = Wiki
+settings.update_githook = Opdatere hook
+settings.lfs_locks_no_locks = Ingen lรฅse
+settings.discord_username = Brugernavn
+settings.lfs_lock = Lรฅs
+settings.deploy_key_content = Indhold
+settings.lfs_lock_path = Filsti til lรฅsโฆ
+milestones.clear = Ryd
+milestones.invalid_due_date_format = Forfaldsdatoformatet skal vรฆre "รฅรฅรฅรฅ-mm-dd".
+milestones.create_success = Milepรฆlen "%s" er blevet oprettet.
+milestones.edit_subheader = Milepรฆle organiserer problemer og sporer fremskridt.
+release.edit_release = Opdater udgivelse
+release.delete_tag = Slet tag
+release.deletion = Slet udgivelse
+release.delete_release = Slet udgivelse
+settings.lfs_pointers.sha = Blob hash
+settings.lfs_pointers.oid = OID
+milestones.cancel = Annuller
+release.save_draft = Gem kladde
+wiki.cancel = Annuller
+milestones.due_date = Forfaldsdato (valgfrit)
+release.cancel = Annuller
+release.publish = Udgiv udgivelse
+milestones.edit = Rediger milepรฆl
+settings.lfs_lock_file_no_exist = Lรฅst fil findes ikke i standardgrenen
+settings.lfs_force_unlock = Tving oplรฅsning
+settings.lfs_pointers.found = Fundet %d blob-pointer(e) - %d tilknyttet, %d ikke-associeret (%d mangler fra butikken)
+settings.lfs_pointers.inRepo = i depot
+settings.lfs_pointers.exists = Eksisterer i lager
+settings.lfs_pointers.accessible = Tilgรฆngeligt for bruger
+signing.wont_sign.not_signed_in = Du er ikke logget ind.
+wiki.welcome = Velkommen til Wikien
+milestones.modify = Opdater milepรฆl
+milestones.edit_success = Milepรฆl "%s" er blevet opdateret.
+milestones.filter_sort.least_issues = Mindst problemer
+signing.wont_sign.error = Der opstod en fejl under kontrol af, om commiten kunne underskrives.
+signing.wont_sign.nokey = Denne instans har ingen nรธgle at underskrive denne commit med.
+milestones.deletion = Slet milepรฆl
+milestones.filter_sort.least_complete = Mindst komplet
+milestones.filter_sort.most_complete = Mest komplet
+milestones.filter_sort.most_issues = Fleste problemer
+signing.wont_sign.commitssigned = Sammenlรฆgningen vil ikke blive underskrevet, da alle de tilknyttede tilsagn ikke er underskrevet.
+ext_wiki = Ekstern Wiki
+signing.wont_sign.approved = Sammenlรฆgningen vil ikke blive underskrevet, da PR'en ikke er godkendt.
+milestones.deletion_desc = Sletning af en milepรฆl fjerner den fra alle relaterede problemer. Vil du fortsรฆtte?
+wiki.welcome_desc = Wikien lader dig skrive og dele dokumentation med samarbejdspartnere.
+wiki.desc = Skriv og del dokumentation med samarbejdspartnere.
+wiki.create_first_page = Opret den fรธrste side
+wiki.save_page = Gem side
+wiki.page = Side
+wiki.new_page = Side
+wiki.page_title = Side title
+wiki.page_content = Side indhold
+wiki.default_commit_message = Skriv en note om denne sideopdatering (valgfrit).
+milestones.deletion_success = Milepรฆlen er blevet slettet.
+milestones.filter_sort.name = Navn
+milestones.filter_sort.earliest_due_data = Nรฆrmeste forfaldsdato
+milestones.filter_sort.latest_due_date = Lรฆngste forfaldsdato
+signing.will_sign = Denne commit vil blive underskrevet med nรธglen "%s".
+signing.wont_sign.never = Commits er aldrig underskrevet.
+signing.wont_sign.always = Commits er altid underskrevet.
+signing.wont_sign.parentsigned = Commiten vil ikke blive underskrevet, da forรฆldre commiten ikke er underskrevet.
+signing.wont_sign.pubkey = Commiten vil ikke blive underskrevet, fordi du ikke har en offentlig nรธgle knyttet til din konto.
+signing.wont_sign.twofa = Du skal have tofaktorautentificering aktiveret for at fรฅ commits underskrevet.
+wiki.last_commit_info = %s redigerede denne side %s
+wiki.page_name_desc = Indtast et navn til denne Wiki-side. Nogle specielle navne er: "Hjem", "_Sidebar" og "_Footer".
+signing.wont_sign.headsigned = Sammenlรฆgningen vil ikke blive underskrevet, da hoved commiten ikke er underskrevet.
+wiki.file_revision = Side revision
+wiki.new_page_button = Ny side
+wiki.wiki_page_revisions = Side revisioner
+wiki.page_already_exists = Der findes allerede en wiki-side med samme navn.
+wiki.last_updated = Sidst opdateret %s
+wiki.original_git_entry_tooltip = Se original Git-fil i stedet for at bruge et venligt link.
+settings.units.overview = Oversigt
+signing.wont_sign.basesigned = Sammenfletningen vil ikke blive underskrevet, da basis commiten ikke er underskrevet.
+wiki.back_to_wiki = Tilbage til wiki-siden
+wiki.delete_page_button = Slet side
+wiki.pages = Sider
+wiki.search = Sรธg wiki
+wiki.no_search_results = Ingen resultater
+wiki.reserved_page = Wikisidenavnet "%s" er reserveret.
+wiki.filter_page = Filter side
+wiki.edit_page_button = Rediger
+wiki.delete_page_notice_1 = Sletning af wiki-siden "%s" kan ikke fortrydes. Vil du fortsรฆtte?
+activity = Aktivitet
+activity.period.yearly = 1 รฅr
+activity.overview = Oversigt
+activity.navbar.contributors = Bidragydere
+activity.navbar.recent_commits = Seneste commits
+settings.units.add_more = Aktiver flere
+activity.navbar.pulse = Puls
+activity.navbar.code_frequency = Kode frekvens
+activity.period.filter_label = Periode:
+activity.period.daily = 1 dag
+activity.period.weekly = 1 uge
+activity.period.monthly = 1 mรฅned
+activity.period.halfweekly = 3 dage
+activity.period.quarterly = 3 mรฅneder
+activity.period.semiyearly = 6 mรฅneder
+activity.title.prs_1 = %d pull-anmodning
+activity.title.prs_merged_by = %s flettet af %s
+contributors.contribution_type.commits = Commits
+contributors.contribution_type.additions = Tilfรธjelser
+contributors.contribution_type.deletions = Sletninger
+settings = Indstillinger
+settings.federation_settings = Fรธderationsindstillinger
+settings.hooks = Webhooks
+activity.title.issues_created_by = %s oprettet af %s
+activity.new_issue_label = ร
bnet
+activity.active_issues_count_n = %d aktive problemer
+activity.closed_issue_label = Lukket
+activity.commit = Commit aktivitet
+settings.collaboration = Samarbejdspartnere
+activity.git_stats_commit_n = %d commits
+activity.git_stats_files_changed_1 = er รฆndret
+activity.git_stats_files_changed_n = har รฆndret
+activity.git_stats_additions = og der har vรฆret
+settings.collaboration.admin = Administrator
+settings.collaboration.write = Skriv
+settings.federation_not_enabled = Fรธderation er ikke aktiveret pรฅ din instans.
+settings.mirror_settings.docs.pull_mirror_instructions = For at opsรฆtte et pull-spejl, se venligst:
+settings.mirror_settings.docs.more_information_if_disabled = Du kan finde ud af mere om push and pull spejle her:
+activity.git_stats_deletion_1 = %d sletning
+activity.git_stats_pushed_n = havde pushed
+activity.title.unresolved_conv_1 = %d uafsluttet samtale
+activity.title.unresolved_conv_n = %d uafsluttede samtaler
+activity.git_stats_pushed_1 = har pushed
+contributors.contribution_type.filter_label = Bidrags type:
+settings.options = Depot
+settings.desc = Indstillinger er, hvor du kan administrere indstillingerne for depotet
+settings.collaboration.read = Lรฆs
+settings.collaboration.owner = Ejer
+settings.collaboration.undefined = Udefineret
+settings.githooks = Git hooks
+settings.basic_settings = Grundlรฆggende indstillinger
+settings.mirror_settings.docs.disabled_push_mirror.instructions = Konfigurer dit projekt til automatisk at trรฆkke commits, tags og branches fra et andet depot.
+activity.title.prs_opened_by = %s foreslรฅet af %s
+activity.merged_prs_label = Flettet
+activity.merged_prs_count_n = Flettede pull-anmodninger
+activity.title.prs_n = %d pull-anmodninger
+activity.opened_prs_label = Foreslรฅet
+activity.active_issues_count_1 = %d aktivt problem
+activity.new_issues_count_1 = Nyt problem
+activity.new_issues_count_n = Nye problemer
+activity.git_stats_commit_1 = %d commit
+settings.federation_apapiurl = Fรธderations-URL for dette depot. Kopiรฉr og indsรฆt dette i Federation Settings af et andet lager som en URL for et Fรธlgende Depot.
+settings.mirror_settings.docs = Konfigurer dit depot til automatisk at synkronisere commits, tags og branches med et andet depot.
+settings.mirror_settings.docs.disabled_pull_mirror.instructions = Indstil dit projekt til automatisk at skubbe commits, tags og branches til et andet depot. Pull-spejle er blevet deaktiveret af din webstedsadministrator.
+settings.mirror_settings.docs.doc_link_pull_section = afsnittet "Trรฆkker fra et fjerndepot" i dokumentationen.
+settings.mirror_settings.docs.pulling_remote_title = Trรฆkker fra et fjerndepot
+settings.mirror_settings.mirrored_repository = Spejlet depot
+settings.mirror_settings.pushed_repository = Pushed depot
+settings.mirror_settings = Spejl indstillinger
+activity.closed_issues_count_n = Lukkede problemer
+activity.title.issues_1 = %d problem
+activity.title.issues_n = %d problemer
+activity.title.issues_closed_from = %s lukket af %s
+activity.closed_issues_count_1 = Lukket problem
+settings.federation_following_repos = URL'er for fรธlgende depoter. Adskilt af ";", ingen mellemrum.
+settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning = Lige nu kan dette kun gรธres i menuen "Ny migration". For mere information, kontakt venligst:
+settings.mirror_settings.docs.disabled_push_mirror.info = Push-spejle er blevet deaktiveret af din webstedsadministrator.
+settings.mirror_settings.docs.no_new_mirrors = Dit depot spejler รฆndringer til eller fra et andet depot. Husk pรฅ, at du ikke kan oprette nye spejle pรฅ nuvรฆrende tidspunkt.
+settings.mirror_settings.docs.can_still_use = Selvom du ikke kan รฆndre eksisterende spejle eller oprette nye, kan du stadig bruge dit eksisterende spejle.
+settings.mirror_settings.docs.doc_link_title = Hvordan spejler jeg depoter?
+activity.active_prs_count_1 = %d aktiv pull-anmodning
+activity.active_prs_count_n = %d aktive pull-anmodninger
+activity.merged_prs_count_1 = Sammenflettet pull-anmodning
+activity.opened_prs_count_1 = Foreslรฅet pull anmodning
+activity.opened_prs_count_n = Foreslรฅede pull-anmodninger
+activity.title.user_n = %d brugere
+activity.title.user_1 = %d bruger
+activity.published_prerelease_label = Fรธr-udgivelse
+activity.published_tag_label = Tag
+activity.no_git_activity = Der har ikke vรฆret nogen commit-aktivitet i denne periode.
+activity.git_stats_exclude_merges = Med undtagelse af fletninger,
+activity.git_stats_author_1 = %d forfatter
+activity.git_stats_author_n = %d forfattere
+activity.git_stats_addition_1 = %d tilfรธjelse
+activity.git_stats_deletion_n = %d sletninger
+activity.git_stats_and_deletions = og
+activity.git_stats_addition_n = %d tilfรธjelser
+settings.event_repository = Depot
+activity.unresolved_conv_desc = Disse nyligt รฆndrede problemer og pull-anmodninger er ikke blevet lรธst endnu.
+activity.git_stats_push_to_branch = til %s og
+activity.git_stats_push_to_all_branches = til alle grene.
+activity.git_stats_on_default_branch = Pรฅ %s,
+activity.git_stats_file_1 = %d fil
+activity.git_stats_file_n = %d filer
+settings.mirror_settings.push_mirror.remote_url = Git-URL for fjerndepot
+settings.external_tracker_url = Eksternt problem tracker URL
+settings.admin_enable_health_check = Aktiver depot sundheds checks (git fsck)
+settings.external_tracker_url_desc = Besรธgende omdirigeres til den eksterne problemsporings-URL, nรฅr de klikker pรฅ problemer-fanen.
+settings.mirror_settings.push_mirror.none = Der er ikke konfigureret push-spejle
+settings.mirror_settings.push_mirror.add = Tilfรธj push spejl
+settings.mirror_settings.push_mirror.edit_sync_time = Rediger spejlsynkroniseringsinterval
+settings.mirror_settings.last_update = Sidste opdatering
+settings.update_settings = Gem indstillinger
+settings.admin_settings = Administratorindstillinger
+settings.tracker_issue_style.regexp_pattern_desc = Den fรธrste fangede gruppe vil blive brugt i stedet for {index}
.
+settings.actions_desc = Aktiver integrerede CI/CD-pipelines med Forgejo Actions
+settings.reindex_requested = Genindeks anmodet
+settings.external_wiki_url = Ekstern wiki-URL
+settings.tracker_issue_style = Eksternt problem tracker Nummerformat
+settings.tracker_issue_style.alphanumeric = Alfanumerisk
+settings.tracker_issue_style.regexp = Regulรฆrt udtryk
+settings.pulls_desc = Aktiver depot pull-anmodninger
+settings.pulls.default_allow_edits_from_maintainers = Tillad som standard redigeringer fra vedligeholdere
+settings.admin_code_indexer = Kodeindekserer
+settings.admin_indexer_unindexed = Uindekseret
+settings.admin_enable_close_issues_via_commit_in_any_branch = Luk et problem via en commit lavet i en ikke-standard filial
+settings.mirror_settings.direction = Retning
+settings.mirror_settings.direction.pull = Pull
+settings.mirror_settings.direction.push = Push
+settings.event_push = Push
+settings.units.units = Enheder
+settings.mirror_settings.push_mirror.copy_public_key = Kopier offentlig nรธgle
+settings.update_mirror_settings = Opdater spejlindstillinger
+settings.wiki_desc = Aktiver depot wiki
+settings.use_internal_wiki = Brug indbygget wiki
+settings.use_external_wiki = Brug ekstern wiki
+settings.external_wiki_url_desc = Besรธgende omdirigeres til den eksterne wiki-URL, nรฅr de klikker pรฅ wiki-fanen.
+settings.issues_desc = Aktiver depotproblemsporing
+settings.use_internal_issue_tracker = Brug indbygget problem tracker
+settings.use_external_issue_tracker = Brug ekstern problemsporing
+settings.tracker_url_format = Eksternt problem tracker URL-format
+settings.tracker_url_format_error = Det eksterne problemsporings-URL-format er ikke en gyldig URL.
+settings.external_tracker_url_error = Den eksterne problemsporings-URL er ikke en gyldig URL.
+settings.external_wiki_url_error = Den eksterne wiki-URL er ikke en gyldig URL.
+settings.reindex_button = Tilfรธj til genindekskรธ
+settings.mirror_settings.push_mirror.none_ssh = Intet
+settings.sync_mirror = Synkroniser nu
+settings.pull_mirror_sync_in_progress = Trรฆkker รฆndringer fra remote %s i รธjeblikket.
+settings.pull_mirror_sync_quota_exceeded = Kvoten overskredet, ingen รฆndringer.
+settings.push_mirror_sync_in_progress = Pusher รฆndringer til remote %s i รธjeblikket.
+settings.branches.switch_default_branch = Skift standardgren
+settings.branches.update_default_branch = Opdater standardgren
+settings.branches.add_new_rule = Tilfรธj ny regel
+settings.advanced_settings = Avancerede indstillinger
+settings.wiki_globally_editable = Tillad enhver at redigere wikien
+settings.tracker_issue_style.numeric = Numerisk
+settings.tracker_issue_style.regexp_pattern = Regulรฆrt udtryksmรธnster
+settings.allow_only_contributors_to_track_time = Lad kun bidragydere spore tid
+settings.pulls.enable_autodetect_manual_merge = Aktiver automatisk manuel fletning (Bemรฆrk: I nogle sรฆrlige tilfรฆlde kan fejlvurderinger forekomme)
+settings.pulls.ignore_whitespace = Ignorer mellemrum for konflikter
+settings.projects_desc = Aktiver depot-projekter
+settings.admin_stats_indexer = Kode statistik indekserer
+settings.tracker_url_format_desc = Brug pladsholderne {user}
, {repo}
og {index}
til brugernavn, depotnavn og problemindeks.
+settings.enable_timetracker = Aktiver tidsregistrering
+settings.releases_desc = Aktiver depotudgivelser
+settings.packages_desc = Aktiver depotpakkeregistrering
+settings.danger_zone = Farezone
+settings.pulls.default_delete_branch_after_merge = Slet pull request-gren efter fletning som standard
+settings.default_update_style_desc = Standard opdateringsstil, der bruges til at opdatere pull-anmodninger, der ligger bag basisgrenen.
+settings.event_push_desc = Git push til et depot.
+settings.site = Websted
+settings.admin_indexer_commit_sha = Sidste indekserede commit
+settings.pulls.allow_rebase_update = Aktiver opdatering af pull request-gren ved rebase
+settings.trust_model.default = Standard tillidsmodel
+settings.transfer_desc = Overfรธr dette depot til en bruger eller til en organisation, som du har administratorrettigheder til.
+settings.enter_repo_name = Indtast ejer- og depotnavnet nรธjagtigt som vist:
+settings.convert_notices_1 = Denne handling vil konvertere spejlet til et almindeligt depot og kan ikke fortrydes.
+settings.transfer.success = Overfรธrsel af depot var vellykket.
+settings.convert_fork_confirm = Konverter depot
+settings.convert_fork_succeed = Forken er omdannet til et almindeligt depot.
+settings.transfer_abort = Annullere overfรธrsel
+settings.transfer_abort_invalid = Du kan ikke annullere en ikke-eksisterende depotoverfรธrsel.
+settings.transfer_abort_success = Depot overfรธrslen til %s blev annulleret.
+settings.transfer_perform = Udfรธr overfรธrslen
+settings.wiki_rename_branch_main_desc = Omdรธb grenen, der bruges internt af Wiki, til "%s". Denne รฆndring er permanent og kan ikke fortrydes.
+settings.trust_model.collaboratorcommitter.long = Collaborator+Committer: Stol pรฅ underskrifter fra samarbejdspartnere, der matcher forpligteren
+settings.wiki_delete = Slet wiki-data
+settings.wiki_delete_notices_1 = - Dette vil permanent slette og deaktivere depot-wikien for %s.
+settings.wiki_branch_rename_failure = Det lykkedes ikke at normalisere depotwikiens filialnavn.
+settings.add_collaborator_duplicate = Samarbejdspartneren er allerede fรธjet til dette depot.
+settings.add_collaborator_owner = Kan ikke tilfรธje en ejer som samarbejdspartner.
+settings.collaborator_deletion = Fjern Samarbejdspartner
+settings.collaborator_deletion_desc = Fjernelse af en samarbejdspartner vil tilbagekalde deres adgang til dette depot. Vil du fortsรฆtte?
+settings.add_team_duplicate = Teamet har allerede depotet
+settings.add_collaborator_blocked_our = Samarbejdspartneren kan ikke tilfรธjes, fordi depots ejer har blokeret dem.
+settings.add_collaborator_blocked_them = Samarbejdspartneren kan ikke tilfรธjes, fordi de har blokeret depot ejeren.
+settings.delete_collaborator = Slet
+settings.trust_model.collaboratorcommitter = Samarbejdspartner+Committer
+settings.convert_confirm = Konverter depot
+settings.trust_model = Signatur tillidsmodel
+settings.trust_model.collaborator.desc = Gyldige signaturer fra samarbejdspartnere af dette depot vil blive markeret som "pรฅlidelige" - (uanset om de matcher committeren eller ej). Ellers vil gyldige signaturer blive markeret som "upรฅlidelige", hvis signaturen matcher committeren og "umatchede", hvis ikke.
+settings.wiki_rename_branch_main = Normaliser Wiki-grenens navn
+settings.wiki_rename_branch_main_notices_1 = Denne handling KAN IKKE fortrydes.
+settings.wiki_deletion_success = Depot-wiki-dataene er blevet slettet.
+settings.delete_notices_1 = - Denne handling KAN IKKE fortrydes.
+settings.delete = Slet dette depot
+settings.deletion_success = Depotet er blevet slettet.
+settings.add_collaborator_success = Samarbejdspartneren er tilfรธjet.
+settings.transfer_in_progress = Der er i รธjeblikket en igangvรฆrende overfรธrsel. Annuller det, hvis du vil overfรธre dette depot til en anden bruger.
+settings.transfer_notices_3 = - Hvis depotet er privat og overfรธres til en individuel bruger, sikrer denne handling, at brugeren har mindst lรฆsetilladelse (og รฆndrer tilladelser, hvis det er nรธdvendigt).
+settings.transfer_started = Dette depot er blevet markeret til overfรธrsel og afventer bekrรฆftelse fra "%s"
+settings.signing_settings = Indstillinger for signering af bekrรฆftelse
+settings.trust_model.committer.long = Committer: Stol pรฅ signaturer, der matcher committers (dette matcher GitHub og vil tvinge Forgejo underskrevne commits til at have Forgejo som committer)
+settings.trust_model.committer.desc = Gyldige signaturer vil kun blive markeret som "trusted", hvis de matcher committeren, ellers vil de blive markeret "unmatched". Dette tvinger Forgejo til at vรฆre committer pรฅ underskrevne commits med den faktiske committer markeret som Co-authored-by: og Co-committed-by: trailer i commit. Forgejo-nรธglen skal matche en bruger i databasen.
+settings.delete_notices_fork_1 = - Forks af dette depot bliver uafhรฆngige efter sletning.
+settings.remove_collaborator_success = Samarbejdspartneren er blevet fjernet.
+settings.remove_team_success = Teamets adgang til depotet er blevet fjernet.
+settings.delete_notices_2 = - Denne handling vil permanent slette %s -depotet, inklusive kode, problemer, kommentarer, wiki-data og samarbejdspartnerindstillinger.
+settings.convert_succeed = Spejlet er blevet omdannet til et almindeligt depot.
+settings.convert_fork_desc = Du kan konvertere denne gaffel til et almindeligt depot. Dette kan ikke fortrydes.
+settings.convert_fork_notices_1 = Denne operation vil konvertere forken til et almindeligt depot og kan ikke fortrydes.
+settings.transfer.rejected = Depotoverfรธrsel blev afvist.
+settings.transfer.title = Overfรธr ejerskab
+settings.transfer.button = Overfรธr ejerskab
+settings.transfer.modal.title = Overfรธr ejerskab
+settings.confirmation_string = Bekrรฆftelsesstreng
+settings.transfer_owner = Nye ejer
+settings.transfer_notices_2 = - Du beholder adgangen til depotet, hvis du overfรธrer det til en organisation, som du (med)ejer.
+settings.transfer_succeed = Depotet er blevet overfรธrt.
+settings.transfer_quota_exceeded = Den nye ejer (%s) er over kvoten. Depotet er ikke blevet overfรธrt.
+settings.trust_model.collaborator = Samarbejdspartner
+settings.trust_model.collaborator.long = Samarbejdspartner: Tillid til underskrifter fra samarbejdspartnere
+settings.trust_model.default.desc = Brug standard depottillidsmodellen til denne installation.
+settings.wiki_rename_branch_main_notices_2 = Dette vil permanent omdรธbe den interne gren af %s' depot wiki. Eksisterende checkouts skal opdateres.
+settings.confirm_wiki_branch_rename = Omdรธb wiki-grenen
+settings.confirm_wiki_delete = Slet wiki-data
+settings.delete_desc = Sletning af et depot er permanent og kan ikke fortrydes.
+settings.confirm_delete = Slet depot
+settings.add_collaborator = Tilfรธj samarbejdspartner
+settings.update_settings_success = Depotingsindstillingerne er blevet opdateret.
+settings.update_settings_no_unit = Depotet bรธr tillade mindst en form for interaktion.
+settings.add_collaborator_inactive_user = Kan ikke tilfรธje en inaktiv bruger som samarbejdspartner.
+settings.add_team_success = Teamet har nu adgang til depotet.
+settings.change_team_permission_tip = Teamets tilladelse er angivet pรฅ teamindstillingssiden og kan ikke รฆndres pr. depot
+settings.delete_team_tip = Dette team har adgang til alle depoter og kan ikke fjernes
+settings.org_not_allowed_to_be_collaborator = Organisationer kan ikke tilfรธjes som samarbejdspartner.
+settings.change_team_access_not_allowed = รndring af teamadgang til depot er begrรฆnset til organisationsejeren
+settings.team_not_in_organization = Teamet er ikke i samme organisation som depotet
+settings.add_webhook = Tilfรธj webhook
+settings.new_owner_has_same_repo = Den nye ejer har allerede et depot med samme navn. Vรฆlg venligst et andet navn.
+settings.new_owner_blocked_doer = Den nye ejer har blokeret dig.
+settings.convert_desc = Du kan konvertere dette spejl til et almindeligt depot. Dette kan ikke fortrydes.
+settings.convert = Konverter til et almindeligt depot
+settings.transfer_notices_1 = - Du mister adgangen til depotet, hvis du overfรธrer det til en individuel bruger.
+settings.wiki_delete_desc = Sletning af depot wiki-data er permanent og kan ikke fortrydes.
+settings.trust_model.committer = Committer
+settings.trust_model.collaboratorcommitter.desc = Gyldige signaturer fra samarbejdspartnere af dette depot vil blive markeret som "pรฅlidelige", hvis de matcher committeren. Ellers vil gyldige signaturer blive markeret som "upรฅlidelige", hvis signaturen matcher committeren og "umatchede" ellers. Dette vil tvinge Forgejo til at blive markeret som committer pรฅ underskrevne commits med den faktiske committer markeret som Co-Authored-By: og Co-Committed-By: trailer i commit. Forgejo-nรธglen skal matche en bruger i databasen.
+settings.add_team = Tilfรธj team
+settings.convert_fork = Konverter til almindeligt depot
+settings.wiki_branch_rename_success = Depot-wikiens filialnavn er blevet normaliseret.
+settings.add_webhook.invalid_channel_name = Webhook-kanalnavnet mรฅ ikke vรฆre tomt og mรฅ ikke kun indeholde et #-tegn.
+settings.webhook_deletion = Fjern webhook
+settings.hooks_desc = Webhooks foretager automatisk HTTP POST-anmodninger til en server, nรฅr visse Forgejo-hรฆndelser udlรธses. Lรฆs mere i webhooks-guiden .
+settings.add_webhook.invalid_path = Sti mรฅ ikke indeholde en del, der er "." eller ".." eller den tomme streng. Det kan ikke starte eller slutte med en skrรฅstreg.
+settings.webhook_deletion_desc = Fjernelse af en webhook sletter dens indstillinger og leveringshistorik. Vil du fortsรฆtte?
+settings.event_pull_request_assign = Tildeling
+settings.event_delete = Slet
+settings.event_delete_desc = Gren eller tag slettet.
+settings.event_fork = Fork
+settings.event_release_desc = Udgivelse offentliggjort, opdateret eller slettet i et depot.
+settings.event_pull_request_comment_desc = Pull-anmodning om kommentar oprettet, redigeret eller slettet.
+settings.event_pull_request_review = Anmeldelser
+settings.event_push_only = Push events
+settings.event_header_pull_request = Trรฆk anmodnings events
+settings.event_pull_request_milestone_desc = Milepรฆl tilfรธjet, fjernet eller รฆndret.
+settings.event_pull_request_label_desc = Pull-anmodnings etiketter tilfรธjet eller fjernet.
+settings.slack_icon_url = Icon URL
+settings.discord_icon_url.exceeds_max_length = Ikonets URL skal vรฆre mindre end eller lig med 2048 tegn
+settings.event_desc = Trigger pรฅ:
+settings.event_send_everything = Alle events
+settings.event_choose = Tilpassede begivenhederโฆ
+settings.web_hook_name_msteams = Microsoft Teams
+settings.web_hook_name_feishu = Feishu / Lark Suite
+settings.web_hook_name_feishu_only = Feishu
+settings.event_issue_label_desc = Problem etiketter tilfรธjet eller fjernet.
+settings.event_issue_milestone = Milepรฆle
+settings.event_pull_request_comment = Kommentarer
+settings.event_pull_request_assign_desc = Pull-anmodning tildelt eller ikke tildelt.
+settings.protect_status_check_matched = Matchet
+branch.deletion_success = Gren "%s" er blevet slettet.
+branch.deletion_failed = Kunne ikke slette grenen "%s".
+settings.event_create_desc = Gren eller tag oprettet.
+settings.event_header_repository = Depot events
+settings.event_create = Opret
+settings.event_pull_request = Modifikation
+settings.event_pull_request_desc = Pull-anmodning รฅbnet, lukket, genรฅbnet eller redigeret.
+settings.event_issue_assign = Tildeling
+settings.event_issues_desc = Problem รฅbnet, lukket, genรฅbnet eller redigeret.
+settings.event_issue_comment_desc = Problem kommentar oprettet, redigeret eller slettet.
+settings.webhook_deletion_success = Webhook er blevet fjernet.
+settings.web_hook_name_telegram = Telegram
+settings.webhook.headers = Headers
+settings.webhook.response = Svar
+settings.webhook.request = Anmod
+settings.event_pull_request_sync = Synkroniseret
+settings.slack_color = Farve
+settings.event_issues = Modifikation
+settings.event_issue_assign_desc = Problem tildelt eller ikke tildelt.
+settings.event_issue_milestone_desc = Milepรฆl tilfรธjet, fjernet eller รฆndret.
+settings.event_issue_comment = Kommentarer
+settings.event_repository_desc = Depot oprettet eller slettet.
+settings.event_header_issue = Problem events
+settings.event_fork_desc = Depot forked.
+branch.delete_head = Slet
+branch.delete = Slet gren "%s"
+branch.delete_html = Slet gren
+branch.delete_desc = Sletning af en gren er permanent. Selvom den slettede gren kan fortsรฆtte med at eksistere i kort tid, fรธr den rent faktisk bliver fjernet, KAN den i de fleste tilfรฆlde IKKE fortrydes. Vil du fortsรฆtte?
+settings.event_pull_request_milestone = Milepรฆle
+settings.webhook.test_delivery = Test levering
+settings.webhook.test_delivery_desc = Test denne webhook med en falsk begivenhed.
+settings.webhook.test_delivery_desc_disabled = For at teste denne webhook med en falsk begivenhed skal du aktivere den.
+settings.update_webhook = Opdatere webhook
+settings.discord_icon_url = Icon URL
+settings.web_hook_name_wechatwork = WeCom (Wechat Work)
+settings.web_hook_name_packagist = Packagist
+settings.packagist_username = Packagist brugernavn
+settings.packagist_api_token = API token
+settings.web_hook_name_matrix = Matrix
+settings.web_hook_name_larksuite_only = Lark Suite
+settings.update_hook_success = Webhook er blevet opdateret.
+settings.sourcehut_builds.secrets_helper = Giv jobbet adgang til byggehemmelighederne (krรฆver SECRETS:RO-bevillingen)
+settings.sourcehut_builds.access_token_helper = Adgangstoken, der har JOBS:RW-bevilling. Generer et builds.sr.ht-token eller et builds.sr.ht-token med hemmelig adgang pรฅ meta.sr.ht.
+settings.protect_approvals_whitelist_enabled_desc = Kun anmeldelser fra hvidlistede brugere eller teams tรฆller med til de pรฅkrรฆvede godkendelser. Uden hvidliste for godkendelse tรฆller anmeldelser fra alle med skriveadgang til de pรฅkrรฆvede godkendelser.
+settings.protect_protected_file_patterns_desc = Beskyttede filer mรฅ ikke รฆndres direkte, selvom brugeren har rettigheder til at tilfรธje, redigere eller slette filer i denne gren. Flere mรธnstre kan adskilles ved hjรฆlp af semikolon (";"). Se dokumentationen til %[2]s for mรธnstersyntaks. Eksempler: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns_desc = Ubeskyttede filer, der mรฅ รฆndres direkte, hvis brugeren har skriveadgang, uden at push-begrรฆnsning. Flere mรธnstre kan adskilles ved hjรฆlp af semikolon (";"). Se dokumentationen til %[2]s for mรธnstersyntaks. Eksempler: .drone.yml
, /docs/**/*.txt
.
+settings.block_rejected_reviews_desc = Fletning vil ikke vรฆre mulig, nรฅr der anmodes om รฆndringer af officielle korrekturlรฆsere, selvom der er tilstrรฆkkelige godkendelser.
+settings.event_pull_request_review_desc = Pull-anmodning godkendt, afvist, eller gennemgรฅ kommentarer tilfรธjet.
+settings.event_pull_request_review_request_desc = Pull-anmodning gennemgang anmodet eller gennemgang anmodning fjernet.
+settings.event_pull_request_approvals = Pull-anmodningsgodkendelser
+settings.event_pull_request_merge = Pull-anmodning flet
+settings.event_pull_request_enforcement = Hรฅndhรฆvelse
+settings.event_package_desc = Pakke oprettet eller slettet i et depot.
+settings.branch_filter = Gren filter
+settings.branch_filter_desc = Grenhvidliste til push, grenoprettelse og grensletningshรฆndelser, angivet som globmรธnster. Hvis den er tom eller *
, rapporteres hรฆndelser for alle filialer. Se dokumentationen til %[2]s for syntaks. Eksempler: master
, {master,release*}
.
+settings.active = Aktiv
+settings.active_helper = Oplysninger om udlรธste hรฆndelser vil blive sendt til denne webhook-URL.
+settings.add_hook_success = Webhook er tilfรธjet.
+settings.hook_type = Hook type
+settings.slack_token = Token
+settings.slack_domain = Domรฆne
+settings.add_web_hook_desc = Integrer %s i dit depot.
+settings.graphql_url = GraphQL URL
+settings.dismiss_stale_approvals_desc = Nรฅr nye commits, der รฆndrer indholdet af pull-anmodningen, skubbes til filialen, vil gamle godkendelser blive afvist.
+settings.require_signed_commits_desc = Afvis push til denne gren, hvis de er usignerede eller ikke kan verificeres.
+settings.protect_branch_name_pattern = Beskyttet gren navn mรธnster
+settings.protect_branch_name_pattern_desc = Beskyttede gren navne mรธnstre. Se dokumentationen for mรธnstersyntaks. Eksempler: main, release/**
+settings.block_on_official_review_requests_desc = Sammenlรฆgning vil ikke vรฆre mulig, nรฅr den har officielle anmodninger om gennemgang, selvom der er tilstrรฆkkelige godkendelser.
+settings.block_outdated_branch = Bloker fletning, hvis pull-anmodning er forรฆldet
+settings.block_outdated_branch_desc = Fletning vil ikke vรฆre mulig, nรฅr hovedgrenen er bagved basisgrenen.
+settings.tags.protection.pattern = Tag mรธnster
+settings.slack_channel = Kanal
+settings.web_hook_name_gitea = Gitea
+settings.web_hook_name_forgejo = Forgejo
+settings.web_hook_name_gogs = Gogs
+settings.protect_merge_whitelist_committers = Aktiver flet hvidliste
+settings.protect_merge_whitelist_committers_desc = Tillad kun hvidlistede brugere eller teams at flette pull-anmodninger ind i denne gren.
+settings.protect_status_check_patterns_desc = Indtast mรธnstre for at angive, hvilke statuskontroller der skal bestรฅ, fรธr grene kan flettes til en gren, der matcher denne regel. Hver linje angiver et mรธnster. Mรธnstre mรฅ ikke vรฆre tomme.
+settings.protect_no_valid_status_check_patterns = Ingen gyldige statuskontrolmรธnstre.
+settings.protect_required_approvals = Krรฆvede godkendelser
+settings.protect_required_approvals_desc = Tillad kun at flette pull-anmodning med nok positive anmeldelser.
+settings.protect_approvals_whitelist_enabled = Begrรฆns godkendelser til hvidlistede brugere eller teams
+settings.protect_approvals_whitelist_users = Hvidlistede anmeldere
+settings.protect_approvals_whitelist_teams = Hvidlistede hold til anmeldelser
+settings.dismiss_stale_approvals = Afvis forรฆldede godkendelser
+settings.remove_protected_branch_failed = Fjernelse af grenbeskyttelsesreglen "%s" mislykkedes.
+settings.protected_branch_deletion = Slet grenbeskyttelse
+settings.protected_branch_deletion_desc = Deaktivering af grenbeskyttelse giver brugere med skrivetilladelse mulighed for at push til grenen. Vil du fortsรฆtte?
+settings.enforce_on_admins_desc = Depotadministratorer kan ikke omgรฅ denne regel.
+settings.block_rejected_reviews = Bloker fletning pรฅ afviste anmeldelser
+settings.block_on_official_review_requests = Bloker fletning pรฅ officielle anmodninger om gennemgang
+settings.protected_branch_required_rule_name = Pรฅkrรฆvet regelnavn
+settings.protected_branch_duplicate_rule_name = Der er allerede en regel for dette sรฆt af grene
+settings.tags.protection.allowed = Tilladt
+settings.tags.protection.allowed.users = Tilladte brugere
+settings.event_pull_request_sync_desc = Gren opdateres automatisk med mรฅlgren.
+settings.event_pull_request_review_request = Gennemse forespรธrgsler
+settings.web_hook_name_discord = Discord
+settings.web_hook_name_dingtalk = DingTalk
+settings.protect_check_status_contexts_desc = Krรฆv statustjek for at bestรฅ fรธr fletning. Nรฅr det er aktiveret, skal commits fรธrst skubbes til en anden gren, derefter flettes eller skubbes direkte til en gren, der matcher denne regel, efter statustjek er bestรฅet. Hvis ingen kontekster matches, skal den sidste commit vรฆre vellykket uanset kontekst.
+settings.protect_check_status_contexts_list = Statustjek fundet i den sidste uge for dette depot
+settings.protect_protected_file_patterns = Beskyttede filmรธnstre (adskilt med semikolon ";")
+settings.protect_unprotected_file_patterns = Ubeskyttede filmรธnstre (adskilt med semikolon ";")
+settings.update_protect_branch_success = Filialbeskyttelse for reglen "%s" er blevet opdateret.
+settings.default_branch_desc = Vรฆlg en standardlagergren for pull-anmodninger og kode commits:
+settings.default_merge_style_desc = Standard flettestil
+settings.no_protected_branch = Der er ingen beskyttede grene.
+settings.edit_protected_branch = Redigere
+settings.protected_branch_required_approvals_min = Pรฅkrรฆvede godkendelser kan ikke vรฆre negative.
+settings.tags.protection = Tag beskyttelse
+release.edit = Redigere
+settings.event_package = Pakke
+settings.authorization_header_desc = Vil blive inkluderet som autorisationshoved for anmodninger, nรฅr de er til stede. Eksempler: %s.
+settings.delete_webhook = Fjern webhook
+settings.recent_deliveries = Seneste leverancer
+settings.deploy_key_deletion_desc = Fjernelse af en deploy nรธgle vil tilbagekalde dens adgang til dette depot. Vil du fortsรฆtte?
+settings.merge_style_desc = Flettestil
+settings.choose_branch = Vรฆlg en grenโฆ
+settings.tags = Tags
+settings.protected_branch = Gren beskyttelse
+settings.protected_branch.save_rule = Gem regel
+settings.protect_whitelist_teams = Hvidlistede hold til at skubbe
+settings.protect_patterns = Mรธnstre
+settings.web_hook_name_slack = Slack
+settings.packagist_package_url = Packagist-pakke-URL
+settings.web_hook_name_sourcehut_builds = SourceHut Builds
+settings.sourcehut_builds.manifest_path = Build manifest sti
+settings.sourcehut_builds.visibility = Jobsynlighed
+settings.sourcehut_builds.secrets = Hemmeligheder
+settings.authorization_header = Autorisationshoved
+settings.deploy_keys = Deploy nรธgler
+settings.add_deploy_key = Tilfรธj deploy nรธgle
+settings.deploy_key_desc = Deploy nรธgler har skrivebeskyttet pull-adgang til depotet.
+settings.is_writable = Aktiver skriveadgang
+settings.is_writable_info = Tillad denne deploy nรธgle at skubbe til depotet.
+settings.no_deploy_keys = Der er ingen deploy nรธgler endnu.
+settings.key_been_used = En deploy nรธgle med identisk indhold er allerede i brug.
+settings.key_name_used = En deploy nรธgle med identisk navn er allerede i brug.
+settings.add_key_success = Deploy nรธglen "%s" er blevet tilfรธjet.
+settings.deploy_key_deletion = Slet deploy nรธglen
+settings.deploy_key_deletion_success = Deploy nรธglen er blevet slettet.
+settings.branches = Grene
+settings.protected_branch.delete_rule = Slet regel
+settings.branch_protection = Beskyttelsesregler for grenen "%s "
+settings.protect_new_rule = Opret en ny gren beskyttelsesregel
+settings.protect_disable_push = Deaktiver push
+settings.protect_disable_push_desc = Ingen push vil vรฆre tilladt til denne gren.
+settings.protect_enable_push = Aktiver push
+settings.protect_enable_push_desc = Enhver med skriveadgang fรฅr lov til at pushe til denne gren (men ikke tvinge push).
+settings.protect_enable_merge = Aktiver fletning
+settings.protect_enable_merge_desc = Enhver med skriveadgang fรฅr lov til at flette pull-anmodningerne ind i denne gren.
+settings.protect_whitelist_committers = Hvidliste begrรฆnset push
+settings.protect_whitelist_committers_desc = Kun hvidlistede brugere eller hold vil fรฅ lov til at pushe til denne gren (men ikke tvinge push).
+settings.protect_whitelist_deploy_keys = Whitelist deploy nรธgler med skriveadgang til push.
+settings.protect_whitelist_users = Hvidlistede brugere til at skubbe
+settings.protect_merge_whitelist_users = Hvidlistede brugere til fletning
+settings.protect_merge_whitelist_teams = Hvidlistede hold til fletning
+settings.protect_check_status_contexts = Aktiver statuskontrol
+settings.protect_status_check_patterns = Statuskontrolmรธnstre
+settings.protect_invalid_status_check_pattern = Ugyldigt statuskontrolmรธnster: "%s".
+settings.ignore_stale_approvals = Ignorer forรฆldede godkendelser
+settings.ignore_stale_approvals_desc = Tรฆl ikke godkendelser, der er foretaget pรฅ รฆldre commits (gamle anmeldelser) med, hvor mange godkendelser PR'en har. Irrelevant, hvis uaktuelle anmeldelser allerede er afvist.
+settings.require_signed_commits = Krรฆv underskrevne commits
+settings.remove_protected_branch_success = Grenbeskyttelse for reglen "%s" er blevet fjernet.
+settings.enforce_on_admins = Hรฅndhรฆv denne regel for depotadministratorer
+
+settings.tags.protection.allowed.teams = Tilladte hold
+settings.tags.protection.allowed.noone = Ingen
+settings.tags.protection.create = Tilfรธj regel
+settings.tags.protection.none = Der er ingen beskyttede tags.
+settings.tags.protection.pattern.description = Du kan bruge et enkelt navn eller et globmรธnster eller regulรฆrt udtryk til at matche flere tags. Lรฆs mere i guiden til beskyttede tags .
+settings.bot_token = Bot token
+settings.chat_id = Chat ID
+settings.thread_id = Thread ID
+settings.matrix.homeserver_url = Hjemmeserver URL
+settings.matrix.room_id = Rum ID
+settings.matrix.message_type = Meddelelsestype
+settings.matrix.access_token_helper = Det anbefales at opsรฆtte en dedikeret Matrix-konto til dette. Adgangstokenet kan hentes fra Element-webklienten (i en privat/inkognito-fane) > Brugermenu (รธverst til venstre) > Alle indstillinger > Hjรฆlp og om > Avanceret > Adgangstoken (lige under hjemmeserverens URL). Luk privat-/inkognitofanen (logging ud ville ugyldiggรธre tokenet).
+settings.matrix.room_id_helper = Rum-id'et kan hentes fra Element-webklienten > Rumindstillinger > Avanceret > Internt rum-id. Eksempel: %s.
+settings.archive.button = Arkivere depot
+settings.archive.header = Arkivere dette depot
+settings.archive.text = Arkivering af depotet vil gรธre den fuldstรฆndig skrivebeskyttet. Det vil blive skjult fra dashboardet. Ingen (ikke engang dig!) vil vรฆre i stand til at foretage nye commits eller รฅbne nogen problemer eller pull-anmodninger.
+settings.archive.success = Depotet blev arkiveret.
+settings.archive.error = Der opstod en fejl under forsรธg pรฅ at arkivere depotet. Se loggen for flere detaljer.
+settings.archive.error_ismirror = Du kan ikke arkivere et spejlet depot.
+settings.archive.branchsettings_unavailable = Indstillinger for gren er ikke tilgรฆngelige i arkiverede depoter.
+settings.archive.tagsettings_unavailable = Tag-indstillinger er ikke tilgรฆngelige i arkiverede depoter.
+settings.archive.mirrors_unavailable = Spejle er ikke tilgรฆngelige i arkiverede depoter.
+settings.unarchive.button = Fjern arkivering af depot
+settings.unarchive.header = Fjern arkivering af dette depot
+settings.unarchive.text = Fjernelse af arkivering af depotet vil genoprette dens evne til at modtage commits og push, sรฅvel som nye problemer og pull-anmodninger.
+settings.unarchive.success = Depotet blev fjernet fra arkivet.
+settings.unarchive.error = Der opstod en fejl under forsรธg pรฅ at fjerne depotet fra arkivet. Se loggen for flere detaljer.
+settings.update_avatar_success = Depot avataren er blevet opdateret.
+settings.lfs = LFS
+settings.lfs_filelist = LFS-filer gemt i dette depot
+settings.lfs_no_lfs_files = Ingen LFS-filer gemt i dette depot
+settings.lfs_findcommits = Find commits
+settings.lfs_lfs_file_no_commits = Ingen commits fundet for denne LFS-fil
+settings.lfs_noattribute = Denne sti har ikke den lรฅsbare attribut i standardgrenen
+settings.lfs_delete = Slet LFS-fil med OID %s
+settings.lfs_delete_warning = Sletning af en LFS-fil kan forรฅrsage "objekt findes ikke"-fejl ved checkout. Er du sikker?
+settings.lfs_findpointerfiles = Find pointer-filer
+settings.lfs_locks = Lรฅse
+settings.lfs_invalid_locking_path = Ugyldig sti: %s
+settings.lfs_invalid_lock_directory = Kan ikke lรฅse mappe: %s
+settings.lfs_lock_already_exists = Lรฅsen findes allerede: %s
+settings.lfs_pointers.associateAccessible = Tilknyt tilgรฆngelige %d OID'er
+settings.rename_branch_failed_protected = Kan ikke omdรธbe grenen %s, fordi den er en beskyttet gren.
+settings.rename_branch_failed_exist = Kan ikke omdรธbe grenen, fordi mรฅlgrenen %s eksisterer.
+settings.rename_branch_failed_not_exist = Kan ikke omdรธbe grenen %s, fordi den ikke eksisterer.
+settings.rename_branch_success = Grenen %s blev omdรธbt til %s.
+settings.rename_branch = Omdรธb gren
+diff.browse_source = Gennemse kilde
+diff.parent = forรฆlder
+diff.commit = commit
+diff.git-notes = Noter
+diff.git-notes.add = Tilfรธj note
+diff.git-notes.remove-header = Fjern note
+diff.git-notes.remove-body = Denne note vil blive fjernet.
+diff.data_not_available = Diff-indhold er ikke tilgรฆngeligt
+diff.options_button = Diff muligheder
+diff.download_patch = Download patch-fil
+diff.download_diff = Download diff fil
+diff.show_split_view = Opdelt visning
+diff.show_unified_view = Samlet visning
+diff.whitespace_button = Blanke mellemrum
+diff.whitespace_show_everything = Vis alle รฆndringer
+diff.whitespace_ignore_all_whitespace = Ignorer blanke mellemrum, nรฅr du sammenligner linjer
+diff.whitespace_ignore_amount_changes = Ignorer รฆndringer i mรฆngden af blanke mellemrum
+diff.whitespace_ignore_at_eol = Ignorer รฆndringer i blanke mellemrum pรฅ EOL
+diff.stats_desc = %d รฆndrede filer med %d tilfรธjelser og %d sletninger
+diff.stats_desc_file = %d รฆndringer: %d tilfรธjelser og %d sletninger
+diff.bin = BIN
+diff.bin_not_shown = Binรฆr fil vises ikke.
+diff.view_file = Se fil
+diff.file_before = Fรธr
+diff.file_after = Efter
+diff.file_image_width = Bredde
+diff.file_image_height = Hรธjde
+diff.file_byte_size = Stรธrrelse
+diff.file_suppressed = Filforskellen er undertrykt, fordi den er for stor
+diff.file_suppressed_line_too_long = Filforskellen er undertrykt, fordi en eller flere linjer er for lange
+diff.too_many_files = Nogle filer blev ikke vist, fordi der er รฆndret for mange filer i denne diff
+diff.show_more = Vis mere
+diff.load = Load diff
+diff.generated = genereret
+diff.vendored = forhandlet
+diff.comment.add_line_comment = Tilfรธj linjekommentar
+diff.comment.placeholder = Efterlad en kommentar
+diff.comment.markdown_info = Styling med Markdown understรธttes.
+diff.comment.add_single_comment = Tilfรธj en enkelt kommentar
+diff.comment.add_review_comment = Tilfรธj kommentar
+diff.comment.start_review = Start anmeldelse
+diff.comment.reply = Svar
+diff.review = Afslut gennemgangen
+diff.review.header = Send anmeldelse
+diff.review.placeholder = Gennemgรฅ kommentar
+diff.review.comment = Kommentar
+diff.review.approve = Godkend
+diff.review.self_reject = Forfattere af pull-anmodninger kan ikke anmode om รฆndringer pรฅ deres egen pull-anmodning
+diff.review.reject = Anmod om รฆndringer
+diff.review.self_approve = Forfattere af pull-anmodninger kan ikke godkende deres egen pull-anmodning
+diff.committed_by = committed af
+diff.protected = Beskyttet
+diff.image.side_by_side = Side om side
+diff.image.swipe = Swipe
+diff.image.overlay = Overlejring
+diff.has_escaped = Denne linje har skjulte Unicode-tegn
+diff.show_file_tree = Vis filtrรฆ
+diff.hide_file_tree = Skjul filtrรฆ
+releases.desc = Spor projektversioner og downloads.
+release.releases = Udgivelser
+release.detail = Udgivelsesdetaljer
+release.tags = Tags
+release.new_release = Ny udgivelse
+release.draft = Udkast
+release.prerelease = Forhรฅndsudgivelse
+release.stable = Stabil
+release.compare = Sammenlign
+release.ahead.commits = %d commits
+release.ahead.target = til %s siden denne udgivelse
+tag.ahead.target = til %s siden dette tag
+release.source_code = Kildekode
+release.new_subheader = Udgivelser organiserer projektversioner.
+release.edit_subheader = Udgivelser organiserer projektversioner.
+release.tag_name = Tag navn
+release.target = Mรฅl
+release.tag_helper = Vรฆlg et eksisterende tag, eller opret et nyt tag.
+release.tag_helper_new = Nyt tag. Dette tag vil blive oprettet fra mรฅlet.
+release.tag_helper_existing = Eksisterende tag.
+release.title = Udgivelsestitel
+release.title_empty = Titel mรฅ ikke vรฆre tom.
+release.message = Beskriv denne udgivelse
+release.prerelease_desc = Markรฉr som pre-release
+release.prerelease_helper = Marker denne udgivelse uegnet til produktionsbrug.
+release.deletion_desc = Sletning af en udgivelse fjerner den kun fra Forgejo. Det vil ikke pรฅvirke Git-tagget, indholdet af dit depot eller dets historie. Vil du fortsรฆtte?
+release.deletion_success = Udgivelsen er blevet slettet.
+release.deletion_tag_desc = Vil slette dette tag fra depotet. Depotindhold og -historik forbliver uรฆndret. Vil du fortsรฆtte?
+release.deletion_tag_success = Tagget er blevet slettet.
+release.tag_name_already_exist = Der findes allerede en udgivelse med dette tagnavn.
+release.tag_name_invalid = Tagnavnet er ikke gyldigt.
+release.tag_name_protected = Tagnavnet er beskyttet.
+release.tag_already_exist = Dette tagnavn findes allerede.
+release.downloads = Downloads
+release.download_count_one = %s download
+release.download_count_few = %s downloads
+release.add_tag_msg = Brug udgivelsens titel og indhold som tagmeddelelse.
+release.hide_archive_links = Skjul automatisk genererede arkiver
+release.hide_archive_links_helper = Skjul automatisk genererede kildekodearkiver for denne udgivelse. For eksempel hvis du uploader din egen.
+release.add_tag = Opret tag
+release.releases_for = Udgivelser for %s
+release.tags_for = Tags for %s
+release.system_generated = Denne vedhรฆftede fil genereres automatisk.
+release.type_attachment = Vedhรฆftning
+release.type_external_asset = Eksternt aktiv
+release.asset_name = Aktivets navn
+release.asset_external_url = Ekstern URL
+release.add_external_asset = Tilfรธj eksternt aktiv
+release.invalid_external_url = Ugyldig ekstern URL: "%s"
+release.summary_card_alt = Oversigtskort for en udgivelse med titlen "%s" i depots %s
+branch.name = Gren navn
+branch.already_exists = En gren med navnet "%s" eksisterer allerede.
+branch.delete_branch_has_new_commits = Gren "%s" kan ikke slettes, fordi nye commits er blevet tilfรธjet efter fletning.
+branch.create_branch = Opret gren %s
+branch.create_from = fra "%s"
+branch.create_success = Gren "%s" er blevet oprettet.
+branch.branch_already_exists = Gren "%s" findes allerede i dette depot.
+branch.branch_name_conflict = Gren navn "%s" er i konflikt med den allerede eksisterende gren "%s".
+branch.tag_collision = Gren "%s" kan ikke oprettes, da et tag med samme navn allerede eksisterer i depotet.
+branch.deleted_by = Slettet af %s
+branch.restore_success = Gren "%s" er blevet gendannet.
+branch.restore_failed = Kunne ikke gendanne grenen "%s".
+branch.protected_deletion_failed = Gren "%s" er beskyttet. Det kan ikke slettes.
+branch.default_deletion_failed = Gren "%s" er standardgrenen. Det kan ikke slettes.
+branch.restore = Gendan grenen "%s"
+branch.download = Download gren "%s"
+branch.rename = Omdรธb grenen "%s"
+branch.included_desc = Denne gren er en del af standardgrenen
+branch.included = Inkluderet
+branch.create_new_branch = Opret en gren fra gren:
+branch.confirm_create_branch = Opret gren
+branch.warning_rename_default_branch = Du omdรธber standardgrenen.
+branch.rename_branch_to = Omdรธb "%s" til:
+branch.create_branch_operation = Opret gren
+branch.new_branch = Opret ny gren
+branch.new_branch_from = Opret ny gren fra "%s"
+branch.renamed = Gren %s blev omdรธbt til %s.
+tag.create_tag = Opret tag %s
+tag.create_tag_operation = Opret tag
+tag.confirm_create_tag = Opret tag
+tag.create_tag_from = Opret nyt tag fra "%s"
+tag.create_success = Tag "%s" er blevet oprettet.
+topic.manage_topics = Administrer emner
+topic.done = Fรฆrdig
+topic.count_prompt = Du kan ikke vรฆlge mere end 25 emner
+topic.format_prompt = Emner skal starte med et bogstav eller tal, kan indeholde bindestreger ("-") og prikker ("."), kan vรฆre op til 35 tegn lange. Bogstaver skal vรฆre smรฅ.
+find_file.go_to_file = Find en fil
+find_file.no_matching = Ingen matchende fil fundet
+error.csv.too_large = Denne fil kan ikke gengives, fordi den er for stor.
+error.csv.unexpected = Denne fil kan ikke gengives, fordi den indeholder et uventet tegn i linje %d og kolonne %d.
+error.csv.invalid_field_count = Denne fil kan ikke gengives, fordi den har et forkert antal felter i linje %d.
+error.broken_git_hook = Git hooks af dette depot ser ud til at vรฆre brudt. Fรธlg venligst dokumentationen for at rette dem, og push derefter pรฅ nogle commits for at opdatere statussen.
+
+[notification]
+watching = Overvรฅger
+read = Lรฆs
+
+notifications = Notifikationer
+unread = Ulรฆst
+no_unread = Ingen ulรฆste notifikationer.
+no_read = Ingen lรฆste notifikationer.
+mark_as_read = Markรฉr som lรฆst
+mark_as_unread = Markรฉr som ulรฆst
+mark_all_as_read = Markรฉr alle som lรฆste
+subscriptions = Abonnementer
+no_subscriptions = Ingen abonnementer
+
+pin = Fastgรธr notifikation
+
+[action]
+watched_repo = begyndte at overvรฅge %[2]s
+
+create_repo = oprettede depot %s
+rename_repo = omdรธbt depot fra %[1]s
til %[3]s
+commit_repo = pushed til %[3]s at %[4]s
+create_issue = `รฅbnet problem %[3]s#%[2]s `
+close_issue = `lukket problem %[3]s#%[2]s `
+reopen_issue = `genรฅbnet problem %[3]s#%[2]s `
+create_pull_request = `oprettet pull-anmodning %[3]s#%[2]s `
+close_pull_request = `lukket pull request %[3]s#%[2]s `
+reopen_pull_request = `genรฅbnet pull request %[3]s#%[2]s `
+comment_issue = `kommenterede problem %[3]s#%[2]s `
+comment_pull = `kommenterede pull request %[3]s#%[2]s `
+merge_pull_request = `sammenflettet pull request %[3]s#%[2]s `
+auto_merge_pull_request = `automatisk flettet pull-anmodning %[3]s#%[2]s `
+transfer_repo = overfรธrte lager %s
til %s
+push_tag = skubbet tag %[3]s til %[4]s
+delete_tag = slettede tag %[2]s fra %[3]s
+delete_branch = slettede gren %[2]s fra %[3]s
+compare_branch = Sammenlign
+compare_commits = Sammenlign %d commits
+compare_commits_general = Sammenlign commits
+mirror_sync_push = synkroniserede commits til %[3]s ved %[4]s fra spejl
+mirror_sync_create = synkroniseret ny reference %[3]s til %[4]s fra spejl
+mirror_sync_delete = synkroniseret og slettet reference %[2]s
ved %[3]s fra spejl
+approve_pull_request = `godkendt %[3]s#%[2]s `
+reject_pull_request = `foreslรฅet รฆndringer for %[3]s#%[2]s `
+publish_release = `udgivet %[4]s pรฅ %[3]s `
+review_dismissed = `afvist anmeldelse fra %[4]s for %[3]s#%[2]s `
+review_dismissed_reason = ร
rsag:
+create_branch = oprettede gren %[3]s i %[4]s
+starred_repo = stjernemarkerede %[2]s
+
+[org]
+repo_updated = Opdateret %s
+lower_members = medlemmer
+teams = Teams
+members = Medlemmer
+org_desc = Beskrivelse
+team_desc = Beskrivelse
+teams.read_access = Lรฆs
+members.owner = Ejer
+settings.options = Organisation
+settings.full_name = Fulde navn
+teams.settings = Indstillinger
+teams.no_desc = Dette team har ingen beskrivelse
+teams.write_access = Skriv
+teams.admin_access = Administrator adgang
+teams.admin_access_helper = Medlemmer kan trรฆkke og skubbe til teamdepoter og tilfรธje samarbejdspartnere til dem.
+settings = Indstillinger
+settings.repoadminchangeteam = Depotsadministrator kan tilfรธje og fjerne adgang for teams
+settings.visibility.public = Offentlig
+settings.visibility.private = Privat (kun synlig for organisationsmedlemmer)
+settings.visibility.limited_shortname = Begrรฆnset
+settings.visibility.limited = Begrรฆnset (kun synlig for brugere, der er logget ind)
+settings.visibility.private_shortname = Privat
+settings.website = Websted
+settings.location = Lokation
+settings.permission = Tilladelser
+settings.visibility = Synlighed
+members.remove = Slet
+
+org_name_holder = Organisationens navn
+org_full_name_holder = Organisationens fulde navn
+org_name_helper = Organisationsnavne skal vรฆre korte og mindevรฆrdige.
+create_org = Opret organisation
+open_dashboard = ร
bn dashboard
+code = Kode
+lower_repositories = depoter
+create_new_team = Nyt team
+create_team = Opret team
+team_name = Team navn
+team_name_helper = Team navne skal vรฆre korte og mindevรฆrdige.
+team_desc_helper = Beskriv teamets formรฅl eller rolle.
+team_access_desc = Depot adgang
+team_permission_desc = Tilladelse
+team_unit_desc = Tillad adgang til depotsektioner
+team_unit_disabled = (Deaktiveret)
+follow_blocked_user = Du kan ikke fรธlge denne organisation, fordi denne organisation har blokeret dig.
+form.name_reserved = Organisationsnavnet "%s" er reserveret.
+form.name_pattern_not_allowed = Mรธnsteret "%s" er ikke tilladt i et organisationsnavn.
+form.create_org_not_allowed = Du har ikke tilladelse til at oprette en organisation.
+settings.email = Kontakt email
+settings.update_settings = Opdater indstillinger
+settings.update_setting_success = Organisationsindstillingerne er blevet opdateret.
+settings.change_orgname_prompt = Bemรฆrk: รndring af organisationens navn vil ogsรฅ รฆndre din organisations URL og frigรธre det gamle navn.
+settings.change_orgname_redirect_prompt = Det gamle navn vil omdirigere, indtil det gรธres krav pรฅ.
+settings.change_orgname_redirect_prompt.with_cooldown.one = Det gamle organisationsnavn vil vรฆre tilgรฆngeligt for alle efter en nedkรธlingsperiode pรฅ %[1]d dag, du kan stadig krรฆve det gamle navn tilbage i nedkรธlingsperioden.
+settings.change_orgname_redirect_prompt.with_cooldown.few = Det gamle organisationsnavn vil vรฆre tilgรฆngeligt for alle efter en nedkรธlingsperiode pรฅ %[1]d dage, du kan stadig krรฆve det gamle navn tilbage i .
+settings.update_avatar_success = Organisationens avatar er blevet opdateret.
+settings.delete = Slet organisation
+settings.delete_account = Slet denne organisation
+settings.delete_prompt = Organisationen fjernes permanent. Dette KAN IKKE fortrydes!
+settings.confirm_delete_account = Bekrรฆft sletning
+settings.delete_org_title = Slet organisation
+settings.delete_org_desc = Denne organisation vil blive slettet permanent. Vil du fortsรฆtte?
+settings.hooks_desc = Tilfรธj webhooks, som vil blive udlรธst for alle lagre under denne organisation.
+settings.labels_desc = Tilfรธj etiketter, som kan bruges til problemer for alle lagre under denne organisation.
+members.membership_visibility = Medlemskabs synlighed:
+members.public = Synlig
+members.public_helper = Gรธr skjult
+members.private = Skjult
+members.private_helper = Gรธr synlig
+members.member_role = Medlemsrolle:
+members.member = Medlem
+members.remove.detail = Vil du fjerne %[1]s fra %[2]s?
+members.leave = Forlad
+members.leave.detail = Er du sikker pรฅ, at du vil forlade organisationen "%s"?
+members.invite_desc = Tilfรธj et nyt medlem til %s:
+members.invite_now = Inviter nu
+teams.join = Deltag
+teams.leave = Forlad
+teams.leave.detail = Er du sikker pรฅ, at du vil forlade teamet "%s"?
+teams.can_create_org_repo = Opret depoter
+teams.can_create_org_repo_helper = Medlemmer kan oprette nye arkiver i organisationen. Skaberen fรฅr administratoradgang til det nye lager.
+teams.none_access = Ingen adgang
+teams.none_access_helper = Muligheden "ingen adgang" har kun effekt pรฅ private arkiver.
+teams.general_access = Brugerdefineret adgang
+teams.general_access_helper = Medlemmers tilladelser bestemmes af nedenstรฅende tilladelsestabell.
+teams.owners_permission_desc = Ejere har fuld adgang til alle depoter og har administratoradgang til organisationen.
+teams.members = Team medlemmer
+teams.update_settings = Opdater indstillinger
+teams.delete_team = Slet team
+teams.add_team_member = Slet team
+teams.invite_team_member = Inviter til %s
+teams.invite_team_member.list = Afventende invitationer
+teams.delete_team_title = Slet team
+teams.delete_team_desc = Sletning af et team tilbagekalder depotadgang fra dets medlemmer. Vil du fortsรฆtte?
+teams.delete_team_success = Teamet er blevet slettet.
+teams.read_permission_desc = Dette team giver lรฆse adgang: medlemmer kan se og klone teamdepoter.
+teams.write_permission_desc = Dette team giver Skrive adgang: medlemmer kan lรฆse fra og skubbe til teamdepoter.
+teams.admin_permission_desc = Dette team giver Administrator adgang: medlemmer kan lรฆse fra, skubbe til og tilfรธje samarbejdspartnere til teamdepoter.
+teams.create_repo_permission_desc = Derudover giver dette team tilladelse til Opret depot : medlemmer kan oprette nye lagre i organisationen.
+teams.repositories = Team depoter
+teams.remove_all_repos_title = Slet alle team depoter
+teams.remove_all_repos_desc = Dette vil slette alle depoter fra teamet
+teams.add_all_repos_title = Tilfรธj alle depoter
+teams.add_all_repos_desc = Dette vil tilfรธje alle organisationens depoter til teamet.
+teams.add_nonexistent_repo = Depotet, du forsรธger at tilfรธje, eksisterer ikke, opret det fรธrst.
+teams.add_duplicate_users = Brugeren er allerede et teammedlem.
+teams.repos.none = Ingen depoter kunne tilgรฅs af dette team.
+teams.members.none = Ingen medlemmer pรฅ dette team.
+teams.specific_repositories = Specifikke depoter
+teams.specific_repositories_helper = Medlemmer vil kun have adgang til depoter, der udtrykkeligt er fรธjet til teamet. Hvis du vรฆlger dette vil det ikke automatisk fjerne depoter, der allerede er tilfรธjet med Alle depoter .
+teams.all_repositories = Alle depoter
+teams.all_repositories_helper = Teamet har adgang til alle depoter. Hvis du vรฆlger dette, fรธjes alle eksisterende depoter til teamet.
+teams.invite.title = Du er blevet inviteret til at deltage i teamet %s i organisationen %s .
+teams.invite.by = Inviteret af %s
+teams.invite.description = Klik venligst pรฅ knappen nedenfor for at blive medlem af teamet.
+
+[admin]
+orgs.members = Medlemmer
+orgs.teams = Teams
+orgs.new_orga = Ny organisation
+monitor.desc = Beskrivelse
+emails.filter_sort.name = Brugernavn
+notices.desc = Beskrivelse
+config.db_user = Brugernavn
+users.name = Brugernavn
+emails.activated = Aktiveret
+packages.repository = Depot
+config.mailer_enabled = Aktiveret
+emails.filter_sort.email = Email
+auths.name = Navn
+config.mailer_name = Navn
+auths.enabled = Aktiveret
+config_settings = Indstillinger
+config.ssh_enabled = Aktiveret
+config.lfs_enabled = Aktiveret
+monitor.name = Navn
+config.oauth_enabled = Aktiveret
+orgs.name = Navn
+repos.owner = Ejer
+packages.name = Navn
+packages.owner = Ejer
+notices.type_1 = Depot
+config.db_name = Navn
+users.full_name = Fulde navn
+users.activated = Aktiveret
+repos.name = Navn
+monitor.queue.name = Navn
+repos.private = Privat
+config.default_enable_timetracking = Aktiver tidsregistrering som standard
+config.enable_timetracking = Aktiver tidsregistrering
+config.default_allow_only_contributors_to_track_time = Lad kun bidragydere spore tid
+config.allow_dots_in_usernames = Tillad brugere at bruge prikker i deres brugernavne. Pรฅvirker ikke eksisterende konti.
+auths.oauth2_icon_url = Icon URL
+users.edit = Redigere
+users.auth_source = Godkendelseskilde
+
+dashboard = Instrumentpanel
+self_check = Selvtjek
+identity_access = Identitet og adgang
+users = Brugerkonti
+organizations = Organisationer
+assets = Kode aktiver
+repositories = Depoter
+hooks = Webhooks
+integrations = Integrationer
+authentication = Godkendelseskilder
+emails = Bruger e-mails
+config = Konfiguration
+notices = Systemmeddelelser
+config_summary = Oversigt
+monitor = Overvรฅgning
+first_page = Fรธrst
+last_page = Sidst
+total = Total: %d
+settings = Admin indstillinger
+dashboard.new_version_hint = Forgejo %s er nu tilgรฆngelig, du kรธrer %s. Tjek bloggen for flere detaljer.
+dashboard.statistic = Oversigt
+dashboard.operations = Vedligeholdelses operationer
+dashboard.system_status = System status
+dashboard.operation_name = Operations navn
+dashboard.operation_switch = Skift
+dashboard.operation_run = Kรธr
+dashboard.clean_unbind_oauth = Rens ubundne OAuth-forbindelser
+dashboard.clean_unbind_oauth_success = Alle ubundne OAuth-forbindelser er blevet slettet.
+dashboard.task.started = Startet opgave: %[1]s
+dashboard.task.process = Opgave: %[1]s
+dashboard.task.cancelled = Opgave: %[1]s annulleret: %[3]s
+dashboard.task.error = Fejl i Opgave: %[1]s: %[3]s
+dashboard.task.finished = Opgave: %[1]s startet af %[2]s er afsluttet
+dashboard.task.unknown = Ukendt opgave: %[1]s
+dashboard.cron.started = Startede Cron: %[1]s
+dashboard.cron.process = Cron: %[1]s
+dashboard.cron.cancelled = Cron: %[1]s annulleret: %[3]s
+dashboard.cron.error = Fejl i Cron: %s: %[3]s
+dashboard.cron.finished = Cron: %[1]s er fรฆrdig
+dashboard.delete_inactive_accounts = Slet alle uaktiverede konti
+dashboard.delete_inactive_accounts.started = Slet alle uaktiverede konti opgave startet.
+dashboard.delete_repo_archives = Slet alle depoters arkiver (ZIP, TAR.GZ osv..)
+dashboard.delete_repo_archives.started = Slet alle repository arkiver opgave startet.
+dashboard.delete_missing_repos = Slet alle depoter, der mangler deres Git-filer
+dashboard.delete_missing_repos.started = Slet alle depoter, der mangler deres Git-filopgave startet.
+dashboard.delete_generated_repository_avatars = Slet genererede depot avatarer
+dashboard.sync_repo_branches = Synkroniser mistede grene fra Git-data til databasen
+dashboard.sync_repo_tags = Synkroniser tags fra Git-data til database
+dashboard.update_mirrors = Opdater spejle
+dashboard.repo_health_check = Sundhedstjek alle depoter
+dashboard.check_repo_stats = Tjek alle depotstatistikker
+dashboard.archive_cleanup = Slet gamle depotarkiver
+dashboard.deleted_branches_cleanup = Ryd op i slettede grene
+dashboard.update_migration_poster_id = Opdater migrationsplakat-id'er
+dashboard.git_gc_repos = Samle alt affald fra alle depoter
+dashboard.resync_all_sshkeys = Opdater filen ".ssh/authorized_keys" med Forgejo SSH-nรธgler.
+dashboard.resync_all_sshprincipals = Opdater ".ssh/authorized_principals" filen med Forgejo SSH principals.
+dashboard.resync_all_hooks = Gensynkroniser pre-receive, update og post-receive hooks for alle depoter
+dashboard.reinit_missing_repos = Geninitialiser alle manglende Git-depoter, som der findes poster for
+dashboard.sync_external_users = Synkroniser eksterne brugerdata
+dashboard.cleanup_hook_task_table = Oprydning hook_task tabel
+dashboard.cleanup_packages = Ryd udlรธbne pakker
+dashboard.cleanup_actions = Oprydning af udlรธbne logfiler og artefakter fra handlinger
+dashboard.server_uptime = Server oppetid
+dashboard.current_goroutine = Nuvรฆrende goroutiner
+dashboard.current_memory_usage = Aktuel hukommelsesbrug
+dashboard.total_memory_allocated = Samlet hukommelse tildelt
+dashboard.memory_obtained = Hukommelse opnรฅet
+dashboard.pointer_lookup_times = Pointer-opslagstider
+dashboard.memory_allocate_times = Hukommelsestildelinger
+dashboard.memory_free_times = Hukommelses frigรธrelse
+dashboard.current_heap_usage = Nuvรฆrende heap-brug
+dashboard.heap_memory_obtained = Heap-hukommelse opnรฅet
+dashboard.heap_memory_idle = Heap hukommelse inaktiv
+dashboard.heap_memory_in_use = Heap hukommelse i brug
+dashboard.heap_memory_released = Heap-hukommelse frigivet
+dashboard.heap_objects = Heap genstande
+dashboard.bootstrap_stack_usage = Brug af bootstrap-stak
+dashboard.stack_memory_obtained = Stakhukommelse opnรฅet
+dashboard.mspan_structures_usage = MSpan strukturer brug
+dashboard.mspan_structures_obtained = Mspan strukturer opnรฅet
+dashboard.mcache_structures_usage = MCache strukturer brug
+dashboard.mcache_structures_obtained = MCache-strukturer opnรฅet
+dashboard.profiling_bucket_hash_table_obtained = Profilering bucket hash tabel opnรฅet
+dashboard.gc_metadata_obtained = GC-metadata opnรฅet
+dashboard.other_system_allocation_obtained = Anden systemallokering opnรฅet
+dashboard.next_gc_recycle = Nรฆste GC genbrug
+dashboard.last_gc_time = Tid siden sidste GC
+dashboard.total_gc_pause = Total GC-pause
+dashboard.last_gc_pause = Sidste GC-pause
+dashboard.gc_times = GC times
+dashboard.delete_old_actions = Slet alle gamle aktiviteter fra databasen
+dashboard.delete_old_actions.started = Slet alle gamle aktiviteter fra den pรฅbegyndte database.
+dashboard.update_checker = Opdateringskontrol
+dashboard.delete_old_system_notices = Slet alle gamle systemmeddelelser fra databasen
+dashboard.gc_lfs = Affaldssamler LFS-metaobjekter
+dashboard.stop_zombie_tasks = Stop zombiehandlingsopgaver
+dashboard.stop_endless_tasks = Stop endelรธse handlingsopgaver
+dashboard.cancel_abandoned_jobs = Annuller forladte handlingsjob
+dashboard.start_schedule_tasks = Start planlรฆg handlingsopgaver
+dashboard.sync_branch.started = Gren synkronisering startede
+dashboard.sync_tag.started = Tag-synkronisering er startet
+dashboard.rebuild_issue_indexer = Genopbyg problemindekser
+users.user_manage_panel = Administrer brugerkonti
+users.new_account = Opret brugerkonto
+users.admin = Admin
+users.restricted = Begrรฆnset
+users.reserved = Reserveret
+users.bot = Bot
+users.remote = Remote
+users.2fa = 2FA
+users.repos = Depoter
+users.created = Oprettet
+users.last_login = Sidst logget ind
+users.never_login = Aldrig logget ind
+users.send_register_notify = Giv besked om tilmelding via e-mail
+users.new_success = Brugerkontoen "%s" er blevet oprettet.
+users.local = Lokal
+users.auth_login_name = Godkendelses-loginnavn
+users.password_helper = Lad adgangskoden vรฆre tom for at bevare den uรฆndret.
+users.update_profile_success = Brugerkontoen er blevet opdateret.
+users.edit_account = Rediger brugerkonto
+users.max_repo_creation = Maksimalt antal depoter
+users.max_repo_creation_desc = (Indtast -1 for at bruge den globale standardgrรฆnse.)
+users.is_activated = Aktiveret konto
+users.activated.description = Afslutning af e-mailbekrรฆftelse. Ejeren af en uaktiveret konto vil ikke vรฆre i stand til at logge ind, fรธr e-mailbekrรฆftelsen er gennemfรธrt.
+users.prohibit_login = Suspenderet konto
+users.block.description = Bloker denne bruger i at interagere med denne tjeneste via deres konto, og forbyd at logge ind.
+users.is_admin = Administrator konto
+users.admin.description = Giv denne bruger fuld adgang til alle administrative funktioner, der er tilgรฆngelige via web-UI og API.
+users.is_restricted = Begrรฆnset konto
+users.restricted.description = Tillad kun interaktion med de depoter og organisationer, hvor denne bruger er tilfรธjet som en samarbejdspartner. Dette forhindrer adgang til offentlige arkiver i denne instans.
+users.allow_git_hook = Kan skabe Git hooks
+users.allow_git_hook_tooltip = Git hooks udfรธres som OS-brugeren, der kรธrer Forgejo og vil have samme niveau af vรฆrtsadgang. Som et resultat kan brugere med dette specielle Git hook-privilegium fรฅ adgang til og รฆndre alle Forgejo-depoter sรฅvel som databasen, der bruges af Forgejo. Derfor er de ogsรฅ i stand til at opnรฅ Forgejo-administratorrettigheder.
+users.allow_import_local = Kan importere lokale depoter
+users.local_import.description = Tillad import af depoter fra serverens lokale filsystem. Dette kan vรฆre et sikkerhedsproblem.
+users.allow_create_organization = Kan skabe organisationer
+users.organization_creation.description = Tillad oprettelse af nye organisationer.
+users.update_profile = Opdater brugerkonto
+users.delete_account = Slet brugerkonto
+users.cannot_delete_self = Du kan ikke slette dig selv
+users.still_own_repo = Denne bruger ejer stadig et eller flere arkiver. Slet eller overfรธr disse depoter fรธrst.
+users.still_has_org = Denne bruger er medlem af en organisation. Fjern fรธrst brugeren fra enhver organisation.
+users.purge = Udrens bruger
+users.purge_help = Tvangsslet brugeren og eventuelle depoter, organisationer og pakker, der ejes af brugeren. Alle kommentarer og problemer indsendt af denne bruger vil ogsรฅ blive slettet.
+users.still_own_packages = Denne bruger ejer stadig en eller flere pakker, slet disse pakker fรธrst.
+users.deletion_success = Brugerkontoen er blevet slettet.
+users.reset_2fa = Nulstil 2FA
+users.list_status_filter.menu_text = Filter
+users.list_status_filter.reset = Nulstil
+users.list_status_filter.is_active = Aktiv
+users.list_status_filter.not_active = Inaktiv
+users.list_status_filter.is_admin = Admin
+users.list_status_filter.not_admin = Ikke admin
+users.list_status_filter.is_restricted = Begrรฆnset
+users.list_status_filter.not_restricted = Ikke begrรฆnset
+users.list_status_filter.is_prohibit_login = Forbyd login
+users.list_status_filter.not_prohibit_login = Tillad login
+users.list_status_filter.is_2fa_enabled = 2FA aktiveret
+users.list_status_filter.not_2fa_enabled = 2FA deaktiveret
+users.details = Brugeroplysninger
+emails.email_manage_panel = Administrer bruger-e-mails
+emails.primary = Primรฆr
+emails.filter_sort.email_reverse = E-mail (omvendt)
+emails.filter_sort.name_reverse = Brugernavn (omvendt)
+emails.updated = E-mail opdateret
+emails.not_updated = Kunne ikke opdatere den anmodede e-mailadresse: %v
+emails.duplicate_active = Denne e-mailadresse er allerede aktiv for en anden bruger.
+emails.change_email_header = Opdater e-mail-egenskaber
+emails.change_email_text = Er du sikker pรฅ, at du vil opdatere denne e-mailadresse?
+emails.delete = Slet e-mail
+emails.delete_desc = Er du sikker pรฅ, at du vil slette denne e-mailadresse?
+emails.deletion_success = E-mailadressen er blevet slettet.
+emails.delete_primary_email_error = Du kan ikke slette den primรฆre e-mail.
+orgs.org_manage_panel = Administrer organisationer
+repos.repo_manage_panel = Administrer depoter
+repos.unadopted = Ikke-adopterede depoter
+repos.unadopted.no_more = Ingen ikke-adopterede depoter fundet.
+repos.issues = Problemer
+repos.size = Stรธrrelse
+repos.lfs_size = LFS stรธrrelse
+packages.package_manage_panel = Administrer pakker
+packages.total_size = Samlet stรธrrelse: %s
+packages.unreferenced_size = Ikke-referencestรธrrelse: %s
+packages.version = Version
+packages.type = Type
+packages.size = Stรธrrelse
+packages.published = Offentliggjort
+auths.type = Type
+auths.syncenabled = Slรฅ brugersynkronisering til
+auths.updated = Opdateret
+auths.security_protocol = Sikkerhedsprotokol
+auths.domain = Domรฆne
+auths.host = Host
+auths.port = Port
+monitor.queue.settings.maxnumberworkers.placeholder = I รธjeblikket %[1]d
+monitor.queue.settings.submit = Opdater indstillinger
+monitor.queue.settings.changed = Indstillinger opdateret
+monitor.queue.settings.remove_all_items = Slet alle
+monitor.queue.settings.remove_all_items_done = Alle varer i kรธen er blevet fjernet.
+notices.system_notice_list = Systemmeddelelser
+
+packages.cleanup = Ryd op i udlรธbne data
+packages.cleanup.success = Der er ryddet op i udlรธbne data
+packages.creator = Skaber
+defaulthooks = Default webhooks
+defaulthooks.desc = Webhooks foretager automatisk HTTP POST-anmodninger til en server, nรฅr visse Forgejo-hรฆndelser udlรธses. Webhooks defineret her er standarder og vil blive kopieret til alle nye repositories. Lรฆs mere i webhooks-guiden .
+defaulthooks.add_webhook = Tilfรธj standard webhook
+defaulthooks.update_webhook = Opdater standardwebhook
+systemhooks = System webhooks
+systemhooks.desc = Webhooks foretager automatisk HTTP POST-anmodninger til en server, nรฅr visse Forgejo-hรฆndelser udlรธses. Webhooks, der er defineret her, vil virke pรฅ alle repositories pรฅ systemet, sรฅ overvej venligst eventuelle prรฆstationsimplikationer, dette kan have. Lรฆs mere i webhooks-guiden .
+systemhooks.add_webhook = Tilfรธj System Webhook
+systemhooks.update_webhook = Opdater System Webhook
+auths.auth_manage_panel = Administrer godkendelseskilder
+auths.new = Tilfรธj godkendelseskilde
+auths.auth_type = Godkendelsestype
+auths.auth_name = Godkendelsesnavn
+auths.bind_dn = Bind DN
+auths.bind_password = Bind adgangskode
+auths.user_base = Bruger sรธgebase
+auths.user_dn = Bruger DN
+auths.attribute_username = Brugernavn attribut
+auths.attribute_username_placeholder = Lad stรฅ tomt for at bruge brugernavnet indtastet i Forgejo.
+auths.attribute_name = Fornavn attribut
+auths.attribute_surname = Efternavn attribut
+auths.attribute_mail = E-mail attribut
+auths.attribute_ssh_public_key = Offentlig SSH-nรธgleattribut
+auths.attribute_avatar = Avatar attribut
+auths.attributes_in_bind = Hent attributter i bind DN-kontekst
+auths.default_domain_name = Standard domรฆnenavn, der bruges til e-mailadressen
+auths.allow_deactivate_all = Tillad et tomt sรธgeresultat for at deaktivere alle brugere
+auths.use_paged_search = Brug sidesรธgning
+auths.search_page_size = Sidestรธrrelse
+auths.filter = Bruger filter
+auths.admin_filter = Admin filter
+auths.restricted_filter = Begrรฆnset filter
+auths.restricted_filter_helper = Lad vรฆre tom for ikke at angive nogen brugere som begrรฆnset. Brug en stjerne ("*") for at indstille alle brugere, der ikke matcher Admin-filteret, som begrรฆnset.
+auths.verify_group_membership = Bekrรฆft gruppemedlemskab i LDAP (lad filteret stรฅ tomt for at springe over)
+auths.group_search_base = Gruppesรธgningsbase DN
+auths.group_attribute_list_users = Gruppeattribut, der indeholder en liste over brugere
+auths.user_attribute_in_group = Brugerattribut angivet i gruppen
+auths.map_group_to_team = Tilknyt LDAP-grupper til organisationsteams (lad feltet stรฅ tomt for at springe over)
+auths.map_group_to_team_removal = Fjern brugere fra synkroniserede teams, hvis brugeren ikke tilhรธrer den tilsvarende LDAP-gruppe
+auths.enable_ldap_groups = Aktiver LDAP-grupper
+auths.ms_ad_sa = MS AD sรธgeattributter
+auths.smtp_auth = SMTP-godkendelsestype
+auths.smtphost = SMTP vรฆrt
+auths.smtpport = SMTP port
+auths.allowed_domains = Tilladte domรฆner
+auths.allowed_domains_helper = Lad vรฆre tomt for at tillade alle domรฆner. Adskil flere domรฆner med et komma (",").
+auths.skip_tls_verify = Spring over TLS-bekrรฆftelse
+auths.force_smtps = Tving SMTPS
+auths.force_smtps_helper = SMTPS bruges altid pรฅ port 465. Indstil denne til at tvinge SMTPS pรฅ andre porte. (Ellers vil STARTTLS blive brugt pรฅ andre porte, hvis det understรธttes af vรฆrten.)
+auths.helo_hostname = HELO vรฆrtsnavn
+auths.helo_hostname_helper = Vรฆrtsnavn sendt med HELO. Lad stรฅ tomt for at sende det nuvรฆrende vรฆrtsnavn.
+auths.disable_helo = Deaktiver HELO
+auths.pam_service_name = PAM-tjenestenavn
+auths.pam_email_domain = PAM e-mail domรฆne (valgfrit)
+auths.oauth2_provider = OAuth2-udbyder
+auths.oauth2_clientID = Klient-id (nรธgle)
+auths.oauth2_clientSecret = Klientens hemmelighed
+auths.openIdConnectAutoDiscoveryURL = OpenID Connect Auto Discovery URL
+auths.oauth2_use_custom_url = Brug tilpassede webadresser i stedet for standardwebadresser
+auths.oauth2_tokenURL = Token URL
+auths.oauth2_authURL = Godkend URL
+auths.oauth2_profileURL = Profil-URL
+auths.oauth2_emailURL = E-mail URL
+auths.skip_local_two_fa = Spring over lokal 2FA
+auths.skip_local_two_fa_helper = Hvis du ikke er indstillet, betyder det, at lokale brugere med 2FA indstillet stadig skal bestรฅ 2FA for at logge pรฅ
+auths.oauth2_tenant = Lejer
+auths.oauth2_scopes = Yderligere omfang
+auths.oauth2_required_claim_name = Pรฅkrรฆvet kravnavn
+auths.oauth2_required_claim_name_helper = Indstil dette navn for at begrรฆnse login fra denne kilde til brugere med et krav med dette navn
+auths.oauth2_required_claim_value = Pรฅkrรฆvet kravvรฆrdi
+auths.oauth2_required_claim_value_helper = Indstil denne vรฆrdi for at begrรฆnse login fra denne kilde til brugere med et krav med dette navn og denne vรฆrdi
+auths.oauth2_group_claim_name = Gรธr krav pรฅ navn med gruppenavne for denne kilde. (Valgfri)
+auths.oauth2_admin_group = Gruppekravvรฆrdi for administratorbrugere. (Valgfrit โ krรฆver kravnavn ovenfor)
+auths.oauth2_restricted_group = Gruppekravsvรฆrdi for begrรฆnsede brugere. (Valgfrit โ krรฆver kravnavn ovenfor)
+auths.oauth2_map_group_to_team = Kortlรฆg hรฆvdede grupper til organisationsteams. (Valgfrit โ krรฆver kravnavn ovenfor)
+auths.oauth2_map_group_to_team_removal = Fjern brugere fra synkroniserede teams, hvis brugeren ikke tilhรธrer den tilsvarende gruppe.
+auths.tips = Tips
+auths.tips.gmail_settings = Gmail-indstillinger:
+auths.tips.oauth2.general = OAuth2-godkendelse
+auths.tips.oauth2.general.tip = Nรฅr du registrerer en ny OAuth2-godkendelse, skal URL-adressen til tilbagekald/omdirigering vรฆre:
+auths.tip.oauth2_provider = OAuth2-udbyder
+auths.tip.bitbucket = Registrer en ny OAuth-bruger pรฅ %s og tilfรธj tilladelsen "Konto" - "Lรฆs"
+auths.tip.nextcloud = Registrer en ny OAuth-bruger pรฅ din instans ved hjรฆlp af fรธlgende menu "Indstillinger -> Sikkerhed -> OAuth 2.0-klient"
+auths.tip.dropbox = Opret en ny applikation pรฅ %s
+auths.tip.facebook = Registrer en ny applikation pรฅ %s og tilfรธj produktet "Facebook Login"
+auths.tip.github = Registrer en ny OAuth-applikation pรฅ %s
+auths.tip.gitlab_new = Registrer en ny applikation pรฅ %s
+auths.tip.google_plus = Hent OAuth2-klientlegitimationsoplysninger fra Google API-konsollen pรฅ %s
+auths.tip.openid_connect = Brug OpenID Connect Discovery URL (/.well-known/openid-configuration) til at angive slutpunkterne
+auths.tip.twitter = Gรฅ til %s, opret en applikation og sรธrg for, at "Tillad, at denne applikation bruges til at logge pรฅ med Twitter" er aktiveret
+auths.tip.discord = Registrer en ny applikation pรฅ %s
+auths.tip.gitea = Registrer en ny OAuth2-applikation. Guide kan findes pรฅ %s
+auths.tip.yandex = Opret en ny applikation pรฅ %s. Vรฆlg fรธlgende tilladelser fra afsnittet "Yandex.Passport API": "Adgang til e-mailadresse", "Adgang til brugeravatar" og "Adgang til brugernavn, fornavn og efternavn, kรธn"
+auths.tip.mastodon = Indtast en brugerdefineret instans-URL for den mastodon-instans, du vil godkende med (eller brug standarden)
+auths.edit = Rediger godkendelseskilden
+auths.activated = Denne godkendelseskilde er aktiveret
+auths.new_success = Godkendelsen "%s" er blevet tilfรธjet.
+auths.update_success = Godkendelseskilden er blevet opdateret.
+auths.update = Opdater godkendelseskilden
+auths.delete = Slet godkendelseskilden
+auths.delete_auth_title = Slet godkendelseskilden
+auths.delete_auth_desc = Sletning af en godkendelseskilde forhindrer brugere i at bruge den til at logge ind. Vil du fortsรฆtte?
+auths.still_in_used = Godkendelseskilden er stadig i brug. Konverter eller slet alle brugere, der bruger denne godkendelseskilde fรธrst.
+auths.deletion_success = Godkendelseskilden er blevet slettet.
+auths.login_source_exist = Godkendelseskilden "%s" findes allerede.
+auths.login_source_of_type_exist = Der findes allerede en godkendelseskilde af denne type.
+auths.unable_to_initialize_openid = Kan ikke initialisere OpenID Connect Provider: %s
+auths.invalid_openIdConnectAutoDiscoveryURL = Ugyldig Auto Discovery URL (dette skal vรฆre en gyldig URL, der starter med http:// eller https://)
+config.server_config = Server konfiguration
+config.app_name = Instans titel
+config.app_slogan = instans slogan
+config.app_ver = Forgejo version
+config.app_url = Base URL
+config.custom_conf = Konfigurationsfilstien
+config.custom_file_root_path = Brugerdefineret fil rodsti
+config.domain = Server domรฆne
+config.offline_mode = Lokal tilstand
+config.disable_router_log = Deaktiver routerlog
+config.run_user = Bruger at kรธre som
+config.run_mode = Kรธr tilstand
+config.git_version = Git version
+config.app_data_path = Appens datasti
+config.repo_root_path = Depotets rodsti
+config.lfs_root_path = LFS rodsti
+config.log_file_root_path = Logsti
+config.script_type = Script type
+config.reverse_auth_user = Omvendt proxy-godkendelsesbruger
+config.ssh_config = SSH konfiguration
+config.ssh_start_builtin_server = Brug indbygget server
+config.ssh_domain = SSH server domรฆne
+config.ssh_port = Port
+config.ssh_listen_port = Lyt port
+config.ssh_root_path = Rodsti
+config.ssh_key_test_path = Nรธgleteststi
+config.ssh_keygen_path = Keygen ("ssh-keygen") sti
+config.ssh_minimum_key_size_check = Minimum nรธglestรธrrelse kontrol
+config.ssh_minimum_key_sizes = Minimum nรธglestรธrrelser
+config.lfs_config = LFS-konfiguration
+config.lfs_content_path = LFS indholdssti
+config.lfs_http_auth_expiry = LFS HTTP-godkendelsesudlรธbstid
+config.db_config = Database konfiguration
+config.db_type = Type
+config.db_host = Vรฆrt
+config.db_schema = Skematisk
+config.db_ssl_mode = SSL
+config.db_path = Sti
+config.service_config = Tjenestekonfiguration
+config.register_email_confirm = Krรฆv e-mail-bekrรฆftelse for at tilmelde dig
+config.disable_register = Deaktiver selvregistrering
+config.allow_only_internal_registration = Tillad kun registrering gennem Forgejo selv
+config.allow_only_external_registration = Tillad kun registrering via eksterne tjenester
+config.enable_openid_signup = Aktiver OpenID-selvregistrering
+config.enable_openid_signin = Aktiver OpenID-logon
+config.show_registration_button = Vis registreringsknap
+config.require_sign_in_view = Krรฆv at logge ind for at se indhold
+config.mail_notify = Aktiver e-mailmeddelelser
+config.enable_captcha = Aktiver CAPTCHA
+config.active_code_lives = Aktiveringskodens udlรธbstid
+config.reset_password_code_lives = Gendannelseskodens udlรธbstid
+config.default_keep_email_private = Skjul e-mailadresser som standard
+config.default_allow_create_organization = Tillad oprettelse af organisationer som standard
+config.no_reply_address = Skjult e-mail-domรฆne
+config.default_visibility_organization = Standardsynlighed for nye organisationer
+config.default_enable_dependencies = Aktiver problemafhรฆngigheder som standard
+config.webhook_config = Webhook-konfiguration
+config.queue_length = Kรธ lรฆngde
+config.deliver_timeout = Lever timeout
+config.skip_tls_verify = Spring over TLS-bekrรฆftelse
+config.mailer_config = Mailer konfiguration
+config.mailer_enable_helo = Aktiver HELO
+config.mailer_protocol = Protokol
+config.mailer_smtp_addr = SMTP vรฆrt
+config.mailer_smtp_port = SMTP-port
+config.mailer_user = Bruger
+config.mailer_use_sendmail = Brug Sendmail
+config.mailer_sendmail_path = Sendmail sti
+config.mailer_sendmail_args = Ekstra argumenter til Sendmail
+config.mailer_sendmail_timeout = Sendmail timeout
+config.mailer_use_dummy = Attrapp
+config.test_email_placeholder = E-mail (f.eks. test@example.com)
+config.send_test_mail = Send test-e-mail
+config.send_test_mail_submit = Send
+config.test_mail_failed = Kunne ikke sende en test-e-mail til "%s": %v
+config.test_mail_sent = En test-e-mail er blevet sendt til "%s".
+config.oauth_config = OAuth-konfiguration
+config.cache_config = Cache konfiguration
+config.cache_adapter = Cache adapter
+config.cache_interval = Cache interval
+config.cache_conn = Cacheforbindelse
+config.cache_item_ttl = Cache element TTL
+config.cache_test = Test cache
+config.cache_test_failed = Kunne ikke undersรธge cachen: %v.
+config.cache_test_slow = Cachetest lykkedes, men svaret er langsomt: %s.
+config.cache_test_succeeded = Cachetest gennemfรธrt, fik et svar i %s.
+config.session_config = Sessionskonfiguration
+config.session_provider = Session udbyder
+config.provider_config = Udbyder konfig
+config.cookie_name = Cookie navn
+config.gc_interval_time = GC interval tid
+config.session_life_time = Session levetid
+config.https_only = Kun HTTPS
+config.cookie_life_time = Cookie levetid
+config.picture_config = Billede og avatar konfiguration
+config.picture_service = Billedservice
+config.disable_gravatar = Deaktiver Gravatar
+config.enable_federated_avatar = Aktiver fรธdererede avatarer
+config.open_with_editor_app_help = "ร
bn med"-editorerne til klonmenuen. Hvis den efterlades tom, vil standarden blive brugt. Udvid for at se standarden.
+config.git_config = Git konfiguration
+config.git_disable_diff_highlight = Deaktiver diff-syntaksfremhรฆvning
+config.git_max_diff_lines = Max diff-linjer pr. fil
+config.git_max_diff_line_characters = Maks. diff-tegn pr. linje
+config.git_max_diff_files = Max diff filer vist
+config.git_gc_args = GC argumenter
+config.git_migrate_timeout = Migration timeout
+config.git_mirror_timeout = Spejlopdateringstimeout
+config.git_clone_timeout = Klone Operation timeout
+config.git_pull_timeout = Pull Operation timeout
+config.git_gc_timeout = GC Operation timeout
+config.log_config = Log konfiguration
+config.logger_name_fmt = Logger: %s
+config.disabled_logger = Deaktiveret
+config.access_log_mode = Adgang til logtilstand
+config.access_log_template = Skabelon til adgangslog
+config.xorm_log_sql = Log SQL
+config.set_setting_failed = Indstilling af %s mislykkedes
+monitor.stats = Statistik
+monitor.cron = Cron opgaver
+monitor.schedule = Tidsplan
+monitor.next = Nรฆste gang
+monitor.previous = Tidligere tid
+monitor.execute_times = Udfรธrelser
+monitor.process = Kรธrende processer
+monitor.stacktrace = Stakspor
+monitor.processes_count = %d Processer
+monitor.download_diagnosis_report = Hent diagnoserapport
+monitor.duration = Varighed (r)
+monitor.start = Starttid
+monitor.execute_time = Udfรธrelsestid
+monitor.last_execution_result = Resultat
+monitor.process.cancel = Annuller processen
+monitor.process.cancel_desc = Annullering af en proces kan medfรธre tab af data
+monitor.process.cancel_notices = Annuller: %s ?
+monitor.process.children = Bรธrn
+monitor.queues = Kรธer
+monitor.queue = Kรธ: %s
+monitor.queue.type = Type
+monitor.queue.exemplar = Eksempler type
+monitor.queue.numberworkers = Antal arbejdere
+monitor.queue.activeworkers = Aktive arbejdere
+monitor.queue.maxnumberworkers = Max antal arbejdere
+monitor.queue.numberinqueue = Nummer i kรธ
+monitor.queue.review_add = Gennemgรฅ / tilfรธj arbejdere
+monitor.queue.settings.title = Pool indstillinger
+monitor.queue.settings.desc = Puljer vokser dynamisk som reaktion pรฅ deres blokering af arbejderkรธ.
+monitor.queue.settings.maxnumberworkers = Max antal arbejdere
+monitor.queue.settings.maxnumberworkers.error = Max antal arbejdere skal vรฆre et tal
+notices.view_detail_header = Bemรฆrk detaljer
+notices.operations = Operationer
+notices.select_all = Vรฆlg alle
+notices.deselect_all = Fravรฆlg alle
+notices.inverse_selection = Omvendt valg
+notices.delete_selected = Slet valgte
+notices.delete_all = Slet alle meddelelser
+notices.type = Type
+notices.type_2 = Opgave
+notices.op = Op.
+notices.delete_success = Systemmeddelelserne er blevet slettet.
+self_check.no_problem_found = Intet problem fundet endnu.
+self_check.database_collation_mismatch = Forvent, at databasen bruger sortering: %s
+self_check.database_collation_case_insensitive = Databasen bruger en sortering %s, som er en ufรธlsom sortering. Selvom Forgejo kunne arbejde med det, kan der vรฆre nogle sjรฆldne tilfรฆlde, som ikke fungerer som forventet.
+self_check.database_inconsistent_collation_columns = Databasen bruger sortering %s, men disse kolonner bruger uoverensstemmende sorteringer. Det kan forรฅrsage nogle uventede problemer.
+self_check.database_fix_mysql = For MySQL/MariaDB-brugere kan du bruge kommandoen "forgejo doctor convert" til at lรธse sorteringsproblemerne, eller du kan ogsรฅ lรธse problemet ved at "ALTER ... COLLATE ..." SQLs manuelt.
+
+[packages]
+arch.version.description = Beskrivelse
+container.labels = Etiketter
+rubygems.dependencies.development = Udviklingsafhรฆngigheder
+conan.details.repository = Depot
+conan.registry = Konfigurer dette register fra kommandolinjen:
+rubygems.dependencies.runtime = Kรธrselsafhรฆngigheder
+rubygems.install = For at installere pakken ved hjรฆlp af gem skal du kรธre fรธlgende kommando:
+debian.repository = Depot info
+npm.details.tag = Tag
+chef.install = For at installere pakken skal du kรธre fรธlgende kommando:
+alpine.repository.architectures = Arkitekturer
+composer.dependencies.development = Udviklingsafhรฆngigheder
+alt.repository.multiple_groups = Denne pakke er tilgรฆngelig i flere grupper.
+owner.settings.cleanuprules.enabled = Aktiveret
+helm.registry = Konfigurer dette register fra kommandolinjen:
+alt.registry.install = For at installere pakken skal du kรธre fรธlgende kommando:
+helm.install = For at installere pakken skal du kรธre fรธlgende kommando:
+alt.repository.architectures = Arkitekturer
+swift.registry = Konfigurer dette register fra kommandolinjen:
+npm.dependencies.bundle = Samlede afhรฆngigheder
+debian.registry = Konfigurer dette register fra kommandolinjen:
+cran.install = For at installere pakken skal du kรธre fรธlgende kommando:
+debian.install = For at installere pakken skal du kรธre fรธlgende kommando:
+pub.install = For at installere pakken ved hjรฆlp af Dart skal du kรธre fรธlgende kommando:
+pypi.requires = Krรฆver Python
+nuget.registry = Konfigurer dette register fra kommandolinjen:
+debian.repository.distributions = Fordelinger
+debian.repository.components = Komponenter
+debian.repository.architectures = Arkitekturer
+rpm.repository.multiple_groups = Denne pakke er tilgรฆngelig i flere grupper.
+rubygems.install2 = eller fรธj det til Gemfilen:
+npm.dependencies.development = Udviklingsafhรฆngigheder
+npm.dependencies.peer = Peer-afhรฆngigheder
+npm.dependencies.optional = Valgfrie afhรฆngigheder
+rpm.registry = Konfigurer dette register fra kommandolinjen:
+rpm.install = For at installere pakken skal du kรธre fรธlgende kommando:
+alpine.install = For at installere pakken skal du kรธre fรธlgende kommando:
+alpine.repository = Depot info
+pypi.install = For at installere pakken ved hjรฆlp af pip skal du kรธre fรธlgende kommando:
+rpm.repository = Depot info
+rpm.repository.architectures = Arkitekturer
+alt.registry = Konfigurer dette register fra kommandolinjen:
+alt.repository = Depot info
+
+dependency.version = Version
+search_in_external_registry = Sรธg i %s
+alpine.registry = Konfigurer dette register ved at tilfรธje url'en i din /etc/apk/repositories
fil:
+alpine.registry.key = Download den offentlige RSA-nรธgle til registreringsdatabasen i mappen /etc/apk/keys/
for at bekrรฆfte indekssignaturen:
+alpine.registry.info = Vรฆlg $branch og $repository fra listen nedenfor.
+alpine.repository.repositories = Depoter
+
+title = Pakker
+desc = Administrer depotpakker.
+empty = Der er ingen pakker endnu.
+empty.documentation = For mere information om pakkeregistret, se dokumentationen .
+empty.repo = Har du uploadet en pakke, men den vises ikke her? Gรฅ til pakkeindstillinger og link den til denne repo.
+registry.documentation = For mere information om %s registreringsdatabasen, se dokumentationen .
+filter.type = Type
+filter.type.all = Alle
+filter.no_result = Dit filter gav ingen resultater.
+filter.container.tagged = Tagget
+filter.container.untagged = Umรฆrket
+published_by = Udgivet %[1]s af %[3]s
+published_by_in = Udgivet %[1]s af %[3]s i %[5]s
+installation = Installation
+about = Om denne pakke
+requirements = Krav
+dependencies = Afhรฆngigheder
+keywords = Keywords
+details = Detaljer
+details.author = Forfatter
+details.project_site = Projektets hjemmeside
+details.repository_site = Depots hjemmeside
+details.documentation_site = Dokumentations hjemmeside
+details.license = Licens
+assets = Aktiver
+versions = Versioner
+versions.view_all = Se alle
+dependency.id = ID
+alpine.repository.branches = Grene
+arch.pacman.helper.gpg = Tilfรธj tillidscertifikat til pacman:
+arch.pacman.repo.multi = %s har den samme version i forskellige distributioner.
+arch.pacman.repo.multi.item = Konfiguration for %s
+arch.pacman.conf = Tilfรธj server med relateret distribution og arkitektur til /etc/pacman.conf
:
+arch.pacman.sync = Synkroniser pakke med pacman:
+arch.version.properties = Versionsegenskaber
+arch.version.provides = Forsyner
+arch.version.groups = Gruppe
+arch.version.depends = Afhรฆnger
+arch.version.optdepends = Valgfri afhรฆnger
+arch.version.makedepends = Gรธr afhรฆnger
+arch.version.checkdepends = Check afhรฆnger
+arch.version.conflicts = Konflikter
+arch.version.replaces = Erstatter
+arch.version.backup = Backup
+cargo.registry = Konfigurer dette register i Cargo-konfigurationsfilen (for eksempel ~/.cargo/config.toml
):
+cargo.install = For at installere pakken ved hjรฆlp af Cargo skal du kรธre fรธlgende kommando:
+chef.registry = Konfigurer dette register i din ~/.chef/config.rb
fil:
+composer.registry = Konfigurer dette register i din ~/.composer/config.json
fil:
+composer.install = For at installere pakken ved hjรฆlp af Composer skal du kรธre fรธlgende kommando:
+composer.dependencies = Afhรฆngigheder
+conan.install = For at installere pakken ved hjรฆlp af Conan skal du kรธre fรธlgende kommando:
+conda.registry = Konfigurer dette register som et Conda-depot i din .condarc
-fil:
+conda.install = For at installere pakken ved hjรฆlp af Conda skal du kรธre fรธlgende kommando:
+container.images.title = Billeder
+container.details.type = Billedtype
+container.details.platform = Platform
+container.pull = Trรฆk billedet fra kommandolinjen:
+container.digest = Fordรธje
+container.multi_arch = OS / Arch
+container.layers = Billedlag
+container.labels.key = Nรธgle
+container.labels.value = Vรฆrdi
+cran.registry = Konfigurer dette register i din Rprofile.site
fil:
+debian.registry.info = Vรฆlg $distribution og $component fra listen nedenfor.
+generic.download = Download pakken fra kommandolinjen:
+go.install = Installer pakken fra kommandolinjen:
+maven.registry = Konfigurer denne registreringsdatabasen i din projekt pom.xml
fil:
+maven.install = For at bruge pakken skal du inkludere fรธlgende i blokken afhรฆngigheder
i filen pom.xml
:
+maven.install2 = Kรธr via kommandolinje:
+maven.download = For at downloade afhรฆngigheden skal du kรธre via kommandolinjen:
+nuget.install = For at installere pakken ved hjรฆlp af NuGet skal du kรธre fรธlgende kommando:
+nuget.dependency.framework = Mรฅl Framework
+npm.registry = Konfigurer denne registreringsdatabase i din projekt-.npmrc
-fil:
+npm.install = For at installere pakken ved hjรฆlp af npm skal du kรธre fรธlgende kommando:
+npm.install2 = eller fรธj det til filen package.json:
+npm.dependencies = Afhรฆngigheder
+rpm.distros.redhat = pรฅ RedHat-baserede distributioner
+rpm.distros.suse = pรฅ SUSE-baserede distributioner
+alt.install = Installer pakken
+alt.setup = Tilfรธj et depot til listen over tilsluttede arkiver (vรฆlg den nรธdvendige arkitektur i stedet for "_arch_"):
+rubygems.required.ruby = Krรฆver Ruby version
+rubygems.required.rubygems = Krรฆver RubyGem version
+swift.install = Tilfรธj pakken i din Package.swift
-fil:
+swift.install2 = og kรธr fรธlgende kommando:
+vagrant.install = For at tilfรธje en Vagrant-boks skal du kรธre fรธlgende kommando:
+settings.link = Link denne pakke til et depot
+settings.link.description = Hvis du forbinder en pakke med et depot, vises pakken i depotets pakkeliste.
+settings.link.select = Vรฆlg Depot
+settings.link.button = Opdater Depot Link
+settings.link.success = Depotlinket blev opdateret.
+settings.link.error = Kunne ikke opdatere depotlinket.
+settings.delete = Slet pakke
+settings.delete.description = Sletning af en pakke er permanent og kan ikke fortrydes.
+settings.delete.notice = Du er ved at slette %s (%s). Denne operation er uigenkaldeligt, er du sikker?
+settings.delete.success = Pakken er blevet slettet.
+settings.delete.error = Kunne ikke slette pakken.
+owner.settings.cargo.title = Lastregisterindeks
+owner.settings.cargo.initialize = Initialiser indeks
+owner.settings.cargo.initialize.description = Et sรฆrligt indeks Git-depot er nรธdvendigt for at bruge Cargo-registret. Brug af denne mulighed vil (gen-)oprette depotet og konfigurere det automatisk.
+owner.settings.cargo.initialize.error = Kunne ikke initialisere Cargo index: %v
+owner.settings.cargo.initialize.success = Cargo-indekset blev oprettet.
+owner.settings.cargo.rebuild = Genopbyg indeks
+owner.settings.cargo.rebuild.description = Genopbygning kan vรฆre nyttig, hvis indekset ikke er synkroniseret med de lagrede Cargo-pakker.
+owner.settings.cargo.rebuild.error = Kunne ikke genopbygge Cargo-indeks: %v
+owner.settings.cargo.rebuild.success = Cargo-indekset blev genopbygget med succes.
+owner.settings.cargo.rebuild.no_index = Kan ikke genopbygge, intet indeks er initialiseret.
+owner.settings.cleanuprules.title = Oprydningsregler
+owner.settings.cleanuprules.add = Tilfรธj oprydningsregel
+owner.settings.cleanuprules.edit = Rediger oprydningsregel
+owner.settings.cleanuprules.none = Der er endnu ingen oprydningsregler.
+owner.settings.cleanuprules.preview = Forhรฅndsvisning af oprydningsregel
+owner.settings.cleanuprules.preview.overview = %d pakker er planlagt til at blive fjernet.
+owner.settings.cleanuprules.preview.none = Oprydningsreglen matcher ikke nogen pakker.
+owner.settings.cleanuprules.pattern_full_match = Anvend mรธnster pรฅ det fulde pakkenavn
+owner.settings.cleanuprules.keep.title = Versioner, der matcher disse regler, bevares, selvom de matcher en fjernelsesregel nedenfor.
+owner.settings.cleanuprules.keep.count = Behold den nyeste
+owner.settings.cleanuprules.keep.count.1 = 1 version pr. pakke
+owner.settings.cleanuprules.keep.count.n = %d versioner pr. pakke
+owner.settings.cleanuprules.keep.pattern = Hold versionerne matchende
+owner.settings.cleanuprules.keep.pattern.container = Den seneste
version bevares altid for containerpakker.
+owner.settings.cleanuprules.remove.title = Versioner, der matcher disse regler, fjernes, medmindre en regel ovenfor siger, at de skal beholdes.
+owner.settings.cleanuprules.remove.days = Fjern versioner รฆldre end
+owner.settings.cleanuprules.remove.pattern = Fjern matchende versioner
+owner.settings.cleanuprules.success.update = Oprydningsreglen er blevet opdateret.
+owner.settings.cleanuprules.success.delete = Oprydningsregel er blevet slettet.
+owner.settings.chef.title = Kokkeregister
+owner.settings.chef.keypair = Generer nรธglepar
+owner.settings.chef.keypair.description = Et nรธglepar er nรธdvendigt for at autentificere til Chef-registret. Hvis du har genereret et nรธglepar fรธr, vil generering af et nyt nรธglepar kassere det gamle nรธglepar.
+
+[actions]
+runners.description = Beskrivelse
+runners.labels = Etiketter
+runners.name = Navn
+runners.task_list.repository = Depot
+
+runners.status.active = Aktiv
+runners.status.offline = Offline
+runners.version = Version
+
+actions = Handlinger
+unit.desc = Administrer integrerede CI/CD-pipelines med Forgejo Actions.
+status.unknown = Ukendt
+status.waiting = Venter
+status.running = Kรธrer
+status.success = Succes
+status.failure = Fiasko
+status.cancelled = Annulleret
+status.skipped = Oversprunget
+status.blocked = Blokeret
+runners = Runners
+runners.runner_manage_panel = Administrer runners
+runners.new = Opret ny runner
+runners.new_notice = Hvordan man starter en runner
+runners.status = Status
+runners.id = ID
+runners.owner_type = Type
+runners.last_online = Sidste online tid
+runners.runner_title = Runner
+runners.task_list = Seneste opgaver pรฅ denne lรธber
+runners.task_list.no_tasks = Der er ingen opgave endnu.
+runners.task_list.run = Kรธr
+runners.task_list.status = Status
+runners.task_list.commit = Commit
+runners.task_list.done_at = Udfรธrt kl
+runners.edit_runner = Rediger Runner
+runners.update_runner = Opdater รฆndringer
+runners.update_runner_success = Runner blev opdateret
+runners.update_runner_failed = Lรธberen kunne ikke opdateres
+runners.delete_runner = Slet denne runner
+runners.delete_runner_success = Runner blev slettet
+runners.delete_runner_failed = Runner kunne ikke slettes
+runners.delete_runner_header = Bekrรฆft for at slette denne runner
+runners.delete_runner_notice = Hvis en opgave kรธrer pรฅ denne runner, vil den blive afsluttet og markeret som mislykket. Det kan bryde bygningens arbejdsgang.
+runners.none = Ingen runners tilgรฆngelige
+runners.status.unspecified = Ukendt
+runners.status.idle = Tomgang
+runners.reset_registration_token = Nulstil registreringstoken
+runners.reset_registration_token_success = Runner registreringstoken blev nulstillet
+runs.all_workflows = Alle arbejdsgange
+runs.commit = Commit
+runs.scheduled = Planlagt
+runs.pushed_by = pushed af
+runs.workflow = Arbejdsgang
+runs.invalid_workflow_helper = Workflow-konfigurationsfilen er ugyldig. Tjek venligst din konfigurationsfil: %s
+runs.no_matching_online_runner_helper = Ingen matchende online-runner med etiket: %s
+runs.no_job_without_needs = Arbejdsgangen skal indeholde mindst รฉt job uden afhรฆngigheder.
+runs.no_job = Arbejdsgangen skal indeholde mindst รฉt job
+runs.actor = Aktรธr
+runs.status = Status
+runs.actors_no_select = Alle aktรธrer
+runs.status_no_select = Alle status
+runs.no_results = Ingen resultater matchede.
+runs.no_workflows = Der er endnu ingen arbejdsgange.
+runs.no_workflows.help_write_access = Ved du ikke, hvordan du starter med Forgejo Actions? Tjek hurtigstarten i brugerdokumentationen for at skrive dit fรธrste workflow, og opsรฆt en Forgejo-lรธber til at udfรธre dine opgaver.
+runs.no_workflows.help_no_write_access = For at lรฆre om Forgejo Actions, se dokumentationen .
+runs.no_runs = Workflowet har ingen kรธrsler endnu.
+runs.empty_commit_message = (tom commit besked)
+runs.expire_log_message = Logfiler er blevet renset, fordi de var for gamle.
+workflow.disable = Deaktiver arbejdsgang
+workflow.disable_success = Arbejdsgangen "%s" blev deaktiveret.
+workflow.enable = Aktiver arbejdsgang
+workflow.enable_success = Arbejdsgangen "%s" blev aktiveret.
+workflow.disabled = Arbejdsgangen er deaktiveret.
+workflow.dispatch.trigger_found = Denne arbejdsgang har en workflow_dispatch -hรฆndelsestrigger.
+workflow.dispatch.use_from = Brug arbejdsgangen fra
+workflow.dispatch.run = Kรธr arbejdsgang
+workflow.dispatch.success = Kรธrsel af arbejdsgang blev anmodet om.
+workflow.dispatch.input_required = Krรฆv vรฆrdi for input "%s".
+workflow.dispatch.invalid_input_type = Ugyldig inputtype "%s".
+workflow.dispatch.warn_input_limit = Viser kun de fรธrste %d input.
+need_approval_desc = Har brug for godkendelse for at kรธre arbejdsgange for fork pull-anmodning.
+variables = Variabler
+variables.management = Administrer variabler
+variables.creation = Tilfรธj variabel
+variables.none = Der er ingen variabler endnu.
+variables.deletion = Fjern variabel
+variables.deletion.description = Fjernelse af en variabel er permanent og kan ikke fortrydes. Vil du fortsรฆtte?
+variables.description = Variabler vil blive videregivet til visse handlinger og kan ikke lรฆses pรฅ anden vis.
+variables.id_not_exist = Variabel med ID %d findes ikke.
+variables.edit = Rediger variabel
+variables.not_found = Variablen kunne ikke findes.
+variables.deletion.failed = Variablen kunne ikke fjernes.
+variables.deletion.success = Variablen er blevet fjernet.
+variables.creation.failed = Kunne ikke tilfรธje variabel.
+variables.creation.success = Variablen "%s" er blevet tilfรธjet.
+variables.update.failed = Variablen kunne ikke redigeres.
+variables.update.success = Variablen er blevet redigeret.
+
+[tool]
+1d = 1 dag
+1w = 1 uge
+1mon = 1 mรฅned
+1y = 1 รฅr
+future = fremtid
+1s = 1 sekund
+1m = 1 minut
+1h = 1 time
+seconds = %d sekunder
+minutes = %d minutter
+hours = %d timer
+days = %d dage
+weeks = %d uger
+months = %d mรฅneder
+years = %d รฅr
+raw_seconds = sekunder
+raw_minutes = minutter
+
+now = nu
+
+[repo.permissions]
+code.read = Lรฆs: Fรฅ adgang til og klon koden for depotet.
+code.write = Skriv: Skub til depotet, opret filialer og tags.
+issues.read = Lรฆs: Lรฆs og opret problemer og kommentarer.
+issues.write = Skriv: Luk problemer og administrer metadata som etiketter, milepรฆle, modtagere, forfaldsdatoer og afhรฆngigheder.
+pulls.read = Lรฆs: Lรฆsning og oprettelse af pull-anmodninger.
+pulls.write = Skriv: Luk pull-anmodninger og administrer metadata som etiketter, milepรฆle, modtagere, forfaldsdatoer og afhรฆngigheder.
+releases.read = Lรฆs: Se og download udgivelser.
+releases.write = Skriv: Udgiv, rediger og slet udgivelser og deres aktiver.
+wiki.read = Lรฆs: Lรฆs den integrerede wiki og dens historie.
+wiki.write = Skriv: Opret, opdater og slet sider i den integrerede wiki.
+projects.read = Lรฆs: Fรฅ adgang til depot-projekttavler.
+projects.write = Skriv: Opret projekter og kolonner, og rediger dem.
+packages.read = Lรฆs: Se og download pakker, der er tildelt depotet.
+packages.write = Skriv: Udgiv og slet pakker, der er tildelt depotet.
+actions.read = Lรฆs: Se integrerede CI/CD-pipelines og deres logfiler.
+actions.write = Skriv: Udlรธs, genstart, annuller eller godkend afventende CI/CD-pipelines manuelt.
+ext_issues = Fรฅ adgang til linket til en ekstern problemsporing. Tilladelserne administreres eksternt.
+ext_wiki = Fรฅ adgang til linket til en ekstern wiki. Tilladelserne administreres eksternt.
+
+[graphs]
+component_loading = Indlรฆser %sโฆ
+component_loading_failed = Kunne ikke indlรฆse %s
+component_loading_info = Dette kan tage lidt tidโฆ
+component_failed_to_load = Der skete en uventet fejl.
+code_frequency.what = kode frekvens
+contributors.what = bidrag
+recent_commits.what = nylige commits
+
+[dropzone]
+invalid_input_type = Filer af denne type mรฅ ikke uploades.
+remove_file = Fjern fil
+
+default_message = Slip filer eller klik her for at uploade.
+file_too_big = Filstรธrrelsen ({{filesize}} MB) overstiger den maksimale stรธrrelse pรฅ ({{maxFilesize}} MB).
+
+[gpg]
+default_key = Underskrevet med standardnรธglen
+
+error.extract_sign = Kunne ikke udtrรฆkke signatur
+error.generate_hash = Kunne ikke generere hash af commit
+error.no_committer_account = Ingen konto knyttet til committers e-mailadresse
+error.no_gpg_keys_found = Ingen kendt nรธgle fundet for denne signatur i databasen
+error.not_signed_commit = Ikke en underskrevet commit
+error.failed_retrieval_gpg_keys = Kunne ikke hente nogen nรธgle knyttet til committerens konto
+error.probable_bad_signature = ADVARSEL! Selvom der er en nรธgle med dette ID i databasen, bekrรฆfter den ikke denne commit! Denne commit er MISTรNLIG.
+error.probable_bad_default_signature = ADVARSEL! Selvom standardnรธglen har dette ID, bekrรฆfter den ikke denne commit! Denne commit er MISTรNLIG.
+
+[secrets]
+creation.name_placeholder = uafhรฆngig af store og smรฅ bogstaver, alfanumeriske tegn eller understregninger, kan ikke starte med GITEA_ eller GITHUB_
+creation.value_placeholder = Indtast ethvert indhold. Mellemrum i starten og slutningen vil blive udeladt.
+secrets = Hemmeligheder
+description = Hemmeligheder vil blive videregivet til visse handlinger og kan ikke lรฆses pรฅ anden vis.
+none = Der er ingen hemmeligheder endnu.
+creation = Tilfรธj hemmelighed
+creation.success = Hemmeligheden "%s" er blevet tilfรธjet.
+creation.failed = Kunne ikke tilfรธje hemmelighed.
+deletion = Fjern hemmelighed
+deletion.description = Fjernelse af en hemmelighed er permanent og kan ikke fortrydes. Vil du fortsรฆtte?
+deletion.success = Hemmeligheden er blevet fjernet.
+deletion.failed = Hemmeligheden kunne ikke fjernes.
+management = Hรฅndter hemmeligheder
+
+[munits.data]
+b = B
+kib = KiB
+mib = MiB
+gib = GiB
+tib = TiB
+pib = PiB
+eib = EiB
+
+[units]
+unit = Enhed
+error.no_unit_allowed_repo = Du har ikke tilladelse til at fรฅ adgang til nogen sektion af dette depot.
+error.unit_not_allowed = Du har ikke tilladelse til at fรฅ adgang til denne depotsektion.
+
+[projects]
+deleted.display_name = Slettet projekt
+type-1.display_name = Individuelt projekt
+type-2.display_name = Depotprojekt
+type-3.display_name = Organisationsprojekt
+
+[git.filemode]
+changed_filemode = %[1]s โ %[2]s
+directory = Directory
+normal_file = Normal fil
+executable_file = Eksekverbar fil
+symbolic_link = Symbolsk link
+submodule = Submodule
+
+[markup]
+filepreview.line = Linje %[1]d i %[2]s
+filepreview.lines = Linjer %[1]d til %[2]d i %[3]s
+filepreview.truncated = Forhรฅndsvisningen er blevet afkortet
+
+[translation_meta]
+test = (OK) DA was translated by Tacaly
\ No newline at end of file
diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini
index 2fdca4f1f1..385a92a004 100644
--- a/options/locale/locale_de-DE.ini
+++ b/options/locale/locale_de-DE.ini
@@ -18,8 +18,8 @@ template=Vorlage
language=Sprache
notifications=Benachrichtigungen
active_stopwatch=Aktive Zeiterfassung
-create_new=Erstellenโฆ
-user_profile_and_more=Profil und Einstellungenโฆ
+create_new=Erstellen โฆ
+user_profile_and_more=Profil und Einstellungen โฆ
signed_in_as=Angemeldet als
enable_javascript=Diese Website benรถtigt JavaScript.
toc=Inhaltsverzeichnis
@@ -110,7 +110,7 @@ preview=Vorschau
loading=Laden โฆ
error=Fehler
-error404=Die Seite, die du versuchst aufzurufen, existiert nicht oder du bist nicht berechtigt , diese anzusehen.
+error404=Die Seite, die du versuchst aufzurufen, existiert nicht , wurde entfernt oder du bist nicht berechtigt , diese anzusehen.
go_back=Zurรผck
never=Niemals
@@ -158,6 +158,15 @@ filter.private = Privat
more_items = Mehr Eintrรคge
invalid_data = Ungรผltige Daten: %v
copy_generic = In die Zwischenablage kopieren
+test = Test
+error413 = Du hast deine Quota ausgereizt.
+new_repo.title = Neues Repository
+new_migrate.title = Neue Migration
+new_org.title = Neue Organisation
+new_repo.link = Neues Repository
+new_migrate.link = Neue Migration
+new_org.link = Neue Organisation
+copy_path = Pfad kopieren
[aria]
navbar=Navigationsleiste
@@ -189,6 +198,18 @@ buttons.ref.tooltip=Issue oder Pull-Request referenzieren
buttons.switch_to_legacy.tooltip=Legacy-Editor verwenden
buttons.enable_monospace_font=Festbreitenschrift aktivieren
buttons.disable_monospace_font=Festbreitenschrift deaktivieren
+buttons.indent.tooltip = Eintrรคge um eine Ebene verschachteln
+buttons.unindent.tooltip = Eintrรคge um eine Ebene entschachteln
+buttons.new_table.tooltip = Tabelle hinzufรผgen
+table_modal.header = Tabelle hinzufรผgen
+table_modal.placeholder.content = Inhalt
+table_modal.placeholder.header = Kopfzeile
+table_modal.label.rows = Zeilen
+table_modal.label.columns = Spalten
+link_modal.header = Einen Link hinzufรผgen
+link_modal.url = URL
+link_modal.description = Beschreibung
+link_modal.paste_reminder = Hinweis: Wenn du einen URL in der Zwischenablage hast, kannst du durch einfรผgen im Editor direkt einen Link erstellen.
[filter]
string.asc=AโZ
@@ -196,7 +217,7 @@ string.desc=ZโA
[error]
occurred=Ein Fehler ist aufgetreten
-report_message=Wenn du glaubst, dass dies ein Fehler von Forgejo ist, such bitte auf Codeberg nach Issues oder erstelle gegebenenfalls ein neues Issue.
+report_message=Wenn du glaubst, dass dies ein Fehler von Forgejo ist, such bitte auf Codeberg nach Issues oder erstelle gegebenenfalls ein neues Issue.
missing_csrf=Fehlerhafte Anfrage: Kein CSRF-Token verfรผgbar
invalid_csrf=Fehlerhafte Anfrage: Ungรผltiger CSRF-Token
not_found=Das Ziel konnte nicht gefunden werden.
@@ -206,13 +227,13 @@ server_internal = Interner Serverfehler
[startpage]
app_desc=Ein einfacher, selbst gehosteter Git-Service
install=Einfach zu installieren
-install_desc=Starte einfach die Anwendung fรผr deine Plattform oder nutze Docker . Es existieren auch paketierte Versionen .
+install_desc=Starte einfach die Anwendung fรผr deine Plattform oder nutze Docker . Es existieren auch paketierte Versionen .
platform=Plattformรผbergreifend
-platform_desc=Forgejo lรคuft รผberall, wo Go kompiliert: Windows, macOS, Linux, ARM, etc. Wรคhle das System, das dir am meisten gefรคllt!
+platform_desc=Forgejo lรคuft auf freien Betriebssystemen wie Linux und FreeBSD sowie auf verschiedenen CPU-Architekturen. Wรคhle das System, das du magst!
lightweight=Leichtgewichtig
lightweight_desc=Forgejo hat minimale Systemanforderungen und kann selbst auf einem gรผnstigen und stromsparenden Raspberry Pi betrieben werden!
license=Quelloffen
-license_desc=Hole dir Forgejo ! Tritt uns bei, indem du uns hilfst , dieses Projekt noch besser zu gestalten. Scheue dich nicht davor, bei uns mitzuwirken!
+license_desc=Hole dir Forgejo ! Schlieร dich uns an, indem du uns hilfst , dieses Projekt noch besser zu gestalten. Scheue dich nicht davor, bei uns mitzuwirken!
[install]
install=Installation
@@ -233,7 +254,7 @@ sqlite_helper=Dateipfad zur SQLite3-Datenbank. Gib einen absoluten Pfad an, w
reinstall_error=Du versuchst, in eine bereits existierende Forgejo Datenbank zu installieren
reinstall_confirm_message=Eine Neuinstallation mit einer bestehenden Forgejo-Datenbank kann mehrere Probleme verursachen. In den meisten Fรคllen solltest du deine vorhandene โapp.iniโ verwenden, um Forgejo auszufรผhren. Wenn du weiรt, was du tust, bestรคtige die folgenden Angaben:
reinstall_confirm_check_1=Die von der SECRET_KEY in app.ini verschlรผsselten Daten kรถnnen verloren gehen: Benutzer kรถnnen sich unter Umstรคnden nicht mit 2FA/OTP einloggen und Spiegel kรถnnten nicht mehr richtig funktionieren. Mit der Ankreuzung dieses Kรคstchens bestรคtigst du, dass die aktuelle app.ini-Datei den korrekten SECRET_KEY enthรคlt.
-reinstall_confirm_check_2=Die Repositorys und Einstellungen mรผssen eventuell neu synchronisiert werden. Durch das Ankreuzen dieses Kรคstchens bestรคtigst du, dass du die Hooks fรผr die Repositories und die authorized_keys-Datei manuell neu synchronisierst. Du bestรคtigst, dass du sicherstellst, dass die Repository- und Spiegeleinstellungen korrekt sind.
+reinstall_confirm_check_2=Die Repositorys und Einstellungen mรผssen eventuell neu synchronisiert werden. Durch das Ankreuzen dieses Kรคstchens bestรคtigst du, dass du die Hooks fรผr die Repositorys und die authorized_keys-Datei manuell neu synchronisierst. Du bestรคtigst, dass du sicherstellst, dass die Repository- und Spiegeleinstellungen korrekt sind.
reinstall_confirm_check_3=Du bestรคtigst, dass du absolut sicher bist, dass diese Forgejo mit der richtigen app.ini lรคuft, und du sicher bist, dass du neu installieren musst. Du bestรคtigst, dass du die oben genannten Risiken anerkennst.
err_empty_db_path=Der SQLite3 Datenbankpfad darf nicht leer sein.
no_admin_and_disable_registration=Du kannst Selbst-Registrierungen nicht deaktivieren, ohne ein Administratorkonto zu erstellen.
@@ -291,8 +312,8 @@ enable_captcha=Registrierungs-Captcha aktivieren
enable_captcha.description=Eine Captcha-Eingabe bei der Benutzerselbstregistrierung verlangen.
require_sign_in_view=Ansehen erfordert Anmeldung
require_sign_in_view.description=Seitenzugriff auf angemeldete Benutzer beschrรคnken. Besucher sehen nur die Anmelde- und Registrierungsseite.
-admin_setting.description=Das Erstellen eines Administrator-Kontos ist optional. Der erste registrierte Benutzer wird automatisch Administrator.
-admin_title=Administratoreinstellungen
+admin_setting.description=Das Erstellen eines Administratorkontos ist optional. Der erste registrierte Benutzer wird automatisch Administrator.
+admin_title=Administratorkonto-Einstellungen
admin_name=Administrator-Benutzername
admin_password=Passwort
confirm_password=Passwort bestรคtigen
@@ -308,7 +329,7 @@ run_user_not_match=Der โAusfรผhren alsโ-Benutzername ist nicht der aktuelle
internal_token_failed=Fehler beim Generieren des internen Tokens: %v
secret_key_failed=Fehler beim Generieren des geheimen Schlรผssels: %v
save_config_failed=Fehler beim Speichern der Konfiguration: %v
-invalid_admin_setting=Administrator-Konto Einstellungen sind ungรผltig: %v
+invalid_admin_setting=Die Administratorkonto-Einstellungen sind ungรผltig: %v
invalid_log_root_path=Pfad zum Log-Verzeichnis ist ungรผltig: %v
default_keep_email_private=E-Mail-Adressen standardmรครig verbergen
default_keep_email_private.description=E-Mail-Adressen von neuen Benutzern standardmรครig verbergen, damit diese nicht direkt nach der Registrierung รถffentlich wird.
@@ -318,7 +339,7 @@ default_enable_timetracking=Zeiterfassung standardmรครig aktivieren
default_enable_timetracking.description=Zeiterfassung standardmรครig fรผr neue Repositorys aktivieren.
no_reply_address=Versteckte E-Mail-Domain
no_reply_address_helper=Domain-Name fรผr Benutzer mit einer versteckten Emailadresse. Zum Beispiel wird der Benutzername โJoeโ in Git als โjoe@noreply.example.orgโ protokolliert, wenn die versteckte E-Mail-Domain โnoreply.example.orgโ festgelegt ist.
-password_algorithm=Passwort Hashing Algorithmus
+password_algorithm=Passwort-Hashing-Algorithmus
invalid_password_algorithm=Ungรผltiger Passwort-Hash-Algorithmus
password_algorithm_helper=Lege einen Passwort-Hashing-Algorithmus fest. Algorithmen haben unterschiedliche Anforderungen und Stรคrken. Der argon2-Algorithmus ist ziemlich sicher, aber er verbraucht viel Speicher und kann fรผr kleine Systeme ungeeignet sein.
enable_update_checker=Aktualisierungsprรผfung aktivieren
@@ -326,11 +347,11 @@ env_config_keys=Umgebungskonfiguration
env_config_keys_prompt=Die folgenden Umgebungsvariablen werden auch auf Ihre Konfigurationsdatei angewendet:
allow_dots_in_usernames = Erlaubt Benutzern die Verwendung von Punkten in ihren Benutzernamen. Hat keine Auswirkungen auf bestehende Konten.
enable_update_checker_helper_forgejo = Prรผft regelmรครig auf neue Forgejo-Versionen, indem ein DNS-TXT-Eintrag unter release.forgejo.org รผberprรผft wird.
-smtp_from_invalid = Die โSende E-Mail Alsโ-Adresse ist ungรผltig
+smtp_from_invalid = Die โSende E-Mail alsโ-Adresse ist ungรผltig
config_location_hint = Diese Konfigurationsoptionen werden gespeichert in:
allow_only_external_registration = Registrierung nur mittels externer Dienste zulassen
app_slogan = Instanz-Slogan
-app_slogan_helper = Instanz-Slogan hier eingeben. Leer lassen zum deaktivieren.
+app_slogan_helper = Instanz-Slogan hier eingeben. Leer lassen zum Deaktivieren.
[home]
uname_holder=Benutzername oder E-Mail-Adresse
@@ -397,14 +418,14 @@ forgot_password_title=Passwort vergessen
forgot_password=Passwort vergessen?
sign_up_now=Noch kein Konto? Jetzt registrieren.
sign_up_successful=Konto wurde erfolgreich erstellt. Willkommen!
-confirmation_mail_sent_prompt=Eine neue Bestรคtigungs-E-Mail wurde an %s gesendet. Bitte รผberprรผfe dein Postfach innerhalb der nรคchsten %s, um die Registrierung abzuschlieรen.
+confirmation_mail_sent_prompt=Eine neue Bestรคtigungs-E-Mail wurde an %s gesendet. Um den Registrierungsprozess abzuschlieรen, รผberprรผfe bitte deinen Posteingang und folge dem angegebenen Link innerhalb von: %s. Falls die E-Mail inkorrekt sein sollte, kannst du dich einloggen und anfragen, eine weitere Bestรคtigungs-E-Mail an eine andere Adresse zu senden.
must_change_password=Aktualisiere dein Passwort
allow_password_change=Verlange vom Benutzer das Passwort zu รคndern (empfohlen)
-reset_password_mail_sent_prompt=Eine Bestรคtigungs-E-Mail wurde an %s gesendet. Bitte รผberprรผfe dein Postfach innerhalb von %s, um den Wiederherstellungsprozess abzuschlieรen.
+reset_password_mail_sent_prompt=Eine Bestรคtigungs-E-Mail wurde an %s gesendet. Um den Kontowiederherstellungsprozess abzuschlieรen, รผberprรผfe bitte deinen Posteingang und folge dem angegebenen Link innerhalb von %s.
active_your_account=Aktiviere dein Konto
account_activated=Konto wurde aktiviert
-prohibit_login=Anmelden verboten
-prohibit_login_desc=Die Anmeldung mit diesem Konto ist nicht gestattet. Bitte kontaktiere den Administrator.
+prohibit_login=Der Account ist gesperrt
+prohibit_login_desc=Dein Account ist auf dieser Instanz gesperrt worden. Bitte kontaktiere den Instanz-Administrator.
resent_limit_prompt=Du hast bereits eine Aktivierungs-E-Mail angefordert. Bitte warte 3 Minuten und probiere es dann nochmal.
has_unconfirmed_mail=Hallo %s, du hast eine unbestรคtigte E-Mail-Adresse (%s ). Wenn du keine Bestรคtigungs-E-Mail erhalten hast oder eine neue senden mรถchtest, klicke bitte auf den folgenden Button.
resend_mail=Aktivierungs-E-Mail erneut verschicken
@@ -430,7 +451,7 @@ oauth_signup_tab=Neues Konto registrieren
oauth_signup_title=Neues Konto fertigstellen
oauth_signup_submit=Konto vervollstรคndigen
oauth_signin_tab=Mit einem existierenden Konto verbinden
-oauth_signin_title=Anmelden um verbundenes Konto zu autorisieren
+oauth_signin_title=Anmelden, um verbundenes Konto zu autorisieren
oauth_signin_submit=Konto verbinden
oauth.signin.error=Beim Verarbeiten der Autorisierungsanfrage ist ein Fehler aufgetreten. Wenn dieser Fehler weiterhin besteht, wende dich bitte an deinen Administrator.
oauth.signin.error.access_denied=Die Autorisierungsanfrage wurde abgelehnt.
@@ -452,7 +473,7 @@ authorize_title=โ%sโ den Zugriff auf deinen Account gestatten?
authorization_failed=Autorisierung fehlgeschlagen
authorization_failed_desc=Die Autorisierung ist fehlgeschlagen, da wir eine ungรผltige Anfrage erkannt haben. Bitte kontaktiere den Betreuer der App, die du zu autorisieren versucht hast.
sspi_auth_failed=SSPI-Authentifizierung fehlgeschlagen
-password_pwned=Das von dir gewรคhlte Passwort befindet sich auf einer List gestohlener Passwรถrter , die รถffentlich verfรผgbar sind. Bitte versuche es erneut mit einem anderen Passwort und ziehe in Erwรคgung, auch anderswo deine Passwรถrter zu รคndern.
+password_pwned=Das von dir gewรคhlte Passwort befindet sich auf einer List gestohlener Passwรถrter , die รถffentlich verfรผgbar sind. Bitte versuche es erneut mit einem anderen Passwort und ziehe in Erwรคgung, auch anderswo deine Passwรถrter zu รคndern.
password_pwned_err=Anfrage an HaveIBeenPwned konnte nicht abgeschlossen werden
change_unconfirmed_email_summary = รndern der E-Mail-Adresse, an die die Aktivierungsnachricht gesendet wird.
change_unconfirmed_email_error = รndern der E-Mail-Adresse fehlgeschlagen: %v
@@ -461,6 +482,13 @@ change_unconfirmed_email = Wenn du bei der Anmeldung eine falsche E-Mail-Adresse
remember_me.compromised = Der Anmeldetoken ist nicht mehr gรผltig, dies kรถnnte auf ein kompromittiertes Konto hindeuten. Bitte prรผfe dein Konto auf ungewรถhnliche Aktivitรคten.
tab_signin = Anmelden
tab_signup = Registrieren
+sign_up_button = Jetzt registrieren.
+back_to_sign_in = Zurรผck zur Anmeldung
+sign_in_openid = Mit OpenID fortfahren
+hint_login = Hast du bereits ein Konto? Jetzt anmelden!
+hint_register = Brauchst du ein Konto? Jetzt registrieren.
+unauthorized_credentials = Die Zugangsdaten sind inkorrekt oder abgelaufen. Versuchen es erneut oder siehe %s fรผr mehr Informationen
+use_onetime_code = Einen One-Time-Code benutzen
[mail]
view_it_on=Auf %s ansehen
@@ -477,10 +505,10 @@ activate_email=Bestรคtige deine E-Mail-Adresse
activate_email.title=%s, bitte verifiziere deine E-Mail-Adresse
activate_email.text=Bitte klicke innerhalb von %s auf folgenden Link, um dein Konto zu aktivieren:
-register_notify=Willkommen bei Forgejo
+register_notify=Willkommen bei %s
register_notify.title=%[1]s, willkommen bei %[2]s
register_notify.text_1=dies ist deine Bestรคtigungs-E-Mail fรผr %s!
-register_notify.text_2=Du kannst dich mit dem Benutzernamen โ%sโ anmelden.
+register_notify.text_2=Du kannst dich mit dem Benutzernamen โ%sโ anmelden
register_notify.text_3=Wenn jemand anderes diesen Account fรผr dich erstellt hat, musst du zuerst dein Passwort setzen .
reset_password=Stelle dein Konto wieder her
@@ -530,6 +558,22 @@ team_invite.text_3=Hinweis: Diese Einladung war fรผr %[1]s gedacht. Wenn du dies
admin.new_user.subject = Neuer Benutzer %s hat sich gerade angemeldet
admin.new_user.user_info = Benutzerinformationen
admin.new_user.text = Bitte hier klicken , um den Benutzer aus dem Admin-Panel zu verwalten.
+password_change.subject = Dein Passwort wurde geรคndert
+password_change.text_1 = Das Passwort fรผr deinen Account wurde soeben geรคndert.
+primary_mail_change.subject = Deine primรคre E-Mail-Adresse wurde geรคndert
+totp_disabled.subject = TOTP wurde deaktiviert
+totp_disabled.text_1 = TOTP (Time-based one-time password [zeitbasiertes Einmalpasswort]) wurde auf deinem Account soeben deaktiviert.
+totp_disabled.no_2fa = Es sind keine anderen 2FA-Methoden mehr konfiguriert, was bedeutet, dass es nicht mehr nรถtig ist, sich in deinen Account mit 2FA einzuloggen.
+removed_security_key.subject = Ein Sicherheitsschlรผssel wurde entfernt
+removed_security_key.no_2fa = Es sind keine anderen 2FA-Methoden mehr konfiguriert, was bedeutet, dass es nicht mehr nรถtig ist, sich in deinen Account mit 2FA einzuloggen.
+account_security_caution.text_1 = Wenn du das warst, kannst du diese E-Mail bedenkenlos ignorieren.
+removed_security_key.text_1 = Sicherheitsschlรผssel โ%[1]sโ wurde soeben von deinem Account entfernt.
+reset_password.text_1 = Das Passwort fรผr deinen Account wurde soeben geรคndert.
+primary_mail_change.text_1 = Die primรคre E-Mail-Adresse deines Account wurde soeben zu %[1]s geรคndert. Das bedeutet, dass diese E-Mail-Adresse keine E-Mail-Benachrichtigungen fรผr deinen Account erhalten wird.
+account_security_caution.text_2 = Wenn du das nicht warst, wurde dein Account kompromittiert. Bitte kontaktiere die Admins dieser Webseite.
+totp_enrolled.subject = Du hast TOTP als 2FA-Methode aktiviert
+totp_enrolled.text_1.has_webauthn = Du hast gerade eben TOTP fรผr deinen Account aktiviert. Das bedeutet, dass du in Zukunft fรผr alle Logins in deinen Account TOTP als 2FA-Methode oder einen deiner Sicherheitsschlรผssel benutzen kรถnntest.
+totp_enrolled.text_1.no_webauthn = Du hast gerade eben TOTP fรผr deinen Account aktiviert. Das bedeutet, dass du in Zukunft fรผr alle Logins in deinen Account TOTP als 2FA-Methode benutzen musst.
[modal]
yes=Ja
@@ -617,8 +661,8 @@ organization_leave_success=Du hast die Organisation %s erfolgreich verlassen.
invalid_ssh_key=Dein SSH-Key kann nicht รผberprรผft werden: %s
invalid_gpg_key=Dein GPG-Key kann nicht รผberprรผft werden: %s
invalid_ssh_principal=Ungรผltige Identitรคt: %s
-must_use_public_key=Der von dir bereitgestellte Key ist ein privater Key. Bitte lade deinen privaten Key nirgendwo hoch. Verwende stattdessen deinen รถffentlichen Key.
-unable_verify_ssh_key=Der SSH-Key kann nicht verifiziert werden, รผberprรผfe ihn auf Fehler.
+must_use_public_key=Der von dir bereitgestellte Schlรผssel ist ein privater. Bitte lade deinen privaten Schlรผssel nirgendwo hoch, sondern verwende stattdessen deinen รถffentlichen.
+unable_verify_ssh_key=Der SSH-Schlรผssel kann nicht verifiziert werden, รผberprรผfe ihn auf Fehler.
auth_failed=Authentifizierung fehlgeschlagen: %v
still_own_repo=Dein Konto besitzt ein oder mehrere Repositorys. Diese mรผssen erst gelรถscht oder รผbertragen werden.
@@ -641,6 +685,8 @@ Website = Webseite
Location = Ort
To = Branchname
AccessToken = Zugangstoken
+username_claiming_cooldown = Der Benutzername kann nicht beansprucht werden, weil seine Schutzzeit noch nicht vorbei ist. Er kann am %[1]s beansprucht werden.
+email_domain_is_not_allowed = Die Domain der E-Mail-Adresse des Benutzers %s steht in Konflikt mit EMAIL_DOMAIN_ALLOWLIST oder EMAIL_DOMAIN_BLOCKLIST. Bitte stelle sicher, dass du die E-Mail-Adresse richtig gesetzt hast.
[user]
@@ -654,7 +700,7 @@ watched=Beobachtete Repositorys
code=Quelltext
projects=Projekte
overview=รbersicht
-following_few=%d Folge ich
+following_few=%d folge ich
follow=Folgen
unfollow=Nicht mehr folgen
user_bio=Biografie
@@ -668,19 +714,24 @@ form.name_reserved=Der Benutzername โ%sโ ist reserviert.
form.name_pattern_not_allowed=Das Muster โ%sโ ist nicht in einem Benutzernamen erlaubt.
form.name_chars_not_allowed=Benutzername โ%sโ enthรคlt ungรผltige Zeichen.
block_user = Benutzer blockieren
-block_user.detail = Bitte beachte, dass andere Maรnahmen ergriffen werden, wenn du diesen Benutzer blockierst, wie:
-block_user.detail_2 = Dieser Benutzer kann nicht mit deinem Repository, erstellten Issues und Kommentaren interagieren.
-block_user.detail_1 = Dieser Benutzer folgt dir nicht mehr.
+block_user.detail = Bitte beachte, dass die Blockierung eines Benutzers auch andere Auswirkungen hat, so wie:
+block_user.detail_2 = Dieser Benutzer wird nicht mehr nicht mit deinen Repositorys oder von dir erstellten Issues und Kommentaren interagieren kรถnnen.
+block_user.detail_1 = Ihr werdet euch nicht mehr gegenseitig folgen und kรถnnt euch auch nicht mehr gegenseitig folgen.
block = Blockieren
follow_blocked_user = Du kannst diesen Benutzer nicht folgen, weil du ihn blockiert hast, oder er dich blockiert hat.
-block_user.detail_3 = Dieser Benutzer kann dich nicht als einen Mitarbeiter hinzufรผgen, und du kannst ihn nicht als Mitarbeiter hinzufรผgen.
+block_user.detail_3 = Ihr werdet nicht mehr in der Lage sein, euch gegenseitig als Repository-Mitarbeiter hinzuzufรผgen.
unblock = Nicht mehr blockieren
followers_one = %d Follower
-following_one = %d Folge ich
+following_one = %d folge ich
followers.title.few = Follower
following.title.one = Folgt
following.title.few = Folgt
followers.title.one = Follower
+public_activity.visibility_hint.self_public = Deine Aktivitรคt ist sichtbar fรผr alle, auรer fรผr Interaktionen in privaten Rรคumen. Konfigurieren .
+public_activity.visibility_hint.admin_public = Diese Aktivitรคt ist sichtbar fรผr alle, aber als Administrator kannst du auรerdem Interaktionen in privaten Rรคumen sehen.
+public_activity.visibility_hint.self_private = Deine Aktivitรคt ist nur sichtbar fรผr dich und den Instanzadministratoren. Konfigurieren .
+public_activity.visibility_hint.admin_private = Diese Aktivitรคt ist sichtbar fรผr dich, weil du ein Administrator bist, aber der Benutzer will sie privat halten.
+public_activity.visibility_hint.self_private_profile = Deine Aktivitรคt ist nur fรผr dich und die Instanzadministratoren sichtbar, weil den Profil privat ist. Konfigurieren .
[settings]
profile=Profil
@@ -702,9 +753,9 @@ uid=UID
webauthn=Hardware-Sicherheitsschlรผssel
public_profile=รffentliches Profil
-biography_placeholder=Erzรคhle uns ein wenig รผber dich selbst! (Du kannst Markdown verwenden)
+biography_placeholder=Erzรคhle anderen ein wenig รผber dich selbst! (Markdown wird unterstรผtzt)
location_placeholder=Teile deinen ungefรคhren Standort mit anderen
-profile_desc=Leg fest, wie dein Profil anderen Benutzern angezeigt wird. Deine primรคre E-Mail-Adresse wird fรผr Benachrichtigungen, Passwort-Wiederherstellung und webbasierte Git-Operationen verwendet.
+profile_desc=รber dich
password_username_disabled=Benutzer, die nicht von Forgejo verwaltet werden kรถnnen ihren Benutzernamen nicht รคndern. Bitte kontaktiere deinen Administrator fรผr mehr Details.
full_name=Vollstรคndiger Name
website=Webseite
@@ -723,7 +774,7 @@ cancel=Abbrechen
language=Sprache
ui=Theme
hidden_comment_types=Ausgeblendete Kommentartypen
-hidden_comment_types_description=Die hier markierten Kommentartypen werden nicht innerhalb der Issue-Seiten angezeigt. Die Markierung von โLabelโ zum Beispiel entfernt alle Kommentare der Form โ hat hinzugefรผgt/entferntโ.
+hidden_comment_types_description=Die hier markierten Kommentartypen werden innerhalb der Issue-Seiten nicht angezeigt. Beispielsweise entfernt das Ankreuzen von โLabelโ alle Kommentare der Form โ hat hinzugefรผgt/entferntโ.
hidden_comment_types.ref_tooltip=Kommentare, in denen dieses Issue von einem anderen Issue/Commit/โฆ referenziert wurde
hidden_comment_types.issue_ref_tooltip=Kommentare, bei denen der Benutzer den Branch/Tag des Issues รคndert
comment_type_group_reference=Verweis auf Mitglieder
@@ -761,7 +812,7 @@ old_password=Aktuelles Passwort
new_password=Neues Passwort
retype_new_password=Neues Passwort bestรคtigen
password_incorrect=Das aktuelle Passwort ist falsch.
-change_password_success=Dein Passwort wurde aktualisiert. Bitte verwende dieses beim nรคchsten Einloggen.
+change_password_success=Dein Passwort wurde aktualisiert. Verwende ab jetzt dein neues Passwort zum Einloggen.
password_change_disabled=Benutzer, die nicht von Forgejo verwaltet werden, kรถnnen ihr Passwort im Web-Interface nicht รคndern.
emails=E-Mail-Adressen
@@ -769,7 +820,7 @@ manage_emails=E-Mail-Adressen verwalten
manage_themes=Standard-Theme
manage_openid=OpenID-Adressen
email_desc=Deine primรคre E-Mail-Adresse wird fรผr Benachrichtigungen, Passwort-Wiederherstellung und, sofern sie nicht versteckt ist, web-basierte Git-Operationen verwendet.
-theme_desc=Dies wird dein Standard-Theme auf der Seite sein.
+theme_desc=Dieses Thema wird fรผr die Weboberflรคche verwendet, wenn du angemeldet bist.
primary=Primรคr
activated=Aktiviert
requires_activation=Erfordert Aktivierung
@@ -790,21 +841,21 @@ add_new_email=Neue E-Mail-Adresse hinzufรผgen
add_new_openid=Neue OpenID-URI hinzufรผgen
add_email=E-Mail-Adresse hinzufรผgen
add_openid=OpenID-URI hinzufรผgen
-add_email_confirmation_sent=Eine Bestรคtigungs-E-Mail wurde an โ%sโ gesendet. Bitte รผberprรผfe dein Postfach innerhalb der nรคchsten %s, um die E-Mail-Adresse zu bestรคtigen.
+add_email_confirmation_sent=Eine Bestรคtigungs-E-Mail wurde an โ%sโ gesendet. Um deine E-Mail-Adresse zu bestรคtigen, รผberprรผfe bitte deinen Posteingang und folge dem angegebenen Link innerhalb von: %s.
add_email_success=Die neue E-Mail-Addresse wurde hinzugefรผgt.
email_preference_set_success=E-Mail-Einstellungen wurden erfolgreich aktualisiert.
add_openid_success=Die neue OpenID-Adresse wurde hinzugefรผgt.
keep_email_private=E-Mail-Adresse verbergen
-keep_email_private_popup=Dies wird deine E-Mail-Adresse nicht nur in deinem Profil ausblenden, sondern auch, wenn du einen Pull Request erstellst oder eine Datei รผber das Web-Interface bearbeitest. Gepushte Commits werden nicht geรคndert. Benutze %s in Commits, um sie mit deinem Konto zu assoziieren.
+keep_email_private_popup=Deine Mailadresse wird nicht in deinem Profil angezeigt und wird nicht der Standard fรผr Commits รผber das Webinterface sein, wie zum Beispiel Dateiuploads, Bearbeitungen, und Merge-Commits. Stattdessen kann eine besondere Adresse %s benutzt werden, um Commits mit deinem Account zu verbinden. Diese Option wirkt sich nicht auf bestehende Commits aus.
openid_desc=Mit OpenID kannst du dich รผber einen Drittanbieter authentifizieren.
manage_ssh_keys=SSH-Schlรผssel verwalten
manage_ssh_principals=SSH-Zertifikats-Principals verwalten
manage_gpg_keys=GPG-Schlรผssel verwalten
add_key=Schlรผssel hinzufรผgen
-ssh_desc=Diese รถffentlichen SSH-Keys sind mit deinem Account verbunden. Der dazugehรถrigen privaten SSH-Keys geben dir vollen Zugriff auf deine Repositorys. Verifizierte SSH-Key kรถnnen verwendet werden, um SSH-signierte Git-Commits zu signieren.
+ssh_desc=Diese รถffentlichen SSH-Schlรผssel sind mit deinem Account verbunden. Der dazugehรถrigen privaten SSH-Schlรผssel geben dir vollen Zugriff auf deine Repositorys. Verifizierte SSH-Schlรผssel kรถnnen verwendet werden, um SSH-signierte Git-Commits zu signieren.
principal_desc=Diese SSH-Zertifikat-Principals sind mit deinem Konto verknรผpft und erlauben den vollen Zugriff auf deine Repositorys.
-gpg_desc=Diese รถffentlichen GPG-Keys sind mit deinem Account verbunden und werden benutzt um deine Commits zu verifizieren. Halte die dazugehรถrigen privaten GPG-Keys geheim, da diese deine Commits signieren.
+gpg_desc=Diese รถffentlichen GPG-Schlรผssel sind mit deinem Account verbunden und werden benutzt, um deine Commits zu verifizieren. Halte die dazugehรถrigen privaten GPG-Schlรผssel geheim, da diese deine Commits signieren.
ssh_helper=Brauchst du Hilfe? Sieh dir die Anleitung zum Erzeugen deiner eigenen SSH-Schlรผssel an oder zum Lรถsen hรคufiger Probleme , denen du bei der Arbeit mit SSH begegnen kannst.
gpg_helper=Brauchst du Hilfe? Sieh dir die Anleitung รผber GPG an.
add_new_key=SSH-Schlรผssel hinzufรผgen
@@ -845,7 +896,7 @@ key_id=Schlรผssel-ID
key_name=Schlรผsselname
key_content=Inhalt
principal_content=Inhalt
-add_key_success=Der SSH-Key โ%sโ wurde hinzugefรผgt.
+add_key_success=Der SSH-Schlรผssel โ%sโ wurde hinzugefรผgt.
add_gpg_key_success=Der GPG-Schlรผssel โ%sโ wurde hinzugefรผgt.
add_principal_success=Die SSH-Zertifikatsidentitรคt โ%sโ wurde hinzugefรผgt.
delete_key=Entfernen
@@ -898,7 +949,7 @@ select_permissions=Berechtigungen auswรคhlen
permission_no_access=Kein Zugriff
permission_read=Lesen
permission_write=Lesen und Schreiben
-access_token_desc=Ausgewรคhlte Token-Berechtigungen beschrรคnken die Authentifizierung auf die entsprechenden API -Routen. Lies die Dokumentation fรผr mehr Informationen.
+access_token_desc=Ausgewรคhlte Token-Berechtigungen beschrรคnken die Authentifizierung auf die entsprechenden API -Routen. Lies die Dokumentation fรผr mehr Informationen.
at_least_one_permission=Du musst mindestens eine Berechtigung auswรคhlen, um ein Token zu erstellen
permissions_list=Berechtigungen:
@@ -917,8 +968,8 @@ oauth2_confidential_client=Vertraulicher Client. Fรผr Anwendungen aktivieren, di
oauth2_redirect_uris=URIs fรผr die Weiterleitung. Bitte verwende eine neue Zeile fรผr jede URI.
save_application=Speichern
oauth2_client_id=Client-ID
-oauth2_client_secret=Client-Secret
-oauth2_regenerate_secret=Secret neu generieren
+oauth2_client_secret=Client-Geheimnis
+oauth2_regenerate_secret=Geheimnis neu generieren
oauth2_regenerate_secret_hint=Secret verloren?
oauth2_client_secret_hint=Das Secret wird nach dem Verlassen oder Aktualisieren dieser Seite nicht mehr angezeigt. Bitte stelle sicher, dass du es gespeichert hast.
oauth2_application_edit=Bearbeiten
@@ -933,7 +984,7 @@ revoke_oauth2_grant=Autorisierung widerrufen
revoke_oauth2_grant_description=Wenn du die Autorisierung widerrufst, kann die Anwendung nicht mehr auf deine Daten zugreifen. Bist du dir sicher?
revoke_oauth2_grant_success=Zugriff erfolgreich widerrufen.
-twofa_desc=Um dein Konto gegen Passwortdiebstahl zu schรผtzen, kannst du eine Smartphone oder ein anderes Gerรคt verwenden, um Time-Based One-Time Passwords (โTOTPโ) zu erhalten.
+twofa_desc=Um dein Konto gegen Passwortdiebstahl zu schรผtzen, kannst du eine Smartphone oder ein anderes Gerรคt verwenden, um zeitbasierte Einmalpasswรถrter (โTOTPโ) zu erhalten.
twofa_is_enrolled=Fรผr dein Konto ist die Zwei-Faktor-Authentifizierung eingeschaltet .
twofa_not_enrolled=Fรผr dein Konto ist die Zwei-Faktor-Authentifizierung momentan nicht eingeschaltet.
twofa_disable=Zwei-Faktor-Authentifizierung deaktivieren
@@ -951,7 +1002,7 @@ passcode_invalid=Die PIN ist falsch. Probiere es erneut.
twofa_enrolled=Die Zwei-Faktor-Authentifizierung wurde fรผr dein Konto aktiviert. Bewahre deinen einmalig verwendbaren Wiederherstellungsschlรผssel (%s) an einem sicheren Ort auf, da er nicht wieder angezeigt werden wird.
twofa_failed_get_secret=Fehler beim Abrufen des Secrets.
-webauthn_desc=Sicherheitsschlรผssel sind Gerรคte, die kryptografische Schlรผssel beeinhalten. Diese kรถnnen fรผr die Zwei-Faktor-Authentifizierung verwendet werden. Der Sicherheitsschlรผssel muss den Standard โWebAuthn โ unterstรผtzen.
+webauthn_desc=Sicherheitsschlรผssel sind Gerรคte, die kryptografische Schlรผssel beeinhalten. Diese kรถnnen fรผr die Zwei-Faktor-Authentifizierung verwendet werden. Der Sicherheitsschlรผssel muss den Standard โWebAuthn โ unterstรผtzen.
webauthn_register_key=Sicherheitsschlรผssel hinzufรผgen
webauthn_nickname=Nickname
webauthn_delete_key=Sicherheitsschlรผssel entfernen
@@ -977,7 +1028,7 @@ confirm_delete_account=Lรถschen bestรคtigen
delete_account_title=Benutzerkonto lรถschen
delete_account_desc=Bist du sicher, dass du diesen Account dauerhaft lรถschen mรถchtest?
-email_notifications.enable=E-Mail Benachrichtigungen aktivieren
+email_notifications.enable=E-Mail-Benachrichtigungen aktivieren
email_notifications.onmention=Nur E-Mail bei Erwรคhnung
email_notifications.disable=E-Mail-Benachrichtigungen deaktivieren
email_notifications.submit=E-Mail-Einstellungen festlegen
@@ -987,14 +1038,14 @@ visibility=Benutzersichtbarkeit
visibility.public=รffentlich
visibility.public_tooltip=Fรผr alle sichtbar
visibility.limited=Begrenzt
-visibility.limited_tooltip=Nur fรผr authentifizierte Benutzer sichtbar
+visibility.limited_tooltip=Nur fรผr angemeldete Benutzer sichtbar
visibility.private=Privat
visibility.private_tooltip=Sichtbar nur fรผr Mitglieder von Organisationen, denen du beigetreten bist
user_block_success = Dieser Benutzer wurde erfolgreich blockiert.
twofa_recovery_tip = Falls du dein Gerรคt verlierst, wirst du in der Lage sein, einen einmalig verwendbaren Wiederherstellungsschlรผssel zu verwenden, um den auf dein Konto wiederherzustellen.
webauthn_alternative_tip = Du mรถchtest vielleicht eine zusรคtzliche Authentifizierungsmethode einrichten.
blocked_users_none = Keine Benutzer blockiert.
-webauthn_key_loss_warning = Falls du deine Security-Keys verlierst, wirst du Zugang zu deinem Konto verlieren.
+webauthn_key_loss_warning = Falls du deine Sicherheitsschlรผssel verlierst, wirst du Zugang zu deinem Konto verlieren.
user_unblock_success = Die Blockierung dieses Benutzers wurde erfolgreich zurรผckgenommen.
blocked_users = Blockierte Benutzer
blocked_since = Blockiert seit %s
@@ -1003,11 +1054,44 @@ hints = Hinweise
additional_repo_units_hint = Aktivierung zusรคtzlicher Repository-Einheiten vorschlagen
update_hints = Hinweise aktualisieren
update_hints_success = Hinweise wurden aktualisiert.
-additional_repo_units_hint_description = Einen โMehr Einheiten hinzufรผgen โฆโ-Button fรผr Repositorys, welche nicht alle verfรผgbaren Einheiten aktiviert haben, anzeigen.
+additional_repo_units_hint_description = Einen โMehr aktivierenโ-Hinweis fรผr Repositorys, welche nicht alle verfรผgbaren Einheiten aktiviert haben, anzeigen.
pronouns = Pronomen
pronouns_custom = Eigene
pronouns_unspecified = Nicht spezifiziert
language.title = Standardsprache
+keep_activity_private.description = Deine รถffentliche Aktivitรคt wird nur fรผr dich selbst und die Instanzadminstratoren sichtbar sein.
+language.localization_project = Hilf uns, Forgejo in deine Sprache zu รผbersetzen! Mehr erfahren .
+language.description = Diese Sprache wird in deinem Konto gespeichert und standardmรครig nach dem Anmelden benutzt.
+user_block_yourself = Du kannst dich nicht selbst blockieren.
+pronouns_custom_label = Individuelle Pronomen
+change_username_redirect_prompt.with_cooldown.one = Der alte Benutzername ist nach einer Schutzzeit von einem Tag wieder fรผr alle verfรผgbar. Du kannst den alten Benutzername wรคhrend dieser Schutzzeit erneut beanspruchen.
+change_username_redirect_prompt.with_cooldown.few = Der alte Benutzername ist nach einer Schutzzeit von %[1]d Tagen wieder fรผr alle verfรผgbar. Du kannst den alten Benutzername wรคhrend dieser Schutzzeit erneut beanspruchen.
+keep_pronouns_private = Pronomen nur angemeldeten Nutzern anzeigen
+keep_pronouns_private.description = Dies verbirgt deine Pronomen von Besuchern, die nicht angemeldet sind.
+quota.sizes.assets.artifacts = Artefakte
+quota.applies_to_user = Die folgenden Quota-Regeln greifen fรผr deinen Account
+quota.sizes.assets.attachments.issues = Issue-Anhรคnge
+quota.rule.exceeded.helper = Die Gesamtgrรถรe der Objekte fรผr diese Regel hat die Quota รผberschritten.
+storage_overview = Speicherรผbersicht
+quota = Kontingent
+quota.sizes.assets.attachments.releases = Release-Anhรคnge
+quota.applies_to_org = Die folgenden Quota-Regeln greifen fรผr diese Organisation
+quota.rule.exceeded = รberschritten
+quota.rule.no_limit = Unbegrenzt
+quota.sizes.all = Alle
+quota.sizes.repos.all = Repositorys
+quota.sizes.repos.public = รffentliche Repositorys
+quota.sizes.repos.private = Private Repositorys
+quota.sizes.git.all = Git-Inhalte
+quota.sizes.git.lfs = Git-LFS
+quota.sizes.assets.all = Assets
+quota.sizes.assets.attachments.all = Anhรคnge
+quota.sizes.assets.packages.all = Pakete
+quota.sizes.wiki = Wiki
+regenerate_token_success = Der Token wurde regeneriert. Anwendungen, die ihn benutzen, haben nicht lรคnger Zugriff auf deinen Account und mรผssen mit dem neuen Token aktualisiert werden.
+access_token_regeneration = Zugangstoken regenerieren
+access_token_regeneration_desc = Einen Token zu regenerieren, wird den Zugriff auf deinen Account von Anwendungen, die ihn nutzen, zurรผckziehen. Dies kann nicht rรผckgรคngig gemacht werden. Fortsetzen?
+regenerate_token = Regenerieren
[repo]
owner=Besitzer
@@ -1016,7 +1100,7 @@ repo_name=Repository-Name
repo_name_helper=Ein guter Repository-Name besteht normalerweise aus kurzen, unvergesslichen und einzigartigen Schlagwรถrtern.
repo_size=Repository-Grรถรe
template=Vorlage
-template_select=Vorlage auswรคhlen.
+template_select=Wรคhle eine Vorlage
template_helper=Repository zu einer Vorlage machen
template_description=Vorlagenrepositorys erlauben es Benutzern, neue Repositorys mit den gleichen Verzeichnisstrukturen, Dateien und optionalen Einstellungen zu erstellen.
visibility=Sichtbarkeit
@@ -1043,17 +1127,17 @@ generate_from=Erstelle aus
repo_desc=Beschreibung
repo_desc_helper=Gib eine kurze Beschreibung an (optional)
repo_lang=Sprache
-repo_gitignore_helper=.gitignore-Vorlagen auswรคhlen.
+repo_gitignore_helper=Wรคhle .gitignore-Vorlagen aus
repo_gitignore_helper_desc=Wรคhle aus einer Liste an Vorlagen fรผr bekannte Sprachen, welche Dateien ignoriert werden sollen. Typische Artefakte, die durch die Build-Tools der gewรคhlten Sprache generiert werden, sind standardmรครig Bestandteil der .gitignore.
-issue_labels=Issue-Labels
-issue_labels_helper=Wรคhle eine Issue-Label-Sammlung.
+issue_labels=Labels
+issue_labels_helper=Wรคhle eine Label-Sammlung
license=Lizenz
-license_helper=Wรคhle eine Lizenz aus.
-license_helper_desc=Eine Lizenz regelt, was andere mit deinem Code tun (oder nicht tun) kรถnnen. Unsicher, welches fรผr dein Projekt die Richtige ist? Siehe Choose a license. .
+license_helper=Wรคhle eine Lizenz
+license_helper_desc=Eine Lizenz regelt, was andere mit deinem Code tun (oder nicht tun) kรถnnen. Unsicher, welche fรผr dein Projekt die richtige ist? Siehe Choose a license .
readme=README
-readme_helper=Wรคhle eine README-Vorlage aus.
+readme_helper=Wรคhle eine README-Vorlage
readme_helper_desc=Hier kannst du eine komplette Beschreibung fรผr dein Projekt schreiben.
-auto_init=Repository initialisieren (Fรผgt .gitignore, License und README-Dateien hinzu)
+auto_init=Repository initialisieren
trust_model_helper=Wรคhle das Vertrauensmodell fรผr die Signaturvalidierung aus. Mรถgliche Modelle sind:
trust_model_helper_collaborator=Mitarbeiter: Vertraue Signaturen von Mitarbeitern am Projekt
trust_model_helper_committer=Committer: Vertraue Signaturen, die mit ihren Committern รผbereinstimmen
@@ -1105,9 +1189,9 @@ tree_path_not_found_commit=Pfad %[1]s existiert nicht in Commit%[2]s
tree_path_not_found_branch=Pfad %[1]s existiert nicht in Branch %[2]s
tree_path_not_found_tag=Pfad %[1]s existiert nicht in Tag %[2]s
-transfer.accept=รbertragung Akzeptieren
+transfer.accept=รbertragung akzeptieren
transfer.accept_desc=รbertragung nach โ%sโ
-transfer.reject=รbertragung Ablehnen
+transfer.reject=รbertragung ablehnen
transfer.reject_desc=รbertragung nachโ%sโ abbrechen
transfer.no_permission_to_accept=Du hast keine Berechtigung, diesen Transfer anzunehmen.
transfer.no_permission_to_reject=Du hast keine Berechtigung, diesen Transfer abzulehnen.
@@ -1126,13 +1210,13 @@ template.webhooks=Webhooks
template.topics=Themen
template.avatar=Profilbild
template.issue_labels=Issue-Labels
-template.one_item=Es muss mindestens eine Vorlage ausgewรคhlt werden
+template.one_item=Es muss mindestens ein Vorlagenelement ausgewรคhlt werden
template.invalid=Es muss ein Vorlagen-Repository ausgewรคhlt werden
-archive.title=Dieses Repository ist archiviert. Du kannst Dateien ansehen und es klonen, kannst aber nicht pushen oder Issues/Pull-Requests รถffnen.
-archive.title_date=Dieses Repository wurde am %s archiviert. Du kannst Dateien ansehen und es klonen, aber nicht pushen oder Issues/Pull-Requests รถffnen.
-archive.issue.nocomment=Dieses Repo ist archiviert. Du kannst Issues nicht kommentieren.
-archive.pull.nocomment=Dieses Repo ist archiviert. Du kannst Pull-Requests nicht kommentieren.
+archive.title=Dieses Repository ist archiviert. Du kannst Dateien ansehen und es klonen, kannst aber du kannst seinen Status nicht verรคndern, zum Beispiel nichts pushen, und keine Issues erรถffnen, oder Pull-Requests oder Kommentare erstellen.
+archive.title_date=Dieses Repository wurde am %s archiviert. Du kannst Dateien ansehen und es klonen, kannst aber seinen Status nicht verรคndern, zum Beispiel nichts pushen, und keine Issues erรถffnen, oder Pull-Requests oder Kommentare erstellen.
+archive.issue.nocomment=Dieses Repository ist archiviert. Du kannst Issues nicht kommentieren.
+archive.pull.nocomment=Dieses Repository ist archiviert. Du kannst Pull-Requests nicht kommentieren.
form.reach_limit_of_creation_1=Du hast bereits dein Limit von %d Repository erreicht.
form.reach_limit_of_creation_n=Du hast bereits dein Limit von %d Repositorys erreicht.
@@ -1157,7 +1241,7 @@ migrate_items_pullrequests=Pull-Requests
migrate_items_merge_requests=Merge-Requests
migrate_items_releases=Releases
migrate_repo=Repository migrieren
-migrate.clone_address=Migrations- / Klon-URL
+migrate.clone_address=Migrations-/Klon-URL
migrate.clone_address_desc=Die HTTP(S)- oder โgit cloneโ-URL eines bereits existierenden Repositorys
migrate.github_token_desc=Du kannst hier ein oder mehrere Token durch Komma getrennt eintippen, um die Migration aufgrund der GitHub-API-Ratenlimitierung zu beschleunigen. WARNUNG: Der Missbrauch dieser Funktion kann gegen die Richtlinien des Diensteanbieters verstoรen und zur Kontosperrung fรผhren.
migrate.clone_local_path=oder ein lokaler Serverpfad
@@ -1170,12 +1254,12 @@ migrate.migrate_items_options=Zugangs-Token wird benรถtigt, um zusรคtzliche Elem
migrated_from=Migriert von %[2]s
migrated_from_fake=Migriert von %[1]s
migrate.migrate=Migrieren von %s
-migrate.migrating=Migriere von %s ...
+migrate.migrating=Migriere von %s โฆ
migrate.migrating_failed=Migrieren von %s fehlgeschlagen.
migrate.migrating_failed.error=Migration fehlgeschlagen: %s
migrate.migrating_failed_no_addr=Migration fehlgeschlagen.
migrate.github.description=Daten von github.com oder GitHub-Enterprise-Server migrieren.
-migrate.git.description=Ein Repository von einem beliebigen Git Service klonen.
+migrate.git.description=Ein Repository von einem beliebigen Git-Dienst klonen.
migrate.gitlab.description=Daten von gitlab.com oder anderen GitLab-Instanzen migrieren.
migrate.gitea.description=Daten von gitea.com oder anderen Gitea-Instanzen migrieren.
migrate.gogs.description=Daten von notabug.org oder anderen Gogs-Instanzen migrieren.
@@ -1237,7 +1321,7 @@ org_labels_desc_manage=verwalten
milestones=Meilensteine
commits=Commits
commit=Commit
-release=Erscheinungsdatum
+release=Release
releases=Releases
tag=Tag
released_this=hat released
@@ -1261,10 +1345,12 @@ ambiguous_character=`%[1]c [U+%04[1]X] kann mit %[2]c [U+%04[2]X] verwechselt we
escape_control_characters=Escapen
unescape_control_characters=Unescapen
file_copy_permalink=Permalink kopieren
-view_git_blame=Git Blame ansehen
+view_git_blame=โgit blameโ ansehen
video_not_supported_in_browser=Dein Browser unterstรผtzt das HTML5-โvideoโ-Tag nicht.
audio_not_supported_in_browser=Dein Browser unterstรผtzt das HTML5-โaudioโ-Tag nicht.
stored_lfs=Gespeichert mit Git LFS
+stored_annex=Gespeichert mit Git Annex
+stored_annex_not_present = hier nicht vorhanden, versuche git annex whereis
symbolic_link=Softlink
executable_file=Ausfรผhrbare Datei
commit_graph=Commit-Graph
@@ -1278,7 +1364,7 @@ commit.load_referencing_branches_and_tags=Lade Branches und Tags, die diesen Com
blame=Blame
download_file=Datei herunterladen
normal_view=Normale Ansicht
-line=zeile
+line=Zeile
lines=Zeilen
from_comment=(Kommentar)
@@ -1288,6 +1374,7 @@ editor.upload_file=Datei hochladen
editor.edit_file=Datei bearbeiten
editor.preview_changes=Vorschau der รnderungen
editor.cannot_edit_lfs_files=LFS-Dateien kรถnnen im Webinterface nicht bearbeitet werden.
+editor.cannot_edit_annex_files=Annex-Dateien kรถnnen im Webinterface nicht bearbeitet werden.
editor.cannot_edit_non_text_files=Binรคrdateien kรถnnen nicht im Webinterface bearbeitet werden.
editor.edit_this_file=Datei bearbeiten
editor.this_file_locked=Datei ist gesperrt
@@ -1302,7 +1389,7 @@ editor.or=oder
editor.cancel_lower=Abbrechen
editor.commit_signed_changes=Committe signierte รnderungen
editor.commit_changes=รnderungen committen
-editor.add_tmpl=โโ hinzufรผgen
+editor.add_tmpl=โ<%s>โ hinzufรผgen
editor.add=%s hinzugefรผgt
editor.update=%s aktualisiert
editor.delete=%s gelรถscht
@@ -1312,7 +1399,7 @@ editor.fail_to_apply_patch=Patch โ%sโ nicht anwendbar
editor.new_patch=Neuer Patch
editor.commit_message_desc=Eine ausfรผhrlichere (optionale) Beschreibung hinzufรผgen โฆ
editor.signoff_desc=Am Ende der Commit-Nachricht einen โSigned-off-byโ-Anhang vom Committer hinzufรผgen.
-editor.commit_directly_to_this_branch=Direkt in den Branch โ%s โ einchecken.
+editor.commit_directly_to_this_branch=Direkt in den Branch โ%[1]s โ einchecken.
editor.create_new_branch=Einen neuen Branch fรผr diesen Commit erstellen und einen Pull-Request starten.
editor.create_new_branch_np=Erstelle einen neuen Branch fรผr diesen Commit.
editor.propose_file_change=Dateiรคnderung vorschlagen
@@ -1328,15 +1415,15 @@ editor.file_is_a_symlink=`โ%sโ ist ein symbolischer Link. Symbolische Links
editor.filename_is_a_directory=Der Dateiname โ%sโ wird bereits als Verzeichnisname in diesem Repository verwendet.
editor.file_editing_no_longer_exists=Die bearbeitete Datei โ%sโ existiert nicht mehr in diesem Repository.
editor.file_deleting_no_longer_exists=Die zu lรถschende Datei โ%sโ existiert nicht mehr in diesem Repository.
-editor.file_changed_while_editing=Der Inhalt der Datei hat sich seit dem Beginn der Bearbeitung geรคndert. Hier klicken , um die รnderungen anzusehen, oder รnderungen erneut comitten , um sie zu รผberschreiben.
+editor.file_changed_while_editing=Der Inhalt der Datei hat sich nach dem รffnen geรคndert. Hier klicken , um die รnderungen anzusehen, oder รnderungen erneut committen , um sie zu รผberschreiben.
editor.file_already_exists=Eine Datei mit dem Namen โ%sโ existiert bereits in diesem Repository.
editor.commit_empty_file_header=Leere Datei committen
editor.commit_empty_file_text=Die Datei, die du commiten willst, ist leer. Fortfahren?
editor.no_changes_to_show=Keine รnderungen vorhanden.
editor.fail_to_update_file=Fehler beim Aktualisieren/Erstellen der Datei โ%sโ.
editor.fail_to_update_file_summary=Fehlermeldung:
-editor.push_rejected_no_message=Die รnderung wurde vom Server ohne Nachricht abgelehnt. Bitte รผberprรผfe die Git Hooks.
-editor.push_rejected=Die รnderung wurde vom Server abgelehnt. Bitte รผberprรผfe die Git Hooks.
+editor.push_rejected_no_message=Die รnderung wurde vom Server ohne Nachricht abgelehnt. Bitte รผberprรผfe die Git-Hooks.
+editor.push_rejected=Die รnderung wurde vom Server abgelehnt. Bitte รผberprรผfe die Git-Hooks.
editor.push_rejected_summary=Vollstรคndige Ablehnungsmeldung:
editor.add_subdir=Verzeichnis erstellen โฆ
editor.unable_to_upload_files=Fehler beim Hochladen der Dateien nach โ%sโ. Fehler: %v
@@ -1366,7 +1453,7 @@ commits.signed_by=Signiert von
commits.signed_by_untrusted_user=Signiert von nicht vertrauenswรผrdigen Benutzern
commits.signed_by_untrusted_user_unmatched=Signiert von nicht vertrauenswรผrdigen Benutzern, der nicht mit dem Committer รผbereinstimmt
commits.gpg_key_id=GPG-Schlรผssel-ID
-commits.ssh_key_fingerprint=SSH-Key-Fingerabdruck
+commits.ssh_key_fingerprint=SSH-Schlรผssel-Fingerabdruck
commits.view_path=An diesem Punkt im Verlauf anzeigen
commit.operations=Operationen
@@ -1382,7 +1469,7 @@ commitstatus.failure=Fehler
commitstatus.pending=Ausstehend
commitstatus.success=Erfolg
-ext_issues=Zugriff auf Externe Issues
+ext_issues=Externe Issues
ext_issues.desc=Link zu externem Issuetracker.
projects=Projekte
@@ -1413,7 +1500,7 @@ projects.column.new_title=Name
projects.column.new_submit=Spalte erstellen
projects.column.new=Neue Spalte
projects.column.set_default=Als Standard verwenden
-projects.column.set_default_desc=Diese Spalte als Standard fรผr nicht kategorisierte Issues und Pull Requests festlegen
+projects.column.set_default_desc=Diese Spalte als Standard fรผr nicht kategorisierte Issues und Pull-Requests festlegen
projects.column.unset_default=Standard entfernen
projects.column.unset_default_desc=Diese Spalte nicht als Standard verwenden
projects.column.delete=Spalte lรถschen
@@ -1483,14 +1570,14 @@ issues.remove_milestone_at=`hat dieses Issue %[2]s vom %[1]s Meilenstein
issues.remove_project_at=`hat dies vom Projekt %s %s entfernt`
issues.deleted_milestone=`(gelรถscht)`
issues.deleted_project=`(gelรถscht)`
-issues.self_assign_at=`hat sich das Issue %s selbst zugewiesen`
+issues.self_assign_at=`hat sich %s selbst zugewiesen`
issues.add_assignee_at=`wurde von %s %s zugewiesen`
issues.remove_assignee_at=`wurde von %s von der Zuweisung %s befreit`
issues.remove_self_assignment=`hat die Selbstzuweisung %s entfernt`
issues.change_title_at=`hat den Titel von %s zu %s %s geรคndert`
issues.change_ref_at=`hat die Referenz von %s zu %s %s geรคndert`
-issues.remove_ref_at=`hat die Referenz %s entfernt %s`
-issues.add_ref_at=`hat die Referenz %s hinzugefรผgt %s`
+issues.remove_ref_at=`hat die Referenz %s %s entfernt`
+issues.add_ref_at=`hat die Referenz %s %s hinzugefรผgt`
issues.delete_branch_at=`lรถschte den Branch %s %s`
issues.filter_label=Label
issues.filter_label_exclude=`Alt
+ Klick/Enter
verwenden, um Labels auszuschlieรen`
@@ -1563,17 +1650,17 @@ issues.no_content=Keine Beschreibung angegeben.
issues.close=Issue schlieรen
issues.comment_pull_merged_at=hat Commit %[1]s in %[2]s %[3]s zusammengefรผhrt
issues.comment_manually_pull_merged_at=hat Commit %[1]s in %[2]s %[3]s manuell zusammengefรผhrt
-issues.close_comment_issue=Kommentieren und schlieรen
+issues.close_comment_issue=Mit Kommentar schlieรen
issues.reopen_issue=Wieder รถffnen
-issues.reopen_comment_issue=Kommentieren und wieder รถffnen
+issues.reopen_comment_issue=Mit Kommentar wieder รถffnen
issues.create_comment=Kommentieren
issues.closed_at=`hat diesen Issue %[2]s geschlossen`
issues.reopened_at=`hat dieses Issue %[2]s wieder geรถffnet`
issues.commit_ref_at=`hat dieses Issue %[2]s aus einem Commit referenziert`
issues.ref_issue_from=`hat %[2]s auf dieses Issue verwiesen %[4]s `
issues.ref_pull_from=`hat %[2]s auf diesen Pull-Request verwiesen %[4]s `
-issues.ref_closing_from=`hat %[2]s auf einen Pull-Request %[4]s verwiesen, welcher das Issue schlieรen wird `
-issues.ref_reopening_from=`hat auf einen Pull-Request %[4]s verwiesen, welcher das Issue %[2]s erneut รถffnen wird`
+issues.ref_closing_from=`hat %[2]s in einem Pull-Request %[4]s auf dieses Issue verwiesen, welcher es schlieรen wird `
+issues.ref_reopening_from=`hat %[2]s in einem Pull-Request %[4]s auf dieses Issue verwiesen, welcher es erneut รถffnen wird `
issues.ref_closed_from=`hat dieses Issue %[4]s geschlossen %[2]s `
issues.ref_reopened_from=`hat dieses Issue %[4]s %[2]s wieder geรถffnet`
issues.ref_from=`von %[1]s`
@@ -1609,7 +1696,7 @@ issues.label_archive_tooltip=Archivierte Labels werden bei der Suche nach Labels
issues.label_exclusive_desc=Nenn das Label Bereich/Element
, um es gegenseitig ausschlieรend mit anderen Bereich/
-Labels zu machen.
issues.label_exclusive_warning=Alle im Konflikt stehenden Labels werden beim Bearbeiten der Labels eines Issues oder eines Pull-Requests entfernt.
issues.label_count=%d Labels
-issues.label_open_issues=%d offene Issues
+issues.label_open_issues=%d offene Issues/Pull-Requests
issues.label_edit=Bearbeiten
issues.label_delete=Lรถschen
issues.label_modify=Label bearbeiten
@@ -1640,7 +1727,7 @@ issues.unlock_comment=hat diese Diskussion %s entsperrt
issues.lock_confirm=Sperren
issues.unlock_confirm=Entsperren
issues.lock.notice_1=- Andere Nutzer kรถnnen keine neuen Kommentare beisteuern.
-issues.lock.notice_2=- Du und andere Mitarbeiter mit Zugriff auf dieses Repository kรถnnen weiterhin fรผr andere sichtbare Kommentare hinterlassen.
+issues.lock.notice_2=โ Du und andere Mitarbeiter mit Zugriff auf dieses Repository kรถnnen weiterhin fรผr andere sichtbare Kommentare hinterlassen.
issues.lock.notice_3=- Du kannst die Diskussion jederzeit wieder entsperren.
issues.unlock.notice_1=- Jeder wird wieder in der Lage sein, zu diesem Issue zu kommentieren.
issues.unlock.notice_2=- Du kannst den Issue jederzeit wieder sperren.
@@ -1678,7 +1765,7 @@ issues.error_modifying_due_date=Fehler beim รndern des Fรคlligkeitsdatums.
issues.error_removing_due_date=Fehler beim Entfernen des Fรคlligkeitsdatums.
issues.push_commit_1=hat %d Commit %s hinzugefรผgt
issues.push_commits_n=hat %d Commits %s hinzugefรผgt
-issues.force_push_codes=`hat %[6]s %[1]s von %[2]s
zu %[4]s
force-gepusht`
+issues.force_push_codes=`hat %[6]s %[1]s von %[2]s
zu %[4]s
force-gepusht`
issues.force_push_compare=Vergleichen
issues.due_date_form=JJJJ-MM-TT
issues.due_date_form_add=Fรคlligkeitsdatum hinzufรผgen
@@ -1732,8 +1819,8 @@ issues.review.left_comment=hat einen Kommentar hinterlassen
issues.review.content.empty=Du musst einen Kommentar hinterlassen, der die gewรผnschte(n) รnderung(en) beschreibt.
issues.review.reject=hat %s รnderungen angefragt
issues.review.wait=wurde fรผr ein Review %s angefragt
-issues.review.add_review_request=hat ein Review von %s %s angefragt
-issues.review.remove_review_request=hat die Aufforderung zum Review an %s %s entfernt
+issues.review.add_review_request=hat ein Review von %[1]s %[2]s angefragt
+issues.review.remove_review_request=hat die Aufforderung zum Review an %[1]s %[2]s entfernt
issues.review.remove_review_request_self=hat das Review verweigert %s
issues.review.pending=Ausstehend
issues.review.pending.tooltip=Dieser Kommentar ist derzeit nicht fรผr andere Benutzer sichtbar. Um deine ausstehenden Kommentare einzureichen, wรคhle โ%sโ -> โ%s/%s/%sโ oben auf der Seite.
@@ -1793,7 +1880,7 @@ pulls.nothing_to_compare=Diese Branches sind identisch. Es muss kein Pull-Reques
pulls.nothing_to_compare_and_allow_empty_pr=Diese Branches sind gleich. Der Pull-Request wird leer sein.
pulls.has_pull_request=`Es existiert bereits ein Pull-Request zwischen diesen beiden Branches: %[2]s#%[3]d `
pulls.create=Pull-Request erstellen
-pulls.title_desc_few=mรถchte %[1]d Commits von %[2]s
nach %[3]s
zusammenfรผhren
+pulls.title_desc_few=mรถchte %[1]d Commits von %[2]s
nach %[3]s
zusammenfรผhren
pulls.merged_title_desc_few=hat %[1]d Commits von %[2]s
nach %[3]s
%[4]s zusammengefรผhrt
pulls.change_target_branch_at=`hat den Zielbranch von %s nach %s %s geรคndert`
pulls.tab_conversation=Diskussion
@@ -1813,7 +1900,7 @@ pulls.still_in_progress=Noch in Bearbeitung?
pulls.add_prefix=Prรคfix โ%s โ hinzufรผgen
pulls.remove_prefix=Prรคfix โ%s โ entfernen
pulls.data_broken=Dieser Pull-Requests ist kaputt, da Fork-Informationen gelรถscht wurden.
-pulls.files_conflicted=Dieser Pull-Request hat รnderungen, die im Widerspruch zum Ziel-Branch stehen.
+pulls.files_conflicted=Dieser Pull-Request hat รnderungen, die Konflikte mit dem Ziel-Branch haben.
pulls.is_checking=Die Merge-Konfliktprรผfung lรคuft noch. Bitte aktualisiere die Seite in wenigen Augenblicken.
pulls.is_ancestor=Dieser Branch ist bereits im Zielbranch enthalten. Es existiert nichts zusammenzufรผhren.
pulls.is_empty=Die รnderungen an diesem Branch sind bereits auf dem Zielbranch. Dies wird ein leerer Commit sein.
@@ -1932,7 +2019,7 @@ milestones.filter_sort.most_complete=Vollstรคndigste
milestones.filter_sort.most_issues=Meiste Issues
milestones.filter_sort.least_issues=Wenigste Issues
-signing.will_sign=Dieser Commit wird mit dem Key โ%sโ signiert werden.
+signing.will_sign=Dieser Commit wird mit dem Schlรผssel โ%sโ signiert werden.
signing.wont_sign.error=Es gab einen Fehler bei der Prรผfung, ob der Commit signiert werden kann.
signing.wont_sign.nokey=Diese Instanz hat keinen Schlรผssel, um diesen Commit zu signieren.
signing.wont_sign.never=Commits werden nie signiert.
@@ -1946,7 +2033,7 @@ signing.wont_sign.commitssigned=Der Merge-Commit wird nicht signiert werden, da
signing.wont_sign.approved=Der Merge-Commit wird nicht signiert werden, da der Pull-Request nicht genehmigt wurde.
signing.wont_sign.not_signed_in=Du bist nicht eingeloggt.
-ext_wiki=Zugriff auf externes Wiki
+ext_wiki=Externes Wiki
ext_wiki.desc=Verweis auf externes Wiki.
wiki=Wiki
@@ -2019,7 +2106,7 @@ activity.unresolved_conv_label=Offen
activity.title.releases_1=%d Release
activity.title.releases_n=%d Releases
activity.title.releases_published_by=%s von %s verรถffentlicht
-activity.published_release_label=Verรถffentlicht
+activity.published_release_label=Release
activity.no_git_activity=In diesem Zeitraum hat es keine Commit-Aktivitรคt gegeben.
activity.git_stats_exclude_merges=Von Merges abgesehen, gilt:
activity.git_stats_author_1=%d Autor
@@ -2042,8 +2129,7 @@ activity.git_stats_and_deletions=und
activity.git_stats_deletion_1=%d Lรถschung
activity.git_stats_deletion_n=%d Lรถschungen
-contributors.contribution_type.commits=Commits
-
+contributors.contribution_type.commits = Commits
search=Suchen
search.search_repo=Repository durchsuchen
search.type.tooltip=Suchmodus
@@ -2130,7 +2216,7 @@ settings.pulls.allow_rebase_update=Update von Pull-Request-Branches per Rebase e
settings.pulls.default_delete_branch_after_merge=Standardmรครig bei Pull-Requests den Branch nach dem Zusammenfรผhren lรถschen
settings.pulls.default_allow_edits_from_maintainers=รnderungen von Maintainern standardmรครig erlauben
settings.releases_desc=Repository-Releases aktivieren
-settings.packages_desc=Repository Packages Registry aktivieren
+settings.packages_desc=Repository-Paket-Registry aktivieren
settings.projects_desc=Repository-Projekte aktivieren
settings.actions_desc=Aktiviere integrierte CI/CD-Pipelines mit Forgejo-Actions
settings.admin_settings=Administratoreinstellungen
@@ -2270,39 +2356,39 @@ settings.event_push_desc=Git push in ein Repository.
settings.event_repository=Repository
settings.event_repository_desc=Repository erstellt oder gelรถscht.
settings.event_header_issue=Issue-Ereignisse
-settings.event_issues=Issues
+settings.event_issues=รnderung
settings.event_issues_desc=Issue geรถffnet, geschlossen, wieder geรถffnet oder bearbeitet.
-settings.event_issue_assign=Issue zugewiesen
+settings.event_issue_assign=Zuweisung
settings.event_issue_assign_desc=Issue zugewiesen oder Zuweisung entfernt.
-settings.event_issue_label=Issue mit Label versehen
-settings.event_issue_label_desc=Issue-Labels aktualisiert oder geleert.
-settings.event_issue_milestone=Meilenstein einem Issue zugewiesen
-settings.event_issue_milestone_desc=Meilenstein zu Issue hinzugefรผgt oder entfernt.
-settings.event_issue_comment=Issue-Kommentar
+settings.event_issue_label=Labels
+settings.event_issue_label_desc=Issue-Labels hinzugefรผgt oder entfernt.
+settings.event_issue_milestone=Meilensteine
+settings.event_issue_milestone_desc=Meilenstein hinzugefรผgt, entfernt oder verรคndert.
+settings.event_issue_comment=Kommentare
settings.event_issue_comment_desc=Issue-Kommentar angelegt, geรคndert oder gelรถscht.
settings.event_header_pull_request=Pull-Request-Ereignisse
-settings.event_pull_request=Pull-Request
+settings.event_pull_request=รnderung
settings.event_pull_request_desc=Pull-Request geรถffnet, geschlossen, wieder geรถffnet oder bearbeitet.
-settings.event_pull_request_assign=Pull-Request zugewiesen
+settings.event_pull_request_assign=Zuweisung
settings.event_pull_request_assign_desc=Pull-Request zugewiesen oder Zuweisung entfernt.
-settings.event_pull_request_label=Pull-Request mit Label versehen
-settings.event_pull_request_label_desc=Pull-Request-Labels aktualisiert oder geleert.
-settings.event_pull_request_milestone=Pull-Request zum Meilenstein hinzugefรผgt
-settings.event_pull_request_milestone_desc=Pull-Request zum Meilenstein hinzugefรผgt oder entfernt.
-settings.event_pull_request_comment=Pull-Request-Kommentar
+settings.event_pull_request_label=Labels
+settings.event_pull_request_label_desc=Pull-Request-Labels hinzugefรผgt oder entfernt.
+settings.event_pull_request_milestone=Meilensteine
+settings.event_pull_request_milestone_desc=Meilenstein hinzugefรผgt, entfernt oder bearbeitet.
+settings.event_pull_request_comment=Kommentare
settings.event_pull_request_comment_desc=Pull-Request-Kommentar angelegt, geรคndert oder gelรถscht.
-settings.event_pull_request_review=Pull-Request รผberprรผft
-settings.event_pull_request_review_desc=Pull-Request genehmigt, abgelehnt oder Kommentar hinterlassen.
-settings.event_pull_request_sync=Pull-Request synchronisiert
-settings.event_pull_request_sync_desc=Pull-Request synchronisiert.
-settings.event_pull_request_review_request=รberprรผfung des Pull-Requests angefragt
+settings.event_pull_request_review=Reviews
+settings.event_pull_request_review_desc=Pull-Request genehmigt, abgelehnt oder Review-Kommentare hinterlassen.
+settings.event_pull_request_sync=Synchronisiert
+settings.event_pull_request_sync_desc=Branch automatisch mit Zielbranch aktualisiert.
+settings.event_pull_request_review_request=Review-Anfragen
settings.event_pull_request_review_request_desc=รberprรผfung des Pull-Requests angefragt oder die Anfrage entfernt.
settings.event_pull_request_approvals=Genehmigungen zum Pull-Request
settings.event_pull_request_merge=Pull-Request-Merge
settings.event_package=Paket
settings.event_package_desc=Paket wurde in einem Repository erstellt oder gelรถscht.
settings.branch_filter=Branch-Filter
-settings.branch_filter_desc=Positivliste fรผr Branches fรผr Push-, Erzeugungs- und Lรถschevents, als glob-Pattern beschrieben. Es werden Events fรผr alle Branches gemeldet, falls das Pattern *
ist, oder falls es leer ist. Siehe die github.com/gobwas/glob -Dokumentation fรผr die Syntax (Englisch). Beispiele: master
, {master,release*}
.
+settings.branch_filter_desc=Positivliste fรผr Branches fรผr Push-, Erzeugungs- und Lรถschevents, als glob-Pattern beschrieben. Es werden Events fรผr alle Branches gemeldet, falls das Pattern *
ist, oder falls es leer ist. Siehe die %[2]s -Dokumentation fรผr die Syntax (Englisch). Beispiele: master
, {master,release*}
.
settings.authorization_header=Authorization-Header
settings.authorization_header_desc=Wird, falls vorhanden, als Authorization-Header mitgesendet. Beispiele: %s.
settings.active=Aktiv
@@ -2367,38 +2453,38 @@ settings.protect_enable_merge_desc=Jeder mit Schreibzugriff darf die Pull-Reques
settings.protect_whitelist_committers=Positivlisten-eingeschrรคnkter Push
settings.protect_whitelist_committers_desc=Jeder, der auf der Whitelist steht, darf in diesen Branch pushen (aber kein Force-Push).
settings.protect_whitelist_deploy_keys=Deploy-Key mit Schreibzugriff zum Pushen whitelisten.
-settings.protect_whitelist_users=Nutzer, die pushen dรผrfen:
+settings.protect_whitelist_users=Nutzer, die pushen dรผrfen
settings.protect_whitelist_search_users=Benutzer suchen โฆ
-settings.protect_whitelist_teams=Teams, die pushen dรผrfen:
+settings.protect_whitelist_teams=Teams, die pushen dรผrfen
settings.protect_whitelist_search_teams=Teams suchen โฆ
-settings.protect_merge_whitelist_committers=Merge-Whitelist aktivieren
-settings.protect_merge_whitelist_committers_desc=Erlaube Nutzern oder Teams auf der Whitelist, Pull-Requests in diesen Branch zusammenzufรผhren.
-settings.protect_merge_whitelist_users=Nutzer, die zusammenfรผhren dรผrfen:
-settings.protect_merge_whitelist_teams=Teams, die zusammenfรผhren dรผrfen:
+settings.protect_merge_whitelist_committers=Merge-Positivliste aktivieren
+settings.protect_merge_whitelist_committers_desc=Erlaube Nutzern oder Teams auf der Positivliste, Pull-Requests in diesen Branch zusammenzufรผhren.
+settings.protect_merge_whitelist_users=Nutzer, die zusammenfรผhren dรผrfen
+settings.protect_merge_whitelist_teams=Teams, die zusammenfรผhren dรผrfen
settings.protect_check_status_contexts=Statusprรผfung aktivieren
-settings.protect_status_check_patterns=Statuscheck-Muster:
+settings.protect_status_check_patterns=Statuscheck-Muster
settings.protect_status_check_patterns_desc=Gib Muster ein, um festzulegen, welche Statusรผberprรผfungen durchgefรผhrt werden mรผssen, bevor Branches in einen Branch, der dieser Regel entspricht, zusammenfรผhren werden kรถnnen. Jede Zeile gibt ein Muster an. Muster dรผrfen nicht leer sein.
settings.protect_check_status_contexts_desc=Vor dem Zusammenfรผhren mรผssen Statusprรผfungen bestanden werden. Wรคhle aus, welche Statusprรผfungen erfolgreich durchgefรผhrt werden mรผssen, bevor Branches in einen anderen zusammengefรผhrt werden kรถnnen, der dieser Regel entspricht. Wenn aktiviert, mรผssen Commits zuerst auf einen anderen Branch gepusht werden, dann nach bestandener Statusprรผfung gemergt oder direkt auf einen Branch gepusht werden, der dieser Regel entspricht. Wenn kein Kontext ausgewรคhlt ist, muss der letzte Commit unabhรคngig vom Kontext erfolgreich sein.
settings.protect_check_status_contexts_list=Statusprรผfungen, die in der letzten Woche fรผr dieses Repository gefunden wurden
settings.protect_status_check_matched=รbereinstimmung
settings.protect_invalid_status_check_pattern=Ungรผltiges Statusprรผfungspattern: โ%sโ.
settings.protect_no_valid_status_check_patterns=Keine gรผltigen Statuscheck-Muster.
-settings.protect_required_approvals=Erforderliche Genehmigungen:
+settings.protect_required_approvals=Erforderliche Genehmigungen
settings.protect_required_approvals_desc=Erlaube das Zusammenfรผhren des Pull-Requests nur mit genรผgend positiven Reviews.
-settings.protect_approvals_whitelist_enabled=Genehmigungen auf Benutzer oder Teams auf der Whitelist beschrรคnken
-settings.protect_approvals_whitelist_enabled_desc=Nur Reviews von Benutzern auf der Whitelist oder Teams zรคhlen zu den erforderlichen Genehmigungen. Existiert keine Whitelist, so zรคhlen Reviews von jedem mit Schreibzugriff zu den erforderlichen Genehmigungen.
-settings.protect_approvals_whitelist_users=Reviewer auf der Whitelist:
-settings.protect_approvals_whitelist_teams=Fรผr Reviews gewhitelistete Teams:
+settings.protect_approvals_whitelist_enabled=Genehmigungen auf Benutzer oder Teams auf der Positivliste beschrรคnken
+settings.protect_approvals_whitelist_enabled_desc=Nur Reviews von Benutzern oder Teams auf der Positivliste zรคhlen zu den erforderlichen Genehmigungen. Existiert keine Positivliste, so zรคhlen Reviews von jedem mit Schreibzugriff zu den erforderlichen Genehmigungen.
+settings.protect_approvals_whitelist_users=Nutzer, die reviewen dรผrfen
+settings.protect_approvals_whitelist_teams=Teams, die reviewen dรผrfen
settings.dismiss_stale_approvals=Entferne alte Genehmigungen
settings.dismiss_stale_approvals_desc=Wenn neue Commits gepusht werden, die den Inhalt des Pull-Requests รคndern, werden alte Genehmigungen entfernt.
settings.require_signed_commits=Signierte Commits erforderlich
settings.require_signed_commits_desc=Pushes auf diesen Branch ablehnen, wenn Commits nicht signiert oder nicht รผberprรผfbar sind.
settings.protect_branch_name_pattern=Muster fรผr geschรผtzte Branchnamen
settings.protect_patterns=Muster
-settings.protect_protected_file_patterns=Geschรผtzte Dateimuster (durch Semikolon โ;โ getrennt):
-settings.protect_protected_file_patterns_desc=Geschรผtzte Dateien dรผrfen nicht direkt geรคndert werden, auch wenn der Benutzer Rechte hat, Dateien in diesem Branch hinzuzufรผgen, zu bearbeiten oder zu lรถschen. Mehrere Muster kรถnnen mit Semikolon (โ;โ) getrennt werden. Siehe github.com/gobwas/glob Dokumentation zur Mustersyntax. Beispiele: .drone.yml
, /docs/**/*.txt
.
-settings.protect_unprotected_file_patterns=Ungeschรผtzte Dateimuster (durch Semikolon โ;โ getrennt):
-settings.protect_unprotected_file_patterns_desc=Ungeschรผtzte Dateien, die direkt geรคndert werden dรผrfen, wenn der Benutzer Schreibzugriff hat, kรถnnen die Push-Beschrรคnkung umgehen. Mehrere Muster kรถnnen mit Semikolon (โ;โ) getrennt werden. Siehe github.com/gobwas/glob Dokumentation zur Mustersyntax. Beispiele: .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns=Geschรผtzte Dateimuster (durch Semikolon โ;โ getrennt)
+settings.protect_protected_file_patterns_desc=Geschรผtzte Dateien dรผrfen nicht direkt geรคndert werden, auch wenn der Benutzer Rechte hat, Dateien in diesem Branch hinzuzufรผgen, zu bearbeiten oder zu lรถschen. Mehrere Muster kรถnnen mit Semikolon (โ;โ) getrennt werden. Siehe %s Dokumentation zur Mustersyntax. Beispiele: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns=Ungeschรผtzte Dateimuster (durch Semikolon โ;โ getrennt)
+settings.protect_unprotected_file_patterns_desc=Ungeschรผtzte Dateien, die direkt geรคndert werden dรผrfen, wenn der Benutzer Schreibzugriff hat, kรถnnen die Push-Beschrรคnkung umgehen. Mehrere Muster kรถnnen mit Semikolon (โ;โ) getrennt werden. Siehe %[2]s Dokumentation zur Mustersyntax. Beispiele: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=Schutz aktivieren
settings.delete_protected_branch=Schutz deaktivieren
settings.update_protect_branch_success=Branchschutzregel โ%sโ wurde aktualisiert.
@@ -2430,7 +2516,7 @@ settings.tags.protection.allowed.teams=Erlaubte Teams
settings.tags.protection.allowed.noone=Niemand
settings.tags.protection.create=Regel hinzufรผgen
settings.tags.protection.none=Es gibt keine geschรผtzten Tags.
-settings.tags.protection.pattern.description=Du kannst einen einzigen Namen oder ein globales Schema oder einen regulรคren Ausdruck verwenden, um mehrere Tags zu schรผtzen. Mehr dazu im Guide fรผr geschรผtzte Tags (Englisch) .
+settings.tags.protection.pattern.description=Du kannst einen einzigen Namen oder ein globales Schema oder einen regulรคren Ausdruck verwenden, um mehrere Tags zu schรผtzen. Mehr dazu im Guide fรผr geschรผtzte Tags (Englisch) .
settings.bot_token=Bot-Token
settings.chat_id=Chat-ID
settings.thread_id=Thread-ID
@@ -2443,8 +2529,8 @@ settings.archive.text=Durch das Archivieren wird ein Repo vollstรคndig schreibge
settings.archive.success=Das Repo wurde erfolgreich archiviert.
settings.archive.error=Beim Versuch, das Repository zu archivieren, ist ein Fehler aufgetreten. Weitere Details finden sich im Log.
settings.archive.error_ismirror=Du kannst kein gespiegeltes Repo archivieren.
-settings.archive.branchsettings_unavailable=Branch-Einstellungen sind nicht verfรผgbar wenn das Repo archiviert ist.
-settings.archive.tagsettings_unavailable=Tag Einstellungen sind nicht verfรผgbar, wenn das Repo archiviert wurde.
+settings.archive.branchsettings_unavailable=Branch-Einstellungen sind nicht verfรผgbar in archivierten Repos.
+settings.archive.tagsettings_unavailable=Tag-Einstellungen sind nicht verfรผgbar in archivierten Repos.
settings.unarchive.button=Archivierung zurรผcksetzen
settings.unarchive.header=Archivierung dieses Repositorys zurรผcksetzen
settings.unarchive.text=Durch das Aufheben der Archivierung kann das Repo wieder Commits und Pushes sowie neue Issues und Pull-Requests empfangen.
@@ -2465,7 +2551,7 @@ settings.lfs_invalid_locking_path=Ungรผltiger Pfad: %s
settings.lfs_invalid_lock_directory=Verzeichnis kann nicht gesperrt werden: %s
settings.lfs_lock_already_exists=Sperre existiert bereits: %s
settings.lfs_lock=Sperren
-settings.lfs_lock_path=Zu sperrender Dateipfad...
+settings.lfs_lock_path=Zu sperrender Dateipfad โฆ
settings.lfs_locks_no_locks=Keine Sperren
settings.lfs_lock_file_no_exist=Gesperrte Datei existiert nicht im Standard-Branch
settings.lfs_force_unlock=Freigabe erzwingen
@@ -2549,7 +2635,7 @@ release.draft=Entwurf
release.prerelease=Pre-Release
release.stable=Stabil
release.compare=Vergleichen
-release.edit=bearbeiten
+release.edit=Bearbeiten
release.ahead.commits=%d Commits
release.ahead.target=zu %s seit dieser Version
tag.ahead.target=auf %s seit diesem Tag
@@ -2597,7 +2683,7 @@ branch.delete_desc=Das Lรถschen eines Branches ist permanent. Obwohl der Branch
branch.deletion_success=Branch โ%sโ wurde gelรถscht.
branch.deletion_failed=Branch โ%sโ konnte nicht gelรถscht werden.
branch.delete_branch_has_new_commits=Der Branch โ%sโ kann nicht gelรถscht werden, da seit dem letzten Merge neue Commits hinzugefรผgt wurden.
-branch.create_branch=Erstelle Branch %s
+branch.create_branch=Erstelle Branch %s
branch.create_from=`von โ%sโ`
branch.create_success=Branch โ%sโ wurde erstellt.
branch.branch_already_exists=Branch โ%sโ existiert bereits in diesem Repository.
@@ -2624,7 +2710,7 @@ branch.new_branch=Neue Branch erstellen
branch.new_branch_from=Neuen Branch von โ%sโ erstellen
branch.renamed=Branch %s wurde in %s umbenannt.
-tag.create_tag=Tag %s erstellen
+tag.create_tag=Tag %s erstellen
tag.create_tag_operation=Tag erstellen
tag.confirm_create_tag=Tag erstellen
tag.create_tag_from=Neuen Tag von โ%sโ erstellen
@@ -2643,10 +2729,10 @@ error.csv.too_large=Diese Datei kann nicht gerendert werden, da sie zu groร ist
error.csv.unexpected=Diese Datei kann nicht gerendert werden, da sie ein unerwartetes Zeichen in Zeile %d und Spalte %d enthรคlt.
error.csv.invalid_field_count=Diese Datei kann nicht gerendert werden, da sie eine falsche Anzahl an Feldern in Zeile %d hat.
rss.must_be_on_branch = Du musst auf einem Branch sein, um einen RSS-Feed zu haben.
-new_repo_helper = Ein Repository enthรคlt alle Projektdateien inklusive der Revisionshistorie. Bereits woanders gehostet? Repository migrieren.
-issues.comment.blocked_by_user = Du kannst kein Kommentar fรผr dieses Issue erstellen, weil du vom Repository-Besitzer oder dem Autoren des Issues blockiert wurdest.
+new_repo_helper = Ein Repository enthรคlt alle Projektdateien inklusive der Revisionshistorie. Bereits woanders gehostet? Repository migrieren .
+issues.comment.blocked_by_user = Du kannst dieses Issue nicht kommentieren, weil du vom Repository-Besitzer oder dem Autoren des Issues blockiert wurdest.
clone_in_vscodium = In VSCodium klonen
-settings.units.add_more = Mehr hinzufรผgen โฆ
+settings.units.add_more = Mehr aktivieren
settings.wiki_rename_branch_main_desc = Den Branch, der intern vom Wiki benutzt wird, zu โ%sโ umbenennen. Dies ist permanent und kann nicht rรผckgรคngig gemacht werden.
desc.sha256 = SHA256
object_format_helper = Objektformat des Repositorys. Kann spรคter nicht geรคndert werden. SHA1 ist am kompatibelsten.
@@ -2657,10 +2743,10 @@ settings.add_collaborator_blocked_them = Der Mitarbeiter konnte nicht hinzugefรผ
settings.wiki_rename_branch_main = Den Wiki-Branch-Namen normalisieren
settings.enter_repo_name = Gib den Besitzer- und den Repository-Namen genau wie angezeigt ein:
settings.wiki_branch_rename_success = Der Branch-Name des Repository-Wikis wurde erfolgreich normalisiert.
-settings.archive.mirrors_unavailable = Spiegel sind nicht verfรผgbar, wenn das Repo archiviert ist.
+settings.archive.mirrors_unavailable = Spiegel sind nicht verfรผgbar in archivierten Repos.
pulls.blocked_by_user = Du kannst keinen Pull-Request in diesem Repository erstellen, weil du vom Repository-Besitzer blockiert wurdest.
settings.add_collaborator_blocked_our = Der Mitarbeiter konnte nicht hinzugefรผgt werden, weil der Repository-Besitzer ihn blockiert hat.
-issues.blocked_by_user = Du kannst kein Issue in diesem Repository erstellen, weil du vom Repository-Besitzer blockiert wurdest.
+issues.blocked_by_user = Du kannst keine Issues in diesem Repository erstellen, weil du vom Repository-Besitzer blockiert wurdest.
admin.manage_flags = Flags verwalten
admin.enabled_flags = Vom Repository aktivierte Flags:
admin.update_flags = Flags aktualisieren
@@ -2677,11 +2763,11 @@ commits.browse_further = Weiter browsen
pulls.nothing_to_compare_have_tag = Der gewรคhlte Branch/Tag ist gleich.
pulls.status_checks_hide_all = Alle Prรผfungen verbergen
pulls.status_checks_show_all = Alle Prรผfungen anzeigen
-pulls.cmd_instruction_hint = `Anweisungen fรผr die Kommandozeile betrachten.`
+pulls.cmd_instruction_hint = Anweisungen fรผr die Kommandozeile betrachten
pulls.cmd_instruction_checkout_title = Auschecken
wiki.cancel = Abbrechen
settings.wiki_globally_editable = Allen erlauben, das Wiki zu bearbeiten
-settings.protect_branch_name_pattern_desc = Geschรผtzte Branch-Namens-Patterns. Siehe die Dokumentation fรผr Pattern-Syntax. Beispiele: main, release/**
+settings.protect_branch_name_pattern_desc = Geschรผtzte Branch-Namens-Patterns. Siehe die Dokumentation fรผr Pattern-Syntax. Beispiele: main, release/**
settings.ignore_stale_approvals = Abgestandene Genehmigungen ignorieren
settings.ignore_stale_approvals_desc = Genehmigungen, welche fรผr รคltere Commits gemacht wurden (abgestandene Reviews), nicht in die Gesamtzahl der Genehmigung des PRs mitzรคhlen. Irrelevant, falls abgestandene Reviews bereits verworfen werden.
pulls.commit_ref_at = `hat sich auf diesen Pull-Request von einem Commit %[2]s bezogen`
@@ -2689,14 +2775,13 @@ pulls.fast_forward_only_merge_pull_request = Nur Fast-forward
pulls.cmd_instruction_checkout_desc = Checke einen neuen Branch aus deinem Projekt-Repository aus und teste die รnderungen.
pulls.cmd_instruction_merge_title = Zusammenfรผhren
pulls.cmd_instruction_merge_desc = Die รnderungen zusammenfรผhren und auf Forgejo aktualisieren.
-settings.units.units = Repository-Einheiten
+settings.units.units = Einheiten
settings.units.overview = รbersicht
settings.wiki_rename_branch_main_notices_1 = Diese Aktion KANN NICHT rรผckgรคngig gemacht werden.
settings.wiki_rename_branch_main_notices_2 = Dies wird den internen Branch des Repository-Wikis von %s permanent umbenennen. Existierende Checkouts mรผssen aktualisiert werden.
settings.wiki_branch_rename_failure = Der Branch-Name des Repository-Wiki konnte nicht normalisiert werden.
settings.confirm_wiki_branch_rename = Den Wiki-Branch umbenenennen
activity.navbar.contributors = Mitwirkende
-contributors.contribution_type.commits = Commits
contributors.contribution_type.deletions = Lรถschungen
contributors.contribution_type.additions = Einfรผgungen
contributors.contribution_type.filter_label = Art des Beitrags:
@@ -2706,11 +2791,11 @@ pulls.made_using_agit = AGit
settings.confirmation_string = Bestรคtigungsstring
pulls.agit_explanation = Mittels AGit-Workflow erstellt. AGit erlaubt Mitwirkenden, รnderungen mittels โgit pushโ vorzuschlagen, ohne einen Fork oder neuen Branch zu erstellen.
activity.navbar.recent_commits = Neueste Commits
-activity.navbar.code_frequency = Code-Frequenz
+activity.navbar.code_frequency = Code-Hรคufigkeit
file_follow = Symlink folgen
error.broken_git_hook = Die Git-Hooks des Repositorys scheinen kaputt zu sein. Bitte folge der Dokumentation um sie zu reparieren, dann pushe einige Commits um den Status zu aktualisieren.
pulls.merged_title_desc_one = hat %[1]d Commit von %[2]s
nach %[3]s
%[4]s zusammengefรผhrt
-pulls.title_desc_one = mรถchte %[1]d Commit von %[2]s
nach %[3]s
zusammenfรผhren
+pulls.title_desc_one = mรถchte %[1]d Commit von %[2]s
nach %[3]s
zusammenfรผhren
open_with_editor = รffnen mit %s
commits.search_branch = Dieser Branch
pulls.ready_for_review = Bereit zum Review?
@@ -2742,7 +2827,7 @@ settings.sourcehut_builds.secrets_helper = Dem Job zugriff auf die Build-Geheimn
settings.web_hook_name_sourcehut_builds = SourceHut-Builds
settings.graphql_url = GraphQL-URL
settings.matrix.room_id_helper = Die Raum-ID kann รผber den Element-Webclient ermittelt werden: Raumeinstellungen > Erweitert > Interne Raum-ID. Beispielsweise %s.
-settings.sourcehut_builds.access_token_helper = Zugangstoken der die JOBS:RW-Freigabe hat. Generiere auf meta.sr.ht einen builds.sr.ht-Token oder einen builds.sr.ht-Token mit Zugriff auf die Secrets .
+settings.sourcehut_builds.access_token_helper = Zugangstoken, der die JOBS:RW-Freigabe hat. Generiere auf meta.sr.ht einen builds.sr.ht-Token oder einen builds.sr.ht-Token mit Zugriff auf die Secrets .
settings.matrix.access_token_helper = Es wird empfohlen, einen dedizierten Matrix-Account hierfรผr anzulegen. Der Zugangstoken kann in einem Incognito-Tab รผber den Element-Webclient geholt werden: Benutzermenรผ (oben links) > Alle Einstellungen > Hilfe & รber > Erweitert > Zugangstoken (direkt unter der Homeserver-URL). Schlieรe das Incognito-Tab dann (Abmelden wรผrde den Token ungรผltig werden lassen).
release.hide_archive_links = Automatisch generierte Archive verstecken
release.hide_archive_links_helper = Verstecke automatisch generierte Quellcodearchive fรผr diesen Release. Zum Beispiel, wenn du deine eigenen hochlรคdst.
@@ -2750,7 +2835,7 @@ settings.transfer.button = Besitz รผbertragen
settings.transfer.modal.title = Besitz รผbertragen
wiki.no_search_results = Keine Ergebnisse
wiki.search = Wiki durchsuchen
-n_release_one = %s freigegebn
+n_release_one = %s freigegeben
n_release_few = %s Verรถffentlichungen
form.string_too_long = Die Zeichenkette ist lรคnger als %d Zeichen.
settings.federation_settings = Fรถderationseinstellungen
@@ -2763,8 +2848,82 @@ issues.edit.already_changed = Die รnderungen an diesem Issue kรถnnen nicht gesp
pulls.edit.already_changed = Die รnderungen an diesem Pull-Request kรถnnen nicht gespeichert werden. Es scheint, als seien die Inhalte bereits durch einen anderen Benutzer verรคndert worden. Bitte die Seite neu laden und das Bearbeiten erneut versuchen, um deren รnderungen nicht zu รผberschreiben
subscribe.pull.guest.tooltip = Einloggen, um diesen Pull-Request zu abbonieren.
subscribe.issue.guest.tooltip = Einloggen, um dieses Issue zu abbonieren.
+issues.author.tooltip.pr = Dieser Benutzer ist der Autor dieses Pull-Requests.
+issues.author.tooltip.issue = Dieser Benutzer ist der Autor dieses Issues.
+activity.commit = Commit-Aktivitรคt
+milestones.filter_sort.name = Name
+release.type_attachment = Anhang
+release.type_external_asset = Externes Asset
+release.asset_name = Asset-Name
+release.asset_external_url = Externe URL
+release.add_external_asset = Externes Asset hinzufรผgen
+release.invalid_external_url = Ungรผltige externe URL: โ%sโ
+activity.published_prerelease_label = Pre-Release
+activity.published_tag_label = Tag
+settings.pull_mirror_sync_quota_exceeded = Quota รผberschritten, รnderungen werden nicht gepullt.
+settings.transfer_quota_exceeded = Der neue Eigentรผmer (%s) hat die Quota รผberschritten. Das Repository wurde nicht รผbertragen.
+no_eol.text = Kein EOL
+no_eol.tooltip = Diese Datei enthรคlt am Ende kein Zeilenende-Zeichen (EOL).
+pulls.cmd_instruction_merge_warning = Achtung : Die Einstellung โAutoerkennung von manuellen Zusammenfรผhrungenโ ist fรผr dieses Repository nicht aktiviert. Du musst hinterher diesen Pull-Request als manuell zusammengefรผhrt markieren.
+settings.protect_new_rule = Neue Branch-Schutzregel erstellen
+mirror_public_key = รffentlicher SSH-Schlรผssel
+mirror_use_ssh.text = SSH-Authentifizierung benutzen
+mirror_use_ssh.helper = Wenn du diese Option auswรคhlst, spiegelt Forgejo das Repository mittels Git รผber SSH und erstellt ein Schlรผsselpaar fรผr dich. Du musst sicherstellen, dass der generierte รถffentliche Schlรผssel zum Pushen in das Zielrepository autorisiert ist. Wenn du diese Option wรคhlst, kannst du die passwortbasierte Autorisierung nicht verwenden.
+mirror_denied_combination = Authentifizierung mittels รถffentlichem Schlรผssel und Passwort in Kombination ist nicht mรถglich.
+settings.mirror_settings.push_mirror.none_ssh = Nichts
+settings.mirror_settings.push_mirror.copy_public_key = รffentlichen Schlรผssel kopieren
+mirror_use_ssh.not_available = SSH-Authentifizierung ist nicht verfรผgbar.
+issues.new.assign_to_me = Mir selbst zuweisen
+issues.all_title = Alle
+settings.discord_icon_url.exceeds_max_length = Die Icon-URL darf eine Lรคnge von 2048 Zeichen nicht รผberschreiten
+issues.review.add_review_requests = hat Reviews von %[1]s %[2]s angefragt
+issues.review.remove_review_requests = hat Aufforderungen zum Review an %[1]s %[2]s entfernt
+issues.review.add_remove_review_requests = hat Reviews von %[1]s angefragt und hat die Aufforderungen zum Review an %[2]s %[3]s entfernt
+pulls.delete_after_merge.head_branch.is_default = Der Head-Branch, den du lรถschen willst, ist der Standardbranch und kann nicht gelรถscht werden.
+pulls.delete_after_merge.head_branch.is_protected = Der Head-Branch, den du lรถschen willst, ist ein geschรผtzter Branch und kann nicht gelรถscht werden.
+pulls.delete_after_merge.head_branch.insufficient_branch = Du hast keine Erlaubnis, den Head-Branch zu lรถschen.
+issues.filter_sort.relevance = Relevanz
+diff.git-notes.add = Anmerkung hinzufรผgen
+diff.git-notes.remove-header = Anmerkung entfernen
+diff.git-notes.remove-body = Diese Anmerkung wird entfernt.
+issues.num_reviews_one = %d Review
+issues.summary_card_alt = Zusammenfassung eines Issues mit dem Titel โ%sโ im Repository %s
+issues.num_reviews_few = %d Reviews
+editor.add_tmpl.filename = Dateiname
+settings.default_update_style_desc = Standard-Aktualisierungsart um Pull-Requests zu aktualisieren, die hinter dem Base-Branch sind.
+new_advanced = Erweiterte Einstellungen
+new_advanced_expand = Zum Ausklappen klicken
+pulls.sign_in_require = Anmelden , um einen neuen Pull-Request zu erstellen.
+new_from_template = Eine Vorlage benutzen
+new_from_template_description = Du kannst eine existierende Repository-Vorlage auf dieser Instanz benutzen und ihre Einstellungen anwenden.
+auto_init_description = Die Git-Historie mit einer README-Datei und optional einer Lizenz- und .gitignore-Datei starten.
+issues.context.menu = Kommentarmenรผ
+issues.reaction.add = Reaktion hinzufรผgen
+issues.reaction.alt_many = %[1]s und %[2]d mehr reagierten %[3]s.
+issues.reaction.alt_few = %[1]s reagierten %[2]s.
+issues.reaction.alt_add = Fรผge %[1]s Reaktion zum Kommentar hinzu.
+issues.reaction.alt_remove = Entferne %[1]s Reaktion von diesem Kommentar.
+summary_card_alt = Zusammenfassungskarte des Repositorys %s
+release.summary_card_alt = รbersichtskarte eines Releases mit dem Titel โ%sโ im Repository %s
+archive.pull.noreview = Dieses Repository ist archiviert. Pull-Requests kรถnnen nicht gereviewt werden.
+editor.commit_email = Commit-E-Mail
+commits.view_single_diff = รnderungen an dieser Datei, die in diesem Commit eingefรผhrt wurden, betrachten
+pulls.editable = Bearbeitbar
+pulls.editable_explanation = Dieser Pull-Request erlaubt Bearbeitungen durch Maintainer. Du kannst direkt dazu beitragen.
+issues.reopen.blocked_by_user = Du kannst dieses Issue nicht wieder erรถffnen, weil du vom Repository-Besitzer oder Ersteller des Issues blockiert wurdest.
+pulls.comment.blocked_by_user = Du kannst diesen Pull-Request nicht kommentieren, da du vom Repository-Besitzer oder Ersteller des Pull-Requests blockiert wurdest.
+issues.filter_no_results = Keine Ergebnisse
+issues.filter_no_results_placeholder = Versuche, deine Suchfilter anzupassen.
[graphs]
+component_loading_failed = Konnte %s nicht laden
+component_loading_info = Dies kรถnnte einen Moment dauern โฆ
+component_failed_to_load = Ein unerwarteter Fehler ist aufgetreten.
+component_loading = Lade %s โฆ
+contributors.what = Beitrรคge
+recent_commits.what = neueste Commits
+code_frequency.what = Code-Hรคufigkeit
+
[org]
org_name_holder=Name der Organisation
@@ -2803,7 +2962,7 @@ settings.permission=Berechtigungen
settings.repoadminchangeteam=Der Repository-Administrator kann den Zugriff fรผr Teams hinzufรผgen und zurรผckziehen
settings.visibility=Sichtbarkeit
settings.visibility.public=รffentlich
-settings.visibility.limited=Begrenzt (nur fรผr authentifizierte Benutzer sichtbar)
+settings.visibility.limited=Begrenzt (nur fรผr angemeldete Benutzer sichtbar)
settings.visibility.limited_shortname=Begrenzt
settings.visibility.private=Privat (nur fรผr Organisationsmitglieder sichtbar)
settings.visibility.private_shortname=Privat
@@ -2834,18 +2993,18 @@ members.member=Mitglied
members.remove=Entfernen
members.remove.detail=%[1]s aus %[2]s entfernen?
members.leave=Verlassen
-members.leave.detail=%s verlassen?
+members.leave.detail=Bist du dir sicher, dass du die Organisation โ%sโ verlassen willst?
members.invite_desc=Neues Mitglied zu %s hinzufรผgen:
members.invite_now=Jetzt einladen
teams.join=Beitreten
teams.leave=Verlassen
-teams.leave.detail=%s verlassen?
+teams.leave.detail=Bist du dir sicher, dass du das Team โ%sโ verlassen willst?
teams.can_create_org_repo=Repositorys erstellen
teams.can_create_org_repo_helper=Mitglieder kรถnnen neue Repositorys in der Organisation erstellen. Der Ersteller erhรคlt Administrator-Zugriff auf das neue Repository.
teams.none_access=Kein Zugriff
-teams.none_access_helper=Teammitglieder haben keinen Zugriff auf diese Einheit.
-teams.general_access=Allgemeiner Zugriff
+teams.none_access_helper=Die Option โKein Zugriffโ hat nur eine Auswirkung auf private Repositorys.
+teams.general_access=Benutzerdefinierter Zugriff
teams.general_access_helper=Mitgliederberechtigungen werden durch folgende Berechtigungstabelle festgelegt.
teams.read_access=Lesen
teams.read_access_helper=Mitglieder kรถnnen Teamrepositorys ansehen und klonen.
@@ -2867,7 +3026,7 @@ teams.delete_team_desc=Das Lรถschen eines Teams widerruft den Repository-Zugriff
teams.delete_team_success=Das Team wurde gelรถscht.
teams.read_permission_desc=Dieses Team hat Lesezugriff : Mitglieder kรถnnen Team-Repositorys einsehen und klonen.
teams.write_permission_desc=Dieses Team hat Schreibzugriff : Mitglieder kรถnnen Team-Repositorys einsehen und darauf pushen.
-teams.admin_permission_desc=Dieses Team hat Adminzugriff : Mitglieder dieses Teams kรถnnen Team-Repositorys ansehen, auf sie pushen und Mitarbeiter hinzufรผgen.
+teams.admin_permission_desc=Dieses Team hat Administrator zugriff: Mitglieder kรถnnen von Team-Repositorys lesen, auf sie pushen und Mitarbeiter hinzufรผgen.
teams.create_repo_permission_desc=Zusรคtzlich erteilt dieses Team die Berechtigung Repository erstellen : Mitglieder kรถnnen neue Repositorys in der Organisation erstellen.
teams.repositories=Team-Repositorys
teams.search_repo_placeholder=Repository durchsuchen โฆ
@@ -2880,7 +3039,7 @@ teams.add_duplicate_users=Dieser Benutzer ist bereits ein Teammitglied.
teams.repos.none=Dieses Team hat Zugang zu keinem Repository.
teams.members.none=Keine Mitglieder in diesem Team.
teams.specific_repositories=Bestimmte Repositorys
-teams.specific_repositories_helper=Mitglieder haben nur Zugriff auf Repositorys, die explizit dem Team hinzugefรผgt wurden. Wenn Du diese Option wรคhlst, werden Repositorys, die bereits mit Alle Repositorys hinzugefรผgt wurden, nicht automatisch entfernt.
+teams.specific_repositories_helper=Mitglieder haben nur Zugriff auf Repositorys, die explizit dem Team hinzugefรผgt wurden. Wenn du diese Option wรคhlst, werden Repositorys, die bereits mit Alle Repositorys hinzugefรผgt wurden, nicht automatisch entfernt.
teams.all_repositories=Alle Repositorys
teams.all_repositories_helper=Team hat Zugriff auf alle Repositorys. Wenn dies ausgewรคhlt wird, werden alle vorhandenen Repositorys zum Team hinzugefรผgt.
teams.all_repositories_read_permission_desc=Dieses Team gewรคhrt Lese -Zugriff auf Repositorys : Mitglieder kรถnnen Repositorys ansehen und klonen.
@@ -2891,6 +3050,8 @@ teams.invite.by=Von %s eingeladen
teams.invite.description=Bitte klicke auf die folgende Schaltflรคche, um dem Team beizutreten.
follow_blocked_user = Du kannst dieser Organisation nicht folgen, weil diese Organisation dich blockiert hat.
open_dashboard = รbersicht รถffnen
+settings.change_orgname_redirect_prompt.with_cooldown.one = Der alte Organisationsname ist nach einer Abkรผhldauer von einem Tag wieder fรผr alle Verfรผgbar. Du kannst den alten Namen wรคhrend dieser Abkรผhldauer erneut beanspruchen.
+settings.change_orgname_redirect_prompt.with_cooldown.few = Der alte Organisationsname ist nach einer Abkรผhldauer von %[1]d Tagen wieder fรผr alle Verfรผgbar. Du kannst den alten Namen wรคhrend dieser Abkรผhldauer erneut beanspruchen.
[admin]
dashboard=รbersicht
@@ -2911,7 +3072,7 @@ last_page=Letzte
total=Gesamt: %d
settings=Administratoreinstellungen
-dashboard.new_version_hint=Forgejo %s ist jetzt verfรผgbar, deine derzeitige Version ist %s. Weitere Details findest du im Blog .
+dashboard.new_version_hint=Forgejo %s ist jetzt verfรผgbar, deine derzeitige Version ist %s. Weitere Details findest du im Blog .
dashboard.statistic=รbersicht
dashboard.operations=Wartungsoperationen
dashboard.system_status=System-Status
@@ -2948,7 +3109,7 @@ dashboard.update_migration_poster_id=Migration Poster-IDs updaten
dashboard.git_gc_repos=Garbage-Collection fรผr alle Repositorys ausfรผhren
dashboard.resync_all_sshkeys=Die Datei โ.ssh/authorized_keysโ mit Forgejo-SSH-Schlรผsseln aktualisieren.
dashboard.resync_all_sshprincipals=Aktualisiere die Datei โ.ssh/authorized_principalsโ mit Forgejo-SSH-Principals.
-dashboard.resync_all_hooks=Die โpre-receiveโ-, โupdateโ- und โpost-receiveโ-Hooks fรผr alle Repositorys erneut synchronisieren.
+dashboard.resync_all_hooks=Die โpre-receiveโ-, โupdateโ- und โpost-receiveโ-Hooks fรผr alle Repositorys erneut synchronisieren
dashboard.reinit_missing_repos=Alle Git-Repositorys neu einlesen, fรผr die Eintrรคge existieren
dashboard.sync_external_users=Externe Benutzerdaten synchronisieren
dashboard.cleanup_hook_task_table=Hook-Task-Tabelle bereinigen
@@ -2988,15 +3149,15 @@ dashboard.delete_old_actions.started=Lรถschen aller alten Aktivitรคten aus der D
dashboard.update_checker=Update-Checker
dashboard.delete_old_system_notices=Alle alten Systemmeldungen aus der Datenbank lรถschen
dashboard.gc_lfs=Garbage-Collection fรผr LFS Meta-Objekte ausfรผhren
-dashboard.stop_zombie_tasks=Zombie-Aufgaben stoppen
-dashboard.stop_endless_tasks=Endlose Aufgaben stoppen
-dashboard.cancel_abandoned_jobs=Aufgegebene Jobs abbrechen
-dashboard.start_schedule_tasks=Terminierte Aufgaben starten
+dashboard.stop_zombie_tasks=Zombie-Actions-Aufgaben stoppen
+dashboard.stop_endless_tasks=Endlose Actions-Aufgaben stoppen
+dashboard.cancel_abandoned_jobs=Aufgegebene Actions-Jobs abbrechen
+dashboard.start_schedule_tasks=Terminierte Actions-Aufgaben starten
dashboard.sync_branch.started=Synchronisierung der Branches gestartet
dashboard.rebuild_issue_indexer=Issue-Indexer neu bauen
users.user_manage_panel=Benutzerkonten verwalten
-users.new_account=Benutzerkonto erstellen
+users.new_account=Benutzeraccount erstellen
users.name=Benutzername
users.full_name=Vollstรคndiger Name
users.activated=Aktiviert
@@ -3021,10 +3182,10 @@ users.update_profile_success=Das Benutzerkonto wurde aktualisiert.
users.edit_account=Benutzerkonto bearbeiten
users.max_repo_creation=Maximale Anzahl an Repositorys
users.max_repo_creation_desc=(Gib -1 ein, um das globale Standardlimit zu verwenden.)
-users.is_activated=Account ist aktiviert
-users.prohibit_login=Anmelden deaktivieren
-users.is_admin=Ist Administrator
-users.is_restricted=Ist eingeschrรคnkt
+users.is_activated=Aktivierter Account
+users.prohibit_login=Gesperrter Account
+users.is_admin=Administrator-Account
+users.is_restricted=Eingeschrรคnkter Account
users.allow_git_hook=Kann Git-Hooks erstellen
users.allow_git_hook_tooltip=Git-Hooks werden mit denselben Benutzer-Rechten ausgefรผhrt, mit denen Forgejo lรคuft, und haben die gleiche Ebene von Host-Zugriff. Dadurch kรถnnen Benutzer mit diesen speziellen Git-Hook-Rechten auf alle Forgejo-Repositorys sowie auf die von Forgejo verwendete Datenbank zugreifen und diese รคndern. Auch das Erhalten von Administratorrechten fรผr Forgejo ist mรถglich.
users.allow_import_local=Kann lokale Repositorys importieren
@@ -3073,7 +3234,7 @@ orgs.new_orga=Neue Organisation
repos.repo_manage_panel=Repositorys verwalten
repos.unadopted=Nicht รผbernommene Repositorys
-repos.unadopted.no_more=Keine weiteren nicht รผbernommenen Repositorys gefunden
+repos.unadopted.no_more=Keine nicht รผbernommenen Repositorys gefunden.
repos.owner=Besitzer
repos.name=Name
repos.private=Privat
@@ -3098,12 +3259,12 @@ packages.size=Grรถรe
packages.published=Verรถffentlicht
defaulthooks=Standard-Webhooks
-defaulthooks.desc=Webhooks senden automatisch ein HTTP-POST-Anfragen an einen Server, wenn bestimmte Forgejo-Events ausgelรถst werden. Hier definierte Webhooks sind die Standardwerte, die in alle neuen Repositorys kopiert werden. Mehr Infos findest du in der Webhooks-Anleitung (auf Englisch).
+defaulthooks.desc=Webhooks senden automatisch ein HTTP-POST-Anfragen an einen Server, wenn bestimmte Forgejo-Events ausgelรถst werden. Hier definierte Webhooks sind die Standardwerte, die in alle neuen Repositorys kopiert werden. Mehr Infos findest du in der Webhooks-Anleitung (auf Englisch).
defaulthooks.add_webhook=Standard-Webhook hinzufรผgen
defaulthooks.update_webhook=Standard-Webhook aktualisieren
systemhooks=System-Webhooks
-systemhooks.desc=Webhooks senden automatisch HTTP-POST-Anfragen an einen Server, wenn bestimmte Forgejo-Events ausgelรถst werden. Hier definierte Webhooks werden auf alle Repositorys des Systems รผbertragen, beachte daher mรถgliche Performance-Einbrรผche. Mehr Infos findest du in der Webhooks-Anleitung (auf Englisch).
+systemhooks.desc=Webhooks senden automatisch HTTP-POST-Anfragen an einen Server, wenn bestimmte Forgejo-Events ausgelรถst werden. Hier definierte Webhooks werden auf alle Repositorys des Systems รผbertragen, beachte daher mรถgliche Performance-Einbrรผche. Mehr Infos findest du in der Webhooks-Anleitung (auf Englisch).
systemhooks.add_webhook=System-Webhook hinzufรผgen
systemhooks.update_webhook=System-Webhook aktualisieren
@@ -3198,18 +3359,18 @@ auths.tips=Tipps
auths.tips.oauth2.general=OAuth2-Authentifizierung
auths.tips.oauth2.general.tip=Beim Registrieren einer OAuth2-Anwendung sollte die Callback-URL folgendermaรen lauten:
auths.tip.oauth2_provider=OAuth2-Anbieter
-auths.tip.bitbucket=Registriere einen neuen OAuth-Consumer unter https://bitbucket.org/account/user//oauth-consumers/new und fรผge die Berechtigung โAccountโ โ โReadโ hinzu
+auths.tip.bitbucket=Registriere einen neuen OAuth-Consumer unter %s
auths.tip.nextcloud=Registriere einen neuen OAuth-Consumer auf deiner Instanz รผber das folgende Menรผ: โSettings -> Security -> OAuth 2.0 clientโ
-auths.tip.dropbox=Erstelle eine neue App auf https://www.dropbox.com/developers/apps
-auths.tip.facebook=Erstelle eine neue Anwendung auf https://developers.facebook.com/apps und fรผge das Produkt โFacebook Loginโ hinzu
-auths.tip.github=Erstelle unter https://github.com/settings/applications/new eine neue OAuth-Anwendung.
+auths.tip.dropbox=Erstelle eine neue App auf %s
+auths.tip.facebook=Erstelle eine neue Anwendung auf %s und fรผge das Produkt โFacebook Loginโ hinzu
+auths.tip.github=Registriere unter %s eine neue OAuth-Anwendung
auths.tip.gitlab=Erstelle unter https://gitlab.com/profile/applications eine neue Anwendung.
-auths.tip.google_plus=Du erhรคltst die OAuth2-Client-Zugangsdaten in der Google-API-Konsole unter https://console.developers.google.com/
+auths.tip.google_plus=Du erhรคltst die OAuth2-Client-Zugangsdaten in der Google-API-Konsole unter %s
auths.tip.openid_connect=Benutze die OpenID-Connect-Discovery-URL (/.well-known/openid-configuration), um die Endpunkte zu spezifizieren
-auths.tip.twitter=Gehe auf https://dev.twitter.com/apps, erstelle eine Anwendung und stelle sicher, dass die Option โAllow this application to be used to Sign in with Twitterโ aktiviert ist
-auths.tip.discord=Erstelle unter https://discordapp.com/developers/applications/me eine neue Anwendung.
-auths.tip.gitea=Registriere eine neue OAuth2-Anwendung. Eine Anleitung findest du unter https://forgejo.org/docs/latest/user/oauth2-provider
-auths.tip.yandex=`Erstelle eine neue Anwendung auf https://oauth.yandex.com/client/new. Wรคhle folgende Berechtigungen aus dem Abschnitt โYandex.Passport APIโ: โZugriff auf E-Mail-Adresseโ, โZugriff auf Benutzeravatarโ und โZugriff auf Benutzername, Vor- und Nachname, Geschlechtโ`
+auths.tip.twitter=Gehe auf %s, erstelle eine Anwendung und stelle sicher, dass die Option โAllow this application to be used to Sign in with Twitterโ aktiviert ist
+auths.tip.discord=Registriere unter %s eine neue Anwendung
+auths.tip.gitea=Registriere eine neue OAuth2-Anwendung. Eine Anleitung findest du unter %s
+auths.tip.yandex=`Erstelle eine neue Anwendung auf %s. Wรคhle folgende Berechtigungen aus dem Abschnitt โYandex.Passport APIโ: โZugriff auf E-Mail-Adresseโ, โZugriff auf Benutzeravatarโ und โZugriff auf Benutzername, Vor- und Nachname, Geschlechtโ`
auths.tip.mastodon=Gib eine benutzerdefinierte URL fรผr die Mastodon-Instanz ein, mit der du dich authentifizieren mรถchtest (oder benutze die standardmรครige)
auths.edit=Authentifikationsquelle bearbeiten
auths.activated=Diese Authentifikationsquelle ist aktiviert
@@ -3417,7 +3578,7 @@ notices.type_2=Aufgabe
notices.desc=Beschreibung
notices.op=Aktion
notices.delete_success=Diese Systemmeldung wurde gelรถscht.
-self_check.database_fix_mysql = Fรผr MySQL-/MariaDB-Benutzer: Du kannst den Befehl โgitea doctor convertโ verwenden, um die Collation-Probleme zu lรถsen, oder du kannst das Problem mit โALTER โฆ COLLATE โฆโ-SQLs manuell lรถsen.
+self_check.database_fix_mysql = Fรผr MySQL-/MariaDB-Benutzer: Du kannst den Befehl โforgejo doctor convertโ verwenden, um die Collation-Probleme zu lรถsen, oder du kannst das Problem mit โALTER โฆ COLLATE โฆโ-SQLs manuell lรถsen.
dashboard.sync_tag.started = Tag-Synchronisierung gestartet
self_check.database_collation_case_insensitive = Datenbank benutzt eine Collation %s, welcher der Groร-/Kleinschreibung egal ist. Obwohl Forgejo damit arbeiten kรถnnte, kรถnnte es ein paar seltene Fรคlle geben, bei denen es nicht wie erwartet funktioniert.
self_check = Selbstprรผfung
@@ -3431,9 +3592,24 @@ auths.tips.gmail_settings = Gmail-Einstellungen:
config_settings = Einstellungen
config.open_with_editor_app_help = Die โรffnen mitโ-Editoren fรผr das Klonmenรผ. Falls es leer gelassen wird, wird der Standardwert benutzt. Erweitern, um den Standardwert zu sehen.
config_summary = Zusammenfassung
-auths.tip.gitlab_new = Registriere eine neue Anwendung auf https://gitlab.com/-/profile/applications
+auths.tip.gitlab_new = Registriere eine neue Anwendung auf %s
auths.default_domain_name = Standarddomainname, der fรผr die E-Mail-Adresse benutzt wird
config.app_slogan = Instanz-Slogan
+config.cache_test_failed = Konnte den Cache nicht untersuchen: %v.
+config.cache_test_succeeded = Cache-Test erfolgreich, eine Antwort erhalten in %s.
+config.cache_test = Cache testen
+config.cache_test_slow = Cache-Test erfolgreich, aber die Antwort ist langsam: %s.
+users.block.description = Interaktionen mit diesen Dienst fรผr diesen Benutzer mit seinem Account blockierten und Einloggen verhindern.
+users.restricted.description = Nur Interaktionen mit den Repositorys und Organisationen erlauben, wo der Benutzer als Mitarbeiter hinzugefรผgt wurde. Dies verhindert Zugriff auf รถffentliche Repositorys in dieser Instanz.
+users.local_import.description = Import von Repositorys aus dem lokalen Dateisystem des Servers erlauben. Dies kann ein Sicherheitsproblem sein.
+users.organization_creation.description = Erstellung neuer Organisationen erlauben.
+users.activated.description = Abschluss der E-Mail-Verifizierung. Der Besitzer eines nicht aktivierten Accounts wird nicht in der Lage sein, sich einzuloggen, bis die E-Mail-Verifikation abgeschlossen wurde.
+users.admin.description = Diesen Benutzer vollstรคndigen Zugriff zu allen administrativen Features gewรคhren mittels der Web-UI und der API.
+emails.delete = E-Mail lรถschen
+emails.deletion_success = Die E-Mail-Adresse wurde gelรถscht.
+emails.delete_primary_email_error = Du kannst die primรคre E-Mail nicht lรถschen.
+emails.delete_desc = Bist du dir sicher, dass du diese E-Mail-Adresse lรถschen willst?
+monitor.duration = Dauer (s)
[action]
@@ -3451,7 +3627,7 @@ comment_pull=`hat den Pull-Request %[3]s#%[2]s kommentiert`
merge_pull_request=`fรผhrte Pull-Request %[3]s#%[2]s zusammen`
auto_merge_pull_request=`fรผhrte Pull-Request %[3]s#%[2]s automatisch zusammen`
transfer_repo=hat Repository %s
รผbertragen zu %s
-push_tag=Tag %[3]s nach %[4]s wurde gepusht
+push_tag=hat Tag %[3]s auf %[4]s gepusht
delete_tag=hat Tag %[2]s in %[3]s gelรถscht
delete_branch=hat Branch %[2]s in %[3]s gelรถscht
compare_branch=Vergleichen
@@ -3516,7 +3692,7 @@ error.generate_hash=Es konnte kein Hash vom Commit generiert werden
error.no_committer_account=Es ist kein Account mit der E-Mail-Adresse des Committers verbunden
error.no_gpg_keys_found=Es konnte kein GPG-Schlรผssel zu dieser Signatur gefunden werden
error.not_signed_commit=Kein signierter Commit
-error.failed_retrieval_gpg_keys=Fehler beim Abrufen eines Keys des Commiter-Kontos
+error.failed_retrieval_gpg_keys=Fehler beim Abrufen eines Schlรผssels des Committer-Kontos
error.probable_bad_signature=WARNHINWEIS! Obwohl ein Schlรผssel mit dieser ID in der Datenbank existiert, verifiziert er nicht diesen Commit! Dieser Commit ist VERDรCHTIG.
error.probable_bad_default_signature=WARNHINWEIS! Obwohl der Standardschlรผssel diese ID hat, verifiziert er nicht diesen Commit! Dieser Commit ist VERDรCHTIG.
@@ -3550,7 +3726,7 @@ details.project_site=Projektwebseite
details.repository_site=Repository-Webseite
details.documentation_site=Dokumentationswebseite
details.license=Lizenz
-assets=Dateien
+assets=Assets
versions=Versionen
versions.view_all=Alle anzeigen
dependency.id=ID
@@ -3576,12 +3752,12 @@ conan.registry=Diese Registry รผber die Kommandozeile einrichten:
conan.install=Um das Paket mit Conan zu installieren, fรผhre den folgenden Befehl aus:
conda.registry=Richte diese Registry als Conda-Repository in deiner .condarc
-Datei ein:
conda.install=Um das Paket mit Conda zu installieren, fรผhre den folgenden Befehl aus:
-container.details.type=Container-Image Typ
+container.details.type=Abbildtyp
container.details.platform=Plattform
container.pull=Downloade das Container-Image aus der Kommandozeile:
-container.digest=Digest:
+container.digest=Digest
container.multi_arch=Betriebsystem / Architektur
-container.layers=Container-Image Ebenen
+container.layers=Abbildebenen
container.labels=Labels
container.labels.key=Schlรผssel
container.labels.value=Wert
@@ -3620,8 +3796,8 @@ rpm.registry=Diese Registry รผber die Kommandozeile einrichten:
rpm.distros.redhat=auf RedHat-basierten Distributionen
rpm.distros.suse=auf SUSE-basierten Distributionen
rpm.install=Nutze folgenden Befehl, um das Paket zu installieren:
-rpm.repository=Repository-Informationen
-rpm.repository.architectures=Architekturen
+rpm.repository = Repository-Info
+rpm.repository.architectures = Architekturen
rubygems.install=Um das Paket mit gem zu installieren, fรผhre den folgenden Befehl aus:
rubygems.install2=oder fรผg es zum Gemfile hinzu:
rubygems.dependencies.runtime=Laufzeitabhรคngigkeiten
@@ -3675,11 +3851,34 @@ owner.settings.cleanuprules.success.delete=Bereinigungsregel wurde gelรถscht.
owner.settings.chef.title=Chef-Registry
owner.settings.chef.keypair=Schlรผsselpaar generieren
owner.settings.chef.keypair.description=Ein Schlรผsselpaar ist notwendig, um mit der Chef-Registry zu authentifizieren. Wenn du bereits eins erstellt hast, wird dieses durch eine Neuerstellung verworfen.
-rpm.repository = Repository-Info
rpm.repository.multiple_groups = Dieses Paket ist in mehreren Gruppen verfรผgbar.
-rpm.repository.architectures = Architekturen
owner.settings.cargo.rebuild.no_index = Kann nicht erneut erzeugen, es wurde kein Index initialisiert.
npm.dependencies.bundle = Gebรผndelte Abhรคngigkeiten
+arch.pacman.helper.gpg = Trust-Zertifikat fรผr pacman hinzufรผgen:
+arch.pacman.repo.multi = %s hat die gleiche Version in verschiedenen Distributionen.
+arch.pacman.repo.multi.item = Konfiguration fรผr %s
+arch.pacman.conf = Server mit verwandter Distribution und Architektur zu /etc/pacman.conf
hinzufรผgen:
+arch.pacman.sync = Paket mit pacman synchronisieren:
+arch.version.properties = Versionseigenschaften
+arch.version.description = Beschreibung
+arch.version.provides = Bietet
+arch.version.groups = Gruppe
+arch.version.depends = Hรคngt ab von
+arch.version.makedepends = Make-Abhรคngigkeit
+arch.version.checkdepends = Check-Abhรคngigkeit
+arch.version.conflicts = Konflikte
+arch.version.replaces = Ersetzt
+arch.version.backup = Backup
+arch.version.optdepends = Optionale Abhรคngigkeit
+container.images.title = Bilder
+search_in_external_registry = In %s suchen
+alt.registry = Diese Registry von der Befehlszeile aus einrichten:
+alt.registry.install = Um das Paket zu installieren, folgenden Befehl ausfรผhren:
+alt.install = Paket installieren
+alt.setup = Ein Repository zur Liste der verbundenen Repositorys hinzufรผgen (wรคhle die nรถtige Architektur anstelle von โ_arch_โ):
+alt.repository = Repository-Infos
+alt.repository.architectures = Architekturen
+alt.repository.multiple_groups = Dieses Paket ist in verschiedenen Gruppen verfรผgbar.
[secrets]
secrets=Secrets
@@ -3699,7 +3898,7 @@ management=Secrets verwalten
[actions]
actions=Actions
-unit.desc=Integrierte CI/CD-Pipelines mit Forgejo-Actions verwalten
+unit.desc=Integrierte CI/CD-Pipelines mit Forgejo-Actions verwalten.
status.unknown=Unbekannt
status.waiting=Wartend
@@ -3790,15 +3989,26 @@ variables.id_not_exist = Variable mit ID %d existiert nicht.
runs.workflow = Workflow
runs.no_job_without_needs = Der Workflow muss mindestens einen Job ohne Abhรคngigkeiten enthalten.
runs.no_job = Der Workflow muss mindestens einen Job enthalten
+workflow.dispatch.use_from = Workflow benutzen von
+workflow.dispatch.run = Workflow ausfรผhren
+workflow.dispatch.input_required = Wert fรผr Eingabe โ%sโ erfordern.
+workflow.dispatch.invalid_input_type = Ungรผltiger Eingabetyp โ%sโ.
+workflow.dispatch.warn_input_limit = Es werden nur die ersten %d Eingaben angezeigt.
+workflow.dispatch.trigger_found = Dieser Workflow hat einen workflow_dispatch -Event-Trigger.
+workflow.dispatch.success = Ausfรผhrung des Workflows wurde erfolgreich angefragt.
+runs.expire_log_message = Logs wurden gelรถscht, weil sie zu alt waren.
+runs.no_workflows.help_write_access = Keine Ahnung, wie man mit Forgejo Actions anfangen soll? Schau im Schnellstart in der Benutzerdokumentation vorbei, um deinen ersten Workflow zu schreiben, dann setze einen Forgejo-Runner auf , um deine Jobs auszufรผhren.
+runs.no_workflows.help_no_write_access = Um รผber Forgejo Actions zu lernen, siehe die Dokumentation .
+variables.not_found = Die Variable wurde nicht gefunden.
[projects]
type-1.display_name=Individuelles Projekt
type-2.display_name=Repository-Projekt
type-3.display_name=Organisationsprojekt
+deleted.display_name = Gelรถschtes Projekt
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=Verzeichnis
normal_file=Normale Datei
executable_file=Ausfรผhrbare Datei
@@ -3807,18 +4017,8 @@ submodule=Submodul
-[graphs]
-component_loading_failed = Konnte %s nicht laden
-component_loading_info = Dies kรถnnte einen Moment dauern โฆ
-component_failed_to_load = Ein unerwarteter Fehler ist aufgetreten.
-component_loading = Lade %s โฆ
-contributors.what = Beitrรคge
-recent_commits.what = neueste Commits
-code_frequency.what = Code-Frequenz
-
-
[search]
-search = Suche โฆ
+search = Suchen โฆ
fuzzy_tooltip = Auch Ergebnisse einbinden, die grob zum Suchbegriff passen
type_tooltip = Suchtyp
fuzzy = Unscharf
@@ -3828,20 +4028,25 @@ repo_kind = Repos suchen โฆ
user_kind = Benutzer suchen โฆ
org_kind = Orgs suchen โฆ
team_kind = Teams suchen โฆ
-code_kind = Code suchen โฆ
+code_kind = Code suchenโฆ
package_kind = Pakete suchen โฆ
project_kind = Projekte suchen โฆ
branch_kind = Branches suchen โฆ
commit_kind = Commits suchen โฆ
-runner_kind = Runners suchen โฆ
+runner_kind = Runner suchen โฆ
no_results = Keine passenden Ergebnisse gefunden.
code_search_unavailable = Die Code-Suche ist momentan nicht verfรผgbar. Bitte kontaktiere den Webseitenadministrator.
-keyword_search_unavailable = Suche nach Schlรผsselwรถrtern ist momentan nicht unterstรผzt. Bitte kontaktiere den Webseitenadministrator.
+keyword_search_unavailable = Die Suche mittels Schlรผsselwort ist momentan nicht verfรผgbar. Bitte kontaktiere den Webseitenadministrator.
code_search_by_git_grep = Die derzeitigen Codesuchergebnisse werden durch โgit grepโ bereitgestellt. Es kรถnnten bessere Ergebnisse erzielt werden, wenn der Administrator die Repository-Indizierung aktiviert.
exact = Exakt
exact_tooltip = Nur Ergebnisse einbinden, die auf den exakten Suchbegriff passen
-issue_kind = Issues durchsuchen โฆ
-pull_kind = Pulls durchsuchen โฆ
+issue_kind = Issues suchen โฆ
+pull_kind = Pulls suchen โฆ
+union = Vereinigungsmenge
+union_tooltip = Ergebnisse, die auf ein beliebiges von den Whitespace getrennten Schlรผsselwรถrtern passen, einbinden
+milestone_kind = Meilensteine suchen โฆ
+regexp = RegExp
+regexp_tooltip = Suchbegriff als regulรคren Ausdruck interpretieren
[markup]
filepreview.line = Zeile %[1]d in %[2]s
@@ -3856,3 +4061,27 @@ tib = TiB
pib = PiB
mib = MiB
eib = EiB
+
+
+[translation_meta]
+test = ok
+
+[repo.permissions]
+code.write = Schreiben: In das Repository pushen, Branches und Tags erstellen.
+code.read = Lesen: Zugriff auf das Repository und Klonen.
+issues.read = Lesen: Issues und Kommentare lesen und erstellen.
+issues.write = Schreiben: Issues schlieรen und Metadaten wie Labels, Meilensteine, Zuweisungen, Fรคlligkeitsdaten und Abhรคngigkeiten verwalten.
+pulls.read = Lesen: Pull-Requests lesen und erstellen.
+releases.read = Lesen: Releases ansehen und herunterladen.
+releases.write = Schreiben: Releases und ihre Assets verรถffentlichen, bearbeiten und lรถschen.
+wiki.read = Lesen: Das integrierte Wiki und seine Historie lesen.
+wiki.write = Schreiben: Seiten im integrierten Wiki erstellen, aktualisieren und lรถschen.
+projects.read = Lesen: Zugriff auf Projektboards des Repositories.
+projects.write = Schreiben: Projekte und Spalten erstellen und bearbeiten.
+packages.read = Lesen: Pakete dieses Repositories betrachten und herunterladen.
+packages.write = Schreiben: Pakete dieses Repositories verรถffentlichen und lรถschen.
+actions.read = Lesen: Integrierte CI/CD-Pipelines und ihre Logs betrachten.
+actions.write = Schreiben: Ausstehende CI/CD-Pipelines manuell auslรถsen, neustarten, abbrechen oder genehmigen.
+ext_issues = Zugriff auf den Link zu einem externen Issue-Tracker. Die Berechtigungen werden extern verwaltet.
+ext_wiki = Zugriff auf den Link zu einem externen Wiki. Die Berechtigungen werden extern verwaltet.
+pulls.write = Schreiben: Pull-Requests schlieรen und Metadaten wie Labels, Meilensteine, Zuweisungen, Fรคlligkeitsdaten und Abhรคngigkeiten verwalten.
diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini
index fb15b5b453..d08fa6e349 100644
--- a/options/locale/locale_el-GR.ini
+++ b/options/locale/locale_el-GR.ini
@@ -51,7 +51,7 @@ webauthn_error_empty=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮฟฯฮฏฯฮตฯฮต ฮญฮฝฮฑ ฯฮฝฮฟฮผฮฑ ฮณฮนฮฑ
webauthn_error_timeout=ฮคฮฟ ฯฯฮฟฮฝฮนฮบฯ ฯฯฮนฮฟ ฮญฯฯฮฑฯฮต ฯฯฮนฮฝ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ ฮฝฮฑ ฮดฮนฮฑฮฒฮฑฯฯฮตฮฏ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮฑฮฝฮฑฮฝฮตฯฯฯฮต ฯฮท ฯฮตฮปฮฏฮดฮฑ ฮบฮฑฮน ฯฯฮฟฯฯฮฑฮธฮฎฯฯฮต ฮพฮฑฮฝฮฌ.
webauthn_reload=ฮฮฝฮฑฮฝฮญฯฯฮท
-repository=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+repository=Repository
organization=ฮฯฮณฮฑฮฝฮนฯฮผฯฯ
mirror=ฮฮฝฯฮฏฮณฯฮฑฯฮฟ
new_repo=ฮฮญฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
@@ -87,7 +87,7 @@ rerun=ฮฯฮฑฮฝฮตฮบฯฮญฮปฮตฯฮท
rerun_all=ฮฯฮฑฮฝฮตฮบฯฮญฮปฮตฯฮท ฯฮปฯฮฝ
save=ฮฯฮฟฮธฮฎฮบฮตฯ
ฯฮท
add=ฮ ฯฮฟฯฮธฮฎฮบฮท
-add_all=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮฮปฯฮฝ
+add_all=ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฮปฯฮฝ
remove=ฮฯฮฑฮฏฯฮตฯฮท
remove_all=ฮฯฮฑฮฏฯฮตฯฮท ฯฮปฯฮฝ
remove_label_str=ฮฯฮฑฮฏฯฮตฯฮท ฮฑฮฝฯฮนฮบฮตฮนฮผฮญฮฝฮฟฯ
ยซ%sยป
@@ -129,7 +129,7 @@ archived=ฮฯฯฮตฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮต
concept_system_global=ฮฮตฮฝฮนฮบฯ
concept_user_individual=ฮฯฮฟฮผฮนฮบฯ
-concept_code_repository=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+concept_code_repository=Repository
concept_user_organization=ฮฯฮณฮฑฮฝฮนฯฮผฯฯ
show_timestamps=ฮฮผฯฮฌฮฝฮนฯฮท ฯฯฮฟฮฝฮฟฯฮทฮผฮฌฮฝฯฮตฯฮฝ
@@ -154,21 +154,31 @@ filter.not_fork = ฮฮพฮฑฮฏฯฮตฯฮท fork
filter.is_mirror = ฮฮฏฮดฯฮปฮฑ
filter.not_mirror = ฮฮพฮฑฮฏฯฮตฯฮท ฮตฮนฮดฯฮปฯฮฝ
filter.not_template = ฮฮพฮฑฮฏฯฮตฯฮท ฯฯฮฟฯฯฯฯฮฝ
-filter.is_fork = Forked
+filter.is_fork = Forks
more_items = ฮ ฮตฯฮนฯฯฯฯฮตฯฮฑ ฮฑฮฝฯฮนฮบฮตฮฏฮผฮตฮฝฮฑ
invalid_data = ฮคฮฑ ฮดฮตฮดฮฟฮผฮญฮฝฮฑ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฑ: %v
+test = ฮคฮตฯฯ
+copy_generic = ฮฮฝฯฮนฮณฯฮฑฯฮฎ ฯฯฮฟ ฯฯฯฯฮตฮนฯฮฟ
+error413 = ฮฯฮตฯฮต ฮตฮพฮฑฮฝฯฮปฮฎฯฮตฮน ฯฮฟฯ
ฯ ฮดฮนฮฑฮธฮญฯฮนฮผฮฟฯ
ฯ ฯฯฯฮฟฯ
ฯ ฯฮฑฯ.
+new_repo.link = ฮฮญฮฟ repository
+new_migrate.link = ฮฮญฮฑ ฮผฮตฯฮฑฯฮฟฯฮฌ
+new_org.link = ฮฮญฮฟฯ ฮฟฯฮณฮฑฮฝฮนฯฮผฯฯ
+new_migrate.title = ฮฮญฮฑ ฮผฮตฯฮฑฯฮฟฯฮฌ
+new_repo.title = ฮฮญฮฟ repository
+new_org.title = ฮฮญฮฟฯ ฮฟฯฮณฮฑฮฝฮนฯฮผฯฯ
+copy_path = ฮฮฝฯฮนฮณฯฮฑฯฮฎ ฯฮฟฯฮฟฮธฮตฯฮฏฮฑฯ
[aria]
-navbar=ฮฯฮฑฮผฮผฮฎ ฮ ฮปฮฟฮฎฮณฮทฯฮทฯ
+navbar=ฮฯฮฌฯฮฑ ฯฮปฮฟฮฎฮณฮทฯฮทฯ
footer=ฮฅฯฮฟฯฮญฮปฮนฮดฮฟ
-footer.software=ฮฃฯฮตฯฮนฮบฮฌ ฮผฮต ฯฮฟ ฮฮฟฮณฮนฯฮผฮนฮบฯ
+footer.software=ฮ ฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฮปฮฟฮณฮนฯฮผฮนฮบฮฟฯ
footer.links=ฮฃฯ
ฮฝฮดฮญฯฮตฮนฯ
[heatmap]
number_of_contributions_in_the_last_12_months=%s ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮญฯ ฯฮฟฯ
ฯ ฯฮตฮปฮตฯ
ฯฮฑฮฏฮฟฯ
ฯ 12 ฮผฮฎฮฝฮตฯ
contributions_zero=ฮงฯฯฮฏฯ ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮญฯ
-less=ฮฮนฮณฯฯฮตฯฮฑ
-more=ฮ ฮตฯฮนฯฯฯฯฮตฯฮฑ
+less=ฮฮนฮณฯฯฮตฯฮตฯ
+more=ฮ ฮตฯฮนฯฯฯฯฮตฯฮตฯ
contributions_format = {contributions} ฯฯฮนฯ {day} {month} ฯฮฟฯ
ฮญฯฮฟฯ
ฯ {year}
contributions_one = ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮฌ
contributions_few = ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮญฯ
@@ -188,6 +198,18 @@ buttons.ref.tooltip=ฮฮฝฮทฮผฯฮฝฮตฯ
ฯฮท ฮตฮฝฯฯ ฮธฮญฮผฮฑฯฮฟฯ ฮฎ pull request
buttons.switch_to_legacy.tooltip=ฮงฯฮฎฯฮท ฯฮฟฯ
ฮบฮปฮฑฯฯฮนฮบฮฟฯ ฮบฮตฮนฮผฮตฮฝฮฟฮณฯฮฌฯฮฟฯ
buttons.enable_monospace_font=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฑฮธฮตฯฮฎฯ ฮณฯฮฑฮผฮผฮฑฯฮฟฯฮตฮนฯฮฌฯ
buttons.disable_monospace_font=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฑฮธฮตฯฮฎฯ ฮณฯฮฑฮผฮผฮฑฯฮฟฯฮตฮนฯฮฌฯ
+buttons.unindent.tooltip = ฮฮตฮฏฯฯฮท ฮตฯฮฟฯฮฎฯ ฯฯฮฟฮนฯฮตฮฏฯฮฝ ฮบฮฑฯฮฌ ฮญฮฝฮฑ ฮตฯฮฏฯฮตฮดฮฟ
+buttons.indent.tooltip = ฮฯฮพฮทฯฮท ฮตฯฮฟฯฮฎฯ ฯฯฮฟฮนฯฮตฮฏฯฮฝ ฮบฮฑฯฮฌ ฮญฮฝฮฑ ฮตฯฮฏฯฮตฮดฮฟ
+table_modal.header = ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฮฏฮฝฮฑฮบฮฑ
+table_modal.placeholder.header = ฮฯฮนฮบฮตฯฮฑฮปฮฏฮดฮฑ
+table_modal.placeholder.content = ฮ ฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ
+table_modal.label.rows = ฮฃฮตฮนฯฮญฯ
+table_modal.label.columns = ฮฃฯฮฎฮปฮตฯ
+buttons.new_table.tooltip = ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฮฏฮฝฮฑฮบฮฑ
+
+link_modal.header = ฮ ฯฮฟฯฮธฮฎฮบฮท ฯ
ฯฮตฯฯฯ
ฮฝฮดฮญฯฮผฮฟฯ
+link_modal.url = URL
+link_modal.description = ฮ ฮตฯฮนฮณฯฮฑฯฮฎ
[filter]
string.asc=A - Z
@@ -195,7 +217,7 @@ string.desc=Z - A
[error]
occurred=ฮ ฮฑฯฮฟฯ
ฯฮนฮฌฯฯฮทฮบฮต ฮญฮฝฮฑ ฯฯฮฌฮปฮผฮฑ
-report_message=ฮฮฝ ฯฮนฯฯฮตฯฮตฯฮต ฯฯฮน ฮฑฯ
ฯฯ ฯฯฮฟฮญฮบฯ
ฯฮต ฮปฯฮณฯ ฮบฮฌฯฮฟฮนฮฟฯ
ฯฯฮฌฮปฮผฮฑฯฮฟฯ ฯฯฮฟ Forgejo, ฯฮฑฯ ฯฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฮฝฮฑ ฯฮฏฮพฮตฯฮต ฮผฮฏฮฑ ฮผฮฑฯฮนฮฌ ฯฯฮฑ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฯฯฮฟ Codeberg ฮฎ ฮฝฮฑ ฮฑฮฝฮฟฮฏฮพฮตฯฮต ฮญฮฝฮฑ ฮฝฮญฮฟ ฮถฮฎฯฮทฮผฮฑ ฮตฮฌฮฝ ฮตฮฏฮฝฮฑฮน ฮฑฯฮฑฯฮฑฮฏฯฮทฯฮฟ.
+report_message=ฮฮฝ ฯฮนฯฯฮตฯฮตฯฮต ฯฯฮน ฮฑฯ
ฯฯ ฯฯฮฟฮญฮบฯ
ฯฮต ฮปฯฮณฯ ฮบฮฌฯฮฟฮนฮฟฯ
ฯฯฮฌฮปฮผฮฑฯฮฟฯ ฯฯฮฟ Forgejo, ฯฮฑฯ ฯฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฮฝฮฑ ฯฮฏฮพฮตฯฮต ฮผฮฏฮฑ ฮผฮฑฯฮนฮฌ ฯฯฮฑ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฯฯฮฟ Codeberg ฮฎ ฮฝฮฑ ฮฑฮฝฮฟฮฏฮพฮตฯฮต ฮญฮฝฮฑ ฮฝฮญฮฟ ฮถฮฎฯฮทฮผฮฑ ฮตฮฌฮฝ ฮตฮฏฮฝฮฑฮน ฮฑฯฮฑฯฮฑฮฏฯฮทฯฮฟ.
missing_csrf=Bad Request: ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ CSRF
invalid_csrf=ฮฮฌฮธฮฟฯ ฮฮฏฯฮทฮผฮฑ: ฮผฮท ฮญฮณฮบฯ
ฯฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ CSRF
not_found=ฮ ฯฯฮฟฮฟฯฮนฯฮผฯฯ ฮดฮตฮฝ ฮฒฯฮญฮธฮทฮบฮต.
@@ -205,13 +227,13 @@ server_internal = ฮฃฯฮฌฮปฮผฮฑ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ
[startpage]
app_desc=ฮฮนฮฑ ฮฑฮฝฯฮดฯ
ฮฝฮท, ฮฑฯ
ฯฮฟ-ฯฮนฮปฮฟฮพฮตฮฝฮฟฯฮผฮตฮฝฮท ฯ
ฯฮทฯฮตฯฮฏฮฑ Git
install=ฮฯฮบฮฟฮปฮท ฮตฮณฮบฮฑฯฮฌฯฯฮฑฯฮท
-install_desc=ฮฯฮปฮฌ ฯฯฮญฮพฮต ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮฟฯ
ฮฑฮฝฯฮนฯฯฮฟฮนฯฮตฮฏ ฯฯฮทฮฝ ฯฮปฮฑฯฯฯฯฮผฮฑ ฯฮฟฯ
, ฮตฮณฮบฮฑฯฮญฯฯฮทฯฮต ฯฮฟ ฮผฮต ฯฮฟ Docker ฮฎ ฯฯฮทฯฮนฮผฮฟฯฮฟฮฏฮทฯฮต ฮญฮฝฮฑ ฯฮฑฮบฮญฯฮฟ ฮปฮฟฮณฮนฯฮผฮนฮบฮฟฯ .
+install_desc=ฮฯฮปฮฌ ฯฯฮญฮพฮต ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮฟฯ
ฮฑฮฝฯฮนฯฯฮฟฮนฯฮตฮฏ ฯฯฮทฮฝ ฯฮปฮฑฯฯฯฯฮผฮฑ ฯฮฟฯ
, ฮตฮณฮบฮฑฯฮญฯฯฮทฯฮต ฯฮฟ ฮผฮต ฯฮฟ Docker ฮฎ ฯฯฮทฯฮนฮผฮฟฯฮฟฮฏฮทฯฮต ฮญฮฝฮฑ ฯฮฑฮบฮญฯฮฟ ฮปฮฟฮณฮนฯฮผฮนฮบฮฟฯ .
platform=ฮคฯฮญฯฮตฮน ฯฮฑฮฝฯฮฟฯ
-platform_desc=ฮคฮฟ Forgejo ฯฯฮญฯฮตฮน ฯฮต ฮบฮฌฮธฮต ฯฯฯฯฮทฮผฮฑ ฯฮฟฯ
ฯ
ฯฮฟฯฯฮทฯฮฏฮถฮตฮน ฮท ฮณฮปฯฯฯฮฑ Go , ฯฯฯฯ: Windows, macOS, Linux, ARM, ฮบฮปฯ. ฮฮนฮฌฮปฮตฮพฮต ฮฑฯ
ฯฯ ฯฮฟฯ
ฮฑฮณฮฑฯฮฌฯ!
+platform_desc=ฮคฮฟ Forgejo ฯฯฮญฯฮตฮน ฯฮต ฮบฮฌฮธฮต ฮตฮปฮตฯฮธฮตฯฮฟ ฮปฮตฮนฯฮฟฯ
ฯฮณฮนฮบฯ ฯฯฯฯฮทฮผฮฑ, ฯฯฯฯ ฯฮฟ Linux ฮฎ ฯฮฟ FreeBSD, ฮบฮฑฮธฯฯ ฮบฮฑฮน ฯฮต ฮดฮนฮฌฯฮฟฯฮฑ ฮตฮฏฮดฮท ฮตฯฮตฮพฮตฯฮณฮฑฯฯฯฮฝ. ฮฮนฮฌฮปฮตฮพฮต ฮฑฯ
ฯฯ ฯฮฟฯ
ฮฑฮณฮฑฯฮฌฯ!
lightweight=ฮฮปฮฑฯฯฯ
lightweight_desc=ฮคฮฟ Forgejo ฮญฯฮตฮน ฮตฮปฮฌฯฮนฯฯฮตฯ ฮฑฯฮฑฮนฯฮฎฯฮตฮนฯ, ฮผฯฮฟฯฮตฮฏฯ ฮบฮฑฮน ฮฝฮฑ ฯฮฟ ฯฯฮญฮพฮตฮนฯ ฯฮต ฮญฮฝฮฑ ฯฯฮทฮฝฯ Raspberry Pi. ฮฮพฮฟฮนฮบฮฟฮฝฯฮผฮทฯฮต ฮตฮฝฮญฯฮณฮตฮนฮฑ!
license=ฮฮฝฮฟฮนฮบฯฮฟฯ ฮบฯฮดฮนฮบฮฑ
-license_desc=ฮฮฑฯฮญฮฒฮฑฯฮต ฯฮฟ Forgejo ! ฮฯฮฏฯฮทฯ, ฮผฯฮฟฯฮตฮฏฯ ฮฝฮฑ ฮผฮฑฯ ฮฒฮฟฮทฮธฮฎฯฮตฮนฯ ฮฝฮฑ ฯฮฟ ฮฒฮตฮปฯฮนฯฯฮฟฯ
ฮผฮต ฮผฮต ฯฮนฯ ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮญฯ ฯฮฟฯ
. ฮงฯฯฮฏฯ ฮฝฯฯฮฟฯฮฎ!
+license_desc=ฮฮฑฯฮญฮฒฮฑฯฮต ฯฮฟ Forgejo ! ฮฯฮฏฯฮทฯ, ฮผฯฮฟฯฮตฮฏฯ ฮฝฮฑ ฮผฮฑฯ ฮฒฮฟฮทฮธฮฎฯฮตฮนฯ ฮฝฮฑ ฯฮฟ ฮฒฮตฮปฯฮนฯฯฮฟฯ
ฮผฮต ฮผฮต ฯฮนฯ ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮญฯ ฯฮฟฯ
. ฮงฯฯฮฏฯ ฮฝฯฯฮฟฯฮฎ!
[install]
install=ฮฮณฮบฮฑฯฮฌฯฯฮฑฯฮท
@@ -238,13 +260,13 @@ err_empty_db_path=ฮ ฮดฮนฮฑฮดฯฮฟฮผฮฎ ฯฮทฯ ฮฒฮฌฯฮทฯ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ SQLit
no_admin_and_disable_registration=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮทฮฝ ฮนฮดฮนฮฟ-ฮตฮณฮณฯฮฑฯฮฎ ฯฯฮฎฯฯฮท ฯฯฯฮฏฯ ฮฝฮฑ ฮญฯฮตฯฮต ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฮน ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮนฮบฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ.
err_empty_admin_password=ฮ ฮบฯฮดฮนฮบฯฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮฟฯ
ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯฯ.
err_empty_admin_email=ฮคฮฟ email ฯฮฟฯ
ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯ.
-err_admin_name_is_reserved=ฮคฮฟ ฮฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฯฮฟฯ
ฮฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟ, ฮตฮฏฮฝฮฑฮน ฮดฮตฯฮผฮตฯ
ฮผฮญฮฝฮฟ
+err_admin_name_is_reserved=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฯฮฟฯ
ฮฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟ, ฮฑฯ
ฯฯ ฯฮฟ ฯฮฝฮฟฮผฮฑ ฮตฮฏฮฝฮฑฮน ฮดฮตฯฮผฮตฯ
ฮผฮญฮฝฮฟ
err_admin_name_pattern_not_allowed=ฮคฮฟ ฮฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฯฮฟฯ
ฮฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟ, ฯฮฑฮนฯฮนฮฌฮถฮตฮน ฯฮต ฮผฮนฮฑ ฮดฮตฯฮผฮตฯ
ฮผฮญฮฝฮท ฮผฮฟฯฯฮฎ
-err_admin_name_is_invalid=ฮคฮฟ ฮฮฝฮฟฮผฮฑ ฮงฯฮฎฯฯฮท ฯฮฟฯ
ฮฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟ
+err_admin_name_is_invalid=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฯฮฟฯ
ฮฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟ
general_title=ฮฮตฮฝฮนฮบฮญฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ
app_name=ฮคฮฏฯฮปฮฟฯ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ
-app_name_helper=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮตฮนฯฮฌฮณฮตฯฮต ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฮทฯ ฮตฯฮฑฮนฯฮตฮฏฮฑฯ ฯฮฑฯ ฮตฮดฯ.
+app_name_helper=ฮฯฮฌฯฯฮต ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฮฟฯ
ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฮฑฯ ฮตฮดฯ. ฮฮฑ ฮตฮผฯฮฑฮฝฮฏฮถฮตฯฮฑฮน ฯฮต ฮบฮฌฮธฮต ฯฮตฮปฮฏฮดฮฑ.
repo_path=ฮคฮฟฯฮฟฮธฮตฯฮฏฮฑ ฮฑฯฯฮตฮฏฯฮฝ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ
repo_path_helper=ฮคฮฑ ฮฑฯฮฟฮผฮฑฮบฯฯ
ฯฮผฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ Git ฮธฮฑ ฮฑฯฮฟฮธฮทฮบฮตฯฮฟฮฝฯฮฑฮน ฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮฑฯฮฌฮปฮฟฮณฮฟ.
lfs_path=ฮคฮฟฯฮฟฮธฮตฯฮฏฮฑ ฮฑฯฯฮตฮฏฯฮฝ Git LFS
@@ -274,22 +296,22 @@ register_confirm=ฮฮฑ ฮฑฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮท ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮท ฯฮทฯ ฮดฮน
mail_notify=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮตฮนฮดฮฟฯฮฟฮนฮฎฯฮตฯฮฝ email
server_service_title=ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฮบฮฑฮน ฯ
ฯฮทฯฮตฯฮนฯฮฝ ฯฯฮฏฯฯฮฝ
offline_mode=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฮฟฯฮนฮบฮฎฯ ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮฑฯ
-offline_mode.description=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮท ฯฯฮฝ ฮดฮนฮบฯฯฯฮฝ ฮดฮนฮฑฮฝฮฟฮผฮฎฯ ฯฮตฯฮนฮตฯฮฟฮผฮญฮฝฮฟฯ
ฯฯฮฏฯฯฮฝ ฮบฮฑฮน ฯฮตฯฮฒฮฏฯฮตฯฮต ฯฮปฯฮฝ ฯฯฮฝ ฯฯฯฯฮฝ ฯฮฟฯฮนฮบฮฌ.
+offline_mode.description=ฮคฮฑ CDN ฯฯฮฏฯฯฮฝ ฮธฮฑ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮธฮฟฯฮฝ, ฮบฮฑฮน ฯฮปฮฑ ฯฮฑ ฮฑฯฯฮตฮฏฮฑ ฮธฮฑ ฯฮฑฯฮญฯฮฟฮฝฯฮฑฮน ฮฑฯฮฟฮบฮปฮตฮนฯฯฮนฮบฮฌ ฮฑฯฯ ฯฮฟฮฝ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ.
disable_gravatar=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท Gravatar
disable_gravatar.description=ฮคฮฟ Gravatar ฮบฮฑฮน ฮฌฮปฮปฮตฯ ฮตฮพฯฯฮตฯฮนฮบฮญฯ ฯฮทฮณฮญฯ ฮตฮนฮบฯฮฝฯฮฝ ฯฯฮฟฯฮฏฮป ฮธฮฑ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮธฮฟฯฮฝ. ฮฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮผฮฏฮฑ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮท ฮตฮนฮบฯฮฝฮฑ ฯฯฮฟฯฮฏฮป, ฮตฮบฯฯฯ ฮฑฮฝ ฮฟ ฯฯฮฎฯฯฮทฯ ฮฑฮฝฮตฮฒฮฌฯฮตฮน ฮฑฯฯ ฮผฯฮฝฮฟฯ ฯฮฟฯ
ฮญฮฝฮฑ avatar.
federated_avatar_lookup=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮฑฯฮฟฮบฮตฮฝฯฯฯฮผฮญฮฝฯฮฝ ฮตฮนฮบฯฮฝฯฮฝ ฯฯฮฟฯฮฏฮป
federated_avatar_lookup.description=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮฑฯฮฟฮบฮตฮฝฯฯฯฮผฮญฮฝฮทฯ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮทฯ ฮตฮนฮบฯฮฝฯฮฝ ฯฯฮฟฯฮฏฮป ฮผฮญฯฯ Libravatar.
disable_registration=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮฑฯ
ฯฮฟฮตฮณฮณฯฮฑฯฮฎฯ
-disable_registration.description=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮฑฯ
ฯฮฟฮตฮณฮณฯฮฑฯฮฎฯ ฯฯฮฎฯฯฮท. ฮฯฮฝฮฟ ฮฟฮน ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮญฯ ฮธฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮฟฯ
ฮฝ ฮฝฮญฮฟฯ
ฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯฯ ฯฯฮทฯฯฯฮฝ.
-allow_only_external_registration.description=ฮฮฑ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฮตฮณฮณฯฮฑฯฮฎ ฮผฯฮฝฮฟ ฮผฮญฯฯ ฮตฮพฯฯฮตฯฮนฮบฯฮฝ ฯ
ฯฮทฯฮตฯฮนฯฮฝ
+disable_registration.description=ฮฯฮฝฮฟ ฮฟฮน ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮญฯ ฮธฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮฟฯ
ฮฝ ฮฝฮญฮฟฯ
ฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯฯ ฯฯฮทฯฯฯฮฝ. ฮฃฮฑฯ ฯฯ
ฮฝฮนฯฯฮฟฯฮผฮต ฮฝฮฑ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮนฯ ฮตฮณฮณฯฮฑฯฮญฯ, ฮตฮบฯฯฯ ฮฑฮฝ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฯฯฮฟฯฯฮญฯฮตฯฮต ฯฮฟฮฝ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฮฑฯ ฯฮต ฮญฮฝฮฑ ฮตฯ
ฯฯ ฮบฮฟฮนฮฝฯ ฮบฮฑฮน ฮตฮฏฯฯฮต ฮญฯฮฟฮนฮผฮฟฯ ฮฝฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฯฮต ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯฯ ฯฮฟฯ
ฮธฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮฟฯฮฝ ฮณฮนฮฑ spam.
+allow_only_external_registration.description=ฮฮน ฯฯฮฎฯฯฮตฯ ฮธฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮฟฯ
ฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯฯ ฮผฯฮฝฮฟ ฮผฮญฯฯ ฮตฮพฯฯฮตฯฮนฮบฯฮฝ ฯ
ฯฮทฯฮตฯฮนฯฮฝ.
openid_signin=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฝฮดฮตฯฮทฯ ฮผฮญฯฯ OpenID
openid_signin.description=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฝฮดฮตฯฮทฯ ฯฯฮฎฯฯฮท ฮผฮญฯฯ OpenID.
openid_signup=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮตฮณฮณฯฮฑฯฯฮฝ ฮผฮญฯฯ OpenID
openid_signup.description=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮนฮดฮนฮฟฮตฮณฮณฯฮฑฯฮฎฯ ฯฯฮทฯฯฯฮฝ ฮผฮต ฮฒฮฌฯฮท ฯฮฟ OpenID.
enable_captcha=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท CAPTCHA ฯฯฮทฮฝ ฮตฮณฮณฯฮฑฯฮฎ
-enable_captcha.description=ฮฮฑ ฮฑฯฮฑฮนฯฮตฮฏฯฮฑฮน CAPTCHA ฮณฮนฮฑ ฯฮทฮฝ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ.
+enable_captcha.description=ฮฮฑ ฮฑฯฮฑฮนฯฮตฮฏฯฮฑฮน CAPTCHA ฮณฮนฮฑ ฯฮทฮฝ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฮฝ.
require_sign_in_view=ฮฮฑ ฮฑฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮตฮฏฯฮฟฮดฮฟฯ ฮณฮนฮฑ ฯฮทฮฝ ฯฯฮฟฮฒฮฟฮปฮฎ ฯฮตฯฮนฮตฯฮฟฮผฮญฮฝฯฮฝ
-require_sign_in_view.description=ฮ ฮตฯฮนฮฟฯฮนฯฮผฯฯ ฯฮทฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮต ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ. ฮฮน ฮตฯฮนฯฮบฮญฯฯฮตฯ ฮธฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮผฯฮฝฮฟ ฮฝฮฑ ฮดฮฟฯ
ฮฝ ฯฮนฯ ฯฮตฮปฮฏฮดฮตฯ ฮตฮนฯฯฮดฮฟฯ
ฮบฮฑฮน ฮตฮณฮณฯฮฑฯฮฎฯ.
+require_sign_in_view.description=ฮคฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฯฮฟฯ
ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฮฑฯ ฮธฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฯฮฟ ฮฒฮปฮญฯฮฟฯ
ฮฝ ฮผฯฮฝฮฟ ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฮน ฯฯฮฎฯฯฮตฯ. ฮฮน ฮตฯฮนฯฮบฮญฯฯฮตฯ ฮธฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮผฯฮฝฮฟ ฮฝฮฑ ฮดฮฟฯ
ฮฝ ฯฮนฯ ฯฮตฮปฮฏฮดฮตฯ ฮตฮนฯฯฮดฮฟฯ
ฮบฮฑฮน ฮตฮณฮณฯฮฑฯฮฎฯ.
admin_setting.description=ฮ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮตฮฝฯฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮตฮฏฮฝฮฑฮน ฯฯฮฟฮฑฮนฯฮตฯฮนฮบฮฎ. ฮ ฯฯฯฯฮฟฯ ฮตฮณฮณฮตฮณฯฮฑฮผฮผฮญฮฝฮฟฯ ฯฯฮฎฯฯฮทฯ ฮธฮฑ ฮณฮฏฮฝฮตฮน ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ.
admin_title=ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ
admin_name=ฮฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ
@@ -310,11 +332,11 @@ save_config_failed=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮฑฯฮฟฮธฮฎฮบฮตฯ
ฯฮทฯ ฯฯ
ฮธฮผฮฏฯฮตฯฮฝ: %
invalid_admin_setting=ฮ ฯฯฮธฮผฮนฯฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮท: %v
invalid_log_root_path=ฮ ฯฮฟฯฮฟฮธฮตฯฮฏฮฑ ฮฑฯฯฮตฮฏฯฮฝ ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮท: %v
default_keep_email_private=ฮฯฯฮบฯฯ
ฯฮท ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฯฮฝ email ฮฑฯฯ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ
-default_keep_email_private.description=ฮฯฯฮบฯฯ
ฯฮท ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฯฮฝ email ฯฯฮฝ ฮฝฮญฯฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฮฝ ฯฯฮฎฯฯฮท ฯฮฑฮฝ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ.
+default_keep_email_private.description=ฮฮฑ ฮณฮฏฮฝฮตฯฮฑฮน ฮฑฯฯฮบฯฯ
ฯฮท ฯฮทฯ ฮดฮนฮตฯฮธฯ
ฮฝฯฮทฯ email ฯฮต ฮฝฮญฮฟฯ
ฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯฯ ฮฑฯฯ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ, ฮญฯฯฮน ฯฯฯฮต ฮฝฮฑ ฮผฮทฮฝ ฮดฮนฮฑฯฯฮตฯฯฮฟฯ
ฮฝ ฮฑฮผฮญฯฯฯ ฮผฮตฯฮฌ ฯฮทฮฝ ฮตฮณฮณฯฮฑฯฮฎ ฯฮฟฯ
ฯ.
default_allow_create_organization=ฮฮฑ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฟฯฮณฮฑฮฝฮนฯฮผฯฮฝ ฮฑฯฯ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ
-default_allow_create_organization.description=ฮฯฮนฯฯฮญฯฯฮต ฯฮต ฮฝฮญฮฟฯ
ฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯฯ ฯฯฮทฯฯฯฮฝ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฟฯฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯฯ ฯฮฑฮฝ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ.
+default_allow_create_organization.description=ฮฮฑ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฯฯฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฟฯฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯฯ ฮฑฯฯ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ. ฮฮฝ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฯฮต ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฯฯฮธฮผฮนฯฮท, ฯฯฯฮต ฮฟ ฯฯฮฎฯฯฮทฯ ฮธฮฑ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฮน ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯฯ ฮผฯฮฝฮฟ ฮผฮต ฯฮทฮฝ ฮญฮณฮบฯฮนฯฮท ฮตฮฝฯฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ.
default_enable_timetracking=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฯฯฯฮฝฮฟฯ
ฮฑฯฯ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ
-default_enable_timetracking.description=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฯฯฯฮฝฮฟฯ
ฮณฮนฮฑ ฮฝฮญฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฑฮฝ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ.
+default_enable_timetracking.description=ฮฮฑ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮท ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮฑ ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฯฯฯฮฝฮฟฯ
ฯฮต ฮฝฮญฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฮฑฯฯ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ.
no_reply_address=Domain ฮบฯฯ
ฯฯฮฝ email
no_reply_address_helper=ฮฮฝฮฟฮผฮฑ ฯฮฟฮผฮญฮฑ (domain) ฮณฮนฮฑ ฯฯฮฎฯฯฮตฯ ฮผฮต ฮผฮนฮฑ ฮบฯฯ
ฯฮฎ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email. ฮฮนฮฑ ฯฮฑฯฮฌฮดฮตฮนฮณฮผฮฑ, ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท 'nikos' ฮธฮฑ ฯฯ
ฮฝฮดฮตฮธฮตฮฏ ฯฯฮฟ Git ฯฯ 'nikos@noreply.example.org' ฮฑฮฝ ฮฟ ฮบฯฯ
ฯฯฯ ฯฮฟฮผฮญฮฑฯ email ฮญฯฮตฮน ฮฟฯฮนฯฯฮตฮฏ ฯฯ 'noreply.example.org'.
password_algorithm=ฮฮปฮณฯฯฮนฮธฮผฮฟฯ hash ฮณฮนฮฑ ฮบฯฮดฮนฮบฮฟฯฯ
@@ -327,19 +349,22 @@ allow_dots_in_usernames = ฮฯฮนฯฯฮญฯฮตฮน ฯฮทฮฝ ฯฯฮฎฯฮท ฯฮตฮปฮตฮฏฯฮฝ ฯ
enable_update_checker_helper_forgejo = ฮฮฑ ฮณฮฏฮฝฮตฯฮฑฮน ฯฮฑฮบฯฮนฮบฮฌ ฮญฮปฮตฮณฯฮฟฯ ฮณฮนฮฑ ฮฝฮญฮตฯ ฮตฮบฮดฯฯฮตฮนฯ ฯฮฟฯ
Forgejo ฮตฮปฮญฮณฯฮฟฮฝฯฮฑฯ ฮผฮฏฮฑ ฮตฮณฮณฯฮฑฯฮฎ DNS TXT ฯฯฮฟ release.forgejo.org.
smtp_from_invalid = ฮ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท ฯฮฟฯ
ฯฮตฮดฮฏฮฟฯ
ยซฮฯฮฟฯฯฮฟฮปฮฎ email ฯฯยป ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮท
config_location_hint = ฮฯ
ฯฮญฯ ฮฟฮน ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฮธฮฑ ฮฑฯฮฟฮธฮทฮบฮตฯ
ฯฮฟฯฮฝ ฯฯฮทฮฝ ฮฑฮบฯฮปฮฟฯ
ฮธฮท ฯฮฟฯฮฟฮธฮตฯฮฏฮฑ:
+allow_only_external_registration = ฮฮฑ ฮตฯฮนฯฯฮญฯฮฟฮฝฯฮฑฮน ฮฟฮน ฮตฮณฮณฯฮฑฯฮญฯ ฮผฯฮฝฮฟ ฮผฮญฯฯ ฮตฮพฯฯฮตฯฮนฮบฯฮฝ ฯ
ฯฮทฯฮตฯฮนฯฮฝ
+app_slogan = Slogan ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ
+app_slogan_helper = ฮฯฮฌฯฯฮต ฯฮฟ slogan ฯฮฟฯ
ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฮฑฯ ฮตฮดฯ. ฮฯฮฎฯฯฮต ฮบฮตฮฝฯ ฮณฮนฮฑ ฮฝฮฑ ฯฮฟ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฯฮต.
[home]
uname_holder=ฮฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฮฎ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email
password_holder=ฮฯฮดฮนฮบฯฯ ฮ ฯฯฯฮฒฮฑฯฮทฯ
-switch_dashboard_context=ฮฮฝฮฑฮปฮปฮฑฮณฮฎ ฮ ฮตฯฮนฮตฯฮฟฮผฮญฮฝฯฮฝ ฮฯฯฮนฮบฮฟฯ ฮ ฮฏฮฝฮฑฮบฮฑ
+switch_dashboard_context=ฮฮฝฮฑฮปฮปฮฑฮณฮฎ ฯฮตฯฮนฮตฯฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯฮนฮบฮฟฯ ฯฮฏฮฝฮฑฮบฮฑ
my_repos=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฑ
show_more_repos=ฮ ฮตฯฮนฯฯฯฯฮตฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑโฆ
-collaborative_repos=ฮฃฯ
ฮฝฮตฯฮณฮฑฯฮนฮบฮฌ ฮฯฮฟฮธฮตฯฮฎฯฮนฮฑ
+collaborative_repos=ฮฃฯ
ฮฝฮตฯฮณฮฑฯฮนฮบฮฌ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ
my_orgs=ฮฯฮณฮฑฮฝฮนฯฮผฮฟฮฏ
my_mirrors=ฮคฮฑ ฮฮฝฯฮฏฮณฯฮฑฯฮฑ ฮฮฟฯ
view_home=ฮ ฯฮฟฮฒฮฟฮปฮฎ %s
search_repos=ฮฯฮตฮฏฯฮต ฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟโฆ
-filter=ฮฮปฮปฮฑ ฮฆฮฏฮปฯฯฮฑ
+filter=ฮฮปฮปฮฑ ฯฮฏฮปฯฯฮฑ
filter_by_team_repositories=ฮฆฮนฮปฯฯฮฌฯฮนฯฮผฮฑ ฮฑฮฝฮฌ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฮฟฮผฮฌฮดฮฑฯ
feed_of=ฮกฮฟฮฎ (feed) ฯฮฟฯ
ยซ%sยป
@@ -382,7 +407,7 @@ forks_one = %d fork
forks_few = %d forks
[auth]
-create_new_account=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
+create_new_account=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
register_helper_msg=ฮฯฮตฯฮต ฮฎฮดฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ; ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฯฯฯฮฑ!
social_register_helper_msg=ฮฯฮตฯฮต ฮฎฮดฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ; ฮฃฯ
ฮฝฮดฮญฯฯฮต ฯฮฟ ฯฯฯฮฑ!
disable_register_prompt=ฮฮน ฮตฮณฮณฯฮฑฯฮญฯ ฮตฮฏฮฝฮฑฮน ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ. ฮ ฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฮฝฮฑ ฮตฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฮตฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฟฯ
ฮนฯฯฮฟฯฯฯฮฟฯ
.
@@ -394,20 +419,20 @@ forgot_password_title=ฮฮญฯฮฑฯฮฑ ฯฮฟฮฝ ฮบฯฮดฮนฮบฯ ฮผฮฟฯ
forgot_password=ฮฮตฯฮฌฯฮฑฯฮต ฯฮฟฮฝ ฮบฯฮดฮนฮบฯ ฯฮฑฯ;
sign_up_now=ฮงฯฮตฮนฮฌฮถฮตฯฯฮต ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ; ฮฮณฮณฯฮฑฯฮตฮฏฯฮต ฯฯฯฮฑ.
sign_up_successful=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฮตฯฮนฯฯ
ฯฯฯ. ฮฮฑฮปฯฯ ฮฟฯฮฏฯฮฑฯฮต!
-confirmation_mail_sent_prompt=ฮฮฝฮฑ ฮฝฮญฮฟ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮญฯฮตฮน ฯฯฮฑฮปฮตฮฏ ฯฯฮทฮฝ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท %s . ฮฮนฮฑ ฯฮทฮฝ ฮฟฮปฮฟฮบฮปฮฎฯฯฯฮท ฯฮทฯ ฮตฮณฮณฯฮฑฯฮฎฯ ฯฮฑฯ, ฯฮฑฯฮฑฮบฮฑฮปฯ ฮตฮปฮญฮณฮพฯฮต ฯฮฑ ฮตฮนฯฮตฯฯฯฮผฮตฮฝฮฑ ฯฮฑฯ ฮผฮญฯฮฑ ฯฯฮนฯ ฮตฯฯฮผฮตฮฝฮตฯ %s.
+confirmation_mail_sent_prompt=ฮฮฝฮฑ ฮฝฮญฮฟ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮญฯฮตฮน ฯฯฮฑฮปฮตฮฏ ฯฯฮทฮฝ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท %s . ฮฮนฮฑ ฯฮทฮฝ ฮฟฮปฮฟฮบฮปฮฎฯฯฯฮท ฯฮทฯ ฮตฮณฮณฯฮฑฯฮฎฯ ฯฮฑฯ, ฯฮฑฯฮฑฮบฮฑฮปฯ ฮตฮปฮญฮณฮพฯฮต ฯฮฑ ฮตฮนฯฮตฯฯฯฮผฮตฮฝฮฑ ฯฮฑฯ ฮบฮฑฮน ฯฮฑฯฮฎฯฯฮต ฯฮฟ link ฯฮฟฯ
ฯฮฑฯ ฮญฯฮฟฯ
ฮผฮต ฯฯฮตฮฏฮปฮตฮน ฮผฮญฯฮฑ ฯฯฮนฯ ฮตฯฯฮผฮตฮฝฮตฯ %s.
must_change_password=ฮฮฝฮทฮผฮตฯฯฯฯฮต ฯฮฟฮฝ ฮบฯฮดฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮฑฯ
allow_password_change=ฮฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮฑฯฯ ฯฮฟ ฯฯฮฎฯฯฮท ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮตฮน ฯฮฟฮฝ ฮบฯฮดฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ (ฯฯ
ฮฝฮนฯฯฯฮผฮตฮฝฮฟ)
-reset_password_mail_sent_prompt=ฮฮฝฮฑ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮญฯฮตฮน ฯฯฮฑฮปฮตฮฏ ฯฯฮฟ %s . ฮฮนฮฑ ฯฮทฮฝ ฮฟฮปฮฟฮบฮปฮฎฯฯฯฮท ฯฮทฯ ฮดฮนฮฑฮดฮนฮบฮฑฯฮฏฮฑฯ ฮฑฮฝฮฌฮบฯฮทฯฮทฯ ฯฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฯฮฑฯ, ฯฮฑฯฮฑฮบฮฑฮปฯ ฮตฮปฮญฮณฮพฯฮต ฯฮฑ ฮตฮนฯฮตฯฯฯฮผฮตฮฝฮฑ ฯฮฑฯ ฯฯฮนฯ ฮตฯฯฮผฮตฮฝฮตฯ %s.
-active_your_account=ฮฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฯฮต ฮคฮฟ ฮฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฮฃฮฑฯ
+reset_password_mail_sent_prompt=ฮฮฝฮฑ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮญฯฮตฮน ฯฯฮฑฮปฮตฮฏ ฯฯฮฟ %s . ฮฮนฮฑ ฮฝฮฑ ฮฟฮปฮฟฮบฮปฮทฯฯฯฮตฯฮต ฯฮทฮฝ ฮดฮนฮฑฮดฮนฮบฮฑฯฮฏฮฑ ฮฑฮฝฮฌฮบฯฮทฯฮทฯ ฯฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฯฮฑฯ, ฯฮฑฯฮฑฮบฮฑฮปฯ ฮตฮปฮญฮณฮพฯฮต ฯฮฑ ฮตฮนฯฮตฯฯฯฮผฮตฮฝฮฑ ฯฮฑฯ ฮบฮฑฮน ฯฮฑฯฮฎฯฯฮต ฯฯฮฟ link ฯฮฟฯ
ฯฮฑฯ ฮญฯฮฟฯ
ฮผฮต ฯฯฮตฮฏฮปฮตฮน ฯฯฮนฯ ฮตฯฯฮผฮตฮฝฮตฯ %s.
+active_your_account=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
account_activated=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฮญฯฮตฮน ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮธฮตฮฏ
-prohibit_login=ฮฮตฮฝ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฯฯฮฝฮดฮตฯฮท
-prohibit_login_desc=ฮฮตฮฝ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฯฯฮฝฮดฮตฯฮท ฯฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ, ฯฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฮตฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฑฯ.
+prohibit_login=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฮฑฯ ฮญฯฮตฮน ฮฑฮฝฮฑฯฯฮฑฮปฮตฮฏ
+prohibit_login_desc=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฮฑฯ ฮญฯฮตฮน ฮฑฮฝฮฑฯฯฮฑฮปฮตฮฏ. ฮฮนฮฑ ฮฝฮฑ ฮพฮฑฮฝฮฑฮฑฯฮฟฮบฯฮฎฯฮตฯฮต ฯฯฯฯฮฒฮฑฯฮท, ฮตฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฑฯ.
resent_limit_prompt=ฮฯฮตฯฮต ฮฎฮดฮท ฮถฮทฯฮฎฯฮตฮน ฮญฮฝฮฑ email ฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮทฯ ฯฯฯฯฯฮฑฯฮฑ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฯฮตฯฮนฮผฮญฮฝฮตฯฮต 3 ฮปฮตฯฯฮฌ ฮบฮฑฮน ฯฯฮฟฯฯฮฑฮธฮฎฯฯฮต ฮพฮฑฮฝฮฌ.
has_unconfirmed_mail=ฮฮตฮนฮฌ %s, ฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท ฮทฮปฮตฮบฯฯฮฟฮฝฮนฮบฮฟฯ ฯฮฑฯฯ
ฮดฯฮฟฮผฮตฮฏฮฟฯ
ฯฮฑฯ (%s ) ฮดฮตฮฝ ฮญฯฮตฮน ฮตฯฮนฮฒฮตฮฒฮฑฮนฯฮธฮตฮฏ ฮฑฮบฯฮผฮฑ. ฮฮฌฮฝ ฮดฮตฮฝ ฮญฯฮตฯฮต ฮปฮฌฮฒฮตฮน ฮบฮฌฯฮฟฮนฮฟ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮฎ ฮฑฮฝ ฯฯฮตฮนฮฌฮถฮตฯฯฮต ฮญฮฝฮฑ ฮฝฮญฮฟ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ, ฯฮฑฯฮฑฮบฮฑฮปฯ ฯฮฑฯฮฎฯฯฮต ฯฮฟ ฯฮฑฯฮฑฮบฮฌฯฯ ฮบฮฟฯ
ฮผฯฮฏ.
resend_mail=ฮฮฌฮฝฯฮต ฮบฮปฮนฮบ ฮตฮดฯ ฮณฮนฮฑ ฮฝฮฑ ฯฯฮตฮฏฮปฮตฯฮต ฮพฮฑฮฝฮฌ ฯฮฟ email ฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮทฯ
email_not_associate=ฮ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท ฮทฮปฮตฮบฯฯฮฟฮฝฮนฮบฮฟฯ ฯฮฑฯฯ
ฮดฯฮฟฮผฮตฮฏฮฟฯ
ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฯฯ
ฯฯฮตฯฮนฯฮผฮญฮฝฮท ฮผฮต ฮบฮฌฯฮฟฮนฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ.
-send_reset_mail=ฮฯฮฟฯฯฮฟฮปฮฎ Email ฮฮฝฮฌฮบฯฮทฯฮทฯ ฮฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
-reset_password=ฮฮฝฮฌฮบฯฮทฯฮท ฮฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
+send_reset_mail=ฮฯฮฟฯฯฮฟฮปฮฎ email ฮฑฮฝฮฌฮบฯฮทฯฮทฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
+reset_password=ฮฮฝฮฌฮบฯฮทฯฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
invalid_code=ฮ ฮบฯฮดฮนฮบฯฯ ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟฯ ฮฎ ฮญฯฮตฮน ฮปฮฎฮพฮตฮน.
invalid_code_forgot_password=ฮ ฮบฯฮดฮนฮบฯฯ ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮญฯฮตฮน ฮปฮฎฮพฮตฮน ฮฎ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟฯ. ฮ ฮฑฯฮฎฯฯฮต ฮตฮดฯ ฮณฮนฮฑ ฮฝฮฑ ฮพฮฑฮฝฮฑฮพฮตฮบฮนฮฝฮฎฯฮตฯฮต ฯฮทฮฝ ฮดฮนฮฑฮดฮนฮบฮฑฯฮฏฮฑ.
invalid_password=ฮ ฮบฯฮดฮนฮบฯฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮฑฯ ฮดฮตฮฝ ฯฮฑฮนฯฮนฮฌฮถฮตฮน ฮผฮต ฯฮฟฮฝ ฮบฯฮดฮนฮบฯ ฯฮฟฯ
ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฮธฮทฮบฮต ฮณฮนฮฑ ฯฮท ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ.
@@ -424,11 +449,11 @@ twofa_scratch_token_incorrect=ฮ ฮบฯฮดฮนฮบฯฯ ฮผฮนฮฑฯ ฯฯฮฎฯฮทฯ ฮตฮฏฮฝฮฑฮน
login_userpass=ฮฮฏฯฮฟฮดฮฟฯ
tab_openid=OpenID
oauth_signup_tab=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฝฮญฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
-oauth_signup_title=ฮฮปฮฟฮบฮปฮฎฯฯฯฮท ฮฮญฮฟฯ
ฮฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
-oauth_signup_submit=ฮฮปฮฟฮบฮปฮทฯฯฮผฮญฮฝฮฟฯ ฮฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ
+oauth_signup_title=ฮฮปฮฟฮบฮปฮฎฯฯฯฮท ฮฝฮญฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
+oauth_signup_submit=ฮฮปฮฟฮบฮปฮฎฯฯฯฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
oauth_signin_tab=ฮฃฯฮฝฮดฮตฯฮท ฮผฮต ฯ
ฯฮฌฯฯฯฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ
-oauth_signin_title=ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฮตฮณฮบฯฮฏฮฝฮตฯฮต ฯฮฟฮฝ ฮฃฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟ ฮฮฟฮณฮฑฯฮนฮฑฯฮผฯ
-oauth_signin_submit=ฮฃฯฮฝฮดฮตฯฮท ฮฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
+oauth_signin_title=ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฮตฮณฮบฯฮฏฮฝฮตฯฮต ฯฮฟฮฝ ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ
+oauth_signin_submit=ฮฃฯฮฝฮดฮตฯฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
oauth.signin.error=ฮ ฮฑฯฮฟฯ
ฯฮนฮฌฯฯฮทฮบฮต ฯฯฮฌฮปฮผฮฑ ฮบฮฑฯฮฌ ฯฮทฮฝ ฮตฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฯฮฟฯ
ฮฑฮนฯฮฎฮผฮฑฯฮฟฯ ฮตฮพฮฟฯ
ฯฮนฮฟฮดฯฯฮทฯฮทฯ. ฮฮฌฮฝ ฮฑฯ
ฯฯ ฯฮฟ ฯฯฮฌฮปฮผฮฑ ฮตฯฮนฮผฮญฮฝฮตฮน, ฯฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฮตฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฟฯ
ฮนฯฯฮฟฯฯฯฮฟฯ
.
oauth.signin.error.access_denied=ฮ ฮฑฮฏฯฮทฯฮท ฮตฮพฮฟฯ
ฯฮนฮฟฮดฯฯฮทฯฮทฯ ฮฑฯฮฟฯฯฮฏฯฮธฮทฮบฮต.
oauth.signin.error.temporarily_unavailable=ฮ ฮตฮพฮฟฯ
ฯฮนฮฟฮดฯฯฮทฯฮท ฮฑฯฮญฯฯ
ฯฮต ฮตฯฮตฮนฮดฮฎ ฮฟ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎฯ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮทฯ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮฟฯ ฯฯฮฟฯฯฯฮนฮฝฮฌ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฯฯฮฟฯฯฮฑฮธฮฎฯฯฮต ฮพฮฑฮฝฮฌ ฮฑฯฮณฯฯฮตฯฮฑ.
@@ -444,12 +469,12 @@ email_domain_blacklisted=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮตฮณฮณฯฮฑฯฮตฮฏฯฮต ฮผฮต
authorize_application=ฮฮพฮฟฯ
ฯฮนฮฟฮดฯฯฮทฯฮท ฮฯฮฑฯฮผฮฟฮณฮฎฯ
authorize_redirect_notice=ฮฮฑ ฮผฮตฯฮฑฯฮตฯฮธฮตฮฏฯฮต ฯฯฮฟ %s ฮตฮฌฮฝ ฮตฮพฮฟฯ
ฯฮนฮฟฮดฮฟฯฮฎฯฮตฯฮต ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฮตฯฮฑฯฮผฮฟฮณฮฎ.
authorize_application_created_by=ฮฯ
ฯฮฎ ฮท ฮตฯฮฑฯฮผฮฟฮณฮฎ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฮฑฯฯ %s.
-authorize_application_description=ฮฮฌฮฝ ฯฮฑฯฮฑฯฯฯฮฎฯฮตฯฮต ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮท, ฮธฮฑ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮญฯฮตฮน ฯฯฯฯฮฒฮฑฯฮท ฮบฮฑฮน ฮฝฮฑ ฮณฯฮฌฯฮตฮน ฯฮต ฯฮปฮตฯ ฯฮนฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฯฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฯฮฑฯ, ฯฯ
ฮผฯฮตฯฮนฮปฮฑฮผฮฒฮฑฮฝฮฟฮผฮญฮฝฯฮฝ ฯฯฮฝ ฮนฮดฮนฯฯฮนฮบฯฮฝ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ ฮบฮฑฮน ฮฟฯฮณฮฑฮฝฮนฯฮผฯฮฝ.
+authorize_application_description=ฮฮฝ ฯฮฑฯฮฑฯฯฯฮฎฯฮตฯฮต ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮท, ฮธฮฑ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮดฮนฮฑฮฒฮฌฯฮตฮน ฮบฮฑฮน ฮฝฮฑ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮตฮฏ ฯฮปฮตฯ ฯฮนฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฯฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฯฮฑฯ, ฯฯ
ฮผฯฮตฯฮนฮปฮฑฮผฮฒฮฑฮฝฮฟฮผฮญฮฝฯฮฝ ฯฯฮฝ ฮนฮดฮนฯฯฮนฮบฯฮฝ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ ฮบฮฑฮน ฮฟฯฮณฮฑฮฝฮนฯฮผฯฮฝ.
authorize_title=ฮฮฏฯฯฮต ฮฒฮญฮฒฮฑฮนฮฟฮน ฯฯฯ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฮดฯฯฮตฯฮต ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฯฯฮทฮฝ ฮตฯฮฑฯฮผฮฟฮณฮฎ ยซ%sยป;
authorization_failed=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮตฮพฮฟฯ
ฯฮนฮฟฮดฯฯฮทฯฮทฯ
authorization_failed_desc=ฮ ฮตฮพฮฟฯ
ฯฮนฮฟฮดฯฯฮทฯฮท ฮฑฯฮญฯฯ
ฯฮต ฮตฯฮตฮนฮดฮฎ ฮตฮฝฯฮฟฯฮฏฯฯฮทฮบฮต ฮผฮนฮฑ ฮผฮท ฮญฮณฮบฯ
ฯฮท ฮฑฮฏฯฮทฯฮท. ฮ ฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฮตฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฯฯ
ฮฝฯฮทฯฮทฯฮฎ ฯฮทฯ ฮตฯฮฑฯฮผฮฟฮณฮฎฯ ฯฮฟฯ
ฯฯฮฟฯฯฮฑฮธฮฎฯฮฑฯฮต ฮฝฮฑ ฮตฮพฮฟฯ
ฯฮนฮฟฮดฮฟฯฮฎฯฮตฯฮต.
sspi_auth_failed=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮทฯ SSPI
-password_pwned=ฮ ฮบฯฮดฮนฮบฯฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮฟฯ
ฮตฯฮนฮปฮญฮพฮฑฯฮต ฮฒฯฮฏฯฮบฮตฯฮฑฮน ฯฮต ฮผฮนฮฑ ฮปฮฏฯฯฮฑ ฮบฮปฮตฮผฮผฮญฮฝฯฮฝ ฮบฯฮดฮนฮบฯฮฝ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮฟฯ
ฯฯฮฟฮทฮณฮฟฯ
ฮผฮญฮฝฯฯ ฮตฮบฯฮญฮธฮทฮบฮฑฮฝ ฯฮต ฯฮฑฯฮฑฮฒฮฏฮฑฯฮท ฮดฮทฮผฯฯฮนฯฮฝ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮดฮฟฮบฮนฮผฮฌฯฯฮต ฮพฮฑฮฝฮฌ ฮผฮต ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฯ ฮบฯฮดฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฮบฮฑฮน ฯฮบฮตฯฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮตฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฯฮดฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฯฮฟฯ
ฮฑฮปฮปฮฟฯ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน.
+password_pwned=ฮ ฮบฯฮดฮนฮบฯฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮฟฯ
ฮตฯฮนฮปฮญฮพฮฑฯฮต ฮฒฯฮฏฯฮบฮตฯฮฑฮน ฯฮต ฮผฮนฮฑ ฮปฮฏฯฯฮฑ ฮบฮปฮตฮผฮผฮญฮฝฯฮฝ ฮบฯฮดฮนฮบฯฮฝ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮฟฯ
ฯฯฮฟฮทฮณฮฟฯ
ฮผฮญฮฝฯฯ ฮตฮบฯฮญฮธฮทฮบฮฑฮฝ ฯฮต ฯฮฑฯฮฑฮฒฮฏฮฑฯฮท ฮดฮทฮผฯฯฮนฯฮฝ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮดฮฟฮบฮนฮผฮฌฯฯฮต ฮพฮฑฮฝฮฌ ฮผฮต ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฯ ฮบฯฮดฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฮบฮฑฮน ฯฮบฮตฯฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮตฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฯฮดฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฯฮฟฯ
ฮฑฮปฮปฮฟฯ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน.
password_pwned_err=ฮฮตฮฝ ฮฎฯฮฑฮฝ ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฮฟฮปฮฟฮบฮปฮฎฯฯฯฮท ฯฮฟฯ
ฮฑฮนฯฮฎฮผฮฑฯฮฟฯ ฯฯฮฟฯ ฯฮฟ HaveIBeenPwned
change_unconfirmed_email_error = ฮฮตฮฝ ฮฎฯฮฑฮฝ ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฮฑฮปฮปฮฑฮณฮฎ ฯฮทฯ ฮดฮนฮตฯฮธฯ
ฮฝฯฮทฯ email: %v
last_admin = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฯฮต ฯฮฟฮฝ ฮผฮฟฮฝฮฑฮดฮนฮบฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ. ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฯ
ฯฮฌฯฯฮตฮน ฯฮฟฯ
ฮปฮฌฯฮนฯฯฮฟฮฝ ฮญฮฝฮฑฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ.
@@ -457,6 +482,13 @@ change_unconfirmed_email = ฮฮฝ ฮญฯฮตฯฮต ฮตฮนฯฮฌฮณฮตฮน ฮผฮฏฮฑ ฮปฮฑฮฝฮธฮฑฯฮผ
change_unconfirmed_email_summary = ฮฮปฮปฮฑฮณฮฎ ฯฮทฯ ฮดฮนฮตฯฮธฯ
ฮฝฯฮทฯ email ฯฯฮทฮฝ ฮฟฯฮฟฮฏฮฑ ฮธฮฑ ฯฯฮฑฮปฮตฮฏ ฯฮฟ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ.
tab_signin = ฮฮฏฯฮฟฮดฮฟฯ
tab_signup = ฮฮณฮณฯฮฑฯฮฎ
+hint_login = ฮฯฮตฯฮต ฮฎฮดฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ; ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮตฮดฯ!
+hint_register = ฮงฯฮตฮนฮฌฮถฮตฯฯฮต ฮญฮฝฮฑฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ; ฮฮฌฮฝฯฮต ฮตฮณฮณฯฮฑฯฮฎ ฮตฮดฯ!
+sign_up_button = ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ.
+back_to_sign_in = ฮฯฮนฯฯฯฮฟฯฮฎ ฯฯฮทฮฝ ฯฮตฮปฮฏฮดฮฑ ฮตฮนฯฯฮดฮฟฯ
+sign_in_openid = ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ ฮผฮต OpenID
+unauthorized_credentials = ฮคฮฑ ฮดฮนฮฑฯฮนฯฯฮตฯ
ฯฮฎฯฮนฮฑ ฯฯฮฝฮดฮตฯฮทฯ ฮตฮฏฮฝฮฑฮน ฮปฮฑฮฝฮธฮฑฯฮผฮญฮฝฮฑ ฮฎ ฮญฯฮฟฯ
ฮฝ ฮปฮฎฮพฮตฮน. ฮ ฯฮฟฯฯฮฑฮธฮฎฯฯฮต ฮพฮฑฮฝฮฌ ฯฮทฮฝ ฮตฮฝฮญฯฮณฮตฮนฮฑ ฮฎ ฮดฮตฮฏฯฮต %s ฮณฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ
+use_onetime_code = ฮงฯฮฎฯฮท ฮบฯฮดฮนฮบฮฟฯ ฮผฮฏฮฑฯ ฯฯฮฎฯฮทฯ
[mail]
view_it_on=ฮฮตฮฏฯฮต ฯฮฟ ฯฯฮฟ %s
@@ -473,7 +505,7 @@ activate_email=ฮฯฮนฮฒฮตฮฒฮฑฮนฯฯฯฮต ฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฑฯ
activate_email.title=%s, ฮตฯฮฑฮปฮทฮธฮตฯฯฯฮต ฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฑฯ
activate_email.text=ฮฮนฮฑ ฮฝฮฑ ฮตฯฮฑฮปฮทฮธฮตฯฯฮตฯฮต ฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฑฯ, ฯฮฑฯฮฑฮบฮฑฮปฯ ฯฮฑฯฮฎฯฯฮต ฯฮฟฮฝ ฮฑฮบฯฮปฮฟฯ
ฮธฮฟ ฯฯฮฝฮดฮตฯฮผฮฟ ฮผฮญฯฮฑ ฯฮต %s :
-register_notify=ฮฮฑฮปฯฯ ฮฎฮปฮธฮฑฯฮต ฯฯฮฟ Forgejo
+register_notify=ฮฮฑฮปฯฯ ฮฎฮปฮธฮฑฯฮต ฯฯฮฟ %s
register_notify.title=%[1]s, ฮบฮฑฮปฯฯ ฮฎฮปฮธฮฑฯฮต ฯฯฮฟ %[2]s
register_notify.text_1=ฮฑฯ
ฯฯ ฮตฮฏฮฝฮฑฮน ฯฮฟ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮตฮณฮณฯฮฑฯฮฎฯ ฯฮฑฯ ฮณฮนฮฑ ฯฮฟ %s!
register_notify.text_2=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฯฮฑฯ: %s
@@ -485,20 +517,20 @@ reset_password.text=ฮฯฯฯฮฟฮฝ ฯฮฟ ฮฑฮฏฯฮทฮผฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฮฑ
register_success=ฮ ฮตฮณฮณฯฮฑฯฮฎ ฮฟฮปฮฟฮบฮปฮทฯฯฮธฮทฮบฮต ฮตฯฮนฯฯ
ฯฯฯ
-issue_assigned.pull=ฮ/ฮ @%[1]s ฯฮฑฯ ฮญฯฮตฮน ฮฑฮฝฮฑฮธฮญฯฮตฮน ฯฯฮฟ pull request %[2]s ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ %[3]s.
-issue_assigned.issue=ฮ/ฮ @%[1]s ฯฮฑฯ ฮฑฮฝฮญฮธฮตฯฮต ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[2]s ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ %[3]s.
+issue_assigned.pull=ฮ/ฮ @%[1]s ฯฮฑฯ ฮญฯฮตฮน ฮฑฮฝฮฑฮธฮญฯฮตฮน ฯฯฮฟ pull request %[2]s ฯฯฮฟ repository %[3]s.
+issue_assigned.issue=ฮ/ฮ @%[1]s ฯฮฑฯ ฮฑฮฝฮญฮธฮตฯฮต ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[2]s ฯฯฮฟ repository %[3]s.
issue.x_mentioned_you=ฮ/ฮ @%s ฯฮฑฯ ฮฑฮฝฮญฯฮตฯฮต:
issue.action.force_push=ฮ/ฮ %[1]s ฮญฮบฮฑฮฝฮต force-push ฯฮฟ %[2]s ฮฑฯฯ %[3]s ฯฮต %[4]s.
-issue.action.push_1=ฮ/ฮ @%[1]s ฮญฮบฮฑฮฝฮต push ฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ %[3]d ฯฯฮฟ %[2]s
-issue.action.push_n=ฮ/ฮ @%[1]s ฮญฮบฮฑฮฝฮต push ฯฮนฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ %[3]d ฯฯฮฟ %[2]s
+issue.action.push_1=ฮ/ฮ @%[1]s ฮญฮบฮฑฮฝฮต push ฯฮฟ commit %[3]d ฯฯฮฟ %[2]s
+issue.action.push_n=ฮ/ฮ @%[1]s ฮญฮบฮฑฮฝฮต push ฯฮฑ commits %[3]d ฯฯฮฟ %[2]s
issue.action.close=ฮ/ฮ @%[1]s ฮญฮบฮปฮตฮนฯฮต ฯฮฟ #%[2]d.
issue.action.reopen=ฮ/ฮ @%[1]s ฮฌฮฝฮฟฮนฮพฮต ฮพฮฑฮฝฮฌ ฯฮฟ #%[2]d.
issue.action.merge=ฮ/ฮ @%[1]s ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮต ฯฮฟ #%[2]d ฯฯฮฟ %[3]s.
issue.action.approve=@%[1]s ฮตฮฝฮญฮบฯฮนฮฝฮต ฮฑฯ
ฯฯ ฯฮฟ pull request.
issue.action.reject=@%[1]s ฮถฮฎฯฮทฯฮต ฮฑฮปฮปฮฑฮณฮญฯ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ pull request.
issue.action.review=@%[1]s ฮฌฯฮทฯฮต ฯฯฯฮปฮนฮฟ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ pull request.
-issue.action.review_dismissed=@%[1]s ฮฑฯฮญฯฯฮนฯฮต ฯฮทฮฝ ฯฮตฮปฮตฯ
ฯฮฑฮฏฮฑ ฮฑฮฝฮฑฮธฮตฯฯฮทฯฮท ฮฑฯฯ %[2]s ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ pull request.
+issue.action.review_dismissed=@%[1]s ฮฑฯฮญฯฯฮนฯฮต ฯฮทฮฝ ฯฮตฮปฮตฯ
ฯฮฑฮฏฮฑ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮท ฮฑฯฯ %[2]s ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ pull request.
issue.action.ready_for_review=ฮ/ฮ @%[1]s ฮตฯฮนฯฮฎฮผฮฑฮฝฮต ฯฯฯ ฮฑฯ
ฯฯ ฯฮฟ pull request ฮตฮฏฮฝฮฑฮน ฮญฯฮฟฮนฮผฮฟ ฮณฮนฮฑ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮท.
issue.action.new=ฮ/ฮ @%[1]s ฮดฮทฮผฮนฮฟฯฯฮณฮทฯฮต ฯฮฟ #%[2]d.
issue.in_tree_path=ฮฃฮต %s:
@@ -511,13 +543,13 @@ release.downloads=ฮฮฎฯฮตฮนฯ:
release.download.zip=ฮ ฮทฮณฮฑฮฏฮฟฯ ฮฯฮดฮนฮบฮฑฯ (ZIP)
release.download.targz=ฮ ฮทฮณฮฑฮฏฮฟฯ ฮฯฮดฮนฮบฮฑฯ (TAR.GZ)
-repo.transfer.subject_to=ฮ/ฮ %s ฮธฮฑ ฮฎฮธฮตฮปฮต ฮฝฮฑ ฮผฮตฯฮฑฯฮญฯฮตฮน ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ยซ%sยป ฯฮต %s
-repo.transfer.subject_to_you=ฮ/ฮ %s ฮธฮฑ ฮฎฮธฮตฮปฮต ฮฝฮฑ ฯฮฑฯ ฮผฮตฯฮฑฯฮญฯฮตฮน ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ยซ%sยป
+repo.transfer.subject_to=ฮ/ฮ %s ฮธฮฑ ฮฎฮธฮตฮปฮต ฮฝฮฑ ฮผฮตฯฮฑฯฮญฯฮตฮน ฯฮฟ repository ยซ%sยป ฯฯฮฟ %s
+repo.transfer.subject_to_you=ฮ/ฮ %s ฮธฮฑ ฮฎฮธฮตฮปฮต ฮฝฮฑ ฯฮฑฯ ฮผฮตฯฮฑฯฮญฯฮตฮน ฯฮฟ repository ยซ%sยป
repo.transfer.to_you=ฮตฯฮฌฯ
repo.transfer.body=ฮฮนฮฑ ฮฝฮฑ ฮฑฯฮฟฮดฮตฯฯฮตฮฏฯฮต ฮฎ ฮฝฮฑ ฮฑฯฮฟฯฯฮฏฯฮตฯฮต ฯฮฟ ฮฑฮฏฯฮทฮผฮฑ ฮฑฯ
ฯฯ, ฮตฯฮนฯฮบฮตฯฮธฮตฮฏฯฮต ฯฮฟ %s ฮฎ ฮฑฯฮปฮฌ ฮฑฮณฮฝฮฟฮฎฯฯฮต ฯฮฟ.
repo.collaborator.added.subject=ฮ/ฮ %s ฯฮฑฯ ฯฯฯฯฮธฮตฯฮต ฯฯฮฟ %s ฯฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮท
-repo.collaborator.added.text=ฮฮฏฯฯฮต ฯฮปฮญฮฟฮฝ ฯฯ
ฮฝฮตฯฮณฮฌฯฮทฯ ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ:
+repo.collaborator.added.text=ฮฮฏฯฯฮต ฯฮปฮญฮฟฮฝ ฯฯ
ฮฝฮตฯฮณฮฌฯฮทฯ ฯฯฮฟ repository:
team_invite.subject=ฮ/ฮ %[1]s ฯฮฑฯ ฯฯฮฟฯฮบฮฌฮปฮตฯฮต ฮฝฮฑ ฯฯ
ฮผฮผฮตฯฮญฯฮตฯฮต ฯฯฮฟฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ %[2]s
team_invite.text_1=ฮ/ฮ %[1]s ฯฮฑฯ ฯฯฮฟฯฮบฮฌฮปฮตฯฮต ฮฝฮฑ ฯฯ
ฮผฮผฮตฯฮญฯฮตฯฮต ฯฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ %[2]s ฯฮฟฯ
ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ %[3]s.
@@ -526,6 +558,21 @@ team_invite.text_3=ฮฃฮทฮผฮตฮฏฯฯฮท: ฮฯ
ฯฮฎ ฮท ฯฯฯฯฮบฮปฮทฯฮท ฯฯฮฟฮฟฯฮน
admin.new_user.text = ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฯฮฑฯฮฎฯฯฮต ฮตฮดฯ ฮณฮนฮฑ ฮฝฮฑ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮตฮฏฯฮต ฯฮฟฮฝ ฯฯฮฎฯฯฮท ฮผฮญฯฯ ฯฮฟฯ
ฯฮฏฮฝฮฑฮบฮฑ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฯฮฝ.
admin.new_user.subject = ฮฮณฮณฯฮฑฯฮฎ ฮฝฮญฮฟฯ
ฯฯฮฎฯฯฮท %s
admin.new_user.user_info = ฮ ฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฯฯฮฎฯฯฮท
+removed_security_key.no_2fa = ฮฮตฮฝ ฮญฯฮตฯฮต ฯฯ
ฮธฮผฮฏฯฮตฮน ฮบฮฌฯฮฟฮนฮฑ ฮฌฮปฮปฮท ฮผฮญฮธฮฟฮดฮฟ ฯฯฮฝฮดฮตฯฮทฯ ฮดฮตฯ
ฯฮญฯฮฟฯ
ฯฮฑฯฮฌฮณฮฟฮฝฯฮฑ (2FA), ฮฌฯฮฑ ฮดฮตฮฝ ฯฯฮตฮนฮฌฮถฮตฯฮฑฮน ฮฝฮฑ ฯฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฯฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮผฮญฯฯ 2FA.
+account_security_caution.text_2 = ฮฮฝ ฮดฮตฮฝ ฮฎฯฮฑฯฯฮฑฮฝ ฮตฯฮตฮฏฯ, ฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฮฑฯ ฮญฯฮตฮน ฯฮฑฯฮฑฮฒฮนฮฑฯฯฮตฮฏ. ฮ ฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฮตฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฮญฮฝฮฑฮฝ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ.
+account_security_caution.text_1 = ฮฮฝ ฮฑฯ
ฯฮฎ ฮท ฮตฮฝฮญฯฮณฮตฮนฮฑ ฯฯฮฟฮญฮบฯ
ฯฮต ฮฑฯฯ ฮตฯฮฌฯ, ฯฯฯฮต ฮผฯฮฟฯฮตฮฏฯฮต ฮฑฯฮปฮฌ ฮฝฮฑ ฮฑฮณฮฝฮฟฮฎฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ email.
+password_change.subject = ฮ ฮบฯฮดฮนฮบฯฯ ฯฮฑฯ ฮญฯฮตฮน ฮฑฮปฮปฮฌฮพฮตฮน
+password_change.text_1 = ฮฯฮปฮนฯ ฮฌฮปฮปฮฑฮพฮต ฮฟ ฮบฯฮดฮนฮบฯฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฯฮฑฯ.
+primary_mail_change.subject = ฮ ฮบฯฯฮนฮฑ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฑฯ ฮฌฮปฮปฮฑฮพฮต
+primary_mail_change.text_1 = ฮ ฮบฯฯฮนฮฑ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฯฮฑฯ ฮผฯฮปฮนฯ ฮฌฮปฮปฮฑฮพฮต ฯฯฮทฮฝ %[1]s. ฮฯ
ฯฯ ฯฮทฮผฮฑฮฏฮฝฮตฮน ฯฯฯ ฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท ฯฯฮทฮฝ ฮฟฯฮฟฮฏฮฑ ฮปฮฑฮผฮฒฮฌฮฝฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮผฮฎฮฝฯ
ฮผฮฑ ฮดฮตฮฝ ฮธฮฑ ฮปฮฑฮผฮฒฮฌฮฝฮตฮน ฮตฮนฮดฮฟฯฮฟฮนฮฎฯฮตฮนฯ email ฮณฮนฮฑ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฯฮนฮฑ.
+totp_disabled.subject = ฮคฮฟ TOTP ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฮธฮทฮบฮต
+totp_disabled.text_1 = ฮ ฮบฯฮดฮนฮบฯฯ ฮผฮฏฮฑฯ ฯฯฮฎฯฮทฯ (TOTP) ฮณฮนฮฑ ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮผฯฮปฮนฯ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฮธฮทฮบฮต.
+removed_security_key.subject = ฮฮฑฯฮฑฯฮณฮฎฮธฮทฮบฮต ฮญฮฝฮฑ ฮบฮปฮตฮนฮดฮฏ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ
+removed_security_key.text_1 = ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ ยซ%[1]sยป ฮผฯฮปฮนฯ ฮฑฯฮฑฮนฯฮญฮธฮทฮบฮต ฮฑฯฯ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
+totp_disabled.no_2fa = ฮฮตฮฝ ฮญฯฮตฯฮต ฯฯ
ฮธฮผฮฏฯฮตฮน ฮบฮฌฯฮฟฮนฮฑ ฮฌฮปฮปฮท ฮผฮญฮธฮฟฮดฮฟ ฯฯฮฝฮดฮตฯฮทฯ ฮดฮตฯ
ฯฮญฯฮฟฯ
ฯฮฑฯฮฌฮณฮฟฮฝฯฮฑ (2FA), ฮฌฯฮฑ ฮดฮตฮฝ ฯฯฮตฮนฮฌฮถฮตฯฮฑฮน ฮฝฮฑ ฯฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฯฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮผฮญฯฯ 2FA.
+totp_enrolled.subject = ฮฯฮตฯฮต ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฮน ฯฮฟ TOTP ฯฯ ฮผฮญฮธฮฟฮดฮฟ ฯฯฮฝฮดฮตฯฮทฯ ฮดฮตฯ
ฯฮญฯฮฟฯ
ฯฮฑฯฮฌฮณฮฟฮฝฯฮฑ 2FA
+totp_enrolled.text_1.no_webauthn = ฮฯฮปฮนฯ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮฑฯฮต ฯฮฟ TOTP ฮณฮนฮฑ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮฯ
ฯฯ ฯฮทฮผฮฑฮฏฮฝฮตฮน ฯฯฮน ฮณฮนฮฑ ฯฮปฮตฯ ฯฮนฯ ฮผฮตฮปฮปฮฟฮฝฯฮนฮบฮญฯ ฯฯ
ฮฝฮดฮญฯฮตฮนฯ ฯฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ, ฮธฮฑ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮต ฯฮฟ TOTP ฯฯ ฮผฮญฮธฮฟฮดฮฟ ฯฯฮฝฮดฮตฯฮทฯ ฮดฮตฯ
ฯฮญฯฮฟฯ
ฯฮฑฯฮฌฮณฮฟฮฝฯฮฑ (2FA).
+totp_enrolled.text_1.has_webauthn = ฮฯฮปฮนฯ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮฑฯฮต ฯฮฟ TOTP ฮณฮนฮฑ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮฯ
ฯฯ ฯฮทฮผฮฑฮฏฮฝฮตฮน ฯฯฮน ฮณฮนฮฑ ฯฮปฮตฯ ฯฮนฯ ฮผฮตฮปฮปฮฟฮฝฯฮนฮบฮญฯ ฯฯ
ฮฝฮดฮญฯฮตฮนฯ ฯฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ, ฮธฮฑ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮต ฯฮฟ TOTP ฮฎ ฮญฮฝฮฑ ฮฑฯฯ ฯฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ ฯฮฑฯ ฯฯ ฮผฮญฮธฮฟฮดฮฟ ฯฯฮฝฮดฮตฯฮทฯ ฮดฮตฯ
ฯฮญฯฮฟฯ
ฯฮฑฯฮฌฮณฮฟฮฝฯฮฑ (2FA).
[modal]
yes=ฮฮฑฮน
@@ -548,14 +595,14 @@ AuthName=ฮฮฝฮฟฮผฮฑ ฮตฮพฮฟฯ
ฯฮนฮฟฮดฯฯฮทฯฮทฯ
AdminEmail=Email ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ
NewBranchName=ฮฮฝฮฟฮผฮฑ ฮฝฮญฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
-CommitSummary=ฮ ฮตฯฮฏฮปฮทฯฮท ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ
-CommitMessage=ฮฮฎฮฝฯ
ฮผฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ
-CommitChoice=ฮฯฮนฮปฮฟฮณฮฎ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ
+CommitSummary=ฮ ฮตฯฮฏฮปฮทฯฮท commit
+CommitMessage=ฮฮฎฮฝฯ
ฮผฮฑ commit
+CommitChoice=ฮฯฮนฮปฮฟฮณฮฎ commit
TreeName=ฮฮนฮฑฮดฯฮฟฮผฮฎ ฮฑฯฯฮตฮฏฮฟฯ
Content=ฮ ฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ
SSPISeparatorReplacement=ฮฮนฮฑฯฯฯฮนฯฯฮนฮบฯ
-SSPIDefaultLanguage=ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮท ฮฮปฯฯฯฮฑ
+SSPIDefaultLanguage=ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮท ฮณฮปฯฯฯฮฑ
require_error=` ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯ.`
alpha_dash_error=`: ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฯฮตฯฮนฮญฯฮตฮน ฮผฯฮฝฮฟ ฮฑฮปฯฮฑฯฮนฮธฮผฮทฯฮนฮบฮฌ, ฯฮฑฯฮปฮตฯ ('-') ฮบฮฑฮน ฮบฮฌฯฯ ฯฮฑฯฮปฮตฯ ('_').`
@@ -581,10 +628,10 @@ username_change_not_local_user=ฮฮตฮฝ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฯฯฮฟฯ
ฯ ฮผฮท ฯ
username_has_not_been_changed=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฮดฮตฮฝ ฮฌฮปฮปฮฑฮพฮต
repo_name_been_taken=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮฎฮดฮท.
repository_force_private=ฮ ฮตฯฮนฮปฮฟฮณฮฎ ฮฯฮฝฮฟ ฮฮดฮนฯฯฮนฮบฮฌ ฮตฮฏฮฝฮฑฮน ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮท: ฯฮฑ ฮนฮดฮนฯฯฮนฮบฮฌ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮทฮผฮฟฯฮนฮตฯ
ฮธฮฟฯฮฝ.
-repository_files_already_exist=ฮฯฯฮตฮฏฮฑ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฎฮดฮท ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฟฯ
ฯฯ
ฯฯฮฎฮผฮฑฯฮฟฯ.
-repository_files_already_exist.adopt=ฮฯฯฮตฮฏฮฑ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฎฮดฮท ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮบฮฑฮน ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮฅฮนฮฟฮธฮตฯฮทฮธฮฟฯฮฝ ฮผฯฮฝฮฟ.
-repository_files_already_exist.delete=ฮคฮฑ ฮฑฯฯฮตฮฏฮฑ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฎฮดฮท ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฯฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮต.
-repository_files_already_exist.adopt_or_delete=ฮคฮฑ ฮฑฯฯฮตฮฏฮฑ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฎฮดฮท ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮฮฏฯฮต ฯ
ฮนฮฟฮธฮตฯฮฎฯฯฮต ฯฮฑ ฮตฮฏฯฮต ฮดฮนฮฑฮณฯฮฌฯฯฮต ฯฮฑ.
+repository_files_already_exist=ฮฯฯฮตฮฏฮฑ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฎฮดฮท ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ repository. ฮฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฟฯ
ฯฯ
ฯฯฮฎฮผฮฑฯฮฟฯ.
+repository_files_already_exist.adopt=ฮฯฯฮตฮฏฮฑ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฎฮดฮท ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ repository ฮบฮฑฮน ฮผฯฮฟฯฮฟฯฮฝ ฮผฯฮฝฮฟ ฮฝฮฑ ฯ
ฮนฮฟฮธฮตฯฮทฮธฮฟฯฮฝ.
+repository_files_already_exist.delete=ฮคฮฑ ฮฑฯฯฮตฮฏฮฑ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฎฮดฮท ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ repository. ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฯฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮต.
+repository_files_already_exist.adopt_or_delete=ฮฅฯฮฌฯฯฮฟฯ
ฮฝ ฮฎฮดฮท ฯฮฑ ฮฑฯฯฮตฮฏฮฑ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ repository. ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฯฮฑ ฯ
ฮนฮฟฮธฮตฯฮฎฯฮตฯฮต ฮฎ ฮฝฮฑ ฯฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮต.
visit_rate_limit=ฮฃฯ
ฮฝฮฑฮฝฯฮฎฮธฮทฮบฮต ฯฮฟ ฯฯฮนฮฟ ฯฯ
ฮธฮผฮฟฯ ฮบฮฑฯฮฌ ฯฮทฮฝ ฮฑฯฮฟฮผฮฑฮบฯฯ
ฯฮผฮญฮฝฮท ฯฯฯฯฮฒฮฑฯฮท.
2fa_auth_required=ฮฯฮฑฮนฯฮฎฮธฮทฮบฮต ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ ฮบฮฑฯฮฌ ฯฮทฮฝ ฮฑฯฮฟฮผฮฑฮบฯฯ
ฯฮผฮญฮฝฮท ฯฯฯฯฮฒฮฑฯฮท.
org_name_been_taken=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฮฟฯ
ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮฎฮดฮท.
@@ -629,6 +676,16 @@ admin_cannot_delete_self = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮต ฯ
unset_password = ฮ ฯฯฮฎฯฯฮทฯ ฮดฮตฮฝ ฮญฯฮตฮน ฮฟฯฮฏฯฮตฮน ฮบฮฌฯฮฟฮนฮฟฮฝ ฮบฯฮดฮนฮบฯ.
unsupported_login_type = ฮ ฮผฮญฮธฮฟฮดฮฟฯ ฮผฮต ฯฮทฮฝ ฮฟฯฮฟฮฏฮฟ ฮณฮฏฮฝฮตฯฮฑฮน ฮท ฯฯฮฝฮดฮตฯฮท ฮดฮตฮฝ ฯ
ฯฮฟฯฯฮทฯฮฏฮถฮตฮน ฯฮทฮฝ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฮฝ.
required_prefix = ฮคฮฟ ฮตฮนฯฮฑฮณฯฮผฮตฮฝฮฟ ฮบฮตฮฏฮผฮตฮฝฮฟ ฯฯฮญฯฮตฮน ฮฝฮฑ ฮพฮตฮบฮนฮฝฮฌ ฮผฮต ยซ%sยป
+To = ฮฮฝฮฟฮผฮฑ ฮบฮปฮฌฮดฮฟฯ
+AccessToken = ฮฮนฮฑฮบฯฮนฯฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ (token)
+FullName = ฮ ฮปฮฎฯฮตฯ ฯฮฝฮฟฮผฮฑ
+Description = ฮ ฮตฯฮนฮณฯฮฑฯฮฎ
+Pronouns = ฮฮฝฯฯฮฝฯ
ฮผฮฏฮตฯ
+Biography = ฮฮนฮฟฮณฯฮฑฯฮฏฮฑ
+Website = ฮฯฯฮฟฯฮตฮปฮฏฮดฮฑ
+Location = ฮคฮฟฯฮฟฮธฮตฯฮฏฮฑ
+username_claiming_cooldown = ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮฑฮบฯฮผฮฑ, ฮตฯฮตฮนฮดฮฎ ฮท ฮทฮผฮตฯฮฟฮผฮทฮฝฮฏฮฑ ฮปฮฎฮพฮทฯ ฯฮฟฯ
ฮฟฮฝฯฮผฮฑฯฮฟฯ ฯฯฮฎฯฯฮท ฮดฮตฮฝ ฮญฯฮตฮน ฮพฮตฯฮตฯฮฑฯฯฮตฮฏ. ฮฮฑ ฮณฮฏฮฝฮตฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮฟ ฯฮต %[1]s.
+email_domain_is_not_allowed = ฮคฮฟ domain ฯฮฟฯ
email ฯฯฮฎฯฯฮท %s ฮญฯฯฮตฯฮฑฮน ฯฮต ฯฯฮณฮบฯฮฟฯ
ฯฮท ฮตฮฏฯฮต ฮผฮต ฯฮทฮฝ ฯฯฮธฮผฮนฯฮท EMAIL_DOMAIN_ALLOWLIST ฮฎ ฮผฮต ฯฮทฮฝ ฯฯฮธฮผฮนฯฮท EMAIL_DOMAIN_BLOCKLIST. ฮฮตฮฒฮฑฮนฯฮธฮตฮฏฯฮต ฯฯฮน ฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฮญฯฮตฮน ฮฟฯฮนฯฯฮตฮฏ ฯฯฯฯฮฌ.
[user]
@@ -659,12 +716,21 @@ follow_blocked_user = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮบฮฟฮปฮฟฯ
ฮธฮฎฯฮตฯฮต ฯฮฟ
unblock = ฮฯฯฮท ฮฑฯฮฟฮบฮปฮตฮนฯฮผฮฟฯ
block = ฮฯฮฟฮบฮปฮตฮนฯฮผฯฯ
block_user = ฮฯฮฟฮบฮปฮตฮนฯฮผฯฯ ฯฯฮฎฯฯฮท
-block_user.detail_1 = ฮ ฯฯฮฎฯฯฮทฯ ฮดฮตฮฝ ฮธฮฑ ฮฑฮบฮฟฮปฮฟฯ
ฮธฮตฮฏ ฯฮนฮฑ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
-block_user.detail_2 = ฮ ฯฯฮฎฯฯฮทฯ ฮดฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮปฮปฮทฮปฮตฯฮนฮดฯฮฌฯฮตฮน ฮผฮต ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฌ ฯฮฑฯ, ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฮน ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮฎ ฮฝฮฑ ฮฑฯฮฎฯฮตฮน ฯฯฯฮปฮนฮฑ.
-block_user.detail_3 = ฮ ฯฯฮฎฯฯฮทฯ ฮดฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮญฯฮตฮน ฮฝฮฑ ฯฮฑฯ ฯฯฮฟฯฮธฮญฯฮตฮน ฯฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฌ ฯฮฟฯ
ฯฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮท ฮบฮฑฮน ฮฑฮฝฯฮฏฯฯฮฟฮนฯฮฑ ฮดฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฮฟฮฝ ฯฯฮฟฯฮธฮญฯฮตฯฮต ฯฯฮฑ ฮดฮนฮบฮฌ ฯฮฑฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ.
-block_user.detail = ฮฯฮนฯฮทฮผฮฑฮฏฮฝฮตฯฮฑฮน ฯฯฯ ฮฑฮฝ ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฯฯฮฎฯฯฮท, ฮธฮฑ ฯฯฮฟฮบฯฯฮฟฯ
ฮฝ ฯฮฑฯ
ฯฯฯฯฮฟฮฝฮฑ ฮบฮฑฮน ฮฌฮปฮปฮตฯ ฮตฮฝฮญฯฮณฮตฮนฮตฯ. ฮฮตฯฮนฮบฮญฯ ฮฑฯฯ ฮฑฯ
ฯฮญฯ:
+block_user.detail_1 = ฮ ฯฯฮฎฯฯฮทฯ ฮธฮฑ ฯฮฌฯฮตฮน ฮฝฮฑ ฮฑฮบฮฟฮปฮฟฯ
ฮธฮตฮฏ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
+block_user.detail_2 = ฮ ฯฯฮฎฯฯฮทฯ ฮดฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮปฮปฮทฮปฮตฯฮนฮดฯฮฌฯฮตฮน ฮผฮต ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฌ, ฯฮฑ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮบฮฑฮน ฯฮฑ ฯฯฯฮปฮนฮฑ ฯฮฑฯ.
+block_user.detail_3 = ฮฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฯฮธฮญฯฮตฯฮต ฮฟ ฮญฮฝฮฑฯ ฯฮฟฮฝ ฮฌฮปฮปฮฟฮฝ ฯฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฌ ฯฮฑฯ ฯฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮท.
+block_user.detail = ฮฯฮนฯฮทฮผฮฑฮฏฮฝฮตฯฮฑฮน ฯฯฯ ฮฑฮฝ ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฯฯฮฎฯฯฮท, ฮธฮฑ ฯฯฮฟฮบฯฯฮฟฯ
ฮฝ ฯฮฑฯ
ฯฯฯฯฮฟฮฝฮฑ ฮบฮฑฮน ฮฌฮปฮปฮตฯ ฮตฮฝฮญฯฮณฮตฮนฮตฯ, ฯฯฯฯ:
followers_one = %d ฮฑฮบฯฮปฮฟฯ
ฮธฮฟฯ
following_one = ฮฑฮบฮฟฮปฮฟฯ
ฮธฮตฮฏ %d
+public_activity.visibility_hint.admin_private = ฮฮฝ ฮบฮฑฮน ฮฟ ฯฯฮฎฯฯฮทฯ ฯฯฮฟฯฮนฮผฮฌ ฮฝฮฑ ฮบฯฮฑฯฮฌ ฯฮทฮฝ ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฌ ฯฮฟฯ
ฮนฮดฮนฯฯฮนฮบฮฎ, ฮตฮฏฮฝฮฑฮน ฮฟฯฮฑฯฮฎ ฯฮต ฮตฯฮฌฯ ฮตฯฮตฮนฮดฮฎ ฮตฮฏฯฯฮต ฮญฮฝฮฑฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ.
+followers.title.one = ฮฑฮบฯฮปฮฟฯ
ฮธฮฟฯ
+followers.title.few = ฮฑฮบฯฮปฮฟฯ
ฮธฮฟฮน
+following.title.few = ฮฑฮบฮฟฮปฮฟฯ
ฮธฮตฮฏ
+following.title.one = ฮฑฮบฮฟฮปฮฟฯ
ฮธฮตฮฏ
+public_activity.visibility_hint.admin_public = ฮ ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฑ ฮตฮฏฮฝฮฑฮน ฮฟฯฮฑฯฮฎ ฯฮต ฯฮปฮฟฯ
ฯ, ฮฑฮปฮปฮฌ ฯฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮตฮฏฯฮต ฮบฮฑฮน ฯฮนฯ ฮฑฮปฮปฮทฮปฮตฯฮนฮดฯฮฌฯฮตฮนฯ ฯฮต ฮนฮดฮนฯฯฮนฮบฮฟฯฯ ฯฯฯฮฟฯ
ฯ.
+public_activity.visibility_hint.self_public = ฮ ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฌ ฯฮฟฯ
ฮตฮฏฮฝฮฑฮน ฮฟฯฮฑฯฮฎ ฯฮต ฯฮปฮฟฯ
ฯ, ฯฮปฮทฮฝ ฯฮนฯ ฮฑฮปฮปฮทฮปฮตฯฮนฮดฯฮฌฯฮตฮนฯ ฯฮฑฯ ฯฮต ฮนฮดฮนฯฯฮนฮบฮฟฯฯ ฯฯฯฮฟฯ
ฯ. ฮฮปฮปฮฑฮณฮฎ ฮฟฯฮฑฯฯฯฮทฯฮฑฯ .
+public_activity.visibility_hint.self_private = ฮ ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฌ ฯฮฑฯ ฮตฮฏฮฝฮฑฮน ฮฟฯฮฑฯฮฎ ฮผฯฮฝฮฟ ฯฮต ฮตฯฮฌฯ ฮบฮฑฮน ฯฯฮฟฯ
ฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮญฯ. ฮฮปฮปฮฑฮณฮฎ ฮฟฯฮฑฯฯฯฮทฯฮฑฯ .
+public_activity.visibility_hint.self_private_profile = ฮ ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฌ ฯฮฑฯ ฮตฮฏฮฝฮฑฮน ฮฟฯฮฑฯฮฎ ฮผฯฮฝฮฟ ฯฮต ฮตฯฮฌฯ ฮบฮฑฮน ฯฮฟฯ
ฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮญฯ ฯฮฟฯ
ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฮบฮฑฮธฯฯ ฯฮฟ ฯฯฮฟฯฮฏฮป ฯฮฑฯ ฮตฮฏฮฝฮฑฮน ฮนฮดฮนฯฯฮนฮบฯ ฮฮปฮปฮฑฮณฮฎ ฮฟฯฮฑฯฯฯฮทฯฮฑฯ .
[settings]
profile=ฮ ฯฮฟฯฮฏฮป
@@ -676,19 +742,19 @@ avatar=ฮฮนฮบฯฮฝฮฑ ฯฯฮฟฯฮฏฮป
ssh_gpg_keys=ฮฮปฮตฮนฮดฮนฮฌ SSH / GPG
social=ฮฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฮฏ ฮบฮฟฮนฮฝฯฮฝฮนฮบฯฮฝ ฮดฮนฮบฯฯฯฮฝ
applications=ฮฯฮฑฯฮผฮฟฮณฮญฯ
-orgs=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮฟฯฮณฮฑฮฝฮนฯฮผฯฮฝ
+orgs=ฮฯฮณฮฑฮฝฮนฯฮผฮฟฮฏ
repos=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฑ
delete=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
twofa=ฮ ฮนฯฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ (TOTP)
-account_link=ฮฃฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฮน ฮฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฮฏ
+account_link=ฮฃฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฮน ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฮฏ
organization=ฮฯฮณฮฑฮฝฮนฯฮผฮฟฮฏ
uid=UID
webauthn=ฮ ฮนฯฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ (ฮฮปฮตฮนฮดฮนฮฌ ฮฯฯฮฑฮปฮตฮฏฮฑฯ)
public_profile=ฮฮทฮผฯฯฮนฮฟ ฯฯฮฟฯฮฏฮป
-biography_placeholder=ฮ ฮตฮฏฯฮต ฮผฮฑฯ ฮปฮฏฮณฮฟ ฮณฮนฮฑ ฯฮฟฮฝ ฮตฮฑฯ
ฯฯ ฯฮฑฯ! (ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮณฯฮฌฯฮตฯฮต ฮผฮต Markdown)
+biography_placeholder=ฮ ฮตฮฏฯฮต ฮปฮฏฮณฮฑ ฯฯฮฌฮณฮผฮฑฯฮฑ ฮณฮนฮฑ ฯฮฟฮฝ ฮตฮฑฯ
ฯฯ ฯฮฑฯ! (ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮณฯฮฌฯฮตฯฮต ฮผฮต Markdown)
location_placeholder=ฮฮฟฮนฯฮฑฯฯฮตฮฏฯฮต ฯฮทฮฝ ฮบฮฑฯฮฌ ฯฯฮฟฯฮญฮณฮณฮนฯฮท ฯฮฟฯฮฟฮธฮตฯฮฏฮฑ ฯฮฑฯ ฮผฮต ฮฌฮปฮปฮฟฯ
ฯ
-profile_desc=ฮฮปฮญฮณฮพฯฮต ฯฯฯ ฮตฮผฯฮฑฮฝฮฏฮถฮตฯฮฑฮน ฯฮฟ ฯฯฮฟฯฮฏฮป ฯฮฑฯ ฯฮต ฮฌฮปฮปฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ. ฮ ฮบฯฯฮนฮฑ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฑฯ ฮธฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮณฮนฮฑ ฮตฮนฮดฮฟฯฮฟฮนฮฎฯฮตฮนฯ, ฮฑฮฝฮฌฮบฯฮทฯฮท ฮบฯฮดฮนฮบฮฟฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฮบฮฑฮน ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮตฯ Git ฯฮฟฯ
ฮฒฮฑฯฮฏฮถฮฟฮฝฯฮฑฮน ฯฯฮฟ web.
+profile_desc=ฮฃฯฮตฯฮนฮบฮฌ ฮผฮต ฮตฯฮฌฯ
password_username_disabled=ฮฮน ฮผฮท ฯฮฟฯฮนฮบฮฟฮฏ ฯฯฮฎฯฯฮตฯ ฮดฮตฮฝ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮฟฯ
ฮฝ ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฯฮฟฯ
ฯ. ฮฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฑฯ ฮณฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฮปฮตฯฯฮฟฮผฮญฯฮตฮนฮตฯ.
full_name=ฮ ฮปฮฎฯฮตฯ ฯฮฝฮฟฮผฮฑ
website=ฮฯฯฮฟฯฮตฮปฮฏฮดฮฑ
@@ -707,8 +773,8 @@ cancel=ฮฮบฯฯฯฯฮท
language=ฮฮปฯฯฯฮฑ
ui=ฮฮญฮผฮฑ ฮฮนฮตฯฮฑฯฮฎฯ
hidden_comment_types=ฮฯฯ
ฮผฮผฮญฮฝฮฟฮน ฯฯฯฮฟฮน ฯฯฮฟฮปฮฏฯฮฝ
-hidden_comment_types_description=ฮฮน ฯฯฯฮฟฮน ฯฯฮฟฮปฮฏฯฮฝ ฯฮฟฯ
ฮตฯฮนฮปฮญฮณฮฟฮฝฯฮฑฮน ฮตฮดฯ ฮดฮต ฮธฮฑ ฮตฮผฯฮฑฮฝฮฏฮถฮฟฮฝฯฮฑฮน ฮผฮญฯฮฑ ฯฯฮนฯ ฯฮตฮปฮฏฮดฮตฯ ฮถฮทฯฮทฮผฮฌฯฯฮฝ. ฮฯฮนฮปฮญฮณฮฟฮฝฯฮฑฯ ฯ.ฯ ฯฮฟ "ฮฃฮฎฮผฮฑฯฮฑ", ฮธฮฑ ฮฑฯฮฑฮนฯฮตฮธฮฟฯฮฝ ฯฮปฮฑ ฯฮฑ ฯฯฯฮปฮนฮฑ ฯฮฑฮฝ ฯฮฟ " ฯฯฯฯฮธฮตฯฮต/ฮฑฯฮฑฮฏฯฮตฯฮต ฯฮฑ ฯฮฎฮผฮฑฯฮฑ ".
-hidden_comment_types.ref_tooltip=ฮฃฯฯฮปฮนฮฑ ฯฯฮฟฯ
ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฮฑฮฝฮฑฯฮญฯฮธฮทฮบฮต ฮฑฯฯ ฮฌฮปฮปฮฟ ฮถฮฎฯฮทฮผฮฑ/ฯ
ฯฮฟฮฒฮฟฮปฮฎ/โฆ
+hidden_comment_types_description=ฮฮน ฯฯฯฮฟฮน ฯฯฮฟฮปฮฏฯฮฝ ฯฮฟฯ
ฮตฯฮนฮปฮญฮณฮฟฮฝฯฮฑฮน ฮตฮดฯ ฮดฮต ฮธฮฑ ฮตฮผฯฮฑฮฝฮฏฮถฮฟฮฝฯฮฑฮน ฮผฮญฯฮฑ ฯฯฮนฯ ฯฮตฮปฮฏฮดฮตฯ ฮถฮทฯฮทฮผฮฌฯฯฮฝ. ฮฯฮนฮปฮญฮณฮฟฮฝฯฮฑฯ ฯ.ฯ ฯฮนฯ "ฮคฮฑฮผฯฮญฮปฮตฯ", ฮธฮฑ ฮฑฯฮฑฮนฯฮตฮธฮฟฯฮฝ ฯฮปฮฑ ฯฮฑ ฯฯฯฮปฮนฮฑ ฯฮฑฮฝ ฯฮฟ " ฯฯฯฯฮธฮตฯฮต/ฮฑฯฮฑฮฏฯฮตฯฮต ฯฮฑ ฯฮฎฮผฮฑฯฮฑ ".
+hidden_comment_types.ref_tooltip=ฮฃฯฯฮปฮนฮฑ ฯฯฮฟฯ
ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฮฑฮฝฮฑฯฮญฯฮธฮทฮบฮต ฮฑฯฯ ฮฌฮปฮปฮฟ ฮถฮฎฯฮทฮผฮฑ/commit/โฆ
hidden_comment_types.issue_ref_tooltip=ฮฃฯฯฮปฮนฮฑ ฯฯฮฟฯ
ฮฟ ฯฯฮฎฯฯฮทฯ ฮฑฮปฮปฮฌฮถฮตฮน ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ/ฮตฯฮนฮบฮญฯฮฑ ฯฮฟฯ
ฯฯฮตฯฮฏฮถฮตฯฮฑฮน ฮผฮต ฯฮฟ ฮถฮฎฯฮทฮผฮฑ
comment_type_group_reference=ฮฮฝฮฑฯฮฟฯฮฌ
comment_type_group_label=ฮฃฮฎฮผฮฑ
@@ -721,7 +787,7 @@ comment_type_group_deadline=ฮ ฯฮฟฮธฮตฯฮผฮฏฮฑ
comment_type_group_dependency=ฮฮพฮฌฯฯฮทฯฮท
comment_type_group_lock=ฮฮฑฯฮฌฯฯฮฑฯฮท ฮบฮปฮตฮนฮดฯฮผฮฑฯฮฟฯ
comment_type_group_review_request=ฮฮฏฯฮทฯฮท ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮทฯ
-comment_type_group_pull_request_push=ฮ ฯฮฟฯฯฮญฮธฮทฮบฮฑฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ
+comment_type_group_pull_request_push=ฮ ฯฮฟฯฯฮญฮธฮทฮบฮฑฮฝ commits
comment_type_group_project=ฮฯฮณฮฟ
comment_type_group_issue_ref=ฮฮฝฮฑฯฮฟฯฮฌ ฮถฮทฯฮฎฮผฮฑฯฮฟฯ
saved_successfully=ฮฮน ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฮฑฯ ฮฑฯฮฟฮธฮทฮบฮตฯฯฮทฮบฮฑฮฝ ฮตฯฮนฯฯ
ฯฯฯ.
@@ -750,20 +816,20 @@ password_change_disabled=ฮฮน ฮผฮท ฯฮฟฯฮนฮบฮฟฮฏ ฯฯฮฎฯฯฮตฯ ฮดฮตฮฝ ฮผฯฮฟฯ
emails=ฮฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ Email
manage_emails=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฯฮฝ email
-manage_themes=ฮฯฮนฮปฮญฮพฯฮต ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮธฮญฮผฮฑ ฮดฮนฮตฯฮฑฯฮฎฯ
-manage_openid=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฯฮฝ OpenID
+manage_themes=ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮธฮญฮผฮฑ
+manage_openid=ฮฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ OpenID
email_desc=ฮ ฮบฯฯฮนฮฑ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท ฮทฮปฮตฮบฯฯฮฟฮฝฮนฮบฮฟฯ ฯฮฑฯฯ
ฮดฯฮฟฮผฮตฮฏฮฟฯ
ฯฮฑฯ ฮธฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮณฮนฮฑ ฮตฮนฮดฮฟฯฮฟฮนฮฎฯฮตฮนฯ, ฮฑฮฝฮฌฮบฯฮทฯฮท ฯฮฟฯ
ฮบฯฮดฮนฮบฮฟฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฮบฮฑฮน, ฮตฯฯฯฮฟฮฝ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮบฯฯ
ฮผฮผฮญฮฝฮท, ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮตฯ Git ฯฯฮฟฮฝ ฮนฯฯฯฯฮฟฯฮฟ.
-theme_desc=ฮฯ
ฯฯ ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฯฮฟ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮธฮญฮผฮฑ ฮดฮนฮตฯฮฑฯฮฎฯ ฯฮฑฯ ฯฮต ฯฮปฮท ฯฮทฮฝ ฮนฯฯฮฟฯฮตฮปฮฏฮดฮฑ.
+theme_desc=ฮฯ
ฯฯ ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฯฮฟ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮธฮญฮผฮฑ ฮดฮนฮตฯฮฑฯฮฎฯ ฯฮฑฯ ฯฯฮฑฮฝ ฮตฮฏฯฯฮต ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฮน.
primary=ฮฯฯฮนฮฟ
activated=ฮฮฝฮตฯฮณฯ
requires_activation=ฮฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท
-primary_email=ฮฮปฮปฮฑฮณฮฎ ฮบฯ
ฯฮนฯฯฮทฯฮฑฯ
-activate_email=ฮฯฮฟฯฯฮฟฮปฮฎ ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮทฯ
-activations_pending=ฮฮบฮบฯฮตฮผฮฟฯฮฝ ฮฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฮนฯ
+primary_email=ฮ ฯฮฟฮตฯฮนฮปฮฟฮณฮฎ
+activate_email=ฮฯฮฟฯฯฮฟฮปฮฎ ฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮทฯ
+activations_pending=ฮฮบฮบฯฮตฮผฮตฮฏ ฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท
can_not_add_email_activations_pending=ฮฮบฮบฯฮตฮผฮตฮฏ ฮผฮนฮฑ ฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท, ฮดฮฟฮบฮนฮผฮฌฯฯฮต ฮพฮฑฮฝฮฌ ฯฮต ฮปฮฏฮณฮฑ ฮปฮตฯฯฮฌ ฮฑฮฝ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฯฯฮฟฯฮธฮญฯฮตฯฮต ฮญฮฝฮฑ ฮฝฮญฮฟ email.
delete_email=ฮฯฮฑฮฏฯฮตฯฮท
-email_deletion=ฮฯฮฑฮฏฯฮตฯฮท ฮฮนฮตฯฮธฯ
ฮฝฯฮทฯ Email
-email_deletion_desc=ฮ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท ฮทฮปฮตฮบฯฯฮฟฮฝฮนฮบฮฟฯ ฯฮฑฯฯ
ฮดฯฮฟฮผฮตฮฏฮฟฯ
ฮบฮฑฮน ฮฟฮน ฯฯฮตฯฮนฮบฮญฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฮธฮฑ ฮฑฯฮฑฮนฯฮตฮธฮฟฯฮฝ ฮฑฯฯ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ Git ฮฑฯฯ ฮฑฯ
ฯฮฎ ฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฮธฮฑ ฯฮฑฯฮฑฮผฮตฮฏฮฝฮฟฯ
ฮฝ ฮฑฮผฮตฯฮฌฮฒฮปฮทฯฮตฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
+email_deletion=ฮฯฮฑฮฏฯฮตฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮทฯ email
+email_deletion_desc=ฮ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฮบฮฑฮน ฮฟฮน ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฯฮฟฯ
ฯฯ
ฯฯฮตฯฮฏฮถฮฟฮฝฯฮฑฮน ฮผฮต ฮฑฯ
ฯฮฎฮฝ ฮธฮฑ ฮฑฯฮฑฮนฯฮตฮธฮฟฯฮฝ ฮฑฯฯ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮคฮฑ Git commit ฯฮฟฯ
ฯฮตฯฮนฮปฮฑฮผฮฒฮฌฮฝฮฟฯ
ฮฝ ฯฮฟ email ฮดฮตฮฝ ฮธฮฑ ฮตฯฮทฯฮตฮฑฯฯฮฟฯฮฝ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
email_deletion_success=ฮ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฑฯ ฮญฯฮตฮน ฮบฮฑฯฮฑฯฮณฮทฮธฮตฮฏ.
theme_update_success=ฮคฮฟ ฮธฮญฮผฮฑ ฮดฮนฮตฯฮฑฯฮฎฯ ฯฮฑฯ ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮต.
theme_update_error=ฮคฮฟ ฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮธฮญฮผฮฑ ฮดฮนฮตฯฮฑฯฮฎฯ ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน.
@@ -771,40 +837,40 @@ openid_deletion=ฮฯฮฑฮฏฯฮตฯฮท ฮฮนฮตฯฮธฯ
ฮฝฯฮทฯ OpenID
openid_deletion_desc=ฮ ฮบฮฑฯฮฌฯฮณฮทฯฮท ฮฑฯ
ฯฮฎฯ ฯฮทฯ ฮดฮนฮตฯฮธฯ
ฮฝฯฮทฯ OpenID ฮฑฯฯ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮธฮฑ ฯฮฑฯ ฮตฮผฯฮฟฮดฮฏฯฮตฮน ฮฝฮฑ ฯฯ
ฮฝฮดฮญฮตฯฯฮต ฮผฮต ฮฑฯ
ฯฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
openid_deletion_success=ฮ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท OpenID ฮฑฯฮฑฮนฯฮญฮธฮทฮบฮต.
add_new_email=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮฝฮญฮฑฯ ฮดฮนฮตฯฮธฯ
ฮฝฯฮทฯ email
-add_new_openid=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮฮญฮฟฯ
OpenID URI
+add_new_openid=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮฝฮญฮฟฯ
OpenID URI
add_email=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮทฯ email
add_openid=ฮ ฯฮฟฯฮธฮฎฮบฮท OpenID URI
-add_email_confirmation_sent=ฮฮฝฮฑ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮญฯฮตฮน ฯฯฮฑฮปฮตฮฏ ฯฯฮทฮฝ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท ยซ%sยป. ฮฮนฮฑ ฮฝฮฑ ฮตฯฮนฮฒฮตฮฒฮฑฮนฯฯฮตฯฮต ฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฑฯ, ฯฮฑฯฮฑฮบฮฑฮปฯ ฮตฮปฮญฮณฮพฯฮต ฯฮฑ ฮตฮนฯฮตฯฯฯฮผฮตฮฝฮฑ ฯฮฑฯ ฮผฮญฯฮฑ ฯฮต %s.
+add_email_confirmation_sent=ฮฮฝฮฑ email ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ ฮญฯฮตฮน ฯฯฮฑฮปฮตฮฏ ฯฯฮทฮฝ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท ยซ%sยป. ฮฮนฮฑ ฮฝฮฑ ฮตฯฮนฮฒฮตฮฒฮฑฮนฯฯฮตฯฮต ฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฑฯ, ฯฮฑฯฮฑฮบฮฑฮปฯ ฮตฮปฮญฮณฮพฯฮต ฯฮฑ ฮตฮนฯฮตฯฯฯฮผฮตฮฝฮฑ ฯฮฑฯ ฮบฮฑฮน ฯฮฑฯฮฎฯฯฮต ฯฯฮฟ link ฯฮฟฯ
ฯฮฑฯ ฮญฯฮฟฯ
ฮผฮต ฯฯฮตฮฏฮปฮตฮน ฮผฮญฯฮฑ ฯฯฮนฯ ฮตฯฯฮผฮตฮฝฮตฯ %s.
add_email_success=ฮ ฮฝฮญฮฑ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฮญฯฮตฮน ฯฯฮฟฯฯฮตฮธฮตฮฏ.
email_preference_set_success=ฮฮน ฯฯฮฟฯฮนฮผฮฎฯฮตฮนฯ email ฮญฯฮฟฯ
ฮฝ ฮฟฯฮนฯฯฮตฮฏ ฮตฯฮนฯฯ
ฯฯฯ.
add_openid_success=ฮ ฯฮฟฯฯฮญฮธฮทฮบฮต ฮท ฮฝฮญฮฑ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท OpenID.
keep_email_private=ฮฯฯฮบฯฯ
ฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮทฯ email
-keep_email_private_popup=ฮฯ
ฯฯ ฮธฮฑ ฮบฯฯฯฮตฮน ฯฮฟ email ฯฮฑฯ ฮฑฯฯ ฯฮฟ ฯฯฮฟฯฮฏฮป ฯฮฑฯ, ฮบฮฑฮธฯฯ ฮบฮฑฮน ฯฯฮฑฮฝ ฮบฮฌฮฝฮตฯฮต ฮญฮฝฮฑ pull request ฮฎ ฮตฯฮตฮพฮตฯฮณฮฌฮถฮตฯฯฮต ฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฟ ฮผฮญฯฯ ฯฮทฯ ฮนฯฯฮฟฯฮตฮปฮฏฮดฮฑฯ. ฮฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฯฮฟฯ
ฮญฯฮตฯฮต ฮฎฮดฮท ฯฮธฮฎฯฮตฮน ฮดฮตฮฝ ฮธฮฑ ฯฯฮฟฯฮฟฯฮฟฮนฮทฮธฮฟฯฮฝ. ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฯฮฟ %s ฯฯฮนฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮณฮนฮฑ ฮฝฮฑ ฯฮนฯ ฯฯ
ฯฯฮตฯฮฏฯฮตฯฮต ฮผฮต ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
+keep_email_private_popup=ฮ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฑฯ ฮดฮตฮฝ ฮธฮฑ ฮตฮผฯฮฑฮฝฮฏฮถฮตฯฮฑฮน ฯฯฮฟ ฯฯฮฟฯฮฏฮป ฯฮฑฯ ฮบฮฑฮน ฮดฮตฮฝ ฮธฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮณฮนฮฑ commits ฯฮฟฯ
ฮณฮฏฮฝฮฟฮฝฯฮฑฮน ฮผฮญฯฯ ฯฮฟฯ
web UI, ฯฯฯฯ ฯฮต ฮฑฮฝฮตฮฒฮฑฯฮผฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฑ, ฮฑฮปฮปฮฑฮณฮญฯ ฮฎ merge commits. ฮฮนฮฑ ฯฮฟฮฝ ฯฯ
ฯฯฮตฯฮนฯฮผฯ commit ฮผฮต ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ, ฮธฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮฑฮฝฯฮฏ ฮฑฯ
ฯฮฟฯ ฮท ฮตฮนฮดฮนฮบฮฎ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท %s. ฮฯ
ฯฮฎ ฮท ฯฯฮธฮผฮนฯฮท ฮดฮตฮฝ ฮตฯฮทฯฮตฮฌฮถฮตฮน commit ฯฮฟฯ
ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฎฮดฮท.
openid_desc=ฮคฮฟ OpenID ฯฮฑฯ ฮตฯฮนฯฯฮญฯฮตฮน ฮฝฮฑ ฮฑฮฝฮฑฮธฮญฯฮตฯฮต ฯฮฟฮฝ ฮญฮปฮตฮณฯฮฟ ฯฮฑฯ
ฯฯฯฮทฯฮฑฯ ฯฮต ฮญฮฝฮฑฮฝ ฮตฮพฯฯฮตฯฮนฮบฯ ฯฮฌฯฮฟฯฮฟ.
manage_ssh_keys=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮบฮปฮตฮนฮดฮนฯฮฝ SSH
manage_ssh_principals=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮคฯฮฝ ฮฯฯฯฮฝ ฮ ฮนฯฯฮฟฯฮฟฮนฮทฯฮนฮบฮฟฯ SSH
manage_gpg_keys=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮบฮปฮตฮนฮดฮนฯฮฝ GPG
add_key=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮบฮปฮตฮนฮดฮนฮฟฯ
-ssh_desc=ฮฯ
ฯฮฌ ฯฮฑ ฮดฮทฮผฯฯฮนฮฑ ฮบฮปฮตฮนฮดฮนฮฌ SSH ฮธฮฑ ฯฯ
ฯฯฮตฯฮนฮธฮฟฯฮฝ ฮผฮต ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮคฮฑ ฮนฮดฮนฯฯฮนฮบฮฌ ฮบฮปฮตฮนฮดฮนฮฌ ฯฮฟฯ
ฯฮฟฯ
ฯ ฮฑฮฝฯฮนฯฯฮฟฮนฯฮฟฯฮฝ ฮธฮฑ ฮตฯฮนฯฯฮญฯฮฟฯ
ฮฝ ฯฮปฮฎฯฮท ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฌ ฯฮฑฯ. ฮฮฝฮฑ ฮตฯฮนฮฒฮตฮฒฮฑฮนฯฮผฮญฮฝฮฟ ฮบฮปฮตฮนฮดฮฏ SSH ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮณฮนฮฑ ฯฮทฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฯฯฮฝ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ (commits) ฯฮฑฯ.
+ssh_desc=ฮฯ
ฯฮฌ ฯฮฑ ฮดฮทฮผฯฯฮนฮฑ ฮบฮปฮตฮนฮดฮนฮฌ SSH ฮธฮฑ ฯฯ
ฯฯฮตฯฮนฮธฮฟฯฮฝ ฮผฮต ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮคฮฑ ฮนฮดฮนฯฯฮนฮบฮฌ ฮบฮปฮตฮนฮดฮนฮฌ ฯฮฟฯ
ฯฮฟฯ
ฯ ฮฑฮฝฯฮนฯฯฮฟฮนฯฮฟฯฮฝ ฮธฮฑ ฮตฯฮนฯฯฮญฯฮฟฯ
ฮฝ ฯฮปฮฎฯฮท ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฌ ฯฮฑฯ. ฮฮฝฮฑ ฮตฯฮนฮฒฮตฮฒฮฑฮนฯฮผฮญฮฝฮฟ ฮบฮปฮตฮนฮดฮฏ SSH ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮณฮนฮฑ ฯฮทฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฯฯฮฝ commit ฯฮฑฯ.
principal_desc=ฮฯ
ฯฮญฯ ฮฟฮน ฮฑฯฯฮญฯ ฯฮนฯฯฮฟฯฮฟฮนฮทฯฮนฮบฯฮฝ SSH ฯฯ
ฮฝฮดฮญฮฟฮฝฯฮฑฮน ฮผฮต ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮบฮฑฮน ฮตฯฮนฯฯฮญฯฮฟฯ
ฮฝ ฯฮทฮฝ ฯฮปฮฎฯฮท ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฌ ฯฮฑฯ.
-gpg_desc=ฮฯ
ฯฮฌ ฯฮฑ ฮดฮทฮผฯฯฮนฮฑ ฮบฮปฮตฮนฮดฮนฮฌ GPG ฯฯ
ฯฯฮตฯฮฏฮถฮฟฮฝฯฮฑฮน ฮผฮต ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮบฮฑฮน ฮตฯฮนฯฯฮญฯฮฟฯ
ฮฝ ฯฮทฮฝ ฮตฯฮนฮบฯฯฯฯฮท ฯฯฮฝ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ (commits) ฯฮฑฯ. ฮฯฮฑฯฮฎฯฯฮต ฯฮฑ ฮนฮดฮนฯฯฮนฮบฮฌ ฮบฮปฮตฮนฮดฮนฮฌ ฯฮฑฯ ฮฑฯฯฮฑฮปฮฎ, ฮบฮฑฮธฯฯ ฮตฯฮนฯฯฮญฯฮฟฯ
ฮฝ ฯฮทฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฯฯฮฝ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ (commits) ฮตฮบ ฮผฮญฯฮฟฯ
ฯ ฯฮฑฯ.
+gpg_desc=ฮฯ
ฯฮฌ ฯฮฑ ฮดฮทฮผฯฯฮนฮฑ ฮบฮปฮตฮนฮดฮนฮฌ GPG ฯฯ
ฯฯฮตฯฮฏฮถฮฟฮฝฯฮฑฮน ฮผฮต ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮบฮฑฮน ฮตฯฮนฯฯฮญฯฮฟฯ
ฮฝ ฯฮทฮฝ ฮตฯฮนฮบฯฯฯฯฮท ฯฯฮฝ commit ฯฮฑฯ. ฮฯฮฑฯฮฎฯฯฮต ฯฮฑ ฮนฮดฮนฯฯฮนฮบฮฌ ฮบฮปฮตฮนฮดฮนฮฌ ฯฮฑฯ ฮฑฯฯฮฑฮปฮฎ, ฮบฮฑฮธฯฯ ฮตฯฮนฯฯฮญฯฮฟฯ
ฮฝ ฯฮทฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฯฯฮฝ commits ฮตฮบ ฮผฮญฯฮฟฯ
ฯ ฯฮฑฯ.
ssh_helper=ฮงฯฮตฮนฮฌฮถฮตฯฯฮต ฮฒฮฟฮฎฮธฮตฮนฮฑ; ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮตฯ
ฯฮตฮฏฯฮต ฯฮฟฮฝ ฮฟฮดฮทฮณฯ ฯฮฟฯ
GitHub ฮณฮนฮฑ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฯฮฑ ฮดฮนฮบฮฌ ฯฮฑฯ ฮบฮปฮตฮนฮดฮนฮฌ SSH ฮฎ ฮฝฮฑ ฮตฯฮนฮปฯฯฮตฯฮต ฮบฮฟฮนฮฝฮฌ ฯฯฮฟฮฒฮปฮฎฮผฮฑฯฮฑ ฯฮฟฯ
ฮฏฯฯฯ ฮฑฮฝฯฮนฮผฮตฯฯฯฮฏฯฮตฯฮต ฮผฮต ฯฮท ฯฯฮฎฯฮท ฯฮฟฯ
SSH.
gpg_helper=ฮงฯฮตฮนฮฌฮถฮตฯฯฮต ฮฒฮฟฮฎฮธฮตฮนฮฑ; ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮตฯ
ฯฮตฮฏฯฮต ฯฮฟฮฝ ฮฟฮดฮทฮณฯ ฯฮฟฯ
GitHub ฮณฮนฮฑ ฯฮฟ GPG .
add_new_key=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮบฮปฮตฮนฮดฮนฮฟฯ SSH
add_new_gpg_key=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮบฮปฮตฮนฮดฮนฮฟฯ GPG
key_content_ssh_placeholder=ฮฯฯฮฏฮถฮตฮน ฮผฮต ยซssh-ed25519ยป, ยซssh-rsaยป, ยซecdsa-sha2-nistp256ยป, ยซecdsa-sha2-nistp384ยป, ยซecdsa-sha2-nistp521ยป, ยซsk-ecdsa-sha2-nistp256@openssh.comยป, ฮฎ ยซsk-ssh-ed25519@openssh.comยป
key_content_gpg_placeholder=ฮฯฯฮฏฮถฮตฮน ฮผฮต ยซ-----BEGIN PGP PUBLIC KEY BLOCK-----ยป
-add_new_principal=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮฯฯฮฎฯ (Principal)
+add_new_principal=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮฑฯฯฮฎฯ (Principal)
ssh_key_been_used=ฮฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ SSH ฮญฯฮตฮน ฮฎฮดฮท ฯฯฮฟฯฯฮตฮธฮตฮฏ ฯฯฮฟ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ.
ssh_key_name_used=ฮฅฯฮฌฯฯฮตฮน ฮฎฮดฮท ฮญฮฝฮฑ SSH ฮบฮปฮตฮนฮดฮฏ ฮผฮต ฯฮฟ ฮฏฮดฮนฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
ssh_principal_been_used=ฮฯ
ฯฮฎ ฮท ฮฑฯฯฮฎ ฯฮนฯฯฮฟฯฮฟฮฏฮทฯฮทฯ (principal) ฮญฯฮตฮน ฮฎฮดฮท ฯฯฮฟฯฯฮตฮธฮตฮฏ ฯฯฮฟ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ.
gpg_key_id_used=ฮฅฯฮฌฯฯฮตฮน ฮฎฮดฮท ฮดฮทฮผฯฯฮนฮฟ ฮบฮปฮตฮนฮดฮฏ GPG ฮผฮต ฯฮฟ ฮฏฮดฮนฮฟ ID.
gpg_no_key_email_found=ฮฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ GPG ฮดฮตฮฝ ฯฮฑฮนฯฮนฮฌฮถฮตฮน ฮผฮต ฮฟฯฮฟฮนฮฑฮดฮฎฯฮฟฯฮต ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท ฮทฮปฮตฮบฯฯฮฟฮฝฮนฮบฮฟฯ ฯฮฑฯฯ
ฮดฯฮฟฮผฮตฮฏฮฟฯ
ฯฮฟฯ
ฯฯฮตฯฮฏฮถฮตฯฮฑฮน ฮผฮต ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮฯฮฟฯฮตฮฏ ฮฑฮบฯฮผฮฑ ฮฝฮฑ ฯฯฮฟฯฯฮตฮธฮตฮฏ, ฮฑฮฝ ฯ
ฯฮฟฮณฯฮฌฯฮตฯฮต ฯฮฟ ฯฮฑฯฮตฯฯฮผฮตฮฝฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ (token).
gpg_key_matched_identities=ฮคฮฑฯ
ฯฯฯฮทฯฮตฯ ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ:
-gpg_key_matched_identities_long=ฮฮน ฮตฮฝฯฯฮผฮฑฯฯฮผฮญฮฝฮตฯ ฯฮฑฯ
ฯฯฯฮทฯฮตฯ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ ฮผฮต ฯฮนฯ ฮฑฮบฯฮปฮฟฯ
ฮธฮตฯ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ email ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ ฯฯฮฎฯฯฮท. ฮฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ ฮผฮต ฮฑฯ
ฯฮญฯ ฯฮนฯ ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ email ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮตฯฮฑฮปฮทฮธฮตฯ
ฯฮฟฯฮฝ ฮผฮต ฮฑฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ.
+gpg_key_matched_identities_long=ฮฮน ฮตฮฝฯฯฮผฮฑฯฯฮผฮญฮฝฮตฯ ฯฮฑฯ
ฯฯฯฮทฯฮตฯ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ ฮผฮต ฯฮนฯ ฮฑฮบฯฮปฮฟฯ
ฮธฮตฯ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ email ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ ฯฯฮฎฯฯฮท. ฮคฮฑ commit ฯฮฟฯ
ฯฮตฯฮนฮญฯฮฟฯ
ฮฝ ฮฑฯ
ฯฮญฯ ฯฮนฯ ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ email ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮตฯฮฑฮปฮทฮธฮตฯ
ฯฮฟฯฮฝ ฮผฮต ฮฑฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ.
gpg_key_verified=ฮฯฮฑฮปฮทฮธฮตฯ
ฮผฮญฮฝฮฟ ฮบฮปฮตฮนฮดฮฏ
-gpg_key_verified_long=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ ฮญฯฮตฮน ฮตฯฮฑฮปฮทฮธฮตฯ
ฯฮตฮฏ ฮผฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ (token) ฮบฮฑฮน ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮณฮนฮฑ ฮฝฮฑ ฮตฯฮฑฮปฮทฮธฮตฯฯฮตฮน ฯฮนฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ ฮผฮต ฮฟฯฮฟฮนฮตฯฮดฮฎฯฮฟฯฮต ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ email ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ ฯฯฮฎฯฯฮท ฮตฮบฯฯฯ ฮฑฯฯ ฮฟฯฮฟฮนฮฑฮดฮฎฯฮฟฯฮต ฮฑฮฝฯฮนฯฯฮฟฮนฯฮนฯฮผฮญฮฝฮท ฯฮฑฯ
ฯฯฯฮทฯฮฑ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ.
+gpg_key_verified_long=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ ฮญฯฮตฮน ฮตฯฮฑฮปฮทฮธฮตฯ
ฯฮตฮฏ ฮผฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ (token) ฮบฮฑฮน ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮณฮนฮฑ ฮฝฮฑ ฮตฯฮฑฮปฮทฮธฮตฯฯฮตฮน ฯฮฑ commit ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ ฮผฮต ฮฟฯฮฟฮนฮตฯฮดฮฎฯฮฟฯฮต ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ email ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ ฯฯฮฎฯฯฮท ฮตฮบฯฯฯ ฮฑฯฯ ฮฟฯฮฟฮนฮฑฮดฮฎฯฮฟฯฮต ฮฑฮฝฯฮนฯฯฮฟฮนฯฮนฯฮผฮญฮฝฮท ฯฮฑฯ
ฯฯฯฮทฯฮฑ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ.
gpg_key_verify=ฮฯฮฑฮปฮฎฮธฮตฯ
ฯฮท
gpg_invalid_token_signature=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ GPG, ฮท ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฮบฮฑฮน ฯฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ (token) ฮดฮตฮฝ ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ ฮฎ ฯฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ (token) ฮตฮฏฮฝฮฑฮน ฯฮฑฯฯฯฮทฮผฮญฮฝฮฟ.
gpg_token_required=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮดฯฯฮตฯฮต ฮผฮนฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฮณฮนฮฑ ฯฮฟ ฯฮฑฯฮฑฮบฮฌฯฯ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ
@@ -815,7 +881,7 @@ gpg_token_signature=ฮฯฯฮฑฮบฮนฯฮผฮญฮฝฮท ฯ
ฯฮฟฮณฯฮฑฯฮฎ GPG
key_signature_gpg_placeholder=ฮฯฯฮฏฮถฮตฮน ฮผฮต ยซ-----BEGIN PGP SIGNATURE-----ยป
verify_gpg_key_success=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ GPG ยซ%sยป ฮตฯฮฑฮปฮทฮธฮตฯฯฮทฮบฮต.
ssh_key_verified=ฮฯฮฑฮปฮทฮธฮตฯ
ฮผฮญฮฝฮฟ ฮบฮปฮตฮนฮดฮฏ
-ssh_key_verified_long=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ ฮญฯฮตฮน ฮตฯฮฑฮปฮทฮธฮตฯ
ฯฮตฮฏ ฮผฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฮบฮฑฮน ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮณฮนฮฑ ฮฝฮฑ ฮตฯฮฑฮปฮทฮธฮตฯฯฮตฮน ฯฮฑ commits ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ ฮผฮต ฮฟฯฮฟฮนฮตฯฮดฮฎฯฮฟฯฮต ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ ฮทฮปฮตฮบฯฯฮฟฮฝฮนฮบฮฟฯ ฯฮฑฯฯ
ฮดฯฮฟฮผฮตฮฏฮฟฯ
ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ ฯฯฮฎฯฯฮท.
+ssh_key_verified_long=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ ฮญฯฮตฮน ฮตฯฮฑฮปฮทฮธฮตฯ
ฯฮตฮฏ ฮผฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฮบฮฑฮน ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮณฮนฮฑ ฮฝฮฑ ฮตฯฮฑฮปฮทฮธฮตฯฯฮตฮน ฯฮฑ commit ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ ฮผฮต ฮฟฯฮฟฮนฮตฯฮดฮฎฯฮฟฯฮต ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ ฮดฮนฮตฯ
ฮธฯฮฝฯฮตฮนฯ ฮทฮปฮตฮบฯฯฮฟฮฝฮนฮบฮฟฯ ฯฮฑฯฯ
ฮดฯฮฟฮผฮตฮฏฮฟฯ
ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ ฯฯฮฎฯฯฮท.
ssh_key_verify=ฮฯฮฑฮปฮฎฮธฮตฯ
ฯฮท
ssh_invalid_token_signature=ฮคฮฟ ฯฮฑฯฮตฯฯฮผฮตฮฝฮฟ ฮบฮปฮตฮนฮดฮฏ SSH, ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฮฎ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฮดฮตฮฝ ฯฮฑฮนฯฮนฮฌฮถฮตฮน ฮฎ ฯฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฮญฮปฮทฮพฮต.
ssh_token_required=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮดฯฯฮตฯฮต ฮผฮนฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฮณฮนฮฑ ฯฮฟ ฯฮฑฯฮฑฮบฮฌฯฯ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ
@@ -837,15 +903,15 @@ ssh_key_deletion=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮบฮปฮตฮนฮดฮนฮฟฯ SSH
gpg_key_deletion=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮบฮปฮตฮนฮดฮนฮฟฯ GPG
ssh_principal_deletion=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฯฯฯฮฝ ฮ ฮนฯฯฮฟฯฮฟฮนฮทฯฮนฮบฮฟฯ SSH
ssh_key_deletion_desc=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮตฮฝฯฯ ฮบฮปฮตฮนฮดฮนฮฟฯ SSH ฮฑฮฝฮฑฮบฮฑฮปฮตฮฏ ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮฎ ฯฮฟฯ
ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
-gpg_key_deletion_desc=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮตฮฝฯฯ ฮบฮปฮตฮนฮดฮนฮฟฯ GPG ฮฑฯฮฟ-ฮตฯฮฑฮปฮทฮธฮตฯฮตฮน ฯฮนฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฯฮฟฯ
ฮญฯฮฟฯ
ฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮฑฯฯ ฮฑฯ
ฯฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
+gpg_key_deletion_desc=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮตฮฝฯฯ ฮบฮปฮตฮนฮดฮนฮฟฯ GPG ฮฑฯฮฑฮนฯฮตฮฏ ฯฮนฯ ฮตฯฮฑฮปฮทฮธฮตฯฯฮตฮนฯ ฯฯฮฝ commit ฯฮฟฯ
ฮญฯฮฟฯ
ฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮฑฯฯ ฮฑฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
ssh_principal_deletion_desc=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮผฮนฮฑฯ ฮฑฯฯฮฎฯ ฯฮนฯฯฮฟฯฮฟฮนฮทฯฮนฮบฮฟฯ SSH ฮฑฮฝฮฑฮบฮฑฮปฮตฮฏ ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮฎ ฯฮทฯ ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
ssh_key_deletion_success=ฮคฮฟ SSH ฮบฮปฮตฮนฮดฮฏ ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
gpg_key_deletion_success=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ GPG ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
ssh_principal_deletion_success=ฮ ฮฑฯฯฮฎ ฯฮนฯฯฮฟฯฮฟฮนฮทฯฮนฮบฮฟฯ ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
-added_on=ฮ ฯฮฟฯฯฮญฮธฮทฮบฮฑฮฝ ฯฯฮนฯ %s
+added_on=ฮ ฯฮฟฯฯฮญฮธฮทฮบฮต ฯฯฮนฯ %s
valid_until_date=ฮฮณฮบฯ
ฯฮฟ ฮผฮญฯฯฮน ฯฮท %s
valid_forever=ฮฮณฮบฯ
ฯฮฟ ฮณฮนฮฑ ฯฮฌฮฝฯฮฑ
-last_used=ฮคฮตฮปฮตฯ
ฯฮฑฮฏฮฑ ฯฯฮฎฯฮท ฯฯฮนฯ
+last_used=ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฮธฮทฮบฮต ฯฮตฮปฮตฯ
ฯฮฑฮฏฮฑ ฯฯฮนฯ
no_activity=ฮฮฑฮผฮฏฮฑ ฯฯฯฯฯฮฑฯฮท ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฑ
can_read_info=ฮฮฝฮฌฮณฮฝฯฯฮท
can_write_info=ฮฮณฮณฯฮฑฯฮฎ
@@ -854,15 +920,15 @@ token_state_desc=ฮฯ
ฯฯ ฯฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฮญฯฮตฮน ฯฯฮทฯฮนฮผฮฟฯฮฟ
principal_state_desc=ฮฯ
ฯฮฎ ฮท ฮฑฯฯฮฎ ฯฮนฯฯฮฟฯฮฟฮนฮทฯฮนฮบฮฟฯ ฮญฯฮตฮน ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฯฮนฯ ฯฮตฮปฮตฯ
ฯฮฑฮฏฮตฯ 7 ฮทฮผฮญฯฮตฯ
show_openid=ฮฮผฯฮฌฮฝฮนฯฮท ฯฯฮฟ ฯฯฮฟฯฮฏฮป
hide_openid=ฮฯฯฮบฯฯ
ฯฮท ฮฑฯฯ ฯฮฟ ฯฯฮฟฯฮฏฮป
-ssh_disabled=SSH ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮฟ
-ssh_signonly=ฮคฮฟ SSH ฮตฮฏฮฝฮฑฮน ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮฟ ฮฑฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ, ฮญฯฯฮน ฮฑฯ
ฯฮฌ ฯฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮตฮฏฮฝฮฑฮน ฮผฯฮฝฮฟ ฮณฮนฮฑ ฯฮทฮฝ ฮตฯฮฑฮปฮฎฮธฮตฯ
ฯฮท ฯ
ฯฮฟฮณฯฮฑฯฮฎฯ ฯฯฮฝ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ.
+ssh_disabled=ฮคฮฟ SSH ฮตฮฏฮฝฮฑฮน ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮฟ
+ssh_signonly=ฮคฮฟ SSH ฮตฮฏฮฝฮฑฮน ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮฟ ฮฑฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ, ฮญฯฯฮน ฮฑฯ
ฯฮฌ ฯฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮตฮฏฮฝฮฑฮน ฮผฯฮฝฮฟ ฮณฮนฮฑ ฯฮทฮฝ ฮตฯฮฑฮปฮฎฮธฮตฯ
ฯฮท ฯ
ฯฮฟฮณฯฮฑฯฯฮฝ ฯฯฮฝ commit.
ssh_externally_managed=ฮฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ SSH ฮดฮนฮฑฯฮตฮนฯฮฏฮถฮตฯฮฑฮน ฮตฮพฯฯฮตฯฮนฮบฮฌ ฮณฮนฮฑ ฮฑฯ
ฯฯฮฝ ฯฮฟ ฯฯฮฎฯฯฮท
manage_social=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮฃฯ
ฯฯฮตฯฮนฮถฯฮผฮตฮฝฯฮฝ ฮฮฟฮณฮฑฯฮนฮฑฯฮผฯฮฝ ฮฮฟฮนฮฝฯฮฝฮนฮบฯฮฝ ฮฮนฮบฯฯฯฮฝ
social_desc=ฮฯ
ฯฮฟฮฏ ฮฟฮน ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฮฏ ฮบฮฟฮนฮฝฯฮฝฮนฮบฯฮฝ ฮดฮนฮบฯฯฯฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮฟฯฮฝ ฮณฮนฮฑ ฮฝฮฑ ฯฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮฮตฮฒฮฑฮนฯฮธฮตฮฏฯฮต ฯฯฮน ฯฮฟฯ
ฯ ฮฑฮฝฮฑฮณฮฝฯฯฮฏฮถฮตฯฮต ฯฮปฮฟฯ
ฯ.
unbind=ฮฯฮฟฯฯฮฝฮดฮตฯฮท
unbind_success=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฮบฮฟฮนฮฝฯฮฝฮนฮบฮฟฯ ฮดฮนฮบฯฯฮฟฯ
ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ ฮตฯฮนฯฯ
ฯฯฯ.
-manage_access_token=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮดฮนฮฑฮบฯฮนฯฮนฮบฯฮฝ ฯฯฯฯฮฒฮฑฯฮทฯ (tokens)
+manage_access_token=ฮฮนฮฑฮบฯฮนฯฮนฮบฮฌ ฯฯฯฯฮฒฮฑฯฮทฯ (tokens)
generate_new_token=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฝฮญฮฟฯ
ฮดฮนฮฑฮบฯฮนฯฮนฮบฮฟฯ (token)
tokens_desc=ฮฯ
ฯฮฌ ฯฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฮฌ (tokens) ฯฮฑฯฮญฯฮฟฯ
ฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮผฮญฯฯ ฯฮฟฯ
API ฯฮฟฯ
Forgejo.
token_name=ฮฮฝฮฟฮผฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฮฟฯ
@@ -875,14 +941,14 @@ access_token_deletion_cancel_action=ฮฮบฯ
ฯฮฟ
access_token_deletion_confirm_action=ฮฮนฮฑฮณฯฮฑฯฮฎ
access_token_deletion_desc=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮตฮฝฯฯ ฮดฮนฮฑฮบฯฮนฯฮนฮบฮฟฯ ฮธฮฑ ฮฑฮฝฮฑฮบฮฑฮปฮญฯฮตฮน ฮฟฯฮนฯฯฮนฮบฮฌ ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮณฮนฮฑ ฮตฯฮฑฯฮผฮฟฮณฮญฯ ฯฮฟฯ
ฯฮฟ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฟฯฮฝ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
delete_token_success=ฮคฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ. ฮฮน ฮตฯฮฑฯฮผฮฟฮณฮญฯ ฯฮฟฯ
ฯฮฟ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฟฯฮฝ ฮดฮตฮฝ ฮญฯฮฟฯ
ฮฝ ฯฮปฮญฮฟฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
-repo_and_org_access=ฮ ฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮบฮฑฮน ฮฯฮณฮฑฮฝฮนฯฮผฯ
+repo_and_org_access=ฮ ฯฯฯฮฒฮฑฯฮท ฯฯฮฟ repository ฮบฮฑฮน ฮฟฯฮณฮฑฮฝฮนฯฮผฯ
permissions_public_only=ฮฮทฮผฯฯฮนฮฑ ฮผฯฮฝฮฟ
permissions_access_all=ฮฮปฮฑ (ฮดฮทฮผฯฯฮนฮฑ, ฮนฮดฮนฯฯฮนฮบฮฌ, ฮบฮฑฮน ฯฮตฯฮนฮฟฯฮนฯฮผฮญฮฝฮฑ)
-select_permissions=ฮฯฮนฮปฮญฮพฯฮต ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ
+select_permissions=ฮฯฮนฮปฮฟฮณฮฎ ฮดฮนฮบฮฑฮนฯฮผฮฌฯฯฮฝ
permission_no_access=ฮฮฑฮผฮฏฮฑ ฯฯฯฯฮฒฮฑฯฮท
permission_read=ฮฮฝฮฑฮณฮฝฯฯฮผฮญฮฝฮตฯ
permission_write=ฮฮฝฮฌฮณฮฝฯฯฮท ฮบฮฑฮน ฮตฮณฮณฯฮฑฯฮฎ
-access_token_desc=ฮคฮฑ ฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฑ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯฮฝ ฯฮตฯฮนฮฟฯฮฏฮถฮฟฯ
ฮฝ ฯฮทฮฝ ฮฌฮดฮตฮนฮฑ ฮผฯฮฝฮฟ ฯฯฮนฯ ฮฑฮฝฯฮฏฯฯฮฟฮนฯฮตฯ ฮดฮนฮฑฮดฯฮฟฮผฮญฯ API . ฮฮนฮฑฮฒฮฌฯฯฮต ฯฮฟ ฮตฮณฯฮตฮนฯฮฏฮดฮนฮฟ ฮณฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ.
+access_token_desc=ฮคฮฑ ฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฑ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯฮฝ ฯฮตฯฮนฮฟฯฮฏฮถฮฟฯ
ฮฝ ฯฮทฮฝ ฮฌฮดฮตฮนฮฑ ฮผฯฮฝฮฟ ฯฯฮนฯ ฮฑฮฝฯฮฏฯฯฮฟฮนฯฮตฯ ฮดฮนฮฑฮดฯฮฟฮผฮญฯ API . ฮฮนฮฑฮฒฮฌฯฯฮต ฯฮฟ ฮตฮณฯฮตฮนฯฮฏฮดฮนฮฟ ฮณฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ.
at_least_one_permission=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮตฯฮนฮปฮญฮพฮตฯฮต ฯฮฟฯ
ฮปฮฌฯฮนฯฯฮฟฮฝ ฮญฮฝฮฑ ฮดฮนฮบฮฑฮฏฯฮผฮฑ ฮณฮนฮฑ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ
permissions_list=ฮฮนฮบฮฑฮนฯฮผฮฑฯฮฑ:
@@ -897,7 +963,7 @@ create_oauth2_application_button=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎฯ
create_oauth2_application_success=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮฑฯฮต ฮตฯฮนฯฯ
ฯฯฯ ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ OAuth2.
update_oauth2_application_success=ฮฮฝฮทฮผฮตฯฯฯฮฑฯฮต ฯฮทฮฝ ฮตฯฮฑฯฮผฮฟฮณฮฎ OAuth2 ฮตฯฮนฯฯ
ฯฯฯ.
oauth2_application_name=ฮฮฝฮฟฮผฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎฯ
-oauth2_confidential_client=ฮฮผฯฮนฯฯฮตฯ
ฯฮนฮบฯฯ ฮ ฮตฮปฮฌฯฮทฯ. ฮฯฮนฮปฮญฮพฯฮต ฯฮฟ ฮณฮนฮฑ ฮตฯฮฑฯฮผฮฟฮณฮญฯ ฯฮฟฯ
ฮดฮนฮฑฯฮทฯฮฟฯฮฝ ฯฮฟ ฮผฯ
ฯฯฮนฮบฯ ฮบฯฮดฮนฮบฯ ฮบฯฯ
ฯฯ, ฯฯฯฯ ฯฯ ฮฟฮน ฮตฯฮฑฯฮผฮฟฮณฮญฯ ฮนฯฯฮฟฯ. ฮฮทฮฝ ฮตฯฮนฮปฮญฮณฮตฯฮต ฮณฮนฮฑ ฮตฮณฮณฮตฮฝฮตฮฏฯ ฮตฯฮฑฯฮผฮฟฮณฮญฯ, ฯฯ
ฮผฯฮตฯฮนฮปฮฑฮผฮฒฮฑฮฝฮฟฮผฮญฮฝฯฮฝ ฮตฯฮฑฯฮผฮฟฮณฯฮฝ ฮตฯฮนฯฮฌฮฝฮตฮนฮฑฯ ฮตฯฮณฮฑฯฮฏฮฑฯ ฮบฮฑฮน ฮตฯฮฑฯฮผฮฟฮณฯฮฝ ฮณฮนฮฑ ฮบฮนฮฝฮทฯฮฌ.
+oauth2_confidential_client=ฮฮผฯฮนฯฯฮตฯ
ฯฮนฮบฯฯ ฯฮตฮปฮฌฯฮทฯ (client). ฮฯฮนฮปฮญฮพฯฮต ฯฮฟ ฮณฮนฮฑ ฮตฯฮฑฯฮผฮฟฮณฮญฯ ฯฮฟฯ
ฮดฮนฮฑฯฮทฯฮฟฯฮฝ ฯฮฟ ฮผฯ
ฯฯฮนฮบฯ ฮบฯฮดฮนฮบฯ ฮบฯฯ
ฯฯ, ฯฯฯฯ ฯ.ฯ. ฮตฯฮฑฯฮผฮฟฮณฮญฯ ฮนฯฯฮฟฯ. ฮฮทฮฝ ฮตฯฮนฮปฮญฮณฮตฯฮต ฮณฮนฮฑ ฮตฮณฮณฮตฮฝฮตฮฏฯ ฮตฯฮฑฯฮผฮฟฮณฮญฯ, ฯฯ
ฮผฯฮตฯฮนฮปฮฑฮผฮฒฮฑฮฝฮฟฮผฮญฮฝฯฮฝ ฮตฯฮฑฯฮผฮฟฮณฯฮฝ ฮตฯฮนฯฮฌฮฝฮตฮนฮฑฯ ฮตฯฮณฮฑฯฮฏฮฑฯ ฮบฮฑฮน ฮตฯฮฑฯฮผฮฟฮณฯฮฝ ฮณฮนฮฑ ฮบฮนฮฝฮทฯฮฌ.
oauth2_redirect_uris=URI ฮฮฝฮฑฮบฮฑฯฮตฯฮธฯ
ฮฝฯฮทฯ. ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮณฯฮฑฮผฮผฮฎ ฮณฮนฮฑ ฮบฮฌฮธฮต URI.
save_application=ฮฯฮฟฮธฮฎฮบฮตฯ
ฯฮท
oauth2_client_id=ฮคฮฑฯ
ฯฯฯฮทฯฮฑ ฮ ฮตฮปฮฌฯฮท
@@ -925,7 +991,7 @@ twofa_disable=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฮนฯฯฮฟฯฮฟฮฏฮทฯฮทฯ ฮดฯฮฟ ฯฮฑ
twofa_scratch_token_regenerate=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฝฮญฮฟฯ
ฮบฮปฮตฮนฮดฮนฮฟฯ ฮผฮฏฮฑฯ ฯฯฮฎฯฮทฯ
twofa_scratch_token_regenerated=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ ฮฑฮฝฮฌฮบฯฮทฯฮทฯ ฮผฮนฮฑฯ ฯฯฮฎฯฮทฯ ฮตฮฏฮฝฮฑฮน ฯฯฯฮฑ %s. ฮฯฮฟฮธฮทฮบฮตฯฯฯฮต ฯฮฟ ฯฮต ฮฑฯฯฮฑฮปฮญฯ ฮผฮญฯฮฟฯ, ฮบฮฑฮธฯฯ ฮดฮต ฮธฮฑ ฮตฮผฯฮฑฮฝฮนฯฯฮตฮฏ ฮพฮฑฮฝฮฌ.
twofa_enroll=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฮนฯฯฮฟฯฮฟฮฏฮทฯฮทฯ ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ
-twofa_disable_note=ฮฮฝ ฯฯฮตฮนฮฑฯฯฮตฮฏ, ฮธฮฑ ฮผฯฮฟฯฮญฯฮตฯฮต ฮฝฮฑ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮทฮฝ ฯฮนฯฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ ฮผฮตฯฮฑฮณฮตฮฝฮญฯฯฮตฯฮฑ.
+twofa_disable_note=ฮฮฝ ฯฯฮตฮนฮฑฯฯฮตฮฏ, ฮธฮฑ ฮผฯฮฟฯฮญฯฮตฯฮต ฮฝฮฑ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮทฮฝ ฯฮนฯฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ ฯฮต ฮผฮตฯฮฑฮณฮตฮฝฮญฯฯฮตฯฮท ฯฮฌฯฮท.
twofa_disable_desc=ฮ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฮทฯ ฯฮนฯฯฮฟฯฮฟฮฏฮทฯฮทฯ ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ ฮธฮฑ ฮบฮฑฯฮฑฯฯฮฎฯฮตฮน ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฮปฮนฮณฯฯฮตฯฮฟ ฮฑฯฯฮฑฮปฮฎ. ฮฮฏฯฯฮต ฮฒฮญฮฒฮฑฮนฮฟฮน;
regenerate_scratch_token_desc=ฮฮฝ ฯฮฌฯฮฑฯฮต ฯฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฮผฮฏฮฑฯ ฯฯฮฎฯฮทฯ ฯฮฑฯ ฮฎ ฯฮฟ ฮญฯฮตฯฮต ฮฎฮดฮท ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฮน ฮณฮนฮฑ ฮฝฮฑ ฯฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฮฟ ฮตฯฮฑฮฝฮฑฯฮญฯฮตฯฮต ฮตฮดฯ.
twofa_disabled=ฮ ฯฮนฯฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ ฮญฯฮตฮน ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮธฮตฮฏ.
@@ -936,7 +1002,7 @@ passcode_invalid=ฮ ฮบฯฮดฮนฮบฯฯ ฮตฮฏฮฝฮฑฮน ฮปฮฌฮธฮฟฯ. ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮพ
twofa_enrolled=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฮฑฯ ฮญฯฮตฮน ฮตฮณฮณฯฮฑฯฮตฮฏ ฯฮต ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ. ฮฯฮฟฮธฮทฮบฮตฯฯฯฮต ฯฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฮผฮนฮฑฯ ฯฯฮฎฯฮทฯ (%s) ฯฮต ฮญฮฝฮฑ ฮฑฯฯฮฑฮปฮญฯ ฮผฮญฯฮฟฯ, ฮตฯฮตฮนฮดฮฎ ฮดฮตฮฝ ฮธฮฑ ฮพฮฑฮฝฮฑฮตฮผฯฮฑฮฝฮนฯฯฮตฮฏ.
twofa_failed_get_secret=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮปฮฎฯฮทฯ ฮผฯ
ฯฯฮนฮบฮฟฯ.
-webauthn_desc=ฮคฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ ฮตฮฏฮฝฮฑฮน ฯฯ
ฯฮบฮตฯ
ฮญฯ ฯฮฟฯ
ฯฮตฯฮนฮญฯฮฟฯ
ฮฝ ฮบฯฯ
ฯฯฮฟฮณฯฮฑฯฮนฮบฮฌ ฮบฮปฮตฮนฮดฮนฮฌ. ฮฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮฟฯฮฝ ฮณฮนฮฑ ฯฮทฮฝ ฯฮนฯฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ. ฮคฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯฯ
ฮฝฮฌฮดฮฟฯ
ฮฝ ฮผฮต ฯฮนฯ ฯฯฮฟฮดฮนฮฑฮณฯฮฑฯฮญฯ ฯฮฟฯ
ฮฟฯฮฏฮถฮตฮน ฯฮฟ ฯฯฯฯฯ
ฯฮฟ WebAuthn .
+webauthn_desc=ฮคฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ ฮตฮฏฮฝฮฑฮน ฯฯ
ฯฮบฮตฯ
ฮญฯ ฯฮฟฯ
ฯฮตฯฮนฮญฯฮฟฯ
ฮฝ ฮบฯฯ
ฯฯฮฟฮณฯฮฑฯฮนฮบฮฌ ฮบฮปฮตฮนฮดฮนฮฌ. ฮฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮฟฯฮฝ ฮณฮนฮฑ ฯฮทฮฝ ฯฮนฯฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ. ฮคฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯฯ
ฮฝฮฌฮดฮฟฯ
ฮฝ ฮผฮต ฯฮนฯ ฯฯฮฟฮดฮนฮฑฮณฯฮฑฯฮญฯ ฯฮฟฯ
ฮฟฯฮฏฮถฮตฮน ฯฮฟ ฯฯฯฯฯ
ฯฮฟ WebAuthn .
webauthn_register_key=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮบฮปฮตฮนฮดฮนฮฟฯ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ
webauthn_nickname=ฮจฮตฯ
ฮดฯฮฝฯ
ฮผฮฟ
webauthn_delete_key=ฮฯฮฑฮฏฯฮตฯฮท ฮบฮปฮตฮนฮดฮนฮฟฯ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ
@@ -944,10 +1010,10 @@ webauthn_delete_key_desc=ฮฮฝ ฮฑฯฮฑฮนฯฮญฯฮตฯฮต ฮญฮฝฮฑ ฮบฮปฮตฮนฮดฮฏ ฮฑฯฯฮฑ
webauthn_key_loss_warning=ฮฮฝ ฯฮฌฯฮตฯฮต ฯฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ ฯฮฑฯ, ฮธฮฑ ฯฮฌฯฮตฯฮต ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
webauthn_alternative_tip=ฮฯฮฟฯฮตฮฏ ฮฝฮฑ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฯฯ
ฮธฮผฮฏฯฮตฯฮต ฮผฮนฮฑ ฯฯฯฯฮธฮตฯฮท ฮผฮญฮธฮฟฮดฮฟ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮทฯ.
-manage_account_links=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮฃฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฯฮฝ ฮฮฟฮณฮฑฯฮนฮฑฯฮผฯฮฝ
+manage_account_links=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฯฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฮฝ
manage_account_links_desc=ฮฯ
ฯฮฟฮฏ ฮฟฮน ฮตฮพฯฯฮตฯฮนฮบฮฟฮฏ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฮฏ ฮตฮฏฮฝฮฑฮน ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฮน ฯฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ Forgejo ฯฮฑฯ.
account_links_not_available=ฮ ฯฮฟฯ ฯฮฟ ฯฮฑฯฯฮฝ ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮตฮพฯฯฮตฯฮนฮบฮฟฮฏ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฮฏ ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฮน ฮผฮต ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฯฯฮฟ Forgejo.
-link_account=ฮฃฯฮฝฮดฮตฯฮท ฮฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
+link_account=ฮฃฯฮฝฮดฮตฯฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
remove_account_link=ฮฯฮฑฮฏฯฮตฯฮท ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
remove_account_link_desc=ฮ ฮบฮฑฯฮฌฯฮณฮทฯฮท ฮตฮฝฯฯ ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฮธฮฑ ฮฑฮฝฮฑฮบฮฑฮปฮญฯฮตฮน ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮฎ ฯฮฟฯ
ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ ฯฯฮฟ Forgejo. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
remove_account_link_success=ฮ ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฮญฯฮตฮน ฮฑฯฮฑฮนฯฮตฮธฮตฮฏ.
@@ -955,7 +1021,7 @@ remove_account_link_success=ฮ ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ
hooks.desc=ฮ ฯฮฟฯฮธฮฎฮบฮท webhooks ฯฮฟฯ
ฮธฮฑ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฟฯฮฝฯฮฑฮน ฮณฮนฮฑ ฯฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
ฯฮฑฯ ฮฑฮฝฮฎฮบฮฟฯ
ฮฝ.
orgs_none=ฮฮตฮฝ ฮตฮฏฯฯฮต ฮผฮญฮปฮฟฯ ฯฮต ฮบฮฌฯฮฟฮนฮฟ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ.
-repos_none=ฮฮตฮฝ ฯฮฑฯ ฮฑฮฝฮฎฮบฮตฮน ฮบฮฑฮฝฮญฮฝฮฑ ฮบฮฌฯฮฟฮนฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+repos_none=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮบฮฌฯฮฟฮนฮฟ repository ฯฮฟฯ
ฯฮฑฯ ฮฑฮฝฮฎฮบฮตฮน.
delete_account=ฮฮนฮฑฮณฯฮฑฯฮฎ ฯฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฯฮฑฯ
delete_prompt=ฮฯ
ฯฮฎ ฮท ฮตฮฝฮญฯฮณฮตฮนฮฑ ฮธฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฮน ฮผฯฮฝฮนฮผฮฑ ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ. ฮฮฮ ฮฮ ฮฮ ฮฮกฮฮ ฮฝฮฑ ฮตฯฮฑฮฝฮญฮปฮธฮตฮน.
@@ -983,25 +1049,35 @@ user_unblock_success = ฮ ฮฌฯฯฮท ฮฑฯฮฟฮบฮปฮตฮนฯฮผฮฟฯ ฯฮฟฯ
ฯฯฮฎฯฯฮท ฮฎ
change_password = ฮฮปฮปฮฑฮณฮฎ ฮบฯฮดฮนฮบฮฟฯ
blocked_users = ฮฯฮฟฮบฮปฮตฮนฯฮผฮญฮฝฮฟฮน ฯฯฮฎฯฯฮตฯ
user_block_success = ฮ ฮฑฯฮฟฮบฮปฮตฮนฯฮผฯฯ ฯฮฟฯ
ฯฯฮฎฯฯฮท ฮฎฯฮฑฮฝ ฮตฯฮนฯฯ
ฯฮฎฯ.
-additional_repo_units_hint = ฮฮฑ ฮณฮฏฮฝฮตฯฮฑฮน ฮตฮฝฮธฮฌฯฯฯ
ฮฝฯฮท ฯฯฮฟฯฮธฮฎฮบฮทฯ ฮผฮฟฮฝฮฌฮดฯฮฝ ฯฮต ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ
+additional_repo_units_hint = ฮฮฑ ฯฯ
ฮฝฮนฯฯฮฌฯฮฑฮน ฮท ฯฯฮฟฯฮธฮฎฮบฮท ฮผฮฟฮฝฮฌฮดฯฮฝ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ
pronouns = ฮฮฝฯฯฮฝฯ
ฮผฮฏฮตฯ
pronouns_custom = ฮบฮฌฯฮน ฮฌฮปฮปฮฟ
pronouns_unspecified = ฮฯฯฮฟฯฮดฮนฯฯฮนฯฯฮตฯ
hints = ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮญฯ
-additional_repo_units_hint_description = ฮฮผฯฮฌฮฝฮนฯฮท ฮบฮฟฯ
ฮผฯฮนฮฟฯ ยซฮ ฯฮฟฯฮธฮฎฮบฮท ฮผฮฟฮฝฮฌฮดฯฮฝ...ยป ฯฮต ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
ฮดฮตฮฝ ฮญฯฮฟฯ
ฮฝ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ ฯฮปฮตฯ ฯฮนฯ ฮดฮนฮฑฮธฮญฯฮนฮผฮตฯ ฮผฮฟฮฝฮฌฮดฮตฯ.
+additional_repo_units_hint_description = ฮฮผฯฮฌฮฝฮนฯฮท ฯ
ฯฯฮดฮตฮนฮพฮทฯ ยซฮ ฯฮฟฯฮธฮฎฮบฮท ฮผฮฟฮฝฮฌฮดฯฮฝ...ยป ฯฮต ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
ฮดฮตฮฝ ฮญฯฮฟฯ
ฮฝ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ ฯฮปฮตฯ ฯฮนฯ ฮดฮนฮฑฮธฮญฯฮนฮผฮตฯ ฮผฮฟฮฝฮฌฮดฮตฯ.
update_hints = ฮฮฝฮทฮผฮญฯฯฯฮท ฯฯ
ฮผฮฒฮฟฯ
ฮปฯฮฝ
update_hints_success = ฮฮน ฯฯ
ฮผฮฒฮฟฯ
ฮปฮญฯ ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮฑฮฝ.
+language.title = ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮท ฮณฮปฯฯฯฮฑ
+keep_activity_private.description = ฮ ฮดฮทฮผฯฯฮนฮฑ ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฌ ฯฮฑฯ ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฮฟฯฮฑฯฮฎ ฮผฯฮฝฮฟ ฯฮต ฮตฯฮฌฯ ฮบฮฑฮน ฯฯฮฟฯ
ฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮญฯ.
+language.localization_project = ฮฮฟฮทฮธฮฎฯฯฮต ฮผฮฑฯ ฮฝฮฑ ฮผฮตฯฮฑฯฯฮฌฯฮฟฯ
ฮผฮต ฯฮฟ Forgejo ฯฯฮทฮฝ ฮณฮปฯฯฯฮฑ ฯฮฑฯ! ฮ ฮตฯฮนฯฯฯฯฮตฯฮตฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ .
+language.description = ฮฯฯ ฮตฮดฯ ฮบฮฑฮน ฯฯฮฟ ฮตฮพฮฎฯ, ฮฑฯ
ฯฮฎ ฮท ฮณฮปฯฯฯฮฑ ฮธฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮฑฯฯ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ ฮณฮนฮฑ ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
+pronouns_custom_label = ฮฮนฮดฮนฮบฮญฯ ฮฑฮฝฯฯฮฝฯ
ฮผฮฏฮตฯ
+user_block_yourself = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฯฮต ฯฮฟฮฝ ฮตฮฑฯ
ฯฯ ฯฮฑฯ.
+change_username_redirect_prompt.with_cooldown.one = ฮคฮฟ ฯฮฑฮปฮนฯ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฮธฮฑ ฮณฮฏฮฝฮตฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮฟ ฯฯฮฑฮฝ ฮปฮฎฮพฮตฮน ฯฮต %[1]d ฮทฮผฮญฯฮฑ. ฮฮญฯฮฑ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฯฯฮฟฮฝฮนฮบฯ ฯฮปฮฑฮฏฯฮนฮฟ, ฮธฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮฝฮฑฮฝฮตฯฯฮตฯฮต ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฯฮฑฯ.
+change_username_redirect_prompt.with_cooldown.few = ฮคฮฟ ฯฮฑฮปฮนฯ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฮธฮฑ ฮณฮฏฮฝฮตฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮฟ ฯฯฮฑฮฝ ฮปฮฎฮพฮตฮน ฯฮต %[1]d ฮทฮผฮญฯฮตฯ. ฮฮญฯฮฑ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฯฯฮฟฮฝฮนฮบฯ ฯฮปฮฑฮฏฯฮนฮฟ, ฮธฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮฝฮฑฮฝฮตฯฯฮตฯฮต ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฯฮฑฯ.
+keep_pronouns_private = ฮฮผฯฮฌฮฝฮนฯฮท ฮฑฮฝฯฯฮฝฯ
ฮผฮนฯฮฝ ฮผฯฮฝฮฟ ฯฮต ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ
+keep_pronouns_private.description = ฮฯ
ฯฮฎ ฮท ฯฯฮธฮผฮนฯฮท ฮธฮฑ ฮฑฯฮฟฮบฯฯฯฮตฮน ฯฮนฯ ฮฑฮฝฯฯฮฝฯ
ฮผฮฏฮตฯ ฯฮฑฯ ฮฑฯฯ ฮผฮท-ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฯ
ฯ ฮตฯฮนฯฮบฮญฯฯฮตฯ.
[repo]
-new_repo_helper=ฮฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฯฮตฯฮนฮญฯฮตฮน ฯฮปฮฑ ฯฮฑ ฮฑฯฯฮตฮฏฮฑ ฮญฯฮณฮฟฯ
, ฯฯ
ฮผฯฮตฯฮนฮปฮฑฮผฮฒฮฑฮฝฮฟฮผฮญฮฝฮฟฯ
ฯฮฟฯ
ฮนฯฯฮฟฯฮนฮบฮฟฯ ฮตฮบฮดฯฯฮตฯฮฝ. ฮฮดฮท ฯฮนฮปฮฟฮพฮตฮฝฮตฮฏฯฮฑฮน ฮฑฮปฮปฮฟฯ; ฮฮตฯฮตฮณฮบฮฑฯฮฌฯฯฮฑฯฮท ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
+new_repo_helper=ฮฮฝฮฑ repository ฯฮตฯฮนฮญฯฮตฮน ฯฮปฮฑ ฯฮฑ ฮฑฯฯฮตฮฏฮฑ ฮญฯฮณฮฟฯ
, ฯฯ
ฮผฯฮตฯฮนฮปฮฑฮผฮฒฮฑฮฝฮฟฮผฮญฮฝฮฟฯ
ฯฮฟฯ
ฮนฯฯฮฟฯฮนฮบฮฟฯ ฮตฮบฮดฯฯฮตฯฮฝ. ฮฯฮตฯฮต ฮฎฮดฮท ฮญฮฝฮฑ ฯฮฟฯ
ฯฮนฮปฮฟฮพฮตฮฝฮตฮฏฯฮฑฮน ฮบฮฌฯฮฟฯ
ฮฑฮปฮปฮฟฯ; ฮฮตฯฮฑฯฮฟฯฮฌ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
owner=ฮฮดฮนฮฟฮบฯฮฎฯฮทฯ
owner_helper=ฮฯฮนฯฮผฮญฮฝฮฟฮน ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฮฏ ฮตฮฝฮดฮญฯฮตฯฮฑฮน ฮฝฮฑ ฮผฮทฮฝ ฮตฮผฯฮฑฮฝฮฏฮถฮฟฮฝฯฮฑฮน ฯฯฮฟ ฮฑฮฝฮฑฯฯฯ
ฯฯฯฮผฮตฮฝฮฟ ฮผฮตฮฝฮฟฯ ฮปฯฮณฯ ฯฮฟฯ
ฮผฮญฮณฮนฯฯฮฟฯ
ฮฑฯฮนฮธฮผฮฟฯ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ.
repo_name=ฮฮฝฮฟฮผฮฑ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
repo_name_helper=ฮคฮฑ ฮบฮฑฮปฮฌ ฮฟฮฝฯฮผฮฑฯฮฑ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฟฯฮฝ ฯฯฮฝฯฮฟฮผฮตฯ, ฮฑฮพฮญฯฮฑฯฯฮตฯ ฮบฮฑฮน ฮผฮฟฮฝฮฑฮดฮนฮบฮญฯ ฮปฮญฮพฮตฮนฯ-ฮบฮปฮตฮนฮดฮนฮฌ.
repo_size=ฮฮญฮณฮตฮธฮฟฯ ฮฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
template=ฮ ฯฯฯฯ
ฯฮฟ
-template_select=ฮฯฮนฮปฮญฮพฯฮต ฯฯฯฯฯ
ฯฮฟ.
-template_helper=ฮฮตฯฮฑฯฯฮฟฯฮฎ ฯฮต ฯฯฯฯฯ
ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+template_select=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฯฯฯฯฯ
ฯฮฟ
+template_helper=ฮฮตฯฮฑฯฯฮฟฯฮฎ ฯฮต ฯฯฯฯฯ
ฯฮฟ repository
template_description=ฮคฮฑ ฯฯฯฯฯ
ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฮตฯฮนฯฯฮญฯฮฟฯ
ฮฝ ฯฯฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮฟฯ
ฮฝ ฮฝฮญฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฮผฮต ฯฮทฮฝ ฮฏฮดฮนฮฑ ฮดฮฟฮผฮฎ, ฮฑฯฯฮตฮฏฮฑ ฮบฮฑฮน ฯฯฮฟฮฑฮนฯฮตฯฮนฮบฮญฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ.
visibility=ฮฯฮฑฯฯฯฮทฯฮฑ
visibility_description=ฮฯฮฝฮฟ ฮฟ ฮนฮดฮนฮฟฮบฯฮฎฯฮทฯ ฮฎ ฯฮฑ ฮผฮญฮปฮท ฯฮฟฯ
ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ ฮตฮฌฮฝ ฮญฯฮฟฯ
ฮฝ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ, ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฯฮต ฮธฮญฯฮท ฮฝฮฑ ฯฮฟ ฮดฮฟฯ
ฮฝ.
@@ -1016,7 +1092,7 @@ fork_to_different_account=Fork ฯฮต ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ
fork_visibility_helper=ฮ ฮฟฯฮฑฯฯฯฮทฯฮฑ ฮตฮฝฯฯ fork ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮตฮน.
fork_branch=ฮฮปฮฌฮดฮฟฯ ฯฮฟฯ
ฮธฮฑ ฮบฮปฯฮฝฮฟฯฮฟฮนฮทฮธฮตฮฏ ฯฯฮฟ fork
all_branches=ฮฮปฮฟฮน ฮฟฮน ฮบฮปฮฌฮดฮฟฮน
-fork_no_valid_owners=ฮฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮณฮฏฮฝฮตฮน fork ฮตฯฮตฮนฮดฮฎ ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮญฮณฮบฯ
ฯฮฟฮน ฮนฮดฮนฮฟฮบฯฮฎฯฮตฯ.
+fork_no_valid_owners=ฮฯ
ฯฯ ฯฮฟ repository ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮณฮฏฮฝฮตฮน fork, ฮตฯฮตฮนฮดฮฎ ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮญฮณฮบฯ
ฯฮฟฮน ฮนฮดฮนฮฟฮบฯฮฎฯฮตฯ.
use_template=ฮงฯฮฎฯฮท ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฯฯฯฯฯ
ฯฮฟฯ
clone_in_vsc=ฮฮปฯฮฝฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฟ VS Code
download_zip=ฮฮฎฯฮท ZIP
@@ -1027,15 +1103,15 @@ generate_from=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฑฯฯ
repo_desc=ฮ ฮตฯฮนฮณฯฮฑฯฮฎ
repo_desc_helper=ฮฮนฯฮฌฮณฮตฯฮต ฮผฮนฮฑ ฯฯฮฝฯฮฟฮผฮท ฯฮตฯฮนฮณฯฮฑฯฮฎ (ฯฯฮฟฮฑฮนฯฮตฯฮนฮบฯ)
repo_lang=ฮฮปฯฯฯฮฑ
-repo_gitignore_helper=ฮฯฮนฮปฮญฮพฯฮต ฯฯฯฯฯ
ฯฮฑ .gitignore.
+repo_gitignore_helper=ฮฯฮนฮปฮญฮพฯฮต ฯฯฯฯฯ
ฯฮฑ .gitignore
repo_gitignore_helper_desc=ฮฯฮนฮปฮญฮพฯฮต ฯฮฟฮนฮฑ ฮฑฯฯฮตฮฏฮฑ ฮดฮตฮฝ ฮธฮฑ ฯฮฑฯฮฑฮบฮฟฮปฮฟฯ
ฮธฮตฮฏฯฮต ฮฑฯฯ ฮผฮนฮฑ ฮปฮฏฯฯฮฑ ฯฯฮฟฯฯฯฯฮฝ ฮณฮนฮฑ ฮบฮฟฮนฮฝฮญฯ ฮณฮปฯฯฯฮตฯ ฯฯฮฟฮณฯฮฑฮผฮผฮฑฯฮนฯฮผฮฟฯ. ฮคฯ
ฯฮนฮบฮฌ ฮฑฮฝฯฮนฮบฮตฮฏฮผฮตฮฝฮฑ ฯฮฟฯ
ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฟฯฮฝฯฮฑฮน ฮฑฯฯ ฯฮฑ ฮตฯฮณฮฑฮปฮตฮฏฮฑ ฮบฮฑฯฮฑฯฮบฮตฯ
ฮฎฯ ฮบฮฌฮธฮต ฮณฮปฯฯฯฮฑฯ ฯฮตฯฮนฮปฮฑฮผฮฒฮฌฮฝฮฟฮฝฯฮฑฮน ฮฎฮดฮท ฯฯฮฟ .gitignore.
-issue_labels=ฮฃฮฎฮผฮฑฯฮฑ ฮถฮทฯฮทฮผฮฌฯฯฮฝ
-issue_labels_helper=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฯฯฮฝฮฟฮปฮฟ ฯฮทฮผฮฌฯฯฮฝ ฮถฮทฯฮทฮผฮฌฯฯฮฝ.
+issue_labels=ฮคฮฑฮผฯฮญฮปฮตฯ ฮถฮทฯฮทฮผฮฌฯฯฮฝ
+issue_labels_helper=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฯฯฮฝฮฟฮปฮฟ ฯฮทฮผฮฌฯฯฮฝ
license=ฮฮดฮตฮนฮฑ
-license_helper=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฟ ฮฌฮดฮตฮนฮฑฯ.
+license_helper=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฟ ฮฌฮดฮตฮนฮฑฯ
license_helper_desc=ฮฮนฮฑ ฮฌฮดฮตฮนฮฑ ฮดฮนฮญฯฮตฮน ฯฮน ฮฌฮปฮปฮฟฮน ฮผฯฮฟฯฮฟฯฮฝ ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮบฮฌฮฝฮฟฯ
ฮฝ ฮผฮต ฯฮฟฮฝ ฮบฯฮดฮนฮบฮฌ ฯฮฑฯ. ฮฮตฮฝ ฮตฮฏฯฯฮต ฯฮฏฮณฮฟฯ
ฯฮฟฮน ฯฮฟฮนฮฑ ฮตฮฏฮฝฮฑฮน ฮท ฯฯฯฯฮฎ ฮณฮนฮฑ ฯฮฟ ฮญฯฮณฮฟ ฯฮฑฯ; ฮฮตฮฏฯฮต ฯฮฟ ฯฯฯ ฮตฯฮนฮปฮญฮณฯ ฮผฮนฮฑ ฮฌฮดฮตฮนฮฑ.
readme=README
-readme_helper=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฯฯฯฯฯ
ฯฮฟ ฮฑฯฯฮตฮฏฮฟฯ
README.
+readme_helper=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฯฯฯฯฯ
ฯฮฟ ฮฑฯฯฮตฮฏฮฟฯ
README
readme_helper_desc=ฮฯ
ฯฯ ฮตฮฏฮฝฮฑฮน ฯฮฟ ฮผฮญฯฮฟฯ ฯฯฮฟฯ
ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮณฯฮฌฯฮตฯฮต ฮผฮนฮฑ ฯฮปฮฎฯฮท ฯฮตฯฮนฮณฯฮฑฯฮฎ ฮณฮนฮฑ ฯฮฟ ฮญฯฮณฮฟ ฯฮฑฯ.
auto_init=ฮฯฯฮนฮบฮฟฯฮฟฮฏฮทฯฮท ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
(ฮ ฯฮฟฯฮธฮฎฮบฮท .gitignore, ฮฌฮดฮตฮนฮฑฯ ฯฯฮฎฯฮทฯ ฮบฮฑฮน README)
trust_model_helper=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฮผฮฟฮฝฯฮญฮปฮฟ ฮตฮผฯฮนฯฯฮฟฯฯฮฝฮทฯ ฮณฮนฮฑ ฯฮทฮฝ ฮตฯฮฑฮปฮฎฮธฮตฯ
ฯฮท ฯ
ฯฮฟฮณฯฮฑฯฮฎฯ. ฮ ฮนฮธฮฑฮฝฮญฯ ฮตฯฮนฮปฮฟฮณฮญฯ ฮตฮฏฮฝฮฑฮน:
@@ -1046,7 +1122,7 @@ trust_model_helper_default=ฮ ฯฮฟฮตฯฮนฮปฮฟฮณฮฎ: ฮงฯฮฎฯฮท ฯฯฮฟฮตฯฮนฮปฮตฮณฮผ
create_repo=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
default_branch=ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ ฮบฮปฮฌฮดฮฟฯ
default_branch_label=ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ
-default_branch_helper=ฮ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ ฮบฮปฮฌฮดฮฟฯ ฮตฮฏฮฝฮฑฮน ฮฟ ฮฒฮฑฯฮนฮบฯฯ ฮบฮปฮฌฮดฮฟฯ ฮณฮนฮฑ pull requests ฮบฮฑฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮบฯฮดฮนฮบฮฑ.
+default_branch_helper=ฮ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ ฮบฮปฮฌฮดฮฟฯ ฮตฮฏฮฝฮฑฮน ฮฟ ฮฒฮฑฯฮนฮบฯฯ ฮบฮปฮฌฮดฮฟฯ ฮณฮนฮฑ pull requests ฮบฮฑฮน commits.
mirror_prune=ฮฮฑฮธฮฑฯฮนฯฮผฯฯ
mirror_prune_desc=ฮฯฮฑฮฏฯฮตฯฮท ฯฮฑฯฯฯฮทฮผฮญฮฝฯฮฝ ฮฑฮฝฮฑฯฮฟฯฯฮฝ ฮฑฯฮฟฮผฮฑฮบฯฯ
ฯฮผฮญฮฝฮทฯ-ฯฮฑฯฮฑฮบฮฟฮปฮฟฯฮธฮทฯฮทฯ
mirror_interval=ฮฮนฮฌฯฯฮทฮผฮฑ ฮฑฮฝฮฑฮฝฮญฯฯฮทฯ ฮตฮนฮดฯฮปฮฟฯ
(ฮญฮณฮบฯ
ฯฮตฯ ฮผฮฟฮฝฮฌฮดฮตฯ ฯฯฮฑฯ ฮตฮฏฮฝฮฑฮน "h", "m", "s"). 0 ฮณฮนฮฑ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฮฟฯ
ฮฑฯ
ฯฯฮผฮฑฯฮฟฯ
ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฮฟฯ. (ฮฮปฮฌฯฮนฯฯฮฟ ฮดฮนฮฌฯฯฮทฮผฮฑ: %s)
@@ -1066,7 +1142,7 @@ mirror_password_blank_placeholder=(ฮฮท ฮฟฯฮนฯฮผฮญฮฝฮฟ)
mirror_password_help=ฮฮปฮปฮฌฮพฯฮต ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฮณฮนฮฑ ฮฝฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮต ฮญฮฝฮฑฮฝ ฮฑฯฮฟฮธฮทฮบฮตฯ
ฮผฮญฮฝฮฟ ฮบฯฮดฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ.
watchers=ฮ ฮฑฯฮฑฯฮทฯฮทฯฮญฯ
stargazers=ฮฮฑฯ
ฮผฮฑฯฯฮญฯ
-stars_remove_warning=ฮฯ
ฯฯ ฮธฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฮน ฯฮปฮฑ ฯฮฑ ฮฑฯฯฮญฯฮนฮฑ ฮฑฯฯ ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+stars_remove_warning=ฮฯ
ฯฯ ฮธฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฮน ฯฮปฮฑ ฯฮฑ ฮฑฯฯฮญฯฮนฮฑ ฮฑฯฯ ฮฑฯ
ฯฯ ฯฮฟ repository.
forks=Forks
reactions_more=ฮบฮฑฮน %d ฯฮตฯฮนฯฯฯฯฮตฯฮฑ
unit_disabled=ฮ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ ฯฮฟฯ
ฮนฯฯฯฯฮฟฯฮฟฯ
ฮญฯฮตฮน ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฮน ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฮตฮฝฯฯฮทฯฮฑ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
@@ -1075,7 +1151,7 @@ adopt_search=ฮฮนฯฮฌฮณฮตฯฮต ฯฮฝฮฟฮผฮฑ ฯฯฮฎฯฯฮท ฮณฮนฮฑ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮท
adopt_preexisting_label=ฮฅฮนฮฟฮธฮญฯฮทฯฮท ฮฑฯฯฮตฮฏฯฮฝ
adopt_preexisting=ฮฅฮนฮฟฮธฮตฯฮฎฯฯฮต ฯฮฑ ฯฯฮฟฯฯฮฌฯฯฮฟฮฝฯฮฑ ฮฑฯฯฮตฮฏฮฑ
adopt_preexisting_content=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฑฯฯ %s
-adopt_preexisting_success=ฮฅฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮฑฮฝ ฮฑฯฯฮตฮฏฮฑ ฮบฮฑฮน ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮฑฯฯ %s
+adopt_preexisting_success=ฮฅฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮฑฮฝ ฮฑฯฯฮตฮฏฮฑ ฮบฮฑฮน ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฯฮฟ repository ฮฑฯฯ %s
delete_preexisting_label=ฮฮนฮฑฮณฯฮฑฯฮฎ
delete_preexisting=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฑฯฯฮตฮฏฯฮฝ ฯฮฟฯ
ฯฯฮฟฯฯฮฎฯฯฮฑฮฝ
delete_preexisting_content=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฑฯฯฮตฮฏฯฮฝ ฯฯฮฟ %s
@@ -1085,7 +1161,7 @@ blame.ignore_revs=ฮฮณฮฝฯฮทฯฮท ฯฯฮฝ ฮฑฮฝฮฑฮธฮตฯฯฮฎฯฮตฯฮฝ ฯฯฮฟ .git-blame-ignore-revs .
author_search_tooltip=ฮฮผฯฮฌฮฝฮนฯฮท ฯฮฟ ฯฮฟฮปฯ 30 ฯฯฮทฯฯฯฮฝ
-tree_path_not_found_commit=ฮ ฮดฮนฮฑฮดฯฮฟฮผฮฎ %[1]s ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ %[2]s
+tree_path_not_found_commit=ฮ ฮดฮนฮฑฮดฯฮฟฮผฮฎ %[1]s ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฯฮฟ commit %[2]s
tree_path_not_found_branch=ฮ ฮดฮนฮฑฮดฯฮฟฮผฮฎ %[1]s ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[2]s
tree_path_not_found_tag=ฮ ฮดฮนฮฑฮดฯฮฟฮผฮฎ %[1]s ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ %[2]s
@@ -1105,17 +1181,17 @@ desc.archived=ฮฯฯฮตฮนฮฟฮธฮตฯฮทฮผฮญฮฝฮฟ
template.items=ฮฮฝฯฮนฮบฮตฮฏฮผฮตฮฝฮฑ ฯฯฮฟฯฯฯฮฟฯ
template.git_content=ฮ ฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ Git (ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ ฮบฮปฮฌฮดฮฟฯ)
template.git_hooks=Git hooks
-template.git_hooks_tooltip=ฮฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮญฯฮตฯฮต ฮฝฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฯฮต ฮฎ ฮฝฮฑ ฯฯฮฟฯฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮฑ Git hook ฮฑฯฮฟฯ ฯฮฑ ฮญฯฮตฯฮต ฯฯฮฟฯฮธฮญฯฮตฮน. ฮฯฮนฮปฮญฮพฯฮต ฯฮทฮฝ ฯฯฮธฮผฮนฯฮท ฮฑฯ
ฯฮฎ ฮผฯฮฝฮฟ ฮฑฮฝ ฮตฮผฯฮนฯฯฮตฯฮตฯฯฮต ฯฮฟ ฯฯฯฯฯ
ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+template.git_hooks_tooltip=ฮฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮญฯฮตฯฮต ฮฝฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฯฮต ฮฎ ฮฝฮฑ ฯฯฮฟฯฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮฑ Git hook ฮฑฯฮฟฯ ฯฮฑ ฮญฯฮตฯฮต ฯฯฮฟฯฮธฮญฯฮตฮน. ฮฯฮนฮปฮญฮพฯฮต ฯฮทฮฝ ฯฯฮธฮผฮนฯฮท ฮฑฯ
ฯฮฎ ฮผฯฮฝฮฟ ฮฑฮฝ ฮตฮผฯฮนฯฯฮตฯฮตฯฯฮต ฯฮฟ ฯฯฯฯฯ
ฯฮฟ repository.
template.webhooks=Webhooks
template.topics=ฮฮญฮผฮฑฯฮฑ
template.avatar=ฮฮนฮบฯฮฝฮฑ
-template.issue_labels=ฮฃฮฎฮผฮฑฯฮฑ ฮถฮทฯฮทฮผฮฌฯฯฮฝ
+template.issue_labels=ฮคฮฑฮผฯฮญฮปฮตฯ ฮถฮทฯฮทฮผฮฌฯฯฮฝ
template.one_item=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮตฯฮนฮปฮญฮพฮตฯฮต ฯฮฟฯ
ฮปฮฌฯฮนฯฯฮฟฮฝ ฮญฮฝฮฑ ฮฑฮฝฯฮนฮบฮตฮฏฮผฮตฮฝฮฟ ฯฯฮฟ ฯฯฯฯฯ
ฯฮฟ
-template.invalid=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮตฯฮนฮปฮญฮพฮตฯฮต ฮญฮฝฮฑ ฯฯฯฯฯ
ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+template.invalid=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮตฯฮนฮปฮญฮพฮตฯฮต ฮญฮฝฮฑ ฯฯฯฯฯ
ฯฮฟ repository
archive.title=ฮฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮตฮนฮฟ ฮฑฯฯฮตฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮต. ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฮฒฮฌฮปฮตฯฮต ฮฑฯฯฮตฮฏฮฑ ฮบฮฑฮน ฮฝฮฑ ฯฮฑ ฮบฮปฯฮฝฮฟฯฮฟฮนฮฎฯฮตฯฮต, ฮฑฮปฮปฮฌ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฮธฮฎฯฮตฯฮต ฮฎ ฮฝฮฑ ฮฑฮฝฮฟฮฏฮพฮตฯฮต ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮฎ pull requests.
-archive.title_date=ฮฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮญฯฮตฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮธฮตฮฏ ฯฯฮฟ %s. ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฮฒฮฌฮปฮตฯฮต ฮฑฯฯฮตฮฏฮฑ ฮบฮฑฮน ฮฝฮฑ ฮบฮปฯฮฝฮฟฯฮฟฮนฮฎฯฮตฯฮต, ฮฑฮปฮปฮฌ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฮธฮฎฯฮตฯฮต ฮฎ ฮฝฮฑ ฮฑฮฝฮฟฮฏฮพฮตฯฮต ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮฎ pull requests.
-archive.issue.nocomment=ฮฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮฑฯฯฮตฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮต. ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฮปฮนฮฌฯฮตฯฮต ฯฮต ฮถฮทฯฮฎฮผฮฑฯฮฑ.
+archive.title_date=ฮฯ
ฯฯ ฯฮฟ repository ฮฑฯฯฮตฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮต ฯฯฮนฯ %s. ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮตฮฏฯฮต ฯฮฑ ฮฑฯฯฮตฮฏฮฑ ฯฮฟฯ
ฮบฮฑฮน ฮฝฮฑ ฯฮฟ ฮบฮปฯฮฝฮฟฯฮฟฮนฮฎฯฮตฯฮต, ฮฑฮปฮปฮฌ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต push, ฮฝฮฑ ฮฑฮฝฮฟฮฏฮพฮตฯฮต ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮฎ pull requests.
+archive.issue.nocomment=ฮฯ
ฯฯ ฯฮฟ repository ฮญฯฮตฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮธฮตฮฏ. ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฮปฮนฮฌฯฮตฯฮต ฯฮต ฮถฮทฯฮฎฮผฮฑฯฮฑ.
archive.pull.nocomment=ฮฯ
ฯฯ ฯฮฟ repo ฮฑฯฯฮตฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮต. ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฮปฮนฮฌฯฮตฯฮต ฯฯฮฑ pull requests.
form.reach_limit_of_creation_1=ฮฯฮตฯฮต ฮฎฮดฮท ฯฯ
ฮผฯฮปฮทฯฯฯฮตฮน ฯฮฟ ฯฯฮนฮฟ ฯฮฟฯ
%d ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
@@ -1126,7 +1202,7 @@ form.name_pattern_not_allowed=ฮคฮฟ ฮผฮฟฯฮฏฮฒฮฟ ยซ%sยป ฮดฮตฮฝ ฮตฯฮนฯฯฮญฯฮตฯ
need_auth=ฮฮพฮฟฯ
ฯฮนฮฟฮดฯฯฮทฯฮท
migrate_options=ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮผฮตฯฮฑฯฮฟฯฮฌฯ
migrate_service=ฮฅฯฮทฯฮตฯฮฏฮฑ ฮฮตฯฮฑฯฮฟฯฮฌฯ
-migrate_options_mirror_helper=ฮฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฮตฮฏฮดฯฮปฮฟ
+migrate_options_mirror_helper=ฮฯ
ฯฯ ฯฮฟ repository ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฮตฮฏฮดฯฮปฮฟ
migrate_options_lfs=ฮฮตฯฮฑฯฮฟฯฮฌ ฮฑฯฯฮตฮฏฯฮฝ LFS
migrate_options_lfs_endpoint.label=ฮฮบฯฮฟ LFS
migrate_options_lfs_endpoint.description=ฮ ฮผฮตฯฮฑฯฮฟฯฮฌ ฮธฮฑ ฯฯฮฟฯฯฮฑฮธฮฎฯฮตฮน ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฮน ฯฮฟ Git remote ฮณฮนฮฑ ฮฝฮฑ ฮบฮฑฮธฮฟฯฮฏฯฮตฮน ฯฮฟฮฝ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ LFS . ฮฯฮฟฯฮตฮฏฯฮต ฮตฯฮฏฯฮทฯ ฮฝฮฑ ฮบฮฑฮธฮฟฯฮฏฯฮตฯฮต ฮญฮฝฮฑ ฮดฮนฮบฯ ฯฮฑฯ endpoint ฮฑฮฝ ฯฮฑ ฮดฮตฮดฮฟฮผฮญฮฝฮฑ LFS ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฑฯฮฟฮธฮทฮบฮตฯฮฟฮฝฯฮฑฮน ฮบฮฌฯฮฟฯ
ฮฑฮปฮปฮฟฯ.
@@ -1135,7 +1211,7 @@ migrate_options_lfs_endpoint.placeholder=ฮฮฝ ฮฑฯฮตฮธฮตฮฏ ฮบฮตฮฝฯ, ฯฮฟ ฮฌฮบฯ
migrate_items=ฮฮฝฯฮนฮบฮตฮฏฮผฮตฮฝฮฑ ฮผฮตฯฮฑฯฮฟฯฮฌฯ
migrate_items_wiki=Wiki
migrate_items_milestones=ฮฯฯฯฮทฮผฮฑ
-migrate_items_labels=ฮฃฮฎฮผฮฑฯฮฑ
+migrate_items_labels=ฮคฮฑฮผฯฮญฮปฮตฯ
migrate_items_issues=ฮฮทฯฮฎฮผฮฑฯฮฑ
migrate_items_pullrequests=Pull requests
migrate_items_merge_requests=Merge requests
@@ -1153,15 +1229,15 @@ migrate.failed=ฮ ฮผฮตฯฮฑฯฮฟฯฮฌ ฮฑฯฮญฯฯ
ฯฮต: %v
migrate.migrate_items_options=ฮคฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ (token) ฮตฮฏฮฝฮฑฮน ฮฑฯฮฑฯฮฑฮฏฯฮทฯฮฟ ฮณฮนฮฑ ฯฮท ฮผฮตฯฮฑฯฮฟฯฮฌ ฯฯฯฯฮธฮตฯฯฮฝ ฯฯฮฟฮนฯฮตฮฏฯฮฝ
migrated_from=ฮฮตฯฮฑฯฮญฯฮธฮทฮบฮต ฮฑฯฯ %[2]s
migrated_from_fake=ฮฮตฯฮฑฯฮญฯฮธฮทฮบฮต ฮฑฯฯ %[1]s
-migrate.migrate=ฮฮตฯฮฑฯฮฟฯฮฌ ฮฑฯฯ ฯฮฟ %s
+migrate.migrate=ฮฮตฯฮฑฯฮฟฯฮฌ ฮฑฯฯ %s
migrate.migrating=ฮฮฏฮฝฮตฯฮฑฮน ฮผฮตฯฮฑฯฮฟฯฮฌ ฮฑฯฯ ฯฮฟ %s ...
migrate.migrating_failed=ฮ ฮผฮตฯฮฑฯฮฟฯฮฌ ฮฑฯฯ ฯฮฟ %s ฮฑฯฮญฯฯ
ฯฮต.
migrate.migrating_failed.error=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮผฮตฯฮฑฯฮฟฯฮฌฯ: %s
migrate.migrating_failed_no_addr=ฮ ฮผฮตฯฮฑฯฮฟฯฮฌ ฮฑฯฮญฯฯ
ฯฮต.
-migrate.github.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฯฮฟ github.com ฮฎ ฮฌฮปฮปฮฟฯ
ฯ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮญฯ GitHub.
+migrate.github.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฯฮฟ github.com ฮฎ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮญฯ GitHub Enterprise.
migrate.git.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮผฯฮฝฮฟ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฑฯฯ ฮผฮนฮฑ ฮฟฯฮฟฮนฮฑฮดฮฎฯฮฟฯฮต ฯ
ฯฮทฯฮตฯฮฏฮฑ Git.
migrate.gitlab.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฯฮฟ gitlab.com ฮฎ ฮฌฮปฮปฮตฯ ฮตฮณฮบฮฑฯฮฑฯฯฮฌฯฮตฮนฯ GitLab.
-migrate.gitea.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฯฮฟ gitea.com ฮฎ ฮฌฮปฮปฮตฯ ฮตฮณฮบฮฑฯฮฑฯฯฮฌฯฮตฮนฯ Gitea/Forgejo.
+migrate.gitea.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฯฮฟ gitea.com ฮฎ ฮฌฮปฮปฮตฯ ฮตฮณฮบฮฑฯฮฑฯฯฮฌฯฮตฮนฯ Gitea.
migrate.gogs.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฯฮฟ notabug.org ฮฎ ฮฌฮปฮปฮตฯ ฮตฮณฮบฮฑฯฮฑฯฯฮฌฯฮตฮนฯ Gogs.
migrate.onedev.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฯฮฟ code.onedev.io ฮฎ ฮฌฮปฮปฮตฯ ฮตฮณฮบฮฑฯฮฑฯฯฮฌฯฮตฮนฯ OneDev.
migrate.codebase.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฯฮฟ codebasehq.com.
@@ -1169,7 +1245,7 @@ migrate.gitbucket.description=ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฮดฮนฮฑ
migrate.migrating_git=ฮคฮฑ ฮดฮตฮดฮฟฮผฮญฮฝฮฑ Git ฮผฮตฯฮฑฯฮญฯฮฟฮฝฯฮฑฮน
migrate.migrating_topics=ฮคฮฑ ฮธฮญฮผฮฑฯฮฑ ฮผฮตฯฮฑฯฮญฯฮฟฮฝฯฮฑฮน
migrate.migrating_milestones=ฮคฮฑ ฮฟฯฯฯฮทฮผฮฑ ฮผฮตฯฮฑฯฮญฯฮฟฮฝฯฮฑฮน
-migrate.migrating_labels=ฮคฮฑ ฯฮฎฮผฮฑฯฮฑ ฮผฮตฯฮฑฯฮญฯฮฟฮฝฯฮฑฮน
+migrate.migrating_labels=ฮฮน ฯฮฑฮผฯฮญฮปฮตฯ ฮผฮตฯฮฑฯฮญฯฮฟฮฝฯฮฑฮน
migrate.migrating_releases=ฮฮน ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮตฯ ฮผฮตฯฮฑฯฮญฯฮฟฮฝฯฮฑฮน
migrate.migrating_issues=ฮคฮฑ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮผฮตฯฮฑฯฮญฯฮฟฮฝฯฮฑฮน
migrate.migrating_pulls=ฮฮตฯฮฑฯฮญฯฮฟฮฝฯฮฑฮน ฯฮฑ pull requests
@@ -1179,10 +1255,10 @@ migrate.cancel_migrating_confirm=ฮฮญฮปฮตฯฮต ฮฝฮฑ ฮฑฮบฯ
ฯฯฯฮตฯฮต ฮฑฯ
ฯฮฎ
mirror_from=ฮตฮฏฮดฯฮปฮฟ ฯฮฟฯ
forked_from=forked ฮฑฯฯ
generated_from=ฯฮฑฯฮฑฮณฮผฮญฮฝฮฟ ฮฑฯฯ
-fork_from_self=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต fork ฯฮต ฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฯฮฟฯ
ฮบฮฑฯฮญฯฮตฯฮต.
-fork_guest_user=ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต fork ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-watch_guest_user=ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฯฮฑฯฮฑฮบฮฟฮปฮฟฯ
ฮธฮฎฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-star_guest_user=ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฮดฯฯฮตฯฮต ฮญฮฝฮฑ ฮฑฯฯฮญฯฮน ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+fork_from_self=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต fork ฮญฮฝฮฑ repository ฯฮฟฯ
ฯฮฑฯ ฮฑฮฝฮฎฮบฮตฮน.
+fork_guest_user=ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต fork ฮฑฯ
ฯฯ ฯฮฟ repository.
+watch_guest_user=ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฯฮฑฯฮฑฮบฮฟฮปฮฟฯ
ฮธฮฎฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
+star_guest_user=ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฮดฯฯฮตฯฮต ฮญฮฝฮฑ ฮฑฯฯฮญฯฮน ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
unwatch=ฮ ฮฑฯฯฮท ฮฑฮบฮฟฮปฮฟฯฮธฮทฯฮทฯ
watch=ฮ ฮฑฯฮฑฮบฮฟฮปฮฟฯฮธฮทฯฮท
unstar=ฮฯฮฑฮฏฯฮตฯฮท ฮฑฯฯฮตฯฮนฮฟฯ
@@ -1194,14 +1270,14 @@ more_operations=ฮ ฮตฯฮนฯฯฯฯฮตฯฮตฯ ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮตฯ
no_desc=ฮงฯฯฮฏฯ ฯฮตฯฮนฮณฯฮฑฯฮฎ
quick_guide=ฮฯฮฎฮณฮฟฯฮฟฯ ฮฟฮดฮทฮณฯฯ
clone_this_repo=ฮฮปฯฮฝฮฟฯฮฟฮฏฮทฯฮท ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
-cite_this_repo=ฮฮฝฮฑฯฮฟฯฮฌ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+cite_this_repo=ฮฮฝฮฑฯฮฟฯฮฌ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository
create_new_repo_command=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฝฮญฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฯฮท ฮณฯฮฑฮผฮผฮฎ ฮตฮฝฯฮฟฮปฯฮฝ
push_exist_repo=ฮ ฯฮฟฯฮธฮทฯฮท ฮตฮฝฯฯ ฯ
ฯฮฌฯฯฮฟฮฝฯฮฟฯ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฑฯฯ ฯฮท ฮณฯฮฑฮผฮผฮฎ ฮตฮฝฯฮฟฮปฯฮฝ
-empty_message=ฮฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮดฮตฮฝ ฮญฯฮตฮน ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ.
-broken_message=ฮคฮฑ ฮดฮตฮดฮฟฮผฮญฮฝฮฑ Git ฯฮฟฯ
ฮดฮนฮญฯฮฟฯ
ฮฝ ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮนฮฑฮฒฮฑฯฯฮฟฯฮฝ. ฮฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮฎ ฮดฮนฮฑฮณฯฮฌฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+empty_message=ฮฯ
ฯฯ ฯฮฟ repository ฮดฮตฮฝ ฮญฯฮตฮน ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ.
+broken_message=ฮคฮฑ ฮดฮตฮดฮฟฮผฮญฮฝฮฑ Git ฯฮฟฯ
ฮดฮนฮญฯฮฟฯ
ฮฝ ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮนฮฑฮฒฮฑฯฯฮฟฯฮฝ. ฮฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฮฎ ฮดฮนฮฑฮณฯฮฌฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
code=ฮฯฮดฮนฮบฮฑฯ
-code.desc=ฮ ฯฯฯฮฒฮฑฯฮท ฯฯฮฟฮฝ ฯฮทฮณฮฑฮฏฮฟ ฮบฯฮดฮนฮบฮฑ, ฮฑฯฯฮตฮฏฮฑ, ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮบฮฑฮน ฮบฮปฮฌฮดฮฟฯ
ฯ.
+code.desc=ฮ ฯฯฯฮฒฮฑฯฮท ฯฯฮฟฮฝ ฯฮทฮณฮฑฮฏฮฟ ฮบฯฮดฮนฮบฮฑ, ฮฑฯฯฮตฮฏฮฑ, commits ฮบฮฑฮน ฮบฮปฮฌฮดฮฟฯ
ฯ.
branch=ฮฮปฮฌฮดฮฟฯ
tree=ฮฮญฮฝฯฯฮฟ
clear_ref=`ฮฮฑฮธฮฑฯฮนฯฮผฯฯ ฯฯฮญฯฮฟฯ
ฯฮฑฯ ฮฑฮฝฮฑฯฮฟฯฮฌฯ`
@@ -1214,17 +1290,17 @@ pulls=Pull requests
project_board=ฮฯฮณฮฑ
packages=ฮ ฮฑฮบฮญฯฮฑ
actions=Actions
-labels=ฮฃฮฎฮผฮฑฯฮฑ
-org_labels_desc=ฮคฮฑ ฯฮฎฮผฮฑฯฮฑ ฯฯฮฟ ฮตฯฮฏฯฮตฮดฮฟ ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ, ฯฮฟฯ
ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮฟฯฮฝ ฮผฮต ฯฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฮบฮฌฯฯ ฮฑฯฯ ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ
+labels=ฮคฮฑฮผฯฮญฮปฮตฯ
+org_labels_desc=ฮฮน ฯฮฑฮผฯฮญฮปฮตฯ, ฯฮฟฯ
ฮนฯฯฯฮฟฯ
ฮฝ ฮณฮนฮฑ ฮฟฮปฯฮบฮปฮทฯฮฟ ฯฮฟฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ, ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮฟฯฮฝ ฯฮต ฯฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
ฮฑฮฝฮฎฮบฮฟฯ
ฮฝ ฯฯฮฟฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ
org_labels_desc_manage=ฮดฮนฮฑฯฮตฮฏฯฮนฯฮท
milestones=ฮฯฯฯฮทฮผฮฑ
-commits=ฮฅฯฮฟฮฒฮฟฮปฮญฯ
-commit=ฮฅฯฮฟฮฒฮฟฮปฮฎ
+commits=Commits
+commit=Commit
release=ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ
releases=ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮตฯ
tag=ฮฯฮนฮบฮญฯฮฑ
-released_this=ฮบฯ
ฮบฮปฮฟฯฯฯฮทฯฮต ฮฑฯ
ฯฯ
+released_this=ฮบฯ
ฮบฮปฮฟฯฯฯฮทฯฮต
tagged_this=ฯฯฯฯฮธฮตฯฮต ฮตฯฮนฮบฮญฯฮฑ ฮณฮนฮฑ ฯฮฟ
file.title=%s ฯฯฮฟ %s
file_raw=ฮฮบฮฑฯฮญฯฮณฮฑฯฯฮฟ
@@ -1238,8 +1314,8 @@ invisible_runes_header=`ฮฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮตฯฮนฮญฯฮตฮน ฮฑฯฯฮฑฯฮฟ
invisible_runes_description=`ฮฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮตฯฮนฮญฯฮตฮน ฮฑฯฯฮฑฯฮฟฯ
ฯ ฯฮฑฯฮฑฮบฯฮฎฯฮตฯ Unicode ฯฮฟฯ
ฮดฮตฮฝ ฮดฮนฮฑฮบฯฮฏฮฝฮฟฮฝฯฮฑฮน ฮฑฯฯ ฮฑฮฝฮธฯฯฯฮฟฯ
ฯ, ฮฑฮปฮปฮฌ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮตฯฮตฮพฮตฯฮณฮฌฮถฮฟฮฝฯฮฑฮน ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮฌ ฮฑฯฯ ฮญฮฝฮฑฮฝ ฯ
ฯฮฟฮปฮฟฮณฮนฯฯฮฎ. ฮฮฝ ฮฝฮฟฮผฮฏฮถฮตฯฮต ฯฯฮน ฮฑฯ
ฯฯ ฮตฮฏฮฝฮฑฮน ฯฮบฯฯฮนฮผฮฟ, ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮณฮฝฮฟฮฎฯฮตฯฮต ฮผฮต ฮฑฯฯฮฌฮปฮตฮนฮฑ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฯฯฮฟฮตฮนฮดฮฟฯฮฟฮฏฮทฯฮท. ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฯฮฟ ฮบฮฟฯ
ฮผฯฮฏ Escape ฮณฮนฮฑ ฮฝฮฑ ฯฮฟฯ
ฯ ฮฑฯฮฟฮบฮฑฮปฯฯฮตฯฮต.`
ambiguous_runes_header=`ฮฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮตฯฮนฮญฯฮตฮน ฮฑฯฮฑฯฮตฮฏฯ ฯฮฑฯฮฑฮบฯฮฎฯฮตฯ Unicode `
ambiguous_runes_description=`ฮฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮตฯฮนฮญฯฮตฮน ฯฮฑฯฮฑฮบฯฮฎฯฮตฯ Unicode ฯฮฟฯ
ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯ
ฮณฯฮญฮฟฮฝฯฮฑฮน ฮผฮต ฮฌฮปฮปฮฟฯ
ฯ ฯฮฑฯฮฑฮบฯฮฎฯฮตฯ. ฮฮฝ ฮฝฮฟฮผฮฏฮถฮตฯฮต ฯฯฮน ฮฑฯ
ฯฯ ฮตฮฏฮฝฮฑฮน ฯฮบฯฯฮนฮผฮฟ, ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮณฮฝฮฟฮฎฯฮตฯฮต ฮผฮต ฮฑฯฯฮฌฮปฮตฮนฮฑ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฯฯฮฟฮตฮนฮดฮฟฯฮฟฮฏฮทฯฮท. ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฯฮฟ ฮบฮฟฯ
ฮผฯฮฏ Escape ฮณฮนฮฑ ฮฝฮฑ ฯฮฟฯ
ฯ ฮฑฯฮฟฮบฮฑฮปฯฯฮตฯฮต.`
-invisible_runes_line=`ฮฯ
ฯฮฎ ฮท ฮณฯฮฑฮผฮผฮฎ ฮญฯฮตฮน ฮฑฯฯฮฑฯฮฟฯ
ฯ ฯฮฑฯฮฑฮบฯฮฎฯฮตฯ unicode `
-ambiguous_runes_line=`ฮฯ
ฯฮฎ ฮท ฮณฯฮฑฮผฮผฮฎ ฮญฯฮตฮน ฮฑฯฮฑฯฮตฮฏฯ ฯฮฑฯฮฑฮบฯฮฎฯฮตฯ unicode `
+invisible_runes_line=`ฮฯ
ฯฮฎ ฮท ฮณฯฮฑฮผฮผฮฎ ฮญฯฮตฮน ฮฑฯฯฮฑฯฮฟฯ
ฯ ฯฮฑฯฮฑฮบฯฮฎฯฮตฯ Unicode`
+ambiguous_runes_line=`ฮฯ
ฯฮฎ ฮท ฮณฯฮฑฮผฮผฮฎ ฮญฯฮตฮน ฮฑฯฮฑฯฮตฮฏฯ ฯฮฑฯฮฑฮบฯฮฎฯฮตฯ Unicode`
ambiguous_character=`ฮฟ %[1]c [U+%04[1]X] ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮผฯฮตฯฮดฮตฯ
ฯฮตฮฏ ฮผฮต ฯฮฟฮฝ %[2]c [U+%04[2]X]`
escape_control_characters=Escape
@@ -1249,16 +1325,17 @@ view_git_blame=ฮ ฯฮฟฮฒฮฟฮปฮฎ git blame
video_not_supported_in_browser=ฮคฮฟ ฯฯฯฮณฯฮฑฮผฮผฮฑ ฯฮตฯฮนฮฎฮณฮทฯฮฎฯ ฯฮฑฯ ฮดฮตฮฝ ฯ
ฯฮฟฯฯฮทฯฮฏฮถฮตฮน ฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ HTML5 ยซvideoยป.
audio_not_supported_in_browser=ฮคฮฟ ฯฯฯฮณฯฮฑฮผฮผฮฑ ฯฮตฯฮนฮฎฮณฮทฯฮฎฯ ฯฮฑฯ ฮดฮตฮฝ ฯ
ฯฮฟฯฯฮทฯฮฏฮถฮตฮน ฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ HTML5 ยซaudioยป.
stored_lfs=ฮฯฮฟฮธฮทฮบฮตฯฯฮทฮบฮต ฮผฮต ฯฮฟ Git LFS
+stored_annex=ฮฯฮฟฮธฮทฮบฮตฯฯฮทฮบฮต ฮผฮต ฯฮฟ Git Annex
symbolic_link=Symbolic link
executable_file=ฮฮบฯฮตฮปฮญฯฮนฮผฮฟ ฮฑฯฯฮตฮฏฮฟ
-commit_graph=ฮฯฮฌฯฮทฮผฮฑ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ
+commit_graph=ฮฯฮฌฯฮทฮผฮฑ commit
commit_graph.select=ฮฯฮนฮปฮฟฮณฮฎ ฮบฮปฮฌฮดฯฮฝ
commit_graph.hide_pr_refs=ฮฯฯฮบฯฯ
ฯฮท pull request
commit_graph.monochrome=ฮฮฟฮฝฯฯฯฯฮผฮฟ
commit_graph.color=ฮฮณฯฯฯฮผฮฟ
-commit.contained_in=ฮฯ
ฯฮฎ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฯฮตฯฮนฮปฮฑฮผฮฒฮฌฮฝฮตฯฮฑฮน ฯฮต:
-commit.contained_in_default_branch=ฮฯ
ฯฮฎ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮตฮฏฮฝฮฑฮน ฮผฮญฯฮฟฯ ฯฮฟฯ
ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
-commit.load_referencing_branches_and_tags=ฮฆฯฯฯฯฯฮท ฮบฮปฮฌฮดฯฮฝ ฮบฮฑฮน ฮตฯฮนฮบฮตฯฯฮฝ ฯฮฟฯ
ฯฮฑฯฮฑฯฮญฮผฯฮฟฯ
ฮฝ ฯฮต ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ
+commit.contained_in=ฮฯ
ฯฯ ฯฮฟ commit ฯฮตฯฮนฮปฮฑฮผฮฒฮฌฮฝฮตฯฮฑฮน ฯฮต:
+commit.contained_in_default_branch=ฮฯ
ฯฯ ฯฮฟ commit ฮฑฯฮฟฯฮตฮปฮตฮฏ ฮผฮญฯฮฟฯ ฯฮฟฯ
ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
+commit.load_referencing_branches_and_tags=ฮฆฯฯฯฯฯฮท ฮบฮปฮฌฮดฯฮฝ ฮบฮฑฮน ฮตฯฮนฮบฮตฯฯฮฝ ฯฮฟฯ
ฯฮฑฯฮฑฯฮญฮผฯฮฟฯ
ฮฝ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ commit
blame=ฮฯ
ฮธฯฮฝฮท
download_file=ฮฮฎฯฮท ฮฑฯฯฮตฮฏฮฟฯ
normal_view=ฮฮฑฮฝฮฟฮฝฮนฮบฮฎ ฮ ฯฮฟฮฒฮฟฮปฮฎ
@@ -1272,11 +1349,12 @@ editor.upload_file=ฮฮฝฮญฮฒฮฑฯฮผฮฑ ฮฑฯฯฮตฮฏฮฟฯ
editor.edit_file=ฮฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฮฑฯฯฮตฮฏฮฟฯ
editor.preview_changes=ฮ ฯฮฟฮตฯฮนฯฮบฯฯฮทฯฮท ฮฑฮปฮปฮฑฮณฯฮฝ
editor.cannot_edit_lfs_files=ฮคฮฑ ฮฑฯฯฮตฮฏฮฑ LFS ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮฟฯฮฝ ฯฯฮท ฮดฮนฮตฯฮฑฯฮฎ web.
+editor.cannot_edit_annex_files=ฮคฮฑ ฮฑฯฯฮตฮฏฮฑ Annex ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮฟฯฮฝ ฯฯฮท ฮดฮนฮตฯฮฑฯฮฎ web.
editor.cannot_edit_non_text_files=ฮคฮฑ ฮดฯ
ฮฑฮดฮนฮบฮฌ ฮฑฯฯฮตฮฏฮฑ ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮฟฯฮฝ ฯฯฮท ฮดฮนฮตฯฮฑฯฮฎ web.
editor.edit_this_file=ฮฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฮฑฯฯฮตฮฏฮฟฯ
editor.this_file_locked=ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ฮตฮฏฮฝฮฑฮน ฮบฮปฮตฮนฮดฯฮผฮญฮฝฮฟ
editor.must_be_on_a_branch=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮฒฯฮฏฯฮบฮตฯฯฮต ฯฮต ฮญฮฝฮฑฮฝ ฮบฮปฮฌฮดฮฟ ฮณฮนฮฑ ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต ฮฎ ฮฝฮฑ ฯฯฮฟฯฮตฮฏฮฝฮตฯฮต ฮฑฮปฮปฮฑฮณฮญฯ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ.
-editor.fork_before_edit=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต fork ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮณฮนฮฑ ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต ฮฎ ฮฝฮฑ ฯฯฮฟฯฮตฮฏฮฝฮตฯฮต ฮฑฮปฮปฮฑฮณฮญฯ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ.
+editor.fork_before_edit=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต fork ฮฑฯ
ฯฯ ฯฮฟ repository ฮณฮนฮฑ ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต ฮฎ ฮฝฮฑ ฯฯฮฟฯฮตฮฏฮฝฮตฯฮต ฮฑฮปฮปฮฑฮณฮญฯ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ.
editor.delete_this_file=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฑฯฯฮตฮฏฮฟฯ
editor.must_have_write_access=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮญฯฮตฯฮต ฯฯฯฯฮฒฮฑฯฮท ฮตฮณฮณฯฮฑฯฮฎฯ ฮณฮนฮฑ ฮฝฮฑ ฮบฮฌฮฝฮตฯฮต ฮฎ ฮฝฮฑ ฯฯฮฟฯฮตฮฏฮฝฮตฯฮต ฮฑฮปฮปฮฑฮณฮญฯ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ.
editor.file_delete_success=ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ยซ%sยป ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
@@ -1286,42 +1364,42 @@ editor.or=ฮฎ
editor.cancel_lower=ฮฮบฯฯฯฯฮท
editor.commit_signed_changes=ฮฅฯฮฟฮฒฮฟฮปฮฎ ฯ
ฯฮฟฮณฮตฮณฯฮฑฮผฮผฮญฮฝฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ
editor.commit_changes=ฮฅฯฮฟฮฒฮฟฮปฮฎ ฮฑฮปฮปฮฑฮณฯฮฝ
-editor.add_tmpl=ฮ ฯฮฟฯฮธฮฎฮบฮท ยซยป
+editor.add_tmpl=ฮ ฯฮฟฯฮธฮฎฮบฮท ยซ<%s>ยป
editor.add=ฮ ฯฮฟฯฮธฮฎฮบฮท %s
editor.update=ฮฮฝฮทฮผฮญฯฯฯฮท %s
editor.delete=ฮฮนฮฑฮณฯฮฑฯฮฎ %s
-editor.patch=ฮฯฮฑฯฮผฮฟฮณฮฎ ฮฮนฯฯฮธฯฯฮทฯ
+editor.patch=ฮฯฮฑฯฮผฮฟฮณฮฎ patch
editor.patching=ฮฯฮนฮดฮนฯฯฮธฯฯฮท:
editor.fail_to_apply_patch=`ฮฮดฯ
ฮฝฮฑฮผฮฏฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎฯ ฯฮทฯ ฮตฯฮนฮดฮนฯฯฮธฯฯฮทฯ "%s"`
-editor.new_patch=ฮฮญฮฑ ฮฮนฯฯฮธฯฯฮท
+editor.new_patch=ฮฮญฮฟ patch
editor.commit_message_desc=ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฯฮฟฮฑฮนฯฮตฯฮนฮบฮฎฯ ฮตฮบฯฮตฮฝฮฟฯฯ ฯฮตฯฮนฮณฯฮฑฯฮฎฯโฆ
-editor.signoff_desc=ฮ ฯฮฟฯฮธฮญฯฯฮต ฮญฮฝฮฑ ฯฯฯฯฮธฮตฯฮฟ Signed-off-by ฯฯฮฟ ฯฮญฮปฮฟฯ ฯฮฟฯ
ฮผฮทฮฝฯฮผฮฑฯฮฟฯ ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฯฮทฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ.
-editor.commit_directly_to_this_branch=ฮฅฯฮฟฮฒฮฟฮปฮฎ ฮฑฯฮตฯ
ฮธฮตฮฏฮฑฯ ฯฯฮฟ ฮบฮปฮฌฮดฮฟ %s .
-editor.create_new_branch=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮณฮนฮฑ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮบฮฑฮน ฮพฮตฮบฮนฮฝฮฎฯฯฮต ฮญฮฝฮฑ pull request.
-editor.create_new_branch_np=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮณฮนฮฑ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ.
+editor.signoff_desc=ฮ ฯฮฟฯฮธฮญฯฯฮต ฮญฮฝฮฑ ฯฯฯฯฮธฮตฯฮฟ Signed-off-by ฯฯฮฟ ฯฮญฮปฮฟฯ ฯฮฟฯ
ฮผฮทฮฝฯฮผฮฑฯฮฟฯ ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฯฮฟฯ
commit.
+editor.commit_directly_to_this_branch=ฮฅฯฮฟฮฒฮฟฮปฮฎ commit ฮฑฯฮตฯ
ฮธฮตฮฏฮฑฯ ฯฯฮฟ ฮบฮปฮฌฮดฮฟ %[1]s .
+editor.create_new_branch=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ commit ฮบฮฑฮน ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮญฮฝฮฑ pull request.
+editor.create_new_branch_np=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ commit.
editor.propose_file_change=ฮ ฯฯฯฮฑฯฮท ฮฑฮปฮปฮฑฮณฮฎฯ ฮฑฯฯฮตฮฏฮฟฯ
-editor.new_branch_name=ฮฮฝฯฮผฮฑฯฮต ฯฮฟฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮณฮนฮฑ ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ
+editor.new_branch_name=ฮฮฝฯฮผฮฑฯฮต ฯฮฟฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ commit
editor.new_branch_name_desc=ฮฮฝฮฟฮผฮฑ ฮฝฮญฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
โฆ
editor.cancel=ฮฮบฯฯฯฯฮท
editor.filename_cannot_be_empty=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฮฑฯฯฮตฮฏฮฟฯ
ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯ.
editor.filename_is_invalid=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฮฑฯฯฮตฮฏฮฟฯ
ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟ: "%s".
-editor.branch_does_not_exist=ฮ ฮบฮปฮฌฮดฮฟฯ "%s" ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-editor.branch_already_exists=ฮ ฮบฮปฮฌฮดฮฟฯ ยซ%sยป ฯ
ฯฮฌฯฯฮตฮน ฮฎฮดฮท ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-editor.directory_is_a_file=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฮฑฮบฮญฮปฮฟฯ
ยซ%sยป ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮฎฮดฮท ฯฯ ฯฮฝฮฟฮผฮฑ ฮฑฯฯฮตฮฏฮฟฯ
ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+editor.branch_does_not_exist=ฮ ฮบฮปฮฌฮดฮฟฯ "%s" ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
+editor.branch_already_exists=ฮ ฮบฮปฮฌฮดฮฟฯ ยซ%sยป ฯ
ฯฮฌฯฯฮตฮน ฮฎฮดฮท ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
+editor.directory_is_a_file=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฮฑฮบฮญฮปฮฟฯ
ยซ%sยป ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮฎฮดฮท ฯฯ ฯฮฝฮฟฮผฮฑ ฮฑฯฯฮตฮฏฮฟฯ
ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
editor.file_is_a_symlink=`ฮคฮฟ ยซ%sยป ฮตฮฏฮฝฮฑฮน ฯฯ
ฮผฮฒฮฟฮปฮนฮบฯฯ ฯฯฮฝฮดฮตฯฮผฮฟฯ. ฮฮน ฯฯ
ฮผฮฒฮฟฮปฮนฮบฮฟฮฏ ฯฯฮฝฮดฮตฯฮผฮฟฮน ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮฟฯฮฝ ฯฯฮทฮฝ ฮตฮฝฯฯฮผฮฑฯฯฮผฮญฮฝฮท ฮตฯฮฑฯฮผฮฟฮณฮฎ`
-editor.filename_is_a_directory=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฮฑฯฯฮตฮฏฮฟฯ
ยซ%sยป ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮฎฮดฮท ฯฯ ฯฮฝฮฟฮผฮฑ ฯฮฑฮบฮญฮปฮฟฯ
ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-editor.file_editing_no_longer_exists=ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ยซ%sยป, ฯฮฟ ฮฟฯฮฟฮฏฮฟ ฮตฯฮตฮพฮตฯฮณฮฌฮถฮตฯฯฮต, ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฮปฮญฮฟฮฝ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-editor.file_deleting_no_longer_exists=ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ยซ%sยป, ฯฮฟ ฮฟฯฮฟฮฏฮฟ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮฑฮน, ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฮปฮญฮฟฮฝ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-editor.file_changed_while_editing=ฮ ฯฮฟฮญฮบฯ
ฯฮฑฮฝ ฮบฮฌฯฮฟฮนฮตฯ ฮฑฮปฮปฮฑฮณฮญฯ ฯฯฮฑ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฑ ฯฮฟฯ
ฮฑฯฯฮตฮฏฮฟฯ
ฮฑฯฯ ฯฯฯฮต ฯฮฟฯ
ฮพฮตฮบฮนฮฝฮฎฯฮฑฯฮต ฮฝฮฑ ฯฮฑ ฮตฯฮตฮพฮตฯฮณฮฌฮถฮตฯฯฮต. ฮฮฌฮฝฯฮต ฮบฮปฮนฮบ ฮตฮดฯ ฮณฮนฮฑ ฮฝฮฑ ฯฮฑ ฮดฮตฮฏฯฮต ฮฎ ฮพฮฑฮฝฮฑฮบฮฌฮฝฯฮต ฮผฮฏฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฯฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ ฯฮฑฯ ฮณฮนฮฑ ฮฝฮฑ ฯฮนฯ ฮฑฮฝฯฮนฮบฮฑฯฮฑฯฯฮฎฯฮตฯฮต.
-editor.file_already_exists=ฮฅฯฮฌฯฯฮตฮน ฮฎฮดฮท ฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฟ ฮผฮต ฯฮฟ ฯฮฝฮฟฮผฮฑ ยซ%sยป ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-editor.commit_empty_file_header=ฮฅฯฮฟฮฒฮฟฮปฮฎ ฮตฮฝฯฯ ฮบฮตฮฝฮฟฯ ฮฑฯฯฮตฮฏฮฟฯ
+editor.filename_is_a_directory=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฮฑฯฯฮตฮฏฮฟฯ
ยซ%sยป ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮฎฮดฮท ฯฯ ฯฮฝฮฟฮผฮฑ ฯฮฑฮบฮญฮปฮฟฯ
ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
+editor.file_editing_no_longer_exists=ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ยซ%sยป, ฯฮฟ ฮฟฯฮฟฮฏฮฟ ฮตฯฮตฮพฮตฯฮณฮฌฮถฮตฯฯฮต, ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฮปฮญฮฟฮฝ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
+editor.file_deleting_no_longer_exists=ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ยซ%sยป, ฯฮฟ ฮฟฯฮฟฮฏฮฟ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮฑฮน, ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฮปฮญฮฟฮฝ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
+editor.file_changed_while_editing=ฮ ฯฮฟฮญฮบฯ
ฯฮฑฮฝ ฮบฮฌฯฮฟฮนฮตฯ ฮฑฮปฮปฮฑฮณฮญฯ ฯฯฮฑ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฑ ฯฮฟฯ
ฮฑฯฯฮตฮฏฮฟฯ
ฮฑฯฯ ฯฯฯฮต ฯฮฟฯ
ฮพฮตฮบฮนฮฝฮฎฯฮฑฯฮต ฮฝฮฑ ฯฮฑ ฮตฯฮตฮพฮตฯฮณฮฌฮถฮตฯฯฮต. ฮฮฌฮฝฯฮต ฮบฮปฮนฮบ ฮตฮดฯ ฮณฮนฮฑ ฮฝฮฑ ฯฮฑ ฮดฮตฮฏฯฮต ฮฎ ฮพฮฑฮฝฮฑฮบฮฌฮฝฮตฯฮต ฮผฮฏฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฯฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ ฯฮฑฯ ฮณฮนฮฑ ฮฝฮฑ ฯฮนฯ ฮฑฮฝฯฮนฮบฮฑฯฮฑฯฯฮฎฯฮตฯฮต.
+editor.file_already_exists=ฮฅฯฮฌฯฯฮตฮน ฮฎฮดฮท ฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฟ ฮผฮต ฯฮฟ ฯฮฝฮฟฮผฮฑ ยซ%sยป ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
+editor.commit_empty_file_header=Commit ฮบฮตฮฝฮฟฯ ฮฑฯฯฮตฮฏฮฟฯ
editor.commit_empty_file_text=ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮฟฯ
ฯฯฯฮบฮตฮนฯฮฑฮน ฮฝฮฑ ฯ
ฯฮฟฮฒฮปฮทฮธฮตฮฏ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
editor.no_changes_to_show=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฑฮปฮปฮฑฮณฮญฯ ฮณฮนฮฑ ฮตฮผฯฮฌฮฝฮนฯฮท.
editor.fail_to_update_file=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮตฮฝฮทฮผฮญฯฯฯฮทฯ/ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑฯ ฯฮฟฯ
ฮฑฯฯฮตฮฏฮฟฯ
ยซ%sยป.
-editor.fail_to_update_file_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฮฃฯฮฌฮปฮผฮฑฯฮฟฯ:
+editor.fail_to_update_file_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฯฯฮฌฮปฮผฮฑฯฮฟฯ:
editor.push_rejected_no_message=ฮ ฮฑฮปฮปฮฑฮณฮฎ ฮฑฯฮฟฯฯฮฏฯฮธฮทฮบฮต ฮฑฯฯ ฯฮฟฮฝ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฮบฮฑฮน ฮดฮตฮฝ ฮณฮฝฯฯฮฏฮถฮฟฯ
ฮผฮต ฯฮฟฮฝ ฮปฯฮณฮฟ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮตฮปฮญฮณฮพฯฮต ฯฮฑ Git hooks ฯฮฑฯ.
editor.push_rejected=ฮ ฮฑฮปฮปฮฑฮณฮฎ ฮฑฯฮฟฯฯฮฏฯฮธฮทฮบฮต ฮฑฯฯ ฯฮฟฮฝ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮตฮปฮญฮณฮพฯฮต ฯฮฑ Git hook ฯฮฑฯ.
-editor.push_rejected_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฮ ฮปฮฎฯฮฟฯ
ฯ ฮฯฯฯฯฮนฯฮทฯ:
+editor.push_rejected_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฯฮปฮฎฯฮฟฯ
ฯ ฮฑฯฯฯฯฮนฯฮทฯ:
editor.add_subdir=ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฮฑฮบฮญฮปฮฟฯ
โฆ
editor.unable_to_upload_files=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮฑฯฮฟฯฯฮฟฮปฮฎฯ ฮฑฯฯฮตฮฏฯฮฝ ฯฯฮฟ ยซ%sยป ฮผฮต ฯฮฟ ฯฯฮฌฮปฮผฮฑ: %v
editor.upload_file_is_locked=ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ยซ%sยป ฮตฮฏฮฝฮฑฮน ฮบฮปฮตฮนฮดฯฮผฮญฮฝฮฟ ฮฑฯฯ %s.
@@ -1334,8 +1412,8 @@ editor.cherry_pick=ฮฮฝฮธฮฟฮปฯฮณฮทฯฮท (cherry-pick) ฯฮฟฯ
%s ฯฮต:
editor.revert=ฮฯฯฯฯ
ฯฯฮท ฯฮฟฯ
%s ฯฯฮฟ:
commits.desc=ฮฮตฮฏฯฮต ฯฮฟ ฮนฯฯฮฟฯฮนฮบฯ ฮฑฮปฮปฮฑฮณฯฮฝ ฯฮฟฯ
ฯฮทฮณฮฑฮฏฮฟฯ
ฮบฯฮดฮนฮบฮฑ.
-commits.commits=ฮฅฯฮฟฮฒฮฟฮปฮญฯ
-commits.no_commits=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮบฮฟฮนฮฝฮญฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ. ฮคฮฑ ยซ%sยป ฮบฮฑฮน ยซ%sยป ฮญฯฮฟฯ
ฮฝ ฮตฮฝฯฮตฮปฯฯ ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮญฯ ฮนฯฯฮฟฯฮฏฮตฯ.
+commits.commits=Commits
+commits.no_commits=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮบฮฟฮนฮฝฮฌ commit. ฮคฮฑ ยซ%sยป ฮบฮฑฮน ยซ%sยป ฮญฯฮฟฯ
ฮฝ ฮตฮฝฯฮตฮปฯฯ ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮญฯ ฮนฯฯฮฟฯฮฏฮตฯ.
commits.nothing_to_compare=ฮฯ
ฯฮฟฮฏ ฮฟฮน ฮบฮปฮฌฮดฮฟฮน ฮตฮฏฮฝฮฑฮน ฯฮผฮฟฮนฮฟฮน.
commits.search=ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฯ
ฯฮฟฮฒฮฟฮปฯฮฝโฆ
commits.search.tooltip=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฮธฮญฯฮตฯฮต ฯฮนฯ ฮปฮญฮพฮตฮนฯ-ฮบฮปฮตฮนฮดฮนฮฌ ฮผฮต "author:", "committer:", "after:", ฮฎ "before:", ฯ.ฯ. "ฮตฯฮฑฮฝฮฑฯฮฟฯฮฌ author:Alice before:2019-01-13".
@@ -1418,8 +1496,8 @@ issues.filter_labels=ฮฆฮฏฮปฯฯฮฟ ฮฃฮทฮผฮฌฯฯฮฝ
issues.filter_reviewers=ฮฆฮนฮปฯฯฮฌฯฮนฯฮผฮฑ ฮฮพฮตฯฮฑฯฯฮฎ
issues.new=ฮฮญฮฟ ฮถฮฎฯฮทฮผฮฑ
issues.new.title_empty=ฮ ฯฮฏฯฮปฮฟฯ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯฯ
-issues.new.labels=ฮฃฮฎฮผฮฑฯฮฑ
-issues.new.no_label=ฮงฯฯฮฏฯ ฮฃฮฎฮผฮฑ
+issues.new.labels=ฮคฮฑฮผฯฮญฮปฮตฯ
+issues.new.no_label=ฮงฯฯฮฏฯ ฯฮฑฮผฯฮญฮปฮตฯ
issues.new.clear_labels=ฮฮฑฮธฮฑฯฮนฯฮผฯฯ ฯฮทฮผฮฌฯฯฮฝ
issues.new.projects=ฮฯฮณฮฑ
issues.new.clear_projects=ฮฮบฮบฮฑฮธฮฌฯฮนฯฮท ฮญฯฮณฯฮฝ
@@ -1449,16 +1527,16 @@ issues.new_label=ฮฮญฮฟ ฯฮฎฮผฮฑ
issues.new_label_placeholder=ฮฮฝฮฟฮผฮฑ ฯฮฎฮผฮฑฯฮฟฯ
issues.new_label_desc_placeholder=ฮ ฮตฯฮนฮณฯฮฑฯฮฎ
issues.create_label=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯฮฎฮผฮฑฯฮฟฯ
-issues.label_templates.title=ฮงฯฮฎฯฮท ฮตฮฝฯฯ ฯฯฮฟฮบฮฑฮธฮฟฯฮนฯฮผฮญฮฝฮฟฯ
ฯฯ
ฮฝฯฮปฮฟฯ
ฯฮทฮผฮฌฯฯฮฝ
-issues.label_templates.info=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฯฮฎฮผฮฑฯฮฑ ฮฑฮบฯฮผฮฑ. ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮญฮฝฮฑ ฯฮฎฮผฮฑ ฮผฮต ฯฮฟ ฮบฮฟฯ
ฮผฯฮฏ ยซฮฮญฮฟ ฮฃฮฎฮผฮฑยป ฮฎ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฮญฮฝฮฑ ฯฮตฯ ฯฯฮฟฮบฮฑฮธฮฟฯฮนฯฮผฮญฮฝฯฮฝ ฯฮทฮผฮฌฯฯฮฝ:
+issues.label_templates.title=ฮงฯฮฎฯฮท ฯฯฮฟฮบฮฑฮธฮฟฯฮนฯฮผฮญฮฝฮฟฯ
ฯฯ
ฮฝฯฮปฮฟฯ
ฯฮทฮผฮฌฮฝฯฮตฯฮฝ
+issues.label_templates.info=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฯฮฑฮผฯฮญฮปฮตฯ ฮฑฮบฯฮผฮฑ. ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮญฮฝฮฑ ฯฮฎฮผฮฑ ฮผฮต ฯฮฟ ฮบฮฟฯ
ฮผฯฮฏ ยซฮฮญฮฑ ฯฮฑฮผฯฮญฮปฮฑยป ฮฎ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฮญฮฝฮฑ ฯฮตฯ ฯฯฮฟฮบฮฑฮธฮฟฯฮนฯฮผฮญฮฝฯฮฝ ฯฮฑฮผฯฮตฮปฯฮฝ:
issues.label_templates.helper=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฯฯฮฝฮฟฮปฮฟ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฯฮฝ ฯฮทฮผฮฌฯฯฮฝ
issues.label_templates.use=ฮงฯฮฎฯฮท ฯฯ
ฮฝฯฮปฮฟฯ
ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฯฮฝ ฯฮทฮผฮฌฯฯฮฝ
issues.label_templates.fail_to_load_file=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฯฯฯฯฯฯฮทฯ ฯฯฮฝ ฯฯฮฟฯฯฯฯฮฝ ฯฮทฮผฮฌฯฯฮฝ ฮฑฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ยซ%sยป: %v
-issues.add_label=ฯฯฯฯฮธฮตฯฮต ฯฮท ฯฮฎฮผฮฑฮฝฯฮท %s %s
-issues.add_labels=ฯฯฯฯฮธฮตฯฮต ฯฮฑ ฯฮฎฮผฮฑฯฮฑ %s %s
+issues.add_label=ฯฯฯฯฮธฮตฯฮต ฯฮฟ ฯฮฎฮผฮฑ %s %s
+issues.add_labels=ฯฯฯฯฮธฮตฯฮต ฯฮนฯ ฯฮฑฮผฯฮญฮปฮตฯ %s %s
issues.remove_label=ฮฑฯฮฑฮฏฯฮตฯฮต ฯฮฟ ฯฮฎฮผฮฑ %s %s
-issues.remove_labels=ฮฑฯฮฑฮฏฯฮตฯฮต ฯฮฑ %s ฯฮฎฮผฮฑฯฮฑ %s
-issues.add_remove_labels=ฯฯฯฯฮธฮตฯฮต ฯฮฑ %s ฮบฮฑฮน ฮฑฯฮฑฮฏฯฮตฯฮต ฯฮฑ %s ฯฮฎฮผฮฑฯฮฑ %s
+issues.remove_labels=ฮฑฯฮฑฮฏฯฮตฯฮต ฯฮนฯ ฯฮฑฮผฯฮญฮปฮตฯ %s %s
+issues.add_remove_labels=ฯฯฯฯฮธฮตฯฮต ฯฮทฮฝ ฯฮฑฮผฯฮญฮปฮฑ %s, ฮบฮฑฮน ฮฑฯฮฑฮฏฯฮตฯฮต ฯฮนฯ ฯฮฑฮผฯฮญฮปฮตฯ %s %s
issues.add_milestone_at=`ฯฮฟ ฯฯฯฯฮธฮตฯฮต ฯฯฮฟ %s ฮฟฯฯฯฮทฮผฮฟ %s`
issues.add_project_at=`ฯฮฟ ฯฯฯฯฮธฮตฯฮต ฯฯฮฟ ฮญฯฮณฮฟ %s %s`
issues.change_milestone_at=`ฯฯฮฟฯฮฟฯฮฟฮฏฮทฯฮต ฯฮฟ ฮฟฯฯฯฮทฮผฮฟ ฮฑฯฯ %s ฯฮต %s %s`
@@ -1478,7 +1556,7 @@ issues.add_ref_at=`ฯฯฯฯฮธฮตฯฮต ฯฮทฮฝ ฮฑฮฝฮฑฯฮฟฯฮฌ %s %s`
issues.delete_branch_at=`ฮดฮนฮญฮณฯฮฑฯฮต ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %s %s`
issues.filter_label=ฮฃฮฎฮผฮฑ
issues.filter_label_exclude=`ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต alt
+ ฮบฮฌฮฝฯฮต ฮบฮปฮนฮบ/Enter
ฮณฮนฮฑ ฮฝฮฑ ฮตฮพฮฑฮนฯฮญฯฮตฯฮต ฯฮนฯ ฯฮทฮผฮฌฮฝฯฮตฮนฯ`
-issues.filter_label_no_select=ฮฮปฮฑ ฯฮฑ ฯฮฎฮผฮฑฯฮฑ
+issues.filter_label_no_select=ฮฮปฮตฯ ฮฟฮน ฯฮฑฮผฯฮญฮปฮตฯ
issues.filter_label_select_no_label=ฮงฯฯฮฏฯ ฮตฯฮนฮบฮญฯฮฑ
issues.filter_milestone=ฮฯฯฯฮทฮผฮฟ
issues.filter_milestone_all=ฮฮปฮฑ ฯฮฑ ฮฟฯฯฯฮทฮผฮฑ
@@ -1531,8 +1609,8 @@ issues.opened_by_fake=ฮฌฮฝฮฟฮนฮพฮต ฯฮฟ %[1]s ฮฑฯฯ %[2]s
issues.closed_by_fake=ฮฑฯฯ %[2]s ฮญฮบฮปฮตฮนฯฮฑฮฝ %[1]s
issues.previous=ฮ ฯฮฟฮทฮณฮฟฯฮผฮตฮฝฮท
issues.next=ฮฯฯฮผฮตฮฝฮท
-issues.open_title=ฮฮฝฮฟฮนฯฯฮฌ
-issues.closed_title=ฮฮปฮตฮนฯฯฮฌ
+issues.open_title=ฮฑฮฝฮฟฮนฯฯฮฌ
+issues.closed_title=ฮบฮปฮตฮนฯฯฮฌ
issues.draft_title=ฮ ฯฮฟฯฯฮญฮดฮนฮฟ
issues.num_comments_1=%d ฯฯฯฮปฮนฮฟ
issues.num_comments=%d ฯฯฯฮปฮนฮฑ
@@ -1556,8 +1634,8 @@ issues.reopened_at=`ฮพฮฑฮฝฮฌ ฮฌฮฝฮฟฮนฮพฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[2]s `
issues.ref_issue_from=`ฮฑฮฝฮฑฯฮญฯฮธฮทฮบฮต ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[4]s %[2]s `
issues.ref_pull_from=`ฮฑฮฝฮฑฯฮญฯฮธฮทฮบฮต ฯฮต ฮฑฯ
ฯฯ ฯฮฟ pull request %[4]s %[2]s `
-issues.ref_closing_from=`ฮฑฮฝฮฑฯฮญฯฮธฮทฮบฮต ฯฮต ฮญฮฝฮฑ pull request %[4]s ฯฮฟฯ
ฮธฮฑ ฮบฮปฮตฮฏฯฮตฮน ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[2]s `
-issues.ref_reopening_from=`ฮฑฮฝฮฑฯฮญฯฮธฮทฮบฮต ฯฮต ฮญฮฝฮฑ pull request %[4]s ฯฮฟฯ
ฮธฮฑ ฮฑฮฝฮฟฮฏฮพฮตฮน ฮพฮฑฮฝฮฌ ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[2]s `
+issues.ref_closing_from=`ฮฑฮฝฮญฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฯฮต ฮญฮฝฮฑ pull request %[4]s ฯฮฟฯ
ฯฯฮฟฯฮตฯฮตฮน ฮฝฮฑ ฮบฮปฮตฮฏฯฮตฮน ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[2]s `
+issues.ref_reopening_from=`ฮฑฮฝฮฑฯฮญฯฮธฮทฮบฮต ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฯฮต ฮญฮฝฮฑ pull request %[4]s ฯฮฟฯ
ฮธฮฑ ฮพฮฑฮฝฮฑฮฑฮฝฮฟฮฏฮพฮตฮน ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[2]s `
issues.ref_closed_from=`ฮญฮบฮปฮตฮนฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[4]s %[2]s `
issues.ref_reopened_from=`ฮฌฮฝฮฟฮนฮพฮต ฮพฮฑฮฝฮฌ ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[4]s %[2]s `
issues.ref_from=`ฮฑฯฯ %[1]s`
@@ -1566,13 +1644,13 @@ issues.author_helper=ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮตฮฏฮฝฮฑฮน ฮฟ ฯฯ
ฮณฮณฯฮฑฯฮญ
issues.role.owner=ฮฮดฮนฮฟฮบฯฮฎฯฮทฯ
issues.role.owner_helper=ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮตฮฏฮฝฮฑฮน ฮฟ ฮนฮดฮนฮฟฮบฯฮฎฯฮทฯ ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
issues.role.member=ฮฮญฮปฮฟฯ
-issues.role.member_helper=ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮตฮฏฮฝฮฑฮน ฮผฮญฮปฮฟฯ ฯฮฟฯ
ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ ฯฮฟฯ
ฮบฮฑฯฮญฯฮตฮน ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+issues.role.member_helper=ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮตฮฏฮฝฮฑฮน ฮผฮญฮปฮฟฯ ฯฮฟฯ
ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ, ฯฮฟฯ
ฮฟฯฮฟฮฏฮฟฯ
ฮฑฮฝฮฎฮบฮตฮน ฯฮฟ repository.
issues.role.collaborator=ฮฃฯ
ฮฝฮตฯฮณฮฌฯฮทฯ
-issues.role.collaborator_helper=ฮ ฯฯฮฎฯฯฮทฯ ฮญฮปฮฑฮฒฮต ฯฯฯฯฮบฮปฮทฯฮท ฯฯ
ฮฝฮตฯฮณฮฑฯฮฏฮฑฯ ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+issues.role.collaborator_helper=ฮ ฯฯฮฎฯฯฮทฯ ฮญฮปฮฑฮฒฮต ฯฯฯฯฮบฮปฮทฯฮท ฯฯ
ฮฝฮตฯฮณฮฑฯฮฏฮฑฯ ฯฯฮฟ repository.
issues.role.first_time_contributor=ฮฃฯ
ฮฝฯฮตฮปฮตฯฯฮฎฯ ฮณฮนฮฑ ฯฯฯฯฮท ฯฮฟฯฮฌ
-issues.role.first_time_contributor_helper=ฮฯ
ฯฮฎ ฮตฮฏฮฝฮฑฮน ฮท ฯฯฯฯฮท ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮฌ ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฯฯฮฎฯฯฮท ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+issues.role.first_time_contributor_helper=ฮฯ
ฯฮฎ ฮตฮฏฮฝฮฑฮน ฮท ฯฯฯฯฮท ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮฌ ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฯฯฮฎฯฯฮท ฯฯฮฟ repository.
issues.role.contributor=ฮฃฯ
ฮฝฯฮตฮปฮตฯฯฮฎฯ
-issues.role.contributor_helper=ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮญฯฮตฮน ฯฯฮฟฮทฮณฮฟฯฮผฮตฮฝฮญฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+issues.role.contributor_helper=ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮญฯฮตฮน ฯฯฮฟฮทฮณฮฟฯฮผฮตฮฝฮญฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ (commits) ฯฯฮฟ repository.
issues.re_request_review=ฮฯฮฑฮฝฮฑฮฏฯฮทฯฮท ฮฑฮฝฮฑฯฮบฯฯฮทฯฮทฯ
issues.is_stale=ฮฯฮฟฯ
ฮฝ ฯ
ฯฮฌฯฮพฮตฮน ฮฑฮปฮปฮฑฮณฮญฯ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ PR ฮฑฯฯ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฮฑฮฝฮฑฮธฮตฯฯฮทฯฮท
issues.remove_request_review=ฮฯฮฑฮฏฯฮตฯฮท ฮฑฮนฯฮฎฮผฮฑฯฮฟฯ ฮฑฮฝฮฑฮธฮตฯฯฮทฯฮทฯ
@@ -1589,10 +1667,10 @@ issues.label_color=ฮงฯฯฮผฮฑ ฯฮฎฮผฮฑฯฮฟฯ
issues.label_exclusive=ฮฯฮฟฮบฮปฮตฮนฯฯฮนฮบฯ
issues.label_archive=ฮฯฯฮตฮนฮฟฮธฮญฯฮทฯฮท ฯฮฎฮผฮฑฯฮฟฯ
issues.label_archived_filter=ฮฮผฯฮฌฮฝฮนฯฮท ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮผฮญฮฝฯฮฝ ฯฮทฮผฮฌฯฯฮฝ
-issues.label_archive_tooltip=ฮคฮฑ ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮผฮญฮฝฮฑ ฯฮฎฮผฮฑฯฮฑ ฮตฮพฮฑฮนฯฮฟฯฮฝฯฮฑฮน ฮฑฯฯ ฯฮนฯ ฯฯฮฟฯฮฌฯฮตฮนฯ ฯฯฮทฮฝ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮท ฮผฮต ฯฮฎฮผฮฑฯฮฑ.
-issues.label_exclusive_desc=ฮฮฝฮฟฮผฮฌฯฯฮต ฯฮฟ ฯฮฎฮผฮฑ ฯฮตฮดฮฏฮฟ/ฯฯฮฟฮนฯฮตฮฏฮฟ
ฮณฮนฮฑ ฮฝฮฑ ฯฮฟ ฮบฮฌฮฝฮตฯฮต ฮฑฮผฮฟฮนฮฒฮฑฮฏฮฑ ฮฑฯฮฟฮบฮปฮตฮนฯฯฮนฮบฯ ฮผฮต ฮฌฮปฮปฮฑ ฯฮฎฮผฮฑฯฮฑ ฯฮตฮดฮฏฮฟฯ
/
.
-issues.label_exclusive_warning=ฮคฯ
ฯฯฮฝ ฯฯ
ฮณฮบฯฮฟฯ
ฯฮผฮตฮฝฮฑ ฯฮฎฮผฮฑฯฮฑ ฮธฮฑ ฮฑฯฮฑฮนฯฮตฮธฮฟฯฮฝ ฮบฮฑฯฮฌ ฯฮทฮฝ ฮตฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฯฯฮฝ ฯฮทฮผฮฌฯฯฮฝ ฮตฮฝฯฯ ฮถฮทฯฮฎฮผฮฑฯฮฟฯ ฮฎ pull request.
-issues.label_count=%d ฯฮฎฮผฮฑฯฮฑ
+issues.label_archive_tooltip=ฮฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮผฮญฮฝฮตฯ ฯฮฑฮผฯฮญฮปฮตฯ ฮดฮตฮฝ ฮธฮฑ ฯฯฮฟฯฮตฮฏฮฝฮฟฮฝฯฮฑฮน ฯฮต ฯฯฮฎฯฯฮตฯ ฯฮฟฯ
ฮฑฮฝฮฑฮถฮทฯฮฟฯฮฝ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฯฮฑฮผฯฮญฮปฮตฯ ฯฯ ฯฯฮฟฯ
ฯ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮทฯ.
+issues.label_exclusive_desc=ฮฮฝฮฟฮผฮฌฯฯฮต ฯฮทฮฝ ฯฮฑฮผฯฮญฮปฮฑ ฯฮตฮดฮฏฮฟ/ฯฯฮฟฮนฯฮตฮฏฮฟ
ฮณฮนฮฑ ฮฝฮฑ ฯฮฟ ฮบฮฌฮฝฮตฯฮต ฮฑฮผฮฟฮนฮฒฮฑฮฏฮฑ ฮฑฯฮฟฮบฮปฮตฮนฯฯฮนฮบฯ ฮผฮต ฮฌฮปฮปฮตฯ ฯฮฑฮผฯฮญฮปฮตฯ ฯฮตฮดฮฏฮฟฯ
/
.
+issues.label_exclusive_warning=ฮคฯ
ฯฯฮฝ ฯฯ
ฮณฮบฯฮฟฯ
ฯฮผฮตฮฝฮตฯ ฯฮฑฮผฯฮญฮปฮตฯ ฮธฮฑ ฮฑฯฮฑฮนฯฮฟฯฮฝฯฮฑฮน ฮบฮฑฯฮฌ ฯฮทฮฝ ฮตฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฯฯฮฝ ฯฮทฮผฮฌฯฯฮฝ ฮตฮฝฯฯ ฮถฮทฯฮฎฮผฮฑฯฮฟฯ ฮฎ pull request.
+issues.label_count=%d ฯฮฑฮผฯฮญฮปฮตฯ
issues.label_open_issues=%d ฮฑฮฝฮฟฮนฮบฯฮฌ ฮถฮทฯฮฎฮผฮฑฯฮฑ
issues.label_edit=ฮฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ
issues.label_delete=ฮฮนฮฑฮณฯฮฑฯฮฎ
@@ -1624,7 +1702,7 @@ issues.unlock_comment=: ฮพฮตฮบฮปฮตฮฏฮดฯฯฮต ฮฑฯ
ฯฮฎ ฯฮท ฯฯ
ฮฝฮฟฮผฮนฮปฮฏฮฑ %s
issues.lock_confirm=ฮฮปฮตฮฏฮดฯฮผฮฑ
issues.unlock_confirm=ฮฮตฮบฮปฮตฮฏฮดฯฮผฮฑ
issues.lock.notice_1=- ฮฮปฮปฮฟฮน ฯฯฮฎฯฯฮตฯ ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮฑฯฮฎฯฮฟฯ
ฮฝ ฮฝฮญฮฑ ฯฯฯฮปฮนฮฑ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ.
-issues.lock.notice_2=- ฮฯฮตฮฏฯ ฮบฮฑฮน ฮฌฮปฮปฮฟฮน ฯฯ
ฮฝฮตฯฮณฮฌฯฮตฯ ฯฮฟฯ
ฮญฯฮฟฯ
ฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮธฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฮฑฮบฯฮผฮฑ ฮฝฮฑ ฮฑฯฮฎฯฮตฯฮต ฯฯฯฮปฮนฮฑ ฯฮฟฯ
ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฮฟฯฮฑฯฮฌ ฯฮต ฮฌฮปฮปฮฟฯ
ฯ.
+issues.lock.notice_2=- ฮฯฮตฮฏฯ, ฮผฮฑฮถฮฏ ฮผฮต ฯฮฟฯ
ฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮตฯ ฯฮฑฯ ฯฮฟฯ
ฮญฯฮฟฯ
ฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ repository, ฮธฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฮฑฮบฯฮผฮฑ ฮฝฮฑ ฮฑฯฮฎฯฮตฯฮต ฯฯฯฮปฮนฮฑ ฯฮฟฯ
ฮธฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮฒฮปฮญฯฮฟฯ
ฮฝ ฮบฮฑฮน ฮฌฮปฮปฮฟฮน.
issues.lock.notice_3=- ฮฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮพฮตฮบฮปฮตฮนฮดฯฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฯฮนฮฟ ฮผฮตฯฮฌ.
issues.unlock.notice_1=- ฮฮปฮฟฮน ฮธฮฑ ฮฒฯฮฏฯฮบฮฟฮฝฯฮฑฮน ฯฮฌฮปฮน ฯฮต ฮธฮญฯฮท ฮฝฮฑ ฮฑฯฮฎฯฮฟฯ
ฮฝ ฯฯฯฮปฮนฮฟ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ.
issues.unlock.notice_2=- ฮฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฯฮฌฮฝฯฮฑ ฮฝฮฑ ฮพฮฑฮฝฮฑฮบฮปฮตฮนฮดฯฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฯฮนฮฟ ฮผฮตฯฮฌ.
@@ -1636,8 +1714,8 @@ issues.delete=ฮฮนฮฑฮณฯฮฑฯฮฎ
issues.delete.title=ฮฮฑ ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ;
issues.delete.text=ฮฮฏฯฯฮต ฮฒฮญฮฒฮฑฮนฮฟฮน ฯฯฯ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ; (ฮฯ
ฯฯ ฮธฮฑ ฯฮฒฮฎฯฮตฮน ฮฟฯฮนฯฯฮนฮบฮฌ ฯฮปฮฟ ฯฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฯฮฟฯ
. ฮฮพฮตฯฮฌฯฯฮต ฮฑฮฝ ฮผฮฎฯฯฯ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฮบฮปฮตฮฏฯฮตฯฮต ฯฮฟ ฮถฮฎฯฮทฮผฮฑ, ฮฑฮฝ ฮธฮฑ ฮธฮญฮปฮฑฯฮต ฮฝฮฑ ฯฮฟ ฮบฯฮฑฯฮฎฯฮตฯฮต.)
issues.tracker=ฮฮฑฯฮฑฮณฯฮฑฯฮฎ ฯฯฯฮฝฮฟฯ
-issues.start_tracking_short=ฮฮบฮบฮฏฮฝฮทฯฮท ฯฯฮฟฮฝฯฮผฮตฯฯฮฟฯ
-issues.start_tracking=ฮฮบฮบฮฏฮฝฮทฯฮท ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฯฯฯฮฝฮฟฯ
+issues.start_tracking_short=ฮฮฝฮฑฯฮพฮท ฯฯฮฟฮฝฯฮผฮตฯฯฮฟฯ
+issues.start_tracking=ฮฮฝฮฑฯฮพฮท ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฯฯฯฮฝฮฟฯ
issues.start_tracking_history=`ฮพฮตฮบฮฏฮฝฮทฯฮต ฮฝฮฑ ฮตฯฮณฮฌฮถฮตฯฮฑฮน %s`
issues.tracker_auto_close=ฮคฮฟ ฯฯฮฟฮฝฯฮผฮตฯฯฮฟ ฮธฮฑ ฯฯฮฑฮผฮฑฯฮฎฯฮตฮน ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฯฯฮฑฮฝ ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฮบฮปฮตฮฏฯฮตฮน
issues.tracking_already_started=`ฮฯฮตฯฮต ฮฎฮดฮท ฮพฮตฮบฮนฮฝฮฎฯฮตฮน ฮฝฮฑ ฮบฮฑฯฮฑฮณฯฮฌฯฮตฯฮต ฯฮฟฮฝ ฯฯฯฮฝฮฟ ฯฮฑฯ ฯฮต ฮญฮฝฮฑ ฮฌฮปฮปฮฟ ฮถฮฎฯฮทฮผฮฑ !`
@@ -1662,7 +1740,7 @@ issues.error_modifying_due_date=ฮ ฯฮฟฮญฮบฯ
ฯฮต ฯฯฮฌฮปฮผฮฑ ฮบฮฑฯฮฌ ฯฮทฮฝ ฮฑ
issues.error_removing_due_date=ฮ ฯฮฟฮญฮบฯ
ฯฮต ฯฯฮฌฮปฮผฮฑ ฮบฮฑฯฮฌ ฯฮทฮฝ ฮบฮฑฯฮฌฯฮณฮทฯฮท ฮทฮผฮตฯฮฟฮผฮทฮฝฮฏฮฑฯ ฯฮฑฯฮฌฮดฮฟฯฮทฯ.
issues.push_commit_1=ฯฯฯฯฮธฮตฯฮต %d ฯ
ฯฮฟฮฒฮฟฮปฮฎ %s
issues.push_commits_n=ฯฯฯฯฮธฮตฯฮต %d ฯ
ฯฮฟฮฒฮฟฮปฮญฯ %s
-issues.force_push_codes=`ฮญฮบฮฑฮฝฮต force-push %[1]s ฮฑฯฯ ฯฮฟ %[2]s
ฯฯฮฟ %[4]s
%[6]s`
+issues.force_push_codes=`ฮญฮบฮฑฮฝฮต force-push %[1]s ฮฑฯฯ ฯฮฟ %[2]s
ฯฯฮฟ %[4]s
%[6]s`
issues.force_push_compare=ฮฃฯฮณฮบฯฮนฯฮท
issues.due_date_form=ฮตฮตฮตฮต-ฮผฮผ-ฮทฮท
issues.due_date_form_add=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮทฮผฮตฯฮฟฮผฮทฮฝฮฏฮฑฯ ฯฮฑฯฮฌฮดฮฟฯฮทฯ
@@ -1705,7 +1783,7 @@ issues.dependency.add_error_dep_issue_not_exist=ฮฮพฮฑฯฯฯฮผฮตฮฝฮฟ ฮถฮฎฯฮทฮผ
issues.dependency.add_error_dep_not_exist=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮท ฮฮพฮฌฯฯฮทฯฮท.
issues.dependency.add_error_dep_exists=ฮ ฮฮพฮฌฯฯฮทฯฮท ฯ
ฯฮฌฯฯฮตฮน ฮฎฮดฮท.
issues.dependency.add_error_cannot_create_circular=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮผฮนฮฑ ฮตฮพฮฌฯฯฮทฯฮท ฮผฮต ฮดฯฮฟ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฯฮฟฯ
ฮผฯฮปฮฟฮบฮฌฯฮฟฯ
ฮฝ ฯฮฟ ฮญฮฝฮฑ ฯฮฟ ฮฌฮปฮปฮฟ.
-issues.dependency.add_error_dep_not_same_repo=ฮฮฑฮน ฯฮฑ ฮดฯฮฟ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฯฯฮญฯฮตฮน ฮฝฮฑ ฮฒฯฮฏฯฮบฮฟฮฝฯฮฑฮน ฯฯฮฟ ฮฏฮดฮนฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+issues.dependency.add_error_dep_not_same_repo=ฮฮฑฮน ฯฮฑ ฮดฯฮฟ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฯฯฮญฯฮตฮน ฮฝฮฑ ฮฒฯฮฏฯฮบฮฟฮฝฯฮฑฮน ฯฯฮฟ ฮฏฮดฮนฮฟ repository.
issues.review.self.approval=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮตฮณฮบฯฮฏฮฝฮตฯฮต ฯฮฟ ฮดฮนฮบฯ ฯฮฑฯ pull request.
issues.review.self.rejection=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮถฮทฯฮฎฯฮตฯฮต ฮฑฮปฮปฮฑฮณฮญฯ ฯฯฮฟ ฮดฮนฮบฯ ฯฮฑฯ pull request.
issues.review.approve=ฮตฮฝฮญฮบฯฮนฮฝฮต ฯฮนฯ ฮฑฮปฮปฮฑฮณฮญฯ %s
@@ -1770,18 +1848,18 @@ pulls.show_all_commits=ฮฮผฯฮฌฮฝฮนฯฮท ฯฮปฯฮฝ ฯฯฮฝ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ
pulls.show_changes_since_your_last_review=ฮฮผฯฮฌฮฝฮนฯฮท ฮฑฮปฮปฮฑฮณฯฮฝ ฮฑฯฯ ฯฮทฮฝ ฯฮตฮปฮตฯ
ฯฮฑฮฏฮฑ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮท
pulls.showing_only_single_commit=ฮฮผฯฮฌฮฝฮนฯฮท ฮผฯฮฝฮฟ ฮฑฮปฮปฮฑฮณฯฮฝ ฯฮทฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ %[1]s
pulls.showing_specified_commit_range=ฮฮผฯฮฌฮฝฮนฯฮท ฮผฯฮฝฮฟ ฯฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ ฮผฮตฯฮฑฮพฯ %[1]s..%[2]s
-pulls.select_commit_hold_shift_for_range=ฮฯฮนฮปฮญฮพฯฮต ฯ
ฯฮฟฮฒฮฟฮปฮฎ. ฮฯฮฑฯฮฎฯฯฮต ฯฮฑฯฮทฮผฮญฮฝฮฟ ฯฮฟ shift + ฮบฮฌฮฝฯฮต ฮบฮปฮนฮบ ฮณฮนฮฑ ฮฝฮฑ ฮตฯฮนฮปฮญฮพฮตฯฮต ฮญฮฝฮฑ ฮตฯฯฮฟฯ
+pulls.select_commit_hold_shift_for_range=ฮฯฮนฮปฮญฮพฯฮต commit. ฮฯฮฑฯฮฎฯฯฮต ฯฮฑฯฮทฮผฮญฮฝฮฟ ฯฮฟ shift + ฮบฮฌฮฝฯฮต ฮบฮปฮนฮบ ฮณฮนฮฑ ฮฝฮฑ ฮตฯฮนฮปฮญฮพฮตฯฮต ฮญฮฝฮฑ ฮตฯฯฮฟฯ
pulls.review_only_possible_for_full_diff=ฮ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮท ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฮผฯฮฝฮฟ ฮบฮฑฯฮฌ ฯฮทฮฝ ฯฯฮฟฮฒฮฟฮปฮฎ ฯฮทฯ ฯฮปฮฎฯฮทฯ ฮดฮนฮฑฯฮฟฯฮฌฯ
-pulls.filter_changes_by_commit=ฮฆฮนฮปฯฯฮฌฯฮนฯฮผฮฑ ฮบฮฑฯฮฌ ฯ
ฯฮฟฮฒฮฟฮปฮฎ
+pulls.filter_changes_by_commit=ฮฆฮนฮปฯฯฮฌฯฮนฯฮผฮฑ ฮบฮฑฯฮฌ commit
pulls.nothing_to_compare=ฮฯ
ฯฮฟฮฏ ฮฟฮน ฮบฮปฮฌฮดฮฟฮน ฮตฮฏฮฝฮฑฮน ฮฏฮดฮนฮฟฮน. ฮฮตฮฝ ฯฯฮตฮนฮฌฮถฮตฯฮฑฮน ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮญฮฝฮฑ pull request.
pulls.nothing_to_compare_and_allow_empty_pr=ฮฯ
ฯฮฟฮฏ ฮฟฮน ฮบฮปฮฌฮดฮฟฮน ฮตฮฏฮฝฮฑฮน ฮฏฮดฮนฮฟฮน. ฮฯ
ฯฯ ฯฮฟ PR ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯ.
pulls.has_pull_request=`ฮฅฯฮฌฯฯฮตฮน ฮฎฮดฮท pull request ฮผฮตฯฮฑฮพฯ ฮฑฯ
ฯฯฮฝ ฯฯฮฝ ฮบฮปฮฌฮดฯฮฝ: %[2]s#%[3]d `
pulls.create=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ pull request
-pulls.title_desc_few=ฮธฮญฮปฮตฮน ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฮน %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮฑฯฯ %[2]s
ฯฮต %[3]s
+pulls.title_desc_few=ฮธฮญฮปฮตฮน ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฮน %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮฑฯฯ %[2]s
ฯฮต %[3]s
pulls.merged_title_desc_few=ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮต %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮฑฯฯ %[2]s
ฯฮต %[3]s
%[4]s
pulls.change_target_branch_at=`ฮฌฮปฮปฮฑฮพฮต ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ ฮฑฯฯ %s ฯฮต %s %s`
pulls.tab_conversation=ฮฃฯ
ฮถฮฎฯฮทฯฮท
-pulls.tab_commits=ฮฅฯฮฟฮฒฮฟฮปฮญฯ
+pulls.tab_commits=Commits
pulls.tab_files=ฮฮปฮปฮฑฮณฮผฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฑ
pulls.reopen_to_merge=ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮฑฮฝฮฟฮฏฮพฯฮต ฮพฮฑฮฝฮฌ ฮฑฯ
ฯฯ ฯฮฟ pull request ฮณฮนฮฑ ฮฝฮฑ ฮตฮบฯฮตฮปฮญฯฮตฯฮต ฮผฮนฮฑ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท.
pulls.cant_reopen_deleted_branch=ฮฯ
ฯฯ ฯฮฟ pull request ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฟฮฏฮพฮตฮน ฮพฮฑฮฝฮฌ ฮตฯฮตฮนฮดฮฎ ฮฟ ฮบฮปฮฌฮดฮฟฯ ฮดฮนฮฑฮณฯฮฌฯฮทฮบฮต.
@@ -1800,7 +1878,7 @@ pulls.data_broken=ฮฯ
ฯฯ ฯฮฟ pull request ฮตฮฏฮฝฮฑฮน ฮบฮฑฯฮตฯฯฯฮฑฮผฮผฮญฮฝ
pulls.files_conflicted=ฮฯ
ฯฯ ฯฮฟ pull request ฯฮตฯฮนฮญฯฮตฮน ฮฑฮปฮปฮฑฮณฮญฯ ฯฮฟฯ
ฯฯ
ฮณฮบฯฮฟฯฮฟฮฝฯฮฑฮน ฮผฮต ฯฮฟ ฮบฮปฮฌฮดฮฟ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ.
pulls.is_checking=ฮ ฮญฮปฮตฮณฯฮฟฯ ฯฯ
ฮณฮบฯฮฟฯฯฮตฯฮฝ ฮบฮฑฯฮฌ ฯฮทฮฝ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฒฯฮฏฯฮบฮตฯฮฑฮน ฯฮต ฮตฮพฮญฮปฮนฮพฮท. ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮพฮฑฮฝฮฌ ฯฮต ฮปฮฏฮณฮฑ ฮปฮตฯฯฮฌ.
pulls.is_ancestor=ฮฯ
ฯฯฯ ฮฟ ฮบฮปฮฌฮดฮฟฯ ฮดฮตฮฝ ฯฮตฯฮนฮญฯฮตฮน ฮบฮฌฯฮน ฮบฮฑฮนฮฝฮฟฯฯฮณฮนฮฟ ฯฮฟฯ
ฮดฮตฮฝ ฮญฯฮตฮน ฮฟ ฮบฮปฮฌฮดฮฟฯ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ ฮฎฮดฮท. ฮฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฮฏฯฮฟฯฮฑ ฯฮฟฯ
ฮธฮฑ ฮผฯฮฟฯฮฟฯฯฮต ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮตฮฏ.
-pulls.is_empty=ฮฮน ฮฑฮปฮปฮฑฮณฮญฯ ฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ฮฒฯฮฏฯฮบฮฟฮฝฯฮฑฮน ฮฎฮดฮท ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ. ฮฮฑ ฮตฮฏฮฝฮฑฮน ฮผฮนฮฑ ฮบฮตฮฝฮฎ ฯ
ฯฮฟฮฒฮฟฮปฮฎ.
+pulls.is_empty=ฮฮน ฮฑฮปฮปฮฑฮณฮญฯ ฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ฮฒฯฮฏฯฮบฮฟฮฝฯฮฑฮน ฮฎฮดฮท ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ. ฮฮฑ ฮตฮฏฮฝฮฑฮน ฮญฮฝฮฑ ฮบฮตฮฝฯ commit.
pulls.required_status_check_failed=ฮฯฮนฯฮผฮญฮฝฮฟฮน ฮฑฯฮฑฮนฯฮฟฯฮผฮตฮฝฮฟฮน ฮญฮปฮตฮณฯฮฟฮน ฮดฮตฮฝ ฮฎฯฮฑฮฝ ฮตฯฮนฯฯ
ฯฮตฮฏฯ.
pulls.required_status_check_missing=ฮฮตฮฏฯฮฟฯ
ฮฝ ฮฟฯฮนฯฮผฮญฮฝฮฟฮน ฮฑฯฮฑฮนฯฮฟฯฮผฮตฮฝฮฟฮน ฮญฮปฮตฮณฯฮฟฮน.
pulls.required_status_check_administrator=ฮฉฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ, ฮผฯฮฟฯฮตฮฏฯฮต ฮฑฮบฯฮผฮฑ ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ pull request.
@@ -1821,33 +1899,33 @@ pulls.reject_count_1=%d ฮฑฮฏฯฮทฮผฮฑ ฮฑฮปฮปฮฑฮณฮฎฯ
pulls.reject_count_n=%d ฮฑฮนฯฮฎฮผฮฑฯฮฑ ฮฑฮปฮปฮฑฮณฮฎฯ
pulls.waiting_count_1=%d ฮฑฮฝฮฑฮผฮฟฮฝฮฎ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮทฯ
pulls.waiting_count_n=%d ฮฑฮฝฮฑฮผฮฟฮฝฮญฯ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮทฯ
-pulls.wrong_commit_id=ฮคฮฟ ฮฑฮฝฮฑฮณฮฝฯฯฮนฯฯฮนฮบฯ ฯฮทฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ ฯฯฮญฯฮตฮน ฮฝฮฑ ฮฑฮฝฯฮนฯฯฮฟฮนฯฮตฮฏ ฯฮต ฮผฮฏฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ
+pulls.wrong_commit_id=ฮคฮฟ ฮฑฮฝฮฑฮณฮฝฯฯฮนฯฯฮนฮบฯ ฯฮฟฯ
commit ฯฯฮญฯฮตฮน ฮฝฮฑ ฮฑฮฝฯฮนฯฯฮฟฮนฯฮตฮฏ ฯฮต ฮผฮฏฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ
pulls.no_merge_desc=ฮฯ
ฯฯ ฯฮฟ pull request ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯ
ฮธฮตฮฏ ฮตฯฮตฮนฮดฮฎ ฯฮปฮตฯ ฮฟฮน ฮตฯฮนฮปฮฟฮณฮญฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ ฮตฮฏฮฝฮฑฮน ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ.
pulls.no_merge_helper=ฮฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฯฮต ฯฮนฯ ฮตฯฮนฮปฮฟฮณฮญฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ ฯฯฮนฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฎ ฯฯ
ฮณฯฯฮฝฮตฯฯฯฮต ฯฮฟ pull request ฯฮตฮนฯฮฟฮบฮฏฮฝฮทฯฮฑ.
pulls.no_merge_wip=ฮฯ
ฯฯ ฯฮฟ pull request ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯ
ฮธฮตฮฏ, ฮตฯฮตฮนฮดฮฎ ฮญฯฮตฮน ฮตฯฮนฯฮทฮผฮฑฮฝฮธฮตฮฏ ฯฯ ฮผฮนฮฑ ฮตฯฮณฮฑฯฮฏฮฑ ฯฮต ฮตฮพฮญฮปฮนฮพฮท.
pulls.no_merge_not_ready=ฮฯ
ฯฯ ฯฮฟ pull request ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฯฮฟฮนฮผฮฟ ฮณฮนฮฑ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท, ฮตฮปฮญฮณฮพฯฮต ฯฮทฮฝ ฮบฮฑฯฮฌฯฯฮฑฯฮท ฮตฮพฮญฯฮฑฯฮทฯ ฮบฮฑฮน ฯฮฟฯ
ฯ ฮตฮปฮญฮณฯฮฟฯ
ฯ ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ.
pulls.no_merge_access=ฮฮตฮฝ ฮตฮฏฯฯฮต ฮตฮพฮฟฯ
ฯฮนฮฟฮดฮฟฯฮทฮผฮญฮฝฮฟฮน ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ pull request.
-pulls.merge_pull_request=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ
+pulls.merge_pull_request=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ commit ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ
pulls.rebase_merge_pull_request=ฮฮปฮปฮฑฮณฮฎ ฮฒฮฌฯฮทฯ ฮบฮฑฮน ฮผฮตฯฮฌ ฮณฯฮฎฮณฮฟฯฮฑ-ฮผฯฯฮฟฯฯฮฌ
-pulls.rebase_merge_commit_pull_request=ฮฮปฮปฮฑฮณฮฎฯ ฮฒฮฌฯฮทฯ ฮบฮฑฮน ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ
-pulls.squash_merge_pull_request=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ squash
+pulls.rebase_merge_commit_pull_request=ฮฮปฮปฮฑฮณฮฎฯ ฮฒฮฌฯฮทฯ ฮบฮฑฮน ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ commit ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ
+pulls.squash_merge_pull_request=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ squash commit
pulls.merge_manually=ฮฃฯ
ฮณฯฯฮฝฮตฯฯฮทฮบฮฑฮฝ ฯฮตฮนฯฮฟฮบฮฏฮฝฮทฯฮฑ
-pulls.merge_commit_id=ฮคฮฟ ID ฯฮทฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ
-pulls.require_signed_wont_sign=ฮ ฮบฮปฮฌฮดฮฟฯ ฮฑฯฮฑฮนฯฮตฮฏ ฯ
ฯฮฟฮณฮตฮณฯฮฑฮผฮผฮญฮฝฮตฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮฑฮปฮปฮฌ ฮฑฯ
ฯฮฎ ฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮดฮตฮฝ ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ
+pulls.merge_commit_id=ฮคฮฟ ID ฯฮฟฯ
commit ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ
+pulls.require_signed_wont_sign=ฮ ฮบฮปฮฌฮดฮฟฯ ฮฑฯฮฑฮนฯฮตฮฏ ฯ
ฯฮฟฮณฮตฮณฯฮฑฮผฮผฮญฮฝฮตฯ commits ฮฑฮปฮปฮฌ ฮฑฯ
ฯฮฎ ฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮดฮตฮฝ ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ
pulls.invalid_merge_option=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฯฮต ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฮตฯฮนฮปฮฟฮณฮฎ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ pull request.
-pulls.merge_conflict=ฮ ฮฃฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฯฮญฯฯ
ฯฮต: ฮฅฯฮฎฯฮพฮต ฮผฮนฮฑ ฮดฮนฮญฮฝฮตฮพฮท ฮบฮฑฯฮฌ ฯฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท. ฮฅฯฯฮดฮตฮนฮพฮท: ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮผฮนฮฑ ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮฎ ฯฯฯฮฑฯฮทฮณฮนฮบฮฎ
-pulls.merge_conflict_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฮฃฯฮฌฮปฮผฮฑฯฮฟฯ
-pulls.rebase_conflict=ฮ ฮฃฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฯฮญฯฯ
ฯฮต: ฮฅฯฮฎฯฮพฮต ฮผฮนฮฑ ฯฯฮณฮบฯฮฟฯ
ฯฮท ฮบฮฑฯฮฌ ฯฮทฮฝ ฮฑฮปฮปฮฑฮณฮฎ ฮฒฮฌฯฮทฯ ฯฮทฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ: %[1]s. ฮฅฯฯฮดฮตฮนฮพฮท: ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮผฮนฮฑ ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮฎ ฯฯฯฮฑฯฮทฮณฮนฮบฮฎ
-pulls.rebase_conflict_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฮฃฯฮฌฮปฮผฮฑฯฮฟฯ
-pulls.unrelated_histories=H ฮฃฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฯฮญฯฯ
ฯฮต: ฮ ฮบฮตฯฮฑฮปฮฎ ฮบฮฑฮน ฮท ฮฒฮฌฯฮท ฯฮทฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ ฮดฮตฮฝ ฮผฮฟฮนฯฮฌฮถฮฟฮฝฯฮฑฮน ฮผฮนฮฑ ฮบฮฟฮนฮฝฮฎ ฮนฯฯฮฟฯฮฏฮฑ. ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮฎ: ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮผฮนฮฑ ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮฎ ฯฯฯฮฑฯฮทฮณฮนฮบฮฎ
-pulls.merge_out_of_date=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฑฯฮญฯฯ
ฯฮต: ฮฮฑฯฮฌ ฯฮท ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯฮทฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ, ฮท ฮฒฮฌฯฮท ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮต. ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮฎ: ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮพฮฑฮฝฮฌ.
-pulls.head_out_of_date=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฑฯฮญฯฯ
ฯฮต: ฮฮฑฯฮฌ ฯฮท ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯฮทฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ, ฯฮฟ HEAD ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮต. ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮฎ: ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮพฮฑฮฝฮฌ.
+pulls.merge_conflict=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฑฯฮญฯฯ
ฯฮต: ฮฅฯฮฎฯฮพฮต ฮผฮนฮฑ ฯฯฮณฮบฯฮฟฯ
ฯฮท ฮบฮฑฯฮฌ ฯฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท. ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮฎ: ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮผฮนฮฑ ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮฎ ฯฯฯฮฑฯฮทฮณฮนฮบฮฎ
+pulls.merge_conflict_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฯฯฮฌฮปฮผฮฑฯฮฟฯ
+pulls.rebase_conflict=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฑฯฮญฯฯ
ฯฮต: ฮ ฯฮฟฮญฮบฯ
ฯฮต ฯฯฮณฮบฯฮฟฯ
ฯฮท ฮบฮฑฯฮฌ ฯฮฟ rebase ฯฮฟฯ
commit: %[1]s. ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮฎ: ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮผฮฏฮฑ ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮฎ ฯฯฯฮฑฯฮทฮณฮนฮบฮฎ
+pulls.rebase_conflict_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฯฯฮฌฮปฮผฮฑฯฮฟฯ
+pulls.unrelated_histories=H ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฑฯฮญฯฯ
ฯฮต: ฮ ฮบฮตฯฮฑฮปฮฎ ฮบฮฑฮน ฮท ฮฒฮฌฯฮท ฯฮทฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ ฮดฮตฮฝ ฮญฯฮฟฯ
ฮฝ ฮบฮฟฮนฮฝฮฎ ฮนฯฯฮฟฯฮฏฮฑ. ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮฎ: ฮฮฟฮบฮนฮผฮฌฯฯฮต ฮผฮนฮฑ ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮฎ ฯฯฯฮฑฯฮทฮณฮนฮบฮฎ
+pulls.merge_out_of_date=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฑฯฮญฯฯ
ฯฮต: ฮฮฑฯฮฌ ฯฮท ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯฮทฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ, ฮท ฮฒฮฌฯฮท ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮต. ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮฎ: ฮ ฯฮฟฯฯฮฑฮธฮฎฯฯฮต ฯฮฌฮปฮน.
+pulls.head_out_of_date=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮฑฯฮญฯฯ
ฯฮต: ฮฮฑฯฮฌ ฯฮท ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯฮทฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ, ฯฮฟ HEAD ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮต. ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮฎ: ฮ ฯฮฟฯฯฮฑฮธฮฎฯฯฮต ฯฮฌฮปฮน.
pulls.has_merged=ฮฯฮฟฯฯ
ฯฮฏฮฑ: ฮคฮฟ pull request ฮญฯฮตฮน ฯฯ
ฮณฯฯฮฝฮตฯ
ฮธฮตฮฏ, ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮพฮฑฮฝฮฌ ฮฎ ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮตฮน ฮฟ ฮบฮปฮฌฮดฮฟฯ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ.
-pulls.push_rejected=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฯฮธฮทฯฮทฯ: ฮ ฯฮธฮทฯฮท ฮฑฯฮฟฯฯฮฏฯฮธฮทฮบฮต. ฮฮปฮญฮณฮพฯฮต ฯฮฑ Git hooks ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-pulls.push_rejected_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฮ ฮปฮฎฯฮฟฯ
ฯ ฮฯฯฯฯฮนฯฮทฯ
-pulls.push_rejected_no_message=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฯฮธฮทฯฮทฯ: ฮ ฯฮธฮทฯฮท ฮฑฯฮฟฯฯฮฏฯฮธฮทฮบฮต, ฮฑฮปฮปฮฌ ฮดฮตฮฝ ฮปฮฌฮฒฮฑฮผฮต ฮบฮฌฯฮฟฮนฮฟ ฮผฮฎฮฝฯ
ฮผฮฑ. ฮฮปฮญฮณฮพฯฮต ฯฮฑ Git hooks ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
+pulls.push_rejected=ฮ ฯฮธฮทฯฮท ฮฑฯฮญฯฯ
ฯฮต: ฮ ฯฮธฮทฯฮท ฮฑฯฮฟฯฯฮฏฯฮธฮทฮบฮต. ฮฮปฮญฮณฮพฯฮต ฯฮฑ Git hooks ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
+pulls.push_rejected_summary=ฮฮฎฮฝฯ
ฮผฮฑ ฯฮปฮฎฯฮฟฯ
ฯ ฮฑฯฯฯฯฮนฯฮทฯ
+pulls.push_rejected_no_message=ฮ ฯฮธฮทฯฮท ฮฑฯฮญฯฯ
ฯฮต: ฮ ฯฮธฮทฯฮท ฮฑฯฮฟฯฯฮฏฯฮธฮทฮบฮต, ฮฑฮปฮปฮฌ ฮดฮตฮฝ ฮปฮฌฮฒฮฑฮผฮต ฮบฮฌฯฮฟฮนฮฟ ฮผฮฎฮฝฯ
ฮผฮฑ. ฮฮปฮญฮณฮพฯฮต ฯฮฑ Git hooks ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
pulls.open_unmerged_pull_exists=`ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮฝฮฟฮฏฮพฮตฯฮต ฮตฮบ ฮฝฮญฮฟฯ
, ฮตฯฮตฮนฮดฮฎ ฯ
ฯฮฌฯฯฮตฮน ฮญฮฝฮฑ ฮตฮบฮบฯฮตฮผฮญฯ pull request (#%d) ฮผฮต ฯฮฑฮฝฮฟฮผฮฟฮนฯฯฯ
ฯฮตฯ ฮนฮดฮนฯฯฮทฯฮตฯ.`
pulls.status_checking=ฮฮตฯฮนฮบฮฟฮฏ ฮญฮปฮตฮณฯฮฟฮน ฮตฮบฮบฯฮตฮผฮฟฯฮฝ
pulls.status_checks_success=ฮฮปฮฟฮน ฮฟฮน ฮญฮปฮตฮณฯฮฟฮน ฮฎฯฮฑฮฝ ฮตฯฮนฯฯ
ฯฮตฮฏฯ
@@ -1866,13 +1944,13 @@ pulls.outdated_with_base_branch=ฮฯ
ฯฯฯ ฮฟ ฮบฮปฮฌฮดฮฟฯ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮต
pulls.close=ฮฮปฮตฮฏฯฮนฮผฮฟ pull request
pulls.closed_at=`ฮญฮบฮปฮตฮนฯฮต ฮฑฯ
ฯฯ ฯฮฟ pull request %[2]s `
pulls.reopened_at=`ฮฌฮฝฮฟฮนฮพฮต ฮพฮฑฮฝฮฌ ฮฑฯ
ฯฯ ฯฮฟ pull request %[2]s `
-pulls.cmd_instruction_hint=`ฮฮตฮฏฯฮต ฯฮนฯ ฮฟฮดฮทฮณฮฏฮตฯ ฮณฯฮฑฮผฮผฮฎฯ ฮตฮฝฯฮฟฮปฯฮฝ .`
+pulls.cmd_instruction_hint=ฮ ฯฮฟฮฒฮฟฮปฮฎ ฮฟฮดฮทฮณฮนฯฮฝ ฮณฯฮฑฮผฮผฮฎฯ ฮตฮฝฯฮฟฮปฯฮฝ
pulls.cmd_instruction_checkout_title=ฮฮปฮตฮณฯฮฟฯ
-pulls.cmd_instruction_checkout_desc=ฮฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฯฮฟฯ
ฮญฯฮณฮฟฯ
ฯฮฑฯ, ฮตฮปฮญฮณฮพฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮบฮฑฮน ฮดฮฟฮบฮนฮผฮฌฯฯฮต ฯฮนฯ ฮฑฮปฮปฮฑฮณฮญฯ.
+pulls.cmd_instruction_checkout_desc=ฮฯฯ ฯฮฟ repository ฯฮฟฯ
ฮญฯฮณฮฟฯ
ฯฮฑฯ, ฮตฮปฮญฮณฮพฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮบฮฑฮน ฮดฮฟฮบฮนฮผฮฌฯฯฮต ฯฮนฯ ฮฑฮปฮปฮฑฮณฮญฯ.
pulls.cmd_instruction_merge_title=ฮฃฯ
ฮณฯฯฮฝฮตฯ
ฯฮท
-pulls.cmd_instruction_merge_desc=ฮฃฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฯฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ ฮบฮฑฮน ฮตฮฝฮทฮผฮญฯฯฯฮท ฯฯฮฟ Gitea.
+pulls.cmd_instruction_merge_desc=ฮฃฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฯฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ ฮบฮฑฮน ฮตฮฝฮทฮผฮญฯฯฯฮท ฯฯฮฟ Forgejo.
pulls.clear_merge_message=ฮฮบฮบฮฑฮธฮฌฯฮนฯฮท ฮผฮทฮฝฯฮผฮฑฯฮฟฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ
-pulls.clear_merge_message_hint=ฮ ฮตฮบฮบฮฑฮธฮฌฯฮนฯฮท ฯฮฟฯ
ฮผฮทฮฝฯฮผฮฑฯฮฟฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ ฮธฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฮน ฮผฯฮฝฮฟ ฯฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฯฮฟฯ
ฮผฮทฮฝฯฮผฮฑฯฮฟฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ ฮบฮฑฮน ฮธฮฑ ฮดฮนฮฑฯฮทฯฮฎฯฮตฮน ฯฮฑ ฯฮฑฯฮฑฮณฯฮผฮตฮฝฮฑ git trailers ฯฯฯฯ "Co-Authored-By โฆ".
+pulls.clear_merge_message_hint=ฮ ฮตฮบฮบฮฑฮธฮฌฯฮนฯฮท ฯฮฟฯ
ฮผฮทฮฝฯฮผฮฑฯฮฟฯ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ ฮธฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฮน ฮผฯฮฝฮฟ ฯฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฯฮฟฯ
ฮผฮทฮฝฯฮผฮฑฯฮฟฯ commit ฮบฮฑฮน ฮธฮฑ ฮดฮนฮฑฯฮทฯฮฎฯฮตฮน ฯฮฑ ฯฮฑฯฮฑฮณฯฮผฮตฮฝฮฑ git trailers ฯฯฯฯ "Co-Authored-By โฆ".
pulls.auto_merge_button_when_succeed=(ฮฯฮฑฮฝ ฮฟฮน ฮญฮปฮตฮณฯฮฟฮน ฯฮตฯฯฯฮฟฯ
ฮฝ)
pulls.auto_merge_when_succeed=ฮฯ
ฯฯฮผฮฑฯฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฯฯฮฑฮฝ ฯฮปฮฟฮน ฮฟฮน ฮญฮปฮตฮณฯฮฟฮน ฯฮตฯฯฯฮฟฯ
ฮฝ
@@ -1923,14 +2001,14 @@ milestones.filter_sort.most_complete=ฮ ฮตฯฮนฯฯฯฯฮตฯฮฟ ฯฮปฮฎฯฮท
milestones.filter_sort.most_issues=ฮ ฮตฯฮนฯฯฯฯฮตฯฮฑ ฮถฮทฯฮฎฮผฮฑฯฮฑ
milestones.filter_sort.least_issues=ฮฮนฮณฯฯฮตฯฮฑ ฮถฮทฯฮฎฮผฮฑฯฮฑ
-signing.will_sign=ฮฯ
ฯฮฎ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮผฮต ฯฮฟ ฮบฮปฮตฮนฮดฮฏ ยซ%sยป.
-signing.wont_sign.error=ฮ ฮฑฯฮฟฯ
ฯฮนฮฌฯฯฮทฮบฮต ฯฯฮฌฮปฮผฮฑ ฮบฮฑฯฮฌ ฯฮฟฮฝ ฮญฮปฮตฮณฯฮฟ ฮณฮนฮฑ ฯฮฟ ฮฑฮฝ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ.
-signing.wont_sign.nokey=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮฟ ฮบฮปฮตฮนฮดฮฏ ฮณฮนฮฑ ฮฝฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮฑฯ
ฯฮฎ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ.
-signing.wont_sign.never=ฮฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮดฮตฮฝ ฯ
ฯฮฟฮณฯฮฌฯฮฟฮฝฯฮฑฮน ฯฮฟฯฮญ.
-signing.wont_sign.always=ฮฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฯ
ฯฮฟฮณฯฮฌฯฮฟฮฝฯฮฑฮน ฯฮฌฮฝฯฮฑ.
-signing.wont_sign.pubkey=ฮ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮดฮต ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮตฯฮตฮนฮดฮฎ ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮดฮทฮผฯฯฮนฮฟ ฮบฮปฮตฮนฮดฮฏ ฯฮฟฯ
ฮฝฮฑ ฯฯ
ฮฝฮดฮญฮตฯฮฑฮน ฮผฮต ฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
-signing.wont_sign.twofa=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮญฯฮตฯฮต ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮท ฯฮทฮฝ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ ฮณฮนฮฑ ฮฝฮฑ ฯ
ฯฮฟฮณฯฮฌฯฮตฯฮฑฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ.
-signing.wont_sign.parentsigned=ฮ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮดฮต ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮบฮฑฮธฯฯ ฮท ฮณฮฟฮฝฮนฮบฮฎ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮดฮตฮฝ ฮญฯฮตฮน ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ.
+signing.will_sign=ฮฯ
ฯฯ ฯฮฟ commit ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮผฮต ฯฮฟ ฮบฮปฮตฮนฮดฮฏ ยซ%sยป.
+signing.wont_sign.error=ฮ ฮฑฯฮฟฯ
ฯฮนฮฌฯฯฮทฮบฮต ฯฯฮฌฮปฮผฮฑ ฮบฮฑฯฮฌ ฯฮฟฮฝ ฮญฮปฮตฮณฯฮฟ ฮณฮนฮฑ ฯฮฟ ฮฑฮฝ ฯฮฟ commit ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ.
+signing.wont_sign.nokey=ฮ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎฯ ฮดฮตฮฝ ฯฮฑฯฮญฯฮตฮน ฮบฮฌฯฮฟฮนฮฟ ฮบฮปฮตฮนฮดฮฏ ฮณฮนฮฑ ฯฮทฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
commit.
+signing.wont_sign.never=ฮคฮฑ commits ฮดฮตฮฝ ฯ
ฯฮฟฮณฯฮฌฯฮฟฮฝฯฮฑฮน ฯฮฟฯฮญ.
+signing.wont_sign.always=ฮคฮฑ commit ฯ
ฯฮฟฮณฯฮฌฯฮฟฮฝฯฮฑฮน ฯฮฌฮฝฯฮฑ.
+signing.wont_sign.pubkey=To ฯฮฟฮผฮผฮนฯ ฮดฮต ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮตฯฮตฮนฮดฮฎ ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮดฮทฮผฯฯฮนฮฟ ฮบฮปฮตฮนฮดฮฏ ฯฮฟฯ
ฯฯ
ฯฯฮตฯฮฏฮถฮตฯฮฑฮน ฮผฮต ฯฮฟฮฝ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฑฯ.
+signing.wont_sign.twofa=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮญฯฮตฯฮต ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮท ฯฮทฮฝ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮท ฮดฯฮฟ ฯฮฑฯฮฑฮณฯฮฝฯฯฮฝ ฮณฮนฮฑ ฯฮทฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮฎ commit.
+signing.wont_sign.parentsigned=To commit ฮดฮตฮฝ ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮบฮฑฮธฯฯ ฯฮฟ ฯฯฮฟฮทฮณฮฟฯฮผฮตฮฝฮฟ commit ฮดฮตฮฝ ฮญฯฮตฮน ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ.
signing.wont_sign.basesigned=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮดฮต ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮบฮฑฮธฯฯ ฮท ฮฒฮฑฯฮนฮบฮฎ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮดฮตฮฝ ฮญฯฮตฮน ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฯฮทฯ ฮฒฮฌฯฮทฯ.
signing.wont_sign.headsigned=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮดฮต ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮบฮฑฮธฯฯ ฮดฮตฮฝ ฮญฯฮตฮน ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฯฮทฯ ฮบฮตฯฮฑฮปฮฎฯ.
signing.wont_sign.commitssigned=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮดฮต ฮธฮฑ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ ฮบฮฑฮธฯฯ ฯฮปฮตฯ ฮฟฮน ฯฯฮตฯฮนฮบฮญฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮดฮตฮฝ ฮญฯฮฟฯ
ฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮตฮฏ.
@@ -1944,21 +2022,21 @@ wiki=Wiki
wiki.welcome=ฮฮฑฮปฯฯ ฮฎฯฮธฮฑฯฮต ฯฯฮฟ Wiki.
wiki.welcome_desc=ฮคฮฟ wiki ฯฮฑฯ ฮตฯฮนฯฯฮญฯฮตฮน ฮฝฮฑ ฮณฯฮฌฯฮตฯฮต ฮบฮฑฮน ฮฝฮฑ ฮผฮฟฮนฯฮฑฯฯฮตฮฏฯฮต ฯฮตฮบฮผฮทฯฮนฯฯฮตฮนฯ (documentation) ฮผฮต ฮฌฮปฮปฮฟฯ
ฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮตฯ.
wiki.desc=ฮฯฮฌฯฯฮต ฮบฮฑฮน ฮผฮฟฮนฯฮฑฯฯฮตฮฏฯฮต ฯฮตฮบฮผฮทฯฮนฯฯฮตฮนฯ ฮผฮต ฯฯ
ฮฝฮตฯฮณฮฌฯฮตฯ.
-wiki.create_first_page=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯฯฯฯฮทฯ ฯฮตฮปฮฏฮดฮฑฯ
+wiki.create_first_page=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฑฯฯฮนฮบฮฎฯ ฯฮตฮปฮฏฮดฮฑฯ
wiki.page=ฮฃฮตฮปฮฏฮดฮฑ
wiki.filter_page=ฮฆฮนฮปฯฯฮฌฯฮนฯฮผฮฑ ฯฮตฮปฮฏฮดฮฑฯ
wiki.new_page=ฮฃฮตฮปฮฏฮดฮฑ
wiki.page_title=ฮคฮฏฯฮปฮฟฯ ฯฮตฮปฮฏฮดฮฑฯ
wiki.page_content=ฮ ฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฯฮตฮปฮฏฮดฮฑฯ
wiki.default_commit_message=ฮฯฮฌฯฯฮต ฮผฮนฮฑ ฯฮทฮผฮตฮฏฯฯฮท ฯฯฮตฯฮนฮบฮฌ ฮผฮต ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฮตฮฝฮทฮผฮญฯฯฯฮท ฯฮตฮปฮฏฮดฮฑฯ (ฯฯฮฟฮฑฮนฯฮตฯฮนฮบฯ).
-wiki.save_page=ฮฯฮฟฮธฮฎฮบฮตฯ
ฯฮท ฮฃฮตฮปฮฏฮดฮฑฯ
-wiki.last_commit_info=%s ฮตฯฮตฮพฮตฯฮณฮฌฯฯฮทฮบฮต ฮฑฯ
ฯฮฎ ฯฮท ฯฮตฮปฮฏฮดฮฑ %s
+wiki.save_page=ฮฯฮฟฮธฮฎฮบฮตฯ
ฯฮท ฯฮตฮปฮฏฮดฮฑฯ
+wiki.last_commit_info=%s ฮตฯฮตฮพฮตฯฮณฮฌฯฯฮทฮบฮต ฯฮทฮฝ ฯฮตฮปฮฏฮดฮฑ %s
wiki.edit_page_button=ฮฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ
-wiki.new_page_button=ฮฮญฮฑ ฮฃฮตฮปฮฏฮดฮฑ
-wiki.file_revision=ฮฮฝฮฑฮธฮตฯฯฮทฯฮท ฮฃฮตฮปฮฏฮดฮฑฯ
-wiki.wiki_page_revisions=ฮฮฝฮฑฮธฮตฯฯฮฎฯฮตฮนฯ ฮฃฮตฮปฮฏฮดฮฑฯ Wiki
+wiki.new_page_button=ฮฮญฮฑ ฯฮตฮปฮฏฮดฮฑ
+wiki.file_revision=ฮฮบฮดฮฟฯฮท ฯฮตฮปฮฏฮดฮฑฯ
+wiki.wiki_page_revisions=ฮฮฝฮฑฮธฮตฯฯฮฎฯฮตฮนฯ ฯฮตฮปฮฏฮดฮฑฯ wiki
wiki.back_to_wiki=ฮ ฮฏฯฯ ฯฯฮท ฯฮตฮปฮฏฮดฮฑ wiki
-wiki.delete_page_button=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฃฮตฮปฮฏฮดฮฑฯ
+wiki.delete_page_button=ฮฮนฮฑฮณฯฮฑฯฮฎ ฯฮตฮปฮฏฮดฮฑฯ
wiki.delete_page_notice_1=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฯฮทฯ ฯฮตฮปฮฏฮดฮฑฯ wiki ยซ%sยป ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
wiki.page_already_exists=ฮฅฯฮฌฯฯฮตฮน ฮฎฮดฮท ฮผฮนฮฑ ฯฮตฮปฮฏฮดฮฑ wiki ฮผฮต ฯฮฟ ฮฏฮดฮนฮฟ ฯฮฝฮฟฮผฮฑ.
wiki.reserved_page=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฮตฮปฮฏฮดฮฑฯ wiki ยซ%sยป ฮตฮฏฮฝฮฑฮน ฮดฮตฯฮผฮตฯ
ฮผฮญฮฝฮฟ.
@@ -2010,15 +2088,15 @@ activity.unresolved_conv_label=ฮฮฝฮฟฮนฯฯฮฎ
activity.title.releases_1=%d ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ
activity.title.releases_n=%d ฮตฮบฮดฯฯฮตฮนฯ
activity.title.releases_published_by=%s ฮดฮทฮผฮฟฯฮนฮตฯฯฮทฮบฮต ฮฑฯฯ %s
-activity.published_release_label=ฮฮทฮผฮฟฯฮนฮตฯฮธฮทฮบฮต
-activity.no_git_activity=ฮฮตฮฝ ฮญฯฮตฮน ฯ
ฯฮฌฯฮพฮตฮน ฮบฮฑฮผฮฏฮฑ ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฑ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ ฯฮต ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฯฮตฯฮฏฮฟฮดฮฟ.
+activity.published_release_label=ฮฮทฮผฮฟฯฮฏฮตฯ
ฯฮท
+activity.no_git_activity=ฮฮตฮฝ ฮญฯฮตฮน ฯ
ฯฮฌฯฮพฮตฮน ฮบฮฑฮผฮฏฮฑ ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฑ commit ฯฮต ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฯฮตฯฮฏฮฟฮดฮฟ.
activity.git_stats_exclude_merges=ฮฮบฯฯฯ ฯฮนฯ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฮนฯ,
activity.git_stats_author_1=%d ฯฯ
ฮณฮณฯฮฑฯฮญฮฑฯ
activity.git_stats_author_n=%d ฯฯ
ฮณฮณฯฮฑฯฮตฮฏฯ
activity.git_stats_pushed_1=ฮญฯฮตฮน ฯฮธฮฎฯฮตฮน
activity.git_stats_pushed_n=ฮญฯฮฟฯ
ฮฝ ฯฮธฮฎฯฮตฮน
-activity.git_stats_commit_1=%d ฯ
ฯฮฟฮฒฮฟฮปฮฎ
-activity.git_stats_commit_n=%d ฯ
ฯฮฟฮฒฮฟฮปฮญฯ
+activity.git_stats_commit_1=%d commit
+activity.git_stats_commit_n=%d commits
activity.git_stats_push_to_branch=ฯฯฮฟ %s ฮบฮฑฮน
activity.git_stats_push_to_all_branches=ฯฮต ฯฮปฮฟฯ
ฯ ฯฮฟฯ
ฯ ฮบฮปฮฌฮดฮฟฯ
ฯ.
activity.git_stats_on_default_branch=ฮฃฯฮฟ %s,
@@ -2033,7 +2111,7 @@ activity.git_stats_and_deletions=ฮบฮฑฮน
activity.git_stats_deletion_1=%d ฮดฮนฮฑฮณฯฮฑฯฮฎ
activity.git_stats_deletion_n=%d ฮดฮนฮฑฮณฯฮฑฯฮญฯ
-contributors.contribution_type.commits=ฮฅฯฮฟฮฒฮฟฮปฮญฯ
+contributors.contribution_type.commits=Commits
search=ฮฮฝฮฑฮถฮฎฯฮทฯฮท
search.search_repo=ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
@@ -2047,8 +2125,8 @@ search.code_no_results=ฮฮตฮฝ ฮฒฯฮญฮธฮทฮบฮต ฯฮทฮณฮฑฮฏฮฟฯ ฮบฯฮดฮนฮบฮฑฯ ฯฮฟ
search.code_search_unavailable=ฮ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮท ฮบฯฮดฮนฮบฮฑ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮท ฮฑฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮตฯฮนฮบฮฟฮนฮฝฯฮฝฮฎฯฯฮต ฮผฮต ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ.
settings=ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ
-settings.desc=ฮฃฯฮนฯ ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮตฮฏฯฮต ฯฮนฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฮณฮนฮฑ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
-settings.options=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+settings.desc=ฮฃฯฮนฯ ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮตฮฏฯฮต ฯฮนฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฮณฮนฮฑ ฯฮฟ repository
+settings.options=Repository
settings.collaboration=ฮฃฯ
ฮฝฮตฯฮณฮฌฯฮตฯ
settings.collaboration.admin=ฮฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ
settings.collaboration.write=ฮฮณฮณฯฮฑฯฮฎ
@@ -2059,18 +2137,18 @@ settings.hooks=Webhooks
settings.githooks=Git hooks
settings.basic_settings=ฮฮฑฯฮนฮบฮญฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ
settings.mirror_settings=ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮตฮนฮดฯฮปฮฟฯ
-settings.mirror_settings.docs=ฮกฯ
ฮธฮผฮฏฯฯฮต ฯฮฟฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฟ ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯ ฯฯฮฝ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ, ฮตฯฮนฮบฮตฯฯฮฝ ฮบฮฑฮน ฮบฮปฮฌฮดฯฮฝ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฮฑฯ ฯฮต ฮญฮฝฮฑ ฮฌฮปฮปฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-settings.mirror_settings.docs.disabled_pull_mirror.instructions=ฮกฯ
ฮธฮผฮฏฯฯฮต ฯฮฟฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฟ ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯ ฯฯฮฝ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ, ฮตฯฮนฮบฮตฯฯฮฝ ฮบฮฑฮน ฮบฮปฮฌฮดฯฮฝ ฯฮฟฯ
ฮญฯฮณฮฟฯ
ฯฮฑฯ ฮผฮต ฮญฮฝฮฑ ฮฌฮปฮปฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮคฮฑ ฮตฮฏฮดฯฮปฮฑ ฯฯฯฮฟฯ
ฮปฮฎฯฮทฯ ฮญฯฮฟฯ
ฮฝ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮฑฯฯ ฯฮฟฮฝ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฑฯ.
-settings.mirror_settings.docs.disabled_push_mirror.instructions=ฮกฯ
ฮธฮผฮฏฯฯฮต ฯฮทฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮท ฮปฮฎฯฮท ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ, ฮตฯฮนฮบฮตฯฯฮฝ ฮบฮฑฮน ฮบฮปฮฌฮดฯฮฝ ฮฑฯฯ ฮญฮฝฮฑ ฮฌฮปฮปฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+settings.mirror_settings.docs=ฮกฯ
ฮธฮผฮฏฯฯฮต ฯฮฟฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฟ ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯ commit, ฮตฯฮนฮบฮตฯฯฮฝ ฮบฮฑฮน ฮบฮปฮฌฮดฯฮฝ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฮฑฯ ฯฮต ฮญฮฝฮฑ ฮฌฮปฮปฮฟ repository.
+settings.mirror_settings.docs.disabled_pull_mirror.instructions=ฮกฯ
ฮธฮผฮฏฯฯฮต ฯฮฟฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฟ ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯ ฯฯฮฝ commit, ฮตฯฮนฮบฮตฯฯฮฝ ฮบฮฑฮน ฮบฮปฮฌฮดฯฮฝ ฯฮฟฯ
ฮญฯฮณฮฟฯ
ฯฮฑฯ ฮผฮต ฮญฮฝฮฑ ฮฌฮปฮปฮฟ repository. ฮคฮฑ ฮตฮฏฮดฯฮปฮฑ ฯฯฯฮฟฯ
ฮปฮฎฯฮทฯ ฮญฯฮฟฯ
ฮฝ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮฑฯฯ ฯฮฟฮฝ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฑฯ.
+settings.mirror_settings.docs.disabled_push_mirror.instructions=ฮกฯ
ฮธฮผฮฏฯฯฮต ฯฮทฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮท ฮปฮฎฯฮท ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ, ฮตฯฮนฮบฮตฯฯฮฝ ฮบฮฑฮน ฮบฮปฮฌฮดฯฮฝ ฮฑฯฯ ฮญฮฝฮฑ ฮฌฮปฮปฮฟ repository.
settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=ฮฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ, ฮฑฯ
ฯฯ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮณฮฏฮฝฮตฮน ฮผฯฮฝฮฟ ฯฯฮฟ ฮผฮตฮฝฮฟฯ "ฮฮญฮฑ ฮฮตฯฮฑฯฮฟฯฮฌ". ฮฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ, ฯฯ
ฮผฮฒฮฟฯ
ฮปฮตฯ
ฯฮตฮฏฯฮต ฯฮฟ:
settings.mirror_settings.docs.disabled_push_mirror.info=ฮคฮฑ ฮตฮฏฮดฯฮปฮฑ ฯฮธฮทฯฮทฯ ฮญฯฮฟฯ
ฮฝ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮฑฯฯ ฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฑฯ.
-settings.mirror_settings.docs.no_new_mirrors=ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฯฮฑฯ ฮฑฮฝฯฮนฮณฯฮฌฯฮตฮน ฯฮนฯ ฮฑฮปฮปฮฑฮณฮญฯ ฯฯฮฟฯ ฮฎ ฮฑฯฯ ฮญฮฝฮฑ ฮฌฮปฮปฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮฮฌฮฒฮตฯฮต ฯ
ฯฯฯฮท ฯฯฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮฝฮญฮฑ ฮตฮฏฮดฯฮปฮฑ ฮฑฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ.
+settings.mirror_settings.docs.no_new_mirrors=ฮคฮฟ repository ฯฮฑฯ ฮฑฮฝฯฮนฮณฯฮฌฯฮตฮน ฯฮนฯ ฮฑฮปฮปฮฑฮณฮญฯ ฯฯฮฟฯ ฮฎ ฮฑฯฯ ฮญฮฝฮฑ ฮฌฮปฮปฮฟ repository. ฮฮฌฮฒฮตฯฮต ฯ
ฯฯฯฮท ฯฯฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮฝฮญฮฑ ฮตฮฏฮดฯฮปฮฑ ฮฑฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ.
settings.mirror_settings.docs.can_still_use=ฮฮฝ ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฯฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮฑ ฯ
ฯฮฌฯฯฮฟฮฝฯฮฑ ฮตฮฏฮดฯฮปฮฑ ฮฎ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮฝฮญฮฑ, ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮฑฮบฯฮผฮฑ ฯฮฟ ฯ
ฯฮฌฯฯฯฮฝ ฮตฮฏฮดฯฮปฮฟ.
settings.mirror_settings.docs.pull_mirror_instructions=ฮฮนฮฑ ฮฝฮฑ ฮฟฯฮฏฯฮตฯฮต ฮญฮฝฮฑฮฝ ฮตฮฏฮดฯฮปฮฟ ฮญฮปฮพฮทฯ, ฯฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฯฯ
ฮผฮฒฮฟฯ
ฮปฮตฯ
ฮธฮตฮฏฯฮต:
settings.mirror_settings.docs.more_information_if_disabled=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮผฮฌฮธฮตฯฮต ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฮณฮนฮฑ ฯฮฑ ฮตฮฏฮดฯฮปฮฑ ฯฮธฮทฯฮทฯ ฮบฮฑฮน ฮญฮปฮพฮทฯ ฮตฮดฯ:
settings.mirror_settings.docs.doc_link_title=ฮ ฯฯ ฮผฯฮฟฯฯ ฮฝฮฑ ฮฑฮฝฯฮนฮณฯฮฌฯฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ;
settings.mirror_settings.docs.doc_link_pull_section=ฯฮฟ ฮบฮตฯฮฌฮปฮฑฮนฮฟ "Pulling from a remote repository" ฯฮทฯ ฯฮตฮบฮผฮทฯฮฏฯฯฮทฯ.
-settings.mirror_settings.docs.pulling_remote_title=ฮฮปฮพฮท ฮฑฯฯ ฮญฮฝฮฑ ฮฑฯฮฟฮผฮฑฮบฯฯ
ฯฮผฮญฮฝฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+settings.mirror_settings.docs.pulling_remote_title=Pull ฮฑฯฯ ฮญฮฝฮฑ ฮฑฯฮฟฮผฮฑฮบฯฯ
ฯฮผฮญฮฝฮฟ repository
settings.mirror_settings.mirrored_repository=ฮฮฏฮดฯฮปฮฟ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
settings.mirror_settings.direction=ฮฮฑฯฮตฯฮธฯ
ฮฝฯฮท
settings.mirror_settings.direction.pull=Pull
@@ -2081,11 +2159,11 @@ settings.mirror_settings.push_mirror.remote_url=URL ฮฑฯฮฟฮผฮฑฮบฯฯ
ฯฮผฮญฮฝฮฟฯ
settings.mirror_settings.push_mirror.add=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮตฮฏฮดฯฮปฮฟฯ
ฯฮธฮทฯฮทฯ
settings.mirror_settings.push_mirror.edit_sync_time=ฮฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฮดฮนฮฑฯฯฮฎฮผฮฑฯฮฟฯ ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฮฟฯ ฮตฮนฮดฯฮปฮฟฯ
-settings.sync_mirror=ฮฃฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯฯ ฮคฯฯฮฑ
+settings.sync_mirror=ฮฮฑ ฮณฮฏฮฝฮตฮน ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯฯ ฯฯฯฮฑ
settings.pull_mirror_sync_in_progress=ฮฮปฮบฮฟฮฝฯฮฑฮน ฮฑฮปฮปฮฑฮณฮญฯ ฮฑฯฯ ฯฮทฮฝ ฮฑฯฮฟฮผฮฑฮบฯฯ
ฯฮผฮญฮฝฮท ฯฮฟฯฮฟฮธฮตฯฮฏฮฑ %s ฮฑฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ.
settings.push_mirror_sync_in_progress=ฮฮธฮทฯฮท ฮฑฮปฮปฮฑฮณฯฮฝ ฯฯฮฟ ฮฑฯฮฟฮผฮฑฮบฯฯ
ฯฮผฮญฮฝฮฟ %s ฮฑฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ.
settings.site=ฮฯฯฮฟฯฮตฮปฮฏฮดฮฑ
-settings.update_settings=ฮฮฝฮทฮผฮญฯฯฯฮท ฯฯ
ฮธฮผฮฏฯฮตฯฮฝ
+settings.update_settings=ฮฯฮฟฮธฮฎฮบฮตฯ
ฯฮท ฯฯ
ฮธฮผฮฏฯฮตฯฮฝ
settings.update_mirror_settings=ฮฮฝฮทฮผฮญฯฯฯฮท ฯฯ
ฮธฮผฮฏฯฮตฯฮฝ ฮตฮนฮดฯฮปฮฟฯ
settings.branches.switch_default_branch=ฮฮปฮปฮฑฮณฮฎ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
settings.branches.update_default_branch=ฮฮฝฮทฮผฮญฯฯฯฮท ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
@@ -2126,41 +2204,41 @@ settings.projects_desc=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮญฯฮณฯฮฝ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟ
settings.actions_desc=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท actions ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
settings.admin_settings=ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ
settings.admin_enable_health_check=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮตฮปฮญฮณฯฯฮฝ ฯ
ฮณฮตฮฏฮฑฯ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ (git fsck)
-settings.admin_code_indexer=Indexer ฮฯฮดฮนฮบฮฑ
-settings.admin_stats_indexer=Indexer ฮฃฯฮฑฯฮนฯฯฮนฮบฯฮฝ ฮฯฮดฮนฮบฮฑ
-settings.admin_indexer_commit_sha=ฮคฮตฮปฮตฯ
ฯฮฑฮฏฮฟ Indexed SHA
+settings.admin_code_indexer=Indexer ฮบฯฮดฮนฮบฮฑ
+settings.admin_stats_indexer=Indexer ฯฯฮฑฯฮนฯฯฮนฮบฯฮฝ ฮบฯฮดฮนฮบฮฑ
+settings.admin_indexer_commit_sha=ฮคฮตฮปฮตฯ
ฯฮฑฮฏฮฟ indexed commit
settings.admin_indexer_unindexed=Unindexed
settings.reindex_button=ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฯฮทฮฝ ฮฟฯ
ฯฮฌ Reindex
settings.reindex_requested=ฮฮนฯฮฎฮธฮทฮบฮต reindex
-settings.admin_enable_close_issues_via_commit_in_any_branch=ฮฮปฮตฮฏฯฮนฮผฮฟ ฮตฮฝฯฯ ฮถฮทฯฮฎฮผฮฑฯฮฟฯ ฮผฮญฯฯ ฮผฮนฮฑฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ ฯฮฟฯ
ฮญฮณฮนฮฝฮต ฯฮต ฮญฮฝฮฑฮฝ ฮผฮท ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮบฮปฮฌฮดฮฟ
+settings.admin_enable_close_issues_via_commit_in_any_branch=ฮฮปฮตฮฏฯฮนฮผฮฟ ฮตฮฝฯฯ ฮถฮทฯฮฎฮผฮฑฯฮฟฯ ฮผฮญฯฯ commit ฯฮฟฯ
ฮญฮณฮนฮฝฮต ฯฮต ฮญฮฝฮฑฮฝ ฮผฮท'ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮบฮปฮฌฮดฮฟ
settings.danger_zone=ฮฯฮฝฮท ฮบฮนฮฝฮดฯฮฝฮฟฯ
-settings.new_owner_has_same_repo=ฮ ฮฝฮญฮฟฯ ฮนฮดฮนฮฟฮบฯฮฎฯฮทฯ ฮญฯฮตฮน ฮฎฮดฮท ฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮผฮต ฯฮฟ ฮฏฮดฮนฮฟ ฯฮฝฮฟฮผฮฑ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮตฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฮฌฮปฮปฮฟ ฯฮฝฮฟฮผฮฑ.
-settings.convert=ฮฮตฯฮฑฯฯฮฟฯฮฎ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
-settings.convert_desc=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮผฮตฯฮฑฯฯฮญฯฮตฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟ ฮตฮฏฮดฯฮปฮฟ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮฯ
ฯฯ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
-settings.convert_notices_1=ฮฯ
ฯฮฎ ฮท ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮฑ ฮธฮฑ ฮผฮตฯฮฑฯฯฮญฯฮตฮน ฯฮฟ ฮตฮฏฮดฯฮปฮฟ ฯฮต ฮญฮฝฮฑ ฮบฮฑฮฝฮฟฮฝฮนฮบฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
+settings.new_owner_has_same_repo=ฮ ฮฝฮญฮฟฯ ฮนฮดฮนฮฟฮบฯฮฎฯฮทฯ ฮญฯฮตฮน ฮฎฮดฮท ฮญฮฝฮฑ repository ฮผฮต ฯฮฟ ฮฏฮดฮนฮฟ ฯฮฝฮฟฮผฮฑ. ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮตฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑ ฮฌฮปฮปฮฟ ฯฮฝฮฟฮผฮฑ.
+settings.convert=ฮฮตฯฮฑฯฯฮฟฯฮฎ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ repository
+settings.convert_desc=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮผฮตฯฮฑฯฯฮญฯฮตฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟ ฮตฮฏฮดฯฮปฮฟ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ repository. ฮฯ
ฯฯ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
+settings.convert_notices_1=ฮฯ
ฯฮฎ ฮท ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮฑ ฮธฮฑ ฮผฮตฯฮฑฯฯฮญฯฮตฮน ฯฮฟ ฮตฮฏฮดฯฮปฮฟ ฯฮต ฮญฮฝฮฑ ฮบฮฑฮฝฮฟฮฝฮนฮบฯ repository ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
settings.convert_confirm=ฮฮตฯฮฑฯฯฮฟฯฮฎ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
-settings.convert_succeed=ฮคฮฟ ฮตฮฏฮดฯฮปฮฟ ฮญฯฮตฮน ฮผฮตฯฮฑฯฯฮฑฯฮตฮฏ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-settings.convert_fork=ฮฮตฯฮฑฯฯฮฟฯฮฎ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
-settings.convert_fork_desc=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮผฮตฯฮฑฯฯฮญฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ fork ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮฯ
ฯฯ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
-settings.convert_fork_notices_1=ฮฯ
ฯฮฎ ฮท ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮฑ ฮธฮฑ ฮผฮตฯฮฑฯฯฮญฯฮตฮน ฯฮฟ fork ฯฮต ฮญฮฝฮฑ ฮบฮฑฮฝฮฟฮฝฮนฮบฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
+settings.convert_succeed=ฮคฮฟ ฮตฮฏฮดฯฮปฮฟ ฮญฯฮตฮน ฮผฮตฯฮฑฯฯฮฑฯฮตฮฏ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ repository.
+settings.convert_fork=ฮฮตฯฮฑฯฯฮฟฯฮฎ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ repository
+settings.convert_fork_desc=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮผฮตฯฮฑฯฯฮญฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ fork ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ repository. ฮฯ
ฯฯ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
+settings.convert_fork_notices_1=ฮฯ
ฯฮฎ ฮท ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮฑ ฮธฮฑ ฮผฮตฯฮฑฯฯฮญฯฮตฮน ฯฮฟ fork ฯฮต ฮญฮฝฮฑ ฮบฮฑฮฝฮฟฮฝฮนฮบฯ repository ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
settings.convert_fork_confirm=ฮฮตฯฮฑฯฯฮฟฯฮฎ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
-settings.convert_fork_succeed=ฮคฮฟ fork ฮญฯฮตฮน ฮผฮตฯฮฑฯฯฮฑฯฮตฮฏ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+settings.convert_fork_succeed=ฮคฮฟ fork ฮญฯฮตฮน ฮผฮตฯฮฑฯฯฮฑฯฮตฮฏ ฯฮต ฮบฮฑฮฝฮฟฮฝฮนฮบฯ repository.
settings.transfer.title=ฮฮตฯฮฑฮฒฮฏฮฒฮฑฯฮท ฮนฮดฮนฮฟฮบฯฮทฯฮฏฮฑฯ
settings.transfer.rejected=ฮ ฮผฮตฯฮฑฮฒฮฏฮฒฮฑฯฮท ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฑฯฮฟฯฯฮฏฯฮธฮทฮบฮต.
settings.transfer.success=ฮ ฮผฮตฯฮฑฮฒฮฏฮฒฮฑฯฮท ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฎฯฮฑฮฝ ฮตฯฮนฯฯ
ฯฮฎฯ.
settings.transfer_abort=ฮฮบฯฯฯฯฮท ฮผฮตฯฮฑฮฒฮฏฮฒฮฑฯฮทฯ
settings.transfer_abort_invalid=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮบฯ
ฯฯฯฮตฯฮต ฮผฮนฮฑ ฮฑฮฝฯฯฮฑฯฮบฯฮท ฮผฮตฯฮฑฮฒฮฏฮฒฮฑฯฮท ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
settings.transfer_abort_success=ฮ ฮผฮตฯฮฑฯฮฟฯฮฌ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฯฮฟ %s ฮฑฮบฯ
ฯฯฮธฮทฮบฮต ฮผฮต ฮตฯฮนฯฯ
ฯฮฏฮฑ.
-settings.transfer_desc=ฮฮตฯฮฑฮฒฮนฮฒฮฌฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฯฮต ฮญฮฝฮฑฮฝ ฯฯฮฎฯฯฮท ฮฎ ฯฮต ฮญฮฝฮฑฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ ฮณฮนฮฑ ฯฮฟฮฝ ฮฟฯฮฟฮฏฮฟ ฮญฯฮตฯฮต ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ.
+settings.transfer_desc=ฮฮตฯฮฑฮฒฮนฮฒฮฌฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository ฯฮต ฮญฮฝฮฑฮฝ ฯฯฮฎฯฯฮท ฮฎ ฯฮต ฮญฮฝฮฑฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ ฮณฮนฮฑ ฯฮฟฮฝ ฮฟฯฮฟฮฏฮฟ ฮญฯฮตฯฮต ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ.
settings.transfer_form_title=ฮฮนฯฮฌฮณฮตฯฮต ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฯ ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮท:
-settings.transfer_in_progress=ฮฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ ฯ
ฯฮฌฯฯฮตฮน ฮผฮนฮฑ ฮตฮฝ ฮตฮพฮตฮปฮฏฮพฮตฮน ฮผฮตฯฮฑฮฒฮฏฮฒฮฑฯฮท. ฮ ฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฮฑฮบฯ
ฯฯฯฯฮต ฯฮทฮฝ ฮฑฮฝ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฮผฮตฯฮฑฮฒฮนฮฒฮฌฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฯฮต ฮฌฮปฮปฮฟ ฯฯฮฎฯฯฮท.
-settings.transfer_notices_1=- ฮฮฑ ฯฮฌฯฮตฯฮต ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮฑฮฝ ฯฮฟ ฮผฮตฯฮฑฮฒฮนฮฒฮฌฯฮตฯฮต ฯฮต ฮญฮฝฮฑฮฝ ฮผฮตฮผฮฟฮฝฯฮผฮญฮฝฮฟ ฯฯฮฎฯฯฮท.
-settings.transfer_notices_2=- ฮฮฑ ฮดฮนฮฑฯฮทฯฮฎฯฮตฯฮต ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮฑฮฝ ฯฮฟ ฮผฮตฯฮฑฮฒฮนฮฒฮฌฯฮตฯฮต ฯฮต ฮญฮฝฮฑฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ ฯฮฟฯ
ฮตฮฏฯฯฮต (ฯฯ
ฮฝ)ฮนฮดฮนฮฟฮบฯฮฎฯฮทฯ.
-settings.transfer_notices_3=- ฮฮฌฮฝ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮตฮฏฮฝฮฑฮน ฮนฮดฮนฯฯฮนฮบฯ ฮบฮฑฮน ฮผฮตฯฮฑฮฒฮนฮฒฮฌฮถฮตฯฮฑฮน ฯฮต ฮผฮตฮผฮฟฮฝฯฮผฮญฮฝฮฟ ฯฯฮฎฯฯฮท, ฮฑฯ
ฯฮฎ ฮท ฮตฮฝฮญฯฮณฮตฮนฮฑ ฮตฮพฮฑฯฯฮฑฮปฮฏฮถฮตฮน ฯฯฮน ฮฟ ฯฯฮฎฯฯฮทฯ ฮญฯฮตฮน ฯฮฟฯ
ฮปฮฌฯฮนฯฯฮฟฮฝ ฮฌฮดฮตฮนฮฑ ฮฑฮฝฮฌฮณฮฝฯฯฮทฯ (ฮบฮฑฮน ฮฑฮปฮปฮฌฮถฮตฮน ฯฮฑ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮตฮฌฮฝ ฮตฮฏฮฝฮฑฮน ฮฑฯฮฑฯฮฑฮฏฯฮทฯฮฟ).
+settings.transfer_in_progress=ฮฯ
ฯฮฎ ฯฮท ฯฯฮนฮณฮผฮฎ ฯ
ฯฮฌฯฯฮตฮน ฮผฮนฮฑ ฮตฮฝ ฮตฮพฮตฮปฮฏฮพฮตฮน ฮผฮตฯฮฑฮฒฮฏฮฒฮฑฯฮท. ฮ ฮฑฯฮฑฮบฮฑฮปฮฟฯฮผฮต ฮฑฮบฯ
ฯฯฯฯฮต ฯฮทฮฝ ฮฑฮฝ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฮผฮตฯฮฑฮฒฮนฮฒฮฌฯฮตฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository ฯฮต ฮฌฮปฮปฮฟ ฯฯฮฎฯฯฮท.
+settings.transfer_notices_1=- ฮฮฑ ฯฮฌฯฮตฯฮต ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ repository ฮฑฮฝ ฯฮฟ ฮผฮตฯฮฑฮฒฮนฮฒฮฌฯฮตฯฮต ฯฮต ฮญฮฝฮฑฮฝ ฮผฮตฮผฮฟฮฝฯฮผฮญฮฝฮฟ ฯฯฮฎฯฯฮท.
+settings.transfer_notices_2=- ฮฮฑ ฮดฮนฮฑฯฮทฯฮฎฯฮตฯฮต ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ repository ฮฑฮฝ ฯฮฟ ฮผฮตฯฮฑฮฒฮนฮฒฮฌฯฮตฯฮต ฯฮต ฮญฮฝฮฑฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ ฯฮฟฯ
ฮตฮฏฯฯฮต (ฯฯ
ฮฝ)ฮนฮดฮนฮฟฮบฯฮฎฯฮทฯ.
+settings.transfer_notices_3=- ฮฮฌฮฝ ฯฮฟ repository ฮตฮฏฮฝฮฑฮน ฮนฮดฮนฯฯฮนฮบฯ ฮบฮฑฮน ฮผฮตฯฮฑฮฒฮนฮฒฮฌฮถฮตฯฮฑฮน ฯฮต ฮผฮตฮผฮฟฮฝฯฮผฮญฮฝฮฟ ฯฯฮฎฯฯฮท, ฮฑฯ
ฯฮฎ ฮท ฮตฮฝฮญฯฮณฮตฮนฮฑ ฮตฮพฮฑฯฯฮฑฮปฮฏฮถฮตฮน ฯฯฮน ฮฟ ฯฯฮฎฯฯฮทฯ ฮญฯฮตฮน ฯฮฟฯ
ฮปฮฌฯฮนฯฯฮฟฮฝ ฮฌฮดฮตฮนฮฑ ฮฑฮฝฮฌฮณฮฝฯฯฮทฯ (ฮบฮฑฮน ฮฑฮปฮปฮฌฮถฮตฮน ฯฮฑ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮตฮฌฮฝ ฮตฮฏฮฝฮฑฮน ฮฑฯฮฑฯฮฑฮฏฯฮทฯฮฟ).
settings.transfer_owner=ฮฮญฮฟฯ ฮนฮดฮนฮฟฮบฯฮฎฯฮทฯ
settings.transfer_perform=ฮฮบฯฮญฮปฮตฯฮท ฮผฮตฯฮฑฯฮฟฯฮฌฯ
-settings.transfer_started=`ฮฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮญฯฮตฮน ฮตฯฮนฯฮทฮผฮฑฮฝฮธฮตฮฏ ฮณฮนฮฑ ฮผฮตฯฮฑฯฮฟฯฮฌ ฮบฮฑฮน ฮฑฮฝฮฑฮผฮญฮฝฮตฮน ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮท ฮฑฯฯ ฯฮฟ "%s"`
-settings.transfer_succeed=ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮญฯฮตฮน ฮผฮตฯฮฑฯฮตฯฮธฮตฮฏ.
+settings.transfer_started=`ฮฯ
ฯฯ ฯฮฟ repository ฮญฯฮตฮน ฮตฯฮนฯฮทฮผฮฑฮฝฮธฮตฮฏ ฮณฮนฮฑ ฮผฮตฯฮฑฯฮฟฯฮฌ ฮบฮฑฮน ฮฑฮฝฮฑฮผฮญฮฝฮตฮน ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮท ฮฑฯฯ ฯฮฟ "%s"`
+settings.transfer_succeed=ฮคฮฟ repository ฮญฯฮตฮน ฮผฮตฯฮฑฯฮตฯฮธฮตฮฏ.
settings.signing_settings=ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮตฯฮฑฮปฮฎฮธฮตฯ
ฯฮทฯ ฯ
ฯฮฟฮณฯฮฑฯฯฮฝ
settings.trust_model=ฮฮฟฮฝฯฮญฮปฮฟ ฮตฮผฯฮนฯฯฮฟฯฯฮฝฮทฯ ฯ
ฯฮฟฮณฯฮฑฯฯฮฝ
settings.trust_model.default=ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮผฮฟฮฝฯฮญฮปฮฟ ฮตฮผฯฮนฯฯฮฟฯฯฮฝฮทฯ
@@ -2182,33 +2260,33 @@ settings.wiki_deletion_success=ฮคฮฑ ฮดฮตฮดฮฟฮผฮญฮฝฮฑ wiki ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮท
settings.delete=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฑฯ
ฯฯฯ
ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
settings.delete_desc=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮตฮฝฯฯ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮตฮฏฮฝฮฑฮน ฮผฯฮฝฮนฮผฮท ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
settings.delete_notices_1=- ฮฯ
ฯฮฎ ฮท ฮตฮฝฮญฯฮณฮตฮนฮฑ ฮฮฮ ฮฮ ฮฮกฮฮ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ.
-settings.delete_notices_2=- ฮฯ
ฯฮฎ ฮท ฮตฮฝฮญฯฮณฮตฮนฮฑ ฮธฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฮน ฮผฯฮฝฮนฮผฮฑ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ %s ฮผฮฑฮถฮฏ ฮผฮต ฯฮฟฮฝ ฮบฯฮดฮนฮบฮฑ, ฯฮฑ ฮถฮทฯฮทฮผฮฌฯฮฑ, ฯฮฑ ฯฯฯฮปฮนฮฑ, ฯฮฑ ฮดฮตฮดฮฟฮผฮญฮฝฮฑ ฯฯฮฝ wiki ฮบฮฑฮน ฯฮนฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฯ
ฮฝฮตฯฮณฮฑฯฯฮฝ ฯฮฟฯ
ฮฒฯฮฏฯฮบฮฟฮฝฯฮฑฮน ฮผฮญฯฮฑ ฯฮต ฮฑฯ
ฯฯ.
+settings.delete_notices_2=- ฮฯ
ฯฮฎ ฮท ฮตฮฝฮญฯฮณฮตฮนฮฑ ฮธฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฮน ฮผฯฮฝฮนฮผฮฑ ฯฮฟ repository %s ฮผฮฑฮถฮฏ ฮผฮต ฯฮฟฮฝ ฮบฯฮดฮนฮบฮฑ, ฯฮฑ ฮถฮทฯฮทฮผฮฌฯฮฑ, ฯฮฑ ฯฯฯฮปฮนฮฑ, ฯฮฑ ฮดฮตฮดฮฟฮผฮญฮฝฮฑ ฯฯฮฝ wiki ฮบฮฑฮน ฯฮนฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฯ
ฮฝฮตฯฮณฮฑฯฯฮฝ ฯฮฟฯ
ฮฒฯฮฏฯฮบฮฟฮฝฯฮฑฮน ฮผฮญฯฮฑ ฯฮต ฮฑฯ
ฯฯ.
settings.delete_notices_fork_1=- ฮคฮฑ Forks ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮธฮฑ ฮณฮฏฮฝฮฟฯ
ฮฝ ฮฑฮฝฮตฮพฮฌฯฯฮทฯฮฑ ฮผฮตฯฮฌ ฯฮท ฮดฮนฮฑฮณฯฮฑฯฮฎ.
-settings.deletion_success=ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
+settings.deletion_success=ฮคฮฟ repository ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
settings.update_settings_success=ฮฮน ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮญฯฮฟฯ
ฮฝ ฮตฮฝฮทฮผฮตฯฯฮธฮตฮฏ.
-settings.update_settings_no_unit=ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮธฮฑ ฯฯฮญฯฮตฮน ฮฝฮฑ ฮตฯฮนฯฯฮญฯฮตฮน ฯฮฟฯ
ฮปฮฌฯฮนฯฯฮฟฮฝ ฮบฮฌฯฮฟฮนฮฟ ฮตฮฏฮดฮฟฯ ฮฑฮปฮปฮทฮปฮตฯฮฏฮดฯฮฑฯฮทฯ.
+settings.update_settings_no_unit=ฮคฮฟ repository ฮธฮฑ ฯฯฮญฯฮตฮน ฮฝฮฑ ฮตฯฮนฯฯฮญฯฮตฮน ฯฮฟฯ
ฮปฮฌฯฮนฯฯฮฟฮฝ ฮบฮฌฯฮฟฮนฮฟ ฮตฮฏฮดฮฟฯ ฮฑฮปฮปฮทฮปฮตฯฮฏฮดฯฮฑฯฮทฯ.
settings.confirm_delete=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
settings.add_collaborator=ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฯ
ฮฝฮตฯฮณฮฌฯฮท
settings.add_collaborator_success=ฮ ฯฯ
ฮฝฮตฯฮณฮฌฯฮทฯ ฯฯฮฟฯฯฮญฮธฮทฮบฮต.
settings.add_collaborator_inactive_user=ฮฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฯฯฮฟฯฮธฮฎฮบฮท ฮตฮฝฯฯ ฮฑฮฝฮตฮฝฮตฯฮณฮฟฯ ฯฯฮฎฯฯฮท ฯฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮท.
settings.add_collaborator_owner=ฮฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฯฯฮฟฯฮธฮฎฮบฮท ฮตฮฝฯฯ ฮนฮดฮนฮฟฮบฯฮฎฯฮท ฯฮฑฮฝ ฯฯ
ฮฝฮตฯฮณฮฌฯฮท.
-settings.add_collaborator_duplicate=ฮ ฯฯ
ฮฝฮตฯฮณฮฌฯฮทฯ ฮญฯฮตฮน ฮฎฮดฮท ฯฯฮฟฯฯฮตฮธฮตฮฏ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+settings.add_collaborator_duplicate=ฮ ฯฯ
ฮฝฮตฯฮณฮฌฯฮทฯ ฮญฯฮตฮน ฮฎฮดฮท ฯฯฮฟฯฯฮตฮธฮตฮฏ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
settings.delete_collaborator=ฮฮฑฯฮฌฯฮณฮทฯฮท
settings.collaborator_deletion=ฮฮฑฯฮฌฯฮณฮทฯฮท ฯฯ
ฮฝฮตฯฮณฮฌฯฮท
-settings.collaborator_deletion_desc=ฮ ฮบฮฑฯฮฌฯฮณฮทฯฮท ฮตฮฝฯฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮท ฮธฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฮน ฮบฮฑฮน ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮฎ ฯฮฟฯ
ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮฮฏฯฯฮต ฮฒฮญฮฒฮฑฮนฮฟฮน;
+settings.collaborator_deletion_desc=ฮ ฮบฮฑฯฮฌฯฮณฮทฯฮท ฮตฮฝฯฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮท ฮธฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฮน ฮบฮฑฮน ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮฎ ฯฮฟฯ
ฯฯฮฟ repository. ฮฮฏฯฯฮต ฮฒฮญฮฒฮฑฮนฮฟฮน;
settings.remove_collaborator_success=ฮ ฯฯ
ฮฝฮตฯฮณฮฌฯฮทฯ ฮญฯฮตฮน ฮบฮฑฯฮฑฯฮณฮทฮธฮตฮฏ.
settings.search_user_placeholder=ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฯฯฮฎฯฯฮทโฆ
settings.org_not_allowed_to_be_collaborator=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฯฮธฮญฯฮตฯฮต ฮญฮฝฮฑฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ ฯฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮท.
-settings.change_team_access_not_allowed=ฮ ฮฑฮปฮปฮฑฮณฮฎ ฯฮทฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ ฮณฮนฮฑ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮญฯฮตฮน ฯฮตฯฮนฮฟฯฮนฯฯฮตฮฏ ฯฯฮฟฮฝ ฮนฮดฮนฮฟฮบฯฮฎฯฮท ฯฮฟฯ
ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ
-settings.team_not_in_organization=ฮ ฮฟฮผฮฌฮดฮฑ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฯฯฮฟฮฝ ฮฏฮดฮนฮฟ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ ฮผฮต ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+settings.change_team_access_not_allowed=ฮ ฮฑฮปฮปฮฑฮณฮฎ ฯฮทฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ ฮณฮนฮฑ ฯฮฟ repository ฮญฯฮตฮน ฯฮตฯฮนฮฟฯฮนฯฯฮตฮฏ ฯฯฮฟฮฝ ฮนฮดฮนฮฟฮบฯฮฎฯฮท ฯฮฟฯ
ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ
+settings.team_not_in_organization=ฮ ฮฟฮผฮฌฮดฮฑ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฯฯฮฟฮฝ ฮฏฮดฮนฮฟ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ ฮผฮต ฯฮฟ repository
settings.teams=ฮฮผฮฌฮดฮตฯ
settings.add_team=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮฟฮผฮฌฮดฮฑฯ
-settings.add_team_duplicate=ฮ ฮฟฮผฮฌฮดฮฑ ฮญฯฮตฮน ฮฎฮดฮท ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
-settings.add_team_success=ฮ ฮฟฮผฮฌฮดฮฑ ฮญฯฮตฮน ฯฮปฮญฮฟฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+settings.add_team_duplicate=ฮ ฮฟฮผฮฌฮดฮฑ ฮญฯฮตฮน ฮฎฮดฮท ฯฮฟ repository
+settings.add_team_success=ฮ ฮฟฮผฮฌฮดฮฑ ฮญฯฮตฮน ฯฮปฮญฮฟฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ repository.
settings.search_team=ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮฮผฮฌฮดฮฑฯโฆ
-settings.change_team_permission_tip=ฮคฮฑ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ ฮญฯฮฟฯ
ฮฝ ฮฟฯฮนฯฯฮตฮฏ ฯฯฮท ฯฮตฮปฮฏฮดฮฑ ฯฯ
ฮธฮผฮฏฯฮตฯฮฝ ฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮฟฯ
ฮฝ ฮฑฮฝฮฌ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+settings.change_team_permission_tip=ฮคฮฑ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ ฮญฯฮฟฯ
ฮฝ ฮฟฯฮนฯฯฮตฮฏ ฯฯฮท ฯฮตฮปฮฏฮดฮฑ ฯฯ
ฮธฮผฮฏฯฮตฯฮฝ ฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮฟฯ
ฮฝ ฮฑฮฝฮฌ repository
settings.delete_team_tip=ฮฯ
ฯฮฎ ฮท ฮฟฮผฮฌฮดฮฑ ฮญฯฮตฮน ฯฯฯฯฮฒฮฑฯฮท ฯฮต ฯฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฯฮฑฮนฯฮตฮธฮตฮฏ
-settings.remove_team_success=ฮฯฮตฮน ฮฑฯฮฑฮนฯฮตฮธฮตฮฏ ฮท ฯฯฯฯฮฒฮฑฯฮท ฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+settings.remove_team_success=ฮฯฮตฮน ฮฑฯฮฑฮนฯฮตฮธฮตฮฏ ฮท ฯฯฯฯฮฒฮฑฯฮท ฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ ฯฯฮฟ repository.
settings.add_webhook=ฮ ฯฮฟฯฮธฮฎฮบฮท webhook
settings.add_webhook.invalid_channel_name=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฮฟฯ
ฮบฮฑฮฝฮฑฮปฮนฮฟฯ Webhook ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯ ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฮตฯฮนฮญฯฮตฮน ฮผฯฮฝฮฟ ฮญฮฝฮฑฮฝ ฯฮฑฯฮฑฮบฯฮฎฯฮฑ #.
settings.hooks_desc=ฮคฮฑ Webhooks ฮบฮฌฮฝฮฟฯ
ฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฮฑฮนฯฮฎฯฮตฮนฯ HTTP POST ฯฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฯฮฑฮฝ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฟฯฮฝฯฮฑฮน ฮฟฯฮนฯฮผฮญฮฝฮฑ ฮณฮตฮณฮฟฮฝฯฯฮฑ ฯฯฮฟ Forgejo. ฮฮนฮฑฮฒฮฌฯฯฮต ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฯฯฮฟฮฝ ฮฟฮดฮทฮณฯ webhooks .
@@ -2251,22 +2329,22 @@ settings.event_create_desc=ฮ ฮบฮปฮฌฮดฮฟฯ ฮฎ ฮท ฮตฯฮนฮบฮญฯฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณ
settings.event_delete=ฮฮนฮฑฮณฯฮฑฯฮฎ
settings.event_delete_desc=ฮ ฮบฮปฮฌฮดฮฟฯ ฮฎ ฮท ฮตฯฮนฮบฮญฯฮฑ ฮดฮนฮฑฮณฯฮฌฯฮทฮบฮต.
settings.event_fork=Fork
-settings.event_fork_desc=ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮญฮณฮนฮฝฮต fork.
+settings.event_fork_desc=ฮคฮฟ repository ฮญฮณฮนฮฝฮต fork.
settings.event_wiki=Wiki
settings.event_wiki_desc=ฮ ฯฮตฮปฮฏฮดฮฑ Wiki ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต, ฮผฮตฯฮฟฮฝฮฟฮผฮฌฯฯฮทฮบฮต, ฮตฯฮตฮพฮตฯฮณฮฌฯฯฮทฮบฮต ฮฎ ฮดฮนฮฑฮณฯฮฌฯฮทฮบฮต.
settings.event_release=ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ
settings.event_release_desc=ฮ ฮญฮบฮดฮฟฯฮท ฮดฮทฮผฮฟฯฮนฮตฯฯฮทฮบฮต, ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮต ฮฎ ฮดฮนฮฑฮณฯฮฌฯฮทฮบฮต ฮฑฯฯ ฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
settings.event_push=Push
-settings.event_push_desc=Git push ฯฮต ฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
-settings.event_repository=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ
-settings.event_repository_desc=ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฮฎ ฮดฮนฮฑฮณฯฮฌฯฮทฮบฮต.
+settings.event_push_desc=Git push ฯฮต ฮญฮฝฮฑ repository.
+settings.event_repository=Repository
+settings.event_repository_desc=ฮคฮฟ repository ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฮฎ ฮดฮนฮฑฮณฯฮฌฯฮทฮบฮต.
settings.event_header_issue=ฮฃฯ
ฮผฮฒฮฌฮฝฯฮฑ ฮถฮทฯฮทฮผฮฌฯฯฮฝ
settings.event_issues=ฮฮทฯฮฎฮผฮฑฯฮฑ
settings.event_issues_desc=ฮคฮฟ ฮถฮฎฯฮทฮผฮฑ ฮฌฮฝฮฟฮนฮพฮต, ฮญฮบฮปฮตฮนฯฮต, ฮฑฮฝฮฟฮฏฯฮธฮทฮบฮต ฮตฮบ ฮฝฮญฮฟฯ
ฮฎ ฮตฯฮตฮพฮตฯฮณฮฌฯฯฮทฮบฮต.
settings.event_issue_assign=ฮฮฝฮฌฮธฮตฯฮท ฮถฮทฯฮฎฮผฮฑฯฮฟฯ
settings.event_issue_assign_desc=ฮฮฎฯฮทฮผฮฑ ฮตฮบฯฯฯฮทฮผฮญฮฝฮฟ ฮฎ ฮผฮท ฮตฮบฯฯฯฮทฮผฮญฮฝฮฟ.
-settings.event_issue_label=ฮฃฮฎฮผฮฑฮฝฯฮท ฮถฮทฯฮฎฮผฮฑฯฮฟฯ
-settings.event_issue_label_desc=ฮคฮฑ ฯฮฎฮผฮฑฯฮฑ ฯฯฮฝ ฮถฮทฯฮทฮผฮฌฯฯฮฝ ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮฑฮฝ ฮฎ ฮตฮบฮบฮฑฮธฮฑฯฮฏฯฯฮทฮบฮฑฮฝ.
+settings.event_issue_label=ฮคฮฟฯฮฟฮธฮตฯฮฎฮธฮทฮบฮต ฯฮฑฮผฯฮญฮปฮฑ ฯฯฮฟ ฮถฮทฯฮฎฮผฮฑ
+settings.event_issue_label_desc=ฮฮน ฯฮฑฮผฯฮญฮปฮตฯ ฯฯฮฝ ฮถฮทฯฮทฮผฮฌฯฯฮฝ ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮฑฮฝ ฮฎ ฮตฮบฮบฮฑฮธฮฑฯฮฏฯฯฮทฮบฮฑฮฝ.
settings.event_issue_milestone=ฮฯฮนฯฮผฯฯ ฮฟฯฯฯฮทฮผฮฟฯ
ฯฮต ฮถฮฎฯฮทฮผฮฑ
settings.event_issue_milestone_desc=ฮฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฮธฮทฮบฮต ฮฎ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฮธฮทฮบฮต ฮฟฯฯฯฮทฮผฮฟ ฯฯฮฟ ฮถฮฎฯฮทฮผฮฑ.
settings.event_issue_comment=ฮฃฯฮฟฮปฮนฮฑฯฮผฯฯ ฮบฮฌฯฮฟฮนฮฟฯ
ฮถฮทฯฮฎฮผฮฑฯฮฟฯ
@@ -2276,8 +2354,8 @@ settings.event_pull_request=Pull request
settings.event_pull_request_desc=ฮคฮฟ pull request ฮฌฮฝฮฟฮนฮพฮต, ฮญฮบฮปฮตฮนฯฮต, ฮฌฮฝฮฟฮนฮพฮต ฮตฮบ ฮฝฮญฮฟฯ
ฮฎ ฮตฯฮตฮพฮตฯฮณฮฌฯฯฮทฮบฮต.
settings.event_pull_request_assign=ฮฮฝฮฌฮธฮตฯฮท pull request
settings.event_pull_request_assign_desc=ฮคฮฟ pull request ฮฑฮฝฮฑฯฮญฮธฮทฮบฮต ฮฎ ฮญฮณฮนฮฝฮต ฮฑฮดฮนฮฌฮธฮตฯฮฟ.
-settings.event_pull_request_label=ฮฃฮฎฮผฮฑฮฝฯฮท pull request
-settings.event_pull_request_label_desc=ฮคฮฑ ฯฮฎฮผฮฑฯฮฑ ฯฮฟฯ
pull request ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮฑฮฝ ฮฎ ฮตฮบฮบฮฑฮธฮฑฯฮฏฯฯฮทฮบฮฑฮฝ.
+settings.event_pull_request_label=ฮคฮฟฯฮฟฮธฮตฯฮฎฮธฮทฮบฮต ฯฮฑฮผฯฮญฮปฮฑ ฯฯฮฟ pull request
+settings.event_pull_request_label_desc=ฮฮน ฯฮฑฮผฯฮญฮปฮตฯ ฯฮฟฯ
pull request ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮฑฮฝ ฮฎ ฮตฮบฮบฮฑฮธฮฑฯฮฏฯฯฮทฮบฮฑฮฝ.
settings.event_pull_request_milestone=ฮฯฮนฯฮผฯฯ ฮฟฯฮฟฯฮฎฮผฮฟฯ
ฯฮต pull request
settings.event_pull_request_milestone_desc=ฮฯฮฎฮบฮต ฮฎ ฮฒฮณฮฎฮบฮต ฮฟฯฯฯฮทฮผฮฟ ฯฯฮฟ Pull request.
settings.event_pull_request_comment=ฮฃฯฮฟฮปฮนฮฑฯฮผฯฯ pull request
@@ -2291,9 +2369,9 @@ settings.event_pull_request_review_request_desc=ฮฮทฯฮฎฮธฮทฮบฮต ฮท ฮฑฮพฮนฮฟฮปฯ
settings.event_pull_request_approvals=ฮฮณฮบฯฮฏฯฮตฮนฯ pull request
settings.event_pull_request_merge=ฮฃฯ
ฮณฯฯฮฝฮตฯ
ฯฮท pull request
settings.event_package=ฮ ฮฑฮบฮญฯฮฟ
-settings.event_package_desc=ฮคฮฟ ฯฮฑฮบฮญฯฮฟ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฮฎ ฮดฮนฮฑฮณฯฮฌฯฮทฮบฮต ฯฮต ฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+settings.event_package_desc=ฮคฮฟ ฯฮฑฮบฮญฯฮฟ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฮฎ ฮดฮนฮฑฮณฯฮฌฯฮทฮบฮต ฯฮต ฮญฮฝฮฑ repository.
settings.branch_filter=ฮฆฮฏฮปฯฯฮฟ ฮบฮปฮฌฮดฮฟฯ
-settings.branch_filter_desc=ฮฮฏฯฯฮฑ ฮตฯฮนฯฯฮตฯฯฮผฮตฮฝฯฮฝ ฮบฮปฮฌฮดฯฮฝ ฮณฮนฮฑ ฯฮธฮฎฯฮตฮนฯ, ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮบฮปฮฌฮดฯฮฝ ฮบฮฑฮน ฮณฮตฮณฮฟฮฝฯฯฮฑ ฮดฮนฮฑฮณฯฮฑฯฮฎฯ ฮบฮปฮฌฮดฯฮฝ, ฯฮฟฯ
ฮฟฯฮฏฮถฮฟฮฝฯฮฑฮน ฯฯ ฮผฮฟฯฮฏฮฒฮฟ glob. ฮฮฌฮฝ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯ ฮฎ *
, ฮฑฮฝฮฑฯฮญฯฮฟฮฝฯฮฑฮน ฯฯ
ฮผฮฒฮฌฮฝฯฮฑ ฮณฮนฮฑ ฯฮปฮฟฯ
ฯ ฯฮฟฯ
ฯ ฮบฮปฮฌฮดฮฟฯ
ฯ. ฮฮตฮฏฯฮต ฯฮท ฯฮตฮบฮผฮทฯฮฏฯฯฮทgithub.com/gobwas/glob ฮณฮนฮฑ ฯฯฮฝฯฮฑฮพฮท. ฮ ฮฑฯฮฑฮดฮตฮฏฮณฮผฮฑฯฮฑ: master
, {master,release*}
.
+settings.branch_filter_desc=ฮฮฏฯฯฮฑ ฮตฯฮนฯฯฮตฯฯฮผฮตฮฝฯฮฝ ฮบฮปฮฌฮดฯฮฝ ฮณฮนฮฑ ฯฮธฮฎฯฮตฮนฯ, ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮบฮปฮฌฮดฯฮฝ ฮบฮฑฮน ฮณฮตฮณฮฟฮฝฯฯฮฑ ฮดฮนฮฑฮณฯฮฑฯฮฎฯ ฮบฮปฮฌฮดฯฮฝ, ฯฮฟฯ
ฮฟฯฮฏฮถฮฟฮฝฯฮฑฮน ฯฯ ฮผฮฟฯฮฏฮฒฮฟ glob. ฮฮฌฮฝ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯ ฮฎ *
, ฮฑฮฝฮฑฯฮญฯฮฟฮฝฯฮฑฮน ฯฯ
ฮผฮฒฮฌฮฝฯฮฑ ฮณฮนฮฑ ฯฮปฮฟฯ
ฯ ฯฮฟฯ
ฯ ฮบฮปฮฌฮดฮฟฯ
ฯ. ฮฮตฮฏฯฮต ฯฮท ฯฮตฮบฮผฮทฯฮฏฯฯฮท%[2]s ฮณฮนฮฑ ฯฯฮฝฯฮฑฮพฮท. ฮ ฮฑฯฮฑฮดฮตฮฏฮณฮผฮฑฯฮฑ: master
, {master,release*}
.
settings.authorization_header=ฮฮตฯฮฑฮปฮฏฮดฮฑ authorization
settings.authorization_header_desc=ฮฮฝ ฯ
ฯฮฌฯฯฮตฮน, ฮธฮฑ ฯฯฮฟฯฯฮฏฮธฮตฯฮฑฮน ฯฯ ฮบฮตฯฮฑฮปฮฏฮดฮฑ authorization ฯฯฮนฯ ฮฑฮนฯฮฎฯฮตฮนฯ HTTP. ฮ ฮฑฯฮฑฮดฮตฮฏฮณฮผฮฑฯฮฑ: %s.
settings.active=ฮฮฝฮตฯฮณฯ
@@ -2307,7 +2385,7 @@ settings.hook_type=ฮฮฏฮดฮฟฯ hook
settings.slack_token=ฮฮนฮฑฮบฯฮนฯฮนฮบฯ
settings.slack_domain=Domain
settings.slack_channel=ฮฮฑฮฝฮฌฮปฮน
-settings.add_web_hook_desc=ฮฮฝฯฯฮผฮฌฯฯฯฮต ฯฮฟ %s ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฯฮฑฯ.
+settings.add_web_hook_desc=ฮฮฝฯฯฮผฮฌฯฯฯฮต ฯฮฟ %s ฯฯฮฟ repository ฯฮฑฯ.
settings.web_hook_name_gitea=Gitea
settings.web_hook_name_forgejo = Forgejo
settings.web_hook_name_gogs=Gogs
@@ -2327,9 +2405,9 @@ settings.packagist_api_token=ฮฮนฮฑฮบฯฮนฯฮนฮบฯ API
settings.packagist_package_url=URL ฯฮฑฮบฮญฯฯฮฝ Packagist
settings.deploy_keys=ฮฮปฮตฮนฮดฮนฮฌ ฮดฮนฮฌฮธฮตฯฮทฯ
settings.add_deploy_key=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮบฮปฮตฮนฮดฮนฮฟฯ ฮดฮนฮฌฮธฮตฯฮทฯ
-settings.deploy_key_desc=ฮคฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮดฮนฮฌฮธฮตฯฮทฯ ฮญฯฮฟฯ
ฮฝ ฯฯฯฯฮฒฮฑฯฮท ฮผฯฮฝฮฟ-ฮฑฮฝฮฌฮณฮฝฯฯฮทฯ ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+settings.deploy_key_desc=ฮคฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮดฮนฮฌฮธฮตฯฮทฯ ฮญฯฮฟฯ
ฮฝ ฯฯฯฯฮฒฮฑฯฮท ฮผฯฮฝฮฟ-ฮฑฮฝฮฌฮณฮฝฯฯฮทฯ ฯฯฮฟ repository.
settings.is_writable=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฯฯฯฮฒฮฑฯฮทฯ ฮตฮณฮณฯฮฑฯฮฎฯ
-settings.is_writable_info=ฮฯฮนฯฯฮญฯฯฮต ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ ฮดฮนฮฌฮธฮตฯฮทฯ ฮฝฮฑ ฯฮธฮฎฯฮตฮน ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+settings.is_writable_info=ฮฯฮนฯฯฮญฯฯฮต ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮบฮปฮตฮนฮดฮฏ ฮดฮนฮฌฮธฮตฯฮทฯ ฮฝฮฑ ฯฮธฮฎฯฮตฮน ฯฯฮฟ repository.
settings.no_deploy_keys=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฑฮบฯฮผฮฑ ฮบฮปฮตฮนฮดฮนฮฌ ฮดฮนฮฌฮธฮตฯฮทฯ.
settings.title=ฮคฮฏฯฮปฮฟฯ
settings.deploy_key_content=ฮ ฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ
@@ -2337,7 +2415,7 @@ settings.key_been_used=ฮฮฝฮฑ ฮบฮปฮตฮนฮดฮฏ ฮดฮนฮฌฮธฮตฯฮทฯ ฮผฮต ฯฮฟ ฮฏฮดฮนฮฟ
settings.key_name_used=ฮฮฝฮฑ ฮบฮปฮตฮนฮดฮฏ ฮดฮนฮฌฮธฮตฯฮทฯ ฮผฮต ฯฮฟ ฮฏฮดฮนฮฟ ฯฮฝฮฟฮผฮฑ ฯ
ฯฮฌฯฯฮตฮน ฮฎฮดฮท.
settings.add_key_success=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ ฮดฮนฮฌฮธฮตฯฮทฯ ยซ%sยป ฯฯฮฟฯฯฮญฮธฮทฮบฮต.
settings.deploy_key_deletion=ฮฯฮฑฮฏฯฮตฯฮท ฮบฮปฮตฮนฮดฮนฮฟฯ ฮดฮนฮฌฮธฮตฯฮทฯ
-settings.deploy_key_deletion_desc=ฮ ฮบฮฑฯฮฌฯฮณฮทฯฮท ฮตฮฝฯฯ ฮบฮปฮตฮนฮดฮฏ ฮดฮนฮฌฮธฮตฯฮทฯ ฮธฮฑ ฮฑฮฝฮฑฮบฮฑฮปฮญฯฮตฮน ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮฎ ฯฮฟฯ
ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
+settings.deploy_key_deletion_desc=ฮ ฮบฮฑฯฮฌฯฮณฮทฯฮท ฮตฮฝฯฯ ฮบฮปฮตฮนฮดฮฏ ฮดฮนฮฌฮธฮตฯฮทฯ ฮธฮฑ ฮฑฮฝฮฑฮบฮฑฮปฮญฯฮตฮน ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮฎ ฯฮฟฯ
ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
settings.deploy_key_deletion_success=ฮคฮฟ ฮบฮปฮตฮนฮดฮฏ ฮดฮนฮฌฮธฮตฯฮทฯ ฮญฯฮตฮน ฮฑฯฮฑฮนฯฮตฮธฮตฮฏ.
settings.branches=ฮฮปฮฌฮดฮฟฮน
settings.protected_branch=ฮ ฯฮฟฯฯฮฑฯฮฏฮฑ ฮบฮปฮฌฮดฮฟฯ
@@ -2346,7 +2424,7 @@ settings.protected_branch.delete_rule=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮบฮฑฮฝฯฮฝฮฑ
settings.protected_branch_can_push=ฮฯฮนฯฯฮญฯฯฮต ฯฮธฮทฯฮท;
settings.protected_branch_can_push_yes=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฮธฮฎฯฮตฯฮต
settings.protected_branch_can_push_no=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฮธฮฎฯฮตฯฮต
-settings.branch_protection=ฮฮฑฮฝฯฮฝฮตฯ ฯฯฮฟฯฯฮฑฯฮฏฮฑฯ ฮณฮนฮฑ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ยซ%s ยป
+settings.branch_protection=ฮฮฑฮฝฯฮฝฮตฯ ฯฯฮฟฯฯฮฑฯฮฏฮฑฯ ฯฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
ยซ%s ยป
settings.protect_this_branch=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฟฯฯฮฑฯฮฏฮฑฯ ฮบฮปฮฌฮดฮฟฯ
settings.protect_this_branch_desc=ฮฯฮฟฯฯฮญฯฮตฮน ฯฮท ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮบฮฑฮน ฯฮตฯฮนฮฟฯฮฏฮถฮตฮน ฯฮฟ Git push ฮบฮฑฮน ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ.
settings.protect_disable_push=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฮธฮฎฯฮตฯฮฝ
@@ -2370,7 +2448,7 @@ settings.protect_check_status_contexts=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮตฮปฮญฮณฯฮฟฯ
settings.protect_status_check_patterns=ฮฮฟฯฮฏฮฒฮฑ ฮตฮปฮญฮณฯฮฟฯ
ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ:
settings.protect_status_check_patterns_desc=ฮฯฮฏฯฯฮต ฮผฮฟฯฮฏฮฒฮฑ ฮณฮนฮฑ ฮฝฮฑ ฮบฮฑฮธฮฟฯฮฏฯฮตฯฮต ฯฮฟฮนฮฟฮน ฮญฮปฮตฮณฯฮฟฮน ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯฮตฯฮฌฯฮฟฯ
ฮฝ ฯฯฮนฮฝ ฮฟฮน ฮบฮปฮฌฮดฮฟฮน ฮฝฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮฟฯฮฝ ฯฮต ฮญฮฝฮฑฮฝ ฮบฮปฮฌฮดฮฟ ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮตฮน ฮผฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮฑฮฝฯฮฝฮฑ. ฮฮฌฮธฮต ฮณฯฮฑฮผฮผฮฎ ฮบฮฑฮธฮฟฯฮฏฮถฮตฮน ฮญฮฝฮฑ ฮผฮฟฯฮฏฮฒฮฟ. ฮคฮฑ ฮผฮฟฯฮฏฮฒฮฑ ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฮฌ.
settings.protect_check_status_contexts_desc=ฮฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮญฮปฮตฮณฯฮฟฯ ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ ฮณฮนฮฑ ฮฝฮฑ ฯฮตฯฮฌฯฮตฮน ฯฮฟ pull request ฯฯฮนฮฝ ฮฑฯฯ ฯฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท. ฮฯฮนฮปฮญฮพฯฮต ฯฮฟฮนฮฟฮน ฮญฮปฮตฮณฯฮฟฮน ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯฮตฯฮฌฯฮฟฯ
ฮฝ ฯฯฮนฮฝ ฮบฮปฮฌฮดฮฟฮน ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮฟฯฮฝ ฯฮต ฮญฮฝฮฑฮฝ ฮบฮปฮฌฮดฮฟ ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮตฮน ฮผฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮฑฮฝฯฮฝฮฑ. ฮฯฮฑฮฝ ฮตฮฏฮฝฮฑฮน ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮฟ, ฮฟฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฯฯฮญฯฮตฮน ฯฯฯฯฮฑ ฮฝฮฑ ฮณฮฏฮฝฮฟฮฝฯฮฑฮน push ฯฮต ฮฌฮปฮปฮฟ ฮบฮปฮฌฮดฮฟ, ฯฯฮท ฯฯ
ฮฝฮญฯฮตฮนฮฑ, ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯฮฟฮฝฯฮฑฮน ฮฎ ฮณฮฏฮฝฮฟฮฝฯฮฑฮน push ฮฑฯฮตฯ
ฮธฮตฮฏฮฑฯ ฯฮต ฮญฮฝฮฑ ฮบฮปฮฌฮดฮฟ ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮตฮน ฮผฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮฑฮฝฯฮฝฮฑ, ฮฑฯฮฟฯ ฮญฯฮฟฯ
ฮฝ ฮฟฮปฮฟฮบฮปฮทฯฯฮธฮตฮฏ ฮฟฮน ฮญฮปฮตฮณฯฮฟฮน ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ. ฮฮฝ ฮดฮตฮฝ ฮตฯฮนฮปฮตฯฮธฮตฮฏ ฮบฮฑฮฝฮญฮฝฮฑ ฯฮปฮฑฮฏฯฮนฮฟ, ฮท ฯฮตฮปฮตฯ
ฯฮฑฮฏฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฯฯฮญฯฮตฮน ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฮตฯฮนฯฯ
ฯฮฎฯ ฮฑฮฝฮตฮพฮฌฯฯฮทฯฮฑ ฮฑฯฯ ฯฮฟ ฯฮปฮฑฮฏฯฮนฮฟ.
-settings.protect_check_status_contexts_list=ฮฮปฮตฮณฯฮฟฮน ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ ฯฮฟฯ
ฮฒฯฮญฮธฮทฮบฮฑฮฝ ฯฮทฮฝ ฯฮตฮปฮตฯ
ฯฮฑฮฏฮฑ ฮตฮฒฮดฮฟฮผฮฌฮดฮฑ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+settings.protect_check_status_contexts_list=ฮฮปฮตฮณฯฮฟฮน ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ ฯฮฟฯ
ฮฒฯฮญฮธฮทฮบฮฑฮฝ ฯฮทฮฝ ฯฮตฮปฮตฯ
ฯฮฑฮฏฮฑ ฮตฮฒฮดฮฟฮผฮฌฮดฮฑ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ repository
settings.protect_status_check_matched=ฮคฮฑฮนฯฮนฮฌฮถฮตฮน
settings.protect_invalid_status_check_pattern=ฮฮท ฮญฮณฮบฯ
ฯฮฟ ฮผฮฟฯฮฏฮฒฮฟ ฮตฮปฮญฮณฯฮฟฯ
ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ: "%s".
settings.protect_no_valid_status_check_patterns=ฮฮท ฮญฮณฮบฯ
ฯฮฑ ฮผฮฟฯฮฏฮฒฮฑ ฮตฮปฮญฮณฯฮฟฯ
ฮบฮฑฯฮฌฯฯฮฑฯฮทฯ.
@@ -2381,16 +2459,16 @@ settings.protect_approvals_whitelist_enabled_desc=ฮฯฮฝฮฟ ฮบฯฮนฯฮนฮบฮญฯ ฮฑฯ
settings.protect_approvals_whitelist_users=ฮฮณฮบฮตฮบฯฮนฮผฮญฮฝฮฟฮน ฮตฮพฮตฯฮฑฯฯฮญฯ:
settings.protect_approvals_whitelist_teams=ฮฮฏฯฯฮฑ ฮตฯฮนฯฯฮตฯฯฮผฮตฮฝฯฮฝ ฮฟฮผฮฌฮดฯฮฝ ฮณฮนฮฑ ฮบฯฮนฯฮนฮบฮญฯ:
settings.dismiss_stale_approvals=ฮ ฮฑฯฮฌฮฒฮปฮตฯฮท ฮบฮฑฮธฯ
ฯฯฮตฯฮทฮผฮญฮฝฯฮฝ ฮตฮณฮบฯฮฏฯฮตฯฮฝ
-settings.dismiss_stale_approvals_desc=ฮฯฮฑฮฝ ฮฟฮน ฮฝฮญฮตฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฯฮฟฯ
ฮฑฮปฮปฮฌฮถฮฟฯ
ฮฝ ฯฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฯฮฟฯ
pull request ฮณฮฏฮฝฮฟฮฝฯฮฑฮน push ฯฯฮฟ ฮบฮปฮฌฮดฮฟ, ฮฟฮน ฯฮฑฮปฮนฮญฯ ฮตฮณฮบฯฮฏฯฮตฮนฯ ฮฑฯฮฟฯฯฮฏฯฯฮฟฮฝฯฮฑฮน.
-settings.require_signed_commits=ฮฮฑ ฮฑฯฮฑฮนฯฮฟฯฮฝฯฮฑฮน ฯ
ฯฮฟฮณฮตฮณฯฮฑฮผฮผฮญฮฝฮตฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ
-settings.require_signed_commits_desc=ฮฯฯฯฯฮนฯฮท ฮฝฮญฯฮฝ ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ ฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ฮตฮฌฮฝ ฮตฮฏฮฝฮฑฮน ฮผฮท ฯ
ฯฮฟฮณฮตฮณฯฮฑฮผฮผฮญฮฝฮตฯ ฮฎ ฮผฮท ฮตฯฮฑฮปฮทฮธฮตฯฯฮนฮผฮตฯ.
+settings.dismiss_stale_approvals_desc=ฮฯฮฑฮฝ ฮฝฮญฮฑ commit ฯฮฟฯ
ฮฑฮปฮปฮฌฮถฮฟฯ
ฮฝ ฯฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฯฮฟฯ
pull request ฮณฮฏฮฝฮฟฮฝฯฮฑฮน push ฯฯฮฟ ฮบฮปฮฌฮดฮฟ, ฮฟฮน ฯฮฑฮปฮนฮญฯ ฮตฮณฮบฯฮฏฯฮตฮนฯ ฮฑฯฮฟฯฯฮฏฯฯฮฟฮฝฯฮฑฮน.
+settings.require_signed_commits=ฮฮฑ ฮฑฯฮฑฮนฯฮฟฯฮฝฯฮฑฮน ฯ
ฯฮฟฮณฮตฮณฯฮฑฮผฮผฮญฮฝฮฑ commit
+settings.require_signed_commits_desc=ฮฯฯฯฯฮนฯฮท ฮฝฮญฯฮฝ commit ฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ฮตฮฌฮฝ ฮตฮฏฮฝฮฑฮน ฮผฮท ฯ
ฯฮฟฮณฮตฮณฯฮฑฮผฮผฮญฮฝฮตฯ ฮฎ ฮผฮท ฮตฯฮฑฮปฮทฮธฮตฯฯฮนฮผฮตฯ.
settings.protect_branch_name_pattern=ฮฮฟฯฮฏฮฒฮฟ ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฮฟฯ
ฮฟฮฝฯฮผฮฑฯฮฟฯ ฮบฮปฮฌฮดฮฟฯ
-settings.protect_branch_name_pattern_desc=ฮฮฟฯฮฏฮฒฮฑ ฮฟฮฝฯฮผฮฑฯฮฟฯ ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฯฮฝ ฮบฮปฮฌฮดฯฮฝ. ฮฃฯ
ฮผฮฒฮฟฮปฮตฯ
ฯฮตฮฏฯฮต ฯฮทฮฝ ฯฮตฮบฮผฮทฯฮฏฯฯฮท ฮณฮนฮฑ ฯฮทฮฝ ฯฯฮฝฯฮฑฮพฮท ฮตฮฝฯฯ ฮผฮฟฯฮฏฮฒฮฟฯ
. ฮ ฮฑฯฮฑฮดฮตฮฏฮณฮผฮฑฯฮฑ: main, release/**
+settings.protect_branch_name_pattern_desc=ฮฮฟฯฮฏฮฒฮฑ ฮฟฮฝฯฮผฮฑฯฮฟฯ ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฯฮฝ ฮบฮปฮฌฮดฯฮฝ. ฮฃฯ
ฮผฮฒฮฟฮปฮตฯ
ฯฮตฮฏฯฮต ฯฮทฮฝ ฯฮตฮบฮผฮทฯฮฏฯฯฮท ฮณฮนฮฑ ฯฮทฮฝ ฯฯฮฝฯฮฑฮพฮท ฮตฮฝฯฯ ฮผฮฟฯฮฏฮฒฮฟฯ
. ฮ ฮฑฯฮฑฮดฮตฮฏฮณฮผฮฑฯฮฑ: main, release/**
settings.protect_patterns=ฮฮฟฯฮฏฮฒฮฑ
settings.protect_protected_file_patterns=ฮฮฟฯฮฏฮฒฮฑ ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฯฮฝ ฮฑฯฯฮตฮฏฯฮฝ (ฮดฮนฮฑฯฯฯฮนฯฮผฯฯ ฮผฮต semicolon ยซ;ยป ฮบฮฑฮน ฮฮงฮ ฯฮฟ ฮตฮปฮปฮทฮฝฮนฮบฯ ฮตฯฯฯฮทฮผฮฑฯฮนฮบฯ):
-settings.protect_protected_file_patterns_desc=ฮคฮฑ ฯฯฮฟฯฯฮฑฯฮตฯ
ฯฮผฮตฮฝฮฑ ฮฑฯฯฮตฮฏฮฑ ฮดฮตฮฝ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮฟฯ
ฮฝ ฮฌฮผฮตฯฮฑ, ฮฑฮบฯฮผฮท ฮบฮฑฮน ฮฑฮฝ ฮฟ ฯฯฮฎฯฯฮทฯ ฮญฯฮตฮน ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮฝฮฑ ฯฯฮฟฯฮธฮญฯฮตฮน, ฮฝฮฑ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮตฮฏ ฮฎ ฮฝฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฮน ฮฑฯฯฮตฮฏฮฑ ฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ. ฮฯฮนฯฮปฮญฯฮฝ ฮผฮฟฯฮฏฮฒฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮนฮฑฯฯฯฮนฯฯฮฟฯฮฝ ฮผฮต ฮตฯฯฯฮทฮผฮฑฯฮนฮบฯ (';'). ฮฮตฮฏฯฮต ฯฮทฮฝ ฯฮตฮบฮผฮทฯฮฏฯฯฮท github.com/gobwas/glob ฮณฮนฮฑ ฯฮท ฯฯฮฝฯฮฑฮพฮท ฯฮฟฯ
ฮผฮฟฯฮฏฮฒฮฟฯ
. ฮ ฯ: .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns_desc=ฮคฮฑ ฯฯฮฟฯฯฮฑฯฮตฯ
ฯฮผฮตฮฝฮฑ ฮฑฯฯฮตฮฏฮฑ ฮดฮตฮฝ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮฟฯ
ฮฝ ฮฌฮผฮตฯฮฑ, ฮฑฮบฯฮผฮท ฮบฮฑฮน ฮฑฮฝ ฮฟ ฯฯฮฎฯฯฮทฯ ฮญฯฮตฮน ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮฝฮฑ ฯฯฮฟฯฮธฮญฯฮตฮน, ฮฝฮฑ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮตฮฏ ฮฎ ฮฝฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฮน ฮฑฯฯฮตฮฏฮฑ ฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ. ฮฯฮนฯฮปฮญฯฮฝ ฮผฮฟฯฮฏฮฒฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮนฮฑฯฯฯฮนฯฯฮฟฯฮฝ ฮผฮต semicolon (ยซ;ยป) (ฮฮงฮ ฮตฯฯฯฮทฮผฮฑฯฮนฮบฯ). ฮฮนฮฑ ฮฝฮฑ ฯฯ
ฮฝฯฮฌฮพฮตฯฮต ฮผฮฟฯฮฏฮฒฮฑ, ฯฯ
ฮผฮฒฮฟฯ
ฮปฮตฯ
ฯฮตฮฏฯฮฑฮน ฯฮทฮฝ ฯฮตฮบฮผฮทฯฮฏฯฯฮท %[2]s . ฮ ฮฑฯฮฌฮดฮตฮนฮณฮผฮฑ: .drone.yml
, /docs/**/*.txt
.
settings.protect_unprotected_file_patterns=ฮฮฟฯฮฏฮฒฮฑ ฮผฮท ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฯฮฝ ฮฑฯฯฮตฮฏฯฮฝ (ฮดฮนฮฑฯฯฯฮนฯฮผฮญฮฝฮฑ ฮผฮต semicolon ยซ;ยป ฮบฮฑฮน ฮฮงฮ ฯฮฟ ฮตฮปฮปฮทฮฝฮนฮบฯ ฮตฯฯฯฮทฮผฮฑฯฮนฮบฯ):
-settings.protect_unprotected_file_patterns_desc=ฮฮท ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฑ ฯฮฟฯ
ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮฟฯ
ฮฝ ฮฑฯฮตฯ
ฮธฮตฮฏฮฑฯ ฮตฮฌฮฝ ฮฟ ฯฯฮฎฯฯฮทฯ ฮญฯฮตฮน ฯฯฯฯฮฒฮฑฯฮท ฮตฮณฮณฯฮฑฯฮฎฯ, ฯฮฑฯฮฑฮบฮฌฮผฯฯฮฟฮฝฯฮฑฯ ฯฮฟฮฝ ฯฮตฯฮนฮฟฯฮนฯฮผฯ ฯฮธฮทฯฮทฯ. ฮฯฮนฯฮปฮญฯฮฝ ฮผฮฟฯฮฏฮฒฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮนฮฑฯฯฯฮนฯฯฮฟฯฮฝ ฮผฮต ฮตฯฯฯฮทฮผฮฑฯฮนฮบฯ (';'). ฮฮตฮฏฯฮต ฯฮทฮฝ ฯฮตฮบฮผฮทฯฮฏฯฯฮท github.com/gobwas/glob ฮณฮนฮฑ ฯฮท ฯฯฮฝฯฮฑฮพฮท ฯฮฟฯ
ฮผฮฟฯฮฏฮฒฮฟฯ
. ฮ ฯ: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns_desc=ฮฮท ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฑ ฯฮฟฯ
ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮฝฮฑ ฮฑฮปฮปฮฌฮพฮฟฯ
ฮฝ ฮฑฯฮตฯ
ฮธฮตฮฏฮฑฯ ฮตฮฌฮฝ ฮฟ ฯฯฮฎฯฯฮทฯ ฮญฯฮตฮน ฯฯฯฯฮฒฮฑฯฮท ฮตฮณฮณฯฮฑฯฮฎฯ, ฯฮฑฯฮฑฮบฮฌฮผฯฯฮฟฮฝฯฮฑฯ ฯฮฟฮฝ ฯฮตฯฮนฮฟฯฮนฯฮผฯ ฯฮธฮทฯฮทฯ. ฮฯฮนฯฮปฮญฯฮฝ ฮผฮฟฯฮฏฮฒฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮนฮฑฯฯฯฮนฯฯฮฟฯฮฝ ฮผฮต ฮตฯฯฯฮทฮผฮฑฯฮนฮบฯ (';'). ฮฮตฮฏฯฮต ฯฮทฮฝ ฯฮตฮบฮผฮทฯฮฏฯฯฮท %[2]s ฮณฮนฮฑ ฯฮท ฯฯฮฝฯฮฑฮพฮท ฯฮฟฯ
ฮผฮฟฯฮฏฮฒฮฟฯ
. ฮ ฯ: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฟฯฯฮฑฯฮฏฮฑฯ
settings.delete_protected_branch=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฟฯฯฮฑฯฮฏฮฑฯ
settings.update_protect_branch_success=ฮ ฯฯฮฟฯฯฮฑฯฮฏฮฑ ฮบฮปฮฌฮดฮฟฯ
ฮณฮนฮฑ ฯฮฟฮฝ ฮบฮฑฮฝฯฮฝฮฑ ยซ%sยป ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮต.
@@ -2404,7 +2482,7 @@ settings.block_on_official_review_requests=ฮฆฯฮฑฮณฮฎ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ ฯ
settings.block_on_official_review_requests_desc=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮดฮตฮฝ ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฯฯฮฑฮฝ ฮธฮฑ ฮญฯฮตฮน ฮฑฮนฯฮฎฯฮตฮนฯ ฮตฯฮฏฯฮทฮผฮทฯ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮทฯ, ฮฑฮบฯฮผฮท ฮบฮฑฮน ฮฑฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฑฯฮบฮตฯฮญฯ ฮตฮณฮบฯฮฏฯฮตฮนฯ.
settings.block_outdated_branch=ฮฆฯฮฑฮณฮฎ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ ฮฑฮฝ ฯฮฟ pull request ฮตฮฏฮฝฮฑฮน ฮพฮตฯฮตฯฮฑฯฮผฮญฮฝฮฟ
settings.block_outdated_branch_desc=ฮ ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฮดฮตฮฝ ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฯฯฮฑฮฝ ฮฟ ฮบฮปฮฌฮดฮฟฯ ฮบฮตฯฮฑฮปฮฎฯ ฮตฮฏฮฝฮฑฮน ฯฮฏฯฯ ฮฑฯฯ ฯฮฟฮฝ ฮฒฮฑฯฮนฮบฯ ฮบฮปฮฌฮดฮฟ.
-settings.default_branch_desc=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑฮฝ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮบฮปฮฌฮดฮฟ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮณฮนฮฑ pull requests ฮบฮฑฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮบฯฮดฮนฮบฮฑ:
+settings.default_branch_desc=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑฮฝ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮบฮปฮฌฮดฮฟ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮณฮนฮฑ pull requests ฮบฮฑฮน commit
settings.merge_style_desc=ฮฃฯฯ
ฮป ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ
settings.default_merge_style_desc=ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฯฯฯ
ฮป ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮทฯ
settings.choose_branch=ฮฯฮนฮปฮญฮพฯฮต ฮญฮฝฮฑฮฝ ฮบฮปฮฌฮดฮฟโฆ
@@ -2422,7 +2500,7 @@ settings.tags.protection.allowed.teams=ฮฯฮนฯฯฮตฯฯฮผฮตฮฝฮตฯ ฮฟฮผฮฌฮดฮตฯ
settings.tags.protection.allowed.noone=ฮฮฑฮผฮฏฮฑ
settings.tags.protection.create=ฮ ฯฮฟฯฯฮฑฯฮฏฮฑ ฮตฯฮนฮบฮญฯฮฑฯ
settings.tags.protection.none=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฮตฯ ฮตฯฮนฮบฮญฯฮตฯ.
-settings.tags.protection.pattern.description=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฯฮต ฮญฮฝฮฑ ฮผฯฮฝฮฟ ฯฮฝฮฟฮผฮฑ ฮฎ ฮญฮฝฮฑ ฮผฮฟฯฮฏฮฒฮฟ ฯฯฯฮฟฯ
glob ฮฎ ฮบฮฑฮฝฮฟฮฝฮนฮบฮฎ ฮญฮบฯฯฮฑฯฮท ฮณฮนฮฑ ฮฝฮฑ ฯฮฑฮนฯฮนฮฌฮพฮตฯฮต ฯฮฟฮปฮปฮฑฯฮปฮญฯ ฮตฯฮนฮบฮญฯฮตฯ. ฮฮนฮฑฮฒฮฌฯฯฮต ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฯฯฮฟฮฝ ฮฟฮดฮทฮณฯ ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฯฮฝ ฮตฯฮนฮบฮตฯฯฮฝ .
+settings.tags.protection.pattern.description=ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฯฮต ฮญฮฝฮฑ ฮผฯฮฝฮฟ ฯฮฝฮฟฮผฮฑ ฮฎ ฮญฮฝฮฑ ฮผฮฟฯฮฏฮฒฮฟ ฯฯฯฮฟฯ
glob ฮฎ ฮบฮฑฮฝฮฟฮฝฮนฮบฮฎ ฮญฮบฯฯฮฑฯฮท ฮณฮนฮฑ ฮฝฮฑ ฯฮฑฮนฯฮนฮฌฮพฮตฯฮต ฯฮฟฮปฮปฮฑฯฮปฮญฯ ฮตฯฮนฮบฮญฯฮตฯ. ฮฮนฮฑฮฒฮฌฯฯฮต ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฯฯฮฟฮฝ ฮฟฮดฮทฮณฯ ฯฯฮฟฯฯฮฑฯฮตฯ
ฮผฮญฮฝฯฮฝ ฮตฯฮนฮบฮตฯฯฮฝ .
settings.bot_token=ฮฮนฮฑฮบฯฮนฯฮนฮบฯ bot
settings.chat_id=ID ฮฃฯ
ฮฝฮฟฮผฮนฮปฮฏฮฑฯ
settings.thread_id=ID ฮฮฎฮผฮฑฯฮฟฯ
@@ -2431,23 +2509,23 @@ settings.matrix.room_id=ID ฮฯฮผฮฑฯฮฏฮฟฯ
settings.matrix.message_type=ฮฮฏฮดฮฟฯ ฮผฮทฮฝฯฮผฮฑฯฮฟฯ
settings.archive.button=ฮฯฯฮตฮนฮฟฮธฮญฯฮทฯฮท ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
settings.archive.header=ฮฯฯฮตฮนฮฟฮธฮญฯฮทฯฮท ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
-settings.archive.text=ฮ ฮฑฯฯฮตฮนฮฟฮธฮญฯฮทฯฮท ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮธฮฑ ฯฮฟ ฮฑฮปฮปฮฌฮพฮตฮน ฯฮต ฮผฯฮฝฮฟ ฮณฮนฮฑ ฮฑฮฝฮฌฮณฮฝฯฯฮท. ฮฮต ฮธฮฑ ฯฮฑฮฏฮฝฮตฯฮฑฮน ฯฯฮฟฮฝ ฮฑฯฯฮนฮบฯ ฯฮฏฮฝฮฑฮบฮฑ. ฮฮฑฮฝฮตฮฏฯ (ฮฑฮบฯฮผฮฑ ฮบฮฑฮน ฮตฯฮตฮฏฯ!) ฮดฮต ฮธฮฑ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮบฮฌฮฝฮตฮน ฮฝฮญฮตฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ, ฮฎ ฮฝฮฑ ฮฑฮฝฮฟฮฏฮพฮตฮน ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮฎ pull request.
-settings.archive.success=ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮฑฯฯฮตฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮต ฮผฮต ฮตฯฮนฯฯ
ฯฮฏฮฑ.
+settings.archive.text=ฮ ฮฑฯฯฮตฮนฮฟฮธฮญฯฮทฯฮท ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮธฮฑ ฯฮฟ ฮฑฮปฮปฮฌฮพฮตฮน ฯฮต ฮผฯฮฝฮฟ ฮณฮนฮฑ ฮฑฮฝฮฌฮณฮฝฯฯฮท. ฮฮต ฮธฮฑ ฯฮฑฮฏฮฝฮตฯฮฑฮน ฯฯฮฟฮฝ ฮฑฯฯฮนฮบฯ ฯฮฏฮฝฮฑฮบฮฑ. ฮฮฑฮฝฮตฮฏฯ (ฮฑฮบฯฮผฮฑ ฮบฮฑฮน ฮตฯฮตฮฏฯ!) ฮดฮต ฮธฮฑ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯ
ฯฮฟฮฒฮฌฮปฮตฮน ฮฝฮญฮฑ commit, ฮฎ ฮฝฮฑ ฮฑฮฝฮฟฮฏฮพฮตฮน ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮฎ pull request.
+settings.archive.success=ฮคฮฟ repository ฮฑฯฯฮตฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮต ฮผฮต ฮตฯฮนฯฯ
ฯฮฏฮฑ.
settings.archive.error=ฮ ฮฑฯฮฟฯ
ฯฮนฮฌฯฯฮทฮบฮต ฯฯฮฌฮปฮผฮฑ ฮบฮฑฯฮฌ ฯฮทฮฝ ฯฯฮฟฯฯฮฌฮธฮตฮนฮฑ ฮฑฯฯฮตฮนฮฟฮธฮญฯฮทฯฮทฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
. ฮฮตฮฏฯฮต ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฮณฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฮปฮตฯฯฮฟฮผฮญฯฮตฮนฮตฯ.
settings.archive.error_ismirror=ฮฮต ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฯฯฮตฮนฮฟฮธฮตฯฮฎฯฮตฯฮต ฮญฮฝฮฑ ฮตฮฏฮดฯฮปฮฟ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
-settings.archive.branchsettings_unavailable=ฮฮน ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮตฯ ฮฑฮฝ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮตฮฏฮฝฮฑฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮผฮญฮฝฮฟ.
-settings.archive.tagsettings_unavailable=ฮฮน ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฮทฯ ฮตฯฮนฮบฮญฯฮฑฯ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮตฯ ฮฑฮฝ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮตฮฏฮฝฮฑฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮผฮญฮฝฮฟ.
+settings.archive.branchsettings_unavailable=ฮฮน ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮตฯ ฮฑฮฝ ฯฮฟ repository ฮตฮฏฮฝฮฑฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮผฮญฮฝฮฟ.
+settings.archive.tagsettings_unavailable=ฮฮน ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฮทฯ ฮตฯฮนฮบฮญฯฮฑฯ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮตฯ ฮฑฮฝ ฯฮฟ repository ฮตฮฏฮฝฮฑฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮผฮญฮฝฮฟ.
settings.unarchive.button=ฮฮฝฮฑฮฏฯฮตฯฮท ฮฑฯฯฮตฮนฮฟฮธฮญฯฮทฯฮทฯ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
settings.unarchive.header=ฮฯฮฟ-ฮฯฯฮตฮนฮฟฮธฮญฯฮทฯฮท ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
-settings.unarchive.text=ฮ ฮฑฯฮฟ-ฮฑฯฯฮตฮนฮฟฮธฮญฯฮทฯฮท ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮธฮฑ ฮฑฯฮฟฮบฮฑฯฮฑฯฯฮฎฯฮตฮน ฯฮทฮฝ ฮนฮบฮฑฮฝฯฯฮทฯฮฌ ฯฮฟฯ
ฮฝฮฑ ฮปฮฑฮผฮฒฮฌฮฝฮตฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮบฮฑฮน ฯฮธฮฎฯฮตฮนฯ, ฮบฮฑฮธฯฯ ฮบฮฑฮน ฮฝฮญฮฑ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮบฮฑฮน pull-requests.
-settings.unarchive.success=ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮฑฯฮฟ-ฮฑฯฯฮตฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮต ฮผฮต ฮตฯฮนฯฯ
ฯฮฏฮฑ.
+settings.unarchive.text=ฮ ฮฑฯฮฟ-ฮฑฯฯฮตฮนฮฟฮธฮญฯฮทฯฮท ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮธฮฑ ฮฑฯฮฟฮบฮฑฯฮฑฯฯฮฎฯฮตฮน ฯฮทฮฝ ฮนฮบฮฑฮฝฯฯฮทฯฮฌ ฯฮฟฯ
ฮฝฮฑ ฮปฮฑฮผฮฒฮฌฮฝฮตฮน commits ฮบฮฑฮน ฯฮธฮฎฯฮตฮนฯ, ฮบฮฑฮธฯฯ ฮบฮฑฮน ฮฝฮญฮฑ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮบฮฑฮน pull-requests.
+settings.unarchive.success=ฮคฮฟ repository ฮฑฯฮฟ-ฮฑฯฯฮตฮนฮฟฮธฮตฯฮฎฮธฮทฮบฮต ฮผฮต ฮตฯฮนฯฯ
ฯฮฏฮฑ.
settings.unarchive.error=ฮ ฮฑฯฮฟฯ
ฯฮนฮฌฯฯฮทฮบฮต ฯฯฮฌฮปฮผฮฑ ฮบฮฑฯฮฌ ฯฮทฮฝ ฯฯฮฟฯฯฮฌฮธฮตฮนฮฑ ฮฑฯฮฟ-ฮฑฯฯฮตฮนฮฟฮธฮญฯฮทฯฮทฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
. ฮฮตฮฏฯฮต ฯฮนฯ ฮบฮฑฯฮฑฮณฯฮฑฯฮญฯ ฮณฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฮปฮตฯฯฮฟฮผฮญฯฮตฮนฮตฯ.
settings.update_avatar_success=ฮ ฮตฮนฮบฯฮฝฮฑ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮญฯฮตฮน ฮตฮฝฮทฮผฮตฯฯฮธฮตฮฏ.
settings.lfs=LFS
-settings.lfs_filelist=ฮฯฯฮตฮฏฮฑ LFS ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
-settings.lfs_no_lfs_files=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฑฯฯฮตฮฏฮฑ LFS ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
-settings.lfs_findcommits=ฮฯฯฮตฯฮท ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ
-settings.lfs_lfs_file_no_commits=ฮฮตฮฝ ฮฒฯฮญฮธฮทฮบฮฑฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ LFS
+settings.lfs_filelist=ฮฯฯฮตฮฏฮฑ LFS ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository
+settings.lfs_no_lfs_files=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฑฯฯฮตฮฏฮฑ LFS ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository
+settings.lfs_findcommits=ฮฯฯฮตฯฮท commit
+settings.lfs_lfs_file_no_commits=ฮฮตฮฝ ฮฒฯฮญฮธฮทฮบฮฑฮฝ commit ฮณฮนฮฑ ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ LFS
settings.lfs_noattribute=ฮฯ
ฯฮฎ ฮท ฮดฮนฮฑฮดฯฮฟฮผฮฎ ฮดฮตฮฝ ฮญฯฮตฮน ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮฑ ฮบฮปฮตฮนฮดฯฮผฮฑฯฮฟฯ ฯฯฮฟฮฝ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮบฮปฮฌฮดฮฟ
settings.lfs_delete=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฑฯฯฮตฮฏฮฟฯ
LFS ฮผฮต ฯฮฟ OID %s
settings.lfs_delete_warning=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮตฮฝฯฯ ฮฑฯฯฮตฮฏฮฟฯ
LFS ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯฮฟฮบฮฑฮปฮญฯฮตฮน ฯฯฮฌฮปฮผฮฑฯฮฑ ยซobject does not existยป ฮบฮฑฯฮฌ ฯฮทฮฝ ฮฟฮปฮฟฮบฮปฮฎฯฯฯฮท ฯฮฟฯ
checkout. ฮฮฏฯฯฮต ฮฒฮญฮฒฮฑฮนฮฟฮน;
@@ -2458,15 +2536,15 @@ settings.lfs_invalid_lock_directory=ฮฮดฯ
ฮฝฮฑฮผฮฏฮฑ ฮบฮปฮตฮนฮดฯฮผฮฑฯฮฟฯ ฯฮฑ
settings.lfs_lock_already_exists=ฮคฮฟ ฮบฮปฮตฮฏฮดฯฮผฮฑ ฯ
ฯฮฌฯฯฮตฮน ฮฎฮดฮท: %s
settings.lfs_lock=ฮฮปฮตฮฏฮดฯฮผฮฑ
settings.lfs_lock_path=ฮฮนฮฑฮดฯฮฟฮผฮฎ ฮฑฯฯฮตฮฏฮฟฯ
ฮณฮนฮฑ ฮฝฮฑ ฮบฮปฮตฮนฮดฯฮธฮตฮฏ...
-settings.lfs_locks_no_locks=ฮงฯฯฮฏฯ ฮฮปฮตฮนฮดฯฮผฮฑฯฮฑ
+settings.lfs_locks_no_locks=ฮงฯฯฮฏฯ ฮบฮปฮตฮนฮดฯฮผฮฑฯฮฑ
settings.lfs_lock_file_no_exist=ฮคฮฟ ฮบฮปฮตฮนฮดฯฮผฮญฮฝฮฟ ฮฑฯฯฮตฮฏฮฟ ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฯฯฮฟฮฝ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮบฮปฮฌฮดฮฟ
-settings.lfs_force_unlock=ฮฮพฮฑฮฝฮฑฮณฮบฮฑฯฮผฯฯ ฮฮตฮบฮปฮตฮนฮดฯฮผฮฑฯฮฟฯ
+settings.lfs_force_unlock=ฮฮพฮฑฮณฮบฮฑฮฝฮฑฯฯฮนฮบฯ ฮพฮตฮบฮปฮตฮฏฮดฯฮผฮฑ
settings.lfs_pointers.found=ฮฯฮญฮธฮทฮบฮฑฮฝ %d ฮดฮตฮฏฮบฯฮทฯ(ฮตฯ) blob - %d ฯฯ
ฯฯฮตฯฮฏฯฯฮทฮบฮฑฮฝ, %d ฮดฮตฮฝ ฯฯ
ฯฯฮตฯฮฏฯฯฮทฮบฮฑฮฝ (%d ฮปฮตฮฏฯฮฟฯ
ฮฝ ฮฑฯฯ ฯฮฟ ฯฯฯฮฟ ฮฑฯฮฟฮธฮฎฮบฮตฯ
ฯฮทฯ)
-settings.lfs_pointers.sha=Blob SHA
+settings.lfs_pointers.sha=Blob hash
settings.lfs_pointers.oid=OID
-settings.lfs_pointers.inRepo=ฮฃฯฮฟ ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+settings.lfs_pointers.inRepo=ฮฃฯฮฟ repository
settings.lfs_pointers.exists=ฮฅฯฮฌฯฯฮตฮน ฯฯฮฟ ฯฯฯฮฟ ฮฑฯฮฟฮธฮฎฮบฮตฯ
ฯฮทฯ
-settings.lfs_pointers.accessible=ฮ ฯฮฟฯฮฒฮฌฯฮนฮผฮฟ ฯฯฮฟ ฮงฯฮฎฯฯฮท
+settings.lfs_pointers.accessible=ฮ ฯฮฟฯฮฒฮฌฯฮนฮผฮฟ ฯฯฮฟฮฝ ฯฯฮฎฯฯฮท
settings.lfs_pointers.associateAccessible=ฮฃฯ
ฯฯฮตฯฮนฯฮผฯฯ ฯฯฮฟฯฮนฯฯฮฝ %d OID
settings.rename_branch_failed_exist=ฮฮดฯ
ฮฝฮฑฮผฮฏฮฑ ฮผฮตฯฮฟฮฝฮฟฮผฮฑฯฮฏฮฑฯ ฯฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
, ฮตฯฮตฮนฮดฮฎ ฮฟ ฮบฮปฮฌฮดฮฟฯ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ %s ฯ
ฯฮฌฯฯฮตฮน ฮฎฮดฮท.
settings.rename_branch_failed_not_exist=ฮฮดฯ
ฮฝฮฑฮผฮฏฮฑ ฮผฮตฯฮฟฮฝฮฟฮผฮฑฯฮฏฮฑฯ ฯฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
%s ฮตฯฮตฮนฮดฮฎ ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน.
@@ -2477,7 +2555,7 @@ settings.rename_branch=ฮฮตฯฮฟฮฝฮฟฮผฮฑฯฮฏฮฑ ฮบฮปฮฌฮดฮฟฯ
diff.browse_source=ฮ ฯฮฟฮฒฮฟฮปฮฎ ฯฮทฮณฮฑฮฏฮฟฯ
ฮบฯฮดฮนฮบฮฑ
diff.parent=ฮณฮฟฮฝฮญฮฑฯ
-diff.commit=ฯ
ฯฮฟฮฒฮฟฮปฮฎ
+diff.commit=commit
diff.git-notes=ฮฃฮทฮผฮตฮนฯฯฮตฮนฯ
diff.data_not_available=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ diff
diff.options_button=ฮฯฮนฮปฮฟฮณฮญฯ diff
@@ -2509,13 +2587,13 @@ diff.load=ฮฆฯฯฯฯฯฮท ฮดฮนฮฑฯฮฟฯฯฮฝ
diff.generated=ฮดฮทฮผฮนฮฟฯ
ฯฮณฮทฮผฮญฮฝฮฟ
diff.vendored=ฮตฮพฯฯฮตฯฮนฮบฯ
diff.comment.add_line_comment=ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฯฮฟฮปฮฏฮฟฯ
ฯฯฮท ฮณฯฮฑฮผฮผฮฎ
-diff.comment.placeholder=ฮฯฮฎฯฯฮต ฮญฮฝฮฑ ฯฯฯฮปฮนฮฟ
+diff.comment.placeholder=ฮฯฮฌฯฯฮต ฮญฮฝฮฑ ฯฯฯฮปฮนฮฟ
diff.comment.markdown_info=ฮฅฯฮฟฯฯฮทฯฮฏฮถฮตฯฮฑฮน ฯฯฯ
ฮป ฮผฮต markdown.
diff.comment.add_single_comment=ฮ ฯฮฟฯฮธฮญฯฯฮต ฮญฮฝฮฑ ฯฯฯฮปฮนฮฟ
diff.comment.add_review_comment=ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฯฮฟฮปฮฏฮฟฯ
diff.comment.start_review=ฮฮฝฮฑฯฮพฮท ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮทฯ
diff.comment.reply=ฮฯฮฌฮฝฯฮทฯฮท
-diff.review=ฮฮพฮนฮฟฮปฯฮณฮทฯฮท
+diff.review=ฮฮปฮฟฮบฮปฮฎฯฯฯฮท ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮทฯ
diff.review.header=ฮฅฯฮฟฮฒฮฟฮปฮฎ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮทฯ
diff.review.placeholder=ฮฃฯฯฮปฮนฮฟ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮทฯ
diff.review.comment=ฮฃฯฯฮปฮนฮฟ
@@ -2536,16 +2614,16 @@ releases.desc=ฮ ฮฑฯฮฑฮบฮฟฮปฮฟฯฮธฮทฯฮท ฮตฮบฮดฯฯฮตฯฮฝ ฮญฯฮณฮฟฯ
ฮบฮฑฮน ฮปฮฎ
release.releases=ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮตฯ
release.detail=ฮฮตฯฯฮฟฮผฮญฯฮตฮนฮตฯ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
release.tags=ฮฯฮนฮบฮญฯฮตฯ
-release.new_release=ฮฮญฮฑ ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ
+release.new_release=ฮฮญฮฑ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ
release.draft=ฮ ฯฮฟฯฯฮญฮดฮนฮฟ
-release.prerelease=ฮ ฯฮฟ-ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ
+release.prerelease=ฮ ฯฮฟฮดฮทฮผฮฟฯฮฏฮตฯ
ฯฮท
release.stable=ฮฃฯฮฑฮธฮตฯฮฎ
release.compare=ฮฃฯฮณฮบฯฮนฯฮท
release.edit=ฮตฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ
-release.ahead.commits=%d ฯ
ฯฮฟฮฒฮฟฮปฮญฯ
+release.ahead.commits=%d commits
release.ahead.target=ฯฮต %s ฮฑฯฯ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฮญฮบฮดฮฟฯฮท
tag.ahead.target=ฮผฮญฯฯฮน ฯฮฟ %s ฮฑฯฯ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ
-release.source_code=ฮ ฮทฮณฮฑฮฏฮฟฯ ฮฯฮดฮนฮบฮฑฯ
+release.source_code=ฮ ฮทฮณฮฑฮฏฮฟฯ ฮบฯฮดฮนฮบฮฑฯ
release.new_subheader=ฮฮน ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮตฯ ฮฟฯฮณฮฑฮฝฯฮฝฮฟฯ
ฮฝ ฮตฮบฮดฯฯฮตฮนฯ ฮญฯฮณฯฮฝ.
release.edit_subheader=ฮฮน ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮตฯ ฮฟฯฮณฮฑฮฝฯฮฝฮฟฯ
ฮฝ ฮตฮบฮดฯฯฮตฮนฯ ฮญฯฮณฯฮฝ.
release.tag_name=ฮฮฝฮฟฮผฮฑ ฮตฯฮนฮบฮญฯฮฑฯ
@@ -2556,18 +2634,18 @@ release.tag_helper_existing=ฮฅฯฮฌฯฯฮฟฯ
ฯฮฑ ฮตฯฮนฮบฮญฯฮฑ.
release.title=ฮคฮฏฯฮปฮฟฯ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
release.title_empty=ฮ ฯฮฏฯฮปฮฟฯ ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฮบฮตฮฝฯฯ.
release.message=ฮ ฮตฯฮนฮณฯฮฌฯฯฮต ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ
-release.prerelease_desc=ฮฃฮฎฮผฮฑฮฝฯฮท ฯฯ ฮ ฯฮฟ-ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ
+release.prerelease_desc=ฮฃฮฎฮผฮฑฮฝฯฮท ฯฯ ฯฯฮฟฮดฮทฮผฮฟฯฮฏฮตฯ
ฯฮท
release.prerelease_helper=ฮฃฮทฮผฮตฮฏฯฯฮท ฮฑฯ
ฯฮฎฯ ฯฮทฯ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ ฯฯ ฮฑฮบฮฑฯฮฌฮปฮปฮทฮปฮท ฮณฮนฮฑ ฯฯฮฎฯฮท ฯฯฮท ฯฮฑฯฮฑฮณฯฮณฮฎ.
release.cancel=ฮฮบฯฯฯฯฮท
-release.publish=ฮฮทฮผฮฟฯฮฏฮตฯ
ฯฮท ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
-release.save_draft=ฮฯฮฟฮธฮฎฮบฮตฯ
ฯฮท ฮ ฯฮฟฯฮตฮฏฯฮฟฯ
-release.edit_release=ฮฮฝฮทฮผฮญฯฯฯฮท ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
-release.delete_release=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
-release.delete_tag=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฯฮนฮบฮญฯฮฑฯ
-release.deletion=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
-release.deletion_desc=ฮฮนฮฑฮณฯฮฌฯฮฟฮฝฯฮฑฯ ฮผฮนฮฑ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ, ฮฑฯ
ฯฮฎ ฮฑฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮผฯฮฝฮฟ ฮฑฯฯ ฯฮฟ Gitea. ฮฮต ฮธฮฑ ฮตฯฮทฯฮตฮฌฯฮตฮน ฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ Git, ฯฮฑ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฑ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฮฑฯ ฮฎ ฯฮฟ ฮนฯฯฮฟฯฮนฮบฯ ฯฮทฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
+release.publish=ฮฮทฮผฮฟฯฮฏฮตฯ
ฯฮท ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
+release.save_draft=ฮฯฮฟฮธฮฎฮบฮตฯ
ฯฮท ฯฯฮฟฯฮตฮฏฯฮฟฯ
+release.edit_release=ฮฮฝฮทฮผฮญฯฯฯฮท ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
+release.delete_release=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
+release.delete_tag=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮตฯฮนฮบฮญฯฮฑฯ
+release.deletion=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑฯ
+release.deletion_desc=ฮฮนฮฑฮณฯฮฌฯฮฟฮฝฯฮฑฯ ฮผฮนฮฑ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ, ฮฑฯ
ฯฮฎ ฮฑฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮผฯฮฝฮฟ ฮฑฯฯ ฯฮฟ Forgejo. ฮฮต ฮธฮฑ ฮตฯฮทฯฮตฮฌฯฮตฮน ฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ Git, ฯฮฑ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฑ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฮฑฯ ฮฎ ฯฮฟ ฮนฯฯฮฟฯฮนฮบฯ ฯฮทฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
release.deletion_success=ฮ ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
-release.deletion_tag_desc=ฮฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฮน ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ ฮฑฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮคฮฑ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฑ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮบฮฑฮน ฯฮฟ ฮนฯฯฮฟฯฮนฮบฯ ฯฮฑฯฮฑฮผฮญฮฝฮฟฯ
ฮฝ ฮฑฮผฮตฯฮฌฮฒฮปฮทฯฮฑ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
+release.deletion_tag_desc=ฮฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฮน ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ ฮฑฯฯ ฯฮฟ repository. ฮคฮฑ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฑ ฯฮฟฯ
repository ฮบฮฑฮน ฯฮฟ ฮนฯฯฮฟฯฮนฮบฯ ฮดฮตฮฝ ฮธฮฑ ฯฮตฮนฯฮฑฯฯฮฟฯฮฝ. ฮฮฑ ฮณฮฏฮฝฮตฮน ฯฯ
ฮฝฮญฯฮตฮนฮฑ;
release.deletion_tag_success=ฮ ฮตฯฮนฮบฮญฯฮฑ ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
release.tag_name_already_exist=ฮฅฯฮฌฯฯฮตฮน ฮฎฮดฮท ฮผฮนฮฑ ฮญฮบฮดฮฟฯฮท ฮผฮต ฮฑฯ
ฯฯ ฯฮฟ ฯฮฝฮฟฮผฮฑ ฮตฯฮนฮบฮญฯฮฑฯ.
release.tag_name_invalid=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฮทฯ ฮตฯฮนฮบฮญฯฮฑฯ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟ.
@@ -2576,7 +2654,7 @@ release.tag_already_exist=ฮฯ
ฯฯ ฯฮฟ ฯฮฝฮฟฮผฮฑ ฮตฯฮนฮบฮญฯฮฑฯ ฯ
ฯฮฌฯฯฮต
release.downloads=ฮฮฎฯฮตฮนฯ
release.download_count=ฮฮฎฯฮตฮนฯ: %s
release.add_tag_msg=ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฯฮฟฮฝ ฯฮฏฯฮปฮฟ ฮบฮฑฮน ฯฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฯฮทฯ ฮญฮบฮดฮฟฯฮทฯ ฯฯ ฮผฮฎฮฝฯ
ฮผฮฑ ฮตฯฮนฮบฮญฯฮฑฯ.
-release.add_tag=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฯฮนฮบฮญฯฮฑฯ ฮฯฮฝฮฟ
+release.add_tag=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮตฯฮนฮบฮญฯฮฑฯ
release.releases_for=ฮฯ
ฮบฮปฮฟฯฮฟฯฮฏฮตฯ ฮณฮนฮฑ %s
release.tags_for=ฮฯฮนฮบฮญฯฮตฯ ฮณฮนฮฑ %s
@@ -2588,11 +2666,11 @@ branch.delete_html=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮบฮปฮฌฮดฮฟฯ
branch.delete_desc=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮตฮฝฯฯ ฮบฮปฮฌฮดฮฟฯ
ฮตฮฏฮฝฮฑฮน ฮผฯฮฝฮนฮผฮท. ฮฮฝ ฮบฮฑฮน ฮฟ ฮดฮนฮฑฮณฯฮฑฮผฮผฮญฮฝฮฟฯ ฮบฮปฮฌฮดฮฟฯ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯ
ฮฝฮตฯฮฏฯฮตฮน ฮฝฮฑ ฯ
ฯฮฌฯฯฮตฮน ฮณฮนฮฑ ฯฯฮฝฯฮฟฮผฮฟ ฯฯฮฟฮฝฮนฮบฯ ฮดฮนฮฌฯฯฮทฮผฮฑ ฯฯฮนฮฝ ฮฝฮฑ ฮฑฯฮฑฮนฯฮตฮธฮตฮฏ, ฮฮฮ ฮฮ ฮฮกฮฮ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ ฯฯฮนฯ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฯฮตฯฮนฯฯฯฯฮตฮนฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
branch.deletion_success=ฮ ฮบฮปฮฌฮดฮฟฯ ยซ%sยป ฮดฮนฮฑฮณฯฮฌฯฮทฮบฮต.
branch.deletion_failed=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฯฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
ยซ%sยป ฮฑฯฮญฯฯ
ฯฮต.
-branch.delete_branch_has_new_commits=ฮ ฮบฮปฮฌฮดฮฟฯ ยซ%sยป ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ ฮตฯฮตฮนฮดฮฎ ฯฯฮฟฯฯฮญฮธฮทฮบฮฑฮฝ ฮฝฮญฮตฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮผฮตฯฮฌ ฯฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท.
-branch.create_branch=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮบฮปฮฌฮดฮฟฯ
%s
+branch.delete_branch_has_new_commits=ฮ ฮบฮปฮฌฮดฮฟฯ ยซ%sยป ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ ฮตฯฮตฮนฮดฮฎ ฯฯฮฟฯฯฮญฮธฮทฮบฮฑฮฝ ฮฝฮญฮฑ commit ฮผฮตฯฮฌ ฯฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท.
+branch.create_branch=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮบฮปฮฌฮดฮฟฯ
%s
branch.create_from=`ฮฑฯฯ ฯฮฟ ยซ%sยป`
branch.create_success=ฮ ฮบฮปฮฌฮดฮฟฯ ยซ%sยป ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต.
-branch.branch_already_exists=ฮ ฮบฮปฮฌฮดฮฟฯ ยซ%sยป ฯ
ฯฮฌฯฯฮตฮน ฮฎฮดฮท ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+branch.branch_already_exists=ฮ ฮบฮปฮฌฮดฮฟฯ ยซ%sยป ฯ
ฯฮฌฯฯฮตฮน ฮฎฮดฮท ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
branch.branch_name_conflict=ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฯฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
ยซ%sยป ฯฯ
ฮณฮบฯฮฟฯฮตฯฮฑฮน ฮผฮต ฯฮฟ ฮฎฮดฮท ฯ
ฯฮฌฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ ยซ%sยป.
branch.tag_collision=ฮ ฮบฮปฮฌฮดฮฟฯ ยซ%sยป ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮทฮธฮตฮฏ ฮตฯฮตฮนฮดฮฎ ฮผฮนฮฑ ฮตฯฮนฮบฮญฯฮฑ ฮผฮต ฯฮฟ ฮฏฮดฮนฮฟ ฯฮฝฮฟฮผฮฑ ฯ
ฯฮฌฯฯฮตฮน ฮฎฮดฮท ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
branch.deleted_by=ฮฮนฮฑฮณฯฮฌฯฮทฮบฮต ฮฑฯฯ %s
@@ -2616,7 +2694,7 @@ branch.new_branch=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฝฮญฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
branch.new_branch_from=`ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฝฮญฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
ฮฑฯฯ ฯฮฟ ยซ%sยป`
branch.renamed=ฮ ฮบฮปฮฌฮดฮฟฯ %s ฮผฮตฯฮฟฮฝฮฟฮผฮฌฯฯฮทฮบฮต ฯฮต %s.
-tag.create_tag=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮตฯฮนฮบฮญฯฮฑฯ %s
+tag.create_tag=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮตฯฮนฮบฮญฯฮฑฯ %s
tag.create_tag_operation=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮตฯฮนฮบฮญฯฮฑฯ
tag.confirm_create_tag=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮตฯฮนฮบฮญฯฮฑฯ
tag.create_tag_from=`ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฝฮญฮฑฯ ฮตฯฮนฮบฮญฯฮฑฯ ฮฑฯฯ ฯฮฟ ยซ%sยป`
@@ -2635,9 +2713,9 @@ error.csv.too_large=ฮฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฮฑฯฯฮดฮฟฯฮท ฮฑฯ
ฯฮฟฯ
error.csv.unexpected=ฮฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฮฑฯฯฮดฮฟฯฮท ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฮฑฯฯฮตฮฏฮฟฯ
, ฮตฯฮตฮนฮดฮฎ ฯฮตฯฮนฮญฯฮตฮน ฮญฮฝฮฑฮฝ ฮผฮท ฮฑฮฝฮฑฮผฮตฮฝฯฮผฮตฮฝฮฟ ฯฮฑฯฮฑฮบฯฮฎฯฮฑ ฯฯฮท ฮณฯฮฑฮผฮผฮฎ %d ฮบฮฑฮน ฯฯฮท ฯฯฮฎฮปฮท %d.
error.csv.invalid_field_count=ฮฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฮฑฯฯฮดฮฟฯฮท ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฮฑฯฯฮตฮฏฮฟฯ
, ฮตฯฮตฮนฮดฮฎ ฮญฯฮตฮน ฮปฮฌฮธฮฟฯ ฮฑฯฮนฮธฮผฯ ฯฮตฮดฮฏฯฮฝ ฯฯฮท ฮณฯฮฑฮผฮผฮฎ %d.
commits.renamed_from = ฮฮตฯฮฟฮฝฮฟฮผฮฌฯฯฮทฮบฮต ฮฑฯฯ %ฯ
-settings.wiki_rename_branch_main_desc = ฮ ฮบฮปฮฌฮดฮฟฯ, ฮฟ ฮฟฯฮฟฮฏฮฟฯ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮตฯฯฯฮตฯฮนฮบฮฌ ฮฑฯฯ ฯฮฟ wiki, ฮธฮฑ ฮผฮตฯฮฟฮฝฮฟฮผฮฑฯฯฮตฮฏ ฯฮต ยซ%sยป. ฮฯ
ฯฮฎ ฮท ฮฑฮปฮปฮฑฮณฮฎ ฮตฮฏฮฝฮฑฮน ฮผฯฮฝฮนฮผฮท ฮบฮฑฮน ฮผฮท ฮฑฮฝฮฑฯฯฯฮญฯฮนฮผฮท.
+settings.wiki_rename_branch_main_desc = ฮ ฮบฮปฮฌฮดฮฟฯ, ฮฟ ฮฟฯฮฟฮฏฮฟฯ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮตฯฯฯฮตฯฮนฮบฮฌ ฮฑฯฯ ฯฮฟ wiki, ฮธฮฑ ฮผฮตฯฮฟฮฝฮฟฮผฮฑฯฯฮตฮฏ (ฮผฯฮฝฮนฮผฮฑ ฮบฮฑฮน ฮผฮท ฮฑฮฝฮฑฯฯฯฮฌฯฮนฮผฮฑ) ฯฮต ยซ%sยป.
issues.comment.blocked_by_user = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฯฮฎฯฮตฯฮต ฯฯฯฮปฮนฮฟ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ, ฮตฯฮตฮนฮดฮฎ ฮฟ ฮบฮฌฯฮฟฯฮฟฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฎ ฯฮฟ ฮฌฯฮฟฮผฮฟ ฯฮฟฯ
ฮดฮทฮผฮนฮฟฯฯฮณฮทฯฮต ฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฯฮฑฯ ฮญฯฮตฮน ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฮน.
-pulls.blocked_by_user = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต pull request ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ, ฮตฯฮตฮนฮดฮฎ ฮฟ ฮบฮฌฯฮฟฯฮฟฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฮฑฯ ฮญฯฮตฮน ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฮน.
+pulls.blocked_by_user = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต pull request ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository, ฮตฯฮตฮนฮดฮฎ ฮฟ ฮบฮฌฯฮฟฯฮฟฯ ฯฮฟฯ
repository ฯฮฑฯ ฮญฯฮตฮน ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฮน.
pulls.made_using_agit = AGit
wiki.cancel = ฮฮบฯฯฯฯฮท
settings.units.add_more = ฮ ฯฮฟฯฮธฮฎฮบฮท ฮผฮฟฮฝฮฌฮดฯฮฝ...
@@ -2645,7 +2723,7 @@ settings.new_owner_blocked_doer = ฮ ฮฝฮญฮฟฯ ฮบฮฌฯฮฟฯฮฟฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯ
settings.enter_repo_name = ฮฯฮฌฯฯฮต ฯฮฟ ฯฮฝฮฟฮผฮฑ ฯฮฟฯ
ฮบฮฑฯฯฯฮฟฯ
ฮบฮฑฮน ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฑฮบฯฮนฮฒฯฯ ฯฯฯฯ ฯฮฟ ฮฒฮปฮญฯฮตฯฮต:
settings.confirmation_string = ฮฮตฮฏฮผฮตฮฝฮฟ ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮทฯ
settings.units.overview = ฮฯฮนฯฮบฯฯฮทฯฮท
-pulls.commit_ref_at = `ฮฑฮฝฮญฯฮตฯฮต ฯฮฟ pull request ฯฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ %[2]s `
+pulls.commit_ref_at = `ฮฑฮฝฮญฯฮตฯฮต ฯฮฟ pull request ฯฯฮฟ commit %[2]s `
contributors.contribution_type.filter_label = ฮฮฏฮดฮฟฯ ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮฌฯ:
settings.wiki_rename_branch_main_notices_1 = ฮฯ
ฯฮฎ ฮท ฮตฮฝฮญฯฮณฮตฮนฮฑ ฮฮฮ ฮฑฮฝฮฑฮนฯฮตฮฏฯฮฑฮน.
activity.navbar.contributors = ฮฃฯ
ฮฝฮตฮนฯฯฮญฯฮฟฮฝฯฮตฯ
@@ -2654,15 +2732,15 @@ contributors.contribution_type.deletions = ฮฮนฮฑฮณฯฮฑฯฮญฯ
migrate.forgejo.description = ฮฮตฯฮฑฯฮฟฯฮฌ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฯฯ ฯฮฟ codeberg.org ฮฎ ฮฌฮปฮปฯฮฝ ฯ
ฯฮทฯฮตฯฮนฯฮฝ Forgejo.
rss.must_be_on_branch = ฮฮนฮฑ ฮฝฮฑ ฮฑฯฮฟฮบฯฮฎฯฮตฯฮต ฮญฮฝฮฑ RSS feed, ฯฯฮญฯฮตฮน ฮฝฮฑ ฮฒฯฮฏฯฮบฮตฯฯฮต ฯฮต ฮญฮฝฮฑฮฝ ฮบฮปฮฌฮดฮฟ.
clone_in_vscodium = ฮฮปฯฮฝฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฟ VSCodium
-editor.invalid_commit_mail = ฮฯ
ฯฮฎ ฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮท ฮณฮนฮฑ ฯฮทฮฝ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮผฮฏฮฑฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ.
+editor.invalid_commit_mail = ฮฯ
ฯฮฎ ฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮท ฮณฮนฮฑ ฯฮทฮฝ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ commit.
pulls.nothing_to_compare_have_tag = ฮ ฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ ฮบฮปฮฌฮดฮฟฯ/tag ฮตฮฏฮฝฮฑฮน ฯฮผฮฟฮนฮฟฯ.
-issues.blocked_by_user = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮถฮทฯฮฎฮผฮฑฯฮฑ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ, ฮตฯฮตฮนฮดฮฎ ฮฟ ฮบฮฌฯฮฟฯฮฟฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฮฑฯ ฮญฯฮตฮน ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฮน.
+issues.blocked_by_user = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮถฮทฯฮฎฮผฮฑฯฮฑ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository, ฮตฯฮตฮนฮดฮฎ ฮฟ ฮบฮฌฯฮฟฯฮฟฯ ฯฮฟฯ
repository ฯฮฑฯ ฮญฯฮตฮน ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฮน.
pulls.agit_explanation = ฮฮทฮผฮนฮฟฯ
ฯฮณฮทฮผฮญฮฝฮฟ ฮผฮญฯฯ ฯฮฟฯ
AGit. ฮคฮฟ AGit ฮตฯฮนฯฯฮญฯฮตฮน ฯฮต ฯฯ
ฮฝฮตฮนฯฯฮญฯฮฟฮฝฯฮตฯ ฮฝฮฑ ฯฯฮฟฯฮตฮฏฮฝฮฟฯ
ฮฝ ฮฑฮปฮปฮฑฮณฮญฯ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฯฮทฮฝ ฮตฮฝฯฮฟฮปฮฎ ยซgit pushยป, ฯฯฯฮฏฯ ฯฮทฮฝ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ fork ฮฎ ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ.
-activity.navbar.recent_commits = ฮ ฯฯฯฯฮฑฯฮตฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ
+activity.navbar.recent_commits = ฮ ฯฯฯฯฮฑฯฮฑ commit
settings.wiki_globally_editable = ฮฮฑ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฮตฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฯฮฟฯ
wiki ฯฮต ฯฮปฮฟฯ
ฯ
admin.manage_flags = ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฯฮทฮผฮฌฮฝฯฮตฯฮฝ
-admin.enabled_flags = ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮญฯฮตฮน ฯฮนฯ ฮตฮพฮฎฯ ฯฮทฮผฮฌฮฝฯฮตฮนฯ:
-settings.mirror_settings.pushed_repository = ฮ ฯฮฟฮฟฯฮนฮถฯฮผฮตฮฝฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+admin.enabled_flags = ฮคฮฟ repository ฮญฯฮตฮน ฯฮนฯ ฮตฮพฮฎฯ ฯฮทฮผฮฌฮฝฯฮตฮนฯ:
+settings.mirror_settings.pushed_repository = ฮ ฯฮฟฮฟฯฮนฮถฯฮผฮตฮฝฮฟ repository
admin.flags_replaced = ฮฮน ฯฮทฮผฮฌฮฝฯฮตฮนฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮฑฮฝฯฮนฮบฮฑฯฮฑฯฯฮฌฮธฮทฮบฮฑฮฝ
activity.navbar.code_frequency = ฮฃฯ
ฯฮฝฯฯฮทฯฮฑ ฮบฯฮดฮนฮบฮฑ
settings.wiki_branch_rename_success = ฮคฮฟ ฯฮฝฮฟฮผฮฑ ฮบฮปฮฌฮดฮฟฯ
wiki ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮบฮฑฮฝฮฟฮฝฮนฮบฮฟฯฮฟฮนฮฎฮธฮทฮบฮต ฮตฯฮนฯฯ
ฯฯฯ.
@@ -2686,13 +2764,13 @@ settings.add_collaborator_blocked_our = ฮฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฯฯฮฟ
n_branch_few = %s ฮบฮปฮฌฮดฮฟฮน
n_tag_one = %s ฮตฯฮนฮบฮญฯฮฑ
n_tag_few = %s ฮตฯฮนฮบฮญฯฮตฯ
-n_commit_one = %s ฯ
ฯฮฟฮฒฮฟฮปฮฎ
+n_commit_one = %s commit
stars = ฮฯฯฮญฯฮนฮฑ
n_branch_one = %s ฮบฮปฮฌฮดฮฟฯ
commits.search_branch = ฮฯ
ฯฯฯ ฮฟ ฮบฮปฮฌฮดฮฟฯ
-pulls.title_desc_one = : ฮธฮฑ ฮฎฮธฮตฮปฮต ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฮน %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮฑฯฯ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[2]s
ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[3]s
+pulls.title_desc_one = : ฮธฮฑ ฮฎฮธฮตฮปฮต ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฮน %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮฑฯฯ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[2]s
ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[3]s
pulls.merged_title_desc_one = ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮต %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮฑฯฯ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[2]s
ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[3]s
%[4]s
-n_commit_few = %s ฯ
ฯฮฟฮฒฮฟฮปฮญฯ
+n_commit_few = %s commits
settings.sourcehut_builds.secrets = ฮฯ
ฯฯฮนฮบฮฌ
settings.add_webhook.invalid_path = ฮ ฯฮฟฯฮฟฮธฮตฯฮฏฮฑ ฯฮฟฯ
ฮฑฯฯฮตฮฏฮฟฯ
ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฮตฯฮนฮญฯฮตฮน ฮบฮตฮฝฮฌ, ยซ.ยป ฮฎ ยซ..ยป. ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฯฯฮฏฮถฮตฮน ฮฎ ฮฝฮฑ ฯฮตฮปฮตฮนฯฮฝฮตฮน ฮผฮต ฮผฮฏฮฑ ฮบฮฌฮธฮตฯฮฟ.
commits.browse_further = ฮ ฮตฯฮนฮฎฮณฮทฯฮท ฯฮตฯฮนฯฯฮฟฯฮญฯฯฮฝ
@@ -2709,19 +2787,74 @@ release.system_generated = ฮฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮฑฯฮฌฮณฮตฯฮฑฮน ฮฑฯ
ฯ
pulls.ready_for_review = ฮฯฮฟฮนฮผฮฟ ฮณฮนฮฑ ฮฑฮพฮนฮฟฮปฯฮณฮทฯฮท;
settings.rename_branch_failed_protected = ฮฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฮผฮตฯฮฟฮฝฮฟฮผฮฑฯฮฏฮฑ ฯฮฟฯ
ฮบฮปฮฌฮดฮฟฯ
%s, ฮตฯฮตฮนฮดฮฎ ฮตฮฏฮฝฮฑฮน ฯฯฮฟฯฯฮฑฯฮตฯ
ฯฮผฮตฮฝฮฟฯ.
settings.event_pull_request_enforcement = ฮฮพฮฑฮฝฮฑฮณฮบฮฑฯฮผฯฯ
-editor.commit_id_not_matching = ฮคฮฟ ฮฑฮฝฮฑฮณฮฝฯฯฮนฯฯฮนฮบฯ ฯฮทฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ ฮดฮตฮฝ ฯฮฑฮนฯฮนฮฌฮถฮตฮน ฮผฮต ฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฯฮฟฯ
ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮฎฮบฮฑฯฮต. ฮฮฑ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯ
ฯฮฟฮฒฮฌฮปฮตฯฮต ฯฮนฯ ฮฑฮปฮปฮฑฮณฮญฯ ฯฮฑฯ ฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮบฮฑฮน ฮผฮตฯฮฌ ฮฝฮฑ ฯฮนฯ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฯฮต.
+editor.commit_id_not_matching = ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ฮฌฮปฮปฮฑฮพฮต ฯฯฮฟ ฯฮฟ ฮตฯฮตฮพฮตฯฮณฮฑฮถฯฯฮฑฯฯฮฑฮฝ. ฮฮฑ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯ
ฯฮฟฮฒฮฌฮปฮตฯฮต ฯฮนฯ ฮฑฮปฮปฮฑฮณฮญฯ ฯฮฑฯ ฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮปฮฌฮดฮฟ ฮบฮฑฮน ฮผฮตฯฮฌ ฮฝฮฑ ฯฮนฯ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฯฮต.
settings.sourcehut_builds.visibility = ฮฯฮฑฯฯฯฮทฯฮฑ ฮตฯฮณฮฑฯฮนฯฮฝ
object_format = ฮฮฟฯฯฮฎ ฮฑฮฝฯฮนฮบฮตฮนฮผฮญฮฝฯฮฝ (ยซobject formatยป)
-settings.ignore_stale_approvals_desc = ฮฮน ฮตฮณฮบฯฮฏฯฮตฮนฯ, ฮฟฮน ฮฟฯฮฟฮฏฮตฯ ฮฑฮฝฮฑฯฮญฯฮฟฮฝฯฮฑฮน ฯฮต ฯฮฑฮปฮฑฮนฯฯฮตฯฮตฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ, ฮดฮตฮฝ ฮธฮฑ ฯฯฮฟฯฮผฮตฯฯฮฟฯฮฝฯฮฑฮน ฯฯฮฟ ฯฯฮฝฮฟฮปฮฟ ฯฯฮฝ ฮฑฯฮฑฮนฯฮฟฯฮผฮตฮฝฯฮฝ ฮตฮณฮบฯฮฏฯฮตฯฮฝ ฯฮฟฯ
pull request. ฮฯฯฯฮฟฮฝ ฮฑฯ
ฯฮญฯ ฮฟฮน ฮตฮณฮบฯฮฏฯฮตฮนฯ ฮญฯฮฟฯ
ฮฝ ฮฎฮดฮท ฮฑฮฝฮฑฮบฮปฮทฮธฮตฮฏ, ฯฯฯฮต ฮฑฯ
ฯฮฎ ฮท ฯฯฮธฮผฮนฯฮท ฮดฮตฮฝ ฮธฮฑ ฯฮฑฮฏฮพฮตฮน ฮบฮฌฯฮฟฮนฮฟฮฝ ฯฯฮปฮฟ.
-settings.archive.mirrors_unavailable = ฮฮน ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮตฯ ฮตฮนฮดฯฮปฮฟฯ
ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮตฯ ฮตฯฯฯฮฟฮฝ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮญฯฮตฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮธฮตฮฏ.
+settings.ignore_stale_approvals_desc = ฮฮน ฮตฮณฮบฯฮฏฯฮตฮนฯ, ฮฟฮน ฮฟฯฮฟฮฏฮตฯ ฮฑฮฝฮฑฯฮญฯฮฟฮฝฯฮฑฮน ฯฮต ฯฮฑฮปฮฑฮนฯฯฮตฯฮฑ commit, ฮดฮตฮฝ ฮธฮฑ ฯฯฮฟฯฮผฮตฯฯฮฟฯฮฝฯฮฑฮน ฯฯฮฟ ฯฯฮฝฮฟฮปฮฟ ฯฯฮฝ ฮฑฯฮฑฮนฯฮฟฯฮผฮตฮฝฯฮฝ ฮตฮณฮบฯฮฏฯฮตฯฮฝ ฯฮฟฯ
pull request. ฮฯฯฯฮฟฮฝ ฮฑฯ
ฯฮญฯ ฮฟฮน ฮตฮณฮบฯฮฏฯฮตฮนฯ ฮญฯฮฟฯ
ฮฝ ฮฎฮดฮท ฮฑฮฝฮฑฮบฮปฮทฮธฮตฮฏ, ฯฯฯฮต ฮฑฯ
ฯฮฎ ฮท ฯฯฮธฮผฮนฯฮท ฮดฮตฮฝ ฮธฮฑ ฯฮฑฮฏฮพฮตฮน ฮบฮฌฯฮฟฮนฮฟฮฝ ฯฯฮปฮฟ.
+settings.archive.mirrors_unavailable = ฮฮน ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮตฯ ฮตฮนฮดฯฮปฮฟฯ
ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮตฯ ฮตฯฯฯฮฟฮฝ ฯฮฟ repository ฮญฯฮตฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮธฮตฮฏ.
settings.web_hook_name_sourcehut_builds = SourceHut Builds
settings.enforce_on_admins = ฮฯฮฑฯฮผฮฟฮณฮฎ ฮบฮฑฮฝฯฮฝฮฑ ฯฮต ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮญฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
-object_format_helper = ฮ ฮผฮฟฯฯฮฎ ฯฯฮฝ ฮฑฮฝฯฮนฮบฮตฮนฮผฮญฮฝฯฮฝ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
. ฮฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฮฟ ฮฑฮปฮปฮฌฮพฮตฯฮต ฮผฮตฯฮฑฮณฮตฮฝฮญฯฯฮตฯฮฑ. ฮ ฯฮนฮฟ ฯฯ
ฮผฮฒฮฑฯฮฎ ฮผฮฟฯฯฮฎ ฮตฮฏฮฝฮฑฮน ฮท SHA1.
+object_format_helper = ฮ ฮผฮฟฯฯฮฎ ฮฑฮฝฯฮนฮบฮตฮนฮผฮญฮฝฯฮฝ (ยซobject formatยป) ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
. ฮฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฮฟ ฮฑฮปฮปฮฌฮพฮตฯฮต ฮผฮตฯฮฑฮณฮตฮฝฮญฯฯฮตฯฮฑ. ฮ ฯฮนฮฟ ฯฯ
ฮผฮฒฮฑฯฮฎ ฮผฮฟฯฯฮฎ ฮตฮฏฮฝฮฑฮน ฮท SHA1.
settings.enforce_on_admins_desc = ฮฮน ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮญฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฯฯฮฟฯฯฮตฮปฮฌฯฮฟฯ
ฮฝ ฯฮฟฮฝ ฮบฮฑฮฝฯฮฝฮฑ.
file_follow = ฮฮบฮฟฮปฮฟฯฮธฮทฯฮท ฯฯ
ฮฝฮดฮญฯฮผฮฟฯ
(symlink)
settings.sourcehut_builds.secrets_helper = ฮ ฮฑฯฮฑฯฯฯฮทฯฮท ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮฟฯ
job ฯฯฮฑ ฮผฯ
ฯฯฮนฮบฮฌ ฮตฮฝฯฯ build (ฮฑฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮท ฮฌฮดฮตฮนฮฑ SECRETS:RO)
generated = ฮ ฮฑฯฮฑฮณฮผฮญฮฝฮฟ
editor.push_out_of_date = ฮ ฮฑฮปฮปฮฑฮณฮฎ ฯฮฑฮฏฮฝฮตฯฮฑฮน ฮฝฮฑ ฮตฮฏฮฝฮฑฮน ฯฮฑฯฯฯฮทฮผฮญฮฝฮท.
+issues.author.tooltip.issue = ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮดฮทฮผฮนฮฟฯฯฮณฮทฯฮต ฯฮฟ ฮถฮฎฯฮทฮผฮฑ.
+issues.author.tooltip.pr = ฮฯ
ฯฯ ฯฮฟ pull request ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฮฑฯฯ ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฯฯฮฎฯฯฮท.
+settings.federation_settings = ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮดฮนฮฑฮปฮตฮนฯฮฟฯ
ฯฮณฮนฮบฯฯฮทฯฮฑฯ
+settings.federation_apapiurl = ฮคฮฟ Federation URL (URL ฮดฮนฮฑฮปฮตฮนฯฮฟฯ
ฯฮณฮนฮบฯฯฮทฯฮฑฯ) ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
. ฮฮฌฮฝฯฮต ฯฮฟ copy-paste ฯฯฮนฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฮดฮนฮฑฮปฮตฮนฯฮฟฯ
ฯฮณฮนฮบฯฯฮทฯฮฑฯ ฮตฮฝฯฯ ฮฌฮปฮปฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฯฯ ฯฮฟ URL ฮตฮฝฯฯ ฮฑฮบฮฟฮปฮฟฯ
ฮธฮฟฯฮผฮตฮฝฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
+form.string_too_long = ฮคฮฟ ฮบฮตฮฏฮผฮตฮฝฮฟ ฮตฮฏฮฝฮฑฮน ฮผฮตฮณฮฑฮปฯฯฮตฯฮฟ ฮฑฯฯ %d ฯฮฑฯฮฑฮบฯฮฎฯฮตฯ.
+release.hide_archive_links = ฮฯฯฮบฯฯ
ฯฮท ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮทฮผฮญฮฝฯฮฝ archive
+settings.graphql_url = URL ฯฮฟฯ
GraphQL
+issues.edit.already_changed = ฮฮตฮฝ ฮฎฯฮฑฮฝ ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฮฑฯฮฟฮธฮฎฮบฮตฯ
ฯฮท ฯฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ ฯฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฮฑฯ
ฯฯ, ฮตฯฮตฮนฮดฮฎ ฯฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฮญฯฮตฮน ฮฎฮดฮท ฮฑฮปฮปฮฑฯฮธฮตฮฏ ฮฑฯฯ ฮบฮฌฯฮฟฮนฮฟฮฝ ฮฌฮปฮปฮฟ ฯฯฮฎฯฯฮท. ฮฮนฮฑ ฮฝฮฑ ฮผฮทฮฝ ฯฮฑฮธฮฟฯฮฝ ฮฟฮน ฮฑฮปฮปฮฑฮณฮญฯ ฯฮฟฯ
, ฯฮฑฯฮฑฮบฮฑฮปฮตฮฏฯฮธฮต ฮฝฮฑ ฮฑฮฝฮฑฮฝฮตฯฯฮตฯฮต ฯฮทฮฝ ฯฮตฮปฮฏฮดฮฑ ฮบฮฑฮน ฯฯฮฟฯฯฮฑฮธฮฎฯฯฮต ฮฝฮฑ ฯฮฟ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮตฮฏฯฮต ฮพฮฑฮฝฮฌ.
+project = ฮฯฮณฮฑ
+settings.sourcehut_builds.access_token_helper = ฮฮนฮฑฮบฯฮนฯฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ (token) ฯฮฟฯ
ฮญฯฮตฮน ฮฌฮดฮตฮนฮฑ JOBS:RW. ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฯฮนฯฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฮณฮนฮฑ ฯฮฟ build.sr.ht ฮฎ ฮญฮฝฮฑ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ build.sr.ht ฮผฮต ฯฯฯฯฮฒฮฑฯฮท ฮนฮดฮนฯฯฮนฮบฯฮฝ ฯฮตฯฮนฮตฯฮฟฮผฮญฮฝฯฮฝ ฯฯฮฟ meta.sr.ht.
+settings.federation_not_enabled = ฮฮน ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮตฯ ฮดฮนฮฑฮปฮตฮนฯฮฟฯ
ฯฮณฮนฮบฯฯฮทฯฮฑฯ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮตฯ ฯฯฮฟฮฝ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฮฑฯ.
+settings.federation_following_repos = URL ฮฑฮบฮฟฯ
ฮปฮฟฯ
ฮธฮฟฯฮผฮตฮฝฯฮฝ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ. ฮฮนฮฑฯฯฯฮฏฮถฮฟฮฝฯฮฑฮน ฮผฮต ยซ;ยป, ฯฯฯฮฏฯ ฮบฮตฮฝฮฌ.
+subscribe.issue.guest.tooltip = ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฮปฮฌฮฒฮตฯฮต ฮตฮฝฮทฮผฮตฯฯฯฮตฮนฯ ฮณฮนฮฑ ฯฮฟ ฮถฮฎฯฮทฮผฮฑ ฮฑฯ
ฯฯ.
+subscribe.pull.guest.tooltip = ฮฃฯ
ฮฝฮดฮตฮธฮตฮฏฯฮต ฮณฮนฮฑ ฮฝฮฑ ฮปฮฌฮฒฮตฯฮต ฮตฮฝฮทฮผฮตฯฯฯฮตฮนฯ ฮณฮนฮฑ ฯฮฟ pull request ฮฑฯ
ฯฯ.
+pulls.edit.already_changed = ฮฮตฮฝ ฮฎฯฮฑฮฝ ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฮฑฯฮฟฮธฮฎฮบฮตฯ
ฯฮท ฯฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ ฯฯฮฟ pull request ฮฑฯ
ฯฯ, ฮตฯฮตฮนฮดฮฎ ฯฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฮญฯฮตฮน ฮฎฮดฮท ฮฑฮปฮปฮฑฯฮธฮตฮฏ ฮฑฯฯ ฮบฮฌฯฮฟฮนฮฟฮฝ ฮฌฮปฮปฮฟ ฯฯฮฎฯฯฮท. ฮฮนฮฑ ฮฝฮฑ ฮผฮทฮฝ ฯฮฑฮธฮฟฯฮฝ ฮฟฮน ฮฑฮปฮปฮฑฮณฮญฯ ฯฮฟฯ
, ฯฮฑฯฮฑฮบฮฑฮปฮตฮฏฯฮธฮต ฮฝฮฑ ฮฑฮฝฮฑฮฝฮตฯฯฮตฯฮต ฯฮทฮฝ ฯฮตฮปฮฏฮดฮฑ ฮบฮฑฮน ฯฯฮฟฯฯฮฑฮธฮฎฯฯฮต ฮฝฮฑ ฯฮฟ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮตฮฏฯฮต ฮพฮฑฮฝฮฌ.
+comments.edit.already_changed = ฮฮตฮฝ ฮฎฯฮฑฮฝ ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฮฑฯฮฟฮธฮฎฮบฮตฯ
ฯฮท ฯฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฯฯฯฮปฮนฮฟ, ฮตฯฮตฮนฮดฮฎ ฯฮฟ ฯฮตฯฮนฮตฯฯฮผฮตฮฝฮฟ ฮญฯฮตฮน ฮฎฮดฮท ฮฑฮปฮปฮฑฯฮธฮตฮฏ ฮฑฯฯ ฮบฮฌฯฮฟฮนฮฟฮฝ ฮฌฮปฮปฮฟ ฯฯฮฎฯฯฮท. ฮฮนฮฑ ฮฝฮฑ ฮผฮทฮฝ ฯฮฑฮธฮฟฯฮฝ ฮฟฮน ฮฑฮปฮปฮฑฮณฮญฯ ฯฮฟฯ
, ฯฮฑฯฮฑฮบฮฑฮปฮตฮฏฯฮธฮต ฮฝฮฑ ฮฑฮฝฮฑฮฝฮตฯฯฮตฯฮต ฯฮทฮฝ ฯฮตฮปฮฏฮดฮฑ ฮบฮฑฮน ฯฯฮฟฯฯฮฑฮธฮฎฯฯฮต ฮฝฮฑ ฯฮฟ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮตฮฏฯฮต ฮพฮฑฮฝฮฌ.
+settings.matrix.access_token_helper = ฮฮนฮฑ ฯฮฟฮฝ ฯฮบฮฟฯฯ ฮฑฯ
ฯฯ, ฯฮฑฯ ฯฯ
ฮฝฮนฯฯฮฟฯฮผฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮญฮฝฮฑฮฝ ฮพฮตฯฯฯฮนฯฯฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ Matrix. ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฯฮฟฮบฯฮฎฯฮตฯฮต ฯฮฟ ฮดฮนฮฑฮบฯฮนฯฮนฮบฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฮผฮญฯฮฑ ฯฯฮฟ Element.
+settings.transfer.modal.title = ฮ ฮฑฯฮฑฯฯฯฮทฯฮท ฮนฮดฮนฮฟฮบฯฮทฯฮฏฮฑฯ
+settings.transfer.button = ฮ ฮฑฯฮฑฯฯฯฮทฯฮท ฮนฮดฮนฮฟฮบฯฮทฯฮฏฮฑฯ
+settings.matrix.room_id_helper = ฮคฮฟ ID ฮดฯฮผฮฑฯฮฏฮฟฯ
ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฮฟ ฮฒฯฮตฮฏฯฮต ฯฯฮฟ ฯฯฯฮณฯฮฑฮผฮผฮฑ Element > Room Settings > Advanced > Internal room ID. ฮ ฮฑฯฮฌฮดฮตฮนฮณฮผฮฑ: %s.
+wiki.search = ฮฮฝฮฑฮถฮฎฯฮทฯฮท wiki
+wiki.no_search_results = ฮฮฑฮฝฮญฮฝฮฑ ฮฑฯฮฟฯฮญฮปฮตฯฮผฮฑ
+n_release_one = %s ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮฑ
+n_release_few = %s ฮบฯ
ฮบฮปฮฟฯฮฟฯฮฏฮตฯ
+release.hide_archive_links_helper = ฮฯฯฮบฯฯ
ฯฮท ฯฯฮฝ ฮฑฯฯฮตฮฏฯฮฝ ฯฮทฮณฮฑฮฏฮฟฯ
ฮบฯฮดฮนฮบฮฑ ฯฮฟฯ
ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฟฯฮฝฯฮฑฮน ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฮณฮนฮฑ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฮดฮทฮผฮนฮฟฯฮฏฮตฯ
ฯฮท. ฮฯ
ฯฮฎ ฮท ฯฯฮธฮผฮนฯฮท ฮตฮฏฮฝฮฑฮน ฯฯฮฎฯฮนฮผฮท ฮฑฮฝ ฮฑฮฝฮตฮฒฮฌฮถฮตฯฮต ฯฮฑ ฮดฮนฮบฮฌ ฯฮฑฯ ฮฑฯฯฮตฮฏฮฑ.
+release.type_attachment = ฮฃฯ
ฮฝฮทฮผฮผฮญฮฝฮฟ
+activity.published_prerelease_label = ฮ ฯฮฟฮดฮทฮผฮฟฯฮฏฮตฯ
ฯฮท
+activity.published_tag_label = ฮฯฮนฮบฮญฯฮฑ
+settings.pull_mirror_sync_quota_exceeded = ฮฯฮตฯฮต ฯ
ฯฮตฯฮฒฮตฮฏ ฯฮฟฯ
ฯ ฮดฮนฮฑฮธฮญฯฮนฮผฮฟฯ
ฯ ฯฯฯฮฟฯ
ฯ ฯฮฑฯ, ฮณฮนฮฑ ฮฑฯ
ฯฯ ฮดฮตฮฝ ฮธฮฑ ฮณฮฏฮฝฮตฮน ฮปฮฎฯฮท ฯฯฮฝ ฯฮนฮฟ ฯฯฯฯฯฮฑฯฯฮฝ ฮฑฮปฮปฮฑฮณฯฮฝ.
+settings.transfer_quota_exceeded = ฮ ฮฝฮญฮฟฯ ฮนฮดฮนฮฟฮบฯฮฎฯฮทฯ (%s) ฮญฯฮตฮน ฯ
ฯฮตฯฮฒฮตฮฏ ฯฮฟฯ
ฯ ฮดฮนฮฑฮธฮญฯฮนฮผฮฟฯ
ฯ ฯฯฯฮฟฯ
ฯ ฯฮฟฯ
. ฮคฮฟ repository ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮผฮตฯฮฑฯฮตฯฮธฮตฮฏ.
+release.asset_name = ฮฮฝฮฟฮผฮฑ ฮฑฯฯฮตฮฏฮฟฯ
+release.asset_external_url = ฮฮพฯฯฮตฯฮนฮบฯ URL
+release.invalid_external_url = ฮฮท ฮญฮณฮบฯ
ฯฮฟ ฮตฮพฯฯฮตฯฮนฮบฯ URL: ยซ%sยป
+no_eol.text = ฮฮตฮฏฯฮตฮน ฯฮฟ EOL
+activity.commit = ฮฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฑ commit
+no_eol.tooltip = ฮฯ
ฯฯ ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฮดฮตฮฝ ฯฮตฯฮนฮญฯฮตฮน ฮญฮฝฮฑฮฝ ฯฮฑฯฮฑฮบฯฮฎฯฮฑ ฯฯฯฮฟฯ
ฮตฯฮนฯฯฯฮฟฯฮฎฯ ฯฮฟฯฮญฮฑ (ยซend of lineยป) ฯฯฮฟ ฯฮญฮปฮฟฯ ฯฮฟฯ
ฮฑฯฯฮตฮฏฮฟฯ
.
+release.add_external_asset = ฮ ฯฮฟฯฮธฮฎฮบฮท ฮตฮพฯฯฮตฯฮนฮบฮฟฯ ฮฑฯฯฮตฮฏฮฟฯ
+milestones.filter_sort.name = ฮฮฝฮฟฮผฮฑ
+release.type_external_asset = ฮฮพฯฯฮตฯฮนฮบฯ ฮฑฯฯฮตฮฏฮฟ
+mirror_public_key = ฮฮทฮผฯฯฮนฮฟ ฮบฮปฮตฮนฮดฮฏ SSH
+mirror_use_ssh.helper = ฯฮฟ Forgejo ฮธฮฑ ฮบฮฑฯฮฟฯฯฯฮฏฯฮตฮน ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮผฮญฯฯ Git ฮผฮต ฯฮท ฯฯฮฎฯฮท SSH ฮบฮฑฮน ฮธฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฮน ฮญฮฝฮฑ ฮถฮตฯฮณฮฟฯ ฮบฮปฮตฮนฮดฮนฯฮฝ. ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮตฮพฮฑฯฯฮฑฮปฮฏฯฮตฯฮต ฯฯฯ ฯฮฟ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮทฮผฮญฮฝฮฟ ฮบฮปฮตฮนฮดฮฏ ฮตฮฏฮฝฮฑฮน ฮตฮพฮฟฯ
ฯฮนฮฟฮดฮฟฯฮทฮผฮญฮฝฮฟ ฮฝฮฑ ฯฮธฮตฮฏ ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฯฯฮฟฮฟฯฮนฯฮผฮฟฯ. ฮฯฯฯฮฟฮฝ ฯฮฟ ฮญฯฮตฯฮต ฮตฯฮนฮปฮญฮพฮตฮน, ฮดฮต ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฯฮต ฮตฮพฮฟฯ
ฯฮนฮฟฮดฯฯฮทฯฮท ฯฯ
ฮฝฮธฮทฮผฮฑฯฮนฮบฮฟฯ.
+issues.all_title = ฮฮปฮฑ
+editor.add_tmpl.filename = ฮฮฝฮฟฮผฮฑ ฮฑฯฯฮตฮฏฮฟฯ
+editor.commit_email = Email ฮณฮนฮฑ commit
+mirror_use_ssh.not_available = ฮ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮท ฮผฮญฯฯ SSH ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮท.
+new_from_template = ฮงฯฮฎฯฮท ฯฯฮฟฯฯฯฮฟฯ
+new_from_template_description = ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฯฮต ฮญฮฝฮฑ ฯฯฮฟฯ
ฯฮฌฯฯฮฟฮฝ ฯฯฯฯฯ
ฯฮฟ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮบฮฑฮน ฮฝฮฑ ฮตฯฮฑฯฮผฯฯฮตฯฮต ฯฮนฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฮฟฯ
.
+new_advanced = ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮณฮนฮฑ ฯฯฮฟฯฯฯฮทฮผฮญฮฝฮฟฯ
ฯ
+new_advanced_expand = ฮฮปฮนฮบ ฮณฮนฮฑ ฮตฯฮญฮบฯฮฑฯฮท
+auto_init_description = ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฑฯฯฮนฮบฮฟฯ commit ฯฮฟฯ
ฯฮตฯฮนฮญฯฮตฮน ฮญฮฝฮฑ ฮฑฯฯฮตฮฏฮฟ README, ฮผฮฑฮถฮฏ ฮผฮต ฯฮฑ ฮฑฯฯฮตฮฏฮฑ ฮฌฮดฮตฮนฮฑฯ ฯฯฮฎฯฮทฯ ฮบฮฑฮน .gitignore ฯฯฮฟฮฑฮนฯฮตฯฮนฮบฮฌ.
+summary_card_alt = ฮฮฌฯฯฮฑ ฯฯฮฝฮฟฯฮทฯ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
%s
+archive.pull.noreview = ฮฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮญฯฮตฮน ฮฑฯฯฮตฮนฮฟฮธฮตฯฮทฮธฮตฮฏ. ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮพฮนฮฟฮปฮฟฮณฮฎฯฮตฯฮต pull requests.
+mirror_denied_combination = ฮ ฯฯฮฎฯฮท ฮตฮฝฯฯ ฮบฮปฮตฮนฮดฮนฮฟฯ ฮบฮฑฮธฯฯ ฮบฮฑฮน ฮตฮฝฯฯ ฮบฯฮดฮนฮบฮฟฯ ฮณฮนฮฑ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮท ฯฮฑฯ
ฯฯฯฯฮฟฮฝฮฑ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ.
+mirror_use_ssh.text = ฮงฯฮฎฯฮท ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮทฯ SSH
+commits.view_single_diff = ฮ ฯฮฟฮฒฮฟฮปฮฎ ฮฑฮปฮปฮฑฮณฯฮฝ ฮฑฯฯฮตฮฏฮฟฯ
ฯฮฟฯ
ฯฯฮฟฮบฮปฮฎฮธฮทฮบฮฑฮฝ ฮฑฯฯ ฮฑฯ
ฯฯ ฯฮฟ commit
[graphs]
component_loading_failed = ฮฮตฮฝ ฮฎฯฮฑฮฝ ฮดฯ
ฮฝฮฑฯฮฎ ฮท ฯฯฯฯฯฯฮท ฯฮฟฯ
%s
@@ -2729,7 +2862,7 @@ component_loading = ฮฮฏฮฝฮตฯฮฑฮน ฯฯฯฯฯฯฮท ฯฮฟฯ
%s...
component_loading_info = ฮฯ
ฯฯ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฮฌฯฮตฮน ฮปฮฏฮณฮท ฯฯฮฑโฆ
component_failed_to_load = ฮ ฯฮฟฮญฮบฯ
ฯฮต ฮญฮฝฮฑ ฮฑฯฯฯฯฮผฮตฮฝฮฟ ฯฯฮฌฮปฮผฮฑ.
contributors.what = ฯฯ
ฮฝฮตฮนฯฯฮฟฯฮญฯ
-recent_commits.what = ฯฯฯฯฯฮฑฯฮตฯ ฯ
ฯฮฟฮฒฮฟฮปฮญฯ
+recent_commits.what = ฯฯฯฯฯฮฑฯฮฑ commit
code_frequency.what = ฯฯ
ฯฮฝฯฯฮทฯฮฑ ฮบฯฮดฮนฮบฮฑ
[org]
@@ -2791,24 +2924,24 @@ settings.labels_desc=ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฮทฮผฮฌฯฯฮฝ ฯฮฟฯ
ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ
members.membership_visibility=ฮฯฮฑฯฯฯฮทฯฮฑ ฮผฮญฮปฮฟฯ
ฯ:
members.public=ฮฯฮฑฯฯ
-members.public_helper=ฮบฮฌฮฝฮต ฯฮฟ ฮบฯฯ
ฯฯ
+members.public_helper=ฮฑฯฯฮบฯฯ
ฯฮท
members.private=ฮฯฯ
ฯฯ
-members.private_helper=ฮบฮฌฮฝฮต ฮฟฯฮฑฯฯ
+members.private_helper=ฮฝฮฑ ฮณฮฏฮฝฮตฮน ฮฟฯฮฑฯฮฎ
members.member_role=ฮกฯฮปฮฟฯ ฮผฮญฮปฮฟฯ
ฯ:
members.owner=ฮฮดฮนฮฟฮบฯฮฎฯฮทฯ
members.member=ฮฮญฮปฮฟฯ
members.remove=ฮฯฮฑฮฏฯฮตฯฮท
members.remove.detail=ฮฯฮฑฮนฯฮญฯฯฮต ฯฮฟ %[1]s ฮฑฯฯ %[2]s;
members.leave=ฮฯฮฟฯฯฯฮทฯฮท
-members.leave.detail=ฮฯฮฟฯฯฯฮทฯฮท ฮฑฯฯ %s;
+members.leave.detail=ฮฃฮฏฮณฮฟฯ
ฯฮฑ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฮฑฯฮฟฯฯฯฮฎฯฮตฯฮต ฮฑฯฯ ฯฮฟฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ %s;
members.invite_desc=ฮ ฯฮฟฯฮธฮญฯฯฮต ฮญฮฝฮฑ ฮฝฮญฮฟ ฮผฮญฮปฮฟฯ ฯฯฮฟ %s:
members.invite_now=ฮฯฮฟฯฯฮฟฮปฮฎ ฯฯฯฯฮบฮปฮทฯฮทฯ
teams.join=ฮฃฯ
ฮผฮผฮตฯฮฟฯฮฎ
teams.leave=ฮฯฮฟฯฯฯฮทฯฮท
-teams.leave.detail=ฮฯฮฟฯฯฯฮทฯฮท ฮฑฯฯ ฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ %s;
+teams.leave.detail=ฮฃฮฏฮณฮฟฯ
ฯฮฑ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฮฑฯฮฟฯฯฯฮฎฯฮตฯฮต ฮฑฯฯ ฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ %s;
teams.can_create_org_repo=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ
-teams.can_create_org_repo_helper=ฮคฮฑ ฮผฮญฮปฮท ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮฟฯ
ฮฝ ฮฝฮญฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฯฮฟฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ. ฮ ฮดฮทฮผฮนฮฟฯ
ฯฮณฯฯ ฮธฮฑ ฮฑฯฮฟฮบฯฮฎฯฮตฮน ฯฯฯฯฮฒฮฑฯฮท ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฯฮฟ ฮฝฮญฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+teams.can_create_org_repo_helper=ฮคฮฑ ฮผฮญฮปฮท ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮฟฯ
ฮฝ ฮฝฮญฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฯฮฟฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ. ฮ ฮดฮทฮผฮนฮฟฯ
ฯฮณฯฯ ฮธฮฑ ฮฑฯฮฟฮบฯฮฎฯฮตฮน ฯฯฯฯฮฒฮฑฯฮท ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฯฮฟ ฮฝฮญฮฟ repository.
teams.none_access=ฮฮฑฮผฮฏฮฑ ฯฯฯฯฮฒฮฑฯฮท
teams.none_access_helper=ฮคฮฑ ฮผฮญฮปฮท ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮฟฯ
ฮฝ ฮฎ ฮฝฮฑ ฮบฮฌฮฝฮฟฯ
ฮฝ ฮฟฯฮฟฮนฮฑฮดฮฎฯฮฟฯฮต ฮฌฮปฮปฮท ฮตฮฝฮญฯฮณฮตฮนฮฑ ฯฮต ฮฑฯ
ฯฮฎ ฯฮท ฮผฮฟฮฝฮฌฮดฮฑ.
teams.general_access=ฮฮตฮฝฮนฮบฮฎ ฯฯฯฯฮฒฮฑฯฮท
@@ -2829,7 +2962,7 @@ teams.add_team_member=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮผฮญฮปฮฟฯ
ฯ ฮฟฮผฮฌฮดฮฑฯ
teams.invite_team_member=ฮ ฯฯฯฮบฮปฮทฯฮท ฯฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ %s
teams.invite_team_member.list=ฮฮบฮบฯฮตฮผฮตฮฏฯ ฯฯฮฟฯฮบฮปฮฎฯฮตฮนฯ
teams.delete_team_title=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮฟฮผฮฌฮดฮฑฯ
-teams.delete_team_desc=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮผฮนฮฑฯ ฮฟฮผฮฌฮดฮฑฯ ฮฑฮฝฮฑฮบฮฑฮปฮตฮฏ ฯฮท ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮฑฯฯ ฯฮฑ ฮผฮญฮปฮท ฯฮทฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
+teams.delete_team_desc=ฮ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฮผฮนฮฑฯ ฮฟฮผฮฌฮดฮฑฯ ฮฑฮฝฮฑฮบฮฑฮปฮตฮฏ ฯฮท ฯฯฯฯฮฒฮฑฯฮท ฯฯฮฟ repository ฮฑฯฯ ฯฮฑ ฮผฮญฮปฮท ฯฮทฯ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
teams.delete_team_success=ฮ ฮฟฮผฮฌฮดฮฑ ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
teams.read_permission_desc=ฮฯ
ฯฮฎ ฮท ฮฟฮผฮฌฮดฮฑ ฯฮฟฯฮทฮณฮตฮฏ ฯฯฯฯฮฒฮฑฯฮท ฮฮฝฮฌฮณฮฝฯฯฮทฯ : ฯฮฑ ฮผฮญฮปฮท ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮฟฯ
ฮฝ ฮบฮฑฮน ฮฝฮฑ ฮบฮปฯฮฝฮฟฯฮฟฮนฮฎฯฮฟฯ
ฮฝ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ.
teams.write_permission_desc=ฮฯ
ฯฮฎ ฮท ฮฟฮผฮฌฮดฮฑ ฯฮฟฯฮทฮณฮตฮฏ ฯฯฯฯฮฒฮฑฯฮท ฮฮณฮณฯฮฑฯฮฎฯ : ฯฮฑ ฮผฮญฮปฮท ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮนฮฑฮฒฮฌฯฮฟฯ
ฮฝ ฮบฮฑฮน ฮฝฮฑ ฮบฮฌฮฝฮฟฯ
ฮฝ push ฯฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ.
@@ -2841,9 +2974,9 @@ teams.remove_all_repos_title=ฮฯฮฑฮฏฯฮตฯฮท ฯฮปฯฮฝ ฯฯฮฝ ฮฑฯฮฟฮธฮตฯฮทฯฮฏ
teams.remove_all_repos_desc=ฮฯ
ฯฯ ฮธฮฑ ฮฑฯฮฑฮนฯฮญฯฮตฮน ฯฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฮฑฯฯ ฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ.
teams.add_all_repos_title=ฮ ฯฮฟฯฮธฮฎฮบฮท ฯฮปฯฮฝ ฯฯฮฝ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ
teams.add_all_repos_desc=ฮฯ
ฯฯ ฮธฮฑ ฯฯฮฟฯฮธฮญฯฮตฮน ฯฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ ฯฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ.
-teams.add_nonexistent_repo=ฮคฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฯฮฟฯ
ฯฯฮฟฯฯฮฑฮธฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฯฮธฮญฯฮตฯฮต ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน, ฯฮฑฯฮฑฮบฮฑฮปฯ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฯฮฟ ฯฯฯฯฮฑ.
+teams.add_nonexistent_repo=ฮคฮฟ repository ฯฮฟฯ
ฯฯฮฟฯฯฮฑฮธฮตฮฏฯฮต ฮฝฮฑ ฯฯฮฟฯฮธฮญฯฮตฯฮต ฮดฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน, ฯฮฑฯฮฑฮบฮฑฮปฯ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฯฮฟ ฯฯฯฯฮฑ.
teams.add_duplicate_users=ฮ ฯฯฮฎฯฯฮทฯ ฮตฮฏฮฝฮฑฮน ฮฎฮดฮท ฮผฮญฮปฮฟฯ ฯฮทฯ ฮฟฮผฮฌฮดฮฑฯ.
-teams.repos.none=ฮฯ
ฯฮฎ ฮท ฮฟฮผฮฌฮดฮฑ ฮดฮตฮฝ ฮญฯฮตฮน ฯฯฯฯฮฒฮฑฯฮท ฯฮต ฮบฮฑฮฝฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+teams.repos.none=ฮฯ
ฯฮฎ ฮท ฮฟฮผฮฌฮดฮฑ ฮดฮตฮฝ ฮญฯฮตฮน ฯฯฯฯฮฒฮฑฯฮท ฯฮต ฮบฮฑฮฝฮญฮฝฮฑ repository.
teams.members.none=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮผฮญฮปฮท ฯฮต ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ.
teams.specific_repositories=ฮฃฯ
ฮณฮบฮตฮบฯฮนฮผฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ
teams.specific_repositories_helper=ฮคฮฑ ฮผฮญฮปฮท ฮธฮฑ ฮญฯฮฟฯ
ฮฝ ฯฯฯฯฮฒฮฑฯฮท ฮผฯฮฝฮฟ ฯฮต ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
ฯฯฮฟฯฯฮฏฮธฮตฮฝฯฮฑฮน ฯฮทฯฮฌ ฯฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ. ฮฯฮนฮปฮญฮณฮฟฮฝฯฮฑฯ ฯฮฟ ฮดฮตฮฝ ฮธฮฑ ฮธฮฑ ฮฑฯฮฑฮนฯฮตฮธฮฟฯฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
ฮญฯฮฟฯ
ฮฝ ฮฎฮดฮท ฯฯฮฟฯฯฮตฮธฮตฮฏ ฮผฮต ฯฮฟ ฮฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ .
@@ -2855,7 +2988,8 @@ teams.all_repositories_admin_permission_desc=ฮฯ
ฯฮฎ ฮท ฮฟฮผฮฌฮดฮฑ ฯฮฑฯฮญฯฮต
teams.invite.title=ฮฯฮตฯฮต ฯฯฮฟฯฮบฮปฮทฮธฮตฮฏ ฮฝฮฑ ฯฯ
ฮผฮผฮตฯฮฌฯฯฮตฯฮต ฯฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ %s ฯฮฟฯ
ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ %s .
teams.invite.by=ฮ ฯฮฟฯฮบฮปฮฎฮธฮทฮบฮต ฮฑฯฯ %s
teams.invite.description=ฮ ฮฑฯฮฑฮบฮฑฮปฯ ฮบฮฌฮฝฯฮต ฮบฮปฮนฮบ ฯฯฮฟฮฝ ฯฮฑฯฮฑฮบฮฌฯฯ ฯฯฮฝฮดฮตฯฮผฮฟ ฮณฮนฮฑ ฯฯ
ฮผฮผฮตฯฮฟฯฮฎ ฯฯฮทฮฝ ฮฟฮผฮฌฮดฮฑ.
-follow_blocked_user = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮบฮฟฮปฮฟฯ
ฮธฮฎฯฮตฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ, ฮตฯฮตฮนฮดฮฎ ฮฟ ฮฟฯฮณฮฑฮฝฮนฯฮผฯฯ ฯฮฑฯ ฮญฯฮตฮน ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฮน.
+follow_blocked_user = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฑฮบฮฟฮปฮฟฯ
ฮธฮฎฯฮตฯฮต ฯฮฟฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯ, ฮตฯฮตฮนฮดฮฎ ฯฮฑฯ ฮญฯฮตฮน ฮฑฯฮฟฮบฮปฮตฮฏฯฮตฮน.
+open_dashboard = ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฯฮฏฮฝฮฑฮบฮฑ ฮดฯฮฑฯฯฮทฯฮนฯฯฮทฯฮฑฯ
[admin]
dashboard=ฮ ฮฏฮฝฮฑฮบฮฑฯ ฮฮปฮญฮณฯฮฟฯ
@@ -2876,7 +3010,7 @@ last_page=ฮคฮตฮปฮตฯ
ฯฮฑฮฏฮฑ
total=ฮฃฯฮฝฮฟฮปฮฟ: %d
settings=ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ
-dashboard.new_version_hint=ฮคฮฟ Forgejo %s ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮฟ, ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮต ฯฮฟ %s. ฮฮฝฮฑฯฯฮญฮพฯฮต ฯฯฮฟ blog ฮณฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฮปฮตฯฯฮฟฮผฮญฯฮตฮนฮตฯ.
+dashboard.new_version_hint=ฮคฮฟ Forgejo %s ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮฟ, ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮต ฯฮฟ %s. ฮฮฝฮฑฯฯฮญฮพฯฮต ฯฯฮฟ blog ฮณฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฮปฮตฯฯฮฟฮผฮญฯฮตฮนฮตฯ.
dashboard.statistic=ฮ ฮตฯฮฏฮปฮทฯฮท
dashboard.operations=ฮฮตฮนฯฮฟฯ
ฯฮณฮฏฮตฯ ฯฯ
ฮฝฯฮฎฯฮทฯฮทฯ
dashboard.system_status=ฮฮฑฯฮฌฯฯฮฑฯฮท ฯฯ
ฯฯฮฎฮผฮฑฯฮฟฯ
@@ -2920,7 +3054,7 @@ dashboard.cleanup_hook_task_table=ฮฮบฮบฮฑฮธฮฌฯฮนฯฮท ฯฮฏฮฝฮฑฮบฮฑ hook_task
dashboard.cleanup_packages=ฮฮบฮบฮฑฮธฮฌฯฮนฯฮท ฮปฮทฮณฮผฮญฮฝฯฮฝ ฯฮฑฮบฮญฯฯฮฝ
dashboard.cleanup_actions=ฮฮฑฮธฮฑฯฮนฯฮผฯฯ ฯฮฑฮปฮนฯฮฝ ฮฑฯฯฮตฮฏฯฮฝ ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฮบฮฑฮน ฯฯฮฟฯฯฮฝฯฯฮฝ ฮฑฯฯ Actions
dashboard.server_uptime=Uptime ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ
-dashboard.current_goroutine=ฮคฯฮญฯฮฟฯ
ฯฮตฯ Goroutines
+dashboard.current_goroutine=ฮคฯฮญฯฮฟฯ
ฯฮตฯ goroutines
dashboard.current_memory_usage=ฮคฯฮญฯฮฟฯ
ฯฮฑ ฯฯฮฎฯฮท ฮผฮฝฮฎฮผฮทฯ
dashboard.total_memory_allocated=ฮฃฯ
ฮฝฮฟฮปฮนฮบฮฎ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฟฯฮผฮตฮฝฮท ฮผฮฝฮฎฮผฮท
dashboard.memory_obtained=ฮฮฝฮฎฮผฮท ฯฮฟฯ
ฮปฮฑฮผฮฒฮฌฮฝฮตฯฮฑฮน
@@ -2957,7 +3091,7 @@ dashboard.stop_zombie_tasks=ฮฮนฮฑฮบฮฟฯฮฎ ฮตฯฮณฮฑฯฮนฯฮฝ ฮถฯฮผฯฮน
dashboard.stop_endless_tasks=ฮฮนฮฑฮบฮฟฯฮฎ ฮฑฯฮตฮปฮตฮฏฯฯฯฮฝ ฮตฯฮณฮฑฯฮนฯฮฝ
dashboard.cancel_abandoned_jobs=ฮฮบฯฯฯฯฮท ฮตฮณฮบฮฑฯฮฑฮปฮตฮปฮตฮนฮผฮผฮญฮฝฯฮฝ ฮตฯฮณฮฑฯฮนฯฮฝ
dashboard.start_schedule_tasks=ฮฮฝฮฑฯฮพฮท ฯฯฮฟฮณฯฮฑฮผฮผฮฑฯฮนฯฮผฮญฮฝฯฮฝ ฮตฯฮณฮฑฯฮนฯฮฝ
-dashboard.sync_branch.started=ฮ ฮฃฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯฯ ฯฯฮฝ ฮฮปฮฌฮดฯฮฝ ฮพฮตฮบฮฏฮฝฮทฯฮต
+dashboard.sync_branch.started=ฮฮตฮบฮฏฮฝฮทฯฮต ฮฟ ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯฯ ฯฯฮฝ ฮบฮปฮฌฮดฯฮฝ
dashboard.rebuild_issue_indexer=ฮฮฝฮฑฮดฯฮผฮทฯฮท ฮตฯ
ฯฮตฯฮทฯฮฏฮฟฯ
ฮถฮทฯฮทฮผฮฌฯฯฮฝ
users.user_manage_panel=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฮฝ ฯฯฮทฯฯฯฮฝ
@@ -2975,7 +3109,7 @@ users.repos=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฑ
users.created=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต
users.last_login=ฮคฮตฮปฮตฯ
ฯฮฑฮฏฮฑ ฯฯฮฝฮดฮตฯฮท
users.never_login=ฮฮฑฮผฮฏฮฑ ฯฯฮฝฮดฮตฯฮท
-users.send_register_notify=ฮฯฮฟฯฯฮฟฮปฮฎ ฮตฮนฮดฮฟฯฮฟฮนฮฎฯฮตฯฮฝ ฮตฮณฮณฯฮฑฯฮฎฯ ฯฯฮฎฯฯฮท
+users.send_register_notify=ฮฮฑ ฮณฮฏฮฝฮตฯฮฑฮน ฮฑฯฮฟฯฯฮฟฮปฮฎ ฮตฮนฮดฮฟฯฮฟฮนฮฎฯฮตฯฮฝ ฮตฮณฮณฯฮฑฯฮฎฯ ฮฝฮญฯฮฝ ฯฯฮทฯฯฯฮฝ ฮผฮญฯฯ email
users.new_success=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฯฮฎฯฯฮท ยซ%sยป ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต.
users.edit=ฮฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ
users.auth_source=ฮ ฮทฮณฮฎ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮทฯ
@@ -2986,10 +3120,10 @@ users.update_profile_success=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฯฮฎฯฯฮท ฮญฯฮตฮน ฮต
users.edit_account=ฮฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฯฯฮฎฯฯฮท
users.max_repo_creation=ฮฮญฮณฮนฯฯฮฟฯ ฮฑฯฮนฮธฮผฯฯ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ
users.max_repo_creation_desc=(ฮฯฮฏฯฯฮต -1 ฮณฮนฮฑ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮฟ ฯฯฮฟฮบฮฑฮธฮฟฯฮนฯฮผฮญฮฝฮฟ ฯฯฮนฮฟ.)
-users.is_activated=ฮ ฮฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฮงฯฮฎฯฯฮท ฮฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฮธฮทฮบฮต
-users.prohibit_login=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮตฮนฯฯฮดฮฟฯ
-users.is_admin=ฮฮฏฮฝฮฑฮน ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ
-users.is_restricted=ฮฮฏฮฝฮฑฮน ฯฮตฯฮนฮฟฯฮนฯฮผฮญฮฝฮฟฯ
+users.is_activated=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฯฮฎฯฯฮท ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฮธฮทฮบฮต
+users.prohibit_login=ฮฮฝฮตฯฯฮฑฮปฮผฮญฮฝฮฟฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ
+users.is_admin=ฮฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ
+users.is_restricted=ฮ ฮตฯฮนฮฟฯฮนฯฮผฮญฮฝฮฟฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ
users.allow_git_hook=ฮฯฮฟฯฮตฮฏ ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮตฮฏ Git hooks
users.allow_git_hook_tooltip=ฮคฮฑ Git hooks ฮตฮบฯฮตฮปฮฟฯฮฝฯฮฑฮน ฮผฮญฯฯ ฯฮฟฯ
ฯฯฮฎฯฯฮท ฯฮฟฯ
ฮตฮบฯฮตฮปฮตฮฏ ฯฮฟ Forgejo ฮบฮฑฮน ฮธฮฑ ฮญฯฮฟฯ
ฮฝ ฯฮฟ ฮฏฮดฮนฮฟ ฮตฯฮฏฯฮตฮดฮฟ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฯฮฟ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ. ฮฉฯ ฮฑฯฮฟฯฮญฮปฮตฯฮผฮฑ, ฮฟฮน ฯฯฮฎฯฯฮตฯ ฮผฮต ฮฑฯ
ฯฯ ฯฮฟ ฮตฮนฮดฮนฮบฯ ฯฯฮฟฮฝฯฮผฮนฮฟ Git hook ฮธฮฑ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮญฯฮฟฯ
ฮฝ ฯฯฯฯฮฒฮฑฯฮท ฮบฮฑฮน ฮฝฮฑ ฯฯฮฟฯฮฟฯฮฟฮนฮฎฯฮฟฯ
ฮฝ ฯฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
Forgejo, ฮบฮฑฮธฯฯ ฮบฮฑฮน ฯฮท ฮฒฮฌฯฮท ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฯฮฟฯ
ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏ ฯฮฟ Forgejo. ฮฮฑฯฮฌ ฯฯ
ฮฝฮญฯฮตฮนฮฑ, ฮฑฯ
ฯฮฟฮฏ ฮฟฮน ฯฯฮฎฯฯฮตฯ ฮธฮฑ ฮตฮฏฮฝฮฑฮน ฯฮต ฮธฮญฯฮท ฮฝฮฑ ฮฑฯฮฟฮบฯฮฎฯฮฟฯ
ฮฝ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฯฮฟ Forgejo.
users.allow_import_local=ฮฯฮฟฯฮตฮฏ ฮฝฮฑ ฮตฮนฯฮฌฮณฮตฮน ฯฮฟฯฮนฮบฮฌ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ
@@ -2999,7 +3133,7 @@ users.delete_account=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฯฯฮฎฯฯฮท
users.cannot_delete_self=ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮต ฯฮฟฮฝ ฮตฮฑฯ
ฯฯ ฯฮฑฯ
users.still_own_repo=ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮตฮพฮฑฮบฮฟฮปฮฟฯ
ฮธฮตฮฏ ฮฝฮฑ ฮบฮฑฯฮญฯฮตฮน ฮญฮฝฮฑ ฮฎ ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ. ฮฮนฮฑฮณฯฮฌฯฯฮต ฮฎ ฮผฮตฯฮฑฯฮญฯฮตฯฮต ฮฑฯ
ฯฮฌ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฯฯฯฮฑ.
users.still_has_org=ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮตฮฏฮฝฮฑฮน ฮผฮญฮปฮฟฯ ฮตฮฝฯฯ ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ. ฮฯฮฑฮนฯฮญฯฯฮต ฯฯฯฯฮฑ ฯฮฟฮฝ ฯฯฮฎฯฯฮท ฮฑฯฯ ฮฟฯฮฟฮนฮฟฮฝฮดฮฎฯฮฟฯฮต ฮฟฯฮณฮฑฮฝฮนฯฮผฯ.
-users.purge=ฮฮบฮบฮฑฮธฮฌฯฮนฯฮท ฮงฯฮฎฯฯฮท
+users.purge=ฮฮนฮฑฮณฯฮฑฯฮฎ ฯฯฮฎฯฯฮท
users.purge_help=ฮฮพฮฑฮฝฮฑฮณฮบฮฑฯฯฮนฮบฮฎ ฮดฮนฮฑฮณฯฮฑฯฮฎ ฯฯฮฎฯฯฮท ฮบฮฑฮธฯฯ ฮบฮฑฮน ฯฯฮฝ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ, ฮฟฯฮณฮฑฮฝฮนฯฮผฯฮฝ ฮบฮฑฮน ฯฮฑฮบฮญฯฯฮฝ ฯฮฟฯ
ฯฮฟฯ
ฮฑฮฝฮฎฮบฮฟฯ
ฮฝ. ฮฮปฮฑ ฯฮฑ ฯฯฯฮปฮนฮฑ ฮบฮฑฮน ฯฮฑ ฮถฮทฯฮฎฮผฮฑฯฮฑ ฯฮฟฯ
ฯฯฮฎฯฯฮท ฮธฮฑ ฮดฮนฮฑฮณฯฮฑฯฮฟฯฮฝ ฮตฯฮฏฯฮทฯ.
users.still_own_packages=ฮฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮตฮพฮฑฮบฮฟฮปฮฟฯ
ฮธฮตฮฏ ฮฝฮฑ ฮบฮฑฯฮญฯฮตฮน ฮญฮฝฮฑ ฮฎ ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฯฮฑฮบฮญฯฮฑ, ฮดฮนฮฑฮณฯฮฌฯฯฮต ฮฑฯ
ฯฮฌ ฯฮฑ ฯฮฑฮบฮญฯฮฑ ฯฯฯฯฮฑ.
users.deletion_success=ฮ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฯฮฎฯฯฮท ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
@@ -3009,14 +3143,14 @@ users.list_status_filter.reset=ฮฯฮฑฮฝฮฑฯฮฟฯฮฌ
users.list_status_filter.is_active=ฮฮฝฮตฯฮณฯ
users.list_status_filter.not_active=ฮฮฝฮตฮฝฮตฯฮณฯ
users.list_status_filter.is_admin=ฮฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ
-users.list_status_filter.not_admin=ฮฮท ฮฮนฮฑฯฮตฮนฯฮนฯฯฮฎฯ
+users.list_status_filter.not_admin=ฮงฯฯฮฏฯ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ
users.list_status_filter.is_restricted=ฮ ฮตฯฮนฮฟฯฮนฯฮผฮญฮฝฮฟฯ
-users.list_status_filter.not_restricted=ฮฮท ฮ ฮตฯฮนฮฟฯฮนฯฮผฮญฮฝฮฟฯ
-users.list_status_filter.is_prohibit_login=ฮฯฮฑฮณฯฯฮตฯ
ฯฮท ฮฃฯฮฝฮดฮตฯฮทฯ
-users.list_status_filter.not_prohibit_login=ฮฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฮฃฯฮฝฮดฮตฯฮท
-users.list_status_filter.is_2fa_enabled=2FA ฮฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮฟ
-users.list_status_filter.not_2fa_enabled=2FA ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮฟ
-users.details=ฮฮตฯฯฮฟฮผฮญฯฮตฮนฮตฯ ฮงฯฮฎฯฯฮท
+users.list_status_filter.not_restricted=ฮงฯฯฮฏฯ ฯฮตฯฮนฮฟฯฮนฯฮผฮฟฯฯ
+users.list_status_filter.is_prohibit_login=ฮฯฮฑฮณฮฟฯฮตฯ
ฮผฮญฮฝฮท ฯฯฮฝฮดฮตฯฮท
+users.list_status_filter.not_prohibit_login=ฮฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฯฯฮฝฮดฮตฯฮท
+users.list_status_filter.is_2fa_enabled=ฮฮต ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮฟ 2FA
+users.list_status_filter.not_2fa_enabled=ฮงฯฯฮฏฯ 2FA
+users.details=ฮฮตฯฯฮฟฮผฮญฯฮตฮนฮตฯ ฯฯฮฎฯฯฮท
emails.email_manage_panel=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท email ฯฯฮทฯฯฯฮฝ
emails.primary=ฮฯฯฮนฮฟ
@@ -3051,8 +3185,8 @@ repos.size=ฮฮญฮณฮตฮธฮฟฯ
repos.lfs_size=ฮฮญฮณฮตฮธฮฟฯ LFS
packages.package_manage_panel=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฯฮฑฮบฮญฯฯฮฝ
-packages.total_size=ฮฃฯ
ฮฝฮฟฮปฮนฮบฯ ฮฮญฮณฮตฮธฮฟฯ: %s
-packages.unreferenced_size=ฮฮญฮณฮตฮธฮฟฯ ฮงฯฯฮฏฯ ฮฮฝฮฑฯฮฟฯฮฌ: %s
+packages.total_size=ฮฃฯ
ฮฝฮฟฮปฮนฮบฯ ฮผฮญฮณฮตฮธฮฟฯ: %s
+packages.unreferenced_size=ฮฮญฮณฮตฮธฮฟฯ ฯฯฯฮฏฯ ฮฑฮฝฮฑฯฮฟฯฮฌ: %s
packages.cleanup=ฮฮบฮบฮฑฮธฮฌฯฮนฯฮท ฮปฮทฮณฮผฮญฮฝฯฮฝ ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ
packages.cleanup.success=ฮฯฮนฯฯ
ฯฮฎฯ ฮตฮบฮบฮฑฮธฮฌฯฮนฯฮท ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฯฮฟฯ
ฮญฯฮฟฯ
ฮฝ ฮปฮฎฮพฮตฮน
packages.owner=ฮฮดฮนฮฟฮบฯฮฎฯฮทฯ
@@ -3060,17 +3194,17 @@ packages.creator=ฮฮทฮผฮนฮฟฯ
ฯฮณฯฯ
packages.name=ฮฮฝฮฟฮผฮฑ
packages.version=ฮฮบฮดฮฟฯฮท
packages.type=ฮคฯฯฮฟฯ
-packages.repository=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+packages.repository=Repository
packages.size=ฮฮญฮณฮตฮธฮฟฯ
packages.published=ฮฮทฮผฮฟฯฮนฮตฯ
ฮผฮญฮฝฮฑ
defaulthooks=ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฑ webhooks
-defaulthooks.desc=ฮคฮฑ Webhooks ฮบฮฌฮฝฮฟฯ
ฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฮฑฮนฯฮฎฯฮตฮนฯ HTTP POST ฯฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฯฮฑฮฝ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฟฯฮฝ ฮฟฯฮนฯฮผฮญฮฝฮฑ ฮณฮตฮณฮฟฮฝฯฯฮฑ ฯฯฮฟ Gitea. ฮคฮฑ Webhooks ฯฮฟฯ
ฮฟฯฮฏฮถฮฟฮฝฯฮฑฮน ฮตฮดฯ ฮตฮฏฮฝฮฑฮน ฯฯฮฟฮบฮฑฮธฮฟฯฮนฯฮผฮญฮฝฮฑ ฮบฮฑฮน ฮธฮฑ ฮฑฮฝฯฮนฮณฯฮฑฯฮฟฯฮฝ ฯฮต ฯฮปฮฑ ฯฮฑ ฮฝฮญฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ. ฮฮนฮฑฮฒฮฌฯฯฮต ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฯฯฮฟฮฝ ฮฟฮดฮทฮณฯ webhooks .
+defaulthooks.desc=ฮคฮฑ Webhooks ฮบฮฌฮฝฮฟฯ
ฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฮฑฮนฯฮฎฯฮตฮนฯ HTTP POST ฯฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฯฮฑฮฝ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฟฯฮฝ ฮฟฯฮนฯฮผฮญฮฝฮฑ ฮณฮตฮณฮฟฮฝฯฯฮฑ ฯฯฮฟ Forgejo. ฮคฮฑ Webhooks ฯฮฟฯ
ฮฟฯฮฏฮถฮฟฮฝฯฮฑฮน ฮตฮดฯ ฮตฮฏฮฝฮฑฮน ฯฯฮฟฮบฮฑฮธฮฟฯฮนฯฮผฮญฮฝฮฑ ฮบฮฑฮน ฮธฮฑ ฮฑฮฝฯฮนฮณฯฮฑฯฮฟฯฮฝ ฯฮต ฯฮปฮฑ ฯฮฑ ฮฝฮญฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ. ฮฮนฮฑฮฒฮฌฯฯฮต ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฯฯฮฟฮฝ ฮฟฮดฮทฮณฯ webhooks .
defaulthooks.add_webhook=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ
Webhook
defaulthooks.update_webhook=ฮฮฝฮทฮผฮญฯฯฯฮท ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟฯ
Webhook
systemhooks=Webhooks ฯฯ
ฯฯฮฎฮผฮฑฯฮฟฯ
-systemhooks.desc=ฮคฮฑ Webhooks ฮบฮฌฮฝฮฟฯ
ฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฮฑฮนฯฮฎฯฮตฮนฯ HTTP POST ฯฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฯฮฑฮฝ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฟฯฮฝฯฮฑฮน ฮฟฯฮนฯฮผฮญฮฝฮฑ ฮณฮตฮณฮฟฮฝฯฯฮฑ ฯฯฮฟ Gitea. ฮคฮฑ Webhooks ฯฮฟฯ
ฮฟฯฮฏฮถฮฟฮฝฯฮฑฮน ฮตฮดฯ ฮธฮฑ ฮตฮฝฮตฯฮณฮฟฯฮฝ ฯฮต ฯฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
ฯฯ
ฯฯฮฎฮผฮฑฯฮฟฯ, ฮณฮน 'ฮฑฯ
ฯฯ ฯฮฑฯฮฑฮบฮฑฮปฯ ฮตฮพฮตฯฮฌฯฯฮต ฯฯ
ฯฯฮฝ ฮตฯฮนฯฯฯฯฮตฮนฯ ฮฑฯฯฮดฮฟฯฮทฯ ฯฮฟฯ
ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮญฯฮตฮน. ฮฮนฮฑฮฒฮฌฯฯฮต ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฯฯฮฟฮฝ ฮฟฮดฮทฮณฯ webhooks .
+systemhooks.desc=ฮคฮฑ Webhooks ฮบฮฌฮฝฮฟฯ
ฮฝ ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฮฑฮนฯฮฎฯฮตฮนฯ HTTP POST ฯฮต ฮญฮฝฮฑ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฯฮฑฮฝ ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฟฯฮฝฯฮฑฮน ฮฟฯฮนฯฮผฮญฮฝฮฑ ฮณฮตฮณฮฟฮฝฯฯฮฑ ฯฯฮฟ Forgejo. ฮคฮฑ Webhooks ฯฮฟฯ
ฮฟฯฮฏฮถฮฟฮฝฯฮฑฮน ฮตฮดฯ ฮธฮฑ ฮตฮฝฮตฯฮณฮฟฯฮฝ ฯฮต ฯฮปฮฑ ฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฮฟฯ
ฯฯ
ฯฯฮฎฮผฮฑฯฮฟฯ, ฮณฮน 'ฮฑฯ
ฯฯ ฯฮฑฯฮฑฮบฮฑฮปฯ ฮตฮพฮตฯฮฌฯฯฮต ฯฯ
ฯฯฮฝ ฮตฯฮนฯฯฯฯฮตฮนฯ ฮฑฯฯฮดฮฟฯฮทฯ ฯฮฟฯ
ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮญฯฮตฮน. ฮฮนฮฑฮฒฮฌฯฯฮต ฯฮตฯฮนฯฯฯฯฮตฯฮฑ ฯฯฮฟฮฝ ฮฟฮดฮทฮณฯ webhooks .
systemhooks.add_webhook=ฮ ฯฮฟฯฮธฮฎฮบฮท Webhook ฮฃฯ
ฯฯฮฎฮผฮฑฯฮฟฯ
systemhooks.update_webhook=ฮฮฝฮทฮผฮญฯฯฯฮท Webhook ฮฃฯ
ฯฯฮฎฮผฮฑฯฮฟฯ
@@ -3098,14 +3232,14 @@ auths.attribute_surname=ฮงฮฑฯฮฑฮบฯฮทฯฮนฯฯฮนฮบฯ ฮตฯฯฮฝฯฮผฮฟฯ
auths.attribute_mail=ฮงฮฑฯฮฑฮบฯฮทฯฮนฯฯฮนฮบฯ email
auths.attribute_ssh_public_key=ฮงฮฑฯฮฑฮบฯฮทฯฮนฯฯฮนฮบฯ ฮดฮทฮผฯฯฮนฮฟฯ
ฮบฮปฮตฮนฮดฮนฮฟฯ SSH
auths.attribute_avatar=ฮงฮฑฯฮฑฮบฯฮทฯฮนฯฯฮนฮบฯ ฮตฮนฮบฯฮฝฮฑฯ
-auths.attributes_in_bind=ฮฮฎฯฮท ฯฮฑฯฮฑฮบฯฮทฯฮนฯฯฮนฮบฯฮฝ ฮผฮญฯฮฑ ฯฯฮฟ ฯฮปฮฑฮฏฯฮนฮฟ ฯฮฟฯ
Bind DN
+auths.attributes_in_bind=ฮฮฎฯฮท ฯฮฑฯฮฑฮบฯฮทฯฮนฯฯฮนฮบฯฮฝ ฮผฮญฯฮฑ ฯฯฮฟ ฯฮปฮฑฮฏฯฮนฮฟ ฯฮฟฯ
bind DN
auths.allow_deactivate_all=ฮฯฮนฯฯฮญฯฯฮต ฯฮต ฮญฮฝฮฑ ฮบฮตฮฝฯ ฮฑฯฮฟฯฮญฮปฮตฯฮผฮฑ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮทฯ ฮฝฮฑ ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฯฮตฮน ฯฮปฮฟฯ
ฯ ฯฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ
auths.use_paged_search=ฮงฯฮฎฯฮท ฯฮตฮปฮนฮดฮฟฯฮฟฮนฮทฮผฮญฮฝฮทฯ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮทฯ
auths.search_page_size=ฮฮญฮณฮตฮธฮฟฯ ฯฮตฮปฮฏฮดฮฑฯ
auths.filter=ฮฆฮฏฮปฯฯฮฟ ฯฯฮทฯฯฯฮฝ
auths.admin_filter=ฮฆฮฏฮปฯฯฮฟ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฯฮฝ
auths.restricted_filter=ฮฆฮฏฮปฯฯฮฟ ฯฮตฯฮนฮฟฯฮนฯฮผฮญฮฝฯฮฝ
-auths.restricted_filter_helper=ฮฯฮฎฯฯฮต ฮบฮตฮฝฯ ฮณฮนฮฑ ฮฝฮฑ ฮผฮทฮฝ ฯฮตฯฮนฮฟฯฮฏฯฮตฯฮต ฮบฮฑฮฝฮญฮฝฮฑฮฝ ฯฯฮฎฯฯฮท. ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฮญฮฝฮฑฮฝ ฮฑฯฯฮตฯฮฏฯฮบฮฟ ('*') ฮณฮนฮฑ ฮฝฮฑ ฯฮตฯฮนฮฟฯฮฏฯฮตฯฮต ฯฮปฮฟฯ
ฯ ฯฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ ฯฮฟฯ
ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮญฯ.
+auths.restricted_filter_helper=ฮฯฮฎฯฯฮต ฮบฮตฮฝฯ ฮณฮนฮฑ ฮฝฮฑ ฮผฮทฮฝ ฯฮตฯฮนฮฟฯฮฏฯฮตฯฮต ฮบฮฑฮฝฮญฮฝฮฑฮฝ ฯฯฮฎฯฯฮท. ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฮญฮฝฮฑฮฝ ฮฑฯฯฮตฯฮฏฯฮบฮฟ (ยซ*ยป) ฮณฮนฮฑ ฮฝฮฑ ฯฮตฯฮนฮฟฯฮฏฯฮตฯฮต ฯฮปฮฟฯ
ฯ ฯฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ ฯฮฟฯ
ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮญฯ.
auths.verify_group_membership=ฮฯฮฑฮปฮฎฮธฮตฯ
ฯฮท ฯฮทฯ ฯฯ
ฮผฮผฮตฯฮฟฯฮฎฯ ฯฮต ฮฟฮผฮฌฮดฮฑ ฯฯฮฟ LDAP (ฮฑฯฮฎฯฯฮต ฯฮฟ ฯฮฏฮปฯฯฮฟ ฮบฮตฮฝฯ ฮณฮนฮฑ ฯฮฑฯฮฌฮปฮตฮนฯฮท)
auths.group_search_base=DN ฮฒฮฌฯฮทฯ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮทฯ ฮฟฮผฮฌฮดฯฮฝ
auths.group_attribute_list_users=ฮงฮฑฯฮฑฮบฯฮทฯฮนฯฯฮนฮบฯ ฮฟฮผฮฌฮดฮฑฯ ฯฮฟฯ
ฯฮตฯฮนฮญฯฮตฮน ฯฮท ฮปฮฏฯฯฮฑ ฯฯฮทฯฯฯฮฝ
@@ -3122,7 +3256,7 @@ auths.allowed_domains_helper=ฮฯฮฎฯฯฮต ฮบฮตฮฝฯ ฮณฮนฮฑ ฮฝฮฑ ฮตฯฮนฯฯฮญฯฮต
auths.skip_tls_verify=ฮ ฮฑฯฮฌฮปฮตฮนฯฮท ฮตฯฮฑฮปฮฎฮธฮตฯ
ฯฮทฯ TLS
auths.force_smtps=ฮฮฝฮฑฮณฮบฮฑฯฯฮนฮบฯ SMTPS
auths.force_smtps_helper=ฮคฮฟ SMTPS ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฯฯ
ฮฝฮฎฮธฯฯ ฯฯฮท ฮธฯฯฮฑ 465. ฮฯฮฏฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฯฮตฮดฮฏฮฟ ฮณฮนฮฑ ฯฯฮฎฯฮท ฯฮฟฯ
SMTPS ฯฮต ฮฌฮปฮปฮตฯ ฮธฯฯฮตฯ. (ฮฮปฮปฮนฯฯ ฯฮฟ STARTTLS ฮธฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฯฮต ฮฌฮปฮปฮตฯ ฮธฯฯฮตฯ ฮฑฮฝ ฯ
ฯฮฟฯฯฮทฯฮฏฮถฮตฯฮฑฮน ฮฑฯฯ ฯฮฟฮฝ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ.)
-auths.helo_hostname=ฮฮฝฮฟฮผฮฑ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฯฮฟ HELO
+auths.helo_hostname=ฮฮฝฮฟฮผฮฑ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ HELO
auths.helo_hostname_helper=ฮฮฝฮฟฮผฮฑ ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ ฯฮฟฯ
ฮฑฯฮฟฯฯฮญฮปฮปฮตฯฮฑฮน ฮผฮต ฯฮฟ HELO. ฮฯฮฎฯฯฮต ฮบฮตฮฝฯ ฮณฮนฮฑ ฮฝฮฑ ฯฯฮตฮฏฮปฮตฯฮต ฯฮฟ ฯฯฮญฯฮฟฮฝ ฯฮฝฮฟฮผฮฑ ฯฮฟฯ
ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ.
auths.disable_helo=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท HELO
auths.pam_service_name=ฮฮฝฮฟฮผฮฑ ฯ
ฯฮทฯฮตฯฮฏฮฑฯ PAM
@@ -3162,21 +3296,21 @@ auths.sspi_separator_replacement_helper=ฮ ฯฮฑฯฮฑฮบฯฮฎฯฮฑฯ ฯฮฟฯ
ฮธฮฑ ฯฯ
auths.sspi_default_language=ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮท ฮณฮปฯฯฯฮฑ ฯฯฮฎฯฯฮท
auths.sspi_default_language_helper=ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮท ฮณฮปฯฯฯฮฑ ฮณฮนฮฑ ฯฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ ฯฮฟฯ
ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฟฯฮฝฯฮฑฮน ฮฑฯ
ฯฯฮผฮฑฯฮฑ ฮผฮต ฯฮท ฮผฮญฮธฮฟฮดฮฟ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮทฯ SSPI. ฮฯฮฎฯฯฮต ฮบฮตฮฝฯ ฮฑฮฝ ฯฯฮฟฯฮนฮผฮฌฯฮต ฮท ฮณฮปฯฯฯฮฑ ฮฝฮฑ ฮตฮฝฯฮฟฯฮนฯฯฮตฮฏ ฮฑฯ
ฯฯฮผฮฑฯฮฑ.
auths.tips=ฮฃฯ
ฮผฮฒฮฟฯ
ฮปฮญฯ
-auths.tips.oauth2.general=ฮคฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮท OAuth2
+auths.tips.oauth2.general=ฮคฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮท ฮผฮญฯฯ OAuth2
auths.tips.oauth2.general.tip=ฮฮฑฯฮฌ ฯฮทฮฝ ฮตฮณฮณฯฮฑฯฮฎ ฮผฮนฮฑฯ ฮฝฮญฮฑฯ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮทฯ OAuth2, ฯฮฟ URL ฮบฮปฮฎฯฮทฯ/ฮฑฮฝฮฑฮบฮฑฯฮตฯฮธฯ
ฮฝฯฮทฯ ฯฯฮญฯฮตฮน ฮฝฮฑ ฮตฮฏฮฝฮฑฮน:
auths.tip.oauth2_provider=ฮ ฮฌฯฮฟฯฮฟฯ OAuth2
-auths.tip.bitbucket=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮฑฯฮฑฮฝฮฑฮปฯฯฮฎ OAuth ฯฯฮฟ https://bitbucket.org/account/user//oauth-consumers/new ฮบฮฑฮน ฯฯฮฟฯฮธฮญฯฯฮต ฯฮฟ ฮดฮนฮบฮฑฮฏฯฮผฮฑ 'Account' - 'Read'
+auths.tip.bitbucket=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮญฮฝฮฑฮฝ ฮฝฮญฮฟ ฮบฮฑฯฮฑฮฝฮฑฮปฯฯฮฎ OAuth ฯฯฮฟ %s
auths.tip.nextcloud=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮญฮฝฮฑ ฮฝฮญฮฟ ฮบฮฑฯฮฑฮฝฮฑฮปฯฯฮฎ OAuth ฯฯฮทฮฝ ฯ
ฯฮทฯฮตฯฮฏฮฑ ฯฮฑฯ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฯฮฟ ฯฮฑฯฮฑฮบฮฌฯฯ ฮผฮตฮฝฮฟฯ "Settings -> Security -> OAuth 2.0 client"
-auths.tip.dropbox=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ https://www.dropbox.com/developers/apps
-auths.tip.facebook=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ https://developers.facebook.com/apps ฮบฮฑฮน ฯฯฮฟฯฮธฮญฯฯฮต ฯฮฟ ฯฯฮฟฯฯฮฝ "Facebook Login"
-auths.tip.github=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ OAuth ฯฯฮฟ https://github.com/settings/applications/new
+auths.tip.dropbox=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ %s
+auths.tip.facebook=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ %s ฮบฮฑฮน ฯฯฮฟฯฮธฮญฯฯฮต ฯฮฟ ฯฯฮฟฯฯฮฝ "Facebook Login"
+auths.tip.github=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ OAuth ฯฯฮฟ %s
auths.tip.gitlab=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ https://gitlab.com/profile/applications
-auths.tip.google_plus=ฮฯฮฟฮบฯฮฎฯฯฮต ฯฮฑ ฮดฮนฮฑฯฮนฯฯฮตฯ
ฯฮฎฯฮนฮฑ ฯฮตฮปฮฌฯฮท OAuth2 ฮฑฯฯ ฯฮทฮฝ ฮบฮฟฮฝฯฯฮปฮฑ API ฯฮทฯ Google ฯฯฮฟ https://console.developers.google.com/
+auths.tip.google_plus=ฮฯฮฟฮบฯฮฎฯฯฮต ฯฮฑ ฮดฮนฮฑฯฮนฯฯฮตฯ
ฯฮฎฯฮนฮฑ ฯฮตฮปฮฌฯฮท OAuth2 ฮฑฯฯ ฯฮทฮฝ ฮบฮฟฮฝฯฯฮปฮฑ API ฯฮทฯ Google ฯฯฮฟ %s
auths.tip.openid_connect=ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฯฮต ฯฮฟ OpenID Connect Discovery URL (/.well known/openid-configuration) ฮณฮนฮฑ ฮฝฮฑ ฮบฮฑฮธฮฟฯฮฏฯฮตฯฮต ฯฮฑ ฯฮตฮปฮนฮบฮฌ ฯฮทฮผฮตฮฏฮฑ
-auths.tip.twitter=ฮ ฮทฮณฮฑฮฏฮฝฮตฯฮต ฯฯฮฟ https://dev.twitter.com/apps, ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮผฮนฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฮบฮฑฮน ฮฒฮตฮฒฮฑฮนฯฮธฮตฮฏฯฮต ฯฯฮน ฮท ฮตฯฮนฮปฮฟฮณฮฎ โAllow this application to be used to Sign in with Twitterโ ฮตฮฏฮฝฮฑฮน ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮท
-auths.tip.discord=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ https://discordapp.com/developers/applications/me
-auths.tip.gitea=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ OAuth2. ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฒฯฮตฮฏฯฮต ฯฮฟฮฝ ฮฟฮดฮทฮณฯ ฯฯฮฟ https://forgejo.org/docs/latest/user/oauth2-provider
-auths.tip.yandex=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ https://oauth.yandex.com/client/new. ฮฯฮนฮปฮญฮพฯฮต ฯฮฑ ฮฑฮบฯฮปฮฟฯ
ฮธฮฑ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮฑฯฯ ฯฮทฮฝ ฮตฮฝฯฯฮทฯฮฑ "Yandex.Passport API": "Access to email address", "Access to user avatar" ฮบฮฑฮน "Access to username, first name and surname, gender"`
+auths.tip.twitter=ฮ ฮทฮณฮฑฮฏฮฝฮตฯฮต ฯฯฮฟ %s, ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮผฮนฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฮบฮฑฮน ฮฒฮตฮฒฮฑฮนฯฮธฮตฮฏฯฮต ฯฯฮน ฮท ฮตฯฮนฮปฮฟฮณฮฎ โAllow this application to be used to Sign in with Twitterโ ฮตฮฏฮฝฮฑฮน ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮท
+auths.tip.discord=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ %s
+auths.tip.gitea=ฮฮฑฯฮฑฯฯฯฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ OAuth2. ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮฒฯฮตฮฏฯฮต ฯฮฟฮฝ ฮฟฮดฮทฮณฯ ฯฯฮฟ %s
+auths.tip.yandex=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฯฮต ฮผฮนฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ %s. ฮฯฮนฮปฮญฮพฯฮต ฯฮฑ ฮฑฮบฯฮปฮฟฯ
ฮธฮฑ ฮดฮนฮบฮฑฮนฯฮผฮฑฯฮฑ ฮฑฯฯ ฯฮทฮฝ ฮตฮฝฯฯฮทฯฮฑ "Yandex.Passport API": "Access to email address", "Access to user avatar" ฮบฮฑฮน "Access to username, first name and surname, gender"`
auths.tip.mastodon=ฮฮนฯฮฑฮณฮฌฮณฮตฯฮต ฮญฮฝฮฑ ฯฯฮฟฯฮฑฯฮผฮฟฮผฮญฮฝฮฟ URL ฮณฮนฮฑ ฯฮทฮฝ ฯ
ฯฮทฯฮตฯฮฏฮฑ mastodon ฮผฮต ฯฮทฮฝ ฮฟฯฮฟฮฏฮฑ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฯฮนฯฯฮฟฯฮฟฮนฮฎฯฮตฯฮต (ฮฎ ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮทฮฝ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮท)
auths.edit=ฮฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฯฮทฮณฮฎฯ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮทฯ
auths.activated=ฮฯ
ฯฮฎ ฮท ฯฮทฮณฮฎ ฮตฮฏฮฝฮฑฮน ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮท
@@ -3218,7 +3352,7 @@ config.ssh_start_builtin_server=ฮงฯฮฎฯฮท ฮตฮฝฯฯฮผฮฑฯฯฮผฮญฮฝฮฟฯ
ฮดฮนฮฑฮบฮฟ
config.ssh_domain=Domain ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ SSH
config.ssh_port=ฮฯฯฮฑ
config.ssh_listen_port=ฮฯฯฮฑ ฮฑฮบฯฯฮฑฯฮทฯ (Listen port)
-config.ssh_root_path=ฮกฮนฮถฮนฮบฮฎ ฮฮนฮฑฮดฯฮฟฮผฮฎ
+config.ssh_root_path=ฮคฮฟฯฮฟฮธฮตฯฮฏฮฑ root
config.ssh_key_test_path=ฮฮนฮฑฮดฯฮฟฮผฮฎ ฮดฮฟฮบฮนฮผฮฎฯ ฮบฮปฮตฮนฮดฮนฮฟฯ
config.ssh_keygen_path=ฮฮนฮฑฮดฯฮฟฮผฮฎ keygen (ยซssh-keygenยป)
config.ssh_minimum_key_size_check=ฮฮปฮตฮณฯฮฟฯ ฮตฮปฮฌฯฮนฯฯฮฟฯ
ฮผฮตฮณฮญฮธฮฟฯ
ฯ ฮบฮปฮตฮนฮดฮนฮฟฯ
@@ -3242,7 +3376,7 @@ config.service_config=ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ ฯ
ฯฮทฯฮตฯฮฏฮฑฯ
config.register_email_confirm=ฮฮฑ ฮฑฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮท ฮตฯฮนฮฒฮตฮฒฮฑฮฏฯฯฮท ฯฮทฯ ฮดฮนฮตฯฮธฯ
ฮฝฯฮทฯ email ฮณฮนฮฑ ฯฮทฮฝ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮตฮฝฯฯ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ
config.disable_register=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮฑฯ
ฯฮฟ-ฮตฮณฮณฯฮฑฯฮฎฯ
config.allow_only_internal_registration=ฮฮฑ ฮตฯฮนฯฯฮญฯฮฟฮฝฯฮฑฮน ฮตฮณฮณฯฮฑฯฮญฯ ฮผฯฮฝฮฟ ฮผฮญฯฯ ฯฮฟฯ
Forgejo
-config.allow_only_external_registration=ฮฮฑ ฮตฯฮนฯฯฮญฯฮฟฮฝฯฮฑฮน ฮตฮณฮณฯฮฑฯฮญฯ ฮผฯฮฝฮฟ ฮผฮต ฯฮทฮฝ ฯฯฮฎฯฮท ฮตฮพฯฯฮตฯฮนฮบฯฮฝ ฯ
ฯฮทฯฮตฯฮนฯฮฝ
+config.allow_only_external_registration=ฮฮฑ ฮตฯฮนฯฯฮญฯฮฟฮฝฯฮฑฮน ฮฟฮน ฮตฮณฮณฯฮฑฯฮญฯ ฮผฯฮฝฮฟ ฮผฮญฯฯ ฮตฮพฯฯฮตฯฮนฮบฯฮฝ ฯ
ฯฮทฯฮตฯฮนฯฮฝ
config.enable_openid_signup=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฮฑฯ
ฯฮฟ-ฮตฮณฮณฯฮฑฯฮฎฯ OpenID
config.enable_openid_signin=ฮฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฝฮดฮตฯฮทฯ ฮผฮญฯฯ OpenID
config.show_registration_button=ฮฮผฯฮฌฮฝฮนฯฮท ฮบฮฟฯ
ฮผฯฮนฮฟฯ ฮตฮณฮณฯฮฑฯฮฎฯ
@@ -3379,7 +3513,7 @@ notices.inverse_selection=ฮฮฝฯฮนฯฯฯฮฟฯฮฎ ฮตฯฮนฮปฮฟฮณฮฎฯ
notices.delete_selected=ฮฮนฮฑฮณฯฮฑฯฮฎ ฮตฯฮนฮปฮตฮณฮผฮญฮฝฯฮฝ
notices.delete_all=ฮฮนฮฑฮณฯฮฑฯฮฎ ฯฮปฯฮฝ ฯฯฮฝ ฮตฮนฮดฮฟฯฮฟฮนฮฎฯฮตฯฮฝ
notices.type=ฮคฯฯฮฟฯ
-notices.type_1=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+notices.type_1=Repository
notices.type_2=ฮฯฮณฮฑฯฮฏฮฑ
notices.desc=ฮ ฮตฯฮนฮณฯฮฑฯฮฎ
notices.op=ฮฮตฮนฯ.
@@ -3387,21 +3521,37 @@ notices.delete_success=ฮฮน ฮตฮนฮดฮฟฯฮฟฮนฮฎฯฮตฮนฯ ฯฮฟฯ
ฯฯ
ฯฯฮฎฮผฮฑฯฮฟฯ
self_check.no_problem_found = ฮฮญฯฯฮน ฯฯฯฮฑ, ฮดฮตฮฝ ฮญฯฮตฮน ฮฒฯฮตฮธฮตฮฏ ฮบฮฌฯฮฟฮนฮฟ ฯฯฯฮฒฮปฮทฮผฮฑ.
self_check = ฮฯ
ฯฮฟฮญฮปฮตฮณฯฮฟฯ
dashboard.sync_repo_tags = ฮฃฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯฯ tag, ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฯฮฑ ฮดฮตฮดฮฟฮผฮญฮฝฮฑ git ฯฯฮทฮฝ ฮฒฮฌฯฮท ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ
-dashboard.sync_tag.started = ฮ ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯฯ tag ฮญฯฮตฮน ฮพฮตฮบฮนฮฝฮฎฯฮตฮน
+dashboard.sync_tag.started = ฮฮตฮบฮฏฮฝฮทฯฮต ฮฟ ฯฯ
ฮณฯฯฮฟฮฝฮนฯฮผฯฯ ฯฯฮฝ ฮตฯฮนฮบฮตฯฯฮฝ
self_check.database_inconsistent_collation_columns = ฮ ฮฒฮฌฯฮท ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏ ฯฮฟ collation %s, ฮฑฮปฮปฮฌ ฮฟฮน ฯฯฮฎฮปฮตฯ ฯฮฟฯ
ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฟฯฮฝ collations ฯฮฟฯ
ฮดฮตฮฝ ฮฑฮฝฯฮนฯฯฮฟฮนฯฮฟฯฮฝ ฯฮต ฮตฮบฮตฮฏฮฝฮฟ ฯฮฟ collation. ฮฯ
ฯฯ ฮตฮฝฮดฮญฯฮตฯฮฑฮน ฮฝฮฑ ฯฯฮฟฮบฮฑฮปฮญฯฮตฮน ฮผฮตฯฮนฮบฮฌ ฮฑฯฯฯฯฮผฮตฮฝฮฑ ฮธฮญฮผฮฑฯฮฑ.
self_check.database_fix_mysql = ฮฮนฮฑ ฯฮฟฯ
ฯ ฯฯฮฎฯฯฮตฯ ฯฮฟฯ
MySQL/MariaDB: ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮฎฯฮตฯฮต ฯฮทฮฝ ฮตฮฝฯฮฟฮปฮฎ ยซgit doctor convertยป ฮณฮนฮฑ ฮฝฮฑ ฮดฮนฮฟฯฮธฯฯฮตฯฮต ฯฮฟ collation ฮฎ ฮฝฮฑ ฯฮฟ ฮดฮนฮฟฯฮธฯฯฮตฯฮต ฯฮตฮนฯฮฟฮบฮฏฮฝฮทฯฮฑ ฮผฮต ฯฮนฯ ฮตฮฝฯฮฟฮปฮญฯ ยซALTER ... COLLATE ...ยป.
config_settings = ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ
auths.tips.gmail_settings = ฮกฯ
ฮธฮผฮฏฯฮตฮนฯ Gmail:
config_summary = ฮ ฮตฯฮฏฮปฮทฯฮท
config.open_with_editor_app_help = ฮฮน ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮญฯ ฮบฮตฮนฮผฮญฮฝฮฟฯ
/ ฮบฯฮดฮนฮบฮฑ ฯฮฟฯ
ฮตฮผฯฮฑฮฝฮฏฮถฮฟฮฝฯฮฑฮน ฯฯฮฟ ฮผฮตฮฝฮฟฯ ฮบฮปฯฮฝฮฟฯฮฟฮฏฮทฯฮทฯ ฯฮต ฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ. ฮฮฝ ฯฮฟ ฮฑฯฮฎฯฮตฯฮต ฮบฮตฮฝฯ, ฮธฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮทฮธฮตฮฏ ฮผฮฏฮฑ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮท ฮปฮฏฯฯฮฑ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฯฮฝ. ฮ ฮฑฯฮฎฯฯฮต ฮณฮนฮฑ ฮฝฮฑ ฮดฮตฮฏฯฮต ฯฮทฮฝ ฯฯฮฟฮตฯฮนฮปฮฟฮณฮฎ.
-auths.tip.gitlab_new = ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮผฮฏฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ https://gitlab.com/-/profile/applications
+auths.tip.gitlab_new = ฮฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฯฮต ฮผฮฏฮฑ ฮฝฮญฮฑ ฮตฯฮฑฯฮผฮฟฮณฮฎ ฯฯฮฟ %s
self_check.database_collation_mismatch = ฮ ฮฒฮฌฯฮท ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮฑฮฝฮฑฮผฮญฮฝฮตฯฮฑฮน ฮฝฮฑ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏ ฯฮฟ collation: %s
self_check.database_collation_case_insensitive = ฮ ฮฒฮฌฯฮท ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏ ฯฮฟ collation %s, ฯฮฟ ฮฟฯฮฟฮฏฮฟ ฮดฮตฮฝ ฮพฮตฯฯฯฮฏฮถฮตฮน ฮบฮตฯฮฑฮปฮฑฮฏฮฑ ฮบฮฑฮน ฯฮตฮถฮฌ ฮณฯฮฌฮผฮผฮฑฯฮฑ. ฮฮฝ ฮบฮฑฮน ฯฮฟ Forgejo ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮดฮฟฯ
ฮปฮญฯฮตฮน ฮผฮต ฮฑฯ
ฯฯ, ฮฏฯฯฯ ฮฝฮฑ ฯฯฮฟฮบฯฯฮฟฯ
ฮฝ ฮบฮฌฯฮฟฮนฮตฯ ฯฯฮฌฮฝฮนฮตฯ ฯฮตฯฮนฯฯฯฯฮตฮนฯ ฯฯฮฟฯ
ฮบฮฌฯฮน ฮดฮตฮฝ ฮธฮฑ ฮดฮฟฯ
ฮปฮญฯฮตฮน ฯฯฯฯ ฮฑฮฝฮฑฮผฮญฮฝฮตฯฮฑฮน.
+config.cache_test_failed = ฮ ฮดฮฟฮบฮนฮผฮฎ cache ฮฑฯฮญฯฯ
ฯฮต: %v.
+config.cache_test_succeeded = ฮ ฮดฮฟฮบฮนฮผฮฎ cache ฯฮญฯฯ
ฯฮต, ฮปฮฌฮฒฮฑฮผฮต ฮฑฯฮฌฮฝฯฮทฯฮท ฯฮต %s.
+config.cache_test = ฮฮฟฮบฮนฮผฮฎ cache
+config.cache_test_slow = ฮ ฮดฮฟฮบฮนฮผฮฎ cache ฯฮญฯฯ
ฯฮต, ฮฑฮปฮปฮฌ ฮบฮฑฮธฯ
ฯฯฮญฯฮทฯฮต: %s.
+config.app_slogan = Slogan ฮดฮนฮฑฮบฮฟฮผฮนฯฯฮฎ
+auths.default_domain_name = ฮ ฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ domain name ฯฮฟฯ
ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฮตฮฏฯฮฑฮน ฮณฮนฮฑ ฯฮทฮฝ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email
+users.restricted.description = ฮฮฑ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฮฑฮปฮปฮทฮปฮตฯฮฏฮดฯฮฑฯฮท ฮผฯฮฝฮฟ ฯฯฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฮบฮฑฮน ฯฮฟฯ
ฯ ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯฯ ฯฯฮฟฯ
ฮฑฯ
ฯฯฯ ฮฟ ฯฯฮฎฯฯฮทฯ ฮญฯฮตฮน ฯฯฮฟฯฯฮตฮธฮตฮฏ ฯฯ ฯฯ
ฮฝฮตฯฮณฮฌฯฮทฯ. ฮฯ
ฯฯ ฮฑฯฮฟฯฯฮญฯฮตฮน ฯฮทฮฝ ฯฯฯฯฮฒฮฑฯฮท ฯฮต ฮฌฮปฮปฮฑ ฮดฮทฮผฯฯฮนฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฑ ฯฯฮทฮฝ ฯ
ฯฮทฯฮตฯฮฏฮฑ ฯฮฑฯ.
+users.local_import.description = ฮฮฑ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฮตฮนฯฮฑฮณฯฮณฮฎ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฯฮฝ ฮฑฯฯ ฯฮฟฮฝ ฯฮบฮปฮทฯฯ ฮดฮฏฯฮบฮฟ ฯฮฟฯ
server. ฮฯ
ฯฯ ฮตฮฝฮดฮญฯฮตฯฮฑฮน ฮฝฮฑ ฯฯฮฟฮบฮฑฮปฮญฯฮตฮน ฮถฮทฯฮฎฮผฮฑฯฮฑ ฮฑฯฯฮฑฮปฮตฮฏฮฑฯ.
+users.activated.description = ฮฮปฮฟฮบฮปฮฎฯฯฯฮท ฯฮทฯ ฮตฯฮฑฮปฮฎฮธฮตฯ
ฯฮทฯ email. ฮ ฮบฮฌฯฮฟฯฮฟฯ ฮตฮฝฯฯ ฮผฮท ฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮทฮผฮญฮฝฮฟฯ
ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฮฟฯ ฮดฮตฮฝ ฮธฮฑ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฯฯ
ฮฝฮดฮตฮธฮตฮฏ ฮผฮญฯฯฮน ฮฝฮฑ ฮฟฮปฮฟฮบฮปฮทฯฯฮธฮตฮฏ ฮท ฮตฯฮฑฮปฮฎฮธฮตฯ
ฯฮท ฯฮฟฯ
email ฯฮฟฯ
.
+users.block.description = ฮฮฑ ฮฑฯฮฑฮณฮฟฯฮตฯ
ฯฮตฮฏ ฮท ฮตฮฏฯฮฟฮดฮฟฯ ฮบฮฑฮน ฮท ฯฯฮฎฯฮท ฯฮทฯ ฯ
ฯฮทฯฮตฯฮฏฮฑฯ ฮฑฯ
ฯฮฎฯ ฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฯฯฮฎฯฯฮท.
+users.admin.description = ฮฮฑ ฮณฮฏฮฝฮตฮน ฯฮฑฯฮฑฯฯฯฮทฯฮท ฯฮปฮฎฯฮทฯ ฯฯฯฯฮฒฮฑฯฮทฯ ฯฮต ฯฮปฮตฯ ฯฮนฯ ฮปฮตฮนฯฮฟฯ
ฯฮณฮฏฮตฯ ฮดฮนฮฑฯฮตฮนฯฮนฯฯฮฎ ฯฮฟฯ
ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮตฯ ฮผฮญฯฯ ฯฮฟฯ
web UI ฮบฮฑฮน ฯฮฟฯ
API ฯฮต ฮฑฯ
ฯฯฮฝ ฯฮฟฮฝ ฯฯฮฎฯฯฮท.
+emails.delete = ฮฮนฮฑฮณฯฮฑฯฮฎ email
+emails.delete_desc = ฮฮฏฯฯฮต ฯฮฏฮณฮฟฯ
ฯฮฟฯ ฯฯฯ ฮธฮญฮปฮตฯฮต ฮฝฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮต ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email;
+emails.deletion_success = ฮ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
+emails.delete_primary_email_error = ฮฮตฮฝ ฮผฯฮฟฯฮตฮฏฯฮต ฮฝฮฑ ฮดฮนฮฑฮณฯฮฌฯฮตฯฮต ฯฮทฮฝ ฮบฯฯฮนฮฑ ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email.
+users.organization_creation.description = ฮฮฑ ฮตฯฮนฯฯฮญฯฮตฯฮฑฮน ฮท ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮฝฮญฯฮฝ ฮฟฯฮณฮฑฮฝฮนฯฮผฯฮฝ.
[action]
create_repo=ฮดฮทฮผฮนฮฟฯฯฮณฮทฯฮต ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ %s
-rename_repo=ฮผฮตฯฮฟฮฝฯฮผฮฑฯฮต ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮฑฯฯ %[1]s
ฯฮต %[3]s
+rename_repo=ฮผฮตฯฮฟฮฝฯฮผฮฑฯฮต ฯฮฟ repository ฮฑฯฯ %[1]s
ฯฮต %[3]s
commit_repo=ฮญฮบฮฑฮฝฮต push ฯฯฮฟ %[3]s ฯฮฟฯ
%[4]s
create_issue=`ฮฌฮฝฮฟฮนฮพฮต ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[3]s#%[2]s `
close_issue=`ฮญฮบฮปฮตฮนฯฮต ฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[3]s#%[2]s `
@@ -3413,19 +3563,19 @@ comment_issue=`ฮฌฯฮทฯฮต ฯฯฯฮปฮนฮฟ ฯฯฮฟ ฮถฮฎฯฮทฮผฮฑ %[3]s
comment_pull=`ฯฯฮฟฮปฮฏฮฑฯฮต ฯฯฮฟ pull request %[3]s#%[2]s `
merge_pull_request=`ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮต ฯฮฟ pull request %[3]s#%[2]s `
auto_merge_pull_request=`ฮฑฯ
ฯฯฮผฮฑฯฮท ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮท ฯฮฟฯ
pull request %[3]s#%[2]s `
-transfer_repo=ฮผฮตฯฮญฯฮตฯฮต ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ %s
ฯฮต %s
+transfer_repo=ฮผฮตฯฮญฯฮตฯฮต ฯฮฟ repository %s
ฯฮต %s
push_tag=ฯฮธฮทฯฮต ฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ %[3]s ฯฮต %[4]s
delete_tag=ฮดฮนฮญฮณฯฮฑฯฮต ฯฮทฮฝ ฮตฯฮนฮบฮญฯฮฑ %[2]s ฮฑฯฯ %[3]s
delete_branch=ฮดฮนฮญฮณฯฮฑฯฮต ฯฮฟ ฮบฮปฮฌฮดฮฟ %[2]s ฮฑฯฯ %[3]s
compare_branch=ฮฃฯฮณฮบฯฮนฯฮท
-compare_commits=ฮฃฯฮณฮบฯฮนฯฮท %d ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ
-compare_commits_general=ฮฃฯฮณฮบฯฮนฯฮท ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ
+compare_commits=ฮฃฯฮณฮบฯฮนฯฮท %d commit
+compare_commits_general=ฮฃฯฮณฮบฯฮนฯฮท commits
mirror_sync_push=ฯฯ
ฮณฯฯฮฟฮฝฮนฯฯฮฎฮบฮฑฮฝ ฮฟฮน ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฯฮฟฯ
%[3]s ฯฯฮฟ %[4]s ฮฑฯฯ ฯฮฟ ฮตฮฏฮดฯฮปฮฟ
mirror_sync_create=ฯฯ
ฮณฯฯฮฟฮฝฮฏฯฯฮทฮบฮต ฮท ฮฝฮญฮฑ ฮฑฮฝฮฑฯฮฟฯฮฌ %[3]s ฯฯฮฟ %[4]s ฮฑฯฯ ฯฮฟ ฮตฮฏฮดฯฮปฮฟ
mirror_sync_delete=ฯฯ
ฮณฯฯฯฮฝฮนฯฮต ฮบฮฑฮน ฮดฮนฮฌฮณฯฮฑฯฮต ฯฮทฮฝ ฮฑฮฝฮฑฯฮฟฯฮฌ %[2]s
ฯฮต %[3]s ฮฑฯฯ ฯฮฟ ฮตฮฏฮดฯฮปฮฟ
approve_pull_request=`ฮตฮฝฮญฮบฯฮนฮฝฮต ฯฮฟ %[3]s#%[2]s `
-reject_pull_request=`ฯฯฯฯฮตฮนฮฝฮต ฮฑฮปฮปฮฑฮณฮญฯ ฮณฮนฮฑ ฯฮฟ %[3]s#%[2]s `
-publish_release=`ฮญฮบฮดฯฯฮต ฯฮท "%[4]s" ฯฯฮฟ %[3]s `
+reject_pull_request=`ฯฯฯฯฮตฮนฮฝฮต ฮฑฮปฮปฮฑฮณฮญฯ ฯฯฮฟ %[3]s#%[2]s `
+publish_release=`ฮดฮทฮผฮฟฯฮฏฮตฯ
ฯฮต ฯฮทฮฝ ฮญฮบฮดฮฟฯฮท %[4]s ฯฯฮฟ %[3]s `
review_dismissed=`ฮฑฮบฯฯฯฯฮต ฯฮทฮฝ ฮตฮพฮญฯฮฑฯฮท ฮฑฯฯ %[4]s for %[3]s#%[2]s `
review_dismissed_reason=ฮฮนฯฮฏฮฑ:
create_branch=ฮดฮทฮผฮนฮฟฯฯฮณฮทฯฮต ฯฮฟ ฮบฮปฮฑฮดฮฟ %[3]s ฯฯฮฟ %[4]s
@@ -3475,13 +3625,13 @@ no_subscriptions=ฮฮฑฮผฮฏฮฑ ฯฯ
ฮฝฮดฯฮฟฮผฮฎ
[gpg]
default_key=ฮฅฯฮฟฮณฯฮฑฯฮฎ ฮผฮต ฯฮฟ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮบฮปฮตฮนฮดฮฏ
error.extract_sign=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮตฮพฮฑฮณฯฮณฮฎฯ ฯ
ฯฮฟฮณฯฮฑฯฮฎฯ
-error.generate_hash=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑฯ ฯฮฟฯ
ฮบฮฑฯฮฑฮบฮตฯฮผฮฑฯฮนฯฮผฮฟฯ (hash) ฯฮทฯ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ
-error.no_committer_account=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟฯ ฮผฮต ฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฟฯ
ฯ
ฯฮฟฮฒฮฟฮปฮญฮฑ
+error.generate_hash=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑฯ hash ฯฮฟฯ
commit
+error.no_committer_account=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯฯ ฯฮฟฯ
ฯฯ
ฯฯฮตฯฮฏฮถฮตฯฮฑฮน ฮผฮต ฯฮท ฮดฮนฮตฯฮธฯ
ฮฝฯฮท email ฯฮฟฯ
ฯ
ฯฮฟฮฒฮฟฮปฮญฮฑ
error.no_gpg_keys_found=ฮฮตฮฝ ฮฒฯฮญฮธฮทฮบฮต ฮณฮฝฯฯฯฯ ฮบฮปฮตฮนฮดฮฏ ฮณฮนฮฑ ฮฑฯ
ฯฮฎฮฝ ฯฮทฮฝ ฯ
ฯฮฟฮณฯฮฑฯฮฎ ฯฯฮท ฮฒฮฌฯฮท ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ
-error.not_signed_commit=ฮ ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฯ
ฯฮฟฮณฮตฮณฯฮฑฮผฮผฮญฮฝฮท
+error.not_signed_commit=ฮคฮฟ commit ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฯ
ฯฮฟฮณฮตฮณฯฮฑฮผฮผฮญฮฝฮท
error.failed_retrieval_gpg_keys=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮฑฮฝฮฌฮบฯฮทฯฮทฯ ฮบฮปฮตฮนฮดฮนฮฟฯ ฯฮฟฯ
ฮตฮฏฮฝฮฑฮน ฯฯ
ฮฝฮดฮตฮดฮตฮผฮญฮฝฮฟ ฯฯฮฟ ฮปฮฟฮณฮฑฯฮนฮฑฯฮผฯ ฯฮฟฯ
ฯ
ฯฮฟฮฒฮฟฮปฮญฮฑ
-error.probable_bad_signature=ฮ ฮกฮฮฃฮฮงฮ! ฮฮฝ ฮบฮฑฮน ฯ
ฯฮฌฯฯฮตฮน ฮญฮฝฮฑ ฮบฮปฮตฮนฮดฮฏ ฮผฮต ฮฑฯ
ฯฯ ฯฮฟ ID ฯฯฮท ฮฒฮฌฯฮท ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮดฮตฮฝ ฮตฯฮฑฮปฮทฮธฮตฯฮตฮน ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ! ฮฯ
ฯฮฎ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮตฮฏฮฝฮฑฮน ฮฅฮ ฮฮ ฮคฮ.
-error.probable_bad_default_signature=ฮ ฮกฮฮฃฮฮงฮ! ฮฮฝ ฮบฮฑฮน ฯฮฟ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮบฮปฮตฮนฮดฮฏ ฮญฯฮตฮน ฮฑฯ
ฯฯ ฯฮฟ ID, ฮดฮตฮฝ ฮตฯฮฑฮปฮทฮธฮตฯฮตฮน ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฯ
ฯฮฟฮฒฮฟฮปฮฎ! ฮฯ
ฯฮฎ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮตฮฏฮฝฮฑฮน ฮฅฮ ฮฮ ฮคฮ.
+error.probable_bad_signature=ฮ ฮกฮฮฃฮฮงฮ! ฮฮฝ ฮบฮฑฮน ฯ
ฯฮฌฯฯฮตฮน ฮญฮฝฮฑ ฮบฮปฮตฮนฮดฮฏ ฮผฮต ฮฑฯ
ฯฯ ฯฮฟ ID ฯฯฮท ฮฒฮฌฯฮท ฮดฮตฮดฮฟฮผฮญฮฝฯฮฝ ฮดฮตฮฝ ฮตฯฮฑฮปฮทฮธฮตฯฮตฮน ฮฑฯ
ฯฯ ฯฮฟ commit! ฮฯ
ฯฮฎ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮตฮฏฮฝฮฑฮน ฮฅฮ ฮฮ ฮคฮ.
+error.probable_bad_default_signature=ฮ ฮกฮฮฃฮฮงฮ! ฮฮฝ ฮบฮฑฮน ฯฮฟ ฯฯฮฟฮตฯฮนฮปฮตฮณฮผฮญฮฝฮฟ ฮบฮปฮตฮนฮดฮฏ ฮญฯฮตฮน ฮฑฯ
ฯฯ ฯฮฟ ID, ฮดฮตฮฝ ฮตฯฮฑฮปฮทฮธฮตฯฮตฮน ฮฑฯ
ฯฯ ฯฮฟ commit! ฮฯ
ฯฮฎ ฮท ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮตฮฏฮฝฮฑฮน ฮฅฮ ฮฮ ฮคฮ.
[units]
unit=ฮฮฟฮฝฮฌฮดฮฑ
@@ -3493,13 +3643,13 @@ title=ฮ ฮฑฮบฮญฯฮฑ
desc=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฯฮฑฮบฮญฯฯฮฝ ฮผฮทฯฯฯฮฟฯ
.
empty=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฯฮฑฮบฮญฯฮฑ ฮฑฮบฯฮผฮฑ.
empty.documentation=ฮฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฯฯฮตฯฮนฮบฮฌ ฮผฮต ฯฮฟ ฮผฮทฯฯฯฮฟ ฯฮฑฮบฮญฯฯฮฝ, ฯฯ
ฮผฮฒฮฟฯ
ฮปฮตฯ
ฯฮตฮฏฯฮต ฯฮฟฮฝ ฮฟฮดฮทฮณฯ .
-empty.repo=ฮฮฎฯฯฯ ฮฑฮฝฮตฮฒฮฌฯฮฑฯฮต ฮญฮฝฮฑ ฯฮฑฮบฮญฯฮฟ, ฮฑฮปฮปฮฌ ฮดฮตฮฝ ฮตฮผฯฮฑฮฝฮฏฮถฮตฯฮฑฮน ฮตฮดฯ; ฮ ฮทฮณฮฑฮฏฮฝฮตฯฮต ฯฯฮนฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฮฑฮบฮญฯฯฮฝ ฮบฮฑฮน ฯฯ
ฮฝฮดฮญฯฯฮต ฯฮฟ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ.
+empty.repo=ฮฮฎฯฯฯ ฮฑฮฝฮตฮฒฮฌฯฮฑฯฮต ฮญฮฝฮฑ ฯฮฑฮบฮญฯฮฟ, ฮฑฮปฮปฮฌ ฮดฮตฮฝ ฮตฮผฯฮฑฮฝฮฏฮถฮตฯฮฑฮน ฮตฮดฯ; ฮ ฮทฮณฮฑฮฏฮฝฮตฯฮต ฯฯฮนฯ ฯฯ
ฮธฮผฮฏฯฮตฮนฯ ฯฮฑฮบฮญฯฯฮฝ ฮบฮฑฮน ฯฯ
ฮฝฮดฮญฯฯฮต ฯฮฟ ฯฮต ฮฑฯ
ฯฯ ฯฮฟ repository.
registry.documentation=ฮฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฯฯฮตฯฮนฮบฮฌ ฮผฮต ฯฮฟ ฮผฮทฯฯฯฮฟ %s, ฯฯ
ฮผฮฒฮฟฯ
ฮปฮตฯ
ฯฮตฮฏฯฮต ฯฮฟฮฝ ฮฟฮดฮทฮณฯ .
filter.type=ฮคฯฯฮฟฯ
filter.type.all=ฮฮปฮฑ
filter.no_result=ฮคฮฟ ฯฮฏฮปฯฯฮฟ ฮดฮตฮฝ ฯฮฑฯฮฎฮณฮฑฮณฮต ฮฑฯฮฟฯฮตฮปฮญฯฮผฮฑฯฮฑ.
filter.container.tagged=ฮฯฮนฯฮทฮผฮฌฮฝฮธฮทฮบฮฑฮฝ
-filter.container.untagged=ฮงฯฯฮฏฯ ฮฯฮนฯฮฎฮผฮฑฮฝฯฮท
+filter.container.untagged=ฮงฯฯฮฏฯ ฮตฯฮนฯฮฎฮผฮฑฮฝฯฮท
published_by=ฮฮทฮผฮฟฯฮนฮตฯฮธฮทฮบฮต %[1]s ฮฑฯฯ %[3]s
published_by_in=ฮฮทฮผฮฟฯฮนฮตฯฮธฮทฮบฮต %[1]s ฮบฮฑฯฮฌ %[3]s ฯฮต %[5]s
installation=ฮฮณฮบฮฑฯฮฌฯฯฮฑฯฮท
@@ -3534,10 +3684,10 @@ composer.registry=ฮกฯ
ฮธฮผฮฏฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮผฮทฯฯฯฮฟ ฯฯฮฟ ฮฑฯฯฮตฮฏ
composer.install=ฮฮนฮฑ ฮฝฮฑ ฮตฮณฮบฮฑฯฮฑฯฯฮฎฯฮตฯฮต ฯฮฟ ฯฮฑฮบฮญฯฮฟ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฯฮฟ Composer, ฮตฮบฯฮตฮปฮญฯฯฮต ฯฮทฮฝ ฮฑฮบฯฮปฮฟฯ
ฮธฮท ฮตฮฝฯฮฟฮปฮฎ:
composer.dependencies=ฮฮพฮฑฯฯฮฎฯฮตฮนฯ
composer.dependencies.development=ฮฮพฮฑฯฯฮฎฯฮตฮนฯ ฮฮฝฮฌฯฯฯ
ฮพฮทฯ
-conan.details.repository=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ
+conan.details.repository=Repository
conan.registry=ฮกฯ
ฮธฮผฮฏฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮผฮทฯฯฯฮฟ ฮฑฯฯ ฯฮท ฮณฯฮฑฮผฮผฮฎ ฮตฮฝฯฮฟฮปฯฮฝ:
conan.install=ฮฮนฮฑ ฮฝฮฑ ฮตฮณฮบฮฑฯฮฑฯฯฮฎฯฮตฯฮต ฯฮฟ ฯฮฑฮบฮญฯฮฟ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฯฮฟ Conan, ฮตฮบฯฮตฮปฮญฯฯฮต ฯฮทฮฝ ฮฑฮบฯฮปฮฟฯ
ฮธฮท ฮตฮฝฯฮฟฮปฮฎ:
-conda.registry=ฮกฯ
ฮธฮผฮฏฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮผฮทฯฯฯฮฟ ฯฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ Conda ฯฯฮฟ ฮฑฯฯฮตฮฏฮฟ .condarc
:
+conda.registry=ฮกฯ
ฮธฮผฮฏฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮผฮทฯฯฯฮฟ ฯฯ repository Conda ฯฯฮฟ ฮฑฯฯฮตฮฏฮฟ .condarc
:
conda.install=ฮฮนฮฑ ฮฝฮฑ ฮตฮณฮบฮฑฯฮฑฯฯฮฎฯฮตฯฮต ฯฮฟ ฯฮฑฮบฮญฯฮฟ ฯฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฯฮฟ Conda, ฮตฮบฯฮตฮปฮญฯฯฮต ฯฮทฮฝ ฮฑฮบฯฮปฮฟฯ
ฮธฮท ฮตฮฝฯฮฟฮปฮฎ:
container.details.type=ฮคฯฯฮฟฯ ฮฮนฮบฯฮฝฮฑฯ
container.details.platform=ฮ ฮปฮฑฯฯฯฯฮผฮฑ
@@ -3595,8 +3745,8 @@ swift.registry=ฮกฯ
ฮธฮผฮฏฯฯฮต ฮฑฯ
ฯฯ ฯฮฟ ฮผฮทฯฯฯฮฟ ฮฑฯฯ ฯฮท ฮณฯฮฑฮผ
swift.install=ฮ ฯฮฟฯฮธฮญฯฯฮต ฯฮฟ ฯฮฑฮบฮญฯฮฟ ฯฯฮฟ ฮฑฯฯฮตฮฏฮฟ Package.swift
:
swift.install2=ฮบฮฑฮน ฮตฮบฯฮตฮปฮญฯฯฮต ฯฮทฮฝ ฮฑฮบฯฮปฮฟฯ
ฮธฮท ฮตฮฝฯฮฟฮปฮฎ:
vagrant.install=ฮฮนฮฑ ฯฯฮฟฯฮธฮฎฮบฮท ฮตฮฝฯฯ ฮบฯ
ฯฮฏฮฟฯ
Vagrant, ฮตฮบฯฮตฮปฮญฯฯฮต ฯฮทฮฝ ฮฑฮบฯฮปฮฟฯ
ฮธฮท ฮตฮฝฯฮฟฮปฮฎ:
-settings.link=ฮฃฯฮฝฮดฮตฯฮท ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฯฮฑฮบฮญฯฮฟฯ
ฮผฮต ฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ
-settings.link.description=ฮฮฌฮฝ ฯฯ
ฮฝฮดฮญฯฮตฯฮต ฮญฮฝฮฑ ฯฮฑฮบฮญฯฮฟ ฮผฮต ฮญฮฝฮฑ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ, ฯฮฟ ฯฮฑฮบฮญฯฮฟ ฯฮตฯฮนฮปฮฑฮผฮฒฮฌฮฝฮตฯฮฑฮน ฯฯฮท ฮปฮฏฯฯฮฑ ฯฮฑฮบฮญฯฯฮฝ ฯฮฟฯ
ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
.
+settings.link=ฮฃฯฮฝฮดฮตฯฮท ฮฑฯ
ฯฮฟฯ ฯฮฟฯ
ฯฮฑฮบฮญฯฮฟฯ
ฮผฮต ฮญฮฝฮฑ repository
+settings.link.description=ฮฮฌฮฝ ฯฯ
ฮฝฮดฮญฯฮตฯฮต ฮญฮฝฮฑ ฯฮฑฮบฮญฯฮฟ ฮผฮต ฮญฮฝฮฑ repository, ฯฮฟ ฯฮฑฮบฮญฯฮฟ ฯฮตฯฮนฮปฮฑฮผฮฒฮฌฮฝฮตฯฮฑฮน ฯฯฮท ฮปฮฏฯฯฮฑ ฯฮฑฮบฮญฯฯฮฝ ฯฮฟฯ
repository.
settings.link.select=ฮฯฮนฮปฮฟฮณฮฎ ฮฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
settings.link.button=ฮฮฝฮทฮผฮญฯฯฯฮท ฮฃฯ
ฮฝฮดฮญฯฮผฮฟฯ
ฮฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
settings.link.success=ฮ ฯฯฮฝฮดฮตฯฮผฮฟฯ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
ฮตฮฝฮทฮผฮตฯฯฮธฮทฮบฮต ฮตฯฮนฯฯ
ฯฯฯ.
@@ -3608,7 +3758,7 @@ settings.delete.success=ฮคฮฟ ฯฮฑฮบฮญฯฮฟ ฮญฯฮตฮน ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ.
settings.delete.error=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮดฮนฮฑฮณฯฮฑฯฮฎฯ ฯฮฟฯ
ฯฮฑฮบฮญฯฮฟฯ
.
owner.settings.cargo.title=ฮฯ
ฯฮตฯฮฎฯฮนฮฟ ฮผฮทฯฯฯฮฟฯ
Cargo
owner.settings.cargo.initialize=ฮฯฯฮนฮบฮฟฯฮฟฮฏฮทฯฮท ฮตฯ
ฯฮตฯฮทฯฮฏฮฟฯ
-owner.settings.cargo.initialize.description=ฮฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮญฮฝฮฑ ฮตฮนฮดฮนฮบฯ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮตฯ
ฯฮตฯฮทฯฮฏฮฟฯ
Git ฮณฮนฮฑ ฯฮท ฯฯฮฎฯฮท ฯฮฟฯ
ฮผฮทฯฯฯฮฟฯ
Cargo. ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฮตฯฮนฮปฮฟฮณฮฎ ฮธฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮทฮธฮตฮฏ ฮพฮฑฮฝฮฌ ฯฮฟ ฮฑฯฮฟฮธฮตฯฮฎฯฮนฮฟ ฮบฮฑฮน ฮธฮฑ ฯฯ
ฮธฮผฮนฯฯฮตฮฏ ฮฑฯ
ฯฯฮผฮฑฯฮฑ.
+owner.settings.cargo.initialize.description=ฮฯฮฑฮนฯฮตฮฏฯฮฑฮน ฮญฮฝฮฑ ฮตฮนฮดฮนฮบฯ repository ฮตฯ
ฯฮตฯฮทฯฮฏฮฟฯ
Git ฮณฮนฮฑ ฯฮท ฯฯฮฎฯฮท ฯฮฟฯ
ฮผฮทฯฯฯฮฟฯ
Cargo. ฮงฯฮทฯฮนฮผฮฟฯฮฟฮนฯฮฝฯฮฑฯ ฮฑฯ
ฯฮฎ ฯฮทฮฝ ฮตฯฮนฮปฮฟฮณฮฎ ฮธฮฑ ฮดฮทฮผฮนฮฟฯ
ฯฮณฮทฮธฮตฮฏ ฮพฮฑฮฝฮฌ ฯฮฟ repository ฮบฮฑฮน ฮธฮฑ ฯฯ
ฮธฮผฮนฯฯฮตฮฏ ฮฑฯ
ฯฯฮผฮฑฯฮฑ.
owner.settings.cargo.initialize.error=ฮฯฮฟฯฯ
ฯฮฏฮฑ ฮฑฯฯฮนฮบฮฟฯฮฟฮฏฮทฯฮทฯ ฮตฯ
ฯฮตฯฮทฯฮฏฮฟฯ
Cargo: %v
owner.settings.cargo.initialize.success=ฮ ฮตฯ
ฯฮตฯฮฎฯฮนฮฟ Cargo ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฮธฮทฮบฮต ฮผฮต ฮตฯฮนฯฯ
ฯฮฏฮฑ.
owner.settings.cargo.rebuild=ฮฮฝฮฑฮฝฮญฯฯฮท ฮตฯ
ฯฮตฯฮทฯฮฏฮฟฯ
@@ -3640,6 +3790,21 @@ owner.settings.chef.keypair=ฮฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮถฮตฯฮณฮฟฯ
ฯ ฮบฮปฮตฮนฮดฮนฯฮฝ
owner.settings.chef.keypair.description=ฮฮฝฮฑ ฮถฮตฯ
ฮณฮฌฯฮน ฮบฮปฮตฮนฮดฮนฯฮฝ ฮตฮฏฮฝฮฑฮน ฮฑฯฮฑฯฮฑฮฏฯฮทฯฮฟ ฮณฮนฮฑ ฯฮทฮฝ ฯฮฑฯ
ฯฮฟฯฮฟฮฏฮทฯฮท ฯฯฮฟ ฮผฮทฯฯฯฮฟ Chef. ฮฮฝ ฮญฯฮตฯฮต ฮฎฮดฮท ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฎฯฮตฮน ฮญฮฝฮฑ ฮถฮตฯ
ฮณฮฌฯฮน ฮบฮปฮตฮนฮดฮนฯฮฝ, ฮท ฮดฮทฮผฮนฮฟฯ
ฯฮณฮฏฮฑ ฮตฮฝฯฯ ฮฝฮญฮฟฯ
ฮถฮตฯ
ฮณฮฑฯฮนฮฟฯ ฮบฮปฮตฮนฮดฮนฯฮฝ ฮธฮฑ ฮฑฮฝฯฮนฮบฮฑฯฮฑฯฯฮฎฯฮตฮน ฯฮฟ ฯฮฑฮปฮนฯ ฮถฮตฯ
ฮณฮฌฯฮน.
rpm.repository.multiple_groups = ฮฯ
ฯฯ ฯฮฟ ฯฮฑฮบฮญฯฮฟ ฮตฮฏฮฝฮฑฮน ฮดฮนฮฑฮธฮญฯฮนฮผฮฟ ฯฮต ฯฮฟฮปฮปฮฑฯฮปฮฌ group.
owner.settings.cargo.rebuild.no_index = ฮ ฮฑฮฝฮฑฮฝฮญฯฯฮท ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮดฯ
ฮฝฮฑฯฮฎ, ฮตฯฮตฮนฮดฮฎ ฯฮฟ ฮตฯ
ฯฮตฯฮฎฯฮนฮฟ ฮดฮตฮฝ ฮญฯฯฮตฮน ฮฑฯฯฮนฮบฮฟฯฮฟฮนฮทฮธฮตฮฏ.
+arch.version.conflicts = ฮฃฯ
ฮณฮบฯฮฟฯฮตฯฮฑฮน ฮผฮต
+arch.version.replaces = ฮฮฝฯฮนฮบฮฑฯฮฑฯฯฮฌ
+arch.pacman.repo.multi = ฮคฮฟ %s ฮญฯฮตฮน ฯฮทฮฝ ฮฏฮดฮนฮฑ ฮญฮบฮดฮฟฯฮท ฯฮต ฮดฮนฮฑฯฮฟฯฮตฯฮนฮบฮญฯ ฮดฮนฮฑฮฝฮฟฮผฮญฯ.
+arch.pacman.repo.multi.item = ฮกฯฮธฮผฮนฯฮท ฮณฮนฮฑ %s
+arch.pacman.helper.gpg = ฮ ฯฮฟฯฮธฮญฯฯฮต ฯฮฟ trust certificate ฮณฮนฮฑ ฯฮฟ pacman:
+arch.pacman.conf = ฮ ฯฮฟฯฮธฮญฯฯฮต ฯฮฟฮฝ server ฮผฮต ฯฮนฯ ฯฯฮตฯฮนฮบฮญฯ ฯฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฮดฮนฮฑฮฝฮฟฮผฮฎฯ ฮบฮฑฮน ฮฑฯฯฮนฯฮตฮบฯฮฟฮฝฮนฮบฮฎฯ ฮตฯฮตฮพฮตฯฮณฮฑฯฯฮฎ ฯฯฮฟ /etc/pacman.conf
:
+arch.pacman.sync = ยซฮฃฯ
ฮณฯฯฮฟฮฝฮฏฯฯฮตยป ฯฮฟ ฯฮฑฮบฮญฯฮฟ ฮผฮต ฯฮฟ pacman:
+arch.version.properties = ฮ ฮปฮทฯฮฟฯฮฟฯฮฏฮตฯ ฮญฮบฮดฮฟฯฮทฯ
+arch.version.description = ฮ ฮตฯฮนฮณฯฮฑฯฮฎ
+arch.version.provides = ฮ ฯฮฟฯฯฮญฯฮตฮน
+arch.version.groups = ฮฮบฯฮฟฯ
ฯ
+arch.version.depends = ฮฮพฮฑฯฯฮฌฯฮฑฮน ฮฑฯฯ
+arch.version.optdepends = ฮฮพฮฑฯฯฮฌฯฮฑฮน ฯฯฮฟฮฑฮนฯฮตฯฮนฮบฮฌ ฮฑฯฯ
+arch.version.makedepends = ฮฮพฮฑฯฯฮฌฯฮฑฮน ฮฑฯฯ (ยซmakeยป)
+arch.version.checkdepends = ฮฮพฮฑฯฯฮฌฯฮฑฮน ฮฑฯฯ (ยซcheckยป)
[secrets]
secrets=ฮฯ
ฯฯฮนฮบฮฌ
@@ -3686,8 +3851,8 @@ runners.task_list=ฮ ฯฯฯฯฮฑฯฮตฯ ฮตฯฮณฮฑฯฮฏฮตฯ ฯฯฮฟฮฝ ฮตฮบฯฮตฮปฮตฯฯ
runners.task_list.no_tasks=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮตฮน ฮบฮฑฮผฮฏฮฑ ฮตฯฮณฮฑฯฮฏฮฑ ฮฑฮบฯฮผฮฑ.
runners.task_list.run=ฮฮบฯฮญฮปฮตฯฮท
runners.task_list.status=ฮฮฑฯฮฌฯฯฮฑฯฮท
-runners.task_list.repository=ฮฯฮฟฮธฮตฯฮฎฯฮนฮฟ
-runners.task_list.commit=ฮฅฯฮฟฮฒฮฟฮปฮฎ
+runners.task_list.repository=Repository
+runners.task_list.commit=Commit
runners.task_list.done_at=ฮฮปฮฟฮบฮปฮฎฯฯฯฮต ฮฃฯฮนฯ
runners.edit_runner=ฮฯฮตฮพฮตฯฮณฮฑฯฮฏฮฑ ฮฮบฯฮตฮปฮตฯฯฮฎ
runners.update_runner=ฮฮฝฮทฮผฮญฯฯฯฮท ฮฑฮปฮปฮฑฮณฯฮฝ
@@ -3708,7 +3873,7 @@ runners.reset_registration_token=ฮฯฮฑฮฝฮฑฯฮฟฯฮฌ ฮดฮนฮฑฮบฯฮนฯฮนฮบฮฟฯ ฮตฮณ
runners.reset_registration_token_success=ฮฯฮนฯฯ
ฯฮฎฯ ฮตฯฮฑฮฝฮญฮบฮดฮฟฯฮท ฮดฮนฮฑฮบฯฮนฯฮนฮบฮฟฯ ฮตฮณฮณฯฮฑฯฮฎฯ ฯฮฟฯ
ฮตฮบฯฮตฮปฮตฯฯฮฎ
runs.all_workflows=ฮฮปฮตฯ ฮฟฮน ฯฮฟฮญฯ ฮตฯฮณฮฑฯฮฏฮฑฯ
-runs.commit=ฮฅฯฮฟฮฒฮฟฮปฮฎ
+runs.commit=Commit
runs.scheduled=ฮ ฯฮฟฮณฯฮฑฮผฮผฮฑฯฮนฯฮผฮญฮฝฮฑ
runs.pushed_by=ฯฮธฮฎฮธฮทฮบฮต ฮฑฯฯ
runs.invalid_workflow_helper=ฮคฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮฟฮฎฯ ฮตฯฮณฮฑฯฮฏฮฑฯ ฮดฮตฮฝ ฮตฮฏฮฝฮฑฮน ฮญฮณฮบฯ
ฯฮฟ. ฮฮปฮญฮณฮพฯฮต ฯฮฟ ฮฑฯฯฮตฮฏฮฟ ฯฮฑฯ: %s
@@ -3720,7 +3885,7 @@ runs.status_no_select=ฮฮปฮตฯ ฮฟฮน ฮบฮฑฯฮฑฯฯฮฌฯฮตฮนฯ
runs.no_results=ฮฮตฮฝ ฮฒฯฮญฮธฮทฮบฮฑฮฝ ฮฑฯฮฟฯฮตฮปฮญฯฮผฮฑฯฮฑ.
runs.no_workflows=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฯฮฟฮญฯ ฮตฯฮณฮฑฯฮฏฮฑฯ ฮฑฮบฯฮผฮฑ.
runs.no_runs=ฮ ฯฮฟฮฎ ฮตฯฮณฮฑฯฮฏฮฑฯ ฮดฮตฮฝ ฮญฯฮตฮน ฯฯฮญฮพฮตฮน ฮฑฮบฯฮผฮฑ.
-runs.empty_commit_message=(ฮบฮตฮฝฯ ฮผฮฎฮฝฯ
ฮผฮฑ ฯ
ฯฮฟฮฒฮฟฮปฮฎฯ)
+runs.empty_commit_message=(ฮบฮตฮฝฯ ฮผฮฎฮฝฯ
ฮผฮฑ commit)
workflow.disable=ฮฯฮตฮฝฮตฯฮณฮฟฯฮฟฮฏฮทฯฮท ฯฮฟฮฎฯ ฮตฯฮณฮฑฯฮฏฮฑฯ
workflow.disable_success=ฮ ฯฮฟฮฎ ฮตฯฮณฮฑฯฮฏฮฑฯ ยซ%sยป ฮฑฯฮตฮฝฮตฯฮณฮฟฯฮฟฮนฮฎฮธฮทฮบฮต ฮตฯฮนฯฯ
ฯฯฯ.
@@ -3732,8 +3897,8 @@ need_approval_desc=ฮ ฯฮญฯฮตฮน ฮฝฮฑ ฮตฮณฮบฯฮนฮธฮตฮฏ ฮท ฮตฮบฯฮญฮปฮตฯฮท ฯฮฟฯ
variables=ฮฮตฯฮฑฮฒฮปฮทฯฮญฯ
variables.management=ฮฮนฮฑฯฮตฮฏฯฮนฯฮท ฮผฮตฯฮฑฮฒฮปฮทฯฯฮฝ
-variables.creation=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮผฮตฯฮฑฮฒฮปฮทฯฮฎฯ
-variables.none=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮผฮตฯฮฑฮฒฮปฮทฯฮญฯ ฮฑฮบฯฮผฮฑ.
+variables.creation=ฮ ฯฮฟฯฮธฮฎฮบฮท ฮผฮตฯฮฑฮฒฮปฮทฯฮฎ
+variables.none=ฮฮตฮฝ ฯ
ฯฮฌฯฯฮฟฯ
ฮฝ ฮฑฮบฯฮผฮฑ ฮผฮตฯฮฑฮฒฮปฮทฯฮญฯ.
variables.deletion=ฮฯฮฑฮฏฯฮตฯฮท ฮผฮตฯฮฑฮฒฮปฮทฯฮฎฯ
variables.deletion.description=ฮ ฮฑฯฮฑฮฏฯฮตฯฮท ฮผฮนฮฑฯ ฮผฮตฯฮฑฮฒฮปฮทฯฮฎฯ ฮตฮฏฮฝฮฑฮน ฮผฯฮฝฮนฮผฮท ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮตฮฏ ฮฝฮฑ ฮฑฮฝฮฑฮนฯฮตฮธฮตฮฏ. ฮฃฯ
ฮฝฮญฯฮตฮนฮฑ;
variables.description=ฮ ฮผฮตฯฮฑฮฒฮปฮทฯฮญฯ ฮธฮฑ ฮดฮฏฮฝฮฟฮฝฯฮฑฮน ฯฮต ฮฟฯฮนฯฮผฮญฮฝฮตฯ ฮดฯฮฌฯฮตฮนฯ ฮบฮฑฮน ฮดฮตฮฝ ฮผฯฮฟฯฮฟฯฮฝ ฮฝฮฑ ฮดฮนฮฑฮฒฮฑฯฯฮฟฯฮฝ ฮฑฮปฮปฮนฯฯ.
@@ -3749,15 +3914,23 @@ runs.no_workflows.documentation = ฮฮนฮฑ ฯฮตฯฮนฯฯฯฯฮตฯฮตฯ ฯฮปฮทฯฮฟฯฮฟ
runs.no_workflows.quick_start = ฮฮตฮฝ ฮพฮญฯฮตฯฮต ฮฑฯฯ ฯฮฟฯ
ฮฝฮฑ ฯฯฯฯฮฟฮพฮตฮบฮนฮฝฮฎฯฮตฯฮต ฮผฮต ฯฮฟ Forgejo Actions; ฮฮนฮฑ ฮผฮนฮฑ ฮณฯฮฎฮณฮฟฯฮท ฮฑฯฯฮฎ, ฯฯ
ฮผฮฒฮฟฯ
ฮปฮตฯ
ฯฮตฮฏฯฮต ฯฮฟฮฝ ฮฟฮดฮทฮณฯ ฮผฮฑฯ .
runs.workflow = ฮกฮฟฮฎ ฮตฯฮณฮฑฯฮฏฮฑฯ
runs.no_job_without_needs = ฮ ฯฮฟฮฎ ฮตฯฮณฮฑฯฮฏฮฑฯ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯฮตฯฮนฮญฯฮตฮน ฯฮฟฯ
ฮปฮฌฯฮนฯฯฮฟฮฝ ฮญฮฝฮฑ ฮญฯฮณฮฟ ฯฮฟฯ
ฮดฮตฮฝ ฮตฮพฮฑฯฯฮฌฯฮฑฮน ฮฑฯฯ ฮบฮฌฯฮฟฮนฮฟ ฮฌฮปฮปฮฟ ฮญฯฮณฮฟ.
+runs.no_job = ฮ ฯฮฟฮฎ ฮตฯฮณฮฑฯฮนฯฮฝ ฯฯฮญฯฮตฮน ฮฝฮฑ ฯฮตฯฮนฮญฯฮตฮน ฯฮฟฯ
ฮปฮฌฯฮนฯฯฮฟฮฝ ฮผฮฏฮฑ ฮตฯฮณฮฑฯฮฏฮฑ (job)
+workflow.dispatch.trigger_found = ฮฯ
ฯฮฎ ฮท ฯฮฟฮฎ ฮตฯฮณฮฑฯฮฏฮฑฯ ฮญฯฮตฮน ฮญฮฝฮฑ ยซevent triggerยป workflow_dispatch .
+workflow.dispatch.success = ฮ ฮตฮบฯฮญฮปฮตฯฮท ฯฮทฯ ฯฮฟฮฎฯ ฮตฯฮณฮฑฯฮฏฮฑฯ ฮฑฮนฯฮฎฮธฮทฮบฮต ฮตฯฮนฯฯ
ฯฯฯ.
+workflow.dispatch.input_required = ฮฯฮฑฮนฯฮตฮฏฯฮฑฮน ฯฮนฮผฮฎ ฮณฮนฮฑ ฯฮทฮฝ ฮตฮฏฯฮฟฮดฮฟ ยซ%sยป.
+workflow.dispatch.use_from = ฮงฯฮฎฯฮท ฯฮฟฮฎฯ ฮตฯฮณฮฑฯฮฏฮฑฯ ฮฑฯฯ
+workflow.dispatch.run = ฮฮบฯฮญฮปฮตฯฮท ฯฮฟฮฎฯ ฮตฯฮณฮฑฯฮฏฮฑฯ
+runs.expire_log_message = ฮคฮฑ ฮฑฯฯฮตฮฏฮฑ ฮบฮฑฯฮฑฮณฯฮฑฯฮฎฯ ฮญฯฮฟฯ
ฮฝ ฮดฮนฮฑฮณฯฮฑฯฮตฮฏ ฮตฯฮตฮนฮดฮฎ ฮฎฯฮฑฮฝ ฯฮฟฮปฯ ฯฮฑฮปฮนฮฌ.
+workflow.dispatch.invalid_input_type = ฮฮท ฮญฮณฮบฯ
ฯฮฟ ฮตฮฏฮดฮฟฯ ฮตฮนฯฯฮดฮฟฯ
ยซ%sยป.
[projects]
type-1.display_name=ฮฯฮฟฮผฮนฮบฯ ฮญฯฮณฮฟ
type-2.display_name=ฮฯฮณฮฟ ฮฑฯฮฟฮธฮตฯฮทฯฮฏฮฟฯ
type-3.display_name=ฮฯฮณฮฟ ฮฟฯฮณฮฑฮฝฮนฯฮผฮฟฯ
+deleted.display_name = ฮฮนฮฑฮณฯฮฑฮผฮผฮญฮฝฮฟ ฮญฯฮณฮฟ
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=ฮฆฮฌฮบฮตฮปฮฟฯ
normal_file=ฮฮฑฮฝฮฟฮฝฮนฮบฯ ฮฑฯฯฮตฮฏฮฟ
executable_file=ฮฮบฯฮตฮปฮญฯฮนฮผฮฟ ฮฑฯฯฮตฮฏฮฟ
@@ -3774,7 +3947,7 @@ code_search_by_git_grep = ฮฮนฮฑ ฯฮทฮฝ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮท ฮบฯฮดฮนฮบฮฑ, ฯฯฮท
package_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฯฮฑฮบฮญฯฯฮฝ...
project_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮญฯฮณฯฮฝ...
branch_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮบฮปฮฌฮดฯฮฝ...
-commit_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฯ
ฯฮฟฮฒฮฟฮปฯฮฝ...
+commit_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท commit...
no_results = ฮฮตฮฝ ฮฒฯฮญฮธฮทฮบฮฑฮฝ ฮบฮฑฯฮฌฮปฮปฮทฮปฮฑ ฮฑฯฮฟฯฮตฮปฮญฯฮผฮฑฯฮฑ.
search = ฮฮฝฮฑฮถฮฎฯฮทฯฮท...
type_tooltip = ฮฮฏฮดฮฟฯ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮทฯ
@@ -3787,6 +3960,15 @@ user_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฯฯฮทฯฯฯฮฝ...
org_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮฟฯฮณฮฑฮฝฮนฯฮผฯฮฝ...
team_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮฟฮผฮฑฮดฯฮฝ...
code_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮบฯฮดฮนฮบฮฑ...
+exact_tooltip = ฮฮฑ ฯฯ
ฮผฯฮตฯฮนฮปฮทฯฮธฮฟฯฮฝ ฮผฯฮฝฮฟ ฮฑฯฮฟฯฮตฮปฮญฯฮผฮฑฯฮฑ ฯฮฟฯ
ฯฮฑฮนฯฮนฮฌฮถฮฟฯ
ฮฝ ฮผฮต ฯฮฟฮฝ ฯฯฮฟ ฮฑฮฝฮฑฮถฮฎฯฮทฯฮทฯ
+issue_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮถฮทฯฮทฮผฮฌฯฯฮฝ...
+pull_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท pull...
+exact = ฮฮบฯฮนฮฒฮฎฯ
+milestone_kind = ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮฟฯฯฯฮทฮผฯฮฝ...
+union = ฮฮฝฯฯฮท
+union_tooltip = ฮฮฑ ฯฯ
ฮผฯฮตฯฮนฮปฮทฯฮธฮฟฯฮฝ ฮฑฯฮฟฯฮตฮปฮญฯฮผฮฑฯฮฑ ฯฮฟฯ
ฯฮตฯฮนฮญฯฮฟฯ
ฮฝ ฮฟฯฮฟฮนฮฑฮดฮฎฯฮฟฯฮต ฮฑฯฯ ฯฮนฯ ฮปฮญฮพฮตฮนฯ ฯฮฟฯ
ฮญฯฮฟฯ
ฮฝ ฮตฮนฯฮฑฯฮธฮตฮฏ ฮบฮฑฮน ฮดฮนฮฑฯฯฯฮนฯฯฮตฮฏ ฮผฮต ฮบฮตฮฝฯ
+regexp = ฮฮฑฮฝฮฟฮฝฮนฮบฮฎ ฮฮบฯฯฮฑฯฮท
+regexp_tooltip = ฮฯฮผฮทฮฝฮตฮฏฮฑ ฯฮฟฯ
ฯฯฮฟฯ
ฮฑฮฝฮฑฮถฮฎฯฮทฯฮทฯ ฯฯ ฮบฮฑฮฝฮฟฮฝฮนฮบฮฎ ฮญฮบฯฯฮฑฯฮท
[munits.data]
mib = MiB
@@ -3800,4 +3982,7 @@ kib = KiB
[markup]
filepreview.line = ฮฯฮฑฮผฮผฮฎ %[1]d ฯฯฮฟ ฮฑฯฯฮตฮฏฮฟ %[2]s
filepreview.lines = ฮฯฮฑฮผฮผฮญฯ %[1]d ฮญฯฯ %[2]d ฯฯฮฟ ฮฑฯฯฮตฮฏฮฟ %[3]s
-filepreview.truncated = ฮ ฯฯฮฟฮตฯฮนฯฮบฯฯฮทฯฮท ฮญฯฮตฮน ฯฮตฯฮนฮบฮฟฯฮตฮฏ
\ No newline at end of file
+filepreview.truncated = ฮ ฯฯฮฟฮตฯฮนฯฮบฯฯฮทฯฮท ฮญฯฮตฮน ฯฮตฯฮนฮบฮฟฯฮตฮฏ
+
+[translation_meta]
+test = ok
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index bac0e8515a..9ec018df5d 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -4,7 +4,7 @@ dashboard = Dashboard
explore = Explore
help = Help
logo = Logo
-sign_in = Sign In
+sign_in = Sign in
sign_in_with_provider = Sign in with %s
sign_in_or = or
sign_out = Sign Out
@@ -51,16 +51,12 @@ webauthn_error_unable_to_process = The server could not process your request.
webauthn_error_duplicated = The security key is not permitted for this request. Please make sure that the key is not already registered.
webauthn_error_empty = You must set a name for this key.
webauthn_error_timeout = Timeout reached before your key could be read. Please reload this page and retry.
-webauthn_reload = Reload
repository = Repository
organization = Organization
mirror = Mirror
-new_repo = New repository
-new_migrate = New migration
new_mirror = New mirror
new_fork = New repository fork
-new_org = New organization
new_project = New project
new_project_column = New column
admin_panel = Site administration
@@ -69,6 +65,14 @@ your_profile = Profile
your_starred = Starred
your_settings = Settings
+new_repo.title = New repository
+new_migrate.title = New migration
+new_org.title = New organization
+
+new_repo.link = New repository
+new_migrate.link = New migration
+new_org.link = New organization
+
all = All
sources = Sources
mirrors = Mirrors
@@ -103,6 +107,7 @@ copy = Copy
copy_generic = Copy to clipboard
copy_url = Copy URL
copy_hash = Copy hash
+copy_path = Copy path
copy_content = Copy content
copy_branch = Copy branch name
copy_success = Copied!
@@ -114,7 +119,8 @@ preview = Preview
loading = Loadingโฆ
error = Error
-error404 = The page you are trying to reach either does not exist or you are not authorized to view it.
+error404 = The page you are trying to reach either does not exist , has been removed or you are not authorized to view it.
+error413 = You have exhausted your quota.
go_back = Go Back
invalid_data = Invalid data: %v
@@ -160,27 +166,30 @@ filter.public = Public
filter.private = Private
[search]
-search = Search...
+search = Searchโฆ
type_tooltip = Search type
fuzzy = Fuzzy
fuzzy_tooltip = Include results that also match the search term closely
+union = Union
+union_tooltip = Include results that match any of the whitespace separated keywords
exact = Exact
exact_tooltip = Include only results that match the exact search term
-repo_kind = Search repos...
-user_kind = Search users...
-org_kind = Search orgs...
-team_kind = Search teams...
-code_kind = Search code...
+regexp = RegExp
+regexp_tooltip = Interpret the search term as a regular expression
+repo_kind = Search reposโฆ
+user_kind = Search usersโฆ
+org_kind = Search orgsโฆ
+team_kind = Search teamsโฆ
+code_kind = Search codeโฆ
code_search_unavailable = Code search is currently not available. Please contact the site administrator.
-code_search_by_git_grep = Current code search results are provided by "git grep". There might be better results if site administrator enables code indexer.
-package_kind = Search packages...
-project_kind = Search projects...
-branch_kind = Search branches...
-commit_kind = Search commits...
-runner_kind = Search runners...
+package_kind = Search packagesโฆ
+project_kind = Search projectsโฆ
+branch_kind = Search branchesโฆ
+commit_kind = Search commitsโฆ
+runner_kind = Search runnersโฆ
no_results = No matching results found.
-issue_kind = Search issues...
-pull_kind = Search pulls...
+issue_kind = Search issuesโฆ
+pull_kind = Search pullsโฆ
keyword_search_unavailable = Searching by keyword is currently not available. Please contact the site administrator.
[aria]
@@ -215,6 +224,18 @@ buttons.enable_monospace_font = Enable monospace font
buttons.disable_monospace_font = Disable monospace font
buttons.indent.tooltip = Nest items by one level
buttons.unindent.tooltip = Unnest items by one level
+buttons.new_table.tooltip = Add table
+
+table_modal.header = Add table
+table_modal.placeholder.header = Header
+table_modal.placeholder.content = Content
+table_modal.label.rows = Rows
+table_modal.label.columns = Columns
+
+link_modal.header = Add a link
+link_modal.url = Url
+link_modal.description = Description
+link_modal.paste_reminder = Hint: With a URL in your clipboard, you can paste directly into the editor to create a link.
[filter]
string.asc = A - Z
@@ -222,9 +243,7 @@ string.desc = Z - A
[error]
occurred = An error occurred
-report_message = If you believe that this is a Forgejo bug, please search for issues on Codeberg or open a new issue if necessary.
-missing_csrf = Bad Request: no CSRF token present
-invalid_csrf = Bad Request: invalid CSRF token
+report_message = If you believe that this is a Forgejo bug, please search for issues on Codeberg or open a new issue if necessary.
not_found = The target couldn't be found.
network_error = Network error
server_internal = Internal server error
@@ -232,13 +251,13 @@ server_internal = Internal server error
[startpage]
app_desc = A painless, self-hosted Git service
install = Easy to install
-install_desc = Simply run the binary for your platform, ship it with Docker , or get it packaged .
+install_desc = Simply run the binary for your platform, ship it with Docker , or get it packaged .
platform = Cross-platform
-platform_desc = Forgejo runs anywhere Go can compile for: Windows, macOS, Linux, ARM, etc. Choose the one you love!
+platform_desc = Forgejo is confirmed to run on libre operating systems like Linux and FreeBSD, as well as different CPU architectures. Choose the one you love!
lightweight = Lightweight
lightweight_desc = Forgejo has low minimal requirements and can run on an inexpensive Raspberry Pi. Save your machine energy!
license = Open Source
-license_desc = Go get Forgejo ! Join us by contributing to make this project even better. Don't be shy to be a contributor!
+license_desc = Go get Forgejo ! Join us by contributing to make this project even better. Don't be shy to be a contributor!
[install]
install = Installation
@@ -265,9 +284,9 @@ err_empty_db_path = The SQLite3 database path cannot be empty.
no_admin_and_disable_registration = You cannot disable user self-registration without creating an administrator account.
err_empty_admin_password = The administrator password cannot be empty.
err_empty_admin_email = The administrator email cannot be empty.
-err_admin_name_is_reserved = Administrator Username is invalid, username is reserved
+err_admin_name_is_reserved = Administrator username is invalid, username is reserved
err_admin_name_pattern_not_allowed = Administrator username is invalid, the username matches a reserved pattern
-err_admin_name_is_invalid = Administrator Username is invalid
+err_admin_name_is_invalid = Administrator username is invalid
general_title = General settings
app_name = Instance title
@@ -360,12 +379,9 @@ env_config_keys_prompt = The following environment variables will also be applie
[home]
uname_holder = Username or email address
-password_holder = Password
switch_dashboard_context = Switch dashboard context
my_repos = Repositories
my_orgs = Organizations
-show_more_repos = Show more repositoriesโฆ
-collaborative_repos = Collaborative repositories
view_home = View %s
filter = Other filters
filter_by_team_repositories = Filter by team repositories
@@ -399,32 +415,30 @@ relevant_repositories = Only relevant repositories are being shown, Sign in now!
+hint_register = Need an account? Register now.
+sign_up_button = Register now.
sign_up_successful = Account was successfully created. Welcome!
-confirmation_mail_sent_prompt = A new confirmation email has been sent to %s . Please check your inbox within the next %s to complete the registration process. If the email is incorrect, you can log in, and request another confirmation email to be sent to a different address.
+confirmation_mail_sent_prompt = A new confirmation email has been sent to %s . To complete the registration process, please check your inbox and follow the provided link within the next %s. If the email is incorrect, you can log in, and request another confirmation email to be sent to a different address.
must_change_password = Update your password
allow_password_change = Require user to change password (recommended)
-reset_password_mail_sent_prompt = A confirmation email has been sent to %s . Please check your inbox within the next %s to complete the account recovery process.
+reset_password_mail_sent_prompt = A confirmation email has been sent to %s . To complete the account recovery process, please check your inbox and follow the provided link within the next %s.
active_your_account = Activate your account
account_activated = Account has been activated
-prohibit_login = Signing in is prohibited
-prohibit_login_desc = Your account is prohibited from signing in, please contact your site administrator.
+prohibit_login = Account is suspended
+prohibit_login_desc = Your account has been suspended from interacting with the instance. Contact the instance administrator to regain access.
resent_limit_prompt = You have already requested an activation email recently. Please wait 3 minutes and try again.
has_unconfirmed_mail = Hi %s, you have an unconfirmed email address (%s ). If you haven't received a confirmation email or need to resend a new one, please click on the button below.
change_unconfirmed_email_summary = Change the email address activation mail is sent to.
change_unconfirmed_email = If you have given the wrong email address during registration, you can change it below, and a confirmation will be sent to the new address instead.
change_unconfirmed_email_error = Unable to change the email address: %v
resend_mail = Click here to resend your activation email
-email_not_associate = The email address is not associated with any account.
send_reset_mail = Send recovery email
reset_password = Account recovery
invalid_code = Your confirmation code is invalid or has expired.
@@ -435,15 +449,15 @@ reset_password_wrong_user = You are signed in as %s, but the account recovery li
password_too_short = Password length cannot be less than %d characters.
non_local_account = Non-local users cannot update their password through the Forgejo web interface.
verify = Verify
+;As https://codeberg.org/forgejo/forgejo/issues/2809 progresses, please update this error message if possible
+unauthorized_credentials = Credentials are incorrect or have expired. Retry your command or see %s for more information
scratch_code = Scratch code
use_scratch_code = Use a scratch code
+use_onetime_code = Use a one-time code
twofa_scratch_used = You have used your scratch code. You have been redirected to the two-factor settings page so you may remove your device enrollment or generate a new scratch code.
twofa_passcode_incorrect = Your passcode is incorrect. If you misplaced your device, use your scratch code to sign in.
twofa_scratch_token_incorrect = Your scratch code is incorrect.
-login_userpass = Sign In
-tab_signin = Sign In
-tab_signup = Sign Up
-tab_openid = OpenID
+login_userpass = Sign in
oauth_signup_tab = Register new account
oauth_signup_title = Complete new account
oauth_signup_submit = Complete account
@@ -469,10 +483,11 @@ authorize_application_description = If you grant the access, it will be able to
authorize_title = Authorize "%s" to access your account?
authorization_failed = Authorization failed
authorization_failed_desc = The authorization failed because we detected an invalid request. Please contact the maintainer of the app you have tried to authorize.
-sspi_auth_failed = SSPI authentication failed
-password_pwned = The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password and consider changing this password elsewhere too.
+password_pwned = The password you chose is on a list of stolen passwords previously exposed in public data breaches. Please try again with a different password and consider changing this password elsewhere too.
password_pwned_err = Could not complete request to HaveIBeenPwned
last_admin = You cannot remove the last admin. There must be at least one admin.
+back_to_sign_in = Back to Sign in
+sign_in_openid = Proceed with OpenID
[mail]
view_it_on = View it on %s
@@ -491,7 +506,7 @@ admin.new_user.subject = New user %s just signed up
admin.new_user.user_info = User information
admin.new_user.text = Please click here to manage this user from the admin panel.
-register_notify = Welcome to Forgejo
+register_notify = Welcome to %s
register_notify.text_1 = this is your registration confirmation email for %s!
register_notify.text_2 = You can sign into your account using your username: %s
register_notify.text_3 = If someone else made this account for you, you will need to set your password first.
@@ -499,6 +514,27 @@ register_notify.text_3 = If someone else made this account for you, you will nee
reset_password = Recover your account
reset_password.text = If this was you, please click the following link to recover your account within %s :
+password_change.subject = Your password has been changed
+password_change.text_1 = The password for your account was just changed.
+
+primary_mail_change.subject = Your primary mail has been changed
+primary_mail_change.text_1 = The primary mail of your account was just changed to %[1]s. This means that this e-mail address will no longer receive e-mail notifications for your account.
+
+totp_disabled.subject = TOTP has been disabled
+totp_disabled.text_1 = Time-based one-time password (TOTP) on your account was just disabled.
+totp_disabled.no_2fa = There are no other 2FA methods configured anymore, meaning it is no longer necessary to log into your account with 2FA.
+
+removed_security_key.subject = A security key has been removed
+removed_security_key.text_1 = Security key "%[1]s" has just been removed from your account.
+removed_security_key.no_2fa = There are no other 2FA methods configured anymore, meaning it is no longer necessary to log into your account with 2FA.
+
+account_security_caution.text_1 = If this was you, then you can safely ignore this mail.
+account_security_caution.text_2 = If this wasn't you, your account is compromised. Please contact the admins of this site.
+
+totp_enrolled.subject = You have activated TOTP as 2FA method
+totp_enrolled.text_1.no_webauthn = You have just enabled TOTP for your account. This means that for all future logins to your account, you must use TOTP as a 2FA method.
+totp_enrolled.text_1.has_webauthn = You have just enabled TOTP for your account. This means that for all future logins to your account, you could use TOTP as a 2FA method or use any of your security keys.
+
register_success = Registration successful
issue_assigned.pull = @%[1]s assigned you to pull request %[2]s in repository %[3]s.
@@ -559,8 +595,6 @@ RepoName = Repository name
Email = Email address
Password = Password
Retype = Confirm password
-SSHTitle = SSH key name
-HttpsUrl = HTTPS URL
PayloadUrl = Payload URL
TeamName = Team name
AuthName = Authorization name
@@ -575,9 +609,6 @@ CommitChoice = Commit choice
TreeName = File path
Content = Content
-SSPISeparatorReplacement = Separator
-SSPIDefaultLanguage = Default language
-
require_error = ` cannot be empty.`
alpha_dash_error = ` should contain only alphanumeric, dash ("-") and underscore ("_") characters.`
alpha_dash_dot_error = ` should contain only alphanumeric, dash ("-"), underscore ("_") and dot (".") characters.`
@@ -600,7 +631,7 @@ lang_select_error = Select a language from the list.
username_been_taken = The username is already taken.
username_change_not_local_user = Non-local users are not allowed to change their username.
-username_has_not_been_changed = Username has not been changed
+username_claiming_cooldown = The username cannot be claimed, because its cooldown period is not yet over. It can be claimed on %[1]s.
repo_name_been_taken = The repository name is already used.
repository_force_private = Force Private is enabled: private repositories cannot be made public.
repository_files_already_exist = Files already exist for this repository. Contact the system administrator.
@@ -614,6 +645,7 @@ team_name_been_taken = The team name is already taken.
team_no_units_error = Allow access to at least one repository section.
email_been_used = The email address is already used.
email_invalid = The email address is invalid.
+email_domain_is_not_allowed = The domain of the user's email address %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST. Make sure you have set the email address correctly.
openid_been_used = The OpenID address "%s" is already used.
username_password_incorrect = Username or password is incorrect.
password_complexity = Password does not pass complexity requirements:
@@ -691,6 +723,7 @@ public_activity.visibility_hint.self_public = Your activity is visible to everyo
public_activity.visibility_hint.admin_public = This activity is visible to everyone, but as an administrator you can also see interactions in private spaces.
public_activity.visibility_hint.self_private = Your activity is only visible to you and the instance administrators. Configure .
public_activity.visibility_hint.admin_private = This activity is visible to you because you're an administrator, but the user wants it to remain private.
+public_activity.visibility_hint.self_private_profile = Your activity is only visible to you and the instance administrators because your profile is private. Configure .
form.name_reserved = The username "%s" is reserved.
form.name_pattern_not_allowed = The pattern "%s" is not allowed in a username.
@@ -704,28 +737,27 @@ password = Password
security = Security
avatar = Avatar
ssh_gpg_keys = SSH / GPG keys
-social = Social accounts
applications = Applications
orgs = Organizations
repos = Repositories
delete = Delete Account
twofa = Two-factor authentication (TOTP)
-account_link = Linked accounts
organization = Organizations
uid = UID
webauthn = Two-factor authentication (Security keys)
blocked_users = Blocked users
+storage_overview = Storage overview
+quota = Quota
public_profile = Public profile
-biography_placeholder = Tell us a little bit about yourself! (You can use Markdown)
+biography_placeholder = Tell others a little bit about yourself! (Markdown is supported)
location_placeholder = Share your approximate location with others
-profile_desc = Control how your profile is shown to other users. Your primary email address will be used for notifications, password recovery and web-based Git operations.
+profile_desc = About you
password_username_disabled = Non-local users are not allowed to change their username. Please contact your site administrator for more details.
full_name = Full name
website = Website
location = Location
pronouns = Pronouns
-pronouns_custom = Custom
pronouns_unspecified = Unspecified
update_theme = Change theme
update_profile = Update profile
@@ -736,14 +768,18 @@ update_profile_success = Your profile has been updated.
change_username = Your username has been changed.
change_username_prompt = Note: Changing your username also changes your account URL.
change_username_redirect_prompt = The old username will redirect until someone claims it.
+change_username_redirect_prompt.with_cooldown.one = The old username will be available to everyone after a cooldown period of %[1]d day, you can still reclaim the old username during the cooldown period.
+change_username_redirect_prompt.with_cooldown.few = The old username will be available to everyone after a cooldown period of %[1]d days, you can still reclaim the old username during the cooldown period.
continue = Continue
cancel = Cancel
language = Language
language.title = Default language
+language.description = This language will be saved to your account and be used as the default after you log in.
+language.localization_project = Help us translate Forgejo into your language! Learn more .
ui = Theme
hints = Hints
additional_repo_units_hint = Suggest to enable additional repository units
-additional_repo_units_hint_description = Display an "Add more units..." button for repositories that do not have all available units enabled.
+additional_repo_units_hint_description = Display an "Enable more" hint for repositories that do not have all available units enabled.
update_hints = Update hints
update_hints_success = Hints have been updated.
hidden_comment_types = Hidden comment types
@@ -767,10 +803,9 @@ comment_type_group_issue_ref = Issue reference
saved_successfully = Your settings were saved successfully.
privacy = Privacy
keep_activity_private = Hide activity from profile page
-keep_activity_private_popup = Your activity will only be visible to you and the instance admins
+keep_activity_private.description = Your public activity will only be visible to you and the instance administrators.
lookup_avatar_by_mail = Lookup avatar by email address
-federated_avatar_lookup = Federated avatar lookup
enable_custom_avatar = Use custom avatar
choose_new_avatar = Choose new avatar
update_avatar = Update avatar
@@ -786,14 +821,14 @@ old_password = Current password
new_password = New password
retype_new_password = Confirm new password
password_incorrect = The current password is incorrect.
-change_password_success = Your password has been updated. Sign in using your new password from now on.
+change_password_success = Your password has been updated. From now on, use your new password to sign in.
password_change_disabled = Non-local users cannot update their password through the Forgejo web interface.
manage_emails = Manage email addresses
manage_themes = Default theme
manage_openid = OpenID addresses
email_desc = Your primary email address will be used for notifications, password recovery and, provided that it is not hidden, web-based Git operations.
-theme_desc = This will be your default theme across the site.
+theme_desc = This theme will be used for the web interface when you are logged in.
primary = Primary
activated = Activated
requires_activation = Requires activation
@@ -814,12 +849,14 @@ add_new_email = Add email address
add_new_openid = Add new OpenID URI
add_email = Add email address
add_openid = Add OpenID URI
-add_email_confirmation_sent = A confirmation email has been sent to "%s". Please check your inbox within the next %s to confirm your email address.
+add_email_confirmation_sent = A confirmation email has been sent to "%s". To confirm your email address, please check your inbox and follow the provided link within the next %s.
add_email_success = The new email address has been added.
email_preference_set_success = Email preference has been set successfully.
add_openid_success = The new OpenID address has been added.
keep_email_private = Hide email address
-keep_email_private_popup = This will hide your email address from your profile, as well as when you make a pull request or edit a file using the web interface. Pushed commits will not be modified. Use %s in commits to associate them with your account.
+keep_email_private_popup = Your email address will not be shown on your profile and will not be the default for commits made via the web interface, like file uploads, edits, and merge commits. Instead, a special address %s can be used to link commits to your account. This option will not affect existing commits.
+keep_pronouns_private = Only show pronouns to authenticated users
+keep_pronouns_private.description = This will hide your pronouns from visitors that are not logged in.
openid_desc = OpenID lets you delegate authentication to an external provider.
manage_ssh_keys = Manage SSH keys
@@ -831,8 +868,6 @@ principal_desc = These SSH certificate principals are associated with your accou
gpg_desc = These public GPG keys are associated with your account and used to verify your commits. Keep your private keys safe as they allow to sign commits with your identity.
ssh_helper = Need help? Have a look at the guide to create your own SSH keys or solve common problems you may encounter using SSH.
gpg_helper = Need help? Have a look at the guide about GPG .
-add_new_key = Add SSH key
-add_new_gpg_key = Add GPG key
key_content_ssh_placeholder = Begins with "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", or "sk-ssh-ed25519@openssh.com"
key_content_gpg_placeholder = Begins with "-----BEGIN PGP PUBLIC KEY BLOCK-----"
add_new_principal = Add principal
@@ -850,7 +885,6 @@ gpg_invalid_token_signature = The provided GPG key, signature and token do not m
gpg_token_required = You must provide a signature for the below token
gpg_token = Token
gpg_token_help = You can generate a signature using:
-gpg_token_code = echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature = Armored GPG signature
key_signature_gpg_placeholder = Begins with "-----BEGIN PGP SIGNATURE-----"
verify_gpg_key_success = GPG key "%s" has been verified.
@@ -897,10 +931,6 @@ hide_openid = Hide from profile
ssh_disabled = SSH is disabled
ssh_signonly = SSH is currently disabled so these keys are only used for commit signature verification.
ssh_externally_managed = This SSH key is externally managed for this user
-manage_social = Manage Associated Social Accounts
-social_desc = These social accounts can be used to sign in to your account. Make sure you recognize all of them.
-unbind = Unlink
-unbind_success = The social account has been removed successfully.
manage_access_token = Access tokens
generate_new_token = Generate new token
@@ -911,10 +941,12 @@ generate_token_success = Your new token has been generated. Copy it now as it wi
generate_token_name_duplicate = %s has been used as an application name already. Please use a new one.
delete_token = Delete
access_token_deletion = Delete access token
-access_token_deletion_cancel_action = Cancel
-access_token_deletion_confirm_action = Delete
access_token_deletion_desc = Deleting a token will revoke access to your account for applications using it. This cannot be undone. Continue?
delete_token_success = The token has been deleted. Applications using it no longer have access to your account.
+regenerate_token = Regenerate
+access_token_regeneration = Regenerate access token
+access_token_regeneration_desc = Regenerating a token will revoke access to your account for applications using it. This cannot be undone. Continue?
+regenerate_token_success = The token has been regenerated. Applications that use it no longer have access to your account and must be updated with the new token.
repo_and_org_access = Repository and Organization Access
permissions_public_only = Public only
permissions_access_all = All (public, private, and limited)
@@ -922,7 +954,7 @@ select_permissions = Select permissions
permission_no_access = No access
permission_read = Read
permission_write = Read and write
-access_token_desc = Selected token permissions limit authorization only to the corresponding API routes. Read the documentation for more information.
+access_token_desc = Selected token permissions limit authorization only to the corresponding API routes. Read the documentation for more information.
at_least_one_permission = You must select at least one permission to create a token
permissions_list = Permissions:
@@ -976,7 +1008,7 @@ passcode_invalid = The passcode is incorrect. Try again.
twofa_enrolled = Your account has been successfully enrolled. Store your single-use recovery key (%s) in a safe place, as it will not be shown again.
twofa_failed_get_secret = Failed to get secret.
-webauthn_desc = Security keys are hardware devices containing cryptographic keys. They can be used for two-factor authentication. Security keys must support the WebAuthn Authenticator standard.
+webauthn_desc = Security keys are hardware devices containing cryptographic keys. They can be used for two-factor authentication. Security keys must support the WebAuthn Authenticator standard.
webauthn_register_key = Add security key
webauthn_nickname = Nickname
webauthn_delete_key = Remove security key
@@ -986,7 +1018,6 @@ webauthn_alternative_tip = You may want to configure an additional authenticatio
manage_account_links = Linked accounts
manage_account_links_desc = These external accounts are linked to your Forgejo account.
-account_links_not_available = There are currently no external accounts linked to your Forgejo account.
link_account = Link account
remove_account_link = Remove linked account
remove_account_link_desc = Removing a linked account will revoke its access to your Forgejo account. Continue?
@@ -1015,13 +1046,33 @@ visibility = User visibility
visibility.public = Public
visibility.public_tooltip = Visible to everyone
visibility.limited = Limited
-visibility.limited_tooltip = Visible only to authenticated users
+visibility.limited_tooltip = Visible only to signed-in users
visibility.private = Private
visibility.private_tooltip = Visible only to members of organizations you have joined
blocked_since = Blocked since %s
user_unblock_success = The user has been unblocked successfully.
user_block_success = The user has been blocked successfully.
+user_block_yourself = You cannot block yourself.
+
+quota.applies_to_user = The following quota rules apply to your account
+quota.applies_to_org = The following quota rules apply to this organisation
+quota.rule.exceeded = Exceeded
+quota.rule.exceeded.helper = The total size of objects for this rule has exceeded the quota.
+quota.rule.no_limit = Unlimited
+quota.sizes.all = All
+quota.sizes.repos.all = Repositories
+quota.sizes.repos.public = Public repositories
+quota.sizes.repos.private = Private repositories
+quota.sizes.git.all = Git content
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.all = Assets
+quota.sizes.assets.attachments.all = Attachments
+quota.sizes.assets.attachments.issues = Issue attachments
+quota.sizes.assets.attachments.releases = Release attachments
+quota.sizes.assets.artifacts = Artifacts
+quota.sizes.assets.packages.all = Packages
+quota.sizes.wiki = Wiki
[repo]
rss.must_be_on_branch = You must be on a branch to have an RSS feed.
@@ -1032,7 +1083,11 @@ admin.update_flags = Update flags
admin.failed_to_replace_flags = Failed to replace repository flags
admin.flags_replaced = Repository flags replaced
-new_repo_helper = A repository contains all project files, including revision history. Already hosting one elsewhere? Migrate repository.
+new_repo_helper = A repository contains all project files, including revision history. Already hosting one elsewhere? Migrate repository .
+new_from_template = Use a template
+new_from_template_description = You can select an existing repository template on this instance and apply its settings.
+new_advanced = Advanced settings
+new_advanced_expand = Click to expand
owner = Owner
owner_helper = Some organizations may not show up in the dropdown due to a maximum repository count limit.
repo_name = Repository name
@@ -1040,7 +1095,7 @@ repo_name_helper = Good repository names use short, memorable and unique keyword
repo_size = Repository Size
size_format = %[1]s: %[2]s, %[3]s: %[4]s
template = Template
-template_select = Select a template.
+template_select = Select a template
template_helper = Make repository a template
template_description = Template repositories let users generate new repositories with the same directory structure, files, and optional settings.
visibility = Visibility
@@ -1067,19 +1122,20 @@ generate_from = Generate from
repo_desc = Description
repo_desc_helper = Enter short description (optional)
repo_lang = Language
-repo_gitignore_helper = Select .gitignore templates.
+repo_gitignore_helper = Select .gitignore templates
repo_gitignore_helper_desc = Choose which files not to track from a list of templates for common languages. Typical artifacts generated by each language's build tools are included on .gitignore by default.
-issue_labels = Issue labels
-issue_labels_helper = Select an issue label set.
+issue_labels = Labels
+issue_labels_helper = Select a label set
license = License
-license_helper = Select a license file.
-license_helper_desc = A license governs what others can and can't do with your code. Not sure which one is right for your project? See Choose a license.
+license_helper = Select a license file
+license_helper_desc = A license governs what others can and can't do with your code. Not sure which one is right for your project? See Choose a license .
object_format = Object format
-object_format_helper = Object format of the repository. Cannot be changed later. SHA1 is most compatible.
+object_format_helper = Object format of the repository. Cannot be changed later. SHA1 is the most compatible.
readme = README
-readme_helper = Select a README file template.
+readme_helper = Select a README file template
readme_helper_desc = This is the place where you can write a complete description for your project.
-auto_init = Initialize repository (Adds .gitignore, License and README)
+auto_init = Initialize repository
+auto_init_description = Start the Git history with a README and optionally add License and .gitignore files.
create_repo = Create repository
default_branch = Default branch
default_branch_label = default
@@ -1088,6 +1144,11 @@ mirror_prune = Prune
mirror_prune_desc = Remove obsolete remote-tracking references
mirror_interval = Mirror interval (valid time units are "h", "m", "s"). 0 to disable periodic sync. (Minimum interval: %s)
mirror_interval_invalid = The mirror interval is not valid.
+mirror_public_key = Public SSH key
+mirror_use_ssh.text = Use SSH authentication
+mirror_use_ssh.helper = Forgejo will mirror the repository via Git over SSH and create a keypair for you when you select this option. You must ensure that the generated public key is authorized to push to the destination repository. You cannot use password-based authorization when selecting this.
+mirror_use_ssh.not_available = SSH authentication isn't available.
+mirror_denied_combination = Cannot use public key and password based authentication in combination.
mirror_sync = synced
mirror_sync_on_commit = Sync when commits are pushed
mirror_address = Clone from URL
@@ -1110,7 +1171,7 @@ stars = Stars
reactions_more = and %d more
unit_disabled = The site administrator has disabled this repository section.
language_other = Other
-adopt_search = Enter username to search for unadopted repositories... (leave blank to find all)
+adopt_search = Enter username to search for unadopted repositoriesโฆ (leave blank to find all)
adopt_preexisting_label = Adopt files
adopt_preexisting = Adopt pre-existing files
adopt_preexisting_content = Create repository from %s
@@ -1123,6 +1184,7 @@ blame_prior = View blame prior to this change
blame.ignore_revs = Ignoring revisions in .git-blame-ignore-revs . Click here to bypass and see the normal blame view.
blame.ignore_revs.failed = Failed to ignore revisions in .git-blame-ignore-revs .
author_search_tooltip = Shows a maximum of 30 users
+summary_card_alt = Summary card of repository %s
tree_path_not_found_commit = Path %[1]s doesn't exist in commit %[2]s
tree_path_not_found_branch = Path %[1]s doesn't exist in branch %[2]s
@@ -1153,10 +1215,11 @@ template.issue_labels = Issue labels
template.one_item = Must select at least one template item
template.invalid = Must select a template repository
-archive.title = This repo is archived. You can view files and clone it, but cannot push or open issues or pull requests.
-archive.title_date = This repository has been archived on %s. You can view files and clone it, but cannot push or open issues or pull requests.
-archive.issue.nocomment = This repo is archived. You cannot comment on issues.
-archive.pull.nocomment = This repo is archived. You cannot comment on pull requests.
+archive.title = This repository is archived. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
+archive.title_date = This repository has been archived on %s. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
+archive.issue.nocomment = This repository is archived. You cannot comment on issues.
+archive.pull.nocomment = This repository is archived. You cannot comment on pull requests.
+archive.pull.noreview = This repository is archived. You cannot review pull requests.
form.reach_limit_of_creation_1 = The owner has already reached the limit of %d repository.
form.reach_limit_of_creation_n = The owner has already reached the limit of %d repositories.
@@ -1195,7 +1258,7 @@ migrate.migrate_items_options = Access token is required to migrate additional i
migrated_from = Migrated from %[2]s
migrated_from_fake = Migrated from %[1]s
migrate.migrate = Migrate from %s
-migrate.migrating = Migrating from %s ...
+migrate.migrating = Migrating from %s โฆ
migrate.migrating_failed = Migrating from %s failed.
migrate.migrating_failed.error = Failed to migrate: %s
migrate.migrating_failed_no_addr = Migration failed.
@@ -1304,6 +1367,8 @@ view_git_blame = View git blame
video_not_supported_in_browser = Your browser does not support the HTML5 "video" tag.
audio_not_supported_in_browser = Your browser does not support the HTML5 "audio" tag.
stored_lfs = Stored with Git LFS
+stored_annex = Stored with Git Annex
+stored_annex_not_present = not present here, try using git annex whereis
symbolic_link = Symbolic link
executable_file = Executable file
vendored = Vendored
@@ -1322,6 +1387,8 @@ normal_view = Normal View
line = line
lines = lines
from_comment = (comment)
+no_eol.text = No EOL
+no_eol.tooltip = This file doesn't contain a trailing end of line character.
editor.add_file = Add file
editor.new_file = New file
@@ -1329,6 +1396,7 @@ editor.upload_file = Upload file
editor.edit_file = Edit file
editor.preview_changes = Preview changes
editor.cannot_edit_lfs_files = LFS files cannot be edited in the web interface.
+editor.cannot_edit_annex_files = Annex files cannot be edited in the web interface.
editor.cannot_edit_non_text_files = Binary files cannot be edited in the web interface.
editor.edit_this_file = Edit file
editor.this_file_locked = File is locked
@@ -1343,7 +1411,8 @@ editor.or = or
editor.cancel_lower = Cancel
editor.commit_signed_changes = Commit signed changes
editor.commit_changes = Commit changes
-editor.add_tmpl = Add ""
+editor.add_tmpl = Add "<%s>"
+editor.add_tmpl.filename = filename
editor.add = Add %s
editor.update = Update %s
editor.delete = Delete %s
@@ -1353,7 +1422,7 @@ editor.fail_to_apply_patch = Unable to apply patch "%s"
editor.new_patch = New patch
editor.commit_message_desc = Add an optional extended descriptionโฆ
editor.signoff_desc = Add a Signed-off-by trailer by the committer at the end of the commit log message.
-editor.commit_directly_to_this_branch = Commit directly to the %s branch.
+editor.commit_directly_to_this_branch = Commit directly to the %[1]s branch.
editor.create_new_branch = Create a new branch for this commit and start a pull request.
editor.create_new_branch_np = Create a new branch for this commit.
editor.propose_file_change = Propose file change
@@ -1370,7 +1439,7 @@ editor.file_is_a_symlink = `"%s" is a symbolic link. Symbolic links cannot be ed
editor.filename_is_a_directory = Filename "%s" is already used as a directory name in this repository.
editor.file_editing_no_longer_exists = The file being edited, "%s", no longer exists in this repository.
editor.file_deleting_no_longer_exists = The file being deleted, "%s", no longer exists in this repository.
-editor.file_changed_while_editing = The file contents have changed since you started editing. Click here to see them or Commit changes again to overwrite them.
+editor.file_changed_while_editing = The file contents have changed since you opened the file. Click here to see them or Commit changes again to overwrite them.
editor.file_already_exists = A file named "%s" already exists in this repository.
editor.commit_id_not_matching = The file was changed while you were editing it. Commit to a new branch and then merge.
editor.push_out_of_date = The push appears to be out of date.
@@ -1392,6 +1461,7 @@ editor.user_no_push_to_branch = User cannot push to branch
editor.require_signed_commit = Branch requires a signed commit
editor.cherry_pick = Cherry-pick %s onto:
editor.revert = Revert %s onto:
+editor.commit_email = Commit email
commits.desc = Browse source code change history.
commits.commits = Commits
@@ -1413,6 +1483,7 @@ commits.signed_by_untrusted_user_unmatched = Signed by untrusted user who does n
commits.gpg_key_id = GPG key ID
commits.ssh_key_fingerprint = SSH key fingerprint
commits.view_path=View at this point in history
+commits.view_single_diff = View changes to this file introduced in this commit
commit.operations = Operations
commit.revert = Revert
@@ -1427,8 +1498,7 @@ commitstatus.failure = Failure
commitstatus.pending = Pending
commitstatus.success = Success
-ext_issues = Access to external issues
-ext_issues.desc = Link to an external issue tracker.
+ext_issues = External issues
projects = Projects
projects.desc = Manage issues and pulls in project boards.
@@ -1474,6 +1544,8 @@ issues.filter_milestones = Filter Milestone
issues.filter_projects = Filter Project
issues.filter_labels = Filter Label
issues.filter_reviewers = Filter Reviewer
+issues.filter_no_results = No results
+issues.filter_no_results_placeholder = Try adjusting your search filters.
issues.new = New issue
issues.new.title_empty = Title cannot be empty
issues.new.labels = Labels
@@ -1493,6 +1565,7 @@ issues.new.closed_milestone = Closed milestones
issues.new.assignees = Assignees
issues.new.clear_assignees = Clear assignees
issues.new.no_assignees = No assignees
+issues.new.assign_to_me = Assign to me
issues.new.no_reviewers = No reviewers
issues.edit.already_changed = Unable to save changes to the issue. It appears the content has already been changed by another user. Please refresh the page and try editing again to avoid overwriting their changes
issues.choose.get_started = Get started
@@ -1560,6 +1633,7 @@ issues.filter_type.mentioning_you = Mentioning you
issues.filter_type.review_requested = Review requested
issues.filter_type.reviewed_by_you = Reviewed by you
issues.filter_sort = Sort
+issues.filter_sort.relevance = Relevance
issues.filter_sort.latest = Newest
issues.filter_sort.oldest = Oldest
issues.filter_sort.recentupdate = Recently updated
@@ -1591,11 +1665,20 @@ issues.previous = Previous
issues.next = Next
issues.open_title = Open
issues.closed_title = Closed
+issues.all_title = All
issues.draft_title = Draft
issues.num_comments_1 = %d comment
issues.num_comments = %d comments
+issues.num_reviews_one = %d review
+issues.num_reviews_few = %d reviews
issues.commented_at = `commented %s `
issues.delete_comment_confirm = Are you sure you want to delete this comment?
+issues.reaction.add = Add reaction
+issues.reaction.alt_few = %[1]s reacted %[2]s.
+issues.reaction.alt_many = %[1]s and %[2]d more reacted %[3]s.
+issues.reaction.alt_remove = Remove %[1]s reaction from comment.
+issues.reaction.alt_add = Add %[1]s reaction to comment.
+issues.context.menu = Comment menu
issues.context.copy_link = Copy link
issues.context.quote_reply = Quote reply
issues.context.reference_issue = Reference in a new issue
@@ -1605,17 +1688,17 @@ issues.no_content = No description provided.
issues.close = Close issue
issues.comment_pull_merged_at = merged commit %[1]s into %[2]s %[3]s
issues.comment_manually_pull_merged_at = manually merged commit %[1]s into %[2]s %[3]s
-issues.close_comment_issue = Comment and close
+issues.close_comment_issue = Close with comment
issues.reopen_issue = Reopen
-issues.reopen_comment_issue = Comment and reopen
+issues.reopen_comment_issue = Reopen with comment
issues.create_comment = Comment
issues.closed_at = `closed this issue %[2]s `
issues.reopened_at = `reopened this issue %[2]s `
issues.commit_ref_at = `referenced this issue from a commit %[2]s `
issues.ref_issue_from = `referenced this issue %[4]s %[2]s `
issues.ref_pull_from = `referenced this pull request %[4]s %[2]s `
-issues.ref_closing_from = `referenced a pull request %[4]s that will close this issue %[2]s `
-issues.ref_reopening_from = `referenced a pull request %[4]s that will reopen this issue %[2]s `
+issues.ref_closing_from = `referenced this issue from a pull request %[4]s that will close it , %[2]s `
+issues.ref_reopening_from = `referenced this issue from a pull request %[4]s that will reopen it , %[2]s `
issues.ref_closed_from = `closed this issue %[4]s %[2]s `
issues.ref_reopened_from = `reopened this issue %[4]s %[2]s `
issues.ref_from = `from %[1]s`
@@ -1718,18 +1801,13 @@ issues.add_time_sum_to_small = No time was entered.
issues.time_spent_total = Total time spent
issues.time_spent_from_all_authors = `Total time spent: %s`
issues.due_date = Due date
-issues.invalid_due_date_format = Due date format must be "yyyy-mm-dd".
-issues.error_modifying_due_date = Failed to modify the due date.
-issues.error_removing_due_date = Failed to remove the due date.
issues.push_commit_1 = added %d commit %s
issues.push_commits_n = added %d commits %s
-issues.force_push_codes = `force-pushed %[1]s from %[2]s
to %[4]s
%[6]s`
+issues.force_push_codes = `force-pushed %[1]s from %[2]s
to %[4]s
%[6]s`
issues.force_push_compare = Compare
issues.due_date_form = yyyy-mm-dd
-issues.due_date_form_add = Add due date
issues.due_date_form_edit = Edit
issues.due_date_form_remove = Remove
-issues.due_date_not_writer = You need write access to this repository in order to update the due date of an issue.
issues.due_date_not_set = No due date set.
issues.due_date_added = added the due date %s %s
issues.due_date_modified = modified the due date from %[2]s to %[1]s %[3]s
@@ -1777,12 +1855,14 @@ issues.review.left_comment = left a comment
issues.review.content.empty = You need to leave a comment indicating the requested change(s).
issues.review.reject = requested changes %s
issues.review.wait = was requested for review %s
-issues.review.add_review_request = requested review from %s %s
-issues.review.remove_review_request = removed review request for %s %s
+issues.review.add_review_request = requested review from %[1]s %[2]s
+issues.review.add_review_requests = requested reviews from %[1]s %[2]s
+issues.review.remove_review_request = removed review request for %[1]s %[2]s
+issues.review.remove_review_requests = removed review requests for %[1]s %[2]s
issues.review.remove_review_request_self = refused to review %s
+issues.review.add_remove_review_requests = requested reviews from %[1]s and removed review requests for %[2]s %[3]s
issues.review.pending = Pending
issues.review.pending.tooltip = This comment is not currently visible to other users. To submit your pending comments, select "%s" -> "%s/%s/%s" at the top of the page.
-issues.review.review = Review
issues.review.reviewers = Reviewers
issues.review.outdated = Outdated
issues.review.outdated_description = Content has changed since this comment was made
@@ -1803,8 +1883,10 @@ issues.content_history.delete_from_history = Delete from history
issues.content_history.delete_from_history_confirm = Delete from history?
issues.content_history.options = Options
issues.reference_link = Reference: %s
-issues.blocked_by_user = You cannot create a issue on this repository because you are blocked by the repository owner.
-issues.comment.blocked_by_user = You cannot create a comment on this issue because you are blocked by the repository owner or the poster of the issue.
+issues.blocked_by_user = You cannot create issues in this repository because you are blocked by the repository owner.
+issues.comment.blocked_by_user = You cannot comment on this issue because you are blocked by the repository owner or the poster of the issue.
+issues.reopen.blocked_by_user = You cannot reopen this issue because you are blocked by the repository owner or the poster of this issue.
+issues.summary_card_alt = Summary card of an issue titled "%s" in repository %s
compare.compare_base = base
compare.compare_head = compare
@@ -1814,6 +1896,7 @@ pulls.new = New pull request
pulls.view = View pull request
pulls.edit.already_changed = Unable to save changes to the pull request. It appears the content has already been changed by another user. Please refresh the page and try editing again to avoid overwriting their changes
pulls.compare_changes = New pull request
+pulls.sign_in_require = Sign in to create a new pull request.
pulls.allow_edits_from_maintainers = Allow edits from maintainers
pulls.allow_edits_from_maintainers_desc = Users with write access to the base branch can also push to this branch
pulls.allow_edits_from_maintainers_err = Updating failed
@@ -1841,10 +1924,6 @@ pulls.nothing_to_compare_have_tag = The selected branch/tag are equal.
pulls.nothing_to_compare_and_allow_empty_pr = These branches are equal. This PR will be empty.
pulls.has_pull_request = `A pull request between these branches already exists: %[2]s#%[3]d `
pulls.create = Create pull request
-pulls.title_desc_one = wants to merge %[1]d commit from %[2]s
into %[3]s
-pulls.title_desc_few = wants to merge %[1]d commits from %[2]s
into %[3]s
-pulls.merged_title_desc_one = merged %[1]d commit from %[2]s
into %[3]s
%[4]s
-pulls.merged_title_desc_few = merged %[1]d commits from %[2]s
into %[3]s
%[4]s
pulls.change_target_branch_at = `changed target branch from %s to %s %s`
pulls.tab_conversation = Conversation
pulls.tab_commits = Commits
@@ -1890,6 +1969,7 @@ pulls.waiting_count_1 = %d waiting review
pulls.waiting_count_n = %d waiting reviews
pulls.wrong_commit_id = commit id must be a commit id on the target branch
pulls.blocked_by_user = You cannot create a pull request on this repository because you are blocked by the repository owner.
+pulls.comment.blocked_by_user = You cannot comment on this pull request because you are blocked by the repository owner or the poster of the pull request.
pulls.no_merge_desc = This pull request cannot be merged because all repository merge options are disabled.
pulls.no_merge_helper = Enable merge options in the repository settings or merge the pull request manually.
@@ -1936,11 +2016,12 @@ pulls.close = Close pull request
pulls.closed_at = `closed this pull request %[2]s `
pulls.reopened_at = `reopened this pull request %[2]s `
pulls.commit_ref_at = `referenced this pull request from a commit %[2]s `
-pulls.cmd_instruction_hint = `View command line instructions .`
+pulls.cmd_instruction_hint = View command line instructions
pulls.cmd_instruction_checkout_title = Checkout
pulls.cmd_instruction_checkout_desc = From your project repository, check out a new branch and test the changes.
pulls.cmd_instruction_merge_title = Merge
pulls.cmd_instruction_merge_desc = Merge the changes and update on Forgejo.
+pulls.cmd_instruction_merge_warning = Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.
pulls.clear_merge_message = Clear merge message
pulls.clear_merge_message_hint = Clearing the merge message will only remove the commit message content and keep generated git trailers such as "Co-Authored-By โฆ".
pulls.reopen_failed.head_branch = The pull request cannot be reopened, because the head branch doesn't exist anymore.
@@ -1949,6 +2030,9 @@ pulls.reopen_failed.base_branch = The pull request cannot be reopened, because t
pulls.made_using_agit = AGit
pulls.agit_explanation = Created using the AGit workflow. AGit lets contributors propose changes using "git push" without creating a fork or a new branch.
+pulls.editable = Editable
+pulls.editable_explanation = This pull request allows edits from maintainers. You can contribute directly to it.
+
pulls.auto_merge_button_when_succeed = (When checks succeed)
pulls.auto_merge_when_succeed = Auto merge when all checks succeed
pulls.auto_merge_newly_scheduled = The pull request was scheduled to merge when all checks succeed.
@@ -1961,6 +2045,10 @@ pulls.auto_merge_canceled_schedule = The auto merge was canceled for this pull r
pulls.auto_merge_newly_scheduled_comment = `scheduled this pull request to auto merge when all checks succeed %[1]s`
pulls.auto_merge_canceled_schedule_comment = `canceled auto merging this pull request when all checks succeed %[1]s`
+pulls.delete_after_merge.head_branch.is_default = The head branch you want to delete is the default branch and cannot be deleted.
+pulls.delete_after_merge.head_branch.is_protected = The head branch you want to delete is a protected branch and cannot be deleted.
+pulls.delete_after_merge.head_branch.insufficient_branch = You don't have permission to delete the head branch.
+
pulls.delete.title = Delete this pull request?
pulls.delete.text = Do you really want to delete this pull request? (This will permanently remove all content. Consider closing it instead, if you intend to keep it archived)
@@ -1993,6 +2081,7 @@ milestones.edit_success = Milestone "%s" has been updated.
milestones.deletion = Delete milestone
milestones.deletion_desc = Deleting a milestone removes it from all related issues. Continue?
milestones.deletion_success = The milestone has been deleted.
+milestones.filter_sort.name = Name
milestones.filter_sort.earliest_due_data = Nearest due date
milestones.filter_sort.latest_due_date = Farthest due date
milestones.filter_sort.least_complete = Least complete
@@ -2014,8 +2103,7 @@ signing.wont_sign.commitssigned = The merge will not be signed as all the associ
signing.wont_sign.approved = The merge will not be signed as the PR is not approved.
signing.wont_sign.not_signed_in = You are not signed in.
-ext_wiki = Access to external Wiki
-ext_wiki.desc = Link to an external wiki.
+ext_wiki = External Wiki
wiki = Wiki
wiki.welcome = Welcome to the Wiki.
@@ -2094,7 +2182,9 @@ activity.unresolved_conv_label = Open
activity.title.releases_1 = %d release
activity.title.releases_n = %d releases
activity.title.releases_published_by = %s published by %s
-activity.published_release_label = Published
+activity.published_release_label = Release
+activity.published_prerelease_label = Pre-release
+activity.published_tag_label = Tag
activity.no_git_activity = There has not been any commit activity in this period.
activity.git_stats_exclude_merges = Excluding merges,
activity.git_stats_author_1 = %d author
@@ -2116,6 +2206,7 @@ activity.git_stats_addition_n = %d additions
activity.git_stats_and_deletions = and
activity.git_stats_deletion_1 = %d deletion
activity.git_stats_deletion_n = %d deletions
+activity.commit = Commit activity
contributors.contribution_type.filter_label = Contribution type:
contributors.contribution_type.commits = Commits
@@ -2161,13 +2252,16 @@ settings.mirror_settings.push_mirror.none = No push mirrors configured
settings.mirror_settings.push_mirror.remote_url = Git remote repository URL
settings.mirror_settings.push_mirror.add = Add push mirror
settings.mirror_settings.push_mirror.edit_sync_time = Edit mirror sync interval
+settings.mirror_settings.push_mirror.none_ssh = None
-settings.units.units = Repository units
+settings.units.units = Units
settings.units.overview = Overview
-settings.units.add_more = Add more...
+settings.units.add_more = Enable more
settings.sync_mirror = Synchronize now
+settings.mirror_settings.push_mirror.copy_public_key = Copy public key
settings.pull_mirror_sync_in_progress = Pulling changes from the remote %s at the moment.
+settings.pull_mirror_sync_quota_exceeded = Quota exceeded, not pulling changes.
settings.push_mirror_sync_in_progress = Pushing changes to the remote %s at the moment.
settings.site = Website
settings.update_settings = Save settings
@@ -2204,6 +2298,7 @@ settings.pulls_desc = Enable repository pull requests
settings.pulls.ignore_whitespace = Ignore whitespace for conflicts
settings.pulls.enable_autodetect_manual_merge = Enable autodetect manual merge (Note: In some special cases, misjudgments can occur)
settings.pulls.allow_rebase_update = Enable updating pull request branch by rebase
+settings.default_update_style_desc=Default update style used for updating pull requests that are behind the base branch.
settings.pulls.default_delete_branch_after_merge = Delete pull request branch after merge by default
settings.pulls.default_allow_edits_from_maintainers = Allow edits from maintainers by default
settings.releases_desc = Enable repository releases
@@ -2251,6 +2346,7 @@ settings.transfer_owner = New owner
settings.transfer_perform = Perform transfer
settings.transfer_started = This repository has been marked for transfer and awaits confirmation from "%s"
settings.transfer_succeed = The repository has been transferred.
+settings.transfer_quota_exceeded = The new owner (%s) is over quota. The repository has not been transferred.
settings.signing_settings = Signing verification settings
settings.trust_model = Signature trust model
settings.trust_model.default = Default trust model
@@ -2265,9 +2361,9 @@ settings.trust_model.collaboratorcommitter = Collaborator+Committer
settings.trust_model.collaboratorcommitter.long = Collaborator+Committer: Trust signatures by collaborators which match the committer
settings.trust_model.collaboratorcommitter.desc = Valid signatures by collaborators of this repository will be marked "trusted" if they match the committer. Otherwise, valid signatures will be marked "untrusted" if the signature matches the committer and "unmatched" otherwise. This will force Forgejo to be marked as the committer on signed commits with the actual committer marked as Co-Authored-By: and Co-Committed-By: trailer in the commit. The default Forgejo key must match a User in the database.
settings.wiki_rename_branch_main = Normalize the Wiki branch name
-settings.wiki_rename_branch_main_desc = Rename the branch used internally by the Wiki to "%s". This is a permanent and cannot be undone.
+settings.wiki_rename_branch_main_desc = Rename the branch used internally by the Wiki to "%s". This change is permanent and cannot be undone.
settings.wiki_rename_branch_main_notices_1 = This operation CANNOT be undone.
-settings.wiki_rename_branch_main_notices_2 = This will permanently rename the the internal branch of %s's repository wiki. Existing checkouts will need to be updated.
+settings.wiki_rename_branch_main_notices_2 = This will permanently rename the internal branch of %s's repository wiki. Existing checkouts will need to be updated.
settings.wiki_branch_rename_success = The repository wiki's branch name has been successfully normalized.
settings.wiki_branch_rename_failure = Failed to normalize the repository wiki's branch name.
settings.confirm_wiki_branch_rename = Rename the wiki branch
@@ -2339,6 +2435,7 @@ settings.slack_icon_url = Icon URL
settings.slack_color = Color
settings.discord_username = Username
settings.discord_icon_url = Icon URL
+settings.discord_icon_url.exceeds_max_length = Icon URL must be less than or equal to 2048 characters
settings.event_desc = Trigger on:
settings.event_push_only = Push events
settings.event_send_everything = All events
@@ -2359,32 +2456,32 @@ settings.event_push_desc = Git push to a repository.
settings.event_repository = Repository
settings.event_repository_desc = Repository created or deleted.
settings.event_header_issue = Issue events
-settings.event_issues = Issues
+settings.event_issues = Modification
settings.event_issues_desc = Issue opened, closed, reopened, or edited.
-settings.event_issue_assign = Issue assigned
+settings.event_issue_assign = Assignment
settings.event_issue_assign_desc = Issue assigned or unassigned.
-settings.event_issue_label = Issue labeled
-settings.event_issue_label_desc = Issue labels updated or cleared.
-settings.event_issue_milestone = Issue milestoned
-settings.event_issue_milestone_desc = Issue milestoned or demilestoned.
-settings.event_issue_comment = Issue comment
+settings.event_issue_label = Labels
+settings.event_issue_label_desc = Issue labels added or removed.
+settings.event_issue_milestone = Milestones
+settings.event_issue_milestone_desc = Milestone added, removed or modified.
+settings.event_issue_comment = Comments
settings.event_issue_comment_desc = Issue comment created, edited, or deleted.
settings.event_header_pull_request = Pull request events
-settings.event_pull_request = Pull request
+settings.event_pull_request = Modification
settings.event_pull_request_desc = Pull request opened, closed, reopened, or edited.
-settings.event_pull_request_assign = Pull request assigned
+settings.event_pull_request_assign = Assignment
settings.event_pull_request_assign_desc = Pull request assigned or unassigned.
-settings.event_pull_request_label = Pull request labeled
-settings.event_pull_request_label_desc = Pull request labels updated or cleared.
-settings.event_pull_request_milestone = Pull request milestoned
-settings.event_pull_request_milestone_desc = Pull request milestoned or demilestoned.
-settings.event_pull_request_comment = Pull request comment
+settings.event_pull_request_label = Labels
+settings.event_pull_request_label_desc = Pull request labels added or removed.
+settings.event_pull_request_milestone = Milestones
+settings.event_pull_request_milestone_desc = Milestone added, removed or modified.
+settings.event_pull_request_comment = Comments
settings.event_pull_request_comment_desc = Pull request comment created, edited, or deleted.
-settings.event_pull_request_review = Pull request reviewed
-settings.event_pull_request_review_desc = Pull request approved, rejected, or review comment.
-settings.event_pull_request_sync = Pull request synchronized
-settings.event_pull_request_sync_desc = Pull request synchronized.
-settings.event_pull_request_review_request = Pull request review requested
+settings.event_pull_request_review = Reviews
+settings.event_pull_request_review_desc = Pull request approved, rejected, or review comments added.
+settings.event_pull_request_sync = Synchronized
+settings.event_pull_request_sync_desc = Branch updated automatically with target branch.
+settings.event_pull_request_review_request = Review requests
settings.event_pull_request_review_request_desc = Pull request review requested or review request removed.
settings.event_pull_request_approvals = Pull request approvals
settings.event_pull_request_merge = Pull request merge
@@ -2392,7 +2489,7 @@ settings.event_pull_request_enforcement = Enforcement
settings.event_package = Package
settings.event_package_desc = Package created or deleted in a repository.
settings.branch_filter = Branch filter
-settings.branch_filter_desc = Branch whitelist for push, branch creation and branch deletion events, specified as glob pattern. If empty or *
, events for all branches are reported. See github.com/gobwas/glob documentation for syntax. Examples: master
, {master,release*}
.
+settings.branch_filter_desc = Branch whitelist for push, branch creation and branch deletion events, specified as glob pattern. If empty or *
, events for all branches are reported. See %[2]s documentation for syntax. Examples: master
, {master,release*}
.
settings.authorization_header = Authorization header
settings.authorization_header_desc = Will be included as authorization header for requests when present. Examples: %s.
settings.active = Active
@@ -2449,12 +2546,8 @@ settings.branches = Branches
settings.protected_branch = Branch protection
settings.protected_branch.save_rule = Save rule
settings.protected_branch.delete_rule = Delete rule
-settings.protected_branch_can_push = Allow push?
-settings.protected_branch_can_push_yes = You can push
-settings.protected_branch_can_push_no = You cannot push
settings.branch_protection = Protection rules for branch "%s "
-settings.protect_this_branch = Enable branch protection
-settings.protect_this_branch_desc = Prevents deletion and restricts Git pushing and merging to the branch.
+settings.protect_new_rule = Create a new branch protection rule
settings.protect_disable_push = Disable push
settings.protect_disable_push_desc = No pushing will be allowed to this branch.
settings.protect_enable_push = Enable push
@@ -2464,26 +2557,26 @@ settings.protect_enable_merge_desc = Anyone with write access will be allowed to
settings.protect_whitelist_committers = Whitelist restricted push
settings.protect_whitelist_committers_desc = Only whitelisted users or teams will be allowed to push to this branch (but not force push).
settings.protect_whitelist_deploy_keys = Whitelist deploy keys with write access to push.
-settings.protect_whitelist_users = Whitelisted users for pushing:
-settings.protect_whitelist_teams = Whitelisted teams for pushing:
+settings.protect_whitelist_users = Whitelisted users for pushing
+settings.protect_whitelist_teams = Whitelisted teams for pushing
settings.protect_merge_whitelist_committers = Enable merge whitelist
settings.protect_merge_whitelist_committers_desc = Allow only whitelisted users or teams to merge pull requests into this branch.
-settings.protect_merge_whitelist_users = Whitelisted users for merging:
-settings.protect_merge_whitelist_teams = Whitelisted teams for merging:
+settings.protect_merge_whitelist_users = Whitelisted users for merging
+settings.protect_merge_whitelist_teams = Whitelisted teams for merging
settings.protect_check_status_contexts = Enable status check
-settings.protect_status_check_patterns = Status check patterns:
+settings.protect_status_check_patterns = Status check patterns
settings.protect_status_check_patterns_desc = Enter patterns to specify which status checks must pass before branches can be merged into a branch that matches this rule. Each line specifies a pattern. Patterns cannot be empty.
settings.protect_check_status_contexts_desc = Require status checks to pass before merging. When enabled, commits must first be pushed to another branch, then merged or pushed directly to a branch that matches this rule after status checks have passed. If no contexts are matched, the last commit must be successful regardless of context.
settings.protect_check_status_contexts_list = Status checks found in the last week for this repository
settings.protect_status_check_matched = Matched
settings.protect_invalid_status_check_pattern = Invalid status check pattern: "%s".
settings.protect_no_valid_status_check_patterns = No valid status check patterns.
-settings.protect_required_approvals = Required approvals:
+settings.protect_required_approvals = Required approvals
settings.protect_required_approvals_desc = Allow only to merge pull request with enough positive reviews.
settings.protect_approvals_whitelist_enabled = Restrict approvals to whitelisted users or teams
settings.protect_approvals_whitelist_enabled_desc = Only reviews from whitelisted users or teams will count to the required approvals. Without approval whitelist, reviews from anyone with write access count to the required approvals.
-settings.protect_approvals_whitelist_users = Whitelisted reviewers:
-settings.protect_approvals_whitelist_teams = Whitelisted teams for reviews:
+settings.protect_approvals_whitelist_users = Whitelisted reviewers
+settings.protect_approvals_whitelist_teams = Whitelisted teams for reviews
settings.dismiss_stale_approvals = Dismiss stale approvals
settings.dismiss_stale_approvals_desc = When new commits that change the content of the pull request are pushed to the branch, old approvals will be dismissed.
settings.ignore_stale_approvals = Ignore stale approvals
@@ -2491,14 +2584,12 @@ settings.ignore_stale_approvals_desc = Do not count approvals that were made on
settings.require_signed_commits = Require signed commits
settings.require_signed_commits_desc = Reject pushes to this branch if they are unsigned or unverifiable.
settings.protect_branch_name_pattern = Protected branch name pattern
-settings.protect_branch_name_pattern_desc = Protected branch name patterns. See the documentation for pattern syntax. Examples: main, release/**
+settings.protect_branch_name_pattern_desc = Protected branch name patterns. See the documentation for pattern syntax. Examples: main, release/**
settings.protect_patterns = Patterns
-settings.protect_protected_file_patterns = Protected file patterns (separated using semicolon ";"):
-settings.protect_protected_file_patterns_desc = Protected files are not allowed to be changed directly even if user has rights to add, edit, or delete files in this branch. Multiple patterns can be separated using semicolon (";"). See github.com/gobwas/glob documentation for pattern syntax. Examples: .drone.yml
, /docs/**/*.txt
.
-settings.protect_unprotected_file_patterns = Unprotected file patterns (separated using semicolon ";"):
-settings.protect_unprotected_file_patterns_desc = Unprotected files that are allowed to be changed directly if user has write access, bypassing push restriction. Multiple patterns can be separated using semicolon (";"). See github.com/gobwas/glob documentation for pattern syntax. Examples: .drone.yml
, /docs/**/*.txt
.
-settings.add_protected_branch = Enable protection
-settings.delete_protected_branch = Disable protection
+settings.protect_protected_file_patterns = Protected file patterns (separated using semicolon ";")
+settings.protect_protected_file_patterns_desc = Protected files are not allowed to be changed directly even if user has rights to add, edit, or delete files in this branch. Multiple patterns can be separated using semicolon (";"). See %[2]s documentation for pattern syntax. Examples: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns = Unprotected file patterns (separated using semicolon ";")
+settings.protect_unprotected_file_patterns_desc = Unprotected files that are allowed to be changed directly if user has write access, bypassing push restriction. Multiple patterns can be separated using semicolon (";"). See %[2]s documentation for pattern syntax. Examples: .drone.yml
, /docs/**/*.txt
.
settings.update_protect_branch_success = Branch protection for rule "%s" has been updated.
settings.remove_protected_branch_success = Branch protection for rule "%s" has been removed.
settings.remove_protected_branch_failed = Removing branch protection rule "%s" failed.
@@ -2530,7 +2621,7 @@ settings.tags.protection.allowed.teams = Allowed teams
settings.tags.protection.allowed.noone = No one
settings.tags.protection.create = Add rule
settings.tags.protection.none = There are no protected tags.
-settings.tags.protection.pattern.description = You can use a single name or a glob pattern or regular expression to match multiple tags. Read more in the protected tags guide .
+settings.tags.protection.pattern.description = You can use a single name or a glob pattern or regular expression to match multiple tags. Read more in the protected tags guide .
settings.bot_token = Bot token
settings.chat_id = Chat ID
settings.thread_id = Thread ID
@@ -2545,12 +2636,12 @@ settings.archive.text = Archiving the repo will make it entirely read-only. It w
settings.archive.success = The repo was successfully archived.
settings.archive.error = An error occurred while trying to archive the repo. See the log for more details.
settings.archive.error_ismirror = You cannot archive a mirrored repo.
-settings.archive.branchsettings_unavailable = Branch settings are not available if the repo is archived.
-settings.archive.tagsettings_unavailable = Tag settings are not available if the repo is archived.
-settings.archive.mirrors_unavailable = Mirrors are not available if the repo is archived.
+settings.archive.branchsettings_unavailable = Branch settings are not available in archived repos.
+settings.archive.tagsettings_unavailable = Tag settings are not available in archived repos.
+settings.archive.mirrors_unavailable = Mirrors are not available in archived repos.
settings.unarchive.button = Unarchive repo
settings.unarchive.header = Unarchive this repo
-settings.unarchive.text = Unarchiving the repo will restore its ability to receive commits and pushes, as well as new issues and pull-requests.
+settings.unarchive.text = Unarchiving the repo will restore its ability to receive commits and pushes, as well as new issues and pull requests.
settings.unarchive.success = The repo was successfully unarchived.
settings.unarchive.error = An error occurred while trying to unarchive the repo. See the log for more details.
settings.update_avatar_success = The repository avatar has been updated.
@@ -2568,7 +2659,7 @@ settings.lfs_invalid_locking_path=Invalid path: %s
settings.lfs_invalid_lock_directory=Cannot lock directory: %s
settings.lfs_lock_already_exists=Lock already exists: %s
settings.lfs_lock=Lock
-settings.lfs_lock_path=Filepath to lock...
+settings.lfs_lock_path=Filepath to lockโฆ
settings.lfs_locks_no_locks=No locks
settings.lfs_lock_file_no_exist=Locked file does not exist in default branch
settings.lfs_force_unlock=Force unlock
@@ -2583,17 +2674,17 @@ settings.rename_branch_failed_protected=Cannot rename branch %s because it is a
settings.rename_branch_failed_exist=Cannot rename branch because target branch %s exists.
settings.rename_branch_failed_not_exist=Cannot rename branch %s because it does not exist.
settings.rename_branch_success =Branch %s was successfully renamed to %s.
-settings.rename_branch_from=old branch name
-settings.rename_branch_to=new branch name
settings.rename_branch=Rename branch
diff.browse_source = Browse source
diff.parent = parent
diff.commit = commit
diff.git-notes = Notes
+diff.git-notes.add = Add note
+diff.git-notes.remove-header = Remove note
+diff.git-notes.remove-body = This note will be removed.
diff.data_not_available = Diff content is not available
diff.options_button = Diff options
-diff.show_diff_stats = Show stats
diff.download_patch = Download patch file
diff.download_diff = Download diff file
diff.show_split_view = Split view
@@ -2622,7 +2713,7 @@ diff.generated = generated
diff.vendored = vendored
diff.comment.add_line_comment = Add line comment
diff.comment.placeholder = Leave a comment
-diff.comment.markdown_info = Styling with markdown is supported.
+diff.comment.markdown_info = Styling with Markdown is supported.
diff.comment.add_single_comment = Add single comment
diff.comment.add_review_comment = Add comment
diff.comment.start_review = Start review
@@ -2653,7 +2744,7 @@ release.draft = Draft
release.prerelease = Pre-release
release.stable = Stable
release.compare = Compare
-release.edit = edit
+release.edit = Edit
release.ahead.commits = %d commits
release.ahead.target = to %s since this release
tag.ahead.target = to %s since this tag
@@ -2695,6 +2786,13 @@ release.add_tag = Create tag
release.releases_for = Releases for %s
release.tags_for = Tags for %s
release.system_generated = This attachment is automatically generated.
+release.type_attachment = Attachment
+release.type_external_asset = External asset
+release.asset_name = Asset name
+release.asset_external_url = External URL
+release.add_external_asset = Add external asset
+release.invalid_external_url = Invalid external URL: "%s"
+release.summary_card_alt = Summary card of an release titled "%s" in repository %s
branch.name = Branch name
branch.already_exists = A branch named "%s" already exists.
@@ -2705,7 +2803,7 @@ branch.delete_desc = Deleting a branch is permanent. Although the deleted branch
branch.deletion_success = Branch "%s" has been deleted.
branch.deletion_failed = Failed to delete branch "%s".
branch.delete_branch_has_new_commits = Branch "%s" cannot be deleted because new commits have been added after merging.
-branch.create_branch = Create branch %s
+branch.create_branch = Create branch %s
branch.create_from = from "%s"
branch.create_success = Branch "%s" has been created.
branch.branch_already_exists = Branch "%s" already exists in this repository.
@@ -2725,25 +2823,24 @@ branch.create_new_branch = Create branch from branch:
branch.confirm_create_branch = Create branch
branch.warning_rename_default_branch = You are renaming the default branch.
branch.rename_branch_to = Rename "%s" to:
-branch.confirm_rename_branch = Rename branch
branch.create_branch_operation = Create branch
branch.new_branch = Create new branch
branch.new_branch_from = Create new branch from "%s"
branch.renamed = Branch %s was renamed to %s.
-tag.create_tag = Create tag %s
+tag.create_tag = Create tag %s
tag.create_tag_operation = Create tag
tag.confirm_create_tag = Create tag
tag.create_tag_from = Create new tag from "%s"
tag.create_success = Tag "%s" has been created.
-topic.manage_topics = Manage Topics
+topic.manage_topics = Manage topics
topic.done = Done
topic.count_prompt = You cannot select more than 25 topics
topic.format_prompt = Topics must start with a letter or number, can include dashes ("-") and dots ("."), can be up to 35 characters long. Letters must be lowercase.
-find_file.go_to_file = Go to file
+find_file.go_to_file = Find a file
find_file.no_matching = No matching file found
error.csv.too_large = Can't render this file because it is too large.
@@ -2751,8 +2848,28 @@ error.csv.unexpected = Can't render this file because it contains an unexpected
error.csv.invalid_field_count = Can't render this file because it has a wrong number of fields in line %d.
error.broken_git_hook = Git hooks of this repository seem to be broken. Please follow the documentation to fix them, then push some commits to refresh the status.
+[repo.permissions]
+code.read = Read: Access and clone the code of the repository.
+code.write = Write: Push to the repository, create branches and tags.
+issues.read = Read: Read and create issues and comments.
+issues.write = Write: Close issues and manage metadata like labels, milestones, assignees, due dates and dependencies.
+pulls.read = Read: Reading and create pull requests.
+pulls.write = Write: Close pull requests and manage metadata like labels, milestones, assignees, due dates and dependencies.
+releases.read = Read: View and download releases.
+releases.write = Write: Publish, edit and delete releases and their assets.
+wiki.read = Read: Read the integrated wiki and it's history.
+wiki.write = Write: Create, update and delete pages in the integrated wiki.
+projects.read = Read: Access repository project boards.
+projects.write = Write: Create projects and columns and edit them.
+packages.read = Read: View and download packages assigned to the repository.
+packages.write = Write: Publish and delete packages assigned to the repository.
+actions.read = Read: View integrated CI/CD pipelines and their logs.
+actions.write = Write: Manually trigger, restart, cancel or approve pending CI/CD pipelines.
+ext_issues = Access the link to an external issue tracker. The permissions are managed externally.
+ext_wiki = Access the link to an external wiki. The permissions are managed externally.
+
[graphs]
-component_loading = Loading %s...
+component_loading = Loading %sโฆ
component_loading_failed = Could not load %s
component_loading_info = This might take a bitโฆ
component_failed_to_load = An unexpected error happened.
@@ -2799,7 +2916,7 @@ settings.permission = Permissions
settings.repoadminchangeteam = Repository admin can add and remove access for teams
settings.visibility = Visibility
settings.visibility.public = Public
-settings.visibility.limited = Limited (visible only to authenticated users)
+settings.visibility.limited = Limited (visible only to signed-in users)
settings.visibility.limited_shortname = Limited
settings.visibility.private = Private (visible only to organization members)
settings.visibility.private_shortname = Private
@@ -2808,6 +2925,8 @@ settings.update_settings = Update settings
settings.update_setting_success = Organization settings have been updated.
settings.change_orgname_prompt = Note: Changing the organization name will also change your organization's URL and free the old name.
settings.change_orgname_redirect_prompt = The old name will redirect until it is claimed.
+settings.change_orgname_redirect_prompt.with_cooldown.one = The old organization name will be available to everyone after a cooldown period of %[1]d day, you can still reclaim the old name during the cooldown period.
+settings.change_orgname_redirect_prompt.with_cooldown.few = The old organization name will be available to everyone after a cooldown period of %[1]d days, you can still reclaim the old name during the cooldown period.
settings.update_avatar_success = The organization's avatar has been updated.
settings.delete = Delete organization
settings.delete_account = Delete this organization
@@ -2830,23 +2949,21 @@ members.member = Member
members.remove = Remove
members.remove.detail = Remove %[1]s from %[2]s?
members.leave = Leave
-members.leave.detail = Leave %s?
+members.leave.detail = Are you sure you want to leave organization "%s"?
members.invite_desc = Add a new member to %s:
members.invite_now = Invite now
teams.join = Join
teams.leave = Leave
-teams.leave.detail = Leave %s?
+teams.leave.detail = Are you sure you want to leave team "%s"?
teams.can_create_org_repo = Create repositories
teams.can_create_org_repo_helper = Members can create new repositories in organization. Creator will get administrator access to the new repository.
teams.none_access = No access
-teams.none_access_helper = Members cannot view or do any other action on this unit. It has no effect for public repositories.
-teams.general_access = General access
+teams.none_access_helper = The "no access" option only has effect on private repositories.
+teams.general_access = Custom access
teams.general_access_helper = Members permissions will be decided by below permission table.
teams.read_access = Read
-teams.read_access_helper = Members can view and clone team repositories.
teams.write_access = Write
-teams.write_access_helper = Members can read and push to team repositories.
teams.admin_access = Administrator access
teams.admin_access_helper = Members can pull and push to team repositories and add collaborators to them.
teams.no_desc = This team has no description
@@ -2863,7 +2980,7 @@ teams.delete_team_desc = Deleting a team revokes repository access from its memb
teams.delete_team_success = The team has been deleted.
teams.read_permission_desc = This team grants Read access: members can view and clone team repositories.
teams.write_permission_desc = This team grants Write access: members can read from and push to team repositories.
-teams.admin_permission_desc = This team grants Admin access: members can read from, push to and add collaborators to team repositories.
+teams.admin_permission_desc = This team grants Administrator access: members can read from, push to and add collaborators to team repositories.
teams.create_repo_permission_desc = Additionally, this team grants Create repository permission: members can create new repositories in organization.
teams.repositories = Team repositories
teams.remove_all_repos_title = Remove all team repositories
@@ -2878,9 +2995,6 @@ teams.specific_repositories = Specific repositories
teams.specific_repositories_helper = Members will only have access to repositories explicitly added to the team. Selecting this will not automatically remove repositories already added with All repositories .
teams.all_repositories = All repositories
teams.all_repositories_helper = Team has access to all repositories. Selecting this will add all existing repositories to the team.
-teams.all_repositories_read_permission_desc = This team grants Read access to all repositories : members can view and clone repositories.
-teams.all_repositories_write_permission_desc = This team grants Write access to all repositories : members can read from and push to repositories.
-teams.all_repositories_admin_permission_desc = This team grants Admin access to all repositories : members can read from, push to and add collaborators to repositories.
teams.invite.title = You have been invited to join team %s in organization %s .
teams.invite.by = Invited by %s
teams.invite.description = Please click the button below to join the team.
@@ -2907,7 +3021,7 @@ last_page = Last
total = Total: %d
settings = Admin settings
-dashboard.new_version_hint = Forgejo %s is now available, you are running %s. Check the blog for more details.
+dashboard.new_version_hint = Forgejo %s is now available, you are running %s. Check the blog for more details.
dashboard.statistic = Summary
dashboard.operations = Maintenance operations
dashboard.system_status = System status
@@ -2984,16 +3098,16 @@ dashboard.delete_old_actions.started = Delete all old activities from database s
dashboard.update_checker = Update checker
dashboard.delete_old_system_notices = Delete all old system notices from database
dashboard.gc_lfs = Garbage collect LFS meta objects
-dashboard.stop_zombie_tasks = Stop zombie tasks
-dashboard.stop_endless_tasks = Stop endless tasks
-dashboard.cancel_abandoned_jobs = Cancel abandoned jobs
-dashboard.start_schedule_tasks = Start schedule tasks
+dashboard.stop_zombie_tasks = Stop zombie actions tasks
+dashboard.stop_endless_tasks = Stop endless actions tasks
+dashboard.cancel_abandoned_jobs = Cancel abandoned actions jobs
+dashboard.start_schedule_tasks = Start schedule actions tasks
dashboard.sync_branch.started = Branch sync started
dashboard.sync_tag.started = Tag sync started
dashboard.rebuild_issue_indexer = Rebuild issue indexer
users.user_manage_panel = Manage user accounts
-users.new_account = Create User Account
+users.new_account = Create user account
users.name = Username
users.full_name = Full name
users.activated = Activated
@@ -3018,14 +3132,20 @@ users.update_profile_success = The user account has been updated.
users.edit_account = Edit user account
users.max_repo_creation = Maximum number of repositories
users.max_repo_creation_desc = (Enter -1 to use the global default limit.)
-users.is_activated = User Account Is Activated
-users.prohibit_login = Disable sign-in
-users.is_admin = Is administrator
-users.is_restricted = Is restricted
+users.is_activated = Activated account
+users.activated.description = Completion of email verification. The owner of an unactivated account will not be able to log in until email verification is completed.
+users.prohibit_login = Suspended account
+users.block.description = Block this user from interacting with this service through their account and prohibit signing in.
+users.is_admin = Administrator account
+users.admin.description = Grant this user full access to all administrative features available through the web UI and the API.
+users.is_restricted = Restricted account
+users.restricted.description = Only allow interaction with the repositories and organizations where this user is added as a collaborator. This prevents access to public repositories on this instance.
users.allow_git_hook = Can create Git hooks
users.allow_git_hook_tooltip = Git hooks are executed as the OS user running Forgejo and will have the same level of host access. As a result, users with this special Git hook privilege can access and modify all Forgejo repositories as well as the database used by Forgejo. Consequently they are also able to gain Forgejo administrator privileges.
users.allow_import_local = Can import local repositories
+users.local_import.description = Allow importing repositories from the server's local file system. This can be a security issue.
users.allow_create_organization = Can create organizations
+users.organization_creation.description = Allow creation of new organizations.
users.update_profile = Update user account
users.delete_account = Delete user account
users.cannot_delete_self = You cannot delete yourself
@@ -3062,6 +3182,10 @@ emails.not_updated = Failed to update the requested email address: %v
emails.duplicate_active = This email address is already active for a different user.
emails.change_email_header = Update Email Properties
emails.change_email_text = Are you sure you want to update this email address?
+emails.delete = Delete Email
+emails.delete_desc = Are you sure you want to delete this email address?
+emails.deletion_success = The email address has been deleted.
+emails.delete_primary_email_error = You can not delete the primary email.
orgs.org_manage_panel = Manage organizations
orgs.name = Name
@@ -3071,7 +3195,7 @@ orgs.new_orga = New organization
repos.repo_manage_panel = Manage repositories
repos.unadopted = Unadopted repositories
-repos.unadopted.no_more = No more unadopted repositories found
+repos.unadopted.no_more = No unadopted repositories found.
repos.owner = Owner
repos.name = Name
repos.private = Private
@@ -3094,12 +3218,12 @@ packages.size = Size
packages.published = Published
defaulthooks = Default webhooks
-defaulthooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Forgejo events trigger. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the webhooks guide .
+defaulthooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Forgejo events trigger. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the webhooks guide .
defaulthooks.add_webhook = Add Default Webhook
defaulthooks.update_webhook = Update Default Webhook
systemhooks = System webhooks
-systemhooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Forgejo events trigger. Webhooks defined here will act on all repositories on the system, so please consider any performance implications this may have. Read more in the webhooks guide .
+systemhooks.desc = Webhooks automatically make HTTP POST requests to a server when certain Forgejo events trigger. Webhooks defined here will act on all repositories on the system, so please consider any performance implications this may have. Read more in the webhooks guide .
systemhooks.add_webhook = Add System Webhook
systemhooks.update_webhook = Update System Webhook
@@ -3180,34 +3304,23 @@ auths.oauth2_admin_group = Group claim value for administrator users. (Optional
auths.oauth2_restricted_group = Group claim value for restricted users. (Optional - requires claim name above)
auths.oauth2_map_group_to_team = Map claimed groups to organization teams. (Optional - requires claim name above)
auths.oauth2_map_group_to_team_removal = Remove users from synchronized teams if user does not belong to corresponding group.
-auths.enable_auto_register = Enable auto registration
-auths.sspi_auto_create_users = Automatically create users
-auths.sspi_auto_create_users_helper = Allow SSPI auth method to automatically create new accounts for users that login for the first time
-auths.sspi_auto_activate_users = Automatically activate users
-auths.sspi_auto_activate_users_helper = Allow SSPI auth method to automatically activate new users
-auths.sspi_strip_domain_names = Remove domain names from usernames
-auths.sspi_strip_domain_names_helper = If checked, domain names will be removed from logon names (eg. "DOMAIN\user" and "user@example.org" both will become just "user").
-auths.sspi_separator_replacement = Separator to use instead of \, / and @
-auths.sspi_separator_replacement_helper = The character to use to replace the separators of down-level logon names (eg. the \ in "DOMAIN\user") and user principal names (eg. the @ in "user@example.org").
-auths.sspi_default_language = Default user language
-auths.sspi_default_language_helper = Default language for users automatically created by SSPI auth method. Leave empty if you prefer language to be automatically detected.
auths.tips = Tips
auths.tips.gmail_settings = Gmail settings:
auths.tips.oauth2.general = OAuth2 authentication
auths.tips.oauth2.general.tip = When registering a new OAuth2 authentication, the callback/redirect URL should be:
auths.tip.oauth2_provider = OAuth2 provider
-auths.tip.bitbucket = Register a new OAuth consumer on https://bitbucket.org/account/user//oauth-consumers/new and add the permission "Account" - "Read"
+auths.tip.bitbucket = Register a new OAuth consumer on %s and add the permission "Account" - "Read"
auths.tip.nextcloud = Register a new OAuth consumer on your instance using the following menu "Settings -> Security -> OAuth 2.0 client"
-auths.tip.dropbox = Create a new application at https://www.dropbox.com/developers/apps
-auths.tip.facebook = Register a new application at https://developers.facebook.com/apps and add the product "Facebook Login"
-auths.tip.github = Register a new OAuth application on https://github.com/settings/applications/new
-auths.tip.gitlab_new = Register a new application on https://gitlab.com/-/profile/applications
-auths.tip.google_plus = Obtain OAuth2 client credentials from the Google API console at https://console.developers.google.com/
+auths.tip.dropbox = Create a new application at %s
+auths.tip.facebook = Register a new application at %s and add the product "Facebook Login"
+auths.tip.github = Register a new OAuth application on %s
+auths.tip.gitlab_new = Register a new application on %s
+auths.tip.google_plus = Obtain OAuth2 client credentials from the Google API console at %s
auths.tip.openid_connect = Use the OpenID Connect Discovery URL (/.well-known/openid-configuration) to specify the endpoints
-auths.tip.twitter = Go to https://dev.twitter.com/apps, create an application and ensure that the โAllow this application to be used to Sign in with Twitterโ option is enabled
-auths.tip.discord = Register a new application on https://discordapp.com/developers/applications/me
-auths.tip.gitea = Register a new OAuth2 application. Guide can be found at https://forgejo.org/docs/latest/user/oauth2-provider
-auths.tip.yandex = Create a new application at https://oauth.yandex.com/client/new. Select following permissions from the "Yandex.Passport API" section: "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"
+auths.tip.twitter = Go to %s, create an application and ensure that the โAllow this application to be used to Sign in with Twitterโ option is enabled
+auths.tip.discord = Register a new application on %s
+auths.tip.gitea = Register a new OAuth2 application. Guide can be found at %s
+auths.tip.yandex = Create a new application at %s. Select following permissions from the "Yandex.Passport API" section: "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"
auths.tip.mastodon = Input a custom instance URL for the mastodon instance you want to authenticate with (or use the default one)
auths.edit = Edit authentication source
auths.activated = This authentication source is activated
@@ -3379,6 +3492,7 @@ monitor.process = Running Processes
monitor.stacktrace = Stacktrace
monitor.processes_count = %d Processes
monitor.download_diagnosis_report = Download diagnosis report
+monitor.duration = Duration (s)
monitor.desc = Description
monitor.start = Start Time
monitor.execute_time = Execution Time
@@ -3427,7 +3541,7 @@ self_check.no_problem_found = No problem found yet.
self_check.database_collation_mismatch = Expect database to use collation: %s
self_check.database_collation_case_insensitive = Database is using a collation %s, which is an insensitive collation. Although Forgejo could work with it, there might be some rare cases which don't work as expected.
self_check.database_inconsistent_collation_columns = Database is using collation %s, but these columns are using mismatched collations. It might cause some unexpected problems.
-self_check.database_fix_mysql = For MySQL/MariaDB users, you could use the "gitea doctor convert" command to fix the collation problems, or you could also fix the problem by "ALTER ... COLLATE ..." SQLs manually.
+self_check.database_fix_mysql = For MySQL/MariaDB users, you could use the "forgejo doctor convert" command to fix the collation problems, or you could also fix the problem by "ALTER ... COLLATE ..." SQLs manually.
[action]
create_repo = created repository %s
@@ -3557,14 +3671,31 @@ versions = Versions
versions.view_all = View all
dependency.id = ID
dependency.version = Version
+search_in_external_registry = Search in %s
alpine.registry = Setup this registry by adding the url in your /etc/apk/repositories
file:
alpine.registry.key = Download the registry public RSA key into the /etc/apk/keys/
folder to verify the index signature:
alpine.registry.info = Choose $branch and $repository from the list below.
alpine.install = To install the package, run the following command:
-alpine.repository = Repository Info
+alpine.repository = Repository info
alpine.repository.branches = Branches
alpine.repository.repositories = Repositories
alpine.repository.architectures = Architectures
+arch.pacman.helper.gpg = Add trust certificate for pacman:
+arch.pacman.repo.multi = %s has the same version in different distributions.
+arch.pacman.repo.multi.item = Configuration for %s
+arch.pacman.conf = Add server with related distribution and architecture to /etc/pacman.conf
:
+arch.pacman.sync = Sync package with pacman:
+arch.version.properties = Version properties
+arch.version.description = Description
+arch.version.provides = Provides
+arch.version.groups = Group
+arch.version.depends = Depends
+arch.version.optdepends = Optional depends
+arch.version.makedepends = Make depends
+arch.version.checkdepends = Check depends
+arch.version.conflicts = Conflicts
+arch.version.replaces = Replaces
+arch.version.backup = Backup
cargo.registry = Setup this registry in the Cargo configuration file (for example ~/.cargo/config.toml
):
cargo.install = To install the package using Cargo, run the following command:
chef.registry = Setup this registry in your ~/.chef/config.rb
file:
@@ -3572,18 +3703,19 @@ chef.install = To install the package, run the following command:
composer.registry = Setup this registry in your ~/.composer/config.json
file:
composer.install = To install the package using Composer, run the following command:
composer.dependencies = Dependencies
-composer.dependencies.development = Development Dependencies
+composer.dependencies.development = Development dependencies
conan.details.repository = Repository
conan.registry = Setup this registry from the command line:
conan.install = To install the package using Conan, run the following command:
conda.registry = Setup this registry as a Conda repository in your .condarc
file:
conda.install = To install the package using Conda, run the following command:
-container.details.type = Image Type
+container.images.title = Images
+container.details.type = Image type
container.details.platform = Platform
container.pull = Pull the image from the command line:
-container.digest = Digest:
+container.digest = Digest
container.multi_arch = OS / Arch
-container.layers = Image Layers
+container.layers = Image layers
container.labels = Labels
container.labels.key = Key
container.labels.value = Value
@@ -3592,7 +3724,7 @@ cran.install = To install the package, run the following command:
debian.registry = Setup this registry from the command line:
debian.registry.info = Choose $distribution and $component from the list below.
debian.install = To install the package, run the following command:
-debian.repository = Repository Info
+debian.repository = Repository info
debian.repository.distributions = Distributions
debian.repository.components = Components
debian.repository.architectures = Architectures
@@ -3611,10 +3743,10 @@ npm.registry = Setup this registry in your project .npmrc
file:
npm.install = To install the package using npm, run the following command:
npm.install2 = or add it to the package.json file:
npm.dependencies = Dependencies
-npm.dependencies.development = Development Dependencies
-npm.dependencies.bundle = Bundled Dependencies
-npm.dependencies.peer = Peer Dependencies
-npm.dependencies.optional = Optional Dependencies
+npm.dependencies.development = Development dependencies
+npm.dependencies.bundle = Bundled dependencies
+npm.dependencies.peer = Peer dependencies
+npm.dependencies.optional = Optional dependencies
npm.details.tag = Tag
pub.install = To install the package using Dart, run the following command:
pypi.requires = Requires Python
@@ -3623,13 +3755,20 @@ rpm.registry = Setup this registry from the command line:
rpm.distros.redhat = on RedHat based distributions
rpm.distros.suse = on SUSE based distributions
rpm.install = To install the package, run the following command:
-rpm.repository = Repository Info
+rpm.repository = Repository info
rpm.repository.architectures = Architectures
rpm.repository.multiple_groups = This package is available in multiple groups.
+alt.registry = Setup this registry from the command line:
+alt.registry.install = To install the package, run the following command:
+alt.install = Install package
+alt.setup = Add a repository to the list of connected repositories (choose the necessary architecture instead of "_arch_"):
+alt.repository = Repository info
+alt.repository.architectures = Architectures
+alt.repository.multiple_groups = This package is available in multiple groups.
rubygems.install = To install the package using gem, run the following command:
rubygems.install2 = or add it to the Gemfile:
-rubygems.dependencies.runtime = Runtime Dependencies
-rubygems.dependencies.development = Development Dependencies
+rubygems.dependencies.runtime = Runtime dependencies
+rubygems.dependencies.development = Development dependencies
rubygems.required.ruby = Requires Ruby version
rubygems.required.rubygems = Requires RubyGem version
swift.registry = Setup this registry from the command line:
@@ -3698,7 +3837,7 @@ management = Manage secrets
[actions]
actions = Actions
-unit.desc = Manage integrated CI/CD pipelines with Forgejo Actions
+unit.desc = Manage integrated CI/CD pipelines with Forgejo Actions.
status.unknown = Unknown
status.waiting = Waiting
@@ -3761,10 +3900,11 @@ runs.actors_no_select = All actors
runs.status_no_select = All status
runs.no_results = No results matched.
runs.no_workflows = There are no workflows yet.
-runs.no_workflows.quick_start = Don't know how to start with Forgejo Actions? See the quick start guide .
-runs.no_workflows.documentation = For more information on Forgejo Actions, see the documentation .
+runs.no_workflows.help_write_access = Don't know how to start with Forgejo Actions? Check out the quick start in the user documentation to write your first workflow, then set up a Forgejo runner to execute your jobs.
+runs.no_workflows.help_no_write_access = To learn about Forgejo Actions, see the documentation .
runs.no_runs = The workflow has no runs yet.
runs.empty_commit_message = (empty commit message)
+runs.expire_log_message = Logs have been purged because they were too old.
workflow.disable = Disable workflow
workflow.disable_success = Workflow "%s" disabled successfully.
@@ -3790,6 +3930,7 @@ variables.deletion.description = Removing a variable is permanent and cannot be
variables.description = Variables will be passed to certain actions and cannot be read otherwise.
variables.id_not_exist = Variable with ID %d does not exist.
variables.edit = Edit Variable
+variables.not_found = Failed to find the variable.
variables.deletion.failed = Failed to remove variable.
variables.deletion.success = The variable has been removed.
variables.creation.failed = Failed to add variable.
@@ -3798,6 +3939,7 @@ variables.update.failed = Failed to edit variable.
variables.update.success = The variable has been edited.
[projects]
+deleted.display_name = Deleted Project
type-1.display_name = Individual project
type-2.display_name = Repository project
type-3.display_name = Organization project
@@ -3815,3 +3957,6 @@ submodule = Submodule
filepreview.line = Line %[1]d in %[2]s
filepreview.lines = Lines %[1]d to %[2]d in %[3]s
filepreview.truncated = Preview has been truncated
+
+[translation_meta]
+test = This is a test string. It is not displayed in Forgejo UI but is used for testing purposes. Feel free to enter "ok" to save time (or a fun fact of your choice) to hit that sweet 100% completion mark :)
diff --git a/options/locale/locale_eo.ini b/options/locale/locale_eo.ini
index 275fc069f5..e4fb8cdbc7 100644
--- a/options/locale/locale_eo.ini
+++ b/options/locale/locale_eo.ini
@@ -1,6 +1,3 @@
-
-
-
[common]
tracked_time_summary = Resumo de trakita tempo bazita sur filtriloj de temolisto
language = Lingvo
@@ -29,7 +26,7 @@ your_profile = Profilo
sign_out = Adiaลญi
settings = Agordoj
logo = Emblemo
-toc = Listo de enhavo
+toc = Enhavotabelo
admin_panel = Retejadministrado
webauthn_unsupported_browser = Via retfoliumilo ne jam subtenas la salutmanieron WebAuthn.
new_org = Novan organizaฤตon
@@ -53,7 +50,7 @@ template = ลablono
webauthn_press_button = Bonvolu premi la butonon sur via sekurลlosiloโฆ
signed_in_as = Salutinta kiel
sign_up = Registriฤi
-enable_javascript = ฤi tiu retejo bezonas JavaScriptโon.
+enable_javascript = ฤi tiu retejo bezonas JavaSkripton.
home = Hejmo
email = Retpoลtadreso
your_settings = Agordoj
@@ -65,7 +62,7 @@ collaborative = Kunlaboraj
pull_requests = Tirpetoj
cancel = Nuligi
preview = Antaลญvido
-disabled = Malลaltita
+disabled = Malaktivigita
go_back = Reiri
copy_content = Kopii enhavon
archived = Arฤฅivita
@@ -108,12 +105,12 @@ unknown = Nekonata
issues = Eraroj
error404 = Aลญ tiu ฤi paฤo ne ekzistas aลญ vi ne rajtas vidi ฤin.
retry = Reprovi
-activities = Agoj
+activities = Aktivecoj
confirm_delete_selected = Konfirmi forigon de ฤiu elektito?
-forks = Disbranฤiฤaj
+forks = Disbranฤigoj
new_mirror = Novan spegulon
re_type = Retajpu pasvorton
-new_fork = Novan disbranฤiฤon de deponejo
+new_fork = Novan disbranฤiฤo de deponejo
new_project_column = Novan kolumnon
new_migrate = Novan enporton
mirror = Spegulo
@@ -122,12 +119,12 @@ remove = Forigi
filter = Filtri
filter.is_archived = Arฤฅivita
filter.not_archived = Nearฤฅivita
-filter.is_fork = Disbranฤigita
-filter.not_fork = Nedisbranฤigita
-filter.is_mirror = Spegulita
-filter.not_mirror = Nespegulita
-filter.is_template = ลablono
-filter.not_template = Neลablono
+filter.is_fork = Disbranฤigoj
+filter.not_fork = Ne disbranฤigoj
+filter.is_mirror = Speguloj
+filter.not_mirror = Ne speguloj
+filter.is_template = ลablonoj
+filter.not_template = Ne ลablonoj
filter.public = Publika
filter.private = Privata
dashboard = Labortablo
@@ -135,6 +132,21 @@ toggle_menu = Baskuli menuon
access_token = Alira ฤตetono
remove_all = Forigi ฤion
remove_label_str = Forigi ยซ%sยป
+test = Provo
+invalid_data = Nevalidaj datumoj: %v
+more_items = Pli da eroj
+copy_generic = Kopii al tondujo
+confirm_delete_artifact = ฤu vi certas, ke vi volas forigi la artefakton "%s"?
+artifacts = Artefaktoj
+new_repo.title = Novan deponejon
+filter.clear = Forigi filtrilojn
+new_migrate.title = Novan migrigon
+new_org.title = Novan organizaฤตon
+new_repo.link = Novan deponejon
+new_migrate.link = Novan migrigon
+new_org.link = Novan organizaฤตon
+error413 = Vi plenkonsumis vian kvoton.
+twofa_scratch = Sukuranta kodo por duobla aลญtentikigo
[editor]
buttons.list.ordered.tooltip = Aldoni nombran liston
@@ -151,10 +163,18 @@ buttons.mention.tooltip = Mencii uzanton aลญ grupon
buttons.italic.tooltip = Aldoni oblikvan tekston
buttons.link.tooltip = Aldoni ligilon
buttons.disable_monospace_font = Malsalti egallarฤan signoformaron
+buttons.indent.tooltip = Krommarฤeni erojn je unu nivelo
+buttons.unindent.tooltip = Malkrommarฤeni erojn je unu nivelo
+buttons.new_table.tooltip = Aldoni tabelon
+table_modal.header = Aldoni tabelon
+table_modal.placeholder.header = Kapo
+table_modal.placeholder.content = Enhavo
+table_modal.label.rows = Horizontaloj
+table_modal.label.columns = Vertikaloj
[aria]
navbar = Esplora breto
-footer.software = Pri programaro
+footer.software = Pri ฤi tiu programaro
footer.links = Ligiloj
footer = Piedo
@@ -164,65 +184,67 @@ string.desc = ZโA
[error]
not_found = La celo ne troviฤis.
-report_message = Se vi pensas ke ฤi tio estas eraro je Forgejo mem, bonvolu traserฤi la erarraportojn ฤe Codeberg aลญ fari novan raporton, laลญnecese.
+report_message = Se vi pensas ke ฤi tio estas eraro je Forgejo mem, bonvolu traserฤi la erarraportojn ฤe Codeberg aลญ fari novan raporton, laลญnecese.
network_error = Reteraro
invalid_csrf = Malvalida peto: malvalida CSRF-kodo
occurred = Eraris iel
missing_csrf = Malvalida peto: neniu CSRF-kodo
-server_internal = Eraris interno de servilo
+server_internal = Ena servila eraro
[heatmap]
less = Malpli
number_of_contributions_in_the_last_12_months = %s kontribuoj dum la pasintaj 12 monatoj
contributions_zero = Neniu kontribuo
more = Pli
+contributions_format = {contributions} la {day}-an de {month} {year}
+contributions_one = kontribuaฤตo
+contributions_few = kontribuaฤตoj
[startpage]
app_desc = Senpena kaj memgastigebla Git-servo
install = Facile instalebla
lightweight = Malpeza
license = Libera fontkodo
-platform_desc = Forgejo ruleblas ฤie ajn Go bittradukeblas: Windows, macOS, Linux, ARM, etc. Elektu laลญplaฤe!
-install_desc = Simple aลญ prenu la ruldosieron por via operaciumo, aลญ instalu enuje per Docker , aลญ instalu pakaฤตe .
+install_desc = Simple aลญ prenu la ruldosieron por via operaciumo, aลญ instalu enuje per Docker , aลญ instalu pakaฤตe .
lightweight_desc = Forgejo ne penigos vian servilon, kaj eฤ ruleblas je Raspberry Pi. Konservu vian komputpotencon!
platform = Plursistema
-license_desc = Ek, prenu Forgejon ! Aliฤu kaj helpu nin plibonigi la projekton. Ne timu kontribui!
+license_desc = Ek, prenu Forgejon ! Aliฤu kaj helpu nin plibonigi la projekton. Ne timu kontribui!
[install]
title = Komenca agordado
install = Instalado
db_name = Datumbazonomo
-run_user = Rulu kiel uzanto
+run_user = Ruli kiel tiu uzanto
log_root_path = Protokola dosiervojo
-err_admin_name_is_invalid = Uzantonomo de administranto malvalidas
+err_admin_name_is_invalid = Uzantnomo de administranto malvalidas
log_root_path_helper = Protokoloj skribiฤos en ฤi tiun dosierujon.
-allow_only_external_registration.description = Permesi registriฤojn sole per fremdaj servoj
+allow_only_external_registration.description = Uzantoj rajtas krei novajn kontojn nur uzante agorditajn fremdajn servojn.
user = Uzantonomo
smtp_addr = SMTP adreso
smtp_port = SMTP adrespordo
-disable_registration = Malลalti registriฤon
+disable_registration = Malaktivigi registriฤon
reinstall_confirm_check_3 = Vi asertas ke vi plencertas ke tiu ฤi Forgejo ruliฤas per la ฤusta app.ini, kaj ke vi certas ke devas reinstali. Vi asertas ke vi bone komprenas la supre menciitajn danฤerojn.
-federated_avatar_lookup.description = ลaltas serฤadon de profilbildoj el federaj fontoj per Libravatar.
+federated_avatar_lookup.description = Serฤi profilbildojn per Libravatar.
mailer_password = SMTP pasvorto
repo_path = Deponeja dosiervojo
err_empty_admin_email = La retpoลtadreso de administranto ne malplenu.
app_url_helper = Baza URL por HTTP(S) elลutaj ligiloj kaj retleteroj.
-mailer_user = SMTP uzantonomo
-openid_signup = ลalti registriฤon per OpenID
+mailer_user = SMTP uzantnomo
+openid_signup = Aktivigi registriฤon per OpenID
reinstall_confirm_check_2 = Deponejoj kaj agordoj eble devos re-interakordiฤi. ลaltinte tiun ฤi skatolon, vi asertas ke vi permane interakordigos kaj la hokojn por la deponejoj kaj authorized_keys. Vi asertas, ke deponejaj kaj spegulaj agordoj pravas.
path = Vojo
-no_admin_and_disable_registration = Neeblas malลalti memregistradon sen kreiฤo de administranta konto.
-disable_gravatar.description = Malลaltas Gravatar kaj fremdajn fontojn de profilbildoj. Implicita profilbildo uziฤos, krom se la uzanto alลutus loke profilbildon.
-offline_mode.description = Malลaltas uzon de fremdaj serviloj por datumosendoj, ฤio datumo sendiฤos deloke.
+no_admin_and_disable_registration = Neeblas malaktivigi memregistradon sen krei administrantan konton.
+disable_gravatar.description = Malaktivigas Gravatar-on kaj aliajn fremdajn fontojn de profilbildoj. Defaลญltaj profilbildoj uziฤos, krom se la uzanto alลutus loke profilbildon.
+offline_mode.description = Malaktivigi uzon de fremdaj serviloj por datumosendaฤตoj kaj okupiฤas pri ciuj datumoj loke.
reinstall_confirm_message = Reinstalado al jamekzistanta Forgejo-datumbazo povas okazigi plurajn problemojn. Vi kredeble anstataลญe rulu Forgejon kun via jama ยซapp.iniยป. Sed se vi certas, ke vi komprenas kion vi faras, asertu jene:
run_user_helper = Forgejo ruliฤos sub tiu ฤi uzanto de via operaciumo. Sciu, ke tiu ฤi uzanto bezonos aliron al la dosiervojon de deponejoj.
domain = Retnomo
err_admin_name_pattern_not_allowed = Uzantonomo de administranto malvalidas, ฤar la nomo akordas rezervan ลablonon
-disable_registration.description = Malลaltas registriฤojn. Sole administrantoj rajtos krei novajn kontojn.
+disable_registration.description = Malaktivigas registriฤojn. Sole administrantoj rajtos krei novajn kontojn.
db_schema = Skemo
reinstall_error = Vi provas instali al jamekzistanta Forgejo-datumbazo
err_empty_admin_password = La pasvorto de administranto ne malplenu.
-disable_gravatar = Malลalti profilbildojn per Gravatar
+disable_gravatar = Malaktivigi Gravatar-on
repo_path_helper = Foraj Git-deponejoj konserviฤos al tiu ฤi dosierujo.
sqlite_helper = Dosiervojo por la datumbazo SQLite3. Enigu absolutan vojon se vi rulas Forgejon kiel servo.
enable_captcha = ลalti dumregistriฤan teston de homeco
@@ -230,7 +252,7 @@ require_db_desc = Forgejo bezonas kiel datumbazo MySQL, PostgreSQL, SQLite3, aลญ
smtp_from = Sendu retleterojn kiel
general_title = ฤeneralaj agordoj
password = Pasvorto
-lfs_path_helper = Dosieroj spurataj de Git LFS konserviฤos en tiu ฤi dosierujo. Lasu malplena por malลalti.
+lfs_path_helper = Dosieroj spurataj de Git LFS konserviฤos en tiu ฤi dosierujo. Lasu malplena por malaktivigi.
openid_signin = ลalti salutadon per OpenID
host = Gastiganto
docker_helper = Se vi rulas Forgejon per Docker, bonvolu legi la gvidpaฤojn antaลญ ajna agordoลanฤo.
@@ -238,67 +260,71 @@ federated_avatar_lookup = ลalti federajn profilbildojn
optional_title = Malnepraj agordoj
domain_helper = Retnomo aลญ adreso de la servilo.
mail_notify = ลalti retpoลtajn sciigojn
-app_url = Forgejo Baza URL
+app_url = Baza URL
ssl_mode = SSL
db_title = Datumbazaj agordoj
err_empty_db_path = La datumbazovojo de SQLite3 ne malplenu.
-openid_signin.description = ลaltas salutadon per OpenID.
+openid_signin.description = Permesas al la uzantoj ensaluti per OpenID.
smtp_from_helper = Retpoลtadreson kiun uzos Forgejo. Enmetu ordinaran adreson aลญ laลญ la formo ยซ"Name" ยป.
-enable_captcha.description = Postulas teston de homeco dum registriฤoj.
-ssh_port_helper = Adresporda numero kiun atentas via SSH-servilo. Lasu malplena por malลalti.
+enable_captcha.description = Postuli teston de homeco al la uzantoj kreantaj kontojn.
+ssh_port_helper = Adresporda numero kiu estos uzata de la SSH-servilo. Lasu malplena por malaktivigi la SSH-servilon.
lfs_path = Git LFS dosiervojo
-app_name_helper = Vi povas enmeti la nomon de via kompanio ฤi tien.
-http_port_helper = Adresporda numero kiun atentos la HTTP-servilo de Forgejo.
-http_port = Forgejo HTTP adrespordo
+app_name_helper = Vi povas enmeti la nomon de via kompanio ฤi tien. ฤi montriฤos en ฤiuj retpaฤoj.
+http_port_helper = Adresporda numero kiu estos uzta de la HTTP-servilo de Forgejo.
+http_port = HTTP adrespordo
db_schema_helper = Lasu malplena por implicita (ยซpublicยป).
ssh_port = SSH adrespordo
-err_admin_name_is_reserved = Uzantonomo de administranto malvalidas, tiu uzantonomo estas rezerva
-openid_signup.description = ลaltas uzantregistriฤon per OpenID.
+err_admin_name_is_reserved = Uzantnomo de administranto malvalidas, tiu uzantnomo estas rezerva
+openid_signup.description = Permesi al la uzantoj krei kontojn per OpenID se reฤitriฤo aktivas.
db_type = Datumbazospeco
email_title = Retpoลtaj agordoj
offline_mode = ลalti lokan reฤimon
reinstall_confirm_check_1 = La datumoj ฤifritaj per la ลlosilo SECRET_KEY en app.ini eble perdiฤos; eblas ke uzantoj ne povos saluti per dumaniera-saluto aลญ unufojaj pasvortoj, kaj ke spegulado ne funkcios ฤuste. ลaltinte tiun ฤi skatolon, vi asertas ke la nuna app.ini dosiero enhavas la ฤustan SECRET_KEY.
app_name = Retejonomo
server_service_title = Servilaj kaj fremdservaj agordoj
-require_sign_in_view = Postuli saluton por vidi paฤojn
+require_sign_in_view = Postuli saluton por vidi instancan enhavon
register_confirm = Postuli retpoลtan kontrolon por registri
admin_password = Pasvorto
admin_title = Administrantaj kontagordoj
admin_email = Retpoลtadreso
install_btn_confirm = Instali Forgejon
-require_sign_in_view.description = Kaลi paฤon de ajna nesalutinto. Vizitantoj sole vidos salutajn kaj registriฤajn paฤojn.
+require_sign_in_view.description = Kaลi paฤon de ajna nesalutinto. Vizitantoj nur vidos salutajn kaj registriฤajn paฤojn.
invalid_db_setting = La datumbazaj agordoj malvalidas: %v
invalid_db_table = La datumbaza tabelo ยซ%sยป malvalidas: %v
sqlite3_not_available = ฤi tiu versio de Forgejo ne subtenas SQLite3. Bonvolu elลuti la oficialan ruldosieron de %s (ne la version ยซgobuildยป).
invalid_app_data_path = La programdatuma dosiervojo malvalidas: %s
-test_git_failed = Ne povis testi programon ยซgitยป: %v
+test_git_failed = Ne povis testi "git" komandon: %v
confirm_password = Konfirmi pasvorton
invalid_repo_path = La deponeja dosiervojo malvalidas: %v
-admin_name = Administranto uzantonomo
-admin_setting.description = Krei administranton estas malnepra. La unue registrota uzanto memage iฤos administranto.
-run_user_not_match = La ยซrulu kielยป uzantonomo ne samas al la nuna uzantonomo: %s -> %s
+admin_name = Administranta uzantnomo
+admin_setting.description = Krei administrantan konton malnepras. La unua registrota uzanto aลญtomate iฤos administranto.
+run_user_not_match = La "ruli kiel tiu uzanto" uzantnomo ne samas al la nuna uzantnomo: %s -> %s
secret_key_failed = Malsukcesis kreante sekretan ลlosilon: %v
save_config_failed = Malsukcesis konservante agordojn: %v
invalid_admin_setting = Agordoj de administranta konto malvalidas: %v
-enable_update_checker_helper_forgejo = Foje serฤas novajn versiojn de Forgejo per kontrolado de DNS TXT registraฤตo ฤe release.forgejo.org.
+enable_update_checker_helper_forgejo = Periode serฤos novajn versiojn de Forgejo kontrolante DNS TXT registraฤตon ฤe release.forgejo.org.
invalid_log_root_path = La protokola dosiervojo malvalidas: %v
-default_enable_timetracking = ลalti tempospuradon implicite
-default_enable_timetracking.description = ลaltus tempospuradon por novaj deponejoj implicite.
-default_keep_email_private.description = Kaลus retpoลtadresojn de novaj kontoj implicite.
-default_allow_create_organization = Permesi kreadon de organizaฤตoj implicite
+default_enable_timetracking = Aktivigi tempospuradon defaลญlte
+default_enable_timetracking.description = Aktivigas tempospuradon por novaj deponejoj defaลญlte.
+default_keep_email_private.description = Kaลi defaลญlte retpoลtadresojn por novaj uzantoj por ke iliaj informoj ne senprokraste likiฤas post reฤistriฤo.
+default_allow_create_organization = Permesi kreadon de organizaฤตoj defaลญlte
allow_dots_in_usernames = Permesi ฤeeston de punktoj en uzantonomoj. Ne efikas je jamaj kontoj.
-no_reply_address = Retnomo de retpoลtaj kaลadresoj
-default_keep_email_private = Kaลi retpoลtadresojn implicite
-default_allow_create_organization.description = Permesus novajn uzantojn krei organizaฤตojn implicite.
+no_reply_address = Retnomo por kaลitaj retpoลtadresoj
+default_keep_email_private = Kaลi retpoลtadresojn defaลญlte
+default_allow_create_organization.description = Permesi al novaj uzantoj krei organizaฤตojn defaลญlte. Kiam ฤi tiu opcio malaktiviฤas, administranto devos permesi al novaj uzantoj krei organizaฤตojn.
env_config_keys_prompt = La jenaj mediaj variantoj ankaลญ fandiฤos kun via agordodosiero:
no_reply_address_helper = Retnomo kiu uziฤus por uzantoj kun kaลita retpoลtadreso. Ekzemple, la uzanto ยซadamoยป protokoliฤus je Git kiel ยซadamo@nerespondu.ekzemplo.orgยป se la adreskaลa retnomo estus ยซnerespondu.ekzemplo.orgยป.
-enable_update_checker = ลalti novversian kontrolanton
+enable_update_checker = Aktivigi novversian kontrolanton
password_algorithm = Pasvorthaketiga algoritmo
env_config_keys = Mediagordoj
invalid_password_algorithm = Malvalida pasvorthakeita algoritmo
password_algorithm_helper = Agordas la pasvorthaketigan algoritmon. Algoritmoj havas malsamajn postulojn kaj efikecojn. La algoritmo argon2 sufiฤe sekuras, sed postulas multan memoron kaj eble ne taลญgas por nepotencaj serviloj.
internal_token_failed = Malsukcesis krei internan ฤตetonon: %v
smtp_from_invalid = La ยซSendu retleterojn kielยป adreso malvalidas
+allow_only_external_registration = Permesi registriฤon nur per fremdaj servoj
+app_slogan = Instanca frapfrazo
+app_slogan_helper = Enigu vian instancan frapfrazon ฤi tien. Lasu malplena por malaktivigi.
+config_location_hint = ฤi tiuj agordoj konserviฤos en:
[admin]
config.app_data_path = Programdatuja doseiervojo
@@ -308,8 +334,8 @@ config.allow_dots_in_usernames = Permesi ฤeeston de punktoj en uzantonomoj. Ne
filter = Aliaj filtriloj
show_archived = Arฤฅivita
search_repos = Serฤi deponejonโฆ
-my_orgs = Miaj organizaฤตoj
-uname_holder = Uzantonomo aลญ Retpoลtadreso
+my_orgs = Organizaฤตoj
+uname_holder = Uzantnomo aลญ retpoลtadreso
my_repos = Deponejoj
show_both_archived_unarchived = Montras arฤฅivitajn kaj nearฤฅivitajn
feed_of = Fluo de ยซ%sยป
@@ -326,7 +352,7 @@ show_only_unarchived = Montras sole nearฤฅivitajn
my_mirrors = Miaj speguloj
show_only_archived = Montras sole arฤฅivitajn
view_home = Vidi %s
-switch_dashboard_context = ลanฤi labortablon
+switch_dashboard_context = Baskuli la kuntekston de la kontrolpanelo
[explore]
search.match.tooltip = Inkluzivu sole rezultojn kiuj akordas precize la serฤomendon
@@ -348,22 +374,26 @@ code_search_results = Serฤrezultoj je ยซ%sยป
relevant_repositories = Sole montras aktualajn deponejojn, montri senfiltrajn rezultojn .
code_last_indexed_at = Plejfreลe esplorita je %s
code_no_results = Neniu fontkodo akorda laลญ via serฤomendo trovita.
+forks_few = %d disbranฤigoj
+stars_one = %d stelo
+forks_one = %d disbranฤigo
+stars_few = %d steloj
[auth]
-disable_register_mail = Retpoลta konfirmado dum registriฤo estas malลaltita.
+disable_register_mail = Retpoลta konfirmado dum registriฤo estas malaktivigita.
sign_up_successful = Konto sukcese kreita. Bonvenon!
forgot_password = ฤu forgesis pasvorton?
sign_up_now = ฤu bezonas konton? Registriฤu nun.
forgot_password_title = Forgesis pasvorton
social_register_helper_msg = ฤu vi jam havas konton? Alligu ฤin nun!
create_new_account = Registri konton
-disable_register_prompt = Registrado estas malลaltita. Bonvolu sciigi vian retejestron.
+disable_register_prompt = Registrado estas malaktivigita. Bonvolu sciigi vian retejestron.
register_helper_msg = ฤu vi jam havas konton? Salutu nun!
manual_activation_only = Kunparolu vian retejestron por finpretigi vian konton.
authorization_failed_desc = La aprobo malsukcesis ฤar ni rimarkis malvalidan peton. Bonvolu sciigi la prizorganton de la programo kiun vi provis aprobi.
-oauth_signin_tab = LIgi al jama konto
+oauth_signin_tab = Ligi al jama konto
invalid_password = Via pasvorto ne samas tiun uzitan dum kreiฤo de via konto.
-send_reset_mail = Sendi retleteron por rehavigo de konto
+send_reset_mail = Sendi retleteron de rehavigo
oauth_signin_title = Salutu por aprobi kontligiฤon
reset_password_helper = Rehavigi konton
tab_openid = OpenID
@@ -375,7 +405,7 @@ login_userpass = Saluti
password_too_short = Pasvortoj devas longi minimume %d signojn.
resend_mail = Klaki ฤi tien por resendi vian konfirmleteron
change_unconfirmed_email_error = Ne povis ลanฤi la retpoลtadreson: %v
-authorize_application_description = Se vi permesus aliron, ฤi povos aliri kaj redakti ฤiujn viajn kontinformojn, inkluzivante privatajn deponejojn kaj organizaฤตojn.
+authorize_application_description = Se vi permesus aliron, ฤi povos aliri kaj redakti ฤiujn viajn kontinformojn, inkluzive privatajn deponejojn kaj organizaฤตojn.
allow_password_change = Postuli novan pasvorton de la uzanto (rekomendita)
oauth.signin.error.access_denied = La aprobpeto malakceptiฤis.
authorize_title = Aprobi aliron de via konto al ยซ%sยป?
@@ -387,15 +417,15 @@ disable_forgot_password_mail = Rehavigo de konto estas malsaltita ฤar neniu ret
last_admin = Vi ne povas forigi la lastan administranton. Nepras havi almenaลญ unu administranton.
reset_password_wrong_user = Vi salutis kiel %s, sed la kontrehaviga ligilo estas celata al %s
openid_connect_title = Konekti jaman konton
-confirmation_mail_sent_prompt = Sendis novan konfirmleteron al %s . Bonvolu kontroli vian retleterkeston antaลญ la venonta %s. Se la retpoลtadreso malฤustas, vi povus saluti kaj peti sendon de plia konfirmletero al alian adreson.
-password_pwned = La pasvorton kiun vi elektis listiฤas ฤe listo de ลtelitaj pasvortoj kiu publikiฤis pro datumลtelo. Bonvolu reprovi kun alia pasvorto, kaj konsideru anstataลญigon de ฤi tiu pasvorto ฤe aliaj kontoj.
+confirmation_mail_sent_prompt = Sendis konfirmleteron al %s . Por fini la reฤistriฤon, bonvolu kontroli vian retleterkeston kaj sekvi la provizotan ligilon antaลญ la venonta %s. Se la retletero malฤustas, vi povas saluti kaj peti ke alian konfirmleteron estas sendota al malsama retpoลtadreso.
+password_pwned = La pasvorton kiun vi elektis listiฤas ฤe listo de ลtelitaj pasvortoj kiu publikiฤis pro datumลtelo. Bonvolu reprovi kun alia pasvorto, kaj konsideru anstataลญigon de ฤi tiu pasvorto ฤe aliaj kontoj.
authorize_application_created_by = ฤi tiun programon kreis %s.
-prohibit_login = Salutado malpermesita
+prohibit_login = La konto estas suspendita
openid_register_title = Krei novan konton
email_domain_blacklisted = Vi ne povas registriฤi per via retpoลtadreso.
verify = Konfirmi
oauth_signup_submit = Finfari konton
-prohibit_login_desc = Salutado per via konto estas malpermesita, bonvolu kunparoli vian retejestron.
+prohibit_login_desc = Via konto estas suspendita kaj ne povas interagi kun la instanco. Bonvolu kontakti vian retejestron por regajni aliron.
openid_connect_desc = La elektita OpenID URI estas nekonata. Ligu ฤin al nova konto ฤi tie.
oauth.signin.error = Eraris traktante aprobpeton. Se plu eraros, bonvolu kunparoli la retejestron.
invalid_code = Via konfirmkodo malvalidas aลญ eksdatiฤis.
@@ -405,7 +435,7 @@ email_not_associate = Tiu retpoลtadreso estas ligita al neniu konto.
openid_signin_desc = Enmetu vian OpenID URI. Ekzemple: sofia.openid.example.org aลญ https://openid.example.org/sofia.
disable_forgot_password_mail_admin = Rehavigo de konto sole uzeblas se retpoลto estas agordita. Bonvolu agordi retpoลton por ลalti kontrehavigon.
change_unconfirmed_email = Se vi donis la malฤustan retpoลtadreson dum registriฤo, vi povas ลanฤi ฤin sube, kaj konfirmletero sendiฤus al tiu anstataลญe.
-reset_password_mail_sent_prompt = Sendis novan konfirmleteron al %s . Bonvolu kontroli vian retleterkeston antaลญ la venonta %s, por daลญrigi rehavigon de konto.
+reset_password_mail_sent_prompt = Sendis konfirmleteron al %s . Por fini la rehavigon de konto, bonvolu kontroli vian retleterkeston kaj sekvi la provizotan ligilon antaลญ la venonta %s.
openid_register_desc = La elektita OpenID URI estas nekonata. Ligi ฤin al nova konto ฤi tie.
reset_password = Rehavigo de konto
sspi_auth_failed = SSPI aลญtentikigo malsukcesis
@@ -417,11 +447,23 @@ change_unconfirmed_email_summary = ลanฤi al retpoลtadreson al kiu la aktiviga
invalid_code_forgot_password = Via konfirmkodo malvalidas aลญ jam eksdatiฤis. Klaku ฤi tien por komenci novan saluton.
authorize_redirect_notice = Vi alidirektiฤos al %s se vi aprobus ฤi tiun programon.
active_your_account = Aktivigi vian konton
+unauthorized_credentials = Viaj salutiloj malฤustas aลญ eksdatiฤis. Reprovu vian komandon aลญ vidu %s por pli da informoj
+scratch_code = Sukuranta kodo
+use_scratch_code = Uzi sukurantan kodon
+twofa_scratch_used = Vi uzis vian sukurantan kodon. Vi redirektiฤis al la agorda retpaฤo por forigi la duoblan aลญtentikigon el via aparato aลญ generi novan sukurantan kodon.
+twofa_passcode_incorrect = Via paskodo malฤustas. Se vi mislokis vian aparaton, uzu vian sukurantan kodo por saluti.
+twofa_scratch_token_incorrect = Via sukuranta kodo malฤustas.
+hint_login = ฤu vi jam havas konton? Salutu nun!
+hint_register = ฤu vi bezonas konton? Reฤistriฤi nun.
+sign_up_button = Reฤistriฤi nun.
+sign_in_openid = Daลญrigi kun OpenID
+back_to_sign_in = Reen en la saluton
+use_onetime_code = Uzi unufojan kodon
[mail]
activate_account.text_1 = Saluton %[1]s , dankon pro via registriฤo ฤe %[2]s!
release.title = Nomo: %s
-register_notify = Bonvenon al Forgejo
+register_notify = Bonvenon al %s
reply = aลญ respondu tiun ฤi retleteron rekte
issue.action.close = @%[1]s fermis #%[2]d.
register_notify.text_1 = jen estas via registriฤa konfirmletero por %s!
@@ -430,7 +472,7 @@ link_not_working_do_paste = ฤu ne funkcias? Provu kopii kaj alglui al via retfo
repo.transfer.body = Akceptu per vizito al %s, malakceptu per malatento.
team_invite.text_3 = Noto: ฤi tiu invito estas alcelita al %[1]s. Se vi ne atendis tiun ฤi invito, vi povus simple malatenti tiun ฤi retletero.
repo.collaborator.added.subject = %s aldonis vin al %3
-team_invite.subject = %[1]s invitis vin aliฤi la organizaฤตon %[2]
+team_invite.subject = %[1]s invitis vin aliฤi la organizaฤตon %[2]s
reset_password.text = Bonvolu klaki la sekvontan ligilon por rehavigi vian konton ฤis % :
issue.action.reopen = @%[1]s remalfermis #%[2]d.
issue.action.approve = @%[1]s aprobis tiun ฤi tirpeton.
@@ -452,7 +494,7 @@ admin.new_user.subject = Nova uzanto %s ฤตus registriฤis
register_notify.text_3 = Se iu alia kreis ฤi tiun konton anstataลญ vi, bonvolu ลanฤi vian pasvorton tuj.
release.new.subject = %s en %s eldoniฤis
view_it_on = Vidu ฤin ฤe %s
-register_notify.text_2 = Vi nun povas saluti per la uzantonomo: %s.
+register_notify.text_2 = Vi povas saluti per la uzantonomo: %s
team_invite.text_1 = %[1]s invitis vin aliฤi grupon %[2]s en organizaฤตo %[3]s.
reset_password.title = %s, vi petis rehavigon de via konto
repo.collaborator.added.text = Vi aldoniฤis kiel kunlaboranto de deponejo:
@@ -468,6 +510,19 @@ issue.action.push_n = @%[1]s puลis %[3]d enmetojn al %[2]s
activate_account = Bonvolu aktivigi vian konton
activate_account.title = %s, bonvolu aktivigi vian konton
activate_account.text_2 = Bonvolu klaki la jenan ligilon por aktivigi vian konton antaลญ %s :
+primary_mail_change.text_1 = La ฤefa retpoลtadreso de via konto ฤตus ลanฤiฤis en %[1]s. Tio volas diri ke ฤi tiu retpoลtadreso ne ricevos plu sciigojn pri via konto.
+totp_disabled.subject = TOTP ฤตus malaktiviฤis
+password_change.subject = Via pasvorto ลanฤiฤis
+password_change.text_1 = La pasvorto de via konto ฤตus ลanฤiฤis.
+primary_mail_change.subject = Via ฤefa retpoลtadreso ลanฤiฤis
+totp_disabled.text_1 = La tempobazita unufoja pasvorto (TOTP) en via konto ฤตus malaktiviฤis.
+admin.new_user.text = Bonvolu klaki ฤi tie por konduki ฤi tiun uzanton el la administranta agordilo.
+removed_security_key.subject = Sekureca ลlosilo estas forigita
+removed_security_key.text_1 = La sekureca ลlosilo "%[1]s" ฤตus estas forigita de via konton.
+totp_enrolled.text_1.has_webauthn = Vi ฤตus aktivigis TOTP-n por via konto. Tio volas diri ke por ฤiuj venontaj salutoj al via konto, vi povus uzi TOTP-n kiel 2FA metodo aลญ ajnan sekurecan ลlosilon.
+totp_enrolled.text_1.no_webauthn = Vi ฤตus aktivigis TOTP-n por via konto. Tio volas diri ke por ฤiuj venontaj salutoj al via konto, vi devos uzi TOTP-n kiel 2FA metodo.
+removed_security_key.no_2fa = Ne estas aliaj 2FA agorditaj metodoj, tio estas ke ne plus necesas uzi 2FA-n por saluti.
+totp_disabled.no_2fa = Ne estas plu aliaj 2FA agorditaj metodoj, tio estas ke ne plus necesas uzi 2FA-n por saluti.
[form]
TeamName = Gruponomo
@@ -552,7 +607,7 @@ yes = Jes
[settings]
applications = Programoj
password = Pasvorto
-twofa_disabled = Duobla aลญtentikigo malลaltita.
+twofa_disabled = Duobla aลญtentikigo malaktivigita.
appearance = Aspekto
repos = Deponejoj
delete = Forigi konton
@@ -567,11 +622,11 @@ account_link = Ligitaj kontoj
organization = Organizaฤตoj
public_profile = Publika profilo
openid_desc = OpenID povigas vin utiligi foran servilon por aลญtentikigo.
-twofa_disable_note = Vi povas malลalti duoblan aลญtentikigon, laลญbezone.
+twofa_disable_note = Vi povas malaktivigi duoblan aลญtentikigon, laลญbezone.
security = Sekureco
account = Konto
ssh_gpg_keys = SSH / GPG-ลlosiloj
-twofa_disable = Malลalti duoblan aลญtentikigon
+twofa_disable = Malaktivigi duoblan aลญtentikigon
twofa_enroll = ลalti duoblan aลญtentikigon
orgs = Mastrumi organizaฤตojn
blocked_users = Blokitaj uzantoj
@@ -640,7 +695,7 @@ update_user_avatar_success = Profilbildo de uzanto ฤisdatigita.
manage_oauth2_applications = Mastrumi OAuth2-programojn
activations_pending = Atendas konfirmiฤon
primary = ฤefa
-ssh_disabled = SSH malลaltita
+ssh_disabled = SSH malaktivigita
update_avatar_success = Via profilbildo konserviฤis.
keep_email_private = Kaลi retpoลtadreson
manage_openid = Mastrumi OpenID-adresojn
@@ -806,4 +861,30 @@ npm.details.tag = Etikedo
[search]
-search = Serฤi...
\ No newline at end of file
+search = Serฤi...
+regexp = RegEsp
+milestone_kind = Serฤi celojn...
+code_search_by_git_grep = Nunaj rezultoj de kodoserฤo estas provizitaj de "git grep". Eble estas plibonaj rezultoj se la retejestro aktivigas la indeksilon de kodo.
+code_search_unavailable = Kodoserฤo ne haveblas nune. Bonvolu kontakti la retejestron.
+package_kind = Serฤi pakojn...
+type_tooltip = Serฤotipo
+user_kind = Serฤi uzantojn...
+fuzzy_tooltip = Inkluzivas rezultojn proksime kongruantajn kun la serฤoterminoj
+repo_kind = Serฤi deponejojn...
+org_kind = Serฤi organizaฤตojn...
+code_kind = Serฤi kodon...
+project_kind = Serฤi projektojn...
+team_kind = Serฤi teamojn...
+keyword_search_unavailable = Serฤo per ลlosilvortoj ne haveblas nune. Bonvolu kontakti la retejestron.
+union = ลlosilvortoj
+union_tooltip = Inkluzivas rezultojn kongruantajn kun la ajnaj blankaspacitaj ลlosilvortoj
+commit_kind = Serฤi enmetojn...
+no_results = Ne trovis kongruantajn rezultojn.
+exact = ฤusta
+exact_tooltip = Inkluzivas nur rezultojn kongruantajn kun la ฤustaj serฤoterminoj
+issue_kind = Serฤi erarojn...
+regexp_tooltip = Interpretas la serฤoterminoj kiel regulesprimo
+fuzzy = Svaga
+branch_kind = Serฤi disbranฤigojn...
+runner_kind = Serฤi rulantojn...
+pull_kind = Serฤi tirpetojn...
\ No newline at end of file
diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini
index 8545b93b0c..0bed98c845 100644
--- a/options/locale/locale_es-ES.ini
+++ b/options/locale/locale_es-ES.ini
@@ -19,8 +19,8 @@ language=Idioma
notifications=Notificaciones
active_stopwatch=Rastreador de tiempo activo
create_new=Crearโฆ
-user_profile_and_more=Perfil y ajustesโฆ
-signed_in_as=Identificado como
+user_profile_and_more=Perfil y configuraciรณnโฆ
+signed_in_as=Conectado como
enable_javascript=Este sitio web requiere JavaScript.
toc=Tabla de contenidos
licenses=Licencias
@@ -32,18 +32,18 @@ password=Contraseรฑa
access_token=Token de acceso
re_type=Confirmar contraseรฑa
captcha=CAPTCHA
-twofa=Autenticaciรณn de doble factor
+twofa=Autenticaciรณn de dos factores
twofa_scratch=Cรณdigo de respaldo
passcode=Cรณdigo de acceso
webauthn_insert_key=Introduzca su clave de seguridad
webauthn_sign_in=Presione el botรณn en su clave de seguridad. Si su clave de seguridad no tiene ningรบn botรณn, vuelva a insertarla.
-webauthn_press_button=Por favor, presione el botรณn de su llave de seguridadโฆ
+webauthn_press_button=Por favor, presione el botรณn en su clave de seguridadโฆ
webauthn_use_twofa=Utilice un cรณdigo de doble factor desde su telรฉfono mรณvil
webauthn_error=No se pudo leer su llave de seguridad.
-webauthn_unsupported_browser=Su navegador no soporta actualmente WebAuthn.
+webauthn_unsupported_browser=Actualmente su navegador no soporta WebAuthn.
webauthn_error_unknown=Ha ocurrido un error desconocido. Por favor, intรฉntelo de nuevo.
-webauthn_error_insecure=`WebAuthn sรณlo soporta conexiones seguras. Para probar sobre HTTP, puede utilizar el origen "localhost" o "127.0.0.1"`
+webauthn_error_insecure=WebAuthn sรณlo soporta conexiones seguras. Para probar sobre HTTP, puede utilizar el origen "localhost" o "127.0.0.1"
webauthn_error_unable_to_process=El servidor no pudo procesar su solicitud.
webauthn_error_duplicated=La clave de seguridad no estรก permitida para esta solicitud. Por favor, asegรบrese de que la clave no estรก ya registrada.
webauthn_error_empty=Debe establecer un nombre para esta clave.
@@ -56,10 +56,10 @@ mirror=Rรฉplica
new_repo=Nuevo repositorio
new_migrate=Nueva migraciรณn
new_mirror=Nueva rรฉplica
-new_fork=Nuevo fork de repositorio
+new_fork=Nueva bifurcaciรณn del repositorio
new_org=Nueva organizaciรณn
new_project=Nuevo proyecto
-new_project_column=Columna nueva
+new_project_column=Nueva columna
manage_org=Administrar organizaciones
admin_panel=Administraciรณn del sitio
account_settings=Configuraciones de la cuenta
@@ -72,10 +72,10 @@ all=Todos
sources=Propios
mirrors=Rรฉplica
collaborative=Colaborativo
-forks=Forks
+forks=Bifurcaciones
activities=Actividades
-pull_requests=Pull requests
+pull_requests=Solicitudes de incorporaciรณn de cambios
issues=Incidencias
milestones=Hitos
@@ -86,7 +86,7 @@ rerun=Re-ejecutar
rerun_all=Volver a ejecutar todos los trabajos
save=Guardar
add=Aรฑadir
-add_all=Aรฑadir todo
+add_all=Aรฑadir todos
remove=Eliminar
remove_all=Eliminar todos
remove_label_str=`Eliminar elemento "%s"`
@@ -110,13 +110,13 @@ preview=Vista previa
loading=Cargandoโฆ
error=Error
-error404=La pรกgina a la que estรก intentando acceder o no existe o no estรก autorizado para verla.
+error404=La pรกgina a la que estรก intentando acceder no existe ,ha sido eliminada o no estรก autorizado a verla.
go_back=Volver
never=Nunca
unknown=Desconocido
-rss_feed=Fuentes RSS
+rss_feed=Fuente RSS
pin=Anclar
unpin=Desanclar
@@ -140,24 +140,38 @@ confirm_delete_selected=ยฟBorrar todos los elementos seleccionados?
name=Nombre
value=Valor
view = Vista
-tracked_time_summary = Resumen del tiempo de monitorizaciรณn basado en filtros de la lista de incidencias
+tracked_time_summary = Resumen del tiempo rastreado en funciรณn de los filtros de la lista de incidencias
filter = Filtro
filter.clear = Limpiar filtros
filter.is_archived = Archivado
filter.not_archived = No archivado
-filter.is_mirror = Replicado
-filter.not_mirror = No replicado
-filter.is_template = Plantilla
-filter.not_template = No plantilla
+filter.is_mirror = Replicas
+filter.not_mirror = No replicas
+filter.is_template = Plantillas
+filter.not_template = No plantillas
filter.public = Pรบblico
filter.private = Privado
-toggle_menu = Alternar Menรบ
+toggle_menu = Alternar menรบ
invalid_data = Datos invรกlidos: %v
+confirm_delete_artifact = ยฟEstรกs seguro de que deseas eliminar el artefacto "%s"?
+more_items = Mas cosas
+copy_generic = Copiar al portapapeles
+filter.not_fork = No hay bifurcaciones
+filter.is_fork = Bifurcaciones
+test = Test
+error413 = Has agotado tu cuota.
+new_repo.title = Nuevo repositorio
+new_migrate.title = Nueva migraciรณn
+new_org.title = Nueva organizaciรณn
+new_repo.link = Nuevo repositorio
+new_migrate.link = Nueva migraciรณn
+new_org.link = Nueva organizaciรณn
+copy_path = Copiar ruta
[aria]
navbar=Barra de navegaciรณn
footer=Pie
-footer.software=Acerca del Software
+footer.software=Acerca de este software
footer.links=Enlaces
[heatmap]
@@ -165,6 +179,9 @@ number_of_contributions_in_the_last_12_months=%s contribuciones en los รบltimos
contributions_zero=No hay contribuciones
less=Menos
more=Mรกs
+contributions_one = contribuciรณn
+contributions_few = contribuciones
+contributions_format = {contributions} el {day} {month} {year}
[editor]
buttons.heading.tooltip=Aรฑadir encabezado
@@ -181,6 +198,19 @@ buttons.ref.tooltip=Referir a una incidencia o pull request
buttons.switch_to_legacy.tooltip=Utilizar el editor antiguo en su lugar
buttons.enable_monospace_font=Activar fuente monoespaciada
buttons.disable_monospace_font=Desactivar fuente monoespaciada
+buttons.unindent.tooltip = Desanidar elementos por un nivel
+buttons.indent.tooltip = Anidar elementos por un nivel
+buttons.new_table.tooltip = Aรฑadir tabla
+table_modal.header = Aรฑadir tabla
+table_modal.placeholder.header = Cabecera
+table_modal.label.rows = Filas
+table_modal.label.columns = Columnas
+table_modal.placeholder.content = Contenido
+link_modal.header = Aรฑadir enlace
+link_modal.description = Descripciรณn
+link_modal.paste_reminder = Pista: Con una URL en tu portapapeles, puedes pegar directamente en el editor para crear un enlace.
+
+link_modal.url = URL
[filter]
string.asc=A - Z
@@ -188,7 +218,7 @@ string.desc=Z - A
[error]
occurred=Ha ocurrido un error
-report_message=Si crees que este es un error de Forgejo, por favor busca incidencias en Codeberg o abre una nueva incidencia si es necesario.
+report_message=Si crees que este es un error de Forgejo, por favor busca incidencias en Codeberg o abre una nueva incidencia si es necesario.
missing_csrf=Solicitud incorrecta: sin token CSRF
invalid_csrf=Solicitud incorrecta: el token CSRF no es vรกlido
not_found=El objetivo no pudo ser encontrado.
@@ -198,13 +228,13 @@ server_internal = Error interno del servidor
[startpage]
app_desc=Un servicio de Git autoalojado y sin complicaciones
install=Fรกcil de instalar
-install_desc=Simplemente ejecuta el binario para tu plataforma, lรกnzalo con Docker o consรญguelo empaquetado .
+install_desc=Simplemente ejecuta el binario para tu plataforma, lรกnzalo con Docker o consรญguelo empaquetado .
platform=Multiplataforma
-platform_desc=Forgejo funciona en cualquier platforma Go puede compilarlo en: Windows, macOS, Linux, ARM, etc. ยกElige tu favorita!
+platform_desc=Se ha confirmado que Forgejo funciona en sistemas operativos libres como Linux y FreeBSD, asรญ como en diferentes arquitecturas de CPU. ยกElige la que mรกs te guste!
lightweight=Ligero
lightweight_desc=Forgejo tiene pocos requisitos y puede funcionar en una Raspberry Pi barata. ยกAhorra energรญa!
license=Cรณdigo abierto
-license_desc=ยกEstรก todo en < Forgejo ! รnase contribuyendo a hacer este proyecto todavรญa mejor. ยกNo sea tรญmido y colabore!
+license_desc=ยกPasa a conseguir Forgejo ! รnete a nosotros y colabora para mejorar este proyecto. ยกNo seas tรญmido y colabora!
[install]
install=Instalaciรณn
@@ -237,7 +267,7 @@ err_admin_name_is_invalid=Nombre de usuario del administrador no es vรกlido
general_title=Configuraciรณn general
app_name=Tรญtulo del sitio
-app_name_helper=Puede colocar aquรญ el nombre de su empresa.
+app_name_helper=Introduzca aquรญ el nombre de su instancia. Aparecerรก en todas las pรกginas.
repo_path=Ruta de la raรญz del repositorio
repo_path_helper=Los repositorios Git se guardarรกn en este directorio.
lfs_path=Ruta raรญz de Git LFS
@@ -247,16 +277,16 @@ run_user_helper=El nombre de usuario del sistema operativo que ejecuta Forgejo.
domain=Dominio del servidor
domain_helper=Dominio o direcciรณn de host para el servidor.
ssh_port=Puerto de servidor SSH
-ssh_port_helper=Nรบmero de puerto en el que estรก escuchando su servidor SSH. Dรฉjelo vacรญo para deshabilitarlo.
-http_port=Puerto de escucha HTTP de Forgejo
-http_port_helper=Nรบmero de puerto en el que escucharรก el servidor web de Forgejo.
+ssh_port_helper=Nรบmero de puerto que serรก utilizado por el servidor SSH. Dรฉjelo vacรญo para desactivar el servidor SSH.
+http_port=Puerto de escucha HTTP
+http_port_helper=Nรบmero de puerto que serรก utilizado por el servidor web de Forgejo.
app_url=URL base
app_url_helper=Direcciรณn base para URLs de clonaciรณn HTTP(S) y notificaciones de correo electrรณnico.
log_root_path=Ruta del registro
log_root_path_helper=Archivos de registro se escribirรกn en este directorio.
optional_title=Configuraciรณn opcional
-email_title=Configuraciรณn de Correo
+email_title=Configuraciรณn de correo electrรณnico
smtp_addr=Servidor SMTP
smtp_port=Puerto SMTP
smtp_from=Enviar correos electrรณnicos como
@@ -266,67 +296,72 @@ mailer_password=Contraseรฑa SMTP
register_confirm=Requerir confirmaciรณn de correo electrรณnico para registrarse
mail_notify=Habilitar las notificaciones por correo electrรณnico
server_service_title=Configuraciรณn del servidor y de servicios de terceros
-offline_mode=Habilitar autenticaciรณn Local
+offline_mode=Habilitar modo local
offline_mode.description=Deshabilitar redes de distribuciรณn de contenido de terceros y servir todos los recursos localmente.
disable_gravatar=Desactivar Gravatar
-disable_gravatar.description=Desactivar el Gravatar y fuentes de avatares de terceros. Se utilizarรก un avatar por defecto a menos que un usuario suba un avatar localmente.
+disable_gravatar.description=Desactivar el Gravatar y otros fuentes de avatares de terceros. Se utilizarรก un avatar por defecto a menos que un usuario suba un avatar localmente.
federated_avatar_lookup=Habilitar avatares federados
-federated_avatar_lookup.description=Habilitar bรบsqueda de avatares federador para usar el servicio federado de cรณdigo abierto basado en libravatar.
+federated_avatar_lookup.description=Busca avatares con Libravatar.
disable_registration=Deshabilitar auto-registro
-disable_registration.description=Deshabilitar auto-registro de usuarios. Sรณlo los administradores podrรกn crear nuevas cuentas de usuario.
-allow_only_external_registration.description=Permitir el registro รบnicamente a travรฉs de servicios externos
+disable_registration.description=Sรณlo los administradores de la instancia podrรกn crear nuevas cuentas. Es muy recomendable mantener deshabilitado el registro a menos que pretenda alojar una instancia pรบblica para todo el mundo y estรฉ preparado para lidiar con grandes cantidades de cuentas de spam.
+allow_only_external_registration.description=Los usuarios sรณlo podrรกn crear nuevas cuentas utilizando servicios externos configurados.
openid_signin=Habilitar el inicio de sesiรณn con OpenID
-openid_signin.description=Habilitar el inicio de sesiรณn de usuarios con OpenID.
+openid_signin.description=Permitir a los usuarios iniciar sesiรณn mediante OpenID.
openid_signup=Habilitar el auto-registro con OpenID
-openid_signup.description=Habilitar autorregistro de usuario basado en OpenID.
+openid_signup.description=Permitir a los usuarios crear cuentas mediante OpenID si el autorregistro estรก activado.
enable_captcha=Requerir CAPTCHA durante el registro
-enable_captcha.description=Requerir CAPTCHA para auto-registro de usuario.
-require_sign_in_view=Requerir inicio de sesiรณn para ver pรกginas
+enable_captcha.description=Requerir que los usuarios pasen CAPTCHA para crear cuentas.
+require_sign_in_view=Requerir inicio de sesiรณn para ver el contenido de la instancia
require_sign_in_view.description=Limitar el acceso a los usuarios conectados. Los visitantes sรณlo verรกn las pรกginas de inicio de sesiรณn y de registro.
admin_setting.description=Crear una cuenta de administrador es opcional. El primer usuario registrado se convertirรก automรกticamente en administrador.
admin_title=Configuraciรณn de la cuenta de administrador
admin_name=Nombre de usuario del administrador
admin_password=Contraseรฑa
-confirm_password=Confirmar Contraseรฑa
+confirm_password=Confirmar contraseรฑa
admin_email=Correo electrรณnico
install_btn_confirm=Instalar Forgejo
-test_git_failed=Fallo al probar el comando 'git': %v
-sqlite3_not_available=Esta versiรณn de Forgejo no soporta SQLite3. Por favor, descarga la versiรณn binaria oficial de %s (no la versiรณn 'gobuild').
+test_git_failed=Fallo al probar el comando "git": %v
+sqlite3_not_available=Esta versiรณn de Forgejo no admite SQLite3. Descรกrguese la versiรณn binaria oficial desde %s (no la versiรณn ยซgobuildยป).
invalid_db_setting=La configuraciรณn de la base de datos no es vรกlida: %v
invalid_db_table=La tabla "%s" de la base de datos no es vรกlida: %v
invalid_repo_path=La ruta de la raรญz del repositorio no es vรกlida: %v
invalid_app_data_path=La ruta de datos de la aplicaciรณn (APP_DATA_PATH) no es vรกlida: %v
-run_user_not_match=El nombre de usuario 'ejecutar como' no es el nombre actual de usuario: %s -> %s
+run_user_not_match=El nombre de usuario "ejecutar como" no es el nombre del usuario actual: %s -> %s
internal_token_failed=Fallo al generar el INTERNAL_TOKEN: %v
secret_key_failed=Fallo al generar el SECRET_KEY: %v
save_config_failed=Error al guardar la configuraciรณn: %v
invalid_admin_setting=La configuraciรณn de la cuenta de administraciรณn no es vรกlida: %v
invalid_log_root_path=La ruta para los registros no es vรกlida: %v
default_keep_email_private=Ocultar direcciones de correo electrรณnico por defecto
-default_keep_email_private.description=Ocultar direcciones de correo electrรณnico de nuevas cuentas de usuario por defecto.
+default_keep_email_private.description=Ocultar direcciones de correo electrรณnico de nuevas cuentas por defecto, de modo que esta informaciรณn no se divulgue inmediatamente despuรฉs de registrarse.
default_allow_create_organization=Permitir la creaciรณn de organizaciones por defecto
-default_allow_create_organization.description=Permitir que las nuevas cuentas de usuario creen organizaciones por defecto.
+default_allow_create_organization.description=Permitir a los nuevos usuarios crear organizaciones por defecto. Si esta opciรณn estรก desactivada, un administrador tendrรก que conceder el permiso para crear organizaciones a los nuevos usuarios.
default_enable_timetracking=Activar el seguimiento de tiempo por defecto
default_enable_timetracking.description=Activar el seguimiento de tiempo para nuevos repositorios por defecto.
no_reply_address=Dominio de correos electrรณnicos ocultos
-no_reply_address_helper=Nombre de dominio para usuarios con direcciรณn de correo electrรณnico oculta. Por ejemplo, el usuario 'joe' quedarรก registrado en Git como 'joe@noreply.example.org' si el dominio de correo electrรณnico oculto se establece a 'noreply.example.org'.
-password_algorithm=Algoritmo Hash de Contraseรฑa
+no_reply_address_helper=Nombre de dominio para usuarios con direcciรณn de correo electrรณnico oculta. Por ejemplo, el usuario "joe" quedarรก registrado en Git como "joe@noreply.example.org" si el dominio de correo electrรณnico oculto estรก configurado como "noreply.example.org".
+password_algorithm=Algoritmo hash de contraseรฑa
invalid_password_algorithm=Algoritmo hash de contraseรฑa no vรกlido
password_algorithm_helper=Establece el algoritmo de hashing de contraseรฑa. Los algoritmos tienen diferentes requisitos y fuerza. El algoritmo argon2 es bastante seguro, pero usa mucha memoria y puede ser inapropiado para sistemas pequeรฑos.
enable_update_checker=Activar comprobador de actualizaciones
env_config_keys=Configuraciรณn del entorno
env_config_keys_prompt=Las siguientes variables de entorno tambiรฉn se aplicarรกn a su archivo de configuraciรณn:
allow_dots_in_usernames = Permite utilizar puntos en los nombres de usuario. No tiene efecto sobre cuentas existentes.
-enable_update_checker_helper_forgejo = Comprobaciones periรณdicas de nuevas versiones de Forgejo mediante la comprobaciรณn del registro DNS TXT en release.forgejo.org.
+enable_update_checker_helper_forgejo = Buscarรก periรณdicamente nuevas versiones de Forgejo consultando un registro DNS TXT en release.forgejo.org.
+smtp_from_invalid = La direcciรณn "Enviar correos electrรณnicos como" no es vรกlida
+allow_only_external_registration = Permitir el registro sรณlo a travรฉs de servicios externos
+app_slogan = Eslogan de la instancia
+app_slogan_helper = Introduce aquรญ el eslogan de tu instancia. Dรฉjalo vacรญo para desactivar.
+config_location_hint = Estas opciones de configuraciรณn se guardarรกn en:
[home]
uname_holder=Nombre de usuario o correo electrรณnico
password_holder=Contraseรฑa
-switch_dashboard_context=Cambiar el contexto del Dashboard
+switch_dashboard_context=Cambiar el contexto del dashboard
my_repos=Repositorios
show_more_repos=Mostrar mรกs repositoriosโฆ
collaborative_repos=Repositorios colaborativos
-my_orgs=Mis organizaciones
+my_orgs=Organizaciones
my_mirrors=Mis rรฉplicas
view_home=Ver %s
search_repos=Buscar un repositorioโฆ
@@ -367,29 +402,31 @@ code_search_results=Resultados de bรบsqueda para ยซ%sยป
code_last_indexed_at=Indexado por รบltima vez %s
relevant_repositories_tooltip=Repositorios que son bifurcaciones o que no tienen ningรบn tema, ningรบn icono, y ninguna descripciรณn estรกn ocultos.
relevant_repositories=Solo se muestran repositorios relevantes, mostrar resultados sin filtrar .
-forks_few = %d forks
-forks_one = %d fork
+forks_few = %d bifurcaciones
+forks_one = %d bifurcaciรณn
+stars_few = %d estrellas
+stars_one = %d estrella
[auth]
-create_new_account=Registrar una cuenta
+create_new_account=Registrar cuenta
register_helper_msg=ยฟYa tienes una cuenta? ยกInicia sesiรณn!
social_register_helper_msg=ยฟYa tienes una cuenta? ยกEnlรกzala!
disable_register_prompt=Registro deshabilitado. Por favor, pรณngase en contacto con el administrador del sitio.
disable_register_mail=Correo electrรณnico de confirmaciรณn de registro deshabilitado.
manual_activation_only=Pรณngase en contacto con el administrador del sitio para completar la activaciรณn.
-remember_me=Recordar este Dispositivo
-forgot_password_title=He olvidado mi contraseรฑa
+remember_me=Recordar este dispositivo
+forgot_password_title=Contraseรฑa olvidada
forgot_password=ยฟHas olvidado tu contraseรฑa?
sign_up_now=ยฟNecesitas una cuenta? Regรญstrate ahora.
sign_up_successful=La cuenta se ha creado correctamente. ยกBienvenido!
-confirmation_mail_sent_prompt=Un nuevo correo de confirmaciรณn se ha enviado a %s . Comprueba tu bandeja de entrada en las siguientes %s para completar el registro.
+confirmation_mail_sent_prompt=Se ha enviado un nuevo correo de confirmaciรณn a %s . Para completar el proceso de registro, revisa tu bandeja de entrada y sigue el enlace proporcionado dentro de los prรณximos %s. Si la direcciรณn no es correcto, puedes iniciar sesiรณn y solicitar otro correo de confirmaciรณn para ser enviado a una direcciรณn diferente.
must_change_password=Actualizar su contraseรฑa
allow_password_change=Obligar al usuario a cambiar la contraseรฑa (recomendado)
-reset_password_mail_sent_prompt=Un correo de confirmaciรณn se ha enviado a %s . Compruebe su bandeja de entrada en las siguientes %s para completar el proceso de recuperaciรณn de la cuenta.
-active_your_account=Activa tu cuenta
+reset_password_mail_sent_prompt=Se ha enviado un correo de confirmaciรณn a %s . Para completar el proceso de recuperaciรณn de la cuenta, consulta tu bandeja de entrada y sigue el enlace proporcionado dentro de los prรณximos %s.
+active_your_account=Activar tu cuenta
account_activated=La cuenta ha sido activada
-prohibit_login=Ingreso prohibido
-prohibit_login_desc=Su cuenta no puede iniciar sesiรณn, pรณngase en contacto con el administrador de su sitio.
+prohibit_login=La cuenta estรก suspendida
+prohibit_login_desc=Se ha suspendido la interacciรณn de su cuenta con la instancia. Pรณngase en contacto con el administrador para recuperar su acceso.
resent_limit_prompt=Ya ha solicitado recientemente un correo de activaciรณn. Por favor, espere 3 minutos y vuelva a intentarlo.
has_unconfirmed_mail=Hola %s, su correo electrรณnico (%s ) no estรก confirmado. Si no ha recibido un correo de confirmaciรณn o necesita que lo enviemos de nuevo, por favor, haga click en el siguiente botรณn.
resend_mail=Haga click aquรญ para reenviar su correo electrรณnico de activaciรณn
@@ -412,11 +449,11 @@ twofa_scratch_token_incorrect=El cรณdigo de respaldo es incorrecto.
login_userpass=Iniciar sesiรณn
tab_openid=OpenID
oauth_signup_tab=Registrar nueva cuenta
-oauth_signup_title=Completar Cuenta Nueva
-oauth_signup_submit=Completar Cuenta
-oauth_signin_tab=Vincular a una Cuenta Existente
-oauth_signin_title=Regรญstrese para autorizar cuenta vinculada
-oauth_signin_submit=Vincular Cuenta
+oauth_signup_title=Completar cuenta nueva
+oauth_signup_submit=Completar cuenta
+oauth_signin_tab=Vincular a una cuenta existente
+oauth_signin_title=Iniciar sesiรณn para autorizar cuenta vinculada
+oauth_signin_submit=Vincular cuenta
oauth.signin.error=Hubo un error al procesar la solicitud de autorizaciรณn. Si este error persiste, pรณngase en contacto con el administrador del sitio.
oauth.signin.error.access_denied=La solicitud de autorizaciรณn fue denegada.
oauth.signin.error.temporarily_unavailable=La autorizaciรณn fallรณ porque el servidor de autenticaciรณn no estรก disponible temporalmente. Intรฉntalo de nuevo mรกs tarde.
@@ -432,22 +469,30 @@ email_domain_blacklisted=No puede registrarse con su correo electrรณnico.
authorize_application=Autorizar aplicaciรณn
authorize_redirect_notice=Serรก redirigido a %s si autoriza esta aplicaciรณn.
authorize_application_created_by=Esta aplicaciรณn fue creada por %s.
-authorize_application_description=Si concede el acceso, podrรก acceder y escribir a toda la informaciรณn de su cuenta, incluyendo repositorios privado y organizaciones.
+authorize_application_description=Si concede el acceso, podrรก acceder y escribir a toda la informaciรณn de su cuenta, incluyendo repositorios privados y organizaciones.
authorize_title=ยฟAutorizar a "%s" a acceder a su cuenta?
authorization_failed=Autorizaciรณn fallida
authorization_failed_desc=La autorizaciรณn ha fallado porque hemos detectado una solicitud no vรกlida. Por favor, pรณngase en contacto con el responsable de la aplicaciรณn que ha intentado autorizar.
sspi_auth_failed=Fallo en la autenticaciรณn SSPI
-password_pwned=La contraseรฑa que eligiรณ estรก en una lista de contraseรฑas robadas previamente expuestas en violaciones de datos pรบblicos. Por favor, intรฉntelo de nuevo con una contraseรฑa diferente y considere cambiar esta contraseรฑa tambiรฉn en otros lugares.
+password_pwned=La contraseรฑa que eligiรณ estรก en una lista de contraseรฑas robadas previamente expuestas en violaciones de datos pรบblicos. Por favor, intรฉntelo de nuevo con una contraseรฑa diferente y considere cambiar esta contraseรฑa tambiรฉn en otros lugares.
password_pwned_err=No se pudo completar la solicitud a HaveIBeenPwned
change_unconfirmed_email = Si has proporcionado una direcciรณn de correo electrรณnico errรณnea durante el registro, la puedes cambiar debajo y se enviarรก una confirmaciรณn a la nueva direcciรณn.
change_unconfirmed_email_error = No es posible cambiar la direcciรณn de correo electrรณnico: %v
change_unconfirmed_email_summary = Cambia la direcciรณn de correo electrรณnico a quien se envรญa el correo de activaciรณn.
last_admin = No puedes eliminar al รบltimo admin (administrador). Debe haber, al menos, un admin.
+sign_up_button = Regรญstrate ahora.
+hint_login = ยฟYa tienes cuenta? ยกIngresa ahora!
+hint_register = ยฟNecesitas una cuenta? Regรญstrate ahora.
+back_to_sign_in = Volver a Iniciar sesiรณn
+sign_in_openid = Proceder con OpenID
+remember_me.compromised = El identificador de inicio de sesiรณn ya no es vรกlido, lo que puede indicar una cuenta comprometida. Por favor, verifica si tu cuenta presenta actividades sospechosas.
+unauthorized_credentials = Las credenciales son incorrectas o han expirado. Reintenta el comando o visita %s para mรกs informaciรณn
+use_onetime_code = Usar cรณdigo de un solo uso
[mail]
view_it_on=Ver en %s
reply=o responde directamente a este correo electrรณnico
-link_not_working_do_paste=ยฟNo funciona? Intenta copiarlo y pegarlo en tu navegador.
+link_not_working_do_paste=๏ปฟ๏ปฟยฟNo funciona el enlace? Intenta copiarlo y pegarlo en tu navegador.
hi_user_x=Hola %s ,
activate_account=Por favor, active su cuenta
@@ -459,11 +504,11 @@ activate_email=Verifique su correo electrรณnico
activate_email.title=%s, por favor verifique su direcciรณn de correo electrรณnico
activate_email.text=Por favor, haga clic en el siguiente enlace para verificar su direcciรณn de correo electrรณnico dentro de %s :
-register_notify=ยกBienvenido a Forgejo
+register_notify=Bienvenido a %s
register_notify.title=%[1]s, bienvenido a %[2]s
register_notify.text_1=este es tu correo de confirmaciรณn de registro para %s!
-register_notify.text_2=Ahora puede iniciar sesiรณn vรญa nombre de usuario: %s.
-register_notify.text_3=Si esta cuenta ha sido creada para usted, por favor establezca su contraseรฑa primero.
+register_notify.text_2=Puede iniciar sesiรณn con su nombre de usuario: %s
+register_notify.text_3=Si otra persona creรณ esta cuenta para usted, tendrรก que establecer su contraseรฑa primero.
reset_password=Recupere su cuenta
reset_password.title=%s, has solicitado recuperar tu cuenta
@@ -497,12 +542,12 @@ release.downloads=Descargas:
release.download.zip=Cรณdigo fuente (ZIP)
release.download.targz=Cรณdigo fuente (TAR.GZ)
-repo.transfer.subject_to=%s desea transferir "%s" a %s
-repo.transfer.subject_to_you=%s desea transferir "%s" a usted
+repo.transfer.subject_to=%s quiere transferir el repositorio "%s" a %s
+repo.transfer.subject_to_you=%s quiere transferir el repositorio "%s" a usted
repo.transfer.to_you=usted
repo.transfer.body=Para aceptarlo o rechazarlo, visita %s o simplemente ignรณrelo.
-repo.collaborator.added.subject=%s le aรฑadiรณ en %s
+repo.collaborator.added.subject=%s le aรฑadiรณ a %s como colaborador
repo.collaborator.added.text=Has sido aรฑadido como colaborador del repositorio:
team_invite.subject=%[1]s le ha invitado a unirse a la organizaciรณn de %[2]s
@@ -512,6 +557,21 @@ team_invite.text_3=Nota: Esta invitaciรณn estaba destinada a %[1]s. Si no espera
admin.new_user.subject = Se acaba de registrar el nuevo usuario %s
admin.new_user.user_info = Informaciรณn del usuario
admin.new_user.text = Por favor, pulsa aquรญ para gestionar este usuario desde el panel de administraciรณn.
+account_security_caution.text_1 = Si fuiste tรบ, puedes ignorar este correo.
+removed_security_key.subject = Se ha eliminado una clave de seguridad
+removed_security_key.no_2fa = Ya no hay otros mรฉtodos 2FA configurados, lo que significa que ya no es necesario iniciar sesiรณn en tu cuenta con 2FA.
+password_change.subject = Tu contraseรฑa ha sido modificada
+password_change.text_1 = La contraseรฑa de tu cuenta acaba de ser modificada.
+primary_mail_change.subject = Tu correo principal ha sido modificado
+totp_disabled.subject = Se ha desactivado el TOTP
+totp_disabled.text_1 = La contraseรฑa de un solo uso basada en el tiempo (TOTP) de tu cuenta acaba de ser desactivada.
+totp_disabled.no_2fa = Ya no hay otros mรฉtodos 2FA configurados, lo que significa que ya no es necesario iniciar sesiรณn en tu cuenta con 2FA.
+account_security_caution.text_2 = Si no fuiste tรบ, tu cuenta estรก comprometida. Ponte en contacto con los administradores de este sitio.
+totp_enrolled.subject = Has activado TOTP como mรฉtodo 2FA
+totp_enrolled.text_1.no_webauthn = Acabas de activar TOTP para tu cuenta. Esto significa que para todos los futuros inicios de sesiรณn en tu cuenta, debes utilizar TOTP como mรฉtodo 2FA.
+removed_security_key.text_1 = La clave de seguridad "%[1]s" acaba de ser eliminada de tu cuenta.
+primary_mail_change.text_1 = El correo principal de tu cuenta acaba de ser cambiado a %[1]s. Esto significa que esta direcciรณn de correo electrรณnico ya no recibirรก notificaciones por correo electrรณnico relativas a tu cuenta.
+totp_enrolled.text_1.has_webauthn = Acabas de activar TOTP para tu cuenta. Esto significa que para todos los futuros inicios de sesiรณn en tu cuenta, podrรกs utilizar TOTP como mรฉtodo 2FA o bien utilizar cualquiera de tus claves de seguridad.
[modal]
yes=Sรญ
@@ -525,7 +585,7 @@ UserName=Nombre de usuario
RepoName=Nombre del repositorio
Email=Direcciรณn de correo electrรณnico
Password=Contraseรฑa
-Retype=Confirmar Contraseรฑa
+Retype=Confirmar contraseรฑa
SSHTitle=Nombre de la Clave de SSH
HttpsUrl=URL HTTPS
PayloadUrl=URL de carga
@@ -541,11 +601,11 @@ TreeName=Ruta del archivo
Content=Contenido
SSPISeparatorReplacement=Separador
-SSPIDefaultLanguage=Idioma predeterminado
+SSPIDefaultLanguage=Idioma por defecto
require_error=` no puede estar vacรญo.`
-alpha_dash_error=` solo debe contener caracteres alfanumรฉricos, guiones medios ('-') y guiones bajos ('_').`
-alpha_dash_dot_error=` solo debe contener caracteres alfanumรฉricos, guiones, ('-'), subrayados ('_'), y puntos ('.').`
+alpha_dash_error=` solo debe contener caracteres alfanumรฉricos, guiones ("-"), y guiones bajos ("_").`
+alpha_dash_dot_error=` solo debe contener caracteres alfanumรฉricos, guiones ("-"), guiones bajos ("_"), y puntos (".").`
git_ref_name_error=` debe ser un nombre de referencia de Git bien formado.`
size_error=` debe ser de tamaรฑo %s.`
min_size_error=` debe contener al menos %s caracteres.`
@@ -555,7 +615,7 @@ url_error=`"%s" no es una URL vรกlida.`
include_error=` debe contener la subcadena "%s".`
glob_pattern_error=` el patrรณn globo no es vรกlido: %s.`
regex_pattern_error=` el patrรณn de regex no es vรกlido: %s.`
-username_error=` sรณlo puede contener caracteres alfanumรฉricos ('0-9','a-z','A-Z'), guiรณn ('-'), guiรณn bajo ('_') y punto ('.'). No puede comenzar o terminar con caracteres no alfanumรฉricos, y los caracteres no alfanumรฉricos consecutivos tambiรฉn estรกn prohibidos.`
+username_error=` sรณlo puede contener caracteres alfanumรฉricos ("0-9","a-z","A-Z"), guiรณn ("-"), guiรณn bajo ("_") y punto ("."). No puede comenzar o terminar con caracteres no alfanumรฉricos, y los caracteres no alfanumรฉricos consecutivos tambiรฉn estรกn prohibidos.`
invalid_group_team_map_error=` la asignaciรณn no es vรกlida: %s`
unknown_error=Error desconocido:
captcha_incorrect=El cรณdigo CAPTCHA no es correcto.
@@ -591,7 +651,7 @@ enterred_invalid_owner_name=El nuevo nombre de usuario no es vรกlido.
enterred_invalid_password=La contraseรฑa que ha introducido es incorrecta.
user_not_exist=Este usuario no existe.
team_not_exist=Este equipo no existe.
-last_org_owner=No puedes eliminar al รบltimo usuario del equipo de 'propietarios'. Todas las organizaciones deben tener al menos un propietario.
+last_org_owner=No puedes eliminar al รบltimo usuario del equipo de "propietarios". Todas las organizaciones deben tener al menos un propietario.
cannot_add_org_to_team=Una organizaciรณn no puede ser aรฑadida como miembro de un equipo.
duplicate_invite_to_team=El usuario ya fue invitado como miembro del equipo.
organization_leave_success=Ha abandonado correctamente la organizaciรณn %s.
@@ -603,15 +663,28 @@ must_use_public_key=La clave que proporcionรณ es una clave privada. No cargue su
unable_verify_ssh_key=No se puede verificar la clave SSH, comprueba si hay errores.
auth_failed=Autenticaciรณn fallo: %v
-still_own_repo=Su cuenta posee uno o mรกs repositorios, elimรญnalos o transfiรฉrelos primero.
+still_own_repo=Tu cuenta posee uno o mรกs repositorios, elimรญnalos o transfiรฉrelos primero.
still_has_org=Tu cuenta es miembro de una o mรกs organizaciones, dรฉjalas primero.
-still_own_packages=Su cuenta posee uno o mรกs paquetes, elimรญnalos primero.
+still_own_packages=Tu cuenta posee uno o mรกs paquetes, elimรญnalos primero.
org_still_own_repo=Esta organizaciรณn todavรญa posee uno o mรกs repositorios, elimรญnalos o transfiรฉrelos primero.
org_still_own_packages=Esta organizaciรณn todavรญa posee uno o mรกs paquetes, elimรญnalos primero.
-target_branch_not_exist=La rama de destino no existe
+target_branch_not_exist=La rama de destino no existe.
admin_cannot_delete_self = No puedes eliminarte a ti mismo cuando eres un admin (administrador). Por favor, elimina primero tus privilegios de administrador.
-username_error_no_dots = ` solo puede contener carรกcteres alfanumรฉricos ('0-9','a-z','A-Z'), guiones ('-') y guiones bajos ('_'). No puede empezar o terminar con carรกcteres no alfanumรฉricos y tambiรฉn estรกn prohibidos los carรกcteres no alfanumรฉricos consecutivos.`
+username_error_no_dots = ` solo puede contener carรกcteres alfanumรฉricos ("0-9","a-z","A-Z"), guiones ("-"), y guiones bajos ("_"). No puede empezar o terminar con carรกcteres no alfanumรฉricos y tambiรฉn estรกn prohibidos los carรกcteres no alfanumรฉricos consecutivos.`
+unsupported_login_type = No se admite el tipo de inicio de sesiรณn para eliminar la cuenta.
+required_prefix = La entrada debe empezar por "%s"
+unset_password = El usuario no ha establecido una contraseรฑa.
+AccessToken = Token de acceso
+FullName = Nombre completo
+Description = Descripciรณn
+Pronouns = Pronombres
+Biography = Biografรญa
+Location = Ubicaciรณn
+To = Nombre de rama
+Website = Sitio web
+username_claiming_cooldown = El nombre de usuario no se puede reclamar, debido a que su periodo de protecciรณn no ha terminado aรบn. Puede ser reclamado el %[1]s.
+email_domain_is_not_allowed = El dominio de la direcciรณn de correo electrรณnico del usuario %s entra en conflicto con EMAL_DOMAIN_ALLOWLIST o EMAIL_DOMAIN_BLOCKLIST. Asegรบrese de que ha establecido la direcciรณn de correo electrรณnico correctamente.
[user]
@@ -620,7 +693,7 @@ joined_on=Se uniรณ el %s
repositories=Repositorios
activity=Actividad pรบblica
followers_few=%d seguidores
-starred=Repositorios Favoritos
+starred=Repositorios favoritos
watched=Repositorios seguidos
code=Cรณdigo
projects=Proyectos
@@ -633,19 +706,30 @@ disabled_public_activity=Este usuario ha desactivado la visibilidad pรบblica de
email_visibility.limited=Tu direcciรณn de correo electrรณnico es visible para todos los usuarios autenticados
email_visibility.private=Tu direcciรณn de correo electrรณnico solo es visible para ti y los administradores
show_on_map=Mostrar este lugar en un mapa
-settings=Ajustes del usuario
+settings=Configuraciรณn del usuario
form.name_reserved=El nombre de usuario "%s" estรก reservado.
form.name_pattern_not_allowed=El patrรณn "%s" no estรก permitido en un nombre de usuario.
form.name_chars_not_allowed=El nombre de usuario "%s" contiene caracteres no vรกlidos.
block_user = Bloquear usuario
block_user.detail_1 = Este usuario te ha dejado de seguir.
-block_user.detail_2 = Este usuario no puede interactuar con tus repositorios, incidencias creadas y comentarios.
+block_user.detail_2 = Este usuario no podrรก interactuar con tus repositorios ni con las incidencias y comentarios que hayas creado.
block_user.detail_3 = Este usuario no te puede aรฑadir como colaborador ni tรบ le puedes aรฑadir como colaborador.
follow_blocked_user = No puedes seguir a este usuario porque le tienes bloqueado o te tiene bloqueado.
block = Bloquear
unblock = Desbloquear
-block_user.detail = Por favor, comprende que si bloqueas a este usuario se llevarรกn a cabo otras acciones. Como:
+block_user.detail = Ten en cuenta que bloquear a un usuario tiene otros efectos, como:
+public_activity.visibility_hint.self_private = Tu actividad sรณlo es visible para ti y para los administradores de la instancia. Configurar .
+public_activity.visibility_hint.admin_private = Esta actividad es visible para ti porque eres administrador, pero el usuario quiere que se mantenga privada.
+following_one = %d siguiendo
+followers_one = %d seguidor
+public_activity.visibility_hint.self_public = Tu actividad es visible para todos, excepto las interacciones en espacios privados. Configurar .
+public_activity.visibility_hint.admin_public = Esta actividad es visible para todos, pero como administrador tambiรฉn puedes ver las interacciones en los espacios privados.
+following.title.one = Siguiendo
+following.title.few = Siguiendo
+followers.title.one = Seguidor
+followers.title.few = Seguidores
+public_activity.visibility_hint.self_private_profile = Tu actividad solamente es visible para ti y los administradores de la instancia porque tu perfil es privado. Configure .
[settings]
profile=Perfil
@@ -654,29 +738,29 @@ appearance=Apariencia
password=Contraseรฑa
security=Seguridad
avatar=Avatar
-ssh_gpg_keys=SSH / claves GPG
-social=Redes Sociales
+ssh_gpg_keys=Claves SSH / GPG
+social=Redes sociales
applications=Aplicaciones
orgs=Administrar organizaciones
repos=Repositorios
delete=Eliminar cuenta
-twofa=Autenticaciรณn de doble factor
+twofa=Autenticaciรณn de dos factores (TOTP)
account_link=Cuentas vinculadas
organization=Organizaciones
uid=UID
-webauthn=Llaves de Seguridad
+webauthn=Autenticaciรณn de dos factores (claves de seguridad)
public_profile=Perfil pรบblico
-biography_placeholder=ยกCuรฉntanos un poco sobre ti mismo! (Puedes usar Markdown)
+biography_placeholder=ยกCuenta a otros un poco sobre ti! (Se admite Markdown)
location_placeholder=Comparte tu ubicaciรณn aproximada con otros
-profile_desc=Controla cรณmo se muestra su perfil a otros usuarios. Tu direcciรณn de correo electrรณnico principal se utilizarรก para notificaciones, recuperaciรณn de contraseรฑa y operaciones de Git basadas en la web.
+profile_desc=Acerca de ti
password_username_disabled=Usuarios no locales no tienen permitido cambiar su nombre de usuario. Por favor, contacta con el administrador del sistema para mรกs detalles.
full_name=Nombre completo
website=Pรกgina web
location=Localizaciรณn
-update_theme=Actualizar tema
+update_theme=Cambiar tema
update_profile=Actualizar perfil
-update_language=Actualizar idioma
+update_language=Cambiar idioma
update_language_not_found=Idioma "%s" no estรก disponible.
update_language_success=El idioma ha sido actualizado.
update_profile_success=Tu perfil ha sido actualizado.
@@ -697,7 +781,7 @@ comment_type_group_milestone=Hito
comment_type_group_assignee=Asignado
comment_type_group_title=Tรญtulo
comment_type_group_branch=Rama
-comment_type_group_time_tracking=Seguimiento de Tiempo
+comment_type_group_time_tracking=Seguimiento de tiempo
comment_type_group_deadline=Fecha lรญmite
comment_type_group_dependency=Dependencia
comment_type_group_lock=Estado de bloqueo
@@ -711,11 +795,11 @@ keep_activity_private=Ocultar actividad de la pรกgina de perfil
keep_activity_private_popup=Hace la actividad visible sรณlo para ti y los administradores
lookup_avatar_by_mail=Buscar avatar por direcciรณn de correo electrรณnico
-federated_avatar_lookup=Bรบsqueda de Avatar Federado
-enable_custom_avatar=Activar avatar personalizado
+federated_avatar_lookup=Bรบsqueda de avatar federado
+enable_custom_avatar=Usar avatar personalizado
choose_new_avatar=Selecciona nuevo avatar
-update_avatar=Actualizar Avatar
-delete_current_avatar=Eliminar avatar
+update_avatar=Actualizar avatar
+delete_current_avatar=Eliminar avatar actual
uploaded_avatar_not_a_image=El archivo subido no es una imagen.
uploaded_avatar_is_too_big=El tamaรฑo del archivo subido (%d KiB) excede el tamaรฑo mรกximo (%d KiB).
update_avatar_success=Su avatar ha sido actualizado.
@@ -723,23 +807,23 @@ update_user_avatar_success=El avatar del usuario se ha actualizado.
update_password=Actualizar contraseรฑa
old_password=Contraseรฑa actual
-new_password=Nueva contraseรฑa
-retype_new_password=Confirme la nueva contraseรฑa
+new_password=Contraseรฑa nueva
+retype_new_password=Confirmar contraseรฑa nueva
password_incorrect=Contraseรฑa actual incorrecta.
-change_password_success=Su contraseรฑa ha sido modificada. Utilice su nueva contraseรฑa la prรณxima vez que acceda a la cuenta.
+change_password_success=Su contraseรฑa ha sido actualizada. Desde ahora, use su nueva contraseรฑa para iniciar sesiรณn.
password_change_disabled=Los usuarios no locales no pueden actualizar su contraseรฑa a travรฉs de la interfaz web de Forgejo.
emails=Direcciones de correo electrรณnico
manage_emails=Administrar direcciones de correo electrรณnico
-manage_themes=Selecciona el tema por defecto
-manage_openid=Administrar direcciones OpenID
+manage_themes=Tema por defecto
+manage_openid=Direcciones OpenID
email_desc=Su direcciรณn de correo electrรณnico principal se utilizarรก para notificaciones, recuperaciรณn de contraseรฑa y, siempre y cuando no estรฉ oculto, operaciones de Git basadas en la web.
-theme_desc=Este serรก su tema por defecto en todo el sitio.
+theme_desc=Este tema serรก usado en la interfaz web cuando hayas iniciado sesiรณn.
primary=Principal
activated=Activado
requires_activation=Requiere activaciรณn
primary_email=Hacer primaria
-activate_email=Enviar email de activaciรณn
+activate_email=Enviar activaciรณn
activations_pending=Activaciones pendientes
can_not_add_email_activations_pending=Hay una activaciรณn pendiente, intรฉntelo de nuevo en unos minutos si desea agregar un nuevo correo electrรณnico.
delete_email=Eliminar
@@ -755,28 +839,28 @@ add_new_email=Aรฑadir nueva direcciรณn de correo electrรณnico
add_new_openid=Aรฑadir nueva direcciรณn OpenID
add_email=Aรฑadir direcciรณn de correo electrรณnico
add_openid=Aรฑadir nuevo OpenID URI
-add_email_confirmation_sent=Un correo de confirmaciรณn ha sido enviado a "%s". Por favor, comprueba tu bandeja de entrada en el siguiente %s para confirmar tu direcciรณn de correo electrรณnico.
+add_email_confirmation_sent=Se ha enviado un correo de confirmaciรณn a "%s". Para confirmar tu direcciรณn de correo electrรณnico, consulta tu bandeja de entrada y sigue el enlace proporcionado dentro de los prรณximos %s.
add_email_success=La nueva direcciรณn de correo electrรณnico ha sido aรฑadida.
email_preference_set_success=La preferencia de correo electrรณnico se ha establecido correctamente.
add_openid_success=La nueva direcciรณn OpenID ha sido aรฑadida.
keep_email_private=Ocultar direcciรณn de correo electrรณnico
-keep_email_private_popup=Esto ocultarรก su direcciรณn de correo electrรณnico de su perfil, asรญ como cuando haga un pull request o edite un archivo usando la interfaz web. Los commits enviados no serรกn modificados.
+keep_email_private_popup=Su direcciรณn de correo electrรณnico no se mostrarรก en su perfil y no serรก la predeterminada para las confirmaciones realizadas a travรฉs de la interfaz web, como las subidas de archivos, las ediciones y las confirmaciones de fusiรณn. En su lugar, se utilizarรก una direcciรณn especial %s para vincular las confirmaciones a tu cuenta. Esta opciรณn no afectarรก a las confirmaciones existentes.
openid_desc=OpenID le permite delegar la autenticaciรณn a un proveedor externo.
-manage_ssh_keys=Gestionar Claves SSH
+manage_ssh_keys=Gestionar claves SSH
manage_ssh_principals=Administrar Principales de Certificado SSH
-manage_gpg_keys=Administrar claves GPG
-add_key=Aรฑadir Clave
-ssh_desc=Estas claves pรบblicas SSH estรกn asociadas con su cuenta. Las correspondientes claves privadas permite acceso completo a sus repositorios.
+manage_gpg_keys=Gestionar claves GPG
+add_key=Aรฑadir clave
+ssh_desc=Estas claves SSH pรบblicas estรกn asociadas a tu cuenta. Las correspondientes claves privadas permiten el acceso total a tus repositorios. Las claves SSH que han sido verificadas pueden utilizarse para verificar confirmaciones de Git firmadas por SSH.
principal_desc=Estos principales de certificado SSH estรกn asociados con su cuenta y permiten el acceso completo a sus repositorios.
-gpg_desc=Estas claves pรบblicas GPG estรกn asociadas con su cuenta. Mantenga sus claves privadas a salvo, ya que permiten verificar commits.
+gpg_desc=Estas claves GPG pรบblicas estรกn asociadas a tu cuenta y se utilizan para verificar tus commits. Mantรฉn a salvo tus claves privadas, ya que permiten firmar commits con tu identidad.
ssh_helper=ยฟNecesitas ayuda? Echa un vistazo en la guรญa de GitHub para crear tus propias claves SSH o resolver problemas comunes que puede encontrar al usar SSH.
gpg_helper=ยฟNecesitas ayuda? Echa un vistazo en la guรญa de GitHub sobre GPG .
add_new_key=Aรฑadir clave SSH
add_new_gpg_key=Aรฑadir clave GPG
-key_content_ssh_placeholder=Comienza con 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', or 'sk-ssh-ed25519@openssh.com'
-key_content_gpg_placeholder=Comienza con '-----BEGIN PGP PUBLIC KEY BLOCK-----'
-add_new_principal=Aรฑadir Principal
+key_content_ssh_placeholder=Comienza con "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", o "sk-ssh-ed25519@openssh.com"
+key_content_gpg_placeholder=Comienza con "-----BEGIN PGP PUBLIC KEY BLOCK-----"
+add_new_principal=Aรฑadir principal
ssh_key_been_used=Esta clave SSH ya ha sido aรฑadida al servidor.
ssh_key_name_used=Una clave SSH con el mismo nombre ya ha sido aรฑadida a su cuenta.
ssh_principal_been_used=Este principal ya ha sido aรฑadido al servidor.
@@ -793,7 +877,7 @@ gpg_token=Token
gpg_token_help=Puede generar una firma de la siguiente manera:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=Firma GPG armadura
-key_signature_gpg_placeholder=Comienza con '-----BEGIN PGP SIGNATURE-----'
+key_signature_gpg_placeholder=Comienza con "-----BEGIN PGP SIGNATURE-----"
verify_gpg_key_success=La clave GPG "%s" ha sido verificada.
ssh_key_verified=Clave verificada
ssh_key_verified_long=La clave ha sido verificada con un token y puede ser usada para verificar confirmaciones que coincidan con cualquier direcciรณn de correo electrรณnico activada para este usuario.
@@ -803,11 +887,11 @@ ssh_token_required=Debe proporcionar una firma para el token de abajo
ssh_token=Token
ssh_token_help=Puede generar una firma de la siguiente manera:
ssh_token_signature=Firma SSH armadura
-key_signature_ssh_placeholder=Comienza con '-----BEGIN SSH SIGNATURE-----'
+key_signature_ssh_placeholder=Comienza con "-----BEGIN SSH SIGNATURE-----"
verify_ssh_key_success=La clave SSH "%s" ha sido verificada.
subkeys=Subclaves
key_id=ID de clave
-key_name=Nombre de la Clave
+key_name=Nombre de la clave
key_content=Contenido
principal_content=Contenido
add_key_success=La clave SSH "%s" ha sido aรฑadida.
@@ -843,15 +927,15 @@ social_desc=Estas cuentas sociales se pueden utilizar para iniciar sesiรณn en tu
unbind=Desvincular
unbind_success=La cuenta social se ha eliminado correctamente.
-manage_access_token=Administrar Tokens de Acceso
-generate_new_token=Generar nuevo Token
+manage_access_token=Tokens de acceso
+generate_new_token=Generar nuevo token
tokens_desc=Estos tokens otorgan acceso a su cuenta usando la API de Forgejo.
-token_name=Nombre del Token
-generate_token=Generar Token
+token_name=Nombre del token
+generate_token=Generar token
generate_token_success=Su nuevo token ha sido generado. Cรณpielo ahora, ya que no se volverรก a mostrar.
generate_token_name_duplicate=%s ya se ha utilizado como nombre de la aplicaciรณn. Por favor, utilice una nueva.
delete_token=Eliminar
-access_token_deletion=Eliminar Token de Acceso
+access_token_deletion=Eliminar token de acceso
access_token_deletion_cancel_action=Cancelar
access_token_deletion_confirm_action=Eliminar
access_token_deletion_desc=Eliminar un token revocarรก el acceso a su cuenta para las aplicaciones que lo usen. Esto no se puede deshacer. ยฟContinuar?
@@ -862,8 +946,8 @@ permissions_access_all=Todo (pรบblico, privado y limitado)
select_permissions=Seleccionar permisos
permission_no_access=Sin acceso
permission_read=Leรญdas
-permission_write=Lectura y Escritura
-access_token_desc=Los permisos de los tokens seleccionados limitan la autorizaciรณn sรณlo a las rutas API correspondientes. Lea la documentaciรณn para mรกs informaciรณn.
+permission_write=Lectura y escritura
+access_token_desc=Los permisos de los tokens seleccionados limitan la autorizaciรณn sรณlo a las rutas >API correspondientes. Lea la >documentaciรณn para mรกs informaciรณn.
at_least_one_permission=Debe seleccionar al menos un permiso para crear un token
permissions_list=Permisos:
@@ -874,10 +958,10 @@ remove_oauth2_application=Eliminar aplicaciรณn OAuth2
remove_oauth2_application_desc=Eliminar una aplicaciรณn OAuth2 revocarรก el acceso a todos los tokens de acceso firmados. ยฟContinuar?
remove_oauth2_application_success=La aplicaciรณn ha sido eliminada.
create_oauth2_application=Crear una nueva aplicaciรณn OAuth2
-create_oauth2_application_button=Crear Aplicaciรณn
+create_oauth2_application_button=Crear aplicaciรณn
create_oauth2_application_success=Ha creado con รฉxito una nueva aplicaciรณn de OAuth2.
update_oauth2_application_success=Ha actualizado correctamente la aplicaciรณn de OAuth2.
-oauth2_application_name=Nombre de la Aplicaciรณn
+oauth2_application_name=Nombre de la aplicaciรณn
oauth2_confidential_client=Cliente confidencial. Seleccione para aplicaciones que mantengan el secreto confidencial, tales como aplicaciones web. No seleccione para aplicaciones nativas, incluyendo aplicaciones de escritorio y mรณviles.
oauth2_redirect_uris=Redirigir URIs. Por favor, usa una nueva lรญnea para cada URI.
save_application=Guardar
@@ -892,7 +976,7 @@ oauth2_application_remove_description=Eliminar una aplicaciรณn de OAuth2 evitar
oauth2_application_locked=Forgejo pre-registra algunas aplicaciones de OAuth2 en el arranque si estรกn habilitadas en la configuraciรณn. Para prevenir un comportamiento inesperado, estos no pueden ser editados ni removidos. Por favor, consulte la documentaciรณn de OAuth2 para mรกs informaciรณn.
authorized_oauth2_applications=Aplicaciones OAuth2 autorizadas
-authorized_oauth2_applications_description=Has concedido acceso a tu cuenta personal de Forgejo a estas aplicaciones de terceros. Por favor, revoca el acceso para las aplicaciones que ya no necesitas.
+authorized_oauth2_applications_description=Has concedido acceso a tu cuenta personal de Forgejo a estas aplicaciones de terceros. Por favor, revoca el acceso para las aplicaciones que ya no estรฉn en uso.
revoke_key=Revocar
revoke_oauth2_grant=Revocar acceso
revoke_oauth2_grant_description=Revocar el acceso a esta aplicaciรณn impedirรก que esta aplicaciรณn acceda a sus datos. ยฟEstรก seguro?
@@ -901,7 +985,7 @@ revoke_oauth2_grant_success=Acceso revocado correctamente.
twofa_desc=La autenticaciรณn de doble factor mejora la seguridad de su cuenta.
twofa_is_enrolled=Su cuenta actualmente estรก registrada en la autenticaciรณn de doble factor.
twofa_not_enrolled=Tu cuenta no estรก actualmente inscrita en la autenticaciรณn de doble factor.
-twofa_disable=Deshabilitar autenticaciรณn de doble factor
+twofa_disable=Deshabilitar autenticaciรณn de dos factores
twofa_scratch_token_regenerate=Regenerar cรณdigo de respaldo
twofa_scratch_token_regenerated=Tu token de scratch es ahora %s. Guรกrdelo en un lugar seguro, nunca se volverรก a mostrar.
twofa_enroll=Inscribirse en la autenticaciรณn de doble factor
@@ -913,19 +997,19 @@ scan_this_image=Escanee esta imagen con su aplicaciรณn de autenticaciรณn:
or_enter_secret=O introduzca el secreto: %s
then_enter_passcode=E introduzca el cรณdigo de acceso mostrado en la aplicaciรณn:
passcode_invalid=El cรณdigo de acceso es incorrecto. Vuelva a intentarlo.
-twofa_enrolled=Su cuenta ha sido inscrita en la autenticaciรณn de doble factor. ยกGuarde su cรณdigo de respaldo (%s) en un lugar seguro, ya que sรณlo se muestra una vez!
+twofa_enrolled=Su cuenta ha sido inscrita en la autenticaciรณn de doble factor. Guarde su cรณdigo de respaldo (%s) en un lugar seguro, ya que no se mostrarรก nuevamente.
twofa_failed_get_secret=No se pudo obtener el secreto.
-webauthn_desc=Las claves de seguridad son dispositivos hardware que contienen claves criptogrรกficas. Pueden ser usados para la autenticaciรณn de doble factor. Las claves de seguridad deben soportar el estรกndar WebAuthn Authenticator .
+webauthn_desc=Las claves de seguridad son dispositivos hardware que contienen claves criptogrรกficas. Pueden ser usados para la autenticaciรณn de doble factor. Las claves de seguridad deben soportar el estรกndar WebAuthn Authenticator .
webauthn_register_key=Aรฑadir clave de seguridad
webauthn_nickname=Apodo
webauthn_delete_key=Eliminar clave de seguridad
webauthn_delete_key_desc=Si elimina una llave de seguridad ya no podrรก utilizarla para iniciar sesiรณn con ella. ยฟContinuar?
-manage_account_links=Administrar cuentas vinculadas
+manage_account_links=Cuentas vinculadas
manage_account_links_desc=Estas cuentas externas estรกn vinculadas a su cuenta de Forgejo.
account_links_not_available=Actualmente no hay cuentas externas vinculadas a su cuenta de Forgejo.
-link_account=Enlazar cuenta
+link_account=Vincular cuenta
remove_account_link=Eliminar cuenta vinculada
remove_account_link_desc=Eliminar una cuenta vinculada revocarรก su acceso a su cuenta de Forgejo. ยฟContinuar?
remove_account_link_success=La cuenta vinculada ha sido eliminada.
@@ -938,21 +1022,21 @@ repos_none=No posees ningรบn repositorio.
delete_account=Elimina tu cuenta
delete_prompt=Esta operaciรณn eliminarรก permanentemente su cuenta de usuario. NO podrรก deshacerse.
delete_with_all_comments=Tu cuenta es menor de %s. Para evitar comentarios fantasma, todos los comentarios/PR serรกn eliminados con ella.
-confirm_delete_account=Confirmar Eliminaciรณn
+confirm_delete_account=Confirmar eliminaciรณn
delete_account_title=Eliminar cuenta de usuario
delete_account_desc=ยฟEstรก seguro que desea eliminar permanentemente esta cuenta de usuario?
email_notifications.enable=Habilitar notificaciones por correo electrรณnico
email_notifications.onmention=Enviar correo sรณlo al ser mencionado
email_notifications.disable=Deshabilitar las notificaciones por correo electrรณnico
-email_notifications.submit=Establecer preferencias de correo electrรณnico
+email_notifications.submit=Establecer preferencia de correo electrรณnico
email_notifications.andyourown=Y sus propias notificaciones
visibility=Visibilidad del usuario
visibility.public=Pรบblico
visibility.public_tooltip=Visible para todos
visibility.limited=Limitado
-visibility.limited_tooltip=Sรณlo visible para usuarios autenticados
+visibility.limited_tooltip=Sรณlo visible para usuarios que han iniciado sesiรณn
visibility.private=Privado
visibility.private_tooltip=Visible sรณlo para los miembros de organizaciones a las que te has unido
blocked_since = Bloqueado desde %s
@@ -962,7 +1046,49 @@ twofa_recovery_tip = Si pierdes tu dispositivo podrรกs usar una clave รบnica de
webauthn_alternative_tip = Es posible que deseee configurar un mรฉtodo de autenticaciรณn adicional.
webauthn_key_loss_warning = Si pierdes tus claves de seguridad perderรกs acceso a tu cuenta.
blocked_users = Usuarios bloqueados
-blocked_users_none = No has bloqueado a ningรบn usuario.
+blocked_users_none = No hay usuarios bloqueados.
+update_hints = Actualizar sugerencias
+pronouns = Pronombres
+pronouns_custom = Personalizados
+additional_repo_units_hint = Sugerir la habilitaciรณn de unidades de repositorio adicionales
+additional_repo_units_hint_description = Mostrar la sugerencia "Habilitar mรกs" para los repositorios que no tengan habilitadas todas las unidades disponibles.
+language.title = Idioma por defecto
+update_hints_success = Se han actualizado las sugerencias.
+pronouns_unspecified = No especificados
+hints = Sugerencias
+change_password = Cambiar contraseรฑa
+keep_activity_private.description = Tu actividad pรบblica solo serรก visible para ti y para los administradores de la instancia.
+language.description = Este idioma se guardarรก en tu cuenta y se utilizarรก como predeterminado cuando te conectes.
+language.localization_project = ยกAyรบdanos a traducir Forgejo a tu idioma! Mรกs informaciรณn .
+pronouns_custom_label = Pronombres personalizados
+user_block_yourself = No puede bloquearse a sรญ mismo.
+quota = Cuota
+quota.sizes.assets.attachments.all = Archivos adjuntos
+
+storage_overview = Resumen del almacenamiento
+keep_pronouns_private = Mostrar pronombres solo a personas autenticadas
+regenerate_token = Regenerar
+quota.sizes.all = Todo
+quota.sizes.repos.all = Repositorios
+quota.sizes.repos.public = Repositorios pรบblicos
+quota.sizes.repos.private = Repositorios privados
+quota.sizes.git.all = Contenido de Git
+quota.sizes.assets.attachments.releases = Archivos adjuntos del lanzamiento
+quota.sizes.assets.artifacts = Artefactos
+quota.sizes.assets.packages.all = Paquetes
+quota.sizes.wiki = Wiki
+
+change_username_redirect_prompt.with_cooldown.one = El antiguo nombre de usuario estarรก disponible para todos despuรฉs un periodo de tiempo de espera de %[1]d dรญa, aรบn puedes reclamar el antiguo nombre de usuario durante el periodo de tiempo de espera.
+change_username_redirect_prompt.with_cooldown.few = El antiguo nombre de usuario estarรก disponible para todos despuรฉs un periodo de tiempo de espera de %[1]d dรญas, aรบn puedes reclamar el antiguo nombre de usuario durante el periodo de tiempo de espera.
+quota.rule.exceeded = Excedido
+quota.rule.no_limit = Ilimitado
+quota.sizes.assets.all = Activos
+
+access_token_regeneration = Regenerar token de acceso
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.attachments.issues = Archivos adjuntos de incidencia
+
+keep_pronouns_private.description = Esto ocultarรก sus pronombres a los visitantes que no hayan iniciado sesiรณn.
[repo]
owner=Propietario
@@ -971,20 +1097,20 @@ repo_name=Nombre del repositorio
repo_name_helper=Un buen nombre de repositorio estรก compuesto por palabras clave cortas, memorables y รบnicas.
repo_size=Tamaรฑo del repositorio
template=Plantilla
-template_select=Seleccionar una plantilla.
+template_select=Seleccionar una plantilla
template_helper=Hacer del repositorio una plantilla
template_description=Las plantillas de repositorio permiten a los usuarios generar nuevos repositorios con la misma estructura de directorios, archivos y configuraciones opcionales.
visibility=Visibilidad
visibility_description=Sรณlo el propietario o los miembros de la organizaciรณn -si tienen derechos- podrรกn verlo.
visibility_helper=Hacer el repositorio privado
visibility_helper_forced=El administrador de su sitio obliga a nuevos repositorios a ser privados.
-visibility_fork_helper=(Cambiar esto afectarรก a todos los forks)
+visibility_fork_helper=(Cambiar esto afectarรก a la visibilidad de todas las bifurcaciones.)
clone_helper=ยฟNecesita ayuda para clonar? Visite Ayuda .
-fork_repo=Hacer fork del repositorio
-fork_from=Crear un fork desde
+fork_repo=Hacer una bifurcaciรณn del repositorio
+fork_from=Crear una bifurcaciรณn desde
already_forked=Ya ha forkeado %s
-fork_to_different_account=Forkear a una cuenta diferente
-fork_visibility_helper=La visibilidad de un repositorio del cual se ha hecho fork no puede ser cambiada.
+fork_to_different_account=Bifurcar a una cuenta diferente
+fork_visibility_helper=No se puede cambiar la visibilidad de un repositorio bifurcado.
fork_branch=Rama a clonar en la bifurcaciรณn
all_branches=Todas las ramas
fork_no_valid_owners=Este repositorio no puede ser bifurcado porque no hay propietarios vรกlidos.
@@ -998,17 +1124,17 @@ generate_from=Generar desde
repo_desc=Descripciรณn
repo_desc_helper=Introduce una descripciรณn corta (opcional)
repo_lang=Idioma
-repo_gitignore_helper=Seleccionar plantillas de .gitignore.
+repo_gitignore_helper=Seleccionar plantillas de .gitignore
repo_gitignore_helper_desc=Elija quรฉ archivos no rastrear de una lista de plantillas para idiomas comunes. Los artefactos tรญpicos generados por las herramientas de construcciรณn de cada idioma se incluyen por defecto en .gitignore.
-issue_labels=Etiquetas de incidencia
-issue_labels_helper=Seleccione un conjunto de etiquetas de incidencia.
+issue_labels=Etiquetas
+issue_labels_helper=Selecciona un conjunto de etiquetas
license=Licencia
-license_helper=Seleccione un archivo de licencia.
-license_helper_desc=Una licencia regula lo que otros pueden y no pueden hacer con tu cรณdigo. ยฟNo estรก seguro de cuรกl es el adecuado para su proyecto? Vea Elija una licencia.
+license_helper=Selecciona un archivo de licencia
+license_helper_desc=Una licencia regula lo que otros pueden y no pueden hacer con tu cรณdigo. ยฟNo estรก seguro de cuรกl es el adecuado para su proyecto? Vea Elija una licencia .
readme=LรAME
-readme_helper=Seleccione una plantilla de archivo LรAME.
+readme_helper=Selecciona una plantilla de archivo README
readme_helper_desc=Este es el lugar donde puedes escribir una descripciรณn completa de su proyecto.
-auto_init=Inicializar el repositorio (aรฑade .gitignore, licencia y README)
+auto_init=Inicializar el repositorio
trust_model_helper=Seleccionar modelo de confianza para la verificaciรณn de la firma. Las opciones posibles son:
trust_model_helper_collaborator=Colaborador: Confiar en firmas de colaboradores
trust_model_helper_committer=Comitter: Firmas de confianza que coinciden con los committers
@@ -1020,29 +1146,29 @@ default_branch_label=por defecto
default_branch_helper=La rama por defecto es la rama base para pull requests y commits de cรณdigo.
mirror_prune=Purgar
mirror_prune_desc=Eliminar referencias de seguimiento de remotes obsoletas
-mirror_interval=Intervalo de rรฉplica (Las unidades de tiempo vรกlidas son 'h', 'm', 's'). 0 para deshabilitar la sincronizaciรณn automรกtica. (Intervalo mรญnimo: %s)
+mirror_interval=Intervalo de rรฉplica (Las unidades de tiempo vรกlidas son "h", "m", "s"). 0 para deshabilitar la sincronizaciรณn automรกtica. (Intervalo mรญnimo: %s)
mirror_interval_invalid=El intervalo de rรฉplica no es vรกlido.
mirror_sync_on_commit=Sincronizar cuando los commits sean subidos
mirror_address=Clonar desde URL
mirror_address_desc=Ponga cualquier credencial requerida en la secciรณn de Autorizaciรณn.
-mirror_address_url_invalid=La URL proporcionada no es vรกlida. Debe escapar todos los componentes de la url correctamente.
+mirror_address_url_invalid=La URL proporcionada no es vรกlida. Debe escapar correctamente todos los componentes de la URL.
mirror_address_protocol_invalid=La URL proporcionada no es vรกlida. Sรณlo http(s):// o git:// se puede utilizar para ser replicadas.
mirror_lfs=Almacenamiento de archivos grande (LFS)
mirror_lfs_desc=Activar la reproducciรณn de datos LFS.
-mirror_lfs_endpoint=Punto final de LFS
+mirror_lfs_endpoint=Destino LFS
mirror_lfs_endpoint_desc=Sync intentarรก usar la url del clon para determinar el servidor LFS . Tambiรฉn puede especificar un punto final personalizado si los datos LFS del repositorio se almacenan en otro lugar.
-mirror_last_synced=Sincronizado por รบltima vez
+mirror_last_synced=รltima sincronizaciรณn
mirror_password_placeholder=(Sin cambios)
mirror_password_blank_placeholder=(Indefinido)
mirror_password_help=Cambie el nombre de usario para eliminar una contraseรฑa almacenada.
watchers=Seguidores
stargazers=Fans
stars_remove_warning=Esto eliminarรก todas las estrellas de este repositorio.
-forks=Forks
+forks=Bifurcaciones
reactions_more=y %d mรกs
unit_disabled=El administrador del sitio ha deshabilitado esta secciรณn del repositorio.
language_other=Otros
-adopt_search=Introduzca el nombre de usuario para buscar repositorios no adoptados... (dรฉjelo en blanco para encontrar todos)
+adopt_search=Introduzca el nombre de usuario para buscar repositorios no adoptadosโฆ (dรฉjelo en blanco para encontrar todos)
adopt_preexisting_label=Adoptar archivos
adopt_preexisting=Adoptar archivos preexistentes
adopt_preexisting_content=Crear repositorio desde %s
@@ -1075,8 +1201,8 @@ desc.archived=Archivado
template.items=Elementos de plantilla
template.git_content=Contenido Git (rama predeterminada)
-template.git_hooks=Git Hooks
-template.git_hooks_tooltip=Actualmente no puede modificar ni eliminar Git Hooks despuรฉs de haberlos agregado. Seleccione esto solo si confรญa en el repositorio de plantillas.
+template.git_hooks=Hooks de Git
+template.git_hooks_tooltip=Actualmente no puedes modificar ni eliminar hooks de Git una vez aรฑadidos. Selecciona esto solo si confรญas en el repositorio de plantillas.
template.webhooks=Webhooks
template.topics=Temas
template.avatar=Avatar
@@ -1084,7 +1210,7 @@ template.issue_labels=Etiquetas de incidencia
template.one_item=Debe seleccionar al menos un elemento de plantilla
template.invalid=Debe seleccionar una plantilla de repositorio
-archive.title=Este repositorio estรก archivado. Usted puede ver los archivos y clonarlos, pero no puede hace push o abrir incidencias o pull requests.
+archive.title=Este repositorio estรก archivado. Puede ver los archivos y clonarlos, pero no puede hacer push o, abrir incidencias o pull requests.
archive.title_date=Este repositorio ha sido archivado en %s. Puedes ver archivos y clonarlo, pero no puedes hacer push o abrir incidencias o pull request.
archive.issue.nocomment=Este repositorio estรก archivado. No se puede comentar en las incidencias.
archive.pull.nocomment=Este repositorio estรก archivado. No se puede comentar en los pull requests.
@@ -1099,7 +1225,7 @@ migrate_options=Opciones de migraciรณn
migrate_service=Servicio de Migraciรณn
migrate_options_mirror_helper=Este repositorio serรก una rรฉplica
migrate_options_lfs=Migrar archivos LFS
-migrate_options_lfs_endpoint.label=Punto final de LFS
+migrate_options_lfs_endpoint.label=Destino LFS
migrate_options_lfs_endpoint.description=Migraciรณn intentarรก usar su mando Git para determinar el servidor LFS . Tambiรฉn puede especificar un punto final personalizado si los datos LFS del repositorio se almacenan en otro lugar.
migrate_options_lfs_endpoint.description.local=Tambiรฉn se admite una ruta del servidor local.
migrate_options_lfs_endpoint.placeholder=Si se deja en blanco, el punto final se derivarรก de la URL de clonaciรณn
@@ -1108,12 +1234,12 @@ migrate_items_wiki=Wiki
migrate_items_milestones=Hitos
migrate_items_labels=Etiquetas
migrate_items_issues=Incidencias
-migrate_items_pullrequests=Pull Requests
-migrate_items_merge_requests=Merge Requests
+migrate_items_pullrequests=Solicitudes de extracciรณn
+migrate_items_merge_requests=Solicitudes de fusiรณn
migrate_items_releases=Lanzamientos
-migrate_repo=Migrar Repositorio
+migrate_repo=Migrar repositorio
migrate.clone_address=Migrar / Clonar desde URL
-migrate.clone_address_desc=La URL HTTP(S) o de Git 'clone' de un repositorio existente
+migrate.clone_address_desc=La URL HTTP(S) o de Git "clone" de un repositorio existente
migrate.github_token_desc=Puedes poner uno o mรกs tokens con comas separadas aquรญ para hacer migrar mรกs rรกpido debido al lรญmite de velocidad de GitHub API. PRECAUCIรN: Abusar esta caracterรญstica puede violar la polรญtica del proveedor de servicios y llevar a bloquear la cuenta.
migrate.clone_local_path=o una ruta local del servidor
migrate.permission_denied=No te estรก permitido importar repositorios locales.
@@ -1121,44 +1247,44 @@ migrate.permission_denied_blocked=No puede importar desde hosts no permitidos, p
migrate.invalid_local_path=La ruta local no es vรกlida. No existe o no es un directorio.
migrate.invalid_lfs_endpoint=El punto final de LFS no es vรกlido.
migrate.failed=Migraciรณn fallida: %v
-migrate.migrate_items_options=Un token de acceso es necesario para migrar elementos adicionales
+migrate.migrate_items_options=Se necesita un token de acceso para migrar elementos adicionales
migrated_from=Migrado desde %[2]s
migrated_from_fake=Migrado desde %[1]s
migrate.migrate=Migrar desde %s
-migrate.migrating=Migrando desde %s ...
+migrate.migrating=Migrando desde %s โฆ
migrate.migrating_failed=La migraciรณn desde %s ha fallado.
migrate.migrating_failed.error=Error al migrar: %s
migrate.migrating_failed_no_addr=Migraciรณn fallida.
-migrate.github.description=Migrar datos desde github.com u otra instancia de GitHub.
+migrate.github.description=Migrar datos desde github.com o un servidor GitHub Enterprise.
migrate.git.description=Migrar un repositorio sรณlo desde cualquier servicio Git.
migrate.gitlab.description=Migrar datos de gitlab.com u otra instancia de GitLab.
-migrate.gitea.description=Migrar datos de gitea.com u otra instancia de Gitea/Forgejo.
+migrate.gitea.description=Migrar datos de gitea.com u otra instancia de Gitea.
migrate.gogs.description=Migrar datos de notabug.org u otra instancia de Gogs.
migrate.onedev.description=Migrar datos desde code.onedev.io u otra instancia de OneDev.
migrate.codebase.description=Migrar datos desde codebasehq.com.
migrate.gitbucket.description=Migrar datos de instancias de GitBucket.
migrate.migrating_git=Migrando datos de Git
-migrate.migrating_topics=Migrando Temas
-migrate.migrating_milestones=Migrando Hitos
+migrate.migrating_topics=Migrando temas
+migrate.migrating_milestones=Migrando hitos
migrate.migrating_labels=Migrando etiquetas
-migrate.migrating_releases=Migrando Lanzamientos
+migrate.migrating_releases=Migrando lanzamientos
migrate.migrating_issues=Migrando incidencias
-migrate.migrating_pulls=Migrando Pull Requests
+migrate.migrating_pulls=Migrando solicitudes de incorporaciรณn de cambios
migrate.cancel_migrating_title=Cancelar la migraciรณn
migrate.cancel_migrating_confirm=ยฟQuiere cancelar esta migraciรณn?
mirror_from=rรฉplica de
-forked_from=forkeado de
+forked_from=bifurcado de
generated_from=generado desde
-fork_from_self=No puede hacer fork a un repositorio que ya es suyo.
-fork_guest_user=Regรญstrate para forkear este repositorio.
+fork_from_self=No puede bifurcar un repositorio que ya es suyo.
+fork_guest_user=Iniciar sesiรณn para bifurcar este repositorio.
watch_guest_user=Iniciar sesiรณn para seguir este repositorio.
star_guest_user=Iniciar sesiรณn para destacar este repositorio.
unwatch=Dejar de seguir
watch=Seguir
unstar=Eliminar de favoritos
star=Destacar
-fork=Fork
+fork=Bifurcar
download_archive=Descargar repositorio
more_operations=Mรกs operaciones
@@ -1181,7 +1307,7 @@ find_tag=Buscar etiqueta
branches=Ramas
tags=Etiquetas
issues=Incidencias
-pulls=Pull Requests
+pulls=Pull requests
project_board=Proyectos
packages=Paquetes
actions=Acciones
@@ -1209,22 +1335,23 @@ invisible_runes_header=`Este archivo contiene caracteres Unicode invisibles`
invisible_runes_description=`Este archivo contiene caracteres Unicode invisibles que son indistinguibles para los humanos, pero que pueden ser procesados de forma diferente por un ordenador. Si crees que esto es intencional, puedes ignorar esta advertencia. Usa el botรณn de Escape para revelarlos.`
ambiguous_runes_header=`Este archivo contiene caracteres Unicode ambiguos`
ambiguous_runes_description=`Este archivo contiene caracteres Unicode que pueden confundirse con otros caracteres. Si crees que esto es intencional, puedes ignorar esta advertencia. Usa el botรณn de Escape para revelarlos.`
-invisible_runes_line=`Esta lรญnea tiene caracteres unicode invisibles`
-ambiguous_runes_line=`Esta lรญnea tiene caracteres unicode ambiguos`
+invisible_runes_line=`Esta lรญnea tiene caracteres Unicode invisibles`
+ambiguous_runes_line=`Esta lรญnea tiene caracteres Unicode ambiguos`
ambiguous_character=`%[1]c [U+%04[1]X] es confusable con %[2]c [U+%04[2]X]`
escape_control_characters=Escapar
unescape_control_characters=No Escapar
-file_copy_permalink=Copiar Permalink
-view_git_blame=Ver la culpa de Git
-video_not_supported_in_browser=Su navegador no soporta el tag video de HTML5.
-audio_not_supported_in_browser=Su navegador no soporta el tag audio de HTML5.
+file_copy_permalink=Copiar permalink
+view_git_blame=Ver Git blame
+video_not_supported_in_browser=Su navegador no soporta el tag "video" de HTML5.
+audio_not_supported_in_browser=Su navegador no soporta el tag "audio" de HTML5.
stored_lfs=Almacenados con Git LFS
+stored_annex=Almacenados con Git Annex
symbolic_link=Enlace simbรณlico
-executable_file=Archivo Ejecutable
+executable_file=Archivo ejecutable
commit_graph=Grรกfico de commits
commit_graph.select=Seleccionar ramas
-commit_graph.hide_pr_refs=Ocultar Pull Requests
+commit_graph.hide_pr_refs=Ocultar pull requests
commit_graph.monochrome=Mono
commit_graph.color=Color
commit.contained_in=Este commit estรก contenido en:
@@ -1238,13 +1365,14 @@ lines=lรญneas
from_comment=(comentario)
editor.add_file=Aรฑadir archivo
-editor.new_file=Nuevo Archivo
+editor.new_file=Nuevo archivo
editor.upload_file=Subir archivo
-editor.edit_file=Editar Archivo
+editor.edit_file=Editar archivo
editor.preview_changes=Vista previa de los cambios
editor.cannot_edit_lfs_files=Los archivos LFS no se pueden editar en la interfaz web.
+editor.cannot_edit_annex_files=Los archivos Annex no se pueden editar en la interfaz web.
editor.cannot_edit_non_text_files=Los archivos binarios no se pueden editar en la interfaz web.
-editor.edit_this_file=Editar Archivo
+editor.edit_this_file=Editar archivo
editor.this_file_locked=El archivo estรก bloqueado
editor.must_be_on_a_branch=Debes estar en una rama para hacer o proponer cambios en este archivo.
editor.fork_before_edit=Debes hacer fork a este repositorio para hacer o proponer cambios a este archivo.
@@ -1252,12 +1380,12 @@ editor.delete_this_file=Eliminar archivo
editor.must_have_write_access=Debes tener permisos de escritura para hacer o proponer cambios a este archivo.
editor.file_delete_success=El archivo "%s" ha sido eliminado.
editor.name_your_file=Nombre su archivoโฆ
-editor.filename_help=Aรฑade un directorio escribiendo su nombre seguido de una barra ('/'). Para eliminar un directorio, presione la tecla de retroceso al comienzo del campo de entrada.
+editor.filename_help=Aรฑade un directorio escribiendo su nombre seguido de una barra ("/"). Para eliminar un directorio, presione la tecla de retroceso al comienzo del campo de entrada.
editor.or=o
editor.cancel_lower=Cancelar
editor.commit_signed_changes=Crear commit firmado de los cambios
editor.commit_changes=Crear commit de los cambios
-editor.add_tmpl=Aรฑadir ''
+editor.add_tmpl=Aรฑadir "<%s>"
editor.add=Aรฑadir %s
editor.update=Actualizar %s
editor.delete=Eliminar %s
@@ -1267,7 +1395,7 @@ editor.fail_to_apply_patch=`No se puede aplicar el parche "%s"`
editor.new_patch=Nuevo parche
editor.commit_message_desc=Aรฑadir una descripciรณn extendida opcionalโฆ
editor.signoff_desc=Aรฑadir un trailer firmado por el committer al final del mensaje de registro de confirmaciรณn.
-editor.commit_directly_to_this_branch=Hacer commit directamente en la rama %s .
+editor.commit_directly_to_this_branch=Hacer commit directamente en la rama %[1]s .
editor.create_new_branch=Crear una nueva rama para este commit y hacer un pull request.
editor.create_new_branch_np=Crear una nueva rama para este commit.
editor.propose_file_change=Proponer cambio de archivo
@@ -1283,16 +1411,16 @@ editor.file_is_a_symlink=`"%s" es un enlace simbรณlico. Los enlaces simbรณlicos
editor.filename_is_a_directory=Nombre de archivo "%s" ya se utiliza como nombre de directorio en este repositorio.
editor.file_editing_no_longer_exists=El archivo que se estรก editando, "%s", ya no existe en este repositorio.
editor.file_deleting_no_longer_exists=El archivo que se estรก eliminando, "%s", ya no existe en este repositorio.
-editor.file_changed_while_editing=Desde que comenzรณ a editar, el contenido del archivo ha sido cambiado. Haga clic aquรญ para ver quรฉ ha cambiado o presione confirmar de nuevo para sobrescribir los cambios.
+editor.file_changed_while_editing=El contenido del archivo ha sido modificado desde que comenzaste a editarlo. Haz clic aquรญ para verlo o confirma de nuevo para sobrescribir los cambios.
editor.file_already_exists=Ya existe un archivo llamado "%s" en este repositorio.
editor.commit_empty_file_header=Commit un archivo vacรญo
editor.commit_empty_file_text=El archivo que estรกs tratando de commit estรก vacรญo. ยฟProceder?
editor.no_changes_to_show=No existen cambios para mostrar.
editor.fail_to_update_file=Error al actualizar/crear el archivo "%s".
-editor.fail_to_update_file_summary=Mensaje de error
-editor.push_rejected_no_message=El cambio fue rechazado por el servidor sin un mensaje. Por favor, compruebe Git Hooks.
+editor.fail_to_update_file_summary=Mensaje de error:
+editor.push_rejected_no_message=El cambio fue rechazado por el servidor sin un mensaje. Por favor, comprueba los Git Hooks.
editor.push_rejected=El cambio fue rechazado por el servidor. Por favor, comprueba los Git Hooks.
-editor.push_rejected_summary=Mensaje completo de rechazo
+editor.push_rejected_summary=Mensaje completo de rechazo:
editor.add_subdir=Aรฑadir un directorioโฆ
editor.unable_to_upload_files=Error al subir los archivos a "%s" con error: %v
editor.upload_file_is_locked=El archivo "%s" estรก bloqueado por %s.
@@ -1311,7 +1439,7 @@ commits.nothing_to_compare=Estas ramas son iguales.
commits.search=Buscar commitsโฆ
commits.search.tooltip=Puede prefijar palabras clave con "author:", "committer:", "after:", o "before:", p. ej., "revertir author:Alice before:2019-01-13".
commits.find=Buscar
-commits.search_all=Todas las Ramas
+commits.search_all=Todas las ramas
commits.author=Autor
commits.message=Mensaje
commits.date=Fecha
@@ -1321,7 +1449,7 @@ commits.signed_by=Firmado por
commits.signed_by_untrusted_user=Firmado por usuario no fiable
commits.signed_by_untrusted_user_unmatched=Firmado por un usuario no fiable que no coincide con el colaborador
commits.gpg_key_id=ID de clave GPG
-commits.ssh_key_fingerprint=Huella clave SSH
+commits.ssh_key_fingerprint=Huella de clave SSH
commits.view_path=Ver en este punto en el historial
commit.operations=Operaciones
@@ -1337,30 +1465,30 @@ commitstatus.failure=Fallo
commitstatus.pending=Pendiente
commitstatus.success=รxito
-ext_issues=Acceso a incidencias externas
+ext_issues=Incidencias externas
ext_issues.desc=Enlace a un gestor de incidencias externo.
projects=Proyectos
projects.desc=Gestionar problemas y pulls en los tablones del proyecto.
projects.description=Descripciรณn (opcional)
projects.description_placeholder=Descripciรณn
-projects.create=Crear Proyecto
+projects.create=Crear proyecto
projects.title=Tรญtulo
projects.new=Nuevo proyecto
projects.new_subheader=Coordine, haga seguimiento y actualice su trabajo en un solo lugar, para que los proyectos se mantengan transparentes y en el calendario previsto.
projects.create_success=El proyecto "%s" ha sido creado.
-projects.deletion=Eliminar Proyecto
+projects.deletion=Eliminar proyecto
projects.deletion_desc=Eliminar un proyecto elimina todos las incidencias relacionadas. ยฟContinuar?
projects.deletion_success=Se eliminรณ el proyecto.
-projects.edit=Editar Proyectos
+projects.edit=Editar proyectos
projects.edit_subheader=Los proyectos organizan las incidencias y el seguimiento del progreso.
-projects.modify=Actualizar Proyecto
+projects.modify=Actualizar proyecto
projects.edit_success=El proyecto "%s" ha sido actualizado.
projects.type.none=Ninguno
projects.type.basic_kanban=Kanban bรกsico
-projects.type.bug_triage=Prueba de error
-projects.template.desc=Plantilla del proyecto
-projects.template.desc_helper=Seleccione una plantilla de proyecto para empezar
+projects.type.bug_triage=Triaje de errores
+projects.template.desc=Plantilla
+projects.template.desc_helper=Selecciona una plantilla de proyecto para empezar
projects.type.uncategorized=Sin categorizar
projects.column.edit=Editar columna
projects.column.edit_title=Nombre
@@ -1372,12 +1500,12 @@ projects.column.set_default_desc=Establecer esta columna como predeterminada par
projects.column.unset_default=Anular valor predeterminado
projects.column.unset_default_desc=Anular esta columna como la predeterminada
projects.column.delete=Borrar columna
-projects.column.deletion_desc=Eliminar una columna del proyecto mueve todos los problemas relacionados a 'Sin categorizar'. ยฟContinuar?
+projects.column.deletion_desc=Eliminar una columna del proyecto mueve todos los problemas relacionados a la columna por defecto. ยฟContinuar?
projects.column.color=Color
projects.open=Abrir
projects.close=Cerrar
projects.column.assigned_to=Asignado a
-projects.card_type.desc=Vista previa de tarjeta
+projects.card_type.desc=Vista previa de tarjetas
projects.card_type.images_and_text=Imรกgenes y texto
projects.card_type.text_only=Sรณlo texto
@@ -1395,17 +1523,17 @@ issues.new.clear_labels=Limpiar etiquetas
issues.new.projects=Proyectos
issues.new.clear_projects=Limpiar proyectos
issues.new.no_projects=Ningรบn proyecto
-issues.new.open_projects=Proyectos Abiertos
+issues.new.open_projects=Proyectos abiertos
issues.new.closed_projects=Proyectos cerrados
issues.new.no_items=No hay elementos
-issues.new.milestone=Milestone
-issues.new.no_milestone=Sin Milestone
+issues.new.milestone=Hito
+issues.new.no_milestone=Sin hito
issues.new.clear_milestone=Limpiar Milestone
-issues.new.open_milestone=Milestones abiertas
-issues.new.closed_milestone=Milestones cerradas
+issues.new.open_milestone=Hitos abiertos
+issues.new.closed_milestone=Hitos cerradas
issues.new.assignees=Asignados
issues.new.clear_assignees=Limpiar asignados
-issues.new.no_assignees=No asignados
+issues.new.no_assignees=Sin encargados
issues.new.no_reviewers=No hay revisores
issues.choose.get_started=Comenzar
issues.choose.open_external_link=Abrir
@@ -1416,14 +1544,14 @@ issues.choose.invalid_templates=%v plantilla(s) no vรกlida(s) encontradas
issues.choose.invalid_config=La configuraciรณn de la incidencia contiene errores:
issues.no_ref=Ninguna Rama/Etiqueta especificada
issues.create=Crear incidencia
-issues.new_label=Nueva Etiqueta
+issues.new_label=Nueva etiqueta
issues.new_label_placeholder=Nombre etiqueta
issues.new_label_desc_placeholder=Descripciรณn
issues.create_label=Crear etiqueta
-issues.label_templates.title=Carga un conjunto predefinido de etiquetas
-issues.label_templates.info=Todavรญa no existen etiquetas. Cree una etiqueta con "Nueva Etiqueta" o use un conjunto predefinido de etiquetas:
-issues.label_templates.helper=Seleccionar un conjunto de etiquetas
-issues.label_templates.use=Usar este conjunto de etiquetas
+issues.label_templates.title=Cargar un conjunto predefinido de etiquetas
+issues.label_templates.info=Todavรญa no existen etiquetas. Crea una etiqueta con "Nueva etiqueta" o usa un conjunto predefinido de etiquetas:
+issues.label_templates.helper=Seleccionar un conjunto predefinido de etiquetas
+issues.label_templates.use=Usar este conjunto predefinido de etiquetas
issues.label_templates.fail_to_load_file=Error al cargar el archivo de plantilla de etiqueta "%s": %v
issues.add_label=aรฑadiรณ la etiqueta %s %s
issues.add_labels=aรฑadiรณ las etiquetas %s %s
@@ -1446,12 +1574,12 @@ issues.change_title_at=`cambiรณ el tรญtulo de %s a %s
issues.change_ref_at=`cambiรณ referencia de %s a %s %s`
issues.remove_ref_at=`eliminรณ la referencia %s %s`
issues.add_ref_at=`aรฑadiรณ la referencia %s %s`
-issues.delete_branch_at=`rama eliminada %s %s`
+issues.delete_branch_at=`eliminรณ la rama %s %s`
issues.filter_label=Etiqueta
issues.filter_label_exclude=`Usa alt
+ clic/enter
para excluir etiquetas`
issues.filter_label_no_select=Todas las etiquetas
issues.filter_label_select_no_label=Sin etiqueta
-issues.filter_milestone=Milestone
+issues.filter_milestone=Hito
issues.filter_milestone_all=Todos los hitos
issues.filter_milestone_none=Sin hitos
issues.filter_milestone_open=Abrir hitos
@@ -1482,8 +1610,8 @@ issues.filter_sort.nearduedate=Fecha de vencimiento mรกs cercana
issues.filter_sort.farduedate=Fecha de vencimiento mรกs lejana
issues.filter_sort.moststars=Mas estrellas
issues.filter_sort.feweststars=Menor nรบmero de estrellas
-issues.filter_sort.mostforks=La mayorรญa de forks
-issues.filter_sort.fewestforks=Menor nรบmero de forks
+issues.filter_sort.mostforks=La mayorรญa de bifurcaciones
+issues.filter_sort.fewestforks=Menor nรบmero de bifurcaciones
issues.keyword_search_unavailable=La bรบsqueda por palabra clave no estรก disponible actualmente. Por favor, contacte con el administrador de su sitio.
issues.action_open=Abrir
issues.action_close=Cerrar
@@ -1507,28 +1635,28 @@ issues.closed_title=Cerrada
issues.draft_title=Borrador
issues.num_comments_1=%d comentario
issues.num_comments=%d comentarios
-issues.commented_at=`comentado %s `
+issues.commented_at=`comentรณ %s `
issues.delete_comment_confirm=ยฟSeguro que deseas eliminar este comentario?
issues.context.copy_link=Copiar enlace
issues.context.quote_reply=Citar respuesta
-issues.context.reference_issue=Referencia en una nueva incidencia
+issues.context.reference_issue=Referenciar en una nueva incidencia
issues.context.edit=Editar
issues.context.delete=Eliminar
issues.no_content=No se ha proporcionado una descripciรณn.
-issues.close=Cerrar Incidencia
+issues.close=Cerrar incidencia
issues.comment_pull_merged_at=commit fusionado %[1]s en %[2]s %[3]s
-issues.comment_manually_pull_merged_at=commit manualmente fusionado %[1]s en %[2]s %[3]s
-issues.close_comment_issue=Comentar y cerrar
+issues.comment_manually_pull_merged_at=commit %[1]s manualmente fusionado en %[2]s %[3]s
+issues.close_comment_issue=Cerrar con comentario
issues.reopen_issue=Reabrir
-issues.reopen_comment_issue=Comentar y reabrir
+issues.reopen_comment_issue=Reabrir con comentario
issues.create_comment=Comentar
issues.closed_at=`cerrรณ esta incidencia %[2]s `
issues.reopened_at=`reabriรณ esta incidencia %[2]s `
issues.commit_ref_at=`referenciรณ esta incidencia en un commit %[2]s `
issues.ref_issue_from=`referenciรณ esta incidencia %[4]s %[2]s `
issues.ref_pull_from=`referenciรณ este pull request %[4]s %[2]s `
-issues.ref_closing_from=`referenciรณ un pull request %[4]s que cerrarรก esta incidencia %[2]s `
-issues.ref_reopening_from=`referenciรณ un pull request %[4]s que reabrirรก esta incidencia %[2]s `
+issues.ref_closing_from=`hizo referencia a esta incidencia desde un pull request %[4]s que lo cerrarรก , %[2]s `
+issues.ref_reopening_from=`hizo referencia a esta incidencia desde un pull request %[4]s que lo reabrirรก , %[2]s `
issues.ref_closed_from=`cerrรณ esta incidencia %[4]s %[2]s `
issues.ref_reopened_from=`reabriรณ esta incidencia %[4]s %[2]s `
issues.ref_from=`de %[1]s`
@@ -1542,8 +1670,8 @@ issues.role.collaborator=Colaborador
issues.role.collaborator_helper=Este usuario ha sido invitado a colaborar en el repositorio.
issues.role.first_time_contributor=Contribuyente por primera vez
issues.role.first_time_contributor_helper=Esta es la primera contribuciรณn de este usuario al repositorio.
-issues.role.contributor=Colaborador
-issues.role.contributor_helper=Este usuario ha realizado commit previamente con el repositorio.
+issues.role.contributor=Contribuidor
+issues.role.contributor_helper=Este usuario ha realizado commit previamente en este repositorio.
issues.re_request_review=Solicitar revisiรณn de nuevo
issues.is_stale=Ha habido cambios en este PR desde esta revisiรณn
issues.remove_request_review=Eliminar solicitud de revisiรณn
@@ -1582,15 +1710,15 @@ issues.subscribe=Suscribir
issues.unsubscribe=Desuscribirse
issues.unpin_issue=Desanclar incidencia
issues.max_pinned=No puedes anclar mรกs incidencias
-issues.pin_comment=anclado este %s
-issues.unpin_comment=desanclado este %s
+issues.pin_comment=anclรณ este %s
+issues.unpin_comment=desanclรณ este %s
issues.lock=Bloquear conversaciรณn
issues.unlock=Desbloquear conversaciรณn
issues.lock.unknown_reason=No se puede bloquear una incidencia con una razรณn desconocida.
issues.lock_duplicate=Una incidencia no puede ser bloqueada dos veces.
issues.unlock_error=No puede desbloquear una incidencia que no esta bloqueada.
-issues.lock_with_reason=bloqueado como %s y conversaciรณn limitada a colaboradores %s
-issues.lock_no_reason=conversaciรณn limitada y bloqueada a los colaboradores %s
+issues.lock_with_reason=bloqueรณ como %s y limitรณ la conversaciรณn a colaboradores %s
+issues.lock_no_reason=bloqueรณ y limitรณ la conversaciรณn a los colaboradores %s
issues.unlock_comment=desbloqueรณ esta conversaciรณn %s
issues.lock_confirm=Bloquear
issues.unlock_confirm=Desbloquear
@@ -1608,7 +1736,7 @@ issues.delete.title=ยฟEliminar esta incidencia?
issues.delete.text=ยฟRealmente quieres eliminar esta incidencia? (Esto eliminarรก permanentemente todo el contenido. Considera cerrarlo en su lugar, si quieres mantenerlo archivado)
issues.tracker=Gestor de tiempo
issues.start_tracking_short=Iniciar temporizador
-issues.start_tracking=Inicio de seguimiento de tiempo
+issues.start_tracking=Iniciar seguimiento de tiempo
issues.start_tracking_history=`ha empezado a trabajar %s`
issues.tracker_auto_close=El temporizador se detendrรก automรกticamente cuando se cierre este problema
issues.tracking_already_started=`ยกYa has iniciado el seguimiento de tiempo en otro problema !`
@@ -1627,25 +1755,25 @@ issues.add_time_minutes=Minutos
issues.add_time_sum_to_small=No se ha entrado tiempo.
issues.time_spent_total=Tiempo total gastado
issues.time_spent_from_all_authors=`Tiempo total gastado: %s`
-issues.due_date=Fecha de vencimiento
+issues.due_date=Fecha lรญmite
issues.invalid_due_date_format=El formato de la fecha de vencimiento debe ser 'aaaa-mm-dd'.
issues.error_modifying_due_date=Fallo al modificar la fecha de vencimiento.
issues.error_removing_due_date=Fallo al eliminar la fecha de vencimiento.
-issues.push_commit_1=aรฑadido %d commit %s
-issues.push_commits_n=aรฑadido %d commits %s
-issues.force_push_codes=`hizo push forzado %[1]s de %[2]s
a %[4]s
%[6]s`
+issues.push_commit_1=aรฑadiรณ %d commit %s
+issues.push_commits_n=aรฑadiรณ %d commits %s
+issues.force_push_codes=`empujรณ forzosamente %[1]s de %[2]s
a %[4]s
%[6]s`
issues.force_push_compare=Comparar
issues.due_date_form=aaaa-mm-dd
issues.due_date_form_add=Aรฑadir fecha de vencimiento
issues.due_date_form_edit=Editar
issues.due_date_form_remove=Eliminar
-issues.due_date_not_writer=Necesita acceso de escritura a este repositorio para actualizar la fecha lรญmite de de una incidencia.
-issues.due_date_not_set=Sin fecha de vencimiento.
-issues.due_date_added=aรฑadiรณ la fecha de vencimiento %s %s
-issues.due_date_modified=modificรณ la fecha de vencimiento de %[2]s a %[1]s %[3]s
-issues.due_date_remove=eliminรณ la fecha de vencimiento %s %s
-issues.due_date_overdue=Vencido
-issues.due_date_invalid=La fecha de vencimiento es invรกlida o estรก fuera de rango. Por favor utilice el formato 'aaaa-mm-dd'.
+issues.due_date_not_writer=Necesitas acceso de escritura a este repositorio para actualizar la fecha lรญmite de una incidencia.
+issues.due_date_not_set=Fecha lรญmite no definida.
+issues.due_date_added=aรฑadiรณ la fecha lรญmite %s %s
+issues.due_date_modified=modificรณ la fecha lรญmite de %[2]s a %[1]s %[3]s
+issues.due_date_remove=eliminรณ la fecha lรญmite %s %s
+issues.due_date_overdue=Atrasado
+issues.due_date_invalid=La fecha lรญmite es invรกlida o estรก fuera de rango. Por favor utiliza el formato "aaaa-mm-dd".
issues.dependency.title=Dependencias
issues.dependency.issue_no_dependencies=No se han establecido dependencias.
issues.dependency.pr_no_dependencies=No se han establecido dependencias.
@@ -1663,7 +1791,7 @@ issues.dependency.issue_closing_blockedby=Cerrando esta incidencia esta bloquead
issues.dependency.issue_close_blocks=Esta incidencia bloquea el cierre de las siguientes incidencias
issues.dependency.pr_close_blocks=Este pull request bloquea el cierre de las siguientes incidencias
issues.dependency.issue_close_blocked=Necesita cerrar todos las incidencias que bloquean esta incidencia antes de que se puede cerrar.
-issues.dependency.issue_batch_close_blocked=No se pueden cerrar por lotes las incidencias que has seleccionado, ya que la incidencia #%d todavรญa tiene dependencias abiertas
+issues.dependency.issue_batch_close_blocked=No se pueden cerrar por lote las incidencias que has seleccionado, ya que la incidencia #%d todavรญa tiene dependencias abiertas
issues.dependency.pr_close_blocked=Necesita cerrar todos las incidencias que bloquean este pull request antes de poder fusionarse.
issues.dependency.blocks_short=Bloquea
issues.dependency.blocked_by_short=Depende de
@@ -1679,17 +1807,17 @@ issues.dependency.add_error_cannot_create_circular=No puede crear una depenciena
issues.dependency.add_error_dep_not_same_repo=Ambas incidencias deben estar en el mismo repositorio.
issues.review.self.approval=No puede aprobar su propio pull request.
issues.review.self.rejection=No puede sugerir cambios en su propio pull request.
-issues.review.approve=aprobado estos cambios %s
-issues.review.comment=revisado %s
+issues.review.approve=aprobรณ estos cambios %s
+issues.review.comment=revisรณ %s
issues.review.dismissed=descartรณ la revisiรณn de %s %s
issues.review.dismissed_label=Descartado
issues.review.left_comment=dejรณ un comentario
issues.review.content.empty=Es necesario dejar un comentario indicando los cambios solicitados.
issues.review.reject=cambios solicitados %s
-issues.review.wait=se solicitรณ para revisiรณn %s
-issues.review.add_review_request=solicitud de revisiรณn de %s %s
-issues.review.remove_review_request=solicitud de revisiรณn eliminada para %s %s
-issues.review.remove_review_request_self=rechazรณ revisar %s
+issues.review.wait=fue solicitado para revisiรณn %s
+issues.review.add_review_request=solicitรณ revisiรณn de %[1]s %[2]s
+issues.review.remove_review_request=eliminรณ la solicitud de revisiรณn para %[1]s %[2]s
+issues.review.remove_review_request_self=se negรณ a revisar %s
issues.review.pending=Pendiente
issues.review.pending.tooltip=Este comentario no es visible actualmente para otros usuarios. Para enviar sus comentarios pendientes, seleccione "%s" -> "%s/%s/%s" en la parte superior de la pรกgina.
issues.review.review=Revisar
@@ -1719,8 +1847,8 @@ compare.compare_base=base
compare.compare_head=comparar
pulls.desc=Activar Pull Requests y revisiones de cรณdigo.
-pulls.new=Nuevo Pull Request
-pulls.view=Ver Pull Request
+pulls.new=Nuevo pull request
+pulls.view=Ver pull request
pulls.compare_changes=Nuevo pull request
pulls.allow_edits_from_maintainers=Permitir ediciones de mantenedores
pulls.allow_edits_from_maintainers_desc=Los usuarios con acceso de escritura a la rama base tambiรฉn pueden hacer push a esta rama
@@ -1747,12 +1875,12 @@ pulls.filter_changes_by_commit=Filtrar por commit
pulls.nothing_to_compare=Estas ramas son iguales. No hay necesidad para crear un pull request.
pulls.nothing_to_compare_and_allow_empty_pr=Estas ramas son iguales. Este PR estarรก vacรญo.
pulls.has_pull_request=`Ya existe un pull request entre estas ramas: %[2]s#%[3]d `
-pulls.create=Crear Pull Request
-pulls.title_desc_few=desea fusionar %[1]d commits de %[2]s
en %[3]s
-pulls.merged_title_desc_few=fusionados %[1]d commits de %[2]s
en %[3]s
%[4]s
+pulls.create=Crear pull request
+pulls.title_desc_few=quiere fusionar %[1]d commits de %[2]s
en %[3]s
+pulls.merged_title_desc_few=fusionรณ %[1]d commits de %[2]s
en %[3]s
%[4]s
pulls.change_target_branch_at=`cambiรณ la rama objetivo de %s a %s %s`
pulls.tab_conversation=Conversaciรณn
-pulls.tab_commits=Commits
+pulls.tab_commits=Confirmaciones
pulls.tab_files=Archivos modificados
pulls.reopen_to_merge=Vuelva a abrir este Pull Request para realizar una fusiรณn.
pulls.cant_reopen_deleted_branch=Este pull request no se puede reabrir porque la rama fue eliminada.
@@ -1769,15 +1897,15 @@ pulls.add_prefix=Aรฑadir prefijo %s
pulls.remove_prefix=Eliminar prefijo %s
pulls.data_broken=Este pull request estรก rota debido a que falta informaciรณn del fork.
pulls.files_conflicted=Este pull request tiene cambios en conflicto con la rama de destino.
-pulls.is_checking=La comprobaciรณn de conflicto de fusiรณn estรก en progreso. Intรฉntalo de nuevo en unos momentos.
+pulls.is_checking=La comprobaciรณn de conflicto de fusiรณn estรก en progreso. Intรฉntelo de nuevo en unos momentos.
pulls.is_ancestor=Esta rama ya estรก incluida en la rama de destino. No hay nada que fusionar.
pulls.is_empty=Los cambios en esta rama ya estรกn en la rama de destino. Esto serรก un commit vacรญo.
pulls.required_status_check_failed=Algunos controles requeridos no han tenido รฉxito.
pulls.required_status_check_missing=Faltan algunos controles necesarios.
pulls.required_status_check_administrator=Como administrador, aรบn puede fusionar este Pull Request.
-pulls.blocked_by_approvals=Esta pull request aรบn no tiene suficientes aprobaciones. %d de %d aprobaciones concedidas.
+pulls.blocked_by_approvals=Esta pull request aรบn no tiene aprobaciones suficientes. %d de %d aprobaciones concedidas.
pulls.blocked_by_rejection=Este pull request tiene cambios solicitados por un revisor oficial.
-pulls.blocked_by_official_review_requests=Esta pull request tiene solicitudes de revisiรณn oficiales.
+pulls.blocked_by_official_review_requests=Esta pull request estรก bloqueada porque le falta la aprobaciรณn de uno o mรกs revisores oficiales.
pulls.blocked_by_outdated_branch=Esta pull request estรก bloqueada porque estรก desactualizada.
pulls.blocked_by_changed_protected_files_1=Esta pull request estรก bloqueada porque cambia un archivo protegido:
pulls.blocked_by_changed_protected_files_n=Esta pull request estรก bloqueada porque cambia archivos protegidos:
@@ -1790,9 +1918,9 @@ pulls.approve_count_1=%d aprobaciรณn
pulls.approve_count_n=%d aprobaciones
pulls.reject_count_1=%d solicitud de cambio
pulls.reject_count_n=%d solicitudes de cambio
-pulls.waiting_count_1=%d esperando revisiรณn
-pulls.waiting_count_n=%d esperando revisiรณnes
-pulls.wrong_commit_id=la identificaciรณn de commit debe ser para un commit en la rama de destino
+pulls.waiting_count_1=%d revisiรณn pendiente
+pulls.waiting_count_n=%d revisiรณnes pendientes
+pulls.wrong_commit_id=la identificaciรณn del commit debe ser para un commit en la rama de destino
pulls.no_merge_desc=Este pull request no se puede combinar porque todas las opciones de combinaciรณn del repositorio estรกn deshabilitadas.
pulls.no_merge_helper=Habilite las opciones de combinaciรณn en la configuraciรณn del repositorio o fusione el pull request manualmente.
@@ -1808,17 +1936,17 @@ pulls.merge_commit_id=La identificaciรณn del commit fusionado
pulls.require_signed_wont_sign=Esta rama requiere commits firmados pero esta fusiรณn no serรก firmada
pulls.invalid_merge_option=No puede utilizar esta opciรณn de combinaciรณn para esta solicitud de extracciรณn.
-pulls.merge_conflict=Fusiรณn fallida: Hubo un conflicto mientras se fusionaba. Pista: Pruebe una estrategia diferente
+pulls.merge_conflict=Fusiรณn fallida: Hubo un conflicto durante la fusiรณn. Sugerencia: Prueba una estrategia diferente
pulls.merge_conflict_summary=Mensaje de error
-pulls.rebase_conflict=Fusiรณn fallida: Hubo un conflicto mientras se rebasaba el commit: %[1]s. Pista: Prueba una estrategia diferente
+pulls.rebase_conflict=Fusiรณn fallida: Hubo un conflicto al rebasar el commit: %[1]s. Sugerencia: Prueba una estrategia diferente
pulls.rebase_conflict_summary=Mensaje de error
-pulls.unrelated_histories=Fusionar Fallidos: El jefe de fusiรณn y la base no comparten un historial comรบn. Pista: Prueba una estrategia diferente
-pulls.merge_out_of_date=Fusiรณn fallida: Mientras se generaba la fusiรณn, la base fue actualizada. Pista: Intรฉntelo de nuevo.
-pulls.head_out_of_date=Fusiรณn fallida: Mientras se generaba la fusiรณn, la cabeza fue actualizada. Pista: Intรฉntelo de nuevo.
+pulls.unrelated_histories=Fusiรณn fallida: La cabeza de fusiรณn y la base no tienen un historial comรบn. Sugerencia: Prueba una estrategia diferente
+pulls.merge_out_of_date=Fusiรณn fallida: Mientras se generaba la fusiรณn, la base fue actualizada. Sugerencia: Intรฉntalo de nuevo.
+pulls.head_out_of_date=Fusiรณn fallida: Mientras se generaba la fusiรณn, la cabeza fue actualizada. Sugerencia: Intรฉntalo de nuevo.
pulls.has_merged=Error: La pull request ha sido fusionada, no puedes fusionarla de nuevo ni cambiar la rama objetivo.
-pulls.push_rejected=Fusiรณn fallida: El push fue rechazado. Revise los Git Hooks para este repositorio.
+pulls.push_rejected=Fusiรณn fallida: El push fue rechazado. Revisa los Git Hooks para este repositorio.
pulls.push_rejected_summary=Mensaje completo de rechazo
-pulls.push_rejected_no_message=Fusiรณn fallida: El push fue rechazado pero no hubo mensaje remoto. Revise los Git Hooks para este repositorio
+pulls.push_rejected_no_message=Push fallida: El push fue rechazado pero no hubo mensaje remoto. Revisa los Git Hooks para este repositorio
pulls.open_unmerged_pull_exists=`No puede realizar la reapertura porque hay un pull request pendiente (#%d) con propiedades idรฉnticas.`
pulls.status_checking=Algunas comprobaciones estรกn pendientes
pulls.status_checks_success=Todas las comprobaciones han sido exitosas
@@ -1832,7 +1960,7 @@ pulls.update_branch_rebase=Actualizar rama por cambio de base
pulls.update_branch_success=La actualizaciรณn de la rama ha finalizado correctamente
pulls.update_not_allowed=No tiene permisos para actualizar esta rama
pulls.outdated_with_base_branch=Esta rama estรก desactualizada con la rama base
-pulls.close=Cerrar Pull Request
+pulls.close=Cerrar pull request
pulls.closed_at=`cerrรณ este pull request %[2]s `
pulls.reopened_at=`reabriรณ este pull request %[2]s `
pulls.clear_merge_message=Borrar mensaje de fusiรณn
@@ -1853,7 +1981,7 @@ pulls.auto_merge_canceled_schedule_comment=`cancelรณ la fusiรณn automรกtica de e
pulls.delete.title=ยฟBorrar este pull request?
pulls.delete.text=ยฟRealmente quieres eliminar esta pull request? (Esto eliminarรก permanentemente todo el contenido. Considera cerrarlo si simplemente deseas archivarlo)
-pulls.recently_pushed_new_branches=Has realizado push en la rama %[1]s %[2]s
+pulls.recently_pushed_new_branches=Empujaste en la rama %[1]s %[2]s
pull.deleted_branch=(eliminado):%s
@@ -1864,15 +1992,15 @@ milestones.no_due_date=Sin fecha lรญmite
milestones.open=Abrir
milestones.close=Cerrar
milestones.new_subheader=Los hitos pueden ayudarle a organizar los problemas y monitorizar su progreso.
-milestones.completeness=%d%% Completado
+milestones.completeness=%d%% Completado
milestones.create=Crear hito
milestones.title=Tรญtulo
milestones.desc=Descripciรณn
milestones.due_date=Fecha lรญmite (opcional)
milestones.clear=Limpiar
-milestones.invalid_due_date_format=El formato de fecha de vencimiento debe ser 'AAAA-mm-dd'.
+milestones.invalid_due_date_format=El formato de fecha lรญmite debe ser "aaaa-mm-dd".
milestones.create_success=Se ha creado el hito "%s".
-milestones.edit=Editar Milestone
+milestones.edit=Editar hito
milestones.edit_subheader=Los hitos organizan los problemas y siguen el progreso.
milestones.cancel=Cancelar
milestones.modify=Actualizar hito
@@ -1880,8 +2008,8 @@ milestones.edit_success=Se ha actualizado el hito "%s".
milestones.deletion=Eliminar hito
milestones.deletion_desc=Eliminando un hito lo elimina de todos los problemas relacionados. ยฟContinuar?
milestones.deletion_success=El hito se ha eliminado.
-milestones.filter_sort.earliest_due_data=Fecha de vencimiento mรกs temprana
-milestones.filter_sort.latest_due_date=Fecha de vencimiento mรกs lejana
+milestones.filter_sort.earliest_due_data=Fecha lรญmite mรกs prรณxima
+milestones.filter_sort.latest_due_date=Fecha lรญmite mรกs lejana
milestones.filter_sort.least_complete=Menos completa
milestones.filter_sort.most_complete=Mรกs completa
milestones.filter_sort.most_issues=Mayorรญa de los problemas
@@ -1889,7 +2017,7 @@ milestones.filter_sort.least_issues=Menos problemas
signing.will_sign=Este commit se firmarรก con la clave "%s".
signing.wont_sign.error=Hubo un error mientras se comprobaba si la confirmaciรณn podรญa ser firmada.
-signing.wont_sign.nokey=No hay ninguna clave disponible para firmar este commit.
+signing.wont_sign.nokey=Esta instancia no tiene ninguna clave con la que firmar este commit.
signing.wont_sign.never=Nunca se firman los commits.
signing.wont_sign.always=Siempre se firman los commits.
signing.wont_sign.pubkey=El commit no se firmarรก porque no tiene una clave pรบblica asociada a su cuenta.
@@ -1901,11 +2029,11 @@ signing.wont_sign.commitssigned=La fusiรณn no se firmarรก ya que todos los commi
signing.wont_sign.approved=La fusiรณn no se firmarรก ya que el PR no estรก aprobado.
signing.wont_sign.not_signed_in=No ha iniciado sesiรณn.
-ext_wiki=Acceso a la wiki externa
+ext_wiki=Wiki externa
ext_wiki.desc=Enlace a una wiki externa.
wiki=Wiki
-wiki.welcome=ยกBienvenidos a la Wiki!
+wiki.welcome=Bienvenido a la Wiki.
wiki.welcome_desc=Esta wiki le permite escribir y compartir documentaciรณn con otros colaboradores.
wiki.desc=Escriba y comparta documentaciรณn con colaboradores.
wiki.create_first_page=Crear la primera pรกgina
@@ -1920,7 +2048,7 @@ wiki.last_commit_info=%s editรณ esta pรกgina %s
wiki.edit_page_button=Editar
wiki.new_page_button=Nueva pรกgina
wiki.file_revision=Revisiรณn de pรกgina
-wiki.wiki_page_revisions=Revisiones de la pรกgina Wiki
+wiki.wiki_page_revisions=Revisiones de la pรกgina
wiki.back_to_wiki=Volver a la pรกgina wiki
wiki.delete_page_button=Eliminar pรกgina
wiki.delete_page_notice_1=Eliminar la pรกgina wiki "%s" no se puede deshacer. ยฟContinuar?
@@ -1928,7 +2056,7 @@ wiki.page_already_exists=Ya existe una pรกgina con el mismo nombre.
wiki.reserved_page=El nombre de la pรกgina wiki "%s" estรก reservado.
wiki.pages=Pรกginas
wiki.last_updated=รltima actualizaciรณn %s
-wiki.page_name_desc=Introduzca un nombre para esta pรกgina de Wiki. Algunos nombres especiales son: 'Home', '_Sidebar' y '_Footer'.
+wiki.page_name_desc=Introduce un nombre para esta pรกgina de Wiki. Algunos nombres especiales son: "Home", "_Sidebar" y "_Footer".
wiki.original_git_entry_tooltip=Ver el archivo Git original en vez de usar el enlace amigable.
activity=Actividad
@@ -1941,40 +2069,40 @@ activity.period.quarterly=3 meses
activity.period.semiyearly=6 meses
activity.period.yearly=1 aรฑo
activity.overview=Resumen
-activity.active_prs_count_1=%d Solicitud de extracciรณn Activa
-activity.active_prs_count_n=%d Solicitudes "pull" activas
-activity.merged_prs_count_1=Solicitud de extracciรณn combinada
-activity.merged_prs_count_n=Pull Requests Fusionados
-activity.opened_prs_count_1=Pull Request Propuesta
-activity.opened_prs_count_n=Pull Requests Propuestas
+activity.active_prs_count_1=%d pull request activa
+activity.active_prs_count_n=%d pull requests activas
+activity.merged_prs_count_1=Pull request fusionado
+activity.merged_prs_count_n=Pull requests fusionados
+activity.opened_prs_count_1=Pull request propuesta
+activity.opened_prs_count_n=Pull requests propuestas
activity.title.user_1=%d usuario
activity.title.user_n=%d usuarios
-activity.title.prs_1=%d Pull request
-activity.title.prs_n=%d Pull requests
+activity.title.prs_1=%d solicitud de incorporaciรณn de cambios
+activity.title.prs_n=%d solicitudes de incorporaciรณn de cambios
activity.title.prs_merged_by=%s fusionado por %s
activity.title.prs_opened_by=%s propuesto por %s
activity.merged_prs_label=Fusionado
activity.opened_prs_label=Propuesto
-activity.active_issues_count_1=%d Incidencia activa
-activity.active_issues_count_n=%d Incidencias activas
+activity.active_issues_count_1=%d incidencia activa
+activity.active_issues_count_n=%d incidencias activas
activity.closed_issues_count_1=Incidencia cerrada
activity.closed_issues_count_n=Incidencias cerradas
-activity.title.issues_1=%d Incidencia
+activity.title.issues_1=%d incidencia
activity.title.issues_n=%d incidencias
activity.title.issues_closed_from=%s cerrado de %s
activity.title.issues_created_by=%s creada por %s
activity.closed_issue_label=Cerrada
-activity.new_issues_count_1=Nueva incidencia
-activity.new_issues_count_n=Nuevas incidencias
+activity.new_issues_count_1=Incidencia nueva
+activity.new_issues_count_n=Incidencias nuevas
activity.new_issue_label=Abierta
-activity.title.unresolved_conv_1=%d Conversaciรณn no resuelta
+activity.title.unresolved_conv_1=%d conversaciรณn sin resolver
activity.title.unresolved_conv_n=%d conversaciones sin resolver
activity.unresolved_conv_desc=Estas incidencias y pull requests que han cambiado recientemente todavรญa no han sido resueltos.
activity.unresolved_conv_label=Abierta
-activity.title.releases_1=%d Lanzamiento
-activity.title.releases_n=%d Lanzamientos
+activity.title.releases_1=%d lanzamiento
+activity.title.releases_n=%d lanzamientos
activity.title.releases_published_by=%s publicado por %s
-activity.published_release_label=Publicado
+activity.published_release_label=Lanzamiento
activity.no_git_activity=No ha habido ningรบn commit en este perรญodo.
activity.git_stats_exclude_merges=Excluyendo fusiones,
activity.git_stats_author_1=%d autor
@@ -1982,7 +2110,7 @@ activity.git_stats_author_n=%d autores
activity.git_stats_pushed_1=ha hecho push
activity.git_stats_pushed_n=han hecho push
activity.git_stats_commit_1=%d commit
-activity.git_stats_commit_n=%d commits
+activity.git_stats_commit_n=%d confirmaciones
activity.git_stats_push_to_branch=a %s y
activity.git_stats_push_to_all_branches=en todas las ramas.
activity.git_stats_on_default_branch=En %s,
@@ -1997,7 +2125,7 @@ activity.git_stats_and_deletions=y
activity.git_stats_deletion_1=%d eliminaciรณn
activity.git_stats_deletion_n=%d eliminaciones
-contributors.contribution_type.commits=Commits
+contributors.contribution_type.commits=Confirmaciones
search=Buscar
search.search_repo=Buscar repositorio
@@ -2020,8 +2148,8 @@ settings.collaboration.read=Lectura
settings.collaboration.owner=Propietario
settings.collaboration.undefined=Indefinido
settings.hooks=Webhooks
-settings.githooks=Git Hooks
-settings.basic_settings=Configuraciรณn Bรกsica
+settings.githooks=Git hooks
+settings.basic_settings=Ajustes bรกsicas
settings.mirror_settings=Configuraciรณn de rรฉplica
settings.mirror_settings.docs=Configure su repositorio para sincronizar automรกticamente commits, etiquetas y ramas con otro repositorio.
settings.mirror_settings.docs.disabled_pull_mirror.instructions=Configure su proyecto para enviar automรกticamente commits, etiquetas y ramas a otro repositorio. Las rรฉplicas han sido deshabilitadas por el administrador del sitio.
@@ -2042,26 +2170,26 @@ settings.mirror_settings.direction.push=Push
settings.mirror_settings.last_update=รltima actualizaciรณn
settings.mirror_settings.push_mirror.none=No hay Rรฉplicas de Push configurados
settings.mirror_settings.push_mirror.remote_url=URL del repositorio remoto de Git
-settings.mirror_settings.push_mirror.add=Aรฑadir Rรฉplica de Push
+settings.mirror_settings.push_mirror.add=Aรฑadir rรฉplica de push
settings.mirror_settings.push_mirror.edit_sync_time=Editar intervalo de sincronizaciรณn de rรฉplica
settings.sync_mirror=Sincronizar ahora
settings.pull_mirror_sync_in_progress=Haciendo pull de los cambios desde el repositorio remoto %s ahora mismo.
settings.push_mirror_sync_in_progress=Haciendo push de los cambios en el repositorio remoto %s ahora mismo.
settings.site=Sitio web
-settings.update_settings=Actualizar configuraciรณn
+settings.update_settings=Guardar configuraciรณn
settings.update_mirror_settings=Actualizar ajustes de rรฉplica
settings.branches.switch_default_branch=Cambiar rama por defecto
settings.branches.update_default_branch=Actualizar rama por defecto
settings.branches.add_new_rule=Aรฑadir nueva regla
-settings.advanced_settings=Ajustes avanzados
-settings.wiki_desc=Activar Wiki de repositorio
-settings.use_internal_wiki=Usar Wiki integrada
-settings.use_external_wiki=Usar Wiki externa
-settings.external_wiki_url=URL externa de la Wiki
+settings.advanced_settings=Configuraciรณn avanzada
+settings.wiki_desc=Activar wiki del repositorio
+settings.use_internal_wiki=Usar wiki integrada
+settings.use_external_wiki=Usar wiki externa
+settings.external_wiki_url=URL del wiki externo
settings.external_wiki_url_error=La URL de la Wiki externa no es una URL vรกlida.
settings.external_wiki_url_desc=Los visitantes serรกn redirigidos a la URL de la Wiki externa al hacer click en la pestaรฑa de la Wiki.
-settings.issues_desc=Activar gestor de incidencias para este repositorio
+settings.issues_desc=Habilitar gestor de incidencias
settings.use_internal_issue_tracker=Usar gestor de incidencias integrado
settings.use_external_issue_tracker=Usar gestor de incidencias externo
settings.external_tracker_url=URL del gestor de incidencias externo
@@ -2077,27 +2205,27 @@ settings.tracker_issue_style.regexp_pattern=Pauta de expresiones regulares
settings.tracker_issue_style.regexp_pattern_desc=Se utilizarรก el primer grupo capturado en lugar de {index}
.
settings.tracker_url_format_desc=Utilice los marcadores {user}
, {repo}
y {index}
para designar el usuario, el nombre del repositorio y el รญndice de incidencia.
settings.enable_timetracker=Habilitar gestor de tiempo
-settings.allow_only_contributors_to_track_time=Deje que solo los colaboradores hagan un seguimiento del tiempo
-settings.pulls_desc=Activar Pull Requests para este repositorio
+settings.allow_only_contributors_to_track_time=Dejar que solo los colaboradores puedan hacer seguimiento del tiempo
+settings.pulls_desc=Activar pull requests para este repositorio
settings.pulls.ignore_whitespace=Ignorar espacios en blanco en conflictos
settings.pulls.enable_autodetect_manual_merge=Habilitar la autodetecciรณn de los commits fusionado manualmente (Nota: en algunos casos especiales, pueden producirse errores de apreciaciรณn)
settings.pulls.allow_rebase_update=Habilitar la actualizaciรณn de la rama de Pull Request por rebase
settings.pulls.default_delete_branch_after_merge=Eliminar por defecto la rama de pull request despuรฉs de fusionar
settings.pulls.default_allow_edits_from_maintainers=Permitir ediciones de mantenedores por defecto
-settings.releases_desc=Activar lanzamientos del repositorio
-settings.packages_desc=Habilitar registro de paquetes de repositorio
-settings.projects_desc=Activar Proyectos de Repositorio
-settings.actions_desc=Activar Acciones del repositorio
-settings.admin_settings=Ajustes de administrador
+settings.releases_desc=Activar lanzamientos en el repositorio
+settings.packages_desc=Habilitar registro de paquetes en el repositorio
+settings.projects_desc=Activar proyectos en el repositorio
+settings.actions_desc=Habilite procesos CI/CD integrados con Forgejo Actions
+settings.admin_settings=Configuraciรณn administrativa
settings.admin_enable_health_check=Activar cheques de estado de salud del repositorio (git fsck)
settings.admin_code_indexer=Indexador de cรณdigo
settings.admin_stats_indexer=Indexador de estadรญsticas de cรณdigo
-settings.admin_indexer_commit_sha=รltimo SHA indexado
+settings.admin_indexer_commit_sha=รltimo commit indexado
settings.admin_indexer_unindexed=Sin indexar
settings.reindex_button=Aรฑadir a la cola de reindexaciรณn
-settings.reindex_requested=Reindexar Solicitado
+settings.reindex_requested=Reindexaciรณn solicitada
settings.admin_enable_close_issues_via_commit_in_any_branch=Cerrar una incidencia a travรฉs de un commit realizado en una rama no principal
-settings.danger_zone=Zona de Peligro
+settings.danger_zone=Zona de peligro
settings.new_owner_has_same_repo=El nuevo propietario tiene un repositorio con el mismo nombre.
settings.convert=Convertir en repositorio normal
settings.convert_desc=Puede convertir este respositorio replicado en un repositorio normal. Esta acciรณn no se puede revertir.
@@ -2121,27 +2249,27 @@ settings.transfer_in_progress=Actualmente hay una transferencia en curso. Por fa
settings.transfer_notices_1=- Perderรก el acceso al repositorio si lo transfiere a un usuario individual.
settings.transfer_notices_2=- Mantendrรก el acceso al repositorio si lo transfiere a una organizaciรณn que usted (co-)posee.
settings.transfer_notices_3=- Si el repositorio es privado y se transfiere a un usuario individual, esta acciรณn se asegura de que el usuario tenga al menos permisos de lectura (y cambie los permisos si es necesario).
-settings.transfer_owner=Nuevo Propietario
+settings.transfer_owner=Nuevo propietario
settings.transfer_perform=Realizar transferencia
settings.transfer_started=`Este repositorio ha sido marcado para transferencia y espera confirmaciรณn de "%s"`
settings.transfer_succeed=El repositorio ha sido transferido.
-settings.signing_settings=Configuraciรณn de verificaciรณn de firmas
-settings.trust_model=Modelo de confianza de firma
+settings.signing_settings=Ajustes de verificaciรณn de firmas
+settings.trust_model=Modelo de confianza de firmas
settings.trust_model.default=Modelo de confianza por defecto
settings.trust_model.default.desc=Utilice el modelo de confianza de repositorio por defecto para esta instalaciรณn.
settings.trust_model.collaborator=Colaborador
settings.trust_model.collaborator.long=Colaborador: Confiar en firmas de colaboradores
settings.trust_model.collaborator.desc=Las firmas vรกlidas de los colaboradores de este repositorio serรกn marcadas como "confiables" - (coincidan o no con el committer). De lo contrario, las firmas vรกlidas serรกn marcadas como "no confiables" si la firma coincide con el committer y "no coincidente" si no lo es.
-settings.trust_model.committer=Committer
+settings.trust_model.committer=Confirmador
settings.trust_model.committer.long=Committer: Firmas de confianza que coinciden con los committers (Esto coincide con GitHub y obligarรก a Forgejo a firmar los commits a tener a Forgejo como el committer)
settings.trust_model.committer.desc=Las firmas vรกlidas sรณlo se marcarรกn como "confiables" si coinciden con el committer, de lo contrario se marcarรกn como "no confiable". Esto obliga a Forgejo a ser el committer en commits firmados con el commit real marcado como Co-autorizado por: y Co-commited por: en el trรกiler. La clave de Forgejo por defecto debe coincidir con un usuario en la base de datos.
settings.trust_model.collaboratorcommitter=Colaborador+Comitter
settings.trust_model.collaboratorcommitter.long=Colaborador+Comitter: Confiar en firmas de colaboradores que coincidan con el committer
settings.trust_model.collaboratorcommitter.desc=Las firmas vรกlidas de los colaboradores de este repositorio se marcarรกn como "de confianza" si coinciden con el confirmador. De lo contrario, las firmas vรกlidas se marcarรกn como "no confiables" si la firma coincide con el autor de la confirmaciรณn y como "no coincidentes" en caso contrario. Esto obligarรก a Forgejo a ser marcado como el confirmador en los compromisos firmados con el confirmador real marcado como Coautor por: y Cocommitido por: trรกiler en el compromiso. La clave Forgejo predeterminada debe coincidir con un usuario en la base de datos.
-settings.wiki_delete=Eliminar datos de Wiki
+settings.wiki_delete=Eliminar datos del wiki
settings.wiki_delete_desc=Eliminar los datos del wiki del repositorio es permanente y no se puede deshacer.
settings.wiki_delete_notices_1=- Esto eliminarรก y desactivarรก permanentemente el wiki del repositorio para %s.
-settings.confirm_wiki_delete=Eliminar los datos del Wiki
+settings.confirm_wiki_delete=Eliminar los datos del wiki
settings.wiki_deletion_success=La wiki del repositorio ha sido eliminada.
settings.delete=Eliminar este repositorio
settings.delete_desc=Eliminar un repositorio es permanente y no se puede deshacer.
@@ -2173,10 +2301,10 @@ settings.search_team=Buscar equiposโฆ
settings.change_team_permission_tip=El permiso del equipo estรก establecido en la pรกgina de configuraciรณn del equipo y no puede ser cambiado por repositorio
settings.delete_team_tip=Este equipo tiene acceso a todos los repositorios y no puede ser eliminado
settings.remove_team_success=Se ha eliminado el acceso del equipo al repositorio.
-settings.add_webhook=Aรฑadir Webhook
+settings.add_webhook=Aรฑadir webhook
settings.add_webhook.invalid_channel_name=El nombre del canal Webhook no puede estar vacรญo y no puede contener sรณlo un # carรกcter.
settings.hooks_desc=Los webhooks automรกticamente hacen peticiones HTTP POST a un servidor cuando ciertos eventos de Forgejo se activan. Lee mรกs en la guรญa de webhooks .
-settings.webhook_deletion=Eliminar Webhook
+settings.webhook_deletion=Eliminar webhook
settings.webhook_deletion_desc=Eliminar un webhook borra sus ajustes e historial de entrega. ยฟContinuar?
settings.webhook_deletion_success=El webhook ha sido eliminado.
settings.webhook.test_delivery=Test de entrega
@@ -2190,12 +2318,12 @@ settings.webhook.body=Cuerpo del mensaje
settings.webhook.replay.description=Reproducir este webhook.
settings.webhook.replay.description_disabled=Para volver a reproducir este webhook, actรญvalo.
settings.webhook.delivery.success=Se ha aรฑadido un evento a la cola. Puede tardar unos segundos antes de que se muestre en el historial de entrega.
-settings.githooks_desc=Los Hooks de Git son ejecutados por el propio Git. Puede editar los archivos de hooks a continuaciรณn para configurar operaciones personalizadas.
+settings.githooks_desc=Los hooks de Git son ejecutados por el propio Git. Puedes editar los archivos de hooks a continuaciรณn para configurar operaciones personalizadas.
settings.githook_edit_desc=Si el hook no estรก activo, se mostrarรก contenido de ejemplo. Dejar el contenido vacรญo deshabilitarรก este hook.
-settings.githook_name=Nombre del Hook
-settings.githook_content=Contenido del Hook
-settings.update_githook=Actualizar Hook
-settings.add_webhook_desc=Forgejo enviarรก solicitudes POST
con un tipo de contenido especificado a la URL de destino. Leer mรกs en la guรญa webhooks .
+settings.githook_name=Nombre del hook
+settings.githook_content=Contenido del hook
+settings.update_githook=Actualizar hook
+settings.add_webhook_desc=Forgejo enviarรก solicitudes POST
con un tipo de contenido especificado a la URL de destino. Lee mรกs en la guรญa sobre webhooks .
settings.payload_url=Url destino
settings.http_method=Mรฉtodo HTTP
settings.content_type=Tipo de contenido POST
@@ -2205,16 +2333,16 @@ settings.slack_icon_url=URL de icono
settings.slack_color=Color
settings.discord_username=Usuario
settings.discord_icon_url=URL de icono
-settings.event_desc=Activar:
-settings.event_push_only=Eventos Push
+settings.event_desc=Activar en:
+settings.event_push_only=Eventos push
settings.event_send_everything=Todos los eventos
settings.event_choose=Eventos personalizadosโฆ
-settings.event_header_repository=Eventos de repositorio
+settings.event_header_repository=Eventos del repositorio
settings.event_create=Crear
settings.event_create_desc=Rama o etiqueta creada.
settings.event_delete=Eliminar
settings.event_delete_desc=Rama o etiqueta eliminada.
-settings.event_fork=Fork
+settings.event_fork=Bifurcaciรณn
settings.event_fork_desc=Repositorio forkeado.
settings.event_wiki=Wiki
settings.event_wiki_desc=Pรกgina de la Wiki creada, renombrada, editada o eliminada.
@@ -2225,49 +2353,49 @@ settings.event_push_desc=Git push a un repositorio.
settings.event_repository=Repositorio
settings.event_repository_desc=Repositorio creado o eliminado.
settings.event_header_issue=Eventos de incidencias
-settings.event_issues=Incidencias
+settings.event_issues=Modificaciรณn
settings.event_issues_desc=Incidencia abierta, cerrada, reabierta o editada.
-settings.event_issue_assign=Incidencia asignada
+settings.event_issue_assign=Asignaciรณn
settings.event_issue_assign_desc=Incidencia asignada o no asignada.
-settings.event_issue_label=Incidencia etiquetada
-settings.event_issue_label_desc=Etiqueta de incidencia actualizada o borrada.
-settings.event_issue_milestone=Hito de incidencia
-settings.event_issue_milestone_desc=Hito de incidencia establecido o desestablecido.
-settings.event_issue_comment=Comentario de incidencia
+settings.event_issue_label=Etiquetas
+settings.event_issue_label_desc=Etiqueta de incidencia aรฑadida o borrada.
+settings.event_issue_milestone=Hitos
+settings.event_issue_milestone_desc=Hito aรฑadido, borrado o modificado.
+settings.event_issue_comment=Comentarios
settings.event_issue_comment_desc=Comentario de incidencias creado, editado o borrado.
-settings.event_header_pull_request=Eventos de Pull Requests
-settings.event_pull_request=Pull Request
+settings.event_header_pull_request=Eventos de pull requests
+settings.event_pull_request=Modificaciรณn
settings.event_pull_request_desc=Pull request abierto, cerrado, reabierto o editado.
-settings.event_pull_request_assign=Pull Request asignado
+settings.event_pull_request_assign=Asignaciรณn
settings.event_pull_request_assign_desc=Pull Request asignado o no asignado.
-settings.event_pull_request_label=Pull Request Etiquetado
-settings.event_pull_request_label_desc=Etiqueta de pull request actualizada o borrada.
-settings.event_pull_request_milestone=Hito de pull request
-settings.event_pull_request_milestone_desc=Hito de pull request establecido o desestablecido.
-settings.event_pull_request_comment=Pull Request Comentario
+settings.event_pull_request_label=Etiquetas
+settings.event_pull_request_label_desc=Etiquetas de pull request actualizadas o borradas.
+settings.event_pull_request_milestone=Hitos
+settings.event_pull_request_milestone_desc=Hitos aรฑadidos, eliminados o modificados.
+settings.event_pull_request_comment=Comentarios
settings.event_pull_request_comment_desc=Comentario de pull request creado, editado o borrado.
-settings.event_pull_request_review=Pull Request revisado
-settings.event_pull_request_review_desc=Pull request aprobado, rechazado o comentario de revisiรณn.
-settings.event_pull_request_sync=Pull Request sincronizado
-settings.event_pull_request_sync_desc=Pull request sincronizado.
-settings.event_pull_request_review_request=Revisiรณn de Pull Request solicitada
+settings.event_pull_request_review=Revisiones
+settings.event_pull_request_review_desc=Pull request aprobada, rechazada o comentarios de revisiรณn aรฑadidos.
+settings.event_pull_request_sync=Sincronizado
+settings.event_pull_request_sync_desc=La rama se actualizรณ automรกticamente con la rama de destino.
+settings.event_pull_request_review_request=Solicitudes de revisiรณn
settings.event_pull_request_review_request_desc=La solicitud de Pull Request ha sido eliminada.
-settings.event_pull_request_approvals=Aprobaciones de Pull Request
-settings.event_pull_request_merge=Fusionar Pull Request
+settings.event_pull_request_approvals=Aprobaciones de pull request
+settings.event_pull_request_merge=Fusiรณn de pull request
settings.event_package=Paquete
settings.event_package_desc=Paquete creado o eliminado en un repositorio.
settings.branch_filter=Filtro de rama
-settings.branch_filter_desc=Lista blanca de rama para eventos de push, creaciรณn de rama y eliminaciรณn de rama, especificados como patrรณn globo. Si estรก vacรญo o *
, se reportan eventos para todas las ramas. Ver github.com/gobwas/glob documentaciรณn para la sintaxis. Ejemplos: master
, {master,release*}
.
+settings.branch_filter_desc=Lista blanca de rama para eventos de push, creaciรณn de rama y eliminaciรณn de rama, especificados como patrรณn globo. Si estรก vacรญo o *
, se reportan eventos para todas las ramas. Ver %[2]s documentaciรณn para la sintaxis. Ejemplos: master
, {master,release*}
.
settings.authorization_header=Encabezado de autorizaciรณn
settings.authorization_header_desc=Se incluirรก como encabezado de autorizaciรณn para solicitudes cuando estรฉ presente. Ejemplo: %s.
settings.active=Activo
settings.active_helper=La informaciรณn sobre los eventos desencadenados se enviarรก a esta URL de webhook.
settings.add_hook_success=El webhook ha sido aรฑadido.
-settings.update_webhook=Actualizar Webhook
+settings.update_webhook=Actualizar webhook
settings.update_hook_success=El webhook ha sido actualizado.
-settings.delete_webhook=Eliminar Webhook
-settings.recent_deliveries=Envรญos Recientes
-settings.hook_type=Tipo de Hook
+settings.delete_webhook=Eliminar webhook
+settings.recent_deliveries=Envรญos recientes
+settings.hook_type=Tipo de hook
settings.slack_token=Token
settings.slack_domain=Dominio
settings.slack_channel=Canal
@@ -2289,8 +2417,8 @@ settings.web_hook_name_packagist=Packagist
settings.packagist_username=Nombre de usuario Packagist
settings.packagist_api_token=Token de API
settings.packagist_package_url=URL del paquete Packagist
-settings.deploy_keys=Claves de Implementaciรณn
-settings.add_deploy_key=Aรฑadir Clave de Implementaciรณn
+settings.deploy_keys=Claves de implementaciรณn
+settings.add_deploy_key=Aรฑadir clave de implementaciรณn
settings.deploy_key_desc=Las claves de implementaciรณn tienen acceso de sรณlo lectura al repositorio.
settings.is_writable=Habilitar acceso de escritura
settings.is_writable_info=Permitir que esta clave de implementaciรณn pueda hacer push a este repositorio.
@@ -2310,50 +2438,50 @@ settings.protected_branch.delete_rule=Eliminar regla
settings.protected_branch_can_push=ยฟPermitir hacer push?
settings.protected_branch_can_push_yes=Puede hacer push
settings.protected_branch_can_push_no=No puede hacer push
-settings.branch_protection=Proteccion de la rama '%s '
+settings.branch_protection=Reglas de protecciรณn de la rama "%s "
settings.protect_this_branch=Activar protecciรณn de rama
settings.protect_this_branch_desc=Evita la eliminaciรณn y restringe hacer push y fusionar contra la rama.
-settings.protect_disable_push=Deshabilitar Push
+settings.protect_disable_push=Deshabilitar push
settings.protect_disable_push_desc=No se permitirรก hacer push a esta rama.
-settings.protect_enable_push=Habilitar Push
+settings.protect_enable_push=Habilitar push
settings.protect_enable_push_desc=Cualquier usuario con permiso de escritura podrรก hacer push a esta rama (pero no push --force).
settings.protect_enable_merge=Activar fusiรณn
settings.protect_enable_merge_desc=Cualquiera con acceso de escritura podrรก fusionar las pull requests en esta rama.
-settings.protect_whitelist_committers=Hacer push restringido a la lista blanca
+settings.protect_whitelist_committers=Push restringido a la lista blanca
settings.protect_whitelist_committers_desc=Sรณlo se permitirรก a los usuarios o equipos de la lista blanca hacer push a esta rama (pero no forzar push).
settings.protect_whitelist_deploy_keys=Lista blanca de claves de despliegue con acceso de escritura a push.
-settings.protect_whitelist_users=Usuarios en la lista blanca para hacer push:
+settings.protect_whitelist_users=Usuarios en la lista blanca para hacer push
settings.protect_whitelist_search_users=Buscar usuariosโฆ
-settings.protect_whitelist_teams=Equipos en la lista blanca para hacer push:
+settings.protect_whitelist_teams=Equipos en la lista blanca para hacer push
settings.protect_whitelist_search_teams=Buscar equiposโฆ
settings.protect_merge_whitelist_committers=Activar lista blanca para fusionar
settings.protect_merge_whitelist_committers_desc=Permitir a los usuarios o equipos de la lista a fusionar peticiones pull dentro de esta rama.
-settings.protect_merge_whitelist_users=Usuarios en la lista blanca para fusionar:
-settings.protect_merge_whitelist_teams=Equipos en la lista blanca para fusionar:
+settings.protect_merge_whitelist_users=Usuarios en la lista blanca para fusionar
+settings.protect_merge_whitelist_teams=Equipos en la lista blanca para fusionar
settings.protect_check_status_contexts=Habilitar comprobaciรณn de estado
-settings.protect_status_check_patterns=Patrones de verificaciรณn de estado:
+settings.protect_status_check_patterns=Patrones de verificaciรณn de estado
settings.protect_status_check_patterns_desc=Introduzca los patrones para especificar quรฉ comprobaciones de estado deben pasar antes de que las ramas puedan ser fusionadas en una rama que coincida con esta regla. Cada lรญnea especifica un patrรณn. Los patrones no pueden estar vacรญos.
settings.protect_check_status_contexts_desc=Requiere verificaciones de estado para pasar antes de fusionar. Elija quรฉ verificaciones de estado deben pasar antes de que las ramas puedan fusionarse en una rama que coincida con esta regla. Cuando se active, los commits primero deben ser empujados a otra rama, y luego fusionados o empujados directamente a una rama que coincida con esta regla luego de que las verificaciones de estado hayan pasado. Si no se selecciona ningรบn contexto, el รบltimo commit debe ser exitoso sin importar el contexto.
settings.protect_check_status_contexts_list=Comprobaciones de estado para este repositorio encontradas durante la semana pasada
settings.protect_status_check_matched=Coincide
settings.protect_invalid_status_check_pattern=Patrรณn de verificaciรณn de estado no vรกlido: "%s".
settings.protect_no_valid_status_check_patterns=No hay patrones de verificaciรณn de estado.
-settings.protect_required_approvals=Aprobaciones requeridas:
+settings.protect_required_approvals=Aprobaciones requeridas
settings.protect_required_approvals_desc=Permite fusionar sรณlo los pull request con suficientes comentarios positivos.
settings.protect_approvals_whitelist_enabled=Restringir las aprobaciones a los usuarios o equipos que estรฉn en una lista blanca
settings.protect_approvals_whitelist_enabled_desc=Solo las revisiones de usuarios o equipos en la lista blanca contarรกn para las aprobaciones requeridas. Sin una lista de aprobaciรณn blanca, las revisiones de cualquier persona con acceso de escritura cuentan para las aprobaciones requeridas.
-settings.protect_approvals_whitelist_users=Lista blanca de usuarios revisores:
-settings.protect_approvals_whitelist_teams=Lista blanca de equipos revisores:
+settings.protect_approvals_whitelist_users=Lista blanca de usuarios revisores
+settings.protect_approvals_whitelist_teams=Lista blanca de equipos revisores
settings.dismiss_stale_approvals=Descartar aprobaciones obsoletas
settings.dismiss_stale_approvals_desc=Cuando los nuevos commits que cambien el contenido de la pull request sean empujados a la rama, se descartarรกn las aprobaciones antiguas.
-settings.require_signed_commits=Requiere commits firmados
+settings.require_signed_commits=Exigir confirmaciones firmadas
settings.require_signed_commits_desc=Rechazar push en esta rama si los commits no estรกn firmados o no son verificables.
-settings.protect_branch_name_pattern=Patrรณn de nombre de la rama protegida
+settings.protect_branch_name_pattern=Patrรณn de nombre de ramas protegidas
settings.protect_patterns=Patrones
-settings.protect_protected_file_patterns=Patrones de archivos protegidos (separados con punto y coma ';'):
-settings.protect_protected_file_patterns_desc=No estรก permitido cambiar archivos directamente incluso si el usuario tiene permiso para agregar, editar o borrar archivos en esta rama. Mรบltiples patrones pueden separarse usando punto y coma (';'). Refvisa la documentaciรณn de github.com/gobwas/glob para la sintaxis de patrones. Ejemplos: .drone.yml
, /docs/**/*.txt
.
-settings.protect_unprotected_file_patterns=Patrones de archivos sin protecciรณn (separados con punto y coma ';'):
-settings.protect_unprotected_file_patterns_desc=Los archivos sin protecciรณn se pueden cambiar directamente si el usuario tiene acceso de escritura, evitando la restricciรณn push. Mรบltiples patrones pueden separarse usando punto y coma (';'). Vea la documentaciรณn de github.com/gobwas/glob para la sintaxis de patrones. Ejemplos: .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns=Patrones de archivos protegidos (separados con punto y coma ';')
+settings.protect_protected_file_patterns_desc=No estรก permitido cambiar archivos directamente incluso si el usuario tiene permiso para agregar, editar o borrar archivos en esta rama. Mรบltiples patrones pueden separarse usando punto y coma (';'). Refvisa la documentaciรณn de %[2]s para la sintaxis de patrones. Ejemplos: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns=Patrones de archivos sin protecciรณn (separados con punto y coma ";")
+settings.protect_unprotected_file_patterns_desc=Los archivos sin protecciรณn se pueden cambiar directamente si el usuario tiene acceso de escritura, evitando la restricciรณn push. Mรบltiples patrones pueden separarse usando punto y coma (';'). Vea la documentaciรณn de %[2]s para la sintaxis de patrones. Ejemplos: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=Activar protecciรณn
settings.delete_protected_branch=Desactivar protecciรณn
settings.update_protect_branch_success=Se ha actualizado la protecciรณn de la rama para la regla "%s".
@@ -2369,12 +2497,12 @@ settings.block_outdated_branch=Bloquear fusiรณn si la pull request estรก desactu
settings.block_outdated_branch_desc=La fusiรณn no serรก posible cuando la rama principal estรฉ detrรกs de la rama base.
settings.default_branch_desc=Seleccione una rama de repositorio por defecto para los pull request y los commits:
settings.merge_style_desc=Estilos de fusiรณn
-settings.default_merge_style_desc=Estilo de fusiรณn por defecto para pull requests:
+settings.default_merge_style_desc=Estilo de fusiรณn por defecto
settings.choose_branch=Elija una ramaโฆ
settings.no_protected_branch=No hay ramas protegidas.
settings.edit_protected_branch=Editar
settings.protected_branch_required_rule_name=Nombre de regla requerido
-settings.protected_branch_duplicate_rule_name=Nombre de regla duplicado
+settings.protected_branch_duplicate_rule_name=Ya hay una regla para este conjunto de ramas
settings.protected_branch_required_approvals_min=Las aprobaciones necesarias no pueden ser negativas.
settings.tags=Etiquetas
settings.tags.protection=Protecciรณn de etiquetas
@@ -2382,27 +2510,27 @@ settings.tags.protection.pattern=Patrรณn de etiquetas
settings.tags.protection.allowed=Permitido
settings.tags.protection.allowed.users=Usuarios permitidos
settings.tags.protection.allowed.teams=Equipos permitidos
-settings.tags.protection.allowed.noone=Ningรบn
-settings.tags.protection.create=Proteger Etiqueta
+settings.tags.protection.allowed.noone=Ningรบno
+settings.tags.protection.create=Aรฑadir regla
settings.tags.protection.none=No hay etiquetas protegidas.
-settings.tags.protection.pattern.description=Puede usar un solo nombre, un patrรณn de glob o expresiรณn regular para que coincida con varias etiquetas. Lea mรกs en la guรญa de etiquetas protegidas .
-settings.bot_token=Token del Bot
+settings.tags.protection.pattern.description=Puede usar un solo nombre, un patrรณn de glob o expresiรณn regular para que coincida con varias etiquetas. Lea mรกs en la guรญa de etiquetas protegidas .
+settings.bot_token=Token del bot
settings.chat_id=ID Chat
settings.thread_id=ID del hilo
settings.matrix.homeserver_url=URL de Homeserver
settings.matrix.room_id=ID de sala
settings.matrix.message_type=Tipo de mensaje
-settings.archive.button=Archivar Repositorio
+settings.archive.button=Archivar repositorio
settings.archive.header=Archivar este repositorio
settings.archive.text=Archivar el repositorio lo harรก de sรณlo lectura. Se ocultarรก del tablero. Nadie (ยกni siquiera tรบ!) serรก capaz de hacer nuevos commits, o abrir nuevas incidencias o pull requests.
settings.archive.success=El repositorio ha sido archivado exitosamente.
settings.archive.error=Ha ocurrido un error al intentar archivar el repositorio. Vea el registro para mรกs detalles.
settings.archive.error_ismirror=No puede archivar un repositorio replicado.
-settings.archive.branchsettings_unavailable=Los ajustes de rama no estรกn disponibles si el repositorio estรก archivado.
+settings.archive.branchsettings_unavailable=Los ajustes de rama no estรกn disponibles en repositorios archivados.
settings.archive.tagsettings_unavailable=Los ajustes de las etiquetas no estรกn disponibles si el repositorio estรก archivado.
settings.unarchive.button=Desarchivar repositorio
settings.unarchive.header=Desarchivar este repositorio
-settings.unarchive.text=La desarchivaciรณn del repositorio restablecerรก su capacidad de recibir commits y pushes, asรญ como nuevas incidencias y pull requests.
+settings.unarchive.text=La desarchivaciรณn del repositorio restablecerรก su capacidad de recibir confirmaciones y empujes, asรญ como nuevas incidencias y solicitudes de incorporaciรณn de cambios.
settings.unarchive.success=El repositorio se ha desarchivado correctamente.
settings.unarchive.error=Ocurriรณ un error mientras se trataba de des-archivar el repositorio. Revisa el registro para mรกs detalles.
settings.update_avatar_success=El avatar del repositorio ha sido actualizado.
@@ -2413,19 +2541,19 @@ settings.lfs_findcommits=Encontrar consignas
settings.lfs_lfs_file_no_commits=No se encontraron commits para este archivo LFS
settings.lfs_noattribute=Esta ruta no tiene el atributo bloqueable en la rama por defecto
settings.lfs_delete=Eliminar archivo LFS con el OID %s
-settings.lfs_delete_warning=Eliminar un archivo LFS puede causar errores de 'objeto no existe' en la compra. ยฟEstรก seguro?
+settings.lfs_delete_warning=Eliminar un archivo LFS puede causar errores de 'objeto no existe' durante un checkout. ยฟEstรก seguro?
settings.lfs_findpointerfiles=Buscar de punteros LFS
settings.lfs_locks=Bloqueos
settings.lfs_invalid_locking_path=Ruta no vรกlida: %s
settings.lfs_invalid_lock_directory=No se puede bloquear el directorio: %s
settings.lfs_lock_already_exists=El bloqueo ya existe: %s
settings.lfs_lock=Bloquear
-settings.lfs_lock_path=Ruta del archivo a bloquear...
+settings.lfs_lock_path=Ruta del archivo a bloquearโฆ
settings.lfs_locks_no_locks=Sin bloqueos
settings.lfs_lock_file_no_exist=El archivo bloqueado no existe en la rama por defecto
settings.lfs_force_unlock=Forzar desbloqueo
settings.lfs_pointers.found=Encontrados %d punteros - %d asociados, %d no asociados (%d falta en el almacรฉn)
-settings.lfs_pointers.sha=Blob SHA
+settings.lfs_pointers.sha=Blob hash
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=En repositorio
settings.lfs_pointers.exists=Existe en almacรฉn
@@ -2438,17 +2566,17 @@ settings.rename_branch_from=nombre de la rama vieja
settings.rename_branch_to=nombre de la rama nueva
settings.rename_branch=Renombrar rama
-diff.browse_source=Explorar el Cรณdigo
+diff.browse_source=Explorar el cรณdigo
diff.parent=padre
diff.commit=commit
diff.git-notes=Notas
-diff.data_not_available=El contenido del Diff no estรก disponible
+diff.data_not_available=El contenido del diff no estรก disponible
diff.options_button=Opciones de diferencias
diff.show_diff_stats=Mostrar estadรญsticas
diff.download_patch=Descargar archivo de parche
diff.download_diff=Descargar archivo de diferencias
diff.show_split_view=Dividir vista
-diff.show_unified_view=Unificar vista
+diff.show_unified_view=Vista unificada
diff.whitespace_button=Espacio blanco
diff.whitespace_show_everything=Mostrar todos los cambios
diff.whitespace_ignore_all_whitespace=Ignorar espacio en blanco al comparar lรญneas
@@ -2458,7 +2586,7 @@ diff.stats_desc=Se han modificado %d ficheros con %d ad
diff.stats_desc_file=%d cambios: %d adiciones y %d eliminaciones
diff.bin=BIN
diff.bin_not_shown=Archivo binario no mostrado.
-diff.view_file=Ver fichero
+diff.view_file=Ver archivo
diff.file_before=Antes
diff.file_after=Despuรฉs
diff.file_image_width=Anchura
@@ -2467,18 +2595,18 @@ diff.file_byte_size=Tamaรฑo
diff.file_suppressed=La diferencia del archivo ha sido suprimido porque es demasiado grande
diff.file_suppressed_line_too_long=Las diferiencias del archivo han sido suprimidas porque una o mas lineas son muy largas
diff.too_many_files=Algunos archivos no se mostraron porque demasiados archivos han cambiado en esta diferencia
-diff.show_more=Ver mรกs
-diff.load=Cargar Diff
+diff.show_more=Mostrar mรกs
+diff.load=Cargar diff
diff.generated=generado
diff.vendored=vendido
diff.comment.add_line_comment=Aรฑadir comentario en lรญnea
diff.comment.placeholder=Deja un comentario
-diff.comment.markdown_info=Es posible estilizar con markdown.
+diff.comment.markdown_info=Es posible dar estilos con Markdown.
diff.comment.add_single_comment=Aรฑadir solo comentario
diff.comment.add_review_comment=Aรฑadir comentario
diff.comment.start_review=Comenzar revisiรณn
diff.comment.reply=Responder
-diff.review=Revisiรณn
+diff.review=Finalizar revisiรณn
diff.review.header=Enviar revisiรณn
diff.review.placeholder=Comentario de revisiรณn
diff.review.comment=Comentario
@@ -2504,11 +2632,11 @@ release.draft=Borrador
release.prerelease=Pre-lanzamiento
release.stable=Estable
release.compare=Comparar
-release.edit=editar
+release.edit=Editar
release.ahead.commits=%d commits
release.ahead.target=a %s desde esta versiรณn
tag.ahead.target=a %s desde esta etiqueta
-release.source_code=Cรณdigo Fuente
+release.source_code=Cรณdigo fuente
release.new_subheader=Los lanzamientos organizan las versiones de proyectos.
release.edit_subheader=Los lanzamientos organizan las versiones de proyectos.
release.tag_name=Nombre de la etiqueta
@@ -2519,15 +2647,15 @@ release.tag_helper_existing=Etiqueta actual.
release.title=Tรญtulo de lanzamiento
release.title_empty=El tรญtulo no puede estar vacรญo.
release.message=Describe esta versiรณn
-release.prerelease_desc=Marcar como Pre-Lanzamiento
+release.prerelease_desc=Marcar como pre-lanzamiento
release.prerelease_helper=Marcar este lanzamiento como no es adecuada para usar en producciรณn.
release.cancel=Cancelar
release.publish=Publicar lanzamiento
release.save_draft=Guardar borrador
release.edit_release=Actualizar Lanzamiento
-release.delete_release=Eliminar Lanzamiento
-release.delete_tag=Eliminar Etiqueta
-release.deletion=Eliminar Lanzamiento
+release.delete_release=Eliminar lanzamiento
+release.delete_tag=Eliminar tag
+release.deletion=Eliminar lanzamiento
release.deletion_desc=Eliminar un lanzamiento sรณlo lo elimina de Forgejo. No afectarรก la etiqueta Git, el contenido de su repositorio o su historial. ยฟContinuar?
release.deletion_success=El lanzamiento ha sido eliminado.
release.deletion_tag_desc=Eliminarรก esta etiqueta del repositorio. El contenido del repositorio y el historial permanecerรกn sin cambios. ยฟContinuar?
@@ -2539,20 +2667,20 @@ release.tag_already_exist=Este nombre de etiqueta ya existe.
release.downloads=Descargas
release.download_count=Descargas: %s
release.add_tag_msg=Utilice el tรญtulo y el contenido de la liberaciรณn como mensaje de etiqueta.
-release.add_tag=Crear solo etiqueta
+release.add_tag=Crear tag
release.releases_for=Lanzamientos para %s
release.tags_for=Etiquetas para %s
branch.name=Nombre de la rama
branch.already_exists=Una rama llamada "%s" ya existe.
branch.delete_head=Eliminar
-branch.delete=`Eliminar rama "%s "`
+branch.delete=Eliminar rama "%s "
branch.delete_html=Eliminar rama
branch.delete_desc=Eliminar una rama es permanente. Aunque la rama eliminada puede continuar existiendo durante un corto tiempo antes de que sea eliminada, en la mayorรญa de los casos NO PUEDE deshacerse. ยฟContinuar?
branch.deletion_success=La rama "%s" ha sido eliminada.
branch.deletion_failed=Error al eliminar la rama "%s".
-branch.delete_branch_has_new_commits=La rama "%s" no se puede eliminar porque se han aรฑadido nuevos commits despuรฉs de la fusiรณn.
-branch.create_branch=Crear rama %s
+branch.delete_branch_has_new_commits=La rama "%s" no se puede eliminar porque se han aรฑadido nuevas confirmaciones despuรฉs de la fusiรณn.
+branch.create_branch=Crear rama %s
branch.create_from=`de "%s"`
branch.create_success=La rama "%s" ha sido creada.
branch.branch_already_exists=La rama "%s" ya existe en este repositorio.
@@ -2563,9 +2691,9 @@ branch.restore_success=La rama "%s" ha sido restaurada.
branch.restore_failed=Error al restaurar la rama "%s".
branch.protected_deletion_failed=La rama "%s" estรก protegida. No se puede eliminar.
branch.default_deletion_failed=La rama "%s" es la rama por defecto. No se puede eliminar.
-branch.restore=`Restaurar rama "%s"`
-branch.download=`Descargar rama "%s"`
-branch.rename=`Renombrar rama "%s"`
+branch.restore=Restaurar rama "%s"
+branch.download=Descargar rama "%s"
+branch.rename=Renombrar rama "%s"
branch.search=Buscar rama
branch.included_desc=Esta rama forma parte de la predeterminada
branch.included=Incluida
@@ -2579,7 +2707,7 @@ branch.new_branch=Crear nueva rama
branch.new_branch_from=`Crear nueva rama de "%s"`
branch.renamed=La rama %s fue renombrada a %s.
-tag.create_tag=Crear etiqueta %s
+tag.create_tag=Crear etiqueta %s
tag.create_tag_operation=Crear etiqueta
tag.confirm_create_tag=Crear etiqueta
tag.create_tag_from=`Crear nueva etiqueta de "%s"`
@@ -2589,9 +2717,9 @@ tag.create_success=La etiqueta "%s" ha sido creada.
topic.manage_topics=Administrar temas
topic.done=Hecho
topic.count_prompt=No puede seleccionar mรกs de 25 temas
-topic.format_prompt=Los temas deben comenzar con una letra o nรบmero, pueden incluir guiones ('-') y puntos ('. ), puede tener hasta 35 caracteres de largo. Las letras deben estar en minรบsculas.
+topic.format_prompt=Los temas deben comenzar con una letra o nรบmero, pueden incluir guiones ("-") y puntos ("."), puede tener hasta 35 caracteres de largo. Las letras deben estar en minรบsculas.
-find_file.go_to_file=Ir al archivo
+find_file.go_to_file=Buscar un archivo
find_file.no_matching=No se encontrรณ ningรบn archivo que coincidiese
error.csv.too_large=No se puede renderizar este archivo porque es demasiado grande.
@@ -2613,16 +2741,166 @@ issues.archived_label_description = (Archivado) %s
n_commit_one = %s commit
generated = Generado
pulls.nothing_to_compare_have_tag = La rama/etiqueta seleccionada es igual.
-commits.search_branch = Esta Rama
+commits.search_branch = Esta rama
commits.renamed_from = Renombrado de %s
+form.string_too_long = El texto introducido tiene mรกs de %d caracteres.
+object_format = Formato de objetos
+n_release_one = %s lanzamiento
+n_release_few = %s lanzamientos
+stars = Estrellas
+editor.invalid_commit_mail = Correo no vรกlido para crear un commit.
+project = Proyectos
+mirror_sync = sincronizado
+editor.commit_id_not_matching = El archivo fue modificado mientras lo editabas. Haz commit en una nueva rama y luego fusiona.
+size_format = %[1]s: %[2]s, %[3]s: %[4]s
+admin.update_flags = Actualizar indicadores
+admin.flags_replaced = Indicadores del repositorio sustituidos
+admin.failed_to_replace_flags = Fallo al substituir los indicadores del repositorio
+new_repo_helper = Un repositorio contiene todos los archivos del proyecto, incluido el historial de revisiones. ยฟYa tienes uno en otro sitio? Migrar repositorio .
+object_format_helper = Formato de objeto del repositorio. No puede ser modificado mรกs tarde. SHA1 es el mรกs compatible.
+commits.browse_further = Seguir explorando
+subscribe.issue.guest.tooltip = Inicia sesiรณn para suscribirte a esta incidencia.
+subscribe.pull.guest.tooltip = Inicia sesiรณn para suscribirte a este pull request.
+admin.manage_flags = Gestionar indicadores
+admin.enabled_flags = Indicadores habilitados para el repositorio:
+editor.push_out_of_date = El empuje parece estar desactualizado.
+mirror_public_key = Clave de SSH pรบblica
+mirror_use_ssh.text = Utilizar autenticaciรณn SSH
+no_eol.text = Sin EOL
+no_eol.tooltip = Este archivo no contiene un carรกcter de fin de lรญnea.
+mirror_denied_combination = No se puede utilizar la autenticaciรณn mediante clave pรบblica y contraseรฑa en combinaciรณn.
+mirror_use_ssh.helper = Forgejo replicarรก el repositorio vรญa Git sobre SSH y crearรก un par de claves para ti cuando selecciones esta opciรณn. Debes asegurarte de que la clave pรบblica generada sea autorizada para empujar al repositorio de destino. No puedes usar autorizaciรณn mediante contraseรฑa cuando selecciones esta opciรณn.
+issues.edit.already_changed = No fue posible guardar los cambios a la incidencia. Parece que el contenido ya fue modificado por otro usuario. Actualiza la pรกgina e intenta editar de nuevo para evitar sobrescribir los cambios
+issues.author.tooltip.issue = Este usuario es el autor de esta incidencia.
+mirror_use_ssh.not_available = La autenticaciรณn por SSH no estรก disponible.
+issues.author.tooltip.pr = Este usuario es el autor de este pull request.
+issues.blocked_by_user = No puedes crear una incidencia en este repositorio porque estas bloqueado por el propietario del repositorio.
+pulls.merged_title_desc_one = fusionรณ %[1]d commit de %[2]s
en %[3]s
%[4]s
+pulls.fast_forward_only_merge_pull_request = Sรณlo fast-forward
+pulls.blocked_by_user = No puedes crear una pull request en este repositorio porque estas bloqueado por el propietario del repositorio.
+issues.comment.blocked_by_user = No puedes crear un comentario en esta incidencia porque estรกs bloqueado por el propietario del repositorio o el autor de la incidencia.
+comments.edit.already_changed = No fue posible guardar los cambios al comentario. Parece que el contenido ya fue modificado por otro usuario. Actualiza la pรกgina e intenta editar de nuevo para evitar sobrescribir los cambios
+pulls.edit.already_changed = No fue posible guardar los cambios al pull request. Parece que el contenido ya fue modificado por otro usuario. Actualiza la pรกgina e intenta editar de nuevo para evitar sobrescribir los cambios
+pulls.title_desc_one = quiere fusionar %[1]d commit de %[2]s
en %[3]s
+pulls.ready_for_review = Listo para revisar?
+activity.navbar.contributors = Contribuidores
+pulls.cmd_instruction_hint = Ver instrucciones para la lรญnea de comandos
+settings.units.units = Unidades
+settings.units.overview = Vista general
+pulls.status_checks_hide_all = Ocultar todas las verificaciones
+settings.federation_not_enabled = La federaciรณn no estรก habilitada en tu instancia.
+wiki.search = Buscar en wiki
+pulls.status_checks_show_all = Mostrar todas las verificaciones
+pulls.commit_ref_at = `hizo referencia a este pull request desde un commit %[2]s `
+pulls.cmd_instruction_merge_title = Fusionar
+contributors.contribution_type.deletions = Eliminaciones
+contributors.contribution_type.filter_label = Tipo de contribuciรณn:
+contributors.contribution_type.additions = Adiciones
+settings.units.add_more = Habilitar mรกs
+wiki.cancel = Cancelar
+activity.published_prerelease_label = Pre-lanzamiento
+activity.published_tag_label = Etiqueta
+pulls.made_using_agit = AGit
+pulls.reopen_failed.head_branch = No se puede reabrir el pull request porque la rama de cabeza ya no existe.
+pulls.cmd_instruction_checkout_desc = Desde el repositorio de tu proyecto, crea una nueva rama y prueba los cambios.
+pulls.cmd_instruction_merge_desc = Fusionar los cambios y actualizar en Forgejo.
+pulls.reopen_failed.base_branch = No se puede reabrir el pull request, porque la rama base ya no existe.
+wiki.no_search_results = Sin resultados
+activity.navbar.pulse = Pulso
+activity.navbar.code_frequency = Frecuencia de cรณdigo
+settings.federation_apapiurl = URL de federaciรณn de este repositorio. Copia y pega esto en los Ajustes de Federaciรณn de otro repositorio como el URL de un Repositorio Seguidor.
+settings.federation_following_repos = URLs de los Repositorios Seguidores. Separados por ";", sin espacios en blanco.
+activity.navbar.recent_commits = Commits recentes
+pulls.cmd_instruction_merge_warning = Atenciรณn: El ajuste "Autodetectar fusiรณn manual" no estรก habilitado para este repositorio, tendrรกs que marcar este pull request como fusionado manualmente despuรฉs.
+pulls.agit_explanation = Creado utilizando el flujo de trabajo AGit. AGit permite a los colaboradores proponer cambios mediante ยซgit pushยป sin crear una bifurcaciรณn o una nueva rama.
+activity.commit = Commits hechos
+milestones.filter_sort.name = Nombre
+settings.federation_settings = Ajustes de federaciรณn
+settings.mirror_settings.push_mirror.none_ssh = Ninguna
+settings.mirror_settings.push_mirror.copy_public_key = Copiar clave pรบblica
+issues.new.assign_to_me = Asignar a mi
+issues.all_title = Todos
+settings.wiki_globally_editable = Permitir a cualquiera editar la wiki
+settings.new_owner_blocked_doer = El nuevo propietario te ha bloqueado.
+settings.add_collaborator_blocked_our = No se puede aรฑadir al colaborador debido a que el propietario del repositorio lo ha bloqueado.
+settings.discord_icon_url.exceeds_max_length = La URL del icono debe tener una longitud menor o igual a 2048 caracteres
+settings.add_webhook.invalid_path = La ruta no debe contener una parte que sea "." o ".." o la cadena vacรญa. No puede empezar o acabar con una barra oblicua.
+settings.wiki_rename_branch_main_notices_1 = Esta operaciรณn NO SE PUEDE deshacer.
+settings.add_collaborator_blocked_them = No se puede aรฑadir al colaborador debido a que este ha bloqueado al propietario del repositorio.
+settings.transfer.button = Transferir la propiedad
+settings.transfer.modal.title = Transferir la propiedad
+settings.enter_repo_name = Introduce el nombre del propietario y del repositorio exactamente como se muestra:
+settings.confirmation_string = Cadena de confirmaciรณn
+issues.filter_sort.relevance = Relevancia
+settings.transfer_quota_exceeded = El nuevo propietario (%s) ha sobrepasado la cuota. El repositorio no ha sido transferido.
+settings.web_hook_name_sourcehut_builds = Builds de SourceHut
+settings.wiki_rename_branch_main_notices_2 =Se va a renombrar de forma permanente la rama interna de la wiki del repositorio %s. Se actualizaran los checkouts existentes.
+settings.wiki_rename_branch_main = Normalizar el nombre de la rama de la wiki
+settings.wiki_rename_branch_main_desc = Renombrar la rama interna usada por la wiki a "%s". Este cambio es permanente y no se puede deshacer.
+settings.confirm_wiki_branch_rename = Renombrar la rama de la wiki
+settings.graphql_url = URL de GraphQL
+settings.sourcehut_builds.manifest_path = Ruta del manifiesto de compilaciรณn
+settings.sourcehut_builds.secrets = Secretos
+release.system_generated = Este archivo adjunto se genera automaticamente.
+release.asset_external_url = URL externa
+release.hide_archive_links = Ocultar archivos generados automaticamente
+settings.mirror_settings.pushed_repository = Repositorio pusheado
+settings.rename_branch_failed_protected = No se puede renombrar la rama %a porque es un rama protegida.
+release.invalid_external_url = URL externa invรกlida: %s
+release.download_count_one = %s descarga
+diff.git-notes.add = Aรฑadir nota
+diff.git-notes.remove-header = Eliminar nota
+release.download_count_few = %s descargas
+diff.git-notes.remove-body = Esta nota serรก eliminada.
+editor.add_tmpl.filename = nombre de fichero
+issues.reaction.add = Aรฑadir reacciรณn
+issues.reaction.alt_remove = Quitar %[1]s reacciรณn de comentario.
+issues.reaction.alt_add = Aรฑadir %[1]s reacciรณn al comentario.
+issues.review.add_review_requests = solicitada revisiones de %[1]s %[2]s
+issues.review.remove_review_requests = eliminada la solicitud de revisiones para %[1]s %[2]s
+new_from_template = Usa una plantilla
+new_from_template_description = Puedes seleccionar una plantilla de repositorio ya existente en esta instancia y aplicar sus ajustes.
+new_advanced = Ajustes avanzados
+new_advanced_expand = Click para expandir
+issues.num_reviews_one = %d revisiรณn
+issues.num_reviews_few = %d revisiones
+auto_init_description = Empieza el historial Git con un README y opcionalmente aรฑade una Licencia y archivos .gitignore.
+release.type_external_asset = Recurso externo
+archive.pull.noreview = Este repositorio estรก archivado. No puedes revisar pull requests.
+release.asset_name = Nombre del recurso
+issues.review.add_remove_review_requests = Revisiones solicitadas de %[1]s y revisiones eliminadas para %[2]s %[3]s
+editor.commit_email = Correo electrรณnico del commit
+settings.protect_new_rule = Crear una nueva regla de protecciรณn de rama
+issues.context.menu = Menรบ de comentarios
+pulls.sign_in_require = Inicia sesiรณn para crear un nuevo pull request.
+pulls.cmd_instruction_checkout_title = Cambiar rama
+release.add_external_asset = Aรฑadir un recurso externo
+settings.enforce_on_admins_desc = Los administradores del repositorio no pueden saltarse esta regla.
+pulls.editable = Editable
+
+issues.filter_no_results = No hay resultados
+
+release.type_attachment = Archivo adjunto
+
+issues.reaction.alt_few = %[1]s reaccionado con %[2]s.
+settings.event_pull_request_enforcement = Aplicaciรณn
+settings.sourcehut_builds.visibility = Visibilidad de trabajo
+settings.ignore_stale_approvals = Ignorar las aprobaciones obsoletas
[graphs]
+component_loading = Cargando %sโฆ
+component_loading_failed = No se pudo cargar %s
+contributors.what = contribuciones
+recent_commits.what = commits recientes
+code_frequency.what = frecuencia de cรณdigo
+component_loading_info = Esto puede tomar un tiempoโฆ
+component_failed_to_load = Ocurriรณ un error inesperado.
[org]
org_name_holder=Nombre de la organizaciรณn
org_full_name_holder=Nombre completo de la organizaciรณn
org_name_helper=Los nombres de organizaciรณn deben ser cortos y destacados.
-create_org=Crear Organizaciรณn
+create_org=Crear organizaciรณn
repo_updated=Actualizado %s
members=Miembros
teams=Equipos
@@ -2675,11 +2953,11 @@ settings.hooks_desc=Aรฑadir webhooks que serรกn ejecutados para todos lo
settings.labels_desc=Aรฑadir etiquetas que pueden ser utilizadas en problemas para todos los repositorios bajo esta organizaciรณn.
-members.membership_visibility=Visibilidad de Membresรญa:
+members.membership_visibility=Visibilidad de membresรญa:
members.public=Pรบblico
-members.public_helper=hacer oculto
+members.public_helper=Hacer oculto
members.private=Oculto
-members.private_helper=hacer pรบblico
+members.private_helper=Hacer pรบblico
members.member_role=Rol del miembro:
members.owner=Propietario
members.member=Miembro
@@ -2688,7 +2966,7 @@ members.remove.detail=ยฟDestituir a %[1]s de %[2]s?
members.leave=Abandonar
members.leave.detail=ยฟIrse de %s?
members.invite_desc=Aรฑadir un miembro nuevo a %s:
-members.invite_now=Invitar
+members.invite_now=Invitar ahora
teams.join=Unirse
teams.leave=Abandonar
@@ -2697,7 +2975,7 @@ teams.can_create_org_repo=Crear repositorios
teams.can_create_org_repo_helper=Los miembros pueden crear nuevos repositorios en la organizaciรณn. El creador obtendrรก acceso al administrador del nuevo repositorio.
teams.none_access=Sin acceso
teams.none_access_helper=Los miembros no pueden ver o hacer ninguna otra acciรณn en esta unidad.
-teams.general_access=Acceso general
+teams.general_access=Acceso personalizado
teams.general_access_helper=Los permisos de los miembros se decidirรกn por debajo de la tabla de permisos.
teams.read_access=Leer
teams.read_access_helper=Los miembros pueden ver y clonar los repositorios del equipo.
@@ -2741,6 +3019,10 @@ teams.all_repositories_admin_permission_desc=Este equipo concede a Admin
teams.invite.title=Has sido invitado a unirte al equipo %s en la organizaciรณn %s .
teams.invite.by=Invitado por %s
teams.invite.description=Por favor, haga clic en el botรณn de abajo para unirse al equipo.
+follow_blocked_user = No puedes seguir a esta organizaciรณn porque esta organizaciรณn te ha bloqueado.
+open_dashboard = Abrir panel de control
+settings.change_orgname_redirect_prompt.with_cooldown.few = El antiguo nombre de la organizaciรณn estarรก disponible para todos despuรฉs un periodo de tiempo de espera de %[1]d dรญas, aรบn puedes reclamar el antiguo nombre durante el periodo de tiempo de espera.
+settings.change_orgname_redirect_prompt.with_cooldown.one = El antiguo nombre de usuario estarรก disponible para cualquiera despuรฉs un periodo de tiempo de espera de %[1]d dรญa, aรบn puedes reclamar el antiguo nombre de usuario durante el periodo de tiempo de espera.
[admin]
dashboard=Panel de control
@@ -2761,7 +3043,7 @@ last_page=รltima
total=Total: %d
settings=Configuraciรณn de Admin
-dashboard.new_version_hint=Forgejo %s ya estรก disponible, estรกs ejecutando %s. Revisa el blog para mรกs detalles.
+dashboard.new_version_hint=Forgejo %s ya estรก disponible, estรกs ejecutando %s. Revisa el blog para mรกs detalles.
dashboard.statistic=Resumen
dashboard.operations=Operaciones de mantenimiento
dashboard.system_status=Estado del sistema
@@ -2798,7 +3080,7 @@ dashboard.update_migration_poster_id=Actualizar ID de usuario en migraciones
dashboard.git_gc_repos=Ejecutar la recolecciรณn de basura en los repositorios
dashboard.resync_all_sshkeys=Actualizar el archivo '.ssh/authorized_keys' con claves SSH de Forgejo.
dashboard.resync_all_sshprincipals=Actualizar el archivo '.ssh/authorized_principals' con los principales de certificado SSH de Forgejo.
-dashboard.resync_all_hooks=Resincronizar los hooks de pre-recepciรณn, actualizaciรณn y post-recepciรณn de todos los repositorios.
+dashboard.resync_all_hooks=Resincronizar los hooks de pre-recepciรณn, actualizaciรณn y post-recepciรณn de todos los repositorios
dashboard.reinit_missing_repos=Reiniciar todos los repositorios Git faltantes de los que existen registros
dashboard.sync_external_users=Sincronizar datos de usuario externo
dashboard.cleanup_hook_task_table=Limpiar tabla hook_task
@@ -2908,7 +3190,7 @@ emails.primary=Principal
emails.activated=Activado
emails.filter_sort.email=Correo electrรณnico
emails.filter_sort.email_reverse=Email (invertir)
-emails.filter_sort.name=Nombre de Usuario
+emails.filter_sort.name=Nombre de usuario
emails.filter_sort.name_reverse=Nombre de usuario (invertir)
emails.updated=Email actualizado
emails.not_updated=Error al actualizar la direcciรณn de correo electrรณnico solicitada: %v
@@ -2923,7 +3205,7 @@ orgs.new_orga=Nueva organizaciรณn
repos.repo_manage_panel=Gestiรณn de repositorios
repos.unadopted=Repositorios no adoptados
-repos.unadopted.no_more=No se encontraron mรกs repositorios no adoptados
+repos.unadopted.no_more=No se encontraron repositorios no adoptados.
repos.owner=Propietario
repos.name=Nombre
repos.private=Privado
@@ -2948,12 +3230,12 @@ packages.size=Tamaรฑo
packages.published=Publicado
defaulthooks=Webhooks por defecto
-defaulthooks.desc=Los webhooks automรกticamente hacen peticiones HTTP POST a un servidor cuando ciertos eventos de Forgejo se activan. Los webhooks definidos aquรญ son predeterminados y serรกn copiados en todos los repositorios nuevos. Leer mรกs en la guรญa webhooks .
+defaulthooks.desc=Los webhooks automรกticamente hacen peticiones HTTP POST a un servidor cuando ciertos eventos de Forgejo se activan. Los webhooks definidos aquรญ son predeterminados y serรกn copiados en todos los repositorios nuevos. Leer mรกs en la guรญa webhooks .
defaulthooks.add_webhook=Aรฑadir Webhook por defecto
defaulthooks.update_webhook=Actualizar Webhook por defecto
systemhooks=Webhooks del sistema
-systemhooks.desc=Los webhooks automรกticamente hacen peticiones HTTP POST a un servidor cuando ciertos eventos de Forgejo se activan. Los webhooks definidos aquรญ actuarรกn en todos los repositorios del sistema, asรญ que por favor considere las implicaciones de rendimiento que esto pueda tener. Lea mรกs en la guรญa de webhooks .
+systemhooks.desc=Los webhooks automรกticamente hacen peticiones HTTP POST a un servidor cuando ciertos eventos de Forgejo se activan. Los webhooks definidos aquรญ actuarรกn en todos los repositorios del sistema, asรญ que por favor considere las implicaciones de rendimiento que esto pueda tener. Lea mรกs en la guรญa de webhooks .
systemhooks.add_webhook=Aรฑadir Webhook del Sistema
systemhooks.update_webhook=Actualizar Webhook del Sistema
@@ -3048,18 +3330,18 @@ auths.tips=Consejos
auths.tips.oauth2.general=Autenticaciรณn OAuth2
auths.tips.oauth2.general.tip=Al registrar una nueva autenticaciรณn de OAuth2, la URL de devoluciรณn de llamada/redirecciรณn debe ser:
auths.tip.oauth2_provider=Proveedor OAuth2
-auths.tip.bitbucket=Registrar un nuevo usuario de OAuth en https://bitbucket.org/account/user//oauth-consumers/new y agregar el permiso 'Cuenta' - 'Lectura'
+auths.tip.bitbucket=Registrar un nuevo usuario de OAuth en %s
auths.tip.nextcloud=`Registre un nuevo consumidor OAuth en su instancia usando el siguiente menรบ "Configuraciรณn-> Seguridad-> cliente OAuth 2.0"`
-auths.tip.dropbox=Crear nueva aplicaciรณn en https://www.dropbox.com/developers/apps
-auths.tip.facebook=`Registre una nueva aplicaciรณn en https://developers.facebook.com/apps y agregue el producto "Facebook Login"`
-auths.tip.github=Registre una nueva aplicaciรณn OAuth en https://github.com/settings/applications/new
+auths.tip.dropbox=Crear nueva aplicaciรณn en %s
+auths.tip.facebook=`Registre una nueva aplicaciรณn en %s y agregue el producto "Facebook Login"`
+auths.tip.github=Registre una nueva aplicaciรณn OAuth en %s
auths.tip.gitlab=Registrar nueva solicitud en https://gitlab.com/profile/applications
-auths.tip.google_plus=Obtener credenciales de cliente OAuth2 desde la consola API de Google en https://console.developers.google.com/
+auths.tip.google_plus=Obtener credenciales de cliente OAuth2 desde la consola API de Google en %s
auths.tip.openid_connect=Use el OpenID Connect Discovery URL (/.well-known/openid-configuration) para especificar los puntos finales
-auths.tip.twitter=Ir a https://dev.twitter.com/apps, crear una aplicaciรณn y asegurarse de que la opciรณn "Permitir que esta aplicaciรณn sea usada para iniciar sesiรณn con Twitter" estรก activada
-auths.tip.discord=Registrar una nueva aplicaciรณn en https://discordapp.com/developers/applications/me
-auths.tip.gitea=Registrar una nueva aplicaciรณn OAuth2. Puede encontrar la guรญa en https://forgejo.org/docs/latest/user/oauth2-provider
-auths.tip.yandex=`Crear una nueva aplicaciรณn en https://oauth.yandex.com/client/new. Seleccione los siguientes permisos del "Yandex.Passport API": "Access to email address", "Access to user avatar" y "Access to username, first name and surname, gender"`
+auths.tip.twitter=Ir a %s, crear una aplicaciรณn y asegurarse de que la opciรณn "Permitir que esta aplicaciรณn sea usada para iniciar sesiรณn con Twitter" estรก activada
+auths.tip.discord=Registrar una nueva aplicaciรณn en %s
+auths.tip.gitea=Registrar una nueva aplicaciรณn OAuth2. La guรญa se encuentra en %s
+auths.tip.yandex=`Crear una nueva aplicaciรณn en %s. Seleccione los siguientes permisos del "Yandex.Passport API": "Access to email address", "Access to user avatar" y "Access to username, first name and surname, gender"`
auths.tip.mastodon=Introduzca una URL de instancia personalizada para la instancia mastodon con la que desea autenticarse (o utilice la predeterminada)
auths.edit=Editar origen de autenticaciรณn
auths.activated=Este origen de autenticaciรณn ha sido activado
@@ -3267,8 +3549,26 @@ notices.type_2=Tarea
notices.desc=Descripciรณn
notices.op=Operaciรณn
notices.delete_success=Los avisos del sistema se han eliminado.
+emails.delete = Eliminar correo electrรณnico
+self_check.no_problem_found = Aรบn no se encontrรณ un problema.
+auths.tip.gitlab_new = Registrar una nueva aplicaciรณn en %s
+config_summary = Resumen
+emails.change_email_text = ยฟEstรกs seguro que quieres actualizar esta direcciรณn de correo electrรณnico?
+auths.tips.gmail_settings = Configuraciรณn de Gmail:
+users.activated.description = Finalizaciรณn de la verificaciรณn del correo electrรณnico. El propietario de una cuenta sin activar no podrรก iniciar sesiรณn hasta que la verificaciรณn se complete.
+config_settings = Ajustes
+users.organization_creation.description = Permitir la creaciรณn de nuevas organizaciones.
+emails.deletion_success = El correo electrรณnico ha sido eliminado.
+emails.delete_primary_email_error = No puedes eliminar el correo electrรณnico principal.
+config.cache_test =Cachรฉ de prueba
+emails.delete_desc = ยฟEstรกs seguro que quieres eliminar esta direcciรณn de correo electrรณnico?
+monitor.duration = Duraciรณn (es)
+self_check = Autocomprobaciรณn
+dashboard.sync_tag.started = Sincronizaciรณn de etiquetas iniciada
+config.app_slogan = Eslogan de la instancia
+
[action]
create_repo=creรณ el repositorio %s
rename_repo=repositorio renombrado de %[1]s
a %[3]s
@@ -3412,7 +3712,7 @@ conda.install=Para instalar el paquete usando Conda, ejecute el siguiente comand
container.details.type=Tipo de imagen
container.details.platform=Plataforma
container.pull=Arrastra la imagen desde la lรญnea de comandos:
-container.digest=Resumen:
+container.digest=Resumen
container.multi_arch=SO / Arquitectura
container.layers=Capas de imagen
container.labels=Etiquetas
@@ -3508,6 +3808,35 @@ owner.settings.cleanuprules.success.delete=Regla de limpieza ha sido eliminada.
owner.settings.chef.title=Registro de Chef
owner.settings.chef.keypair=Generar par de claves
owner.settings.chef.keypair.description=Un par de claves es necesario para autenticarse en el registro del Chef. Si ha generado un par de claves antes, generar un nuevo par de claves descartarรก el par de claves antiguo.
+search_in_external_registry = Buscar en %s
+arch.pacman.sync = Sincronizar el paquete con pacman:
+arch.version.properties = Propiedades de la versiรณn
+arch.pacman.repo.multi = %s tiene la misma versiรณn en diferentes distribuciones.
+arch.pacman.repo.multi.item = Configuraciรณn para %s
+arch.pacman.conf = Aรฑadir servidor con distribuciรณn y arquitectura relacionadas a /etc/pacman.conf
:
+arch.version.backup = Copia de seguridad
+arch.version.depends = Depende
+arch.version.groups = Grupo
+rpm.repository.multiple_groups = Este paquete estรก disponible en mรบltiples grupos.
+arch.version.conflicts = Conflictos
+arch.version.replaces = Reemplazos
+container.images.title = Imรกgenes
+alt.registry = Configurar este registro desde la lรญnea de comandos:
+alt.registry.install = Para instalar el paquete, ejecute el siguiente comando:
+alt.install = Instalar paquete
+alt.repository = Informaciรณn del repositorio
+alt.repository.architectures = Arquitecturas
+alt.repository.multiple_groups = Este paquete estรก disponible en mรบltiples grupos.
+
+arch.version.description = Descripciรณn
+arch.version.provides = Proveedores
+
+arch.version.optdepends = Dependencias opcionales
+arch.version.makedepends = Construir dependencias
+arch.version.checkdepends = Comprobar dependencias
+npm.dependencies.bundle = Empaquetar dependencias
+
+arch.pacman.helper.gpg = Aรฑade el certificado de confianza para pacman:
[secrets]
secrets=Secretos
@@ -3527,15 +3856,15 @@ management=Gestiรณn de secretos
[actions]
actions=Acciones
-unit.desc=Gestionar acciones
+unit.desc=Gestione procesos CI/CD integrados con Forgejo Actions.
status.unknown=Desconocido
status.waiting=Esperando
-status.running=Ejecutando
+status.running=Corriendo
status.success=รxito
status.failure=Fallo
status.cancelled=Cancelado
-status.skipped=Omitido
+status.skipped=Saltado
status.blocked=Bloqueado
runners=Nodos
@@ -3555,7 +3884,7 @@ runners.task_list.no_tasks=Todavรญa no hay tarea.
runners.task_list.run=Ejecutar
runners.task_list.status=Estado
runners.task_list.repository=Repositorio
-runners.task_list.commit=Commit
+runners.task_list.commit=Confirmaciรณn
runners.task_list.done_at=Hecho en
runners.edit_runner=Editar nodo
runners.update_runner=Actualizar cambios
@@ -3587,8 +3916,8 @@ runs.status_no_select=Todo el estado
runs.no_results=No hay resultados coincidentes.
runs.no_runs=El flujo de trabajo no tiene ejecuciones todavรญa.
-workflow.disable=Desactivar fllujo de trabajo
-workflow.disable_success=Flujo de trabajo '%s' deshabilitado correctamente.
+workflow.disable=Desactivar flujo de trabajo
+workflow.disable_success=Flujo de trabajo "%s" desactivado exitosamente.
workflow.enable=Activar flujo de trabajo
workflow.enable_success=Flujo de trabajo '%s' habilitado con รฉxito.
workflow.disabled=El flujo de trabajo estรก deshabilitado.
@@ -3610,15 +3939,26 @@ variables.creation.success=La variable "%s" ha sido aรฑadida.
variables.update.failed=Error al editar la variable.
variables.update.success=La variable ha sido editada.
variables.id_not_exist = Variable con id %d no existe.
+runs.empty_commit_message = (mensaje de commit vacรญo)
+runs.expire_log_message = Los registros han sido eliminados porque eran demasiado antiguos.
+
+runs.workflow = Flujo de trabajo
+
+workflow.dispatch.use_from = Usar el flujo de trabajo de
+workflow.dispatch.run = Correr flujo de trabajo
+
+runs.no_workflows = Aรบn no hay flujos de trabajo.
+workflow.dispatch.success = La ejecuciรณn del flujo de trabajo se ha solicitado correctamente.
+workflow.dispatch.invalid_input_type = Tipo de entrada invรกlida "%s".
[projects]
type-1.display_name=Proyecto individual
-type-2.display_name=Proyecto repositorio
+type-2.display_name=Proyecto de repositorio
type-3.display_name=Proyecto de organizaciรณn
+deleted.display_name = Proyecto borrado
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=Directorio
normal_file=Archivo normal
executable_file=Archivo ejecutable
@@ -3628,14 +3968,63 @@ submodule=Submรณdulo
[search]
-search = Buscar...
+search = Buscarโฆ
type_tooltip = Tipo de bรบsqueda
-project_kind = Buscar proyectos...
-branch_kind = Buscar ramas...
-commit_kind = Buscar commits...
-repo_kind = Buscar repositorios...
-user_kind = Buscar usuarios...
-org_kind = Buscar organizaciones...
-team_kind = Buscar equipos...
-code_kind = Buscar cรณdigo...
-package_kind = Buscar paquetes...
\ No newline at end of file
+project_kind = Buscar proyectosโฆ
+branch_kind = Buscar ramasโฆ
+commit_kind = Buscar confirmacionesโฆ
+repo_kind = Buscar repositoriosโฆ
+user_kind = Buscar usuariosโฆ
+org_kind = Buscar organizacionesโฆ
+team_kind = Buscar equiposโฆ
+code_kind = Buscar cรณdigoโฆ
+package_kind = Buscar paquetesโฆ
+code_search_unavailable = La bรบsqueda de cรณdigo no estรก disponible actualmente. Por favor contacta al administrador del sitio.
+code_search_by_git_grep = Los resultados actuales de la bรบsqueda de cรณdigo son proporcionados por "git grep". Es posible que se obtengan mejores resultados si el administrador del sitio habilita el indexador de cรณdigo.
+no_results = No se encontraron resultados coincidentes.
+keyword_search_unavailable = La bรบsqueda por palabra clave no estรก disponible actualmente. Por favor contacta al administrador del sitio.
+fuzzy_tooltip = Incluir resultados que tambiรฉn coincidan estrechamente con el tรฉrmino de bรบsqueda
+milestone_kind = Buscar hitosโฆ
+pull_kind = Buscar extraccionesโฆ
+union = Uniรณn
+union_tooltip = Incluir resultados correspondientes a cualquiera de las palabras clave separadas por espacios en blanco
+exact = Exacto
+exact_tooltip = Incluir sรณlo los resultados que corresponden al tรฉrmino de bรบsqueda exacto
+issue_kind = Buscar incidenciasโฆ
+fuzzy = Difusa
+runner_kind = Buscar corredoresโฆ
+regexp_tooltip = Interpretar los tรฉrminos de bรบsqueda como una expresiรณn regular
+regexp = Expresiรณn Regular
+
+[markup]
+filepreview.lines = Lรญneas %[1]d a %[2]d en %[3]s
+filepreview.line = Lรญnea %[1]d en %[2]s
+
+filepreview.truncated = La vista previa se ha truncado
+
+[repo.permissions]
+pulls.read = Lectura: Leer y crear pull requests.
+releases.write = Write: Publicar, editar y eliminar lanzamientos y sus archivos.
+packages.read = Lectura: Ver y descargar paquetes asignados al repositorio.
+wiki.read = Lectura: Leer la wiki integrada y su historial.
+issues.read = Lectura: Leer y crear incidencias y comentarios.
+pulls.write = Escritura: Cerrar solicitudes de incorporaciรณn de cambios y gestionar metadatos como etiquetas, hitos, asignaciones, fechas de vencimiento y dependencias.
+releases.read = Lectura: Ver y descagar lanzamientos.
+wiki.write = Escritura: Crear, actualizar y eliminar pรกginas en la wiki integrada.
+projects.read = Lectura: Acceso a las tablas de proyecto del repositorio.
+projects.write = Escritura: Crear proyectos y columnas y editarlos.
+ext_issues = Acceder al enlace del getsor de incidencias externo. Los permisos se gestionan de forma externa.
+code.read = Lectura: Acceso y clonar el codigo del repositorio.
+ext_wiki = Acceder al enlace de la wiki externa. Los permisos se gestionan de forma externa.
+code.write = Escritura: Push al repositorio, crear ramas y tags.
+issues.write = Escritura: Cerrar incidencias y gestion de metadatos como etiquetas, hitos, asignaciones, fechas de vencimiento y dependencias.
+packages.write = Escritura: Publicar y eliminar paquetes asignados al repositorio.
+
+[munits.data]
+b = B
+kib = KiB
+mib = MiB
+gib = GiB
+tib = TiB
+pib = PiB
+eib = EiB
diff --git a/options/locale/locale_et.ini b/options/locale/locale_et.ini
new file mode 100644
index 0000000000..e54ceadbb5
--- /dev/null
+++ b/options/locale/locale_et.ini
@@ -0,0 +1,318 @@
+[common]
+tracked_time_summary = Kokkuvรตte jรคlgitavast ajast, mis pรตhineb probleemide nimekirja filtritel
+your_settings = Seaded
+home = Avaleht
+dashboard = Armatuurlaud
+explore = Uurige
+help = Abi
+logo = Logo
+sign_in = Logi sisse
+sign_in_with_provider = Logi sisse koos %s
+sign_in_or = vรตi
+sign_out = Registreeru vรคlja
+sign_up = Registreeru
+link_account = Lingi konto
+register = Registreeru
+version = Versioon
+page = Lehekรผlg
+template = Mall
+language = Keel
+notifications = Teated
+active_stopwatch = Aktiivne aja jรคlgimine
+create_new = Looโฆ
+user_profile_and_more = Profiil ja seadedโฆ
+signed_in_as = Sisselogitud kui
+enable_javascript = See veebileht nรตuab JavaScripti.
+toc = Sisukord
+licenses = Litsentsid
+username = Kasutajanimi
+webauthn_error_unable_to_process = Server ei saanud teie taotlust tรถรถdelda.
+webauthn_error_duplicated = Turvalisuse vรตti ei ole selle taotluse puhul lubatud. Palun veenduge, et vรตti ei ole juba registreeritud.
+return_to_forgejo = Tagasi Forgejo'sse
+toggle_menu = Lรผlitage menรผรผ
+more_items = Rohkem esemeid
+email = E-posti aadress
+password = Parool
+access_token = Juurdepรครคsutรคhis
+re_type = Kinnita parool
+twofa = Kahefaktoriline autentimine
+twofa_scratch = Kahefaktoriline kriipsukood
+passcode = Passkood
+webauthn_insert_key = Sisestage oma turvavรตti
+webauthn_sign_in = Vajutage turvavรตtme nuppu. Kui teie turvavรตtmel ei ole nuppu, sisestage see uuesti.
+webauthn_press_button = Palun vajutage turvavรตtme nuppuโฆ
+webauthn_use_twofa = Kasutage oma telefonist kahefaktorilist koodi
+webauthn_error = Teie turvavรตti ei saanud lugeda.
+webauthn_unsupported_browser = Teie brauser ei toeta praegu WebAuthn.
+webauthn_error_unknown = Tekkis tundmatu viga. Palun proovige uuesti.
+webauthn_error_insecure = WebAuthn toetab ainult turvalisi รผhendusi. HTTP kaudu testimiseks vรตite kasutada pรคritolu "localhost" vรตi "127.0.0.1"
+webauthn_error_empty = Sellele vรตtmele tuleb mรครคrata nimi.
+webauthn_error_timeout = Ajakatkestus saavutati enne vรตtme lugemist. Palun laadige see lehekรผlg uuesti ja proovige uuesti.
+repository = Hoidla
+organization = Organisatsioon
+new_fork = Uus hoidla haru
+new_project = Uus projekt
+new_project_column = Uus veerg
+admin_panel = Saidi administreerimine
+settings = Seaded
+your_profile = Profiil
+your_starred = Tรคhistatud tรคrniga
+new_repo.title = Uus hoidla
+new_migrate.title = Uus sisserรคnne
+new_org.title = Uus organisatsioon
+new_repo.link = Uus hoidla
+new_migrate.link = Uus sisserรคnne
+new_org.link = Uus organisatsioon
+all = Kรตik
+sources = Allikad
+mirror = Peegelpilt
+mirrors = Peegelpildid
+forks = Harud
+activities = Tegevused
+pull_requests = Tรตmbepรคringud
+issues = Probleemid
+milestones = Verstapostid
+ok = OK
+cancel = Tรผhista
+retry = Proovi uuesti
+rerun = Kรคivita uuesti
+save = Salvesta
+add = Lisa
+add_all = Lisa kรตik
+remove = Eemalda
+remove_all = Eemalda kรตik
+remove_label_str = Eemalda รผhik "%s"
+edit = Redigeeri
+view = Vaata
+test = Test
+enabled = Vรตimaldatud
+disabled = Vรคlja lรผlitatud
+locked = Lukkus
+copy = Kopeeri
+copy_url = Kopeeri URL
+copy_hash = Kooperi hash
+copy_content = Kopeeri sisu
+copy_branch = Kopeeri haru nimi
+copy_success = Kopeeritud!
+copy_error = Kopeerimine ebaรตnnestus
+copy_type_unsupported = Seda failitรผรผpi ei saa kopeerida
+write = Kirjuta
+preview = Eelvaade
+loading = Laadimineโฆ
+error = Viga
+error404 = Lehekรผlge, millele te รผritate jรตuda, kas ei ole olemas vรตi teil ei ole รตigust seda vaadata.
+error413 = Sa oled oma kvoodi ammendanud.
+go_back = Mine tagasi
+invalid_data = Kehtetud andmed: %v
+never = Mitte kunagi
+unknown = Teadmata
+rss_feed = RSS infovoog
+confirm_delete_artifact = Kas oled kindel et soovite artefakti "%s" kustutada?
+pin =
+artifacts = Artefaktid
+archived = Arhiveeritud
+concept_system_global = รlemaailmne
+concept_user_individual = Individuaalne
+concept_code_repository = Hoidla
+concept_user_organization = Organisatsioon
+show_timestamps = Nรคita ajatemplid
+show_log_seconds = Nรคita sekundit
+download_logs = Logide allalaadimine
+name = Nimi
+value = Vรครคrtus
+filter = Filter
+filter.clear = Tรผhjendage filtrid
+filter.is_archived = Arhiveeritud
+filter.not_archived = Mitte arhiveeritud
+filter.is_fork = Harud
+filter.not_fork = Mitte harud
+filter.is_mirror = Peegelpiltid
+filter.not_mirror = Mitte peegelpiltid
+filter.is_template = Mallid
+filter.not_template = Mitte Mallid
+filter.public = Avalik
+filter.private = Privaatne
+rerun_all = Kรคivita uuesti kรตik tรถรถd
+new_mirror = Uus peegelpilt
+copy_generic = Kopeeri lรตikelauale
+confirm_delete_selected = Kinnitage et kustutada kรตik valitud elemendid?
+show_full_screen = Nรคita tรคisekraanil
+
+[search]
+search = Otsi...
+fuzzy = Hรคgus
+fuzzy_tooltip = Lisage tulemused mis vastavad ka otsingu terminile
+union = Mรคrksรตnad
+exact = Tรคpne
+exact_tooltip = Sisaldab ainult tulemusi mis vastavad tรคpsele otsingusรตnale
+repo_kind = Otsi hoidlad...
+user_kind = Otsi kasutajaid...
+org_kind = Otsi organisatsioone...
+team_kind = Otsi meeskonnad...
+code_kind = Otsi koodi...
+code_search_by_git_grep = Praeguse koodi otsingu tulemused annab "git grep". Paremaid tulemusi vรตib saada, kui saidi administraator lubab koodi indekseerija.
+package_kind = Otsi pakette...
+project_kind = Otsi projekte...
+branch_kind = Otsi harusid...
+commit_kind = Otsi kommiteid...
+runner_kind = Otsi jooksjaid...
+no_results = Sobivaid tulemusi ei leitud.
+issue_kind = Otsi probleeme...
+milestone_kind = Otsi verstapostid...
+type_tooltip = Otsingu tรผรผp
+code_search_unavailable = Koodide otsing ei ole praegu saadaval. Palun vรตtke รผhendust saidi administraatoriga.
+union_tooltip = Sisaldab tulemused mis vastavad mis tahes tรผhikutega eraldatud vรตtmesรตnadele
+keyword_search_unavailable = Otsing mรคrksรตna jรคrgi ei ole praegu saadaval. Palun vรตtke รผhendust saidi administraatoriga.
+pull_kind = Otsi tรตmbepรคringuid...
+
+[aria]
+navbar = Navigatsiooniriba
+footer.software = Selle tarkvara kohta
+footer.links = Lingid
+
+[heatmap]
+number_of_contributions_in_the_last_12_months = %s panused viimase 12 kuu jooksul
+contributions_zero = Panused ei ole
+contributions_format = {contributions} {day} {month}, {year}
+contributions_few = panused
+less = Vรคhem
+more = Rohkem
+contributions_one = panus
+
+[editor]
+buttons.heading.tooltip = Lisa pealkiri
+buttons.italic.tooltip = Lisa kursiivne tekst
+buttons.quote.tooltip = Tsitaadi tekst
+buttons.code.tooltip = Lisa kood
+buttons.link.tooltip = Lisa link
+buttons.list.ordered.tooltip = Lisa nummerdatud nimekiri
+buttons.list.unordered.tooltip = Lisa nimekiri
+buttons.list.task.tooltip = Lisa รผlesannete nimekiri
+buttons.ref.tooltip = Viide probleemile vรตi tรตmbepรคringule
+buttons.switch_to_legacy.tooltip = Kasutage selle asemel pรคrandredaktorit
+buttons.enable_monospace_font = Vรตimalda pรผsisammkiri
+buttons.disable_monospace_font = Lรผlita vรคlja pรผsisammkiri
+buttons.indent.tooltip = Pesa esemed รผhe taseme vรตrra
+buttons.bold.tooltip = Lisa rasvane tekst
+buttons.mention.tooltip = Mainige kasutajat vรตi meeskonda
+
+[filter]
+string.asc = A - Z
+string.desc = Z - A
+
+[error]
+occurred = Tekkis viga
+invalid_csrf = Halb taotlus: vigane CSRF token
+not_found = Sihtmรคrki ei leitud.
+network_error = Vรตrguviga
+server_internal = Sisemine serveri viga
+report_message = Kui usute et tegemist on Forgejo veaga siis otsige probleeme Codebergist vรตi avage vajadusel uus probleem.
+
+[startpage]
+app_desc = Valutu, isehostitatud Git'i teenus
+install = Lihtne paigaldada
+platform = Platvormiรผlene
+platform_desc = Forgejo on kinnitust leidnud et tรถรถtab nii libre operatsioonisรผsteemides nagu Linux ja FreeBSD, kui ka erinevatel protsessorarhitektuuridel. Valige see mis teile meeldib!
+lightweight = Kergekaaluline
+lightweight_desc = Forgejo on vรคikeste miinimumnรตuetega ja seda saab kasutada odaval Raspberry Pi'l. Sรครคsta oma masina energiat!
+license = Avatud lรคhtekood
+install_desc = Lihtsalt kรคivitage oma platvormi binaarsรผsteem , tarnige see koos Dockeriga , vรตi saada see pakendatud .
+license_desc = Mine vรตta Forgejo ! Liitu meiega andes oma panuse et muuta see projekt veelgi paremaks. รrge hรคbenege olla kaasaaitaja!
+
+[install]
+install = Paigaldamine
+title = Esialgne konfiguratsioon
+docker_helper = Kui kรคivitate Forgejo't Dockeri sees, lugege dokumentatsiooni enne seadete muutmine.
+require_db_desc = Forgejo vajab MySQL, PostgreSQL, SQLite3 vรตi TiDB (MySQL protokoll).
+db_title = Andmebaasi seaded
+db_type = Andmebaasi tรผรผp
+host = Vastuvรตtja
+user = Kasutajanimi
+password = Parool
+db_name = Andmebaasi nimi
+db_schema = Skeem
+db_schema_helper = Jรคta tรผhjaks andmebaasi vaikimisi ("avalik").
+ssl_mode = SSL
+path = Tee
+sqlite_helper = SQLite3 andmebaasi failitee. Sisestage absoluutne tee, kui kรคivitate Forgejo't teenusena.
+reinstall_error = Sa รผritad installeerida olemasolevasse Forgejo andmebaasi
+reinstall_confirm_message = Olemasoleva Forgejo andmebaasi uuesti paigaldamine vรตib pรตhjustada mitmeid probleeme. Enamasti peaksite Forgejo kรคivitamiseks kasutama olemasolevat "app.ini". Kui te teate, mida teete, kinnitage jรคrgmist:
+reinstall_confirm_check_1 = Andmed, mis on krรผpteeritud SECRET_KEY'ga app.ini's, vรตivad kaduda: kasutajad ei pruugi saada 2FA/OTP-ga sisse logima ja peegelpiltid ei pruugi รตigesti toimida. Selle kasti mรคrkimisega kinnitate, et praegune app.ini fail sisaldab รตiget SECRET_KEY'd.
+reinstall_confirm_check_3 = Te kinnitate, et olete tรคiesti kindel, et see Forgejo tรถรถtab รตiges app.ini asukohas ja et olete kindel, et peate uuesti installima. Te kinnitate, et tunnistate รผlaltoodud riske.
+err_empty_db_path = SQLite3 andmebaasi tee ei saa olla tรผhi.
+no_admin_and_disable_registration = Kasutajate iseregistreerimist ei saa keelata ilma administraatori kontot loomata.
+err_empty_admin_password = Administraatori parool ei saa olla tรผhi.
+err_empty_admin_email = Administraatori e-posti aadress ei saa olla tรผhi.
+err_admin_name_is_reserved = Administraatori kasutajanimi on kehtetu, kasutajanimi on reserveeritud
+err_admin_name_pattern_not_allowed = Administraatori kasutajanimi on kehtetu, kasutajanimi vastab reserveeritud mustrile
+err_admin_name_is_invalid = Administraatori kasutajanimi on kehtetu
+general_title = รldised seaded
+app_name = Instantsi pealkiri
+app_name_helper = Sisestage siia oma instantsi nimi. See kuvatakse igal lehekรผljel.
+app_slogan = Instantse loosung
+repo_path = Hoidla juurte tee
+lfs_path = Git LFS'i juurte tee
+lfs_path_helper = Failid jรคlgitatud Git LFS'ist salvestatakse sellesse kaustale. Jรคtke tรผhjaks et vรคlja lรผlitada.
+run_user = Kasutaja kellena kรคivitada
+run_user_helper = Operatsioonisรผsteemi kasutajanimi, mille all Forgejo tรถรถtab. Pange tรคhele, et sellel kasutajal peab olema juurdepรครคs hoidlate juurte teele.
+domain = Serveri domeen
+domain_helper = Serveri domeen vรตi hostiaadress.
+ssh_port = SSH-serveri port
+ssh_port_helper = Pordi number, mida SSH-server kasutab. Jรคtke tรผhjaks et vรคlja lรผlitada SSH-serveri.
+http_port = HTTP-kuulamise port
+http_port_helper = Pordi number, mida Forgejo veebiserver kasutab.
+app_url = Baasi URL
+app_url_helper = Baasaadress HTTP(S) kloonimise URL-ide ja e-posti teadete jaoks.
+log_root_path = Logi tee
+log_root_path_helper = Logifailid kirjutatakse sellesse kaustale.
+optional_title = Vabatahtlikud seaded
+email_title = E-posti seaded
+smtp_addr = SMTP vastuvรตtja
+smtp_port = SMTP port
+smtp_from = Saada e-kirjad nagu
+smtp_from_invalid = "Saada e-kirjad nagu" aadress on kehtetu
+smtp_from_helper = E-posti aadress, mida Forgejo kasutab. Sisestage tavaline e-posti aadress vรตi kasutage formaati "Nimi" .
+mailer_user = SMTP kasutajanimi
+mailer_password = SMTP parool
+register_confirm = Registreerimiseks on vaja e-posti kinnitust
+mail_notify = Lubage e-posti teated
+server_service_title = Serveri ja kolmanda osapoole teenuste seaded
+offline_mode = Lรผlita sisse lokaalse reลพiimi
+disable_gravatar = Lรผlita vรคlja Gravatar
+federated_avatar_lookup = Lรผlita sisse fรถderaalsed avatarid
+federated_avatar_lookup.description = Otsige avatare kasutades Libravatar'i.
+disable_registration = Lรผlita vรคlja iseregistreerimine
+allow_only_external_registration = Luba registreerimine ainult vรคliste teenuste kaudu
+allow_only_external_registration.description = Kasutajad saavad uusi kontosid luua ainult seadistatud vรคliste teenuste abil.
+openid_signin = Lรผlita sisse OpenID sisselogimise
+openid_signin.description = Luba kasutajatel OpenID kaudu sisse logida.
+openid_signup = Lรผlita sisse OpenID iseregistreerimine
+enable_captcha = Lรผlita sisse registreerimise CAPTCHA
+enable_captcha.description = Nรตudke kasutajatelt CAPTCHA lรคbimist kontode loomiseks.
+require_sign_in_view = Nรตua sisselogimist et vaadata instantsi sisu
+default_keep_email_private = Peida e-posti aadressid vaikimisi
+default_keep_email_private.description = Lรผlita sisse uute kasutajate e-posti aadressi varjamine vaikimisi, et see teave ei lekiks kohe pรคrast registreerimist.
+default_allow_create_organization = Lubada organisatsioonide loomine vaikimisi
+default_enable_timetracking = Aja jรคlgimise sisselรผlitamine vaikimisi
+default_enable_timetracking.description = Lubage uute repositooriumide jaoks vaikimisi aja jรคlgimise funktsiooni kasutamine.
+admin_title = Administraatori konto seaded
+admin_setting.description = Administraatori konto loomine on vabatahtlik. Esimesest registreeritud kasutajast saab automaatselt administraator.
+admin_name = Administraatori kasutajanimi
+admin_password = Parool
+confirm_password = Parooli kinnitamine
+admin_email = E-posti aadress
+config_location_hint = Need konfiguratsioonivalikud salvestatakse sees:
+install_btn_confirm = Paigalda Forgejo
+test_git_failed = Ei saanud testida kรคsku "git": %v
+invalid_db_setting = Andmebaasi seaded on vigased: %v
+invalid_db_table = Andmebaasi tabel "%s" on vigane: %v
+allow_dots_in_usernames = Luba kasutajatel kasutada oma kasutajanimedes punkte. Ei mรตjuta olemasolevaid kontosid.
+default_allow_create_organization.description = Lubage uutel kasutajatel vaikimisi luua organisatsioone. Kui see valik on vรคlja lรผlitatud, peab administraator andma uutele kasutajatele organisatsioonide loomise loa.
+disable_gravatar.description = Lรผlita vรคlja Gravatari vรตi muude kolmandate osapoolte avatariallikate kasutamine. Kasutajate avatarite jaoks kasutatakse vaikimisi pilte, kui nad ei lae oma avatari รผles.
+openid_signup.description = Luba kasutajatel luua kontosid OpenID kaudu, kui iseregistreerimine on sisse lรผlitatud.
+require_sign_in_view.description = Piirake sisule juurdepรครคsu sisselogitud kasutajatele. Kรผlalised saavad kรผlastada ainult autentimislehti.
+reinstall_confirm_check_2 = Hoidlad ja seadeid vรตib olla vaja uuesti sรผnkroniseerida. Selle kasti mรคrkimisega kinnitate, et sรผnkroniseerite hoidlate ja authorized_keys'i faili konksud kรคsitsi uuesti. Te kinnitate, et tagate, et hoidlate ja peegelpilti seaded on รตiged.
+app_slogan_helper = Sisestage siia oma loosung. Jรคtke tรผhjaks, et vรคlja lรผlitada.
+repo_path_helper = Kauged Git-hoidlad salvestatakse sellesse kaustale.
+sqlite3_not_available = See Forgejo versioon ei toeta SQLite3. Palun laadige alla ametlik binaarversioon %s (mitte "gobuild"i versioon).
+offline_mode.description = Lรผlitage kolmandate osapoolte sisu edastamise vรตrgud vรคlja ja teenindage kรตiki ressursse lokaalselt.
\ No newline at end of file
diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini
index 9192116d06..6b6a530639 100644
--- a/options/locale/locale_fa-IR.ini
+++ b/options/locale/locale_fa-IR.ini
@@ -15,9 +15,9 @@ page=ุตูุญู
template=ูุงูุจ
language=ุฒุจุงู
notifications=ุงุนูุงูโูุง
-active_stopwatch=ูุนุงู ฺฉุฑุฏู ุซุจุช ุฒู
ุงู
+active_stopwatch=ูุนุงู ฺฉุฑุฏู ุฑุฏุงุจ ุฒู
ุงู
create_new=ุงุฌุงุฏโฆ
-user_profile_and_more=ูพุฑููุงู ู ุชูุธู
ุงุชโฆ
+user_profile_and_more=ูู
ุงู ู ุชูุธู
ุงุชโฆ
signed_in_as=ูุฑูุฏ ุจู ุนููุงู
toc=ููุฑุณุช ู
ุญุชูุงุช
licenses=ฺฏูุงููุงู
ู ูุง
@@ -26,11 +26,11 @@ return_to_forgejo=ุจุงุฒฺฏุดุช ุจู Forgejo
username=ูุงู
ฺฉุงุฑุจุฑ
email=ูุดุงู ุฑุงุงูุงู
ู
password=ุฑู
ุฒ ุนุจูุฑ
-access_token=ฺุชูู ุฏุณุชุฑุณ
+access_token=ุชฺูฉู ุฏุณุชุฑุณ
re_type=ุชุฃุฏ ฺฏุฐุฑูุงฺู
captcha=ฺฉูพฺุง
twofa=ุงุญุฑุงุฒ ููุช ุฏู ู
ุฑุญููโุง
-twofa_scratch=ฺฉุฏ ุงุญุฑุงุฒ ููุช
+twofa_scratch=ฺฉุฏ ุงุญุฑุงุฒ ููุช ุฏู ู
ุญูู ุง
passcode=ุฑู
ุฒ ุนุจูุฑ
@@ -40,7 +40,7 @@ mirror=ูุฑูู
new_repo=ู
ุฎุฒู ุฌุฏุฏ
new_migrate=ุงูุชูุงู ุฌุฏุฏ
new_mirror=ุขูู ุฌุฏุฏ
-new_fork=ุงูุดุนุงุจ ู
ุฎุฒู ุฌุฏุฏ
+new_fork=ุงูุดุนุงุจ ุฌุฏุฏ ุงุฒ ู
ุฎุฒู
new_org=ุณุงุฒู
ุงู ุฌุฏุฏ
new_project=ูพุฑฺูู ุฌุฏุฏ
manage_org=ู
ุฏุฑุช ุณุงุฒู
ุงูโูุง
@@ -85,7 +85,7 @@ preview=ูพุด ูู
ุงุด
loading=ุจุงุฑฺฏุฐุงุฑโฆ
error=ุฎุทุง
-error404=ุตูุญู ู
ูุฑุฏูุธุฑ ุดู
ุง ุง ูุฌูุฏ ูุฏุงุฑุฏ ุง ุดู
ุง ุฏุณุชุฑุณ ฺฉุงู ุจุฑุง ู
ุดุงูุฏู ุขู ุฑุง ูุฏุงุฑุฏ.
+error404=ุตูุญู ู
ูุฑุฏูุธุฑ ฺฉู ุดู
ุง ุชูุงุด ุฏุงุฑุฏ ุจู ุขู ุฏุณุชุฑุณ ูพุฏุง ฺฉูุฏ ูุฌูุฏ ูุฏุงุฑุฏ ุง ุญุฐู ุดุฏู ุงุณุช ุง ุดู
ุง ุฏุณุชุฑุณ ฺฉุงู ุจุฑุง ู
ุดุงูุฏู ุขู ุฑุง ูุฏุงุฑุฏ.
never=ูุฑฺฏุฒ
@@ -112,45 +112,139 @@ new_project_column = ุณุชูู ุฌุฏุฏ
retry = ุณุน ุฏูุจุงุฑู
rerun = ุงุฌุฑุง ุฏูุจุงุฑู
rerun_all = ุงุฌุฑุง ุฏูุจุงุฑู ุชู
ุงู
ฺฉุงุฑูุง
-rss_feed = ุฎูุฑุงฺฉ RSS
+rss_feed = ุฎูุฑุงฺฉ ุขุฑุงุณโุงุณ
pin = ุณูุฌุงู
-unpin = ุญุฐู ุณูุฌุงู
+unpin = ุจุฑุฏุงุดุชู ุณูุฌุงู
locked = ููู ุดุฏู
copy_hash = ุฑูููุดุช ูุด
unknown = ูุงู
ุดุฎุต
-copy_type_unsupported = ุงู ููุน ุงุฒ ูุงู ูู
โุชูุงูุฏ ุฑูููุดุช ุดูุฏ.
+copy_type_unsupported = ุงู ููุน ุงุฒ ูุงู ูู
โุชูุงูุฏ ุฑูููุดุช ุดูุฏ
+webauthn_insert_key = ฺฉูุฏ ุงู
ูุช ุฎูุฏ ุฑุง ูุงุฑุฏ ฺฉูุฏ
+webauthn_sign_in = ุฏฺฉู
ุฑู ฺฉูุฏ ุงู
ูุช ุฑุง ูุดุงุฑ ุฏูุฏ. ุงฺฏุฑ ฺฉูุฏ ุงู
ูุช ุดู
ุง ุฏฺฉู
ูโุง ูุฏุงุฑุฏุ ุขู ุฑุง ุฏูุจุงุฑู ูุงุฑุฏ ฺฉูุฏ.
+webauthn_use_twofa = ุงุฒ ฺฉ ฺฉุฏ ุฏูู
ุฑุญููโุง ุงุฒ ุชูููุชุงู ุงุณุชูุงุฏู ฺฉูุฏ
+webauthn_error = ฺฉูุฏ ุงู
ูุช ุดู
ุง ูุชูุงูุณุช ุฎูุงูุฏู ุดูุฏ.
+more_items = ู
ูุงุฑุฏ ุจุดุชุฑ
+webauthn_error_duplicated = ฺฉูุฏ ุงู
ูุช ุจุฑุง ุงู ุฏุฑุฎูุงุณุช ู
ุฌุงุฒ ูุณุช. ูุทูุงู ู
ุทู
ุฆู ุดูุฏ ฺฉู ุงู ฺฉูุฏ ุฏุฑ ุญุงู ุญุงุถุฑ ุซุจุช ูุดุฏู ุงุณุช.
+webauthn_error_timeout = ู
ููุช ุฒู
ุงู ูุจู ุงุฒ ุงฺูฉู ฺฉูุฏ ุดู
ุง ุฎูุงูุฏู ุดูุฏ ุชู
ุงู
ุดุฏ. ูุทูุงู ุงู ุตูุญู ุฑุง ุชุงุฒูโุณุงุฒ ฺฉุฑุฏู ู ู
ุฌุฏุฏ ุชูุงุด ฺฉูุฏ.
+new_org.link = ุณุงุฒู
ุงู ุฌุฏุฏ
+new_org.title = ุณุงุฒู
ุงู ุฌุฏุฏ
+new_migrate.link = ู
ูุงุฌุฑุช ุฌุฏุฏ
+webauthn_error_empty = ุดู
ุง ุจุงุฏ ฺฉ ูุงู
ุจุฑุง ุงู ฺฉูุฏ ุงูุชุฎุงุจ ฺฉูุฏ.
+new_repo.title = ู
ุฎุฒู ุฌุฏุฏ
+new_migrate.title = ู
ูุงุฌุฑุช ุฌุฏุฏ
+new_repo.link = ู
ุฎุฒู ุฌุฏุฏ
+
+filter = ููุชุฑ
+filter.is_archived = ุจุงฺฏุงู ุดุฏู
+filter.public = ุนู
ูู
+filter.private = ุฎุตูุต
+tracked_time_summary = ฺฺฉุฏูโุง ุงุฒ ุฒู
ุงู ุฑุฏุงุจโุดุฏู ุจุฑ ุงุณุงุณ ูพุงูุงูโูุง ููุฑุณุช ู
ุดฺฉูโูุง
+toggle_menu = ุฏฺฏุฑุด ููุฑุณุช
+test = ุขุฒู
ูุฏู
+artifacts = ุขูุงู
+filter.is_fork = ฺฺูฏโูุง
+filter.not_fork = ฺฺูฏ ูุดุฏูโูุง
+filter.not_template = ุจุฏูู ฺฉุงูุจุฏโูุง
+copy_path = ุฑูููุดุช ู
ุณุฑ
+confirm_delete_artifact = ุขุง ู
ุทู
ุฆู ูุณุชุฏ ฺฉู ู
โุฎูุงูุฏ ุขูุงู ยซ %s ยป ุฑุง ุญุฐู ฺฉูุฏุ
+concept_system_global = ุณุฑุงุณุฑ
+show_timestamps = ูู
ุงุด ุจุฑฺุณุจโุฒู
ุงู
+show_full_screen = ูู
ุงุด ุชู
ุงู
ุตูุญู
+download_logs = ุจุงุฑฺฏุฑ ูุงูุนูโฺูฏุงุฑ
+value = ุงุฑุฒุด
+filter.is_mirror = ุขููโูุง
+filter.not_mirror = ูุง ุขูู
+filter.is_template = ฺฉุงูุจุฏโูุง
+error413 = ุดู
ุง ุณูู
ู ุฎูุฏ ุฑุง ุชู
ุงู
ฺฉุฑุฏูโุงุฏ.
+concept_user_individual = ุชฺฉ
+filter.not_archived = ุจุงฺฏุงู ูุดุฏู
+copy_content = ุฑูููุดุช ุฏุฑููโู
ุงู
+invalid_data = ุฏุงุฏู ูุงู
ุนุชุจุฑ: %v
+copy_generic = ุฑูููุดุช ุฏุฑ ุจุฑุฏูโุฏุงู
+webauthn_error_insecure = ุงุญุฑุงุฒูุจ ููุท ุงุฒ ุฑูุดโูุง ุงู
ู ู
ู
ฺฉู ุงุณุช. ุจุฑุง ุขุฒู
ูุฏู ุจุฑ ุฑู ุงฺโุชโุชโูพ ู
โุชูุงูุฏ ุงุฒ ยซู
ุฒุจุงูโู
ุญูยป ุง ยซฑฒท.ฐ.ฐ.ฑยป ุงุณุชูุงุฏู ฺฉูุฏ.
+show_log_seconds = ูู
ุงุด ุซุงููโูุง
+confirm_delete_selected = ุชุงุฏ ู
โฺฉูุฏ ฺฉู ูู
ู ู
ูุงุฑุฏ ฺฏุฒูุด ุดุฏู ุญุฐู ุดููุฏุ
+filter.clear = ูพุงฺฉโฺฉุฑุฏู ูพุงูุงูโูุง
+go_back = ุจุงุฒฺฏุดุช
+remove_label_str = ุญุฐู ู
ูุฑุฏ "%s"
+view = ูู
ุง
[aria]
+footer.software = ุฏุฑุจุงุฑู ุงู ูุฑู
โุงูุฒุงุฑ
+navbar = ููุงุฑ ูุงูุจุฑ
+footer.links = ูพููุฏูุง
+footer = ูพุงูุฑู
[heatmap]
+contributions_zero = ุจุฏูู ูู
โฺฉุงุฑ
+contributions_format = {ูู
โฺฉุงุฑ} ุฏุฑ {ุฑูุฒ}{ู
ุงู}{ุณุงู}
+contributions_one = ูู
โฺฉุงุฑ
+contributions_few = ูู
โฺฉุงุฑโูุง
+number_of_contributions_in_the_last_12_months = %s ูู
โฺฉุงุฑ ุฏุฑ ฑฒ ู
ุงู ฺฏุฐุดุชู
+less = ฺฉู
โุชุฑ
+more = ุจุดโุชุฑ
[editor]
+buttons.list.ordered.tooltip = ุงูุฒูุฏู ฺฉ ููุฑุณุช ุดู
ุงุฑูโุฏุงุฑ
+buttons.ref.tooltip = ุงุดุงุฑู ุจู ู
ุดฺฉู ุง ุฏุฑุฎูุงุณุช ูุงฺฉุด
+table_modal.header = ุงูุฒูุฏู ุฌุฏูู
+table_modal.placeholder.header = ุณุฑุขูุฏ
+table_modal.placeholder.content = ู
ุญุชูุง
+table_modal.label.rows = ุฑุฏูโูุง
+table_modal.label.columns = ุณุชููโูุง
+buttons.unindent.tooltip = ุงุฌุฒุง ุฑุง ุจุง ฺฉ ุณุทุญ ฺฏุฑููโุจูุฏ ฺูฉู
+buttons.indent.tooltip = ุงุฌุฒุง ุฑุง ุจุง ฺฉ ุณุทุญ ฺฏุฑููโุจูุฏ ฺฉู
+buttons.bold.tooltip = ุงูุฒูุฏู ู
ุชู ุฏุฑุดุช
+buttons.quote.tooltip = ุงูุฒูุฏู ูููโููู
+buttons.link.tooltip = ุงูุฒูุฏู ฺฉ ูพููุฏ
+buttons.list.unordered.tooltip = ุงูุฒูุฏู ฺฉ ููุฑุณุช ููุทูโุง
+buttons.heading.tooltip = ุงูุฒูุฏู ุณุฑุตูุญู
+buttons.italic.tooltip = ุงูุฒูุฏู ู
ุชู ฺฉุฌ
+buttons.disable_monospace_font = ูููุช ฺฉูพุงุฑฺู ุฑุง ุบุฑูุนุงู ฺฉู
+buttons.enable_monospace_font = ูููุช ฺฉูพุงุฑฺู ุฑุง ูุนุงู ฺฉู
+buttons.list.task.tooltip = ุงูุฒูุฏู ฺฉ ููุฑุณุช ฺฉุงุฑูุง
+buttons.new_table.tooltip = ุงูุฒูุฏู ุฌุฏูู
+buttons.mention.tooltip = ุงุฏฺฉุฑุฏู ุงุฒ ฺฉุงุฑุจุฑ ุง ฺฏุฑูู
+buttons.switch_to_legacy.tooltip = ุจู ุฌุง ุขู ุงุฒ ูุฑุงุดโฺฏุฑ ฺฉูููโุชุฑ ุงุณุชูุงุฏู ฺฉู
+buttons.code.tooltip = ุงูุฒูุฏู ฺฉุฏ
+link_modal.header = ุงูุฒูุฏู ูพููุฏ
+link_modal.url = ูุขุฑุงู
+link_modal.paste_reminder = ุฑุงููู
ุง: ุจุง ุฏุงุดุชู ฺฉ ูุขุฑุงู ุฏุฑ ุจุฑุฏูโโุฏุงูุ ู
โุชูุงูุฏ ุจุง ุฑูููุดุช ู
ุณุชูู
ุขู ุฏุฑ ูุฑุงุดโฺฏุฑุชุงู ฺฉ ูพููุฏ ุจุณุงุฒุฏ.
+link_modal.description = ุฏุจุงฺู
[filter]
+string.asc = ุข -
+string.desc = - ุข
[error]
missing_csrf=ุฏุฑุฎูุงุณุช ุจุฏ: ุจูุท CSRF ูุฏุงุฑุฏ
+not_found = ูุฏู ุฑุง ูู
โุชูุงู ุงูุช.
+network_error = ุฎุทุง ุดุจฺฉู
+report_message = ุงฺฏุฑ ฺฏู
ุงู ู
โุจุฑุฏ ุงู ุงุดฺฉุงู ุงุฒ ููุฑุฌุฌู ุงุณุชุ ูุทูุง ุฏุฑ ู
ุดฺฉูุงุช ุฏุฑ ฺฉุฏุจุฑฺฏ ุฑุง ุจฺฏุฑุฏุฏ ุง ุงฺฏุฑ ูุงุฒู
ุงุณุช ฺฉ ู
ุดฺฉู ุจุงุฒ ฺฉูุฏ.
+occurred = ุฎุทุง ุฑุฎ ุฏุงุฏ
+server_internal = ุฎุทุง ุฏุฑูู ฺฉุงุฑุณุงุฒ
[startpage]
app_desc=ฺฉ ุณุฑูุณ ฺฏุช ุจโุฏุฑุฏ ุณุฑ ู ุฑุงุญุช
install=ุฑุงูโุงูุฏุงุฒ ุณุงุฏู
platform=ู
ุณุชูู ุงุฒ ุณฺฉู
-platform_desc=ฺฏุช ูู
ู ุฌุง ุงุฌุฑุง ู
โุดูุฏ ุจุฑู
! ู
โุชูุงูุฏ Windows, macOS, Linux, ARM ู ... ูุฑ ฺฉุฏุงู
ุฑุง ุฏูุณุช ุฏุงุดุชุฏ ุงูุชุฎุงุจ ฺฉูุฏ!
lightweight=ุงุจุฒุงุฑฺฉ ุณุจฺฉ
lightweight_desc=ฺฏุช ุจุง ุญุฏุงูู ู
ูุงุจุน ู
ุชูุงูุฏ ุจุฑุง ุฑู ุฏุณุชฺฏุงู Raspberry Pi ุงุฌุฑุง ุดูุฏ ู ู
ุตุฑู ุงูุฑฺ ุดู
ุง ุฑุง ฺฉุงูุด ุฏูุฏ!
license=ู
ุชู ุจุงุฒ
-license_desc=ุจุฑู ุจู Forgejo ! ุจู ู
ูุญู ุดูุฏ ุจุง ู
ุดุงุฑฺฉุช ฺฉุฑุฏู ุจุฑุง ุงู ฺฉู ุงู ูพุฑฺูู ุจูุชุฑ ุดูุฏ. ุจุฑุง ู
ุดุงุฑฺฉุช ฺฉุฑุฏู ุฎุฌุงูุช ฺูฉุดุฏ!
+license_desc=ุจุฑู ุจู Forgejo ! ุจู ู
ูุญู ุดูุฏ ุจุง ู
ุดุงุฑฺฉุช ฺฉุฑุฏู ุจุฑุง ุงู ฺฉู ุงู ูพุฑฺูู ุจูุชุฑ ุดูุฏ. ุจุฑุง ู
ุดุงุฑฺฉุช ฺฉุฑุฏู ุฎุฌุงูุช ฺูฉุดุฏ!
+platform_desc = ููุฑุฌุฌู ุจุฑุง ุงุฌุฑุง ุจุฑ ุฑู ุณุงู
ุงููโุนุงู
ูโูุง ุขุฒุงุฏ ู
ุงููุฏ ฺฏูู/ฺูููฉุณ ู ุจโุงุณโุฏ ุขุฒุงุฏ ู ูู
โฺูู ู
ุนู
ุงุฑโูุง ฺฏููุงฺฏูู ูพุฑุฏุงุฒูุฏู ุซุจุงุช ุฏุงุฑุฏ. ูุฑ ฺ ู
ูโุชุงู ูุณุช ุงูุชุฎุงุจ ฺฉูุฏ!
+install_desc = ุจู ุขุณุงู ุงุนุฏุงุฏ ุฏู ุฏู ุฑุง ุจุฑุง ุณฺฉู ุฎูุฏ ุงุฌุฑุง ฺฉูุฏ. ุจุง ุฏุงฺฉุฑ ุขู ุฑุง ุงุฑุณุงู ฺฉูุฏุ ุง ุจุณุชูโุจูุฏ ุชุญูู ุจฺฏุฑุฏ.
[install]
install=ูุตุจ ู ุฑุงู ุงูุฏุงุฒ
-title=ุชูุธู
ุงุช ุงููู
+title=ูพฺฉุฑุจูุฏ ุงููู
docker_helper=ุงฺฏุฑ ฺฏุช ุฑุง ุจุง ุฏุงฺฉุฑ ุงุฌุฑุง ฺฉุฑุฏูโุงุฏุ ูุทูุง ูุจู ุงุฒ ูุฑ ุชุบุฑ ู
ุณุชูุฏุงุช ุฑุง ู
ุทุงูุนู ูู
ุงุฏ.
-db_title=ุชูุธู
ุงุช ูพุงฺฏุงู ุฏุงุฏู
-db_type=ููุน ูพุงฺฏุงู ุฏุงุฏู
+db_title=ุชูุธู
ุงุช ูพุงฺฏุงูโุฏุงุฏู
+db_type=ฺฏููู ูพุงฺฏุงูโุฏุงุฏู
host=ู
ุฒุจุงู
user=ูุงู
ฺฉุงุฑุจุฑ
password=ุฑู
ุฒ ุนุจูุฑ
-db_name=ูุงู
ูพุงฺฏุงู ุฏุงุฏู
+db_name=ูุงู
ูพุงฺฏุงูโุฏุงุฏู
db_schema=ูุงูุจ
db_schema_helper=ุจุฑุง ู
ูุฏุงุฑ ูพุด ูุฑุถ ูพุงฺฏุงู ุฏุงุฏู ุฎุงู ุจฺฏุฐุงุฑุฏ ("public").
ssl_mode=SSL
@@ -165,24 +259,24 @@ err_empty_db_path=ู
ุณุฑ ุฏุชุงุจุณ SQLite3 ูู
ุชูุงูุฏ ุฎุงู ุจุง
no_admin_and_disable_registration=ุดู
ุง ุจุฏูู ุงุฌุงุฏ ุญุณุงุจโ ฺฉุงุฑุจุฑ ู
ุฏุฑ ูู
โุชูุงูุฏ ุนุถูุช ุฑุง ุบุฑ ูุนุงู ฺฉูุฏ.
err_empty_admin_password=ฺฉูู
ู ุนุจูุฑ ุญุณุงุจ ู
ุฏุฑ ูู
ุชูุงูุฏ ุฎุงู ุจุงุดุฏ.
err_empty_admin_email=ุฑุงุงูุงู
ู (ุงู
ู) ู
ุฏุฑ ูู
ุชูุงูุฏ ุฎุงู ุจุงุดุฏ.
-err_admin_name_is_reserved=ูุงู
ฺฉุงุฑุจุฑ ู
ุฏุฑ ุงุดุชุจุงู ุงุณุช. ูุงู
ฺฉุงุฑุจุฑ ูุจูุง ุงุณุชูุงุฏู ุดุฏู ุงุณุช
+err_admin_name_is_reserved=ูุงู
โฺฉุงุฑุจุฑ ู
ุฏุฑ ุงุดุชุจุงู ุงุณุชุ ูุงู
โฺฉุงุฑุจุฑ ูุจูุง ุงุณุชูุงุฏู ุดุฏู ุงุณุช
err_admin_name_pattern_not_allowed=ูุงู
ฺฉุงุฑุจุฑ ู
ุฏุฑ ุงุดุชุจุงู ุงุณุช. ูุงู
ฺฉุงุฑุจุฑ ูุจูุง ุงุณุชูุงุฏู ุดุฏู ุงุณุช
err_admin_name_is_invalid=ูุงู
ฺฉุงุจุฑ ู
ุฏุฑ ุงุดุชุจุงู ุงุณุช
general_title=ุชูุธู
ุงุช ุนู
ูู
-app_name=ุนููุงู ุณุงุช
-app_name_helper=ุดู
ุง ู
ุชูุงูุฏ ูุงู
ุดุฑฺฉุช ุฎูุฏ ุฑุง ุฏุฑ ุงูุฌุง ูุงุฑุฏ ฺฉูุฏ.
+app_name=ุชุชุฑ ูู
ููู
+app_name_helper=ุดู
ุง ู
ุชูุงูุฏ ูุงู
ูู
ููู ุฎูุฏ ุฑุง ุฏุฑ ุงูุฌุง ูุงุฑุฏ ฺฉูุฏ. ุขู ุฏุฑ ูู
ู ุจุฑฺฏูโูุง ุจู ูู
ุงุด ุฏุฑ ุฎูุงูุฏ ุขู
ุฏ.
repo_path=ู
ุณุฑ ุฑุดู ู
ุฎุฒู
repo_path_helper=ุชู
ุงู
ู
ุฎุงุฒู ฺฉุฏ ุฑุงู ุฏูุฑ ุฏุฑ ุงู ูพูุดู ุฐุฎุฑู ู
โุดููุฏ.
-lfs_path=ู
ุณุฑ Git LFS
+lfs_path=ู
ุณุฑ ุฑุดู ุฐุฎุฑูโุณุงุฒ ูพุฑููุฏู ุจุฒุฑฺฏ ฺฏุช
lfs_path_helper=ูุงู ูุง ฺฉู ุชูุณุท Git LFS ุฏูุจุงู ู
ุดููุฏ ุฏุฑ ุงู ูพูุดู ุฐุฎุฑู ุฎูุงููุฏ ุดุฏ. ุฏุฑุตูุฑุช ุฎุงู ุจูุฏู ููุฏ ุงู ูุงุจูุช ุบุฑูุนุงู ุฎูุงูุฏ ุจูุฏ.
-run_user=ุงุฌุฑุง ุจู ุนููุงู ูุงู
ฺฉุงุฑุจุฑ
-domain=ุฏุงู
ูู ุณุฑูุฑ
+run_user=ุงุฌุฑุง ฺฉุงุฑุจุฑ ุจู ุนููุงู
+domain=ุฏุงู
ูู ฺฉุงุฑุณุงุฒ
domain_helper=ุขุฏุฑุณ ู
ุฒุจุงู ุง ุฏุงู
ูู ุจุฑุง ุณุฑูุฑ.
-ssh_port=ูพูุฑุช SSH ุณุฑูุฑ
-ssh_port_helper=ุดู
ุงุฑู ุฏุฑฺฏุงู ฺฉู ุณุฑูุฑ SSH ฺฏูุด ู
ุฏูุฏ. ุจุฑุง ุบุฑ ูุนุงู ฺฉุฑุฏู ุฎุงู ุจฺฏุฐุงุฑุฏ.
-http_port=ูพูุฑุช HTTP ฺฏุช
-http_port_helper=ูพูุฑุช ุณุฑูุฑ ูุจ ฺฏุช.
+ssh_port=ุฏุฑฺฏุงู ฺฉุงุฑุณุงุฒ ูพูุณุชูโุงู
ู
+ssh_port_helper=ุดู
ุงุฑู ุฏุฑฺฏุงู ฺฉู ุณุฑูุฑ ูพูุณุชูโุงู
ู ุงุณุชูุงุฏู ู
โฺฉูุฏ. ุจุฑุง ุบุฑ ูุนุงู ฺฉุฑุฏู ุฎุงู ุจฺฏุฐุงุฑุฏ.
+http_port=ุฏุฑฺฏุงู ุดูููุฏู ุงฺโุชโุชโูพ
+http_port_helper=ุดู
ุงุฑู ุฏุฑฺฏุงู ฺฉู ุชูุณุท ฺฉุงุฑุณุงุฒ ูุจ ูุฑุฌุฌู ุงุณุชูุงุฏู ู
โุดูุฏ.
app_url=ุขุฏุฑุณ ูพุงู ฺฏุช
app_url_helper=ุขุฏุฑุณ ูพุงู ุจุฑุง URLูุง ุงุฌู
ุงุน HTTP(S) ู ูุดุฏุงุฑ ูุง ุฑุงุงูุงู
ู (ุงู
ู).
log_root_path=ู
ุณุฑ ฺฏุฒุงุฑุดโูุง
@@ -204,7 +298,7 @@ offline_mode.description=ุบุฑ ูุนุงู ฺฉุฑุฏู ุดุจฺฉู ูุง ุดุฎุต ุซุงู
disable_gravatar=ุบุฑ ูุนุงู ฺฉุฑุฏู Gravatar
disable_gravatar.description=ุบุฑ ูุนุงู ฺฉุฑุฏู ฺฉฺูฉ ู ู
ูุงุจุน ุขูุงุชุงุฑ ุดุฎุต ุซุงูุซ. ู
ฺฏุฑ ุฏุฑ ู
ูุงุฑุฏ ฺฉู ฺฉุงุฑุจุฑ ู
ุญู ุจุงุฑฺฏุฒุงุฑ ุขูุงุชุงุฑ ูพุด ูุฑุถ ุงุณุชูุงุฏู ุฎูุงูุฏ ุดุฏ.
federated_avatar_lookup=ูุนุงู ุณุงุฒ ุขูุงุชุงุฑ ู
ุดุชุฑฺฉ
-federated_avatar_lookup.description=ู
ุฑุงุฌุนู ู
ุดุชุฑฺฉ ุขูุงุชุงุฑ ุจุง ุงุณุชูุงุฏู ุงุฒ Libravatar ุฑุง ูุงุฏุฑ ู
ุณุงุฒุฏ.
+federated_avatar_lookup.description=ูพุฏุง ฺฉุฑุฏู ุขูุงุชุงุฑ ุจุง ุงุณุชูุงุฏู ุงุฒ Libravatar.
disable_registration=ุบุฑูุนุงูโฺฉุฑุฏู ุฎูุฏ ุซุจุช ูุงู
disable_registration.description=ุบุฑูุนุงู ฺฉุฑุฏู ุซุจุช ูุงู
ฺฉุงุฑุจุฑ. ุชููุง ู
ุฏุฑ ูุง ูุงุฏุฑ ุฎูุงููุฏ ุจูุฏ ุญุณุงุจ ฺฉุงุฑุจุฑ ุฌุฏุฏ ุงุถุงูู ฺฉููุฏ.
allow_only_external_registration.description=ุงุฌุงุฒู ุซุจุช ูุงู
ููุท ุงุฒ ุทุฑู ุฎุฏู
ุงุช ุฎุงุฑุฌ
@@ -242,6 +336,10 @@ default_enable_timetracking.description=ูุนุงูุณุงุฒ ูพฺฏุฑ ุฒู
ุงู
no_reply_address=ู
ุฎู ฺฉุฑุฏู ุฏุงู
ูู ุงู
ู
no_reply_address_helper=ูุงู
ุฏุงู
ูู ุจุฑุง ฺฉุงุฑุจุฑุงู ุฏุงุฑุง ุขุฏุฑุณ ุงู
ู ูพููุงู ุงุณุช. ุจู ุนููุงู ู
ุซุงู ุ ุงฺฏุฑ ูุงู
ุฏุงู
ูู ุงู
ู ู
ุฎู ุฑู "noreply.example.org" ุชูุธู
ุดุฏู ุจุงุดุฏ ุ ูุงู
ฺฉุงุฑุจุฑ "joe" ุฏุฑ Git ุจู ุนููุงู "joe@noreply.example.org" ูุงุฑุฏ ู
ุดูุฏ
password_algorithm=ุงฺูฏูุฑุชู
ุฏุฑูู
โุณุงุฒ ฺฏุฐุฑูุงฺู
+require_db_desc = ูุฑูุฌุฌู ุจู ู
ุงโุงุณโฺฉูุงูุ ูพุณุชฺฏุฑโุงุณโฺฉูุงูุุงุณโฺฉููุงุชณ ุง ุชโุฏโุจ ูุงุฒ ุฏุงุฑุฏ.
+run_user_helper = ูุงู
โฺฉุงุฑุจุฑ ุณุงู
ุงููโุนุงู
ู ฺฉู ุจุง ุนููุงู ูุฑุฌุฌู ุงุฌุฑุง ู
โุดูุฏ. ุจู ุงุฏุฏุงุดุชู ุจุงุดุฏ ฺฉู ฺฉุงุฑุจุฑ ุจุงุฏ ุฏุณุชุฑุณ ุจู ู
ุณุฑ ุฑุดู ู
ุฎุงุฒู ุฏุงุดุชู ุจุงุดุฏ.
+app_slogan_helper = ุดุนุงุฑ ูู
ููู ุฎูุฏ ุฑุง ุงูุฌุง ูุงุฑุฏ ฺฉูุฏ. ุจุฑุง ุบุฑูุนุงู ุดุฏู ุฎุงู ุจฺฏุฐุงุฑุฏ.
+app_slogan = ุดุนุงุฑ ูู
ููู
[home]
uname_holder=ูุงู
ฺฉุงุฑุจุฑ ุง ูุดุงู ุงู
ู
@@ -594,7 +692,7 @@ ssh_helper=ุขุง ูู
ุฏุงูุฏ ฺฺฏูููุ ุฑุงููู
ุง
gpg_helper=ุจู ฺฉู
ฺฉ ูุงุฒ ุฏุงุฑุฏุ ฺูฏุงู ุจู ุฏุฑ GitHub ุฑุง ุฑุงููู
ุง ู
ูุฑุฏ GPG ุงุณุช.
add_new_key=ุงุถุงูู ฺฉุฑุฏู ฺฉูุฏ SSH
add_new_gpg_key=ุงุถุงูู ฺฉุฑุฏู ฺฉูุฏ GPG
-key_content_ssh_placeholder=ู
ุนู
ููุง ุจุง 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', ุง 'sk-ssh-ed25519@openssh.com' ุดุฑูุน ู
โุดูุฏ.
+key_content_ssh_placeholder=ู
ุนู
ููุง ุจุง 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', ุง 'sk-ssh-ed25519@openssh.com' ุดุฑูุน ู
โุดูุฏ.
key_content_gpg_placeholder=ุจุง ุนุจุงุฑุช -----BEGIN PGP PUBLIC KEY BLOCK----- ุดุฑูุน ู
โุดูุฏ
add_new_principal=ฺฉ ฺฉูุฏ ุงุตู ุงุถุงูู ฺฉูุฏ
ssh_key_been_used=ุงู ฺฉูุฏ SSH ูพุด ุงุฒ ุงู ุจู ุณุฑูุฑ ุงูุฒูุฏู ุดุฏู ุงุณุช.
@@ -667,7 +765,7 @@ manage_oauth2_applications=ู
ุฏุฑุช ุจุฑูุงู
ูโูุง OAuth2
edit_oauth2_application=ูุฑุงุด ุจุฑูุงู
ู OAuth2
oauth2_applications_desc=ุจุฑูุงู
ูโูุง OAuth2 ุงุญุฑุงุฒ ููุช ุจุฑูุงู
ู ูุง ุดุฎุต ุซุงูุซ ุฑุง ุจุง ุจุณุชุฑ ุงู
ู ู
ุณุฑ ู
โฺฉูุฏ.
remove_oauth2_application=ุญุฐู ุจุฑูุงู
ู OAuth2
-remove_oauth2_application_desc=ุญุฐู ุจุฑูุงู
ู OAuth2 ุฏุณุชุฑุณ ุชู
ุงู
ุจุฑูุงู
ู ูุง ู
ุชุตู ุจุง ุขู ุฑุง ุงุฒ ุจู ู
โุจุฑุฏ. ุขุง ุงุฏุงู
ู ู
โุฏูุฏุ
+remove_oauth2_application_desc=ุญุฐู ุจุฑูุงู
ู OAuth2 ุฏุณุชุฑุณ ุชู
ุงู
ุจุฑูุงู
ู ูุง ู
ุชุตู ุจุง ุขู ุฑุง ุงุฒ ุจู ู
โุจุฑุฏ. ุขุง ุงุฏุงู
ู ู
โุฏูุฏุ
remove_oauth2_application_success=ุจุฑูุงู
ู ุญุฐู ุดุฏู ุงุณุช.
create_oauth2_application=ุณุงุฎุชู ฺฉ ุจุฑูุงู
ู OAuth2 ุฌุฏุฏ
create_oauth2_application_button=ุงุฌุงุฏ ุจุฑูุงู
ู
@@ -868,7 +966,7 @@ migrate.migrating_failed=ู
ูุงุฌุฑุช ุงุฒ %s ูุงู
ููู ุจูุฏ.
migrate.migrating_failed_no_addr=ู
ูุงุฌุฑุช ูุงู
ููู ุจูุฏ.
migrate.git.description=ฺฉฺู ฺฉ ู
ุฎุฒู ููุท ุงุฒ ฺฉ ุณุฑูุณ Git.
migrate.gitlab.description=ู
ูุงุฌุฑุช ุฏุงุฏู ุงุฒ gitlabb.com ุง ูพุงุฏูโุณุงุฒโูุง ุฏฺฏุฑ GitLab.
-migrate.gitea.description=ู
ูุงุฌุฑุช ุฏุงุฏู ุงุฒ gitea.com ุง ูพุงุฏูโุณุงุฒโูุง ุฏฺฏุฑ Gitea/Forgejo.
+migrate.gitea.description=ู
ูุงุฌุฑุช ุฏุงุฏู ุงุฒ gitea.com ุง ูพุงุฏูโุณุงุฒโูุง ุฏฺฏุฑ Gitea.
migrate.gogs.description=ู
ูุงุฌุฑุช ุฏุงุฏู ุงุฒ notabug.com ุง ูพุงุฏูโุณุงุฒโูุง ุฏฺฏุฑ Gogs.
migrate.onedev.description=ู
ูุงุฌุฑุช ุฏุงุฏู ุงุฒ code.onedev.io ุง ูพุงุฏูโุณุงุฒโูุง ุฏฺฏุฑ OneDev.
migrate.codebase.description=ู
ูุงุฌุฑ ุฏุงุฏู ูุง ุงุฒ codebasehq.com.
@@ -938,6 +1036,7 @@ file_copy_permalink=ูพุฑู
ุงฺููฉ ุฑุง ฺฉูพ ฺฉูุฏ
video_not_supported_in_browser=ู
ุฑูุฑฺฏุฑ ุดู
ุง ุงุฒ ุชฺฏ video ฺฉู ุฏุฑ HTML5 ุชุนุฑู ุดุฏู ุงุณุชุ ูพุดุชุจุงู ูู
ฺฉูุฏ.
audio_not_supported_in_browser=ู
ุฑูุฑฺฏุฑ ุดู
ุง ุงุฒ ุชฺฏ audio ฺฉู ุฏุฑ HTML5 ุชุนุฑู ุดุฏู ุงุณุชุ ูพุดุชุจุงู ูู
ฺฉูุฏ.
stored_lfs=ุฐุฎุฑู ุดุฏู ุจุง GIT LFS
+stored_annex=ุฐุฎุฑู ุดุฏู ุจุง GIT Annex
symbolic_link=ูพููุฏ ูู
ุงุฏู
commit_graph=ูู
ูุฏุงุฑ ฺฉุงู
ุช
commit_graph.select=ุงูุชุฎุงุจ ุจุฑฺููุง
@@ -955,6 +1054,7 @@ editor.upload_file=ุจุงุฑฺฏุฐุงุฑ ูพุฑููุฏู
editor.edit_file=ูุฑุงุด ูพุฑููุฏู
editor.preview_changes=ูพุด ูู
ุงุด ุชุบุฑุงุช
editor.cannot_edit_lfs_files=ูพุฑููุฏู ูุง LFS ุฏุฑ ุตุญูู ูุจ ูุงุจู ุชุบุฑ ูุณุช.
+editor.cannot_edit_annex_files=ูพุฑููุฏู ูุง Annex ุฏุฑ ุตุญูู ูุจ ูุงุจู ุชุบุฑ ูุณุช.
editor.cannot_edit_non_text_files=ูพุฑููุฏูโูุง ุฏูุฏู ุฏุฑ ุตูุญู ูุจ ูุงุจู ุชุบุฑ ูุณุช.
editor.edit_this_file=ูุฑุงุด ูพุฑููุฏู
editor.this_file_locked=ูพุฑููุฏู ููู ุดุฏู ุงุณุช
@@ -968,10 +1068,10 @@ editor.or=ุง
editor.cancel_lower=ุงูุตุฑุงู
editor.commit_signed_changes=ุงุนู
ุงู ุชุบุฑุงุช ุงู
ุถุง ุดุฏู
editor.commit_changes=ุชุบุฑุงุช ฺฉุงู
ุช
-editor.add_tmpl=ุงูุฒูุฏู ''
+editor.add_tmpl=ุงูุฒูุฏู '<%s>'
editor.commit_message_desc=ุชูุถุญ ุชุฎุตุต ุจู ุฏูุฎูุงู ุงุถุงูู ูู
ุงุฏโฆ
editor.signoff_desc=ฺฉ ุชุฑูุฑ Signed-off-by ุชูุณุท committer ุฏุฑ ุงูุชูุง ูพุงู
ฺฏุฒุงุฑุด commit ุงุถุงูู ฺฉูุฏ.
-editor.commit_directly_to_this_branch=ุซุจุช ฺฉุงู
ุช ุจู ุตูุฑุช ู
ุณุชูู
ุฏุฑ ุงูุดุนุงุจ %s .
+editor.commit_directly_to_this_branch=ุซุจุช ฺฉุงู
ุช ุจู ุตูุฑุช ู
ุณุชูู
ุฏุฑ ุงูุดุนุงุจ %[1]s .
editor.create_new_branch=ฺฉ ุดุงุฎู ุฌุฏุฏ ุจุฑุง ุงู commit ุงุฌุงุฏ ฺฉูุฏ ู ุชูุงุถุง ูุงฺฉุด ุฑุง ุดุฑูุน ฺฉูุฏ.
editor.create_new_branch_np=ฺฉ ุดุงุฎู ุฌุฏุฏ ุจุฑุง ฺฉุงู
ุช ุจุณุงุฒุฏ.
editor.propose_file_change=ูพุดููุงุฏ ุชุบุฑ ูพุฑููุฏู
@@ -1240,7 +1340,7 @@ issues.error_modifying_due_date=ุชุบุฑ ู
ูุนุฏ ู
ูุฑุฑ ุจุง ุดฺฉุณุช ู
ู
issues.error_removing_due_date=ุญุฐู ู
ูุนุฏ ู
ูุฑุฑ ุจุง ุดฺฉุณุช ู
ูุงุฌู ุดุฏ.
issues.push_commit_1=%d ุงุนู
ุงู ุชุบุฑ ุงุถุงูู ุดุฏู ุงุณุช %s
issues.push_commits_n=%d ุงุนู
ุงู ุชุบุฑุงุช ุงุถุงูู ุดุฏู ุงุณุช %s
-issues.force_push_codes=`ูพูุด ุดุฏู ุงุฌุจุงุฑ %[1]s ุงุฒ %[2]s
ุจู %[4]s
%[6]s`
+issues.force_push_codes=`ูพูุด ุดุฏู ุงุฌุจุงุฑ %[1]s ุงุฒ %[2]s
ุจู %[4]s
%[6]s`
issues.force_push_compare=ู
ูุงุณู
issues.due_date_form=yyyy-mm-dd
issues.due_date_form_add=ุงูุฒูุฏู ู
ูุนุฏ ู
ูุฑุฑ
@@ -1326,7 +1426,7 @@ pulls.nothing_to_compare=ุงู ุดุงุฎูโูุง ฺฉ ูุณุชูุฏ. ูุงุฒ ุจ
pulls.nothing_to_compare_and_allow_empty_pr=ุงู ุดุงุฎู ูุง ุจุฑุงุจุฑ ูุณุชูุฏ. ุงู PR ุฎุงู ุฎูุงูุฏ ุจูุฏ.
pulls.has_pull_request=`A ุฏุฑุฎูุงุณุช pull ุจู ุงู ุดุงุฎู ูุง ุงุฒ ูุจู ูุฌูุฏ ุฏุงุฑุฏ: %[2]s#%[3]d `
pulls.create=ุงุฌุงุฏ ุชูุงุถุง ูุงฺฉุด
-pulls.title_desc_few=ูุตุฏ ุงุฏุบุงู
%[1]d ุชุบุฑ ุฑุง ุงุฒ %[2]s
ุจู %[3]s
ุฏุงุฑุฏ
+pulls.title_desc_few=ูุตุฏ ุงุฏุบุงู
%[1]d ุชุบุฑ ุฑุง ุงุฒ %[2]s
ุจู %[3]s
ุฏุงุฑุฏ
pulls.merged_title_desc_few=%[1]d ฺฉุงู
ุช ุงุฏุบุงู
ุดุฏู ุงุฒ %[2]s
ุจู %[3]s
%[4]s
pulls.change_target_branch_at=`ูุฏู ุดุงุฎู ุงุฒ %s ุจู %s %s ุชุบุฑ ฺฉุฑุฏ`
pulls.tab_conversation=ฺฏูุชฺฏู
@@ -1440,7 +1540,7 @@ wiki.page=ุตูุญู
wiki.filter_page=ุตุงู ุตูุญู
wiki.new_page=ุตูุญู
wiki.default_commit_message=ููุดุชู ู
ุชู ูพุฑุงู
ูู ุจูโุฑูุฒุฑุณุงู ุงู ุตูุญู (ุงุฎุชุงุฑ).
-wiki.save_page=ููุดุชู ู
ุชู ูพุฑุงู
ูู ุจูโุฑูุฒุฑุณุงู ุงู ุตูุญู (ุงุฎุชุงุฑ).
+wiki.save_page=ุฐุฎุฑู ุตูุญู
wiki.last_commit_info=%s ุงู ุตูุญู %s ุฑุง ูุฑุงุด ฺฉุฑุฏู ุงุณุช
wiki.edit_page_button=ูุฑุงุด
wiki.new_page_button=ุตูุญู ุฌุฏุฏ
@@ -1727,7 +1827,7 @@ settings.event_pull_request_review_desc=ุฏุฑุฎูุงุณุช pull ุชุงุฏ ุดุฏูุ
settings.event_pull_request_sync=ุฏุฑุฎูุงุณุช pull ูู
ฺฏุงู
ุดุฏู
settings.event_pull_request_sync_desc=ุฏุฑุฎูุงุณุช ฺฉุดุด ูู
ฺฏุงู
ุดุฏู ุงุณุช.
settings.branch_filter=ุตุงู ุดุงุฎู
-settings.branch_filter_desc=ููุฑุณุช ุณูุฏ ุดุงุฎู ุจุฑุง ุฑูุฏุงุฏูุง pushุ ุงุฌุงุฏ ุดุงุฎู ู ุญุฐู ุดุงุฎูุ ฺฉู ุจู ุนููุงู ุงฺูฏู glob ู
ุดุฎุต ุดุฏู ุงุณุช. ุงฺฏุฑ ุฎุงู ุง *
ุจุงุดุฏุ ุฑูุฏุงุฏูุง ุจุฑุง ูู
ู ุดุงุฎู ูุง ฺฏุฒุงุฑุด ู
ุดููุฏ. ุจุฑุง syntax ุจู ุงุณูุงุฏ github.com/gobwas/glob ู
ุฑุงุฌุนู ฺฉูุฏ. ู
ุซุงูโูุง: master
ุ {master,release*}
.
+settings.branch_filter_desc=ููุฑุณุช ุณูุฏ ุดุงุฎู ุจุฑุง ุฑูุฏุงุฏูุง pushุ ุงุฌุงุฏ ุดุงุฎู ู ุญุฐู ุดุงุฎูุ ฺฉู ุจู ุนููุงู ุงฺูฏู glob ู
ุดุฎุต ุดุฏู ุงุณุช. ุงฺฏุฑ ุฎุงู ุง *
ุจุงุดุฏุ ุฑูุฏุงุฏูุง ุจุฑุง ูู
ู ุดุงุฎู ูุง ฺฏุฒุงุฑุด ู
ุดููุฏ. ุจุฑุง syntax ุจู ุงุณูุงุฏ %[2]s ู
ุฑุงุฌุนู ฺฉูุฏ. ู
ุซุงูโูุง: master
ุ {master,release*}
.
settings.active=ูุนุงู
settings.active_helper=ุงุทูุงุนุงุช ุฏุฑุจุงุฑู ฺฉุดุฏู ุดุฏู ู
ุงุดู ุฑูุฏุงุฏูุง ุจู ุงู ูุดุงู ฺููฉ ุชุญุช ูุจ ุงุฑุณุงู ุฎูุงูุฏ ุดุฏ.
settings.add_hook_success=ฺฉ ฺููฉ ุชุญุช ูุจ ุฌุฏุฏ ุงูุฒูุฏู ุดุฏู ุงุณุช.
@@ -1951,7 +2051,7 @@ release.add_tag=ููุท ุชฺฏ ุงุฌุงุฏ ฺฉูุฏ
branch.name=ูุงู
ุดุงุฎู
branch.delete_head=ุญุฐู
branch.delete_html=ุญุฐู ุดุงุฎู
-branch.create_branch=ุณุงุฎุชู ุดุงุฎู %s
+branch.create_branch=ุณุงุฎุชู ุดุงุฎู %s
branch.deleted_by=ุญุฐู ุดุฏู ุชูุณุท %s
branch.included_desc=ุงู ุดุงุฎู ุจุฎุด ุงุฒ ุดุงุฎู ูพุด ูุฑุถ ุงุณุช
branch.included=ู
ุดู
ูู ุดุฏู
@@ -1962,7 +2062,7 @@ branch.create_branch_operation=ุงุฌุงุฏ ุดุงุฎู
branch.new_branch=ุดุงุฎู ุฌุฏุฏ ุงุฌุงุฏ ฺฉูุฏ
branch.renamed=ุดุงุฎู %s ูุจูุง ุจู %s ุชุบุฑ ฺฉุฑุฏู ุงุณุช.
-tag.create_tag=ุชฺฏ %s ุงุฌุงุฏ ฺฉูุฏ
+tag.create_tag=ุชฺฏ %s ุงุฌุงุฏ ฺฉูุฏ
topic.manage_topics=ู
ุฏุฑุช ู
ูุถูุนุงุช
@@ -1974,6 +2074,8 @@ error.csv.too_large=ูู
ุชูุงู ุงู ูุงู ุฑุง ุฑูุฏุฑ ฺฉุฑุฏ ุฒุฑ
error.csv.unexpected=ูู
ุชูุงู ุงู ูุงู ุฑุง ุฑูุฏุฑ ฺฉุฑุฏ ุฒุฑุง ุญุงู ฺฉ ฺฉุงุฑุงฺฉุชุฑ ุบุฑู
ูุชุธุฑู ุฏุฑ ุฎุท %d ู ุณุชูู %d ุงุณุช.
error.csv.invalid_field_count=ูู
ุชูุงู ุงู ูุงู ุฑุง ุฑูุฏุฑ ฺฉุฑุฏ ุฒุฑุง ุชุนุฏุงุฏ ููุฏูุง ุขู ุฏุฑ ุฎุท %d ุงุดุชุจุงู ุงุณุช.
+milestones.filter_sort.name = ูุงู
+
[graphs]
[org]
@@ -2278,7 +2380,7 @@ auths.bind_password=ุงุชุตุงู ฺฏุฐุฑูุงฺู
auths.user_base=ูพุงฺฏุงู ุฌุณุชุฌู ฺฉุงุฑุจุฑ
auths.user_dn=ฺฉุงุฑุจุฑ DN
auths.attribute_username=ฺฺูฏ ูุงู
ฺฉุงุฑุจุฑ
-auths.attribute_username_placeholder=ูุงู
ฺฉุงุฑุจุฑ ุฑุง ุฎุงู ุจฺฏุฐุงุฑุฏ ุจุฑุง ุงูุชุฎุงุจ ูุงู
ฺฉุงุฑุจุฑ gitea ุงูุชุฎุงุจ ุดูุฏ.
+auths.attribute_username_placeholder=ูุงู
ฺฉุงุฑุจุฑ ุฑุง ุฎุงู ุจฺฏุฐุงุฑุฏ ุจุฑุง ุงูุชุฎุงุจ ูุงู
ฺฉุงุฑุจุฑ Forgejo ุงูุชุฎุงุจ ุดูุฏ.
auths.attribute_name=ฺฺูฏ ูุงู
auths.attribute_surname=ฺฺูฏ ูุงู
ุฎุงููุงุฏฺฏ
auths.attribute_mail=ฺฺูฏ ุงู
ู
@@ -2336,17 +2438,17 @@ auths.sspi_default_language_helper=ุฒุจุงู ูพุด ูุฑุถ ุจุฑุง ฺฉุงุฑุจุฑุง
auths.tips=๏ปง๏ฎ๏บ๏บ
auths.tips.oauth2.general=ุงุญุฑุงุฒ ููุช OAuth2
auths.tip.oauth2_provider=ุชุงู
ู ฺฉููุฏู OAuth2
-auths.tip.bitbucket=ุซุจุช ฺฉ OAuth ุฌุฏุฏ ู
ุตุฑู ฺฉููุฏู ุจุฑ https://bitbucket.org/account/user//oauth-consumers/new ู ุงูุฒูุฏู ู
ุฌูุฒ 'Account' - 'Read'
+auths.tip.bitbucket=ุซุจุช ฺฉ OAuth ุฌุฏุฏ ู
ุตุฑู ฺฉููุฏู ุจุฑ %s
auths.tip.nextcloud=ุจุง ุงุณุชูุงุฏู ุงุฒ ู
ูู ุฒุฑ "ุชูุธู
ุงุช -> ุงู
ูุช -> ู
ุดุชุฑ OAuth 2.0" ู
ุตุฑู ฺฉููุฏู OAuth ุฌุฏุฏ ุฑุง ุฏุฑ ูู
ููู ุฎูุฏ ุซุจุช ฺฉูุฏ
-auths.tip.dropbox=ฺฉ ุจุฑูุงู
ู ุฌุฏุฏ ุฏุฑ https://www.dropbox.com/developers/apps ุจุณุงุฒุฏ
-auths.tip.facebook=`ฺฉ ุจุฑูุงู
ู ุฌุฏุฏ ุฏุฑ https://developers.facebook.com/apps ุจุณุงุฒุฏ ุจุฑุง ูุฑูุฏ ุงุฒ ุทุฑู ูุณ ุจฺูฉ ูุณู
ุช ู
ุญุตููุงุช "Facebook Login"`
-auths.tip.github=ฺฉ ุจุฑูุงู
ู OAuth ุฌุฏุฏ ุฏุฑ https://github.com/settings/applications/new ุซุจุช ฺฉูุฏ
+auths.tip.dropbox=ฺฉ ุจุฑูุงู
ู ุฌุฏุฏ ุฏุฑ %s ุจุณุงุฒุฏ
+auths.tip.facebook=`ฺฉ ุจุฑูุงู
ู ุฌุฏุฏ ุฏุฑ %s ุจุณุงุฒุฏ ุจุฑุง ูุฑูุฏ ุงุฒ ุทุฑู ูุณ ุจฺูฉ ูุณู
ุช ู
ุญุตููุงุช "Facebook Login"`
+auths.tip.github=ฺฉ ุจุฑูุงู
ู OAuth ุฌุฏุฏ ุฏุฑ %s ุซุจุช ฺฉูุฏ
auths.tip.gitlab=ุซุจุช ฺฉ ุจุฑูุงู
ู ุฌุฏุฏ ุฏุฑ https://gitlab.com/profile/applications
-auths.tip.google_plus=ุงุทูุงุนุงุช ู
ุฑุจูุท ุจู ู
ุดุชุฑ OAuth2 ุฑุง ุงุฒ ฺฉูุงูุช API Google ุฏุฑ https://console.developers.google.com/
+auths.tip.google_plus=ุงุทูุงุนุงุช ู
ุฑุจูุท ุจู ู
ุดุชุฑ OAuth2 ุฑุง ุงุฒ ฺฉูุงูุช API Google ุฏุฑ %s
auths.tip.openid_connect=ุจุฑุง ู
ุดุฎุต ฺฉุฑุฏู ููุงุท ูพุงุงู ุงุฒ ุขุฏุฑุณ OpenID Connect Discovery URL ( /.well-known/openid-configuration) ุงุณุชูุงุฏู ฺฉูุฏ.
-auths.tip.twitter=ุจู https://dev.twitter.com/apps ุจุฑูุฏ ุ ุจุฑูุงู
ู ุง ุงุฌุงุฏ ฺฉูุฏ ู ุงุทู
ูุงู ุญุงุตู ฺฉูุฏ ฺฉู ฺฏุฒูู "ุงุฌุงุฒู ุงุณุชูุงุฏู ุงุฒ ุงู ุจุฑูุงู
ู ุจุฑุง ูุฑูุฏ ุจู ุณุณุชู
ุจุง Twitter" ุฑุง ูุนุงู ฺฉูุฏ
-auths.tip.discord=ฺฉ ุจุฑูุงู
ู ุฌุฏุฏ ุฑุง ุฏุฑ https://discordapp.com/developers/applications/me ุซุจุช ฺฉูุฏ
-auths.tip.yandex=`ฺฉ ุจุฑูุงู
ู ุฌุฏุฏ ุฏุฑ https://oauth.yandex.com/client/new ุงุฌุงุฏ ฺฉูุฏ. ู
ุฌูุฒูุง ุฒุฑ ุฑุง ุงุฒ ุจุฎุด "Yandex.Passport API" ุงูุชุฎุงุจ ฺฉูุฏ: "ุฏุณุชุฑุณ ุจู ุขุฏุฑุณ ุงู
ู"ุ "ุฏุณุชุฑุณ ุจู ุขูุงุชุงุฑ ฺฉุงุฑุจุฑ" ู "ุฏุณุชุฑุณ ุจู ูุงู
ฺฉุงุฑุจุฑุ ูุงู
ู ูุงู
ุฎุงููุงุฏฺฏุ ุฌูุณุช"`
+auths.tip.twitter=ุจู %s ุจุฑูุฏ ุ ุจุฑูุงู
ู ุง ุงุฌุงุฏ ฺฉูุฏ ู ุงุทู
ูุงู ุญุงุตู ฺฉูุฏ ฺฉู ฺฏุฒูู "ุงุฌุงุฒู ุงุณุชูุงุฏู ุงุฒ ุงู ุจุฑูุงู
ู ุจุฑุง ูุฑูุฏ ุจู ุณุณุชู
ุจุง Twitter" ุฑุง ูุนุงู ฺฉูุฏ
+auths.tip.discord=ฺฉ ุจุฑูุงู
ู ุฌุฏุฏ ุฑุง ุฏุฑ %s ุซุจุช ฺฉูุฏ
+auths.tip.yandex=`ฺฉ ุจุฑูุงู
ู ุฌุฏุฏ ุฏุฑ %s ุงุฌุงุฏ ฺฉูุฏ. ู
ุฌูุฒูุง ุฒุฑ ุฑุง ุงุฒ ุจุฎุด "Yandex.Passport API" ุงูุชุฎุงุจ ฺฉูุฏ: "ุฏุณุชุฑุณ ุจู ุขุฏุฑุณ ุงู
ู"ุ "ุฏุณุชุฑุณ ุจู ุขูุงุชุงุฑ ฺฉุงุฑุจุฑ" ู "ุฏุณุชุฑุณ ุจู ูุงู
ฺฉุงุฑุจุฑุ ูุงู
ู ูุงู
ุฎุงููุงุฏฺฏุ ุฌูุณุช"`
auths.tip.mastodon=ฺฉ URL ูู
ููู ุณูุงุฑุด ุจุฑุง ูู
ููู ู
ุงุณุชูุฏูู ฺฉู ู
ุฎูุงูุฏ ุจุง ุขู ุงุญุฑุงุฒ ููุช ฺฉูุฏ ูุงุฑุฏ ฺฉูุฏ (ุง ุงุฒ ฺฉ ูพุด ูุฑุถ ุงุณุชูุงุฏู ฺฉูุฏ)
auths.edit=ูุฑุงุด ู
ูุจุน ุงุญุฑุงุฒ ููุช
auths.activated=ุงู ู
ูุจุน ุงุญุฑุงุฒ ููุช ูุนุงู ุดุฏู ุงุณุช
@@ -2527,6 +2629,9 @@ notices.op=ุนู
ูุงุช.
notices.delete_success=ฺฏุฒุงุฑุด ุณุณุชู
ุญุฐู ุดุฏู ุงุณุช.
+config_summary = ฺฺฉุฏู
+config_settings = ุชูุธูู
ุงุช
+
[action]
create_repo=ู
ุฎุฒู ุงุฌุงุฏ ุดุฏู %s
rename_repo=ู
ุฎุฒู ุชุบุฑ ูุงู
ุฏุงุฏ ุงุฒ %[1]s
ุจู %[3]s
@@ -2621,9 +2726,6 @@ owner.settings.cleanuprules.enabled=ูุนุงู ุดุฏู
[secrets]
[actions]
-
-
-
runners.name=ูุงู
runners.owner_type=ููุน
runners.description=ุดุฑุญ
@@ -2633,13 +2735,56 @@ runners.task_list.commit=ฺฉุงู
ุช
runners.status.active=ูุนุงู
runs.commit=ฺฉุงู
ุช
+variables.edit = ุชุบุฑ ู
ุชุบุฑ
+variables.deletion.success = ู
ุชุบุฑ ุญุฐู ุดุฏ.
+variables.deletion = ุญุฐู ู
ุชุบุฑ
+variables.creation.success = ู
ุชุบุฑ "%s" ุงุฌุงุฏ ุดุฏ.
+variables = ู
ุชุบุฑูุง
+variables.management = ู
ุฏุฑุช ู
ุชุบุฑูุง
+variables.update.failed = ุนุฏู
ู
ูููุช ุฏุฑ ุชุบุฑ ู
ุชุบุฑ
+variables.update.success = ุชุบุฑ ู
ุชุบุฑ ุจุง ู
ูููุช ุงูุฌุงู
ุดุฏ.
+variables.creation = ุงูุฒูุฏู ู
ุชุบุฑ
+variables.none = ฺู ู
ุชุบุฑ ูููุฒ ูุฌูุฏ ูุฏุงุฑุฏ.
[projects]
+type-1.display_name = ูพุฑฺูู ู
ุณุชูู
+type-2.display_name = ู
ุฎุฒู ูพุฑฺูู
+type-3.display_name = ุณุงุฒู
ุงู ูพุฑฺูู
+deleted.display_name = ูพุงฺฉ ฺฉุฑุฏู ูพุฑฺูู
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=ูพููุฏ ูู
ุงุฏู
+executable_file = ูุงู ุงุฌุฑุง
+normal_file = ูุงู ู
ุนู
ูู
+changed_filemode = %[1] ูุง โ %[2] ูุง
+directory = ูพูุดู
+[search]
+type_tooltip = ุฌุณุชุฌู ฺฏููู
+search = ุฌุณุชุฌู...
+fuzzy = ุฏุฑูู
+fuzzy_tooltip = ูพุงู
ุฏูุง ุฑุง ุฏุฑุฌ ฺฉูุฏ ฺฉู ุฏููุง ุจุง ุนุจุงุฑุช ุฌุณุชุฌู ูู
ุฎูุงู ุฏุงุดุชู ุจุงุดูุฏ
+regexp = ุนุจุงุฑุงุช ุจุงูุงุนุฏู
+pull_kind = ุฌุณุชุฌู ูุงฺฉุดโูุง...
+no_results = ูุชุฌู ุฏุฑุฎูุฑ ุงูุช ูุดุฏ.
+runner_kind = ุฌุณุชุฌู ุฏููุฏูโูุง...
+keyword_search_unavailable = ุฌุณุชุฌู ฺฉูุฏูุงฺู ุงฺฉููู ุฏุฑ ุฏุฑุณุชุฑุณ ูุณุช. ูุทูุง ุจุง ู
ุฏุฑ ุณุงุช ุฏุฑ ู
ุงู ุจฺฏุฐุงุฑุฏ.
+repo_kind = ุฌุณุชุฌู ู
ุฎุงุฒู...
+regexp_tooltip = ุงุตุทูุงุญ ุฌุณุชุฌู ุดุฏู ุฑุง ุจุง ุนุจุงุฑุงุช ุจุงูุงุนุฏู ุชูุณุฑ ฺฉู
+user_kind = ุฌุณุชุฌู ฺฉุงุฑุจุฑุงู...
+org_kind = ุฌุณุชุฌู ุณุงุฒู
ุงูโูุง...
+team_kind = ุฌุณุชุฌู ฺฏุฑููโูุง...
+package_kind = ุฌุณุชุฌู ุจุณุชูโูุง...
+project_kind = ุฌุณุชุฌู ูพุฑฺููโูุง...
+code_search_unavailable = ุฌุณุชุฌู ฺฉุฏ ุงฺฉููู ุฏุฑ ุฏุณุชุฑุณ ูุณุช. ูุทูุง ุจุง ู
ุฏุฑ ุณุงุช ุฏุฑู
ุงู ุจฺฏุฐุงุฑุฏ.
+code_kind = ุฌุณุชุฌู ฺฉุฏูุง...
+union = ุจูู
ูพูุณุชฺฏ
+union_tooltip = ูุชุงุฌ ุฑุง ุฏุฑ ุจุฑ ุจฺฏุฑ ฺฉู ุจุง ูุฑ ฺฉ ุงุฒ ฺฉูุฏูุงฺูโูุง ุฌุฏุง ุดุฏู ุงุฒ ูุถุงโุฎุงู ู
ุทุงุจูุช ุฏุงุฑุฏ
+branch_kind = ุฌุณุชุฌู ุดุงุฎูโูุง...
+commit_kind = ุฌุณุชุฌู ุณูพุฑุฏูโูุง...
+issue_kind = ุฌุณุชุฌู ู
ุดฺฉูุงุช...
+exact = ู
ู ุจู ู
ู
+exact_tooltip = ูุชุงุฌ ุฑุง ุฏุฑ ุจุฑ ุจฺฏุฑ ฺฉู ู
ู ุจู ู
ู ุจุง ุงุตุทูุงุญ ุฌุณุชุฌู ุดุฏู ฺฉ ุจุงุดุฏ
diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini
index 6e39931848..5f087b2bf9 100644
--- a/options/locale/locale_fi-FI.ini
+++ b/options/locale/locale_fi-FI.ini
@@ -2,7 +2,7 @@
home=Etusivu
dashboard=Kojelauta
explore=Tutki
-help=Apua
+help=Ohje
logo=Logo
sign_in=Kirjaudu sisรครคn
sign_in_or=tai
@@ -21,13 +21,13 @@ user_profile_and_more=Profiili ja asetuksetโฆ
signed_in_as=Kirjautuneena kรคyttรคjรคnรค
toc=Sisรคllysluettelo
licenses=Lisenssit
-return_to_forgejo=Palaa Forgejoan
+return_to_forgejo=Palaa Forgejohon
username=Kรคyttรคjรคtunnus
email=Sรคhkรถpostiosoite
password=Salasana
-access_token=Pรครคsymerkki
-re_type=Varmista salasana
+access_token=Pรครคsypoletti
+re_type=Vahvista salasana
captcha=CAPTCHA
twofa=Kaksivaiheinen todennus
twofa_scratch=Kaksivaiheinen kertakรคyttรถinen koodi
@@ -41,7 +41,7 @@ webauthn_error=Turva-avainta ei voitu lukea.
webauthn_unsupported_browser=Selaimesi ei tรคllรค hetkellรค tue WebAuthnia.
webauthn_error_unknown=Tuntematon virhe. Yritรค uudelleen.
webauthn_error_insecure=`WebAuthn tukee vain suojattuja yhteyksiรค. Testaukseen HTTP:n yli, voit kรคyttรครค osoitetta "localhost" tai "127.0.0.1"`
-webauthn_error_unable_to_process=Palvelin ei pystynyt toteuttamaan kutsua.
+webauthn_error_unable_to_process=Palvelin ei pystynyt kรคsittelemรครคn pyyntรถรค.
webauthn_error_duplicated=Turva-avainta ei ole sallittu tรคssรค pyynnรถssรค. Varmista, ettei avainta ole jo rekisterรถity.
webauthn_error_empty=Sinun tรคytyy asettaa nimi tรคlle avaimelle.
webauthn_error_timeout=Aikakatkaisu saavutettu ennenkuin avaintasi on voitu lukea. Lataa tรคmรค sivu uudelleen ja yritรค uudelleen.
@@ -52,8 +52,8 @@ organization=Organisaatio
mirror=Peili
new_repo=Uusi repo
new_migrate=Uusi migraatio
-new_mirror=Uusi peilaus
-new_fork=Uusi repositorio
+new_mirror=Uusi peilipalvelin
+new_fork=Uusi repoforkki
new_org=Uusi organisaatio
new_project=Uusi projekti
manage_org=Yllรคpidรค organisaatioita
@@ -71,7 +71,7 @@ collaborative=Yhteistyรถssรค
forks=Haarat
activities=Toimet
-pull_requests=Pull requestit
+pull_requests=Vetopyynnรถt
issues=Ongelmat
milestones=Merkkipaalut
@@ -98,7 +98,7 @@ preview=Esikatselu
loading=Ladataanโฆ
error=Virhe
-error404=Sivu, jota yritรคt nรคhdรค, joko ei lรถydy tai et ole oikeutettu katsomaan sitรค.
+error404=Sivu, jota yritรคt nรคhdรค, joko ei lรถydy , on poistettu tai et ole oikeutettu katsomaan sitรค.
never=Ei koskaan
@@ -119,7 +119,7 @@ new_project_column = Uusi sarake
retry = Yritรค uudelleen
copy_type_unsupported = Tรคtรค tiedostotyyppiรค ei voi kopioida
locked = Lukittu
-filter = Suodatin
+filter = Suodata
filter.is_archived = Arkistoitu
filter.not_archived = Ei arkistoitu
filter.public = Julkinen
@@ -131,48 +131,117 @@ unknown = Tuntematon
show_timestamps = Nรคytรค aikaleimat
show_log_seconds = Nรคytรค sekunnit
copy_generic = Kopioi leikepรถydรคlle
+active_stopwatch = Aktiivisen ajan seuranta
+tracked_time_summary = Yhteenveto seuratusta ajasta, perustuen ongelmalistaan
+remove_label_str = Poista "%s"
+view = Nรคytรค
+toggle_menu = Avaa/sulje valikko
+error413 = Olet tรคyttรคnyt kiintiรถsi.
+copy_hash = Kopioi tiiviste
+go_back = Palaa
+more_items = Lisรครค
+pin = Kiinnitรค
+unpin = Poista kiinnitys
+confirm_delete_selected = Haluatko varmasti poistaa kaikki valitut kohteet?
+value = Arvo
+rerun = Suorita uudelleen
+filter.clear = Tyhjennรค suodattimet
+invalid_data = Virheellistรค dataa: %v
+new_repo.title = Uusi repositorio
+new_org.title = Uusi organisaatio
+new_org.link = Uusi organisaatio
+new_repo.link = Uusi repositorio
+new_migrate.link = Uusi migraatio
+rerun_all = Uudelleensuorita kaikki tyรถt
+artifacts = Artifaktit
+confirm_delete_artifact = Haluatko varmasti poistaa artifaktin "%s"?
+new_migrate.title = Uusi migraatio
+test = Testi
+concept_system_global = Globaali
+sign_in_with_provider = Kirjaudu %s-tilillรค
+filter.is_fork = Forkit
+filter.is_mirror = Peilattu
+filter.is_template = Mallipohjat
+filter.not_fork = Ei forkkeja
+filter.not_template = Ei mallipohjat
+filter.not_mirror = Ei peilattu
+copy_path = Kopioi polku
+concept_user_individual = Yksittรคinen
[aria]
footer.links = Linkit
+navbar = Navigaatiopalkki
+footer.software = Tietoja tรคstรค ohjelmistosta
+footer = Alatunniste
[heatmap]
less = Vรคhemmรคn
more = Enemmรคn
+number_of_contributions_in_the_last_12_months = %s kontribuutiota viimeisen vuoden aikana
+contributions_zero = Ei kontribuutioita
+contributions_one = kontribuutio
+contributions_few = kontribuutiota
+contributions_format = {contributions} {day}. {month} {year}
[editor]
buttons.code.tooltip = Lisรครค koodia
buttons.link.tooltip = Lisรครค linkki
buttons.mention.tooltip = Mainitse kรคyttรคjรค tai tiimi
buttons.list.task.tooltip = Lisรครค tehtรคvรคlista
+buttons.disable_monospace_font = Poista tasalevyinen fontti kรคytรถstรค
+buttons.heading.tooltip = Lisรครค otsikko
+buttons.bold.tooltip = Lisรครค lihavoitua tekstiรค
+buttons.italic.tooltip = Lisรครค kursivoitua tekstiรค
+buttons.list.unordered.tooltip = Lisรครค jรคrjestรคmรคtรถn lista
+buttons.list.ordered.tooltip = Lisรครค numeroitu lista
+buttons.switch_to_legacy.tooltip = Kรคytรค vanhentunutta tekstieditoria
+buttons.indent.tooltip = Sisennรค yhden tason verran
+buttons.quote.tooltip = Lainaa tekstiรค
+buttons.enable_monospace_font = Kรคytรค tasalevyistรค fonttia
+buttons.ref.tooltip = Viittaa ongelmaa tai vetopyyntรถรค
+buttons.new_table.tooltip = Lisรครค taulukko
+table_modal.header = Lisรครค taulukko
+table_modal.placeholder.header = Otsikko
+table_modal.placeholder.content = Sisรคltรถ
+table_modal.label.rows = Rivit
+table_modal.label.columns = Sarakkeet
+buttons.unindent.tooltip = Vรคhennรค sisennystรค yhden tason verran
+link_modal.header = Lisรครค linkki
+link_modal.url = Osoite
+link_modal.description = Kuvaus
+link_modal.paste_reminder = Vihje: Jos leikepรถydรคllรค on URL-osoite, voit liittรครค suoraan editoriin luodaksesi linkin.
[filter]
string.asc = A - ร
string.desc = ร - A
[error]
-occurred=Virhe tapahtui
+occurred=Tapahtui virhe
missing_csrf=Virheellinen pyyntรถ: CSRF-tunnusta ei ole olemassa
invalid_csrf=Virheellinen pyyntรถ: Virheellinen CSRF-tunniste
not_found=Kohdetta ei lรถytynyt.
network_error=Verkkovirhe
+server_internal = Palvelinvirhe
+report_message = Jos uskot tรคmรคn olevan Forgejon virhe, etsi ongelmia Codebergissรค tai avaa tarvittaessa uusi ongelma.
[startpage]
app_desc=Kivuton, itsehostattu Git-palvelu
install=Helppo asentaa
platform=Alustariippumaton
-platform_desc=Forgejo kรคy missรค tahansa alustassa, johon Go kykenee kรครคntรคmรครคn. Windows, macOS, Linux, ARM, jne. Valitse omasi!
+platform_desc=Forgejo on mahdollista suorittaa vapaissa kรคyttรถjรคrjestelmissรค kuten Linux ja FreeBSD, ja se toimii eri suoritinarkkitehtuureilla. Valitse omasi!
lightweight=Kevyt
lightweight_desc=Forgejolla on vรคhรคiset vรคhimmรคisvaatimukset, joten se toimii jopa halvassa Raspberry Pi:ssรค. Sรครคstรค koneesi energiaa!
license=Avoin lรคhdekoodi
-license_desc=Mene osoitteeseen Forgejo ! Liity mukaan tekemรครคn projektista entistรคkin parempi. รlรค ujostele avustamista!
+license_desc=Mene osoitteeseen Forgejo ! Liity mukaan tekemรครคn projektista entistรคkin parempi. รlรค ujostele avustamista!
+install_desc = Suorita alustallesi suunnattu binรครคritiedosto , jaa se kontitettuna tai hanki se pakattuna .
[install]
install=Asennus
-title=Alkuperรคiset asetukset
+title=Aloitusasetukset
docker_helper=Jos ajat Forgejoa Dockerin sisรคllรค, lue ohjeet ennen minkรครคn asetuksen muuttamista.
-require_db_desc=Forgejo tarvitsee toimiakseen MySQL, PostgreSQL, SQLite3 tai TiDB (MySQL protokolla) tietokannan.
-db_title=Tietokanta asetukset
-db_type=Tietokanta tyyppi
+require_db_desc=Forgejo tarvitsee toimiakseen MySQL-, PostgreSQL-, SQLite3- tai TiDB- (MySQL-protokolla) tietokannan.
+db_title=Tietokannan asetukset
+db_type=Tietokannan tyyppi
host=Isรคntรค
user=Kรคyttรคjรคtunnus
password=Salasana
@@ -181,7 +250,7 @@ db_schema=Skeema
ssl_mode=SSL
path=Polku
sqlite_helper=SQLite3-tietokannan tiedostopolku. Syรถtรค absoluuttinen polku, jos ajat Forgejoa palveluna.
-reinstall_error=Yritรคt asentaa olemassa olevaan Forgejo tietokantaan
+reinstall_error=Yritรคt asentaa olemassa olevaan Forgejo-tietokantaan
reinstall_confirm_message=Asentaminen uudelleen olemassa olevalla Forgejo-tietokannalla voi aiheuttaa useita ongelmia. Useimmissa tapauksissa sinun pitรคisi kรคyttรครค olemassa olevia "app.ini" asetuksia Forgejon kรคyttรถรถn. Jos tiedรคt mitรค teet, vahvista seuraavat seikat:
reinstall_confirm_check_1=Tiedot, jotka on salattu SECRET_KEY:llรค app.ini:ssรค saatetaan menettรครค: kรคyttรคjรคt eivรคt ehkรค voi kirjautua sisรครคn 2FA/OTP:lla ja peilit eivรคt vรคlttรคmรคttรค toimi oikein. Ruksaamalla tรคmรคn vahvistat, ettรค nykyinen app.ini -tiedosto sisรคltรครค oikean SECRET_KEY:n.
reinstall_confirm_check_2=Repot ja asetukset saattaa olla tarpeen uudelleensynkronoida. Valitsemalla tรคmรคn vahvistat, ettรค uudelleensynkronoit repojen koukut ja authorized_keys -tiedoston manuaalisesti. Varmistat, ettรค repon ja peilin asetukset ovat oikeat.
@@ -190,54 +259,54 @@ err_empty_db_path=SQLite3-tietokannan polku ei voi olla tyhjรค.
no_admin_and_disable_registration=Et voi kytkeรค rekisterรถintiรค pois luomatta sitรค ennen yllรคpitotiliรค.
err_empty_admin_password=Yllรคpitรคjรคn salasana ei voi olla tyhjรค.
err_empty_admin_email=Yllรคpitรคjรคn sรคhkรถpostiosoite ei voi olla tyhjรค.
-err_admin_name_is_reserved=Yllรคpitรคjรคn kรคyttรคjรคtunnus on virheellinen: kรคyttรคjรคtunnus on varattu
+err_admin_name_is_reserved=`Yllรคpitรคjรคn kรคyttรคjรคtunnus on virheellinen; kรคyttรคjรคtunnus on varattu`
err_admin_name_is_invalid=Yllรคpitรคjรคn kรคyttรคjรคtunnus on virheellinen
general_title=Yleiset asetukset
-app_name=Sivuston otsikko
-app_name_helper=Voit syรถttรครค yrityksesi nimen tรคhรคn.
-repo_path=Repon juuren polku
+app_name=Instanssin otsikko
+app_name_helper=Syรถtรค instanssin nimi tรคhรคn. Se nรคytetรครคn kaikilla sivuilla.
+repo_path=Repositorion juuren polku
repo_path_helper=Muualla olevat git-repositoriot tullaan tallentamaan tรคhรคn kansioon.
lfs_path=Git LFS -juuripolku
lfs_path_helper=Git LFS:n yllรคpitรคmรคt tiedostot tullaan tallentamaan tรคhรคn hakemistoon. Jรคtรค tyhjรคksi kytkeรคksesi toiminnon pois.
run_user=Aja kรคyttรคjรคnรค
domain=Palvelimen verkkotunnus
ssh_port=SSH-palvelimen portti
-ssh_port_helper=Porttinumero, jossa SSH-palvelimesi kuuntelee. Jรคtรค tyhjรคksi kytkeรคksesi pois.
-http_port=Forgejon HTTP-kuunteluportti
-http_port_helper=Portti, jossa Forgejon web-palvelin kuuntelee.
-app_url=Forgejon juuriosoite
+ssh_port_helper=Porttinumero, jossa SSH-palvelimesi kuuntelee. Jรคtรค tyhjรคksi kytkeรคksesi SSH-palvelimen pois pรครคltรค.
+http_port=HTTP-kuunteluportti
+http_port_helper=Portti, jota Forgejon web-palvelin kรคyttรครค.
+app_url=Juuriosoite
app_url_helper=Juuriosoite HTTP(S)-klooniosoitteille ja sรคhkรถpostimuistutuksille.
-log_root_path=Lokin polku
+log_root_path=Lokitiedostojen polku
log_root_path_helper=Lokitiedostot kirjoitetaan tรคhรคn kansioon.
optional_title=Valinnaiset asetukset
email_title=Sรคhkรถpostiasetukset
-smtp_addr=SMTP isรคntรค
-smtp_port=SMTP portti
+smtp_addr=SMTP-isรคntรค
+smtp_port=SMTP-portti
smtp_from=Lรคhetรค sรคhkรถpostit osoitteella
smtp_from_helper=Sรคhkรถpostiosoite, jota Forgejo kรคyttรครค. Kirjoita osoite โnimiโ -muodossa.
mailer_user=SMTP-kรคyttรคjรคtunnus
mailer_password=SMTP-salasana
-register_confirm=Vaadi sรคhkรถpostin vahvistaminen rekisterรถintiin
-mail_notify=Ota kรคyttรถรถn sรคhkรถpostiilmoitukset
-server_service_title=Palvelin ja kolmansien osapuolten palveluiden asetukset
-offline_mode=Ota kรคyttรถรถn lokaali tila
-offline_mode.description=Poista kolmannen osapuolen sisรคllรถstรค jakeluverkot ja tarjoa kaikki resurssit paikallisesti.
+register_confirm=Vaadi sรคhkรถpostinvahvistus rekisterรถinnin edellytykseksi
+mail_notify=Ota sรคhkรถposti-ilmoitukset kรคyttรถรถn
+server_service_title=Palvelimen ja kolmansien osapuolten palveluiden asetukset
+offline_mode=Ota kรคyttรถรถn paikallinen tila
+offline_mode.description=Poista kolmannen osapuolen sisรคllรถnjakeluverkot ja tarjoa kaikki resurssit paikallisesti.
disable_gravatar=Poista Gravatar kรคytรถstรค
-disable_gravatar.description=Poista Gravatar ja kolmannen osapuolen avaratir kรคytรถstรค. Oletus-avatar nรคytetรครคn, ellei kรคyttรคjรค ole ladannut omaansa.
-federated_avatar_lookup=Kรคytรค ulkopuolisia profiilikuvia
-federated_avatar_lookup.description=Enable federated avatars lookup to use federated open source service based on libravatar.
-disable_registration=Poista rekisterรถinti kรคytรถstรค
-disable_registration.description=Poista kรคyttรคjรคn itse-rekisterรถinti, vain yllรคpito voi luoda tilejรค.
-allow_only_external_registration.description=Salli rekisterรถinti vain ulkopuolisista palveluista
-openid_signin=Ota OpenID kirjautuminen kรคyttรถรถn
-openid_signin.description=Ota kรคyttรถรถn kirjautuminen OpenID:n kautta.
-openid_signup=Ota kรคyttรถรถn OpenID itse-rekisterรถinti
-openid_signup.description=Ota kรคyttรถรถn OpenID-pohjainen kรคyttรคjรคn itse-rekisterรถinti.
+disable_gravatar.description=Poista Gravatar- tai muiden kolmansien osapuolien avatar-lรคhteet kรคytรถstรค. Oletuskuvia kรคytetรครคn kรคyttรคjien avatareissa, elleivรคt he uloslataa omaa avatariaan ilmentymรครคn.
+federated_avatar_lookup=Kรคytรค federoituja profiilikuvia
+federated_avatar_lookup.description=Kรคytรค Libravatar-palvelua profiilikuvien hakemiseen.
+disable_registration=Poista omatoiminen rekisterรถityminen kรคytรถstรค
+disable_registration.description=Vain jรคrjestelmรคnvalvojat voivat luoda uusia kรคyttรคjiรค. On suositeltavaa pitรครค rekisterรถinti suljettuna mikรคli kyseessรค ei ole julkinen instanssi jota varten tarvitsee hallinnoida suuria mรครคriรค roskapostikรคyttรคjiรค.
+allow_only_external_registration.description=Kรคyttรคjรคt voivat luoda uusia kรคyttรคjiรค vain erikseen konfiguroituja ulkoisia palveluja kรคyttรคen.
+openid_signin=Ota OpenID-kirjautuminen kรคyttรถรถn
+openid_signin.description=Salli OpenID:n kautta kirjautuminen.
+openid_signup=Ota OpenID-itserekisterรถinti kรคyttรถรถn
+openid_signup.description=Salli OpenID:n kautta rekisterรถinti mikรคli itserekisterรถinti on kรคytรถssรค.
enable_captcha=Ota kรคyttรถรถn CAPTCHA rekisterรถityessรค
-enable_captcha.description=Pakollinen captcha kรคyttรคjรคn itse rekisterรถityessรค.
-require_sign_in_view=Vaadi sisรครคnkirjautuminen sivujen nรคkemiseksi
+enable_captcha.description=Vaadi CAPTCHA rekisterรถinnin yhteydessรค.
+require_sign_in_view=Vaadi sisรครคnkirjautuminen sisรคllรถn nรคkemiseksi
admin_setting.description=Yllรคpitotilin luominen on valinnaista. Ensimmรคisestรค rekisterรถityneestรค kรคyttรคjรคstรค tulee automaattisesti yllรคpitรคjรค.
admin_title=Yllรคpitotilin asetukset
admin_name=Yllรคpitรคjรคn kรคyttรคjรคtunnus
@@ -245,20 +314,44 @@ admin_password=Salasana
confirm_password=Varmista salasana
admin_email=Sรคhkรถpostiosoite
install_btn_confirm=Asenna Forgejo
-test_git_failed=Epรคonnistui testata 'git' komentoa: %v
-sqlite3_not_available=Tรคmรค Forgejo versio ei tue SQLite3. Lataa virallinen binรครคriversio kohteesta %s (ei 'gobuild' versio).
+test_git_failed=Komennon 'git' testaus ei onnistunut: %v
+sqlite3_not_available=Tรคmรค Forgejo-versio ei tue SQLite3-ohjelmistoa. Lataa virallinen binรครคriversio kohteesta %s (ei 'gobuild'-versio).
invalid_db_setting=Tietokanta-asetukset ovat vรครคrin: %v
invalid_repo_path=Repojen juuri polku on virheellinen: %v
invalid_app_data_path=Sovelluksen datapolku on virheellinen: %v
internal_token_failed=Sisรคisen pรครคsymerkin luonti epรคonnistui: %v
save_config_failed=Asetusten tallentaminen epรคonnistui: %v
default_keep_email_private=Piilota sรคhkรถpostiosoitteet oletuksena
-default_keep_email_private.description=Piilota oletusarvoisesti uusien kรคyttรคjรคtilien sรคhkรถpostiosoitteet.
-default_enable_timetracking=Ota ajan seuranta oletusarvoisesti kรคyttรถรถn
-default_enable_timetracking.description=Ota kรคyttรถรถn uusien repojen aikaseuranta oletusarvoisesti.
-no_reply_address=Piilotettu sรคhkรถpostin verkkotunnus
-no_reply_address_helper=Verkkotunnuksen nimi kรคyttรคjille, joilla on piilotettu sรคhkรถpostiosoite. Esimerkiksi kรคyttรคjรคtunnus 'joe' kirjataan Git nimellรค 'joe@noreply.example.org' jos piilotettu sรคhkรถpostiosoite on asetettu 'noreply.example.org'.
+default_keep_email_private.description=Piilota oletusarvoisesti uusien kรคyttรคjรคtilien sรคhkรถpostiosoitteet estรครคksesi tietojen vuotamisen rekisterรถinnin yhteydessรค.
+default_enable_timetracking=Ota ajanseuranta oletusarvoisesti kรคyttรถรถn
+default_enable_timetracking.description=Salli uusien repositorioiden aikaseurannan kรคyttรถรถnotto oletusarvoisesti.
+no_reply_address=Piilotetun sรคhkรถpostin verkkotunnus
+no_reply_address_helper=Verkkotunnuksen nimi kรคyttรคjille, joilla on piilotettu sรคhkรถpostiosoite. Esimerkiksi kรคyttรคjรคtunnus 'joe' kirjataan Git-palveluun nimellรค 'joe@noreply.example.org' jos piilotetun sรคhkรถpostiosoitteen arvoksi on asetettu 'noreply.example.org'.
password_algorithm=Salasanan hajautusalgoritmi
+enable_update_checker_helper_forgejo = Se tarkistaa tietyin vรคliajoin uusia Forgejo-versioita tutkimalla sen TXT DNS record -tietoja osoitteesta release.forgejo.org .
+invalid_admin_setting = Jรคrjestelmรคnvalvojatilin asetukset eivรคt kelpaa: %v
+env_config_keys = Ympรคristรถkonfiguraatio
+run_user_helper = Kรคyttรถjรคrjestelmรคtason kรคyttรคjรคnimi, jona Forgejo ajetaan. Huomaa, ettรค kyseinen kรคyttรคjรค tarvitsee pรครคsyn repositorion juuripolkuun.
+env_config_keys_prompt = Seuraavat ympรคristรถmuuttujat sisรคllytetรครคn myรถs asetustiedostoonne:
+secret_key_failed = Salausavaimen generointi epรคonnistui: %v
+default_allow_create_organization.description = Salli organisaatioiden luonti uusille kรคyttรคjille oletuksena. Jรคrjestelmรคnvalvojan tarvitsee antaa lupa luoda organisaatioita mikรคli tรคmรค asetus on pois pรครคltรค.
+config_location_hint = Tallennettujen asetusten sijainti:
+invalid_db_table = Tietokantataulu "%s" ei kelpaa: %v
+invalid_password_algorithm = Salasananhajautusalgoritmi ei kelpaa
+password_algorithm_helper = Aseta salasananhajautusalgoritmi. Eri algoritmeilla on erilaisia vaatimuksia ja vahvuuksia - argon2-algoritmi on erityisen turvallinen mutta vaatii paljon muistia ja voi nรคin ollen olla pienille jรคrjestelmille soveltumaton.
+db_schema_helper = Jรคtรค tyhjรคksi kรคyttรครคksesi oletusarvoa ("public").
+run_user_not_match = Tรคmรคnhetkinen kรคyttรคjรคnimi ei tรคsmรครค tiettynรค kรคyttรคjรคnรค ajettavan kรคyttรคjรคnimen kanssa: %s -> %s
+invalid_log_root_path = Lokitiedoston polku ei kelpaa: %v
+require_sign_in_view.description = Rajoita sisรคltรถ vain kirjautuneille. Vieraat pรครคsevรคt vain autentikaatiosivuille.
+allow_only_external_registration = Salli rekisterรถinti vain ulkoisia palveluja kรคyttรคen
+default_allow_create_organization = Salli organisaatioiden luonti oletuksena
+allow_dots_in_usernames = Salli pisteiden kรคyttรถ kรคyttรคjรคnimissรค. Ei vaikuta olemassaoleviin kรคyttรคjiin.
+enable_update_checker = Ota pรคivitystentarkistus kรคyttรถรถn
+app_slogan = Instanssin tunnuslause
+app_slogan_helper = Syรถtรค instanssin tunnuslause tรคhรคn. Jรคtรค tyhjรคksi poistaaksesi kรคytรถstรค.
+domain_helper = Palvelimen verkkotunnus tai isรคntรคnimi.
+smtp_from_invalid = "Lรคhetรค sรคhkรถpostit osoitteella"-osoite on virheellinen
+err_admin_name_pattern_not_allowed = Yllรคpitรคjรคn kรคyttรคjรคtunnus on virheellinen, se vastaa varattua kaaviota
[home]
uname_holder=Kรคyttรคjรคtunnus tai sรคhkรถpostiosoite
@@ -299,6 +392,13 @@ user_no_results=Vastaavia kรคyttรคjiรค ei lรถytynyt.
org_no_results=Ei lรถytynyt vastaavia organisaatioita.
code_no_results=Hakuehtoasi vastaavaa lรคhdekoodia ei lรถytynyt.
code_last_indexed_at=Viimeksi indeksoitu %s
+stars_one = %d tรคhti
+stars_few = %d tรคhteรค
+relevant_repositories = Vain relevantit repositoriot nรคytetรครคn, nรคytรค suodattamattomat tulokset .
+forks_one = %d forkki
+forks_few = %d forkkia
+go_to = Siirry
+relevant_repositories_tooltip = Repot, jotka ovat forkkeja, joilla ei ole aiheita, ei kuvakkeita ja ei kuvausta, ovat piilotettuja.
[auth]
create_new_account=Rekisterรถi tili
@@ -310,18 +410,18 @@ remember_me=Muista tรคmรค laite
forgot_password_title=Unohtuiko salasana
forgot_password=Unohtuiko salasana?
sign_up_now=Tarvitsetko tilin? Rekisterรถidy nyt.
-confirmation_mail_sent_prompt=Uusi varmistussรคhkรถposti on lรคhetetty osoitteeseen %s , ole hyvรค ja tarkista saapuneet seuraavan %s tunnin sisรคllรค saadaksesi rekisterรถintiprosessin valmiiksi.
+confirmation_mail_sent_prompt=Uusi varmistussรคhkรถposti on lรคhetetty osoitteeseen %s . Tarkista sรคhkรถpostisi ja seuraa saamaasi linkkiรค seuraavan %s aikana saadaksesi rekisterรถintiprosessin valmiiksi. Mikรคli annettu sรคhkรถpostiosoite on vรครคrin, voit kirjautua sisรครคn ja pyytรครค uutta varmistussรคhkรถpostia toiseen osoitteeseen.
must_change_password=Vaihda salasanasi
allow_password_change=Vaadi kรคyttรคjรครค vaihtamaan salasanansa (suositeltava)
-reset_password_mail_sent_prompt=Varmistussรคhkรถposti on lรคhetetty osoitteeseen %s . Tarkista saapuneet seuraavan %s tunnin sisรคllรค saadaksesi tilin palauttamisen valmiiksi.
+reset_password_mail_sent_prompt=Varmistussรคhkรถposti on lรคhetetty osoitteeseen %s . Tarkista sรคhkรถpostisi ja seuraa annettua linkkiรค seuraavan %s aikana saadaksesi tilin palauttamisen valmiiksi.
active_your_account=Aktivoi tilisi
account_activated=Tili on aktivoitu
-prohibit_login=Kirjautuminen estetty
+prohibit_login=Tili on jรครคdytetty
resent_limit_prompt=Olet jo tilannut aktivointisรคhkรถpostin hetki sitten. Ole hyvรค ja odota 3 minuuttia ja yritรค sitten uudelleen.
has_unconfirmed_mail=Hei %s, sinulla on varmistamaton sรคhkรถposti osoite (%s ). Jos et ole saanut varmistus sรคhkรถpostia tai tarvitset uudelleenlรคhetyksen, ole hyvรค ja klikkaa allaolevaa painiketta.
resend_mail=Klikkaa tรคstรค uudelleenlรคhettรครคksesi aktivointi sรคhkรถpostisi
email_not_associate=Tรคtรค sรคhkรถpostiosoitetta ei ole liitetty mihinkรครคn tiliin.
-send_reset_mail=Lรคhetรค tilin palautussรคhkรถposti
+send_reset_mail=Lรคhetรค palautussรคhkรถposti
reset_password=Tilin palautus
invalid_code=Vahvistusavain on virheellinen tai vanhentunut.
reset_password_helper=Palauta kรคyttรคjรคtili
@@ -336,7 +436,7 @@ twofa_scratch_token_incorrect=Kertakรคyttรถkoodisi on virheellinen.
login_userpass=Kirjaudu sisรครคn
tab_openid=OpenID
oauth_signup_tab=Rekisterรถi uusi tili
-oauth_signup_title=Viimeistele tili
+oauth_signup_title=Viimeistele uusi tili
oauth_signup_submit=Viimeistele tili
oauth_signin_tab=Linkitรค olemassa olevaan tiliin
oauth_signin_title=Kirjaudu sisรครคn valtuuttaaksesi linkitetyn tilin
@@ -351,22 +451,47 @@ email_domain_blacklisted=Et voi rekisterรถityรค sรคhkรถpostiosoittellasi.
authorize_application=Valtuuta sovellus
authorize_redirect_notice=Sinut uudelleen ohjataan osoitteeseen %s jos valtuutat tรคmรคn sovelluksen.
authorize_application_created_by=Tรคmรคn sovelluksen on luonnut %s.
-authorize_application_description=Jos myรถnnรคt valtuuden, sovellus voi kรคyttรครค kaikkia tilitietojasi ja kirjoittaa niihin, mukaan lukien yksityiset repot ja organisaatiot.
+authorize_application_description=Jos myรถnnรคt valtuuden, sovellus voi kรคyttรครค kaikkia tilitietojasi ja kirjoittaa niihin, mukaan lukien yksityiset repositoriot ja organisaatiot.
authorize_title=Valtuutatko "%s" pรครคsemรครคn tilillesi?
authorization_failed=Kรคyttรถoikeuden varmistus epรคonnistui
sspi_auth_failed=SSPI todennus epรคonnistui
+sign_up_successful = Kรคyttรคjรคtili luotiin onnistuneesti. Tervetuloa!
+hint_login = Onko sinulla jo kรคyttรคjรคtili? Kirjaudu sisรครคn!
+hint_register = Tarvitsetko kรคyttรคjรคtilin? Rekisterรถidy nyt.
+sign_up_button = Rekisterรถidy nyt.
+manual_activation_only = Ota yhteyttรค jรคrjestelmรคnvalvojaanne viimeistellรคksesi aktivoinnin.
+change_unconfirmed_email_error = Sรคhkรถpostiosoitteen vaihtaminen ei onnistu: %v
+invalid_password = Salasanasi ei vastaa tilin luomisen yhteydessรค kรคytettyรค salasanaa.
+back_to_sign_in = Takaisin kirjautumiseen
+sign_in_openid = Jatka OpenID:llรค
+change_unconfirmed_email = Jos annoit vรครคrรคn sรคhkรถpostiosoitteen rekisterรถitymisen yhteydessรค, voit vaihtaa sen alapuolella, ja vahvistus lรคhetetรครคn uuteen osoitteeseen.
+invalid_code_forgot_password = Vahvistuskoodisi on virheellinen tai vanhentunut. Napsauta tรคstรค aloittaaksesi uuden istunnon.
+openid_signin_desc = Kirjoita OpenID-URI:si. Esimerkki: alice.openid.example.org tai https://openid.example.org/alice.
+change_unconfirmed_email_summary = Vaihda sรคhkรถpostiosoite, johon aktivointisรคhkรถposti lรคhetetรครคn.
+reset_password_wrong_user = Olet kirjautuneena tilillรค %s, mutta tilin palautuslinkki on tarkoitettu tilille %s
+last_admin = Et voi poistaa viimeistรค yllรคpitรคjรครค. Yllรคpitรคjiรค tulee olla vรคhintรครคn yksi.
+password_pwned = Valitsemasi salasana on varastettujen salasanojen listalla , eli se on paljastanut jossain julkisessa tietovuodossa. Kokeile asettaa eri salasana, ja jos kรคytรคt samaa salasanaa muissa palveluissa, vaihda kyseinen salasana.
+use_onetime_code = Kรคytรค kertakรคyttรถiskoodia
+unauthorized_credentials = Kirjautumistiedot ovat virheelliset tai vanhentuneet. Yritรค suorittaa komento uudelleen tai katso %s saadaksesi lisรคtietoja
+oauth.signin.error.temporarily_unavailable = Valtuus epรคonnistui, koska todennuspalvelin ei ole tรคllรค hetkellรค kรคytettรคvissรค. Yritรค uudelleen myรถhemmin.
+disable_forgot_password_mail = Tilin palautus ei ole kรคytรถssรค, koska sรคhkรถpostia ei ole mรครคritetty. Ota yhteys sivuston yllรคpitoon.
+password_pwned_err = Pyyntรถรค HaveIBeenPwned-palveluun ei voitu suorittaa
+authorization_failed_desc = Valtuus epรคonnistui, koska havaitsimme virheellisen pyynnรถn. Ota yhteys sen sovelluksen yllรคpitรคjรครคn, jota yritit valtuuttaa.
+oauth.signin.error = Valtuuspyynnรถn kรคsittelyssรค tapahtui virhe. Jos virhe toistuu, ota yhteys sivuston yllรคpitoon.
+disable_forgot_password_mail_admin = Tilin palautus on kรคytรถssรค vain, jos sรคhkรถposti on mรครคritetty. Aseta sรคhkรถposti, jotta tilin palauttaminen on mahdollista ottaa kรคyttรถรถn.
+prohibit_login_desc = Tilinne on estetty kanssakรคymรคstรค tรคmรคn instanssin kanssa. Ota yhteys instanssin jรคrjestelmรคvalvojaan pรครคsyn uudelleenmahdollistamiseksi.
[mail]
view_it_on=Nรคytรค %s
-link_not_working_do_paste=Eikรถ toimi? Yritรค kopioida ja liittรครค se selaimeesi.
+link_not_working_do_paste=Eikรถ linkki toimi? Yritรค kopioida ja liittรครค se selaimesi osoitepalkkiin.
hi_user_x=Hei %s ,
activate_account=Ole hyvรค ja aktivoi tilisi
activate_email=Vahvista sรคhkรถpostiosoitteesi
-register_notify=Tervetuloa Forgejoan
-register_notify.text_2=Voit nyt kirjautua kรคyttรคjรคtunnuksella: %s.
+register_notify=Tervetuloa %s-palveluun
+register_notify.text_2=Voit nyt kirjautua tilillesi kรคyttรคjรคtunnuksella: %s
reset_password=Palauta kรคyttรคjรคtili
reset_password.title=%s, olet pyytรคnyt tilisi palauttamista
@@ -386,26 +511,69 @@ release.download.zip=Lรคhdekoodi (ZIP)
release.download.targz=Lรคhdekoodi (TAR.GZ)
repo.transfer.to_you=sinรค
+password_change.subject = Salasanasi on vaihdettu
+password_change.text_1 = Tilisi salasana vaihdettiin juuri hetki sitten.
+removed_security_key.subject = Turva-avain on poistettu
+removed_security_key.text_1 = Turva-avain "%[1]s" on poistettu tililtรคsi.
+team_invite.text_2 = Napsauta seuraavaa linkkiรค liittyรคksesi tiimiin:
+activate_account.text_1 = Hei %[1]s , kiitos kun rekisterรถidyit palveluun %[2]s!
+activate_account.text_2 = Aktivoidaksesi tilin, napsauta alla olevaa linkkiรค aikaikkunan %s sisรคllรค:
+totp_disabled.subject = TOTP on poistettu kรคytรถstรค
+primary_mail_change.subject = Ensisijainen sรคhkรถpostiosoitteesi on vaihdettu
+admin.new_user.user_info = Kรคyttรคjรคtiedot
+activate_email.text = Vahvista sรคhkรถpostiosoitteesi napsauttamalla linkkiรค aikaikkunan %s sisรคllรค:
+admin.new_user.subject = Uusi kรคyttรคjรค %s rekisterรถityi juuri
+register_notify.text_3 = Jos joku muu teki tรคmรคn tilin puolestasi, aseta salasana ensin.
+repo.transfer.subject_to_you = %s haluaa siirtรครค repon "%s" sinulle
+reply = tai vastaa tรคhรคn sรคhkรถpostiin suoraan
+issue.action.new = @%[1]s loi #%[2]d.
+team_invite.subject = %[1]s kutsui sinut liittymรครคn organisaatioon %[2]s
+account_security_caution.text_2 = Jos se et ollut sinรค, tilisi on vaarantunut. Ota yhteys tรคmรคn sivuston yllรคpitoon.
+account_security_caution.text_1 = Jos se olit sinรค, voit jรคttรครค tรคmรคn viestin huomiotta.
+issue.action.approve = @%[1]s hyvรคksyi tรคmรคn vetopyynnรถn.
+issue.action.review = @%[1]s kommentoi tรคtรค vetopyyntรถรค.
+issue.action.ready_for_review = @%[1]s merkitsi tรคmรคn vetopyynnรถn valmiiksi katselmointia varten.
+totp_disabled.text_1 = Tilisi aikapohjainen kertakรคyttรถsalasana (TOTP) poistettiin kรคytรถstรค.
+issue.action.close = @%[1]s sulki ongelman #%[2]d.
+issue.action.reopen = @%[1]s avasi uudelleen ongelman #%[2]d.
+admin.new_user.text = Napsauta tรคstรค hallitaksesi tรคtรค kรคyttรคjรครค yllรคpitonรคkymรคstรค.
+repo.collaborator.added.text = Sinut on lisรคtty avustajaksi repoon:
+primary_mail_change.text_1 = Tilisi ensisijaiseksi sรคhkรถpostiosoitteeksi asetettiin %[1]s. Se tarkoittaa, ettรค tรคmรค sรคhkรถpostiosoite ei enรครค vastaanota tilisi ilmoituksia sรคhkรถpostitse.
+team_invite.text_1 = %[1]s on kutsunut sinut liittymรครคn tiimiin %[2]s organisaatiossa %[3]s.
+issue_assigned.pull = @%[1]s osoitti sinulle vetopyynnรถn %[2]s repossa %[3]s.
+issue_assigned.issue = @%[1]s osoitti sinulle ongelman %[2]s repossa %[3]s.
+register_notify.text_1 = tรคmรค on %s:n rekistรถrรถitymisen vahvistussรคhkรถposti!
+reset_password.text = jos tรคmรค oli sinun toimestasi, ole hyvรค ja klikkaa oheista linkkiรค palauttaaksesi tilisi %s sisรคllรค:
+totp_disabled.no_2fa = Muita kaksivaiheisen tunnistautumisen menetelmiรค ei ole konfiguroituna, joten et tarvitse kaksivaiheista tunnistautumista kirjautuaaksesi tilillesi.
+totp_enrolled.subject = Olet aktivoinut TOTP:in kaksivaiheisen todennuksen menetelmรคksi
+
+removed_security_key.no_2fa = Yhtรครคn kaksivaiheisen tunnistautumisen menetelmรครค ei ole mรครคritelty, joten tilillesi ei enรครค tarvitse kirjautua kaksivaiheisella tunnistautumisella.
+totp_enrolled.text_1.no_webauthn = Otit TOTP:n kรคyttรถรถn tilillesi. Tรคmรค tarkoittaa, ettรค kirjauduttaessa sisรครคn tilillesi sinun tรคytyy kรคyttรครค TOTP menetelmรครค kaksivaiheisena tunnistautumisena.
+totp_enrolled.text_1.has_webauthn = Otit TOTP:n kรคyttรถรถn tilillesi. Tรคmรค tarkoittaa, ettรค kirjauduttaessa sisรครคn tilillesi voit kรคyttรครค TOTP menetelmรครค kaksivaiheisena tunnistautumisena tai mitรค tahansa turva-avaimiasi.
+repo.collaborator.added.subject = %s lisรคsi sinut %s yhteistyรถkumppaniksi
+team_invite.text_3 = Huomaa: Tรคmรค kutsu on tarkoitettu %[1]s:lle. Jos et odottanut tรคtรค kutsua, voit jรคttรครค tรคmรคn sรคhkรถpostin huomiotta.
+
[modal]
yes=Kyllรค
no=Ei
cancel=Peruuta
modify=Pรคivitys
+confirm = Vahvista
[form]
UserName=Kรคyttรคjรคtunnus
RepoName=Repon nimi
Email=Sรคhkรถposti osoite
Password=Salasana
-Retype=Varmista salasana
+Retype=Vahvista salasana
SSHTitle=SSH avain nimi
HttpsUrl=HTTPS-osoite
TeamName=Tiimin nimi
AuthName=Luvan nimi
-AdminEmail=Yllรคpito sรคhkรถposti
+AdminEmail=Yllรคpitรคjรคn sรคhkรถposti
NewBranchName=Uuden haaran nimi
CommitSummary=Commitin yhteenveto
@@ -451,13 +619,32 @@ auth_failed=Todennus epรคonnistui: %v
target_branch_not_exist=Kohde branchia ei ole olemassa.
+Pronouns = Pronomini
+FullName = Koko nimi
+Description = Kuvaus
+Biography = Biografia
+Website = Verkkosivusto
+Location = Sijainti
+To = Haaran nimi
+still_own_repo = Tilisi omistaa yhden tai useamman repon, poista tai siirrรค ne ensin.
+organization_leave_success = Olet poistunut organisaatiosta %s.
+enterred_invalid_repo_name = Kirjoittamasi repon nimi on virheellinen.
+openid_been_used = OpenID-osoite "%s" on jo kรคytetty.
+password_complexity = Salasana ei tรคytรค monimutkaisuusvaatimuksia:
+still_has_org = Tilisi on jรคsen yhdessรค tai useamassa organisaatiossa, poistu niistรค ensin.
+unable_verify_ssh_key = SSH-avainta ei voi vahvistaa, tarkista se mahdollisten virheiden varalta.
+url_error = `"%s" ei ole kelvollinen URL-osoite.`
+must_use_public_key = Antamasi avain on yksityinen avain. รlรค lรคhetรค yksityistรค avaintasi mihinkรครคn. Kรคytรค sen sijaan julkista avaintasi.
+still_own_packages = Tilisi omistaa yhden tai useamman paketin, poista ne ensin.
+AccessToken = Pรครคsypoletti
+enterred_invalid_owner_name = Uuden omistajan nimi ei ole kelvollinen.
[user]
change_avatar=Vaihda profiilikuvasiโฆ
repositories=Repot
activity=Julkinen toiminta
-followers_few=%d seuraajat
+followers_few=%d seuraajaa
starred=Tรคhdelliset repot
projects=Projektit
overview=Yleiskatsaus
@@ -465,8 +652,33 @@ following_few=%d seurataan
follow=Seuraa
unfollow=Lopeta seuraaminen
user_bio=Elรคmรคkerta
+settings = Kรคyttรคjรคasetukset
+email_visibility.limited = Sรคhkรถpostiosoitteesi nรคkyy kaikille tunnistautuneille kรคyttรคjille
+followers_one = %d seuraaja
+public_activity.visibility_hint.self_public = Toimintasi on nรคkyvissรค kaikille, lukuun ottamatta vuorovaikutusta yksityisissรค tiloissa. Mรครคritรค asetukset .
+followers.title.one = seuraaja
+followers.title.few = seuraajaa
+following.title.one = Seurataan
+following.title.few = Seurataan
+joined_on = Liittynyt %s
+public_activity.visibility_hint.self_private = Toimintasi nรคkyy vain sinulle ja instanssin yllรคpitรคjille. Mรครคritรค .
+block = Estรค
+block_user = Estรค kรคyttรคjรค
+code = Koodi
+unblock = Poista esto
+following_one = %d seurataan
+block_user.detail = Huomaa, ettรค kรคyttรคjรคn estรคmisellรค on muita vaikutuksia, kuten:
+show_on_map = Nรคytรค paikka kartalla
+form.name_chars_not_allowed = Kรคyttรคjรคtunnus "%s" sisรคltรครค virheellisiรค merkkejรค.
+follow_blocked_user = Et voi seurata tรคtรค kรคyttรคjรครค, koska olet estรคnyt kyseisen kรคyttรคjรคn tai kyseinen kรคyttรคjรค on estรคnyt sinut.
+disabled_public_activity = Kรคyttรคjรค on poistanut kรคytรถstรค toiminnan julkisen nรคkyvyyden.
+form.name_reserved = Kรคyttรคjรคtunnus "%s" on varattu.
+form.name_pattern_not_allowed = Kaava "%s" ei ole sallittu kรคyttรคjรคtunnuksessa.
+public_activity.visibility_hint.admin_private = Aktiivisuus on nรคkyvissรค sinulle, koska olet yllรคpitรคjรค, mutta kรคyttรคjรค haluaa pitรครค aktiivisuutensa yksityisenรค.
+public_activity.visibility_hint.self_private_profile = Aktiivisuutesi on nรคkyvissรค vain sinulle ja instanssin yllรคpitรคjille, koska profiilisi on yksityinen. Mรครคritรค .
+
[settings]
profile=Profiili
account=Tili
@@ -474,25 +686,25 @@ appearance=Ulkoasu
password=Salasana
security=Turvallisuus
avatar=Profiilikuva
-ssh_gpg_keys=SSH / GPG-avaimet
+ssh_gpg_keys=SSH-/GPG-avaimet
social=Sosiaaliset tilit
applications=Sovellukset
-orgs=Hallitse organisaatioita
+orgs=Organisaatiot
repos=Repot
delete=Poista tili
-twofa=Kaksivaiheinen todennus
+twofa=Kaksivaiheinen todennus (TOTP)
account_link=Linkitetyt tilit
organization=Organisaatiot
-webauthn=Turva-avaimet
+webauthn=Kaksivaiheinen todennus (Turva-avaimet)
public_profile=Julkinen profiili
password_username_disabled=Ei-paikalliset kรคyttรคjรคt eivรคt voi muuttaa kรคyttรคjรคtunnustaan. Ole hyvรค ja ota yhteyttรค sivuston yllรคpitรคjรครคn saadaksesi lisรคtietoa.
-full_name=Kokonimi
-website=Nettisivut
+full_name=Koko nimi
+website=Verkkosivusto
location=Sijainti
-update_theme=Pรคivitรค teema
+update_theme=Vaihda teema
update_profile=Pรคivitรค profiili
-update_language=Pรคivitรค kieli
+update_language=Vaihda kieli
update_language_success=Kieli on pรคivitetty.
update_profile_success=Profiilisi on pรคivitetty.
change_username=Kรคyttรคjรคtunnuksesi on muutettu.
@@ -507,7 +719,7 @@ comment_type_group_milestone=Merkkipaalu
comment_type_group_assignee=Osoitettu henkilรถlle
comment_type_group_title=Otsikko
comment_type_group_branch=Haara
-comment_type_group_time_tracking=Ajan seuranta
+comment_type_group_time_tracking=Ajanseuranta
comment_type_group_deadline=Mรครคrรคaika
comment_type_group_dependency=Riippuvuus
comment_type_group_lock=Lukituksen tila
@@ -520,7 +732,7 @@ keep_activity_private_popup=Tekee toiminnon nรคkyvรคn vain sinulle ja yllรคpitรค
lookup_avatar_by_mail=Hae profiilikuva sรคhkรถpostin perusteella
federated_avatar_lookup=Ulkopuolinen profiilikuvan haku
-enable_custom_avatar=Ota kรคyttรถรถn mukautettu profiilikuva
+enable_custom_avatar=Kรคytรค mukautettua profiilikuvaa
choose_new_avatar=Valitse uusi profiilikuva
update_avatar=Pรคivitรค profiilikuva
delete_current_avatar=Poista nykyinen profiilikuva
@@ -535,9 +747,9 @@ password_change_disabled=Ei-lokaalit kรคyttรคjรคt eivรคt voi pรคivittรครค salasa
emails=Sรคhkรถposti osoitteet
manage_emails=Hallitse sรคhkรถpostiosoitteita
-manage_themes=Valitse oletusteema
-manage_openid=Hallitse OpenID osoitteita
-theme_desc=Tรคmรค on sivuston oletusteemasi.
+manage_themes=Oletusteema
+manage_openid=OpenID-osoitteet
+theme_desc=Tรคtรค teemaa kรคytetรครคn verkkosivuston kรคyttรถliittymรคssรค, kun olet sisรครคnkirjautuneena.
primary=Ensisijainen
activated=Aktivoitu
requires_activation=Vaatii aktivoinnin
@@ -553,7 +765,7 @@ theme_update_error=Valittua teemaa ei lรถydy.
openid_deletion=Poista OpenID-osoite
openid_deletion_success=OpenID-osoite on poistettu.
add_new_email=Lisรครค uusi sรคhkรถpostiosoite
-add_new_openid=Lisรครค uusi OpenID URI
+add_new_openid=Lisรครค uusi OpenID-URI
add_email=Lisรครค sรคhkรถpostiosoite
add_openid=Lisรครค OpenID URI
add_email_success=Uusi sรคhkรถpostiosoite on lisรคtty.
@@ -562,17 +774,17 @@ add_openid_success=Uusi OpenID-osoite on lisรคtty.
keep_email_private=Piilota sรคhkรถpostiosoite
openid_desc=OpenID mahdollistaa todentamisen delegoinnin ulkopuoliselle palvelun tarjoajalle.
-manage_ssh_keys=Hallitse SSH avaimia
-manage_gpg_keys=Hallitse GPG avaimia
+manage_ssh_keys=Hallitse SSH-avaimia
+manage_gpg_keys=Hallitse GPG-avaimia
add_key=Lisรครค avain
-ssh_desc=Nรคmรค julkiset SSH-avaimet on liitetty tiliisi. Vastaavat yksityiset avaimet antavat tรคyden pรครคsyn repoihisi.
-gpg_desc=Nรคmรค julkiset GPG-avaimet on liitetty tiliisi. Pidรค yksityiset avaimet turvassa, koska ne mahdollistavat committien todentamisen.
+ssh_desc=Nรคmรค julkiset SSH-avaimet on liitetty tiliisi. Vastaavat yksityiset avaimet antavat tรคyden pรครคsyn repoihisi. Vahvistettuja SSH-avaimia voi kรคyttรครค SSH-allekirjoitettujen Git-kommittien vahvistamiseen.
+gpg_desc=Nรคmรค julkiset GPG-avaimet on liitetty tiliisi, ja niitรค kรคytetรครคn kommittien vahvistamiseen. Pidรค yksityiset avaimet turvassa, koska ne mahdollistavat kommittien allekirjoittamisen sinun nimissรค.
ssh_helper=Tarvitsetko apua? Tutustu GitHubin oppaaseen omien SSH-avainten luonnista tai yleisistรค ongelmista , joita voit kohdata SSH:n kanssa.
gpg_helper=Tarvitsetko apua? Katso GitHubin opas GPG :stรค.
add_new_key=Lisรครค SSH avain
add_new_gpg_key=Lisรครค GPG-avain
-key_content_ssh_placeholder=Alkaa sanoilla 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', tai 'sk-ssh-ed25519@openssh.com'
-key_content_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP PUBLIC KEY BLOCK-----'
+key_content_ssh_placeholder=Alkaa sanoilla "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com" tai "sk-ssh-ed25519@openssh.com"
+key_content_gpg_placeholder=Alkaa sanoilla "-----BEGIN PGP PUBLIC KEY BLOCK-----"
ssh_key_name_used=Samanniminen SSH avain on jo olemassa tilillรคsi.
gpg_key_id_used=Julkinen GPG-avain samalla tunnuksella on jo olemassa.
gpg_no_key_email_found=Tรคmรค GPG-avain ei vastaa mitรครคn tiliisi liitettyรค aktivoitua sรคhkรถpostiosoitetta. Se voidaan silti lisรคtรค, jos allekirjoitat annetun pรครคsymerkin.
@@ -584,7 +796,7 @@ gpg_token=Pรครคsymerkki
gpg_token_help=Voit luoda allekirjoituksen kรคyttรคen:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=Panssaroitu GPG-allekirjoitus
-key_signature_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP SIGNATURE-----'
+key_signature_gpg_placeholder=Alkaa sanoilla "-----BEGIN PGP SIGNATURE-----"
ssh_key_verified=Vahvistettu avain
ssh_key_verified_long=Avain on vahvistettu pรครคsymerkillรค ja sitรค voidaan kรคyttรครค todentamaan commitit, jotka vastaavat tรคmรคn kรคyttรคjรคn aktivoituja sรคhkรถpostiosoitteita.
ssh_key_verify=Vahvista
@@ -592,7 +804,7 @@ ssh_token_required=Sinun tรคytyy antaa allekirjoitus alla olevalle pรครคsymerkil
ssh_token=Pรครคsymerkki
ssh_token_help=Voit luoda allekirjoituksen kรคyttรคen:
ssh_token_signature=Panssaroitu SSH-allekirjoitus
-key_signature_ssh_placeholder=Alkaa sanoilla '-----BEGIN SSH SIGNATURE-----'
+key_signature_ssh_placeholder=Alkaa sanoilla "-----BEGIN SSH SIGNATURE-----"
subkeys=Aliavaimet
key_id=Avain ID
key_name=Avaimen nimi
@@ -610,7 +822,7 @@ can_read_info=Luku
can_write_info=Kirjoitus
show_openid=Nรคytรค profiilissa
hide_openid=Piilota profiilista
-ssh_disabled=SSH pois kรคytรถstรค
+ssh_disabled=SSH on pois kรคytรถstรค
manage_social=Hallitse liitettyjรค sosiaalisia tilejรค
manage_access_token=Hallitse pรครคsymerkkejรค
@@ -624,14 +836,14 @@ access_token_deletion_cancel_action=Peruuta
access_token_deletion_confirm_action=Poista
permission_read=Luettu
-edit_oauth2_application=Muokkaa OAuth2 sovellusta
-remove_oauth2_application=Poista OAuth2 sovellus
+edit_oauth2_application=Muokkaa OAuth2-sovellusta
+remove_oauth2_application=Poista OAuth2-sovellus
remove_oauth2_application_success=Sovellus on poistettu.
-create_oauth2_application=Luo uusi OAuth2 sovellus
+create_oauth2_application=Luo uusi OAuth2-sovellus
create_oauth2_application_button=Luo sovellus
oauth2_application_name=Sovelluksen nimi
save_application=Tallenna
-oauth2_regenerate_secret=Luo secret uudelleen
+oauth2_regenerate_secret=Luo salaisuus uudelleen
oauth2_regenerate_secret_hint=Kadotitko secretin?
oauth2_application_edit=Muokkaa
@@ -647,10 +859,10 @@ twofa_enrolled=Tiliisi on otettu kรคyttรถรถn kaksivaiheinen vahvistus. Ota palau
webauthn_nickname=Nimimerkki
-manage_account_links=Hallitse linkitettyjรค tilejรค
-manage_account_links_desc=Nรคmรค ulkoiset tilit on linkitetty Forgejo tiliisi.
+manage_account_links=Yhdistetyt tilit
+manage_account_links_desc=Nรคmรค ulkoiset tilit on linkitetty Forgejo-tiliisi.
link_account=Yhdistรค tili
-remove_account_link=Poista linkitetty tili
+remove_account_link=Poista yhdistetty tili
remove_account_link_desc=Linkitetyn tilin poistaminen peruuttaa pรครคsyn Forgejo-tiliisi linkitetyn tili kautta. Jatketaanko?
remove_account_link_success=Linkitetty tili on poistettu.
@@ -659,7 +871,7 @@ orgs_none=Et ole minkรครคn organisaation jรคsen.
delete_account=Poista tilisi
delete_prompt=Tรคmรค toiminto poistaa kรคyttรคjรคtilisi pysyvรคsti. Toimintoa EI VOI kumota.
-confirm_delete_account=Varmista poisto
+confirm_delete_account=Vahvista poisto
delete_account_title=Poista kรคyttรคjรคtili
email_notifications.enable=Ota kรคyttรถรถn sรคhkรถposti-ilmoitukset
@@ -668,6 +880,109 @@ visibility=Kรคyttรคjรคn nรคkyvyys
visibility.public=Julkinen
visibility.limited=Rajattu
visibility.private=Yksityinen
+hints = Vihjeet
+user_block_success = Kรคyttรคjรค on estetty.
+biography_placeholder = Kerro jotain itsestรคsi! (Markdown on tuettu)
+keep_activity_private = Piilota toiminta profiilisivulla
+update_oauth2_application_success = Pรคivitit OAuth2-sovelluksen.
+webauthn_delete_key = Poista turva-avain
+delete_account_desc = Haluatko varmasti poistaa tรคmรคn kรคyttรคjรคtilin pysyvรคsti?
+visibility.public_tooltip = Nรคkyvissรค kaikille
+pronouns = Pronomini
+pronouns_custom = Mukautettu
+language.title = Oletuskieli
+webauthn_delete_key_desc = Jos poistat turva-avaimen, et voi enรครค kirjautua sillรค. Jatketaanko?
+authorized_oauth2_applications = Valtuutetut OAuth2-sovellukset
+pronouns_unspecified = Mรครคrittรคmรคtรถn
+update_hints = Pรคivitรค vihjeet
+language.description = Tรคmรค kieli tallennetaan tilillesi ja sitรค kรคytetรครคn oletuksena sisรครคnkirjautumisen jรคlkeen.
+language.localization_project = Auta suomentamaan Forgejo! Lue lisรครค .
+blocked_users_none = Kรคyttรคjiรค ei ole estetty.
+location_placeholder = Jaa likimรครคrรคinen sijaintisi muiden kanssa
+retype_new_password = Vahvista uusi salasana
+create_oauth2_application_success = Loit uuden OAuth2-sovelluksen.
+repos_none = Et omista yhtรคkรครคn repositoriota.
+visibility.limited_tooltip = Nรคkyvissรค vain kirjautuneille kรคyttรคjille
+email_notifications.disable = Poista sรคhkรถposti-ilmoitukset kรคytรถstรค
+webauthn_register_key = Lisรครค turva-avain
+blocked_users = Estetyt kรคyttรคjรคt
+profile_desc = Tietoja sinusta
+change_password_success = Salasanasi on pรคivitetty. Kirjaudu jatkossa kรคyttรคen uutta salasanaa.
+manage_oauth2_applications = Hallitse OAuth2-sovelluksia
+change_password = Vaihda salasana
+webauthn_key_loss_warning = Jos menetรคt turva-avaimesi, menetรคt pรครคsyn tilillesi.
+keep_activity_private.description = Julkinen toimintasi nรคkyy vain sinulle ja instanssin yllรคpitรคjille.
+email_desc = Ensisijaista sรคhkรถpostiosoitettasi kรคytetรครคn ilmoituksiin, salasanan palautukseen ja jos sรคhkรถpostiosoite ei ole piilotettu, web-pohjaisiin Git-toimenpiteisiin.
+tokens_desc = Nรคmรค poletit mahdollistavat pรครคsyn tilillesi Forgejon rajapintaa vasten.
+keep_email_private_popup = Tรคmรค piilottaa sรคhkรถpostiosoitteesi profiilistasi. Se ei ole enรครค oletus verkkosivukรคyttรถliittymรคn kautta tehdyissรค kommiteissa, kuten tiedostojen lรคhetyksissรค ja muokkauksissa, eikรค sitรค kรคytetรค yhdistรคmiskommiteissa. Sen sijaan erikoisosoitetta %s voidaan kรคyttรครค kommittien liittรคmisessรค tiliisi. Ota huomioon, ettei tรคmรคn asetuksen muuttaminen vaikuta olemassa oleviin kommitteihin.
+added_on = Lisรคtty %s
+additional_repo_units_hint = Ehdota repositorion lisรคyksikรถiden kรคyttรถรถnottoa
+revoke_oauth2_grant_success = Pรครคsy mitรคtรถity.
+revoke_oauth2_grant = Mitรคtรถi pรครคsy
+webauthn_desc = Turva-avaimet ovat kryptografisia avaimia sisรคltรคviรค laitteita. Niitรค on mahdollista kรคyttรครค kaksivaiheiseen todennukseen. Turva-avainten on pakko tukea WebAuthn Authenticator -standardia.
+permissions_public_only = Vain julkinen
+repo_and_org_access = Repojen ja organisaatioiden pรครคsy
+revoke_oauth2_grant_description = Pรครคsyn mitรคtรถinti tรคlle kolmannen osapuolen sovellukselle estรครค sitรค pรครคsemรคstรค dataasi. Oletko varma?
+twofa_recovery_tip = Jos menetรคt laitteesi, voit palauttaa pรครคsyn tiliisi kรคyttรคmรคllรค kertakรคyttรถisen palautusavaimen.
+hooks.desc = Lisรครค webkoukkuja, jotka suoritetaan kaikille omistamillesi repoille .
+revoke_key = Mitรคtรถi
+permissions_list = Kรคyttรถoikeudet:
+at_least_one_permission = Pรครคsymerkin luominen vaatii vรคhintรครคn yhden kรคyttรถoikeuden
+select_permissions = Valitse kรคyttรถoikeudet
+twofa_disable_note = Voit poistaa kaksivaiheisen todennuksen kรคytรถstรค, jos tarve.
+authorized_oauth2_applications_description = Olet myรถntรคnyt pรครคsyn henkilรถkohtaiseen Forgejo-tiliisi nรคille kolmannen osapuolen sovelluksille. Jos et enรครค kรคytรค sovellusta, mitรคtรถi sen pรครคsy tilillesi.
+permission_write = Lue ja kirjoita
+permissions_access_all = Kaikki (julkinen, yksityinen ja rajattu)
+permission_no_access = Ei pรครคsyรค
+hidden_comment_types_description = Tรคssรค valittuja kommenttityyppejรค ei nรคytetรค ongelmasivuilla. Merkitsemรคllรค "Label" esimerkiksi poistaa kaikki " added/removed "-kommentit.
+webauthn_alternative_tip = Saatat haluta mรครคrittรครค lisรคtodennusmenetelmรคn.
+twofa_disable = Poista kaksivaiheinen todennus kรคytรถstรค
+twofa_disable_desc = Kaksivaiheisen todennuksen poistaminen asettaa tilisi aiempaa suurempaan uhkaan. Jatketaanko?
+update_language_not_found = Kieli "%s" ei ole kรคytettรคvissรค.
+change_username_prompt = Huomio: Kรคyttรคjรคtunnuksen vaihtaminen muuttaa myรถs tilisi URL-osoitteen.
+oauth2_client_secret_hint = Tรคtรค salaisuutta ei nรคytetรค uudelleen, kun olet poistunut sivulta tai pรคivittรคnyt sivun. Varmista, ettรค olet ottanut salaisuuden talteen.
+blocked_since = Estetty %s lรคhtien
+user_unblock_success = Kรคyttรคjรคn esto on poistettu.
+oauth2_redirect_uris = Uudelleenohjaus-URI:t. Kรคytรค uutta riviรค (newline) jokaista URI:a kohden.
+oauth2_client_secret = Asiakkaan salaisuus
+verify_ssh_key_success = SSH-avain "%s" on vahvistettu.
+change_username_redirect_prompt = Vanha kรคyttรคjรคtunnus uudelleenohjaa, kunnes joku muu ottaa kรคyttรคjรคtunnuksen kรคyttรถnsรค.
+uploaded_avatar_is_too_big = Lรคhetetyn tiedoston koko (%d KiB) ylittรครค enimmรคiskoon (%d KiB).
+ssh_key_been_used = Tรคmรค SSH-avain on jo lisรคtty palvelimelle.
+verify_gpg_key_success = GPG-avain "%s" on vahvistettu.
+add_key_success = SSH-avain "%s" on lisรคtty.
+add_gpg_key_success = GPG-avain "%s" on lisรคtty.
+ssh_key_deletion_success = SSH-avain on poistettu.
+valid_until_date = Kelvollinen %s asti
+oauth2_client_id = Asiakkaan tunniste
+email_notifications.onmention = Ilmoitus vain maininnasta
+email_notifications.submit = Aseta valinta
+email_notifications.andyourown = Ja omat ilmoitukset
+key_state_desc = Tรคtรค avainta on kรคytetty viimeisen 7 pรคivรคn aikana
+oauth2_application_create_description = OAuth2-sovellukset mahdollistavat kolmannen osapuolen sovelluksen pรครคsyn tilillesi tรคssรค instanssissa.
+oauth2_confidential_client = Luottamuksellinen sovellus. Valitse sovelluksille, jotka pitรคvรคt salaisuuden luottamuksellisena, kuten web-sovelluksille. รlรค valitse natiiveille sovelluksille mukaan lukien tyรถpรถytรค- ja mobiilisovellukset.
+ssh_key_deletion_desc = SSH-avaimen poistaminen kumoaa pรครคsyn tilillesi kyseistรค avainta kรคyttรคen. Jatketaanko?
+add_email_confirmation_sent = Vahvistusviesti on lรคhetetty osoitteeseen "%s". Vahvista sรคhkรถpostiosoitteesi seuraavan %s sisรคllรค.
+pronouns_custom_label = Mukautetut pronominit
+openid_deletion_desc = Tรคmรคn OpenID-osoitteen poistaminen tililtรคsi estรครค kirjautumisen sitรค kรคyttรคen. Jatketaanko?
+generate_token_name_duplicate = Nimeรค %s on jo kรคytetty sovelluksen nimenรค. Kรคytรค eri nimeรค.
+ssh_signonly = SSH on tรคllรค hetkellรค poistettu kรคytรถstรค, joten nรคitรค avaimia kรคytetรครคn vain kommittien allekirjoituksen vahvistamiseen.
+oauth2_applications_desc = OAuth2-sovellukset mahdollistavat kรคyttรคmรคsi kolmannen osapuolen sovelluksen todentaa turvallisesti kรคyttรคjiรค tรคhรคn Forgejo-instanssiin.
+quota.sizes.assets.attachments.all = Liitteet
+quota.applies_to_user = Seuraavia kiintiรถsรครคntรถjรค sovelletaan tiliisi
+user_block_yourself = Et voi estรครค itseรคsi.
+quota = Kiintiรถ
+storage_overview = Tallennustilan yleisnรคkymรค
+quota.applies_to_org = Seuraavia kiintiรถsรครคntรถjรค sovelletaan tรคhรคn organisaatioon
+quota.rule.exceeded = Ylitetty
+quota.rule.no_limit = Rajoittamaton
+quota.sizes.all = Kaikki
+quota.sizes.repos.all = Repot
+quota.sizes.repos.public = Julkiset repot
+quota.sizes.repos.private = Yksityiset repot
+quota.sizes.git.all = Git-sisรคltรถ
+quota.sizes.assets.packages.all = Paketit
+quota.sizes.wiki = Wiki
[repo]
owner=Omistaja
@@ -676,7 +991,7 @@ repo_name=Repon nimi
repo_name_helper=Hyvรค repon nimi on lyhyt, mieleenpainuva ja yksilรถllinen.
repo_size=Repon koko
template=Malli
-template_select=Valitse malli.
+template_select=Valitse malli
template_helper=Tee reposta mallipohja
visibility=Nรคkyvyys
visibility_description=Vain omistaja tai organisaation jรคsenet, jos heillรค on oikeudet, voivat nรคhdรค sen.
@@ -689,15 +1004,15 @@ download_zip=Lataa ZIP
download_tar=Lataa TAR.GZ
repo_desc=Kuvaus
repo_lang=Kieli
-repo_gitignore_helper=Valitse .gitignore mallit.
-issue_labels=Ongelmien tunnisteet
-issue_labels_helper=Valitse pohja ongelmien nimilapuille.
+repo_gitignore_helper=Valitse .gitignore-mallit
+issue_labels=Tunnisteet
+issue_labels_helper=Valitse nimiรถjoukko
license=Lisenssi
-license_helper=Valitse lisenssitiedosto.
+license_helper=Valitse lisenssitiedosto
readme=README
-auto_init=Alusta repo (Luo .gitignore, License ja README)
+auto_init=Alusta repo
create_repo=Luo repo
-default_branch=Oletus branch
+default_branch=Oletushaara
mirror_prune=Karsi
watchers=Tarkkailijat
stargazers=Tรคhtiharrastajat
@@ -727,13 +1042,13 @@ migrate_items_labels=Tunnisteet
migrate_items_issues=Ongelmat
migrate_items_pullrequests=Vetopyynnรถt
migrate_items_releases=Julkaisut
-migrate_repo=Siirrรค repo
-migrate.clone_address=Migraation / Kloonaa URL osoitteesta
+migrate_repo=Tee repomigraatio
+migrate.clone_address=Migraatio/kloonaus URL-osoitteesta
migrate.github_token_desc=Voit laittaa yhden tai useamman pรครคsymerkin pilkulla erotellen tรคhรคn nopeuttaaksesi migraatiota GitHub APIn vauhtirajojen takia. VAROITUS: Tรคmรคn ominaisuuden vรครคrinkรคyttรถ voi rikkoa palveluntarjoajan ehtoja ja johtaa tilin estรคmiseen.
migrate.permission_denied=Sinun ei sallita tuovan paikallisia repoja.
migrate.failed=Siirto epรคonnistui: %v
migrate.migrate_items_options=Pรครคsymerkki vaaditaan lisรคkohteiden siirtรคmiseen
-migrate.migrating=Tuodaan kohteesta %s ...
+migrate.migrating=Tuodaan kohteesta %s โฆ
migrate.migrating_failed=Tuonti kohteesta %s epรคonnistui.
migrate.migrating_git=Tuodaan Git-tietoja
@@ -754,10 +1069,10 @@ code.desc=Pรครคsy lรคhdekoodiin, tiedostoihin, committeihin ja haaroihin.
branch=Haara
tree=Puu
filter_branch_and_tag=Suodata haara tai tagi
-branches=Branchit
+branches=Haarat
tags=Tagit
issues=Ongelmat
-pulls=Pull-pyynnรถt
+pulls=Vetopyynnรถt
project_board=Projektit
packages=Paketit
labels=Tunnisteet
@@ -773,13 +1088,13 @@ file_history=Historia
file_view_raw=Nรคytรค raaka
file_permalink=Pysyvรค linkki
-video_not_supported_in_browser=Selaimesi ei tue HTML5 video-tagia.
-audio_not_supported_in_browser=Selaimesi ei tue HTML5 audio-tagia.
+video_not_supported_in_browser=Selaimesi ei tue HTML5:n video-tagia.
+audio_not_supported_in_browser=Selaimesi ei tue HTML5:n audio-tagia.
blame=Selitys
download_file=Lataa tiedosto
normal_view=Normaali nรคkymรค
line=rivi
-lines=rivejรค
+lines=riviรค
editor.new_file=Uusi tiedosto
editor.upload_file=Lรคhetรค tiedosto
@@ -793,9 +1108,9 @@ editor.filename_help=Lisรครค hakemisto kirjoittamalla sen nimi ja sen jรคlkeen k
editor.or=tai
editor.cancel_lower=Peru
editor.commit_signed_changes=Commitoi vahvistetut muutokset
-editor.commit_changes=Commitoi muutokset
-editor.add_tmpl=Lisรครค ''
-editor.commit_directly_to_this_branch=Commitoi suoraan %s haaraan.
+editor.commit_changes=Kommitoi muutokset
+editor.add_tmpl=Lisรครค "<%s>"
+editor.commit_directly_to_this_branch=Commitoi suoraan %[1]s haaraan.
editor.create_new_branch=Luo uusi haara tรคlle commitille ja aloita vetopyyntรถ.
editor.create_new_branch_np=Luo uusi haara tรคlle commitille.
editor.cancel=Peruuta
@@ -814,8 +1129,8 @@ commits.date=Pรคivรคmรครคrรค
commits.older=Vanhemmat
commits.newer=Uudemmat
commits.signed_by=Allekirjoittanut
-commits.gpg_key_id=GPG avaimen ID
-commits.ssh_key_fingerprint=SSH avaimen sormenjรคlki
+commits.gpg_key_id=GPG-avaimen ID
+commits.ssh_key_fingerprint=SSH-avaimen sormenjรคlki
commitstatus.error=Virhe
@@ -830,9 +1145,9 @@ projects.new=Uusi projekti
projects.deletion=Poista projekti
projects.deletion_success=Projekti on poistettu.
projects.edit=Muokkaa projektia
-projects.modify=Pรคivitรค projekti
-projects.type.basic_kanban=Yksinkertainen Kanban
-projects.template.desc=Malli
+projects.modify=Muokkaa projektia
+projects.type.basic_kanban=Yksinkertainen kanban
+projects.template.desc=Mallipohja
projects.type.uncategorized=Luokittelematon
projects.column.edit_title=Nimi
projects.column.new_title=Nimi
@@ -844,7 +1159,7 @@ issues.filter_assignees=Suodata kรคyttรคjiรค
issues.filter_milestones=Suodata merkkipaalu
issues.new=Uusi ongelma
issues.new.labels=Tunnisteet
-issues.new.no_label=Ei tunnistetta
+issues.new.no_label=Ei tunnisteita
issues.new.clear_labels=Tyhjennรค tunnisteet
issues.new.projects=Projektit
issues.new.no_items=Ei kohteita
@@ -859,12 +1174,12 @@ issues.new.no_assignees=Ei kรคsittelijรครค
issues.choose.open_external_link=Avaa
issues.choose.blank=Oletus
issues.no_ref=Haaraa/tagia ei mรครคritelty
-issues.create=Ilmoita ongelma
+issues.create=Luo ongelma
issues.new_label=Uusi tunniste
issues.new_label_placeholder=Tunnisteen nimi
issues.new_label_desc_placeholder=Kuvaus
issues.create_label=Luo tunniste
-issues.label_templates.helper=Valitse tunnistejoukko
+issues.label_templates.helper=Valitse tunnisteen esiasetus
issues.add_milestone_at=`lisรคsi tรคmรคn merkkipaaluun %s %s`
issues.change_milestone_at=`vaihtoi merkkipaalun %s merkkipaaluun %s %s`
issues.remove_milestone_at=`poisti tรคmรคn %s merkkipaalusta %s`
@@ -886,7 +1201,7 @@ issues.filter_type.all_issues=Kaikki ongelmat
issues.filter_type.assigned_to_you=Osoitettu sinulle
issues.filter_type.created_by_you=Ilmoittamasi
issues.filter_type.mentioning_you=Jotka mainitsee sinut
-issues.filter_type.review_requested=Arvostelua pyydetty
+issues.filter_type.review_requested=Katselmointi pyydetty
issues.filter_sort=Lajittele
issues.filter_sort.latest=Uusin
issues.filter_sort.oldest=Vanhin
@@ -917,7 +1232,7 @@ issues.commented_at=`kommentoi %s `
issues.delete_comment_confirm=Haluatko varmasti poistaa tรคmรคn kommentin?
issues.context.copy_link=Kopioi linkki
issues.context.quote_reply=Vastaa lainaamalla
-issues.context.reference_issue=Viittaa uudesa ongelmassa
+issues.context.reference_issue=Viittaa uudessa ongelmassa
issues.context.edit=Muokkaa
issues.context.delete=Poista
issues.close_comment_issue=Kommentoi ja sulje
@@ -940,7 +1255,7 @@ issues.label_count=%d tunnistetta
issues.label_open_issues=%d avointa ongelmaa
issues.label_edit=Muokkaa
issues.label_delete=Poista
-issues.label_modify=Muokkaa tunniste
+issues.label_modify=Muokkaa tunnistetta
issues.label_deletion=Poista tunniste
issues.label.filter_sort.alphabetically=Aakkosjรคrjestyksessรค
issues.label.filter_sort.reverse_alphabetically=Kรครคnteisessรค aakkosjรคrjestyksessรค
@@ -968,7 +1283,7 @@ issues.start_tracking_history=`aloitti tyรถskentelyn %s`
issues.tracker_auto_close=Ajan seuranta pysรคhtyy automaattisesti kun tรคmรค ongelma on suljettu
issues.stop_tracking=Pysรคytรค ajanotto
issues.stop_tracking_history=`lopetti tyรถskentelyn %s`
-issues.add_time=Lisรครค aika kรคsin
+issues.add_time=Lisรครค aika manuaalisesti
issues.add_time_short=Lisรครค aika
issues.add_time_cancel=Peruuta
issues.add_time_history=`lisรคsi kรคytetyn ajan %s`
@@ -982,7 +1297,7 @@ issues.push_commits_n=lisรคsi %d committia %s
issues.due_date_form=vvvv-kk-pp
issues.due_date_form_edit=Muokkaa
issues.due_date_form_remove=Poista
-issues.due_date_not_set=Mรครคrรคpรคivรครค ei asetettu.
+issues.due_date_not_set=Mรครคrรคpรคivรครค ei ole asetettu.
issues.due_date_overdue=Myรถhรคssรค
issues.dependency.title=Riippuvuudet
issues.dependency.issue_no_dependencies=Riippuvuuksia ei asetettu.
@@ -1005,7 +1320,7 @@ issues.content_history.created=luotu
pulls.new=Uusi vetopyyntรถ
-pulls.compare_changes=Uusi vetopyyntรถ
+pulls.compare_changes=Uusi pull-pyyntรถ
pulls.has_viewed_file=Katsottu
pulls.viewed_files_label=%[1]d / %[2]d tiedostoa katsottu
pulls.compare_compare=vedรค kohteesta
@@ -1014,8 +1329,8 @@ pulls.no_results=Tuloksia ei lรถytynyt.
pulls.nothing_to_compare=Nรคmรค haarat vastaavat toisiaan. Ei ole tarvetta luoda vetopyyntรถรค.
pulls.nothing_to_compare_and_allow_empty_pr=Nรคmรค haarat vastaavat toisiaan. Vetopyyntรถ tulee olemaan tyhjรค.
pulls.has_pull_request=`Vetopyyntรถ haarojen vรคlillรค on jo olemassa: %[2]s#%[3]d `
-pulls.create=Luo Pull-pyyntรถ
-pulls.title_desc_few=haluaa yhdistรครค %[1]d committia lรคhteestรค %[2]s
kohteeseen %[3]s
+pulls.create=Luo vetopyyntรถ
+pulls.title_desc_few=haluaa yhdistรครค %[1]d committia lรคhteestรค %[2]s
kohteeseen %[3]s
pulls.merged_title_desc_few=yhdistetty %[1]d committia lรคhteestรค %[2]s
kohteeseen %[3]s
%[4]s
pulls.tab_conversation=Keskustelu
pulls.tab_commits=Commitit
@@ -1079,20 +1394,20 @@ activity.period.quarterly=3 kuukautta
activity.period.semiyearly=6 kuukautta
activity.period.yearly=1 vuosi
activity.overview=Yleiskatsaus
-activity.active_prs_count_1=%d Aktiivinen vetopyyntรถ
-activity.active_prs_count_n=%d Aktiivista vetopyyntรถรค
+activity.active_prs_count_1=%d aktiivinen vetopyyntรถ
+activity.active_prs_count_n=%d aktiivista vetopyyntรถรค
activity.merged_prs_label=Yhdistetty
-activity.active_issues_count_1=%d Aktiivinen ongelma
-activity.active_issues_count_n=%d Aktiivista ongelmaa
-activity.closed_issues_count_1=Suljettu ongelma
-activity.closed_issues_count_n=Suljettua ongelmaa
+activity.active_issues_count_1=%d aktiivinen ongelma
+activity.active_issues_count_n=%d aktiivista ongelmaa
+activity.closed_issues_count_1=suljettu ongelma
+activity.closed_issues_count_n=suljettua ongelmaa
activity.title.issues_created_by=%s luonnut %s
activity.closed_issue_label=Suljettu
activity.new_issues_count_1=Uusi ongelma
-activity.new_issues_count_n=Uutta ongelmaa
+activity.new_issues_count_n=uutta ongelmaa
activity.new_issue_label=Avoinna
activity.unresolved_conv_label=Auki
-activity.published_release_label=Julkaistu
+activity.published_release_label=Julkaisu
activity.git_stats_pushed_1=on tyรถntรคnyt
activity.git_stats_file_1=%d tiedosto
activity.git_stats_file_n=%d tiedostoa
@@ -1102,7 +1417,7 @@ activity.git_stats_and_deletions=ja
activity.git_stats_deletion_1=%d poisto
activity.git_stats_deletion_n=%d poistoa
-contributors.contribution_type.commits=Commitit
+contributors.contribution_type.commits=Kommitit
search=Haku
search.match=Osuma
@@ -1116,30 +1431,30 @@ settings.collaboration.read=Lue
settings.collaboration.owner=Omistaja
settings.collaboration.undefined=Mรครคrittelemรคtรถn
settings.hooks=Webkoukut
-settings.githooks=Git koukut
+settings.githooks=Git-koukut
settings.basic_settings=Perusasetukset
settings.mirror_settings=Peilauksen asetukset
settings.site=Nettisivu
-settings.update_settings=Pรคivitรค asetukset
+settings.update_settings=Tallenna asetukset
settings.advanced_settings=Lisรคasetukset
settings.use_internal_wiki=Kรคytรค sisรครคnrakennettua wikiรค
settings.use_external_wiki=Kรคytรค ulkoista wikiรค
-settings.external_wiki_url=Ulkoinen Wiki URL
+settings.external_wiki_url=Ulkoisen wikin URL-osoite
settings.external_wiki_url_desc=Wiki-vรคlilehden klikkaus ohjaa vierailijat ulkoisen wiki-URL-osoitteeseen.
settings.tracker_url_format=Ulkoisen vikaseurannan URL muoto
settings.tracker_issue_style.numeric=Numeerinen
settings.tracker_issue_style.alphanumeric=Aakkosnumeerinen
-settings.enable_timetracker=Ota kรคyttรถรถn ajan seuranta
+settings.enable_timetracker=Kรคytรค ajan seurantaa
settings.danger_zone=Vaaravyรถhyke
settings.new_owner_has_same_repo=Uudella omistajalla on jo samanniminen repo. Ole hyvรค ja valitse toinen nimi.
settings.transfer.title=Siirrรค omistajuus
settings.transfer_form_title=Syรถtรค repon nimi vahvistuksena:
settings.transfer_notices_3=- Jos arkisto on yksityinen ja se siirretรครคn yksittรคiselle kรคyttรคjรคlle, tรคmรค toiminto varmistaa, ettรค kรคyttรคjรคllรค on ainakin lukuoikeudet (ja muuttaa kรคyttรถoikeuksia tarvittaessa).
settings.transfer_owner=Uusi omistaja
-settings.wiki_delete=Poista Wiki data
+settings.wiki_delete=Poista wikidata
settings.wiki_delete_desc=Repon wikin data poistaminen on pysyvรค eikรค voi peruuttaa.
-settings.confirm_wiki_delete=Wiki datan poistaminen
+settings.confirm_wiki_delete=Poista wikidata
settings.wiki_deletion_success=Repon wiki data on poistettu.
settings.delete=Poista tรคmรค repo
settings.delete_desc=Repon poistaminen on pysyvรค eikรค voi peruuttaa.
@@ -1160,7 +1475,7 @@ settings.webhook.body=Sisรคltรถ
settings.githook_edit_desc=Jos koukku ei ole kรคytรถssรค, esitellรครคn esimerkkisisรคltรถ. Sisรคllรถn jรคttรคminen tyhjรคksi arvoksi poistaa tรคmรคn koukun kรคytรถstรค.
settings.githook_name=Koukun nimi
settings.githook_content=Koukun sisรคltรถ
-settings.update_githook=Pรคivitys koukku
+settings.update_githook=Pรคivitรค koukku
settings.payload_url=Kohde URL
settings.http_method=HTTP-menetelmรค
settings.secret=Salaus
@@ -1182,22 +1497,22 @@ settings.event_push_desc=Git push repoon.
settings.event_repository=Repo
settings.event_repository_desc=Repo luotu tai poistettu.
settings.event_header_issue=Ongelmien tapahtumat
-settings.event_issues=Ongelmat
+settings.event_issues=Muokkaus
settings.event_issues_desc=Ongelma avattu, suljettu, avattu uudelleen tai muokattu.
settings.event_issue_assign=Ongelma mรครคritetty
settings.event_issue_assign_desc=Ongelma osoitettu tai osoitus poistettu.
settings.event_issue_label_desc=Ongelman tunnisteet pรคivitetty tai tyhjennetty.
-settings.event_issue_milestone_desc=Ongelma merkkipaaluteettu tai merkkipaalu-osoitus poistettu.
+settings.event_issue_milestone_desc=Merkkipaalu lisรคtty, poistettu tai muokattu.
settings.event_issue_comment_desc=Ongelman kommentti luotu, muokattu tai poistettu.
settings.event_header_pull_request=Vetopyyntรถjen tapahtumat
-settings.event_pull_request=Vetopyyntรถ
+settings.event_pull_request=Muokkaus
settings.event_package_desc=Paketti on luotu tai poistettu repossa.
settings.active_helper=Tiedot kรคynnistetyistรค tapahtumista lรคhetetรครคn tรคhรคn webkoukun URL-osoitteeseen.
settings.add_hook_success=Uusi webkoukku on lisรคtty.
settings.update_webhook=Pรคivitรค webkoukku
settings.delete_webhook=Poista webkoukku
settings.recent_deliveries=Viimeisimmรคt toimitukset
-settings.hook_type=Koukkutyyppi
+settings.hook_type=Koukun tyyppi
settings.slack_token=Pรครคsymerkki
settings.slack_domain=Verkkotunnus
settings.slack_channel=Kanava
@@ -1227,15 +1542,15 @@ settings.deploy_key_deletion_desc=Julkaisuavaimen poistaminen kumoaa sen pรครคsy
settings.deploy_key_deletion_success=Julkaisuavain on poistettu.
settings.branches=Haarat
settings.protected_branch=Haaran suojaus
-settings.branch_protection=Haaran '%s ' suojaus
+settings.branch_protection=Haaran "%s " suojaussรครคnnรถt
settings.protect_this_branch=Ota haaran suojaus kรคyttรถรถn
settings.protect_whitelist_deploy_keys=Lisรครค julkaisuavaimet sallittujen listalle mahdollistaaksesi repohin kirjoituksen.
-settings.protect_whitelist_users=Lista kรคyttรคjistรค joilla tyรถntรถ oikeus:
+settings.protect_whitelist_users=Sallitut kรคyttรคjรคt suhteessa tyรถntรคmiseen
settings.protect_whitelist_search_users=Etsi kรคyttรคjiรคโฆ
settings.protect_merge_whitelist_committers_desc=Salli vain listaan merkittyjen kรคyttรคjien ja tiimien yhdistรครค vetopyynnรถt tรคhรคn haaraan.
-settings.protect_merge_whitelist_users=Lista kรคyttรคjistรค joilla yhdistรคmis-oikeus:
-settings.protect_required_approvals=Vaadittavat hyvรคksynnรคt:
-settings.protect_approvals_whitelist_users=Sallittujen tarkastajien lista:
+settings.protect_merge_whitelist_users=Sallitut kรคyttรคjรคt suhteessa yhdistรคmiseen
+settings.protect_required_approvals=Vaadittavat hyvรคksynnรคt
+settings.protect_approvals_whitelist_users=Sallittujen tarkastajien lista
settings.choose_branch=Valitse haaraโฆ
settings.no_protected_branch=Suojattuja haaroja ei ole.
settings.edit_protected_branch=Muokkaa
@@ -1247,7 +1562,7 @@ settings.tags.protection.allowed=Sallitut
settings.tags.protection.allowed.users=Sallitut kรคyttรคjรคt
settings.tags.protection.allowed.teams=Sallitut tiimit
settings.tags.protection.allowed.noone=Ei kukaan
-settings.tags.protection.create=Suojaa tagi
+settings.tags.protection.create=Lisรครค sรครคntรถ
settings.tags.protection.none=Suojattuja tageja ei ole.
settings.bot_token=Botti pรครคsymerkki
settings.matrix.homeserver_url=Kotipalvelimen URL
@@ -1258,7 +1573,7 @@ settings.lfs=LFS
settings.lfs_filelist=LFS-tiedostot tallennettu tรคhรคn repoon
settings.lfs_no_lfs_files=LFS-tiedostoja ei ole tallennettu tรคhรคn repoon.
settings.lfs_findcommits=Etsi commitit
-settings.lfs_lfs_file_no_commits=LFS-tiedostolle ei lรถytynyt committeja
+settings.lfs_lfs_file_no_commits=LFS-tiedostolle ei lรถytynyt kommitteja
settings.lfs_noattribute=Tรคllรค polulla ei ole lukittavaa attribuuttia oletushaarassa
settings.lfs_delete=Poista LFS-tiedosto OID:lla %s
settings.lfs_delete_warning=LFS-tiedoston poistaminen voi aiheuttaa 'object does not exists'-virheitรค checkouttattaessa. Oletko varma?
@@ -1267,7 +1582,7 @@ settings.lfs_locks=Lukot
settings.lfs_invalid_locking_path=Virheellinen polku: %s
settings.lfs_invalid_lock_directory=Hakemistoa ei voida lukita: %s
settings.lfs_lock_already_exists=Lukitus on jo olemassa: %s
-settings.lfs_lock_path=Lukittavan tiedostopolku...
+settings.lfs_lock_path=Lukittavan tiedostopolkuโฆ
settings.lfs_locks_no_locks=Ei lukkoja
settings.lfs_lock_file_no_exist=Lukittua tiedostoa ei ole olemassa oletushaarassa
settings.lfs_force_unlock=Pakota lukituksen avaus
@@ -1296,13 +1611,13 @@ diff.view_file=Nรคytรค tiedosto
diff.file_image_width=Leveys
diff.file_image_height=Korkeus
diff.file_byte_size=Koko
-diff.comment.markdown_info=Muotoilu markdownilla tuettu.
+diff.comment.markdown_info=Muotoilu Markdownilla on tuettu.
diff.comment.add_single_comment=Lisรครค yksittรคinen kommentti
diff.comment.add_review_comment=Lisรครค kommentti
diff.comment.start_review=Aloita tarkistus
diff.comment.reply=Vastaa
-diff.review.header=Lรคhetรค arvio
-diff.review.placeholder=Tarkistuksen kommentti
+diff.review.header=Lรคhetรค katselmointi
+diff.review.placeholder=Katselmoinnin kommentti
diff.review.comment=Kommentoi
diff.review.approve=Hyvรคksy
diff.review.reject=Pyydรค muutoksia
@@ -1311,16 +1626,16 @@ release.releases=Julkaisut
release.tags=Tagit
release.new_release=Uusi julkaisu
release.draft=Tyรถversio
-release.prerelease=Esiversio
+release.prerelease=Esijulkaisu
release.stable=Vakaa
-release.edit=muokkaa
+release.edit=Muokkaa
release.source_code=Lรคhdekoodi
release.new_subheader=Julkaisut organisoivat projektien versioita.
release.edit_subheader=Julkaisut organisoivat projektien versioita.
release.tag_name=Taginimi
release.target=Kohde
release.tag_helper=Valitse olemassa oleva tagi tai luo uusi tagi.
-release.prerelease_desc=Merkitse ensijulkaisuksi
+release.prerelease_desc=Merkitse esijulkaisuksi
release.prerelease_helper=Merkitse tรคmรค julkaisu epรคsopivaksi tuotantokรคyttรถรถn.
release.cancel=Peruuta
release.publish=Julkaise versio
@@ -1336,26 +1651,566 @@ release.downloads=Lataukset
branch.name=Haaran nimi
branch.delete_head=Poista
-branch.create_branch=Luo haara %s
+branch.create_branch=Luo haara %s
topic.manage_topics=Hallitse aiheita
topic.done=Valmis
+already_forked = Olet jo forkannut %s
+fork_to_different_account = Forkkaa toiselle tilille
+release.compare = Vertaa
+release.ahead.commits = %d kommittia
+all_branches = Kaikki haarat
+n_tag_few = %s tagia
+settings.event_fork_desc = Repo forkattu.
+actions = Actions
+fork_guest_user = Kirjaudu sisรครคn forkataksesi tรคmรคn repon.
+fork_from_self = Et voi forkata omistamaasi repoa.
+visibility_fork_helper = (Tรคmรคn muuttaminen vaikuttaa kaikkien forkkien nรคkyvyyteen.)
+fork = Forkkaa
+activity.git_stats_commit_n = %d kommittia
+commits.search_branch = Tรคmรค haara
+n_branch_few = %s haaraa
+pulls.show_all_commits = Nรคytรค kaikki kommitit
+commit_graph.select = Valitse haarat
+activity.navbar.recent_commits = Viimeisimmรคt kommitit
+settings.branches.add_new_rule = Lisรครค uusi sรครคntรถ
+n_commit_few = %s kommittia
+issues.force_push_compare = Vertaa
+commits.desc = Selaa lรคhdekoodin muutoshistoriaa.
+clone_helper = Tarvitseko apua kloonauksen kanssa? Siirry tukisivulle .
+settings.mirror_settings.push_mirror.copy_public_key = Kopioi julkinen avain
+object_format = Objektimuoto
+editor.fail_to_update_file_summary = Virheviesti:
+n_branch_one = %s haara
+issues.content_history.delete_from_history_confirm = Poistetaanko historiasta?
+editor.new_patch = Uusi paikkaus
+pulls.merged_success = Vetopyyntรถ yhdistetty onnistuneesti ja suljettu
+pulls.manually_merged = Manuaalisesti yhdistetty
+pulls.merged_info_text = Haaran %s voi nyt poistaa.
+pulls.status_checks_requested = Vaadittu
+signing.wont_sign.not_signed_in = Et ole kirjautunut sisรครคn.
+tag.create_tag = Luo tagi %s
+release.tag_already_exist = Tรคmรค tagin nimi on jo olemassa.
+activity.git_stats_additions = ja
+release = Julkaisu
+issues.num_comments_1 = %d kommentti
+activity.title.issues_n = %d ongelmaa
+release.detail = Julkaisun tiedot
+diff.hide_file_tree = Piilota tiedostopuu
+issues.role.owner_helper = Tรคmรค kรคyttรคjรค on tรคmรคn repositorion omistaja.
+issues.all_title = Kaikki
+issues.label_archived_filter = Nรคytรค arkistoidut tunnisteet
+pulls.close = Sulje vetopyyntรถ
+branch.already_exists = Haara nimellรค "%s" on jo olemassa.
+diff.show_file_tree = Nรคytรค tiedostopuu
+branch.deletion_failed = Haaran "%s" poistaminen epรคonnistui.
+branch.deletion_success = Haara "%s" on poistettu.
+branch.delete_html = Poista haara
+branch.restore_success = Haara "%s" on palautettu.
+branch.restore_failed = Haaran "%s" palauttaminen epรคonnistui.
+mirror_public_key = Julkinen SSH-avain
+mirror_use_ssh.text = Kรคytรค SSH-todennusta
+diff.show_more = Nรคytรค enemmรคn
+release.deletion_success = Tรคmรค julkaisu on poistettu.
+issues.filter_milestone_closed = Suljetut merkkipaalut
+file_copy_permalink = Kopioi pysyvรคislinkki
+empty_message = Tรคssรค repossa ei ole sisรคltรถรค.
+activity.git_stats_files_changed_n = on muutettu
+settings.event_pull_request_milestone_desc = Merkkipaalu lisรคtty, poistettu tai muokattu.
+settings.event_pull_request_comment = Kommentit
+settings.event_issue_comment = Kommentit
+diff.download_patch = Lataa patch-tiedosto
+issues.filter_milestone_none = Ei merkkipaaluja
+issues.filter_milestone_open = Avoimet merkkipaalut
+new_repo_helper = Tietovarasto sisรคltรครค kaikki projektitiedostot, mukaan lukien tarkistushistoria. Jรคrjestรคtkรถ jo sellaisen muualla? Siirrรค tietovarasto .
+use_template = Kรคytรค tรคtรค mallipohjaa
+star_guest_user = Kirjaudu sisรครคn lisรคtรคksesi tรคhden tรคhรคn repoon.
+watch_guest_user = Kirjaudu sisรครคn tarkkaillaksesi tรคtรค repoa.
+activity.git_stats_author_n = %d tekijรครค
+issues.dependency.add_error_dep_exists = Riippuvuus on jo olemassa.
+wiki.page_content = Sivun sisรคltรถ
+wiki.page_title = Sivun otsikko
+activity.navbar.contributors = Avustajat
+n_release_few = %s julkaisua
+n_release_one = %s julkaisu
+symbolic_link = Symbolinen linkki
+mirror_last_synced = Viimeksi synkronoitu
+find_file.go_to_file = Lรถydรค tiedosto
+find_tag = Etsi tagi
+settings.protected_branch.save_rule = Tallenna sรครคntรถ
+pulls.merge_manually = Manuaalisesti yhdistetty
+diff.stats_desc_file = %d muutosta: %d lisรคystรค ja %d poistoa
+branch.included_desc = Tรคmรค haara on osa oletushaaraa
+branch.confirm_create_branch = Luo haara
+projects.column.edit = Muokkaa saraketta
+editor.add_file = Lisรครค tiedosto
+milestones.deletion_success = Merkkipaalu on poistettu.
+project = Projektit
+pulls.delete.title = Poistetaanko tรคmรค vetopyyntรถ?
+activity.title.issues_1 = %d ongelma
+contributors.contribution_type.filter_label = Avustuksen tyyppi:
+settings.protected_branch.delete_rule = Poista sรครคntรถ
+settings.archive.success = Repo arkistoitiin onnistuneesti.
+diff.comment.placeholder = Jรคtรค kommentti
+release.message = Kuvaile tรคtรค julkaisua
+branch.delete_desc = Haaran poistaminen on pysyvรค toimenpide. Vaikka poistettu haara voi jรครคdรค olemaan lyhyeksi ajaksi, ennen kuin todellisesti poistetaan, poistoa EI VOI perua useimmiten. Jatketaanko?
+branch.protected_deletion_failed = Haara "%s" on suojattu. Sitรค ei voi poistaa.
+open_with_editor = Avaa sovelluksella %s
+download_bundle = Lataa BUNDLE
+pulls.num_conflicting_files_1 = %d ristiriitainen tiedosto
+editor.update = Pรคivitรค %s
+editor.add = Lisรครค %s
+activity.published_prerelease_label = Esijulkaisu
+activity.published_tag_label = Tagi
+diff.download_diff = Lataa diff-tiedosto
+settings.event_package = Paketti
+issues.new.closed_projects = Suljetut projektit
+settings.event_issue_milestone = Merkkipaalut
+branch.branch_already_exists = Haara "%s" on jo olemassa repossa.
+projects.card_type.images_and_text = Kuvat ja teksti
+default_branch_helper = Oletusarvoinen haara on oletushaara vetopyynnรถille ja koodikommiteille.
+author_search_tooltip = Nรคyttรครค enintรครคn 30 kรคyttรคjรครค
+migrate_options_mirror_helper = Tรคstรค reposta tulee peili
+commit_graph.color = Vรคri
+commit_graph.hide_pr_refs = Piilota vetopyynnรถt
+executable_file = Suoritettava tiedosto
+editor.file_already_exists = Tiedosto nimeltรค "%s" on jo olemassa tรคssรค repossa.
+branch.restore = Palauta haara "%s"
+branch.default_deletion_failed = Haara "%s" on oletushaara. Sitรค ei voi poistaa.
+branch.new_branch = Luo uusi haara
+tag.create_success = Tagi "%s" luotu.
+issues.sign_in_require_desc = Kirjaudu sisรครคn liittyรคksesi keskusteluun.
+wiki.cancel = Peruuta
+issues.dependency.remove_header = Poista riippuvuus
+issues.dependency.issue_remove_text = Riippuvuus poistetaan tรคstรค ongelmasta. Jatketaanko?
+issues.dependency.pr_remove_text = Riippuvuus poistetaan tรคstรค vetopyynnรถstรค. Jatketaanko?
+release.download_count_few = %s latausta
+diff.data_not_available = Diff-sisรคltรถ ei ole saatavilla
+diff.image.side_by_side = Rinnakkain
+release.ahead.target = projektiin %s tรคmรคn julkaisun jรคlkeen
+issues.close = Sulje ongelma
+issues.no_content = Ei kuvausta.
+pulls.reject_count_1 = %d muutospyyntรถ
+pulls.update_branch_success = Haarapรคivitys onnistui
+milestones.completeness = %d% % valmiina
+contributors.contribution_type.additions = Lisรคykset
+contributors.contribution_type.deletions = Poistot
+settings.webhook_deletion_success = Webkoukku on poistettu.
+settings.event_pull_request_milestone = Merkkipaalut
+find_file.no_matching = Vastaavaa tiedostoa ei lรถytynyt
+editor.file_delete_success = Tiedosto "%s" on poistettu.
+settings.transfer.button = Siirrรค omistajuus
+settings.slack_color = Vรคri
+release.tag_name_already_exist = Julkaisu tรคllรค taginimellรค on jo olemassa.
+pulls.allow_edits_from_maintainers_err = Pรคivittรคminen epรคonnistui
+stars = Tรคhdet
+editor.branch_already_exists = Haara "%s" on jo olemassa tรคssรค repossa.
+projects.column.delete = Poista sarake
+projects.column.color = Vรคri
+settings.admin_settings = Yllรคpitรคjรคn asetukset
+file_too_large = Tiedosto on liian suuri nรคytettรคvรคksi.
+readme_helper = Valitse README-tiedoston mallipohja
+settings.default_merge_style_desc = Oletusarvoinen yhdistรคmistyyli
+wiki.back_to_wiki = Takaisin wikisivulle
+wiki.delete_page_notice_1 = Wikisivun "%s" poistamista ei voi perua. Jatketaanko?
+activity.merged_prs_count_1 = yhdistetty vetopyyntรถ
+activity.merged_prs_count_n = yhdistettyรค vetopyyntรถรค
+activity.opened_prs_count_1 = ehdotettu vetopyyntรถ
+activity.opened_prs_count_n = ehdotettua vetopyyntรถรค
+activity.title.user_1 = %d kรคyttรคjรค
+activity.title.prs_n = %d vetopyyntรถรค
+settings.sourcehut_builds.secrets = Salaisuudet
+commit_graph = Kommittikaavio
+visibility_helper = Tee reposta yksityinen
+pulls.approve_count_1 = %d hyvรคksyntรค
+settings.confirm_delete = Poista repositorio
+milestones.new_subheader = Merkkipaalut auttavat hallinnoimaan ongelmia ja seuraamaan niiden korjausten edistymistรค.
+activity.title.user_n = %d kรคyttรคjรครค
+activity.title.prs_1 = %d vetopyyntรถ
+activity.navbar.code_frequency = Koodifrekvenssi
+activity.navbar.pulse = Pulssi
+wiki.no_search_results = Ei tuloksia
+settings.federation_settings = Federaation asetukset
+pull.deleted_branch = (poistettu):%s
+settings.transfer.rejected = Repositorion siirto hylรคttiin.
+settings.transfer.modal.title = Siirrรค omistajuus
+settings.event_pull_request_sync = Synkronoitu
+editor.commit_empty_file_text = Tiedosto, jonka olet aikeissa kommitoida, on tyhjรค. Jatketaanko?
+diff.load = Lataa diff
+branch.create_branch_operation = Luo haara
+activity.title.releases_n = %d julkaisua
+projects.column.new = Uusi sarake
+projects.column.new_submit = Luo sarake
+issues.new.open_projects = Avoimet projektit
+issues.filter_project_all = Kaikki projektit
+milestones.update_ago = Pรคivitetty %s
+pulls.update_not_allowed = Sinulla ei ole oikeutta pรคivittรครค haaraa
+pulls.is_closed = Vetopyyntรถ on suljettu.
+pulls.cannot_merge_work_in_progress = Vetopyyntรถ on merkitty keskenerรคiseksi.
+pulls.still_in_progress = Vielรค keskenerรคinen?
+pulls.expand_files = Laajenna kaikki tiedostot
+issues.content_history.delete_from_history = Poista historiasta
+milestones.filter_sort.name = Nimi
+issues.filter_milestone_all = Kaikki merkkipaalut
+issues.filter_label_select_no_label = Ei tunnistetta
+projects.column.set_default = Aseta oletukseksi
+projects.edit_success = Projekti "%s" on pรคivitetty.
+desc.sha256 = SHA256
+n_commit_one = %s kommitti
+transfer.accept = Hyvรคksy siirto
+transfer.reject = Hylkรครค siirto
+default_branch_label = oletus
+repo_desc_helper = Kirjoita lyhyt kuvaus (valinnainen)
+create_new_repo_command = Uuden repon luominen komentoriviltรค
+subscribe.issue.guest.tooltip = Kirjaudu sisรครคn tilataksesi tรคmรคn ongelman pรคivitykset.
+subscribe.pull.guest.tooltip = Kirjaudu sisรครคn tilataksesi tรคmรคn vetopyynnรถn pรคivitykset.
+migrate.migrating_failed_no_addr = Migraatio epรคonnistui.
+need_auth = Valtuutus
+migrate_options = Migraatioasetukset
+projects.create_success = Projekti "%s" on luotu.
+projects.description = Kuvaus (valinnainen)
+editor.commit_empty_file_header = Kommitoi tyhjรค tiedosto
+editor.branch_does_not_exist = Haaraa "%s" ei ole olemassa repossa.
+editor.delete = Poista %s
+editor.patching = Paikkaus:
+editor.patch = Toteuta paikkaus
+issues.filter_poster_no_select = Kaikki tekijรคt
+issues.filter_project_none = Ei projektia
+issues.new.no_projects = Ei projektia
+projects.card_type.text_only = Vain teksti
+issues.comment_on_locked = Et voi kommentoida lukittua ongelmaa.
+pulls.collapse_files = Supista kaikki tiedostot
+pulls.view = Nรคytรค vetopyynnรถt
+issues.dependency.add_error_dep_not_exist = Riippuvuutta ei ole olemassa.
+pulls.reject_count_n = %d muutospyyntรถรค
+pulls.waiting_count_1 = %d odottava katselmointi
+pulls.waiting_count_n = %d odottavaa katselmointia
+pulls.approve_count_n = %d hyvรคksyntรครค
+pulls.num_conflicting_files_n = %d ristiriitaista tiedostoa
+pulls.closed = Vetopyyntรถ suljettu
+milestones.create_success = Merkkipaalu "%s" on luotu.
+milestones.edit_success = Merkkipaalu "%s" on pรคivitetty.
+milestones.filter_sort.least_complete = Vรคhiten valmis
+milestones.filter_sort.most_complete = Eniten valmis
+activity.title.releases_1 = %d julkaisu
+settings.branches.update_default_branch = Pรคivitรค oletushaara
+settings.transfer.success = Repositorion siirto onnistui.
+settings.transfer_abort = Peru siirto
+settings.sync_mirror = Synkronoi nyt
+settings.mirror_settings.docs.doc_link_title = Miten peilaan repoja?
+tag.create_tag_operation = Luo tagi
+branch.rename = Nimeรค haara "%s" uudelleen
+branch.download = Lataa haara "%s"
+branch.deleted_by = Poistanut %s
+branch.create_success = Haara "%s" on luotu.
+branch.delete = Poista haara "%s"
+release.add_tag = Luo tagi
+diff.show_diff_stats = Nรคytรค tilastot
+settings.rename_branch = Nimeรค haara uudelleen
+settings.rename_branch_success = Haaran %s uudeksi nimeksi asetettiin %s.
+settings.rename_branch_failed_not_exist = Haaraa %s ei voi nimetรค uudelleen, koska sitรค ei ole olemassa.
+readme_helper_desc = Tรคhรคn voit kirjoittaa projektisi koko kuvauksen.
+milestones.deletion = Poista merkkipaalu
+more_operations = Lisรครค toimintoja
+settings.branches.switch_default_branch = Vaihda oletushaara
+tag.confirm_create_tag = Luo tagi
+n_tag_one = %s tagi
+branch.renamed = Haaran %s uudeksi nimeksi asetettiin %s.
+release.tag_name_protected = Tagin nimi on suojattu.
+pulls.merge_conflict_summary = Virheviesti
+issues.delete.title = Poistetaanko tรคmรค ongelma?
+migrate.github.description = Tee migraatio github.comista tai GitHub Enterprise -palvelimelta.
+settings.merge_style_desc = Yhdistรคmistyylit
+settings.protected_branch_deletion = Poista haaran suojaus
+settings.deletion_success = Repositorio on poistettu.
+editor.filename_is_invalid = Tiedoston nimi on virheellinen: "%s".
+push_exist_repo = Olemassa olevan repon tyรถntรคminen komentoriviltรค
+issues.new.title_empty = Otsikko ei voi olla tyhjรค
+settings.transfer_perform = Suorita siirto
+activity.git_stats_pushed_n = on tyรถntรคnyt
+settings.mirror_settings.last_update = Viimeisin pรคivitys
+settings.new_owner_blocked_doer = Uusi omistaja on estรคnyt sinut.
+issues.lock_duplicate = Ongelmaa ei voi lukita kahdesti.
+ext_wiki = Ulkoinen wiki
+wiki.file_revision = Sivun versio
+stored_lfs = Talletettu Git LFS:llรค
+activity.git_stats_author_1 = %d tekijรค
+issues.choose.blank_about = Luo ongelma oletusarvoisesta mallipohjasta.
+pulls.made_using_agit = AGit
+editor.cannot_edit_lfs_files = LFS-tiedostoja ei voi muokata web-kรคyttรถliittymรคssรค.
+pulls.cmd_instruction_hint = Nรคytรค komentoriviohjeet
+settings.wiki_globally_editable = Salli kenen tahansa muokata wikiรค
+pulls.rebase_conflict_summary = Virheviesti
+wiki.search = Etsi wikistรค
+activity.commit = Kommittitoiminta
+editor.cannot_edit_non_text_files = Binรครคritiedostoja ei voi muokata web-kรคyttรถliittymรคssรค.
+projects.template.desc_helper = Valitse projektin mallipohja aloittaaksesi
+commit.contained_in_default_branch = Tรคmรค kommitti on osa oletushaaraa
+activity.git_stats_exclude_merges = Poissulkien yhdistรคmiset
+activity.no_git_activity = Tรคllรค ajanjaksolla ei ole ollut kommitointitoimintaa.
+activity.git_stats_commit_1 = %d kommitin
+activity.git_stats_push_to_all_branches = kaikkiin haaroihin.
+settings.graphql_url = GraphQL:n URL-osoite
+branch.create_new_branch = Luo haara haarasta:
+settings.archive.error_ismirror = Et voi arkistoida peilattua repoa.
+branch.warning_rename_default_branch = Olet nimeรคmรคssรค oletushaaran uudelleen.
+settings.web_hook_name_msteams = Microsoft Teams
+release.download_count_one = %s lataus
+settings.update_hook_success = Webkoukku on pรคivitetty.
+diff.file_before = Ennen
+diff.file_after = Jรคlkeen
+settings.protect_new_rule = Luo uusi haaran suojaussรครคntรถ
+settings.branch_filter = Haarasuodatin
+object_format_helper = Repositorion objektimuoto. Tรคtรค ei voi muuttaa myรถhemmin. SHA1 on yhteensopivin muoto.
+migrate.gogs.description = Tee migraatio notabug.orgista tai muista Gogs-instansseista.
+migrate.forgejo.description = Tee migraatio codeberg.orgista tai muista Forgejo-instansseista.
+migrate.gitbucket.description = Tee migraatio GitBucket-instansseista.
+migrate.onedev.description = Tee migraatio code.onedev.io:sta tai muista OneDev-instansseista.
+migrate.codebase.description = Tee migraatio codebasehq.comista.
+migrate.git.description = Tee repomigraatio mistรค tahansa Git-palvelusta.
+migrate.gitlab.description = Tee migraatio gitlab.comista tai muista GitLab-instansseista.
+migrate.gitea.description = Tee migraatio gitea.comista tai muista Gitea-instansseista.
+repo_gitignore_helper_desc = Valitse mitรค tiedostoja ei seurata yleisimpien kielten mallipohjista. Tyypilliset artefaktit, joita eri kielten koostamistyรถkalut tuottavat, lisรคtรครคn .gitignore-tiedostoon oletusarvoisesti.
+milestones.filter_sort.latest_due_date = Kaukaisin mรครคrรคpรคivรค
+license_helper_desc = Lisenssi mรครคrรครค, mitรค muut voivat ja eivรคt voi tehdรค koodillasi. Etkรถ ole varma, mikรค lisenssi soveltuu projektillesi? Lue ohje lisenssin valinnasta .
+milestones.filter_sort.earliest_due_data = Lรคhin mรครคrรคpรคivรค
+issues.filter_type.reviewed_by_you = Katselmoitu toimestasi
+settings.units.overview = Yleisnรคkymรค
+settings.remove_team_success = Tiimin pรครคsy repositorioon on poistettu.
+migrate.cancel_migrating_confirm = Haluatko perua tรคmรคn migraation?
+settings.units.units = Yksikรถt
+settings.update_settings_no_unit = Repositorion tulisi sallia edes jonkinlainen vuorovaikutus.
+settings.units.add_more = Ota lisรครค kรคyttรถรถn
+settings.add_team_success = Tiimillรค on nyt pรครคsy repositorioon.
+settings.use_external_issue_tracker = Kรคytรค ulkoista ongelmienseurantaa
+settings.transfer_started = Tรคmรค repositorio on merkitty siirrettรคvรคksi ja se odottaa vahvistusta kรคyttรคjรคltรค "%s"
+signing.wont_sign.pubkey = Kommittia ei allekirjoiteta, koska sinulla ei ole yhtรคkรครคn julkista avainta liitetty tiliisi.
+settings.transfer_succeed = Repositorio on siirretty.
+activity.git_stats_on_default_branch = Haarassa %s,
+settings.tracker_issue_style.regexp = Sรครคnnรถllinen lauseke
+wiki.reserved_page = Wikisivun nimi "%s" on varattu.
+pulls.recently_pushed_new_branches = Tyรถnsit haaraan %[1]s %[2]s
+signing.will_sign = Tรคmรค kommitti allekirjoitetaan avaimella "%s".
+signing.wont_sign.never = Kommitit eivรคt ole koskaan allekirjoitettuja.
+settings.mirror_settings.direction = Suunta
+settings.mirror_settings.push_mirror.remote_url = Git-etรคrepon URL-osoite
+settings.issues_desc = Kรคytรค repositorion ongelmienseurantaa
+settings.use_internal_issue_tracker = Kรคytรค sisรครคnrakennettua ongelmienseurantaa
+settings.external_tracker_url = Ulkoisen ongelmienseurannan URL-osoite
+settings.transfer_abort_success = Repositorion siirto kรคyttรคjรคlle %s peruttiin.
+settings.transfer_quota_exceeded = Uuden omistajan (%s) tilakiintiรถ on tรคynnรค. Repositoriota ei ole siirretty.
+settings.projects_desc = Kรคytรค repositorion projekteja
+settings.releases_desc = Kรคytรค repositorion julkaisuja
+settings.packages_desc = Kรคytรค repositorion pakettirekisteriรค
+activity.git_stats_push_to_branch = haaraan %s ja
+wiki.wiki_page_revisions = Sivun versiot
+settings.wiki_desc = Kรคytรค repositorion wikiรค
+signing.wont_sign.always = Kommitit ovat aina allekirjoitettuja.
+milestones.edit_subheader = Merkkipaalut jรคrjestรคvรคt ongelmia ja seuraavat edistymistรค.
+view_git_blame = Nรคytรค git blame
+editor.push_rejected = Tรคmรค muutos hylรคttiin palvelimen toimesta. Tarkista Git-koukut.
+editor.push_rejected_no_message = Tรคmรค muutos hylรคttiin palvelimen toimesta ilman viestiรค. Tarkista Git-koukut.
+editor.upload_file_is_locked = Tiedoston "%s" on lukinnut %s.
+editor.fail_to_update_file = Tiedoston "%s" pรคivittรคminen/luominen epรคonnistui.
+diff.protected = Suojattu
+releases.desc = Seuraa projektin versioita ja latauksia.
+settings.protect_patterns = Kaavat
+branch.new_branch_from = Luo uusi haara kohteesta "%s"
+settings.matrix.message_type = Viestin tyyppi
+diff.committed_by = kommitoinut
+invisible_runes_line = `Tรคllรค rivillรค on nรคkymรคttรถmiรค Unicode-merkkejรค`
+editor.fork_before_edit = Sinun tรคytyy forkata tรคmรค repo tehdรคksesi tai ehdottaaksesi muutoksia tรคhรคn tiedostoon.
+editor.file_deleting_no_longer_exists = Poistettava tiedosto, "%s", ei ole enรครค olemassa tรคssรค repossa.
+editor.add_tmpl.filename = tiedostonimi
+editor.fail_to_apply_patch = Ei voitu toteuttaa paikkaa "%s"
+editor.propose_file_change = Ehdota tiedostomuutosta
+editor.new_branch_name = Nimeรค uusi haara tรคtรค kommittia varten
+editor.new_branch_name_desc = Uuden haaran nimiโฆ
+editor.file_editing_no_longer_exists = Muokattava tiedosto, "%s", ei ole enรครค olemassa tรคssรค repossa.
+editor.cannot_commit_to_protected_branch = Suojattuun haaraan "%s" ei voi kommitoida.
+issues.remove_request_review = Poista katselmointipyyntรถ
+issues.remove_request_review_block = Katselmointipyyntรถรค ei voi poistaa
+pulls.require_signed_wont_sign = Tรคmรค haara vaatii allekirjoitetut kommitit, mutta tรคtรค yhdistรคmistรค ei allekirjoiteta
+pulls.push_rejected_summary = Koko hylkรคysviesti
+settings.unarchive.button = Poista repon arkistointi
+release.type_attachment = Liite
+tag.create_tag_from = Luo uusi tagi kohteesta"%s"
+topic.count_prompt = Voit valita korkeintaan 25 aihetta
+settings.require_signed_commits = Vaadi allekirjoitetut kommitit
+editor.push_rejected_summary = Koko hylkรคysviesti:
+release.title = Julkaisun nimi
+release.tag_helper_existing = Olemassa oleva tagi.
+file_view_source = Nรคytรค lรคhde
+diff.bin_not_shown = Binรครคritiedostoa ei nรคytetรค.
+release.system_generated = Tรคmรค liite on luotu automaattisesti.
+invisible_runes_header = `Tรคmรค tiedosto sisรคltรครค nรคkymรคttรถmiรค Unicode-merkkejรค`
+editor.must_have_write_access = Sinulla tรคytyy olla kirjoitusoikeus tehdรคksesi tai ehdottaaksesi muutoksia tรคhรคn tiedostoon.
+issues.re_request_review = Pyydรค katselmointia uudelleen
+pulls.status_checks_details = Yksityiskohdat
+release.title_empty = Nimi ei voi olla tyhjรค.
+archive.title = Tรคmรค repo on arkistoitu. Voit katsella sen sisรคltรคmiรค tiedostoja ja kloonata repon, mutta et voi pushata, avata ongelmia tai luoda vetopyyntรถjรค.
+reactions_more = ja %d lisรครค
+mirror_address = Kloonaa URL-osoitteesta
+migrate_items_merge_requests = Yhdistรคmispyynnรถt
+stars_remove_warning = Tรคmรค poistaa kaikki tรคhdet tรคstรค reposta.
+archive.issue.nocomment = Tรคmรค repo on arkistoitu. Et voi kommentoida ongelmia.
+archive.pull.nocomment = Tรคmรค repo on arkistoitu. Et voi kommentoida vetopyyntรถjรค.
+settings.webhook_deletion_desc = Webkoukun poistaminen poistaa sen asetukset ja toimitushistorian. Jatketaanko?
+settings.discord_icon_url.exceeds_max_length = Kuvakkeen URL-osoite voi sisรคltรครค enintรครคn 2048 merkkiรค
+settings.event_wiki_desc = Wiki-sivu luotu, nimetty uudelleen, muokattu tai poistettu.
+settings.event_pull_request_desc = Vetopyyntรถ avattu, suljettu, avattu uudelleen tai muokattu.
+settings.protect_branch_name_pattern = Suojatun haaran nimen kaava
+issues.dependency.add_error_dep_not_same_repo = Molempien ongelmien tulee olla samassa repossa.
+settings.event_release = Julkaisu
+pulls.merge_pull_request = Luo yhdistรคmiskommitti
+settings.pull_mirror_sync_quota_exceeded = Kiintiรถ ylitetty, ei vedetรค muutoksia.
+settings.wiki_rename_branch_main_notices_1 = Tรคtรค toimintoa EI VOI perua.
+settings.webhook.test_delivery_desc_disabled = Aktivoi webkoukku testataksesi sitรค tekaistulla tapahtumalla.
+settings.discord_icon_url = Kuvakkeen URL-osoite
+settings.archive.branchsettings_unavailable = Haaran asetukset eivรคt ole saatavilla arkistoiduissa repoissa.
+pulls.ready_for_review = Valmiina katselmointiin?
+issues.time_spent_total = Kรคytetty kokonaisaika
+settings.webhook.test_delivery_desc = Testaa tรคtรค webkoukkua tekaistulla tapahtumalla.
+pulls.switch_comparison_type = Vaihda vertailutyyppiรค
+settings.hooks_desc = Webkoukut tekevรคt automaattisesti HTTP POST -pyyntรถjรค palvelimelle, kun jotkin Forgejo-tapahtumat kรคynnistyvรคt. Lue lisรครค webkoukkujen oppaasta .
+issues.num_participants_one = %d osallistuja
+issues.reference_link = Viittaus: %s
+settings.transfer_desc = Siirrรค tรคmรค repo kรคyttรคjรคlle tai organisaatiolle, johon sinulla yllรคpito-oikeus.
+settings.add_collaborator = Lisรครค avustaja
+settings.mirror_settings.push_mirror.none = Push-peilejรค ei ole mรครคritetty
+settings.collaborator_deletion_desc = Avustajan poistaminen estรครค hรคnen pรครคsyn tรคhรคn repoon. Jatketaanko?
+settings.archive.text = Repon arkistointi asettaa sen pelkkรครคn lukutilaan. Se piilotetaan hallintapaneelista. Kukaan (et edes sinรค!) ei pysty tehdรค uusia kommitteja, avata uusia ongelmia tai avata vetopyyntรถjรค.
+settings.mirror_settings.docs = Mรครคritรค reposi automaattisesti synkronoimaan kommitit, tagit ja haarat toiseen repoon.
+settings.add_collaborator_duplicate = Avustaja on jo lisรคtty tรคhรคn repoon.
+settings.add_collaborator_blocked_them = Avustajaa ei voi lisรคtรค, koska kyseinen avustaja on estรคnyt repon omistajan.
+settings.add_collaborator_blocked_our = Avustajaa ei voi lisรคtรค, koska repon omistaja on estรคnyt hรคnet.
+settings.default_branch_desc = Valitse repon oletushaara, johon vetopyynnรถt ja koodikommitit kohdistetaan:
+issues.role.collaborator = Avustaja
+settings.trust_model.collaboratorcommitter.long = Avustaja+kommitoija: Luota avustajien allekirjoituksiin, jotka vastaavat kommitoijaa
+settings.collaborator_deletion = Poista avustaja
+wiki.desc = Kirjoita ja jaa dokumentaatiota avustajien kesken.
+settings.trust_model.collaborator = Avustaja
+mirror_sync_on_commit = Synkronoi kun kommitit pushataan
+settings.mirror_settings.docs.disabled_pull_mirror.instructions = Mรครคritรค projektisi automaattisesti pushaamaan kommitit, tagit ja haarat toiseen repoon. Pull-peilit on poistettu kรคytรถstรค tรคmรคn sivuston yllรคpitรคjรคn toimesta.
+settings.mirror_settings.docs.more_information_if_disabled = Lรถydรคt lisรคtietoja push- ja pull-peileistรค tรครคltรค:
+settings.mirror_settings.push_mirror.add = Lisรครค push-peili
+settings.mirror_settings.push_mirror.edit_sync_time = Muokkaa peilin synkronoinnin aikavรคliรค
+settings.trust_model.collaboratorcommitter = Avustaja+kommitoija
+settings.trust_model.default = Oletusarvoinen luottamusmalli
+settings.admin_enable_health_check = Kรคytรค repositorion terveystarkastuksia (git fsck)
+settings.remove_collaborator_success = Avustaja on poistettu.
+issues.role.collaborator_helper = Tรคmรค kรคyttรคjรค on kutsuttu avustajaksi tรคhรคn repoon.
+settings.pulls_desc = Kรคytรค repositorion vetopyyntรถjรค
+mirror_interval_invalid = Peilauksen aikavรคli ei ole kelvollinen.
+settings.collaboration = Avustajat
+settings.trust_model = Allekirjoituksen luottamusmalli
+settings.org_not_allowed_to_be_collaborator = Organisaatioita ei voi lisรคtรค avustajaksi.
+mirror_interval = Peilauksen aikavรคli (kelvolliset yksikรถt ovat "h", "m", "s"). 0 poistaa kรคytรถstรค aikaan pohjautuvan synkronoinnin. (Pienin aikavรคli: %s)
+settings.add_collaborator_success = Avustaja on lisรคtty.
+settings.add_collaborator_owner = Omistajaa ei voi lisรคtรค avustajaksi.
+settings.signing_settings = Allekirjoituksen vahvistuksen asetukset
+settings.mirror_settings.docs.disabled_push_mirror.instructions = Mรครคritรค projektisi automaattisesti vetรคmรครคn kommitit, tagit ja haarat toisesta reposta.
+settings.trust_model.collaborator.long = Avustaja: Luota avustajien allekirjoituksiin
+issues.dependency.setting = Kรคytรค riippuvuuksia ongelmiin ja vetopyyntรถihin
+settings.allow_only_contributors_to_track_time = Salli vain avustajien seurata aikaa
+settings.actions_desc = Kรคytรค integroituja CI-/CD-putkia Forgejo Actionsia hyรถdyntรคen
+settings.admin_enable_close_issues_via_commit_in_any_branch = Sulje ongelma kommitin toimesta, joka on tehty muuhun kuin oletusarvoiseen haaraan
+settings.mirror_settings.pushed_repository = Tyรถnnetty repo
+pulls.compare_changes_desc = Valitse haara, johon yhdistetรครคn, ja haara, josta vedetรครคn.
+no_eol.text = Ei EOL:รครค
+auto_init_description = Aloita Git-historia README-tiedostolla ja valinnaisesti License- ja .gitignore-tiedostoilla.
+new_from_template = Kรคytรค mallipohjaa
+new_from_template_description = Voit valita olemassa olevan repon mallipohjan ja toteuttaa sen asetukset.
+new_advanced = Lisรคasetukset
+new_advanced_expand = Laajenna napsauttamalla
+template_description = Repojen mallipohjat mahdollistavat uusien repojen luomisen halutulla hakemistorakenteella, tiedostoilla ja valinnaisilla asetuksilla.
+settings.enter_repo_name = Kirjoita omistajan ja repon nimi tรคsmรคlleen kuten esitetty:
+settings.confirmation_string = Vahvistusteksti
+settings.delete_notices_2 = - Tรคmรค toiminto poistaa pysyvรคsti repon %s mukaan lukien koodin, ongelmat, kommentit, wikidatan ja avustaja-asetukset.
+issues.filter_assginee_no_select = Kaikki kรคsittelijรคt
+issues.new.assign_to_me = Osoita itselle
+pulls.closed_at = `sulki tรคmรคn vetopyynnรถn %[2]s `
+tree_path_not_found_branch = Polkua %[1]s ei ole olemassa haarassa %[2]s
+transfer.no_permission_to_reject = Sinulla ei ole oikeutta hylรคtรค tรคtรค siirtoa.
+generate_repo = Luo repo
+tree_path_not_found_commit = Polkua %[1]s ei ole olemassa kommitissa %[2]s
+archive.pull.noreview = Tรคmรค repo on arkistoitu. Et voi katselmoida vetopyyntรถjรค.
+tree_path_not_found_tag = Polkua %[1]s ei ole olemassa tagissa %[2]s
+transfer.no_permission_to_accept = Sinulla ei ole oikeutta hyvรคksyรค tรคtรค siirtoa.
+settings.web_hook_name_feishu = Feishu / Lark Suite
+delete_preexisting = Poista olemassa olevat tiedostot
+projects.edit_subheader = Projektit organisoivat ongelmia ja seuraavat edistymistรค.
+issues.filter_no_results = Ei tuloksia
+issues.filter_no_results_placeholder = Kokeile mรครคrittรครค eri hakusuodattimet.
+issues.new.no_reviewers = Ei katselmoijia
+issues.choose.get_started = Aloitetaan
+issues.label_templates.title = Lataa tunnisteen esiasetus
+issues.label_templates.use = Kรคytรค tunnisteen esiasetusta
+issues.add_label = lisรคsi tunnisteen %s %s
+issues.add_labels = lisรคsi tunnisteet %s %s
+issues.num_reviews_one = %d katselmointi
+issues.num_reviews_few = %d katselmointia
+issues.reaction.add = Lisรครค reaktio
+issues.ref_pull_from = `viittasi tรคhรคn vetopyyntรถรถn %[4]s %[2]s `
+issues.author.tooltip.issue = Tรคmรค kรคyttรคjรค on tรคmรคn ongelman tekijรค.
+issues.author.tooltip.pr = Tรคmรค kรคyttรคjรค on tรคmรคn vetopyynnรถn tekijรค.
+issues.role.contributor_helper = Tรคmรค kรคyttรคjรค on aiemmin kommitoinut tรคhรคn repoon.
+issues.label_deletion_desc = Tunnisteen poistaminen poistaa sen kaikista ongelmista. Jatketaanko?
+issues.label_deletion_success = Tunniste on poistettu.
+issues.attachment.open_tab = `Napsauta nรคhdรคksesi "%s" uudessa vรคlilehdessรค`
+issues.attachment.download = `Napsauta ladataksesi "%s"`
+issues.unpin_issue = Poista ongelman kiinnitys
+issues.max_pinned = Et voi kiinnittรครค enempรครค ongelmia
+issues.cancel_tracking = Hylkรครค
+issues.due_date_added = lisรคsi mรครคrรคpรคivรคn %s %s
+issues.due_date_remove = poisti mรครคrรคpรคivรคn %s %s
+issues.review.comment = katselmoi %s
+issues.review.add_review_request = pyysi katselmointia kรคyttรคjรคltรค %[1]s %[2]s
+issues.review.add_review_requests = pyysi katselmointeja kรคyttรคjiltรค %[1]s %[2]s
+issues.review.reviewers = Katselmoijat
+issues.review.outdated = Vanhentunut
+issues.review.outdated_description = Sisรคltรถ on muuttunut siitรค ajanhetkestรค, kun tรคmรค kommentti luotiin
+issues.review.option.show_outdated_comments = Nรคytรค vanhentuneet kommentit
+issues.review.option.hide_outdated_comments = Piilota vanhentuneet kommentit
+issues.review.show_outdated = Nรคytรค vanhentuneet
+issues.review.hide_outdated = Piilota vanhentuneet
+pulls.sign_in_require = Kirjaudu sisรครคn luodaksesi uuden vetopyynnรถn.
+pulls.blocked_by_official_review_requests = Tรคmรค vetopyyntรถ on estetty, koska siltรค puuttuu hyvรคksyntรค yhdeltรค tai useammalta viralliselta katselmoijalta.
+pulls.no_merge_access = Sinulla ei ole valtuutta yhdistรครค tรคtรค vetopyyntรถรค.
+pulls.commit_ref_at = `viittasi tรคhรคn vetopyyntรถรถn kommitista %[2]s `
+settings.external_wiki_url_error = Ulkoisen wikin URL-osoite ei ole kelvollinen.
+settings.external_tracker_url_error = Ulkoisen ongelmienseurannan URL-osoite ei ole kelvollinen.
+settings.event_fork = Forkkaus
+settings.event_issue_label = Tunnisteet
+settings.event_pull_request_label = Tunnisteet
+settings.event_pull_request_review = Katselmoinnit
+settings.event_pull_request_review_request = Katselmointipyynnรถt
+settings.authorization_header = Authorization-otsake
+diff.has_escaped = Tรคllรค rivillรค on piilotettuja Unicode-merkkejรค
+
[graphs]
+component_loading_info = Tรคmรค saattaa kestรครค hetkenโฆ
+component_failed_to_load = Odottamaton virhe.
+component_loading = Ladataan %sโฆ
+contributors.what = kontribuutiot
+recent_commits.what = viimeisimmรคt kommitit
+code_frequency.what = koodifrekvenssi
+component_loading_failed = Ei voitu ladata %s
[org]
-org_name_holder=Organisaatio
-org_full_name_holder=Organisaation tรคydellinen nimi
+org_name_holder=Organisaation nimi
+org_full_name_holder=Organisaation koko nimi
org_name_helper=Organisaation nimen tulisi olla lyhyt ja mieleenpainuva.
create_org=Luo organisaatio
repo_updated=Pรคivitetty %s
members=Jรคsenet
teams=Tiimit
-lower_members=jรคsenet
+lower_members=jรคsentรค
lower_repositories=repot
create_new_team=Uusi tiimi
create_team=Luo tiimi
@@ -1370,7 +2225,7 @@ team_unit_desc=Salli pรครคsy repon osioihin
settings=Asetukset
settings.options=Organisaatio
-settings.full_name=Kokonimi
+settings.full_name=Koko nimi
settings.website=Nettisivu
settings.location=Sijainti
settings.permission=Kรคyttรถoikeudet
@@ -1413,11 +2268,11 @@ teams.admin_access_helper=Tiimin jรคsenet voivat tyรถntรครค (push) ja vetรครค (p
teams.no_desc=Tรคllรค tiimillรค ei ole kuvausta
teams.settings=Asetukset
teams.owners_permission_desc=Omistajilla on tรคydet kรคyttรถoikeudet kaikkiin organisaation repoihin sekรค organisaation yllรคpitรคjรคn oikeudet .
-teams.members=Ryhmรคn jรคsenet
+teams.members=Tiimin jรคsenet
teams.update_settings=Pรคivitรค asetukset
teams.delete_team=Poista tiimi
teams.add_team_member=Lisรครค tiimin jรคsen
-teams.delete_team_title=Tiimin poisto
+teams.delete_team_title=Poista tiimi
teams.delete_team_desc=Tiimin poisto peruuttaa sen jรคseniltรค oikeuden pรครคstรค tiimin varastoihin. Jatketaanko?
teams.delete_team_success=Tiimi on poistettu.
teams.read_permission_desc=Tรคmรค tiimi myรถntรครค jรคsenille Luku oikeudet: tiimin jรคsenet voivat katsella ja kloonata tiimin varastoja.
@@ -1426,6 +2281,35 @@ teams.admin_permission_desc=Tรคmรค tiimi myรถntรครค jรคsenille Yllรคpito
teams.repositories=Tiimin repot
teams.members.none=Ei jรคseniรค tรคssรค tiimissรค.
teams.all_repositories=Kaikki repot
+teams.invite.by = Kutsunut %s
+members.leave.detail = Haluatko varmasti poistua organisaatiosta "%s"?
+teams.add_all_repos_title = Lisรครค kaikki repot
+teams.invite_team_member.list = Odottavat kutsut
+teams.invite.description = Napsauta alla olevaa painiketta liittyรคksesi tiimiin.
+settings.update_setting_success = Organisaatioasetukset on pรคivitetty.
+form.create_org_not_allowed = Sinulla ei ole oikeutta luoda organisaatiota.
+teams.leave.detail = Haluatko varmasti poistua tiimistรค "%s"?
+teams.invite.title = Sinut on kutsuttu tiimiin %s organisaatiossa %s .
+teams.add_duplicate_users = Kรคyttรคjรค on jo tiimijรคsen.
+settings.visibility.limited = Rajattu (nรคkyvissรค vain kirjautuneille kรคyttรคjille)
+code = Koodi
+teams.remove_all_repos_title = Poista kaikki tiimin repot
+form.name_reserved = Organisaation nimi "%s" on varattu.
+settings.delete_org_desc = Organisaatio poistetaan pysyvรคsti. Jatketaanko?
+team_access_desc = Repositorion kรคyttรถ
+teams.specific_repositories = Mรครคritetyt repositoriot
+open_dashboard = Avaa kojelauta
+teams.remove_all_repos_desc = Tรคmรค poistaa kaikki repot tiimiltรค.
+teams.add_all_repos_desc = Tรคmรค lisรครค kaikki organisaation repot tiimille.
+team_unit_disabled = (Pois kรคytรถstรค)
+follow_blocked_user = Et voi seurata tรคtรค organisaatiota, koska organisaatio on estรคnyt sinut.
+teams.can_create_org_repo = Luo repoja
+teams.none_access = Ei pรครคsyรค
+form.name_pattern_not_allowed = Kaava "%s" ei ole sallittu organisaation nimessรค.
+settings.email = Yhteydenoton sรคhkรถposti
+teams.general_access = Mukautettu pรครคsy
+settings.change_orgname_redirect_prompt = Vanha nimi uudelleenohjaa, kunnes nimi otetaan uudelleen kรคyttรถรถn.
+settings.change_orgname_prompt = Huomio: organisaation nimen vaihtaminen vaihtaa myรถs organisaation URL-osoitteen ja vapauttaa vanhan nimen.
[admin]
dashboard=Kojelauta
@@ -1438,7 +2322,7 @@ config=Asetukset
notices=Jรคrjestelmรคn ilmoitukset
monitor=Valvonta
first_page=Ensimmรคinen
-last_page=Viimeisin
+last_page=Viimeinen
total=Yhteensรค: %d
dashboard.statistic=Yhteenveto
@@ -1449,8 +2333,8 @@ dashboard.operation_switch=Vaihda
dashboard.operation_run=Suorita
dashboard.delete_inactive_accounts=Poista kaikki aktivoimattomat kรคyttรคjรคt
dashboard.delete_repo_archives=Poista kaikki repojen arkistot (ZIP, TAR.GZ, jne..)
-dashboard.server_uptime=Palvelimen Uptime
-dashboard.current_goroutine=Nykyiset Goroutinet
+dashboard.server_uptime=Palvelimen uptime
+dashboard.current_goroutine=Nykyiset goroutinet
dashboard.current_memory_usage=Nykyinen muistinkรคyttรถ
dashboard.total_memory_allocated=Yhteensรค muistia varattu
dashboard.memory_obtained=Muistia saatu
@@ -1470,17 +2354,17 @@ dashboard.mcache_structures_obtained=MCache rakenteita saatu
dashboard.profiling_bucket_hash_table_obtained=Profilointi Bucket Hash Table saatu
dashboard.gc_metadata_obtained=GC metatietoja saatu
dashboard.other_system_allocation_obtained=Muita jรคrjestestelmรคn varauksia saatu
-dashboard.next_gc_recycle=Seuraava GC kierrรคtys
+dashboard.next_gc_recycle=Seuraava GC-kierrรคtys
dashboard.last_gc_time=Edellisen GC ajan jรคlkeen
dashboard.total_gc_time=Yhteensรค GC tauko
dashboard.total_gc_pause=Yhteensรค GC tauko
dashboard.last_gc_pause=Viime GC tauko
dashboard.gc_times=GC aikoja
-users.user_manage_panel=Tilien hallinta
+users.user_manage_panel=Kรคyttรคjรคtilien hallinta
users.new_account=Luo kรคyttรคjรคtili
users.name=Kรคyttรคjรคtunnus
-users.full_name=Kokonimi
+users.full_name=Koko nimi
users.activated=Aktivoitu
users.admin=Yllรคpito
users.restricted=Rajoitettu
@@ -1494,16 +2378,16 @@ users.auth_source=Todennuslรคhde
users.local=Paikallinen
users.password_helper=Jรคtรค salasanakenttรค tyhjรคksi jos haluat pitรครค sen muuttamattomana.
users.update_profile_success=Kรคyttรคjรคn tili on pรคivitetty.
-users.edit_account=Muokkaa kรคyttรคjรคn tiliรค
+users.edit_account=Muokkaa kรคyttรคjรคtiliรค
users.max_repo_creation_desc=(Aseta -1 kรคyttรครคksesi globaalia oletusrajaa.)
-users.is_activated=Kรคyttรคjรคtili on aktivoitu
+users.is_activated=Aktivoitu tili
users.prohibit_login=Ota sisรครคnkirjautuminen pois kรคytรถstรค
-users.is_admin=Yllรคpitรคjรค
+users.is_admin=Yllรคpitรคjรคtili
users.is_restricted=Rajoitettu tili
-users.allow_git_hook=Voi luoda Git koukkuja
+users.allow_git_hook=Voi luoda Git-koukkuja
users.allow_create_organization=Voi luoda organisaatioita
-users.update_profile=Pรคivitรค kรคyttรคjรคn tili
-users.delete_account=Poista kรคyttรคjรคn tili
+users.update_profile=Pรคivitรค kรคyttรคjรคtili
+users.delete_account=Poista kรคyttรคjรคtili
users.list_status_filter.menu_text=Suodata
users.list_status_filter.reset=Tyhjennรค
users.list_status_filter.is_active=Aktiivinen
@@ -1569,11 +2453,11 @@ auths.search_page_size=Sivukoko
auths.filter=Kรคyttรคjรคsuodatin
auths.admin_filter=Yllรคpitosuodatin
auths.restricted_filter=Rajoitettu suodatin
-auths.smtp_auth=SMTP todennustyyppi
-auths.smtphost=SMTP isรคntรค
-auths.smtpport=SMTP portti
+auths.smtp_auth=SMTP-todennustyyppi
+auths.smtphost=SMTP-isรคntรค
+auths.smtpport=SMTP-portti
auths.allowed_domains=Sallitut verkkotunnukset
-auths.skip_tls_verify=Ohita TLS tarkistaminen
+auths.skip_tls_verify=Ohita TLS-vahvistus
auths.pam_service_name=PAM palvelun nimi
auths.oauth2_tokenURL=Pรครคsymerkki URL
auths.enable_auto_register=Ota kรคyttรถรถn automaattinen rekisterรถinti
@@ -1583,21 +2467,21 @@ auths.edit=Muokkaa todennuslรคhdettรค
auths.update_success=Todennuslรคhde on pรคivitetty.
auths.update=Pรคivitรค todennuslรคhde
auths.delete=Poista todennuslรคhde
-auths.delete_auth_title=Todennuslรคhteen poisto
+auths.delete_auth_title=Poista todennuslรคhde
auths.delete_auth_desc=Todennuslรคhteen poisto estรครค kรคyttรคjiรค kรคyttรคmรคstรค sitรค kirjautumiseen. Jatketaanko?
auths.deletion_success=Todennuslรคhde on poistettu.
-config.server_config=Palvelin asetukset
-config.app_name=Sivuston otsikko
-config.app_ver=Forgejo versio
+config.server_config=Palvelimen asetukset
+config.app_name=Instanssin otsikko
+config.app_ver=Forgejo-versio
config.disable_router_log=Poista kรคytรถstรค reitittimen loki
config.run_mode=Suoritustila
-config.git_version=Git versio
+config.git_version=Git-versio
config.repo_root_path=Repon juuren polku
config.script_type=Komentosarjan tyyppi
config.reverse_auth_user=Kรครคnteinen todennus kรคyttรคjรค
-config.ssh_config=SSH asetukset
+config.ssh_config=SSH-asetukset
config.ssh_enabled=Kรคytรถssรค
config.ssh_port=Portti
config.ssh_listen_port=Kuuntele porttia
@@ -1617,24 +2501,24 @@ config.db_user=Kรคyttรคjรคtunnus
config.db_ssl_mode=SSL
config.db_path=Polku
-config.service_config=Palvelu asetukset
-config.show_registration_button=Nรคytรค rekisterรถidy painike
+config.service_config=Palveluasetukset
+config.show_registration_button=Nรคytรค rekisterรถitymispainike
config.enable_captcha=Ota CAPTCHA kรคyttรถรถn
-config.active_code_lives=Aktiivinen koodi elรคmรคt ennen vanhenemista
+config.active_code_lives=Aktivointikoodin vanhenemisaika
config.default_keep_email_private=Piilota sรคhkรถpostiosoitteet oletuksena
-config.default_visibility_organization=Uuden organisaation oletusnรคkyvyys
+config.default_visibility_organization=Uusien organisaatioiden oletusnรคkyvyys
-config.webhook_config=Webkoukku asetukset
+config.webhook_config=Webkoukkujen asetukset
config.queue_length=Jonon pituus
-config.deliver_timeout=Toimitus aikakatkaisu
+config.deliver_timeout=Toimituksen aikakatkaisu
config.mailer_enabled=Kรคytรถssรค
config.mailer_name=Nimi
-config.mailer_smtp_addr=SMTP osoite
-config.mailer_smtp_port=SMTP portti
+config.mailer_smtp_addr=SMTP-isรคntรค
+config.mailer_smtp_port=SMTP-portti
config.mailer_user=Kรคyttรคjรค
-config.oauth_config=OAuth asetukset
+config.oauth_config=OAuth-asetukset
config.oauth_enabled=Kรคytรถssรค
config.cache_config=Vรคlimuistin asetukset
@@ -1645,13 +2529,13 @@ config.cache_conn=Vรคlimuistin yhteys merkkijono
config.session_config=Istunnon asetukset
config.session_provider=Istunnon toimittaja
config.provider_config=Toimittajan asetukset
-config.cookie_name=Evรคstenimi
+config.cookie_name=Evรคsteen nimi
config.gc_interval_time=GC aikavรคli aika
config.session_life_time=Istunnon elinikรค
config.https_only=Vain HTTPS
config.cookie_life_time=Evรคsteen elinikรค
-config.picture_service=Kuva palvelu
+config.picture_service=Kuvapalvelu
config.disable_gravatar=Poista kรคytรถstรค Gravatar
config.git_gc_args=Roskienkeruun parametrit
@@ -1660,12 +2544,12 @@ config.git_mirror_timeout=Peilauspรคivitys aikakatkaistiin
config.git_clone_timeout=Kloonaus aikakatkaistiin
config.git_gc_timeout=Roskienkeruu aikakatkaistiin
-config.log_config=Loki asetukset
+config.log_config=Lokiasetukset
config.disabled_logger=Pois kรคytรถstรค
-monitor.cron=Cron tehtรคvรคt
+monitor.cron=Cron-tehtรคvรคt
monitor.name=Nimi
monitor.schedule=Aikataulu
monitor.next=Seuraava aika
@@ -1691,16 +2575,124 @@ notices.type=Tyyppi
notices.type_1=Repo
notices.desc=Kuvaus
notices.op=Toiminta
+auths.sspi_auto_create_users = Luo kรคyttรคjรคt automaattisesti
+integrations = Integraatiot
+emails.change_email_header = Pรคivitรค sรคhkรถpostiominaisuudet
+emails.change_email_text = Haluatko varmasti pรคivittรครค tรคmรคn sรคhkรถpostiosoitteen?
+emails.updated = Sรคhkรถpostiosoite pรคivitetty
+users.organization_creation.description = Salli uusien organisaatioiden luonti.
+users.deletion_success = Kรคyttรคjรคtili on poistettu.
+users.reset_2fa = Nollaa 2FA
+packages.published = Julkaistu
+packages.version = Versio
+auths.tip.oauth2_provider = OAuth2-palveluntarjoaja
+hooks = Webkoukut
+identity_access = Identiteetti ja pรครคsy
+config.test_email_placeholder = Sรคhkรถposti (esim. test@example.com)
+auths.force_smtps = Pakota SMTPS
+config.mailer_use_sendmail = Kรคytรค Sendmailia
+users.new_success = Kรคyttรคjรคtili "%s" on luotu.
+config.disable_register = Poista itserekisterรถinti kรคytรถstรค
+config.enable_openid_signin = Kรคytรค OpenID-kirjautumista
+config.enable_openid_signup = Kรคytรค OpenID-itserekisterรถintiรค
+monitor.queue.settings.changed = Asetukset pรคivitetty
+config.db_schema = Skeema
+settings = Yllรคpitรคjรคn asetukset
+emails.delete = Poista sรคhkรถpostiosoite
+emails.deletion_success = Sรคhkรถpostiosoite on poistettu.
+emails.delete_desc = Haluatko varmasti poistaa tรคmรคn sรคhkรถpostiosoitteen?
+users.cannot_delete_self = Et voi poistaa itseรคsi
+packages.package_manage_panel = Hallitse paketteja
+config.ssh_start_builtin_server = Kรคytรค sisรครคnrakennettua palvelinta
+notices.type_2 = Tehtรคvรค
+emails.delete_primary_email_error = Et voi poistaa ensisijaista sรคhkรถpostiosoitetta.
+users.details = Kรคyttรคjรคn tiedot
+config_summary = Yhteenveto
+config.send_test_mail = Lรคhetรค testisรคhkรถposti
+auths.oauth2_icon_url = Kuvakkeen URL-osoite
+config.mail_notify = Kรคytรค sรคhkรถposti-ilmoituksia
+config.send_test_mail_submit = Lรคhetรค
+systemhooks = Jรคrjestelmรคn webkoukut
+packages.total_size = Koko yhteensรค: %s
+auths.oauth2_provider = OAuth2-palveluntarjoaja
+auths.tips.gmail_settings = Gmail-asetukset:
+config.mailer_sendmail_path = Sendmail-polku
+auths.sspi_default_language = Kรคyttรคjรคn oletuskieli
+config_settings = Asetukset
+monitor.queue.settings.remove_all_items = Poista kaikki
+config.skip_tls_verify = Ohita TLS-vahvistus
+auths.sspi_auto_activate_users = Aktivoi kรคyttรคjรคt automaattisesti
+dashboard.new_version_hint = Forgejo %s on nyt saatavilla. Kรคytรถssรคsi on %s. Lue lisรคtietoja blogista .
+defaulthooks.add_webhook = Lisรครค oletusarvoinen webkoukku
+monitor.execute_times = Suoritukset
+defaulthooks = Oletusarvoiset webkoukut
+systemhooks.update_webhook = Pรคivitรค jรคrjestelmรคn webkoukku
+systemhooks.add_webhook = Lisรครค jรคrjestelmรคn webkoukku
+config.domain = Palvelimen verkkotunnus
+monitor.process.cancel = Peru prosessi
+config.allow_only_internal_registration = Salli rekisterรถinti vain Forgejon kautta
+config.allow_only_external_registration = Salli rekisterรถinti vain ulkoisten palvelujen kautta
+config.require_sign_in_view = Vaadi sisรครคnkirjautuminen sisรคllรถn katselemiseksi
+config.git_config = Git-asetukset
+monitor.stats = Tilastot
+repos.lfs_size = LFS:n koko
+config.lfs_config = LFS-asetukset
+config.register_email_confirm = Vaadi sรคhkรถpostivahvistus rekisterรถitymiseen
+config.ssh_domain = SSH-palvelimen verkkotunnus
+config.app_slogan = Instanssin tunnuslause
+config.lfs_content_path = LFS-sisรคllรถn polku
+users.max_repo_creation = Repojen enimmรคismรครคrรค
+defaulthooks.update_webhook = Pรคivitรค oletusarvoinen webkoukku
+auths.auth_manage_panel = Todennuslรคhteiden hallinta
+config.custom_conf = Asetustiedoston polku
+config.reset_password_code_lives = Palautuskoodin vanhenemisaika
+monitor.processes_count = %d prosessia
+config.default_allow_create_organization = Salli organisaatioiden luominen oletuksena
+config.test_mail_sent = Testisรคhkรถposti on lรคhetetty osoitteeseen "%s".
+config.mailer_sendmail_timeout = Sendmailin aikakatkaisu
+dashboard.cron.started = Kรคynnistetty Cron: %[1]s
+dashboard.task.process = Tehtรคvรค: %[1]s
+dashboard.task.error = Virhe tehtรคvรคssรค: %[1]s: %[3]s
+dashboard.task.unknown = Tuntematon tehtรคvรค: %[1]s
+dashboard.cron.error = Virhe Cronissa: %s: %[3]s
+dashboard.task.started = Kรคynnistetty tehtรคvรค: %[1]s
+dashboard.cron.finished = Cron: %[1]s on valmistunut
+dashboard.resync_all_sshkeys = Pรคivitรค ".ssh/authorized_keys"-tiedosto Forgejo:n SSH-avaimilla.
+dashboard.cleanup_packages = Siivoa vanhentuneet paketit
+config.default_allow_only_contributors_to_track_time = Salli vain avustajien seurata aikaa
+monitor.download_diagnosis_report = Lataa diagnostiikkaraportti
+monitor.duration = Kesto (s)
+monitor.last_execution_result = Tulos
+dashboard.sync_branch.started = Haarasynkronointi aloitettu
+dashboard.sync_tag.started = Tagisynkronointi aloitettu
+users.bot = Botti
+auths.syncenabled = Kรคytรค kรคyttรคjรคsynkronointia
+auths.enable_ldap_groups = Kรคytรค LDAP-ryhmiรค
+auths.login_source_exist = Todennuslรคhde "%s" on jo olemassa.
+
[action]
-create_repo=luotu repo %s
+create_repo=loi repon %s
rename_repo=uudelleennimetty repo %[1]s
nimelle %[3]s
transfer_repo=siirretty repo %s
kohteeseen %s
push_tag=tyรถnsi tagin %[3]s kohteeseen %[4]s
delete_tag=poisti tagin %[2]s kohteesta %[3]s
compare_commits_general=Vertaa committeja
create_branch=loi haaran %[3]s repossa %[4]s
+compare_commits = Vertaa %d kommittia
+compare_branch = Vertaa
+review_dismissed_reason = Syy:
+commit_repo = tyรถnsi haaraan %[3]s repossa %[4]s
+create_issue = `avasi ongelman %[3]s#%[2]s `
+reopen_issue = `avasi uudelleen ongelman %[3]s#%[2]s `
+create_pull_request = `loi vetopyynnรถn %[3]s#%[2]s `
+reopen_pull_request = `avasi uudelleen vetopyynnรถn %[3]s#%[2]s `
+close_pull_request = `sulki vetopyynnรถn %[3]s#%[2]s `
+comment_issue = `kommentoi ongelmaa %[3]s#%[2]s `
+close_issue = `sulki ongelman %[3]s#%[2]s `
+merge_pull_request = `yhdisti vetopyynnรถn %[3]s#%[2]s `
+comment_pull = `kommentoi vetopyyntรถรค %[3]s#%[2]s `
[tool]
now=nyt
@@ -1725,6 +2717,7 @@ raw_minutes=minuuttia
default_message=Pudota tiedostot tรคhรคn tai klikkaa aluetta ladataksesi tiedoston.
invalid_input_type=Tรคmรคntyyppisiรค tiedostoja ei voi ladata.
remove_file=Poista tiedosto
+file_too_big = Tiedoston koko ({{filesize}} Mt) ylittรครค enimmรคisrajan ({{maxFilesize}} Mt).
[notification]
notifications=Ilmoitukset
@@ -1736,12 +2729,20 @@ pin=Merkitse ilmoitus
mark_as_read=Merkitse luetuksi
mark_as_unread=Merkitse lukemattomaksi
mark_all_as_read=Merkitse kaikki luetuiksi
+watching = Tarkkaillaan
+no_subscriptions = Ei tilauksia
+subscriptions = Tilaukset
[gpg]
error.no_committer_account=Committaajan sรคhkรถpostiosoitteeseen ei ole linkitetty tiliรค
-error.not_signed_commit=Ei allekirjoitettu committi
+error.not_signed_commit=Kommitti ei ole allekirjoitettu
+error.extract_sign = Allekirjoituksen purkaminen epรคonnistui
+default_key = Allekirjoitettu oletusavaimella
+error.failed_retrieval_gpg_keys = Ei saatu yhtรคkรครคn kommitin tekijรคn tiliin liitettyรค avainta
+error.generate_hash = Tiivisteen luominen kommitista epรคonnistui
[units]
+unit = Yksikkรถ
[packages]
title=Paketit
@@ -1756,13 +2757,150 @@ alpine.repository.branches=Haarat
alpine.repository.repositories=Repot
conan.details.repository=Repo
owner.settings.cleanuprules.enabled=Kรคytรถssรค
+details.license = Lisenssi
+about = Tietoja tรคstรค paketista
+debian.install = Asenna paketti seuraavalla komennolla:
+owner.settings.cleanuprules.edit = Muokkaa siivoussรครคntรถรค
+arch.version.groups = Ryhmรค
+details.project_site = Projektin verkkosivusto
+details.repository_site = Repositorion verkkosivusto
+container.pull = Vedรค levykuva komentoriviltรค:
+generic.download = Lataa paketti komentoriviltรค:
+dependency.version = Versio
+keywords = Avainsanat
+dependencies = Riippuvuudet
+container.labels.key = Avain
+container.labels.value = Arvo
+pypi.install = Asenna paketti pipillรค seuraavalla komennolla:
+npm.install = Asenna paketti npm:llรค seuraavalla komennolla:
+npm.install2 = tai lisรครค se package.json-tiedostoon:
+empty.documentation = Lisรคtietoja pakettirekisteristรค on saatavilla dokumentaatiossa .
+helm.install = Asenna paketti seuraavalla komennolla:
+owner.settings.chef.keypair = Luo avainpari
+settings.delete.error = Paketin poistaminen epรคonnistui.
+requirements = Vaatimukset
+published_by_in = Julkaistu %[1]s, julkaisija %[3]s projektissa %[5]s
+pypi.requires = Vaatii Pythonin
+alpine.install = Asenna paketti seuraavalla komennolla:
+debian.repository.components = Komponentit
+cran.install = Asenna paketti seuraavalla komennolla:
+settings.link.select = Valitse repo
+owner.settings.chef.title = Chef-rekisteri
+owner.settings.cleanuprules.add = Lisรครค siivoussรครคntรถ
+versions = Versiot
+versions.view_all = Nรคytรค kaikki
+debian.repository.architectures = Arkkitehtuurit
+container.details.type = Levykuvan tyyppi
+arch.version.properties = Version ominaisuudet
+rpm.install = Asenna paketti seuraavalla komennolla:
+owner.settings.cleanuprules.none = Siivoussรครคntรถjรค ei vielรค ole.
+container.details.platform = Alusta
+npm.dependencies = Riippuvuudet
+owner.settings.cleanuprules.title = Siivoussรครคnnรถt
+arch.version.depends = Riippuu
+settings.delete = Poista paketti
+arch.version.description = Kuvaus
+settings.delete.success = Paketti on poistettu.
+npm.dependencies.optional = Valinnaiset riippuvuudet
+debian.repository.distributions = Jakelut
+composer.dependencies = Riippuvuudet
+chef.install = Asenna paketti seuraavalla komennolla:
+details.documentation_site = Dokumentaation verkkosivusto
+go.install = Asenna paketti komentoriviltรค:
+alpine.repository.architectures = Arkkitehtuurit
+composer.registry = Mรครคritรค tรคmรค rekisteri ~/.composer/config.json
-tiedostossa:
+debian.registry = Mรครคritรค tรคmรค rekisteri komentoriviltรค:
+rpm.registry = Mรครคritรค rekisteri komentoriviltรค:
+maven.install = Kรคytรค pakettia sisรคllyttรคmรคllรค seuraava dependencies
-lohkoon pom.xml
-tiedostossa:
+npm.registry = Mรครคritรค rekisteri projektin .npmrc
-tiedostossa:
+alpine.repository = Repositorion tiedot
+cargo.registry = Mรครคritรค tรคmรค rekisteri Cargon asetustiedostossa (esimerkiksi ~/.cargo/config.toml
):
+cargo.install = Asenna paketti Cargolla suorittamalla seuraava komento:
+composer.install = Asenna paketti Composerilla suorittamalla seuraava komento:
+rpm.distros.redhat = RedHatiin pohjautuvilla jakeluilla
+rpm.distros.suse = SUSE:en pohjautuvilla jakeluilla
+rpm.repository.architectures = Arkkitehtuurit
+cran.registry = Mรครคritรค rekisteri Rprofile.site
-tiedostossa:
+swift.install2 = ja suorita seuraava komento:
+maven.registry = Mรครคritรค tรคmรค rekisteri projektin pom.xml
-tiedostossa:
+maven.install2 = Suorita komentoriviltรค:
+nuget.registry = Mรครคritรค rekisteri komentoriviltรค:
+nuget.install = Asenna paketti NuGetillรค suorittamalla seuraava komento:
+rubygems.install = Asenna paketti gemillรค suorittamalla seuraava komento:
+rubygems.install2 = tai lisรครค se Gemfileen:
+swift.registry = Mรครคritรค rekisteri komentoriviltรค:
+swift.install = Lisรครค paketti Package.swift
-tiedostoon:
+owner.settings.cleanuprules.keep.count.1 = 1 versio per paketti
+owner.settings.cleanuprules.keep.count.n = %d versiota per paketti
+conan.install = Asenna paketti Conanilla suorittamalla seuraava komento:
+chef.registry = Mรครคritรค tรคmรค rekisteri ~/.chef/config.rb
-tiedostossa:
+conan.registry = Mรครคritรค tรคmรค rekisteri komentoriviltรค:
+conda.install = Asenna paketti Condalla suorittamalla seuraava komento:
+helm.registry = Mรครคritรค tรคmรค rekisteri komentoriviltรค:
+pub.install = Asenna paketti Dartilla suorittamalla seuraava komento:
+owner.settings.cargo.title = Cargon rekisteri-indeksi
+settings.delete.description = Paketin poistaminen on peruuttamaton toimenpide, sitรค ei voi perua.
+settings.link.success = Repositorion linkki pรคivitettiin onnistuneesti.
+settings.link.button = Pรคivitรค repositorion linkki
+owner.settings.cleanuprules.preview.overview = %d pakettia on ajastettu poistettavaksi.
+owner.settings.cargo.initialize.success = Cargo-indeksi luotiin onnistuneesti.
+vagrant.install = Lisรครค Vagrant-boksi suorittamalla seuraava komento:
+rubygems.dependencies.development = Kehitysriippuvuudet
+owner.settings.cleanuprules.preview = Siivoussรครคnnรถn esikatselu
+npm.dependencies.development = Kehitysriippuvuudet
+composer.dependencies.development = Kehitysriippuvuudet
+owner.settings.cleanuprules.success.update = Siivoussรครคntรถ on pรคivitetty.
+owner.settings.cleanuprules.success.delete = Siivoussรครคntรถ on poistettu.
+settings.link = Linkitรค tรคmรค paketti repositorioon
+maven.download = Lataa riippuvuus suorittamalla komentorivillรค:
+registry.documentation = Lisรคtietoja %s-rekisteristรค on dokumentaatiossa .
+owner.settings.chef.keypair.description = Avainpari vaaditaan Chef-rekisteriin tunnistautumista varten. Jos olet luonut avainparin aiemmin, uuden avainparin luominen hylkรครค aiemman avainparin.
+owner.settings.cleanuprules.keep.pattern = Sรคilytรค kaavaa vastaavat versiot
+owner.settings.cleanuprules.pattern_full_match = Toteuta kaavio paketin koko nimeen
+owner.settings.cleanuprules.keep.title = Nรคitรค sรครคntรถjรค vastaavat versiot sรคilytetรครคn, vaikka ne vastaisivat alla olevaa poistosรครคntรถรค.
+owner.settings.cleanuprules.keep.count = Sรคilytรค viimeisimmรคt
+owner.settings.cleanuprules.remove.pattern = Poista kaavaa vastaavat versiot
+owner.settings.cleanuprules.keep.pattern.container = Viimeisin (latest
) versio sรคilytetรครคn aina Container-paketeista.
+owner.settings.cleanuprules.remove.title = Nรคitรค sรครคntรถjรค vastaavat versiot poistetaan, ellei sรครคntรถ ylรคpuolella kรคske sรคilyttรครค niitรค.
+owner.settings.cleanuprules.remove.days = Poista versiot, jotka ovat vanhempia kuin
+arch.pacman.helper.gpg = Lisรครค luottamusvarmenne pacmanille:
+arch.pacman.sync = Synkronoi paketti pacmanin kanssa:
+debian.registry.info = Valitse $distribution ja $component alla olevasta listasta.
+rpm.repository.multiple_groups = Tรคmรค paketti on saatavilla useissa ryhmissรค.
+owner.settings.cargo.rebuild.success = Cargo-indeksi rakennettiin uudelleen.
+owner.settings.cleanuprules.preview.none = Siivoussรครคntรถ ei vastaa yhtรคkรครคn pakettia.
+arch.pacman.conf = Lisรครค palvelin asiaan liittyvรคllรค jakelulla ja arkkitehtuurilla tiedostoon /etc/pacman.conf
:
+published_by = Julkaistu %[1]s kรคyttรคjรคn %[3]s toimesta
+alpine.registry.key = Lataa rekisterin julkinen RSA-avain hakemistoon /etc/apk/keys/
vahvistaaksesi indeksin allekirjoituksen:
+alpine.registry = Mรครคritรค tรคmรค rekisteri lisรครคmรคllรค URL-osoite tiedostoon /etc/apk/repositories
:
+rubygems.dependencies.runtime = Ajonaikaiset riippuvuudet
+owner.settings.cargo.rebuild.error = Cargo-indeksin rakentaminen uudelleen epรคonnistui: %v
+owner.settings.cargo.rebuild = Rakenna indeksi uudelleen
+empty.repo = Lรคhetitkรถ paketin, mutta se ei nรคy tรครคllรค? Siirry paketin asetuksiin ja linkitรค se tรคhรคn repoon.
+alpine.registry.info = Valitse $branch ja $repository alla olevasta listasta.
+container.images.title = Levykuvat
+owner.settings.cargo.initialize = Alusta indeksi
+owner.settings.cargo.initialize.description = Erityinen Git-repoindeksi vaaditaan Cargo-rekisterin kรคyttรคmiseksi. Tรคmรคn valinnan kรคyttรคminen luo (tarvittaessa uudelleen) repon ja mรครคrittรครค sen asetukset automaattisesti.
+settings.link.error = Repositorion linkin pรคivittรคminen epรคonnistui.
+alt.repository.multiple_groups = Tรคmรค paketti on saatavilla useissa ryhmissรค.
+alt.repository.architectures = Arkkitehtuurit
+alt.install = Asenna paketti
+alt.registry.install = Asenna paketti suorittamalla komento:
[secrets]
+creation.failed = Salaisuuden lisรครคminen epรคonnistui.
+deletion = Poista salaisuus
+creation.success = Salaisuus "%s" on pรคivitetty.
+creation = Lisรครค salaisuus
+none = Ei salaisuuksia vielรค.
+management = Hallitse salaisuuksia
+deletion.failed = Salaisuuden poistaminen epรคonnistui.
+secrets = Salaisuudet
+deletion.description = Salaisuuden poistaminen on pysyvรค toimenpide, eikรค sitรค voi perua. Jatketaanko?
+deletion.success = Salaisuus on poistettu.
+description = Salaisuudet vรคlitetรครคn tietyille toimenpiteille, eikรค niitรค voi muuten lukea.
[actions]
-
-
-
runners.name=Nimi
runners.owner_type=Tyyppi
runners.description=Kuvaus
@@ -1771,12 +2909,125 @@ runners.task_list.repository=Repo
runners.task_list.commit=Commit
runs.commit=Commit
+status.success = Onnistunut
+status.unknown = Tuntematon
+status.waiting = Odotustilassa
+status.running = Kรคynnissรค
+status.blocked = Estetty
+status.failure = Epรคonnistunut
+status.cancelled = Peruttu
+status.skipped = Ohitettu
+runners.none = Testinajajia ei saatavilla
+runners.status.unspecified = Tuntematon
+runners.update_runner = Pรคivitรค muutokset
+runners.edit_runner = Muokkaa testinajajaa
+runners.update_runner_success = Testinajaja pรคivitetty onnistuneesti
+runners.delete_runner_success = Testinajaja poistettu onnistuneesti
+runners.reset_registration_token = Uudelleenaseta rekisterรถintiavain
+runs.scheduled = Ajastettu
+runs.status = Tila
+runs.empty_commit_message = (tyhjรค commit-viesti)
+variables.deletion = Poista muuttuja
+runners.new_notice = Testinajajan aloitusohjeet
+workflow.dispatch.input_required = Arvo syรถtteelle "%s" vaadittu.
+runners.status.active = Aktiivinen
+runs.no_workflows.documentation = Katso lisรคtietoja Forgejo Actions -ohjelmistosta dokumentaatiosta .
+variables.description = Muuttujat asetetaan tietyille toiminnoille eikรค niitรค voida lukea muutoin.
+runners.labels = Tunnisteet
+runners.delete_runner_failed = Testinajajan poisto epรคonnistui
+runners.delete_runner_header = Varmista testinajajan poisto
+runners.task_list.status = Tila
+runners.reset_registration_token_success = Testiajajan rekisterรถintiavain uudelleenasetettu onnistuneesti
+variables.none = Ei muuttujia vielรค.
+runners.id = Tunniste
+runners.status = Tila
+runners.task_list = Ajajan viimeisimmรคt tehtรคvรคt
+runners.task_list.no_tasks = Tehtรคviรค ei ole vielรค mรครคritelty.
+runners.last_online = Viimeisin kรคynnissรคoloajankohta
+runners.runner_title = Testinajaja
+runners.task_list.done_at = Valmistunut ajankohtana
+runs.no_matching_online_runner_helper = Testiajajaa tunnisteella %s ei lรถytynyt
+runs.no_results = Ei tuloksia.
+runners.delete_runner = Poista testinajaja
+variables.deletion.description = Muuttujan poistaminen on lopullista eikรค sitรค voi peruuttaa. Jatketaanko?
+workflow.dispatch.invalid_input_type = Syรถtetyyppi "%s" ei kelpaa.
+workflow.dispatch.warn_input_limit = Nรคytetรครคn vain ensimmรคiset %d syรถtettรค.
+runners.runner_manage_panel = Hallinnoi testinajajia
+variables = Muuttujat
+variables.management = Hallinnoi muuttujia
+variables.creation = Lisรครค muuttuja
+runs.no_workflows.quick_start = Etkรถ tiedรค kuinka Forgejo Actions toimii? Katso aloitusohje .
+runners.new = Luo uusi testinajaja
+runners.version = Versio
+runs.expire_log_message = Lokitiedostot on tyhjรคtty vanhenemisen vuoksi.
+runners.delete_runner_notice = Mikรคli testinajajalla on keskenerรคinen tehtรคvรค, se pysรคytetรครคn ja merkitรครคn epรคonnistuneeksi. Tรคmรค saattaa johtaa testinajoprosessin rikkoutumiseen.
+runners.update_runner_failed = Testinajajan pรคivitys epรคonnistui
+variables.deletion.success = Muuttuja poistettu.
+variables.edit = Muokkaa muuttujaa
+variables.creation.success = Muuttuja "%s" lisรคtty.
+variables.deletion.failed = Muuttujan poisto epรคonnistui.
+variables.creation.failed = Muuttujan lisรคys epรคonnistui.
+variables.update.failed = Muuttujan muokkaus epรคonnistui.
+variables.update.success = Muuttuja muokattu.
+variables.id_not_exist = Muuttujaa tunnisteella %d ei ole olemassa.
+runs.all_workflows = Kaikki tyรถnkulut
+workflow.dispatch.run = Suorita tyรถnkulku
+workflow.enable = Kรคytรค tyรถnkulkua
+runs.no_workflows = Ei tyรถnkulkuja vielรค.
+runs.actors_no_select = Kaikki toimijat
+runs.workflow = Tyรถnkulku
+workflow.enable_success = Tyรถnkulku "%s" otettu kรคyttรถรถn.
+workflow.disabled = Tyรถnkulku on poistettu kรคytรถstรค.
+runs.actor = Toimija
+workflow.disable = Poista tyรถnkulku kรคytรถstรค
+workflow.disable_success = Tyรถnkulku "%s" on poistettu kรคytรถstรค.
+runs.no_job = Tyรถnkulun tulee sisรคltรครค vรคhintรครคn yksi tyรถ
+runs.invalid_workflow_helper = Tyรถnkulun asetustiedosto on virheellinen. Tarkista asetustiedosto: %s
+runners = Ajajat
+actions = Actions
+unit.desc = Hallitse integroituja CI/CD-putkia Forgejo Actionsia hyรถdyntรคen.
+runs.pushed_by = tyรถntรคnyt
+runs.no_workflows.help_no_write_access = Lisรคtietoja Forgejo Actionsista on saatavilla dokumentaatiosta .
[projects]
+type-1.display_name = Yksittรคinen projekti
+deleted.display_name = Poistettu projekti
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
+changed_filemode = %[1]s -> %[2]s
+executable_file = Ajettava tiedosto
+symbolic_link = Symbolinen linkki
+normal_file = Tavallinen tiedosto
+directory = Kansio
+[search]
+search = Haeโฆ
+type_tooltip = Haun tyyppi
+fuzzy_tooltip = Sisรคllytรค tulokset, jotka myรถs melkein vastaavat hakusanaa
+regexp = RegExp
+regexp_tooltip = Tulkitse hakutermi sรครคnnรถllisenรค lausekkeena
+package_kind = Etsi pakettejaโฆ
+exact = Tรคsmรคllinen
+exact_tooltip = Sisรคllytรค vain tรคsmรคlleen hakusanaa vastaavat tulokset
+team_kind = Etsi tiimejรคโฆ
+code_kind = Etsi koodiaโฆ
+code_search_unavailable = Koodihaku ei tรคllรค hetkellรค ole saatavilla. Ota yhteyttรค jรคrjestelmรคnvalvojaan.
+union = yhdistelmรคhaku
+union_tooltip = Sisรคllytรค tulokset, jotka vastaavat minkรค tahansa vรคlilyรถnnillรค erotetuista avainsanoista
+project_kind = Etsi projektejaโฆ
+no_results = Hakutuloksia ei lรถytynyt.
+keyword_search_unavailable = Avainsanahaku ei tรคllรค hetkellรค ole saatavilla. Ota yhteyttรค jรคrjestelmรคnvalvojaan.
+repo_kind = Etsi repositorioitaโฆ
+user_kind = Etsi kรคyttรคjiรคโฆ
+org_kind = Etsi organisaatioitaโฆ
+branch_kind = Etsi haarojaโฆ
+issue_kind = Etsi ongelmiaโฆ
+milestone_kind = Etsi merkkipaaluja...
+pull_kind = Etsi pull-vetojaโฆ
+commit_kind = Etsi kommittejaโฆ
+fuzzy = Sumea
+runner_kind = Etsi ajajiaโฆ
+code_search_by_git_grep = Nykyiset koodin hakutulokset pohjautuvat komentoon "git grep". Parempia tuloksia on mahdollista saada, jos sivuston yllรคpitรคjรค ottaa kรคyttรถรถn koodin indeksoijan.
diff --git a/options/locale/locale_fil.ini b/options/locale/locale_fil.ini
index b9e6dd8f34..b88e76956c 100644
--- a/options/locale/locale_fil.ini
+++ b/options/locale/locale_fil.ini
@@ -1,6 +1,3 @@
-
-
-
[common]
page = Pahina
language = Wika
@@ -8,17 +5,17 @@ mirrors = Mga Mirror
forks = Mga Fork
activities = Mga Aktibidad
pull_requests = Mga hiling sa paghila
-issues = Mga Isyu
-milestones = Mga Milestone
+issues = Mga isyu
+milestones = Mga milestone
ok = OK
cancel = Kanselahin
retry = Subukan Muli
-rerun = Patakbuhin Muli
+rerun = Patakbuhin muli
save = I-save
add = Magdagdag
remove_all = Tanggalin lahat
-remove_label_str = Tanggalin ang item "%s"
-edit = Baguhin
+remove_label_str = Tanggalin ang item na "%s"
+edit = I-edit
enabled = Naka-enable
copy = Kopyahin
copy_content = Kopyahin ang nilalaman
@@ -32,13 +29,13 @@ twofa_scratch = Scratch code ng two-factor
sources = Mga Source
collaborative = Pagtutulungan
copy_type_unsupported = Hindi makokopya ang itong uri ng file
-error404 = Ang pahina na sinusubukan mong bisitahin ay alinman hindi umiiral o wala kang pahintulot para itignan.
+error404 = Ang pahina na sinusubukan mong bisitahin ay alinman hindi umiiral , tinanggal o wala kang pahintulot para itignan.
version = Bersyon
powered_by = Pinapatakbo ng %s
explore = Tuklasin
help = Tulong
logo = Logo
-sign_in = Mag-Sign In
+sign_in = Mag-sign in
sign_in_with_provider = Mag-sign in gamit ang %s
sign_in_or = o
sign_out = Mag-Sign Out
@@ -95,12 +92,12 @@ your_starred = Naka-bituin
your_settings = Mga Setting
all = Lahat
go_back = Bumalik
-never = Hindi Kailanman
+never = Hindi kailanman
unknown = Hindi Alam
rss_feed = Feed ng RSS
pin = I-pin
unpin = I-unpin
-artifacts = Mga Artifact
+artifacts = Mga artifact
archived = Naka-archive
concept_system_global = Global
concept_user_individual = Indibidwal
@@ -127,7 +124,7 @@ filter.private = Pribado
notifications = Mga Abiso
active_stopwatch = Aktibong tagasubaybay ng oras
locked = Naka-kandado
-preview = Paunang tingnan
+preview = I-preview
confirm_delete_artifact = Sigurado ka bang gusto mong burahin ang artifact na "%s"?
rerun_all = Patakbuhin muli ang lahat ng mga trabaho
add_all = Idagdag lahat
@@ -141,6 +138,15 @@ dashboard = Dashboard
more_items = Higit pang mga item
invalid_data = Hindi wastong datos: %v
copy_generic = Kopyahin sa clipboard
+test = Subukan
+error413 = Naubos mo na ang iyong quota.
+new_repo.title = Bagong repositoryo
+new_migrate.title = Bagong paglipat
+new_repo.link = Bagong repositoryo
+new_migrate.link = Bagong paglipat
+new_org.link = Bagong organisasyon
+new_org.title = Bagong organisasyon
+copy_path = Kopyahin ang path
[home]
search_repos = Maghanap ng Repositoryโฆ
@@ -187,8 +193,8 @@ relevant_repositories_tooltip = Mga repositoryo na isang fork o walang topic, ic
code_search_unavailable = Kasalukuyang hindi available ang code search. Mangyaring makipag-ugnayan sa site administrator.
code_no_results = Walang source code na tumutugma sa iyong search term na nahanap.
relevant_repositories = Ang mga kaugnay na repositoryo ay pinapakita, ipakita ang hindi naka-filter na resulta .
-stars_few = %d mga star
-forks_one = %d tinidor
+stars_few = %d mga bitwin
+forks_one = %d fork
forks_few = %d mga fork
stars_one = %d bituin
@@ -196,10 +202,10 @@ stars_one = %d bituin
footer.software = Tungkol sa software na ito
navbar = Bar ng nabigasyon
footer = Footer
-footer.links = Mga Link
+footer.links = Mga link
[error]
-report_message = Kung naniniwala ka na ito ay isang bug ng Forgejo, mangyaring maghanap ng mga isyu sa Codeberg o magbukas ng bagong isyu kapag kailangan.
+report_message = Kung naniniwala ka na ito ay isang bug ng Forgejo, mangyaring maghanap ng mga isyu sa Codeberg o magbukas ng bagong isyu kapag kailangan.
occurred = May nangyaring error
missing_csrf = Masamang Kahilingan: walang CSRF token
invalid_csrf = Masamang Kahilingan: hindi angkop na CSRF token
@@ -225,12 +231,12 @@ ssl_mode = SSL
path = Daanan
sqlite_helper = File path para sa SQLite3 database. Maglagay ng absolute path kapag tinatakbo mo ang Forgejo bilang serbisyo.
reinstall_confirm_check_3 = Kinukumprima mo na sigurado ka talaga na ang Forgejo na ito ay tumatakbo sa tamang app.ini na lokasyon at sigurado ka na kailangan mo mag-reinstall. Kinukumpirma mo na kilalanin ang mga panganib sa itaas.
-err_empty_db_path = Hindi maaring walang laman ang path ng SQLite database.
-no_admin_and_disable_registration = Hindi mo maaring i-disable ang user self-registration nang hindi gumawa ng isang tagapangasiwa na account.
-err_empty_admin_password = Hindi maaring walang laman ang password ng tagapangasiwa.
-err_empty_admin_email = Hindi maaring walang laman ang email ng tagapangasiwa.
-err_admin_name_is_reserved = Hindi angkop ang Username ng Tagapangasiwa, naka-reserve ang username
-err_admin_name_is_invalid = Hindi angkop ang Username ng Tagapangasiwa
+err_empty_db_path = Hindi maaaring walang laman ang path ng SQLite database.
+no_admin_and_disable_registration = Hindi mo maaaring i-disable ang user self-registration nang hindi gumawa ng isang tagapangasiwa na account.
+err_empty_admin_password = Hindi maaaring walang laman ang password ng tagapangasiwa.
+err_empty_admin_email = Hindi maaaring walang laman ang email ng tagapangasiwa.
+err_admin_name_is_reserved = Hindi angkop ang username ng tagapangasiwa, naka-reserba ang username
+err_admin_name_is_invalid = Hindi angkop ang username ng tagapangasiwa
general_title = Mga General Setting
app_name = Pamagat ng instansya
app_name_helper = Ilagay ang pangalan ng iyong instansya dito. Ipapakita ito sa bawat page.
@@ -242,11 +248,11 @@ run_user_helper = Ang operating system username na ang Forgejo ay tatakbo bilang
domain = Domain ng server
domain_helper = Domain o host para sa server na ito.
ssh_port = Port ng SSH Server
-http_port = HTTP listen port
+http_port = Listen port sa HTTP
lfs_path_helper = Ang mga file na naka-track sa Git LFS ay ilalagay sa directory na ito. Iwanang walang laman para i-disable.
-reinstall_confirm_message = Ang pag-install muli na may umiiral na Forgejo database ay maaring magdulot ng mga problema. Sa karamihan ng mga kaso, dapat mong gamitin ang iyong umiiral na "app.ini" para patakbuhin ang Forgejo. Kung alam mo ang ginagawa mo, kumpirmahin ang mga sumusunod:
-reinstall_confirm_check_1 = Ang data na naka-encrypt sa pamamagitan ng SECRET_KEY sa app.ini ay maaring mawala: baka hindi maka-log in ang mga user gamit ng 2FA/OTP at ang mga mirror ay maaring hindi gumana mg maayos. Sa pamamagitan ng pag-check ng box na ito kinukumpirma mo na ang kasalukuyang app.ini file ay naglalaman ng tamang SECRET_KEY.
-reinstall_confirm_check_2 = Ang mga repositoryo at mga setting ay maaring kailangang i-resynchronize. Sa pamamagitan ng pag-check ng box na ito kinukumprima mo na ire-resynchronize mo ang mga hook para sa mga repositoryo at authorized_keys ng mano-mano. Kinukumpirma mo na sisiguraduhin mo na tama ang mga setting ng repositoryo at mirror.
+reinstall_confirm_message = Ang pag-install muli na may umiiral na Forgejo database ay maaaring magdulot ng mga problema. Sa karamihan ng mga kaso, dapat mong gamitin ang iyong umiiral na "app.ini" para patakbuhin ang Forgejo. Kung alam mo ang ginagawa mo, kumpirmahin ang mga sumusunod:
+reinstall_confirm_check_1 = Ang data na naka-encrypt sa pamamagitan ng SECRET_KEY sa app.ini ay maaaring mawala: baka hindi maka-log in ang mga user gamit ng 2FA/OTP at ang mga mirror ay maaaring hindi gumana mg maayos. Sa pamamagitan ng pag-check ng box na ito kinukumpirma mo na ang kasalukuyang app.ini file ay naglalaman ng tamang SECRET_KEY.
+reinstall_confirm_check_2 = Ang mga repositoryo at mga setting ay maaaring kailangang i-resynchronize. Sa pamamagitan ng pag-check ng box na ito kinukumprima mo na ire-resynchronize mo ang mga hook para sa mga repositoryo at authorized_keys ng mano-mano. Kinukumpirma mo na sisiguraduhin mo na tama ang mga setting ng repositoryo at mirror.
err_admin_name_pattern_not_allowed = Hindi angkop ang username ng tagapangasiwa, ang username ay tumutugma sa reserved pattern
ssh_port_helper = Numero ng port na gagamitin ng SSH server. Iwanang walang laman para i-disable ang SSH server.
server_service_title = Mga setting ng server at third-party na serbisyo
@@ -348,6 +354,18 @@ buttons.list.ordered.tooltip = Magdagdag ng nakanumerong listahan
buttons.ref.tooltip = Magsangguni ng isyu o pull request
buttons.switch_to_legacy.tooltip = Gamitin ang legacy editor sa halip
buttons.heading.tooltip = Magdagdag ng heading
+buttons.indent.tooltip = Isama ang mga item nang isang level
+buttons.unindent.tooltip = I-unnest ang mga item nang isang level
+table_modal.placeholder.header = Header
+buttons.new_table.tooltip = Magdagdag ng table
+table_modal.placeholder.content = Nilalaman
+table_modal.header = Magdagdag ng table
+table_modal.label.rows = Mga Row
+table_modal.label.columns = Mga Column
+link_modal.header = Magdagdag ng link
+link_modal.url = Url
+link_modal.description = Deskripsyon
+link_modal.paste_reminder = Pahiwatig: Kapag may URL sa clipboard, maari mong direktang i-paste sa editor para gumawa ng link.
[filter]
string.asc = A - Z
@@ -357,12 +375,12 @@ string.desc = Z - A
app_desc = Isang hindi masakit, at naka self-host na Git service
install = Madaling i-install
platform = Cross-platform
-platform_desc = Tumatakbo kahit saan ang Forgejo na ang Go ay nakaka-compile para sa: Windows, macOS, Linux, ARM, atbp. Piliin ang isa na gusto mo!
+platform_desc = Kinumpirma na tumatakbo ang Forgejo sa mga libreng operating system tulad ng Linux at FreeBSD, at pati na rin sa mga iba't ibang CPU architechture. Pumili nang isa na gusto mo!
lightweight = Magaan
lightweight_desc = Mababa ang minimal requirements ng Forgejo at tatakbo sa isang murang Raspberry Pi. Tipirin ang enerhiya ng iyong machine!
license = Open Source
-install_desc = Patakbuhin ang binary para sa iyong platform, i-ship gamit ang Docker , o kunin ito nang naka-package .
-license_desc = Kunin ang Forgejo ! Sumali ka sa pamamagitan ng pag-contribute para gawing mas mahusay ang proyekto. Wag kang mahiya para maging isang contributor!
+install_desc = Patakbuhin lang ang binary para sa iyong platform, i-ship gamit ang Docker , o kunin ito nang naka-package .
+license_desc = Kunin ang Forgejo ! Sumali ka sa pamamagitan ng pag-contribute para gawing mas mahusay ang proyekto. Wag kang mahiya para maging isang contributor!
[auth]
create_new_account = Magrehistro ng account
@@ -377,11 +395,11 @@ sign_up_now = Kailangan ng isang account? Magrehistro ngayon.
sign_up_successful = Matagumpay na nagawa ang account. Maligayang pagdating!
must_change_password = Baguhin ang iyong password
allow_password_change = Kailanganin ang user na palitan ang password (inirerekomenda)
-reset_password_mail_sent_prompt = Ang isang bagong email pang-kumpirma ay ipinadala sa %s . Pakisuri ang iyong inbox sa loob ng %s para tapusin ang proseso ng pag-recover ng account.
+reset_password_mail_sent_prompt = Ang isang bagong email na pang-kumpirma ay ipinadala sa %s . Para kumpletuhin ang proseso ng pag-recover ng account, pakisuri ang iyong inbox at sundan ang ibinigay na link sa loob ng %s.
active_your_account = Aktibahin ang iyong account
account_activated = Naaktiba na ang account
-prohibit_login = Ipinagbawalan ang Pag-sign in
-prohibit_login_desc = Pinagbawalan ang iyong account sa pag-sign in, mangyaring makipag-ugnayan sa tagapangasiwa ng site.
+prohibit_login = Nasuspinde ang account
+prohibit_login_desc = Nasuspinde ang iyong account sa pakikipag-ugnayan sa instansya. Makipag-ugnayan sa tagapangasiwa ng instansya upang makakuha muli ng access.
resent_limit_prompt = Humiling ka na ng activation email kamakailan. Mangyaring maghintay ng 3 minuto at subukang muli.
change_unconfirmed_email_summary = Palitan ang email address kung saan ipapadala ang activation email.
change_unconfirmed_email = Kung nagbigay ka ng maling email address habang nagpaparehistro, pwede mong palitan sa ibaba, at ang isang kumpirmasyon ay ipapadala sa bagong address sa halip.
@@ -399,7 +417,7 @@ scratch_code = Scratch code
use_scratch_code = Gumamit ng scratch code
twofa_passcode_incorrect = Mali ang iyong passcode. Kung nawala mo ang iyong device, gamitin ang iyong scratch code para mag-sign in.
twofa_scratch_token_incorrect = Mali ang iyong scratch code.
-login_userpass = Mag-Sign In
+login_userpass = Mag-sign in
login_openid = OpenID
oauth_signup_tab = Mag-rehistro ng bagong account
oauth_signup_title = Kumpletuhin ang bagong account
@@ -414,7 +432,7 @@ openid_connect_desc = Ang piniling OpenID URI ay hindi alam. Iugnay iyan sa bago
invalid_code = Ang iyong confirmation code ay hindi wasto o nag-expire na.
oauth_signin_title = Mag-sign in para pahintulutan ang naka-link na account
invalid_code_forgot_password = Ang iyong confirmation code ay hindi wasto o nag-expire na. Mag-click dito para magsimula ng bagong session.
-confirmation_mail_sent_prompt = Ang isang bagong email pang-kumpirma ay ipinadala sa %s . Pakisuri ang iyong inbox sa loob ng %s para tapusin ang proseso ng pagrehistro. Kung mali ang email, maari kang mag-log in, at humingi ng isa pang email pang-kumpirma na ipapadala sa ibang address.
+confirmation_mail_sent_prompt = Ang isang bagong email na pang-kumpirma ay ipinadala sa %s . Para kumpletuhin ang proseso ng pagrehistro, pakisuri ang iyong inbox at sundan ang ibinigay na link sa loob ng %s. Kung mali ang email, maari kang mag-log in, at humingi ng isa pang email pang-kumpirma na ipapadala sa ibang address.
invalid_password = Ang iyong password ay hindi tugma sa password na ginamit para gawin ang account.
twofa_scratch_used = Ginamit mo na ang scratch code. Na-redirect ka sa two-factor settings page para tanggalin ang device enrollment o mag-generate ng bagong scratch code.
manual_activation_only = Makipag-ugnayan sa tagapangangasiwa ng site para kumpletuhin ang pagrehistro.
@@ -435,12 +453,19 @@ authorize_title = Pahintulutan ang "%s" na i-access ang iyong account?
authorization_failed = Nabigo ang awtorisasyon
authorization_failed_desc = Nabigo ang awtorisasyon dahil may na-detect kami ng hindi angkop na hiling. Mangyaring makipag-ugnayan sa maintainer ng app na sinusubukan mong pahintulutan.
sspi_auth_failed = Nabigo ang SSPI authentication
-password_pwned = Ang pinili mong password ay nasa listahan ng mga ninakaw na password na kasalukuyang napakita sa mga publikong data breach. Mangyaring subukang muli gamit ng ibang password at isaalang-alang palitan din ang password sa ibang lugar.
+password_pwned = Ang pinili mong password ay nasa listahan ng mga ninakaw na password na dating napakita sa mga publikong data breach. Mangyaring subukang muli gamit ng ibang password at isaalang-alang palitan din ang password sa ibang lugar.
password_pwned_err = Hindi makumpleto ang request sa HaveIBeenPwned
last_admin = Hindi mo matatanggal ang pinakahuling admin. Kailangan may hindi bababa sa isang admin.
tab_signin = Mag-sign In
tab_signup = Mag-sign Up
tab_openid = OpenID
+hint_register = Kailangan ng account? Magrehistro ngayon.
+sign_up_button = Magrehistro ngayon.
+back_to_sign_in = Bumalik sa sign in
+sign_in_openid = Magpatuloy gamit ang OpenID
+hint_login = May account ka na? Mag-sign in ngayon!
+unauthorized_credentials = Mali o nag-expire na ang mga kredensyal. Ulitin ang iyong command o tignan ang %s para sa higit pang impormasyon
+use_onetime_code = Gumamit ng isang-beses na code
[mail]
reply = o direktang tumugon sa email na ito
@@ -456,7 +481,7 @@ activate_email = I-verify ang iyong email address
admin.new_user.subject = Nag-sign up lang ngayon ang user na si %s
admin.new_user.user_info = Impormasyon ng user
admin.new_user.text = Mangyaring mag-click dito para ipamahala ang user na ito sa admin panel.
-register_notify = Maligayang Pagdating sa Forgejo
+register_notify = Maligayang Pagdating sa %s
register_notify.title = %[1]s, maligayang pagdating sa %[2]s
register_notify.text_1 = ito ang iyong registration confirmation email para sa %s!
register_notify.text_2 = Maari kang mag-sign in sa iyong account gamit ng iyong username: %s
@@ -466,7 +491,7 @@ reset_password.text = Kung ikaw ito, paki-click ang sumusunod na link para i-rec
register_success = Matagumpay ang pag-rehistro
issue_assigned.issue = Itinalaga ka ni @%[1]s sa isyu na %[2]s sa repositoryo na %[3]s.
issue.x_mentioned_you = Binanggit ka ni %s :
-issue.action.force_push = Na-force push ni/ng %[1]s ang %[2]s mula %[3]s sa %[4]s.
+issue.action.force_push = Pwersahang itinulak ni/ng %[1]s ang %[2]s mula %[3]s sa %[4]s.
issue.action.push_n = Nag-push si @%[1]s ng %[3]d (mga) commit sa %[2]s
issue.action.close = Sinara ni @%[1]s ang #%[2]d.
issue.action.reopen = Binuksan muli ni @%[1]s ang #%[2]d.
@@ -482,13 +507,13 @@ release.download.zip = Source Code (ZIP)
release.download.targz = Source Code (TAR.GZ)
repo.transfer.subject_to_you = Gusto ilipat ni %s ang repositoryo na "%s" sa iyo
repo.transfer.to_you = ikaw
-repo.transfer.body = Para tanggapin o tanggihan bisitahin ang %s o huwag na lang pansinin.
-repo.collaborator.added.subject = Idinagdag ka ni %s sa %s bilang tagaambag
+repo.transfer.body = Para tanggapin o tanggihan bisitahin ang %s o huwag na lang ito pansinin.
+repo.collaborator.added.subject = Idinagdag ka ni %s sa %s bilang katulong
team_invite.subject = Inimbitahan ka ni %[1]s para sumali sa organisasyong %[2]s
team_invite.text_1 = Inimbitahan ka ni %[1]s para sumali sa koponang %[2]s sa organisasyong %[3]s.
team_invite.text_2 = Mangyaring i-click ang sumusunod na link para sumali sa koponan:
activate_email.text = Mangyaring i-click ang sumusunod na link para i-verify ang iyong email address sa loob ng %s :
-repo.collaborator.added.text = Idinagdag ka bilang tagaambag sa repositoryo:
+repo.collaborator.added.text = Idinagdag ka bilang tagatulong sa repositoryo:
activate_email.title = %s, paki-verify ang iyong email address
issue.action.reject = Humingi ng mga pagbabago si @%[1]s sa pull request na ito.
activate_account.title = %s, paki-activate ang iyong account
@@ -499,6 +524,22 @@ issue.action.ready_for_review = Minarkahan ni @%[1]s ang pull request na
release.new.text = Inilabas ni @%[1]s ang %[2]s sa %[3]s
repo.transfer.subject_to = Gusto ni %s na ilipat ang repositoryo na "%s" sa %s
team_invite.text_3 = Tandaan: Ang imbitasyong ito ay inilaan para sa %[1]s. Kung hindi mo inaasahan ang imbitasyong ito, maaari mong balewalain ang email na ito.
+removed_security_key.no_2fa = Wala nang mga ibang paraan ng 2FA ang naka-configure, nangangahulugan na hindi na kailangang mag-log in sa iyong account gamit ang 2FA.
+reset_password.text_1 = Ngayon lang napalitan ang password ng iyong account.
+password_change.subject = Napalitan ang iyong password
+primary_mail_change.text_1 = Ngayon lang napalitan ang iyong pangunahing mail sa %[1]s. Nangangahulugan ito na ang e-mail address na ito ay hindi na makakatanggap ng mga abiso sa e-mail para sa iyong account.
+password_change.text_1 = Ngayon lang napalitan ang password ng iyong account.
+primary_mail_change.subject = Napalitan ang iyong pangunahing mail
+totp_disabled.subject = Na-disable ang TOTP
+totp_disabled.text_1 = Ngayon lang na-disable ang Time-based one-time password (TOTP) sa iyong account.
+totp_disabled.no_2fa = Wala nang mga ibang paraan ng 2FA ang naka-configure, nangangahulugan na hindi na kailangang mag-log in sa iyong account gamit ang 2FA.
+removed_security_key.subject = May tinanggal na security key
+removed_security_key.text_1 = Tinanggal ngayon lang ang security key na "%[1]s" sa iyong account.
+account_security_caution.text_1 = Kung ikaw ito, maari mong ligtas na huwag pansinin ang mail na ito.
+account_security_caution.text_2 = Kung hindi ito ikaw, nakompromiso ang iyong account. Mangyaring makipag-ugnayan sa mga tagapangasiwa ng site na ito.
+totp_enrolled.subject = Nag-activate ka ng TOTP bilang paraan ng 2FA
+totp_enrolled.text_1.has_webauthn = Na-enable mo lang ang TOTP para sa iyong account. Nangangahulugan ito na para sa lahat ng mga hinaharap na pag-login sa iyong account, kailangan mong gumamit ng TOTP bilang paraan ng 2FA o gamitin ang iyong mga security key.
+totp_enrolled.text_1.no_webauthn = Na-enable mo lang ang TOTP para sa iyong account. Nangangahulugan ito na para sa lahat ng mga hinaharap na pag-login sa iyong account, kailangan mong gumamit ng TOTP bilang paraan ng 2FA.
[modal]
yes = Oo
@@ -515,7 +556,7 @@ Password = Password
Retype = Kumpirmahin ang password
SSHTitle = Pangalan ng SSH key
HttpsUrl = HTTPS URL
-PayloadUrl = Payload URL
+PayloadUrl = URL ng payload
TeamName = Pangalan ng koponan
AuthName = Pangalan ng awtorisasyon
AdminEmail = Admin email
@@ -528,7 +569,7 @@ SSPISeparatorReplacement = Pang-hiwalay
SSPIDefaultLanguage = Default na wika
CommitSummary = Pangkalahatang-ideya ng commit
glob_pattern_error = ` hindi angkop ang glob pattern: %s`
-require_error = ` hindi maaring walang laman.`
+require_error = ` hindi maaaring walang laman.`
alpha_dash_error = ` dapat maglaman lamang ng alphanumeric, dash ("-") at underscore ("_") na mga character.`
alpha_dash_dot_error = ` dapat maglaman lamang ng alphanumeric, dash ("-"), underscore ("_") at tuldok (".") na mga character.`
git_ref_name_error = ` dapat na mahusay na nabuong pangalan ng Git reference`
@@ -576,8 +617,8 @@ unset_password = Hindi nagtakda ng password ang login user.
unsupported_login_type = Hindi sinusuportahan ang uri ng pag-login para burahin ang account.
user_not_exist = Hindi umiiral ang user.
team_not_exist = Hindi umiiral ang koponan.
-last_org_owner = Hindi mo maaring tanggalin ang pinakahuling user sa "mga may-ari" na koponan. Kailangan may kahit isang may-ari para sa organisasyon.
-cannot_add_org_to_team = Hindi maaring madagdag ang isang organisasyon bilang miyembro ng koponan.
+last_org_owner = Hindi mo maaaring tanggalin ang pinakahuling user sa "mga may-ari" na koponan. Kailangan may kahit isang may-ari para sa organisasyon.
+cannot_add_org_to_team = Hindi maaaring madagdag ang isang organisasyon bilang miyembro ng koponan.
duplicate_invite_to_team = Inimbita na ang user bilang miyembro ng koponan.
organization_leave_success = Matagumpay kang umalis sa organisasyon na %s.
invalid_ssh_key = Hindi ma-verify ang iyong SSH key: %s
@@ -592,7 +633,7 @@ still_own_packages = Ang iyong account ay nagmamay-ari ng isa o higit pang packa
org_still_own_repo = Ang organisasyon na ito ay nagmamay-ari ng isa o higit pang mga repositoryo, burahin o ilipat sila muna.
org_still_own_packages = Ang organisasyon na ito ay nagmamay-ari ng isa o higit pang mga package, burahin sila muna.
target_branch_not_exist = Hindi umiiral ang target branch.
-admin_cannot_delete_self = Hindi mo maaring burahin ang sarili mo kapag isa kang tagapangasiwa. Paki-tanggal ang iyong pribilehiyong tagapangasiwa muna.
+admin_cannot_delete_self = Hindi mo maaaring burahin ang sarili mo kapag isa kang tagapangasiwa. Paki-tanggal ang iyong pribilehiyong tagapangasiwa muna.
required_prefix = Ang input ay dapat magsimula sa "%s"
FullName = Buong pangalan
Description = Paglalarawan
@@ -602,19 +643,22 @@ To = Pangalan ng branch
AccessToken = Token ng pag-access
Biography = Byograpya
Location = Lokasyon
+visit_rate_limit = Natugunan ang limitasyon sa rate ng malayuang pagbisita.
+username_claiming_cooldown = Hindi ma-claim ang username na ito, dahil hindi pa tapos ang panahon ng cooldown. Maari itong i-claim sa %[1]s.
+email_domain_is_not_allowed = Sumasalungat ang domain ng email address ng user %s sa EMAIL_DOMAIN_ALLOWLIST o EMAIL_DOMAIN_BLOCKLIST. Siguraduhing natakda mo ang email address nang tama.
[user]
joined_on = Sumali noong %s
repositories = Mga Repositoryo
activity = Pampublikong aktibidad
followers_few = %d mga tagasunod
-block_user = I-block ang user
+block_user = Harangan ang user
change_avatar = Palitan ang iyong avatarโฆ
-block_user.detail = Pakitandaan na ang pag-block ng isang user ay may iba pang mga epekto, gaya ng:
+block_user.detail = Pakitandaan na ang pagharang ng isang user ay may iba pang mga epekto, gaya ng:
block_user.detail_1 = Hihinto kayo sa pagsunod sa isa't isa at hindi na kayo makakasunod sa isa't isa.
block_user.detail_2 = Hindi magagawa ng user na ito na makipag-ugnayan sa mga repositoryo na minamamay-ari mo, o sa mga isyu at komentong ginawa mo.
block_user.detail_3 = Hindi mo magagawang idagdag ang isa't isa bilang mga tagatulong ng repositoryo.
-follow_blocked_user = Hindi mo mapa-follow ang user na ito dahil na-block mo ang user na ito o na-block ka ng user na ito.
+follow_blocked_user = Hindi mo masusundan ang user na ito dahil hinarangan mo ang user na ito o hinarangan ka ng user na ito.
starred = Mga naka-bituin na repositoryo
watched = Mga sinusubaybayan na repositoryo
code = Code
@@ -640,6 +684,11 @@ following.title.few = Sinusundan
followers.title.few = Mga tagasunod
following.title.one = Sinusundan
followers.title.one = Tagasunod
+public_activity.visibility_hint.self_public = Nakikita ng lahat ang iyong aktibidad, maliban sa mga interaksyon sa pribadong espasyo. I-configure .
+public_activity.visibility_hint.admin_public = Nakikita ng lahat ang aktibidad na ito, ngunit bilang tagapangasiwa maari mo ring makita ang mga interaksyon sa mga pribadong espasyo.
+public_activity.visibility_hint.self_private = Nakikita mo lang at mga tagapangasiwa ng instansya ang iyong aktibidad. I-configure .
+public_activity.visibility_hint.admin_private = Nakikita mo ang aktibidad na ito dahil isa kang tagapangasiwa, ngunit gusto ng user na panatilihin itong pribado.
+public_activity.visibility_hint.self_private_profile = Ikaw lang at ang mga tagapangasiwa ng instansya ang makakakita ng iyong aktibidad dahil pribado ang iyong profile. I-configure .
[settings]
profile = Profile
@@ -657,7 +706,7 @@ twofa = Authentikasyong two-factor (TOTP)
account_link = Mga naka-link na account
uid = UID
webauthn = Authentikasyong two-factor (Mga security key)
-blocked_users = Mga na-block na user
+blocked_users = Mga hinarang na user
public_profile = Pampublikong Profile
location_placeholder = Ibahagi ang iyong tinatayang lokasyon sa iba
password_username_disabled = Ang mga di-lokal na gumagamit ay hindi pinapayagan na baguhin ang kanilang username. Mangyaring makipag-ugnayan sa iyong tagapangasiwa ng site para sa higit pang mga detalye.
@@ -702,10 +751,10 @@ delete_current_avatar = Burahin ang kasalukuyang avatar
uploaded_avatar_not_a_image = Ang na-upload na file ay hindi isang larawan.
comment_type_group_assignee = Mangangasiwa
social = Mga social account
-biography_placeholder = Sabihin sa amin ng kaunti tungkol sa iyong sarili! (Maaari mong gamitin ang Markdown)
+biography_placeholder = Sabihin sa iba ng kaunti tungkol sa iyong sarili! (Sinusuportahan ang Markdown)
change_username_prompt = Tandaan: Ang pagpalit ng username ay papalitan din ang URL ng iyong account.
organization = Mga Organisasyon
-profile_desc = Kontrolin kung paano ipinapakita ang iyong profile sa ibang mga gumagamit. Ang iyong pangunahing email address ay gagamitin para sa mga abiso, pagbawi ng password at mga Git operation na batay sa web.
+profile_desc = Tungkol sa iyo
hidden_comment_types_description = Ang mga uri ng komento na naka-check dito ay hindi ipapakita sa loob ng mga pahina ng isyu. Halimbawa ang pag-check ng "Label" ay tatanggalin lahat ng mga "Idinagdag/tinanggal ni ang " na komento.
comment_type_group_milestone = Milestone
comment_type_group_issue_ref = Pagsangguni ng isyu
@@ -715,23 +764,23 @@ email_deletion_desc = Ang email address at mga kaugnay na impormasyon ay tatangg
add_email = Idagdag ang email eddress
gpg_token_code = echo "%s" | gpg -a --default-key %s --detach-sig
delete_token_success = Nabura na ang token. Ang mga application na gumagamit nito ay hindi na maa-access ang iyong account.
-add_email_confirmation_sent = Ang isang email pang-kumpirma ay ipinadala sa %s. Pakisuri ang iyong inbox sa loob ng %s para kumpirmahin ang iyong email address.
+add_email_confirmation_sent = Ang isang email na pang-kumpirma ay ipinadala sa %s. Para kumpirmahin ang iyong email address, pakisuri ang iyong inbox at sundan ang ibinigay na link sa loob ng %s.
key_content_ssh_placeholder = Nagsisimula sa "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", o "sk-ssh-ed25519@openssh.com"
-gpg_key_verified_long = Na-verify ang key na ito gamit ng isang token at maaring gamitin para i-verify ang mga commit na tumutugma sa anumang mga naka-activate na email address para sa user na ito kasama ang mga tumutugmang pagkakakilanlan para sa key na ito.
-ssh_key_verified_long = Ang key na ito ay na-verify gamit ng isang token at maaring gamitin para i-verify ang mga commit na tumutugma na email address para sa user na ito.
+gpg_key_verified_long = Na-verify ang key na ito gamit ng isang token at maaaring gamitin para i-verify ang mga commit na tumutugma sa anumang mga naka-activate na email address para sa user na ito kasama ang mga tumutugmang pagkakakilanlan para sa key na ito.
+ssh_key_verified_long = Ang key na ito ay na-verify gamit ng isang token at maaaring gamitin para i-verify ang mga commit na tumutugma na email address para sa user na ito.
add_principal_success = Idinagdag na ang SSH certificate principal na "%s".
ssh_key_deletion_desc = Ang pagtanggal ng SSH key ay matatanggihan ang pag-access sa iyong account. Magpatuloy?
no_activity = Walang kamakilang aktibidad
ssh_signonly = Kasalukuyang naka-disable ang SSH kaya magagamit lang ang mga key na ito para sa pagpapatunay ng commit signature.
gpg_desc = Ang mga pampublikong GPG key dito ay nauugnay sa iyong account at ginagamit para i-verify ang iyong mga commit. Panatilihing ligtas ang iyong mga pribadong key dahil pinapayagan nito ang pag-sign ng mga commit gamit ng iyong pagkakakilanlan.
-keep_email_private_popup = Itatago nito ang iyong email address sa iyong profile, at kung gumawa ka ng pull request o mag-edit ng file sa pamamagitan ng web interface. Hindi babaguhin ang mga naka-push na commit. Gamitin ang %s sa mga commit para i-associate sila sa iyong account.
+keep_email_private_popup = Ang iyong email address ay hindi ipapakita sa iyong profile at hindi magiging default para sa mga commit na ginawa sa pamamagitan ng web interface, tulad ng pag-upload ng mga file, mga pagbabago, at mga merge commit. Sa halip, gagamitin ang isang espeyal na address na %s para i-link ang mga commit sa iyong account. Ang opsyon na ito ay hindi makakaapekto sa mga umiiral na commit.
gpg_key_id_used = Ang isang publikong GPG key na may katulad na ID ay umiiral na.
gpg_no_key_email_found = Ang GPG key na ito ay hindi tumutugma sa anumang email address na nauugnay sa iyong account. Madadagdag pa rin ito kapag i-sign mo ang ibinigay na token.
ssh_principal_deletion_success = Tinanggal na ang principal.
principal_state_desc = Ginamit ang principal na ito sa huling 7 araw
tokens_desc = Ang mga token na ito ay nagbibigay ng pag-access sa iyong account gamit ang Forgejo API.
generate_token_name_duplicate = Ginamit na ang %s bilang isang pangalan ng application. Gumamit ng bago.
-access_token_desc = Ang mga piniling pahintulot sa token ay nililimitahan ang awtorisasyon sa mga kakulang na API route. Basahin ang dokumentasyon para sa higit pang impormasyon.
+access_token_desc = Ang mga piniling pahintulot sa token ay nililimitahan ang awtorisasyon sa mga kakulang na API route. Basahin ang dokumentasyon para sa higit pang impormasyon.
uploaded_avatar_is_too_big = Ang laki ng na-upload na file (%d KiB) ay lumalagpas sa pinakamalaking laki (%d KiB).
update_avatar_success = Nabago na ang iyong avatar.
update_user_avatar_success = Nabago na ang avatar ng user.
@@ -741,14 +790,14 @@ old_password = Kasalukuyang password
new_password = Bagong password
retype_new_password = Kumpirmahin ang bagong password
password_incorrect = Mali ang kasalukuyang password.
-change_password_success = Na-update na ang iyong password. Mag-sign in gamit ng bagong password simula ngayon.
+change_password_success = Na-update na ang iyong password. Simula ngayon, gamitin ang iyong bagong password para mag-sign in.
password_change_disabled = Hindi mababago ng mga di-lokal na gumagamit ang kanilang password sa pamamagitan ng Forgejo web interface.
emails = Mga email address
manage_emails = Ipamahala ang mga email address
manage_themes = Default na tema
manage_openid = Mga OpenID address
email_desc = Ang iyong pangunahing email address ay gagamitin para sa mga notification, pag-recover ng password at, kung hindi tinago, mga Git operation na batay sa web.
-theme_desc = Ito ang iyong magiging default na tema sa buong site.
+theme_desc = Gagamitin ang tema na ito sa web interface kapag naka-log in ka.
primary = Panguna
activated = Naka-activate
requires_activation = Nangangailangan ng activation
@@ -777,7 +826,7 @@ keep_email_private = Itago ang email address
openid_desc = Hinahayaan ka ng OpenID na mag-delegate ng pagpapatunay sa isang panlabas na tagabigay ng serbisyo.
ssh_desc = Ang mga pampublikong SSH key na ito ay nauugnay sa iyong account. Pinapayagan ng kaukulang pribadong key ang buong pag-access sa iyong mga repositoryo. Ang mga SSH key na na-verify ay maaaring magamit upang mapatunayan ang mga naka-sign na Git commit sa pamamagitan ng SSH.
principal_desc = Ang mga SSH principal na ito ay nauugnay sa iyong account at pinapayagan ang buong pag-access sa iyong mga repositoryo.
-ssh_helper = Kailangan ng tulong? Tignan ang guide sa paggawa ng sarili mong mga SSH key o ilutas ang mga karaniwang problema na maaring moong matagpo gamit ng SSH.
+ssh_helper = Kailangan ng tulong? Tignan ang guide sa paggawa ng sarili mong mga SSH key o ilutas ang mga karaniwang problema na maaaring moong matagpo gamit ng SSH.
gpg_helper = Kailangan ng tulong? Tignan ang guide tungkol sa GPG .
add_new_key = Magdagdag ng SSH key
add_new_gpg_key = Magdagdag ng GPG key
@@ -787,7 +836,7 @@ ssh_key_been_used = Idinagdag na ang SSH key na ito sa server.
ssh_key_name_used = Ang isang SSH key na may katulad na pangalan ay umiiral na sa iyong account.
ssh_principal_been_used = Idinagdag na ang principal na ito sa server.
gpg_key_matched_identities = Mga Tumutugma na Pagkakakilanlan:
-gpg_key_matched_identities_long = Ang mga naka-embed na pagkakakilanlan sa key na ito ay tumutugma sa mga sumusunod na naka-activate na email address para sa user na ito. Ang mga commit na tumutugma sa mga email address na ito ay maaring i-verify gamit ng key na ito.
+gpg_key_matched_identities_long = Ang mga naka-embed na pagkakakilanlan sa key na ito ay tumutugma sa mga sumusunod na naka-activate na email address para sa user na ito. Ang mga commit na tumutugma sa mga email address na ito ay maaaring i-verify gamit ng key na ito.
gpg_key_verified = Naka-verify na key
gpg_key_verify = I-verify
gpg_invalid_token_signature = Ang ibinigay na GPG key, signature, at token ay hindi tumutugma o luma.
@@ -866,7 +915,7 @@ twofa_scratch_token_regenerated = Ang iyong isang-beses na paggamit na recovery
regenerate_scratch_token_desc = Kapag nawala mo ang iyong recovery key o ginamit mo na oara mag-sign in, maari mong i-reset dito.
twofa_disable_desc = Ang pag-disable ng authentikasyong two-factor ay gagawing hindi gaanong ligtas ang iyong account. Magpatuloy?
twofa_enrolled = Matagumpay na na-enroll ang iyong account. Ilagay ang iyong isang-beses na paggamit na recovery key (%s) sa isang ligtas na lugar, dahil hindi na ito ipapakita muli.
-webauthn_desc = Ang mga security key ay isang hardware device na naglalaman ng mga cryptographic key. Maari silang gamitin para sa authentikasyong two-factor. Ang mga security key ay dapat suportahan ang WebAuthn Authenticator na standard.
+webauthn_desc = Ang mga security key ay isang hardware device na naglalaman ng mga cryptographic key. Maari silang gamitin para sa authentikasyong two-factor. Ang mga security key ay dapat suportahan ang WebAuthn Authenticator na standard.
remove_oauth2_application = Tanggalin ang OAuth2 Application
remove_oauth2_application_desc = Ang pagtanggal ng OAuth2 application ay babawiin ang access sa lahat ng mga naka-sign na access token. Magpatuloy?
remove_oauth2_application_success = Binura na ang application.
@@ -909,7 +958,7 @@ visibility.public = Publiko
email_notifications.enable = I-enable ang mga email notification
email_notifications.onmention = Mag-email lamang kapag nabanggit
repos_none = Hindi ka nagmamay-ari ng anumang mga repositoryo.
-blocked_users_none = Walang mga na-block na user.
+blocked_users_none = Walang mga hinarangan na user.
authorized_oauth2_applications = Mga pinahintulutang OAuth2 application
authorized_oauth2_applications_description = Pinayagan mo ang pag-access ng iyong personal na Forgejo account sa mga third-party na application na ito. Mangyaring bawiin ang access para sa mga application na hindi mo na ginagamit.
revoke_key = Bawiin
@@ -927,23 +976,23 @@ remove_account_link = Tanggalin ang naka-link na account
visibility.limited = Limitado
visibility.private = Pribado
visibility.private_tooltip = Makikita lang ng mga miyembro ng mga organisasyon na sinali mo
-blocked_since = Na-block noong %s
-user_block_success = Matagumpay na na-block ang user.
+blocked_since = Hinarangan noong %s
+user_block_success = Matagumpay na hinarang ang user.
user_unblock_success = Matagumpay na na-unblock ang user.
oauth2_application_remove_description = Ang pagtanggal ng isang OAuth2 application ay ipipipigil ito ang pag-access ng mga awtorisadong account sa instansya na ito. Magpatuloy?
webauthn_register_key = Magdagdag ng security key
remove_account_link_success = Tinanggal na ang naka-link na account.
-visibility.limited_tooltip = Makikita lamang ng mga naka-authenticate na user
+visibility.limited_tooltip = Makikita lamang ng mga naka-sign in na user
webauthn_delete_key_desc = Kapag magtanggal ka ng security key hindi ka na makaka-sign in gamit niyan. Magpatuloy?
manage_account_links_desc = Ang mga panlabas na account na ito ay naka-link sa iyong Forgejo account.
hooks.desc = Magdagdag ng mga webhook na mati-trigger para sa lahat ng mga repositoryo na minamay-ari mo.
orgs_none = Hindi ka isang miyembro ng anumang mga organisasyon.
oauth2_application_create_description = Ang mga OAuth2 application ay pinapayagan ang mga third-party na aplikasyon na i-access ang mga user account sa instansya na ito.
-oauth2_application_locked = Ang Forgejo ay pini-pre register ang ibang mga OAuth2 application sa startup kapag naka-enable sa config. Para iwasan ang hindi inaasahang gawain, hindi ito maaring i-edit o tanggalin. Mangyaring sumangguni sa dokumentasyon ng OAuth2 para sa karagdagang impormasyon.
+oauth2_application_locked = Ang Forgejo ay pini-pre register ang ibang mga OAuth2 application sa startup kapag naka-enable sa config. Para iwasan ang hindi inaasahang gawain, hindi ito maaaring i-edit o tanggalin. Mangyaring sumangguni sa dokumentasyon ng OAuth2 para sa karagdagang impormasyon.
remove_account_link_desc = Ang pagtanggal ng naka-link na account ay babawiin ang pag-access nito sa iyong Forgejo account. Magpatuloy?
visibility.public_tooltip = Makikita ng lahat
hints = Mga Pahiwatig
-additional_repo_units_hint_description = Magpakita ng "Magdagdag pa ng mga unit..." na button para sa mga repositoryo na hindi naka-enable ang lahat ng mga available na unit.
+additional_repo_units_hint_description = Magpakita ng "Magdagdag ng higit pa" na button para sa mga repositoryo na hindi naka-enable ang lahat ng mga available na unit.
additional_repo_units_hint = Imungkahi na i-enable ng karagdagang mga unit ng repositoryo
update_hints = I-update ang mga pahiwatig
update_hints_success = Na-update na ang mga pahiwatig.
@@ -951,24 +1000,57 @@ pronouns_custom = Pasadya
pronouns_unspecified = Hindi natakda
pronouns = Mga panghalip
language.title = Default na wika
+keep_activity_private.description = Makikita mo lang at mga tagapangasiwa ng instansya ang iyong pampublikong aktibidad .
+language.description = Mase-save ang wika sa iyong account at gagamitin bilang default pagkatapos mong mag-log in.
+language.localization_project = Tulungan kaming isalin ang Forgejo sa iyong wika! Matuto pa .
+pronouns_custom_label = Mga pasadyang pronoun
+user_block_yourself = Hindi mo maaaring harangan ang sarili mo.
+change_username_redirect_prompt.with_cooldown.one = Magiging available ang lumang username sa lahat pagkatapos ng panahon ng cooldown ng %[1]d araw, maari mo pa ring ma-claim muli ang lumang username sa panahon ng panahon ng cooldown.
+change_username_redirect_prompt.with_cooldown.few = Magiging available ang lumang username sa lahat pagkatapos ng panahon ng cooldown ng %[1]d araw, maari mo pa ring ma-claim muli ang lumang username sa panahon ng panahon ng cooldown.
+keep_pronouns_private = Ipakita lang ang mga panghalip sa mga naka-authenticate na user
+keep_pronouns_private.description = Itatago nito ang iyong mga panghalip mula sa mga bisita na hindi naka-log in.
+quota.applies_to_user = Nag-aapply ang mga sumusunod na panuntunan ng quota sa iyong account
+quota.sizes.assets.attachments.issues = Mga attachment sa isyu
+quota.applies_to_org = Ang mga sumusunod na panuntunan sa quota ay nalalapat sa organisasyong ito
+storage_overview = Buod ng Storage
+quota = Quota
+quota.rule.exceeded = Nalampasan
+quota.rule.exceeded.helper = Ang kabuuang sukat ng mga bagay para sa panuntunang ito ay lumampas sa quota.
+quota.rule.no_limit = Walang limitasyon
+quota.sizes.all = Lahat
+quota.sizes.repos.all = Mga repositoryo
+quota.sizes.repos.public = Mga pampublikong repositoryo
+quota.sizes.repos.private = Mga pribadong repositoryo
+quota.sizes.git.all = Nilalaman ng Git
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.all = Mga asset
+quota.sizes.assets.attachments.all = Mga attachment
+quota.sizes.assets.attachments.releases = Mga attachment sa release
+quota.sizes.assets.artifacts = Mga artifact
+quota.sizes.assets.packages.all = Mga package
+quota.sizes.wiki = Wiki
+access_token_regeneration = I-regenerate ang access token
+regenerate_token = I-regenerate
+access_token_regeneration_desc = Ang pag-regenerate ng token ay babawiin ang access sa iyong account para sa mga application na gumagamit nito. Hindi ito mababawi. Magpatuloy?
+regenerate_token_success = Na-generate muli ang token. Ang mga application na gumagamit nito ay hindi na maa-access ang iyong account at dapat ma-update gamit ang bagong token.
[repo]
template_description = Ang mga template na repositoryo ay pinapayagan ang mga gumagamit na mag-generate ng mga bagong repositoryo na may magkatulad na istraktura ng direktoryo, mga file, at opsyonal na mga setting.
clone_helper = Kailangan ng tulong sa pagpili? Bisitahin ang Tulong .
admin.failed_to_replace_flags = Nabigong palitan ang mga flag ng repositoryo
rss.must_be_on_branch = Kailangang nasa branch ka para magkaroon ng RSS feed.
-new_repo_helper = Ang isang repositoryo ay naglalaman ng lahat ng file ng proyekto, kasama ang kasaysayan ng rebisyon. Nagho-host ka na sa ibang lugar? Mag-migrate ng repositoryo
+new_repo_helper = Ang isang repositoryo ay naglalaman ng lahat ng file ng proyekto, kasama ang kasaysayan ng rebisyon. Nagho-host ka na sa ibang lugar? Mag-migrate ng repositoryo .
admin.manage_flags = Ipamahala ang mga flag
admin.enabled_flags = Mga flag na naka-enable para sa repositoryo:
admin.update_flags = I-update ang mga flag
admin.flags_replaced = Napalitan ang mga flag ng repositoryo
owner = May-ari
-owner_helper = Maaring hindi mapapakita ang ibang organisasyon sa dropdown dahil sa pinakamataas na bilang ng repositoryo na limitasyon.
+owner_helper = Maaaring hindi mapapakita ang ibang organisasyon sa dropdown dahil sa pinakamataas na bilang ng repositoryo na limitasyon.
repo_name = Pangalan ng repositoryo
repo_name_helper = Ang mga magandang pangalan ng repositoryo ay gumagamit ng maliit, makakaalala, at unique na mga keyword.
repo_size = Laki ng Repositoryo
template = Template
-template_select = Pumili ng template.
+template_select = Pumili ng template
template_helper = Gawing template ang repositoryo
visibility = Kakayahang pagpakita
visibility_description = Ang owner o ang mga miyembro ng organisasyon kung may karapatan sila, ay makakakita nito.
@@ -979,20 +1061,20 @@ fork_repo = I-fork ang repositoryo
fork_from = I-fork mula sa
already_forked = Na-fork mo na ang %s
fork_to_different_account = Mag-fork sa ibang account
-fork_visibility_helper = Ang visibility ng isang naka-fork na repositoryo ay hindi maaring baguhin.
+fork_visibility_helper = Ang visibility ng isang naka-fork na repositoryo ay hindi maaaring baguhin.
open_with_editor = Buksan gamit ang %s
download_bundle = I-download ang BUNDLE
repo_gitignore_helper_desc = Piliin kung anong mga file na hindi susubaybayin sa listahan ng mga template para sa mga karaniwang wika. Ang mga tipikal na artifact na ginagawa ng mga build tool ng wika ay kasama sa .gitignore ng default.
adopt_preexisting = Mag-adopt ng mga umiiral na file
-repo_gitignore_helper = Pumili ng mga .gitignore template.
+repo_gitignore_helper = Pumili ng mga .gitignore template
readme_helper_desc = Ito ang lugar kung saan makakasulat ka ng kumpletong deskripsyon para sa iyong proyekto.
trust_model_helper_collaborator_committer = Katulong+Committer: I-trust ang mga signature batay sa mga katulong na tumutugma sa committer
mirror_interval = Interval ng mirror (ang mga wastong unit ng oras ay "h", "m", "s"). 0 para i-disable ang periodic sync. (Pinakamababang interval: %s)
transfer.reject_desc = Kanselahin ang pag-transfer mula sa "%s"
mirror_lfs_endpoint_desc = Ang sync ay susubukang gamitin ang clone url upang matukoy ang LFS server . Maari ka rin tumukoy ng isang custom na endpoint kapag ang LFS data ng repositoryo ay nilalagay sa ibang lugar.
-adopt_search = Ilagay ang username para maghanap ng mga unadopted na repositoryo... (iwanang walang laman para hanapin lahat)
+adopt_search = Ilagay ang username para maghanap ng mga unadopted na repositoryoโฆ (iwanang walang laman para hanapin lahat)
object_format = Format ng object
-readme_helper = Pumili ng README file template.
+readme_helper = Pumili ng README file template
default_branch_helper = Ang default branch ay ang base branch para sa mga pull request at mga commit ng code.
mirror_interval_invalid = Hindi wasto ang mirror interval.
mirror_sync = na-sync
@@ -1014,17 +1096,17 @@ fork_no_valid_owners = Hindi mapo-fork ang repositoryo dahil walang mga wastong
use_template = Gamitin ang template na ito
download_zip = I-download ang ZIP
download_tar = I-download ang TAR.GZ
-issue_labels = Mga label ng isyu
+issue_labels = Mga label
generate_repo = I-generate ang repositoryo
repo_desc_helper = Maglagay ng maikling deskripsyon (opsyonal)
repo_lang = Wika
-issue_labels_helper = Pumili ng label set ng isyu.
+issue_labels_helper = Pumili ng label set ng isyu
license = Lisensya
-license_helper = Pumili ng file ng lisensya.
-license_helper_desc = Ang lisensya ay namamahala kung ano ang pwede at hindi pwedeng gawin ng mga ibang tao sa iyong code. Hindi sigurado kung alin ang wasto para sa iyong proyekto? Tignan ang Pumili ng lisensya.
+license_helper = Pumili ng file ng lisensya
+license_helper_desc = Ang lisensya ay namamahala kung ano ang pwede at hindi pwedeng gawin ng mga ibang tao sa iyong code. Hindi sigurado kung alin ang wasto para sa iyong proyekto? Tignan ang Pumili ng lisensya .
object_format_helper = Object format ng repositoryo. Hindi mababago mamaya. Ang SHA1 ang pinaka-compatible.
readme = README
-auto_init = I-initialize ang repositoryo (Nagdadagdag ng .gitignore, Lisensya, at README)
+auto_init = I-initialize ang repositoryo
trust_model_helper = Pumili ng trust model para sa signature verification. Ang mga posibleng opsyon ay:
trust_model_helper_collaborator = Katulong: I-trust ang mga signature batay sa mga katulong
trust_model_helper_committer = Commiter: I-trust ang mga signature na tumutugma sa mga commiter
@@ -1035,7 +1117,7 @@ mirror_prune = Pungusan
mirror_prune_desc = Tanggalin ang mga antikuwado na sangguni ng remote-tracking
mirror_address_url_invalid = Ang ibinigay na url ay hindi wasto. Kailangan mong i-escape ang lahat ng mga components ng URL ng tama.
mirror_address_protocol_invalid = Ang ibinigay na URL ay hindi wasto. Ang http(s):// o git:// na lokasyon lamang ay magagamit para sa pag-mirror.
-mirror_lfs = Large File Storage (LFS)
+mirror_lfs = Imbakan ng Malaking File (LFS)
mirror_lfs_desc = I-activate ang pag-mirror ng LFS data.
mirror_lfs_endpoint = Endpoint ng LFS
mirror_last_synced = Huling na-synchronize
@@ -1057,14 +1139,14 @@ transfer.no_permission_to_reject = Wala kang pahintulot para tanggihan ang palil
desc.private = Pribado
desc.public = Publiko
desc.template = Template
-desc.internal = Internal
+desc.internal = Panloob
template.git_hooks = Mga hook ng Git
delete_preexisting_label = Burahin
stars = Mga bitwin
migrate_options_mirror_helper = Magiging salamin ang repositoryong ito
migrate_options_lfs_endpoint.description.local = Sinusuporta rin ang lokal na server path.
editor.this_file_locked = Nakakandado ang file
-editor.filename_cannot_be_empty = Hindi maaring walang laman ang pangalan ng file.
+editor.filename_cannot_be_empty = Hindi maaaring walang laman ang pangalan ng file.
commits.message = Mensahe
commits.newer = Mas bago
commits.date = Petsa
@@ -1075,15 +1157,15 @@ editor.preview_changes = I-preview ang mga pagbago
editor.edit_this_file = Baguhin ang file
commits.author = May-akda
commits.older = Mas luma
-editor.add_tmpl = Idagdag ang ""
+editor.add_tmpl = Idagdag ang "<%s>"
delete_preexisting = Burahin ang mga dating umiiral na file
delete_preexisting_content = Burahin ang mga file sa %s
tree_path_not_found_commit = Hindi umiiral ang path na %[1]s sa commit %[2]s
tree_path_not_found_branch = Hindi umiiral ang daanang %[1]s sa branch %[2]s
-migrate_items_pullrequests = Mga hiling sa pagtulak
-archive.pull.nocomment = Naka-archive ang repo na ito. Hindi ka makakakomento sa mga pull request.
-archive.title = Naka-archive ang repo na ito. Maari mong itignan ang mga file at i-clone ito, pero hindi makaka-push o magbukas ng mga isyu o mga pull request.
-archive.title_date = Naka-archive ang repositoryo na ito noong %s. Maari mong itignan ang mga file at i-clone ito, pero hindi makaka-push o magbukas ng mga isyu o mga pull request.
+migrate_items_pullrequests = Mga hiling sa paghila
+archive.pull.nocomment = Naka-archive ang repositoryong ito. Hindi ka makakakomento sa mga pull request.
+archive.title = Naka-archive ang repositoryong ito. Maari mong itignan ang mga file at i-clone ito, pero hindi ka makakagawa ng anumang pagbabago sa estado ito, tulad ng pagtulak at paggawa ng mga isyu, pull request o mga komento.
+archive.title_date = Naka-archive ang repositoryo na ito noong %s. Maari mong itignan ang mga file at i-clone ito, pero hindi ka makakagawa ng anumang pagbabago sa estado nito, tulad ng pagtulak o paggawa ng mga bagong isyu, mga pull request, o komento.
pulls = Mga hiling sa paghila
activity.merged_prs_count_n = Mga naisamang hiling sa paghila
wiki.last_updated = Huling binago %s
@@ -1110,7 +1192,7 @@ editor.file_delete_success = Nabura na ang file na "%s".
tree = Puno
issues.filter_sort = Isaayos ayon sa
activity.title.issues_closed_from = Sinara ang %s mula sa %s
-pulls.merged_success = Matagumpay na naisama at sinara ang [pull request]
+pulls.merged_success = Matagumpay na naisama at sinara ang hiling sa paghila
activity.title.prs_merged_by = Sinama ang %s ni/ng %s
find_tag = Maghanap ng tag
issues.label.filter_sort.reverse_by_size = Pinakamalaki
@@ -1121,7 +1203,7 @@ template.avatar = Avatar
migrate_options = Mga opsyon sa paglipat
migrate.clone_address_desc = Ang HTTP(S) o Git "clone" URL ng umiiral na repositoryo
need_auth = Awtorisasyon
-migrate.github_token_desc = Maari kang maglagay ng isa o higit pang mga token na hinihiwalay ng kuwit dito upang gawing mas-mabilis ang pagmigrate dahil sa rate limit ng GitHub API. BABALA: Ang pagabuso ng feature na ito ay maaring maglabag sa patakaran ng tagapagbigay ng serbisyo at maaring magdulot ng pag-block ng account.
+migrate.github_token_desc = Maaari kang maglagay ng isa o higit pang mga token na hinihiwalay ng kuwit dito upang gawing mas-mabilis ang pagmigrate dahil sa rate limit ng GitHub API. BABALA: Ang pagabuso ng feature na ito ay maaaring maglabag sa patakaran ng tagapagbigay ng serbisyo at maaaring magdulot ng pag-block ng account.
template.invalid = Kailangang pumili ng kahit isang template na repositoryo
migrate_options_lfs_endpoint.description = Susubukan ng migration na gamitin ang iyong Git remote upang matukoy ang LFS server . Maari mong magtiyak ng custom na endpoint kapag ang LFS data ng repositoryo ay nakalagay sa ibang lugar.
blame.ignore_revs.failed = Nabigong hindi pansinin ang mga rebisyon sa .git-blame-ignore-revs .
@@ -1138,7 +1220,7 @@ migrate_items_labels = Mga label
migrate_items_issues = Mga isyu
migrate_items_merge_requests = Mga merge request
migrate.clone_address = Magmigrate / Mag-clone mula sa URL
-archive.issue.nocomment = Naka-archive ang repo na ito. Hindi ka makakakomento sa mga isyu.
+archive.issue.nocomment = Naka-archive ang repositoryong ito. Hindi ka makakakomento sa mga isyu.
migrate_items = Mga item sa pagmigrate
migrate_items_releases = Mga paglabas
migrate_repo = I-migrate ang repositoryo
@@ -1154,7 +1236,7 @@ adopt_preexisting_success = Pinagtibay ang mga file at ginawa ang repositoryo mu
delete_preexisting_success = Burahin ang mga hindi pinatibay na file sa %s
blame_prior = Tignan ang blame bago ang pagbabago na ito
migrate.permission_denied = Hindi ka pinapayagang mag-import ng mga lokal na repositoryo.
-migrate.permission_denied_blocked = Hindi ka maaring mag-import mula sa mga hindi pinapayagang host, magyaring magtanong sa pangangasiwa na suriin ang ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS na mga setting.
+migrate.permission_denied_blocked = Hindi ka maaaring mag-import mula sa mga hindi pinapayagang host, magyaring magtanong sa pangangasiwa na suriin ang ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS na mga setting.
migrate.invalid_local_path = Hindi wasto ang lokal na path. Hindi ito umiiral o hindi isang direktoryo.
migrate.invalid_lfs_endpoint = Hindi wasto ang LFS endpoint.
migrate.migrating_failed = Nabigo ang pag-migrate mula sa %s .
@@ -1203,13 +1285,13 @@ file_follow = Sundan ang symlink
file_view_source = Tignan ang source
file_view_rendered = Tignan ng naka-render
ambiguous_runes_header = `Naglalaman ng file na ito ng mga hindi tiyak na Unicode character`
-ambiguous_runes_description = `Ang file na ito ay naglalaman ng mga Unicode character na maaring malilito sa ibang mga character. Kung sa tingin mo ay sinasadya ito, maari mong ligtas na hindi pansinin ang babala ito. Gamitin ang I-escape na button para ipakita sila.`
+ambiguous_runes_description = `Ang file na ito ay naglalaman ng mga Unicode character na maaaring malilito sa ibang mga character. Kung sa tingin mo ay sinasadya ito, maaari mong ligtas na hindi pansinin ang babala ito. Gamitin ang I-escape na button para ipakita sila.`
file_copy_permalink = Kopyahin ang permalink
view_git_blame = Tignan ang git blame
video_not_supported_in_browser = Hindi sinusuportahan ng inyong browser ang HTML5 "video" tag.
audio_not_supported_in_browser = Hindi sinusuportahan ng inyong browser ang HTML5 "audio" tag.
stored_lfs = Nilagay gamit ng Git LFS
-symbolic_link = Symbolic link
+symbolic_link = Symbolic na link
executable_file = Executable na file
generated = Na-generate
commit_graph = Graph ng commit
@@ -1218,7 +1300,7 @@ commit_graph.monochrome = Mono
commit_graph.color = Kulay
commit.contained_in = Ang commit na ito ay nakalagay sa:
commit.load_referencing_branches_and_tags = I-load ang mga branch at tag na sumasangguni sa commit na ito
-blame = Blame
+blame = I-blame
download_file = I-download ang file
normal_view = Normal na Paningin
line = linya
@@ -1233,7 +1315,7 @@ broken_message = Ang Git data na pinagbabatayan sa repositoryo na ito ay hindi m
file_history = Kasaysayan
invisible_runes_header = `Nalalaman ng file na ito ng mga hindi nakikitang Unicode character`
file_too_large = Masyadong malaki ang file para ipakita.
-invisible_runes_description = `Ang file na ito ay naglalaman ng mga hindi nakikitang Unicode character na hindi nakikilala ng mga tao ngunit maaring maproseso ng ibang paraan ng isang computer. Kung sa tingin mo ay sinasadya ito, maari mong ligtas na hindi pansinin ang babala na ito. Gamitin ang I-escape na button para ipakita sila.`
+invisible_runes_description = `Ang file na ito ay naglalaman ng mga hindi nakikitang Unicode character na hindi nakikilala ng mga tao ngunit maaaring maproseso ng ibang paraan ng isang computer. Kung sa tingin mo ay sinasadya ito, maaari mong ligtas na hindi pansinin ang babala na ito. Gamitin ang I-escape na button para ipakita sila.`
commit.contained_in_default_branch = Ang commit na ito ay bahagi ng default na branch
migrate.migrating_labels = Nililipat ang mga label
filter_branch_and_tag = I-filter ang branch o tag
@@ -1261,13 +1343,13 @@ migrated_from_fake = Na-migrate mula sa %[1]s
migrate.migrate = Magmigrate mula sa %s
migrate.failed = Nabigo ang migration: %v
migrate.migrate_items_options = Kinakailangan ang token sa pag-access para i-migrate ang mga karagdagang item
-migrate.migrating = Nagma-migrate mula sa %s ...
+migrate.migrating = Nagma-migrate mula sa %s โฆ
quick_guide = Mabilis na gabay
clone_this_repo = I-clone ang repositoryo na ito
cite_this_repo = Banggitin ang repositoryo na ito
create_new_repo_command = Paggawa ng bagong repositoryo sa command line
code = Code
-ambiguous_character = `Ang %[1]c [U+%04[1]X] ay maaring malito sa %[2]c [U+%04[2]X]`
+ambiguous_character = `Ang %[1]c [U+%04[1]X] ay maaaring malito sa %[2]c [U+%04[2]X]`
escape_control_characters = I-escape
unescape_control_characters = I-unescape
invisible_runes_line = `Ang linya na ito ay may mga hindi nakikitang Unicode character`
@@ -1281,14 +1363,14 @@ editor.must_be_on_a_branch = Dapat nasa branch ka upang gumawa o magmunkahi ng m
editor.new_branch_name_desc = Bagong pangalan ng branchโฆ
editor.cancel = Kanselahin
issues.role.member = Miyembro
-issues.remove_request_review_block = Hindi maaring tanggalin ang hiling sa pagsuri
+issues.remove_request_review_block = Hindi maaaring tanggalin ang hiling sa pagsuri
issues.edit = Baguhin
issues.cancel = Kanselahin
issues.save = IImbak
issues.label_title = Pangalan
issues.delete.title = Burahin ang isyung ito?
-settings.pulls_desc = Paganahin ang mga hiling sa paghatak para sa repositoryo
-editor.branch_does_not_exist = Walang natagpuang [branch] na "%s" sa [repository] na ito.
+settings.pulls_desc = Paganahin ang mga hiling sa paghila para sa repositoryo
+editor.branch_does_not_exist = Walang natagpuang branch na "%s" sa repositoryo na ito.
commits.nothing_to_compare = Magkapareho ang mga branch na ito.
commits.search_all = Lahat na mga branch
editor.file_deleting_no_longer_exists = Walang natagpuang binuburang file na "%s" sa repositoryo na ito.
@@ -1301,7 +1383,7 @@ issues.re_request_review = Hilingin muli ang pagsusuri
issues.lock.reason = Dahilan sa pagkandado
issues.action_close = Isara
issues.label_description = Paglalarawan
-find_file.go_to_file = "Pumunta sa file"
+find_file.go_to_file = Hanapin ang isang file
projects.deletion = Burahin ang proyekto
issues.filter_project_all = Lahat ng mga proyekto
issues.filter_project_none = Walang proyekto
@@ -1320,7 +1402,7 @@ issues.context.edit = I-edit
issues.lock.title = Kandaduhin ang paguusap sa isyung ito.
issues.unlock.title = I-unlock ang paguusap sa isyung ito.
pulls.nothing_to_compare_and_allow_empty_pr = Magkapareho ang mga branch na ito. Magiging walang laman ang PR na ito.
-pulls.has_pull_request =
+pulls.has_pull_request =`Mayroon nang pull request sa pagitan ng mga branch na ito: %[2]s#%[3]d `
issues.delete = Burahin
issues.choose.open_external_link = Buksan
issues.deleted_project = `(binura)`
@@ -1331,7 +1413,7 @@ issues.filter_type.assigned_to_you = Itinalaga sa iyo
issues.filter_type.all_issues = Lahat ng mga isyu
issues.author_helper = May-akda ang tagagamit na ito.
issues.role.owner = May-ari
-activity.title.prs_n = %d mga kahilingan sa paghatak
+activity.title.prs_n = %d mga kahilingan sa paghila
issues.label_color = Kulay
pulls.nothing_to_compare = Magkapareho ang mga branch na ito. Hindi na kailangang gumawa ng hiling sa paghila.
projects.column.assigned_to = Itinalaga sa/kay
@@ -1393,9 +1475,9 @@ pulls.reopened_at = `nabuksang muli ang hiling sa paghatak na %[2]s `
-pulls.reopen_failed.head_branch = Hindi mabuksang muli ang [pull request] na ito dahil nabura ang punong [branch].
+pulls.reopen_failed.head_branch = Hindi mabubuksan muli ang hiling sa paghila, dahil hindi na umiiral ang head branch.
settings.event_pull_request_desc = Binuksan, sinara, muling binuksan, o binago ang hiling sa paghatak.
-activity.opened_prs_count_n = Mga inimungkahing hiling sa paghatak
+activity.opened_prs_count_n = Mga inimungkahing hiling sa paghila
editor.filename_is_invalid = Hindi wasto ang pangalan ng file: "%s".
activity.title.prs_opened_by = %s inimungkahi ni/ng %s
pulls.cant_reopen_deleted_branch = Hindi mabuksang muli ang hiling sa paghatak na ito dahil nabura ang branch.
@@ -1426,12 +1508,12 @@ milestones.close = Isara
wiki.save_page = IImbak ang pahina
wiki.page = Pahina
wiki.page_content = Nilalaman ng pahina
-wiki.new_page = Bagong pahina
+wiki.new_page = Pahina
wiki.page_title = Pamagat ng pahina
issues.lock_confirm = Kandaduhin
issues.stop_tracking_history = `itinigil ang trabaho %s`
issues.label_delete = Burahin
-milestones.closed = Isinara %s
+milestones.closed = Isinara ang %s
issues.unlock_confirm = I-unlock
milestones.open = Buksan
issues.content_history.delete_from_history = Burahin mula sa kasaysayan
@@ -1442,9 +1524,9 @@ wiki.new_page_button = Bagong pahina
wiki.delete_page_button = Burahin ang pahina
milestones.title = Pamagat
milestones.desc = paglalarawan
-pulls.blocked_by_user = Hindi ka makakagawa ng [pull request] sa [repository] na ito dahil hinarang ka ng may-ari ng [repository].
-pulls.no_merge_access = Hindi ka pinapayagang isali ang [pull request] na ito.
-editor.commit_directly_to_this_branch = Direktang mag-commit sa branch na %s .
+pulls.blocked_by_user = Hindi ka makakagawa ng hiling sa paghila sa repositoryo na ito dahil hinarang ka ng may-ari ng repositoryo.
+pulls.no_merge_access = Hindi ka pinapayagang isali ang hiling sa paghila na ito.
+editor.commit_directly_to_this_branch = Direktang mag-commit sa branch na %[1]s .
editor.branch_already_exists = Umiiral na ang branch na "%s" sa repositoryo na ito.
editor.file_editing_no_longer_exists = Ang file na ine-edit, "%s", ay hindi na umiiral sa repositoryo na ito.
editor.filename_is_a_directory = Ang pangalan ng file "%s" ay ginagamit na bilang pangalan ng direktoryo sa repositoryo na ito.
@@ -1453,21 +1535,21 @@ editor.directory_is_a_file = Ang pangalan ng direktoryo "%s" ay ginagamit na bil
pulls.merged_by =ni/ng %[3]s ay naisama %[1]s
commitstatus.pending = Nakabinbin
issues.review.pending = Nakabinbin
-pulls.status_checking = Nakabinbin ang ilang mga [pagsusuri]
-editor.file_changed_while_editing = Ang nilalaman ng file ay nagbago mula noong nagsimula kang mag-edit. Mag-click dito upang makita ang mga pagbabago o Mag-commit ng mga pagbabago muli para i-overwrite sila.
+pulls.status_checking = Nakabinbin ang ilang mga pagsusuri
+editor.file_changed_while_editing = Ang nilalaman ng file ay nagbago mula noong binuksan mo ang file. Mag-click dito upang makita ang mga pagbabago o Mag-commit ng mga pagbabago muli para i-overwrite sila.
editor.file_already_exists = Umiiral na ang file na may pangalang "%s" sa repositoryong ito.
issues.review.review = Suriin
activity.git_stats_push_to_branch = sa %s at
activity.git_stats_and_deletions = at
issues.new.no_projects = Walang mga proyekto
-pulls.auto_merge_button_when_succeed = (Kung nagtagumpay ang mga [check])
+pulls.auto_merge_button_when_succeed = (Kung magtagumpay ang mga pagsusuri)
activity.git_stats_on_default_branch = Sa %s,
activity.period.quarterly = 3 buwan
issues.review.left_comment = nagiwan ang komento
pulls.compare_base = isama sa
activity.git_stats_additions = at mayroong
-issues.reopen_comment_issue = Magkomento at buksang muli
-issues.close_comment_issue = Magkomento at isara
+issues.reopen_comment_issue = Buksan muli ng may komento
+issues.close_comment_issue = Isara ng may komento
pulls.compare_compare = hilain mula sa
pulls.waiting_count_n = %d mga hinihintay na pagsusuri
pulls.waiting_count_1 = %d hinihintay na pagsusuri
@@ -1485,14 +1567,14 @@ settings.transfer_perform = Gawin ang paglipat
settings.transfer_abort = Ipagpaliban ang paglipat
settings.transfer_owner = Bagong may-ari
pulls.tab_conversation = Pag-uusap
-pulls.tab_files = Nabagong mga file
+pulls.tab_files = Mga nabagong file
settings.new_owner_blocked_doer = Hinarang ka ng bagong may-ari.
-settings.transfer.rejected = Tinanggihan ang paglipat ng [repository].
-settings.transfer.success = Matagumpay na inilipat ang [repository].
-settings.transfer.modal.title = Ilipat ang [ownership]
+settings.transfer.rejected = Tinanggihan ang paglipat ng repositoryo.
+settings.transfer.success = Matagumpay na inilipat ang repositoryo.
+settings.transfer.modal.title = Ilipat ang pagmamay-ari
diff.view_file = Tingnan ang file
diff.parent =magulang
-diff.stats_desc = %d nabagong mga file na may %d mga pagdagdag at %d mga pagtanggal
+diff.stats_desc = %d nabagong mga file na may %d mga pagdagdag at %d mga pagtanggal
commits.commits = Mga commit
commits.ssh_key_fingerprint = Fingerprint ng SSH key
commits.signed_by_untrusted_user_unmatched = Nilagdaan ng hindi pinagkakatiwalaan na user na hindi tumutugma sa taga-commit
@@ -1533,7 +1615,7 @@ editor.cherry_pick = I-cherry-pick ang %s sa:
commits.search_branch = Itong branch
commits.browse_further = Higit pang mag-browse
commits.renamed_from = Na-rename mula sa %s
-ext_issues = Access sa mga external na isyu
+ext_issues = Mga panlabas na isyu
ext_issues.desc = Mag-link sa external na issue tracker.
projects.new_subheader = I-coordinate, subaybayan, at i-update ang iyong trabaho sa isang lugar, para manatiling transparent at nasa iskedyul ang mga proyekto.
projects.edit_subheader = Inaayos ng mga proyekto ang mga isyu at sinusubaybayan ang pag-unlad.
@@ -1546,13 +1628,13 @@ projects.column.new_title = Pangalan
projects.card_type.desc = Mga preview ng card
commits.desc = I-browse ang history ng pagbabago ng source code.
commits.search.tooltip = Maari kang mag-prefix ng mga keyword gamit ang "author:", "committer:", "after:", o "before:", hal. "revert author:Nijika before:2022-10-09".
-issues.force_push_codes = `puwersahang itinulak ang %[1]s mula %[2]s
sa %[4]s
%[6]s`
+issues.force_push_codes = `puwersahang itinulak ang %[1]s mula %[2]s
sa %[4]s
%[6]s`
issues.push_commit_1 = idinagdag ang %d commit %s
-issues.push_commits_n = idinagdag ang %d mga [commit] %s
+issues.push_commits_n = idinagdag ang %d mga commit %s
issues.new.no_reviewers = Walang mga tagasuri
-pulls.title_desc_one = hinihiling na isama ang %[1]d [commit] mula %[2]s
patungong %[3]s
-pulls.title_desc_few = hiniling na isama ang %[1]d mga [commit] mula sa %[2]s
patungong %[3]s
-issues.review.add_review_request = hiniling ang pagsuri mula kay %s %s
+pulls.title_desc_one = hinihiling na isama ang %[1]d commit mula %[2]s
patungong %[3]s
+pulls.title_desc_few = hiniling na isama ang %[1]d mga commit mula sa %[2]s
patungong %[3]s
+issues.review.add_review_request = hiniling ang pagsuri mula kay %[1]s %[2]s
pulls.status_checks_details = Mga detalye
activity.git_stats_author_n = %d mga may-akda
issues.change_title_at = `binago ang pamagat mula %s sa %s %s`
@@ -1560,22 +1642,22 @@ activity.git_stats_author_1 = %d may-akda
diff.review.header = Isumite ang pagsusuri
issues.review.comment = sinuri ang %s
pulls.approve_count_1 = %d pag-apruba
-pulls.viewed_files_label = %[1]d / %[2]d tinitingnang mga file
+pulls.viewed_files_label = %[1]d / %[2]d mga tinignang file
pulls.approve_count_n = %d mga pag-apruba
-pulls.push_rejected = Nabigo ang pagtulak: Tinatanggi ang pagtulak. Suriin ang [Git hooks] para sa [repositoryong] ito.
+pulls.push_rejected = Nabigo ang pagtulak: Tinatanggi ang pagtulak. Suriin ang mga Git hook para sa repositoryong ito.
diff.review.reject = Hilingin ang mga pagbago
diff.whitespace_show_everything = Ipakita lahat ng pagbago
issues.review.approve = inaprubahan ang mga pagbabagong ito %s
-diff.review.approve = Aprubahin
-settings.event_pull_request_review_desc = Inapruba, tinatanggihan o [komento ng pagsuri] ang [pull request].
-settings.event_pull_request_review = Sinusuri na ang [pull request]
-diff.whitespace_button = Puting espasyo
-diff.review.self_reject = Hindi makakahiling ng nga pagbago ang mga may-akda ng [pull request] sa kanilang sariling [pull request]
-diff.review.self_approve = Hindi maka-apruba ang mga may-akda ng [pull request] sa kanilang sariling [pull request]
-pulls.has_viewed_file = Tinitingnan na
+diff.review.approve = Aprubahan
+settings.event_pull_request_review_desc = Inapruba, tinatanggihan o gumawa ng komento sa pagsuri sa hiling sa paghila.
+settings.event_pull_request_review = Mga pagsusuri
+diff.whitespace_button = Whitespace
+diff.review.self_reject = Hindi makakahiling ng nga pagbago ang mga may-akda ng hiling sa pahila sa kanilang sariling hiling sa paghila
+diff.review.self_approve = Hindi maka-apruba ang mga may-akda ng hiling sa paghila sa kanilang sariling hiling sa paghila
+pulls.has_viewed_file = Tinignan na
diff.review.placeholder = Komento ng pagsusuri
diff.review = Tapusin ang pagsusuri
-pulls.push_rejected_no_message = Nabigo ang pagtulak: Tinatanggi ang pagtulak ngunit walang [remote] mensahe doon. Suriin ang [Git hooks] para sa [repositoriyong] ito
+pulls.push_rejected_no_message = Nabigo ang pagtulak: Tinatanggi ang pagtulak ngunit walang remote na mensahe doon. Suriin ang mga Git hook para sa repositoryong ito
pulls.reject_count_1 = %d hiling sa pagbago
pulls.reject_count_n = %d mga hiling sa pagbago
projects.desc = Ipamahala ang mga isyu at mga paghila sa mga board ng proyekto.
@@ -1661,7 +1743,7 @@ issues.filter_milestone_all = Lahat ng mga milestone
issues.filter_sort.mostforks = Pinakamaraming fork
issues.action_assignee = Mangangasiwa
issues.change_ref_at = `binago ang sangguni mula %s sa %s %s`
-pulls.cmd_instruction_merge_desc = Isama ang mga pagbago at [update] sa Forgejo.
+pulls.cmd_instruction_merge_desc = Isama ang mga pagbago at i-update sa Forgejo.
issues.dependency.issue_close_blocks = Hinarangan ng isyung ito mula sa pagsara ng mga sumusunod na isyu
issues.dependency.issue_closing_blockedby = Hinarangan mula sa pagsara ng isyung ito ng mga sumusunod na isyu
pulls.status_checks_requested = Kinakailangan
@@ -1682,7 +1764,7 @@ issues.label_exclusive_desc = Pangalanan ang label na scope/item
up
issues.archived_label_description = (Naka-archive) %s
issues.label.filter_sort.alphabetically = Ayon sa alpabeto
issues.subscribe = Mag-subscribe
-issues.max_pinned = Hindi ka maaring mag-pin ng higit pang mga isyu
+issues.max_pinned = Hindi ka maaaring mag-pin ng higit pang mga isyu
issues.pin_comment = na-pin ito %s
issues.unpin_comment = na-unpin ito %s
issues.lock = I-lock ang usapan
@@ -1708,7 +1790,7 @@ issues.lock.notice_1 = - Hindi makakadagdag ng mga bagong komento ang mga ibang
issues.lock.notice_3 = - Maari mong i-unlock muli ang isyung ito sa hinaharap.
issues.label_deletion_desc = Ang pagbura ng label ay tatanggalin ito sa lahat ng mga isyu. Magpatuloy?
issues.commit_ref_at = `isinangguni ang isyu na ito mula sa commit %[2]s `
-issues.ref_issue_from = `isinangguni ang isyu na ito %[4]s %[2]s `
+issues.ref_issue_from = `isinangguni ang isyu na ito sa %[4]s %[2]s `
issues.num_participants_one = %d kasali
issues.attachment.download = `I-click para i-download ang "%s" `
issues.num_participants_few = %d mga kasali
@@ -1719,12 +1801,12 @@ issues.label_modify = I-edit ang label
issues.label_deletion_success = Binura na ang label.
issues.role.collaborator = Tagatulong
issues.role.collaborator_helper = Inimbita ang user na ito na makipagtulungan sa repositoryo.
-issues.role.contributor = Contributor
+issues.role.contributor = Kontribyutor
issues.create_comment = Magkomento
issues.closed_by = ni/ng %[3]s ay isinara %[1]s
issues.context.quote_reply = Mag-quote reply
issues.context.copy_link = Kopyahin ang link
-issues.label_exclusive = Exclusive
+issues.label_exclusive = Eksklusibo
issues.label_archived_filter = Ipakita ang mga naka-archive na label
issues.label.filter_sort.reverse_alphabetically = Ayon sa alpabeto pabaliktad
issues.attachment.open_tab = `I-click para itignan ang "%s" sa bagong tab`
@@ -1733,39 +1815,39 @@ issues.sign_in_require_desc = Mag-sign in upang sumali sa usapa
issues.num_comments = %d mga komento
issues.role.contributor_helper = Nakaraang nag-commit ang user na ito sa repositoryo na ito.
issues.comment_pull_merged_at = isinama ang commit %[1]s sa %[2]s %[3]s
-pulls.commit_ref_at = ` isinangguni ang [pull request] mula sa isang [commit]%[2]s `
+pulls.commit_ref_at = `isinangguni ang hiling sa paghila mula sa isang commit %[2]s `
wiki.last_commit_info = Binago ni %s ang pahinang ito %s
issues.content_history.edited = binago
issues.ref_pull_from = `isinangguni ang hiling sa paghila na ito %[4]s %[2]s `
-pulls.merged_title_desc_few = isinali ang %[1]d mga [commit] mula sa %[2]s
patungong %[3]s
%[4]s
-settings.org_not_allowed_to_be_collaborator = Hindi maaring idagdag ang mga organizasyon bilang tagaambag.
-settings.add_collaborator_success = Naidagdag na ang tagaambag.
-settings.federation_following_repos = Mga [URL] ng mga sinusundang mga repositoryo. Hinihiwalay ng ";", walang puting espasyo.
+pulls.merged_title_desc_few = isinali ang %[1]d mga commit mula sa %[2]s
patungong %[3]s
%[4]s
+settings.org_not_allowed_to_be_collaborator = Hindi maaaring idagdag ang mga organisasyon bilang tagatulong.
+settings.add_collaborator_success = Naidagdag ang tagatulong.
+settings.federation_following_repos = Mga URL ng Mga Sinusundang Repositoryo. Hinihiwalay ng ";", walang whitespace.
diff.comment.reply = Tumugon
-pulls.create = Gumawa ng [pull request]
-issues.dependency.pr_close_blocked = Kailangan mong isara ang lahat ng mga isyu na humaharang sa [pull request] na ito bago mo ito isama.
-pulls.delete.title = Burahin ang [pull request] na ito?
+pulls.create = Gumawa ng hiling sa paghila
+issues.dependency.pr_close_blocked = Kailangan mong isara ang lahat ng mga isyu na humaharang sa hiling sa paghila na ito bago mo ito isama.
+pulls.delete.title = Burahin ang hiling sa paghila na ito?
issues.dependency.pr_closing_blockedby = Hinarang ng mga sumusunod na isyu mula sa pagsara ng hiling sa paghila na ito
-pulls.closed_at = `isinara ang [pull request] na ito%[2]s `
-pulls.close = Isara ang [pull request]
-pulls.cmd_instruction_hint = `Tingnan ang mga panuto para sa linya ng utos .`
+pulls.closed_at = `isinara ang hiling sa paghila na %[2]s `
+pulls.close = Isara ang hiling sa paghila
+pulls.cmd_instruction_hint = Tingnan ang mga panuto para sa command line
project = Mga proyekto
issues.content_history.deleted = binura
-pulls.no_results = Walang nakitang mga resulta.
-pulls.closed = Sarado ang [pull request]
-pulls.is_closed = Naisara na ang [pull request].
-issues.ref_closing_from = `isinangguni ang hiling sa paghila %[4]s na magsasara sa isyung ito %[2]s `
-issues.ref_reopening_from = `isinangguni ang hiling sa paghila %[4]s na muling bubukas sa isyung ito %[2]s `
+pulls.no_results = Walang mga nahanap na resulta.
+pulls.closed = Sarado ang hiling sa paghila
+pulls.is_closed = Naisara na ang hiling sa paghila.
+issues.ref_closing_from = `nagsangguni ang isyu mula sa hiling sa paghila %[4]s na magsasara sa isyu , %[2]s `
+issues.ref_reopening_from = `nagsangguni ang isyu na ito mula sa hiling sa paghila %[4]s na muling bubukas , %[2]s `
issues.ref_closed_from = `isinara ang isyung ito %[4]s %[2]s `
issues.review.wait = hiniling sa pagsuri %s
issues.review.reject = hinihiling ang mga pagbago %s
-issues.review.remove_review_request = tinatanggal ang hiling sa pagsuri para sa/kay %s %s
-pulls.reopen_to_merge = Mangyaring buksan muli ang [pull request] upang gawin ang pagsali.
-pulls.merged_title_desc_one = isinali ang %[1]d [commit] mula%[2]s
patungong %[3]s
%[4]s
+issues.review.remove_review_request = tinatanggal ang hiling sa pagsuri para sa/kay %[1]s %[2]s
+pulls.reopen_to_merge = Mangyaring buksan muli ang hiling sa paghila upang gawin ang pagsali.
+pulls.merged_title_desc_one = isinali ang %[1]d commit mula%[2]s
patungong %[3]s
%[4]s
pull.deleted_branch = (binura):%s
issues.dependency.pr_close_blocks = Hinarang ng hiling sa paghila na ito mula sa pagsara ng mga sumusunod na isyu
issues.reference_issue.body = Katawan
-pulls.recently_pushed_new_branches = Itinulak mo sa [branch] %[1]s %[2]s
+pulls.recently_pushed_new_branches = Nagtulak sa branch na %[1]s %[2]s
issues.add_time_minutes = Minuto
issues.del_time = Burahin ang log ng oras na ito
issues.stop_tracking = Itigil ang orasan
@@ -1802,13 +1884,13 @@ subscribe.pull.guest.tooltip = Mag-sign in para mag-subscribe sa hiling sa paghi
issues.edit.already_changed = Hindi maimbak ang mga pagbabago sa isyu. Mukhang nabago na ng ibang tagagamit ang nilalaman. Mangyaring i-refresh ang pahina at subukang baguhin muli upang maiwasang ma-overwrite ang kanilang pagbago
signing.wont_sign.not_signed_in = Hindi ka naka-sign in.
activity.new_issues_count_n = Bagong mga isyu
-activity.git_stats_files_changed_n = mga nabago
-activity.git_stats_files_changed_1 = nabago
+activity.git_stats_files_changed_n = ay nabago
+activity.git_stats_files_changed_1 = ang nabago
issues.dependency.remove = Tanggalin
-pulls.edit.already_changed = Hindi maimbak ang mga pagbabago sa [pull request]. Mukhang nabago na ng ibang tagagamit ang nilalaman. Mangyaring i-refresh ang pahina at subukang baguhin muli upang maiwasang ma-overwrite ang kanilang pagbago
+pulls.edit.already_changed = Hindi maimbak ang mga pagbabago sa hiling sa paghila. Mukhang nabago na ng ibang tagagamit ang nilalaman. Mangyaring i-refresh ang pahina at subukang baguhin muli upang maiwasang ma-overwrite ang kanilang pagbago
milestones.filter_sort.most_complete = Pinakakumpleto
settings.collaboration.owner = May-ari
-pulls.showing_only_single_commit = Ipinapakita lamang ang mga pagbago ng [commit] %[1]s
+pulls.showing_only_single_commit = Ipinapakita lamang ang mga pagbago ng commit na %[1]s
comments.edit.already_changed = Hindi maimbak ang mga pagbabago sa komento. Mukhang nabago na ng ibang tagagamit ang nilalaman. Mangyaring i-refresh ang pahina at subukang baguhin muli upang maiwasang ma-overwrite ang kanilang pagbago
milestones.completeness = %d%% nakumpleto
wiki.welcome = Maligayang pagdating sa Wiki.
@@ -1817,19 +1899,19 @@ pulls.switch_comparison_type = Ilipat ang uri ng pagkumpara
settings.collaboration.read = Basahin
contributors.contribution_type.additions = Mga pagdagdag
settings.collaboration.write = Isulat
-wiki.search = Hanapin ang wiki
+wiki.search = Maghanap sa wiki
wiki.no_search_results = Walang mga resulta
activity.git_stats_addition_1 = %d pagdagdag
activity.git_stats_addition_n = %d mga pagdagdag
activity.git_stats_deletion_1 = %d pagbura
activity.git_stats_deletion_n = %d mga pagbura
-activity.navbar.code_frequency = Dalas ng [code]
+activity.navbar.code_frequency = Dalas ng code
pulls.switch_head_and_base = Ilipat ang ulo at base
-activity.git_stats_push_to_all_branches = sa lahat ng mga [branch].
-activity.git_stats_pushed_n = mga itinulak
+activity.git_stats_push_to_all_branches = sa lahat ng mga branch.
+activity.git_stats_pushed_n = itinulak ang
issues.reference_link = Pagsangguni: %s
-activity.git_stats_pushed_1 = itinulak
-activity.git_stats_commit_n = %d mga [commit]
+activity.git_stats_pushed_1 = ang itinulak
+activity.git_stats_commit_n = %d mga commit
issues.dependency.add = Magdagdag ng dependencyโฆ
issues.dependency.cancel = Kanselahin
issues.dependency.no_permission.can_remove = Wala kang pahintulot na basahin ang dependency na ito ngunit matatanggal ang dependency
@@ -1837,55 +1919,885 @@ issues.dependency.remove_info = Tanggalin ang dependency na ito
issues.dependency.added_dependency = `nagdagdag ng bagong dependency %s`
issues.review.dismissed_label = Nadismiss
issues.review.dismissed = nadismiss ang pagsuri ni %s %s
-issues.review.self.approval = Hindi mo maaring aprubahan ang sarili mong hiling sa paghila.
-issues.review.self.rejection = Hindi mo maaring humiling ng pagbabago sa sarili mong hiling sa paghila.
+issues.review.self.approval = Hindi mo maaaring aprubahan ang sarili mong hiling sa paghila.
+issues.review.self.rejection = Hindi mo maaaring humiling ng pagbabago sa sarili mong hiling sa paghila.
pulls.nothing_to_compare_have_tag = Magkapareho ang mga piniling branch/tag.
issues.dependency.no_permission_1 = Wala kang pahintulot na basahin ang dependency na %d
issues.dependency.no_permission_n = Wala kang pahintulot na basahin ang mga %d dependency
issues.dependency.removed_dependency = `nagtanggal ng dependency %s`
settings.mirror_settings.push_mirror.add = Magdagdag ng salaming pangtulak
settings.mirror_settings.last_update = Huling nabago
-settings.units.add_more = Magdagdag ng higit pa...
-activity.closed_issues_count_n = Isinarang mga isyu
+settings.units.add_more = Paganahin ang higit pa
+activity.closed_issues_count_n = Mga saradong isyu
activity.new_issues_count_1 = Bagong isyu
settings.branches.add_new_rule = Magdagdag ng bagong patakaran
pulls.push_rejected_summary = Buong mensahe ng pagtanggi
activity.title.issues_1 = %d isyu
-activity.title.issues_n = % mga isyu
+activity.title.issues_n = %d mga isyu
settings.mirror_settings.direction.pull = Paghila
settings.mirror_settings.direction.push = Pagtulak
-settings.push_mirror_sync_in_progress = Itinulak ang mga pagbabago patungo sa [malayuang] %s sa ngayon.
-milestones.filter_sort.least_issues = [Pinakamaliit] na mga isyu
+settings.push_mirror_sync_in_progress = Itinutulak ang mga pagbabago patungo sa remote na %s sa ngayon.
+milestones.filter_sort.least_issues = Pinakakaunting mga isyu
pulls.showing_specified_commit_range = Ipinapakita lamang ang mga pagbabago sa pagitan ng %[1]s..%[2]s
wiki.pages = Mga pahina
activity.unresolved_conv_label = Nakabukas
-settings.pull_mirror_sync_in_progress = Inihatak ang mga pagbabago mula sa [malayuang] %s sa ngayon.
+settings.pull_mirror_sync_in_progress = Hinihila ang mga pagbabago mula sa remote na %s sa ngayon.
+issues.dependency.setting = Paganahin ang mga dependency para sa mga isyu at mga hiling sa paghila
+activity.navbar.pulse = Pulso
+settings.protect_enable_merge_desc = Pinapayagan ang sinumang may access sa pagsulat upang isama ang mga hiling sa paghila sa branch na ito.
+activity.git_stats_commit_1 = %d commit
+activity.git_stats_file_n = %d mga file
+activity.git_stats_file_1 = %d file
+pulls.desc = Paganahin ang mga hiling sa paghila at mga pagsuri sa code.
+activity.git_stats_exclude_merges = Maliban sa mga pagsali,
+activity.active_prs_count_n = %d aktibong mga hiling sa paghila
+issues.author.tooltip.issue = May-akda ng iysung ito ang user.
+issues.author.tooltip.pr = May-akda ng hiling sa paghila na ito ang user na ito.
+issues.dependency.add_error_dep_exists = Umiiral na and dependency.
+issues.dependency.add_error_cannot_create_circular = Hindi ka maaaring gumawa ng dependency na may dalawang isyu na humaharang sa isa't isa.
+issues.dependency.add_error_same_issue = Hindi mo magagwang dumepende ang isyu sa sarili.
+issues.dependency.add_error_dep_not_same_repo = Dapat nasa katulad na repositoryo ang mga isyu.
+issues.dependency.add_error_dep_issue_not_exist = Hindi umiiral ang dumedependeng isyu.
+issues.dependency.add_error_dep_not_exist = Hindi umiiral ang dependency.
+pulls.compare_changes = Bagong hiling sa paghila
+pulls.allow_edits_from_maintainers = Payagan ang mga pagbabago mula sa mga tagapagpanatili
+pulls.show_all_commits = Ipakita ang lahat ng mga commit
+pulls.show_changes_since_your_last_review = Ipakita ang mga pagbabago mula noong huli mong pagsusuri
+issues.dependency.blocked_by_short = Dumedepende sa
+issues.review.pending.tooltip = Kasalukuyang hindi visible ang komentong ito sa ibang mga user. Para i-submit ang iyong mga nakabinbin na komento, piliin ang "%s" -> "%s/%s/%s" sa itaas ng pahina.
+pulls.tab_commits = Mga Commit
+issues.dependency.issue_remove_text = Tatanggalin nito ang dependency sa isyu na ito. Magpatuloy?
+issues.dependency.remove_header = Tanggalin ang Dependency
+issues.dependency.pr_remove_text = Tatanggalin nito ang dependency sa hiling sa paghila na ito. Magpatuloy?
+issues.review.show_resolved = Ipakita ang naresolba
+issues.review.hide_resolved = Itago ang naresolba
+issues.review.resolve_conversation = Iresolba ang paguusap
+issues.review.un_resolve_conversation = I-unresolve ang paguusap
+issues.blocked_by_user = Hindi ka maaaring gumawa ng mga isyu sa repositoryong ito dahil hinarang ka ng may-ari ng repositoryo.
+issues.review.show_outdated = Ipakita ang luma
+issues.review.hide_outdated = Itago ang luma
+issues.review.resolved_by = minarkahan ang paguusap na ito bilang naresolba
+issues.review.content.empty = Kailangan mong magiwan ng komento na nagpapahiwatig sa (mga) hinihiling na pagbabago.
+issues.review.outdated = Luma na
+issues.review.outdated_description = Nagbago ang nilalaman mula noong ginawa ang komentong ito
+issues.review.option.show_outdated_comments = Ipakita ang mga lumang komento
+issues.review.option.hide_outdated_comments = Itago ang mga lumang komento
+wiki.reserved_page = Nakareserba ang pangalan ng wiki page na "%s".
+no_eol.tooltip = Hindi naglalaman ang file na ito ng trailing na end of line character.
+no_eol.text = Walang wakas ng linya
+compare.compare_head = ikumpara
+pulls.review_only_possible_for_full_diff = Posible lang ang pagsuri kapag tinitignan ang punong diff
+wiki.wiki_page_revisions = Mga rebisyon ng pahina
+settings.federation_not_enabled = Hindi naka-enable ang federation sa instansya na ito.
+pulls.filter_changes_by_commit = I-filter ayon sa commit
+settings.githooks = Mga Git hook
+issues.comment.blocked_by_user = Hindi ka maaaring gumawa ng komento sa isyu na ito dahil hinarang ka ng may-ari ng repositoryo o ng gumawa ng isyu.
+pulls.view = Tignan ang hiling sa paghila
+activity.navbar.contributors = Mga contributor
+activity.navbar.recent_commits = Mga kamakailang commit
+activity.period.filter_label = Panahon:
+pulls.filter_branch = I-filter ang branch
+settings.collaboration = Mga katulong
+settings.hooks = Mga webhook
+activity.title.user_1 = %d user
+wiki.desc = Magsulat at magbahagi ng dokumentasyon sa mga katulong.
+activity.title.user_n = %d mga user
+settings.mirror_settings.docs = I-set up ang iyong repositoryo na awtomatikong mag-synchronize ng mga commit, tag, at branch mula sa isa pang repositoryo.
+settings.basic_settings = Mga basic na setting
+compare.compare_base = base
+pulls.allow_edits_from_maintainers_desc = Makakatulak rin ang mga user na may write access sa base branch sa branch na ito
+pulls.allow_edits_from_maintainers_err = Nabigo ang pag-update
+pulls.compare_changes_desc = Piliin ang branch na isasama sa at ang branch na hihilahin mula sa.
+pulls.has_changed_since_last_review = Nabago mula noong huli mong pagsuri
+pulls.expand_files = I-expand ang lahat ng mga file
+pulls.manually_merged = Manwal na naisama
+wiki.cancel = Kanselahin
+settings.collaboration.undefined = Hindi Natukoy
+settings.federation_settings = Mga Setting ng Federation
+settings = Mga Setting
+settings.desc = Ang mga setting ang lugar kung saan maari mong ipamahala ang mga setting para sa repositoryo
+pulls.collapse_files = I-collapse ang lahat ng mga file
+pulls.add_prefix = Magdagdag ng %s na prefix
+pulls.still_in_progress = Ginagawa pa?
+activity.title.prs_1 = %d hiling sa paghila
+activity.active_issues_count_n = %d mga aktibong isyu
+pulls.required_status_check_missing = Nawawala ang ilang mga kinakailangang pagsusuri.
+pulls.required_status_check_administrator = Bilang tagapangasiwa, maari mo pa ring isama ang hiling sa paghila na ito.
+pulls.blocked_by_approvals = Wala pang sapat na pag-apruba ang hiling sa paghila na ito. %d ng %d na pag-apruba ang ibinigay.
+settings.options = Repositoryo
+wiki.back_to_wiki = Bumalik sa pahina ng wiki
+activity.active_issues_count_1 = %d aktibong isyu
+activity.closed_issues_count_1 = Saradong isyu
+settings.federation_apapiurl = Federation URL ng repositoryo na ito. Kopyahin at i-paste ito sa Mga Setting ng Federation ng ibang repositoryo bilang URL ng isang Sinusundan na Repositoryo.
+pulls.select_commit_hold_shift_for_range = Piliin ang commit. I-hold ang shift + click para pumili ng pagitan
+wiki = Wiki
+wiki.file_revision = Rebisyon ng pahina
+pulls.change_target_branch_at = `pinalitan ang target branch mula %s sa %s %s`
+pulls.title_wip_desc = `Simulan ang pamagat sa %s para iwasang hindi sadyang isama ang hiling sa paghila.`
+pulls.cannot_merge_work_in_progress = Naka-marka ang hiling sa paghila na ito bilang ginagawa pa.
+settings.mirror_settings = Mga setting ng mirror
+wiki.filter_page = I-filter ang pahina
+wiki.default_commit_message = Magsulat ng tala tungkol sa update ng pahina (opysonal).
+pulls.is_ancestor = Kasama na ang branch na ito sa target branch. Walang isasama.
+pulls.is_empty = Nasa target branch na ang mga pagbabago sa branch na ito. Ito ay magiging isang walang laman na commit.
+pulls.required_status_check_failed = Hindi matagumpay ang mga ilang kinakailangang pagsusuri.
+pulls.remove_prefix = Tanggalin ang %s na prefix
+pulls.data_broken = Sira ang hiling sa paghila na ito dahil sa nawawalang impormasyon tungkol sa fork.
+pulls.files_conflicted = May mga pagbabago ang hiling sa paghila na ito na sumasalungat sa target na branch.
+pulls.is_checking = Ginagawa pa ang pagsuri ng merge conflict. Subukang muli sa ilang sandali.
+wiki.welcome_desc = Pinapayagan ng wiki ang pagsulat at pagbahagi ng dokumentasyon sa mga katulong.
+activity.active_prs_count_1 = %d aktibong hiling sa paghila
+settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning = Sa ngayon, magagawa lang ito sa "Bagong Paglipat" na menu. Para sa karagdagang impormasyon, mangyaring kumonsulta sa:
+settings.mirror_settings.docs.disabled_push_mirror.info = Na-disable ng iyong tagapangasiwa ng site ang mga push mirror.
+settings.mirror_settings.docs.disabled_push_mirror.instructions = I-set up ang iyong proyekto na awtomatikong hilahin ang mga commit, tag at branch mula sa isa pang repositoryo.
+settings.mirror_settings.docs.disabled_pull_mirror.instructions = I-set up ang iyong proyekto na awtomatikong magtulak ng mga commit, tag at branch sa isa pang repositoryo. Na-disable ng iyong tagapangasiwa ng site ang mga pull mirror.
+activity.overview = Pangkalahatang Ideya
+mirror_public_key = Pampublikong susi ng SSH
+milestones.cancel =Kanselahin
+issues.all_title = Lahat
+mirror_denied_combination = Hindi maaaring gumamit ng pampublikong key at password-based na authentication nang magkakasama.
+issues.filter_sort.relevance = Kaugnayan
+issues.dependency.issue_batch_close_blocked = Hindi ma-batch close ang mga napiling isyu sa pagsasara, dahil ang isyu na #%d ay mayroon pa ring mga bukas na dependency
+mirror_use_ssh.helper = Isasalamin ng Forgejo ang repositoryo sa pamamagitan ng Git over SSH at gumawa ng keypair para sa iyo kapag piliin mo ang opsyon na ito. Kailangan mong siguraduhin na ang na-generate na pampublikong key ay pinahintulutan para magtulak sa tinutunguhan na repositoryo. Hindi ka makakagamit ng password-based na authentication kapag piliin mo ito.
+mirror_use_ssh.text = Gumamit ng SSH na authentikasyon
+issues.new.assign_to_me = I-assign sa akin
+mirror_use_ssh.not_available = Hindi available ang SSH na authentikasyon.
+pulls.cannot_auto_merge_helper = Isama nang manwal upang lutasin ang mga pagkasalungat.
+pulls.cannot_auto_merge_desc = Hindi masasama ang hiling sa paghila na ito dahil sa mga kasalungatan.
+pulls.blocked_by_rejection = Ang kahilingan sa paghila na ito ay may mga pagbabagong hiniling ng isang opisyal na tagasuri.
+pulls.blocked_by_outdated_branch = Hinarangan ang hiling sa paghila na ito dahil luma na ito.
+pulls.wrong_commit_id = ang commit id ay dapat ang commit id sa patutunguhan na branch
+pulls.blocked_by_changed_protected_files_1 = Hinarangan ang hiling sa paghila na ito dahil nagbabago ito ng isang nakaprotektang file:
+pulls.blocked_by_changed_protected_files_n = Hinarangan ang hiling sa paghila na ito dahil nagbabago ito ng mga nakaprotektang file:
+pulls.blocked_by_official_review_requests = Hinarangan ang hiling sa paghila na ito dahil may nawawalang pag-apruba mula sa isa o higit pang mga opisyal na tagasuri.
+pulls.can_auto_merge_desc = Maaaring isama ng awtomatiko ang hiling sa paghila na ito.
+pulls.num_conflicting_files_n = %d mga magkasalungat na file
+pulls.num_conflicting_files_1 = %d magkasalungat na file
+issues.review.add_review_requests = humiling ng mga pagsuri mula sa %[1]s %[2]s
+issues.review.remove_review_requests = tinanggal ang mga hiling sa pagsuri para sa/kay %[1]s %[2]s
+issues.review.add_remove_review_requests = humiling ng mga pagsuri mula kay %[1]s at tinanggal ang mga hiling sa pagsuri para sa/kay %[2]s %[3]s
+pulls.no_merge_helper = I-enable ang mga opsyon sa pagsasama sa mga setting ng repositoryo o isama nang manwal ang hiling sa paghila na ito.
+pulls.no_merge_desc = Hindi masasama ang hiling sa paghila na ito dahil naka-disable ang lahat ng mga opsyon ng pagsasama sa repositoryo.
+pulls.merge_pull_request = Gumawa ng merge commit
+pulls.invalid_merge_option = Hindi mo magagamit ang opsyon ng pagsama na ito para sa hiling sa paghila na ito.
+pulls.fast_forward_only_merge_pull_request = I-fast-forward lamang
+pulls.merge_commit_id = Ang commit ID ng pagsama
+pulls.no_merge_wip = Hindi maisasama ang hiling sa paghila na ito dahil nakamarka ito bilang ginagawa pa.
+pulls.merge_manually = Manwal na naisama
+pulls.merge_conflict = Nabigo ang pagsama: Nagkaroon ng salungatan habang nagsasama. Pahiwatig: Sumubok ng ibang paraan
+pulls.merge_conflict_summary = Mensahe ne error
+pulls.merge_out_of_date = Nabigo ang pagsasama: Habang gine-generate ang pagsama, nag-update ang base. Pahiwatig: Subukan muli.
+pulls.head_out_of_date = Nabigo ang pagsasama: Habang gine-generate ang pagsama, nag-update ang head. Pahiwatig: Subukan muli.
+pulls.has_merged = Nabigo: Naisama na ang hiling sa paghila, hindi ka na pwedeng magsama ulit o palitan ang target branch.
+pulls.require_signed_wont_sign = Kinakailangan ng branch ng mga naka-sign na commit pero hindi isa-sign ang pagsama na ito
+pulls.squash_merge_pull_request = Gumawa ng squash commit
+pulls.rebase_conflict_summary = Mensahe ne error
+pulls.rebase_conflict = Nabigo ang pagsama: Nagkaroon ng salungatan habang nagre-rebase ng commit: %[1]s. Pahiwatig: Sumubok ng ibang paraan
+pulls.rebase_merge_pull_request = I-rebase at i-fast-forward
+pulls.rebase_merge_commit_pull_request = I-rebase at gumawa ng merge commit
+pulls.no_merge_not_ready = Hindi pa handang isama ang hiling sa paghila na ito, suriin ang estado ng pagsusuri at mga status check.
+pulls.unrelated_histories = Nabigo ang pagsasama: Ang merge head at base ay hindi nagbabahagi ng isang karaniwang kasaysayan. Pahiwatig: Sumubok ng ibang paraan
+settings.trust_model.collaborator.long = Tagatulong: Pagkatiwalaan ang mga signature mula sa mga katulong
+settings.enable_timetracker = I-enable ang pagsubaybay ng oras
+settings.add_collaborator_owner = Hindi madadagdag ang may-ari bilang katulong.
+pulls.status_checks_success = Matagumpay ang lahat ng mga pagsusuri
+settings.webhook.test_delivery_desc_disabled = Para subukan ang webhook gamit ng isang pekeng event, i-activate ito.
+settings.slack_username = Username
+pulls.auto_merge_when_succeed = Awtomatikong isama kapag magtagumpay ang lahat ng mga pagsusuri
+settings.allow_only_contributors_to_track_time = Payagan lamang ang mga kontribyutor na subaybayan ang oras
+settings.packages_desc = I-enable ang package registry ng repositoryo
+settings.actions_desc = I-enable ang mga kasamang CI/CD pipeline gamit ang Forgejo Actions
+settings.admin_indexer_commit_sha = Huling na-index na commit
+settings.admin_indexer_unindexed = Hindi naka-index
+settings.transfer_notices_3 = - Kung pribado ang repositoryo at ilipat sa isang indibidwal na user, ang aksyon na ito ay sinisigurado na ang user ay may pahintulot na basahin (at palitan ang mga pahintulot kung kailangan).
+settings.convert_desc = Maari mong i-convert ang repositoryo na ito sa regular na repositoryo. Hindi ito mababawi.
+settings.transfer.button = Ilipat ang pagmamay-ari
+settings.signing_settings = Mga setting sa pagpapatunay ng pag-sign
+settings.admin_enable_close_issues_via_commit_in_any_branch = Isara ang isyu sa pamamagitan ng commit na ginawa sa hindi default na branch
+settings.reindex_button = Idagdag sa reindex queue
+settings.packagist_username = Username sa Packagist
+settings.event_pull_request_assign = Pag-assign
+settings.event_pull_request_approvals = Mga pagapruba sa hiling sa paghila
+settings.web_hook_name_matrix = Matrix
+settings.event_pull_request = Pagbago
+settings.event_issue_comment = Mga komento
+settings.mirror_settings.push_mirror.none = Walang mga na-configure na push mirror
+settings.transfer_started = Namarkahan na ang repositoryo para sa paglipat at naghihintay ng kumpirmasyon mula kay/sa "%s"
+settings.wiki_globally_editable = Payagan ang sinuman na baguhin ang wiki
+settings.external_wiki_url_error = Hindi wastong URL ang panlabas na wiki na URL.
+settings.event_pull_request_enforcement = Pagpapatupad
+settings.title = Pamagat
+settings.pulls.ignore_whitespace = Huwag pansinin ang whitespace para sa mga salungatan
+pulls.delete.text = Gusto mo ba talagang burahin ang hiling sa paghila na ito? (Permanente nitong buburahin ang lahat ng nilalaman. Isaalang-alang na isara ito sa halip, kung balak mo na panatilihin ito naka-archive)
+milestones.new = Bagong milestone
+wiki.page_name_desc = Maglagay ng pangalan para sa pahina ng Wiki na ito. Ang ilang mga espesyal na pangalan ay: "Home", "_Sidebar" at "_Footer".
+settings.transfer.title = Ilipat ang pagmamay-ari
+settings.content_type = Uri ng nilalaman ng POST (content type)
+settings.deploy_key_deletion = Tanggalin ang deploy key
+settings.protect_enable_push = I-enable ang pagtulak
+settings.discord_icon_url.exceeds_max_length = Kailangang bababa o equal sa 2048 characters ang URL ng icon
+settings.protected_branch.save_rule = I-save ang rule
+settings.mirror_settings.docs.can_still_use = Bagama't na hindi ka makakabago ng mga umiiral na mirror o gumawa ng bago, maari mo pa rin gamitin ang iyong umiiral na mirror.
+settings.slack_color = Kulay
+settings.discord_icon_url = URL ng icon
+settings.convert_fork_confirm = I-convert ang repositoryo
+settings.add_webhook = Magdagdag ng webhook
+settings.event_repository_desc = Ginawa o binura ang repositoryo.
+milestones.no_due_date = Walang takdang petsa
+milestones.edit_success = Na-update na ang milestone na "%s".
+activity.title.unresolved_conv_n = %d mga hindi naresolbang paguusap
+settings.units.units = Mga Yunit
+settings.event_pull_request_label = Mga label
+settings.trust_model.collaborator = Tagatulong
+pulls.made_using_agit = AGit
+settings.protect_disable_push = I-disable ang pagtulak
+signing.wont_sign.pubkey = Hindi isa-sign ang commit na ito dahil wala kang pampublikong key na nauugnay sa iyong account.
+settings.transfer_in_progress = May ginagawang paglipat. Mangyaring kanselahin iyan kung gusto mong ilipat ang repositoryo na ito sa isa pang user.
+settings.wiki_branch_rename_failure = Nabigong i-normalize ang pangalan ng branch ng wiki ng repositoryo.
+settings.event_send_everything = Lahat ng mga event
+settings.event_choose = Mga custom na eventโฆ
+settings.add_webhook_desc = Magpapadala ang Forgejo ng POST
request na may tinakdang Content-Type sa target URL. Magbasa pa sa guide ng mga webhook .
+settings.event_create = Gumawa
+settings.event_wiki_desc = Ginawa, binago ang pangalan, o binura ang pahina ng wiki.
+settings.event_push = Pagtulak
+settings.event_wiki = Wiki
+settings.event_pull_request_assign_desc = Na-assign o unassign ang hiling aa paghila.
+settings.event_issues = Pagbago
+settings.event_issue_assign = Pag-assign
+settings.event_pull_request_milestone = Mga milestone
+settings.event_pull_request_milestone_desc = Dinagdag, tinanggal o binago ang milestone.
+settings.event_pull_request_comment = Mga komento
+settings.event_pull_request_review_request_desc = Nahiling o tinanggal ang pagsuri sa hiling sa paghila.
+settings.web_hook_name_forgejo = Forgejo
+settings.web_hook_name_gitea = Gitea
+settings.deploy_key_desc = Ang mga deploy key ay may read-only na access sa repositoryo.
+settings.is_writable_info = Payagan ang deploy key na ito na magtulak sa repositoryo.
+settings.protect_whitelist_committers_desc = Ang mga naka-whitelist na user o koponan lamang ang makakatulak sa branch na ito (pero hindi ang pinwersang pagtulak).
+settings.protect_whitelist_deploy_keys = I-whitelist ang mga deploy key na may write access para sa pagtulak.
+settings.protect_whitelist_users = I-whitelist ang mga user para sa pagtulak
+signing.wont_sign.never = Hindi masa-sign ang mga commit kailanman.
+signing.wont_sign.basesigned = Hindi isa-sign ang pag-sama na ito dahil hindi naka-sign ang base commit.
+settings.event_fork = Pag-fork
+settings.protect_whitelist_teams = I-whitelist ang mga koponan para sa pagtulak
+settings.delete_collaborator = Tanggalin
+settings.remove_collaborator_success = Tinanggal na ang tagatulong.
+settings.collaborator_deletion_desc = Tatanggihan ang pag-access sa repositoryo na ito ang pagtanggal ng tagatulong. Magpatuloy?
+settings.delete_team_tip = May access sa lahat ng mga repositoryo ang koponan na ito at hindi matatanggal
+settings.authorization_header_desc = Isasama bilang authorization header para sa mga request kung present. Mga halimbawa: %s.
+settings.sourcehut_builds.secrets = Mga sikreto
+settings.is_writable = Paganahin ang write access
+milestones.deletion = Burahin ang milestone
+milestones.deletion_desc = Ang pagbura ng milestone ay tinatanggal ito sa lahat ng mga kaugnay na isyu. Magpatuloy?
+settings.discord_username = Username
+wiki.original_git_entry_tooltip = Itignan ang orihinal na Git file sa halip ng isang friendly na link.
+settings.add_team_duplicate = Nasa koponan na ang repositoryo
+settings.add_team = Magdagdag ng koponan
+settings.add_hook_success = Naidagdag na ang webhook.
+settings.use_external_wiki = Gumamit ng panlabas na wiki
+settings.external_wiki_url = URL ng panlabas na wiki
+settings.use_internal_wiki = Gamitin ang kasamang wiki
+settings.transfer_notices_1 = - Mawawalan ka ng access sa repsositoryo kung ilipat ito sa isang indibidwal na user.
+settings.event_issue_assign_desc = Na-assign o unassign ang isyu.
+settings.event_issue_label = Mga label
+settings.event_issue_label_desc = Nadagdag o tinanggal ang mga label ng isyu.
+settings.event_issue_milestone = Mga milestone
+settings.event_issue_milestone_desc = Dinagdag, tinanggal o binago ang milestone.
+activity.title.releases_published_by = %s nailabas ni/ng %s
+settings.projects_desc = I-enable ang mga proyekto sa repositoryo
+activity.published_release_label = Paglabas
+activity.no_git_activity = Walang anumang commit na aktibidad na nakatuon sa panahong ito.
+pulls.status_checks_warning = May mga ilang pagsusuri na nag-ulat ng mga babala
+pulls.status_checks_error = May ilang mga pagsusuri na nag-ulat ng mga error
+pulls.update_branch_rebase = I-update ang branch sa pamamagitan ng pag-rebase
+pulls.update_not_allowed = Hindi ka pinapayagang i-update ang branch
+pulls.clear_merge_message = I-clear ang mensahe ng pagsasama
+pulls.clear_merge_message_hint = Tinatanggal lamang ng pag-clear ng mensahe ng pagsasama ang nilalaman ng mensahe ng commit at pinapanatili ang mga na-generate na git trailer tulad ng "Co-Authored-By โฆ".
+pulls.auto_merge_newly_scheduled = Nakaiskedyul ang hiling sa paghila na ito na maisama kapag magtagumpay ang lahat ng mga pagsusuri.
+pulls.auto_merge_canceled_schedule_comment = `kinansela ang awtomatikong pagsama ng hiling sa paghila na ito kapag magtagumpay ang lahat ng mga pagsusuri %[1]s`
+pulls.delete_after_merge.head_branch.insufficient_branch = Wala kang pahintulot para burahin ang head branch.
+milestones.new_subheader = Tinutulungan ka ng mga milestone na ayusin ang mga isyu at subaybayan ang kanilang pag-unlad.
+milestones.create = Gumawa ng milestone
+milestones.due_date = Takdang petsa (opsyonal)
+milestones.create_success = Ginawa na ang milestone na "%s".
+milestones.edit = Baguhin ang milestone
+milestones.edit_subheader = Ang mga milestone ay nag-aayos ng mga isyu at sumusubaybay sa pag-unlad.
+milestones.modify = I-update ang milestone
+milestones.filter_sort.earliest_due_data = Pinakamalapit na takdang petsa
+milestones.filter_sort.least_complete = Hindi bababa sa kumpleto
+signing.will_sign = Isa-sign ang commit gamit ang key na "%s".
+signing.wont_sign.error = May error na naganap habang sinusuri kung masa-sign ang commit.
+signing.wont_sign.always = Palaging naka-sign ang mga commit.
+signing.wont_sign.twofa = Kailangang naka-enable ang authentikasyong two factor para naka-sign ang mga commit.
+wiki.delete_page_notice_1 = Ang pagtanggal sa pahina ng wiki na "%s" ay hindi na mababawi. Magpatuloy?
+activity.title.releases_n = %d mga paglabas
+activity.published_prerelease_label = Pre-release
+activity.published_tag_label = Tag
+settings.mirror_settings.docs.doc_link_pull_section = ang "Pulling from a remote repository" na seksyon sa dokumentasyon.
+settings.mirror_settings.docs.pulling_remote_title = Paghila mula sa remote na repositoryo
+settings.mirror_settings.mirrored_repository = Naka-mirror na repositoryo
+settings.mirror_settings.push_mirror.remote_url = URL ng remote Git repository
+settings.units.overview = Pangkalahatang Ideya
+settings.update_settings = I-save ang mga setting
+settings.update_mirror_settings = I-update ang mga setting ng mirror
+settings.branches.update_default_branch = I-update ang default branch
+settings.advanced_settings = Mga advanced na setting
+settings.use_internal_issue_tracker = Gamitin ang kasamang tagasubaybay ng isyu
+settings.external_tracker_url = URL ng panlabas na tagasubaybay ng isyu
+settings.external_tracker_url_desc = Ire-redirect ang mga bisita sa URL ng panlabas na tagasubaybay kapag pipindutin ang mga isyu na tab.
+settings.tracker_url_format = URL format ng panlabas na tagasubaybay ng isyu
+settings.tracker_url_format_error = Hindi wastong URL ang URL format ng panlabas na tagasubaybay ng isyu.
+settings.tracker_issue_style.numeric = Numeric
+settings.tracker_issue_style.alphanumeric = Alphanumeric
+settings.tracker_issue_style.regexp_pattern = Pattern ng Regular na Ekspresyon
+settings.tracker_issue_style.regexp_pattern_desc = Ang unang captured group ay gagamitin sa kapalit ng (index)
.
+settings.pulls.allow_rebase_update = I-enable ang pag-update ng hiling sa paghila sa pamamagitan ng rebase
+settings.admin_enable_health_check = I-enable ang pagsusuri ng kalusugan ng repositoryo (git fsck)
+settings.new_owner_has_same_repo = Ang bagong may-ari ay may repositoryo na may katulad na pangalan. Mangyaring pumili ng ibang pangalan.
+settings.convert = I-convert sa regular na repositoryo
+settings.convert_fork_desc = Maari mong i-convert ang fork na ito bilang regular na repositoryo. Hindi ito mababawi.
+settings.convert_fork_notices_1 = Ang operasyon na ito ay ico-convert ang fork bilang regular na repositoryo at hindi mababawi.
+settings.transfer_abort_invalid = Hindi mo makakansela ang isang hindi umiiral na paglipat ng repositoryo.
+settings.transfer_quota_exceeded = Ang bagong may-ari (%s) ay lumalagpas sa quota. Hindi nailipat ang repositoryo.
+settings.trust_model.committer = Taga-commit
+settings.trust_model.committer.long = Taga-commit: Pagkatiwalaan ang mga signature na tumutugma sa mga taga-commit (Tumutugma ito sa GitHub at pinipilit ang mga Forgejo signed na mga commit na Forgejo bilang taga-commit)
+settings.trust_model.collaboratorcommitter = Tagatulong+Taga-commit
+settings.trust_model.collaboratorcommitter.long = Tagatulong+Taga-commit: Pagkatiwalaan ang mga signature batay sa mga katulong na tumutugma sa taga-commit
+settings.wiki_rename_branch_main = I-normalize ang pangalan ng branch ng Wiki
+settings.wiki_rename_branch_main_notices_1 = HINDI MABABAWI ang operasyon na ito.
+settings.wiki_rename_branch_main_notices_2 = Permanente nitong papalitan ang pangalan ng internal branch ng wiki ng repositoryo ng %s. Ang mga umiiral na checkout ay dapat ma-update.
+settings.wiki_branch_rename_success = Matagumpay na na-normalize ang pangalan ng branch ng wiki ng repositoryo.
+settings.wiki_delete = Burahin ang data ng wiki
+settings.wiki_delete_notices_1 = - Permanente nitong buburahin at idi-disable ang wiki ng repositoryo para sa %s.
+settings.confirm_wiki_delete = Burahin ang data ng wiki
+settings.wiki_deletion_success = Binura na ang wiki data ng repositoryo.
+settings.delete = Burahin ang repositoryo na ito
+settings.delete_desc = Permanente ang pagbura ng repositoryo at hindi ito mababawi.
+settings.update_settings_no_unit = Dapat payagan ng repositoryo ang kahit isang uri ng pakikipag-ugnayan.
+settings.confirm_delete = Burahin ang repositoryo
+settings.add_collaborator = Magdagdag ng katulong
+settings.add_collaborator_duplicate = Nadagdag na ang tagatulong na ito sa repositoryo.
+settings.add_collaborator_blocked_our = Hindi madagdag ang tagatulong, dahil hinarang siya ng may-ari ng repositoryo.
+settings.add_collaborator_blocked_them = Hindi madagdag ang tagatulong, dahil hinarang niya ang may-ari ng repositoryo.
+settings.collaborator_deletion = Tanggalin ang Tagatulong
+settings.team_not_in_organization = Ang koponan ay hindi nasa katulad na organisasyon sa repositoryo
+settings.teams = Mga Koponan
+settings.add_team_success = May access na ang koponan sa repositoryo na ito.
+settings.remove_team_success = Tinanggal na ang access ng koponan sa repositoryo na ito.
+settings.webhook_deletion_desc = Ang pagtanggal ng webhook ay binubura rin ang mga setting at deliver history nito. Magpatuloy?
+settings.webhook.test_delivery_desc = Subukan ang webhook na ito gamit ng pekeng event.
+settings.webhook.response = Tugon
+settings.webhook.headers = Mga header
+settings.webhook.payload = Nilalaman
+settings.webhook.body = Katawan
+settings.webhook.replay.description = I-replay ang webhook na ito.
+settings.webhook.delivery.success = May nadagdag na event sa delivery queue. Maari magtagal ng ilang segundo bago makita sa delivery history.
+settings.githooks_desc = Pinapagana ng Git ang mga Git hook. Maari mong baguhin ang mga hook file sa ibaba para mag-set up ng mga custom na operasyon.
+settings.githook_name = Pangalan ng hook
+settings.githook_content = Nilalaman ng hook
+settings.update_githook = I-update ang hook
+settings.payload_url = Target na URL
+settings.http_method = Method ng HTTP
+settings.event_push_only = Mga push event
+settings.event_delete_desc = Binura ang branch o tag.
+settings.event_fork_desc = Na-fork ang repositoryo.
+settings.event_repository = Repositoryo
+settings.event_header_issue = Mga event sa isyu
+settings.event_header_pull_request = Mga event sa hiling sa paghila
+settings.event_pull_request_comment_desc = Gumawa, binago o binura ang komento sa hiling sa paghila.
+settings.event_pull_request_sync = Na-synchronize
+settings.event_pull_request_sync_desc = Na-update ang branch nang awtomatiko sa target branch.
+settings.event_pull_request_review_request = Mga hiling sa pagsuri
+settings.event_pull_request_merge = Pagsama ng hiling sa paghila
+settings.branch_filter = Filter ng branch
+settings.authorization_header = Awtorisasyon (Authrorization) na header
+settings.active = Aktibo
+settings.active_helper = Ang mga impormasyon tungkol sa mga na-trigger na event ay ipapadala sa webhook URL na ito.
+settings.update_webhook = I-update ang webhook
+settings.update_hook_success = Na-update na ang webhook.
+settings.delete_webhook = Tanggalin ang webhook
+settings.recent_deliveries = Mga kamakailang pag-deliver
+settings.hook_type = Uri ng hook
+settings.slack_token = Token
+settings.slack_domain = Domain
+settings.slack_channel = Channel
+settings.add_web_hook_desc = I-integrate ang %s sa iyong repositoryo.
+settings.graphql_url = URL ng GraphQL
+settings.web_hook_name_gogs = Gogs
+settings.web_hook_name_slack = Slack
+settings.web_hook_name_discord = Discord
+settings.web_hook_name_dingtalk = DingTalk
+settings.web_hook_name_packagist = Packagist
+settings.packagist_api_token = API token
+settings.packagist_package_url = Package URL sa Packagist
+settings.web_hook_name_sourcehut_builds = Mga Build sa Sourcehut
+settings.sourcehut_builds.manifest_path = Manifest path ng build
+settings.sourcehut_builds.visibility = Visibility ng job
+settings.deploy_keys = Mga deploy key
+settings.add_deploy_key = Magdagdag ng deploy key
+settings.deploy_key_content = Nilalaman
+settings.deploy_key_deletion_desc = Ang pagtanggal ng deploy key ay tatanggihan ang pag-access sa repositoryo na ito. Magpatuloy?
+settings.deploy_key_deletion_success = Tinanggal na ang deploy key.
+settings.protected_branch = Proteksyon sa branch
+settings.protected_branch.delete_rule = Burahin ang rule
+settings.protect_new_rule = Gumawa ng bagong branch protection rule
+settings.protect_disable_push_desc = Walang pinapayagan na pagtulak sa branch na ito.
+settings.protect_enable_merge = I-enable ang pagsama
+settings.protect_merge_whitelist_committers = I-enable ang whitelist ng pagsasama
+pulls.update_branch_success = Matagumpay ang pag-update ng branch
+settings.protect_whitelist_committers = I-whitelist ang pinahigpit na pagtulak
+settings.site = Website
+settings.convert_confirm = I-convert ang repositoryo
+settings.webhook.replay.description_disabled = Para i-replay ang webhook na ito, i-activate ito.
+settings.tracker_issue_style.regexp = Regular na Ekspresyon
+settings.admin_stats_indexer = Taga-index ng istatistika ng code
+pulls.open_unmerged_pull_exists = `Hindi ka maaaring gumawa ng pagbukas-muli na operasyon dahil may nakabinbin na hiling sa paghila (#%d) na may magkatulad na katangian.`
+milestones.deletion_success = Binura na ang milestone.
+pulls.auto_merge_has_pending_schedule = Naiskedyul ni %[1]s na awtomatiko na isama ang hiling sa paghila na ito kapag magtagumpay ang lahat ng mga pagsusuri %[2]s.
+issues.summary_card_alt = Pangkalahatang-ideyang card ng isyu na tawag na "%s" sa repositoryong %s
+pulls.status_checks_hide_all = Itago ang lahat ng mga pagususri
+pulls.cmd_instruction_merge_warning = Babala: Hindi naka-enable ang "I-auto detect ang manwal na pagsasama" na setting para sa repositoryo na ito, kailangan mong markahan ang hiling sa paghila na ito bilang manwal na naisama pagkatapos.
+pulls.auto_merge_newly_scheduled_comment = `naiskedyul ang hiling sa paghila na ito na awtomatikong maisama kapag magtagumpay ang lahat ng mga pagsusuri %[1]s`
+signing.wont_sign.headsigned = Hindi isa-sign ang pagsama na ito dahil hindi naka-sign ang head commit.
+settings.mirror_settings.docs.pull_mirror_instructions = Para mag-set up ng pull mirror, mangyaring sumangguni sa:
+milestones.invalid_due_date_format = Kailangang "yyyy-mm-dd" na format ang takdang petsa.
+signing.wont_sign.nokey = Walang key ang instansya na ito para i-sign ang commit na ito.
+activity.title.releases_1 = %d paglabas
+settings.mirror_settings.docs.more_information_if_disabled = Maari kang matuto pa tungkol sa mga push at pull na mirror dito:
+settings.branches.switch_default_branch = Magpalit ng default branch
+settings.convert_notices_1 = Ang operasyon na ito ay ico-covert ang mirror sa regular na repositoryo at hindi mababawi.
+settings.convert_fork_succeed = Na-convert na ang fork sa regular na repositoryo.
+settings.external_tracker_url_error = Hindi wastong URL ang URL ng panlabas na tagasubaybay ng isyu.
+settings.tracker_url_format_desc = Gamitin ang mga placeholder na (user)
, (repo)
at (index)
para sa username, pangalan ng repositoryo, at index ng isyu.
+settings.pulls.enable_autodetect_manual_merge = I-enable ang awtomatikong i-detect ang manwal na pagsasama (Tandaan: sa mga espesyal na kaso, maaaring mangyari ang mga maling paghuhusga)
+settings.transfer_notices_2 = - Mapapanatili mo ang access sa repositoryo kung ilipat mo ito sa organisasyon na minamay-ari mo o pinapangasiwaan mo.
+settings.trust_model.collaboratorcommitter.desc = Ang mga angkop na signature mula sa mga tagatulong sa repositoryo na ito ay mamarkahan bilang "pinagkakatiwalaan" kapag tumutugma sila sa taga-commit. Kung hindi, ang mga angkop na signature ay imamarka bilang "hindi pinagkakatiwalaan" kapag ang signature ay tumutugma sa taga-commit at "hindi tumutugma" kung hindi. Pinipilit nito na markahan ang Forgejo bilang taga-commit sa mga naka-sign na commit na ang aktwal na taga-commit na nakamarka bilang Co-Authored-By: at Co-Committed-By: trailer sa commit. Ang default na Forgejo key ay dapat tumugma sa User sa database.
+settings.update_settings_success = Nabago na ang mga setting ng repositoryo.
+settings.trust_model.committer.desc = Ang mga angkop na signature ay mamamarkahan lamang bilang "pinagkakatiwalaan" kapag tumutugma sila sa taga-commit, kung hindi ay mamarkahan sila bilang "hindi tugma". Pinipilit nito na Forgejo ang magiging taga-commit para sa mga naka-sign na commit na may aktwal na taga-commit bilang Co-authored-by: at Co-committed-by: trailer sa commit. Ang default na Forgejo key ay dapat tumugma sa User sa database.
+settings.delete_notices_1 = - HINDI MABABAWI ang operasyon na ito.
+settings.delete_notices_2 = - Permanenteng buburahin ang %s na repositoryo kasama ang code, mga isyu, mga komento, data ng wiki at mga setting ng tagatulong ang operasyon na ito.
+settings.add_collaborator_inactive_user = Hindi makakadagdag ng hindi aktibong user bilang tagatulong.
+settings.change_team_access_not_allowed = Ang pagbago ng pag-access para sa koponan para sa repositoryo na ito ay pinahigpitan sa may-ari ng organisasyon
+settings.change_team_permission_tip = Ang mga pahintulot ng koponan ay nakatakda sa pahina ng mga setting koponan at hindi mababago kada repositoryo
+settings.hooks_desc = Ang mga webhook ay awtomatikong gumagawa ng HTTP POST request sa server kung saan ang ilang mga Forgejo na event ay ma-trigger. Magbasa pa sa guide ng mga webhook .
+settings.githook_edit_desc = Kapag hindi aktibo ang hook, ipapakita ang mga sample na nilalaman. Idi-disable ang hook na ito kapag iwanang walang laman na value ang nilalaman.
+settings.key_been_used = Ang deploy key na may katulad na nilalaman ay ginagamit na.
+settings.event_issue_comment_desc = Gumawa, binura o binago ang komento ng isyu.
+settings.event_pull_request_label_desc = Nadagdag o tinanggal ang mga label ng hiling sa paghila.
+settings.event_package_desc = Ginawa o binura ang package sa repositoryo.
+settings.branch_filter_desc = Branch whitelist para sa pagtulak, paggawa ng branch at pagbura ng branch na event, natakda bilang glob pattern. Kapag walang laman o *
, inuulat ang event para sa lahat ng mga branch. Tignan ang %[2]s na dokumentasyon para sa syntax. Halimbawa: master
, {master,release*}
.
+settings.sourcehut_builds.secrets_helper = Bigyan ang job ng access sa build secrets (kinakailangan ang SECRETS:RO na grant)
+settings.branch_protection = Mga protection rule para sa branch na "%s "
+settings.sourcehut_builds.access_token_helper = Access token na may JOBS:RW na grant. Mag-generate ng builds.sr.ht na token o ng builds.sr.ht na token na may secrets access sa meta.sr.ht.
+settings.protect_enable_push_desc = Ang sinuman na may write access ay mapapayagan na magtulak sa branch na ito (pero hindi ang pinwersang pagtulak).
+settings.key_name_used = Umiiral na ang deploy key na may katulad na pangalan.
+settings.webhook.request = Hiling
+settings.event_package = Package
+settings.no_deploy_keys = Wala pang mga deploy key sa ngayon.
+settings.transfer_succeed = Nalipat na ang repositoryo.
+settings.delete_notices_fork_1 = - Magiging malaya ang mga fork ng repositoryo na ito pagkatapos ng pagbura.
+settings.deletion_success = Nabura na ang repositoryo.
+settings.web_hook_name_msteams = Microsoft Teams
+pulls.auto_merge_cancel_schedule = Kanselahin ang awtomatikong pagsasama
+pulls.auto_merge_not_scheduled = Hindi naka-iskedyul ang hiling sa paghila na ito na awtomatikong magsama.
+settings.convert_succeed = Na-convert na ang mirror sa isang regular na repositoryo.
+settings.convert_fork = I-convert sa regular na repositoryo
+settings.webhook.test_delivery = Subukan ang pag-deliver
+settings.webhook_deletion_success = Tinanggal na ang webhook.
+settings.event_header_repository = Mga event ng repositoryo
+contributors.contribution_type.filter_label = Uri ng ambag:
+contributors.contribution_type.commits = Mga commit
+settings.enter_repo_name = Ilagay ang may-ari at pangalan ng repositoryo nang eksakto na pinapakita:
+settings.transfer_abort_success = Matagumpay na nakansela ang paglipat ng repositoryo kay/sa %s.
+settings.transfer_desc = Ilipat ang repositoryo sa isang user o organisasyon na kung saan may tagapangasiwa ka na pahintulot.
+settings.confirmation_string = String ng kumpirmasyon
+settings.event_release = Paglabas
+settings.event_release_desc = Na-publish, nabago, o nabura ang release sa repositoryo.
+settings.add_key_success = Nadagdag na ang deploy key na "%s".
+wiki.page_already_exists = Umiiral na ang pahina ng wiki na may katulad na pangalan.
+settings.external_wiki_url_desc = Ire-redirect ang mga bisita sa URL ng panlabas na wiki kapag pipindutin ang wiki tab.
+settings.use_external_issue_tracker = Gumamit ng panlabas na tagasubaybay na isyu
+settings.wiki_desc = I-enable ang wiki ng repositoryo
+settings.trust_model.default.desc = Gamitin ang default na modelo ng pagkatiwala ng repositoryo para sa installation na ito.
+settings.add_webhook.invalid_path = Hindi maaaring maglaman ang path ng parte na "." o ".." o walang laman na string. Hindi maaaring magsimula o magtapos sa slash.
+settings.webhook_deletion = Tanggalin ang webhook
+settings.add_webhook.invalid_channel_name = Hindi maaaring walang laman ang pangalan ng channel ng webhook at hindi maaaring maglaman lang ng # na character.
+pulls.update_branch = I-update ang branch sa pamamagitan ng pagsama
+pulls.status_checks_show_all = Ipakita ang lahat ng mga pagsusuri
+pulls.cmd_instruction_checkout_title = I-checkout
+pulls.cmd_instruction_checkout_desc = Sa iyong repositoryo ng proyekto, mag-check out ng bagong branch at subukan ang mga pagbabago.
+activity.title.unresolved_conv_1 = %d hindi naresolbang paguusap
+settings.mirror_settings.docs.no_new_mirrors = Ang iyong repositoryo ay nagsasalamin ng mga pagbabago sa o mula sa ibang repositoryo. Mangyaring tandaan na hindi ka makakagawa ng mga bagong salamin sa oras na ito.
+settings.mirror_settings.push_mirror.edit_sync_time = I-edit ang pagitan ng mirror sync
+settings.sync_mirror = I-synchronize ngayon
+settings.issues_desc = I-enable ang tagasubaybay ng isyu ng repositoryo
+settings.reindex_requested = Nahiling ang reindex
+settings.releases_desc = I-enable ang mga paglalabas sa repositoryo
+settings.wiki_rename_branch_main_desc = Baguhin ang pangalan ng branch na ginagamit ng internal ng Wiki sa "%s". Ang pagbabago na ito ay permanente at hindi mababawi.
+settings.secret = Sikreto
+settings.slack_icon_url = URL ng icon
+settings.event_desc = I-trigger sa:
+settings.event_push_desc = Git push sa repositoryo.
+settings.web_hook_name_telegram = Telegram
+settings.web_hook_name_larksuite_only = Lark Suite
+settings.web_hook_name_wechatwork = WeCom (Wechat Work)
+settings.web_hook_name_feishu_only = Feishu
+settings.branches = Mga branch
+pulls.status_checks_failure = Nabigo ang ilang mga pagsusuri
+pulls.auto_merge_canceled_schedule = Nakansela ang awtomatikong pagsasama para sa hiling sa paghila na ito.
+settings.confirm_wiki_branch_rename = Baguhin ang pangalan ng wiki branch
+settings.wiki_delete_desc = Permanente ang pagbura ng data ng wiki ng repositoryo at hindi mababawi.
+settings.event_delete = Burahin
+settings.pulls.default_allow_edits_from_maintainers = Payagan ang mga pagbabago sa mga tagapagpanatili bilang default
+settings.admin_code_indexer = Taga-index ng code
+settings.pulls.default_delete_branch_after_merge = Burahin ang branch ng hiling sa paghila pagkatapos ng pagsasama bilang default
+settings.trust_model.default = Default na modelo ng pagkatiwala
+settings.trust_model.collaborator.desc = Ang mga angkop na signature mula sa mga katulong sa repositoryo na ito ay mamarkahan bilang "pinagkakatiwalaan" - (kung tumutugma ito sa taga-commit o hindi). Kung hindi, ang mga angkop na signature ay mamarkahan bilang "hindi pinagkakatiwalaan" kapag tumutugma ang signature sa taga-commit at "hindi tumutugma" kapag hindi.
+settings.trust_model = Modelo ng pagkatiwala ng signature
+activity.commit = Mga aktibidad sa commit
+settings.mirror_settings.pushed_repository = Natulak na repositoryo
+settings.mirror_settings.direction = Direksyon
+settings.tracker_issue_style = Number Format ng panlabas na tagasubaybay ng isyu
+settings.web_hook_name_feishu = Feishu / Lark Suite
+pulls.agit_explanation = Ginawa gamit ang AGit workflow. Nagbibigay daan ang AGit sa mga kontribyutor na magmungkahi ng mga pagbabago gamit ang "git push" nang hindi gumawa ng fork o bagong branch.
+milestones.filter_sort.latest_due_date = Pinakamalayong takdang petsa
+activity = Aktibidad
+activity.unresolved_conv_desc = Ang mga kamakailang nabagong isyu at hiling sa paghila na ito ay hindi pa naresolba.
+signing.wont_sign.approved = Hindi isa-sign ang pagsama na ito dahil hindi nakaapruba ang PR.
+ext_wiki = Panlabas na Wiki
+milestones.filter_sort.name = Pangalan
+signing.wont_sign.parentsigned = Hindi isa-sign ang commit na ito dahil hindi naka-sign ang parent commit.
+signing.wont_sign.commitssigned = Hindi isa-sign ang pagsama na ito dahil hindi naka-sign ang lahat ng mga nauugnay na commit.
+pulls.outdated_with_base_branch = Ang branch na ito ay hindi napapanahon sa base branch
+milestones.clear = I-clear
+settings.mirror_settings.docs.doc_link_title = Paano ako mag-mirror ng mga repositoryo?
+settings.pull_mirror_sync_quota_exceeded = Nalagpasan ang quota, hindi hihila ng mga pagbabago.
+settings.mirror_settings.push_mirror.none_ssh = Wala
+settings.mirror_settings.push_mirror.copy_public_key = Kopyahin ang publikong key
+pulls.delete_after_merge.head_branch.is_protected = Ang head branch na gusto mong burahin ay isang pinoprotektahang branch at hindi maaaring burahin.
+pulls.delete_after_merge.head_branch.is_default = Ang head branch na gusto mong burahin ay ang default branch at hindi maaaring burahin.
+issues.num_reviews_few = %d mga pagsusuri
+issues.num_reviews_one = %d pagsusuri
+diff.image.swipe = I-swipe
+release.stable = Stable
+tag.create_tag_operation = Gumawa ng tag
+settings.lfs_pointers.found = Nakahanap ng %d (mga) blob pointer - %d naka-associate, %d hindi naka-associate (%d nawawala sa store)
+diff.hide_file_tree = Itago ang file tree
+release.draft = Draft
+release.compare = Ikumpara
+diff.show_file_tree = Ipakita ang file tree
+settings.lfs_noattribute = Walang lockable attribute ang path na ito sa default branch
+settings.tags = Mga tag
+release.prerelease_desc = Markahan bilang pre-release
+branch.download = I-download ang branch na "%s"
+branch.included = Kasama
+settings.edit_protected_branch = I-edit
+settings.lfs_invalid_lock_directory = Hindi makandado ang direktoryo: %s
+settings.lfs_pointers.sha = Hash ng blob
+diff.comment.add_single_comment = Magdagdag ng iisang komento
+diff.comment.placeholder = Mag-iwan ng komento
+release.detail = Mga detalye sa release
+release.tags = Mga tag
+release.title_empty = Hindi maaaring walang laman ang paksa.
+branch.included_desc = Ang branch na ito ay kabilang ng default branch
+release.source_code = Source code
+release.edit_subheader = Inaayos ng mga release ang mga bersyon ng proyekto.
+diff.file_before = Bago
+release.cancel = Kanselahin
+release.tag_name_invalid = Hindi wasto ang pangalan ng tag.
+release.tag_name_protected = Nakaprotekta ang pangalan ng tag.
+settings.protect_invalid_status_check_pattern = Hindi wastong pattern ng pagsusuri ng estado: "%s".
+settings.protect_no_valid_status_check_patterns = Walang mga wastong pattern ng pagsusuri ng estado.
+settings.dismiss_stale_approvals = I-dismiss ang mga lipas na pagapruba
+settings.protect_approvals_whitelist_enabled_desc = Ang mga pagsusuri lang mula sa mga naka-whitelist na user o koponan ang mabibilang sa mga kinakailangang pag-apruba. Kung walang whitelist ng pag-apruba, binibilang ang mga review mula sa sinumang may write access sa mga kinakailangang pag-apruba.
+settings.ignore_stale_approvals = Huwag pansinin ang mga lipas na pagapruba
+settings.protect_unprotected_file_patterns = Mga hindi nakaprotektang file pattern (hinihiwalay gamit ng semicolon ";")
+settings.protected_branch_deletion = Burahin ang branch protection
+settings.matrix.homeserver_url = URL ng homeserver
+settings.unarchive.header = I-unarchive ang repo na ito
+release.target = Target
+diff.file_image_height = Taas
+diff.file_byte_size = Laki
+topic.done = Tapos na
+topic.count_prompt = Hindi ka maaaring pumili ng higit sa 25 mga topic
+settings.lfs_lock_file_no_exist = Hindi umiiral ang kinandadong file sa default na branch
+release.publish = I-publish ang release
+branch.name = Pangalan ng branch
+error.csv.invalid_field_count = Hindi ma-render ang file dahil may mali itong numero ng mga field sa linya %d.
+diff.download_patch = I-download ang patch file
+release.tag_helper_new = Bagong tag. Gagawin ang tag na ito mula sa target.
+settings.lfs = LFS
+branch.delete_desc = Permanente ang pagbura ang branch. Bagaman na ang binurang branch ay magpapatuloy na umiral sa maikling oras bago ito talagang matanggal, HINDI ito mababawi sa karamihan ng mga kaso. Magpatuloy?
+branch.restore = I-restore ang branch na "%s"
+branch.delete_html = Burahin ang branch
+settings.archive.success = Matagumpay na na-archive ang repo.
+settings.lfs_pointers.inRepo = Sa repo
+settings.lfs_pointers.exists = Umiiral sa store
+diff.show_unified_view = Unified na view
+diff.whitespace_ignore_all_whitespace = Huwag pansinin ang whitespace kapag nagkukumpara ng mga linya
+release.new_subheader = Inaayos ng mga release ang mga bersyon ng proyekto.
+settings.block_on_official_review_requests_desc = Hindi magiging posible ang pagsasama kapag may mga opisyal na hiling sa pagsuri, kahit na may sapat na pagapruba.
+settings.block_outdated_branch_desc = Hindi magiging posible ang pagsasama kung nalilipas ang head branch sa base branch.
+settings.block_rejected_reviews_desc = Hindi magiging posible ang pagsasama kapag may mga hiniling ng pagbabago ang mga opisyal na tagasuri, kahit na may sapat na pagapruba.
+settings.block_on_official_review_requests = Harangan ang merge sa opisyal na hiling sa pagsuri
+settings.tags.protection.allowed = Pinapayagan
+settings.lfs_delete_warning = Ang pagbura ng LFS file ay maaaring magdulot ng mga "object does not exist" na error sa checkout. Sigurado ka ba?
+settings.protected_branch_required_approvals_min = Hindi maaaring negatibo ang mga kinakailangang pagapruba.
+settings.lfs_lock_path = File path na kakandaduhinโฆ
+settings.lfs_force_unlock = Pilitin ang pag-unlock
+settings.lfs_pointers.accessible = Naa-access ng user
+diff.show_diff_stats = Ipakita ang mga stats
+release.releases = Mga release
+settings.protect_merge_whitelist_committers_desc = Payagan lamang ang mga naka-whitelist na user at koponan na magsama ng mga hiling sa paghila sa branch na ito.
+settings.protect_merge_whitelist_users = Mga naka-whitelist na user para sa pagsasama
+settings.protect_merge_whitelist_teams = Mga naka-whitelist na koponan para sa pagsasama
+settings.protect_check_status_contexts = I-enable ang pagsusuri ng estado
+settings.protect_status_check_patterns = Mga pattern sa pagsusuri ng estado
+settings.protect_status_check_patterns_desc = Ilagay ang mga pattern para i-specify kung aling mga pagsusuri ng estado na kailangang magpasa bago maisama ang mga branch sa isang branch na tumutugma sa rule na ito. Nagse-specify ang bawat linya ng pattern. Hindi maaaring walang laman ang mga pattern.
+settings.protect_check_status_contexts_list = Mga pagsusuri ng estado na nahanap sa huling linggo para sa repositoryo na ito
+diff.generated = na-generate
+branch.confirm_create_branch = Gumawa ng branch
+release.save_draft = I-save ang draft
+diff.file_suppressed_line_too_long = Napiligilan ang file diff dahil ang masyadong mahaba ang isa o ilang mga linya
+settings.lfs_pointers.associateAccessible = I-associate ang %d mga naa-access na OID
+settings.rename_branch = Palitan ang pangalan ng branch
+diff.download_diff = I-download ang diff file
+diff.bin_not_shown = Hindi pinapakita ang binary file.
+diff.comment.start_review = Magsimula ng pagsusuri
+release.message = Ilarawan ang paglabas na ito
+release.prerelease_helper = Markahan ang release na ito bilang hindi angkop para sa paggamit sa produksyon.
+release.edit_release = I-update ang release
+settings.tags.protection = Proteksyon sa tag
+settings.protect_check_status_contexts_desc = Kailanganin na pumasa ang pagsusuri ng estado bago isama. Kapag naka-enable, ang mga commit ay dapat itulak muna sa isa pang branch, at direktang isama o itulak sa branvh na tumutugma sa rule na ito pagkatapos na magpasa ang mga pagsusuri ng estado. Kapag walang natugma na context, dapat matagumpay ang huling commit hindi alintana sa kontexto.
+settings.protect_required_approvals_desc = Payagan lamang ang pagsasama ng hiling sa paghila na may sapat na positibong pagsusuri.
+settings.protect_approvals_whitelist_enabled = I-restrict ang mga pagapruba sa mga naka-whitelist na user o koponan
+settings.protect_approvals_whitelist_teams = Mga naka-whitelist na koponan para sa pagsusuri
+settings.remove_protected_branch_failed = Nabigo ang pagtanggal ng branch protection rule na "%s".
+settings.block_rejected_reviews = Harangan ang merge sa mga tinanggihang pagsusuri
+settings.choose_branch = Pumili ng branchโฆ
+settings.tags.protection.allowed.users = Mga pinapayagang user
+settings.tags.protection.allowed.teams = Mga pinapayagang koponan
+settings.tags.protection.create = Magdagdag ng rule
+settings.tags.protection.none = Walang mga nakaprotektang tag.
+settings.chat_id = ID ng chat
+settings.matrix.message_type = Uri ng mensahe
+settings.tags.protection.allowed.noone = Walang sinuman
+settings.archive.header = I-archive ang repo na ito
+settings.archive.text = Ang pag-archive ng repo ay gagawin itong buo na read-only. Itatago ito sa dashboard. Walang tao (kahit ikaw rin!) ay makakagawa ng bagong commit, o magbukas ng mga isyu o hiling sa paghila.
+settings.archive.error = May naganap na error habang sinusubukang i-archive ang repo. Tignan ang log para sa mga detalye.
+settings.archive.error_ismirror = Hindi ka makaka-archive ng naka-mirror na repo.
+settings.unarchive.button = I-unarchive ang repo
+settings.unarchive.text = Ang pag-unarchive ng repo ay ibabalik ang kakayahang makatanggap ng mga commit at pagtulak, pati na rin ang mga bagong isyu at hiling sa paghila.
+settings.unarchive.success = Matagumpay na na-unarchive ang repo.
+settings.update_avatar_success = Nabago na ang avatar ng repositoryo.
+settings.lfs_no_lfs_files = Walang mga LFS file na nakaimbak sa repositoryo na ito
+settings.lfs_lfs_file_no_commits = Walang mga commit na nahanap para sa LFS file na ito
+settings.lfs_delete = Burahin ang LFS file na may OID na %s
+settings.lfs_findpointerfiles = Maghanap ng mga pointer file
+settings.lfs_locks = Mga kandado
+settings.lfs_invalid_locking_path = Hindi wastong path: %s
+settings.lfs_lock_already_exists = Umiiral na ang kandado: %s
+settings.lfs_lock = Kandado
+settings.lfs_locks_no_locks = Walang mga kandado
+settings.lfs_pointers.oid = OID
+settings.rename_branch_failed_not_exist = Hindi mabago ang pangalan ng branch na %s dahil hindi ito umiiral.
+settings.rename_branch_success = Matagumpay na napalit ang pangalan ng branch na %s sa %s.
+diff.show_split_view = Split na view
+settings.rename_branch_failed_exist = Hindi mabago ang pangalan ng branch dahil umiiral ang target branch na %s.
+diff.whitespace_ignore_amount_changes = Huwag pansinin ang mga pagbabago sa bilang ng whitespace
+diff.whitespace_ignore_at_eol = Huwag pansinin ang mga pagbabago sa whitespace sa EOL
+diff.stats_desc_file = %d mga pagbabago: %d mga pagdagdag at %d mga pagtanggal
+diff.file_image_width = Haba
+diff.too_many_files = May ilang mga file na hindi pinapakita dahil masyadong maraming file ay nabago sa diff na ito
+diff.vendored = naka-vendor
+diff.comment.add_line_comment = Magdagdag ng komento sa linya
+diff.comment.markdown_info = Sinusuportahan ang pag-istilio gamit ng Markdown.
+diff.comment.add_review_comment = Magdagdag ng komento
+diff.committed_by = na-commit ni/ng
+diff.image.side_by_side = Magkatabi
+diff.image.overlay = I-overlay
+releases.desc = Subaybayan ang mga bersyon at pag-download ng proyekto.
+release.new_release = Bagong release
+release.prerelease = Pre-release
+release.edit = I-edit
+release.ahead.target = sa %s noong release na ito
+tag.ahead.target = sa %s noong sa tag na ito
+release.tag_helper = Pumili ng umiiral na tag o gumawa ng bagong tag.
+release.tag_helper_existing = Umiiral na tag.
+release.delete_tag = Burahin ang tag
+release.deletion_success = Binura na ang release.
+release.deletion_tag_success = Nabura na ang tag na ito.
+release.tag_name_already_exist = Umiiral na ang release na may pangalan ng tag na ito.
+release.tag_already_exist = Umiiral na ang pangalan ng tag na ito.
+release.download_count_one = %s download
+release.download_count_few = %s mga download
+release.tags_for = Mga tag para sa %s
+release.system_generated = Awtomatikong na-generate ang attachment na ito.
+release.type_attachment = Attachment
+release.type_external_asset = External na asset
+release.asset_name = Pangalan ng asset
+release.asset_external_url = Panlabas a URL
+release.add_external_asset = Magdagdag ng external na asset
+branch.deletion_success = Binura na ang branch na "%s".
+branch.deletion_failed = Nabigong burahin ang branch na "%s".
+branch.tag_collision = Hindi magagwa ang branch na "%s" bilang tag na may tulad na pangalan na umiiral sa repositoryo.
+branch.restore_success = Na-restore ang branch na "%s".
+branch.restore_failed = Nabigong i-restore ang branch na "%s".
+branch.default_deletion_failed = Default branch ang "%s". Hindi ito mabubura.
+branch.rename = Palitan ang pangalan ng branch na "%s"
+branch.create_new_branch = Gumawa ng branch mula sa branch:
+branch.warning_rename_default_branch = Pinapalitan mo ang pangalan ng default branch.
+branch.rename_branch_to = Palitan ang pangalan ng "%s" sa:
+branch.create_branch_operation = Gumawa ng branch
+branch.new_branch = Gumawa ng bagong branch
+branch.renamed = Napalitan ang pangalan ng branch na %s sa %s.
+tag.create_tag = Gumawa ng tag na %s
+tag.confirm_create_tag = Gumawa ng tag
+tag.create_tag_from = Gumawa ng tag mula sa "%s"
+tag.create_success = Ginawa na ang tag na "%s".
+topic.manage_topics = Ipamahala ang mga topic
+find_file.no_matching = Walang nahanap na tumutugmang file
+error.csv.too_large = Hindi ma-render ang file dahil masyado itong malaki.
+settings.protect_status_check_matched = Natugma
+settings.merge_style_desc = Mga istilio ng pagsasama
+settings.archive.tagsettings_unavailable = Hindi available ang mga setting ng tag sa mga naka-archive repo.
+settings.archive.mirrors_unavailable = Hindi available ang mga mirror sa mga naka-archive na repo.
+settings.protect_required_approvals = Mga kinakailangang pagapruba
+diff.load = I-load ang diff
+release.releases_for = Mga release para sa %s
+release.add_tag = Gumawa ng tag
+branch.create_branch = Gumawa ng branch na %s
+branch.deleted_by = Binura ni/ng %s
+diff.browse_source = I-browse ang source
+diff.git-notes = Mga tala
+diff.data_not_available = Hindi available ang nilalaman ng diff
+diff.options_button = Mga opsyon sa diff
+diff.commit = commit
+settings.lfs_findcommits = Maghanap ng mga commit
+settings.lfs_filelist = Mga naimbak na LFS file sa repositoryo
+branch.branch_already_exists = Umiiral na ang branch na "%s" sa repositoryo na ito.
+branch.create_success = Ginawa na ang branch na "%s".
+settings.require_signed_commits = Kailanganin ang mga naka-sign na commit
+settings.block_outdated_branch = Harangan ang merge kapag luma na ang hiling sa paghila
+settings.default_branch_desc = Pumili ng default repository branch para sa mga hiling sa paghila at code commit:
+settings.default_merge_style_desc = Default na istilio ng pagsasama
+settings.matrix.room_id_helper = Ang Room ID ay makukuha sa Element web client > Mga setting sa room > Advanced > Internal room ID. Halimbawa: %s.
+settings.archive.button = I-archive ang repo
+diff.show_more = Magpakita pa
+settings.bot_token = Token ng bot
+diff.protected = Nakaprotekta
+diff.git-notes.add = Magdagdag ng tala
+diff.git-notes.remove-header = Tanggalin ang tala
+diff.git-notes.remove-body = Tatanggalin ang tala na ito.
+diff.review.comment = Komento
+release.ahead.commits = %d mga commit
+release.tag_name = Pangalan ng tag
+release.title = Paksa ng release
+release.delete_release = Burahin ang release
+release.deletion = Burahin ang release
+release.downloads = Mga download
+settings.enforce_on_admins = Ipatupad ang rule na ito sa mga tagapangasiwa ng repositoryo
+settings.dismiss_stale_approvals_desc = Kapag ang mga bagong commit na binabago ang nilalaman ng hiling sa paghila ay naitulak sa branch, idi-dismiss ang mga lumang pagapruba.
+settings.enforce_on_admins_desc = Hindi maba-bypass ng mga tagapangasiwa ang rule na ito.
+settings.protected_branch_deletion_desc = Ang pag-disable ng branch protection ay pinapayagan ang mga user na may pahintulot na pagbabago na magtulak sa branch na ito. Magpatuloy?
+settings.rename_branch_failed_protected = Hindi mababago ang pangalan ng branch na %s dahil ito ay isang nakaprotektang branch.
+editor.add_tmpl.filename = Pangalan ng file
+settings.protect_approvals_whitelist_users = Mga naka-whitelist na tagasuri
+settings.protect_protected_file_patterns_desc = Ang mga nakaprotektang file ay hindi pinapayagan na direktang mabago kahit na may karapatan ang user na magdagdag, i-edit, o burahin ang mga file sa branch na ito. Ang mga maraming pattern ay maaaring mahiwalay gamit ng semicolon (";"). Tignan ang %[2]s na dokumentasyon para sa pattern syntax. Mga halimbawa: .drone.yml
, /docs/**/*.txt
.
+branch.delete_branch_has_new_commits = Hindi maaaring burahin ang branch na "%s" dahil may mga bagong commit na nadagdag matapos ang pagsasama.
+settings.protect_unprotected_file_patterns_desc = Ang mga hindi nakaprotektang file ay pinapayagan na direktang mabago kung may write access ang user, bina-bypass ang restriction ng pagtulak. Ang mga maraming pattern ay maaaring mahiwalay gamit ng semicolon (";"). Tignan ang %[2]s na dokumentasyon para sa pattern syntax. Mga halimbawa: .drone.yml
, /docs/**/*.txt
.
+settings.no_protected_branch = Walang mga nakaprotekta na branch.
+settings.protected_branch_required_rule_name = Kinakailangan na pangalan ng rule
+settings.protected_branch_duplicate_rule_name = Mayroon nang rule para sa set ng mga branch na ito
+release.invalid_external_url = Hindi wastong panlabas na URL: "%s"
+settings.matrix.access_token_helper = Inirerekonenda na mag-setup ng dedicated na Matrix account para dito. Ang access token ay makukuha sa Element Web client (sa pribadong/incognito tab) > User menu (sa itaas kaliwa) > Lahat ng mga setting > Tulong at Tungkol Sa > Advanced > Access Token (sa ibaba ng Homeserver URL). Isara ang incognito tab (ang pag-log out ay magpapawalang-bisa sa token).
+branch.create_from = mula "%s"
+settings.archive.branchsettings_unavailable = Hindi available ang mga setting ng branch sa mga naka-archive na repo.
+diff.file_suppressed = Napigilan ang file diff dahil masyado itong malaki
+release.deletion_desc = Ang pagbura ng release ay binubura lang sa Forgejo. Hindi nito aapektuhan ang Git tag, ang nilalaman ng repositoryo o ang history nito. Magpatuloy?
+error.broken_git_hook = Mukhang sira ang mga Git hook sa repositoryo na ito. Mangyaring sundan ang dokumentasyon para ayusin sila, at magtulak ng mga ilang commit para i-refresh ang status.
+settings.unarchive.error = May naganap na error habang sinusubukang i-unarchive ang repo. Tignan ang log para sa mga detalye.
+branch.branch_name_conflict = Sumasalungat ang pangalan ng branch na "%s" sa umiiral na branch na "%s".
+branch.protected_deletion_failed = Nakaprotekta ang branch na "%s". Hindi ito mabubura.
+diff.file_after = Pagkatapos
+release.deletion_tag_desc = Buburahin ang tag na ito sa repositoryo. Mapapanatiling hindi nabago ang nilalaman at kasaysayan ng repositoryo. Magpatuloy?
+topic.format_prompt = Dapat magsimula ang mga topic ng numero o letra, maaaring magsama ng mga dash ("-") at dot ("."), maaaring hanggang sa 35 na character na haba. Kailangang lowercase ang mga character.
+branch.new_branch_from = Gumawa ng bagong branch mula sa "%s"
+error.csv.unexpected = Hindi ma-render ang file na ito dahil naglalaman ito ng hindi inaasahang character sa linyang %d at column %d.
+settings.ignore_stale_approvals_desc = Huwag ibilang ang mga pagapruba na ginawa sa mga lumang commit (mga lipas na pagsusuri) sa kung gaano karaming pagapruba ang mayroon sa PR na ito. Walang kinalaman kung ang mga lipas na pagsusuri ay na-dismiss na.
+settings.require_signed_commits_desc = Tanggihan ang mga pagtulak sa branch na ito kung hindi sila naka-sign on hindi mapatunayan.
+settings.protect_branch_name_pattern = Pattern ng nakaprotektang pangalan ng branch
+settings.protect_branch_name_pattern_desc = Mga pattern ng nakaprotektang pangalan ng branch. Tignan ang dokumentasyon para sa pattern syntax. Halimbawa: main, release/**
+settings.protect_patterns = Mga pattern
+settings.protect_protected_file_patterns = Mga pattern ng nakaprotektang file (hinihiwalay gamit ang semicolon ";")
+settings.update_protect_branch_success = Binago na ang branch protection rule na "%s".
+settings.remove_protected_branch_success = Tinanggal ang branch protection rule na "%s".
+settings.tags.protection.pattern = Pattern ng tag
+settings.tags.protection.pattern.description = Maari kang gumamit ng iisang pangalan o glob pattern o regular expression para magtugma ng maraming tag. Magbasa pa sa guide ng mga nakaprotektang tag .
+settings.thread_id = ID ng thread
+settings.matrix.room_id = ID ng room
+diff.has_escaped = May mga nakatagong Unicode character ang linya na ito
+branch.delete_head = Burahin
+branch.delete = Burahin ang branch na "%s"
+release.add_tag_msg = Gamitin ang paksa at nilalaman ng release bilang mensahe ng tag.
+release.hide_archive_links = Itago ang mga awtomatikong na-generate na archive
+release.hide_archive_links_helper = Itago ang awtomatikong na-generate na source code archive para sa release na ito. Halimbawa, kung maga-upload ka ng sarili mo.
+branch.already_exists = Umiiral na ang branch na may pangalan na "%s".
+diff.bin = BIN
+settings.default_update_style_desc = Ang default na istilio na gagamitin sa pag-update ng mga hiling sa paghila na nalilipas sa base branch.
+pulls.sign_in_require = Mag-sign in para gumawa ng bagong hiling sa paghila.
+new_from_template = Gumamit ng template
+new_from_template_description = Maari kang pumili ng umiiral na repository template sa instansya na ito at i-apply ang mga setting nito.
+new_advanced = Mga advanced na setting
+new_advanced_expand = I-click para i-expand
+auto_init_description = Simulan ang kasaysayan ng Git gamit ang README at opsyonal na magdagdag ng mga lisensya at .gitignore na file.
+issues.reaction.add = Magdagdag ng reaksyon
+issues.reaction.alt_few = Nag-react si %[1]s ng %[2]s.
+issues.reaction.alt_many = Sina %[1]s at %[2]d pang iba ay nag-react ng %[3]s.
+issues.reaction.alt_remove = Magtanggal ng %[1]s reaksyon mula sa komento.
+issues.reaction.alt_add = Magdagdag ng %[1]s reaksyon sa komento.
+issues.context.menu = Menu ng komento
+summary_card_alt = Pangkalahatang-ideyang card ng repositoryo na %s
+release.summary_card_alt = Pangkalahatang-ideyang card ng isang release na nakapamagat na "%s" sa repositoryo na %s
+editor.commit_email = Email ng commit
+archive.pull.noreview = Naka-archive ang repositoryong ito. Hindi ka makakasuri ng mga hiling sa paghila.
+commits.view_single_diff = Tignan ang mga pagbabago sa file na ito na ipinakilala sa commit na ito
+pulls.editable = Nababago
+pulls.editable_explanation = Pinapayagan ng hiling sa paghila na ito ang mga pagbabago mula sa mga tagapangasiwa. Maaari kang direktang mag-ambag dito.
+issues.reopen.blocked_by_user = Hindi mo maaaring buksan muli ang isyung ito dahil hinarang ka ng may-ari ng repositoryo o ng may-akda ng isyung ito.
+pulls.comment.blocked_by_user = Hindi ka maaaring magkomento sa hiling sa paghila na ito dahil hinarang ka ng may-ari ng repositoryo o ng may-akda ng hiling sa paghila.
+issues.filter_no_results = Walang mga resulta
+issues.filter_no_results_placeholder = Subukang ayusin ang iyong mga filter sa paghahanap.
[search]
-commit_kind = Maghanap ng mga commit...
+commit_kind = Maghanap ng mga commitโฆ
keyword_search_unavailable = Kasalukuyang hindi available ang paghahanap sa pamamagitan ng keyword. Mangyaring makipag-ugnayan sa tagapangasiwa ng site.
-search = Maghanap...
+search = Maghanapโฆ
type_tooltip = Uri ng paghahanap
-fuzzy = Fuzzy
+fuzzy = Humigit-kumulang
fuzzy_tooltip = Samahan ang mga resulta na tumutugma rin sa search term nang malapit
match = Tugma
match_tooltip = Samahan lang ang mga resulta na tumutugma sa eksaktong search term
-repo_kind = Maghanap ng mga repo...
-user_kind = Maghanap ng mga user...
-org_kind = Maghanap ng mga org...
-team_kind = Maghanap ng mga koponan...
-code_kind = Maghanap ng code...
+repo_kind = Maghanap ng mga repoโฆ
+user_kind = Maghanap ng mga userโฆ
+org_kind = Maghanap ng mga orgโฆ
+team_kind = Maghanap ng mga koponanโฆ
+code_kind = Maghanap ng codeโฆ
code_search_unavailable = Kasalukuyang hindi available ang paghahanap ng code. Mangyaring makipag-ugnayan sa tagapangasiwa ng site.
-package_kind = Maghanap ng mga pakete...
-project_kind = Maghanap ng mga proyekto...
-branch_kind = Maghanap ng mga branch...
-runner_kind = Maghanap ng mga runner...
+package_kind = Maghanap ng mga packageโฆ
+project_kind = Maghanap ng mga proyektoโฆ
+branch_kind = Maghanap ng mga branchโฆ
+runner_kind = Maghanap ng mga runnerโฆ
no_results = Walang mga tumutugma na resulta na nahanap.
code_search_by_git_grep = Ang kasalukuyang mga resulta ng paghahanap ng code ay ibinibigay ng "git grep*. Maaring may mga mas magandang resulta kapag na-enable ng tagapangasiwa ng site ang Indexer ng Repositoryo.
-pull_kind = Maghanap ng mga paghila...
-issue_kind = Maghanap ng mga isyu...
+pull_kind = Maghanap ng mga paghilaโฆ
+issue_kind = Maghanap ng mga isyuโฆ
exact = Eksakto
exact_tooltip = Samahan lamang ang mga resulta na tutugma sa eksaktong search term
+union = Kaugnay
+union_tooltip = Isama ang mga resulta na tumutugma sa anumang mga nahiwalay ng whitespace na keyword
+milestone_kind = Maghanap ng mga milestoneโฆ
+regexp = RegExp
+regexp_tooltip = Bigyang-kahulugan ang termino para sa paghahanap bilang isang regular na ekspresyon
[admin]
auths.updated = Nabago
@@ -1954,22 +2866,22 @@ dashboard.stack_memory_obtained = Nakuhang stack memory
dashboard.profiling_bucket_hash_table_obtained = Mga nakuhang profiling bucket hash table
dashboard.gc_metadata_obtained = Nakuhang GC metadata
dashboard.delete_old_actions = Burahin ang lahat ng mga lumang aktibidad mula sa database
-dashboard.stop_endless_tasks = Tigilan ang mga hindi natatapos na task
-dashboard.cancel_abandoned_jobs = Kanselahin ang mga naiwang job
-dashboard.start_schedule_tasks = Simulan ang mga iskedyul task
+dashboard.stop_endless_tasks = Itigil ang mga hindi natatapos na aksyon ng task
+dashboard.cancel_abandoned_jobs = Kanselahin ang mga naiwang aksyon ng trabaho
+dashboard.start_schedule_tasks = Simulan ang mga naka-iskedyul na aksyon ng task
dashboard.sync_branch.started = Nasimulan ang pag-sync ng mga branch
dashboard.rebuild_issue_indexer = Gawin muli ang indexef ng isyu
users.restricted = Pinaghihigpitan
users.2fa = 2FA
users.repos = Mga Repo
users.send_register_notify = Abisuhan tungkol sa pagrehistro sa pamamagitan ng email
-users.is_admin = Ay tagapangasiwa
-users.is_restricted = Ay pinaghihigpitan
-users.allow_import_local = Maaring mag-import ng mga lokal na repositoryo
+users.is_admin = Tagapangasiwa na account
+users.is_restricted = Pinaghihigpitang account
+users.allow_import_local = Maaaring mag-import ng mga lokal na repositoryo
users.allow_create_organization = Makakagawa ng mga organisasyon
users.update_profile = I-update ang user account
users.delete_account = Burahin ang user account
-users.cannot_delete_self = Hindi mo maaring burahin ang sarili mo
+users.cannot_delete_self = Hindi mo maaaring burahin ang sarili mo
users.still_own_repo = Ang user na ito ay nagmamay-ari pa ng isa o higit pang mga repositoryo. Burahin o ilipat sila muna.
users.list_status_filter.is_active = Aktibo
users.list_status_filter.not_active = Hindi aktibo
@@ -2021,7 +2933,7 @@ dashboard.gc_times = Mga oras ng GC
users.list_status_filter.reset = I-reset
users.list_status_filter.not_restricted = Hindi pinaghihigpitan
config_summary = Buod
-dashboard.new_version_hint = Available na ang Forgejo %s, tumatakbo ka ng %s. Suriin ang blog para sa karagdagang detalye.
+dashboard.new_version_hint = Available na ang Forgejo %s, tumatakbo ka ng %s. Suriin ang blog para sa karagdagang detalye.
dashboard.operations = Mga operasyon ng pagpapanatili
dashboard.operation_run = Patakbuhin
dashboard = Dashboard
@@ -2040,15 +2952,15 @@ dashboard.delete_old_actions.started = Nasimula na ang burahin ang lahat ng mga
dashboard.update_checker = Tagasuri ng update
dashboard.delete_old_system_notices = Burahin ang lahat ng mga lumang paunawa ng sistema mula sa database
dashboard.gc_lfs = I-garbage collect ang mga LFS meta object
-dashboard.stop_zombie_tasks = Tigilan ang mga zombie task
+dashboard.stop_zombie_tasks = Itigil ang mga zombie action task
users.user_manage_panel = Ipamahala ang mga user account
-users.new_account = Gumawa ng User Account
+users.new_account = Gumawa ng user account
users.auth_login_name = Pangalan ng sign-in authentication
users.password_helper = Iwanang walang laman ang password upang panatilihing hindi nabago.
users.max_repo_creation = Pinakamataas na numero ng mga repositoryo
users.max_repo_creation_desc = (Ilagay ang -1 para gamitin ang global na default na limitasyon.)
-users.is_activated = Naka-activate ang User Account
-users.prohibit_login = I-disable ang pag-sign in
+users.is_activated = Naka-activate na account
+users.prohibit_login = Sinuspending account
emails.email_manage_panel = Ipamahala ang mga email ng user
self_check = Pansariling pagsusuri
dashboard.total_gc_pause = Kabuuang GC pause
@@ -2098,9 +3010,9 @@ auths.new = Magdagdag ng source ng authentikasyon
auths.attribute_surname = Attribute ng surname
packages.version = Bersyon
systemhooks.add_webhook = Magdagdag ng Sistemang Webhook
-systemhooks.desc = Awtomatikong gumagawa ang mga Webhook ng mga HTTP POST request sa isang server kapag nag-trigger ang ilang partikular na kaganapan sa Forgejo. Ang mga webhook na tinukoy dito ay kikilos sa lahat ng mga repositoryo sa system, kaya mangyaring isaalang-alang ang anumang mga implikasyon ng performance na maaaring mayroon ito. Magbasa pa sa guide ng mga webhook .
+systemhooks.desc = Awtomatikong gumagawa ang mga Webhook ng mga HTTP POST request sa isang server kapag nag-trigger ang ilang partikular na kaganapan sa Forgejo. Ang mga webhook na tinukoy dito ay kikilos sa lahat ng mga repositoryo sa system, kaya mangyaring isaalang-alang ang anumang mga implikasyon ng performance na maaaring mayroon ito. Magbasa pa sa guide ng mga webhook .
packages.cleanup.success = Matagumpay na nalinis ang na-expire na data
-defaulthooks.desc = Awtomatikong gumagawa ang mga Webhook ng mga HTTP POST request sa isang server kapag nag-trigger ang ilang partikular na kaganapan sa Forgejo. Ang mga webhook na tinukoy dito ay mga default at makokopya sa lahat ng mga bagong repositoryo. Magbasa pa sa guide ng mga webhook .
+defaulthooks.desc = Awtomatikong gumagawa ang mga Webhook ng mga HTTP POST request sa isang server kapag nag-trigger ang ilang partikular na kaganapan sa Forgejo. Ang mga webhook na tinukoy dito ay mga default at makokopya sa lahat ng mga bagong repositoryo. Magbasa pa sa guide ng mga webhook .
packages.published = Na-publish
defaulthooks = Mga default webhook
systemhooks.update_webhook = I-update ang Sistemang Webhook
@@ -2120,7 +3032,7 @@ packages.cleanup = Linisin ang na-expire na data
orgs.new_orga = Bagong organisasyon
repos.repo_manage_panel = Ipamahala ang mga repositoryo
repos.unadopted = Mga unadopted na repositoryo
-repos.unadopted.no_more = Wala nang mga unadopted na repositoryo na nahanap
+repos.unadopted.no_more = Wala nang mga unadopted na repositoryo na nahanap.
repos.owner = May-ari
repos.lfs_size = Laki ng LFS
packages.package_manage_panel = Ipamahala ang mga package
@@ -2151,7 +3063,7 @@ config.ssh_listen_port = Listen port
config.ssh_keygen_path = Path ng keygen ("ssh-keygen")
config.ssh_key_test_path = Path ng key test
auths.verify_group_membership = Patunayan ang membership ng grupo sa LDAP (iwanang walang laman ang filter para i-skip)
-config.allow_only_external_registration = Payagan lamang ang pagrehistro sa pamamagitan ng mga panlabas na Serbisyo
+config.allow_only_external_registration = Payagan lamang ang pagrehistro sa pamamagitan ng mga panlabas na serbisyo
config.allow_only_internal_registration = Payagan lamang ang pagrehistro sa pamamagitan ng Forgejo
auths.search_page_size = Laki ng pahina
auths.filter = Filter ng user
@@ -2191,6 +3103,226 @@ notices.delete_selected = Burahin ang pinili
notices.view_detail_header = Mga detalye ng paunawa
notices.inverse_selection = Baliktarin ang pagpili
config.app_slogan = Slogan ng instansya
+auths.oauth2_provider = Tagapagbigay ng OAuth2
+auths.oauth2_tokenURL = URL ng token
+auths.oauth2_authURL = URL ng Authorize
+auths.oauth2_clientID = ID ng kliyente (Key)
+auths.enable_ldap_groups = I-enable ang mga LDAP group
+auths.oauth2_clientSecret = Sikreto ng Kliyente
+auths.openIdConnectAutoDiscoveryURL = URL ng OpenID Connect Auto Discovery
+auths.oauth2_use_custom_url = Gumamit ng mga custom URL sa halip ng mga default URL
+auths.group_attribute_list_users = Group attribute na naglalaman ng listahan ng mga user
+auths.user_attribute_in_group = User attribute na nakalista sa grupo
+auths.oauth2_tenant = Tenant
+auths.oauth2_scopes = Mga karagdagang scope
+auths.oauth2_required_claim_name = Kinakailangang claim name
+auths.pam_email_domain = Email domain ng PAM (opsyonal)
+auths.oauth2_icon_url = URL ng icon
+auths.oauth2_emailURL = URL ng email
+auths.skip_local_two_fa = I-skip ang lokal na 2FA
+auths.skip_tls_verify = I-skip ang pagpapatunay ng TLS
+auths.force_smtps_helper = Palaging ginagagmit ang SMTPS sa port 465. Itakda ito para pilitin ang SMTPS sa mga ibang port. (Kung hindi, gagamitin ang STARTTLS sa mga ibang port kapag sinusuportahan ng host.)
+auths.helo_hostname = Hostname ng HELO
+auths.force_smtps = Pilitin ang SMTPS
+auths.skip_local_two_fa_helper = Ang pag-iwan sa hindi nakatakda ay nangangahulugan na ang mga lokal na user na may 2FA ay kailangan pa ring pumasa sa 2FA upang mag-log on
+auths.ms_ad_sa = Mga search attribute ng MS AD
+auths.smtphost = Host ng SMTP
+auths.allowed_domains_helper = Iwanang walang laman para payagan ang lahat ng mga domain. Ihiwalay ang mga maraming domain gamit ang kuwit (",").
+auths.smtp_auth = Uri ng authentikasyon ng SMTP
+auths.pam_service_name = Pangalan ng serbisyo ng PAM
+auths.map_group_to_team = I-map ang mga LDAP group sa Mga koponan ng organisasyon (iwanang walang laman para i-skip)
+auths.map_group_to_team_removal = Tanggalin ang mga user sa mga naka-synchronize na koponan kapag hindi kasama ang user sa katumbas na LDAP group
+auths.smtpport = Port ng SMTP
+auths.allowed_domains = Mga pinapayagang domain
+auths.helo_hostname_helper = Hostname na pinapadala sa pamamagitan ng HELO. Iwanang walang laman para ipadala ang kasalukuyang hostname.
+auths.disable_helo = I-disable ang HELO
+auths.oauth2_profileURL = URL ng profile
+monitor.queue.settings.maxnumberworkers.placeholder = Kasalukuyang %[1]d
+monitor.queue.settings.remove_all_items = Tanggalin lahat
+users.block.description = Harangan ang tagagamit na ito mula sa pag-interact sa serbisyong ito sa pamamagitan ng kanilang mga account at pagbawalan ang pag-sign in.
+monitor.cron = Mga cron task
+config.mailer_sendmail_timeout = Timeout ng Sendmail
+config.disable_gravatar = I-disable ang Gravatar
+config.test_mail_failed = Nabigong magpadala ng test email sa "%s": %v
+config.mailer_use_dummy = Dummy
+monitor.process.cancel_notices = Kanselahin: %s ?
+auths.tips.oauth2.general = OAuth2 na authentication
+config.show_registration_button = Ipakita ang magrehistro na button
+config.allow_dots_in_usernames = Payagan ang mga user na gumamit ng mga dot sa kanilang mga username. Hindi inaapektuhan ang mga umiiral na account.
+config.https_only = HTTPS lamang
+auths.tip.github = Magrehistro ng bagong OAuth application sa %s
+auths.tip.gitlab_new = Magrehistro ng bagong application sa %s
+emails.delete_primary_email_error = Hindi mo maaaring burahin ang pangunahing email.
+config.provider_config = Config ng provider
+config.cache_test_slow = Matagumpay ang pagsubok ng cache, ngunit mabagal ang tugon: %s.
+config.picture_config = Configuration ng larawan at avatar
+config.disabled_logger = Naka-disable
+monitor.queue.settings.submit = I-update ang mga setting
+auths.tips = Mga tip
+config.test_mail_sent = Ang isang test email ay ipinadala kay "%s".
+monitor.process.cancel = Kanselahin ang proseso
+monitor.queues = Mga queue
+monitor.queue.exemplar = Uri ng Exemplar
+monitor.queue.numberworkers = Numero ng mga worker
+config.enable_openid_signup = I-enable ang OpenID na pansariling pagrehistro
+config.session_config = Configuration ng session
+monitor.name = Pangalan
+config.enable_captcha = I-enable ang CAPTCHA
+config.git_mirror_timeout = Timeout ng pag-update ng mirror
+config.git_max_diff_files = Pinakamataas na mga diff file na ipapakita
+config.git_gc_args = Mga argument ng GC
+config.git_migrate_timeout = Timeout ng paglipat
+config.cache_config = Configuration ng cache
+config.git_pull_timeout = Timeout ng operasyon ng paghila
+monitor.queue.settings.maxnumberworkers = Pinakamaraming numero ng worker
+monitor.queue.settings.title = Mga setting ng pool
+monitor.queue.settings.desc = Dinamikang lumalaki ang mga pool tugon sa kanilang worker queue blocking.
+auths.tip.google_plus = Kumuha ng OAuth2 client credentials mula sa Google API console sa %s
+config.mail_notify = Paganahin ang mga email notification
+config.active_code_lives = Oras ng pag-expire ng activation code
+config.reset_password_code_lives = Oras ng pag-expire ng recovery code
+config.default_keep_email_private = Itago ang mga email address bilang default
+users.organization_creation.description = Payagan ang paggawa ng mga bagong organisasyon.
+auths.delete_auth_title = Burahin ang source ng authentikasyon
+auths.delete_auth_desc = Ang pagtanggal ng authentication source ay pumipigil sa mga user na gamitin ito upang mag-sign in. Magpatuloy?
+auths.login_source_of_type_exist = Umiiral na ang authentication source na may ganitong uri.
+monitor.queue.settings.maxnumberworkers.error = Dapat numero ang pinakamaraming numero ng mga worker
+self_check.no_problem_found = Wala pang mga problema na nahanap.
+self_check.database_collation_mismatch = Inaasahan ang database na gamitin ang collation: %s
+auths.oauth2_admin_group = Group claim value para sa mga tagapangasiwa. (Opsyonal - kinakailangan ang claim name sa itaas)
+auths.tip.facebook = Magrehistro ng bagong application sa %s at idagdag ang produktong "Facebook Login"
+users.restricted.description = Payagan lamang ang interaksyon sa mga repositoryo at organisasyon kung saan ang user ay dinagdag bilang tagatulong. Iniiwasan nito ang pag-access sa publikong repositoryo sa instansya na ito.
+users.local_import.description = Payagan ang pag-import ng mga repositoryo mula sa local file system ng user. Maari itong maging isyu sa seguridad.
+emails.delete = Burahin ang Email
+emails.deletion_success = Binura na ang email address.
+auths.oauth2_required_claim_value = Kinakailangan na claim value
+auths.oauth2_group_claim_name = Claim name na nagbibigay ng mga group name para sa source. (Opsyonal)
+auths.oauth2_restricted_group = Group claim value para sa mga pinahihigpitang user (Opsyonal - kinakailangan ang claim name sa itaas)
+auths.oauth2_map_group_to_team = I-map ang mga claimed groups sa mga koponan ng organisasyon. (Opsyonal, kinakailangan ang claim name sa itaas)
+auths.sspi_auto_create_users = Awtomatikong gumawa ng mga user
+auths.sspi_auto_create_users_helper = Payagan ang SSPI auth method na awtomatikong gumawa ng mga bagong account para sa mga user na maglo-log in sa unang panahon
+auths.sspi_auto_activate_users = Awtomatikong i-activate ang mga user
+auths.sspi_auto_activate_users_helper = Payagan ang SSPI auth method na awtomatikong i-activate ang mga bagong user
+auths.sspi_strip_domain_names = Tanggalin ang mga domain name sa mga username
+auths.sspi_separator_replacement = Separator na gagamitin sa halip ng \, / at @
+auths.sspi_default_language = Default na wika ng user
+auths.sspi_default_language_helper = Default na wiki para sa mga user na awtomatikong ginawa ng SSPI auth method. Iwanang walang laman kung gusto mo na ang wika ay awtomatikong ma-detect.
+auths.tip.oauth2_provider = Tagabigay ng OAuth2
+auths.tip.nextcloud = Magrehistro nf bagong OAuth consumer sa iyong instansya gamit ang sumusunod na menu "Settings -> Security -> OAuth 2.0 client"
+auths.edit = I-edit ang source ng authentikasyon
+auths.update_success = Na-update na ang source ng authentikasyon.
+config.default_allow_only_contributors_to_track_time = Payagan lamang ang mga kontribyutor na subaybayan ang oras
+config.no_reply_address = Domain ng nakatagong email
+config.default_visibility_organization = Default na visibility para sa mga bagong organisasyon
+config.default_enable_dependencies = I-enable ang mga dependency ng isyu bilang default
+config.webhook_config = Configuration ng Webhook
+config.queue_length = Haba ng queue
+config.deliver_timeout = Timeout ng pag-deliver
+config.skip_tls_verify = I-skip ang pagpapatunay ng TLS
+config.mailer_config = Configuration ng mailer
+config.mailer_enabled = Naka-enable
+config.mailer_enable_helo = I-enable ang HELO
+config.mailer_name = Pangalan
+config.mailer_protocol = Protocol
+config.test_email_placeholder = Email (hal. bocchi@example.com)
+config.send_test_mail_submit = Magpadala
+config.oauth_config = Configuration ng OAuth
+config.oauth_enabled = Naka-enable
+config.cache_adapter = Adapter ng cache
+config.cache_interval = Pagitan ng cache
+config.cache_item_ttl = TTL ng cache item
+config.cache_test = Subukan ang Cache
+config.cache_test_failed = Nabigong i-probe ang cache: %v.
+config.session_life_time = Lifetime ng session
+config.picture_service = Serbisyo ng larawan
+config.enable_federated_avatar = I-enable ang mga naka-federate na avatar
+config.git_config = Configuration ng git
+config.git_disable_diff_highlight = I-disable ang diff syntax highlighting
+config.git_max_diff_line_characters = Pinakamataas na mga character ng diff bawat linya
+config.git_gc_timeout = Timeout on operasyon ng GC
+config.log_config = Configuration ng log
+config.logger_name_fmt = Logger: %s
+config.access_log_mode = Mode ng pag-access ng log
+config.access_log_template = Template ng access log
+config.xorm_log_sql = I-log ang SQL
+monitor.stats = Mga estado
+monitor.schedule = Iskedyul
+monitor.execute_times = Mga execution
+monitor.processes_count = %d mga proseso
+monitor.desc = Paglalarawan
+monitor.start = Oras ng pagsimula
+monitor.execute_time = Oras ng pag-execute
+monitor.process.children = Mga anak
+monitor.queue = Queue: %s
+monitor.queue.type = Uri
+monitor.queue.maxnumberworkers = Pinakamaraming numero ng worker
+monitor.queue.numberinqueue = Number sa queue
+monitor.queue.review_add = Suriin / magdagdag ng mga worker
+self_check.database_collation_case_insensitive = Gumagamit ang database ng collation %s, na isang insensitive na collation. Bagama't maaaring gumana ang Forgejo dito, maaaring may ilang bihirang kaso na hindi gumagana gaya ng inaasahan.
+auths.tips.oauth2.general.tip = Kapag nagrerehistro ng bagong OAuth2 na authentication, ang callback/redirect URL ay dapat na:
+auths.activated = Na-activate na ang source ng authentikasyon
+auths.tip.dropbox = Gumawa ng bagong application sa %s
+auths.tip.openid_connect = Gumamit ng OpenID Connect Discovery URL (/.well-known/openid-configuration) para i-specify ang mga endpoint
+monitor.process = Mga tumatakbong proseso
+monitor.stacktrace = Stacktrace
+auths.tip.yandex = Gumawa ng bagong application sa %s. Piliin ang mga sumusunod na pahintulot mula sa seksyong "Yandex.Passport API": "Access sa email address", "Access sa user avatar" at "Access sa username, pangalan at apelyido, kasarian"
+auths.tip.discord = Magrehistro ng bagong application sa %s
+config.default_enable_timetracking = I-enable ang pagsubaybay ng oras bilang default
+auths.deletion_success = Binura na ang authentication source.
+auths.login_source_exist = Umiiral na ang authentication source na "%s".
+auths.still_in_used = Ginagamit pa ang authentication source. I-convert o burahin ang mga user na gumagamit ng authentication source na ito muna.
+monitor.queue.settings.remove_all_items_done = Tinanggal na ang lahat ng mga item sa queue.
+monitor.queue.settings.changed = Na-update ang mga setting
+auths.oauth2_map_group_to_team_removal = Tanggalin ang user sa mga naka-synchronize na team kung ang user ay hindi kasama sa katumbas na groupo.
+auths.sspi_strip_domain_names_helper = Kung naka-check, ang mga domain name ay tatanggalin sa mga logon name (hal. "STARRY\kita" at "kita@example.org" ay parehong magiging "kita").
+config.cache_test_succeeded = Matagumpay ang pagsubok ng cache, nakakuha ng tugon sa %s.
+config.open_with_editor_app_help = Ang mga "Open with" editor para sa clone menu. Kung iniwang walang laman, ang default ang gagamitin. I-expand para makita ang default.
+config.set_setting_failed = Nabigo ang pagtakda ng setting na %s
+monitor.download_diagnosis_report = I-download ang ulat ng diagnosis
+monitor.queue.activeworkers = Mga aktibong worker
+self_check.database_inconsistent_collation_columns = Gumagamit ang database ng collation %s, ngunit ang mga column na ito ay gumagamit ng hindi tugmang collations. Maaaring magdulot ito ng ilang hindi inaasahang problema.
+auths.tip.twitter = Pumunta sa %s, gumawa ng application at siguraduhing naka-enable ang "Payagan ang application na gamitin para Mag-sign in sa Twitter" na opsyon
+auths.tip.gitea = Magrehistro ng bagong OAuth2 na application. Ang guide ay mahahanap sa %s
+auths.delete = Burahin ang source ng authentikasyon
+auths.new_success = Nadagdag na ang authentikasyon na "%s".
+auths.unable_to_initialize_openid = Hindi ma-initialize ang OpenID Connect Provider: %s
+config.ssh_minimum_key_size_check = Pinakamababang key size check
+config.ssh_minimum_key_sizes = Mga pinakamababang laki ng key
+config.db_path = Path
+config.default_allow_create_organization = Payagan ang paggawa ng mga organisasyon bilang default
+config.enable_timetracking = I-enable ang pagsubaybay ng oras
+config.mailer_smtp_addr = Host ng SMTP
+config.mailer_smtp_port = Port ng SMTP
+config.mailer_user = Gumagamit
+config.mailer_use_sendmail = Gumamit ng Sendmail
+config.mailer_sendmail_path = Path ng sendmail
+config.mailer_sendmail_args = Extra na argument sa Sendmail
+config.send_test_mail = Magpadala ng test email
+config.session_provider = Provider ng session
+config.cookie_name = Pangalan ng cookie
+config.gc_interval_time = Oras ng pagitan ng GC
+config.cookie_life_time = Lifetime ng cookie
+config.git_clone_timeout = Timeout ng operasyon na pag-clone
+monitor.process.cancel_desc = Ang pagkansela ng proseso ay maaaring magdulot ng pagkawalan ng data
+monitor.queue.name = Pangalan
+auths.oauth2_required_claim_value_helper = Itakda ang value na ito upang i-restrict ang pag-login mula sa pinagmulang ito sa mga user na may claim na may ganitong pangalan at value
+auths.tip.bitbucket = Magrehistro ng bagong OAuth consumer sa %s at idagdag ang pahintulot na "Account" - "Read"
+config.require_sign_in_view = Kailanganin ang pag-sign in para itignan ang nilalaman
+auths.tip.mastodon = Mag-input ng custom na instance URL para sa Mastodon instance na gusto mong mag-authenticate sa (o gamitin ang default)
+auths.tips.gmail_settings = Mga setting sa Gmail:
+config.git_max_diff_lines = Pinakamataas na mga linya ng diff bawat file
+auths.sspi_separator_replacement_helper = Ang character na gagamitin para palitan ang mga separator ng mga down-level na logon name (hal. ang \ sa "KESSOKUBAND\kita" at ang user principal name (hal. ang @ sa "kita@example.org").
+auths.oauth2_required_claim_name_helper = Itakda ang pangalan na ito para i-restrict ang pag-login mula sa source na ito sa mga user na may claim na may pangalan na ito
+auths.invalid_openIdConnectAutoDiscoveryURL = Hindi wastong Auto Discovery URL (ito ay dapat isang wastong URL na nagsisimula sa http:// o https://)
+emails.delete_desc = Sigurado ka bang gusto mong burahin ang email address na ito?
+self_check.database_fix_mysql = Para sa mga gumagamit ng MySQL/MariaDB, maaari mong gamitin ang "forgejo doctor convert" na utos upang ayusin ang mga problema sa pagkolekta, o maaari mo ring ayusin ang problema sa pamamagitan ng "ALTER ... COLLATE ..." nang manu-manong mga SQL.
+auths.update = I-update ang source ng authentikasyon
+config.cache_conn = Koneksyon ng cache
+users.activated.description = Pagkumpleto ng email verification. Ang owner ng hindi naka-activate na account ay hindi makaka-log in hanggang sa matapos ang email verification.
+users.admin.description = Binibigyan ang user na ito ng punong access sa lahat ng mga tagapangasiwang feature na available sa pamamagitan ng web UI at ang API.
+config.db_ssl_mode = SSL
+config.enable_openid_signin = I-enable ang OpenID sign-in
+monitor.duration = Tagal (s)
[org]
repo_updated = Binago %s
@@ -2217,6 +3349,96 @@ settings.permission = Mga pahintulot
settings.visibility.public = Pangpubliko
settings.full_name = Buong pangalan
form.create_org_not_allowed = Hindi ka pinapayagang gumawa ng organisasyon.
+settings.visibility.limited = Limitado (nakikita lamang ng mga naka-sign in na user)
+settings.visibility.limited_shortname = Limitado
+form.name_reserved = Nakareserba ang pangalan ng organisasyon na "%s".
+teams.can_create_org_repo = Gumawa ng mga repositoryo
+teams.leave = Umalis
+teams.leave.detail = Sigurado ka ba gusto mong umalis sa koponan na "%s"?
+teams.join = Sumali
+team_unit_disabled = (Naka-disable)
+team_unit_desc = Payagan ang access sa mga seksyon ng repositoryo
+settings.change_orgname_redirect_prompt = Magre-redirect ang lumang pangalan hanggang sa may kumuha niyan.
+settings.delete_prompt = Ang organisasyon na ito ay permanenteng mabubura. HINDI ito mababawi!
+settings.confirm_delete_account = Kumpirmahin ang pagbura
+open_dashboard = Buksan ang dashboard
+members.leave.detail = Sigurado ka bang gusto mong umalis sa organisasyon na "%s"?
+members.invite_now = Iimbita ngayon
+members.private = Nakatago
+members.invite_desc = Idagdag ang bagong miyembro sa %s:
+settings.options = Organisasyon
+settings.email = Email ng pakikipag-ugnayan
+settings.repoadminchangeteam = Madadagdag at matatanggal ng tagapangasiwa ng repositoryo ang access para sa mga koponan
+settings.visibility = Kakayahang pagpakita
+settings.visibility.private_shortname = Pribado
+settings.update_settings = I-update ang mga setting
+settings.update_avatar_success = Nabago na ang avatar ng organisasyon.
+settings.delete = Burahin ang organisasyon
+settings.delete_account = Burahin ang organisasyon na ito
+settings.delete_org_title = Burahin ang organisasyon
+settings.delete_org_desc = Permanenteng buburahin ang organisasyon na ito. Magpatuloy?
+settings.hooks_desc = Magdagdag ng mga webhook na mati-trigger para sa lahat ng mga repositoryo sa ilalim ng organisasyon na ito.
+members.membership_visibility = Visibility ng membership:
+members.public = Visible
+teams.none_access = Walang access
+members.remove.detail = Tanggalin ang %[1]s mula sa %[2]s?
+settings = Mga Setting
+settings.visibility.private = Pribado (makikita lamang ng mga miyembro ng organisasyon)
+settings.website = Website
+members.owner = May-ari
+members.member = Miyembro
+members.private_helper = Gawing visible
+settings.location = Lokasyon
+settings.update_setting_success = Nabago na ang mga setting ng organisasyon.
+teams.can_create_org_repo_helper = Maaaring gumawa ang mga miyembro ng mga bagong repositoryo sa organisasyon. Magkakaroon ng tagapangasiwa na access ang tagagawa sa bagong repositoryo.
+settings.change_orgname_prompt = Tandaan: Ang pagpalit ng pangalan ng organisasyon ay papalitan din ang URL ng organisasyon at mapapalaya ang lumang pangalan.
+settings.labels_desc = Magdagdag ng mga label na magagamit sa mga isyu para sa lahat ng mga repositoryo sa ilalim ng organisasyon.
+members.public_helper = Gawing nakatago
+members.member_role = Role ng miyembro:
+form.name_pattern_not_allowed = Hindi pinapayagan ang "%s" na pattern sa pangalan ng organisasyon.
+members.remove = Tanggalin
+members.leave = Umalis
+teams.invite_team_member.list = Mga nakabinbin na imbitasyon
+teams.delete_team_desc = Ang pagbura ng koponan ay tatanggihan ang access ng repositoryo sa kanilang mga miyembro. Magpatuloy?
+teams.invite.by = Inimbita ni %s
+teams.delete_team_title = Burahin ang koponan
+teams.members.none = Walang mga miyembro sa koponan na ito.
+teams.remove_all_repos_title = Tanggalin ang lahat ng mga repositoryo ng koponan
+teams.read_permission_desc = Ang koponan na ito ay nagbibigay ng read access: ang mga miyembro ay makakatingin at makaka-clone ng mga repositoryo ng koponan.
+teams.invite.title = Inimbita kang sumali sa koponan na %s sa organisasyon na %s .
+teams.specific_repositories_helper = Magkakaroon lang ng access ang mga miyembro sa mga repository na tahasang idinagdag sa koponan. Ang pagpili nito ay hindi awtomatikong mag-aalis ng mga repositoryo na naidagdag na kasama ng Lahat ng mga repositoryo .
+teams.create_repo_permission_desc = Bilang karagdagan, ang koponan na ito ay nagbibigay ng gumawa ng repositoryo na pahintulot: ang mga miyembro ay makakagawa ng mga bagong repositoryo sa organisasyon.
+teams.general_access = Custom na access
+teams.write_permission_desc = Ang koponan na ito ay nagbibigay ng write access: ang mga miyembro ay makakabasa mula at magtulak sa mga repositoryo ng koponan.
+teams.none_access_helper = Ang "walang access* na opsyon ay may epekto lang sa mga pribadong repositoryo.
+teams.general_access_helper = Ang mga pahintulot ng mga miyembro ay pagpapasya sa pamamagitan ng talahanayan ng pahintulot sa ibaba.
+teams.write_access = Baguhin
+teams.members = Mga miyembro ng koponan
+teams.add_team_member = Magdagdag ng miyembro ng koponan
+teams.delete_team_success = Nabura na ang koponan.
+teams.repositories = Mga repositoryo ng koponan
+teams.remove_all_repos_desc = Tatanggalin nito ang lahat ng mga repositoryo mula sa koponan.
+teams.add_all_repos_title = Idagdag ang lahat ng mga repositoryo
+teams.add_all_repos_desc = Idadagdag nito ang lahat ng mga repositoryo ng organisasyon sa koponan.
+teams.add_duplicate_users = Ang user ay isa nang miyembro ng koponan.
+teams.specific_repositories = Mga ilang repositoryo
+teams.invite.description = Mangyaring i-click ang button sa ibaba para sumali sa koponan.
+teams.update_settings = I-update ang mga setting
+teams.delete_team = Burahin ang koponan
+teams.admin_permission_desc = Ang koponan na ito ay nagbibigay ng tagapangasiwa na access: ang mga miyembro ay makakabasa mula, magtulak sa, at magdagdag ng mga tagatulong sa mga repositoryo ng koponan.
+teams.read_access = Basahin
+teams.repos.none = Walang mga repositoryo ang maa-access sa koponan na ito.
+teams.invite_team_member = Iimbita sa %s
+teams.admin_access = Access ng tagapangasiwa
+teams.admin_access_helper = Ang mga miyembro ay makakahila at makakatulak sa mga repositoryo ng koponan at magdagdag ng mga tagatulong sa kanila.
+teams.no_desc = Walang paglalarawan ang koponan na ito
+teams.settings = Mga Setting
+teams.owners_permission_desc = Ang mga owner ay may punong access sa lahat ng mga repositoryo at may administrator access sa organisasyon.
+teams.add_nonexistent_repo = Hindi pa umiiral ang repositoryo na sinusubukan mong idagdag. Mangyaring gawin iyan muna.
+teams.all_repositories = Lahat ng mga repositoryo
+teams.all_repositories_helper = Ang koponan ay may access sa lahat ng mga repositoryo. Ang pagpili nito ay idadagdag ang lahat ng mga umiiral na repositoryo sa koponan.
+settings.change_orgname_redirect_prompt.with_cooldown.few = Magiging available ang lumang pangalan ng organisasyon sa lahat pagkatapos ng panahon ng cooldown ng %[1]d araw, maari mo pa ring ma-claim muli ang lumang pangalan sa panahon ng cooldown.
+settings.change_orgname_redirect_prompt.with_cooldown.one = Magiging available ang lumang pangalan ng organisasyon sa lahat pagkatapos ng panahon ng cooldown ng %[1]d araw, maari mo pa ring ma-claim muli ang lumang pangalan ng panahon ng cooldown.
[packages]
@@ -2256,7 +3478,7 @@ dependency.version = Bersyon
alpine.registry = I-setup ang registry na ito sa pamamagitan ng pagdagdag ng url sa iyong /etc/apk/repositories
file:
alpine.registry.info = Pumili ng $branch at $repository mula sa listahan sa ibaba.
alpine.install = Para i-install ang package, patakbuhin ang sumusunod na command:
-alpine.repository = Info ng Repositoryo
+alpine.repository = Info ng repositoryo
cargo.registry = I-setup ang registry na ito sa Cargo configuration file (halimbawa ~/.cargo/config.toml
):
chef.registry = I-setup ang registry na ito sa iyong ~/.chef/config.rb
file:
composer.dependencies = Mga dependency
@@ -2268,29 +3490,267 @@ empty.documentation = Para sa higit pang impormasyon sa package registry, tignan
cargo.install = Para i-install ang package gamit ang Cargo, patakbuhin ang sumusunod na command:
published_by_in = Na-publish ang %[1]s ni %[3]s sa %[5]s
alpine.registry.key = I-download ang registry public RSA key sa /etc/apk/keys
folder para i-verify ang index signature:
+swift.install2 = at patakbuhin ang sumusunod na utos:
+arch.version.description = Paglalarawan
+arch.version.properties = Mga katangian ng bersyon
+settings.delete.description = Permanente ang pagbura ng package at hindi ito mababawi.
+owner.settings.cargo.initialize.description = Ang isang espesyal na index Git repository ay kinakailangan para gamitin ang Cargo registry. Ang paggamit ng opsyon na ito ay (muling) gagawin ang repositoryo at awtomatikong i-configure.
+owner.settings.cargo.rebuild.description = Maaaring maging kapaki-pakinabang ang muling pagtatayo kung ang index ay hindi naka-synchronize sa mga nakaimbak na Cargo package.
+helm.install = Para i-install ang package na ito, patakbuhin ang sumusunod na command:
+helm.registry = I-setup ang registry na ito mula sa command line:
+owner.settings.cargo.rebuild.no_index = Hindi makaka-rebuild, walang index na naka-initialize.
+pypi.install = Para i-install ang package gamit ang pip, patakbuhin ang sumusunod na command:
+owner.settings.cleanuprules.keep.count.n = %d mga bersyon kada package
+owner.settings.cleanuprules.success.update = Na-update na cleanup rule.
+arch.version.backup = Backup
+owner.settings.cleanuprules.keep.pattern = Panatilihin ang mga bersyon na tumutugma
+conda.install = Para i-install ang package gamit ang Conda, patakbuhin ang sumusunod na command:
+container.multi_arch = OS / Arch
+debian.repository.components = Mga component
+conda.registry = I-set up ang registry na ito bilang Conda repository sa iyong .condarc
file:
+npm.registry = I-set up ang registry na ito sa .npmrc
file ng iyong proyekto:
+owner.settings.cargo.rebuild = I-rebuild ang index
+cran.registry = I-set up ang registry na ito sa iyong Rprofile.site
na file:
+arch.version.depends = Dumedepende
+arch.version.provides = Nagbibigay
+arch.version.groups = Grupo
+arch.version.optdepends = Opsyonal na dumepende
+pub.install = Para i-install ang package gamit ang Dart, patakbuhin ang sumusunod na command:
+pypi.requires = Kinakailangan ang Python
+rubygems.dependencies.development = Mga development dependency
+owner.settings.cleanuprules.keep.count.1 = 1 bersyon kada package
+owner.settings.cleanuprules.remove.pattern = Tanggalin ang mga bersyon na tumutugma sa
+nuget.install = Para i-install ang package gamit ang NuGet, patakbuhin ang sumusunod na command:
+container.labels = Mga Label
+rpm.repository.multiple_groups = Available ang package na ito sa iba't ibang grupo.
+settings.delete.error = Nabigong burahin ang package.
+owner.settings.cargo.title = Index ng Cargo registry
+debian.repository = Info ng repositoryo
+owner.settings.cleanuprules.remove.title = Ang mga bersyon na tumutugma sa mga rule na ito ay tatanggalin, maliban mung may rule sa itaas ay sasabihin na panatilihin sila.
+owner.settings.cleanuprules.remove.days = Tanggalin ang mga bersyon mas luma sa
+container.details.platform = Platform
+container.digest = Digest
+container.details.type = Uri ng image
+rubygems.required.ruby = Kinakailangan ang bersyon ng Ruby
+npm.dependencies.bundle = Mga kasamang dependency
+owner.settings.cleanuprules.success.delete = Nabura na ang cleanup rule.
+owner.settings.chef.keypair.description = Ang isang key pair ay kinakailangan upang mapatotohanan sa Chef registry. Kung nakabuo ka na ng key pair dati, ang pagbuo ng bagong key pair ay itapon ang lumang key pair.
+npm.dependencies = Mga dependency
+npm.dependencies.peer = Mga peer dependency
+rubygems.install = Para i-install ang package sa pamamagitan ng gem, patakbuhin ang sumusunod na command:
+settings.link.description = Kung mag-link ka ng package sa repository, ang package ay nakalista sa listahan ng mga package ng repositoryo.
+settings.delete.success = Nabura na ang package.
+arch.pacman.repo.multi.item = Configuration para sa %s
+arch.pacman.conf = Idagdag ang server na may kaugnay na distribution at architechture sa /etc/pacman.conf
:
+arch.pacman.sync = I-sync ang package sa pamamagitan ng pacman:
+arch.version.makedepends = Mga make depend
+arch.version.checkdepends = Mga check depend
+container.pull = Hilahin ang image mula sa command line:
+container.labels.key = Key
+cran.install = Para i-install ang package na ito, patakbuhin ang sumusunod na command:
+debian.repository.distributions = Mga distribution
+generic.download = I-download ang package mula sa command line:
+go.install = I-install ang package mula sa command line:
+maven.install2 = Patakbuhin sa pamamagitan ng command line:
+maven.download = Para i-download ang dependency, patakbuhin sa pamamagitan ng command line:
+nuget.registry = I-setup ang registry na ito mula sa command line:
+nuget.dependency.framework = Target na Framework
+npm.install = Para i-install ang package gamit ng npm, patakbuhin ang sumusunod na command:
+npm.install2 = o idagdag ito sa package.json file:
+npm.dependencies.development = Mga development dependency
+npm.details.tag = Tag
+swift.install = Idagdag ang package sa iyong Package.swift
na file:
+vagrant.install = Para magdagdag ng Vagrant box, patakbuhin ang sumusunod na command:
+settings.link = I-link ang package na ito sa repository
+settings.link.select = Pumili ng Repositoryo
+settings.link.button = I-update ang Link ng Repositoryo
+settings.link.error = Nabigong i-update ang link ng repositoryo.
+settings.delete = Burahin ang package
+owner.settings.cargo.initialize = I-initialize ang index
+owner.settings.cleanuprules.add = Magdagdag ng cleanup rule
+owner.settings.cleanuprules.preview = Preview ng cleanup rule
+owner.settings.cleanuprules.preview.overview = %d mga package ay naka-iskedyul para tanggalin.
+owner.settings.cleanuprules.preview.none = Hindi tumutugma sa anumang mga package ang cleanup rule.
+owner.settings.cleanuprules.enabled = Naka-enable
+owner.settings.cleanuprules.pattern_full_match = I-apply ang pattern sa punong pangalan ng package
+owner.settings.chef.keypair = Gumawa ng key pair
+arch.pacman.helper.gpg = Magdagdag ng trust certificate para sa pacman:
+arch.pacman.repo.multi = Ang %s ay may katulad na beryson sa iba't ibang mga distribution.
+arch.version.conflicts = Mga salungatan
+arch.version.replaces = Pinapalit
+npm.dependencies.optional = Mga opsyonal na dependency
+rpm.distros.suse = sa mga SUSE based na distribution
+rpm.install = Para i-install ang package na ito, patakbuhin ang sumusunod na command:
+rpm.repository = Info ng repositoryo
+rpm.repository.architectures = Mga architechture
+rpm.registry = I-setup ang registry na ito mula sa command line:
+rpm.distros.redhat = sa mga RedHat based na distribution
+rubygems.dependencies.runtime = Mga runtime dependency
+rubygems.install2 = o idagdag ito sa Gemfile:
+debian.repository.architectures = Mga architechture
+owner.settings.chef.title = Chef registry
+rubygems.required.rubygems = Kinakailangan ang bersyon ng RubyGem
+owner.settings.cleanuprules.edit = I-edit ang cleanup rule
+settings.link.success = Matagumpay na na-update ang link ng repositoryo.
+owner.settings.cleanuprules.keep.pattern.container = Ang latest
na bersyon ay palaging pinapatilihin para sa mga Container package.
+owner.settings.cleanuprules.none = Wala pang mga cleanup rule sa ngayon.
+owner.settings.cleanuprules.keep.count = Panatilihin ang pinaka-recent
+settings.delete.notice = Buburahin mo ang %s (%s). Hindi mababalikan ang aksyon na ito, sigurado ka ba?
+owner.settings.cargo.initialize.error = Nabigong i-initialize ang Cargo index: %v
+debian.install = Para i-install ang package na ito, patakbuhin ang sumusunod na command:
+owner.settings.cargo.rebuild.error = Nabigong i-rebuild ang cargo index: %v
+conan.install = Para i-install ang package gamit ang Conan, patakbuhin ang sumusunod na command:
+swift.registry = I-setup ang registry na ito mula sa command line:
+maven.registry = I-set up ang registry na ito sa iyong pom.xml
ng iyong proyekto:
+owner.settings.cleanuprules.keep.title = Ang mga bersyon na tumutugma sa mga rule na ito ay papanatilihin, kahit na tumutugma sila sa removal rule sa ibaba.
+maven.install = Para gamitin ang package isama ang sumusunod sa dependencies
block sa pom.xml
file:
+container.labels.value = Value
+debian.registry = I-setup ang registry na ito mula sa command line:
+debian.registry.info = Pumili ng $distribution at $component sa listahan sa ibaba.
+owner.settings.cargo.rebuild.success = Matagumpay na na-rebuild ang Cargo index.
+owner.settings.cleanuprules.title = Mga cleanup rule
+container.layers = Mga layer ng image
+container.images.title = Mga image
+search_in_external_registry = Maghanap sa %s
+alt.registry = I-setup ang registry na ito mula sa command line:
+alt.registry.install = Para i-install ang package na ito, patakbuhin ang sumusunod na command:
+alt.install = I-install ang package
+alt.setup = Idagdag ang repositoryo sa listahan ng mga nakakonektang repositoryo (piliin ang kinakailangang architechture sa halip ng "_arch_"):
+alt.repository = Info ng repositoryo
+alt.repository.architectures = Mga architechture
+alt.repository.multiple_groups = Available ang package na ito sa iba't ibang grupo.
[actions]
runners.last_online = Huling oras na online
runs.no_workflows.quick_start = Hindi alam kung paano magsimula gamit ang Forgejo Actions? Tingnan ang gabay sa mabilis na pagsisimula .
runs.no_workflows.documentation = Para sa higit pang impormasyon tungkol sa Forgejo Actions, tingnan ang Dokumentasyon .
+status.waiting = Hinihintay
+runners.task_list.run = Patakbuhin
+runners.description = Paglalarawan
+runners.owner_type = Uri
+runners.name = Pangalan
+status.success = Tagumpay
+runs.pushed_by = itinulak ni/ng
+runners.status = Katayuan
+status.failure = Nabigo
+actions = Mga Aksyon
+runs.no_job = Ang workflow ay dapat maglaman ng hindi bababa sa isang trabaho
+runners = Mga Runner
+runs.commit = Commit
+workflow.dispatch.trigger_found = Mayroong workflow_dispatch na trigger ang workflow na ito.
+unit.desc = Ipamahala ang mga pinag-sasamang CI/CD pipeline sa pamamagitan ng Forgejo Actions.
+runners.edit_runner = Baguhin ang Runner
+runners.update_runner = I-update ang mga pagbabago
+variables.update.failed = Nabigong baguhin ang variable.
+variables.update.success = Nabago na ang variable.
+runs.no_results = Walang mga tumugmang resulta.
+runners.delete_runner_success = Matagumpay na nabura ang runner
+runs.all_workflows = Lahat ng mga workflow
+runs.scheduled = Naka-iskedyul
+runs.workflow = Workflow
+variables.edit = Baguhin ang Variable
+workflow.enable = I-enable ang workflow
+workflow.disabled = Naka-disable ang workflow.
+need_approval_desc = Kailangan ng pag-apruba para tumakbo ng mga workflow para sa fork na hiling sa paghila.
+variables = Mga variable
+runners.status.active = Aktibo
+runners.version = Bersyon
+status.unknown = Hindi alam
+runs.invalid_workflow_helper = Hindi wasto ang workflow config file. Pakisuri ang iyong config file: %s
+runs.actors_no_select = Lahat ng mga actor
+runners.runner_title = Runner
+runners.task_list = Mga kamakailang trabaho sa runner na ito
+runners.task_list.no_tasks = Wala pang mga trabaho sa ngayon.
+runners.labels = Mga label
+runs.no_matching_online_runner_helper = Walang tumutugmang online runner na may label: %s
+runs.status = Status
+runs.no_workflows = Wala pang mga workflow sa ngayon.
+runs.no_runs = Wala pang mga pagtatakbo ang workflow na ito sa ngayon.
+variables.creation = Magdagdag ng variable
+variables.none = Wala pang mga variable sa ngayon.
+variables.deletion = Tanggalin ang variable
+variables.deletion.description = Permanente ang pagtanggal ng isang variable at hindi ito mababalik. Magpatuloy?
+status.running = Tumatakbo
+runners.new_notice = Paano magsimula ng runner
+runners.update_runner_success = Matagumpay na na-update ang runner
+runners.delete_runner_notice = Kapag may trabaho na tumatakbo sa runner na ito, titigilan ito at mamarkahan bilang nabigo. Maaaring sirain ang building workflow.
+runners.none = Walang mga available na runner
+runs.status_no_select = Lahat ng status
+runs.empty_commit_message = (walang laman na mensahe ng commit)
+workflow.enable_success = Matagumpay na na-enable ang workflow na "%s".
+workflow.dispatch.run = Patakbuhin ang workflow
+workflow.dispatch.success = Matagumpay na nahiling ang pagtakbo ng workflow.
+variables.management = Ipamahala ang mga variable
+variables.deletion.failed = Nabigong tanggalin ang variable.
+runners.status.unspecified = Hindi alam
+runs.no_job_without_needs = Ang workflow ay dapat maglaman ng hindi bababa sa isang trabaho na walang dependencies.
+workflow.disable = I-disable ang workflow
+workflow.disable_success = Matagumpay na na-disable ang workflow na "%s".
+runners.task_list.repository = Repositoryo
+status.skipped = Nilaktawan
+runners.runner_manage_panel = Ipamahala ang mga runner
+runners.new = Gumawa ng bagong runner
+variables.creation.failed = Nabigong idagdag ang variable.
+runners.id = ID
+runs.actor = Actor
+runners.update_runner_failed = Nabigong i-update ang runner
+runners.delete_runner = Burahin ang runner na ito
+runners.delete_runner_failed = Nabigong burahin ang runner
+runners.delete_runner_header = Kumpirmahin na burahin ang runner
+status.blocked = Naharang
+status.cancelled = Kinansela
+runners.task_list.status = Status
+runners.status.idle = Idle
+workflow.dispatch.use_from = Gamitin ang workflow mula sa
+runners.reset_registration_token = I-reset ang token ng pagrehistro
+runners.status.offline = Offline
+workflow.dispatch.invalid_input_type = Hindi wastong input type "%s".
+runners.task_list.commit = Commit
+runners.task_list.done_at = Natapos Sa
+runners.reset_registration_token_success = Matagumpay na na-reset ang token ng pagrehistro ng runner
+workflow.dispatch.input_required = Kumailangan ng value para sa input na "%s".
+workflow.dispatch.warn_input_limit = Pinapakita lamang ang unang %d na mga input.
+variables.description = Ipapasa ang mga variable sa ilang mga aksyon at hindi mababasa kung hindi man.
+variables.id_not_exist = Hindi umiiral ang variable na may ID na %d.
+variables.deletion.success = Tinanggal na ang variable.
+variables.creation.success = Nadagdag na ang variable na "%s".
+runs.expire_log_message = Na-purge ang mga log dahil masyado silang luma.
+runs.no_workflows.help_write_access = Hindi alam kung paano magsimula sa Forgejo Actions? Tignan ang mabilisang pagsimula sa user documentation para magsimulang magsulat ng unang workflow, at mag-setup ng Forgejo runner para patakbuhin ang mga job.
+runs.no_workflows.help_no_write_access = Para matuto tungkol sa Forgejo Actions, tignan ang dokumentasyon .
+variables.not_found = Nabigong hanapin ang variable.
[action]
commit_repo = itinulak sa %[3]s sa %[4]s
-create_issue = `binuksan ang isyu %[3]s#%[2]s `
+create_issue = `binuksan ang isyu na %[3]s#%[2]s `
comment_issue = `nagiwan ng komento sa isyu %[3]s#%[2]s `
reopen_pull_request = `binuksang muli ang hiling sa paghatak %[3]s#%[2]s `
comment_pull = `nagiwan ng komento sa hiling sa paghatak %[3]s#%[2]s `
-reopen_issue = `binuksang muli ang isyu %[3]s#%[2]s `
+reopen_issue = `binuksang muli ang isyu na %[3]s#%[2]s `
create_pull_request = `ginawa ang hiling sa paghatak %[3]s#%[2]s `
create_branch = ginawa ang branch na %[3]s sa %[4]s
create_repo = ginawa ang repositoryo na %s
starred_repo = na-star ang %[2]s
watched_repo = ay sinimulang panoorin ang %[2]s
-compare_commits_general = Ikumpara ang mga [commit]
-compare_commits = Ikumpara ang %d mga [commit]
-merge_pull_request = `isinama ang [pull request] %[3]s#%[2]s `
-auto_merge_pull_request = `[automatikong] isinama ang [pull request] %[3]s#%[2]s `
+compare_commits_general = Ikumpara ang mga commit
+compare_commits = Ikumpara ang %d mga commit
+merge_pull_request = `isinama ang hiling sa paghila na %[3]s#%[2]s `
+auto_merge_pull_request = `automatikong isinama ang hiling sa paghila na %[3]s#%[2]s `
approve_pull_request = `inaprubahan ang %[3]s#%[2]s `
+review_dismissed_reason = Dahilan:
+compare_branch = Ikumpara
+reject_pull_request = `nagmungkahi ng mga pagbabago para sa %[3]s#%[2]s `
+rename_repo = pinalitan ang pangalan ng repositoryo mula %[1]s
sa %[3]s
+close_issue = `sinara ang isyu na %[3]s#%[2]s `
+review_dismissed = `na-dismiss ang pagsusuri mula %[4]s para sa %[3]s#%[2]s `
+close_pull_request = `sinara ang hiling sa paghila na %[3]s#%[2]s `
+transfer_repo = nilipat ang repositoryo na %s
sa %s
+delete_branch = binura ang branch %[2]s mula %[3]s
+mirror_sync_push = na-sync ang mga commit sa %[3]s sa %[4]s mula sa mirror
+mirror_sync_create = na-syng ang bagong reference %[3]s sa %[4]s mula sa mirror
+publish_release = `inilabas ang %[4]s sa %[3]s `
+delete_tag = binura ang tag na %[2]s mula %[3]s
+push_tag = tinulak ang tag na %[3]s sa %[4]s
+mirror_sync_delete = na-sync at binura ang reference %[2]s
sa %[3]s mula sa mirror
[tool]
1m = 1 minuto
@@ -2353,9 +3813,73 @@ error.unit_not_allowed = Hindi ka pinapayagang ma-access ang seksyon ng reposito
[dropzone]
default_message = I-drop ang mga file o mag-click dito para mag-upload.
-invalid_input_type = Hindi ka maaring mag-upload ng mga file sa uri na ito.
+invalid_input_type = Hindi ka maaaring mag-upload ng mga file sa uri na ito.
file_too_big = Ang laki ng file ({{filesize}}) MB) ay lumalagpas sa pinakamataas na size na ({{maxFilesize}} MB).
remove_file = Tanggalin ang file
[secrets]
-creation.success = Naidagdag na ang lihim na "%s".
\ No newline at end of file
+creation.success = Naidagdag na ang lihim na "%s".
+secrets = Mga lihim
+deletion.success = Natanggal na ang lihim.
+deletion.failed = Nabigong tanggalin ang lihim.
+creation.failed = Nabigong idagdag ang lihim.
+deletion = Tanggalin ang lihim
+creation = Idagdag ang Lihim
+description = Ang mga sikreto ay ipapasa sa ilang mga aksyon at hindi mababasa kung hindi.
+none = Wala pang mga sikreto sa ngayon.
+creation.name_placeholder = case-insensitive, alphanumeric character o underscore lamang, hindi dapat magsimula sa GITEA_ o GITHUB_
+creation.value_placeholder = Maglagay ng anumang content. Tatanggalin ang whitespace sa simula at dulo.
+management = Ipamahala ang mga secret
+deletion.description = Ang pagtanggal ng sikreto ay permanente at hindi mababawi. Magpatuloy?
+
+[markup]
+filepreview.line = Linya %[1]d sa %[2]s
+filepreview.truncated = Na-truncate ang preview
+filepreview.lines = Mga linya %[1]d hanggang %[2]d sa %[3]s
+
+[projects]
+deleted.display_name = Binurang Proyekto
+type-2.display_name = Proyekto ng repositoryo
+type-1.display_name = Indibidwal na proyekto
+type-3.display_name = Proyekto ng organisasyon
+
+[translation_meta]
+test = I love Forgejo and Bocchi The Rock! -- Ikuyo Kita
+
+
+[repo.permissions]
+pulls.write = Baguhin: Isara ang mga hiling sa paghila at ipamahala ang metadata tulad ng mga label, milestone, mangangasiwa, takdang petsa at dependency.
+wiki.write = Baguhin: Gumawa, i-update, at burahin ang mga pahina sa kasamang wiki.
+issues.read = Basahin: Magbasa at gumawa ng mga isyu at komento.
+issues.write = Baguhin: Isara ang mga isyu at ipamahala ang metadata tulad ng mga label, milestone, mangangasiwa, takdang petsa at dependency.
+releases.read = Basahin: Itignan at i-download ang mga release.
+projects.read = Basahin: I-access ang mga board ng proyekto ng repositoryo.
+projects.write = Baguhin: Gumawa ng mga proyekto at column at baguhin sila.
+packages.read = Basahin: Itignan at i-download ang mga package na naka-assign sa repositoryo.
+actions.read = Basahin: Tignan ang kasamang CI/CD na pipeline at ang kanilang tala.
+actions.write = Baguhin: Manwal na i-trigger, i-restart, kanselahin at aprubahan ang mga nakabinbin na CI/CD na pipeline.
+ext_wiki = I-access ang link sa panlabas na wiki. External na pinamamahala ang mga pahintulot.
+code.read = Basahin: I-access at i-clone ang code ng repositoryo.
+pulls.read = Basahin: Pagbasa at paggawa ng mga hiling sa paghila.
+wiki.read = Basahin: Basahin ang kasamang wiki at ang kanilang kasaysayan.
+code.write = Baguhin: Magtulak sa repositoryo, gumawa ng mga branch at tag.
+releases.write = Baguhin: I-publish, i-edit, at burahin ang mga release at ang kanilang mga asset.
+packages.write = Baguhin: Mag-publish at magbura ng mga package na naka-assign sa repositoryo.
+ext_issues = I-access ang link sa panlabas na tagasubaybay ng isyu. External na pinamamahala ang mga pahintulot.
+
+[graphs]
+component_loading = Nilo-load ang %sโฆ
+component_loading_failed = Hindi ma-load ang %s
+component_failed_to_load = May nangyaring hindi inaasahan na error.
+code_frequency.what = dalas ng code
+contributors.what = mga kontribusyon
+recent_commits.what = mga kamakailang commit
+component_loading_info = Maaaring tumagal ito ng kauntiโฆ
+
+[git.filemode]
+normal_file = Normal na file
+changed_filemode = %[1]s โ %[2]s
+directory = Direktoryo
+executable_file = Executable na file
+symbolic_link = Symbolic na link
+submodule = Submodule
\ No newline at end of file
diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini
index 9566626800..8dc9837078 100644
--- a/options/locale/locale_fr-FR.ini
+++ b/options/locale/locale_fr-FR.ini
@@ -1,7 +1,7 @@
[common]
home=Accueil
dashboard=Tableau de bord
-explore=Explorateur
+explore=Explorer
help=Aide
logo=Logo
sign_in=Connexion
@@ -112,7 +112,7 @@ preview=Aperรงu
loading=Chargementโฆ
error=Erreur
-error404=La page que vous essayez d'atteindre n'existe pas ou vous n'รชtes pas autorisรฉ ร la voir.
+error404=La page que vous essayez d'atteindre n'existe pas , a รฉtรฉ supprimรฉ ou vous n'รชtes pas autorisรฉ ร la voir.
go_back=Retour
never=Jamais
@@ -124,8 +124,7 @@ pin=รpingler
unpin=Dรฉsรฉpingler
artifacts=Artefacts
-confirm_delete_artifact=รtes-vous sรปr de vouloir supprimer lโartefact ยซย %sย ยป ?
-
+confirm_delete_artifact = รtes-vous certain de vouloir supprimer l'artefect "%s"โฏ?
archived=Archivรฉ
concept_system_global=Global
@@ -142,7 +141,6 @@ confirm_delete_selected=รtes-vous sรปr de vouloir supprimer tous les รฉlรฉments
name=Nom
value=Valeur
-confirm_delete_artifact = รtes-vous certain de vouloir supprimer l'artefect "%s"โฏ?
filter.clear = Effacer le filtre
filter.is_archived = Archivรฉ
filter.not_archived = Non archivรฉ
@@ -159,6 +157,15 @@ toggle_menu = Menu va-et-vient
more_items = Plus d'รฉlรฉments
invalid_data = Donnรฉes invalidesโฏ: %v
copy_generic = Copier dans le presse-papiers
+test = Test
+new_migrate.title = Nouvelle migration
+new_org.title = Nouvelle organisation
+new_repo.link = Nouveau dรฉpรดt
+error413 = Votre quota est รฉpuisรฉ.
+new_repo.title = Nouveau dรฉpรดt
+new_migrate.link = Nouvelle migration
+new_org.link = Nouvelle organisation
+copy_path = Copier le chemin
[aria]
navbar=Barre de navigation
@@ -190,6 +197,19 @@ buttons.ref.tooltip=Rรฉfรฉrencer un ticket ou demande dโajout
buttons.switch_to_legacy.tooltip=Utiliser lโancien รฉditeur ร la place
buttons.enable_monospace_font=Activer la police ร chasse fixe
buttons.disable_monospace_font=Dรฉsactiver la police ร chasse fixe
+buttons.indent.tooltip = Indenter les รฉlรฉments d'un niveau
+buttons.unindent.tooltip = Supprimer un niveau d'indentation
+buttons.new_table.tooltip = Ajouter une table
+table_modal.header = Ajouter une table
+table_modal.placeholder.header = Entรชte
+table_modal.placeholder.content = Contenu
+table_modal.label.rows = Lignes
+table_modal.label.columns = Colonnes
+link_modal.header = Ajouter un lien
+link_modal.url = Url
+
+link_modal.description = Description
+link_modal.paste_reminder = Indiceย : avec une URL dans votre clipboard, vous pouvez copier directement dans l'รฉditeur pour crรฉer un lien.
[filter]
string.asc=A - Z
@@ -197,7 +217,7 @@ string.desc=Z - A
[error]
occurred=Une erreur sโest produite
-report_message=Si vous pensez qu'il s'agit d'un bug Forgejo, veuillez consulter notre board Codeberg ou ouvrir un nouveau ticket si nรฉcessaire.
+report_message=Si vous pensez qu'il s'agit d'un bug Forgejo, veuillez consulter les tickets de Codeberg ou ouvrir un nouveau ticket si nรฉcessaire.
missing_csrf=Requรชte incorrecteโฏ: aucun jeton CSRF prรฉsent
invalid_csrf=Requรชte incorrecteย : jeton CSRF invalide
not_found=La cible n'a pu รชtre trouvรฉe.
@@ -207,13 +227,13 @@ server_internal = Erreur interne du serveur
[startpage]
app_desc=Un service Git auto-hรฉbergรฉ sans prise de tรชte
install=Facile ร installer
-install_desc=Il suffit de lancer lโexรฉcutable adaptรฉ ร votre plateforme, le dรฉployer avec Docker ou de lโinstaller depuis un gestionnaire de paquet .
+install_desc=Il suffit de lancer lโexรฉcutable adaptรฉ ร votre plateforme, le dรฉployer avec Docker ou de lโinstaller depuis un gestionnaire de paquet .
platform=Multi-plateforme
-platform_desc=Forgejo tourne partout oรน Go peut รชtre compilรฉ : Windows, macOS, Linux, ARM, etc. Choisissez votre prรฉfรฉrรฉ !
+platform_desc=Forgejo est confirmรฉ fonctionner sur des systรจmes d'exploitation libres comme Linux et FreeBSD, ainsi que diffรฉrentes architectures CPU. Choisissez ce que vous prรฉfรฉrez !
lightweight=Lรฉger
lightweight_desc=Forgejo utilise peu de ressources. Il peut mรชme tourner sur un Raspberry Pi trรจs bon marchรฉ. รconomisez l'รฉnergie de vos serveurs !
license=Open Source
-license_desc=Toutes les sources sont sur Forgejo โฏ! Rejoignez-nous et contribuez ร rendre ce projet encore meilleurโฏ!
+license_desc=Toutes les sources sont sur Forgejo โฏ! Rejoignez-nous et contribuez ร rendre ce projet encore meilleur. Ne craignez pas de devenir unยทe contributeurยทtrice !
[install]
install=Installation
@@ -246,7 +266,7 @@ err_admin_name_is_invalid=Le nom d'utilisateur de l'administrateur est invalide
general_title=Configuration gรฉnรฉrale
app_name=Titre du site
-app_name_helper=Entrez ici le nom de votre sociรฉtรฉ.
+app_name_helper=Entrez ici le nom de votre instance. Il sera affichรฉ sur chaque page.
repo_path=Emplacement racine des dรฉpรดts
repo_path_helper=Les dรฉpรดts Git distants seront stockรฉs dans ce rรฉpertoire.
lfs_path=Rรฉpertoire racine Git LFS
@@ -394,19 +414,19 @@ disable_register_prompt=Les inscriptions sont dรฉsactivรฉes. Veuillez contacter
disable_register_mail=La confirmation par courriel ร lโinscription est dรฉsactivรฉe.
manual_activation_only=Contactez l'administrateur de votre site pour terminer l'activation.
remember_me=Mรฉmoriser cet appareil
-remember_me.compromised=Le jeton de connexion nโest plus valide, ce qui peut indiquer un compte compromis. Veuillez inspecter les activitรฉs inhabituelles de votre compte.
+remember_me.compromised = Le jeton de login n'est plus valide ce qui pourrait indiquer une compromission de compte. Veuillez vรฉrifier d'รฉventuelles activitรฉs inhabituelles.
forgot_password_title=Mot de passe oubliรฉ
forgot_password=Mot de passe oubliรฉย ?
sign_up_now=Pas de compte ? Inscrivez-vous maintenant.
sign_up_successful=Le compte a รฉtรฉ crรฉรฉ avec succรจs. Bienvenue !
-confirmation_mail_sent_prompt=Un nouveau mail de confirmation a รฉtรฉ envoyรฉ ร %s . Veuillez vรฉrifier votre boรฎte de rรฉception dans les prochaines %s pour valider votre enregistrement.
+confirmation_mail_sent_prompt=Un nouveau mail de confirmation a รฉtรฉ envoyรฉ ร %s . Pour terminer votre enregistrement, veuillez vรฉrifier votre boรฎte de rรฉception dans les prochaines %s . Si le courriel est incorrect, vous pouvez vous connecter et demander l'envoi d'un autre courriel de confirmation ร une diffรฉrente adresse.
must_change_password=Rรฉinitialisez votre mot de passe
allow_password_change=Demande ร l'utilisateur de changer son mot de passe (recommandรฉ)
reset_password_mail_sent_prompt=Un mail de confirmation a รฉtรฉ envoyรฉ ร %s . Veuillez vรฉrifier votre boรฎte de rรฉception dans les prochaines %s pour terminer la procรฉdure de rรฉcupรฉration du compte.
active_your_account=Activer votre compte
account_activated=Le compte a รฉtรฉ activรฉ
-prohibit_login=Connexion interdite
-prohibit_login_desc=Votre compte n'autorise pas la connexion, veuillez contacter l'administrateur de votre site.
+prohibit_login=Le compte est suspendu
+prohibit_login_desc=Votre compte a รฉtรฉ suspendu et ne peut interagir avec cette instance. Contactez l'administrateur de l'instance pour y avoir accรจs.
resent_limit_prompt=Dรฉsolรฉ, vous avez rรฉcemment demandรฉ un courriel d'activation. Veuillez rรฉessayer dans 3 minutes.
has_unconfirmed_mail=Bonjour %s, votre adresse courriel (%s ) nโa pas รฉtรฉ confirmรฉe. Si vous nโavez reรงu aucun mail de confirmation ou souhaitez renouveler lโenvoi, cliquez sur le bouton ci-dessous.
resend_mail=Cliquez ici pour renvoyer un mail de confirmation
@@ -454,20 +474,26 @@ authorize_title=Autoriser "%s" ร accรฉder ร votre compte ?
authorization_failed=Lโautorisation a รฉchouรฉ
authorization_failed_desc=L'autorisation a รฉchouรฉ car nous avons dรฉtectรฉ une demande incorrecte. Veuillez contacter le responsable de l'application que vous avez essayรฉ d'autoriser.
sspi_auth_failed=รchec de l'authentification SSPI
-password_pwned=Le mot de passe que vous avez choisi se trouve sur la liste des mots de passe ayant fuitรฉ sur internet. Veuillez rรฉessayer avec un mot de passe diffรฉrent et considรฉrer remplacer ce mot de passe si vous l'utilisez ailleurs.
+password_pwned=Le mot de passe que vous avez choisi se trouve sur la liste des mots de passe ayant fuitรฉ sur internet. Veuillez rรฉessayer avec un mot de passe diffรฉrent et considรฉrer remplacer ce mot de passe si vous l'utilisez ailleurs.
password_pwned_err=Impossible d'envoyer la demande ร HaveIBeenPwned
change_unconfirmed_email_error = Le courriel %v n'a pu รชtre modifiรฉ
change_unconfirmed_email = Si vous avez donnรฉ un courriel incorrect ร l'inscription, vous pouvez le changer ci-dessous. La confirmation sera envoyรฉe ร cette nouvelle adresse.
change_unconfirmed_email_summary = Modifier l'adresse ร laquelle le courriel d'activation est envoyรฉ.
last_admin = Vous ne pouvez pas supprimer le dernier compte administrateur. Il doit exister au moins un compte administrateur.
-remember_me.compromised = Le jeton de login n'est plus valide ce qui pourrait indiquer une compromission de compte. Veuillez vรฉrifier d'รฉventuelles activitรฉs inhabituelles.
tab_signup = Enregistrement
tab_signin = Connexion
+hint_register = Besoin d'un compteโฏ? Enregistrez vous.
+sign_up_button = Creation d'un compte.
+hint_login = Vous avez dรฉjร un compteโฏ? Connectez vous maintenantโฏ!
+back_to_sign_in = Retour ร la connexion
+sign_in_openid = Continuer avec OpenID
+unauthorized_credentials = Vos identifiants sont invalides ou ont expirรฉ. Rรฉessayez votre commande, ou allez ร %s pour plus d'informations
+use_onetime_code = Utiliser un code a usage unique
[mail]
view_it_on=Voir sur %s
reply=ou rรฉpondez directement ร ce courriel
-link_not_working_do_paste=Le lien ne fonctionne pas ? Essayez de le copier-coller dans barre de navigation de votre navigateur.
+link_not_working_do_paste=Le lien ne fonctionne pasย ? Essayez de le copier-coller dans la barre de navigation de votre navigateur.
hi_user_x=Bonjour %s ,
activate_account=Veuillez activer votre compte
@@ -479,7 +505,7 @@ activate_email=Veuillez vรฉrifier votre adresse courriel
activate_email.title=%s, veuillez vรฉrifier votre adresse courriel
activate_email.text=Veuillez cliquer sur le lien suivant pour vรฉrifier votre adresse courriel dans %s โฏ:
-register_notify=Bienvenue sur Forgejo
+register_notify=Bienvenue sur %s
register_notify.title=%[1]s, bienvenue ร %[2]s
register_notify.text_1=ceci est votre courriel de confirmation d'inscription pour %sโฏ!
register_notify.text_2=Vous pouvez maintenant vous connecter avec le nom d'utilisateur : %s
@@ -499,7 +525,7 @@ issue.action.force_push=%[1]s a forcรฉ %[2]s de %[3]s vers %[4]s.
issue.action.push_1=@%[1]s a soumis %[3]d rรฉvision sur %[2]s
issue.action.push_n=@%[1]s a soumis %[3]d rรฉvisions sur %[2]s
issue.action.close=@%[1]s a fermรฉ #%[2]d.
-issue.action.reopen=@%[1]s a rรฉouvert #%[2]d.
+issue.action.reopen=@%[1]s a rouvert #%[2]d.
issue.action.merge=@%[1]s a fusionnรฉ de #%[2]d vers %[3]s.
issue.action.approve=@%[1]s a approuvรฉ cette demande d'ajout.
issue.action.reject=@%[1]s a demandรฉ des modifications sur cette demande d'ajout.
@@ -530,8 +556,24 @@ team_invite.text_1=%[1]s vous a invitรฉ ร rejoindre lโรฉquipe %[2]s dans lโ
team_invite.text_2=Veuillez cliquer sur le lien suivant pour rejoindre l'รฉquipe :
team_invite.text_3=Remarque : Cette invitation รฉtait destinรฉe ร %[1]s. Si vous nโattendiez pas cette invitation, vous pouvez ignorer ce courriel.
admin.new_user.user_info = Information ร propos de l'utilisateur
-admin.new_user.text = Veuillez clicker ici afin de gรฉrer l'utilisateur depuis la page d'administration.
+admin.new_user.text = Veuillez cliquer ici afin de gรฉrer l'utilisateur depuis la page d'administration.
admin.new_user.subject = L'utilisateur %s vient de crรฉer un compte
+reset_password.text_1 = Le mot de passe de votre compte vient d'รชtre modifiรฉ.
+password_change.subject = Votre mot de passe a รฉtรฉ modifiรฉ
+password_change.text_1 = Le mot de passe de votre compte vient d'รชtre modifiรฉ.
+primary_mail_change.subject = Votre courriel principal a รฉtรฉ modifiรฉ
+primary_mail_change.text_1 = Le courriel principal de votre compte vient d'รชtre modifiรฉ en %[1]s. Cela signifie que cette adresse e-mail ne recevra plus de notifications par e-mail pour votre compte.
+totp_disabled.no_2fa = Il n'y a plus de mรฉthodes 2FA configurรฉes ce qui signifie qu'il n'est plus nรฉcessaire d'utiliser 2FA pour se connecter ร votre compte.
+totp_disabled.text_1 = Mot de passe ร usage unique basรฉ sur le temps (TOTP) vient d'รชtre dรฉsactivรฉ pour votre compte.
+removed_security_key.subject = Une clรฉ de sรฉcuritรฉ a รฉtรฉ supprimรฉe
+totp_disabled.subject = TOTP a รฉtรฉ dรฉsactivรฉ
+removed_security_key.no_2fa = Il n'y a plus de mรฉthodes 2FA configurรฉes ce qui signifie qu'il n'est plus nรฉcessaire d'utiliser 2FA pour se connecter ร votre compte.
+account_security_caution.text_1 = Si vous รชtes ร lโorigine de cette action, vous pouvez ignorer ce courriel.
+totp_enrolled.text_1.no_webauthn = Vous venez d'activer TOTP pour votre compte. Cela signifie que pour toutes les prochaines connexions ร votre compte, vous devrez utiliser TOTP comme mรฉthode 2FA.
+totp_enrolled.subject = Vous avez activรฉ TOTP comme mรฉthode 2FA
+totp_enrolled.text_1.has_webauthn = Vous venez d'activer TOTP pour votre compte. Cela signifie que pour toutes les prochaines connexions ร votre compte, vous pouvez utiliser TOTP comme mรฉthode 2FA ou l'une de vos clรฉs de sรฉcuritรฉ.
+removed_security_key.text_1 = La clรฉ de sรฉcuritรฉ ยซย %[1]sย ยป vient d'รชtre supprimรฉe de votre compte.
+account_security_caution.text_2 = S'il ne s'agissait pas de vous, votre compte est compromis. Veuillez contacter les administrateurs du site.
[modal]
yes=Oui
@@ -631,8 +673,6 @@ org_still_own_packages=Cette organisation possรจde encore un ou plusieurs paquet
target_branch_not_exist=La branche cible n'existe pas.
username_error_no_dots = ` peut uniquement contenir des caractรจres alphanumรฉriques ('0-9','a-z','A-Z'), tiret ('-') et soulignรฉ ('_'). Ne peut commencer ou terminer avec un caractรจre non-alphanumรฉrique, et l'utilisation de caractรจres non-alphanumรฉriques consรฉcutifs n'est pas permise.`
-admin_cannot_delete_self = Vous ne pouvez supprimer votre compte lorsque vous disposez de droits d'administration. Veuillez d'abord renoncer ร vos droits d'administration.
-
admin_cannot_delete_self=Vous ne pouvez pas vous supprimer vous-mรชme lorsque vous รชtes admin. Veuillez dโabord supprimer vos privilรจges dโadministrateur.
unsupported_login_type = Ce type de compte ne peut รชtre supprimรฉ.
unset_password = L'utilisateur connectรฉ n'a pas de mot de passe.
@@ -645,6 +685,8 @@ Biography = Biographie
Website = Site web
Location = Emplacement
To = Nom de la branche
+email_domain_is_not_allowed = Le domaine %s du courriel utilisateur entre en conflit avec EMAIL_DOMAIN_ALLOWLIST ou EMAIL_DOMAIN_BLOCKLIST. Veuillez vous assurer le courriel est renseignรฉ.
+username_claiming_cooldown = Ce pseudonyme ne peut pas รชtre pris, car la pรฉriode de temporisation n'est pas encore terminรฉe. Il pourra รชtre rรฉclamรฉ dans %[1]s.
[user]
change_avatar=Changer votre avatarโฆ
@@ -672,14 +714,23 @@ form.name_pattern_not_allowed=Le motif ยซย %sย ยป nโest pas autorisรฉ dans un
form.name_chars_not_allowed=Le nom d'utilisateur "%s" contient des caractรจres non valides.
block_user = Bloquer un utilisateur
block_user.detail = Veuillez noter que bloquer un utilisateur a des consรฉquences. En particulier :
-block_user.detail_1 = Vous ne suivez plus cet utilisateur.
+block_user.detail_1 = Vous cesserez de vous suivre l'un et l'autre et ne pourrez plus vous suivre l'un et l'autre.
block_user.detail_2 = Cet utilisateur ne peut interagir avec vos dรฉpรดts, les tickets ou commentaires que vous avez crรฉรฉs.
-block_user.detail_3 = Cet utilisateur ne peut pas vous ajouter en tant que collaborateur, et vous ne pouvez pas l'ajouter en tant que collaborateur.
+block_user.detail_3 = Cet utilisateur ne peut pas vous ajouter l'un et l'autre en tant que collaborateur.
follow_blocked_user = Vous ne pouvez pas suivre cet utilisateur parce vous avez bloquรฉ cet utilisateur ou bien cet utilisateur vous a bloquรฉ.
block = Bloquer
unblock = Dรฉbloquer
following_one = Suit %d personnes
followers_one = %d abonnรฉ
+public_activity.visibility_hint.self_public = Votre activitรฉ est visible de tous, a l'exception de vos interactions dans les espaces privรฉs. Configurer .
+public_activity.visibility_hint.admin_public = Cette activitรฉ est visible de tous mais, en tant qu'administrateur vous pouvez aussi voir les interactions dans les espaces privรฉs.
+public_activity.visibility_hint.self_private = Vous pouvez voir votre propre activitรฉ, ainsi que les administrateurs de l'instance. Configurer .
+public_activity.visibility_hint.admin_private = Vous pouvez voir cette activitรฉ en tant qu'administrateur mais l'utilisateur veut qu'elle reste privรฉe.
+following.title.few = Following
+followers.title.one = Follower
+followers.title.few = Followers
+following.title.one = Following
+public_activity.visibility_hint.self_private_profile = Votre profil est privรฉ mais votre activitรฉ est aussi visible par les administrateursยทtrices. Configure .
[settings]
profile=Profil
@@ -701,9 +752,9 @@ uid=UID
webauthn=Clรฉs de sรฉcuritรฉ ร deux facteurs
public_profile=Profil public
-biography_placeholder=Parlez-nous un peu de vousโฏ! (Vous pouvez utiliser Markdown)
+biography_placeholder=Parlez-nous un peu de vousโฏ! (Markdown est supportรฉ)
location_placeholder=Partagez votre position approximative avec d'autres personnes
-profile_desc=Contrรดlez comment votre profil est affichรฉ aux autres utilisateurs. Votre adresse courriel principale sera utilisรฉe pour les notifications, la rรฉcupรฉration de mot de passe et les opรฉrations Git basรฉes sur le Web.
+profile_desc=ร propos de vous
password_username_disabled=Les utilisateurs externes ne sont pas autorisรฉs ร modifier leur nom d'utilisateur. Veuillez contacter l'administrateur de votre site pour plus de dรฉtails.
full_name=Nom complet
website=Site Web
@@ -768,7 +819,7 @@ manage_emails=Gรฉrer les adresses courriels
manage_themes=Thรจme par dรฉfaut
manage_openid=Adresses OpenID
email_desc=Votre adresse courriel principale sera utilisรฉe pour les notifications, la rรฉcupรฉration de mot de passe et, ร condition qu'elle ne soit pas cachรฉe, les opรฉrations Git basรฉes sur le Web.
-theme_desc=Ce sera votre thรจme par dรฉfaut sur le site.
+theme_desc=Ce thรจme sera utilisรฉ pour l'interface web lorsque vous รชtes authentifiรฉ.
primary=Principale
activated=Activรฉ
requires_activation=Nรฉcessite une activation
@@ -789,12 +840,12 @@ add_new_email=Ajouter une nouvelle adresse e-mail
add_new_openid=Ajouter une nouvelle URI OpenID
add_email=Ajouter une adresse courriel
add_openid=Ajouter une URI OpenID
-add_email_confirmation_sent=Un e-mail de confirmation a รฉtรฉ envoyรฉ ร "%s". Veuillez vรฉrifier votre boรฎte de rรฉception dans les %s suivants pour confirmer votre adresse e-mail.
+add_email_confirmation_sent=Un courriel de confirmation a รฉtรฉ envoyรฉ ร ยซย %sย ยป. Pour confirmer votre adresse de courriel, veuillez vรฉrifier votre boรฎte de rรฉception et suivre le lien indiquรฉ dans les prochains %s.
add_email_success=La nouvelle adresse e-mail a รฉtรฉ ajoutรฉe.
email_preference_set_success=L'e-mail de prรฉfรฉrence a รฉtรฉ dรฉfini avec succรจs.
add_openid_success=La nouvelle adresse OpenID a รฉtรฉ ajoutรฉe.
keep_email_private=Cacher l'adresse courriel
-keep_email_private_popup=Ceci masquera votre adresse e-mail de votre profil, de vos demandes d'ajout et des fichiers modifiรฉs depuis l'interface Web. Les rรฉvisions dรฉjร soumises ne seront pas modifiรฉs. Utilisez %s dans les rรฉvisions pour les relier ร votre compte.
+keep_email_private_popup=Ceci masquera votre adresse courriel de votre profil. Elle ne sera plus la valeur par dรฉfaut pour les commits crรฉรฉs par l'interface web, tel que des ajouts de fichiers ou des รฉditions, et ne sera pas utilisรฉe pour fusionner les commits. Un courriel special %s peut รชtre utilisรฉ pour รฉtablir la relation entre des commits et votre compte. Cette option n'aura pas d'effet sur les commits existants.
openid_desc=OpenID vous permet de confier l'authentification ร une tierce partie.
manage_ssh_keys=Gรฉrer les clรฉs SSH
@@ -897,7 +948,7 @@ select_permissions=Sรฉlectionner les autorisations
permission_no_access=Aucun accรจs
permission_read=Lecture
permission_write=Lecture et รฉcriture
-access_token_desc=Les autorisations des jetons sรฉlectionnรฉes se limitent aux routes API correspondantes. Lisez la documentation pour plus dโinformations.
+access_token_desc=Les autorisations des jetons sรฉlectionnรฉes se limitent aux routes API correspondantes. Lisez la documentation pour plus dโinformation.
at_least_one_permission=Vous devez sรฉlectionner au moins une permission pour crรฉer un jeton
permissions_list=Autorisations :
@@ -951,7 +1002,7 @@ passcode_invalid=Le mot de passe est invalide. Rรฉessayez.
twofa_enrolled=L'authentification ร deux facteurs a รฉtรฉ activรฉe pour votre compte. Gardez votre jeton de secours (%s) en lieu sรปr, car il ne vous sera montrรฉ qu'une seule fois.
twofa_failed_get_secret=Impossible d'obtenir le secret.
-webauthn_desc=Les clefs de sรฉcuritรฉ sont des dispositifs matรฉriels contenant des clefs cryptographiques. Elles peuvent รชtre utilisรฉes pour l'authentification ร deux facteurs. La clef de sรฉcuritรฉ doit supporter le standard WebAuthn Authenticator .
+webauthn_desc=Les clefs de sรฉcuritรฉ sont des dispositifs matรฉriels contenant des clefs cryptographiques. Elles peuvent รชtre utilisรฉes pour l'authentification ร deux facteurs. La clef de sรฉcuritรฉ doit supporter le standard WebAuthn Authenticator .
webauthn_register_key=Ajouter une clรฉ de sรฉcuritรฉ
webauthn_nickname=Pseudonyme
webauthn_delete_key=Retirer la clรฉ de sรฉcuritรฉ
@@ -989,7 +1040,7 @@ visibility=Visibilitรฉ de l'utilisateur
visibility.public=Public
visibility.public_tooltip=Visible par tout le monde
visibility.limited=Limitรฉ
-visibility.limited_tooltip=Visible uniquement pour les utilisateurs authentifiรฉs
+visibility.limited_tooltip=Visible uniquement pour les utilisateurs connectรฉs
visibility.private=Privรฉ
visibility.private_tooltip=Visible uniquement aux membres des organisations que vous avez rejointes
blocked_users = Utilisateurs bloquรฉs
@@ -999,7 +1050,7 @@ user_unblock_success = Cet utilisateur a รฉtรฉ dรฉbloquรฉ avec succรจs.
user_block_success = Cet utilisateur a รฉtรฉ bloquรฉ avec succรจs.
change_password = Modifier le mot de passe
hints = Suggestions
-additional_repo_units_hint_description = Afficher un bouton "Ajouter plus d'unitรฉs..." pour les dรฉpรดts qui n'ont pas toutes les unitรฉs disponibles activรฉes.
+additional_repo_units_hint_description = Afficher un bouton "Ajouter en plus..." pour les dรฉpรดts qui n'ont pas toutes les unitรฉs disponibles activรฉes.
additional_repo_units_hint = Suggรฉrer l'ajout de nouvelles unitรฉs pour le dรฉpรดt
update_hints = Mettre ร jour les suggestions
update_hints_success = Les suggestions ont รฉtรฉ mises ร jour.
@@ -1007,16 +1058,50 @@ pronouns_custom = Personnalisรฉs
pronouns = Pronoms
pronouns_unspecified = Non spรฉcifiรฉs
language.title = Langue par dรฉfaut
+keep_activity_private.description = Vous seul pourrez voir votre activitรฉ publique , ainsi que les administrateurs de l'instance.
+language.localization_project = Aidez-nous ร traduire Forgejo dans votre langueย ! En savoir plus .
+language.description = Cette langue sera enregistrรฉe dans votre compte et utilisรฉe comme langue par dรฉfaut aprรจs votre connexion.
+user_block_yourself = Vous ne pouvez pas vous bloquer vous mรชme.
+pronouns_custom_label = Pronoms personnalisรฉs
+change_username_redirect_prompt.with_cooldown.one = L'ancien pseudonyme sera disponible pour n'importe qui aprรจs une pรฉriode d'%[1]d jour, vous pouvez toujours rรฉclamer votre ancien pseudonyme pendant cette pรฉriode.
+change_username_redirect_prompt.with_cooldown.few = L'ancien pseudonyme sera disponible pour n'importe qui aprรจs une pรฉriode de %[1]d jours, vous pouvez toujours rรฉclamer votre ancien pseudonyme pendant cette pรฉriode.
+
+storage_overview = Vue d'ensemble du stockage
+quota = Quota
+keep_pronouns_private = Ne montrer les pronoms qu'aux utilisateurs authentifiรฉs
+keep_pronouns_private.description = Cela masquera votre pronoms aux visiteurs qui ne sont pas authentifiรฉs.
+regenerate_token = Rรฉgรฉnรฉrer
+access_token_regeneration = Rรฉgรฉnรฉrer le token d'accรจs
+access_token_regeneration_desc = La rรฉgรฉnรฉration d'un token rรฉvoquera l'accรจs ร votre compte pour les applications qui l'utilisaient. Cela n'est pas reversible. Continuer ?
+regenerate_token_success = Le token a รฉtรฉ rรฉgรฉnรฉrรฉ. Les applications qui l'utilisent n'ont plus accรจs ร votre compte et doivent รชtre mises ร jour avec le nouveau token.
+quota.applies_to_user = Les quotas suivants s'appliquent ร votre compte
+quota.applies_to_org = Les quotas suivants s'applique ร cette organisation
+quota.rule.exceeded = Dรฉpassรฉ
+quota.rule.exceeded.helper = La taille totale des objets pour cette rรจgle ont dรฉpassรฉ le quota.
+quota.rule.no_limit = Sans limite
+quota.sizes.all = Tout
+quota.sizes.repos.all = Dรฉpรดts
+quota.sizes.repos.public = Dรฉpรดts publics
+quota.sizes.repos.private = Dรฉpรดts privรฉs
+quota.sizes.git.all = Contenu dans Git
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.all = Contenus
+quota.sizes.assets.attachments.all = Attachements
+quota.sizes.assets.attachments.issues = Attachements de tickets
+quota.sizes.assets.attachments.releases = Attachements de version
+quota.sizes.assets.artifacts = Artefacts
+quota.sizes.assets.packages.all = Paquets
+quota.sizes.wiki = Wiki
[repo]
-new_repo_helper=Un dรฉpรดt contient tous les fichiers dโun projet, ainsi que lโhistorique de leurs modifications. Vous avez dรฉjร รงa ailleurs ? Migrez-le ici.
+new_repo_helper=Un dรฉpรดt contient tous les fichiers dโun projet, ainsi que lโhistorique de leurs modifications. Vous avez dรฉjร รงa ailleurs ? Migrez-le ici. .
owner=Propriรฉtaire
owner_helper=Certaines organisations peuvent ne pas apparaรฎtre dans la liste dรฉroulante en raison d'une limite maximale du nombre de dรฉpรดts.
repo_name=Nom du dรฉpรดt
repo_name_helper=Idรฉalement, le nom d'un dรฉpรดt devrait รชtre court, mรฉmorisable et unique.
repo_size=Taille du dรฉpรดt
template=Modรจle
-template_select=Sรฉlectionner un modรจle.
+template_select=Sรฉlectionner un modรจle
template_helper=Faire de ce dรฉpรดt un modรจle
template_description=Les rรฉfรฉrentiels de modรจles permettent aux utilisateurs de gรฉnรฉrer de nouveaux rรฉfรฉrentiels avec la mรชme structure de rรฉpertoire, fichiers et paramรจtres optionnels.
visibility=Visibilitรฉ
@@ -1043,17 +1128,17 @@ generate_from=Gรฉnรฉrer depuis
repo_desc=Description
repo_desc_helper=Dรฉcrire briรจvement votre dรฉpรดt
repo_lang=Langue
-repo_gitignore_helper=Sรฉlectionner quelques .gitignore prรฉdรฉfinies.
+repo_gitignore_helper=Sรฉlectionner quelques .gitignore prรฉdรฉfinis
repo_gitignore_helper_desc=De nombreux outils et compilateurs gรฉnรจrent des fichiers rรฉsiduels qui n'ont pas besoin d'รชtre supervisรฉs par git. Composez un .gitignore ร lโaide de cette liste des languages de programmation courants.
-issue_labels=Jeu de labels pour les tickets
-issue_labels_helper=Sรฉlectionner un jeu de label.
+issue_labels=รtiquettes
+issue_labels_helper=Sรฉlectionner un jeu d'รฉtiquettes
license=Licence
-license_helper=Sรฉlectionner une licence.
-license_helper_desc=Une licence rรฉglemente ce que les autres peuvent ou ne peuvent pas faire avec votre code. Vous ne savez pas laquelle est la bonne pour votre projet ? Comment choisir une licence.
+license_helper=Sรฉlectionner une licence
+license_helper_desc=Une licence rรฉglemente ce que les autres peuvent ou ne peuvent pas faire avec votre code. Vous ne savez pas laquelle est la bonne pour votre projet ? Comment choisir une licence. .
readme=LISEZMOI
-readme_helper=Choisissez un modรจle de fichier LISEZMOI.
+readme_helper=Choisissez un modรจle de fichier LISEZMOI
readme_helper_desc=Le README est l'endroit idรฉal pour dรฉcrire votre projet et accueillir des contributeurs.
-auto_init=Initialiser le dรฉpรดt (avec un .gitignore, une Licence et un README.md)
+auto_init=Initialiser le dรฉpรดt
trust_model_helper=Choisissez, parmi les รฉlรฉments suivants, les rรจgles de confiance des signatures paraphant les rรฉvisions :
trust_model_helper_collaborator=Collaborateur : ne se fier qu'aux signatures des collaborateurs du dรฉpรดt
trust_model_helper_committer=Auteur : ne se fier qu'aux signatures des auteurs de rรฉvisions
@@ -1067,7 +1152,7 @@ mirror_prune=Purger
mirror_prune_desc=Supprimer les rรฉfรฉrences externes obsolรจtes
mirror_interval=Intervalle de synchronisation (les unitรฉs de temps valides sont "h", "m" et "s"). 0 pour dรฉsactiver la synchronisation automatique. (Intervalle minimum : %s)
mirror_interval_invalid=L'intervalle de synchronisation est invalide.
-mirror_sync=synchronisรฉ
+mirror_sync = synchronisรฉ
mirror_sync_on_commit=Synchroniser quand les rรฉvisions sont soumis
mirror_address=Cloner depuis une URL
mirror_address_desc=Insรฉrez tous les identifiants requis dans la section Autorisation.
@@ -1118,8 +1203,7 @@ desc.public=Publique
desc.template=Modรจle
desc.internal=Interne
desc.archived=Archivรฉ
-desc.sha256=SHA256
-
+desc.sha256 = SHA256
template.items=รlรฉment du modรจle
template.git_content=Contenu Git (branche par dรฉfaut)
template.git_hooks=Dรฉclencheurs Git
@@ -1172,14 +1256,14 @@ migrate.migrate_items_options=Un jeton d'accรจs est requis pour migrer des รฉlรฉ
migrated_from=Migrรฉ de %[2]s
migrated_from_fake=Migrรฉ de %[1]s
migrate.migrate=Migrer depuis %s
-migrate.migrating=Migration de %s ...
+migrate.migrating=Migration de %s โฆ
migrate.migrating_failed=La migration de %s a รฉchouรฉ.
migrate.migrating_failed.error=รchec de la migration : %s
migrate.migrating_failed_no_addr=รchec de la migration.
migrate.github.description=Migrer les donnรฉes depuis github.com ou GitHub Enterprise Server.
migrate.git.description=Migrer uniquement un dรฉpรดt depuis nโimporte quel service Git.
migrate.gitlab.description=Migrer les donnรฉes depuis gitlab.com ou dโautres instances de GitLab.
-migrate.gitea.description=Migrer les donnรฉes depuis gitea.com ou dโautres instances de Gitea/Forgejo.
+migrate.gitea.description=Migrer les donnรฉes depuis gitea.com ou dโautres instances de Gitea.
migrate.gogs.description=Migrer les donnรฉes depuis notabug.org ou dโautres instances de Gogs.
migrate.onedev.description=Migrer les donnรฉes depuis code.onedev.io ou dโautre instance de OneDev.
migrate.codebase.description=Migrer les donnรฉes depuis codebasehq.com.
@@ -1267,10 +1351,11 @@ view_git_blame=Voir Git blame
video_not_supported_in_browser=Votre navigateur ne supporte pas la balise ยซย vidรฉoย ยป HTML5.
audio_not_supported_in_browser=Votre navigateur ne supporte pas la balise ยซย audioย ยป HTML5.
stored_lfs=Stockรฉ avec Git LFS
+stored_annex=Stockรฉ avec Git Annex
symbolic_link=Lien symbolique
executable_file=Fichier exรฉcutable
-vendored=Externe
-generated=Gรฉnรฉrรฉe
+vendored = Vendored
+generated = Gรฉnรฉrรฉ
commit_graph=Graphe des rรฉvisions
commit_graph.select=Sรฉlectionner les branches
commit_graph.hide_pr_refs=Masquer les demandes d'ajout
@@ -1292,6 +1377,7 @@ editor.upload_file=Tรฉlรฉverser un fichier
editor.edit_file=Modifier le fichier
editor.preview_changes=Aperรงu des modifications
editor.cannot_edit_lfs_files=Les fichiers LFS ne peuvent pas รชtre modifiรฉs dans l'interface web.
+editor.cannot_edit_annex_files=Les fichiers Annex ne peuvent pas รชtre modifiรฉs dans l'interface web.
editor.cannot_edit_non_text_files=Les fichiers binaires ne peuvent pas รชtre รฉditรฉs dans l'interface web.
editor.edit_this_file=Modifier le fichier
editor.this_file_locked=Le fichier est verrouillรฉ
@@ -1306,7 +1392,7 @@ editor.or=ou
editor.cancel_lower=Annuler
editor.commit_signed_changes=Rรฉviser les changements (signรฉ)
editor.commit_changes=Rรฉviser les changements
-editor.add_tmpl=Ajouter ""
+editor.add_tmpl=Ajouter "<%s>"
editor.add=Ajouter %s
editor.update=Actualiser %s
editor.delete=Supprimer %s
@@ -1316,7 +1402,7 @@ editor.fail_to_apply_patch=`Impossible d'appliquer le correctif "%s"`
editor.new_patch=Nouveau correctif
editor.commit_message_desc=Ajouter une description dรฉtaillรฉe facultativeโฆ
editor.signoff_desc=Crรฉditer l'auteur "Signed-off-by:" en pied de rรฉvision.
-editor.commit_directly_to_this_branch=Rรฉviser directement dans la branche %s .
+editor.commit_directly_to_this_branch=Rรฉviser directement dans la branche %[1]s .
editor.create_new_branch=Crรฉer une nouvelle branche pour cette rรฉvision et initier une demande d'ajout.
editor.create_new_branch_np=Crรฉer une nouvelle branche pour cette rรฉvision.
editor.propose_file_change=Proposer une modification du fichier
@@ -1332,7 +1418,7 @@ editor.file_is_a_symlink=`ยซย %sย ยป est un lien symbolique. Ce type de fichiers
editor.filename_is_a_directory=ยซย %sย ยป est dรฉjร utilisรฉ comme nom de dossier dans ce dรฉpรดt.
editor.file_editing_no_longer_exists=Impossible de modifier le fichier ยซย %sย ยป car il nโexiste plus dans ce dรฉpรดt.
editor.file_deleting_no_longer_exists=Impossible de supprimer le fichier ยซย %sย ยป car il nโexiste plus dans ce dรฉpรดt.
-editor.file_changed_while_editing=Le contenu du fichier a changรฉ depuis que vous avez commencรฉ ร รฉditer. Cliquez ici pour voir les changements ou soumettez de nouveau pour les รฉcraser.
+editor.file_changed_while_editing=Le contenu du fichier a changรฉ depuis que vous avez ouvert le fichier. Cliquez ici pour voir les changements ou soumettez de nouveau pour les รฉcraser.
editor.file_already_exists=Un fichier nommรฉ "%s" existe dรฉjร dans ce dรฉpรดt.
editor.commit_empty_file_header=Rรฉviser un fichier vide
editor.commit_empty_file_text=Le fichier que vous allez rรฉviser est vide. Continuer ?
@@ -1386,7 +1472,7 @@ commitstatus.failure=รchec
commitstatus.pending=En attente
commitstatus.success=Succรจs
-ext_issues=Accรจs aux tickets externes
+ext_issues=Tickets externes
ext_issues.desc=Lien vers un gestionnaire de tickets externe.
projects=Projets
@@ -1567,17 +1653,17 @@ issues.no_content=Sans contenu.
issues.close=Fermer le ticket
issues.comment_pull_merged_at=a fusionnรฉ la rรฉvision %[1]s dans %[2]s %[3]s
issues.comment_manually_pull_merged_at=a fusionnรฉ manuellement la rรฉvision %[1]s dans %[2]s %[3]s
-issues.close_comment_issue=Commenter et fermer
+issues.close_comment_issue=Fermer avec le commentaire
issues.reopen_issue=Rouvrir
-issues.reopen_comment_issue=Commenter et rรฉouvrir
+issues.reopen_comment_issue=Rรฉouvrir avec le commentaire
issues.create_comment=Commenter
issues.closed_at=`a fermรฉ ce ticket %[2]s .`
-issues.reopened_at=`a rรฉouvert ce ticket %[2]s .`
+issues.reopened_at=`a rouvert ce ticket %[2]s .`
issues.commit_ref_at=`a rรฉfรฉrencรฉ ce ticket depuis une rรฉvision %[2]s .`
issues.ref_issue_from=`a fait rรฉfรฉrence ร %[4]s ce ticket %[2]s .`
issues.ref_pull_from=`a fait rรฉfรฉrence ร cette demande d'ajout %[4]s %[2]s .`
issues.ref_closing_from=`a fait rรฉfรฉrence ร une demande d'ajout %[4]s qui clora ce ticket, %[2]s .`
-issues.ref_reopening_from=`a rรฉfรฉrencรฉ une pull request %[4]s qui va rรฉouvrir ce ticket %[2]s `
+issues.ref_reopening_from=`a rรฉfรฉrencรฉ une pull request %[4]s qui va rรฉ-ouvrir ce ticket %[2]s `
issues.ref_closed_from=`a fermรฉ ce ticket %[4]s %[2]s `
issues.ref_reopened_from=`a rouvert ce ticket %[4]s %[2]s .`
issues.ref_from=`de %[1]s`
@@ -1682,7 +1768,7 @@ issues.error_modifying_due_date=Impossible de modifier l'รฉchรฉance.
issues.error_removing_due_date=Impossible de supprimer l'รฉchรฉance.
issues.push_commit_1=a ajoutรฉ %d rรฉvision %s
issues.push_commits_n=a ajoutรฉ %d rรฉvisions %s
-issues.force_push_codes=`a forcรฉ %[1]s de %[2]s
ร %[4]s
%[6]s.`
+issues.force_push_codes=`a forcรฉ %[1]s de %[2]s
ร %[4]s
%[6]s.`
issues.force_push_compare=Comparer
issues.due_date_form=aaaa-mm-jj
issues.due_date_form_add=Ajouter une รฉchรฉance
@@ -1732,12 +1818,12 @@ issues.review.approve=a approuvรฉ ces modifications %s
issues.review.comment=a รฉvaluรฉ cette demande dโajout %s
issues.review.dismissed=a rรฉvoquรฉ lโรฉvaluation de %s %s
issues.review.dismissed_label=Rรฉvoquรฉe
-issues.review.left_comment=laisser un commentaire
+issues.review.left_comment=a laissรฉ un commentaire
issues.review.content.empty=Vous devez laisser un commentaire indiquant le(s) changement(s) demandรฉ(s).
issues.review.reject=a requis les changements %s
issues.review.wait=a รฉtรฉ sollicitรฉ pour รฉvaluer cette demande dโajout %s
-issues.review.add_review_request=a demandรฉ ร %s une รฉvaluation %s
-issues.review.remove_review_request=a retirรฉ la demande dโรฉvaluation pour %s %s
+issues.review.add_review_request=demande d'รฉvaluation de %[1]s %[2]s
+issues.review.remove_review_request=demande dโรฉvaluation retirรฉe pour %[1]s %[2]s
issues.review.remove_review_request_self=a refusรฉ dโรฉvaluer cette demande dโajout %s
issues.review.pending=En attente
issues.review.pending.tooltip=Ce commentaire n'est pas encore visible par les autres utilisateurs. Pour soumettre vos commentaires en attente, sรฉlectionnez "%s" โ "%s/%s/%s" en haut de la page.
@@ -1797,7 +1883,7 @@ pulls.nothing_to_compare=Ces branches sont identiques. Il nโy a pas besoin de
pulls.nothing_to_compare_and_allow_empty_pr=Ces branches sont รฉgales. Cette demande d'ajout sera vide.
pulls.has_pull_request='Il existe dรฉjร une demande d'ajout entre ces deux branches : %[2]s#%[3]d '
pulls.create=Crรฉer une demande d'ajout
-pulls.title_desc_few=souhaite fusionner %[1]d rรฉvision(s) depuis %[2]s
vers %[3]s
+pulls.title_desc_few=souhaite fusionner %[1]d rรฉvision(s) depuis %[2]s
vers %[3]s
pulls.merged_title_desc_few=a fusionnรฉ %[1]d rรฉvision(s) ร partir de %[2]s
vers %[3]s
%[4]s
pulls.change_target_branch_at=`a remplacรฉe la branche cible %s par %s %s`
pulls.tab_conversation=Discussion
@@ -1852,7 +1938,7 @@ pulls.merge_pull_request=Crรฉer une rรฉvision de fusion
pulls.rebase_merge_pull_request=Rebaser puis avancer rapidement
pulls.rebase_merge_commit_pull_request=Rebaser puis crรฉer une rรฉvision de fusion
pulls.squash_merge_pull_request=Crรฉer une rรฉvision de concatรฉnation
-pulls.fast_forward_only_merge_pull_request=Avance rapide uniquement
+pulls.fast_forward_only_merge_pull_request = Fast-forward uniquement
pulls.merge_manually=Fusionner manuellement
pulls.merge_commit_id=L'ID de la rรฉvision de fusion
pulls.require_signed_wont_sign=La branche nรฉcessite des rรฉvisions signรฉes mais cette fusion ne sera pas signรฉe
@@ -1887,7 +1973,7 @@ pulls.outdated_with_base_branch=Cette branche est dรฉsynchronisรฉe avec la branc
pulls.close=Fermer la demande dโajout
pulls.closed_at=`a fermรฉ cette demande d'ajout %[2]s .`
pulls.reopened_at=`a rouvert cette demande d'ajout %[2]s .`
-pulls.cmd_instruction_hint=`Voir les instructions en ligne de commande .`
+pulls.cmd_instruction_hint=Voir les instructions en ligne de commande
pulls.cmd_instruction_checkout_title=Basculer
pulls.cmd_instruction_checkout_desc=Depuis votre dรฉpรดt, basculer sur une nouvelle branche et tester des modifications.
pulls.cmd_instruction_merge_title=Fusionner
@@ -1958,7 +2044,7 @@ signing.wont_sign.commitssigned=La fusion ne sera pas signรฉe car ses rรฉvisions
signing.wont_sign.approved=La fusion ne sera pas signรฉe car la demande d'ajout n'a pas รฉtรฉ approuvรฉe.
signing.wont_sign.not_signed_in=Vous n'รชtes pas connectรฉ.
-ext_wiki=Accรจs au wiki externe
+ext_wiki=Wiki externe
ext_wiki.desc=Lier un wiki externe.
wiki=Wiki
@@ -1989,7 +2075,7 @@ wiki.page_name_desc=Entrez un nom pour cette page Wiki. Certains noms spรฉciaux
wiki.original_git_entry_tooltip=Voir le fichier Git original au lieu d'utiliser un lien convivial.
activity=Activitรฉ
-activity.navbar.contributors=Contributeurs
+activity.navbar.contributors = Contributeurs
activity.period.filter_label=Pรฉriodeย :
activity.period.daily=1 jour
activity.period.halfweekly=3 jours
@@ -2032,7 +2118,7 @@ activity.unresolved_conv_label=Ouvrir
activity.title.releases_1=%d publication
activity.title.releases_n=%d publications
activity.title.releases_published_by=%s publiรฉe par %s
-activity.published_release_label=Publiรฉe
+activity.published_release_label=Publication
activity.no_git_activity=Il n'y a pas eu de nouvelle rรฉvision dans cette pรฉriode.
activity.git_stats_exclude_merges=En excluant les fusions,
activity.git_stats_author_1=%d auteur
@@ -2055,11 +2141,10 @@ activity.git_stats_and_deletions=et
activity.git_stats_deletion_1=%d suppression
activity.git_stats_deletion_n=%d suppressions
-contributors.contribution_type.filter_label=Type de contribution :
-contributors.contribution_type.commits=Rรฉvisions
-contributors.contribution_type.additions=Ajouts
-contributors.contribution_type.deletions=Suppressions
-
+contributors.contribution_type.filter_label = Type de contributeur :
+contributors.contribution_type.commits = Commits
+contributors.contribution_type.additions = Ajouts
+contributors.contribution_type.deletions = Suppressions
search=Chercher
search.search_repo=Rechercher dans le dรฉpรดt
search.type.tooltip=Type de recherche
@@ -2286,39 +2371,39 @@ settings.event_push_desc=Soumission Git.
settings.event_repository=Dรฉpรดt
settings.event_repository_desc=Dรฉpรดt crรฉรฉ ou supprimรฉ.
settings.event_header_issue=รvรฉnements de ticket
-settings.event_issues=Ticket
+settings.event_issues=Modification
settings.event_issues_desc=Ticket ouvert, rouvert, fermรฉ ou modifiรฉ.
-settings.event_issue_assign=Ticket assignรฉ
+settings.event_issue_assign=Assignรฉ
settings.event_issue_assign_desc=Ticket assignรฉ ou dรฉ-assignรฉ.
-settings.event_issue_label=Ticket รฉtiquetรฉ
+settings.event_issue_label=รtiquetรฉ
settings.event_issue_label_desc=Labels attribuรฉs ou retirรฉs.
-settings.event_issue_milestone=Ticket jalonnรฉ
+settings.event_issue_milestone=Jalonnรฉ
settings.event_issue_milestone_desc=Ticket jalonnรฉ ou dรฉ-jalonnรฉ.
-settings.event_issue_comment=Ticket commentรฉ
+settings.event_issue_comment=Commentรฉ
settings.event_issue_comment_desc=Commentaire crรฉรฉ, modifiรฉ ou supprimรฉ.
settings.event_header_pull_request=รvรฉnements de demande d'ajout
settings.event_pull_request=Demande d'ajout
settings.event_pull_request_desc=Demande dโajout ouverte, rouverte, fermรฉe ou modifiรฉe.
-settings.event_pull_request_assign=Demande d'ajout assignรฉe
+settings.event_pull_request_assign=Assignรฉe
settings.event_pull_request_assign_desc=Demande d'ajout assignรฉe ou non assignรฉe.
-settings.event_pull_request_label=Demande d'ajout รฉtiquetรฉe
+settings.event_pull_request_label=รtiquetรฉe
settings.event_pull_request_label_desc=Label attribuรฉ ou retirรฉ.
-settings.event_pull_request_milestone=Demande d'ajout jalonnรฉe
-settings.event_pull_request_milestone_desc=Demande d'ajout jalonnรฉe ou dรฉ-jalonnรฉe.
-settings.event_pull_request_comment=Commentaire sur une demande d'ajout
+settings.event_pull_request_milestone=Jalonnรฉe
+settings.event_pull_request_milestone_desc=Jalonnรฉe ou dรฉ-jalonnรฉe.
+settings.event_pull_request_comment=Commentaires
settings.event_pull_request_comment_desc=Commentaire crรฉรฉ, modifiรฉ ou supprimรฉ.
-settings.event_pull_request_review=Demande d'ajout รฉvaluรฉe
-settings.event_pull_request_review_desc=Demande dโajout approuvรฉe, rejetรฉe ou commentรฉe.
-settings.event_pull_request_sync=Demande d'ajout synchronisรฉe
-settings.event_pull_request_sync_desc=Demande d'ajout synchronisรฉe.
-settings.event_pull_request_review_request=Requรชte dโรฉvaluation d'une demande d'ajout
+settings.event_pull_request_review=รvaluations
+settings.event_pull_request_review_desc=Demande dโajout approuvรฉe, rejetรฉe ou commentaires d'รฉvaluation ajoutรฉs.
+settings.event_pull_request_sync=Synchronisรฉe
+settings.event_pull_request_sync_desc=Branche mise ร jour automatiquement avec la branche cible.
+settings.event_pull_request_review_request=Requรชte dโรฉvaluation
settings.event_pull_request_review_request_desc=Crรฉation ou suppresion de demandes dโรฉvaluation.
settings.event_pull_request_approvals=Approbations de demande d'ajout
settings.event_pull_request_merge=Fusion de demande d'ajout
settings.event_package=Paquet
settings.event_package_desc=Paquet crรฉรฉ ou supprimรฉ.
settings.branch_filter=Filtre de branche
-settings.branch_filter_desc=Liste de branches et motifs globs autorisant la soumission, la crรฉation et suppression de branches. Laisser vide ou utiliser *
englobent toutes les branches. Voir la syntaxe Glob . Exemples : master
, {master,release*}
.
+settings.branch_filter_desc=Liste de branches et motifs globs autorisant la soumission, la crรฉation et suppression de branches. Laisser vide ou utiliser *
englobent toutes les branches. Voir la syntaxe Glob . Exemples : master
, {master,release*}
.
settings.authorization_header=En-tรชte ยซ Authorization ยป
settings.authorization_header_desc=Si prรฉsent, sera ajoutรฉ aux requรชtes comme en-tรชte dโauthentification. Exemplesย : %s.
settings.active=Actif
@@ -2383,41 +2468,41 @@ settings.protect_enable_merge_desc=Toute personne ayant un accรจs en รฉcriture s
settings.protect_whitelist_committers=Liste blanche des soumissions (push)
settings.protect_whitelist_committers_desc=Seuls les utilisateurs ou les รฉquipes autorisรฉs pourront soumettre sur cette branche (sans forcer).
settings.protect_whitelist_deploy_keys=Mettez les clรฉs de dรฉploiement sur liste blanche avec accรจs en รฉcriture pour soumettre.
-settings.protect_whitelist_users=Utilisateurs sur liste blanche :
+settings.protect_whitelist_users=Utilisateurs sur liste blanche pour pousser
settings.protect_whitelist_search_users=Rechercher des utilisateursโฆ
-settings.protect_whitelist_teams=รquipes sur liste blanche :
+settings.protect_whitelist_teams=รquipes sur liste blanche pour pousser
settings.protect_whitelist_search_teams=Rechercher des รฉquipesโฆ
settings.protect_merge_whitelist_committers=Activer la liste blanche pour la fusion
settings.protect_merge_whitelist_committers_desc=N'autoriser que les utilisateurs et les รฉquipes en liste blanche d'appliquer les demandes de fusion sur cette branche.
-settings.protect_merge_whitelist_users=Utilisateurs en liste blanche de fusion :
-settings.protect_merge_whitelist_teams=รquipes en liste blanche de fusion :
+settings.protect_merge_whitelist_users=Utilisateurs en liste blanche pour fusionner
+settings.protect_merge_whitelist_teams=รquipes en liste blanche pour fusionner
settings.protect_check_status_contexts=Activer le contrรดle de status
-settings.protect_status_check_patterns=Motifs de vรฉrification des statutsย :
+settings.protect_status_check_patterns=Motifs de vรฉrification des statuts
settings.protect_status_check_patterns_desc=Entrez des motifs pour spรฉcifier quelles vรฉrifications doivent rรฉussir avant que des branches puissent รชtre fusionnรฉes. Un motif par ligne. Un motif ne peut รชtre vide.
settings.protect_check_status_contexts_desc=Exiger le status ยซ succรจs ยป avant de fusionner. Quand activรฉe, une branche protรฉgรฉe ne peux accepter que des soumissions ou des fusions ayant le status ยซ succรจs ยป. Lorsqu'il n'y a pas de contexte, la derniรจre rรฉvision fait foi.
settings.protect_check_status_contexts_list=Contrรดles qualitรฉ trouvรฉs au cours de la semaine derniรจre pour ce dรฉpรดt
settings.protect_status_check_matched=Correspondant
settings.protect_invalid_status_check_pattern=Motif de vรฉrification des statuts incorrect : ยซย %sย ยป.
settings.protect_no_valid_status_check_patterns=Aucun motif de vรฉrification des statuts valide.
-settings.protect_required_approvals=Minimum d'approbations requis :
+settings.protect_required_approvals=Approbations requises
settings.protect_required_approvals_desc=Permet de fusionner les demandes dโajout lorsque suffisamment dโรฉvaluation sont positives.
settings.protect_approvals_whitelist_enabled=Restreindre les approbations aux utilisateurs ou aux รฉquipes en liste blanche
settings.protect_approvals_whitelist_enabled_desc=Seuls les รฉvaluations des utilisateurs ou des รฉquipes suivantes compteront dans les approbations requises. Si laissรฉ vide, les รฉvaluations de toute personne ayant un accรจs en รฉcriture seront comptabilisรฉes ร la place.
-settings.protect_approvals_whitelist_users=รvaluateurs autorisรฉs :
-settings.protect_approvals_whitelist_teams=รquipes dโรฉvaluateurs autorisรฉs :
+settings.protect_approvals_whitelist_users=รvaluateurs autorisรฉs
+settings.protect_approvals_whitelist_teams=รquipes dโรฉvaluateurs autorisรฉs
settings.dismiss_stale_approvals=Rรฉvoquer automatiquement les approbations pรฉrimรฉes
settings.dismiss_stale_approvals_desc=Lorsque des nouvelles rรฉvisions changent le contenu de la demande dโajout, les approbations existantes sont rรฉvoquรฉes.
-settings.ignore_stale_approvals=Ignorer les approbations obsolรจtes
-settings.ignore_stale_approvals_desc=Ignorer les approbations dโanciennes rรฉvisions (รฉvaluations obsolรจtes) du dรฉcompte des approbations de la demande dโajout. Non pertinent quand les รฉvaluations obsolรจtes sont dรฉjร rรฉvoquรฉes.
+settings.ignore_stale_approvals = Ignorer les approbations obsolรจtes
+settings.ignore_stale_approvals_desc = Ne pas prendre en compte les approbations faites sur d'anciens commits (revues obsolรจtes) dans le total des approbations pour cette PR. Sans effet si les revues obsolรจtes ont dรฉjร รฉtรฉ annulรฉes.
settings.require_signed_commits=Exiger des rรฉvisions (commits) signรฉes
settings.require_signed_commits_desc=Rejeter les soumissions sur cette branche lorsqu'ils ne sont pas signรฉs ou vรฉrifiables.
settings.protect_branch_name_pattern=Motif de nom de branche protรฉgรฉ
-settings.protect_branch_name_pattern_desc=Motifs de nom de branche protรฉgรฉ. Consultez la documentation pour la syntaxe du motif. Exemplesย :ย main, release/**
+settings.protect_branch_name_pattern_desc=Motifs de nom de branche protรฉgรฉ. Consultez la documentation pour la syntaxe du motif. Exemplesย :ย main, release/**
settings.protect_patterns=Motifs
-settings.protect_protected_file_patterns=Liste des fichiers et motifs protรฉgรฉs (sรฉparรฉs par un point virgule ";") :
-settings.protect_protected_file_patterns_desc=Les fichiers protรฉgรฉs ne peuvent รชtre modifiรฉs, mรชme si l'utilisateur a le droit d'ajouter, รฉditer ou supprimer des fichiers dans cette branche. Plusieurs motifs peuvent รชtre sรฉparรฉs par un point-virgule (";"). Veuillez voir github.com/gobwas/glob la documentation pour la syntaxe des motifs. Exemplesย : .drone.yml
, /docs/**/*.txt
.
-settings.protect_unprotected_file_patterns=Liste des fichiers et motifs exclus (sรฉparรฉs par un point virgule ";") :
-settings.protect_unprotected_file_patterns_desc=Les fichiers non-protรฉgรฉs qui peuvent รชtre modifiรฉs si l'utilisateur a le droit d'รฉcriture, prenant le pas sur les restrictions de push. Plusieurs motifs peuvent รชtre sรฉparรฉs par un point-virgule (";"). Veuillez voir github.com/gobwas/glob la documentation pour la syntaxe des motifs. Exemplesย : .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns=Motifs de fichiers protรฉgรฉs (sรฉparรฉs par un point virgule ";")
+settings.protect_protected_file_patterns_desc=Les fichiers protรฉgรฉs ne peuvent รชtre modifiรฉs, mรชme si l'utilisateur a le droit d'ajouter, รฉditer ou supprimer des fichiers dans cette branche. Plusieurs motifs peuvent รชtre sรฉparรฉs par un point-virgule (";"). Veuillez voir %[2]s la documentation pour la syntaxe des motifs. Exemplesย : .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns=Motifs de fichiers non protรฉgรฉs (sรฉparรฉs par un point virgule ";")
+settings.protect_unprotected_file_patterns_desc=Les fichiers non-protรฉgรฉs qui peuvent รชtre modifiรฉs si l'utilisateur a le droit d'รฉcriture, prenant le pas sur les restrictions de push. Plusieurs motifs peuvent รชtre sรฉparรฉs par un point-virgule (";"). Veuillez voir %[2]s la documentation pour la syntaxe des motifs. Exemplesย : .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=Activer la protection
settings.delete_protected_branch=Dรฉsactiver la protection
settings.update_protect_branch_success=La rรจgle de protection de branche "%s" a รฉtรฉ mise ร jour.
@@ -2449,7 +2534,7 @@ settings.tags.protection.allowed.teams=รquipes autorisรฉes
settings.tags.protection.allowed.noone=Personne
settings.tags.protection.create=Ajouter une rรจgle
settings.tags.protection.none=Il n'y a pas d'รฉtiquettes protรฉgรฉes.
-settings.tags.protection.pattern.description=Vous pouvez utiliser au choix un nom unique, un motif de glob ou une expression rรฉguliรจre qui correspondra ร plusieurs รฉtiquettes. Pour plus dโinformations, consultez le guide sur les รฉtiquettes protรฉgรฉes .
+settings.tags.protection.pattern.description=Vous pouvez utiliser au choix un nom unique, un motif de glob ou une expression rรฉguliรจre qui correspondra ร plusieurs รฉtiquettes. Pour plus dโinformations, consultez le guide sur les รฉtiquettes protรฉgรฉes .
settings.bot_token=Jeton (token) de bot
settings.chat_id=ID de conversation
settings.thread_id=ID du fil
@@ -2464,7 +2549,7 @@ settings.archive.error=Une erreur s'est produite lors de l'archivage du dรฉpรดt.
settings.archive.error_ismirror=Vous ne pouvez pas archiver un dรฉpรดt en miroir.
settings.archive.branchsettings_unavailable=Le paramรฉtrage des branches n'est pas disponible quand le dรฉpรดt est archivรฉ.
settings.archive.tagsettings_unavailable=Le paramรฉtrage des รฉtiquettes n'est pas disponible si le dรฉpรดt est archivรฉ.
-settings.archive.mirrors_unavailable=Les miroirs ne sont pas disponibles lorsque le dรฉpรดt est archivรฉ.
+settings.archive.mirrors_unavailable = Les miroirs ne sont pas disponibles si le dรฉpรดt a รฉtรฉ archivรฉ.
settings.unarchive.button=Dรฉsarchiver ce dรฉpรดt
settings.unarchive.header=Rรฉhabiliter ce dรฉpรดt
settings.unarchive.text=Rรฉhabiliter un dรฉpรดt dรฉgรจle les actions de rรฉvisions et de soumissions, la gestion des tickets et des demandes d'ajouts.
@@ -2485,12 +2570,12 @@ settings.lfs_invalid_locking_path=Chemin invalide : %s
settings.lfs_invalid_lock_directory=Impossible de verrouiller le rรฉpertoire : %s
settings.lfs_lock_already_exists=Verrou dรฉjร existant : %s
settings.lfs_lock=Verrou
-settings.lfs_lock_path=Chemin de fichier ร verrouiller...
+settings.lfs_lock_path=Chemin de fichier ร verrouillerโฆ
settings.lfs_locks_no_locks=Pas de verrous
settings.lfs_lock_file_no_exist=Le fichier verrouillรฉ n'existe pas dans la branche par dรฉfaut
settings.lfs_force_unlock=Forcer le dรฉverrouillage
settings.lfs_pointers.found=%d pointeur(s) sur blob trouvรฉs - %d associรฉs, %d non associรฉs (%d manquant dans le magasin)
-settings.lfs_pointers.sha=SHA du Blob
+settings.lfs_pointers.sha=SHA du blob
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=Dans le dรฉpรดt
settings.lfs_pointers.exists=Existe en magasin
@@ -2538,7 +2623,7 @@ diff.generated=gรฉnรฉrรฉe
diff.vendored=externe
diff.comment.add_line_comment=Commenter cette ligne
diff.comment.placeholder=Laisser un commentaire
-diff.comment.markdown_info=Formater avec Markdown.
+diff.comment.markdown_info=Formater avec Markdown est autorisรฉ.
diff.comment.add_single_comment=Commenter (simple)
diff.comment.add_review_comment=Commenter
diff.comment.start_review=Dรฉbuter une รฉvaluation
@@ -2617,7 +2702,7 @@ branch.delete_desc=La suppression dโune branche est permanente. Bien quโune
branch.deletion_success=La branche "%s" a รฉtรฉ supprimรฉe.
branch.deletion_failed=Impossible de supprimer la branche "%s".
branch.delete_branch_has_new_commits=La branche "%s" ne peut รชtre supprimรฉ, car de nouvelles rรฉvisions ont รฉtรฉ ajoutรฉes aprรจs la fusion.
-branch.create_branch=Crรฉer la branche %s
+branch.create_branch=Crรฉer la branche %s
branch.create_from=`de "%s"`
branch.create_success=La branche "%s" a รฉtรฉ crรฉรฉe.
branch.branch_already_exists=La branche "%s" existe dรฉjร dans ce dรฉpรดt.
@@ -2644,12 +2729,12 @@ branch.new_branch=Crรฉer une nouvelle branche
branch.new_branch_from=`Crรฉer une nouvelle branche ร partir de "%s"`
branch.renamed=La branche %s ร รฉtรฉ renommรฉe en %s.
-tag.create_tag=Crรฉer l'รฉtiquette %s
+tag.create_tag=Crรฉer l'รฉtiquette %s
tag.create_tag_operation=Crรฉer une รฉtiquette
tag.confirm_create_tag=Crรฉer une รฉtiquette
-tag.create_tag_from=`Crรฉer une nouvelle รฉtiquette ร partir de "%s"`
+tag.create_tag_from=Crรฉer une nouvelle รฉtiquette ร partir de ยซย %sย ยป
-tag.create_success=L'รฉtiquette "%s" a รฉtรฉ crรฉรฉe.
+tag.create_success=L'รฉtiquette ยซย %sย ยป a รฉtรฉ crรฉรฉe.
topic.manage_topics=Gรฉrer les sujets
topic.done=Terminรฉ
@@ -2670,24 +2755,17 @@ admin.manage_flags = Gรฉrer les drapeaux
admin.enabled_flags = Drapeaux actifs pour le dรฉpรดtโฏ:
clone_in_vscodium = Clone dans VSCodium
object_format_helper = Format des objets d'un dรฉpรดt. Ne peut pas รชtre changรฉ. SHA1 est le plus compatible.
-mirror_sync = synchronisรฉ
object_format = Format de l'objet
-desc.sha256 = SHA256
-generated = Gรฉnรฉrรฉ
migrate.forgejo.description = Migrer les donnรฉes depuis codeberg.org ou une autre instance Forgejo.
issues.comment.blocked_by_user = Vous ne pouvez pas crรฉer un commentaire sur ce ticket car vous avez รฉtรฉ bloquรฉ par le propriรฉtaire du dรฉpรดt ou l'auteur du ticket.
editor.invalid_commit_mail = Courriel invalide pour la crรฉation d'un commit.
commits.browse_further = Continuer la navigation
commits.renamed_from = Renommรฉ depuis %s
pulls.nothing_to_compare_have_tag = La branche ou le tag sรฉlectionnรฉ sont identiques.
-vendored = Vendored
-issues.blocked_by_user = Vous ne pouvez pas crรฉer un ticket sur ce dรฉpรดt car vous avez รฉtรฉ bloquรฉ par son propriรฉtaire.
+issues.blocked_by_user = Vous ne pouvez pas crรฉer de tickets sur ce dรฉpรดt car vous avez รฉtรฉ bloquรฉ par son propriรฉtaire.
pulls.blocked_by_user = Vous ne pouvez pas crรฉer une pull request sur ce dรฉpรดt car vous รชtes bloquรฉ par son propriรฉtaire.
wiki.cancel = Annuler
settings.wiki_globally_editable = Permettre l'รฉdition du wiki a tout le monde
-settings.ignore_stale_approvals = Ignorer les approbations obsolรจtes
-settings.ignore_stale_approvals_desc = Ne pas prendre en compte les approbations faites sur d'anciens commits (revues obsolรจtes) dans le total des approbations pour cette PR. Sans effet si les revues obsolรจtes ont dรฉjร รฉtรฉ annulรฉes.
-settings.archive.mirrors_unavailable = Les mirroirs ne sont pas disponibles si le dรฉpรดt a รฉtรฉ archivรฉ.
pulls.commit_ref_at = `a rรฉfรฉrencรฉ cette pull request depuis le commit %[2]s `
settings.new_owner_blocked_doer = Le nouveau propriรฉtaire vous a bloquรฉ.
settings.enter_repo_name = Confirmez en entrant le propriรฉtaire et le nom du dรฉpรดt exactement comme affichรฉ :
@@ -2702,17 +2780,11 @@ settings.add_collaborator_blocked_our = Il n'est pas possible d'ajouter ce colla
settings.wiki_rename_branch_main_notices_1 = Cette operation NE PEUT PAS รชtre annulรฉe.
settings.wiki_branch_rename_failure = Le nom de la branche associรฉe au wiki du dรฉpรดt n'a pu รชtre normalisรฉ.
pulls.reopen_failed.head_branch = La pull request ne peut pas รชtre re-ouverte car la branch d'origine n'existe plus.
-settings.units.units = Fonctionnalitรฉs des dรฉpรดt
-pulls.fast_forward_only_merge_pull_request = Fast-forward uniquement
+settings.units.units = Fonctionnalitรฉs
pulls.reopen_failed.base_branch = La pull request ne peut pas รชtre re-ouverte car la branche de destination n'existe plus.
settings.units.overview = Vue gรฉnรฉrale
-settings.units.add_more = Ajouter en plus...
+settings.units.add_more = Ajouter en plus
activity.navbar.pulse = Pouls
-activity.navbar.contributors = Contributeurs
-contributors.contribution_type.commits = Commits
-contributors.contribution_type.additions = Ajouts
-contributors.contribution_type.filter_label = Type de contributeur :
-contributors.contribution_type.deletions = Suppressions
pulls.made_using_agit = AGit
activity.navbar.code_frequency = Frรฉquence de code
activity.navbar.recent_commits = Commits rรฉcents
@@ -2721,7 +2793,7 @@ error.broken_git_hook = Les hooks Git de ce dรฉpรดt semblent cassรฉs. Rรฉfรฉrez
settings.confirmation_string = Chaine de confirmation
pulls.agit_explanation = Crรฉรฉ par le workflow AGit. AGit permet aux contributeurs de proposer des modifications en utilisant "git push" sans crรฉer une bifurcation ou une nouvelle branche.
pulls.merged_title_desc_one = fusionnรฉ %[1]d commit depuis %[2]s
vers %[3]s
%[4]s
-pulls.title_desc_one = veut fusionner %[1]d commit depuis %[2]s
vers %[3]s
+pulls.title_desc_one = veut fusionner %[1]d commit depuis %[2]s
vers %[3]s
stars = รtoiles
n_tag_few = %s รฉtiquettes
editor.commit_id_not_matching = Le fichier a รฉtรฉ modifiรฉ pendant que vous l'รฉditiez. Appliquez les modifications ร une nouvelle branche puis procรฉdez ร la fusion.
@@ -2768,13 +2840,89 @@ subscribe.issue.guest.tooltip = Authentifiez vous pour vous abonner ร ce ticket
subscribe.pull.guest.tooltip = Authentifiez vous pour suivre cette demande d'ajout.
n_release_one = %s publication
n_release_few = %s publications
+issues.author.tooltip.pr = Cet utilisateur est l'auteur de cette pull request.
+issues.author.tooltip.issue = Cet utilisateur est l'auteur de ce ticket.
+issues.edit.already_changed = Impossible de sauvegarder les changements du ticket car son contenu a dรฉjร รฉtรฉ modifiรฉ par un autre utilisateur. Veuillez recharger la page et essayer de l'รฉditer ร nouveau pour รฉviter d'รฉcraser ses changements
+pulls.edit.already_changed = Impossible de sauvegarder les changements de la pull request car son contenu a dรฉjร รฉtรฉ modifiรฉ par un autre utilisateur. Veuillez recharger la page et essayer de l'รฉditer ร nouveau pour รฉviter d'รฉcraser ses changements
+settings.federation_following_repos = Les URL des dรฉpรดts suivis sรฉparรฉs par ";", sans espace.
+settings.federation_not_enabled = La fรฉdรฉration n'est pas activรฉe pour votre instance.
+comments.edit.already_changed = Impossible de sauvegarder les changements du commentaire car son contenu a dรฉjร รฉtรฉ modifiรฉ par un autre utilisateur. Veuillez recharger la page et essayer de l'รฉditer ร nouveau pour รฉviter d'รฉcraser ses changements
+settings.federation_apapiurl = URL de fรฉdรฉration de ce dรฉpรดt. A copier-coller dans les paramรจtres de fรฉdรฉrations d'un autre dรฉpรดt comme URL d'un dรฉpรดt ร suivre.
+mirror_denied_combination = Il n'est pas possible de combiner une authentification par clรฉ publique et par mot de passe.
+mirror_public_key = Clรฉ SSH publique
+mirror_use_ssh.text = Utiliser l'authentification SSH
+mirror_use_ssh.helper = Forgejo va crรฉer un miroir du dรฉpรดt via Git sur SSH et crรฉer une paire de clรฉs pour vous lorsque vous sรฉlectionnez cette option. Vous devez vous assurer que la clรฉ publique gรฉnรฉrรฉe est autorisรฉe ร pousser dans le dรฉpรดt de destination. Il n'est pas possible d'utiliser l'autorisation basรฉe sur un mot de passe si vous choisissez cette option.
+no_eol.text = Pas d'EOL
+mirror_use_ssh.not_available = L'authentification par SSH n'est pas disponible.
+no_eol.tooltip = Ce fichier ne contient pas de caractรจre final de fin de ligne.
+release.type_attachment = Piรจce jointe
+settings.transfer_quota_exceeded = Le nouvel utilisateur (%s) a dรฉpassรฉ son quota. Le dรฉpรดt n'a pas รฉtรฉ transfรฉrรฉ.
+settings.pull_mirror_sync_quota_exceeded = Quota dรฉpassรฉ, les modifications ne sont pas tirรฉes.
+activity.commit = Activitรฉ de commit
+settings.mirror_settings.push_mirror.copy_public_key = Copier la clรฉ publique
+release.asset_external_url = URL externe
+release.invalid_external_url = URL externe non valableย : "%sย "
+milestones.filter_sort.name = Nom
+settings.mirror_settings.push_mirror.none_ssh = Aucun
+settings.protect_new_rule = Crรฉer une nouvelle rรจgle de protection de branche
+pulls.cmd_instruction_merge_warning = Avertissement : Le paramรจtre "dรฉtection automatique de la fusion manuelle" n'est pas activรฉ pour ce dรฉpรดt, vous devrez marquer cette demande d'ajout comme manuellement fusionnรฉe aprรจs.
+release.type_external_asset = Actif externe
+activity.published_prerelease_label = Prรฉ-version
+activity.published_tag_label = รtiquette
+release.asset_name = Nom de l'actif
+release.add_external_asset = Ajouter un actif externe
+issues.new.assign_to_me = Assigner ร moi-mรชme
+issues.all_title = Tous
+settings.discord_icon_url.exceeds_max_length = L'URL de lโicรดne ne doit pas dรฉpasser 2048 caractรจres
+issues.review.add_review_requests = demandes d'รฉvaluation de %[1]s %[2]s
+issues.review.remove_review_requests = demandes dโรฉvaluation retirรฉe pour %[1]s %[2]s
+issues.review.add_remove_review_requests = demandes d'รฉvaluation pour %[1]s et demandes d'รฉvaluation retirรฉes pour %[2]s %[3]s
+pulls.delete_after_merge.head_branch.is_protected = La branche head que vous voulez supprimer est une branche protรฉgรฉe et ne peut pas รชtre supprimรฉe.
+pulls.delete_after_merge.head_branch.is_default = La branche head que vous voulez supprimer est la branche par dรฉfaut et ne peut pas รชtre supprimรฉe.
+pulls.delete_after_merge.head_branch.insufficient_branch = Vous n'avez pas le droit de supprimer la branche head.
+issues.filter_sort.relevance = Pertinence
+diff.git-notes.remove-body = Cette note sera supprimรฉe.
+diff.git-notes.add = Ajouter une note
+diff.git-notes.remove-header = Supprimer la note
+issues.summary_card_alt = Fiche de synthรจse d'un ticket nommรฉ "%s" dans le dรฉpรดt %s
+editor.add_tmpl.filename = fichier
+issues.num_reviews_one = %d revue
+issues.num_reviews_few = %d revues
+settings.default_update_style_desc = Style de mise ร jour des demandes de fusion qui sont en retard par rapport ร la branche de base.
+release.summary_card_alt = Carte rรฉsumรฉ de la publication dont le titre est "%s" dans le dรฉpรดt %s
+pulls.sign_in_require = Identifiez vous pour crรฉer une nouvelle demande d'ajout.
+new_from_template = Utiliser un modรจle
+new_from_template_description = Vous pouvez sรฉlectionner un modรจle de dรฉpรดt existant sur cette instance et appliquer ses paramรจtres.
+new_advanced = Options avancรฉes
+new_advanced_expand = Cliquer pour dรฉvelopper
+auto_init_description = Dรฉbuter l'historique Git avec un README et ajouter en option les fichier de licence et .gitignore.
+issues.reaction.add = Ajouter une rรฉaction
+issues.reaction.alt_few = %[1]s a rรฉagit %[2]s.
+issues.reaction.alt_many = %[1]s et %[2]d de plus ont rรฉagit %[3]s.
+issues.reaction.alt_remove = Enlever la rรฉaction %[1]s du commentaire.
+issues.reaction.alt_add = Ajouter la rรฉaction %[1]s du commentaire.
+issues.context.menu = Menu commentaire
+summary_card_alt = Carte rรฉsumรฉ du dรฉpรดt %s
+archive.pull.noreview = Ce dรฉpรดt est archivรฉ. Vous ne pouvez pas faire de revue de demandes d'ajout.
+editor.commit_email = Courriel de commit
+commits.view_single_diff = Voir les changements dans ce fichier introduit par ce commit
+
+issues.filter_no_results = Pas de rรฉsultats
+issues.filter_no_results_placeholder = Essayez d'ajuster vos critรจres de recherche.
+issues.reopen.blocked_by_user = Vous ne pouvez pas rรฉ-ouvrir ce ticket care vous รชtes bloquรฉs par le propriรฉtaire du dรฉpรดt ou le crรฉateur de ce ticket.
+pulls.editable = Editable
+pulls.editable_explanation = Cette pull request peut รชtre รฉditรฉe par les mainteneurs. Vous pouvez y contribuer directement.
[graphs]
-component_loading=Chargement de %sโฆ
-component_loading_failed=Impossible de charger %s.
-component_loading_info=รa prend son tempsโฆ
-component_failed_to_load=Une erreur inattendue sโest produite.
-contributors.what=contributions
+component_loading = Chargement %sโฆ
+component_loading_failed = รchec de chargement de %s
+
+component_loading_info = Cela peut prendre du tempsโฆ
+component_failed_to_load = Une erreur inattendue s'est produite.
+contributors.what = contributions
+code_frequency.what = fลequence de code
+recent_commits.what = commits rรฉcents
+
[org]
org_name_holder=Nom de l'organisation
@@ -2813,7 +2961,7 @@ settings.permission=Autorisations
settings.repoadminchangeteam=L'administrateur de dรฉpรดt peut ajouter et supprimer l'accรจs aux รฉquipes
settings.visibility=Visibilitรฉ
settings.visibility.public=Public
-settings.visibility.limited=Limitรฉ (Visible uniquement aux utilisateurs authentifiรฉs)
+settings.visibility.limited=Limitรฉ (Visible uniquement aux utilisateurs connectรฉs)
settings.visibility.limited_shortname=Limitรฉ
settings.visibility.private=Privรฉ (visible uniquement aux membres de lโorganisation)
settings.visibility.private_shortname=Privรฉ
@@ -2844,18 +2992,18 @@ members.member=Membre
members.remove=Exclure
members.remove.detail=Supprimer %[1]s de %[2]sโฏ?
members.leave=Quitter
-members.leave.detail=Quitter %sโฏ?
+members.leave.detail=รtes vous certainยทe de vouloir quitter l'organisation ยซ%sยปโฏ?
members.invite_desc=Ajouter un nouveau membre ร %s :
members.invite_now=Envoyer une invitation
teams.join=Rejoindre
teams.leave=Quitter
-teams.leave.detail=Quitter %sโฏ?
+teams.leave.detail=รtes vous certainยทe de vouloir quitter l'รฉquipe ยซ%sยปโฏ?
teams.can_create_org_repo=Crรฉer des dรฉpรดts
teams.can_create_org_repo_helper=Les membres peuvent crรฉer de nouveaux dรฉpรดts dans l'organisation. Le crรฉateur obtiendra l'accรจs administrateur au nouveau dรฉpรดt.
teams.none_access=Aucun accรจs
-teams.none_access_helper=Les membres ne peuvent voir ou faire quoi que ce soit sur cette partie. Sans effet pour les dรฉpรดts publics.
-teams.general_access=Accรจs gรฉnรฉral
+teams.none_access_helper=L'option "Aucun accรจs" n'a pas d'effet sur les dรฉpรดts privรฉs.
+teams.general_access=Accรจs personnalisรฉ
teams.general_access_helper=Les permissions des membres seront dรฉterminรฉes par la table des permissions ci-dessous.
teams.read_access=Lecture
teams.read_access_helper=Les membres peuvent voir et cloner les dรฉpรดts de l'รฉquipe.
@@ -2901,10 +3049,12 @@ teams.invite.by=Invitรฉ par %s
teams.invite.description=Veuillez cliquer sur le bouton ci-dessous pour rejoindre lโรฉquipe.
follow_blocked_user = Vous ne pouvez pas suivre cette organisation car elle vous a bloquรฉ.
open_dashboard = Ouvrir le tableau de bord
+settings.change_orgname_redirect_prompt.with_cooldown.few = L'ancien nom d'organisation sera disponible pour n'importe qui aprรจs une pรฉriode de %[1]d jours, vous pouvez toujours rรฉclamer votre ancien nom d'organisation pendant cette pรฉriode.
+settings.change_orgname_redirect_prompt.with_cooldown.one = L'ancien nom d'organisation sera disponible pour n'importe qui aprรจs une pรฉriode d'%[1]d jour, vous pouvez toujours rรฉclamer votre ancien nom d'organisation pendant cette pรฉriode.
[admin]
dashboard=Tableau de bord
-self_check=Autodiagnostique
+self_check = Auto vรฉrification
identity_access=Identitรฉ et accรจs
users=Comptes utilisateurs
organizations=Organisations
@@ -2922,7 +3072,7 @@ last_page=Derniรจre
total=Total : %d
settings=Paramรจtres administrateur
-dashboard.new_version_hint=Forgejo %s est maintenant disponible, vous utilisez %s. Consultez le blog pour plus de dรฉtails.
+dashboard.new_version_hint=Forgejo %s est maintenant disponible, vous utilisez %s. Consultez le blog pour plus de dรฉtails.
dashboard.statistic=Rรฉsumรฉ
dashboard.operations=Opรฉrations de maintenance
dashboard.system_status=รtat du systรจme
@@ -2950,7 +3100,7 @@ dashboard.delete_missing_repos=Supprimer tous les dรฉpรดts dont les fichiers Git
dashboard.delete_missing_repos.started=Tรขche de suppression de tous les dรฉpรดts sans fichiers Git dรฉmarrรฉe.
dashboard.delete_generated_repository_avatars=Supprimer les avatars de dรฉpรดt gรฉnรฉrรฉs
dashboard.sync_repo_branches=Synchroniser les branches manquantes depuis Git vers la base de donnรฉe
-dashboard.sync_repo_tags=Synchroniser les รฉtiquettes git depuis les dรฉpรดts vers la base de donnรฉes
+dashboard.sync_repo_tags = Synchroniser les รฉtiquettes depuis Git vers la base de donnรฉe
dashboard.update_mirrors=Actualiser les miroirs
dashboard.repo_health_check=Vรฉrifier l'รฉtat de santรฉ de tous les dรฉpรดts
dashboard.check_repo_stats=Voir les statistiques de tous les dรฉpรดts
@@ -3000,12 +3150,12 @@ dashboard.delete_old_actions.started=Suppression de toutes les anciennes activit
dashboard.update_checker=Vรฉrificateur de mise ร jour
dashboard.delete_old_system_notices=Supprimer toutes les anciennes observations de la base de donnรฉes
dashboard.gc_lfs=รpousseter les mรฉtaobjets LFS
-dashboard.stop_zombie_tasks=Arrรชter les tรขches zombies
-dashboard.stop_endless_tasks=Arrรชter les tรขches sans fin
-dashboard.cancel_abandoned_jobs=Annuler les jobs abandonnรฉs
-dashboard.start_schedule_tasks=Dรฉmarrer les tรขches planifiรฉes
+dashboard.stop_zombie_tasks=Arrรชter les actions zombies
+dashboard.stop_endless_tasks=Arrรชter les actions sans fin
+dashboard.cancel_abandoned_jobs=Annuler les actions abandonnรฉes
+dashboard.start_schedule_tasks=Dรฉmarrer les actions planifiรฉes
dashboard.sync_branch.started=Dรฉbut de la synchronisation des branches
-dashboard.sync_tag.started=Synchronisation des รฉtiquettes
+dashboard.sync_tag.started = La synchronisation des รฉtiquettes a commencรฉ
dashboard.rebuild_issue_indexer=Reconstruire lโindexeur des tickets
users.user_manage_panel=Gestion du compte utilisateur
@@ -3035,9 +3185,9 @@ users.edit_account=Modifier un compte
users.max_repo_creation=Nombre maximal de dรฉpรดts
users.max_repo_creation_desc=(Mettre ร -1 pour utiliser la limite globale par dรฉfaut.)
users.is_activated=Ce compte est activรฉ
-users.prohibit_login=Dรฉsactiver la connexion
-users.is_admin=Est administrateur
-users.is_restricted=Est restreint
+users.prohibit_login=Suspendre le compte
+users.is_admin=Compte administrateurยทrice
+users.is_restricted=Compte restreint
users.allow_git_hook=Autoriser la crรฉation de dรฉclencheurs Git
users.allow_git_hook_tooltip=Les Dรฉclencheurs Git sont exรฉcutรฉs par le mรชme utilisateur que Forgejo, qui a des privilรจges systรจmes รฉlevรฉs. Les utilisateurs ayant ce droit peuvent altรฉrer touts les dรฉpรดts, compromettre la base de donnรฉes applicative, et se promouvoir administrateurs de Forgejo.
users.allow_import_local=Autoriser l'importation de dรฉpรดts locaux
@@ -3087,7 +3237,7 @@ orgs.new_orga=Nouvelle organisation
repos.repo_manage_panel=Gestion des dรฉpรดts
repos.unadopted=Dรฉpรดts non adoptรฉs
-repos.unadopted.no_more=Aucun dรฉpรดt dรฉpossรฉdรฉ trouvรฉ
+repos.unadopted.no_more=Aucun dรฉpรดt candidat ร l'adoption n'a รฉtรฉ trouvรฉ.
repos.owner=Propriรฉtaire
repos.name=Nom
repos.private=Privรฉ
@@ -3113,12 +3263,12 @@ packages.size=Taille
packages.published=Publiรฉs
defaulthooks=Dรฉclencheurs web par dรฉfaut
-defaulthooks.desc=Les webhooks font automatiquement des requรชtes POST HTTP ร un serveur spรฉcifiรฉ lorsque certains รฉvรฉnements Forgejo se dรฉclenchent. Ceux crรฉรฉs ici sont par dรฉfautย copiรฉs sur tous les nouveaux dรฉpรดts. Pour plus d'information, consultez le guide des webhooks .
+defaulthooks.desc=Les webhooks font automatiquement des requรชtes POST HTTP ร un serveur spรฉcifiรฉ lorsque certains รฉvรฉnements Forgejo se dรฉclenchent. Ceux crรฉรฉs ici sont par dรฉfautย copiรฉs sur tous les nouveaux dรฉpรดts. Pour plus d'information, consultez le guide des webhooks .
defaulthooks.add_webhook=Ajouter un dรฉclencheur web par dรฉfaut
defaulthooks.update_webhook=Mettre ร jour le dรฉclencheur web par dรฉfaut
systemhooks=Dรฉclencheurs systรจme
-systemhooks.desc=Les webhooks font automatiquement des requรชtes POST HTTP ร un serveur spรฉcifiรฉ lorsque certains รฉvรฉnements Forgejo se dรฉclenchent. Ceux crรฉรฉ ici agiront sur tous les dรฉpรดts, ce qui peux impacter les performances du systรจme. Pour plus dโinformation, consultez le guide des webhooks .
+systemhooks.desc=Les webhooks font automatiquement des requรชtes POST HTTP ร un serveur spรฉcifiรฉ lorsque certains รฉvรฉnements Forgejo se dรฉclenchent. Ceux crรฉรฉ ici agiront sur tous les dรฉpรดts, ce qui peux impacter les performances du systรจme. Pour plus dโinformation, consultez le guide des webhooks .
systemhooks.add_webhook=Ajouter un rappel systรจme
systemhooks.update_webhook=Mettre ร jour un rappel systรจme
@@ -3213,18 +3363,18 @@ auths.tips=Conseils
auths.tips.oauth2.general=Authentification OAuth2
auths.tips.oauth2.general.tip=Lors de l'enregistrement d'une nouvelle authentification OAuth2, l'URL de rappel/redirection doit รชtre :
auths.tip.oauth2_provider=Fournisseur OAuth2
-auths.tip.bitbucket=`Crรฉez un nouveau jeton OAuth sur https://bitbucket.org/account/user//oauth-consumers/new et ajoutez la permission "Compte"-"Lecture"`
+auths.tip.bitbucket=Crรฉez un nouveau jeton OAuth sur %s
auths.tip.nextcloud=`Enregistrez un nouveau consommateur OAuth sur votre instance en utilisant le menu "Paramรจtres -> Sรฉcuritรฉ -> Client OAuth 2.0"`
-auths.tip.dropbox=Crรฉez une nouvelle application sur https://www.dropbox.com/developers/apps
-auths.tip.facebook=`Enregistrez une nouvelle application sur https://developers.facebook.com/apps et ajoutez le produit "Facebook Login"`
-auths.tip.github=Crรฉez une nouvelle application OAuth sur https://github.com/settings/applications/new
+auths.tip.dropbox=Crรฉez une nouvelle application sur %s
+auths.tip.facebook=`Enregistrez une nouvelle application sur %s et ajoutez le produit "Facebook Login"`
+auths.tip.github=Crรฉez une nouvelle application OAuth sur %s
auths.tip.gitlab=Crรฉez une nouvelle application sur https://gitlab.com/profile/applications
-auths.tip.google_plus=Obtenez des identifiants OAuth2 sur la console API de Google (https://console.developers.google.com/)
+auths.tip.google_plus=Obtenez des identifiants OAuth2 sur la console API de Google (%s)
auths.tip.openid_connect=Utilisez l'URL de dรฉcouvert OpenID (/.well-known/openid-configuration) pour spรฉcifier les points d'accรจs
-auths.tip.twitter=Rendez-vous sur https://dev.twitter.com/apps, crรฉez une application et assurez-vous que l'option "Autoriser l'application ร รชtre utilisรฉe avec Twitter Connect" est activรฉe
-auths.tip.discord=Enregistrer une nouvelle application sur https://discordapp.com/developers/applications/me
-auths.tip.gitea=Enregistrez une nouvelle application OAuth2. Le guide peut รชtre trouvรฉ sur https://forgejo.org/docs/latest/user/oauth2-provider
-auths.tip.yandex=`Crรฉez une nouvelle application sur https://oauth.yandex.com/client/new. Sรฉlectionnez les autorisations suivantes dans la section "Yandex API passport" : "Accรจs ร l'adresse e-mail", "Accรจs ร l'avatar de l'utilisateur" et "Accรจs au nom d'utilisateur, prรฉnom et prรฉnom, genre"`
+auths.tip.twitter=Rendez-vous sur %s, crรฉez une application et assurez-vous que l'option "Autoriser l'application ร รชtre utilisรฉe avec Twitter Connect" est activรฉe
+auths.tip.discord=Enregistrer une nouvelle application sur %s
+auths.tip.gitea=Enregistrez une nouvelle application OAuth2. Le guide peut รชtre trouvรฉ sur %s
+auths.tip.yandex=`Crรฉez une nouvelle application sur %s. Sรฉlectionnez les autorisations suivantes dans la section "Yandex API passport" : "Accรจs ร l'adresse e-mail", "Accรจs ร l'avatar de l'utilisateur" et "Accรจs au nom d'utilisateur, prรฉnom et prรฉnom, genre"`
auths.tip.mastodon=Entrez une URL d'instance personnalisรฉe pour l'instance mastodon avec laquelle vous voulez vous authentifier (ou utiliser celle par dรฉfaut)
auths.edit=Mettre ร jour la source d'authentification
auths.activated=Cette source d'authentification est activรฉe
@@ -3290,7 +3440,7 @@ config.service_config=Configuration du service
config.register_email_confirm=Exiger la confirmation de l'e-mail lors de l'inscription
config.disable_register=Dรฉsactiver le formulaire d'inscription
config.allow_only_internal_registration=Autoriser l'inscription uniquement via Forgejo lui-mรชme
-config.allow_only_external_registration=N'autoriser l'inscription qu'ร partir des services externes
+config.allow_only_external_registration=N'autoriser l'inscription qu'ร partir de services externes
config.enable_openid_signup=Activer l'inscription avec OpenID
config.enable_openid_signin=Activer la connexion avec OpenID
config.show_registration_button=Afficher le bouton d'enregistrement
@@ -3432,15 +3582,6 @@ notices.type_2=Tรขche
notices.desc=Description
notices.op=Opรฉration
notices.delete_success=Les informations systรจmes ont รฉtรฉ supprimรฉes.
-self_check = Auto vรฉrification
-dashboard.sync_repo_tags = Synchroniser les รฉtiquettes depuis Git vers la base de donnรฉe
-dashboard.sync_tag.started = La synchronisation des รฉtiquettes a commencรฉ
-self_check.no_problem_found = Aucun problรจme n'a encore รฉtรฉ trouvรฉ.
-self_check.database_collation_mismatch = La base de donnรฉe devrait utiliser la collation %s
-self_check.database_collation_case_insensitive = La base de donnรฉe utilise la collation %s qui n'est pas sensible ร la casse. Bien que Forgejo puisse fonctionner de cette faรงon, il est possible que certains cas limite d'utilisation de la casse ne fonctionne pas comme attendu.
-self_check.database_inconsistent_collation_columns = La base de donnรฉe utilise la collation %s, mais ces colonnes utilisent des collations incohรฉrentes. Cela peut causer des problรจmes inattendus.
-self_check.database_fix_mysql = Les utilisateurs de MySQL/MariaDB peuvent utiliser la commande "forgejo doctor convert" pour corriger les problรจmes de collation, ou bien manuellement avec la commande SQL "ALTER ... COLLATE ...".
-
self_check.no_problem_found=Aucun problรจme trouvรฉ pour lโinstant.
self_check.database_collation_mismatch=Exige que la base de donnรฉes utilise la collation %s
self_check.database_collation_case_insensitive=La base de donnรฉes utilise la collation %s, insensible ร la casse. Bien que Forgejo soit compatible, il peut y avoir quelques rares cas qui ne fonctionnent pas comme prรฉvu.
@@ -3449,10 +3590,25 @@ self_check.database_fix_mysql=Pour les utilisateurs de MySQL ou MariaDB, vous po
config_settings = Paramรจtres
config_summary = Rรฉsumรฉ
auths.tips.gmail_settings = Paramรจtres Gmailโฏ:
-auths.tip.gitlab_new = Enregistrer une nouvelle application sur https://gitlab.com/-/profile/applications
+auths.tip.gitlab_new = Enregistrer une nouvelle application sur %s
auths.default_domain_name = Nom de domaine par dรฉfaut utilisรฉ pour le courriel
config.open_with_editor_app_help = Les รฉditeurs du menu "Ouvrir avec". Si laissรฉ vide, les valeurs par dรฉfaut seront utilisรฉes. Ouvrir pour voir les valeurs par dรฉfaut.
config.app_slogan = Slogan de l'instance
+config.cache_test_slow = Test du cache rรฉussi, mais le temps de rรฉponse est lentย : %s.
+config.cache_test_failed = รchec du contrรดle du cacheย : %v.
+config.cache_test = Tester le cache
+config.cache_test_succeeded = Test du cache rรฉussi, rรฉponse obtenue en %s.
+emails.delete_desc = รtes-vous sรปr de vouloir supprimer cette adresse courriel ?
+users.organization_creation.description = Autoriser la crรฉation de nouvelles organisations.
+emails.deletion_success = L'adresse courriel a รฉtรฉ supprimรฉe.
+emails.delete = Supprimer le courriel
+emails.delete_primary_email_error = Vous ne pouvez pas supprimer l'adresse courriel principale.
+users.activated.description = Achรจvement de la vรฉrification de courriel. Le propriรฉtaire d'un compte non activรฉ ne pourra pas se connecter tant que la vรฉrification de courriel n'est pas terminรฉe.
+users.block.description = Bloquer cet utilisateur d'interagir avec ce service via son compte et interdire la connexion.
+users.admin.description = Accorder ร cet utilisateur un accรจs complet ร toutes les fonctionnalitรฉs administratives disponibles via l'interface web et l'API.
+users.restricted.description = Autoriser uniquement l'interaction avec les dรฉpรดts et les organisations oรน cet utilisateur est ajoutรฉ en tant que collaborateur. Cela empรชche l'accรจs aux dรฉpรดts publics sur cette instance.
+users.local_import.description = Autoriser l'importation de dรฉpรดts ร partir du systรจme de fichiers local du serveur. Cela peut poser un problรจme de sรฉcuritรฉ.
+monitor.duration = Durรฉe (s)
[action]
create_repo=a crรฉรฉ le dรฉpรดt %s
@@ -3460,10 +3616,10 @@ rename_repo=a rebaptisรฉ le dรฉpรดt %[1]s
en %[3]s<
commit_repo=a soumis sur %[3]s dans %[4]s
create_issue=`a ouvert le ticket %[3]s#%[2]s `
close_issue=`a fermรฉ le ticket %[3]s#%[2]s `
-reopen_issue=`a rรฉouvert le ticket %[3]s#%[2]s `
+reopen_issue=`a rouvert le ticket %[3]s#%[2]s `
create_pull_request=`a crรฉรฉ la demande dโajout %[3]s#%[2]s `
close_pull_request=`a fermรฉ la demande dโajout %[3]s#%[2]s `
-reopen_pull_request=`a rรฉouvert la demande dโajout %[3]s#%[2]s `
+reopen_pull_request=`a rouvert la demande dโajout %[3]s#%[2]s `
comment_issue=`a commentรฉ le ticket %[3]s#%[2]s `
comment_pull=`a commentรฉ la demande dโajout %[3]s#%[2]s `
merge_pull_request=`a fusionnรฉ la demande dโajout %[3]s#%[2]s `
@@ -3577,7 +3733,7 @@ alpine.registry=Configurez ce registre en ajoutant lโURL dans votre fichier /etc/apk/keys/
pour vรฉrifier la signature de l'index :
alpine.registry.info=Choisissez $branch et $repository dans la liste ci-dessous.
alpine.install=Pour installer le paquet, exรฉcutez la commande suivante :
-alpine.repository=Informations sur le Dรฉpรดt
+alpine.repository=Informations sur le dรฉpรดt
alpine.repository.branches=Branches
alpine.repository.repositories=Dรฉpรดts
alpine.repository.architectures=Architectures
@@ -3597,7 +3753,7 @@ conda.install=Pour installer le paquet en utilisant Conda, exรฉcutez la commande
container.details.type=Type d'image
container.details.platform=Plateforme
container.pull=Tirez l'image depuis un terminal :
-container.digest=Empreinteย :
+container.digest=Empreinte
container.multi_arch=SE / Arch
container.layers=Calques d'image
container.labels=Labels
@@ -3608,7 +3764,7 @@ cran.install=Pour installer le paquet, exรฉcutez la commande suivante :
debian.registry=Configurez ce registre ร partir d'un terminal :
debian.registry.info=Choisissez $distribution et $component dans la liste ci-dessous.
debian.install=Pour installer le paquet, exรฉcutez la commande suivante :
-debian.repository=Infos sur le Dรฉpรดt
+debian.repository=Infos sur le dรฉpรดt
debian.repository.distributions=Distributions
debian.repository.components=Composants
debian.repository.architectures=Architectures
@@ -3638,9 +3794,9 @@ rpm.registry=Configurez ce registre ร partir d'un terminal :
rpm.distros.redhat=sur les distributions basรฉes sur RedHat
rpm.distros.suse=sur les distributions basรฉes sur SUSE
rpm.install=Pour installer le paquet, exรฉcutez la commande suivante :
-rpm.repository=Informations sur le Dรฉpรดt
-rpm.repository.architectures=Architectures
-rpm.repository.multiple_groups=Ce paquet est disponible en plusieurs groupes.
+rpm.repository = Information sur le dรฉpรดt
+rpm.repository.architectures = Architectures
+rpm.repository.multiple_groups = Ce paquet est disponible dans plusieurs groupes.
rubygems.install=Pour installer le paquet en utilisant gem, exรฉcutez la commande suivante :
rubygems.install2=ou ajoutez-le au Gemfile :
rubygems.dependencies.runtime=Dรฉpendances d'exรฉcution
@@ -3694,11 +3850,33 @@ owner.settings.cleanuprules.success.delete=La rรจgle de nettoyage a รฉtรฉ suppri
owner.settings.chef.title=Dรฉpรดt Chef
owner.settings.chef.keypair=Gรฉnรฉrer une paire de clรฉs
owner.settings.chef.keypair.description=Une paire de clรฉs est nรฉcessaire pour s'authentifier au registre Chef. Si vous avez dรฉjร gรฉnรฉrรฉ une paire de clรฉs, la gรฉnรฉration d'une nouvelle paire de clรฉs supprimera l'ancienne.
-rpm.repository = Information sur le dรฉpรดt
-rpm.repository.architectures = Architectures
-rpm.repository.multiple_groups = Ce paquet est disponible dans plusieurs groupes.
owner.settings.cargo.rebuild.no_index = Incapable de reconstruire, index non initialisรฉ.
npm.dependencies.bundle = Bundles de dรฉpendances
+arch.pacman.helper.gpg = Ajouter un certificat de confiance pour pacman :
+arch.pacman.repo.multi = %s a la mรชme version dans diffรฉrentes distributions.
+arch.pacman.repo.multi.item = Configuration pour %s
+arch.pacman.conf = Ajouter un serveur associรฉes ร la distribution et l'architecture dans /etc/pacman.conf
:
+arch.pacman.sync = Synchroniser le paquet avec pacman :
+arch.version.properties = Propriรฉtรฉs de version
+arch.version.description = Description
+arch.version.provides = Fournit
+arch.version.groups = Groupe
+arch.version.depends = Dรฉpend
+arch.version.optdepends = Dรฉpendances optionnelles
+arch.version.checkdepends = Vรฉrifier les dรฉpendances
+arch.version.conflicts = Conflits
+arch.version.replaces = Remplace
+arch.version.backup = Sauvegarde
+arch.version.makedepends = Faire des dรฉpendances
+container.images.title = Images
+search_in_external_registry = Rechercher dans %s
+alt.repository = Informations sur le dรฉpรดt
+alt.repository.architectures =Architectures
+alt.registry = Configurez ce registre ร partir d'un terminal :
+alt.registry.install = Pour installer le paquet, exรฉcutez la commande suivante :
+alt.install = Installer le paquet
+alt.repository.multiple_groups = Ce paquet est disponible dans plusieurs groupes.
+alt.setup = Ajouter un dรฉpรดt ร la liste des dรฉpรดts connectรฉ (choisissez l'architecture nรฉcessaire ร la place de "_arch") :
[secrets]
secrets=Secrets
@@ -3718,7 +3896,7 @@ management=Gestion des secrets
[actions]
actions=Actions
-unit.desc=Gรฉrer l'intรฉgration continue avec Forgejo Actions
+unit.desc=Gรฉrer l'intรฉgration continue avec Forgejo Actions.
status.unknown=Inconnu
status.waiting=En attente
@@ -3778,8 +3956,8 @@ runs.actors_no_select=Tous les acteurs
runs.status_no_select=Touts les statuts
runs.no_results=Aucun rรฉsultat correspondant.
runs.no_workflows=Il n'y a pas encore de workflows.
-runs.no_workflows.quick_start=Vous dรฉcouvrez les Actions Gitea ? Consultez le didacticiel .
-runs.no_workflows.documentation=Pour plus dโinformations sur les actions Gitea, voir la documentation .
+runs.no_workflows.quick_start = Vous ne savez pas comment commencer avec Forgejo Action ? Consultez le guide de dรฉmarrage rapide .
+runs.no_workflows.documentation = Pour plus dโinformations sur Forgejo Actions, voir la documentation .
runs.no_runs=Le flux de travail n'a pas encore d'exรฉcution.
runs.empty_commit_message=(message de rรฉvision vide)
@@ -3798,7 +3976,7 @@ variables.none=Il n'y a pas encore de variables.
variables.deletion=Retirer la variable
variables.deletion.description=La suppression dโune variable est permanente et ne peut รชtre dรฉfaite. Continuer ?
variables.description=Les variables sont passรฉes aux actions et ne peuvent รชtre lues autrement.
-variables.id_not_exist=La variable avec lโID %d nโexiste pas.
+variables.id_not_exist = La variable numรฉro %d nโexiste pas.
variables.edit=Modifier la variable
variables.deletion.failed=Impossible de retirer la variable.
variables.deletion.success=La variable a bien รฉtรฉ retirรฉe.
@@ -3806,20 +3984,29 @@ variables.creation.failed=Impossible d'ajouter la variable.
variables.creation.success=La variable ยซย %sย ยป a รฉtรฉ ajoutรฉe.
variables.update.failed=Impossible dโรฉditer la variable.
variables.update.success=La variable a bien รฉtรฉ modifiรฉe.
-runs.no_workflows.quick_start = Vous ne savez pas comment commencer avec Forgejo Action ? Consultez le guide de dรฉmarrage rapide .
-runs.no_workflows.documentation = Pour plus dโinformations sur Forgejo Actions, voir la documentation .
-variables.id_not_exist = La variable numรฉro %d nโexiste pas.
runs.workflow = Workflow
runs.no_job_without_needs = Le workflow doit contenir au moins une tรขche sans dรฉpendances.
+workflow.dispatch.use_from = Utiliser un workflow depuis
+runs.no_job = Le workflow doit au moins contenir une tรขche
+workflow.dispatch.trigger_found = Ce workflow a un dรฉclencheur d'รฉvรฉnement workflow_dispatch .
+workflow.dispatch.run = Exรฉcuter le workflow
+workflow.dispatch.success = L'exรฉcution du workflow a bien รฉtรฉ demandรฉe.
+workflow.dispatch.input_required = Le champ "%s" est obligatoire.
+workflow.dispatch.invalid_input_type = Type invalide pour le champ "%s".
+workflow.dispatch.warn_input_limit = Affichage des %d premiers champs seulement.
+runs.expire_log_message = Les journaux ont รฉtรฉ purgรฉs car ils รฉtaient trop anciens.
+runs.no_workflows.help_write_access = Vous ne savez pas par oรน commencer avec Forgejo Actions ? Regardez la section dรฉmarrage rapide dans la documentation utilisateur pour รฉcrire votre premier workflow, puis mettre en place un Forgejo runner pour exรฉcuter vos jobs.
+runs.no_workflows.help_no_write_access = Pour en savoir plus sur Forgejo Actions, consultez la documentation .
+variables.not_found = La variable n'a pas รฉtรฉ trouvรฉe.
[projects]
type-1.display_name=Projet personnel
type-2.display_name=Projet du dรฉpรดt
type-3.display_name=Projet de l'organisation
+deleted.display_name = Projet Supprimรฉ
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=Dossier
normal_file=Fichier normal
executable_file=Fichier exรฉcutable
@@ -3828,38 +4015,36 @@ submodule=Sous-module
-[graphs]
-component_loading_info = Cela peut prendre du tempsโฆ
-component_failed_to_load = Une erreur inattendue s'est produite.
-contributors.what = contributions
-component_loading = Chargement %s...
-component_loading_failed = รchec de chargement de %s
-
-code_frequency.what = fลequence de code
-recent_commits.what = commits rรฉcents
-
-
[search]
-search = Rechercher...
+search = Rechercherโฆ
type_tooltip = Type de recherche
fuzzy = Approximatif
code_search_by_git_grep = Les rรฉsultats de recherche dans le code sont fournis par "git grep". Les rรฉsultats pourraient รชtre plus pertinents si l'administrateur du site active les indexeurs de code source.
-runner_kind = Chercher les runners...
+runner_kind = Chercher les runnersโฆ
no_results = Aucun rรฉsultat n'a รฉtรฉ trouvรฉ.
keyword_search_unavailable = La recherche par mot-clรฉ n'est pas disponible actuellement. Veuillez contacter l'administrateur du site.
fuzzy_tooltip = Inclure les rรฉsultats proches des termes recherchรฉs
match = Correspondance
match_tooltip = Uniquement inclure les rรฉsultats correspondant exactement aux termes recherchรฉs
-repo_kind = Chercher dans les dรฉpรดt...
-user_kind = Chercher les utilisateurs...
-org_kind = Chercher les organisations...
-team_kind = Chercher les รฉquipes...
-code_kind = Chercher le code...
+repo_kind = Chercher dans les dรฉpรดtsโฆ
+user_kind = Chercher les utilisateursโฆ
+org_kind = Chercher les organisationsโฆ
+team_kind = Chercher les รฉquipesโฆ
+code_kind = Chercher le codeโฆ
code_search_unavailable = La recherche dans le code n'est pas disponible. Veuillez contacter l'administrateur du site.
-package_kind = Chercher les paquets...
-project_kind = Chercher les projets...
-branch_kind = Chercher les branches...
-commit_kind = Chercher les commits...
+package_kind = Chercher les paquetsโฆ
+project_kind = Chercher les projetsโฆ
+branch_kind = Chercher les branchesโฆ
+commit_kind = Chercher les commitsโฆ
+exact = Exact
+exact_tooltip = Inclure uniquement les rรฉsultats qui correspondent exactement au terme recherchรฉ
+issue_kind = Rechercher dans les ticketsโฆ
+union = Union
+union_tooltip = Inclus les rรฉsultats contenant au moins un des mots clรฉ sรฉparรฉs par des espaces
+pull_kind = Rechercher dans les demande d'ajoutโฆ
+milestone_kind = Recherche dans les jalons...
+regexp_tooltip = Interprรฉter le terme de recherche comme une expression rรฉguliรจre
+regexp = RegExp
[munits.data]
@@ -3874,4 +4059,27 @@ eib = Eio
[markup]
filepreview.line = Ligne %[1]d dans %[2]s
filepreview.lines = Lignes %[1]d jusqu'ร %[2]d dans %[3]s
-filepreview.truncated = L'aperรงu a รฉtรฉ tronquรฉ
\ No newline at end of file
+filepreview.truncated = L'aperรงu a รฉtรฉ tronquรฉ
+
+[repo.permissions]
+pulls.write = รcrire : Fermer des demandes de tirage et gรฉrer les mรฉtadonnรฉes telles que les รฉtiquettes, les jalons, les assignรฉs, les dates d'รฉchรฉance et les dรฉpendances.
+actions.read = Lire : Voir les pipelines CI/CD intรฉgrรฉs et leurs journaux.
+releases.read = Lire: Voir et tรฉlรฉcharger les versions.
+releases.write = รcrire : Publier, modifier et supprimer des versions et leurs ressources.
+projects.write = รcrire : Crรฉer des projets, des colonnes et les modifier.
+code.read = Lire : Accรฉder au code du dรฉpรดt et le cloner.
+ext_issues = Accรฉder au lien vers un systรจme externe de suivi des problรจmes. Les autorisations sont gรฉrรฉes de maniรจre externe.
+code.write = รcrire : Pousser vers le dรฉpรดt, crรฉer des branches et des รฉtiquettes.
+issues.read = Lire : Lire et crรฉer des tickets et des commentaires.
+wiki.read = Lire : Lire le wiki intรฉgrรฉ et son historique.
+wiki.write = รcrire : Crรฉer, mettre ร jour et supprimer des pages dans le wiki intรฉgrรฉ.
+projects.read = Lire : Accรฉder aux tableaux de projet du dรฉpรดt.
+packages.read = Lire : Voir et tรฉlรฉcharger les paquets assignรฉs au dรฉpรดt.
+packages.write = รcrire : Publier et supprimer des paquets assignรฉs au dรฉpรดt.
+actions.write = รcrire : Dรฉclencher manuellement, redรฉmarrer, annuler ou approuver les pipelines CI/CD en attente.
+ext_wiki = Accรฉder au lien vers un wiki externe. Les autorisations sont gรฉrรฉes de maniรจre externe.
+issues.write = รcrire : Fermer des tickets et gรฉrer les mรฉtadonnรฉes telles que les รฉtiquettes, les jalons, les assignรฉs, les dates d'รฉchรฉance et les dรฉpendances.
+pulls.read = Lire : Lire et crรฉer des demandes de tirage.
+
+[translation_meta]
+test = Ceci est une chaรฎne de test. Elle n'est pas affichรฉe dans l'interface de Forgejo mais est utilisรฉe ร des fins de test. N'hรฉsitez pas ร entrer 'ok' pour gagner du temps (ou un fait amusant de votre choix) pour atteindre ce doux 100 % de complรฉtion. :-)
diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini
new file mode 100644
index 0000000000..d2d960b627
--- /dev/null
+++ b/options/locale/locale_ga-IE.ini
@@ -0,0 +1,2996 @@
+[common]
+home = Baile
+dashboard = Deais
+explore = Iniรบch
+help = Cabhair
+logo = Lรณgรณ
+sign_in = Sรญnigh isteach
+sign_in_with_provider = Sรญnigh isteach le %s
+sign_in_or = nรณ
+sign_out = Sรญnigh amach
+sign_up = Clรกraigh
+link_account = Cuntas Nasc
+register = Clรกraigh
+version = Leagan
+powered_by = Cumhachtaithe ag %s
+page = Leathanach
+template = Teimplรฉad
+language = Teanga
+notifications = Fรณgraรญ
+active_stopwatch = Rianaitheoir Ama Gnรญomhach
+tracked_time_summary = Achoimre ar an am rianaithe bunaithe ar scagairรญ an liosta eisiรบna
+create_new = Cruthaighโฆ
+user_profile_and_more = Prรณifรญl agus Socruitheโฆ
+signed_in_as = Sรญnithe isteach mar
+enable_javascript = รilรญonn JavaScript ar an suรญomh Grรฉasรกin seo.
+toc = Tรกbla na nรbhar
+licenses = Ceadรบnais
+more_items = Tuilleadh mรญreanna
+username = Ainm รบsรกideora
+email = Seoladh rรญomhphoist
+password = Pasfhocal
+access_token = Comhartha Rochtana
+re_type = Deimhnigh Pasfhocal
+captcha = CAPTCHA
+twofa = Fรญordheimhniรบ Dhรก-Fhachtรณir
+twofa_scratch = Cรณd Scratch Dhรก-Fhachtรณra
+passcode = Paschรณd
+webauthn_insert_key = Cuir isteach d'eochair slรกndรกla
+webauthn_sign_in = Brรบigh an cnaipe ar d'eochair slรกndรกla. Mura bhfuil aon chnaipe ag d'eochair slรกndรกla, cuir isteach รฉ arรญs.
+webauthn_press_button = Brรบigh an cnaipe ar d'eochair slรกndรกla le do thoilโฆ
+webauthn_use_twofa = รsรกid cรณd dhรก fhachtรณir รณ do ghuthรกn
+webauthn_error = Nรญ fhรฉadfaรญ do eochair slรกndรกla a lรฉamh.
+webauthn_unsupported_browser = Nรญ thacaรญonn do bhrabhsรกlaรญ le WebAuthn faoi lรกthair.
+webauthn_error_unknown = Tharla earrรกid anaithnid. Dรฉan iarracht arรญs.
+webauthn_error_insecure = Nรญ thacaรญonn WebAuthn ach le naisc slรกn. Le haghaidh tรกstรกla thar HTTP, is fรฉidir leat an bunรบs โlocalhostโ nรณ "127.0.0.1" a รบsรกid
+webauthn_error_unable_to_process = Nรญ fhรฉadfadh an freastalaรญ d'iarratas a phrรณiseรกil.
+webauthn_error_duplicated = Nรญ cheadaรญtear an eochair slรกndรกla don iarratas seo. Dรฉan cinnte le do thoil nach bhfuil an eochair clรกraithe cheana fรฉin.
+webauthn_error_empty = Nรญ mรณr duit ainm a shocrรบ don eochair seo.
+webauthn_error_timeout = Sroicheadh an teorainn ama sula bhfรฉadfaรญ dโeochair a lรฉamh. Athlรณdรกil an leathanach seo, le do thoil, agus dรฉan iarracht arรญs.
+repository = Stรณr
+organization = Eagraรญocht
+mirror = Scรกthรกn
+new_mirror = Scรกthรกn Nua
+new_fork = Forc Stรณr Nua
+new_project = Tionscadal Nua
+new_project_column = Colรบn Nua
+admin_panel = Riarachรกn Lรกithreรกin
+settings = Socruithe
+your_profile = Prรณifรญl
+your_starred = Rรฉaltaigh
+your_settings = Socruithe
+all = Gach
+sources = Foinsรญ
+mirrors = Scรกthรกin
+collaborative = Comhoibritheach
+forks = Forcanna
+activities = Gnรญomhaรญochtaรญ
+pull_requests = Iarrataรญ Tarraing
+issues = Saincheisteanna
+milestones = Clocha mรญle
+ok = CEART GO LEOR
+cancel = Cealaigh
+retry = Atriail
+rerun = Ath-rith
+rerun_all = Ath-rith na poist go lรฉir
+save = Sรกbhรกil
+add = Cuir
+add_all = Cuir Gach
+remove = Bain
+remove_all = Bain Gach
+remove_label_str = Bain mรญr โ%sโ
+edit = Cuir in eagar
+view = Amharc
+test = Tรกstรกil
+enabled = Cumasaithe
+disabled = Dรญchumasaithe
+locked = Faoi ghlas
+copy = Cรณipeรกil
+copy_url = Cรณipeรกil URL
+copy_hash = Cรณipeรกil hais
+copy_path = Cรณipeรกil cosรกn
+copy_content = Cรณipeรกil รกbhair
+copy_branch = Ainm brainse cรณipeรกil
+copy_success = Cรณipeรกil!
+copy_error = Theip ar an gcรณipeรกil
+copy_type_unsupported = Nรญ fรฉidir an cineรกl comhaid seo a chรณipeรกil
+write = Scrรญobh
+preview = Rรฉamhamharc
+loading = ร lรณdรกil...
+error = Earrรกid
+error404 = Nรญl an leathanach atรก tรบ ag iarraidh a bhaint amach ann nรณ nรญl tรบ รบdaraithe chun รฉ a fheiceรกil.
+go_back = Ar ais
+invalid_data = Sonraรญ neamhbhailรญ: %v
+never = Riamh
+unknown = Anaithnid
+rss_feed = Fothรบ RSS
+pin = Biorรกin
+unpin = Dรญphorรกil
+artifacts = Dรฉantรกin
+archived = Cartlann
+concept_system_global = Domhanda
+concept_user_individual = Duine aonair
+concept_code_repository = Stรณrรกil
+concept_user_organization = Eagraรญocht
+show_timestamps = Taispeรกin stampaรญ ama
+show_log_seconds = Taispeรกin soicindรญ
+show_full_screen = Taispeรกin scรกileรกn iomlรกn
+download_logs = รoslรณdรกil logaรญ
+confirm_delete_selected = Deimhnigh chun gach earra roghnaithe a scriosadh?
+name = Ainm
+value = Luach
+filter = Scagaire
+filter.is_archived = Cartlannaithe
+filter.not_archived = Gan Cartlannaithe
+filter.public = Poiblรญ
+filter.private = Prรญobhรกideach
+
+[search]
+search = Cuardaigh...
+type_tooltip = Cineรกl cuardaigh
+fuzzy = Doilรฉir
+fuzzy_tooltip = Cuir san รกireamh torthaรญ a mheaitseรกlann an tรฉarma cuardaigh go dlรบth freisin
+exact = Beacht
+exact_tooltip = Nรญ chuir san รกireamh ach torthaรญ a mheaitseรกlann leis an tรฉarma
+repo_kind = Cuardaigh stรณrtha...
+user_kind = Cuardaigh รบsรกideoirรญ...
+org_kind = Cuardaigh eagraรญochtaรญ...
+team_kind = Cuardaigh foirne...
+code_kind = Cรณd cuardaigh...
+code_search_unavailable = Nรญl cuardach cรณd ar fรกil faoi lรกthair. Dรฉan teagmhรกil le riarthรณir an lรกithreรกin.
+package_kind = Cuardaigh pacรกistรญ...
+project_kind = Cuardaigh tionscadail...
+branch_kind = Cuardaigh brainsรญ...
+commit_kind = Cuardaigh tiomรกintรญ...
+runner_kind = Cuardaigh reathaithe...
+no_results = Nรญl aon torthaรญ meaitseรกla le fรกil.
+issue_kind = Saincheisteanna cuardaigh...
+pull_kind = Cuardaigh iarratais tarraingthe...
+keyword_search_unavailable = Nรญl cuardach de rรฉir eochairfhocal ar fรกil faoi lรกthair. Dรฉan teagmhรกil le riarthรณir an lรกithreรกin.
+
+[aria]
+navbar = Barra Nascleanรบint
+footer = Buntรกsc
+footer.links = Naisc
+
+[heatmap]
+number_of_contributions_in_the_last_12_months = %s rannรญocaรญochtaรญ le 12 mhรญ anuas
+less = Nรญos lรบ
+more = Nรญos mรณ
+
+[editor]
+buttons.heading.tooltip = Cuir ceannteideal leis
+buttons.bold.tooltip = Cuir tรฉacs trom leis
+buttons.italic.tooltip = Cuir tรฉacs iodรกlach leis
+buttons.quote.tooltip = Tรฉacs luaigh
+buttons.code.tooltip = Cuir cรณd leis
+buttons.link.tooltip = Cuir nasc leis
+buttons.list.unordered.tooltip = Cuir liosta pilรฉar leis
+buttons.list.ordered.tooltip = Cuir liosta uimhrithe
+buttons.list.task.tooltip = Cuir liosta tascanna leis
+buttons.mention.tooltip = Luaigh รบsรกideoir nรณ foireann
+buttons.ref.tooltip = Dรฉan tagairt d'eisiรบint nรณ iarratas tarraingthe
+buttons.switch_to_legacy.tooltip = รsรกid an eagarthรณir oidhreachta ina ionad
+buttons.enable_monospace_font = Cumasaigh clรณ monospace
+buttons.disable_monospace_font = Dรญchumasaigh clรณ monospace
+
+[filter]
+string.asc = A - Z
+string.desc = Z - A
+
+[error]
+occurred = Tharla earrรกid
+not_found = Nรญ raibh an sprioc in ann a fhรกil.
+network_error = Earrรกid lรญonra
+
+[startpage]
+app_desc = Seirbhรญs Git gan phian, fรฉin-รณstรกil
+install = รasca a shuiteรกil
+install_desc = Nรญl ort ach rith an dรฉnรกrtha do d'ardรกn, seol รฉ le Docker , nรณ faigh pacรกilte รฉ.
+platform = Tras-ardรกn
+lightweight = รadrom
+license = Foinse Oscailte
+
+[install]
+install = Suiteรกil
+title = Cumraรญocht Tosaigh
+db_title = Socruithe Bunachar Sonraรญ
+db_type = Cineรกl Bunachar Sonraรญ
+host = รstach
+user = Ainm รบsรกideora
+password = Pasfhocal
+db_name = Ainm Bunachar Sonraรญ
+db_schema = Scรฉim
+db_schema_helper = Fรกg bรกn le haghaidh rรฉamhshocraithe bunachar sonraรญ ("poiblรญ").
+ssl_mode = SSL
+path = Cosรกn
+reinstall_confirm_check_1 = Fรฉadfaidh na sonraรญ criptithe ag an SECRET_KEY i app.ini a chailleadh: b'fhรฉidir nach mbeidh รบsรกideoirรญ in ann logรกil isteach le 2FA/OTP & b'fhรฉidir nach bhfeidhmeoidh scรกthรกin i gceart. Trรญ an bhosca seo a sheiceรกil deimhnรญonn tรบ go bhfuil an ceart an SECRET_KEY sa chomhad reatha app.ini.
+reinstall_confirm_check_2 = B'fhรฉidir go gcaithfear na stรณrais agus na socruithe a athshioncronรบ. Trรญ an bhosca seo a sheiceรกil deimhnรญonn tรบ go ndรฉanfaidh tรบ na crรบcaรญ do na stรณrรกlacha agus an chomhad authorized_keys a athshioncronรบ de lรกimh. Deimhnรญonn tรบ go gcinnteoidh tรบ go bhfuil socruithe stรณrais agus scรกthรกin ceart.
+err_empty_db_path = Nรญ fรฉidir cosรกn bunachar sonraรญ SQLite3 a bheith folamh.
+no_admin_and_disable_registration = Nรญ fรฉidir leat fรฉinchlรกrรบ รบsรกideora a dhรญchumasรบ gan cuntas riarthรณra a chruthรบ.
+err_empty_admin_password = Nรญ fรฉidir le pasfhocal an riarthรณra a bheith folamh.
+err_empty_admin_email = Nรญ fรฉidir le rรญomhphost an riarthรณra a bheith folamh.
+err_admin_name_is_reserved = Riarthรณir Tรก an t-ainm รบsรกideora neamhbhailรญ, tรก an t-ainm รบsรกideora curtha in รกirithe
+err_admin_name_pattern_not_allowed = Tรก ainm รบsรกideora an riarthรณra neamhbhailรญ, meaitseรกlann an t-ainm รบsรกideora patrรบn in รกirithe
+err_admin_name_is_invalid = Tรก an t-ainm รบsรกideora Riarthรณra neamhbhailรญ
+general_title = Socruithe Ginearรกlta
+repo_path = Cosรกn Frรฉimhe an Stรณr
+repo_path_helper = Sรกbhรกlfar stรณrais iargรบlta Git chuig an eolaire seo.
+lfs_path = Cosรกn Frรฉamh Git LFS
+lfs_path_helper = Stรณrรกlfar comhaid a rianรณidh Git LFS san eolaire seo. Fรกg folamh le dรญchumasรบ.
+domain = Fearann โโFreastalaรญ
+domain_helper = Seoladh fearainn nรณ รณstach don fhreastalaรญ.
+ssh_port = Port Freastalaรญ SSH
+app_url_helper = Seoladh bonn le haghaidh URLanna clรณin HTTP(S) agus fรณgraรญ rรญomhphoist.
+log_root_path = Cosรกn Logรกla
+log_root_path_helper = Scrรญofar comhaid logรกla chuig an eolaire seo.
+optional_title = Socruithe Roghnacha
+email_title = Socruithe rรญomhphoist
+smtp_addr = รstach SMTP
+smtp_port = Port SMTP
+smtp_from = Seol Rรญomhphost Mar
+smtp_from_invalid = Tรก an seoladh โSeol Rรญomhphost Marโ neamhbhailรญ
+mailer_user = SMTP Ainm รบsรกideora
+mailer_password = Pasfhocal SMTP
+register_confirm = Deimhniรบ Rรญomhphoist a cheangal le Clรกrรบ
+mail_notify = Cumasaigh Fรณgraรญ Rรญomhphoist
+server_service_title = Socruithe Freastalaรญ agus Seirbhรญse Trรญรบ Pรกirtรญ
+offline_mode = Cumasaigh Mรณd รitiรบil
+disable_gravatar = Dรญchumasaigh Gravatar
+federated_avatar_lookup = Cumasaigh Abhatรกir Chรณnaidhme
+disable_registration = Dรญchumasaigh Fรฉin-Chlรกrรบ
+openid_signin = Cumasaigh Sรญniรบ isteach OpenID
+openid_signup = Cumasaigh Fรฉinchlรกrรบ OpenID
+enable_captcha = Cumasaigh clรกrรบ CAPTCHA
+default_keep_email_private = Folaigh Seoltaรญ Rรญomhphoist de rรฉir Rรฉamhshocrรบ
+default_allow_create_organization = Ceadaigh Cruthรบ Eagraรญochtaรญ de rรฉir Rรฉamhshocrรบ
+default_enable_timetracking = Cumasaigh Rianรบ Ama de rรฉir Rรฉamhshocrรบ
+admin_title = Socruithe Cuntas Riarthรณra
+admin_name = Ainm รsรกideora an Riarthรณra
+admin_password = Pasfhocal
+confirm_password = Deimhnigh Pasfhocal
+admin_email = Seoladh rรญomhphoist
+invalid_db_setting = Tรก na socruithe bunachar sonraรญ neamhbhailรญ:%v
+invalid_db_table = Tรก an tรกbla bunachar sonraรญ "%s" neamhbhailรญ: %v
+invalid_repo_path = Tรก cosรกn frรฉimhe an stรณr neamhbhailรญ:%v
+invalid_app_data_path = Tรก cosรกn sonraรญ an aip neamhbhailรญ:%v
+internal_token_failed = Theip ar chomhartha inmheรกnach a ghiniรบint:%v
+secret_key_failed = Theip ar an eochair rรบnda a ghiniรบint:%v
+save_config_failed = Theip ar chumraรญocht a shรกbhรกil:%v
+invalid_admin_setting = Tรก socrรบ cuntas riarthรณra neamhbhailรญ: %v
+invalid_log_root_path = Tรก an cosรกn logรกla neamhbhailรญ:%v
+no_reply_address = Fearann Rรญomhphoist Folaite
+password_algorithm = Algartam Hais Pasfhocal
+invalid_password_algorithm = Algartam hais pasfhocail neamhbhailรญ
+password_algorithm_helper = Socraigh an algartam hashing pasfhocal. Tรก riachtanais agus neart รฉagsรบla ag halgartaim. Tรก an algartam argon2 sรกch slรกn ach รบsรกideann sรฉ go leor cuimhne agus d'fhรฉadfadh sรฉ a bheith mรญchuรญ do chรณrais bheaga.
+enable_update_checker = Cumasaigh Seiceoir Nuashonraithe
+env_config_keys = Cumraรญocht Comhshaoil
+env_config_keys_prompt = Cuirfear na hathrรณga comhshaoil seo a leanas i bhfeidhm ar do chomhad cumraรญochta freisin:
+
+[home]
+uname_holder = Ainm รsรกideora nรณ Seoladh Rรญomhphoist
+switch_dashboard_context = Athraigh Comhthรฉacs an Deais
+my_repos = Stรณrais
+view_home = Amharc %s
+filter = Scagairรญ Eile
+filter_by_team_repositories = Scag de rรฉir stรณrais foirne
+feed_of = `Fotha de "%s"`
+show_archived = Cartlannaithe
+show_both_archived_unarchived = Ag taispeรกint idir chartlannaithe agus neamhchartlann
+show_only_archived = Ag taispeรกint ach na cartlannaigh
+show_only_unarchived = Ag taispeรกint ach na cartlannaigh neamh
+show_private = Prรญobhรกideach
+show_both_private_public = Ag taispeรกint poiblรญ agus prรญobhรกideach araon
+show_only_private = Ag taispeรกint prรญobhรกideach amhรกin
+show_only_public = Ag taispeรกint poiblรญ amhรกin
+issues.in_your_repos = I do stรณrais
+
+[explore]
+repos = Stรณrais
+users = รsรกideoirรญ
+organizations = Eagraรญochtaรญ
+go_to = Tรฉigh chuig
+code = Cรณd
+code_last_indexed_at = Innรฉacsaithe %s is dรฉanaรญ
+relevant_repositories_tooltip = Tรก stรณrais atรก forca iad nรณ nach bhfuil aon รกbhar acu, gan aon deilbhรญn, agus gan aon tuairisc i bhfolach.
+relevant_repositories = Nรญl ach stรณrtha รกbhartha รก dtaispeรกint, taispeรกin torthaรญ neamhscagtha .
+
+[auth]
+create_new_account = Clรกraigh Cuntas
+disable_register_prompt = Tรก clรกrรบ faoi dhรญchumasรบ. Tรฉigh i dteagmhรกil le do riarthรณir suรญomh.
+disable_register_mail = Tรก deimhniรบ rรญomhphoist le haghaidh clรกrรบ faoi dhรญchum
+manual_activation_only = Dรฉan teagmhรกil le riarthรณir do tsuรญmh chun gnรญomhachtรบ a chur i gcrรญch.
+remember_me = Cuimhnigh ar an nGlรฉas seo
+forgot_password_title = Dearmad ar an bPasfhocal
+forgot_password = Dearmad ar an bPasfhocal?
+sign_up_successful = Cruthaรญodh cuntas go rathรบil. Fรกilte romhat!
+must_change_password = Nuashonraigh do phasfhocal
+allow_password_change = A cheangal ar an รบsรกideoir pasfhocal a athrรบ (molta)
+active_your_account = Gnรญomhachtaigh do chuntas
+account_activated = Cuireadh cuntas gnรญomhachtaithe
+resent_limit_prompt = D'iarr tรบ rรญomhphost gnรญomhachtaithe cheana fรฉin le dรฉanaรญ. Fan 3 nรณimรฉad le do thoil agus bain triail as arรญs.
+has_unconfirmed_mail = Dia duit %s, tรก seoladh rรญomhphoist neamhdheimhnithe agat (%s ). Mura bhfuair tรบ rรญomhphost dearbhaithe nรณ mura gcaithfidh tรบ ceann nua a athsheoladh, cliceรกil ar an gcnaipe thรญos le do thoil.
+resend_mail = Cliceรกil anseo chun do r-phost gnรญomhachtaithe a athshe
+reset_password = Aisghabhรกil Cuntas
+invalid_code = Tรก do chรณd deimhnithe neamhbhailรญ nรณ tรก sรฉ in รฉag.
+invalid_code_forgot_password = Tรก do chรณd deimhnithe neamhbhailรญ nรณ tรก sรฉ in รฉag. Cliceรกil anseo chun seisiรบn nua a thosรบ.
+invalid_password = Nรญ mheaitseรกlann do phasfhocal leis an bhfocal faire a รบsรกideadh chun an cuntas a chruthรบ.
+reset_password_helper = Gnรณthaigh Cuntas
+reset_password_wrong_user = Tรก tรบ sรญnithe isteach mar %s, ach tรก an nasc aisghabhรกla cuntas i gceist le haghaidh %s
+password_too_short = Nรญ fรฉidir fad pasfhocal a bheith nรญos lรบ nรก %d carachtair.
+verify = Fรญoraigh
+scratch_code = Cรณd Scratch
+use_scratch_code = รsรกid cรณd scratch
+twofa_scratch_used = D'รบsรกid tรบ do chรณd scratch. Tรก tรบ atreoraithe chuig an leathanach socruithe dhรก fhachtรณir ionas gur fรฉidir leat clรกrรบ do ghlรฉas a bhaint nรณ cรณd scratch nua a ghiniรบint.
+twofa_passcode_incorrect = Tรก do phaschรณd mรญcheart. Mรก chuir tรบ do ghlรฉas mรญchuir tรบ, bain รบsรกid as do chรณd scratch chun sรญniรบ isteach.
+twofa_scratch_token_incorrect = Tรก do chรณd scratch mรญcheart.
+login_userpass = Sรญnigh isteach
+oauth_signup_tab = Clรกraigh Cuntas Nua
+oauth_signup_title = Comhlรกnaigh Cuntas Nua
+oauth_signup_submit = Cuntas Comhlรกnaigh
+oauth_signin_title = Sรญnigh isteach chun Cuntas Nasctha a รdarรบ
+oauth_signin_submit = Cuntas Nasc
+oauth.signin.error = Bhรญ earrรกid ann ag prรณiseรกil an t-iarratas ar รบdarรบ. Mรก leanann an earrรกid seo, dรฉan teagmhรกil le riarthรณir an lรกithreรกin.
+oauth.signin.error.access_denied = Diรบltaรญodh an t-iarratas ar รบdarรบ.
+oauth.signin.error.temporarily_unavailable = Theip ar รบdarรบ toisc nach bhfuil an fhreastalaรญ fรญordheimhnithe ar fรกil Bain triail as arรญs nรญos dรฉanaรญ.
+openid_connect_submit = Ceangail
+openid_connect_title = Ceangail le cuntas atรก ann cheana
+openid_connect_desc = Nรญl an URI OpenID roghnaithe ar eolas. Comhcheangail รฉ le cuntas nua anseo.
+openid_register_title = Cruthaigh cuntas nua
+openid_register_desc = Nรญl an URI OpenID roghnaithe ar eolas. Comhcheangail รฉ le cuntas nua anseo.
+openid_signin_desc = Cuir isteach do URI OpenID. Mar shampla: alice.openid.example.org nรณ https://openid.example.org/alice.
+disable_forgot_password_mail = Tรก aisghabhรกil cuntas dรญchumasaithe toisc nach bhfuil aon rรญomhphost ar bun. Tรฉigh i dteagmhรกil le do riarthรณir suรญomh.
+disable_forgot_password_mail_admin = Nรญl aisghabhรกil cuntas ar fรกil ach amhรกin nuair a bhรญonn rรญomhphost ar bun. Bunaigh rรญomhphost le do thoil chun aisghabhรกil cuntas a chumasรบ
+email_domain_blacklisted = Nรญ fรฉidir leat clรกrรบ le do sheoladh rรญomhphoist.
+authorize_application = รdaraigh an Feidhmchlรกr
+authorize_redirect_notice = Dรฉanfar tรบ a atreorรบ chuig %s mรก รบdaraรญonn tรบ an feidhmchlรกr seo.
+authorize_application_created_by = Chruthaigh %s an feidhmchlรกr seo.
+authorize_title = รdaraigh "%s" chun rochtain a fhรกil ar do chuntas?
+authorization_failed = Theip ar รบdarรบ
+authorization_failed_desc = Theip ar an รบdarรบ toisc gur bhraitheamar iarratas neamhbhailรญ. Tรฉigh i dteagmhรกil le cothabhรกlaรญ an aip a rinne tรบ iarracht a รบdarรบ.
+password_pwned = Tรก an pasfhocal a roghnaigh tรบ ar liosta na bhfocal faire goidte a nochtadh cheana i sรกruithe sonraรญ poiblรญ. Bain triail eile as le pasfhocal eile agus smaoinigh ar an bpasfhocal seo a athrรบ รกit eile freisin.
+password_pwned_err = Nรญ fhรฉadfaรญ iarratas a chomhlรกnรบ ar HaveIBeenPwned
+last_admin = Nรญ fรฉidir leat an riarachรกn deireanach a bhaint. Caithfidh riarachรกn amhรกin ar a laghad a bheith ann.
+back_to_sign_in = Ar ais go Sรญnigh Isteach
+
+[mail]
+view_it_on = Fรฉach air ar %s
+reply = nรณ freagra a thabhairt ar an r-phost seo go dรญreach
+hi_user_x = Dia duit %s ,
+activate_account = Gnรญomhachtaigh do chuntas le do thoil
+activate_account.text_1 = Dia duit %[1]s , go raibh maith agat as clรกrรบ ag %[2]s!
+activate_account.text_2 = Cliceรกil ar an nasc seo a leanas chun do chuntas a ghnรญomhachtรบ laistigh de %s :
+activate_email = Fรญoraigh do sheoladh rรญomhphoist
+activate_email.text = Cliceรกil ar an nasc seo a leanas le do sheoladh rรญomhphoist a fhรญorรบ laistigh de %s :
+register_notify = Fรกilte go dtรญ %s
+register_notify.text_1 = is รฉ seo do rรญomhphost deimhnithe clรกrรบchรกin do %s!
+reset_password = Aisghabhรกil do chuntas
+register_success = Clรกrรบ rathรบil
+issue_assigned.pull = @%[1]s shann tรบ don iarratas tarraingthe %[2]s i stรณr %[3]s.
+issue_assigned.issue = @%[1]s shann tรบ don eisiรบint %[2]s i stรณr %[3]s.
+issue.x_mentioned_you = Luaigh @%s tรบ:
+issue.action.force_push = Bhrรบigh %[1]s an %[2]s go fรณrsa รณ %[3]s go %[4]s.
+issue.action.push_1 = Bhrรบigh @%[1]s %[3]d tiomรกintรญ go %[2]s
+issue.action.push_n = @%[1]s brรบite % [3]d tiomรกintรญ chuig %[2]s
+issue.action.close = @%[1]s dรบnta #%[2]d.
+issue.action.reopen = D'athoscail @%[1]s #%[2]d.
+issue.action.merge = Chomhcheangail @%[1]s #%[2]d le %[3]s.
+issue.action.approve = Cheadaigh @%[1]s an t-iarratas tarraingthe seo.
+issue.action.reject = D'iarr @%[1]s athruithe ar an iarratas tarraingthe seo.
+issue.action.review = Rinne @%[1]s trรกcht ar an iarratas tarraingthe seo.
+issue.action.review_dismissed = Dhiรบltaigh @%[1]s an lรฉirmheas deiridh รณ %[2]s don iarratas tarraingthe seo.
+issue.action.ready_for_review = Mharcรกil @%[1]s an t-iarratas tarraingthe seo rรฉidh lena athbhreithniรบ.
+issue.action.new = Chruthaigh @%[1]s #%[2]d.
+issue.in_tree_path = I %s:
+release.new.subject = Scaoileadh %s i %s
+release.new.text = D'eisigh @%[1]s %[2]s i %[3]s
+release.title = Teideal: %s
+release.note = Nรณta:
+release.downloads = รoslรณdรกlacha:
+release.download.zip = Cรณd Foinse (ZIP)
+release.download.targz = Cรณd Foinse (TAR.GZ)
+repo.transfer.to_you = tรบ
+repo.transfer.body = Chun glacadh leis nรณ a dhiรบltรบ tabhair cuairt ar %s nรณ neamhaird a dhรฉanamh air.
+team_invite.subject = Tรก cuireadh tugtha agat ag %[1]s chun dul le heagraรญocht %[2]s
+team_invite.text_1 = Tรก cuireadh tugtha ag %[1]s duit chun dul le foireann %[2]s in eagraรญocht %[3]s.
+team_invite.text_2 = Cliceรกil ar an nasc seo a leanas le do thoil chun dul isteach san fhoireann:
+team_invite.text_3 = Nรณta: Bhรญ an cuireadh seo beartaithe do %[1]s. Mura raibh tรบ ag sรบil leis an gcuireadh seo, is fรฉidir leat neamhaird a dhรฉanamh den rรญomhphost seo.
+
+[modal]
+yes = Tรก
+no = Nรญl
+confirm = Deimhnigh
+cancel = Cealaigh
+modify = Nuashonraigh
+
+[form]
+UserName = Ainm รบsรกideora
+RepoName = Ainm stรณrais
+Email = Seoladh rรญomhphoist
+Password = Pasfhocal
+Retype = Deimhnigh Pasfhocal
+PayloadUrl = URL Pรกlasta
+TeamName = Ainm foirne
+AuthName = Ainm รบdaraithe
+AdminEmail = Rรญomhphost riarachรกin
+NewBranchName = Ainm brainse nua
+CommitSummary = Achoimre tiomรกintรญ
+CommitMessage = Tiomantas teachtaireacht
+CommitChoice = Rogha tiomanta
+TreeName = Cosรกn comhaid
+Content = รbhar
+SSPISeparatorReplacement = Deighilteoir
+SSPIDefaultLanguage = Teanga Rรฉamhshocraithe
+require_error = ` nรญ fรฉidir a bheith folamh.`
+git_ref_name_error = ` caithfidh gur ainm tagartha Git dea-chruthaithe รฉ.`
+size_error = ` nรญ mรณr mรฉid %s.`
+min_size_error = ` nรญ mรณr go mbeadh carachtar %s ar a laghad ann.`
+max_size_error = caithfidh %s carachtar ar a mhรฉad a bheith ann.
+email_error = `nรญ seoladh rรญomhphoist bailรญ รฉ.`
+url_error = `nรญ URL bailรญ รฉ "%s".`
+include_error = ` nรญ mรณr fotheaghrรกn a bheith ann "%s".`
+glob_pattern_error = ` tรก patrรบn glob neamhbhailรญ: %s.`
+regex_pattern_error = `tรก patrรบn regex neamhbhailรญ: %s.`
+invalid_group_team_map_error = ` tรก mapรกil neamhbhailรญ: %s`
+unknown_error = Earrรกid anaithnid:
+captcha_incorrect = Tรก an cรณd CAPTCHA mรญcheart.
+password_not_match = Nรญ mheaitseรกlann na pasfhocail.
+lang_select_error = Roghnaigh teanga รณn liosta.
+username_been_taken = Tรก an t-ainm รบsรกideora tรณgtha cheana fรฉin.
+username_change_not_local_user = Nรญ cheadaรญtear d'รบsรกideoirรญ neamhรกitiรบla a n-ainm รบsรกideora a athrรบ.
+repo_name_been_taken = รsรกidtear ainm an stรณr cheana fรฉin.
+repository_force_private = Tรก Force Private cumasaithe: nรญ fรฉidir stรณrais phrรญobhรกideacha a dhรฉanamh poiblรญ.
+repository_files_already_exist = Tรก comhaid ann cheana fรฉin don stรณr seo. Dรฉan teagmhรกil leis an riarthรณir cรณrais.
+repository_files_already_exist.adopt = Tรก comhaid ann cheana don stรณr seo agus nรญ fรฉidir iad a ghlacadh ach amhรกin.
+repository_files_already_exist.delete = Tรก comhaid ann cheana fรฉin don stรณr seo. Nรญ mรณr duit iad a scriosadh.
+repository_files_already_exist.adopt_or_delete = Tรก comhaid ann cheana fรฉin don stรณr seo. Glac iad nรณ scrios iad.
+visit_rate_limit = Thug cuairt chianda aghaidh ar theorannรบ rรกtaรญ.
+2fa_auth_required = Bhรญ fรญordheimhniรบ dhรก thoisc ag teastรกil รณ chianchuairt.
+org_name_been_taken = Tรก ainm na heagraรญochta glactha cheana fรฉin.
+team_name_been_taken = Tรก ainm na foirne glactha cheana fรฉin.
+team_no_units_error = Ceadaigh rochtain ar chuid stรณrais amhรกin ar a laghad.
+email_been_used = รsรกidtear an seoladh rรญomhphoist cheana fรฉin.
+email_invalid = Tรก an seoladh rรญomhphoist neamhbhailรญ.
+openid_been_used = รsรกidtear an seoladh OpenID "%s" cheana fรฉin.
+username_password_incorrect = Tรก ainm รบsรกideora nรณ pasfhocal mรญcheart.
+password_complexity = Nรญ shรกsaรญonn pasfhocal ceanglais castachta:
+password_lowercase_one = Carachtar beaga amhรกin ar a laghad
+password_uppercase_one = Carachtar cรกs uachtair amhรกin ar a laghad
+password_digit_one = Digit amhรกin ar a laghad
+password_special_one = Carachtar speisialta amhรกin ar a laghad (poncaรญocht, lรบibรญnรญ, luachana, srl.)
+enterred_invalid_repo_name = Tรก ainm an stรณrais a chuir tรบ isteach mรญcheart.
+enterred_invalid_org_name = Tรก ainm na heagraรญochta a chuir tรบ isteach mรญcheart.
+enterred_invalid_owner_name = Nรญl ainm an รบinรฉara nua bailรญ.
+enterred_invalid_password = Tรก an pasfhocal a chuir tรบ isteach mรญcheart.
+unset_password = Nรญor shocraigh an t-รบsรกideoir logรกla isteach an pasfhocal.
+unsupported_login_type = Nรญ thacaรญtear leis an gcineรกl logรกla isteach chun cuntas a scriosadh.
+user_not_exist = Nรญl an t-รบsรกideoir ann.
+team_not_exist = Nรญl an fhoireann ann.
+cannot_add_org_to_team = Nรญ fรฉidir eagraรญocht a chur leis mar bhall foirne.
+duplicate_invite_to_team = Tugadh cuireadh don รบsรกideoir cheana fรฉin mar bhall foirne.
+organization_leave_success = D'fhรกg tรบ an eagraรญocht %s go rathรบil.
+invalid_ssh_key = Nรญ fรฉidir d'eochair SSH a fhรญorรบ: %s
+invalid_gpg_key = Nรญ fรฉidir d'eochair GPG a fhรญorรบ: %s
+invalid_ssh_principal = Prรญomhoide neamhbhailรญ: %s
+must_use_public_key = Is eochair phrรญobhรกideach an eochair a sholรกthraรญonn tรบ. Nรก uaslรณdรกil d'eochair phrรญobhรกideach รกit ar bith รsรกid d'eochair phoiblรญ ina ionad.
+auth_failed = Theip ar fhรญordheimhniรบ:%v
+target_branch_not_exist = Nรญl spriocbhrainse ann.
+admin_cannot_delete_self = Nรญ fรฉidir leat tรบ fรฉin a scriosadh nuair is riarachรกn tรบ. Bain do phribhlรฉidรญ riarachรกin ar dtรบs.
+
+[user]
+change_avatar = Athraigh do abhatรกrโฆ
+joined_on = Clรกraigh ar %s
+repositories = Stรณrais
+activity = Gnรญomhaรญocht Phoiblรญ
+follow = Lean
+unfollow = Dรญlean
+starred = Stรณrais Rรฉaltaithe
+watched = Stรณrais Breathnaithe
+code = Cรณd
+projects = Tionscadail
+overview = Forbhreathnรบ
+user_bio = Beathaisnรฉis
+email_visibility.limited = Tรก do sheoladh rรญomhphoist le feiceรกil do gach รบsรกideoir fรญordheimhnithe
+show_on_map = Taispeรกin an รกit seo ar lรฉarscรกil
+settings = Socruithe รsรกideora
+disabled_public_activity = Dhรญchumasaigh an t-รบsรกideoir seo infheictheacht phoiblรญ na gnรญomhaรญochta.
+form.name_reserved = Tรก an t-ainm รบsรกideora "%s" in รกirithe.
+form.name_pattern_not_allowed = Nรญ cheadaรญtear an patrรบn "%s" in ainm รบsรกideora.
+
+[settings]
+profile = Prรณifรญl
+account = Cuntas
+appearance = Dealramh
+password = Pasfhocal
+security = Slรกndรกil
+avatar = Abhatรกr
+ssh_gpg_keys = Eochracha SSH/GPG
+applications = Iarratais
+repos = Stรณrais
+delete = Scrios Cuntas
+twofa = Fรญordheimhniรบ Dhรก Fachtรณir (TOTP)
+organization = Eagraรญochtaรญ
+uid = UID
+webauthn = Fรญordheimhniรบ Dhรก-Fachtรณir (Eochracha Slรกndรกla)
+public_profile = Prรณifรญl Phoiblรญ
+location_placeholder = Comhroinn do shuรญomh thart le daoine eile
+full_name = Ainm Iomlรกn
+website = Lรกithreรกn Grรฉasรกin
+location = Suรญomh
+update_profile = Nuashonraigh Prรณifรญl
+update_language_not_found = Nรญl teanga โ%sโ ar fรกil.
+update_language_success = Tรก an teanga nuashonraithe.
+update_profile_success = Nuashonraรญodh do phrรณifรญl.
+change_username = Tรก d'ainm รบsรกideora athraithe.
+change_username_prompt = Nรณta: Athraรญonn athrรบ d'ainm รบsรกideora URL do chuntais freisin.
+change_username_redirect_prompt = Athreorรณidh an sean-ainm รบsรกideora go dtรญ go n-รฉilรญonn duine รฉ
+continue = Lean ar aghaidh
+cancel = Cealaigh
+language = Teanga
+ui = Tรฉama
+hidden_comment_types = Cineรกlacha trรกchtaireachta ceilte
+hidden_comment_types.ref_tooltip = Tuairimรญ ina dtagraรญodh an tsaincheist seo รณ shaincheiste/coiste eile...
+hidden_comment_types.issue_ref_tooltip = Tuairimรญ ina n-athraรญonn an t-รบsรกideoir an brainse/clib a bhaineann leis an tsaincheist
+comment_type_group_reference = Tagairt
+comment_type_group_label = Lipรฉad
+comment_type_group_milestone = Cloch Mhรญle
+comment_type_group_assignee = Sannaitheoir
+comment_type_group_title = Teideal
+comment_type_group_branch = Brainse
+comment_type_group_time_tracking = Rianรบ Ama
+comment_type_group_deadline = Spriocdhรกta
+comment_type_group_dependency = Spleรกchas
+comment_type_group_lock = Stรกdas Glas
+comment_type_group_review_request = Iarratas athbhreithnithe
+comment_type_group_pull_request_push = Tiomรกintรญ curtha leis
+comment_type_group_project = Tionscadal
+comment_type_group_issue_ref = Tagairt eisiรบna
+saved_successfully = Sรกbhรกiltear do shocruithe go rathรบil.
+privacy = Prรญobhรกideacht
+keep_activity_private = Folaigh gnรญomhaรญocht รณ leathanach prรณifรญle
+enable_custom_avatar = รsรกid Avatar Saincheaptha
+choose_new_avatar = Roghnaigh avatar nua
+update_avatar = Nuashonrรบ Avatar
+delete_current_avatar = Scrios Avatar Reatha
+uploaded_avatar_not_a_image = Nรญ รญomhรก รฉ an comhad uaslรณdรกilte.
+uploaded_avatar_is_too_big = Sรกraรญonn mรฉid an chomhaid uaslรณdรกilte (%d KiB) an mรฉid uasta (%d KiB).
+update_avatar_success = Tรก do avatar nuashonraithe.
+update_user_avatar_success = Nuashonraรญodh avatar an รบsรกideora.
+old_password = Pasfhocal Reatha
+new_password = Pasfhocal Nua
+retype_new_password = Deimhnigh Pasfhocal Nua
+password_incorrect = Tรก an pasfhocal reatha mรญcheart.
+manage_emails = Bainistigh Seoltaรญ Rรญomhphoist
+email_desc = รsรกidfear do phrรญomhsheoladh rรญomhphoist le haghaidh fรณgraรญ, aisghabhรกil pasfhocal agus, ar choinnรญoll nach bhfuil sรฉ i bhfolach, oibrรญochtaรญ Git bunaithe ar an ngrรฉas
+primary = Prรญomhรบil
+activated = Gnรญomhachtaithe
+requires_activation = รilรญonn gnรญomhachtรบ
+primary_email = Dรฉan prรญomhรบil
+activate_email = Seol Gnรญomhachtaithe
+activations_pending = Gnรญomhartha ar Feitheamh
+can_not_add_email_activations_pending = Tรก gnรญomhachtรบ ar feitheamh, dรฉan iarracht arรญs i gceann cรบpla nรณimรฉad mรกs mian leat rรญomhphost nua a chur leis.
+delete_email = Bain
+email_deletion = Bain Seoladh R-phoist
+email_deletion_desc = Bainfear an seoladh rรญomhphoist agus an fhaisnรฉis ghaolmhar as do chuntas. Nรญ bheidh na tiomรกintรญ Git a bhaineann leis an seoladh rรญomhphoist seo athraithe. Lean ar aghaidh?
+email_deletion_success = Tรก an seoladh rรญomhphoist bainte.
+theme_update_success = Nuashonraรญodh do thรฉama.
+theme_update_error = Nรญl an tรฉama roghnaithe ann.
+openid_deletion = Bain Seoladh OpenID
+openid_deletion_desc = Cuirfidh an seoladh OpenID seo a bhaint as do chuntas cosc ort sรญniรบ isteach leis. Lean ar aghaidh?
+openid_deletion_success = Tรก an seoladh OpenID bainte.
+add_new_openid = Cuir URI OpenID nua leis
+add_email = Cuir Seoladh R-phoist leis
+add_openid = Cuir OpenID URI
+add_email_success = Cuireadh an seoladh rรญomhphoist nua leis.
+email_preference_set_success = Socraรญodh rogha rรญomhphoist go rathรบil.
+add_openid_success = Cuireadh an seoladh OpenID nua leis.
+keep_email_private = Folaigh Seoladh rรญomhphoist
+openid_desc = Ligeann OpenID duit fรญordheimhniรบ a tharmligean chuig solรกthraรญ seachtrach.
+manage_ssh_keys = Bainistigh Eochracha SSH
+manage_ssh_principals = Bainistigh Prรญomhoidรญ Teastas SSH
+manage_gpg_keys = Bainistigh Eochracha GPG
+add_key = Cuir Eochair
+principal_desc = Tรก baint ag na prรญomhoidรญ deimhnithe SSH seo le do chuntas agus ceadaรญonn siad rochtain iomlรกn ar do stรณrtha.
+add_new_principal = Cuir Prรญomhoide
+ssh_key_been_used = Cuireadh an eochair SSH seo leis an bhfreastalaรญ cheana fรฉin.
+ssh_key_name_used = Tรก eochair SSH leis an ainm cรฉanna ar do chuntas cheana fรฉin.
+ssh_principal_been_used = Cuireadh an prรญomhoide seo leis an bhfreastalaรญ cheana fรฉin.
+gpg_key_id_used = Tรก eochair GPG poiblรญ leis an aitheantas cรฉanna ann cheana fรฉin.
+gpg_no_key_email_found = Nรญ mheaitseรกlann an eochair GPG seo aon seoladh rรญomhphoist gnรญomhachtaithe a bhaineann le do chuntas. Fรฉadfar รฉ a chur leis fรณs mรก shรญnรญonn tรบ an comhartha a chuirtear ar fรกil.
+gpg_key_matched_identities = Aitheantais Meaitseรกilte:
+gpg_key_matched_identities_long = Meaitseรกlann na haitheantais leabaithe san eochair seo na seoltaรญ rรญomhphoist gnรญomhachtaithe seo a leanas don รบsรกideoir seo. Is fรฉidir gealltanais a mheaitseรกlann na seoltaรญ rรญomhphoist seo a fhรญorรบ leis an eochair seo.
+gpg_key_verified = Eochair Fhรญoraithe
+gpg_key_verified_long = Fรญoraรญodh an eochair le heochairchomhartha agus is fรฉidir รญ a รบsรกid chun a fhรญorรบ go bhfuil geallta ag meaitseรกil aon seoltaรญ rรญomhphoist gnรญomhachtaithe don รบsรกideoir seo chomh maith le haon aitheantas comhoiriรบnaithe don eochair seo.
+gpg_key_verify = Fรญoraigh
+gpg_invalid_token_signature = Nรญ mheaitseรกlann an eochair, an sรญniรบ agus an comhartha GPG a sholรกthraรญtear nรณ tรก an comhartha as dรกta.
+gpg_token_required = Nรญ mรณr duit sรญniรบ a sholรกthar don chomhartha thรญos
+gpg_token = Comhartha
+gpg_token_help = Is fรฉidir leat sรญniรบ a ghiniรบint ag รบsรกid:
+gpg_token_signature = Sรญniรบ Armรบrtha GPG
+verify_gpg_key_success = Tรก eochair GPG โ%sโ fรญoraithe.
+ssh_key_verified = Eochair Fhรญoraithe
+ssh_key_verified_long = Fรญoraรญodh an eochair le heochairchomhartha agus is fรฉidir รญ a รบsรกid chun a fhรญorรบ go bhfuil geallta ag teacht le haon seoltaรญ rรญomhphoist gnรญomhachtaithe don รบsรกideoir seo.
+ssh_key_verify = Fรญoraigh
+ssh_invalid_token_signature = Nรญ mheaitseรกlann an eochair, an sรญniรบ nรณ an comhartha SSH a sholรกthraรญtear nรณ tรก an comhartha as dรกta.
+ssh_token_required = Nรญ mรณr duit sรญniรบ a sholรกthar don chomhartha thรญos
+ssh_token = Comhartha
+ssh_token_help = Is fรฉidir leat sรญniรบ a ghiniรบint ag รบsรกid:
+ssh_token_signature = Sรญniรบ armรบrtha SSH
+verify_ssh_key_success = Tรก eochair SSH โ%sโ fรญoraithe.
+subkeys = Fo-eochracha
+key_id = Eochair ID
+key_name = Ainm Eochair
+key_content = รbhar
+principal_content = รbhar
+add_key_success = Cuireadh an eochair SSH โ%sโ leis.
+add_gpg_key_success = Cuireadh an eochair GPG โ%sโ leis.
+add_principal_success = Cuireadh prรญomhoide an deimhnithe SSH โ%sโ leis.
+delete_key = Bain
+ssh_key_deletion = Bain Eochair SSH
+gpg_key_deletion = Bain Eochair GPG
+ssh_principal_deletion = Bain Prรญomhoide Teastas SSH
+ssh_key_deletion_desc = Ag baint eochair SSH, cuirtear a rochtain ar do chuntas a chรบlghairm. Lean ar aghaidh?
+gpg_key_deletion_desc = Mรก bhaintear eochair GPG, nรญ fhรญoraรญtear gealltanais a shรญnigh sรฉ. An leanfaidh tรบ ar aghaidh?
+ssh_principal_deletion_desc = Cรบlghairtear a rochtain ar do chuntas Prรญomhoide Teastas SSH. Lean ar aghaidh?
+ssh_key_deletion_success = Tรก an eochair SSH bainte.
+gpg_key_deletion_success = Tรก an eochair GPG bainte amach.
+ssh_principal_deletion_success = Tรก an prรญomhoide bainte.
+added_on = Cuireadh leis ar %s
+valid_until_date = Bailรญ go dtรญ %s
+valid_forever = Bailรญ go deo
+last_used = รsรกidtear go deireanach ar
+no_activity = Gan gnรญomhaรญocht le dรฉanaรญ
+can_read_info = Lรฉigh
+can_write_info = Scrรญobh
+key_state_desc = รsรกideadh an eochair seo le 7 lรก anuas
+token_state_desc = รsรกideadh an comhartha seo le 7 lรก anuas
+principal_state_desc = รsรกideadh an prรญomhoide seo le 7 lรก anuas
+show_openid = Taispeรกin ar phrรณifรญl
+hide_openid = Folaigh รณn bprรณifรญl
+ssh_signonly = Tรก SSH faoi lรกthair faoi lรกthair mar sin nรญ รบsรกidtear na heochracha seo ach le haghaidh fรญorรบ sรญnithe tiomanta.
+ssh_externally_managed = Dรฉantar an eochair SSH seo a bhainistiรบ go seachtrach don รบsรกideoir seo
+generate_new_token = Gin Comhartha Nua
+token_name = Ainm Comhartha
+generate_token = Gin Comhartha
+generate_token_success = Gintear do chomhartha nua. Cรณipeรกil รฉ anois mar nรญ thaispeรกnfar รฉ arรญs.
+generate_token_name_duplicate = รsรกideadh %s mar ainm feidhmchlรกir cheana fรฉin. รsรกid ceann nua le do thoil.
+delete_token = Scrios
+access_token_deletion = Scrios Comhartha Rochtana
+access_token_deletion_desc = Cรบlghairfear rochtain ar do chuntas le haghaidh feidhmchlรกir a รบsรกideann รฉ a scriosadh comhartha. Nรญ fรฉidir รฉ seo a chur ar ais. Lean ar aghaidh?
+delete_token_success = Tรก an comhartha scriosta. Nรญl rochtain ag iarratais a รบsรกideann รฉ ar do chuntas a thuilleadh.
+repo_and_org_access = Rochtain Stรณrรกla agus Eagraรญochta
+permissions_public_only = Poiblรญ amhรกin
+permissions_access_all = Gach (poiblรญ, prรญobhรกideach agus teoranta)
+select_permissions = Roghnaigh ceadanna
+permission_no_access = Gan rochtain
+permission_read = Lรฉigh
+permission_write = Lรฉigh agus Scrรญobh
+at_least_one_permission = Nรญ mรณr duit cead amhรกin ar a laghad a roghnรบ chun comhartha a chruthรบ
+permissions_list = Ceadanna:
+manage_oauth2_applications = Bainistigh Feidhmchlรกir OAuth2
+edit_oauth2_application = Cuir Feidhmchlรกr OAuth2 in eagar
+remove_oauth2_application = Bain Feidhmchlรกr OAuth2
+remove_oauth2_application_desc = Ag baint feidhmchlรกr OAuth2, cรบlghairfear rochtain ar gach comhartha rochtana sรญnithe. Lean ar aghaidh?
+remove_oauth2_application_success = Scriosadh an feidhmchlรกr.
+create_oauth2_application = Cruthaigh Feidhmchlรกr OAuth2 nua
+create_oauth2_application_button = Cruthaigh Feidhmchlรกr
+create_oauth2_application_success = D'รฉirigh leat feidhmchlรกr nua OAuth2 a chruthรบ.
+update_oauth2_application_success = D'รฉirigh leat an feidhmchlรกr OAuth2 a nuashonrรบ.
+oauth2_application_name = Ainm Feidhmchlรกir
+oauth2_confidential_client = Cliant Rรบnda. Roghnaigh le haghaidh aipeanna a choimeรกdann an rรบn faoi rรบn, mar aipeanna grรฉasรกin. Nรก roghnaigh le haghaidh aipeanna dรบchasacha lena n-รกirรญtear aipeanna deisce agus soghluaiste.
+oauth2_redirect_uris = URIs a atreorรบ. รsรกid lรญne nua do gach URI le do thoil.
+save_application = Sรกbhรกil
+oauth2_client_id = ID Cliant
+oauth2_client_secret = Rรบnda Cliant
+oauth2_regenerate_secret = Athghin Rรบn
+oauth2_regenerate_secret_hint = Chaill tรบ do rรบn?
+oauth2_client_secret_hint = Nรญ thaispeรกnfar an rรบn arรญs tar รฉis duit an leathanach seo a fhรกgรกil nรณ a athnuachan. Dรฉan cinnte le do thoil gur shรกbhรกil tรบ รฉ.
+oauth2_application_edit = Cuir in eagar
+oauth2_application_create_description = Tugann feidhmchlรกir OAuth2 rochtain d'iarratas trรญรบ pรกirtรญ ar chuntais รบsรกideora ar an gcรกs seo.
+oauth2_application_remove_description = Cuirfear feidhmchlรกr OAuth2 a bhaint cosc air rochtain a fhรกil ar chuntais รบsรกideora รบdaraithe ar an gcรกs seo. Lean ar aghaidh?
+authorized_oauth2_applications = Feidhmchlรกir รdaraithe OAuth2
+revoke_key = Cรบlghairm
+revoke_oauth2_grant = Rochtain a chรบlghairm
+revoke_oauth2_grant_description = Cuirfidh rochtain ar an bhfeidhmchlรกr trรญรบ pรกirtรญ seo a chรบlghairm cosc ar an bhfeidhmchlรกr seo rochtain An bhfuil tรบ cinnte?
+revoke_oauth2_grant_success = Cรบlghairtear rochtain go rathรบil.
+twofa_desc = Chun do chuntas a chosaint ar goid pasfhocal, is fรฉidir leat fรณn cliste nรณ glรฉas eile a รบsรกid chun pasfhocail aon-uaire bunaithe ar am (โTOTPโ) a fhรกil.
+twofa_recovery_tip = Mรก chailleann tรบ do ghlรฉas, beidh tรบ in ann eochair aisghabhรกla aonรบsรกide a รบsรกid chun rochtain ar do chuntas a fhรกil ar ais.
+twofa_is_enrolled = Tรก do chuntas clรกraithe i bhfรญord heimhniรบ dhรก fhachtรณir faoi lรกthair.
+twofa_not_enrolled = Nรญl do chuntas clรกraithe faoi lรกthair i bhfรญordheimhniรบ dhรก fhachtรณir.
+twofa_disable = Dรญchumasaigh Fรญordheimhniรบ Dhรก-Fachtรณir
+twofa_scratch_token_regenerate = Athghin Eochair Aisghabhรกla Aonรบsรกide
+twofa_scratch_token_regenerated = Is รฉ %s d'eochair aisghabhรกla aonรบsรกide anois. Stรณrรกil รฉ in รกit shรกbhรกilte, mar nรญ thaispeรกnfar รฉ arรญs.
+twofa_enroll = Clรกraigh le Fรญordheimhniรบ Dhรก-Fachtรณir
+twofa_disable_note = Is fรฉidir leat fรญordheimhniรบ dhรก fhachtรณir a dhรญchumasรบ mรกs gรก.
+twofa_disable_desc = Mรก dhรญchumasaรญtear fรญordheimhniรบ dhรก fhachtรณir beidh do chuntas chomh slรกn. Lean ar aghaidh?
+regenerate_scratch_token_desc = Mรก chuir tรบ d'eochair aisghabhรกla mรญchuir tรบ nรณ mรก d'รบsรกid tรบ รฉ cheana fรฉin chun sรญniรบ isteach, is fรฉidir leat รฉ a athshocrรบ anseo.
+twofa_disabled = Tรก fรญordheimhniรบ dhรก fhachtรณir dรญchumasaithe.
+scan_this_image = Scan an รญomhรก seo le d'fheidhmchlรกr fรญordheimhnithe:
+or_enter_secret = Nรณ cuir isteach an rรบn: %s
+then_enter_passcode = Agus cuir isteach an paschรณd a lรฉirรญtear san fheidhmchlรกr:
+passcode_invalid = Tรก an pascรณd mรญcheart. Bain triail as arรญs.
+twofa_enrolled = Tรก do chuntas clรกraithe go rathรบil. Stรณrรกil d'eochair aisghabhรกla aonรบsรกide (%s) in รกit shรกbhรกilte, mar nรญ thaispeรกnfar รฉ arรญs.
+twofa_failed_get_secret = Theip ar rรบn a fhรกil.
+webauthn_desc = Is feistรญ crua-earraรญ iad eochracha slรกndรกla ina bhfuil eochracha cripte Is fรฉidir iad a รบsรกid le haghaidh fรญordheimhniรบ dhรก fhachtรณir. Caithfidh eochracha slรกndรกla tacรบ le caigh deรกn Fรญordheimhnithe WebAuthn
+webauthn_register_key = Cuir Eochair Slรกndรกla
+webauthn_nickname = Leasainm
+webauthn_delete_key = Bain Eochair Slรกndรกla
+webauthn_delete_key_desc = Mรก bhaineann tรบ eochair slรกndรกla nรญ fรฉidir leat sรญniรบ leis a thuilleadh. Lean ar aghaidh?
+webauthn_key_loss_warning = Mรก chailleann tรบ d'eochracha slรกndรกla, caillfidh tรบ rochtain ar do chuntas.
+webauthn_alternative_tip = B'fhรฉidir gur mhaith leat modh fรญordheimhnithe breise a chumrรบ.
+link_account = Cuntas Nasc
+remove_account_link = Bain Cuntas Nasctha
+remove_account_link_success = Tรก an cuntas nasctha bainte amach.
+hooks.desc = Cuir crรบcaรญ grรฉasรกn leis a spreagfar do gach stรณr ar leatsa iad.
+orgs_none = Nรญl tรบ ina bhall d'aon eagraรญochtaรญ.
+repos_none = Nรญl aon stรณrais agat.
+delete_account = Scrios Do Cuntas
+delete_prompt = Scriosfaidh an oibrรญocht seo do chuntas รบsรกideora go buan. Nร FรIDIR รฉ a chealรบ.
+delete_with_all_comments = Tรก do chuntas nรญos รณige nรก %s. Chun tuairimรญ taibhse a sheachaint, scriosfar gach trรกcht saincheistea/PR leis.
+confirm_delete_account = Deimhnigh scriosadh
+delete_account_title = Scrios Cuntas รsรกide
+delete_account_desc = An bhfuil tรบ cinnte gur mhaith leat an cuntas รบsรกideora seo a scriosadh go buan?
+email_notifications.enable = Cumasaigh Fรณgraรญ Rรญomhphoist
+email_notifications.onmention = Rรญomhphost amhรกin ar luaigh
+email_notifications.disable = Dรญchumasaigh Fรณgraรญ Rรญomhphoist
+email_notifications.submit = Socraigh rogha rรญomhphoist
+email_notifications.andyourown = Agus Do Fรณgraรญ Fรฉin
+visibility = Infheictheacht รบsรกideora
+visibility.public = Poiblรญ
+visibility.public_tooltip = Infheicthe do gach duine
+visibility.limited = Teoranta
+visibility.private = Prรญobhรกideach
+visibility.private_tooltip = Nรญ fheictear ach do bhaill d'eagraรญochtaรญ a chuaigh tรบ isteach
+
+[repo]
+owner = รinรฉir
+owner_helper = B'fhรฉidir nach dtaispeรกnfar roinnt eagraรญochtaรญ sa anuas mar gheall ar theorainn uasta comhaireamh stรณrais.
+repo_name = Ainm Stรณrais
+repo_size = Mรฉid an Stรณras
+template = Teimplรฉad
+template_helper = Dรฉan teimplรฉad den stรณras
+template_description = Ligeann stรณrais teimplรฉid d'รบsรกideoirรญ stรณrais nua a ghiniรบint leis an struchtรบr eolaire cรฉanna, comhaid agus socruithe roghnacha.
+visibility = Infheictheacht
+visibility_description = Nรญ bheidh ach an t-รบinรฉir nรณ baill na heagraรญochta mรก tรก cearta acu in ann รฉ a fheiceรกil.
+visibility_helper = Dรฉan stรณras prรญobhรกideach
+visibility_helper_forced = Cuireann riarthรณir do shuรญomh iallach ar stรณrais nua a bheith prรญobhรกideach.
+clone_helper = Teastaรญonn cabhair รณ chlรณnรกil? Tabhair cuairt ar Cabhair .
+fork_repo = Stรณras Forc
+fork_from = Forc รณ
+already_forked = Tรก tรบ tar รฉis %s a fhoirceann
+fork_to_different_account = Forc chuig cuntas difriรบil
+fork_visibility_helper = Nรญ fรฉidir infheictheacht stรณr forcailte a athrรบ.
+fork_branch = Brainse le clรณnรบ chuig an bhforc
+all_branches = Gach brainse
+fork_no_valid_owners = Nรญ fรฉidir an stรณr seo a fhorcรกil toisc nach bhfuil รบinรฉirรญ bailรญ ann.
+use_template = รsรกid an teimplรฉad seo
+open_with_editor = Oscail le %s
+download_zip = รoslรณdรกil ZIP
+download_tar = รoslรณdรกil TAR.GZ
+download_bundle = รoslรณdรกil BUNDLE
+generate_repo = Cruthaigh Stรณras
+generate_from = Gin ร
+repo_desc = Cur sรญos
+repo_desc_helper = Cuir isteach tuairisc ghearr (roghnach)
+repo_gitignore_helper_desc = Roghnaigh na comhaid nach bhfuil le rianรบ รณ liosta teimplรฉid do theangacha coitianta. Cuirtear dรฉantรกin tipiciรบla a ghineann uirlisรญ tรณgรกla gach teanga san รกireamh ar.gitignore de rรฉir rรฉamhshocraithe.
+license = Ceadรบnas
+object_format = Formรกid Oibiacht
+readme = README
+readme_helper_desc = Seo an รกit inar fรฉidir leat cur sรญos iomlรกn a scrรญobh do thionscadal.
+create_repo = Cruthaigh Stรณras
+default_branch = Branse Rรฉamhshocraithe
+default_branch_label = rรฉamhshocraithe
+default_branch_helper = Is รฉ an brainse rรฉamhshocraithe an bunbhrainse d'iarratais tarraingthe agus gealltanna cรณd.
+mirror_prune = Prรบnรกil
+mirror_prune_desc = Bain tagairtรญ cianrianaithe atรก as feidhm
+mirror_interval_invalid = Nรญl an eatramh scรกthรกin bailรญ.
+mirror_sync = sioncronaithe
+mirror_sync_on_commit = Sioncrรณnaigh nuair a bhrรบitear geallรบintรญ
+mirror_address = Clรณn ร URL
+mirror_address_desc = Cuir aon dhintiรบir riachtanacha sa chuid รdaraithe.
+mirror_address_url_invalid = Tรก an URL curtha ar fรกil neamhbhailรญ. Caithfidh tรบ gach comhphรกirt den url a รฉalรบ i gceart.
+mirror_address_protocol_invalid = Tรก an URL curtha ar fรกil neamhbhailรญ. Nรญ fรฉidir ach suรญomhanna http (s)://nรณ git://a รบsรกid le haghaidh scรกthรกin.
+mirror_lfs = Stรณrรกil Comhad Mรณra (LFS)
+mirror_lfs_desc = Gnรญomhachtaigh scรกthรบ sonraรญ LFS.
+mirror_lfs_endpoint = Crรญochphointe LFS
+mirror_lfs_endpoint_desc = Dรฉanfaidh Sync iarracht an url clรณnรกla a รบsรกid chun an freastalaรญ LFS a chinneadh . Is fรฉidir leat crรญochphointe saincheaptha a shonrรบ freisin mรก tรก na sonraรญ LFS stรณrtha stรณrรกilte รกit รฉigin eile.
+mirror_last_synced = Sincronaithe Deireanach
+mirror_password_placeholder = (Gan athrรบ)
+mirror_password_blank_placeholder = (Neamhshocraithe)
+mirror_password_help = Athraigh ainm รบsรกideora chun pasfhocal stรณrรกilte a scriosadh.
+watchers = Breathnรณirรญ
+stargazers = Rรฉalteoirรญ
+stars_remove_warning = Bainfidh sรฉ seo na rรฉaltaรญ go lรฉir รณn stรณras seo.
+forks = Forcanna
+stars = Rรฉaltaรญ
+reactions_more = agus %d nรญos mรณ
+unit_disabled = Tรก an chuid stรณrais seo dรญchumasaithe ag riarthรณir an lรกithreรกin.
+language_other = Eile
+adopt_search = Iontrรกil ainm รบsรกideora chun stรณrais neamhghlactha a chuardach... (fรกg bรกn chun gach rud a fhรกil)
+adopt_preexisting_label = Glacadh le Comhaid
+adopt_preexisting = Glac le comhaid atรก ann cheana
+adopt_preexisting_content = Cruthaigh stรณr รณ %s
+adopt_preexisting_success = Comhaid ghlacadh agus stรณr cruthaithe รณ %s
+delete_preexisting_label = Scrios
+delete_preexisting = Scrios comhaid atรก ann cheana
+delete_preexisting_content = Scrios comhaid i %s
+delete_preexisting_success = Scriosta comhaid neamhghlactha i %s
+blame_prior = Fรฉach ar an milleรกn roimh an athrรบ seo
+blame.ignore_revs = Ag dรฉanamh neamhairde de leasuithe i .git-blame-ignore-revs . Cliceรกil anseo chun seachaint agus an gnรกth-amharc milleรกn a fheiceรกil.
+blame.ignore_revs.failed = Theip ar neamhaird a dhรฉanamh ar leasuithe i .git-blame-ignore-revs .
+transfer.accept = Glac le hAistriรบ
+transfer.accept_desc = Aistriรบ chuig โ%sโ
+transfer.reject = Diรบltaigh aistriรบ
+transfer.reject_desc = `Cealaigh aistriรบ chuig "%s"`
+transfer.no_permission_to_accept = Nรญl cead agat glacadh leis an aistriรบ seo.
+transfer.no_permission_to_reject = Nรญl cead agat an aistriรบ seo a dhiรบltรบ.
+desc.private = Prรญobhรกideach
+desc.public = Poiblรญ
+desc.template = Teimplรฉad
+desc.internal = Inmheรกnach
+desc.archived = Cartlannaithe
+desc.sha256 = SHA256
+template.items = Mรญreanna Teimplรฉad
+template.git_content = รbhar Git (Brainse Rรฉamhshocraithe)
+template.git_hooks = Crรบcanna Git
+template.git_hooks_tooltip = Faoi lรกthair nรญ fรฉidir leat Git Hooks a mhodhnรบ nรณ a bhaint nuair a chuirtear leis. Roghnaigh รฉ seo ach amhรกin mรก tรก muinรญn agat as an stรณras teimplรฉid.
+template.webhooks = Crรบcaรญ grรฉasรกin
+template.topics = Topaicรญ
+template.avatar = Abhatรกr
+template.issue_labels = Lipรฉid Eisiรบna
+template.one_item = Nรญ mรณr mรญr teimplรฉad amhรกin ar a laghad a roghnรบ
+template.invalid = Nรญ mรณr stรณr teimplรฉad a roghnรบ
+archive.title_date = Tรก an stรณras seo cartlannaithe ar %s. Is fรฉidir leat comhaid a fheiceรกil agus รฉ a chlรณnรบ, ach nรญ fรฉidir leat saincheisteanna a bhrรบ nรณ a oscailt nรก iarratais a tharraingt.
+form.reach_limit_of_creation_1 = Tรก รบinรฉir an stรณras tar รฉis teorainn de %d stรณras a bhaint amach cheana fรฉin.
+form.reach_limit_of_creation_n = Tรก รบinรฉir an stรณrais tar รฉis teorainn de %d stรณrtha a bhaint amach cheana fรฉin.
+form.name_reserved = Tรก ainm an stรณr "%s" in รกirithe.
+form.name_pattern_not_allowed = Nรญ cheadaรญtear an patrรบn "%s" in ainm stรณr.
+need_auth = รdarรบ
+migrate_options = Roghanna Imirce
+migrate_options_mirror_helper = Beidh an stรณras seo ina scรกthรกn
+migrate_options_lfs = Aimirce comhaid LFS
+migrate_options_lfs_endpoint.label = Crรญochphointe LFS
+migrate_options_lfs_endpoint.description = Dรฉanfaidh imirce iarracht do chianda Git a รบsรกid chun freastalaรญ LFS a chinneadh . Is fรฉidir leat crรญochphointe saincheaptha a shonrรบ freisin mรก tรก na sonraรญ LFS stรณrtha stรณrรกilte รกit รฉigin eile.
+migrate_options_lfs_endpoint.description.local = Tacaรญtear le cosรกn freastalaรญ รกitiรบil freisin.
+migrate_options_lfs_endpoint.placeholder = Mรก fhรกgtar bรกn, dรญorthรณfar an crรญochphointe รณn URL clรณin
+migrate_items = Mรญreanna Imirce
+migrate_items_wiki = Wiki
+migrate_items_milestones = Clocha mรญle
+migrate_items_labels = Lipรฉid
+migrate_items_issues = Saincheisteanna
+migrate_items_pullrequests = Iarrataรญ Tarraing
+migrate_items_merge_requests = Iarrataรญ Cumaisc
+migrate_items_releases = Eisiรบintรญ
+migrate_repo = Stรณras Imirc
+migrate.clone_address = Aimirce/ Clรณn ร URL
+migrate.github_token_desc = Is fรฉidir leat comhartha amhรกin nรณ nรญos mรณ a chur le camรณg scartha anseo chun imirce a dhรฉanamh nรญos gasta mar gheall ar theorainn rรกta API GitHub. RABHADH: D'fhรฉadfadh mรญ-รบsรกid na ngnรฉ seo beartas an sholรกthraรญ seirbhรญse a shรกrรบ agus blocรกil cuntais a bheith mar thoradh air.
+migrate.clone_local_path = nรณ cosรกn freastalaรญ รกitiรบil
+migrate.permission_denied = Nรญ cheadaรญtear duit stรณrais รกitiรบla a iompรณrtรกil.
+migrate.permission_denied_blocked = Nรญ fรฉidir leat allmhairiรบ รณ รณstaigh neamh-cheadaithe, iarr ar an riarachรกn socruithe ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS a sheiceรกil le do thoil.
+migrate.invalid_lfs_endpoint = Nรญl an crรญochphointe LFS bailรญ.
+migrate.failed = Theip ar an imirce:% v
+migrate.migrate_items_options = Teastaรญonn Comhartha Rochtana chun mรญreanna breise a aistriรบ
+migrated_from = Aistrรญodh รณ %[2]s
+migrated_from_fake = Aistrithe รณ %[1]s
+migrate.migrate = Aistrigh ร %s
+migrate.migrating = Ag aistriรบ รณ %s ...
+migrate.migrating_failed = Theip ar aistriรบ รณ %s .
+migrate.migrating_failed.error = Theip ar aistriรบ: %s
+migrate.migrating_failed_no_addr = Theip ar an imirce.
+migrate.git.description = Aistrigh stรณr amhรกin รณ aon seirbhรญs Git.
+migrate.gitlab.description = Aistrigh sonraรญ รณ gitlab.com nรณ รณ chรกsanna GitLab eile.
+migrate.gitea.description = Aistrigh sonraรญ รณ gitea.com nรณ รณ chรกsanna Gitea eile.
+migrate.gogs.description = Aistrigh sonraรญ รณ notabug.org nรณ รณ chรกsanna eile de chuid Gogs.
+migrate.onedev.description = Aistrigh sonraรญ รณ code.onedev.io nรณ รณ chรกsanna OneDev eile.
+migrate.codebase.description = Aistrigh sonraรญ รณ codebasehq.com.
+migrate.gitbucket.description = Aistrigh sonraรญ รณ chรกsanna GitBucket.
+migrate.migrating_git = Sonraรญ Git a Aimirce
+migrate.migrating_topics = รbhair Imirce
+migrate.migrating_milestones = Clocha Mรญle a Imirce
+migrate.migrating_labels = Lipรฉid Imirce
+migrate.migrating_releases = Eisiรบintรญ Imirce
+migrate.migrating_issues = Saincheisteanna Imirce
+migrate.migrating_pulls = Iarratais Tarraingthe รก n-Imirce
+migrate.cancel_migrating_title = Cealaigh Imirce
+migrate.cancel_migrating_confirm = Ar mhaith leat an imirce seo a chealรบ?
+mirror_from = scรกthรกn de
+forked_from = forcailte รณ
+generated_from = a ghintear รณ
+fork_from_self = Nรญ fรฉidir leat stรณras atรก agat a fhorcรกil.
+fork_guest_user = Sรญnigh isteach chun an stรณras seo a fhorc.
+watch_guest_user = Sรญnigh isteach chun fรฉachaint ar an stรณr seo.
+star_guest_user = Sรญnigh isteach chun an stรณras seo a rรฉalรบ.
+watch = Fhรฉachaint
+unwatch = Dรญfhรฉachaint
+star = Rรฉalta
+unstar = Bain Rรฉalta
+fork = Forc
+download_archive = รoslรณdรกil Stรณras
+more_operations = Tuilleadh oibrรญochtaรญ
+quick_guide = Treoir Tapa
+clone_this_repo = Clรณin an stรณras seo
+cite_this_repo = Luaigh an stรณras seo
+create_new_repo_command = Stรณras nua a chruthรบ ar an lรญne ordaithe
+push_exist_repo = Stรณras atรก ann cheana a bhrรบ รณn lรญne ordaithe
+empty_message = Nรญl aon รกbhar sa stรณras seo.
+broken_message = Nรญ fรฉidir na sonraรญ Git atรก mar bhunรบs leis an stรณras seo a lรฉamh. Dรฉan teagmhรกil le riarthรณir an chรกs seo nรณ scrios an stรณras seo.
+code = Cรณd
+code.desc = Rochtain ar chรณd foinse, comhaid, gealltanais agus brainsรญ.
+branch = Brainse
+tree = Crann
+clear_ref = `Tagairt reatha soilรฉir`
+filter_branch_and_tag = Scagaire brainse nรณ clib
+find_tag = Aimsigh clib
+branches = Brainsรญ
+tag = Clib
+tags = Clibeanna
+issues = Saincheisteanna
+pulls = Iarratais Tarraingthe
+packages = Pacรกistรญ
+actions = Gnรญomhartha
+release = Scaoileadh
+releases = Scaoileann
+labels = Lipรฉid
+milestones = Clocha mรญle
+org_labels_desc = Lipรฉid ar leibhรฉal eagraรญochta is fรฉidir a รบsรกid le gach stรณras faoin eagraรญocht seo
+org_labels_desc_manage = bainistigh
+commits = Tiomรกintรญ
+commit = Tiomantas
+released_this = scaoileadh seo
+file.title = %s ag %s
+file_raw = Amh
+file_history = Stair
+file_view_source = Fรฉach Foinse
+file_view_rendered = Amharc Rindreรกilte
+file_view_raw = Amharc Amh
+file_permalink = Buan-nasc
+file_too_large = Tรก an comhad rรณ-mhรณr le taispeรกint.
+invisible_runes_header = `Tรก carachtair Unicode dofheicthe sa chomhad seo `
+invisible_runes_description = `Tรก carachtair dofheicthe Unicode sa chomhad seo nach fรฉidir a idirdhealรบ do dhaoine ach d'fhรฉadfadh rรญomhaire iad a phrรณiseรกil ar bhealach difriรบil. Mรก cheapann tรบ go bhfuil sรฉ seo d'aon ghnรณ, is fรฉidir leat neamhaird a dhรฉanamh go sรกbhรกilte don rabhadh seo รsรกid an cnaipe Escape chun iad a nochtadh. `
+ambiguous_runes_header = `Tรก carachtair Unicode dรฉbhrรญoch sa chomhad seo `
+ambiguous_runes_description = `Tรก carachtair Unicode sa chomhad seo a d'fhรฉadfadh a bheith mearbhall le carachtair eile. Mรก cheapann tรบ go bhfuil sรฉ seo d'aon ghnรณ, is fรฉidir leat neamhaird a dhรฉanamh go sรกbhรกilte don rabhadh seo รsรกid an cnaipe Escape chun iad a nochtadh. `
+invisible_runes_line = `Tรก carachtair unicode dofheicthe ag an lรญne seo `
+ambiguous_runes_line = `Tรก carachtair unicode dรฉbhrรญoch ag an lรญne seo `
+ambiguous_character = `Is fรฉidir %[1]c [U+%04[1]X] a mheascadh le %[2]c [U+%04[2]X]`
+escape_control_characters = รalรบ
+unescape_control_characters = Dรญ-รalรบ
+file_copy_permalink = Cรณipeรกil Buan-nasc
+view_git_blame = Fรฉach ar Git Blame
+stored_lfs = Stรณrรกilte le Git LFS
+symbolic_link = Nasc siombalach
+executable_file = Comhad Infheidhmithe
+vendored = Dรญoltรณra
+generated = Gintear
+commit_graph = Graf Tiomantas
+commit_graph.select = Roghnaigh brainsรญ
+commit_graph.hide_pr_refs = Folaigh Iarrataรญ Tarraing
+commit_graph.monochrome = Mona
+commit_graph.color = Dath
+commit.contained_in = Tรก an tiomantas seo le fรกil i:
+commit.contained_in_default_branch = Tรก an tiomantas seo mar chuid den bhrainse rรฉamhshocraithe
+commit.load_referencing_branches_and_tags = Luchtaigh brainsรญ agus clibeanna a thagraรญonn an tiomantas
+blame = An milleรกn
+download_file = รoslรณdรกil comhad
+normal_view = Amharc Gnรกth
+line = lรญne
+lines = lรญnte
+from_comment = (trรกcht)
+editor.add_file = Cuir Comhad
+editor.new_file = Comhad Nua
+editor.upload_file = Uaslรณdรกil Comhad
+editor.edit_file = Cuir Comhad in eagar
+editor.preview_changes = Athruithe Rรฉamhamhar
+editor.cannot_edit_lfs_files = Nรญ fรฉidir comhaid LFS a chur in eagar sa chomhรฉadan grรฉasรกin.
+editor.cannot_edit_non_text_files = Nรญ fรฉidir comhaid dhรฉnรกrtha a chur in eagar sa chomhรฉadan grรฉasรกin.
+editor.edit_this_file = Cuir Comhad in eagar
+editor.this_file_locked = Tรก an comhad faoi ghlas
+editor.must_be_on_a_branch = Caithfidh tรบ a bheith ar bhrainse chun athruithe a dhรฉanamh nรณ a mholadh ar an gcomhad seo.
+editor.fork_before_edit = Nรญ mรณr duit an stรณr seo a fhorcรกil chun athruithe a dhรฉanamh nรณ a mholadh ar an gcomhad seo.
+editor.delete_this_file = Scrios Comhad
+editor.must_have_write_access = Caithfidh rochtain scrรญofa a bheith agat chun athruithe a dhรฉanamh nรณ a mholadh ar an gcomhad seo.
+editor.file_delete_success = Tรก an comhad "%s" scriosta.
+editor.name_your_file = Ainmnigh do chomhadโฆ
+editor.or = nรณ
+editor.cancel_lower = Cealaigh
+editor.commit_signed_changes = Tiomantas Athruithe Sรญnithe
+editor.commit_changes = Athruithe a Tiomantas
+editor.add = Cuir %s leis
+editor.update = Nuashonraigh %s
+editor.delete = Scrios %s
+editor.patch = Cuir paiste i bhfeidh
+editor.patching = Paisteรกil:
+editor.fail_to_apply_patch = Nรญ fรฉidir paiste "%s" a chur i bhfeidhm
+editor.new_patch = Paiste Nua
+editor.commit_message_desc = Cuir cur sรญos leathnaithe roghnach leisโฆ
+editor.signoff_desc = Cuir leantรณir sรญnithe ag an gcoiteoir ag deireadh na teachtaireachta logรกla tiomanta.
+editor.create_new_branch = Cruthaigh brainse nua don ghealltanas seo agus cuir tรบs le hiarratas tarraingthe.
+editor.create_new_branch_np = Cruthaigh brainse nua don tiomantas seo.
+editor.propose_file_change = Athrรบ comhad a mholadh
+editor.new_branch_name = Ainmnigh an brainse nua don gealltanas seo
+editor.new_branch_name_desc = Ainm brainse nuaโฆ
+editor.cancel = Cealaigh
+editor.filename_cannot_be_empty = Nรญ fรฉidir ainm an chomhaid a bheith folamh.
+editor.filename_is_invalid = Tรก ainm an chomhaid neamhbhailรญ: "%s".
+editor.branch_does_not_exist = Nรญl brainse "%s" ann sa stรณras seo.
+editor.branch_already_exists = Tรก brainse "%s" ann cheana fรฉin sa stรณras seo.
+editor.directory_is_a_file = รsรกidtear ainm eolaire "%s" cheana fรฉin mar ainm comhaid sa stรณras seo.
+editor.file_is_a_symlink = Is nasc siombalach รฉ "%s". Nรญ fรฉidir naisc shiombalacha a chur in eagar san eagarthรณir grรฉasรกin
+editor.filename_is_a_directory = รsรกidtear ainm comhaid "%s" cheana fรฉin mar ainm eolaire sa stรณras seo.
+editor.file_editing_no_longer_exists = Nรญl an comhad atรก รก chur in eagar, "%s", ann sa stรณras seo a thuilleadh.
+editor.file_deleting_no_longer_exists = Nรญl an comhad atรก รก scriosadh, "%s", ann sa stรณras seo a thuilleadh.
+editor.file_changed_while_editing = Tรก athrรบ tagtha ar รกbhar an chomhad รณ thosaigh tรบ ag eagarthรณireacht Cliceรกil anseo chun iad a fheiceรกil nรณ Athru ithe a Tiomantas arรญs chun iad a fhorscrรญobh.
+editor.file_already_exists = Tรก comhad darb ainm "%s" ann cheana fรฉin sa stรณras seo.
+editor.push_out_of_date = Is cosรบil go bhfuil an brรบ as dรกta.
+editor.commit_empty_file_header = Tiomantas comhad folamh
+editor.commit_empty_file_text = Tรก an comhad atรก tรบ ar tรญ tiomantas folamh. Ar aghaidh?
+editor.no_changes_to_show = Nรญl aon athruithe le taispeรกint.
+editor.fail_to_update_file = Theip ar nuashonrรบ/cruthรบ comhad "%s".
+editor.fail_to_update_file_summary = Teachtaireacht Earrรกide:
+editor.push_rejected_no_message = Dhiรบltaigh an freastalaรญ an t-athrรบ gan teachtaireacht. Seiceรกil Git Hooks le do thoil.
+editor.push_rejected = Dhiรบltaigh an freastalaรญ an t-athrรบ. Seiceรกil Git Hooks le do thoil.
+editor.push_rejected_summary = Teachtaireacht Diรบltaithe Iomlรกn:
+editor.add_subdir = Cuir eolaire leisโฆ
+editor.unable_to_upload_files = Theip ar uaslรณdรกil comhaid go "%s" le hearrรกid: %v
+editor.upload_file_is_locked = Tรก comhad "%s" faoi ghlas ag %s.
+editor.upload_files_to_dir = `Uaslรณdรกil comhaid go "%s"`
+editor.cannot_commit_to_protected_branch = Nรญ fรฉidir gealltanas a thabhairt don bhrainse faoi chosaint "%s".
+editor.no_commit_to_branch = Nรญ fรฉidir tiomantas a thabhairt go dรญreach don bhrainse mar:
+editor.user_no_push_to_branch = Nรญ fรฉidir leis an รบsรกideoir brรบigh go dtรญ an brainse
+editor.require_signed_commit = รilรญonn an Brainse tiomantas sรญnithe
+editor.cherry_pick = Roghnaigh silรญnรญ %s ar:
+editor.revert = Fill %s ar:
+editor.commit_email = Tiomantas rรญomhphost
+commits.desc = Brabhsรกil stair athraithe cรณd foinse.
+commits.commits = Tiomรกintรญ
+commits.no_commits = Nรญl aon ghealltanas i gcoiteann. Tรก stair iomlรกn difriรบil ag "%s" agus "%s".
+commits.nothing_to_compare = Tรก na brainsรญ seo cothrom.
+commits.search.tooltip = Is fรฉidir eochairfhocail a rรฉamhfhostรบ le โรบdar:โ, โcommitter:โ, โafter:โ, nรณ โbefore:โ, e.g. "fill an t-รบdar:Alice roimh: 2019-01-13".
+commits.search_branch = An Brainse seo
+commits.search_all = Gach Brainse
+commits.author = รdar
+commits.message = Teachtaireacht
+commits.date = Dรกta
+commits.older = Nรญos sine
+commits.newer = Nรญos nuaรญ
+commits.signed_by = Sรญnithe ag
+commits.signed_by_untrusted_user = Sรญnithe ag รบsรกideoir neamhiontaofa
+commits.signed_by_untrusted_user_unmatched = Sรญnithe ag รบsรกideoir neamhiontaofa nach bhfuil ag teacht leis an gcoiste
+commits.gpg_key_id = GPG Eochair ID
+commits.ssh_key_fingerprint = Mรฉarloirg Eochair SSH
+commits.view_path = Fรฉach ag an bpointe seo sa stair
+commit.operations = Oibrรญochtaรญ
+commit.revert = Tรฉigh ar ais
+commit.revert-header = Tรฉigh ar ais: %s
+commit.revert-content = Roghnaigh brainse chun filleadh ar:
+commit.cherry-pick = Roghnaigh silรญnรญ
+commit.cherry-pick-header = Roghnaigh silรญnรญ: %s
+commit.cherry-pick-content = Roghnaigh brainse chun silรญnรญ a phiocadh air:
+commitstatus.error = Earrรกid
+commitstatus.failure = Teip
+commitstatus.pending = Ar feitheamh
+commitstatus.success = Rath
+projects = Tionscadail
+projects.description = Cur sรญos (roghnach)
+projects.description_placeholder = Cur sรญos
+projects.create = Cruthaigh Tionscadal
+projects.title = Teideal
+projects.new = Tionscadal Nua
+projects.new_subheader = Dรฉan do chuid oibre a chomhordรบ, a rianรบ agus a nuashonrรบ in aon รกit amhรกin, ionas go bhfanann na tionscadail trรฉdhearcach agus de rรฉir sceidil.
+projects.create_success = Tรก an tionscadal "%s" cruthaithe.
+projects.deletion = Scrios tionscadal
+projects.deletion_desc = Mรก scriostar tionscadal, bainfear de gach saincheist a bhaineann leis รฉ. Lean ort?
+projects.deletion_success = Tรก an tionscadal scriosta.
+projects.edit = Cuir Tionscadal in Eagar
+projects.edit_subheader = Eagraรญonn tionscadail saincheisteanna agus rianaรญonn siad dul chun cinn.
+projects.modify = Cuir Tionscadal in Eagar
+projects.edit_success = Tรก an tionscadal "%s" nuashonraithe.
+projects.open = Oscailte
+projects.close = Dรบn
+projects.column.assigned_to = Sannta do
+issues.desc = Eagraigh tuarascรกlacha fabht, tascanna agus cloch mhรญle.
+issues.filter_assignees = Scagaire Sannaitheoir
+issues.filter_milestones = Cloch Mhรญle Scagaire
+issues.filter_projects = Tionscadal Scagaire
+issues.filter_labels = Lipรฉad Scagaire
+issues.filter_reviewers = Athbhreithneoir Scagaire
+issues.new = Eagrรกn Nua
+issues.new.title_empty = Nรญ fรฉidir leis an teideal a bheith folamh
+issues.new.labels = Lipรฉid
+issues.new.clear_labels = Lipรฉid shoilรฉir
+issues.new.projects = Tionscadail
+issues.new.clear_projects = Tionscadail soilรฉire
+issues.new.no_projects = Gan aon tionscadal
+issues.new.open_projects = Tionscadail Oscailte
+issues.new.closed_projects = Tionscadail Dรบnta
+issues.new.no_items = Gan aon earraรญ
+issues.new.milestone = Cloch Mhรญle
+issues.new.no_milestone = Gan Chloch Mhรญle
+issues.new.clear_milestone = Cloch Mhรญle soilรฉir
+issues.new.assignees = Sannaitheoirรญ
+issues.new.clear_assignees = Ceannaitheoirรญ soilรฉir
+issues.new.no_assignees = Gan aon Sannaitheoirรญ
+issues.new.no_reviewers = Gan Lรฉirmheastรณirรญ
+issues.edit.already_changed = Nรญ fรฉidir athruithe a shรกbhรกil ar an tsaincheist. Dealraรญonn sรฉ gur athraigh รบsรกideoir eile an t-รกbhar cheana fรฉin. Athnuachan an leathanach agus dรฉan iarracht eagarthรณireacht arรญs chun a gcuid athruithe a sheachaint
+issues.choose.get_started = Faigh Tosaigh
+issues.choose.open_external_link = Oscailte
+issues.choose.blank = Rรฉamhshocrรบ
+issues.choose.blank_about = Cruthaigh saincheist รณ theimplรฉad rรฉamhshocraithe.
+issues.choose.ignore_invalid_templates = Rinneadh neamhaird ar theimplรฉid
+issues.choose.invalid_templates = %v teimplรฉad neamhbhail(รญ) aimsรญodh
+issues.choose.invalid_config = Tรก earrรกidรญ sa chumraรญocht eisiรบint:
+issues.no_ref = Nรญl aon Brainse/Clib Sonraithe
+issues.create = Cruthaigh Saincheist
+issues.new_label = Lipรฉad Nua
+issues.new_label_placeholder = Ainm lipรฉad
+issues.new_label_desc_placeholder = Cur sรญos
+issues.create_label = Cruthaigh Lipรฉad
+issues.label_templates.fail_to_load_file = Theip ar lรณdรกil an chomhaid teimplรฉid lipรฉid "%s": %v
+issues.add_label = cuireadh an lipรฉad %s %s leis
+issues.add_labels = cuireadh na %s lipรฉid %s
+issues.remove_label = bainte an %s lipรฉad %s
+issues.remove_labels = bainte na %s lipรฉid %s
+issues.add_remove_labels = chuir %s leis agus bhain %s lipรฉid %s
+issues.add_milestone_at = `chuir seo leis an gcloch mhรญle %s %s`
+issues.add_project_at = `chuir seo leis an tionscadal %s %s`
+issues.change_milestone_at = `mionathraithe an chloch mhรญle รณ %s go %s %s`
+issues.change_project_at = `mionathraithe an tionscadal รณ %s go %s %s`
+issues.remove_milestone_at = ` bhain seo den %s chloch mhรญle %s`
+issues.remove_project_at = `bhain sรฉ seo den %s an tionscadal %s`
+issues.deleted_milestone = `(scriosta)`
+issues.deleted_project = `(scriosta)`
+issues.self_assign_at = `fรฉin-shannta an %s seo`
+issues.add_assignee_at = `a shannadh ag %s %s`
+issues.remove_assignee_at = `a bhรญ gan shannadh ag %s %s`
+issues.remove_self_assignment = `bhain siad a sannadh %s`
+issues.change_title_at = `athraigh an teideal รณ %s go %s %s`
+issues.change_ref_at = `tagairt athraithe รณ %s go %s %s`
+issues.remove_ref_at = `bhaint an tagairt %s %s`
+issues.add_ref_at = `Cuireadh an tagairt %s %s leis`
+issues.delete_branch_at = `brainse scriosta %s %s`
+issues.filter_label = Lipรฉad
+issues.filter_label_exclude = `รsรกid alt
+ cliceรกil/iontrรกil
chun lipรฉid a eisiamh`
+issues.filter_label_no_select = Gach lipรฉad
+issues.filter_label_select_no_label = Gan lipรฉad
+issues.filter_milestone = Cloch Mhรญle
+issues.filter_milestone_all = Gach cloch mhรญle
+issues.filter_milestone_none = Gan aon clocha mhรญle
+issues.filter_milestone_open = Clocha mhรญle oscailte
+issues.filter_milestone_closed = Clocha mhรญle dรบnta
+issues.filter_project = Tionscadal
+issues.filter_project_all = Gach tionscadal
+issues.filter_project_none = Gan aon tionscadal
+issues.filter_assignee = Sannaitheoir
+issues.filter_assginee_no_select = Gach sannaithe
+issues.filter_assginee_no_assignee = Gan sannaitheoir
+issues.filter_poster = รdar
+issues.filter_type = Cineรกl
+issues.filter_type.all_issues = Gach saincheist
+issues.filter_type.assigned_to_you = Sannta duit
+issues.filter_type.created_by_you = Cruthaithe agat
+issues.filter_type.mentioning_you = Ag tagairt duit
+issues.filter_type.review_requested = Athbhreithniรบ iarrtha
+issues.filter_type.reviewed_by_you = Athbhreithnithe agat
+issues.filter_sort = Sรณrtรกil
+issues.filter_sort.latest = Is nuaรญ
+issues.filter_sort.oldest = Is sine
+issues.filter_sort.recentupdate = Nuashonraithe le dรฉanaรญ
+issues.filter_sort.leastupdate = Is lรบ a nuashonraรญodh le dรฉanaรญ
+issues.filter_sort.mostcomment = Is mรณ a bhfuil trรกchtanna air
+issues.filter_sort.leastcomment = Is lรบ a bhfuil trรกchtanna air
+issues.filter_sort.nearduedate = An dรกta dlite is gaire
+issues.filter_sort.farduedate = An dรกta dlite is faide
+issues.filter_sort.moststars = An lรญon rรฉaltaรญ is mรณ
+issues.filter_sort.feweststars = An lรญon rรฉaltaรญ is lรบ
+issues.filter_sort.mostforks = An lรญon forcanna is mรณ
+issues.filter_sort.fewestforks = An lรญon forcanna is lรบ
+issues.action_open = Oscailte
+issues.action_close = Dรบn
+issues.action_label = Lipรฉad
+issues.action_milestone = Cloch Mhรญle
+issues.action_milestone_no_select = Gan Chloch Mhรญle
+issues.action_assignee = Sannaitheoir
+issues.action_assignee_no_select = Gan sannaitheoir
+issues.action_check = Seiceรกil/Dรญsheiceรกil
+issues.action_check_all = Seiceรกil/Dรญsheiceรกil gach mireanna
+issues.opened_by = oscail %[1]s le %[3]s
+pulls.merged_by = le %[3]s cumasc %[1]s
+pulls.merged_by_fake = le %[2]s a chumasc %[1]s
+issues.closed_by = le dรบnadh %[3]s %[1]s
+issues.opened_by_fake = oscail %[1]s le %[2]s
+issues.closed_by_fake = faoi โโ%[2]s dรบnadh %[1]s
+issues.previous = Roimhe Seo
+issues.next = Ar Aghaidh
+issues.open_title = Oscailte
+issues.closed_title = Dรบnta
+issues.draft_title = Drรฉacht
+issues.num_comments_1 = %d trรกcht
+issues.num_comments = %d trรกchtanna
+issues.commented_at = `trรกcht %s `
+issues.delete_comment_confirm = An bhfuil tรบ cinnte gur mhaith leat an trรกcht seo a scriosadh?
+issues.context.copy_link = Cรณipeรกil Nasc
+issues.context.quote_reply = Luaigh Freagra
+issues.context.edit = Cuir in eagar
+issues.context.delete = Scrios
+issues.no_content = Nรญl aon tuairisc ar fรกil.
+issues.close = Dรบn Eagrรกn
+issues.comment_pull_merged_at = cumasc tiomantas %[1]s le %[2]s %[3]s
+issues.comment_manually_pull_merged_at = cumasc tiomantas %[1]s le %[2]s %[3]s
+issues.close_comment_issue = Dรบn le trรกcht
+issues.reopen_issue = Athoscail
+issues.reopen_comment_issue = Athoscail le trรกcht
+issues.create_comment = Trรกcht
+issues.closed_at = `dhรบn an cheist seo %[2]s `
+issues.reopened_at = `athoscail an t-eagrรกn seo %[2]s `
+issues.commit_ref_at = `rinne tagairt don cheist seo รณ ghealltanas %[2]s `
+issues.ref_issue_from = `rinne dagairt don cheist seo %[4]s %[2]s `
+issues.ref_pull_from = `rinne dagairt don iarratas tarraingthe seo %[4]s %[ 2]s `
+issues.ref_closed_from = `dhรบn an cheist seo %[4]s %[2]s `
+issues.ref_reopened_from = `d'athoscail an eagrรกn seo %[4]s %[2]s `
+issues.ref_from = `รณ %[1]s`
+issues.author = รdar
+issues.role.owner = รinรฉir
+issues.role.owner_helper = Is รฉ an t-รบsรกideoir seo รบinรฉir an stรณr seo.
+issues.role.member = Comhalta
+issues.role.member_helper = Is ball den eagraรญocht รฉ an t-รบsรกideoir seo a bhfuil an stรณr seo ina รบinรฉireacht.
+issues.role.collaborator = Comhoibritheoir
+issues.role.collaborator_helper = Tugadh cuireadh don รบsรกideoir seo comhoibriรบ ar an stรณras.
+issues.role.first_time_contributor = Cuiditheoir den chรฉad uair
+issues.role.first_time_contributor_helper = Seo รฉ an chรฉad uair a chuir an t-รบsรกideoir seo leis an stรณras.
+issues.role.contributor = Cuiditheoir
+issues.re_request_review = Athiarraigh athbhreithniรบ
+issues.is_stale = Rinneadh athruithe ar an PR seo รณn athbhreithniรบ seo
+issues.remove_request_review = Bain iarratas athbhreithni
+issues.remove_request_review_block = Nรญ fรฉidir iarratas athbhreithnithe a bhaint
+issues.dismiss_review = Dรญbhe Athbhreithnithe
+issues.dismiss_review_warning = An bhfuil tรบ cinnte gur mhaith leat an athbhreithnithe seo a dhรญbhe?
+issues.sign_in_require_desc = Sรญnigh isteach chun dul isteach sa chomhrรก seo.
+issues.edit = Cuir in eagar
+issues.cancel = Cealaigh
+issues.save = Sรกbhรกil
+issues.label_title = Ainm
+issues.label_description = Cur sรญos
+issues.label_color = Dath
+issues.label_exclusive = Eisiach
+issues.label_archive = Lipรฉad Cartlann
+issues.label_archived_filter = Taispeรกin lipรฉid cartlainne
+issues.label_archive_tooltip = Eisiatar lipรฉid chartlainne de rรฉir rรฉamhshocraithe รณ na moltaรญ nuair a dhรฉantar cuardach de rรฉir lipรฉid.
+issues.label_exclusive_desc = Ainmnigh an lipรฉad scope/item
chun รฉ a dhรฉanamh comheisiatach le lipรฉid scope/
eile.
+issues.label_exclusive_warning = Bainfear aon lipรฉid scรณipe contrรกrtha le linn eagarthรณireacht a dhรฉanamh ar lipรฉid iarratais eisiรบna nรณ tarraingthe.
+issues.label_count = %d lipรฉid
+issues.label_open_issues = %d saincheisteanna oscailte/iarratais tarraing
+issues.label_edit = Cuir in eagar
+issues.label_delete = Scrios
+issues.label_modify = Cuir Lipรฉad in Eagar
+issues.label_deletion = Scrios Lipรฉad
+issues.label_deletion_desc = Baineann lipรฉad a scriosadh รฉ รณ gach saincheist. Lean ar aghaidh?
+issues.label_deletion_success = Tรก an lipรฉad scriosta.
+issues.label.filter_sort.alphabetically = Aibรญtreach
+issues.label.filter_sort.reverse_alphabetically = Aisiompรบ in ord aibรญtre
+issues.label.filter_sort.by_size = Mรฉid is lรบ
+issues.label.filter_sort.reverse_by_size = Mรฉid is mรณ
+issues.attachment.open_tab = `Cliceรกil chun "%s" a fheiceรกil i gcluaisรญn nua`
+issues.attachment.download = `Cliceรกil chun "%s" a รญoslรณdรกil`
+issues.subscribe = Liostรกil
+issues.unsubscribe = Dรญliostรกil
+issues.lock = Cuir glas ar an gcomhrรก
+issues.unlock = Dรญghlasรกil comhrรก
+issues.lock.unknown_reason = Nรญ fรฉidir fadhb a ghlasรกil le cรบis anaithnid.
+issues.lock_duplicate = Nรญ fรฉidir saincheist a ghlasรกil faoi dhรณ.
+issues.unlock_error = Nรญ fรฉidir saincheist nach bhfuil glasรกilte a dhรญghlasรกil.
+issues.lock_confirm = Glas
+issues.unlock_confirm = Dรญghlasรกil
+issues.lock.notice_2 = - Is fรฉidir leatsa agus le comhoibrithe eile a bhfuil rochtain acu ar an stรณr seo fรณs tuairimรญ a fhรกgรกil a fheiceann daoine eile.
+issues.lock.notice_3 = - Is fรฉidir leat an tsaincheist seo a dhรญghlasรกil arรญs sa todhchaรญ.
+issues.unlock.notice_1 = - Bheadh gach duine in ann trรกcht a dhรฉanamh ar an gceist seo arรญs.
+issues.unlock.notice_2 = - Is fรฉidir leat an tsaincheist seo a ghlasรกil arรญs sa todhchaรญ i gcรณnaรญ.
+issues.lock.reason = Cรบis le glasรกil
+issues.lock.title = Glas comhrรก ar an gceist seo.
+issues.unlock.title = Dรญghlasรกil comhrรก ar an gceist seo.
+issues.comment_on_locked = Nรญ fรฉidir leat trรกcht a dhรฉanamh ar shaincheist faoi ghlas.
+issues.delete = Scrios
+issues.delete.title = Scrios an t-eagrรกn seo?
+issues.delete.text = An bhfuil tรบ cinnte gur mhaith leat an cheist seo a scriosadh? (Bainfidh sรฉ seo an t-inneachar go lรฉir go buan. Smaoinigh ar รฉ a dhรบnadh ina ionad sin, mรก tรก sรฉ i gceist agat รฉ a choinneรกil i gcartlann)
+issues.tracker = Rianaitheoir Ama
+issues.tracker_auto_close = Stopfar ama go huathoibrรญoch nuair a dhรบnfar an tsaincheist seo
+issues.tracking_already_started = `Tรก tรบs curtha agat cheana fรฉin ag rianรบ ama ar eagrรกn eile !`
+issues.cancel_tracking_history = `rianรบ ama curtha ar ceal %s`
+issues.del_time = Scrios an log ama seo
+issues.del_time_history = `an t-am caite scriosta %s`
+issues.add_time_hours = Uaireanta
+issues.add_time_minutes = Miontuairi
+issues.add_time_sum_to_small = Nรญor iontrรกilรญodh aon am.
+issues.time_spent_total = An t-am iomlรกn a chaitear
+issues.time_spent_from_all_authors = `Am Iomlรกn Caitear: %s`
+issues.due_date = Dรกta dlite
+issues.force_push_compare = Dรฉan comparรกid
+issues.dependency.title = Spleithiรบlachtaรญ
+issues.dependency.issue_no_dependencies = Nรญl aon spleรกchais leagtha sรญos.
+issues.dependency.pr_no_dependencies = Nรญl aon spleรกchais leagtha sรญos.
+issues.dependency.add = Cuir spleรกchas leisโฆ
+issues.dependency.cancel = Cealaigh
+issues.dependency.remove = Bain
+issues.dependency.remove_info = Bain an spleรกchas seo
+issues.dependency.added_dependency = `cuireadh spleรกchas nua %s`
+issues.dependency.removed_dependency = `bainte spleรกchas %s`
+issues.dependency.pr_closing_blockedby = Cuireann na saincheisteanna seo a leanas bac ar an iarratas tarraingte seo a dhรบnadh
+issues.dependency.issue_closing_blockedby = Tรก na saincheisteanna seo a leanas bac ar dhรบnadh an cheist seo
+issues.dependency.issue_close_blocks = Cuireann an tsaincheist seo bac ar dhรบnadh na saincheisteanna
+issues.dependency.pr_close_blocks = Cuireann an iarratas tarraingthe seo bac ar dhรบnadh na saincheisteanna
+issues.dependency.issue_close_blocked = Nรญ mรณr duit gach saincheist a chuireann bac ar an gceist seo a dhรบnadh sular fรฉidir leat รฉ a dhรบnadh.
+issues.dependency.pr_close_blocked = Nรญ mรณr duit gach saincheist a bhlocรกlann an iarratas tarraingthe seo a dhรบnadh sula fรฉidir leat รฉ a chumasc.
+issues.dependency.blocks_short = Bloic
+issues.dependency.blocked_by_short = Ag brath ar
+issues.dependency.remove_header = Bain spleรกchas
+issues.dependency.issue_remove_text = Bainfidh sรฉ seo an spleรกchas รณn gceist seo. Lean ar aghaidh?
+issues.dependency.pr_remove_text = Bainfidh sรฉ seo an spleรกchas รณn iarratas tarraingthe seo. Lean ar aghaidh?
+issues.dependency.setting = Cumasaigh spleรกchais le haghaidh Saincheisteanna agus Iarrataรญ Tar
+issues.dependency.add_error_same_issue = Nรญ fรฉidir leat ceist a dhรฉanamh ag brath air fรฉin.
+issues.dependency.add_error_dep_issue_not_exist = Nรญl saincheist spleรกch ann.
+issues.dependency.add_error_dep_not_exist = Nรญ bhรญonn spleรกchas ann.
+issues.dependency.add_error_dep_exists = Tรก spleรกchas ann cheana fรฉin.
+issues.dependency.add_error_cannot_create_circular = Nรญ fรฉidir leat spleรกchas a chruthรบ le dhรก shaincheist a chuireann bac ar a chรฉile.
+issues.dependency.add_error_dep_not_same_repo = Caithfidh an dรก shaincheist a bheith sa stรณr cรฉanna.
+issues.review.self.approval = Nรญ fรฉidir leat d'iarratas tarraingthe fรฉin a cheadรบ.
+issues.review.self.rejection = Nรญ fรฉidir leat athruithe a iarraidh ar d'iarratas tarraingthe fรฉin.
+issues.review.dismissed_label = Dhiรบltaigh
+issues.review.left_comment = d'fhรกg trรกcht
+issues.review.content.empty = Nรญ mรณr duit trรกcht a fhรกgรกil a lรฉirรญonn an t-athrรบ (รญ) iarrtha.
+issues.review.pending = Ar feitheamh
+issues.review.pending.tooltip = Nรญl an nรณta trรกchta seo le feiceรกil ag รบsรกideoirรญ eile faoi lรกthair. Chun do thuairimรญ ar feitheamh a chur isteach, roghnaigh "%s" -> "%s/%s/%s" ag barr an leathanaigh.
+issues.review.reviewers = Lรฉirmheasรณirรญ
+issues.review.outdated = As dรกta
+issues.review.outdated_description = Tรก athrรบ tagtha ar รกbhar รณ rinneadh an trรกcht seo
+issues.review.option.show_outdated_comments = Taispeรกin trรกchtanna atรก as dรกta
+issues.review.option.hide_outdated_comments = Folaigh trรกchtanna atรก as dรกta
+issues.review.show_outdated = Taispeรกin as dรกta
+issues.review.hide_outdated = Folaigh as dรกta
+issues.review.show_resolved = Taispeรกin rรฉitithe
+issues.review.hide_resolved = Folaigh rรฉitithe
+issues.review.resolve_conversation = Rรฉitigh comhrรก
+issues.review.un_resolve_conversation = Comhrรก gan rรฉiteach
+issues.review.resolved_by = mharcรกil an comhrรก seo mar rรฉitigh
+issues.reference_issue.body = Comhlacht
+issues.content_history.deleted = scriosta
+issues.content_history.edited = curtha in eagar
+issues.content_history.created = cruthaithe
+issues.content_history.delete_from_history = Scrios รณn stair
+issues.content_history.delete_from_history_confirm = Scrios รณn stair?
+issues.content_history.options = Roghanna
+issues.reference_link = Tagairt: %s
+compare.compare_base = bonn
+compare.compare_head = dรฉan comparรกid
+pulls.desc = Cumasaigh iarratais tarraingthe agus athbhreithnithe cรณd.
+pulls.new = Iarratas Tarraingthe Nua
+pulls.view = Fรฉach ar Iarratas Tarraing
+pulls.edit.already_changed = Nรญ fรฉidir athruithe a shรกbhรกil ar an iarratas tarraingthe. Dealraรญonn sรฉ gur athraigh รบsรกideoir eile an t-รกbhar cheana fรฉin. Athnuachan an leathanach agus dรฉan iarracht eagarthรณireacht arรญs chun a gcuid athruithe a sheachaint
+pulls.compare_changes = Iarratas Tarraingthe Nua
+pulls.allow_edits_from_maintainers = Ceadaigh eagarthรณirรญ รณ chothabhรกlaรญ
+pulls.allow_edits_from_maintainers_desc = Is fรฉidir le hรบsรกideoirรญ a bhfuil rochtain scrรญofa acu ar an mbunbhrainse brรบ chuig an bhrainse
+pulls.allow_edits_from_maintainers_err = Theip ar nuashonrรบ
+pulls.compare_changes_desc = Roghnaigh an brainse le cumasc isteach agus an brainse le tarraingt uaidh.
+pulls.has_viewed_file = Breathnaithe
+pulls.has_changed_since_last_review = Athraithe รณ d'athbhreithniรบ deire
+pulls.viewed_files_label = Breathnaรญodh ar %[1]d / %[2]d comhaid
+pulls.expand_files = Leathnaigh gach comhaid
+pulls.collapse_files = Laghdaigh gach comhaid
+pulls.compare_base = cumaisc isteach
+pulls.compare_compare = tarraing รณ
+pulls.switch_comparison_type = Athraigh cineรกl comparรกide
+pulls.switch_head_and_base = Athraigh ceann agus bonn
+pulls.filter_branch = Brainse scagaire
+pulls.show_all_commits = Taispeรกin gach gealltanas
+pulls.show_changes_since_your_last_review = Taispeรกin athruithe รณn lรฉirmheas deiridh
+pulls.showing_only_single_commit = Ag taispeรกint athruithe tiomantais %[1]s amhรกin
+pulls.showing_specified_commit_range = Ag taispeรกint athruithe idir %[1]s..%[2]s
+pulls.select_commit_hold_shift_for_range = Roghnaigh tiomantas. Coinnigh shift + cliceรกil chun raon a roghnรบ
+pulls.review_only_possible_for_full_diff = Nรญ fรฉidir athbhreithniรบ a dhรฉanamh ach amhรกin nuair a bhreathnaรญtear ar an difrรญocht iomlรกn
+pulls.filter_changes_by_commit = Scagaigh de rรฉir tiomantas
+pulls.nothing_to_compare = Tรก na brainsรญ seo cothrom. Nรญ gรก iarratas tarraingthe a chruthรบ.
+pulls.nothing_to_compare_have_tag = Tรก an brainse/clib roghnaithe cothrom.
+pulls.nothing_to_compare_and_allow_empty_pr = Tรก na brainsรญ seo cothrom. Beidh an PR seo folamh.
+pulls.has_pull_request = `Tรก iarratas tarraingthe idir na brainsรญ seo ann cheana: %[2]s#%[3]d `
+pulls.create = Cruthaigh Iarratas Tarraing
+pulls.change_target_branch_at = `athraigh an spriocbhrainse รณ %s go %s %s`
+pulls.tab_conversation = Comhrรก
+pulls.tab_commits = Tiomรกintรญ
+pulls.tab_files = Comhaid Athraithe
+pulls.reopen_to_merge = Athoscail an t-iarratas tarraingthe seo le do thoil chun cumasc a dhรฉanamh.
+pulls.cant_reopen_deleted_branch = Nรญ fรฉidir an t-iarratas tarraingthe seo a athoscailt toisc gur scriosadh an brainse.
+pulls.merged = Cumaiscthe
+pulls.merged_success = D'รฉirigh leis an iarratas tarraingthe a chumasc agus a dhรบnadh
+pulls.closed = Iarratas tarraingthe dรบnta
+pulls.manually_merged = Cumaisc de lรกimh
+pulls.merged_info_text = Is fรฉidir an brainse %s a scriosadh anois.
+pulls.is_closed = Tรก an t-iarratas tarraingthe dรบnta.
+pulls.title_wip_desc = `Tosaigh an teideal le %s chun an t-iarratas tarraingthe a chosc รณ chumasc de thaisme.`
+pulls.cannot_merge_work_in_progress = Tรก an t-iarratas tarraingthe seo marcรกilte mar obair atรก ar siรบl.
+pulls.still_in_progress = Fรณs ar siรบl?
+pulls.add_prefix = Cuir rรฉimรญr %s leis
+pulls.remove_prefix = Bain an rรฉimรญr %s
+pulls.data_broken = Tรก an t-iarratas tarraingthe seo briste mar gheall ar fhaisnรฉis forc a bheith in easnamh.
+pulls.files_conflicted = Tรก athruithe ag an iarratas tarraingthe seo atรก contrรกrtha leis an spriocbhrainse.
+pulls.required_status_check_failed = Nรญor รฉirigh le roinnt seiceรกlacha riachtanacha.
+pulls.required_status_check_missing = Tรก roinnt seiceanna riachtanacha ar iarraidh.
+pulls.required_status_check_administrator = Mar riarthรณir, fรฉadfaidh tรบ an t-iarratas tarraingthe seo a chumasc fรณs.
+pulls.can_auto_merge_desc = Is fรฉidir an t-iarratas tarraingt seo a chumasc go huathoibrรญoch.
+pulls.cannot_auto_merge_desc = Nรญ fรฉidir an t-iarratas tarraingthe seo a chumasc go huathoibrรญoch mar gheall ar choinbhleachtaรญ.
+pulls.cannot_auto_merge_helper = Cumaisc de lรกimh chun na coinbhleachtaรญ a rรฉiteach.
+pulls.no_merge_desc = Nรญ fรฉidir an t-iarratas tarraingthe seo a chumasc toisc go bhfuil gach rogha cumaisc stรณr dรญchumasaithe.
+pulls.no_merge_helper = Cumasaigh roghanna cumaisc i socruithe an stรณr nรณ cumasc an t-iarratas tarraingthe de lรกimh.
+pulls.no_merge_wip = Nรญ fรฉidir an t-iarratas tarraingthe seo a chumasc toisc go bhfuil sรฉ marcรกilte mar obair atรก ar siรบl รฉ.
+pulls.no_merge_not_ready = Nรญl an t-iarratas tarraingthe seo rรฉidh le cumasc, seiceรกil stรกdas athbhreithnithe agus seiceรกlacha stรกdais.
+pulls.no_merge_access = Nรญl tรบ รบdaraithe chun an t-iarratas tarraingthe seo a chumasc.
+pulls.merge_pull_request = Cruthaigh tiomantas cumaisc
+pulls.rebase_merge_pull_request = Athbhunaigh ansin go tapa ar aghaidh
+pulls.rebase_merge_commit_pull_request = Rebase ansin cruthaigh tiomantas cumaisc
+pulls.squash_merge_pull_request = Cruthaigh tiomantas scuaise
+pulls.fast_forward_only_merge_pull_request = Go tapa ar aghaidh amhรกin
+pulls.merge_manually = Cumaisc de lรกimh
+pulls.merge_commit_id = ID an tiomantis cumaisc
+pulls.require_signed_wont_sign = รilรญonn an bhrainse tiomรกintรญ shรญnithe, ach nรญ shรญnรญfear an cumasc seo
+pulls.invalid_merge_option = Nรญ fรฉidir leat an rogha cumaisc seo a รบsรกid don iarratas tarraingthe seo.
+pulls.merge_conflict = Theip ar Cumaisc: Bhรญ coinbhleacht ann agus รฉ ag cumasc. Leid: Bain triail as straitรฉis dhifriรบil
+pulls.merge_conflict_summary = Teachtaireacht Earrรกide
+pulls.rebase_conflict = Theip ar Chumasc: Bhรญ coinbhleacht ann agus tiomantas รก athbhunรบ: %[1]s. Leid: Bain triail as straitรฉis eile
+pulls.rebase_conflict_summary = Teachtaireacht Earrรกide
+pulls.unrelated_histories = Theip ar Cumaisc: Nรญ roinneann an ceann cumaisc agus an bonn stair choiteann. Leid: Bain triail as straitรฉis dhifriรบil
+pulls.merge_out_of_date = Theip ar Cumaisc: Agus an cumaisc รก ghiniรบint, nuashonraรญodh an bonn. Leid: Bain triail as arรญs.
+pulls.head_out_of_date = Theip ar Cumaisc: Agus an cumaisc รก ghiniรบint, nuashonraรญodh an ceann. Leid: Bain triail as arรญs.
+pulls.has_merged = Theip ar: Cumaisรญodh an t-iarratas tarraingthe, nรญ fรฉidir leat a chumasc arรญs nรณ an spriocbhrainse a athrรบ.
+pulls.push_rejected = Theip ar Brรบigh: Diรบltaรญodh don bhrรบ. Dรฉan athbhreithniรบ ar na Git Hooks don stรณr seo.
+pulls.push_rejected_summary = Teachtaireacht Diรบltaithe Iomlรกn
+pulls.push_rejected_no_message = Theip ar Brรบigh: Diรบltaรญodh don bhrรบ ach nรญ raibh aon teachtaireacht iargรบlta ann. Dรฉan athbhreithniรบ ar Git Hooks don stรณr seo
+pulls.open_unmerged_pull_exists = `Nรญ fรฉidir leat oibrรญocht athoscailte a dhรฉanamh toisc go bhfuil iarratas tarraingthe ar feitheamh (#%d) le hairรญonna comhionanna. `
+pulls.status_checking = Tรก roinnt seiceรกla ar feitheamh
+pulls.status_checks_success = D'รฉirigh le gach seiceรกil
+pulls.status_checks_warning = Thuairiscigh roinnt seiceรกlacha rabhaidh
+pulls.status_checks_failure = Theip ar roinnt seiceรกlacha
+pulls.status_checks_error = Thug roinnt seiceรกlacha earrรกidรญ
+pulls.status_checks_requested = Riachtanach
+pulls.status_checks_details = Sonraรญ
+pulls.status_checks_hide_all = Folaigh gach seiceรกil
+pulls.status_checks_show_all = Taispeรกin gach seiceรกil
+pulls.update_branch = Nuashonrรบ brainse trรญ chumasc
+pulls.update_branch_rebase = Nuashonraigh an bhrainse trรญ athbhunรบ
+pulls.update_branch_success = Bhรญ nuashonrรบ brainse rathรบil
+pulls.update_not_allowed = Nรญ cheadaรญtear duit brainse a nuashonrรบ
+pulls.outdated_with_base_branch = Tรก an brainse seo as dรกta leis an mbunbhrainse
+pulls.close = Dรบn Iarratas Tarraing
+pulls.closed_at = `dhรบn an t-iarratas tarraingthe seo %[2]s `
+pulls.reopened_at = `athoscail an t-iarratas tarraingthe seo %[2]s `
+pulls.cmd_instruction_checkout_title = Seiceรกil
+pulls.cmd_instruction_checkout_desc = ร stรณr tionscadail, seiceรกil brainse nua agus dรฉan tรกstรกil ar na hathruithe.
+pulls.cmd_instruction_merge_title = Cumaisc
+pulls.clear_merge_message = Glan an teachtaireacht chumaisc
+pulls.clear_merge_message_hint = Mรก imrรญtear an teachtaireacht chumaisc nรญ bhainfear ach รกbhar na teachtaireachta tiomanta agus coimeรกdfar leantรณirรญ git ginte ar nรณs "Co-Authored-By โฆ".
+pulls.auto_merge_button_when_succeed = (Nuair a รฉirรญonn le seiceรกlacha)
+pulls.auto_merge_when_succeed = Cumaisc uathoibrรญoch nuair a รฉirรญonn
+pulls.auto_merge_newly_scheduled = Bhรญ an t-iarratas tarraingt sceidealta le cumasc nuair a รฉirรญonn le gach seiceรกil.
+pulls.auto_merge_has_pending_schedule = Bhรญ an t-iarratas tarraingthe seo sceidealaithe ag %[1]s chun cumasc uathoibrรญoch a dhรฉanamh nuair a รฉirรญonn le gach seiceรกil %[2]s.
+pulls.auto_merge_cancel_schedule = Cealaigh cumasc uathoibrรญoch
+pulls.auto_merge_not_scheduled = Nรญl an t-iarratas tarraingthe seo sceidealaithe le cumasc go huathoibrรญoch.
+pulls.auto_merge_canceled_schedule = Cealaรญodh an cumaisc uathoibrรญoch don iarratas tarraingthe seo.
+pulls.auto_merge_newly_scheduled_comment = `sceidealta an t-iarratas tarraingthe seo le cumasc uathoibrithe nuair a รฉirรญonn le gach seiceรกil %[1]s`
+pulls.auto_merge_canceled_schedule_comment = `curtha ar ceal uathchumasc leis an iarratas tarraingthe seo nuair a รฉirรญonn le gach seiceรกil %[1]s`
+pulls.delete.title = Scrios an t-iarratas tarraingthe seo?
+pulls.delete.text = An bhfuil tรบ cinnte gur mhaith leat an t-iarratas tarraingthe seo a scriosadh? (Bainfidh sรฉ seo an t-inneachar go lรฉir go buan. Smaoinigh ar รฉ a dhรบnadh ina ionad sin, mรก tรก sรฉ i gceist agat รฉ a choinneรกil i gcartlann)
+pull.deleted_branch = (scriosta): %s
+comments.edit.already_changed = Nรญ fรฉidir athruithe a shรกbhรกil ar an trรกcht. Dealraรญonn sรฉ gur athraigh รบsรกideoir eile an t-รกbhar cheana fรฉin. Athnuachan an leathanach agus dรฉan iarracht eagarthรณireacht arรญs chun a gcuid athruithe a sheachaint
+milestones.new = Cloch Mhรญle Nua
+milestones.closed = Dรบnta %s
+milestones.update_ago = Nuashonraithe %s
+milestones.no_due_date = Gan dรกta dlite
+milestones.open = Oscailte
+milestones.close = Dรบn
+milestones.new_subheader = Is fรฉidir le clocha mรญle cabhrรบ leat ceisteanna a eagrรบ agus a ndul chun cinn a rianรบ.
+milestones.completeness = %d%% Crรญochnaithe
+milestones.create = Cruthaigh Cloch Mhรญle
+milestones.title = Teideal
+milestones.desc = Cur sรญos
+milestones.due_date = Dรกta dlite (roghnach)
+milestones.clear = Glan
+milestones.create_success = Cruthaรญodh an chloch mhรญle "%s".
+milestones.edit = Cuir Cloch Mhรญle in eagar
+milestones.edit_subheader = Eagraรญonn Garspriocanna saincheisteanna agus rianaรญtear dul chun cinn.
+milestones.cancel = Cealaigh
+milestones.modify = Nuashonraigh Cloch Mhรญle
+milestones.edit_success = Nuashonraรญodh cloch mhรญle "%s".
+milestones.deletion = Scrios Cloch Mhรญle
+milestones.deletion_desc = Cuireann scriosadh cloch mhรญle รฉ as gach saincheist ghaolmhar. Lean ar aghaidh?
+milestones.deletion_success = Tรก an chloch mhรญle scriosta.
+milestones.filter_sort.name = Ainm
+milestones.filter_sort.least_complete = Is lรบ crรญochnaithe
+milestones.filter_sort.most_complete = Is mรณ crรญochnaithe
+milestones.filter_sort.most_issues = Saincheisteanna is mรณ
+milestones.filter_sort.least_issues = Saincheisteanna is lรบ
+signing.will_sign = Sรญneofar an gealltanas seo le heochair "%s".
+signing.wont_sign.error = Bhรญ earrรกid ann agus tรบ ag seiceรกil an fรฉidir an tiomantas a shรญniรบ.
+signing.wont_sign.never = Nรญ shรญnรญtear tiomรกintรญ riamh.
+signing.wont_sign.always = Sรญnรญtear tiomรกintรญ i gcรณnaรญ.
+signing.wont_sign.pubkey = Nรญ shรญnรญofar an tiomantas toisc nach bhfuil eochair phoiblรญ agat a bhaineann le do chuntas.
+signing.wont_sign.twofa = Caithfidh fรญordheimhniรบ dhรก-fhachtรณir a bheith agat chun tiomรกintรญ a shรญniรบ.
+signing.wont_sign.parentsigned = Nรญ shรญnรญofar an tiomantas toisc nach bhfuil an tiomantas tuismitheora sรญnithe.
+signing.wont_sign.basesigned = Nรญ shรญnรญfear an cumasc toisc nach bhfuil an tiomantas bunaithe sรญnithe.
+signing.wont_sign.headsigned = Nรญ shรญnรญfear an cumasc toisc nach bhfuil an tiomantas ceann sรญnithe.
+signing.wont_sign.commitssigned = Nรญ shรญnรญfear an cumasc toisc nach bhfuil na tiomรกintรญ gaolmhara go lรฉir sรญnithe.
+signing.wont_sign.approved = Nรญ shรญnรญofar an cumaisc toisc nach bhfuil an PR ceadaithe.
+signing.wont_sign.not_signed_in = Nรญl tรบ sรญnithe isteach.
+wiki = Vicรญ
+wiki.welcome = Fรกilte go dtรญ an Vicรญ.
+wiki.welcome_desc = Ligeann an vicรญ duit cรกipรฉisรญocht a scrรญobh agus a roinnt le comhoibrithe.
+wiki.desc = Scrรญobh agus roinn cรกipรฉisรญocht le comhoibrithe.
+wiki.create_first_page = Cruthaigh an Chรฉad Leathanach
+wiki.page = Leathanach
+wiki.filter_page = Leathanach scagaire
+wiki.new_page = Leathanach
+wiki.page_title = Teideal an leathanaigh
+wiki.page_content = รbhar an leathanaigh
+wiki.default_commit_message = Scrรญobh nรณta faoin nuashonrรบ leathanaigh seo (roghnach).
+wiki.save_page = Sรกbhรกil Leathanach
+wiki.last_commit_info = Cuireadh %s an leathanach seo in eagar %s
+wiki.edit_page_button = Cuir in eagar
+wiki.new_page_button = Leathanach Nua
+wiki.file_revision = Athbhreithniรบ Leathanach
+wiki.back_to_wiki = Ar ais go leathanach vicรญ
+wiki.delete_page_button = Scrios Leathanach
+wiki.delete_page_notice_1 = Nรญ fรฉidir leathanach vicรญ "%s" a scriosadh. Lean ort?
+wiki.page_already_exists = Tรก leathanach vicรญ leis an ainm cรฉanna ann cheana fรฉin.
+wiki.reserved_page = Tรก an t-ainm leathanaigh vicรญ "%s" in รกirithe.
+wiki.pages = Leathanaigh
+wiki.last_updated = Nuashonraithe deireanach %s
+wiki.original_git_entry_tooltip = Fรฉach ar an gcomhad bunaidh Git in ionad nasc cairdiรบil a รบsรกid.
+activity = Gnรญomhaรญocht
+activity.navbar.pulse = Cuisle
+activity.navbar.code_frequency = Minicรญocht Cรณd
+activity.navbar.contributors = Rannphรกirtithe
+activity.navbar.recent_commits = Tiomรกintรญ le dรฉanaรญ
+activity.period.filter_label = Trรฉimhse:
+activity.period.daily = 1 lรก
+activity.period.halfweekly = 3 lรก
+activity.period.weekly = 1 seachtain
+activity.period.monthly = 1 mhรญ
+activity.period.quarterly = 3 mhรญ
+activity.period.semiyearly = 6 mhรญ
+activity.period.yearly = 1 bhliain
+activity.overview = Forbhreathnรบ
+activity.active_prs_count_1 = %d Iarratas Tarraingthe Gnรญomhach
+activity.active_prs_count_n = %d Iarratais Tharraing Ghnรญomhach
+activity.merged_prs_count_1 = Iarratas Tarraing Cumaisc
+activity.merged_prs_count_n = Iarratais Tharraing Chomhcheangail
+activity.opened_prs_count_1 = Iarratas Tarraing Beartaithe
+activity.opened_prs_count_n = Iarratais Tarraing Beartaithe
+activity.title.user_1 = %d รบsรกideoir
+activity.title.user_n = %d รบsรกideoirรญ
+activity.title.prs_1 = Iarratas tarraing %d
+activity.title.prs_n = %d Iarratais Tarraing
+activity.title.prs_merged_by = %s a chumasc ag %s
+activity.title.prs_opened_by = %s arna mholadh ag %s
+activity.merged_prs_label = Cumaiscthe
+activity.opened_prs_label = Molta
+activity.active_issues_count_1 = %d Eagrรกn Gnรญomhach
+activity.active_issues_count_n = %d Ceisteanna Gnรญomhacha
+activity.closed_issues_count_1 = Saincheist Dรบnta
+activity.closed_issues_count_n = Saincheisteanna Dรบnta
+activity.title.issues_1 = Saincheist %d
+activity.title.issues_n = Saincheisteanna %d
+activity.title.issues_closed_from = %s dรบnta รณ %s
+activity.title.issues_created_by = %s cruthaithe ag %s
+activity.closed_issue_label = Dรบnta
+activity.new_issues_count_1 = Eagrรกn Nua
+activity.new_issues_count_n = Saincheisteanna Nua
+activity.new_issue_label = Osclaรญodh
+activity.title.unresolved_conv_1 = %d Comhrรก Neamhrรฉitithe
+activity.title.unresolved_conv_n = %d Comhrรกite Neamhrรฉitithe
+activity.unresolved_conv_desc = Nรญor rรฉitรญodh na saincheisteanna agus na hiarratais tarraingthe seo le dรฉanaรญ fรณs.
+activity.unresolved_conv_label = Oscailte
+activity.title.releases_1 = Scaoileadh %d
+activity.title.releases_n = Eisiรบintรญ %d
+activity.title.releases_published_by = %s foilsithe ag %s
+activity.no_git_activity = Nรญor rinneadh aon ghnรญomhaรญocht tiomanta sa trรฉimhse seo.
+activity.git_stats_exclude_merges = Gan cumaisc a รกireamh,
+activity.git_stats_author_1 = %d รบdar
+activity.git_stats_author_n = %d รบdair
+activity.git_stats_pushed_1 = tรก sรฉ brรบite
+activity.git_stats_pushed_n = tรก brรบ orthu
+activity.git_stats_commit_1 = %d tiomantas
+activity.git_stats_commit_n = %d tiomรกintรญ
+activity.git_stats_push_to_branch = chuig %s agus
+activity.git_stats_push_to_all_branches = chuig gach brainse.
+activity.git_stats_on_default_branch = Ar %s,
+activity.git_stats_file_1 = %d comhad
+activity.git_stats_file_n = %d comhaid
+activity.git_stats_files_changed_1 = tรก athrรบ tagtha
+activity.git_stats_files_changed_n = tรก athraithe
+activity.git_stats_additions = agus tรก ann
+activity.git_stats_addition_1 = %d breisiรบ
+activity.git_stats_addition_n = %d breiseanna
+activity.git_stats_and_deletions = agus
+activity.git_stats_deletion_1 = %d scriosadh
+activity.git_stats_deletion_n = %d scriosta
+contributors.contribution_type.filter_label = Cineรกl rannรญocaรญochta:
+contributors.contribution_type.commits = Tiomรกintรญ
+contributors.contribution_type.additions = Breiseanna
+contributors.contribution_type.deletions = Scriosadh
+settings = Socruithe
+settings.desc = Is รฉ socruithe an รกit ar fรฉidir leat na socruithe don stรณras a bhainistiรบ
+settings.options = Stรณras
+settings.collaboration = Comhoibritheoirรญ
+settings.collaboration.admin = Riarthรณir
+settings.collaboration.write = Scrรญobh
+settings.collaboration.read = Lรฉigh
+settings.collaboration.owner = รinรฉir
+settings.collaboration.undefined = Neamhshainithe
+settings.hooks = Crรบcaรญ Grรฉasรกn
+settings.githooks = Crรบcanna Git
+settings.basic_settings = Socruithe Bunรบsacha
+settings.mirror_settings = Socruithe Scรกthรกn
+settings.mirror_settings.docs = Cuir do stรณras ar bun chun tiomรกintรญ, clibeanna agus brainsรญ a shioncronรบ go huathoibrรญoch le stรณras eile.
+settings.mirror_settings.docs.disabled_pull_mirror.instructions = Socraigh do thionscadal chun tiomรกintรญ, clibeanna agus brainsรญ a bhrรบ go huathoibrรญoch chuig stรณras eile. Tรก scรกthรกin tarraingthe dรญchumasaithe ag riarthรณir do shuรญomh.
+settings.mirror_settings.docs.disabled_push_mirror.instructions = Socraigh do thionscadal chun tiomรกintรญ, clibeanna agus brainsรญ a tharraingt go huathoibrรญoch รณ stรณras eile.
+settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning = Faoi lรกthair, nรญ fรฉidir รฉ seo a dhรฉanamh ach sa roghchlรกr "Imirce Nua". Le haghaidh tuilleadh eolais, tรฉigh i gcomhairle le do thoil:
+settings.mirror_settings.docs.disabled_push_mirror.info = Chuir riarthรณir do shuรญomh faoi dhรญchumasรบ scรกthรกin bhrรบ.
+settings.mirror_settings.docs.no_new_mirrors = Tรก do stรณras ag teacht le hathruithe chuig nรณ รณ stรณras eile. Cuimhnigh le do thoil nach fรฉidir leat scรกthรกin nua a chruthรบ faoi lรกthair.
+settings.mirror_settings.docs.can_still_use = Cรฉ nach fรฉidir leat scรกthรกin atรก ann cheana a mhodhnรบ nรณ cinn nua a chruthรบ, fรฉadfaidh tรบ do scรกthรกn atรก ann cheana a รบsรกid fรณs.
+settings.mirror_settings.docs.pull_mirror_instructions = Chun scรกthรกn tarraingthe a shocrรบ, tรฉigh i gcomhairle le do thoil:
+settings.mirror_settings.docs.more_information_if_disabled = Is fรฉidir leat tuilleadh eolais a fhรกil faoi scรกthรกin bhrรบ agus tarraingthe anseo:
+settings.mirror_settings.docs.doc_link_title = Conas is fรฉidir liom na stรณrtha a scรกthรกnรบ?
+settings.mirror_settings.docs.doc_link_pull_section = an chuid "Ag tarraingt รณ stรณras" den doicimรฉadรบ.
+settings.mirror_settings.docs.pulling_remote_title = Ag tarraingt รณ stรณras cianda
+settings.mirror_settings.mirrored_repository = Stรณras scรกthรกin
+settings.mirror_settings.pushed_repository = Stรณras brรบite
+settings.mirror_settings.direction = Treo
+settings.mirror_settings.direction.pull = Tarraingt
+settings.mirror_settings.direction.push = Brรบigh
+settings.mirror_settings.last_update = Nuashonrรบ deireanach
+settings.mirror_settings.push_mirror.none = Nรญl aon scรกthรกin bhrรบ cumraithe
+settings.mirror_settings.push_mirror.remote_url = URL Stรณras Cianda Git
+settings.mirror_settings.push_mirror.add = Cuir Scรกthรกn Brรบigh leis
+settings.mirror_settings.push_mirror.edit_sync_time = Eagar eatramh sioncronaithe scรกthรกin
+settings.sync_mirror = Sioncronaigh Anois
+settings.pull_mirror_sync_in_progress = Athruithe a tharraingt รณn iargรบlta %s i lรกthair na huaire.
+settings.push_mirror_sync_in_progress = Athruithe a bhrรบ ar an iargรบlta %s i lรกthair na huaire.
+settings.site = Lรกithreรกn Grรฉasรกin
+settings.update_mirror_settings = Nuashonraigh Socruithe Scรกthรกin
+settings.branches.switch_default_branch = Athraigh Brainse Rรฉamhshocraithe
+settings.branches.update_default_branch = An Brainse Rรฉamhshocraithe a nuashonrรบ
+settings.branches.add_new_rule = Cuir Riail Nua leis
+settings.advanced_settings = Ardsocruithe
+settings.wiki_desc = Cumasaigh Stรณr Vicรญ
+settings.use_internal_wiki = รsรกid Vicรญ Insuite
+settings.use_external_wiki = รsรกid Vicรญ Seachtrach
+settings.external_wiki_url = URL Vicรญ Seachtrach
+settings.external_wiki_url_error = Nรญ URL bailรญ รฉ URL seachtrach vicรญ.
+settings.external_wiki_url_desc = Atreoraรญtear cuairteoirรญ chuig an URL wiki seachtrach agus iad ag cliceรกil ar an gcluaisรญn wiki.
+settings.issues_desc = Cumasaigh Rianรณir Saincheist Stรณrais
+settings.use_internal_issue_tracker = รsรกid Rianรณir Saincheist Ionsuite
+settings.use_external_issue_tracker = รsรกid Rianaire Eisiรบint Sheachtrach
+settings.external_tracker_url = URL Rianaithe Saincheisteanna Seachtrach
+settings.external_tracker_url_error = Nรญ URL bailรญ รฉ an URL rianaitheora saincheisteanna seachtrach.
+settings.external_tracker_url_desc = Dรฉantar cuairteoirรญ a atreorรบ chuig an URL rianaithe eisiรบintรญ seachtracha nuair a chliceรกlann siad ar an tรกb saincheisteanna.
+settings.tracker_url_format = Formรกid URL Rianaithe Saincheist Seachtrach
+settings.tracker_url_format_error = Nรญ URL bailรญ รฉ an fhormรกid URL rianaitheora saincheisteanna seachtrach.
+settings.tracker_issue_style = Formรกid Uimhir Rianaithe Saincheisteanna
+settings.tracker_issue_style.numeric = Uimhriรบil
+settings.tracker_issue_style.alphanumeric = Alfaumรฉireacha
+settings.tracker_issue_style.regexp = Lรฉiriรบ Rialta
+settings.tracker_issue_style.regexp_pattern = Patrรบn Lรฉirithe Rialta
+settings.tracker_issue_style.regexp_pattern_desc = รsรกidfear an chรฉad ghrรบpa a gabhadh in ionad {index}
.
+settings.tracker_url_format_desc = รsรกid na sealbhรณirรญ รกite {user}
, {repo}
agus {index}
le haghaidh an ainm รบsรกideora, an t-ainm stรณrtha agus an t-innรฉacs eisiรบna.
+settings.enable_timetracker = Cumasaigh Rianรบ Ama
+settings.allow_only_contributors_to_track_time = Lig do Rannphรกirtithe Amach Am a Rianรบ
+settings.pulls_desc = Cumasaigh Iarratais Tarraingthe Stรณras
+settings.pulls.ignore_whitespace = Dรฉan neamhaird de spรกs bรกn le haghaidh coinbhleachtaรญ
+settings.pulls.enable_autodetect_manual_merge = Cumasaigh cumasc lรกimhe autodetector (Nรณta: I roinnt cรกsanna speisialta, is fรฉidir mรญbhreithiรบnais tarlรบ)
+settings.pulls.allow_rebase_update = Cumasaigh brainse iarratais tarraingthe a nuashonrรบ trรญ athbhunรบ
+settings.pulls.default_delete_branch_after_merge = Scrios brainse an iarratais tarraingthe tar รฉis cumasc de rรฉir rรฉamhshocraithe
+settings.pulls.default_allow_edits_from_maintainers = Ceadaigh eagarthรณirรญ รณ chothabhรกlaรญ de rรฉir rรฉamhshocraithe
+settings.releases_desc = Cumasaigh Eisiรบintรญ Stรณrais
+settings.admin_settings = Socruithe Riarthรณra
+settings.admin_enable_health_check = Cumasaigh Seiceรกlacha Slรกinte Stรณrais (git fsck)
+settings.admin_code_indexer = Innรฉacsaitheoir Cรณd
+settings.admin_stats_indexer = Innรฉacsรณir Staitisticรญ Cรณd
+settings.admin_indexer_unindexed = Neamh-innรฉacsaithe
+settings.reindex_button = Cuir le Scuaine Reindex
+settings.reindex_requested = Athinnรฉacsรบ Iarrtha
+settings.admin_enable_close_issues_via_commit_in_any_branch = Saincheist a dhรบnadh trรญ ghealltanas a rinneadh i mbrainse neamh-mhainneachtana
+settings.danger_zone = Crios Contรบirte
+settings.new_owner_has_same_repo = Tรก stรณras leis an ainm cรฉanna ag an รบinรฉir nua cheana fรฉin. Roghnaigh ainm eile le do thoil.
+settings.convert = Tiontaigh go Stรณras Rialta
+settings.convert_desc = Is fรฉidir leat an scรกthรกn seo a thiontรบ ina stรณr rialta. Nรญ fรฉidir รฉ seo a chur ar ais.
+settings.convert_notices_1 = Dรฉanfaidh an oibrรญocht seo an scรกthรกn a thiontรบ ina stรณras rialta agus nรญ fรฉidir รฉ a chur ar ais.
+settings.convert_confirm = Tiontaigh Stรณras
+settings.convert_succeed = Tรก an scรกthรกn tiontaithe ina stรณras rialta.
+settings.convert_fork = Tiontaigh go Stรณras Rialta
+settings.convert_fork_desc = Is fรฉidir leat an forc seo a thiontรบ ina stรณras rialta. Nรญ fรฉidir รฉ seo a chur ar ais.
+settings.convert_fork_notices_1 = Dรฉanfaidh an oibrรญocht seo an forc a thiontรบ ina stรณras rialta agus nรญ fรฉidir รฉ a chur ar ais.
+settings.convert_fork_confirm = Tiontaigh Stรณras
+settings.convert_fork_succeed = Tรก an forc tiontaithe ina stรณras rialta.
+settings.transfer.rejected = Diรบltaรญodh d'aistriรบ stรณras.
+settings.transfer.success = D'รฉirigh le haistriรบ stรณras.
+settings.transfer_abort = Cealaigh aistriรบ
+settings.transfer_abort_invalid = Nรญ fรฉidir leat aistriรบ stรณras nach bhfuil ann a chealรบ.
+settings.transfer_abort_success = Cuireadh an t-aistriรบ stรณras chuig %s ar ceal go rathรบil.
+settings.transfer_desc = Aistrigh an stรณras seo chuig รบsรกideoir nรณ chuig eagraรญocht a bhfuil cearta riarthรณra agat ina leith.
+settings.transfer_in_progress = Tรก aistriรบ leanรบnach ann faoi lรกthair. Cealaigh รฉ mรกs mian leat an stรณras seo a aistriรบ chuig รบsรกideoir eile.
+settings.transfer_notices_1 = - Caillfidh tรบ rochtain ar an stรณras mรก aistrรญonn tรบ รฉ chuig รบsรกideoir aonair.
+settings.transfer_notices_2 = - Coimeรกdfaidh tรบ rochtain ar an stรณras mรก aistrรญonn tรบ รฉ chuig eagraรญocht a bhfuil (comh)รบinรฉir agat.
+settings.transfer_notices_3 = - Mรก tรก an stรณras prรญobhรกideach agus mรก aistrรญtear รฉ chuig รบsรกideoir aonair, cinnteoidh an gnรญomh seo go bhfuil ar a laghad cead lรฉite ag an รบsรกideoir (agus athraรญonn sรฉ ceadanna mรกs gรก).
+settings.transfer_owner = รinรฉir nua
+settings.transfer_perform = Dรฉan Aistriรบ
+settings.transfer_started = `Tรก an stรณras seo marcรกilte le haistriรบ agus tรก sรฉ ag fanacht le deimhniรบ รณ "%s"`
+settings.transfer_succeed = Tรก an stรณras aistrithe.
+settings.signing_settings = Socruithe Fรญoraithe Sรญnithe
+settings.trust_model = Samhail Iontaobhas Sรญnithe
+settings.trust_model.default = Mรบnla Iontaobhais Rรฉamhshocraithe
+settings.trust_model.default.desc = รsรกid an tsamhail iontaobhais stรณrais rรฉamhshocraithe don suiteรกil
+settings.trust_model.collaborator = Comhoibritheoir
+settings.trust_model.collaborator.long = Comhoibritheoir: Sรญnithe muinรญn ag comhoibrithe
+settings.trust_model.collaborator.desc = Dรฉanfar sรญnithe bailรญ รณ chomhoibritheoirรญ an stรณras seo a mharcรกil mar 'iontaofa' โ (cibรฉ acu a mheaitseรกlann siad an tiomnรณir nรณ nach bhfuil). Seachas sin, marcรกlfar sรญnithe bailรญ mar 'neamhiontaofa' mรก mheaitseรกlann an sรญniรบ an tiomnรณir agus mar 'neamh-mheaitseรกilte' mura bhfuil.
+settings.trust_model.committer = Coimisitheoir
+settings.trust_model.collaboratorcommitter = Comhoibritheo+Coimiteoir
+settings.trust_model.collaboratorcommitter.long = Comhoibrรญ+Coiste: sรญnithe muinรญne รณ chomhoibrithe a mheaitseรกlann an tiomnรณir
+settings.wiki_delete = Scrios Sonraรญ Vicรญ
+settings.wiki_delete_desc = Tรก sonraรญ wiki stรณras a scriosadh buan agus nรญ fรฉidir iad a chur ar ais.
+settings.wiki_delete_notices_1 = - Scriosfaidh agus dรญchumasรณidh sรฉ seo an stรณras vicรญ do %s go buan.
+settings.confirm_wiki_delete = Scrios Sonraรญ Vicรญ
+settings.wiki_deletion_success = Scriosadh sonraรญ vicรญ an stรณrais.
+settings.delete = Scrios an Stรณras seo
+settings.delete_desc = Tรก scriosadh stรณras buan agus nรญ fรฉidir รฉ a chealรบ.
+settings.delete_notices_1 = - Nร FรIDIR an oibrรญocht seo a chealรบ.
+settings.delete_notices_2 = - Scriosfaidh an oibrรญocht seo stรณr %s go buan lena n-รกirรญtear cรณd, ceisteanna, nรณtaรญ trรกchta, sonraรญ vicรญ agus socruithe comhoibrithe.
+settings.delete_notices_fork_1 = - Beidh forcanna den stรณras seo neamhspleรกch tar รฉis iad a scriosadh.
+settings.deletion_success = Tรก an stรณras scriosta.
+settings.update_settings_success = Nuashonraรญodh na socruithe stรณras.
+settings.update_settings_no_unit = Ba cheart go gceadรณdh an stรณras idirghnรญomhรบ de chineรกl รฉigin ar a laghad.
+settings.confirm_delete = Scrios Stรณras
+settings.add_collaborator = Cuir Comhoibritheoir leis
+settings.add_collaborator_success = Cuireadh an comhoibritheoir leis.
+settings.add_collaborator_inactive_user = Nรญ fรฉidir รบsรกideoir neamhghnรญomhach a chur mar chomhoibritheoir.
+settings.add_collaborator_owner = Nรญ fรฉidir รบinรฉir a chur leis mar chomhoibritheoir.
+settings.add_collaborator_duplicate = Tรก an comhoibrรญ curtha leis an stรณras seo cheana fรฉin.
+settings.delete_collaborator = Bain
+settings.collaborator_deletion = Bain Comhoibritheoir
+settings.collaborator_deletion_desc = Mรก dhรฉantar comhoibrรญ a bhaint, dรฉanfar a rochtain ar an stรณras seo a chรบlghairm. Lean ort?
+settings.remove_collaborator_success = Tรก an comhoibritheoir bainte.
+settings.org_not_allowed_to_be_collaborator = Nรญ fรฉidir eagraรญochtaรญ a chur leis mar chomhoibritheoir.
+settings.change_team_access_not_allowed = Tรก rochtain foirne a athrรบ don stรณras teoranta d'รบinรฉir eagraรญochta
+settings.team_not_in_organization = Nรญl an fhoireann san eagraรญocht chรฉanna leis an stรณras
+settings.teams = Foirne
+settings.add_team = Cuir Foireann leis
+settings.add_team_duplicate = Tรก an stรณras ag an bhfoireann cheana fรฉin
+settings.add_team_success = Tรก rochtain ag an bhfoireann anois ar an stรณras.
+settings.change_team_permission_tip = Tรก cead na foirne socraithe ar leathanach socraithe foirne agus nรญ fรฉidir รฉ a athrรบ in aghaidh an stรณras
+settings.delete_team_tip = Tรก rochtain ag an bhfoireann seo ar gach stรณrais agus nรญ fรฉidir รญ a bhaint
+settings.remove_team_success = Tรก rochtain na foirne ar an stรณras bainte amach.
+settings.add_webhook = Cuir Crรบca Grรฉasรกn leis
+settings.add_webhook.invalid_channel_name = Nรญ fรฉidir ainm cainรฉal Crรบca Grรฉasรกn a bheith folamh agus nรญ fรฉidir ach carachtar # a bheith ann.
+settings.webhook_deletion = Bain Crรบca Grรฉasรกn
+settings.webhook_deletion_desc = Scriostar a shocruithe agus a stair seachadta a bhaineann le Crรบca Grรฉasรกn a bhaint. Lean ar aghaidh?
+settings.webhook_deletion_success = Tรก an Crรบca Grรฉasรกn bainte amach.
+settings.webhook.test_delivery = Seachadadh Tรกstรกla
+settings.webhook.test_delivery_desc = Dรฉan tรกstรกil ar an Crรบca Grรฉasรกn seo le himeacht bhrรฉige.
+settings.webhook.test_delivery_desc_disabled = Chun an Crรบca Grรฉasรกn seo a thรกstรกil le himeacht bhrรฉige, gnรญomhachtaigh รฉ.
+settings.webhook.request = Iarratas
+settings.webhook.response = Freagra
+settings.webhook.headers = Ceanntรกsca
+settings.webhook.payload = รbhar
+settings.webhook.body = Comhlacht
+settings.webhook.replay.description = Seinn an Crรบca Grรฉasรกn seo arรญs.
+settings.webhook.replay.description_disabled = Chun an Crรบca Grรฉasรกn seo a athsheinm, gnรญomhachtaigh รฉ.
+settings.webhook.delivery.success = Cuireadh imeacht leis an scuaine seachadta. D'fhรฉadfadh sรฉ cรบpla soicind a thรณgรกil sula dtaispeรกntar sรฉ sa stair seachadta.
+settings.githook_edit_desc = Mura bhfuil an hook neamhghnรญomhach, cuirfear รกbhar samplach i lรกthair. Mรก fhรกgann tรบ รกbhar go luach folamh dรญchumasรณfar an crรบca seo.
+settings.githook_name = Ainm Crรบca
+settings.githook_content = รbhar Crรบca
+settings.update_githook = Nuashonraigh Crรบca
+settings.payload_url = URL spriocdhรญrithe
+settings.http_method = Modh HTTP
+settings.content_type = Cineรกl รbhar POST
+settings.secret = Rรบnda
+settings.slack_username = Ainm รบsรกideora
+settings.slack_icon_url = URL deilbhรญn
+settings.slack_color = Dath
+settings.discord_username = Ainm รบsรกideora
+settings.discord_icon_url = URL deilbhรญn
+settings.event_desc = Truicear Ar:
+settings.event_push_only = Imeachtaรญ Brรบigh
+settings.event_send_everything = Gach Imeacht
+settings.event_choose = Imeachtaรญ Saincheapthaโฆ
+settings.event_header_repository = Imeachtaรญ Stรณras
+settings.event_create = Cruthaigh
+settings.event_create_desc = Cruthaรญodh brainse nรณ clib.
+settings.event_delete = Scrios
+settings.event_delete_desc = Brainse nรณ clib scriosta.
+settings.event_fork = Forc
+settings.event_fork_desc = Forcadh stรณras.
+settings.event_wiki = Vicรญ
+settings.event_wiki_desc = Leathanach Vicรญ cruthaithe, athainmnithe, curtha in eagar nรณ scriosta.
+settings.event_release = Scaoileadh
+settings.event_release_desc = Scaoileadh foilsithe, nuashonraithe nรณ scriosta i stรณras.
+settings.event_push = Brรบigh
+settings.event_push_desc = Brรบigh Git chuig stรณras.
+settings.event_repository = Stรณras
+settings.event_repository_desc = Stรณras a cruthaรญodh nรณ a scriosadh.
+settings.event_header_issue = Imeachtaรญ Eisiรบint
+settings.event_issues_desc = Osclaรญodh, dรบnadh, athosclaรญodh nรณ cuireadh an cheist in eagar.
+settings.event_issue_assign_desc = Eisiรบint sannta nรณ neamhshannta.
+settings.event_issue_comment_desc = Trรกcht eisiรบna cruthaithe, curtha in eagar nรณ a scriosadh.
+settings.event_header_pull_request = Tarraingt Imeachtaรญ Iarratas
+settings.event_pull_request_desc = Iarratas tarraingthe oscailte, dรบnta, athoscailte nรณ curtha in eagar.
+settings.event_pull_request_assign_desc = Iarratas tarraingthe sannta nรณ neamhshannta.
+settings.event_pull_request_comment_desc = Trรกcht ar iarratas tarraingthe cruthaithe, curtha in eagar, nรณ scriosta.
+settings.event_pull_request_review_request_desc = Tarraing athbhreithniรบ iarratais iarrtha nรณ baineadh iarratas athbhreithnithe.
+settings.event_pull_request_approvals = Ceaduithe Iarratais Tarraing
+settings.event_pull_request_merge = Cumaisc Iarratas Tarraing
+settings.event_package = Pacรกiste
+settings.event_package_desc = Pacรกiste a cruthaรญodh nรณ a scriosadh i stรณras.
+settings.branch_filter = Scagaire brainse
+settings.branch_filter_desc = Liosta bรกn brainse le haghaidh brรบ, cruthรบ brainse agus imeachtaรญ scriosta brainse, sonraithe mar phatrรบn glob. Mรก tรก sรฉ folamh nรณ *
, tuairiscรญtear imeachtaรญ do gach brainse. Fรฉach %[2]s doicimรฉadรบ le haghaidh comhrรฉire. Samplaรญ: mรกistir
, {master,release*}
.
+settings.authorization_header = Ceanntรกsc รdaraithe
+settings.authorization_header_desc = Cuirfear san รกireamh mar cheanntรกsc รบdaraithe d'iarratais nuair a bheidh ann Samplaรญ: %s.
+settings.active = Gnรญomhach
+settings.active_helper = Seolfar faisnรฉis faoi imeachtaรญ spreagtha chuig an URL Crรบca Grรฉasรกn seo.
+settings.add_hook_success = Cuireadh an Crรบca Grรฉasรกn leis.
+settings.update_webhook = Nuashonraigh Crรบca Grรฉasรกn
+settings.update_hook_success = Nuashonraรญodh an Crรบca Grรฉasรกn.
+settings.delete_webhook = Bain Crรบca Grรฉasรกn
+settings.recent_deliveries = Seachadtaรญ le dรฉana
+settings.hook_type = Cineรกl Crรบca
+settings.slack_token = Comhartha
+settings.slack_domain = Fearann
+settings.slack_channel = Cainรฉal
+settings.add_web_hook_desc = Comhthรกthaigh %s isteach i do stรณras.
+settings.web_hook_name_gitea = Gitea
+settings.web_hook_name_gogs = Gogs
+settings.web_hook_name_slack = Slack
+settings.web_hook_name_discord = Discord
+settings.web_hook_name_dingtalk = DingTalk
+settings.web_hook_name_telegram = Teileagram
+settings.web_hook_name_matrix = Maitrรญs
+settings.web_hook_name_msteams = Microsoft Teams
+settings.web_hook_name_wechatwork = WeCom (Wechat Work)
+settings.web_hook_name_packagist = Packagist
+settings.packagist_username = Ainm รบsรกideora Pacagist
+settings.packagist_api_token = Comhartha API
+settings.packagist_package_url = URL pacรกiste Packagist
+settings.deploy_keys = Eochracha a imscaradh
+settings.add_deploy_key = Cuir Eochair Imscartha leis
+settings.deploy_key_desc = Tรก rochtain tarraingthe lรฉite amhรกin ag eochracha imscartha ar an stรณras.
+settings.is_writable = Cumasaigh Rochtain Scrรญobh
+settings.is_writable_info = Lig don eochair imlonnaithe seo a bhrรบ chuig an stรณras.
+settings.no_deploy_keys = Nรญl aon eochracha imscartha ann fรณs.
+settings.title = Teideal
+settings.deploy_key_content = รbhar
+settings.key_been_used = Tรก eochair imscartha le hรกbhar comhionann in รบsรกid cheana fรฉin.
+settings.key_name_used = Tรก eochair imscartha leis an ainm cรฉanna ann cheana fรฉin.
+settings.add_key_success = Tรก an eochair imlonnaithe "%s" curtha leis.
+settings.deploy_key_deletion = Bain Eochair Imlonnaithe
+settings.deploy_key_deletion_desc = Ag baint eochair imscartha, cuirfear a rochtain ar an stรณras seo a chรบlghairm. Lean ar aghaidh?
+settings.deploy_key_deletion_success = Tรก an eochair imscartha bainte amach.
+settings.branches = Brainsรญ
+settings.protected_branch = Cosaint Brainse
+settings.protected_branch.save_rule = Sรกbhรกil Riail
+settings.protected_branch.delete_rule = Scrios Riail
+settings.protect_disable_push = Dรญchumasaigh Brรบigh
+settings.protect_disable_push_desc = Nรญ cheadfar aon bhrรบ chuig an mbrainse seo.
+settings.protect_enable_push = Cumasaigh Brรบigh
+settings.protect_enable_push_desc = Beidh cead ag aon duine a bhfuil rochtain scrรญofa aige/aici brรบ chuig an mbrainse seo (ach gan brรบ a bhrรบ).
+settings.protect_enable_merge = Cumasaigh Cumaisc
+settings.protect_enable_merge_desc = Beidh cead ag aon duine a bhfuil rochtain scrรญofa aige na hiarratais tarraingte a chumasc leis an mbrainse seo.
+settings.protect_check_status_contexts = Cumasaigh Seiceรกil Stรกdas
+settings.protect_status_check_patterns_desc = Iontrรกil patrรบin chun a shonrรบ cรฉ na seiceรกlacha stรกdais a chaithfidh pas a fhรกil sular fรฉidir brainsรญ a chumasc le brainse a chomhoibrรญonn leis an riail seo. Sonraรญonn gach lรญne patrรบn. Nรญ fรฉidir patrรบin a bheith folamh.
+settings.protect_check_status_contexts_desc = A cheangal ar sheiceรกlacha stรกdais pas a fhรกil roimh chumasc. Nuair a bheidh sรฉ cumasaithe, nรญ mรณr gealltanais a bhrรบ ar dtรบs chuig brainse eile, ansin iad a chumasc nรณ a bhrรบ go dรญreach chuig brainse a thagann leis an riail seo tar รฉis do sheiceรกlacha stรกdais a bheith caite. Mura ndรฉantar comhthรฉacs ar bith a mheaitseรกil, nรญ mรณr go n-รฉireodh leis an ngealltanas deiridh beag beann ar an gcomhthรฉacs.
+settings.protect_check_status_contexts_list = Seiceรกlacha stรกdais a fuarthas sa tseachtain seo caite don stรณras seo
+settings.protect_status_check_matched = Comhoiriรบnach
+settings.protect_invalid_status_check_pattern = Patrรบn seiceรกla stรกdais neamhbhailรญ: "%s".
+settings.protect_no_valid_status_check_patterns = Gan aon phatrรบin seiceรกla stรกdais bailรญ.
+settings.dismiss_stale_approvals = Dรฉan seancheaduithe a dhรญbhe
+settings.dismiss_stale_approvals_desc = Nuair a bhrรบitear gealltanais nua a athraรญonn รกbhar an iarratais tarraingthe chuig an mbrainse, dรฉanfar sean-cheaduithe a dhรญchur.
+settings.ignore_stale_approvals = Dรฉan neamhaird de sheancheaduithe
+settings.ignore_stale_approvals_desc = Nรก cuir faomhadh a rinneadh ar ghealltanais nรญos sine (athbhreithnithe seanchaite) san รกireamh i dtreo cรฉ mhรฉad faomhadh atรก ag an PR. Nรญ bhaineann le hรกbhar mรก dhรฉantar athbhreithnithe seanchaite a dhรญbhe cheana fรฉin.
+settings.require_signed_commits = Ceangaltais Sรญnithe a cheangal
+settings.require_signed_commits_desc = Diรบltaigh brรบ chuig an mbrainse seo mรก tรก siad neamhshรญnithe nรณ neamh-fhรญoraithe.
+settings.protect_branch_name_pattern = Patrรบn Ainm Brainse Cosanta
+settings.protect_patterns = Patrรบin
+settings.update_protect_branch_success = Tรก cosaint brainse don riail "%s" nuashonraithe.
+settings.remove_protected_branch_success = Baineadh cosaint brainse don riail "%s".
+settings.remove_protected_branch_failed = Theip ar riail cosanta brainse "%s" a bhaint.
+settings.protected_branch_deletion = Scrios Cosaint Brainse
+settings.protected_branch_deletion_desc = Ligeann cosaint brainse a dhรญchumasรบ d'รบsรกideoirรญ a bhfuil cead scrรญofa acu brรบ chuig an mbrainse. Lean ar aghaidh?
+settings.block_rejected_reviews = Cuir bac ar chumasc ar lรฉirmheasanna diรบltaithe
+settings.block_rejected_reviews_desc = Nรญ bheidh cumasc indรฉanta nuair a iarrann athbhreithnithe oifigiรบla athruithe, fiรบ mรก tรก go leor ceadaithe ann.
+settings.block_on_official_review_requests = Cuir bac ar chumasc ar iarratais ar athbhreithniรบ oifigiรบil
+settings.block_on_official_review_requests_desc = Nรญ bheidh sรฉ indรฉanta cumasc nuair a bhรญonn iarratais oifigiรบla ar athbhreithniรบ aige, fiรบ mรก tรก go leor ceadaithe ann.
+settings.block_outdated_branch = Cuir bac ar chumasc mรก tรก an t-iarratas tarraingthe as dรกta
+settings.block_outdated_branch_desc = Nรญ bheidh cumasc indรฉanta nuair a bhรญonn ceannbhrainse taobh thiar de bhronnbhrainse.
+settings.default_branch_desc = Roghnaigh brainse stรณras rรฉamhshocraithe le haghaidh iarratas tarraingte agus geallann an cรณd:
+settings.merge_style_desc = Stรญleanna Cumaisc
+settings.default_merge_style_desc = Stรญl Cumaisc Rรฉamhshocraithe
+settings.choose_branch = Roghnaigh brainseโฆ
+settings.no_protected_branch = Nรญl aon bhrainsรญ cosanta ann.
+settings.edit_protected_branch = Cuir in eagar
+settings.protected_branch_required_rule_name = Ainm riail riachtanach
+settings.protected_branch_required_approvals_min = Nรญ fรฉidir ceaduithe riachtanacha a bheith diรบltach.
+settings.tags = Clibeanna
+settings.tags.protection = Cosaint Clib
+settings.tags.protection.pattern = Patrรบn Clib
+settings.tags.protection.allowed = Ceadaithe
+settings.tags.protection.allowed.users = รsรกideoirรญ ceadaithe
+settings.tags.protection.allowed.teams = Foirne ceadaithe
+settings.tags.protection.allowed.noone = Nรญl aon duine
+settings.tags.protection.none = Nรญl aon chlibeanna cosanta ann.
+settings.tags.protection.pattern.description = Is fรฉidir leat ainm amhรกin nรณ patrรบn glob nรณ slonn rialta a รบsรกid chun clibeanna iolracha a mheaitseรกil. Lรฉigh tuilleadh sa treoir na gclibeanna cosanta .
+settings.bot_token = Comhartha Bota
+settings.chat_id = ID Comhrรก
+settings.thread_id = ID Snรกithe
+settings.matrix.homeserver_url = URL sheirbhรญse baile
+settings.matrix.room_id = ID seomra
+settings.matrix.message_type = Cineรกl teachtaireachta
+settings.archive.button = Cartlann Stรณras
+settings.archive.header = Cartlann an Stรณras seo
+settings.archive.text = Mรก dhรฉantar an stรณras a chartlannรบ, beidh sรฉ lรฉite go hiomlรกn amhรกin. Beidh sรฉ i bhfolach รณn bpainรฉal. Aon duine (nรญ fiรบ tรบ!) beidh siad in ann tiomantas nua a dhรฉanamh, nรณ aon saincheisteanna nรณ iarratais a tharraingt a oscailt.
+settings.archive.success = Rinneadh an stรณras a chartlannรบ go rathรบil.
+settings.archive.error = Tharla earrรกid agus tรบ ag iarraidh an stรณras a chartlannรบ. Fรฉach an logรกil le haghaidh tuilleadh sonraรญ.
+settings.archive.error_ismirror = Nรญ fรฉidir leat stรณras scรกthรกin a chartlannรบ.
+settings.unarchive.button = Stรณras gan cartlann
+settings.unarchive.header = Dรญchartlannaigh an stรณras seo
+settings.unarchive.success = Rinneadh an stรณras a dhรญchartlann go rathรบil.
+settings.unarchive.error = Tharla earrรกid agus tรบ ag iarraidh an stรณras a dhรญchartlannรบ. Fรฉach an logรกil le haghaidh tuilleadh sonraรญ.
+settings.update_avatar_success = Nuashonraรญodh avatar an stรณras.
+settings.lfs = LFS
+settings.lfs_filelist = Comhaid LFS a stรณrรกiltear sa stรณras seo
+settings.lfs_no_lfs_files = Nรญl aon chomhaid LFS stรณrรกilte sa stรณras seo
+settings.lfs_findcommits = Aimsigh gealltanais
+settings.lfs_lfs_file_no_commits = Nรญor aimsรญodh aon ghealltanais don chomhad LFS seo
+settings.lfs_noattribute = Nรญl an trรฉith inghlasรกilte sa bhrainse rรฉamhshocraithe ag an gcosรกn seo
+settings.lfs_delete = Scrios comhad LFS le OID %s
+settings.lfs_findpointerfiles = Faigh comhaid pointeora
+settings.lfs_locks = Glais
+settings.lfs_invalid_locking_path = Cosan neamhbhailรญ: %s
+settings.lfs_invalid_lock_directory = Nรญ fรฉidir eolaire a ghlasรกil: %s
+settings.lfs_lock_already_exists = Tรก an glas ann cheana fรฉin: %s
+settings.lfs_lock = Glas
+settings.lfs_lock_path = Cosรกn comhad le haghaidh glasรกil...
+settings.lfs_locks_no_locks = Gan Glais
+settings.lfs_lock_file_no_exist = Nรญl an comhad faoi ghlas sa bhrainse rรฉamhshocraithe
+settings.lfs_force_unlock = Dรญghlasรกil Fรณrsa
+settings.lfs_pointers.found = Aimsรญodh %d pointeoir(รญ) blob - %d bainteach, %d neamhghaolmhar (%d in easnamh รณn siopa)
+settings.lfs_pointers.oid = OID
+settings.lfs_pointers.inRepo = I Stรณras
+settings.lfs_pointers.exists = Ann sa siopa
+settings.lfs_pointers.accessible = Inrochtana don รsรกideoir
+settings.lfs_pointers.associateAccessible = Comhlach %d OID inrochtana
+settings.rename_branch_failed_exist = Nรญ fรฉidir brainse a athainmniรบ toisc go bhfuil spriocbhrainse %s ann.
+settings.rename_branch_failed_not_exist = Nรญ fรฉidir brainse %s a athainmniรบ toisc nach bhfuil sรฉ ann.
+settings.rename_branch_success = Ainmnรญodh brainse %s go rathรบil go %s.
+settings.rename_branch = Athainmnigh brainse
+diff.browse_source = Brabhsรกil Foinse
+diff.parent = tuismitheoir
+diff.commit = tiomantas
+diff.git-notes = Nรณtaรญ
+diff.options_button = Roghanna Diff
+diff.download_patch = รoslรณdรกil an comhad paiste
+diff.download_diff = รoslรณdรกil Comhad Diff
+diff.show_split_view = Amharc Scoilt
+diff.show_unified_view = Amharc Aontaithe
+diff.whitespace_button = Spรกs bรกn
+diff.whitespace_show_everything = Taispeรกin gach athrรบ
+diff.whitespace_ignore_all_whitespace = Dรฉan neamhaird de spรกs bรกn nuair a dhรฉantar comparรกid idir lรญnte
+diff.whitespace_ignore_amount_changes = Dรฉan neamhaird de athruithe ar an mรฉid spรกs bรกn
+diff.whitespace_ignore_at_eol = Dรฉan neamhaird ar athruithe ar spรกs bรกn ag EOL
+diff.stats_desc = D'athraigh %d comhad le %d breiseanna agus %d scriosta
+diff.stats_desc_file = %d athruithe: %d breiseanna agus scriosadh %d
+diff.bin = BRUSCAIR
+diff.bin_not_shown = Nรญ thaispeรกntar comhad dรฉnรกrtha.
+diff.view_file = Fรฉach ar an gComhad
+diff.file_before = Roimhe
+diff.file_after = Tar รฉis
+diff.file_image_width = Leithead
+diff.file_image_height = Airde
+diff.file_byte_size = Mรฉid
+diff.file_suppressed = Tรก difrรญocht comhad cosc orthu toisc go bhfuil sรฉ rรณ-mhรณr
+diff.file_suppressed_line_too_long = Cuirtear difrรญocht comhad faoi chois toisc go bhfuil lรญne amhรกin nรณ nรญos mรณ rรณfhada
+diff.too_many_files = Nรญor taispeรกnadh roinnt comhad mar go bhfuil an iomarca comhad athraithe sa difrรญocht seo
+diff.show_more = Taispeรกin Tuilleadh
+diff.load = Difrรญocht Luchtaigh
+diff.generated = a ghintear
+diff.vendored = curtha ar fรกil
+diff.comment.add_line_comment = Cuir trรกcht lรญne leis
+diff.comment.placeholder = Fรกg trรกcht
+diff.comment.add_single_comment = Cuir trรกcht aonair leis
+diff.comment.add_review_comment = Cuir trรกcht leis
+diff.comment.start_review = Tosaigh athbhreithniรบ
+diff.comment.reply = Freagra
+diff.review.header = Cuir isteach lรฉirmheas
+diff.review.placeholder = Trรกcht athbhreithnithe
+diff.review.comment = Trรกcht
+diff.review.approve = Ceadรบ
+diff.review.self_reject = Nรญ fรฉidir le hรบdair iarratais tarraing athruithe a iarraidh ar a n-iarratas tarraingthe
+diff.review.reject = Iarr athruithe
+diff.review.self_approve = Nรญ fรฉidir le hรบdair iarratais tarraing a n-iarratas tarraingthe fรฉin a chead
+diff.committed_by = tiomanta ag
+diff.protected = Cosanta
+diff.image.side_by_side = Taobh le Taobh
+diff.image.swipe = Scaoil
+diff.image.overlay = Forleagan
+diff.has_escaped = Tรก carachtair Unicode i bhfolach ag an lรญne seo
+diff.show_file_tree = Taispeรกin crann comhad
+diff.hide_file_tree = Folaigh crann comhad
+releases.desc = Rian leaganacha tionscadal agus รญoslรณdรกlacha.
+release.releases = Eisiรบintรญ
+release.detail = Sonraรญ eisithe
+release.tags = Clibeanna
+release.new_release = Scaoileadh Nua
+release.draft = Drรฉacht
+release.prerelease = Rรฉamh-eisiรบint
+release.stable = Cobhsaรญ
+release.compare = Dรฉan comparรกid
+release.edit = cuir in eagar
+release.ahead.commits = Geallann %d
+release.ahead.target = go %s รณn scaoileadh seo
+tag.ahead.target = chuig %s รณn gclib seo
+release.source_code = Cรณd Foinse
+release.new_subheader = Eagraรญonn eiseachtaรญ leaganacha tionscadail
+release.edit_subheader = Eagraรญonn eisiรบintรญ leaganacha tionscadal.
+release.tag_name = Ainm chlib
+release.target = Sprioc
+release.tag_helper = Roghnaigh clib atรก ann cheana nรณ cruthaigh clib nua.
+release.tag_helper_new = Clib nua. Cruthรณfar an chlib seo รณn sprioc.
+release.tag_helper_existing = Clib atรก ann cheana.
+release.title = Teideal scaoileadh
+release.title_empty = Nรญ fรฉidir leis an teideal a bheith folamh.
+release.message = Dรฉan cur sรญos ar an eisiรบint seo
+release.prerelease_desc = Marcรกil mar Rรฉamh-eisiรบint
+release.prerelease_helper = Marcรกil an scaoileadh seo mรญ-oiriรบnach le hรบsรกid tรกirgeachta.
+release.cancel = Cealaigh
+release.publish = Foilsigh Eisiรบint
+release.save_draft = Sรกbhรกil Drรฉacht
+release.edit_release = Eisiรบint Nuashonraithe
+release.delete_release = Scrios Scaoilte
+release.delete_tag = Scrios Clib
+release.deletion = Scrios Scaoilte
+release.deletion_success = Tรก an scaoileadh scriosta.
+release.deletion_tag_desc = Scriosfar an chlib seo รณn stรณras. Nรญ athraรญtear inneachar agus stair na stรณrtha. Lean ort?
+release.deletion_tag_success = Tรก an chlib scriosta.
+release.tag_name_already_exist = Tรก eisiรบint leis an ainm clib seo ann cheana fรฉin.
+release.tag_name_invalid = Nรญl ainm an chlib bailรญ.
+release.tag_name_protected = Tรก ainm an chlib cosanta.
+release.tag_already_exist = Tรก an t-ainm clib seo ann cheana fรฉin.
+release.downloads = รoslรณdรกlacha
+release.add_tag_msg = รsรกid teideal agus รกbhar an eisiรบna mar theachtaireacht chlibe.
+release.releases_for = Eisiรบintรญ do %s
+release.tags_for = Clibeanna do %s
+branch.name = Ainm Brainse
+branch.already_exists = Tรก brainse leis an ainm "%s" ann cheana fรฉin.
+branch.delete_head = Scrios
+branch.delete = `Scrios Brainse "%s"`
+branch.delete_html = Scrios Brainse
+branch.delete_desc = Tรก brainse a scriosadh buan. Cรฉ go bhfรฉadfadh an brainse scriosta leanรบint ar aghaidh ag bheith ann ar feadh trรฉimhse ghearr sula mbaintear รญ i ndรกirรญre, Nร FรIDIR รฉ a dhรญchur i bhformhรณr Lean ar aghaidh?
+branch.deletion_success = Tรก brainse "%s" scriosta.
+branch.deletion_failed = Theip ar scriosadh brainse "%s".
+branch.delete_branch_has_new_commits = Nรญ fรฉidir brainse โ%sโ a scriosadh toisc go bhfuil tiomรกintรญ nua curtha leis tar รฉis a chumasc.
+branch.create_branch = Cruthaigh brainse %s
+branch.create_from = `รณ "%s"`
+branch.create_success = Tรก brainse "%s" cruthaithe.
+branch.branch_already_exists = Tรก brainse "%s" sa stรณras seo cheana.
+branch.branch_name_conflict = Tagann an t-ainm brainse "%s" leis an mbrainse "%s" atรก ann cheana fรฉin.
+branch.tag_collision = Nรญ fรฉidir brainse "%s" a chruthรบ mar tรก clib leis an ainm cรฉanna sa stรณras cheana fรฉin.
+branch.deleted_by = Scriosta ag %s
+branch.restore_success = Tรก brainse "%s" curtha ar ais.
+branch.restore_failed = Theip ar chur ar ais brainse "%s".
+branch.protected_deletion_failed = Tรก brainse "%s" cosanta. Nรญ fรฉidir รฉ a scriosadh.
+branch.default_deletion_failed = Is รฉ brainse "%s" an brainse rรฉamhshocraithe. Nรญ fรฉidir รฉ a scriosadh.
+branch.restore = `Athchรณirigh Brainse "%s"`
+branch.download = `Brainse รosluchtaithe "%s"`
+branch.rename = `Athainmnigh Brainse "%s"`
+branch.included_desc = Tรก an brainse seo mar chuid den bhrainse rรฉamhshocraithe
+branch.included = San รกireamh
+branch.create_new_branch = Cruthaigh brainse รณn mbrainse:
+branch.confirm_create_branch = Cruthaigh brainse
+branch.warning_rename_default_branch = Tรก tรบ ag athainmniรบ an bhrainse rรฉamhshocraithe.
+branch.rename_branch_to = Athainmnigh "%s" go:
+branch.create_branch_operation = Cruthaigh brainse
+branch.new_branch = Cruthaigh brainse nua
+branch.new_branch_from = `Cruthaigh brainse nua รณ "%s"`
+branch.renamed = Ainmnรญodh brainse %s go %s.
+tag.create_tag = Cruthaigh clib %s
+tag.create_tag_operation = Cruthaigh clib
+tag.confirm_create_tag = Cruthaigh clib
+tag.create_tag_from = `Cruthaigh clib nua รณ "%s"`
+tag.create_success = Tรก clib "%s" cruthaithe.
+topic.manage_topics = Bainistigh topaicรญ
+topic.done = Dรฉanta
+topic.count_prompt = Nรญ fรฉidir leat nรญos mรณ nรก 25 topaicรญ a roghnรบ
+find_file.no_matching = Nรญl aon chomhad meaitseรกla le fรกil
+error.csv.too_large = Nรญ fรฉidir an comhad seo a rinneadh toisc go bhfuil sรฉ rรณ-mhรณr.
+error.csv.unexpected = Nรญ fรฉidir an comhad seo a rindreรกil toisc go bhfuil carachtar ann gan sรบil leis i lรญne %d agus i gcolรบn %d.
+error.csv.invalid_field_count = Nรญ fรฉidir an comhad seo a rindreรกil toisc go bhfuil lรญon mรญcheart rรฉimsรญ i lรญne %d.
+error.broken_git_hook = Is cosรบil go bhfuil crรบcaรญ git den stรณr seo briste. Lean an doicimรฉadรบchรกn chun iad a cheartรบ, ansin brรบigh roinnt gealltanas chun an stรกdas a athnuachan.
+
+[graphs]
+component_loading = ร lรณdรกil %s...
+component_loading_failed = Nรญ fhรฉadfaรญ %s a luchtรบ
+component_loading_info = Seans go dtรณgfaidh sรฉ seo beagรกnโฆ
+component_failed_to_load = Tharla earrรกid gan choinne.
+code_frequency.what = minicรญocht cรณd
+contributors.what = rannรญocaรญochtaรญ
+recent_commits.what = tiomantรกin le dรฉanaรญ
+
+[org]
+org_name_holder = Ainm na hEagraรญochta
+org_full_name_holder = Ainm iomlรกn na hEagraรญochta
+org_name_helper = Ba cheart go mbeadh ainmneacha eagraรญochta gearr agus i gcuimhne.
+create_org = Cruthaigh Eagraรญocht
+members = Comhaltaรญ
+teams = Foirne
+code = Cรณd
+lower_members = comhaltaรญ
+lower_repositories = stรณrais
+create_new_team = Foireann Nua
+create_team = Cruthaigh Foireann
+org_desc = Cur sรญos
+team_name = Ainm Foirne
+team_desc = Cur sรญos
+team_name_helper = Ba chรณir go mbeadh ainmneacha foirne gearr agus i gcuimhne.
+team_desc_helper = Dรฉan cur sรญos ar chuspรณir nรณ rรณl na foirne.
+team_access_desc = Rochtain stรณrais
+team_permission_desc = Cead
+team_unit_desc = Ceadaigh Rochtain ar Rannรณga Stรณras
+team_unit_disabled = (Dรญchumasaithe)
+form.name_reserved = Tรก an t-ainm eagraรญochta "%s" curtha in รกirithe.
+form.name_pattern_not_allowed = Nรญ cheadaรญtear an patrรบn "%s" in ainm eagraรญochta.
+form.create_org_not_allowed = Nรญl cead agat eagraรญocht a chruthรบ.
+settings = Socruithe
+settings.options = Eagraรญocht
+settings.full_name = Ainm Iomlรกn
+settings.email = Rรญomhphost Teagmhรกla
+settings.website = Lรกithreรกn Grรฉasรกin
+settings.location = Suรญomh
+settings.permission = Ceadanna
+settings.repoadminchangeteam = Is fรฉidir le riarthรณir an stรณrais rochtain d'fhoirne a chur leis agus a bhaint
+settings.visibility = Infheictheacht
+settings.visibility.public = Poiblรญ
+settings.visibility.limited_shortname = Teoranta
+settings.visibility.private = Prรญobhรกideach (Infheicthe amhรกin do bhaill eagraรญochta)
+settings.visibility.private_shortname = Prรญobhรกideach
+settings.update_settings = Nuashonrรบ Socruithe
+settings.update_setting_success = Nuashonraรญodh socruithe eagraรญochta.
+settings.change_orgname_prompt = Nรณta: Athrรณidh ainm na heagraรญochta ag athrรบ URL d'eagraรญochta agus saorfar an sean-ainm.
+settings.change_orgname_redirect_prompt = Dรฉanfaidh an sean-ainm a atreorรบ go dtรญ go n-รฉilรญtear รฉ.
+settings.update_avatar_success = Nuashonraรญodh avatar na heagraรญochta.
+settings.delete = Scrios Eagraรญocht
+settings.delete_account = Scrios an Eagraรญocht seo
+settings.delete_prompt = Bainfear an eagraรญocht go buan. Nร FรIDIR รฉ seo a chealรบ!
+settings.confirm_delete_account = Deimhnigh scriosadh
+settings.delete_org_title = Scrios Eagraรญocht
+settings.delete_org_desc = Scriosfar an eagraรญocht seo go buan. Lean ar aghaidh?
+settings.hooks_desc = Cuir crรบcaรญ grรฉasรกn in leis a spreagfar do gach stรณras faoin eagraรญocht seo.
+settings.labels_desc = Cuir lipรฉid leis ar fรฉidir iad a รบsรกid ar shaincheisteanna do gach stรณras faoin eagraรญocht seo.
+members.membership_visibility = Infheictheacht Ballraรญochta:
+members.public = Infheicthe
+members.public_helper = dhรฉanamh i bhfolach
+members.private = I bhfolach
+members.private_helper = a dhรฉanamh le feiceรกil
+members.member_role = Rรณl Comhalta:
+members.owner = รinรฉir
+members.member = Comhalta
+members.remove = Bain
+members.remove.detail = Bain %[1]s de %[2]s?
+members.leave = Fรกgรกil
+members.invite_desc = Cuir ball nua le %s:
+members.invite_now = Tabhair cuireadh Anois
+teams.join = Bรญgรญ
+teams.leave = Fรกg
+teams.can_create_org_repo = Cruthaigh stรณrais
+teams.can_create_org_repo_helper = Is fรฉidir le baill stรณras nua a chruthรบ san eagraรญocht. Gheobhaidh an cruthaitheoir rochtain riarthรณra ar an stรณras nua.
+teams.none_access = Gan Rochtain
+teams.general_access_helper = Dรฉanfar ceadanna baill a chinneadh ag an tรกbla ceadanna thรญos.
+teams.read_access = Lรฉigh
+teams.write_access = Scrรญobh
+teams.admin_access = Rochtain Riarthรณra
+teams.admin_access_helper = Is fรฉidir le baill tarraingt agus brรบ chuig stรณrais foirne agus comhoibritheoirรญ a chur leo.
+teams.no_desc = Nรญl aon tuairisc ag an bhfoireann seo
+teams.settings = Socruithe
+teams.owners_permission_desc = Tรก rochtain iomlรกn ag รบinรฉirรญ ar gach stรณrais agus tรก rochtain ag an riarthรณir ar an eagraรญocht.
+teams.members = Baill Foirne
+teams.update_settings = Nuashonrรบ Socruithe
+teams.delete_team = Scrios Foireann
+teams.add_team_member = Cuir Comhalta Foirne leis
+teams.invite_team_member = Tabhair cuireadh chuig %s
+teams.invite_team_member.list = Cuirรญ ar Feitheamh
+teams.delete_team_title = Scrios Foireann
+teams.delete_team_desc = Cรบlghairtear rochtain stรณrais รณna baill a scriosadh foirne. Lean ar aghaidh?
+teams.delete_team_success = Tรก an fhoireann scriosta.
+teams.read_permission_desc = Deonaรญonn an fhoireann seo rochtain Lรฉamh : is fรฉidir le baill stรณrtha foirne a fheiceรกil agus a chlรณnรกil.
+teams.write_permission_desc = Tugann an fhoireann seo rochtain do Scrรญobh : is fรฉidir le baill lรฉamh รณ stรณrtha foirne agus iad a bhrรบ chucu.
+teams.create_repo_permission_desc = Ina theannta sin, tugann an fhoireann seo cead Cruthaigh Stรณras : is fรฉidir le baill stรณrtha nua a chruthรบ san eagraรญocht.
+teams.repositories = Stรณrais Foirne
+teams.remove_all_repos_title = Bain gach stรณrais foirne
+teams.remove_all_repos_desc = Bainfidh sรฉ seo gach stรณrais รณn bhfoireann.
+teams.add_all_repos_title = Cuir gach stรณrais leis
+teams.add_all_repos_desc = Cuirfidh sรฉ seo stรณrais uile na heagraรญochta leis an bhfoireann.
+teams.add_duplicate_users = Is ball foirne รฉ an รบsรกideoir cheana fรฉin.
+teams.repos.none = Nรญ raibh rochtain ag an bhfoireann seo ar aon stรณras.
+teams.members.none = Nรญl aon bhaill ar an bhfoireann seo.
+teams.specific_repositories = Stรณrais Sonrach
+teams.specific_repositories_helper = Nรญ bheidh rochtain ag comhaltaรญ ach ar stรณrtha a cuireadh leis an bhfoireann go sainrรกite. Nรญ bhainfear na stรณrtha a cuireadh leis cheana le Gach stรณras go huathoibrรญoch trรญ รฉ seo a roghnรบ.
+teams.all_repositories = Gach stรณrais
+teams.all_repositories_helper = Tรก rochtain ag an bhfoireann ar gach stรณrais. Mรก roghnaรญonn sรฉ seo, cuirfear na stรณrais go lรฉir atรก ann cheana leis an bhfoireann.
+teams.invite.title = Tugadh cuireadh duit dul isteach i bhfoireann %s san eagraรญocht %s .
+teams.invite.by = Ar cuireadh รณ %s
+teams.invite.description = Cliceรกil ar an gcnaipe thรญos le do thoil chun dul isteach san fhoireann.
+
+[admin]
+dashboard = Deais
+self_check = Fรฉin-sheiceรกil
+identity_access = Fรฉiniรบlacht & Rochtain
+users = Cuntais รsรกideora
+organizations = Eagraรญochtaรญ
+assets = Sรณcmhainnรญ Cรณd
+repositories = Stรณrais
+hooks = Crรบcaรญ Grรฉasรกn
+integrations = Comhthรกthaithe
+authentication = Foinsรญ Fรญordheimhnithe
+emails = Rรญomhphoist รsรกideoirรญ
+config = Cumraรญocht
+notices = Fรณgraรญ Cรณrais
+config_summary = Achoimre
+config_settings = Socruithe
+monitor = Monatรณireacht
+first_page = Ar dtรบs
+last_page = Deiridh
+total = Iomlรกn: %d
+settings = Socruithe Riarachรกin
+dashboard.statistic = Achoimre
+dashboard.system_status = Stรกdas an Chรณrais
+dashboard.operation_name = Ainm Oibrรญochta
+dashboard.operation_switch = Athraigh
+dashboard.operation_run = Rith
+dashboard.clean_unbind_oauth = Glan naisc OAuth neamhcheangailte
+dashboard.clean_unbind_oauth_success = Scriosadh gach nasc OAuth neamhcheangailte.
+dashboard.task.started = Tasc Tosaigh: %[1]s
+dashboard.task.process = Tasc: %[1]s
+dashboard.task.cancelled = Tasc: %[1]s cealaithe: %[3]s
+dashboard.task.error = Earrรกid sa Tasc: %[1]s: %[3]s
+dashboard.task.finished = Tasc: Tรก %[1]s tosaithe ag %[2]s crรญochnaithe
+dashboard.task.unknown = Tasc anaithnid: %[1]s
+dashboard.cron.started = Cron tosaithe: %[1]s
+dashboard.cron.process = Cron: %[1]s
+dashboard.cron.cancelled = Cron: %[1]s cealaithe: %[3]s
+dashboard.cron.error = Earrรกid i gCron: %s: %[3]s
+dashboard.cron.finished = Cron: %[1]s crรญochnaithe
+dashboard.delete_inactive_accounts = Scrios gach cuntas neamhghnรญomhach
+dashboard.delete_inactive_accounts.started = Tasc scriostha gach cuntas neamhghnรญomhachtaithe tosaithe.
+dashboard.delete_repo_archives.started = Scrios gach tasc cartlann stรณrais a thosaigh.
+dashboard.delete_missing_repos = Scrios gach stรณras atรก in easnamh ar a gcuid comhad Git
+dashboard.delete_missing_repos.started = Scrios gach stรณras atรก in easnamh ar a dtasc comhaid Git a thosaigh.
+dashboard.delete_generated_repository_avatars = Scrios abhatรกranna stรณrtha ginte
+dashboard.sync_repo_tags = Clibeanna sioncraigh รณ shonraรญ git go bunachar sonraรญ
+dashboard.update_mirrors = Scรกthรกin a nuashonrรบ
+dashboard.repo_health_check = Seiceรกil slรกinte gach stรณras
+dashboard.check_repo_stats = Seiceรกil gach staitisticรญ stรณrais
+dashboard.archive_cleanup = Scrios sean-chartlanna stรณrais
+dashboard.deleted_branches_cleanup = Brainsรญ scriosta a ghlanadh
+dashboard.update_migration_poster_id = Nuashonraigh ID pรณstaer imir
+dashboard.git_gc_repos = Bailรญonn truflais gach stรณrais
+dashboard.reinit_missing_repos = Aththosaigh gach stรณrais Git atรก in easnamh a bhfuil taifid ann dรณibh
+dashboard.sync_external_users = Sioncrรณnaigh sonraรญ รบsรกideoirรญ seachtracha
+dashboard.cleanup_hook_task_table = Tรกbla hook_task glantachรกin
+dashboard.cleanup_packages = Pacรกistรญ glanta in รฉag
+dashboard.server_uptime = Aga fรณnaimh Freastalaรญ
+dashboard.current_goroutine = Goroutines Reatha
+dashboard.current_memory_usage = รsรกid Cuimhne Reatha
+dashboard.total_memory_allocated = Cuimhne Iomlรกn Leithdhรกilte
+dashboard.memory_obtained = Cuimhne Faighte
+dashboard.pointer_lookup_times = Amanna Cuardaigh Pointeora
+dashboard.memory_allocate_times = Leithdhรกiltรญ Cuimhne
+dashboard.memory_free_times = Saorรกlann Cuimhne
+dashboard.current_heap_usage = รsรกid Charn Reatha
+dashboard.heap_memory_obtained = Cuimhne Charn Faighte
+dashboard.heap_memory_idle = Dรญomhaoin Cuimhne Carn
+dashboard.heap_memory_in_use = Cuimhne Carm In รsรกid
+dashboard.heap_memory_released = Cuimhne Carn Eisithe
+dashboard.heap_objects = Cuspรณirรญ Carn
+dashboard.bootstrap_stack_usage = รsรกid Staca Bootstrap
+dashboard.stack_memory_obtained = Cuimhne Staca Faighte
+dashboard.mspan_structures_usage = รsรกid Struchtรบir MSpan
+dashboard.mspan_structures_obtained = Struchtรบir MSpan a Faightear
+dashboard.mcache_structures_usage = รsรกid Struchtรบir MCache
+dashboard.mcache_structures_obtained = Struchtรบir MCache a Faightear
+dashboard.profiling_bucket_hash_table_obtained = Tรกbla Hash Buicรฉad Prรณifรญlithe a Faightear
+dashboard.gc_metadata_obtained = Meiteashonraรญ GC faighte
+dashboard.other_system_allocation_obtained = Leithdhรกileadh Cรณrais Eile a Fuarthas
+dashboard.next_gc_recycle = Athchรบrsรกil GC Eile
+dashboard.total_gc_pause = Sos Iomlรกn GC
+dashboard.last_gc_pause = Sos GC Deireanach
+dashboard.gc_times = Amanna GC
+dashboard.delete_old_actions = Scrios gach sean-ghnรญomhaรญocht รณn mbunachar
+dashboard.delete_old_actions.started = Scrios na sean-ghnรญomhaรญocht go lรฉir รณn mbunachar sonraรญ tosaithe.
+dashboard.update_checker = Seiceoir nuashonraithe
+dashboard.delete_old_system_notices = Scrios gach seanfhรณgra cรณrais รณn mbunachar sonraรญ
+dashboard.gc_lfs = Bailigh truflais meta rudaรญ LFS
+dashboard.rebuild_issue_indexer = Atรณgรกil innรฉacsรณir eisiรบna
+users.new_account = Cruthaigh cuntas รsรกideora
+users.name = Ainm รบsรกideora
+users.full_name = Ainm Iomlรกn
+users.activated = Gnรญomhachtaithe
+users.admin = Riarachรกn
+users.restricted = Srianta
+users.reserved = In รกirithe
+users.bot = Bota
+users.remote = Iargรบlta
+users.2fa = 2FA
+users.repos = Stรณrais
+users.created = Cruthaithe
+users.last_login = Sรญnigh Isteach Deiridh
+users.new_success = Tรก an cuntas รบsรกideora "%s" cruthaithe.
+users.edit = Eagar
+users.auth_source = Foinse Fรญordheimhnithe
+users.local = รitiรบil
+users.auth_login_name = Ainm Sรญniรบ Isteach Fรญordheimhnithe
+users.password_helper = Fรกg an pasfhocal folamh chun รฉ a choinneรกil gan athrรบ.
+users.update_profile_success = Nuashonraรญodh an cuntas รบsรกideora.
+users.edit_account = Cuir Cuntas รsรกideora in Eagar
+users.max_repo_creation = Uasmhรฉid Stรณras
+users.max_repo_creation_desc = (Cuir isteach -1 chun an teorainn rรฉamhshocraithe domhanda a รบsรกid.)
+users.update_profile = Nuashonraigh Cuntas รsรกideora
+users.delete_account = Scrios Cuntas รsรกide
+users.still_own_repo = Tรก stรณrais amhรกin nรณ nรญos mรณ fรณs ag an รบsรกideoir seo. Scrios nรณ aistrigh na stรณrais seo ar dtรบs.
+users.still_has_org = Is ball d'eagraรญocht รฉ an t-รบsรกideoir seo. Bain an t-รบsรกideoir รณ aon eagraรญochtaรญ ar dtรบs.
+users.purge = รsรกideoir a Ghlanadh
+users.still_own_packages = Tรก pacรกiste amhรกin nรณ nรญos mรณ fรณs ag an รบsรกideoir seo, scrios na pacรกistรญ seo ar dtรบs.
+users.deletion_success = Scriosadh an cuntas รบsรกideora.
+users.reset_2fa = Athshocraigh 2FA
+users.list_status_filter.menu_text = Scagaire
+users.list_status_filter.reset = Athshocraigh
+users.list_status_filter.is_active = Gnรญomhach
+users.list_status_filter.not_active = Neamhghnรญomhach
+users.list_status_filter.is_admin = Riarachรกn
+users.list_status_filter.not_admin = Nรญ Riarachรกn
+users.list_status_filter.is_restricted = Srianta
+users.list_status_filter.not_restricted = Gan Srian
+users.list_status_filter.is_prohibit_login = Cosc ar Logรกil Isteach
+users.list_status_filter.not_prohibit_login = Ceadaigh Logรกil isteach
+users.list_status_filter.is_2fa_enabled = 2FA Cumasaithe
+users.list_status_filter.not_2fa_enabled = 2FA faoi mhรญchumas
+users.details = Sonraรญ รsรกideora
+emails.primary = Bunscoile
+emails.activated = Gnรญomhachtaithe
+emails.filter_sort.email = Rรญomhphost
+emails.filter_sort.email_reverse = Rรญomhphost (droim ar ais)
+emails.updated = Nuashonraรญodh an rรญomhphost
+emails.not_updated = Theip ar an seoladh rรญomhphoist iarrtha a nuashonrรบ: %v
+emails.duplicate_active = Tรก an seoladh rรญomhphoist seo gnรญomhach cheana fรฉin d'รบsรกideoir difriรบil.
+emails.change_email_header = Nuashonraigh Airรญonna Rรญomhphoist
+emails.change_email_text = An bhfuil tรบ cinnte gur mhaith leat an seoladh rรญomhphoist seo a nuashonrรบ?
+emails.delete = Scrios Rรญomhphost
+emails.delete_desc = An bhfuil tรบ cinnte gur mhaith leat an seoladh rรญomhphoist seo a scriosadh?
+emails.deletion_success = Tรก an seoladh rรญomhphoist scriosta.
+emails.delete_primary_email_error = Nรญ fรฉidir leat an rรญomhphost prรญomhรบil a scriosadh.
+orgs.name = Ainm
+orgs.teams = Foirne
+orgs.members = Comhaltaรญ
+orgs.new_orga = Eagraรญocht Nua
+repos.unadopted = Stรณrais Neamhghlactha
+repos.owner = รinรฉir
+repos.name = Ainm
+repos.private = Prรญobhรกideach
+repos.issues = Saincheisteanna
+repos.size = Mรฉid
+repos.lfs_size = Mรฉid LFS
+packages.total_size = Mรฉid Iomlรกn: %s
+packages.unreferenced_size = Mรฉid gan tagairt: %s
+packages.cleanup = Glan suas sonraรญ in รฉag
+packages.cleanup.success = Glanadh suas sonraรญ in รฉag go rathรบil
+packages.owner = รinรฉir
+packages.creator = Cruthaitheoir
+packages.name = Ainm
+packages.version = Leagan
+packages.type = Cineรกl
+packages.repository = Stรณrรกil
+packages.size = Mรฉid
+packages.published = Foilsithe
+defaulthooks = Rรฉamhshocraithe Crรบcaรญ Grรฉasรกn
+defaulthooks.add_webhook = Cuir Crรบca Grรฉasรกn Rรฉamhshocraithe leis
+defaulthooks.update_webhook = Nuashonraigh Rรฉamhshocrรบ Crรบca Grรฉasรกn
+systemhooks = Cรณras Crรบcaรญ Grรฉasรกn
+systemhooks.add_webhook = Cuir Crรบca Grรฉasรกn Cรณras leis
+systemhooks.update_webhook = Nuashonraigh Cรณras Crรบca Grรฉasรกn
+auths.new = Cuir Foinse Fรญordheimhni
+auths.name = Ainm
+auths.type = Cineรกl
+auths.enabled = Cumasaithe
+auths.syncenabled = Cumasaigh Sioncrรณnรบ รsรกideora
+auths.updated = Nuashonraithe
+auths.auth_type = Cineรกl Fรญordheimhnithe
+auths.auth_name = Ainm Fรญordheimhnithe
+auths.security_protocol = Prรณtacal Slรกndรกla
+auths.domain = Fearann
+auths.host = รstach
+auths.port = Calafort
+auths.bind_dn = Ceangail DN
+auths.bind_password = Ceangail Pasfhocal
+auths.user_base = Bonn Cuardaigh รsรกideora
+auths.user_dn = รsรกideoir DN
+auths.attribute_username = Trรฉith Ainm รsรกideora
+auths.attribute_name = Trรฉith Cรฉad Ainm
+auths.attribute_surname = Trรฉith Sloinne
+auths.attribute_mail = Trรฉith rรญomhphoist
+auths.attribute_ssh_public_key = Trรฉith Eochair SSH Phoiblรญ
+auths.attribute_avatar = Trรฉith Avatar
+auths.attributes_in_bind = Faigh trรฉithe i gComhthรฉacs Bind DN
+auths.allow_deactivate_all = Lig do thoradh cuardaigh folamh gach รบsรกideoir a dhรญghnรญomhachtรบ
+auths.use_paged_search = รsรกid Cuardach Leathanaigh
+auths.search_page_size = Mรฉid an Leathanaigh
+auths.filter = Scagaire รsรกideora
+auths.admin_filter = Scagaire Riarachรกin
+auths.restricted_filter = Scagaire Srianta
+auths.verify_group_membership = Fรญoraigh ballraรญocht ghrรบpa i LDAP (fรกg an scagaire folamh le scipeรกil)
+auths.group_search_base = Bonn Cuardaigh Grรบpa DN
+auths.group_attribute_list_users = Trรฉith Grรบpa ina bhfuil Liosta รsรกideoirรญ
+auths.user_attribute_in_group = Trรฉith รsรกideora atรก Liostaithe i nGrรบpa
+auths.map_group_to_team = Lรฉarscรกil grรบpaรญ LDAP chuig foirne na hEagraรญochta (fรกg an rรฉimse folamh le scipeรกil)
+auths.map_group_to_team_removal = Bain รบsรกideoirรญ รณ fhoirne sioncronaithe mura mbaineann an t-รบsรกideoir leis an ngrรบpa comhfhreagrach LDAP
+auths.enable_ldap_groups = Cumasaigh grรบpaรญ LDAP
+auths.ms_ad_sa = MS AD Trรฉithe Cuardaigh
+auths.smtp_auth = Cineรกl Fรญordheimhnithe SMTP
+auths.smtphost = รstach SMTP
+auths.smtpport = SMTP Calafort
+auths.allowed_domains = Fearainn Ceadaithe
+auths.force_smtps = Fรณrsa SMTPS
+auths.force_smtps_helper = รsรกidtear SMTPS i gcรณnaรญ ar chalafort 465. Socraigh รฉ seo chun SMTPS a chur i bhfeidhm ar chalafoirt eile. (Seachas sin รบsรกidfear STARTTLS ar chalafoirt eile mรก thacaรญonn an t-รณstach leis.)
+auths.helo_hostname = Ainm รstach HELO
+auths.helo_hostname_helper = Ainm รณstach a sheoltar le HELO. Fรกg bรกn chun an t-ainm รณstach reatha a sheoladh.
+auths.disable_helo = Dรญchumasaigh HELO
+auths.pam_service_name = Ainm Seirbhรญse PAM
+auths.pam_email_domain = Fearann Rรญomhphoist PAM (roghnach)
+auths.oauth2_provider = Solรกthraรญ OAuth2
+auths.oauth2_icon_url = URL deilbhรญn
+auths.oauth2_clientID = Aitheantas Cliant (Eochair)
+auths.oauth2_clientSecret = Rรบnda Cliant
+auths.openIdConnectAutoDiscoveryURL = URL Fionnachtana Uathoibrรญoch OpenID Connect
+auths.oauth2_use_custom_url = รsรกid URLanna Saincheaptha in ionad URLanna Rรฉamhshocraithe
+auths.oauth2_tokenURL = URL Comhartha
+auths.oauth2_authURL = รdaraigh URL
+auths.oauth2_profileURL = URL Prรณifรญl
+auths.oauth2_emailURL = URL rรญomhphoist
+auths.skip_local_two_fa = Scipeรกil 2FA รกitiรบil
+auths.skip_local_two_fa_helper = Ciallaรญonn fรกgรกil gan socrรบ go mbeidh ar รบsรกideoirรญ รกitiรบla a bhfuil tacar 2FA acu 2FA a rith fรณs chun logรกil isteach
+auths.oauth2_tenant = Tionรณnta
+auths.oauth2_scopes = Scรณipeanna Breise
+auths.oauth2_required_claim_name = Ainm รilimh Riachtanach
+auths.oauth2_required_claim_name_helper = Socraigh an t-ainm seo chun logรกil isteach รณn bhfoinse seo a shrianadh d'รบsรกideoirรญ a bhfuil รฉileamh acu leis an ainm seo
+auths.oauth2_required_claim_value = Luach รilimh Riachtanach
+auths.oauth2_required_claim_value_helper = Socraigh an luach seo chun logรกil isteach รณn bhfoinse seo a shrianadh chuig รบsรกideoirรญ a bhfuil รฉileamh acu leis an ainm agus an luach seo
+auths.oauth2_group_claim_name = Ainm รฉileamh ag solรกthar ainmneacha grรบpa don fhoinse seo (Roghnach)
+auths.oauth2_admin_group = Luach รilimh Grรบpa d'รบsรกideoirรญ riarthรณra. (Roghnach - teastaรญonn ainm รฉilimh thuas)
+auths.oauth2_restricted_group = Luach รilimh Grรบpa d'รบsรกideoirรญ srianta. (Roghnach - teastaรญonn ainm รฉilimh thuas)
+auths.oauth2_map_group_to_team = Map mhaรญgh grรบpaรญ chuig foirne Eagraรญochta. (Roghnach - รฉilรญonn ainm an รฉilimh thuas)
+auths.oauth2_map_group_to_team_removal = Bain รบsรกideoirรญ รณ fhoirne sioncronaithe mura mbaineann an t-รบsรกideoir leis an ngrรบpa comhfhreagrach.
+auths.sspi_auto_create_users = Cruthaigh รบsรกideoirรญ go huathoibrรญoch
+auths.sspi_auto_create_users_helper = Lig do mhodh auth SSPI cuntais nua a chruthรบ go huathoibrรญoch d'รบsรกideoirรญ a logรกlann isteach den chรฉad uair
+auths.sspi_auto_activate_users = Gnรญomhachtaigh รบsรกideoirรญ go huathoibrรญoch
+auths.sspi_auto_activate_users_helper = Lig modh auth SSPI รบsรกideoirรญ nua a ghnรญomhachtรบ go huathoibrรญoch
+auths.sspi_strip_domain_names = Bain ainmneacha fearann รณ ainm รบsรกideora
+auths.sspi_strip_domain_names_helper = Mรก dhรฉantar iad a sheiceรกil, bainfear ainmneacha fearainn รณ ainmneacha logรกla isteach (m.sh. Beidh โDOMAIN\ userโ agus "user@example.org" araon nรญ bheidh ach โรบsรกideoirโ).
+auths.sspi_separator_replacement = Deighilteoir le hรบsรกid in ionad\,/agus @
+auths.sspi_separator_replacement_helper = An carachtar a รบsรกidfear chun na deighilteoirรญ a chur in ionad na n-ainmneacha logรกla sรญos-leibhรฉil (m.sh. an \ i "DOMAIN\รบsรกideoir") agus ainmneacha prรญomhoidรญ รบsรกideora (m.sh. an @ in "user@example.org").
+auths.sspi_default_language = Teanga รบsรกideora rรฉamhshocraithe
+auths.sspi_default_language_helper = Teanga rรฉamhshocraithe d'รบsรกideoirรญ cruthaithe go huathoibrรญoch ag modh auth SSPI. Fรกg folamh mรกs fearr leat teanga a bhrath go huathoibrรญoch.
+auths.tips = Leideanna
+auths.tips.oauth2.general = OAuth2 Fรญordheimhniรบ
+auths.tips.oauth2.general.tip = Agus fรญordheimhniรบ OAuth2 nua รก chlรกrรบ agat, ba chรณir go mbeadh an URL glaonna ais/atreoraithe:
+auths.tip.oauth2_provider = Solรกthraรญ OAuth2
+auths.tip.nextcloud = `Clรกraigh tomhaltรณir OAuth nua ar do chรกs ag baint รบsรกide as an roghchlรกr seo a leanas "Socruithe -> Slรกndรกil -> cliant OAuth 2.0"`
+auths.tip.dropbox = Cruthaigh feidhmchlรกr nua ag %s
+auths.tip.facebook = Clรกraigh feidhmchlรกr nua ag %s agus cuir an tรกirge "Facebook Login" leis
+auths.tip.github = Clรกraigh feidhmchlรกr OAuth nua ar %s
+auths.tip.gitlab_new = Clรกraigh feidhmchlรกr nua ar %s
+auths.tip.google_plus = Faigh dintiรบir chliaint OAuth2 รณ chonsรณl API Google ag %s
+auths.tip.twitter = Tรฉigh go %s, cruthaigh feidhmchlรกr agus cinntigh go bhfuil an rogha "Ceadaigh รบsรกid a bhaint as an bhfeidhmchlรกr seo chun logรกil isteach le Twitter" cumasaithe
+auths.tip.discord = Clรกraigh feidhmchlรกr nua ar %s
+auths.tip.gitea = Clรกraigh feidhmchlรกr OAuth2 nua. Tรก treoir le fรกil ag %s
+auths.tip.yandex = `Cruthaigh feidhmchlรกr nua ag %s. Roghnaigh na ceadanna seo a leanas รณn rannรกn "Yandex.Passport API": "Rochtain ar sheoladh rรญomhphoist", "Rochtain ar avatar รบsรกideora" agus "Rochtain ar ainm รบsรกideora, cรฉad ainm agus sloinne, inscne"`
+auths.tip.mastodon = Ionchur URL sampla saincheaptha don shampla mastodon is mian leat a fhรญordheimhniรบ leis (nรณ bain รบsรกid as an gceann rรฉamhshocraithe)
+auths.edit = Cuir Foinse Fรญordheimhnithe in Eagar
+auths.activated = Tรก an Foinse Fรญordheimhnithe seo gnรญomhachtaithe
+auths.new_success = Tรก an fรญordheimhniรบ "%s" curtha leis.
+auths.update_success = Nuashonraรญodh an fhoinse fรญordheimhnithe.
+auths.update = Nuashonraigh Foinse Fรญordheimhnithe
+auths.delete = Scrios Foinse Fรญordheimhnithe
+auths.delete_auth_title = Scrios Foinse Fรญordheimhnithe
+auths.delete_auth_desc = Mรก scriosann tรบ foinse fรญordheimhnithe cuirtear cosc โโar รบsรกideoirรญ รญ a รบsรกid chun sรญniรบ isteach. Lean ort?
+auths.still_in_used = Tรก an fhoinse fรญordheimhnithe fรณs in รบsรกid. Tiontaigh nรณ scrios aon รบsรกideoir a รบsรกideann an fhoinse fรญordheimhnithe seo ar dtรบs.
+auths.deletion_success = Tรก an fhoinse fรญordheimhnithe scriosta.
+auths.login_source_exist = Tรก an fhoinse fรญordheimhnithe "%s" ann cheana.
+auths.login_source_of_type_exist = Tรก foinse fรญordheimhnithe den chineรกl seo ann cheana fรฉin.
+auths.unable_to_initialize_openid = Nรญ fรฉidir Solรกthraรญ Ceangail OpenID a thionscnamh: %s
+auths.invalid_openIdConnectAutoDiscoveryURL = URL Neamhbhailรญ Fionnachtana Uathoibrรญoch (nรญ mรณr gur URL bailรญ รฉ seo ag tosรบ le http:// nรณ https://)
+config.server_config = Cumraรญocht Freastalaรญ
+config.custom_conf = Cosรกn Comhad Cumraรญochta
+config.domain = Fearann โโFreastalaรญ
+config.offline_mode = Mรณd รitiรบil
+config.disable_router_log = Dรญchumasaigh Loga an Rรณdaire
+config.run_mode = Mรณd Rith
+config.git_version = Leagan Git
+config.app_data_path = Cosรกn Sonraรญ Aip
+config.repo_root_path = Cosรกn Frรฉimhe Stรณrรกla
+config.lfs_root_path = Cosรกn Frรฉamh LFS
+config.log_file_root_path = Cosรกn Logรกla
+config.script_type = Cineรกl Script
+config.ssh_config = Cumraรญocht SSH
+config.ssh_enabled = Cumasaithe
+config.ssh_start_builtin_server = รsรกid Freastalaรญ Ionsuite
+config.ssh_domain = Fearainn Freastalaรญ SSH
+config.ssh_port = Calafort
+config.ssh_listen_port = รist Calafort
+config.ssh_root_path = Cosรกn Frรฉimhe
+config.ssh_key_test_path = Cosรกn Tรกstรกil Eochair
+config.ssh_minimum_key_size_check = Seiceรกil รosta Mรฉid Eochair
+config.ssh_minimum_key_sizes = Mรฉideanna รosta Eochrach
+config.lfs_config = Cumraรญocht LFS
+config.lfs_enabled = Cumasaithe
+config.lfs_content_path = Cosรกn รbhar LFS
+config.db_config = Cumraรญocht Bunachar Sonraรญ
+config.db_type = Cineรกl
+config.db_host = รstach
+config.db_name = Ainm
+config.db_user = Ainm รบsรกideora
+config.db_schema = Scรฉim
+config.db_ssl_mode = SSL
+config.db_path = Cosรกn
+config.service_config = Cumraรญocht Seirbhรญse
+config.register_email_confirm = Deimhniรบ Rรญomhphost a รฉileamh chun Clรกrรบ
+config.disable_register = Dรญchumasaigh Fรฉin-Chlรกrรบ
+config.allow_only_external_registration = Ceadaigh Clรกrรบ Trรญ Sheirbhรญsรญ Seachtracha amhรกin
+config.enable_openid_signup = Cumasaigh Fรฉinchlรกrรบ OpenID
+config.enable_openid_signin = Cumasaigh Sรญniรบ isteach OpenID
+config.show_registration_button = Taispeรกin Cnaipe Clรกraithe
+config.mail_notify = Cumasaigh Fรณgraรญ Rรญomhphoist
+config.enable_captcha = Cumasaigh CAPTCHA
+config.default_keep_email_private = Folaigh Seoltaรญ Rรญomhphoist de rรฉir Rรฉamhshocrรบ
+config.default_allow_create_organization = Ceadaigh Cruthรบ Eagraรญochtaรญ de rรฉir Rรฉamhshocrรบ
+config.enable_timetracking = Cumasaigh Rianรบ Ama
+config.default_enable_timetracking = Cumasaigh Rianรบ Ama de rรฉir Rรฉamhshocrรบ
+config.default_allow_only_contributors_to_track_time = Lig do Rannphรกirtithe Amhรกin Rianรบ Am
+config.no_reply_address = Fearann Rรญomhphoist Folaithe
+config.default_enable_dependencies = Cumasaigh Spleรกchais Eisithe de rรฉir Rรฉamhshocrรบ
+config.webhook_config = Cumraรญocht Crรบca Grรฉasรกn
+config.queue_length = Fad scuaine
+config.deliver_timeout = Teorainn Ama Seachadta
+config.skip_tls_verify = Scipeรกil Fรญorรบ TLS
+config.mailer_config = Cumraรญocht Seoltรณra
+config.mailer_enabled = Cumasaithe
+config.mailer_enable_helo = Cumasaigh HELO
+config.mailer_name = Ainm
+config.mailer_protocol = Prรณtacal
+config.mailer_smtp_port = Calafort SMTP
+config.mailer_user = รsรกideoir
+config.mailer_use_sendmail = รsรกid Sendmail
+config.mailer_sendmail_path = Cosรกn Sendmail
+config.mailer_sendmail_args = Argรณintรญ Breise chuig Sendmail
+config.mailer_sendmail_timeout = Teorainn Ama Sendmail
+config.mailer_use_dummy = Caochadรกn
+config.test_email_placeholder = Rรญomhphost (m.sh. test@example.com)
+config.send_test_mail_submit = Seol
+config.oauth_config = Cumraรญocht OAuth
+config.oauth_enabled = Cumasaithe
+config.cache_config = Cumraรญocht taisce
+config.cache_adapter = Cuibheoir taisce
+config.cache_interval = Eatramh Taisce
+config.cache_conn = Ceangal Taisce
+config.cache_item_ttl = Mรญr Taisce TTL
+config.cache_test = Taisce Tรกstรกil
+config.cache_test_failed = Theip ar an taisce a thaiscรฉaladh: %v.
+config.cache_test_slow = D'รฉirigh leis an tรกstรกil taisce, ach tรก an freagra mall: %s.
+config.cache_test_succeeded = D'รฉirigh leis an tรกstรกil taisce, fuair sรฉ freagra i %s.
+config.session_config = Cumraรญocht Seisiรบin
+config.session_provider = Solรกthraรญ Seisiรบin
+config.provider_config = Cumraรญocht Solรกthraรญ
+config.cookie_name = Ainm Fianรกn
+config.gc_interval_time = Am Eatramh GC
+config.https_only = HTTPS Amhรกin
+config.picture_config = Cumraรญocht Pictiรบr agus Avatar
+config.picture_service = Seirbhรญs Pictiรบr
+config.disable_gravatar = Dรญchumasaigh Gravatar
+config.enable_federated_avatar = Cumasaigh Avatars Cรณnaidhme
+config.open_with_editor_app_help = Na heagarthรณirรญ "Oscailte le" don roghchlรกr Clรณn. Mรก fhรกgtar folamh รฉ, รบsรกidfear an rรฉamhshocrรบ. Leathnaigh chun an rรฉamhshocrรบ a fheiceรกil.
+config.git_config = Cumraรญocht Git
+config.git_gc_args = Argรณintรญ GC
+config.git_migrate_timeout = Teorainn Ama Imirce
+config.git_mirror_timeout = Teorainn Ama Nuashonraithe Scรกthรกin
+config.git_clone_timeout = Teorainn Ama Oibrรญochta Clรณn
+config.git_pull_timeout = Tarraing Am Oibrรญochta
+config.git_gc_timeout = Teorainn Ama Oibriรบchรกin GC
+config.log_config = Cumraรญocht Logรกil
+config.logger_name_fmt = Logรกlaรญ: %s
+config.disabled_logger = Dรญchumasaithe
+config.access_log_mode = Mรณd Logรกil Rochtana
+config.access_log_template = Teimplรฉad Logรกil Rochtana
+config.xorm_log_sql = Logรกil SQL
+config.set_setting_failed = Theip ar shocrรบ %s a shocrรบ
+monitor.stats = Staitisticรญ
+monitor.cron = Tascanna Cron
+monitor.name = Ainm
+monitor.schedule = Sceideal
+monitor.next = An chรฉad uair eile
+monitor.previous = Am Roimhe Seo
+monitor.execute_times = Forghnรญomhaรญochtaรญ
+monitor.process = Prรณisis reatha
+monitor.stacktrace = Rian cruachta
+monitor.processes_count = Prรณisis %d
+monitor.download_diagnosis_report = รoslรณdรกil tuairisc diagnรณis
+monitor.desc = Cur sรญos
+monitor.start = Am Tosaigh
+monitor.execute_time = Am Forghnรญomhaithe
+monitor.last_execution_result = Toradh
+monitor.process.cancel = Cealaigh prรณiseas
+monitor.process.children = Leanaรญ
+monitor.queues = Scuaineanna
+monitor.queue = Scuaine: %s
+monitor.queue.name = Ainm
+monitor.queue.type = Cineรกl
+monitor.queue.exemplar = Cineรกl Eiseamlรกire
+monitor.queue.numberworkers = Lรญon na nOibrithe
+monitor.queue.activeworkers = Oibrithe Gnรญomhacha
+monitor.queue.maxnumberworkers = Lรญon Uasta na nOibrithe
+monitor.queue.numberinqueue = Uimhir i scuaine
+monitor.queue.review_add = Athbhreithniรบ / Cuir Oibrithe leis
+monitor.queue.settings.title = Socruithe Linn
+monitor.queue.settings.desc = Fรกsann linnte go dinimiciรบil mar fhreagra ar a gcuid scuaine oibrithe a bhlocรกil.
+monitor.queue.settings.maxnumberworkers = Uaslรญon na n-oibrithe
+monitor.queue.settings.maxnumberworkers.placeholder = Faoi lรกthair %[1]d
+monitor.queue.settings.maxnumberworkers.error = Caithfidh uaslรญon na n-oibrithe a bheith ina uimhir
+monitor.queue.settings.submit = Nuashonrรบ Socruithe
+monitor.queue.settings.changed = Socruithe Nuashonraithe
+monitor.queue.settings.remove_all_items = Bain gach
+monitor.queue.settings.remove_all_items_done = Baineadh na mรญreanna go lรฉir sa scuaine.
+notices.system_notice_list = Fรณgraรญ Cรณrais
+notices.operations = Oibrรญochtaรญ
+notices.select_all = Roghnaigh Gach
+notices.deselect_all = Dรญroghnaigh Gach
+notices.inverse_selection = Roghnรบ Inbhรฉartha
+notices.delete_selected = Scrios Roghnaithe
+notices.delete_all = Scrios Gach Fรณgra
+notices.type = Cineรกl
+notices.type_1 = Stรณras
+notices.type_2 = Tasc
+notices.desc = Cur sรญos
+notices.op = Oibrรญocht.
+notices.delete_success = Scriosadh na fรณgraรญ cรณrais.
+self_check.no_problem_found = Nรญor aimsรญodh aon fhadhb fรณs.
+self_check.database_collation_mismatch = Bรญ ag sรบil le comhthiomsรบ a รบsรกid sa bhunachar sonraรญ: %s
+self_check.database_inconsistent_collation_columns = Tรก comhthiomsรบ %s in รบsรกid ag an mbunachar sonraรญ, ach tรก comhthiomsuithe mรญmheaitseรกla รก n-รบsรกid ag na colรบin seo. D'fhรฉadfadh sรฉ a bheith ina chรบis le roinnt fadhbanna gan choinne.
+
+[action]
+create_repo = stรณras cruthaithe %s
+rename_repo = stรณras athainmnithe รณ %[1]s
go %[3]s
+commit_repo = brรบ chuig %[3]s ag %[4]s
+create_issue = `osclaรญodh ceist %[3]s#%[2]s `
+close_issue = `eagrรกn dรบnta %[3]s#%[2]s `
+reopen_issue = `athoscailt an cheist %[3]s#%[2]s `
+create_pull_request = `iarratas tarraingthe cruthaithe %[3]s#%[2]s `
+close_pull_request = `iarratas tarraingthe dรบnta %[3]s#%[2]s `
+reopen_pull_request = `iarratas tarraingthe athoscailte %[3]s#%[2]s `
+comment_issue = `trรกcht ar cheist %[3]s#%[2]s `
+comment_pull = `dรฉan trรกcht ar iarratas tarraingthe %[3]s#%[2]s `
+merge_pull_request = `iarratas tarraingthe cumaisc %[3]s#%[2]s `
+auto_merge_pull_request = `iarratas tarraingthe cumasctha go huathoibrรญoch %[3]s#%[2]s `
+transfer_repo = aistrithe stรณras %s
go %s
+push_tag = brรบ %[3]s go %[4]s
+delete_tag = scriosta clib %[2]s รณ %[3]s
+delete_branch = brainse scriosta %[2]s รณ %[3]s
+compare_branch = Dรฉan comparรกid
+compare_commits = Dรฉan comparรกid idir tiomรกintรญ %d
+compare_commits_general = Dรฉan comparรกid idir tiomรกintรญ
+mirror_sync_push = geallann synced do %[3]s ag %[4]s รณn scรกthรกn
+mirror_sync_create = sioncronaigh tagairt nua %[3]s do %[4]s รณn scรกthรกn
+mirror_sync_delete = sioncronaithe agus scriosta an tagairt %[2]s
ag %[3]s รณn scรกthรกn
+approve_pull_request = `ceadaithe %[3]s#%[2]s `
+reject_pull_request = `athruithe molta le haghaidh %[3]s#%[2]s `
+publish_release = `scaoileadh %[4]s ag %[3]s `
+review_dismissed = `lรฉirmheas รณ %[4]s le haghaidh %[3]s#%[2]s `
+review_dismissed_reason = Cรบis:
+create_branch = brainse cruthaithe %[3]s i %[4]s
+starred_repo = le %[2]s le rรฉalta
+watched_repo = thosaigh sรฉ ag breathnรบ ar %[2]s
+
+[tool]
+now = anois
+future = todhchaรญ
+1s = 1 soicind
+1m = 1 nรณimรฉad
+1h = 1 uair an chloig
+1d = 1 lรก
+1w = 1 seachtain
+1mon = 1 mhรญ
+1y = 1 bhliain
+seconds = %d soicind
+minutes = %d nรณimรฉad
+hours = %d uair an chloig
+days = %d laethanta
+weeks = %d seachtain
+months = %d mรญonna
+years = %d bliain
+raw_seconds = soicind
+raw_minutes = nรณimรฉad
+
+[dropzone]
+default_message = Scaoil comhaid nรณ cliceรกil anseo chun iad a uaslรณdรกil.
+invalid_input_type = Nรญ fรฉidir leat comhaid den chineรกl seo a uaslรณdรกil.
+file_too_big = Sรกraรญonn mรฉid comhaid ({{filesize}} MB) an t-uasmhรฉid de ({{maxFilesize}} MB).
+remove_file = Bain an comhad
+
+[notification]
+notifications = Fรณgraรญ
+unread = Gan lรฉamh
+read = Lรฉigh
+no_unread = Gan aon fhรณgraรญ neamh-lรฉite.
+no_read = Gan aon fhรณgraรญ lรฉite.
+pin = Fรณgra biorรกin
+mark_as_read = Marcรกil mar lรฉite
+mark_as_unread = Marcรกil mar neamh-lรฉite
+mark_all_as_read = Marcรกil gach ceann mar lรฉite
+subscriptions = Sรญntiรบis
+watching = Ag fรฉachaint
+no_subscriptions = Gan sรญntiรบis
+
+[gpg]
+default_key = Sรญnithe leis an eochair rรฉamhshocraithe
+error.extract_sign = Theip ar an sรญniรบ a bhaint
+error.generate_hash = Theip ar hash gealltanas a ghiniรบint
+error.no_committer_account = Nรญl aon chuntas nasctha le seoladh rรญomhphoist an tiomnรณra
+
+[units]
+unit = Aonad
+error.no_unit_allowed_repo = Nรญl cead agat rochtain a fhรกil ar aon chuid den tiomantas seo.
+error.unit_not_allowed = Nรญl cead agat an rannรกn stรณras seo a rochtain.
+
+[packages]
+title = Pacรกistรญ
+desc = Bainistigh pacรกistรญ stรณrais.
+empty = Nรญl aon phacรกistรญ ann fรณs.
+empty.documentation = Le haghaidh tuilleadh eolais ar chlรกrlann na bpacรกistรญ, fรฉach ar na doicimรฉid .
+empty.repo = An ndearna tรบ uaslรณdรกil ar phacรกiste, ach nach bhfuil sรฉ lรฉirithe anseo? Tรฉigh go socruithe pacรกiste agus nasc leis an stรณras seo รฉ.
+registry.documentation = Le haghaidh tuilleadh eolais ar chlรกrlann %s, fรฉach ar na doicimรฉid .
+filter.type = Cineรกl
+filter.type.all = Gach
+filter.no_result = Nรญor thug do scagaire aon torthaรญ.
+filter.container.tagged = Clibeรกilte
+filter.container.untagged = Gan chlib
+published_by = Foilsithe %[1]s ag %[3]s
+published_by_in = Foilsithe ag %[1]s ag %[3]s in %[5]s
+installation = Suiteรกil
+about = Maidir leis an bpacรกiste seo
+requirements = Riachtanais
+dependencies = Spleithiรบlachtaรญ
+keywords = Eochairfhocail
+details = Sonraรญ
+details.author = รdar
+details.license = Ceadรบnas
+assets = Sรณcmhainnรญ
+versions = Leaganacha
+versions.view_all = Fรฉach ar gach
+dependency.id = ID
+dependency.version = Leagan
+search_in_external_registry = Cuardaigh i %s
+alpine.registry = Socraigh an chlรกr seo trรญd an url a chur i do chomhad /etc/apk/repositories
:
+alpine.registry.key = รoslรณdรกil eochair RSA poiblรญ na clรกrlainne isteach san fhillteรกn /etc/apk/keys/
chun an sรญniรบ innรฉacs a fhรญorรบ:
+alpine.registry.info = Roghnaigh $branch agus $repository รณn liosta thรญos.
+alpine.install = Chun an pacรกiste a shuiteรกil, rith an t-ordรบ seo a leanas:
+alpine.repository = Eolas Stรณrais
+alpine.repository.branches = Brainsรญ
+alpine.repository.repositories = Stรณrais
+alpine.repository.architectures = Ailtireachtaรญ
+cargo.registry = Socraigh an clรกrlann seo sa chomhad cumraรญochta lasta (mar shampla ~/.cargo/config.toml
):
+cargo.install = Chun an pacรกiste a shuiteรกil ag baint รบsรกide as Cargo, reรกchtรกil an t-ordรบ seo a leanas:
+chef.registry = Socraigh an clรกrlann seo i do chomhad ~/.chef/config.rb
:
+chef.install = Chun an pacรกiste a shuiteรกil, rith an t-ordรบ seo a leanas:
+composer.registry = Socraigh an chlรกr seo i do chomhad ~/.composer/config.json
:
+composer.install = Chun an pacรกiste a shuiteรกil ag baint รบsรกide as Cumadรณir, reรกchtรกil an t-ordรบ seo a leanas:
+composer.dependencies = Spleithiรบlachtaรญ
+composer.dependencies.development = Spleithiรบlachtaรญ Forbartha
+conan.details.repository = Stรณras
+conan.registry = Socraigh an clรกrlann seo รณn lรญne ordaithe:
+conan.install = Chun an pacรกiste a shuiteรกil ag รบsรกid Conan, reรกchtรกil an t-ordรบ seo a leanas:
+conda.registry = Socraigh an chlรกr seo mar stรณras Conda i do chomhad .condarc
:
+conda.install = Chun an pacรกiste a shuiteรกil ag รบsรกid Conda, reรกchtรกil an t-ordรบ seo a leanas:
+container.details.type = Cineรกl รomhรก
+container.details.platform = Ardรกn
+container.pull = Tarraing an รญomhรก รณn lรญne ordaithe:
+container.digest = Dรญleรกigh
+container.multi_arch = Cรณras Oibriรบchรกin / Ailtireacht
+container.layers = Sraitheanna รomhรก
+container.labels = Lipรฉid
+container.labels.key = Eochair
+container.labels.value = Luach
+cran.registry = Cumraigh an chlรกrlann seo i do chomhad Rprofile.site
:
+cran.install = Chun an pacรกiste a shuiteรกil, rith an t-ordรบ seo a leanas:
+debian.registry = Socraigh an clรกrlann seo รณn lรญne ordaithe:
+debian.registry.info = Roghnaigh $distribution agus $component รณn liosta thรญos.
+debian.install = Chun an pacรกiste a shuiteรกil, rith an t-ordรบ seo a leanas:
+debian.repository = Eolas Stรณras
+debian.repository.distributions = Dรกiltรญ
+debian.repository.components = Comhphรกirteanna
+debian.repository.architectures = Ailtireachtaรญ
+generic.download = รoslรณdรกil pacรกiste รณn lรญne ordaithe:
+go.install = Suiteรกil an pacรกiste รณn lรญne ordaithe:
+helm.registry = Socraigh an clรกrlann seo รณn lรญne ordaithe:
+helm.install = Chun an pacรกiste a shuiteรกil, rith an t-ordรบ seo a leanas:
+maven.registry = Socraigh an clรกrlann seo i do chomhad pom.xml
tionscadail:
+maven.install = Chun an pacรกiste a รบsรกid cuir na nithe seo a leanas sa bhloc spleรกchais
sa chomhad pom.xml
:
+maven.install2 = Rith trรญd an lรญne ordaithe:
+maven.download = Chun an spleรกchas a รญoslรณdรกil, rith trรญd an lรญne ordaithe:
+nuget.registry = Socraigh an clรกrlann seo รณn lรญne ordaithe:
+nuget.install = Chun an pacรกiste a shuiteรกil ag รบsรกid NuGet, reรกchtรกil an t-ordรบ seo a leanas:
+nuget.dependency.framework = Spriocchreat
+npm.registry = Socraigh an chlรกrlann seo i do chomhad .npmrc
do thionscadail:
+npm.install = Chun an pacรกiste a shuiteรกil ag รบsรกid npm, reรกchtรกil an t-ordรบ seo a leanas:
+npm.install2 = nรณ cuir leis an gcomhad package.json รฉ:
+npm.dependencies = Spleithiรบlachtaรญ
+npm.dependencies.development = Spleithiรบlachtaรญ Forbartha
+npm.dependencies.bundle = Spleรกchais Chuachta
+npm.dependencies.peer = Spleithiรบlachtaรญ Piaraรญ
+npm.dependencies.optional = Spleรกchais Roghnacha
+npm.details.tag = Clib
+pub.install = Chun an pacรกiste a shuiteรกil ag รบsรกid Dart, reรกchtรกil an t-ordรบ seo a leanas:
+pypi.requires = Teastaรญonn Python
+pypi.install = Chun an pacรกiste a shuiteรกil ag รบsรกid pip, reรกchtรกil an t-ordรบ seo a leanas:
+rpm.registry = Socraigh an clรกrlann seo รณn lรญne ordaithe:
+rpm.distros.redhat = ar dhรกileadh bunaithe ar RedHat
+rpm.distros.suse = ar dhรกileadh bunaithe ar SUSE
+rpm.install = Chun an pacรกiste a shuiteรกil, rith an t-ordรบ seo a leanas:
+rpm.repository = Eolas Stรณras
+rpm.repository.architectures = Ailtireachtaรญ
+rpm.repository.multiple_groups = Tรก an pacรกiste seo ar fรกil i ngrรบpaรญ รฉagsรบla.
+rubygems.install = Chun an pacรกiste a shuiteรกil ag baint รบsรกide as gem, reรกchtรกil an t-ordรบ seo a leanas:
+rubygems.install2 = nรณ cuir leis an Gemfile รฉ:
+rubygems.dependencies.runtime = Spleรกchais Rith-Ama
+rubygems.dependencies.development = Spleรกchais Forbartha
+rubygems.required.ruby = รilรญonn leagan Ruby
+rubygems.required.rubygems = รilรญonn leagan RubyGem
+swift.registry = Socraigh an clรกrlann seo รณn lรญne ordaithe:
+swift.install = Cuir an pacรกiste i do chomhad Package.swift
:
+swift.install2 = agus reรกchtรกil an t-ordรบ seo a leanas:
+vagrant.install = Chun bosca Vagrant a chur leis, reรกchtรกil an t-ordรบ seo a leanas:
+settings.link = Nasc an pacรกiste seo le stรณras
+settings.link.description = Mรก nascann tรบ pacรกiste le stรณras, liostaรญtear an pacรกiste i liosta pacรกistรญ an stรณrais.
+settings.link.select = Roghnaigh Stรณras
+settings.link.button = Nuashonraigh Nasc Stรณrais
+settings.link.success = D'รฉirigh le nasc an stรณrais a nuashonrรบ.
+settings.link.error = Theip ar an nasc stรณras a nuashonrรบ.
+settings.delete = Scrios pacรกiste
+settings.delete.description = Tรก pacรกiste a scriosadh buan agus nรญ fรฉidir รฉ a chur ar ais.
+settings.delete.notice = Tรก tรบ ar tรญ %s (%s) a scriosadh. Tรก an oibrรญocht seo dochรบlaithe, an bhfuil tรบ cinnte?
+settings.delete.success = Tรก an pacรกiste scriosta.
+settings.delete.error = Theip ar an pacรกiste a scriosadh.
+owner.settings.cargo.title = Innรฉacs Clรกrlann Lasta
+owner.settings.cargo.initialize = Innรฉacs a chur i dtosach
+owner.settings.cargo.initialize.description = Tรก gรก le stรณras innรฉacs speisialta Git chun an clรกrlann Cargo a รบsรกid. Trรญd an rogha seo, cruthรณfar an stรณras (nรณ athchruthรณfar รฉ) agus cumrรณfar รฉ go huathoibrรญoch.
+owner.settings.cargo.initialize.error = Nรญorbh fhรฉidir an t-innรฉacs Cargo a thรบsรบ: %v
+owner.settings.cargo.initialize.success = Cruthaรญodh an t-innรฉacs Cargo go rathรบil.
+owner.settings.cargo.rebuild = Innรฉacs Atรณgรกil
+owner.settings.cargo.rebuild.description = Is fรฉidir atรณgรกil a bheith รบsรกideach mura bhfuil an t-innรฉacs sioncronaithe leis na pacรกistรญ Cargo stรณrรกilte.
+owner.settings.cargo.rebuild.error = Nรญorbh fhรฉidir an t-innรฉacs Cargo a atรณgรกil: %v
+owner.settings.cargo.rebuild.success = D'รฉirigh leis an innรฉacs Cargo a atรณgรกil.
+owner.settings.cleanuprules.add = Cuir Riail Glantachรกin leis
+owner.settings.cleanuprules.edit = Cuir Riail Glantachรกin in eagar
+owner.settings.cleanuprules.preview = Rรฉamhamharc Riail Glantachรกin
+owner.settings.cleanuprules.preview.overview = Tรก pacรกistรญ %d beartaithe a bhaint.
+owner.settings.cleanuprules.preview.none = Nรญ hionann riail glantachรกin agus pacรกistรญ ar bith.
+owner.settings.cleanuprules.enabled = Cumasaithe
+owner.settings.cleanuprules.pattern_full_match = Cuir patrรบn i bhfeidhm ar ainm an phacรกiste iomlรกn
+owner.settings.cleanuprules.keep.title = Coinnรญtear leaganacha a mheaitseรกlann leis na rialacha seo, fiรบ mรก mheaitseรกlann siad riail bhaint thรญos.
+owner.settings.cleanuprules.keep.count = Coinnigh an ceann is dรฉanaรญ
+owner.settings.cleanuprules.keep.count.1 = 1 leagan in aghaidh an phacรกiste
+owner.settings.cleanuprules.keep.count.n = Leaganacha %d in aghaidh an phacรกiste
+owner.settings.cleanuprules.keep.pattern = Coinnigh leaganacha meaitseรกla
+owner.settings.cleanuprules.keep.pattern.container = Coinnรญtear an leagan is dรฉanaรญ
le haghaidh pacรกistรญ Coimeรกdรกn i gcรณnaรญ.
+owner.settings.cleanuprules.remove.title = Baintear leaganacha a mheaitseรกlann leis na rialacha seo, mura deir riail thuas iad a choinneรกil.
+owner.settings.cleanuprules.remove.days = Bain leaganacha nรญos sine nรก
+owner.settings.cleanuprules.remove.pattern = Bain leaganacha meaitseรกla
+owner.settings.cleanuprules.success.update = Nuashonraรญodh an riail ghlantachรกin.
+owner.settings.cleanuprules.success.delete = Scriosadh an riail glantachรกin.
+owner.settings.chef.title = Clรกrlann Chef
+owner.settings.chef.keypair = Gin pรฉire eochair
+owner.settings.chef.keypair.description = Tรก eochairphรฉire riachtanach le fรญordheimhniรบ a dhรฉanamh ar chlรกrlann an Chef. Mรก tรก pรฉire eochrach ginte agat roimhe seo, mรก ghinfidh tรบ eochairphรฉire nua, scriosfar an seanphรฉire eochair.
+
+[secrets]
+secrets = Rรบin
+description = Cuirfear rรบin ar aghaidh chuig gnรญomhartha รกirithe agus nรญ fรฉidir iad a lรฉamh ar mhalairt.
+none = Nรญl aon rรบin ann fรณs.
+creation = Cuir Rรบnda leis
+creation.name_placeholder = carachtair alfanumair nรณ รญoslaghda amhรกin nach fรฉidir a thosรบ le GITEA_ nรณ GITHUB_
+creation.value_placeholder = Ionchur รกbhar ar bith. Fรกgfar spรกs bรกn ag tรบs agus ag deireadh ar lรกr.
+creation.success = Tรก an rรบn "%s" curtha leis.
+creation.failed = Theip ar an rรบn a chur leis.
+deletion = Bain rรบn
+deletion.description = Is buan rรบn a bhaint agus nรญ fรฉidir รฉ a chealรบ. Lean ort?
+deletion.success = Tรก an rรบn bainte.
+deletion.failed = Theip ar rรบn a bhaint.
+
+[actions]
+actions = Gnรญomhartha
+runners = Reathaitheoirรญ
+runners.new = Cruthaigh reathaรญ nua
+runners.new_notice = Conas reathaรญ a thosรบ
+runners.status = Stรกdas
+runners.id = ID
+runners.name = Ainm
+runners.owner_type = Cineรกl
+runners.description = Cur sรญos
+runners.labels = Lipรฉid
+runners.last_online = Am Ar Lรญne Deiridh
+runners.runner_title = Reathaรญ
+runners.task_list = Tascanna le dรฉanaรญ ar an reathaรญ seo
+runners.task_list.no_tasks = Nรญl aon tasc ann fรณs.
+runners.task_list.run = Rith
+runners.task_list.status = Stรกdas
+runners.task_list.repository = Stรณras
+runners.task_list.commit = Tiomantas
+runners.task_list.done_at = Dรฉanta ag
+runners.edit_runner = Cuir Reathaรญ in Eagar
+runners.update_runner = Nuashonrรบ Athruithe
+runners.update_runner_success = Nuashonraรญodh an Reathaรญ
+runners.update_runner_failed = Theip ar an reathaรญ a nuashonrรบ
+runners.delete_runner = Scrios an reathaรญ seo
+runners.delete_runner_success = Scriosadh an reathaรญ go rathรบil
+runners.delete_runner_failed = Theip ar an reathaรญ a scriosadh
+runners.delete_runner_header = Deimhnigh an reathaรญ seo a scriosadh
+runners.delete_runner_notice = Mรก tรก tasc ar siรบl ar an reathaรญ seo, cuirfear deireadh leis agus marcรกil mar theip. Fรฉadfaidh sรฉ sreabhadh oibre tรณgรกla a bhriseadh.
+runners.none = Nรญl aon reathaรญ ar fรกil
+runners.status.unspecified = Anaithnid
+runners.status.idle = Dรญomhaoin
+runners.status.active = Gnรญomhach
+runners.status.offline = As lรญne
+runners.version = Leagan
+runners.reset_registration_token = Athshocraigh comhartha clรกr
+runners.reset_registration_token_success = D'รฉirigh le hathshocrรบ comhartha clรกrรบchรกin an dara hรกit
+runs.all_workflows = Gach Sreafaรญ Oibre
+runs.commit = Tiomantas
+runs.scheduled = Sceidealaithe
+runs.pushed_by = bhrรบ ag
+runs.invalid_workflow_helper = Tรก comhad cumraรญochta sreabhadh oibre nebhailรญ. Seiceรกil do chomhad cumraithe le do thoil: %s
+runs.no_matching_online_runner_helper = Gan aon reathaรญ ar lรญne a mheaitseรกil le lipรฉad: %s
+runs.no_job_without_needs = Caithfidh post amhรกin ar a laghad a bheith sa sreabhadh oibre gan spleรกchas.
+runs.no_job = Caithfidh post amhรกin ar a laghad a bheith sa sreabhadh oibre
+runs.actor = Aisteoir
+runs.status = Stรกdas
+runs.actors_no_select = Gach aisteoir
+runs.status_no_select = Gach stรกdas
+runs.no_results = Nรญor mheaitseรกil aon torthaรญ.
+runs.no_workflows = Nรญl aon sreafaรญ oibre ann fรณs.
+runs.no_runs = Nรญl aon rith ag an sreabhadh oibre fรณs.
+runs.empty_commit_message = (teachtaireacht tiomantas folamh)
+runs.expire_log_message = Glanadh logaรญ toisc go raibh siad rรณ-sean.
+workflow.disable = Dรญchumasaigh sreabhadh oibre
+workflow.enable = Cumasaigh sreabhadh oibre
+workflow.disabled = Tรก sreabhadh oibre dรญchumasaithe
+need_approval_desc = Teastaรญonn faomhadh chun sreafaรญ oibre a rith le haghaidh iarratas tarraingt forc.
+variables = Athrรณga
+variables.creation = Cuir Athrรณg leis
+variables.none = Nรญl aon athrรณga ann fรณs.
+variables.deletion = Bain athrรณg
+variables.deletion.description = Tรก athrรณg a bhaint buan agus nรญ fรฉidir รฉ a chur ar ais. Lean ar aghaidh?
+variables.description = Cuirfear athrรณga chuig gnรญomhartha รกirithe agus nรญ fรฉidir iad a lรฉamh ar mhalairt eile.
+variables.id_not_exist = Nรญl athrรณg le ID %d ann.
+variables.edit = Cuir Athrรณg in Eagar
+variables.deletion.failed = Theip ar athrรณg a bhaint.
+variables.deletion.success = Tรก an athrรณg bainte.
+variables.creation.failed = Theip ar athrรณg a chur leis.
+variables.creation.success = Tรก an athrรณg "%s" curtha leis.
+variables.update.failed = Theip ar athrรณg a chur in eagar.
+variables.update.success = Tรก an t-athrรณg curtha in eagar.
+
+[projects]
+deleted.display_name = Tionscadal scriosta
+type-1.display_name = Tionscadal Aonair
+type-2.display_name = Tionscadal Stรณrais
+type-3.display_name = Tionscadal Eagrรบchรกin
+
+[git.filemode]
+changed_filemode = %[1]s โ %[2]s
+directory = Eolaire
+normal_file = Comhad gnรกth
+executable_file = Comhad infheidhmithe
+symbolic_link = Nasc siombalach
+submodule = Fo-mhodรบl
diff --git a/options/locale/locale_gl.ini b/options/locale/locale_gl.ini
index 673486f6c0..75763775eb 100644
--- a/options/locale/locale_gl.ini
+++ b/options/locale/locale_gl.ini
@@ -1,28 +1,25 @@
-
-
-
[common]
home = Inicio
dashboard = Panel de Control
explore = Explorar
help = Axuda
logo = Logo
-sign_in = Iniciar Sesiรณn
+sign_in = Iniciar sesiรณn
sign_in_with_provider = Iniciar Sesiรณn con %s
sign_in_or = ou
sign_out = Pechar Sesiรณn
-sign_up = Rexรญstrate
-link_account = Vincular Conta
+sign_up = Rexistrarse
+link_account = Vincular conta
register = Rexistro
-version = Vesiรณn
-powered_by = Desenvolvido por %s
+version = Versiรณn
+powered_by = Impulsado por %s
page = Pรกxina
template = Modelo
notifications = Notificaciรณns
-active_stopwatch = Activar Rastrexador de Tempo
+active_stopwatch = Rastreador de tempo activo
create_new = Crearโฆ
-user_profile_and_more = Perfil e Configuraciรณnโฆ
-signed_in_as = Inicia Sesiรณn como
+user_profile_and_more = Perfil e configuraciรณnโฆ
+signed_in_as = Sesiรณn iniciada como
enable_javascript = Este sitio web require JavaScript.
toc = Tรกboa de Contidos
licenses = Licenzas
@@ -32,17 +29,17 @@ email = Enderezo Electrรณnico
password = Contrasinal
re_type = Confirme o contrasinal
captcha = CAPTCHA
-twofa = Autenticaciรณn de Dous Factores
-passcode = Cรณdigo de Acceso
-webauthn_insert_key = Insira a sรบa Chave de Seguranza
-webauthn_press_button = Preme o botรณn da sรบa Chave de Seguranzaโฆ
+twofa = Autenticaciรณn de dobre factor
+passcode = Cรณdigo de acceso
+webauthn_insert_key = Insira a sรบa chave de seguridade
+webauthn_press_button = Prema o botรณn da sรบa chave de seguridadeโฆ
webauthn_use_twofa = Use o Cรณdigo de Dous Factores do seu Telรฉfono
-webauthn_error = Non se Puido Ler a sรบa Chave de Seguranza.
-webauthn_unsupported_browser = O seu Navegador non Soporta Actualmente WebAuthn.
-webauthn_error_unknown = Produciuse un Erro Descoรฑecido.Tรฉntao de novo.
-webauthn_error_unable_to_process = O Servidor non Puido Procesar a sรบa Solicitude.
-webauthn_error_duplicated = A Chave de Seguranza non estรก Permitida para esta Solicitude. Asegรบrese de que a Chave non Estea Rexistrada.
-webauthn_error_empty = Debes Definir un Nome para esta Chave.
+webauthn_error = Non se puido ler a sรบa clave de seguridade.
+webauthn_unsupported_browser = O seu navegador non soporta WebAuthn actualmente.
+webauthn_error_unknown = Produciuse un erro descoรฑecido. Tรฉnteo de novo.
+webauthn_error_unable_to_process = O servidor non puido procesar a sรบa solicitude.
+webauthn_error_duplicated = A clave de seguridade non estรก permitida para esta solicitude. Asegรบrese de que a clave non estea xa rexistrada.
+webauthn_error_empty = Debe definir un nome para esta clave.
webauthn_reload = Recarga
repository = Repositorio
organization = Organizaciรณn
@@ -52,21 +49,21 @@ new_migrate = Nova Migraciรณn
new_mirror = Novo Espello
new_fork = Nova Bifurcaciรณn do Repositorio
new_org = Nova Organizaciรณn
-new_project = Novo Proxecto
-new_project_column = Nova Columna
+new_project = Novo proxecto
+new_project_column = Nova columna
manage_org = Xestionar Organizaciรณns
-admin_panel = Administraciรณn do Sitio
+admin_panel = Administraciรณn da pรกxina
account_settings = Axustes da Conta
settings = Configuraciรณn
your_profile = Perfil
your_starred = Destacado
-your_settings = Configuraciรณns
+your_settings = Configuraciรณn
all = Todo
sources = Fontes
mirrors = Espellos
collaborative = Colaborativo
forks = Derivaciรณns
-pull_requests = Pull Requests
+pull_requests = Solicitudes de fusiรณn
milestones = Fitos
ok = OK
cancel = Cancelar
@@ -74,57 +71,57 @@ retry = Volve Tentar
rerun = Volve Executar
rerun_all = Volve Executar Todos os Traballos
add = Engadir
-add_all = Engadir Todo
-remove_all = Quitar Todo
-remove_label_str = Eliminar Elemento "%s"
+add_all = Engadir todo
+remove_all = Quitar todo
+remove_label_str = Eliminar elemento "%s"
edit = Editar
enabled = Activado
locked = Bloqueado
copy = Copiar
copy_url = Copiar URL
-copy_branch = Copiar o Nome da Rama
+copy_branch = Copiar o nome da rama
copy_success = Copiado!
-copy_error = Erro na Copia
+copy_error = Erro na copia
write = Escribir
-preview = Vista Previa
+preview = Vista previa
loading = Cargandoโฆ
error = Erro
-go_back = Volver Atrรกs
+go_back = Volver atrรกs
never = Nunca
unknown = Descoรฑecido
rss_feed = Feed RSS
unpin = Desprender
artifacts = Artefactos
-confirm_delete_artifact = Estรกs seguro de que queres eliminar o Artefacto '%s' ?
+confirm_delete_artifact = Estรก seguro de querer eliminar o artefacto "%s"?
archived = Arquivado
concept_system_global = Global
access_token = Token de Acceso
activities = Actividades
save = Gardar
-copy_content = Copiar Contido
+copy_content = Copiar contido
language = Linguaxe
copy_hash = Copiar hash
twofa_scratch = Cรณdigo Scratch de Dous Factores
-webauthn_sign_in = Preme o botรณn da sรบa Chave de Seguranza. Se a sรบa Chave de Seguranza non ten ningรบn botรณn, insรญrela de novo.
-issues = Problemas
+webauthn_sign_in = Prema o botรณn da sรบa chave de seguridade. Se a sรบa chave de seguridade non ten ningรบn botรณn, volva inserila.
+issues = Incidencias
disabled = Desactivado
-error404 = A pรกxina รก que estรกs tentando acceder Non Existe ou Non tes Autorizaciรณn para vela.
-tracked_time_summary = Resumo do tempo de seguimento baseado nos filtros da lista de problemas
-webauthn_error_insecure = WebAuthn sรณ Admite Conexiรณns Seguras. Para probar a travรฉs de HTTP, pode usar a orixe "localhost" ou "127.0.0.1"
-webauthn_error_timeout = Alcanzouse o tempo de espera antes de que se Pidese Ler a sรบa Chave. Volve cargar esta Pรกxina e Tรฉntao de Novo.
+error404 = A pรกxina รก que estรกs tentando acceder non existe ou non tes autorizaciรณn para vela.
+tracked_time_summary = Resumo do tempo de seguimento baseado nos filtros da lista de incidencias
+webauthn_error_insecure = WebAuthn sรณ admite conexiรณns seguras. Para probar a travรฉs de HTTP, pode usar a orixe "localhost" ou "127.0.0.1"
+webauthn_error_timeout = Alcanzouse o lรญmite de tempo antes de que se puidera ler a sรบa clave. Volva cargar esta pรกxina e tรฉnteo de novo.
remove = Quitar
-view = Vista
+view = Ver
copy_type_unsupported = Este tipo de ficheiro non se pode copiar
concept_user_organization = Organizaciรณn
-show_timestamps = Mostrar M0arcas de Tempo
-show_log_seconds = Mostrar Segundos
-download_logs = Descargar Rexistros
+show_timestamps = Mostrar marcas de tempo
+show_log_seconds = Mostrar segundos
+download_logs = Descargar rexistros
name = Nome
value = Valor
-confirm_delete_selected = Confirmar a eliminaciรณn de todos os elementos seleccionados?
+confirm_delete_selected = Confirmar a eliminaciรณn de tรณdolos elementos seleccionados?
show_full_screen = Mostrar Pantalla Completa
-more_items = Mรกis items
-toggle_menu = Alternar Menรบ
+more_items = Mรกis elementos
+toggle_menu = Alternar menรบ
filter = Filtro
filter.clear = Borrar filtros
filter.is_archived = Arquivado
@@ -142,6 +139,15 @@ filter.public = Publico
pin = Aproximada
filter.private = Privado
copy_generic = Copiar ao portapapeis
+test = Test
+copy_path = Copiar ruta
+error413 = Esgotou a sรบa cota.
+new_repo.title = Novo repositorio
+new_migrate.title = Nova migraciรณn
+new_org.title = Nova organizaciรณn
+new_repo.link = Novo repositorio
+new_migrate.link = Nova migraciรณn
+new_org.link = Nova organizaciรณn
[aria]
navbar = Barra de Navegaciรณn
@@ -156,6 +162,7 @@ more = Mรกis
number_of_contributions_in_the_last_12_months = %s de contribuciรณns nos รบltimos 12 meses
contributions_few = contribuciรณns
contributions_one = contribuciรณn
+contributions_format = {contributions} no {day} de {month} do {year}
[editor]
buttons.heading.tooltip = Engadir Tรญtulo
@@ -168,18 +175,56 @@ buttons.list.unordered.tooltip = Engadir unha lista de marcadores
buttons.enable_monospace_font = Activa o tipo de letra monoespazo
buttons.disable_monospace_font = Desactivar o tipo de letra monoespazo
buttons.ref.tooltip = Referencia un problema ou pull request
+buttons.indent.tooltip = Aniรฑa os elementos nun nivel
+buttons.unindent.tooltip = Desaniรฑar os elementos nun nivel
+table_modal.placeholder.content = Contido
+table_modal.label.rows = Filas
+table_modal.label.columns = Columnas
+buttons.list.ordered.tooltip = Engade unha lista numerada
+buttons.list.task.tooltip = Engade unha lista de tarefas
+buttons.mention.tooltip = Menciona a un usuario ou equipo
+buttons.switch_to_legacy.tooltip = Utilizar o editor herdado
+buttons.new_table.tooltip = Engadir tรกboa
+table_modal.header = Engadir tรกboa
+table_modal.placeholder.header = Cabeceira
+link_modal.header = Engadir ligazรณn
+link_modal.url = Url
+link_modal.description = Descriciรณn
[search]
search = Buscar...
-type_tooltip = Tipo de busca
+type_tooltip = Tipo de procura
+repo_kind = Buscar repositorios...
+user_kind = Buscar usuarios...
+regexp = RegExp
+regexp_tooltip = Interpretar o termo da procura como expresiรณn regular
+org_kind = Procurar organizaciรณns...
+team_kind = Procurar equipos...
+code_kind = Procurar cรณdigo...
+code_search_unavailable = A procura de cรณdigo non estรก dispoรฑible neste momento. Por favor contacte coa persoa responsable da administraciรณn da pรกxina.
+package_kind = Buscar paquetes...
+fuzzy = Difusa
+fuzzy_tooltip = Incluรญr resultados que tamรฉn coincidan estreitamente co termo da procura
+union = Palabras clave
+union_tooltip = Incluรญr resultados correspondentes a calquera dal palabras clave separadas por espazos en branco
+exact = Exacta
+exact_tooltip = Incluรญr sรณ resultados correspondentes ao termo exacto da procura
+issue_kind = Procurar incidencias...
+project_kind = Buscar proxectos...
+branch_kind = Buscar ramas...
+no_results = Non se atoparon resultados coincidentes.
+keyword_search_unavailable = A busca por palabra clave non estรก dispoรฑible actualmente. Pรณรฑase en contacto co administrador do sitio.
+commit_kind = Buscar achegas...
+runner_kind = Buscar executores...
+pull_kind = Buscar pulls...
[startpage]
platform = Multiplataforma
app_desc = Um servizo Git autoxestionado e fรกcil de usar
install = Fรกcil de instalar
-platform_desc = Forgejo execรบtase en calquera lugar onde Go poida compilar para: Windows, MacOS, Linux, ARM, etc. Escolla seu preferido!
-install_desc = Simplemente executa o binario para a tรบa plataforma, envรญao con < un target="_blank" rel="noopener noreferrer" href="https://forgejo.org/download/#container-image">Docker ou consรญgueo empaquetado .
+install_desc = Simplemente executa o binario para a tรบa plataforma, envรญao con Docker ou consรญgueo empaquetado .
+license = Cรณdigo aberto
[error]
occurred = Ocorreu un erro
@@ -188,7 +233,7 @@ server_internal = Erro interno do servidor
invalid_csrf = Solicitude incorrecta: token CSRF non vรกlido
not_found = Non se puido atopar o obxectivo.
network_error = Erro de rede
-report_message = Se cres que se trata dun erro de Forgejo, busca problemas en Codeberg ou abre un novo problema Se รฉ necesario.
+report_message = Se cres que se trata dun erro de Forgejo, busca problemas en Codeberg ou abre un novo problema Se รฉ necesario.
[filter]
string.asc = A - Z
@@ -221,4 +266,28 @@ log_root_path = Ruta de rexistro
log_root_path_helper = Os ficheiros de rexistro escribiranse neste directorio.
sqlite_helper = Ruta do ficheiro para a base de datos SQLite3. Introduza unha ruta absoluta se executa Forgejo como servizo.
reinstall_confirm_message = A reinstalaciรณn cunha base de datos Forgejo existente pode causar varios problemas. Na maiorรญa dos casos, deberรญas usar o teu "app.ini" existente para executar Forgejo. Se sabes o que estรกs facendo, confirma o seguinte:
-reinstall_confirm_check_1 = ร posible que se perdan os datos cifrados pola SECRET_KEY en app.ini: รฉ posible que os usuarios non poidan iniciar sesiรณn con 2FA/OTP e que os espellos non funcionen correctamente. Ao marcar esta caixa, confirmas que o ficheiro app.ini actual contรฉn a SECRET_KEY correcta.
\ No newline at end of file
+reinstall_confirm_check_1 = ร posible que se perdan os datos cifrados pola SECRET_KEY en app.ini: รฉ posible que os usuarios non poidan iniciar sesiรณn con 2FA/OTP e que os espellos non funcionen correctamente. Ao marcar esta caixa, confirmas que o ficheiro app.ini actual contรฉn a SECRET_KEY correcta.
+disable_gravatar.description = Desactiva o uso de Gravatar ou outras fontes de avatares de terceiros. As imaxes predeterminadas utilizaranse para os avatares dos usuarios a menos que carguen o seu propio avatar na instancia.
+federated_avatar_lookup = Activar avatares federados
+repo_path = Ruta raรญz do repositorio
+run_user = O usuario co que executar
+password = Contrasinal
+repo_path_helper = Os repositorios Git remotos gardarรกnse neste directorio.
+lfs_path = Ruta raรญz de Git LFS
+install = Instalaciรณn
+db_title = Configuraciรณn da base de datos
+db_name = Nome da base de datos
+db_schema = Esquema
+db_schema_helper = Dรฉixao baleiro para a base de datos por defecto ("public").
+app_name = Tรญtulo da instancia
+user = Nome de usuario
+general_title = Opciรณns xerais
+app_name_helper = Escribe o nome da tรบa instancia aqui. Serรก amosado en cada pรกxina.
+mailer_user = Usuario SMTP
+mailer_password = Contrasinal SMTP
+title = Configuraciรณn inicial
+db_type = Tipo de base de datos
+app_slogan = Slogan da instancia
+app_slogan_helper = Escribe o slogan da tรบa instancia aqui. Ou deixao baleiro para desabilitala.
+domain = Dominio do servidor
+ssh_port = Porto do servidor SSH
\ No newline at end of file
diff --git a/options/locale/locale_he.ini b/options/locale/locale_he.ini
new file mode 100644
index 0000000000..bff7682a95
--- /dev/null
+++ b/options/locale/locale_he.ini
@@ -0,0 +1,666 @@
+
+
+
+[common]
+webauthn_error_unable_to_process = ืฉืจืช ืื ื ืืฉื ืืขืืืื ืืงืฉืชื.
+help = ืขืืจื
+logo = ืืืื
+sign_in_with_provider = ืื ืืกื ืืจื %s
+sign_in_or = ืื
+sign_out = ืืฆืืื ืืืืฉืืื
+sign_up = ืืจืฉืื
+link_account = ืืืืืจ ืืฉืืื
+register = ืืจืฉืื
+version = ืืจืกื
+page = ืืฃ
+template = ืชืื ืืช
+language = ืฉืคื
+notifications = ืืืืขืืช
+active_stopwatch = ืกืืืคืจ
+create_new = ืืืฉโฆ
+user_profile_and_more = ืคืจืืคืื ืืืืืจืืชโฆ
+signed_in_as = ืฉืืื
+enable_javascript = ืืชืจ ืื ืืฉืชืืฉ ืJavaScript.
+toc = ืชืืื ืืขื ืื ืื
+licenses = ืจืืฉืืื ืืช
+return_to_forgejo = ืืืจื ืืคืืจื'ื
+more_items = ืขืื ืืคืฉืจืืืืช
+username = ืฉื ืืฉืชืืฉ
+email = ืืชืืืช ืืืืืื
+password = ืกืืกืื
+access_token = ืงืื ืืืฉื
+captcha = CAPTCHA
+twofa_scratch = ืงืื ืืืืืช ืืึพืฉืืื
+passcode = ืงืื ืื ืืกื
+webauthn_error_unknown = ืฉืืืื ืื ืืืืขื, ืืคืฉืจ ืื ืกืืช ืฉืื.
+webauthn_error_empty = ืฉื ืืืคืชื ืืื ืฉืื ืืืื.
+webauthn_error_timeout = ืงืจืืืช ืืคืชืื ืืงืื ืืืชืจ ืืื ืืื. ืืคืฉืจ ืืืขืื ืืืืฉ ืืช ืืืฃ ืืื ืกืืช ืฉืื.
+organization = ืืจืืื
+mirror = ืืจืื
+new_mirror = ืืจืื ืืืฉื
+new_fork = ืืืืื ืืืฉ ืฉื ืงืจืคืืฃ ืื
+new_project = ืคืจืืืงื ืืืฉ
+new_project_column = ืขืืืื ืืืฉื
+admin_panel = ืืื ื ืืืื ืืขืจืืช
+your_profile = ืคืจืืคืื
+your_starred = ืืืืืช
+new_org.title = ืืจืืื ืืืฉ
+all = ืืื
+sources = ืืงืืจืืช
+collaborative = ืฉืืชืืคื
+forks = ืืืืืืื
+issues = ืกืืืืืช
+milestones = ืืืจืืช
+ok = ืืืฉืืจ
+cancel = ืืืืื
+rerun = ืืจืฆื ืืืืจืช
+add = ืืืกืคื
+remove_all = ืืกืจืช ืืื
+edit = ืขืจืืื
+locked = ื ืขืื
+copy = ืืขืชืงื
+copy_url = ืืขืชืงืช ืงืืฉืืจ
+copy_hash = ืืขืชืงืช ืงืื ืืืืื
+copy_branch = ืืขืชืงืช ืฉื ืขื ืฃ
+copy_success = ืืืขืชืง!
+write = ืืชืืื
+preview = ืชืฆืืื ืืงืืืื
+loading = ื ืืขืโฆ
+error = ืฉืืืื
+error404 = ืืฃ ืื ืื ืงืืื ืื ืฉืืื ืื ืืืื ืืืฉื .
+never = ืืฃ ืคืขื
+unknown = ืื ืืืืข
+rss_feed = ืคืื RSS
+pin = ืืฆืืื
+archived = ืืจืืืื
+concept_user_organization = ืืจืืื
+show_full_screen = ืืกื ืืื
+confirm_delete_selected = ืืืืืง ืืช ืื ืืคืจืืืื ืืืกืืื ืื?
+name = ืฉื
+value = ืขืจื
+filter = ืืกื ื
+filter.clear = ื ืืงืื ืืกื ื ืื
+filter.is_archived = ืืืจืืืื
+filter.not_archived = ืืืืฅ ืืืจืืืื
+filter.not_fork = ืืืืฆืื ืืืืืืื
+filter.is_mirror = ืจืง ืืจืืืช
+filter.not_mirror = ืืืืฆืื ืืจืืืช
+filter.not_template = ืืืืฆืื ืชืื ืืืช
+filter.public = ืฆืืืืจื
+filter.private = ืคืจืื
+home = ืืืช
+sign_in = ืื ืืกื
+remove = ืืกืจื
+test = ืืืืงื
+copy_error = ืืขืชืงื ื ืืฉืื
+go_back = ืืืืจื
+unpin = ืืืืื ืืฆืืื
+show_timestamps = ืืฆืืช ืืื ืื
+show_log_seconds = ืืฆืืช ืฉื ืืืช
+download_logs = ืืืจืืช ืืืืื
+filter.is_fork = ืจืง ืืืืืืื
+filter.is_template = ืจืง ืชืื ืืืช
+twofa = ืืืืืช ืืึพืฉืืื
+pull_requests = ืืงืฉืืช ืืืืื
+powered_by = ืจืฅ ืขื %s
+copy_generic = ืืขืชืงื ืCtrl + C
+webauthn_unsupported_browser = ืืืคืืคื ืฉืื ืื ืชืืื ืWebAuthn.
+webauthn_error_insecure = ืืคืจืืืืงืื WebAuthn ืื ืชืืื ืืืืืืจืื ืื ืืืืืืืื, ืืืขื ืืจื "localhost" ืื "127.0.0.1"
+settings = ืืืืจืืช
+your_settings = ืืืืจืืช
+new_org.link = ืืจืืื ืืืฉ
+mirrors = ืืจืืืช
+activities = ืคืขืืืืืืช
+retry = ืื ืกืืช ืฉืื
+save = ืฉืืืจื
+add_all = ืืืกืคืช ืืื
+copy_content = ืืขืชืงืช ืชืืื
+copy_type_unsupported = ืื ืืคืฉืจ ืืืขืชืืง ืงืืฆืื ืืกืื ืื
+concept_system_global = ืืืืืื
+concept_user_individual = ืืืฉื
+webauthn_insert_key = ืืฉ ืืืื ืืก ืืช ืืคืชื ืืืืื
+webauthn_press_button = ื ื ืืืืืฅ ืขื ืืืคืชืืจ ืฉืขื ืืคืชื ืืืืืืโฆ
+webauthn_error = ืงืจืืืช ืืคืชื ืืืืืื ื ืืฉืื.
+repository = ืงืจืคืืฃ
+new_repo.title = ืงืจืคืืฃ ืืืฉ
+new_migrate.title = ืืืื ืงืจืคืืฃ
+new_repo.link = ืงืจืคืืฃ ืืืฉ
+new_migrate.link = ืืืื ืงืจืคืืฃ
+enabled = ืืืคืขื
+disabled = ืืืื
+copy_path = ืืขืชืงืช ืืืงืื ืงืืืฅ
+invalid_data = ืืื ืช ืืงืื ื ืืฉืื: %v
+concept_code_repository = ืงืจืคืืฃ
+webauthn_sign_in = ืืฉ ืืืืืฅ ืขื ืืืคืชืืจ ืฉืขื ืืคืชื ืืืืืื. ืื ืืื ืืคืชืืจ, ืืคืฉืจ ืืืืฆืื ืืช ืืืคืชื ืืืืืจ ืืืชื ืฉืื.
+webauthn_error_duplicated = ืืคืชื ืืืืืื ืื ืืืื ืืฉืืฉ ืืืงืฉื ืื. ื ื ืืืืื ืฉืืืคืชื ืื ืจืฉืื.
+dashboard = ืืื ืขื
+remove_label_str = ืืกืจืช "%s"
+explore = ืงืืืืืื
+view = ืขืื ืืืืข
+artifacts = ืืจืืืคืงืืื
+confirm_delete_artifact = ืืืืืง ืืช ืืืจืืืคืงื "%s"?
+toggle_menu = ืืฆืืช\ืืกืชืจืช ืชืคืจืื
+re_type = ืกืืกืื (ืฉืื)
+
+[search]
+search = ืืืคืืฉ...
+type_tooltip = ืกืื ืืืคืืฉ
+fuzzy = ืืงืืจื
+union = ืืืืืช ืืคืชื
+exact = ืืืืืง
+exact_tooltip = ืชืืฆืืืช ืืชืืืื ืืืืืืง ืืชืืื ืชืืืช ืืืืคืืฉ
+regexp = ืจื'ืงืก
+user_kind = ืืืคืืฉ ืื ืฉืื...
+code_kind = ืืืคืืฉ ืงืื...
+team_kind = ืืืคืืฉ ืฆืืืชืื...
+no_results = ืื ื ืืฆืื ืชืืฆืืืช.
+union_tooltip = ืชืืฆืืืช ืืืืื ืืคืืืช ืืืืช ืืคืชื ืืืช; ืืคืฉืจ ืืืคืจืื ืืืืืช ืืคืชื ืขื ืจืืืืื
+org_kind = ืืืคืืฉ ืืจืืื ืื...
+package_kind = ืืืคืืฉ ืืืืืืช...
+project_kind = ืืืคืืฉ ืคืจืืืืงืืื...
+branch_kind = ืืืคืืฉ ืขื ืคืื...
+commit_kind = ืืืคืืฉ ืงืืืืืื...
+issue_kind = ืืืคืืฉ ืกืืืืืช...
+fuzzy_tooltip = ืชืืฆืืืช ืืชืืืื ืืชืืื ืชืืืช ืืืืคืืฉ ืืงืืจืื; ืืืืืฅ ืื ืื ืฉืืืืืช ืืชืื
+repo_kind = ืืืคืืฉ ืงืจืคืืคืื...
+code_search_by_git_grep = ืชืืฆืืืช ืืืืคืืฉ ืืืฆืจื ืขื ืืื "git grep"; ืืืื ืืืืืช ืฉืืชืงืืื ืชืืฆืืืช ืืืืืช ืืืชืจ ืื ืื ืืื ืืืขืจืืช ืืคืขืืื ืืช ืืืคืชืื.
+runner_kind = ืืืคืืฉ ืืจืืฆืื...
+keyword_search_unavailable = ืืืคืืฉ ืืืืืช ืืคืชื ืื ืืืื. ื ื ืืืืื ืืื ืืื ืืืขืจืืช.
+code_search_unavailable = ืืืคืืฉ ืงืื ืื ืืืื. ื ื ืืืืื ืืื ืืื ืืืขืจืืช.
+pull_kind = ืืืคืืฉ ืืงืฉืืช ืืืืื...
+
+[heatmap]
+number_of_contributions_in_the_last_12_months = % ืชืจืืืืช ืึพ12 ืืืืืฉืื ืืืืจืื ืื
+contributions_zero = ืืคืก ืชืจืืืืช
+contributions_format = {contributions} ื{day} ื{month} {year}
+contributions_one = ืชืจืืื
+contributions_few = ืชืจืืืืช
+less = ืคืืืช
+more = ืืืชืจ
+
+[error]
+server_internal = ืฉืืืืช ืฉืจืช ืคื ืืืืช
+not_found = ืืืืจื ืื ื ืืฆืื.
+network_error = ืฉืืืืช ืืื ืืจื ื
+occurred = ืงืจืชื ืฉืืืื
+
+[startpage]
+lightweight = ืงื
+install = ืงื ืืืชืงื ื
+license = ืงืื ืคืชืื
+platform_desc = ืคืืจื'ื ืจืฅ ืขื ืืขืจืืืช ืืคืขืื ืคืชืืืืช ืืื ืืื ืืงืก ืFreeBSD, ืืขื ืืจืืืืงืืืจืืช ืืขืื ืฉืื ืืช.
+lightweight_desc = ืคืืจื'ื ืฆืืจื ืืืืช ืืื ืืืืืช ืฉื ืืฉืืืื ืืืืื ืืจืืฅ ืขื ืืื ืึพืืืฉืืื ืื ืืงืจืื ืืื ืืจืืกืคืจื ืืคืื.
+
+[editor]
+buttons.list.unordered.tooltip = ืืืกืคืช ืจืฉืืื ืื ืืืืกืคืจืช
+buttons.switch_to_legacy.tooltip = ืืขืืจ ืืขืืจื ืืืฉื
+buttons.heading.tooltip = ืืืกืคืช ืืืชืจืช
+buttons.bold.tooltip = ืืืืฉืช ืืงืกื
+buttons.italic.tooltip = ืืืืืช ืืงืกื
+buttons.quote.tooltip = ืฆืืืื
+buttons.code.tooltip = ืืืกืคืช ืงืื
+buttons.link.tooltip = ืืืกืคืช ืงืืฉืืจ
+buttons.list.ordered.tooltip = ืืืกืคืช ืจืฉืืื ืืืืกืคืจืช
+buttons.list.task.tooltip = ืืืกืคืช ืจืฉืืืช ืืฉืืืืช
+buttons.mention.tooltip = ืชืืื ืืื ืื ืฆืืืช
+buttons.ref.tooltip = ืจืืคืจืืจ ืืกืืืื ืื ืืงืฉืช ืืืืื
+buttons.enable_monospace_font = ืืคืขืืช ืืืคื ืงืืืขึพืจืืื
+buttons.disable_monospace_font = ืืืืื ืืืคื ืงืืืขึพืจืืื
+buttons.new_table.tooltip = ืืืกืคืช ืืืื
+table_modal.header = ืืืกืคืช ืืืื
+table_modal.placeholder.header = ืืืชืจืช
+table_modal.placeholder.content = ืชืืื
+table_modal.label.rows = ืฉืืจืืช
+table_modal.label.columns = ืขืืืืืช
+
+[filter]
+string.desc = ืกืืจ ืืืคืืชื ืืืจื
+string.asc = ืกืืจ ืืืคืืชื ืขืืื
+
+[install]
+db_schema_helper = ืชืืื ืจืืง ืืฉืืข ืขืจื ืืจืืจืช ืืืืื ("public") ืฉื ืืกื ืืืืืข.
+title = ืืืืจื ืจืืฉืื ืืช
+install = ืืชืงื ื
+db_title = ืืืืจืืช ืืกื ืืืืข
+db_type = ืกืื ืืกื ืืืืข
+user = ืฉื ืืฉืชืืฉ
+password = ืกืืกืื
+db_name = ืฉื ืืกื ืืืืืข
+db_schema = ืกืืืื
+ssl_mode = SSL
+err_empty_admin_password = ืกืืกืื ืฉื ืื ืื ืืขืจืืช ืื ืืืืื ืืืืืช ืจืืงื.
+err_empty_admin_email = ืืชืืืช ืืืืืื ืฉื ืื ืื ืืขืจืืช ืืื ืืืื.
+general_title = ืืืืจืืช ืืืืืืช
+app_name = ืฉื ืฉืจืช ืื
+err_empty_db_path = ืืืชืืืช ืืืกื ืืืืืข SQLite3 ืื ืืืืื ืืืืืช ืจืืงื.
+err_admin_name_is_reserved = ืฉื ืืฉืชืืฉ ืืฉืืื ืืืขืจืืช ืื ืืืื, ืฉื ืืืฉืชืืฉ ืฉืืืจ
+err_admin_name_is_invalid = ืฉื ืืฉืชืืฉ ืื ืื ืืืขืจืืช ืื ืืืื
+domain = ืืืืืื ืืฉืจืช
+domain_helper = ืืืืืื ืื host address ืืฉืจืช ืื.
+http_port = ืคืืจื ืึพHTTP (ืืืื ื)
+http_port_helper = ืืคืืจื ืฉืืฉืืฉ ืืช ืืฃ ืืืื ืืจื ื (ืื ืฉืืคืืคื ื ืืื ืืจื ื ื ืืืฉืื ืืืื).
+app_url = ืืชืืืช (URL) ืืกืืก
+log_root_path_helper = ืืืื ืื (logfiles) ืืืืฆืื ืืชืืงืืื ืื.
+optional_title = ืืืืจืืช ืื ืืืื
+email_title = ืืืืจืืช ืืืืืื
+smtp_from = ืืืืืืืื ืืฉืืื ืึพ
+register_confirm = ืืืฉืืจ ืืืืืื ืืืื ืืจืืฉืื
+mail_notify = ืืคืขืืช ื ืืืืคืืงืฆืืืช ืืจื ืืืืืื
+offline_mode = ืืคืขืืช ืืฆื ืืืงืืื
+disable_registration = ืืฉืืชืช ืืจืฉืื ืขืฆืืืช
+allow_only_external_registration = ืืคืฉืืจ ืืจืฉืื ืจืง ืืจื ืฉืืจืืชืื ืืืฆืื ืืื
+openid_signup.description = ืืฉืืื ืืช ืืืืื ืืืืืืฆืจ ืืจื OpenID ืื ืืจืฉืื ืขืฆืืืช ืืืคืขืืช.
+enable_captcha.description = ืืื ืืืฆืืจ ืืฉืืื ืืช ืืืฉืื, ืืืื ืฆืจืื ืืขืืืจ ืืชืืจ CAPTCHA (ืืื ืื ืื ืกืคืื ืืืืืื; ืคืืืข ืื ืืืฉืืช ืืคืืืช ืืคืงืืืื ืื ืื AI ืืืืจื ื).
+default_keep_email_private = ืืกืชืจืช ืืชืืืืช ืืืืืื ืืืจืืจืช ืืืื
+default_allow_create_organization = ืืคืฉืืจ ืืฆืืจืช ืืจืืื ืื ืืืจืืจืช ืืืื
+default_enable_timetracking = ืืคืขืืช ืืืืืช ืืื ืืืจืืจืช ืืืื
+admin_title = ืืืืจืืช ืืฉืืื ืื ืื ืืขืจืืช
+admin_name = ืฉื ืืฉืชืืฉ ืฉื ืื ืื ืืขืจืืช
+admin_password = ืกืืกืื
+install_btn_confirm = ืกืืื ืืชืงื ืช ืคืืจื'ื
+test_git_failed = ืืืืงืช ืคืงืืืช "git" ื ืืฉืื: %v
+sqlite3_not_available = ืืจืกืช ืคืืจื'ื ืื ืื ืชืืืืช ืึพSQLite3. ื ื ืืืืจืื ืืช ืืืจืืืคืงื ืืจืฉืื ื %s (*ืื* ืืช ืืจืกืช ื"gobuild").
+invalid_db_setting = ืืืืจืืช ืืกื ืืืืืข ืฉืืืืืช: %v
+invalid_db_table = ืืืืช ืืกื ืืืืืข "%s" ืฉืืืื: %v
+run_user = ืืฉืชืืฉ ืฉืคืืจื'ื ืืจืืฅ ืชืืช
+mailer_password = ืกืืกืืช ืฉืจืช ืึพSMTP
+mailer_user = ืฉื ืืฉืชืืฉ ืืฉืจืช ืึพSMTP
+federated_avatar_lookup = ืืคืขืืช ืชืืื ืืช ืคืจืืคืื ืืืืืจืืช
+disable_gravatar = ืืฉืืชืช Gravatar
+disable_gravatar.description = ืฉืืืืฉ ืืืจืืืืืืจ, ืื ืื ืืงืืจ ืฆืึพืฉืืืฉื ืืืจ ืืชืืื ืืช ืคืจืืคืื, ืืืฉืืช. ืืื ืื ืื ืืืฉืืื ืืฉ ืชืืื ื ืฉืืืขืืชื ืืื ืืช, ืคืืจื'ื ืืฉืชืืฉ ืืชืืื ืืช ืืจืืจืช ืืืืื ืืืืงืืืืืช.
+openid_signin = ืืคืขืืช ืื ืืกื ืืจื OpenID
+no_admin_and_disable_registration = ืื ืืคืฉืจ ืืืกืื ืืจืฉืื ืขืฆืืืช ืืื ืืืฆืืจ ืืฉืืื ืื ืื ืืขืจืืช.
+app_name_helper = ืฉื ืืืชืจ ื ืื ืก ืืื. ืืื ืืืฆื ืืื ืืงืื ืืืชืจ, ืืฆื ืืืื ืืืขืื (ืื ืืื ืืืืช, ืฉืืื ืืืขืื).
+app_slogan = ืกืืืื ืืืชืจ
+app_slogan_helper = ืกืืืื ืืืชืจ ื ืื ืก ืืื. ืคืืจื'ื ืืชืขืื ืืกืืืื ืจืืง.
+ssh_port = ืคืืจื ืฉืจืช ืึพSSH
+ssh_port_helper = ืืกืคืจ ืืคืืจื ืฉืฉืจืช ืึพSSH ืืฉืชืืฉ ืื. ืขืจื ืจืืง ืืืื ืืช ืืชืืืื ืึพSSH.
+smtp_addr = ืฉืจืช SMTP
+smtp_from_helper = ืืชืืืช ืืืืืืื ืฉืคืืจื'ื ืืฉืื ืืื ื ืืืืขืืช ืืืฉืชืืฉืื. ืืคืฉืจ ืืืื ืืก ืืชืืืช ืืืืื ืคืฉืืื ืื ืืืืฉืืชืฉ ืืคืืจืื "ืฉื" <ืืืืืื@ืืืืื.ืงืื>.
+server_service_title = ืืืืจืืช ืฉืจืช ืืฉืืจืืชืื ืฆื ืฉืืืฉื
+offline_mode.description = CDNึพืื ืฆื ืฉืืืฉื ืืืฉืืชื ืืื ืืืฉืืืื ืืืืฉื ืืืืืฉื ืื ืืืื, ืืื ืืืฉื ืืืื ืืจื ื.
+disable_registration.description = ืจืง ืื ืืื ืืขืจืืช ืืืืื ืืืฆืืจ ืืฉืืื ืืช ืืฉืชืืฉ ืืืฉืื. ืืืื ืื ืืืืืฅ ืืืคืขืื ืืจืฉืื ืขืฆืืืช ืืื ืื ืื ืืืืื ืชื ืืืฆืืจ ืฉืจืช ืฆืืืืจื, ืืืจ ืืืืื ืืชืขืกืงืืช ืืืืืืืช ืขืฆืืืืช ืฉื ืกืคืื ืืืชืงืคืืช DDoS.
+allow_only_external_registration.description = ืืฉืืื ืืช ืืืฉืื ืื ืืืืื ืืืืืืฆืจ ืืืงืืืืช, ืืื ืจืง ืืจื ืฉืืจืืชืื ืฆืึพืฉืืืฉื ืฉืงืื ืคืื ืืจืืฉ.
+openid_signup = ืืคืขืืช ืืจืฉืื ืขืฆืืืช ืืจื OpenID
+enable_captcha = ืืคืขืืช CAPTCHA ืืชืืืื ืืจืืฉืื
+require_sign_in_view = ืฉืจืช ืคืจืื
+require_sign_in_view.description = ืืืฉื ืืชืืื ืืฉืจืช ืชืืืกื ืืื ืื ืืกื ืืืฉืืื, ืืืขื ืืคื ืืจืืฉืื ืืืื ืืกื.
+default_keep_email_private.description = ืืชืืืืช ืืืืืืื ืฉื ืืฉืืื ืืช ืืืฉืื ืื ืืืฆืื ืขื ืืคืจืืคืืืื ืืฆืืืืจืืื ืฉืืื (ืืื ืื ืื ืืฉื ื ืืืช ืืขืฆืื), ืืื ืืื ืืข ืืืืื ืฉื ืืืืข ืคืจืื ืืื ืืืืจ ืืืจืฉืื.
+default_allow_create_organization.description = ืืฉืืื ืืช ืืืฉืื ืืืืื ืืืฆืืจ ืืจืืื ืื ืืื ืืืฉืืจ ืื ืื ืืืขืจืืช.
+err_admin_name_pattern_not_allowed = ืฉื ืืฉืชืืฉ ืื ืื ืืืขืจืืช ืื ืืืื, ืฉื ืืืฉืชืืฉ ืขืื ื ืขื ืชืื ืืช ืฉืืืจื
+run_user_helper = ืฉื ืืืฉืชืืฉ ืฉื ืืฉืชืืฉ ืืขืจืืช ืืืคืขืื ืฉืคืืจื'ื ืืจืืฅ ืชืืชืื. ืืืฉืชืืฉ ืืืืืช ืืืืืช ืืืฉื ืืงืจืคืืคืื.
+log_root_path = ืืชืืืช ืืืืื ื
+smtp_port = ืคืืจื SMTP
+default_enable_timetracking.description = ืชืืื ืช ืืืืืช ืืืื ืฉื ืคืืจื'ื ืชืืคืขื ืืงืจืคืืคืื ืืืฉืื ืืืจืืจืช ืืืื.
+admin_setting.description = ืืฆืืจืช ืืฉืืื ืื ืื ืืืขืจืืช ืืื ืื ืืืื; ืืื ืืฉืืื ืืืจืฉื, ืืืฉืืื ืืจืืฉืื ืฉืืืืฆืจ ืืงืื ืืจืฉืืืช ืืืืื ืืกืืจืฆืื.
+config_location_hint = ืืืืจืืช ืืื ืืฉืืจื ืึพ:
+confirm_password = ืกืืกืื (ืฉืื)
+admin_email = ืืชืืืช ืืืืืื
+require_db_desc = ืคืืจื'ื ืืืจืฉ MySQL, PostgreSQL, ืื TiDB (ืืจื ืคืจืืืืงืื MySQL).
+
+[aria]
+navbar = ืกืจืื ืื ืืืื
+footer.software = ืขื ืชืืื ื ืื
+footer.links = ืงืืฉืืจืื
+footer = ืกืืืืช ืขืืื
+
+[mail]
+repo.transfer.subject_to_you = %s ืจืืฆื ืืืขืืืจ ืืช ืืงืจืคืืฃ "%s" ืืืื
+repo.collaborator.added.text = ืืืกืคืช ืืชืืจ ืคืืขื ืืงืจืคืืฃ:
+issue_assigned.issue = @%[1]s ืฉืืื ืืืชื ืืกืืืื %[2]s ืืงืจืคืืฃ %[3]s.
+issue_assigned.pull = @%[1]s ืฉืืื ืืืชื ืืืงืฉืช ืืืืืื %[2]s ืืงืจืคืืฃ %[3]s.
+repo.transfer.subject_to = %s ืจืืฆื ืืืขืืืจ ืืช ืืงืจืคืืฃ "%s" ืึพ%s
+
+[form]
+RepoName = ืฉื ืงืจืคืืฃ
+repository_force_private = ืคืจืืืืช ืืคืืื ืืืคืขืืช: ืงืจืคืืคืื ืคืจืืืื ืื ืืืืืื ืืืขืฉืืช ืฆืืืืจืืื.
+repo_name_been_taken = ืืืจ ืืฉ ืงืจืคืืฃ ืืฉื ืื.
+repository_files_already_exist = ืืืจ ืืฉ ืงืืฆืื ืืงืจืคืืฃ ืื. ืืฉ ืืืืจ ืขื ืื ืื ืืืขืจืืช ืืื ืืชืงื ืืช ืืืขืื.
+AccessToken = ืงืื ืืืฉื
+Content = ืชืืื
+SSPIDefaultLanguage = ืฉืคืช ืืจืืจืช ืืืื
+
+[projects]
+deleted.display_name = ืคืจืืืงื ื ืืืง
+
+[home]
+my_repos = ืงืจืคืืคืื
+my_orgs = ืืจืืื ืื
+show_archived = ืืืจืืืื
+show_only_unarchived = ืื ืืืื ืืช ืืืจืืืื
+show_private = ืคืจืื
+filter_by_team_repositories = ืกืื ืื ืืคื ืงืจืคืืคื ืฆืืืช
+uname_holder = ืฉื ืืฉืชืืฉ ืื ืืชืืืช ืืืืืื
+filter = ืืกื ื ืื ืืืจืื
+feed_of = ืคืื ืฉื "%s"
+show_both_archived_unarchived = ืืืื ืื ืืชืื ืืื ืืืืฅ ืืืจืืืื
+show_only_archived = ืืืื ืจืง ืืืืจืืืื
+issues.in_your_repos = ืืงืจืคืืคืื
+
+[explore]
+repos = ืงืจืคืืคืื
+stars_one = ืืืื ืืื
+stars_few = %d ืืืืืื
+code = ืงืื
+code_last_indexed_at = ืืื ืืงืก ืืืืจืื ื %s
+users = ืื ืฉืื
+forks_few = %d ืืืืืืื
+organizations = ืืจืืื ืื
+relevant_repositories_tooltip = ืืืืืืื ืืงืจืคืืคืื ืืื ืชืืืืจ, ื ืืฉื, ืืกืื ืื ืืืฆืืื.
+relevant_repositories = ืจืง ืงืจืคืืคืื ืจืืืื ืืื ืืืฆืืื; ืืคืฉืจ ืืืฆืื ืชืืฆืืืช ืื ืืกืื ื ืืช .
+forks_one = ืืืืื ืืื
+
+[auth]
+change_unconfirmed_email_error = ืฉืื ืื ืืชืืืช ืืืืืืื ืืฉื: %v
+resend_mail = ืฉืืืืช ืืืื ืืืืืช ืืืฉ
+send_reset_mail = ืฉืืืืช ืืืื ืฉืืืืจ ืืฉืืื
+reset_password = ืฉืืืืจ ืืฉืืื
+invalid_code = ืงืื ืืืืืืช ืฉืื ืื ืชืงืฃ, ืื ืฉืขืืจ ืืืชืจ ืืื ืืื ืืื ืฉืืื ืคืง.
+invalid_password = ืืกืืกืื ืื ืชืืืืช ืืช ืืกืืกืื ืฉืืืชื ืืฆืจืช ืืช ืืฉืืื ื.
+reset_password_helper = ืฉืืืืจ ืืฉืืื
+reset_password_wrong_user = ื ืื ืกืช ืึพ%s, ืืื ืืงืืฉืืจ ื ืืขื ืืฉืืืืจ ืืืฉืืื ืฉื %s
+password_too_short = ืืกืืกืื ืืืืืช ืืืืืช ืืืืจื %d ืชืืืื ืืืขืื.
+non_local_account = ืืฉืืื ืืช ืึพืืืงืืืืื ืื ืืืืืื ืืขืืื ืืช ืกืืกืืชื ืืจื ืืชืจ ืืืื ืืจื ื ืฉื ืคืืจื'ื.
+verify = ืืืืืช
+use_onetime_code = ืฉืืืืฉ ืืงืื ืืึพืคืขืื
+disable_register_mail = ืืืฉืืจ ืืจืฉืื ืืจื ืืืืืื ืืืฉืืช.
+remember_me = ืื ืืืืฉืืจ ืฉืื ืืื ื ืจืืฆื ืืฉืืืจ ืขืืื ืืช ืืกืืกืื ืฉืื ืืคืขื ืืืื
+hint_login = ืืืจ ืืฉ ืื ืืฉืืื? ืื ืืกื
+sign_up_successful = ืืืฉืืื ื ืืฆืจ ืืืฆืืื. ืืจืืืื ืืืืื!
+create_new_account = ืืจืฉืื
+disable_register_prompt = ืืจืฉืื ืืืฉืืชืช. ืืฉ ืืืืจ ืขื ืื ืืื ืืืขืจืืช.
+manual_activation_only = ืืฉ ืืืืจ ืขื ืื ืืื ืืืขืจืืช ืืื ืืืฉืืื ืืช ืืคืขืืช ืืฉืืื ื.
+forgot_password_title = ืฉืืืชื ืืช ืืกืืกืื
+sign_up_button = ืืจืฉืื
+must_change_password = ืขืืื ืกืืกืืชื
+prohibit_login = ืืฉืืื ื ืืืฉืขื
+change_unconfirmed_email = ืื ื ืชืช ืืช ืืชืืืช ืืืืืืื ืืื ื ืืื ื ืืฉื ืจืฉืืช, ืืคืฉืจ ืืฉื ืืช ืืืชื ืืื, ืืืืื ืืืืืช ืืืฉ ืืฉืื ืืืชืืืช ืืืืฉื.
+forgot_password = ืฉืืืช ืืช ืืกืืกืื?
+hint_register = ืืื ืื ืืฉืืื? ืืจืฉืื
+active_your_account = ืืคืขืืช ืืฉืืื ื
+prohibit_login_desc = ืืฉืื ืื ืืืฉืขื ืืฉืจืช ืื. ืืคืฉืจ ืืืงืฉ ืืื ืืื ืืืขืจืืช ืืชืช ืื ืืืฉื.
+invalid_code_forgot_password = ืงืื ืืืืืืช ืฉืื ืื ืชืงืฃ, ืื ืฉืขืืจ ืืืชืจ ืืื ืืื ืืื ืฉืืื ืคืง. ืืคืฉืจ ืื ืกืืช ืฉืื .
+allow_password_change = ืืืจืืช ืืืฉืชืืฉ ืืขืืื ืืช ืกืืกืืช ืืฉืืื ื (ืืืืืฅ)
+account_activated = ืืฉืืื ื ืืืคืขื
+resent_limit_prompt = ืืืจ ืืืงืฉืช ืืืื ืืืืืช ืืฉืืืฉืช ืืืงืืช ืืืืจืื ืืช. ื ื ืืืืืช ืืื ืกืืช ืฉืื.
+has_unconfirmed_mail = ืฉืืื %s, ืืฉืืื ื ืืฉืืื ืืืชืืืช ืืืืืื ืื ืืืืืชืช (%s ). ืื ืื ืงืืืืช ืืืืขืช ืืืืืช ืืืืืืื, ืื ืฉืืชื ืฆืจืื ืืืฉื, ื ื ืืืืืฅ ืขื ืืืคืชืืจ ืืืื.
+
+[settings]
+key_content = ืชืืื
+principal_content = ืชืืื
+add_gpg_key_success = ืืคืชื ืึพGPG "%s" ืืืกืฃ ืืืฉืืื ื.
+gpg_key_deletion_success = ืืคืชื ืึพGPG ืืืกืจ ืืืฉืืื ื.
+valid_until_date = ืชืงืฃ ืขื ืึพ%s
+can_write_info = ืฉืื ืื
+ssh_disabled = SSH ืืืฉืืช
+ssh_externally_managed = ืืคืชื SSH ืื ืื ืืื ืืืฆืื ืืช
+repo_and_org_access = ืืืฉื ืืงืจืคืืคืื ืืืจืืื ืื
+permissions_public_only = ืฆืืืืจื ืืืื
+permissions_access_all = ืืื (ืฆืืืืจื, ืคืจืื, ืืืืื)
+manage_access_token = ืงืืื ืืืฉื
+generate_new_token = ืงืื ืืืฉื ืืืฉ
+token_name = ืฉื ืงืื ืืืืฉื
+access_token_deletion = ืืืืงืช ืงืื ืืืฉื
+delete_token_success = ืงืื ืืืืฉื ื ืืืง. ืืคืืืงืฆืืืช ืฉืืฉืชืืฉื ืื ืื ืืืืืืช ืืืฉืช ืืืฉืืื ืฉืื ืืืชืจ.
+permission_no_access = ืฉืื ืืืฉื
+permission_read = ืงืจืืื
+permission_write = ืงืจืืื ืืฉืื ืื
+permissions_list = ืืจืฉืืืช:
+edit_oauth2_application = ืขืจืืืช ืืคืืืงืฆืืช OAuth2
+remove_oauth2_application = ืืกืจืช ืืคืืืงืฆืืช OAuth2
+remove_oauth2_application_success = ืืืคืืืงืฆืื ื ืืืงื.
+create_oauth2_application_button = ืืฆืืจืช ืืคืืืงืฆืื
+create_oauth2_application_success = ืืฆืจืช ืืคืืืงืฆืืืช OAuth2 ืืืฉื ืืืฆืืื.
+update_oauth2_application_success = ืขืจืืช ืืคืืืงืฆืืืช OAuth2 ืืืฆืืื.
+oauth2_application_name = ืฉื ืืืคืืืงืฆืื
+oauth2_redirect_uris = ืงืืฉืืจื ืืคื ืื ืืืืฉ. ืื ืงืืฉืืจ ืืฉืืจื ืืฉื ืขืฆืื.
+save_application = ืฉืืืจื
+oauth2_application_edit = ืขืจืืื
+revoke_oauth2_grant = ืืกืจืช ืืืฉื
+ssh_key_deletion_success = ืืคืชื ืึพSSH ืืืกืจ ืืืฉืืื ื.
+delete_key = ืืกืจื
+ssh_key_deletion = ืืกืจืช ืืคืชื SSH
+gpg_key_deletion = ืืกืจืช ืืคืชื GPG
+ssh_key_deletion_desc = ืืกืจืช ืืคืชื SSH ืืืืืช ืืช ืืืฉืชื ืืืฉืืื ื. ืืืืฉืื?
+gpg_key_deletion_desc = ืืกืจืช ืืคืชื GPG ืืืคืืช ืงืืืืืื ืฉื ืืชืื ืืขืืจืชื ืืืึพืืืืืชืื. ืืืืฉืื?
+show_openid = ืืฆืื ืขื ืคืจืืคืืื
+hide_openid = ืืกืชืจื ืืคืจืืคืืื
+generate_token_name_duplicate = ืืืจ ืงืืืืช ืืคืืืงืฆืื ืืฉื %s .
+delete_token = ืืืืงื
+generate_token_success = ืงืื ืืืืฉื ืืืืฉ ื ืืฆืจ, ืืื ืืืฆื ืฉืื.
+add_key_success = ืืคืชื ืึพSSH "%s" ืืืกืฃ ืืืฉืืื ื.
+added_on = ืืืกืฃ ืึพ%s
+last_used = ืฉืืืฉ ืืืืจืื ื ื
+select_permissions = ืืืืจืช ืืจืฉืืืช
+key_name = ืฉื ืืืคืชื
+key_state_desc = ืืคืชื ืื ืฉืืืฉ ืืฉืืืข ืืืืจืื
+ssh_signonly = SSH ืืืฉืืช; ืืคืชืืืช ืืื ืืฉืืฉื ืจืง ืืื ืืืชืื ืงืืืืืื.
+manage_oauth2_applications = ื ืืืื ืืคืืืงืฆืืืช OAuth2
+create_oauth2_application = ืืฆืืจืช ืืคืืืงืฆืืืช OAuth2 ืืืฉื
+can_read_info = ืงืจืืื
+valid_forever = ืชืงืฃ ืื ืฆื
+revoke_key = ืืกืจืช ืืืฉื
+at_least_one_permission = ืงืืื ืืืฉื ืฆืจืืืื ืืคืืืช ืืจืฉืื ืืืช
+access_token_deletion_desc = ืืคืืืงืฆืืืช ืฉืืฉืชืืฉืืช ืืงืื ืืืืฉื ืืื ืื ืืืืื ืืืฉืช ืืืฉืืื ืฉืื ืืืชืจ. ืืืื ืคืขืืื ืืืชืึพืืคืืื. ืืืืฉืื?
+delete_account = ืืืืงืช ืืืฉืืื
+confirm_delete_account = ืื, ืื ื ืจืืฆื ืืืืืง ืืช ืืืฉืืื ืฉืื
+delete_account_desc = ืืืืืง ืืช ืืฉืืื ืืฉืชืืฉ ืื ืื ืฆื?
+email_notifications.enable = ืืคืขืืช ืืืืขืืช ืืืืืื
+email_notifications.disable = ืืฉืืชืช ืืืืขืืช ืืืืืื
+email_notifications.submit = ืืืืจืช ืืืืืื ืืืขืืฃ
+visibility.public = ืฆืืืืจื
+visibility = ืกืื ืืฉืืื
+visibility.public_tooltip = ื ืืืฉ ืืืืื
+visibility.limited = ืืืืื
+visibility.limited_tooltip = ื ืืืฉ ืจืง ืืื ืฉืืฉ ืื ืืฉืืื
+visibility.private = ืคืจืื
+blocked_since = ืืกืื ืืืจ %s
+user_block_success = ืืืฉืชืืฉ ื ืืกื.
+user_unblock_success = ืืืกืืื ืืืืื.
+user_block_yourself = ืื ืืคืฉืจ ืืืกืื ืืช ืืืฉืืื ืฉื ืขืฆืื.
+delete_prompt = ืคืขืืื ืื ืืืชื ืืคืืื ืืชืืืืง ืืช ืืืฉืืื ืฉืื ืืืืืืื .
+email_notifications.onmention = ืฉืืืืช ืืืืืืืื ืจืง ืขืืืจ ืืืืืจ (mention\ping) ืืคืืจืฉ
+delete_account_title = ืืืืืงืช ืืฉืืื ืืฉืชืืฉ
+visibility.private_tooltip = ื ืืืฉ ืจืง ืืื ืฉืืืจ ืืืจืืื ืฉืืชื ืืืง ืืื ื
+delete_with_all_comments = ืืฉืืื ื ื ืืฆืจ ืืคื ื ืคืืืช ืึพ%s; ืื ืืชืืืืืช ืฉืื (ืืกืืืืืช, ืืงืฉืืช ืืืืื, ืืืืื) ืืืืงื.
+update_avatar = ืขืืืื ืชืืื ืช ืคืจืืคืื
+delete_current_avatar = ืืืืงืช ืชืืื ืช ืืคืจืืคืื ืื ืืืืืช
+uploaded_avatar_not_a_image = ืืงืืืฅ ืฉืืืขืื ืื ืชืืื ื.
+
+[repo]
+new_advanced = ืืืืจืืช ืืชืงืืืืช
+new_advanced_expand =
+owner = ืืขืืื
+repo_name = ืฉื ืืงืจืคืืฃ
+repo_name_helper = ืฉืืืช ืงืจืคืืคืื ืืืืื ืื ืืืืจืื, ืงืฆืจืื ืืืืืืืืื.
+fork_branch = ืืขื ืฃ ืฉืืืขืชืง ืืืืืื
+all_branches = ืื ืืขื ืคืื
+use_template = ืงืจืคืืฃ ืืืฉ ืืชืื ืืช ืื
+repo_desc = ืชืืืืจ
+repo_desc_helper = ืชืืืืจ ืงืฆืจ (ืื ืืืื)
+issue_labels = ืชืืืืืช
+issue_labels_helper = ืชืืืืืช ืืืืืื ื ืคืืฆืืช ืืืืืืฆืืช ืฉืืคืฉืจ ืืืชืืื ืืืจืืฉืืช ืืคืจืืืงื ืืกืคืฆืืคื
+license = ืจืืฉืืื
+license_helper_desc = ืจืืฉืืื ืืช ืืืชืืืืช ืื ืืืจืื ืืืืืื ืืื ืืืืืื ืืขืฉืืช ืขื ืืงืื ืฉืื. ืืื ืืืืืจ ืจืืฉืืื?
+object_format = ืืืืืจืืชื ืืืืื
+readme = ืงืจืึพืืืชื
+readme_helper = ืชืื ืืช ืงืืืฅ ืงืจืึพืืืชื (README)
+readme_helper_desc = ืืื ืืคืฉืจ ืืืชืื ืืช ืืชืืืืจ ืืืื ืฉื ืืคืจืืืงื ืฉืื, ืืื ืืืจ ืฉืืจืฆืื ื ืฉืื ืฉืื ืืืขื ืขืืื.
+auto_init = ืชืืืื ืืงืจืคืืฃ
+auto_init_description = ืคืืจื'ื ืืืคืฉืจ ืืืืกืืฃ ืงืืฆื ืงืจืึพืืืชื, .gitignore, ืืจืฉืืื ืืช ืืงืืืื ืืจืืฉืื ืฉื ืืงืจืคืืฃ ืฉืื.
+create_repo = ืงืจืคืืฃ ืืืฉ
+mirror_public_key = ืืคืชื SSH ืฆืืืืจื
+mirror_use_ssh.not_available = ืืืืืช ืขืึพืืกืืก SSH ืื ืืืื.
+mirror_denied_combination = ืื ืืคืฉืจ ืืืฉืชืืฉ ืืืืืืช ืขืึพืืกืืก ืื ืกืืกืื ืืื ืืคืชื ืฆืืืืจื; ืืืื ืืืืืจ ืจืง ืืืคืฉืจืืช ืืืช.
+mirror_sync = ืืกืื ืืจื
+mirror_address = ืฉืืคืื ืืืชืืืช ืืื ืืจื ื (URL)
+mirror_lfs_desc = ืฉืืงืืฃ ืืืกืื ืงืืฆืื ืืืืืื (LFS)
+mirror_last_synced = ืกืื ืืจื ืืืืจืื ื
+stargazers = ืืืืืื
+forks = ืืืืืืืื
+stars = ืืืืืื
+reactions_more = ืืขืื %d
+unit_disabled = ืื ืืื ืืืขืจืืช ืืฉืืืชื ืชืืื ืช ืงืจืคืืฃ ืืืช.
+language_other = ืืืจืช
+adopt_preexisting_content = ืงืจืคืืฃ ืืืฉ ืึพโ%s
+delete_preexisting_label = ืืืืงื
+delete_preexisting = ืืืืงืช ืงืืฆืื ืงืืืืื
+delete_preexisting_content = ืืืืงืช ืงืืฆืื ืึพ%s
+summary_card_alt = ืงืืฃ ืชืงืฆืืจ ืืงืจืคืืฃ %s
+tree_path_not_found_branch = ืืืชืืืช %[1]s ืื ืงืืืืช ืืขื ืฃ %[2]s
+transfer.accept = ืืืฉืืจ ืืขืืจืช ืืงืจืคืืฃ
+tree_path_not_found_tag = ืืืชืืืช %[1]s ืื ืงืืืืช ืืชืืืช %[2]s
+transfer.reject = ืืืืืช ืืขืืจืช ืืงืจืคืืฃ
+transfer.reject_desc = ืืืืื ืืขืืจืช ืืงืจืคืืฃ ืึพ"%s"
+transfer.no_permission_to_reject = ืืื ืื ืืจืฉืื ืืืืืช ืืช ืืขืืจืช ืืงืจืคืืฃ ืืื.
+desc.private = ืคืจืื
+desc.public = ืฆืืืืจื
+desc.internal = ืคื ืืื
+desc.archived = ืืืจืืืื
+archive.issue.nocomment = ืงืจืคืืฃ ืื ืืืจืืืื. ืื ืืคืฉืจ ืืืืื ืืกืืืืืช.
+archive.pull.noreview = ืงืจืคืืฃ ืื ืืืจืืืื. ืื ืืคืฉืจ ืืืงืจ ืืงืฉืืช ืืืืื.
+form.reach_limit_of_creation_n = ืืืฉืืื ืฉื ืืืขืืื ืืืจ ืืืืข ืืืืืช ืืงืจืคืืคืื ืืืงืกืืืืืช (%s).
+form.name_reserved = ืฉื ืืงืจืคืืฃ "%s" ืฉืืืจ.
+migrate_items_wiki = ืืืงื
+migrate_items_issues = ืกืืืืืช
+migrate_items_pullrequests = ืืงืฉืืช ืืืืื
+migrate.clone_address = ืืืืื \ ืฉืืคืื ืึพURL
+migrated_from = ืืืื ืโึพ%[2]s
+migrated_from_fake = ืืืื ืึพ%[1]s
+migrate.migrate = ืืืื ืึพ%s
+migrate.migrating = ืคืืจื'ื ืืชืืืืื ืืืื ืึพ%s ...
+migrate.migrating_failed = ืืืืื ื%s ื ืืฉื.
+migrate.migrating_failed.error = ืืืืืื ื ืืฉื: %s
+migrate.migrating_failed_no_addr = ืืืืืื ื ืืฉื.
+migrate.git.description = ืืืืื ืงืจืคืืฃ ืืื ืฉืืจืืช ืืื ืฉืืื.
+migrate.forgejo.description = ืืืืื ืืืืข ืืงืืืืจื ืื ืฉืจืช ืคืืจื'ื ืืืจ.
+migrate.gitea.description = ืืืืื ืืืืข ืึพgitea.com ืื ืฉืจืช ืืืืื ืืืจ.
+migrate.gogs.description = ืืืืื ืืืืข ืึพnotabug.org ืื ืฉืจืช ืืืืก ืืืจ.
+migrate.onedev.description = ืืืืื ืืืืข ืึพcode.onedev.io ืื ืฉืจืช OneDev ืืืจ.
+migrate.codebase.description = ืืืืื ืืืืข ืึพcodebasehq.com.
+migrate.migrating_topics = ืืืืื ื ืืฉืืื
+migrate.migrating_milestones = ืืืืื ืืื ื ืืจื
+editor.delete_this_file = ืืืืงืช ืงืืืฅ
+editor.name_your_file = ืฉื ืืงืืืฅโฆ
+editor.or = ืื
+editor.cancel_lower = ืืืืื
+editor.add_tmpl = ืืืกืคืช "<%s>"
+editor.add_tmpl.filename = ืฉื ืืงืืืฅ
+editor.add = ืืืกืคืชื ืืช %s
+editor.update = ืขืืืื ืชื ืืช %s
+editor.delete = ืืืงืชื ืืช %s
+editor.propose_file_change = ืืฆืขืช ืืฉืื ืื
+editor.directory_is_a_file = ืื ืืคืฉืจ ืืืฆืืจ ืืช ืืชืืงืืื "%s"; ืืืจ ืงืืื ืงืืืฅ ืชืืช ืืืชื ืฉื.
+default_branch_label = ืืจืืจืช ืืืื
+default_branch = ืขื ืฃ ืืจืืจืช ืืืืื
+migrate_options_mirror_helper = ืงืจืคืืฃ ืื ืืืื ืืจืื
+migrate_options_lfs = ืืืืื ืืืกืื ืงืืฆืื ืืืืืื (LFS)
+migrate_options = ืืคืฉืจืืืืช ืืืืื
+migrate.migrating_labels = ืืืืื ืชืืืืืช
+migrate.migrating_releases = ืืืืื ืืจืกืืืช
+editor.file_delete_success = ืืงืืืฅ "%s" ื ืืืง.
+editor.commit_message_desc = ืชืืืืจ ืืจืื ืื ืืืืโฆ
+already_forked = ืืืจ ืืืืืช ืืช %s
+download_tar = ืืืจืื ืึพ.tag.gz
+open_with_editor = ืคืชืืื ืขื %s
+download_zip = ืืืจืื ืึพ.zip
+repo_lang = ืฉืคื
+repo_gitignore_helper = ืชืื ืืช .gitignore
+editor.new_branch_name_desc = ืฉื ืืขื ืฃ ืืืืฉโฆ
+editor.cancel = ืืืืื
+editor.filename_cannot_be_empty = ืฉื ืืงืืืฅ ืื ืืืื ืืืืืช ืจืืง.
+editor.new_branch_name = ืฉื ืืขื ืฃ ืฉืืืื ืืงืืืื ืืืืฃ
+editor.filename_is_invalid = ืฉื ืืงืืืฅ ืื ืชืงืื: "%s".
+editor.invalid_commit_mail = ืืชืืืช ืืืืืื ืื ืื ืืืงืืช ืืืืจืืช ืืฆืืจืช ืงืืืืืื.
+editor.branch_does_not_exist = ืืขื ืฃ "%s" ืื ืงืืื ืืงืจืคืืฃ ืื.
+editor.branch_already_exists = ืืขื ืฃ "%s" ืืืจ ืงืืื ืืงืจืคืืฃ ืื.
+repo_gitignore_helper_desc = ืืืืื ืงืืฆืื ืืื ืืชืขืื. ืืชืคืจืื ืืืื ืจืฉืืืืช ืงืืฆืื ืืืฉืืืืืช ืืฉืคืืช ืื ืกืคืจืืืช ื ืคืืฆืืช. ืืจืืืคืงืืื ืืืคืืกืืื ืืืืืื ื.gitignore ืืืจืืจืช ืืืื.
+object_format_helper = ืืืืืจืืชื ืืืืืื ืฉืืงืจืคืืฃ ืืฉืชืืฉ ืื. ืื ืืคืฉืจ ืืฉื ืืช ืืช ืืืืืจื ืืื. ืึพSHA1 ืืชืืืืืช ืืืืื ืืืืชืจ ืขื ืชืืื ืืช ืืืจืืช.
+mirror_sync_on_commit = ืกื ืืจืื ืืฉืงืืืืืื ืืืืขืื ืืฉืจืช ืืืงืืื
+author_search_tooltip = ืืงืกืืืื 30 ืืฉืืื ืืช ืืืฆืืื
+tree_path_not_found_commit = ืืืชืืืช %[1]s ืื ืงืืืืช ืืงืืืื %[2]s
+form.reach_limit_of_creation_1 = ืืืฉืืื ืฉื ืืืขืืื ืืืจ ืืืืข ืืืืืช ืืงืจืคืืคืื ืืืงืกืืืืืช (ืืื).
+new_from_template = ืงืจืคืืฃ ืืืฉ ืืชืื ืืช
+fork_no_valid_owners = ืงืจืคืืฃ ืื ืื ืืฉืืื ืืืขืืื ืชืงืคืื; ืื ืืคืฉืจ ืืืืืื.
+template.webhooks = Webhookึพืื
+template.topics = ื ืืฉืืื
+stars_remove_warning = ืคืขืืื ืื ืชืกืืจ ืืืงืจืคืืฃ ืืช ืื ืืืืืืื.
+owner_helper = ืืจืืื ืื ืฉืืืจ ืืฆืจื ืืช ืืืืช ืืงืจืคืืคืื ืืืงืกืืืืืช ืื ืืืฆืืื ืืชืคืจืื.
+fork_to_different_account = ืืืืื ืืืฉืืื ืืืจ
+archive.pull.nocomment = ืงืจืคืืฃ ืื ืืืจืืืื. ืื ืืคืฉืจ ืืืืื ืืืงืฉืืช ืืืืื.
+migrate_items_releases = ืืจืกืืืช
+migrate.permission_denied = ืืื ืื ืืจืฉืื ืืืืื ืงืจืคืืคืื ืืืฉืจืช ืื ืืืื.
+fork_repo = ืืืืื
+watchers = ืื ืืืื
+transfer.accept_desc = ืืขืืจื ื "%s"
+desc.template = ืชืื ืืช
+archive.title = ืงืจืคืืฃ ืื ืืืจืืืื. ืืคืฉืจ ืืงืจืื ืงืืฆืื ืืืฉืืคื ืืืชื, ืืื ืื ืืคืฉืจ ืืืืืฃ ืืืื ืื ืืคืชืื ืกืืืืืช.
+archive.title_date = ืงืจืคืื ืื ืืืจืืืื ืืืจ %s. ืืคืฉืจ ืืฆืคืืช ืืงืืฆืื ืืืฉืืคื ืืืชื, ืืื ืื ืืคืฉืจ ืืืืืฃ ืืืื ืื ืืคืชืื ืกืืืืืช.
+form.name_pattern_not_allowed = ืืชืื ืืช "%s" ืื ืืืงืืช ืืชืื ืฉื ืฉื ืงืจืคืืฃ.
+mirror_use_ssh.helper = ืคืืจื'ื ืืฉืงืฃ ืืช ืืงืจืคืืฃ ืืจื ืืชืืืื ืืืืื ืืช ืฉื ืืื ืึพSSH, ืืืฆืืจ ืืฉืืืื ืืื ืืคืชืืืช ืืืืืืืืช. ืืืืจืืืชื ืืืืื ืฉืืืคืชื ืืฆืืืืจื ืฉืืืืฆืจ ืืืื ืืืฉื ืืงืจืคืืฃ ืืืขื. ืื ืืคืฉืจ ืืืฉืชืืฉ ืืื ืืกื ืขืึพืืกืืก ืกืืกืื ืขื ืืคืฉืจืืช ืื.
+mirror_lfs = ืืืกืื ืงืืฆืื ืืืืืื (LFS)
+migrate_items_labels = ืชืืืืืช
+migrate_repo = ืืืืื ืงืจืคืืฃ
+transfer.no_permission_to_accept = ืืื ืื ืืจืฉืื ืืืฉืจ ืืช ืืขืืจืช ืืงืจืคืืฃ ืืื.
+form.string_too_long = ืืืงืกื ืื ืชืื ืืจืื ืึพ%d ืชืืืื.
+migrate_items_milestones = ืืื ื ืืจื
+migrate.failed = ืืืืืื ื ืืฉื: %v
+migrate.migrate_items_options = ืคืืจื'ื ืฆืจืื ืงืื ืืืฉื ืืื ืืืืื ืืืืข ื ืืกืฃ
+migrate.github.description = ืืืืื ืืืืข ืึพgithub.com ืื ืฉืจืช GitHub Enteprise.
+migrate.gitlab.description = ืืืืื ืืืืข ืึพgitlab.com ืื ืืฉืจืชื GitLab ืืืจืื.
+migrate.gitbucket.description = ืืืื ืืืืข ืืฉืจืช GitBucket.
+migrate.migrating_git = ืืืืื ืืงืจืคืืฃ ืขืฆืื
+editor.filename_help = ืืคืฉืจ ืืืคืจืื ืืื ืชืืงืืืช ืขื ืกืืืฉืื, ื"ืืืืืง" ืชืืงืืืช ืขื backspace, ืืืืื ืืืื ืชืืืช ืืงืกื ืจืืืื.
+editor.filename_is_a_directory = ืื ืืคืฉืจ ืืงืจืื ืืงืืืฅ "%s"; ืืืจ ืงืืืืช ืชืืงืืื ืชืืช ืืืชื ืฉื.
+editor.file_editing_no_longer_exists = ืืงืืืฅ ืื ืขืจื ืฉืืื ืืืืข ืึพ"%s" ืื ืงืืื ืืืชืจ ืืงืจืคืืฃ ืื.
+editor.fail_to_update_file = ืืฆืืจืช\ืฉืื ืื ืืงืืืฅ "s" ื ืืฉืื.
+editor.push_rejected_summary = ืืืืขืช ืืืืื ืืืื:
+editor.add_subdir = ืืืกืคืช ืชืืงืืืโฆ
+editor.upload_file_is_locked = ืืงืืืฅ "%s" ื ื ืขื ืข"ื %s.
+editor.upload_files_to_dir = ืืขืืืช ืงืืฆืื ื"%s"
+editor.commit_email = ืืชืืืช ืืืืืืื ืืืฉืืืืช ืืงืืืื
+commits.commits = ืงืืืืืื
+commits.nothing_to_compare = ืขื ืคืื ืืื ืืืื.
+commits.search_branch = ืขื ืฃ ืื
+commits.message = ืืกืจ
+commits.date = ืชืืจืื
+commits.signed_by = ื ืืชื ืข"ื
+commits.signed_by_untrusted_user = ืืขื ืืชืืื ืื ืืืืื ืช
+commits.gpg_key_id = ืืืื ืืคืชื ืึพGPG
+commits.ssh_key_fingerprint = ืืืืขืช ืืฆืืข ืืคืชื ืึพSSH
+commitstatus.error = ืฉืืืื
+commitstatus.failure = ืืืฉืืื
+commitstatus.pending = ืืชืืืืืื
+commitstatus.success = ืืฆืืื
+ext_issues = ืกืืืืืช ืืืฆืื ืืืช
+projects = ืคืจืืืงืืื
+projects.desc = ืคืจืืืงืืื ืขืืืจืื ืื ืืืื ืืืจืืื ืกืืืืืช ืืืงืฉืืช ืืืืื.
+projects.title = ืืืชืจืช
+projects.description_placeholder = ืชืืืืจ...
+projects.description = ืชืืืืจ (ืื ืืืื)
+projects.create = ืคืจืืืงื ืืืฉ
+projects.new = ืคืจืืืงื ืืืฉ
+editor.commit_id_not_matching = ืชืืื ืงืืืฅ ืื ืืฉืชื ื ืืื ืฉืืชืืืช ืืขืจืื. ืืคืฉืจ ืืฉืืืจ ืืช ืืฉืื ืืืื ืืขื ืฃ ืืืฉ ืืืคืชืื ืืงืฉืช ืืืืื ืืืงืื.
+editor.file_deleting_no_longer_exists = ืืืืงืช ืืงืืืฅ ืฉืืื ืืืืข ืึพ"%s" ื ืืฉืื; ืืงืืืฅ ืื ืงืืื ืืืชืจ ืืงืจืคืืฃ ืื.
+editor.file_already_exists = ืืืจ ืืฉ ืงืืืฅ ืชืืช ืืฉื "%s" ืืงืจืคืืฃ ืื.
+editor.unable_to_upload_files = ืืขืืืช ืืงืืฆืื ืึพ"%s" ื ืืฉืื: %v
+commits.author = ืืืืจ
+editor.file_changed_while_editing = ืชืืื ืงืืืฅ ืื ืืฉืชื ื ืืื ืฉืืชืืืช ืืขืจืื. ืืคืฉืจ ืืจืืืช ืื ืืื ืืฉืื ืืืื ืื ืืืฆืืจ ืืช ืืงืืืื ืฉืื ืืื ืืืจืืก ืืืชื.
+commits.signed_by_untrusted_user_unmatched = ืืขื ืืชืืื ืื ืืืืื ืช ืฉืื ืชืืืืช ืืช ืืืืจ ืืงืืืื
+editor.no_changes_to_show = ืืื ืฉืื ืืืื ืืืฆืื.
+editor.fail_to_update_file_summary = ืืืืขืช ืฉืืืื:
+commits.search_all = ืื ืืขื ืคืื
+issues.create = ืกืืืืื ืืืฉื
+issues.edit = ืขืจืืื
+issues.cancel = ืืืืื
+issues.save = ืฉืืืจื
+issues.label_title = ืฉื
+issues.label_description = ืชืืืืจ
+issues.label_color = ืฆืืข
+issues.label_exclusive = ืืืืจื ืืืืืช
+issues.label_archive = ืืืจืืืื
+issues.label_archived_filter = ืืฆืืช ืชืืืืืช ืืืืจืืืื
+issues.label_archive_tooltip = ืชืืืืืช ืืืจืืืื ืื ืืืฆืขืืช ืืืืคืืฉ ืขืึพืืกืืก ืชืืืืช ืืืจืืจืช ืืืื.
+
+[translation_meta]
+test = ืืืืืช ืืจืขื ืืืื
\ No newline at end of file
diff --git a/options/locale/locale_hi.ini b/options/locale/locale_hi.ini
index f89a8483dd..59f66b4d0f 100644
--- a/options/locale/locale_hi.ini
+++ b/options/locale/locale_hi.ini
@@ -1,6 +1,42 @@
-
-
-
[common]
-dashboard = เคกเฅเคถเคฌเฅเคฐเฅเคก
-home = เคเคฐ
\ No newline at end of file
+dashboard = เคจเคฟเคฏเคเคคเฅเคฐเคฃ เคเคเฅเคท
+home = เคฎเฅเคเฅเคฏ เคชเฅเคทเฅเค
+help = เคธเคนเคพเคฏเคคเคพ
+logo = เคเคฟเคนเฅเคจ
+explore = เค
เคจเฅเคตเฅเคทเคฃ เคเคฐเฅเค
+sign_in = เคชเฅเคฐเคตเฅเคถ เคเคฐเฅเค
+sign_in_with_provider = %s เคเฅ เคธเคพเคฅ เคชเฅเคฐเคตเฅเคถ เคเคฐเฅเค
+sign_in_or = เคฏเคพ
+sign_out = เคฌเคพเคนเคฐ เคจเคฟเคเคฒเฅเค
+sign_up = เคชเคเคเฅเคเคฐเคฃ
+register = เคชเคเคเฅเคเคฐเคฃ
+version = เคธเคเคธเฅเคเคฐเคฃ
+powered_by = เคฆเฅเคตเคพเคฐเคพ เคธเคเคเคพเคฒเคฟเคค %s
+page = เคชเฅเคทเฅเค
+template = เคธเคพเคเคเคพ
+language = เคญเคพเคทเคพ
+active_stopwatch = เคธเคเฅเคฐเคฟเคฏ เคธเคฎเคฏ เคเฅเคฐเฅเคเคฐ
+create_new = เคฌเคจเคพเคเคโฆ
+signed_in_as = เคธเคพเคเคจ เคเคจ เคเคฟเคฏเคพ เคเคฏเคพ เคนเฅ
+link_account = เคเคพเคคเคพ เคฒเคฟเคเค เคเคฐเฅเค
+notifications = เคธเฅเคเคจเคพเคเค
+tracked_time_summary = เคธเคฎเคธเฅเคฏเคพเคเค เคเฅ เคธเฅเคเฅ เคเฅ เคซเคผเคฟเคฒเฅเคเคฐ เคเฅ เคเคงเคพเคฐ เคชเคฐ เคเฅเคฐเฅเค เคเคฟเค เคเค เคธเคฎเคฏ เคเคพ เคธเคพเคฐเคพเคเคถ
+user_profile_and_more = เคชเฅเคฐเฅเคซเคผเคพเคเคฒ เคเคฐ เคธเฅเคเคฟเคเคเฅเคธโฆ
+enable_javascript = เคเคธ เคชเคจเฅเคจเฅ เคเฅ เคฒเคฟเคฏเฅ เคเคพเคตเคพ เคเคพเคนเคฟเค
+toc = เคตเคฟเคทเคฏ เคธเฅเคเฅ
+licenses = เคฒเคพเคเคธเฅเคเคธ
+return_to_forgejo = เฅเฅเคฐเฅเคเฅเคเฅ เคชเฅ เคตเคพเคชเคธ เคเคพเคเค
+more_items = เคเคฐ เคตเคธเฅเคคเฅเคเค
+username = เคฏเฅเคเคฐเคจเคพเคฎ
+email = เคเคฎเฅเคฒ เคชเคคเคพ
+password = เคชเคพเคธเคตเคฐเฅเคก
+re_type = เคชเคพเคธเคตเคฐเฅเคก เคชเคเฅเคเคพ เคเคฐเฅเค
+captcha = เคเฅเคชเฅเคเคพ
+twofa = เคเฅ-เคซเฅเคเฅเคเคฐ เคเคฅเฅเคเคเคฟเคเฅเคถเคจ
+twofa_scratch = เคเฅ-เคซเฅเคเฅเคเคฐ เคธเฅเคเฅเคฐเฅเค เคเฅเคก
+passcode = เคชเคพเคธ เคเฅเคก
+repository = เคญเคเคกเคพเคฐ
+organization = เคธเคเคเค เคจ
+mirror = เคเคตเคฟ
+settings = เคธเฅเคเคฟเคเคเฅเคธ
+your_settings = เคเคชเคเฅ เคธเฅเคเคฟเคเคเฅเคธ
\ No newline at end of file
diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini
index 627b3a3700..ea8732f422 100644
--- a/options/locale/locale_hu-HU.ini
+++ b/options/locale/locale_hu-HU.ini
@@ -16,19 +16,19 @@ template=Sablon
language=Nyelv
notifications=รrtesรญtรฉsek
create_new=Lรฉtrehozรกsโฆ
-user_profile_and_more=Profil รฉs beรกllรญtรกsok...
+user_profile_and_more=Profil รฉs beรกllรญtรกsokโฆ
signed_in_as=Bejelentkezve mint
toc=Tartalomjegyzรฉk
licenses=Licencek
-return_to_forgejo=Vissza a Forgejo-hoz
+return_to_forgejo=Vissza a Forgejรณhoz
username=Felhasznรกlรณnรฉv
-email=E-mail cรญm
+email=E-mail-cรญm
password=Jelszรณ
re_type=Jelszรณ megerลsรญtรฉse
captcha=CAPTCHA
twofa=Kรฉtlรฉpcsลs hitelesรญtรฉs
-twofa_scratch=Kรฉtlรฉpcsลs bejelentkezรฉs egyszer hasznรกlatos kรณdja
+twofa_scratch=Kรฉtlรฉpcsลs hitelesรญtรฉs egyszer hasznรกlatos kรณdja
passcode=Jelkรณd
@@ -56,7 +56,7 @@ collaborative=Kรถzremลฑkรถdล
forks=Mรกsolat
activities=Tevรฉkenysรฉgek
-pull_requests=Egyesรญtรฉsi Kรฉrรฉsek
+pull_requests=Egyesรญtรฉsi kรฉrรฉsek
issues=Hibajegyek
milestones=Mรฉrfรถldkรถvek
@@ -90,22 +90,119 @@ concept_user_organization=Szervezet
name=Nรฉv
+filter.not_archived = Nem archivรกlt
+filter.public = Nyilvรกnos
+filter.private = Privรกt
+filter = Szลฑrล
+filter.is_archived = Archivรกlt
+logo = Logรณ
+sign_in_with_provider = Bejelentkezรฉs %s fiรณkkal
+webauthn_insert_key = Helyezze be biztonsรกgi kulcsรกt
+webauthn_press_button = Nyomja meg a biztonsรกgi kulcsรกn talรกlhatรณ gombotโฆ
+access_token = Hozzรกfรฉrรฉsi token
+webauthn_error = A biztonsรกgi kulcsรกnak beolvasรกsa sikertelen volt.
+webauthn_unsupported_browser = A bรถngรฉszลje jelenleg nem tรกmogatja a WebAuthn protokollt.
+webauthn_error_unknown = Ismeretlen hiba tรถrtรฉnt. Prรณbรกlja รบjra.
+webauthn_error_unable_to_process = A kiszolgรกlรณ nem tudta feldolgozni a kรฉrรฉsรฉt.
+webauthn_error_empty = Nevet kell adnia ennek a kulcsnak.
+new_project_column = รj oszlop
+never = Soha
+unknown = Ismeretlen
+value = รrtรฉk
+copy_content = Tartalom mรกsolรกsa
+copy_hash = Hash mรกsolรกsa
+copy_success = Mรกsolva!
+confirm_delete_selected = Biztosan tรถrli az รถsszes kijelรถlt elemet?
+pin = Kitลฑzรฉs
+show_timestamps = Idลbรฉlyegek mutatรกsa
+show_log_seconds = Mรกsodpercek mutatรกsa
+download_logs = Naplรณfรกjlok letรถltรฉse
+filter.is_template = Sablonok
+error = Hiba
+go_back = Vissza
+filter.not_template = Nem sablonok
+locked = Zรกrolt
+more_items = Tovรกbbi elemek
+view = Megtekintรฉs
+ok = OK
+copy_generic = Mรกsolรกs vรกgรณlapra
+copy_url = Webcรญm mรกsolรกsa
+webauthn_error_insecure = A WebAuthn csak biztonsรกgos kapcsolatokat tรกmogat. HTTP-n keresztรผli tesztelรฉs esetรฉn hasznรกlja a โlocalhostโ vagy a โ127.0.0.1โ forrรกst.
+filter.clear = Szลฑrลk tรถrlรฉse
+enable_javascript = Az oldal mลฑkรถdรฉsรฉhez engedรฉlyezni kell a JavaScriptet.
+webauthn_sign_in = Nyomja meg a biztonsรกgi kulcsรกn talรกlhatรณ gombot. Ha nincs rajta gomb, prรณbรกlja meg รบjra behelyezni.
+webauthn_use_twofa = Kรฉtlรฉpcsลs hitelesรญtรฉsi kรณd hasznรกlata telefonrรณl
+webauthn_error_timeout = Idลtรบllรฉpรฉs a kulcs beolvasรกsa sorรกn. Tรถltse be รบjra ezt az oldalt, รฉs prรณbรกlkozzon รบjra.
+copy_branch = Elรกgazรกs nevรฉnek mรกsolรกsa
+test = Tesztelรฉs
+copy_type_unsupported = Ezt a fรกjltรญpust nem lehet mรกsolni
+copy_error = Sikertelen mรกsolรกs
+invalid_data = รrvรฉnytelen adatok: %v
+unpin = Rรถgzรญtรฉs feloldรกsa
+concept_user_individual = Egyรฉni
+toggle_menu = Menรผ megjelenรญtรฉse/elrejtรฉse
+concept_system_global = Globรกlis
+error413 = Felhasznรกlta a kvรณtรกjรกt.
+remove_label_str = โ%sโ eltรกvolรญtรกsa
+rerun_all = Minden feladat รบjrafuttatรกsa
+rerun = รjrafuttatรกs
+show_full_screen = Teljes kรฉpernyล
+rss_feed = RSS csatorna
+copy = Mรกsolรกs
+retry = รjra
+new_repo.title = รj tรกrolรณ
+new_repo.link = รj tรกrolรณ
+new_migrate.title = รj migrรกciรณ
+new_migrate.link = รj migrรกciรณ
+new_org.title = รj szervezet
+new_org.link = รj szervezet
+filter.is_fork = Mรกsolatok
+webauthn_error_duplicated = A biztonsรกgi kulcs nem engedรฉlyezett ehhez a kรฉrรฉshez. Gyลzลdjรถn meg rรณla, hogy a kulcs nincs-e mรกr regisztrรกlva.
+filter.is_mirror = Tรผkrรถk
[aria]
+footer.links = Hivatkozรกsok
+footer = Lรกblรฉc
+navbar = Navigรกciรณs eszkรถzsor
+footer.software = A programrรณl
[heatmap]
+less = Kevesebb
+more = Tรถbb
+number_of_contributions_in_the_last_12_months = %s hozzรกjรกrulรกs az elmรบlt 12 hรณnapban
+contributions_zero = Nincsenek hozzรกjรกrulรกsok
+contributions_one = hozzรกjรกrulรกs
+contributions_few = hozzรกjรกrulรกs
[editor]
+buttons.heading.tooltip = Fejlรฉc hozzรกadรกsa
+buttons.code.tooltip = Kรณd hozzรกadรกsa
+buttons.bold.tooltip = Fรฉlkรถvรฉr szรถveg hozzรกadรกsa
+buttons.italic.tooltip = Dลlt szรถveg hozzรกadรกsa
+buttons.quote.tooltip = Szรถveg idรฉzรฉse
+buttons.link.tooltip = Hivatkozรกs hozzรกadรกsa
+buttons.indent.tooltip = Elemek behรบzรกsa egy szinttel
+buttons.mention.tooltip = Felhasznรกlรณ vagy csapat emlรญtรฉse
+buttons.list.ordered.tooltip = Szรกmozott lista hozzรกadรกsa
+buttons.list.task.tooltip = Feladatlista hozzรกadรกsa
+buttons.list.unordered.tooltip = Felsorolรกs hozzรกadรกsa
+buttons.switch_to_legacy.tooltip = A rรฉgi szerkesztล hasznรกlata
+buttons.unindent.tooltip = Elemek behรบzรกsรกnak csรถkkentรฉse egy szinttel
[filter]
+string.asc = A - Z
+string.desc = Z - A
[error]
+occurred = Hiba tรถrtรฉnt
+server_internal = Belsล szerverhiba
+network_error = Hรกlรณzati hiba
+not_found = A cรฉl nem talรกlhatรณ.
[startpage]
app_desc=Fรกjdalommentes, sajรกt gรฉpre telepรญthetล Git szolgรกltatรกs
install=Kรถnnyen telepรญthetล
platform=Keresztplatformos
-platform_desc=A Forgejo minden platformon fut, ahol a Go fordรญthat: Windows, macOS, Linux, ARM, stb. Vรกlassza azt, amelyet szereti!
lightweight=Kรถnnyลฑsรบlyรบ
license=Nyรญlt forrรกskรณdรบ
@@ -136,7 +233,7 @@ app_name=Webhely cรญme
app_name_helper=Itt megadhatja a vรกllalata nevรฉt.
repo_path=Tรกrolรณk gyรถkรฉrkรถnyvtรกra
repo_path_helper=Minden tรกvoli Git tรกrolรณ ebbe a mappรกba lesz mentve.
-lfs_path=LFS Gyรถkรฉrkรถnyvtรกr
+lfs_path=Git LFS gyรถkรฉrkรถnyvtรกr
lfs_path_helper=A fรกjlok amiket Git LFS-el elmentesz ebbe a kรถnyvtรกrba kerรผlnek. Hagyd รผresen az LFS kikapcsolรกsรกhoz.
run_user=Futtatรกs mint
ssh_port=SSH szerver port
@@ -197,6 +294,7 @@ default_enable_timetracking=Idลmรฉrรฉs bekapcsolรกsa alapรฉrtelmezetten
default_enable_timetracking.description=Idลmรฉrรฉs bekapcsolรกsa az รบj tรกrolรณkra alapรฉrtelmezetten.
no_reply_address=Rejtett e-mail tartomรกny
no_reply_address_helper=Domain nรฉv a rejtett email cรญmmel rendelkezล felhasznรกlรณk szรกmรกra.Pรฉldรกul: Ha a felhasznรกlรณneve "jani" akkor bejelentkezhet a "jani@noreply.example.org" email cรญmmel,ha a rejtett email domain "noreply.example.org"-ra van รกllรญtva.
+domain = Szerver domain
[home]
uname_holder=Felhasznรกlรณnรฉv vagy e-mail cรญm
@@ -285,12 +383,11 @@ authorization_failed=Az engedรฉlyezรฉs nem sikerรผlt
sspi_auth_failed=SSPI hitelesรญtรฉs sikertelen
[mail]
-
activate_account=Kรฉrjรผk aktivรกlja a fiรณkjรกt
activate_email=E-mail cรญm megerลsรญtรฉse
-register_notify=A Forgejo รผdvรถzli
+register_notify=A %s รผdvรถzli
reset_password=Fiรณkjรกnak visszaรกllรญtรกsa
@@ -394,7 +491,7 @@ avatar=Profilkรฉp
ssh_gpg_keys=SSH / GPG kulcsok
social=Kรถzรถssรฉgi fiรณkok
applications=Alkalmazรกsok
-orgs=Szervezetek kezelรฉse
+orgs=Szervezetek
repos=Tรกrolรณk
delete=Fiรณk tรถrlรฉse
twofa=Kรฉtlรฉpcsลs hitelesรญtรฉs
@@ -566,6 +663,7 @@ email_notifications.submit=E-mail beรกllรญtรกsok megadรกsa
visibility.public=Nyilvรกnos
visibility.private=Privรกt
+appearance = Megjelenรฉs
[repo]
owner=Tulajdonos
@@ -689,6 +787,7 @@ file_too_large=Ez a fรกjl tรบl nagy ahhoz, hogy megjelenรญtsรผk.
video_not_supported_in_browser=A bรถngรฉszล nem tรกmogatja a HTML5 video tag-et.
audio_not_supported_in_browser=A bรถngรฉszล nem tรกmogatja a HTML5 audio tag-et.
stored_lfs=Git LFS-el eltรกrolva
+stored_annex=Git Annex-el eltรกrolva
symbolic_link=Szimbolikus hivatkozรกs
commit_graph=Commit grรกf
commit_graph.hide_pr_refs=Pull request-ek elrejtรฉse
@@ -701,6 +800,7 @@ editor.upload_file=Fรกjl feltรถltรฉse
editor.edit_file=Fรกjl szerkesztรฉse
editor.preview_changes=Vรกltozรกsok elลnรฉzete
editor.cannot_edit_lfs_files=LFS fรกjlok nem szerkeszthetลek a webes felรผleten.
+editor.cannot_edit_annex_files=Annex fรกjlok nem szerkeszthetลek a webes felรผleten.
editor.cannot_edit_non_text_files=Binรกris fรกjlok nem szerkeszthetลek a webes felรผleten.
editor.edit_this_file=Fรกjl szerkesztรฉse
editor.this_file_locked=Zรกrolt รกllomรกny
@@ -710,9 +810,9 @@ editor.name_your_file=Fรกjl elnevezรฉseโฆ
editor.or=vagy
editor.cancel_lower=Mรฉgse
editor.commit_changes=Vรกltozรกsok Vรฉglegesรญtรฉse
-editor.add_tmpl='' hozzรกadรกsa
+editor.add_tmpl='<%s>' hozzรกadรกsa
editor.commit_message_desc=Opcionรกlis hosszabb leรญrรกs hozzรกadรกsaโฆ
-editor.commit_directly_to_this_branch=Mentรฉs egyenesen a(z) %s รกgba.
+editor.commit_directly_to_this_branch=Mentรฉs egyenesen a(z) %[1]s รกgba.
editor.create_new_branch=Hozzon lรฉtre egy รบj รกgat ennek a commit-nak รฉs indรญts egy egyesรญtรฉsi kรฉrรฉst.
editor.propose_file_change=Vรกltoztatรกs ajรกnlรกsa
editor.new_branch_name_desc=รj รกg neveโฆ
@@ -933,7 +1033,7 @@ pulls.filter_branch=รgra szลฑrรฉs
pulls.no_results=Nincs talรกlat.
pulls.nothing_to_compare=Ezek az รกgak egyenlลek. Nincs szรผksรฉg egyesรญtรฉsi kรฉrรฉsre.
pulls.create=Egyesรญtรฉsi kรฉrรฉs lรฉtrehozรกsa
-pulls.title_desc_few=egyesรญteni szeretnรฉ %[1]d vรกltozรกs(oka)t a(z) %[2]s
-bรณl %[3]s
-ba
+pulls.title_desc_few=egyesรญteni szeretnรฉ %[1]d vรกltozรกs(oka)t a(z) %[2]s
-bรณl %[3]s
-ba
pulls.merged_title_desc_few=egyesรญtve %[1]d vรกltozรกs(ok) a %[2]s
-bรณl %[3]s
-ba %[4]s
pulls.tab_conversation=Beszรฉlgetรฉs
pulls.tab_commits=Commit-ok
@@ -1162,7 +1262,7 @@ release.download_count=Letรถltรฉsek: %s
branch.delete_head=Tรถrlรฉs
branch.delete_html=รg tรถrlรฉse
-branch.create_branch=รg %s lรฉtrehozรกsa
+branch.create_branch=รg %s lรฉtrehozรกsa
branch.deleted_by=Tรถrรถlve %s รกltal
@@ -1172,6 +1272,8 @@ topic.done=Kรฉsz
+milestones.filter_sort.name = Nรฉv
+
[graphs]
[org]
@@ -1412,16 +1514,15 @@ auths.enable_auto_register=Automatikus regisztrรกciรณ engedรฉlyezรฉse
auths.tips=Tippek
auths.tips.oauth2.general=OAuth2 hitelesรญtรฉs
auths.tip.oauth2_provider=OAuth2 szolgรกltatรณ
-auths.tip.bitbucket=Igรฉnyeljen egy รบj OAuth jogosultsรกgot itt: https://bitbucket.org/account/user//oauth-consumers/new รฉs adja hozzรก jogosultsรกgot a "Fiรณkok"-"Olvasรกs" alรก
-auths.tip.dropbox=Vegyen fel รบj alkalmazรกst itt: https://www.dropbox.com/developers/apps
-auths.tip.facebook=Vegyen fel รบj alkalmazรกst itt: https://developers.facebook.com/apps majd adja hozzรก a "Facebook Login"-t
-auths.tip.github=Vegyen fel รบj OAuth alkalmazรกst itt: https://github.com/settings/applications/new
+auths.tip.bitbucket=Igรฉnyeljen egy รบj OAuth jogosultsรกgot itt: %s
+auths.tip.dropbox=Vegyen fel รบj alkalmazรกst itt: %s
+auths.tip.facebook=Vegyen fel รบj alkalmazรกst itt: %s majd adja hozzรก a "Facebook Login"-t
+auths.tip.github=Vegyen fel รบj OAuth alkalmazรกst itt: %s
auths.tip.gitlab=Vegyen fel รบj alkalmazรกst itt: https://gitlab.com/profile/applications
-auths.tip.google_plus=Szerezzen OAuth2 kliens hitelesรญtรฉsi adatokat a Google API konzolban (https://console.developers.google.com/)
+auths.tip.google_plus=Szerezzen OAuth2 kliens hitelesรญtรฉsi adatokat a Google API konzolban (%s)
auths.tip.openid_connect=Hasznรกlja az OpenID kapcsolรณdรกs felfedezล URL-t (/.well-known/openid-configuration) a vรฉgpontok beรกllรญtรกsรกhoz
-auths.tip.twitter=Menyjen ide: https://dev.twitter.com/apps, hozzon lรฉtre egy alkalmazรกst รฉs gyลzลdjรถn meg rรณla, hogy az โAllow this application to be used to Sign in with Twitterโ opciรณ be van kapcsolva
-auths.tip.discord=Vegyen fel รบj alkalmazรกst itt:
-https://discordapp.com/developers/applications/me
+auths.tip.twitter=Menyjen ide: %s, hozzon lรฉtre egy alkalmazรกst รฉs gyลzลdjรถn meg rรณla, hogy az โAllow this application to be used to Sign in with Twitterโ opciรณ be van kapcsolva
+auths.tip.discord=Vegyen fel รบj alkalmazรกst itt: %s
auths.edit=Hitelesรญtรฉsi forrรกs szerkesztรฉse
auths.activated=A hitelesรญtรฉsi forrรกs aktivรกlva lett
auths.update_success=A hitelesรญtรฉsi forrรกs frissรญtve lett.
@@ -1587,6 +1688,9 @@ config.cache_item_ttl = Gyorsรญtรณtรกrelem TTL รฉrtรฉke
config.app_data_path = Alkalmazรกsadatok elรฉrรฉsi รบtja
+config_summary = รsszefoglalรณ
+config_settings = Beรกllรญtรกsok
+
[action]
create_repo=lรฉtrehozott tรกrolรณt: %s
rename_repo=รกtnevezte a(z) %[1]s
tรกrolรณt %[3]s -ra/re
@@ -1650,9 +1754,6 @@ owner.settings.cleanuprules.enabled=Engedรฉlyezett
[secrets]
[actions]
-
-
-
runners.name=Nรฉv
runners.owner_type=Tรญpus
runners.description=Leรญrรกs
@@ -1669,7 +1770,34 @@ runs.commit=Commit
[projects]
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=Szimbolikus hivatkozรกs
submodule = Almodul
+executable_file = Futtathatรณ fรกjl
+normal_file = รltalรกnos fรกjl
+directory = Kรถnyvtรกr
+
+
+[search]
+search = Keresรฉs...
+type_tooltip = Keresรฉs tรญpusa
+code_kind = Kรณd keresรฉse...
+code_search_unavailable = A kรณdban valรณ keresรฉs jelenleg nem elรฉrhetล. Kรฉrem vegye fel a kapcsolatot az oldal adminisztrรกtorรกval.
+package_kind = Csomagok keresรฉse...
+project_kind = Projektek keresรฉse...
+user_kind = Felhasznรกlรณk keresรฉse...
+repo_kind = Tรกrak keresรฉse...
+org_kind = Szervezetek keresรฉse...
+team_kind = Csapatok keresรฉse...
+exact = Pontos
+code_search_by_git_grep = A kรณdkeresรฉs jelenleg a "git grep" parancsot hasznรกlja. Lehet, hogy jobb talรกlatok is lennรฉnek, ha a webhely adminisztrรกtora bekapcsolja a forrรกskรณd indexelรฉsรฉt.
+milestone_kind = Mรฉrfรถldkรถvek keresรฉse...
+fuzzy_tooltip = A keresรฉsi kifejezรฉshez hasonlรณ talรกlatok mutatรกsa
+fuzzy = Hasonlรณk
+union = Kulcsszavakra
+union_tooltip = A szรณkรถzzel elvรกlasztott kulcsszavak bรกrmelyikรฉt tartalmazรณ talรกlatok mutatรกsa
+branch_kind = รgak keresรฉse...
+no_results = Nincsenek megfelelล talรกlatok.
+issue_kind = Hibajegyek keresรฉse...
+exact_tooltip = Csak a keresรฉsi kifejezรฉst pontosan tartalmazรณ talรกlatok mutatรกsa
+keyword_search_unavailable = A kulcsszรณ alapรบ keresรฉs jelenleg nem elรฉrhetล. Kรฉrlek รฉrtesรญtsd az oldal rendszergazdรกjรกt.
diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini
index d85cb78abb..fc9d934ce6 100644
--- a/options/locale/locale_id-ID.ini
+++ b/options/locale/locale_id-ID.ini
@@ -84,25 +84,102 @@ concept_code_repository=Repositori
name=Nama
+re_type = Konfirmasi Kata Sandi
+webauthn_insert_key = Masukkan kunci keamanan anda
+webauthn_sign_in = Tekan tombol pada kunci keamanan Anda. Jika kunci keamanan Anda tidak memiliki tombol, masukkan kembali.
+webauthn_press_button = Silakan tekan tombol pada kunci keamanan Andaโฆ
+webauthn_use_twofa = Gunakan kode dua faktor dari telepon Anda
+webauthn_error = Tidak dapat membaca kunci keamanan Anda.
+webauthn_unsupported_browser = Browser Anda saat ini tidak mendukung WebAuthn.
+webauthn_error_unknown = Terdapat kesalahan yang tidak diketahui. Mohon coba lagi.
+webauthn_error_insecure = `WebAuthn hanya mendukung koneksi aman. Untuk pengujian melalui HTTP, Anda dapat menggunakan "localhost" atau "127.0.0.1"`
+webauthn_error_unable_to_process = Server tidak dapat memproses permintaan Anda.
+webauthn_error_duplicated = Kunci keamanan tidak diperbolehkan untuk permintaan ini. Pastikan bahwa kunci ini belum terdaftar sebelumnya.
+webauthn_error_empty = Anda harus menetapkan nama untuk kunci ini.
+webauthn_error_timeout = Waktu habis sebelum kunci Anda dapat dibaca. Mohon muat ulang halaman ini dan coba lagi.
+new_project = Proyek Baru
+new_project_column = Kolom Baru
+ok = Oke
+retry = Coba lagi
+rerun = Jalankan ulang
+rerun_all = Jalankan ulang semua job
+remove_label_str = `Hapus item "%s"`
+view = Tampilan
+test = Pengujian
+locked = Terkunci
+copy = Salin
+copy_url = Salin URL
+copy_hash = Salin hash
+copy_content = Salin konten
+copy_branch = Salin nama branch
+copy_success = Tersalin!
+copy_error = Gagal menyalin
+copy_type_unsupported = Tipe berkas ini tidak dapat disalin
+error = Gangguan
+error404 = Halaman yang akan kamu akses tidak dapat ditemukan atau kamu tidak memiliki akses untuk melihatnya.
+go_back = Kembali
+invalid_data = Data invalid: %v
+never = Tidak Pernah
+unknown = Tidak diketahui
+rss_feed = Umpan Berita
+pin = Sematkan
+unpin = Lepas sematan
+artifacts = Artefak
+archived = Diarsipkan
+concept_system_global = Global
+concept_user_individual = Perorangan
+show_full_screen = Tampilkan layar penuh
+download_logs = Unduh Logs
+confirm_delete_selected = Konfirmasi untuk menghapus semua item yang dipilih?
+value = Nilai
+filter = Saring
+filter.is_archived = Diarsipkan
+filter.not_archived = Tidak Diarsipkan
+filter.public = Publik
+filter.private = Pribadi
+
[aria]
+navbar = Bar Navigasi
+footer = Footer
+footer.links = Tautan
[heatmap]
+number_of_contributions_in_the_last_12_months = %s Kontribusi pada 12 bulan terakhir
+less = Lebih sedikit
+more = Lebih banyak
[editor]
+buttons.heading.tooltip = Tambahkan heading
+buttons.bold.tooltip = Tambahkan teks Tebal
+buttons.italic.tooltip = Tambahkan teks Miring
+buttons.quote.tooltip = Kutip teks
+buttons.code.tooltip = Tambah Kode
+buttons.link.tooltip = Tambahkan tautan
+buttons.list.unordered.tooltip = Tambah daftar titik
+buttons.list.ordered.tooltip = Tambah daftar angka
+buttons.list.task.tooltip = Tambahkan daftar tugas
+buttons.mention.tooltip = Tandai pengguna atau tim
+buttons.ref.tooltip = Merujuk pada isu atau permintaan tarik
+buttons.switch_to_legacy.tooltip = Gunakan editor versi lama
+buttons.enable_monospace_font = Aktifkan font monospace
+buttons.disable_monospace_font = Non-Aktifkan font monospace
[filter]
+string.asc = A - Z
+string.desc = Z - A
[error]
+occurred = Terjadi kesalahan
+not_found = Target tidak dapat ditemukan.
[startpage]
app_desc=Sebuah layanan hosting Git sendiri yang tanpa kesulitan
install=Mudah dipasang
platform=Lintas platform
-platform_desc=Forgejo bisa digunakan di mana Go bisa dijalankan: Windows, macOS, Linux, ARM, dll. Silahkan pilih yang Anda suka!
lightweight=Ringan
lightweight_desc=Forgejo hanya membutuhkan persyaratan minimal dan bisa berjalan pada Raspberry Pi yang murah. Bisa menghemat listrik!
license=Sumber Terbuka
-license_desc=Go get (Dapatkan kode sumber dari) Forgejo ! Mari bergabung dengan berkontribusi untuk membuat proyek ini lebih baik. Jangan malu untuk menjadi kontributor!
+license_desc=Go get (Dapatkan kode sumber dari) Forgejo ! Mari bergabung dengan berkontribusi untuk membuat proyek ini lebih baik. Jangan malu untuk menjadi kontributor!
[install]
title=Konfigurasi Awal
@@ -125,6 +202,9 @@ require_sign_in_view=Harus Login Untuk Melihat Halaman
admin_password=Kata Sandi
admin_email=Alamat Email
+email_title = Pengaturan email
+smtp_from = Kirim Email Sebagai
+
[home]
uname_holder=Nama Pengguna atau Alamat Surel
password_holder=Kata Sandi
@@ -142,6 +222,8 @@ show_private=Pribadi
issues.in_your_repos=Dalam repositori anda
+show_archived = Diarsipkan
+
[explore]
repos=Repositori
users=Pengguna
@@ -207,12 +289,11 @@ authorization_failed=Otorisasi gagal
sspi_auth_failed=Autentikasi SSPI gagal
[mail]
-
activate_account=Silakan aktifkan akun anda
activate_email=Verifikasi alamat surel anda
-register_notify=Selamat Datang di Forgejo
+register_notify=Selamat Datang di %s
reset_password=Pulihkan akun Anda
@@ -494,6 +575,8 @@ email_notifications.submit=Pasang Pengaturan Email
visibility.private=Pribadi
+visibility.public = Publik
+
[repo]
owner=Pemilik
repo_name=Nama Repositori
@@ -598,6 +681,7 @@ file_permalink=Permalink
file_too_large=Berkas terlalu besar untuk ditampilkan.
stored_lfs=Tersimpan dengan GIT LFS
+stored_annex=Tersimpan dengan GIT Annex
commit_graph=Grafik Komit
blame=Salahkan
normal_view=Pandangan Normal
@@ -609,6 +693,7 @@ editor.upload_file=Unggah Berkas
editor.edit_file=Sunting Berkas
editor.preview_changes=Tinjau Perubahan
editor.cannot_edit_lfs_files=Berkas LFS tidak dapat disunting dalam antarmuka web.
+editor.cannot_edit_annex_files=Berkas Annex tidak dapat disunting dalam antarmuka web.
editor.cannot_edit_non_text_files=Berkas biner tidak dapat disunting dalam antarmuka web.
editor.edit_this_file=Sunting Berkas
editor.this_file_locked=Berkas terkunci
@@ -621,9 +706,9 @@ editor.filename_help=Tambahkan direktori dengan mengetikkan nama direktori diiku
editor.or=atau
editor.cancel_lower=Batalkan
editor.commit_changes=Perubahan komitmen
-editor.add_tmpl=Tambahkan ''
+editor.add_tmpl=Tambahkan '<%s>'
editor.commit_message_desc=Tambahkan deskripsi opsional yang panjangโฆ
-editor.commit_directly_to_this_branch=Komitmen langsung ke %s cabang.
+editor.commit_directly_to_this_branch=Komitmen langsung ke %[1]s cabang.
editor.create_new_branch=Membuat new branch untuk tarik komit ini mulai permintaan.
editor.create_new_branch_np=Buat cabang baru untuk komit ini.
editor.propose_file_change=Usul perubahan berkas
@@ -752,7 +837,7 @@ pulls.compare_changes=Permintaan Tarik Baru
pulls.filter_branch=Penyaringan cabang
pulls.no_results=Hasil tidak ditemukan.
pulls.create=Buat Permintaan Tarik
-pulls.title_desc_few=ingin menggabungkan komit %[1]d dari %[2]s
menuju %[3]s
+pulls.title_desc_few=ingin menggabungkan komit %[1]d dari %[2]s
menuju %[3]s
pulls.merged_title_desc_few=commit %[1]d telah digabungkan dari %[2]s
menjadi %[3]s
%[4]s
pulls.tab_conversation=Percakapan
pulls.tab_commits=Melakukan
@@ -949,7 +1034,7 @@ release.downloads=Unduhan
branch.delete_head=Hapus
branch.delete_html=Hapus cabang
-branch.create_branch=Membuat cabang %s
+branch.create_branch=Membuat cabang %s
branch.deleted_by=Dihapus oleh %s
@@ -957,6 +1042,12 @@ branch.deleted_by=Dihapus oleh %s
+desc.public = Publik
+desc.archived = Diarsipkan
+commitstatus.error = Gangguan
+projects.new = Proyek Baru
+milestones.filter_sort.name = Nama
+
[graphs]
[org]
@@ -1011,6 +1102,8 @@ teams.delete_team_success=Tim sudah di hapus.
teams.repositories=Tim repositori
teams.search_repo_placeholder=Cari repositoriโฆ
+settings.visibility.public = Publik
+
[admin]
dashboard=Dasbor
organizations=Organisasi
@@ -1126,9 +1219,9 @@ auths.enable_auto_register=Mengaktifkan pendaftaran otomatis
auths.tips=Cara
auths.tips.oauth2.general=Otentikasi OAuth2
auths.tip.oauth2_provider=Penyediaan OAuth2
-auths.tip.dropbox=Membuat aplikasi baru di https://www.dropbox.com/developers/apps
-auths.tip.facebook=`Daftarkan sebuah aplikasi baru di https://developers.facebook.com/apps dan tambakan produk "Facebook Masuk"`
-auths.tip.github=Mendaftar aplikasi OAuth baru di https://github.com/settings/applications/new
+auths.tip.dropbox=Membuat aplikasi baru di %s
+auths.tip.facebook=`Daftarkan sebuah aplikasi baru di %s dan tambakan produk "Facebook Masuk"`
+auths.tip.github=Mendaftar aplikasi OAuth baru di %s
auths.tip.gitlab=Mendaftar aplikasi baru di https://gitlab.com/profile/applications
auths.tip.openid_connect=Gunakan membuka ID yang terhubung ke jelajah URL (/.well-known/openid-configuration) untuk menentukan titik akhir
auths.delete=Menghapus Otentikasi Sumber
@@ -1269,6 +1362,9 @@ notices.op=Op.
notices.delete_success=Laporan sistem telah dihapus.
+config_settings = Pengaturan
+users.list_status_filter.menu_text = Saring
+
[action]
create_repo=repositori dibuat %s
rename_repo=ganti nama gudang penyimpanan dari %[1]s
ke %[3]s
@@ -1332,9 +1428,6 @@ owner.settings.cleanuprules.enabled=Aktif
[secrets]
[actions]
-
-
-
runners.name=Nama
runners.owner_type=Jenis
runners.description=Deskripsi
@@ -1347,8 +1440,56 @@ runs.commit=Memperbuat
+runs.no_matching_online_runner_helper = Tidak ada runner online yang cocok dengan label: %s
+runs.actor = Aktor
+runs.status = Status
+runs.actors_no_select = Semua aktor
+runs.status_no_select = Semua status
+runs.no_results = Tidak ada hasil yang cocok.
+runs.no_workflows = Belum ada alur kerja.
+runs.no_runs = Alur kerja belum berjalan.
+runs.empty_commit_message = (pesan commit kosong)
+workflow.disable = Nonaktifkan Alur Kerja
+workflow.enable = Aktifkan Alur Kerja
+workflow.disabled = Alur kerja dinonaktifkan.
+need_approval_desc = Butuh persetujuan untuk menjalankan alur kerja untuk pull request fork.
+variables = Variabel
+variables.creation = Tambah Variabel
+variables.none = Belum ada variabel.
+variables.deletion = Hapus variabel
+variables.deletion.description = Menghapus variabel bersifat permanen dan tidak dapat dibatalkan. Lanjutkan?
+variables.description = Variabel akan diteruskan ke beberapa tindakan dan tidak dapat dibaca sebaliknya.
+variables.id_not_exist = Variabel dengan ID %d tidak ada.
+variables.edit = Edit Variabel
+variables.deletion.failed = Gagal menghapus variabel.
+variables.deletion.success = Variabel telah dihapus.
+variables.creation.failed = Gagal menambahkan variabel.
+variables.creation.success = Variabel "%s" telah ditambahkan.
+variables.update.failed = Gagal mengedit variabel.
+variables.update.success = Variabel telah diedit.
+
[projects]
+type-1.display_name = Proyek Individu
+type-2.display_name = Proyek Repositori
+type-3.display_name = Proyek Organisasi
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
+changed_filemode = %[1]s โ %[2]s
+directory = Directory
+normal_file = Normal file
+executable_file = Executable file
+symbolic_link = Symbolic link
+submodule = Submodule
+[search]
+search = Cari...
+type_tooltip = Tipe pencarian
+fuzzy_tooltip = Termasuk juga hasil yang mendekati kata pencarian
+exact_tooltip = Hanya menampilkan hasil yang cocok dengan istilah pencarian
+repo_kind = Cari repo...
+user_kind = Telusuri pengguna...
+org_kind = Cari organisasi...
+team_kind = Cari tim...
+code_kind = Cari kode...
+code_search_unavailable = Pencarian kode saat ini tidak tersedia. Silahkan hubungi administrator.
+branch_kind = Cari cabang...
diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini
index 7b5733e2eb..9c39b9d830 100644
--- a/options/locale/locale_is-IS.ini
+++ b/options/locale/locale_is-IS.ini
@@ -3,7 +3,7 @@ home=Forsรญรฐa
dashboard=Stjรณrnborรฐ
explore=Vafra
help=Hjรกlp
-sign_in=Skrรก Inn
+sign_in=Skrรก inn
sign_in_or=eรฐa
sign_out=Skrรก รt
sign_up=Nรฝskrรกning
@@ -15,9 +15,9 @@ page=Sรญรฐa
template=Sniรฐmรกt
language=Tungumรกl
notifications=Tilkynningar
-active_stopwatch=Virk Tรญmamรฆling
+active_stopwatch=Virk tรญmamรฆling
create_new=Skapaโฆ
-user_profile_and_more=Notandasรญรฐa og Stillingarโฆ
+user_profile_and_more=Notandasรญรฐa og stillingarโฆ
signed_in_as=Skrรกรฐ(ur) inn sem
toc=Efnisyfirlit
licenses=Hugbรบnaรฐarleyfi
@@ -111,6 +111,12 @@ concept_code_repository=Hugbรบnaรฐarsafn
name=Heiti
value=Gildi
+sign_in_with_provider = Skrรก inn meรฐ %s
+enable_javascript = รessi sรญรฐa krefst JavaScript.
+
+filter = Sรญa
+filter.is_archived = Safnvistaรฐ
+filter.public = Opinbert
[aria]
@@ -131,11 +137,10 @@ network_error=Netkerfisvilla
app_desc=รrautalaus og sjรกlfhรฝst Git รพjรณnusta
install=Einfรถld uppsetning
platform=Fjรถlvettvangur
-platform_desc=Forgejo virkar hvar sem aรฐ Go gerir: Linux, macOS, Windows, ARM o. s. frv. Veldu รพaรฐ sem รพรบ vilt!
lightweight=Lรฉtt
lightweight_desc=Forgejo hefur lรกgar lรกgmarkskrรถfur og getur keyrt รก รณdรฝrum Raspberry Pi. Sparaรฐu orku!
license=Frjรกls Hugbรบnaรฐur
-license_desc=Sรฆktu Forgejo ! Gakktu til liรฐs meรฐ รพvรญ aรฐ taka รพรกtt til รพess aรฐ gera รพetta verkefni jafnvel betra! Vertu ekki feimin(n) viรฐ aรฐ verรฐa รพรกtttakandi!
+license_desc=Sรฆktu Forgejo ! Gakktu til liรฐs meรฐ รพvรญ aรฐ taka รพรกtt til รพess aรฐ gera รพetta verkefni jafnvel betra! Vertu ekki feimin(n) viรฐ aรฐ verรฐa รพรกtttakandi!
[install]
install=Uppsetning
@@ -302,7 +307,7 @@ activate_account.text_2=Vinsamlegast smelltu รก eftirfarandi tengil til aรฐ virk
activate_email=Staรฐfestu netfangiรฐ รพitt
activate_email.text=Vinsamlegast smelltu รก eftirfarandi tengil til aรฐ staรฐfesta netfangiรฐ รพitt innan %s :
-register_notify=Velkomin(n) รญ Forgejo
+register_notify=Velkomin(n) รญ %s
register_notify.title=%[1]s, velkomin(n) รญ %[2]s
register_notify.text_1=รพetta er staรฐfestingarpรณstur รพinn fyrir skrรกningu รก %s!
register_notify.text_2=รรบ getur nรบ skrรกรฐ รพig inn meรฐ notandanafni: %s.
@@ -679,6 +684,7 @@ file_view_rendered=Skoรฐa Unniรฐ
file_copy_permalink=Afrita Varanlega Slรณรฐ
stored_lfs=Geymt meรฐ Git LFS
+stored_annex=Geymt meรฐ Git Annex
commit_graph.hide_pr_refs=Fela Sameiningarbeiรฐnir
commit_graph.monochrome=Einlitaรฐ
commit_graph.color=Litaรฐ
@@ -697,7 +703,7 @@ editor.delete_this_file=Eyรฐa Skrรก
editor.name_your_file=Nefndu skrรกna รพรญnaโฆ
editor.or=eรฐa
editor.cancel_lower=Hรฆtta viรฐ
-editor.add_tmpl=Bรฆta viรฐ โโ
+editor.add_tmpl=Bรฆta viรฐ โ<%s>โ
editor.create_new_branch=Bรบรฐu til nรฝja grein og sameiningarbeiรฐni fyrir รพetta framlag.
editor.create_new_branch_np=Bรบรฐu til nรฝja grein fyrir รพetta framlag.
editor.new_branch_name_desc=Heiti nรฝjar greinarโฆ
@@ -889,7 +895,7 @@ pulls.new=Nรฝ Sameiningarbeiรฐni
pulls.view=Skoรฐa Sameiningarbeiรฐni
pulls.compare_changes=Nรฝ Sameiningarbeiรฐni
pulls.create=Skapa Sameiningarbeiรฐni
-pulls.title_desc_few=vill sameina %[1]d framlรถg frรก %[2]s
รญ %[3]s
+pulls.title_desc_few=vill sameina %[1]d framlรถg frรก %[2]s
รญ %[3]s
pulls.tab_conversation=Umrรฆรฐa
pulls.tab_commits=Framlรถg
pulls.tab_files=Skrรกum Breytt
@@ -1117,6 +1123,8 @@ topic.done=ร lagi
+milestones.filter_sort.name = Heiti
+
[graphs]
[org]
@@ -1231,8 +1239,8 @@ auths.smtpport=SMTP Gรกtt
auths.oauth2_icon_url=Tรกknmyndarvefslรณรฐ
auths.oauth2_profileURL=Notandasรญรฐuslรณรฐ
auths.tips=รbendingar
-auths.tip.dropbox=Bรบรฐu til nรฝtt forrit รก https://www.dropbox.com/developers/apps
-auths.tip.yandex=`Bรบรฐu til nรฝja umsรณkn รก https://oauth.yandex.com/client/new. Veldu eftirfarandi heimildir รบr โYandex.Passport APIโ kaflanum: "Aรฐgangur aรฐ netfangi", "Aรฐgangur aรฐ notandamynd" og "Aรฐgangur aรฐ notendanafni, fornafni og eftirnafni, kyni"`
+auths.tip.dropbox=Bรบรฐu til nรฝtt forrit รก %s
+auths.tip.yandex=`Bรบรฐu til nรฝja umsรณkn รก %s. Veldu eftirfarandi heimildir รบr โYandex.Passport APIโ kaflanum: "Aรฐgangur aรฐ netfangi", "Aรฐgangur aรฐ notandamynd" og "Aรฐgangur aรฐ notendanafni, fornafni og eftirnafni, kyni"`
config.app_name=Heiti Vefsvรฆรฐis
config.app_ver=รtgรกfu Forgejo
@@ -1286,6 +1294,9 @@ notices.type_2=Verkefni
notices.desc=Lรฝsing
+config_summary = Yfirlit
+config_settings = Stillingar
+
[action]
create_issue=`opnaรฐi vandamรกl %[3]s#%[2]s `
reopen_issue=`enduropnaรฐi vandamรกl %[3]s#%[2]s `
@@ -1351,9 +1362,6 @@ pypi.requires=รarfnast Python
[secrets]
[actions]
-
-
-
runners.id=Auรฐkenni
runners.name=Heiti
runners.owner_type=Tegund
@@ -1373,5 +1381,5 @@ runs.commit=Framlag
[projects]
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
+[search]
diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini
index fe93ea51da..3c5e834260 100644
--- a/options/locale/locale_it-IT.ini
+++ b/options/locale/locale_it-IT.ini
@@ -8,7 +8,7 @@ sign_in=Accedi
sign_in_or=o
sign_out=Esci
sign_up=Registrati
-link_account=Collega account
+link_account=Collega Profilo
register=Registrati
version=Versione
powered_by=Gestito da %s
@@ -16,11 +16,11 @@ page=Pagina
template=Template
language=Lingua
notifications=Notifiche
-active_stopwatch=Tracker Tempo Attivo
+active_stopwatch=Attiva cronometro
create_new=Creaโฆ
-user_profile_and_more=Profilo ed Impostazioniโฆ
+user_profile_and_more=Profilo ed impostazioniโฆ
signed_in_as=Accesso effettuato come
-toc=Indice dei contenuti
+toc=Indice dei Contenuti
licenses=Licenze
return_to_forgejo=Ritorna a Forgejo
@@ -35,26 +35,26 @@ twofa_scratch=Codice di recupero per la verifica in due passaggi
passcode=Codice di sicurezza
webauthn_insert_key=Inserisci la tua chiave di sicurezza
-webauthn_sign_in=Premere il pulsante sul tasto di sicurezza. Se il tasto di sicurezza non ha pulsante, reinseriscilo.
-webauthn_press_button=Si prega di premere il pulsante sul tasto di sicurezzaโฆ
+webauthn_sign_in=Premi il pulsante sul tasto di sicurezza. Se il tasto di sicurezza non ha pulsante, reinseriscilo.
+webauthn_press_button=Premi il pulsante sulla chiave di sicurezzaโฆ
webauthn_use_twofa=Usa un codice a due fattori dal tuo telefono
webauthn_error=Impossibile leggere la tua chiave di sicurezza.
webauthn_unsupported_browser=Il tuo browser al momento non supporta WebAuthn.
webauthn_error_unknown=Si รจ verificato un errore sconosciuto. Riprova.
-webauthn_error_insecure=`WebAuthn supporta solo connessioni sicure. Per il test su HTTP, รจ possibile utilizzare l'origine "localhost" o "127.0.0.1"`
+webauthn_error_insecure=WebAuthn supporta solo connessioni sicure. Per il test su HTTP, รจ possibile utilizzare l'origine "localhost" o "127.0.0.1"
webauthn_error_unable_to_process=Il server non puรฒ elaborare la richiesta.
webauthn_error_duplicated=La chiave di sicurezza non รจ consentita per questa richiesta. Assicurati che la chiave non sia giร registrata.
webauthn_error_empty=Devi impostare un nome per questa chiave.
webauthn_error_timeout=Timeout raggiunto prima che la tua chiave possa essere letta. Ricarica la pagina e riprova.
webauthn_reload=Ricarica
-repository=Repository
+repository=Repositorio
organization=Organizzazione
mirror=Mirror
new_repo=Nuovo repository
new_migrate=Nuova migrazione
new_mirror=Nuovo mirror
-new_fork=Nuovo fork
+new_fork=Nuova derivazione
new_org=Nuova organizzazione
new_project=Nuovo progetto
manage_org=Gestisci le organizzazioni
@@ -62,7 +62,7 @@ admin_panel=Amministrazione sito
account_settings=Impostazioni del profilo
settings=Impostazioni
your_profile=Profilo
-your_starred=Repository votate
+your_starred=Preferiti
your_settings=Impostazioni
all=Tutti
@@ -71,18 +71,18 @@ mirrors=Mirror
collaborative=Condivisi
forks=Fork
-activities=Attivitรก
-pull_requests=Pull request
+activities=Attivitร
+pull_requests=Richieste di modifica
issues=Segnalazioni
-milestones=Milestones
+milestones=Traguardi
ok=OK
cancel=Annulla
save=Salva
add=Aggiungi
-add_all=Aggiungi tutti
+add_all=Aggiungi tutto
remove=Rimuovi
-remove_all=Rimuovi Tutti
+remove_all=Rimuovi tutti
edit=Modifica
enabled=Attivo
@@ -109,7 +109,7 @@ rss_feed=Feed RSS
archived=Archiviato
-concept_code_repository=Repository
+concept_code_repository=Repositorio
concept_user_organization=Organizzazione
@@ -142,27 +142,37 @@ download_logs = Scarica logs
confirm_delete_selected = Confermare l'eliminazione di tutti gli elementi selezionati?
sign_in_with_provider = Accedi con %s
new_project_column = Nuova colonna
-toggle_menu = Mostra/Nascondi Menu
-filter.not_fork = Non da fork
+toggle_menu = Mostra/Nascondi menu
+filter.not_fork = Non fork
filter = Filtro
filter.clear = Rimuovi filtri
filter.is_archived = Archiviato
filter.not_archived = Non archiviato
-filter.is_fork = Da Fork
+filter.is_fork = Da fork
filter.is_mirror = Mirror
filter.not_mirror = Non mirror
-filter.is_template = Modello
-filter.not_template = Non modello
+filter.is_template = Modelli
+filter.not_template = Non modelli
filter.public = Pubblico
filter.private = Privato
more_items = Piรน elementi
invalid_data = Dati non validi: %v
+copy_generic = Copia negli appunti
+test = Prova
+new_repo.title = Nuovo repositorio
+new_repo.link = Nuovo repositorio
+error413 = Hai esaurito la tua quota.
+new_migrate.title = Nuova migrazione
+new_org.title = Nuova organizzazione
+new_migrate.link = Nuova migrazione
+new_org.link = Nuova organizzazione
+copy_path = Copia percorso
[aria]
footer.links = Collegamenti
-navbar = Barra di Navigazione
+navbar = Barra di navigazione
footer = Piรจ di Pagina
-footer.software = A proposito del Software
+footer.software = A proposito di questo software
[heatmap]
more = Piรน
@@ -184,10 +194,21 @@ buttons.list.unordered.tooltip = Aggiungi un elenco puntato
buttons.list.ordered.tooltip = Aggiungi un elenco numerato
buttons.list.task.tooltip = Aggiungi un elenco di attivitร
buttons.mention.tooltip = Menziona un utente o team
-buttons.ref.tooltip = Fai riferimento ad un problema o pull request
+buttons.ref.tooltip = Fa riferimento a una segnalazione o richiesta di modifica
buttons.switch_to_legacy.tooltip = Passa all'editor classico
buttons.enable_monospace_font = Attiva font monospace
buttons.disable_monospace_font = Disattiva font monospace
+buttons.indent.tooltip = Annida elementi di un livello
+buttons.unindent.tooltip = Disannida elementi di un livello
+buttons.new_table.tooltip = Aggiungi tabella
+table_modal.header = Aggiungi tabella
+table_modal.placeholder.header = Intestazione
+table_modal.placeholder.content = Contenuto
+table_modal.label.rows = File
+table_modal.label.columns = Colonne
+link_modal.header = Aggiungi collegamento
+link_modal.url = Url
+link_modal.description = Descrizione
[filter]
string.asc = A - Z
@@ -199,25 +220,24 @@ missing_csrf=Richiesta errata: nessun token CSRF presente
invalid_csrf=Richiesta errata: token CSRF non valido
not_found=Il bersaglio non รจ stato trovato.
network_error=Errore di rete
-report_message = Se credi che questo sia un errore di Forgejo, per favore controlla le segnalazioni su Codeberg o aprine una nuova se necessario.
+report_message = Se si pensa che questo sia un errore di Forgejo, controllare le segnalazioni su Codeberg o aprine una nuova se necessario.
server_internal = Errore interno del server
[startpage]
app_desc=Un servizio auto-ospitato per Git pronto all'uso
install=Facile da installare
platform=Multipiattaforma
-platform_desc=Forgejo funziona ovunque Go possa essere compilato: Windows, macOS, Linux, ARM, etc. Scegli ciรฒ che ami!
lightweight=Leggero
lightweight_desc=Forgejo ha requisiti minimi bassi e puรฒ funzionare su un economico Raspberry Pi. Risparmia l'energia della tua macchina!
license=Open Source
-license_desc=Ottieni Forgejo ! Partecipa per contribuire a rendere questo progetto ancora migliore. Non aver paura di diventare un collaboratore!
-install_desc = Semplicemente avvia l'eseguibile per la tua piattaforma, distribuiscilo con Docker , oppure scarica il pacchetto .
+license_desc=Ottieni Forgejo ! Partecipa per contribuire a rendere questo progetto ancora piรน bello. Non aver paura di diventare collaborante!
+install_desc = Semplicemente avvia l'eseguibile per la tua piattaforma, distribuiscilo con Docker , oppure scarica il pacchetto .
[install]
install=Installazione
title=Configurazione iniziale
docker_helper=Se stai usando Forgejo con Docker, leggi la documentazione prima di cambiare qualsiasi impostazione.
-require_db_desc=Forgejo requires MySQL, PostgreSQL, SQLite3 or TiDB (MySQL protocol).
+require_db_desc=Forgejo richiede MySQL, PostgreSQL, SQLite3 o TiDB (protocollo MySQL).
db_title=Impostazioni database
db_type=Tipo di database
host=Host
@@ -229,13 +249,13 @@ db_schema_helper=Lascia vuoto per il valore predefinito del database ("public").
ssl_mode=SSL
path=Percorso
sqlite_helper=Percorso file del database SQLite3. Inserisci un percorso assoluto se stai usando Forgejo come servizio.
-reinstall_error=Stai cercando di installare in un database Forgejo esistente
+reinstall_error=Stai cercando di installare Forgejo in una base dati giร esistente
reinstall_confirm_message=La reinstallazione con una base dati Forgejo esistente puรฒ causare vari problemi. Nella maggior parte dei casi, dovresti usare il tuo "app.ini" per eseguire Forgejo. Se sai cosa stai facendo, conferma quanto segue:
-reinstall_confirm_check_1=I dati crittografati da SECRET_KEY nell'app. ni potrebbe essere perso: gli utenti potrebbero non essere in grado di accedere con 2FA/OTP & mirror potrebbe non funzionare correttamente. Selezionando questa casella confermi che il file attuale app.ini contiene il corretto SECRET_KEY.
-reinstall_confirm_check_2=I repository e le impostazioni potrebbero avere bisogno di essere ri-sincronizzati. Selezionando questa casella confermi che potrai risincronizzare manualmente gli hook per i repository e il file authorized_keys. Confermi che assicurerai che le impostazioni del repository e del mirror siano corrette.
-reinstall_confirm_check_3=Confermi di essere assolutamente sicuro che questo Forgejo รจ in esecuzione con l'app corretta. ni posizione e che sei sicuro di dover reinstallare. Confermi di aver riconosciuto i rischi di cui sopra.
+reinstall_confirm_check_1=I dati crittografati da SECRET_KEY nell'app.ini potrebbero essere persi: gli utenti potrebbero non essere in grado di accedere con 2FA/OTP & i mirror potrebbero non funzionare correttamente. Selezionando questa casella confermi che il file attuale app.ini contiene il corretto SECRET_KEY.
+reinstall_confirm_check_2=I repositori e le impostazioni potrebbero avere bisogno di essere risincronizzati. Spuntando questa casella confermi che potrai risincronizzare manualmente gli hook per i repositori e il file authorized_keys. Confermi che ti assicurerai che le impostazioni dei repositori e dei mirror siano corrette.
+reinstall_confirm_check_3=Confermi di essere assolutamente sicurษ che questo Forgejo รจ in esecuzione con il file app.ini corretto e che sei sicurษ di dover reinstallare. Confermi di aver riconosciuto i rischi di cui sopra.
err_empty_db_path=Il percorso del database SQLite3 non puรฒ essere vuoto.
-no_admin_and_disable_registration=Non puoi disabilitare l'auto-registrazione degli utenti senza creare un account amministratore.
+no_admin_and_disable_registration=Non puoi disabilitare l'auto-registrazione degli utenti senza creare un profilo amministratore.
err_empty_admin_password=La password dell'amministratore non puรฒ essere vuota.
err_empty_admin_email=L'email dell'amministratore non puรฒ essere vuota.
err_admin_name_is_reserved=Nome utente Administrator non valido, nome utente riservato
@@ -244,11 +264,11 @@ err_admin_name_is_invalid=Il nome utente Administrator non รจ valido
general_title=Impostazioni generali
app_name=Titolo dell'istanza
-app_name_helper=Qui puoi inserire il nome della tua societร .
-repo_path=Percorso radice dei repository
-repo_path_helper=Le Remote Git repositories saranno salvate in questa directory.
+app_name_helper=Inserire qui il nome dell'istanza. Verrร visualizzato su ogni pagina.
+repo_path=Percorso radice del repositorio
+repo_path_helper=I repositori Git remoti saranno salvati in questa cartella.
lfs_path=Percorso radice di git LFS
-lfs_path_helper=I file trovati da Git LFS saranno salvati in questa directory. Lasciare vuoto per disattivare.
+lfs_path_helper=I file trovati da Git LFS saranno salvati in questa cartella. Lascia vuoto per disattivare.
run_user=Nome utente col quale eseguire
domain=Dominio server
domain_helper=Dominio o indirizzo host per il server.
@@ -266,27 +286,27 @@ email_title=Impostazioni e-mail
smtp_addr=Host SMTP
smtp_port=Porta SMTP
smtp_from=Invia e-mail come
-smtp_from_helper=Indirizzo Email che Forgejo utilizzerร . Inserisci un indirizzo email o usa il formato "Name" .
+smtp_from_helper=Indirizzo e-mail che verrร usato da Forgejo. Inserisci un indirizzo e-mail o usa il formato "Nome" .
mailer_user=Nome utente SMTP
mailer_password=Password SMTP
register_confirm=Richiedi conferma e-mail durante la registrazione
mail_notify=Attiva le notifiche e-mail
server_service_title=Impostazioni server e servizi di terze parti
offline_mode=Attiva modalitร in locale
-offline_mode.description=Disattiva le reti di distribuzione dei contenuti di terze parti e fornisci tutte le risorse localmente.
+offline_mode.description=Disattiva le reti di distribuzione dei contenuti di terze parti e servi tutte le risorse localmente.
disable_gravatar=Disattiva Gravatar
-disable_gravatar.description=Disattiva Gravatar e le fonti di avatar di terze parti. Verrร usato un avatar predefinito almeno che un utente non carichi un avatar in locale.
+disable_gravatar.description=Disabilita l'utilizzo di Gravatar o di altre fonti avatar di terze parti. Le immagini predefinite verranno utilizzate per gli avatar degli utenti a meno che non carichino il proprio avatar sull'istanza.
federated_avatar_lookup=Attiva le immagini profilo federate
-federated_avatar_lookup.description=Enable federated avatars lookup to use federated open source service based on libravatar.
+federated_avatar_lookup.description=Cerca gli avatar utilizzando Libravatar.
disable_registration=Disattiva auto-registrazione
-disable_registration.description=Disattiva la user self-registration. Solo gli amministratori saranno in grado di creare account.
-allow_only_external_registration.description=Attiva la registrazione solo tramite servizi esterni
+disable_registration.description=Solo gli amministratori dell'istanza potranno creare nuovi account utente. Si consiglia vivamente di mantenere la registrazione disabilitata a meno che non si intenda ospitare un'istanza pubblica per tutti e siate pronti a gestire grandi quantitร di account spam.
+allow_only_external_registration.description=Gli utenti potranno creare nuovi account usando i servizi esterni configurati.
openid_signin=Attiva l'accesso con OpenID
-openid_signin.description=Attiva registrazione utente via OpenID.
+openid_signin.description=Permetti agli utenti di registrarsi via OpenID.
openid_signup=Attiva auto-registrazione con OpenID
-openid_signup.description=Attiva OpenID-based user self-registration.
+openid_signup.description=Consenti agli utenti di creare account tramite OpenID se l'autoregistrazione รจ abilitata.
enable_captcha=Abilita CAPTCHA per registrazione
-enable_captcha.description=Richiedi convalida captcha per i nuovi utenti.
+enable_captcha.description=Richiedi convalida CAPTCHA per i nuovi utenti.
require_sign_in_view=Richiedi l'accesso per visualizzare il contenuto dell'istanza
admin_setting.description=Creare un account amministratore รจ opzionale. Il primo utente registrato sarร automaticamente un amministratore.
admin_title=Impostazioni profilo amministratore
@@ -298,7 +318,7 @@ install_btn_confirm=Installare Forgejo
test_git_failed=Non รจ stato possibile testare il comando "git": %v
sqlite3_not_available=Questa versione di Forgejo non supporta SQLite3. Si prega di scaricare la versione binaria ufficiale da %s (non la versione "gobuild").
invalid_db_setting=Le impostazioni del database sono invalide: %v
-invalid_repo_path=Il percorso radice del Repository รจ invalido: %v
+invalid_repo_path=Il percorso radice del repositorio รจ invalido: %v
invalid_app_data_path=Il percorso dati dell'app non รจ valido: %v
run_user_not_match=Il nome "utente con cui eseguire" non รจ il nome utente attuale: %s -> %s
internal_token_failed=Generazione del token interno non riuscita: %v
@@ -307,11 +327,11 @@ save_config_failed=Salvataggio della configurazione non riuscito: %v
invalid_admin_setting=Le impostazioni dell'account amministratore sono invalide: %v
invalid_log_root_path=Il percorso del log non รจ valido: %v
default_keep_email_private=Nascondi Indirizzo e-mail come impostazione predefinita
-default_keep_email_private.description=Nasconi l'indirizzo email dei nuovi account utente di default.
+default_keep_email_private.description=Nascondi l'indirizzo email dei nuovi utenti di default cosicchรฉ questa informazione non venga subito rivelata dopo la registrazione.
default_allow_create_organization=Consenti la creazione di organizzazioni come impostazione predefinita
-default_allow_create_organization.description=Consenti ai nuovi account utente di creare organizzazioni di default.
+default_allow_create_organization.description=Consenti ai nuovi utenti di creare organizzazioni per impostazione predefinita. Quando questa opzione รจ disabilitata, un amministratore dovrร concedere l'autorizzazione per la creazione di organizzazioni ai nuovi utenti.
default_enable_timetracking=Attiva il cronografo come impostazione predefinita
-default_enable_timetracking.description=Attiva il cronografo per le nuove repositories di default.
+default_enable_timetracking.description=Attiva di base il cronografo per i nuovi repositori.
no_reply_address=Dominio e-mail nascosto
no_reply_address_helper=Nome di dominio per utenti con un indirizzo email nascosto. Ad esempio, il nome utente "joe" accederร a Git come "joe@noreply.example.org" se il dominio email nascosto รจ impostato a "noreply.example.org".
password_algorithm=Algoritmo per hash delle password
@@ -322,25 +342,28 @@ invalid_password_algorithm = Algoritmo di hash della password non valido
enable_update_checker = Attiva il controllo degli aggiornamenti
env_config_keys = Configurazione Ambiente
env_config_keys_prompt = Le seguenti variabili di ambiente saranno anche applicate al tuo file di configurazione:
-run_user_helper = Il nome utente del sistema operativo con il quale Forgejo viene eseguito. Questo utente deve avere accesso alla cartella principale dei repository.
+run_user_helper = Il nome utente del sistema operativo con il quale Forgejo viene eseguito. Questo utente deve avere accesso alla cartella principale dei repositori.
password_algorithm_helper = Imposta l'algoritmo di hashing della password. Gli algoritmi hanno requisiti e punti di forza diversi. L'algoritmo argon2 รจ relativamente sicuro ma usa un sacco di memoria e potrebbe non essere appropriato a piccoli sistemi.
-require_sign_in_view.description = Limita l'accesso ad utenti autenticati. I visitatori vedranno solo le pagine di accesso e registrazione.
+require_sign_in_view.description = Limita l'accesso a utenti autenticati. I visitatori vedranno solo le pagine di accesso e registrazione.
allow_dots_in_usernames = Consenti l'uso del punto nel nome utente. Non impatta i profili giร esistenti.
config_location_hint = Queste opzioni di configurazione saranno salvate in:
+allow_only_external_registration = Permetti la registrazione solo tramite servizi esterni
+app_slogan = Slogan dell'istanza
+app_slogan_helper = Inserisci qui lo slogan della tua istanza. Lasciala vuota per disabilitarlo.
[home]
uname_holder=Nome utente o indirizzo e-mail
password_holder=Password
-switch_dashboard_context=Cambia Dashboard Context
-my_repos=Repositories
+switch_dashboard_context=Cambia dashboard context
+my_repos=Repositori
show_more_repos=Mostra altre repositoriesโฆ
-collaborative_repos=Repository Condivisi
+collaborative_repos=Repository condivisi
my_orgs=Organizzazioni
my_mirrors=I miei Mirror
view_home=Vedi %s
search_repos=Trova un repositoryโฆ
-filter=Altro filtri
-filter_by_team_repositories=Filtra per repository del team
+filter=Altri filtri
+filter_by_team_repositories=Filtra per repositorio del team
feed_of=`Feed di "%s"`
show_archived=Archiviato
@@ -353,10 +376,10 @@ show_both_private_public=Mostrando sia pubblico che privato
show_only_private=Visualizzazione solo privati
show_only_public=Mostrando solo pubblici
-issues.in_your_repos=Nei tuoi repository
+issues.in_your_repos=Nei tuoi repositori
[explore]
-repos=Repository
+repos=Repositori
users=Utenti
organizations=Organizzazioni
search=Cerca
@@ -373,8 +396,8 @@ go_to = Vai a
search.type.tooltip = Tipo di ricerca
search.fuzzy.tooltip = Includi anche i risultati che corrispondono parzialmente ai termini di ricerca
code_search_results = Risultati di ricerca per "%s"
-relevant_repositories_tooltip = Repository che sono fork o che non hanno un argomento, icona, nรฉ descrizione sono nascosti.
-relevant_repositories = Solo le repository pertinenti sono visibili, mostra risultati non filtrati .
+relevant_repositories_tooltip = I repositori derivati o che non hanno argomento, icona, nรฉ descrizione sono nascosti.
+relevant_repositories = Sono visibili solo i repositori pertinenti, mostra risultati non filtrati .
search.match.tooltip = Includi solo risultati che combaciano perfettamente con i termini di ricerca
stars_few = %d stelle
forks_one = %d fork
@@ -389,21 +412,21 @@ disable_register_prompt=La registrazione รจ disabilitata. Si prega di contattare
disable_register_mail=Email di conferma per la registrazione disabilitata.
manual_activation_only=Contatta l'amministratore del sito per completare l'attivazione.
remember_me=Ricorda questo dispositivo
-forgot_password_title=Password Dimenticata
+forgot_password_title=Password dimenticata
forgot_password=Password dimenticata?
sign_up_now=Hai bisogno di un account? Registrati adesso.
-confirmation_mail_sent_prompt=Una nuova email di conferma รจ stata inviata a %s . Per favore controlla la tua posta in arrivo nelle prossime %s per completare il processo di registrazione.
+confirmation_mail_sent_prompt=Una nuova e-mail di conferma รจ stata inviata a %s . Per completare la registrazione, controlla la tua posta in arrivo e clicca sul link in allegato entro i prossimi %s secondi. Se la tua e-mail รจ errata o incorretta, puoi accedere all'account e richiedere un'altra e-mail di conferma ad un'altro indirizzo.
must_change_password=Aggiorna la tua password
allow_password_change=Richiede all'utente di cambiare la password (scelta consigliata)
-reset_password_mail_sent_prompt=Una email di conferma รจ stata inviata a %s . Per favore controlla la tua posta in arrivo nelle prossime %s per completare il processo di reset della password.
-active_your_account=Attiva il tuo Account
+reset_password_mail_sent_prompt=Un'e-mail di conferma รจ stata inviata a %s . Per completare il processo di recupero dell'account, controlla la tua posta in arrivo e clicca sul link entro i prossimi %s secondi.
+active_your_account=Attiva il tuo account
account_activated=L'account รจ stato attivato
prohibit_login=L'accesso รจ proibito
resent_limit_prompt=Hai giร richiesto un'e-mail d'attivazione recentemente. Si prega di attenere 3 minuti e poi riprovare.
has_unconfirmed_mail=Ciao %s, hai un indirizzo di posta elettronica non confermato (%s ). Se non hai ricevuto una e-mail di conferma o vuoi riceverla nuovamente, fare clic sul pulsante qui sotto.
resend_mail=Clicca qui per inviare nuovamente l'e-mail di attivazione
email_not_associate=L'indirizzo email non รจ associato ad alcuna conta.
-send_reset_mail=Inviare email di recupero account
+send_reset_mail=Invia email di recupero
reset_password=Recupero account
invalid_code=Il tuo codice di conferma รจ invalido oppure รจ scaduto.
reset_password_helper=Recuperare account
@@ -417,12 +440,12 @@ twofa_passcode_incorrect=Il tuo passcode non รจ corretto. Se hai smarrito il tuo
twofa_scratch_token_incorrect=I tuo codice scratch non รจ corretto.
login_userpass=Accedi
tab_openid=OpenID
-oauth_signup_tab=Creare nuovo account
-oauth_signup_title=Completa Nuovo Account
-oauth_signup_submit=Completa l'Account
-oauth_signin_tab=Collegamento ad un Account Esistente
-oauth_signin_title=Accedi per autorizzare l' Account collegato
-oauth_signin_submit=Collega Account
+oauth_signup_tab=Crea nuovo account
+oauth_signup_title=Completa il nuovo account
+oauth_signup_submit=Completa l'account
+oauth_signin_tab=Collega ad un account esistente
+oauth_signin_title=Accedi per autorizzare l'account collegato
+oauth_signin_submit=Collega account
oauth.signin.error=Si รจ verificato un errore nell'elaborazione della richiesta di autorizzazione. Se questo errore persiste, si prega di contattare l'amministratore del sito.
oauth.signin.error.access_denied=La richiesta di autorizzazione รจ stata negata.
oauth.signin.error.temporarily_unavailable=Autorizzazione non riuscita perchรฉ il server di autenticazione non รจ temporaneamente disponibile. Riprova piรน tardi.
@@ -437,7 +460,7 @@ email_domain_blacklisted=Non รจ possibile registrarsi con il proprio indirizzo e
authorize_application=Autorizza applicazione
authorize_redirect_notice=Verrai reindirizzato a %s se autorizzi questa applicazione.
authorize_application_created_by=Questa applicazione รจ stata creata da %s.
-authorize_application_description=Se concedi l'accesso, l'app sarร in grado di accedere e modificare tutte le informazioni del tuo account, inclusi i repository privati e le organizzazioni.
+authorize_application_description=Se concedi l'accesso, l'app sarร in grado di accedere e modificare tutte le informazioni del tuo profilo, inclusi i repositori privati e le organizzazioni.
authorize_title=Vuoi autorizzare "%s" ad accedere al tuo account?
authorization_failed=Autorizzazione fallita
sspi_auth_failed=Autenticazione SSPI fallita
@@ -454,9 +477,14 @@ reset_password_wrong_user = Hai eseguito l'accesso come %s, ma il link per il ri
last_admin = Non puoi rimuovere l'ultimo amministratore. Deve esserci almeno un amministratore.
prohibit_login_desc = Al tuo profilo non รจ consentito effettuare l'accesso, contatta l'amministratore del sito.
openid_signin_desc = Inserisci il tuo URI OpenID. Per esempio: alice.openid.example.org o https://openid.example.org/alice.
-password_pwned = La password che hai scelto รจ in un elenco di password rubate precedentemente esposte a violazioni di dati pubblici. Riprova con una password diversa e valuta di modificare questa password anche altrove.
+password_pwned = La password che hai scelto รจ in un elenco di password rubate precedentemente esposte a violazioni di dati pubblici. Riprova con una password diversa e valuta di modificare questa password anche altrove.
tab_signup = Registrati
tab_signin = Accedi
+back_to_sign_in = Torna alla schermata d'accesso
+sign_in_openid = Procedi con OpenID
+hint_login = Hai giร un'utenza? Accedi!
+hint_register = Non hai un'utenza? Registrati ora.
+sign_up_button = Registrati ora.
[mail]
view_it_on=Visualizza su %s
@@ -471,7 +499,7 @@ activate_account.text_2=Clicca sul seguente link per attivare il tuo account ent
activate_email=Verifica il tuo indirizzo e-mail
activate_email.text=Clicca sul seguente link per verificare il tuo indirizzo email entro %s :
-register_notify=Benvenuto su Forgejo
+register_notify=Benvenutษ su %s
register_notify.title=%[1]s, benvenuto in %[2]s
register_notify.text_1=questa รจ la tua email di conferma di registrazione per %s!
register_notify.text_2=Puoi accedere al tuo profilo tramite il tuo nome utente: %s
@@ -483,21 +511,21 @@ reset_password.text=Se sei stato tu, clicca sul seguente link per recuperare il
register_success=Registrazione completata con successo
-issue_assigned.pull=@%[1]s ti ha assegnato il Problema %[2]s nel repository %[3]s.
-issue_assigned.issue=@%[1]s ti ha assegnato il Problema %[2]s nel repository %[3]s.
+issue_assigned.pull=@%[1]s ti ha assegnato la richiesta di modifica %[2]s nel repositorio %[3]s.
+issue_assigned.issue=@%[1]s ti ha assegnato la segnalazione %[2]s nel repositorio %[3]s.
issue.x_mentioned_you=@%s ti ha menzionato:
issue.action.force_push=%[1]s force-pushed il %[2]s da %[3]s a %[4]s.
issue.action.push_1=@%[1]s ha spinto %[3]d commit a %[2]s
-issue.action.push_n=@%[1]s ha spinto %[3]d commit a %[2]s
+issue.action.push_n=@%[1]s ha immesso %[3]d commit presso %[2]s
issue.action.close=@%[1]s chiuso #%[2]d.
issue.action.reopen=@%[1]s riaperto #%[2]d.
issue.action.merge=@%[1]s unito #%[2]d in %[3]s.
-issue.action.approve=@%[1]s ha approvato questa pull request.
-issue.action.reject=@%[1]s ha richiesto modifiche su questa pull request.
-issue.action.review=@%[1]s ha commentato questa pull request.
-issue.action.review_dismissed=@%[1]s ha respinto l'ultima recensione da %[2]s per questa pull request.
-issue.action.ready_for_review=@%[1]s ha contrassegnato questa pull request pronta per la revisione.
+issue.action.approve=@%[1]s ha approvato questa richiesta di modifica.
+issue.action.reject=@%[1]s ha richiesto modifiche su questa richiesta.
+issue.action.review=@%[1]s ha commentato questa richiesta di modifica.
+issue.action.review_dismissed=@%[1]s ha respinto l'ultima revisione di %[2]s per questa richiesta di modifica.
+issue.action.ready_for_review=@%[1]s ha contrassegnato questa richiesta di modifica come pronta per la revisione.
issue.action.new=@%[1]s creato #%[2]d.
issue.in_tree_path=In %s:
@@ -509,13 +537,13 @@ release.downloads=Scaricamenti:
release.download.zip=Codice Sorgente (Zip)
release.download.targz=Codice Sorgente (Tar.Gz)
-repo.transfer.subject_to=%s vorrebbe trasferire il progetto "%s" presso %s
-repo.transfer.subject_to_you=%s vorrebbe trasferire il progetto "%s" a te
+repo.transfer.subject_to=%s vorrebbe trasferire il repositorio "%s" presso %s
+repo.transfer.subject_to_you=%s ti vorrebbe trasferire il repositorio "%s"
repo.transfer.to_you=tu
repo.transfer.body=Per accettare o respingerla visita %s o semplicemente ignorarla.
-repo.collaborator.added.subject=%s ti ha aggiunto a %s come collaboratorษ
-repo.collaborator.added.text=Sei statษ aggiuntษ come collaboratorษ al progetto:
+repo.collaborator.added.subject=%s ti ha aggiunto a %s come collaborante
+repo.collaborator.added.text=Sei statษ aggiuntษ come collaborante al repositorio:
reply = o rispondi direttamente a questa email
admin.new_user.subject = Il nuovo utente %s si รจ appena registrato
admin.new_user.user_info = Informazioni utente
@@ -525,6 +553,21 @@ activate_email.title = %s, verifica il tuo indirizzo email
admin.new_user.text = Clicca qui per gestire questo utente dal pannello di amministrazione.
team_invite.text_1 = %[1]s ti ha invitato a far parte del team %[2]s nell'organizzazione %[3]s.
team_invite.text_3 = Nota: Questo invito รจ destinato a %[1]s. Se non ti aspettavi questo invito, puoi ignorare questa email.
+primary_mail_change.subject = La tua mail principale รจ stata cambiata
+removed_security_key.no_2fa = Non ci sono piรน altri metodi di autenticazione a due fattori configurati, ergo non c'รจ piรน bisogno di accedere alla tua utenza tramite tale autenticazione.
+primary_mail_change.text_1 = La mail principale della tua utenza รจ appena stata cambiata in %[1]s. Ciรฒ significa che questo indirizzo di posta elettronica non riceverร piรน notifiche mail da quest'utenza.
+totp_disabled.subject = La TOTP รจ stata disabilitata
+totp_disabled.no_2fa = Non ci sono piรน altri metodi d'autenticazione a due fattori configurati, ergo non c'รจ piรน bisogno di accedere alla tua utenza con tale autenticazione.
+removed_security_key.subject = ร stata rimossa una chiave di sicurezza
+removed_security_key.text_1 = La chiave di sicurezza "%[1]s" รจ appena stata rimossa dalla tua utenza.
+totp_disabled.text_1 = La password a tempo usa e getta (TOTP) della tua utenza รจ appena stata disabilitata.
+totp_enrolled.subject = Hai attivato la TOTP come metodo d'autenticazione a due fattori
+totp_enrolled.text_1.no_webauthn = Hai appena attivato la TOTP per la tua utenza. Ciรฒ significa che dovrai usarla come metodo d'autenticazione a due fattori per tutti i tuoi accessi futuri.
+totp_enrolled.text_1.has_webauthn = Hai appena attivato la TOTP per la tua utenza. Ciรฒ significa che dovrai usare come metodo d'autenticazione a due fattori per i tuoi accessi futuri tale TOTP o una delle tue chiavi di sicurezza.
+password_change.subject = La tua password รจ stata modificata
+password_change.text_1 = La password della tua utenza รจ appena stata modificata.
+account_security_caution.text_1 = Se sei statษ tu, puoi ignorare questa mail.
+account_security_caution.text_2 = Se non sei statษ tu, la tua utenza รจ compromessa. Contatta l'amministrazione del sito.
[modal]
@@ -536,7 +579,7 @@ confirm = Conferma
[form]
UserName=Nome utente
-RepoName=Nome Repository
+RepoName=Nome repositorio
Email=Indirizzo E-mail
Password=Password
Retype=Conferma password
@@ -574,17 +617,17 @@ lang_select_error=Selezionare una lingua dall'elenco.
username_been_taken=Il Nome utente esiste giร .
username_change_not_local_user=Gli utenti non locali non sono autorizzati a modificare il proprio nome utente.
-repo_name_been_taken=Il nome del repository esiste giร .
-repository_force_private=Force Private รจ abilitato: i repository privati non possono essere resi pubblici.
-repository_files_already_exist=File giร esistenti per questo repository. Contatta l'amministratore di sistema.
-repository_files_already_exist.adopt=I file esistono giร per questo repository e possono essere solo Adottati.
-repository_files_already_exist.delete=I file esistono giร per questo repository. ร necessario eliminarli.
-repository_files_already_exist.adopt_or_delete=I file esistono giร per questo repository. O li Adotti o li Elimini.
+repo_name_been_taken=Questo nome รจ giร utilizzato da un altro repositorio.
+repository_force_private=Force Private รจ abilitato: i repositori privati non possono essere resi pubblici.
+repository_files_already_exist=File giร esistenti per questo repositorio. Contatta l'amministratore di sistema.
+repository_files_already_exist.adopt=I file esistono giร per questo repositorio e possono solo essere Adottati.
+repository_files_already_exist.delete=I file esistono giร per questo repositorio. ร necessario eliminarli.
+repository_files_already_exist.adopt_or_delete=I file esistono giร per questo repositorio. O li adotti o li elimini.
visit_rate_limit=La visita remota ha segnalato un limite raggiunto.
2fa_auth_required=La visita remota ha richiesto l'autenticazione a due fattori.
org_name_been_taken=Il nome della organizzazione esiste giร .
team_name_been_taken=Il nome del team esiste giร .
-team_no_units_error=Consenti l'accesso ad almeno una sezione del repository.
+team_no_units_error=Consenti l'accesso ad almeno una sezione del repositorio.
email_been_used=L'indirizzo email รจ giร in uso.
email_invalid=L'indirizzo email non รจ valido.
username_password_incorrect=Nome utente o password non corretti.
@@ -593,7 +636,7 @@ password_lowercase_one=Almeno un carattere minuscolo
password_uppercase_one=Almeno un carattere maiuscolo
password_digit_one=Almeno una cifra
password_special_one=Almeno un carattere speciale (punteggiatura, parentesi, virgolette, etc.)
-enterred_invalid_repo_name=Il nome del repository inserito non รจ corretto.
+enterred_invalid_repo_name=Il nome del repositorio inserito non รจ corretto.
enterred_invalid_org_name=Il nome dell'organizzazione inserito non รจ corretto.
enterred_invalid_owner_name=Il nuovo nome del proprietario non รจ valido.
enterred_invalid_password=La password inserita non รจ corretta.
@@ -610,7 +653,7 @@ auth_failed=Autenticazione non riuscita: %v
target_branch_not_exist=Il ramo di destinazione non esiste.
org_still_own_packages = Questa organizzazione รจ ancora proprietaria di uno o piรน pacchetti, devi prima eliminarli.
-org_still_own_repo = Questa organizzazione รจ ancora proprietaria di una o piรน repository, devi prima eliminarle o trasferirle.
+org_still_own_repo = Questa organizzazione possiede uno o piรน repositoro; devi prima eliminarli o trasferirli.
still_own_packages = Il tuo profilo รจ ancora proprietario di uno o piรน pacchetti, devi prima eliminarli.
openid_been_used = L'indirizzo OpenID "%s" รจ giร in uso.
url_error = `"%s" non รจ un URL valido.`
@@ -623,7 +666,7 @@ admin_cannot_delete_self = Non puoi eliminare il tuo profilo mentre sei un ammin
username_error_no_dots = ` puรฒ solo contenere caratteri alfanumerici ("0-9","a-z","A-Z"), trattini ("-") e underscore ("_"). Non puรฒ iniziare o finire con caratteri non-alfanumerici, e sono vietati anche piรน caratteri non-alfanumerici consecutivi.`
username_has_not_been_changed = Il nome utente non รจ stato cambiato
must_use_public_key = La chiave che hai fornito รจ una chiave privata. Non caricare la tua chiave privata da nessuna parte. Usa invece la tua chiave pubblica.
-still_own_repo = Il tuo profilo รจ ancora proprietario di una o piรน repository, devi prima eliminarle o trasferirle.
+still_own_repo = Il tuo profilo possiede uno o piรน repositori; devi prima eliminarli o trasferirli.
duplicate_invite_to_team = L'utente รจ giร stato invitato ad essere un membro del team.
still_has_org = Il tuo profilo รจ ancora membro di una o piรน organizzazioni, devi prima abbandonarle.
unsupported_login_type = Il tipo di accesso non รจ supportato per l'eliminazione del profilo.
@@ -641,11 +684,11 @@ To = Nome del ramo
[user]
change_avatar=Modifica il tuo avatarโฆ
-repositories=Repository
+repositories=Repositori
activity=Attivitร pubblica
followers_few=%d seguaci
-starred=Repository preferite
-watched=Repository osservate
+starred=Repositori preferiti
+watched=Repositori osservati
projects=Progetti
overview=Riepilogo
following_few=%d seguiti
@@ -656,8 +699,8 @@ disabled_public_activity=L'utente ha disabilitato la vista pubblica dell'attivit
joined_on = Membro dal %s
block_user = Blocca utente
block_user.detail_1 = Questo utente non ti seguirร piรน.
-block_user.detail_2 = Quest'utente non potrร interagire con le tue repository, con le segnalazioni che hai aperto nรฉ con i tuoi commenti.
-block_user.detail_3 = Questo utente non ti potrร aggiungere come un collaboratore, nรฉ potrai tu aggiungerlo come un collaboratore.
+block_user.detail_2 = Quest'utente non potrร interagire nรฉ con i tuoi repositori, nรฉ con le segnalazioni che hai aperto, nรฉ con i tuoi commenti.
+block_user.detail_3 = Non sarete in grado di aggiungervi come collaboranti del repositorio.
code = Codice
block = Blocca
unblock = Sblocca
@@ -672,6 +715,14 @@ form.name_pattern_not_allowed = La sequenza "%s" non รจ consentita in un nome ut
follow_blocked_user = Non puoi seguire questo utente perchรจ hai bloccato questo utente o perchรจ questo utente ha bloccato te.
followers_one = %d seguace
following_one = %d seguito
+public_activity.visibility_hint.self_public = L'attivitร รจ visibile a tutti, tranne che per le interazioni negli spazi privati. Configura .
+public_activity.visibility_hint.admin_public = Questa attivitร รจ visibile a tutti, ma come amministratore, si possono vedere anche le interazioni negli spazi privati.
+public_activity.visibility_hint.self_private = L'attivitร รจ visibile solo a te e agli amministratori dell'istanza. Configura .
+public_activity.visibility_hint.admin_private = Questa attivitร รจ visibile a te perchรฉ sei un amministratore, ma l'utente desidera che rimanga privata.
+followers.title.one = Seguace
+followers.title.few = Seguaci
+following.title.one = Seguito
+following.title.few = Osservato
[settings]
@@ -685,7 +736,7 @@ ssh_gpg_keys=Chiavi SSH / GPG
social=Account Sociali
applications=Applicazioni
orgs=Gestisci le organizzazioni
-repos=Repository
+repos=Repositori
delete=Elimina account
twofa=Verifica in due passaggi
account_link=Account collegati
@@ -719,9 +770,9 @@ comment_type_group_deadline=Scadenza
comment_type_group_dependency=Dipendenza
comment_type_group_lock=Stato blocco
comment_type_group_review_request=Richiesta di revisione
-comment_type_group_pull_request_push=Aggiunti commit
+comment_type_group_pull_request_push=Commit aggiunti
comment_type_group_project=Progetto
-comment_type_group_issue_ref=Riferimento del problema
+comment_type_group_issue_ref=Riferimento alla segnalazione
saved_successfully=Le impostazioni sono state salvate correttamente.
privacy=Privacy
keep_activity_private_popup=La tua attivitร sarร visibile solo a te e agli amministratori dell'istanza
@@ -756,7 +807,7 @@ activate_email=Invia Attivazione
activations_pending=Attivazioni in sospeso
delete_email=Rimuovi
email_deletion=Rimuovi indirizzo Email
-email_deletion_desc=L'indirizzo email e le relativa informazioni verranno rimosse dal tuo account. I Git commits di questa email rimarranno invariati. Continuare?
+email_deletion_desc=L'indirizzo e-mail e altre informazioni relative a questa utenza verranno rimosse. I commit di git associati a questo indirizzo e-mail rimarranno invariati. Continuare?
email_deletion_success=L'indirizzo email รจ stato eliminato.
theme_update_success=Il tema รจ stato aggiornato.
theme_update_error=Il tema selezionato non esiste.
@@ -778,7 +829,7 @@ manage_ssh_principals=Gestisci i Certificati SSH
manage_gpg_keys=Gestisci chiavi GPG
add_key=Aggiungi chiave
ssh_desc=Queste chiavi SSH pubbliche sono associate al tuo profilo. Le corrispondenti chiavi private consentono l'accesso completo ai tuoi progetti. Le chiavi SSH che sono state verificate possono essere usate per verificare commit Git firmati tramite SSH.
-principal_desc=Questi certificati SSH principali sono associati al tuo account e permettono l'accesso completo alle tue repository.
+principal_desc=Queste entitร di certificato SSH sono associate al tuo profilo e forniscono l'accesso completo ai tuoi repositori.
gpg_desc=Queste chiavi GPG pubbliche sono associate con il tuo profilo e sono usate per verificare i tuoi commit. Proteggi le tue chiavi private perchรฉ permettono di firmare i commit con la tua identitร .
ssh_helper= Hai bisogno di aiuto? Dร i un'occhiata alla guida percreare le tue chiavi SSH o risolvere quei problemi comuni in cui potresti imbatterti utilizzando SSH.
gpg_helper=Hai bisogno di aiuto? Dai un'occhiata alla guida di GitHub riguardo il GPG .
@@ -898,7 +949,7 @@ passcode_invalid=Il codice di accesso non รจ corretto. Riprova.
twofa_enrolled=Il tuo account รจ stato registrato alla verifica in due passaggi. Conserva il token di sicurezza (%s) in un luogo sicuro in quanto viene visualizzato sono una volta!
twofa_failed_get_secret=Impossibile ottenere il segreto.
-webauthn_desc=Le chiavi di sicurezza sono dispositivi hardware contenenti chiavi crittografiche. Possono essere utilizzate per l'autenticazione a due fattori. Le chiavi di sicurezza devono supportare lo standard WebAuthenticator di WebAuthn.
+webauthn_desc=Le chiavi di sicurezza sono dispositivi hardware contenenti chiavi crittografiche. Possono essere utilizzate per l'autenticazione a due fattori. Le chiavi di sicurezza devono supportare lo standard WebAuthenticator di WebAuthn.
webauthn_register_key=Aggiungi chiave di sicurezza
webauthn_nickname=Soprannome
webauthn_delete_key=Rimuovi chiave di sicurezza
@@ -958,7 +1009,7 @@ valid_until_date = Valido fino a %s
ssh_signonly = SSH รจ attualmente disabilitato quindi queste chiavi sono usate solo per la firma di verifica dei commit.
social_desc = Questi profili social possono essere usati per accedere al tuo profilo. Assicurati di riconoscerli tutti.
permission_write = Leggi e scrivi
-access_token_desc = I permessi token selezionati limitano l'autorizzazione solo alle corrispondenti vie API . Leggi la documentazione per ulteriori informazioni.
+access_token_desc = I permessi token selezionati limitano l'autorizzazione solo alle corrispondenti vie API . Leggi la documentazione per ulteriori informazioni.
create_oauth2_application_success = Hai correttamente creato una nuova applicazione OAuth2.
update_oauth2_application_success = Hai correttamente aggiornato l'applicazione OAuth2.
oauth2_redirect_uris = URI per la reindirizzazione. Usa una nuova riga per ogni URI.
@@ -980,7 +1031,7 @@ hidden_comment_types.issue_ref_tooltip = Commenti in cui l'utente ha cambiato il
add_key_success = La chiave SSH "%s" รจ stata aggiunta.
add_gpg_key_success = La chiave GPG "%s" รจ stata aggiunta.
add_principal_success = Il certificato principale SSH "%s" รจ stato aggiunto.
-repo_and_org_access = Accesso al progetto e all'organizzazione
+repo_and_org_access = Accesso al repositorio e all'organizzazione
permissions_access_all = Tutto (publico, privato e limitato)
oauth2_client_secret_hint = Il segreto non verrร mostrato nuovamente dopo che lasci o ricarichi questa pagina. Assicurati di averlo salvato.
oauth2_application_remove_description = Rimuovere un'applicazione OAuth2 le impedirร di accedere a profili utenti autorizzati su questa istanza. Continuare?
@@ -988,44 +1039,47 @@ oauth2_application_locked = Forgejo preregistra alcune applicazioni OAuth2 all'a
hooks.desc = Aggiungi richiami HTTP che saranno innescati per tutti i progetti che possiedi.
repos_none = Non possiedi alcun progetto.
blocked_users_none = Non ci sono utenti bloccati.
-keep_email_private_popup = Questo nasconderร il tuo indirizzo e-mail nel tuo profilo, nelle pull request e quando modifichi un file usando l'interfaccia web. I commit inoltrati non saranno modificati. Usa %s nei commit per associarli al tuo profilo.
+keep_email_private_popup = Questo nasconderร il tuo indirizzo e-mail nel tuo profilo, nelle richieste di modifica e quando modifichi un file usando l'interfaccia web. I commit inoltrati non saranno modificati. Usa %s nei commit per associarli al tuo profilo.
verify_gpg_key_success = La chiave GPG "%s" รจ stata verificata.
added_on = Aggiunto su %s
-additional_repo_units_hint = Incoraggia l'attivazione di sezioni aggiuntive nelle repository
+additional_repo_units_hint = Suggerisci l'attivazione di unitร aggiuntive nel repositorio
update_hints = Aggiorna suggerimenti
update_hints_success = I suggerimenti sono stati aggiornati.
-additional_repo_units_hint_description = Mostra un pulsante "Aggiungi piรน sezioni..." per le repository che non hanno tutte le sezioni disponibili aggiunte.
+additional_repo_units_hint_description = Mostra un pulsante "Aggiungi piรน sezioni..." per i repositori che non hanno tutte le sezioni disponibili aggiunte.
hints = Suggerimenti
pronouns = Pronomi
pronouns_custom = Personalizzato
pronouns_unspecified = Non specificato
+language.title = Lingua predefinita
+language.description = Questa lingua verrร salvata nella tua utenza e verrร usata come predefinita ogni volta che farai l'accesso.
+language.localization_project = Aiutaci a tradurre Forgejo nella tua lingua! Piรน informazioni .
[repo]
owner=Proprietario
-owner_helper=Alcune organizzazioni potrebbero non essere visualizzate nel menu a discesa a causa di un limite massimo al numero di repository.
-repo_name=Nome progetto
-repo_name_helper=Un buon nome per un repository รจ costituito da parole chiave corte, facili da ricordare e uniche.
-repo_size=Dimensione repository
+owner_helper=Alcune organizzazioni potrebbero non essere visualizzate nel menรน a tendina a causa di un limite massimo al numero di repositori.
+repo_name=Nome del repositorio
+repo_name_helper=Un buon nome per un repositorio รจ costituito da parole chiave corte, facili da ricordare e uniche.
+repo_size=Dimensione del repositorio
template=Modello
template_select=Seleziona un modello.
-template_helper=Rendi il repository un modello
-template_description=I modelli di repository consentono agli utenti di generare nuove repository con la stessa struttura, file e impostazioni facoltative.
+template_helper=Rendi il repositorio un modello
+template_description=I modelli di repositori consentono allษ utenti di generare nuovi repositori con la stessa struttura, file e impostazioni facoltative.
visibility=Visibilitร
visibility_description=Solo il proprietario o i membri dell'organizzazione se hanno diritti, saranno in grado di vederlo.
-visibility_helper_forced=L'amministratore del sito impone che le nuove repository siano private.
+visibility_helper_forced=L'amministratorษ del sito impone che i nuovi repositori siano privati.
visibility_fork_helper=(Questa modifica influenzerร la visibilitร di tutti i fork.)
clone_helper=Hai bisogno di aiuto per la clonazione? Visita Help .
-fork_repo=Deriva progetto
+fork_repo=Deriva repositorio
fork_from=Deriva da
already_forked=Hai giร fatto il fork di %s
fork_to_different_account=Fai Fork a un account diverso
-fork_visibility_helper=La visibilitร di un repository forkato non puรฒ essere modificata.
+fork_visibility_helper=La visibilitร di un repositorio derivato non puรฒ essere modificata.
use_template=Usa questo modello
clone_in_vsc=Clona nel codice VS
download_zip=Scarica ZIP
download_tar=Scarica TAR.GZ
download_bundle=Scarica BUNDLE
-generate_repo=Genera progetto
+generate_repo=Genera repositorio
generate_from=Genera da
repo_desc=Descrizione
repo_desc_helper=Inserisci una breve descrizione (opzionale)
@@ -1040,13 +1094,13 @@ license_helper_desc=Una licenza governa ciรฒ che gli altri possono e non possono
readme=LEGGIMI
readme_helper=Seleziona un template per il file LEGGIMI.
readme_helper_desc=Qui puoi scrivere una descrizione completa del progetto.
-auto_init=Inizializza progetto (Aggiunge .gitignore, Licenza e LEGGIMI)
+auto_init=Inizializza repositorio (Aggiunge .gitignore, licenza e README)
trust_model_helper=Seleziona il modello di fiducia per la verifica della firma. Le opzioni possibili sono:
trust_model_helper_collaborator=Collaboratore: Fidati delle firme da parte dei collaboratori
trust_model_helper_committer=Committer: Fidati delle Firme che corrispondono ai committenti
trust_model_helper_collaborator_committer=Collaboratore+Committer: Fidati delle firme da parte dei collaboratori che corrispondono al committer
trust_model_helper_default=Predefinito: utilizzare il modello di trust predefinito per questa installazione
-create_repo=Crea progetto
+create_repo=Crea repositorio
default_branch=Ramo predefinito
default_branch_helper=Il ramo predefinito รจ il ramo base per le richieste di modifica e i commit.
mirror_prune=Rimuovi
@@ -1059,7 +1113,7 @@ mirror_address_desc=Metti tutte le credenziali richieste nella sezione Autorizza
mirror_lfs=Large File Storage (LFS)
mirror_lfs_desc=Attiva il mirroring dei dati LFS.
mirror_lfs_endpoint=Punto d'accesso LFS
-mirror_lfs_endpoint_desc=La sincronizzazione tenterร di utilizzare l'url clone per determinare il server LFS . ร inoltre possibile specificare un endpoint personalizzato se il repository dati LFS รจ memorizzato da qualche altra parte.
+mirror_lfs_endpoint_desc=La sincronizzazione tenterร di utilizzare l'url clone per determinare il server LFS . ร inoltre possibile specificare un endpoint personalizzato se il repositorio dati LFS รจ memorizzato da qualche altra parte.
mirror_last_synced=Ultima sincronizzazione
mirror_password_placeholder=(Inmodificato)
mirror_password_blank_placeholder=(Disattivato)
@@ -1068,13 +1122,13 @@ watchers=Osservatori
stargazers=Fan
forks=Fork
reactions_more=e %d piรน
-unit_disabled=L'amministratore ha disabilitato questa sezione del repository.
+unit_disabled=L'amministratorษ ha disabilitato questa sezione del repositorio.
language_other=Altro
-adopt_search=Inserisci il nome utente per cercare i repository non adottati... (lascia vuoto per trovare tutti)
+adopt_search=Inserisci il nome utente per cercare i repositori non adottati... (lascia vuoto per trovarli tutti)
adopt_preexisting_label=Adotta file
adopt_preexisting=Adottare file preesistenti
-adopt_preexisting_content=Crea repository da %s
-adopt_preexisting_success=File adottati e repository creati da %s
+adopt_preexisting_content=Crea repositorio da %s
+adopt_preexisting_success=File adottati e repositori creati da %s
delete_preexisting_label=Elimina
delete_preexisting=Elimina file preesistenti
delete_preexisting_content=Elimina file in %s
@@ -1096,42 +1150,42 @@ desc.archived=Archiviato
template.items=Elementi del modello
template.git_content=Contenuto di git (Ramo predefinito)
template.git_hooks=Hook Gitt
-template.git_hooks_tooltip=Al momento non sei in grado di modificare o rimuovere Git hook una volta aggiunti. Selezionare questa opzione solo se ti fidi del progetto modello.
-template.webhooks=Webhooks
+template.git_hooks_tooltip=Al momento non sei in grado di modificare o rimuovere gli hook Git una volta aggiunti. Selezionare questa opzione solo se ti fidi del modello di repositorio.
+template.webhooks=Webhook
template.topics=Argomenti
template.avatar=Avatar
template.issue_labels=Etichette segnalazioni
template.one_item=Deve selezionare almeno un elemento del modello
-template.invalid=Devi selezionare un modello di repository
+template.invalid=Devi selezionare un modello di repositorio
-archive.issue.nocomment=Questo repository รจ archiviato. Non puoi commentare le segnalazioni.
-archive.pull.nocomment=Questo repository รจ archiviato. Non puoi commentare le richieste di pull.
+archive.issue.nocomment=Questo repositorio รจ archiviato. Non puoi commentare le segnalazioni.
+archive.pull.nocomment=Questo repositorio รจ archiviato. Non puoi commentare le richieste di modifica.
-form.reach_limit_of_creation_1=Hai giร raggiunto il tuo limite di %d repository.
-form.reach_limit_of_creation_n=Hai giร raggiunto il tuo limite di %d repository.
+form.reach_limit_of_creation_1=Lษ proprietariษ ha giร raggiunto il limite di %d repositori.
+form.reach_limit_of_creation_n=Lษ proprietariษ ha giร raggiunto il limite di %d repositori.
need_auth=Autorizzazione
migrate_options=Opzioni di migrazione
migrate_service=Servizio migrazione
-migrate_options_mirror_helper=Questo repository sarร un mirror
+migrate_options_mirror_helper=Questo repositorio sarร un mirror
migrate_options_lfs=Migra file LFS
migrate_options_lfs_endpoint.label=Punto d'accesso LFS
-migrate_options_lfs_endpoint.description=La migrazione tenterร di utilizzare il tuo Git remote per determinare il server LFS . ร inoltre possibile specificare un endpoint personalizzato se il repository dati LFS รจ memorizzato da qualche altra parte.
+migrate_options_lfs_endpoint.description=La migrazione tenterร di utilizzare il tuo Git remote per determinare il server LFS . ร inoltre possibile specificare un endpoint personalizzato se il repositorio dati LFS รจ memorizzato da qualche altra parte.
migrate_options_lfs_endpoint.description.local=ร supportato anche un percorso server locale.
migrate_items=Elementi di migrazione
migrate_items_wiki=Wiki
-migrate_items_milestones=Milestone
+migrate_items_milestones=Traguardi
migrate_items_labels=Etichette
-migrate_items_issues=Issues
+migrate_items_issues=Segnalazioni
migrate_items_pullrequests=Richieste di modifica
migrate_items_merge_requests=Richieste di fusione
migrate_items_releases=Rilasci
-migrate_repo=Migra progetto
+migrate_repo=Migra repositorio
migrate.clone_address=Migra / Clona da URL
-migrate.clone_address_desc=URL HTTP(S) o Git "clone" di un progetto esistente
+migrate.clone_address_desc=URL HTTP(S) o Git "clone" di un repositorio esistente
migrate.github_token_desc=ร possibile mettere uno o piรน token con virgola separati qui per rendere la migrazione piรน veloce a causa del limite di velocitร API GitHub. ATTENZIONE: L'abuso di questa funzione potrebbe violare la politica del fornitore di servizi e portare al blocco dell'account.
migrate.clone_local_path=o un percorso del server locale
-migrate.permission_denied=Non รจ consentito importare repository locali.
+migrate.permission_denied=Non รจ consentito importare repositori locali.
migrate.permission_denied_blocked=Non รจ possibile importare da host non consentiti, si prega di chiedere all'amministratore di controllare ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS impostazioni.
migrate.invalid_lfs_endpoint=Il punto d'accesso LFS non รจ valido.
migrate.failed=Migrazione non riuscita: %v
@@ -1143,42 +1197,42 @@ migrate.migrating=Migrazione da %s ...
migrate.migrating_failed=Migrazione da %s fallita.
migrate.migrating_failed_no_addr=Migrazione non riuscita.
migrate.github.description=Migrare i dati da github.com o da server GitHub Enterprise.
-migrate.git.description=Migra un repository solo da qualsiasi servizio Git.
+migrate.git.description=Migra un repositorio solo da qualsiasi servizio Git.
migrate.gitlab.description=Migrare i dati da gitlab.com o da altre istanze di GitLab.
-migrate.gitea.description=Migrare i dati da gitea.com o altre istanze di Gitea/Forgejo.
+migrate.gitea.description=Migrare i dati da gitea.com o altre istanze di Gitea.
migrate.gogs.description=Migrare i dati da notabug.org o da altre istanze Gogs.
migrate.onedev.description=Migrare i dati da code.onedev.io o da altre istanze OneDev.
migrate.codebase.description=Migrare i dati da codebasehq.com.
migrate.gitbucket.description=Migra i dati dalle istanze di GitBucket.
migrate.migrating_git=Migrazione dei dati Git
migrate.migrating_topics=Migrazione degli argomenti
-migrate.migrating_milestones=Migrazione delle pietre miliari
+migrate.migrating_milestones=Migrazione dei traguardi
migrate.migrating_labels=Migrazione delle etichette
migrate.migrating_releases=Migrazione dei rilasci
migrate.migrating_issues=Migrazione delle segnalazioni
migrate.migrating_pulls=Migrazione delle richieste di modifica
mirror_from=mirror da
-forked_from=forkato da
+forked_from=derivato da
generated_from=generato da
-fork_from_self=Non puoi effettuare il fork del tuo stesso repository.
-fork_guest_user=Accedi per effettuare il fork di questo repository.
-watch_guest_user=Accedi per seguire questo repository.
-star_guest_user=Accedi per marcare in questo repository.
+fork_from_self=Non puoi derivare il tuo stesso repositorio.
+fork_guest_user=Accedi per derivare questo repositorio.
+watch_guest_user=Accedi per seguire questo repositorio.
+star_guest_user=Accedi per aggiungere questo repositorio tra i preferiti.
unwatch=Non seguire piรน
watch=Segui
unstar=Togli il voto
-star=Vota
-fork=Forka
-download_archive=Scarica progetto
+star=Salva
+fork=Deriva
+download_archive=Scarica repositorio
no_desc=Nessuna descrizione
quick_guide=Guida rapida
-clone_this_repo=Clona questo repository
-create_new_repo_command=Creazione di un nuovo repository da riga di comando
-push_exist_repo=Push di un repository esistente da riga di comando
-empty_message=Questo repository non contiene alcun contenuto.
-broken_message=I dati Git sottostanti a questo repository non possono essere letti. Contattare l'amministratore di questa istanza o eliminare questo repository.
+clone_this_repo=Clona questo repositorio
+create_new_repo_command=Creazione di un nuovo repositorio da riga di comando
+push_exist_repo=Immissione di un repositorio esistente da riga di comando
+empty_message=Questo repositorio non contiene alcun contenuto.
+broken_message=I dati Git di questo repositorio non possono essere letti. Contattare l'amministratorษ di questa istanza o eliminare il repositorio.
code=Codice
code.desc=Accedi al codice sorgente, ai file, ai commit e ai rami.
@@ -1194,7 +1248,7 @@ pulls=Richieste di modifica
project_board=Progetti
packages=Pacchetti
labels=Etichette
-org_labels_desc=Etichette a livello di organizzazione che possono essere utilizzate con tutti i repository sotto questa organizzazione
+org_labels_desc=Etichette a livello di organizzazione che possono essere utilizzate su tutti i repositori di questa organizzazione
org_labels_desc_manage=gestisci
milestones=Traguardi
@@ -1210,7 +1264,7 @@ file_history=Cronologia
file_view_source=Visualizza sorgente
file_view_rendered=Visualizza renderizzato
file_view_raw=Vedi originale
-file_permalink=Permalink
+file_permalink=Permacollegamento
file_too_large=Il file รจ troppo grande per essere visualizzato.
invisible_runes_line=`Questa riga ha caratteri unicode invisibili`
ambiguous_runes_line=`Questa riga ha caratteri unicode ambigui`
@@ -1223,13 +1277,14 @@ view_git_blame=Visualizza git incolpa
video_not_supported_in_browser=Il tuo browser non supporta le etichette "video" di HTML5.
audio_not_supported_in_browser=Il tuo browser non supporta le etichette "audio" di HTML5.
stored_lfs=Memorizzati con Git LFS
+stored_annex=Memorizzati con Git Annex
symbolic_link=Link Simbolico
commit_graph=Grafico dei commit
commit_graph.select=Seleziona rami
commit_graph.hide_pr_refs=Nascondi richieste di modifica
commit_graph.monochrome=Mono
commit_graph.color=Colore
-blame=Blame
+blame=Incolpa
download_file=Scarica file
normal_view=Vista normale
line=riga
@@ -1241,11 +1296,12 @@ editor.upload_file=Carica file
editor.edit_file=Modifica file
editor.preview_changes=Anteprima modifiche
editor.cannot_edit_lfs_files=I file LFS non possono essere modificati nell'interfaccia web.
+editor.cannot_edit_annex_files=I file Annex non possono essere modificati nell'interfaccia web.
editor.cannot_edit_non_text_files=I file binari non possono essere modificati tramite interfaccia web.
editor.edit_this_file=Modifica file
editor.this_file_locked=Il file รจ bloccato
editor.must_be_on_a_branch=ร necessario essere in un ramo per eseguire o proporre modifiche su questo file.
-editor.fork_before_edit=ร necessario effettuare il fork di questo repository per eseguire o proporre modifiche su questo file.
+editor.fork_before_edit=ร necessario derivare questo repositorio per fare o proporre modifiche su questo file.
editor.delete_this_file=Elimina file
editor.must_have_write_access=ร necessaria l'autorizzazione di scrittura per eseguire o proporre modifiche su questo file.
editor.name_your_file=Dai un nome al fileโฆ
@@ -1254,13 +1310,13 @@ editor.or=o
editor.cancel_lower=Annulla
editor.commit_signed_changes=Conferma modifiche firmate
editor.commit_changes=Conferma le modifiche
-editor.add_tmpl=Aggiungi ""
+editor.add_tmpl=Aggiungi "<%s>"
editor.patch=Applica Patch
editor.patching=Patching:
editor.new_patch=Nuova Patch
editor.commit_message_desc=Aggiungi una descrizione estesa facoltativaโฆ
editor.signoff_desc=Aggiungi "firmato da" dal committer alla fine del messaggio di log di commit.
-editor.commit_directly_to_this_branch=Fai un commit direttamente sul ramo %s .
+editor.commit_directly_to_this_branch=Fai un commit direttamente sul ramo %[1]s .
editor.create_new_branch=Crea un nuovo ramo per questo commit e avvia una richiesta di modifica.
editor.create_new_branch_np=Crea un nuovo ramo per questo commit.
editor.propose_file_change=Proponi la modifica del file
@@ -1294,16 +1350,16 @@ commits.date=Data
commits.older=Piรน vecchio
commits.newer=Piรน recente
commits.signed_by=Firmato da
-commits.signed_by_untrusted_user=Firmato da un utente non attendibile
-commits.signed_by_untrusted_user_unmatched=Firmato da un utente non attendibile che non corrisponde al committer
+commits.signed_by_untrusted_user=Firmato da un*utente non attendibile
+commits.signed_by_untrusted_user_unmatched=Firmato da un*utente non attendibile che non corrisponde al committente
commits.gpg_key_id=ID chiave GPG
commits.ssh_key_fingerprint=Impronta chiave SSH
commit.revert=Ripristina
commit.revert-header=Ripristina: %s
commit.revert-content=Seleziona il ramo sul cui ripristinare:
-commit.cherry-pick=Cherry-pick
-commit.cherry-pick-header=Cherry-pick: %s
+commit.cherry-pick=Scegli selettivamente
+commit.cherry-pick-header=Scegli selettivamente: %s
commit.cherry-pick-content=Seleziona il ramo su cui fare una selezione selettiva:
commitstatus.error=Errore
@@ -1338,9 +1394,9 @@ projects.column.color=Colore
projects.open=Apri
projects.close=Chiudi
-issues.desc=Organizza le segnalazioni di bug, attivitร e pietre miliari.
+issues.desc=Organizza le segnalazioni di bug, attivitร e traguardi.
issues.filter_assignees=Filtra assegnatario
-issues.filter_milestones=Filtra traguardo
+issues.filter_milestones=Filtra Traguardo
issues.filter_projects=Filtra Progetti
issues.filter_labels=Filtra etichetta
issues.filter_reviewers=Filtra revisore
@@ -1356,18 +1412,18 @@ issues.new.open_projects=Apri progetti
issues.new.closed_projects=Progetti chiusi
issues.new.no_items=Nessun elemento
issues.new.milestone=Traguardo
-issues.new.no_milestone=Nessuna pietra miliare
-issues.new.clear_milestone=Milestone pulita
-issues.new.open_milestone=Apri pietra miliare
-issues.new.closed_milestone=Pietre miliari chiuse
+issues.new.no_milestone=Nessun traguardo
+issues.new.clear_milestone=Rimuovi traguardo
+issues.new.open_milestone=Traguardi aperti
+issues.new.closed_milestone=Traguardi chiusi
issues.new.assignees=Assegnatari
issues.new.clear_assignees=Cancella assegnatari
issues.new.no_assignees=Nessun assegnatario
issues.new.no_reviewers=Nessun revisore
-issues.choose.get_started=Inizia
+issues.choose.get_started=Comincia
issues.choose.open_external_link=Apri
issues.choose.blank=Default
-issues.choose.blank_about=Crea un problema dal modello predefinito.
+issues.choose.blank_about=Crea una segnalazione dal modello predefinito.
issues.no_ref=Nessun ramo/etichetta specificati
issues.create=Crea segnalazione
issues.new_label=Nuova etichetta
@@ -1385,7 +1441,7 @@ issues.remove_labels=rimosso le %s etichette %s
issues.add_remove_labels=aggiunto %s e rimosso %s etichette %s
issues.add_milestone_at=`aggiunta alle pietre miliari %s %s`
issues.add_project_at=`aggiunto questo al progetto %s %s`
-issues.change_milestone_at=`pietra miliare modificata da %s a %s %s`
+issues.change_milestone_at=`ha modificato il traguardo da %s a %s %s`
issues.change_project_at=`ha modificato il progetto da %s a %s %s`
issues.remove_milestone_at=`rimossa dalle pietre miliari %s %s`
issues.remove_project_at=`rimosso questo dal progetto %s %s`
@@ -1430,22 +1486,22 @@ issues.filter_sort.moststars=Piรน favoriti
issues.filter_sort.feweststars=Meno favoriti
issues.filter_sort.mostforks=Maggior numero di fork
issues.filter_sort.fewestforks=Minor numero di fork
-issues.action_open=Aperto
+issues.action_open=Apri
issues.action_close=Chiuso
issues.action_label=Etichetta
-issues.action_milestone=Pietra Miliare
-issues.action_milestone_no_select=Nessuna pietra miliare
+issues.action_milestone=Traguardo
+issues.action_milestone_no_select=Nessun Traguardo
issues.action_assignee=Assegnatario
issues.action_assignee_no_select=Nessun assegnatario
-issues.opened_by=aperto %[1]s da %[3]s
-pulls.merged_by=di %[3]s รจ stato fuso %[1]s
-pulls.merged_by_fake=di %[2]s รจ stato fuso %[1]s
+issues.opened_by=aperta %[1]s da %[3]s
+pulls.merged_by=di %[3]s รจ stata fusa %[1]s
+pulls.merged_by_fake=di %[2]s รจ stata fusa %[1]s
issues.closed_by=di %[3]s รจ stato chiuso %[1]s
-issues.opened_by_fake=aperto %[1]s da %[2]s
+issues.opened_by_fake=aperta %[1]s da %[2]s
issues.closed_by_fake=di %[2]s รจ stato chiuso %[1]s
issues.previous=Pagina precedente
issues.next=Pagina successiva
-issues.open_title=Aperto
+issues.open_title=Aperte
issues.closed_title=Chiuso
issues.draft_title=Bozza
issues.num_comments=%d commenti
@@ -1460,15 +1516,15 @@ issues.close_comment_issue=Commenta e chiudi
issues.reopen_issue=Riapri
issues.reopen_comment_issue=Commenta e riapri
issues.create_comment=Commento
-issues.closed_at=`chiuso questo probleam %[2]s `
-issues.reopened_at=`riaperto questo problema %[2]s `
-issues.commit_ref_at=`ha fatto riferimento a questa issue dal commit %[2]s `
-issues.ref_issue_from=`ha fatto riferimento a questo problema %[4]s %[2]s `
-issues.ref_pull_from=`ha fatto riferimento a questa pull request %[4]s %[2]s `
-issues.ref_closing_from=`ha fatto riferimento ad una pull request %[4]s che chiuderร questo problema %[2]s `
-issues.ref_reopening_from=`ha fatto riferimento ad una pull request %[4]s che riaprirร questo problema %[2]s `
-issues.ref_closed_from=`chiuso questo problema %[4]s %[2]s `
-issues.ref_reopened_from=`riaperto questo problema %[4]s %[2]s `
+issues.closed_at=`ha chiuso questa segnalazione %[2]s `
+issues.reopened_at=`ha riaperto questa segnalazione %[2]s `
+issues.commit_ref_at=`ha fatto riferimento a questa segnalazione dal commit %[2]s `
+issues.ref_issue_from=`ha fatto riferimento a questa segnalazione %[4]s %[2]s `
+issues.ref_pull_from=`ha fatto riferimento a questa richiesta di modifica %[4]s %[2]s `
+issues.ref_closing_from=`ha fatto riferimento a questa segnalazione da una richiesta di modifica %[4]s che la chiuderร , %[2]s `
+issues.ref_reopening_from=`ha fatto riferimento a questa segnalazione da una richiesta di modifica %[4]s che la riaprirร , %[2]s `
+issues.ref_closed_from=`chiuso questa segnalazione %[4]s %[2]s `
+issues.ref_reopened_from=`ha riaperto questa segnalazione %[4]s %[2]s `
issues.ref_from=`da %[1]s`
issues.author=Autore
issues.role.owner=Proprietario
@@ -1505,32 +1561,32 @@ issues.subscribe=Iscriviti
issues.unsubscribe=Annulla iscrizione
issues.lock=Blocca conversazione
issues.unlock=Sblocca conversazione
-issues.lock.unknown_reason=Impossibile bloccare un problema con un motivo sconosciuto.
+issues.lock.unknown_reason=Impossibile bloccare una segnalazione senza un motivo.
issues.lock_duplicate=Un issue non puรฒ essere bloccato due volte.
-issues.unlock_error=Impossibile sbloccare un problema che non รจ bloccato.
-issues.lock_with_reason=ha bloccato come %s e limitato la conversazione ai collaboratori %s
-issues.lock_no_reason=ha bloccato e limitato la conversazione ai collaboratori %s
+issues.unlock_error=Impossibile sbloccare una segnalazione che non รจ bloccata.
+issues.lock_with_reason=ha bloccato come %s e limitato la conversazione allษ collaboranti %s
+issues.lock_no_reason=ha bloccato e limitato la conversazione allษ collaboranti %s
issues.unlock_comment=ha sbloccato questa conversazione %s
issues.lock_confirm=Blocca
issues.unlock_confirm=Sblocca
issues.lock.notice_1=- Altri utenti non possono aggiungere nuovi commenti a questa segnalazione.
-issues.lock.notice_2=- Tu e altri collaboratori con accesso a questo repository potete ancora lasciare commenti che altri possono vedere.
-issues.lock.notice_3=- Puoi sempre sbloccare questo problema in futuro.
-issues.unlock.notice_1=- Tutti potranno commentare nuovamente questo problema.
-issues.unlock.notice_2=- Puoi sempre chiudere nuovamente questo problema in futuro.
+issues.lock.notice_2=- Tu e altrษ collaboranti con accesso a questo repositorio potete ancora lasciare commenti visibili da altre persone.
+issues.lock.notice_3=- Puoi sempre sbloccare questa segnalazione in futuro.
+issues.unlock.notice_1=- Tuttษ potranno commentare nuovamente questa segnalazione.
+issues.unlock.notice_2=- Puoi sempre chiudere nuovamente questa segnalazione in futuro.
issues.lock.reason=Motivo per il blocco
issues.lock.title=Blocca la conversazione su questa issue.
issues.unlock.title=Sblocca la conversazione su questa issue.
-issues.comment_on_locked=Non puoi commentare un problema bloccato.
+issues.comment_on_locked=Non puoi commentare una segnalazione bloccata.
issues.delete=Elimina
-issues.delete.title=Eliminare questo problema?
-issues.delete.text=Vuoi davvero eliminare questo problema? (Questo rimuoverร permanentemente tutti i contenuti. Considera invece di chiuderlo, se vuoi tenerlo archiviato)
+issues.delete.title=Eliminare la segnalazione?
+issues.delete.text=Vuoi davvero eliminare la segnalazione? (Questo rimuoverร permanentemente tutti i contenuti. Considera invece di chiuderla, se vuoi tenerla archiviata)
issues.tracker=Cronografo
issues.start_tracking_short=Avvia timer
issues.start_tracking=Avvia cronografo
issues.start_tracking_history=ha iniziato a lavorare %s
-issues.tracker_auto_close=Il timer verrร interrotto automaticamente una volta che il problema verrรก chiuso
-issues.tracking_already_started=`Hai giร avviato il monitoraggio del tempo su un altro problema !`
+issues.tracker_auto_close=Il timer verrร fermato automaticamente quando questa segnalazione verrร chiusa
+issues.tracking_already_started=`Hai giร avviato il monitoraggio del tempo su un'altra segnalazione !`
issues.stop_tracking=Ferma timer
issues.stop_tracking_history=`ha smesso di funzionare %s`
issues.cancel_tracking=Scarta
@@ -1549,9 +1605,9 @@ issues.due_date=Scadenza
issues.invalid_due_date_format=Il formato della scadenza deve essere "aaaa-mm-dd".
issues.error_modifying_due_date=Impossibile modificare la scadenza.
issues.error_removing_due_date=Impossibile rimuovere la scadenza.
-issues.push_commit_1=aggiunto %d commit %s
-issues.push_commits_n=aggiunto %d commit %s
-issues.force_push_codes=`force-pushed %[1]s from %[2]s
to %[4]s
%[6]s`
+issues.push_commit_1=ha aggiunto %d commit %s
+issues.push_commits_n=ha aggiunto %d commit %s
+issues.force_push_codes=`ha forzato l'immissione %[1]s da %[2]s
a %[4]s
%[6]s`
issues.force_push_compare=Confronta
issues.due_date_form=aaaa-mm-dd
issues.due_date_form_add=Aggiungi scadenza
@@ -1576,16 +1632,16 @@ issues.dependency.pr_closing_blockedby=Questa richiesta di modifica non puรฒ ess
issues.dependency.issue_closing_blockedby=Questa segnalazione non puรฒ essere chiusa per via delle seguenti segnalazioni
issues.dependency.issue_close_blocks=Questa segnalazione impedisce la chiusura delle seguenti segnalazioni
issues.dependency.pr_close_blocks=Questa richiesta di modifica impedisce la chiusura delle seguenti segnalazioni
-issues.dependency.issue_close_blocked=Devi chiudere tutte le anomalie che bloiccano questo problema prima di chiudelo.
+issues.dependency.issue_close_blocked=Vanno chiuse tutte le segnalazioni che bloccano quest'ultima, prima di poterla chiudere.
issues.dependency.pr_close_blocked=Chiudere tutte le anomalie che bloccano la richiesta di pull prima di effettaure il merge.
issues.dependency.blocks_short=Blocchi
issues.dependency.blocked_by_short=Dipende da
issues.dependency.remove_header=Rimuovi Dipendenza
issues.dependency.issue_remove_text=Questo rimuoverร la dipendenza da questa issue. Continuare?
-issues.dependency.pr_remove_text=Questo rimuoverร la dipendenza da questa pull request. Continuare?
+issues.dependency.pr_remove_text=Questo rimuoverร la dipendenza da questa richiesta di modifica. Continuare?
issues.dependency.setting=Abilita le dipendenze per segnalazioni e richieste di modifica
-issues.dependency.add_error_same_issue=Non si puรฒ fare dipendere un problema da se stesso.
-issues.dependency.add_error_dep_issue_not_exist=Il problema dipendente non esiste.
+issues.dependency.add_error_same_issue=Non si puรฒ fare dipendere una segnalazione da se stessa.
+issues.dependency.add_error_dep_issue_not_exist=La segnalazione dalla quale dipende non esiste.
issues.dependency.add_error_dep_not_exist=La dipendenza non esiste.
issues.dependency.add_error_dep_exists=La dipendenza esiste giร .
issues.dependency.add_error_cannot_create_circular=Non puoi creare una dipendenza con due segnalazioni che si bloccano a vicenda.
@@ -1627,7 +1683,7 @@ issues.reference_link=Riferimento: %s
compare.compare_base=base
compare.compare_head=confronta
-pulls.desc=Attiva pull request e revisioni di codice.
+pulls.desc=Attiva richieste di modifica e revisioni del codice.
pulls.new=Nuova richiesta di modifica
pulls.view=Visualizza richiesta di modifica
pulls.compare_changes=Nuova richiesta di modifica
@@ -1648,23 +1704,23 @@ pulls.nothing_to_compare=Questi rami sono uguali. Non c'รจ bisogno di creare una
pulls.nothing_to_compare_and_allow_empty_pr=Questi rami sono uguali. Questa richiesta sarร vuota.
pulls.has_pull_request=`Una richiesta di modifica fra questi rami esiste giร : %[2]s#%[3]d `
pulls.create=Crea richiesta di modifica
-pulls.title_desc_few=vuole unire %[1]d commit da %[2]s
a %[3]s
+pulls.title_desc_few=vuole unire %[1]d commit da %[2]s
a %[3]s
pulls.merged_title_desc_few=ha unito %[1]d commit da %[2]s
a %[3]s
%[4]s
pulls.change_target_branch_at=`cambiato il ramo di destinazione da %s a %s %s`
pulls.tab_conversation=Conversazione
pulls.tab_commits=Commit
pulls.tab_files=File modificati
-pulls.reopen_to_merge=Riapri questa pull request per effettuare l'unione.
-pulls.cant_reopen_deleted_branch=Questa richiesta di modifia non puรฒ essere riaperta perchรฉ il ramo รจ stato eliminato.
+pulls.reopen_to_merge=Riapri questa richiesta di modifica per poter fondere.
+pulls.cant_reopen_deleted_branch=Questa richiesta di modifica non puรฒ essere riaperta in quanto il ramo รจ stato eliminato.
pulls.merged=Unito
pulls.manually_merged=Unito manualmente
-pulls.is_closed=La pull request รจ stata chiusa.
-pulls.title_wip_desc=`Inizia il titolo con %s per evitare che la pull request venga unita accidentalmente.`
-pulls.cannot_merge_work_in_progress=Questa pull request รจ contrassegnata come un lavoro in corso.
+pulls.is_closed=La richiesta di modifica รจ stata chiusa.
+pulls.title_wip_desc=`Inizia il titolo con %s per evitare che la richiesta di modifica venga fusa accidentalmente.`
+pulls.cannot_merge_work_in_progress=Questa richiesta di modifica รจ contrassegnata come lavori in corso.
pulls.still_in_progress=Ancora in corso?
pulls.add_prefix=Aggiungi prefisso %s
pulls.remove_prefix=Rimuovi il prefisso %s
-pulls.data_broken=Questa pull request รจ rovinata a causa di informazioni mancanti del fork.
+pulls.data_broken=Questa richiesta di modifica รจ rovinata a causa di informazioni mancanti riguardo la derivazione.
pulls.files_conflicted=Questa richiesta di modifica va in conflitto con il ramo di destinazione.
pulls.is_checking=Verifica dei conflitti di fusione in corso. Riprova tra qualche istante.
pulls.is_ancestor=Questo ramo รจ giร incluso nel ramo di destinazione. Non c'รจ nulla da fondere.
@@ -1672,33 +1728,33 @@ pulls.is_empty=Le modifiche di questo ramo sono giร nel ramo di destinazione. Q
pulls.required_status_check_failed=Alcuni controlli richiesti non hanno avuto successo.
pulls.required_status_check_missing=Mancano alcuni controlli richiesti.
pulls.required_status_check_administrator=Come amministratore, puoi ancora unire questa pull request.
-pulls.can_auto_merge_desc=La pull request puรฒ essere unita automaticamente.
-pulls.cannot_auto_merge_desc=Questa pull request non puรฒ essere unita automaticamente a causa di conflitti.
+pulls.can_auto_merge_desc=La richiesta di modifica puรฒ essere unita automaticamente.
+pulls.cannot_auto_merge_desc=Questa richiesta di modifica non puรฒ essere unita automaticamente a causa di conflitti.
pulls.cannot_auto_merge_helper=Unire manualmente per risolvere i conflitti.
pulls.num_conflicting_files_1=%d file in conflitto
pulls.num_conflicting_files_n=%d file in conflitto
pulls.approve_count_1=%d approvazione
pulls.approve_count_n=%d approvazioni
-pulls.reject_count_1=%d richiesta di cambiamento
-pulls.reject_count_n=%d richieste di cambiamento
+pulls.reject_count_1=%d cambiamento richiesto
+pulls.reject_count_n=%d cambiamenti richiesti
pulls.waiting_count_1=%d in attesa di revisione
pulls.waiting_count_n=%d in attesa di revisione
pulls.wrong_commit_id=l'ID del commit deve essere un ID del commit nel ramo di destinazione
-pulls.no_merge_desc=Questa pull request non puรฒ essere unita perchรฉ tutte le opzioni di merge del repository sono disattivate.
+pulls.no_merge_desc=Questa richiesta di modifica non puรฒ essere fusa perchรฉ tutte le opzioni di fusione del repositorio sono disattivate.
pulls.no_merge_helper=Attiva le opzioni di merge nelle impostazioni del repository o unisci la pull request manualmente.
pulls.no_merge_wip=Questa pull request non puรฒ essere unita perchรฉ รจ contrassegnata come un lavoro in corso.
pulls.no_merge_not_ready=Questa pull request non รจ pronta per il merge, controlla lo stato della revisione e i controlli di stato.
-pulls.no_merge_access=Non sei autorizzato ad effettuare il merge su questa pull request.
-pulls.merge_pull_request=Crea commit unito
-pulls.rebase_merge_pull_request=Ricostruisci poi manda avanti
-pulls.rebase_merge_commit_pull_request=Ricostruisci quindi crea commit unito
+pulls.no_merge_access=Non sei autorizzatษ a fondere questa richiesta di modifica.
+pulls.merge_pull_request=Crea commit di fusione
+pulls.rebase_merge_pull_request=Ricostruisci e avanti veloce
+pulls.rebase_merge_commit_pull_request=Ricostruisci e crea commit di fusione
pulls.squash_merge_pull_request=Crea commit mescolato
pulls.merge_manually=Unito manualmente
pulls.merge_commit_id=L'ID del commit di merge
pulls.require_signed_wont_sign=Il ramo richiede commit firmati ma questa fusione non verrร firmata
-pulls.invalid_merge_option=Non puoi utilizzare questa opzione di merge per questa pull request.
+pulls.invalid_merge_option=Non รจ possibile utilizzare l'opzione di fusione selezionata per questa richiesta di modifica.
pulls.merge_conflict=Unione non riuscita: C'รจ stato un conflitto durante l'operazione. Suggerimento: Prova una strategia diversa
pulls.merge_conflict_summary=Messaggio d'errore
pulls.rebase_conflict=Merge non riuscito: c'รจ stato un conflitto durante il rebase dell'commit: %[1]s. Suggerimento: Prova una strategia diversa
@@ -1722,12 +1778,12 @@ pulls.update_branch_rebase=Aggiorna il ramo per cambio base
pulls.update_branch_success=Ramo aggiornato con successo
pulls.update_not_allowed=Non ti รจ permesso aggiornare il ramo
pulls.outdated_with_base_branch=Questo ramo non รจ aggiornato con il ramo di base
-pulls.closed_at=`chiusa questa pull request %[2]s `
-pulls.reopened_at=`riaperta questa pull request %[2]s `
+pulls.closed_at=`ha chiuso questa richiesta di modifica %[2]s `
+pulls.reopened_at=`ha riaperto questa richiesta di modifica %[2]s `
pulls.auto_merge_button_when_succeed=(Quando i controlli sono superati)
pulls.auto_merge_when_succeed=Unione automatica quando tutti i controlli sono superati
-pulls.auto_merge_newly_scheduled=La pull request era programmata per unire quando tutti i controlli sono superati.
+pulls.auto_merge_newly_scheduled=La richiesta di modifica era programmata per essere fusa al passare di tutti i controlli.
pulls.auto_merge_has_pending_schedule=%[1]s ha programmato questa pull request per unire automaticamente quando tutti i controlli hanno successo %[2]s.
pulls.auto_merge_cancel_schedule=Annulla fusione automatica
@@ -1737,34 +1793,34 @@ pulls.auto_merge_canceled_schedule=L'unione automatica รจ stata annullata per qu
pulls.auto_merge_newly_scheduled_comment=`ha programmato questa pull request per unire automaticamente quando tutti i controlli sono superati %[1]s`
pulls.auto_merge_canceled_schedule_comment=`cancella l'auto-merging di questa pull request quando tutti i testi sono superati %[1]s`
-pulls.delete.title=Eliminare questa pull request?
-pulls.delete.text=Vuoi davvero eliminare questo problema? (Questo rimuoverร permanentemente tutti i contenuti. Considera invece di chiuderlo, se vuoi tenerlo archiviato)
+pulls.delete.title=Eliminare questa richiesta di modifica?
+pulls.delete.text=Vuoi davvero eliminare questa richiesta di modifica? (Ciรฒ rimuoverร permanentemente tutti i contenuti. Considera invece di chiuderla, se vuoi tenerla archiviata)
-milestones.new=Nuova pietra miliare
+milestones.new=Nuovo traguardo
milestones.closed=Chiuso %s
milestones.no_due_date=Nessuna data di scadenza
milestones.open=Apri
milestones.close=Chiudi
-milestones.completeness=%d%% Completato
-milestones.create=Crea pietra miliare
+milestones.completeness=%d%% Completato
+milestones.create=Crea traguardo
milestones.title=Titolo
milestones.desc=Descrizione
milestones.due_date=Scadenza (opzionale)
milestones.clear=Pulisci
milestones.invalid_due_date_format=Il formato della scadenza deve essere 'aaaa-mm-dd'.
-milestones.edit=Modifica pietra miliare
-milestones.edit_subheader=Le pietre miliari organizzano le issue e tengono conto del progresso.
+milestones.edit=Modifica traguardo
+milestones.edit_subheader=I traguardi permettono una migliore organizzazione dei problemi e ne tracciano il progresso.
milestones.cancel=Annulla
-milestones.modify=Aggiorna pietra miliare
-milestones.deletion=Elimina pietra miliare
-milestones.deletion_desc=Eliminare una pietra miliare la rimuove da tutte le relative issue. Continuare?
-milestones.deletion_success=La pietra miliare รจ stata eliminata.
-milestones.filter_sort.least_complete=Meno completato
-milestones.filter_sort.most_complete=Piรน completato
-milestones.filter_sort.most_issues=Maggior parte delle segnalazioni
-milestones.filter_sort.least_issues=Meno segnalazioni
+milestones.modify=Aggiorna traguardo
+milestones.deletion=Elimina traguardo
+milestones.deletion_desc=L'eliminazione di un traguardo lo rimuoverร da tutte le segnalazioni collegate ad esso. Continuare?
+milestones.deletion_success=Il traguardo รจ stato eliminato.
+milestones.filter_sort.least_complete=Completato di meno
+milestones.filter_sort.most_complete=Completato di piรน
+milestones.filter_sort.most_issues=Con piรน segnalazioni
+milestones.filter_sort.least_issues=Con meno segnalazioni
ext_wiki=Accesso al Wiki esterno
@@ -1772,8 +1828,8 @@ ext_wiki.desc=Collegamento a una wiki esterna.
wiki=Wiki
wiki.welcome=Benvenuti nella Wiki.
-wiki.welcome_desc=La wiki ti permette di scrivere e condividere documentazione con i collaboratori.
-wiki.desc=Scrivi e condividi documentazione con i collaboratori.
+wiki.welcome_desc=La wiki ti permette di scrivere e condividere documentazione con lษ collaboranti.
+wiki.desc=Scrivi e condividi documentazione con lษ collaboranti.
wiki.create_first_page=Crea la prima pagina
wiki.page=Pagina
wiki.filter_page=Filtra pagina
@@ -1822,7 +1878,7 @@ activity.closed_issues_count_1=Segnalazione chiusa
activity.closed_issues_count_n=Segnalazioni chiuse
activity.title.issues_1=%d segnalazione
activity.title.issues_n=%d segnalazioni
-activity.title.issues_closed_from=%s chiusa da %s
+activity.title.issues_closed_from=%s chiuse da %s
activity.title.issues_created_by=%s creata da %s
activity.closed_issue_label=Chiusa
activity.new_issues_count_1=Nuova segnalazione
@@ -1871,23 +1927,23 @@ search.code_search_unavailable=Attualmente la ricerca di codice non รจ disponibi
settings=Impostazioni
settings.desc=Impostazioni ti permette di gestire le impostazioni del repository
settings.options=Repository
-settings.collaboration=Collaboratori
+settings.collaboration=Collaboranti
settings.collaboration.admin=Amministratore
settings.collaboration.write=Scrittura
settings.collaboration.read=Lettura
settings.collaboration.owner=Proprietario
settings.collaboration.undefined=Non definito
-settings.hooks=Webhooks
+settings.hooks=Webhook
settings.githooks=Hook git
settings.basic_settings=Impostazioni di base
settings.mirror_settings=Impostazioni dello specchio
-settings.mirror_settings.mirrored_repository=Repository replicata
+settings.mirror_settings.mirrored_repository=Repositorio replicato
settings.mirror_settings.direction=Direzione
settings.mirror_settings.direction.pull=Tira
settings.mirror_settings.direction.push=Push
settings.mirror_settings.last_update=Ultimo aggiornamento
settings.mirror_settings.push_mirror.none=Nessun mirror push configurato
-settings.mirror_settings.push_mirror.remote_url=URL del progetto git remoto
+settings.mirror_settings.push_mirror.remote_url=URL del repositorio git remoto
settings.mirror_settings.push_mirror.add=Aggiungi specchio di immissione
settings.sync_mirror=Sincronizza ora
@@ -1895,13 +1951,13 @@ settings.site=Sito web
settings.update_settings=Salva impostazioni
settings.branches.update_default_branch=Aggiorna ramo predefinito
settings.advanced_settings=Opzioni avanzate
-settings.wiki_desc=Abilita wiki del progetto
+settings.wiki_desc=Abilita wiki del repositorio
settings.use_internal_wiki=Utilizza la wiki incorporata
settings.use_external_wiki=Usa wiki esterna
settings.external_wiki_url=URL wiki esterno
settings.external_wiki_url_error=L'URL della wiki esterna non รจ un URL valido.
settings.external_wiki_url_desc=I visitatori verranno reindirizzati all'URL della wiki esterna cliccando sulla scheda di wiki.
-settings.issues_desc=Abilitร il tracciatore delle segnalazioni del progetto
+settings.issues_desc=Abilitร il tracciatore delle segnalazioni del repositorio
settings.use_internal_issue_tracker=Usa il tracciatore di segnalazioni incorporato
settings.use_external_issue_tracker=Usa un tracciatore di segnalazioni esterno
settings.external_tracker_url=URL del tracciatore di segnalazioni esterno
@@ -1915,18 +1971,18 @@ settings.tracker_issue_style.alphanumeric=Alfanumerico
settings.tracker_issue_style.regexp=Espressione Regolare
settings.tracker_issue_style.regexp_pattern=Motivo Espressione Regolare
settings.tracker_issue_style.regexp_pattern_desc=Il primo gruppo catturato verrร utilizzato al posto di {index}
.
-settings.tracker_url_format_desc=Usa i segnaposto {user}
, {repo}
e {index}
per il nome utente, il nome del repository e l'indice delle issue.
+settings.tracker_url_format_desc=Usa i segnaposto {user}
, {repo}
e {index}
per designare il nome utente, il nome del repositorio e l'ID della segnalazione.
settings.enable_timetracker=Abilita il cronografo
settings.allow_only_contributors_to_track_time=Consenti soltanto ai contributori di utilizzare il cronografo
-settings.pulls_desc=Abilita le richieste di modifica del progetto
+settings.pulls_desc=Abilita le richieste di modifica nel repositorio
settings.pulls.ignore_whitespace=Ignora gli spazi bianchi per evitare conflitti
settings.pulls.enable_autodetect_manual_merge=Abilita il rilevamento automatico della fusione manuale (Nota: in alcuni casi speciali possono verificarsi errori)
settings.pulls.allow_rebase_update=Abilita l'aggiornamento del ramo della richiesta per rebase
settings.pulls.default_delete_branch_after_merge=Elimina il ramo della richiesta dopo la fusione per impostazione predefinita
-settings.packages_desc=Abilita registro dei pacchetti del progetto
-settings.projects_desc=Abilita progetti del progetto
+settings.packages_desc=Abilita registro dei pacchetti nel repositorio
+settings.projects_desc=Abilita progetti nel repositorio
settings.admin_settings=Impostazioni amministratore
-settings.admin_enable_health_check=Abilita verifica dell'integritร del progetto (git fsck)
+settings.admin_enable_health_check=Abilita verifica dell'integritร del repositorio (git fsck)
settings.admin_code_indexer=Indicizzatore del codice
settings.admin_stats_indexer=Indicizzatore di statistiche del codice
settings.admin_indexer_commit_sha=Ultimo SHA indicizzato
@@ -1935,23 +1991,23 @@ settings.reindex_button=Aggiungi alla coda di re-indicizzazione
settings.reindex_requested=Re-indicizzazione richiesta
settings.admin_enable_close_issues_via_commit_in_any_branch=Chiudi una segnalazione tramite un commit eseguito su un ramo non predefinito
settings.danger_zone=Zona pericolosa
-settings.new_owner_has_same_repo=Il nuovo proprietario ha giร un repository con lo stesso nome. Per favore scegli un altro nome.
-settings.convert=Converti in un progetto regolare
-settings.convert_desc=ร possibile convertire questo mirror in un repository regolare. Questa operazione non puรฒ essere annullata.
-settings.convert_notices_1=- Questa operazione convertirร questo mirror in una repository regolare e non potrร essere annullata.
-settings.convert_confirm=Converti progetto
-settings.convert_succeed=Il mirror รจ stato convertito in un repository regolare.
-settings.convert_fork=Converti in un progetto regolare
-settings.convert_fork_desc=Puoi convertire questo fork in un normale repository. Questo non puรฒ essere annullato.
-settings.convert_fork_notices_1=Questa operazione convertirร il fork in un normale repository e non puรฒ essere annullata.
-settings.convert_fork_confirm=Converti progetto
-settings.convert_fork_succeed=Il fork รจ stato convertito in un repository regolare.
+settings.new_owner_has_same_repo=Lษ nuovษ proprietariษ ha giร un repositorio con lo stesso nome. Per favore scegline un altro.
+settings.convert=Converti in un repositorio indipendente
+settings.convert_desc=ร possibile convertire questo mirror in un repositorio indipendente. Questa operazione non puรฒ essere annullata.
+settings.convert_notices_1=Questa operazione convertirร questo mirror in un repositorio indipendente e non potrร essere annullata.
+settings.convert_confirm=Converti repositorio
+settings.convert_succeed=Il mirror รจ stato convertito in un repositorio indipendente.
+settings.convert_fork=Converti in un repositorio indipendente
+settings.convert_fork_desc=Puoi convertire questa derivazione in un repositorio indipendente. Questo non puรฒ essere annullato.
+settings.convert_fork_notices_1=Questa operazione convertirร la derivazione in un repositorio indipendente e non puรฒ essere annullata.
+settings.convert_fork_confirm=Converti repositorio
+settings.convert_fork_succeed=La derivazione รจ stato convertita in un repositorio indipendente.
settings.transfer.title=Trasferisci proprietร
-settings.transfer.rejected=Il trasferimento del repository รจ stato rifiutato.
-settings.transfer.success=Il trasferimento del repository รจ andato a buon fine.
+settings.transfer.rejected=Il trasferimento del repositorio รจ stato rifiutato.
+settings.transfer.success=Il trasferimento del repositorio รจ andato a buon fine.
settings.transfer_abort=Annulla trasferimento
-settings.transfer_abort_invalid=Non รจ possibile annullare un trasferimento di repository non esistente.
-settings.transfer_desc=Trasferisci questo repository a un altro utente o a un'organizzazione nella quale hai diritti d'amministratore.
+settings.transfer_abort_invalid=Non รจ possibile annullare il trasferimento di un repositorio non esistente.
+settings.transfer_desc=Trasferisci questo repositorio a un altro utente o a un'organizzazione nella quale hai diritti d'amministratore.
settings.transfer_form_title=Inserisci il nome del repository come conferma:
settings.transfer_in_progress=Al momento c'รจ un trasferimento in corso. Si prega di annullarlo se si desidera trasferire questo repository a un altro utente.
settings.transfer_notices_1=-Si perderร l'accesso al repository se lo si trasferisce ad un utente singolo.
@@ -1965,14 +2021,14 @@ settings.signing_settings=Impostazioni verifica firma
settings.trust_model=Modello di fiducia per la firma
settings.trust_model.default=Modello di fiducia predefinito
settings.trust_model.default.desc=Usa il modello di trust del repository predefinito per questa installazione.
-settings.trust_model.collaborator=Collaboratore
-settings.trust_model.collaborator.long=Collaboratore: Firme di fiducia da parte dei collaboratori
-settings.trust_model.collaborator.desc=Le firme valide da parte dei collaboratori di questo repository saranno contrassegnate con "trusted" (sia che corrispondano al committer o meno). Altrimenti, le firme valide saranno contrassegnate con "untrusted" se la firma corrisponde al committer e "unmatched" se non.
-settings.trust_model.committer=Committer
+settings.trust_model.collaborator=Collaborante
+settings.trust_model.collaborator.long=Collaborante: firme di fiducia da parte dellษ collaboranti
+settings.trust_model.collaborator.desc=Le firme valide da parte dellษ collaboranti di questo repositorio saranno contrassegnate con "fidate" (sia che corrispondano a chi ha fatto il commit o meno). Altrimenti saranno contrassegnate con "non fidate" se la firma corrisponde a chi ha fatto il commit e "senza riscontro" se non.
+settings.trust_model.committer=Autorษ
settings.trust_model.committer.long=Committer: firme affidabili che corrispondono ai committer (questo corrisponde a GitHub e costringerร i commit firmati di Forgejo ad avere Forgejo come committer)
-settings.trust_model.collaboratorcommitter=Collaboratore+Committer
-settings.trust_model.collaboratorcommitter.long=Collaboratore+Committer: Firme di fiducia da parte dei collaboratori che corrispondono al committer
-settings.trust_model.collaboratorcommitter.desc=Le firme valide da parte dei collaboratori di questa repository saranno contrassegnate "fidate" se corrispondono al committer. Altrimenti le firme saranno contrassegnate con "untrusted" se la firma corrisponde al committer non corrisponde. Questo costringerร Forgejo a essere contrassegnato come committer su impegni firmati con l'effettivo committer contrassegnato come Co-Authored-By: e Co-Committed-By: nel commit. La chiave Forgejo predefinita deve corrispondere a un utente nel database.
+settings.trust_model.collaboratorcommitter=Collaborante+Committente
+settings.trust_model.collaboratorcommitter.long=Collaborante+Committente: firme di fiducia da parte dellษ collaboranti che corrispondono allษ committente
+settings.trust_model.collaboratorcommitter.desc=Le firme valide da parte dellษ collaboranti di questo repositorio saranno contrassegnate "fidate" se corrispondono a chi fa il commit. Altrimenti saranno contrassegnate con "non fidate" se la firma corrisponde a chi fa il commit, e "senza riscontro" se non corrisponde. Questo costringerร Forgejo a essere contrassegnato come committente sui commit firmati, con l'effettivษ committente contrassegnatษ come Co-Authored-By: e Co-Committed-By: nel commit. La chiave Forgejo predefinita deve corrispondere a un*utente nella base dati.
settings.wiki_delete=Elimina dati wiki
settings.wiki_delete_desc=L'eliminazione dei dati della wiki del repository รจ permanente e non puรฒ essere annullata.
settings.wiki_delete_notices_1=-Questa operazione eliminerร permanentemente e disabiliterร la wiki repository per %s.
@@ -1981,21 +2037,21 @@ settings.wiki_deletion_success=I dati della repository wiki sono stati eliminati
settings.delete=Elimina questo progetto
settings.delete_desc=L'eliminazione di un repository รจ un'operazione permanente e non puรฒ essere annullata.
settings.delete_notices_1=-Questa operazione NON PUร essere annullata.
-settings.delete_notices_2=-Questa operazione eliminerร definitivamente il repository %s inclusi codice, issue, commenti, dati wiki e impostazioni collaboratore.
+settings.delete_notices_2=-Questa operazione eliminerร definitivamente il repositorio %s , inclusi codice, segnalazioni commenti, dati della wiki e impostazioni collaboranti.
settings.delete_notices_fork_1=-I fork di questo repository diventeranno indipendenti dopo la cancellazione.
settings.deletion_success=Il repository รจ stato eliminato.
settings.update_settings_success=Le impostazioni del repository sono state aggiornate.
settings.confirm_delete=Elimina progetto
-settings.add_collaborator=Aggiungi collaboratore
-settings.add_collaborator_success=Il collaboratore รจ stato aggiunto.
-settings.add_collaborator_inactive_user=Non posso aggiungere un utente inattivo come collaboratore.
-settings.add_collaborator_duplicate=Il collaboratore รจ giร stato aggiunto a questo repository.
+settings.add_collaborator=Aggiungi collaborante
+settings.add_collaborator_success=Lษ collaborante รจ statษ aggiuntษ.
+settings.add_collaborator_inactive_user=Non posso aggiungere un*utente inattivษ come collaborante.
+settings.add_collaborator_duplicate=Lษ collaborante รจ giร statษ aggiuntษ a questo repositorio.
settings.delete_collaborator=Rimuovi
-settings.collaborator_deletion=Rimuovi collaboratore
-settings.collaborator_deletion_desc=Rimuovere un collaboratore revocherร l'accesso a questo repository. Continuare?
-settings.remove_collaborator_success=Il collaboratore รจ stato rimosso.
+settings.collaborator_deletion=Rimuovi collaborante
+settings.collaborator_deletion_desc=Rimuovere unษ collaborante ne revocherร l'accesso a questo repositorio. Continuare?
+settings.remove_collaborator_success=Lษ collaborante รจ statษ rimossษ.
settings.search_user_placeholder=Ricerca utenteโฆ
-settings.org_not_allowed_to_be_collaborator=Le organizzazioni non possono essere aggiunte come un collaboratore.
+settings.org_not_allowed_to_be_collaborator=Le organizzazioni non possono essere aggiunte come collaborante.
settings.change_team_access_not_allowed=La modifica dell'accesso al team per il repository รจ stato limitato al solo proprietario dell'organizzazione
settings.team_not_in_organization=Il team non รจ nella stessa organizzazione del repository
settings.teams=Gruppi
@@ -2045,8 +2101,8 @@ settings.event_create=Crea
settings.event_create_desc=Ramo o etichetta creati.
settings.event_delete=Elimina
settings.event_delete_desc=Ramo o etichetta eliminati.
-settings.event_fork=Fork
-settings.event_fork_desc=Repository forkato.
+settings.event_fork=Deriva
+settings.event_fork_desc=Repository derivato.
settings.event_wiki=Wiki
settings.event_release=Release
settings.event_release_desc=Release pubblicata, aggiornata o rimossa in una repository.
@@ -2055,8 +2111,8 @@ settings.event_push_desc=Git push in un repository.
settings.event_repository=Repository
settings.event_repository_desc=Repository creato o eliminato.
settings.event_header_issue=Eventi delle segnalazioni
-settings.event_issues=Issues
-settings.event_issues_desc=Issue aperto, chiuso, riaperto o modificato.
+settings.event_issues=Segnalazioni
+settings.event_issues_desc=Segnalazione aperta, chiusa, riaperta o modificata.
settings.event_issue_assign=Segnalazione assegnata
settings.event_issue_assign_desc=Issue assegnata o non assegnata.
settings.event_issue_label=Segnalazione etichettata
@@ -2067,7 +2123,7 @@ settings.event_issue_comment=Commento segnalazione
settings.event_issue_comment_desc=Commento issue creato, modificato o rimosso.
settings.event_header_pull_request=Eventi di richieste di modifiche
settings.event_pull_request=Richiesta di modifica
-settings.event_pull_request_desc=Pull request aperta, chiusa, riaperta o modificata.
+settings.event_pull_request_desc=Richiesta di modifica aperta, chiusa, riaperta o modificata.
settings.event_pull_request_assign=Richiesta di modifica assegnata
settings.event_pull_request_assign_desc=Pull request assegnata o non assegnata.
settings.event_pull_request_label=Richiesta di modifica etichettata
@@ -2083,7 +2139,7 @@ settings.event_pull_request_sync_desc=Pull request sincronizzata.
settings.event_package=Pacchetto
settings.event_package_desc=Pacchetto creato o eliminato in un repository.
settings.branch_filter=Filtro rami
-settings.branch_filter_desc=Whitelist dei rami per gli eventi di spinta, creazione dei rami e cancellazione dei rami, specificati come modello globo. Se vuoto o *
, gli eventi per tutti i rami sono segnalati. Vedi la documentazione github.com/gobwas/glob per la sintassi. Esempi: master
, {master,release*}
.
+settings.branch_filter_desc=Whitelist dei rami per gli eventi di spinta, creazione dei rami e cancellazione dei rami, specificati come modello globo. Se vuoto o *
, gli eventi per tutti i rami sono segnalati. Vedi la documentazione %[2]s per la sintassi. Esempi: master
, {master,release*}
.
settings.active=Attivo
settings.active_helper=Le informazioni sugli eventi innescati saranno inviate a questo URL del webhook.
settings.add_hook_success=Il webhook รจ stato aggiunto.
@@ -2126,7 +2182,7 @@ settings.key_name_used=Esiste giร una deploy key con questo nome.
settings.deploy_key_deletion=Rimuovi chiave di dispiego
settings.deploy_key_deletion_desc=Rimuovere una chiave di distribuzione ne revocherร l'accesso a questo repository. Continuare?
settings.deploy_key_deletion_success=La chiave di distribuzione รจ stata rimossa.
-settings.branches=Branches
+settings.branches=Rami
settings.protected_branch=Protezione ramo
settings.protected_branch_can_push=Consentire push?
settings.protected_branch_can_push_yes=Puoi pushare
@@ -2141,23 +2197,23 @@ settings.protect_enable_push_desc=Chiunque con accesso in scrittura sarร autori
settings.protect_whitelist_committers=Limita immissione alla whitelist
settings.protect_whitelist_committers_desc=Solo gli utenti o i team nella whitelist potranno pushare su questo ramo (ma non forzare il push).
settings.protect_whitelist_deploy_keys=Chiavi di deploy in whitelist con permessi di scrittura per il push.
-settings.protect_whitelist_users=Utenti nella whitelist per pushare:
+settings.protect_whitelist_users=Utenti nella whitelist per pushare
settings.protect_whitelist_search_users=Cerca utentiโฆ
-settings.protect_whitelist_teams=Team nella whitelist per pushare:
+settings.protect_whitelist_teams=Team nella whitelist per pushare
settings.protect_whitelist_search_teams=Ricerca teamโฆ
settings.protect_merge_whitelist_committers=Attiva la whitelist per le fusioni
settings.protect_merge_whitelist_committers_desc=Consentire soltanto agli utenti o ai team in whitelist il permesso di unire le pull request di questo branch.
-settings.protect_merge_whitelist_users=Utenti nella whitelist per il merging:
-settings.protect_merge_whitelist_teams=Team nella whitelist per il merging:
+settings.protect_merge_whitelist_users=Utenti nella whitelist per il merging
+settings.protect_merge_whitelist_teams=Team nella whitelist per il merging
settings.protect_check_status_contexts=Abilita controllo dello stato
settings.protect_check_status_contexts_desc=Richiedi il superamento di controlli di stato prima dell'unione di due rami. Scegliere quali controlli di stato devono passare prima che i rami possano essere uniti in un ramo che corrisponde a questa regola. Se abilitato, i commit devono prima essere inviati a un altro ramo, quindi uniti o pushati direttamente a un ramo che corrisponde a questa regola dopo aver superato i controlli di stato. Se non viene selezionato alcuna regola, l'ultimo commit avrรก successo indipendentemente dal contesto.
settings.protect_check_status_contexts_list=Controlli di stato trovati nell'ultima settimana per questo repository
-settings.protect_required_approvals=Approvazioni richieste:
+settings.protect_required_approvals=Approvazioni richieste
settings.protect_required_approvals_desc=Permetti solo di unire la richiesta pull con abbastanza recensioni positive.
settings.protect_approvals_whitelist_enabled=Limita le approvazioni agli utenti o ai team nella whitelist
settings.protect_approvals_whitelist_enabled_desc=Solo le recensioni di utenti o team nella whitelist saranno contate alle approvazioni richieste. Senza approvazione nella whitelist, le recensioni di chiunque abbia i permessi di scrittura nella repository verrรก contato nelle approvazioni richieste.
-settings.protect_approvals_whitelist_users=Utenti autorizzati:
-settings.protect_approvals_whitelist_teams=Team nella whitelist per le revisioni:
+settings.protect_approvals_whitelist_users=Utenti autorizzati
+settings.protect_approvals_whitelist_teams=Team nella whitelist per le revisioni
settings.dismiss_stale_approvals=Ignora impostazione vecchie
settings.dismiss_stale_approvals_desc=Quando i nuovi commit che cambiano il contenuto della pull request vengono pushati nel branch, le vecchie approvazioni verranno eliminate.
settings.require_signed_commits=Richiedi commit firmati
@@ -2239,8 +2295,8 @@ diff.git-notes=Note
diff.data_not_available=Differenze non disponibili
diff.options_button=Opzioni differenze
diff.show_diff_stats=Mostra statistiche
-diff.download_patch=Scarica il file toppa
-diff.download_diff=Scarica il file differenza
+diff.download_patch=Scarica file .patch
+diff.download_diff=Scarica file .diff
diff.show_split_view=Visualizzazione separata
diff.show_unified_view=Visualizzazione unificata
diff.whitespace_button=Spazi bianchi
@@ -2328,7 +2384,7 @@ release.add_tag=Crea Solo Branch
branch.name=Nome ramo
branch.delete_head=Elimina
branch.delete_html=Elimina ramo
-branch.create_branch=Crea branch %s
+branch.create_branch=Crea branch %s
branch.deleted_by=Eliminato da %s
branch.included_desc=Questo ramo fa parte del ramo predefinito
branch.included=Incluso
@@ -2339,7 +2395,7 @@ branch.create_branch_operation=Crea ramo
branch.new_branch=Crea nuovo ramo
branch.renamed=Il ramo %s รจ stato rinominato in %s.
-tag.create_tag=Crea branch %s
+tag.create_tag=Crea etichetta %s
tag.create_tag_operation=Crea etichetta
tag.confirm_create_tag=Crea etichetta
@@ -2365,7 +2421,7 @@ actions = Azioni
commit.operations = Operazioni
issues.action_check = Seleziona/Deseleziona
issues.close = Chiudi segnalazione
-issues.role.collaborator = Collaboratore
+issues.role.collaborator = Collaborante
desc.sha256 = SHA256
editor.add = Aggiungi %s
editor.update = Aggiorna %s
@@ -2407,11 +2463,11 @@ commitstatus.failure = Errore
settings.units.overview = Panoramica
all_branches = Tutti i rami
projects.column.assigned_to = Assegnato a
-pulls.cmd_instruction_hint = `Visualizza istruzioni per la riga di comando .`
-settings.add_collaborator_blocked_them = Non si puรฒ aggiungere il collaboratore perchรฉ ha bloccato il proprietario del progetto.
+pulls.cmd_instruction_hint = `Visualizza istruzioni per la riga di comando.`
+settings.add_collaborator_blocked_them = Non si puรฒ aggiungere lษ collaborante perchรฉ ha bloccato lษ proprietariษ del progetto.
branch.protected_deletion_failed = Il ramo "%s" รจ protetto. Non puรฒ essere eliminato.
branch.default_deletion_failed = Il ramo "%s" รจ il ramo predefinito. Non puรฒ essere eliminato.
-branch.tag_collision = Il ramo "%s" non puรฒ essere creato perchรฉ un'etichetta con lo stesso nome esiste giร nel progetto.
+branch.tag_collision = Il ramo "%s" non puรฒ essere creato perchรฉ esiste giร un'etichetta con lo stesso nome nel repositorio.
topic.format_prompt = Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ("-") e punti ("."), possono arrivare fino a 35 caratteri di lunghezza. Le lettere devono essere minuscole.
error.broken_git_hook = Le hook Git di questo progetto sembrano rotte. Segui la documentazione per ripararli, poi immetti alcuni commit per aggiornare lo stato.
wiki.reserved_page = La nome della pagina della wiki "%s" รจ riservato.
@@ -2420,23 +2476,23 @@ settings.webhook.test_delivery_desc_disabled = Per testare questo richiamo HTTP
settings.protected_branch_duplicate_rule_name = Esiste giร una regola per questo insieme di rami
rss.must_be_on_branch = Devi essere su un ramo per avere un feed RSS.
admin.manage_flags = Gestisci flag
-admin.enabled_flags = Flag abilitate per il progetto:
+admin.enabled_flags = Flag abilitate per il repositorio:
admin.update_flags = Aggiorna flag
-admin.failed_to_replace_flags = Impossibile sostituire flag del progetto
-admin.flags_replaced = Flag del progetto sostituite
+admin.failed_to_replace_flags = Impossibile sostituire flag del repositorio
+admin.flags_replaced = Flag del repositorio sostituite
fork_branch = Ramo da clonare sulla derivazione
-fork_no_valid_owners = Questo progetto non puรฒ essere derivato perchรฉ non ci sono validi proprietari.
+fork_no_valid_owners = Questo repositorio non puรฒ essere derivato perchรฉ non ci sono proprietari validi.
mirror_address_url_invalid = L'URL fornito รจ invalido. Devi eseguire l'escape di tutti i componenti dell'URL correttamente.
mirror_address_protocol_invalid = L'URL fornito รจ invalido. Solo posizioni http(s):// o git:// possono essere usate come specchio.
-stars_remove_warning = Questo rimuoverร tutte le stelle da questo progetto.
+stars_remove_warning = Questo rimuoverร tutte le stelle da questo repositorio.
blame.ignore_revs = Le revisioni in .git-blame-ignore-revs sono ignorate. Clicca qui per bypassare e vedere la vista incolpa normale.
-archive.title = Questo progetto รจ archiviato. Puoi vedere i file e clonarlo, ma non puoi immettere o aprire segnalazioni o richieste di modifica.
-archive.title_date = Questo progetto รจ stato archiviato il %s. Puoi vedere i file e clonarlo, ma non puoi immettere o aprire segnalazioni o richieste di modifica.
-form.name_pattern_not_allowed = La sequenza "%s" non รจ ammessa nel nome di un progetto.
+archive.title = Questo repositorio รจ archiviato. Puoi vedere i file e clonarlo, ma non puoi immettere o aprire segnalazioni o richieste di modifica.
+archive.title_date = Questo repositorio รจ stato archiviato in data %s. Puoi vedere i file e clonarlo, ma non puoi immettere nรฉ aprire segnalazioni o richieste di modifica.
+form.name_pattern_not_allowed = La sequenza "%s" non รจ ammessa nel nome di un repositorio.
migrate.invalid_local_path = Il percorso locale รจ invalido. Non esiste o non รจ una cartella.
migrate.migrating_failed.error = Impossibile migrare: %s
migrate.forgejo.description = Migra dati da codeberg.org o da altre istanze Forgejo.
-cite_this_repo = Cita questo progetto
+cite_this_repo = Cita questo repositorio
file_follow = Segui symlink
invisible_runes_header = `Questo file contiene caratteri Unicode invisibili`
ambiguous_runes_header = `Questo file contiene caratteri Unicode ambigui`
@@ -2448,8 +2504,8 @@ commit.contained_in_default_branch = Questo commit fa parte del ramo predefinito
commit.load_referencing_branches_and_tags = Carica rami ed etichette che fanno riferimento a questo commit
editor.fail_to_apply_patch = Impossibile applicare toppa "%s"
editor.new_branch_name = Dร i un nome al nuovo ramo per questo commit
-editor.branch_already_exists = Il ramo "%s" esiste giร nella repo.
-editor.directory_is_a_file = Il nome cartella "%s" รจ giร usato come nome file in questo progetto.
+editor.branch_already_exists = C'รจ gia un ramo "%s" nel repositorio.
+editor.directory_is_a_file = Il nome cartella "%s" รจ giร usato come nome file in questo repositorio.
editor.file_is_a_symlink = `"%s" รจ un collegamento simbolico. I collegamenti simbolici non possono essere modificati nell'editor web`
editor.filename_is_a_directory = Il nome file "%s" รจ giร usato come nome cartella in questo progetto.
editor.file_editing_no_longer_exists = Il file in modifica, "%s", non esiste piรน in questo progetto.
@@ -2479,14 +2535,14 @@ pulls.showing_specified_commit_range = Mostrando solo cambiamenti tra %[1]s..%[2
pulls.select_commit_hold_shift_for_range = Seleziona commit. Premi maiusc + click per selezionare un intervallo
pulls.filter_changes_by_commit = Filtra per commit
pulls.nothing_to_compare_have_tag = I rami/etichette selezionati sono uguali.
-pulls.merged_success = Richiesta di modifica fusa correttamente e chiusa
+pulls.merged_success = Richiesta di modifica fusa e chiusa con successo
pulls.closed = Richiesta di modifica chiusa
pulls.merged_info_text = Il ramo %s puรฒ ora essere eliminato.
-pulls.blocked_by_user = Non puoi creare una richiesta di modifica in questo progetto perchรฉ sei bloccato dal proprietario.
+pulls.blocked_by_user = Non puoi creare una richiesta di modifica in questo repositorio perchรฉ sei stato bloccato dallษ proprietariษ.
pulls.status_checks_hide_all = Nascondi tutti i controlli
pulls.status_checks_show_all = Mostra tutti i controlli
pulls.clear_merge_message_hint = Cancellare il messaggio di fusione rimuoverร solo il messaggio di commit e terrร le sequenze generate da git come "Co-Authored-By ..".
-pulls.close = Chiudi la richiesta di modifica
+pulls.close = Chiudi richiesta
pulls.reopen_failed.head_branch = La richiesta di modifica non puรฒ essere riaperta perchรฉ il ramo genitore non esiste piรน.
pulls.clear_merge_message = Cancella messaggio di fusione
pulls.reopen_failed.base_branch = La richiesta di modifica non puรฒ essere riaperta perchรฉ il ramo di base non esiste piรน.
@@ -2510,10 +2566,10 @@ settings.mirror_settings.docs.no_new_mirrors = Il tuo progetto sta specchiando i
settings.mirror_settings.docs.can_still_use = Nonostante tu non possa modificare specchi esistenti o crearne di nuovi puoi comunque il tuo specchio esistente.
settings.mirror_settings.docs.pull_mirror_instructions = Per impostare uno specchio di prelievo consulta:
settings.mirror_settings.docs.doc_link_title = Come specchio progetti?
-settings.mirror_settings.docs.doc_link_pull_section = la sezione "Prelievo da un progetto remoto" della documentazione.
-settings.mirror_settings.docs.pulling_remote_title = Prelievo da un progetto remote
-settings.transfer_abort_success = Il trasferimento del progetto a %s รจ stato correttamente cancellato.
-settings.enter_repo_name = Inserisci il proprietario e il nome del progetto esattamente come mostrato:
+settings.mirror_settings.docs.doc_link_pull_section = la sezione "Prelievo da un repositorio remoto" della documentazione.
+settings.mirror_settings.docs.pulling_remote_title = Prelievo da repositorio remoto
+settings.transfer_abort_success = Il trasferimento del repositorio presso %s รจ stato anullato con successo.
+settings.enter_repo_name = Inserisci lษ proprietariษ e il nome del repositorio esattamente come mostrato:
settings.confirmation_string = Stringa di conferma
settings.wiki_rename_branch_main = Normalizza il nome del ramo della Wiki
settings.wiki_rename_branch_main_desc = Rinomina il ramo usato internamente dalla Wiki in "%s". L'operazione รจ permanente รจ non puรฒ essere annullata.
@@ -2522,7 +2578,7 @@ settings.wiki_branch_rename_success = Il nome del ramo della wiki della repo รจ
settings.wiki_branch_rename_failure = Impossibile normalizzare il nome del ramo della wiki della repo.
settings.confirm_wiki_branch_rename = Rinomina il ramo della wiki
settings.wiki_rename_branch_main_notices_2 = Ciรฒ rinominerร permanentemente il ramo interno della wiki della repo di %s. Passaggi esistenti dovranno essere aggiornati.
-settings.add_collaborator_blocked_our = Non si puรฒ aggiungere il collaboratore perchรฉ il proprietario del progetto lo ha bloccato.
+settings.add_collaborator_blocked_our = Non si puรฒ aggiungere lษ collaborante perchรฉ lษ proprietariษ del progetto l'ha bloccatษ.
settings.webhook.replay.description_disabled = Per riprodurre questo richiamo HTTP, attivalo.
settings.event_wiki_desc = Pagina wiki creata, rinominata, modificata o rimossa.
settings.event_pull_request_review_request = Richiesta di modifica revisionata
@@ -2534,16 +2590,16 @@ branch.warning_rename_default_branch = Stai rinominando il ramo predefinito.
branch.rename_branch_to = Rinomina "%s" come:
branch.new_branch_from = Crea nuovo ramo da "%s"
tag.create_tag_from = Crea nuova etichetta da "%s"
-tag.create_success = Etichetta "%s" creata.
+tag.create_success = L'etichetta "%s" รจ stata creata.
settings.unarchive.button = Disarchivia progetto
release.tags_for = Etichette per %s
branch.delete = Elimina ramo "%s"
issues.role.first_time_contributor_helper = Questa non รจ il primo contributo di questo utente al progetto.
issues.role.contributor_helper = Questo utente ha precedentemente fatto commit al progetto.
-pulls.blocked_by_official_review_requests = Questa richiesta di modifica รจ bloccata perchรฉ manca l'approvazione di uno o piรน revisori ufficiali.
-pulls.blocked_by_changed_protected_files_1 = Questa richiesta di modifica รจ bloccata perchรฉ modifica un file protetto:
-pulls.blocked_by_changed_protected_files_n = Questa richiesta di modifica รจ bloccata perchรฉ modifica file protetti:
-pulls.has_merged = Errore: la richiesta di modifica รจ stata fusa, non puoi fonderla di nuovo o cambiare il ramo di destinazione.
+pulls.blocked_by_official_review_requests = Questa richiesta di modifica รจ bloccata perchรฉ manca l'approvazione di unษ o piรน revisorษ ufficiali.
+pulls.blocked_by_changed_protected_files_1 = Questa richiesta di modifica รจ bloccata perchรฉ tocca un file protetto:
+pulls.blocked_by_changed_protected_files_n = Questa richiesta di modifica รจ bloccata perchรฉ tocca file protetti:
+pulls.has_merged = Errore: la richiesta di modifica รจ stata fusa, non puoi fonderla di nuovo o cambiarne il ramo di destinazione.
milestones.filter_sort.latest_due_date = Scadenza piรน lontana
settings.mirror_settings.docs = Imposta la tua repo in modo che sincronizzi automaticamente commit, etichette e rami con un'altra repo.
settings.mirror_settings.docs.disabled_pull_mirror.instructions = Imposta il tuo progetto in modo che immetta commit, etichette e rami in un altro progetto automaticamente. Gli specchi di prelievo sono stati disabilitati dall'amministratore del sito.
@@ -2554,9 +2610,9 @@ issues.action_check_all = Seleziona/deseleziona tutti gli elementi
issues.num_comments_1 = %d commento
issues.no_content = Descrizione non fornita.
issues.unpin_issue = Sblocca segnalazione
-new_repo_helper = Un progetto contiene tutti i file, inclusa la storia delle revisioni. Ne ospiti giร una altrove? Migra il progetto.
+new_repo_helper = Un repositorio contiene tutti i file, inclusa la cronologia delle revisioni. Ne hai giร uno altrove? Migra il progetto .
projects.card_type.images_and_text = Immagini e testo
-object_format_helper = Formato oggetti del progetto. Non puรฒ essere cambiato in seguito. SHA1 รจ il piรน compatibile.
+object_format_helper = Formato oggetti del repositorio. Non puรฒ essere cambiato in seguito. SHA1 รจ il piรน compatibile.
editor.file_delete_success = Il file "%s" รจ stato eliminato.
editor.upload_files_to_dir = Cari file su "%s"
commits.no_commits = Nessun commit in comune. "%s" e "%s" hanno cronologie completamente diverse.
@@ -2565,11 +2621,11 @@ invisible_runes_description = `Questo file contiene caratteri Unicode invisibili
issues.filter_type.reviewed_by_you = Revisionati da te
projects.edit_success = Il progetto "%s" รจ stato aggiornato.
issues.keyword_search_unavailable = La ricerca per parola chiave non รจ attualmente disponibile. Contatta l'amministratore del sito.
-issues.role.collaborator_helper = Questo utente รจ stato invitato a collaborare sul progetto.
+issues.role.collaborator_helper = Quest*utente รจ statษ invitatษ a collaborare al progetto.
pulls.commit_ref_at = `ha fatto riferimento a questa richiesta di modifica da un commit %[2]s `
settings.thread_id = ID della discussione
release.title = Titolo del rilascio
-visibility_helper = Rendi progetto privato
+visibility_helper = Rendi il repositorio privato
clone_in_vscodium = Clona in VSCodium
blame.ignore_revs.failed = Impossibile ignorare le revisioni in .git-blame-ignore-revs .
author_search_tooltip = Mostra un massimo di 30 utenti
@@ -2592,8 +2648,8 @@ issues.choose.invalid_config = La configurazione della segnalazione contiene err
issues.label_templates.fail_to_load_file = Impossibile caricare file di modello etichetta "%s": %v
issues.role.member_helper = questo utente รจ un membro dell'organizzazione che possiede questo progetto.
issues.review.pending.tooltip = Questo commento non รจ attualmente visibile ad altri utenti. Per inviare il tuo commento in attesa selezione "%s" -> "%s/%s/%s" in cima alla pagina.
-pulls.blocked_by_approvals = Questa richiesta di modifica non ha ancora sufficienti approvazioni. %d di %d approvazioni concesse.
-pulls.blocked_by_rejection = Questa richiesta di modifica ha modifiche richieste da un revisore ufficiale.
+pulls.blocked_by_approvals = Questa richiesta di modifica non ha ancora un numero di approvazioni sufficienti. %d di %d approvazioni concesse.
+pulls.blocked_by_rejection = Unษ revisorษ ufficiale ha richiesto delle correzioni per questa richiesta di modifica.
pulls.blocked_by_outdated_branch = Questa richiesta di modifica รจ bloccata poichรฉ obsoleta.
pulls.fast_forward_only_merge_pull_request = Solo fast-forward
signing.will_sign = Questo commit verrร firmato con la chiave "%s".
@@ -2604,9 +2660,9 @@ signing.wont_sign.always = I commit sono sempre firmati.
signing.wont_sign.approved = La fusione non sarร firmata dato che la RM non รจ approvata.
wiki.page_title = Titolo della pagina
wiki.page_content = Contenuto della pagina
-settings.mirror_settings.pushed_repository = Progetto immesso
+settings.mirror_settings.pushed_repository = Repositorio immesso
settings.mirror_settings.push_mirror.edit_sync_time = Modifica intervallo di sincronizzazione degli specchi
-settings.units.units = Unitร del progetto
+settings.units.units = Unitร della repository
settings.units.add_more = Aggiungi ancora...
settings.wiki_globally_editable = Consenti a tutti di modificare la wiki
settings.pull_mirror_sync_in_progress = Prelevando cambiamenti dal progetto remoto %s.
@@ -2617,24 +2673,24 @@ settings.branches.add_new_rule = Aggiungi una nuova regola
settings.actions_desc = Abilita azioni del progetto
settings.new_owner_blocked_doer = Il nuovo proprietario ti ha bloccato.
settings.update_settings_no_unit = Ili progetto dovrebbe consentire almeno qualche tipo di interazione.
-settings.add_collaborator_owner = Non si puรฒ aggiungere un proprietario come collaboratore.
+settings.add_collaborator_owner = Non si puรฒ aggiungere unษ proprietariษ come collaborante.
branch.delete_desc = L'eliminazione di un ramo รจ definitiva. Nonostante il ramo eliminato potrebbe continuare ad esistere per un breve periodo di tempo prima di essere realmente eliminato, l'eliminazione NON PUร essere annullata in molti casi. Continuare?
editor.invalid_commit_mail = Email invalida per creare un commit.
-editor.branch_does_not_exist = Il ramo "%s" non esiste nella repo.
+editor.branch_does_not_exist = Non esiste nessun ramo "%s" nel repositorio.
issues.label_archive = Archivia etichetta
issues.label_archived_filter = Mostra etichette archiviate
issues.dependency.no_permission_n = Non hai il permesso di lettura per leggere %s dipendenze
branch.restore = Ripristina il ramo "%s"
issues.dependency.no_permission.can_remove = Non ha il permesso per leggere questa dipendenza ma puoi rimuovere questa dipendenza
issues.review.outdated_description = Il contenuto รจ cambiato da quando questo commento รจ stato fatto
-settings.tags.protection.pattern.description = Puoi usare un singolo nome o un glob pattern o un'espressione regolare per selezionare piรน etichette. Leggi di piรน nella guide sulle etichette protette .
+settings.tags.protection.pattern.description = Puoi usare un singolo nome o un glob pattern o un'espressione regolare per selezionare piรน etichette. Leggi di piรน nella guide sulle etichette protette .
issues.author_helper = Questo utente รจ l'autore.
-issues.comment_pull_merged_at = fondi commit %[1]s in %[2]s %[3]s
-issues.comment_manually_pull_merged_at = fondi commit %[1]s in %[2]s %[3]s manualmente
+issues.comment_pull_merged_at = ha fuso il commit %[1]s in %[2]s %[3]s
+issues.comment_manually_pull_merged_at = ha fuso manualmente il commit %[1]s in %[2]s %[3]s
pulls.review_only_possible_for_full_diff = La revisione รจ possibile solo quando visualizzando le differenze complete
issues.role.first_time_contributor = Contributore per la prima volta
issues.label_archive_tooltip = Le etichette archiviate sono escluse dai suggerimenti quando si ricerca un'etichetta.
-form.name_reserved = Il nome progetto "%s" รจ riservato.
+form.name_reserved = Il nome repositorio "%s" รจ riservato.
release.message = Descrivi questo rilascio
branch.deletion_success = Il ramo "%s" รจ stato eliminato.
branch.deletion_failed = Impossibile eliminare il ramo "%s".
@@ -2656,7 +2712,7 @@ settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning = Al mome
settings.pulls.default_allow_edits_from_maintainers = Consenti modifica dai manutentori in modo predefinito
settings.trust_model.committer.desc = Firme valide saranno etichettate "fidata" se corrispondo all'autore del commit, altrimenti saranno etichettate "non corrisponde". Questo costringe Forgejo ad esse l'autore dei commit firmati, con il vero autore etichettato con le sequenze Co-authored-by: e Co-commited-by: nel commit. La chiave predefinita di Forgejo deve corrispondere ad un utente nella base di dati.
signing.wont_sign.pubkey = Il commit non verrร firmato perchรฉ non hai una chiave pubblica associata al tuo profilo.
-settings.releases_desc = Abilita rilasci del progetto
+settings.releases_desc = Abilita rilasci nel repositorio
settings.unarchive.text = Disarchiviare il progetto ripristinerร la sua abilitร di ricevere commit e immissioni, oltre che nuove segnalazioni e richieste di modifica.
settings.unarchive.success = Il progetto รจ stato disarchiviato correttamente.
settings.unarchive.error = Si รจ verificato un errore durante la disarchiviazione del progetto. Vedi il log per ulteriori dettagli.
@@ -2683,21 +2739,21 @@ settings.protected_branch.save_rule = Salva regola
settings.protected_branch.delete_rule = Elimina regola
settings.protect_invalid_status_check_pattern = Sequenza per il controllo dello stato non valida: "%s".
settings.protect_status_check_matched = Coincide
-settings.protect_status_check_patterns = Sequenze per il controllo dello stato:
+settings.protect_status_check_patterns = Sequenze per il controllo dello stato
settings.protect_enable_merge = Abilita fusione
settings.protect_enable_merge_desc = Chiunque con permesso di scrittura potrร fondere richieste di modifica in questo ramo.
-settings.protect_unprotected_file_patterns = Sequenze dei file non protetti (separate da punto e virgola ";"):
-settings.protect_protected_file_patterns = Sequenze dei file protetti (separate da punto e virgola ";"):
-settings.protect_branch_name_pattern_desc = Sequenze di nome di rami protetti. Vedi la documentazione per la sintassi delle sequenze. Esempi: main, release/**
+settings.protect_unprotected_file_patterns = Sequenze dei file non protetti (separate da punto e virgola ";")
+settings.protect_protected_file_patterns = Sequenze dei file protetti (separate da punto e virgola ";")
+settings.protect_branch_name_pattern_desc = Sequenze di nome di rami protetti. Vedi la documentazione per la sintassi delle sequenze. Esempi: main, release/**
settings.protect_branch_name_pattern = Sequenza nome di ramo
settings.ignore_stale_approvals_desc = Non contare le approvazione fatte su vecchi commit (revisioni stantie) nel calcolo delle approvazioni della RM. Irrilevante se le revisioni stantie sono giร state respinte.
settings.ignore_stale_approvals = Ignora approvazioni stantie
settings.protected_branch_required_rule_name = Nome regola richiesta
settings.protect_status_check_patterns_desc = Inserisci sequenze per specificare quali controlli dello stato devono passare prima che i rami possano essere fusi con i rami che soddisfano questa regola. Ogni riga specifica una sequenza. Le sequenze non possono essere vuote.
settings.authorization_header_desc = Verrร inclusa come intestazione dell'autorizzazione per le richieste quando presente. Esempi: %s.
-pulls.title_desc_one = vuole fondere %[1]d commit da %[2]s
in %[3]s
-settings.protect_unprotected_file_patterns_desc = File non protetti dei quali รจ consentita la modifica direttamente se l'utente ha permesso di scrittura, saltandole restrizioni di immissione. Piรน sequenze possono essere separate usando il punto e virgola (";"). Vedi la documentazione su github.com/gobwas/glob per la sintassi delle sequenze glob. Esempi .drone.yml
, /docs/**/*.txt
.
-settings.protect_protected_file_patterns_desc = I file non protetti non possono essere modificati direttamente neanche se l'utente ha il permesso di aggiungere, modificare o eliminare file in questo ramo. Piรน sequenze possono essere separate usando il punto e virgola (";"). Vedi la documentazione su github.com/gobwas/glob per la sintassi della sequenze. Esempi: .drone.yml
, /docs/**/*.txt
.
+pulls.title_desc_one = vuole fondere %[1]d commit da %[2]s
in %[3]s
+settings.protect_unprotected_file_patterns_desc = File non protetti dei quali รจ consentita la modifica direttamente se l'utente ha permesso di scrittura, saltandole restrizioni di immissione. Piรน sequenze possono essere separate usando il punto e virgola (";"). Vedi la documentazione su %[2]s per la sintassi delle sequenze glob. Esempi .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns_desc = I file non protetti non possono essere modificati direttamente neanche se l'utente ha il permesso di aggiungere, modificare o eliminare file in questo ramo. Piรน sequenze possono essere separate usando il punto e virgola (";"). Vedi la documentazione su %s per la sintassi della sequenze. Esempi: .drone.yml
, /docs/**/*.txt
.
settings.protect_no_valid_status_check_patterns = Nessuna sequenza valida per il controllo dello stato.
settings.event_pull_request_review_request_desc = Richiesta la revisione della richiesta di modifica o richiesta di revisione rimossa.
stars = Stelle
@@ -2705,7 +2761,7 @@ issues.num_participants_one = %d partecipante
open_with_editor = Apri con %s
n_commit_few = %s commit
n_branch_one = %s ramo
-n_tag_few = %s tag
+n_tag_few = %s etichette
settings.web_hook_name_sourcehut_builds = Build SourceHut
settings.sourcehut_builds.manifest_path = Percorso manifest della build
settings.sourcehut_builds.visibility = Visibilitร attivitร
@@ -2725,7 +2781,7 @@ release.system_generated = Questo allegato รจ stato generato automaticamente.
pulls.ready_for_review = Pronto alla revisione?
editor.commit_id_not_matching = L'ID del commit non combacia con quello del commit che stavi modificando. Conferma le tue modifiche su un nuovo ramo, poi fondilo col ramo desiderato.
n_branch_few = %s rami
-n_tag_one = %s tag
+n_tag_one = %s etichetta
commits.search_branch = Questo Ramo
settings.rename_branch_failed_protected = Non รจ possibile rinominare il ramo %s perchรฉ รจ un ramo protetto.
settings.event_pull_request_enforcement = Imposizione
@@ -2733,6 +2789,29 @@ settings.matrix.room_id_helper = L'ID della Stanza puรฒ essere ricavato dal web
settings.graphql_url = URL GraphQL
settings.sourcehut_builds.access_token_helper = Token di accesso con grant JOBS:RW. Genera un token builds.sr.ht o un token builds.sr.ht con accesso ai segreti su meta.sr.ht.
settings.matrix.access_token_helper = ร consigliata l'impostazione di un account Matrix dedicato per questa funzione. Il token di accesso puรฒ essere prelevato dal web client Element (in una pagina privata/incognito) > Menu utente (in alto a sinistra) > Tutte le impostazioni > Aiuto e informazioni > Avanzato > Token di accesso (sotto all'URL del Homeserver). Chiudi la pagina privata/incognito (La disconnessione invaliderebbe il token).
+issues.author.tooltip.issue = Questo utente รจ l'autore di questa segnalazione.
+form.string_too_long = La stringa data รจ piรน lunga di %d caratteri.
+project = Progetti
+issues.edit.already_changed = Impossibile salvare le modifiche alla segnalazione. Sembra che il contenuto sia giร stato modificato da un*altrษ utente. Aggiornare la pagina e provare a modificare nuovamente per evitare di sovrascrivere le modifiche
+subscribe.pull.guest.tooltip = Accedi per iscriverti a questa richiesta di modifica.
+subscribe.issue.guest.tooltip = Accedere per seguire questa segnalazione.
+n_release_one = rilascio %s
+n_release_few = rilasci %s
+issues.author.tooltip.pr = Quest'utente รจ l'autorษ di questa richiesta di modifica.
+release.hide_archive_links = Nascondi automaticamente gli archivi generati
+settings.federation_settings = Impostazioni di federazione
+settings.federation_apapiurl = URL della federazione di questo repository. Copiarlo e incollarlo nelle Impostazioni della federazione di un altro repository come URL di un repository successivo.
+release.hide_archive_links_helper = Nascondi gli archivi del codice sorgente generati automaticamente per questa versione. Ad esempio, se stai caricando i tuoi.
+comments.edit.already_changed = Impossibile salvare le modifiche al commento. Sembra che il contenuto sia giร stato modificato da un altro utente. Aggiornare la pagina e provare a modificare nuovamente per evitare di sovrascrivere le modifiche
+settings.federation_following_repos = URL dei repository successivi. Separati da ";", senza spazi.
+settings.federation_not_enabled = La federazione non รจ abilitata nella tua istanza.
+settings.transfer.button = Trasferisci la proprietร
+settings.transfer.modal.title = Trasferisci la proprietร
+pulls.edit.already_changed = Impossibile salvare le modifiche alla richiesta. Sembra che il contenuto sia giร stato modificato da un altro utente. Aggiorna la pagina e prova a modificare nuovamente per evitare di sovrascrivere le modifiche
+wiki.search = Cerca nel wiki
+wiki.no_search_results = Nessun risultato
+mirror_use_ssh.helper = Selezionando quest'opzione, Forgejo replicherร il repositorio tramite Git con SSH e creerร un paio di chiavi per te. Assicurati che la chiave pubblica generata sia autorizzata per l'immissione nel repositorio di destinazione. Non puoi usare l'autorizzazione tramite password se selezioni quest'opzione.
+archive.pull.noreview = Il repositorio รจ archiviato. Non puoi revisionare le richieste di modifica.
[graphs]
contributors.what = contribuzioni
@@ -2823,7 +2902,7 @@ teams.read_access_helper=I membri possono visualizzare e clonare i repository de
teams.write_access=Scrittura
teams.write_access_helper=I membri possono leggere e pushare sui repository del team.
teams.admin_access=Accesso amministratore
-teams.admin_access_helper=I membri possono pullare e pushare sulle repository del team e anche aggiungere collaboratori.
+teams.admin_access_helper=I membri possono prelevare e immettere sui repositori del team e aggiungere collaboranti.
teams.no_desc=Questo team non ha alcuna descrizione
teams.settings=Impostazioni
teams.owners_permission_desc=I proprietari hanno pieno accesso a tutti i repository e hanno diritti di amministratore nell'organizzazione.
@@ -2836,7 +2915,7 @@ teams.delete_team_desc=Eliminare un team revocherร l'accesso al repository da p
teams.delete_team_success=Il team รจ stato eliminato.
teams.read_permission_desc=Questo team concede l'accesso di lettura : i membri possono visualizzare e clonare i repository del team.
teams.write_permission_desc=Questo team concede l'accesso di Scrittura : i membri possono leggere da e pushare sui repository del team.
-teams.admin_permission_desc=Questo team concede l'accesso di Amministratore : i membri possono leggere da, pushare su e aggiungere collaboratori ai repository del team.
+teams.admin_permission_desc=Questo team concede l'accesso di Amministrante : i membri possono leggere da, immettere in e aggiungere collaboranti ai repositori del team.
teams.create_repo_permission_desc=Inoltre, questo team concede il permesso di Creare repository : i membri possono creare nuove repository nell'organizzazione.
teams.repositories=Progetti della squadra
teams.search_repo_placeholder=Ricerca repositoryโฆ
@@ -2867,13 +2946,14 @@ follow_blocked_user = Non puoi seguire questa organizzazione perchรฉ ti ha blocc
form.name_reserved = Il nome di organizzazione "%s" รจ riservato.
settings.email = Email di contatto
settings.visibility.limited = Limitato (visibile solo agli utenti autenticati)
+open_dashboard = Apri pannello di controllo
[admin]
dashboard=Pannello di Controllo
users=Profili utenti
organizations=Organizzazioni
repositories=Repository
-hooks=Webhooks
+hooks=Webhook
authentication=Fonti di autenticazione
emails=Email utenti
config=Configurazione
@@ -3144,17 +3224,17 @@ auths.sspi_default_language_helper=Lingua predefinita per gli utenti creati auto
auths.tips=Consigli
auths.tips.oauth2.general=Autenticazione OAuth2
auths.tip.oauth2_provider=Fornitore OAuth2
-auths.tip.bitbucket=Registra un nuovo cliente OAuth su https://bitbucket.org/account/user//oauth-consumers/new e aggiungi il permesso "Account" - "Read"
+auths.tip.bitbucket=Registra un nuovo cliente OAuth su %s
auths.tip.nextcloud=`Registra un nuovo OAuth sulla tua istanza utilizzando il seguente menu "Impostazioni -> Sicurezza -> OAuth 2.0 client"`
-auths.tip.dropbox=Crea una nuova applicazione su https://www.dropbox.com/developers/apps
-auths.tip.facebook=`Registra una nuova applicazione su https://developers.facebook.com/apps e aggiungi il prodotto "Facebook Login"`
-auths.tip.github=Registra una nuova applicazione OAuth su https://github.com/settings/applications/new
+auths.tip.dropbox=Crea una nuova applicazione su %s
+auths.tip.facebook=`Registra una nuova applicazione su %s e aggiungi il prodotto "Facebook Login"`
+auths.tip.github=Registra una nuova applicazione OAuth su %s
auths.tip.gitlab=Registra una nuova applicazione su https://gitlab.com/profile/applications
-auths.tip.google_plus=Ottieni le credenziali del client OAuth2 dalla console API di Google su https://console.developers.google.com/
+auths.tip.google_plus=Ottieni le credenziali del client OAuth2 dalla console API di Google su %s
auths.tip.openid_connect=Utilizza l'OpenID Connect Discovery URL (/.well-known/openid-configuration) per specificare gli endpoint
-auths.tip.twitter=Vai su https://dev.twitter.com/apps, crea una applicazione e assicurati che l'opzione "Allow this application to be used to Sign In with Twitter" sia abilitata
-auths.tip.discord=Registra una nuova applicazione su https://discordapp.com/developers/applications/me
-auths.tip.yandex=`Crea una nuova applicazione su https://oauth.yandex.com/client/new. Seleziona i seguenti permessi da "Yandex. assport API": "Access to email address", "Access to user avatar" e "Access to username, name and surname, gender"`
+auths.tip.twitter=Vai su %s, crea una applicazione e assicurati che l'opzione "Allow this application to be used to Sign In with Twitter" sia abilitata
+auths.tip.discord=Registra una nuova applicazione su %s
+auths.tip.yandex=`Crea una nuova applicazione su %s. Seleziona i seguenti permessi da "Yandex.Passport API": "Access to email address", "Access to user avatar" e "Access to username, name and surname, gender"`
auths.tip.mastodon=Inserisci un URL di istanza personalizzato per l'istanza mastodon con cui vuoi autenticarti (o usa quella predefinita)
auths.edit=Modifica fonte di autenticazione
auths.activated=Questa fonte di autenticazione รจ attiva
@@ -3310,7 +3390,7 @@ monitor.start=Orario Avvio
monitor.execute_time=Tempo di Esecuzione
monitor.last_execution_result=Risultato
monitor.process.cancel=Annulla processo
-monitor.process.cancel_desc=L'annullamento di un processo potrebbe causare la perdita di dati
+monitor.process.cancel_desc=Annullare un processo potrebbe causare una perdita di dati
monitor.process.cancel_notices=Annulla: %s ?
monitor.process.children=Figli
@@ -3350,7 +3430,7 @@ notices.operations = Operazioni
users.bot = Bot
config.send_test_mail_submit = Invia
dashboard.cron.cancelled = Cron: %[1]s cancellato: %[3]s
-dashboard.new_version_hint = Forgejo %s รจ ora disponibile, stai eseguendo %s. Controlla il blog per ulteriori dettagli.
+dashboard.new_version_hint = Forgejo %s รจ ora disponibile; stai eseguendo %s. Controlla il blog per ulteriori dettagli.
dashboard.sync_repo_branches = Sincronizza rami omessi dai dati Git nella base di dati
dashboard.gc_lfs = Oggetti meta LFS riciclati
dashboard.sync_tag.started = Sincronizzazione delle etichette iniziata
@@ -3363,7 +3443,7 @@ dashboard.sync_repo_tags = Sincronizza etichette dai dati Git alla base di dati
users.new_success = Il profilo utente "%s" รจ stato creato.
users.still_own_packages = Questo utente possiede ancora uno o piรน pacchetti, elimina questi pacchetti prima.
auths.oauth2_map_group_to_team = Associa gruppi reclamati a squadre di organizzazioni. (opzionale - richiede il nome reclamo sopra)
-auths.tip.gitea = Registra una nuova applicazione OAuth2. La guida puรฒ essere trovata a https://forgejo.org/docs/latest/user/oauth2-provider
+auths.tip.gitea = Registra una nuova applicazione OAuth2. La guida puรฒ essere trovata a %s
config.test_mail_sent = Una email di prova รจ stata inviata a "%s".
monitor.processes_count = %d processi
monitor.download_diagnosis_report = Scarica relazione diagnostica
@@ -3386,42 +3466,49 @@ emails.change_email_text = Sei sicuro di voler aggiornare questo indirizzo email
repos.lfs_size = Dimensione LFS
packages.unreferenced_size = Dimensione senza riferimenti: %s
packages.cleanup.success = Dati scaduti puliti correttamente
-defaulthooks.desc = I richiami HTTP fanno automaticamente richieste POST al server innescati da alcuni eventi di Forgejo. I richiami HTTP definiti qui sono predefiniti e saranno copiati in tutti i nuovi progetti. Leggi di piรน nella guida sui richiami HTTP .
+defaulthooks.desc = I richiami HTTP fanno automaticamente richieste POST al server innescati da alcuni eventi di Forgejo. I richiami HTTP definiti qui sono predefiniti e saranno copiati in tutti i nuovi progetti. Leggi di piรน nella guida sui richiami HTTP .
auths.oauth2_map_group_to_team_removal = Rimuovi utenti dalle squadre sincronizzate se l'utente non appartiene al gruppo corrispondente.
auths.tips.oauth2.general.tip = Quando si registra una nuova autenticazione OAuth2, l'URL di richiamata/reindirizzamento dovrebbe essere:
config.logger_name_fmt = Logger: %s
-systemhooks.desc = I richiami HTTP fanno automaticamente richieste POST al server innescati da alcuni eventi di Forgejo. I richiami HTTP definiti qui agiranno su tutti i progetti nel sistema, quindi considera li implicazioni sulle prestazioni che questi possono avere. Leggi di piรน nella guida sui richiami HTTP .
+systemhooks.desc = I richiami HTTP fanno automaticamente richieste POST al server innescati da alcuni eventi di Forgejo. I richiami HTTP definiti qui agiranno su tutti i progetti nel sistema, quindi considera li implicazioni sulle prestazioni che questi possono avere. Leggi di piรน nella guida sui richiami HTTP .
auths.new_success = L'autenticazione "%s" รจ stata aggiunta.
auths.tips.gmail_settings = Impostazioni Gmail:
config.test_mail_failed = Impossibile inviare email di prova a "%s": %v
users.details = Dettagli dell'utente
monitor.queue.review_add = Revisiona / aggiungi lavoratori
-self_check.no_problem_found = Nessun problema trovato.
+self_check.no_problem_found = Non c'รจ ancora nessuna segnalazione.
self_check.database_inconsistent_collation_columns = La base di dati sta usando la collazione %s ma queste colonne usano una collazione diversa. Potrebbe causare problemi imprevisti.
monitor.queue.settings.remove_all_items = Rimuovi tutto
monitor.queue.settings.desc = Le piscine crescono dinamicamente in risposta al blocco dei lavoratori in coda.
monitor.queue.settings.remove_all_items_done = Tutti gli elementi in coda sono stati rimossi.
self_check.database_collation_mismatch = Pretendi che la base di dati usi la collazione: %s
-self_check.database_fix_mysql = Per utenti MySQL/MariaDB, potresti usare il comando "gitea doctor convert" per risolvere problemi di collazione, o potresti risolvere il problema manualmente tramite SQL con "ALTER ... COLLATE ...".
+self_check.database_fix_mysql = Per utenti MySQL/MariaDB, potresti usare il comando "forgejo doctor convert" per risolvere problemi di collazione, o potresti risolvere il problema manualmente tramite SQL con "ALTER ... COLLATE ...".
self_check.database_collation_case_insensitive = La base di dati sta usando la collazione %s, che รจ una collazione insensibile. Nonostante Forgejo potrebbe lavorarci, ci potrebbero essere rari casi che non vanno come previsto.
-auths.tip.gitlab_new = Registra una nuova applicazione su https://gitlab.com/-/profile/applications
+auths.tip.gitlab_new = Registra una nuova applicazione su %s
config_summary = Riepilogo
config.open_with_editor_app_help = L'editor delle opzioni "Apri con" per il menu di clone. Se lasciato vuoto, verranno usati i default. Espandi per vedere i default.
config_settings = Impostazioni
+config.cache_test = Controllo cache
+config.cache_test_failed = Fallito il controllo della cache: %v.
+config.cache_test_succeeded = Successo nel controllo della cache, ottenuta una risposta in %s.
+config.cache_test_slow = Successo nel controllo della cache, ma la risposta รจ lenta: %s.
+config.app_slogan = Slogan dell'istanza
+auths.default_domain_name = Nome di dominio predefinito utilizzato per l'indirizzo e-mail
+users.restricted.description = Permetti di interagire solo con i repositori e le organizzazioni in cui l'utente รจ aggiuntษ come collaborante. Ciรฒ evita l'accesso ai repositori pubblici di quest'istanza.
[action]
create_repo=ha creato il repository %s
rename_repo=repository rinominato da %[1]s
a [3]s
-create_issue=`ha aperto il problema %[3]s#%[2]s `
-close_issue=`ha chiuso il problema %[3]s#%[2]s `
-reopen_issue=`ha riaperto il problema %[3]s#%[2]s `
+create_issue=`ha aperto la segnalazione %[3]s#%[2]s `
+close_issue=`ha chiuso la segnalazione %[3]s#%[2]s `
+reopen_issue=`ha riaperto la segnalazione %[3]s#%[2]s `
create_pull_request=`ha creato la pull request %[3]s#%[2]s `
close_pull_request=`ha chiuso la pull request %[3]s#%[2]s `
-reopen_pull_request=`ha riaperto la pull request %[3]s#%[2]s `
-comment_issue=`ha commentato sul problema %[3]s#%[2]s `
-comment_pull=`ha commentato su pull request %[3]s#%[2]s `
-merge_pull_request=`ha unito il pull request %[3]s#%[2]s `
+reopen_pull_request=`ha riaperto la richiesta di modifica %[3]s#%[2]s `
+comment_issue=`ha commentato la segnalazione %[3]s#%[2]s `
+comment_pull=`ha commentato la richiesta di modifica %[3]s#%[2]s `
+merge_pull_request=`ha fuso la richiesta di modifica %[3]s#%[2]s `
transfer_repo=repository %s
trasferito in %s
push_tag=ha inviato il tag %[3]s su %[4]s
delete_tag=tag eliminato %[2]s da %[3]s
@@ -3434,13 +3521,13 @@ mirror_sync_create=ha sincronizzato un nuovo riferimento %[3]s
mirror_sync_delete=riferimento sincronizzato ed eliminato %[2]s
a %[3]s dal mirror
approve_pull_request=`ha approvato %[3]s#%[2]s `
reject_pull_request=`ha suggerito modifiche per %[3]s#%[2]s `
-publish_release=`ha rilasciato "%[4]s" su %[3]s `
+publish_release=`ha rilasciato %[4]s su %[3]s `
review_dismissed=`respinta la recensione da %[4]s per %[3]s#%[2]s `
review_dismissed_reason=Motivo:
create_branch=ha creato il ramo %[3]s in %[4]s
starred_repo=ha salvato come preferito %[2]s
watched_repo=ha iniziato a guardare %[2]s
-commit_repo = immesso a %[3]s a %[4]s
+commit_repo = ha immesso nel ramo %[3]s presso %[4]s
auto_merge_pull_request = `richiesta di modifica %[3]s#%[2]s fusa automaticamente`
[tool]
@@ -3526,7 +3613,7 @@ versions.view_all=Vedi tutti
dependency.id=ID
dependency.version=Versione
alpine.install=Per installare il pacchetto, eseguire il seguente comando:
-alpine.repository.branches=Branches
+alpine.repository.branches=Rami
alpine.repository.repositories=Repository
chef.install=Per installare il pacchetto, eseguire il seguente comando:
composer.registry=Imposta questo registro nel tuo file ~/.composer/config.json
:
@@ -3539,7 +3626,7 @@ conan.install=Per installare il pacchetto usando Conan, eseguire il seguente com
container.details.type=Tipo Immagine
container.details.platform=Piattaforma
container.pull=Tirare l'immagine dalla riga di comando:
-container.multi_arch=OS / Arch
+container.multi_arch=SO / Architettura
container.layers=Livelli Immagine
container.labels=Etichette
container.labels.key=Chiave
@@ -3651,6 +3738,7 @@ owner.settings.chef.keypair.description = Per autenticarsi al registro Chef รจ n
owner.settings.cargo.initialize.success = L'indice di Cargo รจ stato creato correttamente.
owner.settings.cargo.rebuild.no_index = Impossibile ricostruire, nessun indice รจ inizializzato.
owner.settings.cargo.rebuild.description = La ricostruzione puรฒ essere utile se l'indice non รจ sincronizzato con i pacchetti Cargo conservati.
+npm.dependencies.bundle = Dipendenze raggruppate
[secrets]
secrets = Segreti
@@ -3668,9 +3756,6 @@ creation.success = Il segreto "%s" รจ stato aggiungo.
deletion.success = Il segreto รจ stato rimosso.
[actions]
-
-
-
runners.id=ID
runners.name=Nome
runners.owner_type=Tipo
@@ -3757,6 +3842,14 @@ runs.no_workflows.quick_start = Non sai come iniziare con le Forgejo Actions? Ve
runners.delete_runner_notice = Se un'attivitร รจ in esecuzione su questo esecutore sarร terminata ed etichettata fallito. Potrebbe rompere flussi di lavoro di costruzione.
runners.task_list = Attivitร recenti su questo esecutore
runs.no_job_without_needs = Il flusso di lavoro deve contenere almeno un incarico senza dipendenze.
+workflow.dispatch.trigger_found = Questo flusso di lavoro ha un rilevatore di eventi workflow_dispatch .
+workflow.dispatch.run = Esegui flusso di lavoro
+workflow.dispatch.success = L'esecuzione del flusso di lavoro รจ stata richiesta con successo.
+workflow.dispatch.input_required = Richiedi valore per l'ingresso "%s".
+workflow.dispatch.invalid_input_type = Tipo ingresso "%s" non valido.
+workflow.dispatch.warn_input_limit = Visualizzati solo i primi %d ingressi.
+runs.no_job = Il flusso di lavoro deve contenere almeno un incarico
+workflow.dispatch.use_from = Usa flusso di lavoro da
@@ -3767,7 +3860,6 @@ type-1.display_name = Progetto individuale
type-2.display_name = Progetto
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=Link Simbolico
submodule = Submodule
directory = Directory
@@ -3784,8 +3876,8 @@ fuzzy = Approssimativa
match = Precisa
org_kind = Cerca organizzazioni...
package_kind = Ricerca pacchetti...
-code_search_unavailable = La ricerca del codice non รจ attualmente disponibile. Contatta l'amministratore del sito.
-code_kind = Cerca codice...
+code_search_unavailable = La ricerca del codice non รจ attualmente disponibile. Contatta l'amministratorษ del sito.
+code_kind = Cerca nel codice...
team_kind = Cerca team...
code_search_by_git_grep = I risultati della ricerca del codice sono forniti da "git grep". Potrebbero esserci risultati migliori se l'amministratore del sito avesse abilitato l'indicizzatore del codice.
project_kind = Ricerca progetti...
@@ -3797,7 +3889,15 @@ runner_kind = Ricerca esecutori...
match_tooltip = Includi solo risultati che corrispondono precisamente al termine di ricerca
fuzzy_tooltip = Includi anche risultati che corrispondono approssimativamente al termine di ricerca
user_kind = Cerca utenti...
-repo_kind = Cerca repository...
+repo_kind = Cerca repo...
+exact_tooltip = Includi solo i risultati che corrispondono esattamente al termine di ricerca
+issue_kind = Cerca segnalazioni...
+pull_kind = Cerca richieste...
+exact = Esatto
+milestone_kind = Ricerca tappe...
+regexp_tooltip = Interpreta i termini di ricerca come un'espressione regolare
+regexp = Espressione Regolare
+union_tooltip = Include i risultati che combaciano con una qualsiasi delle parole chiave separata da spazi
[munits.data]
gib = GiB
@@ -3811,4 +3911,9 @@ b = B
[markup]
filepreview.lines = Linee da %[1]d a %[2]d in %[3]s
filepreview.truncated = L'anteprima รจ stata troncata
-filepreview.line = Linea %[1]d in %[2]s
\ No newline at end of file
+filepreview.line = Linea %[1]d in %[2]s
+
+
+[repo.permissions]
+issues.write = Scrittura: Chiudere segnalazioni e gestire metadati come etichette, traguardi, assegnatarษ, scadenze e dipendenze.
+pulls.write = Scrittura: Chiudere richieste di modifica e gestire metadati come etichette, traguardi, assegnatarษ, scadenze e dipendenze.
\ No newline at end of file
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index ac0e855e06..32caac1371 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -158,6 +158,16 @@ filter.not_template = ใใณใใฌใผใใงใฏใชใ
invalid_data = ็กๅนใชใใผใฟ: %v
more_items = ใใใซ่กจ็คบ
copy_generic = ใฏใชใใใใผใใธใณใใผ
+new_repo.title = ๆฐใใใชใใธใใช
+new_migrate.title = ๆฐใใใใคใฐใฌใผใทใงใณ
+new_org.title = ๆฐใใ็ต็น
+new_repo.link = ๆฐใใใชใใธใใช
+new_migrate.link = ๆฐใใใใคใฐใฌใผใทใงใณ
+new_org.link = ๆฐใใ็ต็น
+test = ใในใ
+error413 = ๅฒใๅฝใฆ้ใไฝฟใๅใใใพใใใ
+
+copy_path = ใในใใณใใผ
[aria]
navbar=ใใใฒใผใทใงใณใใผ
@@ -189,6 +199,8 @@ buttons.ref.tooltip=ใคใทใฅใผใพใใฏใใซใชใฏใจในใใๅ็
ง
buttons.switch_to_legacy.tooltip=ใฌใฌใทใผใจใใฃใฟใไฝฟ็จใใ
buttons.enable_monospace_font=็ญๅน
ใใฉใณใใๆๅนใซใใ
buttons.disable_monospace_font=็ญๅน
ใใฉใณใใ็กๅนใซใใ
+buttons.unindent.tooltip = ใขใคใใ ใ1ใคใใคใในใใฎ่งฃ้คใใใ
+buttons.indent.tooltip = ใขใคใใ ใ1ใคใใคใในใใใ
[filter]
string.asc=A - Z
@@ -196,7 +208,7 @@ string.desc=Z - A
[error]
occurred=ใจใฉใผใ็บ็ใใพใใ๏ผ
-report_message=Forgejo ใฎใใฐใ็ใใใๅ ดๅใฏใCodeberg ใงIssueใๆค็ดขใใฆใ่ฆใคใใใชใใใฐๆฐใใIssueใไฝๆใใฆใใ ใใใ
+report_message=Forgejo ใฎใใฐใ็ใใใๅ ดๅใฏใCodeberg ใงIssueใๆค็ดขใใฆใ่ฆใคใใใชใใใฐๆฐใใIssueใไฝๆใใฆใใ ใใใ
missing_csrf=ไธๆญฃใชใชใฏใจในใ: CSRFใใผใฏใณใไธๆใงใ
invalid_csrf=ไธๆญฃใชใชใฏใจในใ: CSRFใใผใฏใณใ็กๅนใงใ
not_found=ใฟใผใฒใใใ่ฆใคใใใพใใใงใใใ
@@ -206,13 +218,12 @@ server_internal = ๅ
้จใตใผใใผใจใฉใผ
[startpage]
app_desc=่ชๅใง็ซใฆใใ่ถ
็ฐกๅ Git ใตใผใใน
install=็ฐกๅใคใณในใใผใซ
-install_desc=ใทใณใใซใซใใใฉใใใใฉใผใ ใซๅฟใใฆใใคใใชใๅฎ่ก ใใใใDocker ใงๅใใใใใใใใฑใผใธ ใไฝฟใใ ใใ
+install_desc=ใทใณใใซใซใใใฉใใใใฉใผใ ใซๅฟใใฆใใคใใชใๅฎ่ก ใใใใDocker ใงๅใใใใใใใใฑใผใธ ใไฝฟใใ ใใ
platform=ใฏใญในใใฉใใใใฉใผใ
-platform_desc=ForgejoใฏGo ใงใณใณใใคใซใงใใ็ฐๅขใชใใฉใใงใๅใใพใ: WindowsใmacOSใLinuxใARM็ญใ
ใๅฅฝใใชใใฎใ้ธใใงใใ ใใ!
lightweight=่ปฝ้
lightweight_desc=Forgejo ใฎๆๅฐๅไฝ่ฆไปถใฏๅฐใใใฆใๅฎไพกใช Raspberry Pi ใงใๅใใพใใใจใใซใฎใผๆถ่ฒปใ็ฏ็ดใใพใใใ!
license=ใชใผใใณใฝใผใน
-license_desc=Go get Forgejo ! ็งใใกใจไธ็ทใซใใฎใใญใธใงใฏใใใใ่ฏใใใฆใใใใใซใไฝใ่ฒข็ฎ ใใฆใฟใพใใใใ ไบ็ดฐใชใใจใงใๅคงไธๅคซ! ็ฉๆฅต็ใซใ้กใใใพใ!
+license_desc=Go get Forgejo ! ็งใใกใจไธ็ทใซใใฎใใญใธใงใฏใใใใ่ฏใใใฆใใใใใซใไฝใ่ฒข็ฎ ใใฆใฟใพใใใใ ไบ็ดฐใชใใจใงใๅคงไธๅคซ! ็ฉๆฅต็ใซใ้กใใใพใ!
[install]
install=ใคใณในใใผใซ
@@ -245,7 +256,7 @@ err_admin_name_is_invalid=็ฎก็่
ใฎใฆใผใถใผๅใไธๆญฃใงใ
general_title=ๅบๆฌ่จญๅฎ
app_name=ใคใณในใฟใณในๅ
-app_name_helper=ไผๆฅญๅใใใใซๅ
ฅใใใใจใใงใใพใใ
+app_name_helper=ใใใซใคใณในใฟใณในๅใๅ
ฅๅใใพใใใใใฏใในใฆใฎใใผใธใซ่กจ็คบใใใพใใ
repo_path=ใชใใธใใชใฎใซใผใใใน
repo_path_helper=ใชใขใผใGitใชใใธใใชใฏใใฎใใฃใฌใฏใใชใซไฟๅญใใใพใใ
lfs_path=Git LFSใซใผใใใน
@@ -279,7 +290,7 @@ offline_mode.description=ๅค้จใฎCDNใตใผใในใไฝฟใใใใในใฆใฎใช
disable_gravatar=Gravatarใ็กๅนใซใใ
disable_gravatar.description=Gravatarใจๅค้จใฎใขใใฟใผใฝใผในใ็กๅนใซใใพใใ ใขใใฟใผใใญใผใซใซใซใขใใใญใผใใใฆใใชใใฆใผใถใผใซใฏใใใใฉใซใใฎใขใใฟใผใไฝฟ็จใใใพใใ
federated_avatar_lookup=ใใงใใฌใผใใใใปใขใใฟใผใๆๅนใซใใ
-federated_avatar_lookup.description=Libravatarใไฝฟ็จใใใใงใใฌใผใใใใปใขใใฟใผๆค็ดขใๆๅนใซใใพใใ
+federated_avatar_lookup.description=Libravatar ใไฝฟ็จใใฆใขใใฟใผใๆค็ดขใใพใใ
disable_registration=ใปใซใ็ป้ฒใ็กๅนใซใใ
disable_registration.description=็ฎก็่
ใ ใใๆฐใใใฆใผใถใผ ใขใซใฆใณใใไฝๆใงใใพใใ่ชฐใใๅฉ็จใงใใใใใชใใฏใคใณในใฟใณในใใในใใใๅคง้ใฎในใใ ใขใซใฆใณใใซๅฏพๅฆใใๆบๅใใงใใฆใใชใ้ใใ็ป้ฒใ็กๅนใซใใฆใใใใจใๅผทใใๅงใใใพใใ
allow_only_external_registration.description=่จญๅฎใใใๅค้จใตใผใในใไฝฟ็จใใฆใฎใฟๆฐใใใขใซใฆใณใใไฝๆใงใใพใใ
@@ -398,14 +409,14 @@ forgot_password_title=ใในใฏใผใใๅฟใใ
forgot_password=ใในใฏใผใใใๅฟใใงใใ๏ผ
sign_up_now=ใขใซใฆใณใใๅฟ
่ฆใงใใ๏ผ ไปใใ็ป้ฒใใพใใใใ
sign_up_successful=ใขใซใฆใณใใฏ็กไบใซไฝๆใใใพใใใใใใใ!
-confirmation_mail_sent_prompt=%s ใซ็ขบ่ชใกใผใซใ้ไฟกใใพใใใ %sไปฅๅ
ใซๅไฟกใใฌใคใ็ขบ่ชใใ็ป้ฒๆ็ถใใๅฎไบใใฆใใ ใใใ
+confirmation_mail_sent_prompt=ๆฐใใ็ขบ่ชใกใผใซใ %s ใซ้ไฟกใใใพใใใ็ป้ฒใใญใปในใๅฎไบใใใซใฏใๅไฟกใใฌใคใ็ขบ่ชใใ %s ไปฅๅ
ใซๆไพใใใใชใณใฏใใฏใชใใฏใใฆไธใใใใกใผใซใ้้ใฃใฆใใๅ ดๅใฏใใญใฐใคใณใใฆๅฅใฎใขใใฌในใซ็ขบ่ชใกใผใซใๅ้ไฟกใใใใใชใฏใจในใใงใใพใใ
must_change_password=ใในใฏใผใใฎๆดๆฐ
allow_password_change=ใฆใผใถใผใฏใในใฏใผใใฎๅคๆดใๅฟ
่ฆ (ๆจๅฅจ)
-reset_password_mail_sent_prompt=%s ใซ็ขบ่ชใกใผใซใ้ไฟกใใพใใใ %sไปฅๅ
ใซๅไฟกใใฌใคใ็ขบ่ชใใใขใซใฆใณใๅๅพฉๆ็ถใใๅฎไบใใฆใใ ใใใ
+reset_password_mail_sent_prompt=็ขบ่ชใกใผใซใ %s ใซ้ไฟกใใใพใใใใขใซใฆใณใๅๅพฉๆ็ถใใๅฎไบใใใซใฏใๅไฟกใใฌใคใ็ขบ่ชใใ%s ไปฅๅ
ใซๆไพใใใใชใณใฏใซๅพใฃใฆใใ ใใใ
active_your_account=ใขใซใฆใณใใฎๆๅนๅ
account_activated=ใขใซใฆใณใใใขใฏใใฃใใผใใใใพใใ
-prohibit_login=ใตใคใณใคใณ็ฆๆญข
-prohibit_login_desc=ใใชใใฎใขใซใฆใณใใฏใตใคใณใคใณใ็ฆๆญขใใใฆใใพใใ ใตใคใ็ฎก็่
ใซใๅใๅใใใใ ใใใ
+prohibit_login=ใขใซใฆใณใใๅๆญขใใใพใใ
+prohibit_login_desc=ใใชใใฎใขใซใฆใณใใฏใคใณในใฟใณในใจใฎใใๅใใๅๆญขใใใฆใใพใใใขใฏใปในใๅๅพฉใใใซใฏใใคใณในใฟใณใน็ฎก็่
ใซๅใๅใใใฆใใ ใใใ
resent_limit_prompt=ๅฐใๅใซใใใชใใใใขใฏใใฃใใผใทใงใณใกใผใซใ่ฆๆฑใใใฆใใพใใ 3ๅๅพ
ใฃใใฎใกใใใไธๅบฆ่ฉฆใใฆใใ ใใใ
has_unconfirmed_mail=ใใใซใกใฏ %s ใใใใใชใใฎใกใผใซ ใขใใฌใน (%s ) ใฏ็ขบ่ชใใจใใฆใใพใใใ ็ขบ่ชใกใผใซใๅใๅใฃใฆใใชใๅ ดๅใใๆนใใฆ้ไฟกใใใๅ ดๅใฏใไธใฎใใฟใณใใฏใชใใฏใใฆใใ ใใใ
resend_mail=ใขใฏใใฃใใผใทใงใณใกใผใซใๅ้ไฟกใใใซใฏใใใใฏใชใใฏ
@@ -448,12 +459,12 @@ email_domain_blacklisted=ใใชใใฎใกใผใซใขใใฌในใงใฏ็ป้ฒใใใ
authorize_application=ใขใใชใฑใผใทใงใณใ่จฑๅฏ
authorize_redirect_notice=ใใฎใขใใชใฑใผใทใงใณใ่จฑๅฏใใใจ %s ใซใชใใคใฌใฏใใใพใใ
authorize_application_created_by=ใใฎใขใใชใฑใผใทใงใณใฏ %s ใไฝๆใใพใใใ
-authorize_application_description=ใขใฏใปในใ่จฑๅฏใใใจใใใฎใขใใชใฑใผใทใงใณใฏใใใฉใคใใผใ ใชใใธใใชใ็ต็นใๅซใใใชใใฎใในใฆใฎใขใซใฆใณใๆ
ๅ ฑใซๅฏพใใฆใใขใฏใปในใจๆธใ่พผใฟใใงใใใใใซใชใใพใใ
+authorize_application_description=ใขใฏใปในใ่จฑๅฏใใใจใใใฉใคใใผใใชใใธใใชใ็ต็นใๅซใใในใฆใฎใขใซใฆใณใๆ
ๅ ฑใซใขใฏใปในใใฆๆธใ่พผใใใจใใงใใใใใซใชใใพใใ
authorize_title=`"%s"ใซใใชใใฎใขใซใฆใณใใธใฎใขใฏใปในใ่จฑๅฏใใพใใ๏ผ`
authorization_failed=่ชๅฏๅคฑๆ
authorization_failed_desc=็กๅนใชใชใฏใจในใใๆคๅบใใใใ่ชๅฏใๅคฑๆใใพใใใ ่ชๅฏใใใใจใใใขใใชใฎ้็บ่
ใซ้ฃ็ตกใใฆใใ ใใใ
sspi_auth_failed=SSPI่ช่จผใซๅคฑๆใใพใใ
-password_pwned=ใใชใใ้ธๆใใใในใฏใผใใฏใ้ๅปใฎๆ
ๅ ฑๆผๆดฉไบไปถใงๆตๅบใใ็ใพใใใในใฏใผใใฎใชในใ ใซๅซใพใใฆใใพใใ ๅฅใฎใในใฏใผใใงใใไธๅบฆ่ฉฆใใฆใใ ใใใ ใพใไปใฎ็ป้ฒใงใใใฎใในใฏใผใใใใฎๅคๆดใๆค่จใใฆใใ ใใใ
+password_pwned=ใใชใใ้ธๆใใใในใฏใผใใฏใ้ๅปใฎๆ
ๅ ฑๆผๆดฉไบไปถใงๆตๅบใใ็ใพใใใในใฏใผใใฎใชในใ ใซๅซใพใใฆใใพใใ ๅฅใฎใในใฏใผใใงใใไธๅบฆ่ฉฆใใฆใใ ใใใ ใพใไปใฎ็ป้ฒใงใใใฎใในใฏใผใใใใฎๅคๆดใๆค่จใใฆใใ ใใใ
password_pwned_err=HaveIBeenPwnedใธใฎใชใฏใจในใใๅฎไบใงใใพใใใงใใ
change_unconfirmed_email = ็ป้ฒๆใซ้้ใฃใใกใผใซ ใขใใฌในใๅ
ฅๅใใๅ ดๅใฏใไปฅไธใงๅคๆดใงใใพใใไปฃใใใซ็ขบ่ชใกใผใซใๆฐใใใขใใฌในใซ้ไฟกใใใพใใ
change_unconfirmed_email_error = ใกใผใซ ใขใใฌในใๅคๆดใงใใพใใ: %v
@@ -461,6 +472,12 @@ change_unconfirmed_email_summary = ใขใฏใใฃใใผใทใงใณใกใผใซใฎ้ไฟก
last_admin=ๆๅพใฎ็ฎก็่
ใฏๅ้คใงใใพใใใๅฐใชใใจใไธไบบใฎ็ฎก็่
ใๅฟ
่ฆใงใใ
tab_signin = ใตใคใณใคใณ
tab_signup = ใตใคใณใขใใ
+sign_in_openid = OpenIDใง็ถ่ก
+back_to_sign_in = ใตใคใณใคใณใซๆปใ
+unauthorized_credentials = ่ณๆ ผๆ
ๅ ฑใๆญฃใใใชใใใๆ้ใๅใใฆใใพใใใณใใณใใๅ่ฉฆ่กใใใใ่ฉณ็ดฐใซใคใใฆใฏ %s ใๅ็
งใใฆใใ ใใ
+sign_up_button = ไปใใ็ป้ฒใใฆไธใใใ
+hint_login = ใใงใซใขใซใฆใณใใใๆใกใงใใ? ไปใใใตใคใณใคใณ!
+hint_register = ใขใซใฆใณใใๅฟ
่ฆใงใใ? ไปใใ็ป้ฒใใฆใใ ใใใ
[mail]
view_it_on=%s ใง่ฆใ
@@ -477,7 +494,7 @@ activate_email=ใกใผใซ ใขใใฌในใ็ขบ่ชใใพใ
activate_email.title=%s ใใใใกใผใซใขใใฌใน็ขบ่ชใใ้กใใใพใ
activate_email.text=ใใชใใฎใกใผใซใขใใฌในใ็ขบ่ชใใใใใ%s ไปฅๅ
ใซๆฌกใฎใชใณใฏใใฏใชใใฏใใฆใใ ใใ:
-register_notify=Forgejoใธใใใใ
+register_notify=%sใธใใใใ
register_notify.title=%[1]s ใใใ%[2]s ใซใใใใ
register_notify.text_1=ใใใฏ %s ใธใฎ็ป้ฒ็ขบ่ชใกใผใซใงใ๏ผ
register_notify.text_2=ใใชใใฏใฆใผใถใผๅ %s ใงใญใฐใคใณใงใใใใใซใชใใพใใใ
@@ -530,6 +547,21 @@ team_invite.text_3=ๆณจ: ใใฎๆๅพ
ใฏ %[1]s ๅฎใงใใ ๆๅพ
ใซๅฟๅฝใใ
admin.new_user.user_info = ใฆใผใถใผๆ
ๅ ฑ
admin.new_user.subject = ๆฐใใใฆใผใถใผใ %sใใตใคใณใขใใใใพใใ
admin.new_user.text = ็ฎก็ใใใซใใใใฎใฆใผใถใผใ็ฎก็ใใใซใฏใใใ ใใฏใชใใฏใใฆใใ ใใใ
+totp_enrolled.text_1.has_webauthn = ใขใซใฆใณใใง TOTP ใๆๅนใซใชใใพใใใไปๅพใฎใขใซใฆใณใใธใฎใญใฐใคใณใงใ2่ฆ็ด ่ช่จผใจใใฆ TOTP ใไฝฟ็จใใใใไปปๆใฎใปใญใฅใชใใฃ ใญใผใไฝฟ็จใใใใจใใงใใพใใ
+totp_enrolled.subject = 2่ฆ็ด ่ช่จผใจใใฆTOTPใๆๅนใซใใพใใ
+totp_enrolled.text_1.no_webauthn = ใขใซใฆใณใใง TOTP ใๆๅนใซใชใใพใใใไปๅพใขใซใฆใณใใซใญใฐใคใณใใใจใใซใ2่ฆ็ด ่ช่จผใจใใฆ TOTP ใไฝฟ็จใใๅฟ
่ฆใใใใพใใ
+password_change.text_1 = ใขใซใฆใณใใฎใในใฏใผใใๅคๆดใใใพใใใ
+password_change.subject = ใในใฏใผใใๅคๆดใใใพใใ
+primary_mail_change.subject = ใใฉใคใใชใกใผใซใๅคๆดใใใพใใ
+primary_mail_change.text_1 = ใใชใใฎใขใซใฆใณใใฎใใฉใคใใชใกใผใซใ %[1]s ใซๅคๆดใใใพใใใใใใซใใใใใฎ้ปๅญใกใผใซ ใขใใฌในใฏใใชใใฎใขใซใฆใณใใซ้ขใใ้ปๅญใกใผใซ้็ฅใๅไฟกใใชใใชใใพใใ
+totp_disabled.subject = TOTPใ็กๅนใซใชใใพใใ
+totp_disabled.text_1 = ใใชใใฎใขใซใฆใณใใฎๆ้ใใผในใฎใฏใณใฟใคใ ใในใฏใผใ (TOTP) ใ็กๅนใซใชใใพใใใ
+totp_disabled.no_2fa = ไปใฎ 2่ฆ็ด ่ช่จผใฏ่จญๅฎใใใฆใใชใใใใ2่ฆ็ด ่ช่จผใไฝฟ็จใใฆใขใซใฆใณใใซใญใฐใคใณใใๅฟ
่ฆใฏใชใใชใใพใใใ
+removed_security_key.subject = ใปใญใฅใชใใฃใญใผใๅ้คใใใพใใ
+removed_security_key.text_1 = ใปใญใฅใชใใฃใญใผ "%[1]s" ใใขใซใฆใณใใใๅ้คใใใพใใใ
+account_security_caution.text_1 = ใใใใใใใชใใฎๆไฝใงใใใฐใใใฎใกใผใซใฏ็ก่ฆใใฆใๅ้กใใใพใใใ
+account_security_caution.text_2 = ใใใใใใใชใใฎๆไฝใงใชใๅ ดๅใใขใซใฆใณใใไธๆญฃๅฉ็จใใใฆใใๅฏ่ฝๆงใใใใพใใใใฎใตใคใใฎ็ฎก็่
ใซ้ฃ็ตกใใฆใใ ใใใ
+removed_security_key.no_2fa = ไปใฎ 2่ฆ็ด ่ช่จผใฏ่จญๅฎใใใฆใใชใใใใ2่ฆ็ด ่ช่จผใไฝฟ็จใใฆใขใซใฆใณใใซใญใฐใคใณใใๅฟ
่ฆใฏใชใใชใใพใใใ
[modal]
yes=ใฏใ
@@ -628,10 +660,9 @@ org_still_own_repo=็ต็นใฏใพใ 1ใคไปฅไธใฎใชใใธใใชใๆๆใใฆใ
org_still_own_packages=็ต็นใฏใพใ 1ใคไปฅไธใฎใใใฑใผใธใๆๆใใฆใใพใใ ๅ
ใซใใใใๅ้คใใฆใใ ใใใ
target_branch_not_exist=ใฟใผใฒใใใฎใใฉใณใใๅญๅจใใฆใใพใใใ
-admin_cannot_delete_self = ็ฎก็่
ใงใใๅ ดๅใ่ชๅ่ช่บซใๅ้คใใใใจใฏใงใใพใใใๆๅใซ็ฎก็่
ๆจฉ้ใๅ้คใใฆใใ ใใใ
+admin_cannot_delete_self=ใใชใใ็ฎก็่
ใงใใๅ ดๅใ่ชๅ่ช่บซใๅ้คใใใใจใฏใงใใพใใใๆๅใซ็ฎก็่
ๆจฉ้ใๅ้คใใฆใใ ใใใ
username_error_no_dots = `่ฑๆฐๅญ (ใ0-9ใใใa-zใใใA-Zใ)ใใใใทใฅ (ใ-ใ)ใใใใณใขใณใใผในใณใข (ใ_ใ) ใฎใฟใๅซใใใใจใใงใใพใใ่ฑๆฐๅญไปฅๅคใฎๆๅญใง้ๅงใพใใฏ็ตไบใใใใจใฏใงใใใ้ฃ็ถใใ่ฑๆฐๅญไปฅๅคใฎๆๅญใ็ฆๆญขใใใฆใใพใใ`
-admin_cannot_delete_self=ใใชใใ็ฎก็่
ใงใใๅ ดๅใ่ชๅ่ช่บซใๅ้คใใใใจใฏใงใใพใใใๆๅใซ็ฎก็่
ๆจฉ้ใๅ้คใใฆใใ ใใใ
unset_password = ใญใฐใคใณใใใฆใผใถใผใซใในใฏใผใใ่จญๅฎใใใฆใใพใใใ
unsupported_login_type = ใใฎใญใฐใคใณใฟใคใใงใฏใใขใซใฆใณใใฎๅ้คใฏใตใใผใใใใฆใใพใใใ
required_prefix = "%s"ใใๅงใพใๅฟ
่ฆใใใใพใ
@@ -668,16 +699,24 @@ settings=ใฆใผใถใผ่จญๅฎ
form.name_reserved=ใฆใผใถใผๅ "%s" ใฏไบ็ดใใใฆใใพใใ
form.name_pattern_not_allowed=`"%s" ใฎๅฝขๅผใฏใฆใผใถใผๅใซไฝฟ็จใงใใพใใใ`
form.name_chars_not_allowed=ใฆใผใถใผๅ "%s" ใซใฏ็กๅนใชๆๅญใๅซใพใใฆใใพใใ
-block_user.detail_2 = ใใฎใฆใผใถใผใฏใใชใใธใใชใไฝๆใใใใคใทใฅใผใใณใกใณใใๆไฝใงใใพใใใ
-block_user.detail_1 = ใใฎใฆใผใถใผใใใฎใใฉใญใผใ่งฃ้คใใใฆใใพใใ
+block_user.detail_2 = ใใฎใฆใผใถใผใฏใใใชใใๆๆใใใชใใธใใชใใใใชใใไฝๆใใๅ้กใใณใกใณใใๆไฝใใใใจใฏใงใใพใใใ
+block_user.detail_1 = ใไบใใฎใใฉใญใผใๅๆญขใใใใใฉใญใผใงใใชใใชใใพใใ
follow_blocked_user = ใใชใใฏใใฎใฆใผใถใผใใใฉใญใผใงใใพใใใใชใใชใใใใชใใฏใใฎใฆใผใถใผใใใญใใฏใใใใใใฎใฆใผใถใผใฏใใชใใใใญใใฏใใฆใใใใใงใใ
-block_user.detail_3 = ใใฎใฆใผใถใผใฏใใชใใใณใฉใใฌใผใฟใผใจใใฆ่ฟฝๅ ใใใใจใฏใงใใพใใใใใใชใใๅฝผใใใณใฉใใฌใผใฟใผใซ่ฟฝๅ ใงใใพใใใ
+block_user.detail_3 = ใไบใใใชใใธใใชใฎๅ
ฑๅไฝๆฅญ่
ใจใใฆ่ฟฝๅ ใใใใจใฏใงใใพใใใ
block_user = ใฆใผใถใผใใใญใใฏ
unblock = ใใญใใฏใ่งฃ้ค
block = ใใญใใฏ
-block_user.detail = ใใฎใฆใผใถใผใใใญใใฏใใๅ ดๅใไธ่จใฎไบใชใฉใ่ตทใใใพใใไพใใฐ๏ผ
+block_user.detail = ใฆใผใถใผใใใญใใฏใใใจใๆฌกใฎใใใชๅฝฑ้ฟใใใใพใ๏ผ
followers_one = %d ไบบใฎใใฉใญใฏใผ
following_one = %d ไบบใใใฉใญใผไธญ
+public_activity.visibility_hint.self_public = ใใชใใฎใขใฏใใฃใใใฃใฏใใใฉใคใใผใ ในใใผในใงใฎใใๅใใ้คใใใในใฆใฎใฆใผใถใผใซ่กจ็คบใใใพใใ่จญๅฎ ใ
+public_activity.visibility_hint.admin_public = ใใฎใขใฏใใฃใใใฃใฏ่ชฐใงใ่ฆใใใจใใงใใพใใใ็ฎก็่
ใฏใใฉใคใใผใ ในใใผในใงใฎใใๅใใ่ฆใใใจใใงใใพใใ
+public_activity.visibility_hint.self_private = ใใชใใฎใขใฏใใฃใใใฃใฏใใชใใจใคใณในใฟใณใน็ฎก็่
ใซใฎใฟ่กจ็คบใใใพใใ่จญๅฎ ใ
+public_activity.visibility_hint.admin_private = ใใฎใขใฏใใฃใใใฃใฏ็ฎก็่
ใงใใใใชใใซใฏ่กจ็คบใใใพใใใใฆใผใถใผใฏ้ๅ
ฌ้ใซใใใใจ่ใใฆใใพใใ
+following.title.one = ใใฉใญใผไธญ
+following.title.few = ใใฉใญใผไธญ
+followers.title.one = ใใฉใญใฏใผ
+followers.title.few = ใใฉใญใฏใผ
[settings]
profile=ใใญใใฃใผใซ
@@ -787,12 +826,12 @@ add_new_email=ๆฐใใใกใผใซใขใใฌในใ่ฟฝๅ
add_new_openid=ๆฐใใOpenID URIใ่ฟฝๅ
add_email=ใกใผใซใขใใฌในใ่ฟฝๅ
add_openid=OpenID URIใ่ฟฝๅ ใใ
-add_email_confirmation_sent=`"%s" ใซ็ขบ่ชใกใผใซใ้ไฟกใใพใใใ %sไปฅๅ
ใซๅไฟกใใฌใคใ็ขบ่ชใใใกใผใซใขใใฌใน็ขบ่ชใ่กใฃใฆใใ ใใใ`
+add_email_confirmation_sent=็ขบ่ชใกใผใซใ"%s"ใซ้ไฟกใใใพใใใใกใผใซใขใใฌในใ็ขบ่ชใใใซใฏใๅไฟกใใฌใคใ็ขบ่ชใใ%sไปฅๅ
ใซๆไพใใใใชใณใฏใใฏใชใใฏใใฆใใ ใใใ
add_email_success=ๆฐใใใกใผใซใขใใฌในใ่ฟฝๅ ใใพใใใ
email_preference_set_success=ใกใผใซ่จญๅฎใไฟๅญใใพใใใ
add_openid_success=ๆฐใใOpenIDใขใใฌในใ่ฟฝๅ ใใพใใใ
keep_email_private=ใกใผใซใขใใฌในใ้ ใ
-keep_email_private_popup=ใใใซใใใใญใใฃใผใซใงใกใผใซใขใใฌในใ้ ใใใWebใคใณใฟใผใใงใผในใงใฎใใซใชใฏใจในใไฝๆใใใกใคใซ็ทจ้ใงใใกใผใซใขใใฌในใ้ ใใใพใใ ใใใทใฅๆธใฟใฎใณใใใใฏๅคๆดใใใพใใใ
+keep_email_private_popup=ใใใซใใใใใญใใฃใผใซใใใกใผใซใขใใฌในใ้่กจ็คบใซใชใใพใใใใกใคใซใฎใขใใใญใผใใ็ทจ้ใชใฉใใฆใงใใคใณใฟใผใใงใผใน็ต็ฑใง่กใใใใณใใใใฎใใใฉใซใใจใใฆไฝฟ็จใใใชใใชใใใใผใธใณใใใใซใไฝฟ็จใใใพใใใไปฃใใใซใใณใใใใใใชใใฎใขใซใฆใณใใซ้ข้ฃไปใใใใใซ็นๅฅใชใขใใฌใน%sใไฝฟ็จใงใใพใใใใฎใชใใทใงใณใๅคๆดใใฆใใๆขๅญใฎใณใใใใซใฏๅฝฑ้ฟใใชใใใจใซๆณจๆใใฆใใ ใใใ
openid_desc=OpenIDใไฝฟใใจๅค้จใใญใใคใใผใซ่ช่จผใๅงไปปใใใใจใใงใใพใใ
manage_ssh_keys=SSHใญใผใฎ็ฎก็
@@ -895,7 +934,7 @@ select_permissions=่จฑๅฏใฎ้ธๆ
permission_no_access=ใขใฏใปในไธๅฏ
permission_read=่ชญใฟๅใ
permission_write=่ชญใฟๅใใจๆธใ่พผใฟ
-access_token_desc=้ธๆใใใใผใฏใณๆจฉ้ใซๅฟใใฆใ้ข้ฃใใAPI ใซใผใใฎใฟใซ่จฑๅฏใๅถ้ใใใพใใ ่ฉณ็ดฐใฏใใญใฅใกใณใ ใๅ็
งใใฆใใ ใใใ
+access_token_desc=้ธๆใใใใผใฏใณๆจฉ้ใซๅฟใใฆใ้ข้ฃใใAPI ใซใผใใฎใฟใซ่จฑๅฏใๅถ้ใใใพใใ ่ฉณ็ดฐใฏใใญใฅใกใณใ ใๅ็
งใใฆใใ ใใใ
at_least_one_permission=ใใผใฏใณใไฝๆใใใซใฏใๅฐใชใใจใใฒใจใคใฎ่จฑๅฏใ้ธๆใใๅฟ
่ฆใใใใพใ
permissions_list=่จฑๅฏ:
@@ -949,7 +988,7 @@ passcode_invalid=ใในใณใผใใ้้ใฃใฆใใพใใ ๅๅบฆใ่ฉฆใใ
twofa_enrolled=ใใชใใฎใขใซใฆใณใใฏๆญฃๅธธใซ็ป้ฒใใใพใใใ ไธๅ้ใใฎใชใซใใชใญใผ (%s) ใฏๅฎๅ
จใชๅ ดๆใซไฟๅญใใฆใใ ใใใ ใใใฏไบๅบฆใจ่กจ็คบใใใพใใใ
twofa_failed_get_secret=ใทใผใฏใฌใใใๅๅพใงใใพใใใ
-webauthn_desc=ใปใญใฅใชใใฃใญใผใฏๆๅทๅใญใผใๅ
่ตใใใใผใใฆใงใข ใป ใใใคในใงใใ 2่ฆ็ด ่ช่จผใซไฝฟ็จใงใใพใใ ใปใญใฅใชใใฃใญใผใฏWebAuthn Authenticator ่ฆๆ ผใใตใใผใใใฆใใๅฟ
่ฆใใใใพใใ
+webauthn_desc=ใปใญใฅใชใใฃใญใผใฏๆๅทๅใญใผใๅ
่ตใใใใผใใฆใงใข ใป ใใใคในใงใใ 2่ฆ็ด ่ช่จผใซไฝฟ็จใงใใพใใ ใปใญใฅใชใใฃใญใผใฏWebAuthn Authenticator ่ฆๆ ผใใตใใผใใใฆใใๅฟ
่ฆใใใใพใใ
webauthn_register_key=ใปใญใฅใชใใฃใญใผใ่ฟฝๅ
webauthn_nickname=ใใใฏใใผใ
webauthn_delete_key=ใปใญใฅใชใใฃใญใผใฎ็ป้ฒ่งฃ้ค
@@ -1000,11 +1039,14 @@ pronouns = ไปฃๅ่ฉ
pronouns_custom = ใซในใฟใ
pronouns_unspecified = ๆชๆๅฎ
update_hints = ใใณใใๆดๆฐ
-additional_repo_units_hint_description = ๅฉ็จๅฏ่ฝใชใในใฆใฎๆฉ่ฝใๆๅนใซใชใฃใฆใใชใใชใใธใใชใซๅฏพใใฆใใๆฉ่ฝใ่ฟฝๅ ...ใใใฟใณใ่กจ็คบใใพใใ
+additional_repo_units_hint_description = ๅฉ็จๅฏ่ฝใชใในใฆใฎๆฉ่ฝใๆๅนใซใชใฃใฆใใชใใชใใธใใชใซๅฏพใใฆใใใใใซๆๅนใซใใใใใณใใ่กจ็คบใใพใใ
update_hints_success = ใใณใใๆดๆฐใใใพใใใ
hints = ใใณใ
additional_repo_units_hint = ใชใใธใใชใงใใๅคใใฎๆฉ่ฝใๆๅนใซใใใใจใๆจๅฅจใใ
language.title = ๆขๅฎใฎ่จ่ช
+keep_activity_private.description = ๅ
ฌ้ใขใฏใใฃใใใฃ ใฏใใใชใใจใคใณในใฟใณใน็ฎก็่
ใซใฎใฟ่กจ็คบใใใพใใ
+language.description = ใใฎ่จ่ชใฏใขใซใฆใณใใซไฟๅญใใใใญใฐใคใณๅพใซใใใฉใซใใจใใฆไฝฟ็จใใใพใใ
+language.localization_project = Forgejo ใใใชใใฎ่จ่ชใซ็ฟป่จณใใใฎใๆไผใฃใฆใใ ใใใ่ฉณ็ดฐใฏใใกใ ใ
[repo]
new_repo_helper=ใชใใธใใชใซใฏใใใญใธใงใฏใใฎใในใฆใฎใใกใคใซใจใชใใธใงใณๅฑฅๆญดใๅ
ฅใใพใใ ใใงใซใปใใฎๅ ดๆใงใในใใใฆใใพใใ๏ผ ใชใใธใใชใ็งป่ก ใใฉใใใ
@@ -1021,7 +1063,7 @@ visibility=ๅ
ฌ้/้ๅ
ฌ้
visibility_description=ใชใผใใผใใพใใฏๆจฉ้ใๆใค็ต็นใฎใกใณใใผใ ใใใใชใใธใใชใ่ฆใใใจใใงใใพใใ
visibility_helper=ใชใใธใใชใใใฉใคใใผใใซใใ
visibility_helper_forced=ใตใคใ็ฎก็่
ใฎ่จญๅฎใซใใใๆฐใใใชใใธใใชใฏๅผทๅถ็ใซใใฉใคใใผใใซใชใใพใใ
-visibility_fork_helper=(ใใฎๅคๆดใฏใในใฆใฎใใฉใผใฏใซ้ฉ็จใใใพใ)
+visibility_fork_helper=(ใใฎๅคๆดใฏใในใฆใฎใใฉใผใฏใฎๅฏ่ฆๆงใซๅฝฑ้ฟใใพใใ)
clone_helper=ใฏใญใผใณใซ้ขใใฆใๅฐใใงใใใฐใใซใ ใๅ็
งใใพใใใใ
fork_repo=ใชใใธใใชใใใฉใผใฏ
fork_from=ใใฉใผใฏๅ
@@ -1043,15 +1085,15 @@ repo_desc_helper=็ฐกๅใช่ชฌๆใๅ
ฅๅใใฆใใ ใใ (ใชใใทใงใณ)
repo_lang=่จ่ช
repo_gitignore_helper=.gitignoreใใณใใฌใผใใ้ธๆใใฆใใ ใใใ
repo_gitignore_helper_desc=ไธ่ฌ็ใช่จ่ชใฎใใณใใฌใผใใชในใใใใ่ฟฝ่ทกใใชใใใกใคใซใฎ่จญๅฎใ้ธๆใใพใใ ๅ่จ่ชใฎใใซใใใผใซใ็ๆใใๅ
ธๅ็ใชใใกใคใซใใใใใฉใซใใง.gitignoreใซๅซใพใใพใใ
-issue_labels=ใคใทใฅใผใฉใใซ
-issue_labels_helper=ใคใทใฅใผใฎใฉใใซใปใใใ้ธๆ
+issue_labels=ใฉใใซ
+issue_labels_helper=ใฉใใซใปใใใ้ธๆ
license=ใฉใคใปใณใน
-license_helper=ใฉใคใปใณใน ใใกใคใซใ้ธๆใใฆใใ ใใใ
+license_helper=ใฉใคใปใณใน ใใกใคใซใ้ธๆใใฆใใ ใใ
license_helper_desc=ใฉใคใปใณในใซใใใไปไบบใใใชใใฎใณใผใใซๅฏพใใฆไฝใใงใใฆไฝใใงใใชใใฎใใ่ฆๅฎใใพใใ ใฉใใใใญใธใงใฏใใซใตใใใใใ่ฟทใฃใฆใใพใใ๏ผ ใฉใคใปใณใน้ธๆใตใคใ ใ็ขบ่ชใใฆใฟใฆใใ ใใใ
object_format=ใชใใธใงใฏใใฎใใฉใผใใใ
-object_format_helper=ใชใใธใใชใฎใชใใธใงใฏใใใฉใผใใใใๅพใงๅคๆดใใใใจใฏใงใใพใใใSHA1 ใฏๆใไบๆๆงใใใใพใใ
+object_format_helper=ใชใใธใใชใฎใชใใธใงใฏใใใฉใผใใใใๅพใงๅคๆดใใใใจใฏใงใใพใใใSHA1 ใๆใไบๆๆงใใใใพใใ
readme=README
-readme_helper=READMEใใกใคใซ ใใณใใฌใผใใ้ธๆใใฆใใ ใใใ
+readme_helper=READMEใใกใคใซ ใใณใใฌใผใใ้ธๆใใฆใใ ใใ
readme_helper_desc=ใใญใธใงใฏใใซใคใใฆใฎ่ชฌๆใใฒใจใจใใๆธใๅ ดๆใงใใ
auto_init=ใชใใธใใชใฎๅๆ่จญๅฎ (.gitignoreใใฉใคใปใณในใใกใคใซใREADMEใใกใคใซใฎ่ฟฝๅ )
trust_model_helper=็ฝฒๅๆค่จผใฎใใฉในใใขใใซใ้ธๆใใพใใ ้ธๆ่ขใฏๆฌกใฎใจใใใงใ:
@@ -1117,8 +1159,7 @@ desc.public=ๅ
ฌ้
desc.template=ใใณใใฌใผใ
desc.internal=็ต็นๅ
desc.archived=ใขใผใซใคใ
-desc.sha256=SHA256
-
+desc.sha256 = SHA256
template.items=ใใณใใฌใผใ้
็ฎ
template.git_content=Gitใณใณใใณใ (ใใใฉใซใใใฉใณใ)
template.git_hooks=Gitใใใฏ
@@ -1178,7 +1219,7 @@ migrate.migrating_failed_no_addr=็งป่กใซๅคฑๆใใพใใใ
migrate.github.description=github.com ใใใฎไปใฎ GitHub ใจใณใฟใผใใฉใคใบใตใผใใผใใใใผใฟใ็งป่กใใพใใ
migrate.git.description=Git ใตใผใในใใใชใใธใใชใฎใฟใ็งป่กใใพใใ
migrate.gitlab.description=gitlab.com ใใใฎไปใฎ GitLab ใคใณในใฟใณในใใใใผใฟใ็งป่กใใพใใ
-migrate.gitea.description=gitea.com ใใใฎไปใฎ Gitea/Forgejo ใคใณในใฟใณในใใใใผใฟใ็งป่กใใพใใ
+migrate.gitea.description=gitea.com ใใใฎไปใฎ Gitea ใคใณในใฟใณในใใใใผใฟใ็งป่กใใพใใ
migrate.gogs.description=notabug.org ใใใฎไปใฎ Gogs ใคใณในใฟใณในใใใใผใฟใ็งป่กใใพใใ
migrate.onedev.description=code.onedev.io ใใใฎไปใฎ OneDev ใคใณในใฟใณในใใใใผใฟใ็งป่กใใพใใ
migrate.codebase.description=codebasehq.com ใใใใผใฟใ็งป่กใใพใใ
@@ -1266,6 +1307,7 @@ view_git_blame=Git Blameใ่กจ็คบ
video_not_supported_in_browser=ใใฎใใฉใฆใถใฏHTML5ใฎvideoใฟใฐใใตใใผใใใฆใใพใใใ
audio_not_supported_in_browser=ใใฎใใฉใฆใถใผใฏHTML5ใฎaudioใฟใฐใใตใใผใใใฆใใพใใใ
stored_lfs=Git LFSใงไฟ็ฎกใใใฆใใพใ
+stored_annex=Git Annexใงไฟ็ฎกใใใฆใใพใ
symbolic_link=ใทใณใใชใใฏ ใชใณใฏ
executable_file=ๅฎ่กใใกใคใซ
commit_graph=ใณใใใใฐใฉใ
@@ -1289,6 +1331,7 @@ editor.upload_file=ใใกใคใซใใขใใใญใผใ
editor.edit_file=ใใกใคใซใ็ทจ้
editor.preview_changes=ๅคๆดใใใฌใใฅใผ
editor.cannot_edit_lfs_files=LFSใฎใใกใคใซใฏWebใคใณใฟใผใใงใผในใง็ทจ้ใงใใพใใใ
+editor.cannot_edit_annex_files=AnnexใฎใใกใคใซใฏWebใคใณใฟใผใใงใผในใง็ทจ้ใงใใพใใใ
editor.cannot_edit_non_text_files=ใใคใใชใใกใคใซใฏWebใคใณใฟใผใใงใผในใง็ทจ้ใงใใพใใใ
editor.edit_this_file=ใใกใคใซใ็ทจ้
editor.this_file_locked=ใใกใคใซใฏใญใใฏใใใฆใใพใ
@@ -1303,7 +1346,8 @@ editor.or=ใพใใฏ
editor.cancel_lower=ใญใฃใณใปใซ
editor.commit_signed_changes=็ฝฒๅใใๅคๆดใใณใใใ
editor.commit_changes=ๅคๆดใใณใใใ
-editor.add_tmpl="<ใใกใคใซๅ>" ใ่ฟฝๅ
+editor.add_tmpl="<%s>" ใ่ฟฝๅ
+editor.add_tmpl.filename = ใใกใคใซๅ
editor.add=%s ใ่ฟฝๅ
editor.update=%s ใๆดๆฐ
editor.delete=%s ใๅ้ค
@@ -1313,7 +1357,7 @@ editor.fail_to_apply_patch=`ใใใใ้ฉ็จใงใใพใใ "%s"`
editor.new_patch=ๆฐใใใใใ
editor.commit_message_desc=่ฉณ็ดฐใช่ชฌๆใ่ฟฝๅ โฆ
editor.signoff_desc=ใณใใใใญใฐใกใใปใผใธใฎๆๅพใซใณใใใฟใผใฎ Signed-off-by ่กใ่ฟฝๅ
-editor.commit_directly_to_this_branch=ใใฉใณใ%s ใธ็ดๆฅใณใใใใใใ
+editor.commit_directly_to_this_branch=ใใฉใณใ%[1]s ใธ็ดๆฅใณใใใใใใ
editor.create_new_branch=ๆฐใใใใฉใณใ ใซใณใใใใใฆใใซใชใฏใจในใใไฝๆใใใ
editor.create_new_branch_np=ๆฐใใใใฉใณใ ใซใณใใใใใใ
editor.propose_file_change=ใใกใคใซไฟฎๆญฃใๆๆก
@@ -1383,7 +1427,7 @@ commitstatus.failure=ๅคฑๆ
commitstatus.pending=ไฟ็
commitstatus.success=ๆๅ
-ext_issues=ๅค้จใคใทใฅใผใธใฎใขใฏใปใน
+ext_issues=ๅค้จใคใทใฅใผ
ext_issues.desc=ๅค้จใฎใคใทใฅใผใใฉใใซใผใธใฎใชใณใฏใ
projects=ใใญใธใงใฏใ
@@ -1418,7 +1462,7 @@ projects.column.set_default_desc=ใใฎๅใๆชๅ้กใฎใคใทใฅใผใใใซ
projects.column.unset_default=ใใใฉใซใใ่งฃ้ค
projects.column.unset_default_desc=ใใฎๅใใใใใฉใซใๅใฎ่จญๅฎใ่งฃ้คใใพใ
projects.column.delete=ๅใๅ้ค
-projects.column.deletion_desc=ใใญใธใงใฏใๅใๅ้คใใใจใ้ข้ฃใใใในใฆใฎใคใทใฅใผใ 'ๆชๅ้ก' ใซ็งปๅใใพใใ ็ถ่กใใพใใ๏ผ
+projects.column.deletion_desc=ใใญใธใงใฏใๅใๅ้คใใใจใ้ข้ฃใใใในใฆใฎใคใทใฅใผใใใใฉใซใใฎๅใซ็งปๅใใพใใ ็ถ่กใใพใใ๏ผ
projects.column.color=ใซใฉใผ
projects.open=ใชใผใใณ
projects.close=ใฏใญใผใบ
@@ -1466,10 +1510,10 @@ issues.new_label=ๆฐใใใฉใใซ
issues.new_label_placeholder=ใฉใใซๅ
issues.new_label_desc_placeholder=่ชฌๆ
issues.create_label=ใฉใใซใไฝๆ
-issues.label_templates.title=ๅฎ็พฉๆธใฟใฉใใซใปใใใฎ่ชญใฟ่พผใฟ
-issues.label_templates.info=ใฉใใซใใพใ ใใใพใใใ"ๆฐใใใฉใใซ"ใงใฉใใซใไฝๆใใใใๆฌกใฎๅฎ็พฉๆธใฟใฎใฉใใซใปใใใไฝฟ็จใใฆใใ ใใ:
-issues.label_templates.helper=ใฉใใซใปใใใ้ธๆ
-issues.label_templates.use=ใฉใใซใปใใใไฝฟ็จ
+issues.label_templates.title=ใฉใใซใใชใปใใใ่ชญใฟ่พผใ
+issues.label_templates.info=ใฉใใซใใพใ ใใใพใใใ"ๆฐใใใฉใใซ"ใงใฉใใซใไฝๆใใใใใฉใใซใใชใปใใใไฝฟ็จใใฆใใ ใใ:
+issues.label_templates.helper=ใฉใใซใใชใปใใใ้ธๆใใ
+issues.label_templates.use=ใฉใใซใใชใปใใใไฝฟ็จ
issues.label_templates.fail_to_load_file=ใฉใใซใใณใใฌใผใ "%s" ใ่ชญใฟ่พผใใพใใใงใใ: %v
issues.add_label=ใใฉใใซ %s ใ่ฟฝๅ %s
issues.add_labels=ใใฉใใซ %s ใ่ฟฝๅ %s
@@ -1589,7 +1633,7 @@ issues.role.collaborator_helper=ใใฎใฆใผใถใผใฏใชใใธใใชไธใงๅ
ฑๅ
issues.role.first_time_contributor=ๅใใฆใฎ่ฒข็ฎ่
issues.role.first_time_contributor_helper=ใใใฏใใใฎใฆใผใถใผใซใใใชใใธใใชใธใฎๆๅใฎ่ฒข็ฎใงใใ
issues.role.contributor=่ฒข็ฎ่
-issues.role.contributor_helper=ใใฎใฆใผใถใผใฏไปฅๅใซใชใใธใใชใซใณใใใใใฆใใพใใ
+issues.role.contributor_helper=ใใฎใฆใผใถใผใฏไปฅๅใซใใฎใชใใธใใชใซใณใใใใใฆใใพใใ
issues.re_request_review=ใฌใใฅใผใๅไพ้ ผ
issues.is_stale=ใใฎใฌใใฅใผใฎใใจใใใฎPRใซๅคๆดใใใใพใใ
issues.remove_request_review=ใฌใใฅใผไพ้ ผใๅใๆถใ
@@ -1604,7 +1648,7 @@ issues.label_title=ๅๅ
issues.label_description=่ชฌๆ
issues.label_color=ใซใฉใผ
issues.label_exclusive=ๆไป
-issues.label_archive=ใขใผใซใคใ ใฉใใซ
+issues.label_archive=ใฉใใซใใขใผใซใคใ
issues.label_archived_filter=ใขใผใซใคใใใใใฉใใซใ่กจ็คบ
issues.label_archive_tooltip=ใขใผใซใคใใใใใฉใใซใฏใใฉใใซใซใใๆค็ดขๆใฎใตใธใงในใใใใใใฉใซใใง้คๅคใใใพใใ
issues.label_exclusive_desc=ใฉใใซๅใ ในใณใผใ/ใขใคใใ
ใฎๅฝขใซใใใใจใงใไปใฎ ในใณใผใ/
ใฉใใซใจๆไป็ใซใชใใพใใ
@@ -1636,8 +1680,8 @@ issues.lock.unknown_reason=ๆชๅฎ็พฉใฎ็็ฑใงใฏใคใทใฅใผใใญใใฏใง
issues.lock_duplicate=ใคใทใฅใผใฏไบ้ใซใญใใฏใงใใพใใใ
issues.unlock_error=ใญใใฏใใใฆใใชใใคใทใฅใผใใขใณใญใใฏใงใใพใใใ
issues.lock_with_reason=ใ%s ใฎใใใญใใฏใไผ่ฉฑใๅ
ฑๅไฝๆฅญ่
ใซ้ๅฎ %s
-issues.lock_no_reason=ใใญใใฏใใฆไผ่ฉฑใๅ
ฑๅไฝๆฅญ่
ใซ้ๅฎ %s
-issues.unlock_comment=ใใใฎไผ่ฉฑใใขใณใญใใฏ %s
+issues.lock_no_reason=ใญใใฏใใใฆใใใไผ่ฉฑใๅ
ฑๅไฝๆฅญ่
ใซๅถ้ใใใฆใใพใ %s
+issues.unlock_comment=ใใฎไผ่ฉฑใฎใญใใฏใ่งฃ้ค %s
issues.lock_confirm=ใญใใฏ
issues.unlock_confirm=ใขใณใญใใฏ
issues.lock.notice_1=- ไปใฎใฆใผใถใผใฏใใฎใคใทใฅใผใซๆฐใใใณใกใณใใ่ฟฝๅ ใงใใพใใใ
@@ -1662,9 +1706,9 @@ issues.stop_tracking=ใฟใคใใผ ็ตไบ
issues.stop_tracking_history=`ใไฝๆฅญใ็ตไบ %s`
issues.cancel_tracking=ไธญๆญข
issues.cancel_tracking_history=`ใใฟใคใ ใใฉใใญใณใฐใไธญๆญข %s`
-issues.add_time=ๆใงๆ้ใๅ
ฅๅ
+issues.add_time=ๆๅใงๆ้ใๅ
ฅๅ
issues.del_time=ใใฎใฟใคใ ใญใฐใๅ้ค
-issues.add_time_short=ๆ้ๅ
ฅๅ
+issues.add_time_short=ๆ้ใๅ
ฅๅ
issues.add_time_cancel=ใญใฃใณใปใซ
issues.add_time_history=`ใไฝๆฅญๆ้ใ่ฟฝๅ %s`
issues.del_time_history=`ใไฝๆฅญๆ้ใๅ้ค %s`
@@ -1679,7 +1723,7 @@ issues.error_modifying_due_date=ๆๆฅใๅคๆดใงใใพใใใงใใใ
issues.error_removing_due_date=ๆๆฅใๅ้คใงใใพใใใงใใใ
issues.push_commit_1=ใ %d ใณใใใ่ฟฝๅ %s
issues.push_commits_n=ใ %d ใณใใใ่ฟฝๅ %s
-issues.force_push_codes=`ใ %[1]s ใๅผทๅถใใใทใฅ ( %[2]s
ใใ %[4]s
ใธ ) %[6]s`
+issues.force_push_codes=`ใ %[1]s ใๅผทๅถใใใทใฅ ( %[2]s
ใใ %[4]s
ใธ ) %[6]s`
issues.force_push_compare=ๆฏ่ผ
issues.due_date_form=yyyy-mm-dd
issues.due_date_form_add=ๆๆฅใฎ่ฟฝๅ
@@ -1691,7 +1735,7 @@ issues.due_date_added=ใๆๆฅ %s ใ่ฟฝๅ %s
issues.due_date_modified=ใๆๆฅใ %[2]s ใใ %[1]s ใซๅคๆด %[3]s
issues.due_date_remove=ใๆๆฅ %s ใๅ้ค %s
issues.due_date_overdue=ๆๆฅใฏ้ใใฆใใพใ
-issues.due_date_invalid=ๆๆฅใๆญฃใใใชใใ็ฏๅฒใ่ถ
ใใฆใใพใใ 'yyyy-mm-dd' ใฎๅฝขๅผใงๅ
ฅๅใใฆใใ ใใใ
+issues.due_date_invalid=ๆๆฅใๆญฃใใใชใใ็ฏๅฒใ่ถ
ใใฆใใพใใ "yyyy-mm-dd" ใฎๅฝขๅผใงๅ
ฅๅใใฆใใ ใใใ
issues.dependency.title=ไพๅญ้ขไฟ
issues.dependency.issue_no_dependencies=ไพๅญ้ขไฟใ่จญๅฎใใใฆใใพใใใ
issues.dependency.pr_no_dependencies=ไพๅญ้ขไฟใ่จญๅฎใใใฆใใพใใใ
@@ -1709,7 +1753,7 @@ issues.dependency.issue_closing_blockedby=ใใฎใคใทใฅใผใฎใฏใญใผใบใฏ
issues.dependency.issue_close_blocks=ใใฎใคใทใฅใผใฏใใใใใฎใคใทใฅใผใฎใฏใญใผใบใใใญใใฏใใฆใใพใ
issues.dependency.pr_close_blocks=ใใฎใใซใชใฏใจในใใฏใใใใใฎใคใทใฅใผใฎใฏใญใผใบใใใญใใฏใใฆใใพใ
issues.dependency.issue_close_blocked=ใใฎใคใทใฅใผใใฏใญใผใบใใใซใฏใใใญใใฏใใฆใใใคใทใฅใผใใในใฆใฏใญใผใบใใๅฟ
่ฆใใใใพใใ
-issues.dependency.issue_batch_close_blocked=้ธๆใใใคใทใฅใผใฎไธๆฌใฏใญใผใบใฏใงใใพใใใ ใคใทใฅใผ #%d ใซใใพใ ใชใผใใณไธญใฎไพๅญ้ขไฟใใใใพใใ
+issues.dependency.issue_batch_close_blocked=ใคใทใฅใผ #%d ใซใพใ ไพๅญ้ขไฟใใใใใใ้ธๆใใใคใทใฅใผใไธๆฌใง้ใใใใจใฏใงใใพใใ
issues.dependency.pr_close_blocked=ใใฎใใซใชใฏใจในใใๆไฝใใใซใฏใใใญใใฏใใฆใใใคใทใฅใผใใในใฆใฏใญใผใบใใๅฟ
่ฆใใใใพใใ
issues.dependency.blocks_short=ใใญใใฏๅฏพ่ฑก
issues.dependency.blocked_by_short=ไพๅญๅ
@@ -1794,7 +1838,7 @@ pulls.nothing_to_compare=ๅใใใฉใณใๅๅฃซใฎใใใ ใใซใชใฏใจใน
pulls.nothing_to_compare_and_allow_empty_pr=ใใใใฎใใฉใณใใฏๅ
ๅฎนใๅใใงใใ ็ฉบใฎใใซใชใฏใจในใใซใชใใพใใ
pulls.has_pull_request=`ๅใใใฉใณใใฎใใซใชใฏใจในใใฏใใงใซๅญๅจใใพใ: %[2]s#%[3]d `
pulls.create=ใใซใชใฏใจในใใไฝๆ
-pulls.title_desc_few=ใ %[2]s
ใใ %[3]s
ใธใฎ %[1]d ใณใใใใฎใใผใธใๅธๆใใฆใใพใ
+pulls.title_desc_few=ใ %[2]s
ใใ %[3]s
ใธใฎ %[1]d ใณใใใใฎใใผใธใๅธๆใใฆใใพใ
pulls.merged_title_desc_few=ใ %[1]d ๅใฎใณใใใใ %[2]s
ใใ %[3]s
ใธใใผใธ %[4]s
pulls.change_target_branch_at=`ใใฟใผใฒใใใใฉใณใใ %s ใใ %s ใซๅคๆด %s`
pulls.tab_conversation=ไผ่ฉฑ
@@ -1824,7 +1868,7 @@ pulls.required_status_check_administrator=็ฎก็่
ใงใใใใใใใฎใ
pulls.blocked_by_approvals=ใใฎใใซใชใฏใจในใใฏใพใ ๆฟ่ชๆฐใ่ถณใใพใใใ %[1]d/%[2]dใฎๆฟ่ชใๅพใฆใใพใใ
pulls.blocked_by_rejection=ใใฎใใซใชใฏใจในใใฏๅ
ฌๅผใฌใใฅใผใขใซใใๅคๆด่ฆ่ซใใใฆใใพใใ
pulls.blocked_by_official_review_requests=ใใฎใใซใชใฏใจในใใซใฏๅ
ฌๅผใฌใใฅใผไพ้ ผใใใใพใใ
-pulls.blocked_by_outdated_branch=ใใฎใใซใชใฏใจในใใฏ้
ใใฎใใใใญใใฏใใใฆใใพใใ
+pulls.blocked_by_outdated_branch=ใใฎใใซใชใฏใจในใใฏๅคใใใใใญใใฏใใใฆใใพใใ
pulls.blocked_by_changed_protected_files_1=ใใฎใใซใชใฏใจในใใฏไฟ่ญทใใฆใใใใกใคใซใๅคๆดใใใใใใญใใฏใใใฆใใพใ๏ผ
pulls.blocked_by_changed_protected_files_n=ใใฎใใซใชใฏใจในใใฏไฟ่ญทใใฆใใใใกใคใซใๅคๆดใใใใใใญใใฏใใใฆใใพใ๏ผ
pulls.can_auto_merge_desc=ใใฎใใซใชใฏใจในใใฏ่ชๅ็ใซใใผใธใงใใพใใ
@@ -1854,17 +1898,17 @@ pulls.merge_commit_id=ใใผใธใณใใใID
pulls.require_signed_wont_sign=ใใฉใณใใงใฏ็ฝฒๅใใใใณใใใใๅฟ
้ ใงใใใใใฎใใผใธใงใฏ็ฝฒๅใใใใพใใ
pulls.invalid_merge_option=ใใฎใใซใชใฏใจในใใงใฏใๆๅฎใใใใผใธๆนๆณใฏไฝฟใใพใใใ
-pulls.merge_conflict=ใใผใธๅคฑๆ: ใใผใธไธญใซใณใณใใชใฏใใใใใพใใใ ใใณใ: ๅฅใฎในใใฉใใธใผใ่ฉฆใใฆใฟใฆใใ ใใ
+pulls.merge_conflict=ใใผใธๅคฑๆ: ใใผใธไธญใซใณใณใใชใฏใใใใใพใใใ ใใณใ: ๅฅใฎๆนๆณใ่ฉฆใใฆใฟใฆใใ ใใ
pulls.merge_conflict_summary=ใจใฉใผใกใใปใผใธ
-pulls.rebase_conflict=ใใผใธๅคฑๆ: ใณใใใ %[1]s ใฎใชใใผในไธญใซใณใณใใชใฏใใใใใพใใใ ใใณใ: ๅฅใฎในใใฉใใธใผใ่ฉฆใใฆใฟใฆใใ ใใ
+pulls.rebase_conflict=ใใผใธๅคฑๆ: ใณใใใ %[1]s ใฎใชใใผในไธญใซใณใณใใชใฏใใใใใพใใใ ใใณใ: ๅฅใฎๆนๆณใ่ฉฆใใฆใฟใฆใใ ใใ
pulls.rebase_conflict_summary=ใจใฉใผใกใใปใผใธ
-pulls.unrelated_histories=ใใผใธๅคฑๆ: ใใผใธHEADใจใใผในใซใฏๅ
ฑ้ใใๅฑฅๆญดใใใใพใใใ ใใณใ: ๅฅใฎในใใฉใใธใผใ่ฉฆใใฆใฟใฆใใ ใใ
-pulls.merge_out_of_date=ใใผใธๅคฑๆ: ใใผใธใฎ็ๆไธญใซใใผในใๆดๆฐใใใพใใใ ใใณใ: ใใไธๅบฆ่ฉฆใใฆใฟใฆใใ ใใ
-pulls.head_out_of_date=ใใผใธๅคฑๆ: ใใผใธใฎ็ๆไธญใซ head ใๆดๆฐใใใพใใใ ใใณใ: ใใไธๅบฆ่ฉฆใใฆใฟใฆใใ ใใ
+pulls.unrelated_histories=ใใผใธๅคฑๆ: ใใผใธHEADใจใใผในใซใฏๅ
ฑ้ใใๅฑฅๆญดใใใใพใใใ ใใณใ: ๅฅใฎๆนๆณใ่ฉฆใใฆใฟใฆใใ ใใ
+pulls.merge_out_of_date=ใใผใธๅคฑๆ: ใใผใธใฎ็ๆไธญใซใใผในใๆดๆฐใใใพใใใ ใใณใ: ใใไธๅบฆ่ฉฆใใฆใฟใฆใใ ใใใ
+pulls.head_out_of_date=ใใผใธๅคฑๆ: ใใผใธใฎ็ๆไธญใซ head ใๆดๆฐใใใพใใใ ใใณใ: ใใไธๅบฆ่ฉฆใใฆใฟใฆใใ ใใใ
pulls.has_merged=ๅคฑๆ: ใใซใชใฏใจในใใฏใใผใธใใใฆใใพใใใๅๅบฆใใผใธใใใใใฟใผใฒใใใใฉใณใใๅคๆดใใใใจใฏใงใใพใใใ
pulls.push_rejected=ใใผใธๅคฑๆ: ใใใทใฅใฏๆๅฆใใใพใใใ ใใฎใชใใธใใชใฎGitใใใฏใ่ฆ็ดใใฆใใ ใใใ
pulls.push_rejected_summary=ๆๅฆใกใใปใผใธๅ
จไฝ:
-pulls.push_rejected_no_message=ใใผใธๅคฑๆ: ใใใทใฅใฏๆๅฆใใใใชใขใผใใใใฎใกใใปใผใธใฏใใใพใใใ ใใฎใชใใธใใชใฎGitใใใฏใ่ฆ็ดใใฆใใ ใใ
+pulls.push_rejected_no_message=ใใผใธๅคฑๆ: ใใใทใฅใฏๆๅฆใใใใชใขใผใใใใฎใกใใปใผใธใฏใใใพใใใใใฎใชใใธใใชใฎGitใใใฏใ็ขบ่ชใใฆไธใใ
pulls.open_unmerged_pull_exists=`ๅใๆกไปถใฎใใซใชใฏใจในใ (#%d) ใๆชๅฆ็ใฎใใใๅใชใผใใณใฏใงใใพใใใ`
pulls.status_checking=ใใใคใใฎในใใผใฟในใใงใใฏใๅพ
ๆฉไธญใงใ
pulls.status_checks_success=ในใใผใฟในใใงใใฏใฏใในใฆๆๅใใพใใ
@@ -1883,7 +1927,7 @@ pulls.outdated_with_base_branch=ใใฎใใฉใณใใฏใใผในใใฉใณใใซๅฏพ
pulls.close=ใใซใชใฏใจในใใใฏใญใผใบ
pulls.closed_at=`ใใใซใชใฏใจในใใใฏใญใผใบ %[2]s `
pulls.reopened_at=`ใใใซใชใฏใจในใใๅใชใผใใณ %[2]s `
-pulls.cmd_instruction_hint=`ใณใใณใใฉใคใณใฎๆ้ ใ่กจ็คบใใพใใ`
+pulls.cmd_instruction_hint=ใณใใณใใฉใคใณใฎๆ้ ใ่กจ็คบ
pulls.cmd_instruction_checkout_title=ใใงใใฏใขใฆใ
pulls.cmd_instruction_checkout_desc=ใใญใธใงใฏใใชใใธใใชใใๆฐใใใใฉใณใใใใงใใฏใขใฆใใใๅคๆดๅ
ๅฎนใใในใใใพใใ
pulls.cmd_instruction_merge_title=ใใผใธ
@@ -1942,7 +1986,7 @@ milestones.filter_sort.least_issues=ใคใทใฅใผใฎๅฐใชใ้
signing.will_sign=ใใฎใณใใใใฏ้ต "%s" ใง็ฝฒๅใใใพใใ
signing.wont_sign.error=ใณใใใใฎ็ฝฒๅๅฏๅฆใ็ขบ่ชไธญใซใจใฉใผใ็บ็ใใพใใใ
-signing.wont_sign.nokey=ใใฎใณใใใใซ็ฝฒๅใใใใใฎ้ตใใใใพใใใ
+signing.wont_sign.nokey=ใใฎใคใณในใฟใณในใซใฏใใใฎใณใใใใซ็ฝฒๅใใใใใฎ้ตใใใใพใใใ
signing.wont_sign.never=ใณใใใใ็ฝฒๅใใใใใจใฏใใใพใใใ
signing.wont_sign.always=ใณใใใใฏๅธธใซ็ฝฒๅใใใพใใ
signing.wont_sign.pubkey=ใขใซใฆใณใใซๅ
ฌ้้ตใ็ป้ฒใใใฆใใชใใใใใณใใใใฏ็ฝฒๅใใใพใใใ
@@ -1954,7 +1998,7 @@ signing.wont_sign.commitssigned=้ข้ฃใใใณใใใใในใฆใ็ฝฒๅใใ
signing.wont_sign.approved=PRใๆชๆฟ่ชใฎใใใใใผใธใฏ็ฝฒๅใใใพใใใ
signing.wont_sign.not_signed_in=ใตใคใณใคใณใใฆใใพใใใ
-ext_wiki=ๅค้จWikiใธใฎใขใฏใปใน
+ext_wiki=ๅค้จWiki
ext_wiki.desc=ๅค้จWikiใธใฎใชใณใฏใ
wiki=Wiki
@@ -1972,8 +2016,8 @@ wiki.save_page=ใใผใธใไฟๅญ
wiki.last_commit_info=%s ใ %s ใซใใฎใใผใธใ็ทจ้
wiki.edit_page_button=็ทจ้
wiki.new_page_button=ๆฐ่ฆใใผใธ
-wiki.file_revision=ใใผใธใปใชใใธใงใณ
-wiki.wiki_page_revisions=Wikiใใผใธใฎใชใใธใงใณ
+wiki.file_revision=ใใผใธใฎๆน่จๅฑฅๆญด
+wiki.wiki_page_revisions=Wikiใใผใธใฎๆน่จๅฑฅๆญด
wiki.back_to_wiki=Wikiใใผใธใซๆปใ
wiki.delete_page_button=ใใผใธใๅ้ค
wiki.delete_page_notice_1=Wikiใใผใธ "%s" ใฎๅ้คใฏๅ
ใซๆปใใพใใใ ็ถ่กใใพใใ๏ผ
@@ -2027,7 +2071,7 @@ activity.unresolved_conv_label=ใชใผใใณ
activity.title.releases_1=%dไปถใฎใชใชใผใน
activity.title.releases_n=%dไปถใฎใชใชใผใน
activity.title.releases_published_by=%sใ%sใซใใฃใฆ็บ่กใใใพใใ
-activity.published_release_label=็บ่ก
+activity.published_release_label=ใชใชใผใน
activity.no_git_activity=ใใฎๆ้ใซใฏใณใใใใฎใขใฏใใฃใใใฃใใใใพใใใ
activity.git_stats_exclude_merges=ใใผใธใ้คใใจใ
activity.git_stats_author_1=%dไบบใฎไฝๆ่
@@ -2103,12 +2147,12 @@ settings.sync_mirror=ไปใใๅๆ
settings.pull_mirror_sync_in_progress=็พๅจใใชใขใผใ %s ใใๅคๆดใใใซใใฆใใพใใ
settings.push_mirror_sync_in_progress=็พๅจใใชใขใผใ %s ใธๅคๆดใใใใทใฅใใฆใใพใใ
settings.site=Webใตใคใ
-settings.update_settings=่จญๅฎใๆดๆฐ
+settings.update_settings=่จญๅฎใไฟๅญ
settings.update_mirror_settings=ใใฉใผใชใณใฐ่จญๅฎใๆดๆฐ
settings.branches.switch_default_branch=ใใใฉใซใใใฉใณใใๅใๆฟใ
settings.branches.update_default_branch=ใใใฉใซใใใฉใณใใๆดๆฐ
settings.branches.add_new_rule=ๆฐใใใซใผใซใ่ฟฝๅ
-settings.advanced_settings=ๆกๅผต่จญๅฎ
+settings.advanced_settings=่ฉณ็ดฐ่จญๅฎ
settings.wiki_desc=Wikiใๆๅนใซใใ
settings.use_internal_wiki=ใใซใใคใณใฎWikiใไฝฟ็จใใ
settings.use_external_wiki=ๅค้จใฎWikiใไฝฟ็จใใ
@@ -2139,14 +2183,14 @@ settings.pulls.allow_rebase_update=ใชใใผในใงใใซใชใฏใจในใใฎใใฉ
settings.pulls.default_delete_branch_after_merge=ใใใฉใซใใงใใซใชใฏใจในใใฎใใฉใณใใใใผใธๅพใซๅ้คใใ
settings.pulls.default_allow_edits_from_maintainers=ใใใฉใซใใงใกใณใใใใใฎ็ทจ้ใ่จฑๅฏใใ
settings.releases_desc=ใชใชใผในใๆๅนใซใใ
-settings.packages_desc=ใชใใธใใชใใใฑใผใธใฌใธในใใชใๆๅนใซใใ
-settings.projects_desc=ใชใใธใใชใใญใธใงใฏใใๆๅนใซใใ
-settings.actions_desc=Actionsใๆๅนใซใใ
-settings.admin_settings=็ฎก็่
็จ่จญๅฎ
+settings.packages_desc=ใใใฑใผใธใฌใธในใใชใๆๅนใซใใ
+settings.projects_desc=ใใญใธใงใฏใใๆๅนใซใใ
+settings.actions_desc=Forgejo Actionsใไฝฟ็จใใฆ็ตฑๅCI/CDใใคใใฉใคใณใๆๅนๅใใ
+settings.admin_settings=็ฎก็่
่จญๅฎ
settings.admin_enable_health_check=ใชใใธใใชใฎใใซในใใงใใฏใๆๅนใซใใ (git fsck)
settings.admin_code_indexer=ใณใผใใคใณใใฏใต
settings.admin_stats_indexer=ใณใผใ็ตฑ่จใคใณใใฏใต
-settings.admin_indexer_commit_sha=ๆๆฐใคใณใใใฏในๆธใฟSHA
+settings.admin_indexer_commit_sha=ๆๆฐใคใณใใใฏในๆธใฟใณใใใ
settings.admin_indexer_unindexed=ๆชใคใณใใใฏใน
settings.reindex_button=ใคใณใใใฏในๅไฝๆใญใฅใผใซ่ฟฝๅ
settings.reindex_requested=ๅใคใณใใใฏในใ่ฆๆฑใใพใใ
@@ -2259,7 +2303,7 @@ settings.slack_icon_url=ใขใคใณใณใฎURL
settings.slack_color=่ฒ
settings.discord_username=ใฆใผใถใผๅ
settings.discord_icon_url=ใขใคใณใณใฎURL
-settings.event_desc=ใใชใฌใผ:
+settings.event_desc=้็ฅใใชใฌใผ:
settings.event_push_only=ใใใทใฅใฎใคใใณใ
settings.event_send_everything=ใในใฆใฎใคใใณใ
settings.event_choose=ใคใใณใใๆๅฎโฆ
@@ -2279,39 +2323,39 @@ settings.event_push_desc=Gitใใชใใธใใชใซใใใทใฅใ่กใฃใใจใ
settings.event_repository=ใชใใธใใช
settings.event_repository_desc=ใชใใธใใชใไฝๆใปๅ้คใใใใจใใ
settings.event_header_issue=ใคใทใฅใผใฎใคใใณใ
-settings.event_issues=ใคใทใฅใผ
+settings.event_issues=ๅคๆด
settings.event_issues_desc=ใคใทใฅใผใใชใผใใณใปใฏใญใผใบใปๅใชใผใใณใป็ทจ้ใใใใจใใ
-settings.event_issue_assign=ใคใทใฅใผใฎใขใตใคใณ
+settings.event_issue_assign=ใขใตใคใณ
settings.event_issue_assign_desc=ใคใทใฅใผใฎๆ
ๅฝ่
ใๅฒใๅฝใฆใใใใจใใ่งฃ้คใใใใจใใ
-settings.event_issue_label=ใคใทใฅใผใฎใฉใใซ
-settings.event_issue_label_desc=ใคใทใฅใผใฎใฉใใซใๆดๆฐใปใฏใชใขใใใใจใใ
-settings.event_issue_milestone=ใคใทใฅใผใฎใใคใซในใใผใณ
-settings.event_issue_milestone_desc=ใคใทใฅใผใฎใใคใซในใใผใณใ่จญๅฎใป่งฃ้คใใใใจใใ
-settings.event_issue_comment=ใคใทใฅใผใธใฎใณใกใณใ
+settings.event_issue_label=ใฉใใซ
+settings.event_issue_label_desc=ใคใทใฅใผใฎใฉใใซใ่ฟฝๅ ใปๅ้คใใใใจใใ
+settings.event_issue_milestone=ใใคใซในใใผใณ
+settings.event_issue_milestone_desc=ใใคใซในใใผใณใ่ฟฝๅ ใปๅ้คใปๅคๆดใใใใจใใ
+settings.event_issue_comment=ใณใกใณใ
settings.event_issue_comment_desc=ใคใทใฅใผใธใฎใณใกใณใใไฝๆใป็ทจ้ใปๅ้คใใใใจใใ
settings.event_header_pull_request=ใใซใชใฏใจในใใฎใคใใณใ
-settings.event_pull_request=ใใซใชใฏใจในใ
+settings.event_pull_request=ๅคๆด
settings.event_pull_request_desc=ใใซใชใฏใจในใใใชใผใใณใปใฏใญใผใบใปๅใชใผใใณใป็ทจ้ใใใใจใใ
-settings.event_pull_request_assign=ใใซใชใฏใจในใใฎใขใตใคใณ
+settings.event_pull_request_assign=ใขใตใคใณ
settings.event_pull_request_assign_desc=ใใซใชใฏใจในใใฎๆ
ๅฝ่
ใๅฒใๅฝใฆใป่งฃ้คใใใใจใใ
-settings.event_pull_request_label=ใใซใชใฏใจในใใฎใฉใใซ
-settings.event_pull_request_label_desc=ใใซใชใฏใจในใใฎใฉใใซใๆดๆฐใปใฏใชใขใใใใจใใ
-settings.event_pull_request_milestone=ใใซใชใฏใจในใใฎใใคใซในใใผใณ
-settings.event_pull_request_milestone_desc=ใใซใชใฏใจในใใฎใใคใซในใใผใณใ่จญๅฎใป่งฃ้คใใใใจใใ
-settings.event_pull_request_comment=ใใซใชใฏใจในใใธใฎใณใกใณใ
+settings.event_pull_request_label=ใฉใใซ
+settings.event_pull_request_label_desc=ใใซใชใฏใจในใใฎใฉใใซใ่ฟฝๅ ใปๅ้คใใใใจใใ
+settings.event_pull_request_milestone=ใใคใซในใใผใณ
+settings.event_pull_request_milestone_desc=ใใคใซในใใผใณใ่ฟฝๅ ใปๅ้คใปๅคๆดใใใใจใใ
+settings.event_pull_request_comment=ใณใกใณใ
settings.event_pull_request_comment_desc=ใใซใชใฏใจในใใธใฎใณใกใณใใไฝๆใป็ทจ้ใปๅ้คใใใใจใใ
-settings.event_pull_request_review=ใใซใชใฏใจในใใฎใฌใใฅใผ
+settings.event_pull_request_review=ใฌใใฅใผ
settings.event_pull_request_review_desc=ใใซใชใฏใจในใใฎๆฟ่ชใปๆๅฆใใพใใฏใฌใใฅใผใณใกใณใใไปใใใจใใ
-settings.event_pull_request_sync=ใใซใชใฏใจในใใฎๅๆ
-settings.event_pull_request_sync_desc=ใใซใชใฏใจในใใๅๆใใใใจใใ
-settings.event_pull_request_review_request=ใใซใชใฏใจในใใฎใฌใใฅใผไพ้ ผ
+settings.event_pull_request_sync=ๅๆ
+settings.event_pull_request_sync_desc=ใฟใผใฒใใใใฉใณใใ่ชๅใงๆดๆฐใใใใจใใ
+settings.event_pull_request_review_request=ใฌใใฅใผไพ้ ผ
settings.event_pull_request_review_request_desc=ใใซใชใฏใจในใใฎใฌใใฅใผใไพ้ ผใใใใจใใใพใใฏไพ้ ผใๅ้คใใใใจใใ
settings.event_pull_request_approvals=ใใซใชใฏใจในใใฎๆฟ่ช
settings.event_pull_request_merge=ใใซใชใฏใจในใใฎใใผใธ
settings.event_package=ใใใฑใผใธ
settings.event_package_desc=ใชใใธใใชใซใใใฑใผใธใไฝๆใพใใฏๅ้คใใใใจใใ
settings.branch_filter=ใใฉใณใ ใใฃใซใฟใผ
-settings.branch_filter_desc=ใใใทใฅใใใฉใณใไฝๆใใใฉใณใๅ้คใฎใคใใณใใ้็ฅใใใใฉใณใใใglobใใฟใผใณใงๆๅฎใใใใฏใคใใชในใใงใใ ็ฉบใ*
ใฎใจใใฏใใในใฆใฎใใฉใณใใฎใคใใณใใ้็ฅใใพใใ ๆๆณใซใคใใฆใฏ github.com/gobwas/glob ใๅ็
งใใฆใใ ใใใ ไพ: master
ใ {master,release*}
+settings.branch_filter_desc=ใใใทใฅใใใฉใณใไฝๆใใใฉใณใๅ้คใฎใคใใณใใ้็ฅใใใใฉใณใใใglobใใฟใผใณใงๆๅฎใใใใฏใคใใชในใใงใใ ็ฉบใ*
ใฎใจใใฏใใในใฆใฎใใฉใณใใฎใคใใณใใ้็ฅใใพใใ ๆๆณใซใคใใฆใฏ %[2]s ใๅ็
งใใฆใใ ใใใ ไพ: master
ใ {master,release*}
settings.authorization_header=Authorizationใใใใผ
settings.authorization_header_desc=ๅ
ฅๅใใๅ ดๅใใชใฏใจในใใซAuthorizationใใใใผใจใใฆไปๅ ใใพใใ ไพ: %s
settings.active=ๆๅน
@@ -2392,23 +2436,23 @@ settings.protect_check_status_contexts_list=ใใฎ1้ฑ้ใซใใใฎใชใใธ
settings.protect_status_check_matched=ใใใ
settings.protect_invalid_status_check_pattern=`ไธๆญฃใชในใใผใฟในใใงใใฏใใฟใผใณ: "%s"`
settings.protect_no_valid_status_check_patterns=ๆๅนใชในใใผใฟในใใงใใฏใใฟใผใณใใใใพใใใ
-settings.protect_required_approvals=ๅฟ
่ฆใชๆฟ่ชๆฐ:
+settings.protect_required_approvals=ๅฟ
่ฆใชๆฟ่ชๆฐ
settings.protect_required_approvals_desc=่ฏๅฎ็ใชใฌใใฅใผใฎๆฐใๆบใใใใใซใชใฏใจในใใใใใผใธใงใใชใใใใซใใพใใ
settings.protect_approvals_whitelist_enabled=ใใฏใคใใชในใใซ็ป้ฒใใใฆใผใถใผใใใผใ ใซๆฟ่ชใๅถ้
settings.protect_approvals_whitelist_enabled_desc=ใใฏใคใใชในใใซ็ป้ฒใใใฆใผใถใผใใใผใ ใซใใใฌใใฅใผใฎใฟใใๅฟ
่ฆใชๆฟ่ชใจใฟใชใใพใใ ๆฟ่ชใฎใใฏใคใใชในใใ็กใๅ ดๅใฏใๆธใ่พผใฟๆจฉ้ใใใไบบใซใใใฌใใฅใผใๅฟ
่ฆใชๆฟ่ชใจใฟใชใใพใใ
-settings.protect_approvals_whitelist_users=ใใฏใคใใชในใใซๅซใใใฌใใฅใผใข:
-settings.protect_approvals_whitelist_teams=ใใฏใคใใชในใใซๅซใใใฌใใฅใผใใผใ :
+settings.protect_approvals_whitelist_users=ใใฏใคใใชในใใซๅซใใใฌใใฅใผใข
+settings.protect_approvals_whitelist_teams=ใใฏใคใใชในใใซๅซใใใฌใใฅใผใใผใ
settings.dismiss_stale_approvals=ๅคใใชใฃใๆฟ่ชใๅใๆถใ
settings.dismiss_stale_approvals_desc=ใใซใชใฏใจในใใฎๅ
ๅฎนใๅคใใๆฐใใชใณใใใใใใฉใณใใซใใใทใฅใใใๅ ดๅใไปฅๅใฎๆฟ่ชใๅใๆถใใพใใ
settings.require_signed_commits=ใณใใใ็ฝฒๅๅฟ
้
settings.require_signed_commits_desc=็ฝฒๅใใใฆใใชใๅ ดๅใใพใใฏ็ฝฒๅใๆค่จผใงใใชใใฃใๅ ดๅใฏใใใฎใใฉใณใใธใฎใใใทใฅใๆๅฆใใพใใ
settings.protect_branch_name_pattern=ไฟ่ญทใใฉใณใๅใฎใใฟใผใณ
-settings.protect_branch_name_pattern_desc=ไฟ่ญทใใฉใณใๅใฎใใฟใผใณใๆธใๆนใซใคใใฆใฏ ใใญใฅใกใณใ ใๅ็
งใใฆใใ ใใใไพ: main, release/**
+settings.protect_branch_name_pattern_desc=ไฟ่ญทใใฉใณใๅใฎใใฟใผใณใๆธใๆนใซใคใใฆใฏ ใใญใฅใกใณใ ใๅ็
งใใฆใใ ใใใไพ: main, release/**
settings.protect_patterns=ใใฟใผใณ
settings.protect_protected_file_patterns=ไฟ่ญทใใใใใกใคใซใฎใใฟใผใณ (ใปใใณใญใณ';'ใงๅบๅใ):
-settings.protect_protected_file_patterns_desc=ไฟ่ญทใใใใใกใคใซใฏใใใฎใใฉใณใใซใใกใคใซใ่ฟฝๅ ใป็ทจ้ใปๅ้คใใๆจฉ้ใๆใคใฆใผใถใผใงใใฃใฆใใ็ดๆฅๅคๆดใใใใจใใงใใชใใชใใพใใ ใปใใณใญใณ(';')ใงๅบๅใฃใฆ่คๆฐใฎใใฟใผใณใๆๅฎใงใใพใใ ใใฟใผใณใฎๆๆณใซใคใใฆใฏ github.com/gobwas/glob ใๅ็
งใใฆใใ ใใใ ไพ: .drone.yml
, /docs/**/*.txt
+settings.protect_protected_file_patterns_desc=ไฟ่ญทใใใใใกใคใซใฏใใใฎใใฉใณใใซใใกใคใซใ่ฟฝๅ ใป็ทจ้ใปๅ้คใใๆจฉ้ใๆใคใฆใผใถใผใงใใฃใฆใใ็ดๆฅๅคๆดใใใใจใใงใใชใใชใใพใใ ใปใใณใญใณ(';')ใงๅบๅใฃใฆ่คๆฐใฎใใฟใผใณใๆๅฎใงใใพใใ ใใฟใผใณใฎๆๆณใซใคใใฆใฏ %[2]s ใๅ็
งใใฆใใ ใใใ ไพ: .drone.yml
, /docs/**/*.txt
settings.protect_unprotected_file_patterns=ไฟ่ญทใใชใใใกใคใซใฎใใฟใผใณ (ใปใใณใญใณ';'ใงๅบๅใ):
-settings.protect_unprotected_file_patterns_desc=ไฟ่ญทใใชใใใกใคใซใฏใใฆใผใถใผใซๆธใ่พผใฟๆจฉ้ใใใใฐใใใทใฅๅถ้ใใใคใในใใฆ็ดๆฅๅคๆดใงใใพใใ ใปใใณใญใณ(';')ใงๅบๅใฃใฆ่คๆฐใฎใใฟใผใณใๆๅฎใงใใพใใ ใใฟใผใณใฎๆๆณใซใคใใฆใฏ github.com/gobwas/glob ใๅ็
งใใฆใใ ใใใ ไพ: .drone.yml
, /docs/**/*.txt
+settings.protect_unprotected_file_patterns_desc=ไฟ่ญทใใชใใใกใคใซใฏใใฆใผใถใผใซๆธใ่พผใฟๆจฉ้ใใใใฐใใใทใฅๅถ้ใใใคใในใใฆ็ดๆฅๅคๆดใงใใพใใ ใปใใณใญใณ(';')ใงๅบๅใฃใฆ่คๆฐใฎใใฟใผใณใๆๅฎใงใใพใใ ใใฟใผใณใฎๆๆณใซใคใใฆใฏ %[2]s ใๅ็
งใใฆใใ ใใใ ไพ: .drone.yml
, /docs/**/*.txt
settings.add_protected_branch=ไฟ่ญทใๆๅนใซใใ
settings.delete_protected_branch=ไฟ่ญทใ็กๅนใซใใ
settings.update_protect_branch_success=ใซใผใซ "%s" ใซๅฏพใใใใฉใณใไฟ่ญทใๆดๆฐใใพใใใ
@@ -2440,7 +2484,7 @@ settings.tags.protection.allowed.teams=่จฑๅฏใใใใผใ
settings.tags.protection.allowed.noone=ใชใ
settings.tags.protection.create=ใฟใฐใไฟ่ญท
settings.tags.protection.none=ใฟใฐใฏไฟ่ญทใใใฆใใพใใใ
-settings.tags.protection.pattern.description=ใฒใจใคใฎใฟใฐๅใใ่คๆฐใฎใฟใฐใซใใใใใglobใใฟใผใณใพใใฏๆญฃ่ฆ่กจ็พใไฝฟ็จใงใใพใใ ่ฉณใใใฏใฟใฐใฎไฟ่ญทใฌใคใ ใใ่ฆงใใ ใใใ
+settings.tags.protection.pattern.description=ใฒใจใคใฎใฟใฐๅใใ่คๆฐใฎใฟใฐใซใใใใใglobใใฟใผใณใพใใฏๆญฃ่ฆ่กจ็พใไฝฟ็จใงใใพใใ ่ฉณใใใฏใฟใฐใฎไฟ่ญทใฌใคใ ใใ่ฆงใใ ใใใ
settings.bot_token=Botใใผใฏใณ
settings.chat_id=ใใฃใใID
settings.thread_id=ในใฌใใID
@@ -2574,10 +2618,10 @@ release.tag_helper_existing=ๅญๅจใใใฟใฐใงใใ
release.title=ใชใชใผใน ใฟใคใใซ
release.title_empty=ใฟใคใใซใฏ็ฉบใซใงใใพใใใ
release.message=ใใฎใชใชใผในใฎ่ชฌๆ
-release.prerelease_desc=ใใฌใชใชใผใน
+release.prerelease_desc=ใใฌใชใชใผในใจใใฆใใผใฏ
release.prerelease_helper=ใใฎใชใชใผในใๆฌ็ชไฝฟ็จใซ้ฉใใชใใใจใ็คบใใพใใ
release.cancel=ใญใฃใณใปใซ
-release.publish=ใชใชใผในใ็บ่ก
+release.publish=ใชใชใผในใๅ
ฌ้
release.save_draft=ไธๆธใใไฟๅญ
release.edit_release=ใชใชใผในใๆดๆฐ
release.delete_release=ใชใชใผในใๅ้ค
@@ -2594,7 +2638,7 @@ release.tag_already_exist=ใใฎใฟใฐๅใฏๆขใซๅญๅจใใพใใ
release.downloads=ใใฆใณใญใผใ
release.download_count=ใใฆใณใญใผใๆฐ: %s
release.add_tag_msg=ใชใชใผในใฎใฟใคใใซใจๅ
ๅฎนใใฟใฐใฎใกใใปใผใธใซใใ
-release.add_tag=ใฟใฐใฎใฟไฝๆ
+release.add_tag=ใฟใฐใไฝๆ
release.releases_for=%s ใฎใชใชใผใน
release.tags_for=%s ใฎใฟใฐ
@@ -2607,7 +2651,7 @@ branch.delete_desc=ใใฉใณใใฎๅ้คใฏๆไน
็ใงใใ ๅฎ้ใซๅ้คใ
branch.deletion_success=ใใฉใณใ "%s" ใๅ้คใใพใใใ
branch.deletion_failed=ใใฉใณใ "%s" ใฎๅ้คใซๅคฑๆใใพใใใ
branch.delete_branch_has_new_commits=ใใผใธๅพใซๆฐใใใณใใใใ่ฟฝๅ ใใใฆใใใใใใใฉใณใ "%s" ใๅ้คใงใใพใใใ
-branch.create_branch=ใใฉใณใ %s ใไฝๆ
+branch.create_branch=ใใฉใณใ %s ใไฝๆ
branch.create_from=`"%s" ใใ`
branch.create_success=ใใฉใณใ "%s" ใไฝๆใใพใใใ
branch.branch_already_exists=ใใฉใณใ "%s" ใฏใใใฎใชใใธใใชใซๆขใซๅญๅจใใพใใ
@@ -2634,7 +2678,7 @@ branch.new_branch=ๆฐใใใใฉใณใใฎไฝๆ
branch.new_branch_from=`"%s" ใใๆฐใใใใฉใณใใไฝๆ`
branch.renamed=ใใฉใณใ %s ใฏ %s ใซใชใใผใ ใใใพใใใ
-tag.create_tag=ใฟใฐ %s ใไฝๆ
+tag.create_tag=ใฟใฐ %s ใไฝๆ
tag.create_tag_operation=ใฟใฐใฎไฝๆ
tag.confirm_create_tag=ใฟใฐใไฝๆ
tag.create_tag_from=`"%s" ใใๆฐใใใฟใฐใไฝๆ`
@@ -2654,7 +2698,6 @@ error.csv.unexpected=ใใฎใใกใคใซใฏ %d ่ก็ฎใฎ %d ๆๅญ็ฎใซไบๆใ
error.csv.invalid_field_count=ใใฎใใกใคใซใฏ %d ่ก็ฎใฎใใฃใผใซใใฎๆฐใๆญฃใใใชใใใ่กจ็คบใงใใพใใใ
admin.enabled_flags = ใใฎใชใใธใใชใงๆๅนใซใชใฃใฆใใใใฉใฐ๏ผ
clone_in_vscodium = VSCodiumใงcloneใใ
-desc.sha256 = SHA256
wiki.cancel = ใญใฃใณใปใซ
activity.navbar.contributors = ่ฒข็ฎ่
contributors.contribution_type.filter_label = ่ฒข็ฎใฎ็จฎ้ก:
@@ -2668,7 +2711,7 @@ issues.blocked_by_user = ใใชใใฏใใฎใชใใธใใชใฎๆๆ่
ใใใ
pulls.nothing_to_compare_have_tag = ้ธๆใใใใใฉใณใใพใใฏใฟใฐใฏๅไธใงใใ
pulls.blocked_by_user = ใใชใใฏใใฎใชใใธใใชใฎๆๆ่
ใใใใญใใฏใใใฆใใใใใใใซใชใฏใจในใใไฝๆใงใใพใใใ
rss.must_be_on_branch = RSSใใฃใผใใ่ฆใใใใซใฏใใใฉใณใใ้ฒ่ฆงใใๅฟ
่ฆใใใใพใใ
-migrate.forgejo.description = codeberge.orgใพใใฏไปใฎใคใณในใฟใณในใใใใผใฟใ็งป่กใใใ
+migrate.forgejo.description = codeberg.orgใพใใฏไปใฎใคใณในใฟใณในใใใใผใฟใ็งป่กใใใ
commits.browse_further = ใใฃใจ่ฆใ
issues.comment.blocked_by_user = ใใชใใฏใใฎใชใใธใใชใฎๆๆ่
ใใIssueใฎๆ็จฟ่
ใใใใญใใฏใใใฆใใใใใใใฎIssueใซใณใกใณใใงใใพใใใ
pulls.reopen_failed.head_branch = ใใฉใณใใใใๅญๅจใใชใใใใใใฎใใซใชใฏใจในใใฏreopenใงใใพใใใ
@@ -2689,15 +2732,15 @@ commits.renamed_from = %sใใๅๅใๅคๆด
pulls.made_using_agit = Agit
pulls.agit_explanation = AgitใซใใใฏใผใฏใใญใผใไฝๆใใพใใAgitใงใฏใ่ฒข็ฎ่
ใฏๅคๆดใforkใใใใใฉใณใใไฝใใฎใงใฏใชใใ"git push"ใใฆๆๆกใใพใใ
contributors.contribution_type.deletions = ๅ้ค
-settings.units.add_more = ใใใซ...
-settings.wiki_globally_editable = ่ชฐใซใงใWikiใฎ็ทจ้ใ่จฑใ
+settings.units.add_more = ใใใซๆๅนใซใใ
+settings.wiki_globally_editable = ่ชฐใงใWikiใ็ทจ้ใงใใๆงใซใใ
settings.confirmation_string = ็ขบ่ช
settings.wiki_rename_branch_main_notices_1 = ใใฎๆไฝใฏ ๅใๆถใใงใใพใใ ใ
stars = ในใฟใผ
n_tag_few = %s ใฎใฟใฐ
settings.graphql_url = GraphQL URL
n_branch_one = %s ใฎใใฉใณใ
-settings.units.units = ใชใใธใใชๆฉ่ฝ
+settings.units.units = ๆฉ่ฝ่จญๅฎ
settings.wiki_rename_branch_main_notices_2 = ใใใซใใใ%s ใฎใชใใธใใช wiki ใฎๅ
้จใใฉใณใใฎๅๅใๆฐธไน
ใซๅคๆดใใใพใใๆขๅญใฎใใงใใฏใขใฆใใๆดๆฐใใๅฟ
่ฆใใใใพใใ
settings.sourcehut_builds.access_token_helper = JOBS:RW ๆจฉ้ใๆใคใขใฏใปใน ใใผใฏใณใmeta.sr.ht ใง builds.sr.ht ใใผใฏใณ ใพใใฏ ใทใผใฏใฌใใ ใขใฏใปในใๆใค builds.sr.ht ใใผใฏใณ ใ็ๆใใพใใ
settings.enforce_on_admins = ใชใใธใใช็ฎก็่
ใซใใฎใซใผใซใ้ฉ็จใใ
@@ -2737,7 +2780,7 @@ issues.archived_label_description = (ใขใผใซใคใๆธ) %s
settings.web_hook_name_sourcehut_builds = SourceHut Builds
settings.matrix.room_id_helper = ใซใผใ IDใฏใElement web clientใฎRoom Settings > Advanced > Internal room IDใใๅๅพใงใใพใใไพ๏ผ%sใ
pulls.merged_title_desc_one = %[4]s ใฎ %[2]s
ใใ %[1]d ไปถใฎใณใใใใ %[3]s
ใธใใผใธใใ
-pulls.title_desc_one = %[3]s
ใใ %[1]d ไปถใฎใณใใใใ %[2]s
ใธใใผใธใใใ
+pulls.title_desc_one = %[2]s
ใใ %[1]d ไปถใฎใณใใใใ %[3]s
ใธใใผใธใใใ
pulls.ready_for_review = ใฌใใฅใผใฎๆบๅใใงใใฆใใพใใ๏ผ
settings.transfer.button = ๆๆๆจฉใ็งป้ใใ
settings.transfer.modal.title = ๆๆๆจฉใ็งป้
@@ -2747,6 +2790,43 @@ form.string_too_long = ๆๅฎใใใๆๅญๅใฏ %d ๆๅญใใ้ทใใงใ
project = ใใญใธใงใฏใ
subscribe.issue.guest.tooltip = ใใฎใคใทใฅใผใ่ณผ่ชญใใใซใฏใตใคใณใคใณใใฆใใ ใใใ
subscribe.pull.guest.tooltip = ใใฎใใซใชใฏใจในใใ่ณผ่ชญใใใซใฏใตใคใณใคใณใใฆใใ ใใใ
+issues.author.tooltip.pr = ใใฎใฆใผใถใผใฏใใฎใใซใชใฏใจในใใฎไฝๆ่
ใงใใ
+issues.author.tooltip.issue = ใใฎใฆใผใถใผใฏใใฎๅ้กใฎไฝๆ่
ใงใใ
+mirror_public_key = ๅ
ฌ้SSHใญใผ
+mirror_use_ssh.text = SSH่ช่จผใไฝฟ็จใใ
+mirror_use_ssh.helper = ใใฎใชใใทใงใณใ้ธๆใใใจใForgejo ใฏ SSH ็ต็ฑใฎ Git ใงใชใใธใใชใใใฉใผใชใณใฐใใใญใผใใขใไฝๆใใพใใ็ๆใใใๅ
ฌ้ใญใผใๅฎๅ
ใชใใธใใชใซใใใทใฅใงใใใใใซๆฟ่ชใใใฆใใใใจใ็ขบ่ชใใๅฟ
่ฆใใใใพใใใใฎใชใใทใงใณใ้ธๆใใๅ ดๅใใในใฏใผใใใผในใฎ่ช่จผใฏไฝฟ็จใงใใพใใใ
+comments.edit.already_changed = ใณใกใณใใฎๅคๆดใไฟๅญใงใใพใใใใณใณใใณใใฏๆขใซๅฅใฎใฆใผใถใผใซใใฃใฆๅคๆดใใใฆใใใใใงใใๅคๆดใไธๆธใใใใชใใใใซใใใผใธใๆดๆฐใใฆๅๅบฆ็ทจ้ใใฆใใ ใใ
+no_eol.tooltip = ใใฎใใกใคใซใซใฏๆซๅฐพใฎ่กๆซๆๅญใๅซใพใใฆใใพใใใ
+issues.edit.already_changed = ใคใทใฅใผใฎๅคๆดใไฟๅญใงใใพใใใใณใณใใณใใฏๆขใซๅฅใฎใฆใผใถใผใซใใฃใฆๅคๆดใใใฆใใใใใงใใๅคๆดใไธๆธใใใใชใใใใซใใใผใธใๆดๆฐใใฆๅๅบฆ็ทจ้ใใฆใใ ใใ
+no_eol.text = EOLใชใ
+pulls.edit.already_changed = ใใซใชใฏใจในใใฎๅคๆดใไฟๅญใงใใพใใใใณใณใใณใใฏๆขใซๅฅใฎใฆใผใถใผใซใใฃใฆๅคๆดใใใฆใใใใใงใใๅคๆดใไธๆธใใใใชใใใใซใใใผใธใๆดๆฐใใฆๅๅบฆ็ทจ้ใใฆใใ ใใ
+pulls.cmd_instruction_merge_warning = ่ญฆๅ: ใใฎใชใใธใใชใงใฏใๆๅใใผใธใฎ่ชๅๆคๅบใ่จญๅฎใๆๅนใซใชใฃใฆใใพใใใๅพใงใใฎใใซ ใชใฏใจในใใๆๅใงใใผใธๆธใฟใจใใฆใใผใฏใใๅฟ
่ฆใใใใพใใ
+n_release_one = %s ใชใชใผใน
+n_release_few = %s ใชใชใผใน
+milestones.filter_sort.name = ๅๅ
+mirror_use_ssh.not_available = SSH่ช่จผใฏๅฉ็จใงใใพใใใ
+mirror_denied_combination = ๅ
ฌ้้ตใจใในใฏใผใใใผในใฎ่ช่จผใ็ตใฟๅใใใฆไฝฟ็จใใใใจใฏใงใใพใใใ
+activity.navbar.pulse = ๆดปๅ็ถๆณ
+activity.published_prerelease_label = ใใฌใชใชใผใน
+activity.published_tag_label = ใฟใฐ
+settings.transfer_quota_exceeded = ๆฐใใๆๆ่
(%s) ใฏๅฒใๅฝใฆ้ใ่ถ
ใใฆใใพใใใชใใธใใชใฏ่ปข้ใใใฆใใพใใใ
+settings.pull_mirror_sync_quota_exceeded = ๅฒใๅฝใฆ้ใ่ถ
้ใใใใใๅคๆดใฏใใซใใใพใใใ
+activity.commit = ใณใใใใขใฏใใฃใใใฃ
+settings.federation_settings = ใใงใใฌใผใทใงใณ่จญๅฎ
+settings.federation_not_enabled = ใคใณในใฟใณในใงใใงใใฌใผใทใงใณใๆๅนใซใชใฃใฆใใพใใใ
+settings.federation_apapiurl = ใใฎใชใใธใใชใฎใใงใใฌใผใทใงใณ URLใใใใใณใใผใใฆใใใฉใญใผ ใชใใธใใชใฎ URL ใจใใฆๅฅใฎใชใใธใใชใฎใใงใใฌใผใทใงใณ่จญๅฎใซ่ฒผใไปใใพใใ
+settings.federation_following_repos = ใใฉใญใผใใฆใใใชใใธใใชใฎ URLใ็ฉบ็ฝใชใใง";"ใงๅบๅใใใพใใ
+settings.mirror_settings.push_mirror.copy_public_key = ๅ
ฌ้้ตใใณใใผ
+release.invalid_external_url = ็กๅนใชๅค้จURL: "%s"
+release.type_attachment = ๆทปไปใใกใคใซ
+release.asset_external_url = ๅค้จURL
+release.type_external_asset = ๅค้จใขใปใใ
+release.asset_name = ใขใปใใๅ
+release.add_external_asset = ๅค้จใขใปใใใ่ฟฝๅ
+issues.all_title = ๅ
จใฆ
+settings.protect_new_rule = ๆฐใใใใฉใณใไฟ่ญทใซใผใซใไฝๆใใ
+settings.discord_icon_url.exceeds_max_length = ใขใคใณใณใฎURLใฏ 2048 ๆๅญไปฅไธใซใใๅฟ
่ฆใใใใพใ
+issues.new.assign_to_me = ่ชๅใซๅฒใๅฝใฆ
[graphs]
component_loading = %s ใฎ่ชญใฟ่พผใฟไธญ...
@@ -2831,18 +2911,18 @@ members.invite_now=ไปใใๆๅพ
teams.join=ๅๅ
teams.leave=่ฑ้
-teams.leave.detail=%s ใใ่ฑ้ใใพใใ๏ผ
+teams.leave.detail=ๆฌๅฝใซ %s ใใ่ฑ้ใใพใใ๏ผ
teams.can_create_org_repo=ใชใใธใใชใไฝๆ
teams.can_create_org_repo_helper=ใกใณใใผใฏ็ต็นใฎใชใใธใใชใๆฐใใซไฝๆใงใใพใใไฝๆ่
ใซใฏๆฐใใใชใใธใใชใฎ็ฎก็่
ๆจฉ้ใไธใใใใพใใ
teams.none_access=ใขใฏใปในใชใ
-teams.none_access_helper=ใกใณใใฏใใใฎใฆใใใใง่กจ็คบใไปใฎๆไฝใ่กใใใจใฏใงใใพใใใ
-teams.general_access=ไธ่ฌ็ใชใขใฏใปใน
+teams.none_access_helper=ใใขใฏใปในใชใใใชใใทใงใณใฏใใฉใคใใผใใชใใธใใชใซใฎใฟๅฝฑ้ฟใใพใใ
+teams.general_access=ใซในใฟใ ๆจฉ้
teams.general_access_helper=ใกใณใใผใฎๆจฉ้ใฏไธ่จใฎๆจฉ้ใใผใใซใงๆฑบๅฎใใใพใใ
teams.read_access=่ชญใฟๅใ
teams.read_access_helper=ใกใณใใผใฏใใผใ ใชใใธใใชใฎ้ฒ่ฆงใจใฏใญใผใณใๅฏ่ฝใงใใ
teams.write_access=ๆธใ่พผใฟ
teams.write_access_helper=ใกใณใใผใฏใใผใ ใชใใธใใชใฎ่ชญใฟๅใใจใใใทใฅใๅฏ่ฝใงใใ
-teams.admin_access=็ฎก็่
ใขใฏใปในๆจฉ
+teams.admin_access=็ฎก็่
ๆจฉ้
teams.admin_access_helper=ใกใณใใผใฏใใใผใ ใชใใธใใชใธใฎใใซใใใใทใฅใๅ
ฑๅไฝๆฅญ่
ใฎ่ฟฝๅ ใๅฏ่ฝใงใใ
teams.no_desc=ใใฎใใผใ ใซใฏ่ชฌๆใใใใพใใใ
teams.settings=่จญๅฎ
@@ -2858,7 +2938,7 @@ teams.delete_team_desc=ใใผใ ใๅ้คใใใจใใกใณใใผใฏใใฎใชใ
teams.delete_team_success=ใใผใ ใๅ้คใใพใใใ
teams.read_permission_desc=ใใฎใใผใ ใฏ่ชญใฟๅใ ใขใฏใปในๆจฉใๆใกใพใ: ใกใณใใผใฏใใผใ ใชใใธใใชใฎ้ฒ่ฆงใจใฏใญใผใณใๅฏ่ฝใงใใ
teams.write_permission_desc=ใใฎใใผใ ใฏๆธใ่พผใฟ ใขใฏใปในๆจฉใๆใกใพใ: ใกใณใใผใฏใใผใ ใชใใธใใชใฎ่ชญใฟๅใใจใใใทใฅใๅฏ่ฝใงใใ
-teams.admin_permission_desc=ใใฎใใผใ ใฏ็ฎก็่
ใขใฏใปในๆจฉใๆใกใพใ: ใกใณใใผใฏใใผใ ใชใใธใใชใฎ่ชญใฟๅใใใใใทใฅใๅ
ฑๅไฝๆฅญ่
ใฎ่ฟฝๅ ใๅฏ่ฝใงใใ
+teams.admin_permission_desc=ใใฎใใผใ ใฏ็ฎก็่
ใขใฏใปในๆจฉใไปไธใใใพใ: ใกใณใใผใฏใใผใ ใชใใธใใชใฎ่ชญใฟๅใใใใใทใฅใๅ
ฑๅไฝๆฅญ่
ใฎ่ฟฝๅ ใๅฏ่ฝใงใใ
teams.create_repo_permission_desc=ใใใซใใใฎใใผใ ใซใฏใชใใธใใชใฎไฝๆ ๆจฉ้ใไธใใใใฆใใพใ: ใกใณใใผใฏ็ต็นใฎใชใใธใใชใๆฐใใซไฝๆใงใใพใใ
teams.repositories=ใใผใ ใฎใชใใธใใช
teams.search_repo_placeholder=ใชใใธใใชใๆค็ดขโฆ
@@ -2888,7 +2968,7 @@ dashboard=ใใใทใฅใใผใ
identity_access=ใขใคใใณใใฃใใฃใจใขใฏใปใน
users=ใฆใผใถใผใขใซใฆใณใ
organizations=็ต็น
-assets=ใณใผใ ใขใปใใ
+assets=ใณใผใใขใปใใ
repositories=ใชใใธใใช
hooks=Webhook
integrations=้ฃๆบ
@@ -2902,7 +2982,7 @@ last_page=ๆๅพ
total=ๅ่จ: %d
settings=็ฎก็่จญๅฎ
-dashboard.new_version_hint=Forgejo %s ใๅ
ฅๆๅฏ่ฝใซใชใใพใใใ ็พๅจๅฎ่กใใฆใใใฎใฏ %s ใงใใ ่ฉณ็ดฐใฏ ใใญใฐ ใ็ขบ่ชใใฆใใ ใใใ
+dashboard.new_version_hint=Forgejo %s ใๅ
ฅๆๅฏ่ฝใซใชใใพใใใ ็พๅจๅฎ่กใใฆใใใฎใฏ %s ใงใใ ่ฉณ็ดฐใฏ ใใญใฐ ใ็ขบ่ชใใฆใใ ใใใ
dashboard.statistic=ใตใใชใผ
dashboard.operations=ใกใณใใใณในๆไฝ
dashboard.system_status=ใทในใใ ็ถๆณ
@@ -2937,14 +3017,14 @@ dashboard.archive_cleanup=ๅคใใชใใธใใชใขใผใซใคใใฎๅ้ค
dashboard.deleted_branches_cleanup=ๅ้คใใฉใณใใฎใฏใชใผใณใขใใ
dashboard.update_migration_poster_id=็งป่กใใๆ็จฟ่
IDใฎๆดๆฐ
dashboard.git_gc_repos=ใในใฆใฎใชใใธใใชใงใฌใใผใธใณใฌใฏใทใงใณใๅฎ่ก
-dashboard.resync_all_sshkeys='.ssh/authorized_keys' ใใกใคใซใForgejoไธใฎSSHใญใผใงๆดๆฐ
-dashboard.resync_all_sshprincipals='.ssh/authorized_principals' ใใกใคใซใForgejoไธใฎSSHใใชใณใทใใซใงๆดๆฐ
-dashboard.resync_all_hooks=ใในใฆใฎใชใใธใใชใฎ pre-receive, update, post-receive ใใใฏใๆดๆฐใใใ
+dashboard.resync_all_sshkeys=Forgejo SSH ใญใผใไฝฟ็จใใฆ".ssh/authorized_keys"ใใกใคใซใๆดๆฐใใพใใ
+dashboard.resync_all_sshprincipals=Forgejo SSH ใใชใณใทใใซใไฝฟ็จใใฆ".ssh/authorized_principals"ใใกใคใซใๆดๆฐใใพใใ
+dashboard.resync_all_hooks=ใในใฆใฎใชใใธใใชใฎ pre-receive, update, post-receive ใใใฏใๆดๆฐใใ
dashboard.reinit_missing_repos=ใฌใณใผใใๅญๅจใใใ่ฆๅฝใใใชใใในใฆใฎGitใชใใธใใชใๅๅๆๅใใ
dashboard.sync_external_users=ๅค้จใฆใผใถใผใใผใฟใฎๅๆ
dashboard.cleanup_hook_task_table=hook_taskใใผใใซใฎใฏใชใผใณใขใใ
dashboard.cleanup_packages=ๆ้ๅใใใใฑใผใธใฎใฏใชใผใณใขใใ
-dashboard.cleanup_actions=Actionsใฎๆ้ๅใใฎใญใฐใจใขใผใใฃใใกใฏใใฎใฏใชใผใณใขใใ
+dashboard.cleanup_actions=Actionsใใๆ้ๅใใฎใญใฐใจใขใผใใฃใใกใฏใใฎใฏใชใผใณใขใใใใ
dashboard.server_uptime=ใตใผใใผใฎ็จผๅๆ้
dashboard.current_goroutine=็พๅจใฎGoroutineๆฐ
dashboard.current_memory_usage=็พๅจใฎใกใขใชไฝฟ็จ้
@@ -3001,7 +3081,7 @@ users.repos=ใชใใธใใช
users.created=ไฝๆๆฅ
users.last_login=ๅๅใฎใตใคใณใคใณ
users.never_login=ๆชใตใคใณใคใณ
-users.send_register_notify=ใฆใผใถใผใซ็ป้ฒ้็ฅใ้ใ
+users.send_register_notify=ใฆใผใถใผใซ็ป้ฒใกใผใซใ้ใ
users.new_success=ใฆใผใถใผใขใซใฆใณใ "%s" ใไฝๆใใพใใใ
users.edit=็ทจ้
users.auth_source=่ช่จผใฝใผใน
@@ -3012,21 +3092,21 @@ users.update_profile_success=ใฆใผใถใผใขใซใฆใณใใๆดๆฐใใพใใใ
users.edit_account=ใฆใผใถใผใขใซใฆใณใใฎ็ทจ้
users.max_repo_creation=ใชใใธใใชๆฐใฎไธ้
users.max_repo_creation_desc=( -1ใ่จญๅฎใใใจใใใฉใซใใฎๅถ้ใ้ฉ็จใใใพใ)
-users.is_activated=ใฆใผใถใผใขใซใฆใณใใฏใขใฏใใฃใใผใๆธใฟ
-users.prohibit_login=ใตใคใณใคใณ็กๅน
+users.is_activated=ๆๅนๅใใใใขใซใฆใณใ
+users.prohibit_login=ใขใซใฆใณใใๅๆญขใใใพใใ
users.is_admin=็ฎก็่
-users.is_restricted=ๅถ้ใใ
-users.allow_git_hook=Gitใใใฏใไฝๆๅฏ
+users.is_restricted=ๅถ้ไปใใขใซใฆใณใ
+users.allow_git_hook=Gitใใใฏใไฝๆๅฏ่ฝ
users.allow_git_hook_tooltip=GitใใใฏใฏใForgejoใๅฎ่กใใฆใใOSใฆใผใถใผใฎๆจฉ้ใงๅฎ่กใใใๅใใฌใใซใฎใในใใขใฏใปในๆจฉใๆใคใใใซใชใใพใใ ใใฎ็ตๆใใใฎ็นๅฅใชGitใใใฏๆจฉ้ใๆใคใฆใผใถใผใฏใForgejoไธใฎใในใฆใฎใชใใธใใชใจForgejoใงไฝฟ็จใใใฆใใใใผใฟใใผในใซใขใฏใปในใใๅคๆดใๅ ใใใใจใใงใใพใใ ใใใใฃใฆใForgejoใฎ็ฎก็่
ๆจฉ้ใๅๅพใใใใจใใงใใพใใ
-users.allow_import_local=ใญใผใซใซใชใใธใใชใใคใณใใผใๅฏ
-users.allow_create_organization=็ต็นใไฝๆๅฏ
+users.allow_import_local=ใญใผใซใซใชใใธใใชใใคใณใใผใๅฏ่ฝ
+users.allow_create_organization=็ต็นใไฝๆๅฏ่ฝ
users.update_profile=ใฆใผใถใผใขใซใฆใณใใๆดๆฐ
users.delete_account=ใฆใผใถใผใขใซใฆใณใใๅ้ค
users.cannot_delete_self=่ชๅ่ช่บซใๅ้คใใใใจใฏใงใใพใใ
users.still_own_repo=ใใฎใฆใผใถใผใฏใพใ 1ใคไปฅไธใฎใชใใธใใชใๆๆใใฆใใพใใ ๅ
ใซใใใใฎใชใใธใใชใๅ้คใใใ็งป่ปขใใฆใใ ใใใ
users.still_has_org=ใใฎใฆใผใถใผใฏ็ต็นใฎใกใณใใผใซใชใฃใฆใใพใใ ๅ
ใซ็ต็นใใใใฎใฆใผใถใผใๅ้คใใฆใใ ใใใ
-users.purge=ใฆใผใถใผใๆนๆถ
-users.purge_help=ๅผทๅถ็ใซใฆใผใถใผใจใใฎใฆใผใถใผใๆๆใใฆใใใชใใธใใชใ็ต็นใใใใฑใผใธใๅ้คใใพใใใณใกใณใใใในใฆๅ้คใใพใใ
+users.purge=ใฆใผใถใผใๆถๅป
+users.purge_help=ๅผทๅถ็ใซใฆใผใถใผใจใใฎใฆใผใถใผใๆๆใใฆใใใชใใธใใชใ็ต็นใใใใฑใผใธใๅ้คใใพใใใณใกใณใใจใคใทใฅใผใใในใฆๅ้คใใพใใ
users.still_own_packages=ใใฎใฆใผใถใผใฏใพใ 1ใคไปฅไธใฎใใใฑใผใธใๆๆใใฆใใพใใๅ
ใซใใใใฎใใใฑใผใธใๅ้คใใฆใใ ใใใ
users.deletion_success=ใฆใผใถใผใขใซใฆใณใใๅ้คใใพใใใ
users.reset_2fa=2่ฆ็ด ่ช่จผใใชใปใใ
@@ -3091,12 +3171,12 @@ packages.size=ใตใคใบ
packages.published=้
ๅธ
defaulthooks=ใใใฉใซใWebhook
-defaulthooks.desc=Webhookใฏใ็นๅฎใฎForgejoใคใใณใใฎใใชใฌใผใ็บ็ใใ้ใซใ่ชๅ็ใซHTTP POSTใชใฏใจในใใใตใผใใผใธ้ไฟกใใใใฎใงใใ ใใใงๅฎ็พฉใใใWebhookใฏใใใฉใซใใจใชใใๅ
จใฆใฎๆฐ่ฆใชใใธใใชใซใณใใผใใใพใใ ่ฉณใใใฏWebhooksใฌใคใ ใใ่ฆงไธใใใ
+defaulthooks.desc=Webhookใฏใ็นๅฎใฎForgejoใคใใณใใฎใใชใฌใผใ็บ็ใใ้ใซใ่ชๅ็ใซHTTP POSTใชใฏใจในใใใตใผใใผใธ้ไฟกใใใใฎใงใใ ใใใงๅฎ็พฉใใใWebhookใฏใใใฉใซใใจใชใใๅ
จใฆใฎๆฐ่ฆใชใใธใใชใซใณใใผใใใพใใ ่ฉณใใใฏWebhooksใฌใคใ ใใ่ฆงไธใใใ
defaulthooks.add_webhook=ใใใฉใซใWebhookใฎ่ฟฝๅ
defaulthooks.update_webhook=ใใใฉใซใWebhookใฎๆดๆฐ
systemhooks=ใทในใใ Webhook
-systemhooks.desc=Webhookใฏใ็นๅฎใฎForgejoใคใใณใใฎใใชใฌใผใ็บ็ใใ้ใซใ่ชๅ็ใซHTTP POSTใชใฏใจในใใใตใผใใผใธ้ไฟกใใใใฎใงใใ ใใใงๅฎ็พฉใใWebhookใฏใทในใใ ๅ
ใฎใในใฆใฎใชใใธใใชใงๅผใณๅบใใใพใใ ใใฎใใใใใใฉใผใใณในใซๅใผใๅฝฑ้ฟใ่ๆ
ฎใใใใใง่จญๅฎใใฆใใ ใใใ ่ฉณใใใฏWebhooksใฌใคใ ใใ่ฆงไธใใใ
+systemhooks.desc=Webhookใฏใ็นๅฎใฎForgejoใคใใณใใฎใใชใฌใผใ็บ็ใใ้ใซใ่ชๅ็ใซHTTP POSTใชใฏใจในใใใตใผใใผใธ้ไฟกใใใใฎใงใใ ใใใงๅฎ็พฉใใWebhookใฏใทในใใ ๅ
ใฎใในใฆใฎใชใใธใใชใงๅผใณๅบใใใพใใ ใใฎใใใใใใฉใผใใณในใซๅใผใๅฝฑ้ฟใ่ๆ
ฎใใใใใง่จญๅฎใใฆใใ ใใใ ่ฉณใใใฏWebhooksใฌใคใ ใใ่ฆงไธใใใ
systemhooks.add_webhook=ใทในใใ Webhookใ่ฟฝๅ
systemhooks.update_webhook=ใทในใใ Webhookใๆดๆฐ
@@ -3191,18 +3271,18 @@ auths.tips=ใใณใ
auths.tips.oauth2.general=OAuth2่ช่จผ
auths.tips.oauth2.general.tip=ๆฐใใOAuth2่ช่จผใ็ป้ฒใใใจใใฏใใณใผใซใใใฏ/ใชใใคใฌใฏใURLใฏไปฅไธใซใชใใพใ:
auths.tip.oauth2_provider=OAuth2ใใญใใคใใผ
-auths.tip.bitbucket=ๆฐใใOAuthใณใณใทใฅใผใใผใ https://bitbucket.org/account/user/<ใใชใใฎใฆใผใถใผๅ>/oauth-consumers/new ใใ็ป้ฒใใ"ใขใซใฆใณใ" ใซ "่ชญใฟๅใ" ๆจฉ้ใ่ฟฝๅ ใใฆใใ ใใใ
+auths.tip.bitbucket=ๆฐใใOAuthใณใณใทใฅใผใใผใ %s
auths.tip.nextcloud=ๆฐใใOAuthใณใณใทใฅใผใใผใใใคใณในใฟใณในใฎใกใใฅใผ "Settings -> Security -> OAuth 2.0 client" ใใ็ป้ฒใใฆใใ ใใใ
-auths.tip.dropbox=ๆฐใใใขใใชใฑใผใทใงใณใ https://www.dropbox.com/developers/apps ใใ็ป้ฒใใฆใใ ใใใ
-auths.tip.facebook=ๆฐใใใขใใชใฑใผใทใงใณใ https://developers.facebook.com/apps ใง็ป้ฒใใ"Facebook Login"ใ่ฟฝๅ ใใฆใใ ใใใ
-auths.tip.github=ๆฐใใOAuthใขใใชใฑใผใทใงใณใ https://github.com/settings/applications/new ใใ็ป้ฒใใฆใใ ใใใ
+auths.tip.dropbox=ๆฐใใใขใใชใฑใผใทใงใณใ %s ใใ็ป้ฒใใฆใใ ใใใ
+auths.tip.facebook=ๆฐใใใขใใชใฑใผใทใงใณใ %s ใง็ป้ฒใใ"Facebook Login"ใ่ฟฝๅ ใใฆใใ ใใใ
+auths.tip.github=ๆฐใใOAuthใขใใชใฑใผใทใงใณใ %s ใใ็ป้ฒใใฆใใ ใใใ
auths.tip.gitlab=ๆฐใใใขใใชใฑใผใทใงใณใ https://gitlab.com/profile/applications ใใ็ป้ฒใใฆใใ ใใใ
-auths.tip.google_plus=OAuth2ใฏใฉใคใขใณใ่ณๆ ผๆ
ๅ ฑใใGoogle APIใณใณใฝใผใซ https://console.developers.google.com/ ใใๅๅพใใฆใใ ใใใ
+auths.tip.google_plus=OAuth2ใฏใฉใคใขใณใ่ณๆ ผๆ
ๅ ฑใใGoogle APIใณใณใฝใผใซ %s ใใๅๅพใใฆใใ ใใใ
auths.tip.openid_connect=OpenID Connect DiscoveryใฎURL (/.well-known/openid-configuration) ใใจใณใใใคใณใใจใใฆๆๅฎใใฆใใ ใใ
-auths.tip.twitter=https://dev.twitter.com/apps ใธใขใฏใปในใใฆใขใใชใฑใผใทใงใณใไฝๆใใโAllow this application to be used to Sign in with Twitterโใชใใทใงใณใๆๅนใซใใฆใใ ใใใ
-auths.tip.discord=ๆฐใใใขใใชใฑใผใทใงใณใ https://discordapp.com/developers/applications/me ใใ็ป้ฒใใฆใใ ใใใ
-auths.tip.gitea=ๆฐใใOAuthใขใใชใฑใผใทใงใณใ็ป้ฒใใฆใใ ใใใ ๅฉ็จใฌใคใใฏ https://forgejo.org/docs/latest/user/oauth2-provider ใซใใใพใ
-auths.tip.yandex=`https://oauth.yandex.com/client/new ใงๆฐใใใขใใชใฑใผใทใงใณใไฝๆใใฆใใ ใใใ "Yandex.Passport API" ใปใฏใทใงใณใงๆฌกใฎ้
็ฎใ่จฑๅฏใใพใ: "Access to email address"ใ"Access to user avatar"ใ"Access to username, first name and surname, gender"`
+auths.tip.twitter=%s ใธใขใฏใปในใใฆใขใใชใฑใผใทใงใณใไฝๆใใโAllow this application to be used to Sign in with Twitterโใชใใทใงใณใๆๅนใซใใฆใใ ใใใ
+auths.tip.discord=ๆฐใใใขใใชใฑใผใทใงใณใ %s ใใ็ป้ฒใใฆใใ ใใใ
+auths.tip.gitea=ๆฐใใOAuthใขใใชใฑใผใทใงใณใ็ป้ฒใใฆใใ ใใใ ๅฉ็จใฌใคใใฏ %s ใซใใใพใ
+auths.tip.yandex=`%s ใงๆฐใใใขใใชใฑใผใทใงใณใไฝๆใใฆใใ ใใใ "Yandex.Passport API" ใปใฏใทใงใณใงๆฌกใฎ้
็ฎใ่จฑๅฏใใพใ: "Access to email address"ใ"Access to user avatar"ใ"Access to username, first name and surname, gender"`
auths.tip.mastodon=่ช่จผใใใMastodonใคใณในใฟใณในใฎใซในใฟใ URLใๅ
ฅๅใใฆใใ ใใ (ๅ
ฅๅใใชใๅ ดๅใฏใใใฉใซใใฎURLใไฝฟ็จใใพใ)
auths.edit=่ช่จผใฝใผในใฎ็ทจ้
auths.activated=่ช่จผใฝใผในใฏใขใฏใใฃใใผใๆธใฟ
@@ -3416,15 +3496,31 @@ dashboard.sync_tag.started = ใฟใฐใฎๅๆใ้ๅงใใใพใใ
self_check = ใปใซใใใงใใฏ
auths.tips.gmail_settings = Gmail่จญๅฎ:
self_check.no_problem_found = ใพใ ๅ้กใฏ่ฆใคใใใพใใใ
-auths.tip.gitlab_new = https://gitlab.com/-/profile/applications ใงๆฐใใใขใใชใฑใผใทใงใณใ็ป้ฒใใพใ
+auths.tip.gitlab_new = %s ใงๆฐใใใขใใชใฑใผใทใงใณใ็ป้ฒใใพใ
auths.default_domain_name = ใกใผใซใขใใฌในใฎใใใซไฝฟใใใใใใฉใซใใฎใใกใคใณๅ
self_check.database_collation_mismatch = ใใผใฟใใผในใไฝฟใใจๆๅพ
ใใใcollation: %s
self_check.database_collation_case_insensitive = ใใผใฟใใผในใฏ %s ใจใใ collation ใ็จใใฆใใพใใใใใใฏๅคงๆๅญๅฐๆๅญใๅบๅฅใใพใใใForgejoใฏๅไฝใงใใพใใใๆๅพ
้ใใซๅใใชใๅ ดๅใ็จใซ็บ็ใใๅ ดๅใใใใพใใ
config_settings = ่จญๅฎ
config_summary = ๆฆ่ฆ
self_check.database_inconsistent_collation_columns = ใใผใฟใใผในใฏ %s ใจใใ collation ใ็จใใฆใใพใใใใใใใฎใซใฉใ ใฏๅฅใฎcollationใ็จใใฆใใพใใใใใฏๆณๅฎๅคใฎๅ้กใๅผใ่ตทใใๅฏ่ฝๆงใใใใพใใ
+users.organization_creation.description = ๆฐใใ็ต็นใฎไฝๆใ่จฑๅฏใใพใใ
+users.restricted.description = ใใฎใฆใผใถใผใๅ
ฑๅไฝๆฅญ่
ใจใใฆ่ฟฝๅ ใใใฆใใใชใใธใใชใใใณ็ต็นใจใฎใใๅใใฎใฟใ่จฑๅฏใใพใใใใใซใใใใใฎใคใณในใฟใณในไธใฎใใใชใใฏใชใใธใใชใธใฎใขใฏใปในใ้ฒๆญขใใใพใใ
+users.activated.description = ใกใผใซ่ช่จผใฎๅฎไบใใขใฏใใฃใๅใใใฆใใชใใขใซใฆใณใใฎๆๆ่
ใฏใใกใผใซ่ช่จผใๅฎไบใใใพใงใญใฐใคใณใงใใพใใใ
+users.admin.description = ใใฎใฆใผใถใผใซใWeb UI ใใใณ API ใ้ใใฆๅฉ็จใงใใใในใฆใฎ็ฎก็ๆฉ่ฝใธใฎใใซใขใฏใปในๆจฉใไปไธใใพใใ
+users.local_import.description = ใตใผใใผใฎใญใผใซใซใใกใคใซ ใทในใใ ใใใชใใธใใชใใคใณใใผใใงใใใใใซใใพใใใใใฏใปใญใฅใชใใฃไธใฎๅ้กใซใชใๅฏ่ฝๆงใใใใพใใ
+users.block.description = ใใฎใฆใผใถใผใ่ชๅใฎใขใซใฆใณใใ้ใใฆใใฎใตใผใในใจใใๅใใใใใจใใใญใใฏใใใตใคใณใคใณใ็ฆๆญขใใพใใ
+emails.delete = ใกใผใซใขใใฌในใๅ้ค
+emails.delete_desc = ใใฎใกใผใซใขใใฌในใๅ้คใใฆใใใใใใงใใ?
+config.cache_test_succeeded = ใญใฃใใทใฅ ใในใใๆๅใใพใใใ%s ใงๅฟ็ญใ่ฟใใใพใใใ
+config.cache_test_slow = ใญใฃใใทใฅ ใในใใฏๆๅใใพใใใใๅฟ็ญใ้
ใใงใ: %sใ
+emails.deletion_success = ใกใผใซใขใใฌในใฏๅ้คใใใพใใใ
+emails.delete_primary_email_error = ใใฉใคใใชใกใผใซใๅ้คใใใใจใฏใงใใพใใใ
+config.app_slogan = ใคใณในใฟใณในใฎในใญใผใฌใณ
+config.cache_test = ใในใใญใฃใใทใฅ
+config.cache_test_failed = ใญใฃใใทใฅใฎ่ชฟๆปใซๅคฑๆใใพใใ: %v.
+
[action]
create_repo=ใใชใใธใใช %s ใไฝๆใใพใใ
rename_repo=ใใชใใธใใชๅใ %[1]s
ใใ %[3]s ใธๅคๆดใใพใใ
@@ -3668,6 +3764,8 @@ rpm.repository.multiple_groups = ใใฎใใใฑใผใธใฏ่คๆฐใฎใฐใซใผใ
owner.settings.cargo.rebuild.no_index = ๅๆง็ฏใงใใพใใใใคใณใใใฏในใๅๆๅใใใฆใใพใใใ
npm.dependencies.bundle = ใใณใใซใใใไพๅญ้ขไฟ
+search_in_external_registry = %s ใงๆค็ดข
+
[secrets]
secrets=ใทใผใฏใฌใใ
description=ใทใผใฏใฌใใใฏ็นๅฎใฎActionsใซๆธกใใใพใใ ใใไปฅๅคใง่ชญใฟๅบใใใใใจใฏใใใพใใใ
@@ -3746,8 +3844,8 @@ runs.actors_no_select=ใในใฆใฎใขใฏใฟใผ
runs.status_no_select=ใในใฆใฎในใใผใฟใน
runs.no_results=ไธ่ดใใ็ตๆใฏใใใพใใใ
runs.no_workflows=ใฏใผใฏใใญใผใฏใพใ ใใใพใใใ
-runs.no_workflows.quick_start=Gitea Actions ใฎๅงใๆนใใใใใชใ๏ผ ใงใฏใฏใคใใฏในใฟใผใใฌใคใ ใใ่ฆงใใ ใใใ
-runs.no_workflows.documentation=Gitea Actions ใฎ่ฉณ็ดฐใซใคใใฆใฏใใใญใฅใกใณใ ใๅ็
งใใฆใใ ใใใ
+runs.no_workflows.quick_start = Forgejo Action ใฎๅงใๆนใใใใใชใ๏ผ ใฏใคใใฏในใฟใผใใฌใคใ ใใ่ฆงใใ ใใใ
+runs.no_workflows.documentation = Forgejo Action ใฎ่ฉณ็ดฐใซใคใใฆใฏใใใญใฅใกใณใ ใๅ็
งใใฆใใ ใใใ
runs.no_runs=ใฏใผใฏใใญใผใฏใพใ ๅฎ่กใใใฆใใพใใใ
runs.empty_commit_message=(็ฉบใฎใณใใใใกใใปใผใธ)
@@ -3773,20 +3871,29 @@ variables.creation.failed=ๅคๆฐใ่ฟฝๅ ใงใใพใใใงใใใ
variables.creation.success=ๅคๆฐ "%s" ใ่ฟฝๅ ใใพใใใ
variables.update.failed=ๅคๆฐใๆดๆฐใงใใพใใใงใใใ
variables.update.success=ๅคๆฐใๆดๆฐใใพใใใ
-runs.no_workflows.quick_start = Forgejo Action ใฎๅงใๆนใใใใใชใ๏ผ ใฏใคใใฏในใฟใผใใฌใคใ ใใ่ฆงใใ ใใใ
-runs.no_workflows.documentation = Forgejo Action ใฎ่ฉณ็ดฐใซใคใใฆใฏใใใญใฅใกใณใ ใๅ็
งใใฆใใ ใใใ
variables.id_not_exist = idใ%dใฎๅคๆฐใฏๅญๅจใใพใใใ
runs.workflow = ใฏใผใฏใใญใผ
runs.no_job_without_needs = ใฏใผใฏใใญใผใซใฏใไพๅญ้ขไฟใฎใชใใธใงใใๅฐใชใใจใ 1 ใคๅซใพใใฆใใๅฟ
่ฆใใใใพใใ
+workflow.dispatch.run = ใฏใผใฏใใญใผใๅฎ่ก
+workflow.dispatch.success = ใฏใผใฏใใญใผใฎๅฎ่กใๆญฃๅธธใซใชใฏใจในใใใใพใใใ
+workflow.dispatch.trigger_found = ใใฎใฏใผใฏใใญใผใซใฏ workflow_dispatch ใคใใณใใใชใฌใผใใใใพใใ
+workflow.dispatch.use_from = ใฏใผใฏใใญใผใไฝฟ็จใใ
+workflow.dispatch.input_required = ๅ
ฅๅ "%s" ใซๅคใๅฟ
่ฆใงใใ
+workflow.dispatch.invalid_input_type = ๅ
ฅๅใฟใคใใ%sใใ็กๅนใงใใ
+workflow.dispatch.warn_input_limit = ๆๅใฎ %d ๅใฎๅ
ฅๅใฎใฟใ่กจ็คบใใพใใ
+runs.no_job = ใฏใผใฏใใญใผใซใฏๅฐใชใใจใ1ใคใฎใธใงใใๅซใพใใฆใใๅฟ
่ฆใใใใพใ
+
+runs.expire_log_message = ใญใฐใฏๅคใใใใใๆถๅปใใใฆใใพใใ
[projects]
type-1.display_name=ๅไบบใใญใธใงใฏใ
type-2.display_name=ใชใใธใใช ใใญใธใงใฏใ
type-3.display_name=็ต็นใใญใธใงใฏใ
+deleted.display_name = ๅ้คใใใใใญใธใงใฏใ
+
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=ใใฃใฌใฏใใช
normal_file=ใใผใใซใใกใคใซ
executable_file=ๅฎ่กๅฏ่ฝใใกใคใซ
@@ -3816,6 +3923,14 @@ no_results = ไธ่ดใใ็ตๆใ่ฆใคใใใพใใใงใใใ
fuzzy_tooltip = ๅ
ฅๅใใใ่ชๅฅใซ่ฟใใใฎใ็ตๆใซๅซใใ
match = ไธ่ด
match_tooltip = ๆค็ดข่ชๅฅใซๅณๅฏใซไธ่ดใใใใฎใฎใฟ็ตๆใซๅซใใ
+milestone_kind = ใใคใซในใใผใณใๆค็ดข...
+union_tooltip = ็ฉบ็ฝใงๅบๅใใใใญใผใฏใผใใฎใใใใใซไธ่ดใใ็ตๆใๅซใใ
+exact_tooltip = ๆค็ดข่ชๅฅใจๅฎๅ
จใซไธ่ดใใ็ตๆใฎใฟใๅซใใ
+issue_kind = ใคใทใฅใผใๆค็ดข...
+pull_kind = ใใซใๆค็ดข...
+exact = ๅฎๅ
จไธ่ด
+regexp_tooltip = ๆค็ดข่ชๅฅใๆญฃ่ฆ่กจ็พใจใใฆ่งฃ้ใใ
+regexp = ๆญฃ่ฆ่กจ็พ
[munits.data]
@@ -3830,4 +3945,27 @@ b = B
[markup]
filepreview.lines = %[3]s ใฎ %[1]d ่ก็ฎใใ %[2]d ่ก็ฎ
filepreview.line = %[2]s ใฎ %[1]d ่ก็ฎ
-filepreview.truncated = ใใฌใใฅใผใฏ้ไธญใใ็็ฅใใใฆใใพใ
\ No newline at end of file
+filepreview.truncated = ใใฌใใฅใผใฏ้ไธญใใ็็ฅใใใฆใใพใ
+
+[repo.permissions]
+actions.write = ๆธใ่พผใฟ: ไฟ็ไธญใฎ CI/CD ใใคใใฉใคใณใๆๅใงใใชใฌใผใๅ่ตทๅใใญใฃใณใปใซใใพใใฏๆฟ่ชใใพใใ
+ext_issues = ๅค้จใฎใคใทใฅใผ่ฟฝ่ทกใธใฎใชใณใฏใซใขใฏใปในใใพใใๆจฉ้ใฏๅค้จใง็ฎก็ใใใพใใ
+ext_wiki = ๅค้จ Wiki ใธใฎใชใณใฏใซใขใฏใปในใใพใใๆจฉ้ใฏๅค้จใง็ฎก็ใใใพใใ
+projects.write = ๆธใ่พผใฟ: ใใญใธใงใฏใใจๅใไฝๆใใ็ทจ้ใใพใใ
+packages.read = ่ชญใฟๅใ: ใชใใธใใชใซๅฒใๅฝใฆใใใใใใฑใผใธใ่กจ็คบใใใณใใฆใณใญใผใใใพใใ
+packages.write = ๆธใ่พผใฟ: ใชใใธใใชใซๅฒใๅฝใฆใใใใใใฑใผใธใๅ
ฌ้ใใใณๅ้คใใพใใ
+code.read = ่ชญใฟๅใ: ใชใใธใใชใฎใณใผใใซใขใฏใปในใใฆใฏใญใผใณใไฝๆใใพใใ
+code.write = ๆธใ่พผใฟ: ใชใใธใใชใซใใใทใฅใใใใฉใณใใจใฟใฐใไฝๆใใพใใ
+issues.read = ่ชญใฟๅใ: ใคใทใฅใผใจใณใกใณใใ่ชญใใงไฝๆใใพใใ
+issues.write = ๆธใ่พผใฟ: ใคใทใฅใผใ่งฃๆฑบใใใฉใใซใใใคใซในใใผใณใๆ
ๅฝ่
ใๆ้ใไพๅญ้ขไฟใชใฉใฎใกใฟใใผใฟใ็ฎก็ใใพใใ
+pulls.read = ่ชญใฟๅใ: ใใซใชใฏใจในใใฎ่ชญใฟๅใใจไฝๆใ
+releases.read = ่ชญใฟๅใ: ใชใชใผในใ่กจ็คบใใใณใใฆใณใญใผใใใพใใ
+releases.write = ๆธใ่พผใฟ: ใชใชใผในใจใใฎใขใปใใใๅ
ฌ้ใ็ทจ้ใๅ้คใใพใใ
+pulls.write = ๆธใ่พผใฟ: ใใซใชใฏใจในใใใฏใญใผใบใใใฉใใซใใใคใซในใใผใณใๆ
ๅฝ่
ใๆ้ใไพๅญ้ขไฟใชใฉใฎใกใฟใใผใฟใ็ฎก็ใใพใใ
+wiki.read = ่ชญใฟๅใ: ็ตฑๅใใใ wiki ใจใใฎๅฑฅๆญดใ่ชญใฟๅใใพใใ
+wiki.write = ๆธใ่พผใฟ: ็ตฑๅใใใ Wiki ๅ
ใฎใใผใธใไฝๆใๆดๆฐใๅ้คใใพใใ
+projects.read = ่ชญใฟๅใ: ใชใใธใใช ใใญใธใงใฏใ ใใผใใซใขใฏใปในใใพใใ
+actions.read = ่ชญใฟๅใ: ็ตฑๅใใใ CI/CD ใใคใใฉใคใณใจใใฎใญใฐใ่กจ็คบใใพใใ
+
+[translation_meta]
+test = ใใใฏใในใๆๅญๅใงใใForgejo UI ใซใฏ่กจ็คบใใใพใใใใใในใ็ฎ็ใงไฝฟ็จใใใพใใๆฉใๆธใพใใใใใซ"ok"ใจๅ
ฅๅใใใๆฅฝใใใฃใๅบๆฅไบใๅ
ฅๅใใฆไธใใใใใใใใฐใๅฎไบใใใใจใใงใใพใ :)
diff --git a/options/locale/locale_ka.ini b/options/locale/locale_ka.ini
new file mode 100644
index 0000000000..b1e1df74b3
--- /dev/null
+++ b/options/locale/locale_ka.ini
@@ -0,0 +1,836 @@
+[common]
+home = แกแแฌแงแแกแ
+dashboard = แกแแแฃแจแแ แแแแแแ
+explore = แแแแแแแแแ แแแ
+help = แแแฎแแแ แแแ
+logo = แแแแ
+sign_in = แจแแกแแแ
+sign_in_or = แแ
+sign_out = แแแกแแแ
+sign_up = แ แแแแกแขแ แแชแแ
+link_account = แแแแแ แแจแแก แแแแแ
+register = แ แแแแกแขแ แแชแแ
+version = แแแ แกแแ
+page = แแแแ แแ
+template = แแแแฃแจแ
+language = แแแ
+notifications = แแแคแ แแฎแแแแแแแ
+create_new = แจแแฅแแแโฆ
+licenses = แแแชแแแแแแแ
+toggle_menu = แแแแแฃแก แแแแแ แแแ
+more_items = แแแขแ แแแแแแแขแ
+username = แแแแฎแแแ แแแแแก แกแแฎแแแ
+email = แแแคแแกแขแแก แแแกแแแแ แแ
+password = แแแ แแแ
+access_token = แฌแแแแแแก แขแแแแแ
+re_type = แแแแแแกแขแฃแ แแ แแแ แแแ
+captcha = แแแแฉแ
+twofa = 2FA
+passcode = แกแแแแแแซแ แแแแ
+repository = แ แแแแแแขแแ แแ
+organization = แแ แแแแแแแชแแ
+mirror = แกแแ แแ
+new_mirror = แแฎแแแ แกแแ แแ
+new_project = แแฎแแแ แแ แแแฅแขแ
+new_project_column = แแฎแแแ แกแแแขแ
+admin_panel = แกแแแขแแก แแแแแแแกแขแ แแ แแแ
+settings = แแแ แแแแ
+your_profile = แแ แแคแแแ
+your_starred = แแแ แกแแแแแแแแแ
+your_settings = แแแ แแแแ
+new_repo.title = แแฎแแแ แ แแแแแแขแแ แแ
+new_migrate.title = แแฎแแแ แแแแ แแชแแ
+new_org.title = แแฎแแแ แแ แแแแแแแชแแ
+new_repo.link = แแฎแแแ แ แแแแแแขแแ แแ
+new_migrate.link = แแฎแแแ แแแแ แแชแแ
+new_org.link = แแฎแแแ แแ แแแแแแแชแแ
+all = แงแแแแ
+sources = แฌแงแแ แแแแ
+mirrors = แกแแ แแแแแ
+collaborative = แกแแแ แแ
+forks = แคแแ แแแแ
+activities = แแฅแขแแแแแแแ
+pull_requests = แจแแ แฌแงแแแก แแแแฎแแแแแแ
+issues = แแ แแแแแแแแ
+milestones = แแแกแแฆแฌแแแ แแแแแแแ
+ok = แแแแฎ
+cancel = แแแฃแฅแแแแ
+retry = แแแแแแแ แชแแ
+rerun = แแแแแแแ แแแจแแแแ
+save = แจแแแแฎแแ
+add = แแแแแขแแแ
+add_all = แงแแแแแก แแแแแขแแแ
+remove = แฌแแจแแ
+remove_all = แงแแแแแก แฌแแจแแ
+edit = แฉแแกแฌแแ แแแ
+view = แฎแแแ
+test = แจแแแแฌแแแแ
+enabled = แฉแแ แแฃแแแ
+disabled = แแแแแ แแฃแแแ
+locked = แฉแแแแขแแแแ
+copy = แแแแแ แแแ
+copy_url = แแแฃแแแก แแแแแ แแแ
+copy_hash = แฐแแจแแก แแแแแ แแแ
+copy_path = แแแแแแแก แแแแแ แแแ
+copy_content = แจแแแชแแแแแแแก แแแแแ แแแ
+copy_success = แแแแแแแ แแแฃแแแ!
+copy_error = แแแแแ แแแ แฉแแแแ แแ
+write = แฉแแฌแแ แ
+preview = แแแแแแขแฃแ แ
+loading = แฉแแขแแแ แแแโฆ
+error = แจแแชแแแแ
+never = แแ แแกแแ แแก
+unknown = แฃแชแแแแ
+pin = แแแแแ แแแ
+unpin = แฉแแแแฎแกแแ
+artifacts = แแ แขแแคแแฅแขแแแ
+archived = แแแแ แฅแแแแแฃแแ
+concept_system_global = แแแแแแแฃแ แ
+concept_user_individual = แแแแแแแแฃแแแฃแ แ
+concept_code_repository = แ แแแแแแขแแ แแ
+concept_user_organization = แแ แแแแแแแชแแ
+name = แกแแฎแแแ
+value = แแแแจแแแแแแแ
+filter = แคแแแขแ แ
+filter.is_archived = แแแแ แฅแแแแแฃแแ
+filter.is_fork = แคแแ แแแแ
+filter.is_mirror = แกแแ แแแแแ
+filter.is_template = แแแแฃแจแแแ
+filter.public = แกแแฏแแ แ
+filter.private = แแแ แแแ
+
+[search]
+search = แซแแแแโฆ
+fuzzy = แแแฃแ แแแแแแแ
+union = แแแแ แแแแแแแ
+exact = แแฃแกแขแ
+regexp = แ แแแแแแแกแ
+
+[aria]
+footer = แฅแแแแ แแแแแแขแแขแฃแแ
+footer.links = แแแฃแแแแ
+
+[heatmap]
+contributions_one = แจแแฌแแ แฃแแแแ
+contributions_few = แจแแฌแแ แฃแแแแแแ
+less = แแแแแแแ
+more = แแแขแ
+
+[editor]
+table_modal.placeholder.header = แแแแ แแแแแแขแแขแฃแแ
+table_modal.placeholder.content = แจแแแชแแแแแแ
+table_modal.label.rows = แแฌแแ แแแ
+table_modal.label.columns = แกแแแขแ
+link_modal.url = Url
+link_modal.description = แแฆแฌแแ แ
+
+[startpage]
+platform = แแแแขแคแแ แแแแแจแแ แแกแ
+lightweight = แแกแฃแแฃแฅแ
+
+[install]
+install = แแแงแแแแแ
+host = แฐแแกแขแ
+user = แแแแฎแแแ แแแแแก แกแแฎแแแ
+password = แแแ แแแ
+db_schema = แกแฅแแแ
+ssl_mode = SSL
+path = แแแแแแ
+admin_password = แแแ แแแ
+
+[home]
+my_repos = แ แแแแแแขแแ แแแแ
+my_orgs = แแ แแแแแแแชแแแแ
+show_archived = แแแแ แฅแแแแแฃแแ
+show_private = แแแ แแแ
+
+[explore]
+repos = แ แแแแแแขแแ แแแแ
+users = แแแแฎแแแ แแแแแแ
+organizations = แแ แแแแแแแชแแแแ
+code = แแแแ
+
+[auth]
+verify = แแแแแแแฌแแแแ
+openid_connect_submit = แแแแ แแแแ
+
+[mail]
+release.note = แจแแแแจแแแ:
+release.downloads = แแแแแแฌแแ แแแ:
+repo.transfer.to_you = แแฅแแแ
+
+[modal]
+yes = แแแแฎ
+no = แแ แ
+confirm = แแแแแกแขแฃแ แแแ
+cancel = แแแฃแฅแแแแ
+modify = แแแแแฎแแแแ
+
+[form]
+UserName = แแแแฎแแแ แแแแแก แกแแฎแแแ
+Description = แแฆแฌแแ แ
+Pronouns = แแแชแแแแกแแฎแแแแแ
+Biography = แแแแแ แแคแแ
+Website = แแแแแแแ แแ
+Location = แแแแแแ แแแแ
+Password = แแแ แแแ
+Content = แจแแแชแแแแแแ
+
+[user]
+repositories = แ แแแแแแขแแ แแแแ
+followers.title.one = แแแแงแแแ
+followers.title.few = แแแแงแแแแแ
+following.title.one = แแแฐแงแแแแแ
+following.title.few = แแแฐแงแแแแแ
+follow = แแแงแแแ
+unfollow = แแแงแแแแก แแแฃแฅแแแแ
+code = แแแแ
+projects = แแ แแแฅแขแแแ
+overview = แแแแแฎแแแแ
+block = แแแแแแแแ
+unblock = แแแแแแแแแ
+user_bio = แแแแแ แแคแแ
+
+[settings]
+profile = แแ แแคแแแ
+account = แแแแแ แแจแ
+appearance = แแแ แแแแแแ
+password = แแแ แแแ
+security = แฃแกแแคแ แแฎแแแแ
+avatar = แแแแขแแ แ
+applications = แแแแแ
+orgs = แแ แแแแแแแชแแแแ
+repos = แ แแแแแแขแแ แแแแ
+organization = แแ แแแแแแแชแแแแ
+uid = UID
+quota = แแแแขแ
+website = แแแแแแแ แแ
+location = แแแแแแ แแแแ
+pronouns = แแแชแแแแกแแฎแแแแแ
+pronouns_unspecified = แแแแแแแแฃแแ แแ แแ
+continue = แแแแ แซแแแแแ
+cancel = แแแฃแฅแแแแ
+language = แแแ
+ui = แแแแ
+hints = แแแแแจแแแแแแ
+comment_type_group_reference = แแแแแ แแแ
+comment_type_group_label = แญแแ
+comment_type_group_milestone = แแแกแแฆแฌแแแ แแแแแแ
+comment_type_group_assignee = แแแแแแญแแแแแ
+comment_type_group_title = แกแแแแฃแ แ
+comment_type_group_branch = แแ แแแฉแ
+comment_type_group_deadline = แแ แแแฅแขแแก แแแแ
+comment_type_group_dependency = แแแแแแแแแแฃแแแแ
+comment_type_group_project = แแ แแแฅแขแ
+privacy = แแแแคแแแแแชแแแแแแ
+primary = แซแแ แแแแแ
+activated = แแแแฅแขแแฃแ แแแฃแแแ
+delete_email = แฌแแจแแ
+gpg_key_verify = แแแแแแแฌแแแแ
+gpg_token = แขแแแแแ
+ssh_key_verify = แแแแแแแฌแแแแ
+ssh_token = แขแแแแแ
+subkeys = แฅแแแแแกแแฆแแแแแ
+key_content = แจแแแชแแแแแแ
+principal_content = แจแแแชแแแแแแ
+delete_key = แฌแแจแแ
+can_read_info = แฌแแแแแฎแแ
+can_write_info = แฉแแฌแแ แ
+delete_token = แฌแแจแแ
+regenerate_token = แ แแแแแแ แแชแแ
+permission_read = แฌแแแแแฎแแ
+permissions_list = แฌแแแแแแแ:
+save_application = แจแแแแฎแแ
+oauth2_application_edit = แฉแแกแฌแแ แแแ
+revoke_key = แแแฃแฅแแแแ
+webauthn_nickname = แแแขแกแแฎแแแ
+visibility.public = แกแแฏแแ แ
+visibility.limited = แจแแแฆแฃแแฃแแ
+visibility.private = แแแ แแแ
+quota.rule.exceeded = แแแแแชแแแแแฃแแแ
+quota.rule.no_limit = แจแแฃแแฆแฃแแแแ
+quota.sizes.all = แงแแแแ
+quota.sizes.repos.all = แ แแแแแแขแแ แแแแ
+quota.sizes.assets.all = แแแแแฅแขแแแ
+quota.sizes.assets.attachments.all = แแแแแแ แแแฃแแ แคแแแแแแ
+quota.sizes.assets.artifacts = แแ แขแแคแแฅแขแแแ
+quota.sizes.assets.packages.all = แแแแแขแแแ
+quota.sizes.wiki = แแแแ
+
+[repo]
+owner = แแคแแแแแแ
+template = แแแแฃแจแ
+visibility = แฎแแแแแแแแ
+repo_desc = แแฆแฌแแ แ
+repo_lang = แแแ
+issue_labels = แญแแแแแ
+license = แแแชแแแแแ
+readme = README
+default_branch_label = แแแแฃแแแกแฎแแแแ
+mirror_prune = แแแกแฃแคแแแแแแ
+mirror_sync = แกแแแฅแ แแแแแแแฃแแแ
+mirror_password_placeholder = (แแ แจแแชแแแแแ)
+mirror_password_blank_placeholder = (แแแงแแแแแ แแแฃแฅแแแแฃแแแ)
+watchers = แแแงแฃแ แแแแแแ
+stargazers = แแแ แกแแแแแแแแ แแชแฎแแแแแแ
+forks = แคแแ แแแแ
+stars = แแแ แกแแแแแแแแ
+language_other = แกแฎแแ
+delete_preexisting_label = แฌแแจแแ
+desc.private = แแแ แแแ
+desc.public = แกแแฏแแ แ
+desc.template = แแแแฃแจแ
+desc.internal = แจแแแ
+desc.archived = แแแแ แฅแแแแแฃแแ
+desc.sha256 = SHA256
+template.webhooks = แแแแฐแฃแแแแ
+template.topics = แแแแแแ
+template.avatar = แแแแขแแ แ
+need_auth = แแแขแแ แแแแชแแ
+migrate_items_wiki = แแแแ
+migrate_items_milestones = แแแกแแฆแฌแแแ แแแแแแแ
+migrate_items_labels = แญแแแแแ
+migrate_items_issues = แแ แแแแแแแแ
+migrate_items_releases = แ แแแแแแแ
+watch = แแแแแงแฃแ แแก แแแแแแแ
+unwatch = แแแแแงแฃแ แแก แแแแแแแแก แแแฃแฅแแแแ
+star = แแแ แกแแแแแแ
+unstar = แแแ แกแแแแแแแก แแแฎแกแแ
+fork = แคแแ แแ
+code = แแแแ
+branch = แแ แแแฉแ
+tree = แฎแ
+branches = แแ แแแฉแแแ
+tag = แญแแ
+tags = แญแแแแแ
+issues = แแ แแแแแแแแ
+project = แแ แแแฅแขแแแ
+packages = แแแแแขแแแ
+actions = แฅแแแแแแแแ
+release = แ แแแแแ
+releases = แ แแแแแแแ
+labels = แญแแแแแ
+milestones = แแแกแแฆแฌแแแ แแแแแแแ
+org_labels_desc_manage = แแแ แแแ
+commits = แแแแแขแแแ
+commit = แแแแแขแ
+file_raw = แแแฃแแฃแจแแแแแแแ
+file_history = แแกแขแแ แแ
+file_permalink = แแฃแแแแแ แแแฃแแ
+escape_control_characters = แแแแแ แแแแแ
+unescape_control_characters = แแแแแ แแแแแแก แแแฎแกแแ
+vendored = แแแ แแแแ แแแฌแแแแแฃแแ
+generated = แแแแแแแ แแ แแแฃแแ
+commit_graph.monochrome = แแแแ
+commit_graph.color = แคแแ แ
+blame = แกแแแแขแแ แ แฃแคแแแแแแ
+line = แฎแแแ
+lines = แฎแแแแแ
+from_comment = (แแแแแแขแแ แ)
+editor.or = แแ
+editor.cancel_lower = แแแฃแฅแแแแ
+editor.add_tmpl.filename = แคแแแแแก แกแแฎแแแ
+editor.patching = แแแฉแแแ:
+editor.cancel = แแแฃแฅแแแแ
+commits.commits = แแแแแขแแแ
+commits.author = แแแขแแ แ
+commits.message = แจแแขแงแแแแแแแ
+commits.date = แแแ แแฆแ
+commits.older = แฃแคแ แ แซแแแแ
+commits.newer = แฃแคแ แ แแฎแแแ
+commit.operations = แแแแ แแชแแแแ
+commit.revert = แแแแ แฃแแแแ
+commit.cherry-pick = แแฃแกแขแ แแ แฉแแแ
+commitstatus.error = แจแแชแแแแ
+commitstatus.failure = แฉแแแแ แแแ
+commitstatus.pending = แ แแแจแแ
+commitstatus.success = แฌแแ แแแขแแแ
+projects = แแ แแแฅแขแแแ
+projects.description_placeholder = แแฆแฌแแ แ
+projects.title = แกแแแแฃแ แ
+projects.type.none = แแ แชแแ แแ
+projects.template.desc = แแแแฃแจแ
+projects.column.edit_title = แกแแฎแแแ
+projects.column.new_title = แกแแฎแแแ
+projects.column.color = แคแแ แ
+projects.open = แแแฎแกแแ
+projects.close = แแแฎแฃแ แแ
+issues.new.labels = แญแแแแแ
+issues.new.projects = แแ แแแฅแขแแแ
+issues.new.milestone = แแแกแแฆแฌแแแ แแแแแแ
+issues.new.assignees = แแแแแแญแแแแแแ
+issues.choose.open_external_link = แแแฎแกแแ
+issues.choose.blank = แแแแฃแแแกแฎแแแแ
+issues.new_label_desc_placeholder = แแฆแฌแแ แ
+issues.deleted_milestone = `(แฌแแจแแแแแ)`
+issues.deleted_project = `(แฌแแจแแแแแ)`
+issues.filter_label = แญแแ
+issues.filter_milestone = แแแกแแฆแฌแแแ แแแแแแ
+issues.filter_project = แแ แแแฅแขแ
+issues.filter_assignee = แแแแแแญแแแแแ
+issues.filter_poster = แแแขแแ แ
+issues.filter_type = แขแแแ
+issues.filter_sort = แแแแแแแแ
+issues.filter_sort.relevance = แจแแกแแแแแแกแแแ
+issues.filter_sort.latest = แฃแแฎแแแกแ
+issues.filter_sort.oldest = แฃแซแแแแแกแ
+issues.action_open = แแแฎแกแแ
+issues.action_close = แแแฎแฃแ แแ
+issues.action_label = แญแแ
+issues.action_milestone = แแแกแแฆแฌแแแ แแแแแแ
+issues.action_assignee = แแแแแแญแแแแแ
+issues.action_check = แฉแแ แแแ/แแแแแ แแแ
+issues.previous = แฌแแแ
+issues.next = แจแแแแแแ
+issues.open_title = แแแฎแกแแ
+issues.closed_title = แแแฎแฃแ แฃแแ
+issues.all_title = แงแแแแ
+issues.draft_title = แแแแแฎแแแ
+issues.context.edit = แฉแแกแฌแแ แแแ
+issues.context.delete = แฌแแจแแ
+issues.reopen_issue = แแแแแแแ แแแฎแกแแ
+issues.create_comment = แแแแแแขแแ แ
+issues.author = แแแขแแ แ
+issues.role.owner = แแคแแแแแแ
+issues.role.member = แฌแแแ แ
+issues.role.collaborator = แแแแแแแแแฌแแแ
+issues.role.contributor = แแแฎแแแแกแ
+issues.edit = แฉแแกแฌแแ แแแ
+issues.cancel = แแแฃแฅแแแแ
+issues.save = แจแแแแฎแแ
+issues.label_title = แกแแฎแแแ
+issues.label_description = แแฆแฌแแ แ
+issues.label_color = แคแแ แ
+issues.label_exclusive = แแฅแกแแแฃแแแฃแ แ
+issues.label_edit = แฉแแกแฌแแ แแแ
+issues.label_delete = แฌแแจแแ
+issues.label.filter_sort.alphabetically = แแแแแแแก แแแฎแแแแแ
+issues.subscribe = แแแแแฌแแ แ
+issues.unsubscribe = แแแแแฌแแ แแก แแแฃแฅแแแแ
+issues.lock_confirm = แฉแแแแขแแ
+issues.unlock_confirm = แฉแแแแขแแแก แแแฃแฅแแแแ
+issues.delete = แฌแแจแแ
+issues.cancel_tracking = แแแชแแแแแ
+issues.add_time_cancel = แแแฃแฅแแแแ
+issues.add_time_hours = แกแแแแ
+issues.add_time_minutes = แฌแฃแแ
+issues.force_push_compare = แจแแแแ แแแ
+issues.due_date_form = แฌแฌแฌแฌ-แแ-แแ
+issues.due_date_form_edit = แฉแแกแฌแแ แแแ
+issues.due_date_form_remove = แฌแแจแแ
+issues.due_date_overdue = แแแแแชแแแแแฃแแ
+issues.dependency.title = แแแแแแแแแแฃแแแแแแ
+issues.dependency.cancel = แแแฃแฅแแแแ
+issues.dependency.remove = แฌแแจแแ
+issues.dependency.blocks_short = แแแแแแแ
+issues.review.dismissed_label = แแแชแแแแแฃแแแ
+issues.review.pending = แ แแแจแแ
+issues.review.reviewers = แแแแแแฎแแแแแแแ
+issues.review.outdated = แแแแแแแแแชแแแแแฃแแ
+issues.reference_issue.body = แกแฎแแฃแแ
+issues.content_history.deleted = แฌแแจแแแแแ
+issues.content_history.edited = แฉแแกแฌแแ แแแฃแแแ
+issues.content_history.created = แจแแแฅแแแ
+issues.content_history.options = แแแ แแแแ
+compare.compare_base = แแแแ
+compare.compare_head = แจแแแแ แแแ
+pulls.has_viewed_file = แแแแแฎแแ
+pulls.tab_conversation = แกแแฃแแแ แ
+pulls.tab_commits = แแแแแขแแแ
+pulls.merged = แจแแ แฌแงแแฃแแแ
+pulls.status_checks_requested = แแฃแชแแแแแแแแ
+pulls.status_checks_details = แแแขแแแแแ
+pulls.cmd_instruction_checkout_title = แแแแแแฎแแแ
+pulls.cmd_instruction_merge_title = แจแแ แฌแงแแ
+pulls.made_using_agit = AGit
+pulls.editable = แฉแแกแฌแแ แแแแแ
+pull.deleted_branch = (แฌแแจแแแแแ):%s
+milestones.open = แแแฎแกแแ
+milestones.close = แแแฎแฃแ แแ
+milestones.title = แกแแแแฃแ แ
+milestones.desc = แแฆแฌแแ แ
+milestones.clear = แแแกแฃแคแแแแแแ
+milestones.cancel = แแแฃแฅแแแแ
+milestones.filter_sort.name = แกแแฎแแแ
+wiki = แแแแ
+wiki.page = แแแแ แแ
+wiki.new_page = แแแแ แแ
+wiki.cancel = แแแฃแฅแแแแ
+wiki.edit_page_button = แฉแแกแฌแแ แแแ
+wiki.pages = แแแแ แแแแ
+activity = แแฅแขแแแแแ
+activity.navbar.pulse = แฃแแฎแแแกแ แแฅแขแแแแแแแ
+activity.navbar.contributors = แแแฎแแแแกแแแแ
+activity.period.filter_label = แแแ แแแแ:
+activity.overview = แแแแแฎแแแแ
+activity.merged_prs_label = แจแแ แฌแงแแฃแแแ
+activity.opened_prs_label = แจแแแแแแแแแฃแแแ
+activity.closed_issue_label = แแแฎแฃแ แฃแแแ
+activity.new_issue_label = แฆแแแ
+activity.unresolved_conv_label = แแแฎแกแแ
+activity.published_release_label = แ แแแแแ
+activity.published_prerelease_label = แแ แ-แ แแแแแ
+activity.published_tag_label = แญแแ
+activity.git_stats_and_deletions = แแ
+contributors.contribution_type.commits = แแแแแขแแแ
+contributors.contribution_type.additions = แแแแแขแแแแแ
+contributors.contribution_type.deletions = แฌแแจแแแแ
+settings = แแแ แแแแ
+settings.options = แ แแแแแแขแแ แแ
+settings.collaboration = แแแแแแแแแฌแแแแแแ
+settings.collaboration.admin = แแแแแแแกแขแ แแขแแ แ
+settings.collaboration.write = แฉแแฌแแ แ
+settings.collaboration.read = แฌแแแแแฎแแ
+settings.collaboration.owner = แแคแแแแแแ
+settings.collaboration.undefined = แแฆแฃแฌแแ แแแ
+settings.hooks = แแแแฐแฃแแแแ
+settings.mirror_settings.direction = แแแแแ แแฃแแแแ
+settings.mirror_settings.direction.pull = แแแฆแแแ
+settings.mirror_settings.direction.push = แแแแแแแแ
+settings.mirror_settings.push_mirror.none_ssh = แแ แชแแ แแ
+settings.units.units = แแ แแแฃแแแแ
+settings.units.overview = แแแแแฎแแแแ
+settings.site = แแแแแแแ แแ
+settings.tracker_issue_style.numeric = แ แแชแฎแแแแ
+settings.tracker_issue_style.alphanumeric = แแแคแแ แแชแฎแแแแ
+settings.admin_indexer_unindexed = แแ แแแแแแแแฅแกแแแฃแแ
+settings.trust_model.collaborator = แแแแแแแแแฌแแแ
+settings.trust_model.committer = แแแแแแชแแแ
+settings.trust_model.collaboratorcommitter = แแแแแแแแแฌแแแ+แแแแแแชแแแ
+settings.delete_collaborator = แฌแแจแแ
+settings.teams = แแฃแแแแแ
+settings.webhook.request = แแแแฎแแแแ
+settings.webhook.response = แแแแแฎแแแฃแ แแแ
+settings.webhook.headers = แแแแกแแ แแแแ
+settings.webhook.payload = แจแแแชแแแแแแ
+settings.webhook.body = แกแฎแแฃแแ
+settings.secret = แกแแแแฃแแแ
+settings.slack_username = แแแแฎแแแ แแแแแก แกแแฎแแแ
+settings.slack_color = แคแแ แ
+settings.discord_username = แแแแฎแแแ แแแแแก แกแแฎแแแ
+settings.event_create = แจแแฅแแแ
+settings.event_delete = แฌแแจแแ
+settings.event_fork = แคแแ แแ
+settings.event_wiki = แแแแ
+settings.event_release = แ แแแแแ
+settings.event_push = แแแแแแแแ
+settings.event_repository = แ แแแแแแขแแ แแ
+settings.event_issues = แชแแแแแแแ
+settings.event_issue_assign = แแแแแญแแแ
+settings.event_issue_label = แญแแแแแ
+settings.event_issue_milestone = แแแกแแฆแฌแแแ แแแแแแแ
+settings.event_issue_comment = แแแแแแขแแ แแแ
+settings.event_pull_request = แชแแแแแแแ
+settings.event_pull_request_assign = แแแแแญแแแ
+settings.event_pull_request_label = แญแแแแแ
+settings.event_pull_request_milestone = แแแกแแฆแฌแแแ แแแแแแแ
+settings.event_pull_request_comment = แแแแแแขแแ แแแ
+settings.event_pull_request_review = แแแแแฎแแแแแแ
+settings.event_pull_request_sync = แกแแแฅแ แแแแแแแฃแแแ
+settings.event_pull_request_enforcement = แคแแ แกแแ แแแ
+settings.event_package = แแแแแขแ
+settings.active = แแฅแขแแฃแ แแ
+settings.slack_token = แขแแแแแ
+settings.slack_domain = แแแแแแ
+settings.slack_channel = แแ แฎแ
+settings.web_hook_name_gitea = Gitea
+settings.web_hook_name_forgejo = Forgejo
+settings.web_hook_name_gogs = Gogs
+settings.web_hook_name_slack = Slack
+settings.web_hook_name_discord = Discord
+settings.web_hook_name_dingtalk = DingTalk
+settings.web_hook_name_telegram = Telegram
+settings.web_hook_name_matrix = Matrix
+settings.web_hook_name_feishu_only = Feishu
+settings.web_hook_name_packagist = Packagist
+settings.sourcehut_builds.secrets = แกแแแแฃแแแแแแ
+settings.title = แกแแแแฃแ แ
+settings.deploy_key_content = แจแแแชแแแแแแ
+settings.branches = แแ แแแฉแแแ
+settings.protect_status_check_matched = แแแแแฎแแแฃแแ
+settings.protect_patterns = แแแแฃแจแแแ
+settings.edit_protected_branch = แฉแแกแฌแแ แแแ
+settings.tags = แญแแแแแ
+settings.tags.protection.allowed = แแแจแแแแฃแแแ
+settings.lfs = LFS
+settings.lfs_locks = แแแแแแแแ
+settings.lfs_lock = แฉแแแแขแแ
+settings.lfs_pointers.oid = OID
+diff.parent = แแจแแแแแ
+diff.commit = แแแแแขแ
+diff.git-notes = แจแแแแจแแแแแ
+diff.whitespace_button = แฐแแ แ
+diff.bin = BIN
+diff.file_before = แแแแแแแ
+diff.file_after = แจแแแแแ
+diff.file_image_width = แกแแแแแ
+diff.file_image_height = แกแแแแฆแแ
+diff.file_byte_size = แแแแ
+diff.generated = แแแแแ แแ แแแฃแแแ
+diff.vendored = แแแ แแแแ แจแแแแขแแแแแแ
+diff.comment.reply = แแแกแฃแฎแ
+diff.review.comment = แแแแแแขแแ แ
+diff.review.approve = แแแแแกแขแฃแ แแแ
+diff.protected = แแแชแฃแแแ
+diff.image.swipe = แแแฃแกแแแ
+diff.image.overlay = แแแแแแแ แแแแแแ
+release.releases = แ แแแแแแแ
+release.tags = แญแแแแแ
+release.draft = แแแแแฎแแแ
+release.prerelease = แแ แ-แ แแแแแ
+release.stable = แกแขแแแแแฃแ แ
+release.compare = แจแแแแ แแแ
+release.edit = แฉแแกแฌแแ แแแ
+release.target = แกแแแแแแ
+release.cancel = แแแฃแฅแแแแ
+release.downloads = แแแแแแฌแแ แแแ
+release.type_attachment = แแแแแแ แแแฃแแ แคแแแแ
+branch.delete_head = แฌแแจแแ
+branch.included = แฉแแกแแฃแแแ
+topic.done = แแแกแ แฃแแแแ
+
+[graphs]
+contributors.what = แแแฎแแแแกแแแแ
+
+[org]
+members = แฌแแแ แแแ
+teams = แแฃแแแแแ
+code = แแแแ
+lower_members = แฌแแแ แแแ
+lower_repositories = แ แแแแแแขแแ แแแแ
+org_desc = แแฆแฌแแ แ
+team_desc = แแฆแฌแแ แ
+team_permission_desc = แฌแแแแแ
+team_unit_disabled = (แแแแแจแฃแแแ)
+settings = แแแ แแแแ
+settings.options = แแ แแแแแแแชแแ
+settings.website = แแแแแแแ แแ
+settings.location = แแแแแแ แแแแ
+settings.permission = แฌแแแแแแแ
+settings.visibility = แฎแแแแแแแแ
+settings.visibility.public = แกแแฏแแ แ
+settings.visibility.limited_shortname = แจแแแฆแฃแแฃแแ
+settings.visibility.private_shortname = แแแ แแแ
+members.public = แฎแแแฃแแ
+members.private = แแแแแแฃแแ
+members.owner = แแคแแแแแแ
+members.member = แฌแแแ แ
+members.remove = แฌแแจแแ
+members.leave = แแแกแแแ
+teams.join = แจแแแ แแแแ
+teams.leave = แแแกแแแ
+teams.read_access = แฌแแแแแฎแแ
+teams.write_access = แฉแแฌแแ แ
+teams.settings = แแแ แแแแ
+
+[admin]
+dashboard = แกแแแฃแจแแ แแแแแแ
+organizations = แแ แแแแแแแชแแแแ
+repositories = แ แแแแแแขแแ แแแแ
+hooks = แแแแฐแฃแแแแ
+integrations = แแแขแแแ แแชแแแแ
+config = แแแ แแแแ
+config_summary = แจแแฏแแแแแ
+config_settings = แแแ แแแแ
+monitor = แแแแแขแแ แแแแ
+first_page = แแแ แแแแ
+last_page = แแแแ
+dashboard.statistic = แจแแฏแแแแแ
+dashboard.operation_switch = แแแแแ แแแ
+dashboard.operation_run = แแแจแแแแ
+users.name = แแแแฎแแแ แแแแแก แกแแฎแแแ
+users.activated = แแแแฅแขแแฃแ แแแฃแแแ
+users.admin = แแแแแแ
+users.restricted = แจแแแฆแฃแแฃแแ
+users.reserved = แแแชแฃแแ
+users.bot = แแแขแ
+users.remote = แแแจแแ แแแฃแแ
+users.2fa = 2FA
+users.repos = แ แแแแแแ
+users.created = แจแแแฅแแแ
+users.edit = แฉแแกแฌแแ แแแ
+users.local = แแแแแแฃแ แ
+users.list_status_filter.menu_text = แคแแแขแ แ
+users.list_status_filter.reset = แฉแแแแงแ แ
+users.list_status_filter.is_active = แแฅแขแแฃแ แแ
+users.list_status_filter.not_active = แแ แแแฅแขแแฃแ แแ
+users.list_status_filter.is_admin = แแแแแแ
+users.list_status_filter.is_restricted = แจแแแฆแฃแแฃแแ
+emails.primary = แซแแ แแแแแ
+emails.activated = แแแแฅแขแแฃแ แแแฃแแแ
+emails.filter_sort.email = แแแคแแกแขแ
+emails.filter_sort.name = แแแแฎแแแ แแแแแก แกแแฎแแแ
+orgs.name = แกแแฎแแแ
+orgs.teams = แแฃแแแแแ
+orgs.members = แฌแแแ แแแ
+repos.owner = แแคแแแแแแ
+repos.name = แกแแฎแแแ
+repos.private = แแแ แแแ
+repos.issues = แแ แแแแแแแแ
+repos.size = แแแแ
+packages.owner = แแคแแแแแแ
+packages.creator = แจแแแฅแแแแแ
+packages.name = แกแแฎแแแ
+packages.version = แแแ แกแแ
+packages.type = แขแแแ
+packages.repository = แ แแแแแแขแแ แแ
+packages.size = แแแแ
+packages.published = แแแแแฅแแแงแแแแฃแแแ
+auths.name = แกแแฎแแแ
+auths.type = แขแแแ
+auths.enabled = แฉแแ แแฃแแแ
+auths.updated = แแแแแฎแแแแฃแแแ
+auths.domain = แแแแแแ
+auths.host = แฐแแกแขแ
+auths.port = แแแ แขแ
+auths.oauth2_tenant = แขแแแแแขแ
+auths.tips = แ แฉแแแแแ
+config.ssh_enabled = แฉแแ แแฃแแแ
+config.ssh_port = แแแ แขแ
+config.lfs_enabled = แฉแแ แแฃแแแ
+config.db_type = แขแแแ
+config.db_host = แฐแแกแขแ
+config.db_name = แกแแฎแแแ
+config.db_user = แแแแฎแแแ แแแแแก แกแแฎแแแ
+config.db_schema = แกแฅแแแ
+config.db_ssl_mode = SSL
+config.db_path = แแแแแแ
+config.mailer_enabled = แฉแแ แแฃแแแ
+config.mailer_name = แกแแฎแแแ
+config.mailer_protocol = แแ แแขแแแแแ
+config.mailer_user = แแแแฎแแแ แแแแแ
+config.mailer_use_dummy = แกแฃแแแแ
+config.send_test_mail_submit = แแแแแแแแ
+config.oauth_enabled = แฉแแ แแฃแแแ
+config.disabled_logger = แแแแแ แแฃแแแ
+monitor.stats = แกแขแแขแแกแขแแแ
+monitor.name = แกแแฎแแแ
+monitor.schedule = แแแแแ
+monitor.execute_times = แจแแกแ แฃแแแแแแ
+monitor.stacktrace = แกแขแแแแก แแแขแ แแแกแแแ
+monitor.desc = แแฆแฌแแ แ
+monitor.last_execution_result = แจแแแแแ
+monitor.process.children = แจแแแแแแ
+monitor.queues = แ แแแแแ
+monitor.queue.name = แกแแฎแแแ
+monitor.queue.type = แขแแแ
+notices.operations = แแแแ แแชแแแแ
+notices.type = แขแแแ
+notices.type_1 = แ แแแแแแขแแ แแ
+notices.type_2 = แแแแชแแแ
+notices.desc = แแฆแฌแแ แ
+notices.op = แแ.
+
+[action]
+compare_branch = แจแแแแ แแแ
+review_dismissed_reason = แแแแแแ:
+
+[tool]
+now = แแฎแแ
+future = แแแแแแแแจแ
+raw_seconds = แฌแแแ
+raw_minutes = แฌแฃแแ
+
+[munits.data]
+b = แ
+kib = แแแ
+mib = แแแ
+gib = แแแ
+tib = แขแแ
+pib = แแแ
+eib = แแแ
+
+[notification]
+notifications = แแแคแ แแฎแแแแแแแ
+unread = แฌแแแแแฎแฃแแแแแก แแแฃแฅแแแแ
+read = แฌแแแแแฎแแ
+subscriptions = แแแแแฌแแ แแแ
+watching = แฃแงแฃแ แแแ
+
+[units]
+unit = แแ แแแฃแแ
+
+[packages]
+title = แแแแแขแแแ
+filter.type = แขแแแ
+filter.type.all = แงแแแแ
+filter.container.tagged = แญแแแ
+filter.container.untagged = แญแแแแแฎแกแแแแ
+installation = แแแงแแแแแ
+requirements = แแแแฎแแแแแแ
+dependencies = แแแแแแแแแแฃแแแแแแ
+keywords = แกแแแแแแซแ แกแแขแงแแแแ
+details = แแแขแแแแแ
+details.author = แแแขแแ แ
+details.license = แแแชแแแแแ
+assets = แแแแแฅแขแแแ
+versions = แแแ แกแแแแ
+dependency.id = ID
+dependency.version = แแแ แกแแ
+alpine.repository.branches = แแ แแแฉแแแ
+alpine.repository.repositories = แ แแแแแแขแแ แแแแ
+alpine.repository.architectures = แแ แฅแแขแแฅแขแฃแ แแแ
+arch.version.description = แแฆแฌแแ แ
+arch.version.provides = แแแแแฌแแแแ
+arch.version.groups = แฏแแฃแคแ
+arch.version.depends = แแแแแแแแแแฃแแแ
+arch.version.conflicts = แแแแคแแแฅแขแจแแ
+arch.version.replaces = แแแแชแแแแแก
+arch.version.backup = แแแ แฅแแคแ
+composer.dependencies = แแแแแแแแแแฃแแแแแแ
+conan.details.repository = แ แแแแแแขแแ แแ
+container.images.title = แแกแแแก แคแแแแแแ
+container.details.platform = แแแแขแคแแ แแ
+container.digest = แแแแฏแแกแขแ
+container.labels = แญแแแแแ
+container.labels.key = แแแกแแฆแแแ
+container.labels.value = แแแแจแแแแแแแ
+debian.repository.distributions = แแแกแขแ แแแฃแขแแแแแ
+debian.repository.components = แแแแแแแแแขแแแ
+debian.repository.architectures = แแ แฅแแขแแฅแขแฃแ แแแ
+npm.dependencies = แแแแแแแแแแฃแแแแแแ
+npm.details.tag = แญแแ
+rpm.repository.architectures = แแ แฅแแขแแฅแขแฃแ แแแ
+alt.repository.architectures = แแ แฅแแขแแฅแขแฃแ แแแ
+owner.settings.cleanuprules.enabled = แฉแแ แแฃแแแ
+
+[secrets]
+secrets = แกแแแแฃแแแแแแ
+
+[actions]
+actions = แฅแแแแแแแแ
+status.unknown = แฃแชแแแแ
+status.waiting = แแแแแแแแ
+status.running = แแแแแแแแ แแแแก แจแแกแ แฃแแแแ
+status.success = แฌแแ แแแขแแแ
+status.failure = แฉแแแแ แแแ
+status.cancelled = แแแฃแฅแแแแฃแแแ
+status.skipped = แแแแแขแแแแแฃแแแ
+status.blocked = แแแแแแแแแแ
+runners = แแแแกแแแแแแ
+runners.status = แกแขแแขแฃแกแ
+runners.id = ID
+runners.name = แกแแฎแแแ
+runners.owner_type = แขแแแ
+runners.description = แแฆแฌแแ แ
+runners.labels = แญแแแแแ
+runners.runner_title = แแแแจแแแแ
+runners.task_list.run = แแแจแแแแ
+runners.task_list.status = แกแขแแขแฃแกแ
+runners.task_list.repository = แ แแแแแแขแแ แแ
+runners.task_list.commit = แแแแแขแ
+runners.status.unspecified = แฃแชแแแแ
+runners.status.idle = แฃแฅแแ
+runners.status.active = แแฅแขแแฃแ แแ
+runners.status.offline = แฅแกแแแแแ แแจแ
+runners.version = แแแ แกแแ
+runs.commit = แแแแแขแ
+runs.scheduled = แแแแแแแแแแ
+runs.workflow = แจแ แแแแก แแ แแชแแกแ
+runs.actor = แแแขแแ แ
+runs.status = แกแขแแขแฃแกแ
+variables = แชแแแแแแแ
+
+[git.filemode]
+directory = แกแแฅแแฆแแแแ
+submodule = แฅแแแแแแฃแแ
diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini
index 7c8cd2e960..6329dc9fe6 100644
--- a/options/locale/locale_ko-KR.ini
+++ b/options/locale/locale_ko-KR.ini
@@ -43,7 +43,7 @@ admin_panel=์ฌ์ดํธ ๊ด๋ฆฌ
account_settings=๊ณ์ ์ค์
settings=์ค์
your_profile=ํ๋กํ
-your_starred=์ฆ๊ฒจ์ฐพ๊ธฐ
+your_starred=์ข์ํ ์ ์ฅ์
your_settings=์ค์
all=์ ์ฒด
@@ -128,7 +128,7 @@ copy_success = ๋ณต์ฌ๋์์ต๋๋ค!
copy_error = ๋ณต์ฌ ์คํจ
copy_type_unsupported = ์ด ํ์ผ ํ์์ ๋ณต์ฌํ ์ ์์ต๋๋ค
error = ์ค๋ฅ
-error404 = ๋๋ฌํ๋ ค๋ ํ์ด์ง๊ฐ ์กด์ฌํ์ง ์๊ฑฐ๋ ๋ณผ ์ ์๋๋ก ์ธ์ฆ๋์ง ์์์ต๋๋ค .
+error404 = ๋๋ฌํ๋ ค๋ ํ์ด์ง๊ฐ ์กด์ฌํ์ง ์๊ฑฐ๋ , ์ ๊ฑฐ ๋์๊ฑฐ๋ ๋๋ ๋ณผ ๊ถํ์ด ์์ต๋๋ค .
go_back = ๋์๊ฐ๊ธฐ
invalid_data = ์ ํจํ์ง ์๋ ๋ฐ์ดํฐ: %v
unknown = ์ ์ ์์
@@ -158,6 +158,15 @@ filter.private = ๋น๊ณต๊ฐ
filter.not_template = ํ
ํ๋ฆฟ์ด ์๋
view = ๋ณด๊ธฐ
never = ์ํจ
+test = ํ
์คํธ
+copy_path = ๊ฒฝ๋ก ๋ณต์ฌ
+new_repo.link = ์ ์ ์ฅ์
+new_org.link = ์ ์กฐ์ง
+new_repo.title = ์ ์ ์ฅ์
+new_org.title = ์ ์กฐ์ง
+error413 = ์ฌ์ฉ ๊ฐ๋ฅํ ํ ๋น๋์ ๋ชจ๋ ์์งํ์์ต๋๋ค.
+new_migrate.title = ๋ง์ด๊ทธ๋ ์ด์
+new_migrate.link = ์ ๋ง์ด๊ทธ๋ ์ด์
[aria]
navbar = ๋ด๋น๊ฒ์ด์
๋ฐ
@@ -167,10 +176,10 @@ footer.software = ์ด ์ํํธ์จ์ด์ ๋ํ์ฌ
[heatmap]
number_of_contributions_in_the_last_12_months = ์ง๋ 12๋ฌ๊ฐ %s ๋ช
์ ๊ธฐ์ฌ์
-contributions_zero = ๊ธฐ์ฌ ์์
-contributions_format = {year}๋
{month} {day}์ผ์ {contributions}
-contributions_one = ๊ธฐ์ฌ
-contributions_few = ๊ธฐ์ฌ
+contributions_zero = ๊ธฐ์ฌ์ ์์
+contributions_format = {year}๋
{month}์ {day}์ผ์ ๊ธฐ์ฌ์ {contributions}
+contributions_one = ๊ธฐ์ฌ์
+contributions_few = ๊ธฐ์ฌ์
less = ์ ์
more = ๋ง์
@@ -180,10 +189,32 @@ buttons.heading.tooltip = ํค๋ฉ ์ถ๊ฐ
buttons.bold.tooltip = ๋๊บผ์ด ํ
์คํธ ์ถ๊ฐ
buttons.code.tooltip = ์ฝ๋ ์ถ๊ฐ
buttons.link.tooltip = ๋งํฌ ์ถ๊ฐ
+buttons.quote.tooltip = ์ธ์ฉ๊ตฌ ์ถ๊ฐ
+buttons.list.unordered.tooltip = ๋ถ๋ฆฟ ๋ฆฌ์คํธ ์ถ๊ฐ
+buttons.ref.tooltip = ์ด์ ๋๋ ํ ๋ฆฌํ์คํธ ์ฐธ์กฐ
+buttons.list.ordered.tooltip = ๋ฒํธ๋ก ๋ ๋ฆฌ์คํธ ์ถ๊ฐ
+buttons.mention.tooltip = ์ฌ์ฉ์ ๋๋ ํ์ ์ธ๊ธ
+buttons.switch_to_legacy.tooltip = ๋์ ์ ๊ตฌํ ํธ์ง๊ธฐ ์ฌ์ฉ
+buttons.enable_monospace_font = ๊ณ ์ ํญ ๊ธ๊ผด ํ์ฑํ
+buttons.disable_monospace_font = ๊ณ ์ ํญ ๊ธ๊ผด ๋นํ์ฑํ
+buttons.list.task.tooltip = ์์
๋ชฉ๋ก ์ถ๊ฐ
+buttons.new_table.tooltip = ํ
์ด๋ธ ์ถ๊ฐ
+table_modal.header = ํ
์ด๋ธ ์ถ๊ฐ
+table_modal.placeholder.header = ํค๋
+table_modal.placeholder.content = ๋ด์ฉ
+table_modal.label.rows = ํ
+table_modal.label.columns = ์ด
[filter]
+string.desc = ํ - ๊ฐ
+string.asc = ๊ฐ - ํ
[error]
+network_error = ๋คํธ์ํฌ ์ค๋ฅ
+server_internal = ๋ด๋ถ ์๋ฒ ์ค๋ฅ
+not_found = ํ๊ฒ์ ์ฐพ์ ์ ์์ต๋๋ค.
+occurred = ์๋ฌ๊ฐ ๋ฐ์ํจ
+report_message = ์ด๊ฒ์ด Forgejo์ ๋ฒ๊ทธ๋ผ๊ณ ์๊ฐํ๋ค๋ฉด, Codeberg ์์ ์ด์๋ฅผ ๊ฒ์ํ๊ฑฐ๋ ํ์ํ๋ค๋ฉด ์ ์ด์๋ฅผ ๋ง๋ค์ด์ฃผ์ธ์.
[startpage]
app_desc=ํธ๋ฆฌํ ์ค์นํ Git ์๋น์ค
@@ -191,6 +222,10 @@ install=์ฌ์ด ์ค์น
platform=ํฌ๋ก์ค ํ๋ซํผ
lightweight=๊ฐ๋ฒผ์
license=์คํ ์์ค
+platform_desc = Forgejo๋ Linux์ FreeBSD๋ฑ์ ์์ ์คํ์์ค ์ด์ ์ฒด์ ๋ฅผ ํฌํจํ ๋ค์ํ CPU ์ํคํ
์ฒ์์ ์คํ๋ฉ๋๋ค. ๋ง์ ๊ฐ๋๋๋ก ๊ณ ๋ฅด์ธ์!
+lightweight_desc = Forgejo์ ๋ฎ์ ์ ๋ ฅ ์๋ชจ๋์ ๊ฐ์ผ Raspberry Pi๋ง์ ๊ตฌ๋ํ ์ ์๊ฒ ํฉ๋๋ค. ๊ธฐ๊ธฐ์ ์๋์ง๋ฅผ ์ ์ฝํ์ธ์!
+license_desc = Forgejo ๋ฅผ ์ค์นํด๋ณด์ธ์! Forgejo๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด ๊ธฐ์ฌ ํ ์ ์์ต๋๋ค. ๊ธฐ์ฌ์๊ฐ ๋๊ธฐ๋ฅผ ๋ง์ค์ด์ง ๋ง์ธ์!
+install_desc = ๊ฐ๋จํ ๋น์ ์ ๊ธฐ๊ธฐ์์๋ฐ์ด๋๋ฆฌ๋ฅผ ์คํํ๊ฑฐ๋ , Docker ๋ฅผ ์ฌ์ฉํ๊ฑฐ๋, ํจํค์ง ์ ์ฅ์ ์์ ์ค์นํ ์ ์์ต๋๋ค.
[install]
install=์ค์น
@@ -199,7 +234,7 @@ docker_helper=Forgejo๋ฅผ Docker์์ ์คํํ๋ ค๋ฉด ์ค์ ์ ์ ์ด ํ์์ผ๋ก ์
๋ ฅํ์ธ์.
-mailer_user=SMTP ์ฌ์ฉ์์ด๋ฆ
+mailer_user=SMTP ์ฌ์ฉ์๋ช
mailer_password=SMTP ๋น๋ฐ๋ฒํธ
register_confirm=๊ฐ์
์ ์ด๋ฉ์ผ ํ์ธ ํ์
mail_notify=์ด๋ฉ์ผ ์๋ฆผ ์ผ๊ธฐ
server_service_title=์๋ฒ ๋ฐ ๊ธฐํ ์๋น์ค ์ค์
offline_mode=๋ก์ปฌ ๋ชจ๋ ์ผ๊ธฐ
-offline_mode.description=ํ์ฌ ์ฝํ
์ธ ์ ์ก ๋คํธ์ํฌ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ก ์ค์ ํ๊ณ ๋ชจ๋ ๋ฆฌ์์ค๋ฅผ ๋ก์ปฌ๋ก ์ ๊ณตํ์ญ์์ค.
+offline_mode.description=ํ์ฌ ์ฝํ
์ธ ์ ์ก ๋คํธ์ํฌ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ก ์ค์ ํ๊ณ ๋ชจ๋ ๋ฆฌ์์ค๋ฅผ ๋ก์ปฌ์์ ์ ๊ณตํฉ๋๋ค.
disable_gravatar=Gravatar ์ฌ์ฉ์ํจ
-disable_gravatar.description=Gravatar ๋ฐ ํ์ฌ ์๋ฐํ ์์ค๋ฅผ ์ฌ์ฉํ์ง ์๋๋ก ์ค์ ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ๋ก์ปฌ๋ก ์๋ฐํ๋ฅผ ์
๋ก๋ํ์ง ์๋ ํ ๊ธฐ๋ณธ ์๋ฐํ๊ฐ ์ฌ์ฉ๋ฉ๋๋ค.
+disable_gravatar.description=Gravatar๋ฅผ ๋น๋กฏํ ํ์ฌ ์๋ฐํ ์ถ์ฒ๋ฅผ ์ฌ์ฉํ์ง ์๋๋ก ์ค์ ํฉ๋๋ค. ์ฌ์ฉ์๊ฐ ์ง์ ์๋ฐํ๋ฅผ ์
๋ก๋ํ์ง ์๋ ํ ๊ธฐ๋ณธ ์๋ฐํ๋ฅผ ์ฌ์ฉํฉ๋๋ค.
federated_avatar_lookup=ํ์ค์ํ ์๋ฐํ ์ฌ์ฉ
-federated_avatar_lookup.description=libravatar ๊ธฐ๋ฐ ์คํ์์ค ์ฐํฉ ์๋ฐํ ์กฐํ๋ฅผ ํ์ฉํฉ๋๋ค.
+federated_avatar_lookup.description=Libravatar ์๋ฐํ๋ฅผ ์กฐํํฉ๋๋ค.
disable_registration=์ฌ์ฉ์ ๋ฑ๋ก ๋นํ์ฑํ
-disable_registration.description=์ฌ์ฉ์๊ฐ ์ง์ ๋ฑ๋กํ ์ ์๊ฒ ํฉ๋๋ค. ๊ด๋ฆฌ์๋ง์ด ์ถ๊ฐํ ์ ์์ต๋๋ค.
-allow_only_external_registration.description=์ธ๋ถ ์๋น์ค๋ฅผ ํตํ ๋ฑ๋ก์ ํ์ฉ
+disable_registration.description=์ธ์คํด์ค ๊ด๋ฆฌ์๋ง์ด ์ ์ฌ์ฉ์ ๊ณ์ ์ ์ถ๊ฐํ ์ ์๊ฒ ๋ฉ๋๋ค. ๊ณต๊ฐ ์ธ์คํด์ค๋ฅผ ์ ๊ณตํ ์์ ์ด๊ณ ๋ง์ ์์ ์คํธ ๊ณ์ ์ ๊ฐ๋นํ ์ค๋น๊ฐ ๋์ด ์์ง ์๋ค๋ฉด ์ฌ์ฉ์ ๋ฑ๋ก์ ๋นํ์ฑํ ํ ๊ฒ์ ๊ฐ๋ ฅํ ๊ถ๊ณ ํฉ๋๋ค.
+allow_only_external_registration.description=์ ๊ณ์ ์ ๋ฑ๋กํ๋ ค๋ ์ฌ์ฉ์๋ ์ค์ ๋ ์ธ๋ถ ์๋น์ค๋ฅผ ์ด์ฉํด์ผ๋ง ์ ๊ณ์ ์ ๋ฑ๋กํ ์ ์์ต๋๋ค.
openid_signin=OpenID ๋ก๊ทธ์ธ ์ฌ์ฉ
-openid_signin.description=OpenID ๋ฅผ ์ด์ฉํ ๋ก๊ทธ์ธ์ ํ์ฉํฉ๋๋ค.
+openid_signin.description=OpenID๋ฅผ ์ด์ฉํ ๋ก๊ทธ์ธ์ ํ์ฉํฉ๋๋ค.
openid_signup=OpenID ๊ฐ์
ํ์ฉ
openid_signup.description=OpenID๋ฅผ ํตํ ๊ฐ์
์ ํ์ฉํฉ๋๋ค.
enable_captcha.description=์ฌ์ฉ์ ๋ฑ๋ก์ ์บก์ฐจ๋ฅผ ์๊ตฌํฉ๋๋ค.
require_sign_in_view=์ธ์คํด์ค์ ์ฝํ
์ธ ๋ฅผ ๋ณผ๋ ๋ก๊ทธ์ธ ์๊ตฌ
admin_setting.description=๊ด๋ฆฌ์ ๊ณ์ ์ ๋ง๋๋ ๊ฒ์ ์ ํ์ฌํญ์
๋๋ค. ์ฒซ๋ฒ์งธ๋ก ๋ฑ๋ก๋ ์ฌ์ฉ์๋ ์๋์ ์ผ๋ก ๊ด๋ฆฌ์๋ก ์ง์ ๋ฉ๋๋ค.
admin_title=๊ด๋ฆฌ์ ๊ณ์ ์ค์
-admin_name=๊ด๋ฆฌ์ ์ด๋ฆ
+admin_name=๊ด๋ฆฌ์์ ์ฌ์ฉ์๋ช
admin_password=๋น๋ฐ๋ฒํธ
confirm_password=๋น๋ฐ๋ฒํธ ํ์ธ
admin_email=์ด๋ฉ์ผ ์ฃผ์
@@ -267,21 +302,37 @@ test_git_failed='git' ๋ช
๋ น ํ
์คํธ ์คํจ: %v
sqlite3_not_available=ํด๋น ๋ฒ์ ์์๋ SQLite3๋ฅผ ์ง์ํ์ง ์์ต๋๋ค. %s์์ ๊ณต์ ๋ฒ์ ์ ๋ค์ด๋ก๋ํด์ฃผ์ธ์. ('gobuild' ๋ฒ์ ์ด ์๋๋๋ค).
invalid_db_setting=๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค์ ์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค: %v
invalid_repo_path=์ ์ฅ์(๋ ํ์งํ ๋ฆฌ) ์ ๊ฒฝ๋ก๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค: %v
-run_user_not_match=์คํ ์ฌ์ฉ์๋ช
์ด ํ์ฌ ์ฌ์ฉ์๋ช
๊ณผ ๋ค๋ฆ
๋๋ค: %s -> %s
+run_user_not_match="์คํ ์ฌ์ฉ์๋ช
"์ด ํ์ฌ ์ฌ์ฉ์๋ช
๊ณผ ๋ค๋ฆ
๋๋ค: %s -> %s
save_config_failed=์ค์ ์ ์ ์ฅํ ์ ์์ต๋๋ค: %v
invalid_admin_setting=๊ด๋ฆฌ์ ๊ณ์ ์ค์ ์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค: %v
invalid_log_root_path=๋ก๊ทธ(Log) ์ ๊ฒฝ๋ก๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค: %v
default_keep_email_private=์ด๋ฉ์ผ ์ฃผ์ ์จ๊น์ฒ๋ฆฌ๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์
-default_keep_email_private.description=์ ์ฌ์ฉ์์ ๋ํ ์ด๋ฉ์ผ ์ฃผ์ ์จ๊น์ฒ๋ฆฌ๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ ํฉ๋๋ค.
+default_keep_email_private.description=์ ์ฌ์ฉ์์ ๋ํ ์ด๋ฉ์ผ ์ฃผ์ ์จ๊น์ฒ๋ฆฌ๋ฅผ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ ํด ๊ฐ์
์งํ ์ ๋ณด๊ฐ ์ ์ถ๋๋๊ฒ์ ๋ฐฉ์งํฉ๋๋ค.
default_allow_create_organization=์กฐ์ง ์์ฑ ํ์ฉ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์
-default_allow_create_organization.description=์ ๊ท ์ฌ์ฉ์ ์์ฑ์ ์กฐ์ง ์์ฑ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ ํฉ๋๋ค.
-default_enable_timetracking=์๊ฐ ์ถ์ ์ฌ์ฉ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์
-default_enable_timetracking.description=์ ๊ท ๋ ํฌ์งํ ๋ฆฌ์ ๋ํ ์๊ฐ ์ถ์ ์ฌ์ฉ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ค์ ํฉ๋๋ค.
+default_allow_create_organization.description=์ ๊ท ์ฌ์ฉ์์๊ฒ ๊ธฐ๋ณธ์ ์ผ๋ก ์กฐ์ง ์์ฑ ๊ถํ์ ๋ถ์ฌํฉ๋๋ค. ์ด ์ต์
์ด ๊บผ์ ธ์๋ค๋ฉด, ๊ด๋ฆฌ์๊ฐ ์ ๊ท ์ฌ์ฉ์์๊ฒ ์กฐ์ง ์์ฑ ๊ถํ์ ๋ถ์ฌํด์ผํฉ๋๋ค.
+default_enable_timetracking=์๊ฐ ๊ธฐ๋ก ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉ
+default_enable_timetracking.description=์ ๊ท ์ ์ฅ์๊ฐ ์๊ฐ๊ธฐ๋ก ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
no_reply_address=๊ฐ๋ ค์ง ์ด๋ฉ์ผ ๋๋ฉ์ธ
-no_reply_address_helper=๊ฐ๋ ค์ง ์ด๋ฉ์ผ์ ๊ฐ์ง ์ฌ์ฉ์์๊ฒ ์ ์ฉ๋ ์ด๋ฉ์ผ ๋๋ฉ์ธ์
๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์ 'joe'์ ๊ฐ๋ ค์ ์ด๋ฉ์ผ ๋๋ฉ์ธ์ด 'noreply.example.org'๋ก ์ค์ ๋์ด ์์ผ๋ฉด 'joe@noreply.example.org'๋ก ์ฒ๋ฆฌ ๋ฉ๋๋ค.
+no_reply_address_helper=์ด๋ฉ์ผ์ ๊ฐ๋ฆฐ ์ฌ์ฉ์์๊ฒ ์ ์ฉ๋ ์ด๋ฉ์ผ ๋๋ฉ์ธ์
๋๋ค. ์๋ฅผ ๋ค์ด, ์ฌ์ฉ์๋ช
'joe'๊ฐ ๋๋ฉ์ธ'noreply.example.org'๋ก ์ด๋ฉ์ผ์ ๊ฐ๋ฆฌ๋ฉด Git์ 'joe@noreply.example.org'๋ก ๋ก๊ทธ์ธ ํ๊ฒ ๋ฉ๋๋ค.
+db_schema_helper = ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ธฐ๋ณธ๊ฐ ("๊ณต๊ฐ")๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ๋น ์นธ์ผ๋ก ๋์ธ์.
+require_db_desc = Forgejo๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด MySQL, PostgreSQL, SQLite3 ๋๋ TiDB (MySQL ํ๋กํ ์ฝ) ์ด ์ค์น๋์ด ์์ด์ผ ํฉ๋๋ค.
+domain = ์๋ฒ ๋๋ฉ์ธ
+smtp_from_invalid = "์ด๋ฉ์ผ ๋ฐ์ ์ธ" ์ฃผ์๊ฐ ์ ํจํ์ง ์์ต๋๋ค
+enable_captcha = ๋ฑ๋ก ์ CAPTCHA ํ์ฑํ
+allow_only_external_registration = ์ธ๋ถ ์๋น์ค๋ฅผ ํตํ ๋ฑ๋ก๋ง ํ์ฉ
+reinstall_confirm_check_3 = Forgejo๊ฐ ์ฌ๋ฐ๋ฅธ app.ini ์์น๋ก ์คํ์ค์ด๋ฉฐ ๊ทธ๊ฒ์ด ๋ค์ ์ค์นํ ๋์์ด ๋ง๋ค๋๊ฒ์ ์ ์ ์ผ๋ก ํ์ ํฉ๋๋ค. ์์ ์ํ์ฑ๋ค์ ์ธ์งํ๊ณ ์์์ ๋์ํฉ๋๋ค.
+reinstall_error = ์ด๋ฏธ ์กด์ฌํ๋ Forgejo ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ค์น๋ฅผ ์๋์ค์
+reinstall_confirm_message = ์ด๋ฏธ ์กด์ฌํ๋ Forgejo ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฌ์ค์น๋ฅผ ํ๋๊ฒ์ ๋ค์์ ๋ฌธ์ ์ ์์ธ์ด ๋ ์ ์์ต๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ด๋ฏธ ์กด์ฌํ๋ "app.ini" ๋ฅผ ์ฌ์ฉํด Forgejo๋ฅผ ๊ตฌ๋ํด์ผํฉ๋๋ค. ๋น์ ์ด ๋ฌด์์ ํ๊ณ ์๋์ง ๋ช
ํํ ์๊ณ ์๋ค๋ฉด ๋ค์ ์ฌํญ๋ค์ ํ์ธํ์ธ์:
+err_admin_name_pattern_not_allowed = ๊ด๋ฆฌ์์ ์ฌ์ฉ์๋ช
์ด ์ฌ๋ฐ๋ฅด์ง ์์, ์ฌ์ฉ์๋ช
์ด ์์ฝ๋ ํจํด๊ณผ ์ผ์นํจ
+allow_dots_in_usernames = ์ฌ์ฉ์๋ค์ด ๋ง์นจํ๋ฅผ ์ฌ์ฉ์๋ช
์ ์ฌ์ฉํ ์ ์๋๋ก ํ๊ฐํฉ๋๋ค. ์ด๋ฏธ ์กด์ฌํ๋ ๊ณ์ ์๋ ์ํฅ์ ์ฃผ์ง ์์ต๋๋ค.
+app_slogan = ์ธ์คํด์ค ์ฌ๋ก๊ฑด
+app_slogan_helper = ์ธ์คํด์ค์ ์ฌ๋ก๊ฑด์ ์
๋ ฅํ์ธ์. ๋น์๋๋ฉด ๋นํ์ฑํ๋ฉ๋๋ค.
+reinstall_confirm_check_1 = app.ini์ SECRET_KEY๋ก ์ํธํ ๋์ด์๋ ๋ฐ์ดํฐ๋ฅผ ์์ ์ ์์ต๋๋ค: 2FA/OTP๋ฅผ ํตํด ๋ก๊ทธ์ธ ํ ์ ์์ผ๋ฉฐ & ๋ฏธ๋ฌ๊ฐ ์ ๋๋ก ์๋ํ์ง ์๊ฒ๋ฉ๋๋ค. app.ini ํ์ผ์ ์ ํํ SECRET_KEY๊ฐ ์๋๊ฒ์ด ํ์คํ๋ค๋ฉด ์ฒดํฌํ์ธ์.
+run_user_helper = Forgejo๋ฅผ ๊ตฌ๋ํ๋ ์ด์์ฒด์ ์ ์ฌ์ฉ์๋ช
์
๋๋ค. ์ด ์ฌ์ฉ์๋ ์ ์ฅ์ ๋ฃจํธ ๊ฒฝ๋ก์ ์ ๊ทผ๊ถํ์ด ์์ด์ผ ํฉ๋๋ค.
+reinstall_confirm_check_2 = ์ ์ฅ์์ ์ค์ ์ ์ฌ๋๊ธฐํ๊ฐ ์๊ตฌ๋ ์ ์์ต๋๋ค. ์ด ๋ฐ์ค์ ์ฒดํฌํ๋ฉด ์ ์ฅ์์ ํ
๊ณผ authorized_key ๋ค์ ์๋์ผ๋ก ์ฌ๋๊ธฐํํด์ผ ํ๋ค๋ ๊ฒ์ ์ธ์งํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ ์ฅ์์ ๋ฏธ๋ฌ์ ์ค์ ์ด ์ฌ๋ฐ๋ฅธ์ง ํ์ธํ์ธ์.
[home]
-uname_holder=์ฌ์ฉ์ ์ด๋ฆ ๋๋ ์ด๋ฉ์ผ ์ฃผ์
+uname_holder=์ฌ์ฉ์๋ช
๋๋ ์ด๋ฉ์ผ ์ฃผ์
password_holder=๋น๋ฐ๋ฒํธ
switch_dashboard_context=๋์๋ณด๋ ์ปจํ
์คํธ ๋ฐ๊พธ๊ธฐ
my_repos=์ ์ฅ์
@@ -307,6 +358,8 @@ repo_no_results=์ผ์นํ๋ ๋ ํฌ์งํ ๋ฆฌ๊ฐ ์์ต๋๋ค.
user_no_results=์ผ์นํ๋ ์ฌ์ฉ์๊ฐ ์์ต๋๋ค.
org_no_results=์ผ์นํ๋ ์กฐ์ง์ด ์์ต๋๋ค.
code_no_results=๊ฒ์์ด์ ์ผ์นํ๋ ์์ค์ฝ๋๊ฐ ์์ต๋๋ค.
+stars_one = %d ์ข์์
+stars_few = %d ์ข์์
[auth]
create_new_account=๊ณ์ ๋ฑ๋ก
@@ -323,7 +376,7 @@ allow_password_change=์ฌ์ฉ์์๊ฒ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ์ ์์ฒญ (๊ถ์ฅ๋จ)
reset_password_mail_sent_prompt=ํ์ธ ๋ฉ์ผ์ด %s ๋ก ์ ์ก๋์์ต๋๋ค. ๋ฐ์ ํธ์งํจ์ผ๋ก ๋์ฐฉํ ๋ฉ์ผ์ %s ์์ ํ์ธํด์ ๋น๋ฐ๋ฒํธ ์ฐพ๊ธฐ ์ ์ฐจ๋ฅผ ์๋ฃํ์ญ์์ค.
active_your_account=๊ณ์ ํ์ฑํ
account_activated=๊ณ์ ์ด ํ์ฑํ ๋์์ต๋๋ค
-prohibit_login=
+prohibit_login =
resent_limit_prompt=ํ์ฑํ๋ฅผ ์ํ ์ด๋ฉ์ผ์ ์ด๋ฏธ ์ ์กํ์ต๋๋ค. 3๋ถ ๋ด๋ก ์ด๋ฉ์ผ์ ๋ฐ์ง ๋ชปํ ๊ฒฝ์ฐ ์ฌ์๋ํด์ฃผ์ธ์.
has_unconfirmed_mail=์๋
ํ์ธ์ %s, ์ด๋ฉ์ผ ์ฃผ์(%s )๊ฐ ํ์ธ๋์ง ์์์ต๋๋ค. ํ์ธ ๋ฉ์ผ์ ๋ฐ์ผ์์ง ๋ชปํ๊ฒผ๊ฑฐ๋ ์๋ก์ด ํ์ธ ๋ฉ์ผ์ด ํ์ํ๋ค๋ฉด, ์๋ ๋ฒํผ์ ํด๋ฆญํด ์ฌ๋ฐ์กํ์ค ์ ์์ต๋๋ค.
resend_mail=์ฌ๊ธฐ๋ฅผ ๋๋ฌ ํ์ธ ๋ฉ์ผ ์ฌ์ ์ก
@@ -360,17 +413,28 @@ authorization_failed=์ธ์ฆ ์คํจ
sspi_auth_failed=SSPI ์ธ์ฆ ์คํจ
[mail]
-
activate_account=๊ณ์ ์ ํ์ฑํํ์ธ์
activate_email=์ด๋ฉ์ผ ์ฃผ์ ํ์ธ
-register_notify=Forgejo์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค
+register_notify=%s์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค
reset_password=๊ณ์ ๋ณต๊ตฌ
register_success=๋ฑ๋ก ์๋ฃ
issue.action.close = @%[1]s ๋์ด #%[2]d๋ฅผ ๋ซ์์ต๋๋ค.
+release.new.text = @%[1]s ๋์ด %[2]s๋ฅผ %[3]s์ ์ถ์ํจ
+issue.action.push_n = @%[1]s ๋์ด %[3]d๊ฐ์ ์ปค๋ฐ์ %[2]s์ ํธ์ํจ
+issue.action.reopen = @%[1]s ๋์ด #%[2]d๋ฅผ ๋ค์ ์ด์์ต๋๋ค.
+issue.action.approve = @%[1]s ๋์ด ์ด ํ ๋ฆฌํ์คํธ๋ฅผ ์น์ธํ์ต๋๋ค.
+issue.action.review = @%[1]s ๋์ด ์ด ํ ๋ฆฌํ์คํธ์ ์ปค๋ฐํ์ต๋๋ค.
+issue.action.ready_for_review = @%[1]s ๋์ด ์ด ํ ๋ฆฌํ์คํธ๋ฅผ ๊ฒํ ํ๊ธฐ ์ ํฉํ๋ค ํ์ํ์ต๋๋ค.
+issue.action.push_1 = @%[1]s ๋์ด %[3]d๊ฐ์ ์ปค๋ฐ์ %[2]s์ ํธ์ํจ
+issue.action.merge = @%[1]s ๋์ด #%[2]d๋ฅผ %[3]s์ ๋ณํฉํ์ต๋๋ค.
+issue.action.review_dismissed = @%[1]s ๋์ด ์ด ํ ๋ฆฌํ์คํธ์ ๋ํ %[2]s์ ๋ง์ง๋ง ๊ฒํ ๋ฅผ ๊ฑฐ๋ถํ์ต๋๋ค.
+issue.action.reject = @%[1]s ๋์ด ์ด ํ ๋ฆฌํ์คํธ์ ์์ ์ ์์ฒญํ์ต๋๋ค.
+issue.action.new = @%[1]s ๋์ด #%[2]d๋ฅผ ๋ง๋ค์์ต๋๋ค.
+register_notify.text_2 = ๋น์ ์ ๊ณ์ ์ ์ฌ์ฉ์๋ช
์ผ๋ก ๋ก๊ทธ์ธ ํ ์ ์์ต๋๋ค: %s
@@ -385,8 +449,8 @@ cancel=์ทจ์
modify=๋ณ๊ฒฝํ๊ธฐ
[form]
-UserName=์ฌ์ฉ์ ์ด๋ฆ
-RepoName=์ ์ฅ์ ์ด๋ฆ
+UserName=์ฌ์ฉ์๋ช
+RepoName=์ ์ฅ์๋ช
Email=์ด๋ฉ์ผ ์ฃผ์
Password=๋น๋ฐ๋ฒํธ
Retype=๋น๋ฐ๋ฒํธ ํ์ธ
@@ -420,14 +484,14 @@ captcha_incorrect=CAPTCHA ์ฝ๋๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค.
password_not_match=๋น๋ฐ๋ฒํธ๊ฐ ์ผ์นํ์ง ์์ต๋๋ค.
lang_select_error=๋ชฉ๋ก์์ ์ธ์ด๋ฅผ ์ ํํด์ฃผ์ธ์.
-username_been_taken=์ด๋ฏธ ์ฌ์ฉํ๊ณ ์๋ ์์ด๋์
๋๋ค.
-repo_name_been_taken=์ด๋ฏธ ์ฌ์ฉํ๊ณ ์๋ ์ ์ฅ์ ์ด๋ฆ์
๋๋ค.
+username_been_taken=์ด๋ฏธ ์ฌ์ฉ๋๋ ์ฌ์ฉ์๋ช
์
๋๋ค.
+repo_name_been_taken=์ด๋ฏธ ์ฌ์ฉ์ค์ธ ์ ์ฅ์๋ช
์
๋๋ค.
org_name_been_taken=์ด๋ฏธ ์ฌ์ฉ์ค์ธ ์กฐ์ง ์ด๋ฆ์
๋๋ค.
team_name_been_taken=์ด๋ฏธ ์ฌ์ฉ์ค์ธ ํ ์ด๋ฆ์
๋๋ค.
team_no_units_error=์ต์ ํ๋ ์ด์์ ๋ ํฌ์งํ ๋ฆฌ ์น์
์ ๋ํ ์ ๊ทผ์ ํ์ฉํ์ญ์์ค.
email_been_used=์ด๋ฏธ ์ฌ์ฉ ์ค์ธ ์ด๋ฉ์ผ ์ฃผ์์
๋๋ค.
-username_password_incorrect=์ฌ์ฉ์ ์ด๋ฆ ๋๋ ์ํธ๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค.
-enterred_invalid_repo_name=์
๋ ฅํ ์ ์ฅ์์ ์ด๋ฆ์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค.
+username_password_incorrect=์ฌ์ฉ์๋ช
๋๋ ์ํธ๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค.
+enterred_invalid_repo_name=์
๋ ฅํ ์ ์ฅ์๋ช
์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค.
enterred_invalid_owner_name=์๋ก์ด ์์ ์ ์ด๋ฆ์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค.
enterred_invalid_password=์
๋ ฅํ ๋น๋ฐ๋ฒํธ๋ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค.
user_not_exist=์กด์ฌํ์ง ์๋ ์ฌ์ฉ์์
๋๋ค.
@@ -443,8 +507,10 @@ target_branch_not_exist=๋์ ๋ธ๋์น๊ฐ ์กด์ฌํ์ง ์์ต๋๋ค.
url_error = `"%s"๋ ์ ํจํ URL์ด ์๋๋๋ค.`
include_error = `"%s"์/๋ฅผ ํฌํจํด์ผ ํฉ๋๋ค.`
regex_pattern_error = `regex ํจํด์ด ์๋ชป๋์์ต๋๋ค: %s`
-username_error = `์๋ฌธ("a-z", "A-Z"), ์ซ์("0-9"), ๋์("-"), ๋ฐ์ค("_"), ์ (".")๋ง ํฌํจํ ์ ์์ต๋๋ค. ์๋ฌธ ํน์ ์ซ์๊ฐ ์๋ ๋ฌธ์๋ก ์์ํ๊ฑฐ๋ ๋๋ ์ ์์ผ๋ฉฐ ์ฐ์๋ ์๋ฌธ ํน์ ์ซ์๊ฐ ์๋ ๋ฌธ์๋ ๊ธ์ง๋ฉ๋๋ค.`
+username_error = `์๋ฌธ("a-z", "A-Z"), ์ซ์("0-9"), ๋์("-"), ๋ฐ์ค("_"), ๋ง์นจํ(".")๋ง ํฌํจํ ์ ์์ต๋๋ค. ์๋ฌธ ํน์ ์ซ์๊ฐ ์๋ ๋ฌธ์๋ก ์์ํ๊ฑฐ๋ ๋๋ ์ ์์ผ๋ฉฐ ์ฐ์๋ ์๋ฌธ ํน์ ์ซ์๊ฐ ์๋ ๋ฌธ์๋ ๊ธ์ง๋ฉ๋๋ค.`
glob_pattern_error = `glob ํจํด์ด ์๋ชป๋์์ต๋๋ค: %s`
+username_error_no_dots = `์๋ฌธ("a-z", "A-Z"), ์ซ์("0-9"), ๋์("-"), ๋ฐ์ค("_")๋ง ํฌํจํ ์ ์์ต๋๋ค. ์๋ฌธ ํน์ ์ซ์๊ฐ ์๋ ๋ฌธ์๋ก ์์ํ๊ฑฐ๋ ๋๋ ์ ์์ผ๋ฉฐ ์ฐ์๋ ์๋ฌธ ํน์ ์ซ์๊ฐ ์๋ ๋ฌธ์๋ ๊ธ์ง๋ฉ๋๋ค.`
+username_change_not_local_user = ์ธ๋ถ ์ฌ์ฉ์๋ค์ ์ฌ์ฉ์๋ช
์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
[user]
@@ -452,7 +518,7 @@ change_avatar=์๋ฐํ ๋ณ๊ฒฝโฆ
repositories=์ ์ฅ์
activity=๊ณต๊ฐ ํ๋
followers_few=%d ํ๋ก์
-starred=๊ด์ฌ์๋ ์ ์ฅ์
+starred=์ข์ํ๋ ์ ์ฅ์
overview=๊ฐ์
following_few=%d ํ๋ก์ฐ ์ค
follow=์ถ์ ํ๊ธฐ
@@ -460,6 +526,9 @@ unfollow=์ถ์ ํด์
user_bio=์๊ฐ
projects = ํ๋ก์ ํธ
watched = ์ฃผ์์ค์ธ ์ ์ฅ์
+form.name_reserved = "%s" ์ฌ์ฉ์๋ช
์ด ์์ฝ(reserved)๋์์ต๋๋ค.
+form.name_pattern_not_allowed = "%s" ํจํด์ด ์ฌ์ฉ์๋ช
์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
+form.name_chars_not_allowed = "%s" ์ฌ์ฉ์๋ช
์ด ์ ํจํ์ง ์์ ๋ฌธ์๋ฅผ ํฌํจํฉ๋๋ค.
[settings]
@@ -479,14 +548,14 @@ account_link=์ฐ๊ฒฐ๋ ๊ณ์
organization=์กฐ์ง
public_profile=๊ณต๊ฐ ํ๋กํ
-password_username_disabled=๋ก์ปฌ ์ฌ์ฉ์๊ฐ ์๋ ๊ฒฝ์ฐ ์ฌ์ฉ์ ์ด๋ฆ ๋ณ๊ฒฝ์ ํ ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ๊ด๋ฆฌ์์๊ฒ ๋ฌธ์ํด์ฃผ์ธ์.
+password_username_disabled=๋ก์ปฌ ์ฌ์ฉ์๊ฐ ์๋ ๊ฒฝ์ฐ ์ฌ์ฉ์๋ช
์ ๋ณ๊ฒฝ ํ ์ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ๊ด๋ฆฌ์์๊ฒ ๋ฌธ์ํด์ฃผ์ธ์.
full_name=์ฑ๋ช
website=์น ์ฌ์ดํธ
location=์์น
update_theme=ํ
๋ง ๋ณ๊ฒฝ
update_profile=ํ๋กํ ์
๋ฐ์ดํธ
update_profile_success=ํ๋กํ์ด ์
๋ฐ์ดํธ ๋์์ต๋๋ค.
-change_username=์ฌ์ฉ์ ์ด๋ฆ ๋ณ๊ฒฝ ๋์์ต๋๋ค.
+change_username=์ฌ์ฉ์๋ช
์ด ๋ณ๊ฒฝ ๋์์ต๋๋ค.
continue=๊ณ์ํ๊ธฐ
cancel=์ทจ์
language=์ธ์ด
@@ -637,11 +706,14 @@ visibility.private=๋น๊ณต๊ฐ
change_password = ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ
email_desc = ๋น์ ์ ๋ํ ์ด๋ฉ์ผ ์ฃผ์๋ ์๋ฆผ, ๋น๋ฐ๋ฒํธ ์ฌ์ค์ ๊ณผ ์น์์์ Git ์๋์ ์ฌ์ฉ๋๋ฉฐ ๊ฐ๋ ค์ง์ง ์์ต๋๋ค.
comment_type_group_dependency = ์ ์ ์กฐ๊ฑด
+change_username_prompt = ์ฐธ๊ณ : ์ฌ์ฉ์๋ช
์ ๋ณ๊ฒฝ์ ๊ณ์ ์ URL์ ๋ณ๊ฒฝ์ํต๋๋ค.
+change_username_redirect_prompt = ๊ณผ๊ฑฐ ์ฌ์ฉ์๋ช
์ ๋๊ตฐ๊ฐ ์ฌ์ฉํ๊ธฐ ์ ๊น์ง ๋ฆฌ๋๋ ํธ๋ฉ๋๋ค.
+comment_type_group_time_tracking = ์๊ฐ ๊ธฐ๋ก
[repo]
owner=์์ ์
-repo_name=์ ์ฅ์ ์ด๋ฆ
-repo_name_helper=์ข์ ์ ์ฅ์ ์ด๋ฆ์ ๋ณดํต ์งง๊ณ ๊ธฐ์ตํ๊ธฐ ์ข์ ํน๋ณํ ํค์๋๋ก ์ด๋ฃจ์ด ์ง๋๋ค.
+repo_name=์ ์ฅ์๋ช
+repo_name_helper=์ข์ ์ ์ฅ์๋ช
์ ๋ณดํต ์งง๊ณ ๊ธฐ์ตํ๊ธฐ ์ข์ ํน๋ณํ ํค์๋๋ก ์ด๋ฃจ์ด ์ง๋๋ค.
repo_size=์ ์ฅ์ ์ฉ๋
template=ํ
ํ๋ฆฟ
template_select=ํ
ํ๋ฆฟ์ ์ ํํฉ๋๋ค.
@@ -739,6 +811,7 @@ file_too_large=๋ณด์ฌ์ฃผ๊ธฐ์๋ ํ์ผ์ด ๋๋ฌด ํฝ๋๋ค.
video_not_supported_in_browser=๋น์ ์ ๋ธ๋ผ์ฐ์ ๊ฐ HTML5์ "video" ํ๊ทธ๋ฅผ ์ง์ํ์ง ์์ต๋๋ค.
audio_not_supported_in_browser=๋น์ ์ ๋ธ๋ผ์ฐ์ ๊ฐ HTML5์ "audio" ํ๊ทธ๋ฅผ ์ง์ํ์ง ์์ต๋๋ค.
stored_lfs=Git LFS์ ์ ์ฅ๋์ด ์์ต๋๋ค
+stored_annex=Git Annex์ ์ ์ฅ๋์ด ์์ต๋๋ค
commit_graph=์ปค๋ฐ ๊ทธ๋ํ
editor.new_file=์ ํ์ผ
@@ -753,7 +826,7 @@ editor.or=ํน์
editor.cancel_lower=์ทจ์
editor.commit_changes=๋ณ๊ฒฝ ๋ด์ฉ์ ์ปค๋ฐ
editor.commit_message_desc=์ ํ์ ํ์ฅ ์ค๋ช
์ถ๊ฐโฆ
-editor.commit_directly_to_this_branch=%s ๋ธ๋์น์์ ์ง์ ์ปค๋ฐํด์ฃผ์ธ์.
+editor.commit_directly_to_this_branch=%[1]s ๋ธ๋์น์์ ์ง์ ์ปค๋ฐํด์ฃผ์ธ์.
editor.create_new_branch=์ด ์ปค๋ฐ์ ๋ํ ์๋ก์ด ๋ธ๋์น ๋ฅผ ๋ง๋ค๊ณ ๋์ด์ค๊ธฐ ์์ฒญ์ ์์ํฉ๋๋ค.
editor.new_branch_name_desc=์๋ก์ด ๋ธ๋์น ์ด๋ฆโฆ
editor.cancel=์ทจ์
@@ -848,7 +921,7 @@ issues.action_milestone=๋ง์ผ์คํค
issues.action_milestone_no_select=๋ง์ผ์คํค ์์
issues.action_assignee=๋ด๋น์
issues.action_assignee_no_select=๋ด๋น์ ์์
-issues.opened_by= %[3]s ๋์ด %[1]s์ ์คํ
+issues.opened_by= %[3]s ๋์ด %[1]s ์คํ
issues.previous=์ด์
issues.next=๋ค์
issues.open_title=์คํ
@@ -890,7 +963,7 @@ issues.subscribe=๊ตฌ๋
ํ๊ธฐ
issues.unsubscribe=๊ตฌ๋
์ทจ์
issues.delete=์ญ์
issues.tracker=ํ์ ํธ๋์ปค
-issues.start_tracking=ํ์ ํธ๋ํน ์์
+issues.start_tracking=์๊ฐ ๊ธฐ๋ก ์์
issues.start_tracking_history=`๋์ด %s ์์
์์`
issues.stop_tracking_history=`๋์ด %s ์์
์ค๋จ`
issues.add_time=์๋์ผ๋ก ์๊ฐ ์
๋ ฅ
@@ -911,8 +984,8 @@ issues.due_date_form_add=๋ง๊ฐ์ผ ์ถ๊ฐ
issues.due_date_form_edit=ํธ์ง
issues.due_date_form_remove=์ญ์
issues.due_date_not_set=๋ง๊ฐ์ผ์ด ์ค์ ๋์ง ์์์ต๋๋ค.
-issues.due_date_added=๋ง๊ฐ์ผ %s ๋ฅผ ์ถ๊ฐ %s
-issues.due_date_remove=%s %s ๋ง๊ฐ์ผ์ด ์ญ์ ๋จ
+issues.due_date_added=๋์ด ๋ง๊ฐ์ผ %s์ %s ์ถ๊ฐํจ
+issues.due_date_remove=๋์ด ๋ง๊ฐ์ผ %s๋ฅผ %s ์ญ์ ํจ
issues.due_date_overdue="๊ธฐํ ์ด๊ณผ"
issues.due_date_invalid=๊ธฐํ์ด ์ฌ๋ฐ๋ฅด์ง ์๊ฑฐ๋ ๋ฒ์๋ฅผ ๋ฒ์ด๋ฌ์ต๋๋ค. "yyyy-mm-dd"ํ์์ ์ฌ์ฉํด์ฃผ์ญ์์ค.
issues.dependency.title=์ ์ ์กฐ๊ฑด
@@ -932,7 +1005,7 @@ issues.dependency.add_error_dep_exists=์ ์ ์กฐ๊ฑด์ด ์ด๋ฏธ ์กด์ฌํฉ๋๋ค.
issues.dependency.add_error_dep_not_same_repo=๋ ์ด์๋ ๊ฐ์ ์ ์ฅ์ ์์ ์์ด์ผ ํฉ๋๋ค.
issues.review.self.approval=์์ ์ ํ ๋ฆฌํ์คํธ๋ฅผ ์น์ธํ ์ ์์ต๋๋ค.
issues.review.self.rejection=์์ ์ ํ ๋ฆฌํ์คํธ์ ๋ํ ๋ณ๊ฒฝ์ ์์ฒญํ ์ ์์ต๋๋ค.
-issues.review.approve="์ด ๋ณ๊ฒฝ์ฌํญ์ ์น์ธํ์์ต๋๋ค. %s"
+issues.review.approve=์ด ๋ณ๊ฒฝ์ฌํญ์ ์น์ธํจ %s
issues.review.comment=๊ฒํ ๋จ %s
issues.review.pending=๋ณด๋ฅ
issues.review.review=๊ฒํ
@@ -948,19 +1021,19 @@ pulls.compare_compare=๋ค์์ผ๋ก๋ถํฐ ํ
pulls.filter_branch=Filter Branch
pulls.no_results=๊ฒฐ๊ณผ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
pulls.create=ํ ๋ฆฌํ์คํธ ์์ฑ
-pulls.title_desc_few=%[2]s
์์ %[3]s
๋ก %[1]d๊ฐ์ ์ปค๋ฐ๋ค์ ๋จธ์งํ๋ ค ํฉ๋๋ค
-pulls.merged_title_desc_few=%[2]s
์์ %[3]s
๋ก %[1]d commits ๋ฅผ ๋จธ์งํ์ต๋๋ค %[4]s
+pulls.title_desc_few=%[2]s
์์ %[3]s
๋ก %[1]d๊ฐ์ ์ปค๋ฐ๋ค์ ๋ณํฉํ๋ คํจ
+pulls.merged_title_desc_few=๋์ด %[2]s
์์ %[3]s
๋ก %[1]d ์ปค๋ฐ์ %[4]s ๋ณํฉํจ
pulls.tab_conversation=๋ํ
pulls.tab_commits=์ปค๋ฐ
-pulls.tab_files=ํ์ผ ๋ณ๊ฒฝ๋จ
-pulls.reopen_to_merge=๋จธ์ง ์์
์ ์ํํ๋ ค๋ฉด ์ด ํ ๋ฆฌํ์คํธ๋ฅผ ๋ค์ ์ด์ด์ฃผ์ธ์.
-pulls.merged=๋ณํฉ
-pulls.can_auto_merge_desc=์ด ํ๋ฆฌํ์คํธ๋ ์๋์ ์ผ๋ก ๋จธ์ง๋ ์ ์์ต๋๋ค.
-pulls.cannot_auto_merge_helper=์ถฉ๋์ ํด๊ฒฐํ๋ ค๋ฉด ์๋์ผ๋ก ๋จธ์งํ์ญ์์ค.
+pulls.tab_files=ํ์ผ ๋ณ๊ฒฝ
+pulls.reopen_to_merge=๋ณํฉ์ ์ํํ๋ ค๋ฉด ์ด ํ ๋ฆฌํ์คํธ๋ฅผ ๋ค์ ์ด์ด์ฃผ์ธ์.
+pulls.merged=๋ณํฉ๋จ
+pulls.can_auto_merge_desc=์ด ํ๋ฆฌํ์คํธ๋ ์๋์ ์ผ๋ก ๋ณํฉ๋ ์ ์์ต๋๋ค.
+pulls.cannot_auto_merge_helper=์ถฉ๋์ ํด๊ฒฐํ๋ ค๋ฉด ์๋์ผ๋ก ๋ณํฉํ์ญ์์ค.
-pulls.no_merge_desc=๋ชจ๋ ์ ์ฅ์ ๋จธ์ง ์ต์
์ด ๋นํ์ฑํ ๋์ด์๊ธฐ ๋๋ฌธ์ ์ด ํ ๋ฆฌํ์คํธ๋ฅผ ๋จธ์งํ ์ ์์ต๋๋ค.
+pulls.no_merge_desc=๋ชจ๋ ์ ์ฅ์ ๋ณํฉ ์ต์
์ด ๋นํ์ฑํ ๋์ด์๊ธฐ ๋๋ฌธ์ ์ด ํ ๋ฆฌํ์คํธ๋ฅผ ๋ณํฉํ ์ ์์ต๋๋ค.
-pulls.invalid_merge_option=์ด ํ ๋ฆฌํ์คํธ์์ ์ค์ ํ ๋จธ์ง ์ต์
์ ์ฌ์ฉํ์ค ์ ์์ต๋๋ค.
+pulls.invalid_merge_option=์ด ํ ๋ฆฌํ์คํธ์์ ์ค์ ํ ๋ณํฉ ์ต์
์ ์ฌ์ฉํ์ค ์ ์์ต๋๋ค.
@@ -1028,7 +1101,7 @@ activity.title.user_1=%d ์ฌ์ฉ์
activity.title.user_n=%d ์ฌ์ฉ์
activity.title.prs_1=ํ ๋ฆฌํ์คํธ %d๊ฐ
activity.title.prs_n=ํ ๋ฆฌํ์คํธ %d๊ฐ
-activity.title.prs_merged_by=%s ๊ฐ %s ๋ก๋ถํฐ ๋จธ์ง ๋์์
+activity.title.prs_merged_by=%s ๊ฐ %s ๋ก๋ถํฐ ๋ณํฉ๋์์
activity.title.prs_opened_by=%s ๊ฐ %s ๋ก ๋ถํฐ ์ ์๋จ
activity.merged_prs_label=๋ณํฉ๋จ
activity.opened_prs_label=์ ์์ค
@@ -1056,7 +1129,6 @@ contributors.contribution_type.commits=์ปค๋ฐ
search=๊ฒ์
search.search_repo=์ ์ฅ์ ๊ฒ์
-search.results="%s ์์ \"%s\" ์ ๋ํ ๊ฒ์ ๊ฒฐ๊ณผ"
search.code_no_results=๊ฒ์์ด์ ์ผ์นํ๋ ์์ค์ฝ๋๊ฐ ์์ต๋๋ค.
settings=์ค์
@@ -1091,7 +1163,7 @@ settings.tracker_url_format=์ธ๋ถ ์ด์ ํธ๋์ปค URL ํ์
settings.tracker_issue_style=์ธ๋ถ ์ด์ ํธ๋์ปค ์ซ์ ํฌ๋งท
settings.tracker_issue_style.numeric=์ซ์
settings.tracker_issue_style.alphanumeric=๋ฌธ์ ์ซ์
-settings.enable_timetracker=์๊ฐ ์ถ์ ํ์ฑํ
+settings.enable_timetracker=์๊ฐ ๊ธฐ๋ก ํ์ฑํ
settings.allow_only_contributors_to_track_time=๊ธฐ์ฌ์ ํธ๋ ํ์๋ง
settings.pulls_desc=์ ์ฅ์ ํ ๋ฆฌํ์คํธ ํ์ฑํ
settings.pulls.ignore_whitespace=๊ณต๋ฐฑ์ ์ถฉ๋์์ ๋ฌด์ํ๊ธฐ
@@ -1137,7 +1209,7 @@ settings.update_githook=Hook ๊ฐฑ์
settings.payload_url=๋์ URL
settings.content_type=POST Content Type
settings.secret=๋น๋ฐ
-settings.slack_username=์ฌ์ฉ์ ์ด๋ฆ
+settings.slack_username=์ฌ์ฉ์๋ช
settings.slack_icon_url=์์ด์ฝ URL
settings.discord_username=์ฌ์ฉ์๋ช
settings.discord_icon_url=์์ด์ฝ URL
@@ -1194,7 +1266,7 @@ settings.protect_disable_push=ํธ์ ๋๊ธฐ
settings.protect_enable_push=ํธ์ ์ผ๊ธฐ
settings.protect_whitelist_search_users=์ฌ์ฉ์ ์ฐพ๊ธฐ...
settings.protect_whitelist_search_teams=ํ ์ฐพ๊ธฐ...
-settings.protect_merge_whitelist_committers=๋จธ์ง ํ์ดํธ๋ฆฌ์คํธ ํ์ฑํ
+settings.protect_merge_whitelist_committers=๋ณํฉ ํ์ดํธ๋ฆฌ์คํธ ํ์ฑํ
settings.protect_required_approvals=ํ์ํ ์น์ธ:
settings.protect_approvals_whitelist_users=ํ์ดํธ๋ฆฌ์คํธ๋ ๋ฆฌ๋ทฐ์ด:
settings.add_protected_branch=๋ณดํธ ํ์ฑํ
@@ -1255,7 +1327,7 @@ release.downloads=๋ค์ด๋ก๋
branch.name=๋ธ๋์น๋ช
branch.delete_head=์ญ์
branch.delete_html=๋ธ๋์น ์ญ์
-branch.create_branch=%s ๋ธ๋์น ์์ฑ
+branch.create_branch=%s ๋ธ๋์น ์์ฑ
branch.deleted_by=%s ์ ์ํด ์ญ์ ๋์์
@@ -1278,7 +1350,7 @@ settings.trust_model.committer.desc = ์ ํจํ ์๋ช
์ด ์ปค๋ฏธํฐ์ ์ผ์นํ
visibility_helper = ์ ์ฅ์ ๋น๊ณต๊ฐ๋ก ๋ง๋ค๊ธฐ
projects.description = ์ค๋ช
(์ ํ)
settings.external_tracker_url_desc = ๋ฐฉ๋ฌธ์๋ค์ด ์ด์ ํญ์ ํด๋ฆญํ๋ฉด ์ธ๋ถ ์ด์ ํธ๋ ์ปค URL๋ก ์ฐ๊ฒฐ๋ฉ๋๋ค.
-settings.tracker_url_format_desc = {user}
, {repo}
and {index}
๋ฅผ ์ฌ์ฉ์ ์ด๋ฆ, ์ ์ฅ์ ์ด๋ฆ, ์ด์ ๋ฒํธ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
+settings.tracker_url_format_desc = {user}
๋ฅผ ์ฌ์ฉ์๋ช
, {repo}
๋ฅผ ์ ์ฅ์๋ช
, {index}
๋ฅผ ์ด์ ๋ฒํธ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
projects = ํ๋ก์ ํธ
projects.desc = ์ด์์ ํ ๋ฆฌํ์คํธ๋ฅผ ํ๋ก์ ํธ์์ ๊ด๋ฆฌํฉ๋๋ค.
projects.create = ํ๋ก์ ํธ ๋ง๋ค๊ธฐ
@@ -1297,7 +1369,7 @@ pulls.blocked_by_official_review_requests = ์ด ํ ๋ฆฌํ์คํธ๋ ๊ณต์ ๊ฒ
watch_guest_user = ์ด ์ ์ฅ์๋ฅผ ์ฃผ์ํ๋ ค๋ฉด ๋ก๊ทธ์ธ ํด์ผํฉ๋๋ค.
issues.closed_by_fake = %[2]s๋์ด %[1]s์ ๋ซ์
issues.new.closed_projects = ๋ซํ ํ๋ก์ ํธ
-pulls.merged_by_fake = %[2]s๋์ด %[1]s์ ๋จธ์งํจ
+pulls.merged_by_fake = %[2]s๋์ด %[1]s ๋ณํฉํจ
issues.closed_by = %[3]s ๋์ด %[1]s์ ๋ซ์
issues.closed_at = `%[2]s `์ ์ด ์ด์๋ฅผ ๋ซ์
issues.filter_milestone_closed = ๋ซํ ๋ง์ผ์คํค
@@ -1321,14 +1393,46 @@ issues.dependency.no_permission_1 = %d๊ฐ์ ์ ์ ์กฐ๊ฑด์ ์ฝ์ ๊ถํ์ด
issues.dependency.no_permission.can_remove = ์ด ์ ์ ์กฐ๊ฑด์ ์ฝ์ ๊ถํ์ด ์์ง๋ง ์ง์ธ ์ ์์
issues.dependency.removed_dependency = `๋์ด %s ์ ์ ์กฐ๊ฑด ์ญ์ `
issues.dependency.pr_close_blocked = ๋ณํฉํ๊ธฐ ์ ์ ์ด ํ ๋ฆฌํ์คํธ์ ์ ํํ๋ ๋ชจ๋ ์ด์๋ฅผ ์ข
๋ฃํด์ผ ํฉ๋๋ค.
+stars = ์ข์์
+stars_remove_warning = ์ด ์์
์ ์ด ์ ์ฅ์์ ๋ํ ๋ชจ๋ ์ข์์๋ฅผ ์ ๊ฑฐํ ๊ฒ์
๋๋ค.
+star_guest_user = ๋ก๊ทธ์ธํ์ฌ ์ด ์ ์ฅ์์ ์ข์์ ํ์ธ์.
+issues.author.tooltip.issue = ์ด ์ฌ์ฉ์๋ ์ด ์ด์์ ์์ฑ์ ์
๋๋ค.
+issues.author.tooltip.pr = ์ด ์ฌ์ฉ์๋ ์ด ํ ๋ฆฌํ์คํธ์ ์์ฑ์ ์
๋๋ค.
+activity.git_stats_author_1 = %d๋ช
์ ์์ฑ์
+issues.filter_poster_no_select = ๋ชจ๋ ์์ฑ์
+pulls.blocked_by_user = ๋น์ ์ ์ด ์ ์ฅ์์ ์์ ์์๊ฒ ์ฐจ๋จ๋นํ๊ธฐ ๋๋ฌธ์ ํ ๋ฆฌํ์คํธ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
+commits.search.tooltip = ํค์๋ ์์ ์ ๋์ฌ "author:", "committer:", "after:", "before:"์ ์ฌ์ฉํ ์ ์์ต๋๋ค (์: "revert author:Alice before:2019-01-13").
+issues.filter_poster = ์์ฑ์
+issues.author = ์์ฑ์
+issues.role.owner_helper = ์ด ์ฌ์ฉ์๋ ์ด ์ ์ฅ์์ ์์ ์ ์
๋๋ค.
+activity.git_stats_author_n = %d๋ช
์ ์์ฑ์
+diff.review.self_reject = ํ ๋ฆฌํ์คํธ ์์ฑ์๋ ์์ ์ ํ ๋ฆฌํ์คํธ์ ์์ ์ ์์ฒญํ ์ ์์
+diff.review.self_approve = ํ ๋ฆฌํ์คํธ ์์ฑ์๋ ์์ ์ ํ ๋ฆฌํ์คํธ๋ฅผ ์น์ธํ ์ ์์
+issues.blocked_by_user = ๋น์ ์ ์ด ์ ์ฅ์์ ์์ ์์๊ฒ ์ฐจ๋จ๋นํ๊ธฐ ๋๋ฌธ์ ์ด์๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
+issues.comment.blocked_by_user = ๋น์ ์ ์ด ์ ์ฅ์์ ์์ ์ ํน์ ์ด ์ด์์ ์์ฑ์ ์๊ฒ ์ฐจ๋จ๋นํ๊ธฐ ๋๋ฌธ์ ์ด์์ ๋๊ธ์ ๋ฌ ์ ์์ต๋๋ค.
+author_search_tooltip = ์ต๋ 30๋ช
์ ์ฌ์ฉ์๋ฅผ ํ์ํจ
+pulls.merged_title_desc_one = ๋์ด %[2]s
์์ %[3]s
๋ก %[1]d ์ปค๋ฐ์ %[4]s ๋ณํฉํจ
+issues.stop_tracking = ํ์ด๋จธ ์ ์ง
+issues.start_tracking_short = ํ์ด๋จธ ์์
+mirror_password_help = ์ฌ์ฉ์๋ช
์ ๋ณ๊ฒฝํด ์ ์ฅ๋ ๋น๋ฐ๋ฒํธ๋ฅผ ์ง์ฐ์ธ์.
+issues.cancel_tracking_history = `์ทจ์๋ ์๊ฐ ๊ธฐ๋ก %s`
+settings.enter_repo_name = ํ์๋ ์์ ์์ ์ ์ฅ์๋ช
์ ์ ํํ๊ฒ ์
๋ ฅํ์ธ์:
+settings.packagist_username = Packagist ์ฌ์ฉ์๋ช
+issues.tracking_already_started = `๋น์ ์ ์ด๋ฏธ ๋ค๋ฅธ ์ด์ ์์ ์๊ฐ์ ๊ธฐ๋ก์ค์
๋๋ค!`
+adopt_search = ์ฌ์ฉ์๋ช
์ ์
๋ ฅํด ์์ ์๊ฐ ๋๋ฝ๋ ์ ์ฅ์๋ฅผ ๊ฒ์... (๋ชจ๋ ์ฐพ์ผ๋ ค๋ฉด ๋น์๋๊ธฐ)
+form.name_reserved = "%s" ์ ์ฅ์๋ช
์ด ์์ฝ๋์ด ์์ต๋๋ค.
+form.name_pattern_not_allowed = "%s" ํจํด์ด ์ ์ฅ์๋ช
์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
+archive.title_date = ์ด ์ ์ฅ์๋ %s์ ๋ณด๊ด์ฒ๋ฆฌ๋์์ต๋๋ค. ํ์ผ์ ๋ณผ ์ ์๊ณ ๋ณต์ ํ ์๋ ์์ง๋ง, ํธ์ํ๊ฑฐ๋ ์ด์๋ฅผ ์ด๊ฑฐ๋ ํ ๋ฆฌํ์คํธ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค.
+milestones.filter_sort.name = ์ด๋ฆ
+
[graphs]
[org]
org_name_holder=์กฐ์ง ์ด๋ฆ
-org_full_name_holder=์กฐ์ง ์ ์ฒด ์ด๋ฆ
+org_full_name_holder=์กฐ์ง ๋ณ๋ช
create_org=์๋ก์ด ์กฐ์ง
repo_updated=์
๋ฐ์ดํธ๋จ %s
members=๋ฉค๋ฒ
@@ -1365,7 +1469,7 @@ members.public=๋ณด์
members.public_helper=์จ๊ธฐ๊ธฐ
members.private=์จ๊น
members.private_helper=๋ณด์ด๊ธฐ
-members.member_role=ํ์ ์ญํ :
+members.member_role=๋ฉค๋ฒ ์ญํ :
members.owner=์์ ์
members.member=๋ฉค๋ฒ
members.remove=์ ๊ฑฐ
@@ -1389,6 +1493,7 @@ teams.repositories=ํ ์ ์ฅ์
teams.search_repo_placeholder=์ ์ฅ์ ์ฐพ๊ธฐ...
teams.add_duplicate_users=์ฌ์ฉ์๊ฐ ์ด๋ฏธ ํ ๋ฉค๋ฒ์
๋๋ค.
teams.members.none=์ด ํ์ ๋ฉค๋ฒ๊ฐ ์์ต๋๋ค.
+form.name_pattern_not_allowed = "%s" ํจํด์ด ์กฐ์ง๋ช
์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.
[admin]
dashboard=๋์๋ณด๋
@@ -1589,9 +1694,9 @@ config.db_path=๊ฒฝ๋ก
config.service_config=์๋น์ค ์ค์
config.register_email_confirm=๊ฐ์
์ ์ด๋ฉ์ผ ํ์ธ ํ์
-config.disable_register=์์ฒด๋ฑ๋ก ์ฌ์ฉ์ํจ
+config.disable_register=์ฌ์ฉ์ ๋ฑ๋ก ๊ฑฐ๋ถ
config.allow_only_external_registration=์ธ๋ถ ์๋น์ค๋ฅผ ํตํด์๋ง ๋ฑ๋ก ํ์ฉ
-config.enable_openid_signup=OpenID ์์ฒด๋ฑ๋ก ํ์ฑํ
+config.enable_openid_signup=OpenID ๋ฑ๋ก ํ์ฑํ
config.enable_openid_signin=OpenID ๋ก๊ทธ์ธ ํ์ฑํ
config.show_registration_button=๋ฑ๋ก ๋ฒํผ์ ํ์
config.require_sign_in_view=ํ์ด์ง๋ฅผ ๋ณด๋ ค๋ฉด ๋ก๊ทธ์ธ ํ์
@@ -1600,8 +1705,8 @@ config.enable_captcha=CAPTCHA ํ์ฑํ
config.active_code_lives=์ฝ๋ ๋ง๋ฃ ๊ธฐํ
config.default_keep_email_private=๊ธฐ๋ณธ์ ์ผ๋ก ์ด๋ฉ์ผ ์ฃผ์๋ฅผ ์จ๊น
config.default_allow_create_organization=๊ธฐ๋ณธ์ ์ผ๋ก ์กฐ์ง ์์ฑ์ ํ์ฉ
-config.enable_timetracking=ํ์ ํธ๋ํน ํ์ฑํ
-config.default_enable_timetracking=๊ธฐ๋ณธ ํ์ ํธ๋ํน ํ์ฑํ
+config.enable_timetracking=์๊ฐ ๊ธฐ๋ก ํ์ฑํ
+config.default_enable_timetracking=๊ธฐ๋ณธ์ผ๋ก ์๊ฐ ๊ธฐ๋ก์ ํ์ฑํ
config.default_allow_only_contributors_to_track_time=๊ธฐ์ฌ์ ํธ๋ ํ์๋ง
config.no_reply_address=๊ฐ๋ ค์ง ์ด๋ฉ์ผ ๋๋ฉ์ธ
config.default_enable_dependencies=๊ธฐ๋ณธ์ ์ผ๋ก ์ด์ ์ข
์์ฑ์ ํ์ฑํ
@@ -1687,14 +1792,24 @@ notices.op=์ผ.
notices.delete_success=์์คํ
์๋ฆผ์ด ์ญ์ ๋์์ต๋๋ค.
users.allow_git_hook_tooltip = Git ํ
์ Forgejo๊ฐ ์คํ์ค์ธ OS ์ ์ ๋ก ์คํ๋๋ฉฐ ๊ฐ์ ์์ค์ ๊ถํ์ ๊ฐ์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก, Git ํ
์ฌ์ฉ๊ถํ์ด ์๋ ์ฌ์ฉ์๋ Forgejo์์ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํฌํจํ ๋ชจ๋ ์ ์ฅ์์ ์ ๊ทผํ๊ฑฐ๋ ์์ ํ ์ ์์ต๋๋ค. ๊ถ๊ทน์ ์ผ๋ก ์ด๋ฌํ ์ฌ์ฉ์๋ค์ Forgejo์ ๊ด๋ฆฌ์ ๊ถํ์ ํ๋ํ ์ ์์ต๋๋ค.
emails.primary = ๋ํ
+auths.sspi_strip_domain_names = ์ฌ์ฉ์๋ช
๋ค์์ ๋๋ฉ์ธ๋ช
์ ์ ๊ฑฐํจ
+auths.tip.yandex = %s์ ์ ์ ํ๋ฆฌ์ผ์ด์
์ ๋ง๋ญ๋๋ค. "Yandex.Passport API"๋ถ๋ถ์ "Access to email address", "Access to user avatar", "Access to username, first name and surname, gender" ๊ถํ์ ํ์ฑํ ํ์ธ์.
+emails.filter_sort.name = ์ฌ์ฉ์๋ช
+auths.attribute_username_placeholder = ๋น์๋๋ฉด Forgejo์ ์
๋ ฅ๋ ์ฌ์ฉ์๋ช
์ ์ฌ์ฉํฉ๋๋ค.
+emails.filter_sort.name_reverse = ์ฌ์ฉ์๋ช
(์์ฝ๋จ)
+config.allow_dots_in_usernames = ์ฌ์ฉ์๋ค์ด ๋ง์นจํ๋ฅผ ์ฌ์ฉ์๋ช
์ ์ฌ์ฉํ ์ ์๋๋ก ํ๊ฐํฉ๋๋ค. ์ด๋ฏธ ์กด์ฌํ๋ ๊ณ์ ์๋ ์ํฅ์ ์ฃผ์ง ์์ต๋๋ค.
+config_summary = ์์ฝ
+config_settings = ์ค์
+
[action]
create_repo=์ ์ฅ์๋ฅผ ๋ง๋ค์์ต๋๋ค. %s
rename_repo=์ ์ฅ์ ์ด๋ฆ์ %[1]s์์
์์ %[3]s ์ผ๋ก ๋ณ๊ฒฝํจ
transfer_repo=์ ์ฅ์๊ฐ %s
์์ %s ๋ก ์ด๋๋จ
compare_commits=%d ์ปค๋ฐ๋ค ๋น๊ต
watched_repo = %[2]s ์๋ํ ์ฃผ์๋ฅผ ์์ํจ
+starred_repo = %[2]s ๋ฅผ ์ข์ํจ
[tool]
now=ํ์ฌ
@@ -1754,13 +1869,11 @@ nuget.dependency.framework = ํ๊ฒ ํ๋ ์์ํฌ
maven.download = ์ข
์์ฑ์ ๋ค์ด๋ก๋ํ๋ ค๋ฉด ๋ช
๋ น์ค์ ํตํด ์คํํ์ธ์:
dependency.id = ID
dependency.version = ๋ฒ์
+details.author = ์์ฑ์
[secrets]
[actions]
-
-
-
runners.name=์ด๋ฆ
runners.owner_type=์ ํ
runners.description=์ค๋ช
@@ -1777,9 +1890,6 @@ runs.commit=์ปค๋ฐ
[projects]
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
-
-
[search]
code_search_by_git_grep = ํ์ฌ ์ฝ๋ ๊ฒ์ ๊ฒฐ๊ณผ๋ "git grep"์ ์ํด ์ ๊ณต๋ฉ๋๋ค.๊ด๋ฆฌ์๊ฐ ์ฝ๋ ์ธ๋ฑ์๋ฅผ ํ์ฑํํ๋ฉด ๋ ๋์ ๊ฒฐ๊ณผ๊ฐ ์ ๊ณต๋ ์ ์์ต๋๋ค.
@@ -1787,17 +1897,24 @@ branch_kind = ๋ธ๋์น ๊ฒ์...
keyword_search_unavailable = ์ง๊ธ์ ํค์๋๋ก ๊ฒ์์ด ์ง์๋์ง ์์ต๋๋ค. ์ฌ์ดํธ ๊ด๋ฆฌ์์๊ฒ ๋ฌธ์ํ์ญ์์ค.
commit_kind = ์ปค๋ฐ ๊ฒ์...
no_results = ์ผ์นํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค.
-search = ๊ฒ์...
+search = ๊ฒ์โฆ
type_tooltip = ๊ฒ์ ํ์
fuzzy_tooltip = ๊ฒ์์ด์ ๋ฐ์ ํ๊ฒ ์ผ์นํ๋ ๊ฒฐ๊ณผ๋ ํฌํจ
-repo_kind = ์ ์ฅ์ ๊ฒ์...
-user_kind = ์ฌ์ฉ์ ๊ฒ์...
-org_kind = ์กฐ์ง ๊ฒ์...
+repo_kind = ์ ์ฅ์ ๊ฒ์โฆ
+user_kind = ์ฌ์ฉ์ ๊ฒ์โฆ
+org_kind = ์กฐ์ง ๊ฒ์โฆ
team_kind = ํ ๊ฒ์...
code_kind = ์ฝ๋ ๊ฒ์...
code_search_unavailable = ์ฝ๋ ๊ฒ์์ ํ์ฌ ํ์ฉ๋์ง ์์์ต๋๋ค. ์ฌ์ดํธ ๊ด๋ฆฌ์์ ์ฐ๋ฝํ์ธ์.
package_kind = ํจํค์ง ๊ฒ์...
project_kind = ํ๋ก์ ํธ ๊ฒ์...
exact_tooltip = ๊ฒ์์ด์ ์ ํํ๊ฒ ์ผ์นํ๋ ๊ฒฐ๊ณผ๋ง ํฌํจ
-issue_kind = ์ด์ ๊ฒ์...
-pull_kind = ํ ๊ฒ์...
\ No newline at end of file
+issue_kind = ์ด์ ๊ฒ์โฆ
+pull_kind = ํ ๊ฒ์โฆ
+milestone_kind = ๋ง์ผ์คํค ๊ฒ์...
+fuzzy = ๋ชจํธํจ
+union = ํตํฉ ๊ฒ์
+union_tooltip = ๊ณต๋ฐฑ์ผ๋ก ๊ตฌ๋ถ๋ ํค์๋ ์ค ํ๋๋ผ๋ ์ผ์นํ๋ ๊ฒฐ๊ณผ๋ฅผ ํฌํจํ์ธ์
+exact = ์ ํํ
+regexp = ์ ๊ท ํํ์
+regexp_tooltip = ๊ฒ์์ด๋ฅผ ์ ๊ท ํํ์์ผ๋ก ํด์ํฉ๋๋ค
\ No newline at end of file
diff --git a/options/locale/locale_lt.ini b/options/locale/locale_lt.ini
new file mode 100644
index 0000000000..868e5bff6e
--- /dev/null
+++ b/options/locale/locale_lt.ini
@@ -0,0 +1,277 @@
+[common]
+dashboard = Sฤ
vadas
+explore = Narลกyti
+help = Pagalba
+logo = Logotipas
+sign_in = Prisijungti
+sign_in_with_provider = Prisijungti su โ%sโ
+sign_in_or = arba
+sign_out = Atsijungti
+link_account = Susieti paskyrฤ
+sign_up = Registruotis
+register = Registruotis
+version = Versija
+powered_by = Veikia su โ%sโ
+language = Kalba
+notifications = Praneลกimai
+active_stopwatch = Aktyvus laiko sekiklis
+tracked_time_summary = Sekamo laiko santrauka pagal problemลณ sฤ
raลกo filtrus
+create_new = Kurtiโฆ
+user_profile_and_more = Profilis ir nustatymaiโฆ
+signed_in_as = Prisijungta kaip
+toc = Turinys
+licenses = Licencijos
+return_to_forgejo = Grฤฏลพti ฤฏ โForgejoโ
+toggle_menu = Perjungti meniu
+more_items = Daugiau elementลณ
+username = Naudotojo vardas
+email = El. paลกto adresas
+password = Slaptaลพodis
+access_token = Prieigos raktas
+re_type = Patvirtinti slaptaลพodฤฏ
+twofa = Dvigubas tapatybฤs nustatymas
+twofa_scratch = Dvigubo ลพenklo kodas
+passcode = PIN kodas
+webauthn_sign_in = Paspauskite saugumo rakto mygtukฤ
. Jei saugumo raktas neturi mygtuko, ฤฏkiลกkite jฤฏ iลก naujo.
+webauthn_press_button = Paspauskite saugumo rakto mygtukฤ
โฆ
+webauthn_error = Nepavyko nuskaityti saugumo rakto.
+webauthn_unsupported_browser = Jลซsลณ narลกyklฤ ลกiuo metu nepalaiko โWebAuthnโ.
+webauthn_error_unknown = ฤฎvyko neลพinoma klaida. Bandykite dar kartฤ
.
+webauthn_error_unable_to_process = Serveris negalฤjo apdoroti jลซsลณ praลกymo.
+webauthn_error_duplicated = Saugumo raktas neleidลพiamas ลกiai praลกymai. ฤฎsitikinkite, kad raktas dar nฤra uลพregistruotas.
+webauthn_error_empty = Turite nustatyti ลกio rakto pavadinimฤ
.
+repository = Saugykla
+organization = Organizacija
+mirror = Dubliuojanฤioji tinklavietฤ
+new_fork = Nauja saugyklos atลกaka
+new_project = Naujas projektas
+new_project_column = Naujas stulpelis
+admin_panel = Svetainฤs administravimas
+settings = Nustatymai
+new_mirror = Nauja dubliuojanฤioji tinklavietฤ
+your_settings = Nustatymai
+new_repo.title = Nauja saugykla
+new_migrate.title = Nauja migracija
+new_org.title = Nauja organizacija
+new_repo.link = Nauja saugykla
+new_migrate.link = Nauja migracija
+new_org.link = Nauja organizacija
+all = Viskas
+sources = ล altiniai
+mirrors = Dubliuojantys tinklavietฤs
+forks = Atลกakos
+activities = Veiklos
+pull_requests = Sujungimo praลกymai
+issues = Problemos
+milestones = Etapai
+ok = Gerai
+cancel = Atลกaukti
+retry = Kartoti
+rerun = Paleisti iลก naujo
+rerun_all = Paleisti iลก naujo visus uลพduoฤius
+save = Iลกsaugoti
+add = Pridฤti
+add_all = Pridฤti viskฤ
+remove_all = Paลกalinti viskฤ
+remove_label_str = Paลกalinti โ%sโ elementฤ
+edit = Redaguoti
+view = Perลพiลซrฤti
+test = Bandyti
+enabled = ฤฎjungta
+disabled = Iลกjungta
+locked = Uลพrakinta
+copy = Kopijuoti
+copy_url = Kopijuoti URL
+copy_hash = Kopijuoti maiลกฤ
+copy_content = Kopijuoti turinฤฏ
+copy_branch = Kopijuoti ลกakos pavadinimฤ
+copy_success = Nukopijuota.
+copy_error = Nepavyko nukopijuoti
+copy_type_unsupported = ล io failo tipo negalima kopijuoti.
+write = Raลกyti
+preview = Perลพiลซra
+loading = ฤฎkeliamaโฆ
+error = Klaida
+error404 = Puslapis, kurฤฏ bandote pasiekti, neegzistuoja arba nesate ฤฏgalioti jฤฏ perลพiลซrฤti.
+error413 = Jลซs iลกnaudojote savo kvotฤ
.
+go_back = Eiti atgal
+invalid_data = Netinkama data: %v
+never = Niekada
+unknown = Neลพinomas
+rss_feed = RSS kanalas
+pin = Prisegti
+unpin = Atsegti
+artifacts = Artefaktai
+confirm_delete_artifact = Ar tikrai norite iลกtrinti artefaktฤ
โ%sโ?
+archived = Archyvuota
+concept_system_global = Globalus
+enable_javascript = ล iai svetainei reikalingas โJavaScriptโ.
+webauthn_insert_key = ฤฎkiลกkite savo saugumo raktฤ
+webauthn_use_twofa = Naudoti dvigubฤ
kodฤ
iลก telefono
+webauthn_error_timeout = Baigฤsi laikas, per kurฤฏ nebuvo galima nuskaityti rakto. Perkraukite ลกฤฏ puslapฤฏ ir bandykite dar kartฤ
.
+your_starred = Paลพymฤti ลพvaigลพdutฤ
+remove = Paลกalinti
+copy_generic = Kopijuoti ฤฏ iลกkarpinฤ
+captcha = Saugos testas (CAPTCHA)
+your_profile = Profilis
+webauthn_error_insecure = โWebAuthnโ palaiko tik saugius ryลกius. Bandymams per HTTP galite naudoti โlocalhostโ arba โ127.0.0.0.1โ.
+collaborative = Bendradarbiavimas
+home = Pagrindinis
+page = Puslapis
+template = ล ablonas
+concept_user_individual = Individualus
+concept_code_repository = Saugykla
+concept_user_organization = Organizacija
+show_timestamps = Rodyti laiko ลพymes
+show_log_seconds = Rodyti sekundes
+show_full_screen = Rodyti visฤ
ekranฤ
+download_logs = Atsisiลณsti ลพurnalus
+confirm_delete_selected = Patvirtinti, kad iลกtrinti visus pasirinktus elementus?
+name = Pavadinimas
+value = Reikลกmฤ
+filter = Filtruoti
+filter.clear = Valyti filtrus
+filter.is_archived = Suarchyvuota
+filter.not_archived = Nesuarchyvuota
+filter.is_fork = Atลกakos
+filter.not_fork = Ne atลกakos
+filter.is_mirror = Dubliuojantys tinklavietฤs
+filter.not_template = Ne ลกablonai
+filter.public = Vieลกa
+filter.private = Privati
+filter.not_mirror = Ne dubliuojantys tinklavietฤs
+filter.is_template = ล ablonai
+
+[search]
+search = Ieลกkoti...
+type_tooltip = Paieลกkos tipas
+fuzzy = Tikslintinas
+union_tooltip = ฤฎtraukti rezultatus, atitinkanฤius bet kurฤฏ iลก matomฤ
tarpฤ
atskirtลณ raktaลพodลพiลณ
+exact = Tiksliai
+exact_tooltip = ฤฎtraukti tik tuos rezultatus, kurie atitinka tiksliฤ
paieลกkos frazฤ
+user_kind = Ieลกkoti naudotojลณ...
+team_kind = Ieลกkoti komandลณ...
+code_kind = Ieลกkoti kodo...
+fuzzy_tooltip = ฤฎtraukti rezultatus, kurie taip pat labai atitinka paieลกkos terminฤ
+repo_kind = Ieลกkoti saugyklลณ...
+code_search_unavailable = Kodลณ paieลกka ลกiuo metu nepasiekiama. Kreipkis ฤฏ svetainฤs administratoriลณ.
+org_kind = Ieลกkoti organizacijลณ...
+union = Bendrinis
+code_search_by_git_grep = Dabartiniai kodo paieลกkos rezultatai pateikiami atliekant โgit grepโ. Rezultatai gali bลซti geresni, jei svetainฤs administratorius ฤฏjungs kodo indeksuotojฤ
.
+package_kind = Ieลกkoti paketลณ...
+project_kind = Ieลกkoti projektลณ...
+commit_kind = Ieลกkoti ฤฏsipareigojimลณ...
+runner_kind = Ieลกkoti vykdykliลณ...
+no_results = Nerasta atitinkamลณ rezultatลณ.
+issue_kind = Ieลกkoti problemลณ...
+branch_kind = Ieลกkoti ลกakลณ...
+milestone_kind = Ieลกkoti gairiลณ...
+pull_kind = Ieลกkoti sujungimลณ...
+keyword_search_unavailable = Ieลกkoti pagal raktaลพodฤฏ ลกiuo metu nepasiekiamas. Susisiekite su svetainฤs administratoriumi.
+regexp = Reguliarusis reiลกkinys
+regexp_tooltip = Interpretuoti paieลกkos terminฤ
kaip reguliariฤ
jฤ
reiลกkinฤฏ
+
+[actions]
+workflow.disable = Iลกjungti darbo eigฤ
+runs.expire_log_message = ลฝurnalai buvo panaikinti, nes buvo per seni.
+workflow.disable_success = Sฤkmingai iลกjungta darbo eiga โ%sโ.
+workflow.enable = ฤฎjungti darbo eigฤ
+runs.empty_commit_message = (tuลกฤias ฤฏsipareigojimo praneลกimas)
+
+[git.filemode]
+submodule = Pomodulis
+changed_filemode = %[1]s โ %[2]s
+symbolic_link = Virtualusis aplankas
+directory = Katalogas
+executable_file = Vykdomasis failas
+normal_file = ฤฎprastas failas
+
+[projects]
+deleted.display_name = Iลกtrintas projektas
+type-1.display_name = Individualus projektas
+type-2.display_name = Saugyklos projektas
+type-3.display_name = Organizacijos projektas
+
+[markup]
+filepreview.truncated = Perลพiลซra buvo sutrumpinta
+
+[mail]
+reset_password.text = Jei tai buvote jลซs, spustelฤkite toliau esanฤiฤ
nuorodฤ
, kad atkurtumฤte savo paskyrฤ
per %s :
+
+[heatmap]
+contributions_one = ฤฏnaลกas
+contributions_few = ฤฏnaลกai
+less = Maลพiau
+more = Daugiau
+number_of_contributions_in_the_last_12_months = %s ฤฏnaลกลณ per pastaruosius 12 mฤnesiลณ
+contributions_zero = ฤฎnaลกลณ nฤra
+contributions_format = {contributions} {year} {month} {day}
+
+[aria]
+navbar = Narลกymo juosta
+footer = Puslapinฤ poraลกtฤ
+footer.software = Apie ลกiฤ
programinฤ ฤฏrangฤ
+footer.links = Nuorodos
+
+[editor]
+buttons.quote.tooltip = Cituoti tekstฤ
+buttons.code.tooltip = Pridฤti kodฤ
+buttons.link.tooltip = Pridฤti nuorodฤ
+buttons.heading.tooltip = Pridฤti antraลกtฤ
+buttons.bold.tooltip = Pridฤti pusjuodฤฏ tekstฤ
+buttons.italic.tooltip = Pridฤti kursyvinฤฏ tekstฤ
+buttons.list.unordered.tooltip = Pridฤti punktลณ sฤ
raลกฤ
+buttons.list.ordered.tooltip = Pridฤti numeruotฤ
sฤ
raลกฤ
+buttons.list.task.tooltip = Pridฤti uลพduoฤiลณ sฤ
raลกฤ
+buttons.mention.tooltip = Minฤti naudotojฤ
arba komandฤ
+buttons.ref.tooltip = Nurodyti ฤฏ problemฤ
arba sujungimo praลกymฤ
+buttons.switch_to_legacy.tooltip = Vietoj to naudoti senฤ
jฤฏ rengyklฤ
+buttons.enable_monospace_font = ฤฎjungti vienspalvฤฏ ลกriftฤ
+buttons.disable_monospace_font = Iลกjungti vienspalvฤฏ ลกriftฤ
+buttons.indent.tooltip = ฤฎdฤti elementus vienu lygiu
+buttons.unindent.tooltip = Iลกdฤti elementus vienu lygiu
+
+[error]
+network_error = Tinklo klaida
+server_internal = Vidinio serverio klaida
+occurred = ฤฎvyko klaida.
+report_message = Jei manote, kad tai โForgejoโ riktas, ieลกkokite problemลณ platformoje โCodebergโ arba, jei reikia, atidarykite naujฤ
problemฤ
.
+
+[startpage]
+app_desc = Nesudฤtinga, savarankiลกkai teikiama โGitโ paslauga
+install = Lengva ฤฏdiegti
+license = Atvirojo kodo
+
+[install]
+path = Kelias
+err_admin_name_is_reserved = Administratoriaus naudotojo vardas netinkamas. Naudotojo vardas yra rezervuotas.
+enable_update_checker = ฤฎjungti naujinimลณ tikrintuvฤ
+env_config_keys = Aplinkos konfigลซracija
+db_title = Duomenลณ bazฤs nustatymai
+db_type = Duomenลณ bazฤs tipas
+user = Naudotojo vardas
+password = Slaptaลพodis
+db_name = Duomenลณ bazฤs pavadinimas
+db_schema = Schema
+ssl_mode = SSL
+host = Pagrindinis komputeris
+general_title = Bendrieji nustatymai
+email_title = El. paลกto nustatymai
+federated_avatar_lookup.description = Ieลกkokite pseudoportretลณ naudojant โLibravatarโ.
+db_schema_helper = Palikite tuลกฤiฤ
, jei tai numatytoji duomenลณ bazฤ (โpublicโ).
+err_empty_admin_password = Administratoriaus slaptaลพodis negali bลซti tuลกฤias.
+err_empty_admin_email = Administratoriaus el. paลกtas negali bลซti tuลกฤias.
+install = Diegimas
+
+[explore]
+go_to = Eiti ฤฏ
+code = Kodas
+
+[auth]
+remember_me = Prisiminti ลกฤฏ ฤฏrenginฤฏ
+forgot_password_title = Pamirลกtas slaptaลพodis
+forgot_password = Pamirลกote slaptaลพodฤฏ?
+
+[filter]
+string.asc = A โ ลฝ
+string.desc = ลฝ โ A
\ No newline at end of file
diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini
index 460b0d351e..4bd379c8e2 100644
--- a/options/locale/locale_lv-LV.ini
+++ b/options/locale/locale_lv-LV.ini
@@ -1,13 +1,13 @@
[common]
home=Sฤkums
-dashboard=Infopanelis
+dashboard=Pฤrskata panelis
explore=Izpฤtฤซt
help=Palฤซdzฤซba
logo=Logo
sign_in=Pieteikties
sign_in_with_provider=Pieteikties ar %s
sign_in_or=vai
-sign_out=Izrakstฤซties
+sign_out=Atteikties
sign_up=Reฤฃistrฤties
link_account=Sasaistฤซt kontu
register=Reฤฃistrฤties
@@ -17,7 +17,7 @@ page=Lapa
template=Sagatave
language=Valoda
notifications=Paziลojumi
-active_stopwatch=Aktฤซvฤ laika uzskaite
+active_stopwatch=Paลกreizฤjฤ laika uzskaite
tracked_time_summary=Izsekojamฤ laika apkopojums, kas ir balstฤซts uz pieteikumu saraksta atlasi
create_new=Izveidotโฆ
user_profile_and_more=Profils un iestatฤซjumiโฆ
@@ -31,66 +31,66 @@ username=Lietotฤjvฤrds
email=E-pasta adrese
password=Parole
access_token=Piekฤผuves pilnvara
-re_type=Apstipriniet paroli
+re_type=Apstiprinฤt paroli
captcha=Cilvฤktests
-twofa=Divfaktoru autentifikฤcija
-twofa_scratch=Divfaktoru vienreizฤjais kods
+twofa=Divpakฤpju pieteikลกanฤs
+twofa_scratch=Divpakฤpju vienreiz izmantojamais kods
passcode=Kods
-webauthn_insert_key=Ievietojiet Jลซsu droลกฤซbas atslฤgu
-webauthn_sign_in=Nospiediet pogu uz droลกฤซbas atslฤgas. Ja tai nav pogas, izลemiet un ievietojiet to atkฤrtoti.
-webauthn_press_button=Nospiediet droลกฤซbas atslฤgas poguโฆ
-webauthn_use_twofa=Izmantot divfaktoru kodu no tฤlruลa
+webauthn_insert_key=Jฤievieto sava droลกฤซbas atslฤga
+webauthn_sign_in=Jฤnospieลพ poga uz droลกฤซbas atslฤgas. Ja tai nav pogas, droลกฤซbas atslฤga ir atkฤrtoti jฤievieto.
+webauthn_press_button=Lลซgums nospiest pogu uz savas droลกฤซbas atslฤgasโฆ
+webauthn_use_twofa=Izmantot divpakฤpju kodu no sava tฤlruลa
webauthn_error=Nevar nolasฤซt droลกฤซbas atslฤgu.
-webauthn_unsupported_browser=Jลซsu pฤrlลซks neatbalsta WebAuthn standartu.
-webauthn_error_unknown=Notikusi nezinฤma kฤผลซda. Atkฤrtojiet darbฤซbu vฤlreiz.
-webauthn_error_insecure=`WebAuthn atbalsta tikai droลกus savienojumus. Pฤrbaudฤซลกanai ar HTTP var izmantot izcelsmi "localhost" vai "127.0.0.1"`
+webauthn_unsupported_browser=Pฤrlลซks paลกlaik nenodroลกina WebAuthn.
+webauthn_error_unknown=Atgadฤซjฤs nezinฤma kฤผลซda. Lลซgums mฤฤฃinฤt vฤlreiz.
+webauthn_error_insecure=WebAuthn atbalsta tikai droลกus savienojumus. Pฤrbaudฤซลกanai ar HTTP var izmantot pirmavotu "localhost" vai "127.0.0.1"
webauthn_error_unable_to_process=Serveris nevarฤja apstrฤdฤt pieprasฤซjumu.
-webauthn_error_duplicated=Droลกฤซbas atslฤga nav atฤผauta ลกim pieprasฤซjumam. Pฤrliecinieties, ka ลกฤซ atslฤga jau nav reฤฃistrฤta.
+webauthn_error_duplicated=Droลกฤซbas atslฤga nav atฤผauta ลกim pieprasฤซjumam. Lลซgums pฤrliecinฤties, ka ลกฤซ atslฤga nav jau reฤฃistrฤta.
webauthn_error_empty=Jฤnorฤda ลกฤซs atslฤgas nosaukums.
-webauthn_error_timeout=Iestฤjusies noildze, mฤฤฃinot, nolasฤซt atslฤgu. Pฤrlฤdฤjiet lapu un mฤฤฃiniet vฤlreiz.
+webauthn_error_timeout=Iestฤjฤs noildze, pirms varฤja nolasฤซt atslฤgu. Lลซgums pฤrlฤdฤt ลกo lapu un mฤฤฃinฤt vฤlreiz.
webauthn_reload=Pฤrlฤdฤt
-repository=Repozitorijs
-organization=Organizฤcija
-mirror=Spogulis
+repository=Glabฤtava
+organization=Apvienฤซba
+mirror=Spoguฤผglabฤtava
new_repo=Jauns repozitorijs
new_migrate=Jauna migrฤcija
-new_mirror=Jauns spogulis
-new_fork=Jauns atdalฤซts repozitorijs
+new_mirror=Jauna spoguฤผglabฤtava
+new_fork=Jauns glabฤtavas atzarojums
new_org=Jauna organizฤcija
new_project=Jauns projekts
-new_project_column=Jauna kolonna
+new_project_column=Jauna aile
manage_org=Pฤrvaldฤซt organizฤcijas
-admin_panel=Vietnes administrฤลกana
+admin_panel=Vietnes pฤrvaldฤซba
account_settings=Konta iestatฤซjumi
settings=Iestatฤซjumi
your_profile=Profils
-your_starred=Pievienots izlasฤ
+your_starred=Izlase
your_settings=Iestatฤซjumi
all=Visi
sources=Avoti
-mirrors=Spoguฤผi
-collaborative=Sadarbฤซbas
-forks=Atdalฤซtie
+mirrors=Spoguฤผglabฤtavas
+collaborative=Lฤซdzdarboลกanฤs
+forks=Atzarojumi
-activities=Aktivitฤte
+activities=Darbฤซbas
pull_requests=Izmaiลu pieprasฤซjumi
-issues=Problฤmas
+issues=Pieteikumi
milestones=Atskaites punkti
ok=Labi
cancel=Atcelt
retry=Mฤฤฃinฤt vฤlreiz
-rerun=Palaist atkฤrtoti
-rerun_all=Palaist atkฤrtoti visus darbus
+rerun=Atkฤrtoti izpildฤซt
+rerun_all=Atkฤrtoti izpildฤซt visus darbus
save=Saglabฤt
add=Pievienot
add_all=Pievienot visus
remove=Noลemt
remove_all=Noลemt visus
-remove_label_str=`Noลemt ierakstu "%s"`
+remove_label_str=Noลemt vienumu "%s"
edit=Labot
view=Skatฤซt
@@ -98,21 +98,21 @@ enabled=Iespฤjots
disabled=Atspฤjots
locked=Slฤgts
-copy=Kopฤt
-copy_url=Kopฤt saiti
-copy_hash=Kopฤt jaucฤjkodu
-copy_content=Kopฤt saturu
-copy_branch=Kopฤt atzara nosaukumu
-copy_success=Nokopฤts!
-copy_error=Kopฤลกana neizdevฤs
-copy_type_unsupported=ล ฤซ veida failus nav iespฤjams nokopฤt
+copy=Ievietot starpliktuvฤ
+copy_url=Ievietot URL starpliktuvฤ
+copy_hash=Ievietot jaucฤjvฤrtฤซbu starpliktuvฤ
+copy_content=Ievietot saturu starpliktuvฤ
+copy_branch=Ievietot zara nosaukumu starpliktuvฤ
+copy_success=Ievietots starpliktuvฤ.
+copy_error=Ievietoลกana starpliktuvฤ neizdevฤs
+copy_type_unsupported=ล ฤda veida datnes nevar ievietot starpliktuvฤ
write=Rakstฤซt
-preview=Priekลกskatฤซtฤซjums
+preview=Priekลกskatฤซjums
loading=Notiek ielฤdeโฆ
error=Kฤผลซda
-error404=Lapa, ko vฤlaties atvฤrt, neeksistฤ vai arฤซ Jums nav tiesฤซbas to aplลซkot.
+error404=ล ฤซ lapa vai nu nepastฤv , vai ir noลemta , vai arฤซ nav tiesฤซbu to apskatฤซt.
go_back=Atgriezties
never=Nekad
@@ -129,34 +129,63 @@ archived=Arhivฤtie
concept_system_global=Globฤls
concept_user_individual=Individuฤls
-concept_code_repository=Repozitorijs
-concept_user_organization=Organizฤcija
+concept_code_repository=Glabฤtava
+concept_user_organization=Apvienฤซba
-show_timestamps=Rฤdฤซt laika zฤซmogus
+show_timestamps=Rฤdฤซt laikspiedolus
show_log_seconds=Rฤdฤซt sekundes
-show_full_screen=Atvฤrt pilnฤ logฤ
+show_full_screen=Atvฤrt pilnekrฤnฤ
download_logs=Lejupielฤdฤt ลพurnฤlus
confirm_delete_selected=Apstiprinฤt, lai izdzฤstu visus atlasฤซtos vienumus?
name=Nosaukums
value=Vฤrtฤซba
+toggle_menu = Pฤrslฤgt izvฤlni
+more_items = Vairฤk vienumu
+error413 = Ir pฤrsniegts ierobeลพojums.
+new_repo.title = Jauna glabฤtava
+new_migrate.title = Jauna pฤrcelลกana
+new_org.title = Jauna apvienฤซba
+new_repo.link = Jauna glabฤtava
+new_migrate.link = Jauna pฤrcelลกana
+new_org.link = Jauna apvienฤซba
+invalid_data = Nederฤซgi dati: %v
+test = Pฤrbaude
+copy_generic = Ievietot starpliktuvฤ
+filter = Atlasฤซลกana
+filter.not_mirror = Nav spoguฤผglabฤtavas
+filter.is_template = Sagataves
+filter.not_template = Nav sagataves
+filter.is_archived = Arhivฤtas
+filter.not_archived = Nav arhivฤtas
+filter.is_fork = Atzarojumi
+filter.not_fork = Nav atzarojumi
+filter.is_mirror = Spoguฤผglabฤtavas
+filter.public = Atklฤtas
+filter.private = Privฤtas
+filter.clear = Notฤซrฤซt atlasi
+confirm_delete_artifact = Vai tieลกฤm izdzฤst artefaktu '%s'?
+copy_path = Ievietot ceฤผu starpliktuvฤ
[aria]
-navbar=Navigฤcijas josla
+navbar=Pฤrieลกanas josla
footer=Kฤjene
-footer.software=Par programmatลซru
+footer.software=Par ลกo programmatลซru
footer.links=Saites
[heatmap]
-number_of_contributions_in_the_last_12_months=%s darbฤซbas pฤdฤjo 12 mฤneลกu laikฤ
-contributions_zero=Nav aktivitฤtes
+number_of_contributions_in_the_last_12_months=%s iesaistes pฤdฤjo 12 mฤneลกu laikฤ
+contributions_zero=Nav iesaistฤซลกanos
less=Mazฤk
more=Vairฤk
+contributions_format = {contributions] {day}. {month}, {year}.
+contributions_few = iesaistฤซลกanฤs
+contributions_one = iesaistฤซลกanฤs
[editor]
-buttons.heading.tooltip=Pievienot virsrakstu
-buttons.bold.tooltip=Izcelt tekstu
+buttons.heading.tooltip=Virsraksts
+buttons.bold.tooltip=Treknraksts
buttons.italic.tooltip=Slฤซpraksta teksts
buttons.quote.tooltip=Citฤt tekstu
buttons.code.tooltip=Pievienot kodu
@@ -165,10 +194,22 @@ buttons.list.unordered.tooltip=Pievienot sarakstu
buttons.list.ordered.tooltip=Pievienot numurฤtu sarakstu
buttons.list.task.tooltip=Pievienot uzdevumu sarakstu
buttons.mention.tooltip=Pieminฤt lietotฤju vai komandu
-buttons.ref.tooltip=Atsaukties uz problฤmu vai izmaiลu pieprasฤซjumu
+buttons.ref.tooltip=Atsaukties uz pieteikumu vai izmaiลu pieprasฤซjumu
buttons.switch_to_legacy.tooltip=Izmantot vฤsturisko redaktoru
-buttons.enable_monospace_font=Izmantot vienฤda izmฤra fontu
-buttons.disable_monospace_font=Neizmantot vienฤda izmฤra fontu
+buttons.enable_monospace_font=Iespฤjot vienplatuma fontu
+buttons.disable_monospace_font=Atspฤjot vienplatuma fontu
+table_modal.placeholder.header = Galvene
+table_modal.placeholder.content = Saturs
+table_modal.label.rows = Rindas
+table_modal.label.columns = Ailes
+buttons.indent.tooltip = Pฤrvietot vienumus vienu lฤซmeni dziฤผฤk
+buttons.unindent.tooltip = Pฤrvietot vienumus vienu lฤซmeni augstฤk
+buttons.new_table.tooltip = Pievienot tabulu
+table_modal.header = Pievienot tabulu
+link_modal.header = Pievienot saiti
+link_modal.url = URL
+link_modal.description = Apraksts
+link_modal.paste_reminder = Norฤde: starpliktuvฤ esoลกu URL var ielฤซmฤt uzreiz redaktorฤ, lai izveidotu saiti.
[filter]
string.asc=A - Z
@@ -176,148 +217,156 @@ string.desc=Z - A
[error]
occurred=Radusies kฤผลซda
-report_message=Ja ir pฤrliecฤซba, ka ลกฤซ ir Gitea nepilnฤซba, lลซgums pฤrbaudฤซt GitHub , vai tฤ jau nav zinฤma, vai izveidot jaunu pieteikumu, ja nepiecieลกams.
+report_message=Ja ir pฤrliecฤซba, ka ลกฤซ ir Forgejo nepilnฤซba, lลซgums pฤrbaudฤซt Codeberg , vai tฤ jau nav zinฤma, vai izveidot jaunu pieteikumu, ja nepiecieลกams.
missing_csrf=Kฤผลซdains pieprasฤซjums: netika iesลซtฤซta droลกฤซbas pilnvara
invalid_csrf=Kฤผลซdains pieprasฤซjums: iesลซtฤซta kฤผลซdaina droลกฤซbas pilnvara
not_found=Pieprasฤซtie dati netika atrasti.
network_error=Tฤซkla kฤผลซda
+server_internal = Iekลกฤja servera kฤผลซda
[startpage]
-app_desc=Viegli uzstฤdฤms Git serviss
-install=Vienkฤrลกi instalฤjams
-install_desc=Vienkฤrลกi jฤpalaiลพ izpildฤmais fails vajadzฤซgajai platformai, jฤizmanto Docker , vai jฤiegลซst pakotne .
-platform=Pieejama daลพฤdฤm platformฤm
-platform_desc=Forgejo iespฤjams uzstฤdฤซt jebkur, kam Go var nokompilฤt: Windows, macOS, Linux, ARM utt. Izvฤlies to, kas tev patฤซk!
+app_desc=Paลกmitinฤms Git pakalpojums bez galvassฤpฤm
+install=Viegli uzstฤdฤซt
+install_desc=Vienkฤrลกi jฤpalaiลพ izpildฤmฤ datne vajadzฤซgajai sistฤmai, jฤizmanto Docker vai jฤiegลซst pakotne .
+platform=Daลพฤdas platformas
lightweight=Viegla
-lightweight_desc=Forgejo ir miminฤlas prasฤซbas un to var darbinฤt uz nedฤrga Raspberry Pi datora. Ietaupi savai ierฤซcei resursus!
+lightweight_desc=Forgejo ir zemas tehniskฤs prasฤซbas, un to var darbinฤt nedฤrgฤ Raspberry Pi datorฤ. Taupฤm savas ierฤซces patฤrฤto enerฤฃiju!
license=Atvฤrtฤ pirmkoda
-license_desc=Iegลซsti Forgejo ! Pievienojies un palฤซdzi uzlabot , lai padarฤซtu ลกo projektu vฤl labฤku! Nekautrฤjies un lฤซdzdarbojies!
+license_desc=Iegลซsti Forgejo ! Pievienojies mums lฤซdzdarbojoties , lai padarฤซtu ลกo projektu vฤl labฤku! Nekautrฤjies un lฤซdzdarbojies!
+platform_desc = Ir apstiprinฤts, ka Forgejo darbojas brฤซvฤs operฤtฤjsistฤmฤs, piemฤram, GNU/Linux un FreeBSD, kฤ arฤซ ar daลพฤdฤm procesoru arhitektลซrฤm. Izvฤlies to, kas patฤซk!
[install]
-install=Instalฤcija
+install=Uzstฤdฤซลกana
title=Sฤkotnฤjฤ konfigurฤcija
-docker_helper=Ja Forgejo ir uzstฤdฤซts Docker konteinerฤซ, izlasiet vadlฤซninas pirms mainฤt iestatฤซjumus.
-require_db_desc=Forgejo nepiecieลกams MySQL, PostgreSQL, SQLite3 vai TiDB (izmantojot MySQL protokolu).
-db_title=Datu bฤzes iestatฤซjumi
-db_type=Datu bฤzes veids
+docker_helper=Ja Forgejo ir uzstฤdฤซts Docker konteinerฤ, lลซgums izlasฤซt vadlฤซnijas , pirms tiek mainฤซti iestatฤซjumi.
+require_db_desc=Forgejo nepiecieลกams MySQL, PostgreSQL, SQLite3 vai TiDB (ar MySQL protokolu).
+db_title=Datubฤzes iestatฤซjumi
+db_type=Datubฤzes veids
host=Resursdators
user=Lietotฤjvฤrds
password=Parole
-db_name=Datu bฤzes nosaukums
+db_name=Datubฤzes nosaukums
db_schema=Shฤma
-db_schema_helper=Atstฤjiet tukลกu, lai izmantu datubฤzes noklusฤto ("public").
+db_schema_helper=Atstฤt tukลกu, lai izmantotu datubฤzes noklusฤjumu ("public").
ssl_mode=SSL
path=Ceฤผลก
-sqlite_helper=Faila ceฤผลก SQLite3 datubฤzei. Ievadiet absolลซto ceฤผu, ja Forgejo tiek startฤts kฤ serviss.
-reinstall_error=Nevar instalฤt datubฤzฤ, kura jau satur Forgejo datus
-reinstall_confirm_message=Veicot Forgejo datubฤzฤs atkฤrtotu instalฤลกanu, tas var izraisฤซt vairฤkas problฤmas. Bลซtu jฤizmanto esoลกais "app.ini", lai palaistu Forgejo. Apstipriniet, ja patieลกฤm vฤlaties to darฤซt:
-reinstall_confirm_check_1=Dati, kas ลกifrฤti ar SECRET_KEY atslฤgu, kas ir norฤdฤซta app.ini failฤ, var tikt pazaudฤti: lietotaji nevฤrฤs autorizฤties ar divfaktoru autorizฤciju, kฤ arฤซ spoguฤผi var pฤrstฤt darboties. Atzฤซmฤjot ลกo pazฤซmi, apstipriniet, ka paลกreizฤjais app.ini fails satur korektu SECRET_KEY vฤrtฤซbu.
-reinstall_confirm_check_2=Repozitorijus un iestatฤซjumus iespฤjams nepiecieลกams pฤrsinhronizฤt. Atzฤซmฤjot, apstipriniet, ka vฤlaties pฤrsinhronizฤt repozitorija ฤฤทus un authorized_keys failu. Pฤrliecinieties, ka repozitorija un spoguฤผoลกanas iestatฤซjumi ir pareizi.
-reinstall_confirm_check_3=Apstiprinat, ka esat pฤrliecinฤts, ka Forgejo izmanto pareizu app.ini faila atraลกanฤs vietu un patieลกฤm vฤlaties veikt atkฤrtotu instalฤciju, tฤpat apstiprinat, ka tas var radฤซt augstฤk minฤtฤs problฤmas.
-err_empty_db_path=Nav norฤdฤซts SQLite3 datu bฤzes ceฤผลก.
-no_admin_and_disable_registration=Reฤฃistrฤciju nevar atslฤgt, kamฤr nav izveidots administratora konts.
-err_empty_admin_password=Administratora kontam ir obligฤti jฤnorฤda parole.
-err_empty_admin_email=Administratora e-pasta adrese nevar bลซt tukลกa.
-err_admin_name_is_reserved=Administratora lietotฤjvฤrds nav korekts, ลกฤds lietotฤjvฤrds ir rezervฤts
-err_admin_name_pattern_not_allowed=Administratora lietotฤjvฤrds nav korekts, ลกฤds lietotฤjvฤrds nav atฤผauts
-err_admin_name_is_invalid=Administratora lietotฤja nav korekts
+sqlite_helper=SQLite3 datubฤzes datnes ceฤผลก. Jฤievada pilns ceฤผลก, ja Forgejo tiek palaists kฤ sistฤmas pakalpojums.
+reinstall_error=Tiek mฤฤฃinฤts uzstฤdฤซt esoลกฤ Forgejo datubฤzฤ
+reinstall_confirm_message=Atkฤrtota uzstฤdฤซลกana ar esoลกu Forgejo datubฤzi var izraisฤซt vairฤkas nebลซลกanas. Vairumฤ gadฤซjumu vajadzฤtu izmantot esoลกo "app.ini", lai palaistu Forgejo. Jฤapstiprina zemฤk esoลกais, ja ir skaidrs, kas tiek darฤซts:
+reinstall_confirm_check_1=Dati, kas ลกifrฤti ar SECRET_KEY, kas ir norฤdฤซta app.ini datnฤ, var tikt pazaudฤti: lietotฤji nevarฤs pieteikties ar 2FA/OTP, kฤ arฤซ spoguฤผglabฤtavas var pฤrstฤt darboties. Ar ลกฤซs izvฤles rลซtiลas atzฤซmฤลกanu tiek apstiprinฤts, ka paลกreizฤjฤ app.ini datne satur pareizu SECRET_KEY vฤrtฤซbu.
+reinstall_confirm_check_2=Glabฤtavas un iestatฤซjumus var bลซt nepiecieลกams atkฤrtoti sinhronizฤt. Ar ลกฤซs izvฤles rลซtiลas atzฤซmฤลกanu tiek apstiprinฤts, ka paลกrocฤซgi tiks veikta glabฤtavu aizฤทeru un authorized_keys datnes atkฤrtota sinhronizฤลกana. Tiek apstiprinฤts, ka tiks nodroลกinฤts, ka glabฤtavas un spoguฤผoลกanas iestatฤซjumi ir pareizi.
+reinstall_confirm_check_3=Ar ลกo tiek apstiprinฤts, ka ir pilnฤซga pฤrliecฤซba, ka Forgejo darbojas ar pareizu app.ini atraลกanฤs vietu un ka tieลกฤm ir nepiecieลกama atkฤrtota uzstฤdฤซลกana. Tiek apliecinฤts, ka iepriekลกminฤtais var novest pie kฤผลซmฤm.
+err_empty_db_path=SQLite3 datubฤzes ceฤผลก nevar bลซt tukลกs.
+no_admin_and_disable_registration=Lietotฤju reฤฃistrฤลกanos nevar atspฤjot bez pฤrvaldฤซtฤja konta izveidoลกanas.
+err_empty_admin_password=Pฤrvaldฤซtฤja parole nevar bลซt tukลกa.
+err_empty_admin_email=Pฤrvaldฤซtฤja e-pasta adrese nevar bลซt tukลกa.
+err_admin_name_is_reserved=Pฤrvaldฤซtฤja lietotฤjvฤrds ir nederฤซgs, ลกis lietotฤjvฤrds ir aizลemts
+err_admin_name_pattern_not_allowed=Pฤrvaldฤซtฤja lietotฤjvฤrds ir nederฤซgs, ลกis lietotฤjvฤrds atbilst aizลemto lietotฤjvฤrdu paraugam
+err_admin_name_is_invalid=Pฤrvaldฤซtฤja lietotฤjvฤrds ir nederฤซgs
-general_title=Vispฤrฤซgie iestatฤซjumi
+general_title=Vispฤrฤซgi iestatฤซjumi
app_name=Vietnes nosaukums
-app_name_helper=ล eit var ievadฤซt savas kompฤnijas nosaukumu.
-repo_path=Repozitoriju glabฤลกanas ceฤผลก
-repo_path_helper=Git repozitoriji tiks glabฤti ลกajฤ direktorijฤ.
-lfs_path=Git LFS glabฤลกanas vieta
-lfs_path_helper=Faili, kas pievienoti Git LFS, tiks glabฤti ลกajฤ direktorijฤ. Atstฤjiet tukลกu, lai atspฤjotu.
-run_user=Izpildes lietotฤjs
-run_user_helper=Operฤtฤjsistฤms lietotฤjs, ar kuru tiks palaists Gitea. Jฤลem vฤrฤ, ka ลกim lietotฤjam ir jฤbลซt piekฤผuvei repozitorija atraลกanฤs vietai.
-domain=Servera domฤns
+app_name_helper=ล eit ir ievadฤms sava servera nosaukums. Tas tiks attฤlots katrฤ lapฤ.
+repo_path=Glabฤtavu atraลกanฤs vieta
+repo_path_helper=Attฤlฤs Git glabฤtavas tiks saglabฤtas ลกajฤ mapฤ.
+lfs_path=Git LFS atraลกanฤs vieta
+lfs_path_helper=Datnes, kas pievienotas Git LFS, tiks glabฤtas ลกajฤ mapฤ. Atstฤt tukลกu, lai atspฤjotu.
+run_user=Lietotฤjs, ar kuru palaist
+run_user_helper=Operฤtฤjsistฤms lietotฤjs, ar kuru tiks palaists Forgejo. Jฤลem vฤrฤ, ka ลกim lietotฤjam ir jฤbลซt piekฤผuvei glabฤtavas atraลกanฤs vietai.
+domain=Servera domฤna vฤrds
domain_helper=Domฤns vai servera adrese.
ssh_port=SSH servera ports
-ssh_port_helper=Porta numurs, kuru SSH serveris klausฤซsies. Atstฤjiet tukลกu, lai atspฤjotu.
-http_port=Forgejo HTTP klausฤซลกanฤs ports
-http_port_helper=Porta numurs, kuru Forgejo tฤซmekฤผa serveris klausฤซsies.
-app_url=Forgejo pamata URL
+ssh_port_helper=Porta numurs, kuru izmantos SSH serveris. Atstฤt tukลกu, lai atspฤjotu SSH serveri.
+http_port=HTTP klausฤซลกanฤs ports
+http_port_helper=Porta numurs, kuru izmantos Forgejo tฤซmekฤผa serveris.
+app_url=Pamata URL
app_url_helper=Pamata adrese HTTP(S) klonฤลกanas URL un e-pastu paziลojumiem.
-log_root_path=ลฝurnalizฤลกanas ceฤผลก
-log_root_path_helper=ลฝurnalizฤลกanas faili tiks rakstฤซti ลกajฤ direktorijฤ.
+log_root_path=ลฝurnฤlu atraลกanฤs vieta
+log_root_path_helper=ลฝurnฤlu datnes tiks rakstฤซtas ลกajฤ mapฤ.
-optional_title=Neobligฤtie iestatฤซjumi
-email_title=E-pastu iestatฤซjumi
-smtp_addr=SMTP resursdators
+optional_title=Izvฤles iestatฤซjumi
+email_title=E-pasta iestatฤซjumi
+smtp_addr=SMTP saimniekdators
smtp_port=SMTP ports
-smtp_from=Nosลซtฤซt e-pastu kฤ
-smtp_from_helper=E-pasta adrese, ko Forgejo izmantos. Ievadiet tika e-pasta adrese vai izmantojiet "Vฤrds" formฤtu.
+smtp_from=Sลซtฤซt e-pasta ziลojumus kฤ
+smtp_from_helper=E-pasta adrese, ko izmantos Forgejo. Jฤievada tikai e-pasta adrese vai jฤizmanto pieraksts "Vฤrds" .
mailer_user=SMTP lietotฤjvฤrds
mailer_password=SMTP parole
-register_confirm=Reฤฃistrฤjoties pieprasฤซt apstiprinฤt e-pastu
+register_confirm=Reฤฃistrฤjoties pieprasฤซt e-pasta adreses apstiprinฤลกanu
mail_notify=Iespฤjot e-pasta paziลojumus
-server_service_title=Servera un citu servisu iestatฤซjumi
+server_service_title=Servera un treลกo puลกu pakalpojumu iestatฤซjumi
offline_mode=Iespฤjot bezsaistes reลพฤซmu
-offline_mode.description=Atspฤjot ฤrฤjos satura piegฤdes tฤซklus, lai visi resursi tiktu piegฤdฤti lokฤli.
+offline_mode.description=Atspฤjot ฤrฤjos satura piegฤdes tฤซklus, lai visi resursi tiktu nodroลกinฤti vietฤji.
disable_gravatar=Atspฤjot Gravatar
-disable_gravatar.description=Atspฤjot Gravatar un citus avotus, visus avatarus augลกupielฤdฤs lietotฤji vai izmantos noklusฤto attฤlu.
-federated_avatar_lookup=Iespฤjot apvienotฤs profila bildes
-federated_avatar_lookup.description=Iespฤjot apvienoto profila bilลพu meklฤtฤju, lai izmantotu atvฤrtฤ koda apvienoto servisu balstฤซtu uz Libravatar.
-disable_registration=Atspฤjot lietotฤju reฤฃistrฤciju
-disable_registration.description=Atspฤjot iespฤju reฤฃistrฤties. Tikai administratori varฤs izveidot jaunus kontus.
-allow_only_external_registration.description=Atฤผaut reฤฃistrฤties tikai ar ฤrฤjiem servisiem
+disable_gravatar.description=Atspฤjot Gravatar un citu treลกo puลกu attฤlu avotu izmantoลกanu. Kฤ lietotฤju attฤli tiks izmantoti noklusฤjuma attฤli, lฤซdz lietotฤji augลกupielฤdฤs paลกi savus.
+federated_avatar_lookup=Iespฤjot apvienotos profila attฤlus
+federated_avatar_lookup.description=Uzmeklฤt profila attฤlus ar Libravatar.
+disable_registration=Atspฤjot paลกreฤฃistrฤลกanos
+disable_registration.description=Tikai servera pฤrvaldฤซtฤji varฤs izveidot jaunus lietotฤju kontus. Ir ฤผoti ieteicams reฤฃistrฤลกanos paturฤt atspฤjotu, ja vien nav iecerฤts mitinฤt visiem pieejamu serveri un ir gatavฤซba tikt galฤ ar lielu negodprฤtฤซgu kontu skaitu.
+allow_only_external_registration.description=Lietotฤji varฤs izveidot jaunos kontus tikai izmantojot konfigurฤtus ฤrฤjos pakalpojumus.
openid_signin=Iespฤjot pieteikลกanos ar OpenID
-openid_signin.description=Iespฤjot lietotฤju pieteikลกanos ar OpenID.
-openid_signup=Iespฤjot reฤฃistrฤciju, izmantojot OpenID
-openid_signup.description=Iespฤjot lietotฤju reฤฃistrฤciju pirms tam autorizฤjoties ar OpenID.
+openid_signin.description=ฤปaut lietotฤjiem pieteikties ar OpenID.
+openid_signup=Iespฤjot paลกreฤฃistrฤลกanos ar OpenID
+openid_signup.description=ฤปaut lietotฤjiem izveidot kontus caur OpenID, ja ir iespฤjota paลกreฤฃistrฤลกanฤs.
enable_captcha=Pieprasฤซt droลกฤซbas kodu lietotฤju reฤฃistrฤcijฤ
-enable_captcha.description=Lietotฤjam reฤฃistrฤjoties, pieprasฤซt ievadฤซt droลกฤซbas kodu.
-require_sign_in_view=Pieprasฤซt pieteikลกanos, lai aplลซkotu lapas
-require_sign_in_view.description=Ierobeลพot piekฤผuvi lapฤm tikai lietotฤjiem, kuri ir pieteikuลกies. Apmeklฤtฤji redzฤs tikai pieteikลกanฤs un reฤฃistrฤลกanฤs lapu.
-admin_setting.description=Nav nepiecieลกams izveidot administratora kontu uzreiz, pirmais reฤฃistrฤtais lietotฤjs saลems administratora tiesฤซbas automฤtiski.
-admin_title=Administratora konta iestatฤซjumi
-admin_name=Administratora lietotฤjvฤrds
+enable_captcha.description=Pieprasฤซt lietotฤjus atrisinฤt CAPTCHA, lai varฤtu izveidot kontus.
+require_sign_in_view=Pieprasฤซt pieteikลกanos, lai skatฤซtu servera saturu
+require_sign_in_view.description=Ierobeลพot piekฤผuvi saturam tikai lietotฤjiem, kuri ir pieteikuลกies. Viesi varฤs apmeklฤt tikai autentificฤลกanฤs lapas.
+admin_setting.description=Var izvฤlฤties, vai izveidot pฤrvaldฤซtฤja kontu vai nฤ. Pirmais reฤฃistrฤtais lietotฤjs automฤtiski kฤผลซs par pฤrvaldฤซtฤju.
+admin_title=Pฤrvaldฤซtฤja konta iestatฤซjumi
+admin_name=Pฤrvaldฤซtฤja lietotฤjvฤrds
admin_password=Parole
-confirm_password=Apstipriniet paroli
+confirm_password=Apstiprinฤt paroli
admin_email=E-pasta adrese
-install_btn_confirm=Instalฤt Forgejo
-test_git_failed=Kฤผลซda pฤrbaudot 'git' komandu: %v
-sqlite3_not_available=Jลซsu paลกreizฤjฤ versija neatbalsta SQLite3, lลซdzu lejupielฤdฤjiet oficiฤlo binฤro versiju no %s, NEVIS gobuild versiju.
+install_btn_confirm=Uzstฤdฤซt Forgejo
+test_git_failed=Nevarฤja pฤrbaudฤซt "git" komandu: %v
+sqlite3_not_available=ล ฤซ Forgejo versija neatbalsta SQLite3. Lลซgums lejupielฤdฤt oficiฤlo binฤro versiju no %s (ne 'gobuild' versiju).
invalid_db_setting=Nederฤซgi datu bฤzes iestatฤซjumi: %v
invalid_db_table=Datubฤzes tabula "%s" ir kฤผลซdaina: %v
-invalid_repo_path=Nederฤซga repozitorija glabฤลกanas vieta: %v
-invalid_app_data_path=Lietojumprogrammas datu ceฤผลก ir kฤผลซdains: %v
-run_user_not_match=Izpildes lietotฤjs nav paลกreizฤjais lietotฤjs: %s -> %s
-internal_token_failed=Neizdevฤs uzฤฃenerฤt iekลกฤjฤs saziลas pilnvaru: %v
-secret_key_failed=Neizdevฤs uzฤฃenerฤt droลกฤซbas atslฤgu: %v
+invalid_repo_path=Nederฤซga glabฤtavu atraลกanฤs vieta: %v
+invalid_app_data_path=Lietotnes datu ceฤผลก ir nederฤซgs: %v
+run_user_not_match="Lietotฤjs, ar kuru palaist" lietotฤjvฤrds neatbilst paลกreizฤjam lietotฤjam: %s -> %s
+internal_token_failed=Neizdevฤs izveidot iekลกฤjo pilnvaru: %v
+secret_key_failed=Neizdevฤs izveidot droลกฤซbas atslฤgu: %v
save_config_failed=Neizdevฤs saglabฤt konfigurฤciju: %v
-invalid_admin_setting=Nederฤซgs administratora iestatฤซjums: %v
-invalid_log_root_path=Nederฤซgs ลพurnalizฤลกanas ceฤผลก: %v
+invalid_admin_setting=Pฤrvaldฤซtฤja konta iestatฤซjums ir nederฤซgs: %v
+invalid_log_root_path=ลฝurnฤla atraลกanฤs vieta ir nederฤซga: %v
default_keep_email_private=Pฤc noklusฤjuma slฤpt e-pasta adreses
-default_keep_email_private.description=ล ฤซ ir noklusฤtฤ pazฤซme, lai noteiktu lietotฤja e-pasta adreses redzamฤซbu. Atzฤซmฤjot to e-pasta adrese visiem jaunajiem lietotฤjiem nebลซs redzama lฤซdz lietotฤjs neizmainฤซs to savos iestatฤซjumos.
-default_allow_create_organization=Pฤc noklusฤjuma ฤผaut veidot organizฤcijas
-default_allow_create_organization.description=Atzฤซmฤjiet ลกo pazฤซmi, ja vฤlaties, lai jauniem lietotฤjiem pฤc noklusฤjuma tiek pieลกฤทirtas tiesฤซbas veidot organizฤcijas.
+default_keep_email_private.description=Pฤc noklusฤjuma iespฤjot e-pasta adreses slฤpลกanu jauniem lietotฤjiem, lai ลกฤซ informฤciju nenoplลซstu uzreiz pฤc reฤฃistrฤลกanฤs.
+default_allow_create_organization=Pฤc noklusฤjuma ฤผaut apvienฤซbu izveidoลกanu
+default_allow_create_organization.description=Pฤc noklusฤjuma ฤผaut jauniem lietotฤjiem izveidot apvienฤซbas. Kad ลกฤซ iespฤja ir atspฤjota, pฤrvaldฤซtฤjam bลซs jฤnodroลกina apvienฤซbu izveidoลกanas atฤผauja jaunajiem lieotฤjiem.
default_enable_timetracking=Pฤc noklusฤjuma iespฤjot laika uzskaiti
-default_enable_timetracking.description=Repozitorijiem pฤc noklusฤjuma tiks iespฤjota laika uzskaite atkarฤซbฤ no ลกฤซ iestatฤซjuma.
-no_reply_address=Neatbildฤt e-pasta adreses domฤns
-no_reply_address_helper=Domฤns lietotฤja e-pasta adresei git ลพurnฤlos, ja lietotฤjs izvฤlas paturฤt savu e-pasta adresi privฤtu. Piemฤram, ja lietotฤjs ir 'janis' un domฤns 'neatbildet.piemers.lv', tad e-pasta adrese bลซs 'janis@neatbildet.piemers.lv'.
-password_algorithm=Paroles jaucฤjsummas algoritms
+default_enable_timetracking.description=Pฤc noklusฤjuma ฤผaut laika uzskaites iespฤjas izmantoลกanu jaunฤs glabฤtavฤs.
+no_reply_address=Slฤpjamo e-pasta adreลกu domฤna vฤrds
+no_reply_address_helper=Domฤna vฤrds lietotฤjiem ar paslฤptu e-pasta adresi. Piemฤram, lietotฤjs 'janis' tiks ierakstฤซts ลพurnฤlฤ kฤ 'janis@noreply.example.org', ja kฤ paslฤpto e-pasta adreลกu domฤna vฤrds ir iestatฤซts 'noreply.example.org'.
+password_algorithm=Paroles jaucฤjkoda algoritms
invalid_password_algorithm=Kฤผลซdaina paroles jaucฤjfunkcija
-password_algorithm_helper=Norฤdiet paroles jaucฤjalgoritmu. Algoritmi atลกฤทirฤs pฤc prasฤซbฤm pret resursiem un stipruma. Argon2 algoritms ir droลกs, bet tam nepiecieลกams daudz operatฤซvฤs atmiลas, lฤซdz ar ko tas var nebลซt piemฤrots sistฤmฤm ar maz pieejamajiem resursiem.
-enable_update_checker=Iespฤjot jaunu versiju paziลojumus
+password_algorithm_helper=Jฤnorฤda paroles jaukลกanas algoritms. Algoritmiem ir atลกฤทirฤซgas prasฤซbas un stiprums. argon2 algoritms ir samฤrฤ droลกs, bet tas izmanto daudz atmiลas un var nebลซt piemฤrots mazฤm sistฤmฤm.
+enable_update_checker=Iespฤjot atjauninฤjumu pฤrbaudฤซtฤju
env_config_keys=Vides konfigurฤcija
-env_config_keys_prompt=ล ie vides mainฤซgie tiks pielietoti arฤซ konfigurฤcijas failฤ:
+env_config_keys_prompt=ล ie vides mainฤซgie tiks pielietoti arฤซ konfigurฤcijas datnฤ:
+smtp_from_invalid = "Sลซtฤซt e-pastu kฤ" adrese ir nederฤซga
+app_slogan = Servera sauklis
+config_location_hint = ล ฤซs konfigurฤcijas iespฤjas tiks saglabฤtas:
+allow_only_external_registration = Atฤผaut reฤฃistrฤลกanos tikai ar ฤrฤjiem pakalpojumiem
+allow_dots_in_usernames = Laut lietotฤjiem izmantot punktus savฤ lietotฤjvฤrdฤ. Neietekmฤ esoลกos kontus.
+app_slogan_helper = ล eit ir ievadฤms servera sauklis. Atstฤt tukลกu, lai atspฤjotu.
+enable_update_checker_helper_forgejo = Tas laiku pa laikam pฤrbaudฤซs, vai ir pieejamas jaunas Forgejo versijas, izmantojot release.forgejo.org TXT DNS ierakstu.
[home]
-uname_holder=Lietotฤjvฤrds vai e-pasts
+uname_holder=Lietotฤjvฤrds vai e-pasta adrese
password_holder=Parole
-switch_dashboard_context=Mainฤซt infopaneฤผa kontekstu
-my_repos=Repozitoriji
+switch_dashboard_context=Mainฤซt pฤrskata paneฤผa kontekstu
+my_repos=Glabฤtavas
show_more_repos=Parฤdฤซt vairฤk repozitorijusโฆ
collaborative_repos=Sadarbฤซbas repozitoriji
-my_orgs=Manas organizฤcijas
+my_orgs=Apvienฤซbas
my_mirrors=Mani spoguฤผi
-view_home=Skatฤซties %s
+view_home=Apskatฤซt %s
search_repos=Meklฤt repozitorijuโฆ
-filter=Citi filtri
-filter_by_team_repositories=Filtrฤt pฤc komandas repozitorijiem
-feed_of=`"%s" plลซsma`
+filter=Citas atlases
+filter_by_team_repositories=Atlasฤซt pฤc komandas glabฤtavฤm
+feed_of="%s" barotne
show_archived=Arhivฤtie
show_both_archived_unarchived=Attฤlot gan arhivฤtos, gan nearhivฤtos
@@ -325,16 +374,16 @@ show_only_archived=Attฤlot tikai arhivฤtos
show_only_unarchived=Attฤlot tikai nearhivฤtos
show_private=Privฤts
-show_both_private_public=Attฤlot gan publiskos, gan privฤtos
+show_both_private_public=Rฤda gan atklฤtฤs, gan privฤtฤs
show_only_private=Attฤlot tikai privฤtos
-show_only_public=Attฤlot tikai publiskos
+show_only_public=Attฤlo tikai atklฤtฤs
-issues.in_your_repos=Jลซsu repozitorijos
+issues.in_your_repos=Manฤs glabฤtavฤs
[explore]
-repos=Repozitoriji
+repos=Glabฤtavas
users=Lietotฤji
-organizations=Organizฤcijas
+organizations=Apvienฤซbas
search=Meklฤt
go_to=Iet uz
code=Kods
@@ -350,145 +399,178 @@ org_no_results=Netika atrasta neviena organizฤcija, kas atbilstu kritฤrijiem.
code_no_results=Netika atrasts pirmkods, kas atbilstu kritฤrijiem.
code_search_results=`Meklฤลกanas rezultฤti "%s"`
code_last_indexed_at=Pฤdฤjo reizi indeksฤts %s
-relevant_repositories_tooltip=Repozitoriju, kas ir atdalฤซti vai kuriem nav tฤmas, ikonas un apraksta ir paslฤpti.
-relevant_repositories=Tikai bลซtiskie repozitoriji tiek rฤdฤซti, pฤrฤdฤซt nefiltrฤtus rezultฤtus .
+relevant_repositories_tooltip=Glabฤtavas, kas ir atzarojumi vai kam nav temata, ikonas un apraksta, ir paslฤptas.
+relevant_repositories=Tiek rฤdฤซtas tikai atbilstoลกฤs glabฤtavas, rฤdฤซt neatsijฤtu iznฤkumu .
+stars_one = %d zvaigzne
+stars_few = %d zvaignznes
+forks_one = %d atzarojums
+forks_few = %d atzarojumi
[auth]
-create_new_account=Reฤฃistrฤt kontu
+create_new_account=Izveidot kontu
register_helper_msg=Jau ir konts? Piesakieties tagad!
social_register_helper_msg=Jau ir konts? Piesaisti to!
-disable_register_prompt=Reฤฃistrฤcija ir atspฤjota. Lลซdzu, sazinieties ar vietnes administratoru.
-disable_register_mail=Reฤฃistrฤcijas e-pasta apstiprinฤลกana ir atspฤjota.
-manual_activation_only=Sazinieties ar lapas administratoru, lai pabeigtu konta aktivizฤciju.
+disable_register_prompt=Reฤฃistrฤลกanฤs ir atspฤjota. Lลซgums sazinฤties ar vietnes pฤrvaldฤซtฤju.
+disable_register_mail=E-pasta adreses apstiprinฤลกana reฤฃistrฤjoties ir atspฤjota.
+manual_activation_only=Jฤsazinฤs ar vietnes pฤrvaldฤซtฤju, lai pabeigtu aktivฤลกanu.
remember_me=Atcerฤties ลกo ierฤซci
remember_me.compromised=Pieteikลกanฤs pilnvara vairs nav derฤซga, kas var norฤdฤซt uz ฤผaunprฤtฤซgฤm darbฤซbฤm kontฤ. Lลซgums pฤrbaudฤซt, vai kontฤ nav neparastu darbฤซbu.
-forgot_password_title=Aizmirsu paroli
+forgot_password_title=Aizmirsta parole
forgot_password=Aizmirsi paroli?
sign_up_now=Nepiecieลกams konts? Reฤฃistrฤjies tagad.
-sign_up_successful=Konts tika veiksmฤซgi izveidots. Laipni lลซdzam!
-confirmation_mail_sent_prompt=Jauns apstiprinฤลกanas e-pasts ir nosลซtฤซts uz %s , pฤrbaudies savu e-pasta kontu tuvฤko %s laikฤ, lai pabeigtu reฤฃistrฤcijas procesu.
-must_change_password=Mainฤซt paroli
+sign_up_successful=Konts tika sekmฤซgi izveidots. Laipni lลซdzam!
+confirmation_mail_sent_prompt=Jauns apstiprinฤลกanas e-pasta ziลojums tika nosลซtฤซts uz %s . Lลซgums pฤrbaudฤซt savu iesลซtni nฤkamajฤs %s, lai pabeigtu reฤฃistrฤลกanos. Ja e-pasta adrese ir nepareiza, ir iespฤjams pieteikties un pieprasฤซt vฤl viena apstiprinฤลกanas e-pasta ziลojuma nosลซtฤซลกanu uz citu adresi.
+must_change_password=Atjauninฤt savu paroli
allow_password_change=Pieprasฤซt lietotฤjam mainฤซt paroli (ieteicams)
-reset_password_mail_sent_prompt=Apstiprinฤลกanas e-pasts tika nosลซtฤซts uz %s . Pฤrbaudiet savu e-pasta kontu tuvฤko %s laikฤ, lai pabeigtu paroles atjaunoลกanas procesu.
-active_your_account=Aktivizฤt savu kontu
-account_activated=Konts ir aktivizฤts
-prohibit_login=Pieteikลกanฤs liegta
-prohibit_login_desc=Jลซsu konts ir bloฤทฤts, sazinieties ar sistฤmas administratoru.
-resent_limit_prompt=Jลซs pieprasฤซjฤt aktivizฤcijas e-pastu pฤrฤk bieลพi. Lลซdzu, uzgaidiet 3 minลซtes un mฤฤฃiniet vฤlreiz.
-has_unconfirmed_mail=Sveiki %s, Jums ir neapstiprinฤta e-pasta adrese (%s ). Ja neesat saลฤmis apstiprinฤลกanas e-pastu vai Jums ir nepiecieลกams nosลซtฤซt jaunu, lลซdzu, nospiediet pogu, kas atrodas zemฤk.
-resend_mail=Nospiediet ลกeit, lai vฤlreiz nosลซtฤซtu aktivizฤcijas e-pastu
+reset_password_mail_sent_prompt=Apstiprinฤjuma e-pasta ziลojums tika nosลซtฤซts uz %s . Lลซgums pฤrbaudฤซt savu iesลซtni un atvฤrt tajฤ saลemto saiti, lai pabeigtu konta atkopi.
+active_your_account=Aktivฤt savu kontu
+account_activated=Konts ir aktivฤts
+prohibit_login=Konta darbฤซba ir apturฤta
+prohibit_login_desc=Kontam ir liegts mijiedarboties ar serveri. Jฤsazinฤs ar tฤ pฤrvaldฤซtฤju, lai atgลซtu piekฤผuvi.
+resent_limit_prompt=Nesen jau tika pieprasฤซts aktivฤลกanas e-pasta ziลojums. Lลซgums uzgaidฤซt 3 minลซtes un mฤฤฃinฤt vฤlreiz.
+has_unconfirmed_mail=Sveiciens, %s! Tev ir neapstiprinฤta e-pasta adrese (%s ). Ja nav saลemts apstiprinฤjuma e-pasta ziลojums vai ir nepiecieลกams nosลซtฤซt jaunu, lลซgums klikลกฤทinฤt uz zemฤk esoลกฤs pogas.
+resend_mail=Klikลกฤทinฤt ลกeit, lai atkฤrtoti nosลซtฤซtu aktivฤลกanas e-pasta ziลojumu
email_not_associate=ล ฤซ e-pasta adrese nav saistฤซta ar nevienu kontu.
-send_reset_mail=Nosลซtฤซt paroles atjaunoลกanas e-pastu
-reset_password=Paroles atjaunoลกana
-invalid_code=Jลซsu apstiprinฤลกanas kodam ir beidzies derฤซguma termiลลก vai arฤซ tas ir nepareizs.
-invalid_code_forgot_password=Apliecinฤjuma kods ir nederฤซgs vai tฤ derฤซgums ir beidzies. Nospiediet ลกeit , lai uzsฤktu jaunu sesiju.
-invalid_password=Jลซsu parole neatbilst parolei, kas tika ievadฤซta veidojot so kontu.
+send_reset_mail=Nosลซtฤซt atkopes e-pasta ziลojumu
+reset_password=Konta atkope
+invalid_code=Apstiprinฤลกanas kods ir nederฤซgs, vai ir beidzies tฤ derฤซgums.
+invalid_code_forgot_password=Apstiprinฤลกanas kods ir nederฤซgs, vai tฤ derฤซgums ir beidzies. Jฤklikลกฤทina ลกeit , lai uzsฤktu jaunu sesiju.
+invalid_password=Parole neatbilst tai, kas tika izmantota konta izveidoลกanas laikฤ.
reset_password_helper=Atjaunot paroli
-reset_password_wrong_user=Jลซs esat pieteicies kฤ %s, bet konta atkopลกanas saite ir paredzฤta lietotฤjam %s
-password_too_short=Paroles garums nedrฤซkst bลซt mazฤks par %d simboliem.
+reset_password_wrong_user=Tu pieteicies kฤ %s, bet konta atkopes saite ir paredzฤta %s
+password_too_short=Paroles garums nevar bลซt mazฤks par %d rakstzฤซmฤm.
non_local_account=ฤrฤjie konti nevar mainฤซt paroli, izmantojot, Forgejo saskarni.
-verify=Pฤrbaudฤซt
+verify=Apliecinฤt
scratch_code=Vienreizฤjais kods
use_scratch_code=Izmantot vienreizฤjo kodu
-twofa_scratch_used=Vienreizฤjais kods tika izmantots. Notika pฤrvirzฤซลกana uz divfaktoru iestatฤซjumu lapu, lai varฤtu pฤrsaistฤซt jaunu ierฤซci vai uzฤฃenerฤt jaunu vienreizฤjo kodu.
-twofa_passcode_incorrect=Piekฤผuves kods nav pareizs. Ja esat pazaudฤjis ierฤซci, izmantojiet vienreizฤjo kodu, lai pieteiktos.
+twofa_scratch_used=Ir izmantots vienreizฤjais kods. Notika pฤrvirzฤซลกana uz divpakฤpju iestatฤซjumu lapu, lai varฤtu noลemt savas ierฤซces piesaisti vai izveidot jaunu vienreizฤjo kodu.
+twofa_passcode_incorrect=Piekฤผuves kods ir nepareizs. Ja ierฤซce ir pazaudฤta, jฤizmanto vienreizฤjais kods, lai pieteiktos.
twofa_scratch_token_incorrect=Ievadฤซts nepareizs vienreizฤjais kods.
login_userpass=Pieteikties
tab_openid=OpenID
-oauth_signup_tab=Reฤฃistrฤt jaunu kontu
-oauth_signup_title=Pabeigt konta veidoลกanu
-oauth_signup_submit=Pabeigt reฤฃistrฤciju
+oauth_signup_tab=Izveidot jaunu kontu
+oauth_signup_title=Pabeigt jauna konta izveidoลกanu
+oauth_signup_submit=Pabeigt konta izveidoลกanu
oauth_signin_tab=Sasaistฤซt ar esoลกu kontu
-oauth_signin_title=Pieteikties, lai autorizฤtu saistฤซto kontu
+oauth_signin_title=Pieteikties, lai pilnvarotu sasaistฤซto kontu
oauth_signin_submit=Sasaistฤซt kontu
-oauth.signin.error=Radฤs kฤผลซda apstrฤdฤjot pieteikลกanฤs pieprasฤซjumu. Ja ลกฤซ kฤผลซda atkฤrtojas, sazinieties ar lapas administratoru.
-oauth.signin.error.access_denied=Autorizฤcijas pieprasฤซjums tika noraidฤซts.
-oauth.signin.error.temporarily_unavailable=Pieteikลกanฤs neizdevฤs, jo autentifikฤcijas serveris ir ฤซslaicฤซgi nepieejams. Mฤฤฃiniet autorizฤties vฤlฤk.
+oauth.signin.error=Pilnvaroลกanas pieprasฤซjuma apstrฤdes laikฤ atgadฤซjฤs kฤผลซda. Jฤ tฤ atkฤrtojas, lลซgums sazinฤties ar vietnes pฤrvaldฤซtฤju.
+oauth.signin.error.access_denied=Pilnvaroลกanas pieprasฤซjums tika noraidฤซts.
+oauth.signin.error.temporarily_unavailable=Pilnvaroลกana neizdevฤs, jo autentificฤลกanฤs serveris ฤซslaicฤซgi nav pieejams. Lลซgums vฤlฤk mฤฤฃinฤt vฤlreiz.
openid_connect_submit=Pievienoties
openid_connect_title=Pievienoties jau esoลกam kontam
-openid_connect_desc=Izvฤlฤtais OpenID konts sistฤmฤ netika atpazฤซts, bet Jลซs to varat piesaistฤซt esoลกam kontam.
+openid_connect_desc=Izvฤlฤtais OpenID URI ir nezinฤms. Tas ir jฤasasaista ar jaunu kontu ลกeit.
openid_register_title=Izveidot jaunu kontu
-openid_register_desc=Izvฤlฤtais OpenID konts sistฤmฤ netika atpazฤซts, bet Jลซs to varat piesaistฤซt esoลกam kontam.
+openid_register_desc=Izvฤlฤtais OpenID URI ir nezinฤms. Tas ir jฤasasaista ar jaunu kontu ลกeit.
openid_signin_desc=Jฤievada OpenID URI. Piemฤram, anna.openid.example.org vai https://openid.example.org/anna.
-disable_forgot_password_mail=Konta atjaunoลกana ir atspฤjota, jo nav uzstฤdฤซti e-pasta servera iestatฤซjumi. Sazinieties ar lapas administratoru.
-disable_forgot_password_mail_admin=Kontu atjaunoลกana ir pieejama tikai, ja ir veikta e-pasta servera iestatฤซjumu konfigurฤลกana. Norฤdiet e-pasta servera iestatฤซjumus, lai iespฤjotu kontu atjaunoลกanu.
+disable_forgot_password_mail=Konta atkope ir atspฤjota, jo nav iestatฤซta e-pasta izsลซtฤซลกana. Lลซgums sazinฤties ar vietnes pฤrvaldฤซtฤju.
+disable_forgot_password_mail_admin=Kontu atkope ir pieejama tikai tad, kad ir veikta e-pasta servera iestatฤซลกana. Lลซgums iestatฤซt e-pasta serveri, lai varฤtu iespฤjot kontu atkopi.
email_domain_blacklisted=Nav atฤผauts reฤฃistrฤties ar ลกฤdu e-pasta adresi.
-authorize_application=Autorizฤt lietotni
-authorize_redirect_notice=Jลซs tiksiet nosลซtฤซts uz %s, ja autorizฤsiet ลกo lietotni.
+authorize_application=Pilnvarot lietotni
+authorize_redirect_notice=Notiks pฤrvirzฤซลกana uz %s, ja pilnvaroลกi ลกo lietotni.
authorize_application_created_by=ล o lietotni izveidoja %s.
-authorize_application_description=Ja pieลกฤทirsiet tiesฤซbas, tฤ varฤs piekฤผลซt un mainฤซt Jลซsu konta informฤciju, ieskaitot privฤtos repozitorijus un organizฤcijas.
-authorize_title=Autorizฤt "%s" piekฤผuvi jลซsu kontam?
-authorization_failed=Autorizฤcija neizdevฤs
-authorization_failed_desc=Autentifikฤcija neizdevฤs, jo tika veikts kฤผลซdains pieprasฤซjums. Sazinieties ar lietojumprogrammas, ar kuru mฤฤฃinฤjฤt autentificฤties, uzturฤtฤju.
+authorize_application_description=Ja nodroลกinฤsi piekฤผuvi, tฤ varฤs piekฤผลซt visai konta informฤcijai un mainฤซt to, tajฤ skaitฤ privฤtฤs glabฤtavas un apvienฤซbas.
+authorize_title=Pilnvarot "%s" piekฤผuvi Tavam kontam?
+authorization_failed=Pilnvaroลกana neizdevฤs
+authorization_failed_desc=Pilnvaroลกana neizdevฤs, jo tika noteikts nederฤซgs pieprasฤซjums. Lลซgums sazinฤties ar lietotnes, no kuras tika veikts pilnvaroลกanas pieprasฤซjums, uzturฤtฤju.
sspi_auth_failed=SSPI autentifikฤcija neizdevฤs
-password_pwned=Izvฤlฤtฤ parole ir nozagto paroฤผu sarakstฤ , kas iepriekลก ir atklฤts publiskฤs datu noplลซdฤs. Lลซgums mฤฤฃinฤt vฤlreiz ar citu paroli un apsvฤrt to nomainฤซt arฤซ citur.
+password_pwned=Izvฤlฤtฤ parole ir nozagto paroฤผu sarakstฤ , kas iepriekลก ir atklฤts pieejamฤs datu noplลซdฤs. Lลซgums mฤฤฃinฤt vฤlreiz ar citu paroli un apsvฤrt to nomainฤซt arฤซ citur.
password_pwned_err=Neizdevฤs pabeigt pieprasฤซjumu uz HaveIBeenPwned
+back_to_sign_in = Atpakaฤผ uz pieteikลกanos
+unauthorized_credentials = Pieteikลกanฤs dati ir nepareizi vai ir izbeiguลกies. Jฤizpilda komanda atkฤrtoti vai jฤizmanto %s, lai iegลซtu vairฤk informฤcijas
+hint_login = Jau ir konts? Pieteikties.
+last_admin = Nevar noลemt pฤdฤjo pฤrvaldฤซtฤju. Ir jฤbลซt vismaz vienam pฤrvaldฤซtฤjam.
+change_unconfirmed_email_error = Nebija iespฤjams nomainฤซt e-pasta adresi: %v
+hint_register = Nepiecieลกams konts? Reฤฃistrฤties.
+sign_up_button = Reฤฃistrฤties.
+use_onetime_code = Izmantot vienreiz izmantojamu kodu
+change_unconfirmed_email_summary = Nomainฤซt e-pasta adresi, uz kuru sลซtฤซt aktivฤลกanas e-pasta ziลojumu.
+change_unconfirmed_email = Ja reฤฃistrฤลกanฤs laikฤ tika iesniegta nepareiza e-pasta addrese, to zemฤk var nomainฤซt, un apstiprinฤjums tiks nosลซtฤซts uz jauno adresi.
+sign_in_openid = Turpinฤt ar OpenID
[mail]
-view_it_on=Aplลซkot %s
-reply=vai atbildiet uz e-pastu
-link_not_working_do_paste=Ja saite nestrฤdฤ, mฤฤฃiniet to nokopฤt un atvฤrt pฤrlลซkฤ.
-hi_user_x=Sveiki %s ,
+view_it_on=Apskatฤซt to %s
+reply=vai jฤatbild uz ลกo e-pasta ziลojumu
+link_not_working_do_paste=Saite nedarbojas? Jฤmฤฤฃina tฤ ievietot starpliktuvฤ un ielฤซmฤt pฤrlลซka adreลกu joslฤ.
+hi_user_x=Sveiciens, %s !
-activate_account=Lลซdzu, aktivizฤjiet savu kontu
+activate_account=Lลซgums aktivฤt savu kontu
activate_account.title=%s, aktivizฤjiet savu kontu
-activate_account.text_1=Sveiki %[1]s , esat reฤฃistrฤjies %[2]s!
-activate_account.text_2=Nospiediet uz saites, lai aktivizฤtu savu kontu lapฤ %s :
+activate_account.text_1=Sveiciens, %[1]s ! Paldies par reฤฃistrฤลกanos %[2]s!
+activate_account.text_2=Jฤklikลกฤทina uz ลกฤซs saites, lai aktivฤtu savu %s kontu:
-activate_email=Apstipriniet savu e-pasta adresi
+activate_email=Apliecini savu e-pasta adresi
activate_email.title=%s, apstipriniet savu e-pasta adresi
-activate_email.text=Nospiediet uz saites, lai apstiprinฤtu savu e-pasta adresi lapฤ %s :
+activate_email.text=Lลซgums klikลกฤทinฤt uz ลกฤซs saites, lai apliecinฤtu savu e-pasta adresi %s :
-register_notify=Laipni lลซdzam Forgejo
+register_notify=Laipni lลซdzam %s
register_notify.title=%[1]s, esat reฤฃistrฤjies %[2]s
-register_notify.text_1=ลกis ir reฤฃistrฤcijas apstiprinฤjuma e-pasts lapai %s!
-register_notify.text_2=Tagad varat autorizฤties ar lietotฤja vฤrdu: %s.
-register_notify.text_3=Ja ลกis konts Jums tika izveidots, tad obligฤti nomainiet citu paroli .
+register_notify.text_1=ล is ir apstiprinฤjuma e-pasta ziลojums reฤฃistrฤcijai %s.
+register_notify.text_2=Tagad var pieteikties ar savu lietotฤjvฤrdu: %s
+register_notify.text_3=Ja ลกo kontu izveidoja kฤds cits, vispirms ir nepiecieลกams iestatฤซt savu paroli .
reset_password=Atgลซt kontu
reset_password.title=%s, esat pieprasฤซjis atjaunot savu kontu
-reset_password.text=Nospiediet uz saites, lai atjaunotu savu kontu lapฤ %s :
+reset_password.text=Lลซgums klikลกฤทinฤt uz ลกฤซs saites, lai atjaunotu savu %s kontu:
-register_success=Veiksmฤซga reฤฃistrฤcija
+register_success=Reฤฃistrฤcija bija sekmฤซga
-issue_assigned.pull=@%[1]s pieลกฤทฤซra jums izmaiลu pieprasฤซjumu %[2]s repozitorijฤ %[3]s.
-issue_assigned.issue=@%[1]s pieลกฤทฤซra jums problฤmu %[2]s repozitorijฤ %[3]s.
+issue_assigned.pull=@%[1]s pieลกฤทฤซra izmaiลu pieprasฤซjumu %[2]s glabฤtavฤ %[3]s.
+issue_assigned.issue=@%[1]s pieลกฤทฤซra pieteikumu %[2]s glabฤtavฤ %[3]s.
-issue.x_mentioned_you=@%s pieminฤja Jลซs:
-issue.action.force_push=%[1]s veica piespiedu izmaiลu iesลซtฤซลกanu atzarฤ %[2]s no revฤซzijas %[3]s uz %[4]s.
-issue.action.push_1=@%[1]s iesลซtฤซja %[3]d revฤซziju atzarฤ %[2]s
-issue.action.push_n=@%[1]s iesลซtฤซja %[3]d revฤซzijas atzarฤ %[2]s
+issue.x_mentioned_you=@%s pieminฤja Tevi:
+issue.action.force_push=%[1]s uzspiesti aizgฤdฤja izmaiลas %[2]s no %[3]s uz %[4]s.
+issue.action.push_1=@%[1]s aizgฤdฤja %[3]d iesลซtฤซjumu uz %[2]s
+issue.action.push_n=@%[1]s aizgฤdฤja %[3]d iesลซtฤซjumus uz %[2]s
issue.action.close=@%[1]s aizvฤra #%[2]d.
issue.action.reopen=@%[1]s atkฤrtoti atvฤra #%[2]d.
-issue.action.merge=@%[1]s sapludinฤja #%[2]d atzarฤ %[3]s.
+issue.action.merge=@%[1]s iekฤผฤva #%[2]d zarฤ %[3]s.
issue.action.approve=@%[1]s apstiprinฤja izmaiลu pieprasฤซjumu.
issue.action.reject=@%[1]s pieprasฤซja izmaiลas ลกajฤ izmaiลu pieprasฤซjumฤ.
-issue.action.review=@%[1]s komentฤja ลกo izmaiลu pieprasฤซjumu.
-issue.action.review_dismissed=@%[1]s atmeta pฤdฤjo %[2]s recenziju ลกim izmaiลu pieprasฤซjumam.
-issue.action.ready_for_review=@%[1]s atzฤซmฤja ลกo izmaiลu pieprasฤซjumu, ka tas ir gatavs recenzฤลกanai.
+issue.action.review=@%[1]s pievienoja piebildi ลกim izmaiลu pieprasฤซjumam.
+issue.action.review_dismissed=@%[1]s atmeta pฤdฤjo ลกฤซ izmaiลu pieprasฤซjuma izskatฤซลกanu no %[2]s.
+issue.action.ready_for_review=@%[1]s atzฤซmฤja ลกo izmaiลu pieprasฤซjumu kฤ gatavu izskatฤซลกanai.
issue.action.new=@%[1]s izveidoja #%[2]d.
issue.in_tree_path=Ceฤผฤ %s:
-release.new.subject=Jauns laidiens %s repozitorijฤ %s
-release.new.text=@%[1]s izveidoja jaunu laidienu %[2]s repozitorijฤ %[3]s
+release.new.subject=Jauns laidiens %s glabฤtavฤ %s
+release.new.text=@%[1]s izveidoja jaunu laidienu %[2]s glabฤtavฤ %[3]s
release.title=Nosaukums: %s
release.note=Piezฤซmes:
release.downloads=Lejupielฤdes:
-release.download.zip=Izejas kods (ZIP)
-release.download.targz=Izejas kods (TAR.GZ)
+release.download.zip=Pirmkods (ZIP)
+release.download.targz=Pirmkods (TAR.GZ)
-repo.transfer.subject_to=%s vฤlas pฤrsลซtฤซt repozitoriju "%s" organizฤcijai %s
-repo.transfer.subject_to_you=`%s vฤlas Jums pฤrsลซtฤซt repozitoriju "%s"`
-repo.transfer.to_you=Jums
-repo.transfer.body=Ja vฤlaties to noraidฤซt vai apstiprinฤt, tad apmeklฤjiet saiti %s.
+repo.transfer.subject_to=%s vฤlas nodot glabฤtavu "%s" %s
+repo.transfer.subject_to_you=%s vฤlas nodot glabฤtavu "%s"
+repo.transfer.to_you=Tev
+repo.transfer.body=Lai to pieลemtu vai noraidฤซtu, jฤapmeklฤ %s vai arฤซ vienkฤrลกi var neลemt to vฤrฤ.
-repo.collaborator.added.subject=%s pievienoja Jลซs repozitorijam %s
-repo.collaborator.added.text=Jลซs tikฤt pievienots kฤ lฤซdzstrฤdnieks repozitorijam:
+repo.collaborator.added.subject=%s pievienoja Tevi glabฤtavai %s kฤ lฤซdzdalฤซbnieku
+repo.collaborator.added.text=Tevi pievienoja kฤ lฤซdzdalฤซbnieku glabฤtavฤ:
-team_invite.subject=%[1]s uzaicinฤja Jลซs pievienoties organizฤcijai %[2]s
-team_invite.text_1=%[1]s uzaicinฤja Jลซs pievienoties komandai %[2]s organizฤcijฤ %[3]s.
-team_invite.text_2=Uzspiediet uz ลกฤซs saites, lai pievienoties komandai:
-team_invite.text_3=Piezฤซme: ล is uzaicinฤjums ir paredzฤts %[1]s. Ja uzskatฤt, ka tas nav domฤts Jums, varat ignorฤt ลกo e-pastu.
+team_invite.subject=%[1]s uzaicinฤja pievienoties apvienฤซbai %[2]s
+team_invite.text_1=%[1]s uzaicinฤja pievienoties apvienฤซbas %[3] komandai %[2]s.
+team_invite.text_2=Lลซgums klikลกฤทinฤt uz sekojoลกฤs saites, lai pievienotos komandai:
+team_invite.text_3=Piezฤซme: ลกis uzaicinฤjums ir paredzฤts %[1]s. Ja ลกis ielลซgums netika gaidฤซts, ลกo e-pasta ziลojumu var neลemt vฤrฤ.
+totp_enrolled.subject = Ir aktivฤts TOTP kฤ divpakฤpju pieteikลกanฤs veids
+account_security_caution.text_1 = Ja tas biji Tu, tad ลกo e-pasta ziลojumu var droลกi neลemt vฤrฤ.
+account_security_caution.text_2 = Ja tas nebiji Tu, Tavฤ kontฤ var bลซt veiktas ฤผaunprฤtฤซgas darbฤซbas. Lลซgums sazinฤties ar ลกฤซs vietnes pฤrvaldฤซtฤjiem.
+totp_enrolled.text_1.no_webauthn = Kontam tikko tika iespฤjota TOTP. Tas nozฤซmฤ, ka visฤs turpmฤkajฤs pieteikลกanฤs kontฤ reizฤs bลซs jฤizmanto TOTP kฤ divpakฤpju pieteikลกanฤs veids.
+totp_enrolled.text_1.has_webauthn = Kontam tikko tika iespฤjota TOTP. Tas nozฤซmฤ, ka visฤs turpmฤkajฤs pieteikลกanฤs kontฤ reizฤs varฤs izmantot TOTP kฤ divpakฤpju pieteikลกanฤs veidu vai izmantot jebkuru no savฤm droลกฤซbas atslฤgฤm.
+admin.new_user.user_info = Informฤcija par lietotฤju
+admin.new_user.text = Lลซgums klikลกฤทinฤt ลกeit , lai pฤrvaldฤซtu ลกo lietotฤju pฤrvaldฤซลกanas panelฤซ.
+password_change.subject = Tika nomainฤซta parole
+primary_mail_change.text_1 = Konta galvenฤ e-pasta adrese tikko tika nomainฤซta uz %[1]s. Tas nozฤซmฤ, ka ลกajฤ e-pasta adresฤ vairs netiks saลemti e-pasta paziลojumi par kontu.
+primary_mail_change.subject = Tika nomainฤซta galvenฤ e-pasta adrese
+totp_disabled.subject = TOTP tika atspฤjota
+admin.new_user.subject = Tikko reฤฃistrฤjฤs jauns lietotฤjs %s
+password_change.text_1 = Tikko tika nomainฤซt konta parole.
+totp_disabled.text_1 = Kontฤ tikko tika iespฤjota laikฤ balstฤซta vienreiz izmantojama parole (TOTP).
+totp_disabled.no_2fa = Vairs nav citu konfigurฤtu 2FA veidu, kas nozฤซmฤ, ka vairs nav nepiecieลกams pieteikties savฤ kontฤ ar 2FA.
+removed_security_key.subject = Tika noลemta droลกฤซbas atslฤga
+removed_security_key.text_1 = No konta tikko kฤ tika noลemta droลกฤซbas atslฤga "%[1]s".
+removed_security_key.no_2fa = Vairs nav neviena cita konfigurฤta 2FA veida, kas nozฤซmฤ, ka vairs nav nepiecieลกams pieteikties savฤ kontฤ ar 2FA.
[modal]
yes=Jฤ
@@ -499,112 +581,127 @@ modify=Atjauninฤt
[form]
UserName=Lietotฤjvฤrds
-RepoName=Repozitorija nosaukums
+RepoName=Glabฤtavas nosaukums
Email=E-pasta adrese
Password=Parole
-Retype=Apstipriniet paroli
+Retype=Apstiprinฤt paroli
SSHTitle=SSH atslฤgas nosaukums
HttpsUrl=HTTPS URL
PayloadUrl=Vฤrtuma URL
TeamName=Komandas nosaukums
-AuthName=Autorizฤcijas nosaukums
-AdminEmail=Admin e-pasta adrese
+AuthName=Pilnvaroลกanas nosaukums
+AdminEmail=Pฤrvaldฤซtฤja e-pasta adrese
-NewBranchName=Jauna atzara nosaukums
-CommitSummary=Revฤซzijas kopsavilkums
-CommitMessage=Revฤซzijas ziลojums
-CommitChoice=Revฤซzijas izvฤle
-TreeName=Faila ceฤผลก
+NewBranchName=Jaunais zara nosaukums
+CommitSummary=Iesลซtฤซjuma kopsavilkums
+CommitMessage=Iesลซtฤซjuma ziลojums
+CommitChoice=Iesลซtฤซjuma izvฤle
+TreeName=Datnes ceฤผลก
Content=Saturs
SSPISeparatorReplacement=Atdalฤซtฤjs
SSPIDefaultLanguage=Noklusฤjuma valoda
require_error=` nedrฤซkst bลซt tukลกs.`
-alpha_dash_error=` drฤซkst saturฤt tikai latฤซลu alfabฤta burtus, ciparus vai domuzฤซmes (-_).`
-alpha_dash_dot_error=` drฤซkst saturฤt tikai latฤซลu alfabฤta burtus, ciparus, domuzฤซmes (-_) vai punktu.`
-git_ref_name_error=` jฤbลซt korektam git references nosaukumam.`
-size_error=` jฤbลซt %s simbolus garam.`
-min_size_error=` jabลซt vismaz %s simbolu garumฤ.`
-max_size_error=` jabลซt ne mazฤk kฤ %s simbolu garumฤ.`
+alpha_dash_error=` drฤซkst sastฤvฤt tikai no burtiem un cipariem, domuzฤซmฤm ("-") un apakลกsvฤซtrฤm ("_").`
+alpha_dash_dot_error=` drฤซkst sastฤvฤt tikai no burtiem un cipariem, domuzฤซmฤm ('-'), apakลกsvฤซtrฤm ('_') un punktiem ('.').`
+git_ref_name_error=` jฤbลซt pareizam Git atsauces nosaukumam.`
+size_error=` jฤbลซt %s rakstzฤซmes garam.`
+min_size_error=` jฤsatur vismaz %s rakstzฤซmes.`
+max_size_error=` jฤsatur ne vairฤk kฤ %s rakstzฤซmes.`
email_error=` nav derฤซga e-pasta adrese.`
-url_error=`"%s" nav korekts URL.`
+url_error=`"%s" nav derฤซgs URL.`
include_error=` ir jฤsatur tekstu "%s".`
-glob_pattern_error=` glob ลกablons nav korekts: %s.`
-regex_pattern_error=` regulฤrฤ izteiksme nav korekta: %s.`
-username_error=` drฤซkst saturฤt tikai burtus un ciparus ('0-9','a-z','A-Z'), domuzฤซme ('-'), apakลกsvฤซtra ('_') un punkts ('.'). Nevar sฤkties vai beigties ar simbolu, kas nav burts vai skaitlis, kฤ arฤซ nevar bลซt vairฤki simboli pฤc kฤrtas, kas nav burti vai skaitฤผi.`
-invalid_group_team_map_error=` sasaiste nav korekta: %s`
+glob_pattern_error=` glob paraugs nav derฤซgs: %s.`
+regex_pattern_error=` regulฤrฤ izteiksme nav derฤซga: %s.`
+username_error=` drฤซkst sastฤvฤt tikai no burtiem un cipariem ("0-9", "a-z", "A-Z"), domuzฤซmฤm ("-"), apakลกsvฤซtrฤm ("_") un punktiem ("."). Tas nevar sฤkties vai beigties ar rakstzฤซmi, kas nav burts vai cipars, kฤ arฤซ nav atฤผautas vairฤkas secฤซgas rakstzฤซmes, kas nav burti vai cipari.`
+invalid_group_team_map_error=` sasaiste nav derฤซga: %s`
unknown_error=Nezinฤma kฤผลซda:
captcha_incorrect=Ievadฤซts nepareizs droลกฤซbas kods.
password_not_match=Izvฤlฤtฤ parole nesakrฤซt ar atkฤrtoti ievadฤซto.
-lang_select_error=Izvฤlieties valodu no saraksta.
+lang_select_error=Atlasฤซt valodu no saraksta.
username_been_taken=Lietotฤjvฤrds jau ir aizลemts.
-username_change_not_local_user=Ne-lokฤlie lietotฤji nevar mainฤซt savus lietotฤjvฤrdus.
+username_change_not_local_user=ฤrฤjie lietotฤji nevar mainฤซt savu lietotฤjvฤrdu.
username_has_not_been_changed=Lietotฤjvฤrds netika mainฤซts
-repo_name_been_taken=Jau eksistฤ repozitorijs ar ลกฤdu nosaukumu.
-repository_force_private=Ir ieslฤgts piespiedu privฤtais reลพฤซms: repozitorijus nav iespฤjams padarฤซt publiskus.
-repository_files_already_exist=ล ฤซ repozitorija faili jau eksistฤ, sazinieties ar sistฤmas administratoru.
-repository_files_already_exist.adopt=ล ฤซ repozitorija faili jau eksistฤ un var tikt tikai pฤrลemti.
-repository_files_already_exist.delete=ล ฤซ repozitorija faili jau eksistฤ, nepiecieลกams tos dzฤst.
-repository_files_already_exist.adopt_or_delete=ล ฤซ repozitorija faili jau eksistฤ, tie ir jฤpฤrลem vai jฤdzฤลก.
+repo_name_been_taken=Glabฤtavas nosaukums jau tiek izmantots.
+repository_force_private=Iespฤjots "Uzspiest privฤtฤs": privฤtฤs glabฤtavas nevar padarฤซt pieejamas visiem.
+repository_files_already_exist=ล ajฤ glabฤtavฤ jau atrodas datnes. Jฤsazinฤs ar sistฤmas pฤrvaldฤซtฤju.
+repository_files_already_exist.adopt=ล ajฤ glabฤtavฤ jau atrodas datnes, un tฤs var tikai tikt pieลemtas.
+repository_files_already_exist.delete=ล ajฤ glabฤtavฤ jau atrodas datnes. Tฤs ir jฤizdzฤลก.
+repository_files_already_exist.adopt_or_delete=ล ajฤ glabฤtavฤ jau atrodas datnes. Vai nu tฤs ir jฤpieลem vai jฤizdzฤลก.
visit_rate_limit=Attฤlinฤtฤ piekฤผuve ir ierobeลพota ar ฤtruma ierobeลพotฤju.
-2fa_auth_required=Attฤlinฤtai piekฤผuvei ir nepiecieลกama divu faktoru autentifikฤcija.
-org_name_been_taken=Organizฤcijas nosaukums jau ir aizลemts.
+2fa_auth_required=Attฤlinฤtai piekฤผuvei ir nepiecieลกama divpakฤpju pieteikลกanฤs.
+org_name_been_taken=Apvienฤซbas nosaukums jau ir aizลemts.
team_name_been_taken=Komandas nosaukums jau ir aizลemts.
team_no_units_error=Komandai ir jฤbลซt iespฤjotai vismaz vienai sadaฤผai.
-email_been_used=E-pasta adrese jau ir izmantota.
-email_invalid=Epasta adrese nav korekta.
+email_been_used=E-pasta adrese jau tiek izmantota.
+email_invalid=E-pasta adrese nav derฤซga.
openid_been_used=OpenID adrese "%s" jau ir izmantota.
username_password_incorrect=Nepareizs lietotฤjvฤrds vai parole.
password_complexity=Parole neatbilst droลกฤซbas prasฤซbฤm:
password_lowercase_one=Vismaz viens mazais burts
password_uppercase_one=Vismaz viens lielais burts
password_digit_one=Vismaz viens cipars
-password_special_one=Vismaz viens speciฤlais simbols (punkts, iekavas, pฤdiลas utt.)
-enterred_invalid_repo_name=Pฤrliecinieties, vai ievadฤซtฤ repozitorija nosaukums ir pareizs.
-enterred_invalid_org_name=Ievadฤซtais organizฤcijas nosaukums ir nepareizs.
-enterred_invalid_owner_name=Pฤrliecinieties, vai ievadฤซtฤ ฤซpaลกnieka vฤrds ir pareizs.
-enterred_invalid_password=Pฤrliecinieties, vai ievadฤซtฤ parole ir pareiza.
-user_not_exist=Lietotฤjs neeksistฤ.
-team_not_exist=Komanda neeksistฤ.
-last_org_owner=Nevar noลemt pฤdejo lietotฤju no ฤซpaลกnieku komandas. Organizฤcijai ir jฤbลซt vismaz vienam ฤซpaลกniekam.
-cannot_add_org_to_team=Organizฤciju nevar pievienot kฤ komandas biedru.
-duplicate_invite_to_team=Lietotฤjs jau ir uzaicinฤts kฤ komandas biedrs.
-organization_leave_success=Jลซs esat pametis organizฤciju %s.
+password_special_one=Vismaz viena ฤซpaลกa rakstzฤซme (punkts, iekavas, pฤdiลas utt.)
+enterred_invalid_repo_name=Ievadฤซtais glabฤtavas nosaukums ir nepareizs.
+enterred_invalid_org_name=Ievadฤซtais apvienฤซbas nosaukums ir nepareizs.
+enterred_invalid_owner_name=Jaunฤ ฤซpaลกnieka vฤrds nav derฤซgs.
+enterred_invalid_password=Ievadฤซtฤ parole ir nepareiza.
+user_not_exist=Lietotฤjs nepastฤv.
+team_not_exist=Komanda nepastฤv.
+last_org_owner=Nevar noลemt ฤซpaลกnieku komandas pฤdฤjo lietotฤju. Apvienฤซbai ir jฤbลซt vismaz vienam ฤซpaลกniekam.
+cannot_add_org_to_team=Apvienฤซbu nevar pievienot kฤ komandas dalฤซbnieku.
+duplicate_invite_to_team=Lietotฤjs jau tika uzaicinฤts kฤ komandas dalฤซbnieks.
+organization_leave_success=Ir veiksmฤซgi atstฤta apvienฤซba %s.
invalid_ssh_key=Nav iespฤjams pฤrbaudฤซt SSH atslฤgu: %s
invalid_gpg_key=Nav iespฤjams pฤrbaudฤซt GPG atslฤgu: %s
invalid_ssh_principal=Kฤผลซdaina identitฤte: %s
-must_use_public_key=Atslฤga, ko norฤdฤซjฤt ir privฤtฤ atslฤga. Nekad nenodotiet savu privฤtu atslฤgu nevienam. Izmantojiet publisko atslฤgu.
-unable_verify_ssh_key=SSH atslฤgu nav iespฤjams pฤrbaudฤซt, pฤrliecinieties, ka tajฤ nav kฤผลซdu.
-auth_failed=Autentifikฤcija neizdevฤs: %v
+must_use_public_key=Norฤdฤซtฤ atslฤga ir privฤtฤ atslฤga. Lลซgums nekur neaugลกupielฤdฤt savu privฤto atslฤgu. Jฤizmanto sava publiskฤ atslฤga.
+unable_verify_ssh_key=SSH atslฤgu nav iespฤjams apliecinฤt. Kฤrtฤซgi jฤpฤrbauda, vai nav pieฤผautas kฤผลซdas.
+auth_failed=Autentificฤลกanฤs neizdevฤs: %v
-still_own_repo=ล is konts ir vismaz viena repozitorija ฤซpaลกnieks, tos sฤkumฤ ir nepiecieลกams izdzฤst vai mainฤซt to ฤซpaลกnieku.
-still_has_org=Jลซsu konts ir piesaistฤซts vismaz vienai organizฤcijai, sฤkumฤ nepiecieลกams to pamest.
-still_own_packages=Jลซsu kontam pieder viena vai vairฤkas pakotnes, tฤs nepiecieลกams izdzฤst.
-org_still_own_repo=Organizฤcijai pieder repozitoriji, tos sฤkumฤ ir nepiecieลกams izdzฤst vai mainฤซt to ฤซpaลกnieku.
-org_still_own_packages=ล ai organizฤcijai pieder viena vai vฤrฤkas pakotnes, tฤs nepiecieลกams izdzฤst.
+still_own_repo=Kontam pieder vismaz viena vai vairฤkas glabฤtavas, tฤs vispirms ir jฤizdzฤลก vai jฤnodod kฤdam.
+still_has_org=Konts ir vienas vai vairฤku apvienฤซbu dalฤซbnieks, vispirms tฤs ir jฤpamet.
+still_own_packages=Kontam pieder viena vai vairฤkas pakotnes, tฤs vispirms ir jฤizdzฤลก.
+org_still_own_repo=Apvienฤซbai joprojฤm pieder viena vai vairฤkas glabฤtavas, tฤs vispirms ir jฤizdzฤลก vai jฤnodod kฤdam.
+org_still_own_packages=ล ai apvienฤซbai joprojฤm pieder viena vai vairฤkas pakotnes, tฤs vispirms ir jฤizdzฤลก.
-target_branch_not_exist=Mฤrฤทa atzars neeksistฤ
+target_branch_not_exist=Mฤrฤทa zars nepastฤv.
+username_error_no_dots = ` var saturฤt tikai ciparus un burtus ("0-9", "a-z", "A-Z"), domuzฤซmi ("-") un apakลกsvฤซtru ("_"). Tas nevar sฤkties vai beigties ar rakstzฤซmi, kas nav cipars vai burts, un ir aizliegti arฤซ vairฤkas secฤซgas rakstzฤซmes, kas nav cipari vai burti.`
+required_prefix = Ievadฤซtajai vฤrtฤซbai jฤsฤkas ar "%s"
+admin_cannot_delete_self = Nevar izdzฤst savu kontu bลซdams pฤrvaldฤซtฤjs. Lลซgums vispirms noลemt savas pฤrvaldฤซtฤja tiesฤซbas.
+unset_password = Pieteicies lietotฤjs nav iestatฤซjis paroli.
+unsupported_login_type = Pieteikลกanฤs veids nenodroลกina konta izdzฤลกanu.
+Description = Apraksts
+Pronouns = Vientiekvฤrdi
+FullName = Pilns vฤrds
+Location = Atraลกanฤs vieta
+Biography = Dzฤซves un darbฤซbas apraksts
+Website = Tฤซmekฤผvietne
+AccessToken = Piekฤผuves pilnvara
+To = Zara nosaukums
+username_claiming_cooldown = ล o lietotฤjvฤrdu vฤl nevar izmantot, jo tฤ noilgums vฤl nav beidzies. To varฤs izmantot %[1]s.
+email_domain_is_not_allowed = Lietotฤja e-pasta adreses %s domฤna vฤrds ir pretrunฤt ar EMAIL_DOMAIN_ALLOWLIST vai EMAIL_DOMAIN_BLOCKLIST. Jฤpฤrliecinฤs, ka e-pasta adrese ir norฤdฤซta pareizi.
[user]
change_avatar=Mainฤซt profila attฤluโฆ
joined_on=Pievienojฤs %s
-repositories=Repozitoriji
-activity=Publiskฤ aktivitฤte
+repositories=Glabฤtavas
+activity=Atklฤti notikumi
followers_few=%d sekotฤji
-starred=Atzฤซmฤti repozitoriji
-watched=Vฤrotie repozitoriji
+starred=Izlasei pievienotฤs glabฤtavas
+watched=Vฤrotฤs glabฤtavas
code=Kods
projects=Projekti
overview=Pฤrskats
following_few=%d seko
follow=Sekot
-unfollow=Nesekot
-user_bio=Biogrฤfija
-disabled_public_activity=ล is lietotฤjs ir atslฤdzies iespฤju aplลซkot tฤ aktivitฤti.
+unfollow=Pฤrtraukt sekot
+user_bio=Apraksts par sevi
+disabled_public_activity=ล is lietotฤjs ir atspฤjojis darbฤซbu redzamฤซbu visiem.
email_visibility.limited=E-pasta adrese ir redzama visiem autentificฤtajiem lietotฤjiem
email_visibility.private=E-pasta adrese ir redzama tikai administratoriem
show_on_map=Rฤdฤซt ลกo vietu kartฤ
@@ -612,7 +709,26 @@ settings=Lietotฤja iestatฤซjumi
form.name_reserved=Lietotฤjvฤrdu "%s" nedrฤซkst izmantot.
form.name_pattern_not_allowed=Lietotฤjvฤrds "%s" nav atฤผauts.
-form.name_chars_not_allowed=Lietotฤja vฤrds "%s" satur neatฤผautus simbolus.
+form.name_chars_not_allowed=Lietotฤja vฤrds "%s" satur nederฤซgas rakstzฤซmes.
+followers.title.one = Sekotฤjs
+public_activity.visibility_hint.admin_private = ล ฤซ darbฤซba ir redzam tikai Tev, jo Tu esi pฤrvaldฤซtฤjs, bet lietotฤjs vฤlas palikt privฤts.
+public_activity.visibility_hint.self_private = Tava darbฤซba ir redzama tikai Tev un servera pฤrvaldฤซtฤjiem. Konfigurฤt .
+block_user.detail = Jฤลem vฤrฤ, ka lietotฤja liegลกanai ir arฤซ citas blakusparฤdฤซbas, piemฤram:
+block_user.detail_1 = Jลซs pฤrstฤsiet sekot viens otram un nevarฤsiet viens otram sekot.
+block_user.detail_2 = ล is lietotฤjs nevarฤs mijiedarboties ar Tev piederoลกajฤm glabฤtavฤm vai Tevis izveidotajiem pieteikumiem un piebildฤm.
+public_activity.visibility_hint.self_public = Tavas darbฤซbas ir redzamas ikvienam, izลemot mijiedarbฤซbas privฤtฤs vietฤs. Konfigurฤt .
+follow_blocked_user = Nevar sekot ลกim lietotฤjam, jo Tu noliedzi ลกo lietotฤju vai ลกis lietotฤjs ir noliedzis Tevi.
+block_user.detail_3 = Nebลซs iespฤjams pievienot citam citu kฤ glabฤtavas lฤซdzdalฤซbniekus.
+block = Noliegt
+unblock = Atฤผaut
+public_activity.visibility_hint.admin_public = ล ฤซ darbฤซba ir redzama ikvienam, bet kฤ pฤrvaldฤซtฤjs vari redzฤt mijiedarbฤซbas arฤซ privฤtฤs vietฤs.
+followers_one = %d sekotฤjs
+block_user = Liegt lietotฤju
+following_one = seko %d
+following.title.few = Seko
+public_activity.visibility_hint.self_private_profile = Tavas darbฤซbas ir redzamas tikai Tev un servera pฤrvaldฤซtฤjiem, jo Tavs profils ir pirvฤts. Konfigurฤt .
+followers.title.few = Sekotฤji
+following.title.one = Seko
[settings]
profile=Profils
@@ -624,154 +740,154 @@ avatar=Profila attฤls
ssh_gpg_keys=SSH / GPG atslฤgas
social=Sociฤlie konti
applications=Lietotnes
-orgs=Pฤrvaldฤซt organizฤcijas
-repos=Repozitoriji
-delete=Dzฤst kontu
-twofa=Divfaktoru autentifikฤcija
+orgs=Apvienฤซbas
+repos=Glabฤtavas
+delete=Izdzฤst kontu
+twofa=Divpakฤpju pieteikลกanฤs (TOTP)
account_link=Saistฤซtie konti
-organization=Organizฤcijas
+organization=Apvienฤซbas
uid=UID
-webauthn=Droลกฤซbas atslฤgas
+webauthn=Divpakฤpju pieteikลกanฤs (droลกฤซbas atslฤgas)
-public_profile=Publiskais profils
-biography_placeholder=Pastฤsti mums mazliet par sevi! (Var izmantot Markdown)
+public_profile=Visiem pieejamais profils
+biography_placeholder=Pastฤsti citiem mazliet par sevi! (Tiek atbalstฤซts Markdown)
location_placeholder=Kopฤซgot savu aptuveno atraลกanฤs vietu ar citiem
-profile_desc=Norฤdฤซt, kฤ profils tiek attฤlots citiem lietotฤjiem. Primฤrฤ e-pasta adrese tiks izmantota paziลojumiem, paroles atjaunoลกanai un Git tฤซmekฤผa darbฤซbฤm.
-password_username_disabled=Ne-lokฤliem lietotฤjiem nav atฤผauts mainฤซt savu lietotฤja vฤrdu. Sazinieties ar sistฤmas administratoru, lai uzzinฤtu sฤซkฤk.
+profile_desc=Par Tevi
+password_username_disabled=ฤrฤjiem lietotฤjiem nav atฤผauts mainฤซt savu lietotฤjvฤrdu. Lลซgums sazinฤties ar vietnes pฤrvaldฤซtฤju, lai uzzinฤtu vairฤk.
full_name=Pilns vฤrds
-website=Mฤjas lapa
+website=Tฤซmekฤผvietne
location=Atraลกanฤs vieta
-update_theme=Mainฤซt motฤซvu
-update_profile=Mainฤซt profilu
+update_theme=Mainฤซt izskatu
+update_profile=Atjauninฤt profilu
update_language=Mainฤซt valodu
update_language_not_found=Valoda "%s" nav pieejama.
update_language_success=Valoda tika nomainฤซta.
-update_profile_success=Jลซsu profila informฤcija tika saglabฤta.
+update_profile_success=Profils tika atjauninฤts.
change_username=Lietotฤjvฤrds mainฤซts.
change_username_prompt=Piezฤซme: lietotฤjvฤrda mainฤซลกana maina arฤซ konta URL.
-change_username_redirect_prompt=Iepriekลกฤjais lietotฤjvฤrds tiks pฤrvirzฤซts, kamฤr neviens cits to neizmanto.
+change_username_redirect_prompt=Iepriekลกฤjais lietotฤjvฤrds tiks pฤrvirzฤซts, lฤซdz kฤds to izmantos.
continue=Turpinฤt
cancel=Atcelt
language=Valoda
ui=Motฤซvs
-hidden_comment_types=Attฤlojot paslฤpt ลกauds komentฤrus:
-hidden_comment_types_description=Komentฤru veidi, kas atzฤซmฤti, netiks rฤdฤซti problฤmas lapฤ. Piemฤram, atzฤซmฤjot "Etiฤทetes" netiks rฤdฤซti komentฤri " pievienoja/noลฤma ".
-hidden_comment_types.ref_tooltip=Komentฤri, kad problฤmai tiek pievienota atsauce uz citu probฤmu, komentฤru, โฆ
-hidden_comment_types.issue_ref_tooltip=Komentฤri par lietotฤja izmaiลฤm ar problฤmas saistฤซto atzaru/tagu
+hidden_comment_types=Slฤpjamo piebilลพu veidi
+hidden_comment_types_description=ล eit atzฤซmฤtie piebilลพu veidi netiks attฤloti pieteikumu lapฤs. "Iezฤซme" atzฤซmฤลกana, piemฤram, noลems visas " pievienoja/noลฤma " piebildes.
+hidden_comment_types.ref_tooltip=Piebildes, kurฤs ir atsauces uz ลกo pieteikumu no cita pieteikuma/iesลซtฤซjuma/โฆ
+hidden_comment_types.issue_ref_tooltip=Piebildes, kurฤs lietotฤjs maina ar pieteikumu saistฤซtu zaru/birku
comment_type_group_reference=Atsauces
-comment_type_group_label=Etiฤทetes
+comment_type_group_label=Iezฤซme
comment_type_group_milestone=Atskaites punktus
comment_type_group_assignee=Atbildฤซgos
comment_type_group_title=Nosaukuma izmaiลas
-comment_type_group_branch=Atzara izmaiลas
-comment_type_group_time_tracking=Laika uzskaiti
+comment_type_group_branch=Zars
+comment_type_group_time_tracking=Laika uzskaitฤซลกana
comment_type_group_deadline=Termiลus
comment_type_group_dependency=Atkarฤซbas
-comment_type_group_lock=Slฤgลกanas maiลu
-comment_type_group_review_request=Izmaiลu pieprasฤซjumus
-comment_type_group_pull_request_push=Pievienotฤs revฤซzijas
-comment_type_group_project=Projektus
-comment_type_group_issue_ref=Problฤmu atsauces
-saved_successfully=Iestatฤซjumi tika veiksmฤซgi saglabati.
+comment_type_group_lock=Aizslฤgลกanas stฤvoklis
+comment_type_group_review_request=Izskatฤซลกanas pieprasฤซjums
+comment_type_group_pull_request_push=Pievienotie iesลซtฤซjumi
+comment_type_group_project=Projekts
+comment_type_group_issue_ref=Pieteikumu atsauces
+saved_successfully=Iestatฤซjumi tika sekmฤซgi saglabฤti.
privacy=Privฤtums
keep_activity_private=Profila lapฤ paslฤpt notikumus
keep_activity_private_popup=Savu aktivitฤti redzฤsiet tikai Jลซs un administratori
-lookup_avatar_by_mail=Meklฤt profila bildes pฤc e-pasta
+lookup_avatar_by_mail=Uzmeklฤt profila attฤlus pฤc e-pasta adreses
federated_avatar_lookup=Apvienotais profila bilลพu meklฤtฤjs
-enable_custom_avatar=Iespฤjot mainฤmu profila attฤlu
+enable_custom_avatar=Izmantot pielฤgotu profila attฤlu
choose_new_avatar=Izvฤlฤties jaunu profila attฤlu
-update_avatar=Saglabฤt profila bildi
-delete_current_avatar=Dzฤst paลกreizฤjo profila bildi
-uploaded_avatar_not_a_image=Augลกupielฤdฤtais fails nav attฤls.
-uploaded_avatar_is_too_big=Augลกupielฤdฤtฤ faila izmฤrs (%d KiB) pฤrsniedz pieฤผaujamo izmฤru (%d KiB).
+update_avatar=Atjauninฤt attฤlu
+delete_current_avatar=Izdzฤst paลกreizฤjo attฤlu
+uploaded_avatar_not_a_image=Augลกupielฤdฤtฤ datne nav attฤls.
+uploaded_avatar_is_too_big=Augลกupielฤdฤtฤs datnes izmฤrs (%d KiB) pฤrsniedz pieฤผaujamo lielumu (%d KiB).
update_avatar_success=Profila attฤls tika saglabฤts.
-update_user_avatar_success=Lietotฤja profila attฤls tika atjaunots.
+update_user_avatar_success=Lietotฤja profila attฤls tika atjauninฤts.
-update_password=Mainฤซt paroli
+update_password=Atjauninฤt paroli
old_password=Paลกreizฤjฤ parole
-new_password=Jauna parole
+new_password=Jaunฤ parole
retype_new_password=Apstiprinฤt jauno paroli
password_incorrect=Ievadฤซta nepareiza paลกreizฤjฤ parole.
-change_password_success=Parole tika veiksmฤซgi nomainฤซta. Tagad varat pieteikties ar jauno paroli.
-password_change_disabled=ฤrฤjie konti nevar mainฤซt paroli, izmantojot, Forgejo saskarni.
+change_password_success=Parole tika atjauninฤta. Turpmฤk jฤizmanto sava jaunฤ parole, lai pieteiktos.
+password_change_disabled=ฤrฤjie lietotฤji nevar mainฤซt savu paroli Forgejo tฤซmekฤผa saskarnฤ.
emails=E-pasta adreses
manage_emails=Pฤrvaldฤซt e-pasta adreses
-manage_themes=Izvฤlieties noklusฤjuma motฤซvu
-manage_openid=Pฤrvaldฤซt OpenID adreses
-email_desc=Primฤrฤ e-pasta adrese tiks izmantota paziลojumiem, paroฤผu atjaunoลกanai un, ja tฤ nav paslฤpta, Git tฤซmekฤผa darbฤซbฤm.
-theme_desc=ล is bลซs noklusฤjuma motฤซvs visiem lietotฤjiem.
-primary=Primฤrฤ
-activated=Aktivizฤts
-requires_activation=Nepiecieลกams aktivizฤt
-primary_email=Uzstฤdฤซt kฤ primฤro
-activate_email=Nosลซtฤซt aktivizฤcijas e-pastu
-activations_pending=Gaida aktivizฤciju
-can_not_add_email_activations_pending=Ir nepabeigta aktivizฤcija. Pฤc daลพฤm minลซtฤm mฤฤฃiniet vฤlreiz, ja ir vฤlme pievienot jaunu e-pasta adresi.
+manage_themes=Noklusฤjuma izskats
+manage_openid=OpenID adreses
+email_desc=Galvenฤ e-pasta adrese tiks izmantota paziลojumiem, paroฤผu atkopei un, ja tฤ nav paslฤpta, Git tฤซmekฤผa darbฤซbฤm.
+theme_desc=ล is izskats tiks izmantots tฤซmekฤผa saskarnei pฤc pieteikลกanฤs.
+primary=Galvenฤ
+activated=Aktivฤts
+requires_activation=Nepiecieลกama aktivฤลกana
+primary_email=Padarฤซt par galveno
+activate_email=Nosลซtฤซt aktivฤลกanas e-pasta ziลojumu
+activations_pending=Gaida aktivฤลกanu
+can_not_add_email_activations_pending=Ir nepabeigta aktivฤลกana. Pฤc daลพฤm minลซtฤm jฤmฤฤฃina vฤlreiz, ja ir vฤlme pievienot jaunu e-pasta adresi.
delete_email=Noลemt
-email_deletion=Dzฤst e-pasta adresi
-email_deletion_desc=E-pasta adrese un ar to saistฤซtฤ informฤcija tiks dzฤsta no ลกฤซ konta. Git revฤซzijas ar ลกo e-pasta adresi netiks mainฤซtas. Vai turpinฤt?
-email_deletion_success=E-pasta adrese ir veiksmฤซgi izdzฤsta.
-theme_update_success=Jลซsu motฤซvs tika nomainฤซts.
-theme_update_error=Izvฤlฤtais motฤซvs neeksistฤ.
+email_deletion=Noลemt e-pasta adresi
+email_deletion_desc=E-pasta adrese un saistฤซtฤ informฤcija tiks noลemta no ลกฤซ konta. Git iesลซtฤซjumi ar ลกo e-pasta adresi paliks nemainฤซti. Turpinฤt?
+email_deletion_success=E-pasta adrese tika sekmฤซgi izdzฤsta.
+theme_update_success=Izskats tika atjauninฤts.
+theme_update_error=Atlasฤซtais izskats nepastฤv.
openid_deletion=Dzฤst OpenID adresi
-openid_deletion_desc=Dzฤลกot ลกo OpenID adresi no Jลซsu konta, ar to vairs nebลซs iespฤjams pieteikties. Vai turpinฤt?
+openid_deletion_desc=ล ฤซs OpenID adreses noลemลกana no konta liegs iespฤju pieteikties ar to. Turpinฤt?
openid_deletion_success=OpenID adrese tika noลemta.
-add_new_email=Pievienot jaunu e-pasta adresi
-add_new_openid=Pievienot jaunu OpenID vietrฤdi
+add_new_email=Pievienot e-pasta adresi
+add_new_openid=Pievienot jaunu OpenID URI
add_email=Pievienot e-pasta adresi
add_openid=Pievienot OpenID vietrฤdi
-add_email_confirmation_sent=Jauns apstiprinฤลกanas e-pasts tika nosลซtฤซts uz "%s". Pฤrbaudiet savu e-pasta kontu tuvฤko %s laikฤ, lai apstiprinฤtu savu e-pasta adresi.
-add_email_success=Jลซsu jaunฤ e-pasta adrese tika veiksmฤซgi pievienota.
-email_preference_set_success=E-pasta izvฤle tika veiksmฤซgi saglabฤta.
-add_openid_success=Jลซsu jaunฤ OpenID adrese tika veiksmฤซgi pievienota.
-keep_email_private=Paslฤpt e-pasta adresi
-keep_email_private_popup=ล is profilฤ paslฤps e-pasta adresi, kฤ arฤซ tad, kad tiks veikts izmaiลu pieprasฤซjums vai tฤซmekฤผa saskarnฤ labota datne. Aizgฤdฤtie iesลซtฤซjumi netiks pฤrveidoti. Revฤซzijฤs jฤizmanto %s, lai sasaistฤซtu tos ar kontu.
-openid_desc=Jลซsu OpenID adreses ฤผauj autorizฤties, izmantojot, Jลซsu izvฤlฤto pakalpojumu sniedzฤju.
+add_email_confirmation_sent=Apstiprinฤลกanas e-pasta ziลojums tika nosลซtฤซts uz "%s". Lai apstiprinฤtu savu e-pasta adresi, lลซgums pฤrbaudฤซt savu iesลซti un atvฤrt nosลซtฤซto saiti nฤkamฤjฤs %s.
+add_email_success=Jaunฤ e-pasta adrese tika pievienota.
+email_preference_set_success=E-pasta izvฤle tika sekmฤซgi iestatฤซta.
+add_openid_success=Jaunฤ OpenID adrese tika pievienota.
+keep_email_private=Slฤpt e-pasta adresi
+keep_email_private_popup=E-pasta adrese netiks rฤdฤซta profilฤ un netiks izmantota kฤ noklusฤjums iesลซtฤซjumiem, kuri veikti tฤซmekฤผa saskarnฤ, piemฤram, datลu augลกupielฤdes, laboลกanas un apvienoลกanas iesลซtฤซjumi. Tฤ vietฤ ฤซpaลกa adrese %s var tikt izmantota, lai sasaistฤซtu iesลซtฤซjumus ar kontu. ล ฤซ iespฤja neietekmฤs esoลกos iesลซtฤซjumus.
+openid_desc=OpenID ฤผauj uzticฤt autentificฤลกanu ฤrฤjam nodroลกinฤtฤjam.
manage_ssh_keys=Pฤrvaldฤซt SSH atslฤgas
manage_ssh_principals=Pฤrvaldฤซt SSH sertifikฤtu identitฤtes
manage_gpg_keys=Pฤrvaldฤซt GPG atslฤgas
add_key=Pievienot atslฤgu
-ssh_desc=ล ฤซs SSH atslฤgas ir piesaistฤซtas Jลซsu kontam. Ir svarฤซgi pฤrliecinฤties, ka visas atpazฤซstat, jo tฤs ฤผauj piekฤผลซt Jลซsu repozitorijiem.
-principal_desc=ล ฤdas SSH sertifikฤtu identitiฤtes ir piesaistฤซtas kontam un ar tฤm iespฤjams piekฤผลซt visiem jลซsu repozitorijiem.
-gpg_desc=ล ฤซs publiskฤs GPG atslฤgas ir saistฤซtas ar Jลซsu kontu. Paturiet privฤtฤs atslฤgas droลกฤซbฤ, jo tฤs ฤผauj parakstฤซt revฤซzijas.
-ssh_helper=Vajadzฤซga palฤซdzฤซba? Iepazฤซstieties ar GitHub pamฤcฤซbu kฤ izveidot jaunu SSH atslฤgu vai atrisinฤtu bieลพฤk sastopamฤs problฤmas ar kurฤm varat saskarties, izmantojot SSH.
-gpg_helper=Vajadzฤซga palฤซdzฤซba? Iepazฤซstieties ar GitHub pamฤcฤซbu par GPG .
+ssh_desc=ล ฤซs publiskฤs SSH atslฤgas ir pievienotas kontam. Atbilstoลกas privฤtฤs atslฤgas nodroลกina pilnu piekฤผuvi glabฤtavฤm. Apliecinฤtas SSH atslฤgas var tikt izmantotas SSH parakstฤซtu Git iesลซtฤซjumu apliecinฤลกanai.
+principal_desc=ล ฤซs SSH sertifikฤtu identitฤtes ir pievienotas kontam un ฤผauj pilnu piekฤผuvi Tavฤm glabฤtavฤm.
+gpg_desc=ล ฤซs publiskฤs GPG atslฤgas ir saistฤซtas ar kontu un tiek izmantotas, lai apliecinฤtu iesลซtฤซjumus. Savas privฤtฤs atslฤgas ir jฤtur droลกฤซbฤ, jo tฤs ฤผauj parakstฤซt iesลซtฤซjumus Tavฤ vฤrdฤ.
+ssh_helper=Vajadzฤซga palฤซdzฤซba? Ir vฤrts ieskatฤซties GitHub pamฤcฤซbฤ par jaunas SSH atslฤgas izveidoลกanu vai bieลพฤk sastopamo sareลพฤฃฤซjumu , ar kuriem var saskarties SSH izmantoลกanas laikฤ, novฤrลกanu.
+gpg_helper=Nepiecieลกama palฤซdzฤซba? Ir vฤrts ieskatฤซties GitHub vadlฤซnijฤs par GPG .
add_new_key=Pievienot SSH atslฤgu
add_new_gpg_key=Pievienot GPG atslฤgu
-key_content_ssh_placeholder=Sฤkas ar 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com' vai 'sk-ssh-ed25519@openssh.com'
-key_content_gpg_placeholder=Sฤkas ar '-----BEGIN PGP PUBLIC KEY BLOCK-----'
+key_content_ssh_placeholder=Sฤkas ar "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com" vai "sk-ssh-ed25519@openssh.com"
+key_content_gpg_placeholder=Sฤkas ar "-----BEGIN PGP PUBLIC KEY BLOCK-----"
add_new_principal=Pievienot identitฤti
ssh_key_been_used=ล ฤซ SSH atslฤga jau ir pievienota ลกajฤ serverฤซ.
-ssh_key_name_used=SSH atslฤga ar ลกฤdu nosaukumu ลกim kontam jau eksistฤ.
+ssh_key_name_used=SSH atslฤga ar tฤdu paลกu nosaukumu jau ir kontฤ.
ssh_principal_been_used=ล ฤda identitฤte jau ir pievienota ลกฤjฤ serverฤซ.
-gpg_key_id_used=Publiskฤ GPG atslฤga ar ลกฤdu ID jau eksistฤ.
-gpg_no_key_email_found=GPG atslฤga neatbilst nevienai Jลซsu konta aktivizฤtajai e-pasta adresei. ล o atslฤgu ir iespฤjams pievienot, veicot, pilnvaras parakstฤซลกanu.
+gpg_key_id_used=Jau pastฤv publiska GPG atslฤga ar tฤdu paลกu identifikatoru.
+gpg_no_key_email_found=ล ฤซ GPG atslฤga neatbilst nevienai ar kontu saistฤซtajai e-pasta adresei. To joprojฤm var pievienot, ja tiek parakstฤซta norฤdฤซtฤ pilnvara.
gpg_key_matched_identities=Atbilstoลกฤs identitฤtes:
-gpg_key_matched_identities_long=Iegultฤs identitฤtes ลกฤjฤ atslฤgฤ atbilst sekojoลกฤm aktivizฤtฤm e-pasta adresฤm ลกim lietotajam. Revฤซzijas ar atbilstoลกฤm e-pasta adresฤm var tik pฤrbaudฤซtas ar ลกo atslฤgu.
-gpg_key_verified=Pฤrbaudฤซtฤ atslฤga
-gpg_key_verified_long=Atslฤga tika apliecinฤta ar pilnvaru un var tikt izmantota, lai pฤrbaudฤซtu revฤซzijas, kas atbilst jebkurai apstiprinฤtai e-pasta adresei ลกim lietotฤjam papildus ลกฤซs atslฤgas atbilstoลกajฤm identitฤtฤm.
+gpg_key_matched_identities_long=ล ajฤ atslฤgฤ iegultฤs identitฤtes atbilst zemฤk uzskaitฤซtฤjฤm aktivฤtajฤm ลกฤซ lietotฤja e-pasta adresฤm. Iesลซtฤซjumus, kas atbilst ลกฤซm e-pasta adresฤm, var apliecinฤt ar ลกo atslฤgu.
+gpg_key_verified=Apliecinฤta atslฤga
+gpg_key_verified_long=Atslฤga tika apliecinฤta ar pilnvaru un var tikt izmantota, lai apliecinฤtu iesลซtฤซjumus, kas atbilst jebkurai apstiprinฤtai ลกฤซ lietotฤja e-pasta adresei papildus jebkurai ลกai atslฤgai atbilstoลกai identitฤtei.
gpg_key_verify=Pฤrbaudฤซt
gpg_invalid_token_signature=Norฤdฤซtฤ GPG atslฤga, paraksts un pilnvara neatbilst vai tai ir beidzies derฤซguma termiลลก.
gpg_token_required=Jฤnorฤda paraksts zemฤk esoลกajai pilnvarai
gpg_token=Pilnvara
-gpg_token_help=Parakstu ir iespฤjams uzฤฃenerฤt izmantojot komandu:
+gpg_token_help=Parakstu var izveidot:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=Tekstuฤls GPG paraksts
-key_signature_gpg_placeholder=Sฤkas ar '-----BEGIN PGP SIGNATURE-----'
-verify_gpg_key_success=GPG atslฤga "%s" veiksmฤซgi pฤrbaudฤซta.
-ssh_key_verified=Pฤrbaudฤซta atslฤga
-ssh_key_verified_long=Atslฤga tika apliecinฤta ar parakstฤซtu pilnvaru un var tikt izmantota, lai pฤrbaudฤซtu revฤซzijas, kas atbilst jebkurai apstiprinฤtai lietotฤja e-pasta adresei.
+key_signature_gpg_placeholder=Sฤkas ar "-----BEGIN PGP SIGNATURE-----"
+verify_gpg_key_success=GPG atslฤga "%s" tika apliecinฤta.
+ssh_key_verified=Apliecinฤta atslฤga
+ssh_key_verified_long=Atslฤga tika apliecinฤta ar pilnvaru un var tikt izmantota, lai apliecinฤtu iesลซtฤซjumus, kas atbilst jebkurai apstiprinฤtai ลกฤซ lietotฤja e-pasta adresei.
ssh_key_verify=Pฤrbaudฤซt
ssh_invalid_token_signature=Norฤdฤซtฤ SSH atslฤga, paraksts un pilnvara neatbilst vai tai ir beidzies derฤซguma termiลลก.
ssh_token_required=Jฤnorฤda paraksts zemฤk esoลกajai pilnvarai
ssh_token=Pilnvara
-ssh_token_help=Parakstu ir iespฤjams uzฤฃenerฤt izmantojot komandu:
+ssh_token_help=Parakstu var izveidot:
ssh_token_signature=Tekstuฤls SSH paraksts
-key_signature_ssh_placeholder=Sฤkas ar '-----BEGIN SSH SIGNATURE-----'
-verify_ssh_key_success=SSH atslฤga "%s" veiksmฤซgi pฤrbaudฤซta.
+key_signature_ssh_placeholder=Sฤkas ar "-----BEGIN SSH SIGNATURE-----"
+verify_ssh_key_success=SSH atslฤga "%s" tika apliecinฤta.
subkeys=Apakลกatslฤgas
key_id=Atslฤgas ID
key_name=Atslฤgas nosaukums
@@ -784,9 +900,9 @@ delete_key=Noลemt
ssh_key_deletion=Noลemt SSH atslฤgu
gpg_key_deletion=Noลemt GPG atslฤgu
ssh_principal_deletion=Noลemt SSH sertifikฤta identitฤti
-ssh_key_deletion_desc=Dzฤลกot ลกo SSH atslฤgu, ar to vairs nebลซs iespฤjams autorizฤties Jลซsu kontฤ. Vai turpinฤt?
-gpg_key_deletion_desc=Noลemot GPG atslฤgu, ar to parakstฤซtฤs revฤซzijas vairs netiks attฤlotas kฤ verificฤtas. Vai turpinฤt?
-ssh_principal_deletion_desc=Noลemot SSH sertifikฤta identitฤti, ar to vairs nebลซs iespฤjams piekฤผลซt ลกim kontam. Vai turpinฤt?
+ssh_key_deletion_desc=SSH atslฤgas noลemลกana atsauks tฤs piekฤผuvi kontam. Turpinฤt?
+gpg_key_deletion_desc=GPG atslฤgas noลemลกana atceฤผ ar to parakstฤซto iesลซtฤซjumu apliecinฤjumu. Turpinฤt?
+ssh_principal_deletion_desc=SSH sertifikฤta identitฤtes noลemลกana atsauks tฤs piekฤผuvi kontam. Turpinฤt?
ssh_key_deletion_success=SSH atslฤga tika izdzฤsta.
gpg_key_deletion_success=GPG atslฤga tika izdzฤsta.
ssh_principal_deletion_success=Identitฤte tika noลemta.
@@ -794,43 +910,43 @@ added_on=Pievienots %s
valid_until_date=Derฤซgs lฤซdz %s
valid_forever=Derฤซgs mลซลพฤซgi
last_used=Pฤdฤjo reizi izmantota
-no_activity=Nav nesenas aktivitฤtes
+no_activity=Nav nesenu darbฤซbu
can_read_info=Lasฤซt
can_write_info=Rakstฤซt
key_state_desc=ล ฤซ atslฤga ir izmantota pฤdฤjo 7 dienu laikฤ
token_state_desc=ล ฤซ pilnvara ir izmantota pฤdฤjo 7 dienu laikฤ
-principal_state_desc=ล ฤซ identitฤte ir lietota pฤdฤjฤs 7 dienฤs
+principal_state_desc=ล ฤซ identitฤte ir izmantota pฤdฤjo 7 dienu laikฤ
show_openid=Rฤdฤซt profilฤ
hide_openid=Paslฤpt no profila
ssh_disabled=SSH atspฤjots
-ssh_signonly=SSH ir atspฤjots, lฤซdz ar to ลกฤซs atslฤgas tiks izmantotas tikai revฤซziju parakstu pฤrbaudei.
+ssh_signonly=SSH paลกlaik ir atspฤjots, tฤdฤฤผ ลกฤซs atslฤgas tiek izmantotas tikai iesลซtฤซjumu parakstu apliecinฤลกanai.
ssh_externally_managed=ล im lietotฤjam SSH atslฤga tiek pฤvaldฤซta attฤlinฤti
manage_social=Pฤrvaldฤซt piesaistฤซtos sociฤlos kontus
social_desc=ล ie sociฤlo tฤซklu konti var tikt izmantoti, lai pieteiktos. Pฤrliecinieties, ka visi ir atpazฤซstami.
unbind=Atsaistฤซt
unbind_success=Sociฤlฤ tฤซkla konts tika veiksmฤซgi noลemts.
-manage_access_token=Pฤrvaldฤซt piekฤผuves pilnvaras
+manage_access_token=Piekฤผuves pilnvaras
generate_new_token=Izveidot jaunu pilnvaru
-tokens_desc=Ar ลกiem taloniem ir iespฤjams piekฤผลซt Jลซsu kontam, izmantojot, Forgejo API.
+tokens_desc=ล ฤซs pilnvaras nodroลกina piekฤผuvi kontam ar Forgejo API.
token_name=Pilnvaras nosaukums
-generate_token=ฤขenerฤt pilnvaru
-generate_token_success=Piekฤผuves pilvara tika veiksmฤซgi uzฤฃenerฤta! Nokopฤjiet to tagad, jo vฤlฤk to vairs nebลซs iespฤjams aplลซkot.
-generate_token_name_duplicate=Jau eksistฤ lietotne ar nosaukumu %s . Izmantojiet citu nosaukumu.
-delete_token=Dzฤst
-access_token_deletion=Dzฤst piekฤผuves pilnvaru
+generate_token=Izveidot pilnvaru
+generate_token_success=Jaunฤ pilnvara tika izveidota. Tฤ ir jฤievieto starpliktuvฤ, jo tฤ vairs netiks rฤdฤซta.
+generate_token_name_duplicate=Lietotnes nosaukums %s jau tiek izmantots. Lลซgums izmantot citu.
+delete_token=Izdzฤst
+access_token_deletion=Izdzฤst piekฤผuves pilnvaru
access_token_deletion_cancel_action=Atcelt
access_token_deletion_confirm_action=Dzฤst
-access_token_deletion_desc=Izdzฤลกot pilnvaru, lietojumprogrammฤm, kas to izmanto, tiks liegta piekฤผuve ลกim kontam. ล ฤซ darbฤซba ir neatgriezeniska. Vai turpinฤt?
-delete_token_success=Pilnvara tika izdzฤsta. Lietojumprogrammฤm, kas izmantoja ลกo pilnvaru, vairs nav piekฤผuves kontam.
-repo_and_org_access=Repozitorija un organizฤcijas piekฤผuve
-permissions_public_only=Tikai publiskie
-permissions_access_all=Visi (publiskie, privฤtie un ierobeลพotie)
-select_permissions=Norฤdiet tiesฤซbas
+access_token_deletion_desc=Pilnvaras izdzฤลกana atsauks lietotลu, kas to izmanto, piekฤผuvi kontam. ล o darbฤซbu nevar atsaukt. Turpinฤt?
+delete_token_success=Pilnvara tika izdzฤsta. Lietotnฤm, kas to izmanto, vairs nav piekฤผuves kontam.
+repo_and_org_access=Glabฤtavas un apvienฤซbas piekฤผuve
+permissions_public_only=Tikai atklฤtฤs
+permissions_access_all=Visas (atklฤtฤs, privฤtฤs un ierobeลพotฤs)
+select_permissions=Atlasฤซt atฤผaujas
permission_no_access=Nav piekฤผuves
-permission_read=Skatฤซลกanฤs
-permission_write=Skatฤซลกanฤs un raksฤซลกanas
-access_token_desc=Atzฤซmฤtie pilnvaras apgabali ierobeลพo autentifikฤciju tikai atbilstoลกiem API izsaukumiem. Sฤซkฤka informฤcija pieejama dokumentฤcijฤ .
+permission_read=Lasฤซt
+permission_write=Lasฤซt un rakstฤซt
+access_token_desc=Atlasฤซtฤs pilnvaru atฤผaujas ierobeลพo pilnvaroลกanu tikai atbilstoลกiem API marลกrutiem. Vairฤk ir lasฤmsdokumentฤcijฤ .
at_least_one_permission=Nepiecieลกams norฤdฤซt vismaz vienu tiesฤซbu, lai izveidotu pilnvaru
permissions_list=Tiesฤซbas:
@@ -838,444 +954,495 @@ manage_oauth2_applications=Pฤrvaldฤซt OAuth2 lietotnes
edit_oauth2_application=Labot OAuth2 lietotni
oauth2_applications_desc=OAuth2 lietotnes ฤผauj treลกo puลกu lietotnฤm droลกa veidฤ autentificฤt lietotajus ลกajฤ Forgejo instancฤ.
remove_oauth2_application=Noลemt OAuth2 lietotni
-remove_oauth2_application_desc=Noลemot OAuth2 lietotni, tiks noลemta piekฤผuve visฤm parakstฤซtajฤm piekฤผuves pilnvarฤm. Vai turpinฤt?
-remove_oauth2_application_success=Lietotne tika dzฤsta.
+remove_oauth2_application_desc=OAuth2 lietotnes noลemลกana atsauks piekฤผuvi visฤm parakstฤซtajฤm piekฤผuves pilnvarฤm. Turpinฤt?
+remove_oauth2_application_success=Lietotne tika izdzฤsta.
create_oauth2_application=Izveidot jaunu OAuth2 lietotni
create_oauth2_application_button=Izveidot lietotni
-create_oauth2_application_success=Ir veiksmฤซgi izveidota jauna OAuth2 lietotne.
-update_oauth2_application_success=Ir veiksmฤซgi atjaunota OAuth2 lietotne.
+create_oauth2_application_success=Ir sekmฤซgi izveidota jauna OAuth2 lietotne.
+update_oauth2_application_success=OAuth2 lietotne ir sekmฤซgi atjauninฤta.
oauth2_application_name=Lietotnes nosaukums
-oauth2_confidential_client=Konfidenciฤls klients. Norฤdiet lietotฤm, kas glabฤ noslฤpumu slepenฤซbฤ, piemฤram, tฤซmekฤผa lietotnฤm. Nenorฤdiet instalฤjamฤm lietotnฤm, tai skaitฤ darbavirsmas vai mobilajฤm lietotnฤm.
-oauth2_redirect_uris=Pฤrsลซtฤซลกanas URI. Norฤdiet katru URI savฤ rindฤ.
+oauth2_confidential_client=Slepens klients. Jฤatlasa lietotnฤm, kas glabฤ noslฤpumu slepenฤซbฤ, piemฤram, tฤซmekฤผa lietotnฤm. Nav jฤatlasa ierastajฤm lietotnฤm, tajฤ skaitฤ darbvirsmas un viedierฤซฤu lietotnฤm.
+oauth2_redirect_uris=Pฤrvirzฤซลกanas URI. Lลซgums norฤdฤซt katru URI savฤ rindฤ.
save_application=Saglabฤt
oauth2_client_id=Klienta ID
oauth2_client_secret=Klienta noslฤpums
-oauth2_regenerate_secret=Pฤrฤฃenerฤt noslฤpumus
+oauth2_regenerate_secret=Atkฤrtoti izveidot noslฤpumu
oauth2_regenerate_secret_hint=Pazaudฤts noslฤpums?
oauth2_client_secret_hint=Pฤc ลกฤซs lapas pameลกanas vai atsvaidzinฤลกanas noslฤpums vairs netiks parฤdฤซts. Lลซgums pฤrliecinฤties, ka tas ir saglabฤts.
oauth2_application_edit=Labot
oauth2_application_create_description=OAuth2 lietotnes ฤผauj treลกas puses lietotnฤm piekฤผลซt lietotฤja kontiem ลกajฤ instancฤ.
-oauth2_application_remove_description=OAuth2 lietotnes noลemลกana liegs tai piekฤผลซt pilnvarotiem lietotฤju kontiem ลกajฤ instancฤ. Vai turpinฤt?
-oauth2_application_locked=Gitea sฤknฤลกanas brฤซdฤซ reฤฃistrฤ daลพas OAuth2 lietotnes, ja tas ir iespฤjots konfigurฤcijฤ. Lai novฤrstu negaidฤซtu uzvedฤซbu, tฤs nevar ne labot, ne noลemt. Lลซgums vฤrsties OAuth2 dokumentฤcijฤ pฤc vairฤk informฤcijas.
+oauth2_application_remove_description=OAuth2 lietotnes noลemลกana liegs tai piekฤผลซt pilnvarotiem lietotฤju kontiem ลกajฤ serverฤซ. Turpinฤt?
+oauth2_application_locked=Forgejo sฤknฤลกanas brฤซdฤซ reฤฃistrฤ daลพas OAuth2 lietotnes, ja tas ir iespฤjots konfigurฤcijฤ. Lai novฤrstu negaidฤซtu uzvedฤซbu, tฤs nevar ne labot, ne noลemt. Lลซgums vฤrsties OAuth2 dokumentฤcijฤ pฤc vairฤk informฤcijas.
-authorized_oauth2_applications=Autorizฤtฤs OAuth2 lietotnes
-authorized_oauth2_applications_description=Ir ฤผauta piekฤผuve savam Gitea kontam ลกฤซm treลกo puลกu lietotnฤm. Lลซgums atsaukt piekฤผuvi lietotnฤm, kas vairs nav nepiecieลกamas.
+authorized_oauth2_applications=Pilnvarotฤs OAuth2 lietotnes
+authorized_oauth2_applications_description=Ir ฤผauta piekฤผuve savam Forgejo kontam ลกฤซm treลกo puลกu lietotnฤm. Lลซgums atsaukt piekฤผuvi lietotnฤm, kas vairs nav nepiecieลกamas.
revoke_key=Atsaukt
revoke_oauth2_grant=Atsaukt piekฤผuvi
-revoke_oauth2_grant_description=Atsaucot piekฤผuvi ลกai treลกas puses lietotnei tiks liegta piekฤผuve Jลซsu datiem. Vai turpinฤt?
-revoke_oauth2_grant_success=Piekฤผuve veiksmฤซgi atsaukta.
+revoke_oauth2_grant_description=ล ฤซs treลกฤs puses lietotnes piekฤผuves atsaukลกana liegs tai piekฤผลซt Taviem datiem. Turpinฤt?
+revoke_oauth2_grant_success=Piekฤผuve sekmฤซgi atsaukta.
-twofa_desc=Divfaktoru autentifikฤcija uzlabo konta droลกฤซbu.
-twofa_recovery_tip=Ja ierฤซce tiek pazaudฤta, iespฤjams izmantot vienreiz izmantojamo atkopลกanas atslฤgu, lai atgลซtu piekฤผuvi savam kontam.
-twofa_is_enrolled=Kontam ir ieslฤgta divfaktoru autentifikฤcija.
-twofa_not_enrolled=Kontam ลกobrฤซd nav ieslฤgta divfaktoru autentifikฤcija.
-twofa_disable=Atslฤgt divfaktoru autentifikฤciju
-twofa_scratch_token_regenerate=ฤขenerฤt jaunu vienreizฤjo kodu
+twofa_desc=Lai aizsargฤtu savu kontu no paroฤผu zฤdzฤซbas, var izmantot viedtฤlruni vai citu ierฤซci, lai saลemtu laikฤ balstฤซtas vienreiz izmantojamas paroles ("TOTP").
+twofa_recovery_tip=Ja ierฤซce tiks pazaudฤta, bลซs iespฤjams izmantot vienreizฤjas izmantoลกanas atkopes atslฤgu, lai atgลซtu piekฤผuvi savam kontam.
+twofa_is_enrolled=Kontam ลกobrฤซd ir ieslฤgta divpakฤpju pieteikลกanฤs.
+twofa_not_enrolled=Kontam ลกobrฤซd nav ieslฤgta divpakฤpju pieteikลกanฤs.
+twofa_disable=Atspฤjot divpakฤpju pieteikลกanos
+twofa_scratch_token_regenerate=Atkฤrtoti izveidot vienreizฤjas izmantoลกanas atkopes atslฤgu
twofa_scratch_token_regenerated=Vienreizฤjฤ pilnvara tagad ir %s. Tฤ ir jฤglabฤ droลกฤ vietฤ, tฤ vairs nekad netiks rฤdฤซta.
-twofa_enroll=Ieslฤgt divfaktoru autentifikฤciju
-twofa_disable_note=Nepiecieลกamฤซbas gadฤซjumฤ divfaktoru autentifikฤciju ir iespฤjams atslฤgt.
-twofa_disable_desc=Atslฤdzot divfaktoru autentifikฤciju, konts vairs nebลซs tik droลกs. Vai turpinฤt?
-regenerate_scratch_token_desc=Ja esat aizmirsis vienreizฤjo kodu vai esat to jau izmantojis, lai pieteiktos, atjaunojiet to ลกeit.
-twofa_disabled=Divfaktoru autentifikฤcija tika atslฤgta.
-scan_this_image=Noskenฤjiet ลกo attฤlu ar autentifikฤcijas lietojumprogrammu:
-or_enter_secret=Vai ievadiet ลกo noslฤpumu: %s
-then_enter_passcode=Ievadiet piekฤผuves kodu no lietojumprogrammas:
-passcode_invalid=Nederฤซgs piekฤผuves kods. Mฤฤฃiniet ievadฤซt atkฤrtoti.
-twofa_enrolled=Kontam tika ieslฤgta divfaktoru autentifikฤcija. Saglabฤjiet vienreizฤjo kodu (%s) droลกฤ vietฤ, jo to vairฤk nebลซs iespฤjams aplลซkot!
+twofa_enroll=Ieslฤgt divpakฤpju pieteikลกanos
+twofa_disable_note=Ja nepiecieลกams, divpakฤpju pieteikลกanos var atslฤgt.
+twofa_disable_desc=Divpakฤpju pieteikลกanฤs atspฤjoลกana padarฤซs kontu mazฤk droลกu. Turpinฤt?
+regenerate_scratch_token_desc=Ja atkopes atslฤga ir pazaudฤta vai tฤ jau ir izmantota, lai pieteiktos, to var atiestatฤซt ลกeit.
+twofa_disabled=Divpakฤpju pieteikลกanฤs tika atspฤjota.
+scan_this_image=ล is attฤls ir jฤnolasa ar autentificฤลกanฤs lietotni:
+or_enter_secret=Vai jฤievada noslฤpums: %s
+then_enter_passcode=Pฤc tam jฤievada lietotnฤ attฤlotais piekฤผuves kods:
+passcode_invalid=Piekฤผuves kods ir nepareizs. Jฤmฤฤฃina vฤlreiz.
+twofa_enrolled=Kontam tika ieslฤgta divpakฤpju pieteikลกanฤs. Vienreiz izmantojamฤ atkopes atslฤga (%s) ir jฤglabฤ droลกฤ vietฤ, jo tฤ vairs netiks rฤdฤซta.
twofa_failed_get_secret=Neizdevฤs ielฤdฤt noslฤpumu.
-webauthn_desc=Droลกฤซbas atslฤgas ir fiziskas ierฤซces, kas satur kriptogrฤfiskas atslฤgas. Tฤs var tikt izmantotas divu faktoru autentifikฤcijai. Droลกฤซbas atslฤgฤm ir jฤatbalsta WebAuthn autentifikฤcijas standarts.
+webauthn_desc=Droลกฤซbas atslฤgas ir ierฤซces, kas satur kriptogrฤfiskas atslฤgas. Tฤs var tikt izmantotas divpakฤpju apliecinฤลกanai. Droลกฤซbas atslฤgฤm ir jฤatbilst WebAuthn autentificฤtฤja standartam.
webauthn_register_key=Pievienot droลกฤซbas atslฤgu
webauthn_nickname=Segvฤrds
webauthn_delete_key=Noลemt droลกฤซbas atslฤgu
webauthn_delete_key_desc=Noลemot droลกฤซbas atslฤgu ar to vairs nebลซs iespฤjams pieteikties. Vai turpinฤt?
webauthn_key_loss_warning=Ja tiek pazaudฤtas droลกฤซbas atslฤgas, tiks zaudฤta piekฤผuve kontam.
-webauthn_alternative_tip=Ir vฤlams uzstฤdฤซt papildu autentifikฤcijas veidu.
+webauthn_alternative_tip=Ir vฤlams uzstฤdฤซt papildu autentificฤลกanฤs veidu.
-manage_account_links=Pฤrvaldฤซt saistฤซtos kontus
-manage_account_links_desc=ล ฤdi ฤrฤjie konti ir piesaistฤซti Jลซsu Forgejo kontam.
+manage_account_links=Sasaistฤซtie konti
+manage_account_links_desc=ล ie ฤrฤjie konti ir sasaistฤซti ar Tavu Forgejo kontu.
account_links_not_available=Paลกlaik nav neviena ฤrฤjฤ konta piesaistฤซta ลกim kontam.
link_account=Sasaistฤซt kontu
-remove_account_link=Noลemt saistฤซto kontu
-remove_account_link_desc=Noลemot saistฤซto kontu, tam tiks liegta piekฤผuve Jลซsu Forgejo kontam. Vai turpinฤt?
-remove_account_link_success=Saistฤซtais konts tika noลemts.
+remove_account_link=Noลemt sasaistฤซto kontu
+remove_account_link_desc=Sasaistฤซtฤ konta noลemลกana atsauks tฤ piekฤผuvi Tavam Forgejo kontam. Turpinฤt?
+remove_account_link_success=Sasaistฤซtais konts tika noลemts.
-hooks.desc=Pievienot tฤซmekฤผa ฤฤทus, kas izpildฤซsies visos repozitorijos , kas jums pieder.
+hooks.desc=Pievienot tฤซmekฤผa aizฤทeres, kas izpildฤซsies visฤs piederoลกajฤs glabฤtavฤs .
-orgs_none=Jลซs neesat nevienas organizฤcijas biedrs.
-repos_none=Jums nepieder neviens repozitorijs.
+orgs_none=Nav dalฤซbas nevienฤ apvienฤซbฤ.
+repos_none=Tev nav nevienas glabฤtavas.
-delete_account=Dzฤst savu kontu
-delete_prompt=ล ฤซ darbฤซba pilnฤซbฤ izdzฤsฤซs Jลซsu kontu, kฤ arฤซ tฤ ir NEATGRIEZENISKA .
-delete_with_all_comments=Jลซsu konts ir jaunฤks par %s. Lai izveirotos no spoka komentฤriem, visu problฤmu un izmaiลu pieprasฤซjumu komentฤri tiks dzฤsti lฤซdz ar kontu.
-confirm_delete_account=Apstiprinฤt dzฤลกanu
-delete_account_title=Dzฤst lietotฤja kontu
-delete_account_desc=Vai tieลกฤm vฤlaties dzฤst ลกo kontu?
+delete_account=Izdzฤst savu kontu
+delete_prompt=ล ฤซ darbฤซba neatgriezeniski izdzฤsฤซs lietotฤja kontu. To NEVAR atsaukt.
+delete_with_all_comments=Konts ir jaunฤks kฤ %s. Lai izvairฤซtos no spoku piebildฤm, visas pieteikumu/izmaiลu pieprasฤซjumu piebildes tiks izdzฤstas kopฤ ar to.
+confirm_delete_account=Apstiprinฤt izdzฤลกanu
+delete_account_title=Izdzฤst lietotฤja kontu
+delete_account_desc=Vai tieลกฤm neatgriezeniski izdzฤst ลกo lietotฤja kontu?
email_notifications.enable=Iespฤjot e-pasta paziลojumus
-email_notifications.onmention=Tikai, ja esmu pieminฤts
-email_notifications.disable=Nesลซtฤซt paziลojumus
-email_notifications.submit=Saglabฤt sลซtฤซลกanas iestatฤซjumus
-email_notifications.andyourown=Iekฤผaut savus paziลojumus
+email_notifications.onmention=Tikai, ja mani piemin
+email_notifications.disable=Atspฤjot e-pasta paziลojumus
+email_notifications.submit=Iestatฤซt e-pasta iestatฤซjumus
+email_notifications.andyourown=Un manus paziลojumus
visibility=Lietotฤja redzamฤซba
-visibility.public=Publisks
+visibility.public=Atklฤta
visibility.public_tooltip=Redzams ikvienam
visibility.limited=Ierobeลพota
-visibility.limited_tooltip=Redzams tikai autentificฤtiem lietotฤjiem
-visibility.private=Privฤts
-visibility.private_tooltip=Redzams tikai organizฤciju, kurฤm esi pievienojies, dalฤซbniekiem
+visibility.limited_tooltip=Redzams tikai lietotฤjiem, kuri ir pieteikuลกies
+visibility.private=Privฤta
+visibility.private_tooltip=Redzams tikai apvienฤซbu, kurฤs pievienojies, dalฤซbniekiem
+change_password = Mainฤซt paroli
+keep_activity_private.description = Tavas atklฤtฤs darbฤซbas bลซs redzamas tikai Tev un servera pฤrvaldฤซtฤjiem.
+update_hints = Atjauninฤt norฤdes
+update_hints_success = Norฤdes tika atjauninฤtas.
+user_block_success = Lietotฤjs tika sekmฤซgi liegts.
+user_unblock_success = Lietotฤja liegums tika sekmฤซgi atcelts.
+blocked_since = Liegts kopลก %s
+blocked_users_none = Nav liegto lietotฤju.
+pronouns = Vietniekvฤrdi
+pronouns_custom = Pielฤgoti
+blocked_users = Liegtie lietotฤji
+pronouns_unspecified = Nav norฤdฤซts
+language.title = Noklusฤjuma valoda
+language.localization_project = Palฤซdzi mums tulkot Forgejo savฤ valodฤ! Uzzinฤt vairฤk .
+hints = Norฤdes
+additional_repo_units_hint = Ieteikt iespฤjot papildu glabฤtavas vienฤซbas
+additional_repo_units_hint_description = Attฤlot norฤdi "Iespฤjot vฤl" glabฤtavฤs, kurฤs nav iespฤjotas visas pieejamฤs vienฤซbas.
+language.description = ล ฤซ valoda tiks saglabฤta kontฤ un pฤc pieteikลกanฤs tiks izmantota kฤ noklusฤjuma.
+user_block_yourself = Nevar liegt sevi.
+pronouns_custom_label = Pielฤgoti vietniekvฤrdi
+change_username_redirect_prompt.with_cooldown.one = Vecais lietotฤjvฤrds bลซs pieejams visiem pฤc noilguma, kas ir %[1]d diena. ล ajฤ laikฤ ir iespฤjams to atkal sฤkt izmantot.
+change_username_redirect_prompt.with_cooldown.few = Vecais lietotฤjvฤrds bลซs pieejams visiem pฤc noilguma, kas ir %[1]d dienas. ล ajฤ laikฤ ir iespฤjams to atkal sฤkt izmantot.
+keep_pronouns_private = Vietniekvฤrdus rฤdฤซt tikai lietotฤjiem, kuri ir pieteikuลกies
+keep_pronouns_private.description = ล is paslฤps vietniekvฤrdus no apmeklฤtฤjiem, kuri nav pieteikuลกies.
+quota.sizes.assets.all = Lฤซdzekฤผi
+quota.sizes.git.lfs = Git LFS
+quota.applies_to_user = Uz kontu attiecas zemฤk esoลกฤs ierobeลพojuma kฤrtulas
+quota.rule.exceeded.helper = Kopฤjais ลกฤซs kฤrtulas objektu izmฤrs pฤrsniedz ierobeลพojumu.
+quota.sizes.git.all = Git saturs
+quota.rule.exceeded = Pฤrsniegts
+quota.sizes.assets.attachments.all = Pielikumi
+quota.sizes.assets.attachments.issues = Pieteikumu pielikumi
+quota.sizes.assets.attachments.releases = Laidienu pielikumi
+quota.sizes.assets.artifacts = Artefakti
+quota.sizes.assets.packages.all = Pakotnes
+quota.sizes.wiki = Vikivietne
+storage_overview = Krฤtuves pฤrskats
+quota = Ierobeลพojums
+quota.applies_to_org = Uz apvienฤซbu attiecas zemฤk esoลกฤs ierobeลพojuma kฤrtulas
+quota.rule.no_limit = Neierobeลพots
+quota.sizes.all = Viss
+quota.sizes.repos.all = Glabฤtavas
+quota.sizes.repos.public = Atklฤtฤs glabฤtavas
+quota.sizes.repos.private = Privฤtฤs glabฤtavas
+regenerate_token = Izveidot no jauna
+access_token_regeneration = Izveidot piekฤผuves pilnvaru no jauna
+regenerate_token_success = Pilnvara tika izveidota no jauna. Lietotnฤm, kas to izmanto, vairs nav piekฤผuve kontam, un tajฤs ir jฤizmanto jaunฤ pilnvara.
+access_token_regeneration_desc = Pilnvaras izveidoลกana no jauna atsauks piekฤผuvi kontam lietotnฤm, kuras to izmanto. Darbฤซba ir neatgriezeniska. Turpinฤt?
[repo]
-new_repo_helper=Repozitorijs satur visus projekta failus, tajฤ skaitฤ izmaiลu vฤsturi. Jau tiek glabฤts kaut kur citur? Pฤrnest repozitoriju.
+new_repo_helper=Glabฤtava satur visas projekta datnes, tajฤ skaitฤ izmaiลu vฤsturi. Jau tiek izmantota kaut kur citur? Pฤrcelt glabฤtavu .
owner=ฤชpaลกnieks
-owner_helper=ล
emot vฤrฤ maksimฤlฤ repozitoriju skaita ierobeลพojumu, ne visas organizฤcijas var tikt parฤdฤซtas sarakstฤ.
-repo_name=Repozitorija nosaukums
-repo_name_helper=Labi repozitorija nosaukumi ir ฤซsi, unikฤli un tฤdi, ko viegli atcerฤties.
-repo_size=Repozitorija izmฤrs
+owner_helper=Daลพas apvienฤซbas var netikt parฤdฤซtas izvฤlnฤ lielฤkฤ iespฤjamฤ glabฤtavu skaita ierobeลพojuma dฤฤผ.
+repo_name=Glabฤtavas nosaukums
+repo_name_helper=Labos glabฤtavu nosaukumos izmanto ฤซsus, viegli iegaumฤjamus un vienreizฤjus atslฤgvฤrdus.
+repo_size=Glabฤtavas izmฤrs
template=Sagatave
-template_select=Izvฤlieties sagatavi.
-template_helper=Padarฤซt repozitoriju par sagatavi
-template_description=Sagatavju repozitoriji tiek izmantoti, lai balstoties uz tiem veidotu jaunus repozitorijus saglabฤjot direktoriju un failu struktลซru.
+template_select=Atlasฤซt sagatavi
+template_helper=Padarฤซt glabฤtavu par sagatavi
+template_description=Sagatavju glabฤtavas ฤผauj lietotฤjiem izveidot jaunas glabฤtavas ar tฤdu paลกu mapju uzbลซvi, datnฤm un izvฤles iestatฤซjumiem.
visibility=Redzamฤซba
-visibility_description=Tikai organizฤcijas ฤซpaลกnieks vai tฤs biedri, kam ir tiesฤซbas, varฤs piekฤผลซt ลกim repozitorijam.
-visibility_helper=Padarฤซt repozitoriju privฤtu
-visibility_helper_forced=Jลซsu sistฤmas administrators ir noteicis, ka visiem no jauna izveidotajiem repozitorijiem ir jฤbลซt privฤtiem.
-visibility_fork_helper=(ล ฤซs vฤrtฤซbas maiลa ietekmฤs arฤซ visus atdalฤซtos repozitorijus.)
+visibility_description=Tikai apvienฤซbas ฤซpaลกnieks vai tฤs dalฤซbnieki, ja viลiem ir tiesฤซbas, varฤs to redzฤt.
+visibility_helper=Padarฤซt glabฤtavu privฤtu
+visibility_helper_forced=Vietnes pฤrvaldฤซtฤjs ir noteicis, ka jaunฤm glabฤtavฤm ir jฤbลซt privฤtฤm.
+visibility_fork_helper=(ล ฤซs vฤrtฤซbas mainฤซลกana ietekmฤs visus atzarojumus.)
clone_helper=Nepiecieลกama palฤซdzฤซba klonฤลกanฤ? Apmeklฤ palฤซdzฤซbas sadaฤผu.
-fork_repo=Atdalฤซt repozitoriju
-fork_from=Atdalฤซt no
-already_forked=Repozitorijs %s jau ir atdalฤซts
-fork_to_different_account=Atdalฤซt uz citu kontu
-fork_visibility_helper=Atdalฤซtam repozitorijam nav iespฤjams mainฤซt tฤ redzamฤซbu.
-fork_branch=Atzars, ko klonฤt atdalฤซtajฤ repozitorijฤ
-all_branches=Visi atzari
-fork_no_valid_owners=ล im repozitorijam nevar izveidot atdalฤซtu repozitoriju, jo tam nav spฤkฤ esoลกu ฤซpaลกnieku.
+fork_repo=Izveidot glabฤtavas atzarojumu
+fork_from=Izveidot atzarojumu no
+already_forked=Jau ir atzarojums no %s
+fork_to_different_account=Izveidot atzarojumu citฤ kontฤ
+fork_visibility_helper=Atzarotas glabฤtavas redzamฤซbu nevar mainฤซt.
+fork_branch=Zars, kas ir klonฤjams atzarojumฤ
+all_branches=Visi zari
+fork_no_valid_owners=ล ai glabฤtavai nevar izveidot atzarojumus, jo tai nav derฤซgu ฤซpaลกnieku.
use_template=Izmantot ลกo sagatavi
clone_in_vsc=Atvฤrt VS Code
download_zip=Lejupielฤdฤt ZIP
download_tar=Lejupielฤdฤt TAR.GZ
download_bundle=Lejupielฤdฤt BUNDLE
-generate_repo=ฤขenerฤt repozitoriju
-generate_from=ฤขenerฤt no
+generate_repo=Izveidot glabฤtavu
+generate_from=Izveidot no
repo_desc=Apraksts
-repo_desc_helper=Ievadiet ฤซsu aprakstu (neobligฤts)
+repo_desc_helper=ฤชss apraksts (pฤc izvฤles)
repo_lang=Valoda
-repo_gitignore_helper=Izvฤlieties .gitignore sagatavi.
-repo_gitignore_helper_desc=Izvฤlieties kฤdi faili netiks glabฤti repozitorijฤ no sagatavฤm bieลพฤk lietotฤjฤm valodฤm. Pฤc noklusฤjuma .gitignore iekฤผauj valodu kompilฤcijas rฤซku artifaktus.
-issue_labels=Problฤmu etiฤทetes
-issue_labels_helper=Izvฤlieties problฤmu etiฤทeลกu kopu.
+repo_gitignore_helper=Atlasฤซt .gitignore sagataves
+repo_gitignore_helper_desc=No izplatฤซtu valodu sagatavju saraksta jฤizvฤlas, kuras datnes neiekฤผaut. Pฤc noklusฤjuma katras valodas bลซvฤลกanas rฤซku izveidotie ierastie artefakti ir iekฤผauti .gitignore.
+issue_labels=Iezฤซmes
+issue_labels_helper=Atlasฤซt iezฤซmju kopu
license=Licence
-license_helper=Izvฤlieties licences failu.
-license_helper_desc=Licence nosaka, ko citi var un ko nevar darฤซt ar ลกo kodu. Neesat pฤrliecintฤts, kฤdu izvฤlฤties ลกim projektam? Aplลซkojiet licences izvฤle .
+license_helper=Atlasฤซt licences datni
+license_helper_desc=Licence nosaka, ko citi var un ko nevar darฤซt ar kodu. Nav skaidrs, kura ir vispiemฤrotฤkฤ projektam? Skatฤซt Licences izvฤle .
readme=LASIMANI
-readme_helper=Izvฤlieties LASIMANI faila sagatavi.
-readme_helper_desc=ล ajฤ vietฤ ir iespฤjams detalizฤti aprakstฤซt ลกo projektu.
-auto_init=Inicializฤt repozitoriju (Pievieno .gitignore, licenci un README)
+readme_helper=Atlasฤซt README datnes sagatavi
+readme_helper_desc=ล ฤซ ir vieta, kurฤ var ievietot izvฤrstu aprakstu par projektu.
+auto_init=Sฤknฤt glabฤtavu
trust_model_helper=Izvฤlieties parakstu pฤrbaudes uzticamฤซbas modeli. Iespฤjamie varianti ir:
trust_model_helper_collaborator=Lฤซdzstrฤdnieka: Uzticฤties lฤซdzstrฤdnieku parakstiem
trust_model_helper_committer=Revฤซzijas iesลซtฤซtฤja: Uzticฤties parakstiem, kas atbilst revฤซzijas iesลซtฤซtฤjam
trust_model_helper_collaborator_committer=Lฤซdzstrฤdnieka un revฤซzijas iesลซtฤซtฤja: Uzticฤties lฤซdzstrฤdnieku parakstiem, kas atbilst revฤซzijas iesลซtฤซtฤjam
trust_model_helper_default=Noklusฤtais: Izmantojiet ลกฤซ servera noklusฤto uzticamฤซbas modeli
-create_repo=Izveidot repozitoriju
-default_branch=Noklusฤtais atzars
+create_repo=Izveidot glabฤtavu
+default_branch=Noklusฤjuma zars
default_branch_label=noklusฤjuma
-default_branch_helper=Noklusฤtais atzars nosaka pamata atzaru uz kuru tiks veidoti izmaiลu pieprasฤซjumi un koda revฤซziju iesลซtฤซลกana.
+default_branch_helper=Noklusฤjuma zars ir pamata zars izmaiลu pieprasฤซjumiem un koda iesลซtฤซjumiem.
mirror_prune=Izmest
-mirror_prune_desc=Izdzฤst visas ฤrฤjฤs atsauces, kas ฤrฤjฤ repozitorijฤ vairs neeksistฤ
-mirror_interval=Spoguฤผoลกanas intervฤls (derฤซgas laika vienฤซbas ir 'h', 'm', 's'). Norฤdiet 0, lai atslฤgtu periodisku spoguฤผoลกanu. (Minimฤlais intervฤls: %s)
-mirror_interval_invalid=Nekorekts spoguฤผoลกanas intervฤls.
-mirror_sync_on_commit=Sinhronizฤt, kad revฤซzijas tiek iesลซtฤซtas
-mirror_address=Spoguฤผa adrese
-mirror_address_desc=Pieslฤgลกanฤs rekvizฤซtus norฤdiet autorizฤcijas sadaฤผฤ.
+mirror_prune_desc=Noลemt novecojuลกas attฤlฤs izsekoลกanas atsauces
+mirror_interval=Starplaiks starp spoguฤผoลกanu (derฤซgas laika vienฤซbas ir 'h', 'm', 's'). 0, lai atslฤgtu atkฤrtojoลกos sinhronizฤลกanu. (Mazฤkais pieฤผaujamais laika posms: %s)
+mirror_interval_invalid=Starplaiks starp spoguฤผoลกanu nav derฤซgs.
+mirror_sync_on_commit=Sinhronizฤt, kad tiek aizgฤdฤti iesลซtฤซjumi
+mirror_address=Klonฤt no URL
+mirror_address_desc=Nepiecieลกamie pieslฤgลกanฤs dati jฤnorฤda pilnvaroลกanas sadaฤผฤ.
mirror_address_url_invalid=Norฤdฤซtais URL ir nederฤซgs. Visas URL daฤผas ir jฤnorฤda pareizi.
mirror_address_protocol_invalid=Norฤdฤซtais URL ir nederฤซgs. Var spoguฤผot tikai no http(s):// vai git:// adresฤm.
-mirror_lfs=Lielu failu glabฤtuve (LFS)
-mirror_lfs_desc=Aktivizฤt LFS datu spoguฤผoลกanu.
+mirror_lfs=Lielu datลu krฤtuve (LFS)
+mirror_lfs_desc=Aktivฤt LFS datu spoguฤผoลกanu.
mirror_lfs_endpoint=LFS galapunkts
-mirror_lfs_endpoint_desc=Sinhronizฤcija mฤฤฃinฤs izmantot klonฤsanas URL, lai noteiktu LFS serveri . Var norฤdฤซt arฤซ citu galapunktu, ja repozitorija LFS dati ir izvietoti citฤ vietฤ.
-mirror_last_synced=Pฤdฤjo reizi sinhronizฤts
+mirror_lfs_endpoint_desc=Sinhronizฤลกana mฤฤฃinฤs izmantot klonฤsanas URL, lai noteiktu LFS serveri . Var norฤdฤซt arฤซ citu galapunktu, ja glabฤtavas LFS dati tiek glabฤti kaut kur citur.
+mirror_last_synced=Pฤdฤjo reizi sinhronizฤta
mirror_password_placeholder=(bez izmaiลฤm)
mirror_password_blank_placeholder=(nav uzstฤdฤซts)
-mirror_password_help=Nomainiet lietotฤju, lai izdzฤstu saglabฤto paroli.
-watchers=Novฤrotฤji
-stargazers=Zvaigลพลdevฤji
-stars_remove_warning=ล is repozitorijs tiks noลemts no visฤm izlasฤm.
-forks=Atdalฤซtie repozitoriji
+mirror_password_help=Jฤnomaina lietotฤjvฤrds, lai izdzฤstu saglabฤto paroli.
+watchers=Vฤrotฤji
+stargazers=Zvaigลพลu vฤrotฤji
+stars_remove_warning=ล ฤซ glabฤtava tiks izลemta no visฤm izlasฤm.
+forks=Atzarojumi
reactions_more=un vฤl %d
-unit_disabled=Administrators ir atspฤjojies ลกo repozitorija sadaฤผu.
+unit_disabled=Vietnes pฤrvaldฤซtฤjs ir atspฤjojis ลกo glabฤtavas sadaฤผu.
language_other=Citas
-adopt_search=Ievadiet lietotฤja vฤrdu, lai meklฤtu nepฤrลemtos repozitorijus... (atstฤjiet tukลกu, lai meklฤtu visus)
-adopt_preexisting_label=Pฤrลemt failus
-adopt_preexisting=Pฤrลemt jau eksistฤjoลกos failus
-adopt_preexisting_content=Izveidot repozitoriju no direktorijas %s
-adopt_preexisting_success=Pฤrลemti faili un izveidots repozitorijs no %s
-delete_preexisting_label=Dzฤst
-delete_preexisting=Dzฤst jau eksistฤjoลกos failus
-delete_preexisting_content=Dzฤst failus direktorijฤ %s
-delete_preexisting_success=Dzฤst nepฤrลemtos failus direktorijฤ %s
-blame_prior=Aplลซkot vainฤซgo par izmaiลฤm pirms ลกฤซs revฤซzijas
-blame.ignore_revs=Neลem vฤrฤ izmaiลas no .git-blame-ignore-revs . Nospiediet ลกeit, lai to apietu un redzฤtu visu izmaiลu skatu.
+adopt_search=Jฤievada lietotฤjvฤrds, lai meklฤtu nepieลemtฤs glabฤtavasโฆ (atstฤt tukลกu, lai atrastu visas)
+adopt_preexisting_label=Pฤrลemt datnes
+adopt_preexisting=Pieลemt jau esoลกas datnes
+adopt_preexisting_content=Izveidot glabฤtavu no %s
+adopt_preexisting_success=Pieลemtas datnes un izveidota glabฤtava no %s
+delete_preexisting_label=Izdzฤst
+delete_preexisting=Izdzฤst jau esoลกas datnes
+delete_preexisting_content=Izdzฤst datnes no %s
+delete_preexisting_success=Izdzฤst nepieลemtฤs datnes no %s
+blame_prior=Apskatฤซt izmaiลu veicฤjus pirms ลกฤซm izmaiลฤm
+blame.ignore_revs=Neลem vฤrฤ izmaiลas no .git-blame-ignore-revs . Klikลกฤทinฤt ลกeit, lai to apietu un redzฤtu ierasto uzrฤdฤซลกanas skatu.
blame.ignore_revs.failed=Neizdevฤs neลemt vฤrฤ izmaiลas no .git-blam-ignore-revs .
author_search_tooltip=Tiks attฤloti ne vairฤk kฤ 30 lietotฤji
-tree_path_not_found_commit=Revฤซzijฤ %[2]s neeksistฤ ceฤผลก %[1]s
-tree_path_not_found_branch=Atzarฤ %[2]s nepastฤv ceฤผลก %[1]s
-tree_path_not_found_tag=Tagฤ %[2]s nepastฤv ceฤผลก %[1]s
+tree_path_not_found_commit=Iesลซtฤซjumฤ %[2]s nepastฤv ceฤผลก %[1]s
+tree_path_not_found_branch=Zarฤ %[2]s nepastฤv ceฤผลก %[1]s
+tree_path_not_found_tag=Birkฤ %[2]s nepastฤv ceฤผลก %[1]s
-transfer.accept=Apstiprinฤt ฤซpaลกnieka maiลu
+transfer.accept=Pieลemt nodoลกanu
transfer.accept_desc=`Mainฤซt ฤซpaลกnieku uz "%s"`
-transfer.reject=Noraidฤซt ฤซpaลกnieka maiลu
+transfer.reject=Noraidฤซt nodoลกanu
transfer.reject_desc=`Atcelt ฤซpaลกnieka maiลu uz "%s"`
-transfer.no_permission_to_accept=Nav atฤผaujas pieลemt ลกo pฤrsลซtฤซลกanu.
-transfer.no_permission_to_reject=Nav atฤผaujas noraidฤซt ลกo pฤrsลซtฤซลกanu.
+transfer.no_permission_to_accept=Nav atฤผaujas pieลemt ลกo nodoลกanu.
+transfer.no_permission_to_reject=Nav atฤผaujas noraidฤซt ลกo nodoลกanu.
desc.private=Privฤts
-desc.public=Publisks
+desc.public=Atklฤts
desc.template=Sagatave
desc.internal=Iekลกฤjs
desc.archived=Arhivฤts
desc.sha256=SHA256
-template.items=Sagataves ieraksti
-template.git_content=Git saturs (noklusฤtais atzars)
-template.git_hooks=Git ฤฤทi
-template.git_hooks_tooltip=Pฤc repozitorija izveidoลกanas, Jums nav tiesฤซbu mainฤซt Git ฤฤทus. Atzฤซmฤjiet ลกo tikai, ja uzticaties sagataves repozitorija saturam.
-template.webhooks=Tฤซmekฤผa ฤฤทi
+template.items=Sagataves vienumi
+template.git_content=Git saturs (noklusฤjuma zars)
+template.git_hooks=Git aizฤทeres
+template.git_hooks_tooltip=ล obrฤซd nav iespฤjams pฤc pievienoลกanas mainฤซt vai noลemt Git aizฤทeres. Atlasฤซt ลกo tikai tad, ja ir uzticฤซba sagataves glabฤtavai.
+template.webhooks=Tฤซmekฤผa aizฤทeres
template.topics=Tฤmas
template.avatar=Profila attฤls
-template.issue_labels=Problฤmu etiฤทetes
-template.one_item=Norฤdiet vismaz vienu sagataves vienฤซbu
-template.invalid=Norฤdiet sagataves repozitoriju
+template.issue_labels=Pieteikumu iezฤซmes
+template.one_item=Jฤatlasa vismaz viens sagataves vienums
+template.invalid=Jฤatlasa sagataves glabฤtava
-archive.title=ล is repozitorijs ir arhivฤts. Ir iespฤjams aplลซkot tฤ failus un to konฤt, bet nav iespฤjams iesลซtฤซt izmaiลas, kฤ arฤซ izveidot jaunas problฤmas vai izmaiลu pieprasฤซjumus.
-archive.title_date=ล is repozitorijs tika arhivฤts %s. Ir iespฤjams aplลซkot tฤ failus un to konฤt, bet nav iespฤjams iesลซtฤซt izmaiลas, kฤ arฤซ izveidot jaunas problฤmas vai izmaiลu pieprasฤซjumus.
-archive.issue.nocomment=Repozitorijs ir arhivฤts. Problฤmฤm nevar pievienot jaunus komentฤrus.
-archive.pull.nocomment=Repozitorijs ir arhivฤts. Izmaiลu pieprasฤซjumiem nevar pievienot jaunus komentฤrus.
+archive.title=ล ฤซ glabฤtava ir arhivฤta. Tajฤ var apskatฤซt datnes, un to var klonฤt, bet tajฤ nevar veikt jebkฤdas izmaiลas, piemฤram, aizgฤdฤt izmaiลas un izveidot jaunus pieteikumus, izmaiลu pieprasฤซjumus vai piebildes.
+archive.title_date=ล ฤซ glabฤtava tika arhivฤta %s. Tajฤ var apskatฤซt datnes, un to var klonฤt, bet tajฤ nevar veikt jebkฤdas izmaiลas, piemฤram, aizgฤdฤt izmaiลas un izveidot pieteikumus, izmaiลu pieprasฤซjumus vai piebildes.
+archive.issue.nocomment=ล ฤซ glabฤtava ir arhivฤta. Pieteikumiem nevar pievienot piebildes.
+archive.pull.nocomment=ล ฤซ glabฤtava ir arhivฤta. Izmaiลu pieprasฤซjumiem nevar pievienot piebildes.
-form.reach_limit_of_creation_1=Sasniegts Jums noteiktais %d repozitorija ierobeลพojums.
-form.reach_limit_of_creation_n=Sasniegts Jums noteiktais %d repozitoriju ierobeลพojums.
-form.name_reserved=Repozitorija nosaukums "%s" ir jau rezervฤts.
-form.name_pattern_not_allowed=Repozitorija nosaukums "%s" nav atฤผauts.
+form.reach_limit_of_creation_1=ฤชpaลกnieks jau ir sasniedzis %d glabฤtavas ierobeลพojumu.
+form.reach_limit_of_creation_n=ฤชpaลกnieks jau ir sasniedzis %d glabฤtavu ierobeลพojumu.
+form.name_reserved=Glabฤtavas nosaukums "%s" ir aizลemts.
+form.name_pattern_not_allowed="%s" nav ฤผauts izmantot glabฤtavas nosaukumฤ.
-need_auth=Autorizฤcija
-migrate_options=Migrฤcijas opcijas
+need_auth=Pilnvaroลกana
+migrate_options=Pฤrcelลกanas iespฤjas
migrate_service=Migrฤcijas serviss
-migrate_options_mirror_helper=ล is repozitorijs bลซs spogulis
-migrate_options_lfs=Migrฤt LFS failus
+migrate_options_mirror_helper=ล ฤซ glabฤtava bลซs spoguฤผglabฤtava
+migrate_options_lfs=Pฤrcelt LFS datnes
migrate_options_lfs_endpoint.label=LFS galapunkts
-migrate_options_lfs_endpoint.description=Migrฤcija mฤฤฃinฤs izmantot attฤlinฤto URL, lai noteiktu LFS serveri . Var norฤdฤซt arฤซ citu galapunktu, ja repozitorija LFS dati ir izvietoti citฤ vietฤ.
+migrate_options_lfs_endpoint.description=Pฤrcelลกana mฤฤฃinฤs izmantot attฤlo Git, lai noteiktu LFS serveri . Var arฤซ norฤdฤซt pielฤgotu galapunktu, ja glabฤtavas LFS dati tiek glabฤti kaut kur citur.
migrate_options_lfs_endpoint.description.local=Iespฤjams norฤdฤซt arฤซ servera ceฤผu.
migrate_options_lfs_endpoint.placeholder=Ja nav norฤdฤซts, galamฤrฤทis tiks atvasinฤts no klonฤลกanas URL
-migrate_items=Vienฤซbas, ko pฤrลemt
+migrate_items=Pฤrcelลกanas vienumi
migrate_items_wiki=Vikivietni
migrate_items_milestones=Atskaites punktus
-migrate_items_labels=Etiฤทetes
-migrate_items_issues=Problฤmas
+migrate_items_labels=Iezฤซmes
+migrate_items_issues=Pieteikumi
migrate_items_pullrequests=Izmaiลu pieprasฤซjumus
-migrate_items_merge_requests=Sapludinฤลกanas pieprasฤซjumi
+migrate_items_merge_requests=Iekฤผauลกanas pieprasฤซjumi
migrate_items_releases=Laidienus
-migrate_repo=Migrฤt repozitoriju
-migrate.clone_address=Klonฤลกanas adrese
-migrate.clone_address_desc=Tฤ var bลซt HTTP(S) adrese vai Git 'clone' URL eksistฤjoลกam repozitorijam
-migrate.github_token_desc=Ir iespฤjams izmantot vienu vai ar komantiem atdalฤซtus vairฤkas pilnvaras, lai veiktu ฤtrฤku migrฤciju, ja tฤ tiek ierobeลพota ar GitHub API ierobeลพojumiem. BRฤชDINฤJUMS: ล ฤซs iespฤjas ฤผaunprฤtฤซga izmantoลกana, var tikt uzskatฤซta par lietoลกanas noteikumu pฤrkฤpumu ar no tฤ izrietoลกฤm sekฤm.
+migrate_repo=Pฤrcelt glabฤtavu
+migrate.clone_address=Pฤrcelt/klonฤt no URL
+migrate.clone_address_desc=Esoลกas glabฤtavas HTTP(S) vai Git "clone" URL
+migrate.github_token_desc=ล eit var pievienot vienu vai vairฤkas ar komatiem atdalฤซtas pilnvaras, lai pฤrcelลกana bลซtu ฤtrฤka, ja tฤ tiek ierobeลพota no GitHub API puses. Uzmanฤซbu: ลกฤซs iespฤjas ฤผaunprฤtฤซga izmantoลกana var pฤrkฤpt pakalpojumu sniedzฤja noteikumus un novest pie piekฤผuves liegลกanas kontam.
migrate.clone_local_path=vai servera lokฤlais ceฤผลก
-migrate.permission_denied=Jums nav tiesฤซbu importฤt lokฤlu repozitoriju.
-migrate.permission_denied_blocked=Nav iespฤjams importฤt no neatฤผautฤm adresฤm, prasiet administratoram pฤrskatฤซt ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS iestatฤซjumus.
-migrate.invalid_local_path=Nederฤซgs lokฤlais ceฤผลก. Tas neeksistฤ vai nav direktorija.
-migrate.invalid_lfs_endpoint=LFS galapunkts nav korekts.
-migrate.failed=Migrฤcija neizdevฤs: %v
-migrate.migrate_items_options=Piekฤผuves pilnvara ir nepiecieลกams, lai migrฤtu papildus datus
-migrated_from=Migrฤts no %[2]s
-migrated_from_fake=Migrฤts no %[1]s
-migrate.migrate=Migrฤt no %s
-migrate.migrating=Migrฤcija no %s ...
-migrate.migrating_failed=Migrฤcija no %s neizdevฤs.
-migrate.migrating_failed.error=Migrฤcija neizdevฤs: %s
-migrate.migrating_failed_no_addr=Migrฤcija neizdevฤs.
-migrate.github.description=Migrฤt datus no github.com vai citฤm GitHub instancฤm.
-migrate.git.description=Migrฤt repozitorija datus no jebkura Git servisa.
-migrate.gitlab.description=Migrฤt datus no gitlab.com vai citฤm GitLab instancฤm.
-migrate.gitea.description=Migrฤt datus no gitea.com vai citฤm Gitea/Forgejo instancฤm.
-migrate.gogs.description=Migrฤt datus no notabug.org vai citฤm Gogs instancฤm.
-migrate.onedev.description=Migrฤt datus no code.onedev.io vai citฤm OneDev instancฤm.
-migrate.codebase.description=Migrฤt datus no codebasehq.com.
-migrate.gitbucket.description=Migrฤt datus no GitBucket instancฤm.
-migrate.migrating_git=Migrฤ git datus
-migrate.migrating_topics=Migrฤ tฤmas
-migrate.migrating_milestones=Migrฤ atskaites punktus
-migrate.migrating_labels=Migrฤ etiฤทetes
-migrate.migrating_releases=Migrฤ laidienus
-migrate.migrating_issues=Migrฤcijas problฤmas
-migrate.migrating_pulls=Migrฤ izmaiลu pieprasฤซjumus
-migrate.cancel_migrating_title=Atcelt migrฤciju
-migrate.cancel_migrating_confirm=Vai patieลกam vฤlaties atcelt ลกo migrฤciju?
+migrate.permission_denied=Nav ฤผauts ievietot vietฤjas glabฤtavas.
+migrate.permission_denied_blocked=Nav iespฤjams ievietot no neatฤผautiem saimniekdatoriem, lลซgums vaicฤt pฤrvaldฤซtฤjam pฤrbaudฤซt ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS iestatฤซjumus.
+migrate.invalid_local_path=Nederฤซgs vietฤjais ceฤผลก. Tas nepastฤv vai nenorฤda uz mapi.
+migrate.invalid_lfs_endpoint=LFS galapunkts nav derฤซgs.
+migrate.failed=Pฤrcelลกana neizdevฤs: %v
+migrate.migrate_items_options=Ir nepiecieลกama piekฤผuves pilnvara, lai pฤrceltu papildu vienumus
+migrated_from=Pฤrcelta no %[2]s
+migrated_from_fake=Pฤrcelta no %[1]s
+migrate.migrate=Pฤrcelt no %s
+migrate.migrating=Pฤrceฤผ no %s โฆ
+migrate.migrating_failed=Pฤrcelลกana no %s neizdevฤs.
+migrate.migrating_failed.error=Neizdevฤs pฤrcelt: %s
+migrate.migrating_failed_no_addr=Pฤrcelลกana neizdevฤs.
+migrate.github.description=Pฤrcelt datus no github.com vai GitHub Enterprise servera.
+migrate.git.description=Pฤrcelt tikai glabฤtavu no jebkura Git pakalpojuma.
+migrate.gitlab.description=Pฤrcelt datus no gitlab.com vai citiem GitLab serveriem.
+migrate.gitea.description=Pฤrcelt datus no gitea.com vai citiem Gitea serveriem.
+migrate.gogs.description=Pฤrcelt datus no notabug.org vai citiem Gogs serveriem.
+migrate.onedev.description=Pฤrcelt datus no code.onedev.io vai citiem OneDev serveriem.
+migrate.codebase.description=Pฤrcelt datus no codebasehq.com.
+migrate.gitbucket.description=Pฤrcelt datus no GitBucket serveriem.
+migrate.migrating_git=Pฤrceฤผ Git datus
+migrate.migrating_topics=Pฤrceฤผ tฤmas
+migrate.migrating_milestones=Pฤrceฤผ atskaites punktus
+migrate.migrating_labels=Pฤrceฤผ iezฤซmes
+migrate.migrating_releases=Pฤrceฤผ laidienus
+migrate.migrating_issues=Pฤrnes pieteikumus
+migrate.migrating_pulls=Pฤrceฤผ izmaiลu pieprasฤซjumus
+migrate.cancel_migrating_title=Atcelt pฤrcelลกanu
+migrate.cancel_migrating_confirm=Vai atcelt ลกo pฤrcelลกanu?
-mirror_from=spogulis no
-forked_from=atdalฤซts no
-generated_from=ฤฃenerฤts no
-fork_from_self=Nav iespฤjams atdalฤซt repozitoriju, kuram esat ฤซpaลกnieks.
-fork_guest_user=Piesakieties, lai atdalฤซtu repozitoriju.
-watch_guest_user=Piesakieties, lai sekotu ลกim repozitorijam.
-star_guest_user=Piesakieties, lai pievienotu ลกo repozitoriju izlasei.
+mirror_from=spoguฤผota no
+forked_from=atzarota no
+generated_from=izveidots no
+fork_from_self=Nevar izveidot sev piederoลกas glabฤtavas atzarojumu.
+fork_guest_user=Jฤpiesakฤs, lai izveidotu ลกฤซs glabฤtavas atzarojumu.
+watch_guest_user=Jฤpiesakฤs, lai vฤrotu ลกo glabฤtavu.
+star_guest_user=Jฤpiesakฤs, lai pievienotu ลกo glabฤtavu izlasei.
unwatch=Nevฤrot
watch=Vฤrot
-unstar=Noลemt zvaigznฤซti
+unstar=Noลemt no izlases
star=Pievienot izlasei
-fork=Atdalฤซts
-download_archive=Lejupielฤdฤt repozitoriju
+fork=Atzarojums
+download_archive=Lejupielฤdฤt glabฤtavu
more_operations=Vairฤk darbฤซbu
no_desc=Nav apraksta
quick_guide=ฤชsa pamฤcฤซba
-clone_this_repo=Klonฤt ลกo repozitoriju
-cite_this_repo=Citฤt ลกo repozitoriju
-create_new_repo_command=Izveidot jaunu repozitoriju komandrindฤ
-push_exist_repo=Nosลซtฤซt izmaiลas no komandrindas eksistฤjoลกam repozitorijam
-empty_message=Repozitorijs ir tukลกs.
-broken_message=Git repozitoriju nav iespฤjams nolasฤซt. Sazinieties ar ลกฤซ servera administratoru vai izdzฤsiet ลกo repozitoriju.
+clone_this_repo=Klonฤt ลกo glabฤtavu
+cite_this_repo=Atsaukties uz ลกo glabฤtavu
+create_new_repo_command=Jaunas glabฤtavas izveidoลกana komandrindฤ
+push_exist_repo=Esoลกas glabฤtavas izmaiลu aizgฤdฤลกana no komandrindas
+empty_message=ล ajฤ glabฤtavฤ nav nekฤda satura.
+broken_message=ล ฤซs glabฤtavas Git datus nevar nolasฤซt. Jฤsazinฤs ar ลกฤซ servera pฤrvaldฤซtฤju vai jฤizdzฤลก ลกฤซ glabฤtava.
code=Kods
-code.desc=Piekฤผลซt pirmkodam, failiem, revฤซzijฤm un atzariem.
-branch=Atzars
+code.desc=Piekฤผuve pirmkodam, datnฤm, iesลซtฤซjumiem un zariem.
+branch=Zars
tree=Koks
clear_ref=`Notฤซrฤซt paลกreizฤjo atsauci`
-filter_branch_and_tag=Filtrฤt atzarus vai tagus
-find_tag=Atrast tagu
-branches=Atzari
-tags=Tagi
-issues=Problฤmas
+filter_branch_and_tag=Atlasฤซt zaru vai birku
+find_tag=Atrast birku
+branches=Zari
+tags=Birkas
+issues=Pieteikumi
pulls=Izmaiลu pieprasฤซjumi
project_board=Projekti
packages=Pakotnes
actions=Darbฤซbas
-labels=Etiฤทetes
-org_labels_desc=Organizฤcijas lฤซmeลa etiฤทetes var tikt izmantotas visiem repozitorijiem ลกajฤ organizฤcijฤ
+labels=Iezฤซmes
+org_labels_desc=Apvienฤซbas lฤซmeลa iezฤซmes var tikt izmantotas ลกฤซs apvienฤซbas visฤs glabฤtavฤs
org_labels_desc_manage=pฤrvaldฤซt
milestones=Atskaites punkti
-commits=Revฤซzijas
-commit=Revฤซzija
+commits=Iesลซtฤซjumi
+commit=Iesลซtฤซjums
release=Laidiens
releases=Laidieni
-tag=Tags
+tag=Birka
released_this=izveidoja ลกo laidienu
tagged_this=izveidoja tagu revฤซzijai
-file.title=%s atzarฤ %s
-file_raw=Neapstrฤdฤts
+file.title=%s zarฤ %s
+file_raw=Neapstrฤdฤta
file_history=Vฤsture
file_view_source=Skatฤซt avotu
-file_view_rendered=Skatฤซt rezultฤtu
-file_view_raw=Rฤdฤซt neapstrฤdฤtu
+file_view_rendered=Skatฤซt atveidojumu
+file_view_raw=Apskatฤซt neapstrฤdฤtu
file_permalink=Patstฤvฤซgฤ saite
-file_too_large=ล is fails ir par lielu, lai to parฤdฤซtu.
-invisible_runes_header=`ล ฤซs fails satur neredzamus unikoda simbolus`
-invisible_runes_description=`ล is fails satur neredzamus unikoda simbolus, kas ir neatลกฤทirami cilvฤkiem, bet dators tฤs var atstrฤdฤt atลกฤทirฤซgi. Ja ลกฤทiet, ka tas ir ar nolลซku, ลกo brฤซdinฤjumu var droลกi neลemt vฤrฤ. Jฤizmanto atsoฤผa taustiลลก (Esc), lai atklฤtu tฤs.`
-ambiguous_runes_header=`ล is fails satur neviennozฤซmฤซgus unikoda simbolus`
-ambiguous_runes_description=`ล is fails satur unikoda simbolus, kas var tikt sajauktas ar citฤm rakstzฤซmฤm. Ja ลกฤทiet, ka tas ir ar nolลซku, ลกo brฤซdinฤjumu var droลกi neลemt vฤrฤ. Jฤizmanto atsoฤผa taustiลลก (Esc), lai atklฤtu tฤs.`
-invisible_runes_line=`ล ฤซ lฤซnija satur neredzamus unikoda simbolus`
-ambiguous_runes_line=`ล ฤซ lฤซnija satur neviennozฤซmฤซgus unikoda simbolus`
+file_too_large=Datne ir pฤrฤk liela, lai to parฤdฤซtu.
+invisible_runes_header=ล ฤซ datne satur neredzamas unikoda rakstzฤซmes
+invisible_runes_description=`ล ฤซ datne satur neredzamas unikoda rakstzฤซmes, kas ir neatลกฤทiramas cilvฤkiem, bet dators tฤs var apstrฤdฤt atลกฤทirฤซgi. Ja ลกฤทiet, ka tas ir ar nolลซku, ลกo brฤซdinฤjumu var droลกi neลemt vฤrฤ. Jฤizmanto atsoฤผa taustiลลก (Esc), lai atklฤtu tฤs.`
+ambiguous_runes_header=`ล ฤซ datne satur neviennozฤซmฤซgas unikoda rakstzฤซmes`
+ambiguous_runes_description=`ล ฤซ datne satur unikoda rakstzฤซmes, kas var tikt sajauktas ar citฤm rakstzฤซmฤm. Ja ลกฤทiet, ka tas ir ar nolลซku, ลกo brฤซdinฤjumu var droลกi neลemt vฤrฤ. Jฤizmanto atsoฤผa taustiลลก (Esc), lai tฤs atklฤtu.`
+invisible_runes_line=`ล ajฤ rindฤ ir neredzamas unikoda rakstzฤซmes`
+ambiguous_runes_line=`ล ajฤ rindฤ ir neviennozฤซmฤซgas unikoda rakstzฤซmes`
ambiguous_character=`%[1]c [U+%04[1]X] var tikt sajaukts ar %[2]c [U+%04[2]X]`
escape_control_characters=Kodฤt
unescape_control_characters=Atkodฤt
-file_copy_permalink=Kopฤt saiti
-view_git_blame=Aplลซkot Git vainฤซgos
-video_not_supported_in_browser=Jลซsu pฤrlลซks neatbalsta HTML5 video.
-audio_not_supported_in_browser=Jลซsu pฤrlลซks neatbalsta HTML5 audio.
+file_copy_permalink=Ievietot pastฤvฤซgo saiti starpliktuvฤ
+view_git_blame=Apskatฤซt Git izmaiลu veicฤjus
+video_not_supported_in_browser=Pฤrlลซks neatbalsta HTML5 tagu "video".
+audio_not_supported_in_browser=Pฤrlลซks neatbalsta HTML5 tagu "audio".
stored_lfs=Saglabฤts Git LFS
+stored_annex=Saglabฤts Git Annex
symbolic_link=Simboliska saite
-executable_file=Izpildฤmais fails
-commit_graph=Revฤซziju grafs
-commit_graph.select=Izvฤlieties atzarus
+executable_file=Izpildฤma datne
+commit_graph=Iesลซtฤซjumu karte
+commit_graph.select=Atlasฤซt zarus
commit_graph.hide_pr_refs=Paslฤpt izmaiลu pieprasฤซjumus
commit_graph.monochrome=Melnbalts
commit_graph.color=Krฤsa
-commit.contained_in=ล ฤซ revฤซzija ir iekฤผauta:
-commit.contained_in_default_branch=ล ฤซ revฤซzija ir daฤผa no noklusฤtฤ atzara
-commit.load_referencing_branches_and_tags=Ielฤdฤt atzarus un tagus, kas atsaucas uz ลกo revฤซziju
-blame=Vainot
-download_file=Lejupielฤdฤt failu
+commit.contained_in=ล is iesลซtฤซjums ir iekฤผauts:
+commit.contained_in_default_branch=ล is iesลซtฤซjums ir daฤผa no noklusฤjuma zara
+commit.load_referencing_branches_and_tags=Ielฤdฤt zarus un birkas, kas atsaucas uz ลกo iesลซtฤซjumu
+blame=Uzrฤdฤซt
+download_file=Lejupielฤdฤt datni
normal_view=Parastais skats
line=rinda
lines=rindas
-from_comment=(komentฤrs)
+from_comment=(piebilde)
-editor.add_file=Pievienot
+editor.add_file=Pievienot datni
editor.new_file=Jauna datne
-editor.upload_file=Augลกupielฤdฤt failu
-editor.edit_file=Labot failu
+editor.upload_file=Augลกupielฤdฤt datni
+editor.edit_file=Labot datni
editor.preview_changes=Priekลกskatฤซt izmaiลas
-editor.cannot_edit_lfs_files=LFS failus nevar labot no tฤซmekฤผa saskarnes.
-editor.cannot_edit_non_text_files=Nav iespฤjams labot binฤros failus no pฤrlลซka saskarnes.
-editor.edit_this_file=Labot failu
-editor.this_file_locked=Fails ir bloฤทฤts
-editor.must_be_on_a_branch=Ir jฤbลซt izvฤlฤtam atzaram, lai varฤtu veikt vai piedฤvฤt izmaiลas ลกim failam.
-editor.fork_before_edit=Lai varฤtu labot failu, ir nepiecieลกams atdalฤซt repozitoriju.
-editor.delete_this_file=Dzฤst failu
-editor.must_have_write_access=Jums ir jฤbลซt rakstฤซลกanas tiesฤซbฤm, lai varฤtu veikt vai piedฤvฤt izmaiลas ลกim failam.
-editor.file_delete_success=Fails "%s" tika izdzฤsts.
-editor.name_your_file=Ievadiet faila nosaukumuโฆ
-editor.filename_help=Lai pievienotu direktoriju, ierakstiet tฤs nosaukumu un slฤซpsvฤซtru ('/'). Lai noลemtu direktoriju, ielieciet kursoru pirms faila nosaukuma un nospiediet atpakaฤผatkฤpes taustiลu.
+editor.cannot_edit_lfs_files=LFS datnes nevar labot tฤซmekฤผa saskarnฤ.
+editor.cannot_edit_annex_files=Annex datnes tฤซmekฤผa saskarnฤ nevar labot.
+editor.cannot_edit_non_text_files=Binฤrฤs datnes nevar labot tฤซmekฤผa saskarnฤ.
+editor.edit_this_file=Labot datni
+editor.this_file_locked=Datne ir slฤgta
+editor.must_be_on_a_branch=Ir jฤbลซt zarฤ, lai ลกajฤ datnฤ veiktu vai ierosinฤtu izmaiลas.
+editor.fork_before_edit=Jฤizveido ลกฤซs glabฤtavas atzarojums, lai ลกajฤ datnฤ veiktu vai ierosinฤtu izmaiลas.
+editor.delete_this_file=Izdzฤst datni
+editor.must_have_write_access=Ir jฤbลซt rakstฤซลกanas piekฤผuvei, lai ลกajฤ datnฤ veiktu vai ierosinฤtu izmaiลas.
+editor.file_delete_success=Datne "%s" tika izdzฤsta.
+editor.name_your_file=Pieลกฤทirt datnei nosaukumuโฆ
+editor.filename_help=Mapi var pievienot, ja ieraksta tฤs nosaukumu, aiz kura ir slฤซpsvฤซtra ("/"). Mapi var noลemt ar atpakaฤผatkฤpes taustiลa nospieลกanu ievades lauka sฤkumฤ.
editor.or=vai
editor.cancel_lower=Atcelt
-editor.commit_signed_changes=Apstiprinฤt parakstฤซtu revฤซziju
-editor.commit_changes=Pabeigt revฤซziju
-editor.add_tmpl=Pievienot ''
+editor.commit_signed_changes=Iesลซtฤซt parakstฤซtas izmaiลas
+editor.commit_changes=Iesลซtฤซt izmaiลas
+editor.add_tmpl=Pievienot "<%s>"
+editor.add_tmpl.filename = datnes nosaukums
editor.add=Pievienot %s
-editor.update=Atjaunot %s
-editor.delete=Dzฤst %s
+editor.update=Atjauninฤt %s
+editor.delete=Izdzฤst %s
editor.patch=Pielietot ielฤpu
editor.patching=Pielieto ielฤpu:
editor.fail_to_apply_patch=`Neizdevฤs pielietot ielฤpu "%s"`
editor.new_patch=Jauns ielฤps
-editor.commit_message_desc=Pievienot neobligฤtu paplaลกinฤtu aprakstuโฆ
-editor.signoff_desc=Pievienot revฤซzijas ลพurnฤla ziลojuma beigฤs Signed-off-by ar revฤซzijas autoru.
-editor.commit_directly_to_this_branch=Apstiprinฤt revฤซzijas izmaiลas atzarฤ %s .
-editor.create_new_branch=Izveidot jaunu atzaru un izmaiลu pieprasฤซjumu ลกai revฤซzijai.
-editor.create_new_branch_np=Izveidot jaunu atzaru ลกai revฤซzijai.
-editor.propose_file_change=Ieteikt faila izmaiลas
-editor.new_branch_name=Jaunฤ atzara nosaukums ลกai revฤซzijai
-editor.new_branch_name_desc=Jaunฤ atzara nosaukumsโฆ
+editor.commit_message_desc=Pฤc izvฤles var pievienot paplaลกinฤtu aprakstuโฆ
+editor.signoff_desc=Iesลซtฤซjuma ลพurnฤla ziลojumam pievienot noslฤgumu Signed-off-by ar iesลซtฤซtฤju.
+editor.commit_directly_to_this_branch=Iesลซtฤซt uzreiz zarฤ %[1]s .
+editor.create_new_branch=Izveidot ลกim iesลซtฤซjumam jaunu zaru un uzsฤkt izmaiลu pieprasฤซjumu.
+editor.create_new_branch_np=Izveidot jaunu zaru ลกim iesลซtฤซjumam.
+editor.propose_file_change=Ierosinฤt datnes izmaiลas
+editor.new_branch_name=Pieลกฤทirt nosaukumu ลกฤซ iesลซtฤซjuma jaunajam zaram
+editor.new_branch_name_desc=Jaunฤ zara nosaukumsโฆ
editor.cancel=Atcelt
-editor.filename_cannot_be_empty=Faila nosaukums nevar bลซt tukลกs.
-editor.filename_is_invalid=Faila nosaukums "%s" nav korekts.
-editor.branch_does_not_exist=ล ajฤ repozitorijฤ neeksistฤ atzars "%s".
-editor.branch_already_exists=Atzars "%s" ลกajฤ repozitorijฤ jau eksistฤ.
-editor.directory_is_a_file=Direktorijas nosaukums "%s" vecฤka ceฤผฤ ir fails nevis direktorija ลกajฤ repozitorijฤ.
-editor.file_is_a_symlink=Fails "%s" ir norฤde, kuru nav iespฤjams labot no tฤซmekฤผa redaktora
-editor.filename_is_a_directory=Faila nosaukums "%s" sakrฤซt ar direktorijas nosaukumu ลกajฤ repozitorijฤ.
-editor.file_editing_no_longer_exists=Fails "%s", ko labojat, vairs neeksistฤ ลกajฤ repozitorijฤ.
-editor.file_deleting_no_longer_exists=Fails "%s", ko dzฤลกat, vairs neeksistฤ ลกajฤ repozitorijฤ.
-editor.file_changed_while_editing=Faila saturs ir mainฤซjies kopลก sฤkฤt to labot. Noklikลกฤทiniet ลกeit , lai apskatฤซtu, vai Nosลซtiet izmaiลas atkฤrtoti , lai pฤrrakstฤซtu.
-editor.file_already_exists=Fails ar nosaukumu "%s" ลกajฤ repozitorijฤ jau eksistฤ.
-editor.commit_empty_file_header=Iesลซtฤซt tukลกu failu
-editor.commit_empty_file_text=Fails, ko vฤlaties iesลซtฤซt, ir tukลกs. Vai turpinฤt?
+editor.filename_cannot_be_empty=Datnes nosaukums nevar bลซt tukลกs.
+editor.filename_is_invalid=Datnes nosaukums "%s" nav derฤซgs.
+editor.branch_does_not_exist=ล ajฤ glabฤtavฤ nav zara "%s".
+editor.branch_already_exists=ล ajฤ glabฤtavฤ jau ir zars "%s".
+editor.directory_is_a_file=Mapes nosaukums "%s" ลกajฤ glabฤtavฤ jau tiek izmantots kฤ datnes nosaukums.
+editor.file_is_a_symlink=`"%s" ir simboliska saite. Simboliskฤs saites tฤซmekฤผa redaktorฤ nevar labot`
+editor.filename_is_a_directory=Datnes nosaukums "%s" ลกajฤ glabฤtavฤ jau tiek izmantos kฤ mapes nosaukums.
+editor.file_editing_no_longer_exists=Datne, kas tiek labota ("%s"), ลกajฤ glabฤtavฤ vairs nepastฤv.
+editor.file_deleting_no_longer_exists=Datne, kas tiek izdzฤsta ("%s"), ลกajฤ glabฤtavฤ vairs nepastฤv.
+editor.file_changed_while_editing=Datnes saturs ir mainฤซjies kopลก tฤs atvฤrลกanas. Klikลกฤทinฤt ลกeit , lai apskatฤซtu vai atkฤrtoti iesลซtฤซtu izmaiลas , lai tฤs pฤrrakstฤซtu.
+editor.file_already_exists=Datne ar nosaukumu "%s" jau pastฤv ลกajฤ glabฤtavฤ.
+editor.commit_empty_file_header=Iesลซtฤซt tukลกu datni
+editor.commit_empty_file_text=Iesลซtฤmฤ datne ir tukลกa. Turpinฤt?
editor.no_changes_to_show=Nav izmaiลu, ko rฤdฤซt.
-editor.fail_to_update_file=Neizdevฤs atjaunot/izveidot failu "%s".
+editor.fail_to_update_file=Neizdevฤs atjauninฤt/izveidot datni "%s".
editor.fail_to_update_file_summary=Kฤผลซdas ziลojums:
-editor.push_rejected_no_message=Izmaiลu iesลซtฤซลกana tika noraidฤซta, bet serveris neatgrieza paziลojumu. Pฤrbaudiet git ฤฤทus ลกim repozitorijam.
-editor.push_rejected=Serveris noraidฤซja ลกo izmaiลu. Pฤrbaudiet git ฤฤทus.
+editor.push_rejected_no_message=Serveris bez paziลojuma noraidฤซja izmaiลas. Lลซgums pฤrbaudฤซt Git aizฤทeres.
+editor.push_rejected=Serveris noraidฤซja izmaiลas. Lลซgums pฤrbaudฤซt Git aizฤทeres.
editor.push_rejected_summary=Pilns noraidฤซลกanas ziลojums:
-editor.add_subdir=Pievienot direktorijuโฆ
-editor.unable_to_upload_files=Neizdevฤs augลกupielฤdฤt failus uz direktoriju "%s", kฤผลซda: %v
-editor.upload_file_is_locked=Failu "%s" ir nobloฤทฤjis %s.
-editor.upload_files_to_dir=`Augลกupielฤdฤt failus uz direktoriju "%s"`
-editor.cannot_commit_to_protected_branch=Nav atฤผauts veikt izmaiลas aizsargฤtam atzaram "%s".
-editor.no_commit_to_branch=Nevar apstiprinฤt revฤซzijas atzarฤ:
-editor.user_no_push_to_branch=Lietotฤjs nevar iesลซtฤซt izmaiลas ลกajฤ atzarฤ
-editor.require_signed_commit=Atzarฤ var iesลซtฤซt tikai parakstฤซtas revฤซzijas
+editor.add_subdir=Pievienot mapiโฆ
+editor.unable_to_upload_files=Neizdevฤs augลกupielฤdฤt datnes "%s" ลกฤซs kฤผลซdas dฤฤผ: %v
+editor.upload_file_is_locked=Datni "%s" aizslฤdza %s.
+editor.upload_files_to_dir=Augลกupielฤdฤt datnes "%s"
+editor.cannot_commit_to_protected_branch=Nevar iesลซtฤซt aizsargฤtajฤ zarฤ "%s".
+editor.no_commit_to_branch=Nevar iesลซtฤซt uzreiz zarฤ, jo:
+editor.user_no_push_to_branch=Lietotฤjs nevar aizgฤdฤt zarฤ
+editor.require_signed_commit=Zarฤ ir nepiecieลกami parakstฤซti iesลซtฤซjumi
editor.cherry_pick=Izlasฤซt %s uz:
editor.revert=Atgriezt %s uz:
commits.desc=Pฤrlลซkot pirmkoda izmaiลu vฤsturi.
-commits.commits=Revฤซzijas
-commits.no_commits=Nav kopฤซgu revฤซziju. Atzariem "%s" un "%s" ir pilnฤซbฤ atลกฤทirฤซga izmaiลu vฤsture.
-commits.nothing_to_compare=Atzari ir vienฤdi.
+commits.commits=Iesลซtฤซjumi
+commits.no_commits=Nav kopฤซgu iesลซtฤซjumu. "%s" un "%s" ir pilnฤซgi atลกฤทirฤซga vฤsture.
+commits.nothing_to_compare=ล ie zari ir vienฤdi.
commits.search=Meklฤt revฤซzijasโฆ
-commits.search.tooltip=Jลซs varat izmantot atslฤgas vฤrdus "author:", "committer:", "after:" vai "before:", piemฤram, "revert author:Alice before:2019-01-13".
+commits.search.tooltip=Atslฤgvฤrdu sฤkumฤ var pievienot "author:", "committer:", "after:" vai "before:", piemฤram, "revert author:Anna before:2019-01-13".
commits.find=Meklฤt
-commits.search_all=Visi atzari
+commits.search_all=Visi zari
commits.author=Autors
commits.message=Ziลojums
commits.date=Datums
@@ -1283,138 +1450,138 @@ commits.older=Vecฤki
commits.newer=Jaunฤki
commits.signed_by=Parakstฤซjis
commits.signed_by_untrusted_user=Parakstฤซjis neuzticams lietotฤjs
-commits.signed_by_untrusted_user_unmatched=Parakstฤซjis neuzticams lietotฤjs, kas neatbilst izmaiลu autoram
-commits.gpg_key_id=GPG atslฤgas ID
-commits.ssh_key_fingerprint=SSH atslฤgas identificฤjoลกฤ zฤซmju virkne
-commits.view_path=Skatฤซt ลกajฤ vฤstures punktฤ
+commits.signed_by_untrusted_user_unmatched=Parakstฤซjis neuzticams lietotฤjs, kurลก neatbilst iesลซtฤซtฤjam
+commits.gpg_key_id=GPG atslฤgas identifikators
+commits.ssh_key_fingerprint=SSH atslฤgas nospiedums
+commits.view_path=Apskatฤซt ลกajฤ vฤstures punktฤ
commit.operations=Darbฤซbas
commit.revert=Atgriezt
commit.revert-header=Atgriezt: %s
-commit.revert-content=Norฤdiet atzaru uz kuru atgriezt:
+commit.revert-content=Atlasฤซt zaru, no kura atjaunot:
commit.cherry-pick=Izlasฤซt
commit.cherry-pick-header=Izlasฤซt: %s
-commit.cherry-pick-content=Norฤdiet atzaru uz kuru izlasฤซt:
+commit.cherry-pick-content=Atlasฤซt zaru, uz kuru izlasฤซt:
commitstatus.error=Kฤผลซda
-commitstatus.failure=Kฤผลซme
+commitstatus.failure=Atteice
commitstatus.pending=Nav iesลซtฤซts
commitstatus.success=Pabeigts
-ext_issues=Piekฤผuve ฤrฤjฤm problฤmฤm
+ext_issues=ฤrฤji pieteikumi
ext_issues.desc=Saite uz ฤrฤjo problฤmu sekotฤju.
projects=Projekti
-projects.desc=Pฤrvaldฤซt problฤmu un izmaiลu pieprasฤซjumu projektu dฤฤผus.
-projects.description=Apraksts (neobligฤts)
+projects.desc=Pฤrvaldฤซt pieteikumus un izmaiลu pieprasฤซjumus projektos.
+projects.description=Apraksts (pฤc izvฤles)
projects.description_placeholder=Apraksts
projects.create=Izveidot projektu
projects.title=Nosaukums
projects.new=Jauns projekts
-projects.new_subheader=Koordinฤ, seko un atjauno savu darbu centralizฤti, lai projekts bลซtu izsekojams un vienmฤr laikฤ.
+projects.new_subheader=Saskaลo, pฤrraugi un atjaunini savu darbu vienฤ vietฤ, lai projekti bลซtu caurskatฤmi un vienmฤr laikฤ.
projects.create_success=Projekts "%s" tika izveidots.
-projects.deletion=Dzฤst projektu
-projects.deletion_desc=Dzฤลกot projektu no tฤ tiks atsaistฤซtฤs visas tam piesaistฤซtฤs problฤmas. Vai turpinฤt?
+projects.deletion=Izdzฤst projektu
+projects.deletion_desc=Projekta izdzฤลกana noลem to no visiem saistฤซtajiem pieteikumiem. Turpinฤt?
projects.deletion_success=ล is projekts tika izdzฤsts.
projects.edit=Labot projektu
-projects.edit_subheader=Projekti organizฤ problฤmas un ฤผauj izsekot to progresam.
-projects.modify=Mainฤซt projektu
+projects.edit_subheader=Projektos var sakฤrtot pieteikumus un sekot attฤซstฤซbai.
+projects.modify=Labot projektu
projects.edit_success=Projekta "%s" izmaiลas tika saglabฤtas.
projects.type.none=Nav
-projects.type.basic_kanban=`Vienkฤrลกots "Kanban"`
+projects.type.basic_kanban=Pamata "Kanban"
projects.type.bug_triage=Kฤผลซdu ลกฤทiroลกana
-projects.template.desc=Projekta sagatave
-projects.template.desc_helper=Izvฤlieties projekta sagatavi, lai sฤktu darbu
+projects.template.desc=Sagatave
+projects.template.desc_helper=Jฤatlasa projekta sagatave, lai uzsฤktu
projects.type.uncategorized=Bez kategorijas
-projects.column.edit=Rediฤฃฤt kolonnas
+projects.column.edit=Labot aili
projects.column.edit_title=Nosaukums
projects.column.new_title=Nosaukums
-projects.column.new_submit=Izveidot kolonnu
-projects.column.new=Jauna kolonna
-projects.column.set_default=Izvฤlฤties kฤ noklusฤto
-projects.column.set_default_desc=Izvฤlฤties ลกo kolonnu kฤ noklusฤto nekategorizฤtฤm problฤmฤm un izmaiลu pieteikumiem
+projects.column.new_submit=Izveidot aili
+projects.column.new=Jauna aile
+projects.column.set_default=Iestatฤซt kฤ noklusฤjuma
+projects.column.set_default_desc=Iestatฤซt ลกo aili kฤ noklusฤjumu neapkopotiem pieteikumiem un izmaiลu pieprasฤซjumiem
projects.column.unset_default=Atiestatฤซt noklusฤto
projects.column.unset_default_desc=Noลemt ลกo kolonnu kฤ noklusฤto
-projects.column.delete=Dzฤst kolonnu
-projects.column.deletion_desc=Dzฤลกot projekta kolonnu visas tam piesaistฤซtฤs problฤmas tiks pฤrliktas kฤ nekategorizฤtas. Vai turpinฤt?
+projects.column.delete=Izdzฤst aili
+projects.column.deletion_desc=Projekta ailes izdzฤลกana pฤrvietos visus saistฤซtos pieteikumus uz noklusฤjuma aili. Turpinฤt?
projects.column.color=Krฤsa
-projects.open=Aktฤซvie
+projects.open=Atvฤrtie
projects.close=Pabeigtie
projects.column.assigned_to=Pieลกฤทirts
-projects.card_type.desc=Kartฤซtes priekลกskatฤซjums
+projects.card_type.desc=Kartฤซลกu priekลกskatฤซjumi
projects.card_type.images_and_text=Attฤli un teksts
projects.card_type.text_only=Tikai teksts
-issues.desc=Organizฤt kฤผลซdu ziลojumus, uzdevumus un atskaites punktus.
-issues.filter_assignees=Filtrฤt pฤc atbildฤซgajiem
-issues.filter_milestones=Filtrฤt pฤc atskaites punkta
-issues.filter_projects=Filtrฤt pฤc projekta
-issues.filter_labels=Filtrฤt pฤc etiฤทetฤm
-issues.filter_reviewers=Filtrฤt pฤc recenzentiem
-issues.new=Jauna problฤma
+issues.desc=Kฤผลซdu ziลojumus, uzdevumu un atskaites punktu apkopoลกana.
+issues.filter_assignees=Atlasฤซt pฤc atbildฤซgajiem
+issues.filter_milestones=Atlasฤซt pฤc atskaites punkta
+issues.filter_projects=Atlasฤซt pฤc projekta
+issues.filter_labels=Atlasฤซt pฤc iezฤซmes
+issues.filter_reviewers=Atlasฤซt izskatฤซtฤjus
+issues.new=Jauns pieteikums
issues.new.title_empty=Nosaukums nevar bลซt tukลกs
-issues.new.labels=Etiฤทetes
-issues.new.no_label=Nav etiฤทeลกu
-issues.new.clear_labels=Noลemt etiฤทetes
+issues.new.labels=Iezฤซmes
+issues.new.no_label=Nav iezฤซmju
+issues.new.clear_labels=Notฤซrฤซt iezฤซmes
issues.new.projects=Projekti
issues.new.clear_projects=Notฤซrฤซt projektus
issues.new.no_projects=Nav projektu
-issues.new.open_projects=Aktฤซvie projekti
-issues.new.closed_projects=Pabeigtie projekti
+issues.new.open_projects=Atvฤrtie projekti
+issues.new.closed_projects=Aizvฤrtie projekti
issues.new.no_items=Nav neviena ieraksta
issues.new.milestone=Atskaites punkts
-issues.new.no_milestone=Nav atskaites punktu
+issues.new.no_milestone=Nav atskaites punkta
issues.new.clear_milestone=Notฤซrฤซt atskaites punktus
-issues.new.open_milestone=Atvฤrtie atskaites punktus
+issues.new.open_milestone=Atvฤrtie atskaites punkti
issues.new.closed_milestone=Aizvฤrtie atskaites punkti
issues.new.assignees=Atbildฤซgie
issues.new.clear_assignees=Noลemt atbildฤซgo
issues.new.no_assignees=Nav atbildฤซgo
-issues.new.no_reviewers=Nav recenzentu
-issues.choose.get_started=Sฤkt darbu
+issues.new.no_reviewers=Nav izskatฤซtฤju
+issues.choose.get_started=Uzsฤkt darbu
issues.choose.open_external_link=Atvฤrt
issues.choose.blank=Noklusฤjuma
-issues.choose.blank_about=Izveidot problฤmu ar noklusฤjuma sagatavi.
+issues.choose.blank_about=Izveidot pieteikumu no noklusฤjuma sagataves.
issues.choose.ignore_invalid_templates=Kฤผลซdainฤs sagataves tika izlaistas
-issues.choose.invalid_templates=%v ฤทฤผลซdaina sagatave(s) atrastas
-issues.choose.invalid_config=Problฤmu konfigurฤcija satur kฤผลซdas:
-issues.no_ref=Nav norฤdฤซts atzars/tags
-issues.create=Pieteikt problฤmu
-issues.new_label=Jauna etiฤทete
-issues.new_label_placeholder=Etiฤทetes nosaukums
+issues.choose.invalid_templates=atrasta(s) %v nederฤซgas(s) sagatave(s)
+issues.choose.invalid_config=Pieteikumu konfigurฤcija satur kฤผลซdas:
+issues.no_ref=Nav norฤdฤซts zars/birka
+issues.create=Izveidot pieteikumu
+issues.new_label=Jauna iezฤซme
+issues.new_label_placeholder=Iezฤซmes nosaukums
issues.new_label_desc_placeholder=Apraksts
-issues.create_label=Izveidot etiฤทeti
-issues.label_templates.title=Ielฤdฤt sฤkotnฤji noteiktu etiฤทeลกu kopu
-issues.label_templates.info=Nav izveidota neviena etiฤทete. Jลซs varat noklikลกฤทinฤt uz "Jauna etiฤทete" augstฤk, lai to izveidotu vai izmantot zemฤk piedฤvฤtฤs etiฤทetes:
-issues.label_templates.helper=Izvฤlieties etiฤทeลกu kopu
-issues.label_templates.use=Izmantot etiฤทeลกu kopu
-issues.label_templates.fail_to_load_file=Neizdevฤs ielฤdฤt etiฤทetes sagataves failu "%s": %v
-issues.add_label=pievienoja %s etiฤทeti %s
-issues.add_labels=pievienoja %s etiฤทetes %s
-issues.remove_label=noลฤma %s etiฤทeti %s
-issues.remove_labels=noลฤma %s etiฤทetes %s
-issues.add_remove_labels=pievienoja %s un noลฤma %s etiฤทetes %s
+issues.create_label=Izveidot iezฤซmi
+issues.label_templates.title=Ielฤdฤt sฤkotnฤji noteiktu iezฤซmju kopu
+issues.label_templates.info=Vฤl nav nevienas iezฤซmes. Jฤizveido iezฤซme ar "Jauna iezฤซme" vai jฤizmanto priekลกiestatฤซta iezฤซmju kopa:
+issues.label_templates.helper=Atlasฤซt priekลกiestatฤซtu iezฤซmju kopu
+issues.label_templates.use=Izmantot iezฤซmju kopu
+issues.label_templates.fail_to_load_file=Neizdevฤs ielฤdฤt iezฤซmju sagataves datni "%s": %v
+issues.add_label=pievienoja %s iezฤซmi %s
+issues.add_labels=pievienoja iezฤซmes %s %s
+issues.remove_label=noลฤma %s iezฤซmi %s
+issues.remove_labels=noลฤma iezฤซmes %s %s
+issues.add_remove_labels=pievienoja iezฤซmes %s un noลฤma %s %s
issues.add_milestone_at=`pievienoja atskaites punktu %s %s`
-issues.add_project_at=`pievienoja ลกo problฤmu %s projektam %s`
+issues.add_project_at=`pievienoja ลกo projektam %s %s`
issues.change_milestone_at=`nomainฤซja atskaites punktu no %s uz %s %s`
-issues.change_project_at=`pฤrvietoja ลกo problฤmu no %s projekta uz %s %s`
+issues.change_project_at=`nomainฤซja projektu no %s uz %s %s`
issues.remove_milestone_at=`noลฤma atskaites punktu %s %s`
-issues.remove_project_at=`noลฤma ลกo problฤmu no %s projekta %s`
-issues.deleted_milestone=`(dzฤsts)`
-issues.deleted_project=`(dzฤsts)`
+issues.remove_project_at=`noลฤma ลกo no projekta %s %s`
+issues.deleted_milestone=`(izdzฤsts)`
+issues.deleted_project=`(izdzฤsts)`
issues.self_assign_at=`pieลกฤทฤซra sev %s`
-issues.add_assignee_at=`tika pieลกฤทirta problฤma no %s %s`
-issues.remove_assignee_at=`tika noลemta problฤma no %s %s`
-issues.remove_self_assignment=`noลฤma sev problฤmu %s`
-issues.change_title_at=`nomainฤซts nosaukums no %s uz %s %s`
+issues.add_assignee_at=`%s pieลกฤทฤซra %s`
+issues.remove_assignee_at=`%s noลฤma %s`
+issues.remove_self_assignment=`noลฤma sev %s`
+issues.change_title_at=`nomainฤซja nosaukumu no %s uz %s %s`
issues.change_ref_at=`nomainฤซta atsauce no %s uz %s %s`
issues.remove_ref_at=`noลฤma atsauci no %s %s`
issues.add_ref_at=`pievienoja atsauci uz %s %s`
-issues.delete_branch_at=`izdzฤsa atzaru %s %s`
-issues.filter_label=Etiฤทete
-issues.filter_label_exclude=`Izmantojiet alt
+ peles klikลกฤทis vai enter
, lai neiekฤผautu etiฤทeti`
-issues.filter_label_no_select=Visas etiฤทetes
-issues.filter_label_select_no_label=Nav etiฤทetes
+issues.delete_branch_at=`izdzฤsa zaru %s %s`
+issues.filter_label=Iezฤซme
+issues.filter_label_exclude=`Jฤizmanto alt
+ klikลกฤทis/Enter
, lai neiekฤผautu iezฤซmes`
+issues.filter_label_no_select=Visas iezฤซmes
+issues.filter_label_select_no_label=Bez iezฤซmes
issues.filter_milestone=Atskaites punkts
issues.filter_milestone_all=Visi atskaites punkti
issues.filter_milestone_none=Nav atskaites punkta
@@ -1429,481 +1596,481 @@ issues.filter_assginee_no_assignee=Nav atbildฤซgฤ
issues.filter_poster=Autors
issues.filter_poster_no_select=Visi autori
issues.filter_type=Veids
-issues.filter_type.all_issues=Visas problฤmas
-issues.filter_type.assigned_to_you=Pieลกฤทirtฤs Jums
-issues.filter_type.created_by_you=Jลซsu izveidotฤs
-issues.filter_type.mentioning_you=Esat pieminฤts
-issues.filter_type.review_requested=Pieprasฤซta recenzija
-issues.filter_type.reviewed_by_you=Tavi recenzฤtie
+issues.filter_type.all_issues=Visi pieteikumi
+issues.filter_type.assigned_to_you=Man pieลกฤทirtie
+issues.filter_type.created_by_you=Manis izveidotie
+issues.filter_type.mentioning_you=Esmu pieminฤts
+issues.filter_type.review_requested=Pieprasฤซta izskatฤซลกana
+issues.filter_type.reviewed_by_you=Manis izskatฤซtie
issues.filter_sort=Kฤrtot
issues.filter_sort.latest=Jaunฤkie
issues.filter_sort.oldest=Vecakie
-issues.filter_sort.recentupdate=Nesen atjaunotฤs
-issues.filter_sort.leastupdate=Vissenฤk atjaunotฤs
-issues.filter_sort.mostcomment=Visvairฤk komentฤtฤs
-issues.filter_sort.leastcomment=Vismazฤk komentฤtฤs
+issues.filter_sort.recentupdate=Nesen atjauninฤtie
+issues.filter_sort.leastupdate=Vissenฤk atjauninฤtie
+issues.filter_sort.mostcomment=Visvairฤk piebilลพu
+issues.filter_sort.leastcomment=Vismazฤk piebilลพu
issues.filter_sort.nearduedate=Tuvฤkais termiลลก
issues.filter_sort.farduedate=Tฤlฤkais termiลลก
-issues.filter_sort.moststars=Visvairฤk atzฤซmฤtie
-issues.filter_sort.feweststars=Vismazฤk atzฤซmฤtie
-issues.filter_sort.mostforks=Visvairฤk atdalฤซtie
-issues.filter_sort.fewestforks=Vismazฤk atdalฤซtie
+issues.filter_sort.moststars=Visvairฤk zvaigลพลu
+issues.filter_sort.feweststars=Vismazฤk zvaigลพลu
+issues.filter_sort.mostforks=Visvairฤk atzarojumu
+issues.filter_sort.fewestforks=Vismazฤk atzarojumu
issues.keyword_search_unavailable=Meklฤลกana pฤc atslฤgvฤrda paลกreiz nav pieejama. Lลซgums sazinฤties ar vietnes administratoru.
issues.action_open=Atvฤrt
issues.action_close=Aizvฤrt
-issues.action_label=Etiฤทete
+issues.action_label=Iezฤซme
issues.action_milestone=Atskaites punkts
issues.action_milestone_no_select=Nav atskaites punkta
issues.action_assignee=Atbildฤซgais
issues.action_assignee_no_select=Nav atbildฤซgฤ
issues.action_check=Atzฤซmฤt/Notฤซrฤซt
-issues.action_check_all=Atzฤซmฤt/Notฤซrฤซt visus ierakstus
+issues.action_check_all=Atzฤซmฤt/Notฤซrฤซt visus vienumus
issues.opened_by=%[3]s atvฤra %[1]s
-pulls.merged_by=%[3]s sapludinฤja %[1]s
-pulls.merged_by_fake=%[2]s sapludinฤja %[1]s
+pulls.merged_by=%[3]s iekฤผฤva %[1]s
+pulls.merged_by_fake=%[2]s iekฤผฤva %[1]s
issues.closed_by=%[3]s aizvฤra %[1]s
issues.opened_by_fake=%[2]s atvฤra %[1]s
issues.closed_by_fake=%[2]s aizvฤra %[1]s
issues.previous=Iepriekลกฤjฤ
issues.next=Nฤkamฤ
-issues.open_title=Atvฤrta
-issues.closed_title=Slฤgta
+issues.open_title=Atvฤrti
+issues.closed_title=Aizvฤrts
issues.draft_title=Melnraksts
-issues.num_comments_1=%d komentฤrs
-issues.num_comments=%d komentฤri
-issues.commented_at=`komentฤja %s `
-issues.delete_comment_confirm=Vai patieลกฤm vฤlaties dzฤst ลกo komentฤru?
-issues.context.copy_link=Kopฤt saiti
-issues.context.quote_reply=Atbildฤt citฤjot
-issues.context.reference_issue=Atsaukties uz ลกo jaunฤ problฤmฤ
+issues.num_comments_1=%d piebilde
+issues.num_comments=%d piebildes
+issues.commented_at=`pievienoja piebildi %s `
+issues.delete_comment_confirm=Vai tieลกฤm izdzฤst ลกo piebildi?
+issues.context.copy_link=Ievietot saiti starpliktuvฤ
+issues.context.quote_reply=Citฤt atbildi
+issues.context.reference_issue=Atsaukties jaunฤ pieteikumฤ
issues.context.edit=Labot
-issues.context.delete=Dzฤst
-issues.no_content=Nav sniegts apraksts.
-issues.close=Slฤgt problฤmu
-issues.comment_pull_merged_at=saplidinฤta revฤซzija %[1]s atzarฤ %[2]s %[3]s
-issues.comment_manually_pull_merged_at=manuฤli saplidinฤta revฤซzija %[1]s atzarฤ %[2]s %[3]s
-issues.close_comment_issue=Komentฤt un aizvฤrt
+issues.context.delete=Izdzฤst
+issues.no_content=Apraksts nav sniegts.
+issues.close=Aizvฤrt pieteikumu
+issues.comment_pull_merged_at=iekฤผฤva iesลซtฤซjumu %[1]s %[2]s %[3]s
+issues.comment_manually_pull_merged_at=paลกrocฤซgi iekฤผฤva iesลซtฤซjumu %[1]s zarฤ %[2]s %[3]s
+issues.close_comment_issue=Aizvฤrt ar piebildi
issues.reopen_issue=Atvฤrt atkฤrtoti
-issues.reopen_comment_issue=Komentฤt un atvฤrt atkฤrtoti
-issues.create_comment=Komentฤt
-issues.closed_at=`slฤdza ลกo problฤmu %[2]s `
-issues.reopened_at=`atkฤrtoti atvฤra ลกo problฤmu %[2]s `
-issues.commit_ref_at=`pieminฤja ลกo problฤmu revฤซzijฤ %[2]s `
-issues.ref_issue_from=`atsaucฤs uz ลกo problฤmu %[4]s %[2]s `
+issues.reopen_comment_issue=Atkฤrtoti atvฤrt ar piebildi
+issues.create_comment=Pievienot piebildi
+issues.closed_at=`aizvฤra ลกo pieteikumu %[2]s `
+issues.reopened_at=`atkฤrtoti atvฤra ลกo pieteikumu %[2]s `
+issues.commit_ref_at=`atsaucฤs uz ลกo pieteikumu iesลซtฤซjumฤ %[2]s `
+issues.ref_issue_from=`atsaucฤs uz ลกo pieteikumu %[4]s %[2]s `
issues.ref_pull_from=`atsaucฤs uz ลกo izmaiลu pieprasฤซjumu %[4]s %[2]s `
-issues.ref_closing_from=`atsaucฤs uz izmaiลu pieprasฤซjumu %[4]s, kas atrisinฤs ลกo problฤmu %[2]s `
-issues.ref_reopening_from=`atsaucฤs uz izmaiลu pieprasฤซjumu %[4]s, kas atkฤrtoti atvฤrs ลกo problฤmu %[2]s `
-issues.ref_closed_from=`aizvฤra problฤmu %[4]s %[2]s `
-issues.ref_reopened_from=`atkฤrtoti atvฤra problฤmu %[4]s %[2]s `
+issues.ref_closing_from=`atsaucฤs uz ลกo pieteikumu izmaiลu pieprasฤซjumฤ %[4]s, kas aizvฤrs to , %[2]s `
+issues.ref_reopening_from=`atsaucฤs uz ลกo pieteikumu izmaiลu pieprasฤซjumฤ %[4]s, kas atkฤrtoti atvฤrs to , %[2]s `
+issues.ref_closed_from=`aizvฤra pieteikumu %[4]s %[2]s `
+issues.ref_reopened_from=`atkฤrtoti atvฤra pieteikumu %[4]s %[2]s `
issues.ref_from=`no %[1]s`
issues.author=Autors
issues.author_helper=ล is lietotฤjs ir autors.
issues.role.owner=ฤชpaลกnieks
-issues.role.owner_helper=ล is lietotฤjs ir ลกฤซ repozitorija ฤซpaลกnieks.
+issues.role.owner_helper=ล is lietotฤjs ir ลกฤซs glabฤtavas ฤซpaลกnieks.
issues.role.member=Dalฤซbnieks
-issues.role.member_helper=ล is lietotฤjs ir organizฤcijas, kurai pieder ลกis repozitorijs, dalฤซbnieks.
-issues.role.collaborator=Lฤซdzstrฤdnieks
-issues.role.collaborator_helper=ล is lietotฤjs ir uzaicinฤts lฤซdzdarboties repozitorijฤ.
-issues.role.first_time_contributor=Pirmreizฤjs lฤซdzradฤซtฤjs
-issues.role.first_time_contributor_helper=ล is ir pirmais ลกฤซ lietotฤja ieguldฤซjums ลกฤjฤ repozitorijฤ.
-issues.role.contributor=Lฤซdzradฤซtฤjs
-issues.role.contributor_helper=ล is lietotฤjs repozitorijฤ ir iepriekลก veicis labojumus.
-issues.re_request_review=Pieprasฤซt atkฤrtotu recenziju
-issues.is_stale=ล ajฤ izmaiลu pieprasฤซjumฤ ir notikuลกas izmaiลฤs, kopลก veicฤt tฤ recenziju
-issues.remove_request_review=Noลemt recenzijas pieprasฤซjumu
-issues.remove_request_review_block=Nevar noลemt recenzฤซjas pieprasฤซjumu
-issues.dismiss_review=Atmest recenziju
-issues.dismiss_review_warning=Vai patieลกฤm vฤlaties atmest ลกo recenziju?
+issues.role.member_helper=ล is lietotฤjs ir apvienฤซbas, kurai pieder ลกฤซ glabฤtava, dalฤซbnieks.
+issues.role.collaborator=Lฤซdzdalฤซbnieks
+issues.role.collaborator_helper=ล is lietotฤjs tika uzaicinฤts lฤซdzdarboties glabฤtavฤ.
+issues.role.first_time_contributor=Pirmreizฤjs lฤซdzdalฤซbnieks
+issues.role.first_time_contributor_helper=ล is ir pirmais ลกฤซ lietotฤja sniegums glabฤtavฤ.
+issues.role.contributor=Lฤซdzdalฤซbnieks
+issues.role.contributor_helper=ล is lietotฤjs iepriekลก ir veicis iesลซtฤซjumus ลกajฤ glabฤtavฤ.
+issues.re_request_review=Pieprasฤซt atkฤrtotu izskatฤซลกanu
+issues.is_stale=Kopลก ลกฤซs izskatฤซลกanas ลกajฤ izmaiลu pieprasฤซjumฤ ir bijuลกas izmaiลas
+issues.remove_request_review=Noลemt izskatฤซลกanas pieprasฤซjumu
+issues.remove_request_review_block=Nevar noลemt izskatฤซลกanas pieprasฤซjumu
+issues.dismiss_review=Atmest izskatฤซลกanu
+issues.dismiss_review_warning=Vai tieลกฤm atmest ลกo izskatฤซลกanu?
issues.sign_in_require_desc=Nepiecieลกams pieteikties , lai pievienotos ลกai sarunai.
issues.edit=Labot
issues.cancel=Atcelt
issues.save=Saglabฤt
-issues.label_title=Etiฤทetes nosaukums
-issues.label_description=Etiฤทetes apraksts
-issues.label_color=Etiฤทetes krฤsa
-issues.label_exclusive=Ekskluzฤซvs
-issues.label_archive=Arhฤซvฤt etiฤทeti
-issues.label_archived_filter=Rฤdฤซt arhivฤtฤs etiฤทetes
-issues.label_archive_tooltip=Arhivฤtฤs etiฤทetes pฤc noklusฤjuma netiek iekฤผautas ieteikumos, kad meklฤ pฤc nosaukuma.
-issues.label_exclusive_desc=Nosauciet etiฤทeti grupa/nosaukums
, lai grupฤtu etiฤทฤtes un varฤtu norฤdฤซt tฤs kฤ ekskluzฤซvas ar citฤm grupa/
etiฤทetฤm.
-issues.label_exclusive_warning=Jebkura konfliktฤjoลกa ekskluzฤซvas grupas etiฤทete tiks noลemta, labojot pieteikumu vai izmaiลu pietikumu etiฤทetes.
-issues.label_count=%d etiฤทetes
-issues.label_open_issues=%d atvฤrtas problฤmas
+issues.label_title=Nosaukums
+issues.label_description=Apraksts
+issues.label_color=Krฤsa
+issues.label_exclusive=Seviลกฤทa
+issues.label_archive=Arhivฤt iezฤซmi
+issues.label_archived_filter=Rฤdฤซt arhivฤtฤs iezฤซmes
+issues.label_archive_tooltip=Arhivฤtฤs iezฤซmes pฤc noklusฤjuma netiek iekฤผautas ieteikumos, kad meklฤ pฤc iezฤซmes.
+issues.label_exclusive_desc=Iezฤซme jฤnodฤvฤ tvฤrums/vienums
, lai padarฤซtu to savstarpฤji seviลกฤทu ar citฤm tvฤrums/
iezฤซmฤm.
+issues.label_exclusive_warning=Jebkura nesaderฤซga tvฤruma iezฤซme tiks noลemta, kad tiks labotas pieteikuma vai izmaiลu pieprasฤซjuma iezฤซmes.
+issues.label_count=%d iezฤซmes
+issues.label_open_issues=%d atvฤrti pieteikumi/izmaiลu pieprasฤซjumi
issues.label_edit=Labot
-issues.label_delete=Dzฤst
-issues.label_modify=Labot etiฤทeti
-issues.label_deletion=Dzฤst etiฤทeti
-issues.label_deletion_desc=Dzฤลกot etiฤทeti, tฤ tiks noลemta no visฤm problฤmฤm un izmaiลu pieprasฤซjumiem. Vai turpinฤt?
-issues.label_deletion_success=Etiฤทete tika izdzฤsta.
+issues.label_delete=Izdzฤst
+issues.label_modify=Labot iezฤซmi
+issues.label_deletion=Izdzฤst iezฤซmi
+issues.label_deletion_desc=Iezฤซmes izdzฤลกana noลems to no visiem pieteikumiem. Turpinฤt?
+issues.label_deletion_success=Iezฤซme tika izdzฤsta.
issues.label.filter_sort.alphabetically=Alfabฤtiski
issues.label.filter_sort.reverse_alphabetically=Pretฤji alfabฤtiski
issues.label.filter_sort.by_size=Mazฤkais izmฤrs
issues.label.filter_sort.reverse_by_size=Lielฤkais izmฤrs
issues.num_participants_few=%d dalฤซbnieki
-issues.attachment.open_tab=`Noklikลกฤทiniet, lai apskatฤซtos "%s" jaunฤ logฤ`
-issues.attachment.download=`Noklikลกฤทiniet, lai lejupielฤdฤtu "%s"`
+issues.attachment.open_tab=`Klikลกฤทinฤt, lai apskatฤซtu "%s" jaunฤ cilnฤ`
+issues.attachment.download=`Klikลกฤทinฤt, lai lejupielฤdฤtu "%s"`
issues.subscribe=Abonฤt
issues.unsubscribe=Atrakstฤซties
-issues.unpin_issue=Atspraust problฤmu
-issues.max_pinned=Nevar piespraust vairฤk problฤmas
+issues.unpin_issue=Atspraust pieteikumu
+issues.max_pinned=Nevar piespraust vairฤk pieteikumu
issues.pin_comment=piesprauda ลกo %s
issues.unpin_comment=atsprauda ลกo %s
-issues.lock=Slฤgt komentฤลกanu
-issues.unlock=Atฤผaut komentฤลกanu
-issues.lock.unknown_reason=Neizdevฤs slฤgt problฤmas komentฤลกanu.
-issues.lock_duplicate=Problฤmas komentฤลกanu nevar slฤgt vairฤkas reizes.
-issues.unlock_error=Nevar atฤผaut komentฤลกanu, ja problฤmai tฤ nav slฤgta.
-issues.lock_with_reason=slฤdza ar iemeslu %s un ierobeลพoja komentฤru pievienoลกanu tikai lฤซdzstrฤdniekiem %s
-issues.lock_no_reason=slฤdza un ierobeลพoja komentฤru pievienoลกanu tikai lฤซdzstrฤdniekiem %s
-issues.unlock_comment=atฤผฤva komentฤลกanu %s
+issues.lock=Slฤgt apsprieลกanu
+issues.unlock=Atslฤgt apsprieลกanu
+issues.lock.unknown_reason=Nevar aizslฤgt pieteikumu ar nezinฤmu iemeslu.
+issues.lock_duplicate=Pieteikumu nevar aizslฤgt divreiz.
+issues.unlock_error=Nevar atslฤgt pieteikumu, kas nav aizslฤgts.
+issues.lock_with_reason=aizslฤdza kฤ %s un padarฤซja sarunu pieejamu tikai lฤซdzdalฤซbniekiem %s
+issues.lock_no_reason=aizslฤdza apsprieลกanu un padarฤซja to pieejamu tikai lฤซdzdalฤซbniekiem %s
+issues.unlock_comment=atslฤdza ลกo apsprieลกanu %s
issues.lock_confirm=Slฤgt
-issues.unlock_confirm=Atฤผaut
-issues.lock.notice_1=- Citi lietotฤji nevar pievienot jaunus komentฤrus ลกai problฤmai.
-issues.lock.notice_2=- Jums un citiem lฤซdzstrฤdniekiem ar piekฤผuvi ลกim repozitorijam tiks saglabฤta iespฤja pievienot komentฤrus.
-issues.lock.notice_3=- Jลซs vienmฤr varat atkal atฤผaut komentฤลกanu.
-issues.unlock.notice_1=- Ikviens varฤs atkal pievienot jaunus komentฤrus.
-issues.unlock.notice_2=- Jลซs vienmฤr varat atkal slฤgt komentฤลกanu.
+issues.unlock_confirm=Atslฤgt
+issues.lock.notice_1=- Citi lietotฤji ลกim pieteikumam nevar pievienot jaunas piebildes.
+issues.lock.notice_2=- Tu un citi lฤซdzdalฤซbnieki ar piekฤผuvi ลกai glabฤtavai joprojฤm var pievienot citiem redzamas piebildes.
+issues.lock.notice_3=- ล o pieteikumu vienmฤr bลซs iespฤja atkal atslฤgt.
+issues.unlock.notice_1=- Ikviens atkal varฤs pievienot jaunas piebildes.
+issues.unlock.notice_2=- ล o pieteikumu vienmฤr bลซs iespฤjams atkal aizslฤgt.
issues.lock.reason=Slฤgลกanas iemesls
-issues.lock.title=Slฤgt komentฤลกanu ลกai problฤmai.
-issues.unlock.title=Atฤผaut komentฤลกanu ลกai problฤmai.
-issues.comment_on_locked=Jลซs nevarat komentฤt slฤgtai problฤmai.
-issues.delete=Dzฤst
-issues.delete.title=Dzฤst ลกo problฤmu?
-issues.delete.text=Vai patieลกฤm vฤlaties dzฤst ลกo problemu? (Neatgriezeniski tiks izdzฤsts viss saturs. Apsveriet iespฤju to aizvฤrt, ja vฤlaties informฤciju saglabฤt vฤsturei)
+issues.lock.title=Slฤgt ลกฤซ pieteikuma sarunu.
+issues.unlock.title=Atslฤgt ลกฤซ pieteikuma apsprieลกanu.
+issues.comment_on_locked=Nevar pievienot piebildi aizslฤgtam pieteikumam.
+issues.delete=Izdzฤst
+issues.delete.title=Izdzฤst ลกo pieteikumu?
+issues.delete.text=Vai tieลกฤm izdzฤst ลกo pieteikumu? (Tas neatgriezeniski noลems visu saturu. Tฤ vietฤ vฤlams apsvฤrt aizvฤrลกanu, ja ir paredzฤts paturฤt to arhivฤtu)
issues.tracker=Laika uzskaite
-issues.start_tracking_short=Uzsฤkt taimeri
+issues.start_tracking_short=Uzsฤkt laika uzskaitฤซลกanu
issues.start_tracking=Uzsฤkt laika uzskaiti
issues.start_tracking_history=` uzsฤka darbu %s`
-issues.tracker_auto_close=Taimeris tiks automฤtiski apturฤts, kad ลกฤซ problฤma tiks aizvฤrta
-issues.tracking_already_started=`Jau ir uzsฤkta laika uzskaite par citu problฤmu !`
-issues.stop_tracking=Apturฤt taimeri
+issues.tracker_auto_close=Laika uzskaite tiks automฤtiski apturฤta, kad ลกis pieteikums tiks aizvฤrts
+issues.tracking_already_started=`Laika uzskaitฤซลกana jau ir uzsฤkta citฤ pieteikumฤ !`
+issues.stop_tracking=Apturฤt laika uzskaitฤซลกanu
issues.stop_tracking_history=` beidza strฤdฤt %s`
issues.cancel_tracking=Atmest
-issues.cancel_tracking_history=`atcฤla laika uzskaiti %s`
-issues.add_time=Manuฤli pievienot laiku
-issues.del_time=Dzฤst ลกo laika ลพurnฤla ierakstu
+issues.cancel_tracking_history=`atcฤla laika uzskaitฤซลกanu %s`
+issues.add_time=Paลกrocฤซgi pievienot laiku
+issues.del_time=Izdzฤst ลกo laika ลพurnฤla ierakstu
issues.add_time_short=Pievienot laiku
issues.add_time_cancel=Atcelt
issues.add_time_history=` pievienoja patฤrฤto laiku %s`
-issues.del_time_history=`dzฤsts patฤrฤtais laiks %s`
+issues.del_time_history=`izdzฤsa patฤrฤto laiku %s`
issues.add_time_hours=Stundas
issues.add_time_minutes=Minลซtes
issues.add_time_sum_to_small=Nav norฤdฤซts laiks.
issues.time_spent_total=Kopฤjais patฤrฤtais laiks
issues.time_spent_from_all_authors=`Kopฤjais patฤrฤtais laiks: %s`
-issues.due_date=Izpildes termiลลก
+issues.due_date=Izpildes datums
issues.invalid_due_date_format=Izpildes termiลam ir jฤbลซt formฤta 'yyyy-mm-dd'.
issues.error_modifying_due_date=Neizdevฤs izmainฤซt izpildes termiลu.
issues.error_removing_due_date=Neizdevฤs noลemt izpildes termiลu.
-issues.push_commit_1=iesลซtฤซja %d revฤซziju %s
-issues.push_commits_n=iesลซtฤซja %d revฤซzijas %s
-issues.force_push_codes=`veica piespiedu izmaiลu iesลซtฤซลกanu atzarฤ %[1]s no revฤซzijas %[2]s
uz %[4]s
%[6]s`
+issues.push_commit_1=pievienoja %d iesลซtฤซjumu %s
+issues.push_commits_n=pievienoja %d iesลซtฤซjumus %s
+issues.force_push_codes=`veica uzspiestu aizgฤdฤลกanu zarฤ %[1]s no %[2]s
uz %[4]s
%[6]s`
issues.force_push_compare=Salฤซdzinฤt
-issues.due_date_form=dd.mm.yyyy
+issues.due_date_form=dd.mm.gggg.
issues.due_date_form_add=Pievienot izpildes termiลu
issues.due_date_form_edit=Labot
issues.due_date_form_remove=Noลemt
issues.due_date_not_writer=Ir nepiecieลกama rakstฤซลกanas piekฤผuve ลกim repozitorijam, lai varฤtu mainฤซt problฤmas plฤnoto izpildes datumu.
-issues.due_date_not_set=Izpildes termiลลก nav uzstฤdฤซts.
-issues.due_date_added=pievienoja izpildes termiลu %s %s
-issues.due_date_modified=mainฤซja termiลa datumu no %[2]s uz %[1]s %[3]s
-issues.due_date_remove=noลฤma izpildes termiลu %s %s
+issues.due_date_not_set=Nav uzstฤdฤซts izpildes datums.
+issues.due_date_added=pievienoja izpildes datumu %s %s
+issues.due_date_modified=mainฤซja izpildes datumu no %[2]s uz %[1]s %[3]s
+issues.due_date_remove=noลฤma izpildes datumu %s %s
issues.due_date_overdue=Nokavฤts
-issues.due_date_invalid=Datums lฤซdz nav korekts. Izmantojiet formฤtu 'gggg-mm-dd'.
+issues.due_date_invalid=Izpildes datums nav derฤซgs vai tas ir ฤrpus datumu apgabala. Lลซgums izmantot pierakstu "gggg-mm-dd".
issues.dependency.title=Atkarฤซbas
issues.dependency.issue_no_dependencies=Nav atkarฤซbu.
issues.dependency.pr_no_dependencies=Nav atkarฤซbu.
-issues.dependency.no_permission_1=Nav tiesฤซbu nolasฤซt %d atkarฤซbu
-issues.dependency.no_permission_n=Nav tiesฤซbu nolasฤซt %d atkarฤซbas
-issues.dependency.no_permission.can_remove=Nav tiesฤซbu nolasฤซt ลกo atkarฤซbu, bet iespฤjams to noลemt
+issues.dependency.no_permission_1=Nav tiesฤซbu lasฤซt %d atkarฤซbu
+issues.dependency.no_permission_n=Nav tiesฤซbu lasฤซt %d atkarฤซbas
+issues.dependency.no_permission.can_remove=Nav tiesฤซbu lasฤซt ลกo atkarฤซbu, bet ir iespฤjams to noลemt
issues.dependency.add=Pievienot atkarฤซbuโฆ
issues.dependency.cancel=Atcelt
issues.dependency.remove=Noลemt
issues.dependency.remove_info=Noลemt ลกo atkarฤซbu
issues.dependency.added_dependency=`pievienoja jaunu atkarฤซbu %s`
issues.dependency.removed_dependency=`noลema atkarฤซbu %s`
-issues.dependency.pr_closing_blockedby=ล ฤซ izmaiลu pieprasฤซjuma sapludinฤลกanu bloฤทฤ sekojoลกas problฤmas
-issues.dependency.issue_closing_blockedby=ล ฤซs problฤmas aizvฤrลกanu bloฤทฤ sekojoลกas problฤmas
-issues.dependency.issue_close_blocks=ล ฤซ problฤma bloฤทฤ sekojoลกu problฤmu aizvฤrลกanu
-issues.dependency.pr_close_blocks=ล is izmaiลu pieprasฤซjums bloฤทฤ sekojoลกu problฤmu aizvฤrลกanu
-issues.dependency.issue_close_blocked=Nepiecieลกams aizvฤrt visas problฤmas, kas bloฤทฤ ลกo problฤmu, lai to varฤtu aizฤrt.
-issues.dependency.issue_batch_close_blocked=Nav iespฤjams aizvฤrt vairฤkas atzฤซmฤtฤs problฤmas, jo problฤmai #%d ir atvฤrtas atkarฤซbas
-issues.dependency.pr_close_blocked=Nepiecieลกams aizvฤrt visas problฤmas, kas bloฤทฤ ลกo izmaiลu pieprasฤซjumu, lai to varฤtu sapludinฤt.
-issues.dependency.blocks_short=Bloฤทฤ
+issues.dependency.pr_closing_blockedby=Zemฤk esoลกie pieteikumi liedz ลกฤซ izmaiลu pieprasฤซjuma aizvฤrลกanu
+issues.dependency.issue_closing_blockedby=Zemฤk esoลกie pieteikumi liedz ลกฤซ pieteikuma aizvฤrลกanu
+issues.dependency.issue_close_blocks=ล is pieteikums liedz zemฤk esoลกo pieteikumu aizvฤrลกanu
+issues.dependency.pr_close_blocks=ล is izmaiลu pieprasฤซjums liedz zemฤk esoลกo pieteikumu aizvฤrลกanu
+issues.dependency.issue_close_blocked=Nepiecieลกams aizvฤrt visus pieteikumus, kas aiztur ลกo pieteikumu, lai to varฤtu aizvฤrt.
+issues.dependency.issue_batch_close_blocked=Nav iespฤjama vairฤku izvฤlฤto pieteikumu aizvฤrลกana, jo pieteikumam #%d joprojฤm ir atvฤrtas atkarฤซbas
+issues.dependency.pr_close_blocked=Nepiecieลกams aizvฤrt visus pieteikumus, kas aiztur ลกo izmaiลu pieprasฤซjumu, lai to varฤtu iekฤผaut.
+issues.dependency.blocks_short=Aiztur
issues.dependency.blocked_by_short=Atkarฤซgs no
issues.dependency.remove_header=Noลemt atkarฤซbu
-issues.dependency.issue_remove_text=ล ฤซ darbฤซba noลems atkarฤซbu no ลกฤซs problฤmas. Turpinฤt?
+issues.dependency.issue_remove_text=Tas noลems atkarฤซbu no ลกฤซ pieteikuma. Turpinฤt?
issues.dependency.pr_remove_text=ล ฤซ darbฤซba noลems atkarฤซbu no ลกฤซ izmaiลu pieprasฤซjuma. Turpinฤt?
-issues.dependency.setting=Iespฤjot atkarฤซbas problฤmฤm un izmaiลu pieprasฤซjumiem
-issues.dependency.add_error_same_issue=Nevar izveidot atkarฤซbu uz paลกu problฤmu.
-issues.dependency.add_error_dep_issue_not_exist=Atkarฤซgฤ problฤma neeksistฤ.
-issues.dependency.add_error_dep_not_exist=Atkarฤซba neeksistฤ.
+issues.dependency.setting=Iespฤjot pieteikumu un izmaiลu pieprasฤซjumu atkarฤซbas
+issues.dependency.add_error_same_issue=Pieteikumu nevar padarฤซt atkarฤซgu paลกu no sevis.
+issues.dependency.add_error_dep_issue_not_exist=Atkarฤซgais pieteikums nepastฤv.
+issues.dependency.add_error_dep_not_exist=Atkarฤซba nepastฤv.
issues.dependency.add_error_dep_exists=Atkarฤซba jau ir pievienota.
-issues.dependency.add_error_cannot_create_circular=Nav iespฤjams veidot atkarฤซbu, kur divas problฤmas bloฤทฤtu viena otru.
-issues.dependency.add_error_dep_not_same_repo=Abฤm problฤmฤm ir jฤbลซt no viena repozitorija.
-issues.review.self.approval=Nevar apstiprinฤt savu izmaiลu pieprasฤซjumi.
+issues.dependency.add_error_cannot_create_circular=Nevar izveidot atkarฤซbu ar diviem vienam otru aizturoลกiem pieteikumiem.
+issues.dependency.add_error_dep_not_same_repo=Abiem pieteikumiem jฤbลซt vienฤ un tajฤ paลกฤ glabฤtavฤ.
+issues.review.self.approval=Nevar apstiprinฤt savu izmaiลu pieprasฤซjumu.
issues.review.self.rejection=Nevar pieprasฤซt izmaiลas savam izmaiลu pieprasฤซjumam.
-issues.review.approve=apstiprinฤja izmaiลas %s
-issues.review.comment=recenzฤja %s
-issues.review.dismissed=atmeta %s recenziju %s
+issues.review.approve=apstiprinฤja ลกฤซs izmaiลas %s
+issues.review.comment=izskatฤซja %s
+issues.review.dismissed=atmeta %s izskatฤซลกanu %s
issues.review.dismissed_label=Atmesta
-issues.review.left_comment=atstฤja komentฤru
-issues.review.content.empty=Nepiecieลกams norฤdฤซt komentฤru par prasฤซtajฤm izmaiลฤm.
-issues.review.reject=pieprasฤซja izmaiลas %s
-issues.review.wait=tika pieprasฤซta recenzija %s
-issues.review.add_review_request=pieprasฤซja recenziju no %s %s
-issues.review.remove_review_request=noลema recenzijas pieprasฤซjumu no %s %s
-issues.review.remove_review_request_self=atteicฤs recenzฤt %s
+issues.review.left_comment=pievienoja piebildi
+issues.review.content.empty=Ir nepiecieลกams pievienot piebildi par pieprasฤซto(ajฤm) izmaiลu(ฤm).
+issues.review.reject=pieprasฤซja labojumus %s
+issues.review.wait=tika pieprasฤซts izskatฤซt %s
+issues.review.add_review_request=pieprasฤซja izskatฤซลกanu no %[1]s %[2]s
+issues.review.remove_review_request=noลฤma izskatฤซลกanas pieprasฤซjumu %[1]s %[2]s
+issues.review.remove_review_request_self=atteicฤs izskatฤซt %s
issues.review.pending=Nav iesลซtฤซts
-issues.review.pending.tooltip=ล is komentฤrs nav redzams citiem lietotฤjiem. Lai padarฤซtu neiesลซtฤซtos komentฤrus pieejamus citiem, nospiediet "%s" -> "%s/%s/%s" lapas augลกpusฤ.
-issues.review.review=Recenzija
-issues.review.reviewers=Recenzenti
-issues.review.outdated=Novecojis
-issues.review.outdated_description=Saturs ir mainฤซjies kopลก ลกฤซ komentฤra pievienoลกanas
-issues.review.option.show_outdated_comments=Rฤdฤซt novecojuลกus komentฤrus
-issues.review.option.hide_outdated_comments=Paslฤpt novecojuลกus komentฤrus
+issues.review.pending.tooltip=ล ฤซ piebilde pagaidฤm nav redzama citiem lietotฤjiem. Lai iesniegtu savas ierindotฤs piebildes, lapas augลกdaฤผฤ jฤatlasa "%s" -> "%s/%s/%s".
+issues.review.review=Izskatฤซลกana
+issues.review.reviewers=Izskatฤซtฤji
+issues.review.outdated=Novecojusi
+issues.review.outdated_description=Pฤc ลกฤซs piebildes pievienoลกanas ir mainฤซjies saturs
+issues.review.option.show_outdated_comments=Rฤdฤซt novecojuลกas piebildes
+issues.review.option.hide_outdated_comments=Paslฤpt novecojuลกas piebildes
issues.review.show_outdated=Rฤdฤซt novecojuลกu
issues.review.hide_outdated=Paslฤpt novecojuลกu
issues.review.show_resolved=Rฤdฤซt atrisinฤto
issues.review.hide_resolved=Paslฤpt atrisinฤto
issues.review.resolve_conversation=Atrisinฤt sarunu
issues.review.un_resolve_conversation=Atcelt sarunas atrisinฤjumu
-issues.review.resolved_by=atzฤซmฤja sarunu kฤ atrisinฤtu
+issues.review.resolved_by=atzฤซmฤja ลกo sarunu kฤ atrisinฤtu
issues.assignee.error=Ne visi atbildฤซgie tika pievienoti, jo radฤs neparedzฤta kฤผลซda.
issues.reference_issue.body=Saturs
-issues.content_history.deleted=dzฤsts
-issues.content_history.edited=rediฤฃฤts
+issues.content_history.deleted=izdzฤsts
+issues.content_history.edited=labots
issues.content_history.created=izveidots
-issues.content_history.delete_from_history=Dzฤst no vฤstures
-issues.content_history.delete_from_history_confirm=Vai dzฤst no vฤstures?
+issues.content_history.delete_from_history=Izdzฤst no vฤstures
+issues.content_history.delete_from_history_confirm=Izdzฤst no vฤstures?
issues.content_history.options=Iespฤjas
-issues.reference_link=Atsaucas uz: %s
+issues.reference_link=Atsauce: %s
compare.compare_base=pamata
compare.compare_head=salฤซdzinฤt
-pulls.desc=Iespฤjot izmaiลu pieprasฤซjumus un koda recenzฤลกanu.
+pulls.desc=Iespฤjot izmaiลu pieprasฤซjumus un koda izskatฤซลกanu.
pulls.new=Jauns izmaiลu pieprasฤซjums
-pulls.view=Skatฤซties izmaiลu pieprasฤซjumu
+pulls.view=Apskatฤซt izmaiลu pieprasฤซjumu
pulls.compare_changes=Jauns izmaiลu pieprasฤซjums
pulls.allow_edits_from_maintainers=Atฤผaut labojumus no uzturฤtฤjiem
-pulls.allow_edits_from_maintainers_desc=Lietotฤji ar rakstฤซลกanas tiesฤซbฤm bฤzes atzarฤ, drฤซkst iesลซtฤซt izmaiลas ลกajฤ atzarฤ
-pulls.allow_edits_from_maintainers_err=Atjaunoลกana neizdevฤs
-pulls.compare_changes_desc=Izvฤlieties atzaru, kurฤ sapludinฤt izmaiลas un atzaru, no kura tฤs saลemt.
-pulls.has_viewed_file=Skatฤซts
-pulls.has_changed_since_last_review=Mainฤซts kopลก pฤdฤjฤs recenzijas
-pulls.viewed_files_label=%[1]d no %[2]d failiem apskatฤซts
-pulls.expand_files=Izvฤrst visus failus
-pulls.collapse_files=Savฤrst visus failus
+pulls.allow_edits_from_maintainers_desc=Lietotฤji ar rakstฤซลกanas piekฤผuvi pamata zaram var aizgฤdฤt izmaiลas arฤซ ลกajฤ zarฤ
+pulls.allow_edits_from_maintainers_err=Atjauninฤลกana neizdevฤs
+pulls.compare_changes_desc=Jฤatlasa zars, kurฤ iekฤผaut izmaiลas, un zars, no kura tฤs atgฤdฤt.
+pulls.has_viewed_file=Apskatฤซta
+pulls.has_changed_since_last_review=Izmainฤซts kopลก pฤdฤjฤs izskatฤซลกanas
+pulls.viewed_files_label=apskatฤซtas %[1]d no %[2]d datnฤm
+pulls.expand_files=Izvฤrst visas datnes
+pulls.collapse_files=Savฤrst visas datnes
pulls.compare_base=pamata
-pulls.compare_compare=salฤซdzinฤmais
-pulls.switch_comparison_type=Mainฤซt salฤซdzinฤลกanas tipu
-pulls.switch_head_and_base=Mainฤซt galvas un pamata atzarus
-pulls.filter_branch=Filtrฤt atzarus
+pulls.compare_compare=atgฤdฤt no
+pulls.switch_comparison_type=Pฤrslฤgt salฤซdzinฤลกanas veidu
+pulls.switch_head_and_base=Apmainฤซt galotnes un pamata zarus
+pulls.filter_branch=Atlasฤซt zarus
pulls.no_results=Nekas netika atrasts.
-pulls.show_all_commits=Rฤdฤซt visas revฤซzijas
-pulls.show_changes_since_your_last_review=Rฤdฤซt izmaiลas kopลก Tavas pฤdฤjฤs recenzijas
-pulls.showing_only_single_commit=Rฤda tikai revฤซzijas %[1]s izmaiลas
-pulls.showing_specified_commit_range=Rฤda tikai izmaiลas starp %[1]s..%[2]s
-pulls.select_commit_hold_shift_for_range=Atlasฤซt revฤซziju. Jฤtur Shift + klikลกฤทis, lai atlasฤซtu vairฤkas
-pulls.review_only_possible_for_full_diff=Recenzฤลกana ir iespฤjama tikai tad, kad tiek apskatฤซts pilns salฤซdzinฤjums
-pulls.filter_changes_by_commit=Atlasฤซt pฤc revฤซzijas
-pulls.nothing_to_compare=Nav ko salฤซdzinฤt, jo bฤzes un salฤซdzinฤmie atzari ir vienฤdi.
-pulls.nothing_to_compare_and_allow_empty_pr=ล ie atzari ir vienฤdi. Izveidotais izmaiลu pieprasฤซjums bลซs tukลกs.
-pulls.has_pull_request=`Izmaiลu pieprasฤซjums starp ลกiem atzariem jau eksistฤ: %[2]s#%[3]d `
+pulls.show_all_commits=Rฤdฤซt visus iesลซtฤซjumus
+pulls.show_changes_since_your_last_review=Rฤdฤซt izmaiลas kopลก Tavas pฤdฤjฤs izskatฤซลกanas
+pulls.showing_only_single_commit=Rฤda tikai iesลซtฤซjuma %[1]s izmaiลas
+pulls.showing_specified_commit_range=Rฤda izmaiลas tikai starp %[1]s..%[2]s
+pulls.select_commit_hold_shift_for_range=Atlasฤซt iesลซtฤซjumu. Jฤtur Shift + klikลกฤทis, lai atlasฤซtu vairฤkus
+pulls.review_only_possible_for_full_diff=Izskatฤซลกana ir iespฤjama tikai tad, kad tiek apskatฤซts pilns salฤซdzinฤjums
+pulls.filter_changes_by_commit=Atlasฤซt pฤc iesลซtฤซjuma
+pulls.nothing_to_compare=ล ie zari ir vienฤdi. Nav nepiecieลกams izveidot izmaiลu pieprasฤซjumu.
+pulls.nothing_to_compare_and_allow_empty_pr=ล ie zari ir vienฤdi. ล is izmaiลu pieprasฤซjums bลซs tukลกs.
+pulls.has_pull_request=`Jau pastฤv izmaiลu pieprasฤซjums starp ลกiem zariem: %[2]s#%[3]d `
pulls.create=Izveidot izmaiลu pieprasฤซjumu
-pulls.title_desc_few=vฤlas sapludinฤt %[1]d revฤซzijas no %[2]s
uz %[3]s
-pulls.merged_title_desc_few=sapludinฤja %[1]d revฤซzijas no %[2]s
uz %[3]s
%[4]s
-pulls.change_target_branch_at=`nomainฤซja mฤrฤทa atzaru no %s uz %s %s`
+pulls.title_desc_few=vฤlas iekฤผaut %[1]d iesลซtฤซjumus no %[2]s
zarฤ %[3]s
+pulls.merged_title_desc_few=Iekฤผฤva %[1]d iesลซtฤซjumus no %[2]s
zarฤ %[3]s
%[4]s
+pulls.change_target_branch_at=`nomainฤซja mฤrฤทa zaru no %s uz %s %s`
pulls.tab_conversation=Saruna
-pulls.tab_commits=Revฤซzijas
-pulls.tab_files=Izmainฤซtie faili
-pulls.reopen_to_merge=Atkฤrtoti atveriet izmaiลu pieprasฤซjumu, lai veiktu sapludinฤลกanu.
-pulls.cant_reopen_deleted_branch=ล o izmaiลu pieprasฤซju nevar atkฤroti atvฤrt, jo atzars ir izdzฤsts.
-pulls.merged=Sapludinฤts
-pulls.merged_success=Izmaiลu pieprasฤซjums vieksmฤซgi sapludinฤts un aizvฤrts
+pulls.tab_commits=Iesลซtฤซjumi
+pulls.tab_files=Izmainฤซtฤs datnes
+pulls.reopen_to_merge=Lลซgums atkฤrtoti atvฤrt ลกo izmaiลu pieprasฤซjumu, lai veiktu apvienoลกanu.
+pulls.cant_reopen_deleted_branch=ล o izmaiลu pieprasฤซjumu nevar atkฤrtoti atvฤrt, jo zars ir izdzฤsts.
+pulls.merged=Apvienots
+pulls.merged_success=Izmaiลu pieprasฤซjums sekmฤซgi iekฤผauts un aizvฤrts
pulls.closed=Izmaiลu pieprasฤซjums aizvฤrts
-pulls.manually_merged=Manuฤli sapludinฤts
-pulls.merged_info_text=Atzaru %s tagad var dzฤst.
+pulls.manually_merged=Paลกrocฤซgi apvienots
+pulls.merged_info_text=Zaru %s tagad var izdzฤst.
pulls.is_closed=Izmaiลu pieprasฤซjums tika aizvฤrts.
-pulls.title_wip_desc=`Sฤciet virsrakstu ar %s , lai ierobeลพotu, ka izmaiลu pieprasฤซjums netฤซลกฤm tiktu sapludinฤts.`
-pulls.cannot_merge_work_in_progress=ล is izmaiลu pieprasฤซjums ir atzฤซmฤts, ka pie tฤ vฤl notiek izstrฤde.
+pulls.title_wip_desc=`Sฤkt virsrakstu ar %s , lai novฤrstu izmaiลu pieprasฤซjuma nejauลกu iekฤผauลกanu.`
+pulls.cannot_merge_work_in_progress=ล is izmaiลu pieprasฤซjums ir atzฤซmฤts kฤ nepabeigts darbs.
pulls.still_in_progress=Joprojฤm notiek izstrฤde?
-pulls.add_prefix=Pievienot %s prefiksu
-pulls.remove_prefix=Noลemt %s prefiksu
-pulls.data_broken=Izmaiลu pieprasฤซjums ir bojฤts, jo dzฤsta informฤcija no atdalฤซtฤ repozitorija.
-pulls.files_conflicted=ล ฤซs izmaiลu pieprasฤซjuma izmaiลas konfliktฤ ar mฤrฤทa atzaru.
-pulls.is_checking=Notiek konfliktu pฤrbaude, mirkli uzgaidiet un atjaunojiet lapu.
-pulls.is_ancestor=Atzars jau ir pilnฤซbฤ iekฤผauts mฤrฤทฤ atzarฤ. Nav izmaiลu, ko sapludinฤt.
-pulls.is_empty=Mฤrฤทa atzars jau satur ลกฤซ atzara izmaiลas. ล ฤซ revฤซzija bลซs tukลกa.
-pulls.required_status_check_failed=Daลพas no pฤrbaudฤm nebija veiksmฤซgas.
-pulls.required_status_check_missing=Trลซkst daลพu obligฤto pฤrbauลพu.
-pulls.required_status_check_administrator=Kฤ administrators Jลซs varat sapludinฤt ลกo izmaiลu pieprasฤซjumu.
+pulls.add_prefix=Pievienot sฤkuma virkni %s
+pulls.remove_prefix=Noลemt sฤkuma virkni %s
+pulls.data_broken=ล is izmaiลu pieprasฤซjums ir bojฤts trลซkstoลกas atzarojuma informฤcijas dฤฤผ.
+pulls.files_conflicted=ล ฤซ izmaiลu pieprasฤซjuma izmaiลas nav saderฤซgas ar mฤrฤทa zaru.
+pulls.is_checking=Notiek apvienoลกanas nesaderฤซbu pฤrbaude. Pฤc brฤซลพa jฤmฤฤฃina vฤlreiz.
+pulls.is_ancestor=Zars jau ir pilnฤซbฤ iekฤผauts mฤrฤทa zarฤ. Nav izmaiลu, ko apvienot.
+pulls.is_empty=ล ฤซ zara izmaiลas jau ir mฤrฤทa zarฤ. ล is bลซs tukลกs iesลซtฤซjums.
+pulls.required_status_check_failed=Daลพas no nepiecieลกamajฤm pฤrbaudฤm bija nesekmฤซgas.
+pulls.required_status_check_missing=Trลซkst daลพu nepiecieลกamo pฤrbauลพu.
+pulls.required_status_check_administrator=Kฤ pฤrvaldฤซtฤjs joprojฤm vari iekฤผaut ลกo izmaiลu pieprasฤซjumu.
pulls.blocked_by_approvals=ล im izmaiลu pieprasฤซjumam vฤl nav pietiekami daudz apstiprinฤjumu. Nodroลกinฤti %d no %d apstiprinฤjumiem.
-pulls.blocked_by_rejection=ล im izmaiลu pieprasฤซjumam oficiฤlais recenzents ir pieprasฤซjis labojumus.
-pulls.blocked_by_official_review_requests=ล im izmaiลu pieprasฤซjumam ir oficiฤli recenzijas pieprasฤซjumi.
-pulls.blocked_by_outdated_branch=ล is izmaiลu pieprasฤซjums ir bloฤทฤts, jo tas ir novecojis.
-pulls.blocked_by_changed_protected_files_1=ล is izmaiลu pieprasฤซjums ir bloฤทฤts, jo tas izmaina aizsargฤto failu:
-pulls.blocked_by_changed_protected_files_n=ล is izmaiลu pieprasฤซjums ir bloฤทฤts, jo tas izmaina aizsargฤtos failus:
-pulls.can_auto_merge_desc=ล o izmaiลu pieprasฤซjumu var automฤtiski sapludinฤt.
-pulls.cannot_auto_merge_desc=ล is izmaiลu pieprasฤซjums nevar tikt automฤtiski sapludinฤts konfliktu dฤฤผ.
-pulls.cannot_auto_merge_helper=Sapludiniet manuฤli, lai atrisinฤtu konfliktus.
-pulls.num_conflicting_files_1=%d fails ar konfliktiem
-pulls.num_conflicting_files_n=%d faili ar konfliktiem
+pulls.blocked_by_rejection=ล im izmaiลu pieprasฤซjumam oficiฤlais izskatฤซtฤjs ir pieprasฤซjis labojumus.
+pulls.blocked_by_official_review_requests=ล is izmaiลu pieprasฤซjums ir aizturฤts, jo tam trลซkst apstiprinฤjuma no viena vai vairฤkiem oficiฤlajiem izskatฤซtฤjiem.
+pulls.blocked_by_outdated_branch=ล is izmaiลu pieprasฤซjums ir aizturฤts, jo tas ir novecojis.
+pulls.blocked_by_changed_protected_files_1=ล is izmaiลu pieprasฤซjums ir aizturฤts, jo tas izmaina aizsargฤtu datni:
+pulls.blocked_by_changed_protected_files_n=ล is izmaiลu pieprasฤซjums ir aizturฤts, jo tas izmaina aizsargฤtas datnes:
+pulls.can_auto_merge_desc=ล o izmaiลu pieprasฤซjumu var automฤtiski iekฤผaut.
+pulls.cannot_auto_merge_desc=ล o izmaiลu pieprasฤซjumu nevar automฤtiski iekฤผaut nesaderฤซbu dฤฤผ.
+pulls.cannot_auto_merge_helper=Jฤapvieno paลกrocฤซgi, lai novฤrstu nesaderฤซbas.
+pulls.num_conflicting_files_1=%d nesaderฤซga datne
+pulls.num_conflicting_files_n=%d nesaderฤซgas datnes
pulls.approve_count_1=%d apstiprinฤjums
pulls.approve_count_n=%d apstiprinฤjumi
-pulls.reject_count_1=%d izmaiลu pieprasฤซjums
-pulls.reject_count_n=%d pieprasฤซtas izmaiลas
-pulls.waiting_count_1=nepiecieลกama %d recenzija
-pulls.waiting_count_n=nepiecieลกamas %d recenzijas
-pulls.wrong_commit_id=revฤซzijas identifikฤtoram ir jฤbลซt revฤซzijas identifikatoram no mฤrฤทa atzara
+pulls.reject_count_1=%d labojumu pieprasฤซjums
+pulls.reject_count_n=%d izmaiลu pieprasฤซjumi
+pulls.waiting_count_1=nepiecieลกama %d izskatฤซลกana
+pulls.waiting_count_n=nepiecieลกamas %d izskatฤซลกanas
+pulls.wrong_commit_id=iesลซtฤซjuma identifikatoram jฤbลซt iesลซtฤซjuma identifikatoram mฤrฤทa zarฤ
-pulls.no_merge_desc=ล o izmaiลu pieprasฤซjumu nav iespฤjams sapludinฤt, jo nav atฤผauts neviens sapludinฤลกanas veids.
-pulls.no_merge_helper=Lai sapludinฤtu ลกo izmaiลu pieprasฤซjumu, iespฤjojiet vismaz vienu sapludinฤลกanas veidu repozitorija iestatฤซjumos vai sapludiniet to manuฤli.
-pulls.no_merge_wip=ล o izmaiลu pieprasฤซjumu nav iespฤjams sapludinฤt, jo tas ir atzฤซmฤts, ka darbs pie tฤ vฤl nav pabeigts.
-pulls.no_merge_not_ready=Izmaiลu pieprasฤซjumu nav iespฤjams sapludinฤt, pฤrbaudiet recenziju statusu un statusa pฤrbaudes.
-pulls.no_merge_access=Jums nav tiesฤซbu sapludinฤt ลกo izmaiลu pieprasฤซjumu.
-pulls.merge_pull_request=Izveidot sapludinฤลกana revฤซziju
-pulls.rebase_merge_pull_request=Pฤrbฤzฤt un pฤrtฤซt uz priekลกu
-pulls.rebase_merge_commit_pull_request=Pฤrbฤzฤt un izveidot sapludinฤลกanas revฤซziju
-pulls.squash_merge_pull_request=Izveidot saspieลกanas revฤซziju
-pulls.merge_manually=Manuฤli sapludinฤts
-pulls.merge_commit_id=Sapludinฤลกanas revฤซzijas ID
-pulls.require_signed_wont_sign=Atzarฤ var iesลซtฤซt tikai parakstฤซtas revฤซzijas, bet sapludinฤลกanas revฤซzijas netiks parakstฤซta
+pulls.no_merge_desc=ล o izmaiลu pieprasฤซjumu nevar iekฤผaut, jo visas glabฤtavas apvienoลกanas iespฤjas ir atspฤjotas.
+pulls.no_merge_helper=Jฤiespฤjo apvienoลกanas iespฤjas glabฤtavas iestatฤซjumos vai arฤซ izmaiลu pieprasฤซjums jฤiekฤผauj paลกrocฤซgi.
+pulls.no_merge_wip=ล o izmaiลu pieprasฤซjumu nav iespฤjams iekฤผaut, jo tas ir atzฤซmฤts kฤ nepabeigts darbs.
+pulls.no_merge_not_ready=ล is izmaiลu pieprasฤซjums nav gatavs apvienoลกanai, jฤpฤrbauda izskatฤซลกanas stฤvoklis un stฤvokฤผa pฤrbaudes.
+pulls.no_merge_access=Nav pilnvaru, lai iekฤผautu ลกo izmaiลu pieprasฤซjumu.
+pulls.merge_pull_request=Izveidot apvienoลกanas iesลซtฤซjumu
+pulls.rebase_merge_pull_request=Pฤrbฤzฤt, tad pฤrlฤkt
+pulls.rebase_merge_commit_pull_request=Pฤrbฤzฤt, tad izveidot apvienoลกanas iesลซtฤซjumu
+pulls.squash_merge_pull_request=Izveidot saspieลกanas iesลซtฤซjumu
+pulls.merge_manually=Paลกrocฤซgi apvienots
+pulls.merge_commit_id=Iekฤผauลกanas iesลซtฤซjuma identifikators
+pulls.require_signed_wont_sign=Zarฤ ir atฤผauti tikai parakstฤซti iesลซtฤซjumi, bet ลกฤซ apvienoลกana netiks parakstฤซta
-pulls.invalid_merge_option=Nav iespฤjams izmantot ลกฤdu sapludinฤลกanas veidu ลกim izmaiลu pieprasฤซjumam.
-pulls.merge_conflict=Sapludinฤลกana neizdevฤs: Veicot sapludinฤลกanu, radฤs konflikts. Mฤฤฃiniet izmantot citu sapludinฤลกanas stratฤฤฃiju
-pulls.merge_conflict_summary=Kฤผลซdas paziลojums
-pulls.rebase_conflict=Sapludinฤลกana neizdevฤs: Veicot pฤrbฤzฤลกanu uz revฤซziju %[1]s, radฤs konflikts. Mฤฤฃiniet izmantot citu sapludinฤลกanas stratฤฤฃiju
-pulls.rebase_conflict_summary=Kฤผลซdas paziลojums
-pulls.unrelated_histories=Sapludinฤลกana neizdevฤs: mฤrฤทa un bฤzes atzariem nav kopฤjas vฤstures. Ieteikums: izvฤlieties citu sapludinฤลกanas stratฤฤฃiju
-pulls.merge_out_of_date=Sapludinฤลกana neizdevฤs: sapludinฤลกanas laikฤ, bฤzes atzarฤ tika iesลซtฤซtas izmaiลas. Ieteikums: mฤฤฃiniet atkฤrtoti.
-pulls.head_out_of_date=Sapludinฤลกana neizdevฤs: sapludinฤลกanas laikฤ, bฤzes atzarฤ tika iesลซtฤซtas izmaiลas. Ieteikums: mฤฤฃiniet atkฤrtoti.
-pulls.has_merged=Neizdevฤs: izmaiลu pieprasฤซjums jau ir sapludinฤts, nevar to darฤซt atkฤrtoti vai mainฤซt mฤrฤทa atzaru.
-pulls.push_rejected=Sapludinฤลกana neizdevฤs: iesลซtฤซลกana tika noraidฤซta. Pฤrbaudiet git ฤฤทus ลกim repozitorijam.
+pulls.invalid_merge_option=ล im izmaiลu pieprasฤซjumam nevar izmantot ลกo apvienoลกanas iespฤju.
+pulls.merge_conflict=Apvienoลกana neizdevฤs: iekฤผauลกanas laikฤ radฤs nesaderฤซbas. Norฤde: jฤmฤฤฃina cita pieeja
+pulls.merge_conflict_summary=Kฤผลซdas ziลojums
+pulls.rebase_conflict=Apvienoลกana neizdevฤs: iesลซtฤซjuma %[1]s pฤrbฤzฤลกanas laikฤ radฤs nesaderฤซba. Norฤde: jฤmฤฤฃina cita pieeja
+pulls.rebase_conflict_summary=Kฤผลซdas ziลojums
+pulls.unrelated_histories=Apvienoลกana neizdevฤs: apvienoลกanas galotnei un pamatam nav kopฤjas vฤstures. Norฤde: jฤmฤฤฃina cita pieeja
+pulls.merge_out_of_date=Apvienoลกana neizdevฤs: iekฤผauลกanas laikฤ pamata zars tika atjauninฤts. Norฤde: jฤmฤฤฃina vฤlreiz.
+pulls.head_out_of_date=Apvienoลกana neizdevฤs: iekฤผauลกanas laikฤ galotne tika atjauninฤta. Norฤde: jฤmฤฤฃina vฤlreiz.
+pulls.has_merged=Neizdevฤs: izmaiลu pieprasฤซjums tika iekฤผauts, to nevar darฤซt atkฤrtoti vai mainฤซt mฤrฤทa zaru.
+pulls.push_rejected=Aizgฤdฤลกana neizdevฤs: aizgฤdฤลกana tika noraidฤซta. Jฤpฤrskata ลกฤซs glabฤtavas Git aizฤทeres.
pulls.push_rejected_summary=Pilns noraidฤซลกanas ziลojums
-pulls.push_rejected_no_message=Sapludinฤลกana neizdevฤs: Izmaiลu iesลซtฤซลกana tika noraidฤซta, bet serveris neatgrieza paziลojumu. Pฤrbaudiet git ฤฤทus ลกim repozitorijam
-pulls.open_unmerged_pull_exists=`Jลซs nevarat veikt atkฤrtotas atvฤrลกanas darbฤซbu, jo jau eksistฤ izmaiลu pieprasฤซjums (#%d) ar ลกฤdu sapludinฤลกanas informฤciju.`
+pulls.push_rejected_no_message=Aizgฤdฤลกana neizdevฤs: aizgฤdฤลกana tika noraidฤซta, bet serveris neatgrieza ziลojumu. Jฤpฤrskata ลกฤซs glabฤtavas Git aizฤทeres
+pulls.open_unmerged_pull_exists=`Nevar veikt atkฤrtotu atvฤrลกanu, jo jau pastฤv neapstiprinฤts izmaiลu pieprasฤซjums (#%d) ar tieลกi tฤdฤm paลกฤm pazฤซmฤm.`
pulls.status_checking=Daลพas pฤrbaudes vฤl tiek veiktas
-pulls.status_checks_success=Visas pฤrbaudes ir veiksmฤซgas
-pulls.status_checks_warning=Daลพas pฤrbaudes ziลoja brฤซdinฤjumus
+pulls.status_checks_success=Visas pฤrbaudes bija sekmฤซgas
+pulls.status_checks_warning=Daลพas pฤrbaudes atgrieza brฤซdinฤjumus
pulls.status_checks_failure=Daลพas pฤrbaudes neizdevฤs izpildฤซt
-pulls.status_checks_error=Daลพu pฤrbauลพu izpildes laikฤ, radฤs kฤผลซdas
-pulls.status_checks_requested=Obligฤts
+pulls.status_checks_error=Daลพas pฤrbaudes atgrieza kฤผลซdas
+pulls.status_checks_requested=Nepiecieลกama
pulls.status_checks_details=Papildu informฤcija
pulls.status_checks_hide_all=Paslฤpt visas pฤrbaudes
pulls.status_checks_show_all=Parฤdฤซt visas pฤrbaudes
-pulls.update_branch=Atjaunot atzaru, izmantojot, sapludinฤลกanu
-pulls.update_branch_rebase=Atjaunot atzaru, izmantojot, pฤrbฤzฤลกanu
-pulls.update_branch_success=Atzara atjauninฤลกana veiksmฤซgi pabeigta
-pulls.update_not_allowed=Jums nav tiesฤซbu veikt atzara atjaunoลกanu
-pulls.outdated_with_base_branch=Atzars ir novecojis salฤซdzinot ar bฤzes atzaru
+pulls.update_branch=Atjauninฤt zaru ar apvienoลกanu
+pulls.update_branch_rebase=Atjauninฤt zaru ar pฤrbฤzฤลกanu
+pulls.update_branch_success=Zara atjauninฤลกana bija sekmฤซga
+pulls.update_not_allowed=Nav ฤผauts atjauninฤt zaru
+pulls.outdated_with_base_branch=ล is zars ir novecojis salฤซdzinฤjumฤ ar pamata zaru
pulls.close=Aizvฤrt izmaiลu pieprasฤซjumu
pulls.closed_at=`aizvฤra ลกo izmaiลu pieprasฤซjumu %[2]s `
pulls.reopened_at=`atkฤrtoti atvฤra ลกo izmaiลu pieprasฤซjumu %[2]s `
-pulls.cmd_instruction_hint=`Apskatฤซt komandrindas izmantoลกanas norฤdes .`
+pulls.cmd_instruction_hint=Apskatฤซt komandrindas izmantoลกanas norฤdes
pulls.cmd_instruction_checkout_title=Paลemt
-pulls.cmd_instruction_checkout_desc=Projekta repozitorijฤ jฤizveido jauns atzars un jฤpฤrbauda izmaiลas.
-pulls.cmd_instruction_merge_title=Sapludinฤt
-pulls.cmd_instruction_merge_desc=Sapludinฤt izmaiลas un atjaunot tฤs Gitea.
-pulls.clear_merge_message=Notฤซrฤซt sapludinฤลกanas ziลojumu
-pulls.clear_merge_message_hint=Notฤซrot sapludinฤลกanas ziลojumu tiks noลemts tikai pats ziลojums, bet tiks paturฤti ฤฃenerฤtie git ziลojumu, kฤ "Co-Authored-By โฆ".
+pulls.cmd_instruction_checkout_desc=Projekta glabฤtavฤ jฤizveido jauns zars un jฤpฤrbauda izmaiลas.
+pulls.cmd_instruction_merge_title=Apvienot
+pulls.cmd_instruction_merge_desc=Apvienot izmaiลas un atjauninฤt tฤs Forgejo.
+pulls.clear_merge_message=Notฤซrฤซt apvienoลกanas ziลojumu
+pulls.clear_merge_message_hint=Apvienoลกanas ziลojuma notฤซrฤซลกana noลems tikai iesลซtฤซjuma ziลojuma saturu un paturฤs izveidotos noslฤgumus, piemฤram, "Co-Authored-By โฆ".
-pulls.auto_merge_button_when_succeed=(Kad pฤrbaudes veiksmฤซgas)
-pulls.auto_merge_when_succeed=Automฤtiski sapludinฤt, kad visas pฤrbaudes veiksmฤซgas
-pulls.auto_merge_newly_scheduled=ล is izmaiลu pieprasฤซjums tika ieplฤnots automฤtiskajai sapludinฤลกanai, kas visas pฤrbaudes bลซs veiksmฤซgas.
-pulls.auto_merge_has_pending_schedule=%[1]s ieplฤnoja ลกฤซ izmaiลu pieprasฤซjuma automฤtisko sapludinฤลกanu, kad visas pฤrbaudes tiks pabeigtas %[2]s.
+pulls.auto_merge_button_when_succeed=(Kad pฤrbaudes sekmฤซgi izpildฤs)
+pulls.auto_merge_when_succeed=Automฤtiski apvienot, kad visas pฤrbaudes ir sekmฤซgi pabeigtas
+pulls.auto_merge_newly_scheduled=Izmaiลu pieprasฤซjums tika ieplฤnots apvienoลกanai, kad visas pฤrbaudes bลซs sekmฤซgi pabeigtas.
+pulls.auto_merge_has_pending_schedule=%[1]s ieplฤnoja ลกฤซ izmaiลu pieprasฤซjuma automฤtisku apvienoลกanu, kad visas pฤrbaudes tiks sekmฤซgi pabeigtas %[2]s.
-pulls.auto_merge_cancel_schedule=Atcelt automฤtisko sapludinฤลกanu
-pulls.auto_merge_not_scheduled=ล o izmaiลu pieprasฤซjumu nav ieplฤnots automฤtiski sapludinฤt.
-pulls.auto_merge_canceled_schedule=Automฤtiskฤ sapludinฤลกana ลกim izmaiลu pieprasฤซjumam tika atcelta.
+pulls.auto_merge_cancel_schedule=Atcelt automฤtisko apvienoลกanu
+pulls.auto_merge_not_scheduled=ล o izmaiลu pieprasฤซjumu nav ieplฤnots automฤtiski apvienot.
+pulls.auto_merge_canceled_schedule=ล ฤซ izmaiลu pieprasฤซjuma automฤtiskฤ apvienoลกana tika atcelta.
-pulls.auto_merge_newly_scheduled_comment=`ieplฤnoja automฤtisko sapludinฤลกanu ลกim izmaiลu pieprasฤซjumam, kad visas pฤrbaudes bลซs veiksmฤซgas %[1]s`
-pulls.auto_merge_canceled_schedule_comment=`atcฤla automฤtisko sapludinฤลกanu ลกim izmaiลu pieprasฤซjumam %[1]s`
+pulls.auto_merge_newly_scheduled_comment=`ieplฤnoja ลกฤซ izmaiลu pieprasฤซjuma automฤtisko apvienoลกanu, kad visas pฤrbaudes tiks sekmฤซgi pabeigtas %[1]s`
+pulls.auto_merge_canceled_schedule_comment=`atcฤla ลกฤซ izmaiลu pieprasฤซjuma automฤtisku apvienoลกanu pฤc visu pฤrbauลพu sekmฤซgas izpildes %[1]s`
-pulls.delete.title=Dzฤst ลกo izmaiลu pieprasฤซjumu?
-pulls.delete.text=Vai patieลกฤm vฤlaties dzฤst ลกo izmaiลu pieprasฤซjumu? (Neatgriezeniski tiks izdzฤsts viss saturs. Apsveriet iespฤju to aizvฤrt, ja vฤlaties informฤciju saglabฤt vฤsturei)
+pulls.delete.title=Izdzฤst ลกo izmaiลu pieprasฤซjumu?
+pulls.delete.text=Vai tieลกฤm izdzฤst ลกo izmaiลu pieprasฤซjumu? (Tiks neatgriezeniski izdzฤsts viss saturs. Jฤapsver iespฤja to aizvฤrt, ja ir nolลซks to paturฤt arhivฤtu)
-pulls.recently_pushed_new_branches=Tu iesลซtฤซji izmaiลas atzarฤ %[1]s %[2]s
+pulls.recently_pushed_new_branches=Tu aizgฤdฤji izmaiลas zarฤ %[1]s %[2]s
pull.deleted_branch=(izdzฤsts):%s
milestones.new=Jauns atskaites punkts
milestones.closed=Aizvฤrts %s
-milestones.update_ago=Atjaunots %s
+milestones.update_ago=Atjauninฤts %s
milestones.no_due_date=Bez termiลa
-milestones.open=Atvฤrta
+milestones.open=Atvฤrts
milestones.close=Aizvฤrt
-milestones.new_subheader=Atskaites punkti var palฤซdzฤt pฤrvaldฤซt problฤmas un sekot to virzฤซbai.
-milestones.completeness=%d%% pabeigti
+milestones.new_subheader=Atskaites punkti var palฤซdzฤt pฤrvaldฤซt pieteikumus un sekot to attฤซstฤซbai.
+milestones.completeness=Pabeigtni %d%%
milestones.create=Izveidot atskaites punktu
milestones.title=Virsraksts
milestones.desc=Apraksts
-milestones.due_date=Termiลลก (neobligฤts)
+milestones.due_date=Beigu datums (pฤc izvฤles)
milestones.clear=Notฤซrฤซt
-milestones.invalid_due_date_format=Izpildes termiลam ir jฤbลซt formฤta 'yyyy-mm-dd'.
-milestones.create_success=Atskaites punkts "%s" tika veiksmฤซgi izveidots.
+milestones.invalid_due_date_format=Beigu datuma pierakstam ir jฤbลซt "yyyy-mm-dd".
+milestones.create_success=Tika izveidots atskaites punkts "%s".
milestones.edit=Labot atskaites punktu
-milestones.edit_subheader=Atskaites punkti, ฤผauj organizฤt problฤmas un sekot to progresam.
+milestones.edit_subheader=Atskaites punkti ฤผauj sakฤrtot pieteikumus un sekot attฤซstฤซbai.
milestones.cancel=Atcelt
-milestones.modify=Labot atskaites punktu
-milestones.edit_success=Izmaiลas atskaites punktฤ "%s" tika veiksmฤซgi saglabฤtas.
-milestones.deletion=Dzฤst atskaites punktu
-milestones.deletion_desc=Dzฤลกot ลกo atskaites punktu, tas tiks noลemts no visฤm saistฤซtajฤm problฤmฤm un izmaiลu pieprasฤซjumiem. Vai turpinฤt?
-milestones.deletion_success=Atskaites punkts tika veiksmฤซgi izdzฤsts.
-milestones.filter_sort.earliest_due_data=Agrฤkais izpildes laiks
-milestones.filter_sort.latest_due_date=Vฤlฤkais izpildes laiks
+milestones.modify=Atjauninฤt atskaites punktu
+milestones.edit_success=Atskaites punkts "%s" tika atjauninฤts.
+milestones.deletion=Izdzฤst atskaites punktu
+milestones.deletion_desc=Atskaites punkta izdzฤลกana noลems to no visiem saistฤซtajiem pieteikumiem. Turpinฤt?
+milestones.deletion_success=Atskaites punkts tika izdzฤsts.
+milestones.filter_sort.earliest_due_data=Agrฤkais izpildes datums
+milestones.filter_sort.latest_due_date=Vฤlฤkais izpildes datums
milestones.filter_sort.least_complete=Vismazฤk pabeigtais
milestones.filter_sort.most_complete=Visvairฤk pabeigtais
-milestones.filter_sort.most_issues=Visvairฤk problฤmu
-milestones.filter_sort.least_issues=Vismazฤk problฤmu
+milestones.filter_sort.most_issues=Visvairฤk pieteikumu
+milestones.filter_sort.least_issues=Vismazฤk pieteikumu
-signing.will_sign=ล ฤซ revฤซzija tiks parakstฤซta ar atslฤgu "%s".
-signing.wont_sign.error=Notika kฤผลซda pฤrbaudot vai revฤซzija var tikt parakstฤซta.
-signing.wont_sign.nokey=Nav pieejamas atslฤgas, ar ko parakstฤซt ลกo revฤซziju.
-signing.wont_sign.never=Revฤซzijas nekad netiek parakstฤซtas.
-signing.wont_sign.always=Revฤซzijas vienmฤr tiek parakstฤซtas.
-signing.wont_sign.pubkey=Revฤซzija netiks parakstฤซta, jo kontam nav piesaistฤซta publiskฤ atslฤga.
-signing.wont_sign.twofa=Jฤbลซt iespฤjotai divfaktoru autentifikฤcijai, lai parakstฤซtu revฤซzijas.
-signing.wont_sign.parentsigned=Revฤซzija netiks parakstฤซta, jo nav parakstฤซta vecฤka revฤซzija.
-signing.wont_sign.basesigned=Sapludinฤลกanas revฤซzija netiks parakstฤซta, jo pamata revฤซzija nav parakstฤซta.
-signing.wont_sign.headsigned=Sapludinฤลกanas revฤซzija netiks parakstฤซta, jo galvenฤ revฤซzija nav parakstฤซta.
-signing.wont_sign.commitssigned=Sapludinฤลกana netiks parakstฤซta, jo visas saistฤซtฤs revฤซzijas nav parakstฤซtas.
-signing.wont_sign.approved=Sapludinฤลกana netiks parakstฤซta, jo izmaiลu pieprasฤซjums nav apstiprinฤts.
-signing.wont_sign.not_signed_in=Jลซs neesat pieteicies.
+signing.will_sign=ล is iesลซtฤซjums tiks parakstฤซts ar atslฤgu "%s".
+signing.wont_sign.error=Atgadฤซjฤs kฤผลซda pฤrbaudot, vai iesลซtฤซjums var tikt parakstฤซts.
+signing.wont_sign.nokey=Nav pieejamas atslฤgas, ar ko parakstฤซt ลกo iesลซtฤซjumu.
+signing.wont_sign.never=Iesลซtฤซjumi nekad netiek parakstฤซti.
+signing.wont_sign.always=Iesลซtฤซjumi vienmฤr tiek parakstฤซti.
+signing.wont_sign.pubkey=Iesลซtฤซjums netiks parakstฤซts, jo kontam nav piesaistฤซta publiska atslฤga.
+signing.wont_sign.twofa=Jฤbลซt iespฤjotai divpakฤpju autentificฤลกanai, lai parakstฤซtu iesลซtฤซjumus.
+signing.wont_sign.parentsigned=Iesลซtฤซjums netiks parakstฤซts, jo nav parakstฤซts cilmes iesลซtฤซjums.
+signing.wont_sign.basesigned=Apvienoลกana netiks parakstฤซta, jo pamata iesลซtฤซjums nav parakstฤซts.
+signing.wont_sign.headsigned=Apvienoลกana netiks parakstฤซta, jo galvenais iesลซtฤซjums nav parakstฤซts.
+signing.wont_sign.commitssigned=Apvienoลกana netiks parakstฤซta, jo visi saistฤซtie iesลซtฤซjumi nav parakstฤซti.
+signing.wont_sign.approved=Apvienoลกana netiks parakstฤซta, jo izmaiลu pieprasฤซjums nav apstiprinฤts.
+signing.wont_sign.not_signed_in=Tu neesi pieteicies.
-ext_wiki=Piekฤผuve ฤrฤjai vikivietnei
+ext_wiki=ฤrฤja vikivietne
ext_wiki.desc=ฤrฤjฤ vikivietne norฤda uz ฤrฤjo vikivietnes adresi.
wiki=Vikivietne
-wiki.welcome=Laipni lลซgti vikivietnฤ.
-wiki.welcome_desc=Vikivietne ฤผauj Jums un Jลซsu lฤซdzstrฤdniekiem viegli dokumentฤt projektu.
-wiki.desc=Vikivietne ir vieta, kur uzglabฤt dokumentฤciju.
+wiki.welcome=Laipni lลซdzam vikivietnฤ.
+wiki.welcome_desc=Vikivietne ฤผauj rakstฤซt un kopฤซgot dokumentฤciju ar lฤซdzdalฤซbniekiem.
+wiki.desc=Dokumentฤcijas rakstฤซลกana un kopฤซgoลกana ar lฤซdzdalฤซbniekiem.
wiki.create_first_page=Izveidot pirmo lapu
wiki.page=Lapa
wiki.filter_page=Meklฤt lapu
wiki.new_page=Lapa
wiki.page_title=Lapas virsraksts
wiki.page_content=Lapas saturs
-wiki.default_commit_message=Ierakstiet piezฤซmes par ลกฤซs lapas izmaiลฤm (neobligฤts).
+wiki.default_commit_message=Rakstฤซt piezฤซmes par ลกฤซs lapas izmaiลฤm (pฤc izvฤles).
wiki.save_page=Saglabฤt lapu
wiki.last_commit_info=%s laboja lapu %s
wiki.edit_page_button=Labot
wiki.new_page_button=Jauna lapa
-wiki.file_revision=Lapas rediฤฃฤjums
-wiki.wiki_page_revisions=Vikivietnes lapas rediฤฃฤjumi
+wiki.file_revision=Lapas labojums
+wiki.wiki_page_revisions=Vikivietnes lapas labojumi
wiki.back_to_wiki=Atpakaฤผ uz vikivietnes lapu
-wiki.delete_page_button=Dzฤst lapu
+wiki.delete_page_button=Izdzฤst lapu
wiki.delete_page_notice_1=ล ฤซ darbฤซba izdzฤsฤซs vikivietnes lapu "%s". Vai turpinฤt?
-wiki.page_already_exists=Vikivietnes lapa ar ลกฤdu nosaukumu jau eksistฤ.
+wiki.page_already_exists=Jau pastฤv vikivietnes lapa ar tฤdu paลกu nosaukumu.
wiki.reserved_page=Vikivietnes lapas nosaukums "%s" ir rezervฤts.
wiki.pages=Lapas
wiki.last_updated=Pฤdฤjo reizi labota %s
-wiki.page_name_desc=Ievadiet vikivietnes lapas nosaukumu. Speciฤlie nosaukumi ir: 'Home', '_Sidebar' un '_Footer'.
-wiki.original_git_entry_tooltip=Attฤlot oriฤฃinฤlo Git faila nosaukumu.
+wiki.page_name_desc=Jฤievada ลกฤซs vikivietnes lapas nosaukums. Daลพi ฤซpaลกie nosaukumi ir: "Home", "_Sidebar" un "_Footer".
+wiki.original_git_entry_tooltip=Rฤdฤซt sฤkotnฤjo Git datni, nevis izmantot draudzฤซgo saiti.
-activity=Aktivitฤte
-activity.period.filter_label=Laika periods:
+activity=Notikumi
+activity.period.filter_label=Laika posms:
activity.period.daily=1 diena
activity.period.halfweekly=3 dienas
activity.period.weekly=1 nedฤฤผa
@@ -1912,63 +2079,63 @@ activity.period.quarterly=3 mฤneลกi
activity.period.semiyearly=6 mฤneลกi
activity.period.yearly=1 gads
activity.overview=Pฤrskats
-activity.active_prs_count_1=%d aktฤซvs izmaiลu pieprasฤซjums
-activity.active_prs_count_n=%d aktฤซvi izmaiลu pieprasฤซjumi
-activity.merged_prs_count_1=Sapludinฤts izmaiลu pieprasฤซjums
-activity.merged_prs_count_n=Sapludinฤti izmaiลu pieprasฤซjumi
-activity.opened_prs_count_1=Piedฤvฤts izmaiลu pieprasฤซjums
-activity.opened_prs_count_n=Piedฤvฤti izmaiลu pieprasฤซjumi
+activity.active_prs_count_1=%d atvฤrts izmaiลu pieprasฤซjums
+activity.active_prs_count_n=%d atvฤrti izmaiลu pieprasฤซjumi
+activity.merged_prs_count_1=Iekฤผauts izmaiลu pieprasฤซjums
+activity.merged_prs_count_n=Iekฤผauti izmaiลu pieprasฤซjumi
+activity.opened_prs_count_1=Ierosinฤts izmaiลu pieprasฤซjums
+activity.opened_prs_count_n=Ierosinฤti izmaiลu pieprasฤซjumi
activity.title.user_1=%d lietotฤjs
activity.title.user_n=%d lietotฤji
activity.title.prs_1=%d izmaiลu pieprasฤซjumu
activity.title.prs_n=%d izmaiลu pieprasฤซjumus
-activity.title.prs_merged_by=%s sapludinฤja %s
-activity.title.prs_opened_by=%s piedฤvฤja %s
-activity.merged_prs_label=Sapludinฤts
-activity.opened_prs_label=Piedฤvฤts
-activity.active_issues_count_1=%d aktฤซva problฤma
-activity.active_issues_count_n=%d aktฤซvas problฤmas
-activity.closed_issues_count_1=Slฤgta problฤma
-activity.closed_issues_count_n=Slฤgtas problฤmas
-activity.title.issues_1=%d problฤmu
-activity.title.issues_n=%d problฤmas
-activity.title.issues_closed_from=%s aizvฤrts no %s
+activity.title.prs_merged_by=%s iekฤผฤva %s
+activity.title.prs_opened_by=%s ierosinฤja %s
+activity.merged_prs_label=Iekฤผauts
+activity.opened_prs_label=Ierosinฤts
+activity.active_issues_count_1=%d atvฤrts pieteikums
+activity.active_issues_count_n=%d atvฤrti pieteikumi
+activity.closed_issues_count_1=Aizvฤrts pieteikums
+activity.closed_issues_count_n=Aizvฤrti pieteikumi
+activity.title.issues_1=%d pieteikumu
+activity.title.issues_n=%d pieteikumus
+activity.title.issues_closed_from=%s aizvฤra %s
activity.title.issues_created_by=%s izveidoja %s
-activity.closed_issue_label=Slฤgta
-activity.new_issues_count_1=Jauna problฤma
-activity.new_issues_count_n=Jaunas problฤmas
-activity.new_issue_label=Atvฤrta
-activity.title.unresolved_conv_1=%d neatrisinฤta diskusija
-activity.title.unresolved_conv_n=%d neatrisinฤtas diskusijas
-activity.unresolved_conv_desc=Saraksts ar visฤm problฤmฤm un izmaiลu pieprasฤซjumiem, kas nesen mainฤซti un vฤl nav atrisinฤti.
+activity.closed_issue_label=Aizvฤrts
+activity.new_issues_count_1=Jauns pieteikums
+activity.new_issues_count_n=Jauni pieteikumi
+activity.new_issue_label=Atvฤra
+activity.title.unresolved_conv_1=%d neatrisinฤta saruna
+activity.title.unresolved_conv_n=%d neatrisinฤtu apsprieลกanu
+activity.unresolved_conv_desc=ล ie nesen mainฤซtie pieteikumi un izmaiลu pieprasฤซjumi vฤl nav atrisinฤti.
activity.unresolved_conv_label=Atvฤrts
-activity.title.releases_1=%d versiju
-activity.title.releases_n=%d versijas
-activity.title.releases_published_by=%s publicฤja %s
-activity.published_release_label=Publicฤts
+activity.title.releases_1=%d laidiens
+activity.title.releases_n=%d laidieni
+activity.title.releases_published_by=%s laida klฤjฤ %s
+activity.published_release_label=Laidiens
activity.no_git_activity=ล ajฤ laika periodฤ nav notikuลกas nekฤdas izmaiลas.
-activity.git_stats_exclude_merges=Neskaitot sapludinฤลกanas revฤซzijas,
+activity.git_stats_exclude_merges=Neskaitot apvienoลกanas iesลซtฤซjumus,
activity.git_stats_author_1=%d autors
activity.git_stats_author_n=%d autori
-activity.git_stats_pushed_1=iesลซtฤซja
-activity.git_stats_pushed_n=iesลซtฤซja
-activity.git_stats_commit_1=%d revฤซziju
-activity.git_stats_commit_n=%d revฤซzijas
-activity.git_stats_push_to_branch=atzarฤ %s un
-activity.git_stats_push_to_all_branches=visos atzaros.
-activity.git_stats_on_default_branch=Atzarฤ %s,
-activity.git_stats_file_1=%d fails
-activity.git_stats_file_n=%d faili
+activity.git_stats_pushed_1=aizgฤdฤja
+activity.git_stats_pushed_n=aizgฤdฤja
+activity.git_stats_commit_1=%d iesลซtฤซjumu
+activity.git_stats_commit_n=%d iesลซtฤซjumus
+activity.git_stats_push_to_branch=zarฤ %s un
+activity.git_stats_push_to_all_branches=visos zaros.
+activity.git_stats_on_default_branch=Zarฤ %s,
+activity.git_stats_file_1=%d datne
+activity.git_stats_file_n=%d datnes
activity.git_stats_files_changed_1=tika izmainฤซts
activity.git_stats_files_changed_n=tika izmainฤซti
activity.git_stats_additions=un tika veiktas
activity.git_stats_addition_1=%d pievienoลกana
activity.git_stats_addition_n=%d pievienoลกanas
activity.git_stats_and_deletions=un
-activity.git_stats_deletion_1=%d dzฤลกana
-activity.git_stats_deletion_n=%d dzฤลกanas
+activity.git_stats_deletion_1=%d izdzฤลกana
+activity.git_stats_deletion_n=%d izdzฤลกanas
-contributors.contribution_type.commits=Revฤซzijas
+contributors.contribution_type.commits=Iesลซtฤซjumi
search=Meklฤt
search.search_repo=Meklฤลกana repozitorijฤ
@@ -1982,267 +2149,267 @@ search.code_no_results=Netika atrasts pirmkods, kas atbilstu kritฤrijiem.
search.code_search_unavailable=Paลกlaik koda meklฤลกana nav pieejama. Sazinieties ar lapas administratoru.
settings=Iestatฤซjumi
-settings.desc=Iestatฤซjumi ir vieta, kur varat pฤrvaldฤซt repozitorija iestatฤซjumus
-settings.options=Repozitorijs
-settings.collaboration=Lฤซdzstrฤdnieks
-settings.collaboration.admin=Administrators
-settings.collaboration.write=Rakstฤซลกanas
-settings.collaboration.read=Skatฤซลกanฤs
+settings.desc=Iestatฤซjumi ir vieta, kur pฤrvaldฤซt glabฤtavas iestatฤซjumus
+settings.options=Glabฤtava
+settings.collaboration=Lฤซdzdalฤซbnieki
+settings.collaboration.admin=Pฤrvaldฤซtฤjs
+settings.collaboration.write=Rakstฤซt
+settings.collaboration.read=Lasฤซt
settings.collaboration.owner=ฤชpaลกnieks
settings.collaboration.undefined=Nedefinฤtas
-settings.hooks=Tฤซmekฤผa ฤฤทi
-settings.githooks=Git ฤฤทi
+settings.hooks=Tฤซmekฤผa aizฤทeres
+settings.githooks=Git aizฤทeres
settings.basic_settings=Pamatiestatฤซjumi
-settings.mirror_settings=Spoguฤผa iestatฤซjumi
-settings.mirror_settings.docs=Iestatiet, ka tiks viekta automฤtiska revฤซziju, tagu un atzaru sinhronizฤcija ar citu repozitoriju.
-settings.mirror_settings.docs.disabled_pull_mirror.instructions=Iestatiet, ka visas revฤซzijas, tagi un atzari tiks automฤtiski nosลซtฤซtu uz citu repozitoriju. Izgลซลกanas spoguฤผus administrators ir aizliedzis izmantot.
-settings.mirror_settings.docs.disabled_push_mirror.instructions=Iestatiet, ka visas revฤซzijas, tagi un atzari tiks automฤtiski pฤrลemti no cita repozitorija.
-settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=Paลกlaik to var izdarฤซt tikai, izmantojot, sadaฤผu "Jauna migrฤcija". Sฤซkฤkai informฤcijai, skatieties:
-settings.mirror_settings.docs.disabled_push_mirror.info=Iesลซtฤซลกanas spoguฤผus administrators ir aizliedzis izmantot.
-settings.mirror_settings.docs.no_new_mirrors=ล is repozitorijs spoguฤผo izmaiลas uz vai no cita repozitorija. Paลกlaik vairฤk nav iespฤjams izveidot jaunus spoguฤผa repozitorijus.
-settings.mirror_settings.docs.can_still_use=Lai arฤซ nav iespฤjams mainฤซt esoลกos vai izveidot jaunus spoguฤผa repozitorijus, esoลกie turpinฤs strฤdฤt.
-settings.mirror_settings.docs.pull_mirror_instructions=Lai ietatฤซtu atvilkลกanas spoguli, sekojiet instrukcijฤm:
-settings.mirror_settings.docs.more_information_if_disabled=Vairฤk par piegฤdฤลกanas un saลemลกanas spoguฤผiem var uzzinฤt ลกeit:
-settings.mirror_settings.docs.doc_link_title=Kฤ spoguฤผot repozitorijus?
-settings.mirror_settings.docs.doc_link_pull_section=dokumentฤcijas nodaฤผฤ "Pulling from a remote repository".
-settings.mirror_settings.docs.pulling_remote_title=Atvilkt no attฤla repozitorija
-settings.mirror_settings.mirrored_repository=Spoguฤผotais repozitorijs
+settings.mirror_settings=Spoguฤผglabฤtavas iestatฤซjumi
+settings.mirror_settings.docs=Iestatฤซt glabฤtavu, lai automฤtiski sinhronizฤtu iesลซtฤซjumus, birkas un zarus ar citu glabฤtavu.
+settings.mirror_settings.docs.disabled_pull_mirror.instructions=Iestatฤซt projektu, lai uz citu glabฤtavu automฤtiski aizgฤdฤtu iesลซtฤซjumus, birkas un zarus. Vietnes pฤrvaldฤซtฤjs ir atspฤjojis izgลซลกanas spoguฤผglabฤtavas.
+settings.mirror_settings.docs.disabled_push_mirror.instructions=Iestatฤซt projektu, lai no citas glabฤtavas automฤtiski atgฤdฤtu iesลซtฤซjumus, birkas un zarus.
+settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=Paลกlaik tas ir izdarฤms tikai sadaฤผฤ "Jauna pฤrcelลกana". Pฤc vairฤk informฤcijas lลซgums vฤrsties:
+settings.mirror_settings.docs.disabled_push_mirror.info=Vietnes pฤrvaldฤซtฤjs ir atspฤjojis iesลซtฤซลกanas spoguฤผglabฤtavas.
+settings.mirror_settings.docs.no_new_mirrors=ล ฤซ glabฤtava spoguฤผo izmaiลas uz vai no citas glabฤtavas. Lลซgums paturฤt prฤtฤ, ka paลกlaik nevar izveidot jaunas spoguฤผglabฤtavas.
+settings.mirror_settings.docs.can_still_use=Lai arฤซ nevar labot esoลกฤs spoguฤผglabฤtavas vai izveidot jaunas, joprojฤm var izmantot esoลกฤs spoguฤผglabฤtavas.
+settings.mirror_settings.docs.pull_mirror_instructions=Lai iestatฤซtu atgฤdฤลกanas spoguฤผglabฤtavu, lลซgums pฤrskatฤซt:
+settings.mirror_settings.docs.more_information_if_disabled=Vairฤk par aizgฤdฤลกanas un izgลซลกanas spoguฤผglabฤtavฤm var uzzinฤt ลกeit:
+settings.mirror_settings.docs.doc_link_title=Kฤ spoguฤผot glabฤtavas?
+settings.mirror_settings.docs.doc_link_pull_section=dokumentฤcijas nodaฤผฤ "Izgลซลกana no attฤlas glabฤtavas".
+settings.mirror_settings.docs.pulling_remote_title=Atgฤdฤ no attฤlas glabฤtavas
+settings.mirror_settings.mirrored_repository=Spoguฤผotฤ glabฤtava
settings.mirror_settings.direction=Virziens
-settings.mirror_settings.direction.pull=Izmaiลu saลemลกana
-settings.mirror_settings.direction.push=Izmaiลu nosลซtฤซลกana
+settings.mirror_settings.direction.pull=Atgฤdฤลกana
+settings.mirror_settings.direction.push=Aizgฤdฤลกana
settings.mirror_settings.last_update=Pฤdฤjฤs izmaiลas
-settings.mirror_settings.push_mirror.none=Nav konfigurฤts iesลซtฤซลกanas spogulis
-settings.mirror_settings.push_mirror.remote_url=Git attฤlinฤtฤ repozitorija URL
-settings.mirror_settings.push_mirror.add=Pievienot iesลซtฤซลกanas spoguli
-settings.mirror_settings.push_mirror.edit_sync_time=Labot spoguฤผa sinhronizฤcijas intervฤlu
+settings.mirror_settings.push_mirror.none=Nav pievienotu aizgฤdฤลกanas spoguฤผglabฤtavu
+settings.mirror_settings.push_mirror.remote_url=Git attฤlฤs glabฤtavas URL
+settings.mirror_settings.push_mirror.add=Pievienot aizgฤdฤลกanas spoguฤผglabฤtavu
+settings.mirror_settings.push_mirror.edit_sync_time=Labot spoguฤผglabฤtavas sinhronizฤลกanas starplaiku
settings.sync_mirror=Sinhronizฤt tagad
-settings.pull_mirror_sync_in_progress=Paลกlaik tiek saลemtas izmaiลas no attฤlฤ %s.
-settings.push_mirror_sync_in_progress=Paลกlaik tiek piegฤdฤtas izmaiลas uz attฤlo %s.
-settings.site=Mฤjas lapa
-settings.update_settings=Mainฤซt iestatฤซjumus
-settings.update_mirror_settings=Atjaunot spoguฤผa iestatฤซjumus
-settings.branches.switch_default_branch=Mainฤซt noklusฤto atzaru
-settings.branches.update_default_branch=Atjaunot noklusฤto atzaru
-settings.branches.add_new_rule=Pievienot jaunu noteikumu
+settings.pull_mirror_sync_in_progress=Paลกlaik tiek atgฤdฤtas izmaiลas no attฤlฤs %s.
+settings.push_mirror_sync_in_progress=Paลกlaik tiek aizgฤdฤtas izmaiลas uz attฤlo %s.
+settings.site=Tฤซmekฤผvietne
+settings.update_settings=Saglabฤt iestatฤซjumus
+settings.update_mirror_settings=Atjauninฤt spoguฤผglabฤtavas iestatฤซjumus
+settings.branches.switch_default_branch=Mainฤซt noklusฤjuma zaru
+settings.branches.update_default_branch=Atjauninฤt noklusฤjuma zaru
+settings.branches.add_new_rule=Pievienot jaunu kฤrtulu
settings.advanced_settings=Papildu iestatฤซjumi
-settings.wiki_desc=Iespฤjot vikivietnes
+settings.wiki_desc=Iespฤjot glabฤtavas vikivietni
settings.use_internal_wiki=Izmantot iebลซvฤto vikivietni
-settings.use_external_wiki=Izmantot ฤrฤjo vikivietni
-settings.external_wiki_url=ฤrฤjฤs Vikivietnes adrese
-settings.external_wiki_url_error=ฤrฤjฤs vikivietnes URL nav korekts URL.
+settings.use_external_wiki=Izmantot ฤrฤju vikivietni
+settings.external_wiki_url=ฤrฤjฤs vikivietnes URL
+settings.external_wiki_url_error=ฤrฤjฤs vikivietnes URL nav derฤซgs URL.
settings.external_wiki_url_desc=Apmeklฤtฤji tiks novirzฤซti uz ฤrฤjฤs vikivietnes adresi, kad uzklikลกฤทinฤs uz cilnes.
-settings.issues_desc=Iespฤjot iebลซvฤto problฤmu sekotฤju
-settings.use_internal_issue_tracker=Izmantot iebลซvฤto problฤmu sekotฤju
-settings.use_external_issue_tracker=Izmantot ฤrฤjo problฤmu sekotฤju
-settings.external_tracker_url=ฤrฤjฤ problฤmu reฤฃistra URL
-settings.external_tracker_url_error=Nekorekts ฤrฤjฤ problฤmu sekotฤja URL.
-settings.external_tracker_url_desc=Apmeklฤtฤji tiks novirzฤซti uz ฤrฤjฤ problฤmu sekotฤja adresi, kad uzklikลกฤทinฤs uz cilnes.
-settings.tracker_url_format=ฤrฤjฤ problฤmu sekotฤja adreses formฤts
-settings.tracker_url_format_error=ฤrฤjฤ problฤmu sekotฤja URL formฤts nav korekts URL.
-settings.tracker_issue_style=ฤrฤjฤ problฤmu sekotฤja numura formฤts
+settings.issues_desc=Iespฤjot glabฤtavas pieteikumu izsekotฤju
+settings.use_internal_issue_tracker=Izmantot iebลซvฤto pieteikumu izsekotฤju
+settings.use_external_issue_tracker=Izmantot ฤrฤju pieteikumu izsekotฤju
+settings.external_tracker_url=ฤrฤjฤ pieteikumu izsekotฤja URL
+settings.external_tracker_url_error=ฤrฤjฤ pieteikumu izsekotฤja URL nav derฤซgs URL.
+settings.external_tracker_url_desc=Apmeklฤtฤji tiks novirzฤซti uz ฤrฤjฤ pieteikumu izsekotฤja URL pฤc klikลกฤทinฤลกanas uz pieteikumu cilnes.
+settings.tracker_url_format=ฤrฤjฤ pieteikumu izsekotฤja URL uzbลซve
+settings.tracker_url_format_error=ฤrฤjฤ pieteikumu izsekotฤja URL uzbลซve neatbilst derฤซgam URL.
+settings.tracker_issue_style=ฤrฤjฤ pieteikumu izsekotฤja numuru uzbลซve
settings.tracker_issue_style.numeric=Cipari
settings.tracker_issue_style.alphanumeric=Burti un cipari
settings.tracker_issue_style.regexp=Regulฤrฤ izteiksme
-settings.tracker_issue_style.regexp_pattern=Regulฤrฤs izteiksmes ลกablons
-settings.tracker_issue_style.regexp_pattern_desc=Pirmฤ iegultฤ grupa tiks izmantota {index}
vietฤ.
-settings.tracker_url_format_desc=Jลซs varat izmantot {user}
, {repo}
un {index}
lietotฤjvฤrdam, repozitorija nosaukumam un problฤmas identifikatoram.
+settings.tracker_issue_style.regexp_pattern=Regulฤrฤs izteiksmes paraugs
+settings.tracker_issue_style.regexp_pattern_desc=Pirmฤ tveramฤ kopa tiks izmantota {index}
vietฤ.
+settings.tracker_url_format_desc=Var izmantot vietturus {user}
, {repo}
un {index}
lietotฤjvฤrdam, glabฤtavas nosaukumam un pieteikuma indeksam.
settings.enable_timetracker=Iespฤjot laika uzskaiti
-settings.allow_only_contributors_to_track_time=Atฤผaut tikai dalฤซbniekiem uzskaitฤซt laiku
-settings.pulls_desc=Iespฤjot repozitorija izmaiลu pieprasฤซjumus
-settings.pulls.ignore_whitespace=Pฤrbaudot konfliktus, ignorฤt izmaiลas atstarpฤs
-settings.pulls.enable_autodetect_manual_merge=Iespฤjot manuฤlas sapludinฤลกanas noteikลกanu (Piezฤซme: daลพos speciฤlos gadฤซjumos, tas var nostrฤdฤt nekorekti)
-settings.pulls.allow_rebase_update=Iespฤjot izmaiลu pieprasฤซjuma atjaunoลกanu ar pฤrbฤzฤลกanu
-settings.pulls.default_delete_branch_after_merge=Pฤc noklusฤjuma dzฤst izmaiลu pieprasฤซjuma atzaru pฤc sapludinฤลกanas
+settings.allow_only_contributors_to_track_time=Atฤผaut uzskaitฤซt laiku tikai lฤซdzdalฤซbniekiem
+settings.pulls_desc=Iespฤjot glabฤtavas izmaiลu pieprasฤซjumus
+settings.pulls.ignore_whitespace=Nesaderฤซbu noteikลกanฤ neลemt vฤrฤ atstarpes
+settings.pulls.enable_autodetect_manual_merge=Iespฤjot paลกrocฤซgas apvienoลกanas noteikลกanu (Piezฤซme: daลพos ฤซpaลกos gadฤซjumos tฤ var nenostrฤdฤt pareizi)
+settings.pulls.allow_rebase_update=Iespฤjot izmaiลu pieprasฤซjuma zara atjauninฤลกanu ar pฤrbฤzฤลกanu
+settings.pulls.default_delete_branch_after_merge=Pฤc noklusฤjuma izdzฤst izmaiลu pieprasฤซjuma zaru pฤc apvienoลกanas
settings.pulls.default_allow_edits_from_maintainers=Atฤผaut uzturฤtฤjiem labot pฤc noklusฤjuma
-settings.releases_desc=Iespฤjot repozitorija laidienus
-settings.packages_desc=Iespฤjot repozitorija pakotลu reฤฃistru
-settings.projects_desc=Iespฤjot repozitorija projektus
-settings.actions_desc=Iespฤjot repozitorija darbฤซbas
-settings.admin_settings=Administratora iestatฤซjumi
-settings.admin_enable_health_check=Iespฤjot veselฤซbas pฤrbaudi (git fsck) ลกim repozitorijam
-settings.admin_code_indexer=Izejas koda indeksฤtฤjs
-settings.admin_stats_indexer=Izejas koda statistikas indeksฤtฤjs
-settings.admin_indexer_commit_sha=Pฤdฤjฤ indeksฤtฤ revฤซzija
+settings.releases_desc=Iespฤjot glabฤtavas laidienus
+settings.packages_desc=Iespฤjot glabฤtavas pakotลu reฤฃistru
+settings.projects_desc=Iespฤjot glabฤtavas projektus
+settings.actions_desc=Iespฤjot iekฤผautos CI/CD cauruฤผvadus ar Forgejo Actions
+settings.admin_settings=Pฤrvaldฤซtฤja iestatฤซjumi
+settings.admin_enable_health_check=Iespฤjot glabฤtavas darbspฤjas pฤrbaudes (git fsck)
+settings.admin_code_indexer=Koda indeksฤtฤjs
+settings.admin_stats_indexer=Koda statistikas indeksฤtฤjs
+settings.admin_indexer_commit_sha=Pฤdฤjais indeksฤtais iesลซtฤซjums
settings.admin_indexer_unindexed=Neindeksฤts
-settings.reindex_button=Pievienot pฤrindeksฤลกanas rindai
+settings.reindex_button=Pievienot pฤrindeksฤลกanas rindsarakstam
settings.reindex_requested=Pieprasฤซta pฤrindeksฤลกana
-settings.admin_enable_close_issues_via_commit_in_any_branch=Aizvฤrt problฤmu ar izmaiลu komentฤru iesลซtฤซtu jebkurฤ atzarฤ
-settings.danger_zone=Bฤซstamฤ zona
-settings.new_owner_has_same_repo=Jaunajam ฤซpaลกniekam jau ir repozitorijs ar ลกฤdu nosaukumu.
-settings.convert=Konvertฤt uz parastu repozitoriju
-settings.convert_desc=Jลซs varat nomainฤซt ลกo spoguli uz parastu repozitoriju. ล ฤซ darbฤซba ir neatgriezeniska.
-settings.convert_notices_1=ล ฤซ darbฤซba mainฤซs spoguli uz parastu repozitoriju un ir neatgriezeniska.
-settings.convert_confirm=Konvertฤt repozitoriju
-settings.convert_succeed=Spogulis tika izmainฤซts par parastu repozitoriju.
-settings.convert_fork=Konvertฤt uz parastu repozitoriju
-settings.convert_fork_desc=Jลซs varat nomainฤซt ลกo atdalฤซto repozitoriju kฤ neatkarฤซgu repozitoriju. ล ฤซ darbฤซba ir neatgriezeniska.
-settings.convert_fork_notices_1=ล ฤซ darbฤซba mainฤซs atdalฤซto repozitoriju uz neatkarฤซgu repozitoriju un ir neatgriezeniska.
-settings.convert_fork_confirm=Konvertฤt repozitoriju
-settings.convert_fork_succeed=Atdalฤซtais repozitorijs tika izmainฤซts par neatkarฤซgu repozitoriju.
-settings.transfer.title=Mainฤซt ฤซpaลกnieku
-settings.transfer.rejected=Repozitorija ฤซpaลกnieka maiลas pieprasฤซjums tika noraidฤซts.
-settings.transfer.success=Repozitorija ฤซpaลกnieka maiลa veiksmฤซga.
-settings.transfer_abort=Atcelt ฤซpaลกnieka maiลu
-settings.transfer_abort_invalid=Nevar atcelt neeksistฤjoลกa repozitorija ฤซpaลกnieka maiลu.
-settings.transfer_abort_success=Repozitorija ฤซpaลกnieka maiลa uz %s tika veiksmฤซgi atcelta.
-settings.transfer_desc=Mainฤซt ลกฤซ repozitorija ฤซpaลกnieku uz citu lietotฤju vai organizฤciju, kurai Jums ir administratora tiesฤซbas.
+settings.admin_enable_close_issues_via_commit_in_any_branch=Aizvฤrt pieteikumu ar iesลซtฤซjumu ne noklusฤjuma zarฤ
+settings.danger_zone=Bฤซstamais apgabals
+settings.new_owner_has_same_repo=Jaunajam ฤซpaลกniekam jau ir glabฤtava ar tฤdu paลกu nosaukumu. Lลซgums izvฤlฤties citu nosaukumu.
+settings.convert=Pฤrveidot par parastu glabฤtavu
+settings.convert_desc=ล o spoguฤผglabฤtavu var pฤrveidot par parastu glabฤtavu. To nevar atsaukt.
+settings.convert_notices_1=ล ฤซ darbฤซba pฤrveidos spoguฤผglabฤtavu par parastu glabฤtavu un nav atsaucama.
+settings.convert_confirm=Pฤrveidot glabฤtavu
+settings.convert_succeed=Spoguฤผglabฤtava tika pฤrveidota par parastu glabฤtavu.
+settings.convert_fork=Pฤrveidot par parastu glabฤtavu
+settings.convert_fork_desc=ล o atzarojumu var pฤrveidot par parastu glabฤtavu. To nevar atsaukt.
+settings.convert_fork_notices_1=ล ฤซ darbฤซba pฤrveidos atzarojumu par parastu glabฤtavu, un tฤ nav atsaucama.
+settings.convert_fork_confirm=Pฤrveidot glabฤtavu
+settings.convert_fork_succeed=Atzarojums tika pฤrveidots par parastu glabฤtavu.
+settings.transfer.title=Nodot ฤซpaลกumtiesฤซbas
+settings.transfer.rejected=Glabฤtavas nodoลกana tika noraidฤซta.
+settings.transfer.success=Glabฤtavas nodoลกana bija sekmฤซga.
+settings.transfer_abort=Atcelt nodoลกanu
+settings.transfer_abort_invalid=Nevar atcelt neesoลกu glabฤtavas nodoลกanu.
+settings.transfer_abort_success=Glabฤtavas nodoลกana %s tika sekmฤซgi atcelta.
+settings.transfer_desc=Nodot ลกo glabฤtavu lietotฤjam vai apvienฤซbai, kurฤ Tev ir pฤrvaldฤซtฤja tiesฤซbas.
settings.transfer_form_title=Ievadiet repozitorija nosaukumu, lai apstiprinฤtu:
-settings.transfer_in_progress=Paลกlaik jau tiek veikta repozitorija ฤซpaลกnieka maiลa. Atceliet iepriekลกฤjo ฤซpaลกnieka maiลu, ja vฤlaties mainฤซt uz citu.
-settings.transfer_notices_1=- Tiks zaudฤta piekฤผuve repozitorijam, ja jaunais ฤซpaลกnieks ir individuฤls lietotฤjs.
-settings.transfer_notices_2=- Tiks saglabฤta piekฤผuve, ja jaunais ฤซpaลกnieks ir organizฤcija un esat viens no tฤs ฤซpaลกniekiem.
-settings.transfer_notices_3=- Ja repozitorijs ir privฤts un tas tiks pฤrsลซtฤซts lietotฤjam, tad pฤrliecinฤties, ka lietotฤjam ir vismaz skatฤซลกanฤs tiesฤซbas (veiciet nepiecieลกamฤs izmaiลas, ja nepiecieลกams).
+settings.transfer_in_progress=Paลกlaik jau ir notiekoลกa nodoลกana. Lลซgums to atcelt, ja ir vฤlme nodot ลกo glabฤtavu citam lietotฤjam.
+settings.transfer_notices_1=- Tiks zaudฤta piekฤผuve glabฤtavai, ja tฤ tiks nodota atseviลกฤทam lietotฤjam.
+settings.transfer_notices_2=- Tiks saglabฤta piekฤผuve glabฤtavai, ja tฤ tiks nodota apvienฤซbai, kurai esi (lฤซdz)ฤซpaลกnieks.
+settings.transfer_notices_3=- Ja glabฤtava ir privฤta un tฤ tiek nodota atseviลกฤทam lietotฤjam, ลกฤซ darbฤซba pฤrbauda, vai lietotฤjam ir vismaz lasฤซลกanas atฤผauja (un izmaina atฤผaujas, ja nepiecieลกams).
settings.transfer_owner=Jaunais ฤซpaลกnieks
-settings.transfer_perform=Veikt ฤซpaลกnieka maiลu
-settings.transfer_started=`ล im repozitorijam tiek veikta ฤซpaลกnieka maiลa un nepiecieลกams apstiprinฤjums no "%s"`
-settings.transfer_succeed=Repozitorijs tika pฤrcelts.
-settings.signing_settings=Parakstu pฤrbaudes iestatฤซjumi
-settings.trust_model=Uzticฤลกanฤs modelis parakstiem
+settings.transfer_perform=Veikt nodoลกanu
+settings.transfer_started=ล ฤซ glabฤtava ir atzฤซmฤta nodoลกanai un gaida apstiprinฤjumu no "%s"
+settings.transfer_succeed=Glabฤtava tika nodota.
+settings.signing_settings=Parakstu apliecinฤลกanas iestatฤซjumi
+settings.trust_model=Parakstu uzticฤลกanฤs modelis
settings.trust_model.default=Noklusฤjuma uzticฤลกanฤs modelis
-settings.trust_model.default.desc=Izmantot noklusฤto repozitoriju uzticฤซbas modeli.
-settings.trust_model.collaborator=Lฤซdzstrฤdnieka
-settings.trust_model.collaborator.long=Lฤซdzstrฤdnieka: Uzticฤties lฤซdzstrฤdnieku parakstiem
-settings.trust_model.collaborator.desc=Derฤซgi lฤซdzstrฤdnieku paraksti tiks atzฤซmฤti kฤ "uzticami" (neatkarฤซgi no tฤ vai tie atbilst revฤซzijas iesลซtฤซtฤjam vai nฤ). Citos gadฤซjumos derฤซgi paraksti tiks atzฤซmฤti kฤ "neuzticami", ja paraksts atbilst revฤซzijas iesลซtฤซtฤjam vai "nesakrฤซtoลกs", ja neatbilst.
-settings.trust_model.committer=Revฤซzijas iesลซtฤซtฤja
-settings.trust_model.committer.long=Revฤซzijas iesลซtฤซtฤja: Uzticฤties parakstiem, kas atbilst revฤซzijas iesลซtฤซtฤjiem (ล is atbilst GitHub uzvedฤซbai un piespiedฤซs Forgejo parakstฤซtฤm revฤซzijฤm norฤdฤซt Forgejo kฤ revฤซzijas iesลซtฤซtฤju)
-settings.trust_model.committer.desc=Derฤซgi paraksti tiks atzฤซmฤti kฤ "uzticami", ja tie atbilst revฤซzijas iesลซtฤซtฤjam, citos gadฤซjumos tie tiks atzฤซmฤti kฤ "nesakrฤซtoลกi". ล is nozฤซmฤ, ka Forgejo bลซs kฤ revฤซzijas iesลซtฤซtฤjs parakstฤซtฤm revฤซzijฤm, kur ฤซstais revฤซzijas iesลซtฤซtฤjs tiks atฤซzmฤts revฤซzijas komentฤra beigฤs ar tekstu Co-authored-by: un Co-committed-by:. Noklusฤtajai Forgejo atslฤgai ir jฤatbilst lietotฤjam datubฤzฤ.
-settings.trust_model.collaboratorcommitter=Lฤซdzstrฤdnieka un revฤซzijas iesลซtฤซtฤja
-settings.trust_model.collaboratorcommitter.long=Lฤซdzstrฤdnieka un revฤซzijas iesลซtฤซtฤja: Uzticฤties lฤซdzstrฤdnieku parakstiem, kas atbilst revฤซzijas iesลซtฤซtฤjam
-settings.trust_model.collaboratorcommitter.desc=Derฤซgi lฤซdzstrฤdnieku paraksti tiks atzฤซmฤti kฤ "uzticami", ja tie atbilst revฤซzijas iesลซtฤซtฤjam, citos gadฤซjumos tie tiks atzฤซmฤti kฤ "neuzticami", ja paraksts atbilst revฤซzijas iesลซtฤซtajam, vai "nesakrฤซtoลกi", ja neatbilst. ล is nozฤซmฤ, ka Forgejo bลซs kฤ revฤซzijas iesลซtฤซtฤjs parakstฤซtฤm revฤซzijฤm, kur ฤซstais revฤซzijas iesลซtฤซtฤjs tiks atฤซzmฤts revฤซzijas komentฤra beigฤs ar tekstu Co-Authored-By: un Co-Committed-By:. Noklusฤtajai Forgejo atslฤgai ir jฤatbilst lietotฤjam datubฤzฤ.
-settings.wiki_delete=Dzฤst vikivietnes datus
-settings.wiki_delete_desc=Vikivietnes repozitorija dzฤลกana ir neatgriezeniska un nav atsaucama.
-settings.wiki_delete_notices_1=- ล ฤซ darbฤซba dzฤsฤซs un atspฤjos repozitorija %s vikivietni.
-settings.confirm_wiki_delete=Dzฤst vikivietnes datus
-settings.wiki_deletion_success=Repozitorija vikivietnes dati tika izdzฤsti.
-settings.delete=Dzฤst ลกo repozitoriju
-settings.delete_desc=Repozitorija dzฤลกana ir neatgriezeniska un nav atsaucama.
+settings.trust_model.default.desc=Izmantot noklusฤjuma glabฤtavu uzticฤซbas modeli.
+settings.trust_model.collaborator=Lฤซdzdalฤซbnieks
+settings.trust_model.collaborator.long=Lฤซdzdalฤซbnieks: uzticฤties lฤซdzdalฤซbnieku parakstiem
+settings.trust_model.collaborator.desc=Derฤซgi ลกฤซs glabฤtavas lฤซdzdalฤซbnieku paraksti tiks atzฤซmฤti ar "uzticams" (neatkarฤซgi no tฤ, vai tie atbilst iesลซtฤซtฤjam vai nฤ). Pretฤjฤ gadฤซjumฤ derฤซgi paraksti tiks atzฤซmฤti ar "neuzticams", ja paraksts atbilst iesลซtฤซtฤjam, un ar "neatbilstoลกs", ja neatbilst.
+settings.trust_model.committer=Iesลซtฤซtฤjs
+settings.trust_model.committer.long=Iesลซtฤซtฤjs: uzticฤties parakstiem, kas atbilst iesลซtฤซtฤjiem (ล is atbilst GitHub un uzsspiedฤซs Forgejo parakstฤซtiem iesลซtฤซjumiem norฤdฤซt Forgejo kฤ iesลซtฤซtฤju)
+settings.trust_model.committer.desc=Derฤซgi paraksti tiks atzฤซmฤti ar "uzticams" tikai tad, ja tie atbildฤซs iesลซtฤซtฤjam, pretฤjฤ gadฤซjumฤ tie tiks atzฤซmฤti ar "neatbilstoลกs". Tas nozฤซmฤ, ka Forgejo bลซs iesลซtฤซtฤjs parakstฤซtiem iesลซtฤซjumiem, patieso iesลซtฤซtฤju iesลซtฤซjumฤ atzฤซmฤjot ar Co-authored-by: un Co-committed-by: noslฤgumu. Noklusฤjuma Forgejo atslฤgai ir jฤatbilst lietotฤjam datu bฤzฤ.
+settings.trust_model.collaboratorcommitter=Lฤซdzdalฤซbnieks un iesลซtฤซtฤjs
+settings.trust_model.collaboratorcommitter.long=Lฤซdzdalฤซbnieks un iesลซtฤซtฤjs: uzticฤties lฤซdzdalฤซbnieku, kas atbilst iesลซtฤซtฤjam, parakstiem
+settings.trust_model.collaboratorcommitter.desc=Derฤซgi ลกฤซs glabฤtavas lฤซdzdalฤซbnieku paraksti tiks atzฤซmฤti ar "uzticams", ja tie atbildฤซs iesลซtฤซtฤjam. Pretฤjฤ gadฤซjumฤ derฤซgi paraksti tiks atzฤซmฤti ar "neuzticams" un ar "neatbilstoลกs", ja neatbilst. Tas nozฤซmฤ, ka Forgejo tiks atzฤซmฤts kฤ iesลซtฤซtฤjs parakstฤซtiem iesลซtฤซjumiem, patieso iesลซtฤซtฤju iesลซtฤซjumฤ atzฤซmฤjot ar Co-authored-by: un Co-committed-by: noslฤgumu. Noklusฤjuma Forgejo atslฤgai ir jฤatbilst lietotฤjam datubฤzฤ.
+settings.wiki_delete=Izdzฤst vikivietnes datus
+settings.wiki_delete_desc=Glabฤtavas vikivietnes datu izdzฤลกana ir neatgriezeniska un nav atsaucama.
+settings.wiki_delete_notices_1=- ล ฤซ darbฤซba neatgriezeniski izdzฤsฤซs un atspฤjos glabฤtavas %s vikivietni.
+settings.confirm_wiki_delete=Izdzฤst vikivietnes datus
+settings.wiki_deletion_success=Glabฤtavas vikivietnes dati tika izdzฤsti.
+settings.delete=Izdzฤst ลกo glabฤtavu
+settings.delete_desc=Glabฤtavas izdzฤลกana ir neatgriezeniska un nav atsaucama.
settings.delete_notices_1=- ล ฤซ darbฤซba ir NEATGRIEZENISKA .
-settings.delete_notices_2=- ล ฤซ darbฤซba neatgriezeniski izdzฤsฤซs visu repozitorijฤ %s , tai skaitฤ problฤmas, komentฤrus, vikivietni un lฤซdzstrฤdnieku piesaisti.
-settings.delete_notices_fork_1=- Visi atdalฤซtie repozitoriju pฤc dzฤลกanas kฤผลซs neatkarฤซgi.
-settings.deletion_success=Repozitorijs tika izdzฤsts.
-settings.update_settings_success=Repozitorija iestatฤซjumi tika saglabฤti.
-settings.update_settings_no_unit=Repozitorijam ir jฤbลซt pieลกฤทirtฤm vismaz kฤdฤm tiesฤซbฤm.
-settings.confirm_delete=Dzฤst repozitoriju
-settings.add_collaborator=Pievienot lฤซdzstrฤdnieku
-settings.add_collaborator_success=Jauns lฤซdzstrฤdnieks tika pievienots.
-settings.add_collaborator_inactive_user=Nevar pievienot neaktฤซvu lietotฤju kฤ lฤซdzstrฤdnieku.
-settings.add_collaborator_owner=Nevar pievienot ฤซpaลกnieku kฤ lฤซdzstrฤdnieku.
-settings.add_collaborator_duplicate=Lฤซdzstrฤdnieks jau ir pievienots ลกim repozitorijam.
+settings.delete_notices_2=- ล ฤซ darbฤซba neatgriezeniski izdzฤsฤซs glabฤtavu %s , tostarp kodu, pieteikumus, piebildes, vikivietnes datus un lฤซdzdalฤซbnieku iestatฤซjumus.
+settings.delete_notices_fork_1=- Pฤc izdzฤลกanas ลกฤซs glabฤtavas atzarojumi kฤผลซs neatkarฤซgi.
+settings.deletion_success=Glabฤtava tika izdzฤsta.
+settings.update_settings_success=Glabฤtavas iestatฤซjumi tika atjauninฤti.
+settings.update_settings_no_unit=Glabฤtavฤ bลซtu jฤbลซt atฤผautai vismaz kaut kฤdai mijiedarbฤซbai.
+settings.confirm_delete=Izdzฤst glabฤtavu
+settings.add_collaborator=Pievienot lฤซdzdalฤซbnieku
+settings.add_collaborator_success=Lฤซdzdalฤซbnieks tika pievienots.
+settings.add_collaborator_inactive_user=Neaktฤซvu lietotฤju nevar pievienot kฤ lฤซdzdalฤซbnieku.
+settings.add_collaborator_owner=ฤชpaลกnieku nevar pievienot kฤ lฤซdzdalฤซbnieku.
+settings.add_collaborator_duplicate=Lฤซdzdalฤซbnieks jau ir pievienots ลกai glabฤtavai.
settings.delete_collaborator=Noลemt
-settings.collaborator_deletion=Noลemt lฤซdzstrฤdnieku
-settings.collaborator_deletion_desc=Noลemot lฤซdzstrฤdnieku, tam tiks liegta piekฤผuve ลกim repozitorijam. Vai turpinฤt?
-settings.remove_collaborator_success=Lฤซdzstrฤdnieks tika noลemts.
+settings.collaborator_deletion=Noลemt lฤซdzdalฤซbnieku
+settings.collaborator_deletion_desc=Lฤซdzdalฤซbnieka noลemลกana atsauks tฤ piekฤผuvi ลกai glabฤtavai. Turpinฤt?
+settings.remove_collaborator_success=Lฤซdzdalฤซbnieks tika noลemts.
settings.search_user_placeholder=Meklฤt lietotฤjuโฆ
-settings.org_not_allowed_to_be_collaborator=Organizฤcijas nevar tikt pievienotas kฤ lฤซdzstrฤdnieki.
-settings.change_team_access_not_allowed=Iespฤja mainฤซt komandu piekฤผuvi repozitorijam ir organizฤcijas ฤซpaลกniekam
-settings.team_not_in_organization=Komanda nav tajฤ paลกฤ organizฤcijฤ kฤ repozitorijs
+settings.org_not_allowed_to_be_collaborator=Apvienฤซbas nevar tikt pievienotas kฤ lฤซdzdalฤซbnieki.
+settings.change_team_access_not_allowed=Komandu piekฤผuves mainฤซลกana glabฤtavai ir pieejama tikai apvienฤซbas ฤซpaลกniekam
+settings.team_not_in_organization=Komanda nav tajฤ paลกฤ apvienฤซbฤ kฤ glabฤtava
settings.teams=Komandas
settings.add_team=Pievienot komandu
-settings.add_team_duplicate=Komandai jau ir piekฤผuve ลกim repozitorijam
-settings.add_team_success=Komandai tagad ir piekฤผuve ลกim repozitorijam.
+settings.add_team_duplicate=Komandai jau ir piekฤผuve glabฤtavai
+settings.add_team_success=Komandai tagad ir piekฤผuve glabฤtavai.
settings.search_team=Meklฤt komanduโฆ
-settings.change_team_permission_tip=Komandas tiesฤซbas tiek uzstฤdฤซtas komandas iestatฤซjumu lapฤ un nevar tikt individuฤli mainฤซtas katram repozitorijam atseviลกฤทi
-settings.delete_team_tip=Komandai ir piekฤผuve visiem repozitorijiem un tฤ nevar tikt noลemta individuฤli
-settings.remove_team_success=Komandas piekฤผuve ลกim repozitorijam ir noลemta.
-settings.add_webhook=Pievienot tฤซmekฤผa ฤฤทi
-settings.add_webhook.invalid_channel_name=Tฤซmekฤผa ฤฤทa kanฤla nosaukums nevar bลซt tukลกs vai saturฤt tikai # simbolu.
-settings.hooks_desc=Tฤซmekฤผa ฤฤทi ฤผauj paziลot ฤrฤjiem servisiem par noteiktiem notikumiem, kas notiek Forgejo. Kad iestฤsies kฤds notikums, katram ฤrฤjฤ servisa URL tiks nosลซtฤซts POST pieprasฤซjums. Lai uzzinฤtu sฤซkฤk skatieties tฤซmekฤผa ฤฤทu rokasgrฤmatฤ .
-settings.webhook_deletion=Noลemt tฤซmekฤผa ฤฤทi
-settings.webhook_deletion_desc=Noลemot tฤซmekฤผa ฤฤทi, tiks dzฤsti visi tฤ iestatฤซjumi un piegฤdes vฤsture. Vai turpinฤt?
-settings.webhook_deletion_success=Tฤซmekฤผa ฤฤทis tika noลemts.
-settings.webhook.test_delivery=Testa piegฤde
-settings.webhook.test_delivery_desc=Veikt viltus push-notikuma piegฤdi, lai notestฤtu Jลซsu tฤซmekฤผa ฤฤทa iestatฤซjumus.
-settings.webhook.test_delivery_desc_disabled=Lai pฤrbaudฤซtu ลกo tฤซmekฤผa ฤฤทi ar neฤซstu notikumu, tas ir jฤiespฤjo.
+settings.change_team_permission_tip=Komandas atฤผauja ir iestatฤซta komandas iestatฤซjumu lapฤ un nav mainฤma katrai glabฤtavai atseviลกฤทi
+settings.delete_team_tip=Komandai ir piekฤผuve visฤm glabฤtavฤm, un to nevar noลemt
+settings.remove_team_success=Tika noลemta komandas piekฤผuve glabฤtavai.
+settings.add_webhook=Pievienot tฤซmekฤผa aizฤทeri
+settings.add_webhook.invalid_channel_name=Tฤซmekฤผa aizฤทeres plลซsmas nosaukums nevar bลซt tukลกs vai saturฤt tikai rakstzฤซmi #.
+settings.hooks_desc=Tฤซmekฤผa aizฤทeres automฤtiski sลซta serverim HTTP POST pieprasฤซjumus, kad iedarbojas noteikti Forgejo notikumi. Vairฤk ir lasฤms tฤซmekฤผa aizฤทeru rokasgrฤmatฤ .
+settings.webhook_deletion=Noลemt tฤซmekฤผa aizฤทeri
+settings.webhook_deletion_desc=Tฤซmekฤผa aizฤทeres noลemลกana izdzฤลก tฤs iestatฤซjumus un piegฤdes vฤsturi. Turpinฤt?
+settings.webhook_deletion_success=Tฤซmekฤผa aizฤทere tika noลemta.
+settings.webhook.test_delivery=Pฤrbaudฤซt piegฤdi
+settings.webhook.test_delivery_desc=Pฤrbaudฤซt ลกo tฤซmekฤผa aizฤทeri ar neฤซstu notikumu.
+settings.webhook.test_delivery_desc_disabled=Lai pฤrbaudฤซtu ลกo tฤซmekฤผa aizฤทeri ar neฤซstu notikumu, tฤ ir jฤiespฤjo.
settings.webhook.request=Pieprasฤซjums
settings.webhook.response=Atbilde
settings.webhook.headers=Galvenes
settings.webhook.payload=Saturs
settings.webhook.body=Saturs
-settings.webhook.replay.description=Izpildฤซt atkฤrtoti ลกo tฤซmekฤผa ฤฤทi.
-settings.webhook.replay.description_disabled=Lai atkฤrtoti izpildฤซtu ลกo tฤซmekฤผa ฤฤทi, tas ir jฤiespฤjo.
-settings.webhook.delivery.success=Notikums tika veiksmฤซgi pievienots piegฤdes rindai. Var paiet vairฤkas sekundes lฤซdz tas parฤdฤs piegฤdes vฤsturฤ.
-settings.githooks_desc=Git ฤฤทus apstrฤdฤ pats Git. Jลซs varat labot atbalstฤซto ฤku failus sarakstฤ zemฤk, lai veiktu pielฤgotas darbฤซbas.
-settings.githook_edit_desc=Ja ฤฤทis nav aktฤซvs, tiks attฤlots piemฤrs kฤ to izmantot. Atstฤjot ฤฤทa saturu tukลกu, tas tiks atspฤjots.
-settings.githook_name=ฤฤทa nosaukums
-settings.githook_content=ฤฤทa saturs
-settings.update_githook=Labot ฤฤทi
-settings.add_webhook_desc=Uz norฤdฤซto URL tiks nosลซtฤซts POST
pieprasฤซjums ar notikuma datiem. Detalizฤtฤku informฤciju ir iespฤjams uzzinฤt tฤซmekฤผa ฤฤทu rokasgrฤmatฤ .
+settings.webhook.replay.description=Atkฤrtoti izpildฤซt ลกo tฤซmekฤผa aizฤทeri.
+settings.webhook.replay.description_disabled=Lai atkฤrtoti izpildฤซtu ลกo tฤซmekฤผa aizฤทeri, tฤ ir jฤiespฤjo.
+settings.webhook.delivery.success=Notikums tika sekmฤซgi pievienots piegฤdes rindsarakstam. Var paiet vairฤkas sekundes, lฤซdz tas parฤdฤs piegฤdes vฤsturฤ.
+settings.githooks_desc=Git aizฤทeres apstrฤdฤ pats Git. Zemฤk var labot aizฤทeru datnes, lai uzstฤdฤซtu pielฤgotas darbฤซbas.
+settings.githook_edit_desc=Ja aizฤทere ir bezdarbฤซga, tiks parฤdฤซts piemฤra saturs. Satura atstฤลกana bez vฤrtฤซbas atspฤjos ลกo aizฤทeri.
+settings.githook_name=Aizฤทeres nosaukums
+settings.githook_content=Aizฤทeres saturs
+settings.update_githook=Atjauninฤt aizฤทeri
+settings.add_webhook_desc=Forgejo uz mฤrฤทa URL nosลซtฤซs POST
pieprasฤซjumus ar noteiktu satura veidu. Vairฤk ir lasฤmstฤซmekฤผa aizฤทeru rokasgrฤmatฤ .
settings.payload_url=Saลฤmฤja URL
settings.http_method=HTTP metode
-settings.content_type=POST satura tips
+settings.content_type=POST satura veids
settings.secret=Noslฤpums
settings.slack_username=Lietotฤjvฤrds
settings.slack_icon_url=Ikonas URL
settings.slack_color=Krฤsa
settings.discord_username=Lietotฤjvฤrds
settings.discord_icon_url=Ikonas URL
-settings.event_desc=Izsaukt notikumiem:
-settings.event_push_only=Izmaiลu nosลซtฤซลกanas notikumi
-settings.event_send_everything=Visus notikumus
-settings.event_choose=Izvฤlฤties notikumusโฆ
-settings.event_header_repository=Repozitorija notikumi
+settings.event_desc=Iedarboties uz:
+settings.event_push_only=Aizgฤdฤลกanas notikumi
+settings.event_send_everything=Visiem notikumiem
+settings.event_choose=Pielฤgoti notikumiโฆ
+settings.event_header_repository=Glabฤtavas notikumi
settings.event_create=Izveidot
-settings.event_create_desc=Atzara vai taga izveidoลกana.
-settings.event_delete=Dzฤst
-settings.event_delete_desc=Atzars vai tags izdzฤsts.
-settings.event_fork=Atdalฤซts
-settings.event_fork_desc=Repozitorijs atdalฤซts.
+settings.event_create_desc=Zars vai birka izveidota.
+settings.event_delete=Izdzฤst
+settings.event_delete_desc=Zars vai birka izdzฤsta.
+settings.event_fork=Izveidot atzarojumu
+settings.event_fork_desc=Izveidots glabฤtavas atzarojums.
settings.event_wiki=Vikivietni
settings.event_wiki_desc=Vikivietnes lapa izveidota, pฤrsaukta, labota vai dzฤsta.
settings.event_release=Laidiens
-settings.event_release_desc=Publicฤts, atjaunots vai dzฤsts laidiens repozitorijฤ.
-settings.event_push=Izmaiลu nosลซtฤซลกana
-settings.event_push_desc=Git izmaiลu nosลซtฤซลกana uz repozitoriju.
-settings.event_repository=Repozitorijs
-settings.event_repository_desc=Repozitorijs izveidots vai dzฤsts.
-settings.event_header_issue=Problฤmu notikumi
-settings.event_issues=Problฤmas
-settings.event_issues_desc=Problฤma atvฤrta, aizvฤrta, atkฤrtoti atvฤrta vai mainฤซta.
-settings.event_issue_assign=Problฤmas atbildฤซgie
-settings.event_issue_assign_desc=Problฤmai pieลกฤทirti vai noลemti atbildฤซgie.
-settings.event_issue_label=Problฤmu etiฤทetes
-settings.event_issue_label_desc=Problฤmai pievienotas vai noลemtas etiฤทetes.
-settings.event_issue_milestone=Problฤmas atskaites punkts
-settings.event_issue_milestone_desc=Problฤmai pievienots vai noลemts atskaites punkts.
-settings.event_issue_comment=Problฤmas komentฤrs
-settings.event_issue_comment_desc=Problฤmas komentฤrs pievienots, labots vai dzฤsts.
+settings.event_release_desc=Laists klajฤ, atjauninฤts vai izdzฤsts laidiens glabฤtavฤ.
+settings.event_push=Aizgฤdฤลกana
+settings.event_push_desc=Git aizgฤdฤลกana uz glabฤtavu.
+settings.event_repository=Glabฤtava
+settings.event_repository_desc=Izveidota vai izdzฤsta glabฤtava.
+settings.event_header_issue=Pieteikumu notikumi
+settings.event_issues=Izmaiลas
+settings.event_issues_desc=Pieteikums atvฤrts, aizvฤrts, atkฤrtoti atvฤrts vai labots.
+settings.event_issue_assign=Pieลกฤทฤซrums
+settings.event_issue_assign_desc=Pieteikumam ir norฤdฤซts vai noลemts atbildฤซgais.
+settings.event_issue_label=Iezฤซmes
+settings.event_issue_label_desc=Pievienotas vai noลemtas pieteikuma iezฤซmes.
+settings.event_issue_milestone=Atskaites punkti
+settings.event_issue_milestone_desc=Pievienots, noลemts vai izmainฤซts atskaites punkts.
+settings.event_issue_comment=Piebildes
+settings.event_issue_comment_desc=Izveidota, labota vai izdzฤsta pieteikuma piebilde.
settings.event_header_pull_request=Izmaiลu pieprasฤซjuma notikumi
-settings.event_pull_request=Izmaiลu pieprasฤซjums
+settings.event_pull_request=Izmaiลas
settings.event_pull_request_desc=Izmaiลu pieprasฤซjums atvฤrts, aizvฤrts, atkฤrtoti atvฤrts vai mainฤซts.
-settings.event_pull_request_assign=Izmaiลu pieprasฤซjuma atbildฤซgie
+settings.event_pull_request_assign=Pieลกฤทฤซrums
settings.event_pull_request_assign_desc=Izmaiลu pieprasฤซjumam pieลกฤทirti vai noลemti atbildฤซgie.
-settings.event_pull_request_label=Izmaiลu pieprasฤซjuma etiฤทetes
-settings.event_pull_request_label_desc=Izmaiลu pieprasฤซjumam pievienotas vai noลemtas etiฤทetes.
-settings.event_pull_request_milestone=Izmaiลu pieprasฤซjuma atskaites punkts
-settings.event_pull_request_milestone_desc=Izmaiลu pieprasฤซjumam pievienots vai noลemts atskaites punkts.
-settings.event_pull_request_comment=Izmaiลu pieprasฤซjuma komentฤrs
-settings.event_pull_request_comment_desc=Izmaiลu pieprasฤซjuma komentฤrs pievienots, labots vai dzฤsts.
-settings.event_pull_request_review=Izmaiลu pieprasฤซjums recenzฤts
-settings.event_pull_request_review_desc=Izmaiลu pieprasฤซjums apstiprinฤts, noraidฤซts vai atstฤts komentฤrs.
-settings.event_pull_request_sync=Izmaiลu pieprasฤซjums sinhronizฤts
-settings.event_pull_request_sync_desc=Izmaiลu pieprasฤซjums sinhronizฤts.
-settings.event_pull_request_review_request=Izmaiลu pieprasฤซjuma recenzฤซju pieprasฤซลกana
-settings.event_pull_request_review_request_desc=Izmaiลu pieprasฤซjuma recenzฤซjas pieprasฤซjums vai recenzijas pieprasฤซjuma atcelลกana.
-settings.event_pull_request_approvals=Izmaiลu pieprasฤซjuma apstiprinฤลกana
-settings.event_pull_request_merge=Izmaiลu pieprasฤซjuma sapludinฤลกana
+settings.event_pull_request_label=Iezฤซmes
+settings.event_pull_request_label_desc=Izmaiลu pieprasฤซjuma iezฤซmes tika pievienotas vai noลemtas.
+settings.event_pull_request_milestone=Atskaites punkti
+settings.event_pull_request_milestone_desc=Atskaites punkts pievienots, noลemts vai mainฤซts.
+settings.event_pull_request_comment=Piebildes
+settings.event_pull_request_comment_desc=Izmaiลu pieprasฤซjuma piebilde izveidota, labota vai izdzฤsta.
+settings.event_pull_request_review=Izskatฤซลกanas
+settings.event_pull_request_review_desc=Izmaiลu pieprasฤซjums apstiprinฤts, noraidฤซts vai pievienota izskatฤซลกanas piebilde.
+settings.event_pull_request_sync=Sinhronizฤts
+settings.event_pull_request_sync_desc=Zars automฤtiski atjauninฤts ar mฤrฤทa zaru.
+settings.event_pull_request_review_request=Izskatฤซลกanas pieprasฤซjumi
+settings.event_pull_request_review_request_desc=Pieprasฤซta izmaiลu pieprasฤซjuma izskatฤซลกana vai noลemts izskatฤซลกanas pieprasฤซjums.
+settings.event_pull_request_approvals=Izmaiลu pieprasฤซjuma apstiprinฤjumi
+settings.event_pull_request_merge=Izmaiลu pieprasฤซjuma iekฤผauลกana
settings.event_package=Pakotne
-settings.event_package_desc=Repozitorijฤ izveidota vai dzฤsta pakotne.
-settings.branch_filter=Atzaru filtrs
-settings.branch_filter_desc=Atzaru ierobeลพojumi izmaiลu iesลซtฤซลกanas, zaru izveidoลกanas vai dzฤลกanas notikumiem, izmantojot, glob ลกablonu. Ja norฤdฤซts tukลกs vai *
, tiks nosลซtฤซti notikumi no visiem zariem. Skatieties github.com/gobwas/glob pieraksta dokumentฤciju. Piemฤrs: master
, {master,release*}
.
-settings.authorization_header=Autorizฤcijas galvene
-settings.authorization_header_desc=Tiks iekฤผauta kฤ autorizฤcijas galvenei pieprasฤซjumiem, ja ir norฤdฤซta. Piemฤram: %s.
+settings.event_package_desc=Izveidota vai izdzฤsta pakotne glabฤtavฤ.
+settings.branch_filter=Zaru atlase
+settings.branch_filter_desc=Zaru baltais saraksts aizgฤdฤลกanas, zaru izveidoลกanas un izdzฤลกanas notikumiem, kas ir norฤdฤซts kฤ glob paraugs. Ja tukลกs vai *
, tiks nosลซtฤซti visu zaru notikumi. Par pierakstu skatฤซt%[2]s dokumentฤcijฤ. Piemฤri: main
, {main,release*}
.
+settings.authorization_header=Pilnvaroลกanas galvene
+settings.authorization_header_desc=Tiks iekฤผauta pieprasฤซjumos kฤ pilnvaroลกanas galvene, ja ir norฤdฤซta. Piemฤram: %s.
settings.active=Aktฤซvs
-settings.active_helper=Informฤcija par notikumiem tiks nosลซtฤซta uz ลกo tฤซmekฤผa ฤฤทa URL.
-settings.add_hook_success=Tฤซmekฤผa ฤฤทis tika pievienots.
-settings.update_webhook=Mainฤซt tฤซmekฤผa ฤฤทi
-settings.update_hook_success=Tฤซmekฤผa ฤฤทis tika atjaunots.
-settings.delete_webhook=Noลemt tฤซmekฤผa ฤฤทi
-settings.recent_deliveries=Pฤdฤjฤs piegฤdes
-settings.hook_type=ฤฤทa veids
+settings.active_helper=Informฤcija par iedarbinฤtajiem notikumiem tiks nosลซtฤซta uz ลกo tฤซmekฤผa aizฤทeres URL.
+settings.add_hook_success=Tฤซmekฤผa aizฤทere tika pievienota.
+settings.update_webhook=Atjauninฤt tฤซmekฤผa aizฤทeri
+settings.update_hook_success=Tฤซmekฤผa aizฤทere tika atjauninฤta.
+settings.delete_webhook=Noลemt tฤซmekฤผa aizฤทeri
+settings.recent_deliveries=Nesenas piegฤdes
+settings.hook_type=Aizฤทeres veids
settings.slack_token=Pilnvara
settings.slack_domain=Domฤns
settings.slack_channel=Kanฤls
-settings.add_web_hook_desc=Integrฤt %s repozitorijฤ.
+settings.add_web_hook_desc=Iekฤผaut %s savฤ glabฤtavฤ.
settings.web_hook_name_gitea=Gitea
settings.web_hook_name_forgejo = Forgejo
settings.web_hook_name_gogs=Gogs
@@ -2252,7 +2419,7 @@ settings.web_hook_name_dingtalk=DingTalk
settings.web_hook_name_telegram=Telegram
settings.web_hook_name_matrix=Matrix
settings.web_hook_name_msteams=Microsoft Teams
-settings.web_hook_name_feishu=Feishu / Lark Suite
+settings.web_hook_name_feishu=Feishu/Lark Suite
settings.web_hook_name_feishu_only =Feishu
settings.web_hook_name_larksuite_only =Lark Suite
settings.web_hook_name_wechatwork=WeCom (Wechat Work)
@@ -2260,470 +2427,650 @@ settings.web_hook_name_packagist=Packagist
settings.packagist_username=Packagist lietotฤjvฤrds
settings.packagist_api_token=API pilnvara
settings.packagist_package_url=Packagist pakotnes URL
-settings.deploy_keys=Izvietot atslฤgas
+settings.deploy_keys=Izvietoลกanas atslฤgas
settings.add_deploy_key=Pievienot izvietoลกanas atslฤgu
-settings.deploy_key_desc=Izvietoลกanas atslฤgฤm ir lasฤซลกanas piekฤผuve repozitorijam.
+settings.deploy_key_desc=Izvietoลกanas atslฤgฤm ir lasฤซลกanas piekฤผuve glabฤtavai.
settings.is_writable=Iespฤjot rakstฤซลกanas piekฤผuvi
-settings.is_writable_info=Atฤผaut ลกai izvietoลกanas atslฤgai nosลซtฤซt izmaiลas uz repozitoriju.
+settings.is_writable_info=Atฤผaut ลกai izvietoลกanas atslฤgai aizgฤdฤt uz glabฤtavu.
settings.no_deploy_keys=Pagaidฤm nav nevienas izvietoลกanas atslฤgas.
settings.title=Virsraksts
settings.deploy_key_content=Saturs
settings.key_been_used=Izvietoลกanas atslฤga ar ลกฤdu saturu jau ir pievienota.
-settings.key_name_used=Izvietoลกanas atslฤga ar ลกฤdu nosaukumu jau eksistฤ.
+settings.key_name_used=Jau pastฤv izvietoลกanas atslฤga ar tฤdu paลกu nosaukumu.
settings.add_key_success=Izvietoลกanas atslฤga "%s" tika pievienota.
settings.deploy_key_deletion=Noลemt izvietoลกanas atslฤgu
-settings.deploy_key_deletion_desc=Noลemot izvietoลกanas atslฤgu, tai tiks liegta piekฤผuve ลกim repozitorija. Vai turpinฤt?
+settings.deploy_key_deletion_desc=Izvietoลกanas atslฤgas noลemลกana atsauks tฤs piekฤผuvi ลกai glabฤtavai. Turpinฤt?
settings.deploy_key_deletion_success=Izvietoลกanas atslฤga tika noลemta.
-settings.branches=Atzari
-settings.protected_branch=Atzaru aizsargฤลกana
-settings.protected_branch.save_rule=Saglabฤt noteikumu
-settings.protected_branch.delete_rule=Dzฤst noteikumu
+settings.branches=Zari
+settings.protected_branch=Zaru aizsargฤลกana
+settings.protected_branch.save_rule=Saglabฤt kฤrtulu
+settings.protected_branch.delete_rule=Izdzฤst kฤrtulu
settings.protected_branch_can_push=Atฤผaut izmaiลu nosลซtฤซลกanu?
settings.protected_branch_can_push_yes=Jลซs varat nosลซtฤซt izmaiลas
settings.protected_branch_can_push_no=Jลซs nevarat nosลซtฤซt izmaiลas
-settings.branch_protection=Atzara aizsardzฤซba atzaram '%s '
+settings.branch_protection=Zara "%s " aizsargฤลกanas kฤrtulas
settings.protect_this_branch=Iespฤjot atzara aizsardzฤซbu
settings.protect_this_branch_desc=Neฤผauj atzara dzฤลกanu, kฤ arฤซ ierobeลพo izmaiลu iesลซtฤซลกanu un sapludinฤลกanu ลกajฤ atzarฤ.
-settings.protect_disable_push=Neฤผaut iesลซtฤซt izmaiลas
-settings.protect_disable_push_desc=Izmaiลu iesลซtฤซลกana ลกajฤ atzarฤ netiks atฤผauta.
-settings.protect_enable_push=Atฤผaut iesลซtฤซt izmaiลas
-settings.protect_enable_push_desc=Ikviens, kam ir rakstฤซลกanas tiesฤซbas uz ลกo repozitoriju, varฤs iesลซtฤซt izmaiลas ลกajฤ atzarฤ (piespiedu izmaiลu iesลซtฤซลกanas netiks atฤผauta).
-settings.protect_enable_merge=Iespฤjot sapludinฤลกanu
-settings.protect_enable_merge_desc=Ikviens ar rakstฤซลกanas tiesฤซbฤm varฤst sapludinฤt izmaiลu pieprasฤซjumus ลกajฤ atzarฤ.
-settings.protect_whitelist_committers=Atฤผaut iesลซtฤซt izmaiลas norฤdฤซtajiem lietotฤjiem vai komandฤm
-settings.protect_whitelist_committers_desc=Tikai norฤdฤซtiem lietotฤji vai komandas varฤs iesลซtฤซt izmaiลas ลกajฤ atzarฤ (piespiedu izmaiลu iesลซtฤซลกanas netiks atฤผauta).
-settings.protect_whitelist_deploy_keys=Atฤผaut izvietoลกanas atslฤgฤm ar rakstฤซลกanas tiesฤซbฤm nosลซtฤซt izmaiลas.
-settings.protect_whitelist_users=Lietotฤji, kas var veikt izmaiลu nosลซtฤซลกanu:
+settings.protect_disable_push=Atspฤjot aizgฤdฤลกanu
+settings.protect_disable_push_desc=Aizgฤdฤลกana ลกajฤ zarฤ netiks ฤผauta.
+settings.protect_enable_push=Iespฤjot aizgฤdฤลกanu
+settings.protect_enable_push_desc=Ikvienam ar rakstฤซลกanas piekฤผuvi bลซs ฤผauts aizgฤdฤt izmaiลas uz ลกo zaru (bet ne uzspiesta aizgฤdฤลกana).
+settings.protect_enable_merge=Iespฤjot apvienoลกanu
+settings.protect_enable_merge_desc=Ikvienam ar rakstฤซลกanas tiesฤซbฤm bลซs ฤผauts apvienot izmaiลu pieprasฤซjumus ar ลกo zaru.
+settings.protect_whitelist_committers=Ierobeลพotas aizgฤdฤลกanas izลฤmumi
+settings.protect_whitelist_committers_desc=Tikai norฤdฤซtajiem lietotฤjiem vai komandฤm bลซs ฤผauts aizgฤdฤt izmaiลas ลกajฤ zarฤ (bet ne uzspiesta aizgฤdฤลกana).
+settings.protect_whitelist_deploy_keys=Atฤผaut izvietoลกanas atslฤgฤm ar rakstฤซลกanas piekฤผuvi aizgฤdฤt izmaiลas.
+settings.protect_whitelist_users=Lietotฤji, kuriem ir ฤผauts aizgฤdฤt izmaiลas
settings.protect_whitelist_search_users=Meklฤt lietotฤjusโฆ
-settings.protect_whitelist_teams=Komandas, kas var veikt izmaiลu nosลซtฤซลกanu:
+settings.protect_whitelist_teams=Komandas, kurฤm ir ฤผauts aizgฤdฤt izmaiลas
settings.protect_whitelist_search_teams=Meklฤt komandasโฆ
-settings.protect_merge_whitelist_committers=Iespฤjot sapludinฤลกanas ierobeลพoลกanu
-settings.protect_merge_whitelist_committers_desc=Atฤผaut tikai noteiktiem lietotฤjiem vai komandฤm sapludinฤt izmaiลu pieprasฤซjumus ลกajฤ atzarฤ.
-settings.protect_merge_whitelist_users=Lietotฤji, kas var veikt izmaiลu sapludinฤลกanu:
-settings.protect_merge_whitelist_teams=Komandas, kas var veikt izmaiลu sapludinฤลกanu:
-settings.protect_check_status_contexts=Iespฤjot statusu pฤrbaudi
-settings.protect_status_check_patterns=Statusa pฤrbaudes ลกabloni:
-settings.protect_status_check_patterns_desc=Norฤdiet ลกablonus, kurฤm statusa pฤrbaudฤm ir jฤatbilst pirms atzaru iespฤjams sapludinฤt ลกajฤ atzarฤ, kas atbilst ลกim nosacฤซjumam. Katru ลกablonu norฤdฤซt savฤ rindฤ, tie nevar bลซt tukลกi.
-settings.protect_check_status_contexts_desc=Nepiecieลกamas veiksmฤซgas statusa pฤrbaudes pirms sapludinฤลกanas. Izvฤlieties, kurฤm statusa pฤrbaudฤm ir jฤizpildฤs pirms ir iespejams tฤs sapludinฤt. Ja iespฤjots, tad revฤซzijas sฤkotnฤji jฤnosลซta uz atseviลกฤทu atzaru, pฤc kฤ var tikt saplusinฤtas vai tieลกi nosลซtฤซtas uz atzariem, kas atbildst veiksmฤซgฤm norฤdฤซtajฤm stautsa pฤrbaudฤm. Ja konteksts nav norฤdฤซts, pฤdฤjai revฤซzijai ir jฤbลซt veiksmฤซga neatkarฤซgi no konteksta.
-settings.protect_check_status_contexts_list=Statusu pฤrbaudes, kas ลกim repozitorijam bijuลกas pฤdฤjฤs nedฤฤผas laikฤ
+settings.protect_merge_whitelist_committers=Iespฤjot apvienoลกanas atฤผauลกanas sarakstu
+settings.protect_merge_whitelist_committers_desc=Atฤผaut tikai noteiktiem lietotฤjiem vai komandฤm apvienot izmaiลu pieprasฤซjumus ar ลกo zaru.
+settings.protect_merge_whitelist_users=Lietotฤji, kuri var veikt apvienoลกanu
+settings.protect_merge_whitelist_teams=Komandas, kuras var veikt apvienoลกanu
+settings.protect_check_status_contexts=Iespฤjot stฤvokฤผa pฤrbaudi
+settings.protect_status_check_patterns=Stฤvokฤผa pฤrbauลพu paraugi
+settings.protect_status_check_patterns_desc=Jฤievada paraugi, lai norฤdฤซtu, kurฤm stฤvokฤผa pฤrbaudฤm sekmฤซgi jฤizpildฤs, pirms zari var tikt iekฤผauti zarฤ, kas atbilst ลกai kฤrtulai. Katrฤ rindฤ ir norฤdฤms viens paraugs. Paraugi nevar bลซt tukลกi.
+settings.protect_check_status_contexts_desc=Pirms apvienoลกanas ir nepiecieลกama sekmฤซga stฤvokฤผa pฤrbauลพu izpilde. Kad iespฤjots, iesลซtฤซjumiem vispirms jฤbลซt aizgฤdฤtiem citฤ zarฤ, tad pฤc stฤvokฤผa pฤrbauลพu sekmฤซgas izpildes iekฤผautiem vai aizgฤdฤtiem tieลกi zarฤ, kas atbilst ลกai kฤrtulai. Ja nav atbilstoลกu kontekstu, pฤdฤjam iesลซtฤซjumam jฤbลซt sekmฤซgam neatkarฤซgi no konteksta.
+settings.protect_check_status_contexts_list=Stฤvokฤผa pฤrbaudes, kas ลกajฤ glabฤtavฤ atrastas pฤdฤjฤs nedฤฤผas laikฤ
settings.protect_status_check_matched=Atbilst
-settings.protect_invalid_status_check_pattern=Kฤผลซdains statusa pฤrbaudes ลกablons: "%s".
-settings.protect_no_valid_status_check_patterns=Nav korekta statusa pฤrbaudes ลกablona.
-settings.protect_required_approvals=Vajadzฤซgi apstiprinฤjumi:
-settings.protect_required_approvals_desc=Atฤผaut sapludinฤt izmaiลu pieprasฤซjumu tikai ar pietiekamu skaitu pozitฤซvu recenziju.
+settings.protect_invalid_status_check_pattern=Nederฤซgs stฤvokฤผa pฤrbaudes paraugs: "%s".
+settings.protect_no_valid_status_check_patterns=Nav derฤซgu stฤvokฤผa pฤrbauลพu paraugu.
+settings.protect_required_approvals=Nepiecieลกamie apstiprinฤjumi
+settings.protect_required_approvals_desc=Atฤผaut iekฤผaut izmaiลu pieprasฤซjumu tikai ar pietiekamu daudzumu apstiprinoลกu izskatฤซลกanu.
settings.protect_approvals_whitelist_enabled=Ierobeลพot apstiprinฤjumus norฤdฤซtajiem lietotฤjiem vai komandฤm
-settings.protect_approvals_whitelist_enabled_desc=Tikai recenzijas no ลกiem lietotฤjiem vai komandฤm tiks skaitฤซtas, lai pฤrbaudฤซtu nepiecieลกamo apstiprinฤjumu skaitu. Bez ลกฤซs pazฤซmes, recenzijas no ikviena lietotฤja, kam ir rakstฤซลกanas piekฤผuve, tiks skaitฤซtas, lai pฤrbaudฤซtu nepiecieลกamo apstiprinฤjumu skaitu.
-settings.protect_approvals_whitelist_users=Lietotฤji, kas var veikt recenzijas:
-settings.protect_approvals_whitelist_teams=Komandas, kas var veikt recenzijas:
-settings.dismiss_stale_approvals=Pieprasฤซt apstiprinฤjumus jaunฤkajฤm izmaiลฤm
-settings.dismiss_stale_approvals_desc=Kad tiek iesลซtฤซtas jaunas revฤซzijas, kas izmaina izmaiลu pieprasฤซjuma saturu, iepriekลกฤjie apstiprinฤjumi tiks atzฤซmฤti kฤ novecojuลกi un bลซs nepiecieลกams apstiprinฤt tos atkฤroti.
-settings.require_signed_commits=Pieprasฤซt parakstฤซtas revฤซzijas
-settings.require_signed_commits_desc=Noraidฤซt iesลซtฤซtฤs izmaiลas ลกim atzaram, ja tฤs nav parakstฤซtas vai nav iespฤjams pฤrbaudฤซt.
-settings.protect_branch_name_pattern=Aizsargฤtฤ zara ลกablons
-settings.protect_branch_name_pattern_desc=Aizsargฤto atzaru nosaukumu ลกabloni. ล ablonu pierakstu skatฤซt dokumentฤcijฤ . Piemฤri: main, release/**
-settings.protect_patterns=ล abloni
-settings.protect_protected_file_patterns=Aizsargฤto failu ลกablons (vairฤkus var norฤdฤซt atdalot ar semikolu ';'):
-settings.protect_protected_file_patterns_desc=Aizsargฤtie faili, ko nevar mainฤซt, pat ja lietotฤjam ir tiesฤซbas veidot jaunus, labot vai dzฤst failus ลกajฤ atzarฤ. Vairฤkus ลกablons ir iespฤjams norฤdฤซt atdalot tos ar semikolu (';'). Sฤซkฤka informฤcija par ลกabloniem pieejama github.com/gobwas/glob dokumentฤcijฤ. Piemฤram, .drone.yml
, /docs/**/*.txt
.
-settings.protect_unprotected_file_patterns=Neaizsargฤto failu ลกablons (vairฤkus var norฤdฤซt atdalot ar semikolu ';'):
-settings.protect_unprotected_file_patterns_desc=Neaizsargฤtie faili, ko iespฤjams mainฤซt apejot iesลซtฤซลกanas ierobeลพojumus, ja lietotฤjam ir tiesฤซbas iesลซtฤซt izmaiลas ลกajฤ atzarฤ. Vairฤkus ลกablons ir iespฤjams norฤdฤซt atdalot tos ar semikolu (';'). Sฤซkฤka informฤcija par ลกabloniem pieejama github.com/gobwas/glob dokumentฤcijฤ. Piemฤram, .drone.yml
, /docs/**/*.txt
.
+settings.protect_approvals_whitelist_enabled_desc=Tikai iepriekลกnorฤdฤซtiem lietotฤju vai komandu izskatฤซลกanas tiks ieskaitฤซtas nepiecieลกamo apstiprinฤjumu skaitฤ. Bez iepriekลกnorฤdฤซta apstiprinฤjumu izskatฤซtฤju saraksta izskatฤซลกanas no ikviena, kam ir rakstฤซลกanas piekฤผuve, tiks ieskaitฤซtas nepiecieลกamo apstiprinฤjumu skaitฤ.
+settings.protect_approvals_whitelist_users=Lietotฤji, kas var veikt izskatฤซลกanu
+settings.protect_approvals_whitelist_teams=Komandas, kas var veikt izskatฤซลกanu
+settings.dismiss_stale_approvals=Atmest novecojuลกus apstiprinฤjumus
+settings.dismiss_stale_approvals_desc=Kad zarฤ tiek aizgฤdฤti jauni iesลซtฤซjumi, kas izmaina izmaiลu pieprasฤซjuma saturu, iepriekลกฤjie apstiprinฤjumi tiks atcelti.
+settings.require_signed_commits=Pieprasฤซt parakstฤซtus iesลซtฤซjumus
+settings.require_signed_commits_desc=Noraidฤซt aizgฤdฤลกanu uz ลกo zaru, ja iesลซtฤซjumi nav parakstฤซti vai apliecinฤmi.
+settings.protect_branch_name_pattern=Aizsargฤtฤ zara nosaukuma paraugs
+settings.protect_branch_name_pattern_desc=Aizsargฤto zaru nosaukumu paraugi. Paraugu pierakstu skatฤซt dokumentฤcijฤ . Piemฤri: main, release/**
+settings.protect_patterns=Paraugi
+settings.protect_protected_file_patterns=Aizsargฤto datลu paraugs (vairฤkus atdala ar semikolu ";")
+settings.protect_protected_file_patterns_desc=Aizsargฤtฤs datnes nav ฤผauts tieลกฤ veidฤ mainฤซt, pat ja lietotฤjam ลกajฤ zarฤ ir tiesฤซbas pievienot, labot vai izdzฤst datnes. Vairฤkus paraugus var atdalฤซt ar semikolu (";"). Paraugu pieraksts ir skatฤms %[2]s dokumentฤcijฤ. Piemฤri: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns=Neaizsargฤto datลu paraugs (vairฤkus atdala ar semikolu ";")
+settings.protect_unprotected_file_patterns_desc=Neaizsargฤtฤs datnes, kuras ir ฤผauts izmainฤซt tieลกฤ veidฤ, apejot aizgฤdฤลกanas ierobeลพojumu, ja lietotฤjam ir rakstฤซลกanas piekฤผuve. Vairฤki paraugi ir atdalฤmi ar semikolu (";"). Paraugu pierakstu skatฤซt %[2]s dokumentฤcijฤ. Piemฤri: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=Iespฤjot aizsargฤลกanu
settings.delete_protected_branch=Atspฤjot aizsargฤลกanu
-settings.update_protect_branch_success=Atzara aizsardzฤซbas nosacฤซjums "%s" tika saglabฤta.
-settings.remove_protected_branch_success=Atzara aizsardzฤซbas nosacฤซjums "%s" tika noลemts.
-settings.remove_protected_branch_failed=Neizdevฤs izdzฤst atzara aizsardzฤซbas nosacฤซjumu "%s".
-settings.protected_branch_deletion=Atspฤjot atzara aizsardzฤซbu
-settings.protected_branch_deletion_desc=Atspฤjojot atzara aizsardzฤซbu, ฤผaus lietotฤjiem ar rakstฤซลกanas tiesฤซbฤm nosลซtฤซt izmaiลas uz atzaru. Vai turpinฤt?
-settings.block_rejected_reviews=Neฤผaut sapludinฤt izmaiลu pieprasฤซjumus, kam ir pieprasฤซtas izmaiลas
-settings.block_rejected_reviews_desc=Sapludinฤลกana nebลซs iespฤjama, kad ir pieprasฤซtas izmaiลas, pat ja ir nepiecieลกamais apstiprinฤjumu skaits.
-settings.block_on_official_review_requests=Bloฤทฤt sapludinฤลกanu, ja ir oficiฤlas recenzijas pieprasฤซtฤs izmaiลas
-settings.block_on_official_review_requests_desc=Sapludinฤลกana nebลซs iespฤjama, ja ir pieprasฤซtas oficiฤlas recenzijas izmaiลas, pat ja ir pietiekoลกs apstiprinฤjumu skaits.
-settings.block_outdated_branch=Bloฤทฤt sapludinฤลกanau, ja izmaiลu pieprasฤซjums ir novecojis
-settings.block_outdated_branch_desc=Sapludinฤลกana nebลซs pieejama, ja atzars bลซs atpalicis no bฤzes atzara.
-settings.default_branch_desc=Norฤdiet noklusฤto repozitorija atzaru izmaiลu pieprasฤซjumiem un koda revฤซzijฤm:
-settings.merge_style_desc=Sapludinฤลกanas veidi
-settings.default_merge_style_desc=Noklusฤtais sapludinฤลกanas veids izmaiลu pieprasฤซjumiem:
-settings.choose_branch=Izvฤlieties atzaruโฆ
-settings.no_protected_branch=Nav neviena aizsargฤtฤ atzara.
+settings.update_protect_branch_success=Zara aizsargฤลกanas kฤrtula "%s" tika atjauninฤta.
+settings.remove_protected_branch_success=Zara aizsargฤลกanas kฤrtula "%s" tika noลemta.
+settings.remove_protected_branch_failed=Zara aizsargฤลกanas kฤrtulas "%s" noลemลกana neizdevฤs.
+settings.protected_branch_deletion=Izdzฤst zara aizsargฤลกanu
+settings.protected_branch_deletion_desc=Zara aizsargฤลกanas atspฤjoลกana ฤผauj lietotฤjiem ar rakstฤซลกanas atฤผauju aizgฤdฤt zarฤ izmaiลas. Turpinฤt?
+settings.block_rejected_reviews=Liegt apvienoลกanu, ja izskatฤซลกana ir beigusies ar noraidฤซลกanu
+settings.block_rejected_reviews_desc=Apvienoลกana nebลซs iespฤjama, kad oficiฤlie izskatฤซtฤji gลซs pieprasฤซjuลกi izmaiลas, pat ja ir pietiekami daudz apstiprinฤjumu.
+settings.block_on_official_review_requests=Liegt apvienoลกanu, ja ir oficiฤli izskatฤซลกanas pieprasฤซjumi
+settings.block_on_official_review_requests_desc=Apvienoลกana nebลซs iespฤjama, ja bลซs oficiฤli izskatฤซลกanas pieprasฤซjumi, pat ja bลซs pietiekami daudz apstiprinฤjumu.
+settings.block_outdated_branch=Liegt apvienoลกanu, ja izmaiลu pieprasฤซjums ir novecojis
+settings.block_outdated_branch_desc=Apvienoลกana nebลซs iespฤjama, ja zars bลซs atpalicis no pamata zara.
+settings.default_branch_desc=Atlasฤซt noklusฤjuma glabฤtavas zaru izmaiลu pieprasฤซjumiem un koda iesลซtฤซjumiem:
+settings.merge_style_desc=Apvienoลกanas veidi
+settings.default_merge_style_desc=Noklusฤjuma apvienoลกanas veids
+settings.choose_branch=Atlasฤซt zaruโฆ
+settings.no_protected_branch=Nav neviena aizsargฤtฤ zara.
settings.edit_protected_branch=Labot
-settings.protected_branch_required_rule_name=Nav norฤdฤซts noteikuma nosaukums
-settings.protected_branch_duplicate_rule_name=Dublฤjoลกs noteikuma nosaukumu
-settings.protected_branch_required_approvals_min=Pieprasฤซto recenziju skaits nevar bลซt negatฤซvs.
-settings.tags=Tagi
-settings.tags.protection=Tagu aizsargฤลกana
-settings.tags.protection.pattern=Tagu ลกablons
+settings.protected_branch_required_rule_name=Jฤnorฤda kฤrtulas nosaukums
+settings.protected_branch_duplicate_rule_name=ล ai zaru kopai jau pastฤv kฤrtula
+settings.protected_branch_required_approvals_min=Pieprasฤซto izskatฤซลกanu skaits nevar bลซt mazฤks par nulli.
+settings.tags=Birkas
+settings.tags.protection=Birku aizsargฤลกana
+settings.tags.protection.pattern=Birku paraugs
settings.tags.protection.allowed=Atฤผauts
settings.tags.protection.allowed.users=Atฤผauts lietotฤjiem
settings.tags.protection.allowed.teams=Atฤผauts komandฤm
-settings.tags.protection.allowed.noone=Nevienam
-settings.tags.protection.create=Aizsargฤt tagus
-settings.tags.protection.none=Nav uzstฤdฤซta tagu aizsargฤลกana.
-settings.tags.protection.pattern.description=Var izmantot vienkฤrลกu nosaukumu vai glob ลกablonu, vai regulฤro izteiksmi, lai atbilstu vairฤkiem tagiem. Vairฤk ir lasฤms aizsargฤto tagu ลกablonu dokumentฤcijฤ .
-settings.bot_token=Bota pilnvara
+settings.tags.protection.allowed.noone=Neviens
+settings.tags.protection.create=Pievienot kฤrtulu
+settings.tags.protection.none=Nav aizsargฤtu birku.
+settings.tags.protection.pattern.description=Var izmantot vienkฤrลกu nosaukumu vai glob paraugu, vai regulฤro izteiksmi, lai atbilstu vairฤkฤm birkฤm. Vairฤk ir lasฤms norฤdฤs par aizsargฤtajฤm birkฤm .
+settings.bot_token=Robotprogrammatลซras pilnvara
settings.chat_id=Tฤrzฤลกanas ID
-settings.thread_id=Pavediena ID
+settings.thread_id=Pavediena identifikators
settings.matrix.homeserver_url=Mฤjas servera URL
settings.matrix.room_id=Istabas ID
-settings.matrix.message_type=Ziลas veids
-settings.archive.button=Arhivฤt
-settings.archive.header=Arhivฤt repozitoriju
-settings.archive.text=Repozitorija arhivฤลกana padarฤซs to tikai lasฤmu. Tas nebลซs redzams infopanelฤซ. Neviens nevarฤs izveidot jaunas revฤซzijas vai atvฤrt jaunus problฤmu pieteikumus vai izmaiลu pieprasฤซjumus.
-settings.archive.success=Repozitorijs veiksmฤซgi arhivฤts.
-settings.archive.error=Arhivฤjot repozitoriju radฤs neparedzฤta kฤผลซda. Pฤrbaudiet kฤผลซdu ลพurnฤlu, lai uzzinฤtu sฤซkฤk.
-settings.archive.error_ismirror=Nav iespฤjams arhivฤt spoguฤผotus repozitorijus.
-settings.archive.branchsettings_unavailable=Atzaru iestatฤซjumi nav pieejami, ja repozitorijs ir arhivฤts.
-settings.archive.tagsettings_unavailable=Tagu iestatฤซjumi nav pieejami, ja repozitorijs ir arhivฤts.
-settings.unarchive.button=Atcelt repozitorija arhivฤลกanu
-settings.unarchive.header=Atcelt ลกฤซ repozitorija arhivฤลกanu
-settings.unarchive.text=Repozitorija arhivฤลกanas atcelลกana atjaunos tฤ spฤju saลemt izmaiลas, kฤ arฤซ jaunus problฤmu pieteikumus un izmaiลu pieprasฤซjumus.
-settings.unarchive.success=Repozitorijam veiksmฤซgi atcelta arhivฤcija.
-settings.unarchive.error=Repozitorija arhivฤลกanas atcelลกanas laikฤ atgadฤซjฤs kฤผลซda. Vairฤk ir redzams ลพurnฤlฤ.
-settings.update_avatar_success=Repozitorija attฤls tika atjauninฤts.
+settings.matrix.message_type=Ziลojuma veids
+settings.archive.button=Arhivฤt glabฤtavu
+settings.archive.header=Arhivฤt ลกo glabฤtavu
+settings.archive.text=Glabฤtavas arhivฤลกana padarฤซs to tikai lasฤmu. Tฤ nebลซs redzama pฤrskata panelฤซ. Neviens (pat ne Tu) nevarฤs izveidot jaunus iesลซtฤซjumus vai atvฤrt pieteikumus vai izmaiลu pieprasฤซjumus.
+settings.archive.success=Glabฤtava tika sekmฤซgi arhivฤts.
+settings.archive.error=Atgadฤซjฤs kฤผลซda, kad tika mฤฤฃinฤts arhivฤt glabฤtavu. Jฤapskata ลพurnฤls, lai uzzinฤtu vairฤk.
+settings.archive.error_ismirror=Nevar arhivฤt spoguฤผotu glabฤtavu.
+settings.archive.branchsettings_unavailable=Zaru iestatฤซjumi nav pieejami arhivฤtฤs glabฤtavฤs.
+settings.archive.tagsettings_unavailable=Birku iestatฤซjumi arhivฤtฤs glabฤtavฤs nav pieejami.
+settings.unarchive.button=Atcelt glabฤtavas arhivฤลกanu
+settings.unarchive.header=Atcelt ลกฤซs glabฤtavas arhivฤลกanu
+settings.unarchive.text=Glabฤtavas arhivฤลกanas atcelลกana atjaunos tฤs spฤju saลemt izmaiลas, kฤ arฤซ jaunus pieteikumus un izmaiลu pieprasฤซjumus.
+settings.unarchive.success=Glabฤtavas arhivฤลกana tika sekmฤซgi atcelta.
+settings.unarchive.error=Glabฤtavas arhivฤลกanas atcelลกanas laikฤ atgadฤซjฤs kฤผลซda. Vairฤk ir redzams ลพurnฤlฤ.
+settings.update_avatar_success=Glabฤtavas attฤls tika atjauninฤts.
settings.lfs=LFS
-settings.lfs_filelist=LFS faili, kas saglabฤti ลกajฤ repozitorijฤ
-settings.lfs_no_lfs_files=ล ajฤ repozitorijฤ nav saglabฤts neviens LFS fails
-settings.lfs_findcommits=Atrast revฤซzijas
-settings.lfs_lfs_file_no_commits=ล im LFS failam netika atrasta neviena revฤซzija
-settings.lfs_noattribute=Norฤdฤซtฤjam ceฤผam nav bloฤทฤลกanas atribลซta noklusฤtajฤ atzarฤ
-settings.lfs_delete=Dzฤst LFS failu ar OID %s
-settings.lfs_delete_warning=Dzฤลกot LFS failu, tas var izraisฤซt kฤผลซdu 'object does not exist' veicot git izmaiลu saลemลกanu. Vai vฤlaties turpinฤt?
-settings.lfs_findpointerfiles=Atrast norฤลพu failus
-settings.lfs_locks=Bloฤทฤลกanas
-settings.lfs_invalid_locking_path=Nekorekts ceฤผลก: %s
-settings.lfs_invalid_lock_directory=Nevar bloฤทฤt direktoriju: %s
-settings.lfs_lock_already_exists=Fails vai direktorija jau ir bloฤทฤta: %s
-settings.lfs_lock=Bloฤทฤt
-settings.lfs_lock_path=Faila ceฤผลก, ko bloฤทฤt...
-settings.lfs_locks_no_locks=Nav bloฤทฤts neviens fails
-settings.lfs_lock_file_no_exist=Bloฤทฤjamais fails neeksistฤ noklusฤtajฤ atzarฤ
-settings.lfs_force_unlock=Piespiedu atbloฤทฤลกana
-settings.lfs_pointers.found=Atrasta(s) %d binฤrฤ objekta norฤde(s) - %d saistฤซtas, %d nesaistฤซtas (%d trลซkstoลกas glabฤtuvฤ)
-settings.lfs_pointers.sha=Binฤrฤ objekta SHA
+settings.lfs_filelist=ล ajฤ glabฤtavฤ uzglabฤtฤs LFS datnes
+settings.lfs_no_lfs_files=ล ajฤ glabฤtavฤ netiek glabฤtas LFS datnes
+settings.lfs_findcommits=Atrast iesลซtฤซjumus
+settings.lfs_lfs_file_no_commits=ล ai LFS datnei netika atrasts neviens iesลซtฤซjums
+settings.lfs_noattribute=ล im ceฤผam noklusฤjuma zarฤ nav slฤdzamฤซbas atribลซta
+settings.lfs_delete=Izdzฤst LFS datni ar OID %s
+settings.lfs_delete_warning=LFS datnes izdzฤลกana var izraisฤซt kฤผลซdu "object does not exist" paลemลกanas laikฤ. Tieลกฤm izdzฤst?
+settings.lfs_findpointerfiles=Atrast norฤลพu datnes
+settings.lfs_locks=Slฤdzenes
+settings.lfs_invalid_locking_path=Nederฤซgs ceฤผลก: %s
+settings.lfs_invalid_lock_directory=Nevar slฤgt mapi: %s
+settings.lfs_lock_already_exists=Slฤdzene jau pastฤv: %s
+settings.lfs_lock=Slฤgt
+settings.lfs_lock_path=Slฤdzamฤs datnes ceฤผลกโฆ
+settings.lfs_locks_no_locks=Nav slฤdzeลu
+settings.lfs_lock_file_no_exist=Aizslฤgtฤ datne nepastฤv noklusฤjuma zarฤ
+settings.lfs_force_unlock=Uzspiest atslฤgลกanu
+settings.lfs_pointers.found=Atrasta(s) %d binฤrฤ objekta norฤde(s) - %d saistฤซta(s), %d nesaistฤซta(s) (%d trลซkst krฤtuvฤ)
+settings.lfs_pointers.sha=Binฤrฤ objekta jaucฤjvirkne
settings.lfs_pointers.oid=OID
-settings.lfs_pointers.inRepo=Repozitorijฤ
-settings.lfs_pointers.exists=Eksistฤ glabฤtuvฤ
+settings.lfs_pointers.inRepo=Glabฤtavฤ
+settings.lfs_pointers.exists=Pastฤv krฤtuvฤ
settings.lfs_pointers.accessible=Pieejams lietotฤjam
settings.lfs_pointers.associateAccessible=Saistฤซt pieejamos %d OID'us
-settings.rename_branch_failed_exist=Nevar pฤrsaukt atzaru, jo atzars %s jau eksistฤ.
-settings.rename_branch_failed_not_exist=Nevar pฤrsaukt atzaru %s, jo tฤds neeksistฤ.
-settings.rename_branch_success=Atzars %s tika veiksmฤซgi pฤrsaukts par %s.
+settings.rename_branch_failed_exist=Nevar pฤrdฤvฤt zaru, jo mฤrฤทa zars %s jau pastฤv.
+settings.rename_branch_failed_not_exist=Nevar pฤrdฤvฤt zaru %s, jo tas nepastฤv.
+settings.rename_branch_success=Zars %s tika sekmฤซgi pฤrdฤvฤts par %s.
settings.rename_branch_from=no vecฤ atzara nosaukuma
settings.rename_branch_to=jaunais atzara nosaukums
-settings.rename_branch=Pฤrsaukt atzaru
+settings.rename_branch=Pฤrdฤvฤt zaru
-diff.browse_source=Pฤrlลซkot izejas kodu
+diff.browse_source=Pฤrlลซkot avotu
diff.parent=vecฤks
-diff.commit=revฤซzija
+diff.commit=iesลซtฤซjums
diff.git-notes=Piezฤซmes
diff.data_not_available=Satura salฤซdzinฤลกana nav pieejama
diff.options_button=Salฤซdzinฤลกanas iespฤjas
-diff.show_diff_stats=Rฤdฤซt statistiku
-diff.download_patch=Lejupielฤdฤt ielฤpa failu
-diff.download_diff=Lejupielฤdฤt izmaiลu failu
-diff.show_split_view=Dalฤซtais skats
+diff.show_diff_stats=Rฤdฤซt apkopojumu
+diff.download_patch=Lejupielฤdฤt ielฤpa datni
+diff.download_diff=Lejupielฤdฤt atลกฤทirฤซbu datni
+diff.show_split_view=Sadalฤซtais skats
diff.show_unified_view=Apvienotais skats
diff.whitespace_button=Atstarpes
diff.whitespace_show_everything=Rฤdฤซt visas izmaiลas
-diff.whitespace_ignore_all_whitespace=Ignorฤt atstarpes salฤซdzinot rindas
-diff.whitespace_ignore_amount_changes=Ignorฤt atstarpju daudzuma izmaiลas
-diff.whitespace_ignore_at_eol=Ignorฤt atstarpju izmaiลas rindu beigฤs
-diff.stats_desc=%d mainฤซti faili ar %d papildinฤjumiem un %d dzฤลกanฤm
-diff.stats_desc_file=%d izmaiลas: %d pievienotas un %d dzฤstas
+diff.whitespace_ignore_all_whitespace=Neลemt vฤrฤ atstarpes, kad tiek salฤซdzinฤtas rindas
+diff.whitespace_ignore_amount_changes=Neลemt vฤrฤ atstarpju daudzuma izmaiลas
+diff.whitespace_ignore_at_eol=Neลemt vฤrฤ atstarpju izmaiลas rindu beigฤs
+diff.stats_desc=%d izmainฤซtas datnes ar %d papildinฤjumiem un %d izdzฤลกanฤm
+diff.stats_desc_file=%d izmaiลas: %d pievienoลกanas un %d izdzฤลกanas
diff.bin=Binฤrs
-diff.bin_not_shown=Binฤro failu nav iespฤjams attฤlot.
-diff.view_file=Parฤdฤซt failu
+diff.bin_not_shown=Binฤrฤ datne netiek rฤdฤซta.
+diff.view_file=Apskatฤซt datni
diff.file_before=Pirms
diff.file_after=Pฤc
diff.file_image_width=Platums
diff.file_image_height=Augstums
diff.file_byte_size=Izmฤrs
-diff.file_suppressed=Failฤ izmaiลas netiks attฤlotas, jo tฤs ir par lielu
-diff.file_suppressed_line_too_long=Faila izmaiลas netiek rฤdฤซtas, jo viena vai vairฤkas lฤซnijas ir pฤrฤk garas
-diff.too_many_files=Daลพi faili netika attฤloti, jo izmaiลu fails ir pฤrฤk liels
-diff.show_more=Rฤdฤซt vairฤk
-diff.load=Ielฤdฤt izmaiลas
-diff.generated=ฤฃenerฤts
+diff.file_suppressed=Datnes izmaiลas netiek rฤdฤซtas, jo tฤs ir pฤrฤk lielas
+diff.file_suppressed_line_too_long=Datnes izmaiลas netiek rฤdฤซtas, jo viena vai vairฤkas rindas ir pฤrฤk garas
+diff.too_many_files=Daลพas datnes netika parฤdฤซtas, jo ลกajฤs izmaiลฤs ir pฤrฤk daudz izmainฤซtu datลu
+diff.show_more=Parฤdฤซt vairฤk
+diff.load=Ielฤdฤt atลกฤทirฤซbas
+diff.generated=izveidots
diff.vendored=ฤrฤjs
-diff.comment.add_line_comment=Pievienot rindas komentฤru
-diff.comment.placeholder=Ievadiet komentฤru
-diff.comment.markdown_info=Tiek atbalstฤซta formatฤลกana ar Markdown.
-diff.comment.add_single_comment=Pievienot vienu komentฤru
-diff.comment.add_review_comment=Pievienot komentฤru
-diff.comment.start_review=Sฤkt recenziju
+diff.comment.add_line_comment=Pievienot piebildi par rindu
+diff.comment.placeholder=Ierakstฤซt piebildi
+diff.comment.markdown_info=Tiek nodroลกinฤta formatฤลกana ar Markdown.
+diff.comment.add_single_comment=Pievienot vienu piebildi
+diff.comment.add_review_comment=Pievienot piebildi
+diff.comment.start_review=Uzsฤkt izskatฤซลกanu
diff.comment.reply=Atbildฤt
-diff.review=Recenzija
-diff.review.header=Iesลซtฤซt recenziju
-diff.review.placeholder=Recenzijas komentฤrs
-diff.review.comment=Komentฤt
+diff.review=Pabeigt izskatฤซลกanu
+diff.review.header=Iesniegt izskatฤซลกanu
+diff.review.placeholder=Izskatฤซลกanas piezฤซmes
+diff.review.comment=Pievienot piebildi
diff.review.approve=Apstiprinฤt
-diff.review.self_reject=Izmaiลu pieprasฤซjuma autors nevar pieprasฤซt izmaiลas savam izmaiลu pieprasฤซjumam
+diff.review.self_reject=Izmaiลu pieprasฤซjuma iesniedzฤji nevar pieprasฤซt izmaiลas savam izmaiลu pieprasฤซjumam
diff.review.reject=Pieprasฤซt izmaiลas
-diff.review.self_approve=Izmaiลu pieprasฤซjuma autors nevar apstiprinฤt savu izmaiลu pieprasฤซjumu
-diff.committed_by=revฤซziju iesลซtฤซja
+diff.review.self_approve=Izmaiลu pieprasฤซjuma iesniedzฤji nevar apstiprinฤt savu izmaiลu pieprasฤซjumu
+diff.committed_by=iesลซtฤซja
diff.protected=Aizsargฤts
diff.image.side_by_side=Blakus
diff.image.swipe=Pฤrvelkot
diff.image.overlay=Pฤrklฤjoลกi
-diff.has_escaped=ล ajฤ lฤซnijฤ ir paslฤpti unikoda simboli
-diff.show_file_tree=Parฤdฤซt failu koku
-diff.hide_file_tree=Paslฤpt failu koku
+diff.has_escaped=ล ajฤ rindฤ ir slฤptas unikoda rakstzฤซmes
+diff.show_file_tree=Parฤdฤซt datลu koku
+diff.hide_file_tree=Paslฤpt datลu koku
-releases.desc=Pฤrvaldiet projekta versijas un lejupielฤdes.
+releases.desc=Projekta versiju un lejupielฤลพu pฤrraudzฤซลกana.
release.releases=Laidieni
-release.detail=Laidiena papildus informฤcija
-release.tags=Tagi
+release.detail=Informฤcija par laidienu
+release.tags=Birkas
release.new_release=Jauns laidiens
release.draft=Melnraksts
-release.prerelease=Pirmsizlaides versija
+release.prerelease=Pirmsizlaide
release.stable=Stabila
release.compare=Salฤซdzinฤt
-release.edit=labot
-release.ahead.commits=%d revฤซzijas
-release.ahead.target=no %s kopลก laidiena publicฤลกanas
-tag.ahead.target=revฤซzijas atzarฤ %s no ลกฤซ taga izveidoลกanas
-release.source_code=Izejas kods
-release.new_subheader=Laidieni palฤซdz organizฤt projekta versijas.
-release.edit_subheader=Laidieni palฤซdz organizฤt projekta versijas.
+release.edit=Labot
+release.ahead.commits=%d iesลซtฤซjumi
+release.ahead.target=%s kopลก ลกฤซ laidiena laiลกanas klajฤ
+tag.ahead.target=%s kopลก ลกฤซs birkas
+release.source_code=Pirmkods
+release.new_subheader=Laidieni apkopo projekta versijas.
+release.edit_subheader=Laidieni apkopo projekta versijas.
release.tag_name=Taga nosaukums
release.target=Mฤrฤทis
-release.tag_helper=Izvฤlieties jau esoลกu tagu vai izveidojiet jaunu.
-release.tag_helper_new=Jauns tags. ล is tags tiks izveidots no mฤrฤทa.
-release.tag_helper_existing=Esoลกs tags.
+release.tag_helper=Jฤizvฤlas esoลกa birka vai jฤizveido jauna.
+release.tag_helper_new=Jauna birka. ล ฤซ birka tiks izveidota no mฤrฤทa.
+release.tag_helper_existing=Esoลกa birka.
release.title=Laidiena nosaukums
release.title_empty=Nosaukums nevar bลซt tukลกs.
-release.message=Aprakstiet ลกo laidienu
-release.prerelease_desc=Atzฤซmฤt kฤ pirmslaidiena versiju
-release.prerelease_helper=Atzฤซmฤt, ka ลกo laidienu nav ieteicams lietot produkcijฤ.
+release.message=Aprakstฤซt ลกo laidienu
+release.prerelease_desc=Atzฤซmฤt kฤ pirmsizlaidi
+release.prerelease_helper=Atzฤซmฤt ลกo laidienu kฤ nepiemฤrotu izmantoลกanai produkcijฤ.
release.cancel=Atcelt
-release.publish=Publicฤt laidienu
+release.publish=Laist klajฤ laidienu
release.save_draft=Saglabฤt melnrakstu
-release.edit_release=Labot laidienu
-release.delete_release=Dzฤst laidienu
-release.delete_tag=Dzฤst tagu
-release.deletion=Dzฤst laidienu
-release.deletion_desc=Laidiena izdzฤลกana tikai noลem to no Gitea. Tฤ neietekmฤs Git tagu, repozitorija saturu vai vฤsturi. Vai turpinฤt?
+release.edit_release=Atjauninฤt laidienu
+release.delete_release=Izdzฤst laidienu
+release.delete_tag=Izdzฤst birku
+release.deletion=Izdzฤst laidienu
+release.deletion_desc=Laidiena izdzฤลกana tikai noลem to no Forgejo. Tฤ neietekmฤs Git birku, glabฤtavas saturu vai vฤsturi. Turpinฤt?
release.deletion_success=Laidiens tika izdzฤsts.
-release.deletion_tag_desc=Tiks izdzฤsts tags no repozitorija. Repozitorija saturs un vฤsture netiks mainฤซta. Vai turpinฤt?
-release.deletion_tag_success=Tags tika izdzฤsts.
-release.tag_name_already_exist=Laidiens ar ลกฤdu taga nosaukumu jau eksistฤ.
-release.tag_name_invalid=Nekorekts taga nosaukums.
-release.tag_name_protected=Taga nosaukums ir aizsargฤts.
-release.tag_already_exist=Tags ar ลกฤdu nosaukumu jau eksistฤ.
+release.deletion_tag_desc=ล ฤซ birka tiks izdzฤsta no glabฤtavas. Glabฤtavas saturs un vฤsture paliks nemainฤซta. Turpinฤt?
+release.deletion_tag_success=Birka tika izdzฤsta.
+release.tag_name_already_exist=Laidiens ar ลกฤdu birkas nosaukumu jau pastฤv.
+release.tag_name_invalid=Nederฤซgs birkas nosaukums.
+release.tag_name_protected=Birkas nosaukums ir aizsargฤts.
+release.tag_already_exist=ล ฤds birkas nosaukums jau pastฤv.
release.downloads=Lejupielฤdes
release.download_count=Lejupielฤdes: %s
-release.add_tag_msg=Izmantot laidiena nosaukumu un saturu kฤ taga aprakstu.
-release.add_tag=Izveidot tikai tagu
-release.releases_for=Repozitorja %s laidieni
-release.tags_for=Repozitorija %s tagi
+release.add_tag_msg=Izmantot laidiena nosaukumu un saturu kฤ birkas ziลojumu.
+release.add_tag=Izveidot birku
+release.releases_for=Glabฤtavas %s laidieni
+release.tags_for=%s birkas
-branch.name=Atzara nosaukums
-branch.already_exists=Atzars ar nosaukumu "%s" jau eksistฤ.
-branch.delete_head=Dzฤst
-branch.delete=`Dzฤst atzaru "%s"`
-branch.delete_html=Dzฤst atzaru
-branch.delete_desc=Atzara dzฤลกana ir neatgriezeniska. Kaut arฤซ izdzฤstais zars neilgu laiku var turpinฤt pastฤvฤt, pirms tas tieลกฤm tiek noลemts, to vairumฤ gadฤซjumu NEVAR atsaukt. Vai turpinฤt?
-branch.deletion_success=Atzars "%s" tika izdzฤsts.
-branch.deletion_failed=Neizdevฤs izdzฤst atzaru "%s".
-branch.delete_branch_has_new_commits=Atzars "%s" nevar tik dzฤsts, jo pฤc sapludinฤลกanas, tam ir pievienotas jaunas revฤซzijas.
-branch.create_branch=Izveidot atzaru %s
+branch.name=Zara nosaukums
+branch.already_exists=Jau pastฤv zars ar nosaukumu "%s".
+branch.delete_head=Izdzฤst
+branch.delete=Izdzฤst zaru "%s"
+branch.delete_html=Izdzฤst zaru
+branch.delete_desc=Zara izdzฤลกana ir neatgriezeniska. Kaut arฤซ izdzฤstais zars neilgu laiku var turpinฤt pastฤvฤt, pirms tas patieลกฤm tiek noลemts, to vairumฤ gadฤซjumu NEVAR atsaukt. Turpinฤt?
+branch.deletion_success=Zars "%s" tika izdzฤsts.
+branch.deletion_failed=Neizdevฤs izdzฤst zaru "%s".
+branch.delete_branch_has_new_commits=Zaru "%s" nevar izdzฤst, jo pฤc apvienoลกanas ir pievienoti jauni iesลซtฤซjumi.
+branch.create_branch=Izveidot zaru %s
branch.create_from=`no "%s"`
-branch.create_success=Tika izveidots atzars "%s".
-branch.branch_already_exists=Atzars "%s" ลกajฤ repozitorijฤ jau eksistฤ.
-branch.branch_name_conflict=Atzara nosaukums "%s" konfliktฤ ar jau esoลกu atzaru "%s" ลกajฤ repozitorijฤ.
-branch.tag_collision=Atzaru "%s" nevar izveidot, jo repozitorijฤ eksistฤ tags ar tฤdu paลกu nosaukumu.
+branch.create_success=Zars "%s" tika izveidots.
+branch.branch_already_exists=ล ajฤ glabฤtavฤ jau ir zars "%s".
+branch.branch_name_conflict=Zara nosaukums "%s" ir pretrunฤ ar jau esoลกu zaru "%s".
+branch.tag_collision=Zaru "%s" nevar izveidot, jo glabฤtavฤ jau ir birka ar tฤdu paลกu nosaukumu.
branch.deleted_by=Izdzฤsa %s
-branch.restore_success=Tika atjaunots atzars "%s".
-branch.restore_failed=Neizdevฤs atjaunot atzaru "%s".
-branch.protected_deletion_failed=Atzars "%s" ir aizsargฤts. To nevar dzฤst.
-branch.default_deletion_failed=Atzars "%s" ir noklusฤtais atzars un to nevar dzฤst.
-branch.restore=`Atjaunot atzaru "%s"`
-branch.download=`Lejupielฤdฤt atzaru "%s"`
-branch.rename=`Pฤrsaukt atzaru "%s"`
+branch.restore_success=Zars "%s" tika atjaunots.
+branch.restore_failed=Neizdevฤs atjaunot zaru "%s".
+branch.protected_deletion_failed=Zars "%s" ir aizsargฤts. To nevar izdzฤst.
+branch.default_deletion_failed=Zars "%s" ir noklusฤjuma zars. To nevar izdzฤst.
+branch.restore=Atjaunot zaru "%s"
+branch.download=Lejupielฤdฤt zaru "%s"
+branch.rename=Pฤrdฤvฤt zaru "%s"
branch.search=Meklฤt atzarฤ
-branch.included_desc=ล is atzars ir daฤผa no noklusฤta atzara
+branch.included_desc=ล is zars ir daฤผa no noklusฤjuma zara
branch.included=Iekฤผauts
-branch.create_new_branch=Izveidot jaunu atzaru no atzara:
-branch.confirm_create_branch=Izveidot atzaru
-branch.warning_rename_default_branch=Tiks pฤrsaukts noklusฤtais atzars.
-branch.rename_branch_to=Pฤrsaukt "%s" uz:
+branch.create_new_branch=Izveidot zaru no zara:
+branch.confirm_create_branch=Izveidot zaru
+branch.warning_rename_default_branch=Tiek pฤrdฤvฤts noklusฤjuma zars.
+branch.rename_branch_to=Pฤrdฤvฤt "%s" par:
branch.confirm_rename_branch=Pฤrdฤvฤt atzaru
-branch.create_branch_operation=Izveidot atzaru
-branch.new_branch=Izveidot jaunu atzaru
-branch.new_branch_from=`Izveidot jaunu atzaru no "%s"`
-branch.renamed=Atzars %s tika pฤrsaukts par %s.
+branch.create_branch_operation=Izveidot zaru
+branch.new_branch=Izveidot jaunu zaru
+branch.new_branch_from=Izveidot jaunu zaru no "%s"
+branch.renamed=Zars %s tika pฤrdฤvฤts par %s.
-tag.create_tag=Izveidot tagu %s
-tag.create_tag_operation=Izveidot tagu
-tag.confirm_create_tag=Izveidot tagu
-tag.create_tag_from=`Izveidot tagu no "%s"`
+tag.create_tag=Izveidot birku %s
+tag.create_tag_operation=Izveidot birku
+tag.confirm_create_tag=Izveidot birku
+tag.create_tag_from=Izveidot jaunu birku no "%s"
-tag.create_success=Tags "%s" tika izveidots.
+tag.create_success=Birka "%s" tika izveidota.
topic.manage_topics=Pฤrvaldฤซt tฤmas
topic.done=Gatavs
topic.count_prompt=Nevar pievienot vairฤk kฤ 25 tฤmas
-topic.format_prompt=Tฤmai jฤsฤkas ar burtu vai ciparu, tฤ var saturฤt domu zฤซmes ('-') un punktus ('.') un var bลซt lฤซdz 35 rakstzฤซmฤm gara. Burtiem jฤbลซt mazajiem.
+topic.format_prompt=Tฤmai jฤsฤkas ar burtu vai ciparu, tฤ var saturฤt domu zฤซmes ("-") un punktus (".") un var bลซt lฤซdz 35 rakstzฤซmฤm gara. Jฤizmanto mazie burti.
-find_file.go_to_file=Iet uz failu
-find_file.no_matching=Atbilstoลกs fails netika atrasts
+find_file.go_to_file=Atrast datni
+find_file.no_matching=Netika atrasta neviena atbilstoลกa datne
-error.csv.too_large=Nevar attฤlot ลกo failu, jo tas ir pฤrฤk liels.
-error.csv.unexpected=Nevar attฤlot ลกo failu, jo tas satur neparedzฤtu simbolu %d. lฤซnijas %d. kolonnฤ.
-error.csv.invalid_field_count=Nevar attฤlot ลกo failu, jo tas satur nepareizu skaitu ar laukiem %d. lฤซnijฤ.
+error.csv.too_large=Nevar atveidot ลกo datni, jo tฤ ir pฤrฤk liela.
+error.csv.unexpected=Nevar atveidot ลกo datni, jo tฤ satur neparedzฤtu rakstzฤซmi %d. rindas %d. slejฤ.
+error.csv.invalid_field_count=Nevar atveidot ลกo datni, jo tฤ satur nepareizu lauku skaitu %d. rindฤ.
+n_release_one = %s laidiens
+n_release_few = %s laidieni
+issues.new.assign_to_me = Pieลกฤทirt man
+admin.flags_replaced = Glabฤtavas karogi aizvietoti
+admin.failed_to_replace_flags = Neizdevฤs aizvietot glabฤtavas karogus
+admin.manage_flags = Pฤrvaldฤซt karogus
+admin.enabled_flags = Glabฤtavฤ iespฤjotie karogi:
+n_commit_one = %s iesลซtฤซjums
+editor.push_out_of_date = Aizgฤdฤjums izskatฤs novecojis.
+file_follow = Sekot simboliskajai saitei
+stars = Zvaigznes
+vendored = Piegฤdฤta
+subscribe.pull.guest.tooltip = Jฤpiesakฤs, lai abonฤtu ลกo izmaiลu pieprasฤซjumu.
+mirror_sync = sinhronizฤta
+editor.invalid_commit_mail = Nederฤซga e-pasta adrese iesลซtฤซjuma izveidoลกanai.
+form.string_too_long = ล ฤซ virkne ir garฤka par %d rakstzฤซmฤm.
+issues.filter_sort.relevance = Atbilstฤซba
+generated = Izveidota
+commits.search_branch = ล is zars
+editor.commit_id_not_matching = Datne laboลกanas laikฤ tika izmainฤซta. Jฤiesลซta jaunฤ zarฤ, tad jฤapvieno.
+object_format = Objektu veidols
+n_tag_one = %s birka
+n_tag_few = %s birkas
+n_branch_few = %s zari
+n_branch_one = %s zars
+object_format_helper = Glabฤtavas objektu veidols. Vฤlak to nevarฤs mainฤซt. SHA1 ir vissaderฤซgฤkais.
+commits.renamed_from = Pฤrdฤvฤts no %s
+rss.must_be_on_branch = Jฤatrodas zarฤ, lai iegลซtu RSS barotni.
+admin.update_flags = Atjauninฤt karogus
+open_with_editor = Atvฤrt ar %s
+n_commit_few = %s iesลซtฤซjumi
+no_eol.text = Nav EOL
+size_format = %[1]s: %[2]s; %[3]s: %[4]s
+mirror_public_key = Publiskฤ SSH atslฤga
+mirror_use_ssh.text = Izmantot SSH autentificฤลกanos
+mirror_use_ssh.helper = Forgejo spoguฤผos glabฤtavu ar Git un SSH un izveidos atslฤgu pฤri, kad tiks atlasฤซta ลกฤซ iespฤja. Jฤnodroลกina, ka izveidotais atslฤgu pฤris ir pilnvarots aizgฤdฤt mฤrฤทa glabฤtavฤ. Nevarฤs izmantot pilnvaroลกanu ar paroli, kad ลกis tiek atlasฤซts.
+mirror_use_ssh.not_available = SSH autentificฤลกanฤs nav pieejama.
+mirror_denied_combination = Nevar izmantot autentificฤลกanos ar publiskฤs atslฤgas un paroles apvienojumu.
+migrate.forgejo.description = Pฤrcelt datus no codeberg.org vai citiem Fogejo serveriem.
+subscribe.issue.guest.tooltip = Jฤpiesakฤs, lai abonฤtu ลกo pieteikumu.
+project = Projekti
+no_eol.tooltip = ล ฤซ datne nesatur noslฤdzoลกo rindas beigu rakstzฤซmi.
+commits.browse_further = Pฤrlลซkot tฤlฤk
+issues.edit.already_changed = Neizdevฤs saglabฤt pieteikuma izmaiลas. Izskatฤs, ka saturu jau ir mainฤซjis kฤds cits lietotฤjs. Lลซgums atsvaidzinฤt lapu un mฤฤฃinฤt labot vฤlreiz, lai izvairฤซtos no izmaiลu pฤrrakstฤซลกanas
+settings.wiki_rename_branch_main_desc = Pฤrdฤvฤt vikivietnes iekลกฤji izmantoto zaru par "%s". ล ฤซ izmaiลa ir neatgriezeniska, un to nevar atsaukt.
+settings.wiki_rename_branch_main_notices_2 = Tas neatgriezeniski pฤrdฤvฤs %s glabฤtavas vikivietnes iekลกฤjo zaru. Esoลกos atvฤrumus bลซs nepiecieลกams atjauninฤt.
+settings.units.units = Vienฤซbas
+settings.pull_mirror_sync_quota_exceeded = Pฤrsniegts ierobeลพojums, izmaiลas netiks atgฤdฤtas.
+settings.new_owner_blocked_doer = Jaunais ฤซpaลกnieks ir liedzis Tevi.
+settings.enter_repo_name = Jฤievada ฤซpaลกnieka vฤrds un glabฤtavas nosaukums tieลกi tฤ, kฤ parฤdฤซts:
+settings.transfer_quota_exceeded = Jaunais ฤซpaลกnieks (%s) ir pฤrsniedzis ierobeลพojumu. Glabฤtava netika nodota.
+settings.wiki_globally_editable = ฤปaut jebkuram veikt labojumus vikivietnฤ
+settings.wiki_rename_branch_main = Mainฤซt vikivietnes zara nosaukumu
+settings.units.add_more = Iespฤjot vฤl
+settings.units.overview = Pฤrskats
+settings.confirmation_string = Apstiprinฤjuma virkne
+settings.transfer.button = Nodot ฤซpaลกumtiesฤซbas
+settings.transfer.modal.title = Nodot ฤซpaลกumtiesฤซbas
+settings.mirror_settings.push_mirror.copy_public_key = Ievietot publisko atslฤgu starpliktuvฤ
+pulls.agit_explanation = Izveidots ar AGit darbplลซsmu. AGit ฤผauj lฤซdzalฤซbniekiem ieteikt izmaiลas ar "git push" bez atzarojuma vai jauna zara izveidoลกanas.
+settings.wiki_rename_branch_main_notices_1 = ล o darbฤซbu NEVAR atsaukt.
+release.download_count_few = %s lejupielฤdes/ลพu
+settings.rename_branch_failed_protected = Nevar pฤrdฤvฤt zaru %s, jo tas ir aizsargฤts zars.
+release.type_external_asset = ฤrฤjs lฤซdzeklis
+release.hide_archive_links = Paslฤpt automฤtiski izveidotos arhฤซvus
+settings.archive.mirrors_unavailable = Spoguฤผglabฤtavas nav pieejamas arhivฤtฤs glabฤtavฤs.
+release.type_attachment = Pielikums
+settings.enforce_on_admins_desc = Glabฤtavas pฤrvaldฤซtฤji ลกo kฤrtulu nevar apiet.
+settings.matrix.access_token_helper = ล im nolลซkam ir ieteicams izveidot atseviลกฤทu Matrix kontu. Piekฤผuves pilnvaru var iegลซt Element tฤซmekฤผa klientฤ (privฤtฤ/inkognito cilnฤ) > Lietotฤja izvฤlne (augลกฤjais kreisais stลซris) > Visi iestatฤซjumi > Palฤซdzฤซba un par > Papildu > Piekฤผuves pilnvara (tieลกi zem mฤjasservera URL). Jฤaizver privฤtฤ/inkognito cilne (atteikลกanฤs padarฤซtu pilnvaru nederฤซgu).
+settings.ignore_stale_approvals = Neลemt vฤrฤ novecojuลกus apstiprinฤjumus
+release.system_generated = ล is pielikums ir izveidots automฤtiski.
+settings.ignore_stale_approvals_desc = Neskaitฤซt apstiprinฤjumus, kas tika veikti vecฤkiem iesลซtฤซjumiem (novecojuลกas izskatฤซลกanas), kopฤjฤ izmaiลu pieprasฤซjuma apstiprinฤjumu skaitฤ. Neattiecas, ja novecojuลกas izskatฤซลกanas jau ir atmestas.
+settings.enforce_on_admins = Uzspiest ลกo kฤrtulu glabฤtavas pฤrvaldฤซtฤjiem
+release.download_count_one = %s lejupielฤde
+release.hide_archive_links_helper = ล ajฤ laidienฤ paslฤpt automฤtiski izveidotos pirmkoda arhฤซvus. Piemฤram, ja tiek augลกupielฤdฤts savs.
+diff.git-notes.add = Pievienot piezฤซmi
+diff.git-notes.remove-header = Noลemt piezฤซmi
+diff.git-notes.remove-body = ล ฤซ piezฤซme tiks noลemta.
+settings.confirm_wiki_branch_rename = Pฤrdฤvฤt vikivietnes zaru
+settings.matrix.room_id_helper = Istabas Id var iegลซt Element tฤซmekฤผa klientฤ > Istabas iestatฤซjumi > Papildu > Iekลกฤjais istabas Id. Piemฤrs: %s.
+settings.mirror_settings.pushed_repository = Aizgฤdฤลกanas glabฤtava
+error.broken_git_hook = ล ฤทiet, ka ลกฤซs glabฤtavas Git aizฤทeres ir salลซzuลกas. Lลซgums vฤrsties dokumentฤcijฤ , lai tฤs salabotu, tad jฤaizgฤdฤ kฤds iesลซtฤซjums, lai atsvaidzinฤtu stฤvokli.
+settings.add_collaborator_blocked_them = Nevar pievienot lฤซdzdalฤซbnieku, jo viลลก/a ir liedzis/a glabฤtavas ฤซpaลกnieku.
+settings.add_collaborator_blocked_our = Nevar pievienot lฤซdzdalฤซbnieku, jo glabฤtavas ฤซpaลกnieks viลu ir liedzis.
+contributors.contribution_type.filter_label = Lฤซdzdarboลกanฤs veids:
+activity.navbar.contributors = Lฤซdzdalฤซbnieki
+issues.review.remove_review_requests = noลฤma %[1]s izskatฤซลกanas pieprasฤซjumus %[2]s
+issues.review.add_remove_review_requests = pieprasฤซja izskatฤซลกanas no %[1] un noลฤma %[2]s izskatฤซลกanas pieprasฤซjumus %[3]s
+issues.author.tooltip.pr = ล is lietotฤjs ir ลกฤซ izmaiลu pieprasฤซjuma izveidotฤjs.
+pulls.edit.already_changed = Neizdevฤs saglabฤt izmaiลu pieprasฤซjuma izmaiลas. Izskatฤs, ka saturu jau ir mainฤซjis kฤds cits lietotฤjs. Lลซgums atsvaidzinฤt lapu un mฤฤฃinฤt labot vฤlreiz, lai izvairฤซtos no izmaiลu pฤrrakstฤซลกanas
+pulls.blocked_by_user = Tu nevari izveidot izmaiลu pieprasฤซjumu ลกajฤ glabฤtavฤ, jo tฤs ฤซpaลกnieks ir Tevi liedzis.
+issues.all_title = Visi
+pulls.commit_ref_at = ` atsaucฤลก uz ลกo izmaiลu pieprasฤซjumu iesลซtฤซjumฤ %[2]s `
+issues.num_participants_one = %d dalฤซbnieks
+pulls.title_desc_one = vฤlas iekฤผaut %[1]d iesลซtฤซjumu no %[2]s
%[3]s
+issues.archived_label_description = (Arhivฤts) %s
+issues.blocked_by_user = ล ajฤ glabฤtavฤ nevari izveidot pieteikumus, jo tฤs ฤซpaลกnieks ir liedzis Tevi.
+issues.summary_card_alt = Pieteikuma "%s" kopsavilkuma karte glabฤtavฤ %s
+pulls.nothing_to_compare_have_tag = Atlasฤซtie zari/birkas ir vienฤdi.
+pulls.merged_title_desc_one = iekฤผฤva %[1]d iesลซtฤซjumu no %[2]s
%[3]s
%[4]s
+pulls.reopen_failed.head_branch = Izmaiลu pieprasฤซjumu nevar atkฤrtoti atvฤrt, jo galotnes zars vairs nepastฤv.
+pulls.reopen_failed.base_branch = Izmaiลu pieprasฤซjumu nevar atkฤrtoti atvฤrt, jo pamata zars vairs nepastฤv.
+pulls.cmd_instruction_merge_warning = Brฤซdinฤjums : "Automฤtiski noteikt paลกrocฤซgu apvienoลกanu" ลกajฤ glabฤtavฤ nav iespฤjots, pฤcฤk bลซs nepiecieลกams atzฤซmฤt ลกo izmaiลu pieprasฤซjumu kฤ paลกrocฤซgi apvienotu.
+issues.author.tooltip.issue = ล is lietotฤjs ir ลกฤซ pieteikuma izveidotฤjs.
+issues.review.add_review_requests = pieprasฤซja izskatฤซลกanu no %[1]s %[2]s
+issues.comment.blocked_by_user = Tu ลกim pieteikumam nevari pievienot piebildi, jo glabฤtavas ฤซpaลกnieks vai pieteikuma izveidotฤjs ir liedzis Tevi.
+issues.num_reviews_one = %d izskatฤซลกana
+issues.num_reviews_few = %d izskatฤซลกanas
+settings.wiki_branch_rename_failure = Neizdevฤs normalizฤt glabฤtavas vikivietnes zara nosaukumu.
+settings.discord_icon_url.exceeds_max_length = Ikonas URL nedrฤซkst bลซt garฤka par 2048 rakstzฤซmฤm
+settings.sourcehut_builds.visibility = Darba redzamฤซba
+pulls.delete_after_merge.head_branch.is_default = Izdzฤลกamais galotnes zars ir noklusฤjuma zars, un to nevar izdzฤst.
+pulls.delete_after_merge.head_branch.is_protected = Izdzฤลกamais galotnes zars ir aizsargฤts zars, un to nevar izdzฤst.
+pulls.delete_after_merge.head_branch.insufficient_branch = Nav atฤผaujas izdzฤst galotnes zaru.
+contributors.contribution_type.deletions = Izdzฤลกanas
+activity.published_tag_label = Birka
+settings.sourcehut_builds.manifest_path = Bลซvฤjuma manifesta ceฤผลก
+settings.federation_settings = Federฤcijas iestatฤซjumi
+activity.navbar.pulse = Pulss
+settings.federation_not_enabled = ล ajฤ serverฤซ federฤcija nav iespฤjota.
+settings.event_pull_request_enforcement = Piemฤroลกana
+settings.sourcehut_builds.secrets = Noslฤpumi
+pulls.ready_for_review = Gatavs izskatฤซลกanai?
+pulls.made_using_agit = AGit
+milestones.filter_sort.name = Nosaukums
+wiki.cancel = Atcelt
+activity.navbar.code_frequency = Koda bieลพums
+activity.navbar.recent_commits = Neseni iesลซtฤซjumi
+activity.published_prerelease_label = Pirmsizlaide
+activity.commit = Iesลซtฤซjumu darbฤซbas
+contributors.contribution_type.additions = Pievienoลกanas
+settings.graphql_url = GraphQL URL
+wiki.no_search_results = Nekas netika atrasts
+wiki.search = Meklฤt vikivietnฤ
+comments.edit.already_changed = Neizdevฤs saglabฤt piebildes izmaiลas. Izskatฤs, ka saturu jau ir mainฤซjis kฤds cits lietotฤjs. Lลซgums atsvaidzinฤt lapu un mฤฤฃinฤt labot vฤlreiz, lai izvairฤซtos no izmaiลu pฤrrakstฤซลกanas
+settings.default_update_style_desc = Noklusฤjuma atjauninฤลกanas veids izmaiลu pieprasฤซjumu, kuri atpaliek no pamata zara, atjauninฤลกanai.
+settings.mirror_settings.push_mirror.none_ssh = Neviena
+settings.wiki_branch_rename_success = Glabฤtavas vikivietnes zara nosaukums tika sekmฤซgi normalizฤts.
+settings.web_hook_name_sourcehut_builds = SourceHut bลซvฤjumi
+pulls.fast_forward_only_merge_pull_request = Tikai pฤrlฤkลกana
+settings.federation_apapiurl = ล ฤซs glabฤtavas federฤcijas URL. Tas ir jฤievieto starpliktuvฤ un jฤielฤซmฤ citas glabฤtavas federฤcijas iestatฤซjumos kฤ sekojoลกas glabฤtavas URL.
+settings.federation_following_repos = Sekojoลกu glabฤtavu URL. Atdalฤซti ar ";", bez atstarpes.
+settings.add_webhook.invalid_path = Ceฤผลก nedrฤซkst saturฤt daฤผu, kas ir "." vai "..", vai tukลกa virkne. Tas nevar sฤkties vai beigties ar slฤซpsvฤซtru.
+settings.protect_new_rule = Izveidot jaunu zaru aizsargฤลกanas kฤrtulu
+settings.sourcehut_builds.secrets_helper = Dot darbam piekฤผuvi bลซvฤลกanas noslฤpumiem (nepiecieลกams nodroลกinฤt SECRETS:RO)
+release.asset_external_url = ฤrฤjais URL
+release.add_external_asset = Pievienot ฤrฤju lฤซdzekli
+release.invalid_external_url = Nederฤซgs ฤrฤjais URL: "%s"
+settings.sourcehut_builds.access_token_helper = Piekฤผuves pilnvara, kurai ir nodroลกinฤta JOBS:RW. meta.sr.ht jฤizveido builds.sr.ht pilnvara vai builds.sr.ht pilnvara ar piekฤผuvi noslฤpumiem .
+release.asset_name = Lฤซdzekฤผa nosaukums
+pulls.sign_in_require = Pieteikties , lai izveidotu jaunu izmaiลu pieprasฤซjumu.
+new_from_template = Izmantot sagatavi
+new_from_template_description = Var atlasฤซt ลกajฤ serverฤซ esoลกu glabฤtavas sagatavi un pielietot tฤs iestatฤซjumus.
+new_advanced = Papildu iestatฤซjumi
+new_advanced_expand = Klikลกฤทinฤt, lai izvฤrstu
+auto_init_description = Sฤkt ar README Git vฤsturฤ, pฤc izvฤles pievienojot licences un .gitignore datnes.
+issues.reaction.add = Pievienot reakciju
+issues.reaction.alt_few = %[1]s atsaucฤs ar %[2]s.
+issues.reaction.alt_many = %[1]s un vฤl %[2]d atsaucฤs ar %[3]s.
+issues.reaction.alt_remove = Noลemt no piebildes %[1] reakciju.
+issues.reaction.alt_add = Pievienot piebildei %[1] reakcijas.
+issues.context.menu = Piebildes izvฤlne
+summary_card_alt = Glabฤtavas %s apkopojuma kartฤซte
+release.summary_card_alt = Laidiena "%s" apkopojuma kartฤซte glabฤtavฤ %s
+archive.pull.noreview = ล ฤซ glabฤtava ir arhivฤta. Nevar izskatฤซt izmaiลu pieprasฤซjumus.
+editor.commit_email = Iesลซtฤซjuma e-pasta adrese
+commits.view_single_diff = Apskatฤซt ลกajฤ datnฤ veiktฤs izmaiลas ลกajฤ iesลซtฤซjumฤ
+pulls.editable = Labojams
+pulls.editable_explanation = ล is izmaiลu pieprasฤซjums pieฤผauj labojumus no uzturฤtฤjiem. Tu vari tieลกi lฤซdzdarboties tajฤ.
+issues.reopen.blocked_by_user = Tu nevari atkฤrtoti atvฤrt ลกo pieteikumu, jo tฤ izveidotฤjs vai glabฤtavas ฤซpaลกnieks ir liedzis Tevi.
+pulls.comment.blocked_by_user = Tu ลกim izmaiลu pieprasฤซjumam nevari pievienot piebildi, jo tฤ izveidotฤjs vai glabฤtavas ฤซpaลกnieks ir liedzis Tevi.
+issues.filter_no_results = Nav vienumu
+issues.filter_no_results_placeholder = Jฤmฤฤฃina pielฤgot meklฤลกanas atlasฤซtฤji.
[graphs]
-component_loading=Ielฤdฤ %s...
+component_loading=Ielฤdฤ %sโฆ
component_loading_failed=Nevarฤja ielฤdฤt %s
component_loading_info=ล is var aizลemt kฤdu brฤซdiโฆ
component_failed_to_load=Atgadฤซjฤs neparedzฤta kฤผลซda.
+code_frequency.what = koda bieลพums
+recent_commits.what = neseni iesลซtฤซjumi
+contributors.what = sniegumi
[org]
-org_name_holder=Organizฤcijas nosaukums
-org_full_name_holder=Organizฤcijas pilnais nosaukums
-org_name_helper=Organizฤciju nosaukumiem vฤlams bลซt ฤซsiem un tฤdiem, ko viegli atcerฤties.
-create_org=Izveidot organizฤciju
-repo_updated=Atjauninฤts %s
+org_name_holder=Apvienฤซbas nosaukums
+org_full_name_holder=Apvienฤซbas pilnais nosaukums
+org_name_helper=Apvienฤซbu nosaukumiem vajadzฤtu bลซt ฤซsiem un viegli iegaumฤjamiem.
+create_org=Izveidot apvienฤซbu
+repo_updated=Atjauninฤta %s
members=Dalฤซbnieki
teams=Komandas
code=Kods
lower_members=dalฤซbnieki
-lower_repositories=repozitoriji
+lower_repositories=glabฤtavas
create_new_team=Jauna komanda
create_team=Izveidot komandu
org_desc=Apraksts
team_name=Komandas nosaukums
team_desc=Apraksts
team_name_helper=Komandu nosaukumiem vฤlams bลซt ฤซsiem un tฤdiem, ko viegli atcerฤties.
-team_desc_helper=Aprakstiet komandas mฤrฤทi vai lomu.
-team_access_desc=Piekฤผuve repozitorijiem
+team_desc_helper=Komandas nolลซka vai lomas apraksts.
+team_access_desc=Glabฤtavu piekฤผuve
team_permission_desc=Atฤผauja
-team_unit_desc=Atฤผaut piekฤผuvi repozitorija sadaฤผฤm
+team_unit_desc=Atฤผaut piekฤผuvi glabฤtavas sadaฤผฤm
team_unit_disabled=(Atspฤjots)
-form.name_reserved=Organizฤcijas nosaukums "%s" ir rezervฤts.
-form.name_pattern_not_allowed=Organizฤcijas nosaukums "%s" nav atฤผauts.
-form.create_org_not_allowed=Jums nav tiesฤซbu veidot jauno organizฤciju.
+form.name_reserved=Apvienฤซbas nosaukums "%s" ir aizลemts.
+form.name_pattern_not_allowed="%s" nav ฤผauts izmantot apvienฤซbas nosaukumฤ.
+form.create_org_not_allowed=Nav ฤผauts izveidot apvienฤซbu.
settings=Iestatฤซjumi
-settings.options=Organizฤcija
-settings.full_name=Pilns vฤrds, uzvฤrds
+settings.options=Apvienฤซba
+settings.full_name=Pilns vฤrds
settings.email=E-pasta adrese saziลai
-settings.website=Mฤjas lapa
+settings.website=Tฤซmekฤผvietne
settings.location=Atraลกanฤs vieta
settings.permission=Tiesฤซbas
-settings.repoadminchangeteam=Repozitorija administrators var pievienot vai noลemt piekฤผuvi komandฤm
+settings.repoadminchangeteam=Glabฤtavas pฤrvaldฤซtฤjs var pievienot un noลemt komandu piekฤผuvi
settings.visibility=Redzamฤซba
-settings.visibility.public=Publiska
-settings.visibility.limited=Ierobeลพots (redzams tikai autentificฤtiem lietotฤjiem)
+settings.visibility.public=Atklฤta
+settings.visibility.limited=Ierobeลพota (redzama tikai lietotฤjiem, kuri ir pieteikuลกies)
settings.visibility.limited_shortname=Ierobeลพota
-settings.visibility.private=Privฤta (redzama tikai organizฤcijas dalฤซbniekiem)
+settings.visibility.private=Privฤta (redzama tikai apvienฤซbas dalฤซbniekiem)
settings.visibility.private_shortname=Privฤta
-settings.update_settings=Mainฤซt iestatฤซjumus
-settings.update_setting_success=Organizฤcijas iestatฤซjumi tika saglabฤti.
-settings.change_orgname_prompt=Piezฤซme: organizฤcijas nosaukuma maiลa izmainฤซs arฤซ organizฤcijas URL un atbrฤซvos veco nosaukumu.
-settings.change_orgname_redirect_prompt=Vecais vฤrds pฤrsลซtฤซs uz jauno, kamฤr vien tas nebลซs izmantots.
-settings.update_avatar_success=Organizฤcijas attฤls tika saglabฤts.
-settings.delete=Dzฤst organizฤciju
-settings.delete_account=Dzฤst ลกo organizฤciju
-settings.delete_prompt=ล ฤซ darbฤซba pilnฤซbฤ dzฤsฤซs ลกo organizฤciju, kฤ arฤซ tฤ ir NEATGRIEZENISKA !
-settings.confirm_delete_account=Apstiprinฤt dzฤลกanu
-settings.delete_org_title=Dzฤst organizฤciju
-settings.delete_org_desc=Organizฤcija tiks dzฤsta neatgriezeniski. Vai turpinฤt?
-settings.hooks_desc=Pievienot tฤซmekฤผa ฤฤทus, kas nostrฤdฤs visiem repozitorijiem ลกajฤ organizฤcijฤ.
+settings.update_settings=Atjauninฤt iestatฤซjumus
+settings.update_setting_success=Apvienฤซbas iestatฤซjumi tika atjauninฤti.
+settings.change_orgname_prompt=Piezฤซme: apvienฤซbas nosaukuma maiลa izmainฤซs arฤซ apvienฤซbas URL un atbrฤซvos veco nosaukumu.
+settings.change_orgname_redirect_prompt=Vecais nosaukums pฤrvirzฤซs, lฤซdz tas bลซs izmantots.
+settings.update_avatar_success=Apvienฤซbas attฤls tika atjauninฤts.
+settings.delete=Izdzฤst apvienฤซbu
+settings.delete_account=Izdzฤst ลกo apvienฤซbu
+settings.delete_prompt=Apvienฤซba tiks neatgriezeniski noลemta. To NEVAR atsaukt.
+settings.confirm_delete_account=Apstiprinฤt izdzฤลกanu
+settings.delete_org_title=Izdzฤst apvienฤซbu
+settings.delete_org_desc=ล ฤซ apvienฤซba tiks neatgriezeniski izdzฤsta. Turpinฤt?
+settings.hooks_desc=Pievienot tฤซmekฤผa aizฤทeres, kas iedarbosies ลกฤซs apvienฤซbas visฤs glabฤtavฤs .
-settings.labels_desc=Pievienojiet etiฤทetes, kas var tikt izmantotas visos ลกฤซs organizฤcijas repozitorijos.
+settings.labels_desc=Pievienot iezฤซmes, kas var tikt izmantotas pieteikumos ลกฤซs apvienฤซbas visฤs glabฤtavฤs .
-members.membership_visibility=Dalฤซbnieka redzamฤซba:
+members.membership_visibility=Dalฤซbnieku redzamฤซba:
members.public=Redzams
-members.public_helper=padarฤซt slฤptu
+members.public_helper=Padarฤซt slฤptu
members.private=Slฤpts
-members.private_helper=padarฤซt redzemu
+members.private_helper=Padarฤซt redzamu
members.member_role=Dalฤซbnieka loma:
members.owner=ฤชpaลกnieks
members.member=Dalฤซbnieks
members.remove=Noลemt
-members.remove.detail=Noลemt lietotฤju %[1]s no organizฤcijas %[2]s?
-members.leave=Atstฤt
-members.leave.detail=Pamest organizฤciju %s?
-members.invite_desc=Pievienot jaunu dalฤซbnieku pie %s:
+members.remove.detail=Noลemt %[1]s no %[2]s?
+members.leave=Pamest
+members.leave.detail=Vai tieลกฤm pamest apvienฤซbu "%s"?
+members.invite_desc=Pievienot jaunu dalฤซbnieku %s:
members.invite_now=Uzaicinฤt tagad
teams.join=Pievienoties
-teams.leave=Atstฤt
-teams.leave.detail=Pamest organizฤciju %s?
-teams.can_create_org_repo=Veidot jaunus repozitorijus
-teams.can_create_org_repo_helper=Komandas biedri varฤs veidot jaunus repozitorijus ลกajฤ organizฤcijฤ. Izveidotฤjam tiks pieลกฤทirtas administratora tiesฤซbas uz jauno repozitoriju.
+teams.leave=Pamest
+teams.leave.detail=Vai tieลกฤm pamest komandu "%s"?
+teams.can_create_org_repo=Izveidot glabฤtavas
+teams.can_create_org_repo_helper=Dalฤซbnieki apvienฤซbฤ var izveidot jaunas glabฤtavas. Izveidotฤjs iegลซs jaunฤs glabฤtavas pฤrvaldฤซtฤja piekฤผuvi.
teams.none_access=Nav piekฤผuves
-teams.none_access_helper=Komandai nebลซs tiesฤซbu skatฤซties vai veikt citas darbฤซbas ar ลกo vienumu.
-teams.general_access=Vispฤrฤja piekฤผuve
+teams.none_access_helper="Nav piekฤผuve" iespฤja iedarbojas tikai privฤtฤs glabฤtavฤs.
+teams.general_access=Pielฤgota piekฤผuve
teams.general_access_helper=Komandas tiesฤซbas tiks noteiktas pฤc tabulas zemฤk.
-teams.read_access=Skatฤซลกanฤs
+teams.read_access=Lasฤซt
teams.read_access_helper=Komanda varฤs skatฤซties un klonฤt ลกฤซs organizฤcijas repozitorijus.
-teams.write_access=Rakstฤซลกanas
+teams.write_access=Rakstฤซt
teams.write_access_helper=ล ฤซ komanda varฤs lasฤซt un nosลซtฤซt izmaiลas uz tฤs repozitorijiem.
-teams.admin_access=Administratora piekฤผuve
-teams.admin_access_helper=ล ฤซ komanda varฤs nosลซtฤซt un saลemt izmaiลas no tฤs repozitorijiem, kฤ arฤซ pievienot tiem citus lฤซdzstrฤdniekus.
+teams.admin_access=Pฤrvaldฤซtฤja piekฤผuve
+teams.admin_access_helper=Dalฤซbnieki var atgฤdฤt un aizgฤdฤt izmaiลas uz komandas glabฤtavฤm un pievienot tฤm lฤซdzdalฤซbniekus.
teams.no_desc=Komandai nav apraksta
teams.settings=Iestatฤซjumi
-teams.owners_permission_desc=ฤชpaลกniekiem ir pilna piekฤผuve visiem repozitorijiem un ir organizฤcijas administratora tiesฤซbas .
-teams.members=Komandas biedri
-teams.update_settings=Saglabฤt iestatฤซjumus
-teams.delete_team=Dzฤst komandu
-teams.add_team_member=Pievienot komandas biedru
+teams.owners_permission_desc=ฤชpaลกniekiem ir pilna piekฤผuve visฤm glabฤtavฤm un ir apvienฤซbas pฤrvaldฤซtฤja tiesฤซbas .
+teams.members=Komandas dalฤซbnieki
+teams.update_settings=Atjauninฤt iestatฤซjumus
+teams.delete_team=Izdzฤst komandu
+teams.add_team_member=Pievienot komandas dalฤซbnieku
teams.invite_team_member=`Uzaicinฤt komandฤ "%s"`
-teams.invite_team_member.list=Neapstiprinฤtie uzaicinฤjumi
-teams.delete_team_title=Dzฤst komandu
-teams.delete_team_desc=Dzฤลกot komandu, tฤs biedri var zaudฤt piekฤผuvi daลพiem vai pat visiem repozitorijiem. Vai turpinฤt?
+teams.invite_team_member.list=Neapstiprinฤti uzaicinฤjumi
+teams.delete_team_title=Izdzฤst komandu
+teams.delete_team_desc=Komandas izdzฤลกana tฤs dalฤซbniekiem atsauc piekฤผuvi glabฤtavฤm. Turpinฤt?
teams.delete_team_success=Komanda tika izdzฤsta.
-teams.read_permission_desc=ล ai komandai ir lasฤซลกanas tiesฤซbas: dalฤซbnieki var skatฤซties un klonฤt komandas repozitorijus.
-teams.write_permission_desc=ล ai komandai ir rakstฤซลกanas tiesฤซbas: dalฤซbnieki var lasฤซt un nosลซtฤซt izmaiลas repozitorijiem.
-teams.admin_permission_desc=ล ai komandai ir administratora tiesฤซbas: dalฤซbnieki var lasฤซt, rakstฤซt un pievienot citus dalฤซbniekus komandas repozitorijiem.
-teams.create_repo_permission_desc=Papildus ลกฤซ komanda pieลกฤทirt Veidot repozitorijus tiesฤซbas: komandas biedri var veidot jaunus repozitorijus ลกajฤ organizฤcijฤ.
-teams.repositories=Komandas repozitoriji
+teams.read_permission_desc=ล ฤซ komanda nodroลกina lasฤซลกanas piekฤผuvi: dalฤซbnieki var apskatฤซt un klonฤt komandas glabฤtavas.
+teams.write_permission_desc=ล ฤซ komanda nodroลกina rakstฤซลกanas piekฤผuvi: dalฤซbnieki var lasฤซt un aizgฤdฤt izmaiลas uz komandas glabฤtavฤm.
+teams.admin_permission_desc=ล ฤซ komanda nodroลกina pฤrvaldฤซtฤja piekฤผuvi: dalฤซbnieki var lasฤซt no, aizgฤdฤt izmaiลas uz un pievienot lฤซdzdalฤซbniekus komandas glabฤtavฤm.
+teams.create_repo_permission_desc=Papildus ลกฤซ komanda nodroลกina atฤผauju Izveidot glabฤtavu : dalฤซbnieki apvienฤซbฤ var izveidot jaunas glabฤtavas.
+teams.repositories=Komandas glabฤtavas
teams.search_repo_placeholder=Meklฤt repozitorijฤโฆ
-teams.remove_all_repos_title=Noลemt visus komandas repozitorijus
-teams.remove_all_repos_desc=ล ฤซ darbฤซba noลems visus repozitorijus no komandas.
-teams.add_all_repos_title=Pievienot visus repozitorijus
-teams.add_all_repos_desc=ล ฤซ darbฤซba pievienos visus organizฤcijas repozitorijus ลกai komandai.
-teams.add_nonexistent_repo=Repozitorijs, kuru mฤฤฃinat pievienot neeksistฤ, sฤkumฤ izveidojiet to.
+teams.remove_all_repos_title=Noลemt visas komandas glabฤtavas
+teams.remove_all_repos_desc=ล ฤซ darbฤซba noลems visas komandas glabฤtavas.
+teams.add_all_repos_title=Pievienot visas glabฤtavas
+teams.add_all_repos_desc=Komandai tiks pievienotas visas apvienฤซbas glabฤtavas.
+teams.add_nonexistent_repo=Pievienojamฤ glabฤtava nepastฤv, lลซgums vispirms to izveidot.
teams.add_duplicate_users=Lietotฤjs jau ir ลกajฤ komandฤ.
-teams.repos.none=ล ai komandai nav piekฤผuves nevienam repozitorijam.
-teams.members.none=ล ajฤ komandฤ nav pievienots neviens lietotฤjs.
-teams.specific_repositories=Atseviลกฤทi repozitoriji
-teams.specific_repositories_helper=Komandas biedriem bลซs piekฤผuve tikai pie norฤdฤซtฤjiem repozitorijiem. Atzฤซmฤjot ลกo netiks automฤtiksi noลemti repozitoriji, kas tika pievienoti ar pazฤซmi Visi repozitoriji .
-teams.all_repositories=Visi repozitoriji
-teams.all_repositories_helper=ล ai komandai ir piekฤผuve visiem repozitorijiem. Atzฤซmฤjot ลกo visi organizฤcijas repozitoriji tiks pievienoti ลกai komandai.
+teams.repos.none=ล ฤซ komanda nevarฤja piekฤผลซt nevienai glabฤtavai.
+teams.members.none=ล ajฤ komandฤ nav dalฤซbnieku.
+teams.specific_repositories=Noteiktas glabฤtavas
+teams.specific_repositories_helper=Dalฤซbniekiem bลซs piekฤผuve tikai komandai pievienotajฤm glabฤtavฤm. Pฤc ลกฤซ atlasฤซลกanas netiks automฤtiski noลemtas glabฤtavas, kas jau tika pievienotas ar Visas glabฤtavas .
+teams.all_repositories=Visas glabฤtavas
+teams.all_repositories_helper=Komandai ir piekฤผuve visฤm glabฤtavฤm. ล ฤซ atlasฤซลกana komandai pievienos visas esoลกฤs glabฤtavas.
teams.all_repositories_read_permission_desc=ล ฤซ komanda pieลกฤทirt skatฤซลกanฤs tiesฤซbas visiem repozitorijiem : komandas biedri var skatฤซties un klonฤt visus organizฤcijas repozitorijus.
teams.all_repositories_write_permission_desc=ล ฤซ komanda pieลกฤทirt laboลกanas tiesฤซbas visiem repozitorijiem : komandas biedri var skatฤซties un nosลซtฤซt izmaiลas visiem organizฤcijas repozitorijiem.
teams.all_repositories_admin_permission_desc=ล ฤซ komanda pieลกฤทirt administratora tiesฤซbas visiem repozitorijiem : komandas biedri var skatฤซties, nosลซtฤซt izmaiลas un mainฤซt iestatฤซjumus visiem organizฤcijas repozitorijiem.
-teams.invite.title=Tu esi uzaicinฤts pievienoties organizฤcijas %[2]s komandai %[1]s .
+teams.invite.title=Tevi uzaicinฤja pievienoties komandai %s apvienฤซbฤ %s .
teams.invite.by=Uzaicinฤja %s
-teams.invite.description=Nospiediet pogu zemฤk, lai pievienotos komandai.
+teams.invite.description=Lลซgums nospiest zemฤk esoลกo pogu, lai pievienotos komandai.
+open_dashboard = Atvฤrt pฤrskata paneli
+follow_blocked_user = Tu nevari sekot ลกai apvienฤซbai, jo tฤ ir liegusi Tevi.
+settings.change_orgname_redirect_prompt.with_cooldown.one = Vecais apvienฤซbas nosaukums bลซs pieejams visiem pฤc noilguma, kas ir %[1]d diena. ล ajฤ laikฤ ir iespฤjams to atkal sฤkt izmantot.
+settings.change_orgname_redirect_prompt.with_cooldown.few = Vecais apvienฤซbas nosaukums bลซs pieejams visiem pฤc noilguma, kas ir %[1]d dienas. ล ajฤ laikฤ ir iespฤjams to atkal sฤkt izmantot.
[admin]
-dashboard=Infopanelis
+dashboard=Pฤrskata panelis
self_check=Paลกpฤrbaude
identity_access=Identitฤte un piekฤผuve
users=Lietotฤju konti
-organizations=Organizฤcijas
-assets=Koda aktฤซvi
-repositories=Repozitoriji
-hooks=Tฤซmekฤผa ฤฤทi
+organizations=Apvienฤซbas
+assets=Koda lฤซdzekฤผi
+repositories=Glabฤtavas
+hooks=Tฤซmekฤผa aizฤทeres
integrations=Integrฤcijas
authentication=Autentificฤลกanas avoti
-emails=Lietotฤja e-pasts
+emails=Lietotฤju e-pasta adreses
config=Konfigurฤcija
notices=Sistฤmas paziลojumi
-monitor=Uzraudzฤซba
+monitor=Pฤrraudzฤซลกana
first_page=Pirmฤ
last_page=Pฤdฤjฤ
total=Kopฤ: %d
-settings=Administratora iestatฤซjumi
+settings=Pฤrvaldฤซลกanas iestatฤซjumi
-dashboard.new_version_hint=Ir pieejama Forgejo versija %s, paลกreizฤjฤ versija %s. Papildus informฤcija par jauno versiju ir pieejama mฤjas lapฤ .
+dashboard.new_version_hint=Ir pieejama Forgejo %s, paลกlaik darbojas %s. Vairฤk informฤcijas ir atrodama emuฤrฤ .
dashboard.statistic=Kopsavilkums
dashboard.operations=Uzturฤลกanas darbฤซbas
-dashboard.system_status=Sistฤmas statuss
+dashboard.system_status=Sistฤmas stฤvoklis
dashboard.operation_name=Darbฤซbas nosaukums
dashboard.operation_switch=Pฤrslฤgt
dashboard.operation_run=Palaist
@@ -2738,342 +3085,342 @@ dashboard.task.unknown=Nezinฤms uzdevums: %[1]s
dashboard.cron.started=Uzsฤkts Cron: %[1]s
dashboard.cron.process=Cron: %[1]s
dashboard.cron.cancelled=Cron: %[1]s atcelts: %[3]s
-dashboard.cron.error=Kฤผลซda Cron: %s: %[3]s
+dashboard.cron.error=Cron kฤผลซda: %s: %[3]s
dashboard.cron.finished=Cron: %[1]s pabeigts
-dashboard.delete_inactive_accounts=Dzฤst visus neaktivizฤtos kontus
-dashboard.delete_inactive_accounts.started=Uzdevums visu neaktivizฤto kontu dzฤลกanai uzsฤkts.
-dashboard.delete_repo_archives=Dzฤst visu repozitoriju arhฤซvus (ZIP, TAR.GZ utt.)
-dashboard.delete_repo_archives.started=Uzdevums visu repozitoriju arhฤซvu dzฤลกanai uzsฤkts.
-dashboard.delete_missing_repos=Dzฤst visus repozitorijus, kam trลซkst Git failu
-dashboard.delete_missing_repos.started=Uzdevums visu repozitoriju dzฤลกanai, kam trลซkst git failu, uzsฤkts.
-dashboard.delete_generated_repository_avatars=Dzฤst ฤฃenerฤtos repozitoriju attฤlus
-dashboard.sync_repo_branches=Sinhronizฤcija ar dabubฤzi izlaida atzarus no git datiem
-dashboard.update_mirrors=Atjaunot spoguฤผus
-dashboard.repo_health_check=Pฤrbaudฤซt visu repozitoriju veselฤซbu
-dashboard.check_repo_stats=Pฤrbaudฤซt visu repozitoriju statistiku
-dashboard.archive_cleanup=Dzฤst repozitoriju vecos arhฤซvus
-dashboard.deleted_branches_cleanup=Notฤซrฤซt dzฤstos atzarus
-dashboard.update_migration_poster_id=Atjaunot migrฤcijฤm autoru ID
-dashboard.git_gc_repos=Veikt atkritumu uzkopลกanas darbus visiem repozitorijiem
-dashboard.resync_all_sshkeys=Atjaunot '.ssh/authorized_keys' failu ar Forgejo SSH atslฤgฤm.
-dashboard.resync_all_sshprincipals=Atjaunot '.ssh/authorized_principals' failu ar Forgejo SSH sertifikฤtu identitฤtฤm.
-dashboard.resync_all_hooks=Pฤrsinhronizฤt pirms-saลemลกanas, atjaunoลกanas un pฤc-saลemลกanas ฤฤทus visiem repozitorijiem.
-dashboard.reinit_missing_repos=Atkฤrtoti inicializฤt visus pazaudฤtos Git repozitorijus par kuriem eksistฤ ieraksti
+dashboard.delete_inactive_accounts=Izdzฤst visus neaktivฤtos kontus
+dashboard.delete_inactive_accounts.started=Ir uzsฤkts visu neaktivฤto kontu izdzฤลกanas uzdevums.
+dashboard.delete_repo_archives=Izdzฤst visus glabฤtavu arhฤซvus (ZIP, TAR.GZ utt.)
+dashboard.delete_repo_archives.started=Visu glabฤtavas arhฤซvu izdzฤลกanas uzdevums ir uzsฤkts.
+dashboard.delete_missing_repos=Izdzฤst visas glabฤtavas, kurฤm trลซkst Git datลu
+dashboard.delete_missing_repos.started=Uzsฤkts uzdevums visu glabฤtavu, kurฤm trลซkst Git datลu, izdzฤลกanai.
+dashboard.delete_generated_repository_avatars=Izdzฤst izveidotos glabฤtavu attฤlus
+dashboard.sync_repo_branches=Sinhronizฤลกana datubฤzฤs izlaida zarus no Git datiem
+dashboard.update_mirrors=Atjauninฤt spoguฤผglabฤtavas
+dashboard.repo_health_check=Pฤrbaudฤซt visu glabฤtavu darbspฤju
+dashboard.check_repo_stats=Pฤrbaudฤซt visu glabฤtavas apkopojumu
+dashboard.archive_cleanup=Izdzฤst vecos glabฤtavu arhฤซvus
+dashboard.deleted_branches_cleanup=Notฤซrฤซt izdzฤstos zarus
+dashboard.update_migration_poster_id=Atjauninฤt pฤrcelลกanas ierosinฤtฤja identifikatorus
+dashboard.git_gc_repos=Veikt drazu savฤkลกanu visฤs glabฤtavฤs
+dashboard.resync_all_sshkeys=Atjauninฤt datni ".ssh/authorized_keys" ar Forgejo SSH atslฤgฤm.
+dashboard.resync_all_sshprincipals=Atjauninฤt datni ".ssh/authorized_principals" ar Forgejo SSH identitฤtฤm.
+dashboard.resync_all_hooks=Atkฤrtoti sinhronizฤt pirmssaลemลกanas, atjauninฤลกanas un pฤcsaลemลกans aizฤทeres visฤs glabฤtavฤs
+dashboard.reinit_missing_repos=Atkฤrtoti sฤknฤt visas trลซkstoลกฤs Git glabฤtavas, par kurฤm ir ieraksti
dashboard.sync_external_users=Sinhronizฤt ฤrฤjo lietotฤju datus
-dashboard.cleanup_hook_task_table=Iztฤซrฤซt tฤซmekฤผa ฤฤทu vฤsturi
+dashboard.cleanup_hook_task_table=Iztฤซrฤซt tabulu hook_task
dashboard.cleanup_packages=Notฤซrฤซt novecojuลกฤs pakotnes
dashboard.cleanup_actions=Notฤซrฤซt darbฤซbu izbeiguลกos ลพurnฤlus un artefaktus
dashboard.server_uptime=Servera darbฤซbas laiks
-dashboard.current_goroutine=Izmantotฤs Gorutฤซnas
-dashboard.current_memory_usage=Paลกreiz izmantotฤ atmiลa
-dashboard.total_memory_allocated=Kopฤjฤ pieลกฤทirtฤ atmiลa
+dashboard.current_goroutine=Paลกreizฤjฤs gorutฤซnas
+dashboard.current_memory_usage=Paลกreizฤjais atmiลas lietojums
+dashboard.total_memory_allocated=Kopฤjฤ iedalฤซtฤ atmiลa
dashboard.memory_obtained=Iegลซtฤ atmiลa
-dashboard.pointer_lookup_times=Rฤdฤซtฤju meklฤลกanas reizes
-dashboard.memory_allocate_times=Atmiลas pieลกฤทirลกanas reizes
-dashboard.memory_free_times=Atmiลas atbrฤซvoลกanas reizes
-dashboard.current_heap_usage=Paลกreizฤjฤ kaudzes izmantoลกana
-dashboard.heap_memory_obtained=Iegลซtฤ kaudzes atmiลa
-dashboard.heap_memory_idle=Neizmantotฤ kaudzes atmiลa
-dashboard.heap_memory_in_use=Izmantotฤ kaudzes atmiลa
-dashboard.heap_memory_released=Atbrฤซvotฤ kaudzes atmiลa
-dashboard.heap_objects=Kaudzes atmiลas objekti
-dashboard.bootstrap_stack_usage=Izmantotais sฤknฤลกanas steka lielums
-dashboard.stack_memory_obtained=Iegลซtฤ steka atmiลa
-dashboard.mspan_structures_usage=Izmantotฤs MSpan struktลซras
+dashboard.pointer_lookup_times=Rฤdฤซtฤju uzmeklฤลกanas reizes
+dashboard.memory_allocate_times=Atmiลas iedalฤซลกanas
+dashboard.memory_free_times=Atmiลas atbrฤซvoลกanas
+dashboard.current_heap_usage=Paลกreizฤjais grฤdas lietojums
+dashboard.heap_memory_obtained=Iegลซtฤ grฤdas atmiลa
+dashboard.heap_memory_idle=Neizmantotฤ grฤdas atmiลa
+dashboard.heap_memory_in_use=Izmantotฤ grฤdas atmiลa
+dashboard.heap_memory_released=Atbrฤซvotฤ grฤdas atmiลa
+dashboard.heap_objects=Grฤdas objekti
+dashboard.bootstrap_stack_usage=Sฤkumielฤdฤtฤja viengala rindas lietojums
+dashboard.stack_memory_obtained=Iegลซtฤ viengala rindas atmiลa
+dashboard.mspan_structures_usage=MSpan struktลซru lietojums
dashboard.mspan_structures_obtained=Iegลซtฤs MSpan struktลซras
-dashboard.mcache_structures_usage=Izmantotฤs MCache struktลซras
+dashboard.mcache_structures_usage=MCache struktลซru lietojums
dashboard.mcache_structures_obtained=Iegลซtฤs MCache struktลซras
-dashboard.profiling_bucket_hash_table_obtained=Iegลซtฤ profilฤลกanas kausa jaucฤjtabula
+dashboard.profiling_bucket_hash_table_obtained=Iegลซtฤ profilฤลกanas groza jaucฤjtabula
dashboard.gc_metadata_obtained=Iegลซtie GC metadati
-dashboard.other_system_allocation_obtained=Iegลซtฤs citas sistฤmas sadales
-dashboard.next_gc_recycle=Nฤkoลกฤ GC atkritne
+dashboard.other_system_allocation_obtained=Citas iegลซtฤs sistฤmas sadales
+dashboard.next_gc_recycle=Nฤkamฤ GC atkritne
dashboard.last_gc_time=Laiks kopลก pฤdฤjฤs GC
dashboard.total_gc_time=Kopฤjais GC izpildes laiks
-dashboard.total_gc_pause=Kopฤjais GC izpildes laiks
-dashboard.last_gc_pause=Pedฤjฤs GC izpildes laiks
+dashboard.total_gc_pause=Kopฤjais GC pฤrtraukums
+dashboard.last_gc_pause=Pedฤjais GC pฤrtraukums
dashboard.gc_times=GC reizes
-dashboard.delete_old_actions=Dzฤst visas darbฤซbas no datu bฤzes
-dashboard.delete_old_actions.started=Uzsฤkta visu novecojuลกo darbฤซbu dzฤลกana no datu bฤzes.
+dashboard.delete_old_actions=Izdzฤst visas novecojuลกฤs darbฤซbas no datubฤzes
+dashboard.delete_old_actions.started=Uzsฤkta visu novecojuลกo darbฤซbu izdzฤลกana no datubฤzes.
dashboard.update_checker=Atjauninฤjumu pฤrbaudฤซtฤjs
dashboard.delete_old_system_notices=Dzฤst vecos sistฤmas paziลojumus no datubฤzes
dashboard.gc_lfs=Veikt atkritumu uzkopลกanas darbus LFS meta objektiem
-dashboard.stop_zombie_tasks=Apturฤt zombija uzdevumus
-dashboard.stop_endless_tasks=Apturฤt nepฤrtrauktus uzdevumus
-dashboard.cancel_abandoned_jobs=Atcelt pamestus darbus
-dashboard.start_schedule_tasks=Sฤkt plฤnotos uzdevumus
-dashboard.sync_branch.started=Sฤkta atzaru sinhronizฤcija
-dashboard.rebuild_issue_indexer=Pฤrbลซvฤt problฤmu indeksu
+dashboard.stop_zombie_tasks=Apturฤt darbฤซbu zombijuzdevumus
+dashboard.stop_endless_tasks=Apturฤt bezgalฤซgus darbฤซbu uzdevumus
+dashboard.cancel_abandoned_jobs=Atcelt pamestus darbฤซbu darbus
+dashboard.start_schedule_tasks=Uzsฤkt paredzฤtos darbฤซbu uzdevumus
+dashboard.sync_branch.started=Uzsฤkta zaru sinhronizฤลกana
+dashboard.rebuild_issue_indexer=Pฤrbลซvฤt pieteikumu indeksฤtฤju
-users.user_manage_panel=Lietotฤju kontu pฤrvaldฤซba
+users.user_manage_panel=Pฤrvaldฤซt lietotฤju kontus
users.new_account=Izveidot lietotฤja kontu
users.name=Lietotฤjvฤrds
-users.full_name=Vฤrds, uzvฤrds
-users.activated=Aktivizฤts
-users.admin=Administrators
+users.full_name=Pilns vฤrds
+users.activated=Aktivฤts
+users.admin=Pฤrvaldฤซtฤjs
users.restricted=Ierobeลพots
users.reserved=Aizลemts
-users.bot=Bots
+users.bot=Robotprogrammatลซra
users.remote=Attฤls
users.2fa=2FA
-users.repos=Repozitoriji
+users.repos=Glabฤtavas
users.created=Izveidots
users.last_login=Pฤdฤjฤ pieteikลกanฤs
-users.never_login=Pieteikลกanฤs nekad nav veikta
-users.send_register_notify=Nosลซtฤซt lietotฤjam reฤฃistrฤcijas paziลojumu
+users.never_login=Pieteikลกanฤs nekad nav notikusi
+users.send_register_notify=Paziลot par reฤฃistrฤciju e-pastฤ
users.new_success=Lietotฤja konts "%s" tika izveidots.
users.edit=Labot
-users.auth_source=Autentificฤลกanas avots
+users.auth_source=Autentificฤลกanฤs avots
users.local=Iebลซvฤtฤ
-users.auth_login_name=Autentifikฤcijas pieteikลกanฤs vฤrds
-users.password_helper=Atstฤjiet paroli tukลกu, ja nevฤlaties mainฤซt.
-users.update_profile_success=Lietotฤja konts tika atjaunots.
+users.auth_login_name=Autentificฤลกanฤs pieteikลกanฤs vฤrds
+users.password_helper=Atstฤt paroli tukลกu, lai paturฤtu to neizmainฤซtu.
+users.update_profile_success=Lietotฤja konts tika atjauninฤts.
users.edit_account=Labot lietotฤja kontu
-users.max_repo_creation=Maksimฤlais repozitoriju skaits
-users.max_repo_creation_desc=(Ievadiet -1 lai izmantotu noklusฤto globฤlo ierobeลพojumu)
-users.is_activated=Lietotฤja konts ir aktivizฤts
-users.prohibit_login=Atspฤjota pieteikลกanฤs
-users.is_admin=Administratora tiesฤซbas
-users.is_restricted=Ir ierobeลพots
-users.allow_git_hook=Atฤผaut veidot git ฤฤทus
-users.allow_git_hook_tooltip=Git ฤฤทi tiek izpildฤซti ar OS lietotฤju zem kura ir izpildฤซts Forgejo serviss un tiem ir tฤda paลกa lฤซmeลa piekฤผuve serverim. ล ฤซ rezultฤtฤ, lietotฤjiem ar speciฤlajฤm Git ฤฤทu tiesฤซbฤm ir iespฤja piekฤผลซt un mainฤซt visus Forgejo repozitorijus, kฤ arฤซ datu bฤzi, ko izmanto Forgejo. Tฤpat ลกie lietotฤji var iegลซt Forgejo administratora tiesฤซbas.
-users.allow_import_local=Atฤผauts importฤt lokฤlus repozitorijus
-users.allow_create_organization=Atฤผauts veidot organizฤcijas
-users.update_profile=Mainฤซt lietotฤja kontu
-users.delete_account=Dzฤst lietotฤja kontu
+users.max_repo_creation=Lielฤkais pieฤผaujamais glabฤtavu skaits
+users.max_repo_creation_desc=(Jฤievada -1, lai izmantotu vispฤrฤjo noklusฤjuma ierobeลพojumu)
+users.is_activated=Aktivฤts konts
+users.prohibit_login=Apturฤta pieteikลกanฤs
+users.is_admin=Pฤrvaldฤซtฤja konts
+users.is_restricted=Ierobeลพots konts
+users.allow_git_hook=Var izveidot Git aizฤทeres
+users.allow_git_hook_tooltip=Git aizฤทeres tiek izpildฤซtas ar OS lietotฤju, ar kuru tiek palaists Forgejo, un tฤm ir tฤda paลกa lฤซmeลa piekฤผuve sistฤmai. Iznฤkumฤ lietotฤji ar ลกo ฤซpaลกo Git aizฤทeru tiesฤซbu var piekฤผลซt un mainฤซt visas Forgejo glabฤtavas, kฤ arฤซ Forgejo izmantoto datu bฤzi. Tฤtad tie var arฤซ iegลซt Forgejo pฤrvaldฤซtฤja tiesฤซbas.
+users.allow_import_local=Var ievietot vietฤjas glabฤtavas
+users.allow_create_organization=Var izveidot apvienฤซbas
+users.update_profile=Atjauninฤt lietotฤja kontu
+users.delete_account=Izdzฤst lietotฤja kontu
users.cannot_delete_self=Nevar izdzฤst sevi
-users.still_own_repo=Lietotฤjam pieder repozitoriji, tos sฤkumฤ ir nepiecieลกams izdzฤst vai mainฤซt to ฤซpaลกnieku.
-users.still_has_org=ล is lietotฤjs ir vienas vai vairฤku organizฤciju biedrs, lietotฤju sฤkumฤ ir nepiecieลกams pamest ลกฤซs organizฤcijas vai viลu no tฤm ir jฤizdzฤลก.
-users.purge=Attฤซrฤซt lietotu
-users.purge_help=Piespiedu dzฤst lietotฤju un visus tฤ repozitorijus, organizฤcijas un pakotnes. Arฤซ visi lietotฤja komentฤri tiks dzฤsti.
+users.still_own_repo=ล im lietotฤjam joprojฤm pieder viena vai vairฤkas glabฤtavas. Tฤs vispirms jฤizdzฤลก vai jฤnodod.
+users.still_has_org=ล is lietotฤjs ir apvienฤซbas dalฤซbnieks. Vispirms lietotฤjs ir jฤnoลem no visฤm apvienฤซbฤm.
+users.purge=Atbrฤซvoties no lietotฤja
+users.purge_help=Veikt lietotฤja un visu tam piederoลกo glabฤtavu, apvienฤซbu un pakotลu uzspiestu izdzฤลกanu. Tiks izdzฤstas visas piebildes un lietotฤja izveidotie pieteikumi.
users.still_own_packages=ล im lietotฤjam pieder viena vai vairฤkas pakotnes, tฤs nepiecieลกams izdzฤst.
-users.deletion_success=Lietotฤja konts veiksmฤซgi izdzฤsts.
-users.reset_2fa=Noลemt 2FA
-users.list_status_filter.menu_text=Filtrs
+users.deletion_success=Lietotฤja konts tika izdzฤsts.
+users.reset_2fa=Atiestatฤซt 2FA
+users.list_status_filter.menu_text=Atlasฤซt
users.list_status_filter.reset=Atiestatฤซt
users.list_status_filter.is_active=Aktฤซvs
users.list_status_filter.not_active=Neaktฤซvs
-users.list_status_filter.is_admin=Admin
-users.list_status_filter.not_admin=Nav administrators
+users.list_status_filter.is_admin=Pฤrvaldฤซtฤjs
+users.list_status_filter.not_admin=Nav pฤrvaldฤซtฤjs
users.list_status_filter.is_restricted=Ierobeลพots
users.list_status_filter.not_restricted=Nav ierobeลพots
-users.list_status_filter.is_prohibit_login=Nav atฤผauta autorizฤลกanฤs
-users.list_status_filter.not_prohibit_login=Atฤผaut autorizฤciju
-users.list_status_filter.is_2fa_enabled=2FA iespฤjots
-users.list_status_filter.not_2fa_enabled=2FA nav iespฤjots
+users.list_status_filter.is_prohibit_login=Neฤผaut pieteikลกanos
+users.list_status_filter.not_prohibit_login=Atฤผaut pieteikลกanos
+users.list_status_filter.is_2fa_enabled=2FA iespฤjota
+users.list_status_filter.not_2fa_enabled=2FA atspฤjota
users.details=Lietotฤja informฤcija
-emails.email_manage_panel=Lietotฤju e-pastu pฤrvaldฤซba
-emails.primary=Primฤrais
-emails.activated=Aktivizฤts
-emails.filter_sort.email=E-pasts
-emails.filter_sort.email_reverse=E-pasta adrese (pretฤji alfabฤtiski)
+emails.email_manage_panel=Pฤrvaldฤซt lietotฤju e-pasta adreses
+emails.primary=Galvenฤ
+emails.activated=Aktivฤta
+emails.filter_sort.email=E-pasta adrese
+emails.filter_sort.email_reverse=E-pasta adrese (apvฤrsti)
emails.filter_sort.name=Lietotฤjvฤrds
-emails.filter_sort.name_reverse=Lietotฤja vฤrds (pretฤji alfabฤtiski)
-emails.updated=E-pasts atjaunots
-emails.not_updated=Neizdevฤs atjaunot pieprasฤซto e-pasta adresi: %v
+emails.filter_sort.name_reverse=Lietotฤja vฤrds (apvฤrsti)
+emails.updated=E-pasta adrese atjauninฤta
+emails.not_updated=Neizdevฤs atjauninฤt pieprasฤซto e-pasta adresi: %v
emails.duplicate_active=E-pasta adrese jau ir aktฤซva citam lietotฤjam.
-emails.change_email_header=Atjaunot e-pasta rekvizฤซtus
-emails.change_email_text=Vai patieลกฤm vฤlaties atjaunot ลกo e-pasta adresi?
+emails.change_email_header=Atjauninฤt e-pasta ฤซpaลกฤซbas
+emails.change_email_text=Vai tieลกฤm atjauninฤt ลกo e-pasta adresi?
-orgs.org_manage_panel=Organizฤciju pฤrvaldฤซba
+orgs.org_manage_panel=Pฤrvaldฤซt apvienฤซbas
orgs.name=Nosaukums
orgs.teams=Komandas
orgs.members=Dalฤซbnieki
-orgs.new_orga=Jauna organizฤcija
+orgs.new_orga=Jauna apvienฤซba
-repos.repo_manage_panel=Repozitoriju pฤrvaldฤซba
-repos.unadopted=Nepฤrลemtie repozitoriji
-repos.unadopted.no_more=Netika atrasts neviens nepฤrลemtais repozitorijs
+repos.repo_manage_panel=Pฤrvaldฤซt glabฤtavas
+repos.unadopted=Nepieลemtฤs glabฤtavas
+repos.unadopted.no_more=Nav atrasta neviena nepieลemta glabฤtava.
repos.owner=ฤชpaลกnieks
repos.name=Nosaukums
-repos.private=Privฤts
+repos.private=Privฤta
repos.watches=Vฤroลกana
repos.stars=Zvaigznes
repos.forks=Atdalฤซtie
-repos.issues=Problฤmas
+repos.issues=Pieteikumi
repos.size=Izmฤrs
-repos.lfs_size=LFS izmฤrs
+repos.lfs_size=LFS lielums
-packages.package_manage_panel=Pakotลu pฤrvaldฤซba
-packages.total_size=Kopฤjais izmฤrs: %s
-packages.unreferenced_size=Izmฤrs bez atsauces: %s
+packages.package_manage_panel=Pฤrvaldฤซt pakotnes
+packages.total_size=Kopฤjais lielums: %s
+packages.unreferenced_size=Lielums bez atsauces: %s
packages.cleanup=Notฤซrฤซt novecojuลกos datus
-packages.cleanup.success=Novecojuลกi dati veiksmฤซgi notฤซrฤซti
+packages.cleanup.success=Izbeiguลกies dati sekmฤซgi notฤซrฤซti
packages.owner=ฤชpaลกnieks
packages.creator=Izveidotฤjs
packages.name=Nosaukums
packages.version=Versija
packages.type=Veids
-packages.repository=Repozitorijs
+packages.repository=Glabฤtava
packages.size=Izmฤrs
-packages.published=Publicฤts
+packages.published=Laista klajฤ
-defaulthooks=Noklusฤtie tฤซmekฤผa ฤฤทi
-defaulthooks.desc=Tฤซmekฤผa ฤฤทi automฤtiski nosลซta HTTP POST pieprasฤซjumus serverim, kad iestฤjas noteikti Gitea notikumi. ล eit pievienotie tฤซmekฤผa ฤฤทi ir noklusฤjuma, un tie tiks pievienoti visiem jaunajiem repozitorijiem. Vairฤk ir lasฤms tฤซmekฤผa ฤฤทu dokumentฤcijฤ .
-defaulthooks.add_webhook=Pievienot noklusฤto tฤซmekฤผa ฤฤทi
-defaulthooks.update_webhook=Mainฤซt noklusฤto tฤซmekฤผa ฤฤทi
+defaulthooks=Noklusฤjuma tฤซmekฤผa aizฤทeres
+defaulthooks.desc=Tฤซmekฤผa aizฤทeres automฤtiski nosลซta HTTP POST pieprasฤซjumus serverim, kad iestฤjas noteikti Forgejo notikumi. ล eit esoลกฤs tฤซmekฤผa aizฤทeres ir noklusฤjuma, un tฤs tiks ievietotas visฤs jaunajฤs glabฤtavฤs. Vairฤk ir lasฤms norฤdฤs par tฤซmekฤผa aizฤทerฤm .
+defaulthooks.add_webhook=Pievienot noklusฤjuma tฤซmekฤผa aizฤทeri
+defaulthooks.update_webhook=Atjauninฤt noklusฤjuma tฤซmekฤผa aizฤทeri
-systemhooks=Sistฤmas tฤซmekฤผa ฤฤทi
-systemhooks.desc=Tฤซmekฤผa ฤฤทi automฤtiski nosลซta HTTP POST pieprasฤซjumus serverim, kad iestฤjas noteikti Gitea notikumi. ล eit pievienotie tฤซmekฤผa ฤฤทi tiks izsaukti visiem sistฤmas repozitorijiem, tฤdฤฤผ lลซgums apsvฤrt to iespฤjamo ietekmi uz veiktspฤju. Vairฤk ir lasฤms tฤซmekฤผa ฤฤทu dokumentฤcijฤ .
-systemhooks.add_webhook=Pievienot sistฤmas tฤซmekฤผa ฤฤทi
-systemhooks.update_webhook=Mainฤซt sistฤmas tฤซmekฤผa ฤฤทi
+systemhooks=Sistฤmas tฤซmekฤผa aizฤทeres
+systemhooks.desc=Tฤซmekฤผa aizฤทeres automฤtiski nosลซta HTTP POST pieprasฤซjumus serverim, kad iestฤjas noteikti Forgejo notikumi. ล eit izveidotฤs tฤซmekฤผa aizฤทeres iedarbosies visฤs sistฤmas glabฤtavฤs, tฤdฤฤผ lลซgums apsvฤrt jebkuru iespฤjamo ietekmi uz veiktspฤju. Vairฤk ir lasฤms norฤdฤs par tฤซmekฤผa aizฤทerฤm .
+systemhooks.add_webhook=Pievienot sistฤmas tฤซmekฤผa aizฤทeri
+systemhooks.update_webhook=Atjauninฤt sistฤmas tฤซmekฤผa aizฤทeri
-auths.auth_manage_panel=Autentifikฤcijas avotu pฤrvaldฤซba
-auths.new=Pievienot autentifikฤcijas avotu
+auths.auth_manage_panel=Pฤrvaldฤซt autentificฤลกanฤs avotus
+auths.new=Pievienot autentificฤลกanas avotu
auths.name=Nosaukums
auths.type=Veids
auths.enabled=Iespฤjots
auths.syncenabled=Iespฤjot lietotฤju sinhronizฤciju
auths.updated=Atjauninฤta
-auths.auth_type=Autentifikฤcijas tips
-auths.auth_name=Autentifikฤcijas nosaukums
+auths.auth_type=Autentificฤลกanas veids
+auths.auth_name=Autentificฤลกanas nosaukums
auths.security_protocol=Droลกฤซbas protokols
auths.domain=Domฤns
auths.host=Resursdators
auths.port=Ports
auths.bind_dn=Saistฤซลกanas DN
auths.bind_password=Saistฤซลกanas parole
-auths.user_base=Lietotฤja pamatnosacฤซjumi
+auths.user_base=Lietotฤju meklฤลกanas pamatnosacฤซjumi
auths.user_dn=Lietotฤja DN
auths.attribute_username=Lietotฤjvฤrda atribลซts
-auths.attribute_username_placeholder=Atstฤjiet tukลกu, ja vฤlaties, lai tiek izmantots Forgejo ievadฤซtais lietotฤjvฤrds.
+auths.attribute_username_placeholder=Atstฤt tukลกu, lai izmantotu Forgejo ievadฤซto lietotฤjvฤrdu.
auths.attribute_name=Vฤrda atribลซts
auths.attribute_surname=Uzvฤrda atribลซts
auths.attribute_mail=E-pasta atribลซts
auths.attribute_ssh_public_key=Publiskฤs SSH atslฤgas atribลซts
auths.attribute_avatar=Profila attฤla atribลซts
auths.attributes_in_bind=Nolasฤซt atribลซtus no saistฤซลกanas DN konteksta
-auths.allow_deactivate_all=Atฤผaut tukลกam datu izgลซลกanas rezultฤtam deaktivizฤt visus lietotฤjus
-auths.use_paged_search=Izmantot, dalฤซto pa lapฤm, meklฤลกanu
-auths.search_page_size=Lapas izmฤrs
-auths.filter=Lietotฤju filts
-auths.admin_filter=Administratoru filtrs
-auths.restricted_filter=Ierobeลพoto lietotฤju filtrs
-auths.restricted_filter_helper=Atstฤjiet tukลกu, lai nevienam lietotajam neuzstฤdฤซt ierobeลพots pazฤซmi. Izmantojiet zvaigznฤซti ('*'), lai uzstฤdฤซtu visiem lietotฤjiem, kas neatbilst administratora filtram.
-auths.verify_group_membership=Pฤrbaudฤซt piederฤซbu LDAP grupai (atstฤjiet filtru tukลกu, lai neizmantotu)
-auths.group_search_base=Grupas pamatnosacฤซjumi
+auths.allow_deactivate_all=ฤปaut tukลกam meklฤลกanas iznฤkumam deaktivฤt visus lietotฤjus
+auths.use_paged_search=Izmantot meklฤลกanu ar lapotฤju
+auths.search_page_size=Lapas lielums
+auths.filter=Lietotฤju atlase
+auths.admin_filter=Pฤrvaldฤซtฤju atlase
+auths.restricted_filter=Ierobeลพoto lietotฤju atlase
+auths.restricted_filter_helper=Atstฤt tukลกu, lai nenorฤdฤซtu nevienu lietotฤju kฤ ierobeลพotu. Zvaigznฤซte ('*') ir izmantojama, lai norฤdฤซtu visus lietotฤjus, kas neatbilst pฤrvaldฤซtฤju atlasei, kฤ ierobeลพotus.
+auths.verify_group_membership=Pฤrbaudฤซt piederฤซbu LDAP kopai (atstฤt atlasi tukลกu, lai izlaistu)
+auths.group_search_base=Grupas meklฤลกanas pamata DN
auths.group_attribute_list_users=Grupas atribลซts, kas satur sarakstu ar lietotฤjiem
-auths.user_attribute_in_group=Grupas atribลซts, kas nosaka lietotฤju
-auths.map_group_to_team=Sasaistฤซt LDAP grupas ar organizฤcijas komandฤm (atstฤjiet tukลกu, lai to nedarฤซtu)
+auths.user_attribute_in_group=Lietotฤja atribลซts, kas ir uzskaitฤซts grupฤ
+auths.map_group_to_team=Sasaistฤซt LDAP kopas ar apvienฤซbas komandฤm (atstฤt lauku tukลกu, lai izlaistu)
auths.map_group_to_team_removal=Noลemt lietotฤjus no sinhronizฤtajฤm komandฤm, ja lietotฤjs nav piesaistฤซts attiecฤซgajai LDAP grupai
auths.enable_ldap_groups=Iespฤjot LDAP grupas
auths.ms_ad_sa=MS AD meklฤลกanas atribลซti
-auths.smtp_auth=SMTP autentifikฤcijas tips
+auths.smtp_auth=SMTP autentificฤลกanas veids
auths.smtphost=SMTP resursdators
auths.smtpport=SMTP ports
auths.allowed_domains=Atฤผautie domฤni
-auths.allowed_domains_helper=Atstฤjiet tukลกu, lai atฤผautu visus domฤnus. Lai norฤdฤซtu vairฤkus domฤnus, tos var atdalฤซt ar komatu (',').
+auths.allowed_domains_helper=Atstฤt tukลกu, lai atฤผautu visus domฤnus. Vairฤki domฤni ir atdalฤmi ar komatu (",").
auths.skip_tls_verify=Izlaist TLS pฤrbaudi
-auths.force_smtps=Piespiedu SMTPS izmantoลกana
-auths.force_smtps_helper=SMTPS vienmฤr tiks izmantots, ja ports ir 465. Uzstฤdiet ลกo, ja nepiecieลกams izmantot SMTPS ar citiem portiem. (Neatzฤซmฤjot tiks izmantots STARTTLS, ja serveris to atbalsta.)
-auths.helo_hostname=HELO resursa nosaukums
-auths.helo_hostname_helper=Resursa nosaukums, ko sลซtฤซt ar HELO. Atstฤjiet tukลกu, lai izmantotu servera resursa nosaukumu.
+auths.force_smtps=Uzspiest SMTPS izmantoลกana
+auths.force_smtps_helper=Portam 465 vienmฤr tiek izmantots SMTPS. Iestatฤซt ลกo, lai piespiestu izmantot SMTPS citiem portiem. (Pretฤjฤ gadฤซjumฤ portiem tiks izmantots STARTTLS, ja saimniekdators to nodroลกina.)
+auths.helo_hostname=HELO resursdatora nosaukums
+auths.helo_hostname_helper=Saimniekdatora nosaukums, ko sลซtฤซt ar HELO. Atstฤt tukลกu, lai izmantotu paลกreizฤjo saimniekdatora nosaukumu.
auths.disable_helo=Atspฤjot HELO
-auths.pam_service_name=PAM servisa nosaukums
-auths.pam_email_domain=PAM e-pasta domฤns (neobligฤts)
-auths.oauth2_provider=OAuth2 pakalpojuma sniedzฤjs
+auths.pam_service_name=PAM pakalpojuma nosaukums
+auths.pam_email_domain=PAM e-pasta domฤna vฤrds (izvฤles)
+auths.oauth2_provider=OAuth2 nodroลกinฤtฤjs
auths.oauth2_icon_url=Ikonas URL
auths.oauth2_clientID=Klienta ID (atslฤga)
auths.oauth2_clientSecret=Klienta noslฤpums
auths.openIdConnectAutoDiscoveryURL=OpenID Connect automฤtiskฤs atklฤลกanas URL
-auths.oauth2_use_custom_url=Noklusฤto URL vietฤ izmantot pielฤgotos URL
+auths.oauth2_use_custom_url=Izmantot pielฤgotus URL noklusฤjuma URL vietฤ
auths.oauth2_tokenURL=Pilnvaras URL
-auths.oauth2_authURL=Autorizฤcijas URL
+auths.oauth2_authURL=Pilnvarot URL
auths.oauth2_profileURL=Profila URL
auths.oauth2_emailURL=E-pasta adreses URL
-auths.skip_local_two_fa=Izlaist vietฤjo divu faktoru autorizฤciju
-auths.skip_local_two_fa_helper=Atstฤjot neatzฤซmฤtu, nozฤซmฤ, ka lokฤlajiem lietotฤjiem, kam ir uzstฤdฤซta divu faktoru autorizฤcija, bลซs nepiecieลกams iziet tฤs pฤrbaudi, lai autorizฤtos
+auths.skip_local_two_fa=Izlaist vietฤjo divupakฤpju pieteikลกanos
+auths.skip_local_two_fa_helper=Atstฤt neiestatฤซtu nozฤซmฤ, ka vietฤjiem lietotฤjiem, kuriem ir iestatฤซta divpakฤpju pieteikลกanฤs, tฤ bลซs jฤizmanto, lai pieteiktos
auths.oauth2_tenant=Nomnieks
-auths.oauth2_scopes=Papildus tvฤrumi
+auths.oauth2_scopes=Papildu tvฤrumi
auths.oauth2_required_claim_name=Nepiecieลกamฤs prasฤซbas nosaukums
-auths.oauth2_required_claim_name_helper=Uzstฤdiet ลกo nosaukumu, lai ierobeลพotu, kas var autorizฤties, izmantojot, ลกo avotu, ar norฤdฤซto prasฤซbas nosaukumu un vertฤซbu
+auths.oauth2_required_claim_name_helper=ล is nosaukums ir iestatฤms, lai ierobeลพotu pieteikลกanos no ลกฤซ avota lietotฤjiem, kuriem ir prasฤซba ar ลกฤdu nosaukumu
auths.oauth2_required_claim_value=Nepiecieลกamฤs prasฤซbas vฤrtฤซba
-auths.oauth2_required_claim_value_helper=Uzstฤdiet ลกo vฤrtฤซbu, lai ierobeลพotu, kas var autorizฤties, izmantojot, ลกo avotu, ar norฤdฤซto prasฤซbas nosaukumu un vertฤซbu
-auths.oauth2_group_claim_name=Prasฤซbas nosaukums, kas nodroลกina grupu nosaukumus ลกim avotam. (Neobligฤts)
-auths.oauth2_admin_group=Grupas prasฤซbas vฤrtฤซba administratoriem. (Neobligฤta - nepiecieลกams prasฤซbas nosaukums augstฤk)
-auths.oauth2_restricted_group=Grupas prasฤซbas vฤrtฤซba ierobeลพotajiem lietotฤjiem. (Neobligฤta - nepiecieลกams prasฤซbas nosaukums augstฤk)
-auths.oauth2_map_group_to_team=Sasaistฤซt prasฤซbas grupas ar organizฤcijas komandฤm. (Neobligฤts - nepiecieลกams prasฤซbas nosaukums augstฤk)
-auths.oauth2_map_group_to_team_removal=Noลemt lietotฤjus no sinhronizฤtajฤm komandฤm, ja lietotฤjs nav piesaistฤซts attiecฤซgajai grupai.
+auths.oauth2_required_claim_value_helper=ล ฤซ vฤrtฤซba ir iestatฤma, lai ierobeลพotu pieteikลกanos no ลกฤซ avota lietotฤjiem, kuriem ir prasฤซba ar ลกฤdu nosaukumu un vฤrtฤซbu
+auths.oauth2_group_claim_name=Prasฤซbas nosaukums, kas ลกim avotam nodroลกina grupu nosaukumus. (Pฤc izvฤles)
+auths.oauth2_admin_group=Kopas prasฤซbas vฤrtฤซba pฤrvaldฤซtฤjiem. (Izvฤles - nepiecieลกams augstฤk esoลกais prasฤซbas nosaukums)
+auths.oauth2_restricted_group=Grupas prasฤซbas vฤrtฤซba ierobeลพotajiem lietotฤjiem. (Izvฤles - nepiecieลกams augstฤk esoลกais prasฤซbas nosaukums)
+auths.oauth2_map_group_to_team=Sasaistฤซt pieprasฤซtฤs kopas ar apvienฤซbas komandฤm. (Izvฤles - nepiecieลกams augstฤk esoลกais prasฤซbas nosaukums)
+auths.oauth2_map_group_to_team_removal=Noลemt lietotฤjus no sinhronizฤtajฤm komandฤm, ja lietotฤjs nav attiecฤซgajฤ grupai.
auths.enable_auto_register=Iespฤjot automฤtisko reฤฃistrฤciju
auths.sspi_auto_create_users=Automฤtiski izveidot lietotฤjus
-auths.sspi_auto_create_users_helper=ฤปauj SSPI autentifikฤcijas metodei automฤtiski izveidot jaunus kontus lietotฤjiem, kas autorizฤjas pirmo reizi
-auths.sspi_auto_activate_users=Automฤtiski aktivizฤt lietotฤjus
-auths.sspi_auto_activate_users_helper=ฤปauj SSPI autentifikฤcijas metodei automฤtiski aktivizฤt jaunos lietotฤjus
+auths.sspi_auto_create_users_helper=ฤปauj SSPI autentificฤลกanฤs veidam automฤtiski izveidot jaunus kontus lietotฤjiem, kas piesakฤs pirmo reizi
+auths.sspi_auto_activate_users=Automฤtiski aktivฤt lietotฤjus
+auths.sspi_auto_activate_users_helper=ฤปauj SSPI autentificฤลกanas viedam automฤtiski aktivฤt jaunus lietotฤjus
auths.sspi_strip_domain_names=Noลemt domฤna vฤrdus no lietotฤju vฤrdiem
auths.sspi_strip_domain_names_helper=Ja atzฤซmฤts, domฤna vฤrdi tiks noลemti no lietotฤja vฤrdiem, piemฤram, "DOMฤNS\lietotฤjs" un "lietotฤjs@domฤns.lv" abi kฤผลซs par tikai "lietotฤjs".
auths.sspi_separator_replacement=Atdalฤซtฤjs, ko izmantot \, / vai @ vietฤ
-auths.sspi_separator_replacement_helper=Simbols, ko izmantot, kฤ atdalฤซtฤju, lai atdalฤซtu lietotฤja vฤrdu no domฤna, piemฤram "DOMฤNS\lietotฤjs", un lietotฤja identitฤลกu nosaukumos, piemฤram, lietotฤjs@domฤns.lv.
-auths.sspi_default_language=Noklusฤtฤ lietotฤja valoda
-auths.sspi_default_language_helper=Noklusฤtฤ valoda, ko uzstฤdฤซt automฤtiski izveidotajiem lietotฤjiem, kas izmanto SSPI autentifikฤcijas veidu. Atstฤjiet tukลกu, ja vฤlaties, lai valoda tiktu noteikta automฤtiski.
+auths.sspi_separator_replacement_helper=Rakstzฤซme, ko izmantot, lai aizstฤtu atdalฤซtฤjus zemฤka lฤซmeลa pieteikลกanฤs vฤrdos (piem., "\" vฤrtฤซbฤ "DOMฤNS\lietotฤjs") un lietotฤja identitฤลกu nosaukumos (piemฤram, "@" vฤrtฤซbฤ "lietotajs@example.org").
+auths.sspi_default_language=Lietotฤju noklusฤjuma valoda
+auths.sspi_default_language_helper=Noklusฤjuma valoda lietotฤjiem, kurus automฤtiski izveido SSPI autentificฤลกanฤs veids. Atstฤt tukลกu, ja ir vฤlams, lai valoda tiktu noteikta automฤtiski.
auths.tips=Padomi
-auths.tips.oauth2.general=OAuth2 autentifikฤcija
-auths.tips.oauth2.general.tip=Kad tiek reฤฃistrฤta jauna OAuth2 autentifikฤcija, atzvanฤซลกanas/pฤrvirzฤซลกanas URL vajadzฤtu bลซt:
-auths.tip.oauth2_provider=OAuth2 pakalpojuma sniedzฤjs
-auths.tip.bitbucket=Reฤฃistrฤjiet jaunu OAuth klientu adresฤ https://bitbucket.org/account/user//oauth-consumers/new un pieลกฤทiriet tam "Account" - "Read" tiesฤซbas
-auths.tip.nextcloud=`Reฤฃistrฤjiet jaunu OAuth klientu jลซsu instances sadฤฤผฤ "Settings -> Security -> OAuth 2.0 client"`
-auths.tip.dropbox=Izveidojiet jaunu aplikฤciju adresฤ https://www.dropbox.com/developers/apps
-auths.tip.facebook=`Reฤฃistrฤjiet jaunu aplikฤciju adresฤ https://developers.facebook.com/apps un pievienojiet produktu "Facebook Login"`
-auths.tip.github=Reฤฃistrฤjiet jaunu aplikฤciju adresฤ https://github.com/settings/applications/new
+auths.tips.oauth2.general=OAuth2 autentificฤลกanฤs
+auths.tips.oauth2.general.tip=Kad tiek reฤฃistrฤta jauna OAuth2 autentificฤลกana, atzvanฤซลกanas/pฤrvirzฤซลกanas URL vajadzฤtu bลซt:
+auths.tip.oauth2_provider=OAuth2 nodroลกinฤtฤjs
+auths.tip.bitbucket=Jฤizveido jauns OAuth patฤrฤtฤjs %s un jฤpievieno atฤผauja "Account" - "Read"
+auths.tip.nextcloud=Reฤฃistrฤt jaunu OAuth patฤrฤtฤju savฤ serverฤซ var izvฤlnฤ "Iestatฤซjumi -> Droลกฤซba -> OAuth 2.0 klients"
+auths.tip.dropbox=Jฤizveido jauna lietotne %s
+auths.tip.facebook=Jฤizveido jauna lietotne %s un jฤpievieno produkts "Facebook Login"
+auths.tip.github=Jฤizveido jauna OAuth lietotne %s
auths.tip.gitlab=Reฤฃistrฤjiet jaunu aplikฤciju adresฤ https://gitlab.com/profile/applications
-auths.tip.google_plus=Iegลซstiet OAuth2 klienta pilnvaru no Google API konsoles adresฤ https://console.developers.google.com/
-auths.tip.openid_connect=Izmantojiet OpenID pieslฤgลกanฤs atklฤลกanas URL (/.well-known/openid-configuration), lai norฤdฤซtu galapunktus
-auths.tip.twitter=Dodieties uz adresi https://dev.twitter.com/apps, izveidojiet lietotni un pฤrliecinieties, ka ir atzฤซmฤts โAllow this application to be used to Sign in with Twitterโ
-auths.tip.discord=Reฤฃistrฤjiet jaunu aplikฤciju adresฤ https://discordapp.com/developers/applications/me
-auths.tip.gitea=Pievienot jaunu OAuth2 lietojumprogrammu. Dokumentฤcija ir pieejama https://forgejo.org/docs/latest/user/oauth2-provider
-auths.tip.yandex=`Izveidojiet jaunu lietotni adresฤ https://oauth.yandex.com/client/new. Izvฤlieties sekojoลกas tiesฤซbas "Yandex.Passport API" sadaฤผฤ: "Access to email address", "Access to user avatar" un "Access to username, first name and surname, gender"`
-auths.tip.mastodon=Norฤdiet pielฤgotu mastodon instances URL, ar kuru vฤlaties autorizฤties (vai izmantojiet noklusฤto)
-auths.edit=Labot autentifikฤcijas avotu
-auths.activated=Autentifikฤcijas avots ir atkivizฤts
-auths.new_success=Jauna autentifikฤcija "%s" tika pievienota.
-auths.update_success=Autentifikฤcijas avots tika atjaunots.
-auths.update=Atjaunot autentifikฤcijas avotu
-auths.delete=Dzฤst autentifikฤcijas avotu
-auths.delete_auth_title=Dzฤst autentifikฤcijas avotu
-auths.delete_auth_desc=Izdzฤลกot autentifikฤcijas avotu, tฤ lietotฤjiem nebลซs iespฤjams pieteikties. Vai turpinฤt?
+auths.tip.google_plus=OAuth2 klienta piekฤผuves dati ir iegลซstami Google API konsolฤ %s
+auths.tip.openid_connect=Jฤizmanto OpenID savienoลกanฤs atklฤลกanas URL (/.well-known/openid-configuration), lai norฤdฤซtu galapunktus
+auths.tip.twitter=Jฤdodas uz %s, jฤizveido lietotne un jฤnodroลกina, ka iespฤja "Allow this application to be used to Sign in with Twitter" ir iespฤjota
+auths.tip.discord=Jฤizveido jauna lietotne %s
+auths.tip.gitea=Pievienot jaunu OAuth2 lietotni. Norฤdes ir atrodamas %s
+auths.tip.yandex=%s jฤizveido jauna lietotne. Sadaฤผฤ "Yandex.Passport API" jฤatlasa ลกฤซs atฤผaujas: "Access to email address", "Access to user avatar" un "Access to username, first name and surname, gender"
+auths.tip.mastodon=Jฤievada pielฤgota Mastodon servera URL, ar kuru ir vฤlฤลกanฤs autentificฤties (vai jฤizmanto noklusฤjuma)
+auths.edit=Labot autentificฤลกanas avotu
+auths.activated=ล is autentificฤลกanas avots ir atkivฤts
+auths.new_success=Autentificฤลกanฤs "%s" tika pievienota.
+auths.update_success=Autentificฤลกanฤs avots tika atjauninฤts.
+auths.update=Atjauninฤt autentificฤลกanฤs avotu
+auths.delete=Izdzฤst autentificฤลกanas avotu
+auths.delete_auth_title=Izdzฤst autentificฤลกanas avotu
+auths.delete_auth_desc=Autentificฤลกanฤs avota izdzฤลกana liedz lietotฤjiem to izmantot, lai pieteiktos. Turpinฤt?
auths.still_in_used=ล o autentificฤลกanฤs avotu joprojฤm izmanto viens vai vairฤki lietotฤji, tos nepiecieลกams izdzฤst vai pฤrvietot uz citu autentificฤลกanฤs avotu.
-auths.deletion_success=Autentifikฤcijas avots tika atjaunots.
-auths.login_source_exist=Autentifikฤcijas avots ar nosaukumu "%s" jau eksistฤ.
-auths.login_source_of_type_exist=Autentifikฤcijas avots ar ลกฤdu veidu jau eksistฤ.
-auths.unable_to_initialize_openid=Nevarฤja inicializฤt OpenID Connect sliedzฤju: %s
-auths.invalid_openIdConnectAutoDiscoveryURL=Kฤผลซdains automฤtiskฤs atklฤลกanas URL (jฤbลซt korektam URL, kas sฤkas ar http:// vai https://)
+auths.deletion_success=Autentificฤลกanฤs avots tika izdzฤsts.
+auths.login_source_exist=Jau pastฤv autentificฤลกanฤs avots "%s".
+auths.login_source_of_type_exist=Jau pastฤv ลกฤda veida autentificฤลกanฤs avots.
+auths.unable_to_initialize_openid=Nevarฤja sฤknฤt OpenID Connect sniedzฤju: %s
+auths.invalid_openIdConnectAutoDiscoveryURL=Nederฤซgs automฤtiskฤs atklฤลกanas URL (tam jฤbลซt derฤซgam URL, kas sฤkas ar http:// vai https://)
config.server_config=Servera konfigurฤcija
-config.app_name=Vietnes nosaukums
+config.app_name=Servera nosaukums
config.app_ver=Forgejo versija
-config.app_url=Forgejo pamata URL
-config.custom_conf=Konfigurฤcijas faila ceฤผลก
-config.custom_file_root_path=Pielฤgoto failu pamata ceฤผลก
-config.domain=Servera domฤns
+config.app_url=Pamata URL
+config.custom_conf=Konfigurฤcijas datnes ceฤผลก
+config.custom_file_root_path=Pielฤgoto datลu pamata ceฤผลก
+config.domain=Servera domฤna vฤrds
config.offline_mode=Bezsaistes reลพฤซms
-config.disable_router_log=Atspฤjot marลกrutฤtฤja ลพurnalizฤลกanu
-config.run_user=Izpildes lietotฤjs
-config.run_mode=Izpildes reลพฤซms
+config.disable_router_log=Atspฤjot marลกrutฤtฤja ลพurnฤlu
+config.run_user=Lietotฤjs, ar kuru palaist
+config.run_mode=Palaiลกanas veids
config.git_version=Git versija
config.app_data_path=Lietotnes datu ceฤผลก
-config.repo_root_path=Repozitoriju glabฤลกanas vieta
-config.lfs_root_path=LFS saknes ceฤผลก
-config.log_file_root_path=ลฝurnalizฤลกanas ceฤผลก
+config.repo_root_path=Glabฤtavu atraลกanฤs vieta
+config.lfs_root_path=LFS pamatmapes ceฤผลก
+config.log_file_root_path=ลฝurnฤlu atraลกanฤs vieta
config.script_type=Skripta veids
-config.reverse_auth_user=Reversฤ lietotฤja autentifikฤcija
+config.reverse_auth_user=Apvฤrstฤ starpniekservera autentificฤลกanฤs lietotฤjs
config.ssh_config=SSH konfigurฤcija
config.ssh_enabled=Iespฤjots
config.ssh_start_builtin_server=Izmantot iebลซvฤto serveri
-config.ssh_domain=SSH servera domฤns
+config.ssh_domain=SSH servera domฤna vฤrds
config.ssh_port=Ports
config.ssh_listen_port=Klausฤซลกanฤs ports
-config.ssh_root_path=Saknes ceฤผลก
+config.ssh_root_path=Atraลกanฤs vieta
config.ssh_key_test_path=Atslฤgu pฤrbaudes ceฤผลก
-config.ssh_keygen_path=Keygen ('ssh-keygen') ceฤผลก
-config.ssh_minimum_key_size_check=Minimฤlฤ atslฤgas lieluma pฤrbaude
-config.ssh_minimum_key_sizes=Minimฤlais atslฤgas lielums
+config.ssh_keygen_path=Keygen ("ssh-keygen") atraลกanฤs vieta
+config.ssh_minimum_key_size_check=Mazฤkฤ pieฤผaujamฤ atslฤgas lieluma pฤrbaude
+config.ssh_minimum_key_sizes=Mazฤkie pieฤผaujamie atslฤgu lielumi
config.lfs_config=LFS konfigurฤcija
config.lfs_enabled=Iespฤjots
-config.lfs_content_path=LFS satura ceฤผลก
-config.lfs_http_auth_expiry=LFS HTTP autorizฤcijas beigลกanฤs
+config.lfs_content_path=LFS satura atraลกanฤs vieta
+config.lfs_http_auth_expiry=LFS HTTP pilnvaroลกanas derฤซguma laiks
-config.db_config=Datu bฤzes konfigurฤcija
+config.db_config=Datubฤzes konfigurฤcija
config.db_type=Veids
config.db_host=Resursdators
config.db_name=Nosaukums
@@ -3083,29 +3430,29 @@ config.db_ssl_mode=SSL
config.db_path=Ceฤผลก
config.service_config=Pakalpojuma konfigurฤcija
-config.register_email_confirm=Reฤฃistrฤjoties pieprasฤซt apstiprinฤt e-pasta adresi
-config.disable_register=Atspฤjot lietotฤju reฤฃistrฤciju
-config.allow_only_internal_registration=Atฤผaut reฤฃistrฤciju tikai no Forgejo
-config.allow_only_external_registration=Atฤผaut reฤฃistrฤties tikai ar ฤrฤjiem servisiem
-config.enable_openid_signup=Iespฤjot reฤฃistrฤciju, izmantojot OpenID
+config.register_email_confirm=Pieprasฤซt e-pasta adreses apstiprinฤลกanu, lai reฤฃistrฤtos
+config.disable_register=Atspฤjot paลกreฤฃistrฤลกanos
+config.allow_only_internal_registration=Atฤผaut reฤฃistrฤลกanos tikai Forgejo
+config.allow_only_external_registration=Atฤผaut reฤฃistrฤลกanos tikai caur ฤrฤjiem pakalpojumiem
+config.enable_openid_signup=Iespฤjot paลกreฤฃistrฤลกanos ar OpenID
config.enable_openid_signin=Iespฤjot pieteikลกanos ar OpenID
config.show_registration_button=Rฤdฤซt reฤฃistrฤลกanฤs pogu
-config.require_sign_in_view=Pieprasฤซt pieteikลกanos, lai aplลซkotu lapas
+config.require_sign_in_view=Pieprasฤซt pieteikลกanos, lai apskatฤซtu saturu
config.mail_notify=Iespฤjot e-pasta paziลojumus
config.enable_captcha=Iespฤjot droลกฤซbas kodu
-config.active_code_lives=Aktฤซvฤ koda ilgums
-config.reset_password_code_lives=Konta atjaunoลกanas koda beigลกanฤs laiks
+config.active_code_lives=Aktivฤลกanas koda derฤซguma laiks
+config.reset_password_code_lives=Atkopes koda derฤซguma laiks
config.default_keep_email_private=Pฤc noklusฤjuma slฤpt e-pasta adreses
-config.default_allow_create_organization=Pฤc noklusฤjuma ฤผaut veidot organizฤcijas
+config.default_allow_create_organization=Pฤc noklusฤjuma ฤผaut apvienฤซbu izveidoลกanu
config.enable_timetracking=Iespฤjot laika uzskaiti
config.default_enable_timetracking=Pฤc noklusฤjuma iespฤjot laika uzskaiti
-config.default_allow_only_contributors_to_track_time=Atฤผaut tikai dalฤซbniekiem uzskaitฤซt laiku
-config.no_reply_address=Neatbildฤt e-pasta adreses domฤns
-config.default_visibility_organization=Noklusฤtฤ redzamฤซba jaunฤm organizฤcijฤm
-config.default_enable_dependencies=Pฤc noklusฤjuma iespฤjot problฤmu atkarฤซbas
+config.default_allow_only_contributors_to_track_time=Atฤผaut uzskaitฤซt laiku tikai lฤซdzdalฤซbniekiem
+config.no_reply_address=Slฤpjamo e-pasta adreลกu domฤna vฤrds
+config.default_visibility_organization=Noklusฤjuma redzamฤซba jaunฤm apvienฤซbฤm
+config.default_enable_dependencies=Pฤc noklusฤjuma iespฤjot pieteikumu atkarฤซbas
-config.webhook_config=Tฤซkla ฤฤทu konfigurฤcija
-config.queue_length=Rindas garums
+config.webhook_config=Tฤซmekฤผa aizฤทeru konfigurฤcija
+config.queue_length=Rindsaraksta garums
config.deliver_timeout=Piegฤdes noildze
config.skip_tls_verify=Izlaist TLS pฤrbaudi
@@ -3114,59 +3461,59 @@ config.mailer_enabled=Iespฤjota
config.mailer_enable_helo=Iespฤjot HELO
config.mailer_name=Nosaukums
config.mailer_protocol=Protokols
-config.mailer_smtp_addr=SMTP adrese
+config.mailer_smtp_addr=SMTP saimniekdators
config.mailer_smtp_port=SMTP ports
config.mailer_user=Lietotฤjs
config.mailer_use_sendmail=Izmantot Sendmail
-config.mailer_sendmail_path=Ceฤผลก lฤซdz sendmail programmai
-config.mailer_sendmail_args=Papildus Sendmail komandrindas argumenti
+config.mailer_sendmail_path=Sendmail ceฤผลก
+config.mailer_sendmail_args=Papildu Sendmail argumenti
config.mailer_sendmail_timeout=Sendmail noildze
config.mailer_use_dummy=Tukลกs
config.test_email_placeholder=E-pasts (piemฤram, test@example.com)
-config.send_test_mail=Nosลซtฤซt pฤrbaudes e-pastu
+config.send_test_mail=Nosลซtฤซt pฤrbaudes e-pasta ziลojumu
config.send_test_mail_submit=Sลซtฤซt
-config.test_mail_failed=Neizdevฤs nosลซtฤซt pฤrbaudes e-pastu uz "%s": %v
-config.test_mail_sent=Pฤrbaudes e-pasts tika nosลซtฤซts uz "%s".
+config.test_mail_failed=Neizdevฤs nosลซtฤซt pฤrbaudes e-pasta ziลojumu uz "%s": %v
+config.test_mail_sent=Pฤrbaudes e-pasta ziลojums tika nosลซtฤซts uz "%s".
config.oauth_config=OAuth konfigurฤcija
config.oauth_enabled=Iespฤjots
config.cache_config=Keลกatmiลas konfigurฤcija
config.cache_adapter=Keลกatmiลas adapteris
-config.cache_interval=Keลกatmiลas intervฤls
-config.cache_conn=Keลกatmiลas pieslฤguma parametri
+config.cache_interval=Keลกatmiลas starplaiks
+config.cache_conn=Keลกatmiลas savienojums
config.cache_item_ttl=Keลกatmiลas vienuma TTL
config.session_config=Sesijas konfigurฤcja
config.session_provider=Sesijas nodroลกinฤtฤjs
-config.provider_config=Pakalpojumu sniedzฤja konfigurฤcija
+config.provider_config=Nodroลกinฤtฤja konfigurฤcija
config.cookie_name=Sฤซkdatnes nosaukums
-config.gc_interval_time=GC laika intervฤls
+config.gc_interval_time=GC starplaiks
config.session_life_time=Sesijas ilgums
config.https_only=Tikai HTTPS
config.cookie_life_time=Sฤซkdatลu glabฤลกanas ilgums
-config.picture_config=Attฤlu un profila bilลพu konfigurฤcija
-config.picture_service=Lokฤli attฤli
+config.picture_config=Attฤlu un profila attฤlu konfigurฤcija
+config.picture_service=Attฤlu pakalpojums
config.disable_gravatar=Atspฤjot Gravatar
-config.enable_federated_avatar=Iespฤjot apvienotฤs profila bildes
+config.enable_federated_avatar=Iespฤjot vienotos profila attฤlus
config.git_config=Git konfigurฤcija
config.git_disable_diff_highlight=Atspฤjot salฤซdzinฤลกanas sintakses iekrฤsoลกanu
-config.git_max_diff_lines=Maksimฤlais salฤซdzinฤmo rindu skaits vienam failam
-config.git_max_diff_line_characters=Maksimฤlais salฤซdzinฤmo simbolu skaits vienai rindai
-config.git_max_diff_files=Maksimฤlais salฤซdzinฤmo failu skaits, ko attฤlot
+config.git_max_diff_lines=Lielฤkais salฤซdzinฤmo rindu skaits datnฤ
+config.git_max_diff_line_characters=Lielฤkais rindas salฤซdzinฤmo rakstzฤซmju skaits
+config.git_max_diff_files=Lielฤkais parฤdฤmo salฤซdzinฤmo datลu skaits
config.git_gc_args=GC argumenti
-config.git_migrate_timeout=Migrฤcijas noilgums
-config.git_mirror_timeout=Spoguฤผa atjaunoลกanas noilgums
-config.git_clone_timeout=Klonฤลกanas darbฤซbas noilgums
-config.git_pull_timeout=Izmaiลu saลemลกanas darbฤซbas noilgums
-config.git_gc_timeout=GC darbฤซbas noilgums
+config.git_migrate_timeout=Pฤrcelลกanas noildze
+config.git_mirror_timeout=Spoguฤผglabฤtavas atjauninฤลกanas noildze
+config.git_clone_timeout=Klonฤลกanas darbฤซbas noildze
+config.git_pull_timeout=Atgฤdฤลกanas darbฤซbas noildze
+config.git_gc_timeout=GC darbฤซbas noildze
-config.log_config=ลฝurnalizฤลกanas konfigurฤcija
+config.log_config=ลฝurnฤla konfigurฤcija
config.logger_name_fmt=ลฝurnalizฤtฤjs: %s
config.disabled_logger=Atspฤjots
-config.access_log_mode=Piekฤผuves ลพurnalizฤลกanas veids
+config.access_log_mode=Piekฤผuves ลพurnalฤลกanas veids
config.access_log_template=Piekฤผuves ลพurnฤla sagatave
config.xorm_log_sql=SQL ลพurnalizฤลกana
@@ -3174,94 +3521,123 @@ config.set_setting_failed=`Neizdevฤs uzstฤdฤซt iestatฤซjumu "%s"`
monitor.stats=Statistika
-monitor.cron=Cron uzdevumi
+monitor.cron=Atkฤrtojamie uzdevumi
monitor.name=Nosaukums
monitor.schedule=Grafiks
-monitor.next=Nฤkoลกฤs izpildes laiks
+monitor.next=Nฤkamฤ reize
monitor.previous=Pฤdฤjฤs izpildes laiks
monitor.execute_times=Izpildes
monitor.process=Darbojoลกies procesi
-monitor.stacktrace=Steka izsekojamฤซba
+monitor.stacktrace=Steka trasฤjums
monitor.processes_count=%d procesi
monitor.download_diagnosis_report=Lejupielฤdฤt diagnostikas atskaiti
monitor.desc=Apraksts
monitor.start=Sฤkuma laiks
monitor.execute_time=Izpildes laiks
-monitor.last_execution_result=Rezultฤts
+monitor.last_execution_result=Iznฤkums
monitor.process.cancel=Atcelt procesu
monitor.process.cancel_desc=Procesa atcelลกana var radฤซt datu zaudฤjumus
monitor.process.cancel_notices=Atcelt: %s ?
monitor.process.children=Apakลกprocesi
-monitor.queues=Rindas
-monitor.queue=Rinda: %s
+monitor.queues=Rindsaraksti
+monitor.queue=Rindsaraksts: %s
monitor.queue.name=Nosaukums
monitor.queue.type=Veids
monitor.queue.exemplar=Eksemplฤra veids
monitor.queue.numberworkers=Strฤdลu skaits
monitor.queue.activeworkers=Darbojoลกies strฤdลi
-monitor.queue.maxnumberworkers=Maksimฤlais strฤdลu skaits
-monitor.queue.numberinqueue=Skaits rindฤ
+monitor.queue.maxnumberworkers=Lielฤkais pieฤผaujamais strฤdลu skaits
+monitor.queue.numberinqueue=Skaits rindsarakstฤ
monitor.queue.review_add=Pฤrskatฤซt/pievienot strฤdลus
monitor.queue.settings.title=Pลซla iestatฤซjumi
-monitor.queue.settings.desc=Pลซls dinamiski tiek palielinฤts atkarฤซbฤ no bloฤทฤtiem darbiem rindฤ.
+monitor.queue.settings.desc=Pลซli dinamiski palielinฤs atkarฤซbฤ no to strฤdลu rindu aizturฤลกanas.
monitor.queue.settings.maxnumberworkers=Maksimฤlais strฤdลu skaits
monitor.queue.settings.maxnumberworkers.placeholder=Paลกalaik %[1]d
-monitor.queue.settings.maxnumberworkers.error=Maksimฤlajam strฤdลu skaitam ir jฤbลซt skaitlim
-monitor.queue.settings.submit=Saglabฤt iestatฤซjumus
-monitor.queue.settings.changed=Iestatฤซjumi saglabฤti
+monitor.queue.settings.maxnumberworkers.error=Lielฤkajam pieฤผaujamajam strฤdลu skaitam ir jฤbลซt skaitlim
+monitor.queue.settings.submit=Atjauninฤt iestatฤซjumus
+monitor.queue.settings.changed=Iestatฤซjumi atjauninฤti
monitor.queue.settings.remove_all_items=Noลemt visus
-monitor.queue.settings.remove_all_items_done=Visi ieraksti rindฤ tika noลemti.
+monitor.queue.settings.remove_all_items_done=Visi rindsaraksta vienumi tika noลemti.
notices.system_notice_list=Sistฤmas paziลojumi
-notices.view_detail_header=Skatฤซt paziลojuma detaฤผas
+notices.view_detail_header=Apskatฤซt paziลojuma informฤciju
notices.operations=Darbฤซbas
-notices.select_all=Iezฤซmฤt visu
-notices.deselect_all=Atcelt visa iezฤซmฤลกanu
-notices.inverse_selection=Apgriezeniskฤ iezฤซmฤลกana
-notices.delete_selected=Dzฤst iezฤซmฤto
-notices.delete_all=Dzฤst visus paziลojumus
+notices.select_all=Atlasฤซt visus
+notices.deselect_all=Atcelt visa atlasฤซลกanu
+notices.inverse_selection=Apvฤrst atlasฤซto
+notices.delete_selected=Izdzฤst atlasฤซtos
+notices.delete_all=Izdzฤst visus paziลojumus
notices.type=Veids
-notices.type_1=Repozitorijs
+notices.type_1=Glabฤtava
notices.type_2=Uzdevums
notices.desc=Apraksts
notices.op=Op.
-notices.delete_success=Sistฤmas paziลojumi ir dzฤsti.
+notices.delete_success=Sistฤmas paziลojumi tika dzฤsti.
-self_check.no_problem_found=Paลกlaik nav atrasta neviena problฤma.
+self_check.no_problem_found=Vฤl nav atrasts neviens sareลพฤฃฤซjums.
+config_summary = Kopsavilkums
+config_settings = Iestatฤซjumi
+config.cache_test_slow = Keลกatmiลas pฤrbaude sekmฤซga, bet atbilde ir lฤna: %s.
+config.cache_test_succeeded = Keลกatmiลas pฤrbaude sekmฤซga, atbilde tika saลemta pฤc %s.
+self_check.database_collation_case_insensitive = Datubฤzฤ tiek izmantota salฤซdzinฤลกana %s, kas ir nejutฤซga salฤซdzinฤลกana. Lai gan Forgejo var ar to darboties, var gadฤซties reti gadฤซjumi, kuros viss varฤtu nenotikt kฤ paredzฤts.
+self_check.database_inconsistent_collation_columns = Datubฤzฤ tiek izmantota salฤซdzinฤลกana %s, bet ลกajฤs ailฤs tiek izmantotas neatbilstoลกas salฤซdzinฤลกanas. Tas var radฤซt neparedzฤtus sareลพฤฃฤซjumus.
+auths.tip.gitlab_new = Jauna lietotne ir reฤฃistrฤjama %s
+config.cache_test = Pฤrbaudฤซt keลกatmiลu
+config.cache_test_failed = Neizdevฤs iegลซt keลกatmiลas paraugu: %v.
+config.open_with_editor_app_help = "Atvฤrt ar" redaktori klonฤลกanas izvฤlnei. Ja ir atstฤts tukลกs, tiks izmantots noklusฤjums. Izvฤrst, lai redzฤtu noklusฤjumu.
+self_check.database_collation_mismatch = Sagaidฤซt, ka datubฤzฤ tiek izmantota salฤซdzinฤลกana: %s
+self_check.database_fix_mysql = MySQL/MariaDB lietotฤji var izmantot komandu "forgejo doctor convert", lai novฤrstu salฤซdzinฤลกanas sareลพฤฃฤซjumus, vai arฤซ tos var paลกrocฤซgi novฤrst ar "ALTER ... COLLATE ..." vaicฤjumiem.
+config.app_slogan = Servera sauklis
+config.allow_dots_in_usernames = ฤปaut lietotฤjiem izmantot punktus savฤ lietotฤjvฤrdฤ. Neietekmฤ esoลกos kontus.
+users.restricted.description = ฤปaut mijiedarbฤซbu tikai ar glabฤtavฤm un apvienฤซbฤm, kurฤs ลกis lietotฤjs ir pievienots kฤ lฤซdzdalฤซbnieks. Tas neฤผauj piekฤผลซt ลกฤซ servera atklฤtajฤm glabฤtavฤm.
+dashboard.sync_tag.started = Uzsฤkta birku sinhronizฤลกana
+users.organization_creation.description = ฤปaut jaunu apvienฤซbu izveidoลกanu.
+users.block.description = Liegt ลกฤซ lietotฤja mijiedarbฤซbu ar ลกo serveri caur tฤ kontu un neฤผaut pieteikลกanos.
+users.admin.description = Nodroลกinฤt ลกim lietotฤjam pilnu piekฤผuvi visฤm pฤrvaldฤซลกanas iespฤjฤm ar tฤซmekฤผa saskarni un API.
+users.local_import.description = ฤปaut glabฤtavu ievietoลกanu no servera vietฤjฤs datลu sistฤmas. Tฤ var bลซt droลกฤซbas nepilnฤซba.
+emails.delete = Izdzฤst e-pasta adresi
+emails.delete_desc = Vai tieลกฤm izdzฤst ลกo e-pasta adresi?
+emails.deletion_success = E-pasta adrese tika izdzฤsta.
+emails.delete_primary_email_error = Nevar izdzฤst galveno e-pasta adresi.
+auths.tips.gmail_settings = Gmail iestatฤซjumi:
+users.activated.description = E-pasta adreses apliecinฤลกanas pabeigลกana. Neaktivฤta konta ฤซpaลกnieks nevarฤs pieteikties, kamฤr e-pasta adreses apliecinฤลกana nebลซs pabeigta.
+auths.default_domain_name = Noklusฤjuma domฤna vฤrds, kas tiek izmantots e-pasta adresฤs
+dashboard.sync_repo_tags = Datubฤzฤ sinhronizฤt birkas no Git datiem
+monitor.duration = Ilgums (s)
[action]
-create_repo=izveidoja repozitoriju %s
-rename_repo=pฤrsauca repozitoriju no %[1]s
uz %[3]s
-commit_repo=iesลซtฤซja izmaiลas %[3]s repozitorijฤ %[4]s
-create_issue=`atvฤra problฤmu %[3]s#%[2]s `
-close_issue=`aizvฤra problฤmu %[3]s#%[2]s `
-reopen_issue=`atkฤrtoti atvฤra problฤmu %[3]s#%[2]s `
+create_repo=izveidoja glabฤtavu %s
+rename_repo=pฤrdฤvฤja glabฤtavu %[1]s
par %[3]s
+commit_repo=aizgฤdฤja izmaiลas uz %[3]s glabฤtavฤ %[4]s
+create_issue=`atvฤra pieteikumu %[3]s#%[2]s `
+close_issue=`aizvฤra pieteikumu %[3]s#%[2]s `
+reopen_issue=`atkฤrtoti atvฤra pieteikumu %[3]s#%[2]s `
create_pull_request=`izveidoja izmaiลu pieprasฤซjumu %[3]s#%[2]s `
close_pull_request=`aizvฤra izmaiลu pieprasฤซjumu %[3]s#%[2]s `
reopen_pull_request=`atkฤrtoti atvฤra izmaiลu pieprasฤซjumu %[3]s#%[2]s `
-comment_issue=`pievienoja komentฤru problฤmai %[3]s#%[2]s `
-comment_pull=`pievienoja komentฤru izmaiลu pieprasฤซjumam %[3]s#%[2]s `
-merge_pull_request=`sapludinฤja izmaiลu pieprasฤซjumu %[3]s#%[2]s `
-auto_merge_pull_request=`automฤtiski sapludinฤja izmaiลu pieprasฤซjumu %[3]s#%[2]s `
-transfer_repo=mainฤซja repozitorija %s
ฤซpaลกnieku uz %s
-push_tag=iesลซtฤซja tagu %[3]s repozitorijฤ %[4]s
-delete_tag=izdzฤsa tagu %[2]s no %[3]s
-delete_branch=izdzฤsa atzaru %[2]s no %[3]s
+comment_issue=`pievienoja piebildi pieteikumam %[3]s#%[2]s `
+comment_pull=`pievienoja piebildi izmaiลu pieprasฤซjumam %[3]s#%[2]s `
+merge_pull_request=`iekฤผฤva izmaiลu pieprasฤซjumu %[3]s#%[2]s `
+auto_merge_pull_request=`automฤtiski iekฤผฤva izmaiลu pieprasฤซjumu %[3]s#%[2]s `
+transfer_repo=glabฤtavu %s
nodeva %s
+push_tag=aizgฤdฤja birku %[3]s uz %[4]s
+delete_tag=izdzฤsa birku %[2]s no %[3]s
+delete_branch=izdzฤsa zaru %[2]s no %[3]s
compare_branch=Salฤซdzinฤt
-compare_commits=Salฤซdzinฤt %d revฤซzijas
-compare_commits_general=Salฤซdzinฤt revฤซzijas
-mirror_sync_push=ar spoguli sinhronizฤtas revฤซzijas %[3]s uz repozitoriju %[4]s
-mirror_sync_create=ar spoguli sinhronizฤta jauna atsauce %[3]s uz repozitoriju %[4]s
-mirror_sync_delete=ar spoguli sinhronizฤta un izdzฤsta atsauce %[2]s
repozitorijam %[3]s
-approve_pull_request=`apstiprinฤja izmaiลu pieprasฤซjumu %[3]s#%[2]s `
+compare_commits=Salฤซdzinฤt %d iesลซtฤซjumus
+compare_commits_general=Salฤซdzinฤt iesลซtฤซjumus
+mirror_sync_push=sinhronizฤja iesลซtฤซjumus uz %[3]s %[4]s no spoguฤผglabฤtavas
+mirror_sync_create=sinhronizฤja jaunu atsauci %[3]s uz %[4]s no spoguฤผglabฤtavas
+mirror_sync_delete=sinhronizฤja un izdzฤsa atsauci %[2]s
%[3]s no spoguฤผglabฤtavas
+approve_pull_request=`apstiprinฤja %[3]s#%[2]s `
reject_pull_request=`ieteica izmaiลas izmaiลu pieprasฤซjumam %[3]s#%[2]s `
-publish_release=`izveidoja versiju "%[4]s" repozitorijฤ %[3]s `
-review_dismissed=`noraidฤซja lietotฤja %[4]s recenziju izmaiลu pieprasฤซjumam %[3]s#%[2]s `
+publish_release=`izdeva laidienu %[4]s %[3]s `
+review_dismissed=`atmeta izskatฤซลกanu no %[4]s %[3]s#%[2]s `
review_dismissed_reason=Iemesls:
-create_branch=izveidoja atzaru %[3]s repozitorijฤ %[4]s
+create_branch=izveidoja zaru %[3]s glabฤtavฤ %[4]s
starred_repo=pievienoja izlasฤ %[2]s
-watched_repo=sฤka sekot %[2]s
+watched_repo=sฤka vฤrot %[2]s
[tool]
now=tagad
@@ -3275,7 +3651,7 @@ future=nฤkotnฤ
1y=1 gada
seconds=%d sekundฤm
minutes=%d minลซtฤm
-hours=%d stundฤm
+hours=%d stundฤs
days=%d dienas
weeks=%d nedฤฤผฤm
months=%d mฤneลกiem
@@ -3284,226 +3660,254 @@ raw_seconds=sekundes
raw_minutes=minลซtes
[dropzone]
-default_message=Ievelciet failus vai nospiediet ลกeit, lai augลกupielฤdฤtu.
-invalid_input_type=ล ฤdus failus nav iespฤjams augลกupielฤdฤt.
-file_too_big=Faila izmฤrs ({{filesize}} MB) pฤrsniedz maksimฤli atฤผauto izmฤru ({{maxFilesize}} MB).
-remove_file=Noลemt failu
+default_message=Ievilkt datnes vai klikลกฤทinฤt ลกeit, lai augลกupielฤdฤtu.
+invalid_input_type=ล ฤซ veida datnes nevar augลกupielฤdฤt.
+file_too_big=Datnes izmฤrs ({{filesize}} MB) pฤrsniedz pieฤผaujamo izmฤru ({{maxFilesize}} MB).
+remove_file=Noลemt datni
[notification]
notifications=Paziลojumi
unread=Neizlasฤซtie
read=Izlasฤซtie
-no_unread=Nav nelasฤซtu paziลojumu.
+no_unread=Nav neizlasฤซtu paziลojumu.
no_read=Nav izlasฤซtu paziลojumu.
pin=Piespraust paziลojumu
mark_as_read=Atzฤซmฤt kฤ izlasฤซtu
-mark_as_unread=Atzฤซmฤt kฤ nelasฤซtu
+mark_as_unread=Atzฤซmฤt kฤ neizlasฤซtu
mark_all_as_read=Atzฤซmฤt visus kฤ izlasฤซtus
subscriptions=Abonementi
watching=Skatฤs
no_subscriptions=Nav abonementu
[gpg]
-default_key=Parakstฤซts ar noklusฤto atslฤgu
+default_key=Parakstฤซts ar noklusฤjuma atslฤgu
error.extract_sign=Neizdevฤs izgลซt parakstu
-error.generate_hash=Neizdevฤs uzฤฃenerฤt revฤซzijas jaucฤjkodu
-error.no_committer_account=Revฤซzijas autora e-pasta adrese nav piesaistฤซta nevienam kontam
-error.no_gpg_keys_found=ล im parakstam datu bฤzฤ netika atrasta zinฤma atslฤga
-error.not_signed_commit=Nav parakstฤซta revฤซzija
-error.failed_retrieval_gpg_keys=Neizdevฤs saลemt nevienu atslฤgu, kas ir piesaistฤซta revฤซzijas autora kontam
-error.probable_bad_signature=BRฤชDINฤJUMS! Lai arฤซ datu bฤzฤ eksistฤ atslฤga ar ลกฤdu identifikatoru, nav iespฤjams verificฤt ลกo revฤซziju! ล ฤซ revฤซzija ir ฤผoti AIZDOMฤชGA.
-error.probable_bad_default_signature=BRฤชDINฤJUMS! Lai arฤซ ลกai atslฤgai ir noklusฤtฤs atslฤgas identifikators, ar to nav iespฤjams verificฤt ลกo revฤซziju! ล ฤซ revฤซzija ir ฤผoti AIZDOMฤชGA.
+error.generate_hash=Neizdevฤs izveidot iesลซtฤซjuma jaucฤjkodu
+error.no_committer_account=Iesลซtฤซtฤja e-pasta adrese nav piesaistฤซta nevienam kontam
+error.no_gpg_keys_found=ล im parakstam datubฤzฤ netika atrasta zinฤma atslฤga
+error.not_signed_commit=Nav parakstฤซts iesลซtฤซjums
+error.failed_retrieval_gpg_keys=Neizdevฤs iegลซt nevienu iesลซtฤซtฤja kontam piesaistฤซtu atslฤgu
+error.probable_bad_signature=UZMANฤชBU! Lai arฤซ datubฤzฤ ir atslฤga ar ลกฤdu identifikatoru, tฤ neapliecina ลกo iesลซtฤซjumu. ล is iesลซtฤซjums ir AIZDOMฤชGS.
+error.probable_bad_default_signature=UZMANฤชBU! Lai arฤซ noklusฤjuma atslฤgai ir ลกis identifikators, tas neapliecina ลกo iesลซtฤซjumu. ล is iesลซtฤซjums ir AIZDOMฤชGS.
[units]
unit=Vienฤซba
-error.no_unit_allowed_repo=Jums nav tiesฤซbu aplลซkot nevienu ลกฤซ repozitorija sadaฤผu.
-error.unit_not_allowed=Jums nav tiesฤซbu piekฤผลซt ลกai repozitorija sadaฤผai.
+error.no_unit_allowed_repo=Nav ฤผauts piekฤผลซt nevienai ลกฤซs glabฤtavas sadaฤผai.
+error.unit_not_allowed=Nav ฤผauts piekฤผลซt ลกai glabฤtavas sadaฤผai.
[packages]
title=Pakotnes
-desc=Pฤrvaldฤซt repozitorija pakotnes.
+desc=Pฤrvaldฤซt glabฤtavas pakotnes.
empty=Paลกlaik ลกeit nav nevienas pakotnes.
-empty.documentation=Papildus informฤcija par pakotลu reฤฃistru pieejama dokumentฤcijฤ .
-empty.repo=Neparฤdฤs augลกupielฤdฤta pakotne? Apmeklฤjiet pakotลu iestatฤซjumus , lai sasaistฤซtu ar repozitoriju.
-registry.documentation=Vairฤk informฤcija par %s reฤฃistru ir pieejama dokumentฤcijฤ .
+empty.documentation=Papildu informฤcija par pakotลu reฤฃistru ir pieejama dokumentฤcijฤ .
+empty.repo=ล eit netiek parฤdฤซta augลกupielฤdฤta pakotne? Jฤdodas uz pakotลu iestatฤซjumiem un jฤsasaista tฤ ar ลกo glabฤtavu.
+registry.documentation=Vairฤk informฤcijas par %s reฤฃistru ir dokumentฤcijฤ .
filter.type=Veids
filter.type.all=Visas
filter.no_result=Pฤc norฤdฤซtajiem kritฤrijiem nekas netika atrasts.
-filter.container.tagged=Ar atzฤซmi
-filter.container.untagged=Bez atzฤซmes
-published_by=Publicฤja %[3]s %[1]s
-published_by_in=Publicฤja %[3]s %[1]s repozitorijฤ %[5]s
-installation=Instalฤcija
+filter.container.tagged=Ar birku
+filter.container.untagged=Bez birkas
+published_by=Laida klajฤ %[3]s %[1]s
+published_by_in=%[3]s laida klajฤ %[1]s %[5]s
+installation=Uzstฤdฤซลกana
about=Par ลกo pakotni
requirements=Prasฤซbas
dependencies=Atkarฤซbas
keywords=Atslฤgvฤrdi
details=Papildu informฤcija
details.author=Autors
-details.project_site=Projekta lapa
-details.repository_site=Repozitorija vietne
-details.documentation_site=Dokumentฤcijas lapa
+details.project_site=Projekta tฤซmekฤผvietne
+details.repository_site=Glabฤtavas tฤซmekฤผvietne
+details.documentation_site=Dokumentฤcijas tฤซmekฤผvietne
details.license=Licence
assets=Resursi
versions=Versijas
versions.view_all=Parฤdฤซt visas
dependency.id=ID
dependency.version=Versija
-alpine.registry=Iestaties ลกo reฤฃistru pievienojot tฤ URL /etc/apk/repositories
failฤ:
-alpine.registry.key=Lejupielฤdฤjiet reฤฃistra publisko RSA atslฤgu direktorijฤ /etc/apk/keys/
, lai pฤrbaudฤซtu indeksa parakstu:
-alpine.registry.info=Izvฤlieties $branch un $repository no saraksta zemฤk.
+alpine.registry=Iestatฤซt ลกo reฤฃistru ar URL pievienoลกanu datnฤ /etc/apk/repositories
:
+alpine.registry.key=Reฤฃistra publiskฤ RSA atslฤga jฤlejupielฤdฤ mapฤ /etc/apk/keys/
, lai apliecinฤtu indeksa parakstu:
+alpine.registry.info=No zemฤk esoลกฤ saraksta jฤizvฤlas $branch un $repository.
alpine.install=Lai uzstฤdฤซtu pakotni, ir jฤizpilda ลกฤซ komanda:
-alpine.repository=Repozitorija informฤcija
-alpine.repository.branches=Atzari
-alpine.repository.repositories=Repozitoriji
+alpine.repository=Glabฤtavas informฤcija
+alpine.repository.branches=Zari
+alpine.repository.repositories=Glabฤtavas
alpine.repository.architectures=Arhitektลซras
-cargo.registry=Uzstฤdiet ลกo reฤฃistru Cargo konfigurฤcijas failฤ, piemฤram, ~/.cargo/config.toml
:
-cargo.install=Lai instalฤtu Cargo pakotni, izpildiet sekojoลกu komandu:
-chef.registry=Uzstฤdiet ลกo reฤฃistru failฤ ~/.chef/config.rb
:
+cargo.registry=Iestatฤซt ลกo reฤฃistru Cargo konfigurฤcijas datnฤ (piemฤram, ~/.cargo/config.toml
):
+cargo.install=Lai uzstฤdฤซtu pakotni ar Cargo, jฤizpilda ลกฤซ komanda:
+chef.registry=Iestatฤซt ลกo reฤฃistru datnฤ ~/.chef/config.rb
:
chef.install=Lai uzstฤdฤซtu pakotni, ir jฤizpilda ลกฤซ komanda:
-composer.registry=Pievienojiet ลกo reฤฃistru savฤ ~/.composer/config.json
failฤ:
-composer.install=Lai instalฤtu Composer pakotni, izpildiet sekojoลกu komandu:
+composer.registry=Iestatฤซt ลกo reฤฃistru datnฤ ~/.composer/config.json
:
+composer.install=Lai uzstฤdฤซt pakotni ar Composer, jฤizpilda ลกฤซ komanda:
composer.dependencies=Atkarฤซbas
composer.dependencies.development=Izstrฤdes atkarฤซbas
-conan.details.repository=Repozitorijs
-conan.registry=Konfigurฤjiet ลกo reฤฃistru no komandrindas:
-conan.install=Lai instalฤtu Conan pakotni, izpildiet sekojoลกu komandu:
-conda.registry=Uzstฤdiet ลกo reฤฃistru kฤ Conda repozitoriju failฤ .condarc
:
-conda.install=Lai instalฤtu Conda pakotni, izpildiet sekojoลกu komandu:
-container.details.type=Attฤla formฤts
+conan.details.repository=Glabฤtava
+conan.registry=ล is reฤฃistra uzstฤdฤซลกana komandrindฤ:
+conan.install=Lai uzstฤdฤซtu pakotni ar Conan, jฤizpilda ลกฤซ komanda:
+conda.registry=Izveidot ลกo reฤฃistru kฤ Conda glabฤtavu datnฤ .condarc
:
+conda.install=Lai uzstฤdฤซtu pakotni ar Conda, jฤizpilda ลกฤซ komanda:
+container.details.type=Attฤla veids
container.details.platform=Platforma
-container.pull=Atgฤdฤjiet ลกo attฤlu no komandrindas:
-container.digest=ฤชssavilkums:
+container.pull=Atgฤdฤt attฤlu komandrindฤ:
+container.digest=ฤชssavilkums
container.multi_arch=OS / arhitektลซra
container.layers=Attฤla slฤลi
-container.labels=Etiฤทetes
+container.labels=Iezฤซmes
container.labels.key=Atslฤga
container.labels.value=Vฤrtฤซba
-cran.registry=Iestaties ลกo reฤฃistru savฤ Rprofile.site
failฤ:
+cran.registry=Iestatฤซt ลกo reฤฃistru datnฤ Rprofile.site
:
cran.install=Lai uzstฤdฤซtu pakotni, ir jฤizpilda ลกฤซ komanda:
-debian.registry=Konfigurฤjiet ลกo reฤฃistru no komandrindas:
-debian.registry.info=Izvฤlieties $distribution un $component no saraksta zemฤk.
+debian.registry=ล is reฤฃistra uzstฤdฤซลกana komandrindฤ:
+debian.registry.info=No zemฤk esoลกฤ saraksta jฤizvฤlas $distribution un $component.
debian.install=Lai uzstฤdฤซtu pakotni, ir jฤizpilda ลกฤซ komanda:
-debian.repository=Repozitorija informฤcija
+debian.repository=Glabฤtavas informฤcija
debian.repository.distributions=Distribลซcijas
debian.repository.components=Komponentes
debian.repository.architectures=Arhitektลซras
generic.download=Lejupielฤdฤt pakotni, izmantojot, komandrindu:
-go.install=Instalฤt pakotni no komandrindas:
-helm.registry=Konfigurฤjiet ลกo reฤฃistru no komandrindas:
-helm.install=Lai instalฤtu pakotni, nepiecieลกams izpildฤซt sekojoลกu komandu:
-maven.registry=Konfigurฤjiet ลกo reฤฃistru sava projekta pom.xml
failฤ:
-maven.install=Lai izmantotu pakotni, sadaฤผฤ dependencies
failฤ pom.xml
ievietojiet sekojoลกas rindas:
-maven.install2=Izpildiet no komandrindas:
-maven.download=Izpildiet no komandrindas, lai lejupielฤdฤtu ลกo atkarฤซbu:
-nuget.registry=Konfigurฤjiet ลกo reฤฃistru no komandrindas:
-nuget.install=Lai instalฤtu NuGet pakotni, izpildiet sekojoลกu komandu:
+go.install=Uzstฤdฤซt pakotni komandrindฤ:
+helm.registry=ล ฤซ reฤฃistra uzstฤdฤซลกana komandrindฤ:
+helm.install=Lai uzstฤdฤซtu pakotni, ir jฤizpilda ลกฤซ komanda:
+maven.registry=Iestatฤซt ลกo reฤฃistru sava projekta datnฤ pom.xml
:
+maven.install=Lai izmantotu pakotni, datnes pom.xml
sadaฤผฤ dependencies
jฤievieto ลกฤซs rindas:
+maven.install2=Jฤizpilda komandrindฤ:
+maven.download=Jฤizpilda komandrindฤ, lai lejupielฤdฤtu ลกo atkarฤซbu:
+nuget.registry=ล ฤซ reฤฃistra uzstฤdฤซลกana komandrindฤ:
+nuget.install=Lai uzstฤdฤซtu pakotni ar NuGet, jฤizpilda ลกฤซ komanda:
nuget.dependency.framework=Mฤrฤทa ietvars
-npm.registry=Konfigurฤjiet ลกo reฤฃistru sava projekta .npmrc
failฤ:
-npm.install=Lai instalฤtu npm pakotni, izpildiet sekojoลกu komandu:
-npm.install2=vai pievienojiet failฤ package.json sekojoลกas rindas:
+npm.registry=Iestatฤซt ลกo reฤฃistru sava projekta datnฤ .npmrc
:
+npm.install=Lai uzstฤdฤซtu pakotni ar npm, jฤizpilda ลกฤซ komanda:
+npm.install2=vai datnฤ package.json jฤpievieno:
npm.dependencies=Atkarฤซbas
npm.dependencies.development=Izstrฤdes atkarฤซbas
-npm.dependencies.peer=Netieลกฤs atkarฤซbas
-npm.dependencies.optional=Neobligฤtฤs atkarฤซbas
-npm.details.tag=Tags
-pub.install=Lai instalฤtu Dart pakotni, izpildiet sekojoลกu komandu:
+npm.dependencies.peer=Lฤซdzatkarฤซbas
+npm.dependencies.optional=Izvฤles atkarฤซbas
+npm.details.tag=Birka
+pub.install=Lai uzstฤdฤซtu pakotni ar Dart, jฤizpilda ลกฤซ komanda:
pypi.requires=Nepiecieลกams Python
-pypi.install=Lai instalฤtu pip pakotni, izpildiet sekojoลกu komandu:
-rpm.registry=Konfigurฤjiet ลกo reฤฃistru no komandrindas:
+pypi.install=Lai uzstฤdฤซtu pakotni ar pip, jฤizpilda ลกฤซ komanda:
+rpm.registry=ล ฤซ reฤฃistra uzstฤdฤซลกana komandrindฤ:
rpm.distros.redhat=uz RedHat balstฤซtฤs operฤtฤjsistฤmฤs
rpm.distros.suse=uz SUSE balstฤซtฤs operฤtฤjsistฤmฤs
rpm.install=Lai uzstฤdฤซtu pakotni, ir jฤizpilda ลกฤซ komanda:
-rpm.repository=Repozitorija informฤcija
+rpm.repository=Glabฤtavas informฤcija
rpm.repository.architectures=Arhitektลซras
-rubygems.install=Lai instalฤtu gem pakotni, izpildiet sekojoลกu komandu:
-rubygems.install2=vai pievienojiet Gemfile:
+rubygems.install=Lai uzstฤdฤซtu pakotni ar gem, jฤizpilda ลกฤซ komanda:
+rubygems.install2=vai jฤpievieno tas Gemfile:
rubygems.dependencies.runtime=Izpildlaika atkarฤซbas
rubygems.dependencies.development=Izstrฤdes atkarฤซbas
rubygems.required.ruby=Nepiecieลกamฤ Ruby versija
rubygems.required.rubygems=Nepiecieลกamฤ RubyGem versija
-swift.registry=Konfigurฤjiet ลกo reฤฃistru no komandrindas:
-swift.install=Pievienojiet pakotni savฤ Package.swift
failฤ:
-swift.install2=un izpildiet sekojoลกu komandu:
-vagrant.install=Lai pievienotu Vagrant kasti, izpildiet sekojoลกu komandu:
-settings.link=Piesaistฤซt pakotni ลกim repozitorijam
-settings.link.description=Sasaistot pakotni ar repozitoriju, tฤ tiks attฤlota repozitorija pakotลu sarakstฤ.
-settings.link.select=Norฤdiet repozitoriju
-settings.link.button=Atjaunot repozitorija saiti
-settings.link.success=Repozitorija saite tika veiksmฤซgi atjaunota.
-settings.link.error=Neizdevฤs atjaunot repozitorija saiti.
-settings.delete=Dzฤst pakotni
+swift.registry=ล ฤซ reฤฃistra uzstฤdฤซลกana komandrindฤ:
+swift.install=Pakotne jฤpievieno datnฤ Package.swift
:
+swift.install2=vai jฤpievieno tฤ Gemfile:
+vagrant.install=Lai pievienotu Vagrant kasti, jฤizpilda ลกฤซ komanda:
+settings.link=Piesaistฤซt ลกo pakotni glabฤtavai
+settings.link.description=Ja pakotne tiek sasaistฤซta ar glabฤtavu, tฤ tiek attฤlota glabฤtavas pakotลu sarakstฤ.
+settings.link.select=Atlasฤซt glabฤtavu
+settings.link.button=Atjauninฤt glabฤtavas saiti
+settings.link.success=Glabฤtavas saite tika sekmฤซgi atjauninฤta.
+settings.link.error=Neizdevฤs atjauninฤt glabฤtavas saiti.
+settings.delete=Izdzฤst pakotni
settings.delete.description=Pakotne tiks neatgriezeniski izdzฤsta.
-settings.delete.notice=Tiks dzฤsts %s (%s). ล ฤซ darbฤซba ir neatgriezeniska. Vai vฤlaties turpinฤt?
+settings.delete.notice=Tiks izdzฤsta pakotne %s (%s). ล ฤซ darbฤซba ir neatgriezeniska. Tieลกฤm turpinฤt?
settings.delete.success=Pakotne tika izdzฤsta.
settings.delete.error=Neizdevฤs izdzฤst pakotni.
owner.settings.cargo.title=Cargo reฤฃistra inkdess
-owner.settings.cargo.initialize=Inicializฤt indeksu
-owner.settings.cargo.initialize.description=Ir nepiecieลกams ฤซpaลกs indeksa Git repozitorijs, lai izmantotu Cargo reฤฃistru. ล ฤซs iespฤjas izmantoลกana (atkฤrtoti) izveidos repozitoriju un automฤtiski to iestatฤซs.
-owner.settings.cargo.initialize.error=Neizdevฤs inicializฤt Cargo indeksu: %v
-owner.settings.cargo.initialize.success=Cargo indekss tika veiksmฤซgi inicializฤts.
+owner.settings.cargo.initialize=Sฤknฤt indeksu
+owner.settings.cargo.initialize.description=Ir nepiecieลกams ฤซpaลกa indeksa Git glabฤtava, lai izmantotu Cargo reฤฃistru. ล ฤซs iespฤjas izmantoลกana (atkฤrtoti) izveidos glabฤtavu un automฤtiski to iestatฤซs.
+owner.settings.cargo.initialize.error=Neizdevฤs sฤknฤt Cargo indeksu: %v
+owner.settings.cargo.initialize.success=Cargo indekss tika sekmฤซgi izveidots.
owner.settings.cargo.rebuild=Pฤrbลซvฤt indeksu
owner.settings.cargo.rebuild.description=Pฤrbลซvฤลกana var bลซt noderฤซga, ja indekss nav sinhronizฤts ar saglabฤtajฤm Cargo pakotnฤm.
owner.settings.cargo.rebuild.error=Neizdevฤs pฤrbลซvฤt Cargo indeksu: %v
-owner.settings.cargo.rebuild.success=Cargo indekss tika veiksmฤซgi pฤrbลซvฤts.
-owner.settings.cleanuprules.title=Pฤrvaldฤซt notฤซrฤซลกanas noteikumus
-owner.settings.cleanuprules.add=Pievienot notฤซrฤซลกanas noteikumu
-owner.settings.cleanuprules.edit=Labot notฤซrฤซลกanas noteikumu
-owner.settings.cleanuprules.none=Nav pievienoti tฤซrฤซลกanas noteikumi. Sฤซkฤku informฤciju iespฤjams iegลซt dokumentฤcijฤ.
-owner.settings.cleanuprules.preview=Notฤซrฤซลกฤnas noteikuma priekลกskatฤซjums
-owner.settings.cleanuprules.preview.overview=Ir ieplฤnota %d paku dzฤลกana.
-owner.settings.cleanuprules.preview.none=Notฤซrฤซลกanas noteikumam neatbilst neviena pakotne.
+owner.settings.cargo.rebuild.success=Cargo indekss tika sekmฤซgi pฤrbลซvฤts.
+owner.settings.cleanuprules.title=Notฤซrฤซลกanas kฤrtulas
+owner.settings.cleanuprules.add=Pievienot notฤซrฤซลกanas kฤrtulu
+owner.settings.cleanuprules.edit=Labot notฤซrฤซลกanas kฤrtulu
+owner.settings.cleanuprules.none=Vฤl nav pieejama neviena tฤซrฤซลกanas kฤrtula.
+owner.settings.cleanuprules.preview=Attฤซrฤซลกanas kฤrtulas priekลกskatฤซjums
+owner.settings.cleanuprules.preview.overview=Ir paredzฤta %d pakotลu noลemลกana.
+owner.settings.cleanuprules.preview.none=Attฤซrฤซลกanas kฤrtulai neatbilst neviena pakotne.
owner.settings.cleanuprules.enabled=Iespฤjots
-owner.settings.cleanuprules.pattern_full_match=Pieลกฤทirt ลกablonu visam pakotnes nosaukumam
-owner.settings.cleanuprules.keep.title=Versijas, kas atbilst ลกiem noteikumiem tiks saglabฤtas, pat ja tฤs atbilst noลemลกanas noteikumiem zemฤk.
-owner.settings.cleanuprules.keep.count=Saglabฤt jaunฤko versiju
+owner.settings.cleanuprules.pattern_full_match=Pielietot paraugu visam pakotnes nosaukumam
+owner.settings.cleanuprules.keep.title=Versijas, kas atbilst ลกฤซm kฤrtulฤm, tiks paturฤtas, pat ja tฤs atbildฤซs zemฤk esoลกajai noลemลกanas kฤrtulai.
+owner.settings.cleanuprules.keep.count=Paturฤt visjaunฤko
owner.settings.cleanuprules.keep.count.1=1 versija katrai pakotnei
owner.settings.cleanuprules.keep.count.n=%d versijas katrai pakotnei
owner.settings.cleanuprules.keep.pattern=Paturฤt versijas, kas atbilst
owner.settings.cleanuprules.keep.pattern.container=Versija latest
vienmฤr tiks paturฤta konteineru pakotnฤm.
-owner.settings.cleanuprules.remove.title=Versijas, kas atbilst ลกiem noteikumiem tiks noลemtas, ja vien neatbilst arฤซ noteikumiem augstฤk, lai tฤs paturฤtu.
+owner.settings.cleanuprules.remove.title=Versijas, kas atbilst ลกฤซm kฤrtulฤm, tiks noลemtas, ja vien augstฤk esoลกฤ kฤrtula nenosaka, ka tฤs ir jฤpatur.
owner.settings.cleanuprules.remove.days=Noลemt versijas vecฤkas kฤ
owner.settings.cleanuprules.remove.pattern=Noลemt versijas, kas atbilst
-owner.settings.cleanuprules.success.update=Notฤซrฤซลกanas noteikumi tika atjaunoti.
-owner.settings.cleanuprules.success.delete=Notฤซrฤซลกanas noteikumi tika izdzฤsti.
+owner.settings.cleanuprules.success.update=Notฤซrฤซลกanas kฤrtula tika atjauninฤta.
+owner.settings.cleanuprules.success.delete=Notฤซrฤซลกanas kฤrtula tika izdzฤsta.
owner.settings.chef.title=Chef reฤฃistrs
-owner.settings.chef.keypair=ฤขenerฤt atslฤgu pฤri
+owner.settings.chef.keypair=Izveidot atslฤgu pฤri
owner.settings.chef.keypair.description=Atslฤgu pฤris ir nepiecieลกams, lai autentificฤtos Chef reฤฃistrฤ. Ja iepriekลก ir izveidots atslฤgu pฤris, jauna pฤra izveidoลกana veco atslฤgu pฤri padarฤซs nederฤซgu.
+arch.version.properties = Versijas ฤซpaลกฤซbas
+arch.pacman.helper.gpg = Jฤpievieno uzticฤลกanฤs sertifikฤts pacman:
+arch.pacman.repo.multi = %s ir tฤda pati versija daลพฤdฤs distribลซcijฤs.
+arch.pacman.repo.multi.item = %s konfigurฤcija
+arch.pacman.sync = Jฤsinhronizฤ pakotne ar pacman:
+arch.version.description = Apraksts
+arch.version.provides = Nodroลกina
+arch.pacman.conf = /etc/pacman.conf
jฤpievieno serveris ar atbilstoลกu distribลซciju un arhitektลซru:
+arch.version.groups = Kopa
+arch.version.replaces = Aizvieto
+arch.version.checkdepends = Pฤrbaudฤซt atkarฤซbas
+arch.version.conflicts = Nesaderฤซbas
+npm.dependencies.bundle = Iekฤผautฤs atkarฤซbas
+container.images.title = Attฤli
+arch.version.optdepends = Izvฤles atkarฤซbas
+arch.version.makedepends = Izveidot atkarฤซbas
+arch.version.backup = Rezerves kopija
+arch.version.depends = Atkarฤซbas
+rpm.repository.multiple_groups = ล ฤซ pakotne ir pieejama vairฤkฤs kopฤs.
+owner.settings.cargo.rebuild.no_index = Nevar pฤrbลซvฤt, nav sฤknฤts neviens indekss.
+search_in_external_registry = Meklฤt %s
+alt.registry = ล ฤซ reฤฃistra uzstฤdฤซลกana komandrindฤ:
+alt.registry.install = Lai uzstฤdฤซtu pakotni, jฤizpilda ลกฤซ komanda:
+alt.install = Uzstฤdฤซt pakotni
+alt.setup = Pievienot glabฤtavu savienoto glabฤtavu sarakstฤ ("_arch_" vietฤ jฤizvฤlas nepiecieลกamฤ arhitektลซra):
+alt.repository = Informฤcija par glabฤtavu
+alt.repository.architectures = Arhitektลซras
+alt.repository.multiple_groups = ล ฤซ pakotne ir pieejama vairฤkฤs kopฤs.
[secrets]
secrets=Noslฤpumi
-description=Noslฤpumi tiks padoti atseviลกฤทฤm darbฤซbฤm un citฤdi nevar tikt nolasฤซti.
+description=Noslฤpumi tiks padoti noteiktฤm darbฤซbฤm, un citฤdฤk tos nevar nolasฤซt.
none=Pagaidฤm nav neviena noslฤpuma.
creation=Pievienot noslฤpumu
-creation.name_placeholder=reฤฃistr-nejลซtฤซgs, tikai burti, cipari un apakลกsvฤซtras, nevar sฤkties ar GITEA_ vai GITHUB_
-creation.value_placeholder=Ievadiet jebkฤdu saturu. Atstarpes sฤkumฤ un beigฤ tiks noลemtas.
+creation.name_placeholder=reฤฃistrnejutฤซgs, tikai burti, cipari un apakลกsvฤซtras, nevar sฤkties ar GITEA_ vai GITHUB_
+creation.value_placeholder=Jฤievada jebkฤds saturs. Atstarpes sฤkumฤ un beigฤs tiks izlaistas.
creation.success=Noslฤpums "%s" tika pievienots.
creation.failed=Neizdevฤs pievienot noslฤpumu.
-deletion=Dzฤst noslฤpumu
-deletion.description=Noslฤpuma dzฤลกana ir neatgriezeniska. Vai turpinฤt?
-deletion.success=Noslฤpums tika izdzฤsts.
-deletion.failed=Neizdevฤs dzฤst noslฤpumu.
-management=Noslฤpumu pฤrvaldฤซba
+deletion=Noลemt noslฤpumu
+deletion.description=Noslฤpuma izdzฤลกana ir neatgriezeniska un nav atsaucama. Turpinฤt?
+deletion.success=Noslฤpums tika noลemts.
+deletion.failed=Neizdevฤs noลemt noslฤpumu.
+management=Pฤrvaldฤซt noslฤpumus
[actions]
actions=Darbฤซbas
-unit.desc=Pฤrvaldฤซt darbฤซbas
+unit.desc=Iebลซvฤto CI/CD cauruฤผvadu pฤrvaldฤซลกana ar Forgejo Actions.
status.unknown=Nezinฤms
status.waiting=Gaida
status.running=Izpildฤs
-status.success=Pabeigts
-status.failure=Neveiksmฤซgs
+status.success=Sekmฤซgi
+status.failure=Nesekmฤซgi
status.cancelled=Atcelts
status.skipped=Izlaists
-status.blocked=Bloฤทฤts
+status.blocked=Aizturฤts
runners=Izpildฤซtฤji
-runners.runner_manage_panel=Izpildฤซtฤju pฤrvaldฤซba
-runners.new=Pievienot jaunu izpildฤซtฤju
+runners.runner_manage_panel=Pฤrvaldฤซt izpildฤซtฤjus
+runners.new=Izveidot jaunu izpildฤซtฤju
runners.new_notice=Kฤ uzstฤdฤซt izpildฤซtฤju
-runners.status=Statuss
+runners.status=Stฤvoklis
runners.id=ID
runners.name=Nosaukums
runners.owner_type=Veids
@@ -3513,58 +3917,58 @@ runners.last_online=Pฤdฤjo reizi tieลกsaistฤ
runners.runner_title=Izpildฤซtฤjs
runners.task_list=Pฤdฤjฤs darbฤซbas, kas izpildฤซtas
runners.task_list.no_tasks=Vฤl nav uzdevumu.
-runners.task_list.run=Izpildฤซt
-runners.task_list.status=Statuss
-runners.task_list.repository=Repozitorijs
-runners.task_list.commit=Revฤซzija
+runners.task_list.run=Izpildฤซjums
+runners.task_list.status=Stฤvoklis
+runners.task_list.repository=Glabฤtava
+runners.task_list.commit=Iesลซtฤซjums
runners.task_list.done_at=Beigu laiks
runners.edit_runner=Labot izpildฤซtฤju
-runners.update_runner=Atjaunot izpildฤซtฤju
-runners.update_runner_success=Izpildฤซtฤjs veiksmฤซgi atjaunots
-runners.update_runner_failed=Neizdevฤs atjaunot izpildฤซtฤju
+runners.update_runner=Atjauninฤt izmaiลas
+runners.update_runner_success=Izpildฤซtฤjs sekmฤซgi atjauninฤts
+runners.update_runner_failed=Neizdevฤs atjauninฤt izpildฤซtฤju
runners.delete_runner=Dzฤst izpildฤซtฤju
-runners.delete_runner_success=Izpildฤซtฤjs veiksmฤซgi izdzฤsts
+runners.delete_runner_success=Izpildฤซtฤjs sekmฤซgi izdzฤsts
runners.delete_runner_failed=Neizdevฤs izdzฤst izpildฤซtฤju
runners.delete_runner_header=Apstiprinฤt izpildฤซtฤja izdzฤลกanu
-runners.delete_runner_notice=Ja ลกis izpildฤซtฤjs veic kฤdus uzdevumus, tad tie tiks apturฤti un atzฤซmฤti kฤ neizdevuลกies. Tas var sabojฤt bลซvฤลกanas darbaplลซsmas.
+runners.delete_runner_notice=Ja ลกis izpildฤซtฤjs veic kฤdus uzdevumus, tad tie tiks apturฤti un atzฤซmฤti kฤ neizdevuลกies. Tas var sabojฤt bลซvฤลกanas darbplลซsmas.
runners.none=Nav pieejami izpildฤซtฤji
runners.status.unspecified=Nezinฤms
runners.status.idle=Dฤซkstฤvฤ
-runners.status.active=Aktฤซvs
+runners.status.active=Darbojas
runners.status.offline=Bezsaistฤ
runners.version=Versija
runners.reset_registration_token=Atiestatฤซt reฤฃistrฤcijas pilnvaru
-runners.reset_registration_token_success=Izpildฤซtฤja reฤฃistrฤcijas pilnvara tika veiksmฤซgi atiestatฤซta
+runners.reset_registration_token_success=Izpildฤซtฤja reฤฃistrฤcijas pilnvara tika sekmฤซgi atiestatฤซta
-runs.all_workflows=Visas darbaplลซsmas
-runs.commit=Revฤซzija
+runs.all_workflows=Visas darbplลซsmas
+runs.commit=Iesลซtฤซjumu
runs.scheduled=Ieplฤnots
-runs.pushed_by=iesลซtฤซja
-runs.invalid_workflow_helper=Darbaplลซsmas konfigurฤcijas fails ir kฤผลซdains. Pฤrbaudiet konfiugrฤcijas failu: %s
-runs.no_matching_online_runner_helper=Nav pieejami izpildฤซtฤji, kas atbilstu ลกai iezฤซmei: %s
-runs.actor=Aktors
-runs.status=Statuss
-runs.actors_no_select=Visi aktori
+runs.pushed_by=aizgฤdฤja
+runs.invalid_workflow_helper=Darbplลซsmas konfigurฤcijas datne ir nederฤซga. Lลซgums pฤrbaudฤซt konfigurฤcijas datni: %s
+runs.no_matching_online_runner_helper=Nav tieลกsaistฤ esoลกu izpildฤซtฤju, kas atbilstu iezฤซmei: %s
+runs.actor=Izraisฤซtฤjs
+runs.status=Stฤvoklis
+runs.actors_no_select=Visi izraisฤซtฤji
runs.status_no_select=Visi stฤvokฤผi
runs.no_results=Netika atrasts nekas atbilstoลกs.
runs.no_workflows=Vฤl nav nevienas darbplลซsmas.
runs.no_runs=Darbplลซsmai vฤl nav nevienas izpildes.
-runs.empty_commit_message=(tukลกs revฤซzijas ziลojums)
+runs.empty_commit_message=(tukลกs iesลซtฤซjuma ziลojums)
workflow.disable=Atspฤjot darbplลซsmu
-workflow.disable_success=Darbplลซsma '%s' ir veiksmฤซgi atspฤjota.
+workflow.disable_success=Darbplลซsma "%s" ir sekmฤซgi atspฤjota.
workflow.enable=Iespฤjot darbplลซsmu
-workflow.enable_success=Darbplลซsma '%s' ir veiksmฤซgi iespฤjota.
+workflow.enable_success=Darbplลซsma "%s" ir sekmฤซgi iespฤjota.
workflow.disabled=Darbplลซsma ir atspฤjota.
-need_approval_desc=Nepiecieลกams apstiprinฤjums, lai izpildฤซtu izmaiลu pieprasฤซjumu darbaplลซsmas no atdalฤซtiem repozitorijiem.
+need_approval_desc=Nepiecieลกams apstiprinฤjums, lai izpildฤซtu darbplลซsmas izmaiลu pieprasฤซjumos no atzarojumiem.
variables=Mainฤซgie
-variables.management=Mainฤซgo pฤrvaldฤซba
+variables.management=Pฤrvaldฤซt mainฤซgos
variables.creation=Pievienot mainฤซgo
variables.none=Vฤl nav neviena mainฤซgฤ.
variables.deletion=Noลemt mainฤซgo
-variables.deletion.description=Mainฤซgฤ noลemลกana ir neatgriezeniska un nav atsaucama. Vai turpinฤt?
+variables.deletion.description=Mainฤซgฤ noลemลกana ir neatgriezeniska un nav atsaucama. Turpinฤt?
variables.description=Mainฤซgie tiks padoti noteiktฤm darbฤซbฤm, un citฤdฤk tos nevar nolasฤซt.
variables.id_not_exist=Mainฤซgais ar identifikatoru %d nepastฤv.
variables.edit=Labot mainฤซgo
@@ -3574,18 +3978,100 @@ variables.creation.failed=Neizdevฤs pievienot mainฤซgo.
variables.creation.success=Mainฤซgais "%s" tika pievienots.
variables.update.failed=Neizdevฤs labot mainฤซgo.
variables.update.success=Mainฤซgais tika labots.
+workflow.dispatch.invalid_input_type = Nederฤซgs ievades mainฤซgฤ veids "%s".
+workflow.dispatch.run = Izpildฤซt darbplลซsmu
+workflow.dispatch.success = Darbplลซsmas izpildฤซลกana tika sekmฤซgi pieprasฤซta.
+workflow.dispatch.use_from = Izmantot darbplลซsmu no
+runs.workflow = Darbplลซsma
+runs.no_job_without_needs = Darbplลซsmฤ ir jฤbลซt vismaz vienam darbam bez atkarฤซbฤm.
+workflow.dispatch.input_required = Nepiecieลกama vฤrtฤซba ievades mainฤซgajam "%s".
+runs.expire_log_message = ลฝurnฤli tika iztฤซrฤซti, jo tie bija pฤrฤk veci.
+runs.no_workflows.help_no_write_access = Lai uzzinฤtu par Forgejo Acties, jฤieskatฤs dokumentฤcijฤ .
+runs.no_job = Darbplลซsmฤ ir jฤbลซt vismaz vienam darbam
+runs.no_workflows.help_write_access = Nav skaidrs, kฤ sฤkt izmantot Forgejo Actions? Jฤieskatฤs ฤtrajฤ ievadฤ lietotฤja dokumentฤcijฤ , lai uzrakstฤซtu savu pirmo darbplลซsmu, tad jฤiestata Forgejo izpildฤซtฤjs , lai izpildฤซtu savus darbus.
+workflow.dispatch.warn_input_limit = Attฤlo tikai pirmos %d ievades mainฤซgos.
+workflow.dispatch.trigger_found = ล ai darbplลซsmai ir workflow_dispatch notikuma izraisฤซtฤjs.
+variables.not_found = Neizdevฤs atrast mainฤซgo.
[projects]
-type-1.display_name=Individuฤlais projekts
-type-2.display_name=Repozitorija projekts
-type-3.display_name=Organizฤcijas projekts
+type-1.display_name=Atseviลกฤทs projekts
+type-2.display_name=Glabฤtavas projekts
+type-3.display_name=Apvienฤซbas projekts
+deleted.display_name = Izdzฤsts projekts
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
-directory=Direktorija
-normal_file=Parasts fails
-executable_file=Izpildฤmais fails
+directory=Mape
+normal_file=Parasta datne
+executable_file=Izpildฤma datne
symbolic_link=Simboliska saite
submodule=Apakลกmodulis
+
+
+[search]
+commit_kind = Meklฤt iesลซtฤซjumusโฆ
+search = Meklฤtโฆ
+type_tooltip = Meklฤลกanas veids
+fuzzy = Aptuveni
+fuzzy_tooltip = Iekฤผaut arฤซ vienumus, kas meklฤลกanas vaicฤjumam atbilst aptuveni
+union = Vispฤrฤji
+union_tooltip = Iekฤผaut vienumus, kas atbilst jebkuram no ar atstarpi atdalฤซtajiem atslฤgvฤrdiem
+exact = Tieลกi
+exact_tooltip = Iekฤผaut tikai vienumus, kas tieลกi atbilst vaicฤjumam
+regexp = Regulฤrฤ izteiksme
+regexp_tooltip = Apstrฤdฤt vaicฤjumu kฤ regulฤro izteiksmi
+repo_kind = Meklฤt glabฤtavasโฆ
+code_search_unavailable = Koda meklฤลกana paลกlaik nav pieejama. Lลซgums sazinฤties ar vietnes pฤrvaldฤซtฤju.
+project_kind = Meklฤt projektusโฆ
+runner_kind = Meklฤt izpildฤซtฤjusโฆ
+no_results = Nekas netika atrasts.
+milestone_kind = Meklฤt atskaites punktus...
+package_kind = Meklฤt pakotnesโฆ
+org_kind = Meklฤt apvienฤซbasโฆ
+user_kind = Meklฤt lietotฤjusโฆ
+team_kind = Meklฤt komandasโฆ
+code_kind = Meklฤt koduโฆ
+code_search_by_git_grep = Paลกreizฤjo koda meklฤลกanas iznฤkumu nodroลกina "git grep". Iznฤkums varฤtu bลซt labฤks, ja vietnes pฤrvaldฤซtฤjs iespฤjo glabฤtavas indeksฤtฤju.
+keyword_search_unavailable = Meklฤลกana pฤc atslฤgvฤrda paลกreiz nav pieejama. Lลซgums sazinฤties ar vietnes pฤrvaldฤซtฤju.
+issue_kind = Meklฤt pieteikumusโฆ
+pull_kind = Meklฤt izmaiลu pieprasฤซjumusโฆ
+branch_kind = Meklฤt zarusโฆ
+
+[repo.permissions]
+actions.write = Rakstฤซt: paลกrocฤซgi izsaukt, pฤrsฤktnฤt, atcelt vai apstiprinฤt ierindotos CI/CD cauruฤผvadus.
+ext_wiki = Piekฤผลซt ฤrฤjas vikivietnes saitei. Atฤผaujas tiek pฤrvaldฤซtas ฤrฤji.
+ext_issues = Piekฤผลซt ฤrฤja pieteikumu izsekotฤja saitei. Atฤผaujas tiek pฤrvaldฤซtas ฤrฤji.
+packages.write = Rakstฤซt: pievienot un izdzฤst glabฤtavai piesaistฤซtฤs pakotnes.
+actions.read = Lasฤซt: skatฤซt iekฤผautos CI/CD cauruฤผvadus un to ลพurnฤlus.
+code.write = Rakstฤซt: aizgฤdฤta izmaiลas uz glabฤtavu, izveidot zarus un birkas.
+pulls.write = Rakstฤซt: aizvฤrt izmaiลu pieprasฤซjumus un pฤลvaldฤซt tฤdus metadatus kฤ iezฤซmes, atskaites punktus, atbildฤซgos, beigu datumus un atkarฤซbas.
+pulls.read = Lasฤซt: lasฤซลกana un izveidot izmaiลu pieprasฤซjumus.
+code.read = Lasฤซt : piekฤผลซt glabฤtavas kodam un klonฤt to.
+issues.read = Lasฤซt : lasฤซt un izveidot pieteikumus un piebildes.
+issues.write = Rakstฤซt : aizvฤrt pieteikums un pฤrvaldฤซt tฤdus metadatus kฤ iezฤซmes, atskaites punktus, atbildฤซgos, beigu datumus un atkarฤซbas.
+wiki.read = Lasฤซt : lasฤซt iebลซvฤto vikivietni un tฤs vฤsturi.
+projects.write = Rakstฤซt : izveidot projektus un slejas un labot tฤs.
+packages.read = Lasฤซt : apskatฤซt un lejupielฤdฤt glabฤtavai piesaistฤซtฤs pakotnes.
+releases.read = Lasฤซt : apskatฤซt un lejupielฤdฤt laidienus.
+releases.write = Rakstฤซt : laist klajฤ, labot un izdzฤst laidienus un to lฤซdzekฤผus.
+wiki.write = Rakstฤซt : izveidot, atjauninฤt un izdzฤst iebลซvฤtฤs vikivietnes lapas.
+projects.read = Lasฤซt : piekฤผลซt glabฤtavas projektu dฤฤผiem.
+
+
+[munits.data]
+mib = MiB
+pib = PiB
+gib = GiB
+tib = TiB
+kib = KiB
+eib = EiB
+b = B
+
+[markup]
+filepreview.line = %[1]d. rinda %[2]s
+filepreview.lines = %[1]d. lฤซdz %[2]d. rinda %[3]s
+filepreview.truncated = Priekลกskatฤซjums tika saฤซsinฤts
+
+[translation_meta]
+test = ล ฤซ ir pฤrbaudes virkne. Tฤ netiek attฤlota Forgejo saskarnฤ, bet tiek izmantota pฤrbaudes nolลซkiem. Droลกi var ievadฤซt "ok", lai ietaupฤซtu laiku (vai kฤdu jautru faktu pฤc izvฤles), lai sasniegtu to saldo 100% pabeigลกanas atzฤซmi.
diff --git a/options/locale/locale_ml-IN.ini b/options/locale/locale_ml-IN.ini
new file mode 100644
index 0000000000..fcc9888d8e
--- /dev/null
+++ b/options/locale/locale_ml-IN.ini
@@ -0,0 +1,787 @@
+[common]
+home=เดชเตเดฎเตเดเด
+dashboard=เดกเดพเดทเตเดฌเตเดพเตผเดกเต
+explore=เดเดฃเตเดเตเดคเตเดคเต
+help=เดธเดนเดพเดฏเด
+sign_in=เดชเตเดฐเดตเตเดถเดฟเดเตเดเตเด
+sign_in_with=เดเดชเดฏเตเดเดฟเดเตเดเตเต เดชเตเดฐเดตเตเดถเดฟเดฏเตเดเตเดเตเด
+sign_out=เดชเตเดฑเดคเตเดคเตเดเดเดเตเดเตเด
+sign_up=เดฐเดเดฟเดธเตเดฑเตเดฑเตผ
+link_account=เด
เดเตเดเตเดฃเตเดเต เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดฏเตเดเตเดเตเด
+register=เดฐเดเดฟเดธเตเดฑเตเดฑเตผ
+version=เดชเดคเดฟเดชเตเดชเต
+page=เดชเตเดเต
+template=เดเตเดเดชเตเดฒเตเดฑเตเดฑเต
+language=เดญเดพเดท
+notifications=เด
เดฑเดฟเดฏเดฟเดชเตเดชเตเดเตพ
+create_new=เดธเตเดทเตเดเดฟเดเตเดเตเดโฆ
+user_profile_and_more=เดชเตเดฐเตเดซเตเดฒเตเด เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเดณเตเดโฆ
+signed_in_as=เดเดฏเดพเดณเดพเดฏเดฟ เดชเตเดฐเดตเตเดถเดฟเดฏเตเดเตเดเตเด
+enable_javascript=เด เดตเตเดฌเตโเดธเตเดฑเตเดฑเต เดเดพเดตเดพเดธเตเดเตเดฐเดฟเดชเตเดฑเตเดฑเดฟเดจเตเดชเตเดชเด เดฎเดฟเดเดเตเด เดฐเตเดคเดฟเดฏเดฟเตฝ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจเต.
+
+username=เดเดชเดฏเตเดเตเดคเตเดฐเต เดจเดพเดฎเด
+email=เดเดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด
+password=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต
+re_type=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต เดตเตเดฃเตเดเตเด เดจเดฒเตโเดเตเด
+captcha=เดเตเดฏเดพเดชเตเด
+twofa=เดเดฐเดเตเด เดเดเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด
+twofa_scratch=เดเดฐเดเตเด เดซเดพเดเตเดเตผ เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดกเต
+passcode=เดฐเดนเดธเตเดฏ เดเตเดกเต
+
+
+repository=เดเดฒเดตเดฑ
+organization=เดธเดเดเดเดจ
+mirror=เดฎเดฟเดฑเดฐเตโ
+new_repo=เดชเตเดคเดฟเดฏ เดเดฒเดตเดฑ
+new_migrate=เดชเตเดคเดฟเดฏ เดเตเดเดฟเดฏเตเดฑเตเดฑเดฟเดชเตเดชเดพเดฐเตโเดชเตเดชเดฟเดเตเดเดฒเตโ
+new_mirror=เดชเตเดคเดฟเดฏ เดฎเดฟเดฑเดฐเตโ
+new_fork=เดเดฒเดตเดฑเดฏเตเดเต เดชเตเดคเดฟเดฏ เดถเดฟเดเดฐเด
+new_org=เดชเตเดคเดฟเดฏ เดธเดเดเดเดจ
+manage_org=เดธเดเดเดเดจเดเดณเต เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+admin_panel=เดธเตเดฑเตเดฑเดฟเดจเตเดฑเต เดเดพเดฐเตเดฏเดจเดฟเดฐเตโเดตเตเดตเดพเดนเดฃเด
+account_settings=เด
เดเตเดเตเดฃเตเดเต เดเตเดฐเดฎเตเดเดฐเดฃเดเดณเตโ
+settings=เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเดณเตโ
+your_profile=เดชเตเดฐเตเดซเตเตฝ
+your_starred=เดจเดเตเดทเดคเตเดฐ เดเดฟเดนเตเดจเดฎเดฟเดเตเดเดต
+your_settings=เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเดณเตโ
+
+all=เดเดฒเตเดฒเดพเด
+sources=เดเดฑเดตเดฟเดเดเตเดเตพ
+mirrors=เดฎเดฟเดฑเดฑเตเดเดณเตโ
+collaborative=เดธเดนเดเดฐเดฟเดเตเดเตเดจเตเดจ
+forks=เดถเดพเดเดเดณเตโ
+
+activities=เดชเตเดฐเดตเดฐเตโเดคเตเดคเดจเดเตเดเดณเตโ
+pull_requests=เดฒเดฏเดจ เด
เดญเตเดฏเตผเดคเตเดฅเดจเดเตพ
+issues=เดชเตเดฐเดถเตเดจเดเตเดเตพ
+
+cancel=เดฑเดฆเตเดฆเดพเดเตเดเตเด
+
+
+write=เดเดดเตเดคเตเด
+preview=เดคเดฟเดฐเดจเตเดเตเดเด
+loading=เดฒเดญเตเดฏเดฎเดพเดเตเดเตเดจเตเดจเตโฆ
+
+
+
+
+
+[filter]
+
+[error]
+
+[startpage]
+
+[install]
+install=เดธเดจเตเดจเดฟเดตเตเดถเดฟเดชเตเดชเดฟเดฏเตเดเตเดเตเด
+title=เดชเตเดฐเดพเดฐเดเดญ เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเดณเตโ
+docker_helper=เดกเตเดเตเดเดฑเดฟเดจเตเดณเตเดณเดฟเดฒเดพเดฃเต เดเดฟเดฑเตเดฑเต เดชเตเดฐเดตเดฐเตโเดคเตเดคเดฟเดชเตเดชเดฟเดฏเตเดเตเดเตเดจเตเดจเดคเตเดเตเดเดฟเดฒเตโ, เดฎเดพเดฑเตเดฑเดเตเดเดณเตโ เดตเดฐเตเดคเตเดคเตเดจเตเดจเดคเดฟเดจเต เดฎเตเดฎเตเดชเตเต เดฆเดฏเดตเดพเดฏเดฟ เดกเตเดเตเดฏเตเดฎเตเดจเตเดฑเตเดทเตป เดตเดพเดฏเดฟเดฏเตเดเตเดเตเด.
+db_title=เดกเดพเดฑเตเดฑเดพเดฌเตเดธเต เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเตพ
+db_type=เดกเดพเดฑเตเดฑเดพเดฌเตเดธเดฟเดจเตเดฑเต เดคเดฐเด
+host=เดนเตเดธเตเดฑเตเดฑเต
+user=เดเดชเดฏเตเดเตเดคเตเดฐเต เดจเดพเดฎเด
+password=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต
+db_name=เดกเดพเดฑเตเดฑเดพเดฌเตเดธเดฟเดจเตเดฑเต เดชเตเดฐเต
+db_helper=MySQL เดเดชเดฏเตเดเตเดคเดพเดเตเดเตพเดเตเดเตเดณเตเดณ เดเตเดฑเดฟเดชเตเดชเต: เดฆเดฏเดตเดพเดฏเดฟ InnoDB เดธเตเดฑเตเดฑเตเดฑเตเดเต เดเดเตเดเดฟเตป เดเดชเดฏเตเดเดฟเดเตเดเตเด. เดจเดฟเดเตเดเตพ "utf8mb4" เดเดชเดฏเตเดเดฟเดเตเดเตเดเดฏเดพเดฃเตเดเตเดเดฟเตฝ, InnoDB เดชเดคเดฟเดชเตเดชเต 5.6 เดจเตเดเตเดเดพเตพ เดตเดฒเตเดคเดพเดฏเดฟเดฐเดฟเดเตเดเดฃเด.
+ssl_mode=SSL
+charset=เดเตเดฏเดพเดฐเตโเดธเตเดฑเตเดฑเต
+path=เดชเดพเดค
+sqlite_helper=SQLite3 เดกเดพเดฑเตเดฑเดพเดฌเตเดธเดฟเดจเตเดฑเต เดซเดฏเดฒเตโ เดชเดพเดคเตเดคเต. เดจเดฟเดเตเดเตพ เดเดฟเดฑเตเดฑเตเดฏเต เดเดฐเต เดธเตเดตเดจเดฎเดพเดฏเดฟ เดชเตเดฐเดตเตผเดคเตเดคเดฟเดชเตเดชเดฟเดเตเดเตเดเดฏเดพเดฃเตเดเตเดเดฟเตฝ เดธเดฎเตเดชเตเดฐเตโเดฃเตเดฃ เดซเดฏเดฒเตโ เดชเดพเดค เดจเตฝเดเตเด.
+err_empty_db_path=SQLite3 เดกเดพเดฑเตเดฑเดพเดฌเตเดธเต เดชเดพเดคเตเดคเต เดถเตเดจเตเดฏเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเดฐเตเดคเต.
+no_admin_and_disable_registration=เดเดฐเต เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเตผ เด
เดเตเดเตเดฃเตเดเต เดธเตเดทเตเดเดฟเดเตเดเดพเดคเต เดจเดฟเดเตเดเตพเดเตเดเต เดเดชเดฏเตเดเตเดคเต เดธเตเดตเดฏเด เดฐเดเดฟเดธเตเดเตเดฐเตเดทเตป เด
เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+err_empty_admin_password=เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฑเตเดเต เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต เดถเตเดจเตเดฏเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเดฐเตเดคเต.
+err_empty_admin_email=เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฑเตเดเต เดเดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด เดถเตเดจเตเดฏเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเดฐเตเดคเต.
+err_admin_name_is_reserved=เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฐเตโ เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด เด
เดธเดพเดงเตเดตเดพเดฃเต, เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด เดฑเดฟเดธเดฐเตโเดตเตเดตเต เดเตเดฏเตเดคเดคเดพเดฃเต
+err_admin_name_is_invalid=เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเตผ เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด เด
เดธเดพเดงเตเดตเดพเดฃเต
+
+general_title=เดชเตเดพเดคเตเดตเดพเดฏ เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเตพ
+app_name=เดธเตเดฑเตเดฑเต เดถเตเตผเดทเดเด
+app_name_helper=เดจเดฟเดเตเดเดณเตเดเต เดเดฎเตเดชเดจเดฟเดฏเตเดเต เดชเตเดฐเต เดเดตเดฟเดเต เดจเตฝเดเดพเด.
+repo_path=เดธเดเดญเดฐเดฃเดฟเดฏเตเดเต เดฑเตเดเตเดเต เดชเดพเดคเตเดคเต
+repo_path_helper=เดตเดฟเดฆเตเดฐ เดเดฟเดฑเตเดฑเตเต เดธเดเดญเดฐเดฃเดฟเดเดณเตโ เด เดกเดฏเดฑเดเตเดเดฑเดฟเดฏเดฟเดฒเตเดเตเดเต เดธเดเดฐเดเตเดทเดฟเดเตเดเตเด.
+lfs_path=Git LFS เดฑเตเดเตเดเต เดชเดพเดคเตเดคเต
+lfs_path_helper=Git LFS เดเตเดฐเดพเดเตเดเตเดเตเดฏเตเดค เดซเดฏเดฒเตเดเตพ เด เดกเดฏเดฑเดเตเดเดฑเดฟเดฏเดฟเตฝ เดธเตเดเตเดทเดฟเดเตเดเตเด. เดชเตเดฐเดตเตผเดคเตเดคเดจเดฐเดนเดฟเดคเดฎเดพเดเตเดเดพเตป เด เดเดณเด เดถเตเดจเตเดฏเดฎเดพเดฏเดฟ เดตเดฟเดเตเด.
+run_user=เดเดชเดฏเตเดเตเดคเดพเดตเดพเดฏเดฟ เดชเตเดฐเดตเดฐเตโเดคเตเดคเดฟเดชเตเดชเดฟเดเตเดเตเด
+run_user_helper=เดเดฟเดฑเตเดฑเต เดชเตเดฐเดตเตผเดคเตเดคเดฟเดเตเดเตเดจเตเดจ เดเดชเตเดชเดฑเตเดฑเตเดฑเดฟเดเดเต เดธเดฟเดธเตเดฑเตเดฑเดคเตเดคเดฟเดจเตเดฑเต เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด เดจเดฒเตเดเตเด. เด เดเดชเดฏเตเดเตเดคเดพเดตเดฟเดจเต เดธเดเดญเดฐเดฃเดฟเดฏเตเดเต เดฑเตเดเตเดเต เดชเดพเดคเตเดคเดฟเดฒเตเดเตเดเต เดชเตเดฐเดตเตเดถเดจเด เดเดฃเตเดเดพเดฏเดฟเดฐเดฟเดเตเดเดฃเด.
+ssh_port=SSH เดธเตเตผเดตเตผ เดชเตเดฐเตโเดเตเดเต
+ssh_port_helper=เดจเดฟเดเตเดเดณเตเดเต SSH เดธเตเตผเดตเตผ เดถเตเดฐเดตเดฟเดเตเดเตเดจเตเดจ เดชเตเตผเดเตเดเต เดจเดฎเตเดชเตผ เดจเดฒเตโเดเตเด. เดชเตเดฐเดตเตผเดคเตเดคเดจเดฐเดนเดฟเดคเดฎเดพเดเตเดเดพเตป เดเดณเด เดถเตเดจเตเดฏเดฎเดพเดฏเดฟ เดตเดฟเดเตเด.
+http_port=เดเดฟเดฑเตเดฑเต เดเดเตเดเตเดเดฟเดเดฟเดชเดฟ เดถเตเดฐเดตเดฟเดฏเตเดเตเดเตเดจเตเดจ เดชเตเตผเดเตเดเต
+http_port_helper=เดเดฟเดฑเตเดฑเต เดตเตเดฌเต เดธเตเตผเดตเตผ เดถเตเดฐเดตเดฟเดฏเตเดเตเดเตเดจเตเดจ เดชเตเตผเดเตเดเต เดจเดฎเตเดชเตผ.
+app_url=เดเดฟเดฑเตเดฑเตเดฏเตเดเต เด
เดเดฟเดธเตเดฅเดพเดจ เดตเดฟเดฒเดพเดธเด
+app_url_helper=เดเดเตเดเตเดเดฟเดเดฟเดชเดฟ(เดเดธเต) เดเตเดฒเตเดฃเตเดเดณเตโเดเตเดเตเด เดเดฎเตเดฏเดฟเตฝ เด
เดฑเดฟเดฏเดฟเดชเตเดชเตเดเตพเดเตเดเตเดฎเดพเดฏเตเดณเตเดณ เด
เดเดฟเดธเตเดฅเดพเดจ เดตเดฟเดฒเดพเดธเด.
+log_root_path=เดฒเตเดเต เดชเดพเดคเตเดคเต
+log_root_path_helper=เดฒเตเดเต เดซเดฏเดฒเตเดเตพ เด เดกเดฏเดฑเดเตเดเดฑเดฟเดฏเดฟเดฒเตเดเตเดเต เดเดดเตเดคเดชเตเดชเตเดเตเด.
+
+optional_title=เดเดเตเดเดฟเดเดฎเดพเดฏ เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเตพ
+email_title=เดเดฎเตเดฏเดฟเตฝ เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเตพ
+smtp_from=เด เดตเดฟเดฒเดพเดธเดคเตเดคเดฟเดฒเตโ เดเดฎเตเดฏเดฟเตฝ เด
เดฏเดฏเตโเดเตเดเตเด
+smtp_from_helper=เดเดฟเดฑเตเดฑเต เดเดชเดฏเตเดเดฟเดฏเตเดเตเดเตเดจเตเดจ เดเดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด. เดเดฐเต เดธเดพเดงเดพ เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดจเตฝเดเตเด เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ "เดชเตเดฐเต" เดเดจเตเดจ เดเดเดจ เดเดชเดฏเตเดเดฟเดเตเดเตเด.
+mailer_user=SMTP เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด
+mailer_password=SMTP เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต
+register_confirm=เดฐเดเดฟเดธเตเดฑเตเดฑเตผ เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต เดเดฎเตเดฏเดฟเตฝ เดธเตเดฅเดฟเดฐเตเดเดฐเดฃเด เดเดตเดถเตเดฏเดฎเดพเดเตเดเตเด
+mail_notify=เดเดฎเตเดฏเดฟเตฝ เด
เดฑเดฟเดฏเดฟเดชเตเดชเตเดเตพ เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด
+server_service_title=เดธเตเตผเดตเดฑเดฟเดจเตเดฑเตเดฏเตเด เดฎเตเดจเตเดจเดพเด เดเดเตเดทเดฟ เดธเตเดตเดจเดเตเดเดณเตเดเตเดฏเตเด เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเดณเตโ
+offline_mode=เดชเตเดฐเดพเดฆเตเดถเดฟเด เดฎเตเดกเต เดชเตเดฐเดตเตผเดคเตเดคเดจเดเตเดทเดฎเดฎเดพเดเตเดเตเด
+offline_mode_popup=เดฎเตเดจเตเดจเดพเด เดเดเตเดทเดฟ เดเดณเตเดณเดเดเตเด เดกเตเดฒเดฟเดตเดฑเดฟ เดจเตเดฑเตเดฑเตโเดตเตผเดเตเดเตเดเตพ เด
เดชเตเดฐเดพเดชเตโเดคเดฎเดพเดเตเดเดฟ เดเดฒเตเดฒเดพ เดตเดฟเดญเดตเดเตเดเดณเตเด เดชเตเดฐเดพเดฆเตเดถเดฟเดเดฎเดพเดฏเดฟ เดจเดฒเตโเดเตเด.
+disable_gravatar=เดเตเดฐเดตเดคเดพเดฐเตโ เดชเตเดฐเดตเตผเดคเตเดคเดจเดฐเดนเดฟเดคเดฎเดพเดเตเดเตเด
+disable_gravatar_popup=เดเตเดฐเดตเดคเดพเดฐเตโ เด
เดฒเตเดฒเตเดเตเดเดฟเดฒเตโ เดฎเตเดจเตเดจเดพเด เดเดเตเดทเดฟ เด
เดตเดคเดพเตผ เดเดฑเดตเดฟเดเดเตเดเตพ เดชเตเดฐเดตเตผเดคเตเดคเดจเดฐเดนเดฟเดคเดฎเดพเดเตเดเตเด. เดเดฐเต เดเดชเดฏเตเดเตเดคเดพเดตเต เดชเตเดฐเดพเดฆเตเดถเดฟเดเดฎเดพเดฏเดฟ เดเดฐเต เด
เดตเดคเดพเตผ เด
เดชเตโเดฒเตเดกเตเดเตเดฏเตเดฏเตเดจเตเดจเดฟเดฒเตเดฒเตเดเตเดเดฟเตฝ เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟ เด
เดตเดคเดพเตผ เดเดชเดฏเตเดเดฟเดเตเดเตเด.
+federated_avatar_lookup=เดเตเดจเตเดฆเตเดฐเตเดเตเดค เด
เดตเดคเดพเดฐเตโ เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด
+federated_avatar_lookup_popup=เดฒเดฟเดฌเตเดฐเดพเดตเดคเดพเตผ เดเดชเดฏเตเดเดฟเดเตเดเต เดเตเดจเตเดฆเตเดฐเตเดเตเดฐเดค เด
เดตเดคเดพเตผ เดคเดฟเดฐเดฏเตฝ เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด.
+disable_registration=เดธเตเดตเดฏเด เดฐเดเดฟเดธเตเดเตเดฐเตเดทเตป เด
เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด
+disable_registration_popup=เดเดชเดฏเตเดเตเดคเดพเดเตเดเดณเตโ เดธเตเดตเดฏเด เดฐเดเดฟเดธเตเดฑเตเดฑเดฐเตโ เดเตเดฏเตเดฏเตเดจเตเดจเดคเต เด
เดชเตเดฐเดพเดชเตเดฏเดฎเดพเดเตเดเตเด. เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเตผเดฎเดพเตผเดเตเดเต เดฎเดพเดคเตเดฐเดฎเต เดชเตเดคเดฟเดฏ เดเดชเดฏเตเดเตเดคเต เด
เดเตเดเตเดฃเตเดเตเดเตพ เดธเตเดทเตเดเดฟเดเตเดเดพเดจเตโ เดเดดเดฟเดฏเต.
+allow_only_external_registration_popup=เดฌเดพเดนเตเดฏ เดธเตเดตเดจเดเตเดเดณเดฟเดฒเตเดเต เดฎเดพเดคเตเดฐเด เดฐเดเดฟเดธเตเดเตเดฐเตเดทเดจเตโ เด
เดจเตเดตเดฆเดฟเดเตเดเตเด
+openid_signin=OpenID เดชเตเดฐเดตเตเดถเดจเด เดชเตเดฐเดตเตผเดคเตเดคเดจเดเตเดทเดฎเดฎเดพเดเตเดเตเด
+openid_signin_popup=OpenID เดตเดดเดฟ เดเดชเดฏเตเดเตเดคเต เดชเตเดฐเดตเตเดถเดจเด เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด.
+openid_signup=OpenID เดธเตเดตเดฏเด เดฐเดเดฟเดธเตเดเตเดฐเตเดทเตป เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด
+openid_signup_popup=OpenID เด
เดเดฟเดธเตเดฅเดพเดจเดฎเดพเดเตเดเดฟเดฏเตเดณเตเดณ เดเดชเดฏเตเดเตเดคเต เดธเตเดตเดฏเด เดฐเดเดฟเดธเตเดเตเดฐเตเดทเตป เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด.
+enable_captcha_popup=เดเดชเดฏเตเดเตเดคเดพเดเตเดเดณเตโ เดธเตเดตเดฏเด เดฐเดเดฟเดธเตเดเตเดฐเตเดทเดจเตโ เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเตเต เดเดฐเต เดเตเดฏเดพเดชเตเด เดเดตเดถเตเดฏเดฎเดพเดฃเต.
+require_sign_in_view=เดชเตเดเตเดเตพ เดเดพเดฃเตเดจเตเดจเดคเดฟเดจเต เดธเตเดฑเตเดฑเดฟเดฒเตโ เดชเตเดฐเดตเตเดถเดฟเดเตเดเดฃเด
+require_sign_in_view_popup=เดชเตเดเต เดเดเตโเดธเดธเตเดธเต, เดชเตเดฐเดตเตเดถเดฟเดเตเด เดเดชเดฏเตเดเตเดคเดพเดเตเดเตพเดเตเดเตเดฎเดพเดคเตเดฐเดฎเดพเดฏเดฟ เดชเดฐเดฟเดฎเดฟเดคเดชเตเดชเตเดเตเดคเตเดคเตเด. เดธเดจเตเดฆเตผเดถเดเตผ 'เดชเตเดฐเดตเตเดถเดจเด', เดฐเดเดฟเดธเตเดเตเดฐเตเดทเตป เดชเตเดเตเดเตพ เดเดจเตเดจเดฟเดต เดฎเดพเดคเตเดฐเดฎเต เดเดพเดฃเต.
+admin_setting_desc=เดเดฐเต เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฐเตโ เด
เดเตเดเตเดฃเตเดเต เดธเตเดทเตเดเดฟเดเตเดเตเดจเตเดจเดคเต เดเดเตเดเดฟเดเดฎเดพเดฃเต. เดเดฆเตเดฏเด เดฐเดเดฟเดธเตเดฑเตเดฑเดฐเตโ เดเตเดฏเตเดค เดเดชเดฏเตเดเตเดคเดพเดตเต เดฏเดพเดจเตเดคเตเดฐเดฟเดเดฎเดพเดฏเดฟ เดเดฐเต เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฑเดพเดฏเดฟ เดฎเดพเดฑเตเด.
+admin_title=เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฐเตโ เด
เดเตเดเตเดฃเตเดเต เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเตพ
+admin_name=เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฑเตเดเต เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด
+admin_password=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต
+confirm_password=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเตเด
+admin_email=เด-เดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด
+install_btn_confirm=เดเดฟเดฑเตเดฑเต เดธเดจเตเดจเดฟเดตเตเดถเดฟเดชเตเดชเดฟเดฏเตเดเตเดเตเด
+test_git_failed='git' เดเดฎเดพเดจเตโเดกเต เดชเดฐเตเดเตเดทเดฟเดเตเดเดพเดจเตโ เดเดดเดฟเดเตเดเดฟเดฒเตเดฒ: %v
+sqlite3_not_available=เดเดฟเดฑเตเดฑเตเดฏเตเดเต เด เดตเตเดฐเตโเดทเดจเตโ SQLite3เดฏเต เดชเดฟเดจเตเดคเตเดฃเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒ. %s เตฝ เดจเดฟเดจเตเดจเตเด เดเดฆเตเดฏเตเดเดฟเด เดฌเตเดจเดฑเดฟ เดชเดคเดฟเดชเตเดชเต เดกเตเดฃเตโโเดฒเตเดกเต เดเตเดฏเตเดฏเตเด ('gobuild' เดชเดคเดฟเดชเตเดชเดฒเตเดฒ).
+invalid_db_setting=เดกเดพเดฑเตเดฑเดพเดฌเตเดธเต เดเตเดฐเดฎเตเดเดฐเดฃเดเตเดเตพ เด
เดธเดพเดงเตเดตเดพเดฃเต: %v
+invalid_repo_path=เดเดฒเดตเดฑเดฏเตเดเต เดฑเตเดเตเดเต เดชเดพเดคเตเดคเต เด
เดธเดพเดงเตเดตเดพเดฃเต: %v
+run_user_not_match='เดฑเตบ เดเดธเต' เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด เดจเดฟเดฒเดตเดฟเดฒเต เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเดฎเดฒเตเดฒ: %s -> %s
+save_config_failed=เดเตเตบเดซเดฟเดเดฑเตเดทเตป เดธเดเดฐเดเตเดทเดฟเดเตเดเตเดจเตเดจเดคเดฟเตฝ เดชเดฐเดพเดเดฏเดชเตเดชเตเดเตเดเต: %v
+invalid_admin_setting=เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฐเตโ เด
เดเตเดเตเดฃเตเดเต เดเตเดฐเดฎเตเดเดฐเดฃเด เด
เดธเดพเดงเตเดตเดพเดฃเต: %v
+install_success=เดธเตเดตเดพเดเดคเด! เดเดฟเดฑเตเดฑเต เดคเดฟเดฐเดเตเดเตเดเตเดคเตเดคเดคเดฟเดจเต เดจเดจเตเดฆเดฟ. เดธเตเดเตเดทเดฟเดเตเดเตเด, เดเดธเตเดตเดฆเดฟเดเตเดเต,!
+invalid_log_root_path=เดฒเตเดเต เดชเดพเดคเตเดคเต เด
เดธเดพเดงเตเดตเดพเดฃเต: %v
+default_keep_email_private=เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟเดฏเดพเดฏเดฟ เดเดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเดเตเดเดณเตโ เดฎเดฑเดฏเตโเดเตเดเตเด
+default_keep_email_private_popup=เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟเดฏเดพเดฏเดฟ เดชเตเดคเดฟเดฏ เดเดชเดฏเตเดเตเดคเต เด
เดเตเดเตเดฃเตเดเตเดเดณเตเดเต เดเดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเดเตเดเดณเตโ เดฎเดฑเดฏเตเดเตเดเตเด.
+default_allow_create_organization=เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟเดฏเดพเดฏเดฟ เดธเดเดเดเดจเดเดณเตโ เดธเตเดทเตเดเดฟเดเตเดเดพเดจเตโ เด
เดจเตเดตเดฆเดฟเดเตเดเตเด
+default_allow_create_organization_popup=เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟเดฏเดพเดฏเดฟ เดธเดเดเดเดจเดเดณเตโ เดธเตเดทเตเดเดฟเดเตเดเดพเดจเตโ เดชเตเดคเดฟเดฏ เดเดชเดฏเตเดเตเดคเต เด
เดเตเดเตเดฃเตเดเตเดเดณเต เด
เดจเตเดตเดฆเดฟเดเตเดเตเด.
+default_enable_timetracking=เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟเดฏเดพเดฏเดฟ เดธเดฎเดฏเด เดเตเดฐเดพเดเตเดเตเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเต เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด
+default_enable_timetracking_popup=เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟเดฏเดพเดฏเดฟ เดชเตเดคเดฟเดฏ เดเดฒเดตเดฑเดเดณเตโเดเตเดเตเต เดธเดฎเดฏเด เดเตเดฐเดพเดเตเดเตเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเตเต เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด.
+no_reply_address=เดฎเดฑเดเตเด เดเดฎเตเดฏเดฟเตฝ เดกเตเดฎเตเดฏเตเตป
+no_reply_address_helper=เดฎเดฑเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจ เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเดฎเตเดณเตเดณ เดเดชเดฏเตเดเตเดคเดพเดเตเดเตพเดเตเดเตเดณเตเดณ เดกเตเดฎเตเดฏเตเตป เดจเดพเดฎเด. เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต, เดฎเดฑเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจ เดเดฎเตเดฏเดฟเตฝ เดกเตเดฎเตเดฏเตเตป 'noreply.example.org' เดเดฏเดฟ เดธเดเตเดเตเดเดฐเดฟเดเตเดเดฟเดเตเดเตเดฃเตเดเตเดเตเดเดฟเตฝ 'joe' เดเดจเตเดจ เดเดชเดฏเตเดเตเดคเดพเดตเตเต 'joe@noreply.example.org' เดเดฏเดฟ เดฒเตเดเดฟเตป เดเตเดฏเตเดฏเตเด.
+
+[home]
+uname_holder=เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเดฎเต เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเดฎเต
+password_holder=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต
+switch_dashboard_context=เดกเดพเดทเตโเดฌเตเตผเดกเต เดธเดจเตเดฆเตผเดญเด เดฎเดพเดฑเตเดฑเตเด
+my_repos=เดเดฒเดตเดฑเดเดณเตโ
+show_more_repos=เดเตเดเตเดคเตฝ เดเดฒเดตเดฑเดเดณเตโ เดเดพเดฃเดฟเดเตเดเตเดโฆ
+collaborative_repos=เดธเดนเดเดฐเดฟเดเตเดเดพเดตเตเดจเตเดจ เดเดฒเดตเดฑเดเดณเตโ
+my_orgs=เดเดจเตเดฑเต เดธเดเดเดเดจเดเดณเตโ
+my_mirrors=เดเดจเตเดฑเต เดฎเดฟเดฑเดฑเตเดเดณเตโ
+view_home=%s เดเดพเดฃเตเด
+search_repos=เดเดฐเต เดเดฒเดตเดฑ เดเดฃเตเดเตเดคเตเดคเตเดโฆ
+
+
+
+issues.in_your_repos=เดจเดฟเดเตเดเดณเตเดเต เดเดฒเดตเดฑเดเดณเดฟเดฒเตโ
+
+[explore]
+repos=เดเดฒเดตเดฑเดเดณเตโ
+users=เดเดชเดฏเตเดพเดเตเดคเดพเดเตเดเดณเตโ
+organizations=เดธเดเดเดเดจเดเดณเตโ
+search=เดคเดฟเดฐเดฏเตเด
+code=เดเตเดกเต
+repo_no_results=เดชเตเดฐเตเดคเตเดคเดชเตเดชเตเดเตเดจเตเดจ เดเดฒเดตเดฑเดเดณเตเดจเตเดจเตเด เดเดฃเตเดเตเดคเตเดคเดพเดจเดพเดฏเดฟเดฒเตเดฒ.
+user_no_results=เดชเตเดฐเตเดคเตเดคเดชเตเดชเตเดเตเดจเตเดจ เดเดชเดฏเตเดเตเดคเดพเดเตเดเดณเตเดฏเตเดจเตเดจเตเด เดเดฃเตเดเตเดคเตเดคเดพเดจเดพเดฏเดฟเดฒเตเดฒ.
+org_no_results=เดชเตเดฐเตเดคเตเดคเดชเตเดชเตเดเตเดจเตเดจ เดธเดเดเดเดจเดเดณเตเดจเตเดจเตเด เดเดฃเตเดเตเดคเตเดคเดพเดจเดพเดฏเดฟเดฒเตเดฒ.
+code_no_results=เดจเดฟเดเตเดเดณเตเดเต เดคเดฟเดฐเดฏเตฝ เดชเดฆเดตเตเดฎเดพเดฏเดฟ เดชเตเดฐเตเดคเตเดคเดชเตเดชเตเดเตเดจเตเดจ เดธเตเดดเตเดธเต เดเตเดกเตเดเดณเตเดจเตเดจเตเด เดเดฃเตเดเตเดคเตเดคเดพเดจเดพเดฏเดฟเดฒเตเดฒ.
+code_search_results=%s เดเดจเตเดจเดคเดฟเดจเดพเดฏเตเดณเตเดณ เดคเดฟเดฐเดฏเตฝ เดซเดฒเดเตเดเตพ
+
+
+[auth]
+create_new_account=เด
เดเตเดเตเดฃเตเดเต เดฐเดเดฟเดธเตเดฑเตเดฑเตผ เดเตเดฏเตเดฏเตเด
+register_helper_msg=เดเดคเดฟเดจเดเด เดเดฐเต เด
เดเตเดเตเดฃเตเดเต เดเดฃเตเดเตเดพ? เดเดชเตเดชเตเตพ เดชเตเดฐเดตเตเดถเดฟเดเตเดเตเด!
+social_register_helper_msg=เดเดคเดฟเดจเดเด เดเดฐเต เด
เดเตเดเตเดฃเตเดเต เดเดฃเตเดเตเดพ? เดเดคเต เดเดชเตเดชเตเตพ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดฏเตเดเตเดเตเด!
+disable_register_prompt=เดฐเดเดฟเดธเตเดเตเดฐเตเดทเตป เด
เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเดฟ. เดจเดฟเดเตเดเดณเตเดเต เดธเตเดฑเตเดฑเต เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฑเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเด.
+disable_register_mail=เดฐเดเดฟเดธเตเดเตเดฐเตเดทเดจเดพเดฏเตเดณเตเดณ เดเดฎเตเดฏเดฟเตฝ เดธเตเดฅเดฟเดฐเตเดเดฐเดฃเด เด
เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเดฟ.
+forgot_password_title=เด
เดเดฏเดพเดณเดตเดพเดเตเดฏเด เดฎเดฑเดจเตเดจเตเดชเตเดฏเต
+forgot_password=เด
เดเดฏเดพเดณ เดตเดพเดเตเดเต เดเตผเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒเต?
+sign_up_now=เดเดฐเต เด
เดเตเดเตเดฃเตเดเต เดเดตเดถเตเดฏเดฎเตเดฃเตเดเต? เดเดชเตเดชเตเดพเดณเตโ เดฐเดเดฟเดธเตเดฑเตเดฑเดฐเตโ เดเตเดฏเตเดฏเตเด.
+sign_up_successful=เด
เดเตเดเตเดฃเตเดเต เดตเดฟเดเดฏเดเดฐเดฎเดพเดฏเดฟ เดธเตเดทเตเดเดฟเดเตเดเต.
+confirmation_mail_sent_prompt=%s เดฒเตเดเตเดเต เดเดฐเต เดชเตเดคเดฟเดฏ เดธเตเดฅเดฟเดฐเตเดเดฐเดฃ เดเดฎเตเดฏเดฟเตฝ เด
เดฏเดเตเดเต. เดฐเดเดฟเดธเตเดเตเดฐเตเดทเตป เดชเตเดฐเดเตเดฐเดฟเดฏ เดชเตเตผเดคเตเดคเดฟเดฏเดพเดเตเดเตเดจเตเดจเดคเดฟเดจเต เด
เดเตเดคเตเดค %s เดจเตเดณเตเดณเดฟเตฝ เดจเดฟเดเตเดเดณเตเดเต เดเตปโเดฌเตเดเตเดธเต เดชเดฐเดฟเดถเตเดงเดฟเดเตเดเตเด.
+must_change_password=เดจเดฟเดเตเดเดณเตเดเต เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต เดชเตเดคเตเดเตเดเตเด
+allow_password_change=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต เดฎเดพเดฑเตเดฑเดพเตป เดเดชเดฏเตเดเตเดคเดพเดตเดฟเดจเตเดเต เดเดตเดถเตเดฏเดชเตเดชเตเดเตเด (เดถเตเดชเดพเตผเดถเดฟเดคเด)
+reset_password_mail_sent_prompt=%s เดฒเตเดเตเดเต เดเดฐเต เดชเตเดคเดฟเดฏ เดธเตเดฅเดฟเดฐเตเดเดฐเดฃ เดเดฎเตเดฏเดฟเตฝ เด
เดฏเดเตเดเต. เด
เดเตเดเตเดฃเตเดเต เดตเตเดฃเตเดเตเดเตเดเตเดเตฝ เดชเตเดฐเดเตเดฐเดฟเดฏ เดชเตเตผเดคเตเดคเดฟเดฏเดพเดเตเดเตเดจเตเดจเดคเดฟเดจเต เด
เดเตเดคเตเดค %s เดจเตเดณเตเดณเดฟเตฝ เดจเดฟเดเตเดเดณเตเดเต เดเตปโเดฌเตเดเตเดธเต เดชเดฐเดฟเดถเตเดงเดฟเดเตเดเตเด.
+active_your_account=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต เดธเดเตเดตเดฎเดพเดเตเดเตเด
+account_activated=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต เดธเดเตเดตเดฎเดพเดเตเดเดฟ
+prohibit_login=เดชเตเดฐเดตเตเดถเดจเด เดจเดฟเดฐเตเดงเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต
+prohibit_login_desc=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเดฒเตเดฏเตเดเตเดเตเดณเตเดณ เดชเตเดฐเดตเตเดถเดจเด เดจเดฟเดฐเตเดงเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต, เดฆเดฏเดตเดพเดฏเดฟ เดจเดฟเดเตเดเดณเตเดเต เดธเตเดฑเตเดฑเต เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฑเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเด.
+resent_limit_prompt=เดจเดฟเดเตเดเตพ เด
เดเตเดคเตเดคเดฟเดเต เดเดฐเต เดธเดเตเดตเดฎเดพเดเตเดเตฝ เดเดฎเตเดฏเดฟเตฝ เด
เดญเตเดฏเตผเดคเตเดฅเดฟเดเตเดเต. 3 เดฎเดฟเดจเดฟเดฑเตเดฑเต เดเดพเดคเตเดคเดฟเดฐเตเดจเตเดจเต เดตเตเดฃเตเดเตเด เดถเตเดฐเดฎเดฟเดเตเดเตเด.
+has_unconfirmed_mail=เดนเดพเดฏเต %s, เดจเดฟเดเตเดเตพเดเตเดเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเดพเดคเตเดค เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด (%s ) เดเดฃเตเดเต. เดจเดฟเดเตเดเตพเดเตเดเต เดเดฐเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฃ เดเดฎเตเดฏเดฟเตฝ เดฒเดญเดฟเดเตเดเดฟเดฒเตเดฒเตเดเตเดเดฟเดฒเต เดชเตเดคเดฟเดฏเดคเตเดจเตเดจเต เดตเตเดฃเตเดเตเด เด
เดฏเดฏเตโเดเตเดเตเดฃเตเดเดคเตเดฃเตเดเตเดเตเดเดฟเดฒเต, เดเตเดตเดเตเดฏเตเดณเตเดณ เดฌเดเตเดเดฃเดฟเตฝ เดเตเดฒเดฟเดเตเดเตเดเตเดฏเตเดฏเตเด.
+resend_mail=เดจเดฟเดเตเดเดณเตเดเต เดธเดเตเดตเดฎเดพเดเตเดเตฝ เดเดฎเตเดฏเดฟเตฝ เดตเตเดฃเตเดเตเด เด
เดฏเดฏเตโเดเตเดเดพเตป เดเดตเดฟเดเต เดเตเดฒเดฟเดเตเดเตเดเตเดฏเตเดฏเตเด
+email_not_associate=เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดเดคเตเดเตเดเดฟเดฒเตเด เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเดคเตเดคเดฟเดฏเดฟเดเตเดเดฟเดฒเตเดฒ.
+send_reset_mail=เด
เดเตเดเตเดฃเตเดเต เดตเตเดฃเตเดเตเดเตเดเตเดเตฝ เดเดฎเตเดฏเดฟเตฝ เด
เดฏเดฏเตโเดเตเดเตเด
+reset_password=เด
เดเตเดเตเดฃเตเดเต เดตเตเดฃเตเดเตเดเตเดเตเดเตฝ
+invalid_code=เดจเดฟเดเตเดเดณเตเดเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฃ เดเตเดกเต เด
เดธเดพเดงเตเดตเดพเดฃเต เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดเดพเดฒเดนเดฐเดฃเดชเตเดชเตเดเตเดเต.
+reset_password_helper=เด
เดเตเดเตเดฃเตเดเต เดตเตเดฃเตเดเตเดเตเดเตเดเตเด
+reset_password_wrong_user=เดจเดฟเดเตเดเตพ %s เดเดฏเดฟ เดธเตเตป เดเตป เดเตเดฏเตโเดคเต, เดชเดเตเดทเต เด
เดเตเดเตเดฃเตเดเต เดตเตเดฃเตเดเตเดเตเดเตเดเตฝ เดฒเดฟเดเตเดเต %s เดเดจเตเดจเดคเดฟเดจเดพเดฃเต
+password_too_short=เดชเดพเดธเตโเดตเตเดกเต เดฆเตเตผเดเตเดฏเด %d เด
เดเตเดทเดฐเดเตเดเดณเดฟเดฒเตเด เดเตเดฑเดตเดพเดฏเดฟเดฐเดฟเดเตเดเดฐเตเดคเต.
+non_local_account=เดชเตเดฐเดพเดฆเตเดถเดฟเด เดเดคเดฐ เดเดชเดฏเตเดเตเดคเดพเดเตเดเตพเดเตเดเต เดเดฟเดฑเตเดฑเต เดตเตเดฌเต เดตเดดเดฟ เดชเดพเดธเตโเดตเตเดกเต เดชเตเดคเตเดเตเดเดพเดจเตโ เดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+verify=เดชเตเดฐเดฎเดพเดฃเตเดเดฐเดฟเดฏเตเดเตเดเตเด
+scratch_code=เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดกเต
+use_scratch_code=เดเดฐเต เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดกเต เดเดชเดฏเตเดเดฟเดเตเดเตเด
+twofa_scratch_used=เดจเดฟเดเตเดเดณเตเดเต เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดกเต เดเดชเดฏเตเดเดฟเดเตเดเต. เดจเดฟเดเตเดเดณเต เดฐเดฃเตเดเต-เดเดเด เดเตเดฐเดฎเตเดเดฐเดฃ เดชเตเดเดฟเดฒเตเดเตเดเต เดฑเตเดกเดฏเดฑเดเตโเดเต เดเตเดฏเตโเดคเดฟเดฐเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเดพเตฝ เดจเดฟเดเตเดเดณเตเดเต เดเดชเดเดฐเดฃ เดเตปเดฑเตเตพเดฎเตเดจเตเดฑเต เดจเตเดเตเดเดเดเตเดฏเตเดฏเดพเดจเต เดชเตเดคเดฟเดฏ เดธเตโเดเตเดฐเดพเดเตเดเต เดเตเดกเต เดธเตเดทเตโเดเดฟเดเตเดเดพเดจเต เดเดดเดฟเดฏเตเด.
+twofa_passcode_incorrect=เดจเดฟเดเตเดเดณเตเดเต เดชเดพเดธเตโเดเตเดกเต เดคเตเดฑเตเดฑเดพเดฃเต. เดจเดฟเดเตเดเดณเตเดเต เดเดชเดเดฐเดฃเด เดคเตเดฑเตเดฑเดพเดฏเดฟ เดธเตเดฅเดพเดชเดฟเดเตเดเดฟเดเตเดเตเดฃเตเดเตเดเตเดเดฟเตฝ, เดชเตเดฐเดตเตเดถเดฟเดเตเดเดพเตป เดจเดฟเดเตเดเดณเตเดเต เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดกเต เดเดชเดฏเตเดเดฟเดเตเดเตเด.
+twofa_scratch_token_incorrect=เดจเดฟเดเตเดเดณเตเดเต เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดกเต เดคเตเดฑเตเดฑเดพเดฃเต.
+login_userpass=เดชเตเดฐเดตเตเดถเดฟเดเตเดเตเด
+login_openid=OpenID
+oauth_signup_tab=เดชเตเดคเดฟเดฏ เด
เดเตเดเตเดฃเตเดเต เดฐเดเดฟเดธเตเดฑเตเดฑเตผ เดเตเดฏเตเดฏเตเด
+oauth_signup_submit=เด
เดเตเดเตเดฃเตเดเต เดชเตเตผเดคเตเดคเดฟเดฏเดพเดเตเดเตเด
+oauth_signin_tab=เดจเดฟเดฒเดตเดฟเดฒเตเดณเตเดณ เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดฏเตเดเตเดเตเด
+oauth_signin_title=เด
เดเตเดเตเดฃเตเดเต เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดฏเตเดเตเดเตเดจเตเดจเดคเตเต เด
เดเดเตเดเดฐเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเดพเดฏเดฟ เดธเตเดฑเตเดฑเดฟเดฒเตเดฏเตเดเตเดเตเต เดชเตเดฐเดตเตเดถเดฟเดเตเดเตเด
+oauth_signin_submit=เด
เดเตเดเตเดฃเตเดเต เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดฏเตเดเตเดเตเด
+openid_connect_submit=เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเตเด
+openid_connect_title=เดจเดฟเดฒเดตเดฟเดฒเตเดณเตเดณ เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดฏเตเดเตเดเตเด
+openid_connect_desc=เดคเดฟเดฐเดเตเดเตเดเตเดคเตเดค เดเดชเตเดชเตบเดเดกเดฟ เดฏเตเดเตผเด เด
เดเตเดเดพเดคเดฎเดพเดฃเต. เดเดตเดฟเดเต เดจเดฟเดจเตเดจเตเด เดเดฐเต เดชเตเดคเดฟเดฏ เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเดคเตเดคเตเด.
+openid_register_title=เด
เดเดเดคเตเดตเดฎเตเดเตเดเตเดเตเด
+openid_register_desc=เดคเดฟเดฐเดเตเดเตเดเตเดคเตเดค เดเดชเตเดชเตบเดเดกเดฟ เดฏเตเดเตผเด เด
เดเตเดเดพเดคเดฎเดพเดฃเต. เดเดตเดฟเดเต เดจเดฟเดจเตเดจเตเด เดเดฐเต เดชเตเดคเดฟเดฏ เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเดคเตเดคเตเด.
+openid_signin_desc=เดจเดฟเดเตเดเดณเตเดเต OpenID URI เดจเตฝเดเตเด. เดเดฆเดพเดนเดฐเดฃเดคเตเดคเดฟเดจเต: https://anne.me, bob.openid.org.cn เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ gnusocial.net/carry.
+email_domain_blacklisted=เดจเดฟเดเตเดเดณเตเดเต เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเดคเตเดคเดฟเตฝ เดฐเดเดฟเดธเตเดฑเตเดฑเตผ เดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+authorize_application=เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเต เด
เดเดเตเดเดพเดฐเด เดจเดฒเตเดเตเด
+authorize_application_created_by=%s เดธเตเดทเตโเดเดฟเดเตเด เด
เดชเตเดฒเดฟเดเตเดเตเดทเตป เดเดฃเต.
+authorize_application_description=เดจเดฟเดเตเดเตพ เดชเตเดฐเดตเตเดถเดจเด เด
เดจเตเดตเดฆเดฟเดเตเดเตเดเดฏเดพเดฃเตเดเตเดเดฟเตฝ, เดธเตเดตเดเดพเดฐเตเดฏ เดฑเดฟเดชเตเดชเตเดเดณเตเด เดเตผเดเดจเตเดธเตเดทเดจเตเดเดณเตเด เดเตพเดชเตเดชเตเดเต เดจเดฟเดเตเดเดณเตเดเต เดเดฒเตเดฒเดพ เด
เดเตเดเตเดฃเตเดเต เดตเดฟเดตเดฐเดเตเดเดณเตโ เดจเตเดเดพเดจเตเด เดตเตเดฃเดฎเตเดเตเดเดฟเดฒเตโโ เดฎเดพเดฑเตเดฑเดเตเดเดณเตโ เดตเดฐเตเดคเตเดคเดพเดจเตเด เด
เดคเดฟเดจเต เดเดดเดฟเดฏเตเด.
+authorize_title=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเดฒเตโ เดชเตเดฐเดตเตเดถเดฟเดฏเตเดเตเดเตเดจเตเดจเดคเดฟเดจเตเต "%s"เดจเตเต เด
เดเดเตเดเดพเดฐเด เดจเตฝเดเดฃเต?
+authorization_failed=เด
เดเดเตเดเดพเดฐเด เดจเดฒเตโเดเตเดจเตเดจเดคเดฟเดฒเตโ เดชเดฐเดพเดเดฏเดชเตเดชเตเดเตเดเต
+authorization_failed_desc=เด
เดธเดพเดงเตเดตเดพเดฏ เดเดฐเต เด
เดญเตเดฏเตผเดคเตเดฅเดจ เดเดฃเตเดเตเดคเตเดคเดฟเดฏเดคเดฟเดจเดพเตฝ เดเดเตเดเตพ เด
เดเดเตเดเดพเดฐเด เดชเดฐเดพเดเดฏเดชเตเดชเตเดเตเดคเตเดคเดฟ. เดฆเดฏเดตเดพเดฏเดฟ เดจเดฟเดเตเดเตพ เด
เดเดเตเดเดฐเดฟเดเตเดเดพเตป เดถเตเดฐเดฎเดฟเดเตเด เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดฑเต เดชเดฐเดฟเดชเดพเดฒเดเดจเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเด.
+
+[mail]
+activate_account=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต เดธเดเตเดตเดฎเดพเดเตเดเตเด
+
+activate_email=เดเดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดฏเตเดเตเดเตเด
+
+register_notify=เดเดฟเดฑเตเดฑเตเดฏเดฟเดฒเตเดฏเตเดเตเดเตเต เดธเตเดตเดพเดเดคเด
+
+reset_password=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต เดตเตเดฃเตเดเตเดเตเดเตเดเตเด
+
+register_success=เดฐเดเดฟเดธเตเดเตเดฐเตเดทเตป เดตเดฟเดเดฏเดเดฐเด
+
+
+
+
+
+
+
+[modal]
+yes=เด
เดคเต
+no=เดเดฒเตเดฒ
+modify=เดชเตเดคเตเดเตเดเตเด
+
+[form]
+UserName=เดเดชเดฏเตเดเตเดคเตเดฐเต เดจเดพเดฎเด
+RepoName=เดเดฒเดตเดฑเดฏเตเดเต เดชเตเดฐเตเต
+Email=เด-เดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด
+Password=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต
+Retype=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต เดตเตเดฃเตเดเตเด เดจเดฒเตโเดเตเด
+SSHTitle=SSH เดเตเดฏเตเดเต เดชเตเดฐเตเต
+HttpsUrl=HTTPS URL
+PayloadUrl=เดชเตเดฒเตเดกเต URL
+TeamName=เดเตเดฎเดฟเดจเตเดฑเต เดชเตเดฐเตเต
+AuthName=เด
เดเดเตเดเดพเดฐเดคเตเดคเดฟเดจเตเดฑเต เดชเตเดฐเตเต
+AdminEmail=เด
เดกเตโเดฎเดฟเตป เดเดฎเตเดฏเดฟเตฝ
+
+NewBranchName=เดชเตเดคเดฟเดฏ เดถเดพเดเดฏเตเดเต เดชเตเดฐเตเต
+CommitSummary=เดจเดฟเดฏเตเดพเดเดคเตเดคเดฟเดจเตเดฑเต เดธเดเดเตเดฐเดนเด
+CommitMessage=เดจเดฟเดฏเตเดพเดเดคเตเดคเดฟเดจเตเดฑเต เดธเดจเตเดฆเตเดถเด
+CommitChoice=เดจเดฟเดฏเตเดเดคเตเดคเดฟเดจเตเดฑเต เดคเดฟเดฐเดเตเดเตเดเตเดเตเดเดฒเตโ
+TreeName=เดซเดฏเดฒเตโ เดชเดพเดคเตเดคเต
+Content=เดเดณเตเดณเดเดเตเดเด
+
+
+require_error=`เดถเตเดจเตเดฏเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเดฐเตเดคเต.`
+alpha_dash_error=`เดเตฝโเดซเดพเดจเตเดฏเตเดฎเตเดฑเดฟเดเต, เดกเดพเดทเต ('-'), เด
เดเดฟเดตเดฐเดฏเดฟเดเตเด ('_') เดเดจเตเดจเต เดเดฟเดนเตเดจเดเตเดเดณเตโ เดฎเดพเดคเตเดฐเด เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเดฃเด.`
+alpha_dash_dot_error=`เดเตฝโเดซเดพเดจเตเดฏเตเดฎเตเดฑเดฟเดเต, เดกเดพเดทเต ('-'), เด
เดเดฟเดตเดฐเดฏเดฟเดเตเด ('_'), เดกเตเดเตเดเต ('.') เดเดจเตเดจเต เดเตเดนเตเดจเดเตเดเดณเตโ เดฎเดพเดคเตเดฐเด เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเดฃเด.`
+git_ref_name_error=`เดจเดจเตเดจเดพเดฏเดฟ เดฐเตเดชเดชเตเดชเตเดเตเดคเตเดคเดฟเดฏ Git เดฑเดซเดฑเตปเดธเต เดจเดพเดฎเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเดฃเด.`
+size_error=`เดตเดฒเตเดชเตเดชเด %s เดเดฏเดฟเดฐเดฟเดเตเดเดฃเด.`
+min_size_error=`เดเตเดฑเดเตเดเดคเต %s เด
เดเตเดทเดฐเดเตเดเดณเตโ เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเดฃเด.`
+max_size_error=`เดชเดฐเดฎเดพเดตเดงเดฟ %s เด
เดเตเดทเดฐเดเตเดเดณเตโ เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเดฃเด.`
+email_error=เดธเดพเดงเตเดตเดพเดฏ เดเดฐเต เด-เดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เด
เดฒเตเดฒ
+include_error=`%s'เดเดจเตเดจ เดเดชเดตเดพเดเตเดฏเด เด
เดเดเตเดเดฟเดฏเดฟเดฐเดฟเดเตเดเดฃเด.`
+glob_pattern_error=เดเตเดฒเตเดฌเตเต เดถเตเตเดฃเดฟ เดคเตเดฑเตเดฑเดพเดฃเตเต: %s
+unknown_error=เด
เดเตเดเดพเดคเดฎเดพเดฏ เดชเดฟเดถเดเต:
+captcha_incorrect=เดเตเดฏเดพเดชเตเด เดเตเดกเต เดคเตเดฑเตเดฑเดพเดฃเต.
+password_not_match=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเดเดณเตโ เดฏเตเดเดฟเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒ.
+
+username_been_taken=เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด เดฒเดญเตเดฏเดฎเดฒเตเดฒ.
+repo_name_been_taken=เดเดฒเดตเดฑเดฏเตเดเต เดชเตเดฐเตเต เดเดคเดฟเดจเตเดเดเด เดเดชเดฏเตเดเดฟเดเตเดเดฟเดเตเดเตเดฃเตเดเตเต.
+visit_rate_limit=เดตเดฟเดฆเตเดฐ เดตเดฟเดฒเดพเดธเด เดตเดฟเดตเดฐเดเตเดฎเดพเดฑเตเดฑเดคเตเดคเดฟเดจเตเต เดชเดฐเดฟเดงเดฟ เดจเดฟเดถเตเดเดฏเดฟเดเตเดเดฟเดเตเดเตเดฃเตเดเตเต.
+2fa_auth_required=เดตเดฟเดฆเตเดฐ เดตเดฟเดฒเดพเดธเด เดเดฐเดเตเด เดเดเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด เดเดตเดถเตเดฏเดชเตเดชเตเดเตเดจเตเดจเตเดฃเตเดเตเต.
+org_name_been_taken=เดธเดเดเดเดจเดฏเตเดเต เดชเตเดฐเต เดเดคเดฟเดจเดเด เดเดเตเดคเตเดคเดฟเดเตเดเตเดฃเตเดเต.
+team_name_been_taken=เดเตเดฎเดฟเดจเตเดฑเต เดชเตเดฐเต เดเดคเดฟเดจเดเด เดเดเตเดคเตเดคเดฟเดเตเดเตเดฃเตเดเต.
+team_no_units_error=เดเตเดฑเดเตเดเดคเต เดเดฐเต เดเดฒเดตเดฑ เดตเดฟเดญเดพเดเดคเตเดคเดฟเดฒเตเดเตเดเต เดชเตเดฐเดตเตเดถเดจเด เด
เดจเตเดตเดฆเดฟเดเตเดเตเด.
+email_been_used=เด เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดเดคเดฟเดจเต เดฎเตเดจเตเดจเต เดเดเตเดคเตเดคเดฟเดเตเดเตเดฃเตเดเต.
+openid_been_used=%s เดเดจเตเดจ เดเดชเตเดชเดฃเตโเดเดกเดฟ เดตเดฟเดฒเดพเดธเด เดเดคเดฟเดจเต เดฎเตเดจเตเดจเต เดเดเตเดคเตเดคเดฟเดเตเดเตเดฃเตเดเต.
+username_password_incorrect=เดเดชเดญเตเดเตเดคเตเดจเดพเดฎเดฎเต เดฐเดนเดธเตเดฏเดตเดพเดเตเดเต เดคเตเดฑเตเดฑเดพเดฃเต.
+enterred_invalid_repo_name=เด เดเดตเดตเดฑเดฏเตเดเต เดชเตเดฐเตเต เดคเตเดฑเตเดฑเดพเดฃเตเต.
+enterred_invalid_owner_name=เดชเตเดคเดฟเดฏ เดเดเดฎเดธเตเดฅเดจเตเดฑเต เดชเตเดฐเตเต เดธเดพเดงเตเดตเดฒเตเดฒ.
+enterred_invalid_password=เดคเดพเดเตเดเดณเตโ เดจเดฒเตโเดเดฟเดฏ เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต เดคเตเดฑเตเดฑเดพเดฃเต.
+user_not_exist=เดเดชเดฏเตเดเตเดคเดพเดตเต เดจเดฟเดฒเดตเดฟเดฒเดฟเดฒเตเดฒ.
+cannot_add_org_to_team=เดเดฐเต เดธเดเดเดเดจเดฏเต เดเตเด เด
เดเดเดฎเดพเดฏเดฟ เดเตเตผเดเตเดเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+
+invalid_ssh_key=เดจเดฟเดเตเดเดณเตเดเต SSH เดเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ: %s
+invalid_gpg_key=เดจเดฟเดเตเดเดณเตเดเต GPG เดเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ: %s
+unable_verify_ssh_key=SSH เดเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ; เดคเตเดฑเตเดฑเตเดเดณเตเดฃเตเดเตเดฏเตเดจเตเดจเตเต เดเดจเตเดจเตเดเตเดเดฟ เดชเดฐเดฟเดถเตเดงเดฟเดเตเดเตเด.
+auth_failed=เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด เดชเดฐเดพเดเดฏเดชเตเดชเตเดเตเดเต: %v
+
+still_own_repo=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเดจเต เดเดจเตเดจเต เด
เดคเดฟเดฒเดงเดฟเดเดฎเต เดเดฒเดตเดฑเดเดณเตโ เดเดฃเตเดเต; เดเดฆเตเดฏเด เด
เดต เดเดฒเตเดฒเดพเดคเดพเดเตเดเตเด เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดเตเดฎเดพเดฑเตเด.
+still_has_org=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต เดเดจเตเดจเต เด
เดคเดฟเดฒเดงเดฟเดเดฎเต เดธเดเดเดเดจเดเดณเดฟเดฒเตโ เด
เดเดเดฎเดพเดฃเต; เดเดฆเตเดฏเด เด
เดต เดตเดฟเดเตเด.
+org_still_own_repo=เดจเดฟเดเตเดเดณเตเดเต เดธเดเดเดเดจ เดเดจเดฟเดฏเตเด เดเดจเตเดจเต เด
เดคเดฟเดฒเดงเดฟเดเดฎเต เดเดฒเดตเดฑเดเดณเตเดเต เดเดเดฎเดธเตเดฅเดจเดพเดฃเตเต; เดเดฆเตเดฏเด เด
เดต เดเดฒเตเดฒเดพเดคเดพเดเตเดเตเด เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดเตเดฎเดพเดฑเตเด.
+
+target_branch_not_exist=เดฒเดเตเดทเตเดฏเดฎเดพเดเตเดเดฟเดฏ เดถเดพเด เดจเดฟเดฒเดตเดฟเดฒเดฟเดฒเตเดฒ.
+
+[user]
+change_avatar=เดจเดฟเดเตเดเดณเตเดเต เด
เดตเดคเดพเตผ เดฎเดพเดฑเตเดฑเตเดโฆ
+join_on=เดเตเตผเดจเตเดจเดคเตเต
+repositories=เดเดฒเดตเดฑเดเดณเตโ
+activity=เดชเตเดคเตเดตเดพเดฏ เดชเตเดฐเดตเตผเดคเตเดคเดจเดเตเดเดณเตโ
+followers=เดชเดฟเดจเตเดคเตเดเดฐเตเดจเตเดจเดตเดฐเตโโ
+starred=เดจเดเตเดทเดคเตเดฐเดฎเดฟเดเตเด เดเดฒเดตเดฑเดเดณเตโ
+following=เดชเดฟเดจเตเดคเตเดเดฐเตเดจเตเดจเดตเดฐเตโ
+follow=เดชเดฟเดจเตเดคเตเดเดฐเต
+unfollow=เดชเดฟเดจเตเดคเตเดเดฐเตเดจเตเดจเดคเต เดจเดฟเดฐเตโเดคเตเดคเตเด
+heatmap.loading=เดนเตเดฑเตเดฑเตเดฎเดพเดชเตเดชเต เดฒเตเดกเตเดเตเดฏเตเดฏเตเดจเตเดจเตโฆ
+user_bio=เดเตเดตเดเดฐเดฟเดคเตเดฐเด
+
+form.name_reserved='%s' เดเดจเตเดจ เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด เดฎเดฑเตเดฑเดพเดตเดถเตเดฏเดเตเดเดณเตโเดเตเดเดพเดฏเดฟ เดจเตเดเตเดเดฟเดตเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
+form.name_pattern_not_allowed=เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเดคเตเดคเดฟเตฝ '%s' เดเดจเตเดจ เดถเตเดฐเตเดฃเดฟ เด
เดจเตเดตเดฆเดจเตเดฏเดฎเดฒเตเดฒ.
+
+[settings]
+profile=เดชเตเดฐเตเดซเตเตฝ
+account=เด
เดเตเดเตเดฃเตเดเต
+password=เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต
+security=เดธเตเดฐเดเตเดท
+avatar=เด
เดตเดคเดพเดฐเตโ
+ssh_gpg_keys=SSH / GPG เดเตเดเดณเตโ
+social=เดธเตเดทเตเดฏเตฝ เด
เดเตเดเตเดฃเตเดเตเดเตพ
+applications=เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพ
+orgs=เดธเดเดเดเดจเดเดณเต เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+repos=เดเดฒเดตเดฑเดเดณเตโ
+delete=เด
เดเตเดเตเดฃเตเดเต เดเดฒเตเดฒเดพเดคเดพเดเตเดเตเด
+twofa=เดเดฐเดเตเด เดเดเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด
+account_link=เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเด เด
เดเตเดเตเดฃเตเดเตเดเดณเตโ
+organization=เดธเดเดเดเดจเดเดณเตโ
+uid=Uid
+
+public_profile=เดชเดฐเดธเตเดฏเดฎเดพเดฏ เดชเตเดฐเตเดซเตเตฝ
+profile_desc=เด
เดฑเดฟเดฏเดฟเดชเตเดชเตเดเตพเดเตเดเตเด เดฎเดฑเตเดฑเต เดชเตเดฐเดตเตผเดคเตเดคเดจเดเตเดเตพเดเตเดเตเดฎเดพเดฏเดฟ เดจเดฟเดเตเดเดณเตเดเต เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดเดชเดฏเตเดเดฟเดเตเดเตเด.
+password_username_disabled=เดชเตเดฐเดพเดฆเตเดถเดฟเดเดฎเดฒเตเดฒเดพเดคเตเดค เดเดชเดฏเตเดเตเดคเดพเดเตเดเตพเดเตเดเต เด
เดตเดฐเตเดเต เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด เดฎเดพเดฑเตเดฑเดพเตป เด
เดจเตเดตเดพเดฆเดฎเดฟเดฒเตเดฒ. เดเตเดเตเดคเตฝ เดตเดฟเดตเดฐเดเตเดเตพเดเตเดเต เดจเดฟเดเตเดเดณเตเดเต เดธเตเดฑเตเดฑเต เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเดฑเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเด.
+full_name=เดชเตเตผเดฃเตเดฃเดฎเดพเดฏ เดชเตเดฐเต
+website=เดตเตเดฌเต เดธเตเดฑเตเดฑเต
+location=เดธเตเดฅเดฒเด
+update_theme=เดชเตเดฐเดฎเตเดฏเด เดชเตเดคเตเดเตเดเตเด
+update_profile=เดชเตเดฐเตเดซเตเดฒเตโ เดชเดฐเดฟเดทเตเดเดฐเดฟเดเตเดเตเด
+update_profile_success=เดจเดฟเดเตเดเดณเตเดเต เดชเตเดฐเตเดพเดซเตเตฝ เดชเดฐเดฟเดทเตเดเดฐเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
+change_username=เดจเดฟเดเตเดเดณเตเดเต เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเด เดฎเดพเดฑเตเดฑเดฟ.
+change_username_prompt=เดเตเดฑเดฟเดชเตเดชเต: เดเดชเดฏเตเดเตเดคเตเดจเดพเดฎเดคเตเดคเดฟเดฒเต เดฎเดพเดฑเตเดฑเด เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต URLเดเด เดฎเดพเดฑเตเดฑเตเดจเตเดจเต.
+continue=เดคเตเดเดฐเตเด
+cancel=เดฑเดฆเตเดฆเดพเดเตเดเตเด
+language=เดญเดพเดท
+ui=เดชเตเดฐเดฎเตเดฏเดเตเดเดณเตโ
+
+lookup_avatar_by_mail=เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เด
เดจเตเดธเดฐเดฟเดเตเดเต เด
เดตเดคเดพเตผ เดเดฃเตเดเตเดคเตเดคเตเด
+federated_avatar_lookup=เดเตเดจเตเดฆเตเดฐเตเดเตเดฐเดค เด
เดตเดคเดพเดฐเตโ เดเดฃเตเดเตเดคเตเดคเดฒเตโ
+enable_custom_avatar=เดเดทเตโเดเดพเดจเตเดธเตเดค เด
เดตเดคเดพเตผ เดเดชเดฏเตเดเดฟเดเตเดเตเด
+choose_new_avatar=เดชเตเดคเดฟเดฏ เด
เดตเดคเดพเตผ เดคเดฟเดฐเดเตเดเตเดเตเดเตเดเตเด
+update_avatar=เด
เดตเดคเดพเตผ เดชเตเดคเตเดเตเดเตเด
+delete_current_avatar=เดจเดฟเดฒเดตเดฟเดฒเต เด
เดตเดคเดพเตผ เดเดฒเตเดฒเดพเดคเดพเดเตเดเตเด
+uploaded_avatar_not_a_image=เด
เดชเตโเดฒเตเดกเตเดเตเดฏเตโเดค เดซเดฏเตฝ เดเดฐเต เดเดฟเดคเตเดฐเดฎเดฒเตเดฒ.
+uploaded_avatar_is_too_big=เด
เดชเตโเดฒเตเดกเตเดเตเดฏเตโเดค เดซเดฏเตฝ เดชเดฐเดฎเดพเดตเดงเดฟ เดตเดฒเตเดชเตเดชเด เดเดตเดฟเดเตเดเต.
+update_avatar_success=เดจเดฟเดเตเดเดณเตเดเต เด
เดตเดคเดพเดฐเตโ เดชเดฐเดฟเดทเตเดเดฐเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
+
+change_password=เดชเดพเดธเตโเดตเตเดกเต เดชเตเดคเตเดเตเดเตเด
+old_password=เดจเดฟเดฒเดตเดฟเดฒเตเดณเตเดณ เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต
+new_password=เดชเตเดคเดฟเดฏ เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต
+retype_new_password=เดชเตเดคเดฟเดฏ เดฐเดนเดธเตเดฏเดตเดพเดเตเดเตเต เดตเตเดฃเตเดเตเด เดจเดฒเตโเดเตเด
+password_incorrect=เดจเดฟเดฒเดตเดฟเดฒเต เดชเดพเดธเตโเดตเตเดกเต เดคเตเดฑเตเดฑเดพเดฃเต.
+change_password_success=เดจเดฟเดเตเดเดณเตเดเต เดชเดพเดธเตโเดตเตเดกเต เด
เดชเตโเดกเตเดฑเตเดฑเตเดเตเดฏเตโเดคเต. เดเดจเดฟ เดฎเตเดคเตฝ เดจเดฟเดเตเดเดณเตเดเต เดชเตเดคเดฟเดฏ เดชเดพเดธเตโเดตเตเดกเต เดเดชเดฏเตเดเดฟเดเตเดเต เดชเตเดฐเดตเตเดถเดฟเดเตเดเตเด.
+password_change_disabled=เดชเตเดฐเดพเดฆเตเดถเดฟเด เดเดคเดฐ เดเดชเดฏเตเดเตเดคเดพเดเตเดเตพเดเตเดเต เดเดฟเดฑเตเดฑเต เดตเตเดฌเต เดตเดดเดฟ เดชเดพเดธเตโเดตเตเดกเต เดชเตเดคเตเดเตเดเดพเดจเตโ เดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+
+emails=เด-เดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเดเตเดเดณเตโ
+manage_emails=เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเดเตเดเตพ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+manage_themes=เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟ เดชเตเดฐเดฎเตเดฏเด เดคเดฟเดฐเดเตเดเตเดเตเดเตเดเตเด
+manage_openid=เดเดชเตเดชเตบเดเดกเดฟ เดตเดฟเดฒเดพเดธเดเตเดเตพ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+email_desc=เด
เดฑเดฟเดฏเดฟเดชเตเดชเตเดเตพเดเตเดเตเด เดฎเดฑเตเดฑเต เดชเตเดฐเดตเตผเดคเตเดคเดจเดเตเดเตพเดเตเดเตเดฎเดพเดฏเดฟ เดจเดฟเดเตเดเดณเตเดเต เดชเตเดฐเดพเดฅเดฎเดฟเด เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดเดชเดฏเตเดเดฟเดเตเดเตเด.
+theme_desc=เดธเตเดฑเตเดฑเดฟเดฒเตเดเดจเตเดณเด เดเดคเต เดจเดฟเดเตเดเดณเตเดเต เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟ เดชเตเดฐเดฎเตเดฏเด เดเดฏเดฟเดฐเดฟเดเตเดเตเด.
+primary=เดชเตเดฐเดพเดฅเดฎเดฟเดเด
+primary_email=เดชเตเดฐเดพเดฅเดฎเดฟเดเดฎเดพเดเตเดเตเด
+delete_email=เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+email_deletion=เด-เดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+email_deletion_desc=เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเดตเตเด เด
เดจเตเดฌเดจเตเดง เดตเดฟเดตเดฐเดเตเดเดณเตเด เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเตฝ เดจเดฟเดจเตเดจเต เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเด. เด เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดตเดดเดฟเดฏเตเดณเตเดณ เดเดฟเดฑเตเดฑเตเต เดจเดฟเดฏเตเดพเดเดเตเดเดณเตเด เดฎเดพเดฑเตเดฑเดฎเดฟเดฒเตเดฒเดพเดคเต เดเดฃเตเดเดพเดเตเด. เดคเตเดเดฐเดเตเดเต?
+email_deletion_success=เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดจเตเดเตเดเดเดเตเดฏเตโเดคเต.
+theme_update_success=เดจเดฟเดเตเดเดณเตเดเต เดชเตเดฐเดฎเตเดฏเด เดชเตเดคเตเดเตเดเดฟ.
+theme_update_error=เดคเดฟเดฐเดเตเดเตเดเตเดคเตเดค เดชเตเดฐเดฎเตเดฏเด เดจเดฟเดฒเดตเดฟเดฒเดฟเดฒเตเดฒ.
+openid_deletion=OpenID เดตเดฟเดฒเดพเดธเด เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+openid_deletion_desc=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเตฝ เดจเดฟเดจเตเดจเต เดเดชเตเดชเตบเดเดกเดฟ เดตเดฟเดฒเดพเดธเด เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเดจเตเดจเดคเต เดเดคเตเดชเดฏเตเดเดฟเดเตเดเตเต เดเดจเดฟ เดชเตเดฐเดตเตเดถเดฟเดเตเดเตเดจเตเดจเดคเดฟเตฝ เดจเดฟเดจเตเดจเต เดจเดฟเดเตเดเดณเต เดคเดเดฏเตเด. เดคเตเดเดฐเดเตเดเต?
+openid_deletion_success=เดเดชเตเดชเตบเดเดกเดฟ เดตเดฟเดฒเดพเดธเด เดจเตเดเตเดเดเดเตเดฏเตโเดคเต.
+add_new_email=เด-เดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด เดเตเดฐเตโเดเตเดเตเด
+add_new_openid=เดชเตเดคเดฟเดฏ เดเดชเตเดชเดฃเตโ เดเดกเดฟ เดตเดฟเดฒเดพเดธเด เดเตเดฐเตโเดเตเดเตเด
+add_email=เด-เดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด เดเตเดฐเตโเดเตเดเตเด
+add_openid=เดเดชเตเดชเดฃเตโ เดเดกเดฟ เดตเดฟเดฒเดพเดธเด เดเตเดฐเตโเดเตเดเตเด
+add_email_confirmation_sent=เดเดฐเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฃ เดเดฎเตเดฏเดฟเตฝ '%s' เดฒเตเดเตเดเต เด
เดฏเดเตเดเต. เดจเดฟเดเตเดเดณเตเดเต เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเต เด
เดเตเดคเตเดค %s เดจเตเดณเตเดณเดฟเตฝ เดจเดฟเดเตเดเดณเตเดเต เดเตปโเดฌเตเดเตเดธเต เดชเดฐเดฟเดถเตเดงเดฟเดเตเดเตเด.
+add_email_success=เดชเตเดคเดฟเดฏ เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดเตเดฐเตโเดคเตเดคเต.
+add_openid_success=เดชเตเดคเดฟเดฏ เดเดชเตเดชเดฃเตโเดเดกเดฟ เดตเดฟเดฒเดพเดธเด เดเตเดฐเตโเดคเตเดคเต.
+keep_email_private=เด-เดฎเตเดฏเดฟเดฒเตโ เดตเดฟเดฒเดพเดธเด เดฎเดฑเดฏเตเดเตเดเตเด
+keep_email_private_popup=เดจเดฟเดเตเดเดณเตเดเต เดเดฎเตเดฏเดฟเตฝ เดตเดฟเดฒเดพเดธเด เดฎเดฑเตเดฑเต เดเดชเดฏเตเดเตเดคเดพเดเตเดเตเต เดเดพเดฃเดพเดจเดพเดเดฟเดฒเตเดฒ.
+openid_desc=เดเดฐเต เดฌเดพเดนเตเดฏ เดฆเดพเดคเดพเดตเดฟเดจเต เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด เดจเดฟเดฏเตเดเตเดคเดฎเดพเดเตเดเดพเตป เดเดชเตเดชเตบเดเดกเดฟ เดจเดฟเดเตเดเดณเต เด
เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจเต.
+
+manage_ssh_keys=โเดเดธเต. เดเดธเต. เดเดเตเดเต เดเตเดเดณเตโ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+manage_gpg_keys=เดเต เดชเต. เดเดฟ เดเตเดเดณเตโ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+add_key=เดเต เดเตเดฐเตโเดเตเดเตเด
+ssh_desc=เดเดตเดฏเดพเดฃเตเต เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเดคเตเดคเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจ เดชเตเดคเตเดตเดพเดฏ เดเดธเต. เดเดธเต. เดเดเตเดเต เดเตเดเตพ. เดเดคเดฟเดจเตเดเดจเต เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเดฟเดเตเดเตเดณเตเดณ เดธเตเดตเดเดพเดฐเตเดฏ เดเตเดเตพ เดจเดฟเดเตเดเดณเตเดเต เดเดฒเดตเดฑเดเดณเดฟเดฒเตเดฏเตเดเตเดเตเต เดชเตเตผเดฃเตเดฃ เดเดเตเดธเดธเต เด
เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจเต.
+gpg_desc=เด เดชเตเดคเต GPG เดเตเดเตพ เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต. เดเดฎเตเดฎเดฟเดฑเตเดฑเตเดเดณเต เดชเดฐเดฟเดถเตเดงเดฟเดเตเดเตเดฑเดชเตเดชเดฟเดเตเดเดพเตป เดจเดฟเดเตเดเดณเตเดเต เดธเตเดตเดเดพเดฐเตเดฏ เดเตเดเตพ เด
เดจเตเดตเดฆเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเดพเตฝ เด
เดต เดธเตเดฐเดเตเดทเดฟเดคเดฎเดพเดฏเดฟ เดธเตเดเตเดทเดฟเดเตเดเตเด.
+ssh_helper=เดธเดนเดพเดฏเด เดเดตเดถเตเดฏเดฎเตเดฃเตเดเต? เดจเดฟเดเตเดเดณเตเดเต เดธเตเดตเดจเตเดคเด SSH เดเตเดเตพ เดธเตเดทเตเดเดฟเดเตเดเตเด, เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดชเตเดคเตเดตเดพเดฏ เดชเตเดฐเดถเตเดจเดเตเดเตพ เดเดจเตเดจเดฟเดตเดฏเตเดเตเดเดพเดฏเตเดณเตเดณ เดเดฟเดฑเตเดฑเตเดนเดฌเตเดฌเดฟเดจเตเดฑเต เดฎเดพเดฐเตโเดเดฆเดฐเตโเดถเดจเดเตเดเดณเตโ เดเดชเดฏเตเดเดฟเดเตเดเตเต เดจเดฟเดเตเดเตพเดเตเดเต เดเดธเต. เดเดธเต. เดเดเตเดเตเดฎเดพเดฏเดฟ เดฌเดจเตเดงเดชเตเดชเตเดเตเด เดชเตเดฐเดถเตเดจเดเตเดเดณเตโ เดชเดฐเดฟเดนเดฐเดฟเดเตเดเดพเด.
+gpg_helper= เดธเดนเดพเดฏเด เดเดตเดถเตเดฏเดฎเตเดฃเตเดเต? เดเดฟเดชเดฟเดเดฟเดฏเตเดเตเดเตเดฑเดฟเดเตเดเต เดเดฟเดฑเตเดฑเตเดนเดฌเดฟเดจเตเดฑเต เดฎเดพเดฐเตโเดเตเดเดจเดฟเดฐเตโเดฆเตเดฆเตเดถเดเตเดเดณเตโ เดชเดฐเดฟเดถเตเดงเดฟเดฏเตเดเตเดเตเด .
+add_new_key=SSH เดเต เดเตเตผเดเตเดเตเด
+add_new_gpg_key=GPG เดเต เดเตเตผเดเตเดเตเด
+ssh_key_been_used=เด SSH เดเต เดเดคเดฟเดจเดเด เดเตเตผเดคเตเดคเต.
+gpg_key_id_used=เดธเดฎเดพเดจ เดเดกเดฟเดฏเตเดณเตเดณ เดเดฐเต เดชเตเดคเต เดเดฟเดชเดฟเดเดฟ เดเต เดเดคเดฟเดจเดเด เดจเดฟเดฒเดตเดฟเดฒเตเดฃเตเดเต.
+subkeys=เดธเดฌเต เดเตเดเดณเตโ
+key_id=เดเต เดเดกเดฟ
+key_name=เดเตเดฏเตเดเต เดชเตเดฐเตเต
+key_content=เดเดณเตเดณเดเดเตเดเด
+add_key_success='%s' เดเดจเตเดจ SSH เดเต เดเตเตผเดคเตเดคเต.
+add_gpg_key_success='%s' เดเดจเตเดจ GPG เดเต เดเตเตผเดคเตเดคเต.
+delete_key=เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+ssh_key_deletion=SSH เดเต เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+gpg_key_deletion=GPG เดเต เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+ssh_key_deletion_desc=เดเดฐเต SSH เดเต เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเดจเตเดจเดคเต เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเดฒเตเดเตเดเตเดณเตเดณ เดชเตเดฐเดตเตเดถเดจเด เด
เดธเดพเดงเตเดตเดพเดเตเดเตเดจเตเดจเต. เดคเตเดเดฐเดเตเดเต?
+gpg_key_deletion_desc=เดเดฐเต เดเดฟโเดชเดฟโเดเดฟ เดเต เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเดจเตเดจเดคเต เด
เดคเดฟเตฝ เดเดชเตเดชเดฟเดเตเด เดเดฎเตเดฎเดฟเดฑเตเดฑเตเดเดณเต เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเดฟเดฒเตเดฒ. เดคเตเดเดฐเดเตเดเต?
+ssh_key_deletion_success=SSH เดเต เดจเตเดเตเดเดเดเตเดฏเตโเดคเต.
+gpg_key_deletion_success=GPG เดเต เดจเตเดเตเดเดเดเตเดฏเตโเดคเต.
+add_on=เดเตเดฐเตโเดคเตเดคเดคเตเต
+valid_until=เดตเดฐเต เดธเดพเดงเตเดตเดพเดฃเต
+valid_forever=เดเดจเตเดจเตเด เดธเดพเดงเตเดตเดพเดฃเตเต
+last_used=เด
เดตเดธเดพเดจเด เดเดชเดฏเตเดเดฟเดเตเดเดคเต
+no_activity=เดธเดฎเตเดชเดเดพเดฒเดคเตเดคเตเต เดชเตเดฐเดตเตผเดคเตเดคเดจเดเตเดเดณเตเดจเตเดจเตเดฎเดฟเดฒเตเดฒ
+can_read_info=เดตเดพเดฏเดฟเดฏเตเดเตเดเตเด
+can_write_info=เดเดดเตเดคเตเด
+key_state_desc=เดเดดเดฟเดเตเด 7 เดฆเดฟเดตเดธเดเตเดเดณเดฟเตฝ เด เดเต เดเดชเดฏเตเดเดฟเดเตเดเต
+token_state_desc=เด เดเตเดเตเดเตบ เดเดดเดฟเดเตเด 7 เดฆเดฟเดตเดธเดเตเดเดณเดฟเตฝ เดเดชเดฏเตเดเดฟเดเตเดเต
+show_openid=เดชเตเดฐเตเดซเตเดฒเดฟเตฝ เดเดพเดฃเตเด
+hide_openid=เดชเตเดฐเตเดซเตเดฒเดฟเตฝ เดจเดฟเดจเตเดจเต เดฎเดฑเดฏเตโเดเตเดเตเด
+ssh_disabled=SSH เด
เดชเตเดฐเดพเดชเตโเดคเดฎเดพเดเตเดเดฟ
+manage_social=เดธเดนเดตเดธเดฟเดเตเดเตเดจเตเดจ เดธเตเดทเตเดฏเตฝ เด
เดเตเดเตเดฃเตเดเตเดเดณเต เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+social_desc=เด เดธเตเดทเตเดฏเตฝ เด
เดเตเดเตเดฃเตเดเตเดเตพ เดจเดฟเดเตเดเดณเตเดเต เดเดฟเดฑเตเดฑเต เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดฒเดฟเดเตเดเตเดเตเดฏเตโเดคเต. เดเดต เดจเดฟเดเตเดเดณเตเดเต เดเตเดฑเตเดฑเต เด
เดเตเดเตเดฃเตเดเดฟเดฒเตเดเตเดเต เดชเตเดฐเดตเตเดถเดฟเดเตเดเดพเตป เดเดชเดฏเตเดเดฟเดเตเดเดพเดตเตเดจเตเดจเดคเดฟเดจเดพเตฝ เด
เดตเดฏเตเดฒเตเดฒเดพเด เดจเดฟเดเตเดเตพ เดคเดฟเดฐเดฟเดเตเดเดฑเดฟเดเตเดเตเดตเตเดจเตเดจเต เดเดฑเดชเตเดชเดพเดเตเดเตเด.
+unbind=เด
เตบเดฒเดฟเดเตเดเต เดเตเดฏเตเดฏเตเด
+unbind_success=เดจเดฟเดเตเดเดณเตเดเต เดเตเดฑเตเดฑเต เด
เดเตเดเตเดฃเตเดเดฟเตฝ เดจเดฟเดจเตเดจเต เดธเตเดทเตเดฏเตฝ เด
เดเตเดเตเดฃเตเดเต เด
เตบเดฒเดฟเดเตเดเต เดเตเดฏเตเดคเต.
+
+manage_access_token=เดเดเตโเดธเดธเตเดธเต เดเตเดเตเดเดฃเตเดเตพ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+generate_new_token=เดชเตเดคเดฟเดฏ เดเตเดเตเดเตบ เดธเตเดทเตโเดเดฟเดเตเดเตเด
+tokens_desc=เด เดเตเดเตเดเดฃเตเดเตพ เดเดฟเดฑเตเดฑเต API เดเดชเดฏเตเดเดฟเดเตเดเต เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเดฒเตเดเตเดเต เดชเตเดฐเดตเตเดถเดจเด เดจเตฝเดเตเดจเตเดจเต.
+new_token_desc=เดเดฐเต เดเตเดเตเดเตบ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจ เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพเดเตเดเต เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเดฒเตเดเตเดเต เดชเตเตผเดฃเตเดฃ เดชเตเดฐเดตเตเดถเดจเด เดเดฃเตเดเต.
+token_name=เดเตเดเตเดเดฃเดฟเดจเตเดฑเต เดชเตเดฐเตเต
+generate_token=เดเตเดเตเดเตบ เดธเตเดทเตโเดเดฟเดเตเดเตเด
+generate_token_success=เดจเดฟเดเตเดเดณเตเดเต เดชเตเดคเดฟเดฏ เดเตเดเตเดเตบ เดเดจเดฑเตเดฑเตเดฑเตเดเตเดฏเตโเดคเต. เดเดคเต เดตเตเดฃเตเดเตเด เดเดพเดฃเดฟเดเตเดเดพเดคเตเดคเดคเดฟเดจเดพเตฝ เดเดชเตเดชเตเตพ เดคเดจเตเดจเต เดชเดเตผเดคเตเดคเตเด.
+delete_token=เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+access_token_deletion=เดเดเตโเดธเดธเตเดธเต เดเตเดเตเดเดฃเตโ เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+delete_token_success=เดเตเดเตเดเตบ เดเดฒเตเดฒเดพเดคเดพเดเตเดเดฟ. เดเดจเดฟ เดเดคเต เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจ เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพเดเตเดเต เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเดฒเตเดเตเดเต เดชเตเดฐเดตเตเดถเดจเด เดเดฃเตเดเดพเดเดฟเดฒเตเดฒ.
+
+manage_oauth2_applications=OAuth2 เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+edit_oauth2_application=OAuth2 เด
เดชเตเดฒเดฟเดเตเดเตเดทเตป เดเดกเดฟเดฑเตเดฑเตเดเตเดฏเตเดฏเตเด
+oauth2_applications_desc=เดจเดฟเดเตเดเดณเตเดเต เดฎเตเดจเตเดจเดพเด เดเดเตเดทเดฟ เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเต, เด เดเดฟเดฑเตเดฑเต เดเดจเตโเดธเตเดฑเตเดฑเดพเดณเตเดทเดจเตเดฎเดพเดฏเดฟ เดธเตเดฐเดเตเดทเดฟเดคเดฎเดพเดฏเดฟ เดเดชเดฏเตเดเตเดคเดพเดเตเดเดณเต เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฟเดเตเดเดพเตป OAuth2 เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพ เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเดจเตเดจเต.
+remove_oauth2_application=OAuth2 เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพ เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเด
+remove_oauth2_application_desc=เดเดฐเต OAuth2 เด
เดชเตเดฒเดฟเดเตเดเตเดทเตป เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเดจเตเดจเดคเต เดเดชเตเดชเดฟเดเตเด เดเดฒเตเดฒเดพ เดเดเตเดธเดธเต เดเตเดเตเดเดฃเตเดเดณเดฟเดฒเตเดเตเดเตเด เดชเตเดฐเดตเตเดถเดจเด เดฑเดฆเตเดฆเดพเดเตเดเตเด. เดคเตเดเดฐเดเตเดเต?
+remove_oauth2_application_success=เด
เดชเตเดฒเดฟเดเตเดเตเดทเตป เดเดฒเตเดฒเดพเดคเดพเดเตเดเดฟ.
+create_oauth2_application=เดเดฐเต เดชเตเดคเดฟเดฏ OAuth2 เด
เดชเตเดฒเดฟเดเตเดเตเดทเตป เดธเตเดทเตเดเดฟเดเตเดเตเด
+create_oauth2_application_button=เด
เดชเตเดฒเดฟเดเตเดเตเดทเตป เดธเตเดทเตเดเดฟเดเตเดเตเด
+create_oauth2_application_success=เดจเดฟเดเตเดเตพ เดตเดฟเดเดฏเดเดฐเดฎเดพเดฏเดฟ เดเดฐเต เดชเตเดคเดฟเดฏ OAuth2 เด
เดชเตเดฒเดฟเดเตเดเตเดทเตป เดธเตเดทเตเดเดฟเดเตเดเต.
+update_oauth2_application_success=เดจเดฟเดเตเดเตพ เดตเดฟเดเดฏเดเดฐเดฎเดพเดฏเดฟ เดเดฐเต เดชเตเดคเดฟเดฏ OAuth2 เด
เดชเตเดฒเดฟเดเตเดเตเดทเตป เดชเตเดคเตเดเตเดเดฟ.
+oauth2_application_name=เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดฑเต เดชเตเดฐเต
+oauth2_redirect_uri=URI เดฑเตเดกเดฏเดฑเดเตโเดเต เดเตเดฏเตเดฏเตเด
+save_application=เดธเดเดฐเดเตเดทเดฟเดฏเตเดเตเดเตเด
+oauth2_client_id=เดเตเดฒเตเดจเตเดฑเต เดเดกเดฟ
+oauth2_client_secret=เดเตเดฒเตเดจเตเดฑเตเต เดฐเดนเดธเตเดฏเด
+oauth2_regenerate_secret=เดฐเดนเดธเตเดฏเด เดชเตเดจเดเดธเตเดทเตเดเดฟเดฏเตเดเตเดเตเด
+oauth2_regenerate_secret_hint=เดจเดฟเดเตเดเดณเตเดเต เดฐเดนเดธเตเดฏเด เดจเดทเตเดเดชเตเดชเตเดเตเดเต?
+oauth2_client_secret_hint=เดจเดฟเดเตเดเตพ เด เดชเตเดเต เดตเตเดฃเตเดเตเด เดธเดจเตเดฆเตผเดถเดฟเดเตเดเตเดเดฏเดพเดฃเตเดเตเดเดฟเตฝ เดฐเดนเดธเตเดฏเด เดฆเตเดถเตเดฏเดฎเดพเดเดฟเดฒเตเดฒ. เดจเดฟเดเตเดเดณเตเดเต เดฐเดนเดธเตเดฏเด เดธเดเดฐเดเตเดทเดฟเดเตเดเตเด.
+oauth2_application_edit=เดเตเดฐเดฎเตเดเดฐเดฟเดเตเดเตเด
+oauth2_application_create_description=OAuth2 เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพ เดจเดฟเดเตเดเดณเตเดเต เดฎเตเดจเตเดจเดพเด เดเดเตเดทเดฟ เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเดชเดฏเตเดเตเดคเต เด
เดเตเดเตเดฃเตเดเตเดเดณเดฟเดฒเตเดเตเดเต เดเดเตเดธเดธเต เดจเตฝเดเตเดจเตเดจเต.
+oauth2_application_remove_description=เดเดฐเต OAuth2 เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเดจเตเดจเดคเต เด เดธเดจเตเดฆเตผเดญเดคเตเดคเดฟเตฝ เด
เดเดเตเดเตเดค เดเดชเดฏเตเดเตเดคเต เด
เดเตเดเตเดฃเตเดเตเดเดณเดฟเดฒเตเดเตเดเต เดชเตเดฐเดตเตเดถเดฟเดเตเดเตเดจเตเดจเดคเต เดคเดเดฏเตเด. เดคเตเดเดฐเดเตเดเต?
+
+authorized_oauth2_applications=เด
เดเดเตเดเตเดค OAuth2 เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพ
+authorized_oauth2_applications_description=เด เดฎเตเดจเตเดจเดพเด เดเดเตเดทเดฟ เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเดณเดฟเดฒเตเดเตเดเต เดจเดฟเดเตเดเดณเตเดเต เดธเตเดตเดเดพเดฐเตเดฏ เดเตเดฑเตเดฑเต เด
เดเตเดเตเดฃเตเดเดฟเดฒเตเดเตเดเต เดชเตเดฐเดตเตเดถเดจเด เด
เดจเตเดตเดฆเดฟเดเตเดเต. เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเตเดเตพเดเตเดเดพเดฏเตเดณเตเดณ เดจเดฟเดฏเดจเตเดคเตเดฐเดฃเด เดเดจเดฟ เดเดตเดถเตเดฏเดฎเดฟเดฒเตเดฒ.
+revoke_key=เด
เดธเดพเดงเตเดตเดพเดเตเดเตเด
+revoke_oauth2_grant=เดจเดฟเดฏเดจเตเดคเตเดฐเดฃเด เดคเดฟเดฐเดฟเดเตเดเตเดเตเดเตเดเตเด
+revoke_oauth2_grant_description=เด เดฎเตเดจเตเดจเดพเด เดเดเตเดทเดฟ เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเดพเดฏเดฟ เดเดเตเดธเดธเต เด
เดธเดพเดงเตเดตเดพเดเตเดเตเดจเตเดจเดคเต เดจเดฟเดเตเดเดณเตเดเต เดกเดพเดฑเตเดฑ เดเดเตเดธเดธเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเตฝ เดจเดฟเดจเตเดจเต เด เดเดชเตเดฒเดฟเดเตเดเตเดทเดจเต เดคเดเดฏเตเด. เดจเดฟเดเตเดเดณเตโเดเตเดเต เดเดฑเดชเตเดชเดพเดฃเตเดพ?
+revoke_oauth2_grant_success=เดจเดฟเดเตเดเตพ เดตเดฟเดเดฏเดเดฐเดฎเดพเดฏเดฟ เดชเตเดฐเดตเตเดถเดจเด เดฑเดฆเตเดฆเดพเดเตเดเดฟ.
+
+twofa_desc=เดเดฐเดเตเด เดเดเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเดฟเดจเตเดฑเต เดธเตเดฐเดเตเดท เดตเตผเดฆเตเดงเดฟเดชเตเดชเดฟเดเตเดเตเดจเตเดจเต.
+twofa_is_enrolled=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต เดจเดฟเดฒเดตเดฟเตฝ เดเดฐเดเตเด เดเดเด เดชเตเดฐเดฎเดพเดฃเตเดเดฐเดฃเดคเตเดคเดฟเดจเตเต เดเตปเดฑเตเตพ เดเตเดฏเตเดคเดฟเดเตเดเตเดฃเตเดเต. .
+twofa_not_enrolled=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต เดจเดฟเดฒเดตเดฟเตฝ เดเดฐเดเตเด เดเดเด เดชเตเดฐเดฎเดพเดฃเตเดเดฐเดฃเดคเตเดคเดฟเดจเตเต เดเตปเดฑเตเตพ เดเตเดฏเตเดคเดฟเดเตเดเดฟเดฒเตเดฒ. .
+twofa_disable=เดเดฐเดเตเด เดเดเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด เดฑเดฆเตเดฆเดพเดเตเดเดฟ
+twofa_scratch_token_regenerate=เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดเตเดเตบ เดชเตเดจเดเดจเดฟเดฐเตโเดฎเตเดฎเดฟเดฏเตเดเตเดเตเด
+twofa_scratch_token_regenerated=%s เดเดฃเต เดเดชเตเดชเตเตพ เดจเดฟเดเตเดเดณเตเดเต เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดเตเดเตบ. เดธเตเดฐเดเตเดทเดฟเดคเดฎเดพเดฏ เดธเตเดฅเดฒเดคเตเดคเต เดธเตเดเตเดทเดฟเดเตเดเตเด.
+twofa_enroll=เดเดฐเดเตเด เดเดเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเดคเตเดคเดฟเดฒเตโ เด
เดเดเดฎเดพเดเตเด
+twofa_disable_note=เดเดตเดถเตเดฏเดฎเตเดเตเดเดฟเตฝ เดจเดฟเดเตเดเตพเดเตเดเต เดฐเดฃเตเดเต-เดเดเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด เด
เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเดพเตป เดเดดเดฟเดฏเตเด.
+twofa_disable_desc=เดฐเดฃเตเดเต-เดเดเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด เด
เดชเตเดฐเดพเดชเตโเดคเดฎเดพเดเตเดเตเดจเตเดจเดคเต เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต เดธเตเดฐเดเตเดทเดฟเดคเดฎเดฒเตเดฒเดพเดคเตเดคเดคเดพเดเตเดเตเด. เดคเตเดเดฐเดเตเดเต?
+regenerate_scratch_token_desc=เดจเดฟเดเตเดเดณเตเดเต เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดเตเดเตบ เดคเตเดฑเตเดฑเดพเดฏเดฟ เดธเตเดฅเดพเดชเดฟเดเตเดเตเดเดฏเต เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดธเตเตป เดเตป เดเตเดฏเตเดฏเดพเตป เดเดคเดฟเดจเดเด เดเดชเดฏเตเดเดฟเดเตเดเตเดเดฏเต เดเตเดฏเตเดคเดฟเดเตเดเตเดฃเตเดเตเดเตเดเดฟเตฝ เด
เดคเต เดเดตเดฟเดเตเดจเดฟเดจเตเดจเตเต เดชเตเดจเดเดธเดเตเดเดฎเดพเดเตเดเดพเตป เดเดดเดฟเดฏเตเด.
+twofa_disabled=เดฐเดฃเตเดเต-เดเดเตเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเด เด
เดชเตเดฐเดพเดชเตโเดคเดฎเดพเดเตเดเดฟ.
+scan_this_image=เดจเดฟเดเตเดเดณเตเดเต เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃ เดเดชเตเดฒเดฟเดเตเดเตเดทเตป เดเดชเดฏเตเดเดฟเดเตเดเต เด เดเดฟเดคเตเดฐเด เดธเตเดเตเดทเตโเดฎเดชเดฐเดฟเดถเตเดพเดงเดจ เดจเดเดคเตเดคเตเด:
+or_enter_secret=เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดฐเดนเดธเตเดฏ เดเตเดกเต เดจเตฝเดเตเด: %s
+then_enter_passcode=เด
เดชเตเดฒเดฟเดเตเดเตเดทเดจเดฟเตฝ เดเดพเดฃเดฟเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจ เดชเดพเดธเตโเดเตเดกเต เดจเตฝเดเตเด:
+passcode_invalid=เดชเดพเดธเตโเดเตเดกเต เดคเตเดฑเตเดฑเดพเดฃเต. เดตเตเดฃเตเดเตเด เดถเตเดฐเดฎเดฟเดเตเดเตเด.
+twofa_enrolled=เดจเดฟเดเตเดเดณเตเดเต เด
เดเตเดเตเดฃเตเดเต เดฐเดฃเตเดเต-เดเดเตเด เดชเตเดฐเดพเดฎเดพเดฃเตเดเดฐเดฃเดคเตเดคเดฟเดฒเตเดเตเดเต เดเตเตผเดคเตเดคเดฟเดเตเดเตเดฃเตเดเต. เดจเดฟเดเตเดเดณเตเดเต เดธเตเดเตเดฐเดพเดเตเดเต เดเตเดเตเดเตบ (%s) เดเดฐเต เดคเดตเดฃ เดฎเดพเดคเตเดฐเด เดเดพเดฃเดฟเดเตเดเตเดจเตเดจเดคเดฟเดจเดพเตฝ เด
เดคเตเต เดธเตเดฐเดเตเดทเดฟเดคเดฎเดพเดฏ เดธเตเดฅเดฒเดคเตเดคเต เดธเตเดเตเดทเดฟเดเตเดเตเด!
+
+
+manage_account_links=เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเดฟเดเตเดเตเดณเตเดณ เด
เดเตเดเตเดฃเตเดเตเดเตพ เดจเดฟเดฏเดจเตเดคเตเดฐเดฟเดเตเดเตเด
+manage_account_links_desc=เด เดฌเดพเดนเตเดฏ เด
เดเตเดเตเดฃเตเดเตเดเตพ เดจเดฟเดเตเดเดณเตเดเต เดเดฟเดฑเตเดฑเต เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดฒเดฟเดเตเดเตเดเตเดฏเตโเดคเต.
+account_links_not_available=เดจเดฟเดเตเดเดณเตเดเต เดเดฟเดฑเตเดฑเต เด
เดเตเดเตเดฃเตเดเตเดฎเดพเดฏเดฟ เดจเดฟเดฒเดตเดฟเตฝ เดฎเดฑเตเดฑเตเต เดฌเดพเดนเตเดฏ เด
เดเตเดเตเดฃเตเดเตเดเดณเตเดจเตเดจเตเด เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเดเดฟเดเตเดเดฟเดฒเตเดฒ.
+remove_account_link=เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเด เด
เดเตเดเตเดฃเตเดเต เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเด
+remove_account_link_desc=เดเดฐเต เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเด เด
เดเตเดเตเดฃเตเดเต เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเดจเตเดจเดคเต เดจเดฟเดเตเดเดณเตเดเต เดเดฟเดฑเตเดฑเต เด
เดเตเดเตเดฃเตเดเดฟเดฒเตเดเตเดเตเดณเตเดณ เดชเตเดฐเดตเตเดถเดจเด เด
เดธเดพเดงเตเดตเดพเดเตเดเตเด. เดคเตเดเดฐเดเตเดเต?
+remove_account_link_success=เดฌเดจเตเดงเดฟเดชเตเดชเดฟเดเตเด เด
เดเตเดเตเดฃเตเดเต เดจเตเดเตเดเดเดเตเดฏเตโเดคเต.
+
+orgs_none=เดจเดฟเดเตเดเตพ เดเดคเตเดเตเดเดฟเดฒเตเด เดธเดเดเดเดจเดฏเดฟเดฒเตโ เด
เดเดเดฎเดฒเตเดฒ.
+repos_none=เดจเดฟเดเตเดเตพเดเตเดเต เดเดฐเต เดเดฒเดตเดฑเดฏเตเด เดธเตเดตเดจเตเดคเดฎเดพเดฏเดฟ เดเดฒเตเดฒ
+
+delete_account=เด
เดเตเดเตเดฃเตเดเต เดเดฒเตเดฒเดพเดคเดพเดเตเดเตเด
+delete_prompt=เด เดชเตเดฐเดตเตผเดคเตเดคเดจเด เดจเดฟเดเตเดเดณเตเดเต เดเดชเดฏเตเดเตเดคเต เด
เดเตเดเตเดฃเตเดเต เดถเดพเดถเตเดตเดคเดฎเดพเดฏเดฟ เดเดฒเตเดฒเดพเดคเดพเดเตเดเตเด. เดเดคเต เดชเตเตผโเดตเตเดตเดพเดตเดธเตเดฅเดฏเดฟเดฒเดพเดเตเดเดพเตปโ เดเดดเดฟเดฏเดฟเดฒเตเดฒ. .
+confirm_delete_account=เดเดฒเตเดฒเดพเดคเดพเดเตเดเตฝ เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดเตเดเตเด
+delete_account_title=เดเดชเดฏเตเดเตเดคเต เด
เดเตเดเตเดฃเตเดเต เดเดฒเตเดฒเดพเดคเดพเดเตเดเตเด
+delete_account_desc=เด เดเดชเดฏเตเดเตเดคเต เด
เดเตเดเตเดฃเตเดเต เดถเดพเดถเตเดตเดคเดฎเดพเดฏเดฟ เดเดฒเตเดฒเดพเดคเดพเดเตเดเดพเตป เดจเดฟเดเตเดเตพ เดเดเตเดฐเดนเดฟเดเตเดเตเดจเตเดจเตเดฃเตเดเต?
+
+email_notifications.enable=เดเดฎเตเดฏเดฟเตฝ เด
เดฑเดฟเดฏเดฟเดชเตเดชเตเดเตพ เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด
+email_notifications.onmention=เด-เดฎเตเดฏเดฟเตฝ เดชเดฐเดพเดฎเดฐเตโเดถเดฟเดเตเดเดพเตฝ เดฎเดพเดคเตเดฐเด เด
เดฏเดฏเตเดเตเดเตเด
+email_notifications.disable=เดเดฎเตเดฏเดฟเตฝ เด
เดฑเดฟเดฏเดฟเดชเตเดชเตเดเตพ เด
เดชเตเดฐเดพเดชเตเดคเดฎเดพเดเตเดเตเด
+email_notifications.submit=เด-เดฎเตเดฏเดฟเดฒเตโ เดฎเตเตปเดเดฃเดจเดเดณเตโ
+
+
+[repo]
+owner=เดเดเดฎเดธเตเดฅเดจเตโ
+repo_name=เดเดฒเดตเดฑเดฏเตเดเต เดชเตเดฐเตเต
+repo_name_helper=เดจเดฒเตเดฒ เดเดฒเดตเดฑเดฏเตเดเต เดชเตเดฐเตเต เดนเตเดฐเดธเตเดตเดตเตเด เด
เดตเดฟเดธเตเดฎเดฐเดฃเตเดฏเดตเตเด เด
เดคเตเดฒเตเดฏเดตเตเดฎเดพเดฏ เดเตเดตเตเดกเตเดเตพ เดเดชเดฏเตเดเดฟเดเตเดเตเดจเตเดจเต.
+visibility=เดเดพเดฃเดพเดจเดพเดตเตเดจเตเดจเดคเตเต
+visibility_description=เดเดเดฎเดฏเตโเดเตเดเต เดเตผเดเดจเตเดธเตเดทเตป เด
เดเดเดเตเดเตพเดเตเดเต เด
เดตเดเดพเดถเดเตเดเดณเตเดฃเตเดเตเดเตเดเดฟเตฝ เดฎเดพเดคเตเดฐเดฎเต เดเดพเดฃเดพเตป เดเดดเดฟเดฏเต.
+visibility_helper=เดเดฒเดตเดฑ เดธเตเดตเดเดพเดฐเตเดฏเดฎเดพเดเตเดเตเด
+visibility_helper_forced=เดจเดฟเดเตเดเดณเตเดเต เดธเตเดฑเตเดฑเต เด
เดกเตเดฎเดฟเดจเดฟเดธเตเดเตเดฐเตเดฑเตเดฑเตผ เดชเตเดคเดฟเดฏ เดเดฒเดตเดฑเดเดณเต เดธเตเดตเดเดพเดฐเตเดฏเดฎเดพเดเตเดเดพเตป เดจเดฟเตผเดฌเดจเตเดงเดฟเดเตเดเตเดจเตเดจเต.
+visibility_fork_helper=(เดฎเดพเดฑเตเดฑเด เดเดฒเตเดฒเดพ เดซเตเตผเดเตเดเตเดเดณเตเดฏเตเด เดฌเดพเดงเดฟเดเตเดเตเด.)
+clone_helper=เดเตเดฒเตเดฃเตโ เดเตเดฏเตเดฏเดพเดจเตโ เดธเดนเดพเดฏเด เดตเตเดฃเต? เดธเดนเดพเดฏเด เดธเดจเตเดฆเดฐเตโเดถเดฟเดเตเดเตเด.
+fork_repo=เดเดฒเดตเดฑ เดซเตเดฐเตโเดเตเดเตเต เดเตเดฏเตเดฏเตเด
+fork_from=เดฒเตโ เดจเดฟเดจเตเดจเตเด เดซเตเดฐเตโเดเตเดเตเต เดเตเดฏเตเดฏเต
+fork_visibility_helper=เดเดฐเต เดเดฒเดตเดฑเดฏเตเดเต เดซเตเดฐเตโเดเตเดเดฟเดจเตเดฑเต เดฆเตเดถเตเดฏเดชเดฐเดค เดฎเดพเดฑเตเดฑเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+repo_desc=เดตเดฟเดฐเดฐเดฃเด
+repo_lang=เดญเดพเดท
+repo_gitignore_helper=.gitignore เดเตเดเดชเตเดฒเตเดฑเตเดฑเตเดเตพ เดคเดฟเดฐเดเตเดเตเดเตเดเตเดเตเด.
+license=เดฒเตเดธเตปเดธเต
+license_helper=เดเดฐเต เดฒเตเดธเตปเดธเต เดซเดฏเตฝ เดคเดฟเดฐเดเตเดเตเดเตเดเตเดเตเด.
+readme=เดฑเตเดกเตโเดฎเต
+readme_helper=เดเดฐเต เดฑเตเดกเตโเดฎเต เดซเดฏเตฝ เดเตเดเดชเตเดฒเตเดฑเตเดฑเต เดคเดฟเดฐเดเตเดเตเดเตเดเตเดเตเด.
+auto_init=เดเดฒเดตเดฑ เดธเดฎเดพเดฐเดเดญเดฟเดเตเดเตเด (.gitignore, เดฒเตเดธเตปเดธเต, เดฑเตเดกเตโเดฎเต เดเดจเตเดจเดฟเดต เดเตเตผเดเตเดเตเดจเตเดจเต)
+create_repo=เดเดฒเดตเดฑ เดธเตเดทเตเดเดฟเดเตเดเตเด
+default_branch=เดธเตเดฅเดฟเดฐเดธเตเดฅเดฟเดคเดฟ เดถเดพเด
+mirror_prune=เดตเตเดเตเดเดฟเดเดคเตเดเตเดเตเด
+mirror_prune_desc=เดเดพเดฒเดนเดฐเดฃเดชเตเดชเตเดเตเด เดตเดฟเดฆเตเดฐ เดเตเดฐเดพเดเตเดเดฟเดเดเต เดฑเดซเดฑเตปเดธเตเดเตพ เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเด
+mirror_interval_invalid=เดฎเดฟเดฑเตผ เดเตเดฏเตเดฏเดพเดจเตเดณเตเดณ เดเดเดตเตเดณ เดธเดพเดงเตเดตเดฒเตเดฒ.
+mirror_address=URL- เตฝ เดจเดฟเดจเตเดจเตเดณเตเดณ เดเตเดฒเตเตบ
+mirror_address_url_invalid=เดจเตฝเดเดฟเดฏ url เด
เดธเดพเดงเตเดตเดพเดฃเต. เดจเดฟเดเตเดเตพ url- เดจเตเดฑเต เดเดฒเตเดฒเดพ เดเดเดเดเตเดเดณเตเด เดถเดฐเดฟเดฏเดพเดฏเดฟ เดจเดฒเตโเดเดฃเด.
+mirror_address_protocol_invalid=เดจเตฝเดเดฟเดฏ url เด
เดธเดพเดงเตเดตเดพเดฃเต. http(s):// เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ git:// เดฒเตเดเตเดเตเดทเดจเตเดเตพ เดฎเดพเดคเตเดฐเดฎเต เดฎเดฟเดฑเตผ เดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเต.
+mirror_last_synced=เด
เดตเดธเดพเดจเด เดธเดฎเดจเตเดตเดฏเดฟเดชเตเดชเดฟเดเตเดเดคเตเต
+watchers=เดจเดฟเดฐเตเดเตเดทเดเตผ
+stargazers=เดธเตเดฑเตเดฑเดพเตผเดเดพเดธเดฑเตเดเตพ
+forks=เดถเดพเดเดเดณเตโ
+pick_reaction=เดจเดฟเดเตเดเดณเตเดเต เดชเตเดฐเดคเดฟเดเดฐเดฃเด เดคเดฟเดฐเดเตเดเตเดเตเดเตเดเตเด
+reactions_more=เดเตเดเดพเดคเต %d เด
เดงเดฟเดเด
+
+
+
+
+archive.title=เด เดเดฒเดตเดฑ เดเดฐเดฟเดคเตเดฐเดฐเตเดเดพเดชเดฐเดฎเดพเดฏเดฟ เดจเดฟเดฒเดจเดฟเดฐเตโเดคเตเดคเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต. เดจเดฟเดเตเดเตพเดเตเดเต เดซเดฏเดฒเตเดเตพ เดเดพเดฃเดพเดจเตเด เดเตเดฒเตเตบ เดเตเดฏเตเดฏเดพเดจเตเด เดเดดเดฟเดฏเตเด, เดชเดเตเดทเต เดชเตเดฐเดถเตโเดจเดเตเดเตพ / เดฒเดฏเดจ เด
เดญเตเดฏเตผเดคเตเดฅเดจเดเตพ เดเดฃเตเดเดพเดเตเดเดพเดจเต เดคเตเดฑเดเตเดเดพเดจเต เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+archive.issue.nocomment=เด เดเดฒเดตเดฑ เดเดฐเดฟเดคเตเดฐเดชเดฐเดฎเดพเดฏเดฟ เดจเดฟเดฒเดจเดฟเดฐเตโเดคเตเดคเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเดคเดพเดฃเตเต. เดจเดฟเดเตเดเตพเดเตเดเต เดชเตเดฐเดถเตเดจเดเตเดเดณเดฟเตฝ เด
เดญเดฟเดชเตเดฐเดพเดฏเดฎเดฟเดเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+archive.pull.nocomment=เด เดเดฒเดตเดฑ เดเดฐเดฟเดคเตเดฐเดชเดฐเดฎเดพเดฏเดฟ เดจเดฟเดฒเดจเดฟเดฐเตโเดคเตเดคเดฟเดฏเดฟเดฐเดฟเดเตเดเตเดจเตเดจเดคเดพเดฃเตเต. เดจเดฟเดเตเดเตพเดเตเดเต เดฒเดฏเดจ เด
เดญเตเดฏเตผเดคเตเดฅเดจเดเดณเดฟเดฒเตโ เด
เดญเดฟเดชเตเดฐเดพเดฏเดฎเดฟเดเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+
+form.name_reserved='%s' เดเดจเตเดจ เดเดฒเดตเดฑเดฏเตเดเต เดชเตเดฐเตเต เดฎเดฑเตเดฑเดพเดตเดถเตเดฏเดเตเดเดณเตโเดเตเดเดพเดฏเดฟ เดจเตเดเตเดเดฟเดตเดเตเดเดฟเดฐเดฟเดเตเดเตเดจเตเดจเต.
+form.name_pattern_not_allowed=เดเดฒเดตเดฑเดจเดพเดฎเดคเตเดคเดฟเตฝ '%s' เดเดจเตเดจ เดถเตเดฐเตเดฃเดฟ เด
เดจเตเดตเดฆเดจเตเดฏเดฎเดฒเตเดฒ.
+
+migrate_items=เดฎเตเดเตเดฐเตเดทเตป เดเดจเดเตเดเตพ
+migrate_items_wiki=เดตเดฟเดเตเดเดฟ
+migrate_items_milestones=เดจเดพเดดเดฟเดเดเตเดเดฒเตเดฒเตเดเดณเตโ
+migrate_items_labels=เดฒเตเดฌเดฒเตเดเดณเตโ
+migrate_items_issues=เดชเตเดฐเดถเตเดจเดเตเดเตพ
+migrate_items_pullrequests=เดฒเดฏเดจ เด
เดญเตเดฏเตผเดคเตเดฅเดจเดเตพ
+migrate_items_releases=เดชเตเดฐเดธเดฟเดฆเตเดงเตเดเดฐเดฃเดเตเดเดณเตโ
+migrate_repo=เดเดฒเดตเดฑ เดฎเตเดเตเดฐเตเดฑเตเดฑเต เดเตเดฏเตเดฏเตเด
+migrate.clone_address=URL- เตฝ เดจเดฟเดจเตเดจเต เดฎเตเดเตเดฐเตเดฑเตเดฑเต / เดเตเดฒเตเตบ เดเตเดฏเตเดฏเตเด
+migrate.clone_address_desc=เดจเดฟเดฒเดตเดฟเดฒเตเดณเตเดณ เดเดฐเต เดเดฒเดตเดฑเดฏเตเดเต HTTP(S) เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดเดฟเดฑเตเดฑเตเต 'เดเตเดฒเตเตบ' URL
+migrate.clone_local_path=เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดเดฐเต เดชเตเดฐเดพเดฆเตเดถเดฟเด เดธเตเตผเดตเตผ เดชเดพเดค
+migrate.permission_denied=เดชเตเดฐเดพเดฆเตเดถเดฟเด เดเดฒเดตเดฑเดเดณเตโ เดเดฑเดเตเดเตเดฎเดคเดฟ เดเตเดฏเตเดฏเดพเตป เดจเดฟเดเตเดเดณเตโเดเตเดเตเต เด
เดจเตเดตเดพเดฆเดฎเดฟเดฒเตเดฒ.
+migrate.invalid_local_path=เดชเตเดฐเดพเดฆเตเดถเดฟเด เดชเดพเดค เด
เดธเดพเดงเตเดตเดพเดฃเต. เดเดคเต เดจเดฟเดฒเดตเดฟเดฒเดฟเดฒเตเดฒ เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดเดฐเต เดกเดฏเดฑเดเตเดเดฑเดฟเดฏเดฒเตเดฒ.
+migrate.failed=เดฎเตเดเตเดฐเตเดทเตป เดชเดฐเดพเดเดฏเดชเตเดชเตเดเตเดเต: %v
+migrated_from=%[2]s เดจเดฟเดจเตเดจเต เดฎเตเดเตเดฐเตเดฑเตเดฑเตเดเตเดฏเตโเดคเต
+migrated_from_fake=%[1]s เดจเดฟเดจเตเดจเต เดฎเตเดเตเดฐเตเดฑเตเดฑเตเดเตเดฏเตเดคเต
+
+mirror_from=เดจเตเดฑเต เดเดฃเตเดฃเดพเดเดฟ
+forked_from=เดฒเตโ เดจเดฟเดจเตเดจเตเด เดตเดดเดฟเดชเดฟเดฐเดฟเดเตเดเดคเตเต
+fork_from_self=เดจเดฟเดเตเดเดณเตเดเต เดเดเดฎเดธเตเดฅเดคเดฏเดฟเดฒเตเดณเตเดณ เดเดฐเต เดถเตเดเดฐเด เดจเดฟเดเตเดเตพเดเตเดเต เดซเตเดฐเตโเดเตเดเตเต เดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+fork_guest_user=เด เดถเตเดเดฐเด เดซเตเตผเดเตเดเต เดเตเดฏเตเดฏเตเดจเตเดจเดคเดฟเดจเต เดธเตเตป เดเตป เดเตเดฏเตเดฏเตเด.
+unwatch=เดถเตเดฐเดฆเตเดงเดฟเดเตเดเดพเดคเดฟเดฐเดฟเดฏเตเดเตเดเตเด
+watch=เดถเตเดฐเดฆเตเดงเดฟเดฏเตเดเตเดเตเด
+unstar=เดจเดเตเดทเดคเตเดฐเด เดจเตเดเตเดเตเด
+star=เดจเดเตเดทเดคเตเดฐเด เดจเดฒเตโเดเตเดเตเด
+fork=เดซเตเดฐเตโเดเตเดเตเต
+download_archive=เดเดฒเดตเดฑ เดกเตเตบเดฒเตเดกเตเดเตเดฏเตเดฏเตเด
+
+no_desc=เดตเดฟเดตเดฐเดฃเด เดฒเดญเตเดฏเดฎเดฒเตเดฒ
+quick_guide=เดฆเตเดฐเตเดค เดฎเดพเดฐเตโเดเดฆเดฐเตโเดถเดจเด
+clone_this_repo=เด เดเดฒเดตเดฑ เดเตเดฒเตเตบ เดเตเดฏเตเดฏเตเด
+create_new_repo_command=เดเดฎเดพเตปเดกเต เดฒเตเดจเตโ เดตเดดเดฟ เดเดฐเต เดชเตเดคเดฟเดฏ เดเดฒเดตเดฑ เดธเตเดทเตเดเดฟเดเตเดเตเด
+push_exist_repo=เดเดฎเดพเตปเดกเต เดฒเตเดจเดฟเตฝ เดจเดฟเดจเตเดจเต เดจเดฟเดฒเดตเดฟเดฒเตเดณเตเดณ เดเดฐเต เดเดฒเดตเดฑ เดคเดณเตเดณเดฟเดเตเดเดฏเดฑเตเดฑเตเด
+empty_message=เด เดเดฒเดตเดฑเดฏเดฟเดฒเตโ เดเดณเตเดณเดเดเตเดเดฎเตเดจเตเดจเตเด เด
เดเดเตเดเดฟเดฏเดฟเดเตเดเดฟเดฒเตเดฒ.
+
+code=เดเตเดกเต
+code.desc=เดเดฑเดตเดฟเด เดเตเดกเต, เดซเดฏเดฒเตเดเตพ, เดเดฎเตเดฎเดฟเดฑเตเดฑเตเดเดณเตเด เดถเดพเดเดเดณเตเด เดชเตเดฐเดตเตเดถเดฟเดฏเตเดเตเดเตเด.
+branch=เดถเดพเด
+tree=เดฎเดฐเด
+filter_branch_and_tag=เดถเดพเด เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดเดพเดเต เด
เดฐเดฟเดเตเดเตเดเตเดเตเดเตเด
+branches=เดถเดพเดเดเดณเตโ
+tags=เดเดพเดเตเดเดณเตโ
+issues=เดชเตเดฐเดถเตเดจเดเตเดเตพ
+pulls=เดฒเดฏเดจ เด
เดญเตเดฏเตผเดคเตเดฅเดจเดเตพ
+labels=เดฒเตเดฌเดฒเตเดเดณเตโ
+
+milestones=เดจเดพเดดเดฟเดเดเตเดเดฒเตเดฒเตเดเดณเตโ
+commits=เดเดฎเตเดฎเดฟเดฑเตเดฑเตเดเดณเตโ
+commit=เดเดฎเตเดฎเดฟเดฑเตเดฑเต
+releases=เดชเตเดฐเดธเดฟเดฆเตเดงเดชเตเดชเตเดเตเดคเตเดคเตเด
+file_raw=เดเดฒเดฐเตโเดชเตเดชเดฟเดฒเตเดฒเดพเดคเตเดคเดคเตเต
+file_history=เดจเดพเดณเตโเดตเดดเดฟ
+file_view_raw=เดเดฒเดฐเตโเดชเตเดชเดฟเดฒเตเดฒเดพเดคเต เดเดพเดฃเตเด
+file_permalink=เดธเตเดฅเดฟเดฐเดฎเดพเดฏ เดเดฃเตเดฃเดฟ
+file_too_large=เด เดซเดฏเตฝ เดเดพเดฃเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเดพเดคเตเดคเดคเตเดฐ เดตเดฒเตเดคเดพเดฃเต.
+
+video_not_supported_in_browser=เดจเดฟเดเตเดเดณเตเดเต เดฌเตเดฐเตเดธเตผ HTML5 'เดตเตเดกเดฟเดฏเต' เดเดพเดเดฟเดจเต เดชเดฟเดจเตเดคเตเดฃเดฏเตเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒ.
+audio_not_supported_in_browser=เดจเดฟเดเตเดเดณเตเดเต เดฌเตเดฐ browser เดธเตผ HTML5 'เดเดกเดฟเดฏเต' เดเดพเดเดฟเดจเต เดชเดฟเดจเตเดคเตเดฃเดฏเตเดเตเดเตเดจเตเดจเดฟเดฒเตเดฒ.
+stored_lfs=เดเดฟเดฑเตเดฑเตเต LFS เดเดชเดฏเตเดเดฟเดเตเดเต เดธเดเดญเดฐเดฟเดเตเดเต
+commit_graph=เดเดฎเตเดฎเดฟเดฑเตเดฑเต เดเตเดฐเดพเดซเต
+blame=เดเตเดฎเดคเดฒ
+normal_view=เดธเดพเดงเดพเดฐเดฃ เดเดพเดดเตเด
+
+editor.new_file=เดชเตเดคเดฟเดฏ เดซเดฏเตฝ
+editor.upload_file=เดซเดฏเตฝ เด
เดชเตโเดฒเตเดกเต
+editor.edit_file=เดซเดฏเตฝ เดคเดฟเดฐเตเดคเตเดคเตเด
+editor.preview_changes=เดฎเดพเดฑเตเดฑเดเตเดเตพ เดเดพเดฃเตเด
+editor.cannot_edit_lfs_files=เดตเตเดฌเต เดเดจเตเดฑเตผเดซเตเดธเดฟเตฝ LFS เดซเดฏเดฒเตเดเตพ เดเดกเดฟเดฑเตเดฑเตเดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+editor.cannot_edit_non_text_files=เดตเตเดฌเต เดเดจเตเดฑเตผเดซเตเดธเดฟเตฝ เดฌเตเดจเดฑเดฟ เดซเดฏเดฒเตเดเตพ เดเดกเดฟเดฑเตเดฑเตเดเตเดฏเตเดฏเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+editor.edit_this_file=เดซเดฏเตฝ เดคเดฟเดฐเตเดคเตเดคเตเด
+editor.must_be_on_a_branch=เด เดซเดฏเดฒเดฟเตฝ เดฎเดพเดฑเตเดฑเดเตเดเตพ เดตเดฐเตเดคเตเดคเดพเดจเต เดจเดฟเตผเดฆเตเดฆเตเดถเดฟเดเตเดเดพเดจเต เดจเดฟเดเตเดเตพ เดเดคเตเดเตเดเดฟเดฒเตเด เดเดฐเต เดถเดพเดเดฏเดฟเตฝ เดเดฏเดฟเดฐเดฟเดเตเดเดฃเด.
+editor.fork_before_edit=เด เดซเดฏเดฒเดฟเตฝ เดฎเดพเดฑเตเดฑเดเตเดเตพ เดตเดฐเตเดคเตเดคเดพเดจเต เดจเดฟเตผเดฆเตเดฆเตเดถเดฟเดเตเดเดพเดจเต เดจเดฟเดเตเดเตพ เด เดถเตเดเดฐเด เดซเตเดฐเตโเดเตเดเต เดเตเดฏเตเดคเดฟเดฐเดฟเดเตเดเดฃเด.
+editor.delete_this_file=เดซเดฏเตฝ เดเดฒเตเดฒเดพเดคเดพเดเตเดเตเด
+editor.must_have_write_access=เด เดซเดฏเดฒเดฟเตฝ เดฎเดพเดฑเตเดฑเดเตเดเตพ เดตเดฐเตเดคเตเดคเดพเดจเต เดจเดฟเตผเดฆเตเดฆเตเดถเดฟเดเตเดเดพเดจเต เดจเดฟเดเตเดเตพเดเตเดเต เดเดดเตเดคเดพเดจเตเดณเตเดณ เด
เดจเตเดฎเดคเดฟ เดเดฃเตเดเดพเดฏเดฟเดฐเดฟเดเตเดเดฃเด.
+editor.file_delete_success=%s เดซเดฏเตฝ เดเดฒเตเดฒเดพเดคเดพเดเตเดเดฟ.
+editor.name_your_file=เดจเดฟเดเตเดเดณเตเดเต เดซเดฏเดฒเดฟเดจเต เดชเตเดฐเต เดจเตฝเดเตเดโฆ
+editor.filename_help=เดเดฐเต เดกเดฏเดฑเดเตโเดเดฑเดฟเดฏเตเดเต เดชเตเดฐเต เดเตเดชเตเดชเตเดเตเดฏเตโเดคเต เดธเตเดฒเดพเดทเตเด ('/') เดเตเตผเดคเตเดคเต เดเตเตผเดเตเดเตเด. เดเตปเดชเตเดเตเดเต เดซเตเตฝเดกเดฟเดจเตเดฑเต เดคเตเดเดเตเดเดคเตเดคเดฟเตฝ เดฌเดพเดเตเดเตโเดธเตโเดชเตเดฏเตโเดธเต เดเตเดชเตเดชเตเดเตเดฏเตโเดคเต เดเดฐเต เดกเดฏเดฑเดเตโเดเดฑเดฟ เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเด.
+editor.or=เด
เดฅเดตเดพ
+editor.cancel_lower=เดฑเดฆเตเดฆเดพเดเตเดเตเด
+editor.commit_changes=เดฎเดพเดฑเตเดฑเดเตเดเตพ เดตเดฐเตเดคเตเดคเตเด
+editor.add_tmpl='<%s>' เดเตเตผเดเตเดเตเด
+editor.add_tmpl.filename = เดซเดฏเดฒเตโ
+editor.add=%s เดเตเดฐเตโเดเตเดเตเด
+editor.update=%s เดชเตเดคเตเดเตเดเตเด
+editor.delete=%s เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+editor.propose_file_change=เดซเดฏเดฒเดฟเดจเตเต เดฎเดพเดฑเตเดฑเดเตเดเดณเตโ เดจเดฟเตผเดฆเตเดฆเตเดถเดฟเดเตเดเตเด
+editor.new_branch_name_desc=เดชเตเดคเดฟเดฏ เดถเดพเดเดฏเตเดเต เดชเตเดฐเตเตโฆ
+editor.cancel=เดฑเดฆเตเดฆเดพเดเตเดเตเด
+editor.filename_cannot_be_empty=เดซเดฏเดฒเดฟเดจเตเดฑเต เดชเตเดฐเตเต เดถเตเดจเตเดฏเดฎเดพเดฏเดฟเดฐเดฟเดเตเดเดฐเตเดคเต.
+editor.add_subdir=เดเดฐเต เดกเดฏเดฑเดเตเดเดฑเดฟ เดเตเตผเดเตเดเตเดโฆ
+editor.upload_files_to_dir=เดซเดฏเดฒเตเดเตพ %s เดฒเตเดเตเดเต เด
เดชเตโเดฒเตเดกเตเดเตเดฏเตเดฏเตเด
+
+
+
+
+
+issues.new.clear_labels=เดฒเตเดฌเดฒเตเดเตพ เดฎเดพเดฏเตโเดเตเดเตเด
+issues.new.milestone=เดจเดพเดดเดฟเดเดเตเดเดฒเตเดฒเต
+issues.new.no_milestone=เดจเดพเดดเดฟเดเดเตเดเดฒเตเดฒเต เดเดฒเตเดฒ
+issues.new.clear_milestone=เดจเดพเดดเดฟเดเดเตเดเดฒเตเดฒเต เดเดเตเดคเตเดคเต เดฎเดพเดฑเตเดฑเตเด
+issues.new.open_milestone=เดจเดพเดดเดฟเดเดเตเดเดฒเตเดฒเตเดเตพ เดคเตเดฑเดเตเดเตเด
+issues.new.closed_milestone=เด
เดเดเตเด เดจเดพเดดเดฟเดเดเตเดเดฒเตเดฒเตเดเตพ
+issues.new.assignees=เดจเดฟเดถเตเดเดฏเดฟเดเตเดเตเดจเตเดจเดตเดฐเตโ
+issues.new.clear_assignees=เดจเดฟเดถเตเดเดฏเดฟเดเตเดเตเดจเตเดจเดตเดฐเต เดจเตเดเตเดเด เดเตเดฏเตเดฏเตเด
+issues.new.no_assignees=เดจเดฟเดถเตเดเดฏเดฟเดเตเดเตเดจเตเดจเดตเดฐเตโ เดเดฒเตเดฒ
+issues.no_ref=เดถเดพเดเดพ เด
เดฅเดตเดพ เดเดพเดเต เดตเตเดฏเดเตเดคเดฎเดพเดเตเดเดฟเดฏเดฟเดเตเดเดฟเดฒเตเดฒ
+issues.create=เดชเตเดฐเดถเตเดจเด เดธเตเดทเตเดเดฟเดเตเดเตเด
+issues.new_label=เดชเตเดคเดฟเดฏ เด
เดเดฏเดพเดณเด
+issues.new_label_placeholder=เด
เดเดฏเดพเดณ เดจเดพเดฎเด
+issues.new_label_desc_placeholder=เดตเดฟเดฐเดฐเดฃเด
+issues.create_label=เด
เดเดฏเดพเดณเด เดธเตเดทเตเดเดฟเดเตเดเตเด
+issues.label_templates.title=เดฎเตเตปโเดจเดฟเดถเตเดเดฏเดฟเดเตเด เดเดฐเต เดเตเดเตเดเด เดฒเตเดฌเดฒเตเดเตพโ เดจเดฟเดฑเดฏเตโเดเตเดเตเด
+issues.label_templates.info=เดฒเตเดฌเดฒเตเดเดณเตเดจเตเดจเตเด เดเดคเตเดตเดฐเต เดจเดฟเดฒเดตเดฟเดฒเดฟเดฒเตเดฒ. 'เดชเตเดคเดฟเดฏ เดฒเตเดฌเตฝ' เดเดชเดฏเตเดเดฟเดเตเดเต เดเดฐเต เดฒเตเดฌเตฝ เดธเตเดทเตเดเดฟเดเตเดเตเด เด
เดฒเตเดฒเตเดเตเดเดฟเตฝ เดฎเตเตปโเดจเดฟเดถเตเดเดฏเดฟเดเตเด เดฒเตเดฌเตฝ เดธเตเดฑเตเดฑเต เดเดชเดฏเตเดเดฟเดเตเดเตเด:
+issues.label_templates.helper=เดเดฐเต เดฒเตเดฌเตฝ เดธเตเดฑเตเดฑเต เดคเดฟเดฐเดเตเดเตเดเตเดเตเดเตเด
+issues.label_templates.use=เดฒเตเดฌเตฝ เดธเตเดฑเตเดฑเต เดเดชเดฏเตเดเดฟเดเตเดเตเด
+issues.deleted_milestone=`(เดเดฒเตเดฒเดพเดคเดพเดเตเดเดฟ)`
+issues.filter_type.all_issues=เดเดฒเตเดฒเดพ เดเดทเตเดฏเตเดเดณเตเด
+issues.label_open_issues=%d เดคเตเดฑเดจเตเดจเดจเดฟเดฒเดฏเดฟเดฒเตเดณเตเดณ เดเดทเตเดฏเตเดเดณเตโ
+issues.label_deletion_desc=เดเดฐเต เดฒเตเดฌเตฝ เดเดฒเตเดฒเดพเดคเดพเดเตเดเดฟเดฏเดพเดฒเตโ, เด
เดคเตเต เดจเดฟเดฏเตเดเดคเดฎเดพเดเตเดเดฟเดฏ เดเดฒเตเดฒเดพ เดเดทเตเดฏเตเดเดณเดฟเดฒเตโ เดจเดฟเดจเตเดจเตเด เดจเตเดเตเดเดเดเตเดฏเตเดฏเตเด. เดคเตเดเดฐเดเตเดเต?
+issues.dependency.issue_close_blocks=เด เดเดทเตเดฏเต เด
เดเดฏเตโเดเตเดเตเดจเตเดจเดคเต เดเดจเดฟเดชเตเดชเดฑเดฏเตเดจเตเดจ เดเดทเตเดฏเตเดเดณเตโ เดคเดเดฏเตเดจเตเดจเตเต
+issues.dependency.pr_close_blocks=เด เดเดทเตเดฏเตเดเดณเตโ เด
เดเดฏเตโเดเตเดเตเดจเตเดจเดคเต เด เดฒเดฏเดจ เด
เดญเตเดฏเดฐเตโเดคเตเดฅเดจ เดคเดเดฏเตเดจเตเดจเตเต
+issues.dependency.issue_close_blocked=เด เดเดทเตเดฏเต เด
เดเดฏเตโเดเตเดเตเดจเตเดจเดคเดฟเดจเต เดฎเตเดฎเตเดชเต เดเดคเดฟเดจเต เดคเดเดฏเตเดจเตเดจ เดเดฒเตเดฒเดพ เดเดทเตเดฏเตเดเดณเตเด เดจเดฟเดเตเดเตพ เด
เดเดฏเตโเดเตเดเตเดฃเตเดเดคเตเดฃเตเดเต.
+issues.dependency.pr_close_blocked=เด เดฒเดฏเดจ เด
เดญเตเดฏเดฐเตโเดคเตเดฅเดจ เดธเตเดฅเดฟเดฐเตเดเดฐเดฟเดฏเตเดเตเดเตเดจเตเดจเดคเดฟเดจเต เดฎเตเดฎเตเดชเต เดเดคเดฟเดจเต เดคเดเดฏเตเดจเตเดจ เดเดฒเตเดฒเดพ เดเดทเตเดฏเตเดเดณเตเด เดจเดฟเดเตเดเตพ เด
เดเดฏเตโเดเตเดเตเดฃเตเดเดคเตเดฃเตเดเต.
+issues.dependency.setting=เดฒเดฏเดจ เด
เดญเตเดฏเดฐเตโเดคเตเดฅเดจเดเดณเตโเดเตเดเตเด เดเดทเตเดฏเตเดเดณเตโเดเตเดเตเดฎเดพเดฏเดฟ เดเดถเตเดฐเดฟเดคเดคเตเดตเด เดธเดเตเดเดฎเดพเดเตเดเตเด
+issues.dependency.add_error_cannot_create_circular=เดฐเดฃเตเดเต เดเดทเตเดฏเตเดเดณเตเด เดชเดฐเดธเตเดชเดฐเด เดคเดเดฏเตเดจเตเดจเดคเดพเดเตเดจเตเดจเดคเดฟเดฒเตเดเต เดจเดฟเดเตเดเตพเดเตเดเต เดเดฐเต เดเดถเตเดฐเดฏเดคเตเดตเด เดธเตเดทเตเดเดฟเดเตเดเดพเตป เดเดดเดฟเดฏเดฟเดฒเตเดฒ.
+issues.dependency.add_error_dep_not_same_repo=เดฐเดฃเตเดเต เดชเตเดฐเดถเตเดจเดเตเดเดณเตเด เดเดฐเต เดเดฒเดตเดฑเดฏเดฟเดฒเตเดคเตเต เดเดฏเดฟเดฐเดฟเดเตเดเดฃเด.
+
+
+
+
+milestones.filter_sort.most_issues=เดฎเดฟเดเตเด เดเดทเตเดฏเตเดเดณเตเด
+milestones.filter_sort.least_issues=เดเตเดฑเดเตเด เดเดทเตเดฏเตเดเดณเตเดเตเดเดฟเดฒเตเด
+
+
+
+
+activity.active_issues_count_n=%d เดธเดเตเดเตเดต เดเดทเตเดฏเตเดเดณเตโ
+activity.closed_issues_count_n=เด
เดเดเตเด เดเดทเตเดฏเตเดเดณเตโ
+activity.title.issues_n=%d เดเดทเตเดฏเตเดเดณเตโ
+activity.new_issues_count_n=เดชเตเดคเดฟเดฏ เดเดทเตเดฏเตเดเดณเตโ
+
+
+settings.event_issues=เดเดทเตเดฏเตเดเดณเตโ
+
+
+
+
+
+
+
+
+
+[org]
+
+[admin]
+repos.issues=เดเดทเตเดฏเตเดเดณเตโ
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+[action]
+
+[tool]
+
+[dropzone]
+
+[notification]
+
+[gpg]
+
+[units]
+
+[packages]
diff --git a/options/locale/locale_nb_NO.ini b/options/locale/locale_nb_NO.ini
new file mode 100644
index 0000000000..2c8b5cfc64
--- /dev/null
+++ b/options/locale/locale_nb_NO.ini
@@ -0,0 +1,155 @@
+[common]
+enable_javascript = Denne nettsiden krever JavaScript.
+toc = Innholdsfortegnelse
+licenses = Lisenser
+return_to_forgejo = Tilbake til Forgejo
+username = Brukernavn
+password = Passord
+access_token = Tilgangsnรธkkel
+re_type = Bekreft passord
+captcha = CAPTCHA
+twofa = Tofaktorautentisering
+email = E-postadresse
+link_account = Koble til konto
+register = Registrer
+version = Versjon
+powered_by = Drives av %s
+page = Side
+template = Mal
+language = Sprรฅk
+notifications = Varslinger
+create_new = Opprettโฆ
+user_profile_and_more = Profil og innstillingerโฆ
+signed_in_as = Logget inn som
+confirm_delete_selected = Bekreft sletting av alle valgte elementer?
+dashboard = Dashbord
+download_logs = Last ned logger
+copy_hash = Kopier hash
+more_items = Flere elementer
+passcode = Adgangskode
+webauthn_insert_key = Skriv inn din sikkerhetsnรธkkel
+webauthn_use_twofa = Bruk tofaktorkode fra din mobil
+organization = Organisasjon
+mirror = Speil
+new_mirror = Ny speiling
+repository = Repositorium
+new_project = Nytt prosjekt
+new_project_column = Ny kolonne
+webauthn_error = Klarte ikke lese sikkerhetsnรธkkelen.
+webauthn_unsupported_browser = Nettleseren din stรธtter ikke WebAuthn.
+webauthn_error_unknown = En ukjent feil oppstod. Vennligst prรธv igjen.
+webauthn_error_insecure = WebAuhn stรธtter kun sikre forbindelser. For testing over HTTP kan du bruke verten "localhost" eller "127.0.0.1"
+admin_panel = Nettsideadministrasjon
+settings = Innstillinger
+your_profile = Profil
+your_starred = Stjernemerket
+your_settings = Innstillinger
+new_repo.title = Nytt repositorium
+new_migrate.title = Ny migrasjon
+new_org.title = Ny organisasjon
+new_repo.link = Nytt repositorium
+new_migrate.link = Ny migrasjon
+new_org.link = Ny organisasjon
+all = Alle
+sources = Kilder
+mirrors = Speilinger
+activities = Aktiviteter
+rss_feed = RSS feed
+retry = Prรธv igjen
+rerun = Kjรธr pรฅ nytt
+rerun_all = Kjรธr alle jobber pรฅ nytt
+save = Lagre
+cancel = Avbryt
+forks = Forks
+milestones = Milepรฆler
+ok = OK
+test = Test
+loading = Laster innโฆ
+error = Feil
+go_back = Gรฅ tilbake
+never = Aldri
+invalid_data = Ugyldig data: %v
+unknown = Ukjent
+pin = Pin
+artifacts = Artefakter
+archived = Arkivert
+concept_system_global = Global
+add = Legg til
+add_all = Legg til alle
+remove = Fjern
+remove_all = Fjern alle
+remove_label_str = Fjern element "%s"
+edit = Rediger
+view = Vis
+enabled = Aktivert
+disabled = Deaktivert
+locked = Lรฅst
+copy = Kopier
+copy_generic = Kopier til utklippstavlen
+copy_url = Kopier URL
+copy_content = Kopier innhold
+copy_success = Kopiert!
+copy_error = Kopiering mislyktes
+copy_type_unsupported = Denne filtypen kan ikke kopieres
+write = Skriv
+preview = Forhรฅndsvis
+concept_user_individual = Individuell
+concept_code_repository = Repositorium
+concept_user_organization = Organisasjon
+show_timestamps = Vis tidsstempler
+show_log_seconds = Vis sekunder
+show_full_screen = Vis fullskjerm
+name = Navn
+value = Verdi
+filter = Filter
+filter.clear = Tรธm filtre
+filter.is_archived = Arkivert
+filter.not_archived = Ikke arkivert
+filter.is_mirror = Speilinger
+filter.not_mirror = Ikke speilinger
+filter.is_template = Maler
+filter.not_template = Ikke maler
+filter.public = Offentlig
+filter.private = Privat
+explore = Utforsk
+active_stopwatch = Aktiv tidsregistrering
+home = Hjem
+help = Hjelp
+logo = Logo
+sign_in = Logg inn
+sign_in_with_provider = Logg inn med %s
+sign_in_or = eller
+sign_out = Logg ut
+sign_up = Opprett konto
+confirm_delete_artifact = Er du sikker pรฅ at du vil slette artefakten "%s" ?
+webauthn_sign_in = Trykk pรฅ knappen pรฅ sikkerhetsnรธkkelen din. Dersom nรธkkelen din ikke har en knapp, sett den inn pรฅ nytt.
+copy_path = Kopier sti
+webauthn_error_unable_to_process = Tjeneren kunne ikke behandle forespรธrselen din.
+webauthn_error_empty = Du mรฅ gi nรธkkelen et navn.
+toggle_menu = ร
pne/lukke meny
+twofa_scratch = To-faktor skrapekode
+webauthn_press_button = Vennligst trykk pรฅ knappen pรฅ sikkerhetsnรธkkelenโฆ
+webauthn_error_duplicated = Sikkerhetsnรธkkelen er ikke tillatt for denne forespรธrselen. Vennligst sรธrg for at nรธkkelen ikke allerede er registrert.
+webauthn_error_timeout = Et tidsavbrudd oppsto fรธr nรธkkelen din kunne leses. Vennligst last inn siden pรฅ nytt og prรธv igjen.
+new_fork = Ny fork av repository
+collaborative = Samarbeidende
+
+[search]
+search = Sรธk...
+type_tooltip = Sรธketype
+fuzzy = Fuzzy
+union = Union
+regexp = RegExp
+exact = Nรธyaktig
+
+[auth]
+verify = Bekreft
+sign_up_button = Opprett konto nรฅ.
+change_unconfirmed_email_error = Kan ikke endre e-postadresse: %v
+login_userpass = Logg inn
+oauth_signup_tab = Registrer ny konto
+oauth_signup_title = Fullfรธr ny konto
+oauth_signup_submit = Fullfรธr konto
+
+[home]
+uname_holder = Brukernavn eller e-postadresse
\ No newline at end of file
diff --git a/options/locale/locale_nds.ini b/options/locale/locale_nds.ini
new file mode 100644
index 0000000000..698f1330d6
--- /dev/null
+++ b/options/locale/locale_nds.ini
@@ -0,0 +1,3809 @@
+[common]
+home = Heimaad
+explore = Utfรถrsken
+help = Hรผlp
+sign_in = Anmellen
+sign_in_with_provider = Mit %s anmellen
+sign_in_or = of
+sign_out = Ofmellen
+sign_up = Registreren
+link_account = Konto verbinnen
+version = Versioon
+powered_by = Dreven mit %s
+page = Sied
+template = Vรถrlaag
+language = Spraak
+notifications = Narichtens
+tracked_time_summary = Tosamenfaten vun erfaat Tied na de Filters in de Gefall-List
+create_new = Neei โฆ
+user_profile_and_more = Profil un Instellens โฆ
+signed_in_as = Anmellt as
+enable_javascript = Deese Internett-Sied bruukt JavaScript.
+toc = Inhollsverteeknis
+return_to_forgejo = Torรผgg to Forgejo
+toggle_menu = Menรผ umschalten
+more_items = Mehr Dingen
+username = Brukernaam
+access_token = Togang-Teken
+captcha = CAPTCHA
+twofa = Twee-Faktooren-Anmellen
+twofa_scratch = Twee-Faktooren-Eenmaalpasswoord
+webauthn_insert_key = Steek dienen Sekerheids-Slรถtel in
+webauthn_press_button = Bidde drรผck de Knoop up dienem Sekerheids-Slรถtel โฆ
+webauthn_use_twofa = Bruuk eene Twee-Faktooren-Tahl vun dienem Telefoon
+webauthn_error = Kunn dienen Sekerheids-Slรถtel nich lesen.
+webauthn_unsupported_browser = Dien Browser unnerstรผtt stedenwies WebAuthn nich.
+webauthn_error_unknown = Een unbekannter Fehler is uptreden. Bidde versรถรถk dat noch eenmaal.
+passcode = Pass-Tahl
+webauthn_error_empty = Du muttst de Slรถtel eenen Naam geven.
+repository = Repositorium
+organization = Vereenigung
+new_fork = Neje Repositoriums-Gabel
+dashboard = Kontor
+logo = Logo
+active_stopwatch = Aktive Tied-Erfatens
+password = Passwoord
+register = Registreren
+licenses = Lizenzen
+email = E-Mail-Adress
+re_type = Passwoord utwiesen
+webauthn_error_unable_to_process = De Server kunn diene Anfraag nich verarbeiden.
+new_mirror = Nejer Spegel
+webauthn_sign_in = Drรผck de Knoop up dienem Sekerheids-Slรถtel. Wenn dien Slรถtel keenen Knoop hett, steek โt ut un weer in.
+webauthn_error_insecure = WebAuthn unnerstรผtt blots seker Verbinnens. Wenn du รถver HTTP testen willst, kannst du de Quell ยปlocalhostยซ of ยป127.0.0.1ยซ bruken
+webauthn_error_duplicated = De Sekerheids-Slรถtel is fรถr deese Anfraag nich verlรถรถvt. Bidde wees wiss, dat de Slรถtel nich al vermarkt is.
+webauthn_error_timeout = Tied รถverweggahn ehr dien Slรถtel lesen worden kunn. Bidde laad deese Sied neei un versรถรถk dat noch eenmaal.
+mirror = Spegel
+new_project = Nejes Projekt
+new_project_column = Neje Rieg
+admin_panel = Sied-Administreren
+settings = Instellens
+your_profile = Profil
+your_starred = Steern sett
+your_settings = Instellens
+new_repo.title = Nejes Repositorium
+new_org.title = Neje Vereenigung
+new_repo.link = Nejes Repositorium
+all = All
+mirrors = Spegels
+forks = Gabels
+activities = Doon
+pull_requests = Haalvรถrslagen
+issues = Gefallens
+milestones = Markstenen
+ok = Jau
+cancel = Ofbreken
+rerun = Weer lopen laten
+rerun_all = All Upgavens weer lopen laten
+save = Sekern
+add_all = All hentofรถgen
+remove = Wegdoon
+remove_all = All wegdoon
+remove_label_str = Ding ยป%sยซ wegdoon
+edit = Bewarken
+view = Wiesen
+test = Testen
+enabled = Anknipst
+disabled = Utknipst
+locked = Tosloten
+copy = Koperen
+copy_generic = To Tรผskenavlaag koperen
+copy_url = URL koperen
+copy_hash = Prรผfsumm koperen
+copy_content = Inholl koperen
+copy_branch = Twiegnaam koperen
+copy_success = Kopeert!
+copy_error = Koperen fehlslagen
+write = Schrieven
+preview = Utkiek
+loading = Lรคdt โฆ
+error = Fehler
+error404 = De Sied, wat du sรถchst, gifft dat of nich , of se is lรถsket worden of du hest nich de Rechten, se antokieken.
+error413 = Du hest diene Quote รถverweggahn.
+go_back = Torรผgg gahn
+invalid_data = Ungรผltiger Weert: %v
+never = Nie
+unknown = Unbekannt
+rss_feed = RSS-Schuuv
+pin = Faststeken
+unpin = Lรถsssteken
+artifacts = Objekten
+confirm_delete_artifact = Willst du dat Objekt ยป%sยซ wรผrrelk lรถsken?
+archived = Archiveert
+concept_user_individual = Enkelt
+concept_code_repository = Repositorium
+show_log_seconds = Sekรผnnen wiesen
+show_full_screen = Hele Billschirm wiesen
+download_logs = Utgaav runnerladen
+name = Naam
+value = Weert
+filter = Filter
+filter.is_archived = Archiveert
+filter.not_archived = Nich archiveert
+filter.is_fork = Gabels
+filter.not_fork = Nich Gabels
+filter.not_mirror = Nich Spegels
+filter.is_template = Vรถrlagen
+filter.not_template = Nich Vรถrlagen
+filter.public = Publik
+filter.private = Privaat
+new_migrate.link = Nejer Umtreck
+concept_system_global = รverall
+new_migrate.title = Nejer Umtreck
+retry = Weer versรถken
+sources = Quellen
+show_timestamps = Tiedstempels wiesen
+confirm_delete_selected = Willst du all de utkรถรถrt Dingen lรถsken?
+collaborative = Mitnanner arbeiden
+add = Hentofรถgen
+copy_type_unsupported = Deese Aard vun Datei kann nich kopeert worden
+new_org.link = Neje Vereenigung
+concept_user_organization = Vereenigung
+filter.clear = Filters leegmaken
+filter.is_mirror = Spegels
+copy_path = Padd koperen
+
+[search]
+search = Sรถken โฆ
+type_tooltip = Sรถรถk-Aard
+fuzzy = um de Slag
+fuzzy_tooltip = Ok Resultaten wiesen, wat dicht to de Sรถรถkwoorden passen
+union = Passt
+union_tooltip = Resultaten wiesen, wat to eets of anner vun de mit Leegtekens trennt Sรถรถkwoorden passen
+exact = akkeraat
+exact_tooltip = Blots Resultaten wiesen, wat akkeraat to de Sรถรถkwoord passen
+regexp = RegEx
+regexp_tooltip = De Sรถรถkwoord as Regel-Utdruck behanneln
+repo_kind = In Repos sรถken โฆ
+user_kind = In Brukers sรถken โฆ
+org_kind = In Vereenigungen sรถken โฆ
+team_kind = In Klottjen sรถken โฆ
+project_kind = In Projekten sรถken โฆ
+commit_kind = In Kommitterens sรถken โฆ
+runner_kind = In Lopers sรถken โฆ
+no_results = Nix funnen, wat passt.
+milestone_kind = In Markstenen sรถken โฆ
+pull_kind = In Haalvรถrslagens sรถken โฆ
+code_search_unavailable = Quelltext-Sรถรถk is stedenwies nich verfรถรถgbaar. Bidde kuntakteer de Sied-Chef.
+branch_kind = In Twiegen sรถken โฆ
+code_kind = In Quelltext sรถken โฆ
+package_kind = In Paketen sรถken โฆ
+issue_kind = In Gefallens sรถken โฆ
+keyword_search_unavailable = Woorden-Sรถรถk is stedenwies nich verfรถรถgbaar. Bidde kuntakteer de Sied-Chef.
+code_search_by_git_grep = Stedenwies Quelltext-Sรถรถk-Resultaten worden vun ยปgit grepยซ paraatstellt. Wenn de Sied-Chef de Quelltext-Indizerer anknipst, kann dat betere Resultaten geven.
+
+[aria]
+navbar = Navigerens-Balken
+footer = Footbalken
+footer.software = รver deeses Programm
+footer.links = Verwiesens
+
+[heatmap]
+number_of_contributions_in_the_last_12_months = %s Bidragens in de lesten 12 Maanten
+contributions_zero = Keene Bidragens
+contributions_format = {contributions} am {day}. {month} {year}
+contributions_one = Bidrag
+less = Minner
+more = Mehr
+contributions_few = Bidragens
+
+[editor]
+buttons.bold.tooltip = Fetten Text hentofรถgen
+buttons.italic.tooltip = Schรผรผnen Text hentofรถgen
+buttons.quote.tooltip = Text ziteren
+buttons.code.tooltip = Quelltext hentofรถgen
+buttons.link.tooltip = Verwies hentofรถgen
+buttons.list.unordered.tooltip = Punkierte List hentofรถgen
+buttons.list.task.tooltip = List vun Upgavens hentofรถgen
+buttons.mention.tooltip = Eenen Bruker of eene Klottje nรถmen
+buttons.ref.tooltip = Een Gefall of Haalvรถrslag nรถmen
+buttons.switch_to_legacy.tooltip = In Stee daarvun de olle Bewarker bruken
+buttons.disable_monospace_font = Fastbreden-Schrift utknipsen
+buttons.indent.tooltip = Dingen um een Stand inschuven
+buttons.unindent.tooltip = Dingen um een Stand utschuven
+buttons.heading.tooltip = รverschrift hentofรถgen
+buttons.list.ordered.tooltip = Nummereerte List hentofรถgen
+buttons.enable_monospace_font = Fastbreden-Schrift anknipsen
+buttons.new_table.tooltip = Tabell hentofรถgen
+table_modal.header = Tabell hentofรถgen
+table_modal.placeholder.header = Kopprieg
+table_modal.placeholder.content = Inholl
+table_modal.label.rows = Riegen
+table_modal.label.columns = Striepen
+link_modal.url = Url
+link_modal.description = Beschrieven
+link_modal.header = Fรถรถg eenen Verwies hento
+link_modal.paste_reminder = Wenk: Wenn in diener Tรผskenavlaag eene URL is, kannst du se stracks in de Bewarker infรถgen, um eenen Verwies to maken.
+
+[filter]
+string.desc = Z โ A
+string.asc = A โ Z
+
+[error]
+not_found = Dat Enn kunn nich funnen worden.
+network_error = Nettwark-Fehler
+server_internal = Binnerer Server-Fehler
+occurred = Een Fehler is uptreden
+report_message = Wenn du glรถรถvst, dat dat een Fehler mit Forgejo is, dann sรถรถk bidde up Codeberg na Gefallens of maak falls nรถdig een nejes Gefall op.
+
+[startpage]
+app_desc = Een sรผlvst-hostet Git-Deenst sรผnner Pien
+install = Licht to installeren
+lightweight = Lichtgewichtig
+lightweight_desc = Forgejo hett minne Minnstanfรถrderns un kann sรผlvst up eenem billigen Raspberry Pi lopen. Spaar diener Maschien Stroom!
+platform_desc = Forgejo lรถppt nawieselk up frejen Bedrievssysteemen as Linux un FreeBSD, un ok up verschedenen CPU-Architekturen. Kรถรถr ut, welke du am leevsten hest!
+license = Quellopen
+platform = รver all Plattformen
+license_desc = Gah un haal di Forgejo ! Maak bi uns mit , um dat Projekt noch beter to maken. Wees nich schรผchtern, een Bidrager to wesen!
+install_desc = Du kannst dat Programm eenfach up diener Plattfoorm utfรถhren , dat mit Docker verdeel, of dat as Paket halen.
+
+[home]
+uname_holder = Brukernaam of E-Mail-Adress
+switch_dashboard_context = Kontor-Umgeven wesseln
+my_repos = Repositoriums
+my_orgs = Vereenigungen
+view_home = %s wiesen
+filter_by_team_repositories = Na Klottjen-Repositoriums filtern
+feed_of = Schuuv vun ยป%sยซ
+show_archived = Archiveert
+show_only_unarchived = Wiest blots nich archiveert
+show_private = Privaat
+show_only_private = Wiest blots privaat
+show_only_public = Wiest blots publik
+show_only_archived = Wiest blots archiveert
+issues.in_your_repos = In dienen Repositoriums
+filter = Anner Filters
+show_both_archived_unarchived = Wiest archiveert un nicht archiveert
+show_both_private_public = Wiest publik un privaat
+
+[explore]
+repos = Repositoriums
+users = Brukers
+stars_one = %d Steern
+stars_few = %d Steerns
+forks_one = %d Gabel
+forks_few = %d Gabels
+go_to = Gah to
+code = Quelltext
+code_last_indexed_at = Tolest indizeert %s
+relevant_repositories_tooltip = Repositoriums, wat Gabels sรผnd of wat keene Themen, keen Bill un keen Beschrieven hebben, sรผnd versteekt.
+relevant_repositories = Blots Repositoriums vun Belang worden wiest; wies Resultaten sรผnner Filter .
+organizations = Vereenigungen
+
+[auth]
+create_new_account = Konto vermarken
+disable_register_prompt = Registreren is utknipst. Bidde kuntakteer de Sied-Chef.
+disable_register_mail = E-Mail-Utwiesen fรถr โt Registreren is utknipst.
+manual_activation_only = Kuntakteer de Sied-Chef, um dat Aktiveren oftosluten.
+remember_me = Deeses Gereed marken
+forgot_password = Passwoord vergeten?
+hint_register = Bruukst du een Konto? Registreer di nu.
+sign_up_button = Registreer di nu.
+sign_up_successful = Dien Konto is anleggt worden. Willkomen!
+must_change_password = Verneei dien Passwoord
+active_your_account = Aktiveer dien Konto
+account_activated = Konto is aktiveert worden
+prohibit_login = Konto is sperrt
+resent_limit_prompt = Du hest kรถrtens eerst eene Aktiverens-E-Mail anfordert. Bidde wacht 3 Menรผten un versรถรถk dat dann weer.
+change_unconfirmed_email_summary = รnner de E-Mail-Adress, waar de Aktiverens-E-Mail hen schickt wordt.
+send_reset_mail = Torรผgghalens-E-Mail schicken
+reset_password = Konto torรผgghalen
+invalid_code = Diene Utwies-Tahl is ungรผltig of avlopen.
+invalid_password = Dien Passwoord passt nich to de Passwoord, wat bruukt worden is, um dat Konto intorichten.
+reset_password_helper = Konto torรผgghalen
+reset_password_wrong_user = Du bรผst as %s anmellt, aver de Konto-Torรผgghalens-Verwies is fรถr %s dacht
+allow_password_change = Verlangen, dat de Bruker sien Passwoord รคnnert (anraadt)
+change_unconfirmed_email = Wenn du biโm Registreren de falske E-Mail-Adress angeven hest, kannst du se รผnnern รคnnern, un de Utwies-Naricht word in Stee daarvun to de neje Adress schickt.
+forgot_password_title = Passwoord vergeten
+hint_login = Hest du al een Konto? Nu anmellen!
+change_unconfirmed_email_error = Kann de E-Mail-Adress nich รคnnern: %v
+prohibit_login_desc = Dien Konto is daartegen sperrt worden, mit de Instanz to warken. Kuntakteer de Instanz-Chef, um weer Togang to kriegen.
+resend_mail = Klick hier, um de Aktiverens-E-Mail neei to schicken
+invalid_code_forgot_password = Diene Utwies-Tahl is ungรผltig of avlopen. Klick hier , um eene neje Sitzung to begรผnnen.
+verify = Utwiesen
+scratch_code = Eenmaalpasswoord
+use_scratch_code = Een Eenmaalpasswoord bruken
+login_userpass = Anmellen
+oauth_signup_submit = Konto ofsluten
+oauth_signin_tab = Mit eenem bestahn Konto verbinnen
+oauth_signin_submit = Konto verbinnen
+openid_connect_submit = Verbinnen
+authorize_application = Programm verlรถven
+authorize_application_created_by = Deeses Programm is vun %s maakt worden.
+authorize_title = ยป%sยซ verlรถven, up dien Konto totogriepen?
+authorization_failed = Verlรถรถv fehlslagen
+back_to_sign_in = Torรผgg tum Anmellen
+openid_register_title = Nejes Konto maken
+password_pwned_err = Kunn Anfraag to HaveIBeenPwned nich ofsluten
+password_too_short = Passwoord kann nich kรถrter as %d Bookstavens wesen.
+email_domain_blacklisted = Du kannst di nich mit deener E-Mail-Adress registreren.
+authorize_redirect_notice = Du worst na %s umleit, wenn du deeses Programm verlรถรถvst.
+oauth.signin.error.access_denied = De Anmell-Anfraag is oflehnt worden.
+last_admin = Du kannst de leste Chef nich wegdoon. Dat mutt tominnst eenen Chef geven.
+unauthorized_credentials = Anmell-Informatioon is falsk of avlopen. Bidde versรถรถk de รrder noch eenmaal of kiek fรถr mehr Informatioonen %s an
+twofa_scratch_token_incorrect = Dien Eenmaalpasswoord is falsk.
+sign_in_openid = Mit OpenID wiedermaken
+oauth_signup_tab = Nejes Konto vermarken
+oauth_signup_title = Nejes Konto ofsluten
+oauth_signin_title = Mell di an, um dat Konto-Verbinnen to verlรถven
+openid_connect_title = Mit eenem bestahn Konto verbinnen
+confirmation_mail_sent_prompt = Eene neje Utwiesens-E-Mail is an %s schickt worden. Um dat Registreren oftosluten, kiek bidde in dienen E-Mail-Ingang un folg de Verwies daarin in de anner %s. Wenn de E-Mail falsk is, kannst du di anmellen un eene neje Utwiesens-E-Mail an eene anner E-Mail-Adress verlangen.
+reset_password_mail_sent_prompt = Eene neje Utwiesens-E-Mail is an %s schickt worden. Um dat Konto-Torรผgghalen oftosluten, kiek bidde in dienen E-Mail-Ingang un folg de Verwies daarin in de anner %s.
+has_unconfirmed_mail = Moin %s, du hest eene nich utwiesen E-Mail-Adress (%s ). Wenn du keene Utwiesens-E-Mail kregen hest of eene neje bruukst, klick bidde up de Knoop unnern.
+non_local_account = Frรถmde Brukers kรถnen hรถr Passwoord nich dรถr de Forgejo-Internett-Brukerschnittstee vernejen.
+openid_register_desc = De utkรถรถrt OpenID-URI is unbekannt. Verbinn dat hier mit eenem nejen Konto.
+disable_forgot_password_mail = Konto-Torรผgghalen is utknipst, denn keene E-Mail is inricht. Bidde kuntakteer dienen Sied-Chef.
+authorize_application_description = Wenn du de Togang verlรถรถvst, kann dat all diene Konto-Informatioon lesen un schrieven, ok privaate Repos un Vereenigungen.
+authorization_failed_desc = Dat Anmellen is fehlslagen, denn wi hebben eene ungรผltig Anfraag funnen. Bidde kuntakteer de Chef vun de Programm, wat du anmellen willst.
+twofa_scratch_used = Du hest dien Eenmaalpasswoord bruukt. Du bรผst to de Twee-Faktooren-Instellens-Sied umleit worden, waar du 2FA utknipsen of een nejes Eenmaalpasswoord maken kannst.
+oauth.signin.error.temporarily_unavailable = Anmellen fehlslagen, denn de Anmell-Server is jรผรผst nich verfรถรถgbaar. Bidde versรถรถk dat naher noch eenmaal.
+twofa_passcode_incorrect = Diene Pass-Tahl is falsk. Wenn du diene Gereedskupp nich finnen kannst, bruuk tum Anmellen dien Eenmaalpasswoord.
+disable_forgot_password_mail_admin = Konto-Torรผgghalen is blots verfรถรถgbaar, wenn E-Mail inricht is. Bidde richt E-Mail in, um Konto-Torรผgghalen antoknipsen.
+oauth.signin.error = Biโm Verarbeiden vun de Anmellens-Anfraag is een Fehler uptreden. Wenn de Fehler wieder uptreddt, kuntakteer bidde de Sied-Chef.
+openid_connect_desc = De utkรถรถrt OpenID-URI is unbekannt. Verbinn dat hier mit eenem nejen Konto.
+openid_signin_desc = Giff diene OpenID-URI in. Toโn Bispรถรถl: alice.openid.example.org of https://openid.example.org/alice.
+password_pwned = Dat Passwoord, wat du utkรถรถrt hest, is up eener List vun klaut Passwoorden , wat tovรถr in publiken Datenbrรถken blootmaakt worden is. Bidde versรถรถk dat noch eenmaal mit eenem anner Passwoord, un รถverlegg di, of du deeses Passwoord ok annerwaar รคnnern willst.
+use_onetime_code = Een Eenmaal-Bruuk-Passwoord bruken
+
+[mail]
+view_it_on = Up %s wiesen
+activate_account = Bidde aktiveer dien Konto
+register_notify.text_1 = dat is diene Registrerens-Utwiesen-E-Mail fรถr %s!
+register_notify.text_3 = Wenn well anners deeses Konto fรถr di maakt hett, muttst du toeerst dien Passwoord setten .
+reset_password = Haal dien Konto torรผgg
+password_change.text_1 = Dat Passwoord fรถr dien Konto is jรผรผst รคnnert worden.
+totp_disabled.subject = TOTP is utknipst
+totp_disabled.text_1 = Tied-baseert Eenmaalpasswoord (TOTP) fรถr dien Konto is jรผรผst utknipst worden.
+totp_disabled.no_2fa = Keene anner 2FA-Aarden sรผnd mehr inricht, sodat dat nu nich mehr nรถdig is, dat du di mit 2FA to dien Konto anmellst.
+removed_security_key.subject = Een Sekerheids-Slรถtel is wegdaan worden
+removed_security_key.text_1 = Sekerheids-Slรถtel ยป%[1]sยซ is jรผรผst ut dienem Konto wegdaan worden.
+account_security_caution.text_1 = Wenn du dat weerst, kannst du deese E-Mail seker minnachten.
+account_security_caution.text_2 = Wenn du dat nich weerst, hett well in dien Konto inbroken. Bidde kuntakteer de Sied-Chefs.
+register_success = Registreren kumpleet
+issue_assigned.pull = @%[1]s hett di to Haalvรถrslag %[2]s in Repositorium %[3]s towiesen.
+issue.action.reopen = @%[1]s hett #%[2]d weer opmaakt.
+issue.action.merge = @%[1]s hett #%[2]d in %[3]s tosamenfรถhrt.
+issue.action.reject = @%[1]s hett um รnners fรถr deesen Haalvรถrslag beden.
+issue.action.ready_for_review = @%[1]s hett deesen Haalvรถrslag as klaar tum Nakieken markeert.
+issue.action.new = @%[1]s hett #%[2]d opmaakt.
+release.new.subject = %s in %s publik maakt
+release.note = Notiz:
+release.downloads = Runnerladen:
+repo.transfer.subject_to = %s will Repositorium ยป%sยซ to %s รถverdragen
+repo.transfer.to_you = du
+link_not_working_do_paste = Gaht de Verwies nich? Versรถรถk, dat to koperen un in de URL-Rieg vun dienem Browser intofรถgen.
+hi_user_x = Moin %s ,
+activate_account.text_2 = Bidde klick up deesen Verwies, um dien Konto binnen %s to aktiveren:
+admin.new_user.user_info = Bruker-Informatioon
+activate_email.text = Bidde klick up deesen Verwies, um diene E-Mail-Adress binnen %s uttowiesen:
+reset_password.text = Wenn du dat weerst, klick bidde up deesen Verwies, um dien Konto binnen %s torรผggtohalen:
+password_change.subject = Dien Passwoord is รคnnert worden
+issue_assigned.issue = @%[1]s hett di to Gefall %[2]s in Repositorium %[3]s towiesen.
+issue.action.push_1 = @%[1]s hett %[3]d Kommitteren to %[2]s schuven
+issue.action.push_n = @%[1]s hett %[3]d Kommitterens to %[2]s schuven
+activate_account.text_1 = Moin %[1]s , wees bedankt, dat du di up %[2]s registreert hest!
+issue.action.review_dismissed = @%[1]s hett dat leste Nakieken vun %[2]s fรถr deesen Haalvรถrslag ofseggt.
+issue.in_tree_path = In %s:
+reply = of anter deeser E-Mail stracks
+activate_email = Wies diene E-Mail-Adress ut
+admin.new_user.subject = Nejer Bruker %s jรผรผst registreert
+register_notify = Willkomen up %s
+register_notify.text_2 = Du kannst di to dien Konto mit dienem Brukernaam anmellen: %s
+primary_mail_change.text_1 = De Hรถรถvd-E-Mail-Adress vun dienem Konto is jรผรผst to %[1]s รคnnert worden. Dat heet, dat deese E-Mail-Adress keene E-Mail-Narichtens fรถr dien Konto mehr kriegen word.
+release.title = Titel: %s
+repo.collaborator.added.subject = %s hett di to %s as Mitarbeider hentofรถรถgt
+team_invite.text_2 = Bidde klick up deesen Verwies, um de Klottje bitotreden:
+issue.action.force_push = %[1]s hett de %[2]s vun %[3]s to %[4]s dwangsschuven.
+issue.action.review = @%[1]s hett รถver deesen Haalvรถrslag kommenteert.
+primary_mail_change.subject = Diene Hรถรถvd-E-Mail-Adress is รคnnert worden
+release.new.text = @%[1]s hett %[2]s in %[3]s publik maakt
+release.download.targz = Quelltext (TAR.GZ)
+repo.collaborator.added.text = Du bรผst as Mitarbeider to deesem Repositorium hentofรถรถgt worden:
+team_invite.text_1 = %[1]s hett di inladen, in de Klottje %[2]s in de Vereenigung %[3]s intotreden.
+removed_security_key.no_2fa = Keene anner 2FA-Aarden sรผnd mehr inricht, sodat dat nu nich mehr nรถdig is, dat du di mit 2FA to dien Konto anmellst.
+totp_enrolled.subject = Du hest TOTP as 2FA-Aard anknipst
+totp_enrolled.text_1.no_webauthn = Du hest jรผรผst TOTP fรถr dien Konto anknipst. Dat heet, dat du bi all tokรผnftig Anmellens TOTP as 2FA-Aard bruken muttst.
+totp_enrolled.text_1.has_webauthn = Du hest jรผรผst TOTP fรถr dien Konto anknipst. Dat heet, dat du bi all tokรผnftig Anmellens TOTP as 2FA-Aard of eets vun dien Sekerheids-Slรถtels bruken kannst.
+issue.x_mentioned_you = @%s hett di nรถรถmt:
+issue.action.approve = @%[1]s hett deesem Haalvรถrslag tostimmt.
+repo.transfer.subject_to_you = %s will Repositorium ยป%sยซ to di รถverdragen
+team_invite.text_3 = Wahrschau: Deese Inladen weer fรถr %[1]s dacht. Wenn du deese Inladen nich verwacht hest, kannst du deese E-Mail minnachten.
+issue.action.close = @%[1]s hett #%[2]d dichtmaakt.
+repo.transfer.body = Um dat antonehmen of oftolehnen, besรถรถk %s, of ignoreer dat eenfach.
+release.download.zip = Quelltext (ZIP)
+team_invite.subject = %[1]s hett di inladen, in de Vereenigung %[2]s intotreden
+admin.new_user.text = Bidde klick hier , um deesen Bruker vun de Chef-Paneel to verwalten.
+
+[modal]
+no = Nee
+confirm = Utwiesen
+cancel = Ofbreken
+yes = Jau
+modify = Vernejen
+
+[form]
+UserName = Brukernaam
+FullName = Kumpleter Naam
+Pronouns = Pronomens
+Biography = Levensloop
+Website = Internett-Sied
+Location = Stee
+RepoName = Repositoriums-Naam
+TeamName = Klottjen-Naam
+AuthName = Verlรถรถv-Naam
+AdminEmail = Chef-E-Mail
+AccessToken = Togang-Teken
+CommitMessage = Kommitteren-Naricht
+TreeName = Dateipadd
+SSPISeparatorReplacement = Trenner
+SSPIDefaultLanguage = Normaalspraak
+email_error = ` is keene gรผltige E-Mail-Adress.`
+captcha_incorrect = De CAPTCHA-Tahl is falsk.
+username_been_taken = Deeser Brukernaam word al bruukt.
+To = Twieg-Naam
+CommitChoice = Kommitteren-Utkรถรถr
+git_ref_name_error = ` mutt een gรผltig Git-Beteekner-Naam wesen.`
+include_error = ` mutt de Text ยป%sยซ enthollen.`
+password_not_match = De Passwoorden passen nich.
+Password = Passwoord
+Content = Inholl
+require_error = ` kann nich leeg wesen.`
+alpha_dash_error = ` sall nix as alphanumerisk Bookstavens un Binnestrekens (ยป-ยซ) un Unnerstrekens (ยป_ยซ) enthollen.`
+size_error = ` mutt de Grรถtt %s hebben.`
+glob_pattern_error = ` Glob-Muster is ungรผltig: %s.`
+Email = E-Mail-Adress
+Retype = Passwoord utwiesen
+CommitSummary = Kommitteren-Tosamenfaten
+Description = Beschrieven
+NewBranchName = Nejer Twieg-Naam
+min_size_error = ` mutt tominnst %s Bookstavens enthollen.`
+regex_pattern_error = ` Regex-Muster is ungรผltig: %s.`
+username_error_no_dots = ` kann nix as alphanumerisk Bookstavens (ยป0-9ยซ, ยปa-zยซ, ยปA-Zยซ) un Binnestrekens (ยป-ยซ) un Unnerstrekens (ยป_ยซ) enthollen. โt kann nich mit nich-alphanumerisk Bookstavens begรผnnen of ennen, un โt dรผรผr nich twee nich-alphanumerisk Bookstavens stracks achternanner geven.`
+lang_select_error = Kรถรถr eene Spraak ut de List ut.
+alpha_dash_dot_error = ` sall nix as alphanumerisk Bookstavens un Binnestrekens (ยป-ยซ), Unnerstrekens (ยป_ยซ) un Punkten (ยป.ยซ) enthollen.`
+max_size_error = ` dรผรผr nich mehr as %s Bookstavens enthollen.`
+url_error = `ยป%sยซ is keene gรผltige URL.`
+username_error = ` kann nix as alphanumerisk Bookstavens (ยป0-9ยซ, ยปa-zยซ, ยปA-Zยซ) un Binnestrekens (ยป-ยซ), Unnerstrekens (ยป_ยซ) un Punkten (ยป.ยซ) enthollen. โt kann nich mit nich-alphanumerisk Bookstavens begรผnnen of ennen, un โt dรผรผr nich twee nich-alphanumerisk Bookstavens stracks achternanner geven.`
+invalid_group_team_map_error = ` Towiesen is ungรผltig: %s`
+unknown_error = Unbekannter Fehler:
+repo_name_been_taken = De Repositoriums-Naam word al bruukt.
+username_change_not_local_user = Frรถmde Brukers dรผren hรถr Brukernaam nich รคnnern.
+repository_files_already_exist.adopt = Dateien fรถr deeses Repositorium gifft โt al un kann blots รถvernohmen worden.
+repository_files_already_exist.delete = Dateien fรถr deeses Repositorium gifft โt al. Du muttst se lรถsken.
+password_uppercase_one = Tominnst een Grootbookstaav
+password_digit_one = Tominnst eene Tahl
+enterred_invalid_repo_name = De Repositoriums-Naam, wat du ingeven hest, is falsk.
+enterred_invalid_org_name = De Vereenigungs-Naam, wat du ingeven hest, is falsk.
+enterred_invalid_owner_name = De neje Eegner-Naam is nich gรผltig.
+user_not_exist = De Bruuker gifft โt nich.
+team_not_exist = De Klottje gifft โt nich.
+unset_password = De Anmell-Bruker hett dat Passwoord nich sett.
+last_org_owner = Du kannst nich de leste Bruker ut de ยปEegnersยซ-Klottje wegdoon. Eene Vereenigung mutt alltieden tominnst eenen Eegner hebben.
+cannot_add_org_to_team = Eene Vereenigung kann nich as Liddmaat hentofรถรถgt worden.
+organization_leave_success = Du hest de Vereenigung %s verlaten.
+invalid_ssh_key = Kann dienen SSH-Slรถtel nich utwiesen: %s
+repository_force_private = Dwang-Privaat is anknipst: Privaate Repositoriums kรถnen nich publik maakt worden.
+repository_files_already_exist.adopt_or_delete = Dateien fรถr deeses Repositorium gifft โt al. Nehm se an of lรถske se.
+username_password_incorrect = Brukernaam of Passwoord is falsk.
+repository_files_already_exist = Dateien fรถr deeses Repositorium gifft โt al. Kuntakteer de Systeemchef.
+email_invalid = De E-Mail-Adress is ungรผltig.
+password_special_one = Tominnst een Sรผnnerbookstaav (Punkte, Klammern, Anfรถhrens-Tekens of so wat)
+org_name_been_taken = De Vereenigungs-Naam word al bruukt.
+team_name_been_taken = De Klottjen-Naam word al bruukt.
+team_no_units_error = Verlรถรถv Togang to tominnst eenem Repositoriums-Deel.
+email_been_used = De E-Mail-Adress word al bruukt.
+enterred_invalid_password = Dat Passwoord, wat du ingeven hest, is falsk.
+password_complexity = Passwoord is nich kumplizeert genoog:
+invalid_gpg_key = Kann dienen GPG-Slรถtel nich utwiesen: %s
+openid_been_used = De OpenID-Adress ยป%sยซ word al bruukt.
+password_lowercase_one = Tominnst een Kleenbookstaav
+duplicate_invite_to_team = De Bruker is al as Liddmaat inladen.
+unsupported_login_type = De Anmell-Aard unnerstรผtt dat Konto-Lรถsken nich.
+invalid_ssh_principal = Ungรผltiger Hรถรถvdmann: %s
+unable_verify_ssh_key = Kann de SSH-Slรถtel nich utwiesen, bidde kiek noch eenmaal, dat daar keen Fehler drin is.
+auth_failed = Verlรถven fehlslagen: %v
+still_own_repo = Dien Konto is een Eegner vun een of mehr Repositoriums, lรถske of รถverdraag se eerst.
+still_own_packages = Dien Konto is een Eegner vun een of mehr Paketen, lรถske se eerst.
+org_still_own_repo = Deese Vereenigung is een Eegner vun een of mehr Repositoriums, lรถske of รถverdraag se eerst.
+target_branch_not_exist = Enn-Twieg gifft โt nich.
+admin_cannot_delete_self = Du kannst di nich sรผlvst lรถsken, wenn du een Chef bรผst. Lรถske eerst diene Chef-Rechten.
+required_prefix = Ingaav mutt mit ยป%sยซ begรผnnen
+must_use_public_key = Du hest eenen privaaten Slรถtel ingeven. Bidde laad dienen privaaten Slรถtel nienich elkeenwaar up. Bruuk in Stee daarvun dienen publiken Slรถtel.
+still_has_org = Dien Konto is een Liddmaat in een of mehr Vereenigungen, verlaat se eerst.
+org_still_own_packages = Deese Vereenigung is een Eegner vun een of mehr Paketen, lรถske se eerst.
+PayloadUrl = Ladung-URL
+visit_rate_limit = Frรถmd-Togriep hett Togrieps-Begrenz troffen.
+2fa_auth_required = Frรถmd-Togriep bruukt Twee-Faktooren-Anmellen.
+email_domain_is_not_allowed = De Domรครคn vun de Bruker-E-Mail-Adress %s passt nich mit EMAIL_DOMAIN_ALLOWLIST of EMAIL_DOMAIN_BLOCKLIST. Wees wiss, dat du de E-Mail-Adress recht sett hest.
+username_claiming_cooldown = De Brukernaam kann nich nohmen worden, denn siene Ofkรถhl-Dรผรผr is noch nich vรถrbi. 't kann am %[1]s nohmen worden.
+
+[user]
+change_avatar = รnner dien Kontobill โฆ
+joined_on = Am %s bitreden
+repositories = Repositoriums
+activity = Publikes Doon
+followers.title.one = Nagaher
+followers.title.few = Nagahers
+following.title.one = Gaht na
+followers_one = %d Nagaher
+followers_few = %d Nagahers
+following_one = gaht %d na
+following_few = gaht %d na
+follow = Nagahn
+unfollow = Nich mehr nagahn
+block_user = Bruker blockeren
+starred = Repositoriums mit Steernen
+watched = Beluurt Repositoriums
+code = Quelltext
+projects = Projekten
+following.title.few = Gaht na
+overview = รversicht
+block = Blockeren
+unblock = Nich mehr blockeren
+user_bio = Levensloop
+email_visibility.limited = All anmellt Brukers kรถnen diene E-Mail-Adress sehn
+show_on_map = Deese Stee up eener Kaart wiesen
+settings = Bruker-Instellens
+disabled_public_activity = Deeser Bruker hett dat publike Ankieken vun de Doon utknipst.
+form.name_chars_not_allowed = Brukernaam ยป%sยซ enhollt ungรผltig Bookstavens.
+form.name_pattern_not_allowed = Dat Muster ยป%sยซ is in eenem Brukernaam nich verlรถรถvt.
+form.name_reserved = De Brukernaam ยป%sยซ is vรถrbehollen.
+block_user.detail = Bidde wees wiss, dat dat Blockeren vun eenem Bruker anner Resultaten hett, nรคmlich:
+block_user.detail_1 = Jo wordt elkeen anner nich mehr nagahn un eenanner ok nich mehr nagahn kรถnen.
+block_user.detail_2 = Deeser Bruker kann nich mit dienen Repositoriums warken, un ok nich mit Gefallens un Kommentaren, wat to maakt hest.
+block_user.detail_3 = Jo kรถรถnt eenanner nich as Repositoriums-Mitarbeiders hentofรถgen.
+follow_blocked_user = Du kannst deesem Bruker nich nagahn, denn du hest deesen Bruker blockeert of deeser Bruker hett di blockeert.
+public_activity.visibility_hint.self_public = Dien Doon is fรถr elkeen sichtbaar, blots nich dat Warken in privaaten Steden. Inrichten .
+public_activity.visibility_hint.admin_public = Dien Doon is fรถr elkeen sichtbaar, aver as Chef kannst du ok dat Warken in privaaten Steden sehn.
+public_activity.visibility_hint.self_private = Blots du un de Instanz-Chefs kรถnen dien Doon sehn. Inrichten .
+public_activity.visibility_hint.admin_private = Du kannst deeses Doon sehn, um dat, dat du een Chef bรผst, aver de Bruker will, dat dat privaat blievt.
+public_activity.visibility_hint.self_private_profile = Blots du un de Instanz-Chefs kรถnen dien Doon sehn, denn dien Profil is privaat. Inrichten .
+
+[settings]
+profile = Profil
+security = Sekerheid
+repos = Repositoriums
+delete = Konto lรถsken
+organization = Vereenigungen
+uid = UID
+webauthn = Twee-Faktooren-Anmellen (Sekerheids-Slรถtels)
+blocked_users = Blockeert Brukers
+public_profile = Publikes Profil
+location_placeholder = Deel waar du umslags bรผst mit Annerns
+pronouns = Pronomens
+pronouns_custom = Eegene
+update_theme = Thema รคnnern
+update_profile = Profil vernejen
+update_language_success = Spraak is verneeit worden.
+update_profile_success = Dien Profil is verneeit worden.
+change_username_prompt = Wahrschau: Wenn du dienen Brukernaam รคnnerst, รคnnert sik ok diene Konto-URL.
+change_username_redirect_prompt = De olle Brukernaam leit daarhen um, bit well anners hรผm nimmt.
+continue = Wiedermaken
+cancel = Ofbreken
+language = Spraak
+language.title = Normaalspraak
+language.localization_project = Hรผlp uns, Forgejo in diene Spraak to รถversetten! Mehr unnerhรถren .
+hints = Wenken
+update_hints = Wenken vernejen
+update_hints_success = Wenken sรผnd verneeit worden.
+hidden_comment_types = Verburgen Kommentaar-Aarden
+hidden_comment_types.issue_ref_tooltip = Kommentaren, waar de Bruker de Twieg/Mark, wat mit deesem Gefall verbunnen is, รคnnert hett
+comment_type_group_branch = Twieg
+comment_type_group_time_tracking = Tied-Erfaten
+comment_type_group_pull_request_push = Kommitterens hentofรถรถgt
+comment_type_group_project = Projekt
+comment_type_group_issue_ref = Gefall-Nรถmen
+saved_successfully = Diene Instellens sรผnd sekert worden.
+privacy = Privaatheid
+lookup_avatar_by_mail = Kontobill vun E-Mail-Adress sรถken
+enable_custom_avatar = Eegen Kontobill bruken
+choose_new_avatar = Nejes Kontobill utkรถren
+update_avatar = Kontobill vernejen
+delete_current_avatar = Stedenwies Kontobill lรถsken
+uploaded_avatar_is_too_big = De upladen Dateigrรถtt ((%d KiB) is mehr as verlรถรถvt (%d KiB).
+update_avatar_success = Dien Kontobill is verneeit worden.
+change_password = Passwoord รคnnern
+update_password = Passwoord vernejen
+old_password = Stedenwies Passwoord
+new_password = Nejes Passwoord
+theme_desc = Deeses Thema word in de Brukerschnittstee bruukt, wenn du anmellt bรผst.
+primary = Hรถรถvd
+activated = Aktiveert
+requires_activation = Mutt aktiveert worden
+primary_email = As Hรถรถvd setten
+activations_pending = Aktiveren staht ut
+delete_email = Wegdoon
+email_deletion = E-Mail-Adress wegdoon
+add_new_openid = Neje OpenID-URI hentofรถgen
+add_email = E-Mail-Adress hentofรถgen
+add_openid = OpenID-URI hentofรถgen
+keep_email_private = E-Mail-Adress verbargen
+manage_gpg_keys = GPG-Slรถtels verwalten
+ssh_principal_been_used = Deeser Hรถรถvdmann is al to de Server hentofรถรถgt worden.
+gpg_key_id_used = Eenen publiken GPG-Slรถtel mit de sรผlve ID gifft โt al.
+gpg_token_signature = Beschรผtt GPG-Unnerschrift
+key_signature_gpg_placeholder = Begรผnnt mit ยป-----BEGIN PGP SIGNATURE-----ยซ
+ssh_key_verified = Utwiest Slรถtel
+ssh_key_verify = Utwiesen
+ssh_token = Teken
+ssh_token_help = So kannst du de Unnerschrift maken:
+ssh_token_signature = Beschรผtt SSH-Unnerschrift
+key_signature_ssh_placeholder = Begรผnnt mit ยป-----BEGIN SSH SIGNATURE-----ยซ
+verify_ssh_key_success = SSH-Slรถtel ยป%sยซ is utwiest worden.
+key_id = Slรถtel-ID
+principal_content = Inholl
+add_gpg_key_success = De GPG-Slรถtel ยป%sยซ is hentofรถรถgt worden.
+delete_key = Wegdoon
+ssh_key_deletion = SSH-Slรถtel wegdoon
+ssh_principal_deletion_success = De Hรถรถvdmann is wegdaan worden.
+orgs = Vereenigungen
+biography_placeholder = Vertell annern een bietje wat รถver di! (Markdown word unnerstรผtt)
+change_username = Dien Brukernaam is รคnnert worden.
+ui = Thema
+additional_repo_units_hint_description = Wiest eenen Wenk ยปMehr anknipsenยซ fรถr Repositoriums, in wat nich all verfรถรถgbaar Delen anknipst sรผnd.
+comment_type_group_label = Vermark
+comment_type_group_title = Titel
+keep_activity_private = Doon vun de Profil-Sied verbargen
+appearance = Utsehn
+twofa = Twee-Faktooren-Anmellen (TOTP)
+update_language_not_found = Spraak ยป%sยซ is nich verfรถรถgbaar.
+hidden_comment_types.ref_tooltip = Kommentaren, waar deeses Gefall vun eenem anner Gefall/Kommitteren/โฆ nรถรถmt worden is
+comment_type_group_assignee = Towiesen
+comment_type_group_deadline = Anstahn
+password_change_disabled = Frรถmde Brukers kรถnen hรถr Passwoord nich dรถr de Forgejo-Internett-Brukerschnittstee vernejen.
+manage_openid = OpenID-Adressen
+openid_deletion_desc = Wenn du deese OpenID-Adress ut dienem Konto wegdoost, kannst du di nich mehr daarmit anmellen. Wiedermaken?
+add_new_email = E-Mail-Adress hentofรถgen
+applications = Programmen
+full_name = Kumpleter Naam
+update_language = Spraak รคnnern
+update_user_avatar_success = Dat Kontobill vum Bruker is verneeit worden.
+ssh_gpg_keys = SSH- un GPG-Slรถtels
+password_incorrect = De stedenwies Passwoord is falsk.
+manage_emails = E-Mail-Adressen verwalten
+activate_email = Aktiveren schicken
+email_deletion_success = De E-Mail-Adress is wegdaan worden.
+uploaded_avatar_not_a_image = De upladen Datei is keen Bill.
+openid_deletion_success = De OpenID-Adress is wegdaan worden.
+openid_desc = OpenID lett di dat Anmellen to eenem frรถmden Anbeder utlagern.
+account = Konto
+password = Passwoord
+avatar = Kontobill
+website = Internett-Sied
+pronouns_unspecified = Nich angeven
+additional_repo_units_hint = Vรถrslagen, mehr Repositorium-Delen antoknipsen
+comment_type_group_reference = Nรถmen
+comment_type_group_milestone = Marksteen
+comment_type_group_lock = Slutens-Tostand
+comment_type_group_review_request = Nakiekens-Anfraag
+keep_activity_private.description = Dien publikes Doon kann blots vun di un de Instanz-Chefs sehn worden.
+ssh_key_deletion_success = De SSH-Slรถtel is wegdaan worden.
+location = Stee
+language.description = Deese Spraak word in deenem Konto sekert un na de Anmellen toeerst bruukt.
+comment_type_group_dependency = Ofhangen
+retype_new_password = Nejes Passwoord utwiesen
+change_password_success = Dien Passwoord is verneeit worden. Bruuk vun nu an tum Anmellen dat neje Passwoord.
+manage_themes = Normaalthema
+theme_update_success = Dien Thema is verneeit worden.
+theme_update_error = Dat utkรถรถrt Thema gifft โt nich.
+add_new_principal = Hรถรถvdmann hentofรถgen
+ssh_key_name_used = Dien Konto hett al eenen SSH-Slรถtel mit de sรผlven Naam.
+gpg_key_verified = Utwiest Slรถtel
+subkeys = Unnerslรถtels
+key_content = Inholl
+add_key_success = De SSH-Slรถtel ยป%sยซ is hentofรถรถgt worden.
+gpg_key_deletion = GPG-Slรถtel wegdoon
+manage_ssh_principals = SSH-Zertifikaat-Hรถรถvdmannen verwalten
+openid_deletion = OpenID-Adress wegdoon
+add_email_success = De neje E-Mail-Adress is hentofรถรถgt worden.
+email_preference_set_success = E-Mail-Instellen is sett worden.
+add_openid_success = De neje OpenID-Adress is hentofรถรถgt worden.
+ssh_key_been_used = Deeser SSH-Slรถtel is al to de Server hentofรถรถgt worden.
+verify_gpg_key_success = GPG-Slรถtel ยป%sยซ is utwiest worden.
+manage_ssh_keys = SSH-Slรถtels verwalten
+add_key = Slรถtel hentofรถgen
+gpg_key_verify = Utwiesen
+gpg_token = Teken
+gpg_token_help = So kannst du de Unnerschrift maken:
+key_name = Slรถtel-Naam
+gpg_key_deletion_success = De GPG-Slรถtel is wegdaan worden.
+key_content_gpg_placeholder = Begรผnnt mit ยป-----BEGIN PGP PUBLIC KEY BLOCK-----ยซ
+key_content_ssh_placeholder = Begรผnnt mit ยปssh-ed25519ยซ, ยปssh-rsaยซ, ยปecdsa-sha2-nistp256ยซ, ยปecdsa-sha2-nistp384ยซ, ยปecdsa-sha2-nistp521ยซ, ยปsk-ecdsa-sha2-nistp256@openssh.comยซ of ยปsk-ssh-ed25519@openssh.comยซ
+gpg_key_matched_identities = Passt up Identitรคten:
+gpg_token_required = Du muttst eene Unnerschrifft fรถr dat Teken unnern angeven
+gpg_invalid_token_signature = De angeven GPG-Slรถtel, Unnerschrift un Teken passen nich tonanner of dat Teken is verollt.
+ssh_invalid_token_signature = De angeven SSH-Slรถtel, Unnerschrift of Teken passen nich tonanner of dat Teken is verollt.
+add_principal_success = De SSH-Zertifikaat-Hรถรถvdmann ยป%sยซ is hentofรถรถgt worden.
+gpg_key_deletion_desc = Wenn du eenen GPG-Slรถtel wegdoost, sรผnd Kommitterens, wat daarmit unnerschreven sรผnd, nich mehr utwiest. Wiedermaken?
+added_on = Am %s hentofรถรถgt
+valid_until_date = Gรผltig bit %s
+no_activity = In de lesten Tied nich bruukt
+can_read_info = Lesen
+key_state_desc = Deeser Slรถtel is in de lesten 7 Dagen bruukt worden
+show_openid = Im Profil wiesen
+hide_openid = Im Profil verbargen
+ssh_externally_managed = Deeser SSH-Slรถtel word fรถr deesen Bruker frรถmd verwalt
+manage_access_token = Togang-Tekens
+generate_new_token = Nejes Teken maken
+token_name = Teken-Naam
+access_token_deletion = Togang-Teken lรถsken
+delete_token_success = Dat Teken is lรถsket worden. Programmen, wat dat bruken, kรถnen nich mehr up dien Konto togriepen.
+repo_and_org_access = Togang to Repositoriums un Vereenigungen
+permissions_public_only = Blots publik
+permissions_access_all = All (publik, privaat un begrenzt)
+select_permissions = Verlรถรถvnissen utkรถren
+permission_no_access = Keen Togang
+permission_read = Lesen
+permission_write = Lesen un Schrieven
+permissions_list = Verlรถรถvnissen:
+at_least_one_permission = Du muttst tominnst eene Verlรถรถvnis utkรถren, um een Teken to maken
+manage_oauth2_applications = OAuth2-Programmen verwalten
+edit_oauth2_application = OAuth2-Programm bewarken
+remove_oauth2_application = OAuth2-Programm wegdoon
+gpg_key_verified_long = Slรถtel is mit eenem Teken utwiest worden un kann bruukt worden, um Kommitterens uttowiesen, wat up elkeen aktiveert E-Mail-Adress fรถr deesen Bruker passen, un daarto ok fรถr de Identitรคten, up wat deeser Slรถtel passt.
+valid_forever = Ewig gรผltig
+principal_state_desc = Deeser SSH-Zertifikaat-Hรถรถvdmann is in de lesten 7 Dagen bruukt worden
+token_state_desc = Deeses Teken is in de lesten 7 Dagen bruukt worden
+ssh_disabled = SSH is utknipst
+ssh_key_verified_long = Slรถtel is mit eenem Teken utwiest worden un kann bruukt worden, um Kommitterens uttowiesen, wat up elkeen aktiveert E-Mail-Adress fรถr deesen Bruker passen.
+tokens_desc = Deese Tekens geven รถver de Forgejo-API Togang to dienem Konto.
+ssh_token_required = Du muttst eene Unnerschrifft fรถr dat Teken unnern angeven
+ssh_key_deletion_desc = Wenn du eenen SSH-Slรถtel wegdoost, kann he nich mehr up dien Konto togriepen. Wiedermaken?
+gpg_no_key_email_found = Deeser GPG-Slรถtel passt up keene aktiveert E-Mail-Adress, wat mit dien Konto verbunnen is. He kann doch hentofรถรถgt worden, wenn du dat angeven Teken unnerschriffst.
+gpg_key_matched_identities_long = De Identitรคten, wat in deesem Slรถtel binnen liggen, passen up deese aktiveert E-Mail-Adressen fรถr deesen Bruker. Kommitterens, wat up deese E-Mail-Adressens passen, kรถnen mit deesem Slรถtel utwiest worden.
+ssh_principal_deletion = SSH-Zertifikaat-Hรถรถvdmann wegdoon
+can_write_info = Schrieven
+generate_token = Teken maken
+generate_token_name_duplicate = %s word al as Programm-Naam bruukt. Bidde bruuk eenen nejen.
+ssh_principal_deletion_desc = Wenn du eenen SSH-Zertifikaat-Hรถรถvdmann wegdoost, kann he nich mehr up dien Konto togriepen. Wiedermaken?
+last_used = Tolest bruukt am
+ssh_signonly = SSH is stedenwies utknipst, sodat deese Slรถtels blots tum Utwiesen vun de Kommitterens-Unnerschrift bruukt worden.
+generate_token_success = Dien nejes Teken is maakt worden. Kopeer dat nu, denn dat word nich noch eenmaal wiest.
+delete_token = Lรถsken
+access_token_deletion_desc = Wenn du een Teken lรถskest, kรถnen Programmen, wat dat bruken, nich mehr up dien Konto togriepen. Dat kann man nich torรผggnehmen. Wiedermaken?
+oauth2_applications_desc = OAuth2-Programmen verlรถรถvt dienen Frรถmdprogrammen, Brukers in deeser Forgejo-Instanz seker antomellen.
+remove_oauth2_application_desc = Wenn du een OAuth2-Programm wegdoost, word sien Togriep to all unnerschreven Togang-Tekens torรผggnohmen. Wiedermaken?
+create_oauth2_application_success = Du hest een nejes OAuth2-Programm hentofรถรถgt.
+oauth2_application_name = Programm-Naam
+save_application = Sekern
+oauth2_client_id = Klient-ID
+oauth2_client_secret = Klient-Geheemst
+oauth2_regenerate_secret = Geheemst neei maken
+oauth2_application_remove_description = Wenn du een OAuth2-Programm wegdoost, kann โt nich mehr up anmellt Brukerkonten in deeser Instanz togriepen. Wiedermaken?
+authorized_oauth2_applications = Anmellt OAuth2-Programmen
+revoke_key = Torรผggnehmen
+revoke_oauth2_grant = Togriep torรผggnehmen
+revoke_oauth2_grant_description = Wenn du Togriep fรถr deeses Frรถmdprogramm torรผgggnimmst, kann deeses Programm nich mehr up diene Daten togriepen. Willst du dat wรผrrelk?
+revoke_oauth2_grant_success = Togriep torรผggnohmen.
+twofa_disable = Twee-Faktooren-Anmellen utknipsen
+twofa_scratch_token_regenerate = Eenmaal-Bruuk-Torรผgghalens-Slรถtel neei maken
+twofa_disable_note = Du kannst dat Twee-Faktooren-Anmellen wenn nรถdig utknipsen.
+twofa_disabled = Twee-Faktooren-Anmellen is utknipst worden.
+scan_this_image = Bekiek deeses Bill mit dienem Anmellens-Programm:
+remove_oauth2_application_success = Dat Programm is wegdaan worden.
+create_oauth2_application = Een nejes OAuth2-Programm hentofรถgen
+update_oauth2_application_success = Du hest dat OAuth2-Programm verneeit.
+create_oauth2_application_button = Nejes Programm
+oauth2_redirect_uris = Umleit-URIs. Bidde schriev elkeen URI up eene neje Rieg.
+twofa_disable_desc = Wenn du Twee-Faktooren-Anmellen utknipst, is dien Konto minner seker. Wiedermaken?
+oauth2_regenerate_secret_hint = Geheemst verloren?
+oauth2_client_secret_hint = Dat Geheemst word nich weer wiest, nadeem du deese Sied verlettst of neei laadst. Bidde wees wiss, dat du โt sekert hest.
+oauth2_application_edit = Bewarken
+twofa_is_enrolled = Dien Konto hett stedenwies Twee-Faktooren-Anmellen anknipst .
+twofa_enroll = Twee-Faktooren-Anmellen anknipsen
+twofa_not_enrolled = Dien Konto hett stedenwies keen Twee-Faktooren-Anmellen anknipst.
+oauth2_application_create_description = OAuth2-Programmen gifft dienen Frรถmdprogrammen Togriep up Brukers in deeser Instanz.
+authorized_oauth2_applications_description = Du hest in deenem eegenen Forgejo-Konto deesen Frรถmdprogrammen Togriep geven. Bidde nimm Togriep fรถr Programmen, wat nich mehr bruukt worden, torรผgg.
+twofa_scratch_token_regenerated = Dien Eenmaal-Bruuk-Torรผgghalens-Slรถtel is nu %s. Bewahr dat an eener sekeren Stee up, denn dat word nich noch eenmaal wiest.
+regenerate_scratch_token_desc = Wenn du dienen Torรผgghalens-Slรถtel verloren of al tum Anmellen bruukt hest, kannst du โt hier torรผggsetten.
+twofa_failed_get_secret = Kunn dat Geheemst nich halen.
+webauthn_register_key = Sekerheids-Slรถtel hentofรถgen
+webauthn_nickname = Spitznaam
+webauthn_delete_key_desc = Wenn du eenen Sekerheids-Slรถtel wegdoost, kannst du di nich mehr daarmit anmellen. Wiedermaken?
+link_account = Konto verbinnen
+remove_account_link_success = Dat verbunnt Konto is wegdaan worden.
+repos_none = Du bรผst keen Eegner vun elkeen Repositoriums.
+orgs_none = Du bรผst keen Liddmaat in elkeen Vereenigungen.
+blocked_users_none = โt gifft keene blockeerten Brukers.
+delete_account = Dien Konto lรถsken
+delete_account_title = Brukerkonto lรถsken
+delete_account_desc = Willst du wรผrrelk deeses Brukerkonto fรถr all Tieden lรถsken?
+email_notifications.enable = E-Mail-Narichtens anknipsen
+email_notifications.onmention = Blots biโm Nรถmen benarichtigen
+email_notifications.submit = E-Mail-Instellen setten
+visibility.limited = Begrenzt
+blocked_since = Blockeert siet %s
+user_block_success = De Bruker is nu blockeert.
+webauthn_alternative_tip = Du willst villicht noch eene anner Twedes-Anmellen-Aard inrichten.
+manage_account_links_desc = Deese frรถmden Konten sรผnd mit dienem Forgejo-Konto verbunnen.
+remove_account_link = Verbunnen Konto wegdoon
+remove_account_link_desc = Wenn du een verbunnen Konto wegdoost, hett โt keenen Togriep mehr to dienem Forgejo-Konto. Wiedermaken?
+then_enter_passcode = Un giff de Pass-Tahl in, wat dat Programm wiest:
+webauthn_delete_key = Sekerheids-Slรถtel wegdoon
+webauthn_key_loss_warning = Wenn du diene Sekerheids-Slรถtels verlรผst, verlรผst du ok Togriep to dien Konto.
+manage_account_links = Verbunnt Konten
+hooks.desc = Fรถรถg Internett-Hakens hento, wat fรถr all Repositoriums , vun wat du een Eegner bรผst, utlรถรถst worden.
+email_notifications.andyourown = Un ok fรถr diene eegenen Narichtens
+visibility = Bruker-Sichtbaarkeid
+visibility.limited_tooltip = Blots anmellt Brukers kรถnen โt sehn
+visibility.private = Privaat
+user_unblock_success = De Bruker is nu nich mehr blockeert.
+or_enter_secret = Of giff dat Geheemst in: %s
+passcode_invalid = De Pass-Tahl is falsk. Versรถรถk dat bidde noch eenmaal.
+twofa_enrolled = Twee-Faktooren-Anmellen is fรถr dien Konto nu inricht. Bewahr dienen Eenmaal-Bruuk-Toorรผgghalens-Slรถtel (%s) an eener sekeren Stee up, denn dat word nich noch eenmaal wiest.
+delete_prompt = Dat lรถsket dien Brukerkonto fรถr all Tieden. Dat KANN NICH torรผggnohmen worden.
+visibility.private_tooltip = Blots de Liddmaten vun Vereenigungen, waar du Liddmaat bรผst, kรถnen โt sehn
+visibility.public = Publik
+delete_with_all_comments = Dien Konto is junger as %s. Um Spรถรถk-Kommentaren to vermieden, worden all Kommentaren up Gefallens un HVs daar ok mit lรถsket.
+confirm_delete_account = Lรถsken utwiesen
+email_notifications.disable = Nich รถver E-Mail benarichtigen
+visibility.public_tooltip = Elkeen kann โt sehen
+password_username_disabled = Frรถmde Brukers kรถnen hรถr Brukernaam nich รคnnern. Bidde kuntakteer dienen Sied-Chef fรถr mehr Informatioonen.
+profile_desc = รver di
+hidden_comment_types_description = Kommentaar-Arden, wat hier utkรถรถrt sรผnd, worden in Gefall-Sieden nich wiest. Wenn du toโn Bispรถรถl ยปVermarkยซ utkรถรถrst, worden all de ยปโบBrukerโน hett โบVermarkโน hentofรถรถgt/wegdaanยซ-Kommentaren wegdaan.
+email_desc = Diene Hรถรถvd-E-Mail-Adress word fรถr Narichtens, Passwoord-Torรผgghalen un, wenn se nich verburgen is, Git-Aktioonen รถver โt Internett bruukt.
+can_not_add_email_activations_pending = Een Aktiveren staht noch ut. Wenn du eene neje E-Mail-Adress hentofรถgen willst, versรถรถk dat in een paar Menรผten noch eenmaal.
+email_deletion_desc = De E-Mail-Adress un daarmit verbunnen Informatioon word ut dienem Konto wegdaan. Git-Kommitterens vun deeser E-Mail-Adress worden nich รคnnert. Wiedermaken?
+principal_desc = Deese SSH-Zertifikaat-Hรถรถvdmannen sรผnd mit dienem Konto verbunnen un geven kumpleten Togriep up diene Repositoriums.
+add_email_confirmation_sent = Eene Utwiesens-E-Mail is an ยป%sยซ schickt worden. Um diene E-Mail-Adress uttowiesen, kiek bidde in dienen E-Mail-Ingang un folg de Verwies daarin in de anner %s.
+ssh_desc = Deese publiken SSH-Slรถtels sรผnd mit dienem Konto verbunnen. De tohรถrig privaate Slรถtel gifft kumpleten Togriep up diene Repositoriums. SSH-Slรถtels, wat utwiest worden sรผnd, kรถnen bruukt worden, um SSH-unnerschreven Git-Kommitterens uttowiesen.
+keep_email_private_popup = Diene E-Mail-Adress word vun dienem Profil verbargen un is nich de Normaalweert fรถr Kommitterens, wat du รถver de Internett-Schnittstee maakst, so as Datei-Upladens, Bewarkens un Tosamenfรถhrens-Kommitterens. In Stee daarvun kann eene besรผnnere Adress %s bruukt worden, um Kommitterens mit dienem Konto to verbinnen. Deese Instellen รคnnert keene bestahn Kommitterens.
+ssh_helper = Bruukst du Hรผlp? Kiek de Infรถhren an, wo du diene eegenen SSH-Slรถtels maakst of hรผlp gewohnten Probleemen of, รถver wat man mit SSH mennigmaal strukelt.
+access_token_desc = Utkรถรถrt Teken-Verlรถรถvnissen begrenzen dat Anmellen blots up de tohรถrig API -Padden. Lees de Dokumenteren fรถr mehr Informatioonen.
+oauth2_confidential_client = Diskreeter Klient. Kรถรถr dat fรถr Programmen ut, wat dat Geheemst diskreet behanneln, as Internett-Sieden. Kรถรถr dat nich fรถr stedenwies Programmen ut, as Schrievdisk- un Telefoon-Programmens.
+gpg_helper = Bruukst du Hรผlp? Kiek de Infรถhren รถver GPG an.
+gpg_desc = Deese publiken GPG-Slรถtels sรผnd mit dienem Konto verbunnen un worden bruukt, um diene Kommitterens uttowiesen. Holl de tohรถrig privaaten Slรถtels seker, denn daarmit kann man Kommitterens mit diener Unnerschrift unnerschrieven.
+oauth2_application_locked = Forgejo vermarkt vรถrweg eenige OAuth2-Programmen biโm Starten, wenn dat in de Instellens anknipst is. Um unverwachts Verhollen to verhinnern, kรถnen se nich bewarkt of wegdaan worden. Bidde kiek fรถr mehr Informatioonen de OAuth2-Dokumenteren an.
+twofa_desc = Um dien Konto tegen Passwoordklau to schรผtten, kannst du een Smart-Telefoon of anner Geraadskupp bruken, um tied-baseerte Eenmaalpasswoorden (ยปTOTPยซ) to kriegen.
+twofa_recovery_tip = Wenn du dien Geraadskupp verlรผst, kannst du eenen Eenmaal-Bruuk-Torรผgghalens-Slรถtel bruken, um weer in dien Konto to komen.
+webauthn_desc = Sekerheids-Slรถtels sรผnd Geraadskuppen, wat kryptographisk Slรถtels enthollen. Se kรถnen fรถr dat Anmellen mit Twee Faktooren bruukt worden. Sekerheids-Slรถtels mutten de ยปWebAuthn Authenticator ยซ-Standard unnerstรผtten.
+user_block_yourself = Du kannst di nich sรผlvst blockeren.
+pronouns_custom_label = Eegene Pronomens
+change_username_redirect_prompt.with_cooldown.one = De olle Brukernaam word na eener Ofkรถhl-Dรผรผr vun %[1]d Dag fรถr all Lรผรผ verfรถรถgbaar wesen. In de Ofkรถhl-Dรผรผr kannst du de ollen Naam noch torรผgghalen.
+change_username_redirect_prompt.with_cooldown.few = De olle Brukernaam word na eener Ofkรถhl-Dรผรผr vun %[1]d Dagen fรถr all Lรผรผ verfรถรถgbaar wesen. In de Ofkรถhl-Dรผรผr kannst du de ollen Naam noch torรผgghalen.
+keep_pronouns_private = Pronomens blots to anmellt Brukers wiesen
+keep_pronouns_private.description = Dat word diene Pronomens vun Besรถkers, wat nich anmellt sรผnd, verbargen.
+quota.rule.exceeded.helper = De Grรถtt vun all Dingen unner deeser Regel all tosamen is hooger as de Quote.
+quota.applies_to_user = Deese Quoten-Regeln gellen fรถr dien Konto
+storage_overview = Spieker-รversicht
+quota = Quote
+quota.applies_to_org = Deese Quoten-Regeln gellen fรถr deese Vereenigung
+quota.rule.exceeded = รverweggahn
+quota.rule.no_limit = Nich begrenzt
+quota.sizes.all = All
+quota.sizes.repos.all = Repositoriums
+quota.sizes.repos.public = Publike Repositoriums
+quota.sizes.repos.private = Privaate Repositoriums
+quota.sizes.git.all = Git-Inhollen
+quota.sizes.git.lfs = Git-LFS
+quota.sizes.assets.attachments.all = Anhangen
+quota.sizes.assets.attachments.issues = Gefall-Anhangen
+quota.sizes.assets.attachments.releases = Publizerens-Anhangen
+quota.sizes.assets.packages.all = Paketen
+quota.sizes.wiki = Wiki
+quota.sizes.assets.all = Objekten
+quota.sizes.assets.artifacts = Warkwies-Objekten
+access_token_regeneration = Togang-Teken neei maken
+regenerate_token = Neei maken
+access_token_regeneration_desc = Wenn du een Teken neei maakst, verlesen Anwennens, wat โt bruken, Togang to dienem Konto. Dat kann nich torรผggnohmen worden. Wiedermaken?
+regenerate_token_success = Dat Teken is neei maakt worden. Anwennens, wat โt bruken, hebben keenen Togang to dienem Konto mehr un mutten mit de nejen Teken verneeit worden.
+
+[repo]
+rss.must_be_on_branch = Du muttst up eenem Twieg wesen, um eenen RSS-Schuuv to hebben.
+admin.manage_flags = Flaggen verwalten
+admin.flags_replaced = Repositoriums-Flaggen utwesselt
+owner = Eegner
+repo_name = Repositoriums-Naam
+repo_size = Repositoriums-Grรถtt
+size_format = %[1]s: %[2]s; %[3]s: %[4]s
+template = Vรถrlaag
+template_select = Kรถรถr eene Vรถrlaag ut
+template_helper = Dat Repositorium as Vรถrlaag bruken
+visibility = Sichtbaarkeid
+visibility_helper = Repositorium privaat maken
+visibility_fork_helper = (Wenn du dat รคnnerst, รคnnert dat ok de Sichtbaarkeid vun all Gabels.)
+fork_repo = Repositorium gabeln
+fork_from = Gabeln vun
+already_forked = Du hest %s al gabelt
+fork_branch = Twieg, wat to de Gabel, kloont worden sall
+open_with_editor = Mit %s opmaken
+download_tar = TAR.GZ runnerladen
+generate_repo = Repositorium maken
+generate_from = Maken ut
+repo_desc = Beschrieven
+admin.update_flags = Flaggen vernejen
+new_repo_helper = In eenem Repositorium sรผnd all Dateien vun eenem Projekt, ok hรถr Versioons-Histoorje. Hest du al annerwaar eens? Treck een Repositorium um .
+owner_helper = Eenige Vereenigungen worden in de List villicht nich wiest, denn โt gifft eene Grenz, wo vรถle Repositoriums man hebben kann.
+admin.enabled_flags = Flaggen, wat fรถr deeses Repositorium anknipst sรผnd:
+admin.failed_to_replace_flags = Kunn Repositoriums-Flaggen nich utwesseln
+fork_no_valid_owners = Deeses Repositorium kann nich gabelt worden, denn โt gifft keene gรผltigen Eegners.
+repo_name_helper = Gode Repositoriums-Namen sรผnd kรถrt, licht to marken un eenmaalige Slรถtelwoorden.
+visibility_helper_forced = Dien Sied-Chef dwingt, dat neje Repositoriums privaat ween mutten.
+template_description = Vรถrlaag-Repositoriums verlรถven Brukers, neje Repositoriums mit de sรผlve Verteeknisstruktur, Dateien un Instellens to maken.
+clone_helper = Bruukst du Hรผlp biโm Klonen? Besรถรถk Hรผlp .
+repo_lang = Spraak
+repo_gitignore_helper = Vรถrlaag fรถr .gitignore utkรถren
+visibility_description = Blots de Eegner vun de Vereenigung, of de Liddmaten vun de Vereenigung, wenn se deeses Recht hebben, worden dat sehn kรถnen.
+fork_to_different_account = To een anner Konto gabeln
+fork_visibility_helper = De Sichtbaarkeid vun eenem gabelt Repositorium kann nich รคnnert worden.
+all_branches = All Twiegen
+use_template = Deese Vรถrlaag bruken
+repo_desc_helper = Giff een kรถrte Beschrieven in (wenn du willst)
+download_zip = ZIP runnerladen
+download_bundle = BUNDLE runnerladen
+license_helper = Kรถรถr eene Lizenz-Datei ut
+object_format = Objekt-Formaat
+object_format_helper = Objekt-Formaat in deesem Repositorium. Kann naher nich mehr รคnnert worden. SHA1 is dat, wat am wiedesten unnerstรผtt word.
+readme = LEESMI
+readme_helper = Kรถรถr eene Vรถrlaag fรถr de LEESMI-Datei ut
+readme_helper_desc = Dat is de Stee, waar du eene kumplete Beschrieven fรถr dien Projekt schrieven kannst.
+create_repo = Repositorium maken
+default_branch_label = Hรถรถvd
+default_branch_helper = De Hรถรถvd-Twieg is de Grund-Twieg fรถr Haalvรถrslagens un Quelltext-Kommitterens.
+mirror_prune = Schรถrtjen
+mirror_interval_invalid = De Spegel-Tiedofstand is ungรผltig.
+mirror_public_key = Publiker SSH-Slรถtel
+mirror_use_ssh.not_available = SSH is nich tum Anmellen verfรถรถgbaar.
+mirror_sync = spegelt
+mirror_address = Vun URL klonen
+mirror_interval = Tiedofstand fรถr โt Spegeln (gรผltige Tied-Eenheiden sรผnd ยปhยซ, ยปmยซ un ยปsยซ). 0 um dat automatisk Spegeln uttoknipsen. (Minnster Ofstand: %s)
+issue_labels = Vermarkens
+issue_labels_helper = Kรถรถr eene Vermarkens-Sammlung ut
+license = Lizenz
+auto_init = Repositorium inrichten
+mirror_sync_on_commit = Spegeln, wenn Kommitterens schuuvt worden
+repo_gitignore_helper_desc = Kรถรถr ut eener List vun Vรถrlagen fรถr bekannte Spraken ut, welke Dateien nich verfolgt worden. Normaale Objekten, wat vun de Bauwarktรผรผg vun elkeen Spraak utgeven worden, sรผnd in deeser .gitignore dann al enthollen.
+default_branch = Hรถรถvd-Twieg
+mirror_prune_desc = Feern-Verfolgens-Nรถmens, wat nich mehr bruukt worden, wegdoon
+mirror_use_ssh.text = SSH tum Anmellen bruken
+license_helper_desc = Eene Lizenz regelt, wat anners mit dienem Quelltext doon un nich doon dรผren. Nich wiss, welke fรถr dien Projekt passt? Kiek Kรถรถr eene Lizenz an.
+mirror_denied_combination = Kann nich publiken Slรถtel un Passwoord tum Anmellen beide tosammen bruken.
+mirror_address_desc = Giff de nรถdigen Anmell-Informatioonen unner ยปAnmellenยซ in.
+mirror_lfs_endpoint = LFS-Ennpunkt
+mirror_last_synced = Tolest spegelt
+mirror_password_placeholder = (Nich รคnnert)
+mirror_password_blank_placeholder = (Nich sett)
+watchers = Belurers
+stargazers = Steernenkiekers
+stars_remove_warning = Dat lรถsket all Steernen vun deesem Repositorium.
+forks = Gabels
+stars = Steernen
+reactions_more = un noch %d daarto
+language_other = Anner
+adopt_preexisting_label = Dateien รถvernehmen
+delete_preexisting_label = Lรถsken
+delete_preexisting_content = Dateien in %s lรถsken
+delete_preexisting_success = Dateien sรผnner Eegner in %s lรถsken
+tree_path_not_found_branch = Padd %[1]s gifft โt nich in Twieg %[2]s
+transfer.accept = รverdragen annehmen
+transfer.accept_desc = To ยป%sยซ รถverdragen
+transfer.reject = รverdragen oflehnen
+transfer.no_permission_to_reject = Du hest nich dat Recht, deeses รverdragen oftolehnen.
+desc.private = Privaat
+desc.public = Publik
+desc.template = Vรถrlaag
+desc.archived = Archiveert
+template.topics = Themen
+template.avatar = Kontobill
+template.one_item = Tominnst een Vรถrlaag-Ding mutt utkรถรถrt worden
+template.invalid = Een Vรถrlaag-Repositorium mutt utkรถรถrt worden
+migrate_options_lfs_endpoint.label = LFS-Ennpunkt
+migrate_options_lfs_endpoint.placeholder = Wenn leeg laten, word de Ennpunkt vun de Kloon-URL avleit
+migrate_items = Umtreck-Dingen
+migrate_items_wiki = Wiki
+migrate_items_milestones = Markstenen
+migrate_items_pullrequests = Haalvรถrslagen
+migrate_items_releases = Publizerens
+migrate_repo = Repositorium umtrecken
+migrate.clone_address = Umtrecken / Klonen vun URL
+migrate.failed = Umtreck fehlslagen: %v
+migrate.migrate_items_options = Togang-Teken is nรถdig, um mehr Dingen umtotrecken
+migrated_from = Vun %[2]s umtrucken
+migrate.migrate = Vun %s umtrecken
+migrate.migrating = Treckt vun %s um โฆ
+migrate.github.description = Daten vun github.com of eenem GitHub-Enterprise-Server umtrecken.
+migrate.gitlab.description = Daten vun gitlab.com of anner GitLab-Instanzen umtrecken.
+migrate.codebase.description = Daten vun codebasehq.com umtrecken.
+migrate.migrating_git = Git-Daten worden umtrucken
+migrate.migrating_topics = Themen worden umtrucken
+migrate.migrating_labels = Vermarkens worden umtrucken
+migrate.migrating_releases = Publizerens worden umtrucken
+migrate.migrating_issues = Gefallens worden umtrucken
+migrate.cancel_migrating_title = Umtreck ofbreken
+mirror_from = Spegel vun
+forked_from = gabelt vun
+fork_from_self = Du kannst dien eegen Repositorium nich gabeln.
+watch_guest_user = Mell di an, um deeses Repositorium to beluren.
+star_guest_user = Mell di an, um eenen Steern up deeses Repositorium to setten.
+subscribe.issue.guest.tooltip = Mell di an, um deeses Gefall to abonneren.
+watch = Beluren
+unwatch = Nich mehr beluren
+star = Steern setten
+unstar = Steern wegnehmen
+download_archive = Repositorium runnerladen
+no_desc = Nich beschrieven
+quick_guide = Fixanwies
+clone_this_repo = Deeses Repositorium klonen
+cite_this_repo = Deeses Repositorium ziteren
+push_exist_repo = Een bestahn Repositorium vun de Oorderreeg schuven
+code = Quelltext
+code.desc = Wies Quelltext, Dateien, Kommitterens un Twiegen.
+branch = Twieg
+tree = Boom
+unit_disabled = De Sied-Chef hett deesen Repositoriums-Deel utknipst.
+delete_preexisting = Vรถrbestahn Dateien lรถsken
+desc.internal = Binnern
+template.git_content = Git-Inholl (Hรถรถvd-Twieg)
+template.webhooks = Internett-Hakens
+mirror_password_help = รnner de Brukernaam, um een sekert Passwoord to lรถsken.
+author_search_tooltip = Wiest bit to 30 Brukers
+transfer.reject_desc = รverdragen to ยป%sยซ ofbreken
+migrate_options_lfs = LFS-Dateien umtrecken
+migrate_items_labels = Vermarkens
+migrate.clone_address_desc = De HTTP(S) of Git ยปcloneยซ URL vun eenem bestahn Repositorium
+migrate.invalid_local_path = De stedenwies Padd is ungรผltig. โt gifft dat nich of dat is keen Verteeknis.
+migrate.gitea.description = Daten vun gitea.com of anner Gitea-Instanzen umtrecken.
+fork_guest_user = Mell di an, um deeses Repositorium to gabeln.
+fork = Gabeln
+adopt_preexisting = Vรถrbestahn Dateien รถvernehmen
+blame_prior = Schรผld vรถr deeser รnnern wiesen
+adopt_search = Giff Brukernaam in, um na Repositoriums sรผnner Eegner to sรถken โฆ (leeg laten, um se all to finnen)
+adopt_preexisting_success = Vun %s Dateien รถvernohmen un Repositorium maakt
+tree_path_not_found_commit = Padd %[1]s gifft โt nich in Kommitteren %[2]s
+tree_path_not_found_tag = Padd %[1]s gifft โt nich in Mark %[2]s
+desc.sha256 = SHA256
+template.issue_labels = Gefall-Vermarkens
+form.name_pattern_not_allowed = Dat Muster ยป%sยซ is in eenem Repositoriums-Naam nich verlรถรถvt.
+mirror_lfs = Spieker fรถr grote Dateien (LFS)
+mirror_lfs_desc = Spegeln vun LFS-Daten anknipsen.
+adopt_preexisting_content = Repositorium vun %s maken
+transfer.no_permission_to_accept = Du hest nich dat Recht, deeses รverdragen antonehmen.
+template.git_hooks = Git-Hakens
+archive.title_date = Deeses Repositorium is am %s archiveert worden. Du kannst de Dateien ankieken un โt klonen, aver du kannst sienen Tostand nich รคnnern, also nix schuven un keene nejen Gefallens, Haalvรถrslagen of Kommentaren maken.
+form.reach_limit_of_creation_1 = De Eegner is al bi de Grenz vun %d Repositorium.
+form.name_reserved = De Repositoriums-Naam ยป%sยซ is vรถrbehollen.
+form.string_too_long = De angeven Text is langer as %d Bookstavens.
+migrate_items_issues = Gefallens
+template.items = Vรถrlaag-Dingen
+template.git_hooks_tooltip = Du kannst jรผรผst keene Git-Hakens bewarken of lรถsken, nadeem se hentofรถรถgt sรผnd. Kรถรถr dat blots ut, wenn du de Vรถrlaag-Repositorium vertraust.
+archive.issue.nocomment = Deeses Repositorium is archiveert. Du kannst nich up Gefallens kommenteren.
+archive.pull.nocomment = Deeses Repositorium is archiveert. Du kannst nich up Haalvรถrslagens kommenteren.
+form.reach_limit_of_creation_n = De Eegner is al bi de Grenz vun %d Repositoriums.
+migrate_options_mirror_helper = Deeses Repositorium word een Spegel wesen
+migrate_options_lfs_endpoint.description.local = Een stedenwies Server-Padd word ok unnerstรผtt.
+migrate_items_merge_requests = Tosamenfรถhren-Vรถrslagen
+migrate.permission_denied = Du dรผรผrst keene stedenwies Repositoriums importeren.
+archive.title = Deeses Repositorium is archiveert. Du kannst de Dateien ankieken un โt klonen, aver du kannst sienen Tostand nich รคnnern, also nix schuven un keene nejen Gefallens, Haalvรถrslagen of Kommentaren maken.
+need_auth = Anmellen
+migrate_options = Umtreck-Instellens
+migrate.clone_local_path = of een stedenwies Server-Padd
+migrate.migrating_failed.error = Umtrecken fehlslagen: %s
+migrate.migrating_failed_no_addr = Umtreck fehlslagen.
+migrate.migrating_pulls = Haalvรถrslagen worden umtrucken
+empty_message = Deeses Repositorium hett noch keenen Inholl.
+migrate.invalid_lfs_endpoint = De LFS-Ennpunkt is nich gรผltig.
+migrated_from_fake = Vun %[1]s umtrucken
+migrate.git.description = Een Repositorium blots vun elkeen Git-Deenst umtrecken.
+migrate.onedev.description = Daten vun code.onedev.io of anner OneDev-Instanzen umtrecken.
+generated_from = maakt vun
+migrate.migrating_failed = Umtrecken un %s fehlslagen.
+migrate.forgejo.description = Daten vun codeberg.org of anner Forgejo-Instanzen umtrecken.
+migrate.gogs.description = Daten vun notabug.org of anner Gogs-Instanzen umtrecken.
+migrate.migrating_milestones = Markstenen worden umtrucken
+create_new_repo_command = Een nejes Repositorium in de Oorderreeg maken
+migrate.cancel_migrating_confirm = Willst du deesen Umtreck ofbreken?
+subscribe.pull.guest.tooltip = Mell di an, um deesen Haalvรถrslag to abonneren.
+more_operations = Mehr doon
+migrate.gitbucket.description = Daten vun GitBucket-Instanzen umtrecken.
+find_tag = Mark finnen
+branches = Twiegen
+tag = Mark
+tags = Markens
+issues = Gefallens
+pulls = Haalvรถrslagen
+packages = Paketen
+actions = Aktioonen
+releases = Publizerens
+milestones = Markstenen
+org_labels_desc_manage = Verwalten
+commits = Kommitterens
+commit = Kommitteren
+n_commit_one = %s Kommitteren
+n_commit_few = %s Kommitterens
+n_branch_one = %s Twieg
+n_tag_one = %s Mark
+n_tag_few = %s Markens
+n_release_one = %s Publizeren
+n_release_few = %s Publizerens
+file.title = %s am %s
+file_history = Histoorje
+file_view_source = Quelltext wiesen
+file_view_rendered = Tekent wiesen
+file_view_raw = Ruug wiesen
+file_permalink = Ewig Verwies
+file_too_large = De Datei is to grot tum Wiesen.
+file_copy_permalink = Ewig Verwies koperen
+view_git_blame = Git-Schรผld wiesen
+video_not_supported_in_browser = Dien Browser unnerstรผtt de HTML5-ยปvideoยซ-Mark nich.
+audio_not_supported_in_browser = Dien Browser unnerstรผtt de HTML5-ยปaudioยซ-Mark nich.
+stored_lfs = Mit Git LFS sekert
+unescape_control_characters = Inkielen
+executable_file = Utfรถhrbaar Datei
+vendored = Verkoperig
+generated = Maakt
+commit_graph = Kommitterens-Boom
+commit_graph.select = Twiegen utkรถren
+commit_graph.monochrome = Eenfarvig
+commit_graph.color = Klรถรถr
+commit.contained_in = Deeses Kommitteren is enthollen in:
+commit.contained_in_default_branch = Deeses Kommitteren is Deel vun de Hรถรถvd-Twieg
+commit.load_referencing_branches_and_tags = Twiegen un Markens laden, wat deeses Kommitteren nรถmen
+blame = Schรผld
+download_file = Datei runnerladen
+normal_view = Normaale Sicht
+line = Rieg
+lines = Riegen
+from_comment = (Kommentaar)
+no_eol.text = Keen Riegenenn
+no_eol.tooltip = Deese Datei ennt nich mit eenem Riegenenn-Bookstaven.
+editor.add_file = Datei hentofรถgen
+editor.new_file = Neje Datei
+editor.edit_file = Datei bewarken
+editor.cannot_edit_lfs_files = LFS-Dateien kรถnen nich in de Internett-Schnittstee bewarkt worden.
+editor.delete_this_file = Datei lรถsken
+editor.file_delete_success = Datei ยป%sยซ is lรถsket worden.
+editor.name_your_file = Benรถรถm diene Datei โฆ
+editor.or = of
+editor.cancel_lower = Ofbreken
+editor.commit_signed_changes = Unnerschrieven รnnerns kommitteren
+editor.commit_changes = รnnerns kommitteren
+editor.add_tmpl = ยป<%s>ยซ hentofรถgen
+editor.add_tmpl.filename = Dateinaam
+editor.add = %s hentofรถgen
+editor.update = %s vernejen
+editor.delete = %s lรถsken
+editor.patch = Plack anwennen
+editor.patching = Plackt:
+editor.fail_to_apply_patch = Kann Plack ยป%sยซ nich anwennen
+editor.new_patch = Nejer Plack
+editor.commit_message_desc = Wenn du willst, fรถรถg een wiederes Beschrieven hento โฆ
+editor.commit_directly_to_this_branch = Kommitteer stracks up de %[1]s -Twieg.
+editor.propose_file_change = Datei-รnnern vรถrslagen
+editor.new_branch_name = Benรถรถm de Twieg fรถr deeses Kommitteren
+editor.new_branch_name_desc = Nejer Twig-Naam โฆ
+editor.cancel = Ofbreken
+editor.filename_is_invalid = De Dateinaam is ungรผltig: ยป%sยซ.
+editor.invalid_commit_mail = Ungรผltige E-Mail fรถr dat Kommitteren.
+editor.branch_does_not_exist = Twieg ยป%sยซ gifft dat in deesem Repositorium nich.
+editor.branch_already_exists = Twieg ยป%sยซ gifft dat in deesem Repositorium al.
+editor.filename_is_a_directory = Dateinaam ยป%sยซ word in deesem Repositorium al as Verteeknisnaam bruukt.
+editor.file_deleting_no_longer_exists = De Datei, wat lรถsket word, ยป%sยซ, gifft dat in deesem Repositorium nich mehr.
+editor.file_already_exists = Eene Datei mit de Naam ยป%sยซ gifft dat in deesem Repositorium al.
+editor.commit_id_not_matching = De Datei is รคnnert worden, as du se bewarkt hest. Kommitteer up eenen nejen Twieg un fรถhr dann tosamen.
+editor.push_out_of_date = De Schuuv schient verollt to wesen.
+editor.commit_empty_file_header = Eene lege Datei kommitteren
+editor.no_changes_to_show = โt gifft keene รnnerns to wiesen.
+editor.fail_to_update_file_summary = Fehler-Naricht:
+editor.push_rejected_summary = Kumpleete Oflehnens-Naricht:
+editor.add_subdir = Verteeknis hentofรถgen โฆ
+editor.upload_file_is_locked = Datei ยป%sยซ is vun %s tosluten.
+editor.upload_files_to_dir = Dateien to ยป%sยซ upladen
+editor.cannot_commit_to_protected_branch = Kann nich up schรผtt Twieg ยป%sยซ kommitteren.
+editor.no_commit_to_branch = Kann nich stracks to de Twieg kommitteren, denn:
+editor.require_signed_commit = Twieg bruuk een unnerschreven Kommitteren
+editor.cherry_pick = Rosienenbick %s up:
+editor.revert = Nehm %s torรผgg up:
+commits.desc = Stรถver dรถr de Quelltext-รnnerns-Histoorje.
+commits.commits = Kommitterens
+commits.no_commits = Keene gemeensaamen Kommitterens. ยป%sยซ un ยป%sยซ hebben kumpleet verscheden Histoorjes.
+commits.nothing_to_compare = Deese Twiegen sรผnd gliek.
+commits.search_branch = Deeser Twieg
+commits.search_all = All Twiegen
+commits.author = Autor
+commits.message = Naricht
+commits.date = Datum
+commits.older = Oller
+commits.newer = Nejer
+commits.signed_by_untrusted_user_unmatched = Unnerschrieven vun eenem unvertraut Bruker, well nich de Kommitterer is
+commits.gpg_key_id = GPG-Slรถtel-ID
+commits.ssh_key_fingerprint = SSH-Slรถtel-Fingerspoor
+commit.operations = Doon
+commit.revert = Torรผggnehmen
+commit.revert-header = Torรผggnehmen: %s
+commit.cherry-pick = Rosienenbicken
+commit.cherry-pick-header = Rosienenbicken: %s
+commit.cherry-pick-content = Twieg utkรถren, up wat du Rosienenbicken willst:
+commitstatus.error = Fehler
+commitstatus.failure = Fehlslagen
+commitstatus.pending = Staht ut
+commitstatus.success = Daankregen
+projects = Projekten
+projects.description_placeholder = Beschrieven
+projects.create = Projekt maken
+projects.title = Titel
+projects.create_success = Dat Projekt ยป%sยซ is maakt worden.
+projects.deletion = Projekt lรถsken
+projects.deletion_success = Dat Projekt is lรถsket worden.
+projects.edit = Projekt bewarken
+projects.edit_subheader = Projekten organiseren Gefallens un verfolgen dat Wiederkomen.
+projects.modify = Projekt bewarken
+projects.edit_success = Projekt ยป%sยซ is verneeit worden.
+projects.type.none = Nix
+projects.type.basic_kanban = Slichtes Kanban
+projects.type.bug_triage = Fehlers verwalten
+projects.template.desc = Vรถrlaag
+projects.column.edit = Striep bewarken
+projects.column.edit_title = Naam
+projects.column.new_title = Naam
+projects.column.new_submit = Striep maken
+projects.column.set_default = Hรถรถvd setten
+projects.column.delete = Striep lรถsken
+projects.column.color = Klรถรถr
+projects.open = Opmaken
+projects.close = Dichtmaken
+projects.column.assigned_to = Towiesen an
+projects.card_type.images_and_text = Billers un Text
+projects.card_type.text_only = Blots Text
+issues.filter_assignees = Towiesen filtern
+issues.filter_milestones = Marksteen filtern
+issues.filter_projects = Projekt filtern
+issues.filter_labels = Vermark filtern
+issues.new = Nejes Gefall
+issues.new.title_empty = Titel kann nich leeg wesen
+issues.new.labels = Vermarkens
+issues.new.clear_labels = Vermarkens leegmaken
+issues.new.projects = Projekten
+issues.new.no_projects = Keen Projekt
+issues.new.closed_projects = Dichtmaakt Projekten
+issues.new.no_items = Keene Dingen
+issues.new.milestone = Marksteen
+issues.new.no_milestone = Keen Marksteen
+issues.new.open_milestone = Open Markstenen
+issues.new.closed_milestone = Dichtmaakt Markstenen
+issues.new.assignees = Towiesen
+issues.new.no_assignees = Keene Towiesens
+issues.new.assign_to_me = An mi towiesen
+project = Projekten
+release = Publizeren
+file_follow = Symbolisk Verwies nagahn
+editor.signoff_desc = Fรถรถg am Enn vun de Kommitterens-Naricht eenen ยปSigned-off-byยซ-Nadrag fรถr de Kommitterer hento.
+editor.create_new_branch_np = Maak eenen nejen Twieg fรถr deeses Kommitteren.
+editor.filename_cannot_be_empty = De Dateinaam kann nich leeg wesen.
+labels = Vermarkens
+file_raw = Ruug
+commit_graph.hide_pr_refs = Haalvรถrslagen verbargen
+editor.upload_file = Datei upladen
+editor.preview_changes = รnnerns vรถrwiesen
+filter_branch_and_tag = Twieg of Mark filtern
+symbolic_link = Symbolisk Verwies
+editor.cannot_edit_non_text_files = Binรครคrdateien kรถnen nich in de Internett-Schnittstee bewarkt worden.
+editor.must_be_on_a_branch = Du muttst up eenem Twieg wesen, um รnnerns an deeser Datei to maken of vรถrtoslagen.
+editor.fork_before_edit = Du muttst deeses Repositorium gabeln, um รnnerns an deeser Datei to maken of vรถrtoslagen.
+n_branch_few = %s Twiegen
+released_this = hett dat publizeert
+escape_control_characters = Utkielen
+editor.edit_this_file = Datei bewarken
+editor.this_file_locked = Datei is tosluten
+editor.filename_help = Fรถรถg een Verteeknis hento, indeem du sienen Naam mit eenem Schรผรผnstreek (ยป/ยซ) daarna ingiffst. Lรถske een Verteeknis, indeem du am Begรผnn vun de Ingaavfeld de Rรผcktast drรผckst.
+editor.unable_to_upload_files = Kunn de Dateien to ยป%sยซ nich upladen mit Fehler: %v
+commits.signed_by_untrusted_user = Unnerschrieven vun eenem unvertraut Bruker
+projects.deletion_desc = Wenn du een Projekt lรถskest, word โt vun all verwandt Gefallens wegnohmen. Wiedermaken?
+projects.column.set_default_desc = Deese Striep as de Hรถรถvd-Striep fรถr unverwalt Gefallens un Haalvรถrslagens setten
+issues.desc = Fehlermellens, Upgavens un Markstenen organiseren.
+issues.new.open_projects = Open Projekten
+editor.create_new_branch = Maak eenen nejen Twieg fรถr deeses Kommitteren un maak daarmit eenen Haalvรถrslag op.
+editor.must_have_write_access = Du muttst Schriev-Togriep hebben, um รnnerns an deeser Datei to maken of vรถrtoslagen.
+editor.file_is_a_symlink = `ยป%sยซ is een symbolisk Verwies. Symbolisk Verwiesen kรถnen in de Internett-Bewarker nich bewarkt worden`
+editor.commit_empty_file_text = De Datei, wat du kommitteren willst, is leeg. Wiedermaken?
+editor.push_rejected = De รnnern is vun de Server oflehnt worden. Bidde รถverprรผรผf de Git-Hakens.
+commits.browse_further = Wiederstรถvern
+projects.description = Beschrieven (wenn du willst)
+projects.card_type.desc = Kaart-Vรถrwiesens
+issues.new.no_label = Keene Vermarkens
+issues.new.clear_projects = Projekten leegmaken
+issues.new.clear_assignees = Towiesens leegmaken
+editor.file_editing_no_longer_exists = De Datei, wat bewarkt word, ยป%sยซ, gifft dat in deesem Repositorium nich mehr.
+editor.user_no_push_to_branch = Bruker kann nich to Twieg schuven
+editor.directory_is_a_file = Verteeknisnaam ยป%sยซ word in deesem Repositorium al as Dateinaam bruukt.
+editor.file_changed_while_editing = De Datei-Inhollens hebben sik รคnnert, siet du de Datei opmaakt hest. Klick hier , um se to sehn, of kommitteer de รnners weer , um se to รถverschrieven.
+editor.push_rejected_no_message = De รnnern is vun de Server sรผnner Naricht oflehnt worden. Bidde รถverprรผรผf de Git-Hakens.
+commits.signed_by = Unnerschrieven vun
+commit.revert-content = Twieg utkรถren, up wat du dat torรผggnehmen willst:
+projects.desc = Gefallens un Haalvรถrslagens in Projekt-Bredden verwalten.
+projects.new = Nejes Projekt
+projects.template.desc_helper = Kรถรถr tum Begรผnnen eene Projekt-Vรถrlaag ut
+editor.fail_to_update_file = Kunn de Datei ยป%sยซ nich vernejen/hentofรถgen.
+ext_issues = Frรถmde Gefallens
+projects.column.new = Neje Striep
+projects.column.deletion_desc = Wenn du eene Projekt-Striep lรถskest, worden all Gefallens daarin in de Hรถรถvd-Striep verschuven. Wiedermaken?
+issues.new.clear_milestone = Marksteen leegmaken
+commits.renamed_from = Umbenรถรถmt vun %s
+commits.view_path = To deeser Tied in de Histoorje wiesen
+issues.filter_reviewers = Nakieker filtern
+issues.new.no_reviewers = Keene Nakiekers
+issues.choose.open_external_link = Opmaken
+issues.choose.blank = Normaal
+issues.choose.invalid_templates = %v ungรผltig Vรถrlagen(s) funnen
+issues.choose.invalid_config = De Gefall-Instellens enthollen Fehlers:
+issues.no_ref = Keen Twieg/Mark angeven
+issues.new_label = Nejer Vermark
+issues.new_label_placeholder = Vermark-Naam
+issues.new_label_desc_placeholder = Beschrieven
+issues.create_label = Vermark maken
+issues.label_templates.helper = Kรถรถr eene Vermarkens-Sammlung ut
+issues.label_templates.use = Vermarkens-Sammlung bruken
+issues.add_labels = hett %[2]s de Vermarkens %[1]s hentofรถรถgt
+issues.remove_label = hett %[2]s de Vermark %[1]s wegdaan
+issues.add_milestone_at = `hett dat %[2]s to de Marksteen %[1]s hentofรถรถgt`
+issues.add_project_at = `hett dat %[2]s to de Projekt %[1]s hentofรถรถgt`
+issues.change_milestone_at = `hett %[3]s de Marksteen vun %[1]s to %[2]s รคnnert`
+issues.remove_milestone_at = `hett dat %[2]s vun de Marksteen %[1]s wegdaan`
+issues.remove_project_at = `hett dat %[2]s vun de Projekt %[1]s wegdaan`
+issues.deleted_milestone = `(lรถsket)`
+issues.deleted_project = `(lรถsket)`
+issues.self_assign_at = `hett dat %s sik sรผlven towiesen`
+issues.remove_self_assignment = `hett sien Towiesen %s wegnohmen`
+issues.change_title_at = `hett %[3]s de Titel vun %[1]s to %[2]s รคnnert`
+issues.change_ref_at = `hett %[3]s de Nรถmen vun %[1]s to %[2]s รคnnert`
+issues.delete_branch_at = `hett %[2]s de Twieg %[1]s lรถsket`
+issues.filter_label = Vermark
+issues.filter_label_exclude = `Bruuk Alt
+Klick/Enter
, um Vermarkens uttosluten`
+issues.filter_label_no_select = All Vermarkens
+issues.filter_label_select_no_label = Keen Vermark
+issues.filter_milestone = Marksteen
+issues.filter_milestone_none = Keene Markstenen
+issues.filter_milestone_open = Open Markstenen
+issues.filter_project = Projekt
+issues.filter_project_all = All Projekten
+issues.filter_project_none = Keen Projekt
+issues.filter_assignee = Towiesen
+issues.filter_assginee_no_select = All Towiesens
+issues.filter_assginee_no_assignee = Nรผms towiesen
+issues.filter_poster = Autor
+issues.filter_poster_no_select = All Autoren
+issues.filter_type.assigned_to_you = Di towiesen
+issues.filter_type.mentioning_you = Nรถรถmt di
+issues.filter_type.review_requested = Nakieken anfraggt
+issues.filter_sort = Sorteren
+issues.filter_sort.latest = Neeist
+issues.filter_sort.oldest = Ollst
+issues.filter_sort.recentupdate = Kรถrtens รคnnert
+issues.filter_sort.leastupdate = Lang nich รคnnert
+issues.filter_sort.mostcomment = Meest kommenteert
+issues.filter_sort.leastcomment = Minnst kommenteert
+issues.filter_sort.nearduedate = Nahst Anstahns-Datum
+issues.filter_sort.farduedate = Feernst Anstahns-Datum
+issues.filter_sort.moststars = Meeste Steernen
+issues.filter_sort.feweststars = Minnste Steernen
+issues.filter_sort.mostforks = Meeste Gabels
+issues.action_open = Opmaken
+issues.action_close = Dichtmaken
+issues.action_label = Vermark
+issues.action_milestone = Marksteen
+issues.action_assignee = Towiesen
+issues.action_check = Utkรถren/Ofkรถren
+issues.action_check_all = All Dingen Utkรถren/Ofkรถren
+issues.opened_by = %[1]s vun %[3]s opmaakt
+pulls.merged_by_fake = vun %[2]s is %[1]s tosamenfรถhrt worden
+issues.closed_by = vun %[3]s is %[1]s dichtmaakt worden
+issues.closed_by_fake = vun %[2]s is %[1]s dichtmaakt worden
+issues.opened_by_fake = vun %[2]s is %[1]s opmaakt worden
+issues.previous = Vรถrig
+issues.all_title = All
+issues.draft_title = Sketts
+issues.num_comments_1 = %d Kommentaar
+issues.delete_comment_confirm = Willst du deesen Kommentaar wรผrrelk lรถsken?
+issues.context.copy_link = Verwies koperen
+issues.context.reference_issue = In nejem Gefall benรถmen
+issues.context.edit = Bewarken
+issues.context.delete = Lรถsken
+issues.no_content = Keen Beschrieven angeven.
+issues.choose.get_started = Lรถssleggen
+issues.label_templates.fail_to_load_file = Kunn de Vermark-Vรถrlaag-Datei ยป%sยซ nich laden: %v
+issues.add_label = hett %[2]s de Vermark %[1]s hentofรถรถgt
+issues.add_assignee_at = `is vun %s %s towiesen worden`
+issues.action_milestone_no_select = Keen Marksteen
+issues.choose.blank_about = Een nejes Gefall vun de Normaal-Vรถrlaag maken.
+issues.create = Gefall maken
+issues.label_templates.title = Eene Vermark-Sammlung laden
+issues.label_templates.info = Dat gifft noch keene Vermarkens. Maak eenen Vermark mit ยปNejer Vermarkยซ of bruuk eene Vermarkens-Sammlung:
+issues.change_project_at = `hett %[3]s dat Projekt vun %[1]s to %[2]s รคnnert`
+issues.remove_assignee_at = `is sien Towiesen vun %s %s wegnohmen worden`
+issues.open_title = Open
+issues.close = Gefall dichtmaken
+issues.choose.ignore_invalid_templates = Ungรผltig Vรถrlagens sรผnd ignoreert worden
+issues.add_ref_at = `hett %[2]s de Nรถmen %[1]s hentofรถรถgt`
+issues.filter_type.all_issues = All Gefallens
+issues.filter_type.created_by_you = Vun di maakt
+issues.filter_milestone_closed = Dichtmaakt Markstenen
+issues.commented_at = `hett %s kommenteert`
+issues.remove_labels = hett %[2]s de Vermarkens %[1]s wegdaan
+issues.filter_type = Aard
+pulls.merged_by = vun %[3]s is %[1]s tosamenfรถhrt worden
+issues.next = Anner
+issues.add_remove_labels = hett %[3]s de Vermarkens %[1]s hentofรถรถgt un %[2]s wegdaan
+issues.remove_ref_at = `hett %[2]s de Nรถmen %[1]s wegdaan`
+issues.filter_milestone_all = All Markstenen
+issues.filter_type.reviewed_by_you = Vun di nakiekt
+issues.filter_sort.fewestforks = Minnste Gabels
+issues.action_assignee_no_select = Nich towiesen
+issues.closed_title = Dicht
+issues.num_comments = %d Kommentaren
+issues.context.quote_reply = Antwoord ziteren
+issues.comment_pull_merged_at = hett Kommitteren %[1]s in %[2]s %[3]s tosamenfรถhrt
+issues.close_comment_issue = Mit Kommentaar dichtmaken
+issues.reopen_comment_issue = Mit Kommentaar weer opmaken
+issues.create_comment = Kommenteren
+issues.reopened_at = `hett deeses Gefall %[2]s weer opmaakt`
+issues.comment_manually_pull_merged_at = hett Kommitteren %[1]s in %[2]s %[3]s vun Hand tosamenfรถhrt
+issues.reopen_issue = Weer opmaken
+issues.closed_at = `hett deeses Gefall %[2]s dichtmaakt`
+issues.commit_ref_at = `hett deeses Gefall %[2]s vun eenem Kommitteren benรถรถmt`
+issues.ref_closing_from = `hett deeses Gefall vun eenem Haalvรถrslag, wat โt %[4]s dichtmaken word, %[2]s benรถรถmt `
+issues.ref_closed_from = `hett deeses Gefall %[4]s %[2]s dichtmaakt `
+issues.ref_reopened_from = `hett deeses Gefall %[4]s %[2]s weer opmaakt `
+issues.ref_from = `vun %[1]s`
+issues.author = Autor
+issues.author.tooltip.pr = Deeser Bruker is de Autor vun deesem Haalvรถrslag.
+issues.role.owner = Eegner
+issues.role.owner_helper = Deeser Bruker is de Eegner vun deesem Repositorium.
+issues.role.member = Liddmaat
+issues.role.collaborator = Mitarbeider
+issues.role.first_time_contributor = Nejer Bidrager
+issues.role.first_time_contributor_helper = Dat is de eerste Bidrag vun deesem Bruker to deesem Repositorium.
+issues.role.contributor = Bidrager
+issues.role.contributor_helper = Deeser Bruker hett al wat in deesem Repositorium kommitteert.
+issues.remove_request_review = Nakieken-Anfragg wegdoon
+issues.remove_request_review_block = Kann Nakiekens-Anfragg nich wegdoon
+issues.dismiss_review = Nakieken ofseggen
+issues.dismiss_review_warning = Willst du deeses Nakieken wรผrrelk ofseggen?
+issues.sign_in_require_desc = Mell di an um mittosnacken.
+issues.edit = Bewarken
+issues.cancel = Ofbreken
+issues.save = Sekern
+issues.label_description = Beschrieven
+issues.label_color = Klรถรถr
+issues.label_exclusive = Sรผnner annere
+issues.label_archive = Vermark archiveren
+issues.label_count = %d Vermarkens
+issues.label_open_issues = %d open Gefallens/Haalvรถrslagens
+issues.label_edit = Bewarken
+issues.label_delete = Lรถsken
+issues.label_modify = Vermark bewarken
+issues.label_deletion = Vermark lรถsken
+issues.label_deletion_success = De Vermark is lรถsket worden.
+issues.label.filter_sort.alphabetically = Na de Alphabeet
+issues.label.filter_sort.reverse_alphabetically = Umdreiht na de Alphabeet
+issues.label.filter_sort.by_size = Lรผttste Grรถtt
+issues.num_participants_one = %d Mitmaker
+issues.num_participants_few = %d Mitmakers
+issues.ref_pull_from = `hett deesen Haalvรถrslag %[4]s %[2]s benรถรถmt `
+issues.label_title = Naam
+issues.label_archived_filter = Archiveert Vermarkens wiesen
+issues.archived_label_description = (Archiveert) %s
+issues.ref_issue_from = `hett deeses Gefall %[4]s %[2]s benรถรถmt `
+issues.ref_reopening_from = `hett deeses Gefall vun eenem Haalvรถrslag, wat โt %[4]s weer opmaken word, %[2]s benรถรถmt `
+issues.author.tooltip.issue = Deeser Bruker is de Autor vun deesem Gefall.
+issues.role.member_helper = Deeser Bruker is een Liddmaat vun de Vereenigung, wat de Eegner vun deesem Repositorium is.
+issues.role.collaborator_helper = Deeser Bruuker is inladen worden, in deesem Repositorium mittoarbeiden.
+issues.re_request_review = Nakieken neei anfragen
+issues.is_stale = โt hett siet de Nakieken รnnerns in deesem HV geven
+issues.label_deletion_desc = Wenn du een Vermark lรถskest, word dat vun all Gefallens wegnohmen. Wiedermaken?
+issues.label.filter_sort.reverse_by_size = Grรถttste Grรถtt
+issues.review.review = Nakieken
+issues.review.reviewers = Nakiekers
+issues.review.show_resolved = Wies lรถรถst
+issues.review.hide_resolved = Verbarg lรถรถst
+issues.review.resolve_conversation = Snack lรถsen
+issues.attachment.open_tab = `Klick, um ยป%sยซ in eener nejen Karteikaart antokieken`
+issues.attachment.download = `Klick, um ยป%sยซ runnertoladen`
+issues.unsubscribe = Ofbestellen
+issues.unpin_issue = Gefall lรถsssteken
+issues.lock = Snack tosluten
+issues.unlock = Snack upsluten
+issues.lock_duplicate = Een Gefall kann nich dรผbbelt tosluten worden.
+issues.unlock_comment = hett deesen Snack %s upsluten
+issues.unlock_confirm = Upsluten
+issues.lock_confirm = Tosluten
+issues.lock.notice_3 = - Du kannst deeses Gefall to elkeen Tied weer upsluten.
+issues.unlock.notice_1 = - Elkeenwell kann weer up deesem Gefall kommenteren.
+issues.unlock.notice_2 = - Du kannst deeses Gefall to elkeen Tied weer tosluten.
+issues.lock.reason = Grund fรถr โt Tosluten
+issues.comment_on_locked = Du kannst nich up een tosloten Gefall kommenteren.
+issues.delete = Lรถsken
+issues.delete.title = Deeses Gefall lรถsken?
+issues.tracker = Tied-Erfater
+issues.start_tracking_short = Tiednehmer starten
+issues.start_tracking = Tied-Erfaten begรผnnen
+issues.stop_tracking_history = `hett %s to warken uphรถรถrt`
+issues.cancel_tracking = Wegdoon
+issues.cancel_tracking_history = `hett %s dat Tied-Erfaten wegdaan`
+issues.add_time = Tied vun Hand indragen
+issues.del_time = Deese Tied-Upschrift lรถsken
+issues.add_time_short = Tied hentofรถgen
+issues.add_time_cancel = Ofbreken
+issues.add_time_history = `hett %s bruukt Tied hentofรถรถgt`
+issues.del_time_history = `hett %s bruukt Tied wegdaan`
+issues.add_time_hours = Stรผnnen
+issues.add_time_minutes = Menรผten
+issues.add_time_sum_to_small = Keene Tied is indragen worden.
+issues.time_spent_total = Tied bruukt all tosamen
+issues.time_spent_from_all_authors = `Tied bruukt all tosamen: %s`
+issues.due_date = Anstahns-Datum
+issues.push_commit_1 = hett %[2]s %[1]d Kommitteren hentofรถรถgt
+issues.push_commits_n = hett %[2]s %[1]d Kommitterens hentofรถรถgt
+issues.force_push_compare = Verglieken
+issues.due_date_form_edit = Bewarken
+issues.due_date_form_remove = Wegdoon
+issues.due_date_not_set = Keen Anstahns-Datum sett.
+issues.due_date_added = hett %[2]s dat Anstahns-Datum %[1]s hentofรถรถgt
+issues.due_date_remove = hett %[2]s dat Anstahns-Datum %[1]s wegdaan
+issues.due_date_overdue = Staht al lang an
+issues.dependency.title = Ofhangens
+issues.dependency.issue_no_dependencies = Keene Ofhangens sett.
+issues.dependency.pr_no_dependencies = Keene Ofhangens sett.
+issues.dependency.no_permission_1 = Du hest nich de Rechten, um %d Ofhangen to lesen
+issues.dependency.no_permission_n = Du hest nich de Rechten, um %d Ofhangens to lesen
+issues.dependency.add = Ofhangen hentofรถgen โฆ
+issues.dependency.cancel = Ofbreken
+issues.dependency.issue_closing_blockedby = Dat Dichtmaken vun deesem Gefall word vun deesen Gefallens blockeert
+issues.dependency.pr_closing_blockedby = Dat Dichtmaken vun deesem Haalvรถrslag word vun deesen Gefallens blockeert
+issues.dependency.pr_close_blocks = Deeser Haalvรถrslag blockeert dat Dichtmaken vun deesen Gefallens
+issues.dependency.issue_batch_close_blocked = Kann de utkรถรถrt Gefallens nich all tosamen dichtmaken, denn Gefall #%d hett noch open Ofhangens
+issues.dependency.pr_close_blocked = Du muttst all Gefallens, wat deesen Haalvรถrslag blockeren, dichtmaken, ehr du dat hier tosamenfรถhren kannst.
+issues.dependency.blocks_short = Blockeert
+issues.dependency.blocked_by_short = Hang of vun
+issues.dependency.remove_header = Ofhangen wegdoon
+issues.dependency.setting = Ofhangens fรถr Gefallens un Haalvรถrslagen anknipsen
+issues.dependency.add_error_same_issue = Du kannst een Gefall nich vun sik sรผlvst ofhangen laten.
+issues.dependency.add_error_dep_issue_not_exist = Ofhangig Gefall gifft dat nich.
+issues.dependency.add_error_dep_not_exist = Ofhangen gifft dat nich.
+issues.dependency.add_error_dep_exists = Ofhangen gifft dat al.
+issues.dependency.add_error_cannot_create_circular = Du kannst keen Ofhangen maken, waar sik twee Gefallens tegensiedig blockeren.
+issues.dependency.add_error_dep_not_same_repo = Beide Gefallens mutten in de sรผlve Repositorium wesen.
+issues.review.self.approval = Du kannst nich dien eegen Haalvรถrslag tostimmen.
+issues.review.self.rejection = Du kannst nich up dien eegen Haalvรถrslag um รnnerns beden.
+issues.review.comment = hett %s nakiekt
+issues.review.dismissed_label = Ofseggt
+issues.review.left_comment = hett kommenteert
+issues.review.content.empty = Du muttst eenen Kommentaar geven, wat fรถr รnnerns du hebben willst.
+issues.review.reject = hett %s um รnnerns beden
+issues.review.remove_review_request = hett %[2]s de Nakieken-Anfraag fรถr %[1]s wegdaan
+issues.review.remove_review_request_self = hett %s dat Nakieken verweigert
+issues.unlock_error = Kann een Gefall nich upsluten, wenn โt nich tosloten is.
+issues.lock_with_reason = hett dat %[2]s um %[1]s tosluten un Snack up Mitarbeiders begrenzt
+issues.unpin_comment = hett dat %s lรถssstoken
+issues.lock.notice_1 = - Anner Brukers kรถnen keene nejen Kommentaren to deesem Gefall hentofรถgen.
+issues.stop_tracking = Tiednehmer anhollen
+issues.lock.unknown_reason = Kann een Gefall nich sรผnner Grund tosluten.
+issues.subscribe = Abonneren
+issues.max_pinned = Du kannst nich mehr Gefallens faststeken
+issues.pin_comment = hett dat %s faststoken
+issues.lock_no_reason = hett dat %s tosluten un Snack up Mitarbeiders begrenzt
+issues.delete.text = Willst du deeses Gefall wรผrrelk lรถsken? (Dat lรถsket fรถr all Tieden all Inhollen. Wenn du โt blots archiveren willst, maakt โt lever blots dicht)
+issues.start_tracking_history = `hett %s to warken begunnen`
+issues.lock.notice_2 = - Du un anner Mitarbeiders mit Togriep to deesem Repositorium kรถรถnt wiederhen Kommentaren schrieven, wat elkeenwell sรผcht.
+issues.due_date_modified = hett dat Anstahns-Datum vun %[2]s to %[1]s %[3]s รคnnert
+issues.dependency.issue_remove_text = Dat word de Ofhangen vun deesem Gefall wegdoon. Wiedermaken?
+issues.review.approve = hett %s deesen รnnerns tostimmt
+issues.review.dismissed = hett %[2]s dat Nakieken vun %[1]s ofseggt
+issues.lock.title = Snack up deesem Gefall tosluten.
+issues.unlock.title = Snack up deesem Gefall upsluten.
+issues.tracker_auto_close = Tiednehmer word automatisk anhollt, wenn dat Gefall dichtmaakt word
+issues.dependency.no_permission.can_remove = Du hest nich de Rechten, um deese Ofhangen to lesen, aver du kannst deese Ofhangen wegdoon
+issues.dependency.remove_info = Deese Ofhangen wegdoon
+issues.dependency.removed_dependency = `hett %s eene Ofhangen wegdaan`
+issues.dependency.issue_close_blocked = Du muttst all Gefallens, wat deeses Gefall blockeren, dichtmaken, ehr du dat hier dichtmaken kannst.
+issues.review.outdated = Verollt
+issues.review.option.show_outdated_comments = Verollte Kommentarens wiesen
+issues.review.un_resolve_conversation = Snack weer opmaken
+issues.tracking_already_started = `Du hest dat Tied-Erfaten al in eenem anner Gefall begunnen!`
+issues.due_date_invalid = Dat Anstahns-Datum is ungรผltig of buten de Rieg. Bidde bruuk dat Formaat ยปJJJJ-MM-DDยซ.
+issues.dependency.remove = Wegdoon
+issues.dependency.issue_close_blocks = Deeses Gefall blockeert dat Dichtmaken vun deesen Gefallens
+issues.review.outdated_description = Inholl hett sik รคnnert, siet deeser Kommentaar schreven worden is
+issues.force_push_codes = `hett %[1]s vun %[2]s
to %[4]s
%[6]s dwangsschuven`
+issues.dependency.pr_remove_text = Dat word de Ofhangen vun deesem Haalvรถrslag wegdoon. Wiedermaken?
+issues.review.pending = Staht ut
+issues.review.option.hide_outdated_comments = Verollte Kommentarens verbargen
+issues.due_date_form = JJJJ-MM-DD
+issues.dependency.added_dependency = `hett %s eene neje Ofhangen hentofรถรถgt`
+issues.review.wait = is %s um een Nakieken anfraggt worden
+issues.review.add_review_request = hett %[2]s um een Nakieken vun %[1]s anfraggt
+issues.review.show_outdated = Wies verollt
+issues.review.hide_outdated = Verbarg verollt
+issues.content_history.options = Instellens
+issues.reference_link = Nรถmen: %s
+compare.compare_base = Grund
+compare.compare_head = Verglieken
+pulls.desc = Haalvรถrslagen un Quelltext-Nakiekens anknipsen.
+pulls.new = Nejer Haalvรถrslag
+pulls.view = Haalvรถrslag wiesen
+pulls.allow_edits_from_maintainers = Bewarkens vun Liddmaten verlรถven
+pulls.allow_edits_from_maintainers_err = Vernejen fehlslagen
+pulls.compare_changes_desc = Kรถรถr de Twieg ut, waarhen tosamenfรถhrt worden sall, un vun welkem Twieg haalt worden sall.
+pulls.has_viewed_file = Ankiekt
+pulls.has_changed_since_last_review = Siet lestem Nakieken รคnnert
+pulls.viewed_files_label = %[1]d vun %[2]d Dateien ankiekt
+pulls.expand_files = All Dateien verwiedern
+pulls.collapse_files = All Dateien tosamenfolden
+pulls.compare_base = tosamenfรถhren na
+pulls.compare_compare = halen vun
+pulls.switch_head_and_base = Kopp un Grund tuusken
+pulls.filter_branch = Twieg filtern
+pulls.no_results = Keene Resultaten funnen.
+pulls.show_all_commits = All Kommitterens wiesen
+pulls.show_changes_since_your_last_review = รnnerns siet dienem lesten Nakieken wiesen
+pulls.showing_specified_commit_range = Blots รnnerns vun Kommitterens %[1]s bit %[2]s wiesen
+pulls.review_only_possible_for_full_diff = Nakieken gaht blots, wenn de hele Unnerscheed wiest word
+pulls.filter_changes_by_commit = Na Kommitteren filtern
+pulls.nothing_to_compare = Deese Twiegen sรผnd gliek. โt is nich nรถdig, eenen Haalvรถrslag to maken.
+pulls.nothing_to_compare_have_tag = De utkรถรถrt Twieg/Mark sรผnd gliek.
+pulls.create = Haalvรถrslag maken
+pulls.title_desc_one = will %[1]d Kommitteren vun %[2]s
na %[3]s
tosamenfรถhren
+pulls.merged_title_desc_one = hett %[1]d Kommitteren vun %[2]s
na %[3]s
%[4]s tosamenfรถhrt
+pulls.change_target_branch_at = `hett %[3]s de Enn-Twieg vun %[1]s to %[2]s รคnnert`
+pulls.tab_conversation = Snack
+pulls.tab_commits = Kommitterens
+pulls.tab_files = รnnert Dateien
+pulls.reopen_to_merge = Bidde maak deesen Haalvรถrslag weer op, um dat Tosamenfรถhren dรถrtofรถhren.
+pulls.cant_reopen_deleted_branch = Deeser Haalvรถrslag kann nich weer opmaakt worden, denn de Twieg is lรถsket worden.
+pulls.merged = Tosamenfรถhrt
+pulls.merged_success = Haalvรถrslag tosamenfรถhrt un dichtmaakt
+pulls.closed = Haalvรถrslag dichtmaakt
+pulls.manually_merged = Vun Hand tosamenfรถhrt
+pulls.merged_info_text = De Twieg %s kann nu lรถsket worden.
+pulls.is_closed = De Haalvรถrslag is dichtmaakt worden.
+pulls.title_wip_desc = `Begรผnn de Titel mit %s , daarmit de Haalvรถrslag nich ut Versehn tosamenfรถhrt word.`
+pulls.still_in_progress = Noch in de Maak?
+pulls.cannot_merge_work_in_progress = Deeser Haalvรถrslag is as noch in de Maak markeert.
+pulls.ready_for_review = Klaar tum Nakieken?
+pulls.add_prefix = Dat Prรคfix %s hentofรถgen
+pulls.remove_prefix = Dat Prรคfix %s wegdoon
+pulls.files_conflicted = Deeser Haalvรถrslag hett รnnerns, wat mit de Enn-Twieg unverdragelk sรผnd.
+pulls.is_ancestor = Deeser Twieg is al in de Enn-Twieg enthollen. Dat gifft nix tum tosamenfรถhren.
+pulls.is_empty = De รnnerns in deesem Twieg sรผnd al in de Enn-Twieg. Dat word een leger Kommitteren.
+pulls.required_status_check_failed = Eenige nรถdig รverprรผfens sรผnd fehlslagen.
+pulls.required_status_check_missing = Eenige nรถdig รverprรผfens sรผnd nich daar.
+pulls.required_status_check_administrator = As een Chef dรผรผrst du deesen Haalvรถrslag doch tosamenfรถhren.
+pulls.blocked_by_approvals = Deeser Haalvรถrslag hett noch nich genoog Tostimmens. %d vun %d Tostimmens geven.
+pulls.blocked_by_rejection = Een offizieller Nakieker hett um รnnerns an deesem Haalvรถrslag beden.
+pulls.blocked_by_outdated_branch = Deeser Haalvรถrslag is blockeert, denn he is verollt.
+pulls.cannot_auto_merge_desc = Deeser Haalvรถrslag kann nich automatisk tosamenfรถhrt worden, denn dat gifft Unverdragelkheidens.
+pulls.cannot_auto_merge_helper = Fรถhr dat vun Hand tosamen, um de Unverdragelkheidens oftohelpen.
+pulls.num_conflicting_files_1 = %d unverdragelk Datei
+pulls.approve_count_1 = %d Tostimmen
+pulls.reject_count_n = %d Bidden um รnnerns
+pulls.waiting_count_n = %d Nakiekens stahn ut
+pulls.wrong_commit_id = Kommitteren-ID mutt eene Kommitteren-ID up de Enn-Twieg wesen
+pulls.no_merge_helper = Knips Tosamenfรถhrens-Instellens in de Repositoriums-Instellens an of fรถhr de Tosamenfรถhren vun Hand tosamen.
+pulls.no_merge_wip = De Haalvรถrslag kann nich tosamenfรถhrt worden, denn dat is as noch in de Maak markeert.
+pulls.no_merge_not_ready = De Haalvรถrslag is nich klaar tum Tosamenfรถhren, bekiek de Nakiekens-Tostand un de รverprรผfens.
+pulls.merge_pull_request = Tosamenfรถhrens-Kommitteren maken
+pulls.has_pull_request = `Eenen Haalvรถrslag tรผsken deesen Twiegen gifft dat al: %[2]s#%[3]d `
+pulls.blocked_by_official_review_requests = Deeser Haalvรถrslag is blockeert, denn een of mehr offiziell Nakiekers hebben noch nich tostimmt.
+pulls.blocked_by_changed_protected_files_1 = Deeser Haalvรถrslag is blockeert, denn dat รคnnert eene beschรผtt Datei:
+pulls.no_merge_desc = De Haalvรถrslag kann nich tosamenfรถhrt worden, denn all Tosamenfรถhrens-Instellens sรผnd in deesem Repositorium utknipst.
+issues.review.resolved_by = hett deesen Snack as lรถรถst markeert
+issues.reference_issue.body = Text
+issues.content_history.delete_from_history = Ut Histoorje lรถsken
+pulls.compare_changes = Nejer Haalvรถrslag
+pulls.allow_edits_from_maintainers_desc = Brukers, well dat Recht hebben, to de Grund-Twieg to schrieven, dรผren ok up deesen Twieg schuuven
+pulls.nothing_to_compare_and_allow_empty_pr = Deese Twiegen sรผnd gliek. De HV word leeg wesen.
+pulls.title_desc_few = will %[1]d Kommitterens vun %[2]s
na %[3]s
tosamenfรถhren
+pulls.data_broken = Deeser Haalvรถrslag is kaputt, denn de Gabel-Informatioon fehlt.
+pulls.waiting_count_1 = %d Nakieken staht ut
+issues.content_history.deleted = lรถsket
+issues.content_history.created = maakt
+issues.content_history.delete_from_history_confirm = Ut Histoorje lรถsken?
+issues.blocked_by_user = Du kannst in deesem Repositorium keene Gefallens opmaken, denn de Repositoriums-Eegner hett di blockeert.
+pulls.merged_title_desc_few = hett %[1]d Kommitterens vun %[2]s
na %[3]s
%[4]s tosamenfรถhrt
+pulls.reject_count_1 = %d Bidde um รnnerns
+pulls.blocked_by_user = Du kannst in deesem Repositorium keenen Haalvรถrslag opmaken, denn de Repositoriums-Eegner hett di blockeert.
+pulls.no_merge_access = Du hest nich dat Recht, deesen Haalvรถrslag tosamentofรถhren.
+issues.comment.blocked_by_user = Du kannst up deesem Gefall nich kommenteren, denn de Repositoriums-Eegner of de Autor vun de Gefall hett di blockeert.
+pulls.switch_comparison_type = Verglieks-Aard รคnnern
+pulls.showing_only_single_commit = Blots รnnerns vun Kommitteren %[1]s wiesen
+pulls.blocked_by_changed_protected_files_n = Deeser Haalvรถrslag is blockeert, denn dat รคnnert beschรผtt Dateien:
+pulls.num_conflicting_files_n = %d unverdragelk Dateien
+issues.content_history.edited = bewarkt
+pulls.select_commit_hold_shift_for_range = Kommitteren utkรถren. Holl Umschalt un Klick, um eene Rieg uttokรถren
+pulls.is_checking = รverprรผfen vun Tosamenfรถhrens-Unverdragelkheidens lรถppt. Bidde versรถรถk dat in kรถrter Tied noch eenmaal.
+pulls.can_auto_merge_desc = Deeser Haalvรถrslag kann automatisk tosamenfรถhrt worden.
+pulls.approve_count_n = %d Tostimmens
+pulls.rebase_merge_pull_request = Umbaseren dann fix na vรถrn
+pulls.rebase_merge_commit_pull_request = Umbaseren dann Tosamenfรถhrens-Kommitteren maken
+pulls.squash_merge_pull_request = Plattdrรผck-Kommitteren maken
+pulls.fast_forward_only_merge_pull_request = Blots fix na vรถrn
+pulls.merge_manually = Vun Hand tosamenfรถhrt
+pulls.merge_commit_id = De Tosamenfรถhrens-Kommitteren-ID
+pulls.require_signed_wont_sign = De Twieg bruukt unnerschrieven Kommitterens, aver deeses Tosamenfรถhren word nich unnerschrieven wesen
+pulls.invalid_merge_option = Du kannst deese Tosamenfรถhrens-Instellen fรถr deesen Haalvรถrslag nich bruken.
+pulls.merge_conflict = Tosamenfรถhren fehlslagen: Dat hett biโm Tosamenfรถhren eene Unverdragelkheid geven. Wenk: Versรถรถk eene anner Tosamenfรถhrens-Aard
+pulls.merge_conflict_summary = Fehler-Naricht
+pulls.rebase_conflict = Tosamenfรถhren fehlslagen: Dat hett biโm Umbaseren vun Kommitteren %[1]s eene Unverdragelkheid geven. Wenk: Versรถรถk eene anner Tosamenfรถhrens-Aard
+pulls.rebase_conflict_summary = Fehler-Naricht
+pulls.merge_out_of_date = Tosamenfรถhren fehlslagen: Biโm Tosamenfรถhren is de Grund verneeit worden. Wenk: Versรถรถk dat noch eenmaal.
+pulls.head_out_of_date = Tosamenfรถhren fehlslagen: Biโm Tosamenfรถhren is de Kopp verneeit worden. Wenk: Versรถรถk dat noch eenmaal.
+pulls.push_rejected_summary = Kumpleete Oflehnens-Naricht
+pulls.push_rejected = Schuven fehlslagen: Dat Schuven is oflehnt worden. Bidde รถverprรผรผf de Git-Hakens fรถr deeses Repositorium.
+pulls.open_unmerged_pull_exists = `Du kannst dat nich weer opmaken, denn dat gifft een anner open Haalvรถrslag (#%d) mit akkeraat de sรผlven Eegenskuppen.`
+pulls.status_checking = Eenige รverprรผfens stahn ut
+pulls.status_checks_success = All รverprรผfens sรผnd klaar
+pulls.status_checks_warning = Eenige รverprรผfens hebben Wahrschauens mellt
+pulls.status_checks_error = Eenige รverprรผfens hebben Fehlers mellt
+pulls.status_checks_failure = Eenige รverprรผfens sรผnd fehlslagen
+pulls.status_checks_requested = Nรถdig
+pulls.status_checks_hide_all = All รverprรผfens verbargen
+pulls.status_checks_details = Mehr Informatioonen
+pulls.status_checks_show_all = All รverprรผfens wiesen
+pulls.update_branch_rebase = Twieg mit Umbaseren vernejen
+pulls.outdated_with_base_branch = De Twieg is tegen de Grund-Twieg verollt
+pulls.close = Haalvรถrslag dichtmaken
+pulls.closed_at = `hett deesen Haalvรถrslag %[2]s dichtmaakt`
+pulls.reopened_at = `hett deesen Haalvรถrslag %[2]s weer opmaakt`
+pulls.cmd_instruction_hint = Wies Oorderreeg-Instruksjes
+pulls.cmd_instruction_checkout_title = Utchecken
+pulls.cmd_instruction_merge_title = Tosamenfรถhren
+pulls.clear_merge_message = Tosamenfรถhrens-Naricht leegmaken
+pulls.reopen_failed.head_branch = De Haalvรถrslag kann nich weer opmaakt worden, denn de Kopp-Twieg gifft dat nich mehr.
+pulls.reopen_failed.base_branch = De Haalvรถrslag kann nich weer opmaakt worden, denn de Grund-Twieg gifft dat nich mehr.
+pulls.made_using_agit = AGit
+pulls.auto_merge_when_succeed = Automatisk Tosamenfรถhren, wenn all รverprรผfens kumpleet sรผnd
+pulls.auto_merge_newly_scheduled_comment = ` hett de Haalvรถrslag %[1]s sett, sik tosamentofรถhren, wenn all รverprรผfens kumpleet sรผnd`
+pulls.delete.title = Deesen Haalvรถrslag lรถsken?
+pulls.recently_pushed_new_branches = Du hest to de Twieg %[1]s %[2]s schuven
+milestones.new = Nejer Marksteen
+milestones.closed = %s dichtmaakt
+milestones.open = Opmaken
+milestones.close = Dichtmaken
+milestones.completeness = %d%% Kumpleet
+milestones.create = Marksteen maken
+milestones.desc = Beschrieven
+milestones.due_date = Anstahns-Datum (kann leeg wesen)
+milestones.create_success = De Marksteen ยป%sยซ is maakt worden.
+milestones.edit = Marksteen bewarken
+milestones.edit_subheader = Markstenen organiseren Gefallens un verfolgen Wiederkomen.
+milestones.cancel = Ofbreken
+milestones.modify = Marksteen vernejen
+milestones.edit_success = Marksteen ยป%sยซ is verneeit worden.
+milestones.deletion = Marksteen lรถsken
+pulls.has_merged = Fehlslagen: De Haalvรถrslag is tosamenfรถhrt worden, du kannst nich noch eenmaal tosamenfรถhren of de Enn-Twieg รคnnern.
+pulls.unrelated_histories = Tosamenfรถhren fehlslagen: De Tosamenfรถhrens-Kopp un -Grund hebben keene gemeensame Histoorje. Wenk: Versรถรถk eene anner Tosamenfรถhrens-Aard
+pulls.update_not_allowed = Du dรผรผrst deesen Twieg nich vernejen
+pulls.commit_ref_at = `hett deesen Haalvรถrslag %[2]s vun eenem Kommitteren benรถรถmt`
+pulls.auto_merge_newly_scheduled = De Haalvรถrslag weer sett, sik tosamentofรถhren, wenn all รverprรผfens kumpleet sรผnd.
+milestones.clear = Leeg maken
+pulls.push_rejected_no_message = Schuven fehlslagen: Dat Schuven is sรผnner feerne Naricht oflehnt worden. Bidde รถverprรผรผf de Git-Hakens fรถr deeses Repositorium
+pulls.update_branch = Twieg mit Tosamenfรถhren vernejen
+pulls.update_branch_success = Twieg is verneeit worden
+pulls.cmd_instruction_checkout_desc = Check in dienem Projekt-Repositorium eenen nejen Twieg ut un probeer de รnnerns ut.
+pulls.cmd_instruction_merge_desc = Fรถhr de รnnerns tosamen un veneei up Forgejo.
+pulls.cmd_instruction_merge_warning = Wahrschau: De Instellens ยปTosamenfรถhren vun Hand automatisk erkennenยซ is fรถr deeses Repositorium utknipst, du muttst deesen Haalvรถrslag daarna noch as vun Hand tosamenfรถhrt markeren.
+pulls.auto_merge_button_when_succeed = (Wenn รverprรผfens kumpleet sรผnd)
+pulls.auto_merge_cancel_schedule = Automatisk Tosamenfรถhren ofbreken
+pulls.auto_merge_canceled_schedule = Dat automatisk Tosamenfรถhren is fรถr deesen Haalvรถrslag ofbroken worden.
+pulls.agit_explanation = Mit de AGit-Warkwies maakt. AGit lett Bidragers รnnerns mit ยปgit pushยซ vรถrslagen, sรผnner eene Gabel of eenen nejen Twieg to maken.
+pulls.auto_merge_has_pending_schedule = %[1]s hett de Haalvรถrslag %[2]s sett, sik tosamentofรถhren, wenn all รverprรผfens kumpleet sรผnd.
+pulls.auto_merge_not_scheduled = Deeser Haalvรถrslag is nich fรถr dat automatisk Tosamenfรถhren sett.
+pull.deleted_branch = (lรถsket):%s
+pulls.auto_merge_canceled_schedule_comment = ` hett dat automatisk Tosamenfรถhren vun deesem Haalvรถrslag, wenn all รverprรผfens kumpleet sรผnd, %[1]s ofbroken`
+pulls.delete.text = Willst du deesen Haalvรถrslag wรผrrelk lรถsken? (Dat lรถsket fรถr all Tieden all Inhollen. Wenn du โt blots archiveren willst, maakt โt lever blots dicht)
+milestones.update_ago = %s verneeit
+milestones.no_due_date = Keen Anstahns-Datum
+milestones.new_subheader = Markstenen kรถnen di hรผlpen, Gefallens to organiseren un hรถr Wiederkomen to verfolgen.
+milestones.title = Titel
+milestones.invalid_due_date_format = Anstahns-Datums-Formaat mutt ยปJJJJ-MM-DDยซ wesen.
+milestones.deletion_desc = Wenn een Marksteen lรถsket word, word dat vun all benรถรถmt Gefallens wegdaan. Wiedermaken?
+milestones.deletion_success = De Marksteen is lรถsket worden.
+milestones.filter_sort.name = Naam
+milestones.filter_sort.latest_due_date = Feernst Anstahns-Datum
+milestones.filter_sort.least_complete = Minnst kumpleet
+milestones.filter_sort.most_complete = Meest kumpleet
+milestones.filter_sort.most_issues = Meest Gefallens
+signing.will_sign = Deeses Kommitteren word mit de Slรถtel ยป%sยซ unnerschreven.
+signing.wont_sign.nokey = Deese Instanz hett keenen Slรถtel, um deeses Kommitteren to unnerschrieven.
+signing.wont_sign.never = Kommitterens worden nie unnerschrieven.
+signing.wont_sign.always = Kommitterens worden alltieden unnerschrieven.
+signing.wont_sign.twofa = Du muttst Twee-Faktooren-Anmellen anknipsen, um Kommitterens to unnerschrieven.
+signing.wont_sign.headsigned = Deeses Kommitteren word nich unnerschrieven, denn dat Kopp-Kommitteren is nich unnerschreven.
+signing.wont_sign.basesigned = Deeses Kommitteren word nich unnerschrieven, denn dat Grund-Kommitteren is nich unnerschreven.
+signing.wont_sign.commitssigned = Dat Tosamenfรถhren word nich unnerschrieven, denn de Kommitterens vun Belang sรผnd nich all unnerschreven.
+signing.wont_sign.approved = Dat Tosamenfรถhren word nich unnerschrieven, denn de HV is nich tostimmt.
+signing.wont_sign.not_signed_in = Du bรผst nich anmellt.
+ext_wiki = Frรถmdes Wiki
+wiki = Wiki
+wiki.welcome = Willkomen im Wiki.
+wiki.desc = Schriev un deel Dokumenterens mit Mitarbeiders.
+wiki.create_first_page = Maak de eerste Sied
+wiki.page = Sied
+wiki.filter_page = Sied filtern
+wiki.new_page = Sied
+wiki.page_title = Sied-Titel
+wiki.page_content = Sied-Text
+wiki.default_commit_message = Schriev eene Notiz รถver deeses Sieden-Vernejen (wenn du willst).
+wiki.save_page = Sied sekern
+wiki.cancel = Ofbreken
+wiki.last_commit_info = %s hett diese Sied %s bewarkt
+wiki.edit_page_button = Bewarken
+wiki.new_page_button = Neje Sied
+wiki.file_revision = Sied-Versioon
+wiki.back_to_wiki = Torรผgg tur Wiki-Sied
+wiki.delete_page_button = Sied lรถsken
+wiki.delete_page_notice_1 = Wenn du de Wiki-Sied ยป%sยซ lรถskest, kann se nich mehr torรผgghaalt worden. Wiedermaken?
+wiki.reserved_page = De Wiki-Sied-Naam ยป%sยซ is vรถrbehollen.
+wiki.pages = Sieden
+wiki.last_updated = Tolest %s verneeit
+wiki.original_git_entry_tooltip = Wies de echte Git-Datei un bruuk nich de frรผndelk Verwies.
+wiki.search = Im Wiki sรถken
+wiki.no_search_results = Keene Resultaten
+activity = Doon
+activity.navbar.pulse = Puls
+activity.navbar.code_frequency = Quelltext-Frequenz
+activity.navbar.contributors = Bidragers
+activity.navbar.recent_commits = Leste Kommitterens
+activity.period.filter_label = Tied:
+activity.period.daily = 1 Dag
+activity.period.halfweekly = 3 Dagen
+activity.overview = รversicht
+activity.active_prs_count_1 = %d aktiiv Haalvรถrslag
+activity.merged_prs_count_1 = Tosamenfรถhrt Haalvรถrslag
+activity.opened_prs_count_1 = Nejer Haalvรถrslag
+activity.title.user_n = %d Brukers
+activity.title.prs_n = %d Haalvรถrslagen
+activity.title.prs_merged_by = %s vun %s tosamenfรถhrt
+activity.title.prs_opened_by = %s vun %s opmaakt
+activity.merged_prs_label = Tosamenfรถhrt
+activity.opened_prs_label = Neei vรถrslagen
+activity.active_issues_count_1 = %d aktiiv Gefall
+activity.closed_issues_count_1 = Dichtmaakt Gefall
+activity.title.issues_closed_from = %s vun %s dichtmaakt
+activity.title.issues_created_by = %s vun %s opmaakt
+activity.new_issues_count_1 = Nejes Gefall
+activity.new_issues_count_n = Neje Gefallens
+activity.new_issue_label = Opmaakt
+activity.closed_issue_label = Dichtmaakt
+activity.title.unresolved_conv_1 = %d nich lรถรถst Snack
+activity.unresolved_conv_desc = Deese kรถrtens รคnnert Gefallens un Haalvรถrslagen sรผnd noch nich lรถรถst worden.
+activity.unresolved_conv_label = Open
+activity.published_release_label = Publizeren
+activity.published_tag_label = Mark
+activity.no_git_activity = In deeser Tied hett dat keen Kommitterens-Doon geven.
+activity.git_stats_exclude_merges = Sรผnner Tosamenfรถhrens
+activity.git_stats_author_1 = %d Autor
+activity.git_stats_author_n = %d Autoren
+activity.git_stats_pushed_1 = hett
+activity.git_stats_pushed_n = hebben
+activity.git_stats_commit_1 = %d Kommittteren
+activity.git_stats_commit_n = %d Kommittterens
+activity.git_stats_push_to_branch = to %s un
+activity.git_stats_push_to_all_branches = to all Twiegen schuven.
+activity.git_stats_on_default_branch = Up %s
+activity.git_stats_files_changed_n = รคnnert worden
+activity.git_stats_addition_n = %d neje Riegen
+activity.git_stats_addition_1 = %d neje Rieg
+activity.git_stats_and_deletions = un
+activity.git_stats_deletion_1 = %d lรถsket Rieg geven
+activity.commit = Kommitterens-Doon
+contributors.contribution_type.filter_label = Bidrag-Aard:
+contributors.contribution_type.additions = Neje Riegen
+settings = Instellens
+settings.options = Repositorium
+settings.collaboration = Mitarbeiders
+settings.collaboration.admin = Chef
+settings.collaboration.write = Schrieven
+settings.collaboration.read = Lesen
+settings.collaboration.owner = Eegner
+settings.hooks = Internett-Hakens
+settings.collaboration.undefined = Nich sett
+settings.githooks = Git-Hakens
+settings.basic_settings = Grund-Instellens
+settings.federation_not_enabled = Verdeeltheid is in diener Instanz utknipst.
+settings.mirror_settings.docs.disabled_push_mirror.instructions = Sett dien Repositorium, dat Kommitterens, Markens un Twiegen automatisk vun eenem anner Repositorium haalt worden.
+settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning = Jรผรผst nu kann dat blots in de Menรผ ยปNejer Umtreckยซ maakt worden. Fรถr mehr Informatioonen, bekiek bidde:
+settings.mirror_settings.docs.disabled_push_mirror.info = Schuuv-Spegels sรผnd vun dienem Sied-Chef utknipst worden.
+settings.mirror_settings.docs.no_new_mirrors = Dien Repositorium spegelt รnnerns to of vun eenem anner Repositorium. Bidde wees wiss, dat du jรผรผst nu keene nejen Spegels maken kannst.
+settings.mirror_settings.docs.can_still_use = Ok wenn du keene Spegels bewarken of neje maken kannst, dรผรผrst du diene bestahn Spegels wiederhen bruken.
+settings.mirror_settings.docs.pull_mirror_instructions = Um eenen Haal-Spegel intorichten, bekiek bidde:
+settings.mirror_settings.docs.more_information_if_disabled = Hier lehrst du mehr รถver Schuuv- un Haal-Spegels:
+settings.mirror_settings.docs.doc_link_title = Wo spegel ick Repositoriums?
+settings.mirror_settings.mirrored_repository = Spegelt Repositorium
+settings.mirror_settings.direction = Richtung
+settings.mirror_settings.direction.pull = Halen
+settings.mirror_settings.direction.push = Schuven
+settings.mirror_settings.last_update = Tolest verneeit
+settings.mirror_settings.push_mirror.edit_sync_time = Spegelns-Tiedofstand bewarken
+settings.mirror_settings.push_mirror.none_ssh = Nix
+settings.units.overview = รversicht
+settings.mirror_settings.push_mirror.copy_public_key = Publiken Slรถtel koperen
+settings.pull_mirror_sync_in_progress = Haalt jรผรผst รnnerns vun de feernen Stee %s.
+settings.pull_mirror_sync_quota_exceeded = Quote รถverweggahn, haalt keene รnnerns.
+settings.site = Internett-Sied
+settings.update_settings = Instellens sekern
+settings.branches.update_default_branch = Hรถรถvd-Twieg vernejen
+settings.branches.add_new_rule = Neje รrder hentofรถgen
+settings.advanced_settings = Mehr Instellens
+settings.use_internal_wiki = Inbaut Wiki bruken
+settings.external_wiki_url = URL vum frรถmden Wiki
+settings.use_internal_issue_tracker = Inbaut Gefall-Verfolger bruken
+settings.external_tracker_url = URL vum frรถmden Gefall-Verfolger
+settings.tracker_url_format = URL-Formaat vum frรถmden Gefall-Verfolger
+settings.tracker_url_format_error = Dat URL-Formaat vum frรถmden Gefall-Verfolger is keene gรผltige URL.
+settings.tracker_issue_style.numeric = Numerisk
+settings.tracker_issue_style.regexp = Regel-Utdruck
+settings.tracker_issue_style.regexp_pattern = Regel-Utdruck-Muster
+settings.enable_timetracker = Tied-Erfaten anknipsen
+settings.allow_only_contributors_to_track_time = Blots Bidragers Tied erfaten laten
+settings.pulls_desc = Haalvรถrslagen im Repositorium anknipsen
+settings.pulls.ignore_whitespace = Leegtekens fรถr Unverdragelkheidens minnachten
+settings.pulls.allow_rebase_update = Verlรถven, Haalvรถrslag-Twieg dรถr Umbaseren to vernejen
+settings.pulls.default_delete_branch_after_merge = Haalvรถrslag-Twieg na de Tosamenfรถhren automatisk lรถsken
+settings.pulls.default_allow_edits_from_maintainers = Bewarkens vun Liddmaten normaal verlรถven
+settings.releases_desc = Repositorium-Publizerens anknipsen
+settings.packages_desc = Repositorium-Paketlist anknipsen
+settings.projects_desc = Repositorium-Projekten anknipsen
+settings.admin_settings = Chef-Instellens
+settings.admin_code_indexer = Quelltext-Indizerer
+settings.admin_stats_indexer = Quelltext-Statistiken-Indizerer
+settings.admin_indexer_commit_sha = Tolest indizeert Kommitteren
+settings.admin_indexer_unindexed = Nich indizeert
+settings.reindex_requested = Nejes Indizeren vรถrmarkt
+settings.reindex_button = Tum Neeiindizeren vรถrmarken
+settings.danger_zone = Gefahren-Zoon
+settings.convert_succeed = De Spegel is in een normaales Repositorium umwannelt worden.
+settings.convert_fork = To normaalem Repositorium umwanneln
+settings.convert_fork_desc = Du kannst deese Gabel in een normaales Repositorium umwanneln. Dat kann nich torรผggnohmen worden.
+settings.convert_fork_confirm = Repositorium umwanneln
+settings.convert_fork_succeed = De Gabel is in een normaales Repositorium umwannelt worden.
+settings.transfer.title = Eegnerskupp รถverdragen
+settings.transfer.button = Eegnerskupp รถverdragen
+settings.transfer.modal.title = Eegnerskupp รถverdragen
+settings.transfer.rejected = Repositoriums-รverdragen is oflehnt worden.
+settings.transfer.success = Repositoriums-รverdragen is ofsluten.
+settings.transfer_abort = รverdragen ofbreken
+settings.transfer_abort_invalid = Du kannst een Repositoriums-รverdragen, wat dat nich gifft, nich ofbreken.
+settings.confirmation_string = Utwiesens-Text
+settings.transfer_in_progress = Een รverdraag lรถppt al. Bidde breck dat eerst of, wenn du deeses Repositorium to een anner Bruker รถverdragen willst.
+settings.transfer_perform = รverdragen dรถrfรถhren
+settings.transfer_succeed = Dat Repositorium is รถverdragen worden.
+settings.transfer_quota_exceeded = De neje Eegner (%s) is รถver de Quote. Dat Repositorium is nich รถverdragen worden.
+milestones.filter_sort.earliest_due_data = Nahst Anstahns-Datum
+milestones.filter_sort.least_issues = Minnst Gefallens
+wiki.wiki_page_revisions = Sied-Versioonen
+activity.period.yearly = 1 Jahr
+activity.title.issues_1 = %d Gefall
+activity.git_stats_files_changed_1 = รคnnert worden
+activity.git_stats_deletion_n = %d lรถsket Riegen geven
+contributors.contribution_type.deletions = Lรถsket Riegen
+settings.federation_following_repos = URLs vun Nagahns-Repositoriums. Trennt mit ยป;ยซ, keene Leegtekens.
+settings.mirror_settings.docs = Sett dien Repositorium, dat Kommitterens, Markens un Twiegen automatisk mit eenem anner Repositorium spegelt worden.
+settings.mirror_settings.push_mirror.add = Schuuv-Spegel hentofรถgen
+settings.units.add_more = Mehr anknipsen
+settings.branches.switch_default_branch = Hรถรถvd-Twieg รคnnern
+settings.use_external_wiki = Frรถmdes Wiki bruken
+settings.external_tracker_url_error = De URL vum frรถmden Gefall-Verfolger is keene gรผltige URL.
+settings.actions_desc = Integreerte CI-/CD-Affolgens mit Forgejo-Aktioonen anknipsen
+settings.convert_notices_1 = Dat wannelt deesen Spegel in een normaales Repositorium um un kann nich torรผggnohmen worden.
+settings.convert_confirm = Repositorium umwanneln
+signing.wont_sign.parentsigned = Deeses Kommitteren word nich unnerschrieven, denn dat Ollern-Kommitteren is nich unnerschreven.
+wiki.page_already_exists = Eene Wiki-Sied mit de sรผlven Naam gifft dat al.
+activity.period.weekly = 1 Week
+activity.period.monthly = 1 Maant
+activity.closed_issues_count_n = Dichtmaakt Gefallens
+settings.desc = Unner ยปInstellensยซ kannst du de Instellens fรถr dat Repositorium verwalten
+settings.federation_apapiurl = Verdeeltheids-URL vun deesem Repositorium. Kopeer un fรถรถg dat in de Verdeeltheids-Instellens vun eenem anner Repositorium as eene URL vun eenem Nagahns-Repositorium in.
+settings.mirror_settings.docs.doc_link_pull_section = de Deel ยปVun eenem feernen Repositorium halenยซ in de Dokumenteren.
+settings.mirror_settings.pushed_repository = Schuuvt Repositorium
+settings.units.units = Eenheiden
+settings.wiki_globally_editable = Elkeenwell verlรถven, dat Wiki to bewarken
+settings.tracker_issue_style.regexp_pattern_desc = De eerste Fangens-Grupp word in Stee vun {index}
bruukt.
+settings.convert = To normaalem Repositorium umwanneln
+settings.convert_desc = Du kannst deesen Spegel in een normaales Repositorium umwanneln. Dat kann nich torรผggnohmen worden.
+settings.transfer_abort_success = Dat Repositoriums-รverdragen na %s is ofbroken worden.
+signing.wont_sign.error = Biโm Nakieken, of dat Kommitteren unnerschrieven worden kann, hett dat eenen Fehler geven.
+signing.wont_sign.pubkey = Deeses Kommitteren word nich unnerschrieven, denn du hest in dienem Konto keenen publiken Slรถtel angeven.
+activity.active_prs_count_n = %d aktiiv Haalvรถrslagen
+activity.merged_prs_count_n = Tosamenfรถhrt Haalvรถrslagen
+activity.title.user_1 = %d Bruker
+activity.title.prs_1 = %d Haalvรถrslag
+activity.active_issues_count_n = %d aktiiv Gefallens
+activity.title.issues_n = %d Gefallens
+activity.title.unresolved_conv_n = %d nich lรถรถst Snacks
+activity.title.releases_1 = %d Publizeren
+activity.git_stats_file_1 = is %d Datei
+contributors.contribution_type.commits = Kommitterens
+settings.mirror_settings = Spegel-Instellens
+settings.federation_settings = Verdeeltheid-Instellens
+settings.mirror_settings.docs.disabled_pull_mirror.instructions = Sett dien Repositorium, dat Kommitterens, Markens un Twiegen automatisk to eenem anner Repositorium schuuvt worden. Haal-Spegels sรผnd vun dienem Sied-Chef utknipst worden.
+settings.mirror_settings.docs.pulling_remote_title = Vun eenem feernen Repositorium halen
+settings.sync_mirror = Nu spegeln
+settings.update_mirror_settings = Spegel-Instellens vernejen
+activity.git_stats_additions = un dat hett
+settings.mirror_settings.push_mirror.none = Keene Schuuv-Spegels inricht
+settings.mirror_settings.push_mirror.remote_url = Feerne Git-Repositoriums-URL
+settings.wiki_desc = Repositoriums-Wiki anknipsen
+settings.external_wiki_url_error = De URL vum frรถmden Wiki is keene gรผltige URL.
+settings.use_external_issue_tracker = Frรถmden Gefall-Verfolger bruken
+wiki.welcome_desc = Dat Wiki lett di Dokumenterens mit Mitarbeiders schrieven un delen.
+wiki.page_name_desc = Giff eenen Naam fรถr deese Wiki-Sied in. Eenige besรผnnere Namens sรผnd: ยปHomeยซ, ยป_Sidebarยซ un ยป_Footerยซ.
+activity.period.quarterly = 3 Maanten
+activity.period.semiyearly = 6 Maanten
+activity.opened_prs_count_n = Neje Haalvรถrslagen
+settings.tracker_issue_style.alphanumeric = Alphanumerisk
+settings.transfer_owner = Nejer Eegner
+activity.title.releases_n = %d Publizerens
+activity.title.releases_published_by = %s vun %s publizeert
+activity.published_prerelease_label = Vรถr-Publizeren
+activity.git_stats_file_n = sรผnd %d Dateien
+settings.push_mirror_sync_in_progress = Schuuvt jรผรผst รnnerns to de feernen Stee %s.
+settings.pulls.enable_autodetect_manual_merge = Tosamenfรถhren vun Hand automatisk erkennen (Wahrschau: In eenigen besรผnneren Fallen kann dat falsk oordelen)
+settings.convert_fork_notices_1 = Dat wannelt deese Gabel in een normaales Repositorium um un kann nich torรผggnohmen worden.
+settings.enter_repo_name = Giff de Eegner un Repositoriums-Naam jรผรผst so in, as se wiesen worden:
+settings.transfer_notices_2 = - Du hest wiederhen Togriep up dat Repositorium, wenn du dat to eener Vereenigung รถverdraggst, waar du een Eegner bรผst.
+settings.transfer_started = Deeses Repositorium is tum รverdragen vรถrmarkt worden un wacht up Verlรถรถv vun ยป%sยซ
+settings.external_wiki_url_desc = Besรถkers worden to de URL vum frรถmden Wiki umleit, wenn se up de Wiki-Karteikaart klicken.
+settings.issues_desc = Repositoriums-Gefall-Verfolger anknipsen
+settings.external_tracker_url_desc = Besรถkers worden to de URL vum frรถmden Gefall-Verfolger umleit, wenn se up de Gefallens-Karteikaart klicken.
+settings.tracker_issue_style = Tahlen-Formaat vum frรถmden Gefall-Verfolger
+settings.tracker_url_format_desc = Bruuk de Utdruckens {user}
, {repo}
un {index}
fรถr de Brukernaam, Repositoriums-Naam un Gefall-Tahl.
+settings.admin_enable_health_check = Repositorium-Gesundheids-รverprรผfens anknipsen (git fsck)
+settings.admin_enable_close_issues_via_commit_in_any_branch = Een Gefall รถver een Kommitteren sluten, wat in eenem nich-Hรถรถvd-Twieg maakt worden is
+settings.new_owner_has_same_repo = De neje Eegner hett al een Repositorium mit de sรผlven Naam. Bidde kรถรถr een anner Naam ut.
+settings.new_owner_blocked_doer = De neje Eegner hett di blockeert.
+settings.transfer_desc = รverdraag deeses Repositorium to eenem Bruker of eener Vereenigung, waar du Chef-Rechtens hest.
+settings.transfer_notices_1 = - Du hest keen Togriep mehr up dat Repositorium, wenn du dat to eenem enkelt Bruker รถverdraggst.
+settings.transfer_notices_3 = - Wenn dat Repositorium privaat is un to eenem enkelt Bruker รถverdragen word, passt deese Aktioon up, dat de Bruker tominnst Lesen-Togriep hett (un รคnnert de Rechtens as nรถdig).
+settings.signing_settings = Unnerschrift-Utwiesens-Instellens
+settings.trust_model.collaborator = Mitarbeider
+settings.trust_model.collaborator.long = Mitarbeider: Unnerschriftens vun Mitarbeiders vertrauen
+settings.trust_model.committer = Kommitterer
+settings.trust_model.committer.long = Kommitterer: Vertrau Unnerschriften, wat to de Kommitterer passen (Dat is jรผรผst as up GitHub un dwingt, dat Kommitterens, wat vun Forgejo unnerschrieven worden, Forgejo as Kommitterer hebben)
+settings.trust_model.committer.desc = Gรผltige Unnerschriften worden blots dann as ยปvertrautยซ markeert, wenn se to de Kommitterer passen, un sรผnst as ยปunvertrautยซ. Dat dwingt Forgejo, de Kommitterer up unnerschrieven Kommitterens to wesen, un de eegentlik Kommitterer word mit Nadragen ยปCo-authored-by:ยซ un ยปCo-committed-by:ยซ im Kommitteren vermarkt. De normaale Slรถtel fรถr Forgejo mutt to eenem Bruker in de Datenbank passen.
+settings.trust_model.collaboratorcommitter = Mitarbeider+Kommitterer
+settings.trust_model.collaboratorcommitter.long = Mitarbeider+Kommitterer: Vertrau Unnerschriften vun Mitarbeiders, wat to de Kommitterer passen
+settings.wiki_rename_branch_main_notices_1 = Dat KANN NICH torรผggnohmen worden.
+settings.wiki_rename_branch_main_notices_2 = Dat benรถรถmt fรถr all Tieden de binnern Twieg vun de Repositoriums-Wiki vun %s um. Bestahn Utcheckens mutten dann verneeit worden.
+settings.wiki_branch_rename_failure = Kunn de Twieg-Naam vun de Wiki vun de Repositorium nich normaliseren.
+settings.confirm_wiki_branch_rename = De Wiki-Twieg umbenรถรถmen
+settings.wiki_delete = Wiki-Daten lรถsken
+settings.wiki_delete_desc = De Repositoriums-Wiki-Daten to lรถsken is fรถr all Tieden un kann nich torรผggnohmen worden.
+settings.wiki_delete_notices_1 = - Dat word dat Repositoriums-Wiki fรถr %s fรถr all Tieden lรถsken un utknipsen.
+settings.confirm_wiki_delete = Wiki-Daten lรถsken
+settings.delete = Deeses Repositorium lรถsken
+settings.delete_desc = Een Repositorium to lรถsken is fรถr all Tieden un kann nich torรผggnohmen worden.
+settings.delete_notices_1 = - Dat KANN NICH torรผggnohmen worden.
+settings.trust_model.default = Normaales Vertroens-Modell
+settings.wiki_deletion_success = De Repositoriums-Wiki-Daten sรผnd lรถsket worden.
+settings.trust_model = Unnerschrift-Vertroens-Modell
+settings.trust_model.collaborator.desc = Gรผltige Unnerschriften vun Mitarbeiders in deesem Repositorium worden as ยปvertrautยซ markeert (of se to de Kommitterer passen of nich). Annerns worden gรผltige Unnerschriften as ยปunvertrautยซ markeert, wenn de Unnerschrift tum Kommitterer passt, un as ยปpasst nichยซ, wenn nich.
+settings.trust_model.collaboratorcommitter.desc = Gรผltige Unnerschriften vun Mitarbeiders in deesem Repositorium worden as ยปvertrautยซ markeert, wenn se to de Kommitterer passen. Annerns worden gรผltige Unnerschriften as ยปunvertrautยซ markeert, wenn de Unnerschrift tum Kommitterer passt, un as ยปpasst nichยซ, wenn nich. Dat dwingt Forgejo, de Kommitterer up unnerschrieven Kommitterens to wesen, un de eegentlik Kommitterer word mit Nadragen ยปCo-authored-by:ยซ un ยปCo-committed-by:ยซ im Kommitteren vermarkt. De normaale Slรถtel fรถr Forgejo mutt to eenem Bruker in de Datenbank passen.
+settings.trust_model.default.desc = Dat normaale Repositoriums-Vertroens-Modell fรถr deese Instanz bruken.
+settings.wiki_rename_branch_main_desc = De Twieg, wat binnern vun de Wiki bruukt word, to ยป%sยซ umbenรถรถmen. Deeses รnnern is fรถr all Tieden un kann nich torรผggnohmen worden.
+settings.wiki_rename_branch_main = De Wiki-Twieg-Naam normaliseren
+settings.wiki_branch_rename_success = De Twieg-Naam vun de Wiki vun de Repositorium is normaliseert worden.
+settings.delete_notices_2 = - Dat lรถsket fรถr all Tieden dat Repositorium %s mit all Quelltexten, Gefallens, Kommentaren, Wiki-Daten un Mitarbeider-Instellens.
+settings.deletion_success = Dat Repositorium is lรถsket worden.
+settings.update_settings_success = De Repositoriums-Instellens sรผnd verneeit worden.
+settings.add_collaborator_success = De Mitarbeider is hentofรถรถgt worden.
+settings.add_collaborator_owner = Kann eenen Eegner nich as Mitarbeider hentofรถgen.
+settings.add_collaborator_duplicate = Deeser Mitarbeider is al to de Repositorium hentofรถรถgt worden.
+settings.add_collaborator_blocked_our = Kann de Mitarbeider nich hentofรถgen, denn de Repositoriums-Eegner hett hรผm blockeert.
+settings.add_collaborator_blocked_them = Kann de Mitarbeider nich hentofรถgen, denn he hett de Repositoriums-Eegner blockeert.
+settings.delete_collaborator = Wegdoon
+settings.collaborator_deletion = Mitarbeider wegdoon
+settings.collaborator_deletion_desc = Wenn du eenen Mitarbeider wegdoost, hett he keenen Togriep mehr up deeses Repositorium. Wiedermaken?
+settings.remove_collaborator_success = De Mitarbeider is wegdaan worden.
+settings.org_not_allowed_to_be_collaborator = Vereenigungen kรถnen nich as Mitarbeider hentofรถรถgt worden.
+settings.change_team_access_not_allowed = Blots de Vereenigungs-Eegner kann de Klottjen-Togriep to de Repositorium รคnnern
+settings.team_not_in_organization = De Klottje is nich in de sรผlve Vereenigung as dat Repositorium
+settings.teams = Klottjen
+settings.add_team = Klottje hentofรถgen
+settings.add_team_duplicate = Klottje hett dat Repositorium al
+settings.add_team_success = De Klottje hett nu Togriep to de Repositorium.
+settings.change_team_permission_tip = De Klottjen-Rechte sรผnd up de Klottjen-Instellens-Sied sett un kรถnen nich pro Repositorium รคnnert worden
+settings.delete_team_tip = Deese Klottje hett Togriep to all Repositoriums un kann nich lรถsket worden
+settings.remove_team_success = De Togriep vun de Klottje to de Repositorium is wegdaan worden.
+settings.add_webhook = Internett-Haak hentofรถgen
+settings.add_webhook.invalid_channel_name = Internett-Haak-Kanaal-Naam dรผรผr nich leeg wesen un mutt mehr as blot de #-Bookstaav enthollen.
+settings.webhook_deletion = Internett-Haak wegdoon
+settings.webhook_deletion_success = De Internett-Haak is wegdaan worden.
+settings.webhook.test_delivery = Levern testen
+settings.webhook.test_delivery_desc = Deesen Internett-Haak mit eenem falsken Vรถrfall testen.
+settings.webhook.test_delivery_desc_disabled = Aktiveer deesen Internett-Haak, um hรผm mit eenem falsken Vรถrfall to testen.
+settings.webhook.request = Anfraag
+settings.webhook.response = Antwoord
+settings.webhook.payload = Inholl
+settings.webhook.body = Text
+settings.webhook.replay.description_disabled = Aktiveer deesen Internett-Haak, um hรผm weer uttofรถhren.
+settings.githook_edit_desc = Wenn de Haak nich aktiiv is, word Bispรถรถl-Inholl wiest. Wenn du de Inholl leeg lettst, word deeser Haak utknipst.
+settings.githook_name = Haak-Naam
+settings.githook_content = Haak-Inholl
+settings.update_githook = Haak vernejen
+settings.payload_url = Enn-URL
+settings.http_method = HTTP-Aard
+settings.content_type = Aard vum POST-Inholl
+settings.secret = Geheemst
+settings.slack_username = Brukernaam
+settings.slack_color = Klรถรถr
+settings.discord_username = Brukernaam
+settings.discord_icon_url = Bill-URL
+settings.event_desc = Utlรถsen fรถr:
+settings.event_push_only = Schuuv-Vรถrfall
+settings.event_send_everything = All Vรถrfallen
+settings.event_choose = Eegene Vรถrfallen โฆ
+settings.event_header_repository = Repositoriums-Vรถrfallen
+settings.event_create = Maken
+settings.event_create_desc = Twieg of Mark maakt.
+settings.event_delete = Lรถsken
+settings.event_delete_desc = Twieg of Mark lรถsket.
+settings.event_fork_desc = Repositorium gabelt.
+settings.event_wiki = Wiki
+settings.event_release = Publizeren
+settings.event_release_desc = Publizeren in eenem Repositorium maakt, verneeit of lรถsket.
+settings.event_push = Schuuv
+settings.event_push_desc = Git-Schuuv to eenem Repositorium.
+settings.event_repository = Repositorium
+settings.event_repository_desc = Repositorium maakt of lรถsket.
+settings.event_header_issue = Gefall-Vรถrfallen
+settings.event_issues_desc = Gefall opmaakt, dichtmaakt, weer opmaakt of bewarkt.
+settings.event_issue_assign = Towiesen
+settings.event_issue_label = Vermarkens
+settings.event_issue_milestone = Markstenen
+settings.event_issue_milestone_desc = Marksteen hentofรถรถgt, wegdaan of รคnnert.
+settings.event_issue_comment = Kommentaren
+settings.event_issue_comment_desc = Gefall-Kommentaar maakt, bewarkt of lรถsket.
+settings.event_header_pull_request = Haalvรถrslag-Vรถrfallens
+settings.event_pull_request = รnnern
+settings.event_pull_request_desc = Haalvรถrslag opmaakt, dichtmaakt, weer opmaakt of bewarkt.
+settings.event_pull_request_assign = Towiesen
+settings.event_pull_request_assign_desc = Haalvรถrslag towiesen of Towiesen wegdaan.
+settings.event_pull_request_label = Vermarkens
+settings.event_pull_request_label_desc = Haalvรถrslag-Vermarkens hentofรถรถgt of wegdaan.
+settings.event_pull_request_milestone = Markstenen
+settings.event_pull_request_milestone_desc = Marksteen hentofรถรถgt, wegdaan of รคnnert.
+settings.event_pull_request_comment = Kommentaren
+settings.event_pull_request_comment_desc = Haalvรถrslag-Kommentaar maakt, bewarkt of lรถsket.
+settings.event_pull_request_review = Nakiekens
+settings.event_pull_request_review_desc = Haalvรถrslag tostimmt of torรผggwiest of Nakiekens-Kommentaren hentofรถรถgt.
+settings.event_pull_request_sync = Verneeit
+settings.event_pull_request_sync_desc = Twieg automatisk mit de Enn-Twieg verneeit.
+settings.event_pull_request_review_request = Nakiekens-Anfragen
+settings.event_pull_request_review_request_desc = Haalvรถrslag-Nakieken anfraggt of Nakiekens-Anfraag wegdaan.
+settings.event_pull_request_approvals = Haalvรถrslag-Tostimmens
+settings.event_pull_request_merge = Haalvรถrslag-Tosamenfรถhren
+settings.event_pull_request_enforcement = Dwingen
+settings.event_package = Paket
+settings.event_package_desc = Paket in eenem Repositorium maakt of lรถsket.
+settings.branch_filter = Twieg-Filter
+settings.add_hook_success = De Internett-Haak is hentofรถรถgt worden.
+settings.update_webhook = Internett-Haak vernejen
+settings.update_hook_success = De Internett-Haak is verneeit worden.
+settings.delete_webhook = Internett-Haak wegdoon
+settings.recent_deliveries = Leste Leverns
+settings.hook_type = Haak-Aard
+settings.slack_token = Teken
+settings.graphql_url = GraphQL-URL
+settings.web_hook_name_gitea = Gitea
+settings.web_hook_name_discord = Discord
+settings.web_hook_name_telegram = Telegram
+settings.web_hook_name_matrix = Matrix
+settings.web_hook_name_msteams = Microsoft Teams
+settings.web_hook_name_feishu = Feishu / Lark Suite
+settings.web_hook_name_feishu_only = Feishu
+settings.web_hook_name_larksuite_only = Lark Suite
+settings.web_hook_name_wechatwork = WeCom (WeChat Work)
+settings.web_hook_name_packagist = Packagist
+settings.packagist_username = Packagist-Brukernaam
+settings.packagist_api_token = API-Teken
+settings.packagist_package_url = Packagist-Paket-URL
+settings.web_hook_name_sourcehut_builds = Up SourceHut bauen
+settings.sourcehut_builds.manifest_path = Padd tum Bau-Manifest
+settings.sourcehut_builds.visibility = Upgaav-Sichtbaarkeid
+settings.add_deploy_key = Utbrengens-Slรถtel hentofรถgen
+settings.is_writable = Schriev-Togriep anknipsen
+settings.is_writable_info = Deesem Utbrengens-Slรถtel verlรถven, tum Repositorium to schuven .
+settings.no_deploy_keys = Dat gifft noch keene Utbrengens-Slรถtels.
+settings.title = Titel
+settings.key_name_used = Dat gifft al eenen Utbrengens-Slรถtel mit de sรผlve Naam.
+settings.add_key_success = De Utbrengens-Slรถtel ยป%sยซ is hentofรถรถgt worden.
+settings.deploy_key_deletion = Utbrengens-Slรถtel wegdoon
+settings.deploy_key_deletion_success = De Utbrengens-Slรถtel is wegdaan worden.
+settings.branches = Twiegen
+settings.protected_branch = Twieg Schรผtten
+settings.protected_branch.save_rule = รrder sekern
+settings.protected_branch.delete_rule = รrder wegdoon
+settings.branch_protection = Schรผttens-รrders fรถr Twieg ยป%s ยซ
+settings.protect_new_rule = Eene neje Twieg-Schรผttens-รrder hentofรถgen
+settings.protect_disable_push = Schuven utknipsen
+settings.protect_enable_push = Schuven anknipsen
+settings.protect_whitelist_committers = Verlรถรถvt Schuvers utkรถren
+settings.protect_whitelist_committers_desc = Blots verlรถรถvt Brukers of Klottjen dรผren to deesem Twieg schuven (aver nich dwangsschuven).
+settings.protect_whitelist_deploy_keys = Verlรถรถvt Utbrengens-Slรถtels mit Schriev-Togriep as Schuvers.
+settings.protect_whitelist_users = Verlรถรถvt Brukers as Schuvers
+settings.protect_merge_whitelist_teams = Verlรถรถvt Klottjen as Tosamenfรถhrers
+settings.protect_check_status_contexts = Tostands-รverprรผfens anknipsen
+settings.protect_check_status_contexts_list = Tostands-รverprรผfens, wat in deesem Repositorium in de leste Week funnen worden sรผnd
+settings.protect_invalid_status_check_pattern = Ungรผltiges Tostands-รverprรผfens-Muster: ยป%sยซ.
+settings.protect_required_approvals = Nรถdige Tostimmens
+settings.protect_approvals_whitelist_enabled = Blots verlรถรถvt Brukers of Klottjen dรผren tostimmen
+settings.protect_approvals_whitelist_teams = Verlรถรถvt Klottjen tum Nakieken
+settings.dismiss_stale_approvals = Verslaan Tostimmens ofseggen
+settings.dismiss_stale_approvals_desc = Wenn neje Kommitterens up de Twieg schuven worden, wat de Inholl vum Haalvรถrslag รคnnern, worden olle Tostimmens ofseggt.
+settings.ignore_stale_approvals = Verslaan Tostimmens minnachten
+settings.ignore_stale_approvals_desc = Tostimmens, wat up oller Kommitterens maakt worden sรผnd (verslaan Nakiekens), nich daarto tellen, wo vรถle Tostimmens de HV hett. Is egaal wenn verslaan Nakiekens eh ofseggt worden.
+settings.require_signed_commits = Kommitterens mutten unnerschrieven wesen
+settings.require_signed_commits_desc = Schuvens to deesem Twieg verseggen, wat nich unnerschrieven sรผnd of nich utwiest worden kรถnen.
+settings.protect_branch_name_pattern = Naam-Muster fรถr schรผtt Twiegen
+settings.protect_patterns = Musters
+settings.protect_protected_file_patterns = Schรผtt Dateinaam-Musters (trennt mit Semikolons ยป;ยซ)
+settings.update_protect_branch_success = Twieg-Schรผtten fรถr รrder ยป%sยซ is verneeit worden.
+settings.remove_protected_branch_failed = Twieg-Schรผttens-รrder ยป%sยซ kunn nich wegdaan worden.
+settings.block_rejected_reviews = Tosamenfรถhren bi Nakiekens mit erbeden รnnerns blockeren
+settings.block_rejected_reviews_desc = Dat Tosamenfรถhren is nich verlรถรถvt, wenn offizielle Nakiekers um รnnerns beden hebben, ok wenn dat genoog Tostimmens gifft.
+settings.block_on_official_review_requests = Tosamenfรถhren bi offiziellen Nakiekens-Anfragen blockeren
+settings.block_on_official_review_requests_desc = Dat Tosamenfรถhren is nich verlรถรถvt, wenn eene offizielle Nakieker-Anfraag utstaht, ok wenn dat genoog Tostimmens gifft.
+settings.block_outdated_branch = Tosamenfรถhren fรถr verollte Haalvรถrslagen blockeren
+settings.enforce_on_admins_desc = Repositoriums-Chefs dรผren deese รrder nich minnachten.
+settings.merge_style_desc = Tosamenfรถhrens-Aarden
+settings.default_merge_style_desc = Normaale Tosamenfรถhrens-Aard
+settings.edit_protected_branch = Bewarken
+settings.add_collaborator = Mitarbeider hentofรถgen
+settings.webhook.replay.description = Deesen Internett-Haak weer utfรถhren.
+settings.event_issues = รnnern
+settings.webhook.delivery.success = Een Vรถrfall is to de Leverslang hentofรถรถgt worden. Dat kann een paar Sekรผnnen dรผren, ehr dat in de Lever-Histoorje vรถrkummt.
+settings.discord_icon_url.exceeds_max_length = Bill-URL dรผรผr nich langer as 2048 Bookstavens wesen
+settings.update_settings_no_unit = Dat Repositorium sall tominnst elk of anner Aard vun Gebruuk verlรถven.
+settings.delete_notices_fork_1 = - Gabels vun deesem Repositorium worden nach de Lรถsken to normaalen Repositoriums.
+settings.confirm_delete = Repositorium lรถsken
+settings.add_collaborator_inactive_user = Kann eenen inaktiiv Bruker nich as Mitarbeider hentofรถgen.
+settings.add_webhook.invalid_path = Padd dรผรผr keen Deel enthollen, wat ยป.ยซ of ยป..ยซ of leeg is, un kann nich mit eenem Schรผรผnstreek begรผnnen of ennen.
+settings.hooks_desc = Internett-Hakens schicken automatisk HTTP-POST-Anfragen to eenem Server, wenn wisse Forgejo-Vรถrfallen passeren. Lees mehr in de Internett-Hakens-Dokumenteren .
+settings.webhook_deletion_desc = Wenn du eenen Internett-Haak wegdoost, worden siene Instellens un Lever-Histoorje lรถsket. Wiedermaken?
+settings.githooks_desc = Git-Hakens worden vun Git sรผlvst utfรถhrt. Du kannst Haken-Dateien unnern bewarken, um eegene Aktioonen intorichten.
+settings.webhook.headers = Koppriegen
+settings.event_fork = Gabel
+settings.event_wiki_desc = Wiki-Sied maakt, umbenรถรถmt, bewarkt of lรถsket.
+settings.slack_icon_url = Bill-URL
+settings.slack_channel = Kanaal
+settings.web_hook_name_forgejo = Forgejo
+settings.sourcehut_builds.secrets = Geheemsten
+settings.sourcehut_builds.secrets_helper = Giff de Upgaav Togang to de Bau-Geheemsten (bruukt de Verlรถรถvnis SECRETS:RO)
+settings.deploy_keys = Utbrengens-Slรถtels
+settings.protect_enable_merge = Tosamenfรถhren anknipsen
+settings.protect_no_valid_status_check_patterns = Keene gรผltigen Tostands-รverprรผfens-Musters.
+settings.protect_approvals_whitelist_users = Verlรถรถvt Nakiekers
+settings.protect_unprotected_file_patterns = Nich schรผtt Dateinaam-Musters (trennt mit Semikolons ยป;ยซ)
+settings.remove_protected_branch_success = Twieg-Schรผtten fรถr รrder ยป%sยซ is wegdaan worden.
+settings.default_branch_desc = Kรถรถr eenen Hรถรถvd-Repositoriums-Twieg fรถr Haalvรถrslagen un Quelltext-Kommitterens ut:
+settings.choose_branch = Kรถรถr eenen Twieg ut โฆ
+settings.event_issue_assign_desc = Gefall towiesen of Towiesen wegdaan.
+settings.add_web_hook_desc = %s in dien Repositorium inbinnen.
+settings.web_hook_name_gogs = Gogs
+settings.key_been_used = Een Utbrengens-Slรถtel mit de sรผlve Inholl word al bruukt.
+settings.protect_merge_whitelist_committers = Tosamenfรถhrens-Verlรถรถv-List anknipsen
+settings.protect_merge_whitelist_users = Verlรถรถvt Brukers as Tosamenfรถhrers
+settings.event_issue_label_desc = Gefall-Vermarkens hentofรถรถgt of wegdaan.
+settings.active_helper = Informatioonen รถver utlรถรถst Vรถrfallen worden to deeser Internett-Haak-URL schickt.
+settings.web_hook_name_slack = Slack
+settings.protect_enable_push_desc = Elkeen, well Schriev-Togriep hett, dรผรผr to deesem Twieg schuven (aver nich dwangsschuven).
+settings.protect_status_check_patterns = Tostands-รverprรผfens-Musters
+settings.protect_status_check_patterns_desc = Giff Musters in, wat angeven, welke Tostands-รverprรผfens klaar wesen mutten, ehr Twiegen in eenen Twieg, wat up deese รrder passt, tosamenfรถhrt worden kรถnen. Elkeen Rieg sett een Muster. Musters dรผren nich leeg wesen.
+settings.protect_status_check_matched = Passt
+settings.protect_approvals_whitelist_enabled_desc = Blots Nakiekens vun verlรถรถvt Brukers of Klottjen tellen to de nรถdige Tahl vun Tostimmens. Sรผnner eene sรผlke List tellen Nakiekens vun elkeen, well Schriev-Togriep hett, to de nรถdige Tahl vun Tostimmens.
+settings.protect_branch_name_pattern_desc = Naam-Musters fรถr schรผtt Twiegen. Kiek in de Dokumenteren fรถr de Muster-Syntax. Bispรถlen: main, release/**
+settings.protected_branch_deletion = Twieg-Schรผtten wegdoon
+settings.protected_branch_deletion_desc = Wenn du de Twieg-Schรผtten utknipst, dรผren all Brukers mit Schriev-Rechten to the Twieg schuven. Wiedermaken?
+settings.active = Aktiiv
+settings.deploy_key_desc = Utbrengens-Slรถtels hebben Blots-Lesen-Togriep up dat Repositorium.
+settings.deploy_key_deletion_desc = Wenn du eenen Utbrengens-Slรถtel wegdoost, hett he keenen Togriep mehr up deeses Repositorium. Wiedermaken?
+settings.protect_disable_push_desc = Man dรผรผr nich to deesem Twieg schuven.
+settings.protect_enable_merge_desc = Elkeen, well Schriev-Togriep hett, dรผรผr Haalvรถrslagens in deesen Twieg tosamenfรถhren.
+settings.protect_whitelist_teams = Verlรถรถvt Klottjen as Schuvers
+settings.protect_merge_whitelist_committers_desc = Blots verlรถรถvt Brukers of Klottjen dรผren Haalvรถrslagen in deesen Twieg tosamenfรถhren.
+settings.protect_check_status_contexts_desc = Verlang, dat vรถr de Tosamenfรถhren Tostands-รverprรผfens klaar wesen mutten. Wenn dat anknipst is, mutten Kommitterens eerst to een anner Twieg schuven worden, un kรถnen eerst dann tosamenfรถhrt of strack to eenem Twieg schuuvt worden, wat up deese รrder passt, nadeem de Tostands-รverprรผfens klaar worden sรผnd. Wenn keen Umgeven passt, mutt de leste Kommitteren klaar wesen, wat ok immer de Umgeven is.
+settings.protect_required_approvals_desc = Verlรถรถv Haalvรถrslagen blots dann tosamentofรถhren, wenn genoog Nakiekers tostimmt hebben.
+settings.block_outdated_branch_desc = Dat Tosamenfรถhren is nich verlรถรถvt, wenn de Kopp-Twieg achter de Grund-Twieg torรผgg is.
+settings.authorization_header = Anmellens-Kopprieg
+settings.authorization_header_desc = Wenn sett, word dat as Anmellens-Kopprieg fรถr Anfragen anfรถรถgt. Bispรถlen: %s.
+settings.slack_domain = Domรครคn
+settings.web_hook_name_dingtalk = DingTalk
+settings.deploy_key_content = Inholl
+settings.no_protected_branch = Dat gifft keene schรผtt Twiegen.
+settings.enforce_on_admins = Deese รrder fรถr Repositoriums-Chefs dwingen
+settings.protected_branch_duplicate_rule_name = Fรถr deese Sammlung vun Twiegen gifft dat all een รrder
+settings.tags = Markens
+settings.tags.protection = Mark-Schรผtten
+settings.tags.protection.allowed = Verlรถรถvt
+settings.tags.protection.allowed.teams = Verlรถรถvt Klottjen
+settings.tags.protection.allowed.noone = Nรผms
+settings.tags.protection.none = Dat gifft keene schรผtt Markens.
+settings.thread_id = Thema-ID
+settings.matrix.homeserver_url = Heimaadserver-URL
+settings.matrix.room_id = Ruum-ID
+settings.archive.header = Deeses Repo archiveren
+settings.archive.error_ismirror = Du kannst een spegelt Repo nich archiveren.
+settings.archive.tagsettings_unavailable = Mark-Instellens sรผnd in archiveert Repos nich verfรถรถgbaar.
+settings.unarchive.button = Repo ut Archiv torรผgghalen
+settings.unarchive.success = Dat Repo is nu nich mehr archiveert.
+settings.unarchive.error = Een Fehler is biโm Torรผgghalen vum Repo ut de Archiv uptreden. Kiek in de Utgaav fรถr mehr Informatioonen.
+settings.lfs = LFS
+settings.lfs_filelist = LFS-Dateien, wat in deesem Repositorium verwahrt sรผnd
+settings.lfs_lfs_file_no_commits = Keene Kommitterens fรถr deese LFS-Datei funnen
+settings.tags.protection.pattern = Mark-Muster
+settings.tags.protection.allowed.users = Verlรถรถvt Brukers
+settings.chat_id = Snack-ID
+settings.archive.button = Repo archiveren
+settings.unarchive.header = Deeses Repo as nich mehr archiveert setten
+settings.update_avatar_success = Dat Repositoriums-Kontobill is verneeit worden.
+settings.lfs_findcommits = Kommitterens finnen
+settings.protected_branch_required_approvals_min = Nรถdige Tostimmens kรถnen nich negativ wesen.
+settings.archive.mirrors_unavailable = Spegels sรผnd in archiveert Repos nich verfรถรถgbaar.
+settings.tags.protection.create = รrder hentofรถgen
+settings.bot_token = Bot-Teken
+settings.matrix.message_type = Narichten-Aard
+settings.archive.text = Wenn dat Repo archiveert word, kann man daar blots noch lesen. Dat word vum Kontor verburgen. Nรผms (ok nich du sรผlvst!) kann noch neje Kommitterens maken of Gefallens of Haalvรถrslagen opmaken.
+settings.archive.success = Dat Repo is archiveert worden.
+settings.archive.error = Een Fehler is biโm Archiveren vum Repo uptreden. Kiek in de Utgaav fรถr mehr Informatioonen.
+settings.archive.branchsettings_unavailable = Twieg-Instellens sรผnd in archiveert Repos nich verfรถรถgbaar.
+settings.unarchive.text = Wenn dat Repo nich mehr archiveert is, kann dat weer Kommitterens un Schuvens kriegen un ok neje Gefallens un Haalvรถrslagens.
+settings.lfs_no_lfs_files = In deesem Repositorium sรผnd keene LFS-Dateien verwahrt
+settings.lfs_noattribute = Deeser Padd is im Hรถรถvd-Twieg nich as toslutbaar markeert
+settings.lfs_findpointerfiles = Wieser-Dateien finnen
+settings.lfs_invalid_locking_path = Ungรผltiger Padd: %s
+settings.lfs_lock = Slรถtt
+settings.lfs_lock_path = Dateipadd tum tosluten โฆ
+settings.lfs_locks_no_locks = Keene Slรถtten
+settings.lfs_force_unlock = Upsluten dwingen
+settings.lfs_pointers.sha = Blob-Prรผfsumm
+settings.lfs_pointers.oid = OID
+settings.lfs_pointers.inRepo = Im Repo
+settings.lfs_pointers.accessible = Bruker kann togriepen
+settings.lfs_pointers.associateAccessible = %d togangelk OIDs benรถรถmen
+settings.rename_branch_failed_exist = Kann Twieg nich umbenรถรถmen, denn de Enn-Twieg %s gifft dat al.
+settings.rename_branch_success = Twieg %s is in %s umbenรถรถmt worden.
+settings.rename_branch = Twieg umbenรถรถmen
+diff.browse_source = In Quell stรถvern
+diff.parent = Ollern
+diff.commit = Kommitteren
+diff.git-notes = Anmarkens
+diff.data_not_available = Unnerscheed-Inholl is nich verfรถรถgbaar
+diff.options_button = Unnerscheed-Instellens
+diff.show_diff_stats = Statistiken wiesen
+diff.download_patch = Plack-Datei runnerladen
+diff.show_split_view = Deelte Sicht
+diff.show_unified_view = Vereenigte Sicht
+diff.whitespace_button = Leegtekens
+diff.whitespace_ignore_all_whitespace = Leegtekens biโm Verglieken vun Riegen minnachten
+diff.whitespace_ignore_amount_changes = รnnerns in de Meng an Leegtekens minnachten
+diff.whitespace_ignore_at_eol = รnnerns in de Leegtekens am Datei-Enn minnachten
+diff.stats_desc_file = %d รnnerns: %d neje Riegen un %d lรถsket Riegen
+diff.bin = BIN
+diff.bin_not_shown = Binรครคrdatei word nich wiesen.
+diff.view_file = Datei wiesen
+diff.file_before = Vรถrher
+diff.file_after = Daarna
+diff.file_byte_size = Grรถtt
+diff.file_suppressed = Datei-Unnerscheed unnerdrรผckt, denn dat is to grot
+diff.too_many_files = Eenige Dateien worden nich wiesen, denn in deesem Unnerscheed sรผnd to vรถle Dateien รคnnert worden
+diff.show_more = Mehr wiesen
+diff.load = Unnerscheed laden
+diff.generated = maakt
+diff.vendored = verkoperig
+diff.comment.placeholder = Eenen Kommentaar schrieven
+diff.comment.start_review = Nakieken begรผnnen
+diff.review = Nakieken klaarmaken
+diff.review.header = Nakieken avgeven
+diff.review.approve = Tostimmen
+diff.committed_by = kommitteert vun
+diff.protected = Schรผtt
+diff.image.side_by_side = Tegenanner
+diff.image.swipe = Wisken
+diff.show_file_tree = Dateiboom wiesen
+diff.hide_file_tree = Dateiboom verbargen
+release.releases = Publizerens
+release.detail = รver de Publizeren
+release.tags = Markens
+release.new_release = Nejes Publizeren
+release.draft = Sketts
+release.prerelease = Vรถr-Publizeren
+release.stable = Stevig
+release.edit = Bewarken
+release.ahead.commits = %d Kommitterens
+release.ahead.target = to %s siet deesem Publizeren
+tag.ahead.target = to %s siet deeser Mark
+release.source_code = Quelltext
+release.edit_subheader = Publizerens organiseren Projekt-Versioonen.
+release.tag_name = Mark-Naam
+release.target = Enn
+release.tag_helper_existing = Bestahn Mark.
+release.title_empty = Titel kann nich leeg wesen.
+release.message = Beschriev deeses Publizeren
+release.prerelease_desc = As Vรถr-Publizeren markeren
+release.prerelease_helper = Markeer, dat deeses Publizeren nich fรถr stevig Gebruuk dacht is.
+release.cancel = Ofbreken
+release.publish = Publizeren publik maken
+release.save_draft = Sketts sekern
+release.deletion_success = Dat Publizeren is lรถsket worden.
+release.tag_name_already_exist = Een Publizeren mit deesem Mark-Naam gifft dat al.
+release.tag_name_invalid = De Mark-Naam is nich gรผltig.
+release.tag_name_protected = De Mark-Naam is schรผtt.
+release.downloads = Runnerladens
+release.download_count_one = %s maal runnerladen
+release.download_count_few = %s maal runnerladen
+release.hide_archive_links = Automatisk maakt Archiven verbargen
+release.releases_for = Publizerens fรถr %s
+release.tags_for = Markens fรถr %s
+release.system_generated = Deeser Anhang is automatisk maakt worden.
+release.type_attachment = Anhang
+release.type_external_asset = Frรถmdes Objekt
+release.asset_external_url = Frรถmde URL
+release.add_external_asset = Frรถmdes Objekt hentofรถgen
+branch.name = Twieg-Naam
+branch.already_exists = Een Twieg mit de Naam ยป%sยซ gifft dat al.
+branch.delete_head = Lรถsken
+branch.delete = Twieg ยป%sยซ lรถsken
+branch.delete_html = Twieg lรถsken
+branch.create_branch = Maak Twieg %s
+branch.create_from = vun ยป%sยซ
+branch.create_success = Twieg ยป%sยซ is maakt worden.
+branch.branch_already_exists = Twieg ยป%sยซ gifft dat in deesem Repositorium al.
+branch.deleted_by = Vun %s lรถsket
+branch.restore_failed = Kunn Twieg ยป%sยซ nich torรผgghalen.
+branch.protected_deletion_failed = Twieg ยป%sยซ is schรผtt un kann nich lรถsket worden.
+branch.restore = Twieg ยป%sยซ torรผgghalen
+branch.download = Twieg ยป%sยซ runnerladen
+branch.rename = Twieg ยป%sยซ umbenรถรถmen
+branch.included = Enthollen
+branch.create_new_branch = Twieg vum Twieg maken:
+branch.rename_branch_to = ยป%sยซ umbenรถรถmen to:
+branch.create_branch_operation = Twieg maken
+branch.new_branch = Nejen Twieg maken
+topic.manage_topics = Themen verwalten
+topic.done = Daan
+topic.count_prompt = Du kannst nich mehr as 25 Themen utkรถren
+settings.lfs_lock_already_exists = Slรถtt gifft dat al: %s
+diff.whitespace_show_everything = All รnnerns wiesen
+diff.review.placeholder = Nakiekens-Kommentaar
+settings.lfs_delete = LFS-Datei mit OID %s lรถsken
+settings.lfs_delete_warning = Wenn eene LFS-Datei lรถsket word, kann biโm Utchecken de Fehler ยปObjekt gifft dat nichยซ uptreden. Willst du dat wรผrrelk?
+settings.lfs_locks = Slรถtten
+diff.comment.markdown_info = Markdown kann bruukt worden, um dat Textformaat antopassen.
+settings.lfs_invalid_lock_directory = Kann Verteeknis nich tosluten: %s
+settings.lfs_pointers.exists = Bestaht im Lager
+settings.rename_branch_failed_not_exist = Kann Twieg %s nich umbenรถรถmen, denn de Twieg gifft dat nich.
+diff.comment.reply = Antern
+diff.image.overlay = รverleggen
+settings.lfs_lock_file_no_exist = Tosluten Datei gifft dat im Hรถรถvd-Twieg nich
+diff.file_suppressed_line_too_long = Datei-Unnerscheed unnerdrรผckt, denn een of mehr Riegen sรผnd to lang
+settings.lfs_pointers.found = Hett %d Blob-Wieser(s) funnen โ %d benรถรถmt, %d unbenรถรถmt (im Lager fehlen %d)
+settings.rename_branch_failed_protected = Kann Twieg %s nich umbenรถรถmen, denn dat is een schรผtt Twieg.
+diff.download_diff = Unnerscheed-Datei runnerladen
+diff.stats_desc = %d รคnnert Dateien mit %d nejen Riegen un %d lรถsket Riegen
+diff.file_image_height = Hรถcht
+tag.create_tag_from = Neje Mark vun ยป%sยซ maken
+tag.create_success = Mark ยป%sยซ is maakt worden.
+error.csv.too_large = Kann deese Datei nich teken, denn se is to grot.
+diff.file_image_width = Breddt
+diff.comment.add_line_comment = Riegen-Kommentaar hentofรถgen
+diff.comment.add_review_comment = Kommentaar hentofรถgen
+release.tag_helper_new = Neje Mark. Deese Mark word vun de Enn maakt.
+release.edit_release = Publizeren vernejen
+release.deletion_desc = Wenn du een Publizeren lรถskest, word dat blots vun Forgejo wegdaan. Dat รคnnert nix an de Git-Mark, de Inholl vun dienem Repositorium of siener Histoorje. Wiedermaken?
+release.add_tag = Mark maken
+release.asset_name = Objekt-Naam
+branch.delete_branch_has_new_commits = Twieg ยป%sยซ kann nich lรถsket worden, denn na de Tosamenfรถhren sรผnd neje Kommitterens hentofรถรถgt worden.
+branch.restore_success = Twieg ยป%sยซ is torรผgghaalt worden.
+tag.create_tag = Mark %s maken
+diff.comment.add_single_comment = Enkelt Kommentaar hentofรถgen
+diff.review.comment = Kommentaar
+diff.review.reject = Um รnnerns bidden
+diff.has_escaped = Deese Rieg hett verburgen Unicode-Bookstavens
+releases.desc = Verfolg Projekt-Versioonen un Runnerladens.
+diff.review.self_reject = Haalvรถrslag-Autoren kรถnen nich up hรถr eegen Haalvรถrslag um รnnerns beden
+diff.review.self_approve = Haalvรถrslag-Autoren kรถnen nich hรถr eegen Haalvรถrslag tostimmen
+release.deletion_tag_desc = Lรถsket deese Mark ut de Repositorium. Dat รคnnert nix an de Inholl vun de Repositorium of siener Histoorje. Wiedermaken?
+release.invalid_external_url = Ungรผltige frรถmde URL: ยป%sยซ
+tag.confirm_create_tag = Mark maken
+release.compare = Verglieken
+branch.delete_desc = Eenen Twieg to lรถsken is fรถr all Tieden. Ok wenn de lรถsket Twieg villicht noch kรถrte Tied rumliggt, ehr he wรผrrelk wegdaan word, KANN DAT MEESTTIEDENS NICH torรผggnohmen worden. Wiedermaken?
+branch.deletion_success = Twieg ยป%sยซ is lรถsket worden.
+branch.included_desc = Deeser Twieg is Deel vum Hรถรถvd-Twieg
+release.new_subheader = Publizerens organiseren Projekt-Versioonen.
+release.tag_helper = Kรถรถr eene bestahn Mark ut of maak eene neje Mark.
+release.deletion_tag_success = De Mark is lรถsket worden.
+release.tag_already_exist = De Mark-Naam gifft dat al.
+branch.warning_rename_default_branch = Du benรถรถmst de Hรถรถvd-Twieg um.
+branch.renamed = Twieg %s is in %s umbenรถรถmt worden.
+topic.format_prompt = Themen mutten mit eenem Bookstaav of Tahl begรผnnen, dรผren Binnestrekens (ยป-ยซ) un Punkten (ยป.ยซ) enthollen un kรถnen bit to 35 Bookstavens lang wesen. All Bookstavens mutten Kleenbookstavens wesen.
+error.csv.invalid_field_count = Kann deese Datei nich teken, denn se hett de falske Tahl vun Felden in Rieg %d.
+release.title = Publizerens-Titel
+release.delete_release = Publizeren lรถsken
+release.delete_tag = Mark lรถsken
+release.deletion = Publizeren lรถsken
+release.hide_archive_links_helper = Verbargt automatisk maakt Quelltext-Archiven fรถr deeses Publizeren. Toโn Bispรถรถl wenn du diene eegenen uplaadst.
+branch.deletion_failed = Kunn Twieg ยป%sยซ nich lรถsken.
+branch.branch_name_conflict = Twieg-Naam ยป%sยซ is unverdragelk mit de al bestahn Twieg ยป%sยซ.
+branch.new_branch_from = Nejen Twieg vun ยป%sยซ maken
+tag.create_tag_operation = Mark maken
+release.add_tag_msg = Bruuk de Titel un Inholl vun de Publizeren as Mark-Naricht.
+find_file.go_to_file = Datei finnen
+find_file.no_matching = Keene passend Datei funnen
+branch.tag_collision = Twieg ยป%sยซ kann nich maakt worden, denn in de Repositorium gifft dat al eene Mark mit de sรผlve Naam.
+branch.default_deletion_failed = Twieg ยป%sยซ is de Hรถรถvd-Twieg un kann nich lรถsket worden.
+branch.confirm_create_branch = Twieg maken
+error.csv.unexpected = Kann deese Datei nich teken, denn se enthollt eenen unverwachten Bookstaav in Rieg %d un Striep %d.
+pulls.edit.already_changed = Kann รnnerns an de Haalvรถrslag nich sekern. Dat schient, dat de Inholl al vun een anner Bruker รคnnert worden is. Bidde laad de Sied neei un versรถรถk, dat dann noch eenmaal to bewarken, daarmit du hรถr รnnerns nich รถverschriffst
+mirror_lfs_endpoint_desc = Spegel word versรถken, de Klonen-URL to bruken, um de LFS-Server uttofinnen . Du kannst ok eenen eegenen Ennpunkt angeven, wenn de Repositoriums-LFS-Dateien annerwaar lagert worden.
+migrate_options_lfs_endpoint.description = Umtreck word versรถken, de frรถmde Git-Tegenstee to bruken, um de LFS-Server uttofinnen . Du kannst ok eenen eegenen Ennpunkt angeven, wenn de Repositoriums-LFS-Dateien annerwaar lagert worden.
+clear_ref = `Stedenwies Beteekner leegmaken`
+org_labels_desc = Vereenigungs-Vermarkens, wat mit all Repositoriums unner deeser Vereenigung bruukt worden kรถnen
+invisible_runes_header = `Deese Datei enthollt unsichtbaare Unicode-Bookstavens`
+ambiguous_runes_line = `Deese Rieg hett verwesselbaare Unicode-Bookstavens`
+ambiguous_character = `%[1]c [U+%04[1]X] kann mit %[2]c [U+%04[2]X] verwesselt worden`
+commits.search.tooltip = Du kannst Slรถtelwoorden mit ยปauthor:ยซ, ยปcommitter:ยซ, ยปafter:ยซ of ยปbefore:ยซ begรผnnen, toโn Bispรถรถl ยปrevert author:Alice before:2019-01-13ยซ.
+projects.new_subheader = Verwalt, verfolg un verneei diene Arbeid an eener Stee, daarmit Projekten dรถrsichtig un up Tied blieven.
+issues.label_archive_tooltip = Archiveert Vermarkens worden in de Vรถrslagens, wenn du na Vermarkens sรถchst, normaal nich wiest.
+issues.label_exclusive_desc = Benรถรถm de Vermark Rebeet/Ding
, daarmit dat nich mit anner Vermarkens ut de sรผlven Rebeet/
tosamen bruukt worden kann.
+issues.label_exclusive_warning = Elkeen anner Vermark in de sรผlve Rebeet word wegdaan, wenn de Vermarkens vun eenem Gefall of Haalvรถrslag bewarkt worden.
+blame.ignore_revs.failed = Kunn de Versioonen in de .git-blame-ignore-revs nich minnachten.
+invisible_runes_line = `Deese Rieg hett verburgen Unicode-Bookstavens`
+mirror_address_url_invalid = De angeven URL is ungรผltig. Du muttst all Delen vun de URL recht utkielen.
+mirror_address_protocol_invalid = De angeven URL is ungรผltig. Blots Steden vun de Aarden ยปhttp(s)://ยซ of ยปgit://ยซ kรถnen tum Spegeln bruukt worden.
+mirror_use_ssh.helper = Forgejo spegelt dat Repositorium mit Git รถver SSH un maakt fรถr di een Slรถtelpaar, wenn du deese Instellen utkรถรถrst. Du muttst wiss maken, dat de maakt publike Slรถtel dat Recht kriggt, to de Enn-Repositorium to schuven. Wenn du dat utkรถรถrst, kannst du keen Anmellen mit Passwoord bruken.
+migrate.permission_denied_blocked = Du kannst nich vun verboden Servers importeren; bidde fraag de Chef, of he de Instellens ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS รถverprรผfen maag.
+blame.ignore_revs = Minnacht Versioonen in .git-blame-ignore-revs . Klick hier, um daar รถverwegtogahn un de normaale Schรผld-Ansicht to wiesen.
+migrate.github_token_desc = Du kannst hier een of mehr Tekens angeven, wat mit Kommas trennt sรผnd, um dat Umtrecken fixer to maken, um de GitHub-API-Togrieps-Begrenz. WAHRSCHAU: Wenn du dat missbruukst, kannst du de Richtlienjen vun de Deenstbedriev verletzen un dien Konto kann sperrt worden.
+issues.edit.already_changed = Kann รnnerns an de Gefall nich sekern. Dat schient, dat de Inholl al vun een anner Bruker รคnnert worden is. Bidde laad de Sied neei un versรถรถk, dat dann noch eenmaal to bewarken, daarmit du hรถr รnnerns nich รถverschriffst
+broken_message = De Git-Daten unner deesem Repositorium kรถnen nich lesen worden. Kuntakteer de Chef vun deeser Instanz of lรถske dat Repositorium.
+ambiguous_runes_header = `Deese Datei enthollt verwesselbaare Unicode-Bookstavens`
+ambiguous_runes_description = `Deese Datei enthollt Unicode-Bookstavens, wat man licht mit anner Bookstavens verwesseln kann. Wenn du glรถรถvst, dat dat so wesen sall, kannst du deese Wahrschau seker minnachten. Bruuk de Utkielen-Knoop, um se to wiesen.`
+invisible_runes_description = `Deese Datei enthollt unsichtbaare Unicode-Bookstavens, wat Minsken nich sehn kรถnen, aver vun eenem Reekner anners verarbeidt worden kรถnen. Wenn du glรถรถvst, dat dat so wesen sall, kannst du deese Wahrschau seker minnachten. Bruuk de Utkielen-Knoop, um se to wiesen.`
+comments.edit.already_changed = Kann รnnerns an de Kommentaar nich sekern. Dat schient, dat de Inholl al vun een anner Bruker รคnnert worden is. Bidde laad de Sied neei un versรถรถk, dat dann noch eenmaal to bewarken, daarmit du hรถr รnnerns nich รถverschriffst
+pulls.clear_merge_message_hint = Wenn du de Tosamenfรถhrens-Naricht leeg maakst, lรถsket dat blots de Naricht-Inholl un behollt sรผlk automatisk maakte Git-Nadragens as ยปCo-Autored-By โฆยซ.
+settings.add_webhook_desc = Forgejo schickt POST
-Anfragen mit eener angeven Inholls-Aard to de Enn-URL. Lees mehr in de Internett-Hakens-Infรถhren .
+issues.review.pending.tooltip = Deeser Kommentaar is jรผรผst fรถr anner Brukers nich sichtbaar. Um diene utstahn Kommentaren avtogeven, kรถรถr boven in de Sied ยป%sยซ โ ยป%s/%s/%sยซ ut.
+settings.sourcehut_builds.access_token_helper = Togang-Teken, wat de Verlรถรถvnis JOBS:RW hett. Maak een builds.sr.ht-Teken of een builds.sr.ht-Teken mit Togriep to Geheemsten up meta.sr.ht.
+settings.protect_unprotected_file_patterns_desc = Nich schรผtt Dateien, wat stracks รคnnert worden dรผren, wenn de Bruker Schriev-Togriep hett, an de Schuuv-Schรผttens-รrders vรถrbi. Mennig Musters kรถnen mit Semikolon (ยป;ยซ) trennt worden. Kiek de Dokumenteren fรถr ">%[2]s fรถr de Syntax an. Bispรถlen: .drone.yml
, /docs/**/*.txt
.
+settings.protected_branch_required_rule_name = รrdernaam is nรถdig
+settings.protect_protected_file_patterns_desc = Schรผtt Dateien, wat nich stracks รคnnert worden dรผren, sรผlvst wenn de Bruker dat Recht hett, Dateien in deesem Twieg hentotofรถgen, to bewarken of to lรถsken. Mennig Musters kรถnen mit Semikolon (ยป;ยซ) trennt worden. Kiek de Dokumenteren fรถr ">%[2]s fรถr de Syntax an. Bispรถlen: .drone.yml
, /docs/**/*.txt
.
+settings.branch_filter_desc = Twieg-Verlรถรถvnis-List fรถr Vรถrfallen รถver dat Schuven un dat Maken un Lรถsken vun Twiegen, angeven as een Glob-Muster. Wenn leeg of *
worden Vรถrfallen fรถr all Twiegen mellt. Kiek de Dokumenteren fรถr %[2]s fรถr de Syntax an. Bispรถlen: master
, {master,release*}
.
+settings.matrix.room_id_helper = De Ruum-ID kann vun de Element-Internett-Sied unner Ruum-Instellens โ Verwiedert โ Binnere Ruum-ID haalt worden. Bispรถรถl: %s.
+settings.tags.protection.pattern.description = Du kannst eenen enkelt Naam bruken of een Glob-Muster of Regel-Utdruck, um up mennig Markens to passen. Lees mehr in de Infรถhren รถver schรผtt Markens .
+error.broken_git_hook = Git-Hakens in deesem Repositorium schienen kaputt to wesen. Bidde folg de Dokumenteren , um se to repareren, dann schuuv een paar Kommitterens, um de Tostand to vernejen.
+settings.matrix.access_token_helper = Dat word anraden, daarfรถรถr eegens een Matrix-Konto intorichten. Dat Togangs-Teken kann in de Element-Internett-Sied (in eener privaaten/anonymen Karteikaart) unner Brukermenรผ (boven links) โ All Instellens โ Hรผlp & รver โ Togangs-Teken (stracks unner de Heimaadserver-URL) haalt worden. Maak de privaate/anonyme Karteikaart dicht (wenn du di avmellst, word dat Teken ungรผltig).
+issues.review.add_remove_review_requests = hett %[3]s um Nakiekens vun %[1]s anfraggt un de Nakiekens-Anfragen fรถr %[2]s wegdaan
+issues.review.add_review_requests = hett %[2]s um Nakiekens vun %[1]s anfraggt
+issues.review.remove_review_requests = hett %[2]s de Nakieken-Anfragen fรถr %[1]s wegdaan
+pulls.delete_after_merge.head_branch.is_protected = De Kopp-Twieg, wat du lรถsken willst, is een schรผtt Twieg un kann nich lรถsket worden.
+pulls.delete_after_merge.head_branch.insufficient_branch = Du hest nich dat Recht, de Kopp-Twieg to lรถsken.
+pulls.delete_after_merge.head_branch.is_default = De Kopp-Twieg, wat du lรถsken willst, is de Hรถรถvd-Twieg un kann nich lรถsket worden.
+issues.filter_sort.relevance = Belang
+diff.git-notes.add = Anmarken hentofรถgen
+diff.git-notes.remove-header = Anmarken wegdoon
+diff.git-notes.remove-body = Deeses Anmarken word wegdaan.
+issues.num_reviews_one = %d Nakieken
+issues.summary_card_alt = Tosamenfatens-Kaart vun eenem Gefall mit de Naam ยป%sยซ im Repositorium %s
+issues.num_reviews_few = %d Nakiekens
+settings.default_update_style_desc = Normaale Vernejens-Aard, wat bruukt word, um Haalvรถrslagens to vernejen, wat achter de Grund-Twieg torรผgg sรผnd.
+pulls.sign_in_require = Mell di an , um eenen nejen Haalvรถrslag to maken.
+new_from_template = Bruuk eene Vรถrlaag
+new_advanced = Mehr Instellens
+new_advanced_expand = Klick, um mehr to wiesen
+auto_init_description = Begรผnn de Git-Histoorje mit eenem LEESMI un fรถรถg, wenn du willst, Lizenz- un .gitignore-Dateien hento.
+new_from_template_description = Du kannst eene bestahn Repositoriums-Vรถrlaag up deeser Instanz utkรถren un hรถr Instellens anwennen.
+summary_card_alt = Tosamenfatens-Kaart vun de Repositorium %s
+issues.reaction.alt_add = De %[1]s-Reageren to de Kommentaar hentofรถgen.
+issues.reaction.add = Reageren hentofรถgen
+issues.reaction.alt_few = %[1]s hett mit %[2]s reageert.
+issues.reaction.alt_many = %[1]s un %[2]d anner hebben mit %[3]s reageert.
+issues.reaction.alt_remove = De %[1]s-Reageren vun de Kommentaar wegdoon.
+issues.context.menu = Kommentaar-Menรผ
+release.summary_card_alt = Tosamenfatens-Kaart vun eenem Publizeren mit de Naam ยป%sยซ im Repositorium %s
+editor.commit_email = Kommitterens-E-Mail
+archive.pull.noreview = Deeses Repositorium is archiveert. Du kannst keene Haalvรถrslagens nakieken.
+commits.view_single_diff = รnnerns an deeser Datei in deesem Kommitteren wiesen
+pulls.editable = Bewarkbaar
+pulls.editable_explanation = Deeser Haalvรถrslag verlรถรถvt Bewarkens vun Liddmaten. Du kannst stracks daarto bidragen.
+issues.reopen.blocked_by_user = Du kannst deeses Gefall nich weer opmaken, denn de Repositoriums-Eegner of de Autor vun de Gefall hett di blockeert.
+pulls.comment.blocked_by_user = Du kannst up deesem Haalvรถrslag nich kommenteren, denn de Repositoriums-Eegner of de Autor vun de Haalvรถrslag hett di blockeert.
+issues.filter_no_results = Keene Resultaten
+issues.filter_no_results_placeholder = Versรถรถk, diene Sรถรถk-Filters antopassen.
+
+[repo.permissions]
+code.read = Lesen: De Quelltext vun deesem Repositorium ankieken un klonen.
+code.write = Schrieven: Schuuv to de Repositorium un maak Twiegen un Markens.
+issues.read = Lesen: Gefallens un Kommentaren lesen un maken.
+issues.write = Schrieven: Gefallens dichtmaken un wiedere Informatioonen so as Vermarkens, Markstenen, Towiesens, Anstahns-Daten un Ofhangens bewarken.
+releases.write = Schrieven: Publizerens un hรถr Objekten publik maken, bewarken un lรถsken.
+releases.read = Lesen: Publizerens ankieken un runnerladen.
+wiki.write = Schrieven: Sieden in de inbaut Wiki maken, vernejen un lรถsken.
+wiki.read = Lesen: Dat inbaut Wiki un siene Histoorje lesen.
+pulls.write = Schrieven: Haalvรถrslagen dichtmaken un wiedere Informatioonen so as Vermarkens, Markstenen, Towiesens, Anstahns-Daten un Ofhangens bewarken.
+pulls.read = Lesen: Haalvรถrslagen lesen un maken.
+projects.read = Lesen: Repositoriums-Projekt-Bredden wiesen.
+projects.write = Schrieven: Projekten un Striepen maken un bewarken.
+packages.read = Lesen: Paketen in de Repositorium ankieken un runnerladen.
+actions.write = Schrieven: CI-/CD-Affolgens vun Hand utlรถsen, neei starten, ofbreken of tostimmen.
+actions.read = Lesen: CI-/CD-Affolgens un hรถr Utgaav ankieken.
+ext_issues = Togriep to de Verwies to eenem frรถmden Gefall-Verfolger. De Rechten worden frรถmd verwalt.
+ext_wiki = Togriep to de Verwies to eenem frรถmden Wiki. De Rechten worden frรถmd verwalt.
+packages.write = Schrieven: Paketen in de Repositorium publik maken un lรถsken.
+
+[graphs]
+component_loading = Lade %s โฆ
+component_loading_failed = Kunn %s nich laden
+component_loading_info = Dat kann een bietje dรผren โฆ
+component_failed_to_load = Een unverwacht Fehler is uptreden.
+code_frequency.what = Quelltext-Frequenz
+contributors.what = Bidragens
+recent_commits.what = Leste Kommitterens
+
+[org]
+org_name_holder = Vereenigungs-Naam
+org_full_name_holder = Kumpleter Naam vun de Vereenigung
+org_name_helper = Vereenigungs-Namen sallen kรถrt un lich to marken wesen.
+create_org = Vereenigung maken
+open_dashboard = Kontor opmaken
+repo_updated = %s verneeit
+members = Liddmaten
+teams = Klottjen
+code = Quelltext
+lower_members = Liddmaten
+lower_repositories = Repositoriums
+create_new_team = Neje Klottje
+team_name = Klottjen-Naam
+team_desc = Beschrieven
+team_desc_helper = Beschriev de Zweck of Rull vun de Klottje.
+team_access_desc = Repositoriums-Togriep
+team_permission_desc = Rechten
+team_unit_desc = Togriep to Repositoriums-Delen verlรถven
+team_unit_disabled = (Utknipst)
+form.create_org_not_allowed = Du hest nich dat Recht, eene Vereenigung to maken.
+settings = Instellens
+settings.options = Vereenigung
+settings.full_name = Kumpleter Naam
+settings.website = Internett-Sied
+settings.visibility.limited = Begrenzt (blots anmellt Brukers kรถnen โt sehn)
+settings.visibility.limited_shortname = Begrenzt
+settings.visibility.private_shortname = Privaat
+settings.update_settings = Instellens vernejen
+settings.update_setting_success = Vereenigungs-Instellens sรผnd verneeit worden.
+settings.change_orgname_redirect_prompt = De olle Naam leit daarhen um, bit well anners hรผm nimmt.
+settings.update_avatar_success = Dat Vereenigungs-Kontobill is verneeit worden.
+settings.delete = Vereenigung lรถsken
+settings.delete_account = Deese Vereenigung lรถsken
+settings.delete_prompt = Dat lรถsket de Vereenigung fรถr all Tieden. Dat KANN NICH torรผggnohmen worden!
+settings.confirm_delete_account = Lรถsken utwiesen
+settings.delete_org_title = Vereenigung lรถsken
+settings.delete_org_desc = De Vereenigung word fรถr all Tieden lรถsket. Wiedermaken?
+settings.labels_desc = Fรถรถg Vermarkens hento, wat fรถr Gefallens in all Repositoriums unner deeser Vereenigung bruukt worden kรถnen.
+create_team = Klottje maken
+form.name_pattern_not_allowed = Dat Muster ยป%sยซ is in eenem Vereenigungs-Naam nich verlรถรถvt.
+follow_blocked_user = Du kannst deeser Vereenigung nich nagahn, denn de Vereenigung hett du blockeert.
+form.name_reserved = De Vereenigungs-Naam ยป%sยซ is vรถrbehollen.
+settings.repoadminchangeteam = Repositoriums-Chef kann Togriep fรถr Klottjen hentofรถgen un wegdoon
+settings.email = Kuntakt-E-Mail
+settings.permission = Verlรถรถvnissen
+settings.visibility.private = Privaat (blots Vereenigungs-Liddmaten kรถnen โt sehn)
+team_name_helper = Klottjen-Namen sallen kรถrt un licht to marken wesen.
+settings.location = Stee
+settings.change_orgname_prompt = Wahrschau: Wenn du de Vereenigungs-Naam รคnnerst, รคnnert sik ok de Vereenigungs-URL un de olle Naam word freeigeven.
+org_desc = Beschrieven
+settings.visibility = Sichtbaarkeid
+settings.visibility.public = Publik
+settings.hooks_desc = Fรถรถg Internett-Hakens hento, wat fรถr all Repositoriums unner deeser Vereenigung utlรถรถst worden.
+members.membership_visibility = Liddmaat-Sichtbaarkeid:
+members.public = Sichtbaar
+members.public_helper = Verbargen
+members.private = Nich sichtbaar
+members.private_helper = Sichtbaar maken
+members.member_role = Liddmaat-Rull:
+members.owner = Eegner
+members.member = Liddmaat
+members.remove = Wegdoon
+members.remove.detail = %[1]s ut %[2]s wegdoon?
+members.leave = Verlaten
+members.leave.detail = Willst du de Vereenigung ยป%sยซ wรผrrelk verlaten?
+members.invite_desc = Fรถรถg eenen nejen Liddmaat to %s hento:
+members.invite_now = Nu inladen
+teams.join = Bitreden
+teams.leave = Verlaten
+teams.leave.detail = Willst du de Klottje ยป%sยซ wรผrrelk verlaten?
+teams.can_create_org_repo = Repositoriums maken
+teams.can_create_org_repo_helper = Liddmaten kรถnen neje Repositoriums in de Vereenigung maken. De Maker kriggt Chef-Rechten in de neje Repositorium.
+teams.none_access = Keen Togang
+teams.none_access_helper = De Instellen ยปKeen Togangยซ is blots fรถr privaate Repositoriums vun Belang.
+teams.general_access = Eegener Togang
+teams.general_access_helper = Liddmaten-Rechten worden vun de Rechten-Tabell unnern fastleggt.
+teams.read_access = Lesen
+teams.write_access = Schrieven
+teams.admin_access = Chef-Togang
+teams.no_desc = Deese Klottje is nich beschrieven
+teams.settings = Instellens
+teams.owners_permission_desc = Eegners hebben kumpleten Togang to all Repositoriums un hebben Chef-Togang to de Vereenigung.
+teams.update_settings = Instellens vernejen
+teams.delete_team = Klottje wegdoon
+teams.add_team_member = Klottjen-Liddmaat hentofรถgen
+teams.delete_team_success = De Klottje is wegdaan worden.
+teams.write_permission_desc = Deese Klottje gifft Schrievens -Togriep: Liddmaten kรถnen Klottjen-Repositoriums ankieken un daarhen schuven.
+teams.remove_all_repos_title = All Klottjen-Repositoriums wegdoon
+teams.add_all_repos_title = All Repositoriums hentofรถgen
+teams.add_nonexistent_repo = Dat Repositorium, wat du hentofรถgen willst, gifft dat nich; bidde maak โt eerst.
+teams.add_duplicate_users = Bruker is al een Klottjen-Liddmaat.
+teams.members.none = Deese Klottje hett keene Liddmaten.
+teams.specific_repositories = Wisse Repositoriums
+teams.all_repositories_helper = Klottje het Togang to all Repositoriums. Wenn du dat utkรถรถrst, worden all bestahn Repositoriums to de Klottje hentofรถรถgt.
+teams.invite.title = Du bรผst inladen worden, to de Klottje %s in de Vereenigung %s bitotreden.
+teams.invite.by = Vun %s inladen
+teams.invite.description = Bidde klick up de Knoop unnern, um to de Klottje bitotreden.
+teams.invite_team_member = To %s inladen
+teams.delete_team_desc = Wenn du eene Klottje wegdoost, hebben hรถr Liddmaten keen Togriep mehr up de Repositoriums. Wiedermaken?
+teams.admin_permission_desc = Deese Klottje gifft Chef -Togriep: Liddmaten kรถnen Klottjen-Repositoriums ankieken, daarhen schuven un Mitarbeiders hentofรถgen.
+teams.create_repo_permission_desc = Daarto gifft deese Klottje dat Recht, Repositoriums to maken : Liddmaten kรถnen neje Repositoriums in de Vereenigung maken.
+teams.repositories = Klottjen-Repositoriums
+teams.members = Klottjen-Liddmaten
+teams.add_all_repos_desc = Dat fรถรถgt all de Repositoriums in de Vereenigung to de Klottje hento.
+teams.admin_access_helper = Liddmaten kรถnen to Klottjen-Repositoriums schuven un halen un daar Mitarbeiders hentofรถgen.
+teams.delete_team_title = Klottje wegdoon
+teams.invite_team_member.list = Utstahn Inladens
+teams.remove_all_repos_desc = Dat doot all Repositoriums vun de Klottje weg.
+teams.read_permission_desc = Deese Klottje gifft Lesens -Togriep: Liddmaten kรถnen Klottjen-Repositoriums ankieken un klonen.
+teams.repos.none = Deese Klottje kann up keene Repositoriums togriepen.
+teams.specific_repositories_helper = Liddmaten hebben blots Togriep up Repositoriums, wat besรผnners to de Klottje hentofรถรถgt worden sรผnd. Wenn du dat utkรถรถrst, worden Repositoriums, wat du al mit All Repositoriums hentofรถรถgt hest, nich automatisk wegdaan .
+teams.all_repositories = All Repositoriums
+settings.change_orgname_redirect_prompt.with_cooldown.one = De olle Vereenigungs-Naam word na eener Ofkรถhl-Dรผรผr vun %[1]d Dag fรถr all Lรผรผ verfรถรถgbaar wesen. In de Ofkรถhl-Dรผรผr kannst du de ollen Naam noch torรผgghalen.
+settings.change_orgname_redirect_prompt.with_cooldown.few = De olle Vereenigungs-Naam word na eener Ofkรถhl-Dรผรผr vun %[1]d Dagen fรถr all Lรผรผ verfรถรถgbaar wesen. In de Ofkรถhl-Dรผรผr kannst du de ollen Naam noch torรผgghalen.
+
+[admin]
+dashboard = Kontor
+self_check = Sรผlvst-รverprรผfen
+identity_access = Sรผlvst & Togang
+users = Brukerkonten
+organizations = Vereenigungen
+assets = Quelltext-Objekten
+repositories = Repositoriums
+hooks = Internett-Hakens
+integrations = Inbinnens
+authentication = Anmellens-Quellen
+emails = Bruker-E-Mails
+config = Inrichten
+notices = Systeem-Narichtens
+config_summary = Tosamenfaten
+monitor = รverwachen
+first_page = Eerste
+last_page = Leste
+config_settings = Instellens
+total = All tosamen: %d
+settings = Chef-Instellens
+dashboard.statistic = Tosamenfaten
+dashboard.operations = Plegens-Aktioonen
+dashboard.new_version_hint = Forgejo %s is nu verfรถรถgbaar, du hest %s. Kiek de Blog fรถr mehr Informatioonen an.
+dashboard.delete_generated_repository_avatars = Maakte Repositoriums-Kontobillers lรถsken
+dashboard.sync_repo_tags = Markens vun Git-Daten to de Datenbank spegeln
+dashboard.update_mirrors = Spegels vernejen
+dashboard.repo_health_check = Gesundheids-รverprรผfen fรถr all Repositoriums
+dashboard.check_repo_stats = De Statistiken vun all Repositoriums รถverprรผfen
+dashboard.deleted_branches_cleanup = Lรถsket Twiegen uprรผmen
+dashboard.git_gc_repos = Up all Repositoriums de Mรผll avhalen
+dashboard.resync_all_sshprincipals = De ยป.ssh/authorized_principalsยซ-Datei mit de SSH-Hรถรถvdmannen vun Forgejo vernejen.
+dashboard.reinit_missing_repos = All fehlend Git-Repositoriums neei inrichten, fรถr wat dat Uptekens gifft
+dashboard.cleanup_packages = Avlopen Paketen uprรผmen
+dashboard.cleanup_actions = Avlopen Utgaven un Objekten vun Aktioonen uprรผmen
+dashboard.current_goroutine = Stedenwies Go-Routinen
+dashboard.total_memory_allocated = Spieker towiesen all tosamen
+dashboard.memory_allocate_times = Spieker-Towiesens
+dashboard.system_status = Systeem-Tostand
+dashboard.operation_switch = Wesseln
+dashboard.operation_run = Utfรถhren
+dashboard.clean_unbind_oauth_success = All unverbunnen OAuth-Verbinnens sรผnd wegdaan worden.
+dashboard.task.process = Upgaav: %[1]s
+dashboard.task.cancelled = Upgaav: %[1]s ofbroken: %[3]s
+dashboard.task.error = Fehler in Upgaav: %[1]s: %[3]s
+dashboard.task.unknown = Unbekannte Upgaav: %[1]s
+dashboard.cron.started = Hett Tiedplaan begunnen: %[1]s
+dashboard.cron.error = Fehler im Tiedplaan: %s: %[3]s
+dashboard.delete_inactive_accounts.started = Upgaav, um all nich aktiveerten Konten to lรถsken, begunnen.
+dashboard.delete_repo_archives = All Repositoriums-Archiven (ZIP, TAR.GZ, usw. โฆ) lรถsken
+dashboard.delete_missing_repos.started = Upgaav, um all Repositoriums sรผnner Git-Dateien to lรถsken, begunnen.
+dashboard.delete_missing_repos = All Repositoriums sรผnner Git-Dateien lรถsken
+dashboard.task.finished = Upgaav: %[1]s vun %[2]s begunnen is daan worden
+dashboard.cron.finished = Tiedplaan: %[1]s is daan worden
+dashboard.operation_name = Aktioons-Naam
+dashboard.cron.process = Tiedplaan: %[1]s
+dashboard.cron.cancelled = Tiedplaan: %[1]s ofbroken: %[3]s
+dashboard.resync_all_sshkeys = De ยป.ssh/authorized_keysยซ-Datei mit de SSH-Slรถtels vun Forgejo vernejen.
+dashboard.memory_obtained = Spieker erhollen
+dashboard.pointer_lookup_times = Wieser-Nakiek-Tieden
+dashboard.task.started = Hett Upgaav begunnen: %[1]s
+dashboard.delete_inactive_accounts = All nich aktiveerten Konten lรถsken
+dashboard.delete_repo_archives.started = Upgaav, um all Repositoriums-Archiven to lรถsken, begunnen.
+dashboard.archive_cleanup = Olle Repositoriums-Archiven lรถsken
+dashboard.resync_all_hooks = De Hakens ยปpre-receiveยซ, ยปupdateยซ un ยปpost-receiveยซ in all Repositoriums vernejen
+dashboard.clean_unbind_oauth = Unverbunnen OAuth-Verbinnens uprรผmen
+dashboard.sync_repo_branches = Fehlend Twiegen vun Git-Daten to de Datenbank spegeln
+dashboard.update_migration_poster_id = Umtreck-Autor-IDs vernejen
+dashboard.cleanup_hook_task_table = hook_task-Tabell uprรผmen
+dashboard.sync_external_users = Frรถmde Brukerdaten vernejen
+dashboard.server_uptime = Server-Bedrievstied
+dashboard.current_memory_usage = Stedenwies Spiekerbruuk
+dashboard.heap_memory_obtained = Hoopspieker erhollen
+dashboard.current_heap_usage = Stedenwies Hoopbruuk
+dashboard.heap_memory_idle = Hoopspieker mit nix to doon
+dashboard.heap_memory_released = Hoopspieker freeigeven
+dashboard.heap_objects = Hoopobjekten
+dashboard.bootstrap_stack_usage = Bootstrap-Stapelbruuk
+dashboard.stack_memory_obtained = Stapelspieker erhollen
+dashboard.mspan_structures_usage = MSpan-Struktuuren-Bruuk
+dashboard.mspan_structures_obtained = MSpan-Struktuuren erhollen
+dashboard.mcache_structures_usage = MCache-Struktuuren-Bruuk
+dashboard.gc_metadata_obtained = Wiedere Informatioonen fรถr GC erhollen
+dashboard.other_system_allocation_obtained = Anner Systeemtowiesens erhollen
+dashboard.next_gc_recycle = Anner GC-Mรผllavhalen
+dashboard.last_gc_time = Tied siet lestem GC
+dashboard.total_gc_pause = GC-Paus all tosamen
+dashboard.last_gc_pause = Leste GC-Paus
+dashboard.gc_times = GC-Tieden
+dashboard.delete_old_actions = All olles Doon ut de Datenbank lรถsken
+dashboard.update_checker = Vernejens-Sรถรถker
+dashboard.delete_old_system_notices = All ollen Systeemnarichten ut de Datenbank lรถsken
+dashboard.gc_lfs = In LFS-Meta-Objekten de Mรผll avhalen
+dashboard.stop_zombie_tasks = Spรถรถk-Aktioonen-Upgaven anhollen
+dashboard.stop_endless_tasks = Aktioonen-Upgaven sรผnner Enn anhollen
+dashboard.cancel_abandoned_jobs = Verlaten Aktioonen-Upgaven ofbreken
+dashboard.sync_branch.started = Twieg-Vernejen begunnen
+users.user_manage_panel = Brukerkonten verwalten
+users.new_account = Brukerkonto maken
+users.name = Brukernaam
+users.full_name = Kumpleter Naam
+users.activated = Aktiveert
+users.admin = Chef
+users.restricted = Begrenzt
+users.reserved = Vรถrbehollen
+users.created = Maakt
+users.last_login = Tolest anmellt
+users.never_login = Nie anmellt
+users.send_register_notify = E-Mail-Naricht รถver dat Registreren schicken
+users.new_success = Dat Brukerkonto ยป%sยซ is maakt worden.
+users.edit = Bewarken
+users.auth_source = Anmellens-Quell
+users.local = Stedenwies
+users.auth_login_name = Anmell-Naam
+users.password_helper = Laat dat Passwoord leeg, um dat nich to รคnnern.
+users.update_profile_success = Dat Brukerkonto is verneeit worden.
+users.edit_account = Brukerkonto bewarken
+users.is_activated = Konto aktiveert
+users.prohibit_login = Konto sperrt
+users.block.description = Deesem Bruker verseggen, mit deesem Deenst dรถr deeses Konto to warken, un dat Anmellen verseggen.
+users.is_admin = Chefkonto
+users.admin.description = Deesem Bruker kumpleten Togriep to all Chef-Aktioonen geven, wat mit de Internett-Schnittstee un de API gahn.
+users.is_restricted = Begrenztes Konto
+users.allow_git_hook = Kann Git-Hakens maken
+dashboard.memory_free_times = Spieker-Freeigevens
+users.bot = Bot
+users.2fa = 2FA
+dashboard.profiling_bucket_hash_table_obtained = Profileren-Emmer-Prรผfsummtabell erhollen
+dashboard.sync_tag.started = Mark-Vernejen begunnen
+dashboard.rebuild_issue_indexer = Gefall-Indizerer neei bauen
+users.activated.description = Of dat E-Mail-Utwiesen ofsluten is. De Eegner vun eenem nich aktiveerten Konto kann sik nich anmellen, bit dat E-Mail-Utwiesen ofsluten is.
+dashboard.heap_memory_in_use = Hoopspieker bruukt
+users.max_repo_creation_desc = (Giff -1 in, um de Normaalweert vun de Instanz to bruken.)
+dashboard.mcache_structures_obtained = MCache-Struktuuren erhollen
+dashboard.start_schedule_tasks = Aktioonen-Upgaven mit Tiedplaan begรผnnen
+users.remote = Frรถmd
+users.max_repo_creation = Hoogste Tahl vun Repositoriums
+dashboard.delete_old_actions.started = Hett begunnen, all olles Doon ut de Datenbank to lรถsken.
+users.repos = Repos
+users.restricted.description = Verlรถรถv blots, mit de Repositoriums un Vereenigungen to warken, waar deeser Bruker as Mitarbeider hentofรถรถgt is. Dat verhinnert Togriep to publiken Repositoriums in deeser Instanz.
+users.allow_git_hook_tooltip = Git-Hakens worden as de BS-Bruker utfรถhrt, unner well Forgejo lรถppt, un hebben dat sรผlve Maat an Host-Togriep. Also kรถnen Brukers mit de Git-Haak-Recht all Forgejo-Repositoriums ankieken un bewarken un ok de Datenbank, wat Forgejo bruukt. Also kรถnen se ok Chef-Rechten fรถr Forgejo kriegen.
+users.allow_import_local = Kann stedenwies Repositoriums importeren
+users.local_import.description = Verlรถรถv, Repositoriums vun de stedenwies Dateisysteem vum Server to importeren. Dat kann een Sekerheidsprobleem wesen.
+users.allow_create_organization = Kann Vereenigungen maken
+users.organization_creation.description = Verlรถรถv, neje Vereenigungen to maken.
+users.update_profile = Brukerkonto vernejen
+users.delete_account = Brukerkonto lรถsken
+users.cannot_delete_self = Du kannst nich di sรผlven lรถsken
+users.still_own_repo = De Bruker is noch een Eegner vun een of mehr Repositoriums. Lรถske of รถverdraag deese Repositoriums eerst.
+users.still_has_org = De Bruker is noch een Liddmaat vun eener Vereenigung. Doo de Bruker eerst ut all Vereenigungen weg.
+users.purge = Bruker wegschรผren
+users.purge_help = Mit Dwang de Bruker un all siene Repositoriums, Vereenigungen un Paketen lรถsken. All Kommentaren un Gefallens, wat deeser Bruker maakt hett, worden ok lรถsket.
+users.still_own_packages = Deeser Bruker is noch Eegner vun een of mehr Paketen, lรถske eerst deese Paketen.
+users.list_status_filter.menu_text = Filter
+users.list_status_filter.not_active = Nich aktiiv
+users.list_status_filter.is_restricted = Begrenzt
+users.list_status_filter.not_restricted = Unbegrenzt
+users.list_status_filter.is_2fa_enabled = 2FA anknipst
+users.list_status_filter.not_2fa_enabled = 2FA utknipst
+users.details = Bruker-Informatioonen
+emails.email_manage_panel = Bruker-E-Mails verwalten
+emails.primary = Hรถรถvd
+emails.activated = Aktiveert
+emails.filter_sort.email = E-Mail
+emails.filter_sort.email_reverse = E-Mail (umdreiht)
+emails.filter_sort.name = Brukernaam
+emails.filter_sort.name_reverse = Brukernaam (umdreiht)
+emails.updated = E-Mail verneeit
+emails.not_updated = Kunn de erbeden E-Mail-Adress nich vernejen: %v
+emails.duplicate_active = Deese E-Mail-Adress is al fรถr eenen anner Bruker aktiiv.
+emails.change_email_header = E-Mail-Eegenskuppen vernejen
+emails.change_email_text = Willst du deese E-Mail-Adress wรผrrelk vernejen?
+emails.delete = E-Mail wegdoon
+emails.delete_desc = Willst du deese E-Mail-Adress wรผrrelk wegdoon?
+emails.deletion_success = De E-Mail-Adress is wegdaan worden.
+emails.delete_primary_email_error = Du kannst de Hรถรถvd-E-Mail nich wegdoon.
+orgs.org_manage_panel = Vereenigungen verwalten
+orgs.name = Naam
+orgs.teams = Klottjen
+orgs.members = Liddmaten
+orgs.new_orga = Neje Vereenigung
+repos.repo_manage_panel = Repositoriums verwalten
+repos.unadopted = Repositoriums sรผnner Eegner
+repos.unadopted.no_more = Keene Repositoriums sรผnner Eegner funnen.
+repos.owner = Eegner
+repos.name = Naam
+repos.private = Privaat
+repos.issues = Gefallens
+repos.size = Grรถtt
+repos.lfs_size = LFS-Grรถtt
+packages.package_manage_panel = Paketen verwalten
+packages.total_size = Grรถtt all tosamen: %s
+packages.unreferenced_size = Unbenรถรถmt Grรถtt: %s
+packages.cleanup = Avlopen Daten uprรผmen
+packages.cleanup.success = Avlopen Daten uprรผรผmt
+packages.owner = Eegner
+packages.creator = Maker
+packages.name = Naam
+packages.version = Versioon
+packages.type = Aard
+packages.repository = Repositorium
+packages.size = Grรถtt
+packages.published = Publizeert
+defaulthooks = Normaale Internett-Hakens
+defaulthooks.add_webhook = Normaalen Internett-Haak hentofรถgen
+defaulthooks.update_webhook = Normaalen Internett-Haak vernejen
+systemhooks = Systeem-Internett-Hakens
+systemhooks.add_webhook = Systeem-Internett-Haak hentofรถgen
+systemhooks.update_webhook = Systeem-Internett-Haak vernejen
+auths.auth_manage_panel = Anmellens-Quellen verwalten
+auths.new = Anmellens-Quell hentofรถgen
+auths.name = Naam
+auths.type = Aard
+systemhooks.desc = Internett-Hakens schicken automatisk HTTP-POST-Anfragen to eenem Server, wenn wisse Forgejo-Vรถrfallen passeren. Internett-Hakens, wat hier inricht worden, hanneln fรถr all Repositoriums in de Systeem, also bedenk bidde, wat dat fรถr de Systeemlast heten word. Lees mehr in de Internett-Hakens-Dokumenteren .
+auths.enabled = Anknipst
+auths.updated = Verneeit
+auths.security_protocol = Sekerheids-Protokoll
+auths.domain = Domรครคn
+auths.host = Host
+auths.port = Poort
+auths.bind_dn = Binne-DN
+auths.bind_password = Binne-Passwoord
+auths.user_base = Bruker-Sรถรถk-Grundlaag
+auths.user_dn = Bruker-DN
+auths.attribute_username = Brukernaam-Eegenskupp
+auths.attribute_username_placeholder = Laat dat leeg, um de Brukernaam to bruken, wat in Forgejo ingeven worden is.
+auths.attribute_name = Vรถrnaam-Eegenskupp
+auths.attribute_surname = Achternaam-Eegenskupp
+auths.attribute_mail = E-Mail-Eegenskupp
+auths.attribute_ssh_public_key = Eegenskupp fรถr publiken SSH-Slรถtel
+auths.attribute_avatar = Kontobill-Eegenskupp
+auths.attributes_in_bind = Eegenskuppen in Binne-DN-Umgeven halen
+auths.default_domain_name = Normaaler Domรครคn-Naam fรถr de E-Mail-Adress
+auths.allow_deactivate_all = Verlรถรถv, dat een leges Sรถรถkresultaat all Brukers as nich aktiiv sett
+auths.use_paged_search = Sรถรถk mit Siedens bruken
+auths.search_page_size = Siedengrรถtt
+auths.filter = Bruker-Filter
+auths.admin_filter = Chef-Filter
+auths.restricted_filter = Begrenzt-Filter
+auths.verify_group_membership = Gruppen-Liddmatenskupp in LDAP utwiesen (laat de Filter leeg, um dat to รถverspringen)
+auths.group_search_base = Gruppensรถรถk-Grundlaag-DN
+auths.group_attribute_list_users = Gruppen-Eegenskupp, wat de Brukerlist enthollt
+auths.user_attribute_in_group = Bruker-Eegenskupp in Grupp list
+auths.map_group_to_team_removal = Brukers ut spegelt Klottjen wegdoon, wenn de Bruker nich in de tohรถrig LDAP-Grupp is
+auths.enable_ldap_groups = LDAP-Gruppen anknipsen
+auths.ms_ad_sa = MS-AD-Sรถรถk-Eegenskuppen
+auths.smtp_auth = SMTP-Anmellens-Aard
+auths.smtphost = SMTP-Host
+auths.smtpport = SMTP-Poort
+auths.allowed_domains = Verlรถรถvte Domรคnen
+auths.skip_tls_verify = TLS-Utwiesen รถverspringen
+auths.force_smtps = SMTPS dwingen
+auths.helo_hostname = HELO-Hostnaam
+auths.helo_hostname_helper = Hostnaam, wat mit HELO schickt word. Laat dat leeg, um de stedenwies Hostnaam to schicken.
+auths.disable_helo = HELO utknipsen
+auths.pam_service_name = PAM-Deenst-Naam
+auths.pam_email_domain = PAM-E-Mail-Domรครคn (nich nรถdig)
+auths.oauth2_provider = OAuth2-Anbeder
+auths.oauth2_icon_url = Bill-URL
+auths.oauth2_clientID = Klient-ID (Slรถtel)
+auths.oauth2_clientSecret = Klient-Geheemst
+auths.oauth2_use_custom_url = Eegene URLs in Stee vun de normaalen URLs bruken
+auths.oauth2_tokenURL = Teken-URL
+auths.oauth2_authURL = Anmellen-URL
+auths.oauth2_profileURL = Profil-URL
+auths.oauth2_emailURL = E-Mail-URL
+auths.skip_local_two_fa = Stedenwies 2FA รถverspringen
+auths.oauth2_tenant = Inwohner
+auths.oauth2_scopes = Wiedere Rebeeten
+users.deletion_success = Dat Brukerkonto is lรถsket worden.
+users.list_status_filter.is_admin = Chef
+auths.syncenabled = Bruker-Vernejen anknipsen
+users.reset_2fa = 2FA torรผggsetten
+users.list_status_filter.is_prohibit_login = Anmellen verseggen
+users.list_status_filter.not_admin = Keen Chef
+auths.auth_type = Anmellens-Aard
+auths.restricted_filter_helper = Laat dat leeg, wenn keene Brukers begrenzt wesen sallen. Bruuk eenen Steern (ยป*ยซ), um all Brukers, wat nich up de Chef-Filter passen, as begrenzt to setten.
+auths.force_smtps_helper = SMTPS word alltieden up Poort 465 bruukt. Sett dat, um SMTPS up anner Poorten to dwingen. (Anners word up anner Poorten STARTTLS bruukt, wenn de Host dat unnerstรผtt.)
+users.list_status_filter.reset = Torรผggsetten
+users.list_status_filter.is_active = Aktiiv
+users.list_status_filter.not_prohibit_login = Anmellen verlรถven
+auths.auth_name = Anmellens-Naam
+auths.map_group_to_team = LDAP-Gruppens up Vereenigungs-Klottjen avbillen (laat dat Feld leeg, um dat to รถverspringen)
+auths.allowed_domains_helper = Laat dat leeg, um all Domรคnens to verlรถven. Trenn mennig Domรคnen mit eenem Komma (ยป,ยซ).
+defaulthooks.desc = Internett-Hakens schicken automatisk HTTP-POST-Anfragen to eenem Server, wenn wisse Forgejo-Vรถrfallen passeren. Internett-Hakens, wat hier inricht worden, sรผnd Normaalweertens un worden in all neje Repositoriums kopeert. Lees mehr in de Internett-Hakens-Dokumenteren .
+auths.openIdConnectAutoDiscoveryURL = URL fรถr Automatisk Utfรถrsken mit OpenID-Verbinnen
+auths.skip_local_two_fa_helper = Wenn dat nich sett is, heet dat, dat stedenwies Brukers mit 2FA doch tum Anmellen dรถr 2FA gahn mutten
+auths.oauth2_required_claim_name = Nรถdig Anrecht-Naam
+auths.oauth2_required_claim_value = Nรถdig Anrecht-Weert
+auths.oauth2_required_claim_value_helper = Sett deesen Weert, um dat Anmellen vun deesem Quell blots to Brukers to verlรถven, well een Anrecht up deesen Naam un Weert hebben
+auths.oauth2_required_claim_name_helper = Sett deesen Naam, um dat Anmellen vun deesem Quell blots to Brukers to verlรถven, well een Anrecht up deesen Naam hebben
+auths.oauth2_group_claim_name = Anrecht-Naam, wat Gruppnamen fรถr deesen Quell gifft. (Nich nรถdig)
+auths.oauth2_admin_group = Gruppen-Anrecht-Weert fรถr Chef-Brukers. (Nich nรถdig โ bruukt boven de Anrecht-Naam)
+auths.oauth2_restricted_group = Gruppen-Anrecht-Weert fรถr begrenzte Brukers. (Nich nรถdig โ bruukt boven de Anrecht-Naam)
+auths.oauth2_map_group_to_team = Billt Anrechts-Gruppen up Vereenigungs-Klottjen av. (Nich nรถdig โ bruukt boven de Anrecht-Naam)
+auths.oauth2_map_group_to_team_removal = Brukers vun spegelt Klottjen wegdoon, wenn de Bruker nich to de tohรถrig Grupp daartohรถรถrt.
+auths.sspi_auto_create_users = Brukers automatisk maken
+auths.sspi_auto_activate_users = Brukers automatisk aktiveren
+auths.sspi_auto_activate_users_helper = Verlรถรถvt de SSPI-Anmellens-Aard, neje Brukers automatisk to aktiveren
+auths.sspi_separator_replacement = Trennteken, wat in Stee vun \, / un @ bruukt word
+auths.sspi_separator_replacement_helper = De Bookstaav, wat bruukt word, um de Trenntekens vun unnerรถrnt Anmell-Namen uttowesseln (toโn Bispรถรถl dat \ in ยปDOMAIN\brukerยซ) un Bruker-Hรถรถvdmann-Namen (toโn Bispรถรถl dat @ in ยปbruker@example.orgยซ).
+auths.sspi_default_language = Bruker-Normaal-Spraak
+auths.tips = Tipps
+auths.tips.gmail_settings = Gmail-Instellens:
+auths.tips.oauth2.general = Anmellen mit OAuth2
+auths.tips.oauth2.general.tip = Wenn du een nejes OAuth2-Programm vermarkst, sall de Rรผckroop-/Umleit-URL wesen:
+auths.tip.oauth2_provider = OAuth2-Anbeder
+auths.tip.bitbucket = Vermark eenen nejen OAuth-Bruker up %s un fรถรถg de Verlรถรถv ยปKontoยซ โ ยปLesenยซ hento
+auths.tip.nextcloud = Vermark eenen nejen OAuth-Bruker up diener Instanz, indeem du dat Menรผ ยปInstellensยซ โ ยปSekerheidยซ โ ยปOAuth-2.0-Klientยซ bruukst
+auths.tip.dropbox = Maak een nejes Programm up %s
+auths.tip.github = Vermark een nejes OAuth-Programm up %s
+auths.tip.gitlab_new = Vermark een nejes Programm up %s
+auths.tip.google_plus = Haal OAuth2-Klient-Anmelldaten vun de Google-API-Konsool up %s
+auths.tip.discord = Vermark een nejes Programm up %s
+auths.tip.gitea = Vermark een nejes OAuth2-Programm. Anleden kann up %s funnen worden
+auths.tip.twitter = Gah to %s, maak een Programm un wees wiss, dat de Instellen ยปVerlรถรถv deesem Programm, tum Anmellen mit Twitter bruukt to wordenยซ anknipst is
+auths.edit = Anmellens-Quell bewarken
+auths.activated = Deeser Anmellens-Quell is aktiveert
+auths.new_success = De Anmellens-Aard ยป%sยซ is hentofรถรถgt worden.
+auths.update_success = De Anmellens-Quell is verneeit worden.
+auths.update = Anmellens-Quell vernejen
+auths.delete = Anmellens-Quell wegdoon
+auths.delete_auth_title = Anmellens-Quell wegdoon
+auths.delete_auth_desc = Wenn du eenen Anmellens-Quell wegdoost, kรถnen Brukers dat nich mehr bruken, um sik antomellen. Wiedermaken?
+auths.still_in_used = De Anmellens-Quell word noch bruukt. Du muttst Brukers, wat deesen Anmellens-Quell bruken, eerst รคnnern of lรถsken.
+auths.deletion_success = De Anmellens-Quell is wegdaan worden.
+auths.login_source_exist = De Anmellens-Quell ยป%sยซ gifft dat al.
+auths.unable_to_initialize_openid = Kann de OpenID-Verbinnens-Anbeder nich inrichten: %s
+auths.invalid_openIdConnectAutoDiscoveryURL = Ungรผltige URL fรถr Automatisk Utfรถrsken (dat mutt eene gรผltige URL wesen, wat mit http:// of https:// begรผnnt)
+config.server_config = Server-Inrichten
+config.app_name = Instanz-Titel
+config.app_slogan = Instanz-Motto
+config.app_ver = Forgejo-Versioon
+config.app_url = Grund-URL
+config.custom_file_root_path = Eegener Datei-Ruut-Padd
+config.domain = Server-Domรครคn
+config.offline_mode = Stedenwies-Modus
+config.disable_router_log = Router-Utgaav utknipsen
+config.run_user = Bruker fรถr โt Utfรถhren
+config.run_mode = Utfรถhrens-Aard
+config.git_version = Git-Versioon
+config.lfs_root_path = LFS-Ruut-Padd
+config.script_type = Schrievens-Aard
+config.ssh_config = SSH-Inrichten
+config.ssh_enabled = Anknipst
+config.ssh_start_builtin_server = Inbaut Server bruken
+config.ssh_domain = SSH-Server-Domรครคn
+config.ssh_port = Poort
+config.ssh_listen_port = Tohรถren-Poort
+config.ssh_root_path = Ruutpadd
+config.ssh_key_test_path = Slรถteltestpadd
+config.ssh_minimum_key_size_check = Minnste Slรถtelgrรถtt prรผfen
+config.ssh_minimum_key_sizes = Minnste Slรถtelgrรถten
+config.lfs_config = LFS-Inrichten
+config.lfs_enabled = Anknipst
+config.lfs_content_path = LFS-Inholls-Padd
+config.db_config = Datenbank-Inrichten
+config.db_type = Aard
+config.db_host = Host
+config.db_name = Naam
+config.db_user = Brukernaam
+config.db_schema = Schema
+config.db_ssl_mode = SSL
+config.db_path = Padd
+config.register_email_confirm = E-Mail-Utwiesen biโm Registreren verlangen
+config.disable_register = Sรผlvst-Registreren utknipsen
+config.reverse_auth_user = Umdreiht-Proxy-Anmell-Bruker
+config.lfs_http_auth_expiry = LFS-HTTP-Anmellens-Avlooptied
+config.enable_openid_signin = OpenID-Anmellen anknipsen
+config.show_registration_button = Registreren-Knoop wiesen
+config.require_sign_in_view = Anmellen verlangen, um Inholl to wiesen
+config.mail_notify = E-Mail-Narichtens anknipsen
+config.enable_captcha = CAPTCHA anknipsen
+config.active_code_lives = Ofloops-Dรผรผr vun de Aktiverens-Teken
+config.default_keep_email_private = E-Mail-Adressen normaal verbargen
+config.default_allow_create_organization = Normaal verlรถven, Vereenigungen to maken
+config.enable_timetracking = Tied-Erfaten anknipsen
+config.default_enable_timetracking = Tied-Erfaten normaal anknipsen
+config.default_allow_only_contributors_to_track_time = Blots Bidragers Tied erfaten laten
+config.no_reply_address = Verburgen E-Mail-Domรครคn
+config.default_visibility_organization = Normaal-Sichtbaarkeid vun nejen Vereenigungen
+config.default_enable_dependencies = Gefall-Ofhangens normaal anknipsen
+config.webhook_config = Internett-Haak-Inrichten
+config.queue_length = Slang-Lรคngde
+config.deliver_timeout = Lever-Tied-รverweggahn
+config.skip_tls_verify = TLS-Utwiesen รถverspringen
+config.mailer_config = E-Mailer-Inrichten
+config.mailer_enabled = Anknipst
+config.mailer_enable_helo = HELO anknipsen
+config.mailer_name = Naam
+config.mailer_smtp_addr = SMTP-Host
+config.mailer_smtp_port = SMTP-Poort
+config.mailer_user = Bruker
+config.mailer_use_sendmail = Sendmail bruken
+config.mailer_sendmail_path = Sendmail-Padd
+config.mailer_sendmail_args = Wiedere Argumenten fรถr Sendmail
+config.mailer_sendmail_timeout = Sendmail-Tied-รverweggahn
+config.test_email_placeholder = E-Mail (toโn Bispรถรถl test@example.com)
+config.send_test_mail = Test-E-Mail schicken
+config.send_test_mail_submit = Schicken
+config.test_mail_failed = Kunn keene Test-E-Mail an ยป%sยซ schicken: %v
+config.test_mail_sent = Eene Test-E-Mail is an ยป%sยซ schickt worden.
+config.oauth_config = OAuth-Inrichten
+config.oauth_enabled = Anknipst
+config.cache_config = Tรผskenspieker-Inrichten
+config.cache_adapter = Tรผskenspieker-Anpasser
+config.cache_interval = Tรผskenspieker-Tiedofstand
+config.cache_conn = Tรผskenspieker-Verbinnen
+config.cache_test = Tรผskenspieker testen
+config.cache_test_failed = Kunn de Tรผskenspieker nich nakieken: %v.
+config.cache_test_succeeded = Tรผskenspieker-Test daankregen, hett eene Antwoord in %s kregen.
+config.session_config = Sitzungs-Inrichten
+config.mailer_use_dummy = Muster
+config.cache_item_ttl = Tรผskenspieker-Ding-TTL
+config.session_provider = Sitzungs-Anbeder
+config.provider_config = Anbeder-Inrichten
+config.cookie_name = Kookje-Naam
+config.gc_interval_time = GC-Tiedofstand
+config.session_life_time = Sitzungs-Levenstied
+config.https_only = Blots HTTPS
+config.cookie_life_time = Kookje-Levenstied
+config.picture_config = Bill- und Kontobill-Inrichten
+config.picture_service = Billdeenst
+config.disable_gravatar = Gravatar utknipsen
+config.enable_federated_avatar = Verdeelte Kontobillers anknipsen
+config.git_config = Git-Inrichten
+config.git_disable_diff_highlight = Syntax-Vรถrheven im Unnerscheed utknipsen
+config.git_max_diff_lines = Hoogste Unnerscheeds-Riegen pro Datei
+config.git_max_diff_line_characters = Hoogste Unnerscheeds-Bookstavens pro Rieg
+config.git_max_diff_files = Hoogste Tahl vun Unnerscheeds-Dateien wiest
+config.git_gc_args = GC-Argumenten
+config.git_migrate_timeout = Umtreck-Tied-รverweggahn
+config.git_mirror_timeout = Spegel-Vernejens-Tied-รverweggahn
+config.git_clone_timeout = Klonen-Tied-รverweggahn
+config.git_pull_timeout = Haal-Tied-รverweggahn
+config.git_gc_timeout = GC-Tied-รverweggahn
+config.log_config = Utgaav-Inrichten
+config.logger_name_fmt = Utgever: %s
+config.disabled_logger = Utknipst
+config.access_log_mode = Utgaav-Togrieps-Aard
+config.access_log_template = Utgaav-Togrieps-Vรถrlaag
+config.xorm_log_sql = SQL utgeven
+monitor.stats = Statistiken
+monitor.cron = Tiedplaan-Upgaven
+monitor.name = Naam
+monitor.schedule = Tiedplaan
+monitor.next = Anner Maal
+monitor.previous = Lestes Maal
+monitor.process = Lopend Prozessen
+monitor.stacktrace = Stapelspoor
+monitor.processes_count = %d Prozessen
+monitor.download_diagnosis_report = Faststellens-Bericht runnerladen
+monitor.desc = Beschrieven
+monitor.start = Begรผnn-Tied
+monitor.execute_time = Looptied
+monitor.last_execution_result = Resultaat
+monitor.process.cancel = Prozess ofbreken
+monitor.process.cancel_desc = Wenn een Prozess ofbroken word, kรถnen Daten verloren gahn
+monitor.process.cancel_notices = Ofbreken: %s ?
+monitor.process.children = Kinners
+monitor.queues = Slangen
+monitor.queue = Slang: %s
+monitor.queue.name = Naam
+monitor.queue.activeworkers = Aktiiv Rieters
+monitor.queue.maxnumberworkers = Hoogste Tahl vun Rieters
+monitor.queue.numberinqueue = Tahl in de Slang
+monitor.queue.review_add = Rieters nakieken / hentofรถgen
+monitor.queue.settings.title = Vรถrraad-Instellens
+monitor.queue.settings.maxnumberworkers = Hoogste Tahl vun Rieters
+monitor.queue.settings.maxnumberworkers.placeholder = Stedenwies %[1]d
+monitor.queue.settings.maxnumberworkers.error = Hoogste Tahl vun Rieters mutt eene Tahl wesen
+monitor.queue.settings.submit = Instellens vernejen
+monitor.queue.settings.changed = Instellens verneeit
+monitor.queue.settings.remove_all_items = All wegdoon
+notices.system_notice_list = Systeem-Narichtens
+notices.operations = Doon
+notices.select_all = All utkรถren
+notices.deselect_all = All nich utkรถren
+notices.inverse_selection = Utkรถren umdreihen
+notices.delete_selected = Utkรถรถrt wegdoon
+notices.delete_all = All Narichtens wegdoon
+notices.type = Aard
+notices.type_1 = Repositorium
+notices.type_2 = Upgaav
+notices.desc = Beschrieven
+notices.op = Up.
+monitor.queue.exemplar = Musteraard
+notices.view_detail_header = Naricht-Informatioonen
+self_check.no_problem_found = Noch keen Probleem funnen.
+self_check.database_collation_mismatch = Verwacht, dat de Datenbank deese Kollatioon bruukt: %s
+self_check.database_collation_case_insensitive = Datenbank bruukt eene Kollatioon %s, wat eene unklรผnige Kollatioon is. Forgejo kann twaar daarmit warken, aver dat kann rare Fallen geven, waar dat nich so warkt as verwacht.
+self_check.database_fix_mysql = Brukers vun MySQL of MariaDB kรถnen de Oorder ยปforgejo doctor convertยซ bruken, um de Kollatioons-Problemen oftohelpen, of du kannst dat Probleem ofhelpen, indeem du vun Hand de SQL-Oorders ยปALTER โฆ COLLATE โฆยซ bruukst.
+self_check.database_inconsistent_collation_columns = Datenbank bruukt Kollatioon %s, aver deese Striepen bruken unpassend Kollatioonen. Dat kann unverwachte Problemen maken.
+auths.sspi_auto_create_users_helper = Verlรถรถvt de SSPI-Anmellens-Aard, automatisk een Konto fรถr Brukers to maken, well sik tum eersten Maal anmellen
+config.log_file_root_path = Utgaav-Padd
+config.reset_password_code_lives = Ofloops-Dรผรผr vun de Torรผgghalens-Teken
+config.allow_dots_in_usernames = Brukers verlรถven, Punkten in hรถr Brukernamen to bruken. รnnert nix an bestahn Konten.
+monitor.queue.numberworkers = Tahl vun Rieters
+config.set_setting_failed = Instellen %s to setten fehlslagen
+monitor.execute_times = Utfรถhrens
+monitor.queue.settings.desc = Vรถrraden wassen as nรถdig, wenn hรถr Rieters-Slang blockeert.
+auths.tip.openid_connect = Bruuk de Utfรถrsken-URL fรถr OpenID-Verbinnen (/.well-known/openid-configuration), um de Ennpunkten antogeven
+auths.login_source_of_type_exist = Eenen Anmellens-Quell vun deeser Aard gifft dat al.
+config.mailer_protocol = Protokoll
+auths.tip.facebook = Vermark een nejes Programm up %s un fรถรถg dat Produkt ยปFacebook-Anmellenยซ hento
+config.custom_conf = Inricht-Dateipadd
+config.app_data_path = Programmdatenpadd
+config.service_config = Deenst-Inrichten
+config.enable_openid_signup = OpenID-Sรผlvst-Registreren anknipsen
+config.cache_test_slow = Tรผskenspieker-Test daankregen, aver de Antwoord is langsaam: %s.
+monitor.queue.type = Aard
+monitor.queue.settings.remove_all_items_done = All Dingen in de Slang sรผnd wegdaan worden.
+auths.tip.mastodon = Giff eene eegene Instanz-URL fรถr de Mastodon-Instanz, mit wat du anmellen willst, in (of bruuk de Normaalweert)
+notices.delete_success = De Systeem-Narichtens sรผnd wegdaan worden.
+auths.sspi_strip_domain_names = Domรครคn-Namen vun Brukernamen lรถsken
+auths.sspi_strip_domain_names_helper = Wenn dat anknipst is, worden Domรครคn-Namen automatisk vun Anmell-Namen lรถsket (toโn Bispรถรถl worden ยปDOMAIN\brukerยซ un ยปbruker@example.orgยซ beide blots ยปbrukerยซ).
+auths.sspi_default_language_helper = Normaal-Spraak fรถr Brukers, wat vun de SSPI-Anmellens-Aard automatisk maakt worden. Laat dat leeg, wenn du willst, dat de Spraak automatisk utkรถรถrt word.
+config.repo_root_path = Repositoriums-Ruut-Padd
+config.allow_only_internal_registration = Registreren blots dรถr Forgejo sรผlvst verlรถven
+config.allow_only_external_registration = Registreren blots dรถr frรถmde Deensten verlรถven
+config.ssh_keygen_path = Slรถtelmakens-Padd (ยปssh-keygenยซ)
+config.open_with_editor_app_help = De ยปMit โฆ opmakenยซ-Bewarkers im Kloon-Menรผ. Wenn du dat leeg lettst, word de Normaalweert bruukt. Verwieder, um de Normaalweert antokieken.
+auths.tip.yandex = Maak een nejes Programm up %s. Kรถรถr deese Verlรถรถvnissen ut de Deel ยปYandex.Passport APIยซ ut: ยปTogriep up E-Mail-Adressยซ, ยปTogriep up Bruker-Kontobillยซ un ยปTogriep up Brukernaam, Vรถrnaam un Achternaam, Geschlechtยซ
+monitor.duration = Dรผรผr (s)
+
+[action]
+rename_repo = hett een Repositorium vun %[1]s
na %[3]s umbenรถรถmt
+create_issue = `hett Gefall %[3]s #%[2]s opmaakt`
+close_issue = `hett Gefall %[3]s #%[2]s dichtmaakt`
+reopen_issue = `hett Gefall %[3]s #%[2]s weer opmaakt`
+create_pull_request = `hett Haalvรถrslag %[3]s #%[2]s opmaakt`
+reopen_pull_request = `hett Haalvรถrslag %[3]s #%[2]s weer opmaakt`
+comment_issue = `hett up Gefall %[3]s #%[2]s kommenteert`
+comment_pull = `hett up Haalvรถrslag %[3]s #%[2]s kommenteert`
+auto_merge_pull_request = `hett Haalvรถrslag %[3]s #%[2]s automatisk tosamenfรถhrt`
+transfer_repo = hett Repositorium %s
na %s รถverdragen
+delete_branch = hett Twieg %[2]s vun %[3]s lรถsket
+compare_branch = Verglieken
+compare_commits = %d Kommitterens verglieken
+compare_commits_general = Kommitterens verglieken
+mirror_sync_create = hett nejen Beteekner %[3]s na %[4]s spegelt
+approve_pull_request = `hett %[3]s#%[2]s tostimmt`
+reject_pull_request = `hett um รnnerns in %[3]s#%[2]s beden`
+review_dismissed = `hett dat Nakieken vun %[4]s fรถr %[3]s#%[2]s ofseggt`
+review_dismissed_reason = Grund:
+starred_repo = hett up %[2]s eenen Steern sett
+merge_pull_request = `hett Haalvรถrslag %[3]s #%[2]s tosamenfรถhrt`
+create_branch = hett Twieg %[3]s in %[4]s maakt
+delete_tag = hett Mark %[2]s vun %[3]s lรถsket
+push_tag = hett Mark %[3]s na %[4]s schuven
+publish_release = `hett %[4]s in %[3]s publik maakt`
+commit_repo = hett to %[3]s in %[4]s schuven
+close_pull_request = `hett Haalvรถrslag %[3]s #%[2]s dichtmaakt`
+create_repo = hett dat Repositorium %s maakt
+mirror_sync_push = hett Kommitterens na %[3]s in %[4]s spegelt
+mirror_sync_delete = hett Beteekner %[2]s
in %[3]s spegelt un lรถsket
+watched_repo = hett begunnen, %[2]s to beluren
+
+[tool]
+future = in Tokunft
+1s = 1 Sekรผnn
+1m = 1 Menรผรผt
+1d = 1 Dag
+1w = 1 Week
+1mon = 1 Maant
+1y = 1 Jahr
+seconds = %d Sekรผnnen
+hours = %d Stรผnnen
+days = %d Dagen
+weeks = %d Weken
+months = %d Maanten
+years = %d Jahren
+raw_seconds = Sekรผnnen
+raw_minutes = Menรผten
+minutes = %d Menรผten
+now = nu
+1h = 1 Stรผnn
+
+[munits.data]
+b = B
+kib = KiB
+mib = MiB
+gib = GiB
+tib = TiB
+pib = PiB
+eib = EiB
+
+[dropzone]
+default_message = Laat Dateien hier fallen of klick hier tum Upladen.
+invalid_input_type = Du kannst deese Aard vun Dateien nich upladen.
+file_too_big = Dateigrรถtt ({{filesize}} MB) is boven de hoogste Dateigrรถtt vun {{maxFilesize}} MB.
+remove_file = Datei wegdoon
+
+[notification]
+notifications = Narichtens
+unread = Nich lesen
+read = Lesen
+no_unread = Keene nejen Narichtens.
+no_read = Keene lesen Narichtens.
+pin = Naricht faststeken
+mark_as_read = As lesen markeren
+mark_as_unread = As nich lesen markeren
+mark_all_as_read = All as lesen markeren
+subscriptions = Abonneerens
+watching = Beluren
+no_subscriptions = Nix abonneert
+
+[gpg]
+default_key = Mit normaalem Slรถtel unnerschrieven
+error.extract_sign = Kunn Unnerschrift nich uttrecken
+error.generate_hash = Kunn Prรผfsumm vum Kommitteren nich bereken
+error.no_committer_account = Keen Konto mit de Kommitterer-E-Mail-Adress verbunnen
+error.no_gpg_keys_found = Keen bekannter Slรถtel fรถr deese Unnerschrift in de Datenbank funnen
+error.not_signed_commit = Kommitteren is nich unnerschrieven
+error.failed_retrieval_gpg_keys = Kunn keenen Slรถtel halen, wat mit de Konto vum Kommitterer verbunnen is
+error.probable_bad_signature = WAHRSCHAU! Ofschoonst een Slรถtel mit deeser ID in de Datenbank is, wiest dat deeses Kommitteren nich ut! Deeses Kommitteren is VERDรCHTIG.
+error.probable_bad_default_signature = WAHRSCHAU! Ofschoonst de normaal-Slรถtel deese ID hett, wiest dat deeses Kommitteren nich ut! Deeses Kommitteren is VERDรCHTIG.
+
+[install]
+install = Installeren
+title = Eerstinrichten
+docker_helper = Wenn du Forgejo in Docker utfรถhrst, lees bidde de Dokumenteren , ehr du eets Instellens รคnnerst.
+require_db_desc = Forgejo bruukt MySQL, PostgreSQL, SQLite3 of TiDB (MySQL-Protokoll).
+db_title = Datenbank-Instellens
+db_type = Datenbank-Aard
+host = Host
+user = Brukernaam
+password = Passwoord
+db_name = Datenbank-Naam
+db_schema = Schema
+db_schema_helper = Leeg laten, um de Normaalweert fรถr de Datenbank to bruken (ยปpublicยซ).
+path = Padd
+reinstall_error = Du versรถchst, in eene bestahn Forgejo-Datenbank to installeren
+reinstall_confirm_check_2 = De Repositoriums un Instellens mutten villicht verneeit worden. Indeem du deese Kist utkรถรถrst, stimmst du to, dat du de Hakens fรถr de Repositoriums un de authorized_keys-Datei vun Hand vernejen worst. Du wiest ut, dat du wiss maken worst, dat de Repositoriums- un Spegel-Instellens all recht sรผnd.
+err_empty_db_path = De SQLite3-Datenbank-Padd kann nich leeg wesen.
+no_admin_and_disable_registration = Du kannst Bruker-Sรผlvst-Registreren nich utknipsen, sรผnner eerst een Chef-Konto to maken.
+err_empty_admin_password = Dat Chef-Passwoord kann nich leeg wesen.
+err_empty_admin_email = De Chef-E-Mail-Adress kann nich leeg wesen.
+err_admin_name_is_reserved = Chef-Brukernaam is ungรผltig, Brukernaam is vรถrbehollen
+general_title = Allgemeene Instellens
+app_name = Instanz-Titel
+app_slogan = Instanz-Motto
+repo_path = Repositoriums-Ruut-Padd
+lfs_path = Git-LFS-Ruut-Padd
+lfs_path_helper = Dateien, wat vun Git LFS verfolgt worden, worden in deesem Verteeknis sekert. Leeg laten, um dat uttoknipsen.
+run_user = Bruker fรถr โt Utfรถhren
+domain = Server-Domรครคn
+domain_helper = Domรครคn of Hostadress fรถr de Server.
+ssh_port = SSH-Server-Poort
+http_port = HTTP-Tohรถren-Poort
+http_port_helper = Poort-Tahl, wat de Forgejo-Internett-Server bruken word.
+ssh_port_helper = Poort-Tahl, wat de SSH-Server bruken word. Leeg laten, um de SSH-Server uttoknipsen.
+log_root_path = Utgaav-Padd
+log_root_path_helper = Utgaav-Dateien worden in deeses Verteeknis schreven.
+email_title = E-Mail-Instellens
+smtp_addr = SMTP-Host
+smtp_port = SMTP-Poort
+smtp_from = E-Mail schicken as
+smtp_from_invalid = De ยปE-Mail schicken asยซ-Adress is ungรผltig
+smtp_from_helper = E-Mail-Adress, wat Forgejo bruken word. Giff eene slichte E-Mail-Adress in of bruuk dat Formaat ยป"Naam" ยซ.
+mailer_user = SMTP-Brukernaam
+mailer_password = SMTP-Passwoord
+register_confirm = E-Mail-Utwiesen biโm Registreren verlangen
+mail_notify = E-Mail-Narichtens anknipsen
+server_service_title = Instellens fรถr de Server un Frรถmdanbeder-Deensten
+offline_mode = Stedenwies-Modus anknipsen
+disable_gravatar = Gravatar utknipsen
+federated_avatar_lookup = Verdeelte Kontobillers anknipsen
+federated_avatar_lookup.description = Kontobillers รถver Libravatar sรถken.
+disable_registration = Sรผlvst-Registreren utknipsen
+disable_registration.description = Blots Instanz-Chefs kรถnen neje Brukerkonten maken. Dat word nรถdig anraden, dat Registreren uttoknipsen, wenn du nich vรถrhest, eene publike Instanz fรถr alle Lรผรผ to hosten un paraat bรผst, mit mennig Oolkert-Konten klaartoworden.
+allow_only_external_registration = Registreren blots รถver frรถmde Deenste verlรถven
+allow_only_external_registration.description = Brukers kรถnen neje Konten blots รถver inricht frรถmde Deensten maken.
+openid_signin.description = Brukers verlรถven, sik รถver OpenID antomellen.
+openid_signup.description = Brukers verlรถven, Konten รถver OpenID to maken, wenn Sรผlvst-Registreren anknipst is.
+enable_captcha = CAPTCHA biโm Registreren anknipsen
+require_sign_in_view = Anmellen verlangen, um Instanz-Inholl to wiesen
+default_keep_email_private = E-Mail-Adressen normaal verbargen
+default_keep_email_private.description = Dat Verbargen vun de E-Mail-Adress fรถr neje Brukers anknipsen, sodat deese Informatioon na de Registreren nich stracks dรถrsickert.
+default_enable_timetracking = Tied-Erfaten normaal anknipsen
+default_enable_timetracking.description = Nejen Repositoriums stracks verlรถven, Tied-Erfatens to bruken.
+admin_title = Chefkonto-Instellens
+admin_setting.description = Du mutts nich vun Nood een Chefkonto inrichten. De eerste registreert Bruker word automatisk een Chef.
+admin_name = Chef-Brukernaam
+admin_password = Passwoord
+confirm_password = Passwoord utwiesen
+install_btn_confirm = Forgejo installeren
+invalid_db_setting = De Datenbank-Instellens sรผnd ungรผltig: %v
+invalid_db_table = De Datenbank-Tabell ยป%sยซ is ungรผltig: %v
+invalid_repo_path = De Repositoriums-Ruut-Padd is ungรผltig: %v
+invalid_app_data_path = De Programm-Daten-Padd is ungรผltig: %v
+run_user_not_match = De ยปBruker fรถr โt Utfรถhrenยซ-Brukernaam is nich de stedenwies Brukernaam: %s โ %s
+internal_token_failed = Kunn binneres Teken nich maken: %v
+secret_key_failed = Kunn geheemen Slรถtel nich maken: %v
+err_admin_name_pattern_not_allowed = Chef-Brukernaam is ungรผltig, de Brukernaam passt up een vรถrbehollen Muster
+run_user_helper = De Bedrievssysteem-Brukernaam, as wat Forgejo lรถppt. Wees wiss, dat deeser Bruker Togriep to de Repositoriums-Ruut-Padd hebben mutt.
+optional_title = Nich nรถdige Instellens
+openid_signin = OpenID-Anmellen anknipsen
+openid_signup = OpenID-Sรผlvst-Registreren anknipsen
+save_config_failed = Kunn Inrichten nich sekern: %v
+enable_update_checker_helper_forgejo = Dat sรถcht alltied weer na nejen Forgejo-Versioonen, indeem een TXT-DNS-Upteken unner release.forgejo.org ankiekt word.
+app_slogan_helper = Giff hier dat Motto fรถr diene Instanz in. Leeg laten, um dat uttoknipsen.
+ssl_mode = SSL
+reinstall_confirm_message = Neei-installeren mit eener bestahn Forgejo-Datenbank kann mennig Problemen geven. Meesttiedens is dat beter, du bruukst diene bestahn ยปapp.iniยซ, um Forgejo uttofรถhren. Wenn du weetst, wat do doost, wies dat hier ut:
+sqlite_helper = Dateipadd fรถr de SQLite3-Datenbank. Giff eenen absoluuten Padd in, wenn du Forgejo as Deenst utfรถhrst.
+reinstall_confirm_check_1 = De Daten, wat vun de SECRET_KEY in app.ini verslรถtelt sรผnd, kรถnen verloren gahn: Brukes kรถnen sik villicht nich mehr mit 2FA/OTP anmellen un Spegels sรผn villicht kaputt. Wenn du deese Kist utkรถรถrst, stimmst du to, dat de stedenwies app.ini de rechten SECRET_KEY enthollt.
+repo_path_helper = Frรถmde Git-Repositoriums worden in deesem Verteeknis sekert.
+offline_mode.description = Frรถmdanbeder-Inholls-Levern-Nettwarken utknipsen un all Objekten stedenwies levern.
+require_sign_in_view.description = Blots anmellt Brukers verlรถven Togriep to eets Inhollen verlรถven. Gasten kรถnen nix as de Anmell-Sieden sehn.
+default_allow_create_organization = Normaal verlรถven, Vereenigungen to maken
+default_allow_create_organization.description = Nejen Brukers stracks verlรถven, Vereenigungen to maken. Wenn deese Instellen utknipst is, mutt een Chef nejen Brukers eerst dat Recht geven, Vereenigungen to maken.
+config_location_hint = Deese Inricht-Instellens worden sekert in:
+reinstall_confirm_check_3 = Du wiest ut, dat du heel un dall wiss bรผst, dat Forgejo mit de rechten app.ini-Stee lรถppt un dat du wiss bรผst, dat du wรผrrelk neei installeren muttst. Du wiest ut, dat du de Gefahren boven annimmst.
+err_admin_name_is_invalid = Chef-Brukernaam is ungรผltig
+app_name_helper = Giff hier dienen Instanz-Naam in. Dat word up elkeen Sied wiest.
+disable_gravatar.description = Gravatar un anner Frรถmdanbeder-Kontobill-Quellen utknipsen. Dat Normaalbill word fรถr Bruker-Kontobillers bruukt, wenn se nich hรถr eegen Kontobill to de Instanz upladen.
+test_git_failed = Kunn ยปgitยซ-Oorder nich testen: %v
+sqlite3_not_available = Deese Forgejo-Versioon unnerstรผtt SQLite3 nich. Bidde laad de offizielle Binรครคrversioon vun %s runner (nich de ยปgobuildยซ-Versioon).
+app_url = Grund-URL
+app_url_helper = Grund-Adress fรถr HTTP(S)-Kloon-URLs un E-Mail-Narichtens.
+enable_captcha.description = Verlangen, dat Brukers een CAPTCHA ofsluten, um Konten to maken.
+admin_email = E-Mail-Adress
+allow_dots_in_usernames = Brukers verlรถven, Punkten in hรถr Brukernamen to bruken. รnnert nix an bestahn Konten.
+no_reply_address = Verburgen E-Mail-Domรครคn
+no_reply_address_helper = Domรครคn-Naam fรถr Brukers mit eener verburgen E-Mail-Adrees. Toโn Bispรถรถl word de Brukernaam ยปfieteยซ in Git as ยปfiete@noreply.example.orgยซ vermarkt, wenn de verbargen E-Mail-Domรครคn as ยปnoreply.example.orgยซ sett is.
+invalid_admin_setting = Chefkonto-Instellen is ungรผltig: %v
+invalid_log_root_path = De Utgaav-Padd is ungรผltig: %v
+password_algorithm = Passwoord-Prรผfsumm-Funktioon
+enable_update_checker = Vernejens-Nakieker anknipsen
+env_config_keys = Umgevens-Inrichten
+env_config_keys_prompt = Deese Umgevens-Variaabeln worden ok up diene Instellens-Datei anwennt:
+password_algorithm_helper = Sett de Passwoord-Prรผfsumm-Funktioon. Funktioonen hebben verscheden Vรถrutsettens un Starkden. De argon2-Funktioon is bannig seker, aver se bruukt mennig Spieker un is fรถr lรผtte Systeemen villicht nich gadelk.
+invalid_password_algorithm = Ungรผltige Passwoord-Prรผfsumm-Funktioon
+
+[units]
+unit = Eenheid
+error.no_unit_allowed_repo = Du hest nich dat Recht, to elkeen Deel vun deesem Repositorium totogriepen.
+error.unit_not_allowed = Du hest nich dat Recht, up deese Deel vum Repositorium totogriepen.
+
+[packages]
+title = Paketen
+desc = Repositorium-Paketen verwalten.
+empty = Dat gifft noch keene Paketen.
+filter.type = Aard
+filter.type.all = All
+filter.container.tagged = Markt
+filter.container.untagged = Nich markt
+published_by = %[1]s vun %[3]s publizeert
+installation = Installeren
+about = รver deeses Paket
+requirements = Bruukt
+dependencies = Ofhangens
+keywords = Slรถtelwoorden
+details = Mehr Informatioonen
+details.author = Autor
+details.project_site = Projekt-Internett-Sied
+details.repository_site = Repositoriums-Internett-Sied
+details.documentation_site = Dokumenterens-Internett-Sied
+details.license = Lizenz
+assets = Objekten
+versions = Versioonen
+versions.view_all = All wiesen
+dependency.id = ID
+dependency.version = Versioon
+alpine.registry.info = Kรถรถr $branch un $repository ut de List unnern ut.
+alpine.repository = Repositoriums-Informatioon
+alpine.repository.branches = Twiegen
+alpine.repository.repositories = Repositoriums
+arch.version.properties = Versioon-Eegenskuppen
+arch.version.provides = Stellt paraat
+arch.version.groups = Grupp
+arch.version.depends = Hangt of vun
+arch.version.optdepends = Hangt nich nรถdig of vun
+arch.version.makedepends = Bau-Ofhangens
+arch.version.checkdepends = รverprรผfens-Ofhangens
+arch.version.conflicts = Unverdragelkheiden
+arch.version.replaces = Staht liek fรถr
+composer.dependencies = Ofhangens
+composer.dependencies.development = Entwicklens-Ofhangens
+conan.details.repository = Repositorium
+container.labels = Vermarkens
+container.labels.key = Slรถtel
+container.labels.value = Weert
+cran.install = Um dat Paket to installeren, fรถhr deese Oorder ut:
+debian.install = Um dat Paket to installeren, fรถhr deese Oorder ut:
+debian.repository = Repositoriums-Informatioon
+debian.repository.distributions = Verdeelens
+debian.repository.components = Delen
+debian.repository.architectures = Architekturen
+helm.install = Um dat Paket to installeren, fรถhr deese Oorder ut:
+npm.dependencies.development = Entwicklens-Ofhangens
+npm.dependencies.bundle = Mitbrocht Ofhangens
+npm.dependencies.peer = Maten-Ofhangens
+npm.dependencies.optional = Nich nรถdige Ofhangens
+npm.details.tag = Mark
+pypi.requires = Bruukt Python
+rpm.repository = Repositoriums-Informatioon
+rpm.repository.architectures = Architekturen
+rubygems.dependencies.runtime = Looptied-Ofhangens
+rubygems.dependencies.development = Entwicklens-Ofhangens
+rubygems.required.ruby = Bruukt Ruby-Versioon
+rubygems.required.rubygems = Bruukt RubyGem-Versioon
+swift.install2 = un fรถhr deese Oorder ut:
+settings.link.description = Wenn du een Paket mit eenem Repositorium verbinnst, word dat Paket in de Paketlist vum Repositorium wiest.
+settings.link.select = Repositorium utkรถren
+settings.link.error = Kunn de Repositoriums-Verwies nich vernejen.
+settings.delete = Paket lรถsken
+settings.delete.description = Een Paket to lรถsken is fรถr all Tieden un kann nich torรผggnohmen worden.
+settings.delete.success = Dat Paket is lรถsket worden.
+settings.delete.error = Kunn dat Paket nich lรถsken.
+owner.settings.cargo.initialize = Index inrichten
+owner.settings.cargo.initialize.error = Kunn Cargo-Index nich inrichten: %v
+owner.settings.cargo.initialize.success = De Cargo-Index is inricht worden.
+owner.settings.cargo.rebuild = Index neei bauen
+owner.settings.cargo.rebuild.error = Kunn Cargo-Index nich neei bauen: %v
+owner.settings.cargo.rebuild.success = De Cargo-Index is neei baut worden.
+owner.settings.cleanuprules.title = Schoonmakens-รrders
+owner.settings.cleanuprules.add = Schoonmakens-รrder hentofรถgen
+owner.settings.cleanuprules.edit = Schoonmakens-รrder bewarken
+owner.settings.cleanuprules.none = Dat gifft noch keene Schoonmakens-รrders.
+owner.settings.cleanuprules.preview = Schoonmakens-รrder-Utkiek
+owner.settings.cleanuprules.preview.none = Schoonmakens-รrder passt up keene Paketen.
+owner.settings.cleanuprules.enabled = Anknipst
+owner.settings.cleanuprules.pattern_full_match = Muster up de kumplete Paketnaam anwennen
+owner.settings.cleanuprules.keep.count = De neeiste behollen
+owner.settings.cleanuprules.keep.count.1 = 1 Versioon pro Paket
+owner.settings.cleanuprules.keep.count.n = %d Versioonen pro Paket
+owner.settings.cleanuprules.keep.pattern = Versioonen behollen, wat passen
+owner.settings.cleanuprules.remove.title = Versioonen, wat up deese รrders passen, worden lรถsket, wenn dat keene รrder boven gifft, wat seggt, dat se behollt worden mutten.
+owner.settings.cleanuprules.remove.days = Versioonen oller as dat lรถsken
+owner.settings.cleanuprules.remove.pattern = Versioonen lรถsken, wat passen
+owner.settings.cleanuprules.success.update = Schoonmakens-รrder is verneeit worden.
+filter.no_result = Dien Filter gifft keene Resultaten.
+alpine.repository.architectures = Architekturen
+settings.link.button = Repositoriums-Verwies vernejen
+alpine.install = Um dat Paket to installeren, fรถhr deese Oorder ut:
+arch.version.description = Beschrieven
+published_by_in = %[1]s vun %[3]s in %[5]s publizeert
+settings.link.success = Repositoriums-Verwies is verneeit worden.
+settings.delete.notice = Du willst %s (%s) lรถsken. Dat kann nich torรผggnohmen worden, willst du dat wรผrrelk?
+owner.settings.cleanuprules.preview.overview = %d Paketen sรผnd tum Lรถsken vรถrmarkt.
+owner.settings.cleanuprules.success.delete = Schoonmakens-รrder is wegdaan worden.
+owner.settings.cargo.rebuild.no_index = Kann nich neei bauen, keen Index is inricht.
+npm.dependencies = Ofhangens
+rpm.install = Um dat Paket to installeren, fรถhr deese Oorder ut:
+settings.link = Verbinn deeses Paket mit eenem Repositorium
+owner.settings.cleanuprules.keep.title = Versioonen, wat up deese รrders passen, worden behollt, ok wenn se up eene Lรถskens-รrder unnern passen.
+empty.documentation = Fรถr mehr Informatioonen รถver de Paketlist, kiek de Dokumenteren an.
+empty.repo = Hest du een Paket upladen, aver dat word hier nich wiest? Gah to de Paket-Instellens un verbinn dat mit deesem Repo.
+registry.documentation = Fรถr mehr Informatioonen รถver de %s-Paketlist, kiek de Dokumenteren an.
+alpine.registry = Richt deese Paketlist in, indeem du de URL in diene /etc/apk/repositories
-Datei infรถรถgst:
+alpine.registry.key = Laad de publiken RSA-Slรถtel vun de Paketlist in dat Verteeknis /etc/apk/keys/
runner, um de Index-Unnerschrift uttowiesen:
+arch.pacman.helper.gpg = Fรถรถg dat Vertroens-Zertifikaat fรถr Pacman hento:
+arch.pacman.repo.multi = %s hett in mennig Verdeelens de sรผlve Versioon.
+arch.pacman.repo.multi.item = Inrichten fรถr %s
+arch.pacman.conf = Fรถรถg de Server mit de verwandt Verdeelen un Architektuur to de /etc/pacman.conf
hento:
+arch.pacman.sync = Verneei dat Paket mit Pacman:
+arch.version.backup = Sekerheids-Kopie
+cargo.registry = Richt deese Paketlist in de Cargo-Instellens-Datei in (toโn Bispรถรถl ~/.cargo/config.toml
):
+cargo.install = Um dat Paket mit Cargo to installeren, fรถhr deese Oorder ut:
+chef.install = Um dat Paket to installeren, fรถhr deese Oorder ut:
+chef.registry = Richt deese Paketlist in diener ~/.chef/config.rb
-Datei in:
+composer.registry = Richt deese Paketlist in diener ~/.composer/config.json
-Datei in:
+conan.registry = Richt deese Paketlist vun de Oorderreeg in:
+conda.registry = Richt deese Paketlist as een Conda-Repositorium in diener ~/.condarc
-Datei in:
+composer.install = Um dat Paket mit Composer to installeren, fรถhr deese Oorder ut:
+conda.install = Um dat Paket mit Conda to installeren, fรถhr deese Oorder ut:
+container.details.type = Avbill-Aard
+container.details.platform = Plattfoorm
+container.pull = Haal deeses Avbill vun de Oorderreeg:
+container.digest = Prรผรผfsumm
+container.multi_arch = BS / Arch
+container.layers = Avbill-Schichten
+cran.registry = Richt deese Paketlist in diener Rprofile.site
-Datei in:
+debian.registry = Richt deese Paketlist vun de Oorderreeg in:
+debian.registry.info = Kรถรถr $distribution un $component ut de unnern List ut.
+generic.download = Laad deeses Paket vun de Oorderreeg runner:
+go.install = Installeer dat Paket vun de Oorderreeg:
+helm.registry = Richt deese Paketlist vun de Oorderreeg in:
+maven.registry = Richt deese Paketlist in diener pom.xml
-Datei in:
+maven.install2 = Vun de Oorderreeg utfรถhren:
+maven.download = Um de Ofhangen runnertoladen, fรถhr in de Oorderreeg ut:
+nuget.registry = Richt deese Paketlist vun de Oorderreeg in:
+nuget.install = Um dat Paket mit NuGet to installeren, fรถhr deese Oorder ut:
+nuget.dependency.framework = Enn-Rahmwark
+npm.registry = Richt deese Paketlist in de .npmrc
-Datei vun dienem Projekt in:
+maven.install = Um dat Paket to bruken, giff in de dependencies
-Deel vun de pom.xml
-Datei dat an:
+npm.install = Um dat Paket mit npm to installeren, fรถhr deese Oorder ut:
+npm.install2 = of fรถรถg dat to de ยปpackage.jsonยซ-Datei hento:
+pub.install = Um dat Paket mit Dart to installeren, fรถhr deese Oorder ut:
+pypi.install = Um dat Paket mit pip to installeren, fรถhr deese Oorder ut:
+rpm.registry = Richt deese Paketlist vun de Oorderreeg in:
+rpm.distros.redhat = Up Verdeelens mit RedHat as Grundlaag
+rpm.distros.suse = Up Verdeelens mit SUSE as Grundlaag
+rpm.repository.multiple_groups = Deeses Paket is in mennig Gruppen verfรถรถgbaar.
+rubygems.install = Um dat Paket mit gem to installeren, fรถhr deese Oorder ut:
+rubygems.install2 = of fรถรถg dat to de ยปGemfileยซ-Datei hento:
+swift.registry = Richt deese Paketlist vun de Oorderreeg in:
+swift.install = Fรถรถg dat Paket in diener Package.swift
-Datei hento:
+vagrant.install = Um eene Vagrant-Kist hentotofรถgen, fรถhr deese Oorder ut:
+owner.settings.cargo.title = Cargo-Paketlist-Index
+owner.settings.cargo.initialize.description = Een besรผnners Index-Git-Repositorium is nรถdig, um de Cargo-Paketlist to bruken. Deese Instellen word dat Repositorium (neei) maken un automatisk inrichten.
+owner.settings.cargo.rebuild.description = Neeibauen kann nรผttelk wesen, wenn de Index nich to de lagert Cargo-Paketen passt.
+owner.settings.cleanuprules.keep.pattern.container = De latest
-Versioon word fรถr Behรคlter-Paketen alltieden behollen.
+owner.settings.chef.title = Chef-Paketlist
+owner.settings.chef.keypair = Slรถtelpaar maken
+owner.settings.chef.keypair.description = Een Slรถtelpaar is nรถdig, um sik bi de Chef-Paketlist antomellen. Wenn du al een Slรถtelpaar maakt hest, word dat olle Slรถtelpaar wegdaan, wenn du een nejes Slรถtelpaar maakst.
+conan.install = Um dat Paket mit Conan to installeren, fรถhr deese Oorder ut:
+container.images.title = Avbillers
+search_in_external_registry = In %s sรถken
+alt.setup = Fรถรถg een Repositorium to de List vun verbunnen Repositoriums hento (kรถรถr de nรถdige Architektuur in Stee vun ยป_arch_ยซ ut):
+alt.registry.install = Um dat Paket to installeren, fรถhr deese Oorder ut:
+alt.repository.architectures = Architekturen
+alt.repository.multiple_groups = Deeses Paket is in mennig Gruppen verfรถรถgbaar.
+alt.registry = Richt deese Paketlist vun de Oorderreeg in:
+alt.install = Paket installeren
+alt.repository = Repositoriums-Informatioon
+
+[secrets]
+secrets = Geheemsten
+description = Geheemsten worden an wisse Aktioonen รถvergeven un kรถnen anners nich lesen worden.
+none = Dat gifft noch keene Geheemsten.
+creation = Geheemst hentofรถgen
+creation.success = Dat Geheemst ยป%sยซ is hentofรถรถgt worden.
+creation.failed = Kunn Geheemst nich hentofรถgen.
+deletion = Geheemst wegdoon
+deletion.success = Dat Geheemst is wegdaan worden.
+deletion.failed = Kunn Geheemst nich wegdoon.
+management = Geheemsten verwalten
+creation.value_placeholder = Giff elkeen Inholl in. Leegtekens am Begรผnn un Enn worden ofsneden.
+deletion.description = Een Geheemst wegtodoon is fรถr all Tieden un kann nich torรผggnohmen worden. Wiedermaken?
+creation.name_placeholder = Blots alphanumerisk Bookstavens (โt word nich tรผsken Groot- un Kleenbookstavens unnerscheden) un Unnerstrekens; kann nich mit GITEA_ of GITHUB_ begรผnnen
+
+[actions]
+actions = Aktioonen
+status.unknown = Unbekannt
+status.waiting = Wacht
+status.running = Lรถppt
+status.success = Daankregen
+status.failure = Fehlslagen
+status.cancelled = Ofbroken
+status.skipped = รversprungen
+runners = Lopers
+runners.runner_manage_panel = Lopers verwalten
+runners.new = Nejen Loper maken
+runners.new_notice = Wo man eenen Loper start
+runners.status = Tostand
+runners.id = ID
+runners.name = Naam
+runners.owner_type = Aard
+runners.description = Beschrieven
+runners.labels = Vermarkens
+runners.runner_title = Loper
+runners.task_list = Leste Upgaven up deesem Loper
+runners.task_list.no_tasks = Dat gifft noch keene Upgaav.
+runners.task_list.run = Utfรถhren
+runners.task_list.status = Tostand
+runners.task_list.repository = Repositorium
+runners.task_list.commit = Kommitteren
+runners.task_list.done_at = Daan um
+runners.edit_runner = Loper bewarken
+runners.update_runner_success = Loper verneeit
+runners.update_runner_failed = Kunn Loper nich vernejen
+runners.delete_runner = Deesen Loper wegdoon
+runners.delete_runner_success = Loper wegdaan
+runners.delete_runner_failed = Kunn Loper nich wegdoon
+runners.delete_runner_header = Wies ut, dat du deesen Loper wegdoon willst
+runners.none = Keene Lopers verfรถรถgbaar
+runners.status.unspecified = Unbekannt
+runners.status.idle = Nix to doon
+runners.status.active = Aktiiv
+runners.status.offline = Nich verbunnen
+runners.version = Versioon
+runners.reset_registration_token = Registrerens-Teken torรผggsetten
+runners.reset_registration_token_success = Loper-Registrerens-Teken torรผggsett
+runs.all_workflows = All Warkwiesen
+runs.commit = Kommitteren
+runs.scheduled = Na Tiedplaan
+runs.pushed_by = schuven vun
+runs.workflow = Warkwies
+runs.invalid_workflow_helper = Warkwies-Instellens-Datei is ungรผltig. Bidde kiek diene Instellens-Datei na: %s
+runs.no_matching_online_runner_helper = Keen verbunnen Loper, wat passt, mit de Vermark funnen: %s
+runs.no_job = De Warkwies mutt tominnst eene Upgaav enthollen
+runs.actor = Aktรถรถr
+runs.status = Tostand
+runs.actors_no_select = All Aktรถren
+runs.status_no_select = All Tostanden
+runs.no_results = Keene Resultaten passen.
+runs.no_workflows = Dat gifft noch keene Warkwiesens.
+runs.no_runs = Deese Warkwies is noch nich utfรถhrt worden.
+runs.empty_commit_message = (lege Kommitterens-Naricht)
+runs.expire_log_message = Utgaav is wegdaan worden, denn se weer to oll.
+workflow.enable = Warkwies anknipsen
+workflow.enable_success = Warkwies ยป%sยซ is anknipst worden.
+workflow.disabled = Warkwies is utknipst.
+workflow.dispatch.trigger_found = Deese Warkwies hett eenen workflow_dispatch -Vรถrfall-Utlรถรถser.
+workflow.dispatch.use_from = Warkwies bruken vun
+workflow.dispatch.run = Warkwies utfรถhren
+workflow.dispatch.input_required = Weert fรถr Ingaav ยป%sยซ nรถdig.
+workflow.dispatch.invalid_input_type = Ungรผltige Ingaav-Aard ยป%sยซ.
+workflow.dispatch.warn_input_limit = Blots de eersten %d Ingaven worden wiesen.
+need_approval_desc = Warkwiesen vun eenem Haalvรถrslag ut eener Gabel mutten eerst tostimmt worden.
+variables = Variaabeln
+variables.management = Variaabeln verwalten
+variables.none = Dat gifft noch keene Variaabeln.
+variables.deletion = Variaabel wegdoon
+variables.description = Variaabeln worden an wisse Aktioonen รถvergeven un kรถnen anners nich lesen worden.
+variables.id_not_exist = Variaabel mit ID %d gifft dat nich.
+variables.edit = Variaabel bewarken
+variables.deletion.failed = Kunn Variaabel nich wegdoon.
+variables.deletion.success = De Variaabel is wegdaan worden.
+variables.creation.failed = Kunn Variaabel nich hentofรถgen.
+variables.creation.success = De Variaabel ยป%sยซ is hentofรถรถgt worden.
+variables.update.success = De Variaabel is bewarkt worden.
+workflow.disable = Warkwies utknipsen
+variables.creation = Variaabel hentofรถgen
+variables.update.failed = Kunn Variaabel nich bewarken.
+status.blocked = Blockeert
+runners.delete_runner_notice = Wenn eene Upgaav up deesem Loper lรถppt, word se ofbroken un as fehlslagen markeert. Dat kann Bau-Warkwiesen stรถren.
+runners.last_online = Tolest verbunnen
+runners.update_runner = รnnerns vernejen
+workflow.disable_success = Warkwies ยป%sยซ is utknipst worden.
+runs.no_job_without_needs = De Warkwies mutt tominnst eene Upgaav sรผnner Ofhangen enthollen.
+workflow.dispatch.success = Warkwies-Utfรถhren is vรถrmarkt worden.
+variables.deletion.description = Eene Variaabel wegtodoon is fรถr all Tieden un kann nich torรผggnohmen worden. Wiedermaken?
+unit.desc = Verwalt integreerte CI-/CD-Affolgens mit Forgejo-Aktioonen.
+runs.no_workflows.quick_start = Weetst du nich, wo man mit Forgejo-Aktioonen begรผnnt? Kiek de fixe Infรถhren an.
+runs.no_workflows.documentation = Fรถr mehr Informatioonen รถver Forgejo-Aktioonen, kiek de Dokumenteren an.
+runs.no_workflows.help_write_access = Weetst du nich, wo man mit Forgejo-Aktioonen begรผnnen sall? Kiek de Fixanwies in de Bruker-Dokumenteren an, um diene eerste Warkwies to schrieven, un richt dann dienen eersten Forgejo-Loper in , um diene Upgavens uttofรถhren.
+runs.no_workflows.help_no_write_access = Um mehr รถver Forgejo-Aktioonen to lehren, kiek de Dokumenteren an.
+variables.not_found = Kunn de Variaabel nich finnen.
+
+[projects]
+deleted.display_name = Lรถsket Projekt
+type-1.display_name = Enkelt Projekt
+type-2.display_name = Repositoriums-Projekt
+type-3.display_name = Vereenigungs-Projekt
+
+[git.filemode]
+changed_filemode = %[1]s โ %[2]s
+directory = Verteeknis
+normal_file = Normaale Datei
+executable_file = Utfรถhrbaare Datei
+symbolic_link = Symbolisk Verwies
+submodule = Unnermoduul
+
+[markup]
+filepreview.lines = Riegen %[1]d bit %[2]d in %[3]s
+filepreview.truncated = Utkiek is ofsneden worden
+filepreview.line = Rieg %[1]d in %[2]s
+
+[translation_meta]
+test = Moin!
diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini
index 399e42de29..f68f738729 100644
--- a/options/locale/locale_nl-NL.ini
+++ b/options/locale/locale_nl-NL.ini
@@ -4,14 +4,14 @@ dashboard=Overzicht
explore=Verkennen
help=Help
logo=Logo
-sign_in=Inloggen
+sign_in=Aanmelden
sign_in_or=of
sign_out=Uitloggen
sign_up=Registreren
link_account=Account Koppelen
register=Registreren
version=Versie
-powered_by=Aangedreven door %s
+powered_by=Mogelijk gemaakt door %s
page=Pagina
template=Sjabloon
language=Taal
@@ -28,24 +28,24 @@ username=Gebruikersnaam
email=E-mailadres
password=Wachtwoord
access_token=Toegangstoken
-re_type=Verifieer wachtwoord
+re_type=Bevestig wachtwoord
captcha=CAPTCHA
twofa=Twee-factor authenticatie
twofa_scratch=Twee-factor krascode
-passcode=PIN
+passcode=Code
webauthn_insert_key=Voer uw beveiligingssleutel in
-webauthn_sign_in=Druk op de knop van uw beveiligingssleutel. Als uw beveiligingssleutel geen knop heeft, voeg deze dan opnieuw in.
+webauthn_sign_in=Druk op de knop van uw beveiligingssleutel. Als uw beveiligingssleutel geen knop heeft, voer deze dan opnieuw in.
webauthn_press_button=Druk alstublieft op de knop van uw beveiligingssleutelโฆ
webauthn_use_twofa=Gebruik een twee-factor code van uw telefoon
webauthn_error=Kon uw beveiligingssleutel niet lezen.
webauthn_unsupported_browser=Uw browser ondersteunt momenteel geen WebAuthn.
webauthn_error_unknown=Er is een onbekende fout opgetreden. Probeer het opnieuw.
-webauthn_error_insecure=WebAuthn ondersteunt alleen beveiligde verbindingen. Om te testen via HTTP, kan je de oorsprong "localhost" of "127.0.0.1" gebruiken
+webauthn_error_insecure=WebAuthn ondersteunt alleen beveiligde verbindingen. Om te testen via HTTP, kan je als systeemnaam "localhost" of "127.0.0.1" gebruiken
webauthn_error_unable_to_process=De server kon uw verzoek niet verwerken.
-webauthn_error_duplicated=De beveiligingssleutel is niet toegestaan voor dit verzoek. Zorg er alstublieft voor dat de sleutel niet al geregistreerd is.
+webauthn_error_duplicated=De beveiligingssleutel is voor dit verzoek niet toegestaan. Controleer alstublieft of de sleutel niet al is geregistreerd.
webauthn_error_empty=U moet een naam voor deze sleutel instellen.
-webauthn_error_timeout=Time-out bereikt voordat uw sleutel kon worden gelezen. Laad deze pagina opnieuw en probeer het opnieuw.
+webauthn_error_timeout=Time-out bereikt voordat uw sleutel kon worden gelezen. Herlaad deze pagina en probeer het opnieuw.
webauthn_reload=Vernieuwen
repository=Repository
@@ -56,9 +56,9 @@ new_migrate=Nieuwe migratie
new_mirror=Nieuwe mirror
new_fork=Nieuwe repository fork
new_org=Nieuwe organisatie
-new_project=Nieuwe project
+new_project=Nieuw project
manage_org=Beheer organisaties
-admin_panel=Website administratie
+admin_panel=Site beheer
account_settings=Accountinstellingen
settings=Instellingen
your_profile=Profiel
@@ -66,12 +66,12 @@ your_starred=Favoriet
your_settings=Instellingen
all=Alles
-sources=Bronnen
-mirrors=Spiegels
-collaborative=Samenwerkend
+sources=Broncode
+mirrors=Mirrors
+collaborative=Samenwerkende
forks=Forks
-activities=Activiteiten
+activities=Activiteit
pull_requests=Pull requests
issues=Issues
milestones=Mijlpalen
@@ -83,7 +83,7 @@ add=Toevoegen
add_all=Alles toevoegen
remove=Verwijder
remove_all=Alles verwijderen
-edit=Bewerk
+edit=Wijzig
enabled=Ingeschakeld
disabled=Uitgeschakeld
@@ -99,7 +99,7 @@ preview=Voorbeeld
loading=Ladenโฆ
error=Fout
-error404=De pagina die u probeert te bereiken bestaat niet of u bent niet gemachtigd om het te bekijken.
+error404=De pagina die u probeert te bereiken bestaat niet , is verwijderd of u bent niet bevoegd om deze te bekijken.
never=Nooit
@@ -115,8 +115,8 @@ concept_user_organization=Organisatie
name=Naam
-sign_in_with_provider = Log in met %s
-tracked_time_summary = Overzicht van geregistreerde tijd op basis van filters van probleemlijst
+sign_in_with_provider = Aanmelden met %s
+tracked_time_summary = Overzicht van geregistreerde tijd op basis van filters van issuelijst
enable_javascript = Deze website vereist JavaScript.
retry = Probeer opnieuw
rerun_all = Alle taken opnieuw uitvoeren
@@ -140,9 +140,9 @@ confirm_delete_selected = Bevestigen om alle geselecteerde items te verwijderen?
copy_type_unsupported = Dit bestandstype kan niet worden gekopieerd
pin = Vastpinnen
unpin = Ontpinnen
-remove_label_str = Verwijder punt "%s"
+remove_label_str = Verwijder item "%s"
confirm_delete_artifact = Weet u zeker dat u het artefact "%s" wilt verwijderen?
-toggle_menu = Menu schakelen
+toggle_menu = Menu aan/uit
filter.clear = Filter wissen
filter.is_archived = Gearchiveerd
filter.is_fork = Forks
@@ -158,6 +158,15 @@ filter.not_archived = Niet gearchiveerd
more_items = Meer items
invalid_data = Ongeldige data: %v
copy_generic = Kopieer naar klembord
+test = Test
+error413 = U heeft uw hele quotum gebruikt.
+new_migrate.title = Nieuwe migratie
+new_org.title = Nieuwe organisatie
+new_repo.link = Nieuwe repository
+new_repo.title = Nieuwe repository
+new_migrate.link = Nieuwe migratie
+new_org.link = Nieuwe organisatie
+copy_path = Kopieer bestandspad
[aria]
navbar = Navigatiebalk
@@ -189,6 +198,18 @@ buttons.enable_monospace_font = Lettertype monospace inschakelen
buttons.italic.tooltip = Schuingedrukte tekst toevoegen
buttons.list.task.tooltip = Een lijst met taken toevoegen
buttons.disable_monospace_font = Lettertype monospace uitschakelen
+buttons.indent.tooltip = Items รฉรฉn niveau lager plaatsen
+buttons.unindent.tooltip = Items รฉรฉn niveau hoger plaatsen
+buttons.new_table.tooltip = Tabel toevoegen
+table_modal.header = Tabel toevoegen
+table_modal.placeholder.header = Kop
+table_modal.placeholder.content = Inhoud
+table_modal.label.rows = Rijen
+table_modal.label.columns = Kolommen
+link_modal.header = Link toevoegen
+link_modal.url = Url
+link_modal.description = Beschrijving
+link_modal.paste_reminder = Tip: Als u een URL op uw klembord heeft, kun u deze direct in de editor plakken om een koppeling te maken.
[filter]
string.asc = A - Z
@@ -200,24 +221,24 @@ missing_csrf=Foutief verzoek: geen CSRF-token aanwezig
invalid_csrf=Verkeerd verzoek: ongeldig CSRF-token
not_found=Het doel kon niet worden gevonden.
network_error=Netwerk fout
-report_message = Als je denkt dat dit een bug is in Forgejo, zoek dan naar issues op Codeberg of open een nieuwe issue als dat nodig is.
+report_message = Als je denkt dat dit een bug is in Forgejo, zoek dan naar issues op Codeberg of open een nieuwe issue als dat nodig is.
server_internal = Interne serverfout
[startpage]
app_desc=Een eenvoudige, self-hosted Git service
install=Makkelijk te installeren
platform=Cross-platform
-platform_desc=Forgejo werkt op alles waar Go op kan compileren: Windows, macOS, Linux, ARM, etc. Kies het platform dat bij je past!
+platform_desc=Forgejo draait op libre-besturingssystemen zoals Linux en FreeBSD en op verschillende CPU-architecturen. Kies degene waar u van houdt!
lightweight=Lichtgewicht
lightweight_desc=Forgejo heeft hele lage systeemeisen, je kunt Forgejo al draaien op een goedkope Raspberry Pi!
license=Open Source
-license_desc=Alles staat op Forgejo ! Help ons door mee te bouwen aan Forgejo , samen maken we dit project nog beter. Aarzel dus niet om een bijdrage te leveren!
-install_desc = Draai gewoon de binary voor je platform, verscheep het met Docker of laat het packagen .
+license_desc=Alles staat op Forgejo ! Help ons door mee te bouwen aan Forgejo , samen maken we dit project nog beter. Aarzel dus niet om een bijdrage te leveren!
+install_desc = Draai gewoon de binary voor je platform, verscheep het met Docker of laat het packagen .
[install]
install=Installatie
title=Initiรซle configuratie
-docker_helper=Als je gitea draait in Docker, Lees eerst de documentatie voordat je een instelling aanpast.
+docker_helper=Als je Forgejo draait in Docker, Lees eerst de documentatie voordat je een instelling aanpast.
require_db_desc=Forgejo vereist MySQL, PostgreSQL, SQLite3 of TiDB (MySQL protocol).
db_title=Database-instellingen
db_type=Database-type
@@ -232,7 +253,7 @@ path=Pad
sqlite_helper=Bestandspad voor de SQLite3-database. Vul een volledig pad in als je Forgejo als een service uitvoert.
reinstall_error=U probeert te installeren in een bestaande Forgejo database
reinstall_confirm_message=Herinstalleren met een bestaande Forgejo-database kan meerdere problemen veroorzaken. In de meeste gevallen kun je het bestaande "app.ini" gebruiken om Forgejo te laten draaien. Als je weet wat je aan het doen bent, bevestig dan het volgende:
-reinstall_confirm_check_1=De gegevens versleuteld door de SECRET_KEY in de app.ini kan verloren gaan: gebruikers kunnen mogelijk niet meer inloggen met 2FA/OTP & spiegels werken mogelijk niet meer. Door dit vakje aan te vinken bevestigt u dat het huidige app.ini bestand de juiste SECRET_KEY bevat.
+reinstall_confirm_check_1=De gegevens versleuteld door de SECRET_KEY in de app.ini kan verloren gaan: gebruikers kunnen mogelijk niet meer inloggen met 2FA/OTP & mirrors werken mogelijk niet meer. Door dit vakje aan te vinken bevestigt u dat het huidige app.ini bestand de juiste SECRET_KEY bevat.
reinstall_confirm_check_2=De repositories en instellingen moeten mogelijk opnieuw worden gesynchroniseerd. Door dit vakje aan te vinken, bevestigt u dat u de hooks voor de repositories en authorized_keys bestand handmatig zult hersynchroniseren. U bevestigt dat u ervoor zult zorgen dat de instellingen van de repository en mirror correct zijn.
reinstall_confirm_check_3=Je bevestigt dat je er absoluut zeker van bent dat deze Forgejo draait met de juiste app. Geen locatie en dat je zeker weet dat je opnieuw moet installeren. Je bevestigt dat je de hierbovenstaande risico's erkent.
err_empty_db_path=SQLite3 database pad mag niet leeg zijn.
@@ -240,7 +261,7 @@ no_admin_and_disable_registration=U kunt zelf-registratie van de gebruiker niet
err_empty_admin_password=Het administrator-wachtwoord mag niet leeg zijn.
err_empty_admin_email=Het e-mailadres van Het beheerder mag niet leeg zijn.
err_admin_name_is_reserved=Gebruikersnaam van beheerder is ongeldig, gebruikersnaam is gereserveerd
-err_admin_name_pattern_not_allowed=Gebruikersnaam van beheerder is ongeldig, de gebruikersnaam is gereserveerd
+err_admin_name_pattern_not_allowed=Gebruikersnaam van beheerder is ongeldig, de gebruikersnaam komt overeen met een gereserveerd patroon
err_admin_name_is_invalid=Gebruikersnaam van beheerder is ongeldig
general_title=Algemene instellingen
@@ -259,7 +280,7 @@ http_port=HTTP luisterpoort
http_port_helper=Poortnummer dat zal worden gebruikt door de Forgejo webserver.
app_url=Basis URL
app_url_helper=Basisadres voor HTTP(S) kloon URL's en e-mailmeldingen.
-log_root_path=Log-pad
+log_root_path=Logboek-pad
log_root_path_helper=Logboekbestanden worden geschreven naar deze map.
optional_title=Optionele instellingen
@@ -274,20 +295,20 @@ register_confirm=E-mailbevestiging vereist bij registreren
mail_notify=Activeer e-mailnotificaties
server_service_title=Server en service-instellingen van derden
offline_mode=Lokale modus inschakelen
-offline_mode.description=Schakel third-party content uit en gebruik alleen lokale middelen.
+offline_mode.description=Schakel content delivery netwerken van derden uit en serveer alle middelen lokaal.
disable_gravatar=Gravatar uitschakelen
disable_gravatar.description=Gravatar en derden avatar bronnen uitschakelen. Een standaard avatar zal worden gebruikt, tenzij een gebruiker hun eigen avatar uploadt naar de instantie.
federated_avatar_lookup=Federated avatars toestaan
federated_avatar_lookup.description=Zoek avatars op met Libravatar.
disable_registration=Schakel zelf registratie uit
-disable_registration.description=Schakel zelfregistratie uit, alleen admins kunnen accounts maken.
-allow_only_external_registration.description=Registratie alleen via externe diensten toestaan
+disable_registration.description=Alleen instantiebeheerders kunnen nieuwe gebruikersaccounts aanmaken. Het wordt sterk aangeraden om registratie uitgeschakeld te houden, tenzij je van plan bent om een publieke instantie voor iedereen te hosten en klaar bent om grote hoeveelheden spam-accounts te verwerken.
+allow_only_external_registration.description=Gebruikers kunnen alleen nieuwe accounts aanmaken via geconfigureerde externe services.
openid_signin=OpenID-inloggen inschakelen
-openid_signin.description=Gebruikerslogin via OpenID inschakelen.
+openid_signin.description=Laat gebruikers zich aanmelden via OpenID.
openid_signup=OpenID zelf-registratie inschakelen
-openid_signup.description=OpenID zelfregistratie inschakelen.
+openid_signup.description=Sta gebruikers toe om accounts aan te maken via OpenID als zelfregistratie is ingeschakeld.
enable_captcha=Registratie CAPTCHA inschakelen
-enable_captcha.description=Vereis captcha validatie voor zelf-registratie van gebruiker.
+enable_captcha.description=Gebruikers verplichten om CAPTCHA te passeren om accounts aan te maken.
require_sign_in_view=Aanmelden vereist om inhoud van instantie te bekijken
admin_setting.description=Het creรซren van een administrator-account is optioneel. De eerste geregistreerde gebruiker wordt automatisch de beheerder.
admin_title=Instellingen beheerdersaccount
@@ -308,11 +329,11 @@ save_config_failed=Kan de configuratie niet opslaan: %v
invalid_admin_setting=Instelling van de administrator-account is ongeldig: %v
invalid_log_root_path=Ongeldig log-pad: %v
default_keep_email_private=Verberg standaard alle e-mailadressen
-default_keep_email_private.description=Verberg standaard de email-adressen van nieuwe gebruikers.
+default_keep_email_private.description=Schakel het verbergen van e-mailadressen standaard in voor nieuwe gebruikers, zodat deze informatie niet meteen na het aanmelden uitlekt.
default_allow_create_organization=Standaard toestaan om organisaties aan te maken
-default_allow_create_organization.description=Standaard toestaan dat nieuwe gebruikers organisaties kunnen aanmaken.
+default_allow_create_organization.description=Sta nieuwe gebruikers standaard toe om organisaties aan te maken. Als deze optie is uitgeschakeld, moet een beheerder nieuwe gebruikers toestemming geven om organisaties aan te maken.
default_enable_timetracking=Tijdregistratie standaard inschakelen
-default_enable_timetracking.description=Tijdsregistratie voor nieuwe repositories standaard inschakelen.
+default_enable_timetracking.description=Sta het gebruik van de tijd-tracking functie voor nieuwe repositories standaard toe.
no_reply_address=Verborgen e-maildomein
no_reply_address_helper=Domeinnaam voor gebruikers met een verborgen e-mailadres. Bijvoorbeeld zal de gebruikersnaam "joe" in Git worden geregistreerd als "joe@noreply.example.org" als het verborgen email domein is ingesteld op "noreply.example.org".
password_algorithm=Wachtwoord hash-algoritme
@@ -324,7 +345,7 @@ enable_update_checker = Updatecontrole inschakelen
invalid_password_algorithm = Ongeldig wachtwoord hash-algoritme
password_algorithm_helper = Stel het hashing-algoritme voor wachtwoorden in. De algoritmes hebben verschillende vereisten en sterkte. Het argon2-algoritme is tamelijk veilig, maar gebruikt veel geheugen en kan ongeschikt zijn voor kleine systemen.
run_user_helper = De gebruikersnaam van het besturingssysteem waaronder Forgejo draait. Merk op dat deze gebruiker toegang moet hebben tot de hoofdmap van de repository.
-require_sign_in_view.description = Beperk de toegang tot de pagina's tot ingelogde gebruikers. Bezoekers zien alleen de aanmeldings- en registratiepagina's.
+require_sign_in_view.description = Beperk de inhoudstoegang tot aangemelde gebruikers. Bezoekers kunnen alleen de verificatiepagina's bezoeken.
enable_update_checker_helper_forgejo = Het zal periodiek controleren op nieuwe Forgejo-versies door een TXT DNS-record op release.forgejo.org te controleren.
smtp_from_invalid = Het adres "E-mails versturen als" is ongeldig
config_location_hint = Deze configuratieopties worden opgeslagen in:
@@ -396,18 +417,18 @@ remember_me=Onthoud dit apparaat
forgot_password_title=Wachtwoord vergeten
forgot_password=Wachtwoord vergeten?
sign_up_now=Een account nodig? Meld u nu aan.
-confirmation_mail_sent_prompt=Een nieuwe bevestigingsmail is gestuurd naar %s . De mail moet binnen %s worden bevestigd om je registratie te voltooien.
+confirmation_mail_sent_prompt=Er is een nieuwe bevestigingsmail verzonden naar %s . Om het registratieproces te voltooien, controleert u uw inbox en volgt u de verstrekte link binnen de komende %s. Als de e-mail niet correct is, kunt u inloggen en verzoeken om een nieuwe bevestigingsmail naar een ander adres te sturen.
must_change_password=Uw wachtwoord wijzigen
allow_password_change=Verplicht de gebruiker om zijn/haar wachtwoord te wijzigen (aanbevolen)
-reset_password_mail_sent_prompt=Een bevestigingsmail is verstuurd naar %s . Controleer uw inbox in de volgende %s om het herstel van uw account te voltooien.
+reset_password_mail_sent_prompt=Er is een bevestigingsmail verzonden naar %s . Om het accountherstelproces te voltooien, controleert u uw inbox en volgt u de meegeleverde link binnen de komende %s.
active_your_account=Activeer uw account
account_activated=Account is geactiveerd
-prohibit_login=Inloggen niet toegestaan
+prohibit_login=Account is geschorst
resent_limit_prompt=Sorry, je hebt te snel na elkaar een aanvraag gedaan voor een activatiemail. Wacht drie minuten voor je volgende aanvraag.
has_unconfirmed_mail=Beste %s, u heeft een onbevestigd e-mailadres (%s ). Als u nog geen bevestiging heeft ontvangen, of u een nieuwe aanvraag wilt doen, klik dan op de onderstaande knop.
resend_mail=Klik hier om uw activatie mail nog een keer te verzenden
email_not_associate=Dit emailadres is niet gekoppeld aan een account.
-send_reset_mail=Stuur account herstel e-mail
+send_reset_mail=Verzend e-mail voor herstel
reset_password=Account herstel
invalid_code=Uw bevestigingscode is ongeldig of is verlopen.
reset_password_helper=Account herstellen
@@ -446,7 +467,7 @@ authorize_title=Autoriseer "%s" voor toegang tot uw account?
authorization_failed=Autorisatie mislukt
sspi_auth_failed=SSPI-authenticatie mislukt
password_pwned_err=Kan het verzoek om HaveIBeenPwned niet voltooien
-prohibit_login_desc = Het is verboden om aan te melden met dit account. Neem contact op met de beheerder van je site.
+prohibit_login_desc = Uw account is geschorst voor interactie met de instantie. Neem contact op met de beheerder van de instantie om weer toegang te krijgen.
change_unconfirmed_email_error = Kan het e-mailadres niet wijzigen: %v
sign_up_successful = Account succesvol aangemaakt. Welkom!
change_unconfirmed_email = Als je tijdens de registratie een verkeerd e-mailadres hebt opgegeven, kun je dit hieronder wijzigen. Er wordt dan een bevestiging naar het nieuwe e-mailadres gestuurd.
@@ -454,13 +475,20 @@ change_unconfirmed_email_summary = Wijzig het e-mailadres waar de activeringsmai
invalid_password = Uw wachtwoord komt niet overeen met het wachtwoord dat is gebruikt bij het aanmaken van de account.
reset_password_wrong_user = U bent aangemeld als %s, maar de link voor accountherstel is bedoeld voor %s
invalid_code_forgot_password = Jouw confirmatiecode is ongeldig of is verlopen. Klik hier om een nieuwe sessie te starten.
-password_pwned = Het wachtwoord dat je hebt gekozen staat op een lijst met gestolen wachtwoorden die eerder zijn vrijgegeven in openbare datalekken. Probeer het opnieuw met een ander wachtwoord en overweeg ook om dit wachtwoord elders te wijzigen.
+password_pwned = Het wachtwoord dat je hebt gekozen staat op een lijst met gestolen wachtwoorden die eerder zijn vrijgegeven in openbare datalekken. Probeer het opnieuw met een ander wachtwoord en overweeg ook om dit wachtwoord elders te wijzigen.
last_admin = Je kunt de laatste beheerder niet verwijderen. Er moet minstens รฉรฉn beheerder zijn.
openid_signin_desc = Voer uw OpenID URI in. Bijvoorbeeld: alice.openid.example.org of https://openid.example.org/alice.
authorization_failed_desc = De autorisatie is mislukt omdat we een ongeldig verzoek hebben gedetecteerd. Neem contact op met de beheerder van de app die u probeerde te autoriseren.
remember_me.compromised = De login-sleutel is niet meer geldig, dit kan wijzen op een gecompromitteerd account. Controleer uw account voor verdachte activiteiten.
tab_signin = Inloggen
tab_signup = Aanmelden
+hint_login = Heb je al een account? Nu aanmelden!
+hint_register = Heb je een account nodig? Registreer nu.
+sign_up_button = Registreer nu.
+back_to_sign_in = Terug naar aanmelden
+sign_in_openid = Ga verder met OpenID
+unauthorized_credentials = Je inloggegevens zijn foutief of vervallen. Probeer opnieuw of zie %s voor meer informatie
+use_onetime_code = Gebruik een eenmalige code
[mail]
view_it_on=Bekijk het op %s
@@ -475,7 +503,7 @@ activate_account.text_2=Klik op de volgende link om uw account te activeren binn
activate_email=Verifieer uw e-mailadres
activate_email.text=Klik op de volgende link om je e-mailadres te bevestigen in %s :
-register_notify=Welkom bij Forgejo
+register_notify=Welkom bij %s
register_notify.title=%[1]s, welkom bij %[2]s
register_notify.text_1=dit is uw registratie bevestigingsemail voor %s!
register_notify.text_2=U kunt zich aanmelden bij uw account met uw gebruikersnaam: %s
@@ -529,6 +557,22 @@ team_invite.text_3 = Merk op: Deze uitnodiging was bestemd voor %[1]s. Als u dez
team_invite.text_1 = %[1]s heeft u een uitnodiging gestuurd om aan het team %[2]s in de organisatie %[3]s deel te nemen.
team_invite.text_2 = Klik alstublieft op de volgende link om aan het team deel te nemen:
admin.new_user.text = Klik hier om deze gebruiker te beheren vanuit het beheerderspaneel.
+password_change.subject = Uw wachtwoord is gewijzigd
+password_change.text_1 = Het wachtwoord voor je account is zojuist gewijzigd.
+reset_password.text_1 =
+totp_disabled.subject = TOTP is uitgeschakeld
+primary_mail_change.subject = Uw primaire e-mail is gewijzigd
+totp_disabled.no_2fa = Er zijn geen andere 2FA methodes meer geconfigureerd, wat betekent dat het niet langer nodig is om in te loggen op uw account met 2FA.
+removed_security_key.no_2fa = Er zijn geen andere 2FA methodes meer geconfigureerd, wat betekent dat het niet langer nodig is om in te loggen op uw account met 2FA.
+account_security_caution.text_1 = Als u dit was, dan kun u deze mail gerust negeren.
+totp_disabled.text_1 = Tijdgebaseerd eenmalig wachtwoord (TOTP) op uw account is zojuist uitgeschakeld.
+primary_mail_change.text_1 = Het primaire e-mailadres van uw account is zojuist gewijzigd in %[1]s. Dit betekent dat dit e-mailadres niet langer e-mailmeldingen voor uw account zal ontvangen.
+removed_security_key.subject = Een beveiligingssleutel is verwijderd
+removed_security_key.text_1 = Beveiligingssleutel โ%[1]sโ is zojuist verwijderd van uw account.
+account_security_caution.text_2 = Als u dit niet was, is uw account gecompromitteerd. Neem contact op met de beheerders van deze site.
+totp_enrolled.text_1.no_webauthn = U heeft zojuist TOTP ingeschakeld voor uw account. Dit betekent dat u voor alle toekomstige aanmeldingen op uw account TOTP moet gebruiken als 2FA-methode.
+totp_enrolled.subject = U heeft TOTP geactiveerd als 2FA methode
+totp_enrolled.text_1.has_webauthn = U heeft zojuist TOTP ingeschakeld voor uw account. Dit betekent dat je voor alle toekomstige aanmeldingen op uw account TOTP kunt gebruiken als 2FA-methode of een van uw beveiligingssleutels kunt gebruiken.
[modal]
@@ -627,7 +671,7 @@ unable_verify_ssh_key = Kan de SSH-sleutel niet verifiรซren, controleer deze voo
still_own_repo = Uw account is eigenaar van รฉรฉn of meer repositories, verwijder of draag deze eerst over.
admin_cannot_delete_self = U kan uzelf niet verwijderen als u een beheerder bent. Verwijder eerst uw beheerdersrechten.
username_error_no_dots = ` kan alleen alfanumerieke karakters ("0-9","a-z","A-Z"), streepje ("-") en liggend streepje ("_") bevatten. Niet-alfanumerieke karakters aan het begin of eind zijn verboden en aaneenvolgende niet alfanumerieke karakters zijn ook verboden.`
-invalid_group_team_map_error = ` mapping is ongeldig: %s"
+invalid_group_team_map_error = ` mapping is ongeldig: %s`
org_still_own_repo = Deze organisatie is eigenaar van รฉรฉn of meer repositories, verwijder of draag deze eerst over.
org_still_own_packages = Deze organisatie is eigenaar van รฉรฉn of meer pakketten, verwijder deze eerst.
unset_password = De inloggebruiker heeft het wachtwoord niet ingesteld.
@@ -641,6 +685,8 @@ To = Branch naam
Website = Website
AccessToken = Toegangstoken
Pronouns = Voornaamwoorden
+username_claiming_cooldown = De gebruikersnaam kan niet opgeรซist worden, omdat de afkoelperiode nog niet voorbij is. Hij kan worden opgeรซist op %[1]s.
+email_domain_is_not_allowed = Het domein van het e-mailadres van de gebruiker %s is in strijd met EMAIL_DOMAIN_ALLOWLIST of EMAIL_DOMAIN_BLOCKLIST. Controleer of u het e-mailadres correct hebt ingesteld.
[user]
@@ -659,10 +705,10 @@ user_bio=Biografie
disabled_public_activity=Deze gebruiker heeft de publieke zichtbaarheid van de activiteit uitgeschakeld.
block_user = Blokkeer gebruiker
joined_on = Geregistreerd op %s
-block_user.detail_1 = Deze gebruiker zal u ontvolgen.
-block_user.detail = Begrijp alsjeblieft dat als u deze gebruiker blokkeert, er andere acties worden genomen. Zoals:
-block_user.detail_2 = Deze gebruiker kan geen interactie hebben met repositories, gecreรซerde issues en reacties.
-block_user.detail_3 = Deze gebruiker kunt u niet toevoegen als samenwerker, noch kunt u hen toevoegen als samenwerker.
+block_user.detail_1 = Jullie zullen elkaar niet meer volgen en zullen elkaar niet meer kunnen volgen.
+block_user.detail = Merk op dat het blokkeren van een gebruiker andere effecten heeft, zoals:
+block_user.detail_2 = Deze gebruiker kan geen interactie hebben met de repositories waarvan jij de eigenaar bent, of met de issues en berichten die je hebt aangemaakt.
+block_user.detail_3 = Je zult elkaar niet kunnen toevoegen als samenwerker.
follow_blocked_user = U kunt deze gebruiker niet volgen, omdat u hen geblokkeerd heeft en of deze gebruiker heeft u geblokkeerd.
block = Blokkeren
unblock = Deblokkeren
@@ -680,6 +726,11 @@ followers.title.few = Volgers
following.title.one = Volgend
following.title.few = Volgend
followers.title.one = Volger
+public_activity.visibility_hint.self_public = Uw activiteiten zijn zichtbaar voor iedereen, behalve voor interacties in privรฉruimtes. Configureer .
+public_activity.visibility_hint.admin_public = Deze activiteit is zichtbaar voor iedereen, maar als beheerder kun je ook interacties in privรฉruimtes zien.
+public_activity.visibility_hint.self_private = Uw activiteiten zijn alleen zichtbaar voor jou en de beheerders van de instantie. Configureer .
+public_activity.visibility_hint.admin_private = Deze activiteit is zichtbaar voor u omdat u een beheerder bent, maar de gebruiker wil dat het privรฉ blijft.
+public_activity.visibility_hint.self_private_profile = Uw activiteit is alleen zichtbaar voor u en de beheerders van de instantie omdat uw profiel privรฉ is. Aanpassen .
[settings]
@@ -692,11 +743,11 @@ avatar=Profielfoto
ssh_gpg_keys=SSH / GPG sleutels
social=Sociale netwerk-accounts
applications=Applicaties
-orgs=Beheer organisaties
+orgs=Organisaties
repos=Repositories
delete=Verwijder account
twofa=Twee-factor authenticatie (TOTP)
-account_link=Gekoppelde Accounts
+account_link=Gekoppelde accounts
organization=Organisaties
webauthn=Twee-factor authenticatie (Beveiligingssleutels)
@@ -748,14 +799,14 @@ update_password=Wachtwoord bijwerken
old_password=Huidige wachtwoord
new_password=Nieuw wachtwoord
password_incorrect=Het wachtwoord is niet correct.
-change_password_success=Je wachtwoord is bijgewerkt. Log vanaf nu in met je nieuwe wachtwoord.
+change_password_success=Uw wachtwoord is bijgewerkt. Log vanaf nu in met uw nieuwe wachtwoord.
password_change_disabled=Niet-lokale gebruikers kunnen hun wachtwoord niet in de webinterface van Forgejo wijzigen.
emails=E-mailadressen
manage_emails=E-mailadressen beheren
-manage_themes=Selecteer standaardthema
-manage_openid=Beheer OpenID-adressen
-theme_desc=Dit zal het standaardthema worden op de gehele site.
+manage_themes=Standaardthema
+manage_openid=OpenID-adressen
+theme_desc=Dit thema wordt gebruikt voor de webinterface wanneer je bent aangemeld.
primary=Primair
activated=Geactiveerd
requires_activation=Vereist activering
@@ -794,7 +845,7 @@ add_new_key=SSH sleutel toevoegen
add_new_gpg_key=GPG sleutel toevoegen
key_content_ssh_placeholder=Begint met "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", of "sk-ssh-ed25519@openssh.com"
key_content_gpg_placeholder=Begint met "-----BEGIN PGP PUBLIC KEY BLOCK-----"
-add_new_principal=Verantwoordelijke toevoegen
+add_new_principal=Principaal toevoegen
ssh_key_been_used=Deze SSH-sleutel is al toegevoegd aan de server.
ssh_key_name_used=Er bestaat al een SSH sleutel met dezelfde naam in uw account.
ssh_principal_been_used=Deze verantwoordelijke is al toegevoegd aan de server.
@@ -821,7 +872,7 @@ ssh_token=Token
ssh_token_help=U kunt een handtekening genereren door het volgende:
ssh_token_signature=Gepantserde SSH handtekening
key_signature_ssh_placeholder=Begint met "-----BEGIN SSH SIGNATURE-----"
-subkeys=Subkeys
+subkeys=Subsleutels
key_id=Key-ID
key_name=Sleutel naam
key_content=Inhoud
@@ -846,12 +897,12 @@ token_state_desc=Dit token werd gebruikt in de laatste 7 dagen
principal_state_desc=Deze verantwoordelijke werd gebruikt in de laatste 7 dagen
show_openid=Tonen op profiel
hide_openid=Verbergen van profiel
-ssh_disabled=SSH uitgeschakeld
+ssh_disabled=SSH is uitgeschakeld
ssh_externally_managed=Deze SSH sleutel wordt extern beheerd voor deze gebruiker
manage_social=Beheer gekoppelde sociale accounts
unbind=Ontkoppelen
-manage_access_token=Beheer toegangstokens
+manage_access_token=Toegangstokens
generate_new_token=Nieuw token genereren
tokens_desc=Deze tokens geven toegang tot je account via de API van Forgejo.
token_name=Tokennaam
@@ -905,13 +956,13 @@ passcode_invalid=De code is niet correct. Probeer het nogmaals.
twofa_enrolled=Tweefactorsauthenticatie is geactiveerd voor dit account. Bewaar je token (%s) op een veilige plek, omdat hij maar รฉรฉn keer wordt weergegeven.
twofa_failed_get_secret=Kon geheim niet ophalen.
-webauthn_desc=Beveiligingssleutels zijn hardware apparaten die cryptografische sleutels bevatten. Ze kunnen worden gebruikt voor tweestapsverificatie. Beveiligingssleutels moeten de WebAuthn Authenticator standaard ondersteunen.
+webauthn_desc=Beveiligingssleutels zijn hardware apparaten die cryptografische sleutels bevatten. Ze kunnen worden gebruikt voor tweestapsverificatie. Beveiligingssleutels moeten de WebAuthn Authenticator standaard ondersteunen.
webauthn_register_key=Voeg beveiligingssleutel toe
webauthn_nickname=Bijnaam
webauthn_delete_key=Verwijder beveiligingssleutel
webauthn_delete_key_desc=Als u een beveiligingssleutel verwijdert, kunt u er niet meer mee inloggen. Doorgaan?
-manage_account_links=Gekoppelde accounts beheren
+manage_account_links=Gekoppelde accounts
manage_account_links_desc=Deze externe accounts zijn gekoppeld aan je Forgejo-account.
account_links_not_available=Er zijn momenteel geen externe accounts aan je Forgejo-account gelinkt.
link_account=Account koppelen
@@ -941,8 +992,8 @@ visibility.limited=Beperkt
visibility.private=Privรฉ
blocked_users = Geblokkeerde gebruikers
uid = UID
-biography_placeholder = Vertel ons iets over uzelf! (U kunt van Markdown gebruik maken)
-profile_desc = Controleer hoe uw profiel aan andere gebruikers wordt getoond. Uw primaire e-mailadres zal worden gebruikt voor notificaties, wachtwoord herstel en web-gebaseerde Git-operaties.
+biography_placeholder = Vertel anderen een beetje over uzelf! (Markdown is ondersteund)
+profile_desc = Over u
update_language_not_found = Taal "%s" is niet beschikbaar.
change_username_prompt = Opmerking: Het veranderen van uw gebruikersnaam zal ook de URL van uw account veranderen.
change_username_redirect_prompt = De oude gebruikersnaam zal worden doorverwezen totdat iemand deze opeist.
@@ -958,7 +1009,7 @@ permission_no_access = Geen toegang
permissions_list = Machtigingen:
update_oauth2_application_success = U heeft met succes een OAuth2 applicatie bijgewerkt.
twofa_recovery_tip = Als u uw apparaat verliest, kunt u gebruik maken van de eenmalige herstelcode om weer toegang te krijgen tot uw account.
-add_email_confirmation_sent = Er is een bevestigingsmail verzonden naar "%s". Controleer uw inbox binnen de %s om uw e-mailadres te bevestigen.
+add_email_confirmation_sent = Er is een bevestigingsmail verzonden naar โ%sโ. Om uw e-mailadres te bevestigen, controleert u uw inbox en volgt u de meegeleverde link binnen de komende %s.
verify_ssh_key_success = SSH-sleutel "%s" is geverifieerd.
add_key_success = De SSH-sleutel "%s" is toegevoegd.
add_gpg_key_success = De GPG-sleutel "%s" is toegevoegd.
@@ -975,7 +1026,7 @@ at_least_one_permission = Je moet minstens รฉรฉn machtiging kiezen om een token
permission_write = Lees en schrijf
oauth2_client_secret_hint = Dit geheim zal niet meer worden getoond nadat u deze pagina heeft verlaten of vernieuwd. Zorg ervoor dat u het heeft opgeslagen.
revoke_oauth2_grant_success = Toegang succesvol ingetrokken.
-keep_email_private_popup = Dit zal uw e-mailadres verbergen van uw profielpagina en ook wanneer u een web-gebaseerde Git-operatie uitvoert. Gepushte commits zullen niet aangepast worden. Gebruik %s in commits om deze met uw account te associรซren.
+keep_email_private_popup = Uw e-mailadres zal niet getoond worden op uw profiel en zal niet de standaard zijn voor commits die via de webinterface gemaakt worden, zoals bestandsuploads, bewerkingen en samenvoeg commits. In plaats daarvan kan een speciaal adres %s gebruikt worden om commits aan uw account te koppelen. Deze optie zal bestaande commits niet beรฏnvloeden.
create_oauth2_application_success = U heeft met succes een OAuth2 applicatie gecreรซerd.
permissions_access_all = Alle (publiek, privรฉ en gelimiteerd)
oauth2_application_remove_description = Door een OAuth2-applicatie te verwijderen, krijgt deze geen toegang meer tot geautoriseerde gebruikersaccounts op deze instantie. Doorgaan?
@@ -986,12 +1037,12 @@ webauthn_key_loss_warning = Als u uw beveiligingssleutels verliest, zal u toegan
repos_none = U bezit geen repositories.
hooks.desc = Voeg webhooks toe die door alle repositories waarvan u eigenaar bent aangeroept kunnen worden.
visibility.public_tooltip = Zichtbaar voor iedereen
-visibility.limited_tooltip = Alleen zichtbaar voor geauthenticeerde gebruikers
+visibility.limited_tooltip = Alleen zichtbaar voor ingelogde gebruikers
visibility.private_tooltip = Alleen zichtbaar voor leden van organisaties waarbij u bent aangesloten
user_unblock_success = De gebruiker is succesvol gedeblokkeerd.
user_block_success = De gebruiker is succesvol geblokkeerd.
blocked_since = Geblokkeerd sinds %s
-access_token_desc = Geselecteerde token machtigingen beperken autorisatie alleen tot de bijbehorende API routes. Lees de documentatie voor meer informatie.
+access_token_desc = Geselecteerde token machtigingen beperken autorisatie alleen tot de bijbehorende API routes. Lees de documentatie voor meer informatie.
oauth2_confidential_client = Vertrouwelijke client. Selecteer deze optie voor apps die het geheim bewaren, zoals webapps. Niet selecteren voor native apps, waaronder desktop- en mobiele apps.
authorized_oauth2_applications_description = Je hebt deze applicaties van derden toegang verleend tot je persoonlijke Forgejo-account. Trek de toegang in voor applicaties die niet langer in gebruik zijn.
hidden_comment_types.ref_tooltip = Reacties waarbij naar deze issue werd verwezen vanuit een ander issue/commit/โฆ
@@ -999,15 +1050,48 @@ hidden_comment_types.issue_ref_tooltip = Reacties waarbij de gebruiker de branch
oauth2_redirect_uris = Omleiding URI's. Gebruik een nieuwe regel voor elke URI.
oauth2_application_locked = Forgejo registreert sommige OAuth2 applicaties vooraf bij het opstarten als dit is ingeschakeld in de configuratie. Om onverwacht gedrag te voorkomen, kunnen deze niet bewerkt of verwijderd worden. Raadpleeg de OAuth2 documentatie voor meer informatie.
change_password = Wachtwoord bijwerken
-additional_repo_units_hint = Stimuleer het inschakelen van extra repositorie units
+additional_repo_units_hint = Stel voor om extra repositorie units in te schakelen
update_hints = Tips bijwerken
update_hints_success = Tips zijn bijgewerkt.
hints = Tips
-additional_repo_units_hint_description = Toon een "Voeg meer eenheden toe..." knop voor repositories die niet alle beschikbare eenheden hebben ingeschakeld.
+additional_repo_units_hint_description = Toon een โMeer activerenโ hint voor repositories die niet alle beschikbare eenheden hebben ingeschakeld.
pronouns = Persoonlijke voornaamwoord
pronouns_custom = Aangepast
pronouns_unspecified = Ongedefinieerd
language.title = Standaard taal
+keep_activity_private.description = Uw publieke activiteit zal alleen zichtbaar zijn voor u en de beheerders van de instantie.
+language.description = Deze taal wordt opgeslagen in uw account en wordt als standaardtaal gebruikt nadat u zich heeft aangemeld.
+language.localization_project = Help ons Forgejo in uw taal te vertalen! Leer meer .
+user_block_yourself = U kunt niet zichzelf blokkeren.
+pronouns_custom_label = Aangepaste voornaamwoorden
+change_username_redirect_prompt.with_cooldown.few = De oude gebruikersnaam zal voor iedereen beschikbaar zijn na een afkoelperiode van %[1]d dagen. U kunt de oude gebruikersnaam nog steeds opeisen tijdens de afkoelperiode.
+change_username_redirect_prompt.with_cooldown.one = De oude gebruikersnaam zal voor iedereen beschikbaar zijn na een afkoelperiode van %[1]d dag. U kunt de oude gebruikersnaam nog steeds opeisen tijdens de afkoelperiode.
+keep_pronouns_private = Toon voornaamwoorden alleen aan geauthenticeerde gebruikers
+keep_pronouns_private.description = Dit verbergt uw voornaamwoorden voor bezoekers die niet zijn ingelogd.
+quota.rule.exceeded.helper = De totale grootte van objecten voor deze regel heeft de quota overschreden.
+quota.sizes.repos.private = Privรฉ repositories
+storage_overview = Opslagoverzicht
+quota = Quotum
+quota.applies_to_user = De volgende quotaregels zijn van toepassing op uw account
+quota.applies_to_org = De volgende quotaregels zijn van toepassing op deze organisatie
+quota.rule.exceeded = Overschreden
+quota.rule.no_limit = Onbeperkt
+quota.sizes.all = Alle
+quota.sizes.repos.all = Repositories
+quota.sizes.repos.public = Openbare repositories
+quota.sizes.git.all = Git inhoud
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.all = Bezittingen
+quota.sizes.assets.attachments.all = Bijlagen
+quota.sizes.assets.attachments.issues = Issue bijlagen
+quota.sizes.assets.attachments.releases = Release bijlagen
+quota.sizes.assets.artifacts = Artefacten
+quota.sizes.assets.packages.all = Pakketten
+quota.sizes.wiki = Wiki
+access_token_regeneration = Toegangstoken opnieuw genereren
+regenerate_token = Opnieuw genereren
+regenerate_token_success = De token is opnieuw gegenereerd. Toepassingen die het gebruiken, hebben niet langer toegang tot uw account en moeten worden bijgewerkt om de nieuwe token te gebruiken.
+access_token_regeneration_desc = Als u een token opnieuw genereert, wordt de toegang tot uw account ingetrokken voor toepassingen die de token gebruiken. Dit kan niet ongedaan worden gemaakt. Doorgaan?
[repo]
owner=Eigenaar
@@ -1016,13 +1100,13 @@ repo_name=Naam van repository
repo_name_helper=Goede repository-namen zijn kort, makkelijk te onthouden en uniek.
repo_size=Repositorygrootte
template=Sjabloon
-template_select=Selecteer een sjabloon.
+template_select=Selecteer een sjabloon
template_helper=Maak template van repository
template_description=Sjabloon repositories laten gebruikers nieuwe repositories genereren met dezelfde directory structuur, bestanden en optionele instellingen.
visibility=Zichtbaarheid
visibility_description=Alleen de eigenaar of de organisatielid kan het zien als ze rechten hebben.
visibility_helper_forced=De sitebeheerder verplicht alle repositories om privรฉ te zijn.
-visibility_fork_helper=(Als je dit wijzigt, heeft dit invloed op de zichtbaarheid van alle forks).
+visibility_fork_helper=(Als u dit wijzigt, heeft dit invloed op de zichtbaarheid van alle forks.)
clone_helper=Heb je hulp nodig om te clonen? Bekijk dan de handleiding .
fork_repo=Repository forken
fork_from=Fork van
@@ -1039,17 +1123,17 @@ generate_from=Genereer van
repo_desc=Omschrijving
repo_desc_helper=Voer korte beschrijving in (optioneel)
repo_lang=Taal
-repo_gitignore_helper=Selecteer .gitignore templates.
+repo_gitignore_helper=Selecteer .gitignore sjabloons
repo_gitignore_helper_desc=Kies welke bestanden niet bij te houden vanuit een lijst met sjablonen voor alledaagse talen. Gebruikelijke artefacten gegenereerd door de build tools van elke taal zijn standaard inbegrepen met .gitignore.
-issue_labels=Issue labels
-issue_labels_helper=Selecteer een issuelabelset.
+issue_labels=Labels
+issue_labels_helper=Selecteer een labelset
license=Licentie
-license_helper=Selecteer een licentie bestand.
-license_helper_desc=Een licentie bepaalt wat anderen wel en niet met je code kunnen doen. Niet zeker welke juist is voor jouw project? Zie Kies een licentie.
+license_helper=Selecteer een licentie bestand
+license_helper_desc=Een licentie bepaalt wat anderen wel en niet met je code kunnen doen. Niet zeker welke juist is voor jouw project? Zie Kies een licentie .
readme=README
-readme_helper=Selecteer een README-bestandssjabloon.
+readme_helper=Selecteer een README-bestandssjabloon
readme_helper_desc=Dit is de plek waar je een volledige beschrijving van je project kunt schrijven.
-auto_init=Initialiseer repository (voegt .gitignore, License en README toe)
+auto_init=Initialiseer repository
trust_model_helper=Selecteer het vertrouwensmodel voor handtekeningverificatie. Mogelijke opties zijn:
trust_model_helper_collaborator=Samenwerker: Vertrouw handtekeningen door samenwerker
trust_model_helper_committer=Committer: Vertrouw handtekeningen die overeenkomen met de committers
@@ -1074,12 +1158,12 @@ mirror_password_placeholder=(Ongewijzigd)
mirror_password_blank_placeholder=(Niet ingesteld)
mirror_password_help=Wijzig de gebruikersnaam om een opgeslagen wachtwoord te wissen.
watchers=Volgers
-stargazers=Stargazers
+stargazers=Sterrenkijkers
forks=Forks
reactions_more=en %d meer
unit_disabled=De sitebeheerder heeft deze repositorie sectie uitgeschakeld.
language_other=Andere
-adopt_search=Voer gebruikersnaam in om te zoeken naar niet-geadopteerde repositories... (laat leeg om alles te vinden)
+adopt_search=Voer gebruikersnaam in om te zoeken naar niet-geadopteerde repositoriesโฆ (laat leeg om alles te vinden)
adopt_preexisting_label=Bestanden adopteren
adopt_preexisting=Bestaamde bestanden adopteren
adopt_preexisting_content=Maak een repository van %s
@@ -1113,8 +1197,8 @@ template.issue_labels=Issue labels
template.one_item=Moet ten minste รฉรฉn sjabloon selecteren
template.invalid=Moet een sjabloon repository selecteren
-archive.issue.nocomment=Deze repo is gearchiveerd. U kunt niet reageren op problemen.
-archive.pull.nocomment=Deze repo is gearchiveerd. U kunt niet reageren op pull requests.
+archive.issue.nocomment=Deze repository is gearchiveerd. U kunt niet reageren op problemen.
+archive.pull.nocomment=Deze repository is gearchiveerd. U kunt niet reageren op pull requests.
form.reach_limit_of_creation_1=U heeft al uw limiet van %d repository bereikt.
form.reach_limit_of_creation_n=U heeft al uw limiet van %d repositories bereikt.
@@ -1122,7 +1206,7 @@ form.reach_limit_of_creation_n=U heeft al uw limiet van %d repositories bereikt.
need_auth=Autorisatie
migrate_options=Migratie opties
migrate_service=Migratie service
-migrate_options_mirror_helper=Deze repositorie zal een spiegel zijn
+migrate_options_mirror_helper=Deze repositorie zal een mirror zijn
migrate_options_lfs=Migreer LFS bestanden
migrate_options_lfs_endpoint.label=LFS eindpunt
migrate_options_lfs_endpoint.description=Migratie zal proberen om je Git remote te gebruiken om de LFS-server te bepalen. Je kan ook een aangepast eindpunt opgeven als de LFS-gegevens ergens anders zijn opgeslagen.
@@ -1148,13 +1232,13 @@ migrate.migrate_items_options=Toegangstoken is vereist om extra items te migrere
migrated_from=Gemigreerd van %[2]s
migrated_from_fake=Gemigreerd van %[1]s
migrate.migrate=Migreer van %s
-migrate.migrating=Migreren van %s ...
+migrate.migrating=Migreren van %s โฆ
migrate.migrating_failed=Migreren van %s is mislukt.
migrate.migrating_failed_no_addr=Migratie is mislukt.
migrate.github.description=Migreer gegevens van github.com of GitHub Enterprise server.
migrate.git.description=Migreer een repositorie van elke Git service.
migrate.gitlab.description=Gegevens migreren van gitlab.com of andere GitLab-instanties.
-migrate.gitea.description=Gegevens overzetten van gitea.com of andere Gitea/Forgejo instanties.
+migrate.gitea.description=Gegevens overzetten van gitea.com of andere Gitea instanties.
migrate.gogs.description=Gegevens overzetten van notabug.org of andere Gogs instanties.
migrate.onedev.description=Gegevens overzetten van code.onedev.io of andere OneDev instanties.
migrate.codebase.description=Gegevens migreren van codebasehq.com.
@@ -1201,7 +1285,7 @@ tags=Labels
issues=Issues
pulls=Pull requests
project_board=Projecten
-packages=Paketten
+packages=Pakketten
labels=Labels
org_labels_desc=Organisatielabel dat gebruikt kan worden met alle repositories onder deze organisatie
org_labels_desc_manage=beheren
@@ -1221,8 +1305,8 @@ file_view_rendered=Weergave weergeven
file_view_raw=Weergave ruw bestand
file_permalink=Permalink
file_too_large=Dit bestand is te groot om te tonen.
-invisible_runes_line=`Deze lijn heeft onzichtbare unicode karakters`
-ambiguous_runes_line=`Deze lijn heeft dubbelzinnige unicode karakters`
+invisible_runes_line=`Deze lijn heeft onzichtbare Unicode karakters`
+ambiguous_runes_line=`Deze lijn heeft dubbelzinnige Unicode karakters`
ambiguous_character=`%[1]c [U+%04[1]X] is verwarrend met %[2]c [U+%04[2]X]`
escape_control_characters=Escape
@@ -1232,6 +1316,7 @@ view_git_blame=Bekijk git blame
video_not_supported_in_browser=Uw browser ondersteunt de HTML5 "video" element niet.
audio_not_supported_in_browser=Uw browser ondersteunt de HTML5 "audio" element niet.
stored_lfs=Opgeslagen met Git LFS
+stored_annex=Opgeslagen met Git Annex
symbolic_link=Symbolische link
commit_graph=Commit grafiek
commit_graph.select=Selecteer branches
@@ -1250,6 +1335,7 @@ editor.upload_file=Upload bestand
editor.edit_file=Bewerk bestand
editor.preview_changes=Voorbeeld tonen
editor.cannot_edit_lfs_files=LFS-bestanden kunnen niet worden bewerkt in de webinterface.
+editor.cannot_edit_annex_files=Annex-bestanden kunnen niet worden bewerkt in de webinterface.
editor.cannot_edit_non_text_files=Binaire bestanden kunnen niet worden bewerkt in de webinterface.
editor.edit_this_file=Bewerk bestand
editor.this_file_locked=Bestand is vergrendeld
@@ -1263,20 +1349,21 @@ editor.or=of
editor.cancel_lower=Annuleer
editor.commit_signed_changes=Commit ondertekende wijzigingen
editor.commit_changes=Wijzigingen doorvoeren
-editor.add_tmpl="" toevoegen
+editor.add_tmpl="<%s>" toevoegen
+editor.add_tmpl.filename = bestandsnaam
editor.patch=Patch toepassen
editor.patching=Patchen:
-editor.new_patch=Nieuwe Patch
+editor.new_patch=Nieuwe patch
editor.commit_message_desc=Voeg een optionele uitgebreide omschrijving toeโฆ
editor.signoff_desc=Voeg een Signed-off-by toe aan het einde van het commit logbericht.
-editor.commit_directly_to_this_branch=Commit direct naar de branch '%s '.
+editor.commit_directly_to_this_branch=Commit direct naar de branch %[1]s .
editor.create_new_branch=Maak een nieuwe branch voor deze commit en start van een pull request.
editor.create_new_branch_np=Maak een nieuwe branch voor deze commit.
editor.propose_file_change=Stel bestandswijziging voor
editor.new_branch_name_desc=Nieuwe branch naamโฆ
editor.cancel=Annuleer
editor.filename_cannot_be_empty=Bestandsnaam mag niet leeg zijn.
-editor.file_changed_while_editing=De bestandsinhoud is veranderd sinds je bent begonnen met bewerken. Klik hier om ze te zien, of commit de veranderingen opnieuw om ze te overschrijven.
+editor.file_changed_while_editing=De inhoud van het bestand is gewijzigd sinds u het bestand hebt geopend. Klik hier om ze te zien, of commit de veranderingen opnieuw om ze te overschrijven.
editor.commit_empty_file_header=Commit een leeg bestand
editor.commit_empty_file_text=Het bestand dat u wilt committen is leeg. Doorgaan?
editor.no_changes_to_show=Er zijn geen wijzigingen om weer te geven.
@@ -1318,7 +1405,7 @@ commit.cherry-pick-content=Selecteer een branch om te cherry-pick op:
commitstatus.error=Fout
commitstatus.pending=In behandeling
-ext_issues=Toegang tot externe issues
+ext_issues=Externe issues
ext_issues.desc=Koppelen aan een externe kwestie-tracker.
projects=Projecten
@@ -1465,16 +1552,16 @@ issues.context.quote_reply=Citeer antwoord
issues.context.reference_issue=Verwijs in een nieuwe issue
issues.context.edit=Bewerken
issues.context.delete=Verwijder
-issues.close_comment_issue=Reageer en sluit
+issues.close_comment_issue=Sluit met commentaar
issues.reopen_issue=Heropen
-issues.reopen_comment_issue=Reageer en heropen
+issues.reopen_comment_issue=Heropen met commentaar
issues.create_comment=Reageer
issues.closed_at=`heeft dit probleem gesloten %[2]s `
issues.reopened_at=`heropende dit probleem %[2]s `
issues.commit_ref_at=`verwees naar dit probleem vanuit commit %[2]s' `
issues.ref_issue_from=`refereerde aan dit issue %[4]s %[2]s `
issues.ref_pull_from=`refereerde aan deze pull request %[4]s %[2]s `
-issues.ref_closing_from=`verwees naar een pull request %[4]s dat het issue zal sluiten %[2]s `
+issues.ref_closing_from=`verwees naar deze issue van een pull request %[4]s dat het zal sluiten , %[2]s `
issues.ref_reopening_from=`verwees naar een pull request %[4]s dat dit issue heropent %[2]s `
issues.ref_closed_from=`sloot dit issue %[4]s %[2]s `
issues.ref_reopened_from=`heropende dit issue %[4]s %[2]s `
@@ -1559,7 +1646,7 @@ issues.error_modifying_due_date=Deadline aanpassen mislukt.
issues.error_removing_due_date=Deadline verwijderen mislukt.
issues.push_commit_1=toegevoegd %d commit %s
issues.push_commits_n=toegevoegd %d commits %s
-issues.force_push_codes=`force-push %[1]s van %[2]s
naar %[4]s
%[6]s`
+issues.force_push_codes=`force-push %[1]s van %[2]s
naar %[4]s
%[6]s`
issues.force_push_compare=Vergelijk
issues.due_date_form=jjjj-mm-dd
issues.due_date_form_add=Vervaldatum toevoegen
@@ -1608,12 +1695,12 @@ issues.review.left_comment=heeft een reactie achtergelaten
issues.review.content.empty=Je moet een reactie achterlaten die de gewenste verandering(en) beschrijft.
issues.review.reject=aangevraagde wijzigingen %s
issues.review.wait=is gevraagd voor review %s
-issues.review.add_review_request=heeft een review aangevraagd van %s %s
-issues.review.remove_review_request=beoordelingsaanvraag voor %s %s verwijderd
-issues.review.remove_review_request_self=beoordeling geweigerd %s
+issues.review.add_review_request=beoordeling gevraagd van %[1]s %[2]s
+issues.review.remove_review_request=beoordelingsaanvraag voor %[1]s %[2]s verwijderd
+issues.review.remove_review_request_self=weigerde te beoordelen %s
issues.review.pending=In behandeling
issues.review.review=Review
-issues.review.reviewers=Reviewers
+issues.review.reviewers=Beoordelaars
issues.review.outdated=Verouderd
issues.review.show_outdated=Toon verouderd
issues.review.hide_outdated=Verouderde verbergen
@@ -1656,7 +1743,7 @@ pulls.nothing_to_compare=Deze branches zijn gelijk. Er is geen pull request nodi
pulls.nothing_to_compare_and_allow_empty_pr=Deze branches zijn gelijk. Deze pull verzoek zal leeg zijn.
pulls.has_pull_request=`Een pull-verzoek tussen deze branches bestaat al: %[2]s#%[3]d `
pulls.create=Pull request aanmaken
-pulls.title_desc_few=wilt %[1]d commits van %[2]s
samenvoegen met %[3]s
+pulls.title_desc_few=wilt %[1]d commits van %[2]s
samenvoegen met %[3]s
pulls.merged_title_desc_few=heeft %[1]d commits samengevoegd van %[2]s
naar %[3]s
%[4]s
pulls.change_target_branch_at='doelbranch aangepast van %s naar %s %s'
pulls.tab_conversation=Discussie
@@ -1773,7 +1860,7 @@ milestones.filter_sort.most_issues=Meeste problemen
milestones.filter_sort.least_issues=Minste problemen
-ext_wiki=Toegang tot externe wiki
+ext_wiki=Externe wiki
ext_wiki.desc=Koppelen aan een externe wiki.
wiki=Wiki
@@ -1790,7 +1877,7 @@ wiki.last_commit_info=%s heeft deze pagina aangepast %s
wiki.edit_page_button=Bewerken
wiki.new_page_button=Nieuwe pagina
wiki.file_revision=Pagina revisie
-wiki.wiki_page_revisions=Herzieningen wiki pagina
+wiki.wiki_page_revisions=Pagina revisies
wiki.back_to_wiki=Terug naar wiki-pagina
wiki.delete_page_button=Verwijder pagina
wiki.page_already_exists=Er bestaat al een wiki-pagina met deze naam.
@@ -1808,8 +1895,8 @@ activity.period.quarterly=3 maanden
activity.period.semiyearly=6 maanden
activity.period.yearly=1 jaar
activity.overview=Overzicht
-activity.active_prs_count_1=%d actieve pull requests
-activity.active_prs_count_n=%d Actieve pull requests
+activity.active_prs_count_1=%d actieve pull request
+activity.active_prs_count_n=%d actieve pull requests
activity.merged_prs_count_1=Samengevoegde pull request
activity.merged_prs_count_n=Samengevoegde pull requests
activity.opened_prs_count_1=Voorgestelde pull request
@@ -1841,7 +1928,7 @@ activity.unresolved_conv_label=Open
activity.title.releases_1=%d release
activity.title.releases_n=%d releases
activity.title.releases_published_by=%s gepubliceerd door %s
-activity.published_release_label=Gepubliceerd
+activity.published_release_label=Release
activity.no_git_activity=Er is in deze periode geen sprake geweest van een commit activiteit.
activity.git_stats_exclude_merges=Exclusief merges,
activity.git_stats_author_1=%d auteur
@@ -1864,8 +1951,7 @@ activity.git_stats_and_deletions=en
activity.git_stats_deletion_1=%d verwijdering
activity.git_stats_deletion_n=%d verwijderingen
-contributors.contribution_type.commits=Commits
-
+contributors.contribution_type.commits = Commits
search=Zoek
search.search_repo=Zoek repository
search.fuzzy=Vergelijkbaar
@@ -1892,12 +1978,12 @@ settings.mirror_settings.direction=Richting
settings.mirror_settings.direction.pull=Pull
settings.mirror_settings.direction.push=Push
settings.mirror_settings.last_update=Laatst bijgewerkt
-settings.mirror_settings.push_mirror.none=Geen spiegels geconfigureerd
+settings.mirror_settings.push_mirror.none=Geen push mirrors geconfigureerd
settings.mirror_settings.push_mirror.add=Push mirror toevoegen
settings.sync_mirror=Nu synchroniseren
settings.site=Website
-settings.update_settings=Instellingen bewerken
+settings.update_settings=Instellingen opslaan
settings.branches.update_default_branch=Standaard branch bewerken
settings.advanced_settings=Geavanceerde instellingen
settings.wiki_desc=Repository-wiki inschakelen
@@ -2010,29 +2096,29 @@ settings.event_repository_desc=Repository gemaakt of verwijderd.
settings.event_header_issue=Issue gebeurtenissen
settings.event_issues=Issues
settings.event_issues_desc=Issue geopend, gesloten, heropend of bewerkt.
-settings.event_issue_assign=issue toegekend
+settings.event_issue_assign=Toewijzing
settings.event_issue_assign_desc=Issue toegewezen of niet-toegewezen.
-settings.event_issue_label=Issue gelabeld
-settings.event_issue_label_desc=Issue-labels bijgewerkt of verwijderd.
-settings.event_issue_milestone=Issue gemilestoned
-settings.event_issue_milestone_desc=Issue gemilestoned of gedemilestoned.
-settings.event_issue_comment=Issue reactie
+settings.event_issue_label=Labels
+settings.event_issue_label_desc=Issue labels toegevoegd of verwijderd.
+settings.event_issue_milestone=Mijlpalen
+settings.event_issue_milestone_desc=Mijlpaal toegevoegd, verwijderd of gewijzigd.
+settings.event_issue_comment=Opmerkingen
settings.event_issue_comment_desc=Issue reactie aangemaakt, bewerkt of verwijderd.
settings.event_header_pull_request=Pull request gebeurtenissen
-settings.event_pull_request=Pull request
+settings.event_pull_request=Wijziging
settings.event_pull_request_desc=Pull request geopend, gesloten, heropend of bewerkt.
-settings.event_pull_request_assign=Pull request toegewezen
+settings.event_pull_request_assign=Toewijzing
settings.event_pull_request_assign_desc=Pull request toegewezen of niet-toegewezen.
-settings.event_pull_request_label=Pull request gelabeld
-settings.event_pull_request_label_desc=Pull request labels bijgewerkt of gewist.
-settings.event_pull_request_milestone=Pull Request gemilestoned
-settings.event_pull_request_milestone_desc=Pull Reguest gemilestoned of gedemilestoned.
-settings.event_pull_request_comment=Pull request reactie
+settings.event_pull_request_label=Labels
+settings.event_pull_request_label_desc=Pull request labels toegevoegd of verwijderd.
+settings.event_pull_request_milestone=Mijlpalen
+settings.event_pull_request_milestone_desc=Mijlpaal toegevoegd, verwijderd of gewijzigd.
+settings.event_pull_request_comment=Opmerkingen
settings.event_pull_request_comment_desc=Pull request commentaar gemaakt, bewerkt of verwijderd.
-settings.event_pull_request_review=Pull request gereviewed
-settings.event_pull_request_review_desc=Pull request goedgekeurd, afgewezen of review commentaar.
-settings.event_pull_request_sync=Pull request gesynchroniseerd
-settings.event_pull_request_sync_desc=Pull request gesynchroniseerd.
+settings.event_pull_request_review=Beoordelingen
+settings.event_pull_request_review_desc=Pull request goedgekeurd, afgewezen of opmerkingen over beoordeling toegevoegd.
+settings.event_pull_request_sync=Gesynchroniseerd
+settings.event_pull_request_sync_desc=Branch automatisch bijgewerkt met doel branch.
settings.branch_filter=Branch filter
settings.active=Actief
settings.active_helper=Informatie over geactiveerde gebeurtenissen wordt naar deze webhook URL gestuurd.
@@ -2080,7 +2166,7 @@ settings.protected_branch=Branch bescherming
settings.protected_branch_can_push=Push toestaan?
settings.protected_branch_can_push_yes=U mag pushen
settings.protected_branch_can_push_no=U mag niet pushen
-settings.branch_protection=Branch bescherming voor branch "%s "
+settings.branch_protection=Beschermingsregels voor branch โ%s โ
settings.protect_this_branch=Branch bescherming inschakelen
settings.protect_this_branch_desc=Voorkomt verwijdering en beperkt Git pushing en samenvoegen tot de branch.
settings.protect_disable_push=Push uitschakelen
@@ -2090,23 +2176,23 @@ settings.protect_enable_push_desc=Iedereen met schrijftoegang heeft toegang om t
settings.protect_whitelist_committers=Whitelist beperkte push
settings.protect_whitelist_committers_desc=Alleen gewhiteliste gebruikers of teams mogen pushen naar deze branch (maar geen force push).
settings.protect_whitelist_deploy_keys=Whitelist deploy sleutels met schrijftoegang om te pushen.
-settings.protect_whitelist_users=Toegestane gebruikers voor push:
+settings.protect_whitelist_users=Toegestane gebruikers voor push
settings.protect_whitelist_search_users=Zoek gebruikerโฆ
-settings.protect_whitelist_teams=Toegestane teams voor push:
+settings.protect_whitelist_teams=Toegestane teams voor push
settings.protect_whitelist_search_teams=Zoek teamsโฆ
settings.protect_merge_whitelist_committers=Samenvoegen whitelist inschakelen
settings.protect_merge_whitelist_committers_desc=Sta alleen gebruikers of teams van de whitelist toe om pull requests samen te voegen met deze branch.
-settings.protect_merge_whitelist_users=Toegestane gebruikers voor samenvoegen:
-settings.protect_merge_whitelist_teams=Toegestane teams voor samenvoegen:
+settings.protect_merge_whitelist_users=Toegestane gebruikers voor samenvoegen
+settings.protect_merge_whitelist_teams=Toegestane teams voor samenvoegen
settings.protect_check_status_contexts=Status controle inschakelen
settings.protect_check_status_contexts_desc=Statuscontroles zijn vereist om te kunnen samenvoegen. Kies welke statuscontroles moeten slagen voordat branches kunnen worden samengevoegd tot een branch die aan deze regel voldoet. Wanneer ingeschakeld, moeten commits eerst naar een andere branch worden gepusht, vervolgens samengevoegd of gepusht worden naar een branch die overeenkomt met deze regel nadat de statuscontroles zijn uitgevoerd. Als er geen contexten worden geselecteerd, moet de laatste commit succesvol zijn, ongeacht de context.
settings.protect_check_status_contexts_list=Status controles gevonden in de afgelopen week voor deze repository
-settings.protect_required_approvals=Vereiste goedkeuringen:
+settings.protect_required_approvals=Vereiste goedkeuringen
settings.protect_required_approvals_desc=Sta alleen toe om pull request samen te voegen met voldoende positieve beoordelingen.
settings.protect_approvals_whitelist_enabled=Beperk goedkeuringen tot gebruikers of teams op de whitelist
settings.protect_approvals_whitelist_enabled_desc=Alleen beoordelingen van gebruikers of teams op de whitelist zullen voor het vereiste aantal goedkeuringen tellen. Zonder een goedkeurings whitelist, tellen beoordelingen van iedereen met schrijfrechten mee voor het vereiste aantal goedkeuringen.
-settings.protect_approvals_whitelist_users=Toegestane reviewers:
-settings.protect_approvals_whitelist_teams=Toegestane teams voor beoordelingen:
+settings.protect_approvals_whitelist_users=Toegestane reviewers
+settings.protect_approvals_whitelist_teams=Toegestane teams voor beoordelingen
settings.dismiss_stale_approvals=Verouderde goedkeuringen afwijzen
settings.dismiss_stale_approvals_desc=Wanneer nieuwe commits die de inhoud van het pull-verzoek veranderen, naar de branch worden gepusht, worden oude goedkeuringen verwijderd.
settings.require_signed_commits=Ondertekende commits vereisen
@@ -2145,15 +2231,15 @@ settings.archive.button=Repo archiveren
settings.archive.header=Archiveer deze repo
settings.archive.success=De repo is succesvol gearchiveerd.
settings.archive.error=Er is een fout opgetreden tijdens het archiveren van de repo. Zie het logboek voor meer informatie.
-settings.archive.error_ismirror=U kunt geen gespiegelde repo archiveren.
-settings.archive.branchsettings_unavailable=Branch instellingen zijn niet beschikbaar als de repo is gearchiveerd.
-settings.archive.tagsettings_unavailable=Labelinstellingen zijn niet beschikbaar als de repo is gearchiveerd.
+settings.archive.error_ismirror=U kunt geen gespiegelde repository archiveren.
+settings.archive.branchsettings_unavailable=Branchinstellingen zijn niet beschikbaar in gearchiveerde repo's.
+settings.archive.tagsettings_unavailable=Tag-instellingen zijn niet beschikbaar in gearchiveerde repo's.
settings.update_avatar_success=De repository avatar is bijgewerkt.
settings.lfs=LFS
settings.lfs_filelist=LFS bestanden opgeslagen in deze repository
settings.lfs_no_lfs_files=Geen LFS bestanden opgeslagen in deze repository
settings.lfs_findcommits=Vind commits
-settings.lfs_lfs_file_no_commits=Geen Commits gevonden voor dit LFS-bestand
+settings.lfs_lfs_file_no_commits=Geen commits gevonden voor dit LFS-bestand
settings.lfs_noattribute=Dit pad heeft niet het vergrendelbare attribuut in de standaard branch
settings.lfs_delete=LFS-bestand met OID %s verwijderen
settings.lfs_delete_warning=Het verwijderen van een LFS bestand kan leiden tot "object bestaat niet" fouten bij het uitchecken. Weet u het zeker?
@@ -2163,14 +2249,14 @@ settings.lfs_invalid_locking_path=Ongeldig pad: %s
settings.lfs_invalid_lock_directory=Kan map %s niet vergrendelen
settings.lfs_lock_already_exists=Vergrendeling bestaat al: %s
settings.lfs_lock=Vergrendel
-settings.lfs_lock_path=Bestandspad om te vergrendelen...
-settings.lfs_locks_no_locks=Geen Locks
+settings.lfs_lock_path=Bestandspad om te vergrendelenโฆ
+settings.lfs_locks_no_locks=Geen locks
settings.lfs_lock_file_no_exist=Vergrendeld bestand bestaat niet in de standaard branch
settings.lfs_force_unlock=Forceer ontgrendelen
settings.lfs_pointers.found=%d blob-pointer(s) gevonden - %d gekoppeld, %d niet-gekoppeld (%d ontbreekt in de winkel)
-settings.lfs_pointers.sha=Blob SHA
+settings.lfs_pointers.sha=Blob hash
settings.lfs_pointers.oid=OID
-settings.lfs_pointers.inRepo=In Repository
+settings.lfs_pointers.inRepo=In repository
settings.lfs_pointers.exists=Bestaat in opslag
settings.lfs_pointers.accessible=Toegankelijk voor gebruiker
settings.lfs_pointers.associateAccessible=Koppel toegankelijke %d OIDs
@@ -2220,7 +2306,7 @@ diff.comment.add_single_comment=รรฉn reactie toevoegen
diff.comment.add_review_comment=Voeg commentaar toe
diff.comment.start_review=Review starten
diff.comment.reply=Reageer
-diff.review=Review
+diff.review=Beoordeling voltooien
diff.review.header=Review versturen
diff.review.placeholder=Commentaar controleren
diff.review.comment=Opmerking
@@ -2239,24 +2325,24 @@ release.detail=Release details
release.tags=Labels
release.new_release=Nieuwe release
release.draft=Concept
-release.prerelease=Voorlopige versie
+release.prerelease=Voorlopige release
release.stable=Stabiel
release.compare=Vergelijk
-release.edit=bewerken
+release.edit=Bewerken
release.ahead.commits=%d commits
release.ahead.target=aan %s sinds deze release
release.source_code=Broncode
release.tag_name=Tagnaam
release.target=Doel
release.tag_helper=Kies een bestaande tag, of creรซer een nieuwe tag bij publiceren.
-release.prerelease_desc=Markeren als voorlopige versie
+release.prerelease_desc=Markeren als voorlopige release
release.prerelease_helper=Markeer deze release als ongeschikt voor productiedoeleinden.
release.cancel=Annuleren
release.publish=Release publiceren
release.save_draft=Concept opslaan
-release.edit_release=Update release
-release.delete_release=Verwijder release
-release.deletion=Verwijder release
+release.edit_release=Release bijwerken
+release.delete_release=Release verwijderen
+release.deletion=Release verwijderen
release.deletion_success=De release is verwijderd.
release.tag_name_already_exist=Een versie met deze naam bestaat al.
release.tag_name_invalid=Tagnaam is niet geldig.
@@ -2266,7 +2352,7 @@ release.download_count=Downloads: %s
branch.name=Branch naam
branch.delete_head=Verwijder
branch.delete_html=Verwijder branch
-branch.create_branch=Maak branch %s
+branch.create_branch=Maak branch %s
branch.deleted_by=Verwijderd door %s
branch.included_desc=Deze branch maakt deel uit van de standaard branch
branch.included=Inbegrepen
@@ -2283,9 +2369,9 @@ settings.protect_no_valid_status_check_patterns = Geen geldige status controlpat
settings.protect_branch_name_pattern = Beschermd branch naam patroon
settings.ignore_stale_approvals = Negeer verouderde goedkeuringen
settings.ignore_stale_approvals_desc = Tel goedkeuringen gemaakt op oudere commits (verouderde reviews) niet mee voor het aantal goedkeuringen dat het PR heeft. Irrelevant als verouderde reviews al afgekeurd zijn.
-settings.protect_branch_name_pattern_desc = Beschermd branch naam patronen. Zie de documentatie voor patroon syntax. Bijvoorbeeld: main, release/**
+settings.protect_branch_name_pattern_desc = Beschermd branch naam patronen. Zie de documentatie voor patroon syntax. Bijvoorbeeld: main, release/**
settings.protect_patterns = Patronen
-settings.protect_protected_file_patterns = Beschermde bestand patronen (gescheiden door een puntkomma ";"):
+settings.protect_protected_file_patterns = Beschermde bestand patronen (gescheiden door een puntkomma ";")
issues.no_content = Geen beschrijving gegeven.
issues.close = Issue sluiten
issues.comment_pull_merged_at = commit %[1]s samengevoegd in %[2]s %[3]s
@@ -2306,7 +2392,7 @@ fork_no_valid_owners = Deze repository kan niet geforkt worden omdat er geen gel
visibility_helper = Maak repository privรฉ
clone_in_vscodium = Kloon in VSCodium
object_format = Objectformaat
-object_format_helper = Objectformaat van de repository. Dit kan niet worden veranderd. SHA1 is het meest compatibel.
+object_format_helper = Objectformaat van de repository. Kan later niet worden gewijzigd. SHA1 is het meest compatibel.
mirror_sync = gesynchroniseerd
branch.delete_branch_has_new_commits = Branch "%s" kan niet verwijderd worden omdat er nieuwe commits zijn toegevoegd na het samenvoegen.
branch.create_success = Branch "%s" is gecreรซerd.
@@ -2327,7 +2413,7 @@ branch.warning_rename_default_branch = Je hernoemt de standaard branch.
branch.rename_branch_to = Hernoem "%s" naar:
tag.create_tag_operation = Creรซer tag
branch.create_from = van "%s"
-tag.create_tag = Creรซer tag %s
+tag.create_tag = Creรซer tag %s
tag.confirm_create_tag = Creรซer tag
tag.create_tag_from = Creรซer nieuwe tag van "%s"
branch.create_branch_operation = Creรซer branch
@@ -2336,13 +2422,13 @@ branch.new_branch_from = Creรซer nieuwe branch van "%s"
branch.renamed = Branch %s is hernoemd naar %s.
tag.create_success = Tag "%s" is gecreรซerd.
topic.format_prompt = Onderwerpen moeten beginnen met een letter of cijfer, kunnen streepjes ("-") en puntjes (".") bevatten en mogen maximaal 35 tekens lang zijn. Letters moeten kleine letters zijn.
-find_file.go_to_file = Ga naar bestand
+find_file.go_to_file = Zoek een bestand
find_file.no_matching = Geen overeenkomstige bestanden gevonden
error.csv.too_large = Kan dit bestand niet renderen omdat het te groot is.
error.csv.unexpected = Kan dit bestand niet renderen omdat het een onverwacht karakter bevat in regel %d en kolom %d.
error.csv.invalid_field_count = Kan dit bestand niet renderen omdat het een verkeerd aantal velden heeft in regel %d.
-issues.comment.blocked_by_user = U kunt geen reactie op deze issue plaatsen omdat u geblokkeerd bent door de eigenaar van de repository of door de persoon die de issue heeft gepost.
-issues.blocked_by_user = U kunt geen issue op deze repository maken omdat u geblokkeerd bent door de eigenaar van de repository.
+issues.comment.blocked_by_user = U kunt niet reageren op deze issue omdat u geblokkeerd bent door de eigenaar van de repository of de poster van de issue.
+issues.blocked_by_user = U kunt geen issues aanmaken in deze repository omdat u geblokkeerd bent door de eigenaar van deze repository.
issues.label_archived_filter = Gearchiveerde labels bekijken
issues.label_archive_tooltip = Gearchiveerde labels zijn standaard uitgezonderd van de suggesties als men op een label zoekt.
issues.max_pinned = U kunt geen issues meer vastpinnen
@@ -2360,7 +2446,7 @@ issues.review.option.hide_outdated_comments = Verouderde reacties verbergen
pulls.expand_files = Alle bestanden uitklappen
pulls.collapse_files = Alle bestanden inklappen
pulls.show_all_commits = Alle commits weergeven
-new_repo_helper = Een repository bevat alle projectbestanden, inclusief revisiegeschiedenis. Host je er al ergens anders een? Repository migreren.
+new_repo_helper = Een repository bevat alle projectbestanden, inclusief revisiegeschiedenis. Host je er al ergens anders een? Repository migreren .
editor.fail_to_update_file = Mislukt bij het bijwerken/creรซren van bestand "%s".
editor.file_is_a_symlink = `"%s" is een symbolische link. Symbolische links kunnen niet worden bewerkt in de webeditor`
editor.filename_is_a_directory = Bestandsnaam "%s" wordt al gebruikt als naam van een map in deze repository.
@@ -2405,7 +2491,7 @@ issues.role.collaborator_helper = Deze gebruiker is uitgenodigd om mee te werken
issues.role.first_time_contributor = Eerste keer bijdrager
issues.role.first_time_contributor_helper = Dit is de eerste bijdrage van deze gebruiker aan de repository.
issues.role.contributor = Bijdrager
-issues.role.contributor_helper = Deze gebruiker heeft al eerder gecommitteerd in de repository.
+issues.role.contributor_helper = Deze gebruiker heeft al eerder gecommitteerd in deze repository.
issues.label_exclusive = Exclusief
issues.label_archive = Label archiveren
issues.label_exclusive_warning = Eventuele conflicterende scoped labels worden verwijderd bij het bewerken van de labels van een issue of pull request.
@@ -2429,9 +2515,9 @@ tree_path_not_found_commit = Pad %[1]s bestaat niet in commit %[2]s
tree_path_not_found_tag = Pad %[1]s bestaat niet in tag %[2]s
transfer.no_permission_to_reject = Je hebt geen rechten om deze overdracht af te wijzen.
settings.transfer_owner = Nieuwe eigenaar
-mirror_address_protocol_invalid = De opgegeven URL is ongeldig. Alleen http(s):// of git:// locaties kunnen gebruikt worden voor spiegeling.
-archive.title = Deze repo is gearchiveerd. Je kunt bestanden bekijken en klonen, maar geen issues of pull requests pushen of openen.
-archive.title_date = Deze repository is gearchiveerd op %s. Je kunt bestanden bekijken en klonen, maar je kunt niet pushen of issues of pull requests openen.
+mirror_address_protocol_invalid = De opgegeven URL is ongeldig. Alleen http(s):// of git:// locaties kunnen gebruikt worden voor spiegelen.
+archive.title = Deze repository is gearchiveerd. U kunt bestanden bekijken en klonen, maar u kunt geen wijzigingen aanbrengen aan de status, zoals het pushen en aanmaken van nieuwe issues, pull requests of opmerkingen.
+archive.title_date = Deze repository is gearchiveerd op %s. U kunt bestanden bekijken en klonen, maar u kunt geen wijzigingen aanbrengen aan de status, zoals het pushen en aanmaken van nieuwe issues, pull requests of opmerkingen.
migrate_options_lfs_endpoint.placeholder = Als dit leeg gelaten wordt, zal het eindpunt afgeleid worden van de kloon URL
invisible_runes_description = `Dit bestand bevat onzichtbare Unicode-tekens die voor mensen niet te onderscheiden zijn, maar door een computer anders verwerkt kunnen worden. Als je denkt dat dit opzettelijk is, kun je deze waarschuwing gerust negeren. Gebruik de Escape knop om ze te onthullen.`
ambiguous_runes_header = `Dit bestand bevat dubbelzinnige Unicode-tekens`
@@ -2485,7 +2571,7 @@ wiki.page_content = Pagine inhoud
wiki.cancel = Annuleren
settings.projects_desc = Repository projecten inschakelen
settings.admin_code_indexer = Code indexeerder
-settings.admin_indexer_commit_sha = Laatst geรฏndexeerde SHA
+settings.admin_indexer_commit_sha = Laatst geรฏndexeerde commit
settings.reindex_button = Toevoegen aan herindexeringswachtrij
settings.reindex_requested = Herindexering aangevraagd
settings.danger_zone = Gevaren zone
@@ -2505,7 +2591,7 @@ editor.update = %s bijwerken
projects.column.unset_default_desc = Maak deze kolom ongedaan als standaard
pulls.showing_only_single_commit = Alleen veranderingen tonen van commit %[1]s
pulls.blocked_by_changed_protected_files_1 = Dit pull request is geblokkeerd omdat het een beveiligd bestand wijzigt:
-signing.wont_sign.nokey = Er is geen sleutel beschikbaar om deze commit te ondertekenen.
+signing.wont_sign.nokey = Deze instantie heeft geen sleutel om deze commmit mee te ondertekenen.
settings.admin_enable_close_issues_via_commit_in_any_branch = Sluit een issue via een commit gedaan in een niet standaard branch
stars_remove_warning = Hiermee worden alle sterren uit deze repository verwijderd.
tree_path_not_found_branch = Pad %[1]s bestaat niet in branch %[2]s
@@ -2544,7 +2630,7 @@ issues.action_check = Aanvinken/uitvinken
issues.dependency.issue_batch_close_blocked = Het is niet mogelijk om de issues die u gekozen heeft in bulk te sluiten, omdat issue #%d nog open afhankelijkheden heeft
pulls.review_only_possible_for_full_diff = Beoordeling is alleen mogelijk bij het bekijken van de volledige diff
pulls.commit_ref_at = `heeft naar deze pull request verwezen vanuit een commit %[2]s `
-pulls.cmd_instruction_hint = `Bekijk opdrachtregelinstructies .`
+pulls.cmd_instruction_hint = Bekijk opdrachtregelinstructies
pulls.cmd_instruction_checkout_desc = Vanuit uw project repository, schakel over naar een nieuwe branch en test de veranderingen.
pulls.showing_specified_commit_range = Alleen veranderingen weergeven tussen %[1]s..%[2]s
pulls.reopen_failed.base_branch = De pull request kan niet worden heropend, omdat de base branch niet meer bestaat.
@@ -2562,7 +2648,7 @@ settings.remove_protected_branch_success = Branchbescherming voor regel "%s" is
settings.remove_protected_branch_failed = Verwijderen van branchbeschermings regel "%s" is mislukt.
settings.merge_style_desc = Samenvoegstijl
settings.thread_id = Thread ID
-settings.archive.mirrors_unavailable = Mirrors zijn niet beschikbaar als de repo is gearchiveerd.
+settings.archive.mirrors_unavailable = Mirrors zijn niet beschikbaar in gearchiveerde repo's.
settings.unarchive.header = Deze repo uit het archief halen
settings.unarchive.text = Het uit het archief halen van de repo zal het vermogen herstellen om commits en pushes te ontvangen, evenals nieuwe issues en pull requests.
settings.unarchive.error = Er is een fout opgetreden bij het uit het archief halen van de repo. Bekijk de logs voor meer details.
@@ -2573,9 +2659,9 @@ release.tag_helper_existing = Bestaande tag.
release.title = Releasetitel
release.title_empty = Titel kan niet leeg zijn.
release.message = Beschrijf deze release
-release.delete_tag = Verwijder Tag
+release.delete_tag = Tag verwijderen
release.add_tag_msg = Gebruik de titel en inhoud van de release als bericht.
-release.add_tag = Alleen Tag Aanmaken
+release.add_tag = Tag aanmaken
release.releases_for = Releases voor %s
release.tags_for = Tags voor %s
branch.delete = Branch "%s" verwijderen
@@ -2583,16 +2669,16 @@ diff.review.self_approve = Auteurs van een pull request kunnen hun eigen pull re
diff.review.self_reject = Auteurs van een pull request kunnen geen wijzigingen aanvragen op hun eigen pull request
branch.already_exists = Een branch genaamd "%s" bestaat al.
settings.protected_branch_required_rule_name = Vereiste regelnaam
-settings.protect_unprotected_file_patterns_desc = Onbeschermde bestanden die direct gewijzigd mogen worden als een gebruiker schrijftoegang heeft, waarbij pushbeperking omzeild zal worden. Meerdere patronen kunnen gescheiden worden d.m.v. een puntkomma (";"). Zie github.com/gobwas/glob documentatie voor patroon syntax. Bijvoorbeeld: .drone.yml
, /docs/**/*.txt
.
-settings.tags.protection.pattern.description = U kunt een enkele naam, glob patroon of reguliere expressie gebruiken om tags te matchen. Lees meer in de beschermde tags gids .
-settings.protect_unprotected_file_patterns = Onbeschermde bestandspatronen (gescheiden d.m.v. een puntkomma ";"):
+settings.protect_unprotected_file_patterns_desc = Onbeschermde bestanden die direct gewijzigd mogen worden als een gebruiker schrijftoegang heeft, waarbij pushbeperking omzeild zal worden. Meerdere patronen kunnen gescheiden worden d.m.v. een puntkomma (";"). Zie %[2]s documentatie voor patroon syntax. Bijvoorbeeld: .drone.yml
, /docs/**/*.txt
.
+settings.tags.protection.pattern.description = U kunt een enkele naam, glob patroon of reguliere expressie gebruiken om tags te matchen. Lees meer in de beschermde tags gids .
+settings.protect_unprotected_file_patterns = Onbeschermde bestandspatronen (gescheiden d.m.v. een puntkomma ";")
branch.delete_desc = Het verwijderen van een branch is permanent. Hoewel de verwijderde branch kan blijven bestaan voor een korte tijd voordat het daadwerkelijk wordt verwijderd, kan het in de meeste gevallen NIET ongedaan gemaakt worden. Wilt u doorgaan?
release.deletion_desc = Het verwijderen van een release zal het alleen verwijderen van Forgejo. Het zal niet de Git tag, de inhoud van uw repository of de geschiedenis ervan beรฏnvloeden. Wilt u doorgaan?
release.deletion_tag_desc = Verwijdert deze tag uit de repository. De inhoud van de repository en de geschiedenis ervan zullen ongewijzigd blijven. Wilt u doorgaan?
release.tag_name_protected = De tagnaam is beschermd.
release.tag_already_exist = Deze tagnaam bestaat al.
settings.mirror_settings.docs.disabled_pull_mirror.instructions = Stel je project in om automatisch commits, tags en branches naar een andere repository te pushen. Pull mirrors zijn uitgeschakeld door de beheerder van de site.
-settings.protect_status_check_patterns = Patronen voor statuscontrole:
+settings.protect_status_check_patterns = Patronen voor statuscontrole
settings.mirror_settings.docs = Stel je repository in om automatisch commits, tags en branches te synchroniseren met een andere repository.
settings.mirror_settings.docs.disabled_push_mirror.instructions = Stel je project in om automatisch commits, tags en branches uit een andere repository te halen.
pulls.made_using_agit = AGit
@@ -2606,7 +2692,7 @@ settings.tracker_issue_style.regexp_pattern_desc = De eerste groep wordt gebruik
settings.admin_indexer_unindexed = Niet-geรฏndexeerd
settings.admin_enable_health_check = Repository gezondheidscontroles inschakelen (git fsck)
settings.admin_settings = Beheerdersinstellingen
-settings.actions_desc = Repository acties inschakelen
+settings.actions_desc = Geรฏntegreerde CI/CD-pijplijnen met Forgejo Actions inschakelen
settings.releases_desc = Repository releases inschakelen
settings.pulls.default_delete_branch_after_merge = Verwijder standaard pull request branch na samenvoegen
settings.pulls.allow_rebase_update = Het bijwerken van een pull request branch door rebase inschakelen
@@ -2616,7 +2702,7 @@ settings.trust_model.default.desc = Gebruik de standaard repository vertrouwensm
settings.signing_settings = Instellingen voor verificatie van ondertekening
settings.wiki_branch_rename_success = De branch naam van de repository wiki is succesvol genormaliseerd.
settings.wiki_rename_branch_main_notices_1 = Deze bewerking KAN NIET ongedaan worden gemaakt.
-settings.wiki_rename_branch_main_desc = Hernoem de branch die intern door de Wiki wordt gebruikt naar "%s". Dit is permanent en kan niet ongedaan gemaakt worden.
+settings.wiki_rename_branch_main_desc = Hernoem de branch die intern door de Wiki wordt gebruikt naar "%s". Deze verandering is permanent en kan niet ongedaan worden gemaakt.
settings.add_collaborator_owner = Kan geen eigenaar toevoegen als samenwerker.
settings.update_settings_no_unit = De repository moet op zijn minst enige vorm van interactie toestaan.
settings.authorization_header = Autorisatie-header
@@ -2639,9 +2725,9 @@ settings.webhook.test_delivery_desc_disabled = Om deze webhook met een nepgebeur
settings.mirror_settings.docs.no_new_mirrors = Uw repository mirrort wijzigingen van of naar een andere repository. Houd er rekening mee dat u op dit moment geen nieuwe mirrors kunt aanmaken.
settings.pulls.default_allow_edits_from_maintainers = Standaard bewerkingen van maintainers toestaan
settings.trust_model.collaboratorcommitter.desc = Geldige handtekeningen van samenwerkers van dit archief zullen "vertrouwd" gemarkeerd worden als ze overeenkomen met de committer. Anders zullen geldige handtekeningen gemarkeerd worden als "niet vertrouwd" als de handtekening overeenkomt met de committer en "niet gematcht" anders. Dit zal Forgejo dwingen om gemarkeerd te worden als de committer op ondertekende commits met de werkelijke committer gemarkeerd als Co-Authored-By: en Co-Committed-By: aanhanger in de commit. De standaard Forgejo sleutel moet overeenkomen met een gebruiker in de database.
-settings.branch_filter_desc = Branch whitelist for push, branch creation and branch deletion events, specified as glob pattern. Indien leeg of *
, worden gebeurtenissen voor alle takken gerapporteerd. Zie github.com/gobwas/glob documentatie voor syntax. Voorbeelden: master
, {master,release*}
.
+settings.branch_filter_desc = Branch whitelist for push, branch creation and branch deletion events, specified as glob pattern. Indien leeg of *
, worden gebeurtenissen voor alle takken gerapporteerd. Zie %[2]s documentatie voor syntax. Voorbeelden: master
, {master,release*}
.
contributors.contribution_type.filter_label = Soort bijdrage:
-settings.event_pull_request_review_request = Pull request beoordeling aangevraagd
+settings.event_pull_request_review_request = Beoordelingsverzoeken
pulls.recently_pushed_new_branches = Je hebt op branch gepusht %[1]s %[2]s
settings.protect_enable_merge_desc = Iedereen met schrijftoegang mogen pull requests samenvoegen in deze branch.
settings.add_web_hook_desc = Integreer %s in uw repository.
@@ -2654,28 +2740,27 @@ settings.wiki_rename_branch_main_notices_2 = Dit zal de interne branch van %s's
settings.trust_model.collaborator.desc = Geldige handtekeningen van samenwerkers van deze repository worden als "vertrouwd" gemarkeerd - (of ze nu overeenkomen met de committer of niet). Anders worden geldige handtekeningen gemarkeerd als "niet-vertrouwd" als de handtekening overeenkomt met de committer en "niet-gematcht" als dat niet het geval is.
settings.trust_model.committer.desc = Geldige handtekeningen zullen alleen "vertrouwd" gemarkeerd worden als ze overeenkomen met de committer, anders zullen ze gemarkeerd worden als "ongeรซvenaard". Dit dwingt Forgejo om de committer te zijn op ondertekende commits met de werkelijke committer gemarkeerd als Co-authored-by: en Co-committed-by: aanhanger in de commit. De standaard Forgejo sleutel moet overeenkomen met een gebruiker in de database.
settings.pulls.enable_autodetect_manual_merge = Handmatig samenvoegen met autodetectie inschakelen (Opmerking: In sommige speciale gevallen kunnen hierdoor verkeerde beoordelingen optreden)
-settings.protect_protected_file_patterns_desc = Beschermde bestanden mogen niet direct gewijzigd worden, zelfs als de gebruiker rechten heeft om bestanden in deze branch toe te voegen, te bewerken of te verwijderen. Meerdere patronen kunnen gescheiden worden met een puntkomma (";"). Zie github.com/gobwas/glob documentatie voor patroon syntax. Voorbeelden: .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns_desc = Beschermde bestanden mogen niet direct gewijzigd worden, zelfs als de gebruiker rechten heeft om bestanden in deze branch toe te voegen, te bewerken of te verwijderen. Meerdere patronen kunnen gescheiden worden met een puntkomma (";"). Zie %s documentatie voor patroon syntax. Voorbeelden: .drone.yml
, /docs/**/*.txt
.
wiki.delete_page_notice_1 = Het verwijderen van de wikipagina "%s" kan niet ongedaan worden gemaakt. Doorgaan?
wiki.reserved_page = De wikipaginanaam "%s" is gereserveerd.
activity.navbar.pulse = Puls
wiki.original_git_entry_tooltip = Bekijk het originele Git bestand in plaats van een vriendelijke link te gebruiken.
activity.navbar.contributors = Samenwerkers
contributors.contribution_type.additions = Toevoegingen
-contributors.contribution_type.commits = Commits
contributors.contribution_type.deletions = Verwijderingen
settings.mirror_settings.docs.doc_link_pull_section = het gedeelte "Pullen uit een externe repository" in de documentatie.
settings.mirror_settings.docs.doc_link_title = Hoe kan ik repositories spiegelen?
settings.mirror_settings.docs.pull_mirror_instructions = Raadpleeg voor het instellen van een pull mirror:
settings.mirror_settings.docs.more_information_if_disabled = Hier vindt u meer informatie over duw- en pull mirrors:
settings.mirror_settings.docs.pulling_remote_title = Pullen uit een externe repository
-settings.mirror_settings.pushed_repository = Pushed repository
-settings.units.units = Repository-eenheden
+settings.mirror_settings.pushed_repository = Gepusht repository
+settings.units.units = Eenheden
settings.mirror_settings.push_mirror.remote_url = Git externe repository URL
settings.units.overview = Overzicht
settings.mirror_settings.push_mirror.edit_sync_time = Synchronisatie-interval van mirror bewerken
settings.push_mirror_sync_in_progress = Wijzigingen worden momenteel naar de externe %s gepusht.
settings.pull_mirror_sync_in_progress = Haalt momenteel wijzigingen op van de externe %s.
-settings.units.add_more = Meer toevoegen...
+settings.units.add_more = Meer activeren
settings.update_mirror_settings = Mirrorinstellingen bijwerken
settings.branches.switch_default_branch = Wissel standaard branch
settings.branches.add_new_rule = Voeg nieuwe regel toe
@@ -2705,13 +2790,13 @@ activity.navbar.code_frequency = Code frequentie
activity.navbar.recent_commits = Recente commits
file_follow = Volg symlink
error.broken_git_hook = it hooks van deze repository lijken kapot te zijn. Volg alsjeblieft de documentatie om ze te repareren, push daarna wat commits om de status te vernieuwen.
-pulls.title_desc_one = wilt %[1]d commit van %[2]s
samenvoegen in %[3]s
+pulls.title_desc_one = wilt %[1]d commit van %[2]s
samenvoegen in %[3]s
open_with_editor = Open met %s
commits.search_branch = Deze branch
pulls.merged_title_desc_one = heeft %[1]d commit van %[2]s
samengevoegd in %[3]s
%[4]s
pulls.ready_for_review = Klaar voor een beoordeling?
editor.push_out_of_date = De push lijkt verouderd.
-editor.commit_id_not_matching = De commit ID komt niet overeen met degene die je aan het bewerken was. Committeer naar een nieuwe branch en voeg dan samen.
+editor.commit_id_not_matching = Het bestand is gewijzigd terwijl je het aan het bewerken was. Committeer naar een nieuwe branch en voeg dan samen.
settings.rename_branch_failed_protected = Kan branch %s niet hernoemen omdat het een beschermde branch is.
stars = Sterren
n_commit_few = %s commits
@@ -2737,8 +2822,8 @@ settings.federation_following_repos = URLs van de volgende repositories. Geschei
settings.federation_settings = Federatie instellingen
settings.federation_apapiurl = Federatie URL van deze repository. Kopiรซr en plak dit in de federatie instellingen van een andere repository als een URL van de volgende repository.
settings.federation_not_enabled = Federatie is niet ingeschakeld voor deze instantie.
-subscribe.issue.guest.tooltip = Log in om dit issue te volgen.
-subscribe.pull.guest.tooltip = Log in om dit pull request te volgen.
+subscribe.issue.guest.tooltip = Log in om deze issue te volgen.
+subscribe.pull.guest.tooltip = Log in om deze pull request te volgen.
settings.transfer.modal.title = Eigendom overdragen
settings.transfer.button = Eigendom overdragen
settings.graphql_url = GraphQL URL
@@ -2750,17 +2835,98 @@ settings.sourcehut_builds.visibility = Job zichtbaarheid
settings.sourcehut_builds.manifest_path = Bouw manifestpad
n_release_one = %s release
n_release_few = %s releases
+issues.author.tooltip.issue = Deze gebruiker is de auteur van deze issue.
+issues.author.tooltip.pr = Deze gebruiker is de auteur van deze pull request.
+settings.matrix.room_id_helper = De kamer-ID kan worden opgehaald uit de Element webclient > Kamerinstellingen > Geavanceerd > Interne ruimte ID. Voorbeeld: %s.
+issues.edit.already_changed = Kan wijzigingen in deze issue niet opslaan. Het lijkt erop dat de inhoud al is gewijzigd door een andere gebruiker. Vernieuw de pagina en probeer opnieuw te bewerken om te voorkomen dat hun wijzigingen worden overschreven
+pulls.edit.already_changed = Kan wijzigingen in deze pull request niet opslaan. Het lijkt erop dat de inhoud al is gewijzigd door een andere gebruiker. Vernieuw de pagina en probeer opnieuw te bewerken om te voorkomen dat hun wijzigingen worden overschreven
+comments.edit.already_changed = Kan wijzigingen in deze reactie niet opslaan. Het lijkt erop dat de inhoud al is gewijzigd door een andere gebruiker. Vernieuw de pagina en probeer opnieuw te bewerken om te voorkomen dat hun wijzigingen worden overschreven
+settings.sourcehut_builds.secrets_helper = Geef de job toegang tot de bouwgeheimen (SECRETS:RO toekenning vereist)
+settings.add_webhook.invalid_path = Het pad mag geen deel bevatten dat "." of ".." of de lege tekenreeks is. Het kan niet beginnen of eindigen met een schuine streep.
+settings.matrix.access_token_helper = Het is aanbevolen om hiervoor een speciale Matrix-account in te stellen. Het toegangstoken kan worden opgehaald via de Element webclient (in een besloten/incognito tabblad) > Gebruikersmenu (linksboven) > Instellingen > Hulp & Info > Geavanceerd > Toegangstoken (onder de Homeserver URL). Sluit het privรฉ/incognito tabblad (uitloggen maakt de token ongeldig).
+settings.sourcehut_builds.access_token_helper = Toegangstoken met JOBS:RW toekenning. Genereer een builds.sr.ht token of een builds.sr.ht token met toegang voor geheimen op meta.sr.ht.
+activity.commit = Commit activiteit
+milestones.filter_sort.name = Naam
+release.type_external_asset = Externe asset
+release.asset_name = Asset naam
+release.asset_external_url = Externe URL
+release.invalid_external_url = Ongeldige externe URL: โ%sโ
+release.type_attachment = Bijlage
+release.add_external_asset = Externe asset toevoegen
+activity.published_prerelease_label = Pre-versie
+activity.published_tag_label = Tag
+settings.pull_mirror_sync_quota_exceeded = Quotum overschreden, wijzigingen worden niet doorgevoerd.
+settings.transfer_quota_exceeded = De nieuwe eigenaar (%s) is over hun quotum heen. De repository is niet overgedragen.
+no_eol.text = Geen EOL
+no_eol.tooltip = Dit bestand bevat geen afsluitend regeleinde.
+pulls.cmd_instruction_merge_warning = Waarschuwing: De instelling โAutomatisch handmatig samenvoegen detecterenโ is niet ingeschakeld voor deze repository, je zult deze pull request achteraf als handmatig samengevoegd moeten markeren.
+settings.protect_new_rule = Maak een nieuwe regel voor branch beveiliging
+settings.mirror_settings.push_mirror.copy_public_key = Kopieer openbare sleutel
+mirror_use_ssh.text = SSH-authenticatie gebruiken
+mirror_denied_combination = Kan openbare sleutel en wachtwoordgebaseerde authenticatie niet combineren.
+mirror_public_key = Publieke SSH-sleutel
+mirror_use_ssh.helper = Forgejo zal deze repository mirroren via Git over SSH en een sleutelpaar voor je aanmaken als je deze optie selecteert. Je moet ervoor zorgen dat de gegenereerde publieke sleutel geautoriseerd is om naar het doel-repository te pushen. Je kunt geen wachtwoord-gebaseerde autorisatie gebruiken als je dit selecteert.
+settings.mirror_settings.push_mirror.none_ssh = Geen
+mirror_use_ssh.not_available = SSH-authenticatie is niet beschikbaar.
+issues.new.assign_to_me = Aan mij toewijzen
+issues.all_title = Alles
+settings.discord_icon_url.exceeds_max_length = Icoon-URL moet 2048 tekens of minder zijn
+issues.review.add_review_requests = beoordelingen gevraagd van %[1]s %[2]s
+issues.review.remove_review_requests = verwijderde beoordelingsverzoeken voor %[1]s %[2]s
+issues.review.add_remove_review_requests = vraagde beoordelingen van %[1]s en verwijderde beoordelingsverzoeken voor %[2]s %[3]s
+pulls.delete_after_merge.head_branch.is_default = De hoofdbranch die u wilt verwijderen is de standaard branch en kan niet verwijderd worden.
+pulls.delete_after_merge.head_branch.is_protected = De hoofdbranch die u wilt verwijderen is een beschermde branch en kan niet verwijderd worden.
+pulls.delete_after_merge.head_branch.insufficient_branch = Je hebt geen toestemming om de hoofdbranch te verwijderen.
+issues.filter_sort.relevance = Relevantie
+diff.git-notes.add = Notitie toevoegen
+diff.git-notes.remove-header = Notitie verwijderen
+diff.git-notes.remove-body = Deze notitie zal worden verwijderd.
+issues.summary_card_alt = Overzichtskaart van een issue met de titel "%s" in repository %s
+issues.num_reviews_one = %d beoordeling
+issues.num_reviews_few = %d beoordelingen
+settings.default_update_style_desc = Standaard update stijl gebruikt voor het updaten van pull requests die achter de basis branch liggen.
+pulls.sign_in_require = Aanmelden om een nieuwe pull request aan te maken.
+new_advanced = Geavanceerde instellingen
+new_advanced_expand = Klik om uit te breiden
+new_from_template_description = Je kunt een bestaand repositorysjabloon op deze instantie selecteren en de instellingen toepassen.
+new_from_template = Een sjabloon gebruiken
+auto_init_description = De Git geschiedenis starten met een README en optioneel License en .gitignore bestanden toevoegen.
+issues.reaction.add = Reactie toevoegen
+issues.reaction.alt_few = %[1]s reageerde %[2]s.
+issues.reaction.alt_add = Voeg %[1]s reactie toe aan commentaar.
+issues.context.menu = Commentaar menu
+summary_card_alt = Overzichtskaart van repository %s
+release.summary_card_alt = Samenvattende kaart van een release met de titel "%s" in repository %s
+issues.reaction.alt_remove = Verwijder %[1]s reactie van bericht.
+issues.reaction.alt_many = %[1]s en %[2]d meer gereageerd %[3]s.
+editor.commit_email = Commit e-mail
+archive.pull.noreview = Deze repository is gearchiveerd. U kunt geen pull requests beoordelen.
+commits.view_single_diff = Bekijk de veranderingen aan dit bestand die in deze commit zijn geรฏntroduceerd
+pulls.editable_explanation = Deze pull request staat bewerkingen toe van beheerders. Je kunt er direct aan bijdragen.
+pulls.editable = Bewerkbaar
+issues.reopen.blocked_by_user = U kunt deze issue niet heropenen omdat u geblokkeerd bent door de eigenaar van de repository of de poster van de issue.
+pulls.comment.blocked_by_user = U kunt niet reageren op deze pull request omdat u geblokkeerd bent door de eigenaar van de repository of de poster van de issue.
+issues.filter_no_results_placeholder = Probeer uw zoekfilters aan te passen.
+issues.filter_no_results = Geen resultaten
[graphs]
+component_loading_info = Dit kan even durenโฆ
+component_failed_to_load = Er is een onverwachte fout opgetreden.
+contributors.what = bijdragen
+component_loading_failed = %s kon niet worden geladen
+component_loading = Bezig met laden van %sโฆ
+code_frequency.what = code frequentie
+recent_commits.what = recente commits
+
[org]
org_name_holder=Organisatienaam
org_full_name_holder=Volledige naam organisatie
org_name_helper=Organisatienamen horen kort en memorabel zijn.
create_org=Nieuwe organisatie aanmaken
-repo_updated=Geupdate %s
+repo_updated=Geรผpdatet %s
members=Leden
teams=Teams
lower_members=leden
@@ -2807,9 +2973,9 @@ settings.labels_desc=Voeg labels toe die kunnen worden gebruikt bij problemen vo
members.membership_visibility=Zichtbaarheid lidmaatschap:
members.public=Zichtbaar
-members.public_helper=verborgen maken
+members.public_helper=Verborgen maken
members.private=Verborgen
-members.private_helper=maak zichtbaar
+members.private_helper=Maak zichtbaar
members.member_role=Rol van lid:
members.owner=Eigenaar
members.member=Lid
@@ -2819,7 +2985,7 @@ members.invite_desc=Voeg nieuw lid toe aan %s:
members.invite_now=Nu uitnodigen
teams.join=Lid worden
-teams.leave=Vertlaat
+teams.leave=Verlaat
teams.can_create_org_repo=Maak repositories
teams.can_create_org_repo_helper=Leden kunnen nieuwe repositories aanmaken in de organisatie. De maker krijgt beheerder toegang tot de nieuwe repository.
teams.read_access=Gelezen
@@ -2839,7 +3005,7 @@ teams.delete_team_desc=Het verwijderen van een team heeft de toegang tot de repo
teams.delete_team_success=Het team is verwijderd.
teams.read_permission_desc=Dit team heeft Lees rechten: leden kunnen repositories lezen en klonen.
teams.write_permission_desc=Dit team heeft Schrijf rechten: leden kunnen repositories lezen en push aanvragen verwerken.
-teams.admin_permission_desc=Dit team heeft beheersrechten : leden kunnen van en naar teamrepositories pullen, pushen, en er medewerkers aan toevoegen.
+teams.admin_permission_desc=Deze team heeft Beheerder rechten: leden kunnen van en naar teamrepositories pullen, pushen, en er medewerkers aan toevoegen.
teams.create_repo_permission_desc=Daarnaast verleent dit team Maak repository permissie: leden kunnen nieuwe repositories maken in de organisatie.
teams.repositories=Teamrepositories
teams.search_repo_placeholder=Repository zoekenโฆ
@@ -2856,8 +3022,8 @@ teams.all_repositories=Alle repositories
teams.all_repositories_helper=Team heeft toegang tot alle repositories. Door dit te selecteren worden alle bestaande repositories aan het team toegevoegd.
teams.all_repositories_read_permission_desc=Dit team heeft Lees toegang tot alle repositories : leden kunnen repositories bekijken en klonen.
teams.none_access = Geen toegang
-teams.none_access_helper = Leden kunnen op deze eenheid kunnen geen actie ondernemen of zien. Het heeft geen effect op openbare repositories.
-teams.general_access = Globale toegang
+teams.none_access_helper = De optie "geen toegang" heeft alleen effect op privรฉ repositories.
+teams.general_access = Aangepaste toegang
follow_blocked_user = Je kunt deze organisatie niet volgen omdat deze organisatie je geblokkeerd heeft.
code = Broncode
form.name_reserved = De organisatienaam "%s" is gereserveerd.
@@ -2865,8 +3031,8 @@ form.name_pattern_not_allowed = Het patroon "%s' is niet toegestaan in een organ
settings.email = Contact e-mail
settings.change_orgname_redirect_prompt = De oude naam zal worden omgeleid tot het wordt geclaimd.
members.remove.detail = %[1]s van %[2]s verwijderen?
-members.leave.detail = %s verlaten?
-teams.leave.detail = %s verlaten?
+members.leave.detail = Weet u zeker dat je organisatie "%s" wilt verlaten?
+teams.leave.detail = Weet u zeker dat je team โ%sโ wilt verlaten?
teams.general_access_helper = De machtigingen van de leden zullen worden vastgesteld door middel van de onderstaande tabel.
teams.write_access = Schrijf
teams.invite_team_member = Uitnodigen tot %s
@@ -2876,10 +3042,12 @@ teams.invite.description = Klik op onderstaande knop om u bij het team aan te sl
teams.invite.by = Uitgenodigd door %s
teams.all_repositories_admin_permission_desc = Dit team verleent Administrator permissies tot alle repositories : leden kunnen lezen, pushen naar en samenwerkers toevoegen aan repositories.
settings.change_orgname_prompt = Merk op: Het wijzigen van de organisatienaam zal ook de URL van uw organisatie veranderen en de oude naam vrijgeven.
-settings.visibility.limited = Beperkt (alleen zichtbaar voor geauthenticeerde gebruikers)
+settings.visibility.limited = Beperkt (alleen zichtbaar voor ingelogde gebruikers)
teams.add_nonexistent_repo = De repository die u probeert toe te voegen bestaat niet, maak deze eerst aan alstublieft.
teams.all_repositories_write_permission_desc = Dit team verleent Schrijf permissies tot alle repositories : leden kunnen lezen en pushen naar repositories.
open_dashboard = Open dashboard
+settings.change_orgname_redirect_prompt.with_cooldown.one = De oude organisatienaam zal voor iedereen beschikbaar zijn na een afkoelperiode van %[1]d dag. U kunt de oude naam nog steeds opeisen tijdens de afkoelperiode.
+settings.change_orgname_redirect_prompt.with_cooldown.few = De oude organisatienaam zal voor iedereen beschikbaar zijn na een afkoelperiode van %[1]d dagen. U kunt de oude naam nog steeds opeisen tijdens de afkoelperiode.
[admin]
dashboard=Overzicht
@@ -2962,7 +3130,7 @@ dashboard.gc_times=GC verwerkingen
dashboard.delete_old_system_notices=Verwijder alle oude systeemmededelingen uit de database
users.user_manage_panel=Gebruikersaccounts beheren
-users.new_account=Nieuw account aanmaken
+users.new_account=Gebruikersaccount aanmaken
users.name=Gebruikersnaam
users.full_name=Volledige naam
users.activated=Geactiveerd
@@ -2973,7 +3141,7 @@ users.repos=Repos
users.created=Aangemaakt
users.last_login=Laatste keer ingelogd
users.never_login=Nooit ingelogd
-users.send_register_notify=Stuur gebruikersregistratie notificatie
+users.send_register_notify=Via e-mail informeren over registratie
users.edit=Bewerken
users.auth_source=Authenticatiebron
users.local=Lokaal
@@ -2983,10 +3151,10 @@ users.update_profile_success=Het gebruikersaccount is bijgewerkt.
users.edit_account=Wijzig gebruikers account
users.max_repo_creation=Maximale aantal repositories
users.max_repo_creation_desc=(Zet op -1 om de globale limiet te gebruiken)
-users.is_activated=Gebruikersaccount is geactiveerd
-users.prohibit_login=Inloggen uitschakelen
-users.is_admin=Is beheerder
-users.is_restricted=Is beperkt
+users.is_activated=Geactiveerd account
+users.prohibit_login=Geschorst account
+users.is_admin=Beheerdersaccount
+users.is_restricted=Beperkte account
users.allow_git_hook=Mag Git hooks maken
users.allow_git_hook_tooltip=Git hooks worden uitgevoerd als de OS-gebruiker die Forgejo uitvoert en zal hetzelfde niveau van host toegang hebben. Als gevolg daarvan hebben gebruikers met dit speciale Git hook privilege toegang tot alle Forgejo repositories en de door Forgejo gebruikte database. Zij zijn dus ook in staat om Forgejo beheerdersprivileges te verkrijgen.
users.allow_import_local=Mag lokale repositories importeren
@@ -3022,7 +3190,7 @@ orgs.new_orga=Nieuwe organisatie
repos.repo_manage_panel=Repositories beheren
repos.unadopted=Niet-geadopteerde repositories
-repos.unadopted.no_more=Geen niet-geadopteerde repositories meer gevonden
+repos.unadopted.no_more=Geen niet-geadopteerde repositories gevonden.
repos.owner=Eigenaar
repos.name=Naam
repos.private=Prive
@@ -3106,13 +3274,13 @@ auths.tips=Tips
auths.tips.oauth2.general=OAuth2 authenticatie
auths.tip.oauth2_provider=OAuth2 provider
auths.tip.nextcloud=`Registreer een nieuwe OAuth consument op je installatie met behulp van het volgende menu "Instellingen -> Security -> OAuth 2.0 client"`
-auths.tip.dropbox=Maak een nieuwe applicatie aan op https://www.dropbox.com/developers/apps
-auths.tip.facebook=Registreer een nieuwe applicatie op https://developers.facebook.com/apps en voeg het product "Facebook Login" toe
-auths.tip.github=Registreer een nieuwe OAuth toepassing op https://github.com/settings/applications/new
+auths.tip.dropbox=Maak een nieuwe applicatie aan op %s
+auths.tip.facebook=Registreer een nieuwe applicatie op %s en voeg het product "Facebook Login" toe
+auths.tip.github=Registreer een nieuwe OAuth toepassing op %s
auths.tip.gitlab=Registreer een nieuwe applicatie op https://gitlab.com/profile/applicaties
-auths.tip.google_plus=Verkrijg OAuth2 client referenties van de Google API console op https://console.developers.google.com/
+auths.tip.google_plus=Verkrijg OAuth2 client referenties van de Google API console op %s
auths.tip.openid_connect=Gebruik de OpenID Connect Discovery URL (/.well-known/openid-configuration) om de eindpunten op te geven
-auths.tip.yandex=`Maak een nieuwe applicatie aan op https://oauth.yandex.com/client/new. Selecteer de volgende machtigingen van de "Yandex". assport API sectie: "Toegang tot e-mailadres", "Toegang tot avatar" en "Toegang tot gebruikersnaam, voornaam en achternaam, geslacht"`
+auths.tip.yandex=Maak een nieuwe toepassing op %s. Selecteer de volgende rechten in het gedeelte โYandex.Passport APIโ: โToegang tot e-mailadresโ, โToegang tot gebruikersavatarโ en โToegang tot gebruikersnaam, voor- en achternaam, geslachtโ
auths.edit=Authenticatiebron bewerken
auths.activated=Deze authenticatiebron is geactiveerd
auths.update_success=De authenticatie-bron is bijgewerkt.
@@ -3232,7 +3400,7 @@ config.git_max_diff_lines=Max diff regels per bestand
config.git_max_diff_files=Max. getoonde diff-bestanden
config.git_gc_args=GC-argumenten
config.git_migrate_timeout=Migratie time-out
-config.git_mirror_timeout=Time-out spiegelupdate
+config.git_mirror_timeout=Time-out mirror update
config.git_clone_timeout=Kloon operatie timeout
config.git_pull_timeout=Pull operatie timeout
config.git_gc_timeout=GC operatie timeout
@@ -3308,7 +3476,7 @@ users.list_status_filter.not_prohibit_login = Inloggen toestaan
users.list_status_filter.is_2fa_enabled = 2FA ingeschakeld
users.details = Gebruikersgegevens
emails.change_email_text = Weet je zeker dat je dit e-mailadres wilt bijwerken?
-repos.lfs_size = LFS Grootte
+repos.lfs_size = LFS grootte
packages.package_manage_panel = Pakketten beheren
packages.total_size = Totale grootte: %s
packages.unreferenced_size = Grootte waarnaar niet wordt verwezen: %s
@@ -3333,28 +3501,28 @@ auths.oauth2_required_claim_value_helper = Stel deze waarde in om het aanmelden
users.remote = Externe
users.list_status_filter.not_2fa_enabled = 2FA uitgeschakeld
users.reserved = Gereserveerd
-defaulthooks.desc = Webhooks doen automatisch HTTP POST verzoeken naar een server wanneer bepaalde Forgejo gebeurtenissen zich voordoen. Webhooks die hier gedefinieerd zijn, zijn standaard en worden gekopieerd naar alle nieuwe repositories.. Lees meer in de webhooks gids .
+defaulthooks.desc = Webhooks doen automatisch HTTP POST verzoeken naar een server wanneer bepaalde Forgejo gebeurtenissen zich voordoen. Webhooks defined here are defaults and will be copied into all new repositories. Read more in the webhooks guide .
auths.verify_group_membership = Controleer het groepslidmaatschap in LDAP (laat het filter leeg om over te slaan)
dashboard.rebuild_issue_indexer = Herbouw issue indexer
-systemhooks.desc = Webhooks doen automatisch HTTP POST verzoeken naar een server wanneer bepaalde Forgejo gebeurtenissen zich voordoen. Webhooks die hier gedefinieerd zijn, werken op alle repositories op het systeem, dus houd rekening met mogelijke gevolgen voor de prestaties. Lees meer in de webhooks gids .
+systemhooks.desc = Webhooks doen automatisch HTTP POST verzoeken naar een server wanneer bepaalde Forgejo gebeurtenissen zich voordoen. Webhooks die hier gedefinieerd zijn, werken op alle repositories op het systeem, dus houd rekening met mogelijke gevolgen voor de prestaties. Lees meer in de webhooks guide .
hooks = Webhooks
integrations = Integraties
-dashboard.new_version_hint = Forgejo %s is nu beschikbaar, u gebruikt versie %s. Zie de blog voor meer details.
+dashboard.new_version_hint = Forgejo %s is nu beschikbaar, u gebruikt versie %s. Zie de blog voor meer details.
dashboard.sync_repo_tags = Tags synchroniseren van git data naar database
dashboard.cleanup_hook_task_table = Tabel hook_task opschonen
dashboard.cleanup_packages = Verlopen pakketten opschonen
dashboard.cleanup_actions = Verlopen logs en artefacten van actions opschonen
-dashboard.delete_old_actions.started = Het verwijderen van alle oude acties uit de database is gestart.
+dashboard.delete_old_actions.started = Het verwijderen van alle oude activiteiten uit de database is gestart.
dashboard.update_checker = Update checker
dashboard.stop_zombie_tasks = Zombietaken stoppen
dashboard.stop_endless_tasks = Eindeloze taken stoppen
dashboard.start_schedule_tasks = Start geplande taken
-dashboard.sync_branch.started = Branches synchroniseren is gestart
-dashboard.sync_tag.started = Tags synchroniseren is gestart
+dashboard.sync_branch.started = Branch synchronisatie is gestart
+dashboard.sync_tag.started = Tag synchronisatie is gestart
auths.attribute_avatar = Avatar attribuut
auths.enable_ldap_groups = LDAP-groepen inschakelen
auths.ms_ad_sa = MS AD zoekattributen
-dashboard.delete_old_actions = Verwijder alle oude acties uit de database
+dashboard.delete_old_actions = Verwijder alle oude activiteiten uit de database
identity_access = Identiteit & toegang
assets = Code assets
auths.helo_hostname_helper = Hostnaam verzonden met HELO. Laat leeg om huidige hostnaam te versturen.
@@ -3373,7 +3541,7 @@ self_check.database_inconsistent_collation_columns = Database gebruikt collatie
monitor.stacktrace = Stacktrace
monitor.download_diagnosis_report = Diagnoserapport downloaden
self_check.database_collation_case_insensitive = Database gebruikt collatie %s, wat een ongevoelige collatie is. Hoewel Forgejo ermee kan werken, kunnen er enkele zeldzame gevallen zijn die niet werken zoals verwacht.
-self_check.database_fix_mysql = Voor MySQL/MariaDB gebruikers zou je het "gitea doctor convert" commando kunnen gebruiken om de collatieproblemen op te lossen, of je zou het probleem ook kunnen oplossen door "ALTER ... COLLATE ..." SQL's handmatig op te lossen.
+self_check.database_fix_mysql = Voor MySQL/MariaDB gebruikers zou je het "forgejo doctor convert" commando kunnen gebruiken om de collatieproblemen op te lossen, of je zou het probleem ook kunnen oplossen door "ALTER ... COLLATE ..." SQL's handmatig op te lossen.
dashboard.gc_lfs = LFS meta-objecten afval opruimen
auths.map_group_to_team = Breng LDAP-groepen in kaart voor organisatieteams (laat het veld leeg om over te slaan)
auths.oauth2_required_claim_name = Verplichte claimnaam
@@ -3382,9 +3550,9 @@ auths.skip_local_two_fa_helper = Niet ingesteld betekent dat lokale gebruikers m
auths.skip_local_two_fa = Lokale 2FA overslaan
auths.oauth2_icon_url = Pictogram URL
auths.pam_email_domain = PAM e-maildomein (optioneel)
-auths.tip.gitea = Registreer een nieuwe OAuth2-toepassing. De handleiding is te vinden op https://forgejo.org/docs/latest/user/oauth2-provider
-auths.tip.discord = Registreer een nieuwe toepassing op https://discordapp.com/developers/applications/me
-auths.tip.bitbucket = Registreer een nieuwe OAuth consumer op https://bitbucket.org/account/user//oauth-consumers/new en voeg de rechten "Account" - "Read"
+auths.tip.gitea = Registreer een nieuwe OAuth2-toepassing. De handleiding is te vinden op %s
+auths.tip.discord = Registreer een nieuwe toepassing op %s
+auths.tip.bitbucket = Registreer een nieuwe OAuth consumer op %s en voeg de rechten โAccountโ - โReadโ toe
auths.tips.oauth2.general.tip = Bij het registreren van een nieuwe OAuth2-authenticatie moet de callback/redirect URL zijn:
config.ssh_domain = SSH-server domein
auths.login_source_of_type_exist = Er bestaat al een authenticatiebron van dit type.
@@ -3401,7 +3569,7 @@ auths.unable_to_initialize_openid = OpenID Connect Provider kan niet worden geรฏ
auths.new_success = De authenticatiebron "%s" is toegevoegd.
auths.delete_auth_desc = Door een authenticatiebron te verwijderen, kunnen gebruikers deze niet meer gebruiken om zich aan te melden. Doorgaan?
auths.tip.mastodon = Voer een aangepaste instantie URL in voor de mastodon instantie waarmee je wilt authenticeren (of gebruik de standaard URL)
-auths.tip.twitter = Ga naar https://dev.twitter.com/apps, maak een applicatie en zorg ervoor dat de optie "Sta toe dat deze applicatie wordt gebruikt om u aan te melden bij Twitter" is ingeschakeld
+auths.tip.twitter = Ga naar %s, maak een applicatie en zorg ervoor dat de optie "Sta toe dat deze applicatie wordt gebruikt om u aan te melden bij Twitter" is ingeschakeld
auths.disable_helo = HELO uitschakelen
auths.force_smtps_helper = SMTPS wordt altijd gebruikt op poort 465. Stel dit in om SMTPS op andere poorten te forceren. (Anders wordt STARTTLS gebruikt op andere poorten als dit wordt ondersteund door de host)
auths.invalid_openIdConnectAutoDiscoveryURL = Ongeldige URL voor automatische detectie (dit moet een geldige URL zijn die begint met http:// of https://)
@@ -3420,9 +3588,24 @@ config_settings = Instellingen
auths.tips.gmail_settings = Gmail instellingen:
config_summary = Samenvatting
config.open_with_editor_app_help = De "Openen met" editors voor het kloonmenu. Als deze leeg blijft, wordt de standaardwaarde gebruikt. Uitvouwen om de standaard te zien.
-auths.tip.gitlab_new = Registreer een nieuwe applicatie op https://gitlab.com/-/profile/applications
+auths.tip.gitlab_new = Registreer een nieuwe applicatie op %s
config.app_slogan = Instantie slogan
auths.default_domain_name = Standaarddomeinnaam die voor het e-mailadres wordt gebruikt
+config.cache_test = Test cache
+config.cache_test_succeeded = Cache test succesvol, kreeg een antwoord in %s.
+users.activated.description = Voltooiing van e-mailverificatie. De eigenaar van een niet-geactiveerd account kan zich pas aanmelden nadat de e-mailverificatie is voltooid.
+users.block.description = Blokkeer deze gebruiker voor interactie met deze service via zijn account en verbied het aanmelden.
+users.admin.description = Geef deze gebruiker volledige toegang tot alle beheerfuncties die beschikbaar zijn via de web UI en de API.
+users.restricted.description = Sta alleen interactie toe met de repositories en organisaties waar deze gebruiker als samenwerker is toegevoegd. Dit voorkomt toegang tot openbare repositories op deze instantie.
+users.local_import.description = Sta het importeren van repositories vanaf het lokale bestandssysteem van de server toe. Dit kan een beveiligingsprobleem zijn.
+users.organization_creation.description = Sta het aanmaken van nieuwe organisaties toe.
+config.cache_test_failed = Het is niet gelukt om de cache te peilen: %v.
+config.cache_test_slow = Cache-test geslaagd, maar reactie is traag: %s.
+emails.delete_desc = Weet u zeker dat u deze e-mailadres wilt verwijderen?
+emails.delete_primary_email_error = U kunt de primaire e-mail niet verwijderen.
+emails.delete = E-mail verwijderen
+emails.deletion_success = Het e-mailadres is verwijderd.
+monitor.duration = Duur (s)
[action]
@@ -3438,13 +3621,13 @@ comment_issue = `gaf reactie op issue %[3]s#%[2]s `
comment_pull = `gaf reactie op pull request %[3]s#%[2]s `
merge_pull_request = `pull request samengevoegd %[3]s#%[2]s `
push_tag = tag %[3]s gepusht naar %[4]s
-mirror_sync_create = nieuwe referentie gesynchroniseerd naar %[3]s op %[4]s van spiegel
+mirror_sync_create = nieuwe referentie gesynchroniseerd naar %[3]s op %[4]s van mirror
approve_pull_request = `goedgekeurd %[3]s#%[2]s `
reopen_pull_request = `heropend pull request %[3]s#%[2]s `
close_pull_request = `sloot pull request %[3]s#%[2]s `
-mirror_sync_delete = gesynchroniseerde en verwijderde referentie %[2]s
op %[3]s van spiegel
+mirror_sync_delete = gesynchroniseerde en verwijderde referentie %[2]s
op %[3]s van mirror
auto_merge_pull_request = `pull request automatisch samengevoegd %[3]s#%[2]s `
-mirror_sync_push = commits gesynchroniseerd naar %[3]s op %[4]s van spiegel
+mirror_sync_push = commits gesynchroniseerd naar %[3]s op %[4]s van mirror
review_dismissed_reason = Reden:
commit_repo = gepusht naar %[3]s bij %[4]s
create_issue = `opent issue %[3]s#%[2]s `
@@ -3455,7 +3638,7 @@ reject_pull_request = `stelde wijzigingen voor %[3]s#%[2]s `
review_dismissed = `heeft beoordeling van %[4]s voor %[3]s#%[2]s afgewezen`
create_branch = heeft de branch %[3]s gemaakt in %[4]s
watched_repo = begon te kijken naar %[2]s
-publish_release = `released "%[4]s" op %[3]s `
+publish_release = `released %[4]s op %[3]s `
starred_repo = heeft %[2]s een star gegeven
[tool]
@@ -3548,16 +3731,16 @@ cargo.install = Voer de volgende opdracht uit om het pakket met Cargo te install
chef.install = Voer het volgende commando uit om het pakket te installeren:
composer.registry = Stel dit register in je ~/.composer/config.json
bestand:
composer.dependencies = Afhankelijkheden
-composer.dependencies.development = Ontwikkelings Afhankelijkheden
+composer.dependencies.development = Ontwikkelings afhankelijkheden
conan.registry = Stel dit register in vanaf de terminal:
conan.install = Voer het volgende commando uit om het pakket met Conan te installeren:
conda.registry = Stel dit register in als een Conda repository in je .condarc
bestand:
-container.details.type = Afbeelding Type
+container.details.type = Afbeelding type
container.details.platform = Platform
container.pull = Haal de afbeelding op vanaf de terminal:
-container.digest = Digest:
+container.digest = Digest
container.multi_arch = Besturingssysteem / Arch
-container.layers = Afbeelding Lagen
+container.layers = Afbeelding lagen
container.labels = Labels
container.labels.key = Sleutel
debian.repository = Repository informatie
@@ -3579,7 +3762,7 @@ rpm.repository.architectures = Architecturen
rpm.repository.multiple_groups = Dit pakket is beschikbaar in meerdere groepen.
rubygems.install = Voer het volgende commando uit om het pakket met gem te installeren:
rubygems.install2 = of voeg het toe aan het Gemfile:
-rubygems.dependencies.development = Ontwikkelings Dependencies
+rubygems.dependencies.development = Ontwikkelings dependencies
swift.registry = Stel dit register in vanaf de terminal:
swift.install = Voeg het pakket toe in je Package.swift
bestand:
swift.install2 = en voer het volgende commando uit:
@@ -3597,7 +3780,7 @@ nuget.install = Voer het volgende commando uit om het pakket met NuGet te instal
npm.install = Voer het volgende commando uit om het pakket met npm te installeren:
npm.install2 = of voeg het toe aan het package.json bestand:
npm.dependencies = Afhankelijkheden
-npm.dependencies.development = Ontwikkelings Afhankelijkheden
+npm.dependencies.development = Ontwikkelings afhankelijkheden
npm.dependencies.peer = Peer afhankelijkheden
npm.dependencies.optional = Optionele afhankelijkheden
owner.settings.cargo.title = Cargo register index
@@ -3608,7 +3791,7 @@ owner.settings.cargo.rebuild = Index herbouwen
owner.settings.cargo.rebuild.description = Heropbouwen kan nuttig zijn als de index niet is gesynchroniseerd met de opgeslagen Cargo pakketten.
owner.settings.cargo.rebuild.error = Mislukt om Cargo index te herbouwen: %v
owner.settings.cargo.rebuild.success = De Cargo index is met succes opnieuw opgebouwd.
-owner.settings.cleanuprules.title = Opschoonregels beheren
+owner.settings.cleanuprules.title = Opschoonregels
owner.settings.cleanuprules.add = Regel voor opschonen toevoegen
owner.settings.cleanuprules.edit = Regel voor opschonen bewerken
owner.settings.cleanuprules.preview = Voorbeeld opruimregel
@@ -3619,7 +3802,7 @@ owner.settings.cleanuprules.keep.count = Bewaar de meest recente
owner.settings.cleanuprules.keep.count.1 = 1 versie per pakket
owner.settings.cleanuprules.keep.count.n = %d versies per pakket
pub.install = Voer het volgende commando uit om het pakket met Dart te installeren:
-rubygems.dependencies.runtime = Runtime Dependencies
+rubygems.dependencies.runtime = Runtime dependencies
settings.delete.error = Het verwijderen van het pakket is mislukt.
alpine.registry = Stel dit register in door de url toe te voegen aan je /etc/apk/repositories
bestand:
maven.registry = Stel dit register in het pom.xml
bestand van je project:
@@ -3667,6 +3850,31 @@ versions.view_all = Alles weergeven
filter.type.all = Alle
owner.settings.cargo.rebuild.no_index = Kan niet herbouwen, er is geen index geรฏnitialiseerd.
npm.dependencies.bundle = Gebundelde dependencies
+arch.version.depends = Afhankelijk van
+arch.pacman.helper.gpg = Vertrouwenscertificaat toevoegen voor pacman:
+arch.pacman.repo.multi = %s heeft dezelfde versie in verschillende distributies.
+arch.pacman.repo.multi.item = Configuratie voor %s
+arch.pacman.conf = Voeg server met gerelateerde distributie en architectuur toe aan /etc/pacman.conf
:
+arch.pacman.sync = Synchroniseer pakket met pacman:
+arch.version.properties = Versie-eigenschappen
+arch.version.description = Beschrijving
+arch.version.provides = Biedt
+arch.version.groups = Groep
+arch.version.optdepends = Optioneel is afhankelijk van
+arch.version.checkdepends = Controleer is afhankelijk van
+arch.version.conflicts = Conflicten
+arch.version.replaces = Vervangt
+arch.version.backup = Back-up
+arch.version.makedepends = Maken is afhankelijk van
+container.images.title = Afbeeldingen
+search_in_external_registry = Zoeken in %s
+alt.registry.install = Voer het volgende commando uit om het pakket te installeren:
+alt.repository = Repository info
+alt.repository.architectures = Architecturen
+alt.repository.multiple_groups = Dit pakket is beschikbaar in meerdere groepen.
+alt.registry = Stel dit register in vanaf de opdrachtregel:
+alt.install = Pakket installeren
+alt.setup = Voeg een repository toe aan de lijst met gekoppelde repositories (kies de benodigde architectuur in plaats van "_arch_"):
[secrets]
secrets = Geheimen
@@ -3684,9 +3892,6 @@ creation.name_placeholder = hoofdlettergevoelig, alleen alfanumerieke tekens of
deletion.failed = Mislukt om geheim te verwijderen.
[actions]
-
-
-
runners.name=Naam
runners.owner_type=Type
runners.description=Omschrijving
@@ -3761,7 +3966,7 @@ runs.actors_no_select = Alle acteurs
runs.status_no_select = Alle statussen
runs.no_results = Geen resultaten gevonden.
runs.no_workflows = Er zijn nog geen workflows.
-unit.desc = Beheer actions
+unit.desc = Beheer geรฏntegreerde CI/CD-pijplijnen met Forgejo Actions.
runs.no_workflows.documentation = Voor meer informatie over Forgejo acties, zie de documentatie .
workflow.disable_success = Workflow "%s" is succesvol uitgeschakeld.
variables.none = Er zijn nog geen variabelen.
@@ -3774,6 +3979,17 @@ runs.no_matching_online_runner_helper = Geen overeenkomende online runner met la
runs.workflow = Workflow
runs.no_job_without_needs = De workflow moet ten minste รฉรฉn taak zonder afhankelijkheden bevatten.
runs.no_job = De workflow moet minimaal รฉรฉn job bevatten
+workflow.dispatch.trigger_found = Deze workflow heeft een workflow_dispatch event trigger.
+workflow.dispatch.success = Workflow-run is met succes aangevraagd.
+workflow.dispatch.use_from = Gebruik workflow van
+workflow.dispatch.run = Workflow uitvoeren
+workflow.dispatch.warn_input_limit = Alleen de eerste %d invoeren worden weergegeven.
+workflow.dispatch.invalid_input_type = Ongeldig invoertype โ%sโ.
+workflow.dispatch.input_required = Waarde vereist voor invoer โ%sโ.
+runs.expire_log_message = Logs zijn verwijderd omdat ze te oud waren.
+runs.no_workflows.help_no_write_access = Om meer te weten te komen over Forgejo Acties, zie de documentatie .
+runs.no_workflows.help_write_access = Weet je niet hoe je moet beginnen met Forgejo Actions? Bekijk de snelstart in de gebruikersdocumentatie om je eerste workflow te schrijven en stel vervolgens een Forgejo runner in om je jobs uit te voeren.
+variables.not_found = De variabele kon niet gevonden worden.
@@ -3782,9 +3998,9 @@ runs.no_job = De workflow moet minimaal รฉรฉn job bevatten
type-1.display_name = Individueel project
type-2.display_name = Repository project
type-3.display_name = Organisatie project
+deleted.display_name = Verwijderd project
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=Symbolische link
submodule = Submodule
changed_filemode = %[1]s โ %[2]s
@@ -3794,31 +4010,21 @@ executable_file = Uitvoerbaar bestand
-[graphs]
-component_loading_info = Dit kan even durenโฆ
-component_failed_to_load = Er is een onverwachte fout opgetreden.
-contributors.what = bijdragen
-component_loading_failed = %s kon niet worden geladen
-component_loading = Bezig met laden van %s...
-code_frequency.what = code frequentie
-recent_commits.what = recente commits
-
-
[search]
-search = Zoek...
+search = Zoekโฆ
fuzzy = Fuzzy
match = Overeenkomen
match_tooltip = Alleen resultaten opnemen die exact overeenkomen met de zoekterm
-repo_kind = Zoek repos...
-user_kind = Zoek gebruikers...
-org_kind = Zoek orgs...
-team_kind = Zoek teams...
-code_kind = Zoek code...
-package_kind = Zoek pakketten...
-project_kind = Zoek projecten...
-branch_kind = Zoek branches...
-commit_kind = Zoek commits...
-runner_kind = Zoek runners...
+repo_kind = Zoek reposโฆ
+user_kind = Zoek gebruikersโฆ
+org_kind = Zoek orgsโฆ
+team_kind = Zoek teamsโฆ
+code_kind = Zoek codeโฆ
+package_kind = Zoek pakkettenโฆ
+project_kind = Zoek projectenโฆ
+branch_kind = Zoek branchesโฆ
+commit_kind = Zoek commitsโฆ
+runner_kind = Zoek runnersโฆ
no_results = Geen overeenkomende resultaten gevonden.
type_tooltip = Zoektype
fuzzy_tooltip = Neem resultaten op die ook sterk overeenkomen met de zoekterm
@@ -3827,8 +4033,13 @@ keyword_search_unavailable = Zoeken op trefwoord is momenteel niet beschikbaar.
code_search_by_git_grep = Huidige code zoekresultaten worden geleverd door "git grep". Er kunnen betere resultaten zijn als de sitebeheerder code indexer inschakelt.
exact = Exact
exact_tooltip = Bevat alleen resultaten die de exacte zoekterm bevatten
-issue_kind = Zoek issues...
-pull_kind = Zoek pulls...
+issue_kind = Zoek issuesโฆ
+pull_kind = Zoek pullsโฆ
+union = Trefwoorden
+union_tooltip = Neem resultaten op die overeenkomen met een van de trefwoorden gescheiden door spaties
+milestone_kind = Zoek mijlpalen...
+regexp_tooltip = Interpreteer de zoekterm als een reguliere expressie
+regexp = RegExp
[munits.data]
b = B
@@ -3843,3 +4054,27 @@ pib = PiB
filepreview.line = Lijn %[1]d in %[2]s
filepreview.lines = Lijnen %[1]d naar %[2]d in %[3]s
filepreview.truncated = Voorbeeld is ingekort
+
+
+[translation_meta]
+test = Okรฉ
+
+[repo.permissions]
+code.write = Schrijven: Push naar de repositorie, maak branches en tags.
+code.read = Lezen: Toegang en clone de code van de repository.
+issues.read = Lezen: Lees en maak issues en commentaren.
+pulls.read = Lezen: Lezen en pull requests maken.
+releases.read = Lezen: Bekijk en download releases.
+ext_issues = Toegang tot de link naar een externe issue tracker. De rechten worden extern beheerd.
+ext_wiki = Toegang tot de link naar een externe wiki. De rechten worden extern beheerd.
+actions.write = Write: Handmatig starten, herstarten, annuleren of goedkeuren van hangende CI/CD-pijplijnen.
+pulls.write = Schrijven: Sluit pull requests af en beheer metadata zoals labels, mijlpalen, verantwoordelijken, vervaldatums en afhankelijkheden.
+releases.write = Schrijven: Publiceren, bewerken en verwijderen van releases en hun assets.
+wiki.read = Lezen: Lees de geรฏntegreerde wiki en zijn geschiedenis.
+wiki.write = Schrijven: Pagina's maken, bijwerken en verwijderen in de geรฏntegreerde wiki.
+projects.read = Lezen: Toegang tot projectboards van repository's.
+projects.write = Schrijven: Projecten en kolommen maken en bewerken.
+packages.read = Lezen: Bekijk en download pakketten die aan de repository is toegewezen.
+packages.write = Schrijven: Publiceer en verwijder pakketten die aan de repository is toegewezen.
+actions.read = Lezen: Bekijk geรฏntegreerde CI/CD-pijplijnen en hun logboeken.
+issues.write = Schrijven: Sluit issues af en beheer metadata zoals labels, mijlpalen, verantwoordelijken, vervaldatums en afhankelijkheden.
diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini
index f2bc34d711..f7bb6f3294 100644
--- a/options/locale/locale_pl-PL.ini
+++ b/options/locale/locale_pl-PL.ini
@@ -29,8 +29,8 @@ password=Hasลo
access_token=Token dostฤpu
re_type=Potwierdลบ hasลo
captcha=CAPTCHA
-twofa=Autoryzacja dwuskลadnikowa
-twofa_scratch=Kod jednorazowy weryfikacji dwuetapowej
+twofa=Uwierzytelnianie dwuskลadnikowe
+twofa_scratch=Kod jednorazowy uwierzytelniania dwuskลadnikowego
passcode=Kod dostฤpu
webauthn_insert_key=Podลฤ
cz swรณj klucz bezpieczeลstwa
@@ -71,7 +71,7 @@ collaborative=Wspรณลtworzone
forks=Forki
activities=Aktywnoลci
-pull_requests=Oczekujฤ
ce zmiany
+pull_requests=Pull requesty
issues=Zgลoszenia
milestones=Kamienie milowe
@@ -128,7 +128,7 @@ retry = Ponรณw
view = Widok
go_back = Wrรณฤ
filter = Filtr
-confirm_delete_artifact = Jesteล penwy ลผe chcesz usunฤ
ฤ artefakt "%s"?
+confirm_delete_artifact = Jesteล pewny(-na) ลผe chcesz usunฤ
ฤ artefakt "%s"?
concept_system_global = Globalne
concept_user_individual = Indywidualny
filter.clear = Wyczyลฤ filtry
@@ -148,30 +148,40 @@ filter.public = Publiczne
filter.private = Prywatne
copy_generic = Skopiuj do schowka
toggle_menu = Przeลฤ
cz menu
-tracked_time_summary = Podsumowanie ลledzonego czasu na podstawie filtrรณw listy problemรณw
+tracked_time_summary = Podsumowanie ลledzonego czasu na podstawie filtrรณw listy zgลoszeล
show_timestamps = Pokaลผ znaczniki czasu
filter.not_archived = Nie zarchiwizowane
-filter.not_mirror = Nie lustrzane odbicie
+filter.not_mirror = Bez kopii lustrzanych
filter.not_template = Nie szablony
filter.is_archived = Zarchiwizowane
filter.is_mirror = Kopie lustrzane
more_items = Wiฤcej elementรณw
filter.is_fork = Forki
+test = Test
+error413 = Wyczerpano limit.
+new_repo.title = Nowe repozytorium
+new_migrate.title = Nowa migracja
+new_org.title = Nowa organizacja
+new_repo.link = Nowe repozytorium
+new_migrate.link = Nowa migracja
+new_org.link = Nowa organizacja
+filter.not_fork = Nie forki
+copy_path = Skopiuj ลcieลผkฤ
[aria]
navbar = Pasek nawigacji
footer = Stopka
-footer.software = O Oprogramoiwaniu
+footer.software = O tym oprogramowaniu
footer.links = Linki
[heatmap]
-contributions_format = {contributions} w dniu {month} {day}, {year}
+contributions_format = {contributions} w dniu {day} {month} {year}
less = Mniej
more = Wiฤcej
-number_of_contributions_in_the_last_12_months = %s wkลadรณw w ciฤ
gu ostatnich 12 miesiฤcy
-contributions_zero = Brak wkลadรณw
-contributions_one = Wkลad
-contributions_few = Wkลady
+number_of_contributions_in_the_last_12_months = %s kontrybucji w ciฤ
gu ostatnich 12 miesiฤcy
+contributions_zero = Brak kontrybucji
+contributions_one = kontrybucja
+contributions_few = kontrybucji
[editor]
buttons.heading.tooltip = Dodaj nagลรณwek
@@ -186,8 +196,16 @@ buttons.list.task.tooltip = Dodaj listฤ zadaล
buttons.ref.tooltip = Dodaj odniesienie do zgลoszenia lub pull requestu
buttons.mention.tooltip = Dodaj wzmiankฤ o uลผytkowniku lub zespole
buttons.switch_to_legacy.tooltip = Zamiast tego uลผyj starego edytora
-buttons.disable_monospace_font = Wyลฤ
cz czcionkฤ monospace
-buttons.enable_monospace_font = Wลฤ
cz czcionkฤ monospace
+buttons.disable_monospace_font = Wyลฤ
cz czcionkฤ o staลej szerokoลci
+buttons.enable_monospace_font = Wลฤ
cz czcionkฤ o staลej szerokoลci
+buttons.indent.tooltip = Zagnieลบdลบ elementy o jeden poziom
+buttons.new_table.tooltip = Dodaj tabelฤ
+table_modal.header = Dodaj tabelฤ
+table_modal.placeholder.header = Nagลรณwek
+table_modal.placeholder.content = Zawartoลฤ
+table_modal.label.rows = Wiersze
+table_modal.label.columns = Kolumny
+buttons.unindent.tooltip = Usuล jeden poziom zagnieลผdลผenia
[filter]
string.asc = A - Z
@@ -199,19 +217,19 @@ missing_csrf=Bลฤdne ลผฤ
danie: brak tokenu CSRF
invalid_csrf=Bลฤdne ลผฤ
danie: nieprawidลowy token CSRF
not_found=Nie moลผna odnaleลบฤ celu.
network_error=Bลฤ
d sieci
-report_message = Jeลli podejrzewasz ลผe jest to bug w Forgejo, przeszukaj zgลoszenia na Codeberg lub otwรณrz nowe zgลoszenie w razie potrzeby.
+report_message = Jeลli podejrzewasz ลผe jest to bug w Forgejo, przeszukaj zgลoszenia na Codeberg lub otwรณrz nowe zgลoszenie w razie potrzeby.
server_internal = Wewnฤtrzny bลฤ
d serwera
[startpage]
app_desc=Bezbolesna usลuga Git na wลasnym serwerze
install=ลatwa instalacja
platform=Wieloplatformowoลฤ
-platform_desc=Forgejo ruszy gdziekolwiek Go jest moลผliwe do skompilowania: Windows, macOS, Linux, ARM, itd. Wybierz swรณj ulubiony system!
+platform_desc=Potwierdzono, ลผe Forgejo dziaลa na libre systemach operacyjnych, takich jak Linux i FreeBSD, a takลผe na rรณลผnych architekturach procesorรณw. Wybierz to co ci siฤ podoba!
lightweight=Niskie wymagania
lightweight_desc=Forgejo ma niskie minimalne wymagania i moลผe dziaลaฤ na niedrogim Raspberry Pi. Oszczฤdzaj energiฤ swojego komputera!
license=Otwarte ลบrรณdลo
-license_desc=Pobierz na Forgejo ! Doลฤ
cz do nas dziฤki swojemu wkลadowi , aby uczyniฤ ten projekt jeszcze lepszym. Nie wstydลบ siฤ zostaฤ wspรณลtwรณrcฤ
!
-install_desc = Po prostu uruchom plik binarny dla swojej platformy, dostarcz jฤ
za pomocฤ
Dockera , lub uลผyj wersji zapakowanej .
+license_desc=Pobierz na Forgejo ! Doลฤ
cz do nas dziฤki swojemu wkลadowi , aby uczyniฤ ten projekt jeszcze lepszym. Nie wstydลบ siฤ zostaฤ wspรณลtwรณrcฤ
!
+install_desc = Po prostu uruchom plik binarny dla swojej platformy, dostarcz jฤ
za pomocฤ
Dockera , lub uลผyj wersji zapakowanej .
[install]
install=Instalacja
@@ -238,13 +256,13 @@ err_empty_db_path=ลcieลผka do bazy danych SQLite3 nie moลผe byฤ pusta.
no_admin_and_disable_registration=Nie moลผesz wyลฤ
czyฤ moลผliwoลci samodzielnej rejestracji kont uลผytkownikรณw bez stworzenia konta administratora.
err_empty_admin_password=Hasลo administratora nie moลผe byฤ puste.
err_empty_admin_email=Pole adresu e-mail administratora nie moลผe byฤ puste.
-err_admin_name_is_reserved=Nazwa uลผytkownika administratora jest nieprawidลowa, pseudonim jest zastrzeลผony
+err_admin_name_is_reserved=Nazwa uลผytkownika administratora jest nieprawidลowa, nazwa uลผytkownika jest zarezerwowana
err_admin_name_pattern_not_allowed=Nazwa uลผytkownika administratora jest nieprawidลowa, pseudonim zawiera zastrzeลผone znaki
err_admin_name_is_invalid=Nazwa uลผytkownika administratora jest nieprawidลowa
general_title=Ustawienia ogรณlne
app_name=Tytuล witryny
-app_name_helper=Wprowadลบ nazwฤ firmy.
+app_name_helper=Wprowadลบ tutaj swojฤ
nazwฤ instancji. Bฤdzie ona wyลwietlana na kaลผdej stronie.
repo_path=Katalog repozytoriรณw
repo_path_helper=Zdalne repozytoria Git zostanฤ
zapisane w tym katalogu.
lfs_path=ลcieลผka gลรณwna Git LFS
@@ -275,18 +293,18 @@ server_service_title=Ustawienia serwera i innych usลug
offline_mode=Wลฤ
cz tryb lokalny
offline_mode.description=Wyลฤ
cz zewnฤtrzne usลugi dostarczania i dostarczaj wszystkie zasoby lokalnie.
disable_gravatar=Wyลฤ
cz Gravatar
-disable_gravatar.description=Wyลฤ
cz Gravatar i inne usลugi zewnฤtrzne awatarรณw. Zostanie zastosowany domyลlny awatar, chyba ลผe uลผytkownik przeลle swรณj wลasny.
+disable_gravatar.description=Wyลฤ
cz Gravatar i inne usลugi zewnฤtrzne awatarรณw. Zostanie zastosowany domyลlny awatar, chyba ลผe uลผytkownik ustawi swรณj wลasny.
federated_avatar_lookup=Wลฤ
cz zewnฤtrzne awatary
-federated_avatar_lookup.description=Enable federated avatars lookup to use federated open source service based on libravatar.
+federated_avatar_lookup.description=Wyszukuj awatary za pomocฤ
Libravatar.
disable_registration=Wyลฤ
cz samodzielnฤ
rejestracjฤ
-disable_registration.description=Wyลฤ
cz samodzielnฤ
rejestracjฤ uลผytkownikรณw. Tylko administratorzy bฤdฤ
w stanie tworzyฤ nowe konta.
-allow_only_external_registration.description=Wลฤ
cz rejestracjฤ wyลฤ
cznie za pomocฤ
zewnฤtrznych usลug
+disable_registration.description=Tylko administratorzy instancji bฤdฤ
mogli tworzyฤ nowe konta uลผytkownikรณw. Zaleca siฤ pozostawienie rejestracji wyลฤ
czonej, chyba ลผe zamierzasz hostowaฤ publicznฤ
instancjฤ dla wszystkich i jesteล gotowy(-a) na radzenie sobie z duลผฤ
iloลciฤ
kont spamerskich.
+allow_only_external_registration.description=Uลผytkownicy bฤdฤ
mogli tworzyฤ nowe konta tylko za pomocฤ
skonfigurowanych usลug zewnฤtrznych.
openid_signin=Wลฤ
cz logowanie za pomocฤ
OpenID
-openid_signin.description=Wลฤ
cz logowanie uลผytkownikรณw za pomocฤ
OpenID.
+openid_signin.description=Zezwรณl uลผytkownikom na logowanie siฤ przez OpenID.
openid_signup=Wลฤ
cz samodzielnฤ
rejestracjฤ za pomocฤ
OpenID
-openid_signup.description=Wลฤ
cz samodzielnฤ
ย rejestracjฤ opartฤ
ย o OpenID.
+openid_signup.description=Zezwalaj uลผytkownikom na tworzenie kont za poลrednictwem OpenID, jeลli wลฤ
czona jest samodzielna rejestracja.
enable_captcha=Wลฤ
cz CAPTCHA przy rejestracji
-enable_captcha.description=Wymagaj walidacji CAPTCHA przy samodzielnej rejestracji uลผytkownika.
+enable_captcha.description=Wymagaj weryfikacji CAPTCHA przy rejestracji.
require_sign_in_view=Wymagaj zalogowania siฤ, aby wyลwietliฤ zawartoลฤ instancji
admin_setting.description=Tworzenie konta administratora jest opcjonalne. Pierwszy zarejestrowany uลผytkownik automatycznie zostanie administratorem.
admin_title=Ustawienia konta administratora
@@ -307,16 +325,16 @@ save_config_failed=Nie udaลo siฤ zapisaฤ konfiguracji: %v
invalid_admin_setting=Nieprawidลowe ustawienia konta administratora: %v
invalid_log_root_path=ลcieลผka dla logรณw jest niepoprawna: %v
default_keep_email_private=Domyลlne ukrywanie adresรณw e-mail
-default_keep_email_private.description=Domyลlnie ukrywaj adresy e-mail nowych kont uลผytkownikรณw.
+default_keep_email_private.description=Domyลlnie wลฤ
cz ukrywanie adresu e-mail dla nowych uลผytkownikรณw, aby informacje te nie wyciekaลy natychmiast po zarejestrowaniu siฤ.
default_allow_create_organization=Domyลlne zezwolenie na tworzenie organizacji
-default_allow_create_organization.description=Domyลlnie zezwalaj nowym kontom na tworzenie organizacji.
+default_allow_create_organization.description=Domyลlnie zezwalaj nowym uลผytkownikom na tworzenie organizacji. Gdy ta opcja jest wyลฤ
czona, administrator bฤdzie musiaล przyznaฤ uprawnienia do tworzenia organizacji nowym uลผytkownikom.
default_enable_timetracking=Domyลlnie wลฤ
cz ลledzenie czasu
-default_enable_timetracking.description=Domyลlnie wลฤ
cz ลledzenie czasu dla nowych repozytoriรณw.
-no_reply_address=Ukryta domena e-mail
+default_enable_timetracking.description=Domyลlnie zezwรณl na korzystanie z funkcji ลledzenia czasu dla nowych repozytoriรณw.
+no_reply_address=Domena ukrytych e-maili
no_reply_address_helper=Nazwa domeny dla uลผytkownikรณw z ukrytym adresem e-mail. Przykลadowo, uลผytkownik "jan" bฤdzie zalogowany na Git'cie jako "jan@noreply.example.org", jeลli domena ukrytego adresu e-mail jest ustawiona na "noreply.example.org".
password_algorithm=Algorytm hashowania haseล
invalid_db_table = Tabela bazy danych "%s" jest nieprawidลowa: %v
-allow_dots_in_usernames = Zezwolenie uลผytkownikom na uลผywanie kropek w nazwach uลผytkownikรณw. Nie ma to wpลywu na istniejฤ
ce konta.
+allow_dots_in_usernames = Zezwรณl uลผytkownikom na uลผywanie kropek w nazwach uลผytkownikรณw. Nie ma to wpลywu na istniejฤ
ce konta.
invalid_password_algorithm = Nieprawidลowy algorytm hashowania haseล
smtp_from_invalid = Adres "Wyลlij e-mail jako" jest nieprawidลowy
env_config_keys_prompt = Nastฤpujฤ
ce zmienne ลrodowiskowe zostanฤ
rรณwnieลผ zastosowane do pliku konfiguracyjnego:
@@ -326,7 +344,10 @@ password_algorithm_helper = Ustaw algorytm haszowania haseล. Algorytmy majฤ
r
enable_update_checker = Wลฤ
cz sprawdzanie aktualizacji
env_config_keys = Konfiguracja ลrodowiska
run_user_helper = Nazwa uลผytkownika systemu operacyjnego, pod ktรณrฤ
dziaลa Forgejo. Naleลผy pamiฤtaฤ, ลผe ten uลผytkownik musi mieฤ dostฤp do ลcieลผki gลรณwnej repozytorium.
-require_sign_in_view.description = Ogranicz dostฤp do strony jedynie do zalogowanych uลผytkownikรณw. Odwiedzajฤ
cy zobaczฤ
tylko strony logowania i rejestracji.
+require_sign_in_view.description = Ogranicz dostฤp do strony jedynie do zalogowanych uลผytkownikรณw. Goลcie zobaczฤ
tylko strony logowania i rejestracji.
+allow_only_external_registration = Zezwalaj na rejestracjฤ tylko za poลrednictwem usลug zewnฤtrznych
+app_slogan = Slogan instancji
+app_slogan_helper = Wprowadลบ tutaj slogan swojej instancji. Pozostaw puste, aby wyลฤ
czyฤ.
[home]
uname_holder=Nazwa uลผytkownika lub adres e-mail
@@ -377,7 +398,7 @@ forks_few = %d forki
relevant_repositories_tooltip = Repozytoria, ktรณre nie sฤ
forkami lub nie majฤ
ย tematu, ikony i opisu sฤ
ย ukryte.
[auth]
-create_new_account=Zarejestruj konto
+create_new_account=Utwรณrz konto
register_helper_msg=Masz juลผ konto? Zaloguj siฤ teraz!
social_register_helper_msg=Masz juลผ konto? Powiฤ
ลผ je teraz!
disable_register_prompt=Rejestracja jest wyลฤ
czona. Skontaktuj siฤ z administratorem strony.
@@ -386,18 +407,18 @@ remember_me=Zapamiฤtaj to urzฤ
dzenie
forgot_password_title=Zapomniaลem hasลa
forgot_password=Zapomniaลeล hasลa?
sign_up_now=Potrzebujesz konta? Zarejestruj siฤ teraz.
-confirmation_mail_sent_prompt=Nowy email aktywacyjny zostaล wysลany na adres %s . Sprawdลบ swojฤ
skrzynkฤ odbiorczฤ
w ciฤ
gu %s aby dokoลczyฤ proces rejestracji.
+confirmation_mail_sent_prompt=Nowa wiadomoลฤ e-mail z potwierdzeniem zostaลa wysลana do %s . Aby zakoลczyฤ proces rejestracji, sprawdลบ swojฤ
skrzynkฤ odbiorczฤ
i kliknij podany link w ciฤ
gu najbliลผszych %s. Jeลli wiadomoลฤ e-mail jest niewaลผna, moลผesz siฤ zalogowaฤ i poprosiฤ o wysลanie kolejnej wiadomoลci e-mail z potwierdzeniem na inny adres.
must_change_password=Zaktualizuj swoje hasลo
allow_password_change=Uลผytkownik musi zmieniฤ hasลo (zalecane)
-reset_password_mail_sent_prompt=E-mail potwierdzajฤ
cy zostaล wysลany na adres %s . Sprawdลบ swojฤ
skrzynkฤ odbiorczฤ
w przeciฤ
gu %s, aby ukoลczyฤ proces odzyskiwania konta.
+reset_password_mail_sent_prompt=Wiadomoลฤ e-mail z potwierdzeniem zostaลa wysลana do %s . Aby zakoลczyฤ proces odzyskiwania konta, sprawdลบ swojฤ
skrzynkฤ odbiorczฤ
i kliknij podany link w ciฤ
gu najbliลผszych %s.
active_your_account=Aktywuj swoje konto
account_activated=Konto zostaลo aktywowane
-prohibit_login=Logowanie jest zabronione
+prohibit_login=Konto jest zawieszone
resent_limit_prompt=Zaลผฤ
dano juลผ wiadomoลci aktywacyjnej. Zaczekaj 3 minuty i sprรณbuj ponownie.
has_unconfirmed_mail=Witaj, %s, masz niepotwierdzony adres e-mail (%s ). Jeลli nie otrzymaลeล wiadomoลci e-mail z potwierdzeniem lub potrzebujesz wysลaฤ nowฤ
, kliknij na poniลผszy przycisk.
resend_mail=Kliknij tutaj, aby wysลaฤ e-mail aktywacyjny
email_not_associate=Adres e-mail nie jest powiฤ
zany z ลผadnym kontem.
-send_reset_mail=Wyลlij e-mail odzyskujฤ
cy
+send_reset_mail=Wyลlij e-mail odzyskiwania
reset_password=Odzyskiwanie konta
invalid_code=Twรณj kod potwierdzajฤ
cy jest nieprawidลowy lub wygasล.
reset_password_helper=Odzyskaj konto
@@ -412,7 +433,7 @@ twofa_scratch_token_incorrect=Twรณj kod jednorazowy jest niepoprawny.
login_userpass=Zaloguj siฤ
tab_openid=OpenID
oauth_signup_tab=Utwรณrz nowe konto
-oauth_signup_title=Ukoลcz nowe konto
+oauth_signup_title=Ukoลcz tworzenie nowego konta
oauth_signup_submit=Utwรณrz konto
oauth_signin_tab=Poลฤ
cz z istniejฤ
cym kontem
oauth_signin_title=Zaloguj siฤ, aby autoryzowaฤ poลฤ
czone konto
@@ -435,23 +456,30 @@ sspi_auth_failed=Uwierzytelnianie SSPI nie powiodลo siฤ
password_pwned_err=Nie udaลo siฤ ukoลczyฤ ลผฤ
dania do HaveIBeenPwned
remember_me.compromised = Token logowania nie jest juลผ waลผny, co moลผe wskazywaฤ na naruszenie bezpieczeลstwa konta. Sprawdลบ swoje konto pod kฤ
tem podejrzanych dziaลaล.
sign_up_successful = Konto zostaลo pomyลlnie utworzone. Witamy!
-prohibit_login_desc = Twoje konto jest zablokowane, skontaktuj siฤ z administratorem witryny.
+prohibit_login_desc = Twoje konto zostaลo zawieszone i nie moลผe wchodziฤ w interakcje z instancjฤ
. Skontaktuj siฤ z administratorem instancji, aby odzyskaฤ dostฤp.
change_unconfirmed_email_summary = Zmieล adres e-mail, na ktรณry zostanie wysลana wiadomoลฤ aktywacyjna.
manual_activation_only = Skontaktuj siฤ z administratorem witryny, aby dokoลczyฤ aktywacjฤ.
-change_unconfirmed_email = Jeลli podczas rejestracji podaลeล nieprawidลowy adres e-mail, moลผesz go zmieniฤ poniลผej, a potwierdzenie zostanie wysลane na nowy adres.
+change_unconfirmed_email = Jeลli podczas rejestracji podaลeล(-aล) nieprawidลowy adres e-mail, moลผesz go zmieniฤ poniลผej, a potwierdzenie zostanie wysลane na nowy adres.
openid_signin_desc = Wprowadลบ swรณj identyfikator URI OpenID. Na przykลad: alice.openid.example.org lub https://openid.example.org/alice.
-authorization_failed_desc = Autoryzacja nie powiodลa siฤ, poniewaลผ wykryliลmy nieprawidลowe ลผฤ
danie. Skontaktuj siฤ z autorem aplikacji, ktรณrฤ
prรณbowaลeล autoryzowaฤ.
-password_pwned = Wybrane hasลo znajduje siฤ na liลcie skradzionych haseล , ktรณre zostaลy wczeลniej ujawnione w wyniku publicznego naruszenia danych. Sprรณbuj ponownie z innym hasลem i rozwaลผ zmianฤ tego hasลa rรณwnieลผ w innych miejscach.
+authorization_failed_desc = Autoryzacja nie powiodลa siฤ, poniewaลผ wykryliลmy nieprawidลowe ลผฤ
danie. Skontaktuj siฤ z autorem aplikacji, ktรณrฤ
prรณbowaลeล(-aล) autoryzowaฤ.
+password_pwned = Wybrane hasลo znajduje siฤ na liลcie skradzionych haseล , ktรณre zostaลy wczeลniej ujawnione w wyniku publicznego naruszenia danych. Sprรณbuj ponownie z innym hasลem i rozwaลผ zmianฤ tego hasลa rรณwnieลผ w innych miejscach.
last_admin = Nie moลผna usunฤ
ฤ ostatniego administratora. Musi istnieฤ co najmniej jeden administrator.
tab_signin = Zaloguj
oauth.signin.error = Wystฤ
piล bลฤ
d podczas przetwarzania ลผฤ
dania autoryzacji. Jeลli ten bลฤ
d nadal wystฤpuje, skontaktuj siฤ z administratorem witryny.
-change_unconfirmed_email_error = Nie udaลo siฤย zmieniฤย adresu email: %v
+change_unconfirmed_email_error = Nie udaลo siฤ zmieniฤ adresu e-mail: %v
invalid_code_forgot_password = Twรณj kod potwierdzajฤ
cy jest niepoprawny lub wygasล. Naciลnij tutajโฃ , aby rozpoczฤ
ฤย nowฤ
ย sesjฤ.
invalid_password = Twoje hasลo nie zgadza siฤ z hasลem, ktรณre zostaลo uลผyte do stworzenia konta.
-reset_password_wrong_user = Jesteลย zalogowany jako %s, ale link odzyskujฤ
cy jest dla %s
+reset_password_wrong_user = Jesteล zalogowany(-a) jako %s, ale link odzyskujฤ
cy jest dla %s
tab_signup = Zarejestruj
oauth.signin.error.access_denied = Wniosek o autoryzacjฤ zostaล odrzucony.
oauth.signin.error.temporarily_unavailable = Autoryzacja nie powiodลa siฤ, poniewaลผ serwer uwierzytelniania jest tymczasowo niedostฤpny. Sprรณbuj ponownie pรณลบniej.
+hint_register = Potrzebujesz konta? Zarejestruj siฤ.
+back_to_sign_in = Wrรณฤ do logowania
+sign_in_openid = Kontynuuj z OpenID
+hint_login = Masz juลผ konto? Zaloguj siฤ teraz!
+sign_up_button = Zarejestruj siฤ.
+use_onetime_code = Uลผyj kodu jednorazowego
+unauthorized_credentials = Dane uwierzytelniajฤ
ce sฤ
nieprawidลowe lub wygasลy. Sprรณbuj ponownie wykonaฤ polecenie lub zobacz %s, aby uzyskaฤ wiฤcej informacji
[mail]
view_it_on=Zobacz na %s
@@ -466,7 +494,7 @@ activate_account.text_2=Kliknij poniลผszy link, aby aktywowaฤ swoje konto w ci
activate_email=Potwierdลบ swรณj adres e-mail
activate_email.text=Aby zweryfikowaฤ swรณj adres e-mail, w ciฤ
gu nastฤpnych %s kliknij poniลผszy link:
-register_notify=Witamy w Forgejo
+register_notify=Witamy w %s
register_notify.title=%[1]s, witaj w %[2]s
register_notify.text_1=to jest Twรณj e-mail z potwierdzeniem rejestracji dla %s!
register_notify.text_2=Moลผesz teraz zalogowaฤ siฤ za pomocฤ
nazwy uลผytkownika: %s
@@ -474,7 +502,7 @@ register_notify.text_3=Jeลli ktoล inny utworzyล dla ciebie to konto, musisz n
reset_password=Odzyskaj swoje konto
reset_password.title=%s, otrzymaliลmy proลbฤ o odzyskanie konta
-reset_password.text=Jeลli to byลeล ty, kliknij poniลผszy link, aby odzyskaฤ swoje konto w ciฤ
gu %s :
+reset_password.text=Jeลli to byลeล(-aล) ty, kliknij poniลผszy link, aby odzyskaฤ swoje konto w ciฤ
gu %s :
register_success=Rejestracja powiodลa siฤ
@@ -504,7 +532,7 @@ repo.transfer.to_you=ciebie
repo.transfer.body=Aby zaakceptowaฤ lub odrzuciฤ go, odwiedลบ %s lub po prostu go zignoruj.
repo.collaborator.added.subject=%s dodaล ciฤ do %s jako wspรณลtwรณrce
-repo.collaborator.added.text=Zostaลeล dodany jako wspรณลtwรณrca do repozytorium:
+repo.collaborator.added.text=Zostaลeล(-aล) dodany jako wspรณลtwรณrca do repozytorium:
issue.action.push_1 = @%[1]s pchnฤ
ล %[3]d commit do %[2]s
activate_email.title = %s, zweryfikuj swรณj adres e-mail
admin.new_user.text = Kliknij tutaj , aby zarzฤ
dzaฤ tym uลผytkownikiem z panelu administracyjnego.
@@ -513,9 +541,28 @@ reply = lub odpowiedz bezpoลrednio na ten e-mail
admin.new_user.subject = Wลaลnie zarejestrowaล siฤ nowy uลผytkownik %s
admin.new_user.user_info = Informacje uลผytkownika
issue.action.approve = @%[1]s zatwierdziล ten pull request.
-issue.action.reject = @%[1]s poprosiล o zmiany w tym pull requescie.
+issue.action.reject = @%[1]s poprosiล o zmiany w tym pull requeลcie.
issue.action.review_dismissed = @%[1]s odrzuciล ostatniฤ
analizฤ od %[2]s dla tego pull requesta.
team_invite.subject = %[1]s zaprosiล ciฤ do doลฤ
czenia do organizacji %[2]s
+primary_mail_change.subject = Twรณj gลรณwny mail zostaล zmieniony
+primary_mail_change.text_1 = Gลรณwny mail twojego konta zostaล wลaลnie zmieniony na %[1]s. To oznacza ze ten adres e-mail nie bฤdzie juลผ otrzymywaล powiadomieล dla twojego konta.
+totp_disabled.subject = TOTP zostaล wyลฤ
czony
+password_change.subject = Twoje hasลo zostaลo zmienione
+password_change.text_1 = Hasลo do twojego konta zostaลo wลaลnie zmienione.
+team_invite.text_1 = %[1]s zaprosiล ciฤ do zespoลu %[2]s w organizacji %[3]s.
+removed_security_key.no_2fa = Nie ma juลผ skonfigurowanych innych metod 2FA, co oznacza, ลผe nie jest juลผ konieczne logowanie siฤ do konta za pomocฤ
2FA.
+account_security_caution.text_2 = Jeลli to nie byลeล(-aล) Ty, Twoje konto padลo ofiarฤ
wลamania. Skontaktuj siฤ z administratorem tej strony.
+account_security_caution.text_1 = Jeลli to byลeล(-aล) ty, moลผesz bezpiecznie zignorowaฤ tฤ wiadomoลฤ.
+totp_enrolled.subject = Aktywowaลeล(-aล) TOTP jako metodฤ 2FA
+totp_enrolled.text_1.no_webauthn = Wลaลnie wลฤ
czyลeล(-aล) TOTP dla swojego konta. Oznacza to, ลผe dla wszystkich przyszลych logowaล do konta musisz uลผywaฤ TOTP jako metody 2FA.
+team_invite.text_3 = Uwaga: To zaproszenie byลo przeznaczone dla %[1]s. Jeลli nie spodziewaลeล(-aล) siฤ tego zaproszenia, moลผesz zignorowaฤ ten e-mail.
+totp_disabled.text_1 = Jednorazowe hasลo czasowe (TOTP) zostaลo wลaลnie wyลฤ
czone na twoim koncie.
+totp_disabled.no_2fa = Nie ma juลผ skonfigurowanych innych metod 2FA, co oznacza, ลผe nie jest juลผ konieczne logowanie siฤ do konta za pomocฤ
2FA.
+removed_security_key.subject = Klucz bezpieczeลstwa zostaล usuniฤty
+removed_security_key.text_1 = Klucz bezpieczeลstwa "%[1]s" zostaล wลaลnie usuniฤty z twojego konta.
+totp_enrolled.text_1.has_webauthn = Wลaลnie wลฤ
czyลeล(-aล) TOTP dla swojego konta. Oznacza to, ลผe dla wszystkich przyszลych logowaล do konta moลผesz uลผyฤ TOTP jako metody 2FA lub uลผyฤ dowolnego klucza bezpieczeลstwa.
+team_invite.text_2 = Kliknij poniลผszy link, aby doลฤ
czyฤ do zespoลu:
+issue.action.merge = @%[1]s poลฤ
czyล(-ลa) #%[2]d z %[3]s.
[modal]
@@ -523,6 +570,7 @@ yes=Tak
no=Nie
cancel=Anuluj
modify=Aktualizuj
+confirm = Potwierdลบ
[form]
UserName=Nazwa uลผytkownika
@@ -588,7 +636,7 @@ enterred_invalid_owner_name=Nowa nazwa wลaลciciela nie jest prawidลowa.
enterred_invalid_password=Wprowadzone hasลo jest nieprawidลowe.
user_not_exist=Uลผytkownik nie istnieje.
team_not_exist=Ten zespรณล nie istnieje.
-last_org_owner=Nie moลผesz usunฤ
ฤ ostatniego uลผytkownika z zespoลu "Owners". Organizacja musi mieฤ przynajmniej jednego wลaลciciela.
+last_org_owner=Nie moลผesz usunฤ
ฤ ostatniego uลผytkownika z zespoลu "owners". Organizacja musi mieฤ przynajmniej jednego wลaลciciela.
cannot_add_org_to_team=Organizacja nie moลผe zostaฤ dodana jako czลonek zespoลu.
invalid_ssh_key=Nie moลผna zweryfikowaฤ Twojego klucza SSH: %s
@@ -597,6 +645,37 @@ auth_failed=Uwierzytelnienie siฤ nie powiodลo: %v
target_branch_not_exist=Gaลฤ
ลบ docelowa nie istnieje.
+still_own_repo = Twoje konto posiada jedno lub wiฤcej repozytoriรณw, usuล lub przenieล je.
+unable_verify_ssh_key = Nie moลผna zweryfikowaฤ klucza SSH, sprawdลบ go pod kฤ
tem bลฤdรณw.
+FullName = Imiฤ i nazwisko
+Description = Opis
+duplicate_invite_to_team = Uลผytkownik zostaล juลผ zaproszony do zespoลu.
+Pronouns = Zaimki
+Biography = Biografia
+AccessToken = Token dostฤpu
+To = Nazwa gaลฤzi
+repository_force_private = Opcja Wymuszaj Prywatne repozytoria, jest wลฤ
czona: prywatne repozytoria nie mogฤ
zostaฤ upublicznione.
+Website = Strona Internetowa
+invalid_group_team_map_error = ` mapowanie jest nieprawidลowe: %s`
+url_error = `"%s" nie jest poprawnym adresem URL.`
+unset_password = Uลผytkownik nie ustawiล hasลa.
+openid_been_used = Adres OpenID "%s" jest juลผ uลผywany.
+organization_leave_success = Pomyลlnie opuลciลeล(-aล) organizacjฤ %s.
+must_use_public_key = Podany klucz jest kluczem prywatnym. Nie przesyลaj nigdzie swojego klucza prywatnego. Zamiast tego uลผyj klucza publicznego.
+Location = Lokalizacja
+username_error_no_dots = ` moลผe zawieraฤ tylko znaki alfanumeryczne ("0-9", "a-z", "A-Z"), myลlnik ("-") oraz podkreลlenie ("_"). Nie moลผe zaczynaฤ siฤ ani koลczyฤ znakami niealfanumerycznymi, a znaki niealfanumeryczne wystฤpujฤ
ce po sobie sฤ
rรณwnieลผ zabronione.`
+username_error = ` moลผe zawieraฤ tylko znaki alfanumeryczne ("0-9", "a-z", "A-Z"), myลlnik ("-") oraz podkreลlenie ("_"). Nie moลผe zaczynaฤ siฤ ani koลczyฤ znakami niealfanumerycznymi, a znaki niealfanumeryczne wystฤpujฤ
ce po sobie sฤ
rรณwnieลผ zabronione.`
+still_has_org = Twoje konto jest czลonkiem jednej bฤ
dลบ wielu organizacji, musisz je najpierw opuลciฤ.
+org_still_own_repo = Ta organizacja nadal jest wลaลcicielem jednego lub wielu repozytoriรณw. Najpierw je usuล lub przenieล.
+admin_cannot_delete_self = Nie moลผesz usunฤ
ฤ siebie, gdy jesteล administratorem. Proszฤ najpierw usunฤ
ฤ swoje uprawnienia administratora.
+required_prefix = Pole musi zaczynaฤ siฤ od "%s"
+org_still_own_packages = Ta organizacja nadal jest wลaลcicielem jednego lub wielu pakietรณw, musisz je najpierw usunฤ
ฤ.
+unsupported_login_type = Ta forma logowania nie wspiera moลผliwoลci usuniฤcia konta.
+include_error = ` musi zawieraฤ podciฤ
g znakรณw "%s".`
+still_own_packages = Twoje konto jest wลaลcicielem jednego lub wiฤcej pakietรณw, musisz je najpierw usunฤ
ฤ.
+username_claiming_cooldown = Nazwa uลผytkownika nie moลผe byฤ uzyskana, poniewaลผ okres ochrony jeszcze nie minฤ
ล. Moลผe zostaฤ uzyskana dopiero w %[1]s.
+email_domain_is_not_allowed = Domena adresu e-mail uลผytkownika %s konfliktuje z EMAIL_DOMAIN_ALLOWLIST lub EMAIL_DOMAIN_BLOCKLIST. Upewnij siฤ, ลผe ustawiony adres e-mail jest poprawny.
+invalid_ssh_principal = Nieprawidลowy podmiot: %s
[user]
@@ -613,6 +692,33 @@ follow=Obserwuj
unfollow=Przestaล obserwowaฤ
user_bio=Biografia
disabled_public_activity=Ten uลผytkownik wyลฤ
czyล publiczne wyลwietlanie jego aktywnoลci.
+code = Kod
+block = Zablokuj
+unblock = Odblokuj
+block_user.detail = Pamiฤtaj, ลผe zablokowanie uลผytkownika powoduje inne skutki, takie jak:
+block_user.detail_2 = Ten uลผytkownik nie bฤdzie mรณgล wchodziฤ w interakcjฤ z repozytoriami, ktรณrych jesteล wลaลcicielem, ani ze zgลoszeniami i komentarzami, ktรณre utworzyลeล(-aล).
+settings = Ustawienia uลผytkownika
+followers_one = %d obserwujฤ
cych
+following_one = %d obserwowanych
+followers.title.one = Obserwujฤ
cy
+followers.title.few = Obserwujฤ
cy
+following.title.one = Obserwowani
+following.title.few = Obserwowani
+email_visibility.limited = Twรณj adres e-mail jest widoczny dla wszystkich uwierzytelnionych uลผytkownikรณw
+block_user = Zablokuj uลผytkownika
+block_user.detail_1 = Przestaniecie siฤ wzajemnie obserwowaฤ i nie bฤdziecie mogli siฤ wzajemnie obserwowaฤ.
+follow_blocked_user = Nie moลผesz obserwowaฤ tego uลผytkownika, poniewaลผ go zablokowaลeล(-aล) lub ten uลผytkownik zablokowaล Ciebie.
+show_on_map = Pokaลผ to mejsce na mapie
+joined_on = Doลฤ
czyล w %s
+block_user.detail_3 = Nie bฤdziecie mogli dodaฤ siebie jako wspรณลpracownicy repozytorium.
+public_activity.visibility_hint.self_public = Twoja aktywnoลฤ jest widoczna dla wszystkich, z wyjฤ
tkiem interakcji w przestrzeniach prywatnych. Konfiguruj .
+public_activity.visibility_hint.admin_public = Twoja aktywnoลฤ jest widoczna dla wszystkich, jednak jako administrator masz moลผliwoลฤ podejrzenia interakcji w przestrzeniach prywatnych.
+public_activity.visibility_hint.self_private = Twoja aktywnoลฤ jest widoczna tylko dla ciebie i administratorรณw tej instancji. Konfiguruj .
+public_activity.visibility_hint.admin_private = Ta aktywnoลฤ jest dla ciebie widoczna poniewaลผ jesteล administratorem, ale uลผytkownik preferuje by ta aktywnoลฤ byลa ukryta.
+form.name_reserved = Nazwa uลผytkownika "%s" jest zarezerwowana.
+form.name_pattern_not_allowed = Wzรณr "%s" nie jest dozwolony w nazwie uลผytkownika.
+public_activity.visibility_hint.self_private_profile = Twoja aktywnoลฤ jest widoczna tylko dla ciebie i administratorรณw tej instancji poniewaลผ twรณj profil jest prywatny. Konfiguruj .
+form.name_chars_not_allowed = Nazwa uลผytkownika "%s" zawiera nieprawidลowe znaki.
[settings]
@@ -625,7 +731,7 @@ avatar=Awatar
ssh_gpg_keys=Klucze SSH / GPG
social=Konta spoลecznoลciowe
applications=Aplikacje
-orgs=Zarzฤ
dzaj organizacjami
+orgs=Organizacje
repos=Repozytoria
delete=Usuล konto
twofa=Autoryzacja dwuetapowa
@@ -638,7 +744,7 @@ password_username_disabled=Uลผytkownicy nielokalni nie mogฤ
zmieniaฤ swoich na
full_name=Imiฤ i nazwisko
website=Strona
location=Lokalizacja
-update_theme=Zaktualizuj motyw
+update_theme=Zmieล motyw
update_profile=Zaktualizuj profil
update_language_success=Jฤzyk zostaล zaktualizowany.
update_profile_success=Twรณj profil zostaล zaktualizowany.
@@ -669,17 +775,17 @@ password_change_disabled=Konta niebฤdฤ
ce lokalnymi nie mogฤ
zmieniฤ swojego
emails=Adresy e-mail
manage_emails=Zarzฤ
dzaj adresami e-mail
-manage_themes=Wybierz motyw domyลlny
-manage_openid=Zarzฤ
dzanie adresami OpenID
-theme_desc=Bฤdzie to domyลlny motyw na caลej stronie.
+manage_themes=Domyลlny motyw
+manage_openid=Adresy OpenID
+theme_desc=Ten motyw bฤdzie uลผyty dla interfejsu przeglฤ
darkowego kiedy bฤdziesz zalogowany.
primary=Podstawowy
activated=Aktywowany
requires_activation=Wymaga aktywacji
primary_email=Ustaw jako podstawowy
-activate_email=Wyลlij aktywacjฤ
-activations_pending=Aktywacje oczekujฤ
ce
+activate_email=Wyลlij e-mail aktywacyjny
+activations_pending=Oczekujฤ
ce aktywacje
delete_email=Usuล
-email_deletion=Usuล adres email
+email_deletion=Usuล adres e-mail
email_deletion_desc=Adres e-mail i powiฤ
zane informacje zostanฤ
usuniฤte z Twojego konta. Commity za pomocฤ
tego adresu e-mail pozostanฤ
niezmienione. Kontynuowaฤ?
email_deletion_success=Adres e-mail zostaล usuniฤty.
theme_update_success=Twรณj motyw zostaล zaktualizowany.
@@ -687,7 +793,7 @@ theme_update_error=Wybrany motyw nie istnieje.
openid_deletion=Usuล adres OpenID
openid_deletion_desc=Usuniฤcie tego adresu OpenID z Twojego konta uniemoลผliwi Ci logowanie siฤ za jego pomocฤ
. Kontynuowaฤ?
openid_deletion_success=Adres OpenID zostaล usuniฤty.
-add_new_email=Dodaj nowy e-mail
+add_new_email=Dodaj e-mail
add_new_openid=Dodaj nowy URI OpenID
add_email=Dodaj adres e-mail
add_openid=Dodaj OpenID URI
@@ -700,13 +806,13 @@ openid_desc=OpenID pozwala na delegowanie uwierzytelniania do zewnฤtrznego oper
manage_ssh_keys=Zarzฤ
dzaj kluczami SSH
manage_gpg_keys=Zarzฤ
dzaj kluczami GPG
add_key=Dodaj klucz
-ssh_desc=Te publiczne klucze SSH sฤ
powiฤ
zane z Twoim kontem. Odpowiadajฤ
ce im klucze prywatne umoลผliwiajฤ
peลny dostฤp do Twoich repozytoriรณw.
-gpg_desc=Te publiczne klucze GPG sฤ
powiฤ
zane z Twoim kontem. Dbaj o bezpieczeลstwo kluczy prywatnych, gdyลผ pozwalajฤ
one na weryfikacjฤ commitรณw.
+ssh_desc=Te publiczne klucze SSH sฤ
powiฤ
zane z Twoim kontem. Odpowiadajฤ
ce im klucze prywatne umoลผliwiajฤ
peลny dostฤp do Twoich repozytoriรณw. Klucze SSH, ktรณre zostaลy zweryfikowane mogฤ
zostaฤ uลผyte do weryfikacji commitรณw podpisanych kluczem SSH.
+gpg_desc=Te publiczne klucze GPG sฤ
powiฤ
zane z Twoim kontem i bฤdฤ
uลผywane do weryfikacji twoich commitรณw. Dbaj o bezpieczeลstwo kluczy prywatnych, gdyลผ pozwalajฤ
one na podpisywanie commitรณw.
ssh_helper=Potrzebujesz pomocy? Sprawdลบ na GitHubie przewodnik generowania kluczy SSH lub rozwiฤ
zywanie typowych problemรณw z SSH .
gpg_helper=Potrzebujesz pomocy? Przeczytaj na GitHubie poradnik na temat GPG .
add_new_key=Dodaj klucz SSH
add_new_gpg_key=Dodaj klucz GPG
-key_content_gpg_placeholder=Zaczyna siฤ od '-----BEGIN PGP PUBLICZNEJ BLOKI KLUCZOWEJ PGP---'
+key_content_gpg_placeholder=Zaczyna siฤ od "-----BEGIN PGP PUBLIC KEY BLOCK-----"
ssh_key_been_used=Ten klucz SSH zostaล juลผ dodany do tego serwera.
ssh_key_name_used=Klucz SSH z tฤ
nazwฤ
zostaล juลผ dodany do Twojego konta.
ssh_principal_been_used=Ten klucz SSH zostaล juลผ dodany do tego serwera.
@@ -723,7 +829,7 @@ gpg_token=Token
gpg_token_help=Moลผesz wygenerowaฤ podpis za pomocฤ
:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=Wzmocniony podpis GPG
-key_signature_gpg_placeholder=Zaczyna siฤ od '-----BEGIN PGP SIGNATURE-----'
+key_signature_gpg_placeholder=Zaczyna siฤ od "-----BEGIN PGP SIGNATURE-----"
ssh_key_verified=Zweryfikowany klucz
ssh_key_verified_long=Klucz zostaล zweryfikowany tokenem i moลผe byฤ uลผyty do weryfikacji zmian pasujฤ
cych do wszystkich aktywowanych adresรณw e-mail tego uลผytkownika.
ssh_key_verify=Weryfikuj
@@ -731,7 +837,7 @@ ssh_token_required=Musisz podaฤ podpis poniลผszego tokenu
ssh_token=Token
ssh_token_help=Moลผesz wygenerowaฤ podpis uลผywajฤ
c:
ssh_token_signature=Wzmocniony podpis SSH
-key_signature_ssh_placeholder=Zaczyna siฤ od '-----BEGIN SSH SIGNATURE-----'
+key_signature_ssh_placeholder=Zaczyna siฤ od "-----BEGIN SSH SIGNATURE-----"
subkeys=Podklucze
key_id=ID klucza
key_name=Nazwa klucza
@@ -761,10 +867,10 @@ ssh_externally_managed=Ten klucz SSH jest zarzฤ
dzany zewnฤtrznie dla tego uลผy
manage_social=Zarzฤ
dzaj powiฤ
zanymi kontami spoลecznoลciowymi
unbind=Rozลฤ
cz
-manage_access_token=Zarzฤ
dzaj tokenami dostฤpu
+manage_access_token=Tokeny dostฤpu
generate_new_token=Wygeneruj nowy token
tokens_desc=Te tokeny dostฤpu udzielajฤ
dostฤpu do Twojego konta za pomocฤ
API Forgejo.
-token_name=Nazwa tokena
+token_name=Nazwa tokenu
generate_token=Wygeneruj token
generate_token_success=Twรณj nowy token zostaล wygenerowany. Skopiuj go teraz, gdyลผ nie zostanie ujawniony ponownie.
generate_token_name_duplicate=%s istnieje juลผ jako nazwa aplikacji. Uลผyj nowej.
@@ -794,15 +900,15 @@ oauth2_application_create_description=Aplikacje OAuth2 umoลผliwiajฤ
Twojej apli
authorized_oauth2_applications=Autoryzowane aplikacje OAuth2
revoke_key=Odwoลaj
-revoke_oauth2_grant=Odwoลaj dostฤp
+revoke_oauth2_grant=Zabierz dostฤp
revoke_oauth2_grant_description=Odwoลanie dostฤpu dla tej aplikacji uniemoลผliwi jej korzystanie z Twoich danych. Czy jesteล pewny(-a)?
twofa_desc=Weryfikacja dwuskลadnikowa zwiฤksza bezpieczeลstwo Twojego konta.
twofa_is_enrolled=Twoje konto ma obecnie wลฤ
czonฤ
ย autoryzacjฤ dwuetapowฤ
.
twofa_not_enrolled=Twoje konto obecnie nie ma wลฤ
czonej autoryzacji dwuetapowej.
twofa_disable=Wyลฤ
cz weryfikacjฤ dwuetapowฤ
-twofa_scratch_token_regenerate=Wygeneruj ponownie kod jednorazowy
-twofa_enroll=Wลฤ
cz weryfikacjฤ dwuskลadnikowฤ
+twofa_scratch_token_regenerate=Ponownie wygeneruj jednorazowy kod odzyskiwania
+twofa_enroll=Wลฤ
cz weryfikacjฤ dwuetapowฤ
twofa_disable_note=W kaลผdej chwili moลผesz wyลฤ
czyฤ weryfikacjฤ dwuskลadnikowฤ
.
twofa_disable_desc=Wyลฤ
czenie weryfikacji dwuetapowej sprawi, ลผe Twoje konto bฤdzie mniej bezpieczne. Kontynuowaฤ?
regenerate_scratch_token_desc=Jeลli zgubiลeล(-aล) lub zuลผyลeล(-aล) swรณj kod jednorazowy, moลผesz go wygenerowaฤ ponownie tutaj.
@@ -818,7 +924,7 @@ webauthn_register_key=Dodaj klucz bezpieczeลstwa
webauthn_delete_key=Usuล klucz bezpieczeลstwa
webauthn_delete_key_desc=Jeลผeli usuniesz klucz bezpieczeลstwa, utracisz moลผliwoลฤ zalogowania siฤย z jego uลผyciem. Kontynuowaฤ?
-manage_account_links=Zarzฤ
dzaj powiฤ
zanymi kontami
+manage_account_links=Powiฤ
zane konta
manage_account_links_desc=Te konta zewnฤtrzne sฤ
powiฤ
zane z Twoim kontem Forgejo.
account_links_not_available=Obecnie nie ma ลผadnych zewnฤtrznych kont powiฤ
zanych z tym kontem Forgejo.
link_account=Powiฤ
ลผ konto
@@ -833,7 +939,7 @@ delete_account=Usuล swoje konto
delete_prompt=Ta operacja permanentnie usunie Twoje konto uลผytkownika i jest NIEODWRACALNA .
delete_with_all_comments=Twoje konto jest mลodsze niลผ %s. Aby uniknฤ
ฤ faลszywych komentarzy, wszystkie komentarze zgลoszenia/PR zostanฤ
z nim usuniฤte.
confirm_delete_account=Potwierdลบ usuniฤcie
-delete_account_title=Usuล swoje konto
+delete_account_title=Usuล konto uลผytkownika
delete_account_desc=Czy na pewno chcesz permanentnie usunฤ
ฤ to konto uลผytkownika?
email_notifications.enable=Wลฤ
cz powiadomienia e-mail
@@ -845,6 +951,109 @@ visibility=Widocznoลฤ uลผytkownika
visibility.public=Publiczny
visibility.limited=Ograniczony
visibility.private=Prywatny
+uid = UID
+comment_type_group_label = Etykieta
+comment_type_group_milestone = Kamieล milowy
+comment_type_group_assignee = Przypisanie
+comment_type_group_branch = Gaลฤ
ลบ
+comment_type_group_deadline = Termin
+comment_type_group_project = Projekt
+comment_type_group_reference = Odniesienie
+webauthn_nickname = Pseudonim
+comment_type_group_dependency = Zaleลผnoลฤ
+permissions_list = Uprawnienia:
+hints = Wskazรณwki
+change_password = Zmieล hasลo
+visibility.public_tooltip = Widoczne dla wszystkich
+comment_type_group_review_request = Proลba o recenzjฤ
+comment_type_group_lock = Status blokady
+comment_type_group_pull_request_push = Dodane commity
+keep_activity_private = Ukryj aktywnoลฤ ze strony profilu
+oauth2_application_locked = Forgejo rejestruje zawczasu kilka aplikacji OAuth2 podczas rozruchu jeลผeli wลฤ
czono takฤ
opcjฤ w konfiguracji. By zapobiec nieoczekiwanym zachowaniom, nie mogฤ
one zostaฤ ani edytowane, ani usuniฤte. Proszฤ odnieล siฤ do dokumentacji OAuth2 po wiฤcej informacji.
+oauth2_client_secret_hint = Sekret nie bฤdzie pokazany ponownie po opuszczeniu lub odลwieลผeniu tej strony. Proszฤ upewnij siฤ, ลผe zostaล zapisany.
+email_desc = Twรณj gลรณwny adres e-mail bฤdzie uลผyty dla powiadomieล, odzyskiwania hasลa i, chyba ลผe jest ukryty, operacji Git w przeglฤ
darce.
+key_content_ssh_placeholder = Rozpoczyna siฤ z "ssh-ed25519", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "sk-ecdsa-sha2-nistp256@openssh.com", lub "sk-ssh-ed25519@openssh.com"
+repo_and_org_access = Dostฤp do Repozytoriรณw i Organizacji
+revoke_oauth2_grant_success = Dostฤp cofniฤty pomyลlnie.
+update_language = Zmieล jฤzyk
+keep_email_private_popup = Twรณj adres e-mail nie bฤdzie pokazywany na twoim profilu i nie bฤdzie uลผywany jako domyลlny dla commitรณw utworzonych przez interfejs przeglฤ
darki, takich jak wgrywanie plikรณw, edycje, commity scalajฤ
ce. Zamiast tego, specjalny adres %s moลผe zostaฤ uลผyty do powiฤ
zania commitรณw z twoim kontem. Ta opcja nie wpลywa na commity juลผ istniejฤ
ce.
+repos_none = Nie posiadasz ลผadnych repozytoriรณw.
+verify_gpg_key_success = Klucz GPG "%s" zostaล zweryfikowany.
+email_notifications.andyourown = Dodaj swoje wลasne powiadomienia
+user_block_success = Uลผytkownik zablokowany pomyลlnie.
+change_username_prompt = Uwaga: Zmiana nazwy uลผytkownika rรณwnieลผ zmienia URL konta.
+change_username_redirect_prompt = Stara nazwa uลผytkownika bฤdzie przekierowywaฤ dopรณki ktoล jej nie przejmie.
+hidden_comment_types = Rodzaje ukrytych komentarzy
+pronouns_unspecified = Nieokreลlone
+additional_repo_units_hint = Proponuj wลฤ
czenie dodatkowych jednostek repozytorium
+webauthn_desc = Klucze bezpieczeลstwa to urzฤ
dzenia zawierajฤ
ce klucze kryptograficzne. Mogฤ
zostaฤ uลผyte do uwierzytelniania dwuskลadnikowego. Klucze bezpieczeลstwa muszฤ
wspieraฤ standard WebAuthn Authenticator .
+uploaded_avatar_is_too_big = Rozmiar wgranego pliku (%d KiB) przekraczana rozmiar maksymalny (%d KiB).
+retype_new_password = Potwierdลบ nowe hasลo
+can_not_add_email_activations_pending = Aktywacja w toku, sprรณbuj ponownie w ciฤ
gu kolejnych kilku minut jeลผeli chcesz dodaฤ nowy e-mail.
+location_placeholder = Podziel siฤ swoim poลoลผeniem z innymi
+select_permissions = Wybierz uprawnienia
+permissions_access_all = Wszystkie (publiczne, prywatne i ograniczone)
+oauth2_application_remove_description = Usuniฤcie aplikacji OAuth2 uniemoลผliwi dostฤp autoryzowanych kont uลผytkownikรณw na tej instancji. Kontynuowaฤ?
+authorized_oauth2_applications_description = Przyznaลeล(-aล) dostฤp do swojego osobistego konta Forgejo tym aplikacjom stron trzecich. Proszฤ cofnij dostฤp dla aplikacji ktรณrych juลผ nie uลผywasz.
+twofa_scratch_token_regenerated = Twรณj jednorazowy klucz odzyskiwania to %s. Przechowuj go w bezpiecznym miejscu, gdyลผ nie bฤdzie juลผ pokazywany ponownie.
+hooks.desc = Dodaj webhooki ktรณre bฤdฤ
aktywowane dla wszystkich repozytoriรณw ktรณrych jesteล wลaลcicielem.
+visibility.private_tooltip = Widoczne tylko dla czลonkรณw organizacji do ktรณrych doลฤ
czyลeล(-aล)
+visibility.limited_tooltip = Widoczne tylko dla zalogowanych uลผytkownikรณw
+blocked_since = Zablokowany od %s
+add_key_success = Klucz SSH "%s" zostaล dodany.
+add_gpg_key_success = Klucz GPG "%s" zostaล dodany.
+valid_until_date = Waลผne do %s
+user_unblock_success = Uลผytkownik odblokowany pomyลlnie.
+create_oauth2_application_success = Pomyลlnie utworzyลeล(-aล) aplikacjฤ OAuth2.
+blocked_users = Zablokowani uลผytkownicy
+biography_placeholder = Powiedz innym coล o sobie! (Markdown jest wspierany)
+additional_repo_units_hint_description = Wyลwietl wskazรณwkฤ "Wลฤ
cz wiฤcej" dla repozytoriรณw ktรณre nie majฤ
wลฤ
czonych wszystkich jednostek.
+hidden_comment_types.ref_tooltip = Komentarze ktรณre odniosลy siฤ do zgลoszenia z innego zgลoszenia/commitu/โฆ
+hidden_comment_types.issue_ref_tooltip = Komentarze gdzie uลผytkownikรณw zmieniล gaลฤ
ลบ/tag powiฤ
zany ze zgลoszeniem
+comment_type_group_time_tracking = ลledzenie czasu
+comment_type_group_issue_ref = Odniesienie do zgลoszenia
+ssh_invalid_token_signature = Zapewniony klucz SSH, sygnatura lub token nie zgadzajฤ
siฤ lub token jest przedawniony.
+added_on = Dodane w %s
+ssh_signonly = SSH jest obecnie wyลฤ
czone wiฤc te klucze uลผywane sฤ
wyลฤ
cznie do weryfikacji podpisรณw commitรณw.
+access_token_deletion_desc = Usuniฤcie tokenu cofnie dostฤp do twojego konta aplikacjom ktรณre z niego korzystajฤ
. Ta operacja nie moลผe zostaฤ cofniฤta. Kontynuowaฤ?
+permissions_public_only = Wyลฤ
cznie publiczne
+permission_no_access = Brak dostฤpu
+permission_write = Odczyt i zapis
+at_least_one_permission = Musisz wybraฤ przynajmniej jedno uprawnienie by utworzyฤ token
+update_oauth2_application_success = Pomyลlnie zaktualizowaลeล(-aล) aplikacjฤ OAuth2.
+oauth2_confidential_client = Poufny klient. Zaznacz dla aplikacji ktรณre korzystajฤ
z ukrytego sekretu, na przykลad aplikacji przeglฤ
darkowych. Nie zaznaczaj dla aplikacji natywnych, w tym aplikacji mobilnych.
+oauth2_redirect_uris = Przekierowania URI. Proszฤ uลผyj osobnej linii dla kaลผdego URI.
+blocked_users_none = Brak zablokowanych uลผytkownikรณw.
+update_user_avatar_success = Awatar uลผytkownika zostaล zaktualizowany.
+access_token_desc = Wybrane uprawnienia tokenu ograniczajฤ
autoryzacjฤ tylko dla nastฤpujฤ
cych ลcieลผek API . Wiฤcej szczegรณลรณw znajdziesz w dokumentacji .
+profile_desc = O tobie
+pronouns = Zaimki
+pronouns_custom = Wลasne
+saved_successfully = Twoje ustawienia zostaลy zapisane pomyลlnie.
+keep_activity_private.description = Twoja aktywnoลฤ publiczna bฤdzie widoczna tylko dla ciebie i administratorรณw tej instancji.
+add_email_confirmation_sent = E-mail z potwierdzeniem zostaล wysลany do "%s". By potwierdziฤ swรณj adres e-mail, proszฤ sprawdลบ swojฤ
skrzynkฤ odbiorczฤ
i odwiedลบ dostarczony link w ciฤ
gu %s.
+verify_ssh_key_success = Klucz SSH "%s" zostaล zweryfikowany.
+twofa_recovery_tip = Jeลผeli zgubisz swoje urzฤ
dzenie, bฤdziesz mรณgล uลผyฤ jednorazowego klucza odzyskiwania by odzyskaฤ dostฤp do swojego konta.
+webauthn_key_loss_warning = Jeลผeli zgubisz swoje klucze bezpieczeลstwa, utracisz dostฤp do swojego konta.
+webauthn_alternative_tip = Moลผesz skonfigurowaฤ dodatkowฤ
metodฤ uwierzytelniania.
+user_block_yourself = Nie moลผesz zablokowaฤ siebie.
+pronouns_custom_label = Wลasne zaimki
+update_language_not_found = Jฤzyk "%s" nie jest dostฤpny.
+language.title = Domyลlny jฤzyk
+language.localization_project = Pomรณลผ nam przetลumaczyฤ Forgejo na twรณj jฤzyk! Dowiedz siฤ wiฤcej .
+update_hints = Zaktualizuj wskazรณwki
+update_hints_success = Wskazรณwki zostaลy zaktualizowane.
+change_username_redirect_prompt.with_cooldown.one = Stara nazwa uลผytkownika bฤdzie dostฤpna dla kaลผdego po okresie ochronnym wynoszฤ
cym %[1]d dzieล, nadal moลผesz uzyskaฤ z powrotem starฤ
nazwฤ uลผytkownika podczas okresu ochronnego.
+change_username_redirect_prompt.with_cooldown.few = Stara nazwa uลผytkownika bฤdzie dostฤpna dla kaลผdego po okresie ochronnym wynoszฤ
cym %[1]d dni, nadal moลผesz uzyskaฤ z powrotem starฤ
nazwฤ uลผytkownika podczas okresu ochronnego.
+language.description = Ten jฤzyk zostanie zapisany na twoim koncie i bฤdzie uลผywany jako domyลlny po zalogowaniu.
+hidden_comment_types_description = Rodzaje komentarzy zaznaczone tutaj nie bฤdฤ
wyลwietlaลy siฤ na stronach zgลoszeล. Zaznaczenie "Etykieta" na przykลad usunie wszystkie komentarze " dodaล/usunฤ
ล ".
+principal_desc = Te podmioty certyfikatu SSH bฤdฤ
powiฤ
zane z twoim kontem i pozwolฤ
na peลen dostฤp do twoich repozytoriรณw.
+add_new_principal = Dodaj podmiot
+manage_ssh_principals = Zarzฤ
dzaj podmiotami certyfikatu SSH
+principal_state_desc = Ten podmiot nie byล uลผywany w ciฤ
gu ostatnich 7 dni
+add_principal_success = Podmiot certyfikatu SSH "%s" zostaล dodany.
+keep_pronouns_private = Wyลwietlaj zaimki tylko uwierzytelnionym uลผytkownikom
+keep_pronouns_private.description = Spowoduje to ukrycie zaimkรณw przed odwiedzajฤ
cymi, ktรณrzy nie sฤ
zalogowani.
[repo]
owner=Wลaลciciel
@@ -853,13 +1062,13 @@ repo_name=Nazwa repozytorium
repo_name_helper=Dobra nazwa repozytorium jest utworzona z krรณtkich, ลatwych do zapamiฤtania i unikalnych sลรณw kluczowych.
repo_size=Rozmiar repozytorium
template=Szablon
-template_select=Wybierz szablon.
+template_select=Wybierz szablon
template_helper=Ustaw repozytorium jako szablon
template_description=Szablony repozytoriรณw pozwalajฤ
uลผytkownikom generowaฤ nowe repozytoria o takiej samej strukturze katalogรณw, plikรณw i opcjonalnych ustawieniach.
visibility=Widocznoลฤ
visibility_description=Tylko wลaลciciel lub czลonkowie organizacji, jeลli majฤ
odpowiednie uprawnienia, bฤdฤ
mogli to zobaczyฤ.
visibility_helper_forced=Administrator strony wymaga, aby nowe repozytoria byลy prywatne.
-visibility_fork_helper=(Zmiana tej wartoลci wpลynie na wszystkie forki.)
+visibility_fork_helper=(Zmiana tej wartoลci wpลynie na widocznoลฤ wszystkich forkรณw.)
clone_helper=Potrzebujesz pomocy z klonowaniem? Odwiedลบ pomoc .
fork_repo=Forkuj repozytorium
fork_from=Forkuj z
@@ -869,31 +1078,31 @@ clone_in_vsc=Klonuj w VS Code
download_zip=Pobierz ZIP
download_tar=Pobierz TAR.GZ
download_bundle=Pobierz BUNDLE
-generate_repo=Generuj repozytorium
-generate_from=Generuj z
+generate_repo=Wygeneruj repozytorium
+generate_from=Wygeneruj z
repo_desc=Opis
repo_desc_helper=Wprowadลบ krรณtki opis (opcjonalnie)
repo_lang=Jฤzyk
-repo_gitignore_helper=Wybierz szablony pliku .gitignore.
-issue_labels=Etykiety zgลoszenia
-issue_labels_helper=Wybierz zestaw etykiet zgลoszeล.
+repo_gitignore_helper=Wybierz szablony pliku .gitignore
+issue_labels=Etykiety
+issue_labels_helper=Wybierz zestaw etykiet zgลoszeล
license=Licencja
-license_helper=Wybierz plik licencji.
-license_helper_desc=Licencja reguluje co inni mogฤ
a czego nie mogฤ
zrobiฤ z Twoim kodem. Nie jesteล pewien, ktรณra licencja jest wลaลciwa dla Twojego projektu? Zobacz Wybรณr licencji.
+license_helper=Wybierz plik licencji
+license_helper_desc=Licencja reguluje co inni mogฤ
a czego nie mogฤ
zrobiฤ z Twoim kodem. Nie jesteล pewien(-na), ktรณra licencja jest wลaลciwa dla Twojego projektu? Zobacz Wybรณr licencji .
readme=README
-readme_helper=Wybierz szablonowy plik README.
+readme_helper=Wybierz szablon pliku README
readme_helper_desc=To jest miejsce, w ktรณrym moลผesz napisaฤ peลny opis swojego projektu.
-auto_init=Inicjalizuj repozytorium (dodaje .gitignore, licencjฤ i README)
+auto_init=Inicjalizuj repozytorium
trust_model_helper_default=Domyลlnie: Uลผyj domyลlnego modelu zaufania dla tej instalacji
create_repo=Utwรณrz repozytorium
-default_branch=Domyลlna gaลฤ
ลบ
+default_branch=Domyลlny branch
default_branch_helper=Domyลlny branch jest podstawowym branch'em dla pull requestรณw i commit'รณw kodu.
mirror_prune=Wyczyลฤ
mirror_prune_desc=Usuล przestarzaลe odwoลania do zdalnych ลledzeล
mirror_interval_invalid=Interwaล lustrzanej kopii jest niepoprawny.
mirror_address=Sklonuj z adresu URL
mirror_lfs=Duลผe przechowywanie plikรณw (LFS)
-mirror_lfs_endpoint=Punkt koลcowy LFS
+mirror_lfs_endpoint=Endpoint LFS
mirror_lfs_endpoint_desc=Synchronizacja sprรณbuje uลผyฤ adresu URL klonowania, aby okreลliฤ serwer LFS . Moลผesz rรณwnieลผ okreลliฤ niestandardowy punkt koลcowy, jeลli dane repozytorium LFS sฤ
przechowywane gdzieล indziej.
mirror_last_synced=Ostatnio zsynchronizowano
mirror_password_placeholder=(Nie zmieniono)
@@ -928,7 +1137,7 @@ desc.internal=Wewnฤtrzny
desc.archived=Zarchiwizowane
template.items=Elementy szablonu
-template.git_content=Zawartoลฤ gita (domyลlna gaลฤ
ลบ)
+template.git_content=Zawartoลฤ gita (Domyลlna gaลฤ
ลบ)
template.git_hooks=Hooki Git
template.webhooks=Webhooki
template.topics=Tematy
@@ -938,7 +1147,7 @@ template.one_item=Musisz wybraฤ co najmniej jeden element szablonu
template.invalid=Musisz wybraฤ repozytorium dla szablonu
archive.issue.nocomment=To repozytorium jest zarchiwizowane. Nie moลผesz komentowaฤ zgลoszeล.
-archive.pull.nocomment=To repozytorium jest zarchiwizowane. Nie moลผesz komentowaฤ Pull Requestรณw.
+archive.pull.nocomment=To repozytorium jest zarchiwizowane. Nie moลผesz komentowaฤ pull requestรณw.
form.reach_limit_of_creation_1=Osiฤ
gnฤ
ลeล juลผ limit %d repozytorium.
form.reach_limit_of_creation_n=Osiฤ
gnฤ
ลeล juลผ limit %d repozytoriรณw.
@@ -950,33 +1159,33 @@ migrate_options_lfs=Migruj pliki LFS
migrate_options_lfs_endpoint.label=Punkt koลcowy LFS
migrate_options_lfs_endpoint.description=Migracja sprรณbuje uลผyฤ Git remote, aby okreลliฤ serwer LFS . Moลผesz rรณwnieลผ okreลliฤ niestandardowy punkt koลcowy, jeลli dane repozytorium LFS sฤ
przechowywane gdzieล indziej.
migrate_options_lfs_endpoint.description.local=Obsลugiwana jest rรณwnieลผ lokalna ลcieลผka serwera.
-migrate_items=Skลadniki migracji
+migrate_items=Elementy migracji
migrate_items_wiki=Wiki
migrate_items_milestones=Kamienie milowe
migrate_items_labels=Etykiety
migrate_items_issues=Zgลoszenia
-migrate_items_pullrequests=Pull Requesty
-migrate_items_merge_requests=Merge Requests
+migrate_items_pullrequests=Pull requesty
+migrate_items_merge_requests=Requesty scalajฤ
ce
migrate_items_releases=Wydania
-migrate_repo=Przenieล repozytorium
-migrate.clone_address=Migruj/klonuj z adresu URL
+migrate_repo=Migruj repozytorium
+migrate.clone_address=Migruj / Klonuj z adresu URL
migrate.clone_address_desc=Adres HTTP(S) lub "klona" Gita istniejฤ
cego repozytorium
migrate.clone_local_path=lub ลcieลผka lokalnego serwera
migrate.permission_denied=Nie moลผesz importowaฤ lokalnych repozytoriรณw.
migrate.permission_denied_blocked=Nie moลผesz importowaฤ z niedozwolonych hostรณw, poproล administratora o sprawdzenie ustawieล ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS.
migrate.invalid_lfs_endpoint=Punkt koลcowy LFS jest nieprawidลowy.
migrate.failed=Migracja nie powiodลa siฤ: %v
-migrate.migrate_items_options=Token dostฤpu jest wymagany, aby zmigrowaฤ dodatkowe elementy
+migrate.migrate_items_options=Token dostฤpu jest wymagany, aby migrowaฤ dodatkowe elementy
migrated_from=Zmigrowane z %[2]s
-migrated_from_fake=Zmigrowane z %[1]s
+migrated_from_fake=Migrowane z %[1]s
migrate.migrate=Migracja z %s
migrate.migrating=Migrowanie z %s ...
migrate.migrating_failed=Migrowanie z %s nie powiodลo siฤ.
migrate.migrating_failed_no_addr=Migracja nie powiodลa siฤ.
-migrate.github.description=Migracja danych z github.com lub innych instancji GitHub.
+migrate.github.description=Migracja danych z github.com lub serwerรณw Github Enterprise.
migrate.git.description=Migracja repozytorium tylko z dowolnej usลugi Git.
migrate.gitlab.description=Migruj dane z gitlab.com lub innych instancji GitLab.
-migrate.gitea.description=Migruj dane z gitea.com lub innych instancji Gitea/Forgejo.
+migrate.gitea.description=Migruj dane z gitea.com lub innych instancji Gitea.
migrate.gogs.description=Migracja danych z notabug.org lub innych instancji Gogs.
migrate.onedev.description=Migracja danych z code.onedev.io lub innych instancji OneDev.
migrate.codebase.description=Migracja danych z codebasehq.com.
@@ -986,8 +1195,8 @@ migrate.migrating_topics=Migracja tematรณw
migrate.migrating_milestones=Migracja kamieni milowych
migrate.migrating_labels=Migracja etykiet
migrate.migrating_releases=Migracja wydaล
-migrate.migrating_issues=Migracja problemรณw
-migrate.migrating_pulls=Migracja Pull Requestรณw
+migrate.migrating_issues=Migracja zgลoszeล
+migrate.migrating_pulls=Migracja pull requestรณw
mirror_from=kopia lustrzana
forked_from=sforkowany z
@@ -1004,7 +1213,7 @@ fork=Forkuj
download_archive=Pobierz repozytorium
no_desc=Brak opisu
-quick_guide=Skrรณcona instrukcja
+quick_guide=Szybki przewodnik
clone_this_repo=Klonuj repozytorium
create_new_repo_command=Tworzenie nowego repozytorium z linii poleceล
push_exist_repo=Wypychanie istniejฤ
cego repozytorium z linii poleceล
@@ -1020,7 +1229,7 @@ find_tag=Znajdลบ tag
branches=Gaลฤzie
tags=Tagi
issues=Zgลoszenia
-pulls=Oczekujฤ
ce zmiany
+pulls=Pull requesty
project_board=Projekty
labels=Etykiety
org_labels_desc=Etykiety organizacji, ktรณre mogฤ
byฤ uลผywane z wszystkimi repozytoriami w tej organizacji
@@ -1036,9 +1245,9 @@ released_this=wydaล to
file.title=%s w %s
file_raw=Czysty
file_history=Historia
-file_view_source=Zobacz ลนrรณdลo
+file_view_source=Zobacz ลบrรณdลo
file_view_rendered=Wyลwietl renderowane
-file_view_raw=Zobacz czysty
+file_view_raw=Zobacz nieprzetworzony
file_permalink=Bezpoลredni odnoลnik
file_too_large=Ten plik jest zbyt duลผy, aby go wyลwietliฤ.
@@ -1046,10 +1255,11 @@ file_copy_permalink=Kopiuj bezpoลredni odnoลnik
video_not_supported_in_browser=Twoja przeglฤ
darka nie obsลuguje znacznika HTML5 "video".
audio_not_supported_in_browser=Twoja przeglฤ
darka nie obsลuguje znacznika HTML5 "audio".
stored_lfs=Przechowane za pomocฤ
Git LFS
+stored_annex=Przechowane za pomocฤ
Git Annex
symbolic_link=Dowiฤ
zanie symboliczne
commit_graph=Wykres commitรณw
commit_graph.select=Wybierz gaลฤzie
-commit_graph.hide_pr_refs=Ukryj Pull Requesty
+commit_graph.hide_pr_refs=Ukryj pull requesty
commit_graph.monochrome=Monochromatyczny
commit_graph.color=Kolor
blame=Wina
@@ -1063,6 +1273,7 @@ editor.upload_file=Wyลlij plik
editor.edit_file=Edytuj plik
editor.preview_changes=Podglฤ
d zmian
editor.cannot_edit_lfs_files=Pliki LFS nie mogฤ
byฤ edytowane poprzez interfejs przeglฤ
darkowy.
+editor.cannot_edit_annex_files=Pliki Annex nie mogฤ
byฤ edytowane poprzez interfejs przeglฤ
darkowy.
editor.cannot_edit_non_text_files=Pliki binarne nie mogฤ
byฤ edytowane poprzez interfejs przeglฤ
darkowy.
editor.edit_this_file=Edytuj plik
editor.this_file_locked=Plik jest zablokowany
@@ -1071,14 +1282,14 @@ editor.fork_before_edit=Musisz sforkowaฤ to repozytorium, aby nanieลฤ lub zap
editor.delete_this_file=Usuล plik
editor.must_have_write_access=Musisz mieฤ uprawnienia do zapisu, aby nanieลฤ lub zaproponowaฤ zmiany tego pliku.
editor.name_your_file=Nazwij plikโฆ
-editor.filename_help=Utwรณrz katalog, poprzez wpisanie jego nazwy i dodanie ukoลnika ('/'). Usuล katalog, wciskajฤ
c klawisz Backspace na poczฤ
tku pola tekstowego.
+editor.filename_help=Utwรณrz katalog, poprzez wpisanie jego nazwy i dodanie ukoลnika ("/"). Usuล katalog, wciskajฤ
c klawisz Backspace na poczฤ
tku pola tekstowego.
editor.or=lub
editor.cancel_lower=Anuluj
editor.commit_signed_changes=Zatwierdลบ podpisane zmiany
editor.commit_changes=Zatwierdลบ zmiany
-editor.add_tmpl=Dodanie ''
+editor.add_tmpl=Dodanie '<%s>'
editor.commit_message_desc=Dodaj dodatkowy rozszerzony opisโฆ
-editor.commit_directly_to_this_branch=Zmieniaj bezpoลrednio gaลฤ
ลบ %s .
+editor.commit_directly_to_this_branch=Zmieniaj bezpoลrednio gaลฤ
ลบ %[1]s .
editor.create_new_branch=Stwรณrz nowฤ
gaลฤ
ลบ dla tego commita i rozpocznij Pull Request.
editor.create_new_branch_np=Stwรณrz nowฤ
gaลฤ
ลบ dla tego commita.
editor.propose_file_change=Zaproponuj zmiany w pliku
@@ -1131,10 +1342,10 @@ projects.edit=Edytuj projekty
projects.edit_subheader=Cele pozwalajฤ
na organizacjฤ zgลoszeล i ลledzenie postฤpรณw.
projects.modify=Zaktualizuj projekt
projects.type.none=Brak
-projects.type.basic_kanban=Basic Kanban
-projects.type.bug_triage=Bug Triage
-projects.template.desc=Szablon projektu
-projects.template.desc_helper=Wybierz szablon projektu do rozpoczฤcia
+projects.type.basic_kanban=Podstawowy kanban
+projects.type.bug_triage=Segregacja bugรณw
+projects.template.desc=Szablon
+projects.template.desc_helper=Wybierz szablon projektu by rozpoczฤ
ฤ
projects.type.uncategorized=Bez kategorii
projects.column.edit_title=Nazwa
projects.column.new_title=Nazwa
@@ -1151,12 +1362,12 @@ issues.filter_reviewers=Filtruj recenzentรณw
issues.new=Nowe zgลoszenie
issues.new.title_empty=Tytuล nie moลผe byฤ pusty
issues.new.labels=Etykiety
-issues.new.no_label=Brak etykiety
+issues.new.no_label=Brak etykiet
issues.new.clear_labels=Wyczyลฤ etykiety
issues.new.projects=Projekty
issues.new.clear_projects=Wyczyลฤ projekty
issues.new.no_projects=Brak projektu
-issues.new.open_projects=Otwรณrz projekty
+issues.new.open_projects=Otwarte projekty
issues.new.closed_projects=Zamkniฤte projekty
issues.new.no_items=Brak elementรณw
issues.new.milestone=Kamieล milowy
@@ -1172,7 +1383,7 @@ issues.choose.get_started=Rozpocznij
issues.choose.open_external_link=Otwรณrz
issues.choose.blank=Domyลlny
issues.choose.blank_about=Utwรณrz problem z domyลlnego szablonu.
-issues.no_ref=Nie okreลlono gaลฤzi/etykiety
+issues.no_ref=Nie okreลlono Gaลฤzi/Etykiety
issues.create=Utwรณrz zgลoszenie
issues.new_label=Nowa etykieta
issues.new_label_placeholder=Nazwa etykiety
@@ -1247,17 +1458,17 @@ issues.context.copy_link=Skopiuj link
issues.context.quote_reply=Cytuj odpowiedลบ
issues.context.edit=Edytuj
issues.context.delete=Usuล
-issues.close_comment_issue=Skomentuj i zamknij
+issues.close_comment_issue=Zamknij z komentarzem
issues.reopen_issue=Otwรณrz ponownie
-issues.reopen_comment_issue=Skomentuj i otwรณrz ponownie
+issues.reopen_comment_issue=Otwรณrz ponownie z komentarzem
issues.create_comment=Skomentuj
issues.closed_at=`zamknฤ
ล(-ฤลa) to zgลoszenie %[2]s `
issues.reopened_at=`otworzyล(-a) ponownie to zgลoszenie %[2]s `
issues.commit_ref_at=`wspomniaล(-a) to zgลoszenie z commita %[2]s `
issues.ref_issue_from=`odwoลaล(-a) siฤ do tego zgลoszenia %[4]s %[2]s `
issues.ref_pull_from=`odwoลaล(-a) siฤ do tego Pull Requesta %[4]s %[2]s `
-issues.ref_closing_from=`odwoลaล(-a) siฤ do Pull Requesta %[4]s, ktรณry zamknie to zgลoszenie %[2]s `
-issues.ref_reopening_from=`odwoลaล(-a) siฤ do Pull Requesta %[4]s, ktรณry otworzy na nowo to zgลoszenie %[2]s `
+issues.ref_closing_from=`odwoลaล(-a) siฤ do pull requesta %[4]s, ktรณry zamknie to zgลoszenie %[2]s `
+issues.ref_reopening_from=`odwoลaล(-a) siฤ z pull requesta %[4]s, ktรณry otworzy na nowo to zgลoszenie %[2]s `
issues.ref_closed_from=`zamknฤ
ล(-ฤลa) to zgลoszenie %[4]s %[2]s `
issues.ref_reopened_from=`ponownie otworzyล(-a) to zgลoszenie %[4]s %[2]s `
issues.ref_from=`z %[1]s`
@@ -1295,12 +1506,12 @@ issues.unlock=Odblokuj konwersacjฤ
issues.lock.unknown_reason=Nie moลผna zablokowaฤ zagadnienia bez ลผadnego powodu.
issues.lock_duplicate=Zagadnienie nie moลผe byฤ zablokowane ponownie.
issues.unlock_error=Nie moลผna odblokowaฤ zagadnienia, ktรณre nie jest zablokowane.
-issues.lock_with_reason=zablokowano jako %s i ograniczono konwersacjฤ do wspรณลtwรณrcรณw %s
-issues.lock_no_reason=zablokowano i ograniczono konwersacjฤ do wspรณลtwรณrcรณw %s
+issues.lock_with_reason=zablokowano jako %s i ograniczono konwersacjฤ do wspรณลpracownikรณw %s
+issues.lock_no_reason=zablokowano i ograniczono konwersacjฤ do wspรณลpracownikรณw %s
issues.unlock_comment=odblokowano tฤ konwersacjฤ %s
issues.lock_confirm=Zablokuj
issues.unlock_confirm=Odblokuj
-issues.lock.notice_1=- Inni uลผytkownicy nie mogฤ
dodawaฤ nowych komentarzy do tego zagadnienia.
+issues.lock.notice_1=- Inni uลผytkownicy nie mogฤ
dodawaฤ nowych komentarzy do tego zgลoszenia.
issues.lock.notice_2=- Ty i inni wspรณลtwรณrcy z dostฤpem do tego repozytorium moลผecie dalej pozostawiaฤ komentarze dla innych.
issues.lock.notice_3=- Moลผesz zawsze odblokowaฤ to zagadnienie w przyszลoลci.
issues.unlock.notice_1=- Wszyscy bฤdฤ
mogli ponownie umieszczaฤ komentarze w tym zagadnieniu.
@@ -1359,7 +1570,7 @@ issues.dependency.blocked_by_short=Zaleลผy od
issues.dependency.remove_header=Usuล zaleลผnoลฤ
issues.dependency.issue_remove_text=Usunie to zaleลผnoลฤ z tego zgลoszenia. Kontynuowaฤ?
issues.dependency.pr_remove_text=Usunie to tฤ zaleลผnoลฤ z tego Pull Requesta. Kontynuowaฤ?
-issues.dependency.setting=Wลฤ
cz zaleลผnoลci dla zgลoszeล i Pull Requestรณw
+issues.dependency.setting=Wลฤ
cz zaleลผnoลci dla zgลoszeล i pull requestรณw
issues.dependency.add_error_same_issue=Zgลoszenie nie moลผe byฤ zaleลผne od siebie samego.
issues.dependency.add_error_dep_issue_not_exist=Zgลoszenie zaleลผne nie istnieje.
issues.dependency.add_error_dep_not_exist=Zaleลผnoลฤ nie istnieje.
@@ -1398,8 +1609,8 @@ compare.compare_base=baza
compare.compare_head=porรณwnaj
pulls.desc=Wลฤ
cz Pull Requesty i recenzjonowanie kodu.
-pulls.new=Nowy Pull Request
-pulls.compare_changes=Nowy Pull Request
+pulls.new=Nowy pull request
+pulls.compare_changes=Nowy pull request
pulls.compare_changes_desc=Wybierz gaลฤ
ลบ, do ktรณrej chcesz scaliฤ oraz gaลฤ
ลบ, z ktรณrej pobraฤ zmiany.
pulls.compare_base=scal do
pulls.compare_compare=ลciฤ
gnij z
@@ -1407,8 +1618,8 @@ pulls.filter_branch=Filtruj branch
pulls.no_results=Nie znaleziono wynikรณw.
pulls.nothing_to_compare=Te gaลฤzie sฤ
sobie rรณwne. Nie ma potrzeby tworzyฤ Pull Requesta.
pulls.nothing_to_compare_and_allow_empty_pr=Te gaลฤzie sฤ
rรณwne. Ten PR bฤdzie pusty.
-pulls.create=Utwรณrz Pull Request
-pulls.title_desc_few=chce scaliฤ %[1]d commity/รณw z %[2]s
do %[3]s
+pulls.create=Utwรณrz pull request
+pulls.title_desc_few=chce scaliฤ %[1]d commity/รณw z %[2]s
do %[3]s
pulls.merged_title_desc_few=scala %[1]d commity/รณw z %[2]s
do %[3]s
%[4]s
pulls.change_target_branch_at=`zmienia gaลฤ
ลบ docelowฤ
z %s na %s %s`
pulls.tab_conversation=Dyskusja
@@ -1432,7 +1643,7 @@ pulls.required_status_check_administrator=Jako administrator, moลผesz wciฤ
ลผ sc
pulls.can_auto_merge_desc=Ten Pull Request moลผe byฤ automatycznie scalony.
pulls.cannot_auto_merge_desc=Ten Pull Request nie moลผe byฤ automatycznie scalony z powodu konfliktรณw.
pulls.cannot_auto_merge_helper=Scal rฤcznie, aby rozwiฤ
zaฤ konflikty.
-pulls.num_conflicting_files_1=%d plikรณw zawierajฤ
cych konflikty
+pulls.num_conflicting_files_1=%d plik zawierajฤ
cych konflikty
pulls.num_conflicting_files_n=%d plikรณw zawierajฤ
cych konflikty
pulls.approve_count_1=%d zatwierdzenie
pulls.approve_count_n=%d zatwierdzeล
@@ -1494,7 +1705,7 @@ milestones.invalid_due_date_format=Format daty realizacji musi mieฤ wartoลฤ '
milestones.edit=Edytuj kamieล milowy
milestones.edit_subheader=Cele pozwalajฤ
zorganizowaฤ zagadnienia i ลledziฤ postฤpy.
milestones.cancel=Anuluj
-milestones.modify=Zaktualizuj cel
+milestones.modify=Zaktualizuj kamieล milowy
milestones.deletion=Usuล kamieล milowy
milestones.deletion_desc=Usuniฤcie celu usuwa go z wszystkich pozostaลych zagadnieล. Kontynuowaฤ?
milestones.deletion_success=Cel zostaล usuniฤty.
@@ -1520,7 +1731,7 @@ wiki.last_commit_info=%s edytuje tฤ stronฤ %s
wiki.edit_page_button=Edytuj
wiki.new_page_button=Nowa strona
wiki.file_revision=Wersja strony
-wiki.wiki_page_revisions=Wersje stron wiki
+wiki.wiki_page_revisions=Wersje strony
wiki.back_to_wiki=Powrรณt do strony wiki
wiki.delete_page_button=Usuล stronฤ
wiki.page_already_exists=Strona Wiki o tej samej nazwie juลผ istnieje.
@@ -1537,39 +1748,39 @@ activity.period.quarterly=3 miesiฤ
ce
activity.period.semiyearly=6 miesiฤcy
activity.period.yearly=1 rok
activity.overview=Przeglฤ
d
-activity.active_prs_count_1=%d aktywny Pull Request
-activity.active_prs_count_n=%d aktywne Pull Requesty
-activity.merged_prs_count_1=Scalono Pull Request
-activity.merged_prs_count_n=Scalone Pull Requesty
-activity.opened_prs_count_1=Proponowany Pull Request
-activity.opened_prs_count_n=Proponowane Pull Requesty
+activity.active_prs_count_1=%d aktywny pull request
+activity.active_prs_count_n=%d aktywne pull requesty
+activity.merged_prs_count_1=Scalono pull request
+activity.merged_prs_count_n=Scalone pull requesty
+activity.opened_prs_count_1=Proponowany pull request
+activity.opened_prs_count_n=Proponowane pull requesty
activity.title.user_1=%d uลผytkownik
activity.title.user_n=%d uลผytkownikรณw
-activity.title.prs_1=%d Pull Request
-activity.title.prs_n=%d Pull Requesty
+activity.title.prs_1=%d pull request
+activity.title.prs_n=%d pull requesty
activity.title.prs_merged_by=%s zmergowane przez %s
activity.title.prs_opened_by=%s zaproponowane przez %s
activity.merged_prs_label=Scalone
activity.opened_prs_label=Proponowane
-activity.active_issues_count_1=%d Aktywne zgลoszenia
-activity.active_issues_count_n=%d Aktywnych zgลoszeล
+activity.active_issues_count_1=%d aktywne zgลoszenie
+activity.active_issues_count_n=%d aktywne zgลoszenia
activity.closed_issues_count_1=Zamkniฤte zgลoszenie
activity.closed_issues_count_n=Zamkniฤte zgลoszenia
-activity.title.issues_1=%d Zgลoszenie
-activity.title.issues_n=%d Zgลoszenia
+activity.title.issues_1=%d zgลoszenie
+activity.title.issues_n=%d zgลoszenia
activity.title.issues_created_by=%s utworzone przez %s
activity.closed_issue_label=Zamkniฤty
activity.new_issues_count_1=Nowe zgลoszenie
activity.new_issues_count_n=Nowe zgลoszenia
activity.new_issue_label=Otwarte
-activity.title.unresolved_conv_1=%d Nierozstrzygniฤta dyskusja
-activity.title.unresolved_conv_n=%d Nierozstrzygniฤtych dyskusji
+activity.title.unresolved_conv_1=%d nierozstrzygniฤta dyskusja
+activity.title.unresolved_conv_n=%d nierozstrzygniฤtych dyskusji
activity.unresolved_conv_desc=Te niedawno zmienione zagadnienia i Pull Requesty nie zostaลy jeszcze rozwiฤ
zane.
activity.unresolved_conv_label=Otwarte
-activity.title.releases_1=%d Wydanie
-activity.title.releases_n=%d Wydaล
+activity.title.releases_1=%d wydanie
+activity.title.releases_n=%d wydania
activity.title.releases_published_by=%s opublikowane przez %s
-activity.published_release_label=Opublikowane
+activity.published_release_label=Wydanie
activity.no_git_activity=Nie byลo ลผadnej aktywnoลci w tym okresie czasu.
activity.git_stats_exclude_merges=Wykluczajฤ
c scalenia,
activity.git_stats_author_1=%d autor
@@ -1613,7 +1824,7 @@ settings.collaboration.undefined=Niezdefiniowany
settings.hooks=Webhooki
settings.githooks=Hooki Git
settings.basic_settings=Ustawienia podstawowe
-settings.mirror_settings=Kopia lustrzana ustawieล
+settings.mirror_settings=Ustawienia kopii lustrzanej
settings.mirror_settings.mirrored_repository=Repozytorium lustrzane
settings.mirror_settings.direction=Kierunek
settings.mirror_settings.direction.pull=Pull
@@ -1624,30 +1835,30 @@ settings.mirror_settings.push_mirror.remote_url=Adres URL zdalnego repozytorium
settings.sync_mirror=Synchronizuj teraz
settings.site=Strona
-settings.update_settings=Aktualizuj ustawienia
+settings.update_settings=Zapisz ustawienia
settings.branches.update_default_branch=Aktualizuj domyลlnฤ
gaลฤ
ลบ
settings.advanced_settings=Ustawienia zaawansowane
settings.wiki_desc=Wลฤ
cz wiki repozytorium
settings.use_internal_wiki=Uลผyj wbudowanego wiki
settings.use_external_wiki=Uลผyj zewnฤtrznego wiki
-settings.external_wiki_url=Adres URL zewnฤtrznego Wiki
+settings.external_wiki_url=Adres URL zewnฤtrznego wiki
settings.external_wiki_url_error=URL zewnฤtrznego wiki nie jest prawidลowym adresem URL.
settings.external_wiki_url_desc=Odwiedzajฤ
cy sฤ
przekierowywani do zewnฤtrznego adresu URL wiki po klikniฤciu w zakลadkฤ wiki.
-settings.issues_desc=Wลฤ
cz ลledzenie zgลoszeล w repozytorium
-settings.use_internal_issue_tracker=Uลผyj wbudowanego ลledzenia zgลoszeล
-settings.use_external_issue_tracker=Uลผyj zewnฤtrznego ลledzenia zgลoszeล
-settings.external_tracker_url=URL zewnฤtrznego systemu ลledzenia zgลoszeล
+settings.issues_desc=Wลฤ
cz dziennik zgลoszeล w repozytorium
+settings.use_internal_issue_tracker=Uลผyj wbudowanego dziennika zgลoszeล
+settings.use_external_issue_tracker=Uลผyj zewnฤtrznego dziennika zgลoszeล
+settings.external_tracker_url=URL zewnฤtrznego dziennika zgลoszeล
settings.external_tracker_url_error=Adres URL zewnฤtrznego ลledzenia zgลoszeล nie jest poprawnym adresem URL.
settings.external_tracker_url_desc=Odwiedzajฤ
cy sฤ
przekierowywani do adresu URL zewnฤtrznego systemu ลledzenia zgลoszeล po klikniฤciu w zakลadkฤ zgลoszeล.
-settings.tracker_url_format=Format adresu URL zewnฤtrznego systemu ลledzenia zgลoszeล
+settings.tracker_url_format=Format adresu URL zewnฤtrznego dziennika zgลoszeล
settings.tracker_url_format_error=Adres URL zewnฤtrznego systemu ลledzenia zgลoszeล nie jest poprawnym adresem URL.
-settings.tracker_issue_style=Format numerowania dla zewnฤtrznego systemu ลledzenia zgลoszeล
+settings.tracker_issue_style=Format numerowania dla zewnฤtrznego dziennika zgลoszeล
settings.tracker_issue_style.numeric=Numeryczny
settings.tracker_issue_style.alphanumeric=Alfanumeryczne
settings.tracker_url_format_desc=Uลผyj zamiennikรณw {user}
, {repo}
i {index}
dla nazwy uลผytkownika, nazwy repozytorium i numeru porzฤ
dkowego zgลoszenia.
settings.enable_timetracker=Wลฤ
cz ลledzenie czasu
settings.allow_only_contributors_to_track_time=Zezwalaj wyลฤ
cznie wspรณลpracownikom na ลledzenie czasu
-settings.pulls_desc=Wลฤ
cz Pull Requesty w repozytorium
+settings.pulls_desc=Wลฤ
cz pull requesty w repozytorium
settings.pulls.ignore_whitespace=Ignoruj znaki biaลe w konfliktach
settings.projects_desc=Wลฤ
cz projekty w repozytorium
settings.admin_settings=Ustawienia administratora
@@ -1692,7 +1903,7 @@ settings.trust_model.committer.long=Committer: Ufaj podpisom zgodnym z committer
settings.wiki_delete=Usuล dane Wiki
settings.wiki_delete_desc=Usuniฤcie danych wiki jest nieodwracalne.
settings.wiki_delete_notices_1=- Ta operacja usunie i wyลฤ
czy wiki repozytorium %s.
-settings.confirm_wiki_delete=Usuล dane Wiki
+settings.confirm_wiki_delete=Usuล dane wiki
settings.wiki_deletion_success=Dane wiki repozytorium zostaลy usuniฤte.
settings.delete=Usuล to repozytorium
settings.delete_desc=Usuniฤcie repozytorium jest trwaลe i nieodwracalne.
@@ -1702,7 +1913,7 @@ settings.delete_notices_fork_1=- Forki tego repozytorium bฤdฤ
niezaleลผne po j
settings.deletion_success=Repozytorium zostaลo usuniฤte.
settings.update_settings_success=Ustawienia repozytorium zostaลy zaktualizowane.
settings.confirm_delete=Usuล repozytorium
-settings.add_collaborator=Dodaj
+settings.add_collaborator=Dodaj wspรณลpracownika
settings.add_collaborator_success=Dodano uลผytkownika.
settings.add_collaborator_inactive_user=Nie moลผesz dodaฤ nieaktywnego uลผytkownika jako wspรณลpracownika.
settings.add_collaborator_duplicate=Wspรณลpracownik zostaล juลผ dodany do tego repozytorium.
@@ -1725,7 +1936,7 @@ settings.remove_team_success=Dostฤp zespoลu do repozytorium zostaล usuniฤty.
settings.add_webhook=Dodaj webhooka
settings.add_webhook.invalid_channel_name=Nazwa kanaลu Webhooka nie moลผe byฤ pusta i nie moลผe zawieraฤ jedynie znaku #.
settings.hooks_desc=Webhooki automatycznie tworzฤ
zapytania HTTP POST do serwera, kiedy nastฤpujฤ
pewne zdarzenia w Forgejo. Przeczytaj o tym wiฤcej w przewodniku o Webhookach .
-settings.webhook_deletion=Usuล Webhooka
+settings.webhook_deletion=Usuล webhooka
settings.webhook_deletion_desc=Usuniฤcie Webhooka wykasuje jego ustawienia i historiฤ dostaw. Kontynuowaฤ?
settings.webhook_deletion_success=Webhook zostaล usuniฤty.
settings.webhook.test_delivery=Testuj dostawฤ
@@ -1739,7 +1950,7 @@ settings.githook_edit_desc=Jeลli hook jest nieaktywny, zaprezentowana zostanie
settings.githook_name=Nazwa hooka
settings.githook_content=Treลฤ hooka
settings.update_githook=Zaktualizuj hook
-settings.add_webhook_desc=Forgejo wyลle ลผฤ
danie POST
z okreลlonym typem zawartoลci do docelowego adresu URL. Przeczytaj o tym wiฤcej w przewodniku o Webhookach .
+settings.add_webhook_desc=Forgejo wyลle ลผฤ
danie POST
z okreลlonym typem zawartoลci do docelowego adresu URL. Przeczytaj o tym wiฤcej w przewodniku o webhookach .
settings.payload_url=Adres docelowy URL
settings.http_method=Metoda HTTP
settings.content_type=Typ zawartoลci POST
@@ -1750,7 +1961,7 @@ settings.slack_color=Kolor
settings.discord_username=Nazwa uลผytkownika
settings.discord_icon_url=Adres URL ikony
settings.event_desc=Wywoลaj przy:
-settings.event_push_only=Wydarzeniach przepchniฤcia
+settings.event_push_only=Wydarzeniach wypchniฤcia
settings.event_send_everything=Wszystkich wydarzeniach
settings.event_choose=Niestandardowych wydarzeniachโฆ
settings.event_header_repository=Zdarzenia repozytorium
@@ -1768,39 +1979,39 @@ settings.event_push_desc=Wypchniฤcie git do repozytorium.
settings.event_repository=Repozytorium
settings.event_repository_desc=Repozytorium stworzone lub usuniฤte.
settings.event_header_issue=Zdarzenia zgลoszeล
-settings.event_issues=Zgลoszenia
+settings.event_issues=Modyfikacje
settings.event_issues_desc=Zgลoszenie otwarte, zamkniฤte, ponownie otwarte lub zmodyfikowane.
-settings.event_issue_assign=Zgลoszenie przypisane
+settings.event_issue_assign=Przypisania
settings.event_issue_assign_desc=Zgลoszenie przypisane bฤ
dลบ nieprzypisane.
-settings.event_issue_label=Zgลoszenie oznaczone
-settings.event_issue_label_desc=Etykieta zgลoszenia zaktualizowana lub usuniฤta.
-settings.event_issue_milestone=Ustawiono cel zgลoszenia
-settings.event_issue_milestone_desc=Ustawiono lub usuniฤto cel zgลoszenia.
-settings.event_issue_comment=Komentarz w zgลoszeniu
+settings.event_issue_label=Etykiety
+settings.event_issue_label_desc=Etykiety zgลoszeล zaktualizowane lub usuniฤte.
+settings.event_issue_milestone=Kamienie milowe
+settings.event_issue_milestone_desc=Dodano, usuniฤto lub zmodyfikowano kamieล milowy.
+settings.event_issue_comment=Komentarze
settings.event_issue_comment_desc=Komentarz w zgลoszeniu stworzony, edytowany lub usuniฤty.
-settings.event_header_pull_request=Zdarzenia Pull Requestรณw
-settings.event_pull_request=Pull Request
+settings.event_header_pull_request=Zdarzenia pull requestรณw
+settings.event_pull_request=Modyfikacje
settings.event_pull_request_desc=Pull request otwarty, zamkniฤty, ponownie otwarty lub zmodyfikowany.
-settings.event_pull_request_assign=Pull Request przypisany
+settings.event_pull_request_assign=Przypisania
settings.event_pull_request_assign_desc=Pull Request przypisany bฤ
dz nieprzypisany.
-settings.event_pull_request_label=Pull Request zaetykietowany
-settings.event_pull_request_label_desc=Etykieta pull requesta zaktualizowana lub usuniฤta.
-settings.event_pull_request_milestone=Ustawiono cel Pull Requesta
-settings.event_pull_request_milestone_desc=Ustawiono lub usuniฤto cel pull requesta.
-settings.event_pull_request_comment=Pull Request skomentowany
+settings.event_pull_request_label=Etykiety
+settings.event_pull_request_label_desc=Etykiety pull requestรณw zaktualizowane lub usuniฤte.
+settings.event_pull_request_milestone=Kamienie milowe
+settings.event_pull_request_milestone_desc=Ustawiono lub usuniฤto kamieล milowy pull requesta.
+settings.event_pull_request_comment=Komentarze
settings.event_pull_request_comment_desc=Komentarz pull requestu stworzony, edytowany lub usuniฤty.
-settings.event_pull_request_review=Pull Request zrecenzowany
+settings.event_pull_request_review=Recenzje
settings.event_pull_request_review_desc=Pull request zatwierdzony, odrzucony lub zrecenzowany.
-settings.event_pull_request_sync=Pull Request Zsynchronizowany
-settings.event_pull_request_sync_desc=Pull request zsynchronizowany.
+settings.event_pull_request_sync=Synchronizacja
+settings.event_pull_request_sync_desc=Gaลฤ
ลบ zaktualizowana automatycznie z gaลฤziฤ
docelowฤ
.
settings.branch_filter=Filtr gaลฤzi
settings.active=Aktywne
settings.active_helper=Informacja o wywoลanych wydarzeniach bฤdzie przesลana do tego adresu URL Webhooka.
settings.add_hook_success=Webhook zostaล dodany.
settings.update_webhook=Zaktualizuj webhook
settings.update_hook_success=Webhook zostaล zaktualizowany.
-settings.delete_webhook=Usuล Webhooka
-settings.recent_deliveries=Ostatnie wywoลania
+settings.delete_webhook=Usuล webhooka
+settings.recent_deliveries=Ostatnie dostarczenia
settings.hook_type=Typ hooka
settings.slack_token=Token
settings.slack_domain=Domena
@@ -1823,7 +2034,7 @@ settings.protected_branch=Ochrona gaลฤzi
settings.protected_branch_can_push=Umoลผliwiฤ push?
settings.protected_branch_can_push_yes=Moลผesz wysyลaฤ
settings.protected_branch_can_push_no=Nie moลผesz wysyลaฤ
-settings.branch_protection=`Ochrona gaลฤzi dla "%s "`
+settings.branch_protection=Reguลy ochrony dla gaลฤzi "%s "
settings.protect_this_branch=Wลฤ
cz ochronฤ gaลฤzi
settings.protect_this_branch_desc=Zapobiega usuniฤciu oraz ogranicza wypychanie i scalanie zmian do tej gaลฤzi.
settings.protect_disable_push=Wyลฤ
cz wypychanie
@@ -1833,23 +2044,23 @@ settings.protect_enable_push_desc=Kaลผdy uลผytkownik z uprawnieniem zapisu bฤdz
settings.protect_whitelist_committers=Wypychanie ograniczone biaลฤ
listฤ
settings.protect_whitelist_committers_desc=Tylko dopuszczeni uลผytkownicy oraz zespoลy bฤdฤ
miaลy moลผliwoลฤ wypychania zmian do tej gaลฤzi (oprรณcz wymuszenia wypchniฤcia).
settings.protect_whitelist_deploy_keys=Dozwolona lista kluczy wdroลผeniowych z uprawnieniem zapisu do push'a.
-settings.protect_whitelist_users=Uลผytkownicy dopuszczeni do wypychania:
+settings.protect_whitelist_users=Uลผytkownicy dopuszczeni do wypychania
settings.protect_whitelist_search_users=Szukaj uลผytkownikรณwโฆ
-settings.protect_whitelist_teams=Zespoลy dopuszczone do wypychania:
+settings.protect_whitelist_teams=Zespoลy dopuszczone do wypychania
settings.protect_whitelist_search_teams=Szukaj zespoลรณwโฆ
settings.protect_merge_whitelist_committers=Wลฤ
cz dopuszczenie scalania
settings.protect_merge_whitelist_committers_desc=Zezwรณl jedynie dopuszczonym uลผytkownikom lub zespoลom na scalanie Pull Requestรณw w tej gaลฤzi.
-settings.protect_merge_whitelist_users=Uลผytkownicy dopuszczeni do scalania:
-settings.protect_merge_whitelist_teams=Zespoลy dopuszczone do scalania:
+settings.protect_merge_whitelist_users=Uลผytkownicy dopuszczeni do scalania
+settings.protect_merge_whitelist_teams=Zespoลy dopuszczone do scalania
settings.protect_check_status_contexts=Wลฤ
cz kontrolฤ stanu
settings.protect_check_status_contexts_desc=Wymagaj powodzenia kontroli stanรณw przed scalaniem. Wybierz ktรณre kontrole stanรณw muszฤ
zostaฤ ukoลczone pomyลlnie, zanim gaลฤzie bฤdฤ
mogลy zostaฤ scalone z gaลฤziฤ
, ktรณra pokrywa siฤ z tฤ
zasadฤ
. Kiedy wลฤ
czone, commity muszฤ
byฤ najpierw wypchniฤte do innej gaลฤzi, a nastฤpnie scalone lub wypchniฤte bezpoลrednio do gaลฤzi, ktรณra pokrywa siฤ z tฤ
zasadฤ
po pomyลlnej kontroli stanรณw. Jeลผeli nie zostanฤ
wybrane konteksty, ostatni commit musi zakoลczyฤ siฤ powodzeniem niezaleลผnie od kontekstu.
settings.protect_check_status_contexts_list=Kontrole stanรณw w poprzednim tygodniu dla tego repozytorium
-settings.protect_required_approvals=Wymagane zatwierdzenia:
+settings.protect_required_approvals=Wymagane zatwierdzenia
settings.protect_required_approvals_desc=Zezwรณl na scalanie Pull Requestรณw tylko z wystarczajฤ
cฤ
iloลciฤ
pozytywnych recenzji.
settings.protect_approvals_whitelist_enabled=Ogranicz zatwierdzenia do dopuszczonych uลผytkownikรณw i zespoลรณw
settings.protect_approvals_whitelist_enabled_desc=Tylko recenzje pochodzฤ
ce od uลผytkownikรณw lub zespoลรณw na biaลej liลcie bฤdฤ
liczyลy siฤ do wymaganych zatwierdzeล. Bez biaลej listy zatwierdzeล, recenzja od kaลผdego uลผytkownika z uprawnieniem zapisu bฤdzie liczyลa siฤ do wymaganych zatwierdzeล.
-settings.protect_approvals_whitelist_users=Dopuszczeni recenzenci:
-settings.protect_approvals_whitelist_teams=Dopuszczone zespoลy do recenzji:
+settings.protect_approvals_whitelist_users=Dopuszczeni recenzenci
+settings.protect_approvals_whitelist_teams=Dopuszczone zespoลy do recenzji
settings.dismiss_stale_approvals=Uniewaลผnij przestarzaลe zatwierdzenia
settings.dismiss_stale_approvals_desc=Kiedy nowe commity zmieniajฤ
ce zawartoลฤ Pull Requesta sฤ
wypychane do gaลฤzi, wczeลniejsze zatwierdzenia zostanฤ
uniewaลผnione.
settings.require_signed_commits=Wymagaj podpisanych commitรณw
@@ -1864,19 +2075,19 @@ settings.block_on_official_review_requests_desc=Poลฤ
czenie nie bฤdzie moลผliw
settings.block_outdated_branch=Zablokuj scalanie, jeลli pull request jest nieaktualny
settings.block_outdated_branch_desc=Scalanie nie bฤdzie moลผliwe, gdy gaลฤ
ลบ gลรณwna jest za gaลฤziฤ
bazowฤ
.
settings.default_branch_desc=Wybierz domyลlnฤ
gaลฤ
ลบ repozytorium dla Pull Requestรณw i commitรณw kodu:
-settings.default_merge_style_desc=Domyลlny styl scalania dla pull requestรณw:
+settings.default_merge_style_desc=Domyลlny styl scalania dla pull requestรณw
settings.choose_branch=Wybierz gaลฤ
ลบโฆ
settings.no_protected_branch=Nie ma chronionych gaลฤzi.
settings.edit_protected_branch=Zmieล
settings.protected_branch_required_approvals_min=Wymagane zatwierdzenia nie mogฤ
mieฤ wartoลci ujemnej.
settings.tags=Tagi
-settings.tags.protection=Ochrona Tagรณw
+settings.tags.protection=Ochrona tagรณw
settings.tags.protection.pattern=Wzรณr tagu
settings.tags.protection.allowed=Zezwolone
settings.tags.protection.allowed.users=Dozwoleni uลผytkownicy
settings.tags.protection.allowed.teams=Dozwolone zespoลy
settings.tags.protection.allowed.noone=Brak
-settings.tags.protection.create=Chroล tag
+settings.tags.protection.create=Dodaj reguลฤ
settings.tags.protection.none=Brak chronionych tagรณw.
settings.bot_token=Token bota
settings.chat_id=ID czatu
@@ -1898,7 +2109,7 @@ settings.lfs_findcommits=Znajdลบ commity
settings.lfs_lfs_file_no_commits=Nie znaleziono commitรณw dla tego pliku LFS
settings.lfs_noattribute=Ta ลcieลผka nie ma atrybutu do zablokowania w domyลlnej gaลฤzi
settings.lfs_delete=Usuล plik LFS z OID %s
-settings.lfs_delete_warning=Usuniฤcie pliku LFS moลผe spowodowaฤ bลฤdy typu 'obiekt nie istnieje' przy checkout'cie. Czy chcesz kontynuowaฤ?
+settings.lfs_delete_warning=Usuniฤcie pliku LFS moลผe spowodowaฤ bลฤdy typu 'obiekt nie istnieje' przy checkout'cie. Czy jesteล pewien(-na)?
settings.lfs_findpointerfiles=Znajdลบ pliki wskaลบnika
settings.lfs_locks=Blokady
settings.lfs_invalid_locking_path=Nieprawidลowa ลcieลผka: %s
@@ -1910,7 +2121,7 @@ settings.lfs_locks_no_locks=Brak blokad
settings.lfs_lock_file_no_exist=Zablokowany plik nie istnieje w domyลlnej gaลฤzi
settings.lfs_force_unlock=Wymuล odblokowanie
settings.lfs_pointers.found=Znaleziono %d wskaลบnikรณw blob - %d powiฤ
zanych, %d niepowiฤ
zanych (%d brakujฤ
cych w magazynie danych)
-settings.lfs_pointers.sha=SHA bloba
+settings.lfs_pointers.sha=Hash bloba
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=W repozytorium
settings.lfs_pointers.exists=Istnieje w magazynie
@@ -1926,8 +2137,8 @@ diff.git-notes=Notatki
diff.data_not_available=Informacje nt. zmian nie sฤ
dostฤpne
diff.options_button=Opcje porรณwnania
diff.show_diff_stats=Pokaลผ statystyki
-diff.download_patch=ลciฤ
gnij plik aktualizacji
-diff.download_diff=ลciฤ
gnij plik porรณwnania
+diff.download_patch=Pobierz plik ลatki
+diff.download_diff=Pobierz plik zmian
diff.show_split_view=Widok podzielony
diff.show_unified_view=Zunifikowany widok
diff.whitespace_button=Znaki biaลe
@@ -1953,7 +2164,7 @@ diff.comment.add_single_comment=Dodaj jeden komentarz
diff.comment.add_review_comment=Dodaj komentarz
diff.comment.start_review=Rozpocznij recenzjฤ
diff.comment.reply=Odpowiedz
-diff.review=Recenzuj
+diff.review=Zakoลcz recenzjฤ
diff.review.header=Dodaj recenzjฤ
diff.review.placeholder=Komentarz recenzji
diff.review.comment=Skomentuj
@@ -1972,7 +2183,7 @@ release.draft=Szkic
release.prerelease=Wersja wstฤpna
release.stable=Stabilna
release.compare=Porรณwnaj
-release.edit=edytuj
+release.edit=Edytuj
release.ahead.commits=%d commitรณw
release.ahead.target=do %s od tego wydania
release.source_code=Kod ลบrรณdลowy
@@ -1981,10 +2192,10 @@ release.edit_subheader=Wydania pozwalajฤ
na zorganizowanie wersji projektu.
release.tag_name=Nazwa tagu
release.target=Cel
release.tag_helper=Wybierz istniejฤ
cy tag lub stwรณrz nowy.
-release.prerelease_desc=Oznacz jako wczesne wydanie
+release.prerelease_desc=Oznacz jako wersja wstฤpna
release.prerelease_helper=Oznacz to wydanie jako nieprzeznaczone na uลผytek produkcyjny.
release.cancel=Anuluj
-release.publish=Publikuj wersjฤ
+release.publish=Publikuj wydanie
release.save_draft=Zapisz szkic
release.edit_release=Zaktualizuj wydanie
release.delete_release=Usuล wydanie
@@ -2000,12 +2211,12 @@ release.tag_already_exist=Ta nazwa tag'a juลผ istnieje.
release.downloads=Pliki do pobrania
release.download_count=Pobrania: %s
release.add_tag_msg=Uลผyj tytuลu i zawartoลci wydania jako wiadomoลci znacznika.
-release.add_tag=Utwรณrz tylko znacznik
+release.add_tag=Utwรณrz tag
branch.name=Nazwa gaลฤzi
branch.delete_head=Usuล
branch.delete_html=Usuล gaลฤ
ลบ
-branch.create_branch=Utwรณrz gaลฤ
ลบ %s
+branch.create_branch=Utwรณrz gaลฤ
ลบ %s
branch.deleted_by=Usuniฤta przez %s
branch.included_desc=Ta gaลฤ
ลบ jest czฤลciฤ
domyลlnej gaลฤzi
branch.included=Zawarte
@@ -2014,7 +2225,7 @@ branch.confirm_create_branch=Utwรณrz gaลฤ
ลบ
branch.create_branch_operation=Utwรณrz gaลฤ
ลบ
branch.new_branch=Utwรณrz nowฤ
gaลฤ
ลบ
-tag.create_tag=Utwรณz tag %s
+tag.create_tag=Utwรณz tag %s
topic.manage_topics=Zarzฤ
dzaj tematami
@@ -2025,8 +2236,631 @@ topic.count_prompt=Nie moลผesz wybraฤ wiฤcej, niลผ 25 tematรณw
error.csv.too_large=Nie moลผna wyลwietliฤ tego pliku, poniewaลผ jest on zbyt duลผy.
error.csv.unexpected=Nie moลผna renderowaฤ tego pliku, poniewaลผ zawiera nieoczekiwany znak w wierszu %d i kolumnie %d.
error.csv.invalid_field_count=Nie moลผna renderowaฤ tego pliku, poniewaลผ ma nieprawidลowฤ
liczbฤ pรณl w wierszu %d.
+settings.admin_indexer_unindexed = Nieindeksowane
+settings.web_hook_name_forgejo = Forgejo
+issues.filter_poster = Autor
+issues.content_history.options = Opcje
+issues.content_history.deleted = usuniฤto
+issues.content_history.created = utworzono
+editor.patching = ลatanie:
+settings.web_hook_name_gogs = Gogs
+desc.sha256 = SHA256
+commitstatus.failure = Awaria
+settings.protect_status_check_matched = Dopasowano
+settings.web_hook_name_slack = Slack
+settings.web_hook_name_dingtalk = DingTalk
+commitstatus.success = Sukces
+wiki.cancel = Anuluj
+settings.web_hook_name_packagist = Packagist
+settings.web_hook_name_telegram = Telegram
+settings.event_package = Pakiet
+settings.web_hook_name_discord = Discord
+settings.web_hook_name_matrix = Matrix
+settings.protect_patterns = Szablony
+default_branch_label = domyลlnie
+issues.author = Autor
+commit.operations = Operacje
+commit.revert = Przywrรณฤ
+pull.deleted_branch = (usuniฤto):%s
+diff.vendored = dostarczono
+from_comment = (komentarz)
+issues.filter_project = Projekt
+mirror_sync = zsynchronizowano
+settings.web_hook_name_gitea = Gitea
+packages = Pakiety
+actions = Akcje
+issues.role.collaborator = Wspรณลpracownik
+pulls.made_using_agit = AGit
+activity.navbar.contributors = Wspรณลtwรณrcy
+diff.image.swipe = Przesuล
+settings.web_hook_name_feishu_only = Feishu
+escape_control_characters = Zakoduj
+stars = Gwiazdki
+generated = Wygenerowano
+pulls.cmd_instruction_checkout_title = Kontrola
+settings.units.overview = Podsumowanie
+fork_branch = Gaลฤ
ลบ ktรณra ma zostaฤ sklonowa do forku
+tree_path_not_found_commit = ลcieลผa %[1]s nie istnieje w commicie %[2]s
+tree_path_not_found_branch = ลcieลผka %[1]s nie istnieje w gaลฤzi %[2]s
+admin.manage_flags = Zarzฤ
dzaj flagami
+object_format_helper = Format obiektรณw repozytorium. Nie moลผe zostaฤ zmieniony pรณลบniej. SHA1 jest najbardziej kompatybilny.
+migrate_options_lfs_endpoint.placeholder = Jeลli pozostawione puste, endpoint bฤdzie uzyskany z URL clone
+repo_gitignore_helper_desc = Wybierz ktรณre pliki nie bฤdฤ
ลledzone z listy szablonowych dla powszechnych jฤzykรณw. Typowe artefakty wygenerowane przed kaลผdy z narzฤdzi jฤzyka sฤ
doลฤ
czone w .gitignore domyลlnie.
+transfer.no_permission_to_reject = Nie masz uprawnieล by odrzuciฤ ten transfer.
+transfer.no_permission_to_accept = Nie masz uprawnieล by zaakceptowaฤ ten transfer.
+form.string_too_long = Podany ciฤ
g znakรณw jest dลuลผszy niลผ %d znakรณw.
+fork_to_different_account = Utwรณrz fork do innego konta
+size_format = %[1]s: %[2]s, %[3]s: %[4]s
+rss.must_be_on_branch = Musisz byฤ na gaลฤzi by mieฤ dostฤp do kanaลu RSS.
+visibility_helper = Ustaw repozytorium jako prywatne
+mirror_address_url_invalid = Przekazany URL nie jest poprawny. Musisz zakodowaฤ wszystkie komponenty URL poprawnie.
+form.name_pattern_not_allowed = Wzรณr "%s" nie jest dozwolony w nazwie repozytorium.
+blame_prior = Zobacz blame przed tฤ
zmianฤ
+template.git_hooks_tooltip = W tym momencie nie moลผna modyfikowaฤ ani usuwaฤ hookรณw Gita ktรณre zostaลy juลผ dodane. Wybierz tฤ opcjฤ tylko jeลผeli ufasz szablonowi repozytorium.
+already_forked = Juลผ utworzyลeล(-aล) fork %s
+admin.enabled_flags = Aktywne flagi dla tego repozytorium:
+admin.flags_replaced = Flagi repozytorium zmienione
+admin.update_flags = Zaktualizuj flagi
+admin.failed_to_replace_flags = Zmiana flag repozytorium nie powiodลa siฤ
+all_branches = Wszystkie gaลฤzie
+stars_remove_warning = Ta operacja usunie wszystkie otrzymane gwiazdy tego repozytorium.
+new_repo_helper = Repozytorium zawiera wszystkie pliki projektu, wลฤ
czajฤ
c historiฤ zmian. Hostujesz juลผ jakieล gdzie-indziej? Migruj repozytorium .
+mirror_denied_combination = Nie moลผna uลผyฤ klucza publicznego i uwierzytelniania na podstawie hasลa razem.
+mirror_public_key = Publiczny klucz SSH
+mirror_use_ssh.text = Uลผyj uwierzytelniania SSH
+new_from_template = Uลผyj szablonu
+new_from_template_description = Moลผesz wybraฤ istniejฤ
cy szablon repozytorium na tej instancji i zastosowaฤ jego ustawienia.
+new_advanced = Ustawienia zaawansowane
+fork_no_valid_owners = Z tego repozytorium nie moลผna utworzyฤ forku poniewaลผ nie posiada poprawnych wลaลcicieli.
+open_with_editor = Otwรณrz przy pomocy %s
+new_advanced_expand = Kliknij by rozwinฤ
ฤ
+author_search_tooltip = Pokazuje maksymalnie 30 uลผytkownikรณw
+form.name_reserved = Nazwa repozytorium "%s" jest zarezerwowana.
+archive.title = To repozytorium zostaลo zarchiwizowane. Moลผesz podglฤ
daฤ pliki i sklonowaฤ je, ale nie moลผesz wypychaฤ, otwieraฤ zgลoszeล oraz pull requestรณw.
+archive.title_date = To repozytorium zostaลo zarchiwizone w %s. Moลผesz podglฤ
daฤ pliki i sklonowaฤ je, ale nie moลผesz wypychaฤ, otwieraฤ zgลoszeล oraz pull requestรณw.
+object_format = Format obiektรณw
+auto_init_description = Zainicjuj historiฤ Git z README oraz opcjonalnie dodaj pliki Licencji oraz .gitignore.
+mirror_use_ssh.not_available = Uwierzytelnianie SSH nie jest dostฤpne.
+mirror_sync_on_commit = Synchronizuj kiedy commity sฤ
wypychane
+summary_card_alt = Karta podsumowania repozytorium %s
+tree_path_not_found_tag = ลcieลผa %[1]s nie istnieje w tagu %[2]s
+archive.pull.noreview = To repozytorium jest zarchiwizowane. Nie moลผesz recenzowaฤ pull requestรณw.
+migrate.migrating_failed.error = Nie udaลo siฤ migrowaฤ: %s
+migrate.cancel_migrating_title = Anuluj migracjฤ
+migrate.cancel_migrating_confirm = Czy chcesz anulowaฤ tฤ migracjฤ?
+migrate.forgejo.description = Migruj dane z codeberg.org lub innych instancji Forgejo.
+migrate.github_token_desc = Moลผesz wprowadziฤ tutaj jeden lub wiฤcej tokenรณw oddzielonych przecinkiem by przeprowadziฤ migracjฤ szybciej w zwiฤ
zku z ograniczeniem GitHub API. OSTRZEลปENIE: Naduลผywanie tej funkcjonalnoลci moลผe naruszyฤ politykฤ dostawcy usลug i doprowadziฤ do zablokowania konta.
+migrate.invalid_local_path = ลcieลผka lokalna jest niepoprawna. Nie istnieje lub nie jest katalogiem.
+issues.review.add_remove_review_requests = poprosiล o recenzje od %[1]s i cofnฤ
ล proลby o recenzje od %[2]s %[3]s
+pulls.ready_for_review = Gotรณw do recenzji?
+pulls.cmd_instruction_merge_desc = Scal zmiany i zaktualizuj na Forgejo.
+editor.push_rejected_no_message = Zmiana zostaลa odrzucona przez serwer bez wiadomoลci. Proszฤ sprawdลบ hooki Git.
+settings.branches.add_new_rule = Dodaj nowฤ
reguลฤ
+issues.dependency.pr_no_dependencies = Brak ustawionych zaleลผnoลci.
+pulls.cmd_instruction_merge_warning = Ostrzeลผenie: Ustawienie "Autodetekcja rฤcznego scalenia" nie zostaลo wลฤ
czone dla tego repozytorium, bฤdziesz musiaล oznaczyฤ ten pull request jako rฤcznie scalony.
+settings.trust_model.committer.desc = Prawidลowe podpisy bฤdฤ
oznaczone jako "zaufane" tylko jeลli pasujฤ
do autora commitu, w innym wypadku bฤdฤ
oznaczone jako "niedopasowane". To zmusza Forgejo do bycia autorem commita dla podpisanych commitรณw, z rzeczywistym autorem commita oznaczonym w dopiskach Co-authored-by: i Co-commited-by: w commicie. Domyลlny klucz Forgejo musi pasowaฤ do Uลผytkownika w bazie danych.
+settings.add_collaborator_blocked_our = Nie moลผna dodaฤ wspรณลpracownika, poniewaลผ wลaลciciel repozytorium go zablokowaล.
+settings.webhook.test_delivery_desc_disabled = By przetestowaฤ webhook z przykลadowym wydarzeniem, aktywuj go.
+settings.protect_enable_merge_desc = Ktokolwiek z uprawnieniem zapisu bฤdzie mรณgล scaliฤ pull requesta do tej gaลฤzi.
+settings.unarchive.error = Wystฤ
piล bลฤ
d podczas prรณby odarchiwizowania repo. Zobacz wiฤcej szczegรณลรณw w logach.
+settings.protect_protected_file_patterns_desc = Chronione pliki nie mogฤ
zostaฤ zmienione bezpoลrednio nawet jeลli uลผytkownik ma prawa do dodawania, edytowania, lub usuwania plikรณw w tej gaลฤzi. Kilka wzorรณw moลผe byฤ oddzielone przy uลผyciu ลrednika (";"). Zobacz skลadniฤ wzorรณw w dokumentacji %[2]s . Przykลady: .drone.yml
, /docs/**/*.txt
.
+release.invalid_external_url = Nieprawidลowy zewnฤtrzny URL: "%s"
+settings.trust_model.collaboratorcommitter.desc = Prawidลowe podpisy wspรณลpracownikรณw tego repozytorium bฤdฤ
oznaczone jako "zaufane" tylko jeลli pasujฤ
do autora commitu, w innym wypadku bฤdฤ
oznaczone jako "niedopasowane". To zmusza Forgejo do bycia autorem commita dla podpisanych commitรณw, z rzeczywistym autorem commita oznaczonym w dopiskach Co-authored-by: i Co-commited-by: w commicie. Domyลlny klucz Forgejo musi pasowaฤ do Uลผytkownika w bazie danych.
+pulls.agit_explanation = Utworzone przy uลผyciu procesu pracy AGit. AGit pozwala wspรณลpracownikom proponowaฤ zmiany uลผywajฤ
c "git push" bez potrzeby tworzenia forku lub nowej gaลฤzi.
+pulls.merge_commit_id = Identyfikator commita scalajฤ
cego
+pulls.auto_merge_canceled_schedule_comment = `anulowaล(a) automatyczne scalenie tego pull requestu kiedy wszystkie weryfikacje odniosฤ
sukces %[1]s`
+settings.sourcehut_builds.access_token_helper = Token dostฤpu ktรณry ma uprawnienie JOBS:RW. Wygeneruj token builds.sr.ht lub token builds.sr.ht z dostฤpem do sekretรณw na meta.sr.ht.
+pulls.delete.text = Czy na pewno chcesz usunฤ
ฤ ten pull request? (Ta akcja permanentnie usunie caลฤ
treลฤ. Zamiast tego rozwaลผ jego zamkniฤcie, jeลผeli masz zamiar zostawiฤ go zarchiwizowanego)
+settings.sourcehut_builds.secrets_helper = Uprawnij pracฤ do budowania sekretรณw (wymaga przyznania SECRETS:RO)
+vendored = Doลฤ
czone
+editor.add = Dodaj %s
+release.message = Opisz to wydanie
+release.download_count_few = %s pobrania
+tag.create_tag_operation = Utwรณrz tag
+tag.create_success = Tag "%s" zostaล utworzony.
+editor.commit_email = E-mail commitu
+projects.edit_success = Projekt "%s" zostaล zaktualizowany.
+issues.choose.invalid_config = Konfiguracja zgลoszeล zawiera bลฤdy:
+issues.add_ref_at = `dodaล(a) odniesienie %s %s`
+issues.filter_milestone_all = Wszystkie kamienie milowe
+issues.filter_milestone_none = Brak kamieni milowych
+issues.unpin_comment = odpiฤ
ล to %s
+issues.max_pinned = Nie moลผesz przypiฤ
ฤ wiฤcej zgลoszeล
+issues.tracking_already_started = `Juลผ wลฤ
czyลeล(-aล) ลledzenie czasu na innym zgลoszeniu !`
+issues.review.option.hide_outdated_comments = Ukryj przedawnione komentarze
+pulls.cannot_merge_work_in_progress = Ten pull request jest oznaczony jako praca w toku.
+pulls.merge_pull_request = Utwรณrz commit scalajฤ
cy
+pulls.rebase_merge_pull_request = Zmiana bazy, potem fast-forward
+pulls.push_rejected = Wypchniฤcie nie powiodลo siฤ: Wypchniฤcie zostaลo odrzucone. Sprawdลบ hooki Git dla tego repozytorium.
+commits.search.tooltip = Moลผesz rozpoczฤ
ฤ sลowa kluczowe z "author:", "committer:","after:", lub "before:", np. "revert author:Alice before:2019-01-13".
+commit.revert-header = Przywrรณcenie: %s
+issues.label_exclusive_warning = Wszystkie kolidujฤ
ce etykiety z zakresem bฤdฤ
usuniฤte podczas edycji etykiet zgลoszenia lub pull requestu.
+pulls.switch_head_and_base = Zmieล head i bazฤ
+settings.add_collaborator_blocked_them = Nie moลผna dodaฤ wspรณลpracownika, poniewaลผ zablokowaล on wลaลciciela repozytorium.
+settings.web_hook_name_sourcehut_builds = Buildy SourceHut
+settings.packagist_username = Nazwa uลผytkownika Packagist
+projects.column.edit = Edytuj kolumnฤ
+issues.filter_poster_no_select = Wszyscy autorzy
+issues.closed_by = przez %[3]s zostaล zamkniฤty %[1]s
+issues.opened_by_fake = otworzony %[1]s przez %[2]s
+issues.new.assign_to_me = Przypisz do mnie
+tag.create_tag_from = Utwรณrz nowy tag z "%s"
+issues.label_archived_filter = Pokaลผ zarchiwizowane etykiety
+issues.label_archive_tooltip = Zarchiwizowane etykiety sฤ
wyลฤ
czone domyลlnie z sugestii kiedy korzysta siฤ szukania po etykietach.
+pulls.merged_info_text = Gaลฤ
ลบ %s moลผe teraz zostaฤ usuniฤta.
+milestones.create_success = Kamieล milowy "%s" zostaล utworzony.
+settings.federation_settings = Ustawienia Federacji
+settings.mirror_settings.push_mirror.add = Dodaj wypychajฤ
cฤ
kopiฤ lustrzanฤ
+settings.admin_code_indexer = Indekser kodu
+settings.ignore_stale_approvals = Ignoruj przestarzaลe zatwierdzenia
+settings.enforce_on_admins_desc = Administratorzy repozytorium nie mogฤ
ominฤ
ฤ tej reguลy.
+mirror_address_desc = Wprowadลบ wymagane dane uwierzytelniajฤ
ce w seksji Autoryzacja.
+cite_this_repo = Cytuj to repozytorium
+issues.all_title = Wszystkie
+pulls.select_commit_hold_shift_for_range = Wybierz commit. Przytrzymaj shift i kliknij by wybraฤ zakres
+pulls.review_only_possible_for_full_diff = Recenzja jest tylko moลผliwe przy wyลwietlaniu peลnych zmian
+settings.archive.mirrors_unavailable = Kopie lustrzane nie sฤ
dostฤpne dla zarchiwizowanych repozytoriรณw.
+settings.rename_branch_failed_protected = Nie moลผna zmieniฤ nazwy gaลฤzi %s poniewaลผ jest ona gaลฤziฤ
chronionฤ
.
+mirror_lfs_desc = Aktywuj kopie lustrzane danych LFS.
+branch.protected_deletion_failed = Gaลฤ
ลบ "%s" jest chroniona. Nie moลผe zostaฤ usuniฤta.
+settings.discord_icon_url.exceeds_max_length = URL ikony musi mieฤ mniej lub rรณwno 2048 znakรณw
+settings.protect_new_rule = Dodaj nowฤ
reguลฤ ochrony gaลฤzi
+settings.protect_status_check_patterns_desc = Wprowadลบ wzory do okreลlenia ktรณre weryfikacje muszฤ
przejลฤ zanim gaลฤzie zostanฤ
scalone do gaลฤzi ktรณra pasuje do reguลy. Kaลผda linia okreลla jeden wzรณr. Wzory nie mogฤ
byฤ puste.
+settings.protect_protected_file_patterns = Chronione wzory plikรณw (oddzielone przy uลผyciu ลrednika ";")
+diff.hide_file_tree = Ukryj drzewo plikรณw
+release.title_empty = Tytuล nie moลผe byฤ pusty.
+release.releases_for = Wydania dla %s
+release.system_generated = Ten zaลฤ
cznik jest automatycznie wygenerowany.
+branch.delete_desc = Usuniฤcie gaลฤzi jest permanentne. Mimo, ลผe usuniฤta gaลฤ
ลบ moลผe istnieฤ przez krรณtki czas zanim zostanie rzeczywiลcie usuniฤta, ta operacja NIE MOลปE zostaฤ cofniฤta w wiฤkszoลci przypadkรณw. Kontynuowaฤ?
+branch.rename_branch_to = Zmieล nazwฤ gaลฤzi "%s" na:
+editor.patch = Zastosuj patch
+commits.no_commits = Brak wspรณlnych commitรณw. "%s" i "%s" majฤ
zupeลnie inne historie.
+projects.create_success = Projekt "%s" zostaล utworzony.
+projects.column.assigned_to = Przypisane do
+projects.column.deletion_desc = Usuniฤcie kolumny projekty przeniesie wszystkie powiฤ
zane zgลoszenia do kolumny domyลlnej. Kontynuowaฤ?
+issues.author.tooltip.pr = Ten uลผytkownik jest autorem tego pull requesta.
+wiki.no_search_results = Brak wynikรณw
+diff.image.side_by_side = Obok siebie
+editor.fail_to_apply_patch = Nie udaลo siฤ zastosowaฤ patcha "%s"
+issues.content_history.delete_from_history_confirm = Usunฤ
ฤ z historii?
+invisible_runes_header = `Ten plik zawiera niewidoczne znaki Unicode`
+invisible_runes_description = `Ten plik zawiera niewidoczne znaki Unicode ktรณre sฤ
nierozrรณลผnialne dla ludzi, ale mogฤ
byฤ przetwarzane w inny sposรณb przez komputer. Jeลli uwaลผasz, ลผe to jest zamierzone, moลผesz bezpiecznie zignorowaฤ to ostrzeลผenie. Uลผyj klawisza Escape by je wyลwietliฤ.`
+unescape_control_characters = Zdekoduj
+editor.signoff_desc = Dodaj dopisek Signed-off-by w imieniu autora commita na koลcu wiadomoลci commita.
+editor.invalid_commit_mail = Nieprawidลowy mail do utworzenia commita.
+commit.revert-content = Wybierz gaลฤ
ลบ na ktรณrej wykonaฤ przywrรณcenie:
+projects.column.new = Nowa kolumna
+projects.card_type.text_only = Tylko tekst
+issues.comment_manually_pull_merged_at = rฤcznie scaliล commit %[1]s do %[2]s %[3]s
+issues.dependency.no_permission.can_remove = Nie masz uprawnieล do odczytu tej zaleลผnoลci, ale moลผesz usunฤ
ฤ tฤ zaleลผnoลฤ
+pulls.blocked_by_user = Nie moลผesz utworzyฤ pull requesta w tym repozytorium poniewaลผ jesteล zablokowany(-a) przez wลaลciciela repozytorium.
+wiki.delete_page_notice_1 = Usuniฤcie strony wiki "%s" nie moลผe zostaฤ cofniฤte. Kontynuowaฤ?
+wiki.reserved_page = Strona wiki o nazwie "%s" jest zarezerwowana.
+settings.branches.switch_default_branch = Zmieล domyลlnฤ
gaลฤ
ลบ
+settings.webhook.delivery.success = Wydarzenie zostaลo dodane do kolejki dorฤczeล. Moลผe to zajฤ
ฤ kilka sekund zanim pojawi siฤ w historii dorฤczeล.
+settings.authorization_header_desc = Zostanie doลฤ
czony jako nagลรณwek autoryzacji dla ลผฤ
daล kiedy bฤdzie dostฤpny. Przykลady: %s.
+settings.authorization_header = Nagลรณwek autoryzacji
+settings.protect_branch_name_pattern = Wzรณr nazwy gaลฤzi chronionej
+branch.delete_branch_has_new_commits = Gaลฤ
ลบ "%s" nie moลผe zostaฤ usuniฤta poniewaลผ nowe commity zostaลy dodane po scaleniu.
+signing.wont_sign.nokey = Ta instancja nie posiada klucza do podpisania tego commita.
+release.tag_helper_existing = Istniejฤ
cy tag.
+release.title = Tytuล wydania
+branch.create_from = z "%s"
+pulls.cmd_instruction_merge_title = Scal
+more_operations = Wiฤcej operacji
+pulls.auto_merge_button_when_succeed = (Kiedy wszystkie weryfikacje odniosฤ
sukces)
+settings.update_mirror_settings = Aktualizuj ustawienia kopii lustrzanej
+settings.pulls.default_allow_edits_from_maintainers = Pozwรณl domyลlnie na edycje przez opiekunรณw
+settings.confirmation_string = Ciฤ
g potwierdzajฤ
cy
+branch.renamed = Nazwa gaลฤzi %s zostaลa zmieniona na %s.
+issues.filter_sort.relevance = Trafnoลฤ
+issues.stop_tracking = Zatrzymaj zegar
+settings.units.units = Jednostki
+settings.mirror_settings.push_mirror.copy_public_key = Skopiuj klucz publiczny
+settings.pull_mirror_sync_quota_exceeded = Limit przekroczony, zmiany niepobrane.
+settings.tracker_issue_style.regexp_pattern = Wzรณr Wyraลผenia Regularnego
+settings.trust_model.collaboratorcommitter.long = Wspรณลpracownik+Commitujฤ
cy: Ufaj podpisom wspรณลpracownik ktรณre pasujฤ
do commitujฤ
cego
+settings.event_wiki_desc = Strona wiki zostaลa utworzona, zmieniono jej nazwฤ, edytowano lub usuniฤto.
+settings.packagist_package_url = URL pakietu Packagist
+settings.update_protect_branch_success = Ochrona gaลฤzi dla reguลy "%s" zostaลa zaktualizowana.
+topic.format_prompt = Tematy muszฤ
zaczynaฤ siฤ od litery lub liczby, mogฤ
zawieraฤ myลlniki ("-") i kropki ("."), mogฤ
byฤ dลugie do 35 znakรณw. Litery muszฤ
byฤ maลe.
+find_file.go_to_file = Szukaj pliku
+n_branch_few = %s gaลฤzie
+issues.dismiss_review = Odrzuฤ recenzjฤ
+settings.trust_model.collaboratorcommitter = Wspรณลpracownik+Commitujฤ
cy
+release.type_attachment = Zaลฤ
cznik
+release.type_external_asset = Zewnฤtrzny zasรณb
+release.asset_name = Nazwa zasobu
+release.asset_external_url = Zewnฤtrzny URL
+release.add_external_asset = Dodaj zewnฤtrzny zasรณb
+settings.transfer_abort_success = Transfer repozytorium do %s pomyลlnie anulowany.
+milestones.filter_sort.earliest_due_data = Najbliลผszy termin realizacji
+issues.remove_ref_at = `usunฤ
ล(-ฤลa) odniesienie %s %s`
+editor.file_is_a_symlink = `"%s" jest dowiฤ
zaniem symbolicznym. Dowiฤ
zania symboliczne nie mogฤ
byฤ edytowane w edytorze przeglฤ
darkowym`
+editor.unable_to_upload_files = Nie udaลo siฤ wgraฤ plikรณw do "%s", bลฤ
d: %v
+editor.upload_file_is_locked = Plik "%s" jest zablokowany przez %s.
+commits.renamed_from = Zmieniono nazwฤ z %s
+issues.filter_milestone_open = Otwarte kamienie milowe
+issues.filter_milestone_closed = Zamkniฤte kamienie milowe
+issues.role.first_time_contributor = Kontrybutor pierwszy raz
+pulls.squash_merge_pull_request = Utwรณrz squash commit
+pulls.fast_forward_only_merge_pull_request = Tylko fast-forward
+settings.web_hook_name_feishu = Feishu / Lark Suite
+settings.add_key_success = Klucz wdroลผenia "%s" zostaล dodany.
+settings.protect_unprotected_file_patterns = Niechronione wzory plikรณw (oddzielone przy uลผyciu ลrednika ";")
+branch.branch_name_conflict = Nazwa gaลฤzi "%s" koliduje z juลผ istniejฤ
cฤ
gaลฤziฤ
"%s".
+branch.restore_failed = Nie udaลo siฤ przywrรณciฤ gaลฤzi "%s".
+pulls.allow_edits_from_maintainers = Zezwalaj na zmiany przez opiekunรณw
+projects.card_type.images_and_text = Obrazy i tekst
+pulls.merged_by = przez %[3]s zostaล scalony %[1]s
+issues.num_comments_1 = %d komentarz
+issues.comment_pull_merged_at = scaliล commit %[1]s do %[2]s %[3]s
+issues.no_content = Opis zgลoszenia jest pusty.
+issues.delete.title = Usunฤ
ฤ to zgลoszenie?
+issues.delete.text = Czy na pewno chcesz usunฤ
ฤ to zgลoszenie? (Ta akcja permanentnie usunie caลฤ
treลฤ. Rozwaลผ zamkniฤcie zgลoszenia, jeลli zamierzasz pozostawiฤ je zarchiwizowane)
+issues.review.pending.tooltip = Ten komentarz bieลผฤ
co nie jest widoczny dla pozostaลych uลผytkownik. By dodaฤ twoje oczekujฤ
ce komentarze, wybierz "%s" -> "%s/%s/%s" na gรณrze strony.
+pulls.blocked_by_changed_protected_files_n = Ten pull request jest zablokowany poniewaลผ wprowadza zmiany do chronionych plikรณw:
+settings.mirror_settings.docs.can_still_use = Mimo, ลผe nie moลผesz modyfikowaฤ istniejฤ
cych kopii lustrzanych lub utworzyฤ nowych, nadal moลผesz korzystaฤ z bieลผฤ
cej kopii lustrzanej.
+settings.mirror_settings.docs.no_new_mirrors = Twoje repozytorium wykonuje kopie lustrzane do lub z innego repozytorium. Proszฤ miej na uwadze, ลผe nie moลผesz utworzyฤ nowych kopii lustrzanych w tym momencie.
+settings.mirror_settings.docs.pull_mirror_instructions = By skonfigurowaฤ kopiฤ lustrzanฤ
typu pull, proszฤ sprawdลบ:
+settings.mirror_settings.docs.disabled_push_mirror.info = Wypychajฤ
ce kopie lustrzane zostaลy wyลฤ
czone przez twojego administratora strony.
+settings.tracker_issue_style.regexp = Wyraลผenie Regularne
+branch.rename = Zmieล nazwฤ gaลฤzi "%s"
+settings.protect_no_valid_status_check_patterns = Brak prawidลowych wzorรณw weryfikacji stanu.
+issues.is_stale = Zostaลy wniesione zmiany do tego pull requesta od momentu tej recenzji
+project = Projekty
+issues.reaction.add = Dodaj reakcjฤ
+issues.reaction.alt_remove = Usuล reakcjฤ %[1]s z komentarza.
+issues.reaction.alt_add = Dodaj reakcjฤ %[1]s do komentarza.
+issues.context.menu = Menu komentarza
+issues.role.member_helper = Ten uลผytkownik jest czลonkiem organizacji ktรณra jest wลaลcicielem tego repozytorium.
+issues.reaction.alt_few = %[1]s dodaล(a) reakcjฤ %[2]s.
+issues.role.collaborator_helper = Ten uลผytkownik zostaล zaproszony do wspรณลpracy nad tym repozytorium.
+issues.reaction.alt_many = %[1]s i %[2]d wiฤcej dodali reakcjฤ %[3]s.
+issues.dependency.pr_closing_blockedby = Zamkniฤcie tego pull requesta jest zablokowane przez nastฤpujฤ
ce zgลoszenia
+settings.federation_following_repos = URLe Podฤ
ลผanych Repozytoriรณw. Rozdzielone ";", bez znakรณw biaลych.
+branch.warning_rename_default_branch = Zmieniasz nazwฤ domyลlnej gaลฤzi.
+ambiguous_runes_description = `Ten plik zawiera znaki Unicode ktรณre mogฤ
byฤ pomylone z innymi znakami. Jeลli uwaลผasz, ลผe to jest zamierzone, moลผesz bezpiecznie zignorowaฤ to ostrzeลผenie. Uลผyj klawisza Escape by je wyลwietliฤ.`
+activity.navbar.recent_commits = Ostatnie commity
+signing.wont_sign.headsigned = To scalenie nie bฤdzie podpisane poniewaลผ head commit nie jest podpisany.
+pulls.has_changed_since_last_review = Zmiany od twojej ostatniej recenzji
+find_file.no_matching = Nie znaleziono pasujฤ
cych plikรณw
+n_tag_one = %s tag
+n_tag_few = %s tagi
+n_release_few = %s wydaล
+no_eol.text = Brak znaku koลca linii
+editor.add_file = Dodaj plik
+pulls.has_merged = Niepowodzenie: Pull request zostaล scalony, nie moลผesz scaliฤ ponownie lub zmieniฤ gaลฤzi docelowej.
+issues.filter_type.review_requested = Poproszono o recenzjฤ
+issues.label_templates.fail_to_load_file = Nie udaลo siฤ zaลadowaฤ pliku szablonu etykiet "%s": %v
+issues.change_ref_at = `zmieniล(a) odniesienie z %s na %s %s`
+issues.action_check_all = Zaznacz/Odznacz wszystkie elementy
+issues.context.reference_issue = Odniesienie w nowym zgลoszeniu
+issues.role.first_time_contributor_helper = To jest pierwsza kontrybucja tego uลผytkownika w tym repozytorium.
+issues.role.contributor = Kontrybutor
+settings.event_pull_request_merge = Scalenie pull requesta
+settings.web_hook_name_msteams = Microsoft Teams
+settings.web_hook_name_wechatwork = WeCom (Wechat Work)
+settings.sourcehut_builds.secrets = Sekrety
+settings.sourcehut_builds.manifest_path = ลcieลผka manifestu budowy
+settings.sourcehut_builds.visibility = Widocznoลฤ pracy
+issues.label_exclusive_desc = Nazwij etykietฤ scope/item
by wzajemnie wykluczaลa siฤ z innymi etykietami scope/
.
+issues.archived_label_description = (Zarchiwizowano) %s
+pulls.is_ancestor = Ta gaลฤ
ลบ jest juลผ czฤลciฤ
gaลฤzi docelowej. Nie ma nic do scalenia.
+pulls.is_empty = Zmiany na tej gaลฤzi sฤ
juลผ czฤลciฤ
gaลฤzi docelowej. Commit bฤdzie pusty.
+pulls.blocked_by_approvals = Ten pull request nie ma wystarczajฤ
co zatwierdzeล. %d z %d zatwierdzeล udzielonych.
+pulls.blocked_by_rejection = Ten pull request ma proลbฤ o zmiany od oficjalnego recenzenty.
+pulls.blocked_by_official_review_requests = Ten pull request jest zablokowany poniewaลผ nie posiada zatwierdzenia od jednego lub wiฤcej oficjalnych recenzentรณw.
+pulls.wrong_commit_id = Identyfikator commitu musi byฤ identyfikatorem commitu na gaลฤzi docelowej
+pulls.rebase_merge_commit_pull_request = Zmiana bazy, potem utwรณrz commit scalajฤ
cy
+branch.tag_collision = Gaลฤ
ลบ "%s" nie moลผe zostaฤ utworzona, poniewaลผ tag z tฤ
samฤ
nazwฤ
juลผ istnieje w tym repozytorium.
+n_commit_one = %s commit
+n_commit_few = %s commity
+file_follow = Podฤ
ลผaj za dowiฤ
zaniem
+n_branch_one = %s gaลฤ
ลบ
+n_release_one = %s wydanie
+editor.new_branch_name = Nazwij nowฤ
gaลฤ
ลบ dla tego commita
+issues.action_check = Zaznacz/Odznacz
+issues.close = Zamknij zgลoszenie
+issues.label_exclusive = Wykluczajฤ
ca
+issues.cancel_tracking_history = `anulowaล(a) ลledzenie czasu %s`
+issues.dependency.no_permission_1 = Nie masz uprawnieล do odczytu %d zaleลผnoลci
+issues.dependency.issue_closing_blockedby = Zamkniฤcie tego zgลoszenia jest blokowane przez nastฤpujฤ
ce zgลoszenia
+pulls.auto_merge_newly_scheduled_comment = `zaplanowaล(a) ten pull request do automatycznego scalenia kiedy wszystkie weryfikacje odniosฤ
sukces %[1]s`
+signing.wont_sign.not_signed_in = Nie jesteล zalogowany(-a).
+settings.protected_branch.save_rule = Zapisz reguลฤ
+settings.protected_branch.delete_rule = Usuล reguลฤ
+branch.deletion_success = Gaลฤ
ลบ "%s" zostaลa usuniฤta.
+settings.rename_branch_failed_exist = Nie moลผna zmieniฤ nazwy gaลฤzi poniewaลผ gaลฤ
ลบ docelowa %s juลผ istnieje.
+settings.rename_branch_failed_not_exist = Nie moลผna zmieniฤ nazwy gaลฤzi %s poniewaลผ taka gaลฤ
ลบ nie istnieje.
+diff.file_suppressed_line_too_long = Diff pliku wstrzymany poniewaลผ jedna lub wiฤcej linii jest za dลuga
+diff.too_many_files = Niektรณre pliki nie sฤ
pokazane poniewaลผ zbyt wiele plikรณw zostaลo zmienionych w tym diffie
+diff.review.self_reject = Autorzy pull requestรณw nie mogฤ
poprosiฤ o zmiany na ich wลasnym pull requeลcie
+diff.review.self_approve = Autorzy pull requestรณw nie mogฤ
zatwierdziฤ ich wลasnych pull requestรณw
+diff.has_escaped = Ta linia ma ukryte znaki Unicode
+diff.show_file_tree = Pokaลผ drzewo plikรณw
+release.deletion_desc = Usuniฤcie wydania tylko usuwa je z Forgejo. Nie wpลynie ono na tag Git, zawartoลci twojego repozytorium lub jego historii. Kontynuowaฤ?
+release.hide_archive_links = Ukryj automatycznie wygenerowane archiwa
+release.hide_archive_links_helper = Ukryj automatycznie wygenerowane archiwa kodu ลบrรณdลowego dla tego wydania. Dla przykลadu, jeลli wgrywasz swoje wลasne.
+release.tags_for = Tagi dla %s
+branch.already_exists = Gaลฤ
ลบ o nazwie "%s" juลผ istnieje.
+branch.create_success = Gaลฤ
ลบ "%s" zostaลa utworzona.
+editor.file_delete_success = Plik "%s" zostaล usuniฤty.
+branch.branch_already_exists = Gaลฤ
ลบ "%s" juลผ istnieje w repozytorium.
+branch.new_branch_from = Utwรณrz nowฤ
gaลฤ
ลบ z "%s"
+error.broken_git_hook = Hooki Git tego repozytorium zdajฤ
siฤ byฤ zepsute. Proszฤ sprawdลบ jak je naprawiฤ w dokumentacji , a nastฤpnie wypchnij parฤ commitรณw by odลwieลผyฤ stan.
+editor.cherry_pick = Cherry-pick %s na:
+milestones.edit_success = Kamieล milowy "%s" zostaล zaktualizowany.
+activity.title.issues_closed_from = %s zamkniฤte przez %s
+settings.enforce_on_admins = Wymuล tฤ reguลฤ dla administratorรณw repozytorium
+commits.view_path = Zobacz w tym punkcie w historii
+pulls.auto_merge_cancel_schedule = Anuluj automatyczne scalenie
+settings.reindex_button = Dodaj do kolejki ponownego indeksowania
+settings.transfer.button = Przenieล wลaลcicielstwo
+commit.cherry-pick = Cherry-pick
+tag.confirm_create_tag = Utwรณrz tag
+issues.review.dismissed = odrzuciล recenzjฤ %s %s
+pulls.auto_merge_when_succeed = Automatycznie scal kiedy wszystkie weryfikacje odniosฤ
sukces
+pulls.reopen_failed.base_branch = Pull request nie moลผe zostaฤ ponownie otworzony, poniewaลผ baza gaลฤzi juลผ nie istnieje.
+pulls.auto_merge_newly_scheduled = Pull request zostaล zaplanowany do scalenia kiedy wszystkie weryfikacje odniosฤ
sukces.
+issues.dismiss_review_warning = Czy jesteล pewien(-na), ลผe chcesz odrzuciฤ tฤ recenzjฤ?
+pulls.recently_pushed_new_branches = Wypchnฤ
ลeล(-ฤลaล) na gaลฤ
ลบ %[1]s %[2]s
+subscribe.issue.guest.tooltip = Zaloguj siฤ by subskrybowaฤ to zgลoszenie.
+subscribe.pull.guest.tooltip = Zaloguj siฤ by subskrybowaฤ ten pull request.
+broken_message = Dane Git powiฤ
zane z tym repozytorium nie mogฤ
zostaฤ odczytane. Skontaktuj siฤ z administratorem tej instacji lub usuล to repozytorium.
+invisible_runes_line = `Ta linia zawiera niewidoczne znaki Unicode`
+ambiguous_runes_header = `Ten plik zawiera niejednoznaczne znaki Unicode`
+ambiguous_runes_line = `Ta linia zawiera niejednoznaczne znaki Unicode`
+ambiguous_character = `%[1]c [U+%04[1]X] moลผe byฤ pomylone z %[2]c [U+%04[2]X]`
+view_git_blame = Zobacz git blame
+executable_file = Plik wykonywalny
+commit.contained_in_default_branch = Ten commit jest czฤลciฤ
gaลฤzi domyลlnej
+commit.load_referencing_branches_and_tags = Wczytaj gaลฤzie i tagi odnoszฤ
ce siฤ do tego commitu
+no_eol.tooltip = Ten plik nie zawiera na koลcowego znaku koลca linii.
+editor.new_patch = Nowy patch
+editor.fail_to_update_file = Nie udaลo siฤ zaktualizowaฤ/utworzyฤ pliku "%s".
+commits.nothing_to_compare = Te gaลฤzie sฤ
takie same.
+commits.ssh_key_fingerprint = Odcisk klucza SSH
+projects.card_type.desc = Podglฤ
d karty
+issues.choose.ignore_invalid_templates = Nieprawidลowe szablony zostaลy zignorowane
+issues.closed_by_fake = przez %[2]s zostaล zamkniฤty %[1]s
+issues.num_reviews_few = %d recenzje
+issues.label_archive = Zarchiwizuj etykietฤ
+issues.num_participants_one = %d uczestnik
+issues.unpin_issue = Odepnij zgลoszenie
+issues.pin_comment = przypiฤ
ล to %s
+issues.due_date_modified = zmieniล termin realizacji z %[2]s na %[1]s %[3]s
+issues.dependency.issue_no_dependencies = Brak ustawionych zaleลผnoลci.
+issues.dependency.no_permission_n = Nie masz uprawnieล do odczytu %d zaleลผnoลci
+issues.dependency.issue_batch_close_blocked = Nie moลผna zamknฤ
ฤ wybranych zgลoszeล, poniewaลผ zgลoszenie #%d nadal ma otwarte zaleลผnoลci
+issues.reference_link = Odniesienie: %s
+issues.blocked_by_user = Nie moลผesz utworzyฤ zgลoszeล w tym repozytorium poniewaลผ jesteล zablokowany(-a) przez wลaลciciela repozytorium.
+pulls.view = Zobacz pull request
+issues.summary_card_alt = Podsumowanie karty zgลoszenia zatytuลowanego "%s" w repozytorium %s
+pulls.edit.already_changed = Nie moลผna zapisaฤ zmian pull requestu. Wyglฤ
da na to, ลผe zawartoลฤ zostaลa juลผ zmieniona przez innego uลผytkownika. Proszฤ odลwieลผ stronฤ i sprรณbuj edytowaฤ ponownie by uniknฤ
ฤ nadpisania ich zmian
+pulls.expand_files = Rozwiล wszystkie pliki
+pulls.merged_success = Pull request scalony pomyลlnie i zamkniฤty
+pulls.viewed_files_label = %[1]d / %[2]d plikรณw zobaczonych
+pulls.closed = Pull request zamkniฤty
+pulls.blocked_by_outdated_branch = Ten pull request jest zablokowany poniewaลผ jest przedawniony.
+pulls.blocked_by_changed_protected_files_1 = Ten pull request jest zablokowany poniewaลผ wprowadza zmiany do chronionego pliku:
+pulls.push_rejected_no_message = Wypchniฤcie nie powiodลo siฤ: Wypchniฤcie zostaลo odrzucone, ale nie otrzymano zdalnej wiadomoลci. Sprawdลบ hooki Git dla tego repozytorium.=
+pulls.commit_ref_at = `odniรณsล siฤ do tego pull requesta z commita %[2]s `
+pulls.cmd_instruction_checkout_desc = Ze swojego repozytorium projektu, utwรณrz nowฤ
gaลฤ
ลบ i przetestuj zmiany.
+pulls.clear_merge_message_hint = Wyczyszczenie wiadomoลci scalenia usunie tylko treลฤ wiadomoลci commitu pozostawiajฤ
c wygenerowane przez git dopiski takie jak "Co-Authored-By ...".
+pulls.delete_after_merge.head_branch.insufficient_branch = Nie masz uprawnieล by usunฤ
ฤ head gaลฤzi.
+pulls.delete.title = Usunฤ
ฤ ten pull request?
+milestones.update_ago = Zaktualizowano %s
+comments.edit.already_changed = Nie moลผna zapisaฤ zmian komentarza. Wyglฤ
da na to, ลผe zawartoลฤ zostaลa juลผ zmieniona przez innego uลผytkownika. Proszฤ odลwieลผ stronฤ i sprรณbuj edytowaฤ ponownie by uniknฤ
ฤ nadpisania ich zmian
+milestones.new_subheader = Kamienie milowe mogฤ
pomรณc organizowaฤ zgลoszenia i ลledziฤ ich postฤp.
+milestones.filter_sort.latest_due_date = Najdalszy termin realizacji
+signing.wont_sign.always = Commity sฤ
zawsze podpisywane.
+signing.wont_sign.pubkey = Ten commit nie bฤdzie podpisany poniewaลผ nie posiadasz ลผadnego klucza publicznego powiฤ
zanego z twoim kontem.
+signing.wont_sign.twofa = Musisz mieฤ wลฤ
czone uwierzytelnianie dwuskลadnikowe by mรณc podpisywaฤ commity.
+signing.wont_sign.parentsigned = Ten commit nie bฤdzie podpisany poniewaลผ commit rodzic nie jest podpisany.
+signing.wont_sign.basesigned = To scalenie nie bฤdzie podpisane poniewaลผ commit bazowy nie jest podpisany.
+signing.wont_sign.commitssigned = To scalenie nie bฤdzie podpisane poniewaลผ wszystkie powiฤ
zane commity nie sฤ
podpisane.
+signing.wont_sign.approved = To scalenie nie bฤdzie podpisane poniewaลผ pull request nie zostaล zatwierdzony.
+wiki.page_title = Tytuล strony
+wiki.page_content = Treลฤ strony
+wiki.page_name_desc = Wprowadลบ nazwฤ dla tej strony Wiki. Niektรณre ze specjalnych nazw to: "Home", "_Sidebar" i "_Footer".
+wiki.original_git_entry_tooltip = Zobacz oryginalny plik Git zamiast korzystaฤ z przyjaznych linkรณw.
+activity.navbar.code_frequency = Czฤstotliwoลฤ kodu
+activity.navbar.pulse = Puls
+activity.published_prerelease_label = Wersja Wstฤpna
+activity.published_tag_label = Tag
+contributors.contribution_type.filter_label = Rodzaj kontrybucji:
+contributors.contribution_type.additions = Dodania
+contributors.contribution_type.deletions = Usuniฤcia
+settings.federation_apapiurl = URL federacji tego repozytorium. Skopiuj i wklej do Ustawieล Federacji innego repozytorium jako URL ลledzonego Repozytorium.
+settings.mirror_settings.docs.disabled_pull_mirror.instructions = Ustaw swรณj projekt ลผeby automatycznie wypychaล commity, tagi i gaลฤzie do innego repozytorium. Kopie lustrzane typu pull zostaลy wyลฤ
czone przez twojego administratora strony.
+settings.mirror_settings.docs.disabled_push_mirror.instructions = Skonfiguruj swรณj projekt ลผeby automatycznie pullowaล commity, tagi i gaลฤzie z innego repozytorium.
+settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning = W tym momencie, ta akcja moลผe zostaฤ wykonana tylko poprzez menu "Nowa Migracja". Po wiฤcej informacji, proszฤ sprawdลบ:
+settings.mirror_settings.docs.doc_link_title = W jaki sposรณb mogฤ utworzyฤ kopie lustrzane repozytoriรณw?
+settings.mirror_settings.docs.pulling_remote_title = Pobieranie ze zdalnego repozytorium
+settings.mirror_settings.docs.doc_link_pull_section = sekcja "Pulling from a remote repository" w dokumentacji.
+settings.mirror_settings.pushed_repository = Wypchniฤte repozytorium
+settings.mirror_settings.push_mirror.edit_sync_time = Edytuj interwaล synchronizacji kopii lustrzanej
+settings.mirror_settings.push_mirror.none_ssh = Brak
+settings.units.add_more = Wลฤ
cz wiฤcej
+settings.wiki_globally_editable = Pozwรณl kaลผdemu edytowaฤ wiki
+settings.pull_mirror_sync_in_progress = W tym momencie zmiany sฤ
pobierane z repozytorium zdalnego %s.
+settings.push_mirror_sync_in_progress = W tym momencie zmiany sฤ
wypychane do repozytorium zdalnego %s.
+settings.tracker_issue_style.regexp_pattern_desc = Pierwsza odnaleziona grupa bฤdzie uลผyta zamiast {index}
.
+settings.pulls.default_delete_branch_after_merge = Usuล domyลlnie gaลฤ
ลบ pull requesta po scaleniu
+settings.pulls.enable_autodetect_manual_merge = Wลฤ
cz automatyczne wykrycie rฤcznego scalenia (Uwaga: W niektรณrych specjalnych przypadkach wykrycie bฤdzie nieprawidลowe)
+settings.pulls.allow_rebase_update = Wลฤ
cz aktualizowanie gaลฤzi pull requesta przez zmianฤ bazy
+settings.releases_desc = Wลฤ
cz wydania repozytorium
+settings.packages_desc = Wลฤ
cz rejestr pakietรณw repozytorium
+settings.actions_desc = Wลฤ
cz zintegrowane procesy CI/CD z Forgejo Actions
+settings.admin_indexer_commit_sha = Ostatni zaindeksowany commit
+settings.new_owner_blocked_doer = Zostaลeล(-aล) zablokowany przez nowego wลaลciciela.
+settings.reindex_requested = Ponowne indeksowanie zaลผฤ
dane
+settings.transfer_quota_exceeded = Nowy wลaลciciel (%s) przekracza limit. Repozytorium nie zostaลo przekazane.
+settings.wiki_rename_branch_main = Normalizuj nazwฤ gaลฤzi Wiki
+settings.wiki_rename_branch_main_desc = Zmieล gaลฤ
ลบ uลผywanฤ
wewnฤtrznie przez Wiki jako "%s". Ta zmiana jest permanentna i nie moลผe zostaฤ cofniฤta.
+settings.wiki_rename_branch_main_notices_1 = Ta operacja NIE MOลปE zostaฤ cofniฤta.
+settings.wiki_rename_branch_main_notices_2 = To permanentnie zmieni nazwฤ wewnฤtrznej gaลฤzi wiki dla repozytorium %s. Istniejฤ
ce checkouty bฤdฤ
musiaลy zostaฤ zaktualizowane.
+settings.wiki_branch_rename_failure = Nie udaลo siฤ znormalizowaฤ nazwy gaลฤzi wiki dla repozytorium.
+settings.confirm_wiki_branch_rename = Zmieล gaลฤ
ลบ wiki
+settings.update_settings_no_unit = Repozytorium powinno pozwalaฤ na jakฤ
kolwiek interakcjฤ.
+settings.add_collaborator_owner = Nie moลผna dodaฤ wลaลciciela jako wspรณลpracownika.
+settings.webhook.replay.description = Uruchom ponownie ten webhook.
+settings.webhook.replay.description_disabled = By uruchomiฤ ponownie ten webhook, aktywuj go.
+settings.event_pull_request_review_request = Proลby o recenzjฤ
+settings.event_pull_request_review_request_desc = Recenzja pull requesta zostaลa poproszona lub proลba o recenzjฤ zostaลa usuniฤta.
+settings.event_pull_request_approvals = Zatwierdzenia pull requesta
+settings.event_package_desc = Pakiet utworzony lub usuniฤty w repozytorium.
+settings.add_web_hook_desc = Zintegruj %s ze swoim repozytorium.
+settings.event_pull_request_enforcement = Egzekwowanie
+settings.protect_enable_merge = Wลฤ
cz scalanie
+settings.protect_status_check_patterns = Wzory weryfikacji stanu
+settings.protect_invalid_status_check_pattern = Nieprawidลowy wzรณr weryfikacji stanu: "%s".
+settings.ignore_stale_approvals_desc = Nie licz zatwierdzeล ktรณre zostaลy wykonane na starszych commitach (przestarzaลe recenzje) do iloลci zatwierdzeล ktรณre dany pull request posiada. Nie ma znaczenia gdy przestarzaลe recenzje sฤ
juลผ odrzucone.
+settings.remove_protected_branch_failed = Usuniฤcie reguลy ochrony gaลฤzi "%s" nie powiodลo siฤ.
+settings.protect_unprotected_file_patterns_desc = Niechronione pliki ktรณre mogฤ
zostaฤ zmienione bezpoลrednio jeลli uลผytkownik jest uprawniony do zapisu, pomijajฤ
c ograniczenie wypchniฤฤ. Kilka wzorรณw moลผe byฤ oddzielone przy uลผyciu ลrednika (";"). Zobacz skลadniฤ wzorรณw w dokumentacji %[2]s . Przykลady: .drone.yml
, /docs/**/*.txt
.
+settings.block_on_official_review_requests = Blokuj scalanie przy oficjalnych proลbach o recenzje
+settings.tags.protection.pattern.description = Moลผesz uลผyฤ pojedynczej nazwy, wzรณr glob lub wyraลผenia regularnego by okreลliฤ kilka tagรณw. Przeczytaj wiฤcej w przewodniku chronionych tagรณw .
+settings.unarchive.header = Odarchiwizuj to repo
+settings.rename_branch_success = Zmiana nazwy gaลฤzi z %s na %s zakoลczona pomyลlnie.
+settings.rename_branch = Zmieล nazwฤ gaลฤzi
+diff.show_more = Pokaลผ wiฤcej
+diff.load = Wczytaj diff
+pulls.cmd_instruction_hint = Zobacz instrukcje wiersza poleceล
+settings.thread_id = ID wฤ
tku
+diff.comment.add_line_comment = Dodaj komentarz do linii
+branch.restore_success = Gaลฤ
ลบ "%s" zostaลa przywrรณcona.
+branch.restore = Przywrรณฤ gaลฤ
ลบ "%s"
+branch.default_deletion_failed = Gaลฤ
ลบ "%s" jest domyลlnฤ
gaลฤziฤ
. Nie moลผe zostaฤ usuniฤta.
+branch.download = Pobierz gaลฤ
ลบ "%s"
+commit.contained_in = Ten commit jest zawarty w:
+pulls.allow_edits_from_maintainers_err = Aktualizowanie nie powiodลo siฤ
+pulls.collapse_files = Zwiล wszystkie pliki
+issues.comment.blocked_by_user = Nie moลผesz utworzyฤ komentarza do tego zgลoszenia poniewaลผ jesteล zablokowany(-a) przez wลaลciciela repozytorium lub autora zgลoszenia.
+pulls.switch_comparison_type = Zmieล rodzaj porรณwnania
+settings.branch_filter_desc = Biaลa lista gaลฤzi na wydarzenia wypchniฤcia, tworzenie gaลฤzi i usuwanie gaลฤzi, okreลlone wzorem glob. Jeลผeli puste lub *
, raportowane bฤdฤ
wydarzenia wszystkich gaลฤzi. Sprawdลบ skลadniฤ w dokumentacji %[2]s . Przykลady: master
, {master,release*}
.
+settings.remove_protected_branch_success = Ochrona gaลฤzi dla reguลy "%s" zostaลa usuniฤta.
+diff.git-notes.add = Dodaj notatkฤ
+diff.git-notes.remove-header = Usuล notatkฤ
+diff.git-notes.remove-body = Ta notatka zostanie usuniฤta.
+editor.push_out_of_date = To wypchniฤcie wyglฤ
da na nieaktualne.
+editor.file_already_exists = Plik o nazwie "%s" juลผ istnieje w tym repozytorium.
+editor.filename_is_invalid = Nazwa pliku jest nieprawidลowa: "%s".
+editor.branch_already_exists = Gaลฤ
ลบ "%s" juลผ istnieje w tym repozytorium.
+editor.directory_is_a_file = Nazwa katalogu "%s" jest juลผ uลผyta jako nazwa pliku w tym repozytorium.
+branch.delete = Usuล gaลฤ
ลบ "%s"
+wiki.search = Szukaj na wiki
+activity.commit = Aktywnoลฤ commitรณw
+release.tag_helper_new = Nowy tag. Ten tag bฤdzie utworzony z wydania docelowego.
+release.download_count_one = %s pobranie
+branch.deletion_failed = Nie udaลo siฤ usunฤ
ฤ gaลฤzi "%s".
+pulls.merged_by_fake = przez %[2]s zostaล scalony %[1]s
+settings.admin_stats_indexer = Indekser statystyk kodu
+issues.role.contributor_helper = Ten uลผytkownik juลผ wczeลniej dodaล commity do tego repozytorium.
+signing.will_sign = Ten commit zostanie podpisany kluczem "%s".
+signing.wont_sign.error = Wystฤ
piล bลฤ
d podczas sprawdzenia czy commit mรณgล zostaฤ podpisany.
+signing.wont_sign.never = Commity nie sฤ
nigdy podpisywane.
+editor.update = Aktualizuj %s
+issues.edit.already_changed = Nie moลผna zapisaฤ zmian zgลoszenia. Wyglฤ
da na to, ลผe zawartoลฤ zostaลa juลผ zmieniona przez innego uลผytkownika. Proszฤ odลwieลผ stronฤ i sprรณbuj edytowaฤ ponownie by uniknฤ
ฤ nadpisania ich zmian
+issues.choose.invalid_templates = %v nieprawidลowy(-e) szablon(y) znaleziony(-e)
+mirror_use_ssh.helper = Forgejo bฤdzie wykonywaฤ kopiฤ lustrzanฤ
repozytorium przy uลผyciu Git przez SSH i utworzy parฤ kluczy dla ciebie kiedy wybierzesz tฤ opcjฤ. Musisz najpierw upewniฤ siฤ, ลผe wygenerowany klucz publiczny jest upowaลผniony do wypychania na repozytorium docelowe. Nie moลผesz korzystaฤ z autoryzacji opartej na haลle przy wyborze tej opcji.
+commit.cherry-pick-header = Cherry-pick: %s
+ext_issues = Zewnฤtrzne zgลoszenia
+commit.cherry-pick-content = Wybierz gaลฤ
ลบ na ktรณrej wykonaฤ cherry-pick:
+projects.column.new_submit = Utwรณrz kolumnฤ
+projects.column.set_default = Ustaw jako domyลlnฤ
+projects.column.delete = Usuล kolumnฤ
+projects.column.set_default_desc = Ustaw tฤ kolumnฤ jako domyลlnฤ
dla niekategoryzowanych zgลoszeล i pullรณw
+settings.default_update_style_desc = Domyลlny styl aktualizacji uลผyty do aktualizowania pull requestรณw ktรณre sฤ
w tyle za gaลฤziฤ
gลรณwnฤ
.
+settings.transfer.modal.title = Przenieล wลaลcicielstwo
+settings.protect_branch_name_pattern_desc = Wzory nazwy gaลฤzi chronionej. Zobacz skลadniฤ wzorรณw w dokumentacji . Przykลady: main, release/**
+settings.merge_style_desc = Style scalania
+editor.delete = Usuล %s
+editor.branch_does_not_exist = Gaลฤ
ลบ "%s" nie istnieje w tym repozytorium.
+pulls.close = Zamknij pull request
+pulls.sign_in_require = Zaloguj siฤ by utworzyฤ nowy pull request.
+pulls.show_all_commits = Pokaลผ wszystkie commity
+pulls.show_changes_since_your_last_review = Pokaลผ zmiany od ostatniej twojej recenzji
+pulls.showing_only_single_commit = Pokazywane tylko zmiany commita %[1]s
+pulls.allow_edits_from_maintainers_desc = Uลผytkownicy z uprawnieniem zapisu do gaลฤzi gลรณwnej mogฤ
rรณwnieลผ wypychaฤ do tej gaลฤzi
+pulls.showing_specified_commit_range = Pokazywane tylko zmiany miฤdzy %[1]s..%[2]s
+pulls.filter_changes_by_commit = Filtruj commitem
+pulls.nothing_to_compare_have_tag = Wybrana gaลฤ
ลบ/tag sฤ
takie same.
+pulls.has_pull_request = `Pull request miฤdzy tymi gaลฤziami juลผ istnieje: %[2]s#%[3]d `
+settings.wiki_branch_rename_success = Gaลฤ
ลบ wiki dla repozytorium zostaลa znormalizowana pomyลlnie.
+settings.web_hook_name_larksuite_only = Lark Suite
+settings.packagist_api_token = Token API
+issues.force_push_codes = `wymusiล(a) wypchniฤcie %[1]s z %[2]s
do %[4]s
%[6]s`
+issues.filter_label_select_no_label = Brak etykiety
+issues.filter_project_all = Wszystkie projekty
+issues.filter_type.reviewed_by_you = Recenzowane przez ciebie
+issues.role.owner_helper = Ten uลผytkownik jest wลaลcicielem tego repozytorium.
+issues.author.tooltip.issue = Ten uลผytkownik jest autorem tego zgลoszenia.
+pulls.has_viewed_file = Zobaczone
+pulls.head_out_of_date = Scalanie nie powiodลo siฤ: W trakcie generowanie scalania, head zostaล zaktualizowany. Wskazรณwka: Sprรณbuj ponownie.
+settings.federation_not_enabled = Federacja nie jest wลฤ
czona na twojej instancji.
+settings.mirror_settings.docs = Skonfiguruj swoje repozytorium by automatycznie synchronizowaลo commity, tagi i gaลฤzie z innym repozytorium.
+settings.mirror_settings.docs.more_information_if_disabled = Moลผesz dowiedzieฤ siฤ wiฤcej o wypychajฤ
cych i pobierajฤ
cych kopiach lustrzanych tutaj:
+settings.enter_repo_name = Wprowadลบ wลaลciciela i nazwฤ repozytorium dokลadnie jak pokazane:
+settings.graphql_url = URL GraphQL
+issues.num_reviews_one = %d recenzja
+mirror_address_protocol_invalid = Wprowadzony URL jest nieprawidลowy. Tylko lokacje http(s):// lub git:// mogฤ
zostaฤ uลผyte do kopii lustrzanych.
+blame.ignore_revs = Pominiฤto zmiany w .git-blame-ignore-revs . Kliknij tutaj by ominฤ
ฤ i zobaczyฤ normalny widok blame.
+blame.ignore_revs.failed = Nie udaลo siฤ pominฤ
ฤ zmian w .git-blame-ignore-revs .
+commits.search_branch = Ta gaลฤ
ลบ
+projects.desc = Zarzฤ
dzaj zgลoszeniami i pullami w panelu projektu.
+settings.unarchive.success = Repo zostaลo odarchiwizowane pomyลlnie.
+settings.unarchive.text = Odarchiwizowanie repo przywrรณci moลผliwoลฤ otrzymywania commitรณw i wypchniฤฤ, jak i rรณwnieลผ nowych zgลoszeล i pull requestรณw.
+mirror_interval = Interwaล kopii lustrzanej (prawidลowe jednostki czasu to "h", "m", "s"). 0 wyลฤ
cza okresowฤ
synchronizacjฤ. (Minimalny interwaล: %s)
+editor.revert = Przywrรณฤ %s na:
+milestones.filter_sort.name = Nazwa
+commits.browse_further = Przeglฤ
daj dalej
+migrate_options_mirror_helper = To repozytorium bฤdzie kopiฤ
lustrzanฤ
+editor.add_tmpl.filename = nazwa pliku
+editor.filename_is_a_directory = Nazwa pliku "%s" jest juลผ uลผyta jako nazwa katalogu w tym repozytorium.
+editor.file_deleting_no_longer_exists = Usuwany plik, "%s", juลผ nie istnieje w tym repozytorium.
+editor.file_editing_no_longer_exists = Edytowany plik, "%s", juลผ nie istnieje w tym repozytorium.
+editor.commit_id_not_matching = Plik zostaล zmieniony podczas twojej edycji. Utwรณrz commit na nowej gaลฤzi, a nastฤpnie scal.
+editor.push_rejected = Zmiana zostaลa odrzucona przez serwer. Proszฤ sprawdลบ hooki Git.
+editor.upload_files_to_dir = Wgraj pliki do "%s"
+editor.cannot_commit_to_protected_branch = Nie moลผna dodaฤ commita do gaลฤzi chronionej "%s".
+issues.review.add_review_requests = poprosiล o recenzje od %[1]s %[2]s
+issues.review.remove_review_requests = cofnฤ
ล proลby o recenzje do %[1]s %[2]s
+issues.review.outdated_description = Treลฤ zostaลa zmieniona od momentu kiedy ten komentarz zostaล utworzony
+issues.review.option.show_outdated_comments = Pokaลผ przedawnione komentarze
+issues.start_tracking_short = Wystartuj zegar
+pulls.clear_merge_message = Wyczyลฤ wiadomoลฤ scalenia
+ext_wiki = Zewnฤtrzna Wiki
+settings.add_webhook.invalid_path = ลcieลผka nie moลผe zawieraฤ czฤลci ktรณra jest "." lub ".." lub pustym ciฤ
giem znakรณw. Nie moลผe rozpoczynaฤ siฤ i koลczyฤ ukoลnikiem.
+settings.githooks_desc = Hooki Git sฤ
czฤลciฤ
samego Git. Moลผesz edytowaฤ pliki hookรณw poniลผej by skonfigurowaฤ wลasne operacje.
+pulls.status_checks_hide_all = Ukryj wszystkie kontrole
+pulls.status_checks_show_all = Pokaลผ wszystkie kontrole
+pulls.reopen_failed.head_branch = Pull request nie moลผe zostaฤ ponownie otworzony, poniewaลผ head gaลฤzi juลผ nie istnieje.
+pulls.auto_merge_has_pending_schedule = %[1]s zaplanowaล by ten pull request zostaล automatycznie scalony kiedy wszystkie weryfikacje odniosฤ
sukces %[2]s.
+pulls.auto_merge_not_scheduled = Ten pull request nie jest zaplanowany do automatycznego scalenia.
+pulls.auto_merge_canceled_schedule = Automatyczne scalenie byลo anulowane dla tego pull requestu.
+pulls.delete_after_merge.head_branch.is_default = Head gaลฤzi ktรณry chcesz usunฤ
ฤ jest gaลฤziฤ
domyลlnฤ
i nie moลผe zostaฤ usuniฤty.
+pulls.delete_after_merge.head_branch.is_protected = Head gaลฤzi ktรณry chcesz usunฤ
ฤ jest gaลฤziฤ
chronionฤ
i nie moลผe zostaฤ usuniฤty.
+settings.protected_branch_required_rule_name = Wymagana nazwa reguลy
+settings.protected_branch_duplicate_rule_name = Juลผ istnieje reguลa dla tego zbioru gaลฤzi
+release.summary_card_alt = Karta podsumowania wydania zatytuลowanego "%s" w repozytorium %s
+settings.archive.text = Zarchiwizowanie tego repo sprawi, ลผe bฤdzie ono w caลoลci tylko do odczytu. Bฤdzie ukryte z pulpitu. Nikt (nawet ty!) nie bฤdzie mรณgล utworzyฤ nowych commitรณw, lub otworzyฤ jakichkolwiek zgลoszeล lub pull requestรณw.
+settings.unarchive.button = Odarchiwizuj repo
+commits.view_single_diff = Zobacz zmiany tego pliku wprowadzone w tym commicie
+tag.ahead.target = do %s od tego tagu
+settings.matrix.room_id_helper = ID Pokoju moลผe byฤ pozyskane z klienta przeglฤ
darkowego Element > Ustawienia pokoju > Zaawansowane > Wewnฤtrzne ID pokoju. Przykลad: %s.
+settings.matrix.access_token_helper = Zalecane jest skonfigurowanie dedykowany konta Matrix. Token dostฤpu moลผe zostaฤ pozyskany z przeglฤ
darkowego klienta Element (w zakลadce incognito/prywatnej) > Menu uลผytkownika (lewy gรณrny rรณg) > Wszystkie ustawienia > Pomoc i O aplikacji > Zaawansowane > Token dostฤpu (zaraz pod URL Serwera domowego). Zamknij zakลadkฤ incognito/prywatnฤ
(wylogowanie siฤ uniewaลผniลoby ten token).
+pulls.editable = Edytowalne
+pulls.editable_explanation = Ten pull request zezwala na edycje przez opiekunรณw. Moลผesz uczestniczyฤ w nim bezpoลrednio.
[graphs]
+component_loading = Wczytywanie %s...
+component_loading_failed = Nie moลผna wczytaฤ %s
+component_loading_info = To moลผe trochฤ zajฤ
ฤโฆ
+code_frequency.what = czฤstotliwoลฤ kodu
+component_failed_to_load = Wydarzyล siฤ niespodziewany bลฤ
d.
+contributors.what = kontrybucje
+recent_commits.what = ostatnie commity
[org]
org_name_holder=Nazwa organizacji
@@ -2081,21 +2915,21 @@ settings.labels_desc=Dodaj etykiety, ktรณre mogฤ
byฤ uลผywane w zgลoszeniach
members.membership_visibility=Widocznoลฤ czลonkostwa:
members.public=Widoczny
-members.public_helper=ukryj
+members.public_helper=Ukryj
members.private=Ukryty
-members.private_helper=pokaลผ
-members.member_role=Rola:
+members.private_helper=Pokaลผ
+members.member_role=Rola czลonka:
members.owner=Wลaลciciel
members.member=Czลonek
members.remove=Usuล
members.leave=Opuลฤ
-members.leave.detail=Opuลciฤ %s?
+members.leave.detail=Czy jesteล pewien(-na), ลผe chcesz opuลciฤ organizacjฤ "%s"?
members.invite_desc=Dodaj nowego czลonka do %s:
members.invite_now=Zaproล teraz
teams.join=Doลฤ
cz
teams.leave=Opuลฤ
-teams.leave.detail=Opuลciฤ %s?
+teams.leave.detail=Czy jesteล pewien(-na), ลผe chcesz opuลciฤ zespรณล "%s"?
teams.can_create_org_repo=Tworzenie repozytoriรณw
teams.can_create_org_repo_helper=Czลonkowie mogฤ
tworzyฤ nowe repozytoria w organizacji. Twรณrca otrzyma uprawnienia administracyjne do nowego repozytorium.
teams.read_access=Przeczytane
@@ -2115,7 +2949,7 @@ teams.delete_team_desc=Usuniฤcie zespoลu wycofa dostฤp do repozytorium jego c
teams.delete_team_success=Zespรณล zostaล usuniฤty.
teams.read_permission_desc=Ten zespรณล udziela dostฤpu z odczytem : czลonkowie mogฤ
wyลwietlaฤ i klonowaฤ repozytoria zespoลu.
teams.write_permission_desc=Ten zespรณล udziela dostฤpu z zapisem : czลonkowie mogฤ
wyลwietlaฤ i wypychaฤ zmiany do repozytoriรณw zespoลu.
-teams.admin_permission_desc=Ten zespรณล udziela dostฤpu administratora : czลonkowie mogฤ
wyลwietlaฤ i wypychaฤ zmiany oraz dodawaฤ wspรณลpracownikรณw do repozytoriรณw zespoลu.
+teams.admin_permission_desc=Ten zespรณล udziela dostฤpu Administratora : czลonkowie mogฤ
wyลwietlaฤ i wypychaฤ zmiany oraz dodawaฤ wspรณลpracownikรณw do repozytoriรณw zespoลu.
teams.create_repo_permission_desc=Dodatkowo, ten zespรณล otrzyma uprawnienie Tworzenie repozytoriรณw : jego czลonkowie mogฤ
tworzyฤ nowe repozytoria w organizacji.
teams.repositories=Repozytoria zespoลu
teams.search_repo_placeholder=Szukaj repozytoriumโฆ
@@ -2133,6 +2967,28 @@ teams.all_repositories_helper=Zespรณล ma dostฤp do wszystkich repozytoriรณw. W
teams.all_repositories_read_permission_desc=Ten zespรณล nadaje uprawnienie Odczytu do wszystkich repozytoriรณw : jego czลonkowie mogฤ
wyลwietlaฤ i klonowaฤ repozytoria.
teams.all_repositories_write_permission_desc=Ten zespรณล nadaje uprawnienie Zapisu do wszystkich repozytoriรณw : jego czลonkowie mogฤ
odczytywaฤ i przesyลaฤ do repozytoriรณw.
teams.all_repositories_admin_permission_desc=Ten zespรณล nadaje uprawnienia Administratora do wszystkich repozytoriรณw : jego czลonkowie mogฤ
odczytywaฤ, przesyลaฤ oraz dodawaฤ innych wspรณลtwรณrcรณw do repozytoriรณw.
+teams.write_access = Zapis
+code = Kod
+open_dashboard = Otwรณrz pulpit
+form.name_reserved = Nazwa organizacji "%s" jest zarezerwowana.
+follow_blocked_user = Nie moลผesz obserwowaฤ tej organizacji poniewaลผ ta organizacja ciebie zablokowaลa.
+settings.change_orgname_prompt = Uwaga: Zmiana nazwy organizacji zmieni rรณwnieลผ URL twojej organizacji i udostฤpni starฤ
nazwฤ.
+form.name_pattern_not_allowed = Wzรณr "%s" nie jest dozwolony w nazwie organizacji.
+settings.email = E-mail kontaktowy
+teams.general_access_helper = Uprawnienia czลonkรณw bฤdฤ
okreลlane na podstawie poniลผszej tabeli uprawnieล.
+members.remove.detail = Usunฤ
ฤ %[1]s z %[2]s?
+teams.none_access_helper = Opcja "brak dostฤpu" dotyczy tylko repozytoriรณw prywatnych.
+teams.general_access = Niestandardowy dostฤp
+teams.add_nonexistent_repo = Repozytorium ktรณre prรณbujesz dodaฤ nie istnieje, proszฤ je najpierw utworzyฤ.
+teams.invite_team_member.list = Oczekujฤ
ce zaproszenia
+settings.change_orgname_redirect_prompt.with_cooldown.few = Stara nazwa organizacji bฤdzie dostฤpna dla kaลผdego po okresie ochrony wynoszฤ
cym %[1]d dni, moลผesz nadal odzyskaฤ starฤ
nazwฤ podczas okresu ochrony.
+settings.change_orgname_redirect_prompt.with_cooldown.one = Stara nazwa organizacji bฤdzie dostฤpna dla kaลผdego po okresie ochrony wynoszฤ
cym %[1]d dzieล, moลผesz nadal odzyskaฤ starฤ
nazwฤ podczas okresu ochrony.
+teams.invite_team_member = Zaproล do %s
+settings.visibility.limited = Ograniczona (widoczne tylko dla zalogowanych uลผytkownikรณw)
+teams.none_access = Brak dostฤpu
+teams.invite.title = Zostaลeล(-aล) zaproszony(-a) do doลฤ
czenia do zespoลu %s w organizacji %s .
+teams.invite.by = Zaproszony(-a) przez %s
+teams.invite.description = Proszฤ kliknij przycisk poniลผej by doลฤ
czyฤ do zespoลu.
[admin]
dashboard=Pulpit
@@ -2141,7 +2997,7 @@ organizations=Organizacje
repositories=Repozytoria
hooks=Weebhook'i
authentication=ลนrรณdลa uwierzytelniania
-emails=Emaile uลผytkownikรณw
+emails=E-maile uลผytkownikรณw
config=Konfiguracja
notices=Powiadomienia systemu
monitor=Monitorowanie
@@ -2180,13 +3036,13 @@ dashboard.archive_cleanup=Usuล stare archiwa repozytoriรณw
dashboard.deleted_branches_cleanup=Wyczyลฤ usuniฤte galฤzie
dashboard.git_gc_repos=Wykonaj zbieranie ลmieci ze wszystkich repozytoriรณw
dashboard.resync_all_sshkeys=Zaktualizuj plik '.ssh/authorized_keys' z kluczami SSH Forgejo.
-dashboard.resync_all_sshprincipals=Zaktualizuj plik '.ssh/authorized_keys' z kluczami SSH Forgejo.
-dashboard.resync_all_hooks=Ponownie synchronizuj hooki pre-receive, update i post-receive we wszystkich repozytoriach.
+dashboard.resync_all_sshprincipals=Zaktualizuj plik ".ssh/authorized_principals" z podmiotami SSH Forgejo.
+dashboard.resync_all_hooks=Ponownie synchronizuj hooki pre-receive, update i post-receive we wszystkich repozytoriach
dashboard.reinit_missing_repos=Ponownie zainicjalizuj wszystkie brakujฤ
ce repozytoria Git, dla ktรณrych istniejฤ
ย rekordy
dashboard.sync_external_users=Synchronizuj zewnฤtrzne dane uลผytkownika
dashboard.cleanup_hook_task_table=Oczyลฤ tabelฤ hook_task
-dashboard.server_uptime=Uptime serwera
-dashboard.current_goroutine=Bieลผฤ
ce Goroutines
+dashboard.server_uptime=Czas pracy serwera
+dashboard.current_goroutine=Bieลผฤ
ce goroutines
dashboard.current_memory_usage=Bieลผฤ
ce uลผycie pamiฤci
dashboard.total_memory_allocated=Caลkowita przydzielona pamiฤฤ
dashboard.memory_obtained=Pamiฤฤ uzyskana
@@ -2218,7 +3074,7 @@ dashboard.delete_old_actions=Usuล wszystkie stare akcje z bazy danych
dashboard.delete_old_actions.started=Usuwanie wszystkich starych akcji z bazy danych rozpoczฤte.
users.user_manage_panel=Zarzฤ
dzanie kontami uลผytkownikรณw
-users.new_account=Nowy uลผytkownik
+users.new_account=Utwรณrz konto uลผytkownika
users.name=Nazwa uลผytkownika
users.full_name=Imiฤ i nazwisko
users.activated=Aktywny
@@ -2228,7 +3084,7 @@ users.2fa=2FA
users.repos=Repozytoria
users.created=Utworzony
users.last_login=Ostatnie logowanie
-users.never_login=Nigdy nie zalogowaล(-a) siฤ
+users.never_login=Nigdy nie zalogowaล(a) siฤ
users.send_register_notify=Wyลlij uลผytkownikowi powiadomienie o rejestracji
users.edit=Edytuj
users.auth_source=ลนrรณdลo uwierzytelniania
@@ -2239,12 +3095,12 @@ users.update_profile_success=Konto uลผytkownika zostaลo zaktualizowane.
users.edit_account=Edytuj konto uลผytkownika
users.max_repo_creation=Maksymalna iloลฤ repozytoriรณw
users.max_repo_creation_desc=(Wpisz -1, aby uลผyฤ domyลlnego globalnego limitu.)
-users.is_activated=Konto uลผytkownika jest aktywne
-users.prohibit_login=Wyลฤ
cz logowanie
-users.is_admin=Jest administratorem
-users.is_restricted=Jest ograniczone
+users.is_activated=Aktywne konto
+users.prohibit_login=Zawieszone konto
+users.is_admin=Konto administratora
+users.is_restricted=Ograniczone konto
users.allow_git_hook=Moลผe tworzyฤ hooki Gita
-users.allow_git_hook_tooltip=Git Hook'i sฤ
wykonywane jako uลผytkownik systemu operacyjnego obsลugujฤ
cy Forgejo i bฤdฤ
miaลy taki sam poziom dostฤpu jak host. W rezultacie uลผytkownicy z tym specjalnym przywilejem Git Hook mogฤ
uzyskaฤ dostฤp i modyfikowaฤ wszystkie repozytoria Forgejo oraz bazฤ danych uลผywanฤ
przez Forgejo. W zwiฤ
zku z tym sฤ
oni rรณwnieลผ w stanie zdobyฤ uprawnienia administratora Forgejo.
+users.allow_git_hook_tooltip=Hooki Git sฤ
wykonywane jako uลผytkownik systemu operacyjnego obsลugujฤ
cy Forgejo i bฤdฤ
miaลy taki sam poziom dostฤpu jak host. W rezultacie uลผytkownicy z tym specjalnym przywilejem Git hook mogฤ
uzyskaฤ dostฤp i modyfikowaฤ wszystkie repozytoria Forgejo oraz bazฤ danych uลผywanฤ
przez Forgejo. W zwiฤ
zku z tym sฤ
oni rรณwnieลผ w stanie zdobyฤ uprawnienia administratora Forgejo.
users.allow_import_local=Moลผe importowaฤ lokalne repozytoria
users.allow_create_organization=Moลผe tworzyฤ organizacje
users.update_profile=Zaktualizuj konto uลผytkownika
@@ -2257,7 +3113,7 @@ users.list_status_filter.is_active=Aktywne
users.list_status_filter.is_admin=Administrator
users.list_status_filter.is_restricted=Ograniczone
-emails.email_manage_panel=Zarzฤ
dzanie adresami email
+emails.email_manage_panel=Zarzฤ
dzanie adresami e-mail
emails.primary=Podstawowy
emails.activated=Aktywowany
emails.filter_sort.email=E-mail
@@ -2269,7 +3125,7 @@ emails.not_updated=Nie udaลo siฤ zaktualizowaฤ ลผฤ
danego adresu e-mail: %v
emails.duplicate_active=Ten e-mail jest juลผ aktywny dla innego uลผytkownika.
emails.change_email_header=Aktualizuj wลaลciwoลci adresu e-mail
-orgs.org_manage_panel=Zarzฤ
dzanie organizacjฤ
+orgs.org_manage_panel=Zarzฤ
dzanie organizacjami
orgs.name=Nazwa
orgs.teams=Zespoลy
orgs.members=Czลonkowie
@@ -2277,7 +3133,7 @@ orgs.new_orga=Nowa organizacja
repos.repo_manage_panel=Zarzฤ
dzanie repozytoriami
repos.unadopted=Nieprzyjฤte repozytoria
-repos.unadopted.no_more=Nie znaleziono wiฤcej nieprzyjฤtych repozytoriรณw
+repos.unadopted.no_more=Nie znaleziono wiฤcej nieadoptowanych repozytoriรณw.
repos.owner=Wลaลciciel
repos.name=Nazwa
repos.private=Prywatne
@@ -2293,11 +3149,11 @@ packages.type=Typ
packages.repository=Repozytorium
packages.size=Rozmiar
-defaulthooks=Domyลlne Webhooki
+defaulthooks=Domyลlne webhooki
defaulthooks.add_webhook=Dodaj domyลlny Webhook
defaulthooks.update_webhook=Zaktualizuj domyลlny Webhook
-systemhooks=Webhooki Systemowe
+systemhooks=Webhooki systemowe
systemhooks.add_webhook=Dodaj Webhook Systemowy
systemhooks.update_webhook=Aktualizuj Webhook Systemowy
@@ -2331,7 +3187,7 @@ auths.search_page_size=Rozmiar strony
auths.filter=Filtr uลผytkownika
auths.admin_filter=Filtr administratora
auths.restricted_filter=Filtr ograniczenia
-auths.restricted_filter_helper=Pozostaw puste, aby nie ustawiaฤ ลผadnych uลผytkownikรณw jako ograniczonych. Uลผyj gwiazdki ('*'), aby ustawiฤ wszystkich uลผytkownikรณw, ktรณrzy nie pasujฤ
do Filtra Administratora jako ograniczonych.
+auths.restricted_filter_helper=Pozostaw puste, aby nie ustawiaฤ ลผadnych uลผytkownikรณw jako ograniczonych. Uลผyj gwiazdki ('*'), aby ustawiฤ wszystkich uลผytkownikรณw, ktรณrzy nie pasujฤ
do filtra Administratora jako ograniczonych.
auths.ms_ad_sa=Atrybuty wyszukiwania MS AD
auths.smtp_auth=Typ uwierzytelnienia SMTP
auths.smtphost=Serwer SMTP
@@ -2367,17 +3223,17 @@ auths.sspi_default_language_helper=Domyลlny jฤzyk dla uลผytkownikรณw automatyc
auths.tips=Wskazรณwki
auths.tips.oauth2.general=Uwierzytelnianie OAuth2
auths.tip.oauth2_provider=Dostawca OAuth2
-auths.tip.bitbucket=`Zarejestruj nowego konsumenta OAuth na https://bitbucket.org/account/user//oauth-consumers/new i dodaj uprawnienie "Account" - "Read"`
+auths.tip.bitbucket=`Zarejestruj nowego konsumenta OAuth na %s
auths.tip.nextcloud=`Zarejestruj nowego klienta OAuth w swojej instancji za pomocฤ
menu "Ustawienia -> Bezpieczeลstwo -> Klient OAuth 2.0"`
-auths.tip.dropbox=Stwรณrz nowฤ
aplikacjฤ na https://www.dropbox.com/developers/apps
-auths.tip.facebook=`Zarejestruj nowฤ
aplikacjฤ na https://developers.facebook.com/apps i dodaj produkt "Facebook Login"`
-auths.tip.github=Zarejestruj nowฤ
aplikacjฤ OAuth na https://github.com/settings/applications/new
+auths.tip.dropbox=Stwรณrz nowฤ
aplikacjฤ na %s
+auths.tip.facebook=`Zarejestruj nowฤ
aplikacjฤ na %s i dodaj produkt "Facebook Login"`
+auths.tip.github=Zarejestruj nowฤ
aplikacjฤ OAuth na %s
auths.tip.gitlab=Zarejestruj nowฤ
aplikacjฤ na https://gitlab.com/profile/applications
-auths.tip.google_plus=Uzyskaj dane uwierzytelniajฤ
ce klienta OAuth2 z konsoli Google API na https://console.developers.google.com/
+auths.tip.google_plus=Uzyskaj dane uwierzytelniajฤ
ce klienta OAuth2 z konsoli Google API na %s
auths.tip.openid_connect=Uลผyj adresu URL OpenID Connect Discovery (/.well-known/openid-configuration), aby okreลliฤ punkty koลcowe
-auths.tip.twitter=Przejdลบ na https://dev.twitter.com/apps, stwรณrz aplikacjฤ i upewnij siฤ, ลผe opcja โAllow this application to be used to Sign in with Twitterโ jest wลฤ
czona
-auths.tip.discord=Zarejestruj nowฤ
aplikacjฤ na https://discordapp.com/developers/applications/me
-auths.tip.yandex=`Utwรณrz nowฤ
aplikacjฤ na https://oauth.yandex.com/client/new. Wybierz nastฤpujฤ
ce uprawnienia z "Yandex.Passport API": "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"`
+auths.tip.twitter=Przejdลบ na %s, stwรณrz aplikacjฤ i upewnij siฤ, ลผe opcja โAllow this application to be used to Sign in with Twitterโ jest wลฤ
czona
+auths.tip.discord=Zarejestruj nowฤ
aplikacjฤ na %s
+auths.tip.yandex=`Utwรณrz nowฤ
aplikacjฤ na %s. Wybierz nastฤpujฤ
ce uprawnienia z "Yandex.Passport API": "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"`
auths.tip.mastodon=Wprowadลบ niestandardowy adres URL instancji mastodona, ktรณrฤ
chcesz uwierzytelniฤ (lub uลผyj domyลlnego)
auths.edit=Edytuj ลบrรณdลo uwierzytelniania
auths.activated=To ลบrรณdลo uwierzytelniania jest aktywne
@@ -2391,9 +3247,9 @@ auths.deletion_success=ลนrรณdลo uwierzytelniania zostaลo usuniฤte.
auths.login_source_of_type_exist=ลนrรณdลo uwierzytelniania tego typu juลผ istnieje.
config.server_config=Konfiguracja serwera
-config.app_name=Tytuล strony
+config.app_name=Tytuล instancji
config.app_ver=Wersja Forgejo
-config.app_url=Podstawowy adres URL Forgejo
+config.app_url=Podstawowy adres URL
config.custom_conf=ลcieลผka do pliku konfiguracyjnego
config.custom_file_root_path=ลcieลผka gลรณwna plikรณw niestandardowych
config.offline_mode=Tryb lokalny
@@ -2450,7 +3306,7 @@ config.default_allow_create_organization=Domyลlnie zezwalaj na tworzenie organi
config.enable_timetracking=Wลฤ
cz ลledzenie czasu
config.default_enable_timetracking=Domyลlnie wลฤ
cz ลledzenie czasu
config.default_allow_only_contributors_to_track_time=Zezwalaj wyลฤ
cznie wspรณลpracownikom na ลledzenie czasu
-config.no_reply_address=Ukryta domena e-mail
+config.no_reply_address=Domena ukrytych e-maili
config.default_visibility_organization=Domyลlna widocznoลฤ dla nowych organizacji
config.default_enable_dependencies=Domyลlne wลฤ
czanie zaleลผnoลci zgลoszeล
@@ -2491,19 +3347,19 @@ config.cookie_life_time=Czas waลผnoลci ciasteczka
config.picture_config=Konfiguracja obrazu i awataru
config.picture_service=Usลuga obrazรณw
config.disable_gravatar=Wyลฤ
cz Gravatar
-config.enable_federated_avatar=Wลฤ
cz sfederowane awatary
+config.enable_federated_avatar=Wลฤ
cz federowane awatary
config.git_config=Konfiguracja Git
-config.git_disable_diff_highlight=Wyลฤ
czyฤ wyrรณลผnianie skลadni diff
-config.git_max_diff_lines=Maksymalna liczba linii diff (dla pojedynczego pliku)
-config.git_max_diff_line_characters=Maksymalna liczba znakรณw diff (dla pojedynczego pliku)
-config.git_max_diff_files=Maksymalna liczba plikรณw diff (ktรณre zostanฤ
wyลwietlone)
+config.git_disable_diff_highlight=Wyลฤ
cz wyrรณลผnianie skลadni diff
+config.git_max_diff_lines=Maksymalna liczba linii diff na plik
+config.git_max_diff_line_characters=Maksymalna liczba znakรณw diff na liniฤ
+config.git_max_diff_files=Maksymalna liczba plikรณw diff
config.git_gc_args=Argumenty GC
config.git_migrate_timeout=Limit czasu migracji
config.git_mirror_timeout=Limit czasu aktualizacji kopii lustrzanej
config.git_clone_timeout=Limit czasu operacji klonowania
config.git_pull_timeout=Limit czasu dla operacji pull
-config.git_gc_timeout=Limit czasu usuwania ลmieci
+config.git_gc_timeout=Limit czasu operacji GC
config.log_config=Konfiguracja dziennika
config.disabled_logger=Wyลฤ
czone
@@ -2532,8 +3388,8 @@ monitor.queue.name=Nazwa
monitor.queue.type=Typ
monitor.queue.exemplar=Przykลadowy typ
monitor.queue.numberworkers=Liczba procesรณw pracujฤ
cych
-monitor.queue.maxnumberworkers=Maksymalna liczba procesรณw pracujฤ
cych
-monitor.queue.settings.title=Ustawienia Puli
+monitor.queue.maxnumberworkers=Maksymalna Liczba procesรณw pracujฤ
cych
+monitor.queue.settings.title=Ustawienia puli
monitor.queue.settings.maxnumberworkers=Maksymalna liczba procesรณw pracujฤ
cych
monitor.queue.settings.maxnumberworkers.placeholder=Obecnie %[1]d
monitor.queue.settings.maxnumberworkers.error=Maksymalna liczba procesรณw pracujฤ
cych musi byฤ liczbฤ
@@ -2541,7 +3397,7 @@ monitor.queue.settings.submit=Aktualizuj ustawienia
monitor.queue.settings.changed=Zaktualizowano ustawienia
notices.system_notice_list=Powiadomienia systemu
-notices.view_detail_header=Pokaลผ szczegรณลy powiadomienia
+notices.view_detail_header=Szczegรณลy powiadomienia
notices.select_all=Wybierz wszystkie
notices.deselect_all=Odznacz wszystkie
notices.inverse_selection=Odwrรณฤ wybรณr
@@ -2553,6 +3409,144 @@ notices.type_2=Zadanie
notices.desc=Opis
notices.op=Operacja
notices.delete_success=Powiadomienia systemu zostaลy usuniฤte.
+monitor.last_execution_result = Wynik
+monitor.process.children = Dzieci
+integrations = Integracje
+users.bot = Bot
+users.list_status_filter.menu_text = Filtr
+packages.version = Wersja
+packages.creator = Twรณrca
+users.list_status_filter.not_active = Nieaktywne
+notices.operations = Operacje
+config.send_test_mail_submit = Wyลlij
+packages.published = Opublikowane
+config.mailer_protocol = Protokรณล
+monitor.stats = Statystyki
+users.remote = Zdalnie
+users.list_status_filter.reset = Zresetuj
+config_summary = Podsumowanie
+config_settings = Ustawienia
+assets = Zasoby kodu
+dashboard.cleanup_packages = Wyczyลฤ przedawnione pakiety
+dashboard.delete_old_system_notices = Usuล wszystkie stare powiadomienia systemowe z bazy danych
+users.details = Szczegรณลy uลผytkownika
+emails.deletion_success = Adres e-mail zostaล usuniฤty.
+emails.delete_primary_email_error = Nie moลผesz usunฤ
ฤ gลรณwnego adresu e-mail.
+users.purge_help = Wymusza usuniฤcie uลผytkownika razem z jakimikolwiek repozytoriami, organizacjami, oraz pakietami ktรณrych ten uลผytkownik jest wลaลcicielem. Wszystkie komentarze i zgลoszenia przez tego uลผytkownika rรณwnieลผ zostanฤ
usuniฤte.
+dashboard.sync_branch.started = Synchronizacja gaลฤzi rozpoczฤta
+dashboard.cancel_abandoned_jobs = Anuluj porzucone prace akcji
+users.reserved = Zarezerwowane
+dashboard.task.cancelled = Zadanie: %[1]s anulowane: %[3]s
+dashboard.sync_repo_branches = Synchronizuj pominiฤte gaลฤzie z danych Git do bazy danych
+dashboard.sync_repo_tags = Synchronizuj tagi z danych Git do bazy danych
+settings = Ustawienia administratora
+dashboard.stop_zombie_tasks = Zatrzymaj zadania zombi akcji
+users.cannot_delete_self = Nie moลผesz usunฤ
ฤ sam(a) siebie
+packages.cleanup.success = Pomyลlnie wyczyszczono przedawnione dane
+dashboard.sync_tag.started = Synchronizacja tagu rozpoczฤta
+users.list_status_filter.not_restricted = Nie ograniczony
+users.list_status_filter.is_prohibit_login = Zabroล logowania
+users.list_status_filter.not_prohibit_login = Zezwรณl na logowanie
+users.list_status_filter.is_2fa_enabled = 2FA wลฤ
czone
+dashboard.gc_lfs = Wywoลaj GC na metaobiektach LFS
+dashboard.stop_endless_tasks = Zatrzymaj niekoลczฤ
ce siฤ zadania akcji
+repos.lfs_size = Wielkoลฤ LFS
+packages.package_manage_panel = Zarzฤ
dzaj pakietami
+dashboard.cleanup_actions = Wyczyลฤ przedawnione logi i artefakty z akcji
+dashboard.rebuild_issue_indexer = Przebuduj indekser zgลoszeล
+users.new_success = Konto uลผytkownika "%s" zostaลo utworzone.
+users.purge = Pozbฤ
dลบ siฤ uลผytkownika
+users.activated.description = Zakoลczenie weryfikacji e-mail. Wลaลciciel nieaktywowanego konta nie bฤdzie mรณgล siฤ zalogowaฤ dopรณki weryfikacja e-mail nie zostaลa zakoลczona.
+users.block.description = Zablokuj uลผytkownikowi moลผliwoลci interakcji z tym serwisem przez jego konto i zabroล logowania siฤ.
+users.admin.description = Nadaj temu uลผytkownikowi peลen dostฤp do wszystkich funkcji administracyjnych dostฤpnych przez interfejs przeglฤ
darkowy lub API.
+users.restricted.description = Zezwรณl tylko na interakcje z repozytoriami i organizacjami do ktรณrych ten uลผytkownik zostaล dodany jako wspรณลpracownik. To uniemoลผliwia dostฤp do publicznych repozytoriรณw na tej instancji.
+users.local_import.description = Zezwรณl na importowanie repozytoriรณw z lokalnego systemu plikรณw serwera. To moลผe byฤ problemem zabezpieczeล.
+users.organization_creation.description = Zezwรณl na tworzenie nowych organizacji.
+users.still_own_packages = Ten uลผytkownik nadal jest wลaลcicielem jednego lub wiฤcej pakietรณw, usuล najpierw te pakiety.
+users.list_status_filter.not_admin = Nie administrator
+users.list_status_filter.not_2fa_enabled = 2FA wyลฤ
czone
+emails.change_email_text = Czy jesteล pewien(-na), ลผe chcesz zaktualizowaฤ ten adres e-mail?
+emails.delete = Usuล E-mail
+emails.delete_desc = Czy jesteล pewien(-na), ลผe chcesz usunฤ
ฤ ten adres e-mail?
+packages.total_size = Wielkoลฤ caลkowita: %s
+packages.unreferenced_size = Nieodniesiona wielkoลฤ: %s
+packages.cleanup = Wyczyลฤ przedawnione dane
+defaulthooks.desc = Webhooki automatycznie wykonujฤ
ลผฤ
dania HTTP POST do serwera kiedy pewne wydarzenia Forgejo zostajฤ
wywoลane. Webhooki zdefiniowane tutaj sฤ
domyลlne i bฤdฤ
kopiowane do wszystkich nowych repozytoriรณw. Przeczytaj wiฤcej w przewodniku webhookรณw .
+dashboard.new_version_hint = Forgejo %s jest juลผ dostฤpne, w tej chwili korzystasz z %s. Sprawdลบ szczegรณลy na blogu .
+identity_access = Toลผsamoลฤ i dostฤp
+dashboard.cron.cancelled = Cron: %[1]s anulowany: %[3]s
+config.domain = Domena serwera
+monitor.queue.activeworkers = Aktywne procesy pracujฤ
ce
+monitor.queue.settings.remove_all_items = Usuล wszystkie
+monitor.queue.settings.desc = Pule rosnฤ
dynamicznie w odpowiedzi na blokadฤ kolejki procesรณw pracujฤ
cych.
+config.mailer_config = Konfiguracja Mailer
+auths.tip.gitea = Zarejestruj nowฤ
aplikacjฤ OAuth2. Przewodnik moลผna znaleลบฤ na %s
+auths.unable_to_initialize_openid = Nie moลผna zainicjalizowaฤ Dostawcy Uwierzytelniania OpenID Connect: %s
+auths.force_smtps = Wymuล SMTPS
+auths.helo_hostname = Nazwa hosta HELO
+self_check = Autoweryfikacja
+config.mailer_enable_helo = Wลฤ
cz HELO
+monitor.queue.settings.remove_all_items_done = Wszystkie elementy w kolejce zostaลy usuniฤte.
+auths.tips.gmail_settings = Ustawienia Gmail:
+auths.map_group_to_team_removal = Usuล uลผytkownikรณw z synchronizowanych zespoลรณw jeลผeli uลผytkownik nie naleลผy do odpowiadajฤ
cej grupy LDAP
+auths.enable_ldap_groups = Wลฤ
cz grupy LDAP
+auths.map_group_to_team = Odwzorowywuj grupy LDAP na zespoลy Organizacji (pozostaw pole puste by pominฤ
ฤ)
+config.test_mail_sent = Testowy e-mail zostaล wysลany do "%s".
+config.cache_test_slow = Test pamiฤci podrฤcznej zakoลczony powodzeniem, jednak odpowiedลบ byลa wolna: %s.
+auths.verify_group_membership = Weryfikuj przynaleลผnoลฤ do grupy w LDAP (pozostaw filtr pusty by pominฤ
ฤ)
+monitor.stacktrace = Stacktrace
+monitor.download_diagnosis_report = Pobierz raport diagnostyczny
+auths.skip_local_two_fa_helper = Pozostawienie tej opcji jako odznaczonej oznacza, ลผe uลผytkownicy lokalni z aktywowanym 2FA nadal bฤdฤ
musieli przejลฤ 2FA by mรณc siฤ zalogowaฤ
+config.app_slogan = Slogan instancji
+config.test_mail_failed = Nie udaลo siฤ wysลaฤ testowego e-maila do "%s": %v
+config.mailer_use_dummy = Testowa
+config.cache_test_failed = Nie udaลo siฤ zbadaฤ pamiฤci podrฤcznej: %v.
+config.cache_test = Przetestuj Pamiฤฤ Podrฤcznฤ
+monitor.processes_count = %d Procesรณw
+monitor.queue.numberinqueue = Liczba w kolejce
+monitor.queue.review_add = Sprawdลบ / dodaj procesy pracujฤ
ce
+self_check.no_problem_found = Nie znaleziono jeszcze ลผadnych problemรณw.
+config.cache_test_succeeded = Test pamiฤci podrฤcznej zakoลczony powodzeniem, otrzymano odpowiedลบ w ciฤ
gu %s.
+auths.login_source_exist = ลนrรณdลo uwierzytelniania "%s" juลผ istnieje.
+auths.new_success = Uwierzytelnianie "%s" zostaลa dodana.
+config.app_data_path = ลcieลผka danych aplikacji
+systemhooks.desc = Webhooki automatycznie tworzฤ
zapytania HTTP POST do serwera, kiedy nastฤpujฤ
pewne zdarzenia w Forgejo. Zdefiniowane tutaj webhooki bฤdฤ
oddziaลywaฤ na wszystkie repozytoria tego systemu, zatem proszฤ rozwaลผ ich moลผliwy wpลyw na wydajnoลฤ. Przeczytaj o tym wiฤcej w przewodniku o webhookach .
+auths.force_smtps_helper = SMTPS jest zawsze uลผywane na porcie 465. Zaznacz tฤ opcjฤ by wymusiฤ SMTPS na innych portach. (W przeciwnym wypadku dla innych portรณw zostanie uลผyte STARTTLS gdy jest wspierane przez hosta.)
+auths.default_domain_name = Domyลlna nazwa domeny uลผywana do adresu e-mail
+config.allow_dots_in_usernames = Zezwรณl uลผytkownikom na uลผycie kropek w ich nazwach uลผytkownikรณw. Nie wpลywa na juลผ istniejฤ
ce konta.
+config.open_with_editor_app_help = Edytory dostฤpne w menu klonowania "Otwรณrz przy pomocy". Jeลผeli pozostawione puste, ustawienie domyลlne bฤdzie uลผyte. Rozwiล by zobaczyฤ ustawienie domyลlne.
+monitor.duration = Okres (s)
+config.ssh_domain = Domena serwera SSH
+config.mailer_smtp_addr = Host SMTP
+auths.tip.gitlab_new = Zarejestruj nowฤ
aplikacjฤ na %s
+auths.oauth2_scopes = Dodatkowe zakresy
+auths.tips.oauth2.general.tip = Podczas rejestrowania nowego uwierzytelniania OAuth2, callback/przekierowanie URL powinno byฤ:
+auths.oauth2_group_claim_name = Nazwa oลwiadczenia okreลlajฤ
cego nazwy grup dla tego ลบrรณdลa. (Opcjonalne)
+dashboard.update_migration_poster_id = Aktualizuj ID autora migracji
+config.access_log_template = Szablon dziennika dostฤpu
+dashboard.start_schedule_tasks = Uruchomienie zaplanowanych zadaล akcji
+config.logger_name_fmt = Dziennik: %s
+self_check.database_collation_case_insensitive = Baza danych korzysta z ukลadu sortowania %s, dla ktรณrego nie ma znaczenia wielkoลฤ liter. Mimo, ลผe Forgejo mรณgลoby dziaลaฤ z tym ustawieniem poprawnie, mogฤ
wydarzyฤ siฤ rzadkie przypadki, ktรณre nie bฤdฤ
dziaลaฤ zgodnie z oczekiwaniami.
+auths.helo_hostname_helper = Nazwa hosta wysyลana z HELO. Aby wysลaฤ bieลผฤ
cฤ
nazwฤ hosta, pozostaw puste.
+dashboard.update_checker = Sprawdzanie aktualizacji
+auths.oauth2_required_claim_name_helper = Ustaw tฤ nazwฤ by ograniczyฤ logowanie z tego ลบrรณdลa dla uลผytkownikรณw z oลwiadczeniem o tej nazwie
+auths.group_attribute_list_users = Atrybut grupy zawierajฤ
cy listฤ uลผytkownikรณw
+auths.attribute_avatar = Atrybut awatara
+config.set_setting_failed = Ustawienie %s nie powiodลo siฤ
+auths.oauth2_tenant = Dzierลผawa
+auths.oauth2_map_group_to_team_removal = Usuล uลผytkownikรณw z synchronizowanych zespoลรณw jeลผeli uลผytkownik nie naleลผy do odpowiadajฤ
cej grupy.
+auths.oauth2_required_claim_value_helper = Ustaw tฤ nazwฤ by ograniczyฤ logowanie z tego ลบrรณdลa dla uลผytkownikรณw z oลwiadczeniem o tej nazwie i wartoลci
+auths.oauth2_restricted_group = Wartoลฤ oลwiadczenia grupy dla uลผytkownikรณw ograniczonych. (Opcjonalne - wymaga nazwy oลwiadczenia powyลผej)
+auths.oauth2_map_group_to_team = Odwzorowywuj grupy oลwiadczenia na zespoลy organizacji (Opcjonalne - wymaga nazwy oลwiadczenia powyลผej)
+auths.invalid_openIdConnectAutoDiscoveryURL = Niepoprawny URL Auto Discovery (musi to byฤ poprawny URL rozpoczynajฤ
cy siฤ od http:// lub https://)
+self_check.database_fix_mysql = Dla uลผytkownikรณw MySQL/MariaDB, moลผesz uลผyฤ polecenia "forgejo doctor convert" by naprawiฤ problemy ukลadu sortowania. Moลผesz teลผ naprawiฤ problem przez rฤczne uลผycie kwerend SQL "ALTER ... COLLATE ...".
+auths.oauth2_required_claim_name = Nazwa wymaganego oลwiadczenia
+auths.oauth2_required_claim_value = Wymagana wartoลฤ oลwiadczenia
+auths.oauth2_admin_group = Wartoลฤ oลwiadczenia grupy dla administratorรณw. (Opcjonalne - wymaga nazwy oลwiadczenia powyลผej)
+auths.group_search_base = Podstawowy DN do wyszukiwania grup
+auths.user_attribute_in_group = Atrybut uลผytkownika w grupie
+self_check.database_collation_mismatch = Wymagaj by baza danych korzystaลa z ukลadu sortowania: %s
+self_check.database_inconsistent_collation_columns = Baza danych korzysta z ukลadu sortowania %s, ale te kolumny korzystajฤ
z niedopasowanych ukลadรณw sortowania. Moลผe to spowodowaฤ nieoczekiwane problemy.
[action]
@@ -2566,6 +3560,27 @@ compare_commits=Porรณwnaj %d commitรณw
compare_commits_general=Porรณwnaj commity
mirror_sync_delete=synchronizuje i usuwa odwoลanie %[2]s
w %[3]s z kopii lustrzanej
review_dismissed_reason=Powรณd:
+auto_merge_pull_request = `automatycznie scaliล(a) pull request %[3]s#%[2]s `
+starred_repo = daล(a) gwiazdkฤ %[2]s
+create_pull_request = `utworzyล(a) pull request %[3]s#%[2]s `
+comment_issue = `skomentowaล(a) zgลoszenie %[3]s#%[2]s `
+mirror_sync_create = zsynchronizowaล(a) nowe odniesienie %[3]s do %[4]s z kopii lustrzanej
+reject_pull_request = `zasugerowaล(a) zmiany dla %[3]s#%[2]s `
+publish_release = `wydaล %[4]s na %[3]s `
+comment_pull = `skomentowaล(a) pull request %[3]s#%[2]s `
+review_dismissed = `odrzuciล(a) recenzjฤ od %[4]s dla %[3]s#%[2]s `
+close_pull_request = `zamknฤ
ล(-ฤลa) pull request %[3]s#%[2]s `
+reopen_pull_request = `otworzyล(a) ponownie pull request %[3]s#%[2]s `
+merge_pull_request = `scaliล(a) pull request %[3]s#%[2]s `
+approve_pull_request = `zatwierdziล(a) %[3]s#%[2]s `
+create_branch = utworzyล(a) gaลฤ
ลบ %[3]s in %[4]s
+watched_repo = zaczฤ
ล(-ฤลa) obserwowaฤ %[2]s
+push_tag = wypchnฤ
ล tag %[3]s do %[4]s
+mirror_sync_push = zsynchronizowaล commity do %[3]s na %[4]s z kopii lustrzanej
+create_issue = `otworzyล(a) zgลoszenie %[3]s#%[2]s `
+close_issue = `zamknฤ
ล(-ฤลa) zgลoszenie %[3]s#%[2]s `
+reopen_issue = `otworzyล(a) ponownie zgลoszenie %[3]s#%[2]s `
+commit_repo = wypchnฤ
ล(-ฤลa) do %[3]s na %[4]s
[tool]
now=teraz
@@ -2603,6 +3618,9 @@ pin=Przypnij powiadomienie
mark_as_read=Oznacz jako przeczytane
mark_as_unread=Oznacz jak nieprzeczytane
mark_all_as_read=Oznacz wszystkie jako przeczytane
+subscriptions = Subskrypcje
+no_subscriptions = Brak subskrypcji
+watching = Obserwowane
[gpg]
default_key=Podpisano domyลlnym kluczem
@@ -2610,14 +3628,15 @@ error.extract_sign=Nie udaลo siฤย wyลuskaฤย podpisu
error.generate_hash=Nie udaลo siฤ wygenerowaฤ skrรณtu dla commitu
error.no_committer_account=Brak konta powiฤ
zanego z adresem e-mail autora
error.no_gpg_keys_found=Nie znaleziono w bazie danych klucza dla tego podpisu
-error.not_signed_commit=Commit nie podpisany
-error.failed_retrieval_gpg_keys=Nie udaลo siฤ odzyskaฤย ลผadnego klucza powiฤ
zanego z kontem autora
+error.not_signed_commit=Commit niepodpisany
+error.failed_retrieval_gpg_keys=Nie udaลo siฤ uzyskaฤ ลผadnego klucza powiฤ
zanego z kontem autora
error.probable_bad_signature=OSTRZEลปENIE! Pomimo istnienia klucza z takim ID w bazie, nie weryfikuje on tego commita! Ten commit jest PODEJRZANY.
error.probable_bad_default_signature=OSTRZEลปENIE! Pomimo, ลผe domyลlny klucz posiada to ID, nie weryfikuje on tego commita! Ten commit jest PODEJRZANY.
[units]
error.no_unit_allowed_repo=Nie masz uprawnieล do ลผadnej sekcji tego repozytorium.
error.unit_not_allowed=Nie masz uprawnieล do tej sekcji repozytorium.
+unit = Jednostka
[packages]
filter.type=Typ
@@ -2625,13 +3644,195 @@ alpine.repository.branches=Gaลฤzie
alpine.repository.repositories=Repozytoria
conan.details.repository=Repozytorium
owner.settings.cleanuprules.enabled=Wลฤ
czone
+alpine.repository.architectures = Architektury
+container.details.platform = Platforma
+requirements = Wymagania
+keywords = Sลowa kluczowe
+versions = Wersje
+dependency.id = ID
+dependency.version = Wersja
+details.author = Autor
+filter.type.all = Wszystko
+filter.container.tagged = Oznaczone
+details.license = Licencja
+installation = Instalacja
+composer.dependencies = Zaleลผnoลci
+filter.container.untagged = Nieoznaczone
+title = Pakiety
+dependencies = Zaleลผnoลci
+details = Szczegรณลy
+debian.repository.distributions = Dystrybucje
+npm.details.tag = Znacznik
+container.labels = Etykiety
+container.labels.key = Klucz
+debian.repository.architectures = Architektury
+debian.repository.components = Komponenty
+container.labels.value = Wartoลฤ
+npm.dependencies = Zaleลผnoลci
+rpm.repository.architectures = Architektury
+owner.settings.chef.keypair.description = Para kluczy jest konieczna do uwierzytelnienia do rejestru Chef. Jeลผeli wygenerowaลeล(-aล) parฤ kluczy wczeลniej, generowanie nowej pary kluczy porzuci starฤ
parฤ kluczy.
+maven.install2 = Uruchom z wiersza poleceล:
+settings.delete = Usuล pakiet
+assets = Zasoby
+helm.registry = Skonfiguruj ten rejestr z wiersza poleceล:
+helm.install = By zainstalowaฤ ten pakiet, wykonaj nastฤpujฤ
ce polecenie:
+alt.install = Zainstaluj pakiet
+alt.repository.multiple_groups = Ten pakiet jest dostฤpny w wielu grupach.
+settings.delete.description = Usuniฤcie pakietu jest operacjฤ
permanentnฤ
i nie moลผe zostaฤ cofniฤte.
+nuget.registry = Skonfiguruj ten rejestr z wiersza poleceล:
+conda.registry = Skonfiguruj ten rejestr jako repozytorium Conda w twoim pliku .condarc
:
+search_in_external_registry = Szukaj w %s
+settings.delete.notice = Za moment usuniesz %s (%s). Ta operacja jest nieodwracalna, jesteล pewien(-na)?
+settings.delete.success = Pakiet zostaล usuniฤty.
+settings.delete.error = Nie udaลo siฤ usunฤ
ฤ pakietu.
+debian.registry = Skonfiguruj ten rejestr z wiersza poleceล:
+debian.repository = Informacje o repozytorium
+generic.download = Pobierz pakiet z wiersza poleceล:
+go.install = Zainstaluj pakiet z wiersza poleceล:
+maven.registry = Skonfiguruj ten rejestr w twoim pliku projektu pom.xml
:
+npm.install = By zainstalowaฤ ten pakiet przy uลผyciu npm, wykonaj nastฤpujฤ
ce polecenie:
+npm.dependencies.optional = Zaleลผnoลci opcjonalne
+alt.setup = Dodaj repozytorium do listy poลฤ
czonych repozytoriรณw (wybierz wymaganฤ
architekturฤ zamiast '_arch_'):
+alt.repository.architectures = Architektury
+alpine.install = By zainstalowaฤ ten pakiet, wykonaj nastฤpujฤ
ce polecenie:
+conan.install = By zainstalowaฤ ten pakiet przy uลผyciu Conan, wykonaj nastฤpujฤ
ce polecenie:
+composer.install = By zainstalowaฤ ten pakiet przy uลผyciu Composer, wykonaj nastฤpujฤ
ce polecenie:
+npm.dependencies.peer = Zaleลผnoลci rรณwieลnicze
+owner.settings.chef.keypair = Wygeneruj parฤ kluczy
+owner.settings.cleanuprules.success.update = Reguลa czyszczenia zostaลa zaktualizowana.
+chef.registry = Skonfiguruj ten rejestr w twoim pliku ~/.chef/config.rb
:
+rubygems.install2 = lub dodaj to do Gemfile:
+about = O tym pakiecie
+published_by_in = Opublikowano %[1]s przez %[3]s w %[5]s
+published_by = Opublikowano %[1]s przez %[3]s
+npm.registry = Skonfiguruj ten rejestr w pliku projektu .npmrc
:
+rpm.repository.multiple_groups = Ten pakiet jest dostฤpny w wielu grupach.
+rpm.repository = Informacje o repozytorium
+alpine.registry = Skonfiguruj ten rejestr dodajฤ
c url do twojego pliku /etc/apk/repositories
:
+cargo.registry = Skonfiguruj ten rejestr w pliku konfiguracyjnym Cargo (na przykลad ~/.cargo/config.toml
):
+nuget.install = By zainstalowaฤ ten pakiet przy uลผyciu NuGet, wykonaj nastฤpujฤ
ce polecenie:
+rpm.distros.suse = na dystrybucjach opartych o SUSE
+npm.dependencies.bundle = Doลฤ
czone zaleลผnoลci
+rubygems.required.ruby = Wymaga wersji Ruby
+rubygems.required.rubygems = Wymaga wersji RubyGem
+arch.version.groups = Grupa
+arch.version.depends = Zaleลผnoลci
+arch.version.optdepends = Opcjonalne zaleลผnoลci
+composer.registry = Skonfiguruj ten rejestr w twoim pliku ~/.composer/config.json
:
+conda.install = By zainstalowaฤ ten pakiet przy uลผyciu Conda, wykonaj nastฤpujฤ
ce polecenie:
+container.details.type = Rodzaj obrazu
+rpm.distros.redhat = na dystrybucjach opartych o RedHat
+filter.no_result = Twรณj filtr nie daล ลผadnych wynikรณw.
+registry.documentation = Wiฤcej informacji o rejestrze %s znajdziesz w dokumentacji .
+empty.repo = Czy wgraลeล pakiet, ale nie jest tutaj wyลwietlany? Odwiedลบ ustawienia pakietรณw i powiฤ
ลผ go z tym repozytorium.
+empty.documentation = Wiฤcej informacji o rejestrze przekietรณw znajdziesz w dokumentacji .
+alpine.repository = Informacje o repozytorium
+arch.pacman.helper.gpg = Dodaj certyfikat zaufania do pacmana:
+alpine.registry.key = Pobierz klucz publiczny RSA rejestru do folderu /etc/apk/keys/
by zweryfikowaฤ podpis indeksu:
+arch.pacman.sync = Synchronizuj pakiet przy uลผyciu pacman:
+arch.version.checkdepends = Zaleลผnoลci weryfikacji
+arch.version.conflicts = Konflikty
+cargo.install = By zainstalowaฤ ten pakiet przy uลผyciu Cargo, wykonaj nastฤpujฤ
ce polecenie:
+chef.install = By zainstalowaฤ ten pakiet, wykonaj nastฤpujฤ
ce polecenie:
+debian.install = By zainstalowaฤ ten pakiet, wykonaj nastฤpujฤ
ce polecenie:
+maven.download = By pobraฤ zaleลผnoลฤ, wykonaj w wierszu poleceล:
+npm.install2 = lub dodaj to do pliku package.json:
+pub.install = By zainstalowaฤ ten pakiet przy uลผyciu Dart, wykonaj nastฤpujฤ
ce polecenie:
+maven.install = By uลผyฤ tego pakietu doลฤ
cz nastฤpujฤ
cฤ
treลฤ w bloku dependencies
w pliku pom.xml
:
+pypi.install = By zainstalowaฤ ten pakiet przy uลผyciu pip, wykonaj nastฤpujฤ
ce polecenie:
+rpm.registry = Skonfiguruj ten rejestr z wiersza poleceล:
+rpm.install = By zainstalowaฤ ten pakiet, wykonaj nastฤpujฤ
ce polecenie:
+rubygems.install = By zainstalowaฤ ten pakiet przy uลผyciu gem, wykonaj nastฤpujฤ
ce polecenie:
+settings.link.description = Jeลผeli poลฤ
czych pakiet z repozytorium, pakiet ten bฤdzie widoczny na liลcie pakietรณw danego repozytorium.
+settings.link.success = Poลฤ
czone repozytorium zostaลo zaktualizowane pomyลlnie.
+owner.settings.cleanuprules.keep.count = Pozostaw ostatnie
+owner.settings.cleanuprules.keep.count.1 = 1 wersji na pakiet
+owner.settings.chef.title = Rejestr Chef
+conan.registry = Skonfiguruj ten rejestr z wiersza poleceล:
+container.multi_arch = OS / Architektura
+container.images.title = Obrazy
+owner.settings.cleanuprules.keep.pattern = Pozostaw pasujฤ
ce wersje
+desc = Zarzฤ
dzaj pakietami repozytoriรณw.
+settings.link.button = Zaktualizuj Poลฤ
czone Repozytorium
+settings.link = Poลฤ
cz ten pakiet z repozytorium
+swift.install2 = i wykonaj nastฤpujฤ
ce polecenie:
+arch.version.properties = Wลasnoลci wersji
+arch.pacman.repo.multi.item = Konfiguracja dla %s
+arch.pacman.repo.multi = %s ma tฤ samฤ
wersjฤ co w innych dystrybucjach.
+arch.pacman.conf = Dodaj serwer z powiฤ
zanฤ
dystrybucjฤ
i architekturฤ
do /etc/pacman.conf
:
+versions.view_all = Pokaลผ wszystkie
+details.documentation_site = Strona dokumentacji
+details.repository_site = Strona repozytorium
+arch.version.description = Opis
+arch.version.provides = Zapewnia
+arch.version.makedepends = Zaleลผnoลci budowy
+container.pull = Pobierz obraz z wiersza poleceล:
+container.layers = Warstwy obrazu
+pypi.requires = Wymagany Python
+rubygems.dependencies.runtime = Zaleลผnoลci czasu wykonywania
+swift.registry = Skonfiguruj ten rejestr z wiersza poleceล:
+alt.registry = Skonfiguruj ten rejestr z wiersza poleceล:
+alt.registry.install = By zainstalowaฤ ten pakiet, wykonaj nastฤpujฤ
ce polecenie:
+owner.settings.cleanuprules.preview.overview = %d pakietรณw jest zaplanowanych do usuniฤcia.
+owner.settings.cleanuprules.keep.count.n = %d wersji na pakiet
+owner.settings.cleanuprules.remove.title = Wersje ktรณre nie pasujฤ
do tych reguล zostanฤ
usuniฤte, chyba, ลผe reguลa wczeลniej kaลผe jest pozostawiฤ.
+owner.settings.cleanuprules.remove.days = Usuล wersje starsze niลผ
+alt.repository = Informacje o repozytorium
+owner.settings.cleanuprules.remove.pattern = Usuล wersje pasujฤ
ce
+owner.settings.cleanuprules.success.delete = Reguลa czyszczenia zostaลa usuniฤta.
+arch.version.replaces = Zamienia
+arch.version.backup = Kopia zapasowa
+details.project_site = Strona projektu
+settings.link.error = Nie udaลo siฤ zaktualizowaฤ poลฤ
czonego repozytorium.
+swift.install = Dodaj ten packiet do twojego pliku Package.swift
:
+settings.link.select = Wybierz Repozytorium
+empty = Nie ma jeszcze ลผadnych pakietรณw.
+cran.registry = Skonfiguruj ten rejestr w twoim pliku Rprofile.site
:
+cran.install = By zainstalowaฤ ten pakiet, wykonaj nastฤpujฤ
ce polecenie:
+owner.settings.cargo.rebuild.no_index = Nie moลผna odbudowaฤ, ลผaden indeks nie jest zainicjowany.
+owner.settings.cargo.title = Indeks rejestru Cargo
+owner.settings.cargo.rebuild.error = Nie udaลo siฤ odbudowaฤ indeksu Cargo: %v
+owner.settings.cargo.rebuild.success = Indeks Cargo zostaล odbudowany pomyลlnie.
+owner.settings.cleanuprules.none = Nie ma jeszcze ลผadnych reguล czyszczenia.
+nuget.dependency.framework = Framework Docelowy
+owner.settings.cleanuprules.preview = Podglฤ
d reguลy czyszczenia
+owner.settings.cleanuprules.keep.pattern.container = Wersja latest
jest zawsze pozostawiana dla pakietรณw kontenerรณw.
+owner.settings.cargo.initialize.success = Indeks Cargo zostaล utworzony pomyลlnie.
+owner.settings.cargo.rebuild = Odbuduj indeks
+owner.settings.cargo.initialize.error = Nie udaลo siฤ zainicjowaฤ indeksu Cargo: %v
+composer.dependencies.development = Zaleลผnoลci programistyczne
+owner.settings.cargo.initialize = Zainicjuj indeks
+alpine.registry.info = Wybierz $branch i $repository z listy poniลผej.
+owner.settings.cleanuprules.pattern_full_match = Zastosuj wzรณr do peลnej nazwy pakietu
+owner.settings.cleanuprules.keep.title = Wersje ktรณre pasujฤ
do tych reguล sฤ
pozostawiane, nawet jeลผeli pasujฤ
do reguลy usuniฤcia niลผej.
+vagrant.install = By dodaฤ box Vagrant, wykonaj nastฤpujฤ
ce polecenie:
+npm.dependencies.development = Zaleลผnoลci programistyczne
+rubygems.dependencies.development = Zaleลผnoลci programistyczne
+owner.settings.cargo.rebuild.description = Odbudowanie moลผe byฤ przydatne gdy indeks nie jest synchronizowany z zapisanymi pakietami Cargo.
+owner.settings.cleanuprules.title = Reguลy czyszczenia
+owner.settings.cleanuprules.add = Dodaj reguลฤ czyszczenia
+owner.settings.cleanuprules.edit = Edytuj reguลฤ czyszczenia
+owner.settings.cleanuprules.preview.none = Reguลa czyszczenia nie pasuje do ลผadnego pakietu.
+owner.settings.cargo.initialize.description = Specjalny indeks repozytorium Git jest potrzebny by uลผyฤ rejestru Cargo. Wybranie tej opcji utworzy/odtworzy repozytorium i skonfiguruje jest automatycznie.
+container.digest = Digest
+debian.registry.info = Wybierz $distribution i $component z listy poniลผej.
[secrets]
+secrets = Sekrety
+deletion = Usuล sekret
+creation.failed = Dodanie sekretu nie powiodลo siฤ.
+description = Sekrety bฤdฤ
przekazane pewnym akcjom, nie mogฤ
byฤ odczytane inaczej.
+creation.success = Secret "%s" zostaล dodany.
+creation = Dodaj Sekret
+deletion.success = Sekret zostaล usuniฤty.
+deletion.description = Usuniฤcie sekretu jest permanentne i nie moลผe zostaฤ cofniฤte. Kontynuowaฤ?
+creation.value_placeholder = Wprowadลบ dowolnฤ
treลฤ. Biaลe znaki na poczฤ
tku i koลcu bฤdฤ
pominiฤte.
+creation.name_placeholder = wielkoลฤ liter nie ma znaczenia, tylko znaki alfanumeryczne i znak podkreลlenia, nie moลผe zaczynaฤ siฤ od GITEA_ lub GITHUB_
+none = Nie ma jeszcze sekretรณw.
+management = Zarzฤ
dzaj sekretami
+deletion.failed = Nie udaลo siฤ usunฤ
ฤ sekretu.
[actions]
-
-
-
runners.name=Nazwa
runners.owner_type=Typ
runners.description=Opis
@@ -2641,25 +3842,119 @@ runners.task_list.commit=Commit
runners.status.active=Aktywne
runs.commit=Commit
+status.skipped = Pominiฤto
+runs.status = Status
+status.waiting = Oczekiwanie
+status.unknown = Nieznane
+runs.scheduled = Zaplanowane
+runners.id = ID
+status.failure = Niepowodzenie
+status.cancelled = Anulowano
+runners.status = Status
+runners.status.unspecified = Nieznane
+runners.status.idle = Bezczynne
+variables = Zmienne
+status.success = Sukces
+runs.actor = Aktor
+runners.status.offline = Offline
+runners.version = Wersja
+runners.task_list.status = Status
+runners.labels = Etykiety
+status.blocked = Zablokowano
+variables.id_not_exist = Zmienna o ID %d nie istnieje.
+variables.edit = Edytuj Zmiennฤ
+variables.update.failed = Nie udaลo siฤ zmieniฤ zmiennej.
+variables.creation.success = Zmienna "%s" zostaลa dodana.
+variables.creation.failed = Nie udaลo siฤ dodaฤ zmiennej.
+variables.deletion.success = Zmienna zostaลa usuniฤta.
+variables.update.success = Zmienna zostaลa zmieniona.
+variables.deletion.failed = Nie udaลo siฤ usunฤ
ฤ zmiennej.
+runs.no_workflows.help_write_access = Nie wiesz jak zaczฤ
ฤ z Forgejo Actions? Sprawdลบ szybki start w dokumentacji uลผytkownika i napisz swรณj pierwszy proces pracy, a nastฤpnie skonfiguruj runnera Forgejo by wykonywaล twoje zadania.
+runners.reset_registration_token = Resetuj token rejestracji
+runners.reset_registration_token_success = Rejestracja tokenu resetu runnera pomyลlna
+runners.none = Brak dostฤpnych runnerรณw
+runners.delete_runner_notice = Jeลผeli zadanie nadal jest wykonywane przez ten runner, zostanie ono zakoลczone i oznaczone jako niepowodzenie. Moลผe to przerwaฤ proces pracy.
+variables.deletion.description = Usuniฤcie zmiennej jest permanentne i nie moลผe zostaฤ cofniฤte. Kontynuowaฤ?
+variables.deletion = Usuล zmiennฤ
+runners.delete_runner_failed = Nie udaลo siฤ usunฤ
ฤ runnera
+runs.no_results = Brak pasujฤ
cych wynikรณw.
+runners.update_runner = Aktualizuj zmiany
+runners.new_notice = Jak uruchomiฤ runner
+variables.management = Zarzฤ
dzaj zmiennymi
+runners.task_list.no_tasks = Nie ma jeszcze zadaล.
+runners.task_list = Ostatnie zadania w tym runnerze
+runners.update_runner_success = Runner zaktualizowany pomyลlnie
+runners.update_runner_failed = Nie udaลo siฤ zaktualizowaฤ runnera
+runs.expire_log_message = Logi zostaลy oczyszczone poniewaลผ byลy za stare.
+variables.none = Nie ma jeszcze zmiennych.
+runs.empty_commit_message = (pusta wiadomoลฤ commita)
+variables.creation = Dodaj zmiennฤ
+runners = Runnery
+actions = Akcje
+runners.last_online = Ostatni czas online
+runners.runner_title = Runner
+runners.delete_runner = Usuล ten runner
+runners.delete_runner_success = Runner usuniฤty pomyลlnie
+runners.delete_runner_header = Potwierdลบ usuniฤcie tego runnera
+runs.no_workflows.help_no_write_access = By dowiedzieฤ siฤ o Forgejo Actions, zobacz dokumentacjฤ .
+runners.edit_runner = Edytuj Runnera
+variables.description = Zmienne bฤdฤ
przekazane pewnym akcjom, nie mogฤ
byฤ odczytane inaczej.
+runners.runner_manage_panel = Zarzฤ
dzaj runnerami
+runners.new = Utwรณrz nowy runner
+runs.no_matching_online_runner_helper = Brak pasujฤ
cych runnerรณw online z etykietฤ
: %s
+workflow.disable = Wyลฤ
cz proces pracy
+unit.desc = Zarzฤ
dzaj zintegrowanymi procesami CI/CD z Forgejo Actions.
+runs.all_workflows = Wszystkie procesy prac
+variables.not_found = Nie udaลo siฤ znaleลบฤ zmiennej.
+runs.invalid_workflow_helper = Plik konfiguracyjny procesu pracy jest nieprawidลowy. Proszฤ sprawdลบ swรณj plik konfiguracyjny: %s
+runs.no_workflows = Nie ma jeszcze ลผadnych procesรณw pracy.
+runs.no_runs = Ten proces pracy nie ma jeszcze uruchomieล.
+workflow.dispatch.use_from = Wykorzystaj proces pracy z
+workflow.disabled = Proces pracy jest wyลฤ
czony.
+workflow.enable_success = Proces pracy "%s" wลฤ
czony pomyลlnie.
+workflow.enable = Wลฤ
cz proces pracy
+workflow.disable_success = Proces pracy "%s" wyลฤ
czony pomyลlnie.
+workflow.dispatch.run = Uruchom proces pracy
+runs.no_job = Proces pracy musi posiadaฤ chociaลผ jedno zadanie
+runs.no_job_without_needs = Proces pracy musi zawieraฤ chociaลผ jedno zadanie bez zaleลผnoลci.
+status.running = Uruchomione
+runs.workflow = Proces pracy
+runners.task_list.done_at = Ukoลczone W
+need_approval_desc = Potrzebne zatwierdzenie by mรณc uruchamiaฤ procesy pracy dla pull requestรณw forkรณw.
+runs.pushed_by = wypchniฤty przez
+runs.status_no_select = Wszystkie stany
+runs.actors_no_select = Wszyscy aktorzy
+workflow.dispatch.success = Proces pracy zostaล pomyลlnie zaลผฤ
dany.
+workflow.dispatch.invalid_input_type = Nieprawidลowy typ danych wejลcia "%s".
+workflow.dispatch.input_required = Wymagaj wartoลci dla danych wejลcia "%s".
+workflow.dispatch.warn_input_limit = Wyลwietlane jest tylko pierwszych %d danych wejลcia.
+workflow.dispatch.trigger_found = Ten proces pracy zawiera wywoลanie przy wydarzeniu workflow_dispatch .
[projects]
+deleted.display_name = Projekt usuniฤty
+type-2.display_name = Projekt repozytorium
+type-1.display_name = Projekt osobisty
+type-3.display_name = Projekt organizacji
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=Dowiฤ
zanie symboliczne
executable_file = Plik wykonywalny
+submodule = Podmoduล
+directory = Katalog
+changed_filemode = %[1]s โ %[2]s
+normal_file = Zwykลy plik
[search]
search = Wyszukaj...
type_tooltip = Typ wyszukiwania
-fuzzy = Fuzzy
-package_kind = Wyszukaj paczki...
-fuzzy_tooltip = Uwzglฤdnij wyniki, ktรณre rรณwnieลผ pasujฤ
do wyszukiwanego hasลa
+fuzzy = Przybliลผone
+package_kind = Wyszukaj pakiety...
+fuzzy_tooltip = Uwzglฤdnij wyniki, ktรณre sฤ
bliskie wyszukiwanemu hasลu
match = Dopasuj
match_tooltip = Uwzglฤdniaj tylko wyniki pasujฤ
ce do wyszukiwanego hasลa
repo_kind = Wyszukaj repozytoria...
@@ -2674,4 +3969,51 @@ project_kind = Wyszukaj projekty...
branch_kind = Wyszukaj gaลฤzie...
commit_kind = Wyszukaj commity...
runner_kind = Wyszukaj runnery...
-keyword_search_unavailable = Wyszukiwanie wedลug sลรณw kluczowych jest obecnie niedostฤpne. Skontaktuj siฤ z administratorem strony.
\ No newline at end of file
+keyword_search_unavailable = Wyszukiwanie wedลug sลรณw kluczowych jest obecnie niedostฤpne. Skontaktuj siฤ z administratorem strony.
+milestone_kind = Wyszukaj kamienie milowe...
+union_tooltip = Uwzglฤdnia wyniki pasujฤ
ce do dowolnego sลowa kluczowego rozdzielonego biaลymi znakami
+exact = Dokลadne
+exact_tooltip = Uwzglฤdniaj tylko wyniki pasujฤ
ce do wyszukiwanego hasลa
+issue_kind = Wyszukaj zgลoszenia...
+pull_kind = Wyszukaj pull requesty...
+union = Unia
+regexp = RegExp
+regexp_tooltip = Interpretuj wyszukiwane hasลo jako wyraลผenie regularne
+
+
+[markup]
+filepreview.lines = Linie %[1]d do %[2]d w %[3]s
+filepreview.truncated = Podglฤ
d zostaล przyciฤty
+filepreview.line = Linia %[1]d w %[2]s
+
+[translation_meta]
+test = Litwo, Ojczyzno moja! ty jesteล jak zdrowie; ile ciฤ trzeba ceniฤ, ten tylko siฤ dowie, kto ciฤ straciล. Dziล piฤknoลฤ twฤ
w caลej ozdobie widzฤ i opisujฤ, bo tฤskniฤ po tobie :)
+
+[repo.permissions]
+code.read = Odczyt: Dostฤp i klonowanie kodu repozytorium.
+wiki.write = Zapis: Tworzenie, edycja i usuwanie stron ze zintegrowanej wiki.
+releases.write = Zapis: Publikowanie, edycja i usuwanie wydaล oraz ich zasobรณw.
+wiki.read = Odczyt: Czytanie zintegrowanej wiki oraz jej historii.
+releases.read = Odczyt: Czytanie i pobieranie wydaล.
+pulls.read = Odczyt: Czytanie i tworzenie pull requestรณw.
+projects.read = Odczyt: Dostฤp do plansz projektu repozytorium.
+issues.read = Odczyt: Odczyt i tworzenie zgลoszeล i komentarzy.
+code.write = Zapis: Wypychanie do repozytorium, tworzenie gaลฤzi i tagรณw.
+packages.read = Odczyt: Podglฤ
d i pobieranie pakietรณw przypisanych do repozytorium.
+projects.write = Zapis: Tworzenie projektรณw i kolumn oraz ich edycja.
+packages.write = Zapis: Publikowanie i usuwanie pakietรณw przypisanych do repozytorium.
+issues.write = Zapis: Zamykanie zgลoszeล i zarzฤ
dzanie metadanymi takimi jak etykiety, kamienie milowe, osoby przypisane, terminy i zaleลผnoลci.
+pulls.write = Zapis: Zamykanie pull requestรณw i zarzฤ
dzanie metadanymi takimi jak etykiety, kamienie milowe, osoby przypisane, terminy i zaleลผnoลci.
+ext_issues = Dostฤp do linku kierujฤ
cego do zewnฤtrznego dziennika zgลoszeล. Uprawnienia sฤ
zarzฤ
dzane zewnฤtrznie.
+ext_wiki = Dostฤp do linku kierujฤ
cego do zewnฤtrznej wiki. Uprawnienia sฤ
zarzฤ
dzane zewnฤtrznie.
+actions.write = Zapis: Rฤczne wywoลanie, restart, anulowanie lub zatwierdzenie oczekujฤ
cych procesรณw CI/CD.
+actions.read = Odczyt: Podglฤ
d zintegrowanych procesรณw CI/CD i ich logรณw.
+
+[munits.data]
+eib = EiB
+pib = PiB
+tib = TiB
+gib = GiB
+b = B
+kib = KiB
+mib = MiB
\ No newline at end of file
diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini
index 1778c865be..2092e7e4d4 100644
--- a/options/locale/locale_pt-BR.ini
+++ b/options/locale/locale_pt-BR.ini
@@ -4,7 +4,7 @@ dashboard=Painel
explore=Explorar
help=Ajuda
logo=Logotipo
-sign_in=Acessar
+sign_in=Iniciar sessรฃo
sign_in_with_provider=Entrar com %s
sign_in_or=ou
sign_out=Sair
@@ -12,7 +12,7 @@ sign_up=Cadastrar
link_account=Vincular conta
register=Cadastrar
version=Versรฃo
-powered_by=Desenvolvido por %s
+powered_by=Oferecido por %s
page=Pรกgina
template=Template
language=Idioma
@@ -24,7 +24,7 @@ signed_in_as=Sessรฃo iniciada como
enable_javascript=Este site requer JavaScript.
toc=รndice
licenses=Licenรงas
-return_to_forgejo=Volte para Forgejo
+return_to_forgejo=Retornar ao Forgejo
username=Nome de usuรกrio
email=Endereรงo de e-mail
@@ -33,7 +33,7 @@ access_token=Token de acesso
re_type=Confirmar senha
captcha=CAPTCHA
twofa=Autenticaรงรฃo de dois fatores
-twofa_scratch=Cรณdigo de backup da autenticaรงรฃo de dois fatores
+twofa_scratch=Cรณdigo de uso รบnico da autenticaรงรฃo de dois fatores
passcode=Senha
webauthn_insert_key=Insira sua chave de seguranรงa
@@ -55,13 +55,13 @@ organization=Organizaรงรฃo
mirror=Espelhamento
new_repo=Novo repositรณrio
new_migrate=Nova migraรงรฃo
-new_mirror=Novo espelhamento
+new_mirror=Novo espelho
new_fork=Novo fork do repositรณrio
new_org=Nova organizaรงรฃo
new_project=Novo projeto
new_project_column=Nova coluna
manage_org=Gerenciar organizaรงรตes
-admin_panel=Administraรงรฃo geral
+admin_panel=Administraรงรฃo do site
account_settings=Configuraรงรตes da conta
settings=Configuraรงรตes
your_profile=Perfil
@@ -76,7 +76,7 @@ forks=Forks
activities=Atividades
pull_requests=Pull requests
-issues=Issues
+issues=Problemas
milestones=Marcos
ok=OK
@@ -89,7 +89,7 @@ add=Adicionar
add_all=Adicionar todos
remove=Remover
remove_all=Excluir todos
-remove_label_str=`Remover item "%s"`
+remove_label_str=Remover item "%s"
edit=Editar
enabled=Habilitado
@@ -109,7 +109,7 @@ preview=Prรฉ-visualizaรงรฃo
loading=Carregandoโฆ
error=Erro
-error404=A pรกgina que vocรช estรก tentando acessar nรฃo existe ou vocรช nรฃo estรก autorizado a visualizรก-la.
+error404=A pรกgina que vocรช estรก tentando acessar nรฃo existe , foi removida ou vocรช nรฃo tem autorizaรงรฃo para visualizรก-la.
never=Nunca
unknown=Desconhecido
@@ -157,7 +157,16 @@ filter.not_archived = Nรฃo arquivado
filter.not_fork = Sem forks
filter.not_mirror = Sem espelhos
filter.not_template = Sem modelos
-copy_generic = Copiar para รกrea de transferรชncia
+copy_generic = Copiar para a รกrea de transferรชncia
+new_repo.title = Novo repositรณrio
+new_migrate.title = Nova migraรงรฃo
+new_org.title = Nova organizaรงรฃo
+new_repo.link = Novo repositรณrio
+new_migrate.link = Nova migraรงรฃo
+new_org.link = Nova organizaรงรฃo
+test = Teste
+error413 = Vocรช esgotou sua cota.
+copy_path = Copiar caminho
[aria]
navbar=Barra de navegaรงรฃo
@@ -189,6 +198,18 @@ buttons.ref.tooltip=Referenciar um issue ou um pull request
buttons.switch_to_legacy.tooltip=Em vez disso, usar o editor legado
buttons.enable_monospace_font=Habilitar fonte mono espaรงada
buttons.disable_monospace_font=Desabilitar fonte mono espaรงada
+buttons.indent.tooltip = Aninhar items em um nรญvel
+buttons.unindent.tooltip = Desaninhar items em um nรญvel
+buttons.new_table.tooltip = Adicionar tabela
+table_modal.header = Adicionar tabela
+table_modal.placeholder.header = Cabeรงalho
+table_modal.placeholder.content = Conteรบdo
+table_modal.label.rows = Linhas
+table_modal.label.columns = Colunas
+link_modal.header = Adicionar um link
+link_modal.url = URL
+link_modal.description = Descriรงรฃo
+link_modal.paste_reminder = Dica: Com uma URL na sua รกrea de transferรชncia, vocรช pode colar diretamente no editor para criar um link.
[filter]
string.asc=A - Z
@@ -196,7 +217,7 @@ string.desc=Z - A
[error]
occurred=Ocorreu um erro
-report_message=Se vocรช acredita que esse รฉ um falha do Forgejo, pesquise por issues no Codeberg ou abra uma nova issue, se necessรกrio.
+report_message=Se vocรช acredita que esse รฉ um falha do Forgejo, pesquise por issues no Codeberg ou abra uma nova issue, se necessรกrio.
missing_csrf=Pedido invรกlido: nรฃo tem token CSRF presente
invalid_csrf=Requisiรงรฃo Invรกlida: token CSRF invรกlido
not_found=Nรฃo foi possรญvel encontrar o destino.
@@ -207,12 +228,12 @@ server_internal = Erro interno do servidor
app_desc=Um serviรงo de hospedagem Git amigรกvel
install=Fรกcil de instalar
platform=Multi-plataforma
-platform_desc=Forgejo roda em qualquer sistema em que Go consegue compilar: Windows, macOS, Linux, ARM, etc. Escolha qual vocรช gosta mais!
lightweight=Leve e rรกpido
lightweight_desc=Forgejo utiliza poucos recursos e consegue mesmo rodar no barato Raspberry Pi. Economize energia elรฉtrica da sua mรกquina!
license=Cรณdigo aberto
-license_desc=Estรก tudo no Forgejo ! Contribua e torne este projeto ainda melhor. Nรฃo tenha vergonha de contribuir!
-install_desc = Apenas rode o binรกrio para a sua plataforma, execute-o com Docker , ou obtenha-o empacotado .
+license_desc=Estรก tudo no Forgejo ! Contribua e torne este projeto ainda melhor. Nรฃo tenha vergonha de contribuir!
+install_desc = Apenas rode o binรกrio para a sua plataforma, execute-o com Docker , ou obtenha-o empacotado .
+platform_desc = Foi confirmado que o Forgejo roda em sistemas operacionais livres, como Linux e FreeBSD, assim como em diferentes arquiteturas de CPU. Escolha sua preferida!
[install]
install=Instalaรงรฃo
@@ -245,7 +266,7 @@ err_admin_name_is_invalid=Nome de usuรกrio do administrador invรกlido
general_title=Configuraรงรตes gerais
app_name=Tรญtulo do servidor
-app_name_helper=Vocรช pode inserir o nome da empresa aqui.
+app_name_helper=Insira o nome da sua instรขncia aqui. Ele serรก mostrado em todas as pรกginas.
repo_path=Caminho raiz do repositรณrio
repo_path_helper=Todos os repositรณrios remotos do Git serรฃo salvos neste diretรณrio.
lfs_path=Caminho raiz do Git LFS
@@ -275,22 +296,22 @@ register_confirm=Exigir confirmaรงรฃo de e-mail para cadastros
mail_notify=Habilitar notificaรงรตes por e-mail
server_service_title=Configuraรงรตes do servidor e serviรงos de terceiros
offline_mode=Habilitar modo local
-offline_mode.description=Desabilitar redes de entrega de conteรบdo de terceiros e entregar todos os recursos localmente.
+offline_mode.description=Desabilitar redes de entrega de conteรบdo (CDNs) de terceiros e fornecer todos os recursos localmente.
disable_gravatar=Desabilitar o gravatar
-disable_gravatar.description=Desabilitar o gravatar e avatar de fontes de terceiros. Um avatar padrรฃo serรก usado a menos que um usuรกrio localmente carrega um avatar.
+disable_gravatar.description=Desabilitar o uso do Gravatar e avatar de fontes de terceiros. Um avatar padrรฃo serรก usado a menos que um usuรกrio localmente carrega um avatar.
federated_avatar_lookup=Habilitar avatares federados
-federated_avatar_lookup.description=Habilitar a busca federativa de avatares a usar o serviรงo federativo de cรณdigo aberto baseado no libravatar.
+federated_avatar_lookup.description=Buscar avatares usando Libravatar.
disable_registration=Somente administradores podem criar novas contas
-disable_registration.description=Desabilitar auto-cadastro de usuรกrio. Somente os administradores serรฃo capazes de criar novas contas de usuรกrio.
-allow_only_external_registration.description=Permitir cadastro somente por meio de serviรงos externos
+disable_registration.description=Apenas administradores do servidor poderรฃo criar novas contas. ร altamente recomendado manter o cadastro desativado a nรฃo ser que deseje hospedar uma instรขncia pรบblica para qualquer pessoa e puder lidar com uma grande quantidade de contas de spam.
+allow_only_external_registration.description=Usuรกrios apenas poderรฃo criar novas contas usando serviรงos externos que tenham sido configurados.
openid_signin=Habilitar acesso via OpenID
openid_signin.description=Habilitar o acesso de usuรกrios via OpenID.
openid_signup=Habilitar cadastros via OpenID
-openid_signup.description=Habilitar o auto-cadastro com base no OpenID.
+openid_signup.description=Permitir que os usuรกrios criem contas com OpenID se o autorregistro estiver habilitado.
enable_captcha=Habilitar CAPTCHA ao registrar
enable_captcha.description=Impor validaรงรฃo por CAPTCHA para cadastro de usuรกrios.
require_sign_in_view=Apenas usuรกrios logados podem visualizar pรกginas
-require_sign_in_view.description=Limitar o acesso de pรกgina aos usuรกrios autenticados. Os visitantes sรณ verรฃo as pรกginas de autenticaรงรฃo e cadastro.
+require_sign_in_view.description=Limitar acesso ao conteรบdo apenas aos usuรกrios autenticados. Visitantes sรณ poderรฃo acessar as pรกginas de autenticaรงรฃo.
admin_setting.description=Criar uma conta de administrador รฉ opcional. O primeiro usuรกrio cadastrado automaticamente se tornarรก um administrador.
admin_title=Configuraรงรตes da conta de administrador
admin_name=Usuรกrio
@@ -311,11 +332,11 @@ save_config_failed=Falha ao salvar a configuraรงรฃo: %v
invalid_admin_setting=Configuraรงรฃo da conta de administrador estรก invรกlida: %v
invalid_log_root_path=Pasta raรญz do log estรก invรกlida: %v
default_keep_email_private=Ocultar endereรงos de e-mail por padrรฃo
-default_keep_email_private.description=Ocultar endereรงos de e-mail de novas contas de usuรกrio por padrรฃo.
+default_keep_email_private.description=Ocultar endereรงos de e-mail de novas contas de usuรกrio por padrรฃo para que esta informaรงรฃo nรฃo seja vazada imediatamente apรณs o cadastro.
default_allow_create_organization=Permitir a criaรงรฃo de organizaรงรตes
-default_allow_create_organization.description=Permitir que novas contas de usuรกrios criem organizaรงรตes por padrรฃo.
+default_allow_create_organization.description=Permitir que novas contas de usuรกrio criem organizaรงรตes por padrรฃo. Quando esta opรงรฃo estรก desabilitada, um administrador precisa dar permissรฃo para a criaรงรฃo de organizaรงรตes por novos usuรกrios.
default_enable_timetracking=Habilitar o cronรดmetro por padrรฃo
-default_enable_timetracking.description=Habilitar o cronรดmetro para novos repositรณrios por padrรฃo.
+default_enable_timetracking.description=Habilitar o uso da funcionalidade de contagem de tempo para novos repositรณrios por padrรฃo.
no_reply_address=Domรญnio de e-mail oculto
no_reply_address_helper=Nome de domรญnio para usuรกrios com endereรงo de e-mail oculto. Por exemplo, o nome de usuรกrio "joe" serรก registrado no Git como "joe@noreply.example.org" se o domรญnio de e-mail oculto estiver definido como "noreply.example.org".
password_algorithm=Algoritmo de hash de senhas
@@ -335,7 +356,7 @@ app_slogan_helper = Insira o slogan de seu servidor aqui. Deixe em branco para d
[home]
uname_holder=Usuรกrio ou e-mail
password_holder=Senha
-switch_dashboard_context=Trocar contexto do painel de controle
+switch_dashboard_context=Trocar contexto do painel
my_repos=Repositรณrios
show_more_repos=Mostrar mais repositรณriosโฆ
collaborative_repos=Repositรณrios colaborativos
@@ -397,14 +418,14 @@ forgot_password_title=Esqueci minha senha
forgot_password=Esqueceu sua senha?
sign_up_now=Precisa de uma conta? Cadastre-se agora.
sign_up_successful=A conta foi criada com sucesso. Bem-vindo!
-confirmation_mail_sent_prompt=Um novo e-mail de confirmaรงรฃo foi enviado para %s . Por favor, verifique sua caixa de e-mail nas prรณximas %s horas para finalizar o processo de cadastro.
+confirmation_mail_sent_prompt=Um novo email de confirmaรงรฃo foi enviado para %s . Para completar o processo de cadastro, por favor verifique sua caixa de entrada e acesse o link fornecido dentro de %s. Se o e-mail estiver incorreto, vocรช pode entrar na conta e solicitar outro e-mail de confirmaรงรฃo para um endereรงo diferente.
must_change_password=Redefina sua senha
allow_password_change=Exigir que o usuรกrio redefina a senha (recomendado)
-reset_password_mail_sent_prompt=Um e-mail de confirmaรงรฃo foi enviado para %s . Por favor, verifique sua caixa de entrada dentro do(s) prรณximo(s) %s para concluir o processo de recuperaรงรฃo de conta.
-active_your_account=Ativar sua conta
+reset_password_mail_sent_prompt=Um e-mail de confirmaรงรฃo foi enviado para %s . Para concluir o processo de recuperaรงรฃo de conta, por favor verifique sua caixa de entrada e siga o link dentro do(s) prรณximo(s) %s.
+active_your_account=Ative sua conta
account_activated=Conta foi ativada
-prohibit_login=ร proibido fazer login
-prohibit_login_desc=Sua conta estรก proibida de fazer login, entre em contato com o administrador do site.
+prohibit_login=Conta estรก suspensa
+prohibit_login_desc=Sua conta foi suspensa de interagir com o servidor. Entre em contato com a administraรงรฃo do servidor para recuperar o acesso.
resent_limit_prompt=Vocรช jรก solicitou recentemente um e-mail de ativaรงรฃo. Por favor, aguarde 3 minutos e tente novamente.
has_unconfirmed_mail=Oi %s, vocรช possui um endereรงo de e-mail nรฃo confirmado (%s ). Se vocรช nรฃo recebeu um e-mail de confirmaรงรฃo ou precisa reenviar um novo, clique no botรฃo abaixo.
resend_mail=Clique aqui para reenviar seu e-mail de ativaรงรฃo
@@ -427,7 +448,7 @@ twofa_scratch_token_incorrect=Seu cรณdigo de backup estรก incorreto.
login_userpass=Acessar
tab_openid=OpenID
oauth_signup_tab=Cadastrar nova conta
-oauth_signup_title=Completar Nova Conta
+oauth_signup_title=Completar nova conta
oauth_signup_submit=Completar conta
oauth_signin_tab=Vincular a uma conta existente
oauth_signin_title=Faรงa login para autorizar a conta vinculada
@@ -447,20 +468,27 @@ email_domain_blacklisted=Vocรช nรฃo pode se cadastrar com seu endereรงo de e-mai
authorize_application=Autorizar aplicativo
authorize_redirect_notice=Vocรช serรก redirecionado para %s se vocรช autorizar este aplicativo.
authorize_application_created_by=Este aplicativo foi criado por %s.
-authorize_application_description=Se vocรช conceder o acesso, ele serรก capaz de acessar e escrever em todas as informaรงรตes da sua conta, incluindo repositรณrios privados e organizaรงรตes.
+authorize_application_description=Se vocรช conceder o acesso, isso permitirรก acessar e alterar todas as informaรงรตes da sua conta, incluindo repositรณrios privados e organizaรงรตes.
authorize_title=Autorizar "%s" para acessar sua conta?
authorization_failed=Autorizaรงรฃo falhou
authorization_failed_desc=A autorizaรงรฃo falhou porque detectamos uma solicitaรงรฃo invรกlida. Entre em contato com o responsรกvel do aplicativo que vocรช tentou autorizar.
sspi_auth_failed=Falha de autenticaรงรฃo SSPI
-password_pwned=A senha que vocรช escolheu faz parte de uma lista de senhas roubadas expostas anteriormente em violaรงรตes de dados. Tente novamente com uma senha diferente e considere alterar essa senha em outro lugar tambรฉm.
+password_pwned=A senha que vocรช escolheu faz parte de uma lista de senhas roubadas expostas anteriormente em violaรงรตes de dados. Tente novamente com uma senha diferente e considere alterar essa senha em outro lugar tambรฉm.
password_pwned_err=Nรฃo foi possรญvel concluir a requisiรงรฃo ao HaveIBeenPwned
change_unconfirmed_email_error = Erro ao alterar o endereรงo de e-mail: %v
change_unconfirmed_email_summary = Alterar o endereรงo de e-mail que o e-mail de ativaรงรฃo serรก enviado para.
-last_admin = Nรฃo รฉ possรญvel remover o รบltimo administrador. Deve haver ao menos um usuรกrio administrador.
+last_admin = Nรฃo รฉ possรญvel remover o รบltimo administrador. Deve existir ao menos um usuรกrio administrador.
change_unconfirmed_email = Se vocรช colocou o endereรงo de e-mail errado durante o cadastro, vocรช pode alterรก-lo abaixo, e uma confirmaรงรฃo serรก enviada para o novo endereรงo.
-remember_me.compromised = O token de login foi invalidado, o que pode indicar que a sua conta foi comprometida. Verifique se nรฃo hรก atividades suspeitas em sua conta.
+remember_me.compromised = O identificador de sessรฃo foi invalidado, o que pode indicar que a sua conta foi comprometida. Verifique se nรฃo hรก atividades suspeitas em sua conta.
tab_signin = Iniciar sessรฃo
tab_signup = Inscrever-se
+hint_register = Precisa de uma conta? Registre-se agora .
+sign_up_button = Registre-se agora.
+hint_login = Jรก possui uma conta? Faรงa login agora!
+sign_in_openid = Continuar com OpenID
+back_to_sign_in = Voltar a Iniciar Sessรฃo
+unauthorized_credentials = As credenciais estรฃo incorretas ou expiraram. Tente novamente o comando ou consulte %s para obter mais informaรงรตes
+use_onetime_code = Usar um cรณdigo de uso รบnico
[mail]
view_it_on=Veja em %s
@@ -477,10 +505,10 @@ activate_email=Verifique seu endereรงo de e-mail
activate_email.title=%s, por favor verifique o seu endereรงo de e-mail
activate_email.text=Por favor clique no link a seguir para verificar o seu endereรงo de e-mail em %s :
-register_notify=Bem-vindo ao Forgejo
+register_notify=Boas vindas a %s
register_notify.title=%[1]s, bem-vindo(a) a %[2]s
register_notify.text_1=este รฉ o seu e-mail de confirmaรงรฃo de registro para %s!
-register_notify.text_2=Vocรช pode fazer login em sua conta utilizando o usuรกrio: %s
+register_notify.text_2=Vocรช pode iniciar a sessรฃo com o usuรกrio: %s
register_notify.text_3=Se outra pessoa criou esta conta para vocรช, รฉ preciso definir a sua senha primeiro.
reset_password=Recuperar sua conta
@@ -530,6 +558,21 @@ team_invite.text_3=Nota: este convite foi destinado a %[1]s. Se vocรช nรฃo estav
admin.new_user.text = Clique aqui para gerenciar este usuรกrio no painel de administraรงรฃo.
admin.new_user.user_info = Informaรงรตes do usuรกrio
admin.new_user.subject = Novo usuรกrio %s acabou de se cadastrar
+password_change.subject = A sua senha foi alterada
+password_change.text_1 = A senha de sua conta foi alterada recentemente.
+account_security_caution.text_2 = Caso nรฃo tenha realizado esta aรงรฃo, a sua conta pode ter sido roubada. Entre em contato com os administradores do site.
+primary_mail_change.subject = O seu endereรงo de e-mail principal foi alterado
+primary_mail_change.text_1 = O endereรงo de e-mail principal de sua conta foi alterado para %[1]s. Vocรช nรฃo receberรก mais notificaรงรตes relativas ร sua conta neste endereรงo.
+totp_disabled.subject = A autenticaรงรฃo em dois fatores foi desabilitada
+removed_security_key.subject = Uma chave de seguranรงa foi removida
+removed_security_key.text_1 = A chave de seguranรงa "%[1]s" foi removida de sua conta.
+account_security_caution.text_1 = Caso tenha sido vocรช, este e-mail pode ser ignorado.
+totp_enrolled.subject = Vocรช ativou TOTP como mรฉtodo 2FA
+totp_disabled.text_1 = A senha de uso รบnico baseada em tempo (TOTP) na sua conta foi desativada.
+totp_disabled.no_2fa = Jรก nรฃo existem mais outros mรฉtodos de autenticaรงรฃo em dois fatores (2FA) configurados, ou seja, nรฃo รฉ mais necessรกrio acessar sua conta com 2FA.
+removed_security_key.no_2fa = Jรก nรฃo existem mais outros mรฉtodos de autenticaรงรฃo em dois fatores (2FA) configurados, ou seja, nรฃo รฉ mais necessรกrio acessar sua conta com 2FA.
+totp_enrolled.text_1.no_webauthn = Vocรช acabou de habilitar a TOTP para sua conta. Isso significa que para todos os acessos futuros ร sua conta vocรช deverรก usar a TOTP como mรฉtodo de 2FA.
+totp_enrolled.text_1.has_webauthn = Vocรช acabou de habilitar a TOTP para sua conta. Isso significa que para todos os futuros acessos ร sua conta vocรช pode usar a TOTP como mรฉtodo de 2FA ou usar qualquer uma de suas chaves de seguranรงa.
[modal]
yes=Sim
@@ -631,7 +674,7 @@ target_branch_not_exist=O branch de destino nรฃo existe.
username_error_no_dots = ` pode conter apenas caracteres alfanumรฉricos ("0-9, "a-z", "A-Z"), hรญfens ("-") e traรงos inferiores ("_"). Nรฃo รฉ permitido conter caracteres nรฃo alfanumรฉricos no inรญcio ou fim. Caracteres nรฃo alfanumรฉricos consecutivos tambรฉm nรฃo sรฃo permitidos.`
admin_cannot_delete_self = Vocรช nรฃo pode excluir a si mesmo quando vocรช รฉ um administrador. Por favor, remova suas permissรตes de administrador primeiro.
AccessToken = Token de acesso
-To = Nome do Branch
+To = Nome do ramo
Website = Site
Pronouns = Pronomes
Biography = Biografia
@@ -641,6 +684,8 @@ required_prefix = A entrada deve comeรงar com "%s"
FullName = Nome completo
Description = Descriรงรฃo
unset_password = O usuรกrio de login nรฃo definiu a senha.
+username_claiming_cooldown = Este nome de usuรกrio nรฃo pode ser registrado porque o perรญodo de espera ainda nรฃo acabou. Ele poderรก ser registrado em %[1]s.
+email_domain_is_not_allowed = O domรญnio do endereรงo de email da conta %s estรก em conflito com EMAIL_DOMAIN_ALLOWLIST ou EMAIL_DOMAIN_BLOCKLIST. Certifique-se de que vocรช colocou o endereรงo de email correto.
[user]
@@ -670,13 +715,22 @@ form.name_chars_not_allowed=O usuรกrio "%s" contรฉm caracteres invรกlidos.
block_user = Bloquear usuรกrio
unblock = Desbloquear
block = Bloquear
-block_user.detail_2 = Este usuรกrio nรฃo poderรก interagir com seus repositรณrios, questรตes criadas e comentรกrios.
-follow_blocked_user = Vocรช nรฃo pode seguir este usuรกrio, pois vocรช o bloqueou ou foi bloqueado por ele.
-block_user.detail_3 = Este(a) usuรกrio(a) nรฃo poderรก adicionรก-lo(a) como colaborador(a), nem vocรช poderรก adicionรก-lo(a) como colaborador(a).
-block_user.detail = Por favor, entenda que se vocรช bloquear este usuรกrio, outras aรงรตes serรฃo tomadas. Tais como:
+block_user.detail_2 = Este usuรกrio nรฃo poderรก interagir com repositรณrios, issues ou comentรกrios criados por vocรช.
+follow_blocked_user = Vocรช nรฃo pode seguir este usuรกrio porque vocรช o bloqueou ou foi bloqueado por ele.
+block_user.detail_3 = Vocรชs nรฃo poderรฃo adicionar um ao outro como colaboradores de um repositรณrio.
+block_user.detail = Note que bloquear um usuรกrio tem outros efeitos, tais como:
followers_one = %d seguidor
-following_one = %d seguindo
-block_user.detail_1 = Vocรช deixarรก de seguir este usuรกrio.
+following_one = seguindo %d
+block_user.detail_1 = Vocรชs deixarรฃo de seguir um ao outro e nรฃo poderรฃo mais seguir um ao outro.
+following.title.few = seguindo
+following.title.one = seguindo
+followers.title.one = seguidor
+followers.title.few = seguidores
+public_activity.visibility_hint.self_private = Sua atividade estรก visรญvel apenas para vocรช e para os administradores da instรขncia. Configurar .
+public_activity.visibility_hint.self_public = Sua atividade estรก visรญvel para todos, exceto interaรงรตes em espaรงos privados. Configurar .
+public_activity.visibility_hint.admin_public = Sua atividade estรก visรญvel para todos, mas como um administrador vocรช tambรฉm pode ver interaรงรตes em espaรงos privados.
+public_activity.visibility_hint.admin_private = Essa atividade estรก visรญvel para vocรช porque vocรช รฉ um administrador, mas o usuรกrio dejesa que ela seja mantida em privado.
+public_activity.visibility_hint.self_private_profile = Sua atividade sรณ รฉ visรญvel para vocรช e para os administradores do servidor porque seu perfil รฉ privado. Configurar .
[settings]
profile=Perfil
@@ -698,9 +752,9 @@ uid=UID
webauthn=Chaves de seguranรงa
public_profile=Perfil pรบblico
-biography_placeholder=Conte-nos um pouco sobre vocรช! (Vocรช pode usar Markdown)
+biography_placeholder=Conte um pouco sobre vocรช! (Markdown รฉ suportado)
location_placeholder=Compartilhe sua localizaรงรฃo aproximada com outras pessoas
-profile_desc=Controle como o seu perfil รฉ exibido para outros usuรกrios. Seu endereรงo de e-mail principal serรก usado para notificaรงรตes, recuperaรงรฃo de senha e operaรงรตes do Git baseadas na Web.
+profile_desc=Sobre vocรช
password_username_disabled=Usuรกrios nรฃo-locais nรฃo podem alterar seus nomes de usuรกrio. Por favor contate o administrador do site para mais informaรงรตes.
full_name=Nome completo
website=Site
@@ -755,22 +809,22 @@ update_user_avatar_success=O avatar do usuรกrio foi atualizado.
update_password=Modificar senha
old_password=Senha atual
new_password=Nova senha
-retype_new_password=Confirmar nova senha
+retype_new_password=Confirme a nova senha
password_incorrect=A senha atual estรก incorreta.
-change_password_success=Sua senha foi atualizada. Acesse usando sua nova senha de agora em diante.
+change_password_success=Sua senha foi atualizada. A partir de agora, use sua nova senha para acessar sua conta.
password_change_disabled=Contas nรฃo-locais nรฃo podem alterar sua senha atravรฉs da interface web do Forgejo.
emails=Endereรงos de e-mail
manage_emails=Gerenciar endereรงos de e-mail
-manage_themes=Tema Padrรฃo
+manage_themes=Tema padrรฃo
manage_openid=Endereรงos OpenID
email_desc=Seu endereรงo de e-mail principal serรก usado para notificaรงรตes, recuperaรงรฃo de senha e, desde que nรฃo esteja oculto, para operaรงรตes do Git baseadas na Web.
-theme_desc=Este serรก o seu tema padrรฃo em todo o site.
+theme_desc=Este tema serรก usado para a interface web quando vocรช fizer login.
primary=Principal
activated=Ativado
requires_activation=Requer ativaรงรฃo
primary_email=Tornar primรกrio
-activate_email=Enviar ativaรงรฃo
+activate_email=Enviar e-mail de ativaรงรฃo
activations_pending=Ativaรงรตes pendentes
can_not_add_email_activations_pending=Hรก uma ativaรงรฃo pendente, tente novamente em alguns minutos se quiser adicionar um novo e-mail.
delete_email=Remover
@@ -786,12 +840,12 @@ add_new_email=Adicionar novo endereรงo de e-mail
add_new_openid=Adicionar novo URI OpenID
add_email=Adicionar novo endereรงo de e-mail
add_openid=Adicionar URI OpenID
-add_email_confirmation_sent=Um e-mail de confirmaรงรฃo foi enviado para "%s". Verifique sua caixa de entrada nos prรณximos %s para confirmar seu endereรงo de e-mail.
+add_email_confirmation_sent=Um e-mail de confirmaรงรฃo foi enviado para "%s". Para confirmar seu endereรงo de e-mail, verifique sua caixa de entrada e acesse o link fornecido nela em atรฉ %s.
add_email_success=O novo endereรงo de e-mail foi adicionado.
email_preference_set_success=Preferรชncia de e-mail definida com sucesso.
add_openid_success=O novo endereรงo de OpenID foi adicionado.
keep_email_private=Ocultar endereรงo de e-mail
-keep_email_private_popup=Isso ocultarรก seu endereรงo de e-mail do seu perfil, bem como quando vocรช fizer um pull request ou editar um arquivo usando a interface Web. Os commits enviados nรฃo serรฃo modificados.
+keep_email_private_popup=Seu endereรงo de email nรฃo serรก exibido no seu perfil e nรฃo serรก o padrรฃo para commits feitos pela interface web, como envios de arquivos, modificaรงรตes e commits de merge. Em vez disso, um endereรงo especial %s pode ser usado para associar commits com a sua conta. Esta opรงรฃo nรฃo irรก afetar commits jรก existentes.
openid_desc=OpenID permite delegar autenticaรงรฃo para um provedor externo.
manage_ssh_keys=Gerenciar chaves SSH
@@ -932,9 +986,9 @@ twofa_desc=Autenticaรงรฃo de dois fatores melhora a seguranรงa de sua conta.
twofa_is_enrolled=Sua conta estรก atualmente habilitada com autenticaรงรฃo de dois fatores.
twofa_not_enrolled=Sua conta nรฃo estรก atualmente inscrita para a autenticaรงรฃo em duas etapas.
twofa_disable=Desabilitar autenticaรงรฃo de dois fatores
-twofa_scratch_token_regenerate=Gerar novamente o token de backup
+twofa_scratch_token_regenerate=Gerar novamente o token de recuperaรงรฃo de uso รบnico
twofa_scratch_token_regenerated=Seu token agora รฉ %s. Guarde-a em um local seguro, pois ela nunca mais serรก exibido.
-twofa_enroll=Inscrever para a autenticaรงรฃo de dois fatores
+twofa_enroll=Habilitar a autenticaรงรฃo de dois fatores
twofa_disable_note=Vocรช pode desabilitar a autenticaรงรฃo de dois fatores se necessรกrio.
twofa_disable_desc=Desabilitar a autenticaรงรฃo de dois fatores tornarรก sua conta menos segura. Tem certeza que deseja continuar?
regenerate_scratch_token_desc=Se vocรช perdeu o seu token de backup, ou teve que usรก-lo para realizar um acesso, vocรช pode redefini-lo.
@@ -943,10 +997,10 @@ scan_this_image=Escaneie esta imagem com o seu aplicativo de autenticaรงรฃo:
or_enter_secret=Ou digite esse cรณdigo: %s
then_enter_passcode=E insira a senha mostrada no aplicativo:
passcode_invalid=Esse cรณdigo de acesso รฉ invรกlido. Tente novamente.
-twofa_enrolled=Sua conta foi inscrita na autenticaรงรฃo de dois fatores. Armazene seu token de backup (%s) em um local seguro, pois ele รฉ exibido apenas uma vez!
+twofa_enrolled=Sua conta foi inscrita na autenticaรงรฃo de dois fatores. Armazene seu token de recuperaรงรฃo de uso รบnico (%s) em um local seguro, pois ele nรฃo serรก exibido novamente.
twofa_failed_get_secret=Falha ao obter o segredo.
-webauthn_desc=Chaves de seguranรงa sรฃo dispositivos de hardware que contรฉm chaves de criptografia. Elas podem ser usadas para autenticaรงรฃo de dois fatores. A chave de seguranรงa deve suportar o padrรฃo WebAuthnn Authenticator .
+webauthn_desc=Chaves de seguranรงa sรฃo dispositivos de hardware que contรฉm chaves de criptografia. Elas podem ser usadas para autenticaรงรฃo de dois fatores. A chave de seguranรงa deve suportar o padrรฃo WebAuthnn Authenticator .
webauthn_register_key=Adicionar chave
webauthn_nickname=Apelido
webauthn_delete_key=Remover chave
@@ -975,7 +1029,7 @@ delete_account_desc=Tem certeza que deseja apagar sua conta de usuรกrio permanen
email_notifications.enable=Habilitar notificaรงรตes por e-mail
email_notifications.onmention=Somente quando for mencionado(a)
email_notifications.disable=Desabilitar notificaรงรตes por e-mail
-email_notifications.submit=Atualizar preferรชncias de e-mail
+email_notifications.submit=Definir preferรชncia de email
email_notifications.andyourown=e suas prรณprias notificaรงรตes
visibility=Visibilidade do usuรกrio
@@ -986,13 +1040,13 @@ visibility.limited_tooltip=Visรญvel apenas para usuรกrios autenticados
visibility.private=Privada
visibility.private_tooltip=Visรญvel apenas para membros das organizaรงรตes ร s quais vocรช se associou
blocked_users = Usuรกrios bloqueados
-blocked_since = Bloqueado desde %s
+blocked_since = Bloqueado(a) desde %s
user_unblock_success = O usuรกrio foi desbloqueado.
user_block_success = O usuรกrio foi bloqueado.
twofa_recovery_tip = Caso perca o seu dispositivo, vocรช poderรก usar uma chave de uso รบnico para recuperar o acesso ร sua conta.
webauthn_key_loss_warning = Caso perca as suas chaves de seguranรงa, vocรช perderรก o acesso ร sua conta.
blocked_users_none = Nenhum usuรกrio bloqueado.
-access_token_desc = As permissรตes selecionadas para o token limitam o acesso apenas ร s rotas da API correspondentes. Veja a documentaรงรฃo para mais informaรงรตes.
+access_token_desc = As permissรตes selecionadas para o token limitam o acesso apenas ร s rotas da API correspondentes. Veja a documentaรงรฃo para mais informaรงรตes.
webauthn_alternative_tip = Vocรช talvez queira configurar um mรฉtodo adicional de autenticaรงรฃo.
change_password = Alterar senha
hints = Dicas
@@ -1001,9 +1055,42 @@ pronouns_custom = Personalizado
pronouns_unspecified = Nรฃo especificado
language.title = Idioma padrรฃo
additional_repo_units_hint = Sugira habilitar unidades de repositรณrio adicionais
-additional_repo_units_hint_description = Exiba um botรฃo "Adicionar mais unidades..." para repositรณrios que nรฃo possuem todas as unidades disponรญveis habilitadas.
+additional_repo_units_hint_description = Exibir uma sugestรฃo para "Habilitar mais" em repositรณrios que nรฃo possuem todas as unidades disponรญveis habilitadas.
update_hints = Dicas de atualizaรงรฃo
update_hints_success = As dicas foram atualizadas.
+keep_activity_private.description = A sua atividade pรบblica estarรก visรญvel apenas para si e para os administradores do servidor.
+language.localization_project = Ajude-nos a traduzir Forgejo para o seu idioma! Mais informaรงรตes .
+language.description = Essa lรญngua serรก salva em sua conta e serรก usada como padrรฃo apรณs vocรช iniciar a sessรฃo.
+user_block_yourself = Vocรช nรฃo pode se bloquear.
+pronouns_custom_label = Pronomes personalizados
+change_username_redirect_prompt.with_cooldown.one = O nome de usuรกrio antigo ficarรก disponรญvel para qualquer pessoa apรณs um perรญodo de espera de %[1]d dia, vocรช ainda pode recuperar o nome de usuรกrio antigo durante este perรญodo de espera.
+change_username_redirect_prompt.with_cooldown.few = O nome de usuรกrio antigo ficarรก disponรญvel para qualquer pessoa apรณs um perรญodo de espera de %[1]d dias, vocรช ainda pode recuperar o nome de usuรกrio antigo durante este perรญodo de espera.
+quota.applies_to_user = As seguintes regras de cota se aplicam ร sua conta
+quota.rule.exceeded.helper = O tamanho total de objetos para esta regra excedeu a cota.
+keep_pronouns_private = Mostrar pronomes apenas para usuรกrios autenticados
+keep_pronouns_private.description = Isto irรก esconder seus pronomes de visitantes que nรฃo fizeram login.
+storage_overview = Visรฃo geral de armazenamento
+quota = Cota
+quota.applies_to_org = As seguintes regras de cota se aplicam a esta organizaรงรฃo
+quota.rule.exceeded = Excedido
+quota.rule.no_limit = Ilimitado
+quota.sizes.all = Tudo
+quota.sizes.repos.all = Repositรณrios
+quota.sizes.repos.public = Repositรณrios pรบblicos
+quota.sizes.repos.private = Repositรณrios privados
+quota.sizes.git.all = Conteรบdo Git
+quota.sizes.git.lfs = LFS Git
+quota.sizes.assets.all = Assets
+quota.sizes.assets.attachments.all = Anexos
+quota.sizes.assets.attachments.issues = Anexos de issue
+quota.sizes.assets.attachments.releases = Anexos de release
+quota.sizes.assets.artifacts = Artefatos
+quota.sizes.assets.packages.all = Pacotes
+quota.sizes.wiki = Wiki
+regenerate_token = Regenerar
+regenerate_token_success = O token foi regenerado. Aplicaรงรตes que usam este token nรฃo terรฃo mais acesso ร sua conta e precisam ser atualizadas com o novo token.
+access_token_regeneration = Regenerar token de acesso
+access_token_regeneration_desc = Regenerar um token de acesso irรก revogar o acesso a essa conta para as aplicaรงรตes que estiverem utilizando este token. Isto nรฃo pode ser desfeito. Continuar?
[repo]
owner=Proprietรกrio
@@ -1012,16 +1099,16 @@ repo_name=Nome do repositรณrio
repo_name_helper=Um bom nome de repositรณrio รฉ composto por palavras curtas, memorizรกveis e รบnicas.
repo_size=Tamanho do repositรณrio
template=Modelo
-template_select=Selecione um modelo.
+template_select=Selecione um modelo
template_helper=Tornar repositรณrio um modelo
template_description=Os repositรณrios de modelo permitem que os usuรกrios gerem novos repositรณrios com a mesma estrutura de diretรณrio, arquivos e configuraรงรตes opcionais.
visibility=Visibilidade
visibility_description=Somente o proprietรกrio ou os membros da organizaรงรฃo, se tiverem direitos, poderรฃo vรช-lo.
visibility_helper=Tornar o repositรณrio privado
visibility_helper_forced=O administrador do site forรงa novos repositรณrios a serem privados.
-visibility_fork_helper=(Esta alteraรงรฃo irรก afetar todos os forks.)
+visibility_fork_helper=(Esta alteraรงรฃo irรก afetar a visibilidade de todos os forks.)
clone_helper=Precisa de ajuda com o clone? Visite a Ajuda .
-fork_repo=Fork do repositรณrio
+fork_repo=Fazer fork do repositรณrio
fork_from=Fork de
already_forked=Vocรช jรก fez o fork de %s
fork_to_different_account=Faรงa um fork para uma conta diferente
@@ -1037,17 +1124,17 @@ generate_from=Gerar a partir de
repo_desc=Descriรงรฃo
repo_desc_helper=Digite uma breve descriรงรฃo (opcional)
repo_lang=Linguagem
-repo_gitignore_helper=Selecione modelos do .gitignore.
+repo_gitignore_helper=Selecionar modelos de .gitignore
repo_gitignore_helper_desc=Escolha os arquivos que nรฃo serรฃo rastreados da lista de modelos para linguagens comuns. Artefatos tรญpicos gerados pelos compiladores de cada linguagem estรฃo incluรญdos no .gitignore por padrรฃo.
-issue_labels=Etiquetas de issue
-issue_labels_helper=Selecione um conjunto de etiquetas de issue.
+issue_labels=Etiquetas
+issue_labels_helper=Selecione um conjunto de etiquetas
license=Licenรงa
-license_helper=Selecione um arquivo de licenรงa.
-license_helper_desc=Uma licenรงa define o que os outros podem e nรฃo podem fazer com o seu cรณdigo. Nรฃo tem certeza qual รฉ a mais adequada para o seu projeto? Veja Escolher uma licenรงa.
+license_helper=Selecione um arquivo de licenรงa
+license_helper_desc=Uma licenรงa define o que os outros podem e nรฃo podem fazer com o seu cรณdigo. Nรฃo tem certeza qual รฉ a mais adequada para o seu projeto? Veja Escolher uma licenรงa .
readme=LEIA-ME
-readme_helper=Selecione um modelo de arquivo LEIA-ME.
+readme_helper=Selecione um modelo de arquivo README
readme_helper_desc=Aqui vocรช pode escrever uma descriรงรฃo completa para o seu projeto.
-auto_init=Inicializar o repositรณrio (adicionando .gitignore, licenรงa e LEIA-ME)
+auto_init=Inicializar repositรณrio
trust_model_helper=Selecione o modelo de confianรงa para verificaรงรฃo de assinatura. As opรงรตes possรญveis sรฃo:
trust_model_helper_collaborator=Colaborador: Confiar em assinaturas de colaboradores
trust_model_helper_committer=Committer: Confiar em assinaturas que correspondem aos committers
@@ -1059,12 +1146,12 @@ default_branch_label=padrรฃo
default_branch_helper=O branch padrรฃo รฉ o branch base para pull requests e commits de cรณdigo.
mirror_prune=Varrer
mirror_prune_desc=Remover referรชncias obsoletas de controle remoto
-mirror_interval=Intervalo de espelhamento (unidades vรกlidas sรฃo 'h', 'm', ou 's'). O desabilita a sincronizaรงรฃo automรกtica. (Intervalo mรญnimo: %s)
+mirror_interval=Intervalo de espelhamento (unidades vรกlidas de tempo sรฃo "h", "m", "s"). O valor 0 desabilita a sincronizaรงรฃo periรณdica. (Intervalo mรญnimo: %s)
mirror_interval_invalid=O intervalo do espelhamento nรฃo รฉ vรกlido.
mirror_sync_on_commit=Sincronizar quando commits forem enviados
mirror_address=Clonar a partir de URL
mirror_address_desc=Coloque todas as credenciais necessรกrias na seรงรฃo de autorizaรงรฃo.
-mirror_address_url_invalid=O URL fornecido รฉ invรกlido. Vocรช deve escapar todos os componentes do URL corretamente.
+mirror_address_url_invalid=A URL fornecida รฉ invรกlida. Vocรช deve escapar todos os componentes da URL corretamente.
mirror_address_protocol_invalid=O URL fornecido รฉ invรกlido. Somente locais http(s):// ou git:// podem ser usados para espelhamento.
mirror_lfs=Armazenamento de Arquivo Grande (LFS)
mirror_lfs_desc=Ativar espelhamento de dados LFS.
@@ -1081,7 +1168,7 @@ forks=Forks
reactions_more=e %d mais
unit_disabled=O administrador do site desabilitou esta seรงรฃo do repositรณrio.
language_other=Outra
-adopt_search=Digite o nome de usuรกrio para pesquisar por repositรณrios รณrfรฃos... (deixe em branco para encontrar todos)
+adopt_search=Digite o nome de usuรกrio para pesquisar por repositรณrios รณrfรฃosโฆ (deixe em branco para encontrar todos)
adopt_preexisting_label=Adotar arquivos
adopt_preexisting=Adotar arquivos prรฉ-existentes
adopt_preexisting_content=Criar repositรณrio a partir de %s
@@ -1118,10 +1205,10 @@ template.issue_labels=Etiquetas de issue
template.one_item=Deve-se selecionar pelo menos um item de modelo
template.invalid=Deve-se selecionar um repositรณrio de modelo
-archive.title=Este repositรณrio estรก arquivado. Vocรช pode visualizar arquivos e clonรก-lo, mas nรฃo pode fazer push, abrir issues ou pull requests.
-archive.title_date=Este repositรณrio foi arquivado em %s. Vocรช pode visualizar arquivos e clonรก-lo, mas nรฃo pode fazer push, abrir issues ou pull requests.
-archive.issue.nocomment=Este repositรณrio estรก arquivado. Vocรช nรฃo pode comentar nas issues.
-archive.pull.nocomment=Este repositรณrio estรก arquivado. Vocรช nรฃo pode comentar nos pull requests.
+archive.title=Este repositรณrio estรก arquivado. Vocรช pode visualizar arquivos e clonรก-lo, mas nรฃo pode fazer alteraรงรตes, tais como push, novos issues, pull requests ou comentรกrios.
+archive.title_date=Este repositรณrio foi arquivado em %s. Vocรช pode visualizar arquivos e clonรก-lo, mas nรฃo pode fazer alteraรงรตes, tais como push, abrir issues, pull requests ou comentรกrios.
+archive.issue.nocomment=Este repositรณrio estรก arquivado. Vocรช nรฃo pode comentar em issues.
+archive.pull.nocomment=Este repositรณrio estรก arquivado. Vocรช nรฃo pode comentar em pull requests.
form.reach_limit_of_creation_1=Vocรช jรก atingiu o seu limite de %d repositรณrio.
form.reach_limit_of_creation_n=Vocรช jรก atingiu o limite de %d repositรณrios.
@@ -1143,7 +1230,7 @@ migrate_items_milestones=Marcos
migrate_items_labels=Etiquetas
migrate_items_issues=Issues
migrate_items_pullrequests=Pull requests
-migrate_items_merge_requests=Requisiรงรตes de merge
+migrate_items_merge_requests=Pedidos de merge
migrate_items_releases=Versรตes
migrate_repo=Migrar repositรณrio
migrate.clone_address=Migrar / Clonar de URL
@@ -1159,14 +1246,14 @@ migrate.migrate_items_options=Um Token de Acesso รฉ necessรกrio para migrar iten
migrated_from=Migrado de %[2]s
migrated_from_fake=Migrado de %[1]s
migrate.migrate=Migrar de %s
-migrate.migrating=Migrando a partir de %s ...
+migrate.migrating=Migrando de %s โฆ
migrate.migrating_failed=Migraรงรฃo a partir de %s falhou.
migrate.migrating_failed.error=Falha ao migrar: %s
migrate.migrating_failed_no_addr=A migraรงรฃo falhou.
migrate.github.description=Migre dados do servidor github.com ou GitHub Enterprise.
migrate.git.description=Migrar um repositรณrio somente de qualquer serviรงo Git.
migrate.gitlab.description=Migrar dados de gitlab.com ou de outras instรขncias do GitLab.
-migrate.gitea.description=Migrar dados de gitea.com ou de outras instรขncias do Gitea/Forgejo.
+migrate.gitea.description=Migrar dados de gitea.com ou de outras instรขncias do Gitea.
migrate.gogs.description=Migrar dados de notabug.org ou de outras instรขncias do Gogs.
migrate.onedev.description=Migrar dados de code.onedev.io ou de outras instรขncias do OneDev.
migrate.codebase.description=Migrar dados de codebasehq.com.
@@ -1175,9 +1262,9 @@ migrate.migrating_git=Migrando dados Git
migrate.migrating_topics=Migrando tรณpicos
migrate.migrating_milestones=Migrando marcos
migrate.migrating_labels=Migrando rรณtulos
-migrate.migrating_releases=Migrando Versรตes
-migrate.migrating_issues=Migrando Issues
-migrate.migrating_pulls=Migrando Pull Requests
+migrate.migrating_releases=Migrando releases
+migrate.migrating_issues=Migrando issues
+migrate.migrating_pulls=Migrando pull requests
migrate.cancel_migrating_title=Cancelar migraรงรฃo
migrate.cancel_migrating_confirm=Vocรช quer cancelar essa migraรงรฃo?
@@ -1250,15 +1337,16 @@ ambiguous_character=`%[1]c [U+%04[1]X] รฉ confundรญvel com o %[2]c [U+%04[2]X]`
escape_control_characters=Escapar
unescape_control_characters=Desescapar
file_copy_permalink=Copiar link permanente
-view_git_blame=Ver Git Blame
-video_not_supported_in_browser=Seu navegador nรฃo suporta a tag 'video' do HTML5.
-audio_not_supported_in_browser=Seu navegador nรฃo suporta a tag 'audio' do HTML5.
+view_git_blame=Ver git blame
+video_not_supported_in_browser=Seu navegador nรฃo tem suporte para a tag "video" do HTML5.
+audio_not_supported_in_browser=Seu navegador nรฃo tem suporte para a tag "audio" do HTML5.
stored_lfs=Armazenado com Git LFS
+stored_annex=Armazenado com Git Annex
symbolic_link=Link simbรณlico
executable_file=Arquivo executรกvel
commit_graph=Grรกfico de commits
commit_graph.select=Selecionar branches
-commit_graph.hide_pr_refs=Esconder Pull Requests
+commit_graph.hide_pr_refs=Esconder pull requests
commit_graph.monochrome=Monocromรกtico
commit_graph.color=Colorido
commit.contained_in=Esse commit estรก contido em:
@@ -1277,6 +1365,7 @@ editor.upload_file=Enviar arquivo
editor.edit_file=Editar arquivo
editor.preview_changes=Prรฉ-visualizar alteraรงรตes
editor.cannot_edit_lfs_files=Arquivos LFS nรฃo podem ser editados na interface web.
+editor.cannot_edit_annex_files=Arquivos Annex nรฃo podem ser editados na interface web.
editor.cannot_edit_non_text_files=Arquivos binรกrios nรฃo podem ser editados na interface web.
editor.edit_this_file=Editar arquivo
editor.this_file_locked=Arquivo estรก bloqueado
@@ -1286,22 +1375,23 @@ editor.delete_this_file=Excluir arquivo
editor.must_have_write_access=Vocรช deve ter permissรฃo de escrita para fazer ou propor alteraรงรตes neste arquivo.
editor.file_delete_success=O arquivo "%s" foi excluรญdo.
editor.name_your_file=Nomeie o seu arquivoโฆ
-editor.filename_help=Adicione um diretรณrio digitando seu nome seguido por uma barra ('/'). Remova um diretรณrio digitando o backspace no inรญcio do campo de entrada.
+editor.filename_help=Adicione um diretรณrio digitando o nome seguido por uma barra ("/"). Remova um diretรณrio pressionando apagar no inรญcio do campo de entrada.
editor.or=ou
editor.cancel_lower=Cancelar
-editor.commit_signed_changes=Commit de alteradores assinadas
-editor.commit_changes=Aplicar commit das alteraรงรตes
-editor.add_tmpl=Adicionar ""
+editor.commit_signed_changes=Criar commit das modificaรงรตes assinadas
+editor.commit_changes=Criar commit das modificaรงรตes
+editor.add_tmpl=Adicionar "<%s>"
+editor.add_tmpl.filename = nome do arquivo
editor.add=Adicionar %s
editor.update=Atualizar %s
editor.delete=Excluir %s
editor.patch=Aplicar correรงรฃo
editor.patching=Corrigindo:
editor.fail_to_apply_patch=`Nรฃo foi possรญvel aplicar a correรงรฃo "%s"`
-editor.new_patch=Nova correรงรฃo
+editor.new_patch=Novo patch
editor.commit_message_desc=Adicione uma descriรงรฃo detalhada (opcional)...
editor.signoff_desc=Adicione um assinado-por-committer no final do log do commit.
-editor.commit_directly_to_this_branch=Commit diretamente no branch %s .
+editor.commit_directly_to_this_branch=Commit diretamente no branch %[1]s .
editor.create_new_branch=Crie um novo branch para este commit e crie um pull request.
editor.create_new_branch_np=Crie um novo branch para este commit.
editor.propose_file_change=Propor alteraรงรฃo de arquivo
@@ -1317,15 +1407,15 @@ editor.file_is_a_symlink=`"%s" รฉ um link simbรณlico. Links simbรณlicos nรฃo pod
editor.filename_is_a_directory=O nome do arquivo "%s" jรก รฉ usado como um nome de diretรณrio neste repositรณrio.
editor.file_editing_no_longer_exists=O arquivo que estรก sendo editado, "%s", nรฃo existe mais neste repositรณrio.
editor.file_deleting_no_longer_exists=O arquivo a ser excluรญdo, "%s", nรฃo existe mais neste repositรณrio.
-editor.file_changed_while_editing=O conteรบdo do arquivo mudou desde que vocรช comeรงou a editar. Clique aqui para ver o que foi editado ou clique em Aplicar commit das alteraรงรตes novamemente para sobreescrever estas alteraรงรตes.
+editor.file_changed_while_editing=O conteรบdo do arquivo mudou desde que vocรช abriu o arquivo. Clique aqui para ver as diferenรงas ou clique em Aplicar commit das alteraรงรตes novamente para sobrescrever as alteraรงรตes com sua versรฃo atual.
editor.file_already_exists=Um arquivo com nome "%s" jรก existe neste repositรณrio.
editor.commit_empty_file_header=Fazer commit de um arquivo vazio
editor.commit_empty_file_text=O arquivo que vocรช estรก prestes fazer commit estรก vazio. Continuar?
editor.no_changes_to_show=Nenhuma alteraรงรฃo a mostrar.
editor.fail_to_update_file=Falha ao atualizar/criar arquivo "%s".
editor.fail_to_update_file_summary=Mensagem de erro:
-editor.push_rejected_no_message=A alteraรงรฃo foi rejeitada pelo servidor sem uma mensagem. Por favor, verifique os Hooks Git.
-editor.push_rejected=A alteraรงรฃo foi rejeitada pelo servidor. Por favor, verifique os Hooks Git.
+editor.push_rejected_no_message=A alteraรงรฃo foi rejeitada pelo servidor sem uma mensagem. Por favor, verifique os Git hooks .
+editor.push_rejected=A alteraรงรฃo foi rejeitada pelo servidor. Por favor, verifique os Git hooks .
editor.push_rejected_summary=Mensagem completa de rejeiรงรฃo:
editor.add_subdir=Adicionar um subdiretรณrio...
editor.unable_to_upload_files=Ocorreu um erro ao enviar arquivos para "%s": %v
@@ -1370,7 +1460,7 @@ commitstatus.failure=Falha
commitstatus.pending=Pendente
commitstatus.success=Sucesso
-ext_issues=Acesso a Issues Externos
+ext_issues=Issues externos
ext_issues.desc=Link para o issue tracker externo.
projects=Projetos
@@ -1391,7 +1481,7 @@ projects.modify=Editar projeto
projects.edit_success=Projeto "%s" atualizado.
projects.type.none=Nenhum
projects.type.basic_kanban=Kanban bรกsico
-projects.type.bug_triage=Triagem de Bugs
+projects.type.bug_triage=Triagem de bugs
projects.template.desc=Modelo de projeto
projects.template.desc_helper=Selecione um modelo de projeto para comeรงar
projects.type.uncategorized=Sem categoria
@@ -1405,7 +1495,7 @@ projects.column.set_default_desc=Definir esta coluna como padrรฃo para pull e is
projects.column.unset_default=Desatribuir padrรฃo
projects.column.unset_default_desc=Desatribuir esta coluna como padrรฃo
projects.column.delete=Excluir coluna
-projects.column.deletion_desc=Excluir uma coluna do projeto move todas as issues relacionadas para 'Sem categoria'. Continuar?
+projects.column.deletion_desc=Excluir uma coluna do projeto move todos os issues relacionados para a coluna padrรฃo. Continuar?
projects.column.color=Cor
projects.open=Abrir
projects.close=Fechar
@@ -1420,7 +1510,7 @@ issues.filter_milestones=Filtrar Marco
issues.filter_projects=Filtrar Projeto
issues.filter_labels=Filtrar Rรณtulo
issues.filter_reviewers=Filtrar Revisor
-issues.new=Nova issue
+issues.new=Novo issue
issues.new.title_empty=Tรญtulo nรฃo pode ser em branco
issues.new.labels=Etiquetas
issues.new.no_label=Nenhum rรณtulo
@@ -1438,7 +1528,7 @@ issues.new.open_milestone=Marcos abertos
issues.new.closed_milestone=Marcos fechados
issues.new.assignees=Responsรกveis
issues.new.clear_assignees=Limpar responsรกveis
-issues.new.no_assignees=Sem responsรกvel
+issues.new.no_assignees=Sem responsรกveis
issues.new.no_reviewers=Sem revisor
issues.choose.get_started=Primeiros passos
issues.choose.open_external_link=Abrir
@@ -1452,10 +1542,10 @@ issues.new_label=Novo rรณtulo
issues.new_label_placeholder=Nome da etiqueta
issues.new_label_desc_placeholder=Descriรงรฃo
issues.create_label=Criar rรณtulo
-issues.label_templates.title=Carregue um conjunto de etiquetas prรฉ-definidas
-issues.label_templates.info=Ainda nรฃo existem etiquetas. Crie uma etiqueta em 'Nova etiqueta' ou use um conjunto de etiquetas predefinida:
-issues.label_templates.helper=Selecione um conjunto de etiquetas
-issues.label_templates.use=Use o conjunto de etiquetas
+issues.label_templates.title=Carregue um modelo de etiquetas
+issues.label_templates.info=Ainda nรฃo existem etiquetas. Crie uma etiqueta em "Nova etiqueta" ou use um modelo etiquetas:
+issues.label_templates.helper=Selecione uma predefiniรงรฃo de etiqueta
+issues.label_templates.use=Use predefiniรงรฃo de etiqueta
issues.label_templates.fail_to_load_file=Falha ao carregar o modelo de etiquetas "%s": %v
issues.add_label=adicionou o rรณtulo %s %s
issues.add_labels=adicionou os rรณtulos %s %s
@@ -1559,8 +1649,8 @@ issues.reopened_at=`reabriu esta issue %[2]s `
issues.commit_ref_at=`citou esta issue em um commit %[2]s `
issues.ref_issue_from=`referenciado esta issue %[4]s %[2]s `
issues.ref_pull_from=`referenciado este pull request %[4]s %[2]s `
-issues.ref_closing_from=`referenciado um pull request %[4]s que fecharรก esta issue %[2]s `
-issues.ref_reopening_from=`referenciado um pull request %[4]s que reabrirรก esta issue %[2]s `
+issues.ref_closing_from=`referenciado esta issue de um pull request %[4]s que a fecharรก %[2]s `
+issues.ref_reopening_from=`referenciado esta issue de um pull request %[4]s que a reabrirรก %[2]s `
issues.ref_closed_from=`fechou esta issue %[4]s %[2]s `
issues.ref_reopened_from=`reabriu esta issue %[4]s %[2]s `
issues.ref_from=`de %[1]s`
@@ -1656,7 +1746,7 @@ issues.error_modifying_due_date=Falha ao modificar a data limite.
issues.error_removing_due_date=Falha ao remover a data limite.
issues.push_commit_1=adicionou %d commit %s
issues.push_commits_n=adicionou %d commits %s
-issues.force_push_codes=`forรงou o push %[1]s de %[2]s
para %[4]s
%[6]s`
+issues.force_push_codes=`forรงou o push %[1]s de %[2]s
para %[4]s
%[6]s`
issues.force_push_compare=Comparar
issues.due_date_form=dd/mm/aaaa
issues.due_date_form_add=Adicionar data limite
@@ -1667,13 +1757,13 @@ issues.due_date_added=adicionou a data limite %s %s
issues.due_date_modified=modificou a data limite de %[2]s para %[1]s %[3]s
issues.due_date_remove=removeu a data limite %s %s
issues.due_date_overdue=Em atraso
-issues.due_date_invalid=A data limite รฉ invรกlida ou estรก fora do intervalo. Por favor, use o formato 'dd/mm/aaaa'.
+issues.due_date_invalid=A data limite รฉ invรกlida ou estรก fora do intervalo permitido. Por favor, use o formato "yyyy-mm-dd".
issues.dependency.title=Dependรชncias
issues.dependency.issue_no_dependencies=Nรฃo hรก dependรชncias definidas.
issues.dependency.pr_no_dependencies=Nรฃo hรก dependรชncias definidas.
-issues.dependency.no_permission_1=Vocรช nรฃo tem permissรฃo para ler %d dependรชncia
-issues.dependency.no_permission_n=Vocรช nรฃo tem permissรฃo para ler %d dependรชncias
-issues.dependency.no_permission.can_remove=Vocรช nรฃo tem permissรฃo para ler esta dependรชncia, mas pode remover esta dependรชncia
+issues.dependency.no_permission_1=Vocรช nรฃo tem permissรฃo para ler a dependรชncia %d
+issues.dependency.no_permission_n=Vocรช nรฃo tem permissรฃo para ler as dependรชncias %d
+issues.dependency.no_permission.can_remove=Vocรช nรฃo tem permissรฃo para ler esta dependรชncia, mas pode removรช-la
issues.dependency.add=Adicionar dependรชnciaโฆ
issues.dependency.cancel=Cancelar
issues.dependency.remove=Remover
@@ -1685,7 +1775,7 @@ issues.dependency.issue_closing_blockedby=Fechamento desta issue estรก bloqueado
issues.dependency.issue_close_blocks=Esta issue bloqueia o fechamento das seguintes issues
issues.dependency.pr_close_blocks=Este pull request bloqueia o fechamento das seguintes issues
issues.dependency.issue_close_blocked=Vocรช precisa fechar todas as issues que bloqueiam esta issue antes de poder fechรก-la.
-issues.dependency.issue_batch_close_blocked=Nรฃo รฉ possรญvel fechar as issues que vocรช escolheu, porque a issue #%d ainda tem dependรชncias abertas
+issues.dependency.issue_batch_close_blocked=Nรฃo รฉ possรญvel fechar as issues que vocรช escolheu porque a issue #%d ainda tem dependรชncias abertas
issues.dependency.pr_close_blocked=Vocรช precisa fechar todas issues que bloqueiam este pull request antes de poder fazer o merge.
issues.dependency.blocks_short=Bloqueia
issues.dependency.blocked_by_short=Depende de
@@ -1709,8 +1799,8 @@ issues.review.left_comment=deixou um comentรกrio
issues.review.content.empty=Vocรช precisa deixar um comentรกrio indicando as alteraรงรตes solicitadas.
issues.review.reject=solicitou alteraรงรตes %s
issues.review.wait=foi solicitado(a) para revisar %s
-issues.review.add_review_request=solicitou uma revisรฃo de %s %s
-issues.review.remove_review_request=removeu a solicitaรงรฃo de revisรฃo para %s %s
+issues.review.add_review_request=solicitou revisรฃo de %[1]s %[2]s
+issues.review.remove_review_request=removeu a solicitaรงรฃo de revisรฃo para %[1]s %[2]s
issues.review.remove_review_request_self=recusou-se a revisar %s
issues.review.pending=Pendente
issues.review.pending.tooltip=Este comentรกrio nรฃo estรก atualmente visรญvel para outros usuรกrios. Para enviar seus comentรกrios pendentes, selecione "%s" -> "%s/%s/%s" no topo da pรกgina.
@@ -1742,7 +1832,7 @@ compare.compare_head=comparar
pulls.desc=Habilitar pull requests e revisรตes de cรณdigo.
pulls.new=Novo pull request
-pulls.view=Ver Pull Request
+pulls.view=Ver pull request
pulls.compare_changes=Novo pull request
pulls.allow_edits_from_maintainers=Permitir ediรงรตes de mantenedores
pulls.allow_edits_from_maintainers_desc=Usuรกrios com acesso de gravaรงรฃo para o branch base tambรฉm podem fazer push para este branch
@@ -1770,8 +1860,8 @@ pulls.nothing_to_compare=Estes branches sรฃo iguais. Nรฃo hรก nenhuma necessidad
pulls.nothing_to_compare_and_allow_empty_pr=Estes branches sรฃo iguais. Este PR ficarรก vazio.
pulls.has_pull_request=`Um pull request entre esses branches jรก existe: %[2]s#%[3]d `
pulls.create=Criar pull request
-pulls.title_desc_few=quer aplicar o merge de %[1]d commits de %[2]s
em %[3]s
-pulls.merged_title_desc_few=aplicou merge dos %[1]d commits de %[2]s
em %[3]s
%[4]s
+pulls.title_desc_few=quer mesclar %[1]d commits de %[2]s
em %[3]s
+pulls.merged_title_desc_few=mesclou %[1]d commits de %[2]s
em %[3]s
%[4]s
pulls.change_target_branch_at=`mudou o branch de destino de %s para %s %s`
pulls.tab_conversation=Conversaรงรฃo
pulls.tab_commits=Commits
@@ -1791,15 +1881,15 @@ pulls.add_prefix=Adicione o prefixo %s
pulls.remove_prefix=Remover o prefixo %s
pulls.data_broken=Este pull request estรก quebrado devido a falta de informaรงรฃo do fork.
pulls.files_conflicted=Este pull request tem alteraรงรตes conflitantes com o branch de destino.
-pulls.is_checking=Verificaรงรฃo de conflitos do merge estรก em andamento. Tente novamente em alguns momentos.
+pulls.is_checking=Verificaรงรฃo de conflitos de merge estรก em andamento. Tente novamente em alguns momentos.
pulls.is_ancestor=Este branch jรก estรก incluรญdo no branch de destino. Nรฃo hรก nada para mesclar.
-pulls.is_empty=As alteraรงรตes neste branch jรก estรฃo na branch de destino. Este serรก um commit vazio.
+pulls.is_empty=As alteraรงรตes neste branch jรก estรฃo no branch de destino. Este serรก um commit vazio.
pulls.required_status_check_failed=Algumas verificaรงรตes necessรกrias nรฃo foram bem sucedidas.
pulls.required_status_check_missing=Estรฃo faltando algumas verificaรงรตes necessรกrias.
pulls.required_status_check_administrator=Como administrador, vocรช ainda pode aplicar o merge deste pull request.
pulls.blocked_by_approvals=Este pull request ainda nรฃo tem aprovaรงรตes suficientes. %d de %d aprovaรงรตes concedidas.
pulls.blocked_by_rejection=Este pull request tem alteraรงรตes solicitadas por um revisor oficial.
-pulls.blocked_by_official_review_requests=Este pull request tem solicitaรงรตes de revisรฃo oficiais.
+pulls.blocked_by_official_review_requests=Este pull request estรก bloqueado porque falta aprovaรงรฃo de um ou mais revisores oficiais.
pulls.blocked_by_outdated_branch=Este pull request estรก bloqueado porque estรก desatualizado.
pulls.blocked_by_changed_protected_files_1=Este pull request estรก bloqueado porque altera um arquivo protegido:
pulls.blocked_by_changed_protected_files_n=Este pull request estรก bloqueado porque altera arquivos protegidos:
@@ -1833,13 +1923,13 @@ pulls.invalid_merge_option=Vocรช nรฃo pode usar esta opรงรฃo de merge neste pull
pulls.merge_conflict=O merge falhou: Houve um conflito ao fazer merge. Dica: Tente uma estratรฉgia diferente
pulls.merge_conflict_summary=Mensagem de erro
pulls.rebase_conflict=O merge falhou: Houve um conflito durante o rebase do commit %[1]s. Dica: Tente uma estratรฉgia diferente
-pulls.rebase_conflict_summary=Mensagem de Erro
-pulls.unrelated_histories=Merge falhou: O merge do principal e da base nรฃo compartilham uma histรณria comum. Dica: Tente uma estratรฉgia diferente
-pulls.merge_out_of_date=Merge falhou: durante a geraรงรฃo do merge, a base nรฃo foi atualizada. Dica: Tente novamente.
+pulls.rebase_conflict_summary=Mensagem de erro
+pulls.unrelated_histories=Merge falhou: A head do merge e da base nรฃo compartilham um histรณrico comum. Dica: Tente uma estratรฉgia diferente
+pulls.merge_out_of_date=Merge falhou: Durante a geraรงรฃo do merge, a base foi atualizada. Dica: Tente novamente.
pulls.head_out_of_date=O merge falhou: Enquanto gerava o merge, a head foi atualizada. Dica: Tente novamente.
-pulls.push_rejected=O merge falhou: O push foi rejeitado. Revise os Git Hooks para este repositรณrio.
+pulls.push_rejected=O merge falhou: O push foi rejeitado. Revise os hooks do Git para este repositรณrio.
pulls.push_rejected_summary=Mensagem completa da rejeiรงรฃo
-pulls.push_rejected_no_message=O merge falhou: O push foi rejeitado mas nรฃo houve mensagem remota. Revise os Git Hooks para este repositรณrio
+pulls.push_rejected_no_message=O push falhou: O push foi rejeitado mas nรฃo houve mensagem remota. Revise os hooks do Git para este repositรณrio
pulls.open_unmerged_pull_exists=`Nรฃo รฉ possรญvel executar uma operaรงรฃo de reabertura pois hรก um pull request pendente (#%d) com propriedades idรชnticas.`
pulls.status_checking=Algumas verificaรงรตes estรฃo pendentes
pulls.status_checks_success=Todas as verificaรงรตes foram bem sucedidas
@@ -1891,7 +1981,7 @@ milestones.title=Tรญtulo
milestones.desc=Descriรงรฃo
milestones.due_date=Data limite (opcional)
milestones.clear=Limpar
-milestones.invalid_due_date_format=Formato da data limite deve ser 'dd/mm/aaaa'.
+milestones.invalid_due_date_format=Formato da data limite deve ser "aaaa-mm-dd".
milestones.create_success=O marco "%s" foi criado.
milestones.edit=Editar marco
milestones.edit_subheader=Marcos organizam as issues e acompanham o progresso.
@@ -1910,7 +2000,7 @@ milestones.filter_sort.least_issues=Com menos issues
signing.will_sign=Esse commit serรก assinado com a chave "%s".
signing.wont_sign.error=Ocorreu um erro ao verificar se o commit poderia ser assinado.
-signing.wont_sign.nokey=Nรฃo hรก nenhuma chave disponรญvel para assinar esse commit.
+signing.wont_sign.nokey=Esta instรขncia nรฃo tem uma chave para assinar esse commit.
signing.wont_sign.never=Commits nunca sรฃo assinados.
signing.wont_sign.always=Commits sรฃo sempre assinados.
signing.wont_sign.pubkey=O commit nรฃo serรก assinado porque vocรช nรฃo tem uma chave pรบblica associada ร sua conta.
@@ -1921,7 +2011,7 @@ signing.wont_sign.commitssigned=O merge nรฃo serรก assinado, pois todos os commi
signing.wont_sign.approved=O merge nรฃo serรก assinado porque o PR nรฃo foi aprovado.
signing.wont_sign.not_signed_in=Vocรช nรฃo estรก conectado.
-ext_wiki=Acesso a Wiki Externo
+ext_wiki=Wiki Externa
ext_wiki.desc=Link para uma wiki externa.
wiki=Wiki
@@ -1940,7 +2030,7 @@ wiki.last_commit_info=%s editou esta pรกgina %s
wiki.edit_page_button=Editar
wiki.new_page_button=Nova pรกgina
wiki.file_revision=Revisรฃo de pรกgina
-wiki.wiki_page_revisions=Revisรตes de pรกgina Wiki
+wiki.wiki_page_revisions=Revisรตes da pรกgina
wiki.back_to_wiki=Voltar para pรกgina Wiki
wiki.delete_page_button=Excluir pรกgina
wiki.delete_page_notice_1=A exclusรฃo da pรกgina de wiki "%s" nรฃo pode ser desfeita. Continuar?
@@ -1948,7 +2038,7 @@ wiki.page_already_exists=Uma pรกgina de wiki com o mesmo nome jรก existe.
wiki.reserved_page=O nome da pรกgina da wiki "%s" estรก reservado.
wiki.pages=Pรกginas
wiki.last_updated=รltima atualizaรงรฃo %s
-wiki.page_name_desc=Digite um nome para esta pรกgina Wiki. Alguns nomes especiais sรฃo: 'Home', '_Sidebar' e '_Footer'.
+wiki.page_name_desc=Digite um nome para esta pรกgina Wiki. Alguns nomes especiais sรฃo: "Home", "_Sidebar" e "_Footer".
wiki.original_git_entry_tooltip=Ver o arquivo Git original em vez de usar o link amigรกvel.
activity=Atividade
@@ -1961,26 +2051,26 @@ activity.period.quarterly=3 meses
activity.period.semiyearly=6 meses
activity.period.yearly=1 ano
activity.overview=Visรฃo geral
-activity.active_prs_count_1=%d Pull request ativo
-activity.active_prs_count_n=%d Pull requests ativos
-activity.merged_prs_count_1=Pull request com merge aplicado
-activity.merged_prs_count_n=Pull requests com merge aplicado
+activity.active_prs_count_1=%d pull request ativo
+activity.active_prs_count_n=%d pull requests ativos
+activity.merged_prs_count_1=Pull request com merge concluรญdo
+activity.merged_prs_count_n=Pull requests com merge concluรญdo
activity.opened_prs_count_1=Pull request proposto
activity.opened_prs_count_n=Pull requests propostos
activity.title.user_1=%d usuรกrio
activity.title.user_n=%d usuรกrios
-activity.title.prs_1=%d Pull request
-activity.title.prs_n=%d Pull requests
+activity.title.prs_1=%d pull request
+activity.title.prs_n=%d pull requests
activity.title.prs_merged_by=%s com merge aplicado por %s
activity.title.prs_opened_by=%s proposto(s) por %s
activity.merged_prs_label=Merge aplicado
activity.opened_prs_label=Proposto
-activity.active_issues_count_1=%d Issue ativa
-activity.active_issues_count_n=%d Issues ativas
+activity.active_issues_count_1=%d issue ativa
+activity.active_issues_count_n=%d issues ativas
activity.closed_issues_count_1=Issue fechada
activity.closed_issues_count_n=Issues fechadas
-activity.title.issues_1=+%d Issue
-activity.title.issues_n=+%d Issues
+activity.title.issues_1=%d issue
+activity.title.issues_n=%d issues
activity.title.issues_closed_from=%s fechada por %s
activity.title.issues_created_by=%s criada por %s
activity.closed_issue_label=Fechado
@@ -1991,10 +2081,10 @@ activity.title.unresolved_conv_1=%d conversa nรฃo resolvida
activity.title.unresolved_conv_n=%d conversas nรฃo resolvidas
activity.unresolved_conv_desc=Estas issues foram recentemente alteradas e pull requests ainda nรฃo foram resolvidos.
activity.unresolved_conv_label=Aberta
-activity.title.releases_1=%d Versรฃo
-activity.title.releases_n=%d Versรตes
+activity.title.releases_1=%d release
+activity.title.releases_n=%d releases
activity.title.releases_published_by=%s publicada(s) por %s
-activity.published_release_label=Publicado
+activity.published_release_label=Release
activity.no_git_activity=Nรฃo houve nenhuma atividade de commit neste perรญodo.
activity.git_stats_exclude_merges=Excluindo merges,
activity.git_stats_author_1=%d autor
@@ -2017,8 +2107,7 @@ activity.git_stats_and_deletions=e
activity.git_stats_deletion_1=%d exclusรฃo
activity.git_stats_deletion_n=%d exclusรตes
-contributors.contribution_type.commits=Commits
-
+contributors.contribution_type.commits = Commits
search=Pesquisar
search.search_repo=Pesquisar no repositรณrio...
search.type.tooltip=Tipo de pesquisa
@@ -2053,22 +2142,22 @@ settings.mirror_settings.direction.pull=Pull
settings.mirror_settings.direction.push=Push
settings.mirror_settings.last_update=รltima atualizaรงรฃo
settings.mirror_settings.push_mirror.none=Nenhum espelhamento de push configurado
-settings.mirror_settings.push_mirror.remote_url=URL do repositรณrio do Git remoto
-settings.mirror_settings.push_mirror.add=Adicionar Espelho de Push
+settings.mirror_settings.push_mirror.remote_url=URL do repositรณrio Git remoto
+settings.mirror_settings.push_mirror.add=Adicionar espelho de push
settings.mirror_settings.push_mirror.edit_sync_time=Editar intervalo de sincronizaรงรฃo de espelhos
settings.sync_mirror=Sincronizar agora
settings.site=Site
-settings.update_settings=Atualizar configuraรงรตes
-settings.update_mirror_settings=Atualizar espelho
-settings.branches.switch_default_branch=Alterar
-settings.branches.update_default_branch=Atualizar Branch Padrรฃo
-settings.branches.add_new_rule=Adicionar Nova Regra
+settings.update_settings=Salvar configuraรงรตes
+settings.update_mirror_settings=Atualizar configuraรงรตes do espelho
+settings.branches.switch_default_branch=Alterar branch padrรฃo
+settings.branches.update_default_branch=Atualizar branch padrรฃo
+settings.branches.add_new_rule=Adicionar nova regra
settings.advanced_settings=Configuraรงรตes avanรงadas
settings.wiki_desc=Habilitar a wiki do repositรณrio
settings.use_internal_wiki=Usar a wiki nativa
settings.use_external_wiki=Usar wiki externa
-settings.external_wiki_url=URL externa da wiki
+settings.external_wiki_url=URL da wiki externa
settings.external_wiki_url_error=A URL da wiki externa nรฃo รฉ vรกlida.
settings.external_wiki_url_desc=Visitantes sรฃo redirecionados para a URL da wiki externa ao clicar na aba da wiki.
settings.issues_desc=Habilitar issue tracker para o repositรณrio
@@ -2086,40 +2175,40 @@ settings.tracker_issue_style.regexp=Expressรฃo Regular
settings.tracker_issue_style.regexp_pattern=Padrรฃo de expressรฃo regular
settings.tracker_issue_style.regexp_pattern_desc=O primeiro grupo capturado serรก usado no lugar de {index}
.
settings.tracker_url_format_desc=Use os espaรงos reservados {user}
, {repo}
e {index}
para o nome de usuรกrio, nome do repositรณrio e o รญndice de problemas.
-settings.enable_timetracker=Habilitar Cronรดmetro
-settings.allow_only_contributors_to_track_time=Permitir que apenas os colaboradores acompanhem o contador de tempo
+settings.enable_timetracker=Habilitar estatรญsticas de tempo
+settings.allow_only_contributors_to_track_time=Permitir que apenas os colaboradores usem estatรญsticas de tempo
settings.pulls_desc=Habilitar pull requests no repositรณrio
settings.pulls.ignore_whitespace=Ignorar espaรงo em branco em conflitos
settings.pulls.enable_autodetect_manual_merge=Habilitar a detecรงรฃo automรกtica de merge manual (Nota: Em alguns casos especiais, podem ocorrer julgamentos errados)
settings.pulls.allow_rebase_update=Ativar atualizaรงรฃo do branch do pull request por rebase
settings.pulls.default_delete_branch_after_merge=Excluir o branch de pull request apรณs o merge por padrรฃo
settings.pulls.default_allow_edits_from_maintainers=Permitir ediรงรตes de mantenedores por padrรฃo
-settings.releases_desc=Habilitar versรตes do Repositรณrio
-settings.packages_desc=Habilitar Registro de Pacotes de Repositรณrio
-settings.projects_desc=Habilitar Projetos do Repositรณrio
-settings.actions_desc=Habilitar aรงรตes do repositรณrio
-settings.admin_settings=Configuraรงรตes do administrador
+settings.releases_desc=Habilitar releases no repositรณrio
+settings.packages_desc=Habilitar registro de pacotes do repositรณrio
+settings.projects_desc=Habilitar projetos do repositรณrio
+settings.actions_desc=Habilitar pipelines integradas de CI/CD com Forgejo Actions
+settings.admin_settings=Configuraรงรตes de administrador
settings.admin_enable_health_check=Habilitar verificaรงรตes de integridade (git fsck) no repositรณrio
settings.admin_code_indexer=Indexador de cรณdigo
-settings.admin_stats_indexer=Indexador de Estatรญsticas do Cรณdigo
-settings.admin_indexer_commit_sha=รltimo SHA indexado
+settings.admin_stats_indexer=Indexador de estatรญsticas de cรณdigo
+settings.admin_indexer_commit_sha=รltimo commit indexado
settings.admin_indexer_unindexed=Nรฃo indexado
settings.reindex_button=Adicionar ร fila de reindexaรงรฃo
-settings.reindex_requested=Reindexaรงรฃo requisitada
+settings.reindex_requested=Reindexaรงรฃo solicitada
settings.admin_enable_close_issues_via_commit_in_any_branch=Fechar issue via commit em um branch nรฃo padrรฃo
settings.danger_zone=Zona de perigo
settings.new_owner_has_same_repo=O novo proprietรกrio jรก tem um repositรณrio com o mesmo nome. Por favor, escolha outro nome.
-settings.convert=Converter para repositรณrio tradicional
+settings.convert=Converter para repositรณrio comum
settings.convert_desc=Vocรช pode converter este espelhamento em um repositรณrio tradicional. Esta aรงรฃo nรฃo pode ser revertida.
settings.convert_notices_1=Esta operaรงรฃo vai converter este espelhamento em um repositรณrio tradicional. Esta aรงรฃo nรฃo pode ser desfeita.
-settings.convert_confirm=Converter o repositรณrio
+settings.convert_confirm=Converter repositรณrio
settings.convert_succeed=O espelhamento foi convertido em um repositรณrio tradicional.
-settings.convert_fork=Converter Para Um Repositรณrio Normal
+settings.convert_fork=Converter para um repositรณrio comum
settings.convert_fork_desc=Vocรช pode converter este fork em um repositรณrio normal. Esta aรงรฃo nรฃo pode ser desfeita.
settings.convert_fork_notices_1=Esta operaรงรฃo irรก converter o fork em um repositรณrio normal e nรฃo pode ser desfeita.
settings.convert_fork_confirm=Converter repositรณrio
settings.convert_fork_succeed=O fork foi convertido em um repositรณrio normal.
-settings.transfer.title=Transferir propriedade
+settings.transfer.title=Transferir titularidade
settings.transfer.rejected=A transferรชncia do repositรณrio foi rejeitada.
settings.transfer.success=A transferรชncia do repositรณrio foi bem sucedida.
settings.transfer_abort=Cancelar transferรชncia
@@ -2131,12 +2220,12 @@ settings.transfer_notices_1=- Vocรช perderรก o acesso ao repositรณrio se transfe
settings.transfer_notices_2=- Vocรช manterรก acesso ao repositรณrio se transferi-lo para uma organizaรงรฃo que vocรช tambรฉm รฉ proprietรกrio.
settings.transfer_notices_3=- Se o repositรณrio for privado e for transferido para um usuรกrio individual, esta aรงรฃo certifica que o usuรกrio tem pelo menos permissรฃo de leitura (e altera as permissรตes se necessรกrio).
settings.transfer_owner=Novo proprietรกrio
-settings.transfer_perform=Executar Transferรชncia
+settings.transfer_perform=Executar transferรชncia
settings.transfer_started=`Este repositรณrio foi marcado para transferรชncia e aguarda a confirmaรงรฃo de "%s"`
settings.transfer_succeed=O repositรณrio foi transferido.
-settings.signing_settings=Configuraรงรตes de Verificaรงรฃo de Assinatura
-settings.trust_model=Modelo de Confianรงa na Assinatura
-settings.trust_model.default=Modelo Padrรฃo de Confianรงa
+settings.signing_settings=Configuraรงรตes de verificaรงรฃo de assinatura
+settings.trust_model=Modelo de confianรงa para assinaturas
+settings.trust_model.default=Modelo padrรฃo de confianรงa
settings.trust_model.default.desc=Use o modelo de confianรงa de repositรณrio padrรฃo para esta instalaรงรฃo.
settings.trust_model.collaborator=Colaborador
settings.trust_model.collaborator.long=Colaborador: Confiar em assinaturas feitas por colaboradores
@@ -2173,7 +2262,7 @@ settings.org_not_allowed_to_be_collaborator=Organizaรงรตes nรฃo podem ser adicio
settings.change_team_access_not_allowed=Alteraรงรฃo do acesso da equipe para o repositรณrio estรก restrito ao proprietรกrio da organizaรงรฃo
settings.team_not_in_organization=A equipe nรฃo estรก na mesma organizaรงรฃo que o repositรณrio
settings.teams=Equipes
-settings.add_team=Adicionar Equipe
+settings.add_team=Adicionar equipe
settings.add_team_duplicate=A equipe jรก tem o repositรณrio
settings.add_team_success=A equipe agora tem acesso ao repositรณrio.
settings.search_team=Pesquisar Equipeโฆ
@@ -2197,10 +2286,10 @@ settings.webhook.replay.description=Executar novamente esse webhook.
settings.webhook.delivery.success=Um evento foi adicionado ร fila de envio. Pode levar alguns segundos atรฉ que ele apareรงa no histรณrico de envio.
settings.githooks_desc=Hooks do Git sรฃo executados pelo prรณprio Git. Vocรช pode editar arquivos de hook abaixo para configurar operaรงรตes personalizadas.
settings.githook_edit_desc=Se o hook nรฃo estiver ativo, o conteรบdo de exemplo serรก apresentado. Deixar o conteรบdo em branco irรก desabilitar esse hook.
-settings.githook_name=Nome do Hook
-settings.githook_content=Conteรบdo do Hook
-settings.update_githook=Atualizar Hook
-settings.add_webhook_desc=Forgejo enviarรก requisiรงรตes POST
com um tipo de conteรบdo especificado para a URL de destino. Leia mais no guia de webhooks .
+settings.githook_name=Nome do hook
+settings.githook_content=Conteรบdo do hook
+settings.update_githook=Atualizar hook
+settings.add_webhook_desc=Forgejo enviarรก requisiรงรตes POST
com um Content-Type especificado para a URL de destino. Leia mais no guia de webhooks .
settings.payload_url=URL de destino
settings.http_method=Mรฉtodo HTTP
settings.content_type=Tipo de conteรบdo POST
@@ -2210,11 +2299,11 @@ settings.slack_icon_url=URL do รญcone
settings.slack_color=Cor
settings.discord_username=Nome de usuรกrio
settings.discord_icon_url=URL do รญcone
-settings.event_desc=Acionado em:
+settings.event_desc=Acionar em:
settings.event_push_only=Eventos de push
settings.event_send_everything=Todos os eventos
-settings.event_choose=Eventos personalizados...
-settings.event_header_repository=Eventos do Repositรณrio
+settings.event_choose=Eventos personalizadosโฆ
+settings.event_header_repository=Eventos do repositรณrio
settings.event_create=Criar
settings.event_create_desc=Branch ou tag criado.
settings.event_delete=Excluir
@@ -2229,37 +2318,37 @@ settings.event_push=Push
settings.event_push_desc=Git push para o repositรณrio.
settings.event_repository=Repositรณrio
settings.event_repository_desc=Repositรณrio criado ou excluรญdo.
-settings.event_header_issue=Eventos da Issue
-settings.event_issues=Issues
+settings.event_header_issue=Eventos de issues
+settings.event_issues=Modificaรงรฃo
settings.event_issues_desc=Issue aberta, fechada, reaberta ou editada.
-settings.event_issue_assign=Issue Atribuรญda
+settings.event_issue_assign=Atribuiรงรฃo
settings.event_issue_assign_desc=Issue atribuรญda ou nรฃo atribuรญda.
-settings.event_issue_label=Issue Rotulada
-settings.event_issue_label_desc=Rรณtulos da issue atualizados ou removidos.
-settings.event_issue_milestone=Marco Atribuรญdo ร Issue
-settings.event_issue_milestone_desc=Marco atribuรญdo ou desatribuรญdo ร Issue.
-settings.event_issue_comment=Comentรกrio da issue
+settings.event_issue_label=Rรณtulos
+settings.event_issue_label_desc=Rรณtulos da issue adicionados ou removidos.
+settings.event_issue_milestone=Marcos
+settings.event_issue_milestone_desc=Marco adicionado, removido ou modificado.
+settings.event_issue_comment=Comentรกrios
settings.event_issue_comment_desc=Comentรกrio da issue criado, editado ou excluรญdo.
-settings.event_header_pull_request=Eventos de Pull Request
-settings.event_pull_request=Pull request
+settings.event_header_pull_request=Eventos de pull request
+settings.event_pull_request=Modificaรงรฃo
settings.event_pull_request_desc=Pull request aberto, fechado, reaberto ou editado.
-settings.event_pull_request_assign=Pull Request Atribuรญdo
+settings.event_pull_request_assign=Atribuiรงรฃo
settings.event_pull_request_assign_desc=Pull request atribuรญdo ou desatribuรญdo.
-settings.event_pull_request_label=Pull Request Rotulado
-settings.event_pull_request_label_desc=Rรณtulos do pull request atualizados ou limpos.
-settings.event_pull_request_milestone=Marco Atribuรญdo ao Pull Request
-settings.event_pull_request_milestone_desc=Marco atribuรญdo ou desatribuรญdo ao pull request.
-settings.event_pull_request_comment=Comentรกrio no Pull Request
+settings.event_pull_request_label=Rรณtulos
+settings.event_pull_request_label_desc=Rรณtulos do pull request adicionados ou removidos.
+settings.event_pull_request_milestone=Marcos
+settings.event_pull_request_milestone_desc=Marco adicionado, removido ou modificado.
+settings.event_pull_request_comment=Comentรกrios
settings.event_pull_request_comment_desc=Comentรกrio criado, editado ou excluรญdo no pull request.
-settings.event_pull_request_review=Pull Request Revisado
-settings.event_pull_request_review_desc=Pull request aprovado, rejeitado ou revisรฃo comentada.
-settings.event_pull_request_sync=Pull Request Sincronizado
-settings.event_pull_request_sync_desc=Pull request sincronizado.
+settings.event_pull_request_review=Revisรตes
+settings.event_pull_request_review_desc=Pull request aprovado, rejeitado ou comentรกrios de revisรฃo adicionados.
+settings.event_pull_request_sync=Sincronizado
+settings.event_pull_request_sync_desc=Branch atualizado automaticamente com o branch alvo.
settings.event_package=Pacote
settings.event_package_desc=Pacote criado ou excluรญdo em um repositรณrio.
settings.branch_filter=Filtro de branch
-settings.branch_filter_desc=Lista dos branches a serem considerados nos eventos push, criaรงรฃo de branch e exclusรฃo de branch, especificados como padrรฃo glob. Se estiver vazio ou for *
, eventos para todos os branches serรฃo relatados. Veja github.com/gobwas/glob documentaรงรฃo da sintaxe. Exemplos: master
, {master,release*}
.
-settings.authorization_header=Header de Autorizaรงรฃo
+settings.branch_filter_desc=Lista dos branches a serem considerados nos eventos push, criaรงรฃo de branch e exclusรฃo de branch, especificados como padrรฃo glob. Se estiver vazio ou for *
, eventos para todos os branches serรฃo relatados. Veja %[2]s documentaรงรฃo da sintaxe. Exemplos: master
, {master,release*}
.
+settings.authorization_header=Cabeรงalho de autorizaรงรฃo
settings.authorization_header_desc=Serรก incluรญdo como header de autorizaรงรฃo para solicitaรงรตes quando estiver presente. Exemplos: %s.
settings.active=Ativo
settings.active_helper=Informaรงรตes sobre eventos disparados serรฃo enviadas para esta URL do webhook.
@@ -2267,8 +2356,8 @@ settings.add_hook_success=O webhook foi adicionado.
settings.update_webhook=Atualizar webhook
settings.update_hook_success=O webhook foi atualizado.
settings.delete_webhook=Remover webhook
-settings.recent_deliveries=Entregas Recentes
-settings.hook_type=Tipo de Hook
+settings.recent_deliveries=Entregas recentes
+settings.hook_type=Tipo de hook
settings.slack_token=Token
settings.slack_domain=Domรญnio
settings.slack_channel=Canal
@@ -2290,8 +2379,8 @@ settings.web_hook_name_packagist=Packagist
settings.packagist_username=Nome de usuรกrio no Packagist
settings.packagist_api_token=Token de API
settings.packagist_package_url=URL do pacote do Packagist
-settings.deploy_keys=Chaves de Deploy
-settings.add_deploy_key=Nova chave
+settings.deploy_keys=Chaves de deploy
+settings.add_deploy_key=Adicionar chave de deploy
settings.deploy_key_desc=As chaves de deploy possuem somente acesso de leitura (pull) ao repositรณrio.
settings.is_writable=Habilitar acesso de escrita
settings.is_writable_info=Permitir que esta chave de deploy faรงa push para o repositรณrio.
@@ -2304,13 +2393,13 @@ settings.deploy_key_deletion=Remover chave de deploy
settings.deploy_key_deletion_desc=A exclusรฃo de uma chave de deploy irรก revogar o seu acesso a este repositรณrio. Continuar?
settings.deploy_key_deletion_success=A chave de deploy foi removida.
settings.branches=Branches
-settings.protected_branch=Proteรงรฃo de Branch
-settings.protected_branch.save_rule=Salvar Regra
-settings.protected_branch.delete_rule=Excluir Regra
+settings.protected_branch=Proteรงรฃo de branch
+settings.protected_branch.save_rule=Salvar regra
+settings.protected_branch.delete_rule=Excluir regra
settings.protected_branch_can_push=Permitir push?
settings.protected_branch_can_push_yes=Vocรช pode fazer push
settings.protected_branch_can_push_no=Vocรช nรฃo pode fazer push
-settings.branch_protection=Proteรงรฃo de Branch para '%s '
+settings.branch_protection=Regras de proteรงรฃo do branch "%s "
settings.protect_this_branch=Habilitar Proteรงรฃo de Branch
settings.protect_this_branch_desc=Previne a exclusรฃo e restringe o merge e push para o branch.
settings.protect_disable_push=Desabilitar push
@@ -2318,42 +2407,42 @@ settings.protect_disable_push_desc=Nenhum push serรก permitido neste branch.
settings.protect_enable_push=Habilitar push
settings.protect_enable_push_desc=Qualquer pessoa com acesso de escrita terรก permissรฃo para realizar push neste branch (mas nรฃo forรงar o push).
settings.protect_enable_merge=Permitir merge
-settings.protect_whitelist_committers=Lista permitida para push
+settings.protect_whitelist_committers=Push restrito ร lista de permissรฃo
settings.protect_whitelist_committers_desc=Somente usuรกrios ou equipes da lista permitida serรฃo autorizados realizar push neste branch (mas nรฃo forรงar o push).
settings.protect_whitelist_deploy_keys=Dar permissรฃo ร s chaves de deploy com acesso de gravaรงรฃo para push.
-settings.protect_whitelist_users=Usuรกrios com permissรฃo para realizar push:
+settings.protect_whitelist_users=Usuรกrios com permissรฃo para realizar push
settings.protect_whitelist_search_users=Pesquisar usuรกrios...
-settings.protect_whitelist_teams=Equipes com permissรฃo para realizar push:
+settings.protect_whitelist_teams=Equipes com permissรฃo para realizar push
settings.protect_whitelist_search_teams=Pesquisar equipes...
-settings.protect_merge_whitelist_committers=Habilitar controle de permissรฃo de merge
+settings.protect_merge_whitelist_committers=Habilitar lista de permissรฃo de merge
settings.protect_merge_whitelist_committers_desc=Permitir que determinados usuรกrios ou equipes possam aplicar merge de pull requests neste branch.
-settings.protect_merge_whitelist_users=Usuรกrios com permissรฃo para aplicar merge:
-settings.protect_merge_whitelist_teams=Equipes com permissรฃo para aplicar merge:
+settings.protect_merge_whitelist_users=Usuรกrios com permissรฃo para fazer merge
+settings.protect_merge_whitelist_teams=Equipes com permissรฃo para fazer merge
settings.protect_check_status_contexts=Habilitar verificaรงรฃo de status
settings.protect_check_status_contexts_desc=Exigir que as verificaรงรตes de status passem antes de fazer merge. Escolha quais verificaรงรตes de status devem passar antes que os branches possam ter o merge aplicado em um branch que corresponda a esta regra. Quando habilitado, os commits devem primeiro ser enviados para outro branch, entรฃo faรงa merge ou push diretamente para um branch que corresponde a esta regra apรณs a verificaรงรฃo de status ter passado. Se nenhum contexto for selecionado, o รบltimo commit deve ser bem sucedido, independentemente do contexto.
settings.protect_check_status_contexts_list=Verificaรงรตes de status encontradas na รบltima semana para este repositรณrio
-settings.protect_required_approvals=Aprovaรงรตes necessรกrias:
+settings.protect_required_approvals=Aprovaรงรตes necessรกrias
settings.protect_required_approvals_desc=Permite apenas realizar merge do pull request com avaliaรงรตes positivas suficientes.
settings.protect_approvals_whitelist_enabled=Restringir aprovaรงรตes a usuรกrios ou equipes da lista permitida
settings.protect_approvals_whitelist_enabled_desc=Somente as avaliaรงรตes de usuรกrios ou equipes da lista permitida serรฃo contadas com as aprovaรงรตes necessรกrias. Sem aprovaรงรฃo da lista permitida, as revisรตes de qualquer pessoa com acesso de escrita contam para as aprovaรงรตes necessรกrias.
-settings.protect_approvals_whitelist_users=Usuรกrios com permissรฃo de revisรฃo:
-settings.protect_approvals_whitelist_teams=Equipes com permissรฃo de revisรฃo:
+settings.protect_approvals_whitelist_users=Usuรกrios com permissรฃo de fazer revisรตes
+settings.protect_approvals_whitelist_teams=Equipes com permissรฃo de fazer revisรตes
settings.dismiss_stale_approvals=Descartar aprovaรงรตes obsoletas
settings.dismiss_stale_approvals_desc=Quando novos commits que mudam o conteรบdo do pull request sรฃo enviados para o branch, as antigas aprovaรงรตes serรฃo descartadas.
-settings.require_signed_commits=Exibir commits assinados
+settings.require_signed_commits=Exigir commits assinados
settings.require_signed_commits_desc=Rejeitar pushes para este branch se nรฃo estiverem assinados ou nรฃo forem validรกveis.
-settings.protect_branch_name_pattern=Padrรฃo de Nome de Branch Protegida
+settings.protect_branch_name_pattern=Padrรฃo de nome de branch protegido
settings.protect_patterns=Padrรตes
-settings.protect_protected_file_patterns=Padrรตes de arquivos protegidos (separados usando ponto e vรญrgula ';'):
-settings.protect_protected_file_patterns_desc=Arquivos protegidos nรฃo podem ser alterados diretamente, mesmo que o usuรกrio tenha direitos para adicionar, editar ou excluir arquivos neste branch. Vรกrios padrรตes podem ser separados usando ponto e vรญrgula (';'). Consulte a documentaรงรฃo github.com/gobwas/glob para a sintaxe padrรฃo. Exemplos: .drone.yml
, /docs/**/*.txt
.
-settings.protect_unprotected_file_patterns=Padrรตes de arquivos desprotegidos (separados usando ponto e vรญrgula ';'):
-settings.protect_unprotected_file_patterns_desc=Arquivos nรฃo protegidos que podem ser alterados diretamente se o usuรกrio tiver acesso de gravaรงรฃo, ignorando as restriรงรตes de push. Vรกrios padrรตes podem ser separados usando ponto e vรญrgula (\;'). Veja github.com/gobwas/glob documentaรงรฃo para sintaxe de padrรตes. Exemplos: .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns=Padrรตes de arquivo protegidos (separados usando ponto e vรญrgula ";")
+settings.protect_protected_file_patterns_desc=Arquivos protegidos nรฃo podem ser alterados diretamente, mesmo que o usuรกrio tenha direitos para adicionar, editar ou excluir arquivos neste branch. Vรกrios padrรตes podem ser separados usando ponto e vรญrgula (';'). Consulte a documentaรงรฃo %[2]s para a sintaxe padrรฃo. Exemplos: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns=Padrรตes de arquivo desprotegidos (separados usando ponto e vรญrgula ";")
+settings.protect_unprotected_file_patterns_desc=Arquivos nรฃo protegidos que podem ser alterados diretamente se o usuรกrio tiver acesso de gravaรงรฃo, ignorando as restriรงรตes de push. Vรกrios padrรตes podem ser separados usando ponto e vรญrgula (\;'). Veja %[2]s documentaรงรฃo para sintaxe de padrรตes. Exemplos: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=Habilitar proteรงรฃo
settings.delete_protected_branch=Desabilitar proteรงรฃo
settings.update_protect_branch_success=Proteรงรฃo do branch "%s" foi atualizada.
settings.remove_protected_branch_success=Proteรงรฃo do branch "%s" foi desabilitada.
settings.remove_protected_branch_failed=Removendo regra de proteรงรฃo de branch "%s" falhou.
-settings.protected_branch_deletion=Desabilitar proteรงรฃo de branch
+settings.protected_branch_deletion=Remover proteรงรฃo de branch
settings.protected_branch_deletion_desc=Desabilitar a proteรงรฃo de branch permite que os usuรกrios com permissรฃo de escrita realizem push. Continuar?
settings.block_rejected_reviews=Bloquear merge em revisรตes rejeitadas
settings.block_rejected_reviews_desc=O merge nรฃo serรก possรญvel quando sรฃo solicitadas alteraรงรตes pelos revisores oficiais, mesmo que haja aprovaรงรฃo suficiente.
@@ -2362,35 +2451,35 @@ settings.block_on_official_review_requests_desc=O merge nรฃo serรก possรญvel qua
settings.block_outdated_branch=Bloquear o merge se o pull request estiver desatualizado
settings.block_outdated_branch_desc=O merge nรฃo serรก possรญvel quando o branch de topo estiver atrรกs do branch base.
settings.default_branch_desc=Selecione um branch padrรฃo para pull requests e commits de cรณdigo:
-settings.merge_style_desc=Estilos de Merge
-settings.default_merge_style_desc=Estilo de merge padrรฃo para pull requests:
+settings.merge_style_desc=Estilos de merge
+settings.default_merge_style_desc=Estilo de merge padrรฃo
settings.choose_branch=Escolha um branch...
settings.no_protected_branch=Nรฃo hรก branches protegidos.
settings.edit_protected_branch=Editar
settings.protected_branch_required_rule_name=Nome da regra รฉ obrigatรณrio
-settings.protected_branch_duplicate_rule_name=Regra com nome duplicado
+settings.protected_branch_duplicate_rule_name=Jรก existe uma regra para este conjunto de branches
settings.protected_branch_required_approvals_min=Aprovaรงรตes necessรกrias nรฃo podem ser negativas.
settings.tags=Tags
-settings.tags.protection=Proteรงรฃo das Tags
-settings.tags.protection.pattern=Padrรฃo de Tag
+settings.tags.protection=Proteรงรฃo de tags
+settings.tags.protection.pattern=Padrรฃo de tag
settings.tags.protection.allowed=Permitido
settings.tags.protection.allowed.users=Usuรกrios permitidos
settings.tags.protection.allowed.teams=Equipes permitidas
settings.tags.protection.allowed.noone=Ninguรฉm
-settings.tags.protection.create=Proteger tag
+settings.tags.protection.create=Adicionar regra
settings.tags.protection.none=Nรฃo hรก tags protegidas.
-settings.bot_token=Token do Bot
+settings.bot_token=Token do bot
settings.chat_id=ID do Chat
settings.matrix.homeserver_url=URL do Homeserver
settings.matrix.room_id=ID da Sala
-settings.matrix.message_type=Tipo de Mensagem
+settings.matrix.message_type=Tipo de mensagem
settings.archive.button=Arquivar repositรณrio
settings.archive.header=Arquivar este repositรณrio
settings.archive.success=O repositรณrio foi arquivado com sucesso.
settings.archive.error=Um erro ocorreu enquanto estava sendo arquivado o repositรณrio. Veja o log para mais detalhes.
settings.archive.error_ismirror=Vocรช nรฃo pode arquivar um repositรณrio espelhado.
-settings.archive.branchsettings_unavailable=Configuraรงรตes do branch nรฃo estรฃo disponรญveis quando o repositรณrio estรก arquivado.
-settings.archive.tagsettings_unavailable=As configuraรงรตes de tag nรฃo estรฃo disponรญveis se o repositรณrio estiver arquivado.
+settings.archive.branchsettings_unavailable=Configuraรงรตes de branch nรฃo estรฃo disponรญveis em repositรณrios arquivados.
+settings.archive.tagsettings_unavailable=Configuraรงรตes de tag nรฃo estรฃo disponรญveis em repositรณrios arquivados.
settings.update_avatar_success=O avatar do repositรณrio foi atualizado.
settings.lfs=LFS
settings.lfs_filelist=Arquivos LFS armazenados neste repositรณrio
@@ -2399,23 +2488,23 @@ settings.lfs_findcommits=Encontrar commits
settings.lfs_lfs_file_no_commits=Nenhum commit encontrado para este arquivo LFS
settings.lfs_noattribute=Este caminho nรฃo possui atributo bloqueรกvel no branch padrรฃo
settings.lfs_delete=Excluir arquivo LFS com OID %s
-settings.lfs_delete_warning=A exclusรฃo de um arquivo LFS pode causar erros do tipo 'o objeto nรฃo existe' no checkout. Vocรช tem certeza?
+settings.lfs_delete_warning=A exclusรฃo de um arquivo LFS pode causar erros do tipo "o objeto nรฃo existe" ao fazer checkout. Vocรช tem certeza?
settings.lfs_findpointerfiles=Encontre arquivos de ponteiro
settings.lfs_locks=Bloqueios
settings.lfs_invalid_locking_path=Caminho invรกlido: %s
settings.lfs_invalid_lock_directory=Nรฃo รฉ possรญvel bloquear o diretรณrio: %s
settings.lfs_lock_already_exists=O bloqueio jรก existe: %s
settings.lfs_lock=Bloqueio
-settings.lfs_lock_path=Caminho de arquivo para bloquear...
+settings.lfs_lock_path=Caminho de arquivo para travarโฆ
settings.lfs_locks_no_locks=Sem bloqueios
settings.lfs_lock_file_no_exist=Arquivo bloqueado nรฃo existe no branch padrรฃo
settings.lfs_force_unlock=Forรงar desbloqueio
settings.lfs_pointers.found=Encontrado %d ponteiro(s) de blob - %d associado, %d nรฃo associado (%d ausente na loja)
-settings.lfs_pointers.sha=SHA Blob
+settings.lfs_pointers.sha=Hash do blob
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=No repositรณrio
settings.lfs_pointers.exists=Existe na loja
-settings.lfs_pointers.accessible=Acessรญvel ao Usuรกrio
+settings.lfs_pointers.accessible=Acessรญvel ao usuรกrio
settings.lfs_pointers.associateAccessible=Associar %d OIDs acessรญveis
settings.rename_branch_failed_exist=Nรฃo รฉ possรญvel renomear o branch porque existe o branch %s.
settings.rename_branch_failed_not_exist=Nรฃo รฉ possรญvel renomear o branch %s porque ele nรฃo existe.
@@ -2428,11 +2517,11 @@ diff.browse_source=Ver cรณdigo fonte
diff.parent=pai
diff.commit=commit
diff.git-notes=Notas
-diff.data_not_available=Conteรบdo de diff nรฃo disponรญvel
-diff.options_button=Opรงรตes de diferenรงas
+diff.data_not_available=O conteรบdo do diff nรฃo estรก disponรญvel
+diff.options_button=Opรงรตes de visualizaรงรฃo de diferenรงas
diff.show_diff_stats=Mostrar estatรญsticas
-diff.download_patch=Baixar arquivo de patch
-diff.download_diff=Baixar arquivo de diferenรงas
+diff.download_patch=Baixar arquivo patch
+diff.download_diff=Baixar arquivo diff
diff.show_split_view=Visรฃo dividida
diff.show_unified_view=Visรฃo unificada
diff.whitespace_button=Espaรงo em branco
@@ -2458,12 +2547,12 @@ diff.load=Carregar Diff
diff.generated=gerado
diff.vendored=externo
diff.comment.placeholder=Deixe um comentรกrio
-diff.comment.markdown_info=Estilo com markdown รฉ suportado.
+diff.comment.markdown_info=Estilo com Markdown รฉ suportado.
diff.comment.add_single_comment=Adicionar um รบnico comentรกrio
diff.comment.add_review_comment=Adicionar comentรกrio
diff.comment.start_review=Iniciar revisรฃo
diff.comment.reply=Responder
-diff.review=Revisรฃo
+diff.review=Finalizar revisรฃo
diff.review.header=Enviar revisรฃo
diff.review.placeholder=Comentรกrio da revisรฃo
diff.review.comment=Comentar
@@ -2484,12 +2573,12 @@ releases.desc=Acompanhe as versรตes e downloads do projeto.
release.releases=Versรตes
release.detail=Detalhes da versรฃo
release.tags=Tags
-release.new_release=Nova versรฃo
+release.new_release=Nova release
release.draft=Rascunho
-release.prerelease=Versรฃo prรฉvia
+release.prerelease=Prรฉ-release
release.stable=Estรกvel
release.compare=Comparar
-release.edit=editar
+release.edit=Editar
release.ahead.commits=%d commits
release.ahead.target=para %s desde esta versรฃo
tag.ahead.target=para %s desde esta tag
@@ -2504,15 +2593,15 @@ release.tag_helper_existing=Tag existente.
release.title=Tรญtulo da versรฃo
release.title_empty=O tรญtulo nรฃo pode estar em branco.
release.message=Descreva esta versรฃo
-release.prerelease_desc=Marcar como prรฉ-lanรงamento
+release.prerelease_desc=Marcar como prรฉ-release
release.prerelease_helper=Marcar esta versรฃo como inadequada para uso em produรงรฃo.
release.cancel=Cancelar
-release.publish=Publicar versรฃo
+release.publish=Publicar release
release.save_draft=Salvar rascunho
-release.edit_release=Atualizar versรฃo
-release.delete_release=Excluir versรฃo
-release.delete_tag=Apagar Tag
-release.deletion=Excluir versรฃo
+release.edit_release=Atualizar release
+release.delete_release=Excluir release
+release.delete_tag=Excluir tag
+release.deletion=Excluir release
release.deletion_success=A versรฃo foi excluรญda.
release.deletion_tag_desc=A tag serรก excluรญda do repositรณrio. Conteรบdo do repositรณrio e histรณrico permanecerรฃo inalterados. Continuar?
release.deletion_tag_success=A tag foi excluรญda.
@@ -2523,19 +2612,19 @@ release.tag_already_exist=Este nome de tag jรก existe.
release.downloads=Downloads
release.download_count=Downloads: %s
release.add_tag_msg=Use o tรญtulo e o conteรบdo do lanรงamento como mensagem da tag.
-release.add_tag=Criar apenas a tag
+release.add_tag=Criar tag
release.releases_for=Versรตes para %s
release.tags_for=Tags para %s
-branch.name=Nome do Branch
+branch.name=Nome do branch
branch.already_exists=Um branch com o nome "%s" jรก existe.
branch.delete_head=Excluir
-branch.delete=`Excluir branch "%s"`
-branch.delete_html=Excluir Branch
+branch.delete=Excluir branch "%s"
+branch.delete_html=Excluir branch
branch.deletion_success=Branch "%s" excluรญdo.
branch.deletion_failed=Falha ao excluir o branch "%s".
branch.delete_branch_has_new_commits=O branch "%s" nรฃo pode ser excluรญdo porque novos commits foram feitos apรณs o merge.
-branch.create_branch=Criar branch %s
+branch.create_branch=Criar branch %s
branch.create_from=`a partir de "%s"`
branch.create_success=Branch "%s" criado.
branch.branch_already_exists=Branch "%s" jรก existe neste repositรณrio.
@@ -2544,9 +2633,9 @@ branch.restore_success=Branch "%s" restaurado.
branch.restore_failed=Ocorreu um erro ao restaurar o branch "%s".
branch.protected_deletion_failed=Branch "%s" รฉ protegido. Ele nรฃo pode ser excluรญdo.
branch.default_deletion_failed=Branch "%s" รฉ o branch padrรฃo. Ele nรฃo pode ser excluรญdo.
-branch.restore=`Restaurar branch "%s"`
-branch.download=`Baixar branch "%s"`
-branch.rename=`Renomear branch "%s"`
+branch.restore=Restaurar branch "%s"
+branch.download=Baixar branch "%s"
+branch.rename=Renomear branch "%s"
branch.included_desc=Este branch faz parte do branch padrรฃo
branch.included=Incluรญdo
branch.create_new_branch=Criar branch a partir do branch:
@@ -2559,18 +2648,18 @@ branch.new_branch=Criar novo branch
branch.new_branch_from=`Criar novo branch a partir de "%s"`
branch.renamed=Branch %s foi renomeado para %s.
-tag.create_tag=Criar tag %s
+tag.create_tag=Criar tag %s
tag.create_tag_operation=Criar tag
tag.confirm_create_tag=Criar tag
tag.create_tag_from=`Criar nova tag a partir de "%s"`
tag.create_success=Tag "%s" criada.
-topic.manage_topics=Gerenciar Tรณpicos
+topic.manage_topics=Gerenciar tรณpicos
topic.done=Feito
topic.count_prompt=Vocรช nรฃo pode selecionar mais de 25 tรณpicos
-find_file.go_to_file=Ir para arquivo
+find_file.go_to_file=Encontrar um arquivo
find_file.no_matching=Nenhum arquivo correspondente encontrado
error.csv.too_large=Nรฃo รฉ possรญvel renderizar este arquivo porque ele รฉ muito grande.
@@ -2584,26 +2673,26 @@ issues.role.collaborator = Colaborador(a)
issues.label_archived_filter = Mostrar etiquetas arquivadas
pulls.status_checks_hide_all = Esconder todas as verificaรงรตes
pulls.status_checks_show_all = Mostrar todas as verificaรงรตes
-pulls.cmd_instruction_hint = `Ver as instruรงรตes da linha de comando .`
+pulls.cmd_instruction_hint = Ver instruรงรตes de linha de comando
wiki.cancel = Cancelar
settings.unarchive.success = O repositรณrio foi desarquivado.
settings.unarchive.button = Desarquivar repositรณrio
settings.unarchive.header = Desarquivar este repositรณrio
diff.comment.add_line_comment = Adicionar comentรกrio na linha
-new_repo_helper = Um repositรณrio contรฉm todos os arquivos de projeto, incluindo o histรณrico de revisรตes. Jรก hospeda um repositรณrio em outra plataforma? Migrar repositรณrio
+new_repo_helper = Um repositรณrio contรฉm todos os arquivos de projeto, incluindo o histรณrico de revisรตes. Jรก hospeda um repositรณrio em outra plataforma? Migrar repositรณrio .
blame.ignore_revs.failed = Falha ao ignorar as revisรตes em .git-blame-ignore-revs .
-migrate.forgejo.description = Migrar dados do codeberg.org ou outras instรขncias Forgejo.
+migrate.forgejo.description = Migrar dados do codeberg.org ou outras servidores Forgejo.
commits.browse_further = Ver mais
issues.role.first_time_contributor = Primeira vez contribuindo
issues.role.first_time_contributor_helper = Esta รฉ a primeira contribuiรงรฃo deste usuรกrio para o repositรณrio.
issues.role.contributor = Contribuidor(a)
issues.role.member_helper = Este usuรกrio รฉ membro da organizaรงรฃo proprietรกria deste repositรณrio.
-issues.role.collaborator_helper = Este usuรกrio foi convidado para colaborar neste repositรณrio.
+issues.role.collaborator_helper = Este(a) usuรกrio(a) foi convidado(a) para colaborar neste repositรณrio.
pulls.cmd_instruction_checkout_title = Checkout
-settings.wiki_globally_editable = Permitir que qualquer pessoa possa editar a wiki
+settings.wiki_globally_editable = Permitir que qualquer pessoa edite a wiki
settings.transfer_abort_success = A transferรชncia de repositรณrio para %s foi cancelada.
settings.enter_repo_name = Digite os nomes do dono e do repositรณrio exatamente neste formato:
-issues.blocked_by_user = Vocรช nรฃo pode criar uma questรฃo neste repositรณrio porque vocรช foi bloqueado pelo dono do repositรณrio.
+issues.blocked_by_user = Vocรช nรฃo pode criar issues neste repositรณrio porque vocรช foi bloqueado pelo dono do repositรณrio.
settings.new_owner_blocked_doer = Vocรช foi bloqueado pelo novo dono do repositรณrio.
settings.wiki_rename_branch_main_notices_1 = NรO ร POSSรVEL desfazer esta aรงรฃo.
tree_path_not_found_commit = O caminho %[1]s nรฃo existe no commit %[2]s
@@ -2612,12 +2701,12 @@ admin.manage_flags = Gerenciar sinalizadores
admin.enabled_flags = Sinalizadores habilitados para o repositรณrio:
admin.update_flags = Atualizar sinalizadores
admin.flags_replaced = Os sinalizadores do repositรณrio foram substituรญdos
-all_branches = Todas as branches
+all_branches = Todos os ramos
fork_branch = Branch a ser clonada para o fork
-object_format_helper = O formato utilizado para armazenar os objetos do repositรณrio, sendo SHA1 o mais compatรญvel. Esta aรงรฃo รฉ IRREVERSรVEL .
+object_format_helper = O formato utilizado para armazenar os objetos do repositรณrio. Nรฃo pode ser alterado depois. SHA1 รฉ o mais compatรญvel.
object_format = Formato dos objetos
-tree_path_not_found_branch = Caminho %[1]s nรฃo existe na branch %[2]s
-tree_path_not_found_tag = Caminho %[1]s nรฃo existe na etiqueta %[2]s
+tree_path_not_found_branch = O caminho %[1]s nรฃo existe no ramo %[2]s
+tree_path_not_found_tag = O caminho %[1]s nรฃo existe na etiqueta %[2]s
commits.view_path = Ver neste ponto do histรณrico
commits.renamed_from = Renomeado de %s
admin.failed_to_replace_flags = Falha ao substituir os sinalizadores do repositรณrio
@@ -2626,20 +2715,19 @@ issues.role.contributor_helper = Este usuรกrio fez commits para o repositรณrio a
issues.choose.invalid_config = A configuraรงรฃo de issue contรฉm erros:
pulls.made_using_agit = AGit
contributors.contribution_type.filter_label = Tipo de contribuiรงรฃo:
-contributors.contribution_type.commits = Commits
settings.webhook.test_delivery_desc_disabled = Ative este webhook para testรก-lo com um evento simulado.
activity.navbar.contributors = Contribuidores
issues.label_archive_tooltip = Etiquetas arquivadas nรฃo serรฃo exibidas nas sugestรตes de pesquisa de etiquetas.
activity.navbar.pulse = Recente
settings.units.overview = Geral
-settings.units.add_more = Adicionar mais...
+settings.units.add_more = Habilitar mais
pulls.commit_ref_at = `referenciou este pedido de mesclagem no commit %[2]s `
pulls.cmd_instruction_merge_title = Mesclar
-settings.units.units = Funcionalidades
+settings.units.units = Unidades
vendored = Externo
issues.num_participants_one = %d participante
issues.archived_label_description = (arquivada) %s
-n_branch_few = %s branches
+n_branch_few = %s ramos
stars = Favoritos
n_commit_one = %s commit
n_tag_few = %s etiquetas
@@ -2648,7 +2736,7 @@ settings.confirm_wiki_branch_rename = Renomar o ramo da wiki
pulls.merged_title_desc_one = mesclou %[1]d commit de %[2]s
em %[3]s
%[4]s
activity.navbar.recent_commits = Commits recentes
size_format = %[1]s: %[2]s; %[3]s: %[4]s
-pulls.title_desc_one = quer mesclar %[1]d commit de %[2]s
em %[3]s
+pulls.title_desc_one = quer mesclar %[1]d commit de %[2]s
em %[3]s
pulls.cmd_instruction_merge_desc = Mescle as alteraรงรตes e enviar para o Forgejo.
pulls.ready_for_review = Pronto para revisรฃo?
commits.search_branch = Este ramo
@@ -2676,11 +2764,11 @@ comments.edit.already_changed = Falha ao salvar as alteraรงรตes ao comentรกrio.
activity.navbar.code_frequency = Frequรชncia de cรณdigo
settings.protect_status_check_matched = Correspondente
branch.tag_collision = O ramo "%s" nรฃo pode ser criado porque jรก existe uma etiqueta com o mesmo nome no repositรณrio.
-settings.archive.mirrors_unavailable = As rรฉplicas ficarรฃo indisponรญveis se o repositรณrio estiver arquivado.
+settings.archive.mirrors_unavailable = Rรฉplicas nรฃo estรฃo disponรญveis em repositรณrios arquivados.
release.download_count_one = %s download
settings.mirror_settings.docs.no_new_mirrors = O seu repositรณrio estรก replicando alteraรงรตes de ou para outro repositรณrio. Observe que nรฃo รฉ possรญvel criar novas rรฉplicas no momento.
settings.mirror_settings.docs.pull_mirror_instructions = Para configurar uma rรฉplica de outro repositรณrio, consulte:
-settings.wiki_rename_branch_main_desc = Renomear o ramo usado internamente pela wiki para "%s". Esta aรงรฃo รฉ IRREVERSรVEL .
+settings.wiki_rename_branch_main_desc = Renomear o branch usado internamente pela Wiki para "%s". Esta aรงรฃo รฉ permanente e nรฃo pode ser desfeita.
settings.enforce_on_admins = Impor esta regra aos administradores de repositรณrios
settings.enforce_on_admins_desc = Administradores de repositรณrio nรฃo podem burlar esta regra.
subscribe.issue.guest.tooltip = Faรงa login para receber notificaรงรตes desta questรฃo
@@ -2695,14 +2783,142 @@ release.system_generated = Este anexo foi gerado automaticamente.
settings.wiki_branch_rename_failure = Falha ao regularizar o nome do ramo da wiki do repositรณrio.
settings.add_collaborator_blocked_them = Nรฃo foi possรญvel adicionar o(a) colaborador(a) porque ele(a) bloqueou o(a) proprietรกrio(a) do repositรณrio.
settings.thread_id = ID da discussรฃo
-issues.edit.already_changed = Nรฃo foi possรญvel salvar as alteraรงรตes desta questรฃo porque o conteรบdo foi alterado por outro(a) usuรกrio(a). Atualize a pรกgina e tente novamente para evitar sobrescrever as alteraรงรตes.
-pulls.edit.already_changed = Nรฃo foi possรญvel salvar as alteraรงรตes deste pedido de integraรงรฃo porque o conteรบdo foi alterado por outro(a) usuรกrio(a). Atualize a pรกgina e tente novamente para evitar sobrescrever as alteraรงรตes.
+issues.edit.already_changed = Nรฃo foi possรญvel salvar as alteraรงรตes desta questรฃo. O conteรบdo parece jรก ter sido alterado por outro(a) usuรกrio(a). Atualize a pรกgina e tente novamente para evitar sobrescrever estas alteraรงรตes.
+pulls.edit.already_changed = Nรฃo foi possรญvel salvar as alteraรงรตes deste pull request. Parece que o conteรบdo jรก foi alterado por outro(a) usuรกrio(a). Atualize a pรกgina e tente novamente para evitar sobrescrever estas alteraรงรตes.
editor.commit_id_not_matching = O arquivo foi alterado durante a ediรงรฃo. Salve as alteraรงรตes em um novo ramo e realize a mesclagem.
blame.ignore_revs = As revisรตes em .git-blame-ignore-revs foram ignoradas. Clique aqui para retornar ร visualizaรงรฃo normal.
topic.format_prompt = Os tรณpicos devem comeรงar com um caracter alfanumรฉrico, podem incluir hรญfens ("-") e pontos ("."), e podem ter atรฉ 35 caracteres. As letras devem ser minรบsculas.
settings.rename_branch_failed_protected = Nรฃo foi possรญvel renomar o ramo %s porque ele estรก protegido.
+milestones.filter_sort.name = Nome
+activity.published_prerelease_label = Prรฉ-lanรงamento
+activity.published_tag_label = Etiqueta
+issues.author.tooltip.issue = Este(a) usuรกrio(a) รฉ o(a) autor(a) desta questรฃo.
+no_eol.text = Sem EOL
+no_eol.tooltip = Nรฃo hรก um caractere de fim de linha no final do arquivo.
+pulls.fast_forward_only_merge_pull_request = Apenas fast-forward
+pulls.has_merged = Falha: O pull request foi merged, vocรช nรฃo pode merge novamente ou mudar o branch destino.
+issues.author.tooltip.pr = Esse usuรกrio รฉ o autor dessa solicitaรงรฃo de pull.
+editor.push_out_of_date = O push parece estar desatualizado.
+issues.comment.blocked_by_user = Vocรช nรฃo pode comentar neste issue porque vocรช foi bloqueado pelo dono do repositรณrio ou pelo autor deste issue.
+pulls.blocked_by_user = Vocรช nรฃo pode criar uma solicitaรงรฃo de pull nesse repositรณrio porque vocรช estรก bloqueado pelo dono do repositรณrio.
+mirror_use_ssh.helper = Forgejo irรก espelhar o repositรณrio via Git atravรฉs de SSH e criar um par de chaves para vocรช ao escolher essa opรงรฃo. Vocรช deverรก garantir que a chave pรบblica gerada estรก autorizada a fazer push para o repositรณrio de destino. Vocรช nรฃo pode usar autorizaรงรฃo baseada em senha ao escolher essa opรงรฃo.
+mirror_denied_combination = Nรฃo รฉ possรญvel combinar o uso de chave pรบblica e autenticaรงรฃo baseada em senha.
+mirror_public_key = Chave SSH pรบblica
+mirror_use_ssh.text = Usar autenticaรงรฃo por SSH
+mirror_use_ssh.not_available = Autenticaรงรฃo por SSH nรฃo estรก disponรญvel.
+settings.push_mirror_sync_in_progress = Fazendo push das mudanรงas para o remoto %s nesse momento.
+settings.federation_apapiurl = URL de federaรงรฃo deste repositรณrio. Copie e cole isso nas Configuraรงรตes de Federaรงรฃo de outro repositรณrio como uma URL de um Repositรณrio Seguidor.
+pulls.agit_explanation = Criado usando o fluxo de trabalho AGit. AGit permite que contribuidores proponham mudanรงas usando "git push" sem criar um fork ou novo branch.
+signing.wont_sign.headsigned = O merge nรฃo serรก assinado pois o commit head nรฃo estรก assinado.
+settings.mirror_settings.push_mirror.copy_public_key = Copiar chave pรบblica
+settings.pull_mirror_sync_in_progress = Fazendo pull das mudanรงas do remoto %s nesse momento.
+pulls.reopen_failed.head_branch = O pull request nรฃo pode ser reaberto porque o branch head nรฃo existe mais.
+pulls.cmd_instruction_checkout_desc = Do repositรณrio do seu projeto, faรงa checkout de um novo branch e teste as alteraรงรตes.
+settings.mirror_settings.docs.pulling_remote_title = Fazendo pull de um repositรณrio remoto
+settings.mirror_settings.pushed_repository = Repositรณrio enviado
+settings.mirror_settings.docs.disabled_pull_mirror.instructions = Configure seu projeto para automaticamente fazer push de commits, tags e branches para outro repositรณrio. Espelhos de pull foram desativados pelo administrador do seu site.
+settings.mirror_settings.docs.disabled_push_mirror.instructions = Configure seu projeto para automaticamente fazer pull de commits, tags e branches de outro repositรณrio.
+settings.mirror_settings.docs.doc_link_pull_section = a seรงรฃo "Fazendo pull de um repositรณrio remoto" da documentaรงรฃo.
+subscribe.pull.guest.tooltip = Entre para receber notificaรงรตes deste pull request.
+settings.pull_mirror_sync_quota_exceeded = Cota excedida, nรฃo serรก feito pull das mudanรงas.
+settings.mirror_settings.docs.more_information_if_disabled = Saiba mais sobre espelhos de push e pull aqui:
+settings.transfer_quota_exceeded = O novo dono (%s) excedeu a cota. O repositรณrio nรฃo foi transferido.
+pulls.reopen_failed.base_branch = O pull request nรฃo pode ser reaberto porque o branch base nรฃo existe mais.
+activity.commit = Atividade de commits
+pulls.cmd_instruction_merge_warning = Atenรงรฃo: A opรงรฃo "Autodetectar merge manual" nรฃo estรก habilitada para este repositรณrio, vocรช terรก que marcar este pull request como um merge manual depois.
+settings.federation_following_repos = URLs de Repositรณrios Seguidores. Separado por ";", sem espaรงos.
+settings.mirror_settings.docs.disabled_push_mirror.info = Espelhos de pull foram desativados pelo administrador do seu site.
+settings.mirror_settings.push_mirror.none_ssh = Nenhum
+settings.protect_status_check_patterns_desc = Insira padrรตes para especificar quais verificaรงรตes de status devem passar com sucesso antes que merges possam ser feitos em branches aos quais esta regra se aplica. Cada linha especifica um padrรฃo. Padrรตes nรฃo podem estar vazios.
+settings.archive.text = Arquivar o repositรณrio irรก tornรก-lo totalmente "somente leitura". Ele ficarรก oculto do painel. Ninguรฉm (nem mesmo vocรช!) poderรก fazer novos commits, ou abrir quaisquer issues ou pull requests.
+settings.add_key_success = A chave de deploy "%s" foi adicionada.
+settings.protect_invalid_status_check_pattern = Padrรฃo de verificaรงรฃo de status invรกlido: "%s".
+settings.web_hook_name_sourcehut_builds = Builds do SourceHut
+settings.protect_new_rule = Criar uma nova regra de proteรงรฃo de branch
+settings.wiki_rename_branch_main_notices_2 = Isso irรก renomear permanentemente o branch interno da wiki do repositรณrio %s. Checkouts existentes precisarรฃo ser atualizados.
+settings.protect_enable_merge_desc = Qualquer pessoa com permissรฃo de escrita terรก autorizaรงรฃo para fazer merge dos pull requests neste ramo.
+settings.protect_no_valid_status_check_patterns = Nรฃo hรก padrรตes de verificaรงรฃo de status vรกlidos.
+settings.event_pull_request_approvals = Aprovaรงรตes de pull request
+settings.event_pull_request_enforcement = Aplicaรงรฃo
+settings.ignore_stale_approvals = Ignorar aprovaรงรตes inativas
+settings.update_settings_no_unit = O repositรณrio deve permitir pelo menos algum tipo de interaรงรฃo.
+settings.protect_branch_name_pattern_desc = Padrรตes de nome de branch protegidos. Ver sintaxe de padrรตes na documentaรงรฃo . Exemplos: main, release/**
+settings.webhook.replay.description_disabled = Para executar novamente este webhook, ative-o.
+settings.sourcehut_builds.manifest_path = Caminho do manifest de build
+settings.sourcehut_builds.secrets_helper = Dar a este job acesso aos segredos de build (requer a permissรฃo SECRETS:RO)
+settings.sourcehut_builds.access_token_helper = Token de acesso tem a permissรฃo JOBS:RW. Gere um token builds.sr.ht ou um token builds.sr.ht com acesso a segredos em meta.sr.ht.
+settings.matrix.room_id_helper = O ID da sala pode ser obtido do cliente web Element > Configuraรงรตes da Sala > Avanรงado > ID interno da sala. Exemplo: %s.
+settings.unarchive.error = Ocorreu um erro ao tentar desarquivar o repositรณrio. Veja o log para mais detalhes.
+settings.event_pull_request_review_request = Pedidos de revisรฃo
+settings.event_pull_request_review_request_desc = Revisรฃo de pull request solicitada ou pedido de revisรฃo removido.
+settings.event_pull_request_merge = Merge de pull request
+settings.matrix.access_token_helper = ร recomendado configurar uma conta Matrix dedicada para isso. O token de acesso pode ser obtido do cliente web Element (em uma aba privada/anรดnima) > Menu do usuรกrio (acima ร esquerda) > Todas as configuraรงรตes > Ajuda & Sobre > Avanรงado > Token de acesso (logo abaixo da URL do servidor). Feche a aba privada/anรดnima (sair da conta irรก invalidar o token).
+settings.tags.protection.pattern.description = Vocรช pode usar um รบnico nome, um padrรฃo glob ou uma expressรฃo regular para corresponder a vรกrias tags. Saiba mais no guia de tags protegidas .
+settings.add_webhook.invalid_path = O caminho nรฃo deve conter partes que sejam "." ou ".." ou uma string vazia. Ele nรฃo pode comeรงar ou terminar com uma barra.
+settings.sourcehut_builds.visibility = Visibilidade do job
+settings.unarchive.text = Desarquivar o repositรณrio irรก restaurar a possibilidade de receber commits e push, bem como novos issues e pull requests.
+settings.ignore_stale_approvals_desc = Nรฃo contar aprovaรงรตes feitas em commits mais antigos (revisรตes inativas) no nรบmero de aprovaรงรตes de pedidos de merge. Nรฃo tem efeito se as revisรตes inativas jรก sรฃo desconsideradas.
+settings.protect_status_check_patterns = Padrรตes de verificaรงรฃo de status
+error.broken_git_hook = Os hooks Git desse repositรณrio parecem estar quebrados. Por favor, siga a documentaรงรฃo para corrigi-los e entรฃo faรงa push de alguns commits para atualizar o status.
+release.type_attachment = Anexo
+release.type_external_asset = Recurso externo
+release.asset_name = Nome do recurso
+release.asset_external_url = URL Externa
+release.hide_archive_links_helper = Esconder automaticamente arquivos de cรณdigo fonte gerados para esse release. Por exemplo, se vocรช estiver enviando os seus manualmente.
+branch.delete_desc = Apagar um branch รฉ permanente. Ainda que o branch apagado possa continuar a existir por um breve perรญodo antes de ser realmente apagado, isso NรO PODE ser desfeito na maioria dos casos. Continuar?
+release.add_external_asset = Adicionar componente externo
+release.invalid_external_url = URL externo invรกlido: "%s"
+release.deletion_desc = Eliminar um release apenas o remove do Forgejo. Isso nรฃo irรก afetar a tag no Git, o conteรบdo do seu repositรณrio ou o histรณrico. Continuar?
+issues.all_title = Tudo
+issues.new.assign_to_me = Designar a mim
+settings.discord_icon_url.exceeds_max_length = A URL do รญcone precisa ter 2048 caracteres ou menos
+issues.review.add_review_requests = solicitou revisรตes de %[1]s %[2]s
+issues.review.remove_review_requests = removeu pedidos de revisรฃo para %[1]s %[2]s
+issues.review.add_remove_review_requests = solicitou revisรตes de %[1]s e removeu pedidos de revisรฃo para %[2]s %[3]s
+pulls.delete_after_merge.head_branch.is_default = O branch head que vocรช quer excluir รฉ o branch padrรฃo e nรฃo pode ser excluรญdo.
+pulls.delete_after_merge.head_branch.is_protected = O branch head que vocรช quer excluir รฉ um branch protegido e nรฃo pode ser excluรญdo.
+pulls.delete_after_merge.head_branch.insufficient_branch = Vocรช nรฃo tem permissรฃo para excluir o branch head.
+issues.filter_sort.relevance = Relevรขncia
+diff.git-notes.add = Adicionar anotaรงรฃo
+diff.git-notes.remove-header = Remover anotaรงรฃo
+diff.git-notes.remove-body = Esta anotaรงรฃo serรก removida.
+issues.num_reviews_one = %d revisรฃo
+issues.summary_card_alt = Cartรฃo de resumo de um issue com o tรญtulo "%s" no repositรณrio %s
+issues.num_reviews_few = %d revisรตes
+settings.default_update_style_desc = Estilo padrรฃo de atualizaรงรฃo usado para atualizar pull requests que estรฃo atrasados em relaรงรฃo ao branch base.
+pulls.sign_in_require = Entre para criar um novo pull request.
+new_from_template = Use um modelo
+new_from_template_description = Vocรช pode selecionar um modelo de repositรณrio nesta instรขncia e aplicar suas configuraรงรตes.
+new_advanced = Configuraรงรตes avanรงadas
+new_advanced_expand = Clique para expandir
+auto_init_description = Inicializar o histรณrico do Git com um README e opcionalmente adicionar arquivos License e .gitignore.
+issues.reaction.alt_remove = Remover reaรงรฃo %[1]s deste comentรกrio.
+issues.reaction.alt_add = Adicionar reaรงรฃo %[1]s ao comentรกrio.
+issues.context.menu = Menu de comentรกrio
+issues.reaction.add = Adicionar reaรงรฃo
+issues.reaction.alt_few = %[1]s reagiu com %[2]s.
+issues.reaction.alt_many = %[1]s e mais %[2]d reagiram com %[3]s.
+summary_card_alt = Cartรฃo de resumo do repositรณrio %s
+release.summary_card_alt = Cartรฃo de resumo de um release intitulado "%s" no repositรณrio %s
+archive.pull.noreview = Este repositรณrio estรก arquivado. Nรฃo รฉ possรญvel revisar pull requests.
+editor.commit_email = Email de commit
+commits.view_single_diff = Ver modificaรงรตes neste arquivo introduzidas neste commit
+pulls.editable = Editรกvel
+pulls.editable_explanation = Este pull request permite ediรงรตes de mantenedores. Voรงรช pode contribuir diretamenta para ele.
+issues.reopen.blocked_by_user = Vocรช nรฃo pode reabrir este issue porque vocรช foi bloqueado pelo dono do repositรณrio ou pelo criador deste issue.
+pulls.comment.blocked_by_user = Vocรช nรฃo pode comentar neste pull request porque vocรช foi bloqueado pelo dono do repositรณrio ou pelo autor do pull request.
+issues.filter_no_results = Nenhum resultado
+issues.filter_no_results_placeholder = Tente ajustar seus filtros de pesquisa.
[graphs]
+component_loading = Carregando %sโฆ
+component_loading_failed = Nรฃo foi possรญvel carregar o(a) %s
+component_loading_info = Pode demorar um poucoโฆ
+contributors.what = contribuiรงรตes
+code_frequency.what = frequรชncia de cรณdigo
+recent_commits.what = commits recentes
+component_failed_to_load = Ocorreu um erro inesperado.
+
[org]
org_name_holder=Nome da organizaรงรฃo
@@ -2724,7 +2940,7 @@ team_name_helper=Nomes de equipe devem ser curtos e memorรกveis.
team_desc_helper=Descreva a finalidade ou o papel da equipe.
team_access_desc=Acesso ao repositรณrio
team_permission_desc=Permissรฃo
-team_unit_desc=Permitir o acesso a seรงรตes de repositรณrio
+team_unit_desc=Permitir acesso a seรงรตes do repositรณrio
team_unit_disabled=(Desabilitado)
form.name_reserved=O nome de organizaรงรฃo "%s" estรก reservado.
@@ -2739,12 +2955,12 @@ settings.permission=Permissรตes
settings.repoadminchangeteam=O administrador do repositรณrio pode adicionar e remover o acesso para equipes
settings.visibility=Visibilidade
settings.visibility.public=Pรบblica
-settings.visibility.limited=Limitado (Visรญvel apenas para usuรกrios autenticados)
+settings.visibility.limited=Limitado (visรญvel apenas para usuรกrios autenticados)
settings.visibility.limited_shortname=Limitado
-settings.visibility.private=Privada (Visรญvel apenas para membros da organizaรงรฃo)
+settings.visibility.private=Privada (visรญvel apenas para membros da organizaรงรฃo)
settings.visibility.private_shortname=Privado
-settings.update_settings=Atualizar Configuraรงรตes
+settings.update_settings=Atualizar configuraรงรตes
settings.update_setting_success=Configuraรงรตes da organizaรงรฃo foram atualizadas.
settings.change_orgname_redirect_prompt=O nome antigo irรก redirecionar atรฉ que seja reivindicado.
settings.update_avatar_success=O avatar da organizaรงรฃo foi atualizado.
@@ -2758,29 +2974,29 @@ settings.hooks_desc=Adicionar Webhooks que serรฃo acionados para todos o
settings.labels_desc=Adicionar rรณtulos que possam ser usadas em issues para todos os repositรณrios desta organizaรงรฃo.
-members.membership_visibility=Visibilidade da associaรงรฃo:
+members.membership_visibility=Visibilidade de membros:
members.public=Pรบblico
-members.public_helper=tornar privado
+members.public_helper=Tornar privado
members.private=Privado
-members.private_helper=tornar pรบblico
-members.member_role=Categoria de membro:
+members.private_helper=Tornar pรบblico
+members.member_role=Papel do membro:
members.owner=Proprietรกrio
members.member=Membro
members.remove=Remover
members.remove.detail=Remover %[1]s de %[2]s?
members.leave=Sair
-members.leave.detail=Sair de %s?
+members.leave.detail=Vocรช tem certeza que quer sair da organizaรงรฃo "%s"?
members.invite_desc=Adicionar novo membro em %s:
members.invite_now=Convidar agora
teams.join=Juntar-se
teams.leave=Deixar
-teams.leave.detail=Sair de %s?
+teams.leave.detail=Vocรช tem certeza que quer sair da equipe "%s"?
teams.can_create_org_repo=Criar repositรณrios
teams.can_create_org_repo_helper=Membros podem criar novos repositรณrios na organizaรงรฃo. O criador terรก acesso administrativo ao novo repositรณrio.
-teams.none_access=Sem Acesso
-teams.none_access_helper=Os membros nรฃo podem ver ou fazer qualquer outra aรงรฃo nesta unidade.
-teams.general_access=Acesso Geral
+teams.none_access=Sem acesso
+teams.none_access_helper=A opรงรฃo "sem acesso" sรณ tem efeito em repositรณrios privados.
+teams.general_access=Acesso personalizado
teams.general_access_helper=As permissรตes dos membros serรฃo decididas pela tabela de permissรตes abaixo.
teams.read_access=Leitura
teams.read_access_helper=Os membros podem ver e clonar os repositรณrios da equipe.
@@ -2802,7 +3018,7 @@ teams.delete_team_desc=A exclusรฃo de uma equipe revoga o acesso ao repositรณrio
teams.delete_team_success=A equipe foi excluรญda.
teams.read_permission_desc=Essa equipe concede acesso para Leitura : membros podem ver e clonar os repositรณrios da equipe.
teams.write_permission_desc=Esta equipe concede acesso para escrita : Membros podem ler e fazer push para os repositรณrios da equipe.
-teams.admin_permission_desc=Esta equipe concede acesso de Administrador : Membros podem ler, fazer push e adicionar outros colaboradores para os repositรณrios da equipe.
+teams.admin_permission_desc=Esta equipe concede acesso de Administrador : membros podem ler, fazer push e adicionar outros colaboradores em repositรณrios da equipe.
teams.create_repo_permission_desc=Alรฉm disso, esta equipe concede permissรฃo de Criar repositรณrio : membros podem criar novos repositรณrios na organizaรงรฃo.
teams.repositories=Repositรณrios da equipe
teams.search_repo_placeholder=Pesquisar repositรณrio...
@@ -2810,7 +3026,7 @@ teams.remove_all_repos_title=Remover todos os repositรณrios da equipe
teams.remove_all_repos_desc=Isto irรก remover todos os repositรณrios da equipe.
teams.add_all_repos_title=Adicionar todos os repositรณrios
teams.add_all_repos_desc=Isto irรก adicionar todos os repositรณrios da organizaรงรฃo ร equipe.
-teams.add_nonexistent_repo=O repositรณrio que vocรช estรก tentando adicionar nรฃo existe. Crie-o antes de adicionรก-lo.
+teams.add_nonexistent_repo=O repositรณrio que vocรช estรก tentando adicionar nรฃo existe, por favor crie-o primeiro.
teams.add_duplicate_users=Usuรกrio jรก รฉ um membro da equipe.
teams.repos.none=Nenhum repositรณrio pode ser acessado por essa equipe.
teams.members.none=Nenhum membro nesta equipe.
@@ -2829,6 +3045,8 @@ open_dashboard = Abrir painel
settings.change_orgname_prompt = Obs.: Alterar o nome de uma organizaรงรฃo resultarรก na alteraรงรฃo do URL dela e disponibilizarรก o nome antigo para uso.
follow_blocked_user = Nรฃo foi possรญvel seguir esta organizaรงรฃo porque ela bloqueou-o(a).
form.name_pattern_not_allowed = O padrรฃo "%s" nรฃo รฉ permitido no nome de uma organizaรงรฃo.
+settings.change_orgname_redirect_prompt.with_cooldown.one = O nome de organizaรงรฃo antigo ficarรก disponรญvel para qualquer pessoa apรณs um perรญodo de proteรงรฃo de %[1]d dia, vocรช ainda pode recuperar o nome antigo durante este perรญodo de proteรงรฃo.
+settings.change_orgname_redirect_prompt.with_cooldown.few = O nome de organizaรงรฃo antigo ficarรก disponรญvel para qualquer pessoa apรณs um perรญodo de espera de %[1]d dia, vocรช ainda pode recuperar o nome antigo durante este perรญodo de espera.
[admin]
dashboard=Painel
@@ -2838,7 +3056,7 @@ repositories=Repositรณrios
hooks=Webhooks
integrations=Integraรงรตes
authentication=Fontes de autenticaรงรฃo
-emails=E-mails do Usuรกrio
+emails=E-mails do usuรกrio
config=Configuraรงรฃo
notices=Avisos do sistema
monitor=Monitoramento
@@ -2846,7 +3064,7 @@ first_page=Primeira
last_page=รltima
total=Total: %d
-dashboard.new_version_hint=Uma nova versรฃo estรก disponรญvel: %s. Versรฃo atual: %s. Visite o blog para mais informaรงรตes.
+dashboard.new_version_hint=Uma nova versรฃo estรก disponรญvel: %s. Versรฃo atual: %s. Visite o blog para mais informaรงรตes.
dashboard.statistic=Resumo
dashboard.operations=Operaรงรตes de manutenรงรฃo
dashboard.system_status=Status do sistema
@@ -2871,62 +3089,62 @@ dashboard.delete_repo_archives.started=A tarefa de remover todos os arquivos foi
dashboard.delete_missing_repos=Excluir todos os repositรณrios que nรฃo possuem seus arquivos Git
dashboard.delete_missing_repos.started=Foi iniciada a tarefa de excluir todos os repositรณrios que nรฃo tรชm arquivos Git.
dashboard.delete_generated_repository_avatars=Excluir avatares gerados do repositรณrio
-dashboard.update_mirrors=Atualizar espelhamentos
+dashboard.update_mirrors=Atualizar espelhos
dashboard.repo_health_check=Verificar estado de saรบde de todos os repositรณrios
dashboard.check_repo_stats=Verificar estatรญsticas de todos os repositรณrios
dashboard.archive_cleanup=Apagar arquivos antigos de repositรณrio
dashboard.deleted_branches_cleanup=Realizar limpeza de branches apagados
dashboard.update_migration_poster_id=Sincronizar os IDs do remetente da migraรงรฃo
dashboard.git_gc_repos=Coleta de lixo em todos os repositรณrios
-dashboard.resync_all_sshkeys=Atualizar o arquivo '.ssh/authorized_keys' com as chaves SSH do Forgejo.
-dashboard.resync_all_sshprincipals=Atualizar o arquivo '.ssh/authorized_principals' com os diretores do Forgejo SSH.
-dashboard.resync_all_hooks=Ressincronizar hooks pre-receive, update e post-receive de todos os repositรณrios.
+dashboard.resync_all_sshkeys=Atualizar o arquivo ".ssh/authorized_keys" com as chaves SSH do Forgejo.
+dashboard.resync_all_sshprincipals=Atualizar o arquivo ".ssh/authorized_principals" com os principals SSH do Forgejo.
+dashboard.resync_all_hooks=Ressincronizar hooks pre-receive, update e post-receive de todos os repositรณrios
dashboard.reinit_missing_repos=Reinicializar todos os repositรณrios Git perdidos cujos registros existem
dashboard.sync_external_users=Sincronizar dados de usuรกrio externo
dashboard.cleanup_hook_task_table=Limpar tabela hook_task
dashboard.cleanup_packages=Limpar pacotes expirados
-dashboard.server_uptime=Tempo de atividade do Servidor
-dashboard.current_goroutine=Goroutines Atuais
+dashboard.server_uptime=Tempo de atividade do servidor
+dashboard.current_goroutine=Goroutines atuais
dashboard.current_memory_usage=Uso de memรณria atual
dashboard.total_memory_allocated=Total de memรณria alocada
dashboard.memory_obtained=Memรณria obtida
-dashboard.pointer_lookup_times=Nยบ de consultas a ponteiros
+dashboard.pointer_lookup_times=Nรบmero de consultas a ponteiros
dashboard.memory_allocate_times=Alocaรงรตes de memรณria
dashboard.memory_free_times=Liberaรงรตes de memรณria
dashboard.current_heap_usage=Uso atual da heap
dashboard.heap_memory_obtained=Memรณria de heap obtida
-dashboard.heap_memory_idle=Memรณria da heap ociosa
-dashboard.heap_memory_in_use=Memรณria da heap em uso
-dashboard.heap_memory_released=Memรณria da heap liberada
+dashboard.heap_memory_idle=Memรณria de heap ociosa
+dashboard.heap_memory_in_use=Memรณria de heap em uso
+dashboard.heap_memory_released=Memรณria de heap liberada
dashboard.heap_objects=Objetos na heap
dashboard.bootstrap_stack_usage=Uso de pilha bootstrap
dashboard.stack_memory_obtained=Memรณria de pilha obtida
-dashboard.mspan_structures_usage=Uso de estruturas de MSpan
-dashboard.mspan_structures_obtained=Estruturas de MSpan obtidas
-dashboard.mcache_structures_usage=Uso de estruturas de MCache
-dashboard.mcache_structures_obtained=Estruturas de MCache obtidas
-dashboard.profiling_bucket_hash_table_obtained=Perfil obtido da Bucket Hash Table
+dashboard.mspan_structures_usage=Uso de estruturas MSpan
+dashboard.mspan_structures_obtained=Estruturas MSpan obtidas
+dashboard.mcache_structures_usage=Uso de estruturas MCache
+dashboard.mcache_structures_obtained=Estruturas MCache obtidas
+dashboard.profiling_bucket_hash_table_obtained=Hash table de profiling bucket obtida
dashboard.gc_metadata_obtained=Metadados do GC obtidos
dashboard.other_system_allocation_obtained=Outra alocaรงรฃo de sistema obtida
dashboard.next_gc_recycle=Prรณxima reciclagem do GC
-dashboard.last_gc_time=Desde da ultima vez do GC
+dashboard.last_gc_time=Tempo desde รบltima GC
dashboard.total_gc_time=Pausa total do GC
-dashboard.total_gc_pause=Pausa total do GC
-dashboard.last_gc_pause=รltima pausa do GC
-dashboard.gc_times=Nยบ de execuรงรตes do GC
-dashboard.delete_old_actions=Excluir todas as aรงรตes antigas do banco de dados
-dashboard.delete_old_actions.started=A exclusรฃo de todas as aรงรตes antigas do banco de dados foi iniciada.
+dashboard.total_gc_pause=Pausa total de GC
+dashboard.last_gc_pause=รltima pausa de GC
+dashboard.gc_times=Nรบmero de execuรงรตes do GC
+dashboard.delete_old_actions=Excluir todas as atividades antigas do banco de dados
+dashboard.delete_old_actions.started=A exclusรฃo de todas as atividades antigas do banco de dados foi iniciada.
dashboard.update_checker=Verificador de atualizaรงรฃo
dashboard.delete_old_system_notices=Excluir todos os avisos de sistema antigos do banco de dados
dashboard.gc_lfs=Coletar lixos dos meta-objetos LFS
-dashboard.stop_zombie_tasks=Parar tarefas zumbi
-dashboard.stop_endless_tasks=Parar tarefas infinitas
-dashboard.cancel_abandoned_jobs=Cancelar trabalhos abandonados
+dashboard.stop_zombie_tasks=Parar tarefas de actions zumbi
+dashboard.stop_endless_tasks=Parar tarefas infinitas de actions
+dashboard.cancel_abandoned_jobs=Cancelar trabalhos abandonados de actions
-users.user_manage_panel=Gerenciamento de conta de usuรกrio
+users.user_manage_panel=Gerenciar contas de usuรกrio
users.new_account=Criar conta de usuรกrio
users.name=Nome de usuรกrio
-users.full_name=Nome Completo
+users.full_name=Nome completo
users.activated=Ativado
users.admin=Administrador
users.restricted=Restrito
@@ -2935,11 +3153,11 @@ users.2fa=2FA
users.repos=Repositรณrios
users.created=Criado
users.last_login=รltimo acesso
-users.never_login=Nunca acessado
-users.send_register_notify=Enviar notificaรงรฃo de cadastro de usuรกrio
+users.never_login=Nunca entrou
+users.send_register_notify=Notificar sobre cadastros via e-mail
users.new_success=Usuรกrio "%s" criado.
users.edit=Editar
-users.auth_source=Fonte da autenticaรงรฃo
+users.auth_source=Fonte de autenticaรงรฃo
users.local=Local
users.auth_login_name=Nome de acesso da autenticaรงรฃo
users.password_helper=Deixe a senha em branco para mantรช-la inalterada.
@@ -2947,21 +3165,21 @@ users.update_profile_success=A conta de usuรกrio foi atualizada.
users.edit_account=Editar a conta de usuรกrio
users.max_repo_creation=Nรบmero mรกximo de repositรณrios
users.max_repo_creation_desc=(Use -1 para usar o limite padrรฃo global.)
-users.is_activated=Conta de usuรกrio estรก ativada
-users.prohibit_login=Desabilitar acesso
-users.is_admin=ร administrador
-users.is_restricted=Estรก restrito
-users.allow_git_hook=Pode criar hooks Git
-users.allow_git_hook_tooltip=Hooks Git sรฃo executados como o usuรกrio do SO que executa Forgejo e terรก o mesmo nรญvel de acesso ao servidor. Como resultado, os usuรกrios com esse privilรฉgio especial de Hook do Git podem acessar e modificar todos os repositรณrios do Forgejo, bem como o banco de dados usado pelo Forgejo. Por conseguinte, podem tambรฉm obter privilรฉgios de administrador do Forgejo.
+users.is_activated=Conta ativada
+users.prohibit_login=Conta suspensa
+users.is_admin=Conta de administrador
+users.is_restricted=Conta restrita
+users.allow_git_hook=Pode criar hooks do Git
+users.allow_git_hook_tooltip=Hooks do Git sรฃo executados como o usuรกrio do SO que executa Forgejo e terรฃo o mesmo nรญvel de acesso ao servidor. Como resultado, usuรกrios com esse privilรฉgio especial de hooks do Git podem acessar e modificar todos os repositรณrios do Forgejo, bem como o banco de dados usado pelo Forgejo. Por isso, eles tambรฉm podem obter privilรฉgios de administrador do Forgejo.
users.allow_import_local=Pode importar repositรณrios locais
users.allow_create_organization=Pode criar organizaรงรตes
users.update_profile=Atualizar conta de usuรกrio
users.delete_account=Excluir conta de usuรกrio
-users.cannot_delete_self=Vocรช nรฃo pode excluir vocรช mesmo
+users.cannot_delete_self=Vocรช nรฃo pode excluir a si mesmo
users.still_own_repo=Este usuรกrio ainda possui um ou mais repositรณrios. Exclua ou transfira esses repositรณrios primeiro.
users.still_has_org=Este usuรกrio รฉ membro de uma organizaรงรฃo. Remova o usuรกrio de qualquer organizaรงรฃo primeiro.
users.purge=Eliminar usuรกrio
-users.purge_help=Exclua forรงosamente o usuรกrio e quaisquer repositรณrios, organizaรงรตes e pacotes pertencentes ao usuรกrio. Todos os comentรกrios tambรฉm serรฃo excluรญdos.
+users.purge_help=Exclua forรงosamente o usuรกrio e quaisquer repositรณrios, organizaรงรตes e pacotes pertencentes ao usuรกrio. Todos os comentรกrios e issues criados por esse usuรกrio tambรฉm serรฃo excluรญdos.
users.still_own_packages=Este usuรกrio รฉ dono de um ou mais pacotes. Exclua estes pacotes antes de continuar.
users.deletion_success=A conta de usuรกrio foi excluรญda.
users.reset_2fa=Reinicializar 2FA
@@ -2970,12 +3188,12 @@ users.list_status_filter.reset=Reset
users.list_status_filter.is_active=Ativo
users.list_status_filter.not_active=Inativo
users.list_status_filter.is_admin=Administrador
-users.list_status_filter.not_admin=Nรฃo Administrador
+users.list_status_filter.not_admin=Nรฃo administrador
users.list_status_filter.is_restricted=Restrito
users.list_status_filter.not_restricted=Nรฃo restrito
users.list_status_filter.is_prohibit_login=Proibir login
users.list_status_filter.not_prohibit_login=Permitir login
-users.list_status_filter.is_2fa_enabled=2FA Ativado
+users.list_status_filter.is_2fa_enabled=Autenticaรงรฃo de dois fatores ativada
users.list_status_filter.not_2fa_enabled=Autenticaรงรฃo em duas etapas desativada
users.details=Detalhes do usuรกrio
@@ -2998,8 +3216,8 @@ orgs.members=Membros
orgs.new_orga=Nova organizaรงรฃo
repos.repo_manage_panel=Gerenciar repositรณrios
-repos.unadopted=Repositรณrios Nรฃo Adotados
-repos.unadopted.no_more=Nรฃo foram encontrados mais repositรณrios nรฃo adotados
+repos.unadopted=Repositรณrios nรฃo adotados
+repos.unadopted.no_more=Nรฃo foram encontrados repositรณrios nรฃo adotados.
repos.owner=Proprietรกrio(a)
repos.name=Nome
repos.private=Privado
@@ -3023,11 +3241,11 @@ packages.repository=Repositรณrio
packages.size=Tamanho
packages.published=Publicado
-defaulthooks=Webhooks Padrรตes
+defaulthooks=Webhooks padrรฃo
defaulthooks.add_webhook=Adicionar Webhook Padrรฃo
defaulthooks.update_webhook=Atualizar Webhook Padrรฃo
-systemhooks=Webhooks do Sistema
+systemhooks=Webhooks do sistema
systemhooks.add_webhook=Adicionar Webhook do Sistema
systemhooks.update_webhook=Atualizar Webhook do Sistema
@@ -3053,20 +3271,20 @@ auths.attribute_username_placeholder=Deixe em branco para usar o nome de usuรกri
auths.attribute_name=Atributo primeiro nome
auths.attribute_surname=Atributo sobrenome
auths.attribute_mail=Atributo e-mail
-auths.attribute_ssh_public_key=Atributo de chave SSH pรบblica
-auths.attribute_avatar=Atributo do avatar
-auths.attributes_in_bind=Buscar os atributos no contexto de Bind DN
+auths.attribute_ssh_public_key=Atributo chave SSH pรบblica
+auths.attribute_avatar=Atributo avatar
+auths.attributes_in_bind=Obter os atributos no contexto de bind DN
auths.allow_deactivate_all=Permitir que um resultado de pesquisa vazio para desativar todos os usuรกrios
auths.use_paged_search=Usar pesquisa paginada
auths.search_page_size=Tamanho da pรกgina
auths.filter=Filtro de usuรกrio
auths.admin_filter=Filtro de administrador
auths.restricted_filter=Filtro restrito
-auths.restricted_filter_helper=Deixe em branco para nรฃo definir nenhum usuรกrio como restrito. Use um asterisco ('*') para definir todos os usuรกrios que nรฃo correspondem ao Filtro de administrador como restritos.
+auths.restricted_filter_helper=Deixe em branco para nรฃo definir nenhum usuรกrio como restrito. Use um asterisco ("*") para definir todos os usuรกrios que nรฃo correspondem ao filtro Administrador como restritos.
auths.verify_group_membership=Verificar associaรงรฃo ao grupo no LDAP (deixe o filtro vazio para ignorar)
-auths.group_search_base=Grupo de Pesquisa DN Base
-auths.group_attribute_list_users=Atributo do Grupo que Contรฉm a Lista de Usuรกrios
-auths.user_attribute_in_group=Atributo do Usuรกrio Listado em Grupo
+auths.group_search_base=DN Base para pesquisa de grupos
+auths.group_attribute_list_users=Atributo do grupo que contรฉm a lista de usuรกrio
+auths.user_attribute_in_group=Atributo de usuรกrio listado no grupo
auths.map_group_to_team=Mapear grupos LDAP para Organizaรงรตes (deixe o campo vazio para pular)
auths.map_group_to_team_removal=Remover usuรกrios de equipes sincronizadas se o usuรกrio nรฃo pertence ao grupo LDAP correspondente
auths.enable_ldap_groups=Habilitar grupos LDAP
@@ -3097,15 +3315,15 @@ auths.oauth2_emailURL=URL do e-mail
auths.skip_local_two_fa=Ignorar autenticaรงรฃo em duas etapas local
auths.skip_local_two_fa_helper=Deixar desligado significa que os usuรกrios locais com 2FA ligada ainda terรฃo que fazer login com 2FA
auths.oauth2_tenant=Locatรกrio
-auths.oauth2_scopes=Escopos Adicionais
-auths.oauth2_required_claim_name=Nome do Claim Obrigatorio
+auths.oauth2_scopes=Escopos adicionais
+auths.oauth2_required_claim_name=Nome obrigatรณrio do claim
auths.oauth2_required_claim_name_helper=Defina este nome para permitir o login desta fonte apenas para usuรกrios que tenham um claim com este nome
-auths.oauth2_required_claim_value=Valor do Claim Obrigatorio
+auths.oauth2_required_claim_value=Valor obrigatรณrio do claim
auths.oauth2_required_claim_value_helper=Defina este valor para permitir o login desta fonte apenas para usuรกrios que tenham um claim com este nome e valor
auths.oauth2_group_claim_name=Nome do claim que fornece os nomes dos grupos para esta fonte. (Opcional)
-auths.oauth2_admin_group=Valor do Claim de Grupo para os usuรกrios administradores. (Opcional - requer nome do claim acima)
-auths.oauth2_restricted_group=Valor do Claim de Grupo para os usuรกrios restritos. (Opcional - requer nome do claim acima)
-auths.oauth2_map_group_to_team=Mapear grupos para Organizaรงรตes. (Opcional - requer nome do claim acima)
+auths.oauth2_admin_group=Valor do claim de grupo para os usuรกrios administradores. (Opcional - requer nome do claim acima)
+auths.oauth2_restricted_group=Valor do claim de grupo para os usuรกrios restritos. (Opcional - requer nome do claim acima)
+auths.oauth2_map_group_to_team=Mapear grupos do claim a equipes da organizaรงรฃo. (Opcional - requer nome do claim acima)
auths.oauth2_map_group_to_team_removal=Remover usuรกrios de equipes sincronizadas se o usuรกrio nรฃo pertence ao grupo correspondente.
auths.enable_auto_register=Habilitar cadastro automรกtico
auths.sspi_auto_create_users=Criar usuรกrios automaticamente
@@ -3122,17 +3340,17 @@ auths.tips=Dicas
auths.tips.oauth2.general=Autenticaรงรฃo OAuth2
auths.tips.oauth2.general.tip=Ao registrar uma nova autenticaรงรฃo OAuth2, o URL de retorno de chamada/redirecionamento deve ser:
auths.tip.oauth2_provider=Provedor OAuth2
-auths.tip.bitbucket=Cadastrar um novo consumidor de OAuth em https://bitbucket.org/account/user/ e adicionar a permissรฃo 'Account' - 'Read'
+auths.tip.bitbucket=Cadastrar um novo consumidor de OAuth em %s
auths.tip.nextcloud=`Registre um novo consumidor OAuth em sua instรขncia usando o seguinte menu "Configuraรงรตes -> Seguranรงa -> Cliente OAuth 2.0"`
-auths.tip.dropbox=Criar um novo aplicativo em https://www.dropbox.com/developers/apps
-auths.tip.facebook=`Cadastrar um novo aplicativo em https://developers.facebook.com/apps e adicionar o produto "Facebook Login"`
-auths.tip.github=Cadastrar um novo aplicativo de OAuth na https://github.com/settings/applications/new
+auths.tip.dropbox=Criar um novo aplicativo em %s
+auths.tip.facebook=`Cadastrar um novo aplicativo em %s e adicionar o produto "Facebook Login"`
+auths.tip.github=Cadastrar um novo aplicativo de OAuth na %s
auths.tip.gitlab=Cadastrar um novo aplicativo em https://gitlab.com/profile/applications
-auths.tip.google_plus=Obter credenciais de cliente OAuth2 do console de API do Google em https://console.developers.google.com/
+auths.tip.google_plus=Obter credenciais de cliente OAuth2 do console de API do Google em %s
auths.tip.openid_connect=Use o OpenID Connect Discovery URL (/.well-known/openid-configuration) para especificar os endpoints
-auths.tip.twitter=Vรก em https://dev.twitter.com/apps, crie um aplicativo e certifique-se de que estรก habilitada a opรงรฃo โAllow this application to be used to Sign in with Twitterโ
-auths.tip.discord=Cadastrar um novo aplicativo em https://discordapp.com/developers/applications/me
-auths.tip.yandex=`Crie um novo aplicativo em https://oauth.yandex.com/client/new. Selecione as seguintes permissรตes da seรงรฃo "Yandex.Passport API": "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"`
+auths.tip.twitter=Vรก em %s, crie um aplicativo e certifique-se de que estรก habilitada a opรงรฃo โAllow this application to be used to Sign in with Twitterโ
+auths.tip.discord=Cadastrar um novo aplicativo em %s
+auths.tip.yandex=`Crie um novo aplicativo em %s. Selecione as seguintes permissรตes da seรงรฃo "Yandex.Passport API": "Access to email address", "Access to user avatar" and "Access to username, first name and surname, gender"`
auths.tip.mastodon=Insira a URL da instรขncia personalizada do mastodon que vocรช deseja usar para autenticar (ou use o padrรฃo)
auths.edit=Editar fonte de autenticaรงรฃo
auths.activated=Esta fonte de autenticaรงรฃo estรก ativada
@@ -3140,7 +3358,7 @@ auths.new_success=A fonte de autenticaรงรฃo "%s" foi adicionada.
auths.update_success=A fonte de autenticaรงรฃo foi atualizada.
auths.update=Atualizar fonte de autenticaรงรฃo
auths.delete=Excluir fonte de autenticaรงรฃo
-auths.delete_auth_title=Excluir a Fonte de Autenticaรงรฃo
+auths.delete_auth_title=Excluir fonte de autenticaรงรฃo
auths.delete_auth_desc=A exclusรฃo de uma fonte de autenticaรงรฃo impede que os usuรกrios a usem para acessar. Continuar?
auths.still_in_used=A fonte de autenticaรงรฃo ainda estรก em uso. Converta ou exclua todos os usuรกrios que usam essa fonte de autenticaรงรฃo primeiro.
auths.deletion_success=A fonte de autenticaรงรฃo foi excluรญda.
@@ -3152,20 +3370,20 @@ auths.invalid_openIdConnectAutoDiscoveryURL=URL do Auto Discovery invรกlida (dev
config.server_config=Configuraรงรฃo do servidor
config.app_name=Nome do servidor
config.app_ver=Versรฃo do Forgejo
-config.app_url=URL base do Forgejo
-config.custom_conf=Caminho do Arquivo de Configuraรงรฃo
-config.custom_file_root_path=Caminho raiz para arquivo personalizado
+config.app_url=URL base
+config.custom_conf=Localizaรงรฃo do arquivo de configuraรงรฃo
+config.custom_file_root_path=Localizaรงรฃo raiz dos arquivos personalizados
config.domain=Domรญnio do servidor
config.offline_mode=Modo local
-config.disable_router_log=Desabilitar o Log do roteador
-config.run_user=Executar como nome de usuรกrio
+config.disable_router_log=Desabilitar log do roteador
+config.run_user=Executar como este usuรกrio
config.run_mode=Modo de execuรงรฃo
config.git_version=Versรฃo do Git
-config.repo_root_path=Caminho raiz do repositรณrio
-config.lfs_root_path=Caminho raiz do LFS
-config.log_file_root_path=Caminho do log
+config.repo_root_path=Localizaรงรฃo raiz do repositรณrio
+config.lfs_root_path=Localizaรงรฃo raiz de LFS
+config.log_file_root_path=Localizaรงรฃo do log
config.script_type=Tipo de script
-config.reverse_auth_user=Usuรกrio de autenticaรงรฃo reversa
+config.reverse_auth_user=Usuรกrio de autenticaรงรฃo do proxy reverso
config.ssh_config=Configuraรงรฃo de SSH
config.ssh_enabled=Habilitado
@@ -3173,16 +3391,16 @@ config.ssh_start_builtin_server=Usar o servidor embutido
config.ssh_domain=Domรญnio do servidor SSH
config.ssh_port=Porta
config.ssh_listen_port=Porta de escuta
-config.ssh_root_path=Caminho da raiz
-config.ssh_key_test_path=Caminho da chave de teste
-config.ssh_keygen_path=Caminho do keygen ('ssh-keygen')
+config.ssh_root_path=Caminho raiz
+config.ssh_key_test_path=Localizaรงรฃo de teste para chave
+config.ssh_keygen_path=Localizaรงรฃo do gerador de chaves ("ssh-keygen")
config.ssh_minimum_key_size_check=Verificar tamanho mรญnimo da chave
config.ssh_minimum_key_sizes=Tamanhos mรญnimos da chave
config.lfs_config=Configuraรงรฃo de LFS
config.lfs_enabled=Habilitado
-config.lfs_content_path=Caminho do conteรบdo LFS
-config.lfs_http_auth_expiry=Expiraรงรฃo da autenticaรงรฃo HTTP LFS
+config.lfs_content_path=Localizaรงรฃo do conteรบdo LFS
+config.lfs_http_auth_expiry=Tempo de expiraรงรฃo da autenticaรงรฃo HTTP de LFS
config.db_config=Configuraรงรฃo do banco de dados
config.db_type=Tipo
@@ -3195,42 +3413,42 @@ config.db_path=Caminho
config.service_config=Configuraรงรฃo do serviรงo
config.register_email_confirm=Exigir confirmaรงรฃo de e-mail para se cadastrar
-config.disable_register=Desabilitar auto-cadastro
-config.allow_only_internal_registration=Permitir Registro Somente Atravรฉs do Prรณprio Forgejo
-config.allow_only_external_registration=Permitir cadastro somente por meio de serviรงos externos
-config.enable_openid_signup=Habilitar o auto-cadastro via OpenID
+config.disable_register=Desabilitar autocadastro
+config.allow_only_internal_registration=Permitir cadastro somente atravรฉs do prรณprio Forgejo
+config.allow_only_external_registration=Permitir cadastro somente atravรฉs de serviรงos externos
+config.enable_openid_signup=Habilitar autocadastro via OpenID
config.enable_openid_signin=Habilitar acesso via OpenID
config.show_registration_button=Mostrar botรฃo de cadastro
-config.require_sign_in_view=Exigir acesso do usuรกrio para a visualizaรงรฃo de pรกginas
-config.mail_notify=Habilitar notificaรงรตes de e-mail
+config.require_sign_in_view=Exigir cadastro para visualizaรงรฃo de pรกginas
+config.mail_notify=Habilitar notificaรงรตes via e-mail
config.enable_captcha=Habilitar o CAPTCHA
-config.active_code_lives=Ativar Code Lives
-config.reset_password_code_lives=Tempo de expiraรงรฃo do cรณdigo de recuperaรงรฃo de conta
+config.active_code_lives=Tempo de expiraรงรฃo do cรณdigo de ativaรงรฃo
+config.reset_password_code_lives=Tempo de expiraรงรฃo do cรณdigo de recuperaรงรฃo
config.default_keep_email_private=Ocultar endereรงos de e-mail por padrรฃo
config.default_allow_create_organization=Permitir a criaรงรฃo de organizaรงรตes por padrรฃo
-config.enable_timetracking=Habilitar Cronรดmetro
-config.default_enable_timetracking=Habilitar o Cronรดmetro por Padrรฃo
+config.enable_timetracking=Habilitar estatรญsticas de tempo
+config.default_enable_timetracking=Habilitar estatรญsticas de tempo por padrรฃo
config.allow_dots_in_usernames = Permitir pontos em nomes de usuรกrio. Esta opรงรฃo nรฃo afeta contas jรก existentes.
-config.default_allow_only_contributors_to_track_time=Permitir que apenas os colaboradores acompanhem o contador de tempo
-config.no_reply_address=Ocultar domรญnio de e-mail
+config.default_allow_only_contributors_to_track_time=Permitir que apenas os colaboradores usem as estatรญsticas de tempo
+config.no_reply_address=Domรญnio do email oculto
config.default_visibility_organization=Visibilidade padrรฃo para novas organizaรงรตes
config.default_enable_dependencies=Habilitar dependรชncias de issue por padrรฃo
-config.webhook_config=Configuraรงรฃo de Hook da Web
+config.webhook_config=Configuraรงรฃo de webhook
config.queue_length=Tamanho da fila
-config.deliver_timeout=Intervalo de entrega
+config.deliver_timeout=Tempo limite de entrega
config.skip_tls_verify=Ignorar verificaรงรฃo de TLS
-config.mailer_config=Configuraรงรฃo de Envio de E-mail
+config.mailer_config=Configuraรงรฃo de envio de e-mails
config.mailer_enabled=Habilitado
config.mailer_enable_helo=Ativar HELO
config.mailer_name=Nome
config.mailer_protocol=Protocolo
-config.mailer_smtp_addr=Addr SMTP
+config.mailer_smtp_addr=Host SMTP
config.mailer_smtp_port=Porta SMTP
config.mailer_user=Usuรกrio
config.mailer_use_sendmail=Usar o Sendmail
-config.mailer_sendmail_path=Caminho do Sendmail
+config.mailer_sendmail_path=Localizaรงรฃo do Sendmail
config.mailer_sendmail_args=Argumentos extras para o Sendmail
config.mailer_sendmail_timeout=Tempo limite do Sendmail
config.mailer_use_dummy=Dummy
@@ -3240,20 +3458,20 @@ config.send_test_mail_submit=Enviar
config.test_mail_failed=Ocorreu um erro ao enviar um e-mail de teste para "%s": %v
config.test_mail_sent=Um e-mail de teste foi enviado para "%s".
-config.oauth_config=Configuraรงรฃo do OAuth
+config.oauth_config=Configuraรงรฃo de OAuth
config.oauth_enabled=Habilitado
config.cache_config=Configuraรงรฃo de cache
config.cache_adapter=Adaptador de cache
config.cache_interval=Intervalo de cache
config.cache_conn=Conexรฃo de cache
-config.cache_item_ttl=Item de cache TTL
+config.cache_item_ttl=TTL do item de cache
-config.session_config=Configuraรงรฃo da sessรฃo
-config.session_provider=Provedor da sessรฃo
+config.session_config=Configuraรงรฃo de sessรฃo
+config.session_provider=Provedor de sessรฃo
config.provider_config=Configuraรงรฃo do provedor
config.cookie_name=Nome do cookie
-config.gc_interval_time=Tempo de Intervalo do GC
+config.gc_interval_time=Tempo de intervalo do GC
config.session_life_time=Tempo de vida da sessรฃo
config.https_only=Apenas HTTPS
config.cookie_life_time=Tempo de vida do cookie
@@ -3261,25 +3479,25 @@ config.cookie_life_time=Tempo de vida do cookie
config.picture_config=Configuraรงรฃo de imagem e avatar
config.picture_service=Serviรงo de imagens
config.disable_gravatar=Desabilitar o gravatar
-config.enable_federated_avatar=Habilitar avatares federativos
+config.enable_federated_avatar=Habilitar avatares federados
config.git_config=Configuraรงรฃo do Git
-config.git_disable_diff_highlight=Desabilitar realce de mudanรงas no diff
-config.git_max_diff_lines=Mรกximo de linhas mostradas no diff (para um รบnico arquivo)
-config.git_max_diff_line_characters=Mรกximo de caracteres mostrados no diff (para uma รบnica linha)
-config.git_max_diff_files=Mรกximo de arquivos a serem mostrados no diff
+config.git_disable_diff_highlight=Desabilitar realce de sintaxe em diffs
+config.git_max_diff_lines=Mรกximo de linhas por arquivo em diffs
+config.git_max_diff_line_characters=Mรกximo de caracteres por linha em diffs
+config.git_max_diff_files=Mรกximo de arquivos de diff exibidos
config.git_gc_args=Argumentos do GC
config.git_migrate_timeout=Tempo limite de migraรงรฃo
-config.git_mirror_timeout=Tempo limite de atualizaรงรฃo de espelhamento
-config.git_clone_timeout=Tempo limite para operaรงรฃo de clone
-config.git_pull_timeout=Tempo limite para operaรงรฃo de pull
-config.git_gc_timeout=Tempo limite para execuรงรฃo do GC
+config.git_mirror_timeout=Tempo limite para atualizaรงรฃo de espelhos
+config.git_clone_timeout=Tempo limite para operaรงรตes de clonagem
+config.git_pull_timeout=Tempo limite para operaรงรตes de pull
+config.git_gc_timeout=Tempo limite para operaรงรฃo de GC
config.log_config=Configuraรงรฃo de log
config.logger_name_fmt=Logger: %s
config.disabled_logger=Desabilitado
-config.access_log_mode=Modo log Access
-config.access_log_template=Modelo do registro de acesso
+config.access_log_mode=Modo do log de acesso
+config.access_log_template=Modelo do log de acesso
config.xorm_log_sql=Log SQL
config.set_setting_failed=Falha ao definir configuraรงรฃo %s
@@ -3310,10 +3528,10 @@ monitor.queue=Fila: %s
monitor.queue.name=Nome
monitor.queue.type=Tipo
monitor.queue.exemplar=Tipo de modelo
-monitor.queue.numberworkers=Nรบmero de executores
-monitor.queue.maxnumberworkers=Nรบmero mรกximo de executores
-monitor.queue.numberinqueue=Nรบmero na Fila
-monitor.queue.settings.title=Configuraรงรตes do conjunto
+monitor.queue.numberworkers=Nรบmero de workers
+monitor.queue.maxnumberworkers=Nรบmero mรกximo de workers
+monitor.queue.numberinqueue=Nรบmero na fila
+monitor.queue.settings.title=Configuraรงรตes do pool
monitor.queue.settings.maxnumberworkers=Nรบmero mรกximo de executores
monitor.queue.settings.maxnumberworkers.placeholder=Atualmente %[1]d
monitor.queue.settings.maxnumberworkers.error=Nรบmero mรกximo de executores deve ser um nรบmero
@@ -3323,10 +3541,10 @@ monitor.queue.settings.remove_all_items=Remover tudo
monitor.queue.settings.remove_all_items_done=Todos os itens da fila foram removidos.
notices.system_notice_list=Avisos do sistema
-notices.view_detail_header=Ver detalhes do aviso
+notices.view_detail_header=Detalhes do aviso
notices.operations=Operaรงรตes
-notices.select_all=Marcar todos
-notices.deselect_all=Desmarcar todos
+notices.select_all=Selecionar tudo
+notices.deselect_all=Desselecionar tudo
notices.inverse_selection=Inverter seleรงรฃo
notices.delete_selected=Excluir seleรงรฃo
notices.delete_all=Excluir todos os avisos
@@ -3339,17 +3557,17 @@ notices.delete_success=Os avisos do sistema foram excluรญdos.
identity_access = Identidade e acesso
settings = Configuraรงรตes de administrador
users.bot = Robรด
-dashboard.start_schedule_tasks = Iniciar tarefas programadas
+dashboard.start_schedule_tasks = Iniciar tarefas de actions programadas
users.reserved = Reservado
emails.change_email_text = Tem certeza de que deseja atualizar este endereรงo de e-mail?
-self_check = Autodiagnรณstico
-auths.tip.gitea = Registre um novo aplicativo OAuth2. A documentaรงรฃo pode ser encontrada em https://forgejo.org/docs/latest/user/oauth2-provider/
-dashboard.sync_tag.started = Sincronizaรงรฃo de etiquetas iniciada
+self_check = Autoverificaรงรฃo
+auths.tip.gitea = Registre um novo aplicativo OAuth2. A documentaรงรฃo pode ser encontrada em %s/
+dashboard.sync_tag.started = Sincronizaรงรฃo de tags iniciada
self_check.no_problem_found = Por enquanto nรฃo hรก algum problema.
config_settings = Configuraรงรตes
config_summary = Resumo
auths.tips.gmail_settings = Configuraรงรตes do Gmail:
-auths.tip.gitlab_new = Registre um novo aplicativo em https://gitlab.com/-/profile/applications
+auths.tip.gitlab_new = Registre um novo aplicativo em %s
config.app_slogan = Slogan do servidor
auths.default_domain_name = Domรญnio padrรฃo usado para o endereรงo de e-mail
dashboard.sync_repo_tags = Sincronizar etiquetas do Git para o banco de dados
@@ -3358,6 +3576,35 @@ dashboard.task.cancelled = Tarefa: %[1]s cancelada: %[3]s
dashboard.sync_branch.started = Sincronizaรงรฃo de ramos iniciada
dashboard.sync_repo_branches = Sincronizar ramos perdidos do Git para o banco de dados
packages.cleanup.success = Os dados expirados foram limpos com sucesso
+monitor.queue.activeworkers = Processos ativos
+systemhooks.desc = Os webhooks fazem automaticamente solicitaรงรตes HTTP POST para um servidor quando certos eventos Forgejo sรฃo acionados. Os webhooks definidos aqui atuarรฃo em todos os repositรณrios do sistema, entรฃo, considere quaisquer implicaรงรตes de desempenho que isso possa ter. Leia mais no guia de webhooks .
+defaulthooks.desc = Os webhooks fazem automaticamente solicitaรงรตes HTTP POST para um servidor quando certos eventos Forgejo sรฃo acionados. Os webhooks definidos aqui sรฃo padrรตes e serรฃo copiados para todos os novos repositรณrios. Leia mais no guia de webhooks .
+self_check.database_fix_mysql = Para usuรกrios do MySQL/MariaDB, vocรช pode usar o comando "forgejo doctor convert" para corrigir os problemas de ordenamento, ou tambรฉm pode corrigir o problema usando "ALTER ... COLLATE ..." SQLs manualmente.
+monitor.queue.settings.desc = Os pools crescem dinamicamente quando as filas de seus workers ficam bloqueadas.
+config.cache_test_succeeded = Teste de cache bem-sucedido, obteve uma resposta em %s.
+self_check.database_inconsistent_collation_columns = O banco de dados estรก usando o ordenamento %s, mas essas colunas estรฃo usando ordenamentos incompatรญveis. Isso pode causar alguns problemas inesperados.
+dashboard.rebuild_issue_indexer = Reconstruir indexador de problemas
+monitor.queue.review_add = Revisar / adicionar workers
+assets = Ativos de cรณdigo
+config.open_with_editor_app_help = Os editores "Abrir com" para o menu clone. Se deixado em branco, o padrรฃo serรก usado. Expanda para ver o padrรฃo.
+config.cache_test_slow = Teste de cache bem-sucedido, mas a resposta รฉ lenta: %s.
+config.cache_test = Cache de Teste
+config.cache_test_failed = Falha ao sondar o cache: %v.
+self_check.database_collation_mismatch = Esperar que o banco de dados use o ordenamento: %s
+dashboard.cleanup_actions = Limpar logs expirados e artefatos de aรงรตes
+emails.delete = Deletar email
+emails.delete_primary_email_error = Vocรช nรฃo pode excluir o email principal.
+emails.deletion_success = O endereรงo de email foi excluรญdo.
+emails.delete_desc = Tem certeza de que deseja excluir este endereรงo de e-mail?
+dashboard.cron.cancelled = Cron: %[1]s cancelado: %[3]s
+users.activated.description = Conclusรฃo da verificaรงรฃo de e-mail. O proprietรกrio de uma conta nรฃo ativada nรฃo poderรก efetuar login atรฉ que a verificaรงรฃo de e-mail seja concluรญda.
+users.block.description = Bloquear este usuรกrio de interagir com este serviรงo atravรฉs de sua conta e proibir o login.
+users.admin.description = Conceda a este usuรกrio acesso total a todos os recursos administrativos disponรญveis por meio da interface do usuรกrio da Web e da API.
+users.restricted.description = Permitir interaรงรฃo somente com os repositรณrios e organizaรงรตes onde este usuรกrio รฉ adicionado como colaborador. Isso impede o acesso a repositรณrios pรบblicos nesta instรขncia.
+users.organization_creation.description = Permitir a criaรงรฃo de novas organizaรงรตes.
+users.local_import.description = Permitir importar repositรณrios do sistema de arquivos local do servidor. Isso pode ser um problema de seguranรงa.
+self_check.database_collation_case_insensitive = O banco de dados estรก usando um ordenamento %s, que รฉ um ordenamento insensรญvel. Embora o Forgejo possa funcionar com ele, pode haver alguns casos raros que nรฃo funcionam como esperado.
+monitor.duration = Duraรงรฃo (s)
[action]
@@ -3386,7 +3633,7 @@ mirror_sync_create=sincronizou a nova referรชncia %[3]s para
mirror_sync_delete=referรชncia excluรญda e sincronizada %[2]s
em %[3]s do espelhamento
approve_pull_request=`aprovou %[3]s#%[2]s `
reject_pull_request=`sugeriu modificaรงรตes para %[3]s#%[2]s `
-publish_release=`lanรงou a versรฃo "%[4]s" em %[3]s `
+publish_release=`lanรงou o release "%[4]s" em %[3]s `
review_dismissed=`descartou a revisรฃo de %[4]s para %[3]s#%[2]s `
review_dismissed_reason=Motivo:
create_branch=criou o branch %[3]s em %[4]s
@@ -3440,9 +3687,9 @@ error.generate_hash=Falha ao gerar hash de commit
error.no_committer_account=Nenhuma conta vinculada ao e-mail do autor do commit
error.no_gpg_keys_found=Nenhuma chave conhecida encontrada para esta assinatura no banco de dados
error.not_signed_commit=Nรฃo รฉ um commit assinado
-error.failed_retrieval_gpg_keys=Falha em obter qualquer chave anexada ร conta do autor do commit
-error.probable_bad_signature=AVISO! Embora exista uma chave com este ID no banco de dados, ela nรฃo verifica este commit! Este commit รฉ SUSPEITO.
-error.probable_bad_default_signature=AVISO! Embora a chave padrรฃo tenha este ID, ela nรฃo verifica este commit! Este commit รฉ SUSPEITO.
+error.failed_retrieval_gpg_keys=Falha ao obter qualquer chave anexada ร conta do autor do commit
+error.probable_bad_signature=ATENรรO! Embora exista uma chave com este ID no banco de dados, ela nรฃo verifica este commit! Este commit รฉ SUSPEITO.
+error.probable_bad_default_signature=ATENรรO! Embora a chave padrรฃo tenha este ID, ela nรฃo verifica este commit! Este commit รฉ SUSPEITO.
[units]
unit=Unidade
@@ -3469,9 +3716,9 @@ dependencies=Dependรชncias
keywords=Palavras-chave
details=Detalhes
details.author=Autor
-details.project_site=Site do Projeto
-details.repository_site=Site do Repositรณrio
-details.documentation_site=Site da Documentaรงรฃo
+details.project_site=Site do projeto
+details.repository_site=Site do repositรณrio
+details.documentation_site=Site da documentaรงรฃo
details.license=Licenรงa
assets=Recursos
versions=Versรตes
@@ -3493,18 +3740,18 @@ chef.install=Para instalar o pacote, execute o seguinte comando:
composer.registry=Configure este registro em seu arquivo ~/.composer/config.json
:
composer.install=Para instalar o pacote usando o Composer, execute o seguinte comando:
composer.dependencies=Dependรชncias
-composer.dependencies.development=Dependรชncias de Desenvolvimento
+composer.dependencies.development=Dependรชncias de desenvolvimento
conan.details.repository=Repositรณrio
conan.registry=Configure este registro pela linha de comando:
conan.install=Para instalar o pacote usando o Conan, execute o seguinte comando:
conda.registry=Configure este registro como um repositรณrio Conda no arquivo .condarc
:
conda.install=Para instalar o pacote usando o Conda, execute o seguinte comando:
-container.details.type=Tipo de Imagem
+container.details.type=Tipo de imagem
container.details.platform=Plataforma
container.pull=Puxe a imagem pela linha de comando:
-container.digest=Digest:
+container.digest=Digest
container.multi_arch=S.O. / Arquitetura
-container.layers=Camadas da Imagem
+container.layers=Camadas da imagem
container.labels=Rรณtulos
container.labels.key=Chave
container.labels.value=Valor
@@ -3532,9 +3779,9 @@ npm.registry=Configure este registro no arquivo .npmrc
do seu proje
npm.install=Para instalar o pacote usando o npm, execute o seguinte comando:
npm.install2=ou adicione-o ao arquivo package.json:
npm.dependencies=Dependรชncias
-npm.dependencies.development=Dependรชncias de Desenvolvimento
-npm.dependencies.peer=Dependรชncias Peer
-npm.dependencies.optional=Dependรชncias Opcionais
+npm.dependencies.development=Dependรชncias de desenvolvimento
+npm.dependencies.peer=Dependรชncias peer
+npm.dependencies.optional=Dependรชncias opcionais
npm.details.tag=Tag
pub.install=Para instalar o pacote usando Dart, execute o seguinte comando:
pypi.requires=Requer Python
@@ -3543,12 +3790,12 @@ rpm.registry=Configure este registro pela linha de comando:
rpm.distros.redhat=em distribuiรงรตes baseadas no RedHat
rpm.distros.suse=em distribuiรงรตes baseadas no SUSE
rpm.install=Para instalar o pacote, execute o seguinte comando:
-rpm.repository=Informaรงรตes do repositรณrio
-rpm.repository.architectures=Arquiteturas
+rpm.repository = Informaรงรตes do repositรณrio
+rpm.repository.architectures = Arquiteturas
rubygems.install=Para instalar o pacote usando gem, execute o seguinte comando:
rubygems.install2=ou adicione-o ao Gemfile:
-rubygems.dependencies.runtime=Dependรชncias de Execuรงรฃo
-rubygems.dependencies.development=Dependรชncias de Desenvolvimento
+rubygems.dependencies.runtime=Dependรชncias de tempo de execuรงรฃo
+rubygems.dependencies.development=Dependรชncias de desenvolvimento
rubygems.required.ruby=Requer o Ruby versรฃo
rubygems.required.rubygems=Requer o RubyGem versรฃo
swift.registry=Configure este registro pela linha de comando:
@@ -3566,17 +3813,17 @@ settings.delete.description=A exclusรฃo de um pacote รฉ permanente e nรฃo pode s
settings.delete.notice=Vocรช estรก prestes a excluir %s (%s). Esta operaรงรฃo รฉ irreversรญvel, tem certeza?
settings.delete.success=O pacote foi excluรญdo.
settings.delete.error=Falha ao excluir o pacote.
-owner.settings.cargo.title=รndice do Registro Cargo
-owner.settings.cargo.initialize=Iniciar รndice
+owner.settings.cargo.title=รndice do registro Cargo
+owner.settings.cargo.initialize=Inicializar รญndice
owner.settings.cargo.initialize.error=Falha ao inicializar รญndice Cargo: %v
owner.settings.cargo.initialize.success=O รญndice Cargo foi criado com sucesso.
-owner.settings.cargo.rebuild=Reconstruir รndice
+owner.settings.cargo.rebuild=Reconstruir รญndice
owner.settings.cargo.rebuild.error=Falha ao reconstruir รญndice Cargo: %v
owner.settings.cargo.rebuild.success=O รญndice Cargo foi reconstruรญdo com sucesso.
-owner.settings.cleanuprules.title=Gerenciar Regras de Limpeza
-owner.settings.cleanuprules.add=Adicionar Regra de Limpeza
-owner.settings.cleanuprules.edit=Editar Regra de Limpeza
-owner.settings.cleanuprules.preview=Prรฉ-visualizar Regra de Limpeza
+owner.settings.cleanuprules.title=Regras de limpeza
+owner.settings.cleanuprules.add=Adicionar regra de limpeza
+owner.settings.cleanuprules.edit=Editar regra de limpeza
+owner.settings.cleanuprules.preview=Prรฉ-visualizar regra de limpeza
owner.settings.cleanuprules.preview.overview=%d pacotes agendados para serem removidos.
owner.settings.cleanuprules.preview.none=A regra de limpeza nรฃo corresponde a nenhum pacote.
owner.settings.cleanuprules.enabled=Habilitado
@@ -3594,11 +3841,39 @@ owner.settings.cleanuprules.success.update=Regra de limpeza foi atualizada.
owner.settings.cleanuprules.success.delete=Regra de limpeza foi excluรญda.
owner.settings.chef.title=Registro Chef
owner.settings.chef.keypair=Gerar par de chaves
-rpm.repository.architectures = Arquiteturas
-rpm.repository = Informaรงรตes do repositรณrio
rpm.repository.multiple_groups = Este pacote estรก disponรญvel em vรกrios grupos.
-npm.dependencies.bundle = Dependรชncias empacotadas
+npm.dependencies.bundle = Dependรชncias em bundle
registry.documentation = Para mais informaรงรตes sobre o registro %s, veja a documentaรงรฃo .
+arch.version.replaces = Substitui
+arch.version.conflicts = Conflitos
+arch.version.properties = Propriedades da versรฃo
+arch.version.description = Descriรงรฃo
+arch.version.groups = Grupo
+arch.version.provides = Fornece
+arch.version.depends = Depende
+arch.version.optdepends = Depende opcionalmente
+arch.pacman.repo.multi.item = Configuraรงรฃo para %s
+arch.pacman.sync = Sincronizar pacote com o pacman:
+arch.pacman.repo.multi = %s possui a mesma versรฃo em distribuiรงรตes diferentes.
+arch.pacman.helper.gpg = Adicionar certificado de confianรงa para o pacman:
+arch.version.backup = Cรณpia de Seguranรงa
+owner.settings.cleanuprules.none = Nรฃo hรก regras de limpeza ainda.
+owner.settings.cargo.rebuild.description = Reconstruir pode ser รบtil se o รญndice nรฃo estiver sincronizado com os pacotes do Cargo armazenados.
+owner.settings.cargo.rebuild.no_index = Nรฃo foi possรญvel reconstruir, nรฃo hรก um รญndice inicializado.
+arch.pacman.conf = Adicione o servidor com a distribuiรงรฃo e arquitetura no arquivo /etc/pacman.conf
:
+arch.version.makedepends = Dependรชncias do make
+arch.version.checkdepends = Verificar dependรชncias
+owner.settings.cargo.initialize.description = ร necessรกrio um repositรณrio Git especial de รญndice para usar o registro Cargo. Usar esta opรงรฃo irรก (re-)criar o repositรณrio e configurรก-lo automaticamente.
+owner.settings.chef.keypair.description = ร necessรกrio um par de chaves para autenticar no registro Chef. Se vocรช jรก gerou um par de chaves, gere um novo par e descarte o antigo.
+container.images.title = Imagens
+search_in_external_registry = Buscar em %s
+alt.registry.install = Para instalar o pacote, execute o seguinte comando:
+alt.registry = Configurar este registro da linha de comando:
+alt.install = Instalar pacote
+alt.repository = Informaรงรฃo do repositรณrio
+alt.repository.architectures = Arquiteturas
+alt.repository.multiple_groups = Este pacote estรก disponรญvel em mรบltiplos grupos.
+alt.setup = Adicionar um repositรณrio ร lista de repositรณrios conectados (escolha a arquitetura necessรกria em vez de "_arch_"):
[secrets]
secrets=Segredos
@@ -3613,15 +3888,15 @@ deletion=Excluir segredo
deletion.description=A exclusรฃo de um segredo รฉ permanente e nรฃo pode ser desfeita. Continuar?
deletion.success=O segredo foi excluรญdo.
deletion.failed=Falha ao excluir segredo.
-management=Gerenciamento de Segredos
+management=Gerenciar segredos
[actions]
actions=Aรงรตes
-unit.desc=Gerenciar aรงรตes
+unit.desc=Gerenciar pipelines integradas de CI/CD com Forgejo Actions.
status.unknown=Desconhecido
-status.waiting=Em espera
+status.waiting=Aguardando
status.running=Rodando
status.success=Sucesso
status.failure=Falha
@@ -3630,8 +3905,8 @@ status.skipped=Ignorado
status.blocked=Bloqueado
runners=Runners
-runners.runner_manage_panel=Gerenciamento de Runners
-runners.new=Criar novo Runner
+runners.runner_manage_panel=Gerenciar runners
+runners.new=Criar novo runner
runners.new_notice=Como iniciar um runner
runners.status=Estado
runners.id=ID
@@ -3649,7 +3924,7 @@ runners.task_list.repository=Repositรณrio
runners.task_list.commit=Commit
runners.task_list.done_at=Realizada em
runners.edit_runner=Editar Runner
-runners.update_runner=Atualizar as Alteraรงรตes
+runners.update_runner=Salvar alteraรงรตes
runners.update_runner_success=Runner atualizado com sucesso
runners.update_runner_failed=Falha ao atualizar runner
runners.delete_runner=Deletar esse runner
@@ -3665,7 +3940,7 @@ runners.status.offline=Offline
runners.version=Versรฃo
runners.reset_registration_token_success=Token de registro de runner redefinido com sucesso
-runs.all_workflows=Todos os Workflows
+runs.all_workflows=Todos os workflows
runs.commit=Commit
runs.pushed_by=push feito por
runs.invalid_workflow_helper=O arquivo de configuraรงรฃo do workflow รฉ invรกlido. Por favor, verifique seu arquivo de configuraรงรฃo: %s
@@ -3681,7 +3956,7 @@ runners.reset_registration_token = Resetar token de registro
runs.scheduled = Programadas
variables.creation = Adicionar variรกvel
variables.deletion = Remover variรกvel
-variables.management = Gerenciamento de variรกveis
+variables.management = Gerenciar variรกveis
runs.actors_no_select = Todos os atores
variables.none = Ainda nรฃo hรก variรกveis.
variables.update.failed = Falha ao editar a variรกvel.
@@ -3696,15 +3971,38 @@ runs.no_workflows.documentation = Para mais informaรงรตes sobre Forgejo Actions,
runs.no_workflows.quick_start = Forgejo Actions รฉ uma novidade para vocรช? Veja o guia rรกpido .
runs.no_results = Nenhum resultado.
variables.description = As variรกveis serรฃo passadas para certas aรงรตes e nรฃo poderรฃo ser lidas de outra forma.
+workflow.dispatch.trigger_found = Este workflow tem um disparador de evento workflow_dispatch .
+workflow.dispatch.run = Executar workflow
+runs.no_runs = O workflow ainda nรฃo foi executado.
+workflow.dispatch.warn_input_limit = Exibindo apenas as %d primeiras entradas.
+runs.no_matching_online_runner_helper = Nenhum runner online encontrado com o rรณtulo: %s
+workflow.disabled = Workflow estรก desativado.
+workflow.dispatch.use_from = Usar workflow de
+runs.no_job = O workflow precisa conter pelo menos um trabalho
+workflow.disable_success = Workflow "%s" desativado com sucesso.
+workflow.enable = Ativar workflow
+workflow.disable = Desabilitar workflow
+runs.no_workflows = Nรฃo hรก workflows ainda.
+runs.no_job_without_needs = O workflow deve conter pelo menos um trabalho sem dependรชncias.
+runs.workflow = Workflow
+workflow.enable_success = Workflow "%s" ativado com sucesso.
+workflow.dispatch.success = Execuรงรฃo do workflow solicitada com sucesso.
+workflow.dispatch.input_required = Exigir um valor para a entrada "%s".
+workflow.dispatch.invalid_input_type = Tipo de entrada "%s" invรกlido.
+variables.deletion.description = Apagar uma variรกvel รฉ permanente e nรฃo pode ser desfeito. Continuar?
+runs.expire_log_message = Os logs foram apagados pois eram antigos demais.
+runs.no_workflows.help_no_write_access = Para aprender sobre as Actions do Forgejo, veja a documentaรงรฃo .
+runs.no_workflows.help_write_access = Nรฃo sabe como comeรงar a usar as Actions do Forgejo? Veja o guia de como comeรงar na documentaรงรฃo do usuรกrio para escrever seu primeiro workflow, depois configure um runner do Forgejo para executar trabalhos.
+variables.not_found = Nรฃo foi possรญvel encontrar a variรกvel.
[projects]
type-1.display_name=Projeto individual
type-2.display_name=Projeto do repositรณrio
type-3.display_name=Projeto da organizaรงรฃo
+deleted.display_name = Projeto Apagado
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=Ligaรงรฃo simbรณlica
changed_filemode = %[1]s โ %[2]s
directory = Diretรณrio
@@ -3714,37 +4012,36 @@ executable_file = Arquivo executรกvel
-[graphs]
-component_loading = Carregando %s...
-component_loading_failed = Nรฃo foi possรญvel carregar o(a) %s
-component_loading_info = Pode demorar um poucoโฆ
-contributors.what = contribuiรงรตes
-code_frequency.what = frequรชncia de cรณdigo
-recent_commits.what = commits recentes
-component_failed_to_load = Ocorreu um erro inesperado.
-
-
[search]
-org_kind = Buscar organizaรงรตes...
-team_kind = Buscar equipes...
-code_kind = Buscar cรณdigo...
-user_kind = Buscar usuรกrios...
+org_kind = Buscar organizaรงรตesโฆ
+team_kind = Buscar equipesโฆ
+code_kind = Buscar cรณdigoโฆ
+user_kind = Buscar usuรกriosโฆ
no_results = Nenhum resultado encontrado.
keyword_search_unavailable = A busca por palavras-chave nรฃo estรก disponรญvel. Entre em contato com o administrador.
-package_kind = Buscar pacotes...
-project_kind = Buscar projetos...
-search = Buscar...
+package_kind = Buscar pacotesโฆ
+project_kind = Buscar projetosโฆ
+search = Buscarโฆ
fuzzy = Aproximada
fuzzy_tooltip = Inclui resultados que se aproximam dos termos de busca
match = Correspondente
match_tooltip = Inclui apenas os resultados que correspondem exatamente aos termos de busca
-repo_kind = Buscar repositรณrios...
+repo_kind = Buscar repositรณriosโฆ
type_tooltip = Tipo de busca
code_search_by_git_grep = Os resultados atuais da pesquisa de cรณdigo sรฃo fornecidos por "git grep". Pode haver melhores resultados se o administrador do site ativar o indexador de cรณdigo.
-branch_kind = Pesquisar branchesโฆ
-commit_kind = Pesquisar commitsโฆ
-runner_kind = Pesquisar runners...
+branch_kind = Buscar ramosโฆ
+commit_kind = Buscar commitsโฆ
+runner_kind = Buscar runnersโฆ
code_search_unavailable = A pesquisa de cรณdigo nรฃo estรก disponรญvel no momento. Entre em contato com o administrador do site.
+milestone_kind = Pesquisar marcos...
+union_tooltip = Incluir resultados que correspondam a quaisquer palavras-chave separadas por espaรงos em branco
+union = Uniรฃo
+exact = Exato
+exact_tooltip = Incluir apenas resultados que correspondam exatamente ao termo de pesquisa
+issue_kind = Buscar issuesโฆ
+pull_kind = Buscar pullsโฆ
+regexp_tooltip = Interpretar o termo de busca como uma expressรฃo regular
+regexp = RegExp
[munits.data]
b = B
@@ -3758,4 +4055,27 @@ eib = EiB
[markup]
filepreview.line = Linha %[1]d em %[2]s
filepreview.lines = Linhas %[1]d a %[2]d em %[3]s
-filepreview.truncated = Prรฉ-visualizaรงรฃo truncada
\ No newline at end of file
+filepreview.truncated = Prรฉ-visualizaรงรฃo truncada
+
+[repo.permissions]
+pulls.write = Escrita: Encerrar pull requests e gerir metadados como rรณtulos, marcos, responsรกveis, prazos e dependรชncias.
+code.read = Leitura: Acessar e clonar o cรณdigo do repositรณrio.
+issues.read = Leitura: Visualizar e criar issues e comentรกrios.
+code.write = Escrita: Fazer push para o repositรณrio, criar branches e tags.
+issues.write = Escrita: Encerrar issues e gerir metadados como rรณtulos, marcos, responsรกveis, prazos e dependรชncias.
+pulls.read = Leitura: Visualizar e criar pull requests.
+releases.read = Leitura: Visualizar e baixar releases.
+releases.write = Escrita: Publicar editar e apagar releases e seus recursos.
+wiki.read = Leitura: Ler a wiki integrada e o histรณrico dela.
+wiki.write = Escrita: Criar, alterar e apagar pรกginas na wiki integrada.
+projects.read = Ler: Acesse os painรฉis de projetos do repositรณrio.
+ext_wiki = Acesse o link para um wiki externo. As permissรตes sรฃo gerenciadas externamente.
+actions.write = Escrever: Acione, reinicie, cancele ou aprove manualmente pipelines de CI/CD pendentes.
+projects.write = Escrever: Crie projetos e colunas e edite-os.
+actions.read = Ler: Visualize pipelines de CI/CD integrados e seus logs.
+packages.read = Ler: Visualize e baixe pacotes atribuรญdos ao repositรณrio.
+packages.write = Escrever: Publique e delete pacotes atribuรญdos ao repositรณrio.
+ext_issues = Acesse o link para um issue tracker externo. As permissรตes sรฃo gerenciadas externamente.
+
+[translation_meta]
+test = To preserve its claws, the giant anteater walks on its front knuckles, like gorillas
diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini
index f4ab925dd0..42866bbf5e 100644
--- a/options/locale/locale_pt-PT.ini
+++ b/options/locale/locale_pt-PT.ini
@@ -112,7 +112,7 @@ preview=Prรฉ-visualizar
loading=Carregandoโฆ
error=Erro
-error404=A pรกgina que pretende aceder nรฃo existe ou nรฃo tem autorizaรงรฃo para a ver.
+error404=A pรกgina que pretende aceder nรฃo existe , foi removida ou nรฃo tem autorizaรงรฃo para a ver.
go_back=Voltar
never=Nunca
@@ -142,7 +142,7 @@ confirm_delete_selected=Confirma a exclusรฃo de todos os itens marcados?
name=Nome
value=Valor
-filter.is_fork = Derivaรงรตes
+filter.is_fork = Derivado
filter.is_mirror = Rรฉplicas
filter.is_template = Modelos
filter.public = Pรบblico
@@ -156,8 +156,17 @@ filter.clear = Retirar filtros
filter.is_archived = Arquivado
filter.not_template = Nรฃo modelos
toggle_menu = Comutar menu
-filter = Filtro
+filter = Filtrar
copy_generic = Copiar para a รกrea de transferรชncia
+test = Teste
+error413 = Vocรช esgotou a sua quota.
+new_repo.title = Novo repositรณrio
+new_migrate.title = Nova migraรงรฃo
+new_org.title = Nova organizaรงรฃo
+new_repo.link = Novo repositรณrio
+new_migrate.link = Nova migraรงรฃo
+new_org.link = Nova organizaรงรฃo
+copy_path = Copiar caminho
[aria]
navbar=Barra de navegaรงรฃo
@@ -189,6 +198,18 @@ buttons.ref.tooltip=Referenciar uma questรฃo ou um pedido de integraรงรฃo
buttons.switch_to_legacy.tooltip=Usar o editor clรกssico
buttons.enable_monospace_font=Habilitar tipo de letra mono-espaรงado
buttons.disable_monospace_font=Desabilitar tipo de letra mono-espaรงado
+buttons.indent.tooltip = Aninhar itens num nรญvel
+buttons.unindent.tooltip = Desaninhar itens por um nรญvel
+buttons.new_table.tooltip = Adicionar tabela
+table_modal.header = Adicionar tabela
+table_modal.placeholder.header = Cabeรงalho
+table_modal.placeholder.content = Conteรบdo
+table_modal.label.rows = Linhas
+table_modal.label.columns = Colunas
+link_modal.header = Adicionar uma ligaรงรฃo
+link_modal.url = URL
+link_modal.description = Descriรงรฃo
+link_modal.paste_reminder = Sugestรฃo: Com um URL na รกrea de transferรชncia, pode colar diretamente no editor para criar uma ligaรงรฃo.
[filter]
string.asc=A - Z
@@ -196,7 +217,7 @@ string.desc=Z - A
[error]
occurred=Ocorreu um erro
-report_message=Se acredita de que se trata de um erro do Forgejo, procure, por favor, questรตes relacionadas no GitHub ou abra uma nova questรฃo, se necessรกrio.
+report_message=Se acredita de que se trata de um erro do Forgejo, procure, por favor, questรตes relacionadas no Codeberg ou abra uma nova questรฃo, se necessรกrio.
missing_csrf=Pedido invรกlido: nรฃo hรก cรณdigo CSRF
invalid_csrf=Pedido invรกlido: cรณdigo CSRF invรกlido
not_found=Nรฃo foi possรญvel encontrar o destino.
@@ -206,13 +227,13 @@ server_internal = Erro interno do servidor
[startpage]
app_desc=Um serviรงo Git auto-hospedado e fรกcil de usar
install=Fรกcil de instalar
-install_desc=Corra, simplesmente, o ficheiro binรกrio executรกvel para a sua plataforma, despache-o com o Docker , ou obtenha-o sob a forma de pacote .
+install_desc=Corra, simplesmente, o ficheiro binรกrio executรกvel para a sua plataforma, despache-o com o Docker , ou obtenha-o sob a forma de pacote .
platform=Multiplataforma
-platform_desc=Forgejo corre em qualquer plataforma onde possa compilar em linguagem Go : Windows, macOS, Linux, ARM, etc. Escolha a sua preferida!
+platform_desc=Estรก confirmado que Forgejo corre em sistemas operativos livres, tais como Linux ou FreeBSD, assim como em arquitecturas de CPU diversas. Escolha a sua preferida!
lightweight=Leve
lightweight_desc=Forgejo requer poucos recursos e pode correr num simples Raspberry Pi. Economize a energia da sua mรกquina!
license=Cรณdigo aberto
-license_desc=Vรก buscรก-lo em Forgejo ! Junte-se a nรณs dando a sua contribuiรงรฃo para tornar este programa ainda melhor. Nรฃo se acanhe e contribua!
+license_desc=Vรก buscรก-lo em Forgejo ! Junte-se a nรณs dando a sua contribuiรงรฃo para tornar este programa ainda melhor. Nรฃo se acanhe e contribua!
[install]
install=Instalaรงรฃo
@@ -245,7 +266,7 @@ err_admin_name_is_invalid=O nome de utilizador do administrador รฉ invรกlido
general_title=Configuraรงรตes gerais
app_name=Tรญtulo do sรญtio
-app_name_helper=Pode escrever aqui o nome da sua companhia.
+app_name_helper=Escreva aqui o nome da sua instรขncia. Serรก mostrado em todas as pรกginas.
repo_path=Localizaรงรฃo dos repositรณrios
repo_path_helper=Os repositรณrios Git remotos serรฃo guardados nesta pasta.
lfs_path=Localizaรงรฃo do Git LFS
@@ -398,14 +419,14 @@ forgot_password_title=Esqueci-me da senha
forgot_password=Esqueceu a sua senha?
sign_up_now=Precisa de uma conta? Inscreva-se agora.
sign_up_successful=A conta foi criada com sucesso. Bem-vindo/a!
-confirmation_mail_sent_prompt=Foi enviado um novo email de confirmaรงรฃo para %s . Verifique a sua caixa de entrada dentro de %s para completar o processo de inscriรงรฃo.
+confirmation_mail_sent_prompt=Foi enviado um novo email de confirmaรงรฃo para %s . Para completar o processo de inscriรงรฃo, verifique a sua caixa de entrada e siga a ligaรงรฃo fornecida dentro de %s. Se o email estiver errado, pode iniciar a sessรฃo e pedir que seja enviado outro email de confirmaรงรฃo para um endereรงo diferente.
must_change_password=Mude a sua senha
allow_password_change=Exigir que o utilizador mude a senha (recomendado)
-reset_password_mail_sent_prompt=Foi enviado um email de confirmaรงรฃo para %s . Verifique a sua caixa de entrada dentro de %s para completar o processo de recuperaรงรฃo.
+reset_password_mail_sent_prompt=Foi enviado um email de confirmaรงรฃo para %s . Para completar o processo de recuperaรงรฃo, verifique a sua caixa de entrada e siga a ligaรงรฃo fornecida dentro de %s.
active_your_account=Ponha a sua conta em funcionamento
account_activated=A conta foi posta em funcionamento
-prohibit_login=ร proibido iniciar sessรฃo
-prohibit_login_desc=A sua conta estรก proibida de iniciar sessรฃo. Contacte o administrador.
+prohibit_login=A conta estรก suspensa
+prohibit_login_desc=A sua conta foi suspendida de interagir com a instรขncia. Contacte o administrador da instรขncia para recuperar o acesso.
resent_limit_prompt=Jรก fez um pedido recentemente para enviar um email para pรดr a conta em funcionamento. Espere 3 minutos e tente novamente.
has_unconfirmed_mail=Olรก %s, tem um endereรงo de email nรฃo confirmado (%s ). Se nรฃo recebeu um email de confirmaรงรฃo ou precisa de o voltar a enviar, clique no botรฃo abaixo.
resend_mail=Clique aqui para voltar a enviar um email para pรดr a conta em funcionamento
@@ -453,7 +474,7 @@ authorize_title=Autorizar o acesso de "%s" ร sua conta?
authorization_failed=A autorizaรงรฃo falhou
authorization_failed_desc=A autorizaรงรฃo falhou porque encontrรกmos um pedido invรกlido. Entre em contacto com o responsรกvel pela aplicaรงรฃo que tentou autorizar.
sspi_auth_failed=Falhou a autenticaรงรฃo SSPI
-password_pwned=A senha utilizada estรก numa lista de senhas roubadas anteriormente expostas em fugas de dados pรบblicas. Tente novamente com uma senha diferente e considere tambรฉm mudar esta senha nos outros sรญtios.
+password_pwned=A senha utilizada estรก numa lista de senhas roubadas anteriormente expostas em fugas de dados pรบblicas. Tente novamente com uma senha diferente e considere tambรฉm mudar esta senha nos outros sรญtios.
password_pwned_err=Nรฃo foi possรญvel completar o pedido ao HaveIBeenPwned
last_admin=Nรฃo pode remover o รบltimo administrador. Tem que existir pelo menos um administrador.
change_unconfirmed_email = Se forneceu um endereรงo de email errado durante o registo, pode mudรก-lo abaixo e ser-lhe-รก enviada uma confirmaรงรฃo para o novo endereรงo.
@@ -461,6 +482,13 @@ change_unconfirmed_email_summary = Mudar o endereรงo de email para onde a mensag
tab_signin = Iniciar sessรฃo
tab_signup = Criar conta
change_unconfirmed_email_error = Nรฃo foi possรญvel mudar o endereรงo de email: %v
+hint_login = Jรก tem uma conta? Inicie a sessรฃo agora!
+hint_register = Precisa de uma conta? Faรงa uma inscriรงรฃo agora.
+sign_up_button = Faรงa uma inscriรงรฃo agora.
+back_to_sign_in = Voltar ao iniciar a sessรฃo
+sign_in_openid = Prosseguir com OpenID
+unauthorized_credentials = As credenciais estรฃo erradas ou expiraram. Tente o comando de novo ou veja %s para mais informaรงรฃo
+use_onetime_code = Usar cรณdigo de utilizaรงรฃo รบnica
[mail]
view_it_on=Ver em %s
@@ -477,7 +505,7 @@ activate_email=Valide o seu endereรงo de email
activate_email.title=%s, por favor valide o seu endereรงo de email
activate_email.text=Por favor clique na seguinte ligaรงรฃo para validar o seu endereรงo de email dentro de %s :
-register_notify=Bem-vindo(a) ao Forgejo
+register_notify=Bem-vindo/a ao %s
register_notify.title=%[1]s, bem-vindo(a) a %[2]s
register_notify.text_1=este รฉ o seu email de confirmaรงรฃo de registo para %s!
register_notify.text_2=Pode iniciar a sessรฃo usando o seu nome de utilizador: %s
@@ -530,6 +558,21 @@ team_invite.text_3=Nota: Este convite รฉ dirigido a %[1]s. Se nรฃo estava ร esp
admin.new_user.subject = O novo utilizador %s acabou de criar uma conta
admin.new_user.user_info = Informaรงรฃo do utilizador
admin.new_user.text = Clique aqui para gerir este utilizador a partir do painel de administraรงรฃo.
+totp_disabled.subject = O TOTP foi desabilitado
+totp_disabled.text_1 = A senha de uso รบnico baseada no tempo (TOTP) na sua conta acabou de ser desabilitada.
+totp_disabled.no_2fa = Jรก nรฃo hรก quaisquer outros mรฉtodos 2FA configurados, o que quer dizer que jรก nรฃo รฉ necessรกrio iniciar a sua conta com 2FA.
+removed_security_key.subject = Foi removida uma chave de seguranรงa
+removed_security_key.text_1 = A chave de seguranรงa "%[1]s" acabou de ser removida da sua conta.
+removed_security_key.no_2fa = Jรก nรฃo existem quaisquer outros mรฉtodos 2FA configurados, o que quer dizer que jรก nรฃo รฉ necessรกrio iniciar a sua conta com 2FA.
+account_security_caution.text_1 = Se foi vocรช, pode ignorar este email em seguranรงa.
+account_security_caution.text_2 = Se nรฃo foi vocรช, a sua conta estรก comprometida. Contacte o administrador deste sรญtio.
+totp_enrolled.subject = Habilitou TOTP como mรฉtodo 2FA
+totp_enrolled.text_1.no_webauthn = Acabou de habilitar TOTP para a sua conta. Isso significa que no futuro, ao iniciar sessรฃo na sua conta, vai ter de usar TOTP como um mรฉtodo 2FA.
+totp_enrolled.text_1.has_webauthn = Acabou de habilitar TOTP para a sua conta. Isso significa que no futuro, ao iniciar sessรฃo na sua conta, pode usar TOTP como um mรฉtodo 2FA ou usar uma das suas chaves de seguranรงa.
+primary_mail_change.subject = O seu email principal foi alterado
+password_change.subject = A sua senha foi alterada
+password_change.text_1 = A senha para a sua conta acabou de ser alterada.
+primary_mail_change.text_1 = O email principal da sua conta acabou de ser alterado para %[1]s. Isso quer dizer que este endereรงo de email nรฃo vai mais receber notificaรงรตes de email relativas ร sua conta.
[modal]
yes=Sim
@@ -642,6 +685,8 @@ AccessToken = Cรณdigo de acesso
FullName = Nome completo
Description = Descriรงรฃo
Pronouns = Pronomes
+username_claiming_cooldown = O nome de utilizador nรฃo pode ser reivindicado, porque o perรญodo de espera do mesmo ainda nรฃo terminou. Pode ser reivindicado em %[1]s.
+email_domain_is_not_allowed = O domรญnio do endereรงo de email %s do utilizador entra em conflito com EMAIL_DOMAIN_ALLOWLIST ou EMAIL_DOMAIN_BLOCKLIST. Certifique-se de que definiu corretamente o endereรงo de email.
[user]
change_avatar=Mude o seu avatarโฆ
@@ -671,12 +716,21 @@ block = Bloquear
unblock = Desbloquear
followers_one = %d seguidor
following_one = %d seguindo
-block_user.detail = Note que se bloquear este utilizador, serรฃo executadas outras operaรงรตes, tais como:
-block_user.detail_1 = Estรก a deixar de ser seguido/a por este utilizador.
-block_user.detail_2 = Este utilizador nรฃo pode interagir com os seus repositรณrios, questรตes criadas e comentรกrios.
-block_user.detail_3 = Este/a utilizador/a nรฃo o/a pode adicionar como colaborador/a nem vocรช pode o/a adicionar como colaborador/a.
+block_user.detail = Repare que bloquear um utilizador tem outros efeitos, tais como:
+block_user.detail_1 = Irรฃo deixar de seguir um ao outro e deixarรฃo de poder seguir um ao outro.
+block_user.detail_2 = Este/a utilizador/a deixarรก de poder interagir com os seus repositรณrios ou com as questรตes e comentรกrios criados por si.
+block_user.detail_3 = Nรฃo poderรฃo adicionar um ao outro como colaboradores do repositรณrio.
follow_blocked_user = Nรฃo pode seguir este/a utilizador/a porque vocรช o/a bloqueou ou este/a utilizador/a bloqueou-o/a a si.
block_user = Bloquear utilizador
+followers.title.one = Seguidor
+followers.title.few = Seguidores
+following.title.one = Seguindo
+following.title.few = Seguindo
+public_activity.visibility_hint.self_public = O seu trabalho estรก visรญvel para todos, salvo o que รฉ feito em espaรงos privados. Configurar .
+public_activity.visibility_hint.admin_public = Este trabalho estรก visรญvel para todos, mas como administrador/a pode tambรฉm ver o que consta em espaรงos privados.
+public_activity.visibility_hint.self_private = O seu trabalho apenas estรก visรญvel para si e para os administradores da instรขncia. Configurar .
+public_activity.visibility_hint.admin_private = Este trabalho estรก visรญvel para si porque รฉ um/a administrador/a, mas o/a utilizador/a quer permanecer privado/a.
+public_activity.visibility_hint.self_private_profile = O seu trabalho estรก visรญvel somente para si e para os administradores da instรขncia porque o seu perfil รฉ privado. Configure .
[settings]
profile=Perfil
@@ -698,9 +752,9 @@ uid=UID
webauthn=Autenticaรงรฃo em dois passos (chaves de seguranรงa)
public_profile=Perfil pรบblico
-biography_placeholder=Conte-nos um pouco sobre si! (Pode usar Markdown)
+biography_placeholder=Diga aos outros um pouco sobre si! (Markdown รฉ suportado)
location_placeholder=Partilhe a sua localizaรงรฃo aproximada com outros
-profile_desc=Controle como o seu perfil รฉ apresentado aos outros utilizadores. O seu endereรงo de email principal serรก usado para notificaรงรตes, recuperaรงรฃo de senha e operaรงรตes Git baseadas na web.
+profile_desc=Sobre si
password_username_disabled=Utilizadores nรฃo-locais nรฃo podem mudar os seus nomes de utilizador. Entre em contacto com o administrador do sรญtio saber para mais detalhes.
full_name=Nome completo
website=Sรญtio web
@@ -757,7 +811,7 @@ old_password=Senha corrente
new_password=Nova senha
retype_new_password=Confirme a nova senha
password_incorrect=A senha corrente estรก errada.
-change_password_success=A sua senha foi substituรญda. Inicie a sessรฃo com a nova senha a partir de agora.
+change_password_success=A sua senha foi atualizada. A partir de agora, utilize a sua nova senha para iniciar sessรฃo.
password_change_disabled=Os utilizadores nรฃo-locais nรฃo podem alterar a sua senha atravรฉs da interface web do Forgejo.
emails=Endereรงos de email
@@ -765,7 +819,7 @@ manage_emails=Gerir endereรงos de email
manage_themes=Tema padrรฃo
manage_openid=Endereรงos OpenID
email_desc=O seu endereรงo de email principal irรก ser usado para notificaรงรตes, recuperaรงรฃo de senha e, desde que nรฃo esteja oculto, operaรงรตes Git baseados na web.
-theme_desc=Este serรก o seu tema padrรฃo em todo o sรญtio.
+theme_desc=Este tema serรก usado para a interface web quando tiver sessรฃo iniciada.
primary=Principal
activated=Em uso
requires_activation=Tem que ser habilitado
@@ -786,12 +840,12 @@ add_new_email=Adicionar endereรงo de email
add_new_openid=Adicionar novo URI OpenID
add_email=Adicionar endereรงo de email
add_openid=Adicionar URI OpenID
-add_email_confirmation_sent=Um email de confirmaรงรฃo foi enviado para "%s". Verifique a sua caixa de entrada dentro de %s para confirmar o seu endereรงo de email.
+add_email_confirmation_sent=Foi enviado um email de confirmaรงรฃo para "%s". Para confirmar o seu endereรงo de email, verifique a sua caixa de entrada e siga a ligaรงรฃo fornecida dentro de %s.
add_email_success=O novo endereรงo de email foi adicionado.
email_preference_set_success=As preferรชncias relativas ao email foram definidas com sucesso.
add_openid_success=O novo endereรงo OpenID foi adicionado.
keep_email_private=Ocultar endereรงo de email
-keep_email_private_popup=Isto irรก ocultar o seu endereรงo de email no seu perfil, assim como quando fizer um pedido de integraรงรฃo ou editar um ficheiro usando a interface web. Cometimentos enviados nรฃo serรฃo modificados.
+keep_email_private_popup=O seu endereรงo de e-mail nรฃo serรก mostrado no seu perfil e nรฃo serรก o predefinido para cometimentos feitos atravรฉs da interface web, tais como upload de arquivos, ediรงรตes e cometimentos de integraรงรฃo. Ao invรฉs disso, um endereรงo especial %s poderรก ser usado para vincular cometimentos ร sua conta. Esta opรงรฃo nรฃo irรก alterar os cometimentos existentes.
openid_desc=O OpenID permite delegar a autenticaรงรฃo num fornecedor externo.
manage_ssh_keys=Gerir chaves SSH
@@ -894,7 +948,7 @@ select_permissions=Escolher permissรตes
permission_no_access=Sem acesso
permission_read=Lidas
permission_write=Leitura e escrita
-access_token_desc=As permissรตes dos cรณdigos escolhidos limitam a autorizaรงรฃo apenas ร s rotas da API correspondentes. Leia a documentaรงรฃo para obter mais informaรงรฃo.
+access_token_desc=As permissรตes dos cรณdigos escolhidos limitam a autorizaรงรฃo apenas ร s rotas da API correspondentes. Leia a documentaรงรฃo para obter mais informaรงรฃo.
at_least_one_permission=Tem que escolher pelo menos uma permissรฃo para criar um cรณdigo
permissions_list=Permissรตes:
@@ -948,7 +1002,7 @@ passcode_invalid=O cรณdigo estรก errado. Tente de novo.
twofa_enrolled=A sua conta usa autenticaรงรฃo em dois passos. Guarde o seu cรณdigo de recuperaรงรฃo (%s) num lugar seguro porque รฉ mostrado somente uma vez!
twofa_failed_get_secret=Falhou a obtenรงรฃo do segredo.
-webauthn_desc=Chaves de seguranรงa sรฃo dispositivos de hardware contendo chaves criptogrรกficas. Podem ser usadas para autenticaรงรฃo em dois passos. As chaves de seguranรงa tรชm de suportar o standard Autenticador WebAuthn .
+webauthn_desc=Chaves de seguranรงa sรฃo dispositivos de hardware contendo chaves criptogrรกficas. Podem ser usadas para autenticaรงรฃo em dois passos. As chaves de seguranรงa tรชm de suportar o standard Autenticador WebAuthn .
webauthn_register_key=Adicionar chave de seguranรงa
webauthn_nickname=Apelido
webauthn_delete_key=Remover chave de seguranรงa
@@ -986,7 +1040,7 @@ visibility=Visibilidade do utilizador
visibility.public=Pรบblica
visibility.public_tooltip=Visรญvel para todos
visibility.limited=Limitada
-visibility.limited_tooltip=Visรญvel apenas para utilizadores autenticados
+visibility.limited_tooltip=Visรญvel apenas para utilizadores registados
visibility.private=Privada
visibility.private_tooltip=Visรญvel apenas para membros das organizaรงรตes a que se associou
additional_repo_units_hint = Sugere a habilitaรงรฃo de unidades do repositรณrio adicionais
@@ -999,11 +1053,44 @@ hints = Sugestรตes
blocked_users = Utilizadores bloqueados
blocked_since = Bloqueado desde %s
user_block_success = O utilizador foi bloqueado com sucesso.
-additional_repo_units_hint_description = Mostrar um botรฃo "Adicionar mais unidades..." para repositรณrios que nรฃo tรชm todas as unidades disponรญveis habilitadas.
+additional_repo_units_hint_description = Mostrar uma sugestรฃo "Habilitar mais" para repositรณrios que nรฃo tรชm todas as unidades disponรญveis habilitadas.
update_hints_success = As sugestรตes foram modificadas.
blocked_users_none = Nรฃo hรก utilizadores bloqueados.
user_unblock_success = O utilizador foi desbloqueado com sucesso.
language.title = Idioma predefinido
+keep_activity_private.description = O seu trabalho pรบblico apenas estarรก visรญvel para si e para os administradores da instรขncia.
+language.description = Este idioma vai ser guardado na sua conta e ser usado como o predefinido depois de iniciar sessรฃo.
+language.localization_project = Ajude-nos a traduzir o Forgejo para o seu idioma! Saiba mais .
+pronouns_custom_label = Pronomes personalizados
+user_block_yourself = Nรฃo se pode bloquear a si prรณprio.
+change_username_redirect_prompt.with_cooldown.one = O nome de utilizador antigo estarรก disponรญvel para todos apรณs um perรญodo de espera de %[1]d dia, podendo ainda reivindicar o nome de utilizador antigo durante o perรญodo de espera.
+change_username_redirect_prompt.with_cooldown.few = O nome de utilizador antigo ficarรก disponรญvel para todos apรณs um perรญodo de espera de %[1]d dias, podendo ainda reivindicar o nome de utilizador antigo durante o perรญodo de espera.
+quota.applies_to_user = As seguintes regras de quotas aplicam-se ร sua conta
+quota.sizes.assets.artifacts = Artefactos
+quota.rule.exceeded.helper = O tamanho total dos objectos para esta regra excedeu a quota.
+keep_pronouns_private = Mostrar os pronomes apenas aos utilizadores autenticados
+keep_pronouns_private.description = Isto irรก ocultar os seus pronomes dos visitantes que nรฃo tenham iniciado sessรฃo.
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.all = Ativos
+storage_overview = Panorama geral do armazenamento
+quota = Quota
+quota.applies_to_org = As seguintes regras de quotas aplicam-se a esta organizaรงรฃo
+quota.rule.exceeded = Excedido
+quota.rule.no_limit = Ilimitado
+quota.sizes.all = Tudo
+quota.sizes.repos.all = Repositรณrios
+quota.sizes.repos.public = Repositรณrios pรบblicos
+quota.sizes.repos.private = Repositรณrios privados
+quota.sizes.git.all = Conteรบdo Git
+quota.sizes.assets.attachments.all = Anexos
+quota.sizes.assets.attachments.issues = Anexos de questรตes
+quota.sizes.assets.attachments.releases = Anexos de lanรงamentos
+quota.sizes.assets.packages.all = Pacotes
+quota.sizes.wiki = Wiki
+access_token_regeneration = Regenerar cรณdigo de acesso
+regenerate_token_success = O cรณdigo foi regenerado. As aplicaรงรตes que o utilizam jรก nรฃo tรชm acesso ร sua conta e devem ser atualizadas com o novo cรณdigo.
+regenerate_token = Regenerar
+access_token_regeneration_desc = A regeneraรงรฃo de um cรณdigo irรก revogar o acesso ร sua conta para as aplicaรงรตes que o utilizam. Isto nรฃo pode ser anulado. Continuar?
[repo]
new_repo_helper=Um repositรณrio contรฉm todos os ficheiros do trabalho, incluindo o histรณrico das revisรตes. Jรก tem um hospedado noutro sรญtio? Migre o repositรณrio .
@@ -1013,7 +1100,7 @@ repo_name=Nome do repositรณrio
repo_name_helper=Um bom nome de repositรณrio utiliza palavras curtas, memorรกveis e รบnicas.
repo_size=Tamanho do repositรณrio
template=Modelo
-template_select=Escolha um modelo.
+template_select=Escolha um modelo
template_helper=Fazer do repositรณrio um modelo
template_description=Repositรณrios modelo permitem que os utilizadores gerem novos repositรณrios com a mesma estrutura de pastas, ficheiros e configuraรงรตes opcionais.
visibility=Visibilidade
@@ -1040,19 +1127,19 @@ generate_from=Gerar a partir de
repo_desc=Descriรงรฃo
repo_desc_helper=Insira uma descriรงรฃo curta (opcional)
repo_lang=Idioma
-repo_gitignore_helper=Escolher modelos .gitignore.
+repo_gitignore_helper=Escolher modelos .gitignore
repo_gitignore_helper_desc=Escolha os ficheiros que nรฃo sรฃo para rastrear, a partir de uma lista de modelos de linguagens comuns. Serรฃo incluรญdos no ficheiro .gitignore, logo ร partida, artefactos tรญpicos gerados pelas ferramentas de construรงรฃo de cada uma das linguagens.
-issue_labels=Rรณtulos para as questรตes
-issue_labels_helper=Escolha um conjunto de rรณtulos para as questรตes.
+issue_labels=Rรณtulos
+issue_labels_helper=Escolha um conjunto de rรณtulos
license=Licenรงa
-license_helper=Escolha um ficheiro de licenรงa.
-license_helper_desc=Uma licenรงa rege o que os outros podem, ou nรฃo, fazer com o seu cรณdigo fonte. Nรฃo tem a certeza sobre qual a mais indicada para o seu trabalho? Veja: Escolher uma licenรงa.
+license_helper=Escolha um ficheiro de licenรงa
+license_helper_desc=Uma licenรงa rege o que os outros podem, ou nรฃo, fazer com o seu cรณdigo fonte. Nรฃo tem a certeza sobre qual a mais indicada para o seu trabalho? Veja: Escolher uma licenรงa .
object_format=Formato dos elementos
object_format_helper=Formato dos elementos do repositรณrio. Nรฃo poderรก ser alterado mais tarde. SHA1 รฉ o mais compatรญvel.
readme=README
-readme_helper=Escolha um modelo de ficheiro README.
+readme_helper=Escolha um modelo de ficheiro README
readme_helper_desc=Este รฉ o sรญtio onde pode escrever uma descriรงรฃo completa do seu trabalho.
-auto_init=Inicializar repositรณrio (adiciona `.gitignore`, `LICENSE` e `README.md`)
+auto_init=Inicializar repositรณrio
trust_model_helper=Escolha o modelo de confianรงa para a validaรงรฃo das assinaturas. As opรงรตes sรฃo:
trust_model_helper_collaborator=Colaborador: Confiar nas assinaturas dos colaboradores
trust_model_helper_committer=Autor do cometimento: Confiar nas assinaturas que correspondem a autores de cometimentos
@@ -1087,7 +1174,7 @@ forks=Derivaรงรตes
reactions_more=e mais %d
unit_disabled=O administrador desabilitou esta secรงรฃo do repositรณrio.
language_other=Outros
-adopt_search=Insira o nome de utilizador para procurar repositรณrios adoptados... (deixe em branco para encontrar todos)
+adopt_search=Insira o nome de utilizador para procurar repositรณrios nรฃo adotadosโฆ (deixe em branco para encontrar todos)
adopt_preexisting_label=Usar ficheiros
adopt_preexisting=Adoptar ficheiros prรฉ-existentes
adopt_preexisting_content=Criar repositรณrio a partir de %s
@@ -1130,8 +1217,8 @@ template.issue_labels=Rรณtulos das questรตes
template.one_item=Tem que escolher pelo menos um item do modelo
template.invalid=Tem que escolher um repositรณrio modelo
-archive.title=Este repositรณrio estรก arquivado. Pode ver os seus ficheiros e clonรก-lo, mas nรฃo pode fazer envios para o repositรณrio nem lanรงar questรตes ou fazer pedidos de integraรงรฃo.
-archive.title_date=Este repositรณrio foi arquivado em %s. Pode ver os ficheiros e clonรก-lo, mas nรฃo pode fazer envios ou abrir questรตes/pedidos de integraรงรฃo.
+archive.title=Este repositรณrio estรก arquivado. Pode ver os ficheiros e clonรก-lo, mas nรฃo pode fazer quaisquer alteraรงรตes ao seu estado, tais como fazer envios e criar novas questรตes, pedidos de integraรงรฃo ou comentรกrios.
+archive.title_date=Este repositรณrio foi arquivado em %s. Pode ver os ficheiros e clonรก-lo, mas nรฃo pode fazer quaisquer alteraรงรตes ao seu estado, tais como fazer envios e criar novas questรตes, pedidos de integraรงรฃo ou comentรกrios.
archive.issue.nocomment=Este repositรณrio estรก arquivado. Nรฃo pode comentar nas questรตes.
archive.pull.nocomment=Este repositรณrio estรก arquivado. Nรฃo pode comentar nos pedidos de integraรงรฃo.
@@ -1171,14 +1258,14 @@ migrate.migrate_items_options=ร necessรกrio um cรณdigo de acesso para migrar it
migrated_from=Migrado de %[2]s
migrated_from_fake=Migrado de %[1]s
migrate.migrate=Migrar de %s
-migrate.migrating=Migrando a partir de %s ...
+migrate.migrating=Migrando a partir de %s โฆ
migrate.migrating_failed=A migraรงรฃo de %s falhou.
migrate.migrating_failed.error=Falhou a migraรงรฃo: %s
migrate.migrating_failed_no_addr=A migraรงรฃo falhou.
migrate.github.description=Migrar dados do github.com ou do GitHub Enterprise server.
migrate.git.description=Migrar um repositรณrio somente de qualquer serviรงo Git.
migrate.gitlab.description=Migrar dados de gitlab.com ou de outras instรขncias do GitLab.
-migrate.gitea.description=Migrar dados de gitea.com ou de outras instรขncias do Gitea/Forgejo.
+migrate.gitea.description=Migrar dados de gitea.com ou de outras instรขncias do Gitea.
migrate.gogs.description=Migrar dados de notabug.org ou de outras instรขncias do Gogs.
migrate.onedev.description=Migrar dados de code.onedev.io ou de outras instรขncias do OneDev.
migrate.codebase.description=Migrar dados de codebasehq.com.
@@ -1266,6 +1353,7 @@ view_git_blame=Ver git blame
video_not_supported_in_browser=O seu navegador nรฃo suporta a etiqueta "video" do HTML5.
audio_not_supported_in_browser=O seu navegador nรฃo suporta a etiqueta "audio" do HTML5.
stored_lfs=Armazenado com Git LFS
+stored_annex=Armazenado com Git Annex
symbolic_link=Ligaรงรฃo simbรณlica
executable_file=Ficheiro executรกvel
vendored=Externo
@@ -1291,6 +1379,7 @@ editor.upload_file=Carregar ficheiro
editor.edit_file=Editar ficheiro
editor.preview_changes=Prรฉ-visualizar modificaรงรตes
editor.cannot_edit_lfs_files=Ficheiros LFS nรฃo podem ser editados na interface web.
+editor.cannot_edit_annex_files=Ficheiros Annex nรฃo podem ser editados na interface web.
editor.cannot_edit_non_text_files=Ficheiros binรกrios nรฃo podem ser editados na interface da web.
editor.edit_this_file=Editar ficheiro
editor.this_file_locked=Ficheiro bloqueado
@@ -1305,7 +1394,7 @@ editor.or=ou
editor.cancel_lower=Cancelar
editor.commit_signed_changes=Cometer modificaรงรตes assinadas
editor.commit_changes=Cometer modificaรงรตes
-editor.add_tmpl=Adicionar ""
+editor.add_tmpl=Adicionar "<%s>"
editor.add=Adicionar %s
editor.update=Modificar %s
editor.delete=Eliminar %s
@@ -1315,7 +1404,7 @@ editor.fail_to_apply_patch=`Nรฃo foi possรญvel aplicar o remendo (patch) "%s"`
editor.new_patch=Novo remendo (patch)
editor.commit_message_desc=Adicionar uma descriรงรฃo alargada opcionalโฆ
editor.signoff_desc=Adicionar "Assinado-por" seguido do autor do cometimento no fim da mensagem do registo de cometimentos.
-editor.commit_directly_to_this_branch=Cometer imediatamente no ramo %s .
+editor.commit_directly_to_this_branch=Cometer imediatamente no ramo %[1]s .
editor.create_new_branch=Crie um novo ramo para este cometimento e inicie um pedido de integraรงรฃo.
editor.create_new_branch_np=Criar um novo ramo para este cometimento.
editor.propose_file_change=Propor modificaรงรฃo do ficheiro
@@ -1331,7 +1420,7 @@ editor.file_is_a_symlink=`"%s" รฉ uma ligaรงรฃo simbรณlica. Ligaรงรตes simbรณlic
editor.filename_is_a_directory=O nome de ficheiro "%s" jรก estรก a ser usado como um nome de pasta neste repositรณrio.
editor.file_editing_no_longer_exists=O ficheiro que estรก a ser editado, "%s", jรก nรฃo existe neste repositรณrio.
editor.file_deleting_no_longer_exists=O ficheiro que estรก a ser eliminado, "%s", jรก nรฃo existe neste repositรณrio.
-editor.file_changed_while_editing=O conteรบdo do ficheiro mudou desde que comeรงou a editar. Clique aqui para ver as modificaรงรตes ou clique em Cometer modificaรงรตes novamente para escrever por cima.
+editor.file_changed_while_editing=O conteรบdo do ficheiro mudou desde que abriu o ficheiro. Clique aqui para ver as modificaรงรตes ou Cometer modificaรงรตes novamente para escrever por cima.
editor.file_already_exists=Jรก existe um ficheiro com o nome "%s" neste repositรณrio.
editor.commit_empty_file_header=Cometer um ficheiro vazio
editor.commit_empty_file_text=O ficheiro que estรก prestes a cometer estรก vazio. Quer continuar?
@@ -1385,7 +1474,7 @@ commitstatus.failure=Falha
commitstatus.pending=Pendente
commitstatus.success=Sucesso
-ext_issues=Acesso a questรตes externas
+ext_issues=Questรตes externas
ext_issues.desc=Ligaรงรฃo para um rastreador de questรตes externo.
projects=Planeamentos
@@ -1566,17 +1655,17 @@ issues.no_content=Nenhuma descriรงรฃo fornecida.
issues.close=Encerrar questรฃo
issues.comment_pull_merged_at=cometimento %[1]s integrado em %[2]s %[3]s
issues.comment_manually_pull_merged_at=cometimento %[1]s integrado manualmente em %[2]s %[3]s
-issues.close_comment_issue=Comentar e fechar
+issues.close_comment_issue=Fechar com comentรกrio
issues.reopen_issue=Reabrir
-issues.reopen_comment_issue=Comentar e reabrir
+issues.reopen_comment_issue=Reabrir com comentรกrio
issues.create_comment=Comentar
issues.closed_at=`encerrou esta questรฃo %[2]s `
issues.reopened_at=`reabriu esta questรฃo %[2]s `
issues.commit_ref_at=`referenciou esta questรฃo num cometimento %[2]s `
issues.ref_issue_from=`referiu esta questรฃo %[4]s %[2]s `
issues.ref_pull_from=`referiu este pedido de integraรงรฃo %[4]s %[2]s `
-issues.ref_closing_from=`referiu um pedido de integraรงรฃo %[4]s que fecharรก esta questรฃo %[2]s `
-issues.ref_reopening_from=`referiu um pedido de integraรงรฃo %[4]s que reabrirรก esta questรฃo %[2]s `
+issues.ref_closing_from=`referiu esta questรฃo a partir de um pedido de integraรงรฃo %[4]s que a fecharรก %[2]s `
+issues.ref_reopening_from=`referiu esta questรฃo a partir de um pedido de integraรงรฃo %[4]s que a reabrirรก %[2]s `
issues.ref_closed_from=`encerrou esta questรฃo %[4]s %[2]s `
issues.ref_reopened_from=`reabriu esta questรฃo %[4]s %[2]s `
issues.ref_from=`de %[1]s`
@@ -1681,9 +1770,9 @@ issues.error_modifying_due_date=Falhou a modificaรงรฃo da data de vencimento.
issues.error_removing_due_date=Falhou a remoรงรฃo da data de vencimento.
issues.push_commit_1=adicionou %d cometimento %s
issues.push_commits_n=adicionou %d cometimentos %s
-issues.force_push_codes=`forรงou o envio %[1]s de %[2]s
para %[4]s
%[6]s`
+issues.force_push_codes=`forรงou o envio %[1]s de %[2]s
para %[4]s
%[6]s`
issues.force_push_compare=Comparar
-issues.due_date_form=yyyy-mm-dd
+issues.due_date_form=aaaa-mm-dd
issues.due_date_form_add=Adicionar data de vencimento
issues.due_date_form_edit=Editar
issues.due_date_form_remove=Remover
@@ -1735,8 +1824,8 @@ issues.review.left_comment=deixou um comentรกrio
issues.review.content.empty=Tem que deixar um comentรกrio indicando a(s) modificaรงรฃo(รตes) solicitada(s).
issues.review.reject=modificaรงรตes solicitadas %s
issues.review.wait=foi solicitada para revisรฃo %s
-issues.review.add_review_request=solicitou revisรฃo de %s %s
-issues.review.remove_review_request=removeu a solicitaรงรฃo de revisรฃo para %s %s
+issues.review.add_review_request=solicitou revisรฃo de %[1]s %[2]s
+issues.review.remove_review_request=removeu a solicitaรงรฃo de revisรฃo para %[1]s %[2]s
issues.review.remove_review_request_self=recusou-se a rever %s
issues.review.pending=Pendente
issues.review.pending.tooltip=Este comentรกrio nรฃo estรก visรญvel para os outros utilizadores, neste momento. Para submeter os seus comentรกrios pendentes, escolha "%s" โ "%s/%s/%s" no topo da pรกgina.
@@ -1797,7 +1886,7 @@ pulls.nothing_to_compare_have_tag=O ramo/etiqueta escolhidos sรฃo iguais.
pulls.nothing_to_compare_and_allow_empty_pr=Estes ramos sรฃo iguais. Este pedido de integraรงรฃo ficarรก vazio.
pulls.has_pull_request=`Jรก existe um pedido de integraรงรฃo entre estes ramos: %[2]s#%[3]d `
pulls.create=Criar um pedido de integraรงรฃo
-pulls.title_desc_few=quer integrar %[1]d cometimento(s) do ramo %[2]s
no ramo %[3]s
+pulls.title_desc_few=quer integrar %[1]d cometimento(s) do ramo %[2]s
no ramo %[3]s
pulls.merged_title_desc_few=integrou %[1]d cometimento(s) do ramo %[2]s
no ramo %[3]s
%[4]s
pulls.change_target_branch_at=`mudou o ramo de destino de %s para %s %s`
pulls.tab_conversation=Diรกlogo
@@ -1887,7 +1976,7 @@ pulls.outdated_with_base_branch=Este ramo รฉ obsoleto em relaรงรฃo ao ramo base
pulls.close=Encerrar pedido de integraรงรฃo
pulls.closed_at=`fechou este pedido de integraรงรฃo %[2]s `
pulls.reopened_at=`reabriu este pedido de integraรงรฃo %[2]s `
-pulls.cmd_instruction_hint=`Ver instruรงรตes para a linha de comandos .`
+pulls.cmd_instruction_hint=Ver instruรงรตes para a linha de comandos
pulls.cmd_instruction_checkout_title=Conferir
pulls.cmd_instruction_checkout_desc=No seu repositรณrio, irรก criar um novo ramo para que possa testar as modificaรงรตes.
pulls.cmd_instruction_merge_title=Integrar
@@ -1958,7 +2047,7 @@ signing.wont_sign.commitssigned=A integraรงรฃo nรฃo irรก ser assinada, uma vez q
signing.wont_sign.approved=A integraรงรฃo nรฃo irรก ser assinada, uma vez que o pedido de integraรงรฃo nรฃo foi assinado.
signing.wont_sign.not_signed_in=Nรฃo tem a sessรฃo iniciada.
-ext_wiki=Acesso a wiki externo
+ext_wiki=Wiki externo
ext_wiki.desc=Ligaรงรฃo para um wiki externo.
wiki=Wiki
@@ -2033,7 +2122,7 @@ activity.unresolved_conv_label=Em aberto
activity.title.releases_1=%d lanรงamento
activity.title.releases_n=%d lanรงamentos
activity.title.releases_published_by=%s publicado por %s
-activity.published_release_label=Publicado
+activity.published_release_label=Lanรงamento
activity.no_git_activity=Nรฃo houve quaisquer cometimentos feitos durante este perรญodo.
activity.git_stats_exclude_merges=Excluindo integraรงรตes,
activity.git_stats_author_1=%d autor
@@ -2288,39 +2377,39 @@ settings.event_push_desc=Envio do Git para um repositรณrio.
settings.event_repository=Repositรณrio
settings.event_repository_desc=Repositรณrio criado ou eliminado.
settings.event_header_issue=Eventos da questรฃo
-settings.event_issues=Questรตes
+settings.event_issues=Modificaรงรฃo
settings.event_issues_desc=Questรฃo aberta, fechada, reaberta ou editada.
-settings.event_issue_assign=Questรฃo atribuรญda
+settings.event_issue_assign=Atribuiรงรฃo
settings.event_issue_assign_desc=Encarregado atribuรญdo ou retirado ร questรฃo.
-settings.event_issue_label=Questรฃo com rรณtulo
-settings.event_issue_label_desc=Rรณtulos modificados ou retirados ร s questรตes.
-settings.event_issue_milestone=Questรฃo com etapa atribuรญda
-settings.event_issue_milestone_desc=Etapa atribuรญda ou retirada ร questรฃo.
-settings.event_issue_comment=Comentรกrio da questรฃo
+settings.event_issue_label=Rรณtulos
+settings.event_issue_label_desc=Rรณtulos adicionados ou retirados ร s questรตes.
+settings.event_issue_milestone=Etapas
+settings.event_issue_milestone_desc=Etapa atribuรญda, removida ou modificada.
+settings.event_issue_comment=Comentรกrios
settings.event_issue_comment_desc=Comentรกrio da questรฃo criado, editado ou eliminado.
settings.event_header_pull_request=Eventos de pedidos de integraรงรฃo
-settings.event_pull_request=Pedido de integraรงรฃo
+settings.event_pull_request=Modificaรงรฃo
settings.event_pull_request_desc=Pedido de integraรงรฃo aberto, fechado, reaberto ou editado.
-settings.event_pull_request_assign=Encarregado atribuรญdo ao pedido de integraรงรฃo
+settings.event_pull_request_assign=Atribuiรงรฃo
settings.event_pull_request_assign_desc=Encarregado atribuรญdo ou retirado ao pedido de integraรงรฃo.
-settings.event_pull_request_label=Rรณtulo atribuรญdo ao pedido de integraรงรฃo
-settings.event_pull_request_label_desc=Rรณtulos modificados ou retirados aos pedidos de integraรงรฃo.
-settings.event_pull_request_milestone=Etapa atribuรญda ao pedido de integraรงรฃo
-settings.event_pull_request_milestone_desc=Etapa atribuรญda ou retirada ao pedido de integraรงรฃo.
-settings.event_pull_request_comment=Comentรกrio do pedido de integraรงรฃo
+settings.event_pull_request_label=Rรณtulos
+settings.event_pull_request_label_desc=Rรณtulos adicionados ou retirados aos pedidos de integraรงรฃo.
+settings.event_pull_request_milestone=Etapas
+settings.event_pull_request_milestone_desc=Etapas adicionadas, removidas ou modificadas.
+settings.event_pull_request_comment=Comentรกrios
settings.event_pull_request_comment_desc=Comentรกrio do pedido de integraรงรฃo criado, editado ou eliminado.
-settings.event_pull_request_review=Pedido de integraรงรฃo revisto
+settings.event_pull_request_review=Revisรตes
settings.event_pull_request_review_desc=Pedido de integraรงรฃo aprovado, rejeitado ou comentado na revisรฃo.
-settings.event_pull_request_sync=Pedido de integraรงรฃo sincronizado
-settings.event_pull_request_sync_desc=Pedido de integraรงรฃo sincronizado.
-settings.event_pull_request_review_request=Solicitada a revisรฃo do pedido de integraรงรฃo
+settings.event_pull_request_sync=Sincronizado
+settings.event_pull_request_sync_desc=Ramo sincronizado automaticamente com o ramo de destino.
+settings.event_pull_request_review_request=Pedidos de revisรฃo
settings.event_pull_request_review_request_desc=A revisรฃo do pedido de integraรงรฃo foi solicitada ou a solicitaรงรฃo de revisรฃo foi removida.
settings.event_pull_request_approvals=Aprovaรงรตes do pedido de integraรงรฃo
settings.event_pull_request_merge=Integraรงรฃo constante no pedido
settings.event_package=Pacote
settings.event_package_desc=Pacote criado ou eliminado num repositรณrio.
settings.branch_filter=Filtro de ramos
-settings.branch_filter_desc=Lista dos ramos a serem considerados nos eventos de envio e de criaรงรฃo e eliminaรงรฃo de ramos, especificada como um padrรฃo glob. Se estiver em branco ou for *
, serรฃo reportados eventos para todos os ramos. Veja a documentaรงรฃo github.com/gobwas/glob para ver os detalhes da sintaxe. Exemplos: trunk
, {trunk,release*}
.
+settings.branch_filter_desc=Lista dos ramos a serem considerados nos eventos de envio e de criaรงรฃo e eliminaรงรฃo de ramos, especificada como um padrรฃo glob. Se estiver em branco ou for *
, serรฃo reportados eventos para todos os ramos. Veja a documentaรงรฃo %[2]s para ver os detalhes da sintaxe. Exemplos: trunk
, {trunk,release*}
.
settings.authorization_header=Cabeรงalho de autorizaรงรฃo
settings.authorization_header_desc=Serรก incluรญdo como cabeรงalho de autorizaรงรฃo para pedidos, quando estiver presente. Exemplos: %s.
settings.active=Em funcionamento
@@ -2385,28 +2474,28 @@ settings.protect_enable_merge_desc=Qualquer pessoa com permissรฃo de escrita tem
settings.protect_whitelist_committers=Lista de permissรตes para restringir os envios
settings.protect_whitelist_committers_desc=Apenas os utilizadores ou equipas constantes na lista terรฃo permissรฃo para enviar para este ramo (mas nรฃo poderรฃo fazer envios forรงados).
settings.protect_whitelist_deploy_keys=Dar permissรฃo ร s chaves de instalaรงรฃo para terem acesso de escrita para enviar.
-settings.protect_whitelist_users=Utilizadores com permissรฃo para enviar:
+settings.protect_whitelist_users=Utilizadores com permissรฃo para enviar
settings.protect_whitelist_search_users=Procurar utilizadoresโฆ
-settings.protect_whitelist_teams=Equipas com permissรฃo para enviar:
+settings.protect_whitelist_teams=Equipas com permissรฃo para enviar
settings.protect_whitelist_search_teams=Procurar equipasโฆ
settings.protect_merge_whitelist_committers=Habilitar lista de permissรฃo para integrar
settings.protect_merge_whitelist_committers_desc=Permitir que somente utilizadores ou equipas constantes na lista de permissรฃo possam executar, neste ramo, integraรงรตes constantes em pedidos de integraรงรฃo.
-settings.protect_merge_whitelist_users=Utilizadores com permissรฃo para executar integraรงรตes:
-settings.protect_merge_whitelist_teams=Equipas com permissรฃo para executar integraรงรตes:
+settings.protect_merge_whitelist_users=Utilizadores com permissรฃo para executar integraรงรตes
+settings.protect_merge_whitelist_teams=Equipas com permissรฃo para executar integraรงรตes
settings.protect_check_status_contexts=Habilitar verificaรงรฃo de estado
-settings.protect_status_check_patterns=Padrรตes de verificaรงรฃo de estado:
+settings.protect_status_check_patterns=Padrรตes de verificaรงรฃo de estado
settings.protect_status_check_patterns_desc=Insira padrรตes para especificar que verificaรงรตes de estado tรชm de passar antes que os ramos possam ser integrados num ramo correspondente a esta regra. Cada linha especifรญca um padrรฃo. Os padrรตes nรฃo podem estar em branco.
settings.protect_check_status_contexts_desc=Exigir que as verificaรงรตes de estado passem antes de ser aplicada a integraรงรฃo. Escolha quais as verificaรงรตes de estado que tรชm de passar para que os ramos possam ser integrados num ramo que corresponda a esta regra. Quando habilitado, os cometimentos primeiro tรชm de ser enviados para outro ramo e depois integrados, ou entรฃo enviados imediatamente para um ramo que corresponda a esta regra, apรณs terem passado as verificaรงรตes de estado. Se nรฃo forem escolhidos quaisquer contextos, o รบltimo cometimento tem que ser bem sucedido, independentemente do contexto.
settings.protect_check_status_contexts_list=Verificaรงรตes de estado encontradas na รบltima semana para este repositรณrio
settings.protect_status_check_matched=Correspondido
settings.protect_invalid_status_check_pattern=Padrรฃo de verificaรงรฃo de estado invรกlido: "%s".
settings.protect_no_valid_status_check_patterns=Nรฃo existem padrรตes de verificaรงรฃo de estado vรกlidos.
-settings.protect_required_approvals=Aprovaรงรตes necessรกrias:
+settings.protect_required_approvals=Aprovaรงรตes necessรกrias
settings.protect_required_approvals_desc=Permitir somente a integraรงรฃo constante de pedidos que tenham revisรตes positivas suficientes.
settings.protect_approvals_whitelist_enabled=Restringir aprovaรงรตes a utilizadores ou equipas da lista de permissรฃo
settings.protect_approvals_whitelist_enabled_desc=Somente as revisรตes dos utilizadores ou equipas da lista de permissรฃo irรฃo contar para as aprovaรงรตes necessรกrias. Se nรฃo houver uma lista de permissรฃo de aprovaรงรตes, revisรตes de qualquer pessoa com acesso de escrita contam para as aprovaรงรตes necessรกrias.
-settings.protect_approvals_whitelist_users=Revisores com permissรฃo:
-settings.protect_approvals_whitelist_teams=Equipas com permissรฃo para rever:
+settings.protect_approvals_whitelist_users=Revisores com permissรฃo
+settings.protect_approvals_whitelist_teams=Equipas com permissรฃo para rever
settings.dismiss_stale_approvals=Descartar aprovaรงรตes obsoletas
settings.dismiss_stale_approvals_desc=Quando novos cometimentos que mudam o conteรบdo do pedido de integraรงรฃo forem enviados para o ramo, as aprovaรงรตes antigas serรฃo descartadas.
settings.ignore_stale_approvals=Ignorar aprovaรงรตes obsoletas
@@ -2414,12 +2503,12 @@ settings.ignore_stale_approvals_desc=Nรฃo contar as aprovaรงรตes feitas em comet
settings.require_signed_commits=Exigir cometimentos assinados
settings.require_signed_commits_desc=Rejeitar envios para este ramo que nรฃo estejam assinados ou que nรฃo sejam validรกveis.
settings.protect_branch_name_pattern=Padrรฃo do nome do ramo protegido
-settings.protect_branch_name_pattern_desc=Padrรตes de nomes de ramos protegidos. Consulte a documentaรงรฃo para ver a sintaxe dos padrรตes. Exemplos: main, release/**
+settings.protect_branch_name_pattern_desc=Padrรตes de nomes de ramos protegidos. Consulte a documentaรงรฃo para ver a sintaxe dos padrรตes. Exemplos: main, release/**
settings.protect_patterns=Padrรตes
-settings.protect_protected_file_patterns=Padrรตes de ficheiros protegidos (separados com ponto e vรญrgula ";"):
-settings.protect_protected_file_patterns_desc=Ficheiros protegidos nรฃo podem ser modificados imediatamente, mesmo que o utilizador tenha direitos para adicionar, editar ou eliminar ficheiros neste ramo. Mรบltiplos padrรตes podem ser separados com ponto e vรญrgula (";"). Veja a documentaรงรฃo em github.com/gobwas/glob para ver a sintaxe. Exemplos: .drone.yml
, /docs/**/*.txt
.
-settings.protect_unprotected_file_patterns=Padrรตes de ficheiros desprotegidos (separados com ponto e vรญrgula ";"):
-settings.protect_unprotected_file_patterns_desc=Ficheiros desprotegidos que podem ser modificados imediatamente se o utilizador tiver direitos de escrita, contornando a restriรงรฃo no envio. Padrรตes mรบltiplos podem ser separados com ponto e vรญrgula (";"). Veja a documentaรงรฃo em github.com/gobwas/glob para ver a sintaxe. Exemplos: .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns=Padrรตes de ficheiros protegidos (separados com ponto e vรญrgula ";")
+settings.protect_protected_file_patterns_desc=Ficheiros protegidos nรฃo podem ser modificados imediatamente, mesmo que o utilizador tenha direitos para adicionar, editar ou eliminar ficheiros neste ramo. Mรบltiplos padrรตes podem ser separados com ponto e vรญrgula (";"). Veja a documentaรงรฃo em %s para ver a sintaxe. Exemplos: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns=Padrรตes de ficheiros desprotegidos (separados com ponto e vรญrgula ";")
+settings.protect_unprotected_file_patterns_desc=Ficheiros desprotegidos que podem ser modificados imediatamente se o utilizador tiver direitos de escrita, contornando a restriรงรฃo no envio. Padrรตes mรบltiplos podem ser separados com ponto e vรญrgula (";"). Veja a documentaรงรฃo em %[2]s para ver a sintaxe. Exemplos: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=Habilitar salvaguarda
settings.delete_protected_branch=Desabilitar salvaguarda
settings.update_protect_branch_success=A salvaguarda do ramo "%s" foi modificada.
@@ -2451,7 +2540,7 @@ settings.tags.protection.allowed.teams=Equipas com permissรฃo
settings.tags.protection.allowed.noone=Ninguรฉm
settings.tags.protection.create=Adicionar regra
settings.tags.protection.none=Nรฃo hรก etiquetas protegidas.
-settings.tags.protection.pattern.description=Pode usar um sรณ nome ou um padrรฃo glob ou uma expressรฃo regular para corresponder a vรกrias etiquetas. Para mais informaรงรตes leia o guia das etiquetas protegidas .
+settings.tags.protection.pattern.description=Pode usar um sรณ nome ou um padrรฃo glob ou uma expressรฃo regular para corresponder a vรกrias etiquetas. Para mais informaรงรตes leia o guia das etiquetas protegidas .
settings.bot_token=Cรณdigo do bot
settings.chat_id=ID do diรกlogo
settings.thread_id=ID da discussรฃo
@@ -2464,9 +2553,9 @@ settings.archive.text=Arquivar o repositรณrio irรก tornรก-lo apenas de leitura.
settings.archive.success=O repositรณrio foi arquivado com sucesso.
settings.archive.error=Ocorreu um erro enquanto decorria o processo de arquivo do repositรณrio. Veja os registo para obter mais detalhes.
settings.archive.error_ismirror=Nรฃo pode arquivar um repositรณrio que tenha sido replicado.
-settings.archive.branchsettings_unavailable=As configuraรงรตes dos ramos nรฃo estรฃo disponรญveis quando o repositรณrio estรก arquivado.
-settings.archive.tagsettings_unavailable=As configuraรงรตes sobre etiquetas nรฃo estรฃo disponรญveis quando o repositรณrio estรก arquivado.
-settings.archive.mirrors_unavailable=As rรฉplicas nรฃo estรฃo disponรญveis se o repositรณrio estiver arquivado.
+settings.archive.branchsettings_unavailable=As configuraรงรตes dos ramos nรฃo estรฃo disponรญveis em repositรณrios arquivados.
+settings.archive.tagsettings_unavailable=As configuraรงรตes sobre etiquetas nรฃo estรฃo disponรญveis em repositรณrios arquivados.
+settings.archive.mirrors_unavailable=As rรฉplicas nรฃo estรฃo disponรญveis em repositรณrios arquivados.
settings.unarchive.button=Desarquivar repositรณrio
settings.unarchive.header=Desarquivar este repositรณrio
settings.unarchive.text=Desarquivar o repositรณrio irรก restaurar a capacidade de receber cometimentos e envios, assim como novas questรตes e pedidos de integraรงรฃo.
@@ -2487,7 +2576,7 @@ settings.lfs_invalid_locking_path=Localizaรงรฃo invรกlida: %s
settings.lfs_invalid_lock_directory=Nรฃo foi possรญvel bloquear a pasta: %s
settings.lfs_lock_already_exists=Jรก existe um bloqueio: %s
settings.lfs_lock=Bloquear
-settings.lfs_lock_path=Localizaรงรฃo do ficheiro a bloquear...
+settings.lfs_lock_path=Localizaรงรฃo do ficheiro a bloquearโฆ
settings.lfs_locks_no_locks=Sem bloqueios
settings.lfs_lock_file_no_exist=O ficheiro bloqueado nรฃo existe no ramo principal
settings.lfs_force_unlock=Forรงar desbloqueio
@@ -2540,7 +2629,7 @@ diff.generated=gerado
diff.vendored=externo
diff.comment.add_line_comment=Adicionar comentรกrio de linha
diff.comment.placeholder=Deixar um comentรกrio
-diff.comment.markdown_info=A formataรงรฃo com markdown รฉ suportada.
+diff.comment.markdown_info=A formataรงรฃo com Markdown รฉ suportada.
diff.comment.add_single_comment=Adicionar um รบnico comentรกrio
diff.comment.add_review_comment=Adicionar comentรกrio
diff.comment.start_review=Iniciar revisรฃo
@@ -2571,7 +2660,7 @@ release.draft=Rascunho
release.prerelease=Prรฉ-lanรงamento
release.stable=Estรกvel
release.compare=Comparar
-release.edit=editar
+release.edit=Editar
release.ahead.commits=%d cometimentos
release.ahead.target=para %s desde este lanรงamento
tag.ahead.target=para o ramo %s desde esta etiqueta
@@ -2619,7 +2708,7 @@ branch.delete_desc=Eliminar um ramo รฉ algo permanente. Embora o ramo eliminado
branch.deletion_success=O ramo "%s" foi eliminado.
branch.deletion_failed=Falhou a eliminaรงรฃo do ramo "%s".
branch.delete_branch_has_new_commits=O ramo "%s" nรฃo pode ser eliminado porque foram adicionados novos cometimentos apรณs a integraรงรฃo.
-branch.create_branch=Criar ramo %s
+branch.create_branch=Criar ramo %s
branch.create_from=`a partir de "%s"`
branch.create_success=O ramo "%s" foi criado.
branch.branch_already_exists=O ramo "%s" jรก existe neste repositรณrio.
@@ -2646,7 +2735,7 @@ branch.new_branch=Criar um novo ramo
branch.new_branch_from=`Criar um novo ramo a partir do ramo "%s"`
branch.renamed=O ramo %s foi renomeado para %s.
-tag.create_tag=Criar etiqueta %s
+tag.create_tag=Criar etiqueta %s
tag.create_tag_operation=Criar etiqueta
tag.confirm_create_tag=Criar etiqueta
tag.create_tag_from=`Criar uma etiqueta nova a partir do ramo "%s"`
@@ -2658,13 +2747,13 @@ topic.done=Concluรญdo
topic.count_prompt=Nรฃo pode escolher mais do que 25 tรณpicos
topic.format_prompt=Os tรณpicos devem comeรงar com uma letra ou um nรบmero, podem incluir traรงos ("-") ou pontos (".") e podem ter atรฉ 35 caracteres. As letras tรชm que ser minรบsculas.
-find_file.go_to_file=Ir para o ficheiro
+find_file.go_to_file=Procurar um ficheiro
find_file.no_matching=Nรฃo foi encontrado qualquer ficheiro correspondente
error.csv.too_large=Nรฃo รฉ possรญvel apresentar este ficheiro por ser demasiado grande.
error.csv.unexpected=Nรฃo รฉ possรญvel apresentar este ficheiro porque contรฉm um caractere inesperado na linha %d e coluna %d.
error.csv.invalid_field_count=Nรฃo รฉ possรญvel apresentar este ficheiro porque tem um nรบmero errado de campos na linha %d.
-issues.blocked_by_user = Nรฃo pode criar uma questรฃo neste repositรณrio porque foi bloqueado/a pelo/a proprietรกrio/a do repositรณrio.
+issues.blocked_by_user = Nรฃo pode criar questรตes neste repositรณrio porque foi bloqueado(a) pelo(a) proprietรกrio(a) do repositรณrio.
issues.num_participants_one = %d participante
stars = Favoritos
editor.invalid_commit_mail = Email invรกlido para criar um cometimento.
@@ -2690,10 +2779,10 @@ migrate.forgejo.description = Migrar dados de codeberg.org ou de outras instรขnc
n_commit_one = %s cometimento
editor.commit_id_not_matching = O ficheiro foi modificado enquanto o estava a editar. Cometa para um ramo novo e depois integre.
commits.search_branch = Este ramo
-pulls.title_desc_one = quer integrar %[1]d cometimento do ramo %[2]s
no ramo %[3]s
+pulls.title_desc_one = quer integrar %[1]d cometimento do ramo %[2]s
no ramo %[3]s
pulls.reopen_failed.base_branch = O pedido de integraรงรฃo nรฃo pode ser reaberto porque o ramo base jรก nรฃo existe.
activity.navbar.code_frequency = Frequรชncia de programaรงรฃo
-settings.units.add_more = Adicionar mais...
+settings.units.add_more = Habilitar mais
settings.wiki_rename_branch_main_desc = Renomear o ramo usado internamente pelo Wiki para "%s". Esta operaรงรฃo รฉ permanente e nรฃo poderรก ser revertida.
settings.add_collaborator_blocked_our = Nรฃo foi possรญvel adicionar o/a colaborador/a porque o/a proprietรกrio/a do repositรณrio bloqueou-os.
settings.add_webhook.invalid_path = A localizaรงรฃo nรฃo pode conter "." ou ".." ou ficar em branco. Nรฃo pode comeรงar ou terminar com uma barra.
@@ -2716,7 +2805,7 @@ release.download_count_one = %s descarga
release.download_count_few = %s descargas
release.system_generated = Este anexo รฉ gerado automaticamente.
pulls.ready_for_review = Pronto/a para rever?
-settings.units.units = Unidades do repositรณrio
+settings.units.units = Unidades
error.broken_git_hook = Os automatismos git deste repositรณrio parecem estar danificados. Consulte a documentaรงรฃo sobre como os consertar e depois envie alguns cometimentos para refrescar o estado.
settings.rename_branch_failed_protected = Nรฃo รฉ possรญvel renomear o ramo %s porque รฉ um ramo protegido.
settings.units.overview = Visรฃo geral
@@ -2730,7 +2819,7 @@ settings.sourcehut_builds.secrets = Segredos
settings.matrix.room_id_helper = O ID da Sala pode ser obtido no cliente web Element > Configuraรงรตes da sala > Avanรงado > ID interno da sala. Exemplo: %s.
settings.web_hook_name_sourcehut_builds = Construรงรตes do SourceHut
settings.enter_repo_name = Insira o nome do/a proprietรกrio/a e do repositรณrio tal como รฉ apresentado:
-issues.comment.blocked_by_user = Nรฃo pode criar um comentรกrio nesta questรฃo porque foi bloqueado/a pelo/a proprietรกrio/a ou pelo remetente da questรฃo.
+issues.comment.blocked_by_user = Nรฃo pode comentar nesta questรฃo porque foi bloqueado(a) pelo(a) proprietรกrio(a) ou pelo autor da questรฃo.
pulls.merged_title_desc_one = integrou %[1]d cometimento do ramo %[2]s
no ramo %[3]s
%[4]s
pulls.agit_explanation = Criado usando a sequรชncia de trabalho AGit. AGit deixa os contribuidores proporem alteraรงรตes usando "git push" sem criar uma derivaรงรฃo ou um ramo novo.
settings.new_owner_blocked_doer = O/A novo/a proprietรกrio/a bloqueou-o/a.
@@ -2756,9 +2845,75 @@ settings.federation_following_repos = URLs de repositรณrios que estรฃo a ser seg
settings.federation_not_enabled = A federaรงรฃo nรฃo estรก a habilitada na sua instรขncia.
n_release_one = %s lanรงamento
n_release_few = %s lanรงamentos
+issues.author.tooltip.issue = Este/a utilizador/a รฉ o/a autor/a desta questรฃo.
+issues.author.tooltip.pr = Este/a utilizador/a รฉ o/a autor/a deste pedido de integraรงรฃo.
+activity.commit = Cometimentos feitos
+milestones.filter_sort.name = Nome
+release.invalid_external_url = URL externo invรกlido: "%s"
+release.type_external_asset = Recurso externo
+release.asset_name = Nome do recurso
+release.asset_external_url = URL externo
+release.add_external_asset = Adicionar recurso externo
+release.type_attachment = Anexo
+activity.published_prerelease_label = Prรฉ-lanรงamento
+activity.published_tag_label = Etiqueta
+settings.pull_mirror_sync_quota_exceeded = A quota foi excedida, as modificaรงรตes nรฃo vรฃo ser puxadas.
+settings.transfer_quota_exceeded = O novo proprietรกrio (%s) excedeu a quota. O repositรณrio nรฃo foi transferido.
+no_eol.text = Sem EOL
+no_eol.tooltip = Este ficheiro nรฃo contรฉm, no final, um caractere de fim da linha.
+pulls.cmd_instruction_merge_warning = Aviso: A opรงรฃo "Auto-identificar integraรงรฃo manual" nรฃo estรก habilitada para este repositรณrio, depois vai ter de marcar este pedido de integraรงรฃo como tendo sido executado manualmente.
+mirror_public_key = Chave de SSH pรบblica
+mirror_use_ssh.text = Utilizar a autenticaรงรฃo SSH
+mirror_denied_combination = Nรฃo รฉ possรญvel usar a autenticaรงรฃo baseada em chave pรบblica e senha em combinaรงรฃo.
+settings.mirror_settings.push_mirror.copy_public_key = Copiar chave pรบblica
+settings.mirror_settings.push_mirror.none_ssh = Nenhuma
+settings.protect_new_rule = Criar uma nova regra de proteรงรฃo de ramo
+mirror_use_ssh.helper = O Forgejo irรก replicar o repositรณrio via Git sobre SSH e criar um par de chaves para si quando escolher esta opรงรฃo. Tem que se certificar que a chave pรบblica gerada estรก autorizada a enviar para o repositรณrio de destino. Nรฃo pode usar a autorizaรงรฃo baseada numa senha quando escolher isto.
+mirror_use_ssh.not_available = A autenticaรงรฃo por SSH nรฃo estรก disponรญvel.
+issues.new.assign_to_me = Atribuir a mim
+issues.all_title = Todas
+settings.discord_icon_url.exceeds_max_length = O URL do รญcone tem que ter 2048 caracteres ou menos
+issues.filter_sort.relevance = Relevรขncia
+diff.git-notes.add = Adicionar nota
+diff.git-notes.remove-header = Remover nota
+diff.git-notes.remove-body = Esta nota irรก ser removida.
+issues.review.add_review_requests = revisรตes solicitadas de %[1]s %[2]s
+issues.review.remove_review_requests = pedidos de revisรฃo removidos para %[1]s %[2]s
+issues.review.add_remove_review_requests = pedidos de revisรฃo de %[1]s e pedidos de revisรฃo removidos para %[2]s %[3]s
+pulls.delete_after_merge.head_branch.is_default = O ramo de topo que pretende eliminar รฉ o ramo predefinido e nรฃo pode ser eliminado.
+pulls.delete_after_merge.head_branch.is_protected = O ramo de topo que pretende eliminar รฉ um ramo protegido e nรฃo pode ser eliminado.
+pulls.delete_after_merge.head_branch.insufficient_branch = Nรฃo tem permissรฃo para eliminar o ramo de topo.
+issues.summary_card_alt = Cartรฃo de resumo de uma questรฃo com o tรญtulo "%s" no repositรณrio %s
+issues.num_reviews_one = %d revisรฃo
+issues.num_reviews_few = %d revisรตes
+editor.add_tmpl.filename = nome do ficheiro
+new_from_template = Utilize um template
+settings.default_update_style_desc = Estilo de atualizaรงรฃo predefinido utilizado para atualizar pedidos de integraรงรฃo que estรฃo atrasados em relaรงรฃo ao ramo base.
+pulls.sign_in_require = Inicie sessรฃo para criar um novo pedido de integraรงรฃo.
+new_advanced = Configuraรงรตes avanรงadas
+new_advanced_expand = Clique para expandir
+new_from_template_description = Pode selecionar um modelo de repositรณrio existente nesta instรขncia e aplicar as suas definiรงรตes.
+auto_init_description = Iniciar o histรณrico do Git com um README e, opcionalmente, adicione os ficheiros License e .gitignore.
+issues.reaction.add = Adicionar reaรงรฃo
+issues.reaction.alt_few = %[1]s reagiu com %[2]s.
+issues.reaction.alt_many = %[1]s e mais %[2]d reagiram com %[3]s.
+issues.reaction.alt_remove = Remover reaรงรฃo %[1]s deste comentรกrio.
+issues.reaction.alt_add = Adicionar reaรงรฃo %[1]s ao comentรกrio.
+issues.context.menu = Menu de comentรกrio
+summary_card_alt = Cartรฃo de resumo do repositรณrio %s
+release.summary_card_alt = Cartรฃo de resumo de um lanรงamento com o tรญtulo "%s" no repositรณrio %s
+archive.pull.noreview = Este repositรณrio estรก arquivado. Nรฃo รฉ possรญvel rever os pedidos de integraรงรฃo.
+editor.commit_email = Endereรงo de email do cometimento
+commits.view_single_diff = Ver alteraรงรตes a este ficheiro introduzidas neste cometimento
+pulls.comment.blocked_by_user = Nรฃo pode comentar este pedido de integraรงรฃo porque estรก bloqueado pelo(a) proprietรกrio(a) do repositรณrio ou pelo(a) autor(a) do pedido de integraรงรฃo.
+issues.reopen.blocked_by_user = Nรฃo pode reabrir esta questรฃo porque estรก bloqueado pelo(a) proprietรกrio(a) do repositรณrio ou pelo autor da questรฃo.
+pulls.editable = Editรกvel
+pulls.editable_explanation = Este pedido de integraรงรฃo permite ediรงรตes dos responsรกveis. Pode contribuir diretamente para ele.
+issues.filter_no_results = Nenhum resultado
+issues.filter_no_results_placeholder = Tente ajustar os seus filtros de pesquisa.
[graphs]
-component_loading=A carregar %s...
+component_loading=A carregar %sโฆ
component_loading_failed=Nรฃo foi possรญvel carregar %s
component_loading_info=Isto pode demorar um poucoโฆ
component_failed_to_load=Ocorreu um erro inesperado.
@@ -2803,7 +2958,7 @@ settings.permission=Permissรตes
settings.repoadminchangeteam=O administrador do repositรณrio pode adicionar e remover o acesso ร s equipas
settings.visibility=Visibilidade
settings.visibility.public=Pรบblico
-settings.visibility.limited=Limitada (visรญvel apenas para utilizadores autenticados)
+settings.visibility.limited=Limitada (visรญvel apenas para utilizadores regitados)
settings.visibility.limited_shortname=Limitada
settings.visibility.private=Privada (visรญvel apenas para membros da organizaรงรฃo)
settings.visibility.private_shortname=Privado
@@ -2834,7 +2989,7 @@ members.member=Membro
members.remove=Remover
members.remove.detail=Remover %[1]s de %[2]s?
members.leave=Sair
-members.leave.detail=Sair de %s?
+members.leave.detail=Tem a certeza que quer sair da organizaรงรฃo %s?
members.invite_desc=Adicionar um novo membro a %s:
members.invite_now=Convidar agora
@@ -2844,8 +2999,8 @@ teams.leave.detail=Sair de %s?
teams.can_create_org_repo=Criar repositรณrios
teams.can_create_org_repo_helper=Os membros podem criar novos repositรณrios na organizaรงรฃo. O criador terรก acesso de administrador ao novo repositรณrio.
teams.none_access=Sem acesso
-teams.none_access_helper=Os membros nรฃo podem ver nem fazer qualquer outra operaรงรฃo nesta unidade. Nรฃo tem qualquer efeito nos repositรณrios pรบblicos.
-teams.general_access=Acesso geral
+teams.none_access_helper=A opรงรฃo "sem acesso" sรณ tem efeito nos repositรณrios privados.
+teams.general_access=Acesso personalizado
teams.general_access_helper=As permissรตes dos membros serรฃo decididas pela tabela de permissรตes abaixo.
teams.read_access=Ler
teams.read_access_helper=Os membros podem ver e clonar os repositรณrios da equipa.
@@ -2891,6 +3046,8 @@ teams.invite.by=Convidado(a) por %s
teams.invite.description=Clique no botรฃo abaixo para se juntar ร equipa.
follow_blocked_user = Nรฃo pode seguir esta organizaรงรฃo porque esta organizaรงรฃo bloqueou-o/a.
open_dashboard = Abrir painel de controlo
+settings.change_orgname_redirect_prompt.with_cooldown.one = O nome antigo da organizaรงรฃo estarรก disponรญvel para todos apรณs um perรญodo de espera de %[1]d dia, podendo ainda reivindicar o nome antigo durante o perรญodo de espera.
+settings.change_orgname_redirect_prompt.with_cooldown.few = O nome antigo da organizaรงรฃo estarรก disponรญvel para todos apรณs um perรญodo de espera de %[1]d dias, podendo ainda reivindicar o nome antigo durante o perรญodo de espera.
[admin]
dashboard=Painel de controlo
@@ -2912,7 +3069,7 @@ last_page=รltima
total=total: %d
settings=Configuraรงรตes de administraรงรฃo
-dashboard.new_version_hint=O Forgejo %s estรก disponรญvel, vocรช estรก a correr a versรฃo %s. Verifique o blog para mais detalhes.
+dashboard.new_version_hint=O Forgejo %s estรก disponรญvel, vocรช estรก a correr a versรฃo %s. Verifique o blog para mais detalhes.
dashboard.statistic=Resumo
dashboard.operations=Operaรงรตes de manutenรงรฃo
dashboard.system_status=Estado do sistema
@@ -2990,10 +3147,10 @@ dashboard.delete_old_actions.started=Foi iniciado o processo de eliminaรงรฃo de
dashboard.update_checker=Verificador de novas versรตes
dashboard.delete_old_system_notices=Eliminar todas as notificaรงรตes do sistema antigas da base de dados
dashboard.gc_lfs=Recolher lixo dos meta-elementos LFS
-dashboard.stop_zombie_tasks=Parar tarefas zombies
-dashboard.stop_endless_tasks=Parar tarefas interminรกveis
-dashboard.cancel_abandoned_jobs=Cancelar trabalhos abandonados
-dashboard.start_schedule_tasks=Iniciar tarefas de agendamento
+dashboard.stop_zombie_tasks=Parar tarefas de operaรงรตes zombies
+dashboard.stop_endless_tasks=Parar tarefas de operaรงรตes interminรกveis
+dashboard.cancel_abandoned_jobs=Cancelar trabalhos de operaรงรตes abandonados
+dashboard.start_schedule_tasks=Iniciar tarefas de operaรงรตes de agendamento
dashboard.sync_branch.started=Sincronizaรงรฃo de ramos iniciada
dashboard.sync_tag.started=Sincronizaรงรฃo de etiquetas iniciada
dashboard.rebuild_issue_indexer=Reconstruir indexador de questรตes
@@ -3026,8 +3183,8 @@ users.max_repo_creation=Nรบmero mรกximo de repositรณrios
users.max_repo_creation_desc=(insira -1 para usar o limite predefinido a nรญvel global)
users.is_activated=A conta de utilizador estรก em funcionamento
users.prohibit_login=Desabilitar inรญcio de sessรฃo
-users.is_admin=ร administrador/a
-users.is_restricted=A conta รฉ restrita
+users.is_admin=Conta de administrador
+users.is_restricted=Conta restrita
users.allow_git_hook=Pode criar automatismos do Git
users.allow_git_hook_tooltip=Os automatismos do Git sรฃo executados em nome do utilizador do sistema operativo que corre o Forgejo e tรชm o mesmo nรญvel de acesso ao servidor. Por causa disso, utilizadores com este privilรฉgio especial de automatismo do Git podem aceder e modificar todos os repositรณrios do Forgejo, assim como a base de dados usada pelo Forgejo. Consequentemente, tambรฉm podem ganhar privilรฉgios de administrador do Forgejo.
users.allow_import_local=Pode importar repositรณrios locais
@@ -3076,8 +3233,8 @@ orgs.members=Membros
orgs.new_orga=Nova organizaรงรฃo
repos.repo_manage_panel=Gerir repositรณrios
-repos.unadopted=Repositรณrios nรฃo adoptados
-repos.unadopted.no_more=Nรฃo foram encontrados mais repositรณrios nรฃo adoptados
+repos.unadopted=Repositรณrios nรฃo adotados
+repos.unadopted.no_more=Nรฃo foram encontrados repositรณrios nรฃo adotados.
repos.owner=Proprietรกrio(a)
repos.name=Nome
repos.private=Privado
@@ -3103,12 +3260,12 @@ packages.size=Tamanho
packages.published=Publicado
defaulthooks=Automatismos web predefinidos
-defaulthooks.desc=Os automatismos web fazem pedidos HTTP POST automaticamente a um servidor quando sรฃo despoletados determinados eventos do Forgejo. Os automatismos web definidos aqui sรฃo os predefinidos e serรฃo copiados para todos os novos repositรณrios. Leia mais no guia de automatismos web .
+defaulthooks.desc=Os automatismos web fazem pedidos HTTP POST automaticamente a um servidor quando sรฃo despoletados determinados eventos do Forgejo. Os automatismos web definidos aqui sรฃo os predefinidos e serรฃo copiados para todos os novos repositรณrios. Leia mais no guia de automatismos web .
defaulthooks.add_webhook=Adicionar automatismo web predefinido
defaulthooks.update_webhook=Modificar automatismo web predefinido
systemhooks=Automatismos web do sistema
-systemhooks.desc=Os automatismos web fazem pedidos HTTP POST automaticamente a um servidor quando sรฃo despoletados determinados eventos do Forgejo. Os automatismos web definidos aqui irรฃo operar em todos os repositรณrios deste sistema, por isso tenha em consideraรงรฃo quaisquer implicaรงรตes de desempenho que isso possa ter. Leia mais no guia de automatismos web .
+systemhooks.desc=Os automatismos web fazem pedidos HTTP POST automaticamente a um servidor quando sรฃo despoletados determinados eventos do Forgejo. Os automatismos web definidos aqui irรฃo operar em todos os repositรณrios deste sistema, por isso tenha em consideraรงรฃo quaisquer implicaรงรตes de desempenho que isso possa ter. Leia mais no guia de automatismos web .
systemhooks.add_webhook=Adicionar automatismo web do sistema
systemhooks.update_webhook=Modificar automatismo web do sistema
@@ -3184,9 +3341,9 @@ auths.oauth2_required_claim_name_helper=Defina este nome para restringir o inรญc
auths.oauth2_required_claim_value=Valor de reivindicaรงรฃo obrigatรณrio
auths.oauth2_required_claim_value_helper=Defina este valor para restringir o inรญcio de sessรฃo desta fonte a utilizadores que tenham uma reivindicaรงรฃo com este nome e este valor
auths.oauth2_group_claim_name=Reivindicar nome que fornece nomes de grupo para esta fonte. (Opcional)
-auths.oauth2_admin_group=Valor da reivindicaรงรฃo de grupo para utilizadores administradores (opcional โ exige a reivindicaรงรฃo de nome acima).
-auths.oauth2_restricted_group=Valor da reivindicaรงรฃo de grupo para utilizadores restritos (opcional โ exige a reivindicaรงรฃo de nome acima).
-auths.oauth2_map_group_to_team=Mapear grupos reclamados em equipas da organizaรงรฃo (opcional โ requer nome de reclamaรงรฃo acima).
+auths.oauth2_admin_group=Valor da reivindicaรงรฃo de grupo para utilizadores administradores. (Opcional โ exige a reivindicaรงรฃo de nome acima)
+auths.oauth2_restricted_group=Valor da reivindicaรงรฃo de grupo para utilizadores restritos. (Opcional โ exige a reivindicaรงรฃo de nome acima)
+auths.oauth2_map_group_to_team=Mapear grupos reclamados em equipas da organizaรงรฃo. (Opcional โ requer nome de reclamaรงรฃo acima)
auths.oauth2_map_group_to_team_removal=Remover utilizadores das equipas sincronizadas se esses utilizadores nรฃo pertencerem ao grupo correspondente.
auths.enable_auto_register=Habilitar o registo automรกtico
auths.sspi_auto_create_users=Criar utilizadores automaticamente
@@ -3203,18 +3360,18 @@ auths.tips=Dicas
auths.tips.oauth2.general=Autenticaรงรฃo OAuth2
auths.tips.oauth2.general.tip=Ao registar uma nova autenticaรงรฃo OAuth2, o URL da ligaรงรฃo de retorno ou do reencaminhamento deve ser:
auths.tip.oauth2_provider=Fornecedor OAuth2
-auths.tip.bitbucket=Registe um novo consumidor de OAuth em https://bitbucket.org/account/user//oauth-consumers/new e adicione a permissรฃo "Account" - "Read"
+auths.tip.bitbucket=Registe um novo consumidor de OAuth em %s
auths.tip.nextcloud=`Registe um novo consumidor OAuth na sua instรขncia usando o seguinte menu "Configuraรงรตes โ Seguranรงa โ Cliente OAuth 2.0"`
-auths.tip.dropbox=Crie uma nova aplicaรงรฃo em https://www.dropbox.com/developers/apps
-auths.tip.facebook=`Registe uma nova aplicaรงรฃo em https://developers.facebook.com/apps e adicione o produto "Facebook Login"`
-auths.tip.github=Registe uma nova aplicaรงรฃo OAuth em https://github.com/settings/applications/new
+auths.tip.dropbox=Crie uma nova aplicaรงรฃo em %s
+auths.tip.facebook=`Registe uma nova aplicaรงรฃo em %s e adicione o produto "Facebook Login"`
+auths.tip.github=Registe uma nova aplicaรงรฃo OAuth em %s
auths.tip.gitlab=Registe uma nova aplicaรงรฃo em https://gitlab.com/profile/applications
-auths.tip.google_plus=Obtenha credenciais de cliente OAuth2 a partir da consola do Google API em https://console.developers.google.com/
+auths.tip.google_plus=Obtenha credenciais de cliente OAuth2 a partir da consola do Google API em %s
auths.tip.openid_connect=Use o URL da descoberta de conexรฃo OpenID (/.well-known/openid-configuration) para especificar os extremos
-auths.tip.twitter=`Vรก a https://dev.twitter.com/apps, crie uma aplicaรงรฃo e certifique-se de que estรก habilitada a opรงรฃo "Allow this application to be used to Sign in with Twitter"`
-auths.tip.discord=Registe uma nova aplicaรงรฃo em https://discordapp.com/developers/applications/me
-auths.tip.gitea=Registe uma nova aplicaรงรฃo OAuth2. O guia pode ser encontrado em https://forgejo.org/docs/latest/user/oauth2-provider
-auths.tip.yandex=`Crie uma nova aplicaรงรฃo em https://oauth.yandex.com/client/new. Escolha as seguintes permissรตes da secรงรฃo "Yandex.Passport API": "Acesso ao endereรงo de email", "Acesso ao avatar do utilizador" e "Acesso ao nome de utilizador, nome e sobrenome, gรฉnero"`
+auths.tip.twitter=`Vรก a %s, crie uma aplicaรงรฃo e certifique-se de que estรก habilitada a opรงรฃo "Allow this application to be used to Sign in with Twitter"`
+auths.tip.discord=Registe uma nova aplicaรงรฃo em %s
+auths.tip.gitea=Registe uma nova aplicaรงรฃo OAuth2. O guia pode ser encontrado em %s
+auths.tip.yandex=`Crie uma nova aplicaรงรฃo em %s. Escolha as seguintes permissรตes da secรงรฃo "Yandex.Passport API": "Acesso ao endereรงo de email", "Acesso ao avatar do utilizador" e "Acesso ao nome de utilizador, nome e sobrenome, gรฉnero"`
auths.tip.mastodon=Insira o URL de uma instรขncia personalizada para a instรขncia do mastodon com que se pretende autenticar (ou entรฃo use a predefinida)
auths.edit=Editar fonte de autenticaรงรฃo
auths.activated=Esta fonte de autenticaรงรฃo estรก em funcionamento
@@ -3424,17 +3581,32 @@ notices.delete_success=As notificaรงรตes do sistema foram eliminadas.
self_check.no_problem_found=Nenhum problema encontrado atรฉ agora.
self_check.database_collation_mismatch=Supor que a base de dados usa a colaรงรฃo: %s
-self_check.database_collation_case_insensitive=A base de dados estรก a usar a colaรงรฃo %s, que รฉ insensรญvel ร diferenรงa entre maiรบsculas e minรบsculas. Embora o Gitea possa trabalhar com ela, pode haver alguns casos raros que nรฃo funcionem como esperado.
+self_check.database_collation_case_insensitive=A base de dados estรก a usar a colaรงรฃo %s, que รฉ insensรญvel ร diferenรงa entre maiรบsculas e minรบsculas. Embora o Forgejo possa trabalhar com ela, pode haver alguns casos raros que nรฃo funcionem como esperado.
self_check.database_inconsistent_collation_columns=A base de dados estรก a usar a colaรงรฃo %s, mas estas colunas estรฃo a usar colaรงรตes diferentes. Isso poderรก causar alguns problemas inesperados.
-self_check.database_fix_mysql=Para utilizadores do MySQL/MariaDB, pode usar o comando "gitea doctor convert" para resolver os problemas de colaรงรฃo. Tambรฉm pode resolver o problema com comandos SQL "ALTER ... COLLATE ..." aplicados manualmente.
+self_check.database_fix_mysql=Para utilizadores do MySQL/MariaDB, pode usar o comando "forgejo doctor convert" para resolver os problemas de colaรงรฃo. Tambรฉm pode resolver o problema com comandos SQL "ALTER ... COLLATE ..." aplicados manualmente.
config_summary = Resumo
auths.tips.gmail_settings = Configuraรงรตes do Gmail:
config_settings = Configuraรงรตes
-auths.tip.gitlab_new = Registe uma nova aplicaรงรฃo em https://gitlab.com/-/profile/applications
+auths.tip.gitlab_new = Registe uma nova aplicaรงรฃo em %s
config.open_with_editor_app_help = Os editores da opรงรฃo "Abrir com" do menu da clonagem. Se for deixado em branco, serรก usado o valor predefinido. Expanda para ver o que estรก predefinido.
config.allow_dots_in_usernames = Permitir que os utilizadores usem pontos no seu nome de utilizador. Nรฃo altera as contas existentes.
auths.default_domain_name = Nome de domรญnio predefinido usado para o endereรงo de email
config.app_slogan = Lema da instรขncia
+config.cache_test = Testar a cache
+config.cache_test_slow = O teste da cache foi bem sucedido, mas a resposta รฉ lenta: %s.
+config.cache_test_succeeded = O teste da cache foi bem sucedido, o tempo de resposta foi de %s.
+config.cache_test_failed = Falhou a sondagem da cache: %v.
+users.block.description = Impedir que este utilizador interaja com este serviรงo atravรฉs da sua conta e proibi-lo de iniciar sessรฃo.
+users.admin.description = Atribuir acesso total a este utilizador a todos os recursos administrativos disponรญveis atravรฉs da interface web e da API.
+users.local_import.description = Permitir a importaรงรฃo de repositรณrios a partir do sistema de ficheiros local do servidor. Isto poderรก ser um problema de seguranรงa.
+users.organization_creation.description = Permitir a criaรงรฃo de novas organizaรงรตes.
+users.activated.description = Finalizaรงรฃo da verificaรงรฃo do email. O proprietรกrio de uma conta nรฃo habilitada nรฃo poderรก iniciar a sessรฃo enquanto a verificaรงรฃo do email nรฃo estiver finalizada.
+users.restricted.description = Permitir que este/a utilizador/a interaja apenas com os repositรณrios e as organizaรงรตes onde tenha sido adicionado/a como colaborador/a. Isto impede o acesso a repositรณrios pรบblicos nesta instรขncia.
+emails.delete = Eliminar email
+emails.deletion_success = O endereรงo de email foi eliminado.
+emails.delete_primary_email_error = Nรฃo pode eliminar o endereรงo de email principal.
+emails.delete_desc = Tem a certeza que quer eliminar este endereรงo de email?
+monitor.duration = Duraรงรฃo (s)
[action]
create_repo=criou o repositรณrio %s
@@ -3559,7 +3731,7 @@ alpine.registry=Configure este registo adicionando o URL no seu ficheiro /
alpine.registry.key=Descarregue a chave RSA pรบblica do registo para dentro da pasta /etc/apk/keys/
para verificar a assinatura do รญndice:
alpine.registry.info=Escolha $branch e $repository da lista abaixo.
alpine.install=Para instalar o pacote, execute o seguinte comando:
-alpine.repository=Informaรงรฃo do repositรณrio
+alpine.repository=Informaรงรตes do repositรณrio
alpine.repository.branches=Ramos
alpine.repository.repositories=Repositรณrios
alpine.repository.architectures=Arquitecturas
@@ -3579,9 +3751,9 @@ conda.install=Para instalar o pacote usando o Conda, execute o seguinte comando:
container.details.type=Tipo de imagem
container.details.platform=Plataforma
container.pull=Puxar a imagem usando a linha de comandos:
-container.digest=Resumo:
+container.digest=Resumo
container.multi_arch=S.O. / Arquit.
-container.layers=Camadas de imagem
+container.layers=Camadas da imagem
container.labels=Rรณtulos
container.labels.key=Chave
container.labels.value=Valor
@@ -3590,7 +3762,7 @@ cran.install=Para instalar o pacote, execute o seguinte comando:
debian.registry=Configurar este registo usando a linha de comandos:
debian.registry.info=Escolha $distribution e $component da lista abaixo.
debian.install=Para instalar o pacote, execute o seguinte comando:
-debian.repository=Informaรงรฃo do repositรณrio
+debian.repository=Informaรงรตes do repositรณrio
debian.repository.distributions=Distribuiรงรตes
debian.repository.components=Componentes
debian.repository.architectures=Arquitecturas
@@ -3620,12 +3792,12 @@ rpm.registry=Configurar este registo usando a linha de comandos:
rpm.distros.redhat=em distribuiรงรตes baseadas no RedHat
rpm.distros.suse=em distribuiรงรตes baseadas no SUSE
rpm.install=Para instalar o pacote, execute o seguinte comando:
-rpm.repository=Informaรงรฃo do repositรณrio
+rpm.repository=Informaรงรตes do repositรณrio
rpm.repository.architectures=Arquitecturas
rpm.repository.multiple_groups=Este pacote estรก disponรญvel em vรกrios grupos.
rubygems.install=Para instalar o pacote usando o gem, execute o seguinte comando:
rubygems.install2=ou adicione-o ao ficheiro Gemfile
:
-rubygems.dependencies.runtime=Dependรชncias do tempo de execuรงรฃo (runtime)
+rubygems.dependencies.runtime=Dependรชncias em tempo de execuรงรฃo
rubygems.dependencies.development=Dependรชncias de desenvolvimento
rubygems.required.ruby=Requer a versรฃo do Ruby
rubygems.required.rubygems=Requer a versรฃo do RubyGem
@@ -3678,6 +3850,31 @@ owner.settings.chef.keypair=Gerar par de chaves
owner.settings.chef.keypair.description=ร necessรกrio um par de chaves para autenticar no registro Chef. Se vocรช gerou um par de chaves antes, gerar um novo par de chaves irรก descartar o par de chaves antigo.
owner.settings.cargo.rebuild.no_index = Nรฃo foi possรญvel reconstruir, nรฃo hรก um รญndice inicializado.
npm.dependencies.bundle = Dependรชncias agrupadas
+arch.pacman.repo.multi.item = Configuraรงรตes para %s
+arch.pacman.sync = Sincronizar pacote com o pacman:
+arch.version.properties = Propriedades da versรฃo
+arch.version.description = Descriรงรฃo
+arch.version.provides = Fornece
+arch.pacman.helper.gpg = Adicionar certificado de confianรงa para o pacman:
+arch.pacman.conf = Adicionar servidor com distribuiรงรฃo e arquitectura relacionadas a /etc/pacman.conf
:
+arch.pacman.repo.multi = %s tem a mesma versรฃo em distribuiรงรตes diferentes.
+arch.version.optdepends = Depende opcionalmente
+arch.version.depends = Depende de
+arch.version.makedepends = Dependรชncias do make
+arch.version.groups = Grupo
+arch.version.checkdepends = Verificar dependรชncias
+arch.version.conflicts = Conflitos
+arch.version.backup = Cรณpia de seguranรงa
+arch.version.replaces = Substitui
+container.images.title = Imagens
+search_in_external_registry = Procurar em %s
+alt.registry = Configure este registo a partir da linha de comandos:
+alt.registry.install = Para instalar o pacote, execute o seguinte comando:
+alt.install = Instalar pacote
+alt.repository = Informaรงรฃo do repositรณrio
+alt.repository.architectures = Arquiteturas
+alt.repository.multiple_groups = Este pacote estรก disponรญvel em vรกrios grupos.
+alt.setup = Adicionar um repositรณrio ร lista de repositรณrios ligados (escolha a arquitetura necessรกria em vez de "_arch_"):
[secrets]
secrets=Segredos
@@ -3697,7 +3894,7 @@ management=Gerir segredos
[actions]
actions=Operaรงรตes
-unit.desc=Gerir sequรชncias CI/CD integradas com Forgejo Actions
+unit.desc=Gerir sequรชncias CI/CD integradas com Forgejo Actions.
status.unknown=Desconhecido
status.waiting=Aguardando
@@ -3788,15 +3985,26 @@ runs.no_workflows.quick_start = Nรฃo sabe como comeรงar com o Forgejo Action? Ve
runs.no_job_without_needs = A sequรชncia de trabalho tem de conter pelo menos um trabalho sem dependรชncias.
runs.workflow = Sequรชncia de trabalho
runs.no_job = A sequรชncia de trabalho tem de conter pelo menos um trabalho
+workflow.dispatch.use_from = Usar sequรชncia de trabalho de
+workflow.dispatch.run = Executar sequรชncia de trabalho
+workflow.dispatch.input_required = Exigir valor para a entrada "%s".
+workflow.dispatch.warn_input_limit = Apresentando apenas as %d primeiras entradas.
+workflow.dispatch.trigger_found = Esta sequรชncia de trabalho รฉ despoletada pelo evento workflow_dispatch .
+workflow.dispatch.success = A execuรงรฃo da sequรชncia de trabalho foi pedida com sucesso.
+workflow.dispatch.invalid_input_type = Tipo de entrada "%s" invรกlido.
+runs.expire_log_message = Os registos foram purgados por serem demasiado antigos.
+runs.no_workflows.help_no_write_access = Para aprender sobre Forgejo Actions, vejaa documentaรงรฃo .
+runs.no_workflows.help_write_access = Nรฃo sabe como comeรงar com o Forgejo Actions? Consulte o inรญcio rรกpido na documentaรงรฃo do utilizador para escrever a sua primeira sequรชncia de trabalho, depois prepare um executor Forgejo para executar os seus trabalhos.
+variables.not_found = Nรฃo foi possรญvel encontrar a variรกvel.
[projects]
type-1.display_name=Planeamento individual
type-2.display_name=Planeamento do repositรณrio
type-3.display_name=Planeamento da organizaรงรฃo
+deleted.display_name = Planeamento eliminado
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=Pasta
normal_file=Ficheiro normal
executable_file=Ficheiro executรกvel
@@ -3806,26 +4014,35 @@ submodule=Submรณdulo
[search]
-org_kind = Pesquisar organizaรงรตes...
+org_kind = Pesquisar organizaรงรตesโฆ
keyword_search_unavailable = Pesquisar por palavra-chave nรฃo estรก disponรญvel, neste momento. Entre em contacto com o administrador.
code_search_by_git_grep = Os resultados da pesquisa no cรณdigo-fonte neste momento sรฃo fornecidos pelo "git grep". Esses resultados podem ser melhores se o administrador habilitar o indexador de cรณdigo-fonte.
no_results = Nรฃo foram encontrados resultados correspondentes.
-package_kind = Pesquisar pacotes...
-runner_kind = Pesquisar executores...
-project_kind = Pesquisar planeamentos...
-branch_kind = Pesquisar ramos...
-commit_kind = Pesquisar cometimentos...
-search = Procurar...
+package_kind = Pesquisar pacotesโฆ
+runner_kind = Pesquisar executoresโฆ
+project_kind = Pesquisar planeamentosโฆ
+branch_kind = Pesquisar ramosโฆ
+commit_kind = Pesquisar cometimentosโฆ
+search = Procurarโฆ
type_tooltip = Tipo de pesquisa
fuzzy = Aproximada
fuzzy_tooltip = Incluir tambรฉm os resultados que estejam prรณximos do termo de pesquisa
match = Fiel
match_tooltip = Incluir somente os resultados que correspondam rigorosamente ao termo de pesquisa
-repo_kind = Pesquisar repositรณrios...
-user_kind = Pesquisar utilizadores...
-team_kind = Pesquisar equipas...
-code_kind = Pesquisar cรณdigo...
+repo_kind = Pesquisar repositรณriosโฆ
+user_kind = Pesquisar utilizadoresโฆ
+team_kind = Pesquisar equipasโฆ
+code_kind = Pesquisar cรณdigoโฆ
code_search_unavailable = A pesquisa de cรณdigo nรฃo estรก disponรญvel, neste momento. Entre em contacto com o administrador.
+exact = Fiel
+exact_tooltip = Incluir somente os resultados que correspondam rigorosamente ao termo de pesquisa
+issue_kind = Procurar questรตesโฆ
+pull_kind = Procurar pedidos de integraรงรฃoโฆ
+union = Palavras-chave
+union_tooltip = Incluir resultados correspondentes a qualquer das palavras-chave separadas por espaรงos em branco
+milestone_kind = Procurar etapas...
+regexp_tooltip = Interpreta o termo de pesquisa como uma expressรฃo regular
+regexp = ExpReg
[munits.data]
kib = KiB
@@ -3839,4 +4056,27 @@ b = B
[markup]
filepreview.lines = Linhas %[1]d atรฉ %[2]d em %[3]s
filepreview.line = Linha %[1]d em %[2]s
-filepreview.truncated = A previsรฃo foi truncada
\ No newline at end of file
+filepreview.truncated = A previsรฃo foi truncada
+
+[translation_meta]
+test = ok :)
+
+[repo.permissions]
+code.read = Ler: Aceder e clonar o cรณdigo-fonte do repositรณrio.
+releases.read = Ler: Ver e descarregar lanรงamentos.
+projects.read = Ler: Aceder aos quadros de planeamento do repositรณrio.
+projects.write = Escrever: Criar planeamentos e colunas e editรก-las.
+packages.read = Ler: Ver e descarregar pacotes atribuรญdos ao repositรณrio.
+packages.write = Escrever: Publicar e eliminar pacotes atribuรญdos ao repositรณrio.
+actions.read = Ler: Ver sequรชncias CI/CD integrados e os seus registos.
+actions.write = Escrever: Despoletar, reiniciar, cancelar ou aprovar manualmente sequรชncias CI/CD pendentes.
+ext_issues = Aceder ร ligaรงรฃo para um rastreador de questรตes externo. As permissรตes sรฃo geridas externamente.
+ext_wiki = Aceder ร ligaรงรฃo para um wiki externo. As permissรตes sรฃo geridas externamente.
+issues.write = Escrever: Fechar questรตes e gerir metadados, tais como rรณtulos, etapas, encarregados, datas de vencimento e dependรชncias.
+pulls.read = Ler: Ler e criar pedidos de integraรงรฃo.
+releases.write = Escrever: Publicar, editar e eliminar lanรงamentos e seus recursos.
+wiki.read = Ler: Ler o wiki integrado e o seu histรณrico.
+wiki.write = Escrever: Criar, modificar e eliminar pรกginas no wiki integrado.
+code.write = Escrever: Enviar para o repositรณrio, criar ramos e etiquetas.
+issues.read = Ler: Ler e criar questรตes e comentรกrios.
+pulls.write = Escrever: Fechar pedidos de integraรงรฃo e gerir metadados, tais como rรณtulos, etapas, encarregados, datas de vencimento e dependรชncias.
diff --git a/options/locale/locale_ro.ini b/options/locale/locale_ro.ini
new file mode 100644
index 0000000000..305c34d013
--- /dev/null
+++ b/options/locale/locale_ro.ini
@@ -0,0 +1,249 @@
+
+
+
+[common]
+return_to_forgejo = รnapoi la Forgejo
+explore = Exploreazฤ
+page = Paginฤ
+licenses = Licenศe
+copy_type_unsupported = Acest tip de fiศier nu poate fi copiat
+sign_in = Autentificare
+sign_out = Deconectare
+sign_in_with_provider = Autentificare cu %s
+sign_in_or = sau
+toc = Cuprins
+admin_panel = Administrare site
+artifacts = Artefacte
+concept_user_organization = Organizaศie
+logo = Logo
+help = Ajutor
+sign_up = รnregistrare
+link_account = Conectare cont
+register = รnregistrare
+template = ศablon
+language = Limbฤ
+notifications = Notificฤri
+create_new = Creeazฤโฆ
+user_profile_and_more = Profil ศi setฤriโฆ
+username = Nume de utilizator
+email = Adresฤ de email
+password = Parolฤ
+access_token = Token de acces
+captcha = CAPTCHA
+twofa = Autentificare prin doi factori
+webauthn_insert_key = Insereazฤ cheia de securitate
+webauthn_press_button = Apasฤ butonul de pe cheia de securitateโฆ
+webauthn_use_twofa = Foloseศte un cod de verificare de pe telefon
+webauthn_error = Cheia de securitate nu a putut fi cititฤ.
+webauthn_unsupported_browser = Browserul tฤu nu are abilitฤศi WebAuthn pe moment.
+webauthn_error_unable_to_process = Serverul nu a putut procesa cererea.
+webauthn_error_duplicated = Cheia de securitate nu este permisฤ pentru aceastฤ cerere. Asigurฤ-te cฤ cheia nu este รฎnregistratฤ deja.
+webauthn_error_empty = Trebuie sฤ setezi un nume pentru aceastฤ cheie.
+organization = Organizaศie
+mirror = Oglindฤ
+settings = Setฤri
+your_profile = Profil
+your_starred = Favorite
+your_settings = Setฤri
+new_migrate.title = Migrare nouฤ
+new_org.title = Organizaศie nouฤ
+new_migrate.link = Migrare nouฤ
+new_org.link = Organizaศie nouฤ
+sources = Surse
+mirrors = Oglinzi
+ok = OK
+cancel = Anulare
+retry = Reรฎncearcฤ
+add = Adaugฤ
+edit = Editeazฤ
+view = Vezi
+test = Test
+enabled = Activat
+disabled = Dezactivat
+locked = Blocat
+copy = Copiazฤ
+copy_generic = Copiazฤ รฎn clipboard
+copy_url = Copiazฤ URL
+copy_hash = Copiazฤ hash
+copy_content = Copiazฤ conศinut
+copy_success = Copiat!
+preview = Previzualizeazฤ
+loading = Se รฎncarcฤโฆ
+error = Eroare
+go_back = รnapoi
+never = Niciodatฤ
+rss_feed = Flux RSS
+confirm_delete_artifact = Eศti sigur cฤ vrei sฤ ศtergi artefactul "%s"?
+archived = Arhivat
+concept_system_global = Global
+show_log_seconds = Aratฤ secunde
+name = Nume
+filter = Filtru
+filter.clear = ศterge filtre
+filter.is_archived = Arhivat
+enable_javascript = Acest site are nevoie de JavaScript.
+webauthn_error_unknown = O eroare necunoscutฤ a apฤrut. Te rog reรฎncearcฤ.
+re_type = Confirmฤ parola
+webauthn_sign_in = Apasฤ butonul de pe cheia de securitate. Dacฤ cheia de securitate nu are un buton, reintrodu-o.
+new_mirror = Oglindฤ nouฤ
+new_project = Proiect nou
+remove_label_str = ศterge elementul "%s"
+save = Salveazฤ
+remove = ศterge
+copy_path = Copiazฤ cale
+error404 = Pagina pe care รฎncerci sฤ o vizitezi fie nu existฤ sau nu eศti autorizat sฤ o vezi.
+filter.not_archived = Nearhivat
+activities = Activitฤศi
+confirm_delete_selected = ศtergi toate elementele selectate?
+webauthn_error_insecure = WebAuthn funcศioneazฤ doar prin conexiuni securizate. Pentru a testa folosind HTTP, poศi folosi "localhost" sau "127.0.0.1" ca origine
+webauthn_error_timeout = Limita de timp a fost depฤศitฤ รฎnainte ca cheia ta sฤ poatฤ fi cititฤ. Reรฎncarcฤ pagina ศi reรฎncearcฤ.
+copy_error = Copiere eศuatฤ
+concept_user_individual = Individual
+unknown = Necunoscut
+home = Acasฤ
+dashboard = Panou de Control
+version = Versiune
+powered_by = Susศinut de %s
+active_stopwatch = Monitorizor de timp activ
+more_items = Mai multe elemente
+
+[editor]
+table_modal.header = Adaugฤ tabel
+table_modal.placeholder.content = Conศinut
+table_modal.label.rows = Rรขnduri
+table_modal.label.columns = Coloane
+buttons.list.ordered.tooltip = Adaugฤ o listฤ numerotatฤ
+table_modal.placeholder.header = Antet
+buttons.italic.tooltip = Adaugฤ text cursiv
+buttons.mention.tooltip = Menศioneazฤ un utilizator sau o echipฤ
+buttons.new_table.tooltip = Adaugฤ tabel
+buttons.bold.tooltip = Adaugฤ text aldin
+buttons.code.tooltip = Adaugฤ cod
+buttons.quote.tooltip = Citeazฤ text
+buttons.link.tooltip = Adaugฤ un link
+
+[filter]
+string.asc = A - Z
+string.desc = Z - A
+
+[error]
+server_internal = Eroare internฤ a serverului
+network_error = Eroare de reศea
+
+[startpage]
+install = Uศor de instalat
+license = Sursฤ deschisฤ
+
+[install]
+require_db_desc = Forgejo are nevoie de MySQL, PostgreSQL, SQLite3 sau TiDB (protocol MySQL).
+db_title = Setฤri bazฤ de date
+db_type = Tipul bazei de date
+user = Nume de utilizator
+ssl_mode = SSL
+path = Cale
+sqlite_helper = Calea fiศierului pentru baza de date SQLite3. Introdu o cale absolutฤ dacฤ rulezi Forgejo ca serviciu.
+reinstall_error = รncerci sฤ instalezi รฎntr-o bazฤ de date Forgejo care existฤ deja
+err_empty_db_path = Calea cฤtre baza de date SQLite3 nu poate fi goalฤ.
+no_admin_and_disable_registration = Nu poศi dezactiva propria รฎnregistrare a utilizatorilor fฤrฤ un cont de administrator.
+err_empty_admin_password = Parola administratorului nu poate fi goalฤ.
+err_empty_admin_email = Emailul administratorului nu poate fi gol.
+err_admin_name_is_invalid = Numele de utilizator al administratorului este invalid
+general_title = Setฤri generale
+ssh_port = Port pentru serverul SSH
+ssh_port_helper = Numฤrul de port care va fi folosit de serverul SSH. Lasฤ gol pentru a dezactiva serverul SSH.
+http_port = Port de ascultare HTTP
+http_port_helper = Numฤr de port care va fi folosit de serverul web Forgejo.
+app_url = URL de bazฤ
+app_url_helper = Adresa de bazฤ pentru URL-uri de clonare HTTP(S) ศi notificฤri prin email.
+log_root_path = Cale pentru loguri
+log_root_path_helper = Fiศiere cu loguri vor fi scrise รฎn acest dosar.
+optional_title = Setฤri opศionale
+email_title = Setฤri pentru email
+smtp_addr = Host SMTP
+smtp_port = Port SMTP
+mailer_user = Nume de utilizator SMTP
+mailer_password = Parolฤ SMTP
+mail_notify = Porneศte notificฤri prin email
+server_service_title = Setฤri pentru server ศi servicii terศe
+offline_mode.description = Dezactiveazฤ reศele de livrare a conศinutului (CDN) terศe ศi oferฤ toate resursele รฎn mod local.
+disable_gravatar = Dezactiveazฤ Gravatar
+openid_signin = Porneศte conectare folosind OpenID
+openid_signin.description = Permite utilizatorilor conectarea prin OpenID.
+openid_signup = Porneศte รฎnregistrarea proprie folosind OpenID
+enable_captcha = Porneศte CAPTCHA pentru รฎnregistrare
+enable_captcha.description = Solicitฤ utilizatorilor sฤ treacฤ de CAPTCHA pentru a crea conturi.
+default_keep_email_private = Ascunde adresa de email รฎn mod implicit
+default_allow_create_organization = Permite crearea de organizaศii รฎn mod implicit
+default_allow_create_organization.description = Permite utilizatorilor noi sฤ creeze organizaศii รฎn mod implicit. Cรขnd aceastฤ opศiune este dezactivatฤ, un administrator va trebui sฤ ofere permisiune pentru crearea de organizaศii noilor utilizatori.
+admin_title = Setฤri pentru contul de administrator
+admin_name = Numele de utilizator al administratorului
+admin_password = Parola administratorului
+install_btn_confirm = Instaleazฤ Forgejo
+internal_token_failed = Eroare la generarea tokenului intern: %v
+secret_key_failed = Eroare la generarea cheii secrete: %v
+save_config_failed = Eroare la salvarea configuraศiei: %v
+invalid_admin_setting = Setฤrile pentru contul de administrator sunt invalide: %v
+allow_dots_in_usernames = Permite utilizatorilor sฤ foloseascฤ puncte รฎn numele de utilizator. Conturile existente nu vor fi afectate.
+password_algorithm = Algoritm de hash pentru parole
+invalid_password_algorithm = Algoritm de hash pentru parole invalid
+title = Configurare iniศialฤ
+smtp_from = Trimite email ca
+openid_signup.description = Permite utilizatorilor sฤ creeze conturi folosind OpenID dacฤ รฎnregistrarea proprie este pornitฤ.
+test_git_failed = Eroare la testarea comenzii โgitโ: %v
+sqlite3_not_available = Aceastฤ versiune de Forgejo nu este compatibilฤ cu SQLite3. Te rog descarcฤ versiunea binarฤ oficialฤ de la %s (nu versiunea โgobuildโ).
+password = Parolฤ
+reinstall_confirm_message = Reinstalarea cu o bazฤ de date Forgejo care existฤ deja poate cauza probleme multiple. รn cele mai multe cazuri, ar trebui sฤ รฎศi foloseศti โapp.iniโ existent pentru a rula Forgejo. Dacฤ ศtii ce faci, confirmฤ urmฤtoarele:
+reinstall_confirm_check_3 = Confirmi cฤ eศti absolut sigur cฤ acest Forgejo ruleazฤ cu locaศia app.ini corectฤ ศi cฤ eศti sigur cฤ trebuie sฤ reinstalezi. Confirmi cฤ ai luat la cunoศtinศฤ riscurile de mai sus.
+admin_email = Adresa de email
+docker_helper = Dacฤ rulezi Forgejo รฎn Docker, mai รฎntรขi citeศte documentaศia รฎnainte de a schimba setฤri.
+lfs_path = Cale rฤdฤcinฤ pentru Git LFS
+domain_helper = Domeniul sau adresa host pentru acest server.
+install = Instalare
+db_name = Numele bazei de date
+allow_only_external_registration.description = Utilizatorii รฎศi vor putea crea conturi noi doar folosind servicii externe configurate.
+admin_setting.description = Crearea unui cont de administrator este opศionalฤ. Primul utilizator รฎnregistrat va deveni administrator รฎn mod automat.
+confirm_password = Confirmฤ parola
+enable_update_checker = Porneศte verificarea pentru actualizฤri
+db_schema_helper = Lasฤ gol pentru baza de date implicitฤ (โpublicโ).
+smtp_from_invalid = Adresa "Trimite email ca" este invalidฤ
+smtp_from_helper = Adresa de email pe care Forgejo o va utiliza. Introdu o adresฤ de email simplฤ sau foloseศte formatul โ"Nume" โ.
+disable_registration = Dezactiveazฤ รฎnregistrarea proprie
+allow_only_external_registration = Permite รฎnregistrare doar prin servicii externe
+default_keep_email_private.description = Porneศte ascunderea adresei de email pentru utilizatori noi รฎn mod implicit astfel รฎncรขt aceastฤ informaศie sฤ nu fie scursฤ imediat dupฤ รฎnregistrare.
+invalid_app_data_path = Calea pentru datele aplicaศiei este invalidฤ: %v
+no_reply_address_helper = Domeniu pentru utilizatorii cu adresฤ de email ascunsฤ. De exemplu, utilizatorul โjoeโ va fi conectat la Git ca โjoe@noreply.example.orgโ dacฤ domeniul pentru adrese de email ascunse este โnoreply.example.orgโ.
+reinstall_confirm_check_1 = Datele criptate folosind SECRET_KEY din app.ini ar putea fi pierdute: s-ar putea ca utilizatorii sฤ nu se mai poatฤ conecta folosing 2FA/OTP ศi oglinzile ar putea sฤ nu mai funcศioneze corect. Bifรขnd aceastฤ opศiune confirmฤ cฤ fiศierul app.ini curent conศine valoarea corectฤ pentru SECRET_KEY.
+config_location_hint = Aceste opศiuni de configurare vor fi salvate รฎn:
+err_admin_name_is_reserved = Numele de utilizator al administratorului este invalid, numele de utilizator este rezervat
+invalid_db_table = Tabelul โ%sโ al bazei de date este invalid: %v
+err_admin_name_pattern_not_allowed = Numele de utilizator al administratorului este invalid, numele de utilizator se potriveศte cu un model rezervat
+domain = Domeniul serverului
+require_sign_in_view.description = Limiteazฤ accesul la conศinut cฤtre utilizatori conectaศi. Oaspeศii vor putea sฤ viziteze doar paginile de autentificare.
+invalid_db_setting = Setฤrile pentru bazฤ de date sunt invalide: %v
+no_reply_address = Domeniu pentru adrese de email ascunse
+
+[search]
+user_kind = Cautฤ utilizatori...
+team_kind = Cautฤ echipe...
+code_kind = Cautฤ cod...
+project_kind = Cautฤ proiecte...
+package_kind = Cautฤ pachete...
+org_kind = Cautฤ organizaศii...
+code_search_unavailable = Cฤutarea de cod nu este disponibilฤ momentan. Te rog contacteazฤ administratorul site-ului.
+keyword_search_unavailable = Cฤutarea dupฤ cuvรขnt cheie nu este disponibilฤ momentan. Te rog contacteazฤ administratorul site-ului.
+no_results = Nu a fost gฤsit niciun rezultat corespunzฤtor.
+
+[aria]
+navbar = Barฤ de navigare
+footer = Subsol
+footer.software = Despre acest software
+footer.links = Link-uri
+
+[heatmap]
+contributions_zero = Nicio contribuศie
+contributions_format = {contributions} pe {day} {month} {year}
+contributions_few = contribuศii
+less = Mai puศin
+number_of_contributions_in_the_last_12_months = %s contribuศii รฎn ultimele 12 luni
+more = Mai mult
+contributions_one = contribuศie
\ No newline at end of file
diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini
index 30cb893fa0..4820a60ca8 100644
--- a/options/locale/locale_ru-RU.ini
+++ b/options/locale/locale_ru-RU.ini
@@ -17,14 +17,14 @@ page=ะกััะฐะฝะธัะฐ
template=ะจะฐะฑะปะพะฝ
language=ะฏะทัะบ
notifications=ะฃะฒะตะดะพะผะปะตะฝะธั
-active_stopwatch=ะขัะตะบะตั ัะฐะฑะพัะตะณะพ ะฒัะตะผะตะฝะธ
+active_stopwatch=ะกััััะธะบ ะทะฐััะฐัะตะฝะฝะพะณะพ ะฒัะตะผะตะฝะธ
create_new=ะกะพะทะดะฐััโฆ
user_profile_and_more=ะัะพัะธะปั ะธ ะฝะฐัััะพะนะบะธโฆ
signed_in_as=ะั ะฒะพัะปะธ ะบะฐะบ
enable_javascript=ะะปั ััะพะณะพ ัะฐะนัะฐ ััะตะฑัะตััั ะฟะพะดะดะตัะถะบะฐ JavaScript.
toc=ะกะพะดะตัะถะฐะฝะธะต
licenses=ะะธัะตะฝะทะธะธ
-return_to_forgejo=ะะตัะฝััััั ะบ Forgejo
+return_to_forgejo=ะะตัะฝััััั ะฒ Forgejo
username=ะะผั ะฟะพะปัะทะพะฒะฐัะตะปั
email=ะะดัะตั ัะป. ะฟะพััั
@@ -33,19 +33,19 @@ access_token=ะขะพะบะตะฝ ะดะพัััะฟะฐ
re_type=ะะพะดัะฒะตัะถะดะตะฝะธะต ะฟะฐัะพะปั
captcha=CAPTCHA
twofa=ะะฒัั
ัะฐะบัะพัะฝะฐั ะฐััะตะฝัะธัะธะบะฐัะธั
-twofa_scratch=Scratch-ะบะพะด 2ะคะ
+twofa_scratch=ะะพะด ะฒะพัััะฐะฝะพะฒะปะตะฝะธั 2ะคะ
passcode=ะะพะด
-webauthn_insert_key=ะััะฐะฒััะต ะฒะฐั ะบะปัั ะฑะตะทะพะฟะฐัะฝะพััะธ
-webauthn_sign_in=ะะฐะถะผะธัะต ะบะฝะพะฟะบั ะฝะฐ ะบะปััะต ะฑะตะทะพะฟะฐัะฝะพััะธ. ะัะปะธ ะฒะฐั ะบะปัั ะฑะตะทะพะฟะฐัะฝะพััะธ ะฝะต ะธะผะตะตั ะบะฝะพะฟะบะธ, ะฒััะฐะฒััะต ะตะณะพ ัะฝะพะฒะฐ.
-webauthn_press_button=ะะพะถะฐะปัะนััะฐ, ะฝะฐะถะผะธัะต ะบะฝะพะฟะบั ะฝะฐ ะบะปััะต ะฑะตะทะพะฟะฐัะฝะพััะธโฆ
+webauthn_insert_key=ะััะฐะฒััะต ะฒะฐั ัะพะบะตะฝ ะฐะฒัะพัะธะทะฐัะธะธ
+webauthn_sign_in=ะะพะดัะฒะตัะดะธัะต ะดะตะนััะฒะธะต ะฝะฐ ัะพะบะตะฝะต ะฐะฒัะพัะธะทะฐัะธะธ. ะัะปะธ ะฝะฐ ะฒะฐัะตะผ ัะพะบะตะฝะต ะฝะตั ะบะฝะพะฟะบะธ, ะฒััะฐะฒััะต ะตะณะพ ะทะฐะฝะพะฒะพ.
+webauthn_press_button=ะะพะดัะฒะตัะดะธัะต ะดะตะนััะฒะธะต ะฝะฐ ัะพะบะตะฝะต ะฐะฒัะพัะธะทะฐัะธะธโฆ
webauthn_use_twofa=ะัะฟะพะปัะทัะนัะต ะดะฒัั
ัะฐะบัะพัะฝัะน ะบะพะด ั ะฒะฐัะตะณะพ ัะตะปะตัะพะฝะฐ
-webauthn_error=ะะต ัะดะฐะปะพัั ะฟัะพัะธัะฐัั ะฒะฐั ะบะปัั ะฑะตะทะพะฟะฐัะฝะพััะธ.
+webauthn_error=ะะต ัะดะฐะปะพัั ะฟัะพัะธัะฐัั ัะพะบะตะฝ ะฐะฒัะพัะธะทะฐัะธะธ.
webauthn_unsupported_browser=ะะฐั ะฑัะฐัะทะตั ะฒ ะฝะฐััะพััะตะต ะฒัะตะผั ะฝะต ะฟะพะดะดะตัะถะธะฒะฐะตั WebAuthn.
webauthn_error_unknown=ะัะพะธะทะพัะปะฐ ะฝะตะธะทะฒะตััะฝะฐั ะพัะธะฑะบะฐ. ะะพะฒัะพัะธัะต ะฟะพะฟััะบั.
webauthn_error_insecure=WebAuthn ะฟะพะดะดะตัะถะธะฒะฐะตั ัะพะปัะบะพ ะฑะตะทะพะฟะฐัะฝัะต ัะพะตะดะธะฝะตะฝะธั. ะะปั ัะตััะธัะพะฒะฐะฝะธั ะฟะพ HTTP ะผะพะถะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั "localhost" ะธะปะธ "127.0.0.1"
webauthn_error_unable_to_process=ะกะตัะฒะตั ะฝะต ัะผะพะณ ะพะฑัะฐะฑะพัะฐัั ะฒะฐั ะทะฐะฟัะพั.
-webauthn_error_duplicated=ะะฐะฝะฝัะน ะบะปัั ะฑะตะทะพะฟะฐัะฝะพััะธ ะฝะต ัะฐะทัะตัะตะฝ ะดะปั ััะพะณะพ ะทะฐะฟัะพัะฐ. ะะพะถะฐะปัะนััะฐ, ัะฑะตะดะธัะตัั, ััะพ ะบะปัั ะฝะต ัะตะณะธัััะธัะพะฒะฐะปัั ัะฐะฝะตะต.
+webauthn_error_duplicated=ะญัะพั ัะพะบะตะฝ ะฐะฒัะพัะธะทะฐัะธะธ ะฝะต ัะฐะทัะตัะตะฝ ะดะปั ะฒัะฟะพะปะฝะตะฝะธั ััะพะณะพ ะทะฐะฟัะพัะฐ. ะฃะฑะตะดะธัะตัั, ััะพ ัะพะบะตะฝ ะฝะต ะฑัะป ะทะฐัะตะณะธัััะธัะพะฒะฐะฝ ัะฐะฝะตะต.
webauthn_error_empty=ะะตะพะฑั
ะพะดะธะผะพ ะทะฐะดะฐัั ะธะผั ะดะปั ััะพะณะพ ะบะปััะฐ.
webauthn_error_timeout=ะัะตะผั ะธััะตะบะปะพ ัะฐะฝััะต, ัะตะผ ะบะปัั ะฑัะป ะฟัะพัะธัะฐะฝ. ะะตัะตะทะฐะณััะทะธัะต ััั ัััะฐะฝะธัั ะธ ะฟะพะฒัะพัะธัะต ะฟะพะฟััะบั.
webauthn_reload=ะะฑะฝะพะฒะธัั
@@ -53,11 +53,11 @@ webauthn_reload=ะะฑะฝะพะฒะธัั
repository=ะ ะตะฟะพะทะธัะพัะธะน
organization=ะัะณะฐะฝะธะทะฐัะธั
mirror=ะะตัะบะฐะปะพ
-new_repo=ะะพะฒัะน ัะตะฟะพะทะธัะพัะธะน
-new_migrate=ะะพะฒะฐั ะผะธะณัะฐัะธั
+new_repo=ะกะพะทะดะฐัั ัะตะฟะพะทะธัะพัะธะน
+new_migrate=ะัะฟะพะปะฝะธัั ะผะธะณัะฐัะธั
new_mirror=ะะพะฒะพะต ะทะตัะบะฐะปะพ
new_fork=ะะพะฒะพะต ะพัะฒะตัะฒะปะตะฝะธะต ัะตะฟะพะทะธัะพัะธั
-new_org=ะะพะฒะฐั ะพัะณะฐะฝะธะทะฐัะธั
+new_org=ะกะพะทะดะฐัั ะพัะณะฐะฝะธะทะฐัะธั
new_project=ะะพะฒัะน ะฟัะพะตะบั
new_project_column=ะะพะฒัะน ััะพะปะฑะตั
manage_org=ะฃะฟัะฐะฒะปะตะฝะธะต ะพัะณะฐะฝะธะทะฐัะธัะผะธ
@@ -100,7 +100,7 @@ copy=ะะพะฟะธัะพะฒะฐัั
copy_url=ะะพะฟะธัะพะฒะฐัั ัััะปะบั
copy_hash=ะะพะฟะธัะพะฒะฐัั ั
ะตั
copy_content=ะะพะฟะธัะพะฒะฐัั ัะพะดะตัะถะธะผะพะต
-copy_branch=ะะพะฟะธัะพะฒะฐัั ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะบะธ
+copy_branch=ะะพะฟะธัะพะฒะฐัั ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธ
copy_success=ะกะบะพะฟะธัะพะฒะฐะฝะพ!
copy_error=ะะต ัะดะฐะปะพัั ัะบะพะฟะธัะพะฒะฐัั
copy_type_unsupported=ะะตะฒะพะทะผะพะถะฝะพ ัะบะพะฟะธัะพะฒะฐัั ััะพั ัะธะฟ ัะฐะนะปะฐ
@@ -110,7 +110,7 @@ preview=ะัะตะดะฟัะพัะผะพัั
loading=ะะฐะณััะทะบะฐโฆ
error=ะัะธะฑะบะฐ
-error404=Cััะฐะฝะธัะฐ, ะบะพัะพััั ะฒั ะฟััะฐะตัะตัั ะพัะบัััั, ะฝะต ัััะตััะฒัะตั , ะปะธะฑะพ ั ะฒะฐั ะฝะตะดะพััะฐัะพัะฝะพ ะฟัะฐะฒ ะดะปั ะตะต ะฟัะพัะผะพััะฐ.
+error404=Cััะฐะฝะธัะฐ, ะบะพัะพััั ะฒั ะฟััะฐะตัะตัั ะพัะบัััั, ะฝะต ัััะตััะฒัะตั , ะฑัะปะฐ ัะดะฐะปะตะฝะฐ , ะปะธะฑะพ ั ะฒะฐั ะฝะตะดะพััะฐัะพัะฝะพ ะฟัะฐะฒ ะดะปั ะตั ะฟัะพัะผะพััะฐ.
go_back=ะะฐะทะฐะด
never=ะะธะบะพะณะดะฐ
@@ -152,12 +152,21 @@ filter.is_mirror = ะะตัะบะฐะปะฐ
filter.is_template = ะจะฐะฑะปะพะฝั
filter.not_template = ะะต ัะฐะฑะปะพะฝั
filter.public = ะัะฑะปะธัะฝัะต
-filter.private = ะัะธะฒะฐัะฝัะต
+filter.private = ะงะฐััะฝัะต
filter.is_archived = ะัั
ะธะฒะธัะพะฒะฐะฝะฝัะต
filter.not_mirror = ะะต ะทะตัะบะฐะปะฐ
-more_items = ะะพะปััะต ัะปะตะผะตะฝัะพะฒ
+more_items = ะะพะปััะต ัะฐะทะดะตะปะพะฒ
invalid_data = ะะตะฒะตัะฝัะต ะดะฐะฝะฝัะต: %v
copy_generic = ะะพะฟะธัะพะฒะฐัั ะฒ ะฑััะตั ะพะฑะผะตะฝะฐ
+test = ะัะพะฒะตัะธัั
+error413 = ะะฐัะฐ ะบะฒะพัะฐ ะธััะตัะฟะฐะฝะฐ.
+new_migrate.link = ะัะฟะพะปะฝะธัั ะฟะตัะตะฝะพั
+new_org.link = ะกะพะทะดะฐัั ะพัะณะฐะฝะธะทะฐัะธั
+new_repo.title = ะะพะฒัะน ัะตะฟะพะทะธัะพัะธะน
+new_migrate.title = ะะพะฒัะน ะฟะตัะตะฝะพั
+new_org.title = ะะพะฒะฐั ะพัะณะฐะฝะธะทะฐัะธั
+new_repo.link = ะกะพะทะดะฐัั ัะตะฟะพะทะธัะพัะธะน
+copy_path = ะะพะฟะธัะพะฒะฐัั ะฟััั
[aria]
navbar=ะะฐะฝะตะปั ะฝะฐะฒะธะณะฐัะธะธ
@@ -189,6 +198,18 @@ buttons.ref.tooltip=ะกะพัะปะฐัััั ะฝะฐ ะทะฐะดะฐัั ะธะปะธ ะทะฐะฟัะพั ั
buttons.switch_to_legacy.tooltip=ะัะฟะพะปัะทะพะฒะฐัั ััะฐััะน ัะตะดะฐะบัะพั
buttons.enable_monospace_font=ะะบะปััะธัั ะผะพะฝะพัะธัะธะฝะฝัะน ััะธัั
buttons.disable_monospace_font=ะัะบะปััะธัั ะผะพะฝะพัะธัะธะฝะฝัะน ััะธัั
+buttons.unindent.tooltip = ะฃะผะตะฝััะธัั ะฒะปะพะถะตะฝะฝะพััั ะฝะฐ 1
+buttons.indent.tooltip = ะฃะฒะตะปะธัะธัั ะฒะปะพะถะตะฝะฝะพััั ะฝะฐ 1
+buttons.new_table.tooltip = ะกะพะทะดะฐัั ัะฐะฑะปะธัั
+table_modal.label.columns = ะะพะป-ะฒะพ ััะพะปะฑัะพะฒ
+table_modal.header = ะกะพะทะดะฐะฝะธะต ัะฐะฑะปะธัั
+table_modal.placeholder.header = ะะฐะณะพะปะพะฒะพะบ
+table_modal.placeholder.content = ะกะพะดะตัะถะธะผะพะต
+table_modal.label.rows = ะะพะป-ะฒะพ ัััะพะบ
+link_modal.header = ะะพะฑะฐะฒะธัั ัััะปะบั
+link_modal.url = ะกััะปะบะฐ
+link_modal.description = ะะฟะธัะฐะฝะธะต
+link_modal.paste_reminder = ะะผะตั ัััะปะบั ะฒ ะฑััะตัะต ะพะฑะผะตะฝะฐ, ะฒั ะผะพะถะตัะต ะฒััะฐะฒะธัั ะตั ะฝะฐะฟััะผัั ะฒ ัะตะบัั, ััะพะฑั ัะพะทะดะฐัั ัััะปะบั ั ะพะฟะธัะฐะฝะธะตะผ.
[filter]
string.asc=A - ะฏ
@@ -196,7 +217,7 @@ string.desc=ะฏ - ะ
[error]
occurred=ะัะพะธะทะพัะปะฐ ะพัะธะฑะบะฐ
-report_message=ะัะปะธ ะฒั ััะธัะฐะตัะต, ััะพ ััะพ ะฑะฐะณ Forgejo, ะฟะพะถะฐะปัะนััะฐ, ะฟะพะธัะธัะต ะทะฐะดะฐัั ะฝะฐ Codeberg ะธะปะธ ัะพะทะดะฐะนัะต ะฝะพะฒัั ะฟัะธ ะฝะตะพะฑั
ะพะดะธะผะพััะธ.
+report_message=ะัะปะธ ะฒั ััะธัะฐะตัะต, ััะพ ััะพ ะฑะฐะณ Forgejo, ะฟะพะถะฐะปัะนััะฐ, ะฟะพะธัะธัะต ะทะฐะดะฐัั ะฝะฐ Codeberg ะธะปะธ ัะพะทะดะฐะนัะต ะฝะพะฒัั ะฟัะธ ะฝะตะพะฑั
ะพะดะธะผะพััะธ.
missing_csrf=ะะตะบะพััะตะบัะฝัะน ะทะฐะฟัะพั: ะพััััััะฒัะตั ัะพะบะตะฝ CSRF
invalid_csrf=ะะตะบะพััะตะบัะฝัะน ะทะฐะฟัะพั: ะฝะตะฒะตัะฝัะน ัะพะบะตะฝ CSRF
not_found=ะฆะตะปั ะฝะต ะฝะฐะนะดะตะฝะฐ.
@@ -206,18 +227,18 @@ server_internal = ะะฝัััะตะฝะฝัั ะพัะธะฑะบะฐ ัะตัะฒะตัะฐ
[startpage]
app_desc=ะฃะดะพะฑะฝัะน, ัะฐะผะพััะพััะตะปัะฝัะน ั
ะพััะธะฝะณ Git-ัะตะฟะพะทะธัะพัะธะตะฒ
install=ะัะพััะพะน ะฒ ัััะฐะฝะพะฒะบะต
-install_desc=ะัะพััะพ ะทะฐะฟัััะธัะต ะธัะฟะพะปะฝัะตะผัะน ัะฐะนะป ะดะปั ะฒะฐัะตะน ะฟะปะฐััะพัะผั, ัะฐะทะฒะตัะฝะธัะต ัะตัะตะท Docker , ะธะปะธ ัััะฐะฝะพะฒะธัะต ั ะฟะพะผะพััั ะผะตะฝะตะดะถะตัะฐ ะฟะฐะบะตัะพะฒ .
+install_desc=ะัะพััะพ ะทะฐะฟัััะธัะต ะธัะฟะพะปะฝัะตะผัะน ัะฐะนะป ะดะปั ะฒะฐัะตะน ะฟะปะฐััะพัะผั, ัะฐะทะฒะตัะฝะธัะต ัะตัะตะท Docker , ะธะปะธ ัััะฐะฝะพะฒะธัะต ั ะฟะพะผะพััั ะผะตะฝะตะดะถะตัะฐ ะฟะฐะบะตัะพะฒ .
platform=ะัะพััะฟะปะฐััะพัะผะตะฝะฝัะน
-platform_desc=Forgejo ัะฐะฑะพัะฐะตั ะฝะฐ ะปัะฑะพะน ะฟะปะฐััะพัะผะต, ะฟะพะดะดะตัะถะธะฒะฐะตะผะพะน Go : Windows, macOS, Linux, ARM ะธ ั. ะด. ะัะฑะธัะฐะนัะต, ััะพ ะฒะฐะผ ะฑะพะปััะต ะฝัะฐะฒะธััั!
+platform_desc=Forgejo ะผะพะถะตั ัะฐะฑะพัะฐัั ะฝะฐ ะผะฝะพะณะธั
ะพัะบััััั
ะะก ะฒัะพะดะต Linux ะธ FreeBSD, ะฐ ัะฐะบะถะต ะฝะฐ ะพะฑะพััะดะพะฒะฐะฝะธะธ ัะฐะทะปะธัะฝัั
ะฐัั
ะธัะตะบััั. ะัะฑะตัะธัะต ัั, ััะพ ะฝัะฐะฒะธััั ะฒะฐะผ!
lightweight=ะะตะณะบะพะฒะตัะฝัะน
lightweight_desc=Forgejo ะธะผะตะตั ะฝะธะทะบะธะต ัะธััะตะผะฝัะต ััะตะฑะพะฒะฐะฝะธั ะธ ะผะพะถะตั ัะฐะฑะพัะฐัั ะฝะฐ ะฝะตะดะพัะพะณะพะผ Raspberry Pi. ะญะบะพะฝะพะผััะต ัะตััััั ะฒะฐัะตะน ะผะฐัะธะฝั!
license=ะัะบััััะน ะธัั
ะพะดะฝัะน ะบะพะด
-license_desc=ะัั ััะพ ะฝะฐ Forgejo ! ะัะธัะพะตะดะธะฝัะนัะตัั ะบ ะฝะฐะผ, ะฒะฝะพัั ะฒะบะปะฐะด , ััะพะฑั ัะดะตะปะฐัั ััะพั ะฟัะพะตะบั ะตัั ะปัััะต. ะะต ะฑะพะนัะตัั ะฟะพะผะพะณะฐัั!
+license_desc=ะัั ััะพ ะฝะฐ Forgejo ! ะัะธัะพะตะดะธะฝัะนัะตัั ะบ ะฝะฐะผ, ะฒะฝะพัั ะฒะบะปะฐะด , ััะพะฑั ัะดะตะปะฐัั ััะพั ะฟัะพะตะบั ะตัั ะปัััะต. ะะต ะฑะพะนัะตัั ะฟะพะผะพะณะฐัั!
[install]
install=ะฃััะฐะฝะพะฒะบะฐ
title=ะะฐัะฐะปัะฝะฐั ะบะพะฝัะธะณััะฐัะธั
-docker_helper=ะัะปะธ ะฒั ะทะฐะฟััะบะฐะตัะต Forgejo ะฟะพะด Docker, ะฟะพะถะฐะปัะนััะฐ, ะพะทะฝะฐะบะพะผััะตัั ั ะดะพะบัะผะตะฝัะฐัะธะตะน , ะฟัะตะถะดะต ัะตะผ ะธะทะผะตะฝััั ะปัะฑัะต ะฝะฐัััะพะนะบะธ.
+docker_helper=ะัะปะธ ะฒั ะทะฐะฟััะบะฐะตัะต Forgejo ะฟะพะด Docker, ะฟัะตะถะดะต ัะตะผ ะธะทะผะตะฝััั ะปัะฑัะต ะฝะฐัััะพะนะบะธ, ะฟะพะถะฐะปัะนััะฐ, ะพะทะฝะฐะบะพะผััะตัั ั ะดะพะบัะผะตะฝัะฐัะธะตะน .
require_db_desc=Forgejo ััะตะฑัะตััั MySQL, PostgreSQL, SQLite3 ะธะปะธ TiDB (ะฟะพ ะฟัะพัะพะบะพะปั MySQL).
db_title=ะะฐัััะพะนะบะธ ะฑะฐะทั ะดะฐะฝะฝัั
db_type=ะขะธะฟ ะฑะฐะทั ะดะฐะฝะฝัั
@@ -239,9 +260,9 @@ err_empty_db_path=ะััั ะบ ะฑะฐะทะต ะดะฐะฝะฝัั
SQLite3 ะฝะต ะผะพะถะตั ะฑั
no_admin_and_disable_registration=ะั ะฝะต ะผะพะถะตัะต ะพัะบะปััะธัั ัะตะณะธัััะฐัะธั ะดะพ ัะพะทะดะฐะฝะธั ััััะฝะพะน ะทะฐะฟะธัะธ ะฐะดะผะธะฝะธัััะฐัะพัะฐ.
err_empty_admin_password=ะะฐัะพะปั ะฐะดะผะธะฝะธัััะฐัะพัะฐ ะฝะต ะผะพะถะตั ะฑััั ะฟััััะผ.
err_empty_admin_email=ะะดัะตั ัะป. ะฟะพััั ะฐะดะผะธะฝะธัััะฐัะพัะฐ ะฝะต ะผะพะถะตั ะฑััั ะฟััััะผ.
-err_admin_name_is_reserved=ะะตะฒะตัะฝะพะต ะธะผั ะฐะดะผะธะฝะธัััะฐัะพัะฐ, ััะพ ะธะผั ะทะฐัะตะทะตัะฒะธัะพะฒะฐะฝะพ
-err_admin_name_pattern_not_allowed=ะะตะฒะตัะฝะพะต ะธะผั ะฐะดะผะธะฝะธัััะฐัะพัะฐ, ะธะผั ะฟะพะฟะฐะดะฐะตั ะฟะพะด ะทะฐัะตะทะตัะฒะธัะพะฒะฐะฝะฝัะน ัะฐะฑะปะพะฝ
-err_admin_name_is_invalid=ะะตะฒะตัะฝะพะต ะธะผั ะฐะดะผะธะฝะธัััะฐัะพัะฐ
+err_admin_name_is_reserved=ะะตะฟะพะดั
ะพะดััะตะต ะธะผั ะฐะดะผะธะฝะธัััะฐัะพัะฐ, ะพะฝะพ ะทะฐัะตะทะตัะฒะธัะพะฒะฐะฝะพ
+err_admin_name_pattern_not_allowed=ะะตะฟะพะดั
ะพะดััะตะต ะธะผั ะฐะดะผะธะฝะธัััะฐัะพัะฐ, ะพะฝะพ ะฟะพะฟะฐะดะฐะตั ะฟะพะด ัะฐะฑะปะพะฝ ะทะฐัะตะทะตัะฒะธัะพะฒะฐะฝะฝัั
+err_admin_name_is_invalid=ะะตะฟะพะดั
ะพะดััะตะต ะธะผั ะฐะดะผะธะฝะธัััะฐัะพัะฐ
general_title=ะัะฝะพะฒะฝัะต ะฝะฐัััะพะนะบะธ
app_name=ะะฐะทะฒะฐะฝะธะต ัะตัะฒะตัะฐ
@@ -250,16 +271,16 @@ repo_path=ะััั ะดะพ ะบะฐัะฐะปะพะณะฐ ัะตะฟะพะทะธัะพัะธะตะฒ
repo_path_helper=ะัะต ัะดะฐะปัะฝะฝัะต Git ัะตะฟะพะทะธัะพัะธะธ ะฑัะดัั ัะพั
ัะฐะฝะตะฝั ะฒ ััะพะผ ะบะฐัะฐะปะพะณะต.
lfs_path=ะััั ะดะพ ะบะพัะฝะตะฒะพะณะพ ะบะฐัะฐะปะพะณะฐ Git LFS
lfs_path_helper=ะ ััะพะผ ะบะฐัะฐะปะพะณะต ะฑัะดัั ั
ัะฐะฝะธัััั ัะฐะนะปั Git LFS. ะััะฐะฒััะต ะฟััััะผ, ััะพะฑั ะพัะบะปััะธัั LFS.
-run_user=ะะฐะฟััะบ ะพั ะธะผะตะฝะธ ะฟะพะปัะทะพะฒะฐัะตะปั
+run_user=ะัะฟะพะปะฝะตะฝะธะต ะฟะพะด ะฟะพะปัะทะพะฒะฐัะตะปะตะผ
run_user_helper=ะะผั ะฟะพะปัะทะพะฒะฐัะตะปั ะพะฟะตัะฐัะธะพะฝะฝะพะน ัะธััะตะผั, ะฟะพะด ะบะพัะพััะผ ัะฐะฑะพัะฐะตั Forgejo. ะะฑัะฐัะธัะต ะฒะฝะธะผะฐะฝะธะต, ััะพ ััะพั ะฟะพะปัะทะพะฒะฐัะตะปั ะดะพะปะถะตะฝ ะธะผะตัั ะดะพัััะฟ ะบ ะบะพัะฝะตะฒะพะผั ะฟััะธ ัะตะฟะพะทะธัะพัะธะตะฒ.
domain=ะะพะผะตะฝ ัะตัะฒะตัะฐ
domain_helper=ะะพะผะตะฝ ะธะปะธ ะฐะดัะตั ั
ะพััะฐ ะดะปั ัะตัะฒะตัะฐ.
ssh_port=ะะพัั SSH-ัะตัะฒะตัะฐ
-ssh_port_helper=ะะพะผะตั ะฟะพััะฐ, ะธัะฟะพะปัะทัะตะผัะน SSH-ัะตัะฒะตัะพะผ. ะััะฐะฒััะต ะฟััััะผ ะดะปั ะพัะบะปััะตะฝะธั ะดะพัััะฟะฐ ะฟะพ SSH.
+ssh_port_helper=ะะพะผะตั ะฟะพััะฐ, ะธัะฟะพะปัะทัะตะผัะน ะดะปั ะฒั
ะพะดััะธั
ะฟะพะดะบะปััะตะฝะธะน ะฟะพ SSH. ะััะฐะฒััะต ะฟััััะผ ะดะปั ะพัะบะปััะตะฝะธั ะดะพัััะฟะฐ ะฟะพ SSH.
http_port=ะะพัั HTTP-ัะตัะฒะตัะฐ
-http_port_helper=ะะพะผะตั ะฟะพััะฐ, ะธัะฟะพะปัะทัะตะผัะน ะฒะตะฑ-ัะตัะฒะตัะพะผ Forgejo.
-app_url=ะะฐะทะพะฒัะน URL Forgejo
-app_url_helper=ะญัะพั ะฟะฐัะฐะผะตัั ะฒะปะธัะตั ะฝะฐ URL ะดะปั ะบะปะพะฝะธัะพะฒะฐะฝะธั ะฟะพ HTTP/HTTPS ะธ ะฝะฐ ะฝะตะบะพัะพััะต ัะฒะตะดะพะผะปะตะฝะธั ะฟะพ ัะป. ะฟะพััะต.
+http_port_helper=ะะพะผะตั ะฟะพััะฐ, ะบะพัะพััะน ะฑัะดะตั ะฟัะพัะปััะธะฒะฐัััั ะฒะตะฑ-ัะตัะฒะตัะพะผ Forgejo.
+app_url=ะะฐะทะพะฒัะน URL
+app_url_helper=ะญัะพั ะฟะฐัะฐะผะตัั ะฒะปะธัะตั ะฝะฐ URL ะบะปะพะฝะธัะพะฒะฐะฝะธั ะฟะพ HTTP/HTTPS ะธ ะฝะฐ ัััะปะบะธ ะฒ ัะฒะตะดะพะผะปะตะฝะธัั
ะฟะพ ัะป. ะฟะพััะต.
log_root_path=ะััั ะถััะฝะฐะปะพะฒ
log_root_path_helper=ะคะฐะนะปั ะถััะฝะฐะปะฐ ะฑัะดัั ะทะฐะฟะธััะฒะฐัััั ะฒ ััะพั ะบะฐัะฐะปะพะณ.
@@ -267,9 +288,9 @@ optional_title=ะะพะฟะพะปะฝะธัะตะปัะฝัะต ะฝะฐัััะพะนะบะธ
email_title=ะะฐัััะพะนะบะธ ัะป. ะฟะพััั
smtp_addr=ะะดัะตั SMTP
smtp_port=ะะพัั SMTP
-smtp_from=ะัะฟัะฐะฒะปััั ะฟะธััะผะฐ ะพั
+smtp_from=ะัะฟัะฐะฒะธัะตะปั
smtp_from_helper=ะะดัะตั ัะป. ะฟะพััั, ะบะพัะพััะน ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั Forgejo. ะะฒะตะดะธัะต ะพะฑััะฝัะน ะฐะดัะตั ัะป. ะฟะพััั ะธะปะธ ะธัะฟะพะปัะทัะนัะต ัะพัะผะฐั "ะะผั" .
-mailer_user=ะะพะณะธะฝ SMTP
+mailer_user=ะะผั ะฟะพะปัะทะพะฒะฐัะตะปั SMTP
mailer_password=ะะฐัะพะปั SMTP
register_confirm=ะขัะตะฑะพะฒะฐัั ะฟะพะดัะฒะตัะถะดะตะฝะธะต ะฟะพ ัะป. ะฟะพััะต ะดะปั ัะตะณะธัััะฐัะธะธ
mail_notify=ะฃะฒะตะดะพะผะปะตะฝะธั ะฟะพ ัะป. ะฟะพััะต
@@ -277,9 +298,9 @@ server_service_title=ะะฐัััะพะนะบะธ ัะตัะฒะตัะฐ ะธ ะฒะฝะตัะฝะธั
ัะปั
offline_mode=ะะพะบะฐะปัะฝัะน ัะตะถะธะผ
offline_mode.description=ะัะบะปััะธัั ััะพัะพะฝะฝะธะต ัะปัะถะฑั ะดะพััะฐะฒะบะธ ะบะพะฝัะตะฝัะฐ ะธ ะฟะตัะตะดะฐะฒะฐัั ะฒัะต ัะตััััั ะธะท ะธั
ะปะพะบะฐะปัะฝัั
ะบะพะฟะธะน.
disable_gravatar=ะัะบะปััะธัั Gravatar
-disable_gravatar.description=ะัะบะปััะธัั Gravatar ะธ ะฟัะพัะธะต ััะพัะพะฝะฝะธะต ะธััะพัะฝะธะบะธ ะฐะฒะฐัะฐัะพะฒ. ะัะปะธ ั ะฟะพะปัะทะพะฒะฐัะตะปั ะฝะตั ะปะพะบะฐะปัะฝะพ ัััะฐะฝะพะฒะปะตะฝะฝะพะณะพ ะฐะฒะฐัะฐัะฐ, ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐะฝ ะฐะฒะฐัะฐั ะฟะพ ัะผะพะปัะฐะฝะธั.
-federated_avatar_lookup=ะคะตะดะตัะธัะพะฒะฐะฝะฝัะต ะฐะฒะฐัะฐัั
-federated_avatar_lookup.description=ะัะบะฐัั ะฐะฒะฐัะฐัั ะธัะฟะพะปัะทัั Libravatar.
+disable_gravatar.description=ะัะบะปััะธัั Gravatar ะธ ะฟัะพัะธะต ััะพัะพะฝะฝะธะต ะธััะพัะฝะธะบะธ ะธะทะพะฑัะฐะถะตะฝะธะน ะฟัะพัะธะปะตะน. ะัะปะธ ั ะฟะพะปัะทะพะฒะฐัะตะปั ะฝะตั ะปะพะบะฐะปัะฝะพ ัััะฐะฝะพะฒะปะตะฝะฝะพะณะพ ะธะทะพะฑัะฐะถะตะฝะธั ะฟัะพัะธะปั, ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐะฝะพ ะธะทะพะฑัะฐะถะตะฝะธะต ะฟะพ ัะผะพะปัะฐะฝะธั.
+federated_avatar_lookup=ะคะตะดะตัะธัะพะฒะฐะฝะฝัะต ะธะทะพะฑัะฐะถะตะฝะธั ะฟัะพัะธะปะตะน
+federated_avatar_lookup.description=ะัะบะฐัั ะธะทะพะฑัะฐะถะตะฝะธั ะฟัะพัะธะปะตะน, ะธัะฟะพะปัะทัั Libravatar.
disable_registration=ะัะบะปััะธัั ัะฐะผะพััะพััะตะปัะฝัั ัะตะณะธัััะฐัะธั
disable_registration.description=ะขะพะปัะบะพ ะฐะดะผะธะฝะธัััะฐัะพัั ัะผะพะณัั ัะพะทะดะฐะฒะฐัั ะฝะพะฒัะต ััััะฝัะต ะทะฐะฟะธัะธ ะฟะพะปัะทะพะฒะฐัะตะปะตะน. ะัะบะปััะตะฝะธะต ัะฐะผะพัะตะณะธัััะฐัะธะธ ะบัะฐะนะฝะต ัะตะบะพะผะตะฝะดะพะฒะฐะฝะพ, ัะฐะทะฒะต ััะพ ะตัะปะธ ะฒั ะฝะต ัะพะฑะธัะฐะตัะตัั ัะพะทะดะฐัั ะฟัะฑะปะธัะฝัะน ัะตัะฒะตั ะดะปั ะฒัะตั
ะธ ะณะพัะพะฒั ะฑะพัะพัััั ั ะฑะพะปััะธะผ ะบะพะปะธัะตััะฒะพะผ ัะฟะฐะผะฐ.
allow_only_external_registration.description=ะะพะปัะทะพะฒะฐัะตะปะธ ัะผะพะณัั ัะพะทะดะฐะฒะฐัั ะฝะพะฒัะต ััััะฝัะต ะทะฐะฟะธัะธ ัะพะปัะบะพ ัะตัะตะท ะดะพะฑะฐะฒะปะตะฝะฝัะต ััะพัะพะฝะฝะธะต ัะปัะถะฑั.
@@ -291,19 +312,19 @@ enable_captcha=CAPTCHA ะดะปั ัะตะณะธัััะฐัะธะธ
enable_captcha.description=ะขัะตะฑะพะฒะฐัั ะฟัะพั
ะพะถะดะตะฝะธะต CAPTCHA ะดะปั ัะตะณะธัััะฐัะธะธ ััััะฝัั
ะทะฐะฟะธัะตะน.
require_sign_in_view=ะขัะตะฑะพะฒะฐัั ะฐะฒัะพัะธะทะฐัะธั ะดะปั ะฟัะพัะผะพััะฐ ัะพะดะตัะถะธะผะพะณะพ
require_sign_in_view.description=ะขัะตะฑะพะฒะฐัั ะฝะฐะปะธัะธะต ััััะฝะพะน ะทะฐะฟะธัะธ ะดะปั ะฟัะพัะผะพััะฐ ัะพะดะตัะถะธะผะพะณะพ ัะตัะฒะตัะฐ. ะะพัะตัะธัะตะปะธ ัะฒะธะดัั ะปะธัั ัััะฐะฝะธัั ะฒั
ะพะดะฐ ะธ ัะตะณะธัััะฐัะธะธ.
-admin_setting.description=ะกะพะทะดะฐะฝะธะต ััััะฝะพะน ะทะฐะฟะธัะธ ะฐะดะผะธะฝะธัััะฐัะพัะฐ ะฝะตะพะฑัะทะฐัะตะปัะฝะพ. ะะตัะฒัะน ะทะฐัะตะณะธัััะธัะพะฒะฐะฝะฝัะน ะฟะพะปัะทะพะฒะฐัะตะปั ะฐะฒัะพะผะฐัะธัะตัะบะธ ััะฐะฝะพะฒะธััั ะฐะดะผะธะฝะธัััะฐัะพัะพะผ.
+admin_setting.description=ะกะพะทะดะฐะฝะธะต ััััะฝะพะน ะทะฐะฟะธัะธ ะฐะดะผะธะฝะธัััะฐัะพัะฐ ะฝะตะพะฑัะทะฐัะตะปัะฝะพ. ะะตัะฒัะน ะทะฐัะตะณะธัััะธัะพะฒะฐะฒัะธะนัั ะฟะพะปัะทะพะฒะฐัะตะปั ะฐะฒัะพะผะฐัะธัะตัะบะธ ััะฐะฝะตั ะฐะดะผะธะฝะธัััะฐัะพัะพะผ.
admin_title=ะฃัััะฝะฐั ะทะฐะฟะธัั ะฐะดะผะธะฝะธัััะฐัะพัะฐ
-admin_name=ะะพะณะธะฝ ะฐะดะผะธะฝะธัััะฐัะพัะฐ
+admin_name=ะะผั ะฐะดะผะธะฝะธัััะฐัะพัะฐ
admin_password=ะะฐัะพะปั
confirm_password=ะะพะดัะฒะตัะถะดะตะฝะธะต ะฟะฐัะพะปั
admin_email=ะะดัะตั ัะป. ะฟะพััั
install_btn_confirm=ะฃััะฐะฝะพะฒะธัั Forgejo
test_git_failed=ะะต ัะดะฐะปะพัั ะฟัะพะฒะตัะธัั ะบะพะผะฐะฝะดั ยซgitยป: %v
-sqlite3_not_available=ะญัะฐ ะฒะตััะธั Forgejo ะฝะต ะฟะพะดะดะตัะถะธะฒะฐะตั SQLite3. ะะพะถะฐะปัะนััะฐ, ะทะฐะณััะทะธัะต ะพัะธัะธะฐะปัะฝัั ะฑะธะฝะฐัะฝัั ัะฑะพัะบั ะธะท %s (ะฝะต ัะฑะพัะบั ยซgobuildยป).
+sqlite3_not_available=ะญัะฐ ะฒะตััะธั Forgejo ะฝะต ะฟะพะดะดะตัะถะธะฒะฐะตั SQLite3. ะะพะถะฐะปัะนััะฐ, ัะบะฐัะฐะนัะต ะพัะธัะธะฐะปัะฝัั ัะฑะพัะบั ะธะท %s (ะฝะต ะฒะตััะธั ยซgobuildยป).
invalid_db_setting=ะะตะบะพััะตะบัะฝัะต ะฝะฐัััะพะนะบะธ ะฑะฐะทั ะดะฐะฝะฝัั
: %v
invalid_db_table=ะขะฐะฑะปะธัะฐ ยซ%sยป ะฑะฐะทั ะดะฐะฝะฝัั
ะฝะตะบะพััะตะบัะฝะฐ: %v
-invalid_repo_path=ะะตะดะพะฟัััะธะผัะน ะฟััั ะบ ะบะพัะฝั ัะตะฟะพะทะธัะพัะธั: %v
-invalid_app_data_path=ะะตะฒะตัะฝัะน ะฟััั ะบ ะฟัะธะปะพะถะตะฝะธั: %v
+invalid_repo_path=ะะตะฒะตัะฝัะน ะฟััั ะบ ะบะพัะฝั ัะตะฟะพะทะธัะพัะธะตะฒ: %v
+invalid_app_data_path=ะะตะฒะตัะฝัะน ะฟััั ะบ ะดะฐะฝะฝัะผ ะฟัะธะปะพะถะตะฝะธั: %v
run_user_not_match=ะขะตะบััะธะน ะฟะพะปัะทะพะฒะฐัะตะปั ะฝะต ัะฒะปัะตััั ะฟะพะปัะทะพะฒะฐัะตะปะตะผ ะดะปั ะทะฐะฟััะบะฐ: %s -> %s
internal_token_failed=ะะต ัะดะฐะปะพัั ัะพะทะดะฐัั ะฒะฝัััะตะฝะฝะธะน ัะพะบะตะฝ: %v
secret_key_failed=ะะต ัะดะฐะปะพัั ัะพะทะดะฐัั ัะตะบัะตัะฝัะน ะบะปัั: %v
@@ -324,18 +345,18 @@ password_algorithm_helper=ะะฐะดะฐะนัะต ะฐะปะณะพัะธัะผ ั
ะตัะธัะพะฒะฐะฝะธั
enable_update_checker=ะัะพะฒะตัะบะฐ ะพะฑะฝะพะฒะปะตะฝะธะน
env_config_keys=ะะฐัััะพะนะบะฐ ะพะบััะถะตะฝะธั
env_config_keys_prompt=ะกะปะตะดัััะธะต ะฟะตัะตะผะตะฝะฝัะต ะพะบััะถะตะฝะธั ัะฐะบะถะต ะฑัะดัั ะฟัะธะผะตะฝะตะฝั ะบ ะฒะฐัะตะผั ะบะพะฝัะธะณััะฐัะธะพะฝะฝะพะผั ัะฐะนะปั:
-enable_update_checker_helper_forgejo = ะะตัะธะพะดะธัะตัะบะธ ะฟัะพะฒะตัััั ะฝะฐะปะธัะธะต ะฝะพะฒัั
ะฒะตััะธะน Forgejo ัะตัะตะท DNS-ะทะฐะฟะธัั TXT ะฝะฐ release.forgejo.org.
-allow_dots_in_usernames = ะ ะฐะทัะตัะธัั ัะพัะบะธ ะฒ ะปะพะณะธะฝะฐั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน. ะญัะพ ะฝะต ะฟะพะฒะปะธัะตั ะฝะฐ ัะถะต ัะพะทะดะฐะฝะฝัะต ััััะฝัะต ะทะฐะฟะธัะธ.
+enable_update_checker_helper_forgejo = ะะตัะธะพะดะธัะตัะบะธ ะฟัะพะฒะตัััั ะฝะฐะปะธัะธะต ะฝะพะฒัั
ะฒะตััะธะน Forgejo ัะตัะตะท ยซTXTยป DNS-ะทะฐะฟะธัั ะดะพะผะตะฝะฐ release.forgejo.org.
+allow_dots_in_usernames = ะ ะฐะทัะตัะธัั ัะพัะบะธ ะฒ ะธะผะตะฝะฐั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน. ะญัะพ ะฝะต ะฟะพะฒะปะธัะตั ะฝะฐ ัะถะต ัะพะทะดะฐะฝะฝัะต ััััะฝัะต ะทะฐะฟะธัะธ.
smtp_from_invalid = ะะดัะตั ะดะปั ะพัะฟัะฐะฒะบะธ ะฟะธัะตะผ ะฝะตะบะพััะตะบัะตะฝ
config_location_hint = ะญัะธ ะฝะฐัััะพะนะบะธ ะบะพะฝัะธะณััะฐัะธะธ ะฑัะดัั ัะพั
ัะฐะฝะตะฝั ะฒ:
-allow_only_external_registration = ะ ะฐะทัะตัะธัั ัะตะณะธัััะฐัะธั ัะพะปัะบะพ ัะตัะตะท ััะพัะพะฝะฝะธะต ัะปัะถะฑั
+allow_only_external_registration = ะ ะตะณะธัััะฐัะธั ัะพะปัะบะพ ัะตัะตะท ััะพัะพะฝะฝะธะต ัะปัะถะฑั
app_slogan = ะะพะทัะฝะณ ัะตัะฒะตัะฐ
app_slogan_helper = ะฃะบะฐะถะธัะต ะปะพะทัะฝะณ ะฒะฐัะตะณะพ ัะตัะฒะตัะฐ, ะปะธะฑะพ ะพััะฐะฒััะต ะฟััััะผ ะดะปั ะพัะบะปััะตะฝะธั.
[home]
-uname_holder=ะะพะณะธะฝ ะธะปะธ ะฐะดัะตั ัะป. ะฟะพััั
+uname_holder=ะะผั ะธะปะธ ะฐะดัะตั ัะป. ะฟะพััั
password_holder=ะะฐัะพะปั
-switch_dashboard_context=ะะตัะตะบะปััะธัั ะบะพะฝัะตะบัั ะฟะฐะฝะตะปะธ ัะฟัะฐะฒะปะตะฝะธั
+switch_dashboard_context=ะกะผะตะฝะธัั ะฟัะพัะผะฐััะธะฒะฐะตะผะพะต ะฟัะพัััะฐะฝััะฒะพ
my_repos=ะ ะตะฟะพะทะธัะพัะธะธ
show_more_repos=ะะพะบะฐะทะฐัั ะฑะพะปััะต ัะตะฟะพะทะธัะพัะธะตะฒโฆ
collaborative_repos=ะกะพะฒะผะตััะฝัะต ัะตะฟะพะทะธัะพัะธะธ
@@ -343,7 +364,7 @@ my_orgs=ะัะณะฐะฝะธะทะฐัะธะธ
my_mirrors=ะะพะธ ะทะตัะบะฐะปะฐ
view_home=ะะพะบะฐะทะฐัั %s
search_repos=ะะพะธัะบ ัะตะฟะพะทะธัะพัะธัโฆ
-filter=ะััะณะธะต ัะธะปัััั
+filter=ะัะพัะธะต ัะธะปัััั
filter_by_team_repositories=ะคะธะปัััะพะฒะฐัั ะฟะพ ัะตะฟะพะทะธัะพัะธัะผ ะบะพะผะฐะฝะดั
feed_of=ะะตะฝัะฐ ยซ%sยป
@@ -352,7 +373,7 @@ show_both_archived_unarchived=ะะพะบะฐะทะฐะฝั ะฐัั
ะธะฒะธัะพะฒะฐะฝะฝัะต ะธ
show_only_archived=ะะพะบะฐะทะฐะฝั ัะพะปัะบะพ ะฐัั
ะธะฒะธัะพะฒะฐะฝะฝัะต
show_only_unarchived=ะะพะบะฐะทะฐะฝั ัะพะปัะบะพ ัะฐะทะฐัั
ะธะฒะธัะพะฒะฐะฝะฝัะต
-show_private=ะัะธะฒะฐัะฝัะน
+show_private=ะงะฐััะฝัะต
show_both_private_public=ะะพะบะฐะทะฐะฝั ะบะฐะบ ะฟัะฑะปะธัะฝัะต, ัะฐะบ ะธ ัะฐััะฝัะต
show_only_private=ะะพะบะฐะทะฐะฝั ัะพะปัะบะพ ะฟัะธะฒะฐัะฝัะต
show_only_public=ะะพะบะฐะทะฐะฝั ัะพะปัะบะพ ะฟัะฑะปะธัะฝัะต
@@ -377,8 +398,8 @@ user_no_results=ะะพะดั
ะพะดััะธะต ะฟะพะปัะทะพะฒะฐัะตะปะธ ะฝะต ะฝะฐะนะดะตะฝ
org_no_results=ะะพะดั
ะพะดััะธะต ะพัะณะฐะฝะธะทะฐัะธะธ ะฝะต ะฝะฐะนะดะตะฝั.
code_no_results=ะกะพะพัะฒะตัััะฒัััะธะน ะฟะพะธัะบะพะฒะพะผั ะทะฐะฟัะพัั ะธัั
ะพะดะฝัะน ะบะพะด ะฝะต ะฝะฐะนะดะตะฝ.
code_search_results=ะ ะตะทัะปััะฐัั ะฟะพะธัะบะฐ ยซ%sยป
-code_last_indexed_at=ะะพัะปะตะดะฝะธะน ะฟัะพะธะฝะดะตะบัะธัะพะฒะฐะฝะฝัะน %s
-relevant_repositories_tooltip=ะ ะตะฟะพะทะธัะพัะธะธ, ัะฒะปัััะธะตัั ะพัะฒะตัะฒะปะตะฝะธัะผะธ ะธะปะธ ะฝะต ะธะผะตััะธะต ะฝะธ ัะตะผั, ะฝะธ ะทะฝะฐัะบะฐ, ะฝะธ ะพะฟะธัะฐะฝะธั, ัะบัััั.
+code_last_indexed_at=ะะพัะปะตะดะฝัั ะธะฝะดะตะบัะฐัะธั %s
+relevant_repositories_tooltip=ะกะบัััั ะพัะฒะตัะฒะปะตะฝะธั ะธ ัะตะฟะพะทะธัะพัะธะธ, ะฝะต ะธะผะตััะธะต ะฝะธ ัะตะผั, ะฝะธ ะทะฝะฐัะบะฐ, ะฝะธ ะพะฟะธัะฐะฝะธั.
relevant_repositories=ะะพะบะฐะทะฐะฝั ัะพะปัะบะพ ัะตะปะตะฒะฐะฝัะฝัะต ัะตะฟะพะทะธัะพัะธะธ, ะฟะพะบะฐะทะฐัั ัะตะทัะปััะฐัั ะฑะตะท ัะธะปัััะฐัะธะธ .
forks_one = %d ะพัะฒะตัะฒะปะตะฝะธะต
forks_few = %d ะพัะฒะตัะฒะปะตะฝะธะน
@@ -394,23 +415,23 @@ disable_register_mail=ะะพะดัะฒะตัะถะดะตะฝะธะต ัะตะณะธัััะฐัะธะธ ะฟะพ ั
manual_activation_only=ะะฑัะฐัะธัะตัั ะบ ะฐะดะผะธะฝะธัััะฐัะพัั ัะฐะนัะฐ ะดะปั ะทะฐะฒะตััะตะฝะธั ะฐะบัะธะฒะฐัะธะธ.
remember_me=ะะฐะฟะพะผะฝะธัั ััะพ ััััะพะนััะฒะพ
remember_me.compromised=ะขะพะบะตะฝ ะฒั
ะพะดะฐ ะฑะพะปะตะต ะฝะต ะดะตะนััะฒะธัะตะปะตะฝ, ััะพ ะผะพะถะตั ัะบะฐะทัะฒะฐัั ะฝะฐ ะบะพะผะฟัะพะผะตัะฐัะธั ััััะฝะพะน ะทะฐะฟะธัะธ. ะะพะถะฐะปัะนััะฐ, ะฟัะพะฒะตัััะต ัะฒะพั ััััะฝัั ะทะฐะฟะธัั ะฝะฐ ะฝะตะพะฑััะฝัะต ะดะตะนััะฒะธั.
-forgot_password_title=ะะพัััะฐะฝะพะฒะธัั ะฟะฐัะพะปั
+forgot_password_title=ะะพัััะฐะฝะพะฒะปะตะฝะธะต ะฟะฐัะพะปั
forgot_password=ะะฐะฑัะปะธ ะฟะฐัะพะปั?
sign_up_now=ะัะถะฝะฐ ััััะฝะฐั ะทะฐะฟะธัั? ะะฐัะตะณะธัััะธััะนัะตัั.
sign_up_successful=ะฃัััะฝะฐั ะทะฐะฟะธัั ััะฟะตัะฝะพ ัะพะทะดะฐะฝะฐ. ะะพะฑัะพ ะฟะพะถะฐะปะพะฒะฐัั!
-confirmation_mail_sent_prompt=ะะพะฒะพะต ะฟะธััะผะพ ะดะปั ะฟะพะดัะฒะตัะถะดะตะฝะธั ะฝะฐะฟัะฐะฒะปะตะฝะพ ะฝะฐ %s . ะะพะถะฐะปัะนััะฐ, ะฟัะพะฒะตัััะต ะฒะฐั ะฟะพััะพะฒัะน ััะธะบ ะฒ ัะตัะตะฝะธะต %s ะดะปั ะทะฐะฒะตััะตะฝะธั ัะตะณะธัััะฐัะธะธ.
+confirmation_mail_sent_prompt=ะะพะฒะพะต ะฟะธััะผะพ ะดะปั ะฟะพะดัะฒะตัะถะดะตะฝะธั ะฑัะปะพ ะพัะฟัะฐะฒะปะตะฝะพ ะฝะฐ %s . ะะปั ะทะฐะฒะตััะตะฝะธั ัะตะณะธัััะฐัะธะธ, ะฟะพะถะฐะปัะนััะฐ, ะฟะตัะตะนะดะธัะต ะฟะพ ัััะปะบะต ะฒะฝัััะธ ะฒ ัะตัะตะฝะธะต %s. ะัะปะธ ะฑัะป ะฒะฒะตะดัะฝ ะฝะตะฟัะฐะฒะธะปัะฝัะน ะฐะดัะตั, ะฒั ะผะพะถะตัะต ะฒะพะนัะธ ะธ ะธะทะผะตะฝะธัั ะตะณะพ.
must_change_password=ะะฑะฝะพะฒะธัะต ะฟะฐัะพะปั
allow_password_change=ะขัะตะฑะพะฒะฐัั ัะผะตะฝั ะฟะฐัะพะปั ะฟะพะปัะทะพะฒะฐัะตะปะตะผ (ัะตะบะพะผะตะฝะดัะตััั)
-reset_password_mail_sent_prompt=ะะธััะผะพ ั ะฟะพะดัะฒะตัะถะดะตะฝะธะตะผ ะพัะฟัะฐะฒะปะตะฝะพ ะฝะฐ %s . ะะพะถะฐะปัะนััะฐ, ะฟัะพะฒะตัััะต ะฒั
ะพะดัััั ะฟะพััั ะฒ ัะตัะตะฝะธะต %s, ััะพะฑั ะทะฐะฒะตััะธัั ะฟัะพัะตัั ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ััััะฝะพะน ะทะฐะฟะธัะธ.
-active_your_account=ะะบัะธะฒะธััะนัะต ัะฒะพั ััััะฝัั ะทะฐะฟะธัั
+reset_password_mail_sent_prompt=ะะธััะผะพ ะดะปั ะฟะพะดัะฒะตัะถะดะตะฝะธั ะฑัะปะพ ะพัะฟัะฐะฒะปะตะฝะพ ะฝะฐ %s . ะงัะพะฑั ะทะฐะฒะตััะธัั ะฟัะพัะตัั ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ััััะฝะพะน ะทะฐะฟะธัะธ, ะฟะตัะตะนะดะธัะต ะฟะพ ัะบะฐะทะฐะฝะฝะพะน ะฒ ะฝัะผ ัััะปะบะต ะฒ ัะตัะตะฝะธะต %s.
+active_your_account=ะะบัะธะฒะฐัะธั ััััะฝะพะน ะทะฐะฟะธัะธ
account_activated=ะฃัััะฝะฐั ะทะฐะฟะธัั ะฐะบัะธะฒะธัะพะฒะฐะฝะฐ
-prohibit_login=ะั
ะพะด ะทะฐะฟัะตััะฝ
-prohibit_login_desc=ะั
ะพะด ะฒ ะฒะฐัั ััััะฝัั ะทะฐะฟะธัั ะทะฐะฟัะตัะตะฝ. ะกะฒัะถะธัะตัั ั ะฐะดะผะธะฝะธัััะฐัะพัะพะผ ัะฐะนัะฐ.
+prohibit_login=ะฃัััะฝะฐั ะทะฐะฟะธัั ะฟัะธะพััะฐะฝะพะฒะปะตะฝะฐ
+prohibit_login_desc=ะะพะทะผะพะถะฝะพััั ะธัะฟะพะปัะทะพะฒะฐะฝะธั ััะพะน ัั. ะทะฐะฟะธัะธ ะฑัะปะฐ ะฟัะธะพััะฐะฝะพะฒะปะตะฝะฐ. ะะฑัะฐัะธัะตัั ะบ ะฐะดะผะธะฝะธัััะฐัะธะธ ัะตัะฒะตัะฐ ะดะปั ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ะดะพัััะฟะฐ.
resent_limit_prompt=ะะตะดะฐะฒะฝะพ ะฒั ัะถะต ะทะฐะฟัะฐัะธะฒะฐะปะธ ะฟะธััะผะพ ะดะปั ะฐะบัะธะฒะฐัะธะธ. ะะพะถะฐะปัะนััะฐ, ะฟะพะฒัะพัะธัะต ะฟะพะฟััะบั ัะตัะตะท 3 ะผะธะฝััั.
has_unconfirmed_mail=ะะดัะฐะฒััะฒัะนัะต, %s! ะฃ ะฒะฐั ะตััั ะฝะตะฟะพะดัะฒะตัะถะดะตะฝะฝัะน ะฐะดัะตั ัะป. ะฟะพััั (%s ). ะัะปะธ ะฒะฐะผ ะฝะต ะฟัะธั
ะพะดะธะปะพ ะฟะธััะผะพ ั ะฟะพะดัะฒะตัะถะดะตะฝะธะตะผ ะธะปะธ ะฝัะถะฝะพ ะฒััะปะฐัั ะฝะพะฒะพะต ะฟะธััะผะพ, ะฝะฐะถะผะธัะต ะฝะฐ ะบะฝะพะฟะบั ะฝะธะถะต.
resend_mail=ะะฐะถะผะธัะต ะทะดะตัั, ััะพะฑั ะพัะฟัะฐะฒะธัั ะฟะธััะผะพ ะดะปั ะฐะบัะธะฒะฐัะธะธ ะตัั ัะฐะท
email_not_associate=ะญัะพั ะฐะดัะตั ัะป. ะฟะพััั ะฝะต ัะฒัะทะฐะฝ ะฝะธ ั ะพะดะฝะพะน ััััะฝะพะน ะทะฐะฟะธััั.
-send_reset_mail=ะัะฟัะฐะฒะธัั ะฟะธััะผะพ ะดะปั ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ััััะฝะพะน ะทะฐะฟะธัะธ
+send_reset_mail=ะัะฟัะฐะฒะธัั ะฒะพัััะฐะฝะพะฒะปะตะฝะธะต ะฟะฐัะพะปั
reset_password=ะะพัััะฐะฝะพะฒะปะตะฝะธะต ััััะฝะพะน ะทะฐะฟะธัะธ
invalid_code=ะะพะด ะฟะพะดัะฒะตัะถะดะตะฝะธั ะฝะตะดะตะนััะฒะธัะตะปะตะฝ ะธะปะธ ะธัััะบ.
invalid_code_forgot_password=ะะฐั ะบะพะด ะฟะพะดัะฒะตัะถะดะตะฝะธั ะฝะตะดะตะนััะฒะธัะตะปะตะฝ ะธะปะธ ะธััะตะบ. ะะฐะถะผะธัะต ะทะดะตัั ะดะปั ะฝะฐัะฐะปะฐ ะฝะพะฒะพะน ัะตััะธะธ.
@@ -420,21 +441,21 @@ reset_password_wrong_user=ะั ะฒะพัะปะธ ะบะฐะบ %s, ะฝะพ ัััะปะบะฐ ะดะปั ะฒ
password_too_short=ะะฐัะพะปั ะฝะต ะผะพะถะตั ะฑััั ะบะพัะพัะต %d ัะธะผะฒะพะปะพะฒ.
non_local_account=ะะตะปะพะบะฐะปัะฝัะต ััััะฝัะต ะทะฐะฟะธัะธ ะฝะต ะผะพะณัั ะธะทะผะตะฝะธัั ะฟะฐัะพะปั ะฒ ะฒะตะฑ-ะธะฝัะตััะตะนัะต Forgejo.
verify=ะัะพะฒะตัะธัั
-scratch_code=ะะดะฝะพัะฐะทะพะฒัะน ะฟะฐัะพะปั
-use_scratch_code=ะัะฟะพะปัะทะพะฒะฐัั scratch-ะบะพะด
-twofa_scratch_used=ะั ะธัะฟะพะปัะทะพะฒะฐะปะธ scratch-ะบะพะด. ะั ะฑัะปะธ ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝั ะฝะฐ ัััะฐะฝะธัั ะฝะฐัััะพะตะบ ะดะปั ะณะตะฝะตัะฐัะธะธ ะฝะพะฒะพะณะพ ะบะพะดะฐ ะธะปะธ ะพัะบะปััะตะฝะธั ะดะฒััะฐะบัะพัะฝะพะน ะฐััะตะฝัะธัะธะบะฐัะธะธ.
-twofa_passcode_incorrect=ะะฐั ะฟะฐัะพะปั ะฝะตะฒะตัะตะฝ. ะัะปะธ ะฒั ะฟะพัะตััะปะธ ััััะพะนััะฒะพ, ะธัะฟะพะปัะทัะนัะต ะฒะฐั scratch-ะบะพะด.
-twofa_scratch_token_incorrect=ะะตะฒะตัะฝัะน scratch-ะบะพะด.
+scratch_code=ะะพะด ะฒะพัััะฐะฝะพะฒะปะตะฝะธั
+use_scratch_code=ะัะฟะพะปัะทะพะฒะฐัั ะบะพะด ะฒะพัััะฐะฝะพะฒะปะตะฝะธั
+twofa_scratch_used=ะั ะธัะฟะพะปัะทะพะฒะฐะปะธ ะบะพะด ะฒะพัััะฐะฝะพะฒะปะตะฝะธั. ะั ะฑัะปะธ ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝั ะฝะฐ ัััะฐะฝะธัั ะฝะฐัััะพะตะบ ะดะปั ะณะตะฝะตัะฐัะธะธ ะฝะพะฒะพะณะพ ะบะพะดะฐ ะธะปะธ ะพัะบะปััะตะฝะธั ะดะฒััะฐะบัะพัะฝะพะน ะฐััะตะฝัะธัะธะบะฐัะธะธ.
+twofa_passcode_incorrect=ะะฒะตะดัะฝ ะฝะตะฒะตัะฝัะน ะบะพะด. ะัะปะธ ะฒั ะฟะพัะตััะปะธ ััััะพะนััะฒะพ, ะธัะฟะพะปัะทัะนัะต ะบะพะด ะฒะพัััะฐะฝะพะฒะปะตะฝะธั.
+twofa_scratch_token_incorrect=ะะตะฒะตัะฝัะน ะบะพะด ะฒะพัััะฐะฝะพะฒะปะตะฝะธั.
login_userpass=ะั
ะพะด
tab_signin = ะะพะนัะธ
tab_signup = ะะฐัะตะณะธัััะธัะพะฒะฐัััั
tab_openid=OpenID
oauth_signup_tab=ะะฐัะตะณะธัััะธัะพะฒะฐัั ะฝะพะฒัั ััััะฝัั ะทะฐะฟะธัั
-oauth_signup_title=ะะพะปะฝะฐั ะฝะพะฒะฐั ััััะฝะฐั ะทะฐะฟะธัั
-oauth_signup_submit=ะะพะปะฝะฐั ััััะฝะฐั ะทะฐะฟะธัั
-oauth_signin_tab=ะกััะปะบะฐ ะฝะฐ ัััะตััะฒััััั ััััะฝัั ะทะฐะฟะธัั
+oauth_signup_title=ะะฐะฒะตััะตะฝะธะต ัะตะณะธัััะฐัะธะธ ััััะฝะพะน ะทะฐะฟะธัะธ
+oauth_signup_submit=ะะฐะฒะตััะธัั ัะตะณะธัััะฐัะธั
+oauth_signin_tab=ะัะธะฒัะทะฐัั ัััะตััะฒััััั ัั. ะทะฐะฟะธัั
oauth_signin_title=ะะพะนะดะธัะต, ััะพะฑั ะฐะฒัะพัะธะทะพะฒะฐัั ัะฒัะทะฐะฝะฝัั ััััะฝัั ะทะฐะฟะธัั
-oauth_signin_submit=ะัะธะฒัะทะฐัั ััััะฝัั ะทะฐะฟะธัั
+oauth_signin_submit=ะัะธะฒัะทะฐัั ัั. ะทะฐะฟะธัั
oauth.signin.error=ะัะพะธะทะพัะปะฐ ะพัะธะฑะบะฐ ะฟัะธ ะพะฑัะฐะฑะพัะบะต ะทะฐะฟัะพัะฐ ะฐะฒัะพัะธะทะฐัะธะธ. ะัะปะธ ััะฐ ะพัะธะฑะบะฐ ะฟะพะฒัะพััะตััั, ะพะฑัะฐัะธัะตัั ะบ ะฐะดะผะธะฝะธัััะฐัะพัั ัะฐะนัะฐ.
oauth.signin.error.access_denied=ะะฐะฟัะพั ะฝะฐ ะฐะฒัะพัะธะทะฐัะธั ะฑัะป ะพัะบะปะพะฝะตะฝ.
oauth.signin.error.temporarily_unavailable=ะัะพะธะทะพัะปะฐ ะพัะธะฑะบะฐ ะฐะฒัะพัะธะทะฐัะธะธ, ัะฐะบ ะบะฐะบ ัะตัะฒะตั ะฐััะตะฝัะธัะธะบะฐัะธะธ ะฒัะตะผะตะฝะฝะพ ะฝะตะดะพัััะฟะตะฝ. ะะพะถะฐะปัะนััะฐ, ะฟะพะฒัะพัะธัะต ะฟะพะฟััะบั ะฟะพะทะถะต.
@@ -455,12 +476,19 @@ authorize_title=ะ ะฐะทัะตัะธัั ยซ%sยป ะดะพัััะฟ ะบ ะฒะฐัะตะน ััััะฝ
authorization_failed=ะัะธะฑะบะฐ ะฐะฒัะพัะธะทะฐัะธะธ
authorization_failed_desc=ะัะธะฑะบะฐ ะฐะฒัะพัะธะทะฐัะธะธ, ะพะฑะฝะฐััะถะตะฝ ะฝะตะฒะตัะฝัะน ะทะฐะฟัะพั. ะะพะถะฐะปัะนััะฐ, ัะฒัะถะธัะตัั ั ะฐะฒัะพัะพะผ ะฟัะธะปะพะถะตะฝะธั, ะบะพัะพัะพะต ะฒั ะฟััะฐะปะธัั ะฐะฒัะพัะธะทะพะฒะฐัั.
sspi_auth_failed=ะััะตะฝัะธัะธะบะฐัะธั SSPI ะฝะต ัะดะฐะปะฐัั
-password_pwned=ะัะฑัะฐะฝะฝัะน ะฒะฐะผะธ ะฟะฐัะพะปั ะฝะฐั
ะพะดะธััั ะฒ ัะฟะธัะบะต ัะบัะฐะดะตะฝะฝัั
ะฟะฐัะพะปะตะน ะธะท ัะฐะฝะตะต ะพะฟัะฑะปะธะบะพะฒะฐะฝะฝัั
ััะตัะตะบ. ะะพะฒัะพัะธัะต ะฟะพะฟััะบั ั ะดััะณะธะผ ะฟะฐัะพะปะตะผ. ะขะฐะบะถะต ัะตะบะพะผะตะฝะดัะตะผ ัะผะตะฝะธัั ััะพั ะฟะฐัะพะปั ะฒ ะดััะณะธั
ะผะตััะฐั
.
+password_pwned=ะัะฑัะฐะฝะฝัะน ะฒะฐะผะธ ะฟะฐัะพะปั ะฝะฐั
ะพะดะธััั ะฒ ัะฟะธัะบะต ัะบัะฐะดะตะฝะฝัั
ะฟะฐัะพะปะตะน ะธะท ัะฐะฝะตะต ะพะฟัะฑะปะธะบะพะฒะฐะฝะฝัั
ััะตัะตะบ. ะะพะฒัะพัะธัะต ะฟะพะฟััะบั ั ะดััะณะธะผ ะฟะฐัะพะปะตะผ. ะขะฐะบะถะต ัะตะบะพะผะตะฝะดัะตะผ ัะผะตะฝะธัั ััะพั ะฟะฐัะพะปั ะฒ ะดััะณะธั
ะผะตััะฐั
.
password_pwned_err=ะะต ัะดะฐะปะพัั ะทะฐะฒะตััะธัั ะทะฐะฟัะพั ะบ HaveIBeenPwned
change_unconfirmed_email_summary = ะะทะผะตะฝะธัะต ะฐะดัะตั ัะป. ะฟะพััั, ะฝะฐ ะบะพัะพััะน ะฑัะดะตั ะพัะฟัะฐะฒะปะตะฝะพ ะฟะธััะผะพ ะดะปั ะฐะบัะธะฒะฐัะธะธ ััััะฝะพะน ะทะฐะฟะธัะธ.
change_unconfirmed_email_error = ะะตะฒะพะทะผะพะถะฝะพ ะธะทะผะตะฝะธัั ะฐะดัะตั ะฟะพััั: %v
last_admin = ะะตะฒะพะทะผะพะถะฝะพ ัะดะฐะปะธัั ะตะดะธะฝััะฒะตะฝะฝะพะณะพ ะฐะดะผะธะฝะธัััะฐัะพัะฐ. ะัะตะณะดะฐ ะดะพะปะถะตะฝ ะพััะฐะฒะฐัััั ั
ะพัั ะฑั ะพะดะธะฝ ะฐะดะผะธะฝะธัััะฐัะพั.
change_unconfirmed_email = ะัะปะธ ะฟัะธ ัะตะณะธัััะฐัะธะธ ะฑัะป ะฒะฒะตะดัะฝ ะฝะตะฟัะฐะฒะธะปัะฝัะน ะฐะดัะตั, ะตะณะพ ะผะพะถะฝะพ ะธะทะผะตะฝะธัั ะฝะธะถะต, ะธ ะฟะธััะผะพ ั ะฟะพะดัะฒะตัะถะดะตะฝะธะตะผ ะฑัะดะตั ะฒััะปะฐะฝะพ ะฝะฐ ะธัะฟัะฐะฒะปะตะฝะฝัะน ะฐะดัะตั.
+hint_register = ะะตั ััััะฝะพะน ะทะฐะฟะธัะธ? ะะฐัะตะณะธัััะธััะนัะตัั.
+sign_up_button = ะะฐัะตะณะธัััะธัะพะฒะฐัััั.
+back_to_sign_in = ะะฐะทะฐะด ะบะพ ะฒั
ะพะดั
+sign_in_openid = ะัะพะดะพะปะถะธัั ั OpenID
+hint_login = ะฃะถะต ะตััั ััััะฝะฐั ะทะฐะฟะธัั? ะะพะนะดะธัะต!
+unauthorized_credentials = ะฃัััะฝัะต ะดะฐะฝะฝัะต ะฝะตะฒะตัะฝั ะธะปะธ ะธััะตะบะปะธ. ะะพะฟัะพะฑัะนัะต ะฟะพะฒัะพัะธัั ะบะพะผะฐะฝะดั ะธะปะธ ะพะทะฝะฐะบะพะผััะตัั ั ะฟะพะดัะพะฑะฝะพัััะผะธ ะฟะพ ัััะปะบะต: %s
+use_onetime_code = ะัะฟะพะปัะทะพะฒะฐัั ะพะดะฝะพัะฐะทะพะฒัะน ะบะพะด
[mail]
view_it_on=ะะพัะผะพััะตัั ะฝะฐ %s
@@ -477,10 +505,10 @@ activate_email=ะะพะดัะฒะตัะดะธัะต ัะฒะพะน ะฐะดัะตั ัะป. ะฟะพััั
activate_email.title=%s, ะฟะพะถะฐะปัะนััะฐ, ะฟะพะดัะฒะตัะดะธัะต ัะฒะพะน ะฐะดัะตั ัะป. ะฟะพััั
activate_email.text=ะะปั ะฟะพะดัะฒะตัะถะดะตะฝะธั ัะป. ะฟะพััั ะฟะตัะตะนะดะธัะต ะฟะพ ัะปะตะดัััะตะน ัััะปะบะต ะฒ ัะตัะตะฝะธะต %s :
-register_notify=ะะพะฑัะพ ะฟะพะถะฐะปะพะฒะฐัั ะฒ Forgejo
+register_notify=ะัะธะฒะตัััะฒัะตะผ ะฒ %s
register_notify.title=%[1]s, ะดะพะฑัะพ ะฟะพะถะฐะปะพะฒะฐัั ะฒ %[2]s
register_notify.text_1=ััะพ ะฟะธััะผะพ ั ะฒะฐัะธะผ ะฟะพะดัะฒะตัะถะดะตะฝะธะตะผ ัะตะณะธัััะฐัะธะธ ะฒ %s!
-register_notify.text_2=ะขะตะฟะตัั ะฒั ะผะพะถะตัะต ะฒะพะนัะธ ะฒ ััััะฝัั ะทะฐะฟะธัั, ะธัะฟะพะปัะทัั ะปะพะณะธะฝ: %s
+register_notify.text_2=ะขะตะฟะตัั ะฒั ะผะพะถะตัะต ะฒะพะนัะธ ะฒ ัะฒะพั ััััะฝัั ะทะฐะฟะธัั, ะธัะฟะพะปัะทัั ะธะผั: %s
register_notify.text_3=ะัะปะธ ััะฐ ััััะฝะฐั ะทะฐะฟะธัั ัะพะทะดะฐะฝะฐ ะบะตะผ-ัะพ ะดะปั ะฒะฐั, ัะฟะตัะฒะฐ ะฑัะดะตั ะฝะตะพะฑั
ะพะดะธะผะพ ะทะฐะดะฐัั ะฟะฐัะพะปั .
reset_password=ะะพัััะฐะฝะพะฒะปะตะฝะธะต ััััะฝะพะน ะทะฐะฟะธัะธ
@@ -499,10 +527,10 @@ issue.action.push_n=@%[1]s ะพัะฟัะฐะฒะธะป(ะฐ) %[3]d ะธะทะผะตะฝะตะฝะธะน
issue.action.close=@%[1]s ะทะฐะบััะป(ะฐ) #%[2]d.
issue.action.reopen=@%[1]s ะฟะตัะตะพัะบััะป(ะฐ) #%[2]d.
issue.action.merge=@%[1]s ัะปะธะป(ะฐ) #%[2]d ะฒ %[3]s.
-issue.action.approve=@%[1]s ะพะดะพะฑัะธะป(ะฐ) ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต.
+issue.action.approve=@%[1]s ัะปะธัะฝะธะต ะพะดะพะฑัะตะฝะพ.
issue.action.reject=@%[1]s ะทะฐะฟัะพัะธะป(ะฐ) ะธะทะผะตะฝะตะฝะธั ะฒ ััะพะผ ะทะฐะฟัะพัะต ะฝะฐ ัะปะธัะฝะธะต.
issue.action.review=@%[1]s ะฟัะพะบะพะผะผะตะฝัะธัะพะฒะฐะป(ะฐ) ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต.
-issue.action.review_dismissed=@%[1]s ะพัะบะปะพะฝะธะป(ะฐ) ะฟะพัะปะตะดะฝะธะน ะพัะทัะฒ ั %[2]s ะดะปั ััะพะณะพ ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต.
+issue.action.review_dismissed=@%[1]s ะพัะบะปะพะฝะตะฝะฐ ะฟะพัะปะตะดะฝัั ัะตัะตะฝะทะธั ั %[2]s ะดะปั ััะพะณะพ ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต.
issue.action.ready_for_review=@%[1]s ะพัะผะตัะธะป(ะฐ) ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะบะฐะบ ะณะพัะพะฒัะน ะบ ัะฐััะผะพััะตะฝะธั.
issue.action.new=@%[1]s ัะพะทะดะฐะป(ะฐ) #%[2]d.
issue.in_tree_path=ะ %s:
@@ -530,6 +558,21 @@ team_invite.text_3=ะัะธะผะตัะฐะฝะธะต: ะญัะพ ะฟัะธะณะปะฐัะตะฝะธะต ะฑัะปะพ
admin.new_user.user_info = ะะฝัะพัะผะฐัะธั ะพ ะฟะพะปัะทะพะฒะฐัะตะปะต
admin.new_user.text = ะะฐะถะผะธัะต ะทะดะตัั , ััะพะฑั ะพัะบัััั ััะพะณะพ ะฟะพะปัะทะพะฒะฐัะตะปั ะฒ ะฟะฐะฝะตะปะธ ะฐะดะผะธะฝะธัััะฐัะธะธ.
admin.new_user.subject = ะะฐัะตะณะธัััะธัะพะฒะฐะปัั ะฝะพะฒัะน ะฟะพะปัะทะพะฒะฐัะตะปั %s
+totp_disabled.subject = ะัะบะปััะตะฝะฐ 2ะคะ ะฟะพ TOTP
+totp_disabled.text_1 = ะะฒัั
ัะฐะบัะพัะฝะฐั ะฐััะตะฝัะธัะธะบะฐัะธั ะฒัะตะผะตะฝะฝัะผะธ ะบะพะดะฐะผะธ (TOTP) ัะพะปัะบะพ ััะพ ะฑัะปะฐ ะพัะบะปััะตะฝะฐ ะฝะฐ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ.
+removed_security_key.subject = ะัะฒัะทะฐะฝ ัะพะบะตะฝ ะฐะฒัะพัะธะทะฐัะธะธ
+removed_security_key.text_1 = ะขะพะบะตะฝ ะฐะฒัะพัะธะทะฐัะธะธ ยซ%[1]sยป ัะพะปัะบะพ ััะพ ะฑัะป ะพัะฒัะทะฐะฝ ะพั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ.
+primary_mail_change.text_1 = ะัะฝะพะฒะฝะพะน ะฐะดัะตั ัะป. ะฟะพััั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ ัะพะปัะบะพ ััะพ ะฑัะป ะธะทะผะตะฝัะฝ ะฝะฐ %[1]s. ะัะตะถะฝะธะน ะฐะดัะตั ะฑะพะปััะต ะฝะต ะฑัะดะตั ะฟะพะปััะฐัั ัะฒะตะดะพะผะปะตะฝะธั ะพะฑ ััะพะน ััััะฝะพะน ะทะฐะฟะธัะธ.
+totp_disabled.no_2fa = ะ ะดะฐะฝะฝัะน ะผะพะผะตะฝั ะฝะฐ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ ะพััััััะฒััั ะบะฐะบะธะต-ะปะธะฑะพ ะดััะณะธะต ะผะตัะพะดั 2ะคะ ะธ ะฒั
ะพะด ะฒะพะทะผะพะถะตะฝ ะฑะตะท ะดะพะฟะพะปะฝะธัะตะปัะฝะพะณะพ ัะฐะบัะพัะฐ ะฐััะตะฝัะธัะธะบะฐัะธะธ.
+password_change.text_1 = ะะฐัะพะปั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ ัะพะปัะบะพ ััะพ ะฑัะป ะธะทะผะตะฝัะฝ.
+password_change.subject = ะะทะผะตะฝัะฝ ะฟะฐัะพะปั ััััะฝะพะน ะทะฐะฟะธัะธ
+primary_mail_change.subject = ะะทะผะตะฝัะฝ ะพัะฝะพะฒะฝะพะน ะฐะดัะตั ัะป. ะฟะพััั
+account_security_caution.text_1 = ะัะปะธ ััะพ ะดะตะนััะฒะธะต ะฒัะฟะพะปะฝะธะปะธ ะฒั, ัะพ ะผะพะถะตัะต ัะฟะพะบะพะนะฝะพ ะธะณะฝะพัะธัะพะฒะฐัั ััะพ ัะฒะตะดะพะผะปะตะฝะธะต.
+account_security_caution.text_2 = ะัะปะธ ััะพ ะฑัะปะธ ะฝะต ะฒั, ะฒะฐัะฐ ััััะฝะฐั ะทะฐะฟะธัั ะฑัะปะฐ ัะบะพะผะฟัะพะผะตัะธัะพะฒะฐะฝะฐ. ะกะฒัะถะธัะตัั ั ะฐะดะผะธะฝะธัััะฐัะธะตะน ัะตัะฒะตัะฐ.
+removed_security_key.no_2fa = ะ ะดะฐะฝะฝัะน ะผะพะผะตะฝั ะฝะฐ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ ะพััััััะฒััั ะบะฐะบะธะต-ะปะธะฑะพ ะดััะณะธะต ะผะตัะพะดั 2ะคะ ะธ ะฒั
ะพะด ะฒะพะทะผะพะถะตะฝ ะฑะตะท ะดะพะฟะพะปะฝะธัะตะปัะฝะพะณะพ ัะฐะบัะพัะฐ ะฐััะตะฝัะธัะธะบะฐัะธะธ.
+totp_enrolled.subject = ะะบัะธะฒะธัะพะฒะฐะฝะฐ ะดะฒัั
ัะฐะบัะพัะฝะฐั ะฐััะตะฝัะธัะธะบะฐัะธั ะฟะพ TOTP
+totp_enrolled.text_1.has_webauthn = ะะฐ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ ะฑัะปะฐ ะฐะบัะธะฒะธัะพะฒะฐะฝะฐ 2ะคะ ะฟะพ TOTP. ะญัะพ ะพะทะฝะฐัะฐะตั, ััะพ ะดะปั ัะปะตะดัััะธั
ะฒั
ะพะดะพะฒ ะฟะพััะตะฑัะตััั ะฒะฒะพะดะธัั ะพะดะฝะพัะฐะทะพะฒัะน ะบะพะด (TOTP), ะปะธะฑะพ ะฟัะธะผะตะฝััั ะฟัะธะฒัะทะฐะฝะฝัะน ัะพะบะตะฝ ะฐะฒัะพัะธะทะฐัะธะธ.
+totp_enrolled.text_1.no_webauthn = ะะฐ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ ะฑัะปะฐ ะฐะบัะธะฒะธัะพะฒะฐะฝะฐ 2ะคะ ะฟะพ TOTP. ะญัะพ ะพะทะฝะฐัะฐะตั, ััะพ ะดะปั ัะปะตะดัััะธั
ะฒั
ะพะดะพะฒ ะฟะพััะตะฑัะตััั ะฒะฒะพะดะธัั ะพะดะฝะพัะฐะทะพะฒัะน ะบะพะด (TOTP).
[modal]
yes=ะะฐ
@@ -551,7 +594,7 @@ TeamName=ะะฐะทะฒะฐะฝะธะต ะบะพะผะฐะฝะดั
AuthName=ะะผั ะฐะฒัะพัะธะทะฐัะธะธ
AdminEmail=ะญะป. ะฟะพััะฐ ะฐะดะผะธะฝะธัััะฐัะพัะฐ
-NewBranchName=ะะพะฒะฐั ะฒะตัะบะฐ
+NewBranchName=ะะพะฒะฐั ะฒะตัะฒั
CommitSummary=ะ ะตะทัะผะต ะบะพะผะผะธัะฐ
CommitMessage=ะะฐัะธะบัะธัะพะฒะฐัั ัะพะพะฑัะตะฝะธะต
CommitChoice=ะัะฑะพั ะบะพะผะผะธัะฐ
@@ -627,7 +670,7 @@ still_own_packages=ะะฐัะฐ ััััะฝะฐั ะทะฐะฟะธัั ะฒะปะฐะดะตะตั ะพะดะฝะธ
org_still_own_repo=ะญัะฐ ะพัะณะฐะฝะธะทะฐัะธั ะฒัั ะตัั ะฒะปะฐะดะตะตั ะพะดะฝะธะผ ะธะปะธ ะฝะตัะบะพะปัะบะธะผะธ ัะตะฟะพะทะธัะพัะธัะผะธ, ัะฝะฐัะฐะปะฐ ัะดะฐะปะธัะต ะธะปะธ ะฟะตัะตะดะฐะนัะต ะธั
.
org_still_own_packages=ะญัะฐ ะพัะณะฐะฝะธะทะฐัะธั ะฒัั ะตัั ะฒะปะฐะดะตะตั ะพะดะฝะธะผ ะธะปะธ ะฝะตัะบะพะปัะบะธะผะธ ะฟะฐะบะตัะฐะผะธ, ัะฝะฐัะฐะปะฐ ัะดะฐะปะธัะต ะธั
.
-target_branch_not_exist=ะฆะตะปะตะฒะฐั ะฒะตัะบะฐ ะฝะต ัััะตััะฒัะตั.
+target_branch_not_exist=ะฆะตะปะตะฒะฐั ะฒะตัะฒั ะฝะต ัััะตััะฒัะตั.
admin_cannot_delete_self = ะั ะฝะต ะผะพะถะตัะต ัะดะฐะปะธัั ัะฒะพั ััััะฝัั ะทะฐะฟะธัั, ะฑัะดััะธ ะฐะดะผะธะฝะธัััะฐัะพัะพะผ. ะกะฟะตัะฒะฐ ัะฝะธะผะธัะต ั ัะตะฑั ัะพะปั ะฐะดะผะธะฝะธัััะฐัะพัะฐ.
username_error_no_dots = ` ะผะพะถะตั ัะพััะพััั ัะพะปัะบะพ ะธะท ะปะฐัะธะฝัะบะธั
ะฑัะบะฒ (ยซa-zยป, ยซA-Zยป), ัะธัั (ยซ0-9ยป), ะทะฝะฐะบะพะฒ ะผะธะฝััะฐ (ยซ-ยป) ะธ ะฝะธะถะฝะตะณะพ ะฟะพะดัััะบะธะฒะฐะฝะธั (ยซ_ยป). ะะฝะฐะบะธ ะฝะต ะผะพะณัั ััะพััั ะฒ ะฝะฐัะฐะปะต ะธะปะธ ะฒ ะบะพะฝัะต, ะฐ ัะฐะบะถะต ะธะดัะธ ะฟะพะดััะด.`
unsupported_login_type = ะฃะดะฐะปะตะฝะธะต ะฐะบะบะฐัะฝัะฐ ะฝะตะฒะพะทะผะพะถะฝะพ ั ััะธะผ ัะธะฟะพะผ ะฐะฒัะพัะธะทะฐัะธะธ.
@@ -640,21 +683,23 @@ Pronouns = ะะตััะพะธะผะตะฝะธั
Biography = ะ ัะตะฑะต
Website = ะะตะฑ-ัะฐะนั
Location = ะะตััะพะฟะพะปะพะถะตะฝะธะต
-To = ะะฐะทะฒะฐะฝะธะต ะฒะตัะบะธ
+To = ะะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธ
+email_domain_is_not_allowed = ะะพะผะตะฝ ะฐะดัะตัะฐ ัะป. ะฟะพััั %s ะฝะต ัะฐะทัะตััะฝ ะบ ะธัะฟะพะปัะทะพะฒะฐะฝะธั. ะฃะฑะตะดะธัะตัั, ััะพ ะพะฝ ะฒะฒะตะดัะฝ ะฟัะฐะฒะธะปัะฝะพ ะธะปะธ ะฟะพะฟัะพะฑัะนัะต ะดััะณะพะน ะฐะดัะตั.
+username_claiming_cooldown = ะญัะพ ะธะผั ะฟะพะบะฐ ะฝะต ะผะพะถะตั ะฑััั ะทะฐะฝััะพ, ั.ะบ. ััะพะบ ะตะณะพ ะทะฐัะธัั ะตัั ะฝะต ะฒััะตะป. ะะณะพ ะฟะพะปััะธััั ะทะฐะฝััั ะฟะพัะปะต %[1]s.
[user]
-change_avatar=ะะทะผะตะฝะธัั ัะฒะพะน ะฐะฒะฐัะฐัโฆ
+change_avatar=ะะทะผะตะฝะธัั ะธะทะพะฑัะฐะถะตะฝะธะต ะฟัะพัะธะปัโฆ
joined_on=ะ ะตะณะธัััะฐัะธั %s
repositories=ะ ะตะฟะพะทะธัะพัะธะธ
activity=ะัะฑะปะธัะฝะฐั ะฐะบัะธะฒะฝะพััั
-followers_few=%d ะฟะพะดะฟะธััะธะบะธ
+followers_few=%d ะฟะพะดะฟะธััะธะบะพะฒ
starred=ะะทะฑัะฐะฝะฝัะต ัะตะฟะพะทะธัะพัะธะธ
watched=ะััะปะตะถะธะฒะฐะตะผัะต ัะตะฟะพะทะธัะพัะธะธ
code=ะะพะด
projects=ะัะพะตะบัั
overview=ะะฑะทะพั
-following_few=%d ะฟะพะดะฟะธัะบะธ
+following_few=%d ะฟะพะดะฟะธัะพะบ
follow=ะะพะดะฟะธัะฐัััั
unfollow=ะัะฟะธัะฐัััั
user_bio=ะ ัะตะฑะต
@@ -685,6 +730,7 @@ public_activity.visibility_hint.self_public = ะะฐัะฐ ะฐะบัะธะฒะฝะพััั ะฒะธ
public_activity.visibility_hint.self_private = ะะฐัะฐ ะฐะบัะธะฒะฝะพััั ะฒะธะดะฝะฐ ัะพะปัะบะพ ะฒะฐะผ ะธ ะฐะดะผะธะฝะธัััะฐัะพัะฐะผ ัะตัะฒะตัะฐ. ะะทะผะตะฝะธัั .
public_activity.visibility_hint.admin_private = ะญัะฐ ะฐะบัะธะฒะฝะพััั ะดะพัััะฟะฝะฐ ะฒะฐะผ, ะฟะพัะพะผั ััะพ ะฒั ะฐะดะผะธะฝะธัััะฐัะพั. ะญัะพั ะฟะพะปัะทะพะฒะฐัะตะปั ะถะตะปะฐะตั, ััะพะฑั ะพะฝะฐ ะพััะฐะปะฐัั ัะฐััะฝะพะน.
public_activity.visibility_hint.admin_public = ะญัะฐ ะฐะบัะธะฒะฝะพััั ะดะพัััะฟะฝะฐ ะฒัะตะผ, ะฝะพ ะฒั, ะบะฐะบ ะฐะดะผะธะฝะธัััะฐัะพั, ัะฐะบะถะต ะฒะธะดะธัะต ะดะตะนััะฒะธั ะฒ ะฟัะธะฒะฐัะฝัั
ะผะตััะฐั
.
+public_activity.visibility_hint.self_private_profile = ะะฐัะฐ ะฐะบัะธะฒะฝะพััั ะฒะธะดะฝะฐ ัะพะปัะบะพ ะฒะฐะผ ะธ ะฐะดะผะธะฝะธัััะฐัะพัะฐะผ ัะตัะฒะตัะฐ, ะฟะพัะพะผั ััะพ ะฒะฐั ะฟัะพัะธะปั ัะบััั. ะะทะผะตะฝะธัั .
[settings]
profile=ะัะพัะธะปั
@@ -692,11 +738,11 @@ account=ะฃัััะฝะฐั ะทะฐะฟะธัั
appearance=ะะฝะตัะฝะธะน ะฒะธะด
password=ะะฐัะพะปั
security=ะะตะทะพะฟะฐัะฝะพััั
-avatar=ะะฒะฐัะฐั
+avatar=ะะทะพะฑัะฐะถะตะฝะธะต ะฟัะพัะธะปั
ssh_gpg_keys=ะะปััะธ SSH / GPG
social=ะฃัััะฝัะต ะทะฐะฟะธัะธ ะฒ ัะพััะตััั
applications=ะัะธะปะพะถะตะฝะธั
-orgs=ะฃะฟัะฐะฒะปะตะฝะธะต ะพัะณะฐะฝะธะทะฐัะธัะผะธ
+orgs=ะัะณะฐะฝะธะทะฐัะธะธ
repos=ะ ะตะฟะพะทะธัะพัะธะธ
delete=ะฃะดะฐะปะธัั ััััะฝัั ะทะฐะฟะธัั
twofa=ะะฒัั
ัะฐะบัะพัะฝะฐั ะฐััะตะฝัะธัะธะบะฐัะธั (TOTP)
@@ -706,9 +752,9 @@ uid=UID
webauthn=ะะฒัั
ัะฐะบัะพัะฝะฐั ะฐััะตะฝัะธัะธะบะฐัะธั (ะบะปััะฐะผะธ ะฑะตะทะพะฟะฐัะฝะพััะธ)
public_profile=ะัะฑะปะธัะฝัะน ะฟัะพัะธะปั
-biography_placeholder=ะ ะฐััะบะฐะถะธัะต ะฝะตะผะฝะพะณะพ ะพ ัะตะฑะต! (ะะพะถะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั Markdown)
-location_placeholder=ะะพะดะตะปะธัะตัั ัะฒะพะธะผ ะฟัะธะฑะปะธะทะธัะตะปัะฝัะผ ะผะตััะพะฟะพะปะพะถะตะฝะธะตะผ ั ะดััะณะธะผะธ
-profile_desc=ะะฐะบ ะฒะฐั ะฟัะพัะธะปั ะฑัะดะตั ะพัะพะฑัะฐะถะฐัััั ะดะปั ะดััะณะธั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน. ะะฐั ะพัะฝะพะฒะฝะพะน ะฐะดัะตั ัะป. ะฟะพััั ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั ะดะปั ัะฒะตะดะพะผะปะตะฝะธะน, ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ะฟะฐัะพะปั ะธ ะฒะตะฑ-ะพะฟะตัะฐัะธะน ั Git.
+biography_placeholder=ะัะฐัะบะพ ัะฐััะบะฐะถะธัะต ะพ ัะตะฑะต ะดััะณะธะผ! (ะะพะถะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั Markdown)
+location_placeholder=ะัััั ะฒัะต ะทะฝะฐัั, ะพัะบัะดะฐ ะฒั
+profile_desc=ะะฐั ะฟัะพัะธะปั
password_username_disabled=ะะตะปะพะบะฐะปัะฝัะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะทะฐะฟัะตัะตะฝะพ ะธะทะผะตะฝะตะฝะธะต ะธั
ะธะผะตะฝะธ ะฟะพะปัะทะพะฒะฐัะตะปั. ะะปั ะฟะพะปััะตะฝะธั ะฑะพะปะตะต ะฟะพะดัะพะฑะฝะพะน ะธะฝัะพัะผะฐัะธะธ ะพะฑัะฐัะธัะตัั ะบ ะฐะดะผะธะฝะธัััะฐัะพัั ัะฐะนัะฐ.
full_name=ะะพะปะฝะพะต ะธะผั
website=ะะตะฑ-ัะฐะนั
@@ -721,7 +767,7 @@ update_language_success=ะฏะทัะบ ะพะฑะฝะพะฒะปัะฝ.
update_profile_success=ะะฐั ะฟัะพัะธะปั ััะฟะตัะฝะพ ะพะฑะฝะพะฒะปัะฝ.
change_username=ะะฐัะต ะธะผั ะฟะพะปัะทะพะฒะฐัะตะปั ะฑัะปะพ ะธะทะผะตะฝะตะฝะพ.
change_username_prompt=ะะฑัะฐัะธัะต ะฒะฝะธะผะฐะฝะธะต: ะธะทะผะตะฝะตะฝะธะต ะธะผะตะฝะธ ะฟะพะปัะทะพะฒะฐัะตะปั ัะฐะบะถะต ะผะตะฝัะตั URL ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ.
-change_username_redirect_prompt=ะกัะฐัะพะต ะธะผั ะฟะพะปัะทะพะฒะฐัะตะปั ะฑัะดะตั ะฟะตัะตะฝะฐะฟัะฐะฒะปััั ะฝะฐ ะฝะพะฒะพะต ะดะพ ัะตั
ะฟะพั, ะฟะพะบะฐ ะตะณะพ ะฝะต ะทะฐะนะผัั.
+change_username_redirect_prompt=ะกัะฐัะพะต ะธะผั ะฑัะดะตั ะฟะตัะตะฝะฐะฟัะฐะฒะปััั ะฝะฐ ะฝะพะฒะพะต ะดะพ ัะตั
ะฟะพั, ะฟะพะบะฐ ะพะฝะพ ะฝะต ะฑัะดะตั ะทะฐะฝััะพ.
continue=ะะฐะปะตะต
cancel=ะัะผะตะฝะฐ
language=ะฏะทัะบ
@@ -729,13 +775,13 @@ ui=ะขะตะผะฐ
hidden_comment_types=ะกะบััััะต ัะธะฟั ะบะพะผะผะตะฝัะฐัะธะตะฒ
hidden_comment_types_description=ะัะผะตัะตะฝะฝัะต ัะธะฟั ะบะพะผะผะตะฝัะฐัะธะตะฒ ะฝะต ะฑัะดัั ะพัะพะฑัะฐะถะฐัััั ะฝะฐ ัััะฐะฝะธัะฐั
ะทะฐะดะฐั. ะะฐะฟัะธะผะตั, ะตัะปะธ ะฒัะฑัะฐัั ยซะะตัะบะธยป, ะฝะต ััะฐะฝะตั ะฒัะตั
ะบะพะผะผะตะฝัะฐัะธะตะฒ ยซ<ะฟะพะปัะทะพะฒะฐัะตะปั> ะดะพะฑะฐะฒะธะป/ัะดะฐะปะธะป <ะผะตัะบั>ยป.
hidden_comment_types.ref_tooltip=ะะพะผะผะตะฝัะฐัะธะธ ะพะฑ ัะฟะพะผะธะฝะฐะฝะธะธ ะทะฐะดะฐัะธ ะฒ ะดััะณะพะน ะทะฐะดะฐัะต/ะบะพะผะผะธัะต/โฆ
-hidden_comment_types.issue_ref_tooltip=ะะพะผะผะตะฝัะฐัะธะธ ะพะฑ ะธะทะผะตะฝะตะฝะธะธ ะฒะตัะบะธ/ัะตะณะฐ, ัะฒัะทะฐะฝะฝัั
ั ััะพะน ะทะฐะดะฐัะตะน
+hidden_comment_types.issue_ref_tooltip=ะะพะผะผะตะฝัะฐัะธะธ ะพะฑ ะธะทะผะตะฝะตะฝะธะธ ะฒะตัะฒะธ/ัะตะณะฐ, ัะฒัะทะฐะฝะฝัั
ั ััะพะน ะทะฐะดะฐัะตะน
comment_type_group_reference=ะฃะฟะพะผะธะฝะฐะฝะธั
comment_type_group_label=ะะฟะตัะฐัะธะธ ั ะผะตัะบะฐะผะธ
comment_type_group_milestone=ะญัะฐะฟ
comment_type_group_assignee=ะะฐะทะฝะฐัะตะฝะธั
comment_type_group_title=ะัะฐะฒะบะธ ะทะฐะณะพะปะพะฒะบะพะฒ
-comment_type_group_branch=ะะฟะตัะฐัะธะธ ั ะฒะตัะบะฐะผะธ
+comment_type_group_branch=ะะฟะตัะฐัะธะธ ั ะฒะตัะฒัะผะธ
comment_type_group_time_tracking=ะััะปะตะถะธะฒะฐะฝะธะต ะฒัะตะผะตะฝะธ
comment_type_group_deadline=ะะพะดะธัะธะบะฐัะธะธ ััะพะบะพะฒ ะฒัะฟะพะปะฝะตะฝะธั
comment_type_group_dependency=ะะพะดะธัะธะบะฐัะธะธ ะทะฐะฒะธัะธะผะพััะตะน
@@ -745,41 +791,41 @@ comment_type_group_pull_request_push=ะะพะฑะฐะฒะปะตะฝะฝัะต ะบะพะผะผะธัั
comment_type_group_project=ะัะพะตะบั
comment_type_group_issue_ref=ะกััะปะบะฐ ะฝะฐ ะทะฐะดะฐัั
saved_successfully=ะะฐัะธ ะฝะฐัััะพะนะบะธ ััะฟะตัะฝะพ ัะพั
ัะฐะฝะตะฝั.
-privacy=ะัะธะฒะฐัะฝะพััั
+privacy=ะะพะฝัะธะดะตะฝัะธะฐะปัะฝะพััั
keep_activity_private=ะกะบัััั ะฐะบัะธะฒะฝะพััั ัะพ ัััะฐะฝะธัั ะฟัะพัะธะปั
keep_activity_private_popup=ะะฐัะฐ ะฐะบัะธะฒะฝะพััั ะฑัะดะตั ะฒะธะดะฝะฐ ัะพะปัะบะพ ะฒะฐะผ ะธ ะฐะดะผะธะฝะธัััะฐัะพัะฐะผ ัะตัะฒะตัะฐ
-lookup_avatar_by_mail=ะะฐะนัะธ ะฐะฒะฐัะฐั ะฟะพ ะฐะดัะตัั ัะป. ะฟะพััั
-federated_avatar_lookup=ะะฐะนัะธ ะฒะฝะตัะฝะธะน ะฐะฒะฐัะฐั
-enable_custom_avatar=ะัะฟะพะปัะทะพะฒะฐัั ัะพะฑััะฒะตะฝะฝัะน ะฐะฒะฐัะฐั
-choose_new_avatar=ะัะฑัะฐัั ะฝะพะฒัะน ะฐะฒะฐัะฐั
-update_avatar=ะะฑะฝะพะฒะธัั ะฐะฒะฐัะฐั
-delete_current_avatar=ะฃะดะฐะปะธัั ัะตะบััะธะน ะฐะฒะฐัะฐั
-uploaded_avatar_not_a_image=ะะฐะณััะถะฐะตะผัะน ัะฐะนะป ะฝะต ัะฒะปัะตััั ะธะทะพะฑัะฐะถะตะฝะธะตะผ.
-uploaded_avatar_is_too_big=ะ ะฐะทะผะตั ะทะฐะณััะถะฐะตะผะพะณะพ ัะฐะนะปะฐ (%d ะะธะ) ะฟัะตะฒััะฐะตั ะผะฐะบัะธะผะฐะปัะฝัะน ัะฐะทะผะตั (%d ะะธะ).
-update_avatar_success=ะะฐั ะฐะฒะฐัะฐั ะฑัะป ะธะทะผะตะฝะตะฝ.
-update_user_avatar_success=ะะฒะฐัะฐั ะฟะพะปัะทะพะฒะฐัะตะปั ะพะฑะฝะพะฒะปัะฝ.
+lookup_avatar_by_mail=ะะฐะนัะธ ะธะทะพะฑัะฐะถะตะฝะธะต ะฟะพ ะผะพะตะผั ะฐะดัะตัั ัะป. ะฟะพััั
+federated_avatar_lookup=ะคะตะดะตัะธัะพะฒะฐะฝะฝัะน ะฟะพะธัะบ ะธะทะพะฑัะฐะถะตะฝะธะน ะฟัะพัะธะปะตะน
+enable_custom_avatar=ะัะฟะพะปัะทะพะฒะฐัั ัะฒะพั ะธะทะพะฑัะฐะถะตะฝะธะต ะฟัะพัะธะปั
+choose_new_avatar=ะัะฑะตัะธัะต ะฝะพะฒะพะต ะธะทะพะฑัะฐะถะตะฝะธะต ะฟัะพัะธะปั
+update_avatar=ะะฑะฝะพะฒะธัั ะธะทะพะฑัะฐะถะตะฝะธะต ะฟัะพัะธะปั
+delete_current_avatar=ะฃะดะฐะปะธัั ัะตะบััะตะต ะธะทะพะฑัะฐะถะตะฝะธะต ะฟัะพัะธะปั
+uploaded_avatar_not_a_image=ะะฐะณััะถะตะฝะฝัะน ัะฐะนะป ะฝะต ัะฒะปัะตััั ะธะทะพะฑัะฐะถะตะฝะธะตะผ.
+uploaded_avatar_is_too_big=ะ ะฐะทะผะตั ะฒัะฑัะฐะฝะฝะพะณะพ ัะฐะนะปะฐ (%d ะะธะ) ะฟัะตะฒััะฐะตั ะผะฐะบัะธะผะฐะปัะฝัะน ัะฐะทะผะตั (%d ะะธะ).
+update_avatar_success=ะะทะพะฑัะฐะถะตะฝะธะต ะฟัะพัะธะปั ะฑัะปะพ ะธะทะผะตะฝะตะฝะพ.
+update_user_avatar_success=ะะทะพะฑัะฐะถะตะฝะธะต ะฟัะพัะธะปั ะฑัะปะพ ะพะฑะฝะพะฒะปะตะฝะพ.
update_password=ะะฑะฝะพะฒะธัั ะฟะฐัะพะปั
old_password=ะขะตะบััะธะน ะฟะฐัะพะปั
new_password=ะะพะฒัะน ะฟะฐัะพะปั
retype_new_password=ะะพะดัะฒะตัะถะดะตะฝะธะต ะฝะพะฒะพะณะพ ะฟะฐัะพะปั
password_incorrect=ะขะตะบััะธะน ะฟะฐัะพะปั ะฝะตะฟัะฐะฒะธะปัะฝัะน.
-change_password_success=ะะฐั ะฟะฐัะพะปั ะฑัะป ะธะทะผะตะฝัะฝ. ะก ััะพะณะพ ะผะพะผะตะฝัะฐ ะฝะตะพะฑั
ะพะดะธะผะพ ะธัะฟะพะปัะทะพะฒะฐัั ะฝะพะฒัะน ะฟะฐัะพะปั ะดะปั ะฒั
ะพะดะฐ.
+change_password_success=ะะฐั ะฟะฐัะพะปั ะฑัะป ะธะทะผะตะฝัะฝ. ะขะตะฟะตัั ะฟัะธ ะฒั
ะพะดะต ะธัะฟะพะปัะทัะนัะต ะฝะพะฒัะน.
password_change_disabled=ะะตะปะพะบะฐะปัะฝัะต ััััะฝัะต ะทะฐะฟะธัะธ ะฝะต ะผะพะณัั ะธะทะผะตะฝะธัั ะฟะฐัะพะปั ะฒ ะฒะตะฑ-ะธะฝัะตััะตะนัะต Forgejo.
emails=ะะดัะตัะฐ ัะป. ะฟะพััั
manage_emails=ะฃะฟัะฐะฒะปะตะฝะธะต ะฐะดัะตัะฐะผะธ ัะป. ะฟะพััั
-manage_themes=ะัะฑะตัะธัะต ัะตะผั ะฟะพ ัะผะพะปัะฐะฝะธั
-manage_openid=ะฃะฟัะฐะฒะปะตะฝะธะต ะฐะดัะตัะฐะผะธ OpenID
+manage_themes=ะขะตะผะฐ ะธะฝัะตััะตะนัะฐ
+manage_openid=ะะดัะตัะฐ OpenID
email_desc=ะะฐั ะพัะฝะพะฒะฝะพะน ะฐะดัะตั ัะป. ะฟะพััั ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั ะดะปั ัะฒะตะดะพะผะปะตะฝะธะน, ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ะฟะฐัะพะปั ะธ, ะตัะปะธ ะพะฝ ะฝะต ัะบััั, ะดะปั ะดะตะนััะฒะธะน ั Git ะฒ ะฒะตะฑ-ะธะฝัะตััะตะนัะต.
-theme_desc=ะญัะพ ะฑัะดะตั ัะตะผะพะน ะฟะพ ัะผะพะปัะฐะฝะธั ะดะปั ะฒัะตะณะพ ัะฐะนัะฐ.
+theme_desc=ะญัะฐ ัะตะผะฐ ะพัะพัะผะปะตะฝะธั ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั ะฟัะธ ะฒั
ะพะดะต ะฝะฐ ัะฐะนั ะฟะพะด ััะพะน ััััะฝะพะน ะทะฐะฟะธััั.
primary=ะัะฝะพะฒะฝะพะน
activated=ะะบัะธะฒะธัะพะฒะฐะฝ
requires_activation=ะขัะตะฑัะตััั ะฐะบัะธะฒะฐัะธั
primary_email=ะกะดะตะปะฐัั ะพัะฝะพะฒะฝัะผ
-activate_email=ะัะฟัะฐะฒะธัั ะฐะบัะธะฒะฐัะธั
-activations_pending=ะะถะธะดะฐะตั ะฐะบัะธะฒะฐัะธะธ
+activate_email=ะัะฟัะฐะฒะธัั ะฟะธััะผะพ ะฐะบัะธะฒะฐัะธะธ
+activations_pending=ะะถะธะดะฐัั ะฐะบัะธะฒะฐัะธะธ
can_not_add_email_activations_pending=ะะถะธะดะฐะตััั ะฐะบัะธะฒะฐัะธั. ะัะปะธ ั
ะพัะธัะต ะดะพะฑะฐะฒะธัั ะฝะพะฒัะน ะฟะพััะพะฒัะน ััะธะบ, ะฟะพะฟัะพะฑัะนัะต ะตัะต ัะฐะท ัะตัะตะท ะฝะตัะบะพะปัะบะพ ะผะธะฝัั.
delete_email=ะฃะดะฐะปะธัั
email_deletion=ะฃะดะฐะปะธัั ะฐะดัะตั ัะป. ะฟะพััั
@@ -791,10 +837,10 @@ openid_deletion=ะฃะดะฐะปะธัั OpenID URI
openid_deletion_desc=ะะพัะปะต ัะดะฐะปะตะฝะธั ะฐะดัะตัะฐ OpenID ะฒั ะฝะต ัะผะพะถะตัะต ะฒะพะนัะธ ะฒ ะฒะฐัั ััััะฝัั ะทะฐะฟะธัั ั ะตะณะพ ะฟะพะผะพััั. ะั ัะฒะตัะตะฝั?
openid_deletion_success=ะะดัะตั OpenID ัะดะฐะปะตะฝ.
add_new_email=ะะพะฑะฐะฒะธัั ะฐะดัะตั ัะป. ะฟะพััั
-add_new_openid=ะะพะฑะฐะฒะธัั ะฝะพะฒัะน OpenID URI
+add_new_openid=ะะพะฑะฐะฒะธัั ะฝะพะฒัะน URI OpenID
add_email=ะะพะฑะฐะฒะธัั ะฐะดัะตั ัะป. ะฟะพััั
add_openid=ะะพะฑะฐะฒะธัั ะฐะดัะตั OpenID
-add_email_confirmation_sent=ะะธััะผะพ ะดะปั ะฟะพะดัะฒะตัะถะดะตะฝะธั ะพัะฟัะฐะฒะปะตะฝะพ ะฝะฐ ยซ%sยป. ะะพะถะฐะปัะนััะฐ, ะฟัะพะฒะตัััะต ะฒะฐั ะฟะพััะพะฒัะน ััะธะบ ะฒ ัะตัะตะฝะธะต %s, ััะพะฑั ะทะฐะฒะตััะธัั ะฟัะพัะตัั ะฟะพะดัะฒะตัะถะดะตะฝะธั.
+add_email_confirmation_sent=ะะธััะผะพ ะดะปั ะฟะพะดัะฒะตัะถะดะตะฝะธั ะพัะฟัะฐะฒะปะตะฝะพ ะฝะฐ ยซ%sยป. ะงัะพะฑั ะฟะพะดัะฒะตัะดะธัั ััะพั ะฐะดัะตั ัะป. ะฟะพััั, ะฟะพะถะฐะปัะนััะฐ, ะฟะตัะตะนะดะธัะต ะฟะพ ัััะปะบะต ะฒะฝัััะธ ะฒ ัะตัะตะฝะธะต %s.
add_email_success=ะะพะฑะฐะฒะปะตะฝ ะฝะพะฒัะน ะฐะดัะตั ัะป. ะฟะพััั.
email_preference_set_success=ะะฐัััะพะนะบะธ ัะป. ะฟะพััั ััะฟะตัะฝะพ ัััะฐะฝะพะฒะปะตะฝั.
add_openid_success=ะะพะฑะฐะฒะปะตะฝ ะฝะพะฒัะน ะฐะดัะตั OpenID.
@@ -805,16 +851,16 @@ manage_ssh_keys=ะฃะฟัะฐะฒะปะตะฝะธะต ะบะปััะฐะผะธ SSH
manage_ssh_principals=ะฃะฟัะฐะฒะปะตะฝะธะต ะฟัะธะฝัะธะฟะฐะปะฐะผะธ ัะตััะธัะธะบะฐัะพะฒ SSH
manage_gpg_keys=ะฃะฟัะฐะฒะปะตะฝะธะต ะบะปััะฐะผะธ GPG
add_key=ะะพะฑะฐะฒะธัั ะบะปัั
-ssh_desc=ะญัะธ ะพัะบััััะต ะบะปััะธ SSH ัะฒัะทะฐะฝั ั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธััั. ะกะพะพัะฒะตัััะฒัััะธะต ะธะผ ะทะฐะบััััะต ะบะปััะธ ะพะฑะตัะฟะตัะธะฒะฐัั ะฟะพะปะฝัะน ะดะพัััะฟ ะบ ะฒะฐัะธะผ ัะตะฟะพะทะธัะพัะธัะผะธ. ะะพะดัะฒะตัะถะดัะฝะฝัะต ะบะปััะธ SSH ะผะพะณัั ะฑััั ะธัะฟะพะปัะทะพะฒะฐะฝั ะดะปั ะฟะพะดัะฒะตัะถะดะตะฝะธั ะฟะพะดะฟะธัะฐะฝะฝัั
ั SSH ะบะพะผะผะธัะพะฒ.
+ssh_desc=ะญัะธ ะพัะบััััะต ะบะปััะธ SSH ัะฒัะทะฐะฝั ั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธััั. ะกะพะพัะฒะตัััะฒัััะธะต ะธะผ ะทะฐะบััััะต ะบะปััะธ ะดะฐัั ะฟะพะปะฝัะน ะดะพัััะฟ ะบ ะฒะฐัะธะผ ัะตะฟะพะทะธัะพัะธัะผ. ะะพะดัะฒะตัะถะดัะฝะฝัะต ะบะปััะธ SSH ะผะพะณัั ะฑััั ะธัะฟะพะปัะทะพะฒะฐะฝั ะดะปั ะฟัะพะฒะตัะบะธ ะบะพะผะผะธัะพะฒ, ะฟะพะดะฟะธัะฐะฝะฝัั
ั SSH.
principal_desc=ะญัะธ ะฟัะธะฝัะธะฟะฐะปั ัะตััะธัะธะบะฐัะพะฒ SSH ะฟัะธะฒัะทะฐะฝั ะบ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ ะธ ัะฐะทัะตัะฐัั ะฟะพะปะฝัะน ะดะพัััะฟ ะบ ะฒะฐัะธะผ ัะตะฟะพะทะธัะพัะธัะผ.
-gpg_desc=ะญัะธ ะพัะบััััะต GPG-ะบะปััะธ ะฐััะพัะธะธัััััั ั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธััั ะธ ะธัะฟะพะปัะทััััั ะดะปั ะฟัะพะฒะตัะบะธ ะฟะพะดะปะธะฝะฝะพััะธ ะบะพะผะผะธัะพะฒ. ะฅัะฐะฝะธัะต ะทะฐะบััััะต ะบะปััะธ ะฒ ะฑะตะทะพะฟะฐัะฝะพััะธ, ั.ะบ. ะธะผะธ ะผะพะถะฝะพ ะฟะพะดะฟะธััะฒะฐัั ะบะพะผะผะธัั ะพั ะฒะฐัะตะณะพ ะปะธัะฐ.
+gpg_desc=ะญัะธ ะพัะบััััะต ะบะปััะธ GPG ัะฒัะทะฐะฝั ั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธััั ะธ ะธัะฟะพะปัะทััััั ะดะปั ะฟัะพะฒะตัะบะธ ะฟะพะดะปะธะฝะฝะพััะธ ะบะพะผะผะธัะพะฒ. ะฅัะฐะฝะธัะต ะทะฐะบััััะต ะบะปััะธ ะฒ ะฑะตะทะพะฟะฐัะฝะพััะธ, ั.ะบ. ะธะผะธ ะผะพะถะฝะพ ะฟะพะดะฟะธััะฒะฐัั ะบะพะผะผะธัั ะพั ะฒะฐัะตะณะพ ะปะธัะฐ.
ssh_helper=ะัะถะฝะฐ ะฟะพะผะพัั? ะะทะฝะฐะบะพะผััะตัั ั ััะบะพะฒะพะดััะฒะพะผ GitHub ะฟะพ ัะพะทะดะฐะฝะธั ะบะปััะตะน SSH ะธะปะธ ัะตัะตะฝะธั ะฒะพะทะฝะธะบะฐััะธั
ะฟัะพะฑะปะตะผ ะฟัะธ ะธัะฟะพะปัะทะพะฒะฐะฝะธะธ SSH.
gpg_helper=ะัะถะฝะฐ ะฟะพะผะพัั? ะะทะณะปัะฝะธัะต ะฝะฐ ััะบะพะฒะพะดััะฒะพ GitHub ะฟะพ GPG .
add_new_key=ะะพะฑะฐะฒะธัั ะบะปัั SSH
add_new_gpg_key=ะะพะฑะฐะฒะธัั ะบะปัั GPG
key_content_ssh_placeholder=ะะฐัะธะฝะฐะตััั ั ยซssh-ed25519ยป, ยซssh-rsaยป, ยซecdsa-sha2-nistp256ยป, ยซecdsa-sha2-nistp384ยป, ยซecdsa-sha2-nistp521ยป, ยซsk-ecdsa-sha2-nistp256@openssh.comยป ะธะปะธ ยซsk-ssh-ed25519@openssh.comยป
key_content_gpg_placeholder=ะะฐัะธะฝะฐะตััั ั ยซ-----BEGIN PGP PUBLIC KEY BLOCK-----ยป
-add_new_principal=ะะพะฑะฐะฒะธัั ะฟัะธะฝัะธะฟะฐะปะฐ
+add_new_principal=ะะพะฑะฐะฒะธัั ะฟัะธะฝัะธะฟะฐะป
ssh_key_been_used=ะญัะพั ะบะปัั SSH ัะถะต ะฑัะป ะดะพะฑะฐะฒะปะตะฝ ะฝะฐ ัะตัะฒะตั.
ssh_key_name_used=ะะปัั SSH ั ัะฐะบะธะผ ะธะผะตะฝะตะผ ัะถะต ะตััั ะฒ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ.
ssh_principal_been_used=ะัะธะฝัะธะฟะฐะป ัะถะต ะฑัะป ะดะพะฑะฐะฒะปะตะฝ ะฝะฐ ัะตัะฒะตั.
@@ -881,7 +927,7 @@ social_desc=ะญัะธ ััััะฝัะต ะทะฐะฟะธัะธ ัะพัะธะฐะปัะฝัั
ัะตัะตะน
unbind=ะฃะดะฐะปะธัั ัะฒัะทั
unbind_success=ะฃัััะฝะฐั ะทะฐะฟะธัั ัะพัะธะฐะปัะฝะพะน ัะตัะธ ััะฟะตัะฝะพ ัะดะฐะปะตะฝะฐ.
-manage_access_token=ะฃะฟัะฐะฒะปะตะฝะธะต ัะพะบะตะฝะฐะผะธ
+manage_access_token=ะขะพะบะตะฝั ะดะพัััะฟะฐ
generate_new_token=ะกะพะทะดะฐัั ะฝะพะฒัะน ัะพะบะตะฝ
tokens_desc=ะญัะธ ัะพะบะตะฝั ะฟัะตะดะพััะฐะฒะปััั ะดะพัััะฟ ะบ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ ั ะฟะพะผะพััั Forgejo API.
token_name=ะะผั ัะพะบะตะฝะฐ
@@ -901,27 +947,27 @@ select_permissions=ะัะฑัะฐัั ัะฐะทัะตัะตะฝะธั
permission_no_access=ะะตั ะดะพัััะฟะฐ
permission_read=ะงัะตะฝะธะต
permission_write=ะงัะตะฝะธะต ะธ ะทะฐะฟะธัั
-access_token_desc=ะัะฑัะฐะฝะฝัะต ะพะฑะปะฐััะธ ะดะตะนััะฒะธั ัะพะบะตะฝะฐ ะพะณัะฐะฝะธัะธะฒะฐัั ะฐะฒัะพัะธะทะฐัะธั ัะพะปัะบะพ ัะพะพัะฒะตัััะฒัััะธะผะธ ะผะฐัััััะฐะผะธ API . ะงะธัะฐะนัะต ะดะพะบัะผะตะฝัะฐัะธั ะดะปั ะฟะพะปััะตะฝะธั ะดะพะฟะพะปะฝะธัะตะปัะฝะพะน ะธะฝัะพัะผะฐัะธะธ.
+access_token_desc=ะัะฑัะฐะฝะฝัะต ะพะฑะปะฐััะธ ะดะตะนััะฒะธั ัะพะบะตะฝะฐ ะพะณัะฐะฝะธัะธะฒะฐัั ะตะณะพ ะธัะฟะพะปัะทะพะฒะฐะฝะธะต ะดะพ ัะพะพัะฒะตัััะฒัััะธั
ะผะฐัััััะพะฒ API . ะะปั ะฟะพะปััะตะฝะธั ะฟะพะดัะพะฑะฝะพััะตะน ะพะทะฝะฐะบะพะผััะตัั ั ะดะพะบัะผะตะฝัะฐัะธะตะน .
at_least_one_permission=ะะตะพะฑั
ะพะดะธะผะพ ะฒัะฑัะฐัั ั
ะพัั ะฑั ะพะดะฝะพ ัะฐะทัะตัะตะฝะธะต ะดะปั ัะพะทะดะฐะฝะธั ัะพะบะตะฝะฐ
permissions_list=ะ ะฐะทัะตัะตะฝะธั:
manage_oauth2_applications=ะฃะฟัะฐะฒะปะตะฝะธะต ะฟัะธะปะพะถะตะฝะธัะผะธ OAuth2
edit_oauth2_application=ะะทะผะตะฝะธัั ะฟัะธะปะพะถะตะฝะธะต OAuth2
oauth2_applications_desc=ะัะธะปะพะถะตะฝะธั OAuth2 ะฟะพะทะฒะพะปัะตั ััะพัะพะฝะฝะตะผั ะฟัะธะปะพะถะตะฝะธั ะบ ะฑะตะทะพะฟะฐัะฝะพ ะฐััะตะฝัะธัะธัะธัะพะฒะฐัั ะฟะพะปัะทะพะฒะฐัะตะปะตะน ะดะฐะฝะฝะพะน ัััะฐะฝะพะฒะบะธ Forgejo.
-remove_oauth2_application=ะฃะดะฐะปะธัั ะฟัะธะปะพะถะตะฝะธะต OAuth2
-remove_oauth2_application_desc=ะฃะดะฐะปะตะฝะธะต ะฟัะธะปะพะถะตะฝะธั OAuth2 ะพัะผะตะฝะธั ะดะพัััะฟ ะบะพ ะฒัะตะผ ะฟะพะดะฟะธัะฐะฝะฝัะผ ัะพะบะตะฝะฐะผ ะดะพัััะฟะฐ. ะัะพะดะพะปะถะธัั?
-remove_oauth2_application_success=ะัะธะปะพะถะตะฝะธะต ัะดะฐะปะตะฝะพ.
+remove_oauth2_application=ะฃะดะฐะปะตะฝะธะต ะฟัะธะปะพะถะตะฝะธั OAuth2
+remove_oauth2_application_desc=ะฃะดะฐะปะตะฝะธะต ััะพะณะพ ะฟัะธะปะพะถะตะฝะธั ะพัะผะตะฝะธั ะดะพัััะฟ ะบะพ ะฒัะตะผ ะฟะพะดะฟะธัะฐะฝะฝัะผ ัะพะบะตะฝะฐะผ ะดะพัััะฟะฐ. ะัะพะดะพะปะถะธัั?
+remove_oauth2_application_success=ะัะธะปะพะถะตะฝะธะต ะฑัะปะพ ััะฟะตัะฝะพ ัะดะฐะปะตะฝะพ.
create_oauth2_application=ะกะพะทะดะฐัั ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต OAuth2
create_oauth2_application_button=ะกะพะทะดะฐัั ะฟัะธะปะพะถะตะฝะธะต
create_oauth2_application_success=ะั ััะฟะตัะฝะพ ัะพะทะดะฐะปะธ ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต OAuth2.
update_oauth2_application_success=ะะทะผะตะฝะตะฝะธั ะฝะฐัััะพะตะบ ะฟัะธะปะพะถะตะฝะธั OAuth2 ััะฟะตัะฝะพ ะฟัะธะผะตะฝะตะฝั.
oauth2_application_name=ะะผั ะฟัะธะปะพะถะตะฝะธั
-oauth2_redirect_uris=URI ะดะปั ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝะธั. ะัะฟะพะปัะทัะนัะต ะฝะพะฒัั ัััะพะบั ะดะปั ะบะฐะถะดะพะณะพ URI.
+oauth2_redirect_uris=URI ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝะธะน. ะ ะฐะทะผะตัะฐะนัะต URI ะฝะฐ ะพัะดะตะปัะฝัั
ัััะพะบะฐั
.
save_application=ะกะพั
ัะฐะฝะธัั
oauth2_client_id=ะะ ะบะปะธะตะฝัะฐ
oauth2_client_secret=ะะปะธะตะฝััะบะธะน ะบะปัั
-oauth2_regenerate_secret=ะกะณะตะฝะตัะธัะพะฒะฐัั ะฝะพะฒัะน ะบะปัั
-oauth2_regenerate_secret_hint=ะะพัะตััะปะธ ัะฒะพะน ะบะปัั?
+oauth2_regenerate_secret=ะกะพะทะดะฐัั ะฝะพะฒัะน
+oauth2_regenerate_secret_hint=ะะปัั ะฑัะป ััะตััะฝ?
oauth2_client_secret_hint=ะกะตะบัะตั ะฝะต ะฑัะดะตั ะฟะพะบะฐะทะฐะฝ ะฟะพัะปะต ัะพะณะพ, ะบะฐะบ ะฒั ะฟะพะบะธะฝะตัะต ะธะปะธ ะพะฑะฝะพะฒะธัะต ัััะฐะฝะธัั. ะฃะฑะตะดะธัะตัั, ััะพ ะฒั ะตะณะพ ะฝะฐะดัะถะฝะพ ัะพั
ัะฐะฝะธะปะธ.
oauth2_application_edit=ะะทะผะตะฝะธัั
oauth2_application_create_description=ะัะธะปะพะถะตะฝะธั OAuth2 ะฟัะตะดะพััะฐะฒะปัะตั ััะพัะพะฝะฝะตะผั ะฟัะธะปะพะถะตะฝะธั ะดะพัััะฟ ะบ ััััะฝัะผ ะทะฐะฟะธััะผ ะฟะพะปัะทะพะฒะฐัะตะปะตะน ะดะฐะฝะฝะพะณะพ ัะตัะฒะธัะฐ.
@@ -943,7 +989,7 @@ twofa_scratch_token_regenerate=ะะตัะตัะพะทะดะฐัั ะพะดะฝะพัะฐะทะพะฒัะน ะบ
twofa_enroll=ะะบะปััะธัั 2ะคะ
twofa_disable_note=ะัะธ ะฝะตะพะฑั
ะพะดะธะผะพััะธ ะผะพะถะฝะพ ะพัะบะปััะธัั ะดะฒัั
ัะฐะบัะพัะฝัั ะฐััะตะฝัะธัะธะบะฐัะธั.
twofa_disable_desc=ะัะบะปััะตะฝะธะต ะดะฒัั
ัะฐะบัะพัะฝะพะน ะฐััะตะฝัะธัะธะบะฐัะธะธ ัะฝะธะทะธั ะฑะตะทะพะฟะฐัะฝะพััั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ. ะัะพะดะพะปะถะธัั?
-regenerate_scratch_token_desc=ะัะปะธ ะฒั ะฟะพัะตััะปะธ ัะฒะพะน scratch-ัะพะบะตะฝ ะธะปะธ ัะถะต ะธัะฟะพะปัะทะพะฒะฐะปะธ ะตะณะพ ะดะปั ะฒั
ะพะดะฐ, ะฒั ะผะพะถะตัะต ัะฑัะพัะธัั ะตะณะพ ะทะดะตัั.
+regenerate_scratch_token_desc=ะัะปะธ ะฒั ะฟะพัะตััะปะธ ัะฒะพะน ะบะพะด ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ะธะปะธ ัะถะต ะธัะฟะพะปัะทะพะฒะฐะปะธ ะตะณะพ ะดะปั ะฒั
ะพะดะฐ, ะผะพะถะตัะต ัะฑัะพัะธัั ะตะณะพ ะทะดะตัั.
twofa_disabled=ะะฒัั
ัะฐะบัะพัะฝะฐั ะฐััะตะฝัะธัะธะบะฐัะธั ะฒัะบะปััะตะฝะฐ.
scan_this_image=ะััะบะฐะฝะธััะนัะต ััะพ ะธะทะพะฑัะฐะถะตะฝะธะต ะฒะฐัะธะผ ะฟัะธะปะพะถะตะฝะธะตะผ ะดะปั ะดะฒัั
ัะฐะบัะพัะฝะพะน ะฐััะตะฝัะธัะธะบะฐัะธะธ:
or_enter_secret=ะะปะธ ะฒะฒะตะดะธัะต ะบะพะดะพะฒะพะต ัะปะพะฒะพ: %s
@@ -952,18 +998,18 @@ passcode_invalid=ะะตะฒะตัะฝัะน ะฟะฐัะพะปั. ะฟะพะฟัะพะฑัะนัะต ัะฝะพะฒะฐ.
twofa_enrolled=ะะปั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ ะฑัะปะฐ ะฒะบะปััะตะฝะฐ ะดะฒัั
ัะฐะบัะพัะฝะฐั ะฐััะตะฝัะธัะธะบะฐัะธั. ะกะพั
ัะฐะฝะธัะต ััะพั ะพะดะฝะพัะฐะทะพะฒัะน ะบะปัั ะฒะพัััะฐะฝะพะฒะปะตะฝะธั (%s) ะฒ ะฑะตะทะพะฟะฐัะฝะพะผ ะผะตััะต. ะะฝ ะฑะพะปััะต ะฝะต ะฑัะดะตั ะฟะพะบะฐะทะฐะฝ.
twofa_failed_get_secret=ะะต ัะดะฐะปะพัั ะฟะพะปััะธัั ะบะปัั.
-webauthn_desc=ะะปััะธ ะฑะตะทะพะฟะฐัะฝะพััะธ - ััะพ ะฐะฟะฟะฐัะฐัะฝัะต ััััะพะนััะฒะฐ, ัะพะดะตัะถะฐัะธะต ะบัะธะฟัะพะณัะฐัะธัะตัะบะธะต ะบะปััะธ. ะะฝะธ ะผะพะณัั ะธัะฟะพะปัะทะพะฒะฐัััั ะดะปั ะดะฒัั
ัะฐะบัะพัะฝะพะน ะฐััะตะฝัะธัะธะบะฐัะธะธ. ะะปััะธ ะฑะตะทะพะฟะฐัะฝะพััะธ ะดะพะปะถะฝั ะฟะพะดะดะตัะถะธะฒะฐัั ััะฐะฝะดะฐัั WebAuthn Authenticator .
+webauthn_desc=ะะปััะธ ะฑะตะทะพะฟะฐัะฝะพััะธ - ััะพ ะฐะฟะฟะฐัะฐัะฝัะต ััััะพะนััะฒะฐ, ัะพะดะตัะถะฐัะธะต ะบัะธะฟัะพะณัะฐัะธัะตัะบะธะต ะบะปััะธ. ะะฝะธ ะผะพะณัั ะธัะฟะพะปัะทะพะฒะฐัััั ะดะปั ะดะฒัั
ัะฐะบัะพัะฝะพะน ะฐััะตะฝัะธัะธะบะฐัะธะธ. ะะปััะธ ะฑะตะทะพะฟะฐัะฝะพััะธ ะดะพะปะถะฝั ะฟะพะดะดะตัะถะธะฒะฐัั ััะฐะฝะดะฐัั WebAuthn Authenticator .
webauthn_register_key=ะะพะฑะฐะฒะธัั ะบะปัั ะฑะตะทะพะฟะฐัะฝะพััะธ
webauthn_nickname=ะะผั ะฟะพะปัะทะพะฒะฐัะตะปั
webauthn_delete_key=ะฃะดะฐะปะธัั ะบะปัั ะฑะตะทะพะฟะฐัะฝะพััะธ
webauthn_delete_key_desc=ะัะปะธ ัะดะฐะปะธัั ะบะปัั ะฑะตะทะพะฟะฐัะฝะพััะธ, ะตะณะพ ะฑะพะปััะต ะฝะต ะฒัะนะดะตั ะธัะฟะพะปัะทะพะฒะฐัั ะดะปั ะฒั
ะพะดะฐ. ะัะพะดะพะปะถะธัั?
webauthn_key_loss_warning=ะะพัะตัั ะบะปััะตะน ะฑะตะทะพะฟะฐัะฝะพััะธ ะฟัะธะฒะตะดัั ะบ ัััะฐัะต ะดะพัััะฟะฐ ะบ ััััะฝะพะน ะทะฐะฟะธัะธ.
-manage_account_links=ะฃะฟัะฐะฒะปะตะฝะธะต ะฟัะธะฒัะทะฐะฝะฝัะผะธ ััััะฝัะผะธ ะทะฐะฟะธััะผะธ
+manage_account_links=ะัะธะฒัะทะฐะฝะฝัะต ััะตัะฝัะต ะทะฐะฟะธัะธ
manage_account_links_desc=ะญัะธ ััะพัะพะฝะฝะธะต ััััะฝัะต ะทะฐะฟะธัะธ ะฟัะธะฒัะทะฐะฝั ะบ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ Forgejo.
account_links_not_available=ะฃ ะฒะฐั ะฝะตั ะฟัะธะฒัะทะฐะฝะฝัั
ััะพัะพะฝะฝะธั
ััััะฝัั
ะทะฐะฟะธัะตะน.
link_account=ะัะธะฒัะทะฐัั ััััะฝัั ะทะฐะฟะธัั
-remove_account_link=ะฃะดะฐะปะธัั ะฟัะธะฒัะทะฐะฝะฝัะน ะฐะบะบะฐัะฝั
+remove_account_link=ะฃะดะฐะปะธัั ะฟัะธะฒัะทะฐะฝะฝัั ััััะฝัั ะทะฐะฟะธัั
remove_account_link_desc=ะฃะดะฐะปะตะฝะธะต ะฟัะธะฒัะทะฐะฝะฝะพะน ััััะฝะพะน ะทะฐะฟะธัะธ ะพัะผะตะฝะธั ะตั ะดะพัััะฟ ะบ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ Forgejo. ะัะพะดะพะปะถะธัั?
remove_account_link_success=ะัะธะฒัะทะฐะฝะฝะฐั ััััะฝะฐั ะทะฐะฟะธัั ัะดะฐะปะตะฝะฐ.
@@ -972,11 +1018,11 @@ orgs_none=ะั ะฝะต ัะพััะพะธัะต ะฝะธ ะฒ ะพะดะฝะพะน ะพัะณะฐะฝะธะทะฐัะธะธ.
repos_none=ะั ะฝะต ะฒะปะฐะดะตะตัะต ะฝะธ ะพะดะฝะธะผ ัะตะฟะพะทะธัะพัะธะตะผ.
delete_account=ะฃะดะฐะปะตะฝะธะต ััััะฝะพะน ะทะฐะฟะธัะธ
-delete_prompt=ะญัะฐ ะพะฟะตัะฐัะธั ะฝะฐะฒัะตะณะดะฐ ัะดะฐะปะธั ะฒะฐัั ััััะฝัั ะทะฐะฟะธัั. ะญัะพ ะะะะะะะะะะ ะฑัะดะตั ะพัะผะตะฝะธัั.
+delete_prompt=ะญัะฐ ะพะฟะตัะฐัะธั ะฝะฐะฒัะตะณะดะฐ ัะดะฐะปะธั ะฒะฐัั ััััะฝัั ะทะฐะฟะธัั. ะั ะะะะะะะะะะ ะพัะผะตะฝะธัั.
delete_with_all_comments=ะะฐัะฐ ััััะฝะฐั ะทะฐะฟะธัั ะผะปะฐะดัะต %s. ะงัะพะฑั ะธะทะฑะตะถะฐัั ะบะพะผะผะตะฝัะฐัะธะตะฒ ะบ ะฟะปะฐะฝั, ะฒัะต ะบะพะผะผะตะฝัะฐัะธะธ ะบ ะฝะตะน ะฑัะดัั ัะดะฐะปะตะฝั.
confirm_delete_account=ะะพะดัะฒะตัะดะธัั ัะดะฐะปะตะฝะธะต
-delete_account_title=ะฃะดะฐะปะธัั ััั ััััะฝัั ะทะฐะฟะธัั
-delete_account_desc=ะั ัะฒะตัะตะฝั, ััะพ ั
ะพัะธัะต ะฝะฐะฒัะตะณะดะฐ ัะดะฐะปะธัั ััั ััััะฝัั ะทะฐะฟะธัั?
+delete_account_title=ะฃะดะฐะปะตะฝะธะต ััััะฝะพะน ะทะฐะฟะธัะธ
+delete_account_desc=ะั ัะพัะฝะพ ั
ะพัะธัะต ะฝะฐะฒัะตะณะดะฐ ัะดะฐะปะธัั ััั ััััะฝัั ะทะฐะฟะธัั?
email_notifications.enable=ะะบะปััะธัั ัะฒะตะดะพะผะปะตะฝะธั ะฟะพ ัะป. ะฟะพััะต
email_notifications.onmention=ะะพััะปะฐัั ะฟะธััะผะพ ะฝะฐ ัะป. ะฟะพััั ัะพะปัะบะพ ะฟัะธ ัะฟะพะผะธะฝะฐะฝะธะธ
@@ -984,34 +1030,67 @@ email_notifications.disable=ะัะบะปััะธัั ัะฒะตะดะพะผะปะตะฝะธั ะฟะพ ะฟะพ
email_notifications.submit=ะะฐะดะฐัั ะฝะฐัััะพะนะบั ัะฒะตะดะพะผะปะตะฝะธะน
email_notifications.andyourown=ะ ะฒะฐัะธ ัะพะฑััะฒะตะฝะฝัะต ัะฒะตะดะพะผะปะตะฝะธั
-visibility=ะะธะดะธะผะพััั ะฟะพะปัะทะพะฒะฐัะตะปั
+visibility=ะะธะดะธะผะพััั ะฟัะพัะธะปั
visibility.public=ะัะฑะปะธัะฝัะน
-visibility.public_tooltip=ะะธะดะธะผัะน ะดะปั ะฒัะตั
+visibility.public_tooltip=ะะธะดะตะฝ ะฒัะตะผ, ะบัะพ ะผะพะถะตั ะพัะบัััั ััะพั ัะฐะนั
visibility.limited=ะะณัะฐะฝะธัะตะฝะฝัะน
-visibility.limited_tooltip=ะะธะดะตะฝ ัะพะปัะบะพ ะฒัะฟะพะปะฝะธะฒัะธะผ ะฒั
ะพะด ะฟะพะปัะทะพะฒะฐัะตะปัะผ
-visibility.private=ะัะธะฒะฐัะฝัะน
-visibility.private_tooltip=ะะธะดะฝะพ ัะพะปัะบะพ ััะฐััะฝะธะบะฐะผ ะพัะณะฐะฝะธะทะฐัะธะน, ะบ ะบะพัะพััะผ ะฒั ะฟัะธัะพะตะดะธะฝะธะปะธัั
+visibility.limited_tooltip=ะะธะดะตะฝ ัะพะปัะบะพ ะทะฐัะตะณะธัััะธัะพะฒะฐะฝะฝัะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ
+visibility.private=ะกะบััััะน
+visibility.private_tooltip=ะะธะดะตะฝ ัะพะปัะบะพ ััะฐััะฝะธะบะฐะผ ะพัะณะฐะฝะธะทะฐัะธะน, ะฒ ะบะพัะพััั
ะฒั ัะพััะพะธัะต
blocked_users_none = ะะฐะฑะปะพะบะธัะพะฒะฐะฝะฝัั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน ะฝะตั.
user_block_success = ะะพะปัะทะพะฒะฐัะตะปั ะทะฐะฑะปะพะบะธัะพะฒะฐะฝ.
oauth2_application_locked = Forgejo ะฟัะตะดะฒะฐัะธัะตะปัะฝะพ ัะตะณะธัััะธััะตั ะฝะตะบะพัะพััะต ะฟัะธะปะพะถะตะฝะธั OAuth2 ะฟัะธ ะทะฐะฟััะบะต, ะตัะปะธ ััะพ ะฒะบะปััะตะฝะพ ะฒ ะบะพะฝัะธะณััะฐัะธะธ. ะะปั ะธะทะฑะตะถะฐะฝะธั ะฝะตะพะถะธะดะฐะฝะฝะพะณะพ ะฟะพะฒะตะดะตะฝะธั ะธั
ะฝะตะปัะทั ัะดะฐะปััั ะธะปะธ ัะตะดะฐะบัะธัะพะฒะฐัั. ะะทะฝะฐะบะพะผะธัััั ั ะฟะพะดัะพะฑะฝะพัััะผะธ ะผะพะถะฝะพ ะฒ ะดะพะบัะผะตะฝัะฐัะธะธ OAuth2.
hooks.desc = ะะพะฑะฐะฒััะต ะฒะตะฑ-ั
ัะบะธ, ะบะพัะพััะต ะฑัะดัั ััะฐะฑะฐััะฒะฐัั ะฒะพ ะฒัะตั
ะฒะฐัะธั
ัะตะฟะพะทะธัะพัะธัั
.
webauthn_alternative_tip = ะะพะทะผะพะถะฝะพ, ััะพะธั ะฝะฐัััะพะธัั ะดะพะฟะพะปะฝะธัะตะปัะฝัะน ะผะตัะพะด ะฐััะตะฝัะธัะธะบะฐัะธะธ.
-blocked_since = ะะฐะฑะปะพะบะธัะพะฒะฐะฝ ั %s
+blocked_since = ะะฐะฑะปะพะบะธัะพะฒะฐะฝ %s
user_unblock_success = ะะพะปัะทะพะฒะฐัะตะปั ัะฐะทะฑะปะพะบะธัะพะฒะฐะฝ.
twofa_scratch_token_regenerated = ะะฐั ะพะดะฝะพัะฐะทะพะฒัะน ะบะปัั ะฒะพัััะฐะฝะพะฒะปะตะฝะธั: %s. ะกะพั
ัะฐะฝะธัะต ะตะณะพ ะฒ ะฝะฐะดัะถะฝะพะผ ะผะตััะต. ะะพะปััะต ะพะฝ ะฟะพะบะฐะทะฐะฝ ะฝะต ะฑัะดะตั.
blocked_users = ะะฐะฑะปะพะบะธัะพะฒะฐะฝะฝัะต ะฟะพะปัะทะพะฒะฐัะตะปะธ
-keep_email_private_popup = ะะฐั ะฐะดัะตั ัะป. ะฟะพััั ะฑัะดะตั ัะบััั ะธะท ะฟัะพัะธะปั ะธ ะฝะต ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐะฝ ะดะปั ะทะฐะฟัะพัะพะฒ ะฝะฐ ัะปะธัะฝะธะต ะธะปะธ ะฟัะธ ัะตะดะฐะบัะธัะพะฒะฐะฝะธะธ ัะฐะนะปะพะฒ ะธะท ะฒะตะฑ-ะธะฝัะตััะตะนัะฐ. ะฃะถะต ัััะตััะฒัััะธะต ะบะพะผะธัั ะฝะต ะฑัะดัั ะธะทะผะตะฝะตะฝั. ะัะฟะพะปัะทัะนัะต %s ะฒ ะบะฐัะตััะฒะต ะฐะดัะตัะฐ ะดะปั ะบะพะผะธัะพะฒ, ััะพะฑั ะพะฝะธ ะฐััะพัะธะธัะพะฒะฐะปะธัั ั ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธััั.
+keep_email_private_popup = ะะฐั ะฐะดัะตั ัะป. ะฟะพััั ะฝะต ะฑัะดะตั ะฒะธะดะธะผ ะฒ ะฟัะพัะธะปะต ะธ ะฝะต ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐะฝ ะฟะพ ัะผะพะปัะฐะฝะธั ะดะปั ะบะพะผะผะธัะพะฒ ะธะท ะฒะตะฑ-ะธะฝัะตััะตะนัะฐ, ัะฐะบะธั
ะบะฐะบ ะทะฐะณััะทะบะฐ ะธ ัะตะดะฐะบัะธัะพะฒะฐะฝะธะต ัะฐะนะปะพะฒ, ะฐ ัะฐะบะถะต ะดะปั ะบะพะผะผะธัะพะฒ ัะปะธัะฝะธะน. ะะผะตััะพ ะฝะตะณะพ ะดะปั ัะฒัะทะธ ะบะพะผะผะธัะพะฒ ั ัั. ะทะฐะฟะธััั ะผะพะถะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั ัะฟะตัะธะฐะปัะฝัะน ะฐะดัะตั %s. ะะทะผะตะฝะตะฝะธะต ะดะฐะฝะฝะพะน ะฝะฐัััะพะนะบะธ ะฝะต ะธะทะผะตะฝะธั ะฐะดัะตั ะฒ ัััะตััะฒัััะธั
ะบะพะผะผะธัะฐั
.
oauth2_confidential_client = ะะพะฝัะธะดะตะฝัะธะฐะปัะฝัะน ะบะปะธะตะฝั. ะัะฑะตัะธัะต ะดะปั ะฟัะธะปะพะถะตะฝะธะน, ั
ัะฐะฝััะธั
ัะตะบัะตั ะฒ ัะฐะนะฝะต, ะฝะฐะฟัะธะผะตั, ะดะปั ะฒะตะฑ-ะฟัะธะปะพะถะตะฝะธะน. ะะต ะฒัะฑะธัะฐะนัะต ะดะปั ะฝะฐัะธะฒะฝัั
ะฟัะธะปะพะถะตะฝะธะน, ะฒะบะปััะฐั ะฟัะธะปะพะถะตะฝะธั ะดะปั ะะ ะธะปะธ ัะผะฐัััะพะฝะพะฒ.
change_password = ะะทะผะตะฝะตะฝะธะต ะฟะฐัะพะปั
hints = ะะพะดัะบะฐะทะบะธ
additional_repo_units_hint = ะัะตะดะปะฐะณะฐัั ะฒะบะปััะธัั ะฑะพะปััะต ัะฐะทะดะตะปะพะฒ ะฒ ัะตะฟะพะทะธัะพัะธัั
update_hints = ะะฑะฝะพะฒะธัั ะฟะพะดัะบะฐะทะบะธ
update_hints_success = ะะพะดัะบะฐะทะบะธ ะพะฑะฝะพะฒะปะตะฝั.
-additional_repo_units_hint_description = ะะพะบะฐะทัะฒะฐัั ะบะฝะพะฟะบั "ะะพะฑะฐะฒะธัั ะฑะพะปััะต ัะฐะทะดะตะปะพะฒ" ะฒ ัะตะฟะพะทะธัะพัะธัั
, ะฒ ะบะพัะพััั
ะฒะบะปััะตะฝั ะฝะต ะฒัะต ัะฐะทะดะตะปั.
+additional_repo_units_hint_description = ะะพะบะฐะทัะฒะฐัั ะฟะพะดัะบะฐะทะบั "ะะบะปััะธัั ะฑะพะปััะต ัะฐะทะดะตะปะพะฒ" ะฒ ัะตะฟะพะทะธัะพัะธัั
, ะฒ ะบะพัะพััั
ะฒะบะปััะตะฝั ะฝะต ะฒัะต ัะฐะทะดะตะปั.
pronouns_custom = ะััะณะธะต
pronouns = ะะตััะพะธะผะตะฝะธั
pronouns_unspecified = ะะต ัะบะฐะทะฐะฝั
-language.title = ะฏะทัะบ ะฟะพ ัะผะพะปัะฐะฝะธั
+language.title = ะฏะทัะบ ะธะฝัะตััะตะนัะฐ
+keep_activity_private.description = ะะฐัะฐ ะฟัะฑะปะธัะฝะฐั ะฐะบัะธะฒะฝะพััั ะฑัะดะตั ะฒะธะดะฝะฐ ัะพะปัะบะพ ะฒะฐะผ ะธ ะฐะดะผะธะฝะธัััะฐัะพัะฐะผ ัะตัะฒะตัะฐ.
+language.description = ะัะฑัะฐะฝะฝัะน ัะทัะบ ะฑัะดะตั ัะพั
ัะฐะฝัะฝ ะฒ ะฒะฐัะตะน ัั. ะทะฐะฟะธัะธ ะธ ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐะฝ ะฟะพ ัะผะพะปัะฐะฝะธั ะฟะพัะปะต ะฒั
ะพะดะฐ.
+language.localization_project = ะะพะผะพะณะธัะต ั ะฟะตัะตะฒะพะดะพะผ Forgejo ะฝะฐ ัะฒะพะน ัะทัะบ! ะะพะดัะพะฑะฝะตะต .
+user_block_yourself = ะะตะปัะทั ะทะฐะฑะปะพะบะธัะพะฒะฐัั ัะตะฑั.
+pronouns_custom_label = ะััะณะธะต ะผะตััะพะธะผะตะฝะธั
+change_username_redirect_prompt.with_cooldown.one = ะัะตะถะฝะตะต ะธะผั ะฑัะดะตั ะดะพัััะฟะฝะพ ะดะปั ะธัะฟะพะปัะทะพะฒะฐะฝะธั ะดััะณะธะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะฟะพัะปะต ะธััะตัะตะฝะธั ะทะฐัะธัั ะฒ %[1]d ะดะตะฝั. ะั ัะผะพะถะตัะต ะฒะตัะฝััั ะตะณะพ ัะตะฑะต ะฒะพ ะฒัะตะผั ััะพะบะฐ ะทะฐัะธัั.
+change_username_redirect_prompt.with_cooldown.few = ะัะตะถะฝะตะต ะธะผั ะฑัะดะตั ะดะพัััะฟะฝะพ ะดะปั ะธัะฟะพะปัะทะพะฒะฐะฝะธั ะดััะณะธะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะฟะพัะปะต ะธััะตัะตะฝะธั ะทะฐัะธัั ะฒ %[1]d ะดะฝะตะน. ะั ัะผะพะถะตัะต ะฒะตัะฝััั ะตะณะพ ัะตะฑะต ะฒะพ ะฒัะตะผั ััะพะบะฐ ะทะฐัะธัั.
+keep_pronouns_private = ะะพะบะฐะทัะฒะฐัั ะผะตััะพะธะผะตะฝะธั ัะพะปัะบะพ ะทะฐัะตะณะธัััะธัะพะฒะฐะฝะฝัะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ
+keep_pronouns_private.description = ะะตััะพะธะผะตะฝะธั ะฑัะดัั ัะบัััั ะพั ะฟะพะปัะทะพะฒะฐัะตะปะตะน, ะฝะต ะธะผะตััะธั
ััััะฝัั
ะทะฐะฟะธัะตะน ะฝะฐ ัะตัะฒะตัะต.
+quota.applies_to_user = ะญัะธ ะพะณัะฐะฝะธัะตะฝะธั ั
ัะฐะฝะธะปะธัะฐ ะฟัะธะผะตะฝััััั ะบ ะฒะฐัะตะน ััััะฝะพะน ะทะฐะฟะธัะธ
+quota.applies_to_org = ะญัะธ ะพะณัะฐะฝะธัะตะฝะธั ั
ัะฐะฝะธะปะธัะฐ ะฟัะธะผะตะฝััััั ะบ ััะพะน ะพัะณะฐะฝะธะทะฐัะธะธ
+quota.sizes.repos.public = ะะฑัะตะดะพัััะฟะฝัะต ัะตะฟะพะทะธัะพัะธะธ
+storage_overview = ะัะฟะพะปัะทะพะฒะฐะฝะธะต ะผะตััะฐ
+quota = ะะณัะฐะฝะธัะตะฝะธั ั
ัะฐะฝะธะปะธัะฐ
+quota.rule.exceeded = ะัะตะฒััะตะฝะพ
+quota.rule.exceeded.helper = ะกัะผะผะฐัะฝัะน ะพะฑััะผ ะพะฑัะตะบัะพะฒ ะฒ ััะพะผ ะฟัะฐะฒะธะปะต ะฟัะตะฒััะธะป ะดะพะฟัััะธะผัะน.
+quota.rule.no_limit = ะะตะพะณัะฐะฝะธัะตะฝะฝะพ
+quota.sizes.all = ะัั
+quota.sizes.repos.all = ะ ะตะฟะพะทะธัะพัะธะธ
+quota.sizes.repos.private = ะงะฐััะฝัะต ัะตะฟะพะทะธัะพัะธะธ
+quota.sizes.git.all = ะกะพะดะตัะถะธะผะพะต Git
+quota.sizes.git.lfs = Git LFS
+quota.sizes.wiki = ะะธะบะธ
+quota.sizes.assets.packages.all = ะะฐะบะตัั
+quota.sizes.assets.all = ะะฑัะตะบัั
+quota.sizes.assets.attachments.all = ะัะต ะฟัะธะบัะตะฟะปัะฝะฝัะต ัะฐะนะปั
+quota.sizes.assets.attachments.releases = ะคะฐะนะปั ะฒัะฟััะบะพะฒ
+quota.sizes.assets.attachments.issues = ะคะฐะนะปั ะทะฐะดะฐั
+quota.sizes.assets.artifacts = ะััะตัะฐะบัั
+regenerate_token = ะะฐะผะตะฝะธัั
+access_token_regeneration_desc = ะัะดะตั ัะพะทะดะฐะฝ ะฝะพะฒัะน ัะพะบะตะฝ, ะฟัะตะดัะดััะธะน ะฑัะดะตั ะพัะพะทะฒะฐะฝ. ะะฐะผ ะฟะพััะตะฑัะตััั ะทะฐะผะตะฝะธัั ัะพะบะตะฝ ะฒ ะฟัะธะปะพะถะตะฝะธัั
, ะธัะฟะพะปัะทัััะธั
ะตะณะพ. ะญัะพ ะดะตะนััะฒะธะต ะฝะตะปัะทั ะพัะผะตะฝะธัั. ะัะพะดะพะปะถะธัั?
+regenerate_token_success = ะขะพะบะตะฝ ะฑัะป ะทะฐะผะตะฝัะฝ. ะัะธะปะพะถะตะฝะธั, ะธัะฟะพะปัะทัััะธะต ะตะณะพ, ะฑะพะปะตะต ะฝะต ะธะผะตัั ะดะพัััะฟะฐ ะบ ััะพะน ััััะฝะพะน ะทะฐะฟะธัะธ ะธ ะดะพะปะถะฝั ะฟะพะปััะธัั ะฝะพะฒัะน ัะพะบะตะฝ.
+access_token_regeneration = ะะฐะผะตะฝะฐ ัะพะบะตะฝะฐ ะดะพัััะฟะฐ
[repo]
owner=ะะปะฐะดะตะปะตั
@@ -1021,12 +1100,12 @@ repo_name_helper=ะัััะธะต ะฝะฐะทะฒะฐะฝะธั ัะตะฟะพะทะธัะพัะธะตะฒ ัะพัั
repo_size=ะ ะฐะทะผะตั ัะตะฟะพะทะธัะพัะธั
size_format = `%[1]s: %[2]s; %[3]s: %[4]s`
template=ะจะฐะฑะปะพะฝ
-template_select=ะัะฑัะฐัั ัะฐะฑะปะพะฝ.
-template_helper=ะกะดะตะปะฐัั ัะตะฟะพะทะธัะพัะธะน ัะฐะฑะปะพะฝะพะผ
+template_select=ะัะฑะตัะธัะต ัะฐะฑะปะพะฝ
+template_helper=ะะพะผะตัะธัั ัะตะฟะพะทะธัะพัะธะน ะบะฐะบ ัะฐะฑะปะพะฝ
template_description=ะจะฐะฑะปะพะฝะฝัะต ัะตะฟะพะทะธัะพัะธะธ ะดะฐัั ะฒะพะทะผะพะถะฝะพััั ะฟะพะปัะทะพะฒะฐัะตะปัะผ ัะพะทะดะฐะฒะฐัั ะฝะพะฒัะต ัะตะฟะพะทะธัะพัะธะธ ั ัะพะน ะถะต ััััะบัััะพะน ะบะฐัะฐะปะพะณะพะฒ, ัะฐะนะปะฐะผะธ ะธ ะดะพะฟะพะปะฝะธัะตะปัะฝัะผะธ ะฝะฐัััะพะนะบะฐะผะธ.
visibility=ะะธะดะธะผะพััั
-visibility_description=ะญัะพ ัะฒะธะดัั ัะพะปัะบะพ ะฒะปะฐะดะตะปะตั ะพัะณะฐะฝะธะทะฐัะธะธ ะธะปะธ ััะฐััะฝะธะบะธ ะฟัะธ ะฝะฐะปะธัะธะธ ะฟัะฐะฒ.
-visibility_helper=ะกะดะตะปะฐัั ัะตะฟะพะทะธัะพัะธะน ะฟัะธะฒะฐัะฝัะผ
+visibility_description=ะะฝ ะฑัะดะตั ะฒะธะดะธะผ ัะพะปัะบะพ ะฒะปะฐะดะตะปััั ะพัะณะฐะฝะธะทะฐัะธะธ ะธ ะตั ััะฐััะฝะธะบะฐะผ ะฟัะธ ะฝะฐะปะธัะธะธ ะฟัะฐะฒ.
+visibility_helper=ะงะฐััะฝัะน ัะตะฟะพะทะธัะพัะธะน
visibility_helper_forced=ะะดะผะธะฝะธัััะฐัะพั ัะฐะนัะฐ ะฝะฐัััะพะธะป ะฟะฐัะฐะผะตัั ะฒะธะดะธะผะพััะธ ะฝะพะฒัั
ัะตะฟะพะทะธัะพัะธะตะฒ. ะ ะตะฟะพะทะธัะพัะธะน ะฟัะธะฒะฐัะฝัะน ะฟะพ ัะผะพะปัะฐะฝะธั.
visibility_fork_helper=(ะญัะพ ะธะทะผะตะฝะธั ะฒะธะดะธะผะพััั ะฒัะตั
ะพัะฒะตัะฒะปะตะฝะธะน.)
clone_helper=ะัะถะฝะฐ ะฟะพะผะพัั ะฒ ะบะปะพะฝะธัะพะฒะฐะฝะธะธ? ะะพัะตัะธัะต ัััะฐะฝะธัั ะฟะพะผะพัะธ .
@@ -1035,8 +1114,8 @@ fork_from=ะัะฒะตัะฒะธัั ะพั
already_forked=ะฃ ะฒะฐั ัะถะต ะตััั ะพัะฒะตัะฒะปะตะฝะธะต %s
fork_to_different_account=ะัะฒะตัะฒะปะตะฝะธะต ะดะปั ะดััะณะพะน ััััะฝะพะน ะทะฐะฟะธัะธ
fork_visibility_helper=ะะตะปัะทั ะธะทะผะตะฝะธัั ะฒะธะดะธะผะพััั ะพัะฒะตัะฒะปัะฝะฝะพะณะพ ัะตะฟะพะทะธัะพัะธั.
-fork_branch=ะะตัะบะฐ, ะบะปะพะฝะธััะตะผะฐั ะฒ ะพัะฒะตัะฒะปะตะฝะธะต
-all_branches=ะัะต ะฒะตัะบะธ
+fork_branch=ะะตัะฒั, ะบะปะพะฝะธััะตะผะฐั ะฒ ะพัะฒะตัะฒะปะตะฝะธะต
+all_branches=ะัะต ะฒะตัะฒะธ
use_template=ะัะฟะพะปัะทะพะฒะฐัั ััะพั ัะฐะฑะปะพะฝ
clone_in_vsc=ะะปะพะฝะธัะพะฒะฐัั ะฒ VS Code
download_zip=ะกะบะฐัะฐัั ZIP
@@ -1047,26 +1126,26 @@ generate_from=ะกะพะทะดะฐัั ะธะท
repo_desc=ะะฟะธัะฐะฝะธะต
repo_desc_helper=ะะพะฑะฐะฒััะต ะบัะฐัะบะพะต ะพะฟะธัะฐะฝะธะต (ะฝะตะพะฑัะทะฐัะตะปัะฝะพ)
repo_lang=ะฏะทัะบ
-repo_gitignore_helper=ะัะฑะตัะธัะต ัะฐะฑะปะพะฝ .gitignore.
-repo_gitignore_helper_desc=ะัะฑะตัะธัะต ะธะท ัะฟะธัะบะฐ ัะฐะฑะปะพะฝะพะฒ ะดะปั ะฟะพะฟัะปััะฝัั
ัะทัะบะพะฒ , ะบะฐะบะธะต ัะฐะนะปั ะฝะต ะฝะฐะดะพ ะพััะปะตะถะธะฒะฐัั. ะะพ ัะผะพะปัะฐะฝะธั ะฒ .gitignore ะฒะบะปััะตะฝั ัะธะฟะธัะฝัะต ะฐััะตัะฐะบัั, ัะพะทะดะฐะฒะฐะตะผัะต ะธะฝััััะผะตะฝัะฐะผะธ ัะฑะพัะบะธ ะบะฐะถะดะพะณะพ ัะทัะบะฐ.
-issue_labels=ะะตัะบะธ ะทะฐะดะฐั
-issue_labels_helper=ะัะฑะตัะธัะต ะฝะฐะฑะพั ััะปัะบะพะฒ ะทะฐะดะฐัะธ.
+repo_gitignore_helper=ะัะฑะตัะธัะต ัะฐะฑะปะพะฝั .gitignore
+repo_gitignore_helper_desc=ะัะฑะตัะธัะต ัะฐะฑะปะพะฝั ะธะท ัะฟะธัะบะฐ ะดะปั ะฟะพะฟัะปััะฝัั
ัะทัะบะพะฒ. .gitignore ะพะฟัะตะดะตะปัะตั, ะบะฐะบะธะต ัะฐะนะปั ะฝะต ะฝะฐะดะพ ะพััะปะตะถะธะฒะฐัั ะฒ ะฟัะพะตะบัะต. ะะพ ัะผะพะปัะฐะฝะธั ะฒ ะฝะตะณะพ ะฒะบะปััะตะฝั ัะธะฟะธัะฝัะต ะฐััะตัะฐะบัั, ัะพะทะดะฐะฒะฐะตะผัะต ะธะฝััััะผะตะฝัะฐะผะธ ัะฑะพัะบะธ ะบะฐะถะดะพะณะพ ัะทัะบะฐ.
+issue_labels=ะะตัะบะธ
+issue_labels_helper=ะัะฑะตัะธัะต ะฝะฐะฑะพั ะผะตัะพะบ
license=ะะธัะตะฝะทะธั
-license_helper=ะัะฑะตัะธัะต ัะฐะนะป ะปะธัะตะฝะทะธะธ.
-license_helper_desc=ะะธัะตะฝะทะธั ะพะฟัะตะดะตะปัะตั, ััะพ ะดััะณะธะต ะปัะดะธ ะผะพะณัั, ะฐ ััะพ ะฝะต ะผะพะณัั ะดะตะปะฐัั ั ะฒะฐัะธะผ ะบะพะดะพะผ. ะะต ัะฒะตัะตะฝั, ะบะฐะบะฐั ะปะธัะตะฝะทะธั ะฟะพะดั
ะพะดะธั ะดะปั ะฒะฐัะตะณะพ ะฟัะพะตะบัะฐ? ะกะผะพััะธัะต ะัะฑะตัะธัะต ะปะธัะตะฝะทะธั.
+license_helper=ะัะฑะตัะธัะต ะปะธัะตะฝะทะธั
+license_helper_desc=ะะธัะตะฝะทะธั ะพะฟัะตะดะตะปัะตั, ััะพ ะดััะณะธะต ะผะพะณัั ะธ ะฝะต ะผะพะณัั ะดะตะปะฐัั ั ะฒะฐัะธะผ ะบะพะดะพะผ. ะะต ะทะฝะฐะตัะต, ะบะฐะบะฐั ะปะธัะตะฝะทะธั ะฟะพะดะพะนะดัั ะดะปั ะฒะฐัะตะณะพ ะฟัะพะตะบัะฐ? ะะทะฝะฐะบะพะผััะตัั ั ะัะฑะพัะพะผ ะปะธัะตะฝะทะธะธ .
readme=README
-readme_helper=ะัะฑะตัะธัะต ัะฐะฑะปะพะฝ README.
+readme_helper=ะัะฑะตัะธัะต ัะฐะฑะปะพะฝ README
readme_helper_desc=ะญัะพ ะผะตััะพ, ะณะดะต ะฒั ะผะพะถะตัะต ะฝะฐะฟะธัะฐัั ะฟะพะดัะพะฑะฝะพะต ะพะฟะธัะฐะฝะธะต ะฒะฐัะตะณะพ ะฟัะพะตะบัะฐ.
-auto_init=ะะฝะธัะธะฐะปะธะทะธัะพะฒะฐัั ัะตะฟะพะทะธัะพัะธะน (ะะพะฑะฐะฒะปัะตั .gitignore, LICENSE and README)
+auto_init=ะะฝะธัะธะฐะปะธะทะธัะพะฒะฐัั ัะตะฟะพะทะธัะพัะธะน
trust_model_helper=ะัะฑะตัะธัะต ะผะพะดะตะปั ะดะพะฒะตัะธั ะดะปั ะฟัะพะฒะตัะบะธ ะฟะพะดะฟะธัะธ. ะะพะทะผะพะถะฝัะต ะฒะฐัะธะฐะฝัั:
trust_model_helper_collaborator=ะกะพััะฐััะฝะธะบ: ะดะพะฒะตัััั ะฟะพะดะฟะธััะผ ัะพััะฐััะฝะธะบะพะฒ
trust_model_helper_committer=ะะฒัะพั ะบะพะผะผะธัะฐ: ะดะพะฒะตัััั ะฟะพะดะฟะธััะผ, ัะพะพัะฒะตัััะฒัััะธะผ ะฐะฒัะพัะฐะผ ะบะพะผะผะธัะพะฒ
trust_model_helper_collaborator_committer=ะกะพััะฐััะฝะธะบ+ะะพะผะผะธัะตั: ะดะพะฒะตัััั ะฟะพะดะฟะธััะผ ัะพััะฐััะฝะธะบะพะฒ, ะบะพัะพััะต ัะพะพัะฒะตัััะฒััั ะฐะฒัะพัั ะบะพะผะผะธัะฐ
trust_model_helper_default=ะะพ ัะผะพะปัะฐะฝะธั: ะธัะฟะพะปัะทัะนัะต ะผะพะดะตะปั ะดะพะฒะตัะธั ะฟะพ ัะผะพะปัะฐะฝะธั ะดะปั ััะพะน ัััะฐะฝะพะฒะบะธ
create_repo=ะกะพะทะดะฐัั ัะตะฟะพะทะธัะพัะธะน
-default_branch=ะะตัะบะฐ ะฟะพ ัะผะพะปัะฐะฝะธั
+default_branch=ะะตัะฒั ะฟะพ ัะผะพะปัะฐะฝะธั
default_branch_label=ะฟะพ ัะผะพะปัะฐะฝะธั
-default_branch_helper=ะะตัะบะฐ ะฟะพ ัะผะพะปัะฐะฝะธั ัะฒะปัะตััั ะฑะฐะทะพะฒะพะน ะฒะตัะบะพะน ะดะปั ะทะฐะฟัะพัะพะฒ ะฝะฐ ัะปะธัะฝะธะต ะธ ะบะพะผะผะธัะพะฒ ะบะพะดะฐ.
+default_branch_helper=ะะตัะฒั ะฟะพ ัะผะพะปัะฐะฝะธั ัะฒะปัะตััั ะฑะฐะทะพะฒะพะน ะฒะตัะฒัั ะดะปั ะทะฐะฟัะพัะพะฒ ะฝะฐ ัะปะธัะฝะธะต ะธ ะบะพะผะผะธัะพะฒ ะบะพะดะฐ.
mirror_prune=ะัะธััะธัั
mirror_prune_desc=ะฃะดะฐะปะตะฝะธะต ัััะฐัะตะฒัะธั
ะพััะปะตะถะธะฒะฐะตะผัั
ัััะปะพะบ
mirror_interval=ะะฝัะตัะฒะฐะป ะทะตัะบะฐะปะธัะพะฒะฐะฝะธั (ะตะดะธะฝะธัั ะฒัะตะผะตะฝะธ: ยซhยป, ยซmยป, ยซsยป). ะะฝะฐัะตะฝะธะต 0 ะพัะบะปััะธั ะฟะตัะธะพะดะธัะตัะบัั ัะธะฝั
ัะพะฝะธะทะฐัะธั. (ะะธะฝ. ะธะฝัะตัะฒะฐะป: %s)
@@ -1089,7 +1168,7 @@ forks=ะัะฒะตัะฒะปะตะฝะธั
reactions_more=ะธ ะตัั %d
unit_disabled=ะะดะผะธะฝะธัััะฐัะพั ัะฐะนัะฐ ะพัะบะปััะธะป ััะพั ัะฐะทะดะตะป ัะตะฟะพะทะธัะพัะธั.
language_other=ะ ะฐะทะฝะพะต
-adopt_search=ะะฒะตะดะธัะต ะธะผั ะฟะพะปัะทะพะฒะฐัะตะปั ะดะปั ะฟะพะธัะบะฐ ะฝะตััะฒะตัะถะดัะฝะฝัั
ัะตะฟะพะทะธัะพัะธะตะฒ... (ะพััะฐะฒััะต ะฟััััะผ, ััะพะฑั ะฝะฐะนัะธ ะฒัะต)
+adopt_search=ะะฒะตะดะธัะต ะธะผั ะฟะพะปัะทะพะฒะฐัะตะปั ะดะปั ะฟะพะธัะบะฐ ะฝะตััะฒะตัะถะดัะฝะฝัั
ัะตะฟะพะทะธัะพัะธะตะฒโฆ (ะพััะฐะฒััะต ะฟััััะผ, ััะพะฑั ะฝะฐะนัะธ ะฒัะต)
adopt_preexisting_label=ะัะธะฝัััะต ัะฐะนะปั
adopt_preexisting=ะัะธะฝััั ัะถะต ัััะตััะฒัััะธะต ัะฐะนะปั
adopt_preexisting_content=ะกะพะทะดะฐัั ัะตะฟะพะทะธัะพัะธะน ะธะท %s
@@ -1102,14 +1181,14 @@ blame_prior=ะะพะบะฐะทะฐัั ะฐะฒัะพัััะฒะพ ะฟัะตะดัะตััะฒัััะธั
ะธ
author_search_tooltip=ะะพะบะฐะทัะฒะฐะตั ะผะฐะบัะธะผัะผ 30 ะฟะพะปัะทะพะฒะฐัะตะปะตะน
tree_path_not_found_commit=ะััั %[1]s ะฝะต ัััะตััะฒัะตั ะฒ ะบะพะผะผะธัะต %[2]s
-tree_path_not_found_branch=ะััั %[1]s ะฝะต ัััะตััะฒัะตั ะฒ ะฒะตัะบะต %[2]s
+tree_path_not_found_branch=ะััั %[1]s ะฝะต ัััะตััะฒัะตั ะฒ ะฒะตัะฒะธ %[2]s
transfer.accept=ะัะธะฝััั ะฟะตัะตะดะฐัั
transfer.accept_desc=ะะตัะตะผะตััะธัั ะฒ ยซ%sยป
transfer.reject=ะัะบะฐะทะฐัััั ะพั ะฟะตัะตะดะฐัะธ
transfer.reject_desc=ะัะผะตะฝะธัั ะฟะตัะตะผะตัะตะฝะธะต ะฒ ยซ%sยป
-desc.private=ะัะธะฒะฐัะฝัะน
+desc.private=ะงะฐััะฝัะน
desc.public=ะัะฑะปะธัะฝัะน
desc.template=ะจะฐะฑะปะพะฝ
desc.internal=ะะฝัััะตะฝะฝะธะน
@@ -1121,13 +1200,13 @@ template.git_hooks=Git-ั
ัะบะธ
template.git_hooks_tooltip=ะ ะฝะฐััะพััะตะต ะฒัะตะผั ะฒั ะฝะต ะผะพะถะตัะต ะธะทะผะตะฝะธัั ะธะปะธ ัะดะฐะปะธัั Git-ั
ัะบะธ ะฟะพัะปะต ะดะพะฑะฐะฒะปะตะฝะธั. ะัะฑะตัะธัะต ััะพ ัะพะปัะบะพ ะตัะปะธ ะฒั ะดะพะฒะตััะตัะต ัะตะฟะพะทะธัะพัะธั ัะฐะฑะปะพะฝะฐ.
template.webhooks=ะะตะฑ-ั
ัะบะธ
template.topics=ะขะตะผั
-template.avatar=ะะฒะฐัะฐั
+template.avatar=ะะฐััะธะฝะบะฐ
template.issue_labels=ะะตัะบะธ ะทะฐะดะฐั
template.one_item=ะะตะพะฑั
ะพะดะธะผะพ ะฒัะฑัะฐัั ั
ะพัั ะฑั ะพะดะธะฝ ัะปะตะผะตะฝั ัะฐะฑะปะพะฝะฐ
template.invalid=ะะตะพะฑั
ะพะดะธะผะพ ะฒัะฑัะฐัั ัะฐะฑะปะพะฝ ัะตะฟะพะทะธัะพัะธั
-archive.issue.nocomment=ะญัะพั ัะตะฟะพะทะธัะพัะธะน ะฒ ะฐัั
ะธะฒะต. ะั ะฝะต ะผะพะถะตัะต ะบะพะผะผะตะฝัะธัะพะฒะฐัั ะทะฐะดะฐัะธ.
-archive.pull.nocomment=ะญัะพ ัะตะฟะพะทะธัะพัะธะน ะฒ ะฐัั
ะธะฒะต. ะั ะฝะต ะผะพะถะตัะต ะบะพะผะผะตะฝัะธัะพะฒะฐัั ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต.
+archive.issue.nocomment=ะญัะพั ัะตะฟะพะทะธัะพัะธะน ะฐัั
ะธะฒะธัะพะฒะฐะฝ. ะะพะผะผะตะฝัะธัะพะฒะฐะฝะธะต ะฒ ะทะฐะดะฐัะฐั
ะฝะตะฒะพะทะผะพะถะฝะพ.
+archive.pull.nocomment=ะญัะพั ัะตะฟะพะทะธัะพัะธะน ะฐัั
ะธะฒะธัะพะฒะฐะฝ. ะะพะผะผะตะฝัะธัะพะฒะฐะฝะธะต ะฒ ะทะฐะฟัะพัะฐั
ัะปะธัะฝะธะน ะฝะตะฒะพะทะผะพะถะฝะพ.
form.reach_limit_of_creation_1=ะะพััะธะณะฝััะพ ะพะณัะฐะฝะธัะตะฝะธะต ะฝะฐ ะบะพะปะธัะตััะฒะพ ัะตะฟะพะทะธัะพัะธะตะฒ: %d.
form.reach_limit_of_creation_n=ะะพััะธะณะฝััะพ ะพะณัะฐะฝะธัะตะฝะธะต ะฝะฐ ะบะพะปะธัะตััะฒะพ ัะตะฟะพะทะธัะพัะธะตะฒ: %d.
@@ -1153,7 +1232,7 @@ migrate_items_releases=ะัะฟััะบะธ
migrate_repo=ะะตัะตะฝะพั ัะตะฟะพะทะธัะพัะธั
migrate.clone_address=ะะตัะตะฝะพั / ะะปะพะฝะธัะพะฒะฐะฝะธะต ะฟะพ URL
migrate.clone_address_desc=HTTP/HTTPS ะธะปะธ Git ะฐะดัะตั ัััะตััะฒัััะตะณะพ ัะตะฟะพะทะธัะพัะธั
-migrate.github_token_desc=ะั ะผะพะถะตัะต ะฟะพะผะตััะธัั ะพะดะธะฝ ะธะปะธ ะฝะตัะบะพะปัะบะพ ัะพะบะตะฝะพะฒ, ัะฐะทะดะตะปะตะฝะฝัั
ะทะฐะฟัััะผะธ, ััะพะฑั ััะบะพัะธัั ะผะธะณัะฐัะธั, ะพะฑั
ะพะดะพะผ ะพะณัะฐะฝะธัะตะฝะธะน ัะบะพัะพััะธ API GitHub. ะะ ะะะฃะะ ะะะะะะะ: ะทะปะพัะฟะพััะตะฑะปะตะฝะธะต ััะพะน ััะฝะบัะธะตะน ะผะพะถะตั ะฝะฐัััะธัั ะฟะพะปะธัะธะบั ะฟะพััะฐะฒัะธะบะฐ ััะปัะณ ะธ ะฟัะธะฒะตััะธ ะบ ะฑะปะพะบะธัะพะฒะบะต ััััะฝะพะน ะทะฐะฟะธัะธ.
+migrate.github_token_desc=ะั ะผะพะถะตัะต ัะบะฐะทะฐัั ะพะดะธะฝ ะธะปะธ ะฝะตัะบะพะปัะบะพ ัะฐะทะดะตะปะตะฝะฝัั
ะทะฐะฟัััะผะธ ัะพะบะตะฝะพะฒ, ััะพะฑั ััะบะพัะธัั ะฟะตัะตะฝะพั ะทะฐ ัััั ะพะฑั
ะพะดะฐ ะพะณัะฐะฝะธัะตะฝะธะน ัะฐััะพัั ะพะฑัะฐัะตะฝะธะน ะบ API GitHub. ะะ ะะะฃะะ ะะะะะะะ: ะทะปะพัะฟะพััะตะฑะปะตะฝะธะต ััะพะน ััะฝะบัะธะตะน ะผะพะถะตั ะฝะฐัััะธัั ััะปะพะฒะธั ะฟัะตะดะพััะฐะฒะปะตะฝะธั ััะปัะณ ะธ ะฟัะธะฒะตััะธ ะบ ะฑะปะพะบะธัะพะฒะบะต ััััะฝะพะน ะทะฐะฟะธัะธ.
migrate.clone_local_path=ะธะปะธ ะปะพะบะฐะปัะฝัะน ะฟััั ะฝะฐ ัะตัะฒะตัะต
migrate.permission_denied=ะฃ ะฒะฐั ะฝะตั ะฟัะฐะฒ ะฝะฐ ะธะผะฟะพัั ะปะพะบะฐะปัะฝัั
ัะตะฟะพะทะธัะพัะธะตะฒ.
migrate.permission_denied_blocked=ะั ะฝะต ะผะพะถะตัะต ะธะผะฟะพััะธัะพะฒะฐัั ั ะทะฐะฟัะตััะฝะฝัั
ั
ะพััะพะฒ, ะฟะพะถะฐะปัะนััะฐ, ะฟะพะฟัะพัะธัะต ะฐะดะผะธะฝะธัััะฐัะพัะฐ ะฟัะพะฒะตัะธัั ะฝะฐัััะพะนะบะธ ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS.
@@ -1164,9 +1243,9 @@ migrate.migrate_items_options=ะขะพะบะตะฝ ะดะพัััะฟะฐ ะฝะตะพะฑั
ะพะดะธะผ ะดะป
migrated_from=ะะตัะตะฝะตัะตะฝะพ ะธะท %[2]s
migrated_from_fake=ะะตัะตะฝะตัะตะฝะพ ะธะท %[1]s
migrate.migrate=ะะตัะตะฝะพั ะธะท %s
-migrate.migrating=ะะตัะตะฝะพั ะธะท %s ...
+migrate.migrating=ะะตัะตะฝะพั ะธะท %s โฆ
migrate.migrating_failed=ะะตัะตะฝะพั ะธะท %s ะฝะต ัะดะฐะปัั.
-migrate.migrating_failed.error=ะะต ัะดะฐะปะพัั ะผะธะณัะธัะพะฒะฐัั: %s
+migrate.migrating_failed.error=ะะต ัะดะฐะปะพัั ะฟะตัะตะฝะตััะธ: %s
migrate.migrating_failed_no_addr=ะะตัะตะฝะพั ะฝะต ัะดะฐะปัั.
migrate.github.description=ะะตัะตะฝะตัะธัะต ะดะฐะฝะฝัะต ั github.com ะธะปะธ ัะตัะฒะตัะฐ GitHub Enterprise.
migrate.git.description=ะะตัะตะฝะตััะธ ัะพะปัะบะพ ัะตะฟะพะทะธัะพัะธะน ะธะท ะปัะฑะพะณะพ Git ัะตัะฒะธัะฐ.
@@ -1184,7 +1263,7 @@ migrate.migrating_releases=ะะตัะตะฝะพั ะฒัะฟััะบะพะฒ
migrate.migrating_issues=ะะตัะตะฝะพั ะทะฐะดะฐั
migrate.migrating_pulls=ะะตัะตะฝะพั ะทะฐะฟัะพัะพะฒ ะฝะฐ ัะปะธัะฝะธะต
migrate.cancel_migrating_title=ะัะผะตะฝะธัั ะฟะตัะตะฝะพั
-migrate.cancel_migrating_confirm=ะั ั
ะพัะธัะต ะพัะผะตะฝะธัั ััั ะผะธะณัะฐัะธั?
+migrate.cancel_migrating_confirm=ะั ั
ะพัะธัะต ะพัะผะตะฝะธัั ะฟะตัะตะฝะพั?
mirror_from=ะทะตัะบะฐะปะพ ะธะท
forked_from=ะพัะฒะตัะฒะปัะฝ ะพั
@@ -1211,13 +1290,13 @@ empty_message=ะ ัะตะฟะพะทะธัะพัะธะธ ะฝะตั ัะฐะนะปะพะฒ.
broken_message=ะะฐะฝะฝัะต Git, ะปะตะถะฐัะธะต ะฒ ะพัะฝะพะฒะต ัะตะฟะพะทะธัะพัะธั, ะฝะต ะผะพะณัั ะฑััั ะฟัะพัะธัะฐะฝั. ะกะฒัะถะธัะตัั ั ะฐะดะผะธะฝะธัััะฐัะพัะพะผ ััะพะณะพ ัะตััััะฐ ะธะปะธ ัะดะฐะปะธัะต ััะพั ัะตะฟะพะทะธัะพัะธะน.
code=ะะพะด
-code.desc=ะัั
ะพะดะฝัะน ะบะพะด, ัะฐะนะปั, ะบะพะผะผะธัั ะธ ะฒะตัะบะธ.
-branch=ะฒะตัะบะฐ
+code.desc=ะัั
ะพะดะฝัะน ะบะพะด, ัะฐะนะปั, ะบะพะผะผะธัั ะธ ะฒะตัะฒะธ.
+branch=ะฒะตัะฒั
tree=ะะตัะตะฒะพ
clear_ref=`ะฃะดะฐะปะธัั ัะตะบัััั ัััะปะบั`
-filter_branch_and_tag=ะคะธะปััั ะฟะพ ะฒะตัะบะต ะธะปะธ ัะตะณั
+filter_branch_and_tag=ะคะธะปััั ะฟะพ ะฒะตัะฒะธ ะธะปะธ ัะตะณั
find_tag=ะะฐะนัะธ ัะตะณ
-branches=ะฒะตัะบะธ
+branches=ะฒะตัะฒะธ
tags=ัะตะณะธ
issues=ะะฐะดะฐัะธ
pulls=ะกะปะธัะฝะธั
@@ -1257,16 +1336,17 @@ view_git_blame=ะะพะบะฐะทะฐัั git blame
video_not_supported_in_browser=ะะฐั ะฑัะฐัะทะตั ะฝะต ะฟะพะดะดะตัะถะธะฒะฐะตั ััะณ HTML5 ยซvideoยป.
audio_not_supported_in_browser=ะะฐั ะฑัะฐัะทะตั ะฝะต ะฟะพะดะดะตัะถะธะฒะฐะตั ััะณ HTML5 ยซaudioยป.
stored_lfs=ะฅัะฐะฝะธััั Git LFS
+stored_annex=ะฅัะฐะฝะธััั Git Annex
symbolic_link=ะกะธะผะฒะพะปะธัะตัะบะฐั ัััะปะบะฐ
executable_file=ะัะฟะพะปะฝัะตะผัะน ัะฐะนะป
commit_graph=ะัะฐั ะบะพะผะผะธัะพะฒ
-commit_graph.select=ะัะฑัะฐัั ะฒะตัะบั
+commit_graph.select=ะัะฑัะฐัั ะฒะตัะฒั
commit_graph.hide_pr_refs=ะกะบัััั ะทะฐะฟัะพัั ัะปะธัะฝะธะน
commit_graph.monochrome=ะะพะฝะพ
commit_graph.color=ะฆะฒะตั
commit.contained_in=ะญัะพั ะบะพะผะผะธั ัะพะดะตัะถะธััั ะฒ:
-commit.contained_in_default_branch=ะญัะพั ะบะพะผะผะธั ัะฒะปัะตััั ัะฐัััั ะฒะตัะบะธ ะฟะพ ัะผะพะปัะฐะฝะธั
-commit.load_referencing_branches_and_tags=ะะฐะณััะทะธัั ะฒะตัะบะธ ะธ ัะตะณะธ, ัััะปะฐััะธะตัั ะฝะฐ ััะพั ะบะพะผะผะธั
+commit.contained_in_default_branch=ะญัะพั ะบะพะผะผะธั ัะฒะปัะตััั ัะฐัััั ะฒะตัะฒะธ ะฟะพ ัะผะพะปัะฐะฝะธั
+commit.load_referencing_branches_and_tags=ะะฐะณััะทะธัั ะฒะตัะฒะธ ะธ ัะตะณะธ, ัััะปะฐััะธะตัั ะฝะฐ ััะพั ะบะพะผะผะธั
blame=ะะฒัะพัััะฒะพ
download_file=ะกะบะฐัะฐัั ัะฐะนะป
normal_view=ะะฑััะฝัะน ะฒะธะด
@@ -1280,10 +1360,11 @@ editor.upload_file=ะะฐะณััะทะธัั ัะฐะนะป
editor.edit_file=ะ ะตะดะฐะบัะธัะพะฒะฐัั ัะฐะนะป
editor.preview_changes=ะัะพัะผะพัั ะธะทะผะตะฝะตะฝะธะน
editor.cannot_edit_lfs_files=LFS ัะฐะนะปั ะฝะตะฒะพะทะผะพะถะฝะพ ัะตะดะฐะบัะธัะพะฒะฐัั ะฒ ะฒะตะฑ-ะธะฝัะตััะตะนัะต.
+editor.cannot_edit_annex_files=Annex ัะฐะนะปั ะฝะตะฒะพะทะผะพะถะฝะพ ัะตะดะฐะบัะธัะพะฒะฐัั ะฒ ะฒะตะฑ-ะธะฝัะตััะตะนัะต.
editor.cannot_edit_non_text_files=ะะฒะพะธัะฝัะต ัะฐะนะปั ะฝะตะปัะทั ัะตะดะฐะบัะธัะพะฒะฐัั ะฒ ะฒะตะฑ-ะธะฝัะตััะตะนัะต.
editor.edit_this_file=ะ ะตะดะฐะบัะธัะพะฒะฐัั ัะฐะนะป
editor.this_file_locked=ะคะฐะนะป ะทะฐะฑะปะพะบะธัะพะฒะฐะฝ
-editor.must_be_on_a_branch=ะงัะพะฑั ะฒะฝะตััะธ ะธะปะธ ะฟัะตะดะปะพะถะธัั ะธะทะผะตะฝะตะฝะธั ััะพะณะพ ัะฐะนะปะฐ, ะฝะตะพะฑั
ะพะดะธะผะพ ะฒัะฑัะฐัั ะฒะตัะบั.
+editor.must_be_on_a_branch=ะงัะพะฑั ะฒะฝะตััะธ ะธะปะธ ะฟัะตะดะปะพะถะธัั ะธะทะผะตะฝะตะฝะธั ััะพะณะพ ัะฐะนะปะฐ, ะฝะตะพะฑั
ะพะดะธะผะพ ะฒัะฑัะฐัั ะฒะตัะฒั.
editor.fork_before_edit=ะะตะพะฑั
ะพะดะธะผะพ ัะดะตะปะฐัั ะพัะฒะตัะฒะปะตะฝะธะต ััะพะณะพ ัะตะฟะพะทะธัะพัะธั, ััะพะฑั ะฒะฝะตััะธ ะธะปะธ ะฟัะตะดะปะพะถะธัั ะธะทะผะตะฝะตะฝะธั ััะพะณะพ ัะฐะนะปะฐ.
editor.delete_this_file=ะฃะดะฐะปะธัั ัะฐะนะป
editor.must_have_write_access=ะะฐะผ ะฝะตะพะฑั
ะพะดะธะผะพ ะธะผะตัั ะฟัะฐะฒะฐ ะฝะฐ ะทะฐะฟะธัั, ััะพะฑั ะฒะฝะพัะธัั ะธะปะธ ะฟัะตะดะปะฐะณะฐัั ะธะทะผะตะฝะตะฝะธั ััะพะณะพ ัะฐะนะปะฐ.
@@ -1294,34 +1375,34 @@ editor.or=ะธะปะธ
editor.cancel_lower=ะัะผะตะฝะธัั
editor.commit_signed_changes=ะะฐัะธะบัะธัะพะฒะฐัั ะฟะพะดะฟะธัะฐะฝะฝัะต ะธะทะผะตะฝะตะฝะธั
editor.commit_changes=ะกะพั
ัะฐะฝะธัั ะฟัะฐะฒะบะธ
-editor.add_tmpl=ะะพะฑะฐะฒะธัั ยซยป
+editor.add_tmpl=ะะพะฑะฐะฒะธัั ยซ<%s>ยป
editor.add=ะะพะฑะฐะฒะธัั %s
editor.update=ะะฑะฝะพะฒะธัั %s
editor.delete=ะฃะดะฐะปะธัั %s
-editor.patch=ะัะธะผะตะฝะธัั ะฟะฐัั
+editor.patch=ะัะธะผะตะฝะธัั ะฟัะฐะฒะบั
editor.patching=ะัะฟัะฐะฒะปะตะฝะธะต:
editor.fail_to_apply_patch=ะะตะฒะพะทะผะพะถะฝะพ ะฟัะธะผะตะฝะธัั ะฟะฐัั ยซ%sยป
-editor.new_patch=ะะพะฒัะน ะฟะฐัั
+editor.new_patch=ะะพะฒะฐั ะฟัะฐะฒะบะฐ
editor.commit_message_desc=ะะพะฑะฐะฒััะต ะฝะตะพะฑัะทะฐัะตะปัะฝะพะต ัะฐััะธัะตะฝะฝะพะต ะพะฟะธัะฐะฝะธะตโฆ
editor.signoff_desc=ะะพะฑะฐะฒะธัั ััะตะนะปะตั Signed-off-by ั ะฐะฒัะพัะพะผ ะบะพะผะผะธัะฐ ะฒ ะบะพะฝัะต ัะพะพะฑัะตะฝะธั ะบะพะผะผะธัะฐ.
-editor.commit_directly_to_this_branch=ะกะดะตะปะฐะนัะต ะบะพะผะผะธั ะฝะฐะฟััะผัั ะฒ ะฒะตัะบั %s .
-editor.create_new_branch=ะกะพะทะดะฐะนัะต ะฝะพะฒัั ะฒะตัะบั ะดะปั ััะพะณะพ ะบะพะผะผะธัะฐ, ะธ ัะดะตะปะฐะนัะต ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต.
-editor.create_new_branch_np=ะกะพะทะดะฐัั ะฝะพะฒัั ะฒะตัะบั ะดะปั ััะพะณะพ ะบะพะผะผะธัะฐ.
+editor.commit_directly_to_this_branch=ะกะพั
ัะฐะฝะธัั ะบะพะผะผะธั ะฝะฐะฟััะผัั ะฒ ะฒะตัะฒั %[1]s .
+editor.create_new_branch=ะกะพั
ัะฐะฝะธัั ะบะพะผะผะธั ะฒ ะฝะพะฒัั ะฒะตัะฒั ะธ ะฝะฐัะฐัั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต.
+editor.create_new_branch_np=ะกะพะทะดะฐัั ะฝะพะฒัั ะฒะตัะฒั ะดะปั ััะพะณะพ ะบะพะผะผะธัะฐ.
editor.propose_file_change=ะัะตะดะปะพะถะธัั ะธะทะผะตะฝะตะฝะธะต ัะฐะนะปะฐ
-editor.new_branch_name=ะฃะบะฐะถะธัะต ะฝะฐะทะฒะฐะฝะธะต ะฝะพะฒะพะน ะฒะตัะบะธ ะดะปั ััะพะณะพ ะบะพะผะผะธัะฐ
-editor.new_branch_name_desc=ะะพะฒะพะต ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะบะธโฆ
+editor.new_branch_name=ะฃะบะฐะถะธัะต ะฝะฐะทะฒะฐะฝะธะต ะฝะพะฒะพะน ะฒะตัะฒะธ ะดะปั ััะพะณะพ ะบะพะผะผะธัะฐ
+editor.new_branch_name_desc=ะะพะฒะพะต ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธโฆ
editor.cancel=ะัะผะตะฝะฐ
editor.filename_cannot_be_empty=ะะผั ัะฐะนะปะฐ ะฝะต ะผะพะถะตั ะฑััั ะฟััััะผ.
editor.filename_is_invalid=ะะตะดะพะฟัััะธะผะพะต ะธะผั ัะฐะนะปะฐ: ยซ%sยป.
-editor.branch_does_not_exist=ะะตัะบะฐ ยซ%sยป ะพััััััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
-editor.branch_already_exists=ะะตัะบะฐ ยซ%sยป ัะถะต ัััะตััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
+editor.branch_does_not_exist=ะะตัะฒั ยซ%sยป ะพััััััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
+editor.branch_already_exists=ะะตัะฒั ยซ%sยป ัะถะต ัััะตััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
editor.directory_is_a_file=ะะผั ะบะฐัะฐะปะพะณะฐ ยซ%sยป ัะถะต ะธัะฟะพะปัะทัะตััั ะฒ ะบะฐัะตััะฒะต ะธะผะตะฝะธ ัะฐะนะปะฐ ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
editor.file_is_a_symlink=`ยซ%sยป ัะฒะปัะตััั ัะธะผะฒะพะปะธัะตัะบะพะน ัััะปะบะพะน. ะกะธะผะฒะพะปะธัะตัะบะธะต ัััะปะบะธ ะฝะตะฒะพะทะผะพะถะฝะพ ะพััะตะดะฐะบัะธัะพะฒะฐัั ะฒ ะฒะตะฑ-ัะตะดะฐะบัะพัะต`
editor.filename_is_a_directory=ะะผั ัะฐะนะปะฐ ยซ%sยป ัะถะต ะธัะฟะพะปัะทัะตััั ะฒ ะบะฐัะตััะฒะต ะบะฐัะฐะปะพะณะฐ ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
editor.file_editing_no_longer_exists=ะ ะตะดะฐะบัะธััะตะผัะน ัะฐะนะป ยซ%sยป ะฑะพะปััะต ะฝะต ัััะตััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
editor.file_deleting_no_longer_exists=ะฃะดะฐะปัะตะผัะน ัะฐะนะป ยซ%sยป ะฑะพะปััะต ะฝะต ัััะตััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
-editor.file_changed_while_editing=ะกะพะดะตัะถะธะผะพะต ัะฐะนะปะฐ ะธะทะผะตะฝะธะปะพัั ั ะผะพะผะตะฝัะฐ ะฝะฐัะฐะปะฐ ัะตะดะฐะบัะธัะพะฒะฐะฝะธั. ะะฐะถะผะธัะต ะทะดะตัั , ััะพะฑั ัะฒะธะดะตัั, ััะพ ะฑัะปะพ ะธะทะผะตะฝะตะฝะพ, ะธะปะธ ะะฐัะธะบัะธัะพะฒะฐัั ะธะทะผะตะฝะตะฝะธั ัะฝะพะฒะฐ , ััะพะฑั ะทะฐะผะตะฝะธัั ะธั
.
-editor.file_already_exists=ะคะฐะนะป ยซ%sยป ัะถะต ัััะตััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
+editor.file_changed_while_editing=ะกะพะดะตัะถะธะผะพะต ัะฐะนะปะฐ ะธะทะผะตะฝะธะปะพัั ะฟะพัะปะต ัะพะณะพ, ะบะฐะบ ะพะฝ ะฑัะป ะพัะบััั. ะะทะฝะฐะบะพะผััะตัั ั ะฟัะพะธะทะพัะตะดัะธะผะธ ะธะทะผะตะฝะตะฝะธัะผะธ ะธะปะธ ัะพั
ัะฐะฝะธัะต ะตัั ัะฐะท , ััะพะฑั ะฟะตัะตะทะฐะฟะธัะฐัั ะธั
.
+editor.file_already_exists=ะคะฐะนะป ั ะฝะฐะทะฒะฐะฝะธะตะผ ยซ%sยป ัะถะต ัััะตััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
editor.commit_empty_file_header=ะะฐะบะพะผะผะธัะธัั ะฟัััะพะน ัะฐะนะป
editor.commit_empty_file_text=ะคะฐะนะป, ะบะพัะพััะน ะฒั ัะพะฑะธัะฐะตัะตัั ะทะฐัะธะบัะธัะพะฒะฐัั, ะฟััั. ะัะพะดะพะปะถะธัั?
editor.no_changes_to_show=ะะตั ะธะทะผะตะฝะตะฝะธะน.
@@ -1329,26 +1410,26 @@ editor.fail_to_update_file=ะะต ัะดะฐะปะพัั ะพะฑะฝะพะฒะธัั/ัะพะทะดะฐัั
editor.fail_to_update_file_summary=ะัะธะฑะบะฐ:
editor.push_rejected_no_message=ะะทะผะตะฝะตะฝะธะต ะพัะบะปะพะฝะตะฝะพ ัะตัะฒะตัะพะผ ะฑะตะท ัะพะพะฑัะตะฝะธั. ะะพะถะฐะปัะนััะฐ, ะฟัะพะฒะตัััะต Git-ั
ัะบะธ.
editor.push_rejected=ะะทะผะตะฝะตะฝะธะต ะพัะบะปะพะฝะตะฝะพ ัะตัะฒะตัะพะผ. ะะพะถะฐะปัะนััะฐ, ะฟัะพะฒะตัััะต Git-ั
ัะบะธ.
-editor.push_rejected_summary=ะะพะปะฝะพะต ัะพะพะฑัะตะฝะธะต ะพะฑ ะพัะบะปะพะฝะตะฝะธะธ:
+editor.push_rejected_summary=ะัะธัะธะฝะฐ ะพัะบะปะพะฝะตะฝะธั:
editor.add_subdir=ะะพะฑะฐะฒะธัั ะบะฐัะฐะปะพะณโฆ
editor.unable_to_upload_files=ะะต ัะดะฐะปะพัั ะทะฐะณััะทะธัั ัะฐะนะปั ะฒ ยซ%sยป ะธะท-ะทะฐ ะพัะธะฑะบะธ: %v
editor.upload_file_is_locked=ะคะฐะนะป ยซ%sยป ะทะฐะฑะปะพะบะธัะพะฒะฐะฝ %s.
editor.upload_files_to_dir=ะะฐะณััะทะธัั ัะฐะนะปั ะฒ ยซ%sยป
-editor.cannot_commit_to_protected_branch=ะะตะฒะพะทะผะพะถะฝะพ ัะดะตะปะฐัั ะบะพะผะผะธั ะฒ ะทะฐัะธััะฝะฝัั ะฒะตัะบั ยซ%sยป.
-editor.no_commit_to_branch=ะะตะฒะพะทะผะพะถะฝะพ ัะพะฒะตััะธัั ะฟััะผะพะน ะบะพะผะผะธั ะฒ ะฒะตัะบั ะฟะพ ะฟัะธัะธะฝะต:
-editor.user_no_push_to_branch=ะะพะปัะทะพะฒะฐัะตะปั ะฝะต ะผะพะถะตั ะพัะฟัะฐะฒะปััั ะบะพะผะผะธัั ะฒ ััั ะฒะตัะบั
-editor.require_signed_commit=ะะตัะบะฐ ะพะถะธะดะฐะตั ะฟะพะดะฟะธัะฐะฝะฝัะน ะบะพะผะผะธั
+editor.cannot_commit_to_protected_branch=ะะตะฒะพะทะผะพะถะฝะพ ัะดะตะปะฐัั ะบะพะผะผะธั ะฒ ะทะฐัะธััะฝะฝัั ะฒะตัะฒั ยซ%sยป.
+editor.no_commit_to_branch=ะะตะฒะพะทะผะพะถะฝะพ ัะพะฒะตััะธัั ะฟััะผะพะน ะบะพะผะผะธั ะฒ ะฒะตัะฒั ะฟะพ ะฟัะธัะธะฝะต:
+editor.user_no_push_to_branch=ะะพะปัะทะพะฒะฐัะตะปั ะฝะต ะผะพะถะตั ะพัะฟัะฐะฒะปััั ะบะพะผะผะธัั ะฒ ััั ะฒะตัะฒั
+editor.require_signed_commit=ะะตัะฒั ะพะถะธะดะฐะตั ะฟะพะดะฟะธัะฐะฝะฝัะน ะบะพะผะผะธั
editor.cherry_pick=ะะตัะตะฝะตััะธ ะธะทะผะตะฝะตะฝะธั %s ะฒ:
editor.revert=ะัะบะฐัะธัั %s ะบ:
commits.desc=ะัะพัะผะพัั ะธััะพัะธะธ ะธะทะผะตะฝะตะฝะธะน ะธัั
ะพะดะฝะพะณะพ ะบะพะดะฐ.
commits.commits=ะบะพะผะผะธัั
commits.no_commits=ะะตั ะพะฑัะธั
ะบะพะผะผะธัะพะฒ. ยซ%sยป ะธ ยซ%sยป ะธะผะตัั ัะพะฒะตััะตะฝะฝะพ ัะฐะทะฝัะต ะธััะพัะธะธ.
-commits.nothing_to_compare=ะญัะธ ะฒะตัะบะธ ะพะดะธะฝะฐะบะพะฒั.
+commits.nothing_to_compare=ะญัะธ ะฒะตัะฒะธ ะพะดะธะฝะฐะบะพะฒั.
commits.search=ะะพะธัะบ ะบะพะผะผะธัะพะฒโฆ
commits.search.tooltip=ะะพะถะฝะพ ะฟัะตะดะฒะฐัััั ะบะปััะตะฒัะต ัะปะพะฒะฐ ะฟัะตัะธะบัะฐะผะธ "author:", "committer:", "after:", ะธะปะธ "before:", ะฝะฐะฟัะธะผะตั "revert author:Alice before:2019-01-13".
commits.find=ะะพะธัะบ
-commits.search_all=ะะพ ะฒัะตั
ะฒะตัะบะฐั
+commits.search_all=ะะพ ะฒัะตั
ะฒะตัะฒัั
commits.author=ะะฒัะพั
commits.message=ะกะพะพะฑัะตะฝะธะต
commits.date=ะะฐัะฐ
@@ -1363,17 +1444,17 @@ commits.ssh_key_fingerprint=ะัะฟะตัะฐัะพะบ ะบะปััะฐ SSH
commit.operations=ะะฟะตัะฐัะธะธ
commit.revert=ะัะบะฐัะธัั
commit.revert-header=ะัะบะฐั: %s
-commit.revert-content=ะัะฑัะฐัั ะฒะตัะบั ะดะปั ะพัะบะฐัะฐ:
+commit.revert-content=ะัะฑัะฐัั ะฒะตัะฒั ะดะปั ะพัะบะฐัะฐ:
commit.cherry-pick=ะะตัะตะฝะพั
commit.cherry-pick-header=ะัะฑัะฐัั: %s
-commit.cherry-pick-content=ะัะฑัะฐัั ะฒะตัะบั ะดะปั ะฟะตัะตะฝะพัะฐ:
+commit.cherry-pick-content=ะัะฑัะฐัั ะฒะตัะฒั ะดะปั ะฟะตัะตะฝะพัะฐ:
commitstatus.error=ะัะธะฑะบะฐ
commitstatus.failure=ะะตัะดะฐัะฐ
commitstatus.pending=ะะถะธะดะฐะฝะธะต
commitstatus.success=ะฃัะฟะตัะฝะพ
-ext_issues=ะะพัััะฟ ะบะพ ะฒะฝะตัะฝะธะผ ะทะฐะดะฐัะฐะผ
+ext_issues=ะะฝะตัะฝะธะต ะทะฐะดะฐัะธ
ext_issues.desc=ะกััะปะบะฐ ะฝะฐ ะฒะฝะตัะฝัั ัะธััะตะผั ะพััะปะตะถะธะฒะฐะฝะธั ะทะฐะดะฐั.
projects=ะัะพะตะบัั
@@ -1423,25 +1504,25 @@ issues.filter_milestones=ะคะธะปััั ััะฐะฟะพะฒ
issues.filter_projects=ะคะธะปัััะพะฒะฐัั ะฟัะพะตะบัั
issues.filter_labels=ะคะธะปััั ะผะตัะพะบ
issues.filter_reviewers=ะคะธะปััั ัะตัะตะฝะทะตะฝัะพะฒ
-issues.new=ะะพะฑะฐะฒะธัั ะทะฐะดะฐัั
+issues.new=ะกะพะทะดะฐัั ะทะฐะดะฐัั
issues.new.title_empty=ะะฐะณะพะปะพะฒะพะบ ะฝะต ะผะพะถะตั ะฑััั ะฟััััะผ
issues.new.labels=ะะตัะบะธ
issues.new.no_label=ะะตั ะผะตัะพะบ
issues.new.clear_labels=ะัะธััะธัั ะผะตัะบะธ
issues.new.projects=ะัะพะตะบัั
-issues.new.clear_projects=ะัะธััะธัั ะฟัะพะตะบัั
+issues.new.clear_projects=ะฃะดะฐะปะธัั ะธะท ะฟัะพะตะบัะพะฒ
issues.new.no_projects=ะะตั ะฟัะพะตะบัะฐ
issues.new.open_projects=ะัะบััััะต ะฟัะพะตะบัั
issues.new.closed_projects=ะะฐะบััััะต ะฟัะพะตะบัั
issues.new.no_items=ะะตั ัะปะตะผะตะฝัะพะฒ
issues.new.milestone=ะญัะฐะฟ
issues.new.no_milestone=ะะตั ััะฐะฟะฐ
-issues.new.clear_milestone=ะัะธััะธัั ััะฐะฟ
+issues.new.clear_milestone=ะฃะดะฐะปะธัั ะธะท ััะฐะฟะฐ
issues.new.open_milestone=ะัะบััััะต ััะฐะฟั
issues.new.closed_milestone=ะะฐะฒะตัััะฝะฝัะต ััะฐะฟั
issues.new.assignees=ะะฐะทะฝะฐัะตะฝะฝัะต
-issues.new.clear_assignees=ะฃะฑัะฐัั ะพัะฒะตัััะฒะตะฝะฝัั
-issues.new.no_assignees=ะะตั ะฝะฐะทะฝะฐัะตะฝะฝัั
ะปะธั
+issues.new.clear_assignees=ะกะฝััั ะฝะฐะทะฝะฐัะตะฝะธั
+issues.new.no_assignees=ะะตั ะฝะฐะทะฝะฐัะตะฝะฝัั
issues.new.no_reviewers=ะะตั ัะตัะตะฝะทะตะฝัะพะฒ
issues.choose.get_started=ะะฐัะฐัั
issues.choose.open_external_link=ะัะบัััั
@@ -1449,8 +1530,8 @@ issues.choose.blank=ะะพ ัะผะพะปัะฐะฝะธั
issues.choose.blank_about=ะกะพะทะดะฐัั ะทะฐะฟัะพั ะธะท ัะฐะฑะปะพะฝะฐ ะฟะพ ัะผะพะปัะฐะฝะธั.
issues.choose.ignore_invalid_templates=ะะตะบะพััะตะบัะฝัะต ัะฐะฑะปะพะฝั ะฑัะปะธ ะฟัะพะธะณะฝะพัะธัะพะฒะฐะฝั
issues.choose.invalid_templates=ะะฐะนะดะตะฝ(ั) %v ะฝะตะฒะตัะฝัะน(ั
) ัะฐะฑะปะพะฝ(ะพะฒ)
-issues.choose.invalid_config=ะะพะฝัะธะณััะฐัะธั ะทะฐะดะฐัะธ ัะพะดะตัะถะธั ะพัะธะฑะบะธ:
-issues.no_ref=ะะตั ัะฒัะทะฐะฝะฝะพะน ะฒะตัะบะธ ะธะปะธ ัะตะณะฐ
+issues.choose.invalid_config=ะัะธะฑะบะธ ะฒ ะบะพะฝัะธะณััะฐัะธะธ ะทะฐะดะฐัะธ:
+issues.no_ref=ะะตั ัะฒัะทะฐะฝะฝะพะน ะฒะตัะฒะธ ะธะปะธ ัะตะณะฐ
issues.create=ะกะพะทะดะฐัั ะทะฐะดะฐัั
issues.new_label=ะะพะฒะฐั ะผะตัะบะฐ
issues.new_label_placeholder=ะะผั ะผะตัะบะธ
@@ -1482,7 +1563,7 @@ issues.change_title_at=`ะธะทะผะตะฝะธะป(ะฐ) ะทะฐะณะพะปะพะฒะพะบ ั %s
issues.change_ref_at=`ะธะทะผะตะฝะธะป(ะฐ) ัััะปะบั ั %s ะฝะฐ %s %s`
issues.remove_ref_at=`ัะฑัะฐะป(ะฐ) ัััะปะบั %s %s`
issues.add_ref_at=`ะดะพะฑะฐะฒะปะตะฝะฐ ัััะปะบะฐ %s %s`
-issues.delete_branch_at=`ัะดะฐะปะตะฝะฐ ะฒะตัะบะฐ %s %s`
+issues.delete_branch_at=`ัะดะฐะปะตะฝะฐ ะฒะตัะฒั %s %s`
issues.filter_label=ะะตัะบะฐ
issues.filter_label_exclude=`ะัะฟะพะปัะทัะนัะต alt
+ click/enter
, ััะพะฑั ะธัะบะปััะธัั ะผะตัะบะธ`
issues.filter_label_no_select=ะัะต ะผะตัะบะธ
@@ -1494,7 +1575,7 @@ issues.filter_milestone_open=ะัะบััััะต ััะฐะฟั
issues.filter_milestone_closed=ะะฐะฒะตัััะฝะฝัะต ััะฐะฟั
issues.filter_project=ะัะพะตะบั
issues.filter_project_all=ะัะต ะฟัะพะตะบัั
-issues.filter_project_none=ะะตั ะฟัะพะตะบัะฐ
+issues.filter_project_none=ะะตะท ะฟัะพะตะบัะฐ
issues.filter_assignee=ะะฐะทะฝะฐัะตะฝะพ
issues.filter_assginee_no_select=ะัะต ะฝะฐะทะฝะฐัะตะฝะธั
issues.filter_assginee_no_assignee=ะะตั ะพัะฒะตัััะฒะตะฝะฝะพะณะพ
@@ -1525,9 +1606,9 @@ issues.action_open=ะัะบัััั
issues.action_close=ะะฐะบัััั
issues.action_label=ะะตัะบะฐ
issues.action_milestone=ะญัะฐะฟ
-issues.action_milestone_no_select=ะะตั ััะฐะฟะฐ
-issues.action_assignee=ะัะฒะตัััะฒะตะฝะฝัะน
-issues.action_assignee_no_select=ะะตั ะพัะฒะตัััะฒะตะฝะฝะพะณะพ
+issues.action_milestone_no_select=ะะตะท ััะฐะฟะฐ
+issues.action_assignee=ะะฐะทะฝะฐัะตะฝะฝัะน
+issues.action_assignee_no_select=ะะตะท ะฝะฐะทะฝะฐัะตะฝะฝะพะณะพ
issues.action_check=ะัะฑัะฐัั/ะพัะผะตะฝะธัั ะฒัะฑะพั
issues.action_check_all=ะัะฑัะฐัั/ะพัะผะตะฝะธัั ะฒัะฑะพั ะฒัะตั
ัะปะตะผะตะฝัะพะฒ
issues.opened_by=ะพัะบัััะฐ %[1]s %[3]s
@@ -1542,7 +1623,7 @@ issues.open_title=ะัะบัััะพ
issues.closed_title=ะะฐะบัััะพ
issues.draft_title=ะงะตัะฝะพะฒะธะบ
issues.num_comments_1=%d ะบะพะผะผะตะฝัะฐัะธะน
-issues.num_comments=ะบะพะผะผะตะฝัะฐัะธะตะฒ: %d
+issues.num_comments=%d ะบะพะผะผะตะฝัะฐัะธะตะฒ
issues.commented_at=`ะพััะฐะฒะปะตะฝ ะบะพะผะผะตะฝัะฐัะธะน %s `
issues.delete_comment_confirm=ะั ัะฒะตัะตะฝั, ััะพ ั
ะพัะธัะต ัะดะฐะปะธัั ััะพั ะบะพะผะผะตะฝัะฐัะธะน?
issues.context.copy_link=ะะพะฟะธัะพะฒะฐัั ัััะปะบั
@@ -1554,17 +1635,17 @@ issues.no_content=ะะฟะธัะฐะฝะธะต ะพััััััะฒัะตั.
issues.close=ะะฐะบัััั ะทะฐะดะฐัั
issues.comment_pull_merged_at=ะบะพะผะผะธั %[1]s ะฑัะป ะดะพะฑะฐะฒะปะตะฝ ะฒ %[2]s %[3]s
issues.comment_manually_pull_merged_at=ะบะพะผะผะธั %[1]s ะฑัะป ะฒัััะฝัั ะดะพะฑะฐะฒะปะตะฝ ะฒ %[2]s %[3]s
-issues.close_comment_issue=ะัะพะบะพะผะผะตะฝัะธัะพะฒะฐัั ะธ ะทะฐะบัััั
+issues.close_comment_issue=ะะฐะบัััั ะบะพะผะผะตะฝัะฐัะธะตะผ
issues.reopen_issue=ะัะบัััั ัะฝะพะฒะฐ
-issues.reopen_comment_issue=ะัะพะบะพะผะผะตะฝัะธัะพะฒะฐัั ะธ ะพัะบัััั ัะฝะพะฒะฐ
+issues.reopen_comment_issue=ะัะบัััั ัะฝะพะฒะฐ ะบะพะผะผะตะฝัะฐัะธะตะผ
issues.create_comment=ะะพะผะผะตะฝัะธัะพะฒะฐัั
issues.closed_at=`ะทะฐะดะฐัะฐ ะฑัะปะฐ ะทะฐะบัััะฐ %[2]s `
issues.reopened_at=`ะทะฐะดะฐัะฐ ะฑัะปะฐ ะพัะบัััะฐ ัะฝะพะฒะฐ %[2]s `
issues.commit_ref_at=`ัะฟะพะผะธะฝะฐะฝะธะต ััะพะน ะทะฐะดะฐัะธ ะฒ ะบะพะผะผะธัะต %[2]s `
issues.ref_issue_from=`ัะฟะพะผะธะฝะฐะฝะธะต ััะพะน ะทะฐะดะฐัะธ %[4]s %[2]s `
issues.ref_pull_from=`ัะฟะพะผะธะฝะฐะฝะธะต ััะพะณะพ ะทะฐะฟัะพัะฐ ัะปะธัะฝะธั %[4]s %[2]s `
-issues.ref_closing_from=`ัะฟะพะผะธะฝะฐะฝะธะต ะทะฐะฟัะพัะฐ ัะปะธัะฝะธั %[4]s, ะทะฐะบััะฒะฐััะตะณะพ ััั ะทะฐะดะฐัั %[2]s `
-issues.ref_reopening_from=`ัะฟะพะผะธะฝะฐะฝะธะต ะทะฐะฟัะพัะฐ ัะปะธัะฝะธั %[4]s, ะฟะพะฒัะพัะฝะพ ะพัะบััะฒะฐััะตะณะพ ััั ะทะฐะดะฐัั %[2]s `
+issues.ref_closing_from=`ัะฟะพะผะธะฝะฐะฝะธะต ะธะท ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต %[4]s, ะบะพัะพััะน ะทะฐะบัะพะตั ััั ะทะฐะดะฐัั %[2]s `
+issues.ref_reopening_from=`ัะฟะพะผะธะฝะฐะฝะธะต ะธะท ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต %[4]s, ะบะพัะพััะน ะฟะพะฒัะพัะฝะพ ะพัะบัะพะตั ััั ะทะฐะดะฐัั %[2]s `
issues.ref_closed_from=`ะทะฐะบััะป ััะพั ะทะฐะฟัะพั %[4]s %[2]s `
issues.ref_reopened_from=`ะทะฐะดะฐัะฐ ะฑัะปะฐ ะพัะบัััะฐ ัะฝะพะฒะฐ %[4]s %[2]s `
issues.ref_from=`ะธะท %[1]s`
@@ -1581,9 +1662,9 @@ issues.role.first_time_contributor_helper=ะญัะพ ะฟะตัะฒะพะต ััะฐััะธะต ะฟ
issues.role.contributor=ะกะพะฐะฒัะพั
issues.re_request_review=ะะพะฒัะพัะธัั ะทะฐะฟัะพั ะฝะฐ ะพัะทัะฒ
issues.is_stale=ะกะพ ะฒัะตะผะตะฝะธ ััะพะณะพ ะพะฑะทะพัะฐ ะฒ ััะพั PR ะฑัะปะธ ะฒะฝะตัะตะฝั ะฝะตะบะพัะพััะต ะธะทะผะตะฝะตะฝะธั
-issues.remove_request_review=ะฃะดะฐะปะธัั ะทะฐะฟัะพั ะฝะฐ ะพัะทัะฒ
-issues.remove_request_review_block=ะะตะฒะพะทะผะพะถะฝะพ ัะดะฐะปะธัั ะทะฐะฟัะพั ะฝะฐ ะพัะทัะฒ
-issues.dismiss_review=ะัะบะปะพะฝะธัั ะพัะทัะฒ
+issues.remove_request_review=ะัะผะตะฝะธัั ะทะฐะฟัะพั ัะตัะตะฝะทะธะธ
+issues.remove_request_review_block=ะะต ัะดะฐะปะพัั ะพัะผะตะฝะธัั ะทะฐะฟัะพั ัะตัะตะฝะทะธะธ
+issues.dismiss_review=ะัะบะปะพะฝะธัั ัะตัะตะฝะทะธั
issues.dismiss_review_warning=ะั ัะฒะตัะตะฝั, ััะพ ั
ะพัะธัะต ะพัะบะปะพะฝะธัั ััั ัะตัะตะฝะทะธั?
issues.sign_in_require_desc=ะะพะนะดะธัะต , ััะพะฑั ะฟัะธัะพะตะดะธะฝะธัััั ะบ ะพะฑััะถะดะตะฝะธั.
issues.edit=ะะทะผะตะฝะธัั
@@ -1615,7 +1696,7 @@ issues.num_participants_few=%d ััะฐััะฝะธะบะพะฒ
issues.attachment.open_tab=`ะะฐะถะผะธัะต, ััะพะฑั ะฟะพัะผะพััะตัั ยซ%sยป ะฒ ะฝะพะฒะพะน ะฒะบะปะฐะดะบะต`
issues.attachment.download=`ะะฐะถะผะธัะต, ััะพะฑั ัะบะฐัะฐัั ยซ%sยป`
issues.subscribe=ะะพะดะฟะธัะฐัััั
-issues.unsubscribe=ะัะบะฐะทะฐัััั ะพั ะฟะพะดะฟะธัะบะธ
+issues.unsubscribe=ะัะฟะธัะฐัััั
issues.unpin_issue=ะัะบัะตะฟะธัั ะทะฐะดะฐัั
issues.max_pinned=ะะตะปัะทั ะทะฐะบัะตะฟะธัั ะฑะพะปััะต ะทะฐะดะฐั
issues.pin_comment=ะทะฐะบัะตะฟะธะป(ะฐ) ััั ะทะฐะดะฐัั %s
@@ -1669,15 +1750,15 @@ issues.error_modifying_due_date=ะะต ัะดะฐะปะพัั ะธะทะผะตะฝะธัั ััะพะบ ะฒ
issues.error_removing_due_date=ะะต ัะดะฐะปะพัั ัะฑัะฐัั ััะพะบ ะฒัะฟะพะปะฝะตะฝะธั.
issues.push_commit_1=ะดะพะฑะฐะฒะปะตะฝ %d ะบะพะผะผะธั %s
issues.push_commits_n=ะดะพะฑะฐะฒะปะตะฝั %d ะบะพะผะผะธัะฐ(ะพะฒ) %s
-issues.force_push_codes=`ัะพััะธัะพะฒะฐะฝะฝะพะต ะพะฑะฝะพะฒะปะตะฝะธะต ะธะทะผะตะฝะตะฝะธะน %[1]s %[4]s
ะฒะผะตััะพ %[2]s
%[6]s`
+issues.force_push_codes=`ัะพััะธัะพะฒะฐะฝะฝะพะต ะพะฑะฝะพะฒะปะตะฝะธะต ะธะทะผะตะฝะตะฝะธะน %[1]s %[4]s
ะฒะผะตััะพ %[2]s
%[6]s`
issues.force_push_compare=ะกัะฐะฒะฝะธัั
issues.due_date_form=ะณะณะณะณ-ะผะผ-ะดะด
issues.due_date_form_add=ะะพะฑะฐะฒะธัั ััะพะบ ะฒัะฟะพะปะฝะตะฝะธั
issues.due_date_form_edit=ะะทะผะตะฝะธัั
issues.due_date_form_remove=ะฃะดะฐะปะธัั
issues.due_date_not_set=ะกัะพะบ ะฒัะฟะพะปะฝะตะฝะธั ะฝะต ัััะฐะฝะพะฒะปะตะฝ.
-issues.due_date_added=ะดะพะฑะฐะฒะปะตะฝ ััะพะบ ะฒัะฟะพะปะฝะตะฝะธั %s %s
-issues.due_date_modified=ััะพะบ ะฒัะฟะพะปะฝะตะฝะธั ะฟะตัะตะดะฒะธะฝัั ั %[2]s ะฝะฐ %[1]s %[3]s
+issues.due_date_added=ะดะพะฑะฐะฒะปะตะฝ ััะพะบ ะฒัะฟะพะปะฝะตะฝะธั โ %s, %s
+issues.due_date_modified=ััะพะบ ะฒัะฟะพะปะฝะตะฝะธั ะธะทะผะตะฝัะฝ ั %[2]s ะฝะฐ %[1]s %[3]s
issues.due_date_remove=ัะฑัะฐะฝ ััะพะบ ะฒัะฟะพะปะฝะตะฝะธั %s %s
issues.due_date_overdue=ะัะพััะพัะตะฝะฝัะต
issues.due_date_invalid=ะกัะพะบ ะฒัะฟะพะปะฝะตะฝะธั ะฝะตะดะตะนััะฒะธัะตะปะตะฝ ะธะปะธ ะฝะฐั
ะพะดะธััั ะทะฐ ะฟัะตะดะตะปะฐะผะธ ะดะพะฟัััะธะผะพะณะพ ะดะธะฐะฟะฐะทะพะฝะฐ. ะะพะถะฐะปัะนััะฐ, ะธัะฟะพะปัะทัะนัะต ัะพัะผะฐั ยซะณะณะณะณ-ะผะผ-ะดะดยป.
@@ -1714,17 +1795,17 @@ issues.dependency.add_error_cannot_create_circular=ะั ะฝะต ะผะพะถะตัะต ัะพะท
issues.dependency.add_error_dep_not_same_repo=ะะฑะต ะทะฐะดะฐัะธ ะดะพะปะถะฝั ะฝะฐั
ะพะดะธัััั ะฒ ะพะดะฝะพะผ ัะตะฟะพะทะธัะพัะธะธ.
issues.review.self.approval=ะั ะฝะต ะผะพะถะตัะต ะพะดะพะฑัะธัั ัะพะฑััะฒะตะฝะฝัะน ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต.
issues.review.self.rejection=ะะตะฒะพะทะผะพะถะฝะพ ะทะฐะฟัะฐัะธะฒะฐัั ะธะทะผะตะฝะตะฝะธั ัะฒะพะตะณะพ ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต.
-issues.review.approve=ะพะดะพะฑัะธะป(ะฐ) ััะธ ะธะทะผะตะฝะตะฝะธั %s
-issues.review.comment=ัะฐััะผะพััะตะป(ะฐ) ะธะทะผะตะฝะตะฝะธั %s
-issues.review.dismissed=ะพัะบะปะพะฝะธะป(ะฐ) ะพัะทัะฒ %s %s
+issues.review.approve=ะธะทะผะตะฝะตะฝะธั ะพะดะพะฑัะตะฝั %s
+issues.review.comment=ะพััะฐะฒะปะตะฝะฐ ัะตัะตะฝะทะธั %s
+issues.review.dismissed=ะพัะบะปะพะฝะตะฝะฐ ัะตัะตะฝะทะธั %s %s
issues.review.dismissed_label=ะัะบะปะพะฝะตะฝะพ
issues.review.left_comment=ะพััะฐะฒะธะป ะบะพะผะผะตะฝัะฐัะธะน
issues.review.content.empty=ะะฐะฟัะฐัะธะฒะฐั ะธะทะผะตะฝะตะฝะธั, ะฒั ะพะฑัะทะฐะฝั ะพััะฐะฒะธัั ะบะพะผะผะตะฝัะฐัะธะน ั ะฟะพััะฝะตะฝะธะตะผ ัะฒะพะธั
ะฟะพะถะตะปะฐะฝะธะน ะพัะฝะพัะธัะตะปัะฝะพ ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต.
-issues.review.reject=ะทะฐะฟัะพัะธะป(ะฐ) ะธะทะผะตะฝะตะฝะธั %s
+issues.review.reject=ะทะฐะฟัะพัะตะฝั ะธะทะผะตะฝะตะฝะธั %s
issues.review.wait=ะฑัะป ะทะฐะฟัะพัะตะฝ ะดะปั ะพัะทัะฒะฐ %s
-issues.review.add_review_request=ะทะฐะฟัะพัะธะป(ะฐ) ะพัะทัะฒ ะพั %s %s
-issues.review.remove_review_request=ัะดะฐะปะธะป(ะฐ )ะทะฐัะฒะบั ะฝะฐ ะพัะทัะฒ ะดะปั %s %s
-issues.review.remove_review_request_self=ะพัะบะฐะทะฐะปัั ะดะพะฑะฐะฒะปััั ะพัะทัะฒ %s
+issues.review.add_review_request=ะทะฐะฟัะพัะตะฝะฐ ัะตัะตะฝะทะธั ะพั %[1]s %[2]s
+issues.review.remove_review_request=ะพัะผะตะฝัะฝ ะทะฐะฟัะพั ัะตัะตะฝะทะธะธ ะพั %[1]s %[2]s
+issues.review.remove_review_request_self=ะพัะบะฐะท ะพั ัะตัะตะฝะทะธัะพะฒะฐะฝะธั %s
issues.review.pending=ะะถะธะดะฐะฝะธะต
issues.review.pending.tooltip=ะญัะพั ะบะพะผะผะตะฝัะฐัะธะน ะฒ ะฝะฐััะพััะตะต ะฒัะตะผั ะฝะต ะฒะธะดะตะฝ ะดััะณะธะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ. ะงัะพะฑั ะพัะฟัะฐะฒะธัั ะพัะปะพะถะตะฝะฝัะต ะบะพะผะผะตะฝัะฐัะธะธ, ะฒัะฑะตัะธัะต ยซ%sยป โ ยซ%s/%s/%sยป ะฒ ะฒะตัั
ะฝะตะน ัะฐััะธ ัััะฐะฝะธัั.
issues.review.review=ะ ะตัะตะฝะทะธั
@@ -1756,56 +1837,56 @@ pulls.desc=ะะบะปััะธัั ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต ะธ ะฟัะพะฒะตัะบ
pulls.new=ะกะพะทะดะฐัั ะทะฐะฟัะพั
pulls.view=ะัะพัะผะพัั ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต
pulls.compare_changes=ะะพะฒัะน ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต
-pulls.allow_edits_from_maintainers=ะ ะฐะทัะตัะธัั ัะตะดะฐะบัะธัะพะฒะฐะฝะธะต ัะพะฟัะพะฒะพะถะดะฐััะธะผะธ
-pulls.allow_edits_from_maintainers_desc=ะะพะปัะทะพะฒะฐัะตะปะธ ั ะดะพัััะฟะพะผ ะฝะฐ ะทะฐะฟะธัั ะฒ ะพัะฝะพะฒะฝัั ะฒะตัะบั ะผะพะณัั ะพัะฟัะฐะฒะปััั ะธะทะผะตะฝะตะฝะธั ะธ ะฒ ััั ะฒะตัะบั
+pulls.allow_edits_from_maintainers=ะ ะฐะทัะตัะธัั ะฟัะฐะฒะบะธ ะพั ัะพะฟัะพะฒะพะถะดะฐััะธั
+pulls.allow_edits_from_maintainers_desc=ะะพะปัะทะพะฒะฐัะตะปะธ ั ะดะพัััะฟะพะผ ะฝะฐ ะทะฐะฟะธัั ะฒ ะพัะฝะพะฒะฝัั ะฒะตัะฒั ะผะพะณัั ะพัะฟัะฐะฒะปััั ะธะทะผะตะฝะตะฝะธั ะธ ะฒ ััั ะฒะตัะฒั
pulls.allow_edits_from_maintainers_err=ะะต ัะดะฐะปะพัั ะพะฑะฝะพะฒะธัั
-pulls.compare_changes_desc=ะกัะฐะฒะฝะธัั ะดะฒะต ะฒะตัะบะธ ะธ ัะพะทะดะฐัั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะดะปั ะธะทะผะตะฝะตะฝะธะน.
+pulls.compare_changes_desc=ะกัะฐะฒะฝะธัั ะดะฒะต ะฒะตัะฒะธ ะธ ัะพะทะดะฐัั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะดะปั ะธะทะผะตะฝะตะฝะธะน.
pulls.has_viewed_file=ะัะพัะผะพััะตะฝะพ
pulls.has_changed_since_last_review=ะะทะผะตะฝะตะฝะพ ั ะผะพะผะตะฝัะฐ ะฒะฐัะตะณะพ ะฟะพัะปะตะดะฝะตะณะพ ะพัะทัะฒะฐ
pulls.viewed_files_label=%[1]d ะธะท %[2]d ัะฐะนะปะพะฒ ะฟัะพัะผะพััะตะฝะพ
pulls.expand_files=ะะพะบะฐะทะฐัั ะฒัะต ัะฐะนะปั
pulls.collapse_files=ะกะฒะตัะฝััั ะฒัะต ัะฐะนะปั
-pulls.compare_base=ะฑะฐะทะพะฒะฐั ะฒะตัะบะฐ
+pulls.compare_base=ะฑะฐะทะพะฒะฐั ะฒะตัะฒั
pulls.compare_compare=ะฒะทััั ะธะท
pulls.switch_comparison_type=ะะตัะตะบะปััะธัั ัะธะฟ ััะฐะฒะฝะตะฝะธั
-pulls.switch_head_and_base=ะะพะผะตะฝััั ะธัั
ะพะดะฝัั ะธ ัะตะปะตะฒัั ะฒะตัะบะธ ะผะตััะฐะผะธ
-pulls.filter_branch=ะคะธะปััั ะฟะพ ะฒะตัะบะต
+pulls.switch_head_and_base=ะะพะผะตะฝััั ะธัั
ะพะดะฝัั ะธ ัะตะปะตะฒัั ะฒะตัะฒะธ ะผะตััะฐะผะธ
+pulls.filter_branch=ะคะธะปััั ะฟะพ ะฒะตัะฒะธ
pulls.no_results=ะ ะตะทัะปััะฐัะพะฒ ะฝะต ะฝะฐะนะดะตะฝะพ.
pulls.show_all_commits=ะะพะบะฐะทะฐัั ะฒัะต ะบะพะผะผะธัั
pulls.show_changes_since_your_last_review=ะะพะบะฐะทะฐัั ะธะทะผะตะฝะตะฝะธั ั ะผะพะผะตะฝัะฐ ะฒะฐัะตะณะพ ะฟะพัะปะตะดะฝะตะณะพ ะพัะทัะฒะฐ
pulls.showing_only_single_commit=ะะพะบะฐะทะฐัั ัะพะปัะบะพ ะธะทะผะตะฝะตะฝะธั ะบะพะผะผะธัะฐ %[1]s
pulls.showing_specified_commit_range=ะะพะบะฐะทะฐะฝั ัะพะปัะบะพ ะธะทะผะตะฝะตะฝะธั ะผะตะถะดั %[1]s..%[2]
pulls.filter_changes_by_commit=ะคะธะปััั ะฟะพ ะบะพะผะผะธัั
-pulls.nothing_to_compare=ะะตัะตะณะพ ััะฐะฒะฝะธะฒะฐัั, ัะพะดะธัะตะปััะบะฐั ะธ ัะตะบััะฐั ะฒะตัะบะฐ ะพะดะธะฝะฐะบะพะฒัะต.
-pulls.nothing_to_compare_and_allow_empty_pr=ะะตัะบะธ ะธะดะตะฝัะธัะฝั. ะญัะพั PR ะฑัะดะตั ะฟััััะผ.
-pulls.has_pull_request=`ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ััะธั
ะฒะตัะพะบ ัะถะต ัััะตััะฒัะตั: %[2]s#%[3]d `
+pulls.nothing_to_compare=ะะตัะตะณะพ ััะฐะฒะฝะธะฒะฐัั, ัะพะดะธัะตะปััะบะฐั ะธ ัะตะบััะฐั ะฒะตัะฒั ะพะดะธะฝะฐะบะพะฒัะต.
+pulls.nothing_to_compare_and_allow_empty_pr=ะะตัะฒะธ ะธะดะตะฝัะธัะฝั. ะญัะพั PR ะฑัะดะตั ะฟััััะผ.
+pulls.has_pull_request=`ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ััะธั
ะฒะตัะฒะตะน ัะถะต ัััะตััะฒัะตั: %[2]s#%[3]d `
pulls.create=ะกะพะทะดะฐัั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต
-pulls.title_desc_one=ั
ะพัะตั ะฒะปะธัั %[1]d ะบะพะผะผะธั ะธะท %[2]s
ะฒ %[3]s
-pulls.title_desc_few=ั
ะพัะตั ะฒะปะธัั %[1]d ะบะพะผะผะธั(ะพะฒ) ะธะท %[2]s
ะฒ %[3]s
+pulls.title_desc_one=ั
ะพัะตั ะฒะปะธัั %[1]d ะบะพะผะผะธั ะธะท %[2]s
ะฒ %[3]s
+pulls.title_desc_few=ั
ะพัะตั ะฒะปะธัั %[1]d ะบะพะผะผะธั(ะพะฒ) ะธะท %[2]s
ะฒ %[3]s
pulls.merged_title_desc_one=ัะปะธั %[1]d ะบะพะผะผะธั ะธะท %[2]s
ะฒ %[3]s
%[4]s
pulls.merged_title_desc_few=ัะปะธัะพ %[1]d ะบะพะผะผะธั(ะพะฒ) ะธะท %[2]s
ะฒ %[3]s
%[4]s
-pulls.change_target_branch_at=`ะธะทะผะตะฝะธะป(ะฐ) ัะตะปะตะฒัั ะฒะตัะบั ั %s ะฝะฐ %s %s`
+pulls.change_target_branch_at=`ะธะทะผะตะฝะธะป(ะฐ) ัะตะปะตะฒัั ะฒะตัะฒั ั %s ะฝะฐ %s %s`
pulls.tab_conversation=ะะฑััะถะดะตะฝะธะต
pulls.tab_commits=ะะพะผะผะธัั
pulls.tab_files=ะะทะผะตะฝัะฝะฝัะต ัะฐะนะปั
pulls.reopen_to_merge=ะะพะถะฐะปัะนััะฐ, ะฟะตัะตะพัะบัะพะนัะต ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะดะปั ะฒัะฟะพะปะฝะตะฝะธั ัะปะธัะฝะธั.
-pulls.cant_reopen_deleted_branch=ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฝะต ะผะพะถะตั ะฑััั ะพัะบััั ะทะฐะฝะพะฒะพ, ะฟะพัะพะผั ััะพ ะฒะตัะบะฐ ะฑัะปะฐ ัะดะฐะปะตะฝะฐ.
+pulls.cant_reopen_deleted_branch=ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฝะต ะผะพะถะตั ะฑััั ะพัะบััั ะฟะพะฒัะพัะฝะพ, ะฟะพัะพะผั ััะพ ะฒะตัะฒั ะฑัะปะฐ ัะดะฐะปะตะฝะฐ.
pulls.merged=ะกะปะธัะพ
pulls.merged_success=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ัะดะพะฒะปะตัะฒะพััะฝ ะธ ะทะฐะบััั
pulls.closed=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะทะฐะบััั
pulls.manually_merged=ะกะปะธัะพ ะฒัััะฝัั
-pulls.merged_info_text=ะะตัะบั %s ัะตะฟะตัั ะผะพะถะฝะพ ัะดะฐะปะธัั.
+pulls.merged_info_text=ะะตัะฒั %s ัะตะฟะตัั ะผะพะถะฝะพ ัะดะฐะปะธัั.
pulls.is_closed=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะทะฐะบััั.
pulls.title_wip_desc=`ะะพะฑะฐะฒััะต %s ะฒ ะฝะฐัะฐะปะพ ะทะฐะณะพะปะพะฒะบะฐ ะดะปั ะทะฐัะธัั ะพั ัะปััะฐะนะฝะพะณะพ ะดะพััะพัะฝะพะณะพ ะฟัะธะฝััะธั ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต`
pulls.cannot_merge_work_in_progress=ะญัะพั ะทะฐะฟัะพั ัะปะธัะฝะธั ะฟะพะผะตัะตะฝ ะบะฐะบ ัะตัะฝะพะฒะธะบ.
pulls.still_in_progress=ะัั ะตัั ะฒ ะฟัะพัะตััะต?
pulls.add_prefix=ะะพะฑะฐะฒะธัั ะฟัะตัะธะบั %s
pulls.remove_prefix=ะฃะดะฐะปะธัั ะฟัะตัะธะบั %s
-pulls.data_broken=ะกะพะดะตัะถะธะผะพะต ััะพะณะพ ัะปะธัะฝะธั ะฝะฐัััะตะฝะพ ะธะท-ะทะฐ ัะดะฐะปะตะฝะธั ะธะฝัะพัะผะฐัะธะธ ะพะฑ ะพัะฒะตัะฒะปะตะฝะธะธ.
-pulls.files_conflicted=ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะธะผะตะตั ะธะทะผะตะฝะตะฝะธั ะบะพะฝัะปะธะบััััะธะต ั ัะตะปะตะฒะพะน ะฒะตัะบะพะน.
+pulls.data_broken=ะกะพะดะตัะถะธะผะพะต ััะพะณะพ ัะปะธัะฝะธั ะฝะฐัััะตะฝะพ ะธะท-ะทะฐ ะพััััััะฒะธั ะธะฝัะพัะผะฐัะธะธ ะพะฑ ะพัะฒะตัะฒะปะตะฝะธะธ.
+pulls.files_conflicted=ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะธะผะตะตั ะธะทะผะตะฝะตะฝะธั ะบะพะฝัะปะธะบััััะธะต ั ัะตะปะตะฒะพะน ะฒะตัะฒัั.
pulls.is_checking=ะัะพะดะพะปะถะฐะตััั ะฟัะพะฒะตัะบะฐ ะบะพะฝัะปะธะบัะพะฒ. ะะพะฒัะพัะธัะต ะฟะพะฟััะบั ะฟะพะทะถะต.
-pulls.is_ancestor=ะญัะฐ ะฒะตัะบะฐ ัะถะต ะฒะบะปััะตะฝะฐ ะฒ ัะตะปะตะฒัั ะฒะตัะบั. ะะฑัะตะดะธะฝััั ะฝะตัะตะณะพ.
-pulls.is_empty=ะะทะผะตะฝะตะฝะธั ะธะท ััะพะน ะฒะตัะบะธ ัะถะต ะตััั ะฒ ัะตะปะตะฒะพะน ะฒะตัะบะต. ะะพะปััะธััั ะฟัััะพะน ะบะพะผะผะธั.
+pulls.is_ancestor=ะกะพะดะตัะถะธะผะพะต ััะพะน ะฒะตัะฒะธ ัะถะต ะฒะบะปััะตะฝะพ ะฒ ัะตะปะตะฒัั ะฒะตัะฒั. ะะฑัะตะดะธะฝััั ะฝะตัะตะณะพ.
+pulls.is_empty=ะะทะผะตะฝะตะฝะธั ะธะท ััะพะน ะฒะตัะฒะธ ัะถะต ะตััั ะฒ ัะตะปะตะฒะพะน ะฒะตัะฒะธ. ะะพะปััะธััั ะฟัััะพะน ะบะพะผะผะธั.
pulls.required_status_check_failed=ะะตะบะพัะพััะต ะฝะตะพะฑั
ะพะดะธะผัะต ะฟัะพะฒะตัะบะธ ะฝะต ะฑัะปะธ ะฟัะพะนะดะตะฝั.
pulls.required_status_check_missing=ะััััััะฒััั ะฝะตะบะพัะพััะต ะพะฑัะทะฐัะตะปัะฝัะต ะฟัะพะฒะตัะบะธ.
pulls.required_status_check_administrator=ะะฐะบ ะฐะดะผะธะฝะธัััะฐัะพั, ะฒั ะฒัะต ัะฐะฒะฝะพ ะผะพะถะตัะต ะฟัะธะฝััั ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต.
@@ -1822,7 +1903,7 @@ pulls.reject_count_1=%d ะทะฐะฟัะพั ะธะทะผะตะฝะตะฝะธะน
pulls.reject_count_n=%d ะทะฐะฟัะพัะพะฒ ะธะทะผะตะฝะตะฝะธะน
pulls.waiting_count_1=%d ะพะถะธะดะฐะตั ะฟัะพะฒะตัะบะธ
pulls.waiting_count_n=%d ะพะถะธะดะฐััะธั
ะฟัะพะฒะตัะบะธ
-pulls.wrong_commit_id=id ะบะพะผะผะธัะฐ ะดะพะปะถะตะฝ ะฑััั ะธะด ะบะพะผะผะธัะฐ ะฒ ัะตะปะตะฒะพะน ะฒะตัะบะต
+pulls.wrong_commit_id=ะธะด ะบะพะผะผะธัะฐ ะดะพะปะถะตะฝ ะฑััั ะธะด ะบะพะผะผะธัะฐ ะฒ ัะตะปะตะฒะพะน ะฒะตัะฒะธ
pulls.no_merge_desc=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฝะต ะผะพะถะตั ะฑััั ะฟัะธะฝัั, ัะฐะบ ะบะฐะบ ะพัะบะปััะตะฝั ะฒัะต ะฝะฐัััะพะนะบะธ ัะปะธัะฝะธั.
pulls.no_merge_helper=ะะบะปััะธัะต ะพะฟัะธะธ ัะปะธัะฝะธั ะฒ ะฝะฐัััะพะนะบะฐั
ัะตะฟะพะทะธัะพัะธั ะธะปะธ ัะพะฒะตััะธัะต ัะปะธัะฝะธะต ััะพะณะพ ะทะฐะฟัะพัะฐ ะฒัััะฝัั.
@@ -1835,7 +1916,7 @@ pulls.rebase_merge_commit_pull_request=ะัะฟะพะปะฝะธัั rebase ะธ ัะพะทะดะฐั
pulls.squash_merge_pull_request=ะกะพะทะดะฐัั ะพะฑัะตะดะธะฝัััะธะน ะบะพะผะผะธั
pulls.merge_manually=ะกะปะธัะพ ะฒัััะฝัั
pulls.merge_commit_id=ะะ ะบะพะผะผะธัะฐ ัะปะธัะฝะธั
-pulls.require_signed_wont_sign=ะะฐะฝะฝะฐั ะฒะตัะบะฐ ะพะถะธะดะฐะตั ะฟะพะดะฟะธัะฐะฝะฝัะต ะบะพะผะผะธัั, ะพะดะฝะฐะบะพ ัะปะธัะฝะธะต ะฝะต ะฑัะดะตั ะฟะพะดะฟะธัะฐะฝะพ
+pulls.require_signed_wont_sign=ะะฐะฝะฝะฐั ะฒะตัะฒั ะพะถะธะดะฐะตั ะฟะพะดะฟะธัะฐะฝะฝัะต ะบะพะผะผะธัั, ะพะดะฝะฐะบะพ ัะปะธัะฝะธะต ะฝะต ะฑัะดะตั ะฟะพะดะฟะธัะฐะฝะพ
pulls.invalid_merge_option=ะญัะพั ะฟะฐัะฐะผะตัั ัะปะธัะฝะธั ะฝะตะปัะทั ะธัะฟะพะปัะทะพะฒะฐัั ะดะปั ััะพะณะพ ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต.
pulls.merge_conflict=ะกะปะธัะฝะธะต ะฝะต ัะดะฐะปะพัั: ะฟัะพะธะทะพัะตะป ะบะพะฝัะปะธะบั ะฒะพ ะฒัะตะผั ัะปะธัะฝะธั. ะกะพะฒะตั: ะฟะพะฟัะพะฑัะนัะต ะดััะณัั ัััะฐัะตะณะธั
@@ -1849,7 +1930,7 @@ pulls.push_rejected=ะัะฟัะฐะฒะบะฐ ะฑัะปะฐ ะพัะบะปะพะฝะตะฝะฐ. ะัะพะฒะตัั
pulls.push_rejected_summary=ะะพะปะฝะฐั ะฟัะธัะธะฝะฐ ะพัะบะปะพะฝะตะฝะธั
pulls.push_rejected_no_message=ะัะฟัะฐะฒะบะฐ ะฑัะปะฐ ะพัะบะปะพะฝะตะฝะฐ ะธ ัะดะฐะปัะฝะฝัะน ัะตัะฒะตั ะฝะต ัะบะฐะทะฐะป ะฟัะธัะธะฝั. ะัะพะฒะตัััะต Git-ั
ัะบะธ ััะพะณะพ ัะตะฟะพะทะธัะพัะธั
pulls.open_unmerged_pull_exists=`ะะตะปัะทั ะพัะบัััั ัะฝะพะฒะฐ, ะฟะพัะบะพะปัะบั ัััะตััะฒัะตั ะดััะณะพะน ะพัะบััััะน ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต (#%d) ั ัะฐะบะธะผะธ ะถะต ัะฒะพะนััะฒะฐะผะธ.`
-pulls.status_checking=ะัะฟะพะปะฝััััั ะฟัะพะฒะตัะบะธ
+pulls.status_checking=ะะถะธะดะฐะตััั ะฒัะฟะพะปะฝะตะฝะธะต ะฟัะพะฒะตัะพะบ
pulls.status_checks_success=ะัะต ะฟัะพะฒะตัะบะธ ััะฟะตัะฝะพ ะฟัะพะนะดะตะฝั
pulls.status_checks_warning=ะะตะบะพัะพััะต ะฟัะพะฒะตัะบะธ ะธะผะตัั ะฟัะตะดัะฟัะตะถะดะตะฝะธั
pulls.status_checks_failure=ะะตะบะพัะพััะต ะฟัะพะฒะตัะบะธ ะฟัะพะฒะฐะปะธะปะธัั
@@ -1858,15 +1939,15 @@ pulls.status_checks_requested=ะขัะตะฑัะตััั
pulls.status_checks_details=ะะพะดัะพะฑะฝะพััะธ
pulls.status_checks_hide_all=ะกะบัััั ะฒัะต ะฟัะพะฒะตัะบะธ
pulls.status_checks_show_all=ะะพะบะฐะทะฐัั ะฒัะต ะฟัะพะฒะตัะบะธ
-pulls.update_branch=ะะฑะฝะพะฒะธัั ะฒะตัะบั ัะปะธัะฝะธะตะผ
-pulls.update_branch_rebase=ะะฑะฝะพะฒะธัั ะฒะตัะบั ะฟะตัะตะฑะฐะทะธัะพะฒะฐะฝะธะตะผ
-pulls.update_branch_success=ะะตัะบะฐ ััะฟะตัะฝะพ ะพะฑะฝะพะฒะปะตะฝะฐ
-pulls.update_not_allowed=ะะตะดะพััะฐัะพัะฝะพ ะฟัะฐะฒ ะดะปั ะพะฑะฝะพะฒะปะตะฝะธั ะฒะตัะบะธ
-pulls.outdated_with_base_branch=ะญัะฐ ะฒะตัะบะฐ ะพัััะฐะตั ะพั ะฑะฐะทะพะฒะพะน ะฒะตัะบะธ
-pulls.close=ะะฐะบัััั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต
+pulls.update_branch=ะะฑะฝะพะฒะธัั ะฒะตัะฒั ัะปะธัะฝะธะตะผ
+pulls.update_branch_rebase=ะะฑะฝะพะฒะธัั ะฒะตัะฒั ะฟะตัะตะฑะฐะทะธัะพะฒะฐะฝะธะตะผ
+pulls.update_branch_success=ะะตัะฒั ััะฟะตัะฝะพ ะพะฑะฝะพะฒะปะตะฝะฐ
+pulls.update_not_allowed=ะะตะดะพััะฐัะพัะฝะพ ะฟัะฐะฒ ะดะปั ะพะฑะฝะพะฒะปะตะฝะธั ะฒะตัะฒะธ
+pulls.outdated_with_base_branch=ะญัะฐ ะฒะตัะฒั ะพัััะฐะตั ะพั ะฑะฐะทะพะฒะพะน ะฒะตัะฒะธ
+pulls.close=ะะฐะบัััั ะทะฐะฟัะพั ัะปะธัะฝะธั
pulls.closed_at=`ะทะฐะบััะป ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต %[2]s `
pulls.reopened_at=`ะฟะตัะตะพัะบััะป ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต %[2]s `
-pulls.cmd_instruction_hint=`ะะพะบะฐะทะฐัั ะธะฝััััะบัะธะธ ะดะปั ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ .`
+pulls.cmd_instruction_hint=ะะพะบะฐะทะฐัั ะธะฝััััะบัะธะธ ะดะปั ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ
pulls.cmd_instruction_merge_title=ะกะปะตะนัะต ะธะทะผะตะฝะตะฝะธั
pulls.cmd_instruction_merge_desc=ะกะปะตะนัะต ะธะทะผะตะฝะตะฝะธั ะธ ะพัะฟัะฐะฒััะต ะธั
ะพะฑัะฐัะฝะพ.
pulls.clear_merge_message=ะัะธััะธัั ัะพะพะฑัะตะฝะธะต ะพ ัะปะธัะฝะธะธ
@@ -1885,7 +1966,7 @@ pulls.auto_merge_newly_scheduled_comment=`ะทะฐะฟะปะฐะฝะธัะพะฒะฐะป ััะพั ะทะฐ
pulls.auto_merge_canceled_schedule_comment=`ะพัะผะตะฝะธะป ะฐะฒัะพะผะฐัะธัะตัะบะพะต ัะปะธัะฝะธะต ััะพะณะพ ะทะฐะฟัะพัะฐ ะฟะพัะปะต ะฟัะพั
ะพะถะดะตะฝะธั ะฒัะตั
ะฟัะพะฒะตัะพะบ %[1]s`
pulls.delete.title=ะฃะดะฐะปะธัั ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต?
-pulls.delete.text=ะั ัะพัะฝะพ ั
ะพัะธัะต ัะดะฐะปะธัั ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต? (ะญัะพ ะฝะฐะฒัะตะณะดะฐ ัะดะฐะปะธั ะฒัั ะตะณะพ ัะพะดะตัะถะธะผะพะต. ะะพะทะผะพะถะฝะพ, ะปัััะต ะทะฐะบัััั ะตะณะพ ะฒ ะฐัั
ะธะฒะฝัั
ัะตะปัั
)
+pulls.delete.text=ะั ัะพัะฝะพ ั
ะพัะธัะต ัะดะฐะปะธัั ััะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต? (ะญัะพ ะฝะฐะฒัะตะณะดะฐ ัะดะฐะปะธั ะฒัั ะตะณะพ ัะพะดะตัะถะธะผะพะต. ะะพะทะผะพะถะฝะพ, ะฑัะดะตั ะปัััะต ะทะฐะบัััั ะตะณะพ ะฒ ะฐัั
ะธะฒะฝัั
ัะตะปัั
)
pull.deleted_branch=(ัะดะฐะปะตะฝะฐ):%s
@@ -1931,7 +2012,7 @@ signing.wont_sign.commitssigned=ะกะปะธัะฝะธะต ะฝะต ะฑัะดะตั ะฟะพะดะฟะธัะฐะฝ
signing.wont_sign.approved=ะกะปะธัะฝะธะต ะฝะต ะฑัะดะตั ะฟะพะดะฟะธัะฐะฝะพ, ัะฐะบ ะบะฐะบ ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฝะต ะพะดะพะฑัะตะฝ.
signing.wont_sign.not_signed_in=ะั ะฝะต ะฒะพัะปะธ ะฒ ัะธััะตะผั.
-ext_wiki=ะะพัััะฟ ะบะพ ะฒะฝะตัะฝะตะน ะฒะธะบะธ
+ext_wiki=ะะฝะตัะฝัั ะฒะธะบะธ
ext_wiki.desc=ะกััะปะบะฐ ะฝะฐ ะฒะฝะตัะฝัั ะฒะธะบะธ.
wiki=ะะธะบะธ
@@ -1950,7 +2031,7 @@ wiki.last_commit_info=%s ัะตะดะฐะบัะธัะพะฒะฐะป(ะฐ) ััั ัััะฐะฝะธัั %s
wiki.edit_page_button=ะ ะตะดะฐะบัะธัะพะฒะฐัั
wiki.new_page_button=ะะพะฒะฐั ัััะฐะฝะธัะฐ
wiki.file_revision=ะะตััะธั ัััะฐะฝะธัั
-wiki.wiki_page_revisions=ะะตััะธะธ ัััะฐะฝะธัั ะฒะธะบะธ
+wiki.wiki_page_revisions=ะะตััะธะธ ัััะฐะฝะธัั
wiki.back_to_wiki=ะะตัะฝััััั ะฝะฐ ัััะฐะฝะธัั ะฒะธะบะธ
wiki.delete_page_button=ะฃะดะฐะปะธัั ัััะฐะฝะธัั
wiki.delete_page_notice_1=ะฃะดะฐะปะตะฝะธะต ัััะฐะฝะธัั ะฒะธะบะธ ยซ%sยป ะฝะต ะผะพะถะตั ะฑััั ะพัะผะตะฝะตะฝะพ. ะัะพะดะพะปะถะธัั?
@@ -2003,7 +2084,7 @@ activity.unresolved_conv_label=ะัะบััััะต
activity.title.releases_1=%d ะฒัะฟััะบ
activity.title.releases_n=%d ะฒัะฟััะบะธ
activity.title.releases_published_by=%s ะพะฟัะฑะปะธะบะพะฒะฐะฝั %s
-activity.published_release_label=ะะฟัะฑะปะธะบะพะฒะฐะฝะพ
+activity.published_release_label=ะัะฟััะบ
activity.no_git_activity=ะ ััะพั ะฟะตัะธะพะด ะฝะต ะฑัะปะพ ะฝะพะฒัั
ะบะพะผะผะธัะพะฒ.
activity.git_stats_exclude_merges=ะะฐ ะธัะบะปััะตะฝะธะตะผ ัะปะธัะฝะธะน,
activity.git_stats_author_1=%d ะฐะฒัะพั
@@ -2013,7 +2094,7 @@ activity.git_stats_pushed_n=ะพัะฟัะฐะฒะธะปะธ
activity.git_stats_commit_1=%d ะบะพะผะผะธั
activity.git_stats_commit_n=%d ะบะพะผะผะธัะพะฒ
activity.git_stats_push_to_branch=ะฒ %s ะธ
-activity.git_stats_push_to_all_branches=ะฒะพ ะฒัะต ะฒะตัะบะธ.
+activity.git_stats_push_to_all_branches=ะฒะพ ะฒัะต ะฒะตัะฒะธ.
activity.git_stats_on_default_branch=ะะฐ %s,
activity.git_stats_file_1=%d ัะฐะนะป
activity.git_stats_file_n=%d ัะฐะนะปะพะฒ
@@ -2026,8 +2107,7 @@ activity.git_stats_and_deletions=ะธ
activity.git_stats_deletion_1=%d ัะดะฐะปะตะฝะธะต
activity.git_stats_deletion_n=%d ัะดะฐะปะตะฝะธะน
-contributors.contribution_type.commits=ะบะพะผะผะธัะพะฒ
-
+contributors.contribution_type.commits = ะะพะผะผะธัั
search=ะะพะธัะบ
search.search_repo=ะะพะธัะบ ะฟะพ ัะตะฟะพะทะธัะพัะธั
search.type.tooltip=ะขะธะฟ ะฟะพะธัะบะฐ
@@ -2052,10 +2132,10 @@ settings.hooks=ะะตะฑ-ั
ัะบะธ
settings.githooks=Git-ั
ัะบะธ
settings.basic_settings=ะัะฝะพะฒะฝัะต ะฟะฐัะฐะผะตััั
settings.mirror_settings=ะะตัะบะฐะปะธัะพะฒะฐะฝะธะต
-settings.mirror_settings.docs=ะะฐัััะพะนัะต ัะฒะพะน ัะตะฟะพะทะธัะพัะธะน ะดะปั ะฐะฒัะพะผะฐัะธัะตัะบะพะน ัะธะฝั
ัะพะฝะธะทะฐัะธะธ ะบะพะผะผะธัะพะฒ, ัะตะณะพะฒ ะธ ะฒะตัะพะบ ั ะดััะณะธะผ ัะตะฟะพะทะธัะพัะธะตะผ.
-settings.mirror_settings.docs.disabled_pull_mirror.instructions=ะะฐัััะพะนัะต ัะฒะพะน ะฟัะพะตะบั ะดะปั ะฐะฒัะพะผะฐัะธัะตัะบะพะน ะพัะฟัะฐะฒะบะธ ะบะพะผะผะธัะพะฒ, ัะตะณะพะฒ ะธ ะฒะตัะพะบ ะฒ ะดััะณะพะน ัะตะฟะพะทะธัะพัะธะน. Pull-ะทะตัะบะฐะปะฐ ะฑัะปะธ ะพัะบะปััะตะฝั ะฐะดะผะธะฝะธัััะฐัะพัะพะผ ัะฐะนัะฐ.
-settings.mirror_settings.docs.disabled_push_mirror.instructions=ะะฐัััะพะนัะต ัะฒะพะน ะฟัะพะตะบั, ััะพะฑั ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฟะพะปััะฐัั ะบะพะผะผะธัั, ัะตะณะธ ะธ ะฒะตัะบะธ ะธะท ะดััะณะพะณะพ ัะตะฟะพะทะธัะพัะธั.
-settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=ะ ะฝะฐััะพััะตะต ะฒัะตะผั ััะพ ะผะพะถะฝะพ ัะดะตะปะฐัั ัะพะปัะบะพ ะฒ ะผะตะฝั ยซะะพะฒะฐั ะผะธะณัะฐัะธัยป. ะะปั ะฟะพะปััะตะฝะธั ะดะพะฟะพะปะฝะธัะตะปัะฝะพะน ะธะฝัะพัะผะฐัะธะธ, ะฟะพะถะฐะปัะนััะฐ, ะพะทะฝะฐะบะพะผััะตัั:
+settings.mirror_settings.docs=ะะฐัััะพะนัะต ัะฒะพะน ัะตะฟะพะทะธัะพัะธะน ะดะปั ะฐะฒัะพะผะฐัะธัะตัะบะพะน ัะธะฝั
ัะพะฝะธะทะฐัะธะธ ะบะพะผะผะธัะพะฒ, ัะตะณะพะฒ ะธ ะฒะตัะฒะตะน ั ะดััะณะธะผ ัะตะฟะพะทะธัะพัะธะตะผ.
+settings.mirror_settings.docs.disabled_pull_mirror.instructions=ะะฐัััะพะนัะต ัะฒะพะน ะฟัะพะตะบั ะดะปั ะฐะฒัะพะผะฐัะธัะตัะบะพะน ะพัะฟัะฐะฒะบะธ ะบะพะผะผะธัะพะฒ, ัะตะณะพะฒ ะธ ะฒะตัะฒะตะน ะฒ ะดััะณะพะน ัะตะฟะพะทะธัะพัะธะน. Pull-ะทะตัะบะฐะปะฐ ะฑัะปะธ ะพัะบะปััะตะฝั ะฐะดะผะธะฝะธัััะฐัะพัะพะผ ัะฐะนัะฐ.
+settings.mirror_settings.docs.disabled_push_mirror.instructions=ะะฐัััะพะนัะต ัะฒะพะน ะฟัะพะตะบั, ััะพะฑั ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฟะพะปััะฐัั ะบะพะผะผะธัั, ัะตะณะธ ะธ ะฒะตัะฒะธ ะธะท ะดััะณะพะณะพ ัะตะฟะพะทะธัะพัะธั.
+settings.mirror_settings.docs.disabled_push_mirror.pull_mirror_warning=ะ ะฝะฐััะพััะตะต ะฒัะตะผั ััะพ ะผะพะถะฝะพ ัะดะตะปะฐัั ัะพะปัะบะพ ัะตัะตะท ะผะตะฝั ยซะัะฟะพะปะฝะธัั ะฟะตัะตะฝะพัยป. ะะปั ะฟะพะปััะตะฝะธั ะดะพะฟะพะปะฝะธัะตะปัะฝะพะน ะธะฝัะพัะผะฐัะธะธ, ะฟะพะถะฐะปัะนััะฐ, ะพะทะฝะฐะบะพะผััะตัั:
settings.mirror_settings.docs.disabled_push_mirror.info=Push-ะทะตัะบะฐะปะฐ ะพัะบะปััะตะฝั ะฐะดะผะธะฝะธัััะฐัะพัะพะผ ัะฐะนัะฐ.
settings.mirror_settings.docs.no_new_mirrors=ะะฐั ัะตะฟะพะทะธัะพัะธะน ะทะตัะบะฐะปะธััะตั ะธะทะผะตะฝะตะฝะธั ะฒ ะดััะณะพะน ัะตะฟะพะทะธัะพัะธะน ะธะปะธ ะธะท ะฝะตะณะพ. ะะพะถะฐะปัะนััะฐ, ะธะผะตะนัะต ะฒ ะฒะธะดั, ััะพ ะฒ ะดะฐะฝะฝัะน ะผะพะผะตะฝั ะฝะตะฒะพะทะผะพะถะฝะพ ัะพะทะดะฐะฒะฐัั ะฝะพะฒัะต ะทะตัะบะฐะปะฐ.
settings.mirror_settings.docs.can_still_use=ะฅะพัั ะฒั ะฝะต ะผะพะถะตัะต ะธะทะผะตะฝััั ัััะตััะฒัััะธะต ะทะตัะบะฐะปะฐ ะธะปะธ ัะพะทะดะฐะฒะฐัั ะฝะพะฒัะต, ะฒั ะผะพะถะตัะต ะฟะพ-ะฟัะตะถะฝะตะผั ะธัะฟะพะปัะทะพะฒะฐัั ัััะตััะฒัััะตะต ะทะตัะบะฐะปะพ.
@@ -2068,8 +2148,8 @@ settings.mirror_settings.direction=ะะฐะฟัะฐะฒะปะตะฝะธะต
settings.mirror_settings.direction.pull=ะัะฟัะฐะฒะบะฐ
settings.mirror_settings.direction.push=ะัะฟัะฐะฒะบะฐ
settings.mirror_settings.last_update=ะะพัะปะตะดะฝะตะต ะพะฑะฝะพะฒะปะตะฝะธะต
-settings.mirror_settings.push_mirror.none=Push-ะทะตัะบะฐะปะพ ะฝะต ะดะพะฑะฐะฒะปะตะฝะพ
-settings.mirror_settings.push_mirror.remote_url=ะกััะปะบะฐ ะฝะฐ ัะดะฐะปัะฝะฝัะน git-ัะตะฟะพะทะธัะพัะธะน
+settings.mirror_settings.push_mirror.none=Push-ะทะตัะบะฐะปะฐ ะฝะต ะฝะฐัััะพะตะฝั
+settings.mirror_settings.push_mirror.remote_url=ะกััะปะบะฐ ะฝะฐ ัะดะฐะปัะฝะฝัะน Git-ัะตะฟะพะทะธัะพัะธะน
settings.mirror_settings.push_mirror.add=ะะพะฑะฐะฒะธัั push-ะทะตัะบะฐะปะพ
settings.mirror_settings.push_mirror.edit_sync_time=ะะทะผะตะฝะธัั ะธะฝัะตัะฒะฐะป ัะธะฝั
ัะพะฝะธะทะฐัะธะธ ะทะตัะบะฐะปะฐ
@@ -2078,8 +2158,8 @@ settings.push_mirror_sync_in_progress=ะะดัั ะพัะฟัะฐะฒะบะฐ ะธะทะผะตะฝะตะฝะธ
settings.site=ะกะฐะนั
settings.update_settings=ะกะพั
ัะฐะฝะธัั ะฝะฐัััะพะนะบะธ
settings.update_mirror_settings=ะะฑะฝะพะฒะธัั ะฝะฐัััะพะนะบะธ ะทะตัะบะฐะปะฐ
-settings.branches.switch_default_branch=ะะทะผะตะฝะธัั ะฒะตัะบั ะฟะพ ัะผะพะปัะฐะฝะธั
-settings.branches.update_default_branch=ะกะผะตะฝะธัั ะฒะตัะบั ะฟะพ ัะผะพะปัะฐะฝะธั
+settings.branches.switch_default_branch=ะะทะผะตะฝะธัั ะฒะตัะฒั ะฟะพ ัะผะพะปัะฐะฝะธั
+settings.branches.update_default_branch=ะกะผะตะฝะธัั ะฒะตัะฒั ะฟะพ ัะผะพะปัะฐะฝะธั
settings.branches.add_new_rule=ะะพะฑะฐะฒะธัั ะฝะพะฒะพะต ะฟัะฐะฒะธะปะพ
settings.advanced_settings=ะ ะฐััะธัะตะฝะฝัะต ะฝะฐัััะพะนะบะธ
settings.wiki_desc=ะะบะปััะธัั ะฒะธะบะธ ัะตะฟะพะทะธัะพัะธั
@@ -2087,14 +2167,14 @@ settings.use_internal_wiki=ะัะฟะพะปัะทะพะฒะฐัั ะฒัััะพะตะฝะฝัั ะฒะธะบ
settings.use_external_wiki=ะัะฟะพะปัะทะพะฒะฐัั ะฒะฝะตัะฝัั ะฒะธะบะธ
settings.external_wiki_url=ะกััะปะบะฐ ะฝะฐ ะฒะฝะตัะฝัั ะฒะธะบะธ
settings.external_wiki_url_error=URL ะฒะฝะตัะฝะตะน ะฒะธะบะธ ะฝะต ัะฒะปัะตััั ะบะพััะตะบัะฝัะผ URL.
-settings.external_wiki_url_desc=ะะพัะตัะธัะตะปะธ ะฑัะดัั ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝั ะฝะฐ URL, ะบะพะณะดะฐ ะพะฝะธ ะบะปะธะบะฝัั ะฟะพ ะฒะบะปะฐะดะบะต.
-settings.issues_desc=ะะบะปััะธัั ัะธััะตะผั ะทะฐะดะฐั
+settings.external_wiki_url_desc=ะะพัะตัะธัะตะปะธ ะฑัะดัั ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝั ะฟะพ ัะบะฐะทะฐะฝะฝะพะผั ะฐะดัะตัั ะฒะธะบะธ ะฟัะธ ะพัะบัััะธะธ ะฒะบะปะฐะดะบะธ.
+settings.issues_desc=ะะบะปััะธัั ะทะฐะดะฐัะธ
settings.use_internal_issue_tracker=ะัะฟะพะปัะทะพะฒะฐัั ะฒัััะพะตะฝะฝัั ัะธััะตะผั ะทะฐะดะฐั
settings.use_external_issue_tracker=ะัะฟะพะปัะทะพะฒะฐัั ะฒะฝะตัะฝัั ัะธััะตะผั ะทะฐะดะฐั
-settings.external_tracker_url=ะกััะปะบะฐ ะฝะฐ ะฒะฝะตัะฝัั ัะธััะตะผั ะพััะปะตะถะธะฒะฐะฝะธั ะทะฐะดะฐั
+settings.external_tracker_url=ะกััะปะบะฐ ะฝะฐ ะฒะฝะตัะฝัั ัะธััะตะผั ะทะฐะดะฐั
settings.external_tracker_url_error=URL ะฒะฝะตัะฝะตะณะพ ะฑะฐะณ-ััะตะบะตัะฐ ะฝะต ัะฒะปัะตััั ะบะพััะตะบัะฝัะผ URL.
-settings.external_tracker_url_desc=ะะพัะตัะธัะตะปะธ ะฑัะดัั ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝั ะฝะฐ URL, ะบะพะณะดะฐ ะพะฝะธ ะบะปะธะบะฝัั ะฟะพ ะฒะบะปะฐะดะบะต.
-settings.tracker_url_format=ะคะพัะผะฐั ัััะปะบะธ ะฒะฝะตัะฝะตะน ัะธััะตะผั ะพััะปะตะถะธะฒะฐะฝะธั ะทะฐะดะฐั
+settings.external_tracker_url_desc=ะะพัะตัะธัะตะปะธ ะฑัะดัั ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝั ะฟะพ ัะบะฐะทะฐะฝะฝะพะผั ะฐะดัะตัั ััะตะบะตัะฐ ะทะฐะดะฐั ะฟัะธ ะพัะบัััะธะธ ะฒะบะปะฐะดะบะธ.
+settings.tracker_url_format=ะคะพัะผะฐั ัััะปะพะบ ะฒะฝะตัะฝะตะน ัะธััะตะผั ะทะฐะดะฐั
settings.tracker_url_format_error=ะคะพัะผะฐั URL ะฒะฝะตัะฝะตะณะพ ะฑะฐะณ-ััะตะบะตัะฐ ะฝะตะบะพััะตะบัะตะฝ.
settings.tracker_issue_style=ะคะพัะผะฐั ะฝัะผะตัะฐัะธะธ ะฒะพ ะฒะฝะตัะฝะตะน ัะธััะตะผะต ะทะฐะดะฐั
settings.tracker_issue_style.numeric=ะฆะธััะพะฒะพะน
@@ -2103,27 +2183,27 @@ settings.tracker_issue_style.regexp=ะ ะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต
settings.tracker_issue_style.regexp_pattern=ะจะฐะฑะปะพะฝ ัะตะณัะปััะฝะพะณะพ ะฒััะฐะถะตะฝะธั
settings.tracker_issue_style.regexp_pattern_desc=ะะผะตััะพ {index}
ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั ะฟะตัะฒะฐั ะทะฐั
ะฒะฐัะตะฝะฝะฐั ะณััะฟะฟะฐ.
settings.tracker_url_format_desc=ะั ะผะพะถะตัะต ะธัะฟะพะปัะทะพะฒะฐัั ัะฐะฑะปะพะฝั {user}
, {repo}
ะธ {index}
ะดะปั ะธะผะตะฝะธ ะฟะพะปัะทะพะฒะฐัะตะปั, ัะตะฟะพะทะธัะพัะธั ะธ ะฝะพะผะตัะฐ ะทะฐะดะฐัะธ.
-settings.enable_timetracker=ะะบะปััะธัั ะพััะปะตะถะธะฒะฐะฝะธะต ะฒัะตะผะตะฝะธ
+settings.enable_timetracker=ะกััััะธะบ ะฒัะตะผะตะฝะธ
settings.allow_only_contributors_to_track_time=ะะพะดััะธััะฒะฐัั ะฒัะตะผั ะผะพะณัั ัะพะปัะบะพ ัะพะฐะฒัะพัั
settings.pulls_desc=ะะบะปััะธัั ะทะฐะฟัะพัั ัะปะธัะฝะธะน
settings.pulls.ignore_whitespace=ะะณะฝะพัะธัะพะฒะฐัั ะฝะตะทะฝะฐัะฐัะธะต ัะฐะทะปะธัะธั (ะฟัะพะฑะตะปั, ัะฐะฑัะปััะธั) ะฟัะธ ะฟัะพะฒะตัะบะต ัะปะธัะฝะธะน ะฝะฐ ะบะพะฝัะปะธะบัั
settings.pulls.enable_autodetect_manual_merge=ะะบะปััะธัั ะฐะฒัะพะพะฟัะตะดะตะปะตะฝะธะต ัััะฝะพะณะพ ัะปะธัะฝะธั (ะัะธะผะตัะฐะฝะธะต: ะฒ ะฝะตะบะพัะพััั
ะพัะพะฑัั
ัะปััะฐัั
ะผะพะณัั ะฒะพะทะฝะธะบะฝััั ะพัะธะฑะบะธ)
-settings.pulls.allow_rebase_update=ะะบะปััะธัั ะพะฑะฝะพะฒะปะตะฝะธะต ะฒะตัะบะธ ะธะท ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต ะฟัััะผ rebase
-settings.pulls.default_delete_branch_after_merge=ะฃะดะฐะปะธัั ะฒะตัะบั ะทะฐะฟัะพัะฐ ะฟะพัะปะต ะตะณะพ ัะปะธัะฝะธั ะฟะพ ัะผะพะปัะฐะฝะธั
+settings.pulls.allow_rebase_update=ะะบะปััะธัั ะพะฑะฝะพะฒะปะตะฝะธะต ะฒะตัะฒะธ ะธะท ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต ะฟัััะผ rebase
+settings.pulls.default_delete_branch_after_merge=ะฃะดะฐะปะธัั ะฒะตัะฒั ะทะฐะฟัะพัะฐ ะฟะพัะปะต ะตะณะพ ัะปะธัะฝะธั ะฟะพ ัะผะพะปัะฐะฝะธั
settings.pulls.default_allow_edits_from_maintainers=ะะพ ัะผะพะปัะฐะฝะธั ัะฐะทัะตัะฐัั ัะตะดะฐะบัะธัะพะฒะฐะฝะธะต ัะพะฟัะพะฒะพะถะดะฐััะธะผะธ
settings.releases_desc=ะะบะปััะธัั ะฒัะฟััะบะธ
settings.packages_desc=ะะบะปััะธัั ัะตะตััั ะฟะฐะบะตัะพะฒ
-settings.projects_desc=ะะบะปััะธัั ะฟัะพะตะบัั ัะตะฟะพะทะธัะพัะธั
+settings.projects_desc=ะะบะปััะธัั ะฟัะพะตะบัั
settings.actions_desc=ะะบะปััะธัั ะธะฝัะตะณัะฐัะธั ะบะพะฝะฒะตะนะตัะพะฒ CI/CD ั Forgejo Actions
settings.admin_settings=ะะฐัััะพะนะบะธ ะฐะดะผะธะฝะธัััะฐัะพัะฐ
-settings.admin_enable_health_check=ะัะพะฒะตัััั ัะตะปะพััะฝะพััั ััะพะณะพ ัะตะฟะพะทะธัะพัะธั (git fsck)
+settings.admin_enable_health_check=ะัะฟะพะปะฝััั ะฟัะพะฒะตัะบะธ ัะตะปะพััะฝะพััะธ ะดะฐะฝะฝัั
(git fsck)
settings.admin_code_indexer=ะะฝะดะตะบัะฐัะพั ะบะพะดะฐ
settings.admin_stats_indexer=ะะฝะดะตะบัะฐัะพั ััะฐัะธััะธะบะธ ะบะพะดะฐ
settings.admin_indexer_commit_sha=ะะพัะปะตะดะฝะธะน ะธะฝะดะตะบัะธัะพะฒะฐะฝะฝัะน ะบะพะผะผะธั
settings.admin_indexer_unindexed=ะะต ะธะฝะดะตะบัะธัะพะฒะฐะฝะพ
settings.reindex_button=ะะพะฑะฐะฒะธัั ะฒ ะพัะตัะตะดั ะฟะตัะตะธะฝะดะตะบัะฐัะธะธ
settings.reindex_requested=ะะตัะตะธะฝะดะตะบัะฐัะธั ะทะฐะฟัะพัะตะฝะฐ
-settings.admin_enable_close_issues_via_commit_in_any_branch=ะะฐะบัััั ะทะฐะดะฐัั ั ะฟะพะผะพััั ะบะพะผะผะธัะฐ, ัะดะตะปะฐะฝะฝะพะณะพ ะฒ ะฒะตัะบะต ะฝะต ะฟะพ ัะผะพะปัะฐะฝะธั
+settings.admin_enable_close_issues_via_commit_in_any_branch=ะะฐะบัััั ะทะฐะดะฐัั ั ะฟะพะผะพััั ะบะพะผะผะธัะฐ, ัะดะตะปะฐะฝะฝะพะณะพ ะฒ ะฒะตัะฒะธ ะฝะต ะฟะพ ัะผะพะปัะฐะฝะธั
settings.danger_zone=ะะฟะฐัะฝะฐั ะทะพะฝะฐ
settings.new_owner_has_same_repo=ะฃ ะฝะพะฒะพะณะพ ะฒะปะฐะดะตะปััะฐ ัะถะต ะตััั ัะตะฟะพะทะธัะพัะธะน ั ัะฐะบะธะผ ะฝะฐะทะฒะฐะฝะธะตะผ.
settings.convert=ะัะตะพะฑัะฐะทะพะฒะฐัั ะฒ ะพะฑััะฝัะน ัะตะฟะพะทะธัะพัะธะน
@@ -2132,7 +2212,7 @@ settings.convert_notices_1=ะญัะฐ ะพะฟะตัะฐัะธั ะฟัะตะพะฑัะฐะทัะตั ััะพ
settings.convert_confirm=ะะพะดัะฒะตัะดะธัะต ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะธะต
settings.convert_succeed=ะ ะตะฟะพะทะธัะพัะธะน ััะฟะตัะฝะพ ะฟัะตะพะฑัะฐะทะพะฒะฐะฝ ะฒ ะพะฑััะฝัะน.
settings.convert_fork=ะัะตะพะฑัะฐะทะพะฒะฐัั ะฒ ะพะฑััะฝัะน ัะตะฟะพะทะธัะพัะธะน
-settings.convert_fork_desc=ะั ะผะพะถะตัะต ะฟัะตะพะฑัะฐะทะพะฒะฐัั ััะพ ะพัะฒะตัะฒะปะตะฝะธะต ะฒ ะพะฑััะฝัะน ัะตะฟะพะทะธัะพัะธะน. ะญัะพ ะฝะต ะผะพะถะตั ะฑััั ะพัะผะตะฝะตะฝะพ.
+settings.convert_fork_desc=ะญัะพ ะพัะฒะตัะฒะปะตะฝะธะต ะผะพะถะฝะพ ะฟัะตะพะฑัะฐะทะพะฒะฐัั ะฒ ะพะฑััะฝัะน ัะตะฟะพะทะธัะพัะธะน. ะญัะพ ะดะตะนััะฒะธะต ะฝะตะฒะพะทะผะพะถะฝะพ ะพัะผะตะฝะธัั.
settings.convert_fork_notices_1=ะญัะฐ ะพะฟะตัะฐัะธั ะฟัะตะพะฑัะฐะทัะตั ััะพั ะพัะฒะตัะฒะปะตะฝะธะต ะฒ ะพะฑััะฝัะน ัะตะฟะพะทะธัะพัะธะน, ะธ ะฝะต ะผะพะถะตั ะฑััั ะพัะผะตะฝะตะฝะฐ.
settings.convert_fork_confirm=ะัะตะพะฑัะฐะทะพะฒะฐัั ัะตะฟะพะทะธัะพัะธะน
settings.convert_fork_succeed=ะัะฒะตัะฒะปะตะฝะธะต ะฟัะตะพะฑัะฐะทะพะฒะฐะฝะพ ะฒ ะพะฑััะฝัะน ัะตะฟะพะทะธัะพัะธะน.
@@ -2152,25 +2232,25 @@ settings.transfer_owner=ะะพะฒัะน ะฒะปะฐะดะตะปะตั
settings.transfer_perform=ะัะฟะพะปะฝะธัั ะฟะตัะตะดะฐัั
settings.transfer_started=ะ ะตะฟะพะทะธัะพัะธะน ะพะถะธะดะฐะตั ะฟะพะดัะฒะตัะถะดะตะฝะธั ะฟะตัะตะดะฐัะธ ะพั ยซ%sยป
settings.transfer_succeed=ะ ะตะฟะพะทะธัะพัะธะน ะฟะตัะตะฝะตััะฝ.
-settings.signing_settings=ะะฐัััะพะนะบะธ ะฟะพะดะฟะธัะธ ะฒะตัะธัะธะบะฐัะธะธ
-settings.trust_model=ะะพะดะตะปั ะดะพะฒะตัะธั ะฟะพะดะฟะธัะธ
-settings.trust_model.default=ะะพะดะตะปั ะดะพะฒะตัะธั ะฟะพ ัะผะพะปัะฐะฝะธั
-settings.trust_model.default.desc=ะัะฟะพะปัะทะพะฒะฐัั ััะฐะฝะดะฐััะฝัั ะผะพะดะตะปั ะดะพะฒะตัะธั ัะตะฟะพะทะธัะพัะธั ะดะปั ััะพะน ัััะฐะฝะพะฒะบะธ.
+settings.signing_settings=ะะฐัััะพะนะบะธ ะฟัะพะฒะตัะบะธ ะฟะพะดะฟะธัะตะน
+settings.trust_model=ะคะฐะบัะพัั ะดะพะฒะตัะธั ะฟะพะดะฟะธััะผ
+settings.trust_model.default=ะคะฐะบัะพั ะดะพะฒะตัะธั ะฟะพ ัะผะพะปัะฐะฝะธั
+settings.trust_model.default.desc=ะัะฟะพะปัะทะพะฒะฐัั ัะฐะบัะพั ะดะพะฒะตัะธั ะฟะพ ัะผะพะปัะฐะฝะธั, ะธัะฟะพะปัะทัะตะผัะน ะฝะฐ ััะพะผ ัะตัะฒะตัะต.
settings.trust_model.collaborator=ะกะพััะฐััะฝะธะบ
settings.trust_model.collaborator.long=ะกะพััะฐััะฝะธะบ: ะดะพะฒะตัััั ะฟะพะดะฟะธััะผ ัะพััะฐััะฝะธะบะพะฒ
settings.trust_model.collaborator.desc=ะะตะนััะฒะธัะตะปัะฝัะต ะฟะพะดะฟะธัะธ ัะพััะฐััะฝะธะบะพะฒ ััะพะณะพ ัะตะฟะพะทะธัะพัะธั ะฑัะดัั ะฟะพะผะตัะตะฝั ะบะฐะบ ยซะดะพะฒะตัะตะฝะฝัะตยป (ะฝะตะทะฐะฒะธัะธะผะพ ะพั ัะพะณะพ, ัะพะพัะฒะตัััะฒััั ะปะธ ะพะฝะธ ะฐะฒัะพัั ะบะพะผะผะธัะฐ). ะ ะพััะฐะปัะฝัั
ัะปััะฐัั
ะดะตะนััะฒะธัะตะปัะฝัะต ะฟะพะดะฟะธัะธ ะฑัะดัั ะฟะพะผะตัะตะฝั ะบะฐะบ ยซะฝะตะดะพะฒะตัะตะฝะฝัะตยป, ะตัะปะธ ะฟะพะดะฟะธัั ัะพะพัะฒะตัััะฒัะตั ะฐะฒัะพัั ะบะพะผะผะธัะฐ, ะธ ยซะฝะต ัะพะฒะฟะฐะดะฐััะธะตยป, ะตัะปะธ ะฝะตั.
-settings.trust_model.committer=ะะพะผะผะธัะตั
-settings.trust_model.committer.long=ะะพะผะผะธัะตั: ะดะพะฒะตัััั ะฟะพะดะฟะธััะผ, ัะพะพัะฒะตัััะฒัััะธะผ ะบะพะผะผะธัะตัะฐะผ (ัะพะพัะฒะตัััะฒัะตั GitHub ะธ ััะตะฑัะตั ะบะพะผะผะธัั, ะฟะพะดะฟะธัะฐะฝะฝัะต Forgejo, ะธะผะตัั Forgejo ะฒ ะบะฐัะตััะฒะต ะบะพะผะผะธัะตัะฐ)
+settings.trust_model.committer=ะะฒัะพั ะบะพะผะผะธัะฐ
+settings.trust_model.committer.long=ะะฒัะพั ะบะพะผะผะธัะฐ: ะดะพะฒะตัััั ะฟะพะดะฟะธััะผ, ัะพะพัะฒะตัััะฒัััะธะผ ะฐะฒัะพัะฐะผ ะบะพะผะผะธัะพะฒ. ะญัะพ ะฟะพะฒะตะดะตะฝะธะต ัะพะพัะฒะตัััะฒัะตั GitHub ะธ ััะตะฑัะตั, ััะพะฑั ะบะพะผะผะธัั, ะฟะพะดะฟะธัะฐะฝะฝัะต Forgejo, ะธะผะตะปะธ Forgejo ะฒ ะบะฐัะตััะฒะต ะฐะฒัะพัะฐ
settings.trust_model.committer.desc=ะะตะนััะฒะธัะตะปัะฝัะต ะฟะพะดะฟะธัะธ ะฑัะดัั ะฟะพะผะตัะตะฝั ยซะดะพะฒะตัะตะฝะฝัะผะธยป, ัะพะปัะบะพ ะตัะปะธ ะพะฝะธ ัะพะพัะฒะตัััะฒััั ะฐะฒัะพัั ะบะพะผะผะธัะฐ, ะฒ ะฟัะพัะธะฒะฝะพะผ ัะปััะฐะต ะพะฝะธ ะฑัะดัั ะฟะพะผะตัะตะฝั ยซะฝะต ัะพะฒะฟะฐะดะฐััะธะผะธยป. ะญัะพ ะทะฐััะฐะฒะธั Forgejo ะฑััั ะฐะฒัะพัะพะผ ะฟะพะดะฟะธัะฐะฝะฝัั
ะบะพะผะผะธัะพะฒ, ะฐ ัะฐะบัะธัะตัะบะธะน ะฐะฒัะพั ะฑัะดะตั ะพะฑะพะทะฝะฐัะตะฝ ะฒ ััะตะนะปะตัะฐั
Co-Authored-By: ะธ Co-Committed-By: ะบะพะผะผะธัะฐ. ะะปัั Forgejo ะฟะพ ัะผะพะปัะฐะฝะธั ะดะพะปะถะตะฝ ัะพะพัะฒะตัััะฒะพะฒะฐัั ะฟะพะปัะทะพะฒะฐัะตะปั ะฒ ะฑะฐะทะต ะดะฐะฝะฝัั
.
-settings.trust_model.collaboratorcommitter=ะกะพััะฐััะฝะธะบ+ะะพะผะผะธัะตั
-settings.trust_model.collaboratorcommitter.long=ะกะพััะฐััะฝะธะบ+ะะพะผะผะธัะตั: ะดะพะฒะตัััั ะฟะพะดะฟะธััะผ ัะพััะฐััะฝะธะบะพะฒ, ะบะพัะพััะต ัะพะพัะฒะตัััะฒััั ะฐะฒัะพัั ะบะพะผะผะธัะฐ
+settings.trust_model.collaboratorcommitter=ะกะพััะฐััะฝะธะบ ะธ ะฐะฒัะพั ะบะพะผะผะธัะฐ
+settings.trust_model.collaboratorcommitter.long=ะกะพััะฐััะฝะธะบ ะธ ะฐะฒัะพั ะบะพะผะผะธัะฐ: ะดะพะฒะตัััั ะฟะพะดะฟะธััะผ ัะพััะฐััะฝะธะบะพะฒ, ะบะพัะพััะต ัะพะพัะฒะตัััะฒััั ะฐะฒัะพัั ะบะพะผะผะธัะฐ
settings.trust_model.collaboratorcommitter.desc=ะะตะนััะฒะธัะตะปัะฝัะต ะฟะพะดะฟะธัะธ ัะพััะฐััะฝะธะบะพะฒ ััะพะณะพ ัะตะฟะพะทะธัะพัะธั ะฑัะดัั ะฟะพะผะตัะตะฝั ยซะดะพะฒะตัะตะฝะฝัะผะธยป, ะตัะปะธ ะพะฝะธ ัะพะพัะฒะตัััะฒััั ะฐะฒัะพัั ะบะพะผะผะธัะฐ. ะะตะนััะฒะธัะตะปัะฝัะต ะฟะพะดะฟะธัะธ ะฑัะดัั ะฟะพะผะตัะตะฝั ะบะฐะบ ยซะฝะตะดะพะฒะตัะตะฝะฝัะตยป, ะตัะปะธ ะฟะพะดะฟะธัั ัะพะพัะฒะตัััะฒัะตั ะฐะฒัะพัั ะบะพะผะผะธัะฐ, ะธ ยซะฝะต ัะพะฒะฟะฐะดะฐััะธะตยป ะฒะฟัะพัะธะฒะฝะพะผ ัะปััะฐะต. ะญัะพ ะทะฐััะฐะฒะธั Forgejo ะฑััั ะพัะผะตัะตะฝะฝัะผ ะฒ ะบะฐัะตััะฒะต ะฐะฒัะพัะฐ ะฟะพะดะฟะธัะฐะฝะฝะพะณะพ ะบะพะผะผะธัะฐ, ะฐ ัะฐะบัะธัะตัะบะธะน ะฐะฒัะพั ะฑัะดะตั ัะบะฐะทะฐะฝ ะฒ ััะตะนะปะตัะฐั
Co-Authored-By: ะธ Co-Committed-By: ะบะพะผะผะธัะฐ. ะะปัั Forgejo ะฟะพ ัะผะพะปัะฐะฝะธั ะดะพะปะถะตะฝ ัะพะพัะฒะตัััะฒะพะฒะฐัั ะฟะพะปัะทะพะฒะฐัะตะปั ะฒ ะฑะฐะทะต ะดะฐะฝะฝัั
.
settings.wiki_delete=ะกัะตัะตัั ะดะฐะฝะฝัะต ะฒะธะบะธ
settings.wiki_delete_desc=ะัะดััะต ะฒะฝะธะผะฐัะตะปัะฝั! ะะฐะบ ัะพะปัะบะพ ะฒั ัะดะฐะปะธัะต ะฒะธะบะธ โ ะฟััะธ ะฝะฐะทะฐะด ะฝะต ะฑัะดะตั.
settings.wiki_delete_notices_1=- ะญัะพ ะฑะตะทะฒะพะทะฒัะฐัะฝะพ ัะดะฐะปะธั ะธ ะพัะบะปััะธั ะฒะธะบะธ ะดะปั %s.
settings.confirm_wiki_delete=ะกัะตัะตัั ะดะฐะฝะฝัะต ะฒะธะบะธ
settings.wiki_deletion_success=ะะฐะฝะฝัะต ะฒะธะบะธ ัะตะฟะพะทะธัะพัะธั ัะดะฐะปะตะฝั.
-settings.delete=ะฃะดะฐะปะธัั ััะพั ัะตะฟะพะทะธัะพัะธะน
+settings.delete=ะฃะดะฐะปะธัั ัะตะฟะพะทะธัะพัะธะน
settings.delete_desc=ะัะดััะต ะฒะฝะธะผะฐัะตะปัะฝั! ะะฐะบ ัะพะปัะบะพ ะฒั ัะดะฐะปะธัะต ัะตะฟะพะทะธัะพัะธะน โ ะฟััะธ ะฝะฐะทะฐะด ะฝะต ะฑัะดะตั.
settings.delete_notices_1=- ะญัะฐ ะพะฟะตัะฐัะธั ะะ ะะะะะข ะฑััั ะพัะผะตะฝะตะฝะฐ.
settings.delete_notices_2=- ะญัะฐ ะพะฟะตัะฐัะธั ะฝะฐะฒัะตะณะดะฐ ัะดะฐะปะธั ะฒัั ะธะท ัะตะฟะพะทะธัะพัะธั %s , ะฒะบะปััะฐั ะดะฐะฝะฝัะต Git, ัะฒัะทะฐะฝะฝัะต ั ะฝะธะผ ะทะฐะดะฐัะธ, ะบะพะผะผะตะฝัะฐัะธะธ ะธ ะฟัะฐะฒะฐ ะดะพัััะฟะฐ ะดะปั ัะพัััะดะฝะธะบะพะฒ.
@@ -2206,7 +2286,7 @@ settings.hooks_desc=ะะตะฑ-ั
ัะบะธ ะฟะพะทะฒะพะปััั ะฒะฝะตัะฝะธะผ ัะปัะถะฑ
settings.webhook_deletion=ะฃะดะฐะปะตะฝะธะต ะฒะตะฑ-ั
ัะบะฐ
settings.webhook_deletion_desc=ะฃะดะฐะปะตะฝะธะต ััะพะณะพ ะฒะตะฑ-ั
ัะบะฐ ะฟัะธะฒะตะดะตั ะบ ัะดะฐะปะตะฝะธั ะฒัะตะน ัะฒัะทะฐะฝะฝะพะน ั ะฝะธะผ ะธะฝัะพัะผะฐัะธะธ, ะฒะบะปััะฐั ะธััะพัะธั. ะฅะพัะธัะต ะฟัะพะดะพะปะถะธัั?
settings.webhook_deletion_success=ะะตะฑ-ั
ัะบ ะฑัะป ัะดะฐะปัะฝ.
-settings.webhook.test_delivery=ะัะพะฒะตัะธัั ะดะพััะฐะฒะบั
+settings.webhook.test_delivery=ะัะพะฒะตัะธัั ะพัะฟัะฐะฒะบั
settings.webhook.test_delivery_desc=ะัะฟัะฐะฒะธัั ัะตััะพะฒะพะต ัะพะฑััะธะต ะดะปั ัะตััะธัะพะฒะฐะฝะธั ะฝะฐัััะพะนะบะธ ะฒะตะฑ-ั
ัะบะฐ.
settings.webhook.request=ะะฐะฟัะพั
settings.webhook.response=ะัะฒะตั
@@ -2220,7 +2300,7 @@ settings.githook_edit_desc=ะัะปะธ ั
ัะบ ะฝะต ะฐะบัะธะฒะตะฝ, ะฑัะดะตั ะฟะพ
settings.githook_name=ะะฐะทะฒะฐะฝะธะต ั
ัะบa
settings.githook_content=ะกะพะดะตัะถะธะผะพะต ั
ัะบะฐ
settings.update_githook=ะะฑะฝะพะฒะธัั ั
ัะบ
-settings.add_webhook_desc=Forgejo ะฑัะดะตั ะพะฟัะฐะฒะปััั POST
-ะทะฐะฟัะพัั ะฝะฐ ัะบะฐะทะฐะฝะฝัะน URL ะฐะดัะตั ั ะธะฝัะพัะผะฐัะธะตะน ะพ ะฟัะพะธัั
ะพะดััะธั
ัะพะฑััะธัั
. ะะพะดัะพะฑะฝะพััะธ ะฝะฐ ัััะฐะฝะธัะต ะธะฝััััะบัะธะธ ะฟะพ ะธัะฟะพะปัะทะพะฒะฐะฝะธั ะฒะตะฑ-ั
ัะบะพะฒ .
+settings.add_webhook_desc=Forgejo ะฑัะดะตั ะพะฟัะฐะฒะปััั POST
-ะทะฐะฟัะพัั ะฝะฐ ัะบะฐะทะฐะฝะฝัะน URL ะพะฑัะฐะฑะพััะธะบะฐ ั ัะบะฐะทะฐะฝะฝัะผ ะทะฐะณะพะปะพะฒะบะพะผ ยซContent-Typeยป. ะะพะดัะพะฑะฝะพััะธ ะดะพัััะฟะฝั ะฒ ะธะฝััััะบัะธะธ ะฟะพ ะธัะฟะพะปัะทะพะฒะฐะฝะธั ะฒะตะฑ-ั
ัะบะพะฒ .
settings.payload_url=URL ะพะฑัะฐะฑะพััะธะบะฐ
settings.http_method=HTTP-ะผะตัะพะด
settings.content_type=ะขะธะฟ ัะพะดะตัะถะธะผะพะณะพ POST
@@ -2231,69 +2311,69 @@ settings.slack_color=ะฆะฒะตั
settings.discord_username=ะะผั ะฟะพะปัะทะพะฒะฐัะตะปั
settings.discord_icon_url=URL ะธะบะพะฝะบะธ
settings.event_desc=ะกัะฐะฑะฐััะฒะฐัั ะฝะฐ:
-settings.event_push_only=ะกะพะฑััะธั ะพัะฟัะฐะฒะบะธ
+settings.event_push_only=ะกะพะฑััะธั ะพัะฟัะฐะฒะบะธ (push)
settings.event_send_everything=ะัะต ัะพะฑััะธั
-settings.event_choose=ะััะณะธะต ัะพะฑััะธัโฆ
-settings.event_header_repository=ะกะพะฑััะธั ัะตะฟะพะทะธัะพัะธั
-settings.event_create=ะกะพะทะดะฐัั
-settings.event_create_desc=ะะตัะบะฐ ะธะปะธ ััะณ ัะพะทะดะฐะฝั.
-settings.event_delete=ะฃะดะฐะปะธัั
-settings.event_delete_desc=ะะตัะบะฐ ะธะปะธ ัะตะณ ัะดะฐะปะตะฝั.
+settings.event_choose=ะัะฑัะฐะฝะฝัะต ัะพะฑััะธัโฆ
+settings.event_header_repository=ะกะพะฑััะธั ัะตะฟะพะทะธัะพัะธะตะฒ
+settings.event_create=ะกะพะทะดะฐะฝะธะต
+settings.event_create_desc=ะกะพะทะดะฐะฝะธะต ะฒะตัะฒะตะน ะธ ัะตะณะพะฒ.
+settings.event_delete=ะฃะดะฐะปะตะฝะธะต
+settings.event_delete_desc=ะฃะดะฐะปะตะฝะธะต ะฒะตัะฒะตะน ะธ ัะตะณะพะฒ.
settings.event_fork=ะัะฒะตัะฒะปะตะฝะธะต
-settings.event_fork_desc=ะัะฒะตัะฒะปะตะฝะธะต ัะพะทะดะฐะฝะพ.
+settings.event_fork_desc=ะกะพะทะดะฐะฝะธะต ะพัะฒะตัะฒะปะตะฝะธะน ัะตะฟะพะทะธัะพัะธะตะฒ.
settings.event_wiki=ะะธะบะธ
-settings.event_wiki_desc=ะกััะฐะฝะธัะฐ ะฒะธะบะธ ัะพะทะดะฐะฝะฐ, ะฟะตัะตะธะผะตะฝะพะฒะฐะฝะฐ, ะธะทะผะตะฝะตะฝะฐ ะธะปะธ ัะดะฐะปะตะฝะฐ.
+settings.event_wiki_desc=ะกะพะทะดะฐะฝะธะต, ะฟะตัะตะธะผะตะฝะพะฒะฐะฝะธะต, ะธะทะผะตะฝะตะฝะธะต ะธ ัะดะฐะปะตะฝะธะต ัััะฐะฝะธั ะฒะธะบะธ.
settings.event_release=ะัะฟััะบ
-settings.event_release_desc=ะัะฟััะบ ะพะฟัะฑะปะธะบะพะฒะฐะฝ, ะพะฑะฝะพะฒะปัะฝ ะธะปะธ ัะดะฐะปัะฝ ะธะท ัะตะฟะพะทะธัะพัะธั.
-settings.event_push=ะัะฟัะฐะฒะบะฐ
-settings.event_push_desc=ะัะฟัะฐะฒะบะฐ ะฒ ัะตะฟะพะทะธัะพัะธะน.
+settings.event_release_desc=ะัะฑะปะธะบะฐัะธั, ะธะทะผะตะฝะตะฝะธะต ะธ ัะดะฐะปะตะฝะธะต ะฒัะฟััะบะพะฒ.
+settings.event_push=ะัะฟัะฐะฒะบะฐ ะธะทะผะตะฝะตะฝะธะน
+settings.event_push_desc=ะัะฟัะฐะฒะบะฐ ะธะทะผะตะฝะตะฝะธะน ะฒ ัะตะฟะพะทะธัะพัะธะน ัะตัะตะท Git.
settings.event_repository=ะ ะตะฟะพะทะธัะพัะธะน
-settings.event_repository_desc=ะ ะตะฟะพะทะธัะพัะธะน ัะพะทะดะฐะฝ ะธะปะธ ัะดะฐะปะตะฝ.
+settings.event_repository_desc=ะกะพะทะดะฐะฝะธะต ะธ ัะดะฐะปะตะฝะธะต ัะตะฟะพะทะธัะพัะธะตะฒ.
settings.event_header_issue=ะกะพะฑััะธั ะทะฐะดะฐั
-settings.event_issues=ะะฐะดะฐัะธ
-settings.event_issues_desc=ะะฐะดะฐัะฐ ะพัะบัััะฐ, ะทะฐะบัััะฐ, ะฟะตัะตะพัะบัััะฐ ะธะปะธ ะพััะตะดะฐะบัะธัะพะฒะฐะฝะฐ.
-settings.event_issue_assign=ะะฐะทะฝะฐัะตะฝะธะต ะทะฐะดะฐั
-settings.event_issue_assign_desc=ะะฐะดะฐัะฐ ะฝะฐะทะฝะฐัะตะฝะฐ ะธะปะธ ัะฝััะฐ ั ะฝะฐะทะฝะฐัะตะฝะธั.
-settings.event_issue_label=ะะทะผะตะฝะตะฝะธะต ะผะตัะพะบ ะทะฐะดะฐั
-settings.event_issue_label_desc=ะะตัะบะธ ะทะฐะดะฐั ะพะฑะฝะพะฒะปะตะฝั ะธะปะธ ะพัะธัะตะฝั.
-settings.event_issue_milestone=ะะพะฑะฐะฒะปะตะฝะธะต ะทะฐะดะฐั ะฒ ััะฐะฟั
-settings.event_issue_milestone_desc=ะญัะฐะฟ ะธะปะธ ััะฐะฟ ะฒัะฟะพะปะฝะตะฝะธั ะทะฐะดะฐะฝะธั.
-settings.event_issue_comment=ะะพะผะผะตะฝัะฐัะธะธ ะฒ ะทะฐะดะฐัะต
-settings.event_issue_comment_desc=ะะพะผะผะตะฝัะฐัะธะน ัะพะทะดะฐะฝ, ะธะทะผะตะฝัะฝ ะธะปะธ ัะดะฐะปัะฝ.
+settings.event_issues=ะะทะผะตะฝะตะฝะธะต
+settings.event_issues_desc=ะกะพะทะดะฐะฝะธะต, ะทะฐะบัััะธะต, ะฟะตัะตะพัะบัััะธะต ะธ ะธะทะผะตะฝะตะฝะธะต ะทะฐะดะฐั.
+settings.event_issue_assign=ะะฐะทะฝะฐัะตะฝะธะต
+settings.event_issue_assign_desc=ะัะดะฐัะฐ ะธ ัะฝััะธะต ะฝะฐะทะฝะฐัะตะฝะธั ะทะฐะดะฐัะธ.
+settings.event_issue_label=ะะตัะบะธ
+settings.event_issue_label_desc=ะะพะฑะฐะฒะปะตะฝะธะต ะธ ัะดะฐะปะตะฝะธะต ะผะตัะพะบ ะทะฐะดะฐั.
+settings.event_issue_milestone=ะญัะฐะฟั
+settings.event_issue_milestone_desc=ะะพะฑะฐะฒะปะตะฝะธะต ะทะฐะดะฐั ะฒ ััะฐะฟั, ัะดะฐะปะตะฝะธะต ะธ ะธะทะผะตะฝะตะฝะธะต.
+settings.event_issue_comment=ะะพะผะผะตะฝัะฐัะธะธ
+settings.event_issue_comment_desc=ะะพะฑะฐะฒะปะตะฝะธะต, ะธะทะผะตะฝะตะฝะธะต ะธ ัะดะฐะปะตะฝะธะต ะบะพะผะผะตะฝัะฐัะธะตะฒ ะฒ ะทะฐะดะฐัะฐั
.
settings.event_header_pull_request=ะกะพะฑััะธั ะทะฐะฟัะพัะพะฒ ัะปะธัะฝะธะน
-settings.event_pull_request=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต
-settings.event_pull_request_desc=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะพัะบััั, ะทะฐะบััั, ะฟะตัะตะพัะบััั ะธะปะธ ะพััะตะดะฐะบัะธัะพะฒะฐะฝ.
-settings.event_pull_request_assign=ะะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต ะฝะฐะทะฝะฐัะตะฝ
-settings.event_pull_request_assign_desc=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฝะฐะทะฝะฐัะตะฝ ะธะปะธ ะฝะต ะฝะฐะทะฝะฐัะตะฝ.
-settings.event_pull_request_label=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะพัะผะตัะตะฝ
-settings.event_pull_request_label_desc=ะะตัะบะธ ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต ะพะฑะฝะพะฒะปะตะฝั ะธะปะธ ะพัะธัะตะฝั.
-settings.event_pull_request_milestone=ะญัะฐะฟ ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต ะทะฐะฒะตััะตะฝ
-settings.event_pull_request_milestone_desc=ะญัะฐะฟ ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต ะธะปะธ ะฟัะพะผะตะถััะพัะฝัะน ัะฐะณ.
-settings.event_pull_request_comment=ะะพะผะผะตะฝัะฐัะธะน ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต
-settings.event_pull_request_comment_desc=ะะพะผะผะตะฝัะฐัะธะน ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต ัะพะทะดะฐะฝ, ะพััะตะดะฐะบัะธัะพะฒะฐะฝ ะธะปะธ ัะดะฐะปัะฝ.
-settings.event_pull_request_review=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ัะฐััะผะพััะตะฝ
-settings.event_pull_request_review_desc=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ััะฒะตัะถะดะตะฝ, ะพัะบะปะพะฝัะฝ ะธะปะธ ะพััะฐะฒะปะตะฝ ะบะพะผะผะตะฝัะฐัะธะน.
-settings.event_pull_request_sync=ะกะธะฝั
ัะพะฝะธะทะฐัะธั ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต
-settings.event_pull_request_sync_desc=ะะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐะฝ.
-settings.event_pull_request_review_request=ะะฐะฟัะพัะตะฝะฐ ัะตัะตะฝะทะธั ะดะปั ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต
-settings.event_pull_request_review_request_desc=ะกะพะทะดะฐะฝ ะธะปะธ ัะดะฐะปัะฝ ะทะฐะฟัะพั ะฝะฐ ัะตัะตะฝะทะธั ะดะปั ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต.
+settings.event_pull_request=ะะทะผะตะฝะตะฝะธะต
+settings.event_pull_request_desc=ะกะพะทะดะฐะฝะธะต, ะทะฐะบัััะธะต, ะฟะตัะตะพัะบัััะธะต ะธ ะธะทะผะตะฝะตะฝะธะต ะทะฐะฟัะพัะพะฒ ัะปะธัะฝะธั.
+settings.event_pull_request_assign=ะะฐะทะฝะฐัะตะฝะธะต
+settings.event_pull_request_assign_desc=ะัะดะฐัะฐ ะธ ัะฝััะธะต ะฝะฐะทะฝะฐัะตะฝะธั ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต.
+settings.event_pull_request_label=ะะตัะบะธ
+settings.event_pull_request_label_desc=ะะพะฑะฐะฒะปะตะฝะธะต ะธ ัะดะฐะปะตะฝะธะต ะผะตัะพะบ ะทะฐะฟัะพัะฐ ัะปะธัะฝะธั.
+settings.event_pull_request_milestone=ะญัะฐะฟั
+settings.event_pull_request_milestone_desc=ะะพะฑะฐะฒะปะตะฝะธะต ะทะฐะฟัะพัะพะฒ ัะปะธัะฝะธั ะฒ ััะฐะฟั, ัะดะฐะปะตะฝะธะต ะธ ะธะทะผะตะฝะตะฝะธะต.
+settings.event_pull_request_comment=ะะพะผะผะตะฝัะฐัะธะธ
+settings.event_pull_request_comment_desc=ะะพะฑะฐะฒะปะตะฝะธะต, ะธะทะผะตะฝะตะฝะธะต ะธ ัะดะฐะปะตะฝะธะต ะบะพะผะผะตะฝัะฐัะธะตะฒ ะฒ ะทะฐะฟัะพัะฐั
ะฝะฐ ัะปะธัะฝะธะต.
+settings.event_pull_request_review=ะ ะตัะตะฝะทะธะธ
+settings.event_pull_request_review_desc=ะะทะผะตะฝะตะฝะธั ะฒ ะทะฐะฟัะพัะต ัะปะธัะฝะธั ะพะดะพะฑัะตะฝั, ะพัะบะปะพะฝะตะฝั ะฟัะพะบะพะผะผะตะฝัะธัะพะฒะฐะฝั.
+settings.event_pull_request_sync=ะกะธะฝั
ัะพะฝะธะทะฐัะธั
+settings.event_pull_request_sync_desc=ะะตัะฒั ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐะฝะฐ ั ัะตะปะตะฒะพะน ะฒะตัะฒัั ะฐะฒัะพะผะฐัะธัะตัะบะธ.
+settings.event_pull_request_review_request=ะะฐะฟัะพัั ัะตัะตะฝะทะธะน
+settings.event_pull_request_review_request_desc=ะกะพะทะดะฐะฝะธะต ะธ ะพัะผะตะฝะฐ ะทะฐะฟัะพัะพะฒ ัะตัะตะฝะทะธะน ะฒ ะทะฐะฟัะพัะฐั
ัะปะธัะฝะธะน.
settings.event_pull_request_approvals=ะะดะพะฑัะตะฝะธั ะทะฐะฟัะพัะพะฒ ัะปะธัะฝะธะน
settings.event_pull_request_merge=ะกะปะธัะฝะธะต ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต
settings.event_package=ะะฐะบะตัั
settings.event_package_desc=ะะฐะบะตั ัะพะทะดะฐะฝ ะธะปะธ ัะดะฐะปะตะฝ ะฒ ัะตะฟะพะทะธัะพัะธะธ.
-settings.branch_filter=ะคะธะปััั ะฒะตัะพะบ
-settings.branch_filter_desc=ะะตะปัะน ัะฟะธัะพะบ ะฒะตัะฒะตะน ะดะปั ัะพะฑััะธะน Push, ัะพะทะดะฐะฝะธั ะฒะตัะฒะตะน ะธ ัะดะฐะปะตะฝะธั ะฒะตัะฒะตะน, ัะบะฐะทะฐะฝะฝัั
ะฒ ะฒะธะดะต ะณะปะพะฑ-ัะฐะฑะปะพะฝะฐ. ะัะปะธ ะฟัััะพะน ะธะปะธ *
, ัะพ ะฒัะต ัะพะฑััะธะน ะดะปั ะฒัะตั
ะฒะตัะฒะตะน ะฑัะดัั ะทะฐัะตะณะธัััะธัะพะฒะฐะฝั. ะะตัะตะนะดะธัะต ะฟะพ ัััะปะบะต github.com/gobwas/glob ะฝะฐ ะดะพะบัะผะตะฝัะฐัะธั ะฟะพ ัะธะฝัะฐะบัะธัั. ะัะธะผะตัั: master
, {master,release*}
.
+settings.branch_filter=ะคะธะปััั ะฒะตัะฒะตะน
+settings.branch_filter_desc=ะะตะปัะน ัะฟะธัะพะบ ะฒะตัะฒะตะน ะดะปั ัะพะฑััะธะน Push, ัะพะทะดะฐะฝะธั ะฒะตัะฒะตะน ะธ ัะดะฐะปะตะฝะธั ะฒะตัะฒะตะน, ัะบะฐะทะฐะฝะฝัั
ะฒ ะฒะธะดะต ะณะปะพะฑ-ัะฐะฑะปะพะฝะฐ. ะัะปะธ ะฟัััะพะน ะธะปะธ *
, ัะพ ะฒัะต ัะพะฑััะธะน ะดะปั ะฒัะตั
ะฒะตัะฒะตะน ะฑัะดัั ะทะฐัะตะณะธัััะธัะพะฒะฐะฝั. ะะตัะตะนะดะธัะต ะฟะพ ัััะปะบะต %[2]s ะฝะฐ ะดะพะบัะผะตะฝัะฐัะธั ะฟะพ ัะธะฝัะฐะบัะธัั. ะัะธะผะตัั: master
, {master,release*}
.
settings.authorization_header=ะะฐะณะพะปะพะฒะพะบ ะฐะฒัะพัะธะทะฐัะธะธ
settings.authorization_header_desc=ะัะดะตั ะฒะบะปัััะฝ ะฒ ะบะฐัะตััะฒะต ะทะฐะณะพะปะพะฒะบะฐ ะฐะฒัะพัะธะทะฐัะธะธ ะดะปั ะทะฐะฟัะพัะพะฒ. ะัะธะผะตัั: %s.
-settings.active=ะะบัะธะฒะฝัะน
+settings.active=ะะบัะธะฒะตะฝ
settings.active_helper=ะะฝัะพัะผะฐัะธั ะพ ะฟัะพะธัั
ะพะดััะธั
ัะพะฑััะธัั
ะฑัะดะตั ะพัะฟัะฐะฒะปััััั ะฝะฐ URL ััะพะณะพ ะฒะตะฑ-ั
ัะบะฐ.
settings.add_hook_success=ะะตะฑ-ั
ัะบ ะดะพะฑะฐะฒะปะตะฝ.
settings.update_webhook=ะะฑะฝะพะฒะธัั ะฒะตะฑ-ั
ัะบ
settings.update_hook_success=ะะตะฑ-ั
ัะบ ะพะฑะฝะพะฒะปัะฝ.
settings.delete_webhook=ะฃะดะฐะปะธัั ะฒะตะฑ-ั
ัะบ
-settings.recent_deliveries=ะะตะดะฐะฒะฝะธะต ัะฐัััะปะบะธ
-settings.hook_type=ะขะธะฟ ั
ัะบะฐ
-settings.slack_token=Slack ัะพะบะตะฝ
+settings.recent_deliveries=ะะตะดะฐะฒะฝะธะต ะพัะฟัะฐะฒะบะธ
+settings.hook_type=ะขะธะฟ ะฒะตะฑ-ั
ัะบะฐ
+settings.slack_token=ะขะพะบะตะฝ
settings.slack_domain=ะะพะผะตะฝ
settings.slack_channel=ะะฐะฝะฐะป
settings.add_web_hook_desc=ะะฝัะตะณัะธััะนัะต %s ั ััะธะผ ัะตะฟะพะทะธัะพัะธะตะผ .
@@ -2328,79 +2408,79 @@ settings.add_key_success=ะะปัั ัะฐะทะฒััััะฒะฐะฝะธั ยซ%sยป ะดะพะฑะฐะฒะป
settings.deploy_key_deletion=ะฃะดะฐะปะธัั ะบะปัั ัะฐะทะฒััััะฒะฐะฝะธั
settings.deploy_key_deletion_desc=ะฃะดะฐะปะตะฝะธะต ะบะปััะฐ ัะฐะทะฒััััะฒะฐะฝะธั ัะดะตะปะฐะตั ะฝะตะฒะพะทะผะพะถะฝัะผ ะดะพัััะฟ ะบ ัะตะฟะพะทะธัะพัะธั ั ะตะณะพ ะฟะพะผะพััั. ะั ัะฒะตัะตะฝั?
settings.deploy_key_deletion_success=ะะปัั ัะฐะทะฒััััะฒะฐะฝะธั ัะดะฐะปัะฝ.
-settings.branches=ะะตัะบะธ
-settings.protected_branch=ะะฐัะธัะฐ ะฒะตัะพะบ
+settings.branches=ะะตัะฒะธ
+settings.protected_branch=ะะฐัะธัะฐ ะฒะตัะฒะตะน
settings.protected_branch.save_rule=ะกะพั
ัะฐะฝะธัั ะฟัะฐะฒะธะปะพ
settings.protected_branch.delete_rule=ะฃะดะฐะปะธัั ะฟัะฐะฒะธะปะพ
settings.protected_branch_can_push=ะ ะฐะทัะตัะธัั ะพัะฟัะฐะฒะบั?
settings.protected_branch_can_push_yes=ะั ะผะพะถะตัะต ะฒัะฟะพะปะฝััั ะพัะฟัะฐะฒะบั
settings.protected_branch_can_push_no=ะั ะฝะต ะผะพะถะตัะต ะฒัะฟะพะปะฝััั ะพัะฟัะฐะฒะบั
-settings.branch_protection=ะัะฐะฒะธะปะฐ ะดะพัััะฟะฐ ะฒะตัะบะธ ยซ%s ยป
-settings.protect_this_branch=ะะฐัะธัะธัั ััั ะฒะตัะบั
-settings.protect_this_branch_desc=ะัะตะดะพัะฒัะฐัะฐะตั ัะดะฐะปะตะฝะธะต, ะพะณัะฐะฝะธัะธะฒะฐะตั Push ะธ ัะปะธัะฝะธะต Git ะฒ ะฒะตัะบั.
+settings.branch_protection=ะัะฐะฒะธะปะฐ ะดะพัััะฟะฐ ะฒะตัะฒะธ ยซ%s ยป
+settings.protect_this_branch=ะะฐัะธัะธัั ััั ะฒะตัะฒั
+settings.protect_this_branch_desc=ะัะตะดะพัะฒัะฐัะฐะตั ัะดะฐะปะตะฝะธะต, ะพะณัะฐะฝะธัะธะฒะฐะตั Push ะธ ัะปะธัะฝะธะต Git ะฒ ะฒะตัะฒั.
settings.protect_disable_push=ะะฐะฟัะตัะธัั ะพัะฟัะฐะฒะบั ะธะทะผะตะฝะตะฝะธะน
-settings.protect_disable_push_desc=ะัะฟัะฐะฒะบะฐ ะฝะต ะฑัะดะตั ัะฐะทัะตัะตะฝะฐ ะฒ ััั ะฒะตัะบั.
+settings.protect_disable_push_desc=ะัะฟัะฐะฒะบะฐ ะฒ ััั ะฒะตัะฒั ะฝะต ะฑัะดะตั ัะฐะทัะตัะตะฝะฐ.
settings.protect_enable_push=ะ ะฐะทัะตัะธัั ะพัะฟัะฐะฒะบั ะธะทะผะตะฝะตะฝะธะน
-settings.protect_enable_push_desc=ะัะฑะพะผั, ั ะบะพะณะพ ะตััั ะดะพัััะฟ ะฝะฐ ะทะฐะฟะธัั, ะฑัะดะตั ัะฐะทัะตัะตะฝะฐ ะพัะฟัะฐะฒะบะฐ ะธะทะผะตะฝะตะฝะธะน ะฒ ััั ะฒะตัะบั (ะฝะพ ะฝะต ะฟัะธะฝัะดะธัะตะปัะฝะฐั ะพัะฟัะฐะฒะบะฐ).
+settings.protect_enable_push_desc=ะัะฑะพะผั, ั ะบะพะณะพ ะตััั ะดะพัััะฟ ะฝะฐ ะทะฐะฟะธัั, ะฑัะดะตั ัะฐะทัะตัะตะฝะฐ ะพัะฟัะฐะฒะบะฐ ะธะทะผะตะฝะตะฝะธะน ะฒ ััั ะฒะตัะฒั (ะฝะพ ะฝะต ะฟัะธะฝัะดะธัะตะปัะฝะฐั ะพัะฟัะฐะฒะบะฐ).
settings.protect_enable_merge=ะ ะฐะทัะตัะธัั ัะปะธัะฝะธะต ะธะทะผะตะฝะตะฝะธะน
-settings.protect_enable_merge_desc=ะัะต, ั ะบะพะณะพ ะตััั ะดะพัััะฟ ะฝะฐ ะทะฐะฟะธัั, ัะผะพะณัั ัะดะพะฒะปะตัะฒะพัััั ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต ะฒ ััั ะฒะตัะบั.
+settings.protect_enable_merge_desc=ะัะต, ั ะบะพะณะพ ะตััั ะดะพัััะฟ ะฝะฐ ะทะฐะฟะธัั, ัะผะพะณัั ัะดะพะฒะปะตัะฒะพัััั ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต ะฒ ััั ะฒะตัะฒั.
settings.protect_whitelist_committers=ะะณัะฐะฝะธัะตะฝะธะต ะพัะฟัะฐะฒะบะธ ะฟะพ ะฑะตะปะพะผั ัะฟะธัะบั
-settings.protect_whitelist_committers_desc=ะขะพะปัะบะพ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะธะปะธ ะบะพะผะฐะฝะดะฐะผ ะธะท ะฑะตะปะพะณะพ ัะฟะธัะบะฐ ะฑัะดะตั ัะฐะทัะตัะตะฝะฐ ะพัะฟัะฐะฒะบะฐ ะธะทะผะตะฝะตะฝะธะน ะฒ ััั ะฒะตัะบั (ะฝะพ ะฝะต ะฟัะธะฝัะดะธัะตะปัะฝะฐั ะพัะฟัะฐะฒะบะฐ).
+settings.protect_whitelist_committers_desc=ะขะพะปัะบะพ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะธะปะธ ะบะพะผะฐะฝะดะฐะผ ะธะท ะฑะตะปะพะณะพ ัะฟะธัะบะฐ ะฑัะดะตั ัะฐะทัะตัะตะฝะฐ ะพัะฟัะฐะฒะบะฐ ะธะทะผะตะฝะตะฝะธะน ะฒ ััั ะฒะตัะฒั (ะฝะพ ะฝะต ะฟัะธะฝัะดะธัะตะปัะฝะฐั ะพัะฟัะฐะฒะบะฐ).
settings.protect_whitelist_deploy_keys=ะะตะปัะน ัะฟะธัะพะบ ัะฐะทะฒััััะฒะฐะตะผัั
ะบะปััะตะน ั ะดะพัััะฟะพะผ ะฝะฐ ะทะฐะฟะธัั ะฒ push.
-settings.protect_whitelist_users=ะะพะปัะทะพะฒะฐัะตะปะธ, ะบะพัะพััะต ะผะพะณัั ะพัะฟัะฐะฒะปััั ะธะทะผะตะฝะตะฝะธั ะฒ ััั ะฒะตัะบั:
+settings.protect_whitelist_users=ะะพะปัะทะพะฒะฐัะตะปะธ, ะบะพัะพััะต ะผะพะณัั ะพัะฟัะฐะฒะปััั ะธะทะผะตะฝะตะฝะธั ะฒ ััั ะฒะตัะฒั
settings.protect_whitelist_search_users=ะะพะธัะบ ะฟะพะปัะทะพะฒะฐัะตะปะตะนโฆ
-settings.protect_whitelist_teams=ะะพะผะฐะฝะดั, ัะปะตะฝั ะบะพัะพััั
ะผะพะณัั ะพัะฟัะฐะฒะปััั ะธะทะผะตะฝะตะฝะธั ะฒ ััั ะฒะตัะบั:
+settings.protect_whitelist_teams=ะะพะผะฐะฝะดั, ัะปะตะฝั ะบะพัะพััั
ะผะพะณัั ะพัะฟัะฐะฒะปััั ะธะทะผะตะฝะตะฝะธั ะฒ ััั ะฒะตัะฒั
settings.protect_whitelist_search_teams=ะะพะธัะบ ะบะพะผะฐะฝะดโฆ
settings.protect_merge_whitelist_committers=ะะณัะฐะฝะธัะธัั ะฟัะฐะฒะพ ะฝะฐ ัะปะธัะฝะธะต ะฑะตะปัะผ ัะฟะธัะบะพะผ
-settings.protect_merge_whitelist_committers_desc=ะ ะฐะทัะตัะธัั ะฟัะธะฝะธะผะฐัั ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต ะฒ ััั ะฒะตัะบั ัะพะปัะบะพ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะธ ะบะพะผะฐะฝะดะฐะผ ะธะท ยซะฑะตะปะพะณะพ ัะฟะธัะบะฐยป.
-settings.protect_merge_whitelist_users=ะะพะปัะทะพะฒะฐัะตะปะธ ั ะฟัะฐะฒะพะผ ะฝะฐ ัะปะธัะฝะธะต:
-settings.protect_merge_whitelist_teams=ะะพะผะฐะฝะดั, ัะปะตะฝั ะบะพัะพััั
ะพะฑะปะฐะดะฐัั ะฟัะฐะฒะพะผ ะฝะฐ ัะปะธัะฝะธะต:
-settings.protect_check_status_contexts=ะะบะปััะธัั ะฟัะพะฒะตัะบั ััะฐัััะฐ
-settings.protect_status_check_patterns=ะจะฐะฑะปะพะฝั ะฟัะพะฒะตัะบะธ ัะพััะพัะฝะธั:
+settings.protect_merge_whitelist_committers_desc=ะ ะฐะทัะตัะธัั ะฟัะธะฝะธะผะฐัั ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต ะฒ ััั ะฒะตัะฒั ัะพะปัะบะพ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะธ ะบะพะผะฐะฝะดะฐะผ ะธะท ยซะฑะตะปะพะณะพ ัะฟะธัะบะฐยป.
+settings.protect_merge_whitelist_users=ะะพะปัะทะพะฒะฐัะตะปะธ ั ะฟัะฐะฒะพะผ ะฝะฐ ัะปะธัะฝะธะต
+settings.protect_merge_whitelist_teams=ะะพะผะฐะฝะดั, ัะปะตะฝั ะบะพัะพััั
ะพะฑะปะฐะดะฐัั ะฟัะฐะฒะพะผ ะฝะฐ ัะปะธัะฝะธะต
+settings.protect_check_status_contexts=ะะบะปััะธัั ะฟัะพะฒะตัะบั ัะพััะพัะฝะธั
+settings.protect_status_check_patterns=ะจะฐะฑะปะพะฝั ะฟัะพะฒะตัะบะธ ัะพััะพัะฝะธั
settings.protect_status_check_patterns_desc=ะะพะฑะฐะฒััะต ัะฐะฑะปะพะฝั, ััะพะฑั ัะบะฐะทะฐัั, ะบะฐะบะธะต ะฟัะพะฒะตัะบะธ ัะพััะพัะฝะธั ะดะพะปะถะฝั ะฑััั ะฟัะพะนะดะตะฝั, ะฟัะตะถะดะต ัะตะผ ะฒะตัะฒะธ ะผะพะณัั ะฑััั ะพะฑัะตะดะธะฝะตะฝั ะฒ ะฒะตัะฒั, ัะพะพัะฒะตัััะฒััััั ััะพะผั ะฟัะฐะฒะธะปั. ะ ะบะฐะถะดะพะน ัััะพะบะต ัะบะฐะทัะฒะฐะตััั ัะฐะฑะปะพะฝ. ะจะฐะฑะปะพะฝั ะฝะต ะผะพะณัั ะฑััั ะฟััััะผะธ.
-settings.protect_check_status_contexts_desc=ะขัะตะฑัะตััั ะฟัะพะนัะธ ะฟัะพะฒะตัะบั ัะพััะพัะฝะธั ะฟะตัะตะด ัะปะธัะฝะธะตะผ. ะัะฑะตัะธัะต, ะบะฐะบะธะต ะฟัะพะฒะตัะบะธ ัะพััะพัะฝะธั ะดะพะปะถะฝั ะฑััั ะฟัะพะนะดะตะฝั, ะฟัะตะถะดะต ัะตะผ ะฒะตัะฒะธ ะผะพะถะฝะพ ะฑัะดะตั ะพะฑัะตะดะธะฝะธัั ะฒ ะฒะตัะฒั, ัะพะพัะฒะตัััะฒััััั ััะพะผั ะฟัะฐะฒะธะปั. ะัะปะธ ััะพั ะฟะฐัะฐะผะตัั ะฒะบะปััะตะฝ, ะบะพะผะผะธัั ัะฝะฐัะฐะปะฐ ะดะพะปะถะฝั ะฑััั ะฟะตัะตะผะตัะตะฝั ะฒ ะดััะณัั ะฒะตัะฒั, ะฐ ะทะฐัะตะผ ะพะฑัะตะดะธะฝะตะฝั ะธะปะธ ะฟะตัะตะผะตัะตะฝั ะฝะตะฟะพััะตะดััะฒะตะฝะฝะพ ะฒ ะฒะตัะฒั, ัะพะพัะฒะตัััะฒััััั ััะพะผั ะฟัะฐะฒะธะปั, ะฟะพัะปะต ะฟัะพั
ะพะถะดะตะฝะธั ะฟัะพะฒะตัะบะธ ัะพััะพัะฝะธั. ะัะปะธ ะบะพะฝัะตะบััั ะฝะต ะฒัะฑัะฐะฝั, ัะพ ะฟะพัะปะตะดะฝะธะน ะบะพะผะผะธั ะดะพะปะถะตะฝ ะฑััั ััะฟะตัะฝัะผ ะฒะฝะต ะทะฐะฒะธัะธะผะพััะธ ะพั ะบะพะฝัะตะบััะฐ.
+settings.protect_check_status_contexts_desc=ะขัะตะฑะพะฒะฐัั ััะฟะตัะฝะตะต ะฟัะพั
ะพะถะดะตะฝะธะต ะฟัะพะฒะตัะพะบ ะฟะตัะตะด ัะปะธัะฝะธะตะผ. ะะพะผะผะธัั ัะฝะฐัะฐะปะฐ ะดะพะปะถะฝั ะฑัะดัั ะฑััั ะฟะตัะตะผะตัะตะฝั ะฒ ะดััะณัั ะฒะตัะฒั, ะฐ ะทะฐัะตะผ ะพะฑัะตะดะธะฝะตะฝั ะธะปะธ ะฟะตัะตะผะตัะตะฝั ะฝะตะฟะพััะตะดััะฒะตะฝะฝะพ ะฒ ะฒะตัะฒั, ัะพะพัะฒะตัััะฒััััั ััะพะผั ะฟัะฐะฒะธะปั, ะฟะพัะปะต ะฟัะพั
ะพะถะดะตะฝะธั ะฟัะพะฒะตัะบะธ ัะพััะพัะฝะธั. ะัะปะธ ะฝะตั ัะพะพัะฒะตัััะฒัััะธั
ะบะพะฝัะตะบััะพะฒ, ัะพ ะฟะพัะปะตะดะฝะธะน ะบะพะผะผะธั ะดะพะปะถะตะฝ ะฑััั ััะฟะตัะฝัะผ ะฒะฝะต ะทะฐะฒะธัะธะผะพััะธ ะพั ะบะพะฝัะตะบััะฐ.
settings.protect_check_status_contexts_list=ะัะพะฒะตัะบะธ ัะพััะพัะฝะธั ะทะฐ ะฟะพัะปะตะดะฝัั ะฝะตะดะตะปั ะดะปั ััะพะณะพ ัะตะฟะพะทะธัะพัะธั
settings.protect_status_check_matched=ะกะพะฒะฟะฐะปะพ
settings.protect_invalid_status_check_pattern=ะะตะฒะตัะฝัะน ัะฐะฑะปะพะฝ ะฟัะพะฒะตัะบะธ ัะพััะพัะฝะธั: ยซ%sยป.
settings.protect_no_valid_status_check_patterns=ะะตั ะดะพะฟัััะธะผัั
ัะฐะฑะปะพะฝะพะฒ ะฟัะพะฒะตัะบะธ ัะพััะพัะฝะธั.
-settings.protect_required_approvals=ะะตะพะฑั
ะพะดะธะผัะต ะพะดะพะฑัะตะฝะธั:
+settings.protect_required_approvals=ะะตะพะฑั
ะพะดะธะผัะต ะพะดะพะฑัะตะฝะธั
settings.protect_required_approvals_desc=ะ ะฐะทัะตัะธัั ะฟัะธะฝััะธะต ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต ัะพะปัะบะพ ั ะดะพััะฐัะพัะฝัะผ ะบะพะปะธัะตััะฒะพะผ ะฟะพะปะพะถะธัะตะปัะฝัั
ะพัะทัะฒะพะฒ.
settings.protect_approvals_whitelist_enabled=ะะณัะฐะฝะธัะธัั ััะฒะตัะถะดะตะฝะธั ะฑะตะปัะผ ัะฟะธัะบะพะผ ะฟะพะปัะทะพะฒะฐัะตะปะตะน ะธะปะธ ะบะพะผะฐะฝะด
settings.protect_approvals_whitelist_enabled_desc=ะขะพะปัะบะพ ะพัะทัะฒั ะฟะพะปัะทะพะฒะฐัะตะปะตะน ะธะปะธ ะบะพะผะฐะฝะด ะธะท ะฑะตะปะพะณะพ ัะฟะธัะบะฐ ะฑัะดัั ะทะฐััะธัะฐะฝั ะดะพ ััะตะฑัะตะผัั
ััะฒะตัะถะดะตะฝะธะน. ะะตะปัะน ัะฟะธัะพะบ ะฑะตะท ะพะดะพะฑัะตะฝะธั ะพัะทัะฒะพะฒ ะพั ะฒัะตั
, ั ะบะพะณะพ ะตััั ะบะพะปะธัะตััะฒะพ ะฟัะฐะฒ ะฝะฐ ะทะฐะฟะธัั, ะบ ััะตะฑัะตะผัะผ ััะฒะตัะถะดะตะฝะธัะผ.
-settings.protect_approvals_whitelist_users=ะ ะตัะตะฝะทะตะฝัั ะฒ ะฑะตะปะพะผ ัะฟะธัะบะต:
-settings.protect_approvals_whitelist_teams=ะะพะผะฐะฝะดั ะฒ ะฑะตะปะพะผ ัะฟะธัะบะต ะดะปั ัะตัะตะฝะทะธัะพะฒะฐะฝะธั:
+settings.protect_approvals_whitelist_users=ะะพะฟััะตะฝะฝัะต ัะตัะตะฝะทะตะฝัั
+settings.protect_approvals_whitelist_teams=ะะพะฟััะตะฝะฝัะต ะบ ัะตัะตะฝะทะธัะพะฒะฐะฝะธั ะบะพะผะฐะฝะดั
settings.dismiss_stale_approvals=ะัะบะปะพะฝะธัั ัััะฐัะตะฒัะธะต ัะฐะทัะตัะตะฝะธั
-settings.dismiss_stale_approvals_desc=ะะพะณะดะฐ ะฝะพะฒัะต ะบะพะผะผะธัั, ะธะทะผะตะฝัััะธะต ัะพะดะตัะถะธะผะพะต ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต, ะพัะฟัะฐะฒะปััััั ะฒ ะฒะตัะบั, ััะฐััะต ัะฐะทัะตัะตะฝะธั ะฑัะดัั ะพัะบะปะพะฝะตะฝั.
+settings.dismiss_stale_approvals_desc=ะะพะณะดะฐ ะฝะพะฒัะต ะบะพะผะผะธัั, ะธะทะผะตะฝัััะธะต ัะพะดะตัะถะธะผะพะต ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต, ะพัะฟัะฐะฒะปััััั ะฒ ะฒะตัะฒั, ััะฐััะต ัะฐะทัะตัะตะฝะธั ะฑัะดัั ะพัะบะปะพะฝะตะฝั.
settings.require_signed_commits=ะขัะตะฑะพะฒะฐัั ะฟะพะดะฟะธัั ะบะพะผะผะธัะพะฒ
-settings.require_signed_commits_desc=ะัะบะปะพะฝะธัั ะพัะฟัะฐะฒะบั ะธะทะผะตะฝะตะฝะธะน ะฒ ััั ะฒะตัะบั, ะตัะปะธ ะพะฝะธ ะฝะต ะฟะพะดะฟะธัะฐะฝั ะธะปะธ ะฝะต ะฟัะพะฒะตััะตะผั.
-settings.protect_branch_name_pattern=ะจะฐะฑะปะพะฝ ะฝะฐะทะฒะฐะฝะธะน ะทะฐัะธััะฝะฝัั
ะฒะตัะพะบ
-settings.protect_branch_name_pattern_desc=ะจะฐะฑะปะพะฝั ะฝะฐะทะฒะฐะฝะธะน ะทะฐัะธััะฝะฝัั
ะฒะตัะพะบ. ะ ัะธะฝัะฐะบัะธัะต ัะฐะฑะปะพะฝะพะฒ ัะธัะฐะนัะต ะฒ ะดะพะบัะผะตะฝัะฐัะธะธ . ะัะธะผะตัั: main, release/**
+settings.require_signed_commits_desc=ะัะบะปะพะฝะธัั ะพัะฟัะฐะฒะบั ะธะทะผะตะฝะตะฝะธะน ะฒ ััั ะฒะตัะฒั, ะตัะปะธ ะพะฝะธ ะฝะต ะฟะพะดะฟะธัะฐะฝั ะธะปะธ ะฝะต ะฟัะพะฒะตััะตะผั.
+settings.protect_branch_name_pattern=ะจะฐะฑะปะพะฝ ะฝะฐะทะฒะฐะฝะธะน ะทะฐัะธััะฝะฝัั
ะฒะตัะฒะตะน
+settings.protect_branch_name_pattern_desc=ะจะฐะฑะปะพะฝั ะฝะฐะทะฒะฐะฝะธะน ะทะฐัะธััะฝะฝัั
ะฒะตัะฒะตะน. ะ ัะธะฝัะฐะบัะธัะต ัะฐะฑะปะพะฝะพะฒ ัะธัะฐะนัะต ะฒ ะดะพะบัะผะตะฝัะฐัะธะธ . ะัะธะผะตัั: main, release/**
settings.protect_patterns=ะจะฐะฑะปะพะฝั
-settings.protect_protected_file_patterns=ะจะฐะฑะปะพะฝั ะทะฐัะธััะฝะฝัั
ัะฐะนะปะพะฒ, ัะฐะทะดะตะปัะฝะฝัะต ัะพัะบะพะน ั ะทะฐะฟััะพะน ยซ;ยป:
-settings.protect_protected_file_patterns_desc=ะะฐัะธัะตะฝะฝัะต ัะฐะนะปั ะฝะตะปัะทั ะธะทะผะตะฝะธัั ะฝะฐะฟััะผัั, ะดะฐะถะต ะตัะปะธ ะฟะพะปัะทะพะฒะฐัะตะปั ะธะผะตะตั ะฟัะฐะฒะพ ะดะพะฑะฐะฒะปััั, ัะตะดะฐะบัะธัะพะฒะฐัั ะธะปะธ ัะดะฐะปััั ัะฐะนะปั ะฒ ััะพะน ะฒะตัะบะต. ะะพะถะฝะพ ัะบะฐะทะฐัั ะฝะตัะบะพะปัะบะพ ัะฐะฑะปะพะฝะพะฒ, ัะฐะทะดะตะปัั ะธั
ัะพัะบะพะน ั ะทะฐะฟััะพะน (ยซ;ยป). ะ ัะธะฝัะฐะบัะธัะต ัะฐะฑะปะพะฝะพะฒ ัะธัะฐะนัะต ะฒ ะดะพะบัะผะตะฝัะฐัะธะธ github.com/gobwas/glob . ะัะธะผะตัั: .drone.yml
, /docs/**/*.txt
.
-settings.protect_unprotected_file_patterns=ะจะฐะฑะปะพะฝั ะฝะตะทะฐัะธััะฝะฝัั
ัะฐะนะปะพะฒ, ัะฐะทะดะตะปัะฝะฝัะต ัะพัะบะพะน ั ะทะฐะฟััะพะน ยซ;ยป:
-settings.protect_unprotected_file_patterns_desc=ะะตะทะฐัะธัะตะฝะฝัะต ัะฐะนะปั, ะบะพัะพััะต ะดะพะฟััะบะฐะตััั ะธะทะผะตะฝััั ะฝะฐะฟััะผัั, ะตัะปะธ ะฟะพะปัะทะพะฒะฐัะตะปั ะธะผะตะตั ะฟัะฐะฒะพ ะฝะฐ ะทะฐะฟะธัั, ะฝะตัะผะพััั ะฝะฐ ะพะณัะฐะฝะธัะตะฝะธะต ะพัะฟัะฐะฒะบะธ ะธะทะผะตะฝะตะฝะธะน. ะะพะถะฝะพ ัะบะฐะทะฐัั ะฝะตัะบะพะปัะบะพ ัะฐะฑะปะพะฝะพะฒ, ัะฐะทะดะตะปัั ะธั
ัะพัะบะพะน ั ะทะฐะฟััะพะน (ยซ;ยป). ะ ัะธะฝัะฐะบัะธัะต ัะฐะฑะปะพะฝะพะฒ ัะธัะฐะนัะต ะฒ ะดะพะบัะผะตะฝัะฐัะธะธ github.com/gobwas/glob . ะัะธะผะตัั: .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns=ะจะฐะฑะปะพะฝั ะทะฐัะธััะฝะฝัั
ัะฐะนะปะพะฒ, ัะฐะทะดะตะปัะฝะฝัะต ัะพัะบะพะน ั ะทะฐะฟััะพะน ยซ;ยป
+settings.protect_protected_file_patterns_desc=ะะฐัะธัะตะฝะฝัะต ัะฐะนะปั ะฝะตะปัะทั ะธะทะผะตะฝะธัั ะฝะฐะฟััะผัั, ะดะฐะถะต ะตัะปะธ ะฟะพะปัะทะพะฒะฐัะตะปั ะธะผะตะตั ะฟัะฐะฒะพ ะดะพะฑะฐะฒะปััั, ัะตะดะฐะบัะธัะพะฒะฐัั ะธะปะธ ัะดะฐะปััั ัะฐะนะปั ะฒ ััะพะน ะฒะตัะฒะธ. ะะพะถะฝะพ ัะบะฐะทะฐัั ะฝะตัะบะพะปัะบะพ ัะฐะฑะปะพะฝะพะฒ, ัะฐะทะดะตะปัั ะธั
ัะพัะบะพะน ั ะทะฐะฟััะพะน (ยซ;ยป). ะ ัะธะฝัะฐะบัะธัะต ัะฐะฑะปะพะฝะพะฒ ัะธัะฐะนัะต ะฒ ะดะพะบัะผะตะฝัะฐัะธะธ %s . ะัะธะผะตัั: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns=ะจะฐะฑะปะพะฝั ะฝะตะทะฐัะธััะฝะฝัั
ัะฐะนะปะพะฒ, ัะฐะทะดะตะปัะฝะฝัะต ัะพัะบะพะน ั ะทะฐะฟััะพะน ยซ;ยป
+settings.protect_unprotected_file_patterns_desc=ะะตะทะฐัะธัะตะฝะฝัะต ัะฐะนะปั, ะบะพัะพััะต ะดะพะฟััะบะฐะตััั ะธะทะผะตะฝััั ะฝะฐะฟััะผัั, ะตัะปะธ ะฟะพะปัะทะพะฒะฐัะตะปั ะธะผะตะตั ะฟัะฐะฒะพ ะฝะฐ ะทะฐะฟะธัั, ะฝะตัะผะพััั ะฝะฐ ะพะณัะฐะฝะธัะตะฝะธะต ะพัะฟัะฐะฒะบะธ ะธะทะผะตะฝะตะฝะธะน. ะะพะถะฝะพ ัะบะฐะทะฐัั ะฝะตัะบะพะปัะบะพ ัะฐะฑะปะพะฝะพะฒ, ัะฐะทะดะตะปัั ะธั
ัะพัะบะพะน ั ะทะฐะฟััะพะน (ยซ;ยป). ะ ัะธะฝัะฐะบัะธัะต ัะฐะฑะปะพะฝะพะฒ ัะธัะฐะนัะต ะฒ ะดะพะบัะผะตะฝัะฐัะธะธ %[2]s . ะัะธะผะตัั: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=ะะบะปััะธัั ะทะฐัะธัั
settings.delete_protected_branch=ะัะบะปััะธัั ะทะฐัะธัั
settings.update_protect_branch_success=ะัะฐะฒะธะปะฐ ะดะพัััะฟะฐ ะฒะตัะพะบ ยซ%sยป ะธะทะผะตะฝะตะฝะฐ.
settings.remove_protected_branch_success=ะัะฐะฒะธะปะฐ ะดะพัััะฟะฐ ะฒะตัะพะบ ยซ%sยป ัะดะฐะปะตะฝะฐ.
-settings.remove_protected_branch_failed=ะะต ัะดะฐะปะพัั ัะดะฐะปะธัั ะฟัะฐะฒะธะปะพ ะดะพัััะฟะฐ ะฒะตัะพะบ ยซ%sยป.
-settings.protected_branch_deletion=ะัะบะปััะตะฝะธะต ะทะฐัะธัั ะฒะตัะบะธ
-settings.protected_branch_deletion_desc=ะัะฑะพะน ะฟะพะปัะทะพะฒะฐัะตะปั ั ัะฐะทัะตัะตะฝะธัะผะธ ะฝะฐ ะทะฐะฟะธัั ัะผะพะถะตั ะฒัะฟะพะปะฝััั push ะฒ ััั ะฒะตัะบั. ะั ัะฒะตัะตะฝั?
+settings.remove_protected_branch_failed=ะะต ัะดะฐะปะพัั ัะดะฐะปะธัั ะฟัะฐะฒะธะปะพ ะดะพัััะฟะฐ ะฒะตัะฒะตะน ยซ%sยป.
+settings.protected_branch_deletion=ะฃะดะฐะปะตะฝะธะต ะฟัะฐะฒะธะปะฐ ะทะฐัะธัั ะฒะตัะฒะตะน
+settings.protected_branch_deletion_desc=ะัะฑะพะน ะฟะพะปัะทะพะฒะฐัะตะปั ั ัะฐะทัะตัะตะฝะธัะผะธ ะฝะฐ ะทะฐะฟะธัั ัะผะพะถะตั ะฒัะฟะพะปะฝััั push ะฒ ััั ะฒะตัะฒั. ะั ัะฒะตัะตะฝั?
settings.block_rejected_reviews=ะะปะพะบะธัะพะฒะบะฐ ัะปะธัะฝะธั ะฟะพ ะพัะบะปะพะฝะตะฝะฝัะผ ะพัะทัะฒะฐะผ
settings.block_rejected_reviews_desc=ะกะปะธัะฝะธะต ะฑัะดะตั ะฝะตะฒะพะทะผะพะถะฝะพ, ะตัะปะธ ะพัะธัะธะฐะปัะฝัะผะธ ัะตัะตะฝะทะตะฝัะฐะผะธ ะฑัะดัั ะทะฐะฟัะพัะตะฝั ะธะทะผะตะฝะตะฝะธั, ะดะฐะถะต ะตัะปะธ ะธะผะตะตััั ะดะพััะฐัะพัะฝะพะต ะบะพะปะธัะตััะฒะพ ะพะดะพะฑัะตะฝะธะน.
settings.block_on_official_review_requests=ะะปะพะบะธัะพะฒะฐัั ัะปะธัะฝะธะต ะฟัะธ ะทะฐะฟัะพัะฐั
ะฝะฐ ะพัะธัะธะฐะปัะฝะพะต ัะฐััะผะพััะตะฝะธะต
settings.block_on_official_review_requests_desc=ะกะปะธัะฝะธะต ะฝะตะฒะพะทะผะพะถะฝะพ, ะตัะปะธ ะฝะต ะธะผะตะตััั ะดะพััะฐัะพัะฝะพะต ะบะพะปะธัะตััะฒะพ ะพะดะพะฑัะตะฝะธะน ะพัะธัะธะฐะปัะฝัั
ะฟัะตะดััะฐะฒะธัะตะปะตะน.
settings.block_outdated_branch=ะะปะพะบะธัะพะฒะฐัั ัะปะธัะฝะธะต, ะตัะปะธ ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ัััะฐัะตะป
settings.block_outdated_branch_desc=ะกะปะธัะฝะธะต ะฑัะดะตั ะฝะตะฒะพะทะผะพะถะฝะพ, ะตัะปะธ ะณะพะปะพะฒะฝะฐั ะฒะตัะฒั ะฝะฐั
ะพะดะธััั ะฟะพะทะฐะดะธ ะฑะฐะทะพะฒะพะน ะฒะตัะฒะธ.
-settings.default_branch_desc=ะะปะฐะฒะฝะฐั ะฒะตัะบะฐ ัะฒะปัะตััั "ะฑะฐะทะพะฒะพะน" ะดะปั ะฒะฐัะตะณะพ ัะตะฟะพะทะธัะพัะธั, ะฝะฐ ะบะพัะพััั ะฟะพ ัะผะพะปัะฐะฝะธั ะฝะฐะฟัะฐะฒะปะตะฝั ะฒัะต ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต ะธ ะบะพัะพัะฐั ัะฒะปัะตััั ะปะธัะพะผ ะฒะฐัะตะณะพ ัะตะฟะพะทะธัะพัะธั. ะะตัะฒะพะต, ััะพ ัะฒะธะดะธั ะฟะพัะตัะธัะตะปั โ ััะพ ัะพะดะตัะถะธะผะพะต ะณะปะฐะฒะฝะพะน ะฒะตัะบะธ. ะัะฑะตัะธัะต ะตั ะธะท ัะถะต ัััะตััะฒัััะธั
:
+settings.default_branch_desc=ะะปะฐะฒะฝะฐั ะฒะตัะฒั ัะฒะปัะตััั "ะฑะฐะทะพะฒะพะน" ะดะปั ะฒะฐัะตะณะพ ัะตะฟะพะทะธัะพัะธั, ะฝะฐ ะบะพัะพััั ะฟะพ ัะผะพะปัะฐะฝะธั ะฝะฐะฟัะฐะฒะปะตะฝั ะฒัะต ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต ะธ ะบะพัะพัะฐั ัะฒะปัะตััั ะปะธัะพะผ ะฒะฐัะตะณะพ ัะตะฟะพะทะธัะพัะธั. ะะตัะฒะพะต, ััะพ ัะฒะธะดะธั ะฟะพัะตัะธัะตะปั โ ััะพ ัะพะดะตัะถะธะผะพะต ะณะปะฐะฒะฝะพะน ะฒะตัะฒะธ. ะัะฑะตัะธัะต ะตั ะธะท ัะถะต ัััะตััะฒัััะธั
:
settings.merge_style_desc=ะกัะธะปะธ ัะปะธัะฝะธั
settings.default_merge_style_desc=ะกัะธะปั ัะปะธัะฝะธั ะฟะพ ัะผะพะปัะฐะฝะธั
-settings.choose_branch=ะัะฑะตัะธัะต ะฒะตัะบัโฆ
-settings.no_protected_branch=ะะตั ะทะฐัะธััะฝะฝัั
ะฒะตัะพะบ.
+settings.choose_branch=ะัะฑะตัะธัะต ะฒะตัะฒัโฆ
+settings.no_protected_branch=ะะตั ะทะฐัะธััะฝะฝัั
ะฒะตัะฒะตะน.
settings.edit_protected_branch=ะ ะตะดะฐะบัะธัะพะฒะฐัั
settings.protected_branch_required_rule_name=ะะตะพะฑั
ะพะดะธะผะพ ะธะผั ะดะปั ะฟัะฐะฒะธะปะฐ
-settings.protected_branch_duplicate_rule_name=ะะปั ััะพะณะพ ะฝะฐะฑะพัะฐ ะฒะตัะพะบ ัะถะต ะตััั ะฟัะฐะฒะธะปะพ
+settings.protected_branch_duplicate_rule_name=ะะปั ััะพะณะพ ะฝะฐะฑะพัะฐ ะฒะตัะฒะตะน ัะถะต ะตััั ะฟัะฐะฒะธะปะพ
settings.protected_branch_required_approvals_min=ะงะธัะปะพ ะฝะตะพะฑั
ะพะดะธะผัั
ะพะดะพะฑัะตะฝะธะน ะฝะต ะผะพะถะตั ะฑััั ะพััะธัะฐัะตะปัะฝัะผ.
settings.tags=ะขะตะณะธ
settings.tags.protection=ะะฐัะธัะฐ ัะตะณะพะฒ
@@ -2411,54 +2491,54 @@ settings.tags.protection.allowed.teams=ะ ะฐะทัะตัะตะฝะฝัะต ะบะพะผะฐะฝะดั
settings.tags.protection.allowed.noone=ะะธะบัะพ
settings.tags.protection.create=ะะพะฑะฐะฒะธัั ะฟัะฐะฒะธะปะพ
settings.tags.protection.none=ะะตั ะทะฐัะธัะตะฝะฝัั
ัะตะณะพะฒ.
-settings.bot_token=ะขะพะบะตะฝ ะดะปั ะฑะพัะฐ
+settings.bot_token=ะขะพะบะตะฝ ะฑะพัะฐ
settings.chat_id=ะะ ัะฐัะฐ
settings.matrix.homeserver_url=URL ะดะพะผะฐัะฝะตะณะพ ัะตัะฒะตัะฐ
settings.matrix.room_id=ะะ ะบะพะผะฝะฐัั
settings.matrix.message_type=ะขะธะฟ ัะพะพะฑัะตะฝะธั
-settings.archive.button=ะัั
ะธะฒะธัะพะฒะฐัั
-settings.archive.header=ะัั
ะธะฒะธัะพะฒะฐัั ััะพั ัะตะฟะพะทะธัะพัะธะน
+settings.archive.button=ะัั
ะธะฒะธัะพะฒะฐัั ัะตะฟะพะทะธัะพัะธะน
+settings.archive.header=ะัั
ะธะฒะฐัะธั ัะตะฟะพะทะธัะพัะธั
settings.archive.success=ะ ะตะฟะพะทะธัะพัะธะน ะฑัะป ััะฟะตัะฝะพ ะฐัั
ะธะฒะธัะพะฒะฐะฝ.
settings.archive.error=ะัะธะฑะบะฐ ะฟัะธ ะฟะพะฟััะบะต ะฐัั
ะธะฒะธัะพะฒะฐัั ัะตะฟะพะทะธัะพัะธะน. ะกะผะพััะธัะต ะปะพะณะธ ะดะปั ะฟะพะปััะตะฝะธั ะฟะพะดัะพะฑะฝะพััะตะน.
settings.archive.error_ismirror=ะั ะฝะต ะผะพะถะตัะต ะฟะพะผะตััะธัั ะทะตัะบะฐะปะธััะตะผัะน ัะตะฟะพะทะธัะพัะธะน ะฒ ะฐัั
ะธะฒ.
-settings.archive.branchsettings_unavailable=ะะฐัััะพะนะบะธ ะฒะตัะบะธ ะฝะตะดะพัััะฟะฝั, ะตัะปะธ ัะตะฟะพะทะธัะพัะธะน ะฐัั
ะธะฒะธัะพะฒะฐะฝ.
-settings.archive.tagsettings_unavailable=ะะฐัััะพะนะบะธ ัะตะณะพะฒ ะฝะตะดะพัััะฟะฝั, ะตัะปะธ ัะตะฟะพะทะธัะพัะธะน ะฐัั
ะธะฒะธัะพะฒะฐะฝ.
+settings.archive.branchsettings_unavailable=ะะฐัััะพะนะบะธ ะฒะตัะฒะตะน ะฝะตะดะพัััะฟะฝั ะฒ ะฐัั
ะธะฒะธัะพะฒะฐะฝะฝัั
ัะตะฟะพะทะธัะพัะธัั
.
+settings.archive.tagsettings_unavailable=ะะฐัััะพะนะบะธ ัะตะณะพะฒ ะฝะตะดะพัััะฟะฝั ะฒ ะฐัั
ะธะฒะธัะพะฒะฐะฝะฝัั
ัะตะฟะพะทะธัะพัะธัั
.
settings.unarchive.button=ะ ะฐะทะฐัั
ะธะฒะธัะพะฒะฐัั
settings.unarchive.header=ะะตัะฝััั ััะพั ัะตะฟะพะทะธัะพัะธะน ะธะท ะฐัั
ะธะฒะฐ
-settings.unarchive.text=ะ ะฐะทะฐัั
ะธะฒะธัะพะฒะฐะฝะธะต ัะตะฟะพะทะธัะพัะธั ะฒะพัััะฐะฝะพะฒะธั ะตะณะพ ัะฟะพัะพะฑะฝะพััั ะฟัะธะฝะธะผะฐัั ะธะทะผะตะฝะตะฝะธั, ะฐ ัะฐะบะถะต ะฝะพะฒัะต ะทะฐะดะฐัะธ ะธ ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต.
+settings.unarchive.text=ะ ะฐะทะฐัั
ะธะฒะฐัะธั ัะตะฟะพะทะธัะพัะธั ะฒะพัััะฐะฝะพะฒะธั ะฒะพะทะผะพะถะฝะพััั ะพัะฟัะฐะฒะปััั ะฒ ะฝะตะณะพ ะธะทะผะตะฝะตะฝะธั, ะฐ ัะฐะบะถะต ัะพะทะดะฐะฒะฐัั ะฝะพะฒัะต ะทะฐะดะฐัะธ ะธ ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต.
settings.unarchive.success=ะ ะตะฟะพะทะธัะพัะธะน ะฑัะป ััะฟะตัะฝะพ ัะฐะทะฐัั
ะธะฒะธัะพะฒะฐะฝ.
-settings.update_avatar_success=ะะฒะฐัะฐั ัะตะฟะพะทะธัะพัะธั ะพะฑะฝะพะฒะปัะฝ.
+settings.update_avatar_success=ะะฐััะธะฝะบะฐ ัะตะฟะพะทะธัะพัะธั ะธะทะผะตะฝะตะฝะฐ.
settings.lfs=LFS
settings.lfs_filelist=ะคะฐะนะปั LFS ั
ัะฐะฝัััั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ
settings.lfs_no_lfs_files=ะะตั ัะฐะนะปะพะฒ LFS ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ
settings.lfs_findcommits=ะะฐะนัะธ ะบะพะผะผะธัั
-settings.lfs_lfs_file_no_commits=ะะปั ััะพะณะพ LFS ัะฐะนะปะฐ ะฝะต ะฝะฐะนะดะตะฝะพ ะบะพะผะผะธัะพะฒ
-settings.lfs_noattribute=ะญัะพั ะฟััั ะฝะต ะธะผะตะตั ะฑะปะพะบะธััะตะผะพะณะพ ะฐััะธะฑััะฐ ะฒ ะฒะตัะบะต ะฟะพ ัะผะพะปัะฐะฝะธั
+settings.lfs_lfs_file_no_commits=ะะต ะฝะฐะนะดะตะฝั ะบะพะผะผะธัั ั ััะธะผ ัะฐะนะปะพะผ ะฒ LFS
+settings.lfs_noattribute=ะญัะพั ะฟััั ะฝะต ะธะผะตะตั ะฑะปะพะบะธััะตะผะพะณะพ ะฐััะธะฑััะฐ ะฒ ะฒะตัะฒะธ ะฟะพ ัะผะพะปัะฐะฝะธั
settings.lfs_delete=ะฃะดะฐะปะธัั ัะฐะนะป LFS ั OID %s
-settings.lfs_delete_warning=ะฃะดะฐะปะตะฝะธะต ัะฐะนะปะฐ LFS ะผะพะถะตั ะฟัะธะฒะตััะธ ะบ ะพัะธะฑะบะฐะผ ยซะพะฑัะตะบั ะฝะต ัััะตััะฒัะตัยป ะฟัะธ ะฟัะพะฒะตัะบะต. ะั ัะฒะตัะตะฝั?
+settings.lfs_delete_warning=ะฃะดะฐะปะตะฝะธะต ัะฐะนะปะฐ ะธะท LFS ะผะพะถะตั ะฟัะธะฒะตััะธ ะบ ะพัะธะฑะบะฐะผ ยซะพะฑัะตะบั ะฝะต ัััะตััะฒัะตัยป ะฟัะธ ะฟัะพะฒะตัะบะฐั
. ะั ัะพัะฝะพ ั
ะพัะธัะต ะตะณะพ ัะดะฐะปะธัั?
settings.lfs_findpointerfiles=ะะฐะนัะธ ัะฐะนะปั ัะบะฐะทะฐัะตะปั
settings.lfs_locks=ะะฐะฑะปะพะบะธัะพะฒะฐัั
settings.lfs_invalid_locking_path=ะะตะดะพะฟัััะธะผัะน ะฟััั: %s
settings.lfs_invalid_lock_directory=ะะตะฒะพะทะผะพะถะฝะพ ะทะฐะฑะปะพะบะธัะพะฒะฐัั ะบะฐัะฐะปะพะณ: %s
settings.lfs_lock_already_exists=ะะปะพะบะธัะพะฒะบะฐ ัะถะต ัััะตััะฒัะตั: %s
settings.lfs_lock=ะะฐะฑะปะพะบะธัะพะฒะฐัั
-settings.lfs_lock_path=ะััั ะบ ัะฐะนะปั ะดะปั ะฑะปะพะบะธัะพะฒะบะธ...
-settings.lfs_locks_no_locks=ะะตั ะฑะปะพะบะธัะพะฒะบะธ
-settings.lfs_lock_file_no_exist=ะะฐะฑะปะพะบะธัะพะฒะฐะฝะฝัะน ัะฐะนะป ะฝะต ัััะตััะฒัะตั ะฒ ะฒะตัะบะต ะฟะพ ัะผะพะปัะฐะฝะธั
+settings.lfs_lock_path=ะััั ะบ ัะฐะนะปั ะดะปั ะฑะปะพะบะธัะพะฒะบะธโฆ
+settings.lfs_locks_no_locks=ะะตั ะฑะปะพะบะธัะพะฒะพะบ
+settings.lfs_lock_file_no_exist=ะะฐะฑะปะพะบะธัะพะฒะฐะฝะฝัะน ัะฐะนะป ะฝะต ัััะตััะฒัะตั ะฒ ะฒะตัะฒะธ ะฟะพ ัะผะพะปัะฐะฝะธั
settings.lfs_force_unlock=ะัะธะฝัะดะธัะตะปัะฝะฐั ัะฐะทะฑะปะพะบะธัะพะฒะบะฐ
settings.lfs_pointers.found=ะะฐะนะดะตะฝะพ %d ัะบะฐะทะฐัะตะปั(ะตะน) ะฑะปะพะบะพะฒ - ะฟัะธัะพะตะดะธะฝะตะฝะพ %d, %d ะฝะต ะฟัะธะฒัะทะฐะฝะพ (%d ะพััััััะฒัะตั ะฒ ั
ัะฐะฝะธะปะธัะต)
-settings.lfs_pointers.sha=Blob SHA
+settings.lfs_pointers.sha=ะฅะตั blob'ะฐ
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=ะ ัะตะฟะพะทะธัะพัะธะธ
settings.lfs_pointers.exists=ะกััะตััะฒััั ะฒ ั
ัะฐะฝะธะปะธัะต
-settings.lfs_pointers.accessible=ะะพัััะฟะฝะพ ะดะปั ะฟะพะปัะทะพะฒะฐัะตะปั
+settings.lfs_pointers.accessible=ะะพัััะฟะฝะพ ะฟะพะปัะทะพะฒะฐัะตะปั
settings.lfs_pointers.associateAccessible=ะกะฒัะทะฐัั ะดะพัััะฟะฝัะต %d OID
-settings.rename_branch_failed_exist=ะะตะฒะพะทะผะพะถะฝะพ ะฟะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะบั, ะฟะพัะพะผั ััะพ ัะตะปะตะฒะฐั ะฒะตัะบะฐ %s ัะถะต ัััะตััะฒัะตั.
-settings.rename_branch_failed_not_exist=ะะตะฒะพะทะผะพะถะฝะพ ะฟะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะบั %s, ะฟะพัะพะผั ััะพ ะพะฝะฐ ะฝะต ัััะตััะฒัะตั.
-settings.rename_branch_success=ะะตัะบะฐ %s ะฑัะปะฐ ััะฟะตัะฝะพ ะฟะตัะตะธะผะตะฝะพะฒะฐะฝะฐ ะฒ %s.
-settings.rename_branch_from=ััะฐัะพะต ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะบะธ
-settings.rename_branch_to=ะฝะพะฒะพะต ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะบะธ
-settings.rename_branch=ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะบั
+settings.rename_branch_failed_exist=ะะตะฒะพะทะผะพะถะฝะพ ะฟะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะฒั, ะฟะพัะพะผั ััะพ ัะตะปะตะฒะฐั ะฒะตัะฒั %s ัะถะต ัััะตััะฒัะตั.
+settings.rename_branch_failed_not_exist=ะะตะฒะพะทะผะพะถะฝะพ ะฟะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะฒั %s, ะฟะพัะพะผั ััะพ ะพะฝะฐ ะฝะต ัััะตััะฒัะตั.
+settings.rename_branch_success=ะะตัะฒั %s ะฑัะปะฐ ััะฟะตัะฝะพ ะฟะตัะตะธะผะตะฝะพะฒะฐะฝะฐ ะฒ %s.
+settings.rename_branch_from=ััะฐัะพะต ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธ
+settings.rename_branch_to=ะฝะพะฒะพะต ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธ
+settings.rename_branch=ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะฒั
diff.browse_source=ะัะพัะผะพัั ะธัั
ะพะดะฝะพะณะพ ะบะพะดะฐ
diff.parent=ัะพะดะธัะตะปั
@@ -2490,11 +2570,11 @@ diff.file_suppressed=ะ ะฐะทะปะธัะธั ัะฐะนะปะพะฒ ะฝะต ะฟะพะบะฐะทะฐะฝั, ั.ะบ.
diff.file_suppressed_line_too_long=ะ ะฐะทะปะธัะธั ัะฐะนะปะพะฒ ัะบัััั, ั.ะบ. ะพะฝะธ ะฒะบะปััะฐัั ัะปะธัะบะพะผ ะดะปะธะฝะฝัะต ัััะพะบะธ
diff.too_many_files=ะะพะบะฐะทะฐะฝั ะฝะต ะฒัะต ะธะทะผะตะฝัะฝะฝัะต ัะฐะนะปั, ั.ะบ. ะธั
ัะปะธัะบะพะผ ะผะฝะพะณะพ
diff.show_more=ะะพะบะฐะทะฐัั ะฑะพะปััะต
-diff.load=ะะฐะณััะทะธัั ัะฐะทะปะธัะธั
+diff.load=ะะพะบะฐะทะฐัั ัะฐะทะปะธัะธั
diff.generated=ัะณะตะฝะตัะธัะพะฒะฐะฝะฝัะน
diff.vendored=ะฟัะตะดะพััะฐะฒะปะตะฝะฝัะน
diff.comment.placeholder=ะััะฐะฒะธัั ะบะพะผะผะตะฝัะฐัะธะน
-diff.comment.markdown_info=ะะพะดะดะตัะถะธะฒะฐะตััั ัะธะฝัะฐะบัะธั Markdown.
+diff.comment.markdown_info=ะะพะดะดะตัะถะธะฒะฐะตััั ัะพัะผะฐัะธัะพะฒะฐะฝะธะต ั Markdown.
diff.comment.add_single_comment=ะะพะฑะฐะฒะธัั ะฟัะพััะพะน ะบะพะผะผะตะฝัะฐัะธะน
diff.comment.add_review_comment=ะะพะฑะฐะฒะธัั ะบะพะผะผะตะฝัะฐัะธะน
diff.comment.start_review=ะะฐัะฐัั ัะตัะตะฝะทะธั
@@ -2525,13 +2605,13 @@ release.draft=ะงะตัะฝะพะฒะธะบ
release.prerelease=ะัะตะดะฒะฐัะธัะตะปัะฝัะน ะฒัะฟััะบ
release.stable=ะกัะฐะฑะธะปัะฝัะน
release.compare=ะกัะฐะฒะฝะธัั
-release.edit=ัะตะดะฐะบัะธัะพะฒะฐัั
+release.edit=ะ ะตะดะฐะบัะธัะพะฒะฐัั
release.ahead.commits=%d ะบะพะผะผะธัั
release.ahead.target=%s ั ััะพะณะพ ะฒัะฟััะบะฐ
tag.ahead.target=ะฒ %s ะฟะพัะปะต ััะพะณะพ ัะตะณะฐ
release.source_code=ะัั
ะพะดะฝัะน ะบะพะด
-release.new_subheader=ะะพะดัะพะฑะฝัะน ะถััะฝะฐะป ะธะทะผะตะฝะตะฝะธะน ะผะพะถะตั ะฟะพะผะพัั ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะฟะพะฝััั, ััะพ ะฑัะปะพ ะธะทะผะตะฝะตะฝะพ ะฒ ะพัะตัะตะดะฝะพะน ะฒะตััะธะธ.
-release.edit_subheader=ะะพะดัะพะฑะฝัะน ะถััะฝะฐะป ะธะทะผะตะฝะตะฝะธะน ะผะพะถะตั ะฟะพะผะพัั ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะฟะพะฝััั, ััะพ ะฑัะปะพ ะธะทะผะตะฝะตะฝะพ ะฒ ะพัะตัะตะดะฝะพะน ะฒะตััะธะธ.
+release.new_subheader=ะัะฟััะบะธ ะฟะพะผะพะณะฐัั ั ะพัะณะฐะฝะธะทะฐัะธะตะน ะธ ัะฐัะฟัะพัััะฐะฝะตะฝะธะตะผ ะฒะตััะธะน ะฟัะพะตะบัะฐ.
+release.edit_subheader=ะัะฟััะบะธ ะฟะพะผะพะณะฐัั ั ะพัะณะฐะฝะธะทะฐัะธะตะน ะธ ัะฐัะฟัะพัััะฐะฝะตะฝะธะตะผ ะฒะตััะธะน ะฟัะพะตะบัะฐ.
release.tag_name=ะะผั ัะตะณะฐ
release.target=ะฆะตะปั
release.tag_helper=ะัะฑะตัะธัะต ัััะตััะฒัััะธะน ัะตะณ, ะธะปะธ ัะพะทะดะฐะนัะต ะฝะพะฒัะน.
@@ -2563,55 +2643,55 @@ release.add_tag=ะกะพะทะดะฐัั ัะตะณ
release.releases_for=ะัะฟััะบะธ %s
release.tags_for=ะขะตะณะธ %s
-branch.name=ะะฐะทะฒะฐะฝะธะต ะฒะตัะบะธ
-branch.already_exists=ะะตัะบะฐ ั ะฝะฐะทะฒะฐะฝะธะตะผ ยซ%sยป ัะถะต ัััะตััะฒัะตั.
+branch.name=ะะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธ
+branch.already_exists=ะะตัะฒั ั ะฝะฐะทะฒะฐะฝะธะตะผ ยซ%sยป ัะถะต ัััะตััะฒัะตั.
branch.delete_head=ะฃะดะฐะปะธัั
-branch.delete=ะฃะดะฐะปะธัั ะฒะตัะบั ยซ%sยป
-branch.delete_html=ะฃะดะฐะปะธัั ะฒะตัะบั
-branch.delete_desc=ะฃะดะฐะปะตะฝะธะต ะฒะตัะบะธ ะฝะตะพะฑัะฐัะธะผะพ. ะะตัะผะพััั ะฝะฐ ัะพ, ััะพ ัะดะฐะปะตะฝะฝะฐั ะฒะตัะบะฐ ะผะพะถะตั ะฟัะพัััะตััะฒะพะฒะฐัั ะฝะตะบะพัะพัะพะต ะฒัะตะผั ะฟะตัะตะด ัะตะผ, ะบะฐะบ ะพะฝะฐ ะฑัะดะตั ะพะบะพะฝัะฐัะตะปัะฝะพ ัะดะฐะปะตะฝะฐ, ััะพ ะดะตะนััะฒะธะต ะะะะะะะะะะ ะพัะผะตะฝะธัั ะฒ ะฑะพะปััะธะฝััะฒะต ัะปััะฐะตะฒ. ะัะพะดะพะปะถะธัั?
-branch.deletion_success=ะะตัะบะฐ ยซ%sยป ัะดะฐะปะตะฝะฐ.
-branch.deletion_failed=ะะต ัะดะฐะปะพัั ัะดะฐะปะธัั ะฒะตัะบั ยซ%sยป.
-branch.delete_branch_has_new_commits=ะะตัะบั ยซ%sยป ะฝะตะปัะทั ัะดะฐะปะธัั, ะฟะพัะบะพะปัะบั ะฟะพัะปะต ัะปะธัะฝะธั ะฑัะปะธ ะดะพะฑะฐะฒะปะตะฝั ะฝะพะฒัะต ะบะพะผะผะธัั.
-branch.create_branch=ะกะพะทะดะฐัั ะฒะตัะบั %s
+branch.delete=ะฃะดะฐะปะธัั ะฒะตัะฒั ยซ%sยป
+branch.delete_html=ะฃะดะฐะปะธัั ะฒะตัะฒั
+branch.delete_desc=ะฃะดะฐะปะตะฝะธะต ะฒะตัะฒะธ ะฝะตะพะฑัะฐัะธะผะพ. ะะตัะผะพััั ะฝะฐ ัะพ, ััะพ ัะดะฐะปะตะฝะฝะฐั ะฒะตัะฒั ะผะพะถะตั ะฟัะพัััะตััะฒะพะฒะฐัั ะฝะตะบะพัะพัะพะต ะฒัะตะผั ะฟะตัะตะด ัะตะผ, ะบะฐะบ ะพะฝะฐ ะฑัะดะตั ะพะบะพะฝัะฐัะตะปัะฝะพ ัะดะฐะปะตะฝะฐ, ััะพ ะดะตะนััะฒะธะต ะะะะะะะะะะ ะพัะผะตะฝะธัั ะฒ ะฑะพะปััะธะฝััะฒะต ัะปััะฐะตะฒ. ะัะพะดะพะปะถะธัั?
+branch.deletion_success=ะะตัะฒั ยซ%sยป ัะดะฐะปะตะฝะฐ.
+branch.deletion_failed=ะะต ัะดะฐะปะพัั ัะดะฐะปะธัั ะฒะตัะฒั ยซ%sยป.
+branch.delete_branch_has_new_commits=ะะตัะฒั ยซ%sยป ะฝะตะปัะทั ัะดะฐะปะธัั, ะฟะพัะบะพะปัะบั ะฟะพัะปะต ัะปะธัะฝะธั ะฑัะปะธ ะดะพะฑะฐะฒะปะตะฝั ะฝะพะฒัะต ะบะพะผะผะธัั.
+branch.create_branch=ะกะพะทะดะฐัั ะฒะตัะฒั %s
branch.create_from=ะพั ยซ%sยป
-branch.create_success=ะะตัะบะฐ ยซ%sยป ัะพะทะดะฐะฝะฐ.
-branch.branch_already_exists=ะะตัะบะฐ ยซ%sยป ัะถะต ัััะตััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
-branch.branch_name_conflict=ะะฐะทะฒะฐะฝะธะต ะฒะตัะบะธ ยซ%sยป ะบะพะฝัะปะธะบััะตั ั ัะถะต ัััะตััะฒัััะตะน ะฒะตัะบะพะน ยซ%sยป.
-branch.tag_collision=ะะตัะบะฐ ยซ%sยป ะฝะต ะผะพะถะตั ะฑััั ัะพะทะดะฐะฝะฐ, ัะฐะบ ะบะฐะบ ัะถะต ัััะตััะฒัะตั ัะตะณ ั ัะฐะบะธะผ ะธะผะตะฝะตะผ.
+branch.create_success=ะะตัะฒั ยซ%sยป ัะพะทะดะฐะฝะฐ.
+branch.branch_already_exists=ะะตัะฒั ยซ%sยป ัะถะต ัััะตััะฒัะตั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
+branch.branch_name_conflict=ะะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธ ยซ%sยป ะบะพะฝัะปะธะบััะตั ั ัะถะต ัััะตััะฒัััะตะน ะฒะตัะฒัั ยซ%sยป.
+branch.tag_collision=ะะตัะฒั ยซ%sยป ะฝะต ะผะพะถะตั ะฑััั ัะพะทะดะฐะฝะฐ, ัะฐะบ ะบะฐะบ ัะถะต ัััะตััะฒัะตั ัะตะณ ั ัะฐะบะธะผ ะธะผะตะฝะตะผ.
branch.deleted_by=ะฃะดะฐะปัะฝ %s
-branch.restore_success=ะะตัะบะฐ ยซ%sยป ะฒะพัััะฐะฝะพะฒะปะตะฝะฐ.
-branch.restore_failed=ะะต ัะดะฐะปะพัั ะฒะพัััะฐะฝะพะฒะธัั ะฒะตัะบั ยซ%sยป.
-branch.protected_deletion_failed=ะะตัะบะฐ ยซ%sยป ะทะฐัะธัะตะฝะฐ. ะั ะฝะตะปัะทั ัะดะฐะปะธัั.
-branch.default_deletion_failed=ะะตัะบะฐ ยซ%sยป ัะฒะปัะตััั ะฒะตัะบะพะน ะฟะพ ัะผะพะปัะฐะฝะธั. ะั ะฝะตะปัะทั ัะดะฐะปะธัั.
-branch.restore=ะะพัััะฐะฝะพะฒะธัั ะฒะตัะบั ยซ%sยป
-branch.download=ะกะบะฐัะฐัั ะฒะตัะบั ยซ%sยป
-branch.rename=ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะบั ยซ%sยป
+branch.restore_success=ะะตัะฒั ยซ%sยป ะฒะพัััะฐะฝะพะฒะปะตะฝะฐ.
+branch.restore_failed=ะะต ัะดะฐะปะพัั ะฒะพัััะฐะฝะพะฒะธัั ะฒะตัะฒั ยซ%sยป.
+branch.protected_deletion_failed=ะะตัะฒั ยซ%sยป ะทะฐัะธัะตะฝะฐ. ะั ะฝะตะปัะทั ัะดะฐะปะธัั.
+branch.default_deletion_failed=ะะตัะฒั ยซ%sยป ัะฒะปัะตััั ะฒะตัะฒัั ะฟะพ ัะผะพะปัะฐะฝะธั. ะั ะฝะตะปัะทั ัะดะฐะปะธัั.
+branch.restore=ะะพัััะฐะฝะพะฒะธัั ะฒะตัะฒั ยซ%sยป
+branch.download=ะกะบะฐัะฐัั ะฒะตัะฒั ยซ%sยป
+branch.rename=ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะฒั ยซ%sยป
branch.search=ะะพะธัะบ ะฒะตัะบะธ
-branch.included_desc=ะญัะฐ ะฒะตัะบะฐ ัะฒะปัะตััั ัะฐัััั ะฒะตัะบะธ ะฟะพ ัะผะพะปัะฐะฝะธั
+branch.included_desc=ะญัะฐ ะฒะตัะฒั ัะฒะปัะตััั ัะฐัััั ะฒะตัะฒะธ ะฟะพ ัะผะพะปัะฐะฝะธั
branch.included=ะะบะปััะตะฝะพ
-branch.create_new_branch=ะกะพะทะดะฐัั ะฒะตัะบั ะธะท ะฒะตัะฒะธ:
-branch.confirm_create_branch=ะกะพะทะดะฐัั ะฒะตัะบั
-branch.warning_rename_default_branch=ะั ะฟะตัะตะธะผะตะฝะพะฒัะฒะฐะตัะต ะฒะตัะบั ะฟะพ ัะผะพะปัะฐะฝะธั.
-branch.rename_branch_to=ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะบั ยซ%sยป ะฒ:
-branch.confirm_rename_branch=ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะบั
-branch.create_branch_operation=ะกะพะทะดะฐัั ะฒะตัะบั
-branch.new_branch=ะกะพะทะดะฐัั ะฝะพะฒัั ะฒะตัะบั
-branch.new_branch_from=ะกะพะทะดะฐัั ะฝะพะฒัั ะฒะตัะบั ะธะท ยซ%sยป
-branch.renamed=ะะตัะบะฐ %s ะฑัะปะฐ ะฟะตัะตะธะผะตะฝะพะฒะฐะฝะฐ ะฒ %s.
+branch.create_new_branch=ะกะพะทะดะฐัั ะฒะตัะฒั ะธะท ะฒะตัะฒะธ:
+branch.confirm_create_branch=ะกะพะทะดะฐัั ะฒะตัะฒั
+branch.warning_rename_default_branch=ะั ะฟะตัะตะธะผะตะฝะพะฒัะฒะฐะตัะต ะฒะตัะฒั ะฟะพ ัะผะพะปัะฐะฝะธั.
+branch.rename_branch_to=ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะฒั ยซ%sยป ะฒ:
+branch.confirm_rename_branch=ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะฒั
+branch.create_branch_operation=ะกะพะทะดะฐัั ะฒะตัะฒั
+branch.new_branch=ะกะพะทะดะฐัั ะฝะพะฒัั ะฒะตัะฒั
+branch.new_branch_from=ะกะพะทะดะฐัั ะฝะพะฒัั ะฒะตัะฒั ะธะท ยซ%sยป
+branch.renamed=ะะตัะฒั %s ะฑัะปะฐ ะฟะตัะตะธะผะตะฝะพะฒะฐะฝะฐ ะฒ %s.
-tag.create_tag=ะกะพะทะดะฐัั ัะตะณ %s
+tag.create_tag=ะกะพะทะดะฐัั ัะตะณ %s
tag.create_tag_operation=ะกะพะทะดะฐัั ัะตะณ
tag.confirm_create_tag=ะกะพะทะดะฐัั ัะตะณ
tag.create_tag_from=ะกะพะทะดะฐัั ะฝะพะฒัะน ัะตะณ ะธะท ยซ%sยป
tag.create_success=ะขะตะณ ยซ%sยป ัะพะทะดะฐะฝ.
-topic.manage_topics=ะ ะตะดะฐะบัะธัะพะฒะฐัั ัะตะผะฐัะธัะตัะบะธะต ะผะตัะบะธ
+topic.manage_topics=ะะทะผะตะฝะธัั ัะตะผั
topic.done=ะกะพั
ัะฐะฝะธัั
topic.count_prompt=ะะตะปัะทั ะฒัะฑัะฐัั ะฑะพะปะตะต 25 ัะตะผ
topic.format_prompt=ะขะตะผั ะดะพะปะถะฝั ะฝะฐัะธะฝะฐัััั ั ะฑัะบะฒั ะธะปะธ ัะธััั ะธ ะผะพะณัั ัะพะดะตัะถะฐัั ะดะตัะธัั (ยซ-ยป) ะธ ัะพัะบะธ (ยซ.ยป). ะะปะธะฝะฐ ัะตะผั ะฝะต ะดะพะปะถะฝะฐ ะฟัะตะฒััะฐัั 35 ัะธะผะฒะพะปะพะฒ. ะัะต ะฑัะบะฒั ะดะพะปะถะฝั ะฑััั ัััะพัะฝัะผะธ.
-find_file.go_to_file=ะะตัะตะนัะธ ะบ ัะฐะนะปั
+find_file.go_to_file=ะะฐะนัะธ ัะฐะนะป
find_file.no_matching=ะกะพะฒะฟะฐะดะฐััะธั
ัะฐะนะปะพะฒ ะฝะต ะฝะฐะนะดะตะฝะพ
error.csv.too_large=ะะต ัะดะฐะตััั ะพัะพะฑัะฐะทะธัั ััะพั ัะฐะนะป, ะฟะพัะพะผั ััะพ ะพะฝ ัะปะธัะบะพะผ ะฑะพะปััะพะน.
@@ -2619,7 +2699,7 @@ error.csv.unexpected=ะะต ัะดะฐะตััั ะพัะพะฑัะฐะทะธัั ััะพั ัะฐะนะป,
error.csv.invalid_field_count=ะะต ัะดะฐะตััั ะพัะพะฑัะฐะทะธัั ััะพั ัะฐะนะป, ะฟะพัะพะผั ััะพ ะพะฝ ะธะผะตะตั ะฝะตะฟัะฐะฒะธะปัะฝะพะต ะบะพะปะธัะตััะฒะพ ะฟะพะปะตะน ะฒ ัััะพะบะต %d.
mirror_address_protocol_invalid = ะญัะฐ ัััะปะบะฐ ะฝะตะดะตะนััะฒะธัะตะปัะฝะฐ. ะะปั ะทะตัะบะฐะปะธัะพะฒะฐะฝะธั ะผะพะถะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั ัะพะปัะบะพ ัะฐัะฟะพะปะพะถะตะฝะธั http(s):// ะธ git:// .
fork_no_valid_owners = ะะตะฒะพะทะผะพะถะฝะพ ัะพะทะดะฐัั ะพัะฒะตัะฒะปะตะฝะธะต ััะพะณะพ ัะตะฟะพะทะธัะพัะธั, ั.ะบ. ะทะดะตัั ะฝะตั ะดะตะนััะฒัััะธั
ะฒะปะฐะดะตะปััะตะฒ.
-new_repo_helper = ะ ะตะฟะพะทะธัะพัะธะน ัะพะดะตัะถะธั ะฒัะต ัะฐะนะปั ะฟัะพะตะบัะฐ ะธ ะธััะพัะธั ะธะทะผะตะฝะตะฝะธะน. ะฃะถะต ะณะดะต-ัะพ ะตััั ัะตะฟะพะทะธัะพัะธะน? ะัะฟะพะปะฝะธัะต ะผะธะณัะฐัะธั.
+new_repo_helper = ะ ะตะฟะพะทะธัะพัะธะน ัะพะดะตัะถะธั ะฒัะต ัะฐะนะปั ะฟัะพะตะบัะฐ ะธ ะธััะพัะธั ะธะทะผะตะฝะตะฝะธะน. ะฃะถะต ะณะดะต-ัะพ ะตััั ัะตะฟะพะทะธัะพัะธะน? ะัะฟะพะปะฝะธัะต ะฟะตัะตะฝะพั .
mirror_address_url_invalid = ะญัะฐ ัััะปะบะฐ ะฝะตะดะตะนััะฒะธัะตะปัะฝะฐ. ะะตะพะฑั
ะพะดะธะผะพ ะฟัะฐะฒะธะปัะฝะพ ัะบะฐะทะฐัั ะฒัะต ัะฐััะธ ะฐะดัะตัะฐ.
issues.comment.blocked_by_user = ะั ะฝะต ะผะพะถะตัะต ะบะพะผะผะตะฝัะธัะพะฒะฐัั ะฟะพะด ััะพะน ะทะฐะดะฐัะตะน, ั.ะบ. ะฒั ะทะฐะฑะปะพะบะธัะพะฒะฐะฝั ะฒะปะฐะดะตะปััะตะผ ัะตะฟะพะทะธัะพัะธั ะธะปะธ ะฐะฒัะพัะพะผ ะทะฐะดะฐัะธ.
pulls.blocked_by_user = ะะตะฒะพะทะผะพะถะฝะพ ัะพะทะดะฐัั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ, ั.ะบ. ะฒั ะทะฐะฑะปะพะบะธัะพะฒะฐะฝั ะตะณะพ ะฒะปะฐะดะตะปััะตะผ.
@@ -2627,14 +2707,14 @@ settings.add_collaborator_blocked_our = ะะตะฒะพะทะผะพะถะฝะพ ะดะพะฑะฐะฒะธัั ั
admin.enabled_flags = ะะบะปััะตะฝะฝัะต ัะปะฐะณะธ ัะตะฟะพะทะธัะพัะธั:
admin.failed_to_replace_flags = ะะต ัะดะฐะปะพัั ะทะฐะผะตะฝะธัั ัะปะฐะณะธ ัะตะฟะพะทะธัะพัะธั
admin.flags_replaced = ะคะปะฐะณะธ ัะตะฟะพะทะธัะพัะธั ะทะฐะผะตะฝะตะฝั
-rss.must_be_on_branch = ะะตัะตะนะดะธัะต ะฝะฐ ะฒะตัะบั, ััะพะฑั ัะดะตะปะฐัั RSS-ะปะตะฝัั ะดะพัััะฟะฝะพะน.
+rss.must_be_on_branch = ะะตัะตะนะดะธัะต ะบ ะฒะตัะฒะธ, ััะพะฑั ัะดะตะปะฐัั RSS-ะปะตะฝัั ะดะพัััะฟะฝะพะน.
admin.manage_flags = ะฃะฟัะฐะฒะปะตะฝะธะต ัะปะฐะณะฐะผะธ
admin.update_flags = ะะฑะฝะพะฒะธัั ัะปะฐะณะธ
object_format = ะคะพัะผะฐั ะพะฑัะตะบัะฐ
clone_in_vscodium = ะะปะพะฝะธัะพะฒะฐัั ะฒ VSCodium
mirror_sync = ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐะฝ
blame.ignore_revs = ะัะฐะฒะบะธ ะฒ .git-blame-ignore-revs ะฟัะพะธะณะฝะพัะธัะพะฒะฐะฝั. ะะฐะถะผะธัะต ะทะดะตัั, ััะพะฑั ะพะฑะพะนัะธ ััะพั ัะฐะนะป ะธ ะฟัะพัะผะพััะตัั ะฐะฒัะพัะพะฒ ะฟะพะปะฝะพัะตะฝะฝะพ.
-issues.blocked_by_user = ะะตะฒะพะทะผะพะถะฝะพ ัะพะทะดะฐัั ะทะฐะดะฐัั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ, ั.ะบ. ะฒั ะทะฐะฑะปะพะบะธัะพะฒะฐะฝั ะตะณะพ ะฒะปะฐะดะตะปััะตะผ.
+issues.blocked_by_user = ะกะพะทะดะฐะฝะธะต ะทะฐะดะฐั ะฝะตะฒะพะทะผะพะถะฝะพ ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ, ั.ะบ. ะฒั ะทะฐะฑะปะพะบะธัะพะฒะฐะฝั ะตะณะพ ะฒะปะฐะดะตะปััะตะผ.
settings.new_owner_blocked_doer = ะั ะทะฐะฑะปะพะบะธัะพะฒะฐะฝั ะฝะพะฒัะผ ะฒะปะฐะดะตะปััะตะผ.
settings.add_collaborator_blocked_them = ะะตะฒะพะทะผะพะถะฝะพ ะดะพะฑะฐะฒะธัั ัะพััะฐััะฝะธะบะฐ, ั.ะบ. ะธะผ ะทะฐะฑะปะพะบะธัะพะฒะฐะฝ ะฒะปะฐะดะตะปะตั ัะตะฟะพะทะธัะพัะธั.
pulls.blocked_by_changed_protected_files_1 = ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะทะฐะฑะปะพะบะธัะพะฒะฐะฝ, ั.ะบ. ะธะผ ะธะทะผะตะฝัะตััั ะทะฐัะธััะฝะฝัะน ัะฐะนะป:
@@ -2643,11 +2723,11 @@ pulls.blocked_by_outdated_branch = ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะท
pulls.blocked_by_changed_protected_files_n = ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะทะฐะฑะปะพะบะธัะพะฒะฐะฝ, ั.ะบ. ะธะผ ะธะทะผะตะฝััััั ะทะฐัะธััะฝะฝัะต ัะฐะนะปั:
blame.ignore_revs.failed = ะะต ัะดะฐะปะพัั ะฟัะพะธะณะฝะพัะธัะพะฒะฐัั ะฟัะฐะฒะบะธ ะธะท .git-blame-ignore-revs .
desc.sha256 = SHA256
-archive.title = ะญัะพั ัะตะฟะพะทะธัะพัะธะน ะฐัั
ะธะฒะธัะพะฒะฐะฝ. ะั ะผะพะถะตัะต ะฟัะพัะผะฐััะธะฒะฐัั ะตะณะพ ัะพะดะตัะถะธะผะพะต ะธะปะธ ะบะปะพะฝะธัะพะฒะฐัั, ะฝะพ ะฝะต ะดะพะฑะฐะฒะปััั ะฝะพะฒัะต ะบะพะผะธัั, ะพัะบััะฒะฐัั ะทะฐะดะฐัะธ ะธะปะธ ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต.
-archive.title_date = ะก %s ััะพั ัะตะฟะพะทะธัะพัะธะน ะฐัั
ะธะฒะธัะพะฒะฐะฝ. ะั ะผะพะถะตัะต ะฟัะพัะผะฐััะธะฒะฐัั ะตะณะพ ัะพะดะตัะถะธะผะพะต ะธะปะธ ะบะปะพะฝะธัะพะฒะฐัั, ะฝะพ ะฝะต ะดะพะฑะฐะฒะปััั ะฝะพะฒัะต ะบะพะผะธัั, ะพัะบััะฒะฐัั ะทะฐะดะฐัะธ ะธะปะธ ะทะฐะฟัะพัั ะฝะฐ ัะปะธัะฝะธะต.
+archive.title = ะญัะพั ัะตะฟะพะทะธัะพัะธะน ะฐัั
ะธะฒะธัะพะฒะฐะฝ. ะั ะผะพะถะตัะต ะฟัะพัะผะฐััะธะฒะฐัั ัะพะดะตัะถะธะผะพะต ะธะปะธ ะบะปะพะฝะธัะพะฒะฐัั, ะฝะพ ะฝะต ะฒะฝะพัะธัั ะธะทะผะตะฝะตะฝะธั: ะดะพะฑะฐะฒะปััั ะบะพะผะผะธัั, ัะพะทะดะฐะฒะฐัั ะทะฐะดะฐัะธ ะธ ะทะฐะฟัะพัั ัะปะธัะฝะธะน.
+archive.title_date = ะก %s ััะพั ัะตะฟะพะทะธัะพัะธะน ะฐัั
ะธะฒะธัะพะฒะฐะฝ. ะั ะผะพะถะตัะต ะฟัะพัะผะฐััะธะฒะฐัั ัะพะดะตัะถะธะผะพะต ะธะปะธ ะบะปะพะฝะธัะพะฒะฐัั, ะฝะพ ะฝะต ะฒะฝะพัะธัั ะธะทะผะตะฝะตะฝะธั: ะดะพะฑะฐะฒะปััั ะบะพะผะผะธัั, ัะพะทะดะฐะฒะฐัั ะทะฐะดะฐัะธ ะธ ะทะฐะฟัะพัั ัะปะธัะฝะธะน.
migrate.forgejo.description = ะะตัะตะฝะตััะธ ะดะฐะฝะฝัะต ั codeberg.org ะธะปะธ ะดััะณะพะณะพ ัะตัะฒะตัะฐ Forgejo.
generated = ะกะณะตะฝะตัะธัะพะฒะฐะฝะฝัะน
-pulls.review_only_possible_for_full_diff = ะัะทัะฒ ะฒะพะทะผะพะถะตะฝ ัะพะปัะบะพ ะฟัะธ ะฟัะพัะผะพััะต ะฒัะตั
ัะฐะทะปะธัะธะน
+pulls.review_only_possible_for_full_diff = ะััะฐะฒะธัั ะพัะทัะฒ ะผะพะถะฝะพ ัะพะปัะบะพ ะฟัะธ ะฟัะพัะผะพััะต ะฒัะตั
ัะฐะทะปะธัะธะน
diff.comment.add_line_comment = ะะพะฑะฐะฒะธัั ะบะพะผะผะตะฝัะฐัะธะน ะบ ัััะพะบะต
tree_path_not_found_tag = ะััั %[1]s ะพััััััะฒัะตั ะฒ ัะตะณะต %[2]s
migrate_options_lfs_endpoint.placeholder = ะัะปะธ ะฝะต ะทะฐะฟะพะปะฝะตะฝะพ, ะบะพะฝะตัะฝะฐั ัะพัะบะฐ ะฑัะดะตั ะพะฟัะตะดะตะปะตะฝะฐ ะธะท URL ะบะปะพะฝะธัะพะฒะฐะฝะธั
@@ -2658,25 +2738,25 @@ commits.view_path = ะัะพัะผะพััะตัั ะฒ ััะพะผ ะผะพะผะตะฝัะต ะธััะพั
commits.renamed_from = ะะตัะตะธะผะตะฝะพะฒะฐะฝ ั %s
issues.due_date_not_writer = ะะปั ะพะฑะฝะพะฒะปะตะฝะธั ััะพะบะฐ ะฒัะฟะพะปะฝะตะฝะธั ะทะฐะดะฐัะธ ััะตะฑัะตััั ะฟัะฐะฒะพ ะฝะฐ ะทะฐะฟะธัั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
issues.review.outdated_description = ะก ะผะพะผะตะฝัะฐ ะดะพะฑะฐะฒะปะตะฝะธั ััะพะณะพ ะบะพะผะผะตะฝัะฐัะธั ัะพะดะตัะถะธะผะพะต ะธะทะผะตะฝะธะปะพัั
-pulls.nothing_to_compare_have_tag = ะัะฑัะฐะฝะฝัะต ะฒะตัะบะธ/ัะตะณะธ ะธะดะตะฝัะธัะฝั.
+pulls.nothing_to_compare_have_tag = ะัะฑัะฐะฝะฝัะต ะฒะตัะฒะธ/ัะตะณะธ ะธะดะตะฝัะธัะฝั.
pulls.select_commit_hold_shift_for_range = ะัะฑะตัะธัะต ะบะพะผะผะธั. ะะฐะถะผะธัะต Shift, ััะพะฑั ะฒัะฑัะฐัั ะดะธะฐะฟะฐะทะพะฝ
pulls.blocked_by_official_review_requests = ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะทะฐะฑะปะพะบะธัะพะฒะฐะฝ, ั.ะบ. ั ะฝะตะณะพ ะฝะต ั
ะฒะฐัะฐะตั ะพะดะพะฑัะตะฝะธะน ะพั ะพะดะฝะพะณะพ ะธะปะธ ะฝะตัะบะพะปัะบะธั
ะพัะธัะธะฐะปัะฝัั
ัะตัะตะฝะทะตะฝัะพะฒ.
-pulls.recently_pushed_new_branches = ะั ะพัะฟัะฐะฒะธะปะธ ะบะพะผะผะธัั ะฒ ะฒะตัะบั %[1]s %[1]s
+pulls.recently_pushed_new_branches = ะั ะพัะฟัะฐะฒะธะปะธ ะบะพะผะผะธัั ะฒ ะฒะตัะฒั %[1]s %[1]s
milestones.new_subheader = ะญัะฐะฟั ะฟะพะปะตะทะฝั ะดะปั ัะธััะตะผะฐัะธะทะฐัะธะธ ะทะฐะดะฐั ะธ ะพััะปะตะถะธะฒะฐะฝะธั ะธั
ะฒัะฟะพะปะฝะตะฝะธั.
wiki.cancel = ะัะผะตะฝะฐ
-settings.unarchive.error = ะัะธ ัะฐะทะฐัั
ะธะฒะฐัะธะธ ัะตะฟะพะทะธัะพัะธั ะฟัะพะธะทะพัะปะฐ ะพัะธะฑะบะฐ. ะะพะดัะพะฑะฝะพััะธ ะดะพัััะฟะฝั ะฒ ะปะพะณะต.
-settings.archive.mirrors_unavailable = ะะตัะบะฐะปะธัะพะฒะฐะฝะธะต ะฝะตะดะพัััะฟะฝะพ ะดะปั ะฐัั
ะธะฒะธัะพะฒะฐะฝะฝัั
ัะตะฟะพะทะธัะพัะธะตะฒ.
+settings.unarchive.error = ะัะธ ัะฐัะฟะฐะบะพะฒะบะต ัะตะฟะพะทะธัะพัะธั ะฟัะพะธะทะพัะปะฐ ะพัะธะฑะบะฐ. ะะพะดัะพะฑะฝะพััะธ ะดะพัััะฟะฝั ะฒ ะปะพะณะต.
+settings.archive.mirrors_unavailable = ะะฐัััะพะนะบะธ ะทะตัะบะฐะปะธัะพะฒะฐะฝะธั ะฝะตะดะพัััะฟะฝั ะฒ ะฐัั
ะธะฒะธัะพะฒะฐะฝะฝัั
ัะตะฟะพะทะธัะพัะธัั
.
issues.role.contributor_helper = ะ ัะตะฟะพะทะธัะพัะธะธ ะฟัะธัััััะฒััั ะบะพะผะผะธัั ะทะฐ ะฐะฒัะพัััะฒะพะผ ััะพะณะพ ะฟะพะปัะทะพะฒะฐัะตะปั.
-settings.wiki_rename_branch_main = ะะพัะผะฐะปะธะทะพะฒะฐัั ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะบะธ ะฒะธะบะธ
-settings.wiki_rename_branch_main_notices_2 = ะะฝัััะตะฝะฝัั ะฒะตัะบะฐ ะฒะธะบะธ ัะตะฟะพะทะธัะพัะธั %s ะฑัะดะตั ะฟะตัะตะธะผะตะฝะพะฒะฐะฝะฐ. ะะตัะพั
ัะฐะฝัะฝะฝัะต ะธะทะผะตะฝะตะฝะธั ะฟะพััะตะฑััั ะพะฑะฝะพะฒะปะตะฝะธั.
-settings.wiki_branch_rename_failure = ะะต ัะดะฐะปะพัั ะฝะพัะผะฐะปะธะทะพะฒะฐัั ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะบะธ ะฒะธะบะธ ัะตะฟะพะทะธัะพัะธั.
-settings.confirm_wiki_branch_rename = ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะบั ะฒะธะบะธ
+settings.wiki_rename_branch_main = ะะพัะผะฐะปะธะทะพะฒะฐัั ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธ ะฒะธะบะธ
+settings.wiki_rename_branch_main_notices_2 = ะะฝัััะตะฝะฝัั ะฒะตัะฒั ะฒะธะบะธ ัะตะฟะพะทะธัะพัะธั %s ะฑัะดะตั ะฟะตัะตะธะผะตะฝะพะฒะฐะฝะฐ. ะะตัะพั
ัะฐะฝัะฝะฝัะต ะธะทะผะตะฝะตะฝะธั ะฟะพััะตะฑััั ะพะฑะฝะพะฒะปะตะฝะธั.
+settings.wiki_branch_rename_failure = ะะต ัะดะฐะปะพัั ะฝะพัะผะฐะปะธะทะพะฒะฐัั ะฝะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธ ะฒะธะบะธ ัะตะฟะพะทะธัะพัะธั.
+settings.confirm_wiki_branch_rename = ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะตัะฒั ะฒะธะบะธ
settings.wiki_rename_branch_main_notices_1 = ะญัะฐ ะพะฟะตัะฐัะธั ะะะะะ ะะขะะะ .
-settings.wiki_rename_branch_main_desc = ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะฝัััะตะฝะฝัั ะฒะตัะบั, ะธัะฟะพะปัะทัะตะผัั ะฒะธะบะธ, ะฒ "%s". ะญัะพ ะธะทะผะตะฝะตะฝะธะต ัะฒะปัะตััั ะฟะตัะผะฐะฝะตะฝัะฝัะผ ะธ ะฝะตะพะฑัะฐัะธะผัะผ.
-settings.wiki_branch_rename_success = ะะฐะทะฒะฐะฝะธะต ะฒะตัะบะธ ะฒะธะบะธ ัะตะฟะพะทะธัะพัะธั ััะฟะตัะฝะพ ะฝะพัะผะฐะปะธะทะพะฒะฐะฝะพ.
+settings.wiki_rename_branch_main_desc = ะะตัะตะธะผะตะฝะพะฒะฐัั ะฒะฝัััะตะฝะฝัั ะฒะตัะฒั, ะธัะฟะพะปัะทัะตะผัั ะฒะธะบะธ, ะฒ "%s". ะญัะพ ะธะทะผะตะฝะตะฝะธะต ัะฒะปัะตััั ะฟะตัะผะฐะฝะตะฝัะฝัะผ ะธ ะฝะตะพะฑัะฐัะธะผัะผ.
+settings.wiki_branch_rename_success = ะะฐะทะฒะฐะฝะธะต ะฒะตัะฒะธ ะฒะธะบะธ ัะตะฟะพะทะธัะพัะธั ััะฟะตัะฝะพ ะฝะพัะผะฐะปะธะทะพะฒะฐะฝะพ.
ambiguous_runes_description = `ะญัะพั ัะฐะนะป ัะพะดะตัะถะธั ัะธะผะฒะพะปั ะฎะฝะธะบะพะดะฐ, ะบะพัะพััะต ะปะตะณะบะพ ัะฟััะฐัั ั ะฟะพั
ะพะถะธะผะธ. ะัะปะธ ัะฐะบ ะธ ะดะพะปะถะฝะพ ะฑััั, ะผะพะถะตัะต ัะฟะพะบะพะนะฝะพ ะธะณะฝะพัะธัะพะฒะฐัั ััะพ ะฟัะตะดัะฟัะตะถะดะตะฝะธะต. ะัะพะฑัะฐะทะธัั ัะธะผะฒะพะปั ะผะพะถะฝะพ ะบะฝะพะฟะบะพะน ะญะบัะฐะฝะธัะพะฒะฐะฝะธั.`
editor.invalid_commit_mail = ะะตะฟัะฐะฒะธะปัะฝะฐั ะฟะพััะฐ ะดะปั ัะพะทะดะฐะฝะธั ะบะพะผะผะธัะฐ.
-pulls.has_merged = ะกะปะธัะฝะธะต ะฝะต ัะดะฐะปะพัั: ะทะฐะฟัะพั ัะถะต ะฑัะป ัะปะธั, ะธะทะผะตะฝะตะฝะธะต ัะตะปะตะฒะพะน ะฒะตัะบะธ ะธะปะธ ะฟะพะฒัะพัะฝะพะต ัะปะธัะฝะธะต ะฝะตะฒะพะทะผะพะถะฝะพ.
+pulls.has_merged = ะกะปะธัะฝะธะต ะฝะต ัะดะฐะปะพัั: ะทะฐะฟัะพั ัะถะต ะฑัะป ัะปะธั, ะธะทะผะตะฝะตะฝะธะต ัะตะปะตะฒะพะน ะฒะตัะฒะธ ะธะปะธ ะฟะพะฒัะพัะฝะพะต ัะปะธัะฝะธะต ะฝะตะฒะพะทะผะพะถะฝะพ.
settings.enter_repo_name = ะะฒะตะดะธัะต ะธะผั ะฒะปะฐะดะตะปััะฐ ะธ ะฝะฐะทะฒะฐะฝะธะต ัะตะฟะพะทะธัะพัะธั ะบะฐะบ ัะบะฐะทะฐะฝะพ:
signing.wont_sign.error = ะะต ัะดะฐะปะพัั ะฟัะพะฒะตัะธัั ะฒะพะทะผะพะถะฝะพััั ะฟะพะดะฟะธัะฐัั ะบะพะผะผะธั.
signing.wont_sign.nokey = ะกะตัะฒะตั ะฝะต ะฟัะตะดะพััะฐะฒะปัะตั ะบะปัั ะดะปั ะฟะพะดะฟะธัะธ ะบะพะผะผะธัะฐ.
@@ -2684,14 +2764,13 @@ settings.wiki_globally_editable = ะ ะฐะทัะตัะธัั ัะตะดะฐะบัะธัะพะฒะฐะฝะธ
settings.webhook.test_delivery_desc_disabled = ะะบัะธะฒะธััะนัะต ััะพั ะฒะตะฑ-ั
ัะบ ะดะปั ะฟัะพะฒะตัะบะธ ัะตััะพะฒัะผ ัะพะฑััะธะตะผ.
commits.browse_further = ะกะผะพััะตัั ะดะฐะปะตะต
vendored = ะกัะพัะพะฝะฝะธะน
-settings.units.add_more = ะะพะฑ. ะฑะพะปััะต...
+settings.units.add_more = ะะบะป. ะฑะพะปััะต
pulls.fast_forward_only_merge_pull_request = ะขะพะปัะบะพ fast-forward
settings.units.overview = ะะฑะทะพั
-settings.units.units = ะ ะฐะทะดะตะปั ัะตะฟะพะทะธัะพัะธั
-pulls.reopen_failed.head_branch = ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฝะต ะผะพะถะตั ะฑััั ะพัะบััั ะทะฐะฝะพะฒะพ, ะฟะพัะพะผั ััะพ ะณะพะปะพะฒะฝะฐั ะฒะตัะบะฐ ะฑะพะปััะต ะฝะต ัััะตััะฒัะตั.
-pulls.reopen_failed.base_branch = ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฝะต ะผะพะถะตั ะฑััั ะพัะบััั ะทะฐะฝะพะฒะพ, ะฟะพัะพะผั ััะพ ะฑะฐะทะพะฒะฐั ะฒะตัะบะฐ ะฑะพะปััะต ะฝะต ัััะตััะฒัะตั.
+settings.units.units = ะ ะฐะทะดะตะปั
+pulls.reopen_failed.head_branch = ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฝะต ะผะพะถะตั ะฑััั ะพัะบััั ะฟะพะฒัะพัะฝะพ, ัะฐะบ ะบะฐะบ ะธัั
ะพะดะฝะฐั ะฒะตัะฒั ะฑะพะปััะต ะฝะต ัััะตััะฒัะตั.
+pulls.reopen_failed.base_branch = ะญัะพั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต ะฝะต ะผะพะถะตั ะฑััั ะพัะบััั ะทะฐะฝะพะฒะพ, ะฟะพัะพะผั ััะพ ะฑะฐะทะพะฒะฐั ะฒะตัะฒั ะฑะพะปััะต ะฝะต ัััะตััะฒัะตั.
settings.ignore_stale_approvals = ะะณะฝะพัะธัะพะฒะฐัั ัััะฐัะตะฒัะธะต ะพะดะพะฑัะตะฝะธั
-contributors.contribution_type.commits = ะะพะผะผะธัั
contributors.contribution_type.additions = ะะพะฑะฐะฒะปะตะฝะธั
contributors.contribution_type.deletions = ะฃะดะฐะปะตะฝะธั
contributors.contribution_type.filter_label = ะะธะด ะดะตััะตะปัะฝะพััะธ:
@@ -2701,33 +2780,33 @@ pulls.made_using_agit = AGit
activity.navbar.contributors = ะกะพะฐะฒัะพัั
activity.navbar.code_frequency = ะงะฐััะพัะฐ ะธะทะผะตะฝะตะฝะธะน
activity.navbar.recent_commits = ะะตะดะฐะฒะฝะธะต ะบะพะผะผะธัั
-settings.confirmation_string = ะะพะดัะฒะตัะถะดะตะฝะธะต
+settings.confirmation_string = ะกััะพะบะฐ ะฟะพะดัะฒะตัะถะดะตะฝะธั
settings.archive.text = ะัั
ะธะฒะฐัะธั ัะตะฟะพะทะธัะพัะธั ัะดะตะปะฐะตั ะฒัั ะตะณะพ ัะพะดะตัะถะธะผะพะต ะดะพัััะฟะฝัะผ ัะพะปัะบะพ ะดะปั ััะตะฝะธั. ะะฝ ะฑัะดะตั ัะบััั ั ะดะพะผะฐัะฝะตะณะพ ัะบัะฐะฝะฐ. ะะธะบัะพ (ะฒะบะปััะฐั ะฒะฐั!) ะฝะต ัะผะพะถะตั ะดะพะฑะฐะฒะปััั ะบะพะผะผะธัั, ะพัะบััะฒะฐัั ะทะฐะดะฐัะธ ะธ ะทะฐะฟัะพัั ัะปะธัะฝะธะน.
release.deletion_desc = ะฃะดะฐะปะตะฝะธะต ะฒัะฟััะบะฐ ัะดะฐะปัะตั ะตะณะพ ัะพะปัะบะพ ะฒ Forgejo. ะญัะพ ะดะตะนััะฒะธะต ะฝะต ะทะฐััะพะฝะตั ัะตะณ ะฒ git, ัะพะดะตัะถะธะผะพะต ัะตะฟะพะทะธัะพัะธั ะธ ะตะณะพ ะธััะพัะธั. ะัะพะดะพะปะถะธัั?
-pulls.agit_explanation = ะกะพะทะดะฐะฝะพ ัะตัะตะท ัะฐะฑะพัะธะน ะฟะพัะพะบ AGit. ะก ะฝะธะผ ะผะพะถะฝะพ ะฟัะตะดะปะฐะณะฐัั ะธะทะผะตะฝะตะฝะธั, ะธัะฟะพะปัะทัั ะบะพะผะฐะฝะดั ยซgit pushยป, ะฑะตะท ะฝะตะพะฑั
ะพะดะธะผะพััะธ ะฒ ัะพะทะดะฐะฝะธะธ ะพัะฒะตัะฒะปะตะฝะธั ะธะปะธ ะฝะพะฒะพะน ะฒะตัะบะธ.
+pulls.agit_explanation = ะกะพะทะดะฐะฝะพ ัะตัะตะท ัะฐะฑะพัะธะน ะฟะพัะพะบ AGit. ะก ะฝะธะผ ะผะพะถะฝะพ ะฟัะตะดะปะฐะณะฐัั ะธะทะผะตะฝะตะฝะธั, ะธัะฟะพะปัะทัั ะบะพะผะฐะฝะดั ยซgit pushยป, ะฑะตะท ะฝะตะพะฑั
ะพะดะธะผะพััะธ ะฒ ัะพะทะดะฐะฝะธะธ ะพัะฒะตัะฒะปะตะฝะธั ะธะปะธ ะฝะพะฒะพะน ะฒะตัะฒะธ.
settings.webhook.replay.description_disabled = ะะบัะธะฒะธััะนัะต ะฒะตะฑ-ั
ัะบ ะดะปั ะฟะพะฒัะพัะตะฝะธั ะพัะฟัะฐะฒะบะธ.
activity.navbar.pulse = ะะตะดะฐะฒะฝัั ะฐะบัะธะฒะฝะพััั
-settings.tags.protection.pattern.description = ะะพะถะฝะพ ัะบะฐะทะฐัั ะฝะฐะทะฒะฐะฝะธะต ัะตะณะฐ. ะะปั ะฒัะฑะพัะฐ ะฝะตัะบะพะปัะบะธั
ัะตะณะพะฒ ะผะพะถะฝะพ ัะบะฐะทะฐัั ะฟะพะธัะบะพะฒัะน ัะฐะฑะปะพะฝ ะธะปะธ ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต. ะะพะดัะพะฑะฝะตะต ะพ ะทะฐัะธััะฝะฝัั
ัะตะณะฐั
.
+settings.tags.protection.pattern.description = ะะพะถะฝะพ ัะบะฐะทะฐัั ะฝะฐะทะฒะฐะฝะธะต ัะตะณะฐ. ะะปั ะฒัะฑะพัะฐ ะฝะตัะบะพะปัะบะธั
ัะตะณะพะฒ ะผะพะถะฝะพ ัะบะฐะทะฐัั ะฟะพะธัะบะพะฒัะน ัะฐะฑะปะพะฝ ะธะปะธ ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต. ะะพะดัะพะฑะฝะตะต ะพ ะทะฐัะธััะฝะฝัั
ัะตะณะฐั
.
file_follow = ะัะพะนัะธ ะฟะพ ัะธะผะฒะพะปัะฝะพะน ัััะปะบะต
settings.pull_mirror_sync_in_progress = ะะดัั ะฟะพะปััะตะฝะธะต ะธะทะผะตะฝะตะฝะธะน ะธะท ัะดะฐะปัะฝะฝะพะณะพ ัะตะฟะพะทะธัะพัะธั %s.
settings.ignore_stale_approvals_desc = ะะต ััะธััะฒะฐัั ะพะดะพะฑัะตะฝะธั, ะพััะฐะฒะปะตะฝะฝัะต ะดะปั ััะฐััั
ะบะพะผะผะธัะพะฒ (ัััะฐัะตะฒัะธะต ะพัะทัะฒั), ะฟัะธ ะฟะพะดััััะต ะพะฑัะตะณะพ ัะธัะปะฐ ะพะดะพะฑัะตะฝะธะน ั ะทะฐะฟัะพัะฐ ะฝะฐ ัะปะธัะฝะธะต. ะะต ะพัะฝะพัะธััั ะบ ะพัะบะปะพะฝัะฝะฝัะผ ะพัะทัะฒะฐะผ.
settings.mirror_settings.docs.doc_link_pull_section = ัะฐะทะดะตะป ะดะพะบัะผะตะฝัะฐัะธะธ ยซPulling from a remote repositoryยป.
wiki.original_git_entry_tooltip = ะะตัะตะนัะธ ะฟะพ ะฝะฐััะพััะตะผั ะฟััะธ ะฒะผะตััะพ ัะธัะฐะฑะตะปัะฝะพะน ัััะปะบะธ.
open_with_editor = ะัะบัััั ะฒ %s
-commits.search_branch = ะ ััะพะน ะฒะตัะบะต
+commits.search_branch = ะ ััะพะน ะฒะตัะฒะธ
stars = ะะพะฑะฐะฒะธะฒัะธะต ะฒ ะธะทะฑัะฐะฝะฝะพะต
n_tag_one = %s ัะตะณ
-n_branch_few = %s ะฒะตัะพะบ
+n_branch_few = %s ะฒะตัะฒะตะน
n_commit_few = %s ะบะพะผะผะธัะพะฒ
n_commit_one = %s ะบะพะผะผะธั
n_tag_few = %s ัะตะณะพะฒ
-n_branch_one = %s ะฒะตัะบะฐ
+n_branch_one = %s ะฒะตัะฒั
pulls.ready_for_review = ะะพัะพะฒะพ ะบ ัะตัะตะฝะทะธะธ?
-editor.commit_id_not_matching = ID ะบะพะผะผะธัะฐ ะฝะต ัะพะฒะฟะฐะดะฐะตั ั ัะตะผ, ะบะพัะพััะน ะฒั ัะตะดะฐะบัะธัะพะฒะฐะปะธ. ะกะพั
ัะฐะฝะธัะต ะธะทะผะตะฝะตะฝะธั ะฒ ะฝะพะฒัั ะฒะตัะบั ะธ ะฒัะฟะพะปะฝะธัะต ัะปะธัะฝะธะต.
+editor.commit_id_not_matching = ะคะฐะนะป ะฑัะป ะธะทะผะตะฝัะฝ ะบะตะผ-ัะพ ะดััะณะธะผ, ะฟะพะบะฐ ะฒั ะตะณะพ ัะตะดะฐะบัะธัะพะฒะฐะปะธ. ะกะพั
ัะฐะฝะธัะต ะธะทะผะตะฝะตะฝะธั ะฒ ะฝะพะฒัั ะฒะตัะฒั ะธ ะฒัะฟะพะปะฝะธัะต ัะปะธัะฝะธะต.
editor.push_out_of_date = ะะพั
ะพะถะต, ะพัะฟัะฐะฒะบะฐ ัััะฐัะตะปะฐ.
settings.enforce_on_admins = ะะฑัะทะฐัะตะปัะฝะพ ะดะปั ะฐะดะผะธะฝะธัััะฐัะพัะพะฒ ัะตะฟะพะทะธัะพัะธั
settings.enforce_on_admins_desc = ะะดะผะธะฝะธัััะฐัะพัั ัะตะฟะพะทะธัะพัะธั ะฝะต ัะผะพะณัั ะพะฑะพะนัะธ ััะพ ะพะณัะฐะฝะธัะตะฝะธะต.
-settings.rename_branch_failed_protected = ะะตะฒะพะทะผะพะถะฝะพ ะฟะตัะตะธะผะตะฝะพะฒะฐัั ะทะฐัะธััะฝะฝัั ะฒะตัะบั ยซ%sยป.
+settings.rename_branch_failed_protected = ะะตะฒะพะทะผะพะถะฝะพ ะฟะตัะตะธะผะตะฝะพะฒะฐัั ะทะฐัะธััะฝะฝัั ะฒะตัะฒั ยซ%sยป.
issues.archived_label_description = (ะัั
ะธะฒะฝะฐั) %s
settings.sourcehut_builds.graphql_url = ะกััะปะบะฐ ะฝะฐ GraphQL (ะฝะฐะฟั. https://builds.sr.ht/query)
settings.sourcehut_builds.secrets_helper = ะะฐัั ะทะฐะดะฐัะฐะผ ะดะพัััะฟ ะบ ัะตะบัะตัะฐะผ ัะฑะพัะบะธ (ััะตะฑัะตััั ัะฐะทัะตัะตะฝะธะต SECRETS:RO)
@@ -2740,9 +2819,9 @@ release.download_count_one = %s ัะบะฐัะธะฒะฐะฝะธะต
release.download_count_few = %s ัะบะฐัะธะฒะฐะฝะธะน
release.system_generated = ะญัะพ ะฒะปะพะถะตะฝะธะต ัะณะตะฝะตัะธัะพะฒะฐะฝะพ ะฐะฒัะพะผะฐัะธัะตัะบะธ.
settings.event_pull_request_enforcement = ะคะพััะธัะพะฒะฐะฝะธะต
-pulls.cmd_instruction_checkout_desc = ะ ัะตะฟะพะทะธัะพัะธะธ ะฒะฐัะตะณะพ ะฟัะพะตะบัะฐ ะฟะตัะตะนะดะธัะต ะฝะฐ ััะฐ ะฒะตัะบั ะธ ะฟัะพัะตััะธััะนัะต ะธะทะผะตะฝะตะฝะธั.
-error.broken_git_hook = ะะธั-ั
ัะบะธ ััะพะณะพ ัะตะฟะพะทะธัะพัะธั ัะปะพะผะฐะฝั. ะะทะฝะฐะบะพะผััะตัั ั ะดะพะบัะผะตะฝัะฐัะธะตะน ะธ ะฟะพัะธะฝะธัะต ะธั
, ะทะฐัะตะผ ะพัะฟัะฐะฒััะต ะบะฐะบะธะต-ะฝะธะฑัะดั ะบะพะผะผะธัั ะดะปั ะพะฑะฝะพะฒะปะตะฝะธั ััะฐัััะฐ.
-pulls.cmd_instruction_checkout_title = ะะตัะตะนะดะธัะต ะฝะฐ ะฒะตัะบั
+pulls.cmd_instruction_checkout_desc = ะ ัะตะฟะพะทะธัะพัะธะธ ะฒะฐัะตะณะพ ะฟัะพะตะบัะฐ ะฟะตัะตะนะดะธัะต ะฝะฐ ััั ะฒะตัะฒั ะธ ะฟัะพัะตััะธััะนัะต ะธะทะผะตะฝะตะฝะธั.
+error.broken_git_hook = ะะธั-ั
ัะบะธ ััะพะณะพ ัะตะฟะพะทะธัะพัะธั ัะปะพะผะฐะฝั. ะะทะฝะฐะบะพะผััะตัั ั ะดะพะบัะผะตะฝัะฐัะธะตะน ะธ ะธัะฟัะฐะฒััะต ะธั
, ะทะฐัะตะผ ะพัะฟัะฐะฒััะต ะบะฐะบะธะต-ะฝะธะฑัะดั ะบะพะผะผะธัั ะดะปั ะพะฑะฝะพะฒะปะตะฝะธั ััะฐัััะฐ.
+pulls.cmd_instruction_checkout_title = ะะตัะตะนะดะธัะต ะบ ะฒะตัะฒะธ
settings.graphql_url = ะกััะปะบะฐ GraphQL
settings.sourcehut_builds.access_token_helper = ะขะพะบะตะฝ builds.sr.ht ั ัะฐะทัะตัะตะฝะธะตะผ JOBS:RW. ะกะพะทะดะฐะนัะต ะพะฑััะฝัะน ัะพะบะตะฝ ะธะปะธ ัะพะบะตะฝ ั ะดะพัััะฟะพะผ ะบ ัะตะบัะตัะฐะผ ะฝะฐ meta.sr.ht.
settings.matrix.room_id_helper = ID ะบะพะผะฝะฐัั ะผะพะถะฝะพ ะฟะพะปััะธัั ะฒ ะฒะตะฑ-ะบะปะธะตะฝัะต Element: ะะฐัััะพะนะบะธ ะบะพะผะฝะฐัั > ะะพะดัะพะฑะฝะพััะธ > ะะฝัััะตะฝะฝะธะน ID ะบะพะผะฝะฐัั. ะัะธะผะตั: %s.
@@ -2761,14 +2840,88 @@ issues.edit.already_changed = ะะต ัะดะฐะปะพัั ะพััะตะดะฐะบัะธัะพะฒะฐัั
pulls.edit.already_changed = ะะต ัะดะฐะปะพัั ะพััะตะดะฐะบัะธัะพะฒะฐัั ะทะฐะฟัะพั ัะปะธัะฝะธั. ะะพั
ะพะถะต, ัะพะดะตัะถะธะผะพะต ัะถะต ะฑัะปะพ ะธะทะผะตะฝะตะฝะพ ะดััะณะธะผ ะฟะพะปัะทะพะฒะฐัะตะปะตะผ. ะะพะฟัะพะฑัะนัะต ะพะฑะฝะพะฒะธัั ัััะฐะฝะธัั ะธ ะพััะตะดะฐะบัะธัะพะฒะฐัั ะทะฐะฟัะพั ะตัั ัะฐะท, ััะพะฑั ะธะทะฑะตะถะฐัั ะพัะผะตะฝั ััะถะธั
ะธะทะผะตะฝะตะฝะธะน
comments.edit.already_changed = ะะต ัะดะฐะปะพัั ะพััะตะดะฐะบัะธัะพะฒะฐัั ะบะพะผะผะตะฝัะฐัะธะน. ะะพั
ะพะถะต, ะพะฝ ัะถะต ะฑัะป ะธะทะผะตะฝัะฝ ะดััะณะธะผ ะฟะพะปัะทะพะฒะฐัะตะปะตะผ. ะะพะฟัะพะฑัะนัะต ะพะฑะฝะพะฒะธัั ัััะฐะฝะธัั ะธ ะพััะตะดะฐะบัะธัะพะฒะฐัั ะตะณะพ ะตัั ัะฐะท, ััะพะฑั ะธะทะฑะตะถะฐัั ะพัะผะตะฝั ััะถะธั
ะธะทะผะตะฝะตะฝะธะน
settings.federation_settings = ะะฐัััะพะนะบะธ ัะตะดะตัะฐัะธะธ
-settings.federation_apapiurl = ะคะตะดะตัะฐัะธะฒะฝะฐั ัััะปะบะฐ ะฝะฐ ััะพั ัะตะฟะพะทะธัะพัะธะน. ะกะบะพะฟะธััะนัะต ะธ ะฒััะฐะฒััะต ะตั ะฒ ะฝะฐัััะพะนะบะธ ัะตะดะตัะฐัะธะธ ะดััะณะพะณะพ ัะตะฟะพะทะธัะพัะธั ะบะฐะบ ัััะปะบั ัะปะตะดัะตะผะพะณะพ ัะตะฟะพะทะธัะพัะธั.
-settings.federation_following_repos = ะกััะปะบะธ ัะปะตะดัะตะผัั
ัะตะฟะพะทะธัะพัะธะตะฒ. ะ ะฐะทะดะตะปะตะฝั ั ยซ;ยป, ะฑะตะท ะฟัะพะฑะตะปะพะฒ.
+settings.federation_apapiurl = ะคะตะดะตัะฐัะธะฒะฝะฐั ัััะปะบะฐ ะฝะฐ ััะพั ัะตะฟะพะทะธัะพัะธะน. ะกะบะพะฟะธััะนัะต ะธ ะฒััะฐะฒััะต ะตั ะฒ ะฝะฐัััะพะนะบะธ ัะตะดะตัะฐัะธะธ ะดััะณะพะณะพ ัะตะฟะพะทะธัะพัะธั ะบะฐะบ ัััะปะบั ัะตะฟะพะทะธัะพัะธั ะดะปั ะพััะปะตะถะธะฒะฐะฝะธั.
+settings.federation_following_repos = ะกััะปะบะธ ะฝะฐ ะพััะปะตะถะธะฒะฐะตะผัะต ัะตะฟะพะทะธัะพัะธะธ. ะ ะฐะทะดะตะปััััั ั ะฟะพะผะพััั ยซ;ยป, ะฑะตะท ะฟัะพะฑะตะปะพะฒ.
n_release_one = %s ะฒัะฟััะบ
n_release_few = %s ะฒัะฟััะบะพะฒ
subscribe.issue.guest.tooltip = ะะพะนะดะธัะต, ััะพะฑั ะฟะพะดะฟะธัะฐัััั ะฝะฐ ััั ะทะฐะดะฐัั.
subscribe.pull.guest.tooltip = ะะพะนะดะธัะต, ััะพะฑั ะฟะพะดะฟะธัะฐัััั ะฝะฐ ััะพ ัะปะธัะฝะธะต.
+issues.author.tooltip.issue = ะะฒัะพั ััะพะน ะทะฐะดะฐัะธ.
+issues.author.tooltip.pr = ะะฒัะพั ััะพะณะพ ะทะฐะฟัะพัะฐ ัะปะธัะฝะธั.
+activity.commit = ะะพะป-ะฒะพ ะบะพะผะผะธัะพะฒ
+milestones.filter_sort.name = ะะพ ะฝะฐะทะฒะฐะฝะธั
+release.asset_external_url = ะะฝะตัะฝัั ัััะปะบะฐ
+release.type_external_asset = ะะฝะตัะฝะธะน ัะฐะนะป
+release.asset_name = ะะฐะทะฒะฐะฝะธะต ัะฐะนะปะฐ
+release.invalid_external_url = ะะตะดะพะฟัััะธะผะฐั ัััะปะบะฐ: ยซ%sยป
+release.add_external_asset = ะะพะฑะฐะฒะธัั ะฒะฝะตัะฝะธะน ัะฐะนะป
+release.type_attachment = ะะปะพะถะตะฝะธะต
+activity.published_prerelease_label = ะัะตะด. ะฒัะฟััะบ
+activity.published_tag_label = ะขะตะณ
+settings.transfer_quota_exceeded = ะฃ ะฝะพะฒะพะณะพ ะฒะปะฐะดะตะปััะฐ (%s) ะฟัะตะฒััะตะฝะฐ ะบะฒะพัะฐ. ะ ะตะฟะพะทะธัะพัะธะน ะฝะต ะฑัะดะตั ะฟะตัะตะดะฐะฝ.
+settings.pull_mirror_sync_quota_exceeded = ะะฒะพัะฐ ะธััะตัะฟะฐะฝะฐ, ัะธะฝั
ัะพะฝะธะทะฐัะธั ะฝะตะฒะพะทะผะพะถะฝะฐ.
+no_eol.text = ะะตะท EOL
+no_eol.tooltip = ะ ัะฐะนะปะต ะพััััััะฒัะตั ะทะฐะฒะตััะฐััะธะน ัะธะผะฒะพะป ะบะพะฝัะฐ ัััะพะบะธ.
+pulls.cmd_instruction_merge_warning = ะะฑัะฐัะธัะต ะฒะฝะธะผะฐะฝะธะต: ยซะะฒัะพะพะฟัะตะดะตะปะตะฝะธะต ัััะฝะพะณะพ ัะปะธัะฝะธัยป ะฝะต ะฒะบะปััะตะฝะพ ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ. ะะพัะปะต ะฒัะฟะพะปะฝะตะฝะธั ัะปะธัะฝะธั ะฒะฐะผ ะฟะพััะตะฑัะตััั ะฟะพะผะตัะธัั ััะพั ะทะฐะฟัะพั ะบะฐะบ ะฟัะธะฝัััะน ะฒัััะฝัั.
+mirror_use_ssh.not_available = ะััะตะฝัะธัะธะบะฐัะธั ะฟะพ SSH ะฝะตะดะพัััะฟะฝะฐ.
+settings.protect_new_rule = ะกะพะทะดะฐัั ะฝะพะฒะพะต ะฟัะฐะฒะธะปะพ ะดะพัััะฟะฐ ะบ ะฒะตัะฒัะผ
+mirror_public_key = ะัะฑะปะธัะฝัะน ะบะปัั SSH
+mirror_use_ssh.text = ะััะตะฝัะธัะธะบะฐัะธั ะฟะพ SSH
+mirror_use_ssh.helper = Forgejo ะฑัะดะตั ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐัั ะธะทะผะตะฝะตะฝะธั ะฒ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ Git ะฟะพ SSH. ะัะธ ะฒะบะปััะตะฝะธะธ ััะพะน ะพะฟัะธะธ ะฑัะดะตั ัะพะทะดะฐะฝะฐ ะฟะฐัะฐ ะบะปััะตะน. ะะฐะผ ะฟะพััะตะฑัะตััั ัะดะพััะพะฒะตัะธััั, ััะพ ั ัะพะทะดะฐะฝะฝัะผ ะฟัะฑะปะธัะฝัะผ ะบะปััะพะผ Forgejo ัะผะพะถะตั ะพัะฟัะฐะฒะปััั ะธะทะผะตะฝะตะฝะธั ะฒ ัะดะฐะปัะฝะฝัะน ัะตะฟะพะทะธัะพัะธะน. ะััะตะฝัะธัะธะบะฐัะธั ะฟะพ ะฟะฐัะพะปั ะฝะตะดะพัััะฟะฝะฐ ะฟัะธ ะธัะฟะพะปัะทะพะฒะฐะฝะธะธ ััะพะน ะพะฟัะธะธ.
+mirror_denied_combination = ะะตะฒะพะทะผะพะถะฝะพ ะพะดะฝะพะฒัะตะผะตะฝะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั ะฐััะตะฝัะธัะธะบะฐัะธั ะฟะพ SSH ะธ ะฟะพ ะฟะฐัะพะปั.
+settings.mirror_settings.push_mirror.none_ssh = ะะตั
+settings.mirror_settings.push_mirror.copy_public_key = ะะพะฟะธัะพะฒะฐัั ะฟัะฑะปะธัะฝัะน ะบะปัั
+issues.new.assign_to_me = ะะฐะทะฝะฐัะธัั ัะตะฑะต
+issues.all_title = ะัะต
+settings.discord_icon_url.exceeds_max_length = URL ะธะบะพะฝะบะธ ะฝะต ะผะพะถะตั ะฑััั ะดะปะธะฝะฝะตะต 2048 ัะธะผะฒะพะปะพะฒ
+issues.review.add_review_requests = ะทะฐะฟัะพัะตะฝั ัะตัะตะฝะทะธะธ ะพั %[1]s %[2]s
+issues.review.remove_review_requests = ะพัะผะตะฝะตะฝั ะทะฐะฟัะพัั ัะตัะตะฝะทะธะน ะพั %[1]s %[2]s
+issues.review.add_remove_review_requests = ะทะฐะฟัะพัะตะฝั ัะตัะตะฝะทะธะธ ะพั %[1]s ะธ ะพัะผะตะฝะตะฝั ะทะฐะฟัะพัั ัะตัะตะฝะทะธะน ะพั %[2]s %[3]s
+pulls.delete_after_merge.head_branch.is_default = ะะพะปะพะฒะฝะฐั ะฒะตัะฒั, ะบะพัะพััั ะฒั ะฟะพะฟััะฐะปะธัั ัะดะฐะปะธัั, ัะฒะปัะตััั ะฒะตัะฒัั ะฟะพ ัะผะพะปัะฐะฝะธั ะธ ะฝะต ะผะพะถะตั ะฑััั ัะดะฐะปะตะฝะฐ.
+pulls.delete_after_merge.head_branch.is_protected = ะะพะปะพะฒะฝะฐั ะฒะตัะฒั, ะบะพัะพััั ะฒั ะฟะพะฟััะฐะปะธัั ัะดะฐะปะธัั, ะทะฐัะธัะตะฝะฐ ะพั ััะพะณะพ ะธ ะฝะต ะผะพะถะตั ะฑััั ัะดะฐะปะตะฝะฐ.
+pulls.delete_after_merge.head_branch.insufficient_branch = ะััััััะฒัะตั ัะฐะทัะตัะตะฝะธะต ะดะปั ัะดะฐะปะตะฝะธั ะณะพะปะพะฒะฝะพะน ะฒะตัะฒะธ.
+issues.filter_sort.relevance = ะะพ ัะพะพัะฒะตัััะฒะธั
+diff.git-notes.remove-header = ะฃะดะฐะปะตะฝะธะต ะทะฐะผะตัะบะธ
+diff.git-notes.remove-body = ะะฐะผะตัะบะฐ ะฑัะดะตั ัะดะฐะปะตะฝะฐ.
+diff.git-notes.add = ะะพะฑะฐะฒะธัั ะทะฐะผะตัะบั
+issues.num_reviews_few = %d ัะตัะตะฝะทะธะน
+issues.num_reviews_one = %d ัะตัะตะฝะทะธั
+issues.summary_card_alt = ะะฐััะพัะบะฐ ัะพ ัะฒะพะดะบะพะน ะทะฐะดะฐัะธ "%s" ะฒ ัะตะฟะพะทะธัะพัะธะธ %s
+editor.add_tmpl.filename = ะธะผั ัะฐะนะปะฐ
+settings.default_update_style_desc = ะกัะธะปั ะพะฑะฝะพะฒะปะตะฝะธั ะพัััะฐััะธั
ะฒะตัะฒะตะน ะทะฐะฟัะพัะพะฒ ะฝะฐ ัะปะธัะฝะธะต ะฟะพ ัะผะพะปัะฐะฝะธั.
+pulls.sign_in_require = ะะพะนะดะธัะต , ััะพะฑั ัะพะทะดะฐัั ะทะฐะฟัะพั ัะปะธัะฝะธั.
+new_from_template = ะัะธะผะตะฝะธัั ัะฐะฑะปะพะฝ
+new_from_template_description = ะั ะผะพะถะตัะต ะฒัะฑัะฐัั ะปัะฑะพะน ัะฐะฑะปะพะฝ ัะตะฟะพะทะธัะพัะธั ะฝะฐ ััะพะผ ัะตัะฒะตัะต ะธ ะฟัะธะผะตะฝะธัั ะตะณะพ ะฝะฐัััะพะนะบะธ ะฝะฐ ััะพะผ ัะตะฟะพะทะธัะพัะธะธ.
+new_advanced = ะ ะฐััะธัะตะฝะฝัะต ะฝะฐัััะพะนะบะธ
+new_advanced_expand = ะะฐะถะผะธัะต, ััะพะฑั ัะฐัะบัััั
+auto_init_description = ะะฐัะฐัั ะธััะพัะธั ะบะพะผะผะธัะพะฒ ั ะดะพะฑะฐะฒะปะตะฝะธั README ะธ, ะตัะปะธ ะฝะฐะดะพ, ะปะธัะตะฝะทะธะธ ะธ .gitignore.
+summary_card_alt = ะะฐััะพัะบะฐ ัะพ ัะฒะพะดะบะพะน ะพ ัะตะฟะพะทะธัะพัะธะธ %s
+issues.reaction.add = ะะพะฑะฐะฒะธัั ัะตะฐะบัะธั
+issues.reaction.alt_few = ะ ะตะฐะบัะธั %[2]s ะพั %[1]s.
+issues.reaction.alt_many = ะ ะตะฐะบัะธั %[3]s ะพั %[1]s ะธ %[2]d ะดััะณะธั
.
+issues.reaction.alt_remove = ะฃะฑัะฐัั ัะตะฐะบัะธั %[1]s ั ััะพะณะพ ะบะพะผะผะตะฝัะฐัะธั.
+issues.reaction.alt_add = ะะพะฑะฐะฒะธัั ัะตะฐะบัะธั %[1]s ะบ ััะพะผั ะบะพะผะผะตะฝัะฐัะธั.
+issues.context.menu = ะะตะฝั ะบะพะผะผะตะฝัะฐัะธั
+release.summary_card_alt = ะะฐััะพัะบะฐ ัะพ ัะฒะพะดะบะพะน ะพ ะฒัะฟััะบะต ยซ%sยป ะฒ ัะตะฟะพะทะธัะพัะธะธ %s
+archive.pull.noreview = ะญัะพั ัะตะฟะพะทะธัะพัะธะน ะฐัั
ะธะฒะธัะพะฒะฐะฝ. ะ ะตัะตะฝะทะธัะพะฒะฐะฝะธะต ะทะฐะฟัะพัะพะฒ ัะปะธัะฝะธะน ะฝะตะฒะพะทะผะพะถะฝะพ.
+editor.commit_email = ะญะป. ะฟะพััะฐ ะฐะฒัะพัะฐ
+commits.view_single_diff = ะะพัะผะพััะตัั ะธะทะผะตะฝะตะฝะธั ะฒ ััะพะผ ัะฐะนะปะต ะธะท ััะพะณะพ ะบะพะผะผะธัะฐ
+pulls.editable = ะะทะผะตะฝัะตะผัะน
+pulls.editable_explanation = ะะฒัะพั ัะฐะทัะตัะธะป ะธะทะผะตะฝะตะฝะธั ะพั ัะพััะฐััะฝะธะบะพะฒ. ะั ะผะพะถะตัะต ะฝะฐะฟััะผัั ะพัะฟัะฐะฒะปััั ะฒ ะฝะตะณะพ ะธะทะผะตะฝะตะฝะธั.
+issues.reopen.blocked_by_user = ะะพะฒัะพัะฝะพะต ะพัะบัััะธะต ะทะฐะดะฐัะธ ะฝะตะฒะพะทะผะพะถะฝะพ, ั.ะบ. ะฒั ะทะฐะฑะปะพะบะธัะพะฒะฐะฝั ะฒะปะฐะดะตะปััะตะผ ัะตะฟะพะทะธัะพัะธั ะธะปะธ ะฐะฒัะพัะพะผ ะทะฐะดะฐัะธ.
+pulls.comment.blocked_by_user = ะั ะฝะต ะผะพะถะตัะต ะบะพะผะผะตะฝัะธัะพะฒะฐัั ะฟะพะด ััะธะผ ะทะฐะฟัะพัะพะผ ัะปะธัะฝะธั, ั.ะบ. ะฒั ะทะฐะฑะปะพะบะธัะพะฒะฐะฝั ะฒะปะฐะดะตะปััะตะผ ัะตะฟะพะทะธัะพัะธั ะธะปะธ ะฐะฒัะพัะพะผ ะทะฐะดะฐัะธ.
+issues.filter_no_results = ะะธัะตะณะพ ะฝะต ะฝะฐัะปะพัั
+issues.filter_no_results_placeholder = ะะพะฟัะพะฑัะนัะต ะฟะพะธัะบะฐัั ะฟะพ-ะดััะณะพะผั.
[graphs]
+component_loading_failed = ะะต ัะดะฐะปะพัั ะทะฐะณััะทะธัั %s
+component_failed_to_load = ะกะปััะธะปะฐัั ะฝะตะฟัะตะดะฒะธะดะตะฝะฝะฐั ะพัะธะฑะบะฐ.
+contributors.what = ัะพััะฐััะธะต
+component_loading = ะะฐะณััะทะบะฐ %sโฆ
+component_loading_info = ะญัะพ ะทะฐะนะผัั ะฝะตะบะพัะพัะพะต ะฒัะตะผัโฆ
+code_frequency.what = ัะฐััะพัะฐ ะธะทะผะตะฝะตะฝะธะน
+recent_commits.what = ะฝะตะดะฐะฒะฝะธะต ะบะพะผะผะธัั
+
[org]
org_name_holder=ะะฐะทะฒะฐะฝะธะต ะพัะณะฐะฝะธะทะฐัะธะธ
@@ -2787,9 +2940,9 @@ org_desc=ะะฟะธัะฐะฝะธะต
team_name=ะะฐะทะฒะฐะฝะธะต ะบะพะผะฐะฝะดั
team_desc=ะะฟะธัะฐะฝะธะต
team_name_helper=ะะฐะทะฒะฐะฝะธั ะบะพะผะฐะฝะด ะดะพะปะถะฝั ะฑััั ะบะพัะพัะบะธะผะธ ะธ ะทะฐะฟะพะผะธะฝะฐััะธะผะธัั.
-team_desc_helper=ะะฟะธัะธัะต ะฝะฐะทะฝะฐัะตะฝะธะต ะธะปะธ ัะพะปั ะบะพะผะฐะฝะดั.
-team_access_desc=ะะพัััะฟ ะบ ัะตะฟะพะทะธัะพัะธั
-team_permission_desc=ะ ะฐะทัะตัะตะฝะธะต
+team_desc_helper=ะะฐะทะฝะฐัะตะฝะธะต ะธะปะธ ัะพะปั ััะพะน ะบะพะผะฐะฝะดั.
+team_access_desc=ะะพัััะฟ ะบ ัะตะฟะพะทะธัะพัะธัะผ
+team_permission_desc=ะ ะฐะทัะตัะตะฝะธั
team_unit_desc=ะ ะฐะทัะตัะธัั ะดะพัััะฟ ะบ ัะฐะทะดะตะปะฐะผ ัะตะฟะพะทะธัะพัะธั
team_unit_disabled=(ะัะบะปััะตะฝะพ)
@@ -2807,7 +2960,7 @@ settings.permission=ะ ะฐะทัะตัะตะฝะธั
settings.repoadminchangeteam=ะะดะผะธะฝะธัััะฐัะพั ัะตะฟะพะทะธัะพัะธั ะผะพะถะตั ะดะพะฑะฐะฒะปััั ะธ ัะดะฐะปััั ะฟัะฐะฒะฐ ะดะพัััะฟะฐ ะดะปั ะบะพะผะฐะฝะด
settings.visibility=ะะธะดะธะผะพััั
settings.visibility.public=ะัะฑะปะธัะฝัะน
-settings.visibility.limited=ะะณัะฐะฝะธัะตะฝะฝะฐั (ะฒะธะดะฝะฐ ัะพะปัะบะพ ะฐะฒัะพัะธะทะพะฒะฐะฝะฝัะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ)
+settings.visibility.limited=ะะณัะฐะฝะธัะตะฝะฝะฐั (ะฒะธะดะฝะฐ ัะพะปัะบะพ ะทะฐัะตะณะธัััะธัะพะฒะฐะฝะฝัะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ)
settings.visibility.limited_shortname=ะะณัะฐะฝะธัะตะฝะฝัะน
settings.visibility.private=ะงะฐััะฝะฐั (ะฒะธะดะฝะฐ ัะพะปัะบะพ ััะฐััะฝะธะบะฐะผ ะพัะณะฐะฝะธะทะฐัะธะธ)
settings.visibility.private_shortname=ะงะฐััะฝะฐั
@@ -2816,7 +2969,7 @@ settings.update_settings=ะะฑะฝะพะฒะธัั ะฝะฐัััะพะนะบะธ
settings.update_setting_success=ะะฐัััะพะนะบะธ ะพัะณะฐะฝะธะทะฐัะธะธ ะพะฑะฝะพะฒะปะตะฝั.
settings.change_orgname_prompt=ะะฑัะฐัะธัะต ะฒะฝะธะผะฐะฝะธะต: ะธะทะผะตะฝะตะฝะธะต ะฝะฐะทะฒะฐะฝะธั ะพัะณะฐะฝะธะทะฐัะธะธ ัะฐะบะถะต ะธะทะผะตะฝะธั URL ะฒะฐัะตะน ะพัะณะฐะฝะธะทะฐัะธะธ ะธ ะพัะฒะพะฑะพะดะธั ััะฐัะพะต ะธะผั.
settings.change_orgname_redirect_prompt=ะกัะฐัะพะต ะธะผั ะฑัะดะตั ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝะพ ะดะพ ัะตั
ะฟะพั, ะฟะพะบะฐ ะพะฝะพ ะฝะต ะฑัะดะตั ะฒะฒะตะดะตะฝะพ.
-settings.update_avatar_success=ะะฒะฐัะฐั ะพัะณะฐะฝะธะทะฐัะธะธ ะพะฑะฝะพะฒะปัะฝ.
+settings.update_avatar_success=ะะทะพะฑัะฐะถะตะฝะธะต ะพัะณะฐะฝะธะทะฐัะธะธ ะพะฑะฝะพะฒะปะตะฝะพ.
settings.delete=ะฃะดะฐะปะธัั ะพัะณะฐะฝะธะทะฐัะธั
settings.delete_account=ะฃะดะฐะปะธัั ััั ะพัะณะฐะฝะธะทะฐัะธั
settings.delete_prompt=ะญัะพ ะดะตะนััะฒะธะต ะะะะะะะะ ะะขะะ ัะดะฐะปะธั ััั ะพัะณะฐะฝะธะทะฐัะธั ะฝะฐะฒัะตะณะดะฐ!
@@ -2838,23 +2991,23 @@ members.member=ะฃัะฐััะฝะธะบ
members.remove=ะฃะดะฐะปะธัั
members.remove.detail=ะัะบะปััะธัั %[1]s ะธะท %[2]s?
members.leave=ะะพะบะธะฝััั
-members.leave.detail=ะะพะบะธะฝััั %s?
+members.leave.detail=ะั ัะพัะฝะพ ั
ะพัะธัะต ะฟะพะบะธะฝััั ะพัะณะฐะฝะธะทะฐัะธั ยซ%sยป?
members.invite_desc=ะะพะฑะฐะฒะธัั ะฝะพะฒะพะณะพ ััะฐััะฝะธะบะฐ ะฒ %s:
members.invite_now=ะัะธะณะปะฐัะธัั
teams.join=ะัะธัะพะตะดะธะฝะธัััั
teams.leave=ะัะนัะธ
-teams.leave.detail=ะะพะบะธะฝััั %s?
+teams.leave.detail=ะั ัะพัะฝะพ ั
ะพัะธัะต ะฟะพะบะธะฝััั ะบะพะผะฐะฝะดั ยซ%sยป?
teams.can_create_org_repo=ะกะพะทะดะฐัั ัะตะฟะพะทะธัะพัะธะธ
teams.can_create_org_repo_helper=ะฃัะฐััะฝะธะบะธ ะผะพะณัั ัะพะทะดะฐะฒะฐัั ะฝะพะฒัะต ัะตะฟะพะทะธัะพัะธะธ ะฒ ะพัะณะฐะฝะธะทะฐัะธะธ. ะกะพะทะดะฐัะตะปั ะฟะพะปััะธั ะฐะดะผะธะฝะธัััะฐัะพััะบะธะน ะดะพัััะฟ ะบ ะฝะพะฒะพะผั ัะตะฟะพะทะธัะพัะธั.
teams.none_access=ะะตั ะดะพัััะฟะฐ
-teams.none_access_helper=ะฃัะฐััะฝะธะบะธ ะฝะต ะผะพะณัั ะฟัะพัะผะฐััะธะฒะฐัั ะธะปะธ ะฒัะฟะพะปะฝััั ะปัะฑัะต ะดััะณะธะต ะดะตะนััะฒะธั ะฝะฐะด ััะธะผ ัะปะตะผะตะฝัะพะผ. ะญัะพ ะฝะต ะฒะปะธัะตั ะฝะฐ ะฟัะฑะปะธัะฝัะต ัะตะฟะพะทะธัะพัะธะธ.
+teams.none_access_helper=ะะฐัััะพะนะบะฐ ยซะฝะตั ะดะพัััะฟะฐยป ะฟะพะปะตะทะฝะฐ ะปะธัั ะฒ ัะฐััะฝัั
ัะตะฟะพะทะธัะพัะธัั
.
teams.general_access_helper=ะ ะฐะทัะตัะตะฝะธั ััะฐััะฝะธะบะพะฒ ะฑัะดัั ะพะฟัะตะดะตะปััััั ัะฐะฑะปะธัะตะน ัะฐะทัะตัะตะฝะธะน ะฝะธะถะต.
teams.read_access=ะงัะตะฝะธะต
teams.read_access_helper=ะฃัะฐััะฝะธะบะธ ะผะพะณัั ะฟัะพัะผะฐััะธะฒะฐัั ะธ ะบะปะพะฝะธัะพะฒะฐัั ะบะพะผะฐะฝะดะฝัะต ัะตะฟะพะทะธัะพัะธะธ.
teams.write_access=ะะฐะฟะธัั
teams.write_access_helper=ะฃัะฐััะฝะธะบะธ ะผะพะณัั ัะธัะฐัั ะธ ะฒัะฟะพะปะฝััั push ะฒ ะบะพะผะฐะฝะดะฝัะต ัะตะฟะพะทะธัะพัะธะธ.
-teams.admin_access=ะะพัััะฟ ะฐะดะผะธะฝะธัััะฐัะพัะฐ
+teams.admin_access=ะะดะผะธะฝะธัััะฐัะธะฒะฝัะน ะดะพัััะฟ
teams.admin_access_helper=ะฃัะฐััะฝะธะบะธ ะผะพะณัั ะฒัะฟะพะปะฝััั pull, push ะฒ ะบะพะผะฐะฝะดะฝัะต ัะตะฟะพะทะธัะพัะธะธ ะธ ะดะพะฑะฐะฒะปััั ัะพััะฐััะฝะธะบะพะฒ ะฒ ะบะพะผะฐะฝะดั.
teams.no_desc=ะญัะฐ ะณััะฟะฟะฐ ะฝะต ะธะผะตะตั ะพะฟะธัะฐะฝะธั
teams.settings=ะะฐัััะพะนะบะธ
@@ -2895,6 +3048,8 @@ teams.invite.description=ะะฐะถะผะธัะต ะฝะฐ ะบะฝะพะฟะบั ะฝะธะถะต, ััะพะฑั
follow_blocked_user = ะั ะฝะต ะผะพะถะตัะต ะฟะพะดะฟะธัะฐัััั ะฝะฐ ััั ะพัะณะฐะฝะธะทะฐัะธั, ั.ะบ. ะฒั ะฒ ะฝะตะน ะทะฐะฑะปะพะบะธัะพะฒะฐะฝั.
teams.general_access = ะะฐัััะฐะธะฒะฐะตะผัะน ะดะพัััะฟ
open_dashboard = ะัะบัััั ะฟะฐะฝะตะปั
+settings.change_orgname_redirect_prompt.with_cooldown.few = ะัะตะถะฝะตะต ะฝะฐะทะฒะฐะฝะธะต ะฑัะดะตั ะดะพัััะฟะฝะพ ะดะปั ะธัะฟะพะปัะทะพะฒะฐะฝะธั ะดััะณะธะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะฟะพัะปะต ะธััะตัะตะฝะธั ะทะฐัะธัั ะฒ %[1]d ะดะฝะตะน. ะั ัะผะพะถะตัะต ะฒะตัะฝััั ะตะณะพ ะฒะพ ะฒัะตะผั ััะพะบะฐ ะทะฐัะธัั.
+settings.change_orgname_redirect_prompt.with_cooldown.one = ะัะตะถะฝะตะต ะฝะฐะทะฒะฐะฝะธะต ะฑัะดะตั ะดะพัััะฟะฝะพ ะดะปั ะธัะฟะพะปัะทะพะฒะฐะฝะธั ะดััะณะธะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะฟะพัะปะต ะธััะตัะตะฝะธั ะทะฐัะธัั ะฒ %[1]d ะดะตะฝั. ะั ัะผะพะถะตัะต ะฒะตัะฝััั ะตะณะพ ะฒะพ ะฒัะตะผั ััะพะบะฐ ะทะฐัะธัั.
[admin]
dashboard=ะะฐะฝะตะปั ัะฟัะฐะฒะปะตะฝะธั
@@ -2913,7 +3068,7 @@ first_page=ะะตัะฒะฐั
last_page=ะะพัะปะตะดะฝัั
total=ะัะตะณะพ: %d
-dashboard.new_version_hint=ะะพัััะฟะฝะฐ ะฝะพะฒะฐั ะฒะตััะธั Forgejo %s, ะฒั ะธัะฟะพะปัะทัะตัะต %s. ะะพะปะตะต ะฟะพะดัะพะฑะฝัั ะธะฝัะพัะผะฐัะธั ัะธัะฐะนัะต ะฒ ะฑะปะพะณะต .
+dashboard.new_version_hint=ะะพัััะฟะฝะฐ ะฝะพะฒะฐั ะฒะตััะธั Forgejo %s, ะฒั ะธัะฟะพะปัะทัะตัะต %s. ะะพะปะตะต ะฟะพะดัะพะฑะฝัั ะธะฝัะพัะผะฐัะธั ัะธัะฐะนัะต ะฒ ะฑะปะพะณะต .
dashboard.statistic=ะกัะฐัะธััะธะบะฐ
dashboard.operations=ะะฑัะปัะถะธะฒะฐะฝะธะต
dashboard.system_status=ะกะพััะพัะฝะธะต ัะธััะตะผั
@@ -2939,7 +3094,7 @@ dashboard.delete_repo_archives=ะฃะดะฐะปะธัั ะฒัะต ะฐัั
ะธะฒั ัะตะฟะพะทะธั
dashboard.delete_repo_archives.started=ะฃะดะฐะปะตะฝะธะต ะฒัะตั
ะฐัั
ะธะฒะพะฒ ัะตะฟะพะทะธัะพัะธั ะฝะฐัะฐะปะพัั.
dashboard.delete_missing_repos=ะฃะดะฐะปะธัั ะฒัะต ะทะฐะฟะธัะธ ะพ ัะตะฟะพะทะธัะพัะธัั
ั ะพััััััะฒัััะธะผะธ ัะฐะนะปะฐะผะธ Git
dashboard.delete_missing_repos.started=ะะฐัะฐัะพ ัะดะฐะปะตะฝะธะต ะฒัะตั
ัะตะฟะพะทะธัะพัะธะตะฒ ะฑะตะท Git-ัะฐะนะปะพะฒ.
-dashboard.delete_generated_repository_avatars=ะฃะดะฐะปะธัั ะณะตะฝะตัะธัะพะฒะฐะฝะฝัะต ะฐะฒะฐัะฐัั ัะตะฟะพะทะธัะพัะธั
+dashboard.delete_generated_repository_avatars=ะฃะดะฐะปะธัั ัะณะตะฝะตัะธัะพะฒะฐะฝะฝัะต ะบะฐััะธะฝะบะธ ัะตะฟะพะทะธัะพัะธะตะฒ
dashboard.update_mirrors=ะะฑะฝะพะฒะธัั ะทะตัะบะฐะปะฐ
dashboard.repo_health_check=ะัะพะฒะตัะบะฐ ัะพััะพัะฝะธั ะฒัะตั
ัะตะฟะพะทะธัะพัะธะตะฒ
dashboard.check_repo_stats=ะัะพะฒะตัะธัั ะฒัั ััะฐัะธััะธะบั ัะตะฟะพะทะธัะพัะธั
@@ -2947,15 +3102,15 @@ dashboard.archive_cleanup=ะฃะดะฐะปะธัั ััะฐััะต ะฐัั
ะธะฒั ัะตะฟะพะทะธ
dashboard.deleted_branches_cleanup=ะัะธััะบะฐ ัะดะฐะปัะฝะฝัั
ะฒะตัะฒะตะน
dashboard.update_migration_poster_id=ะะฑะฝะพะฒะธัั ะะ ะฟะปะฐะบะฐัะพะฒ ะผะธะณัะฐัะธะธ
dashboard.git_gc_repos=ะัะฟะพะปะฝะธัั ัะฑะพัะบั ะผััะพัะฐ ะดะปั ะฒัะตั
ัะตะฟะพะทะธัะพัะธะตะฒ
-dashboard.resync_all_sshkeys=ะะฑะฝะพะฒะธัั ัะฐะนะป ยซ.ssh/authorized_keysยป ั SSH-ะบะปััะฐะผะธ Forgejo.
-dashboard.resync_all_sshprincipals=ะะฑะฝะพะฒะธัั ัะฐะนะป ยซssh/authorized_principalsยป ั ััััะฝัะผะธ ะดะฐะฝะฝัะผะธ SSH Forgejo.
-dashboard.resync_all_hooks=ะะตัะตัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐัั ั
ัะบะธ pre-receive, update ะธ post-receive ะฒัะตั
ัะตะฟะพะทะธัะพัะธะตะฒ
+dashboard.resync_all_sshkeys=ะะฑะฝะพะฒะธัั SSH-ะบะปััะธ Forgejo ะฒ ัะฐะนะปะต ยซ.ssh/authorized_keysยป.
+dashboard.resync_all_sshprincipals=ะะฑะฝะพะฒะธัั ััััะฝัะต ะดะฐะฝะฝัะต SSH Forgejo ะฒ ัะฐะนะปะต ยซ.ssh/authorized_principalsยป.
+dashboard.resync_all_hooks=ะะพะฒัะพัะฝะพ ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐัั ั
ัะบะธ pre-receive, update ะธ post-receive ะฒัะตั
ัะตะฟะพะทะธัะพัะธะตะฒ
dashboard.reinit_missing_repos=ะะตัะตะธะฝะธัะธะฐะปะธะทะธัะพะฒะฐัั ะฒัะต ะพััััััะฒัััะธะต Git ัะตะฟะพะทะธัะพัะธะธ, ะดะปั ะบะพัะพััั
ัััะตััะฒััั ะทะฐะฟะธัะธ
dashboard.sync_external_users=ะกะธะฝั
ัะพะฝะธะทะธัะพะฒะฐัั ะดะฐะฝะฝัะต ััะพัะพะฝะฝะธั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน
dashboard.cleanup_hook_task_table=ะัะธััะธัั ัะฐะฑะปะธัั hook_task
dashboard.cleanup_packages=ะัะธััะบะฐ ัััะฐัะตะฒัะธั
ะฟะฐะบะตัะพะฒ
dashboard.server_uptime=ะัะตะผั ัะฐะฑะพัั
-dashboard.current_goroutine=ะะพะปะธัะตััะฒะพ goroutines
+dashboard.current_goroutine=ะัะฟะพะปะฝัะตะผัะต goroutines
dashboard.current_memory_usage=ะขะตะบััะตะต ะธัะฟะพะปัะทะพะฒะฐะฝะธะต ะฟะฐะผััะธ
dashboard.total_memory_allocated=ะัะตะณะพ ะฟะฐะผััะธ ะฒัะดะตะปัะปะพัั
dashboard.memory_obtained=ะะพะปััะตะฝะพ ะฟะฐะผััะธ
@@ -2988,23 +3143,23 @@ dashboard.delete_old_actions.started=ะะฐะฟััะตะฝะพ ัะดะฐะปะตะฝะธะต ะฒัะตั
dashboard.update_checker=ะัะพะฒะตัะบะฐ ะพะฑะฝะพะฒะปะตะฝะธะน
dashboard.delete_old_system_notices=ะฃะดะฐะปะธัั ะฒัะต ััะฐััะต ัะธััะตะผะฝัะต ัะฒะตะดะพะผะปะตะฝะธั ะธะท ะฑะฐะทั ะดะฐะฝะฝัั
dashboard.gc_lfs=ะัะฟะพะปะฝะธัั ัะฑะพัะบั ะผััะพัะฐ ะผะตัะฐะพะฑัะตะบัะพะฒ LFS
-dashboard.stop_zombie_tasks=ะััะฐะฝะพะฒะธัั ะทะฐะดะฐะฝะธั-ะทะพะผะฑะธ
-dashboard.stop_endless_tasks=ะััะฐะฝะพะฒะธัั ะฝะตะฟัะตะบัะฐัะฐััะธะตัั ะทะฐะดะฐะฝะธั
-dashboard.cancel_abandoned_jobs=ะัะผะตะฝะธัั ะฑัะพัะตะฝะฝัะต ะทะฐะดะฐะฝะธั
-dashboard.start_schedule_tasks=ะะฐะฟัััะธัั ะทะฐะฟะปะฐะฝะธัะพะฒะฐะฝะฝัะต ะทะฐะดะฐะฝะธั
+dashboard.stop_zombie_tasks=ะััะฐะฝะพะฒะธัั ะทะพะผะฑะธ-ะทะฐะดะฐะฝะธั ะะตะนััะฒะธะน
+dashboard.stop_endless_tasks=ะััะฐะฝะพะฒะธัั ะฝะตะฟัะตะบัะฐัะฐััะธะตัั ะทะฐะดะฐะฝะธั ะะตะนััะฒะธะน
+dashboard.cancel_abandoned_jobs=ะัะผะตะฝะธัั ะฑัะพัะตะฝะฝัะต ะทะฐะดะฐะฝะธั ะะตะนััะฒะธะน
+dashboard.start_schedule_tasks=ะะฐะฟัััะธัั ะทะฐะฟะปะฐะฝะธัะพะฒะฐะฝะฝัะต ะทะฐะดะฐะฝะธั ะะตะนััะฒะธะน
users.user_manage_panel=ะฃะฟัะฐะฒะปะตะฝะธะต ะฟะพะปัะทะพะฒะฐัะตะปัะผะธ
-users.new_account=ะกะพะทะดะฐัั ะฝะพะฒัั ััััะฝัั ะทะฐะฟะธัั
+users.new_account=ะกะพะทะดะฐัั ะฝะพะฒัั ัั. ะทะฐะฟะธัั
users.name=ะะผั ะฟะพะปัะทะพะฒะฐัะตะปั
users.full_name=ะะพะปะฝะพะต ะธะผั
users.activated=ะะบัะธะฒะธัะพะฒะฐะฝ
users.admin=ะะดะผะธะฝะธัััะฐัะพั
-users.restricted=ะะณัะฐะฝะธัะตะฝะพ
+users.restricted=ะะณัะฐะฝะธัะตะฝ
users.reserved=ะ ะตะทะตัะฒ
users.bot=ะะพั
-users.2fa=ะะฒัั
ัะฐะบัะพัะฝะฐั ะฐะฒัะพัะธะทะฐัะธั
+users.2fa=2ะคะ
users.repos=ะ ะตะฟะพะทะธัะพัะธะธ
-users.created=ะกะพะทะดะฐะฝะพ
+users.created=ะ ะตะณะธัััะฐัะธั
users.last_login=ะะพัะปะตะดะฝะธะน ะฒั
ะพะด
users.never_login=ะะธะบะพะณะดะฐ ะฝะต ะฒั
ะพะดะธะป
users.send_register_notify=ะฃะฒะตะดะพะผะธัั ะพ ัะตะณะธัััะฐัะธะธ ะฟะพ ัะป. ะฟะพััะต
@@ -3018,21 +3173,21 @@ users.update_profile_success=ะัะพัะธะปั ััััะฝะพะน ะทะฐะฟะธัะธ ะพะฑะฝะพ
users.edit_account=ะะทะผะตะฝะตะฝะธะต ััััะฝะพะน ะทะฐะฟะธัะธ
users.max_repo_creation=ะะณัะฐะฝะธัะตะฝะธะต ะบะพะปะธัะตััะฒะฐ ัะตะฟะพะทะธัะพัะธะตะฒ
users.max_repo_creation_desc=(ะฃััะฐะฝะพะฒะธัะต -1 ะดะปั ะธัะฟะพะปัะทะพะฒะฐะฝะธั ััะฐะฝะดะฐััะฝะพะณะพ ะณะปะพะฑะฐะปัะฝะพะณะพ ะทะฝะฐัะตะฝะธั ะฟัะตะดะตะปะฐ)
-users.is_activated=ะญัะฐ ััััะฝะฐั ะทะฐะฟะธัั ะฐะบัะธะฒะธัะพะฒะฐะฝะฐ
-users.prohibit_login=ะั
ะพะด ะทะฐะฟัะตััะฝ
-users.is_admin=ะฏะฒะปัะตััั ะฐะดะผะธะฝะธัััะฐัะพัะพะผ
-users.is_restricted=ะะณัะฐะฝะธัะตะฝะฝะฐั
-users.allow_git_hook=ะะพะถะตั ัะพะทะดะฐะฒะฐัั Git-ั
ัะบะธ
+users.is_activated=ะะพะดัะฒะตัะถะดัะฝะฝะฐั ัั. ะทะฐะฟะธัั
+users.prohibit_login=ะัะธะพััะฐะฝะพะฒะปะตะฝะฝะฐั ัั. ะทะฐะฟะธัั
+users.is_admin=ะฃั. ะทะฐะฟะธัั ะฐะดะผะธะฝะธัััะฐัะพัะฐ
+users.is_restricted=ะะณัะฐะฝะธัะตะฝะฝะฐั ัั. ะทะฐะฟะธัั
+users.allow_git_hook=ะ ะฐะทัะตัะตะฝะพ ัะพะทะดะฐะฝะธะต Git-ั
ัะบะพะฒ
users.allow_git_hook_tooltip=Git hooks ะฒัะฟะพะปะฝััััั ะพั ะฟะพะปัะทะพะฒะฐัะตะปั ะะก, ะฟะพะด ะบะพัะพััะผ ัะฐะฑะพัะฐะตั Forgejo. ะะฝะธ ะฑัะดัั ะธะผะตัั ัะฐะบะพะน ะถะต ะดะพัััะฟ ะบ ั
ะพััั. ะะท-ะทะฐ ััะพะณะพ ะฟะพะปัะทะพะฒะฐัะตะปะธ ั ะฟัะฐะฒะฐะผะธ ะฝะฐ Git hook ะฑัะดัั ะธะผะตัั ะฒะพะทะผะพะถะฝะพััั ะฟะพะปััะฐัั ะดะพัััะฟ ะธ ะผะพะดะธัะธัะธัะพะฒะฐัั ะฒัะต ัะตะฟะพะทะธัะพัะธะธ ะฒ Forgejo, ะฐ ัะฐะบะถะต ะฑะฐะทั ะดะฐะฝะฝัั
Forgejo. ะกะปะตะดะพะฒะฐัะตะปัะฝะพ, ะพะฝะธ ัะฐะบะถะต ะผะพะณัั ะฟะพะปััะธัั ะฟัะฐะฒะฐ ะฐะดะผะธะฝะธัััะฐัะพัะฐ Forgejo.
-users.allow_import_local=ะะพะถะตั ะธะผะฟะพััะธัะพะฒะฐัั ะปะพะบะฐะปัะฝัะต ัะตะฟะพะทะธัะพัะธะธ
-users.allow_create_organization=ะะพะถะตั ัะพะทะดะฐะฒะฐัั ะพัะณะฐะฝะธะทะฐัะธะธ
+users.allow_import_local=ะ ะฐะทัะตััะฝ ะธะผะฟะพัั ะปะพะบะฐะปัะฝัั
ัะตะฟะพะทะธัะพัะธะตะฒ
+users.allow_create_organization=ะ ะฐะทัะตัะตะฝะพ ัะพะทะดะฐะฝะธะต ะพัะณะฐะฝะธะทะฐัะธะน
users.update_profile=ะะฑะฝะพะฒะธัั ััััะฝัั ะทะฐะฟะธัั
-users.delete_account=ะฃะดะฐะปะธัั ััั ััััะฝัั ะทะฐะฟะธัั
+users.delete_account=ะฃะดะฐะปะธัั ััััะฝัั ะทะฐะฟะธัั
users.cannot_delete_self=ะั ะฝะต ะผะพะถะตัะต ัะดะฐะปะธัั ัะฒะพั ััััะฝัั ะทะฐะฟะธัั
users.still_own_repo=ะญัะพั ะฟะพะปัะทะพะฒะฐัะตะปั ะฒัั ะตัั ัะฒะปัะตััั ะฒะปะฐะดะตะปััะตะผ ะพะดะฝะพะณะพ ะธะปะธ ะฑะพะปะตะต ัะตะฟะพะทะธัะพัะธะตะฒ. ะกะฝะฐัะฐะปะฐ ัะดะฐะปะธัะต ะธะปะธ ะฟะตัะตะดะฐะนัะต ััะธ ัะตะฟะพะทะธัะพัะธะธ.
users.still_has_org=ะญัะพั ะฟะพะปัะทะพะฒะฐัะตะปั ัะพััะพะธั ะฒ ะพะดะฝะพะน ะธะปะธ ะฝะตัะบะพะปัะบะธั
ะพัะณะฐะฝะธะทะฐัะธัั
. ะกะฝะฐัะฐะปะฐ ัะดะฐะปะธัะต ะฟะพะปัะทะพะฒะฐัะตะปั ะธะท ะฒัะตั
ะพัะณะฐะฝะธะทะฐัะธะน.
-users.purge=ะฃะดะฐะปะธัั ะฟะพะปัะทะพะฒะฐัะตะปั
-users.purge_help=ะัะธะฝัะดะธัะตะปัะฝะพะต ัะดะฐะปะตะฝะธะต ะฟะพะปัะทะพะฒะฐัะตะปั ะธ ะปัะฑัั
ัะตะฟะพะทะธัะพัะธะตะฒ, ะพัะณะฐะฝะธะทะฐัะธะน ะธ ะฟะฐะบะตัะพะฒ, ะฟัะธะฝะฐะดะปะตะถะฐัะธั
ะฟะพะปัะทะพะฒะฐัะตะปั. ะัะต ะบะพะผะผะตะฝัะฐัะธะธ ะธ ะทะฐะดะฐัะธ ััะพะณะพ ะฟะพะปัะทะพะฒะฐัะตะปั ัะพะถะต ะฑัะดัั ัะดะฐะปะตะฝั.
+users.purge=ะฃะฝะธััะพะถะธัั ะดะฐะฝะฝัะต
+users.purge_help=ะัะธะฝัะดะธัะตะปัะฝะพ ัะดะฐะปะธัั ะฒัะต ะดะฐะฝะฝัะต, ัะฒัะทะฐะฝะฝัะต ั ััะธะผ ะฟะพะปัะทะพะฒะฐัะตะปะตะผ: ะฒัะต ะตะณะพ ัะตะฟะพะทะธัะพัะธะธ, ะพัะณะฐะฝะธะทะฐัะธะธ, ะฟะฐะบะตัั, ะฒัะต ัะพะทะดะฐะฝะฝัะต ะธะผ ะทะฐะดะฐัะธ ะธ ะพััะฐะฒะปะตะฝะฝัะต ะบะพะผะผะตะฝัะฐัะธะธ.
users.still_own_packages=ะญัะพั ะฟะพะปัะทะพะฒะฐัะตะปั ะฒัั ะตัั ะฒะปะฐะดะตะตั ะพะดะฝะธะผ ะธะปะธ ะฝะตัะบะพะปัะบะธะผะธ ะฟะฐะบะตัะฐะผะธ, ัะฝะฐัะฐะปะฐ ัะดะฐะปะธัะต ะธั
.
users.deletion_success=ะฃัััะฝะฐั ะทะฐะฟะธัั ััะฟะตัะฝะพ ัะดะฐะปะตะฝะฐ.
users.reset_2fa=ะกะฑัะพั 2ะคะ
@@ -3067,11 +3222,11 @@ orgs.org_manage_panel=ะฃะฟัะฐะฒะปะตะฝะธะต ะพัะณะฐะฝะธะทะฐัะธัะผะธ
orgs.name=ะะฐะทะฒะฐะฝะธะต
orgs.teams=ะะพะผะฐะฝะดั
orgs.members=ะฃัะฐััะฝะธะบะธ
-orgs.new_orga=ะะพะฒะฐั ะพัะณะฐะฝะธะทะฐัะธั
+orgs.new_orga=ะกะพะทะดะฐัั ะพัะณะฐะฝะธะทะฐัะธั
repos.repo_manage_panel=ะฃะฟัะฐะฒะปะตะฝะธะต ัะตะฟะพะทะธัะพัะธัะผะธ
repos.unadopted=ะะตะฟัะธะฝัััะต ัะตะฟะพะทะธัะพัะธะธ
-repos.unadopted.no_more=ะะพะปััะต ะฝะตะฟัะธะฝัััั
ัะตะฟะพะทะธัะพัะธะตะฒ ะฝะต ะฝะฐะนะดะตะฝะพ
+repos.unadopted.no_more=ะะตะฟัะธะฝัััะต ัะตะฟะพะทะธัะพัะธะธ ะฝะต ะฝะฐะนะดะตะฝั.
repos.owner=ะะปะฐะดะตะปะตั
repos.name=ะะฐะทะฒะฐะฝะธะต
repos.private=ะงะฐััะฝัะน
@@ -3084,7 +3239,7 @@ repos.lfs_size=ะ ะฐะทะผะตั LFS
packages.package_manage_panel=ะฃะฟัะฐะฒะปะตะฝะธะต ะฟะฐะบะตัะฐะผะธ
packages.total_size=ะะฑัะธะน ัะฐะทะผะตั: %s
-packages.unreferenced_size=ะ ะฐะทะผะตั ะฟะพ ัััะปะบะต: %s
+packages.unreferenced_size=ะะตัะบะฐะทะฐะฝะฝัะน ัะฐะทะผะตั: %s
packages.cleanup=ะัะธััะธัั ัััะฐัะตะฒัะธะต ะดะฐะฝะฝัะต
packages.cleanup.success=ะัะธััะบะฐ ัััะฐัะตะฒัะธั
ะดะฐะฝะฝัั
ััะฟะตัะฝะพ ะทะฐะฒะตััะตะฝะฐ
packages.owner=ะะปะฐะดะตะปะตั
@@ -3118,7 +3273,7 @@ auths.domain=ะะพะผะตะฝ
auths.host=ะกะตัะฒะตั
auths.port=ะะพัั
auths.bind_dn=Bind DN
-auths.bind_password=ะัะธะฒัะทะฐัั ะฟะฐัะพะปั
+auths.bind_password=ะะฐัะพะปั bind
auths.user_base=ะะฐะทะฐ ะฟะพะธัะบะฐ ะฟะพะปัะทะพะฒะฐัะตะปะตะน
auths.user_dn=DN ะฟะพะปัะทะพะฒะฐัะตะปั
auths.attribute_username=ะััะธะฑัั username
@@ -3127,15 +3282,15 @@ auths.attribute_name=ะััะธะฑัั first name
auths.attribute_surname=ะััะธะฑัั surname
auths.attribute_mail=ะััะธะฑัั ัะป. ะฟะพััั
auths.attribute_ssh_public_key=ะััะธะฑัั ะพัะบัััะพะณะพ ะบะปััะฐ SSH
-auths.attribute_avatar=ะััะธะฑัั ะฐะฒะฐัะฐัะฐ
-auths.attributes_in_bind=ะะทะฒะปะตะบะฐัั ะฐััะธะฑััั ะฒ ะบะพะฝัะตะบััะต Bind DN
+auths.attribute_avatar=ะััะธะฑัั ะธะทะพะฑัะฐะถะตะฝะธั ะฟัะพัะธะปั (avatar)
+auths.attributes_in_bind=ะะทะฒะปะตะบะฐัั ะฐััะธะฑััั ะฒ ะบะพะฝัะตะบััะต bind DN
auths.allow_deactivate_all=ะ ะฐะทัะตัะธัั ะฟัััะพะน ัะตะทัะปััะฐั ะฟะพะธัะบะฐ ะดะปั ะพัะบะปััะตะฝะธั ะฒัะตั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน
auths.use_paged_search=ะัะฟะพะปัะทะพะฒะฐัั ะฟะพัััะฐะฝะธัะฝัะน ะฟะพะธัะบ
auths.search_page_size=ะ ะฐะทะผะตั ัััะฐะฝะธัั
-auths.filter=ะคะธะปััั ะฟะพะปัะทะพะฒะฐัะตะปั
-auths.admin_filter=ะคะธะปััั ะฐะดะผะธะฝะธัััะฐัะพัะฐ
-auths.restricted_filter=ะะณัะฐะฝะธัะตะฝะฝัะน ัะธะปััั
-auths.restricted_filter_helper=ะััะฐะฒััะต ะฟััััะผ, ััะพะฑั ะฝะต ะฝะฐะทะฝะฐัะฐัั ะฝะธะบะฐะบะธั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน ะพะณัะฐะฝะธัะตะฝะฝัะผะธ. ะัะฟะพะปัะทัะนัะต ะทะฒัะทะดะพัะบั (ยซ*ยป), ััะพะฑั ัะดะตะปะฐัั ะพะณัะฐะฝะธัะตะฝะฝัะผะธ ะฒัะตั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน, ะฝะต ัะพะพัะฒะตัััะฒัััะธั
ัะธะปัััั ะฐะดะผะธะฝะธัััะฐัะพัะฐ.
+auths.filter=ะคะธะปััั ะฟะพะปัะทะพะฒะฐัะตะปะตะน
+auths.admin_filter=ะคะธะปััั ะฐะดะผะธะฝะธัััะฐัะพัะพะฒ
+auths.restricted_filter=ะคะธะปััั ะพะณัะฐะฝะธัะตะฝะฝัั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน
+auths.restricted_filter_helper=ะััะฐะฒััะต ะฟััััะผ, ััะพะฑั ะฝะต ะพะณัะฐะฝะธัะธะฒะฐัั ะฝะธะบะฐะบะธั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน. ะฃะบะฐะถะธัะต ะทะฒัะทะดะพัะบั (ยซ*ยป), ััะพะฑั ะพะณัะฐะฝะธัะธัั ะฒัะตั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน, ะฝะต ัะฒะปัััะธั
ัั ะฐะดะผะธะฝะธัััะฐัะพัะฐะผะธ.
auths.verify_group_membership=ะัะพะฒะตัะธัั ะฟัะธะฝะฐะดะปะตะถะฝะพััั ะบ ะณััะฟะฟะต ะฒ LDAP (ะพััะฐะฒััะต ัะธะปััั ะฟััััะผ, ััะพะฑั ะฟัะพะฟัััะธัั)
auths.group_search_base=ะะพะธัะบะพะฒะฐั ะฑะฐะทะฐ ะณััะฟะฟ DN
auths.group_attribute_list_users=ะััะธะฑัั ะณััะฟะฟั, ัะพะดะตัะถะฐัะธะน ัะฟะธัะพะบ ะฟะพะปัะทะพะฒะฐัะตะปะตะน
@@ -3152,11 +3307,11 @@ auths.allowed_domains_helper=ะ ะฐะทะดะตะปัะนัะต ะดะพะผะตะฝั ะทะฐะฟัััะผะธ
auths.skip_tls_verify=ะัะพะฟััะบ ะฟัะพะฒะตัะบะธ TLS
auths.force_smtps=ะัะธะฝัะดะธัะตะปัะฝัะน SMTPS
auths.force_smtps_helper=SMTPS ะฒัะตะณะดะฐ ะธัะฟะพะปัะทัะตั 465 ะฟะพัั. ะฃััะฐะฝะพะฒะธัะต ััะพ, ััะพ ะฑั ะฟัะธะฝัะดะธัะตะปัะฝะพ ะธัะฟะพะปัะทะพะฒะฐัั SMTPS ะฝะฐ ะดััะณะธั
ะฟะพััะฐั
. (ะะฝะฐัะต STARTTLS ะฑัะดะตั ะธัะฟะพะปัะทะพะฒะฐัััั ะฝะฐ ะดััะณะธั
ะฟะพััะฐั
, ะตัะปะธ ััะพ ะฟะพะดะดะตัะถะธะฒะฐะตััั ั
ะพััะพะผ.)
-auths.helo_hostname=HELO Hostname
+auths.helo_hostname=ะะผั ั
ะพััะฐ HELO
auths.helo_hostname_helper=ะะผั ั
ะพััะฐ ะพัะฟัะฐะฒะปัะตััั ั HELO. ะััะฐะฒััะต ะฟะพะปะต ะฟััััะผ, ััะพะฑั ะพัะฟัะฐะฒะธัั ัะตะบััะตะต ะธะผั ั
ะพััะฐ.
auths.disable_helo=ะัะบะปััะธัั HELO
auths.pam_service_name=ะะผั ัะปัะถะฑั PAM
-auths.pam_email_domain=ะะพะผะตะฝ ะฟะพััั PAM (ะฝะตะพะฑัะทะฐัะตะปัะฝะพ)
+auths.pam_email_domain=ะะพััะพะฒัะน ะดะพะผะตะฝ PAM (ะฝะตะพะฑัะทะฐัะตะปะตะฝ)
auths.oauth2_provider=ะะพััะฐะฒัะธะบ OAuth2
auths.oauth2_icon_url=URL ะธะบะพะฝะบะธ
auths.oauth2_clientID=ID ะบะปะธะตะฝัะฐ (ะบะปัั)
@@ -3170,17 +3325,17 @@ auths.oauth2_emailURL=URL ัะป. ะฟะพััั
auths.skip_local_two_fa=ะัะพะฟัััะธัั ะปะพะบะฐะปัะฝัั ะดะฒัั
ัะฐะบัะพัะฝัั ะฐััะตะฝัะธัะธะบะฐัะธั
auths.skip_local_two_fa_helper=ะัะปะธ ะทะฝะฐัะตะฝะธะต ะฝะต ะทะฐะดะฐะฝะพ, ะปะพะบะฐะปัะฝัะผ ะฟะพะปัะทะพะฒะฐัะตะปัะผ ั ัััะฐะฝะพะฒะปะตะฝะฝะพะน ะดะฒัั
ัะฐะบัะพัะฝะพะน ะฐััะตะฝัะธัะธะบะฐัะธะตะน ะฒัะต ัะฐะฒะฝะพ ะฟัะธะดะตััั ะฟัะพะนัะธ ะดะฒัั
ัะฐะบัะพัะฝัั ะฐััะตะฝัะธัะธะบะฐัะธั ะดะปั ะฒั
ะพะดะฐ ะฒ ัะธััะตะผั
auths.oauth2_tenant=Tenant
-auths.oauth2_scopes=ะะพะฟะพะปะฝะธัะตะปัะฝัะต ะฟะพะปะฝะพะผะพัะธั
-auths.oauth2_required_claim_name=ะะตะพะฑั
ะพะดะธะผะพะต ะธะผั ะทะฐัะฒะบะธ
+auths.oauth2_scopes=ะะพะฟะพะปะฝะธัะตะปัะฝัะต ัะฐะทัะตัะตะฝะธั
+auths.oauth2_required_claim_name=ะขัะตะฑัะตะผะพะต ะธะผั ะทะฐัะฒะบะธ
auths.oauth2_required_claim_name_helper=ะะฐะดะฐะนัะต, ััะพะฑั ะพะณัะฐะฝะธัะธัั ะฒั
ะพะด ั ััะพะณะพ ะธััะพัะฝะธะบะฐ ัะพะปัะบะพ ะฟะพะปัะทะพะฒะฐัะตะปัะผะธ ั ะทะฐัะฒะบะพะน, ะธะผะตััะตะน ัะฐะบะพะต ะธะผั
-auths.oauth2_required_claim_value=ะะตะพะฑั
ะพะดะธะผะพะต ะทะฝะฐัะตะฝะธะต ะทะฐัะฒะบะธ
+auths.oauth2_required_claim_value=ะขัะตะฑัะตะผะพะต ะทะฝะฐัะตะฝะธะต ะทะฐัะฒะบะธ
auths.oauth2_required_claim_value_helper=ะะฐะดะฐะนัะต, ััะพะฑั ะพะณัะฐะฝะธัะธัั ะฒั
ะพะด ั ััะพะณะพ ะธััะพัะฝะธะบะฐ ัะพะปัะบะพ ะฟะพะปัะทะพะฒะฐัะตะปัะผะธ ั ะทะฐัะฒะบะพะน, ะธะผะตััะตะน ัะฐะบะธะต ะธะผั ะธ ะทะฝะฐัะตะฝะธะต
auths.oauth2_group_claim_name=ะะผั ะทะฐัะฒะบะธ, ัะบะฐะทัะฒะฐััะตะต ะธะผะตะฝะฐ ะณััะฟะฟ ะดะปั ััะพะณะพ ะธััะพัะฝะธะบะฐ. (ะะตะพะฑัะทะฐัะตะปัะฝะพ)
auths.oauth2_admin_group=ะะฝะฐัะตะฝะธะต ะทะฐัะฒะบะธ ะณััะฟะฟั ะดะปั ะฐะดะผะธะฝะธัััะฐัะพัะพะฒ. (ะะตะพะฑัะทะฐัะตะปัะฝะพ - ััะตะฑัะตััั ะธะผั ะทะฐัะฒะบะธ ะฒััะต)
auths.oauth2_restricted_group=ะะฝะฐัะตะฝะธะต ะทะฐัะฒะบะธ ะณััะฟะฟั ะดะปั ะพะณัะฐะฝะธัะตะฝะฝัั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน. (ะะตะพะฑัะทะฐัะตะปัะฝะพ - ััะตะฑัะตััั ะธะผั ะทะฐัะฒะบะธ ะฒััะต)
auths.oauth2_map_group_to_team=ะกะพะฟะพััะฐะฒะปะตะฝะธะต ะทะฐัะฒะปะตะฝะฝัั
ะณััะฟะฟ ะบะพะผะฐะฝะดะฐะผ ะพัะณะฐะฝะธะทะฐัะธะธ. (ะะตะพะฑัะทะฐัะตะปัะฝะพ โ ััะตะฑัะตััั ะธะผั ะทะฐัะฒะบะธ ะฒััะต)
auths.oauth2_map_group_to_team_removal=ะฃะดะฐะปะธัั ะฟะพะปัะทะพะฒะฐัะตะปะตะน ะธะท ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐะฝะฝัั
ะบะพะผะฐะฝะด, ะตัะปะธ ะฟะพะปัะทะพะฒะฐัะตะปั ะฝะต ะฟัะธะฝะฐะดะปะตะถะธั ะบ ัะพะพัะฒะตัััะฒัััะตะน ะณััะฟะฟะต.
-auths.enable_auto_register=ะะบะปััะธัั ะฐะฒัะพะผะฐัะธัะตัะบัั ัะตะณะธัััะฐัะธั
+auths.enable_auto_register=ะะฒัะพะผะฐัะธัะตัะบะฐั ัะตะณะธัััะฐัะธั
auths.sspi_auto_create_users=ะะฒัะพะผะฐัะธัะตัะบะธ ัะพะทะดะฐะฒะฐัั ะฟะพะปัะทะพะฒะฐัะตะปะตะน
auths.sspi_auto_create_users_helper=ะ ะฐะทัะตัะธัั ะผะตัะพะด ะฐััะตะฝัะธัะธะบะฐัะธะธ SSPI ะดะปั ะฐะฒัะพะผะฐัะธัะตัะบะพะณะพ ัะพะทะดะฐะฝะธั ะฝะพะฒัั
ััััะฝัั
ะทะฐะฟะธัะตะน ะดะปั ะฟะพะปัะทะพะฒะฐัะตะปะตะน, ะบะพัะพััะต ะฒะฟะตัะฒัะต ะฒั
ะพะดัั ะฒ ัะธััะตะผั
auths.sspi_auto_activate_users=ะะฒัะพะผะฐัะธัะตัะบะธ ะฐะบัะธะฒะธัะพะฒะฐัั ะฟะพะปัะทะพะฒะฐัะตะปะตะน
@@ -3194,24 +3349,24 @@ auths.sspi_default_language_helper=ะฏะทัะบ ะฟะพ ัะผะพะปัะฐะฝะธั ะดะปั ะฟะพ
auths.tips=ะกะพะฒะตัั
auths.tips.oauth2.general=ะััะตะฝัะธัะธะบะฐัะธั OAuth2
auths.tip.oauth2_provider=ะะพััะฐะฒัะธะบ OAuth2
-auths.tip.bitbucket=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะณะพ ะฟะพััะตะฑะธัะตะปั OAuth ะฝะฐ https://bitbucket.org/account/user/<ะธะผั ะฟะพะปัะทะพะฒะฐัะตะปั>/oauth-consumers/new ะธ ะดะพะฑะฐะฒััะต ะฟัะฐะฒะพ ยซAccountยป - ยซReadยป
+auths.tip.bitbucket=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะณะพ ะฟะพััะตะฑะธัะตะปั OAuth ะฝะฐ %s
auths.tip.nextcloud=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะณะพ ะฟะพััะตะฑะธัะตะปั OAuth ะฒ ะฒะฐัะตะผ ัะตัะฒะตัะต, ะธัะฟะพะปัะทัั ะผะตะฝั ยซะะฐัััะพะนะบะธ -> ะะตะทะพะฟะฐัะฝะพััั -> ะะปะธะตะฝั OAuth 2.0ยป
-auths.tip.dropbox=ะกะพะทะดะฐะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฝะฐ https://www.dropbox.com/developers/apps
-auths.tip.facebook=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฝะฐ https://developers.facebook.com/apps ะธ ะดะพะฑะฐะฒััะต ะผะพะดัะปั ยซFacebook Loginยป
-auths.tip.github=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต OAuth ะฝะฐ https://github.com/settings/applications/new
+auths.tip.dropbox=ะกะพะทะดะฐะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฝะฐ %s
+auths.tip.facebook=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฝะฐ %s ะธ ะดะพะฑะฐะฒััะต ะผะพะดัะปั ยซFacebook Loginยป
+auths.tip.github=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต OAuth ะฝะฐ %s
auths.tip.gitlab=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฝะฐ https://gitlab.com/profile/applications
-auths.tip.google_plus=ะะพะปััะธัะต ััััะฝัะต ะดะฐะฝะฝัะต ะบะปะธะตะฝัะฐ OAuth2 ะฒ ะบะพะฝัะพะปะธ Google API ะฝะฐ ัััะฐะฝะธัะต https://console.developers.google.com/
+auths.tip.google_plus=ะะพะปััะธัะต ััััะฝัะต ะดะฐะฝะฝัะต ะบะปะธะตะฝัะฐ OAuth2 ะฒ ะบะพะฝัะพะปะธ Google API ะฝะฐ ัััะฐะฝะธัะต %s
auths.tip.openid_connect=ะัะฟะพะปัะทัะนัะต URL ะฒ OpenID Connect Discovery (/.well-known/openid-configuration) ะดะปั ัะบะฐะทะฐะฝะธั ะบะพะฝะตัะฝัั
ัะพัะตะบ
-auths.tip.twitter=ะะตัะตะนะดะธัะต ะฝะฐ https://dev.twitter.com/apps, ัะพะทะดะฐะนัะต ะฟัะธะปะพะถะตะฝะธะต ะธ ัะฑะตะดะธัะตัั, ััะพ ะฒะบะปััะตะฝะฐ ะพะฟัะธั ยซะ ะฐะทัะตัะธัั ะธัะฟะพะปัะทะพะฒะฐัั ััะพ ะฟัะธะปะพะถะตะฝะธะต ะดะปั ะฒั
ะพะดะฐ ัะตัะตะท Twitterยป
-auths.tip.discord=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฝะฐ https://discordapp.com/developers/applications/me
-auths.tip.yandex=ะกะพะทะดะฐะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฝะฐ https://oauth.yandex.com/client/new. ะ ัะฐะทะดะตะปะต ยซAPI ะฏะฝะดะตะบั.ะะฐัะฟะพััะฐยป ะฒัะฑะตัะธัะต ัะปะตะดัััะธะต ัะฐะทัะตัะตะฝะธั: ยซะะพัััะฟ ะบ ะฐะดัะตัั ัะป. ะฟะพัััยป, ยซะะพัััะฟ ะบ ะฐะฒะฐัะฐัั ะฟะพะปัะทะพะฒะฐัะตะปัยป ะธ ยซะะพัััะฟ ะบ ะปะพะณะธะฝั, ะธะผะตะฝะธ, ัะฐะผะธะปะธะธ ะธ ะฟะพะปัยป
+auths.tip.twitter=ะะตัะตะนะดะธัะต ะฝะฐ %s, ัะพะทะดะฐะนัะต ะฟัะธะปะพะถะตะฝะธะต ะธ ัะฑะตะดะธัะตัั, ััะพ ะฒะบะปััะตะฝะฐ ะพะฟัะธั ยซะ ะฐะทัะตัะธัั ะธัะฟะพะปัะทะพะฒะฐัั ััะพ ะฟัะธะปะพะถะตะฝะธะต ะดะปั ะฒั
ะพะดะฐ ัะตัะตะท Twitterยป
+auths.tip.discord=ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฝะฐ %s
+auths.tip.yandex=ะกะพะทะดะฐะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฝะฐ %s. ะ ัะฐะทะดะตะปะต ยซAPI ะฏะฝะดะตะบั.ะะฐัะฟะพััะฐยป ะฒัะฑะตัะธัะต ัะปะตะดัััะธะต ัะฐะทัะตัะตะฝะธั: ยซะะพัััะฟ ะบ ะฐะดัะตัั ัะปะตะบััะพะฝะฝะพะน ะฟะพัััยป, ยซะะพัััะฟ ะบ ะฟะพัััะตัั ะฟะพะปัะทะพะฒะฐัะตะปัยป ะธ ยซะะพัััะฟ ะบ ะปะพะณะธะฝั, ะธะผะตะฝะธ, ัะฐะผะธะปะธะธ, ะฟะพะปัยป
auths.tip.mastodon=ะะฒะตะดะธัะต URL ัะตัะฒะตัะฐ Mastodon, ะบะพัะพััะน ั
ะพัะธัะต ะธัะฟะพะปัะทะพะฒะฐัั (ะธะปะธ ะพััะฐะฒััะต ัะตัะฒะตั ะฟะพ ัะผะพะปัะฐะฝะธั)
-auths.edit=ะะฑะฝะพะฒะธัั ะฟะฐัะฐะผะตััั ะฐััะตะฝัะธัะธะบะฐัะธะธ
+auths.edit=ะะทะผะตะฝะธัั ะฟะฐัะฐะผะตััั ะฐััะตะฝัะธัะธะบะฐัะธะธ
auths.activated=ะััะพัะฝะธะบ ะฐััะตะฝัะธัะธะบะฐัะธะธ ะฐะบัะธะฒะธัะพะฒะฐะฝ
auths.new_success=ะะตัะพะด ะฐััะตะฝัะธัะธะบะฐัะธะธ ยซ%sยป ะดะพะฑะฐะฒะปะตะฝ.
auths.update_success=ะััะพัะฝะธะบ ะฐััะตะฝัะธัะธะบะฐัะธะธ ะพะฑะฝะพะฒะปัะฝ.
auths.update=ะะฑะฝะพะฒะธัั ะธััะพัะฝะธะบ ะฐััะตะฝัะธัะธะบะฐัะธะธ
-auths.delete=ะฃะดะฐะปะธัั ััะพั ะธััะพัะฝะธะบ ะฐััะตะฝัะธัะธะบะฐัะธะธ
+auths.delete=ะฃะดะฐะปะธัั ะธััะพัะฝะธะบ ะฐััะตะฝัะธัะธะบะฐัะธะธ
auths.delete_auth_title=ะฃะดะฐะปะธัั ะธััะพัะฝะธะบ ะฐััะตะฝัะธัะธะบะฐัะธะธ
auths.delete_auth_desc=ะฃะดะฐะปะตะฝะธะต ะธััะพัะฝะธะบะฐ ะฐััะตะฝัะธัะธะบะฐัะธะธ ะฝะต ะฟะพะทะฒะพะปัะตั ะฟะพะปัะทะพะฒะฐัะตะปัะผ ะธัะฟะพะปัะทะพะฒะฐัั ะตะณะพ ะดะปั ะฒั
ะพะดะฐ. ะัะพะดะพะปะถะธัั?
auths.still_in_used=ะญัะฐ ะฟัะพะฒะตัะบะฐ ะฟะพะดะปะธะฝะฝะพััะธ ะดะพ ัะธั
ะฟะพั ะธัะฟะพะปัะทัะตััั ะฝะตะบะพัะพััะผะธ ะฟะพะปัะทะพะฒะฐัะตะปัะผะธ, ัะดะฐะปะธัะต ะธะปะธ ะฟัะตะพะฑัะฐะทัะนัะต ััะธั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน ะฒ ะดััะณะพะน ัะธะฟ ะฒั
ะพะดะฐ ะฒ ัะธััะตะผั.
@@ -3224,13 +3379,13 @@ auths.invalid_openIdConnectAutoDiscoveryURL=ะะตะฒะตัะฝัะน URL ะดะปั ะฐะฒัะพ
config.server_config=ะะพะฝัะธะณััะฐัะธั ัะตัะฒะตัะฐ
config.app_name=ะะฐะทะฒะฐะฝะธะต ัะตัะฒะตัะฐ
config.app_ver=ะะตััะธั Forgejo
-config.app_url=ะะฐะทะพะฒัะน URL Forgejo
+config.app_url=ะะฐะทะพะฒัะน URL
config.custom_conf=ะััั ะบ ัะฐะนะปั ะบะพะฝัะธะณััะฐัะธะธ
config.custom_file_root_path=ะััั ะดะพ ะบะฐัะฐะปะพะณะฐ ั ัะฐะนะปะฐะผะธ ะดะปั ะฟะตััะพะฝะฐะปะธะทะฐัะธะธ
config.domain=ะะพะผะตะฝ ัะตัะฒะตัะฐ
config.offline_mode=ะะพะบะฐะปัะฝัะน ัะตะถะธะผ
config.disable_router_log=ะัะบะปััะตะฝะธะต ะถััะฝะฐะปะฐ ะผะฐัััััะธะทะฐัะพัะฐ
-config.run_user=ะะฐะฟััะบ ะพั ะธะผะตะฝะธ ะฟะพะปัะทะพะฒะฐัะตะปั
+config.run_user=ะ ะฐะฑะพัะฐ ะฟะพะด ะฟะพะปัะทะพะฒะฐัะตะปะตะผ
config.run_mode=ะ ะตะถะธะผ ัะฐะฑะพัั
config.git_version=ะะตััะธั git
config.app_data_path=ะััั ะบ ะดะฐะฝะฝัะผ ะฟัะธะปะพะถะตะฝะธั
@@ -3249,8 +3404,8 @@ config.ssh_listen_port=ะัะพัะปััะธะฒะฐะตะผัะน ะฟะพัั
config.ssh_root_path=ะะพัะฝะตะฒะพะน ะฟััั
config.ssh_key_test_path=ะััั ะบ ัะตััะพะฒะพะผั ะบะปััั
config.ssh_keygen_path=ะััั ะดะพ ะณะตะฝะตัะฐัะพัะฐ ะบะปััะตะน (ยซssh-keygenยป)
-config.ssh_minimum_key_size_check=ะะธะฝะธะผะฐะปัะฝัะน ัะฐะทะผะตั ะบะปััะฐ ะฟัะพะฒะตัะบะธ
-config.ssh_minimum_key_sizes=ะะธะฝะธะผะฐะปัะฝัะต ัะฐะทะผะตัั ะบะปััะฐ
+config.ssh_minimum_key_size_check=ะัะพะฒะตัะบะฐ ะผะธะฝะธะผะฐะปัะฝะพะณะพ ัะฐะทะผะตั ะบะปััะฐ
+config.ssh_minimum_key_sizes=ะะธะฝะธะผะฐะปัะฝัะต ัะฐะทะผะตัั ะบะปััะตะน
config.lfs_config=ะะพะฝัะธะณััะฐัะธั LFS
config.lfs_enabled=ะะบะปััะตะฝะพ
@@ -3274,16 +3429,16 @@ config.allow_only_external_registration=ะ ะตะณะธัััะฐัะธั ัะพะปัะบะพ ัะต
config.enable_openid_signup=ะกะฐะผะพัะตะณะธัััะฐัะธั ัะตัะตะท OpenID
config.enable_openid_signin=ะั
ะพะด ัะตัะตะท OpenID
config.show_registration_button=ะะฝะพะฟะบะฐ ัะตะณะธัััะฐัะธะธ
-config.require_sign_in_view=ะะปั ะฟัะพัะผะพััะฐ ะฝะตะพะฑั
ะพะดะธะผะฐ ะฐะฒัะพัะธะทะฐัะธั
+config.require_sign_in_view=ะขัะตะฑะพะฒะฐัั ะฐะฒัะพัะธะทะฐัะธั ะดะปั ะฟัะพัะผะพััะฐ ัะพะดะตัะถะธะผะพะณะพ
config.mail_notify=ะฃะฒะตะดะพะผะปะตะฝะธั ะฟะพ ัะป. ะฟะพััะต
config.enable_captcha=CAPTCHA
config.active_code_lives=ะกัะพะบ ะดะตะนััะฒะธั ะบะพะดะฐ ะฐะบัะธะฒะฐัะธะธ ััััะฝะพะน ะทะฐะฟะธัะธ
config.reset_password_code_lives=ะกัะพะบ ะดะตะนััะฒะธั ะบะพะดะฐ ะฒะพัััะฐะฝะพะฒะปะตะฝะธั ััััะฝะพะน ะทะฐะฟะธัะธ
config.default_keep_email_private=ะกะบััะฒะฐัั ะฐะดัะตัะฐ ัะป. ะฟะพััั ะฟะพ ัะผะพะปัะฐะฝะธั
config.default_allow_create_organization=ะ ะฐะทัะตัะธัั ัะพะทะดะฐะฝะธะต ะพัะณะฐะฝะธะทะฐัะธะน ะฟะพ ัะผะพะปัะฐะฝะธั
-config.enable_timetracking=ะััะปะตะถะธะฒะฐะฝะธะต ะฒัะตะผะตะฝะธ
-config.default_enable_timetracking=ะะบะปััะธัั ะพััะปะตะถะธะฒะฐะฝะธะต ะฒัะตะผะตะฝะธ ะฟะพ ัะผะพะปัะฐะฝะธั
-config.allow_dots_in_usernames = ะ ะฐะทัะตัะธัั ัะพัะบะธ ะฒ ะปะพะณะธะฝะฐั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน. ะญัะพ ะฝะต ะฟะพะฒะปะธัะตั ะฝะฐ ัะถะต ัะพะทะดะฐะฝะฝัะต ััััะฝัะต ะทะฐะฟะธัะธ.
+config.enable_timetracking=ะกััััะธะบ ะฒัะตะผะตะฝะธ
+config.default_enable_timetracking=ะะบะปััะธัั ัััััะธะบ ะทะฐััะฐัะตะฝะฝะพะณะพ ะฒัะตะผะตะฝะธ ะฟะพ ัะผะพะปัะฐะฝะธั
+config.allow_dots_in_usernames = ะ ะฐะทัะตัะธัั ัะพัะบะธ ะฒ ะธะผะตะฝะฐั
ะฟะพะปัะทะพะฒะฐัะตะปะตะน. ะญัะพ ะฝะต ะฟะพะฒะปะธัะตั ะฝะฐ ัะถะต ัะพะทะดะฐะฝะฝัะต ััััะฝัะต ะทะฐะฟะธัะธ.
config.default_allow_only_contributors_to_track_time=ะะพะดััะธััะฒะฐัั ะฒัะตะผั ะผะพะณัั ัะพะปัะบะพ ัะพะฐะฒัะพัั
config.no_reply_address=ะะพะผะตะฝ ัะบััััั
ะฐะดัะตัะพะฒ ะฟะพััั
config.default_visibility_organization=ะะธะดะธะผะพััั ะฝะพะฒัั
ะพัะณะฐะฝะธะทะฐัะธะน ะฟะพ ัะผะพะปัะฐะฝะธั
@@ -3303,7 +3458,7 @@ config.mailer_smtp_addr=ะะดัะตั SMTP
config.mailer_smtp_port=ะะพัั SMTP
config.mailer_user=ะะพะปัะทะพะฒะฐัะตะปั
config.mailer_use_sendmail=ะัะฟะพะปัะทะพะฒะฐัั Sendmail
-config.mailer_sendmail_path=ะััั ะบ Sendmail
+config.mailer_sendmail_path=ะััั Sendmail
config.mailer_sendmail_args=ะะพะฟะพะปะฝะธัะตะปัะฝัะต ะฐัะณัะผะตะฝัั ะดะปั Sendmail
config.mailer_sendmail_timeout=ะััะตัะตะฝะธะต ะพะถะธะดะฐะฝะธั Sendmail
config.mailer_use_dummy=ะะฐะณะปััะบะฐ
@@ -3322,7 +3477,7 @@ config.cache_interval=ะะฝัะตัะฒะฐะป ะบััะธัะพะฒะฐะฝะธั
config.cache_conn=ะะพะดะบะปััะตะฝะธะต ะบััะฐ
config.cache_item_ttl=ะัะตะผั ะถะธะทะฝะธ ะดะฐะฝะฝัั
ะฒ ะบะตัะต
-config.session_config=ะะพะฝัะธะณััะฐัะธั ัะตััะธะธ
+config.session_config=ะะพะฝัะธะณััะฐัะธั ัะตััะธะน
config.session_provider=ะัะพะฒะฐะนะดะตั ัะตััะธะธ
config.provider_config=ะะพะฝัะธะณััะฐัะธั ะฟัะพะฒะฐะนะดะตัะฐ
config.cookie_name=ะะผั ัะฐะนะปะฐ cookie
@@ -3331,10 +3486,10 @@ config.session_life_time=ะัะตะผั ะถะธะทะฝะธ ัะตััะธะธ
config.https_only=ะขะพะปัะบะพ HTTPS
config.cookie_life_time=ะัะตะผั ะถะธะทะฝะธ ัะฐะนะปะฐ cookie
-config.picture_config=ะะพะฝัะธะณััะฐัะธั ะฐะฒะฐัะฐัะพะฒ ะธ ะธะทะพะฑัะฐะถะตะฝะธะน
+config.picture_config=ะะพะฝัะธะณััะฐัะธั ะธะทะพะฑัะฐะถะตะฝะธะน ะฟัะพัะธะปะตะน
config.picture_service=ะกะปัะถะฑะฐ ะธะทะพะฑัะฐะถะตะฝะธะน
config.disable_gravatar=ะัะบะปััะธัั Gravatar
-config.enable_federated_avatar=ะคะตะดะตัะธัะพะฒะฐะฝะฝัะต ะฐะฒะฐัะฐัั
+config.enable_federated_avatar=ะคะตะดะตัะธัะพะฒะฐะฝะฝัะต ะธะทะพะฑัะฐะถะตะฝะธั ะฟัะพัะธะปะตะน
config.git_config=ะะพะฝัะธะณััะฐัะธั Git
config.git_disable_diff_highlight=ะัะบะปััะธัั ะฟะพะดัะฒะตัะบั ัะธะฝัะฐะบัะธัะฐ ะฟัะธ ััะฐะฒะฝะตะฝะธะธ
@@ -3342,7 +3497,7 @@ config.git_max_diff_lines=ะะฐะบั. ะบะพะปะธัะตััะฒะพ ัััะพะบ ะฒ ัะฐะนะป
config.git_max_diff_line_characters=ะะฐะบั. ะบะพะปะธัะตััะฒะพ ัะธะผะฒะพะปะพะฒ ะฒ ัััะพะบะต ะฟัะธ ััะฐะฒะฝะตะฝะธะธ
config.git_max_diff_files=ะะฐะบั. ะพัะพะฑัะฐะถะฐะตะผะพะต ะบะพะปะธัะตััะฒะพ ัะฐะนะปะพะฒ ะฟัะธ ััะฐะฒะฝะตะฝะธะธ
config.git_gc_args=ะัะณัะผะตะฝัั ัะฑะพััะธะบะฐ ะผััะพัะฐ
-config.git_migrate_timeout=ะะณัะฐะฝะธัะตะฝะธะต ะฒัะตะผะตะฝะธ ะผะธะณัะฐัะธะน
+config.git_migrate_timeout=ะะณัะฐะฝะธัะตะฝะธะต ะฒัะตะผะตะฝะธ ะฟะตัะตะฝะพัะพะฒ
config.git_mirror_timeout=ะะณัะฐะฝะธัะตะฝะธะต ะฒัะตะผะตะฝะธ ะฝะฐ ัะธะฝั
ัะพะฝะธะทะฐัะธั ะทะตัะบะฐะปะฐ
config.git_clone_timeout=ะะณัะฐะฝะธัะตะฝะธะต ะฒัะตะผะตะฝะธ ะพะฟะตัะฐัะธะน ะบะปะพะฝะธัะพะฒะฐะฝะธั
config.git_pull_timeout=ะะณัะฐะฝะธัะตะฝะธะต ะฒัะตะผะตะฝะธ ะฝะฐ ะฟะพะปััะตะฝะธะต ะธะทะผะตะฝะตะฝะธะน
@@ -3388,7 +3543,7 @@ monitor.queue.activeworkers=ะะบัะธะฒะฝัะต ะพะฑัะฐะฑะพััะธะบะธ
monitor.queue.maxnumberworkers=ะะฐะบั. ะบะพะปะธัะตััะฒะพ ะพะฑัะฐะฑะพััะธะบะพะฒ
monitor.queue.numberinqueue=ะะพะทะธัะธั ะฒ ะพัะตัะตะดะธ
monitor.queue.settings.title=ะะฐัััะพะนะบะธ ะฟัะปะฐ
-monitor.queue.settings.desc=ะัะปั ัะฒะตะปะธัะธะฒะฐัััั ะดะธะฝะฐะผะธัะตัะบะธ ะฒ ะพัะฒะตั ะฝะฐ ะฑะปะพะบะธัะพะฒะบั ะพัะตัะตะดะตะน ัะฒะพะธั
ะพะฑัะฐะฑะพััะธะบะพะฒ.
+monitor.queue.settings.desc=ะัะปั ะดะธะฝะฐะผะธัะตัะบะธ ัะฐัััั ะฒ ะทะฐะฒะธัะธะผะพััะธ ะพั ะฑะปะพะบะธัะพะฒะบะธ ะพัะตัะตะดะตะน ะธั
ัะฐะฑะพัะธั
.
monitor.queue.settings.maxnumberworkers=ะะฐะบั. ะบะพะปะธัะตััะฒะพ ะพะฑัะฐะฑะพััะธะบะพะฒ
monitor.queue.settings.maxnumberworkers.placeholder=ะ ะฝะฐััะพััะธะน ะผะพะผะตะฝั %[1]d
monitor.queue.settings.maxnumberworkers.error=ะะฐะบัะธะผะฐะปัะฝะพะต ะบะพะปะธัะตััะฒะพ ะพะฑัะฐะฑะพััะธะบะพะฒ ะดะพะปะถะฝะพ ะฑััั ัะธัะปะพะผ
@@ -3400,9 +3555,9 @@ monitor.queue.settings.remove_all_items_done=ะัะต ัะปะตะผะตะฝัั ะฒ ะพัะตั
notices.system_notice_list=ะกะธััะตะผะฝัะต ะพะฟะพะฒะตัะตะฝะธั
notices.view_detail_header=ะะพะดัะพะฑะฝะพััะธ ัะฒะตะดะพะผะปะตะฝะธั
notices.operations=ะะฟะตัะฐัะธะธ
-notices.select_all=ะัะฑัะฐัั ะฒัั
-notices.deselect_all=ะัะผะตะฝะธัั ะฒัะดะตะปะตะฝะธะต
-notices.inverse_selection=ะะฝะฒะตััะธั ะฒัะดะตะปะตะฝะธั
+notices.select_all=ะัะฑัะฐัั ะฒัะต
+notices.deselect_all=ะกะฝััั ะฒัะดะตะปะตะฝะธะต
+notices.inverse_selection=ะะฝะฒะตััะธัะพะฒะฐัั ะฒัะดะตะปะตะฝะฝัะต
notices.delete_selected=ะฃะดะฐะปะธัั ะฒัะฑัะฐะฝะฝัะต
notices.delete_all=ะฃะดะฐะปะธัั ะฒัะต ัะฒะตะดะพะผะปะตะฝะธั
notices.type=ะขะธะฟ
@@ -3412,32 +3567,47 @@ notices.desc=ะะฟะธัะฐะฝะธะต
notices.op=Oะฟ.
notices.delete_success=ะฃะฒะตะดะพะผะปะตะฝะธั ัะธััะตะผั ะฑัะปะธ ัะดะฐะปะตะฝั.
self_check.no_problem_found = ะะพะบะฐ ะฟัะพะฑะปะตะผ ะฝะต ะพะฑะฝะฐััะถะตะฝะพ.
-auths.tip.gitea = ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต OAuth2. ะะพัััะฟะฝะฐ ะธะฝััััะบัะธั: https://forgejo.org/docs/latest/user/oauth2-provider
+auths.tip.gitea = ะะฐัะตะณะธัััะธััะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต OAuth2. ะะพัััะฟะฝะฐ ะธะฝััััะบัะธั: %s
auths.tips.oauth2.general.tip = ะัะธ ัะตะณะธัััะฐัะธะธ ะฝะพะฒะพะณะพ ะฟัะธะปะพะถะตะฝะธั OAuth2 ัััะปะบะฐ ะพะฑัะฐัะฝะพะณะพ ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝะธั ะดะพะปะถะฝะฐ ะฑััั:
-self_check.database_fix_mysql = ะะพะปัะทะพะฒะฐัะตะปะธ MySQL ะธ MariaDB ะผะพะณัั ะธัะฟัะฐะฒะธัั ะฟัะพะฑะปะตะผั ั ัะพะฟะพััะฐะฒะปะตะฝะธะตะผ ะบะพะผะฐะฝะดะพะน "gitea doctor convert". ะขะฐะบะถะต ะผะพะถะฝะพ ะฒัััะฝัั ะฒะฟะธัะฐัั "ALTER ... COLLATE ..." ะฒ SQL.
+self_check.database_fix_mysql = ะะพะปัะทะพะฒะฐัะตะปะธ MySQL ะธ MariaDB ะผะพะณัั ะธัะฟัะฐะฒะธัั ะฟัะพะฑะปะตะผั ั ัะพะฟะพััะฐะฒะปะตะฝะธะตะผ ะบะพะผะฐะฝะดะพะน "forgejo doctor convert". ะขะฐะบะถะต ะผะพะถะฝะพ ะฒัััะฝัั ะฒะฟะธัะฐัั "ALTER ... COLLATE ..." ะฒ SQL.
dashboard.cleanup_actions = ะัะธััะธัั ัััะฐัะตะฒัะธะต ะถััะฝะฐะปั ะธ ะฐััะตัะฐะบัั ะะตะนััะฒะธะน
-dashboard.sync_repo_branches = ะกะธะฝั
ัะพะฝะธะทะธัะพะฒะฐัั ะฒะตัะบะธ ะธะท Git ะฒ ะฑะฐะทั ะดะฐะฝะฝัั
+dashboard.sync_repo_branches = ะกะธะฝั
ัะพะฝะธะทะธัะพะฒะฐัั ะฒะตัะฒะธ ะธะท Git ะฒ ะฑะฐะทั ะดะฐะฝะฝัั
assets = ะะพะดะพะฒัะต ะพะฑัะตะบัั
dashboard.sync_tag.started = ะะฐัะฐัะฐ ัะธะฝั
ัะพะฝะธะทะฐัะธั ัะตะณะพะฒ
settings = ะะดะผะธะฝ. ะฝะฐัััะพะนะบะธ
self_check.database_collation_case_insensitive = ะะ ะธัะฟะพะปัะทัะตั ะฝะตััะฒััะฒะธัะตะปัะฝะพะต ัะพะฟะพััะฐะฒะปะตะฝะธะต %s. ะฅะพัั Forgejo ะธ ะฑัะดะตั ัะฐะฑะพัะฐัั, ะผะพะณัั ะฒะพะทะฝะธะบะฐัั ัะปััะฐะธ ั ะฝะตะพะถะธะดะฐะฝะฝัะผ ะฟะพะฒะตะดะตะฝะธะตะผ.
self_check.database_inconsistent_collation_columns = ะะ ะธัะฟะพะปัะทัะตั ัะพะฟะพััะฐะฒะปะตะฝะธะต %s, ะฝะพ ััะธ ััะพะปะฑัั ะธัะฟะพะปัะทััั ะฟะตัะตะผะตัะฐะฝะฝัะต ัะพะฟะพััะฐะฒะปะตะฝะธั. ะญัะพ ะผะพะถะตั ะฒัะทัะฒะฐัั ะฝะตะพะถะธะดะฐะฝะฝัะต ะฟัะพะฑะปะตะผั.
-dashboard.sync_branch.started = ะะฐัะฐัะฐ ัะธะฝั
ัะพะฝะธะทะฐัะธั ะฒะตัะพะบ
-dashboard.sync_repo_tags = ะกะธะฝั
ัะพะฝะธะทะธัะพะฒะฐัั ัะตะณะธ ะธะท Git ะฒ ะฑะฐะทั ะดะฐะฝะฝัั
+dashboard.sync_branch.started = ะะฐัะฐัะฐ ัะธะฝั
ัะพะฝะธะทะฐัะธั ะฒะตัะฒะตะน
+dashboard.sync_repo_tags = ะกะธะฝั
ัะพะฝะธะทะธัะพะฒะฐัั ัะตะณะธ Git-ัะตะฟะพะทะธัะพัะธะตะฒ ะฒ ะฑะฐะทั ะดะฐะฝะฝัั
self_check.database_collation_mismatch = ะะถะธะดะฐะตััั, ััะพ ะะ ะธัะฟะพะปัะทัะตั ัะพะฟะพััะฐะฒะปะตะฝะธะต: %s
self_check = ะกะฐะผะพะฟัะพะฒะตัะบะฐ
dashboard.rebuild_issue_indexer = ะะตัะตัะพะฑัะฐัั ะธะฝะดะตะบัะฐัะพั ะทะฐะดะฐั
-systemhooks.desc = ะะตะฑ-ั
ัะบะธ ะฐะฒัะพะผะฐัะธัะตัะบะธ ัะพะฒะตััะฐัั POST ะทะฐะฟัะพัั ะดะพ ัะบะฐะทะฐะฝะฝะพะณะพ HTTP ัะตัะฒะตัะฐ, ะบะพะณะดะฐ ะฒ Forgejo ะฟัะพะธัั
ะพะดัั ะพะฟัะตะดะตะปัะฝะฝัะต ัะพะฑััะธั. ะะฐะดะฐะฝะฝัะต ะทะดะตัั ะฒะตะฑ-ั
ัะบะธ ะฑัะดัั ััะฐะฑะฐััะฒะฐัั ะฒะพ ะฒัะตั
ัะตะฟะพะทะธัะพัะธัั
ะฝะฐ ััะพะผ ัะตัะฒะตัะต ะธ ะผะพะณัั ะฟัะธะฒะตััะธ ะบ ะฟัะพะฑะปะตะผะฐะผ ั ะฟัะพะธะทะฒะพะดะธัะตะปัะฝะพัััั. ะะพะดัะพะฑะฝะตะต ะพ ะฒะตะฑ-ั
ัะบะฐั
.
-defaulthooks.desc = ะะตะฑ-ั
ัะบะธ ะฐะฒัะพะผะฐัะธัะตัะบะธ ัะพะฒะตััะฐัั POST ะทะฐะฟัะพัั ะดะพ ัะบะฐะทะฐะฝะฝะพะณะพ HTTP ัะตัะฒะตัะฐ, ะบะพะณะดะฐ ะฒ Forgejo ะฟัะพะธัั
ะพะดัั ะพะฟัะตะดะตะปัะฝะฝัะต ัะพะฑััะธั. ะะฐะดะฐะฝะฝัะต ะทะดะตัั ะฒะตะฑ-ั
ัะบะธ ะธัะฟะพะปัะทััััั ะฟะพ ัะผะพะปัะฐะฝะธั ะธ ะฑัะดัั ะดะพะฑะฐะฒะปะตะฝั ะฒะพ ะฒัะต ะฝะพะฒัะต ัะตะฟะพะทะธัะพัะธะธ. ะะพะดัะพะฑะฝะตะต ะพ ะฒะตะฑ-ั
ัะบะฐั
.
+systemhooks.desc = ะะตะฑ-ั
ัะบะธ ะฐะฒัะพะผะฐัะธัะตัะบะธ ัะพะฒะตััะฐัั POST ะทะฐะฟัะพัั ะดะพ ัะบะฐะทะฐะฝะฝะพะณะพ HTTP ัะตัะฒะตัะฐ, ะบะพะณะดะฐ ะฒ Forgejo ะฟัะพะธัั
ะพะดัั ะพะฟัะตะดะตะปัะฝะฝัะต ัะพะฑััะธั. ะะฐะดะฐะฝะฝัะต ะทะดะตัั ะฒะตะฑ-ั
ัะบะธ ะฑัะดัั ััะฐะฑะฐััะฒะฐัั ะฒะพ ะฒัะตั
ัะตะฟะพะทะธัะพัะธัั
ะฝะฐ ััะพะผ ัะตัะฒะตัะต ะธ ะผะพะณัั ะฟัะธะฒะตััะธ ะบ ะฟัะพะฑะปะตะผะฐะผ ั ะฟัะพะธะทะฒะพะดะธัะตะปัะฝะพัััั. ะะพะดัะพะฑะฝะตะต ะพ ะฒะตะฑ-ั
ัะบะฐั
.
+defaulthooks.desc = ะะตะฑ-ั
ัะบะธ ะฐะฒัะพะผะฐัะธัะตัะบะธ ัะพะฒะตััะฐัั POST ะทะฐะฟัะพัั ะดะพ ัะบะฐะทะฐะฝะฝะพะณะพ HTTP ัะตัะฒะตัะฐ, ะบะพะณะดะฐ ะฒ Forgejo ะฟัะพะธัั
ะพะดัั ะพะฟัะตะดะตะปัะฝะฝัะต ัะพะฑััะธั. ะะฐะดะฐะฝะฝัะต ะทะดะตัั ะฒะตะฑ-ั
ัะบะธ ะธัะฟะพะปัะทััััั ะฟะพ ัะผะพะปัะฐะฝะธั ะธ ะฑัะดัั ะดะพะฑะฐะฒะปะตะฝั ะฒะพ ะฒัะต ะฝะพะฒัะต ัะตะฟะพะทะธัะพัะธะธ. ะะพะดัะพะฑะฝะตะต ะพ ะฒะตะฑ-ั
ัะบะฐั
.
users.remote = ะะธััะฐะฝั
config_summary = ะกะฒะพะดะบะฐ
config.open_with_editor_app_help = ะัะธะปะพะถะตะฝะธั ะดะปั "ะัะบัััั ะฒ" ะฒ ะผะตะฝั. ะััะฐะฒััะต ะฟััััะผ ะดะปั ะฟัะธะปะพะถะตะฝะธะน ะฟะพ ัะผะพะปัะฐะฝะธั. ะ ะฐะทะฒะตัะฝะธัะต ะดะปั ะฟัะพัะผะพััะฐ.
config_settings = ะะฐัััะพะนะบะธ
auths.tips.gmail_settings = ะะฐัััะพะนะบะธ Gmail:
-auths.tip.gitlab_new = ะกะพะทะดะฐะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฒ https://gitlab.com/-/profile/applications
+auths.tip.gitlab_new = ะกะพะทะดะฐะนัะต ะฝะพะฒะพะต ะฟัะธะปะพะถะตะฝะธะต ะฒ %s
monitor.queue.review_add = ะะพะดัะพะฑะฝะพััะธ / ะดะพะฑะฐะฒะธัั ะพะฑัะฐะฑะพััะธะบะธ
auths.default_domain_name = ะะพะผะตะฝ ะฟะพ ัะผะพะปัะฐะฝะธั ะดะปั ะฐะดัะตัะพะฒ ัะป. ะฟะพััั
config.app_slogan = ะะพะทัะฝะณ ัะตัะฒะตัะฐ
+config.cache_test = ะัะพะฒะตัะธัั ะบัั
+config.cache_test_slow = ะัั ะฟัะพะฒะตัะตะฝ ััะฟะตัะฝะพ, ะฝะพ ะพัะฒะตั ะฑัะป ะผะตะดะปะตะฝะฝัะผ: %s.
+config.cache_test_failed = ะะต ัะดะฐะปะพัั ะฟัะพะฒะตัะธัั ะบัั: %v.
+config.cache_test_succeeded = ะัั ะฑัะป ะฟัะพะฒะตัะตะฝ ััะฟะตัะฝะพ, ะพัะฒะตั ะฟะพะปััะตะฝ ะทะฐ %v.
+users.activated.description = ะะพะดัะฒะตัะถะดะตะฝะธะต ััััะฝะพะน ะทะฐะฟะธัะธ ะฟะพ ัะป. ะฟะพััะต. ะะพะปัะทะพะฒะฐัะตะปั ะฝะตะฟะพะดัะฒะตัะถะดัะฝะฝะพะน ัั. ะทะฐะฟะธัะธ ะฝะต ัะผะพะถะตั ะฒะพะนัะธ, ะฝะต ะฒัะฟะพะปะฝะธะฒ ะฟะพะดัะฒะตัะถะดะตะฝะธะต.
+users.block.description = ะะฐะฑะปะพะบะธัะพะฒะฐัั ััััะฝัั ะทะฐะฟะธัั, ััะพะฑั ะฟัะตะฟััััะฒะพะฒะฐัั ะตั ะธัะฟะพะปัะทะพะฒะฐะฝะธั ะธ ะทะฐะฟัะตัะธัั ะฒั
ะพะด.
+users.organization_creation.description = ะ ะฐะทัะตัะธัั ัะพะทะดะฐะฝะธะต ะฝะพะฒัั
ะพัะณะฐะฝะธะทะฐัะธะน ะฝะฐ ัะตัะฒะตัะต.
+users.local_import.description = ะ ะฐะทัะตัะธัั ะธะผะฟะพััะธัะพะฒะฐัั ัะตะฟะพะทะธัะพัะธะธ ะธะท ะปะพะบะฐะปัะฝะพะน ะคะก ัะตัะฒะตัะฐ. ะญัะพ ะผะพะถะตั ะฝะตััะธ ัะณัะพะทั ะฑะตะทะพะฟะฐัะฝะพััะธ.
+users.admin.description = ะัะตะดะพััะฐะฒะธัั ะฟะพะปะฝัะน ะดะพัััะฟ ะบ ะฐะดะผะธะฝะธัััะฐัะธะฒะฝะพะผั ััะฝะบัะธะพะฝะฐะปั ะฒะตะฑ-ะธะฝัะตััะตะนัะฐ ะธ API.
+users.restricted.description = ะ ะฐะทัะตัะธัั ะฒะทะฐะธะผะพะดะตะนััะฒะธะต ั ะปะธัั ัะตะฟะพะทะธัะพัะธัะผะธ ะธ ะพัะณะฐะฝะธะทะฐัะธัะผะธ, ะฒ ะบะพัะพััั
ััะพั ะฟะพะปัะทะพะฒะฐัะตะปั ัะพััะพะธั ะฒ ะบะฐัะตััะฒะต ัะพััะฐััะฝะธะบะฐ. ะัะตะดะพัะฒัะฐัะฐะตั ะดะพัััะฟ ะบ ะฟัะฑะปะธัะฝัะผ ัะตะฟะพะทะธัะพัะธัะผ ะฝะฐ ััะพะผ ัะตัะฒะตัะต.
+emails.delete = ะฃะดะฐะปะธัั ะฐะดัะตั
+emails.deletion_success = ะะดัะตั ัะป. ะฟะพััั ัะดะฐะปัะฝ ะธะท ััััะฝะพะน ะทะฐะฟะธัะธ.
+emails.delete_primary_email_error = ะะตะฒะพะทะผะพะถะฝะพ ัะดะฐะปะธัั ะพัะฝะพะฒะฝะพะน ะฐะดัะตั.
+emails.delete_desc = ะั ัะพัะฝะพ ั
ะพัะธัะต ัะดะฐะปะธัั ััะพั ะฐะดัะตั ัะป. ะฟะพััั?
+monitor.duration = ะะปะธัะตะปัะฝะพััั (ั)
[action]
@@ -3454,22 +3624,22 @@ comment_issue=`ะพััะฐะฒะปะตะฝ ะบะพะผะผะตะฝัะฐัะธะน ะฟะพะด ะทะฐะดะฐัะตะน %[3]s#%[2]s `
merge_pull_request=`ะฟัะธะฝัั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต %[3]s#%[2]s `
auto_merge_pull_request=`ะฐะฒัะพะผะฐัะธัะตัะบะธ ะฟัะธะฝัั ะทะฐะฟัะพั ะฝะฐ ัะปะธัะฝะธะต %[3]s#%[2]s `
-transfer_repo=ะฟะตัะตะดะฐะฝ ัะตะฟะพะทะธัะพัะธะน %s
%s
-push_tag=ัะพะทะดะฐะฝ ัะตะณ %[3]s ะฒ %[4]s
-delete_tag=ัะดะฐะปัะฝ ััะณ %[2]s ะธะท %[3]s
-delete_branch=ัะดะฐะปะตะฝะฐ ะฒะตัะบะฐ %[2]s ะธะท %[3]s
+transfer_repo=ัะตะฟะพะทะธัะพัะธะน %s
ะฑัะป ะฟะตัะตะดะฐะฝ: %s
+push_tag=ะพัะฟัะฐะฒะปะตะฝ ัะตะณ %[3]s ะฒ %[4]s
+delete_tag=ัะดะฐะปัะฝ ัะตะณ %[2]s ะฒ %[3]s
+delete_branch=ัะดะฐะปะตะฝะฐ ะฒะตัะฒั %[2]s ะฒ %[3]s
compare_branch=ะกัะฐะฒะฝะธัั
compare_commits=ะกัะฐะฒะฝะธัั %d ะบะพะผะผะธัะพะฒ
compare_commits_general=ะกัะฐะฒะฝะธัั ะบะพะผะผะธัั
mirror_sync_push=ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐะป(ะฐ) ะบะพะผะผะธัั %[3]s ะฒ %[4]s ะธะท ะทะตัะบะฐะปะฐ
mirror_sync_create=ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐะป(ะฐ) ะฝะพะฒัั ัััะปะบั %[3]s ะฒ %[4]s ะธะท ะทะตัะบะฐะปะฐ
mirror_sync_delete=ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐะฝะฝัะต ะธ ัะดะฐะปัะฝะฝัะต ัััะปะบะธ %[2]s
ะฝะฐ %[3]s ะธะท ะทะตัะบะฐะปะฐ
-approve_pull_request=`ะพะดะพะฑัะตะฝ %[3]s#%[2]s `
+approve_pull_request=`ะพะดะพะฑัะตะฝ ะทะฐะฟัะพั ัะปะธัะฝะธั %[3]s#%[2]s `
reject_pull_request=`ะฟัะตะดะปะพะถะธะป(ะฐ) ะธะทะผะตะฝะตะฝะธั ะดะปั %[3]s#%[2]s `
publish_release=`ะฒัะฟััะบ %[4]s ะพะฟัะฑะปะธะบะพะฒะฐะฝ ะฒ %[3]s `
review_dismissed=`ะพัะบะปะพะฝัะฝ ะพัะทัะฒ ะพั %[4]s ะดะปั %[3]s#%[2]s `
review_dismissed_reason=ะัะธัะธะฝะฐ:
-create_branch=ัะพะทะดะฐะฝะฐ ะฒะตัะบะฐ %[3]s ะฒ %[4]s
+create_branch=ัะพะทะดะฐะฝะฐ ะฒะตัะฒั %[3]s ะฒ %[4]s
starred_repo=ะดะพะฑะฐะฒะปะตะฝะพ %[2]s ะฒ ะธะทะฑัะฐะฝะฝะพะต
watched_repo=ัะตะฟะตัั ะพััะปะตะถะธะฒะฐะตั %[2]s
@@ -3503,7 +3673,7 @@ pib = ะะธะ
eib = ะญะธะ
[dropzone]
-default_message=ะะตัะตัะฐัะธัะต ัะฐะนะป ะธะปะธ ะบะปะธะบะฝะธัะต ััะดะฐ ะดะปั ะทะฐะณััะทะบะธ.
+default_message=ะะตัะตัะฐัะธัะต ััะดะฐ ัะฐะนะปั ะธะปะธ ะฝะฐะถะผะธัะต ะดะปั ะทะฐะณััะทะบะธ.
invalid_input_type=ะั ะฝะต ะผะพะถะตัะต ะทะฐะณััะถะฐัั ัะฐะนะปั ััะพะณะพ ัะธะฟะฐ.
file_too_big=ะ ะฐะทะผะตั ัะฐะนะปะฐ ({{filesize}} ะะ) ะฑะพะปััะต ัะตะผ ะผะฐะบัะธะผะฐะปัะฝัะน ัะฐะทะผะตั ({{maxFilesize}} ะะ).
remove_file=ะฃะดะฐะปะธัั ัะฐะนะป
@@ -3525,8 +3695,8 @@ no_subscriptions=ะะตั ะฟะพะดะฟะธัะพะบ
[gpg]
default_key=ะะพะดะฟะธัะฐะฝะพ ะบะปััะพะผ ะฟะพ ัะผะพะปัะฐะฝะธั
error.extract_sign=ะะต ัะดะฐะปะพัั ะธะทะฒะปะตัั ะฟะพะดะฟะธัั
-error.generate_hash=ะะต ัะดะฐะปะพัั ัะพะทะดะฐัั ั
ัั ะบะพะผะผะธัะฐ
-error.no_committer_account=ะฃัััะฝะฐั ะทะฐะฟะธัั ั ัะป. ะฟะพััะพะน ััะพะณะพ ะบะพะผะผะธัะตัะฐ ะฝะต ะฝะฐะนะดะตะฝะฐ
+error.generate_hash=ะะต ัะดะฐะปะพัั ัะพะทะดะฐัั ั
ะตั ะบะพะผะผะธัะฐ
+error.no_committer_account=ะฃัััะฝะฐั ะทะฐะฟะธัั ั ัะป. ะฟะพััะพะน ะฐะฒัะพัะฐ ััะพะณะพ ะบะพะผะผะธัะฐ ะฝะต ะฝะฐะนะดะตะฝะฐ
error.no_gpg_keys_found=ะะต ะฝะฐะนะดะตะฝ ะบะปัั, ัะพะพัะฒะตัััะฒัััะธะน ะดะฐะฝะฝะพะน ะฟะพะดะฟะธัะธ
error.not_signed_commit=ะะตะฟะพะดะฟะธัะฐะฝะฝัะน ะบะพะผะผะธั
error.failed_retrieval_gpg_keys=ะะต ัะดะฐะปะพัั ะฟะพะปััะธัั ะฝะธ ะพะดะฝะพะณะพ ะบะปััะฐ GPG ะฐะฒัะพัะฐ ะบะพะผะผะธัะฐ
@@ -3559,11 +3729,11 @@ dependencies=ะะฐะฒะธัะธะผะพััะธ
keywords=ะะปััะตะฒัะต ัะปะพะฒะฐ
details=ะกะฒะตะดะตะฝะธั
details.author=ะะฒัะพั
-details.project_site=ะกะฐะนั ะฟัะพะตะบัะฐ
-details.repository_site=ะกะฐะนั ัะตะฟะพะทะธัะพัะธั
-details.documentation_site=ะกะฐะนั ะดะพะบัะผะตะฝัะฐัะธะธ
+details.project_site=ะะตะฑ-ัะฐะนั ะฟัะพะตะบัะฐ
+details.repository_site=ะะตะฑ-ัะฐะนั ัะตะฟะพะทะธัะพัะธั
+details.documentation_site=ะะตะฑ-ัะฐะนั ะดะพะบัะผะตะฝัะฐัะธะธ
details.license=ะะธัะตะฝะทะธั
-assets=ะ ะตััััั
+assets=ะะฑัะตะบัั
versions=ะะตััะธะธ
versions.view_all=ะะพะบะฐะทะฐัั ะฒัั
dependency.id=ID
@@ -3571,51 +3741,51 @@ dependency.version=ะะตััะธั
alpine.registry=ะะฐัััะพะนัะต ััะพั ัะตะตััั, ะดะพะฑะฐะฒะธะฒ URL ะฒ ัะฐะนะป /etc/apk/repositories
:
alpine.registry.key=ะะฐะณััะทะธัะต ะฟัะฑะปะธัะฝัะน ะบะปัั RSA ัะตะตัััะฐ ะฒ ะบะฐัะฐะปะพะณ /etc/apk/keys/
ะดะปั ะฟัะพะฒะตัะบะธ ะฟะพะดะฟะธัะธ ะธะฝะดะตะบัะฐ:
alpine.registry.info=ะัะฑะตัะธัะต $branch ะธ $repository ะธะท ัะฟะธัะบะฐ ะฝะธะถะต.
-alpine.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
+alpine.install=ะะปั ัััะฐะฝะพะฒะบะธ ะฟะฐะบะตัะฐ ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
alpine.repository=ะ ัะตะฟะพะทะธัะพัะธะธ
-alpine.repository.branches=ะะตัะบะธ
+alpine.repository.branches=ะะตัะฒะธ
alpine.repository.repositories=ะ ะตะฟะพะทะธัะพัะธะธ
alpine.repository.architectures=ะัั
ะธัะตะบัััั
cargo.registry=ะะฐัััะพะนัะต ััะพั ัะตะตััั ะฒ ัะฐะนะปะต ะบะพะฝัะธะณััะฐัะธะธ Cargo (ะฝะฐะฟัะธะผะตั, ~/.cargo/config.toml
):
cargo.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั ั ะฟะพะผะพััั Cargo, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
chef.registry=ะะฐัััะพะนัะต ััะพั ัะตะตััั ะฒ ัะฒะพัะผ ัะฐะนะปะต ~/.chef/config.rb
:
-chef.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
+chef.install=ะะปั ัััะฐะฝะพะฒะบะธ ะฟะฐะบะตัะฐ ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
composer.registry=ะะฐัััะพะนัะต ััะพั ัะตะตััั ะฒ ัะฐะนะปะต ~/.composer/config.json
:
composer.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั ั ะฟะพะผะพััั Composer, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
composer.dependencies=ะะฐะฒะธัะธะผะพััะธ
composer.dependencies.development=ะะฐะฒะธัะธะผะพััะธ ะดะปั ัะฐะทัะฐะฑะพัะบะธ
conan.details.repository=ะ ะตะฟะพะทะธัะพัะธะน
-conan.registry=ะะฐัััะพะธัั ัะตะตััั ะธะท ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ:
+conan.registry=ะะพะฑะฐะฒััะต ัะตะตััั ะบะพะผะฐะฝะดะพะน:
conan.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั ั ะฟะพะผะพััั Conan, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
conda.registry=ะัะพะฟะธัะธัะต ััะพั ัะตะตััั ะฒ ะบะฐัะตััะฒะต ัะตะฟะพะทะธัะพัะธั Conda ะฒ ัะฒะพัะผ ัะฐะนะปะต .condarc
:
conda.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั ั ะฟะพะผะพััั Conda, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
container.details.type=ะขะธะฟ ะพะฑัะฐะทะฐ
container.details.platform=ะะปะฐััะพัะผะฐ
container.pull=ะะฐะณััะทะธัะต ะพะฑัะฐะท ะธะท ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ:
-container.digest=ะัะฟะตัะฐัะพะบ:
+container.digest=ะัะฟะตัะฐัะพะบ
container.multi_arch=ะะก / ะฐัั
ะธัะตะบัััะฐ
container.layers=ะกะปะพะธ ะพะฑัะฐะทะฐ
container.labels=ะะตัะบะธ
container.labels.key=ะะปัั
container.labels.value=ะะฝะฐัะตะฝะธะต
cran.registry=ะะฐัััะพะนัะต ััะพั ัะตะตััั ะฒ ัะฐะนะปะต Rprofile.site
:
-cran.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
-debian.registry=ะะฐัััะพะธัั ัะตะตััั ะธะท ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ:
+cran.install=ะะปั ัััะฐะฝะพะฒะบะธ ะฟะฐะบะตัะฐ ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
+debian.registry=ะะพะฑะฐะฒััะต ัะตะตััั ะบะพะผะฐะฝะดะพะน:
debian.registry.info=ะัะฑะตัะธัะต $distribution ะธ $component ะธะท ัะฟะธัะบะฐ ะฝะธะถะต.
-debian.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
+debian.install=ะะปั ัััะฐะฝะพะฒะบะธ ะฟะฐะบะตัะฐ ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
debian.repository=ะ ัะตะฟะพะทะธัะพัะธะธ
debian.repository.distributions=ะะธัััะธะฑััะธะฒั
debian.repository.components=ะะพะผะฟะพะฝะตะฝัั
debian.repository.architectures=ะัั
ะธัะตะบัััั
generic.download=ะกะบะฐัะฐัั ะฟะฐะบะตั ะธะท ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ:
go.install=ะฃััะฐะฝะพะฒะธัะต ะฟะฐะบะตั ะธะท ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ:
-helm.registry=ะะฐัััะพะธัั ัะตะตััั ะธะท ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ:
-helm.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
+helm.registry=ะะพะฑะฐะฒััะต ัะตะตััั ะบะพะผะฐะฝะดะพะน:
+helm.install=ะะปั ัััะฐะฝะพะฒะบะธ ะฟะฐะบะตัะฐ ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
maven.registry=ะะฐัััะพะนัะต ัะตะตััั ะฒ ัะฐะนะปะต pom.xml
ะฒะฐัะตะณะพ ะฟัะพะตะบัะฐ:
maven.install=ะงัะพะฑั ะธัะฟะพะปัะทะพะฒะฐัั ะฟะฐะบะตั, ะฒะบะปััะธัะต ะฒ ะฑะปะพะบ dependencies
ะฒ ัะฐะนะปะต pom.xml
ัะปะตะดัััะตะต:
maven.install2=ะัะฟะพะปะฝะธัั ัะตัะตะท ะบะพะผะฐะฝะดะฝัั ัััะพะบั:
maven.download=ะงัะพะฑั ัะบะฐัะฐัั ะทะฐะฒะธัะธะผะพััั, ะทะฐะฟัััะธัะต ะฒ ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะต:
-nuget.registry=ะะฐัััะพะธัั ัะตะตััั ะธะท ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ:
+nuget.registry=ะะพะฑะฐะฒััะต ัะตะตััั ะบะพะผะฐะฝะดะพะน:
nuget.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั ั ะฟะพะผะพััั NuGet, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
nuget.dependency.framework=ะฆะตะปะตะฒะพะน ััะตะนะผะฒะพัะบ
npm.registry=ะะฐัััะพะนัะต ัะตะตััั ะฒ ัะฐะนะปะต .npmrc
ะฒะฐัะตะณะพ ะฟัะพะตะบัะฐ:
@@ -3629,19 +3799,19 @@ npm.details.tag=ะขะตะณ
pub.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั ั ะฟะพะผะพััั Dart, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
pypi.requires=ะขัะตะฑัะตััั Python
pypi.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั ั ะฟะพะผะพััั pip, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
-rpm.registry=ะะฐัััะพะธัั ัะตะตััั ะธะท ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ:
+rpm.registry=ะะพะฑะฐะฒััะต ัะตะตััั ะบะพะผะฐะฝะดะพะน:
rpm.distros.redhat=ะฝะฐ ะดะธัััะธะฑััะธะฒะฐั
ัะตะผะตะนััะฒะฐ RedHat
rpm.distros.suse=ะฝะฐ ะดะธัััะธะฑััะธะฒะฐั
ัะตะผะตะนััะฒะฐ SUSE
-rpm.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
-rpm.repository=ะ ัะตะฟะพะทะธัะพัะธะธ
-rpm.repository.architectures=ะัั
ะธัะตะบัััั
+rpm.install=ะะปั ัััะฐะฝะพะฒะบะธ ะฟะฐะบะตัะฐ ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
+rpm.repository = ะ ัะตะฟะพะทะธัะพัะธะธ
+rpm.repository.architectures = ะัั
ะธัะตะบัััั
rubygems.install=ะงัะพะฑั ัััะฐะฝะพะฒะธัั ะฟะฐะบะตั ั ะฟะพะผะพััั gem, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
rubygems.install2=ะธะปะธ ะดะพะฑะฐะฒััะต ะตะณะพ ะฒ Gemfile:
rubygems.dependencies.runtime=ะะฐะฒะธัะธะผะพััะธ ะฒัะตะผะตะฝะธ ะฒัะฟะพะปะฝะตะฝะธั
rubygems.dependencies.development=ะะฐะฒะธัะธะผะพััะธ ะดะปั ัะฐะทัะฐะฑะพัะบะธ
rubygems.required.ruby=ะขัะตะฑัะตััั ะฒะตััะธั Ruby
rubygems.required.rubygems=ะขัะตะฑัะตััั ะฒะตััะธั RubyGem
-swift.registry=ะะฐัััะพะธัั ัะตะตััั ะธะท ะบะพะผะฐะฝะดะฝะพะน ัััะพะบะธ:
+swift.registry=ะะพะฑะฐะฒััะต ัะตะตััั ะบะพะผะฐะฝะดะพะน:
swift.install=ะะพะฑะฐะฒััะต ะฟะฐะบะตั ะฒ ัะฒะพะน ัะฐะนะป Package.swift
:
swift.install2=ะธ ะทะฐะฟัััะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
vagrant.install=ะงัะพะฑั ะดะพะฑะฐะฒะธัั ะฑะพะบั Vagrant, ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
@@ -3664,10 +3834,10 @@ owner.settings.cargo.initialize.success=ะะฝะดะตะบั Cargo ััะฟะตัะฝะพ ัะพะท
owner.settings.cargo.rebuild=ะะตัะตัััะพะธัั ะธะฝะดะตะบั
owner.settings.cargo.rebuild.error=ะะต ัะดะฐะปะพัั ะฟะตัะตัััะพะธัั ะธะฝะดะตะบั Cargo: %v
owner.settings.cargo.rebuild.success=ะะฝะดะตะบั Cargo ััะฟะตัะฝะพ ะฟะตัะตัััะพะตะฝ.
-owner.settings.cleanuprules.title=ะฃะฟัะฐะฒะปะตะฝะธะต ะฟัะฐะฒะธะปะฐะผะธ ะพัะธััะบะธ
+owner.settings.cleanuprules.title=ะัะฐะฒะธะปะฐ ะพัะธััะบะธ
owner.settings.cleanuprules.add=ะะพะฑะฐะฒะธัั ะฟัะฐะฒะธะปะพ ะพัะธััะบะธ
owner.settings.cleanuprules.edit=ะะทะผะตะฝะธัั ะฟัะฐะฒะธะปะพ ะพัะธััะบะธ
-owner.settings.cleanuprules.preview=ะัะตะดะฒะฐัะธัะตะปัะฝัะน ะฟัะพัะผะพัั ะฟัะฐะฒะธะปะฐ ะพัะธััะบะธ
+owner.settings.cleanuprules.preview=ะัะตะดะฟัะพัะผะพัั ะฟัะฐะฒะธะปะฐ ะพัะธััะบะธ
owner.settings.cleanuprules.preview.overview=ะะปะฐะฝะธััะตััั ัะดะฐะปะธัั %d ะฟะฐะบะตัะพะฒ.
owner.settings.cleanuprules.preview.none=ะัะฐะฒะธะปะพ ะพัะธััะบะธ ะฝะต ัะพะพัะฒะตัััะฒัะตั ะฝะธ ะพะดะฝะพะผั ะฟะฐะบะตัั.
owner.settings.cleanuprules.enabled=ะะบะปััะตะฝะพ
@@ -3686,13 +3856,36 @@ owner.settings.cleanuprules.success.delete=ะัะฐะฒะธะปะพ ะพัะธััะบะธ ัะดะฐ
owner.settings.chef.title=ะ ะตะตััั Chef
owner.settings.chef.keypair=ะกะพะทะดะฐัั ะฟะฐัั ะบะปััะตะน
owner.settings.cleanuprules.none = ะัะฐะฒะธะป ะพัะธััะบะธ ะฟะพะบะฐ ะฝะตั.
-owner.settings.cargo.rebuild.description = ะะตัะตัะฑะพัะบะฐ ะผะพะถะตั ะฑััั ะฟะพะปะตะทะฝะพะน ะฒ ัะปััะฐะต, ะตัะปะธ ะธะฝะดะตะบั ะฝะต ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐะฝ ั ัะพั
ัะฐะฝัะฝะฝัะผะธ ะฟะฐะบะตัะฐะผะธ Cargo.
-rpm.repository = ะ ัะตะฟะพะทะธัะพัะธะธ
-rpm.repository.architectures = ะัั
ะธัะตะบัััั
+owner.settings.cargo.rebuild.description = ะะตัะตัะฑะพัะบะฐ ะผะพะถะตั ะฑััั ะฟะพะปะตะทะฝะฐ ะฒ ัะปััะฐะต, ะตัะปะธ ะธะฝะดะตะบั ะฝะต ัะธะฝั
ัะพะฝะธะทะธัะพะฒะฐะฝ ั ั
ัะฐะฝััะธะผะธัั ะฟะฐะบะตัะฐะผะธ Cargo.
rpm.repository.multiple_groups = ะญัะพั ะฟะฐะบะตั ะดะพัััะฟะตะฝ ะฒ ะฝะตัะบะพะปัะบะธั
ะณััะฟะฟะฐั
.
owner.settings.chef.keypair.description = ะะปั ะฐััะตะฝัะธัะธะบะฐัะธะธ ัะตะตัััะฐ Chef ะฝะตะพะฑั
ะพะดะธะผะฐ ะฟะฐัะฐ ะบะปััะตะน. ะัะปะธ ะดะพ ััะพะณะพ ะฒั ัะถะต ัะณะตะฝะตัะธัะพะฒะฐะปะธ ะฟะฐัั ะบะปััะตะน, ะณะตะฝะตัะฐัะธั ะฝะพะฒะพะน ะฟัะธะฒะตะดัั ะบ ะฟัะตะบัะฐัะตะฝะธั ะดะตะนััะฒะธั ะฟัะตะดัะดััะตะน.
owner.settings.cargo.rebuild.no_index = ะะตะฒะพะทะผะพะถะฝะพ ะฒัะฟะพะปะฝะธัั ะฟะตัะตัะฑะพัะบั. ะะตั ะธะฝะธัะธะฐะปะธะทะธัะพะฒะฐะฝะฝะพะณะพ ะธะฝะดะตะบัะฐ.
npm.dependencies.bundle = ะะพะผะฟะปะตะบัะฝัะต ะทะฐะฒะธัะธะผะพััะธ
+arch.pacman.conf = ะะพะฑะฐะฒััะต ะฐะดัะตั ั ะฝะตะพะฑั
ะพะดะธะผัะผ ะดะธัััะธะฑััะธะฒะพะผ ะธ ะฐัั
ะธัะตะบัััะพะน ะฒ /etc/pacman.conf
:
+arch.pacman.helper.gpg = ะะพะฑะฐะฒััะต ัะตััะธัะธะบะฐั ะดะพะฒะตัะธั ะฒ pacman:
+arch.pacman.repo.multi.item = ะะพะฝัะธะณััะฐัะธั %s
+arch.pacman.sync = ะกะธะฝั
ัะพะฝะธะทะธััะนัะต ะฟะฐะบะตั ะฒ pacman:
+arch.version.properties = ะกะฒะพะนััะฒะฐ ะฒะตััะธะธ
+arch.version.description = ะะฟะธัะฐะฝะธะต
+arch.version.provides = ะัะตะดะพััะฐะฒะปัะตั
+arch.version.groups = ะััะฟะฟะฐ
+arch.version.depends = ะะฐะฒะธัะธั ะพั
+arch.version.optdepends = ะะฟัะธะพะฝะฐะปัะฝัะต ะทะฐะฒะธัะธะผะพััะธ
+arch.pacman.repo.multi = ะฃ %s ะธะผะตะตััั ะพะดะฝะฐ ะธ ัะฐ ะถะต ะฒะตััะธั ะฒ ัะฐะทะฝัั
ะดะธัััะธะฑััะธะฒะฐั
.
+arch.version.makedepends = ะกะฑะพัะพัะฝัะต ะทะฐะฒะธัะธะผะพััะธ
+arch.version.replaces = ะะฐะผะตะฝัะตั
+arch.version.backup = ะ ะตะท. ะบะพะฟะธั
+arch.version.conflicts = ะะพะฝัะปะธะบััะตั ั
+arch.version.checkdepends = ะัะพะฒะตัะพัะฝัะต ะทะฐะฒะธัะธะผะพััะธ
+container.images.title = ะะฑัะฐะทั
+search_in_external_registry = ะะฐะนัะธ ะฒ %s
+alt.repository = ะ ัะตะฟะพะทะธัะพัะธะธ
+alt.repository.architectures = ะัั
ะธัะตะบัััั
+alt.registry = ะะพะฑะฐะฒััะต ัะตะตััั ะบะพะผะฐะฝะดะพะน:
+alt.repository.multiple_groups = ะญัะพั ะฟะฐะบะตั ะดะพัััะฟะตะฝ ะฒ ะฝะตัะบะพะปัะบะธั
ะณััะฟะฟะฐั
.
+alt.setup = ะะพะฑะฐะฒััะต ัะตะฟะพะทะธัะพัะธะน ะฒ ัะฒะพะน ัะฟะธัะพะบ ัะตะฟะพะทะธัะพัะธะตะฒ (ะฒัะฑะตัะธัะต ะฟะพะดั
ะพะดัััั ะฐัั
ะธัะตะบัััั ะฒะผะตััะพ ยซ_arch_ยป):
+alt.install = ะฃััะฐะฝะพะฒะบะฐ ะฟะฐะบะตัะฐ
+alt.registry.install = ะะปั ัััะฐะฝะพะฒะบะธ ะฟะฐะบะตัะฐ ะฒัะฟะพะปะฝะธัะต ัะปะตะดััััั ะบะพะผะฐะฝะดั:
[secrets]
secrets=ะกะตะบัะตัั
@@ -3712,7 +3905,7 @@ management=ะฃะฟัะฐะฒะปะตะฝะธะต ัะตะบัะตัะฐะผะธ
[actions]
actions=ะะตะนััะฒะธั
-unit.desc=ะฃะฟัะฐะฒะปะตะฝะธะต ะฒัััะพะตะฝะฝัะผะธ ะบะพะฝะฒะตะนะตัะฐะผะธ CI/CD ั ะะตะนััะฒะธัะผะธ Forgejo
+unit.desc=ะฃะฟัะฐะฒะปะตะฝะธะต ะฒัััะพะตะฝะฝัะผะธ ะบะพะฝะฒะตะนะตัะฐะผะธ CI/CD ั ะะตะนััะฒะธัะผะธ Forgejo.
status.unknown=ะะตะธะทะฒะตััะฝะพ
status.waiting=ะะถะธะดะฐะตั
@@ -3803,15 +3996,26 @@ runs.status_no_select = ะัะฑะพะต ัะพััะพัะฝะธะต
runs.no_matching_online_runner_helper = ะะตั ัะฐะฑะพัะฐััะตะณะพ ะธัะฟะพะปะฝะธัะตะปั ั ะผะตัะบะพะน: %s
runs.no_job_without_needs = ะ ะฐะฑะพัะธะน ะฟะพัะพะบ ะดะพะปะถะตะฝ ัะพะดะตัะถะฐัั ั
ะพัั ะฑั ะพะดะฝั ะทะฐะดะฐัั ะฑะตะท ะทะฐะฒะธัะธะผะพััะตะน.
runs.no_job = ะ ะฐะฑะพัะธะน ะฟะพัะพะบ ะดะพะปะถะตะฝ ะฒะบะปััะฐัั ั
ะพัั ะฑั ะพะดะฝั ะทะฐะดะฐัั
+workflow.dispatch.trigger_found = ะญัะพั ัะฐะฑะพัะธะน ะฟะพัะพะบ ััะฐะฑะฐััะฒะฐะตั ะฝะฐ ัะพะฑััะธั workflow_dispatch .
+workflow.dispatch.use_from = ะัะฟะพะปัะทะพะฒะฐัั ัะฐะฑะพัะธะน ะฟะพัะพะบ ะธะท
+workflow.dispatch.run = ะัะฟะพะปะฝะธัั ัะฐะฑะพัะธะน ะฟะพัะพะบ
+workflow.dispatch.success = ะัะฟะพะปะฝะตะฝะธะต ัะฐะฑะพัะตะณะพ ะฟะพัะพะบะฐ ะทะฐะฟัะพัะตะฝะพ ััะฟะตัะฝะพ.
+workflow.dispatch.input_required = ะขัะตะฑะพะฒะฐัั ะทะฝะฐัะตะฝะธะต ะดะปั ะฟะพะปั ยซ%sยป.
+workflow.dispatch.invalid_input_type = ะะตะธะทะฒะตััะฝัะน ัะธะฟ ะฟะพะปั ยซ%sยป.
+workflow.dispatch.warn_input_limit = ะัะพะฑัะฐะถะฐัััั ัะพะปัะบะพ ะฟะตัะฒัะต %d ะฟะพะปะตะน.
+runs.expire_log_message = ะััะฝะฐะป ะฑัะป ัะดะฐะปัะฝ ะธะท-ะทะฐ ััะฐัะพััะธ.
+runs.no_workflows.help_write_access = ะะต ะทะฝะฐะตัะต, ะบะฐะบ ะฝะฐัะฐัั ะธัะฟะพะปัะทะพะฒะฐัั ะะตะนััะฒะธั Forgejo? ะะทะฝะฐะบะพะผััะตัั ั ััะบะพะฒะพะดััะฒะพะผ ะฟะพ ะฑััััะพะผั ััะฐััั ะฒ ะดะพะบัะผะตะฝัะฐัะธะธ ะธ ัะพะทะดะฐะนัะต ะฟะตัะฒัะน ัะฐะฑะพัะธะน ะฟะพัะพะบ, ะทะฐัะตะผ ะฝะฐัััะพะนัะต ะธัะฟะพะปะฝะธัะตะปั Forgejo , ะบะพัะพััะน ะฑัะดะตั ะฒัะฟะพะปะฝััั ะทะฐะดะฐัะธ.
+runs.no_workflows.help_no_write_access = ะะทะฝะฐะบะพะผััะตัั ั ะดะพะบัะผะตะฝัะฐัะธะตะน , ััะพะฑั ัะทะฝะฐัั ะฟัะพ ะะตะนััะฒะธั Forgejo.
+variables.not_found = ะะต ัะดะฐะปะพัั ะฝะฐะนัะธ ะฟะตัะตะผะตะฝะฝัั.
[projects]
type-1.display_name=ะะฝะดะธะฒะธะดัะฐะปัะฝัะน ะฟัะพะตะบั
type-2.display_name=ะัะพะตะบั ัะตะฟะพะทะธัะพัะธั
type-3.display_name=ะัะพะตะบั ะพัะณะฐะฝะธะทะฐัะธะธ
+deleted.display_name = ะฃะดะฐะปัะฝะฝัะน ะฟัะพะตะบั
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=ะะฐัะฐะปะพะณ
normal_file=ะะฑััะฝัะน ัะฐะนะป
executable_file=ะัะฟะพะปะฝัะตะผัะน ัะฐะนะป
@@ -3820,44 +4024,62 @@ submodule=ะะพะดะผะพะดัะปั
-[graphs]
-component_loading_failed = ะะต ัะดะฐะปะพัั ะทะฐะณััะทะธัั %s
-component_failed_to_load = ะกะปััะธะปะฐัั ะฝะตะฟัะตะดะฒะธะดะตะฝะฝะฐั ะพัะธะฑะบะฐ.
-contributors.what = ัะพััะฐััะธะต
-component_loading = ะะฐะณััะทะบะฐ %s...
-component_loading_info = ะญัะพ ะทะฐะนะผัั ะฝะตะบะพัะพัะพะต ะฒัะตะผัโฆ
-code_frequency.what = ัะฐััะพัะฐ ะธะทะผะตะฝะตะฝะธะน
-recent_commits.what = ะฝะตะดะฐะฒะฝะธะต ะบะพะผะผะธัั
-
-
[search]
-search = ะะพะธัะบ...
-fuzzy_tooltip = ะะบะปััะฐัั ัะตะทัะปััะฐัั, ะดะพััะฐัะพัะฝะพ ะฟะพั
ะพะถะธะต ะฝะฐ ะทะฐะฟัะพั
+search = ะะพะธัะบโฆ
+fuzzy_tooltip = ะะบะปััะฐะตั ัะตะทัะปััะฐัั, ะดะพััะฐัะพัะฝะพ ะฟะพั
ะพะถะธะต ะฝะฐ ะทะฐะฟัะพั, ะดะฐะถะต ะฟัะธ ะฝะฐะปะธัะธะธ ะฝะตัะพัะฝะพััะตะน
type_tooltip = ะขะธะฟ ะฟะพะธัะบะฐ
fuzzy = ะัะธะฑะปะธะทะธัะตะปัะฝัะน
match = ะขะพัะฝัะน
-repo_kind = ะะพะธัะบ ัะตะฟะพะทะธัะพัะธะตะฒ...
-user_kind = ะะพะธัะบ ะฟะพะปัะทะพะฒะฐัะตะปะตะน...
-org_kind = ะะพะธัะบ ะพัะณะฐะฝะธะทะฐัะธะน...
-team_kind = ะะพะธัะบ ะบะพะผะฐะฝะด...
-code_kind = ะะพะธัะบ ะฟะพ ะบะพะดั...
-package_kind = ะะพะธัะบ ะฟะฐะบะตัะพะฒ...
-project_kind = ะะพะธัะบ ะฟัะพะตะบัะพะฒ...
-branch_kind = ะะพะธัะบ ะฒะตัะพะบ...
-commit_kind = ะะพะธัะบ ะบะพะผะผะธัะพะฒ...
+repo_kind = ะะฐะนัะธ ัะตะฟะพะทะธัะพัะธะธโฆ
+user_kind = ะะฐะนัะธ ะฟะพะปัะทะพะฒะฐัะตะปะตะนโฆ
+org_kind = ะะฐะนัะธ ะพัะณะฐะฝะธะทะฐัะธะธโฆ
+team_kind = ะะฐะนัะธ ะบะพะผะฐะฝะดัโฆ
+code_kind = ะะฐะนัะธ ะฒ ะบะพะดะตโฆ
+package_kind = ะะฐะนัะธ ะฟะฐะบะตััโฆ
+project_kind = ะะฐะนัะธ ะฟัะพะตะบััโฆ
+branch_kind = ะะฐะนัะธ ะฒะตัะฒะธโฆ
+commit_kind = ะะฐะนัะธ ะบะพะผะผะธััโฆ
no_results = ะะพ ะทะฐะฟัะพัั ะฝะธัะตะณะพ ะฝะต ะฝะฐะนะดะตะฝะพ.
-keyword_search_unavailable = ะะพะธัะบ ะฟะพ ะบะปััะตะฒัะผ ัะปะพะฒะฐะผ ะฝะตะดะพัััะฟะตะฝ. ะฃัะพัะฝะธัะต ะฟะพะดัะพะฑะฝะพััะธ ั ะฐะดะผะธะฝะธัััะฐัะพัะฐ.
+keyword_search_unavailable = ะะพะธัะบ ะฟะพ ะบะปััะตะฒัะผ ัะปะพะฒะฐะผ ะฝะตะดะพัััะฟะตะฝ. ะฃัะพัะฝะธัะต ะฟะพะดัะพะฑะฝะพััะธ ั ะฐะดะผะธะฝะธัััะฐัะพัะฐ ัะตัะฒะตัะฐ.
match_tooltip = ะะบะปััะฐัั ัะพะปัะบะพ ัะตะทัะปััะฐัั, ัะพัะฝะพ ัะพะพัะฒะตัััะฒัััะธะต ะทะฐะฟัะพัั
-code_search_unavailable = ะะพะธัะบ ะฟะพ ะบะพะดั ัะตะนัะฐั ะฝะตะดะพัััะฟะตะฝ. ะฃัะพัะฝะธัะต ะฟะพะดัะพะฑะฝะพััะธ ั ะฐะดะผะธะฝะธัััะฐัะพัะฐ.
-runner_kind = ะะพะธัะบ ะธัะฟะพะปะฝะธัะตะปะตะน...
-code_search_by_git_grep = ะญัะธ ัะตะทัะปััะฐัั ะฟะพะปััะตะฝั ัะตัะตะท ยซgit grepยป. ะ ะตะทัะปััะฐัะพะฒ ะผะพะถะตั ะฑััั ะฑะพะปััะต, ะตัะปะธ ะฐะดะผะธะฝะธัััะฐัะพั ัะตัะฒะตัะฐ ะฒะบะปััะธั ะธะฝะดะตะบัะฐัะพั ะบะพะดะฐ.
+code_search_unavailable = ะะพะธัะบ ะฒ ะบะพะดะต ะฝะตะดะพัััะฟะตะฝ. ะฃัะพัะฝะธัะต ะฟะพะดัะพะฑะฝะพััะธ ั ะฐะดะผะธะฝะธัััะฐัะพัะฐ ัะตัะฒะตัะฐ.
+runner_kind = ะะฐะนัะธ ะธัะฟะพะปะฝะธัะตะปะตะนโฆ
+code_search_by_git_grep = ะญัะธ ัะตะทัะปััะฐัั ะฟะพะปััะตะฝั ัะตัะตะท ยซgit grepยป. ะ ะตะทัะปััะฐัะพะฒ ะผะพะถะตั ะฑััั ะฑะพะปััะต, ะตัะปะธ ะฝะฐ ัะตัะฒะตัะต ะฑัะดะตั ะฒะบะปััะตะฝ ะธะฝะดะตะบัะฐัะพั ะบะพะดะฐ.
exact = ะขะพัะฝัะน
-exact_tooltip = ะะบะปััะฐัั ัะพะปัะบะพ ัะตะทัะปััะฐัั, ัะพัะฝะพ ัะพะพัะฒะตัััะฒัััะธะต ะทะฐะฟัะพัั
-issue_kind = ะะพะธัะบ ะทะฐะดะฐั...
-pull_kind = ะะพะธัะบ ัะปะธัะฝะธะน...
+exact_tooltip = ะะบะปััะฐะตั ัะพะปัะบะพ ัะตะทัะปััะฐัั, ะฒ ัะพัะฝะพััะธ ัะพะพัะฒะตัััะฒัััะธะต ะทะฐะฟัะพัั
+issue_kind = ะะฐะนัะธ ะทะฐะดะฐัะธโฆ
+pull_kind = ะะฐะนัะธ ัะปะธัะฝะธัโฆ
+union_tooltip = ะะบะปััะฐะตั ัะตะทัะปััะฐัั ั ัะพะฒะฟะฐะฒัะธะผะธ ะบะปััะตะฒัะผะธ ัะปะพะฒะฐะผะธ, ัะฐะทะดะตะปัะฝะฝัะผะธ ะฟัะพะฑะตะปะฐะผะธ
+union = ะะฑััะฝัะน
+milestone_kind = ะะฐะนัะธ ััะฐะฟั...
+regexp = ะ ะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต
+regexp_tooltip = ะะพะธัะบะพะฒัะน ะทะฐะฟัะพั ะฑัะดะตั ะฒะพัะฟัะธะฝัั ะบะฐะบ ัะตะณัะปััะฝะพะต ะฒััะฐะถะตะฝะธะต
[markup]
filepreview.line = ะกััะพะบะฐ %[1]d ะฒ %[2]s
filepreview.lines = ะกััะพะบะธ ั %[1]d ะฟะพ %[2]d ะฒ %[3]s
-filepreview.truncated = ะัะตะดะฟัะพัะผะพัั ะฑัะป ะพะฑัะตะทะฐะฝ
\ No newline at end of file
+filepreview.truncated = ะัะตะดะฟัะพัะผะพัั ะฑัะป ะพะฑัะตะทะฐะฝ
+
+[translation_meta]
+test = Forgejo
+
+[repo.permissions]
+code.write = ะะฐะฟะธัั: ะพัะฟัะฐะฒะบะฐ ะธะทะผะตะฝะตะฝะธะน ะฒ ัะตะฟะพะทะธัะพัะธะน, ัะพะทะดะฐะฝะธะต ะฒะตัะพะบ ะธ ัะตะณะพะฒ.
+code.read = ะงัะตะฝะธะต: ะฟัะพัะผะพัั ะธ ะบะปะพะฝะธัะพะฒะฐะฝะธะต ะธัั
ะพะดะฝะพะณะพ ะบะพะดะฐ ัะตะฟะพะทะธัะพัะธั.
+issues.read = ะงัะตะฝะธะต: ะฟัะพัะผะพัั ะธ ัะพะทะดะฐะฝะธะต ะทะฐะดะฐั ะธ ะบะพะผะผะตะฝัะฐัะธะตะฒ.
+pulls.read = ะงัะตะฝะธะต: ะฟัะพัะผะพัั ะธ ะพัะบัััะธะต ะทะฐะฟัะพัะพะฒ ัะปะธัะฝะธะน.
+releases.read = ะงัะตะฝะธะต: ะฟัะพัะผะพัั ะฒัะฟััะบะพะฒ ะธ ัะบะฐัะธะฒะฐะฝะธะต ัะฐะนะปะพะฒ.
+releases.write = ะะฐะฟะธัั: ะฟัะฑะปะธะบะฐัะธั, ะธะทะผะตะฝะตะฝะธะต ะธ ัะดะฐะปะตะฝะธะต ะฒัะฟััะบะพะฒ ะธ ะธั
ัะฐะนะปะพะฒ.
+wiki.read = ะงัะตะฝะธะต: ะฟัะพัะผะพัั ัััะฐะฝะธั ะธ ะธััะพัะธะธ ัะตะดะฐะบัะธัะพะฒะฐะฝะธั ะฒัััะพะตะฝะฝะพะน ะฒะธะบะธ.
+projects.write = ะะฐะฟะธัั: ัะพะทะดะฐะฝะธะต ะธ ะธะทะผะตะฝะตะฝะธะต ะฟัะพะตะบัะพะฒ ะธ ะบะพะปะพะฝะพะบ.
+packages.write = ะะฐะฟะธัั: ะฟัะฑะปะธะบะฐัะธั ะธ ัะดะฐะปะตะฝะธะต ะฟะฐะบะตัะพะฒ ะฒ ัะตะฟะพะทะธัะพัะธะธ.
+projects.read = ะงัะตะฝะธะต: ะฟัะพัะผะพัั ะฟัะพะตะบัะพะฒ ะฒ ัะตะฟะพะทะธัะพัะธะธ.
+ext_wiki = ะะพัััะฟ ะบะพ ัััะปะบะต ะฝะฐ ะฒะฝะตัะฝัั ะฒะธะบะธ. ะะฐัััะพะนะบะฐ ัะฐะทัะตัะตะฝะธะน ะฒัะฟะพะปะฝัะตััั ะฒะฝะต ัะฐะนัะฐ.
+actions.read = ะงัะตะฝะธะต: ะฟัะพัะผะพัั ะธะฝัะตะณัะธัะพะฒะฐะฝะฝัั
ะบะพะฝะฒะตะนะตัะพะฒ CI/CD ะธ ะธั
ะปะพะณะพะฒ.
+pulls.write = ะะฐะฟะธัั: ะทะฐะบัััะธะต ะทะฐะฟัะพัะพะฒ ัะปะธัะฝะธะน ะธ ะธะทะผะตะฝะตะฝะธะต ะธั
ะผะตัะฐะดะฐะฝะฝัั
: ะผะตัะพะบ, ััะฐะฟะฐ, ะฝะฐะทะฝะฐัะตะฝะธะน, ััะพะบะฐ ะฒัะฟะพะปะฝะตะฝะธั ะธ ะทะฐะฒะธัะธะผะพััะตะน ะธ ะฟั.
+issues.write = ะะฐะฟะธัั: ะทะฐะบัััะธะต ะทะฐะดะฐั ะธ ะธะทะผะตะฝะตะฝะธะต ะธั
ะผะตัะฐะดะฐะฝะฝัั
: ะผะตัะพะบ, ััะฐะฟะฐ, ะฝะฐะทะฝะฐัะตะฝะธะน, ััะพะบะฐ ะฒัะฟะพะปะฝะตะฝะธั ะธ ะทะฐะฒะธัะธะผะพััะตะน ะธ ะฟั.
+actions.write = ะะฐะฟะธัั: ัััะฝะพะน ะทะฐะฟััะบ, ะฟะตัะตะทะฐะฟััะบ, ะพัะผะตะฝะฐ ะธ ะพะดะพะฑัะตะฝะธะต ัะฐะฑะพัั ะบะพะฝะฒะตะนะตัะพะฒ CI/CD.
+wiki.write = ะะฐะฟะธัั: ัะพะทะดะฐะฝะธะต, ะธะทะผะตะฝะตะฝะธะต ะธ ัะดะฐะปะตะฝะธะต ัััะฐะฝะธั ะฒะพ ะฒัััะพะตะฝะฝะพะน ะฒะธะบะธ.
+packages.read = ะงัะตะฝะธะต: ะฟัะพัะผะพัั ะธ ัะบะฐัะธะฒะฐะฝะธะต ะฟะฐะบะตัะพะฒ ะฒ ัะตะฟะพะทะธัะพัะธะธ.
+ext_issues = ะะพัััะฟ ะบ ัััะปะบะต ะฝะฐ ะฒะฝะตัะฝะธะน ััะตะบะตั ะทะฐะดะฐั. ะะฐัััะพะนะบะฐ ัะฐะทัะตัะตะฝะธะน ะฒัะฟะพะปะฝัะตััั ะฒะฝะต ัะฐะนัะฐ.
diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini
index a6fb37c2bb..6dbb6dc3c2 100644
--- a/options/locale/locale_si-LK.ini
+++ b/options/locale/locale_si-LK.ini
@@ -101,6 +101,11 @@ concept_user_organization=เทเถเทเทเถฐเทเถฑเถบ
name=เถฑเถธ
+filter = เถดเทเถปเทเถฑ
+filter.is_archived = เทเถเถปเถเทเทเทเถญ
+filter.public = เถดเทโเถปเทเทเถฏเทเถฐ
+filter.private = เถดเทเถฏเทเถเถฝเทเถ
+
[aria]
[heatmap]
@@ -116,7 +121,6 @@ missing_csrf=เถฑเถปเถ เถเถฝเทเถฝเทเถธ: CSRF เถงเทเถเถฑเท เถฑเทเถธเทเถญ
app_desc=เทเทเถฏเถฑเทเถเทเถปเท, เทเทเทเถบเถ-เทเถญเทเถเทเถปเถ Git เทเทเทเทเทเถเท
install=เทเทเถฎเทเถดเถฑเถบเถง เถดเทเทเทเถบ
platform=เทเถปเทเท เทเทเถฏเทเถเทเท
-platform_desc=Forgejo เถเถฑเทเถธ เถญเทเถฑเถ เถฐเทเทเถฑเถบ Go เทเถณเทเท เทเถธเทเถดเทเถฏเถฑเถบ เถเท
เทเทเถเทเถบ: เทเทเถฑเทเถฉเทเทเท, เถธเทเถเทเทเท, เถฝเทเถฑเถเทเทเท, ARM, เถเถฏเทเถบ เถเถถ เถเถฏเถปเถบ เถเถปเถฑ เถเถเถเท เถญเทเถปเถฑเทเถฑ!
lightweight=เทเทเทเทเถฝเทเถฝเท
lightweight_desc=Forgejo เถ
เถฉเท เถ
เทเถธ เถ
เทเทเทเถบเถญเท เถเถญเท เถ
เถญเถป เถธเทเถฝ เถ
เถฉเท Raspberry Pi เถธเถญ เถฐเทเทเถฑเถบ เถเท
เทเทเถเทเถบ. เถเถถเท เถบเถฑเทเถญเทเถป เทเถเทเถญเทเถบ เทเทเถปเถเทเถฑเทเถฑ!
license=เทเทเทเทเถญ เถธเทเถฝเทเทเทโเถป
@@ -822,7 +826,7 @@ migrate.migrating_failed=%s เทเทเถง เทเถเถเทเถปเถธเถซเถบ เทเทเถธ
migrate.migrating_failed_no_addr=เทเถเถเทเถปเถธเถซเถบ เถ
เทเทเถปเทเถฎเถเถบเท.
migrate.git.description=เถเถฑเทเถธ Git เทเทเทเทเทเถเทเถฑเท เถดเถธเถซเถเท เถเถถเถฉเทเทเถเท เทเถเถเทเถปเถธเถซเถบ เถเถปเถฑเทเถฑ.
migrate.gitlab.description=gitlab.com เทเท เทเทเถฑเถญเท GitLab เถ
เทเทเทเถฎเท เทเถฝเทเถฑเท เถฏเถญเทเถญ เทเถเถเทเถปเถธเถซเถบ เถเถปเถฑเทเถฑ.
-migrate.gitea.description=Gitea.com เทเท เทเทเถฑเถญเท Gitea/Forgejo เถ
เทเทเทเถฎเท เทเถฝเทเถฑเท เถฏเถญเทเถญ เทเถเถเทเถปเถธเถซเถบ เถเถปเถฑเทเถฑ.
+migrate.gitea.description=Gitea.com เทเท เทเทเถฑเถญเท Gitea เถ
เทเทเทเถฎเท เทเถฝเทเถฑเท เถฏเถญเทเถญ เทเถเถเทเถปเถธเถซเถบ เถเถปเถฑเทเถฑ.
migrate.gogs.description=notabug.org เทเท เทเทเถฑเถญเท Gogs เถ
เทเทเทเถฎเท เทเถฝเทเถฑเท เถฏเถญเทเถญ เทเถเถเทเถปเถธเถซเถบ เถเถปเถฑเทเถฑ.
migrate.onedev.description=code.onedev.io เทเท เทเทเถฑเถญเท OnedeV เถ
เทเทเทเถฎเท เทเถฝเทเถฑเท เถฏเถญเทเถญ เทเถเถเทเถปเถธเถซเถบ เถเถปเถฑเทเถฑ.
migrate.gitbucket.description=GitBucket เถ
เทเทเทเถฎเท เทเถฝเทเถฑเท เถฏเถญเทเถญ เทเถเถเทเถปเถธเถซเถบ เถเถปเถฑเทเถฑ.
@@ -890,6 +894,7 @@ file_copy_permalink=เถดเทเถงเถดเถญเท เถธเทเถธเถฝเทเถฑเทเถเท
video_not_supported_in_browser=เถเถถเถเท เถถเทเถปเทเทเทเถปเถบ HTML5 'เทเทเถฉเทเถบเท' เถงเทเถเถบ เทเถณเทเท เทเทเถบ เถฑเทเถฏเถเทเทเถบเท.
audio_not_supported_in_browser=เถเถถเถเท เถถเทเถปเทเทเทเถปเถบ HTML5 'เทเทเถปเทเทเถบ' เถงเทเถเถบ เทเถณเทเท เทเทเถบ เถฑเทเถฏเถเทเทเถบเท.
stored_lfs=Git LFS เทเถธเถ เถเถถเถฉเท
+stored_annex=Git Annex เทเถธเถ เถเถถเถฉเท
symbolic_link=เทเถเถเทเถญเทเถญเทเถธเถ เทเถถเทเถณเทเถบ
commit_graph=เถดเทเถปเทเทเถญเทเถปเถบ เถเทเถด
commit_graph.select=เทเทเถเท เถญเทเถปเถฑเทเถฑ
@@ -907,6 +912,7 @@ editor.upload_file=เถเทเถฑเทเท เถเถฉเทเถเถญ เถเถปเถฑเทเถฑ
editor.edit_file=เถเทเถฑเทเท เทเถเทเทเถเถปเถซเถบ
editor.preview_changes=เทเทเถฑเทเทเถเถธเท เถดเทเถปเถฏเทเทเถฑ
editor.cannot_edit_lfs_files=LFS เถเทเถฑเท เทเทเถถเท เถ
เถญเทเถปเท เถธเทเทเทเถซเถญ เถญเทเท
เทเถเทเทเถเถปเถซเถบ เถเท
เถฑเทเทเทเถ.
+editor.cannot_edit_annex_files=Annex เถเทเถฑเท เทเทเถถเท เถ
เถญเทเถปเท เถธเทเทเทเถซเถญ เถญเทเท
เทเถเทเทเถเถปเถซเถบ เถเท
เถฑเทเทเทเถ.
editor.cannot_edit_non_text_files=เถฏเทเทเทเถธเถบ เถเทเถฑเท เทเทเถถเท เถ
เถญเทเถปเท เถธเทเทเทเถซเถญ เถญเทเท
เทเถเทเทเถเถปเถซเถบ เถเท
เถฑเทเทเทเถ.
editor.edit_this_file=เถเทเถฑเทเท เทเถเทเทเถเถปเถซเถบ
editor.this_file_locked=เถเทเถฑเทเทเถง เถ
เถเทเท
เท เถฝเท เถเถญ
@@ -920,10 +926,10 @@ editor.or=เทเท
editor.cancel_lower=เถ
เทเถฝเถเถเท เถเถปเถฑเทเถฑ
editor.commit_signed_changes=เถ
เถญเทเทเถฑเท เถเท
เทเทเถฑเทเทเถเถธเท เทเทเถฏเท เถเถปเถฑเทเถฑ
editor.commit_changes=เทเทเถฑเทเทเถเถธเท เทเทเถฏเท เถเถปเถฑเทเถฑ
-editor.add_tmpl='' เถเถเถญเท เถเถปเถฑเทเถฑ
+editor.add_tmpl='<%s>' เถเถเถญเท เถเถปเถฑเทเถฑ
editor.commit_message_desc=เทเทเถเถฝเทเถด เถฏเทเถปเทเถ เทเทเทเทเถญเถปเถบเถเท เถเถเท เถเถปเถฑเทเถฑโฆ
editor.signoff_desc=เถเทเถดเทเท เถฝเทเถเท เถดเถซเทเทเทเถฉเถบ เถ
เทเทเทเถฑเถบเท เถฏเท เถเทเถดเถเถปเท เทเทเทเทเถฑเท เทเทเถเทเถฑเทเถฉเท-เถเทเท-เทเทเทเทเถฑเท เถงเทเถปเทเถฝเถปเถบเถเท เถเถเท เถเถปเถฑเทเถฑ.
-editor.commit_directly_to_this_branch=%s เทเทเถเทเทเถง เถเทเถฝเทเถฑเทเถธ เถเทเถด เถเถปเถฑเทเถฑ.
+editor.commit_directly_to_this_branch=%[1]s เทเทเถเทเทเถง เถเทเถฝเทเถฑเทเถธ เถเทเถด เถเถปเถฑเทเถฑ.
editor.create_new_branch=เถธเทเถธ เถเทเถด เถเทเถปเทเถธ เทเถณเทเท เถฑเท เทเทเถเทเทเถเท เทเทเถฏเท เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธเถเท เถเถปเถธเทเถท เถเถปเถฑเทเถฑ.
editor.create_new_branch_np=เถธเทเถธ เถเทเถด เถเทเถปเทเถธ เทเถณเทเท เถฑเท เทเทเถเทเทเถเท เทเทเถฏเถฑเทเถฑ.
editor.propose_file_change=เถเทเถฑเท เทเทเถฑเทเท เถเทเถปเทเถธ เถบเทเถขเถฑเท เถเถปเถฑเทเถฑ
@@ -1098,12 +1104,12 @@ issues.reopen_comment_issue=เถ
เถฏเทเทเท เถฏเถเทเทเท เทเทเทเทเถญ เถ
issues.create_comment=เถ
เถฏเทเท
issues.closed_at=`เถธเทเถธ เถเทเถงเท
เทเท เทเทเท %[2]s `
issues.reopened_at=`เถธเทเถธ เถเทเถงเท
เทเท เถฑเทเทเถญ เทเทเทเทเถญ เถเถปเถฑ เถฝเถฏเท %[2]s `
-issues.ref_issue_from=เถธเทเถธ เถฑเทเถเทเถญเทเท %[4]s เทเท %[2]s
-issues.ref_pull_from=เถธเทเถธ เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธ%[4]s %[2]s
-issues.ref_closing_from=เถธเทเถธ เถเทเถงเท
เทเท เทเทเท เถฏเถธเถฑเท เถเถญ%[4]s เถธเทเถธ เถเทเถงเท
เทเท %[2]s
-issues.ref_reopening_from=เถธเทเถธ เถเทเถงเท
เทเท เถฑเทเทเถญ เทเทเทเทเถญ เถเถปเถฑเท เถเถญ%[4]s เถธเทเถธ เถเทเถงเท
เทเท %[2]s
-issues.ref_closed_from=เถธเทเถธ เถฑเทเถเทเถญเทเท%[4]s %[2]s
-issues.ref_reopened_from=เถธเทเถธ เถฑเทเถเทเถญเทเท%[4]s %[2]s เถฑเทเทเถญ เทเทเทเทเถญ เถเถปเถฑ เถฝเถฏเท
+issues.ref_issue_from=`เถธเทเถธ เถฑเทเถเทเถญเทเท %[4]s เทเท %[2]s `
+issues.ref_pull_from=`เถธเทเถธ เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธ%[4]s %[2]s `
+issues.ref_closing_from=`เถธเทเถธ เถเทเถงเท
เทเท เทเทเท เถฏเถธเถฑเท เถเถญ%[4]s เถธเทเถธ เถเทเถงเท
เทเท %[2]s `
+issues.ref_reopening_from=`เถธเทเถธ เถเทเถงเท
เทเท เถฑเทเทเถญ เทเทเทเทเถญ เถเถปเถฑเท เถเถญ%[4]s เถธเทเถธ เถเทเถงเท
เทเท %[2]s `
+issues.ref_closed_from=`เถธเทเถธ เถฑเทเถเทเถญเทเท%[4]s %[2]s `
+issues.ref_reopened_from=`เถธเทเถธ เถฑเทเถเทเถญเทเท%[4]s %[2]s เถฑเทเทเถญ เทเทเทเทเถญ เถเถปเถฑ เถฝเถฏเท`
issues.ref_from=`เทเทเถธ%[1]s`
issues.role.owner=เทเทเถธเทเถเถปเท
issues.role.member=เทเทเถธเทเถขเทเถ
@@ -1183,7 +1189,7 @@ issues.error_modifying_due_date=เถฑเทเถบเถธเทเถญ เถฏเทเถฑเถบ เทเทเถฑเทเท
issues.error_removing_due_date=เถฑเทเถบเถธเทเถญ เถฏเทเถฑเถบ เถเทเถญเท เถเทเถปเทเถธเถง เถ
เถดเทเทเทเทเถญเท เทเทเถบ.
issues.push_commit_1=เถเถเถญเท %d เถเทเถด %s
issues.push_commits_n=เถเถเถญเท %d เทเทเทเถปเถบเถฑเท %s
-issues.force_push_codes=`เถถเถฝเถบ-pushed%[1]s เทเทเถง %[2]s
%[4]s เถเท
%[6]s`
+issues.force_push_codes=`เถถเถฝเถบ-pushed%[1]s เทเทเถง %[2]s
%[4]s เถเท
%[6]s`
issues.force_push_compare=เทเทเถณเถฑเทเถฑ
issues.due_date_form=Yyy-mm-dd
issues.due_date_form_add=เถฑเทเถบเถธเทเถญ เถฏเทเถฑเถบ เถเถเถญเท เถเถปเถฑเทเถฑ
@@ -1269,7 +1275,7 @@ pulls.nothing_to_compare=เถธเทเถธ เทเทเถเท เทเถธเทเถฑ เทเท. เถ
เถฏเท
pulls.nothing_to_compare_and_allow_empty_pr=เถธเทเถธ เทเทเถเท เทเถธเทเถฑ เทเท. เถธเทเถธ เถธเทเถขเถฑ เทเถธเทเถถเถฑเทเถฐเถญเท เทเทเทเท เทเถฑเท เถเถญ.
pulls.has_pull_request=`เถธเทเถธ เทเทเถเท เถ
เถญเถป เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธ เถฏเทเถฑเถงเถธเถญเท เถดเทเถญเท: %[2]s #%[3]d `
pulls.create=เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธ เถฑเทเถปเทเถธเทเถซเถบ
-pulls.title_desc_few=%[1]d เทเทเถง %[2]s
เถฏเถเทเทเท %[3]s
+pulls.title_desc_few=%[1]d เทเทเถง %[2]s
เถฏเถเทเทเท %[3]s
pulls.merged_title_desc_few=เถธเถปเทเถขเท%[1]d เทเทเถง %[2]s
เถฏเถเทเทเท %[3]s
%[4]s
pulls.change_target_branch_at=`เถเถฝเถเทเถเถเถญ เทเทเถเทเท %s เทเทเถง %s %sเถฏเถเทเทเท เทเทเถฑเทเท เถเถป เถเถญ`
pulls.tab_conversation=เทเถเทเทเถฏเถบ
@@ -1280,7 +1286,7 @@ pulls.cant_reopen_deleted_branch=เทเทเถเทเท เถธเถเท เถฏเทเถธเท เถฑเท
pulls.merged=เทเถเถบเทเถเทเถญ เถเทเถปเทเถซเท
pulls.manually_merged=เถ
เถญเทเถฑเท เทเถเถบเทเถเทเถญ เถเถป เถเถญ
pulls.is_closed=เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธ เทเทเท เถฏเถธเท เถเถญ.
-pulls.title_wip_desc=เถ
เทเถธเทเถถเทเถฑเท เถเถเทเถถเถฏเทเถฐ เถเทเถปเทเถธเทเถฑเท เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธ เทเทเท
เทเถเทเทเทเถธ เทเถณเทเท %s เทเถธเถ เถธเทเถญเทเถเทเท เถเถปเถธเทเถท เถเถปเถฑเทเถฑ.
+pulls.title_wip_desc=`เถ
เทเถธเทเถถเทเถฑเท เถเถเทเถถเถฏเทเถฐ เถเทเถปเทเถธเทเถฑเท เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธ เทเทเท
เทเถเทเทเทเถธ เทเถณเทเท %s เทเถธเถ เถธเทเถญเทเถเทเท เถเถปเถธเทเถท เถเถปเถฑเทเถฑ.`
pulls.cannot_merge_work_in_progress=เถธเทเถธ เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธ เถเทเถปเทเถบเทเถญเทเถธเถ เทเถฑ เถเทเถปเทเถบเถบเถเท เถฝเทเท เทเถฝเถเทเถซเท เถเถป เถเถญ.
pulls.still_in_progress=เถญเทเถธเถญเท เถเทเถปเทเถบเทเถญเทเถธเถ เทเทเถธเทเถฑเท เถญเทเถถเทเถฏ?
pulls.add_prefix=%s เถเถดเทเถปเทเถเถบ เถเถเถญเท เถเถปเถฑเทเถฑ
@@ -1669,7 +1675,7 @@ settings.event_pull_request_review_desc=เถ
เถฏเทเถฑเทเถฑ เถเถฝเทเถฝเทเถธ
settings.event_pull_request_sync=เทเถธเถธเทเทเทเถปเทเถญ เถเถฝเทเถฝเทเถธ เถ
เถฏเทเถฑเทเถฑ
settings.event_pull_request_sync_desc=เทเถธเถธเทเทเทเถปเทเถญ เถเถฝเทเถฝเทเถธ เถ
เถฏเทเถฑเทเถฑ.
settings.branch_filter=เทเทเถเท เถดเทเถปเทเถฑ
-settings.branch_filter_desc=เถเทเถฝเทเถถเท เถปเถงเทเท เถฝเทเท เถฑเทเทเทเถ เทเถญเท เถฏเถเทเทเท เถเถญเท เถญเถฝเทเถฝเทเท, เทเทเถเท เถฑเทเถปเทเถธเทเถซเถบ เทเท เทเทเถเท เถธเถเทเถฏเทเถธเทเถธเท เทเทเถฏเทเทเทเถธเท เทเถณเทเท เทเทเถเท เทเถบเทเถงเทเถฝเทเทเทเถงเท. เทเทเทเท เทเท *
เถฑเถธเท, เทเทเถบเถฝเท เทเทเถเท เทเถณเทเท เทเทเถฏเทเทเทเถธเท เทเทเถปเทเถญเท เทเท. เทเทเถฑเทเถงเทเถเทเทเท เทเถณเทเท github.com/gobwas/glob เถฝเทเถบเถเทเถบเทเทเถฝเท เถถเถฝเถฑเทเถฑ. เถเถฏเทเทเถปเถซ: เทเทเทเทเถธเทเถบเท
, {เทเทเทเทเถธเทเถบเท, เถธเทเถฏเทเทเทเถปเทเถธ*}
.
+settings.branch_filter_desc=เถเทเถฝเทเถถเท เถปเถงเทเท เถฝเทเท เถฑเทเทเทเถ เทเถญเท เถฏเถเทเทเท เถเถญเท เถญเถฝเทเถฝเทเท, เทเทเถเท เถฑเทเถปเทเถธเทเถซเถบ เทเท เทเทเถเท เถธเถเทเถฏเทเถธเทเถธเท เทเทเถฏเทเทเทเถธเท เทเถณเทเท เทเทเถเท เทเถบเทเถงเทเถฝเทเทเทเถงเท. เทเทเทเท เทเท *
เถฑเถธเท, เทเทเถบเถฝเท เทเทเถเท เทเถณเทเท เทเทเถฏเทเทเทเถธเท เทเทเถปเทเถญเท เทเท. เทเทเถฑเทเถงเทเถเทเทเท เทเถณเทเท %[2]s เถฝเทเถบเถเทเถบเทเทเถฝเท เถถเถฝเถฑเทเถฑ. เถเถฏเทเทเถปเถซ: เทเทเทเทเถธเทเถบเท
, {เทเทเทเทเถธเทเถบเท, เถธเทเถฏเทเทเทเถปเทเถธ*}
.
settings.active=เถเทเถปเทเถบเทเถเทเถปเท
settings.active_helper=เถ
เทเทเถฝเทเทเทเถฝเท เทเทเถฏเทเทเทเถธเท เถดเทเท
เทเถถเถณ เถญเทเถปเถญเทเถปเท เถธเทเถธ เทเทเถถเทเถเทเถเท URL เทเทเถญ เถบเทเถฑเท เถฝเทเถถเท.
settings.add_hook_success=เถธเทเถธ เทเทเถถเท เถเทเถเทเถเทเถฑเท เถเถเถญเท เถเถป เถเถญ.
@@ -1891,7 +1897,7 @@ release.add_tag=เถงเทเถ เถดเถธเถซเถเท เทเทเถฏเถฑเทเถฑ
branch.name=เทเทเถเทเทเท เถฑเถธ
branch.delete_head=เถธเถเถฑเทเถฑ
branch.delete_html=เทเทเถเทเท เถธเถเถฑเทเถฑ
-branch.create_branch=%s เทเทเถเทเท เทเทเถฏเถฑเทเถฑ
+branch.create_branch=%s เทเทเถเทเท เทเทเถฏเถฑเทเถฑ
branch.deleted_by=%sเทเทเทเทเถฑเท เถธเถเท เถฏเถธเถฑ เถฝเถฏเท
branch.included_desc=เถธเทเถธ เทเทเถเทเท เถดเทเถปเถฑเทเถธเท เทเทเถเทเทเท เถเทเถงเทเถเท
branch.included=เถเถญเทเท
เถญเท
@@ -1902,7 +1908,7 @@ branch.create_branch_operation=เทเทเถเทเท เทเทเถฏเถฑเทเถฑ
branch.new_branch=เถฑเท เทเทเถเทเทเถเท เทเทเถฏเถฑเทเถฑ
branch.renamed=เทเทเถเทเท %s %sเถฝเทเท เถฑเถธเท เถเถปเถฑ เถฝเถฏเท.
-tag.create_tag=เถงเทเถเถบ เถฑเทเถปเทเถธเทเถซเถบ %s
+tag.create_tag=เถงเทเถเถบ เถฑเทเถปเทเถธเทเถซเถบ %s
topic.manage_topics=เถธเทเถญเทเถเท เถเท
เถธเถฑเทเถเถปเถซเถบ
@@ -1914,6 +1920,8 @@ error.csv.too_large=เถเถบ เถเถญเท เทเทเทเทเถฝ เถฑเทเทเท เถธเทเถธ เถ
error.csv.unexpected=%d เถดเทเท
เทเถบเท เทเท %dเถญเทเถปเทเทเท เถ
เถฑเถดเทเถเทเทเทเถญ เถ เถปเทเถญเถบเถเท เถ
เถฉเถเถเท เถถเทเทเทเถฑเท เถธเทเถธ เถเทเถฑเทเท เทเทเถฏเทเทเทเถธเทเถเถปเถซเถบ เถเท
เถฑเทเทเทเถ.
error.csv.invalid_field_count=เถธเทเถธ เถเทเถฑเทเท เถปเทเถเทเทเท เทเทเถปเถฏเท เถเทเทเทเถญเทเถป เทเถเถเทเถบเทเทเถเท เถเถญเท เถถเทเทเทเถฑเท เถเถบ เทเทเถฏเทเทเทเถธเทเถเถปเถซเถบ เถเท
เถฑเทเทเทเถ %d.
+milestones.filter_sort.name = เถฑเถธ
+
[graphs]
[org]
@@ -2276,15 +2284,15 @@ auths.tips=เถเถเท
auths.tips.oauth2.general=OUTU2 เทเถญเทเถบเทเถดเถฑ
auths.tip.oauth2_provider=OUTU2 เทเทเถดเถบเทเถธเทเถเถปเท
auths.tip.nextcloud=เถดเทเถญ เทเถณเทเถฑเท เถธเทเถฑเทเท เถทเทเทเทเถญเท เถเถปเถธเทเถฑเท เถเถถเถเท เถเถฏเทเทเถปเถซเถบเถเท เถธเถญ เถฑเท OAUTH เถดเทเถปเทเถทเทเถเทเถเถบเทเถเท เถฝเทเถบเทเถดเถฏเทเถเถ เท เถเถปเถฑเทเถฑ โเทเทเถเทเทเถธเท -> เถเถปเถเทเทเทเท -> OAUTH 2.0 เทเทเทเทเถฏเทเถบเถเถบเทโ
-auths.tip.dropbox=https://www.dropbox.com/developers/apps เทเท เถฑเท เถบเทเถฏเทเถธเถเท เทเทเถฏเถฑเทเถฑ
-auths.tip.facebook=https://developers.facebook.com/apps เทเท เถฑเท เถบเทเถฏเทเถธเถเท เถฝเทเถบเทเถดเถฏเทเถเถ เท เถเถป เถฑเทเทเทเถดเทเถฏเถฑเถบ เถเถเถญเท เถเถปเถฑเทเถฑ โเทเทเทเทเถถเทเถเท เถฝเทเถเทเถฑเท เทเถฑเทเถฑโ
-auths.tip.github=https://github.com/settings/applications/new เทเท เถฑเท OAUTH เถ
เถบเถฏเทเถธเทเถดเถญเถเท เถฝเทเถบเทเถดเถฏเทเถเถ เท เถเถปเถฑเทเถฑ
+auths.tip.dropbox=%s เทเท เถฑเท เถบเทเถฏเทเถธเถเท เทเทเถฏเถฑเทเถฑ
+auths.tip.facebook=%s เทเท เถฑเท เถบเทเถฏเทเถธเถเท เถฝเทเถบเทเถดเถฏเทเถเถ เท เถเถป เถฑเทเทเทเถดเทเถฏเถฑเถบ เถเถเถญเท เถเถปเถฑเทเถฑ โเทเทเทเทเถถเทเถเท เถฝเทเถเทเถฑเท เทเถฑเทเถฑโ
+auths.tip.github=%s เทเท เถฑเท OAUTH เถ
เถบเถฏเทเถธเทเถดเถญเถเท เถฝเทเถบเทเถดเถฏเทเถเถ เท เถเถปเถฑเทเถฑ
auths.tip.gitlab=https://gitlab.com/profile/applications เทเท เถฑเท เถ
เถบเถฏเทเถธเทเถดเถญเถเท เถฝเทเถบเทเถดเถฏเทเถเถ เท เถเถปเถฑเทเถฑ
-auths.tip.google_plus=เถเทเถเถฝเท API เถเทเถฑเทเทเทเถฝเถบ เทเทเถญเทเถฑเท OUT2 เทเทเทเทเถฏเทเถบเถ เถ
เถเทเถญเถดเถญเทเถป เถฝเถถเท เถเถฑเทเถฑ https://console.developers.google.com/
+auths.tip.google_plus=เถเทเถเถฝเท API เถเทเถฑเทเทเทเถฝเถบ เทเทเถญเทเถฑเท OUT2 เทเทเทเทเถฏเทเถบเถ เถ
เถเทเถญเถดเถญเทเถป เถฝเถถเท เถเถฑเทเถฑ %s
auths.tip.openid_connect=เถ
เถฑเทเถญ เถฝเถเทเทเทเถบ เถฑเทเถบเถธ เถเทเถปเทเถธ เทเถณเทเท OpenID Connect เถฉเทเทเทเถเทเถปเท URL (/.เทเทเถณเทเถฑเท เถฏเทเถฑ /openid-เทเทเถฑเทเถบเทเทเถบ) เถทเทเทเทเถญเท เถเถปเถฑเทเถฑ
-auths.tip.twitter=https://dev.twitter.com/apps เทเทเถญ เถบเถฑเทเถฑ, เถบเทเถฏเทเถธเถเท เทเทเถฏเถฑเทเถฑ เทเท โเถธเทเถธ เถบเทเถฏเทเถธ เถงเทเทเทเถงเถปเท เทเถธเถ เถดเทเถปเถฑเถบ เทเทเถธเถง เถทเทเทเทเถญเท เถเทเถปเทเถธเถง เถเถฉ เถฏเทเถฑเทเถฑโ เทเทเถเถฝเทเถดเถบ เทเถเทเถปเทเถบ เถเถป เถเถญเท เถถเทเถง เทเทเถญเทเถ เทเถฑเทเถฑ
-auths.tip.discord=https://discordapp.com/developers/applications/me เทเท เถฑเท เถ
เถบเถฏเทเถธเทเถดเถญเถเท เถฝเทเถบเทเถดเถฏเทเถเถ เท เถเถปเถฑเทเถฑ
-auths.tip.yandex=https://oauth.yandex.com/client/new เทเท เถฑเท เถบเทเถฏเทเถธเถเท เทเทเถฏเถฑเทเถฑ. โYandex.Passport APIโ เถเทเถงเทเท เถดเทเถญ เทเถณเทเถฑเท เถ
เทเทเถปเถบเถฑเท เถญเทเถปเถฑเทเถฑ: โเทเทเถฏเทเถบเทเถญเท เถญเทเถดเทเถฝเท เถฝเทเถดเทเถฑเถบ เทเทเถญ เถดเทเถปเทเทเทเถบโ, โเถดเถปเทเทเทเถฝเถ เถ
เทเถญเทเถปเท เทเทเถญ เถดเทเถปเทเทเทเถบโ เทเท โเถดเถปเทเทเทเถฝเถ เถฑเทเถธเถบ, เถธเทเถฝเท เถฑเถธ เทเท เทเทเทเถเถธ, เทเทเถญเทเถปเท เถดเทเถปเทเท เถทเทเทเถบโ
+auths.tip.twitter=%s เทเทเถญ เถบเถฑเทเถฑ, เถบเทเถฏเทเถธเถเท เทเทเถฏเถฑเทเถฑ เทเท โเถธเทเถธ เถบเทเถฏเทเถธ เถงเทเทเทเถงเถปเท เทเถธเถ เถดเทเถปเถฑเถบ เทเทเถธเถง เถทเทเทเทเถญเท เถเทเถปเทเถธเถง เถเถฉ เถฏเทเถฑเทเถฑโ เทเทเถเถฝเทเถดเถบ เทเถเทเถปเทเถบ เถเถป เถเถญเท เถถเทเถง เทเทเถญเทเถ เทเถฑเทเถฑ
+auths.tip.discord=%s เทเท เถฑเท เถ
เถบเถฏเทเถธเทเถดเถญเถเท เถฝเทเถบเทเถดเถฏเทเถเถ เท เถเถปเถฑเทเถฑ
+auths.tip.yandex=%s เทเท เถฑเท เถบเทเถฏเทเถธเถเท เทเทเถฏเถฑเทเถฑ. โYandex.Passport APIโ เถเทเถงเทเท เถดเทเถญ เทเถณเทเถฑเท เถ
เทเทเถปเถบเถฑเท เถญเทเถปเถฑเทเถฑ: โเทเทเถฏเทเถบเทเถญเท เถญเทเถดเทเถฝเท เถฝเทเถดเทเถฑเถบ เทเทเถญ เถดเทเถปเทเทเทเถบโ, โเถดเถปเทเทเทเถฝเถ เถ
เทเถญเทเถปเท เทเทเถญ เถดเทเถปเทเทเทเถบโ เทเท โเถดเถปเทเทเทเถฝเถ เถฑเทเถธเถบ, เถธเทเถฝเท เถฑเถธ เทเท เทเทเทเถเถธ, เทเทเถญเทเถปเท เถดเทเถปเทเท เถทเทเทเถบโ
auths.tip.mastodon=เถเถถเถง เทเถญเทเถบเทเถดเถฑเถบ เถเทเถปเทเถธเถง เถ
เทเทเทเถบ mastodon เถเถฏเทเทเถปเถซเถบเถเท เทเถณเทเท เถ
เถทเทเถปเทเถ เท เถเถฏเทเทเถปเถซเถบเถเท URL เถเถเถเท เถเถฏเทเถฑ เถเถปเถฑเทเถฑ (เทเท เถดเทเถปเถฑเทเถธเท เถเถเถเท เถทเทเทเทเถญเท เถเถปเถฑเทเถฑ)
auths.edit=เทเถญเทเถบเทเถดเถฑ เถธเทเถฝเทเทเทเถปเถบ เทเถเทเทเถเถปเถซเถบ เถเถปเถฑเทเถฑ
auths.activated=เถธเทเถธ เทเถญเทเถบเทเถดเถฑ เถธเทเถฝเทเทเทเถปเถบ เทเถเทเถปเทเถบ เถเถป เถเถญ
@@ -2463,6 +2471,9 @@ notices.op=เถเถดเท.
notices.delete_success=เถดเถฏเทเถฐเถญเท เถฏเทเถฑเทเทเทเถธเท เถธเถเท เถฏเถธเท เถเถญ.
+config_summary = เทเทเถปเทเถเทเถบ
+config_settings = เทเทเถเทเทเถธเท
+
[action]
create_repo=เถฑเทเถปเทเถธเทเถญ เถเถถเถฉเทเท %s
rename_repo=%[1]s
เทเทเถง %[3]s เถฏเถเทเทเท เถฑเถธเท เถเถปเถฑ เถฝเถฏ เถเถถเถฉเทเท
@@ -2538,9 +2549,6 @@ owner.settings.cleanuprules.enabled=เทเถถเถฝ เถเถป เถเถญ
[secrets]
[actions]
-
-
-
runners.name=เถฑเถธ
runners.owner_type=เทเถปเทเถเถบ
runners.description=เทเทเทเทเทเถญเถปเถบ
@@ -2557,6 +2565,6 @@ runs.commit=เถเทเถด
[projects]
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=เทเถเถเทเถญเทเถญเทเถธเถ เทเถถเทเถณเทเถบ
+[search]
diff --git a/options/locale/locale_sk-SK.ini b/options/locale/locale_sk-SK.ini
index d37f909c40..885fcf0433 100644
--- a/options/locale/locale_sk-SK.ini
+++ b/options/locale/locale_sk-SK.ini
@@ -142,6 +142,12 @@ name=Meno
value=Hodnota
issues = Problรฉmy
+filter.is_archived = Archivovanรฉ
+filter.private = Sรบkromnรฝ
+
+toggle_menu = Prepni menu
+more_items = Viac vecรญ
+
[aria]
navbar=Navigaฤnรก liลกta
footer=Pรคta
@@ -176,7 +182,7 @@ string.desc=Z - A
[error]
occurred=Vyskytla sa chyba
-report_message=Ak si myslรญte, ลพe ide o chybu Gitea, vyhฤพadajte problรฉmy na GitHub-e alebo v prรญpade potreby otvorte novรฝ problรฉm.
+report_message=Ak si myslรญte, ลพe ide o chybu Forgejo, vyhฤพadajte problรฉmy na Codeberg-e alebo v prรญpade potreby otvorte novรฝ problรฉm.
missing_csrf=Nesprรกvna ลพiadosลฅ: neprรญtomnรฝ CSFR token
invalid_csrf=Nesprรกvna ลพiadosลฅ: nesprรกvny CSFR token
not_found=Nebolo moลพnรฉ nรกjsลฅ cieฤพ.
@@ -185,13 +191,12 @@ network_error=Chyba siete
[startpage]
app_desc=Jednoducho prรญstupnรฝ vlastnรฝ Git
install=Jednoduchรก inลกtalรกcia
-install_desc=Jednoducho spustite binรกrku pre vaลกu platformu, poลกlite ju ako Docker , alebo ju zรญskajte ako balรญฤek .
+install_desc=Jednoducho spustite binรกrku pre vaลกu platformu, poลกlite ju ako Docker , alebo ju zรญskajte ako balรญฤek .
platform=Multiplatformovรฝ
-platform_desc=Forgejo beลพรญ vลกade kde je moลพnรฉ preloลพiลฅ Go : Windows, macOS, Linux, ARM, a podobne. Vyberte si!
lightweight=ฤฝahkรก
lightweight_desc=Forgejo mรก minimรกlne poลพiadavky a mรดลพe beลพaลฅ na Raspberry Pi. ล etrite energiou vรกลกho stroja!
license=Otvorenรฝ zdrojovรฝ kรณd
-license_desc=Zรญskajte Forgejo ! Pridajte sa k nรกm a prispejte , aby bol tento projekt eลกte lepลกรญ. Nehanbite sa byลฅ prispievateฤพom!
+license_desc=Zรญskajte Forgejo ! Pridajte sa k nรกm a prispejte , aby bol tento projekt eลกte lepลกรญ. Nehanbite sa byลฅ prispievateฤพom!
[install]
install=Inลกtalรกcia
@@ -425,7 +430,7 @@ activate_account.text_2=Pre aktivรกciu vaลกeho รบฤtu kliknite, prosรญm, na nasl
activate_email=Overte svoju e-mailovรบ adresu
activate_email.text=Pre overenie vaลกej e-mailovej adresy kliknite, prosรญm, na nasledovnรฝ odkaz do %s :
-register_notify=Vitajte v Forgejo
+register_notify=Vitajte v %s
register_notify.title=%[1]s, vitajte v %[2]s
register_notify.text_1=toto je e-mail potvrdzujรบci vaลกu registrรกciu pre %s!
register_notify.text_2=Teraz sa mรดลพete prihlรกsiลฅ s pouลพรญvateฤพskรฝm menom: %s.
@@ -804,7 +809,7 @@ passcode_invalid=Prรญstupovรฝ kรณd je nesprรกvny. Skรบste to znova.
twofa_enrolled=Vรกลก รบฤet bol zaregistrovanรฝ do dvojfaktorovej autentifikรกcie. Uloลพte si token (%s) na bezpeฤnom mieste, pretoลพe sa zobrazuje iba raz!
twofa_failed_get_secret=Nepodarilo sa zรญskaลฅ tajomstvo.
-webauthn_desc=Bezpeฤnostnรฉ kฤพรบฤe sรบ hardvรฉrovรฉ โโzariadenia obsahujรบce kryptografickรฉ kฤพรบฤe. Mรดลพu byลฅ pouลพitรฉ na dvojfaktorovรบ autentifikรกciu. Bezpeฤnostnรฉ kฤพรบฤe musia podporovaลฅ ลกtandard WebAuthn Authenticator .
+webauthn_desc=Bezpeฤnostnรฉ kฤพรบฤe sรบ hardvรฉrovรฉ โโzariadenia obsahujรบce kryptografickรฉ kฤพรบฤe. Mรดลพu byลฅ pouลพitรฉ na dvojfaktorovรบ autentifikรกciu. Bezpeฤnostnรฉ kฤพรบฤe musia podporovaลฅ ลกtandard WebAuthn Authenticator .
webauthn_register_key=Pridaลฅ bezpeฤnostnรฝ kฤพรบฤ
webauthn_nickname=Prezรฝvka
webauthn_delete_key=Odstrรกniลฅ bezpeฤnostnรฝ kฤพรบฤ
@@ -1011,6 +1016,7 @@ view_git_blame=Zobraziลฅ Git Blame
video_not_supported_in_browser=Vรกลก prehliadaฤ nepodporuje HTML5 tag 'video'.
audio_not_supported_in_browser=Vรกลก prehliadaฤ nepodporuje HTML5 tag 'audio'.
stored_lfs=Uloลพenรฉ pomocou Git LFS
+stored_annex=Uloลพenรฉ pomocou Git Annex
symbolic_link=Symbolickรฝ odkaz
commit_graph=Graf commitov
line=riadok
@@ -1030,7 +1036,7 @@ editor.cancel_lower=Zruลกiลฅ
editor.commit_signed_changes=Odoslaลฅ podpรญsanรฉ zmeny
editor.commit_changes=Odoslaลฅ zmeny
editor.patch=Pouลพiลฅ patch
-editor.commit_directly_to_this_branch=Odoslaลฅ zmeny revรญzie priamo do vetvy %s .
+editor.commit_directly_to_this_branch=Odoslaลฅ zmeny revรญzie priamo do vetvy %[1]s .
editor.cancel=Zruลกiลฅ
editor.commit_empty_file_header=Odoslaลฅ prรกzdny sรบbor
editor.commit_empty_file_text=Sรบbor, ktorรฝ sa chystรกte odoslaลฅ, je prรกzdny. Pokraฤovaลฅ?
@@ -1362,9 +1368,6 @@ owner.settings.cleanuprules.enabled=Povolenรฉ
[secrets]
[actions]
-
-
-
runners.labels=ล tรญtky
@@ -1374,6 +1377,6 @@ runners.labels=ล tรญtky
[projects]
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=Symbolickรฝ odkaz
+[search]
\ No newline at end of file
diff --git a/options/locale/locale_sl.ini b/options/locale/locale_sl.ini
index 962b1d0d72..7754796558 100644
--- a/options/locale/locale_sl.ini
+++ b/options/locale/locale_sl.ini
@@ -1,26 +1,23 @@
-
-
-
[common]
language = Jezik
-passcode = Pristopna koda
+passcode = Vstopna koda
webauthn_error_timeout = Preden je bilo mogoฤe prebrati vaลก kljuฤ, je bil doseลพen ฤasovni rok. Ponovno naloลพite to stran in poskusite znova.
cancel = Prekliฤi
webauthn_sign_in = Pritisnite gumb na varnostnem kljuฤu. ฤe varnostni kljuฤ nima gumba, ga ponovno vstavite.
-create_new = Ustvariteโฆ
+create_new = Ustvari โฆ
disabled = Invalidi
go_back = Pojdi nazaj
licenses = Licence
-sign_in = Prijavite se
+sign_in = Prijava
activities = Dejavnosti
copy_content = Kopiranje vsebine
collaborative = Sodelovanje
archived = Arhivirano
-user_profile_and_more = Profil in nastavitveโฆ
+user_profile_and_more = Profil in nastavitve โฆ
view = Ogled
your_settings = Nastavitve
-explore = Raziลกฤite
-return_to_forgejo = Vrnitev v Forgejo
+explore = Raziลกฤi
+return_to_forgejo = Nazaj na Forgejo
write = Napiลกite
webauthn_error_unknown = Zgodila se je neznana napaka. Prosimo, poskusite znova.
webauthn_reload = Ponovno polnjenje
@@ -41,10 +38,10 @@ page = Stran
concept_system_global = Globalno
forks = Vilice
concept_user_organization = Organizacija
-link_account = Povezava raฤun
+link_account = Poveลพi raฤun
your_profile = Profil
copy_hash = Kopiraj hash
-sign_out = Odjavite se
+sign_out = Odjava
settings = Nastavitve
locked = Zaklenjeno
error = Napaka
@@ -79,7 +76,7 @@ active_stopwatch = Aktivno sledenje ฤasu
organization = Organizacija
new_migrate = Nova migracija
save = Shrani
-sign_in_with_provider = Prijavite se z %s
+sign_in_with_provider = Prijava s/z %s
manage_org = Upravljanje organizacij
new_repo = Nov repozitorij
webauthn_error_unable_to_process = Streลพnik ni mogel obdelati vaลกe zahteve.
@@ -87,24 +84,24 @@ register = Registracija
mirror = Zrcalo
access_token = Token za dostop
download_logs = Prenos dnevnikov
-webauthn_insert_key = Vstavite varnostni kljuฤ
+webauthn_insert_key = Vnesite varnostni kljuฤ
password = Geslo
webauthn_error_duplicated = Varnostni kljuฤ za to zahtevo ni dovoljen. Prepriฤajte se, da kljuฤ ลกe ni registriran.
-template = ล ablona
+template = Predloga
webauthn_press_button = Pritisnite gumb na varnostnem kljuฤuโฆ
unknown = Neznano
sign_up = Registracija
enable_javascript = To spletno mesto zahteva JavaScript.
twofa_scratch = Dvofaktorska koda Scratch
home = Domov
-powered_by = Poganja ga %s
+powered_by = Poganja %s
retry = Ponovite
preview = Predogled
mirrors = Ogledala
loading = Nalaganjeโฆ
show_full_screen = Prikaลพi celoten zaslon
webauthn_error_insecure = WebAuthn podpira samo varne povezave. Za testiranje prek protokola HTTP lahko uporabite izvor "localhost" ali "127.0.0.1"
-username = Usmerjevalno ime
+username = Uporabniลกko ime
tracked_time_summary = Povzetek spremljanega ฤasa na podlagi filtrov seznama zadev
email = E-poลกtni naslov
captcha = CAPTCHA
@@ -114,7 +111,7 @@ milestones = Mejniki
ok = OK
copy_branch = Kopiranje imena veje
artifacts = Artefakti
-signed_in_as = Prijavil se je kot
+signed_in_as = Prijavljeni ste kot
remove = Odstrani
remove_all = Odstrani vse
remove_label_str = Odstranite element "%s"
@@ -243,12 +240,12 @@ smtp_from_helper = e-poลกtni naslov, ki ga bo uporabljal Forgejo. Vnesite navade
[admin]
users.allow_git_hook_tooltip = Kljuke Git se izvajajo kot uporabnik operacijskega sistema, v katerem je nameลกฤen program Forgejo, in imajo enako raven dostopa do gostitelja. Uporabniki s tem posebnim privilegijem Git Hook lahko dostopajo do vseh skladiลกฤ Forgejo in spreminjajo vse zbirke Forgejo ter podatkovno bazo, ki jo uporablja Forgejo. Poslediฤno lahko pridobijo tudi skrbniลกke privilegije Forgejo.
auths.force_smtps_helper = SMTPS se vedno uporablja na vratih 465. ฤe ลพelite, da se SMTPS uporablja tudi na drugih vratih, to nastavite. (V nasprotnem primeru se bo STARTTLS uporabljal na drugih vratih, ฤe ga gostitelj podpira.)
-self_check.database_fix_mysql = Uporabniki MySQL/MariaDB lahko za odpravo teลพav s kollacijo uporabite ukaz "gitea doctor convert", lahko pa teลพavo odpravite tudi z ukazom "ALTER ... COLLATE ..." SQL roฤno.
+self_check.database_fix_mysql = Uporabniki MySQL/MariaDB lahko za odpravo teลพav s kollacijo uporabite ukaz "forgejo doctor convert", lahko pa teลพavo odpravite tudi z ukazom "ALTER ... COLLATE ..." SQL roฤno.
users.purge_help = Prisilno izbriลกite uporabnika in vsa skladiลกฤa, organizacije in pakete, ki so v njegovi lasti. Izbrisani bodo tudi vsi komentarji in vpraลกanja, ki jih je objavil ta uporabnik.
auths.sspi_default_language_helper = Privzet jezik za uporabnike, samodejno ustvarjene z metodo avtentikacije SSPI. Pustite prazno, ฤe ลพelite, da se jezik zazna samodejno.
auths.restricted_filter_helper = Pustite prazno, ฤe ne ลพelite nastaviti nobenega uporabnika kot omejenega. Uporabite zvezdico ("*"), ฤe ลพelite vse uporabnike, ki se ne ujemajo z administratorskim filtrom, nastaviti kot omejene.
-auths.tip.twitter = Pojdite na https://dev.twitter.com/apps, ustvarite aplikacijo in preverite, ali je omogoฤena moลพnost "Allow this application to be used to Sign in with Twitter"
-auths.tip.yandex = Ustvarite novo aplikacijo na spletnem mestu https://oauth.yandex.com/client/new. V razdelku "Yandex.Passport API" izberite naslednja dovoljenja: "Dostop do e-poลกtnega naslova", "Dostop do avatarja uporabnika" in "Dostop do uporabniลกkega imena, imena in priimka, spola"
+auths.tip.twitter = Pojdite na %s, ustvarite aplikacijo in preverite, ali je omogoฤena moลพnost "Allow this application to be used to Sign in with Twitter"
+auths.tip.yandex = Ustvarite novo aplikacijo na spletnem mestu %s. V razdelku "Yandex.Passport API" izberite naslednja dovoljenja: "Dostop do e-poลกtnega naslova", "Dostop do avatarja uporabnika" in "Dostop do uporabniลกkega imena, imena in priimka, spola"
config.git_migrate_timeout = ฤasovna omejitev migracije
config.git_gc_args = Argumenti GC
config.git_max_diff_files = Prikazane najveฤje razlike v datotekah
@@ -312,7 +309,7 @@ appearance = Videz
password = Geslo
authorized_oauth2_applications_description = Tem aplikacijam tretjih oseb ste odobrili dostop do svojega osebnega raฤuna Forgejo. Prosimo, da prekliฤete dostop do aplikacij, ki jih ne uporabljate veฤ.
social_desc = S temi druลพabnimi raฤuni se lahko prijavite v svoj raฤun. Prepriฤajte se, da jih vse prepoznate.
-access_token_desc = Izbrana dovoljenja ลพetona omejujejo avtorizacijo samo na ustrezne poti API . Za veฤ informacij preberite dokumentacijo .
+access_token_desc = Izbrana dovoljenja ลพetona omejujejo avtorizacijo samo na ustrezne poti API . Za veฤ informacij preberite dokumentacijo .
oauth2_client_secret_hint = Skrivnost se ne bo veฤ prikazala, ko zapustite ali osveลพite to stran. Prepriฤajte se, da ste jo shranili.
twofa_desc = Za zaลกฤito raฤuna pred krajo gesla lahko uporabite pametni telefon ali drugo napravo za prejemanje ฤasovno omejenih enkratnih gesel ("TOTP").
twofa_recovery_tip = ฤe napravo izgubite, boste lahko z obnovitvenim kljuฤem za enkratno uporabo ponovno pridobili dostop do raฤuna.
@@ -537,7 +534,7 @@ activate_account.text_1 = Pozdravljeni %[1]s , hvala za registracijo na %[
admin.new_user.subject = Prijavil se je nov uporabnik %s
admin.new_user.user_info = Informacije o uporabniku
admin.new_user.text = Prosimo, da klikni tukaj za upravljanje tega uporabnika iz upraviteljske ploลกฤe.
-register_notify = Dobrodoลกli v Forgejo
+register_notify = Dobrodoลกli v %s
register_notify.title = %[1]s, dobrodoลกli v %[2]s
register_notify.text_2 = V svoj raฤun se lahko prijavite z uporabniลกkim imenom: %s
register_notify.text_3 = ฤe je ta raฤun namesto vas ustvaril nekdo drug, boste morali najprej nastaviti svoje geslo .
@@ -555,7 +552,7 @@ repo.collaborator.added.subject = %s vas je dodal v %s
team_invite.subject = %[1]s vas je povabil, da se pridruลพite organizaciji %[2]s
issue.action.new = @%[1]s ustvaril #%[2]d.
team_invite.text_1 = %[1]s vas je povabil, da se pridruลพite ekipi %[2]s v organizaciji %[3]s.
-team_invite.text_3 = Opomba: To vabilo je bilo namenjeno %[1]. ฤe tega vabila niste priฤakovali, ga lahko ignorirate.
+team_invite.text_3 = Opomba: To vabilo je bilo namenjeno %[1]s. ฤe tega vabila niste priฤakovali, ga lahko ignorirate.
reply = ali neposredno odgovorite na to e-poลกtno sporoฤilo
activate_email = Preverite svoj e-poลกtni naslov
activate_email.title = %s, preverite svoj e-poลกtni naslov
@@ -691,4 +688,4 @@ code = Koda
owner.settings.chef.keypair.description = Za preverjanje pristnosti v registru Chef je potreben par kljuฤev. ฤe ste par kljuฤev ustvarili ลพe prej, se pri ustvarjanju novega para kljuฤev stari par kljuฤev zavrลพe.
[actions]
-runners.runner_manage_panel = Upravljanje tekaฤev
+runners.runner_manage_panel = Upravljanje tekaฤev
\ No newline at end of file
diff --git a/options/locale/locale_sr-SP.ini b/options/locale/locale_sr-SP.ini
new file mode 100644
index 0000000000..56c1a7e650
--- /dev/null
+++ b/options/locale/locale_sr-SP.ini
@@ -0,0 +1,727 @@
+[common]
+home=ะะพัะตัะฝะฐ
+dashboard=ะะพะฝััะพะปะฝะธ ะฟะฐะฝะตะป
+explore=ะัะตะณะปะตะด
+help=ะะพะผะพั
+sign_in=ะัะธัะฐะฒะธัะต ะกะต
+sign_out=ะะดัะฐะฒะฐ
+register=ะ ะตะณะธัััะฐัะธัะฐ
+website=ะะตะฑ-ัััะฐะฝะธัะฐ
+version=ะะตัะทะธัะฐ
+page=ะกััะฐะฝะธัะฐ
+template=ะจะฐะฑะปะพะฝ
+language=ะะตะทะธะบ
+signed_in_as=ะัะธัะฐะฒัะตะฝะธ ััะต ะบะฐะพ
+
+username=ะะพัะธัะฝะธัะบะพ ะธะผะต
+password=ะะพะทะธะฝะบะฐ
+
+
+repository=ะกะฟัะตะผะธััะต
+organization=ะัะณะฐะฝะธะทะฐัะธัะฐ
+mirror=ะะณะปะตะดะฐะปะพ
+new_repo=ะะพะฒะพ ัะฟัะตะผะธััะต
+new_migrate=ะะพะฒะฐ ะผะธะณัะฐัะธัะฐ
+new_mirror=ะะพะฒะพ ะพะณะปะตะดะฐะปะพ
+new_org=ะะพะฒะฐ ะพัะณะฐะฝะธะทะฐัะธัะฐ
+manage_org=ะฃะฟัะฐะฒัะฐัะต ะพัะณะฐะฝะธะทะฐัะธัะฐะผะฐ
+account_settings=ะะพะดะตัะฐะฒะฐัะฐ ะฝะฐะปะพะณะฐ
+settings=ะะพะดะตัะฐะฒะฐัะฐ
+
+
+activities=ะะบัะธะฒะฝะพััะธ
+pull_requests=ะะฐั
ัะตะฒะธ ะทะฐ ัะฟะฐัะฐัะต
+issues=ะะธัะบััะธัะต
+
+cancel=ะัะบะฐะถะธ
+
+
+
+
+
+
+[error]
+
+[startpage]
+
+[install]
+install=ะะฝััะฐะปะฐัะธัะฐ
+db_title=ะะพะดะตัะฐะฒะฐัะฐ ะฑะฐะทะต
+db_type=ะขะธะฟ ะฑะฐะทะต ะฟะพะดะฐัะฐะบะฐ
+host=ะฅะพัั
+password=ะะพะทะธะฝะบะฐ
+db_name=ะะผะต ะฑะฐะทะต ะฟะพะดะฐัะฐะบะฐ
+path=ะัั
+
+repo_path=ะัั ะดะพ ะบะพัะตะฝะฐ ัะฟัะตะผะธััะฐ
+log_root_path=ะัั ะดะพ ะถััะฝะฐะปะฐ
+
+optional_title=ะะฐะฟัะตะดะฝะฐ ะฟะพะดะตัะฐะฒะฐัะฐ
+smtp_host=SMTP ัะตัะฒะตั
+federated_avatar_lookup_popup=ะะผะพะณััะธัะต federated avatars lookup ะดะฐ ะฑะธ ััะต ะบะพัะธััะธะปะธ ัะตะดะตัะฐัะธะฒะฝะธ ัะตัะฒะธั ะฟะพะผะพัั libravatar.
+enable_captcha_popup=ะขัะฐะถะธ Captcha ะฟัะธะปะธะบะพะผ ัะตะณะธัััะฐัะธัะต ะบะพัะธัะฝะธะบะฐ.
+admin_password=ะะพะทะธะฝะบะฐ
+confirm_password=ะะพัะฒัะดะธัะต ะปะพะทะธะฝะบั
+install_btn_confirm=ะฃัะฟะพััะฐะฒะธ Forgejo
+test_git_failed=ะะพะผะฐะฝะดะฐ 'git' ะฝะธัะต ััะฟะตะปะฐ: %v
+
+[home]
+password_holder=ะะพะทะธะฝะบะฐ
+switch_dashboard_context=ะัะตะฑะฐัะธัะต ะบะพะฝัะตะบัั ะบะพะฝััะพะปะฝะพั ะฟะฐะฝะตะปะธ
+collaborative_repos=ะะฐัะตะดะฝะธัะบะฐ ัะฟัะตะผะธััะฐ
+my_orgs=ะะพัะต ะพัะณะฐะฝะธะทะฐัะธัะต
+my_mirrors=ะะพัะฐ ะพะณะปะตะดะฐะปะฐ
+view_home=ะัะธะบะฐะถะธ %s
+
+
+
+issues.in_your_repos=ะฃ ะฒะฐัะธะผ ัะฟัะตะผะธััะธะผะฐ
+
+[explore]
+repos=ะกะฟัะตะผะธััะฐ
+users=ะะพัะธัะฝะธัะธ
+search=ะัะตััะฐะณะฐ
+
+[auth]
+register_helper_msg=ะะตั ะธะผะฐัะต ะฝะฐะปะพะณ? ะัะธัะฐะฒะธัะต ัะต!
+active_your_account=ะะบัะธะฒะธัะฐััะต ะฒะฐั ะฝะฐะปะพะณ
+has_unconfirmed_mail=ะะดัะฐะฒะพ, %s! ะะผะฐัะต ะฝะตะฟะพัะฒััะตะฝั ะฐะดัะตัั ะต-ะฟะพััะต (%s ). ะะบะพ ะฒะฐะผ ะฝะธัะต ััะธะณะปะพ ะฟะธัะผะพ ัะฐ ะฟะพัะฒัะดะพะผ ะธะปะธ ะผะพัะฐัะต ะดะฐ ะฟะพัะฐัะตัะต ะฝะพะฒั ะฟะพััะบั, ะฟัะธัะธัะฝะธัะต ะฝะฐ ะฟัะฐัะตัะต ะดัะณะผะต.
+resend_mail=ะะปะธะบะฝะธัะต ะพะฒะดะต ะดะฐ ะฟะพะฝะพะฒะพ ะฟะพัะฐัะตัะต ะฟะธัะผะพ
+
+[mail]
+activate_account=ะะพะปะธะผะพ ะฒะฐั ะฐะบัะธะฒะธัะฐััะต ะฒะฐั ะฝะฐะปะพะณ
+
+activate_email=ะะพัะฒัะดะธัะต ะฒะฐัั ะฐะดัะตัั ะต-ะฟะพััะต
+
+
+
+
+
+
+
+
+
+[modal]
+yes=ะะฐ
+no=ะะต
+
+[form]
+UserName=ะะพัะธัะฝะธัะบะพ ะธะผะต
+RepoName=ะะผะต ัะฟัะตะผะธััะฐ
+Email=ะะดัะตัะฐ ะตะป. ะฟะพััะต
+Password=ะะพะทะธะฝะบะฐ
+SSHTitle=ะะผะต SSH ะบัััะฐ
+HttpsUrl=HTTPS URL ะฐะดัะตัะฐ
+PayloadUrl=URL ะฐะดัะตัะฐ ะทะฐ ัะปะฐัะต
+TeamName=ะะผะต ัะธะผะฐ
+AuthName=ะััะพัะธะทะฐัะธััะบะพ ะธะผะต
+AdminEmail=ะะดัะตัะฐ ะต-ะฟะพััะต ะฐะดะผะธะฝะธัััะฐัะพัะฐ
+
+NewBranchName=ะะผะต ะฝะพะฒะต ะณัะฐะฝะต
+CommitSummary=ะะฟะธั ะทะฐ ัะตะฒะธะทะธัั
+CommitMessage=ะ ะตะฒะธะทะฝะธ ัะตะบัั
+CommitChoice=ะะทะฑะพั ัะตะฒะธะทะธัะต
+TreeName=ะัั ะดะพ ะดะฐัะพัะตะบะต
+Content=ะกะฐะดัะถะฐั
+
+
+require_error=` ะฝะต ะผะพะถะต ะฑะธัะธ ะฟัะฐะทะฝะพ.`
+size_error=` ะผะพัะฐ ะฑะธัะธ ะฒะตะปะธัะธะฝะต %s.`
+min_size_error=` ะผะพัะฐ ะดะฐ ัะฐะดัะถะธ ะฝะฐัะผะฐัะต %s ะบะฐัะฐะบัะตัะฐ.`
+max_size_error=` ะผะพัะฐ ะดะฐ ัะฐะดัะถะธ ะฝะฐัะฒะธัะต %s ะบะฐัะฐะบัะตัะฐ.`
+email_error=` ะฝะธัะต ะฒะฐะถะตัะฐ ะฐะดัะตัะฐ ะต-ะฟะพััะต.`
+url_error=` ะฝะธัะต ะธัะฟัะฐะฒะฝะฐ URL ะฐะดัะตัะฐ.`
+include_error=` ะผะพัะฐ ะดะฐ ัะฐะดัะถะธ ัะตะบัั '%s'.`
+unknown_error=ะะตะฟะพะทะฝะฐัะฐ ะณัะตัะบะฐ:
+
+
+auth_failed=ะัะตัะบะฐ ะธะดะตะฝัะธัะตัะฐ: %v
+
+
+target_branch_not_exist=ะะฒะฐ ะณัะฐะฝะฐ ะฝะต ะฟะพััะพัะธ.
+
+[user]
+join_on=ะ ะตะณะธัััะธัะฐะฝ
+repositories=ะกะฟัะตะผะธััะฐ
+activity=ะะบัะธะฒะฝะพััะธ
+followers=ะัะฐัะธะพัะธ
+following=ะัะฐัะธะผ
+follow=ะัะฐัะธ
+unfollow=ะัะตััะฐะฝะธ ะดะฐ ะฟัะฐัะธั
+
+
+[settings]
+profile=ะัะพัะธะป
+password=ะะพะทะธะฝะบะฐ
+avatar=ะะฒะฐัะฐั
+social=ะะฐะปะพะทะธ ะฝะฐ ะดััััะฒะตะฝะธะผ ะผัะตะถะฐะผะฐ
+delete=ะฃะบะปะพะฝะธัะต ะฝะฐะปะพะณ
+
+public_profile=ะะฐะฒะฝะธ ะฟัะพัะธะป
+full_name=ะะผะต ะธ ะฟัะตะทะธะผะต
+website=ะะตะฑ ัััะฐะฝะธัะฐ
+location=ะะพะบะฐัะธัะฐ
+update_profile=ะะถััะธัะฐั ะฟัะพัะธะป
+continue=ะะฐััะฐะฒะธ
+cancel=ะัะบะฐะถะธ
+
+federated_avatar_lookup=Federated Avatar ะฟัะตััะฐะณะฐ
+enable_custom_avatar=ะฃะบัััะธ ะฒะฐั ะฐะฒะฐัะฐั
+choose_new_avatar=ะะทะฐะฑะตัะธัะต ะฝะพะฒะธ ะฐะฒะฐัะฐั
+delete_current_avatar=ะะฑัะธัะธัะต ััะตะฝััะฝะธ ะฐะฒะฐัะฐั
+
+old_password=ะขัะตะฝััะฝะฐ ะปะพะทะธะฝะบะฐ
+new_password=ะะพะฒะฐ ะปะพะทะธะฝะบะฐ
+
+emails=ะะดัะตัะฐ ะตะป. ะฟะพััะต
+email_desc=ะะฐัะฐ ะณะปะฐะฒะฝะฐ ะฐะดัะตัะฐ ัะต ัะต ะบะพัะธััะธัะธ ะทะฐ ะพะฑะฐะฒะตััะตัะฐ ะธ ะดััะณะธั
ะพะฟะตัะฐัะธัะฐ.
+primary=ะะปะฐะฒะฝะพ
+
+manage_ssh_keys=ะฃะฟัะฐะฒัะฐัะต SSH ะบัััะตะฒะฐ
+add_key=ะะพะดะฐั ะบััั
+add_new_key=ะะพะดะฐั SSH ะบััั
+key_name=ะะผะต ะบัััะฐ
+key_content=ะกะฐะดัะถะฐั
+add_on=ะะพะดะฐัะพ
+last_used=ะะฐะดัะต ะบะพััััะตะฝะพ
+no_activity=ะะตะผะฐ ะฝะตะดะฐะฒะฝะธั
ะฐะบัะธะฒะฝะพััะธ
+manage_social=ะฃะฟัะฐะฒัะฐัะต ะฟัะธะบัััะตะฝะธั
ะดััััะฒะตะฝะธะผ ะผัะตะถะฐะผะฐ
+
+generate_new_token=ะะตะฝะตัะธัะธ ะฝะพะฒะธ ัะพะบะตะฝ
+token_name=ะะผะต ัะพะบะตะฝะฐ
+generate_token=ะะตะฝะตัะธัะธ ัะพะบะตะฝ
+delete_token=ะฃะบะปะพะฝะธ
+
+
+
+
+
+
+
+delete_account=ะฃะบะปะพะฝะธัะต ะฒะฐั ะฝะฐะปะพะณ
+confirm_delete_account=ะะพัะฒัะดะธัะต ะฑัะธัะฐัะต
+
+
+
+[repo]
+owner=ะะปะฐัะฝะธะบ
+repo_name=ะะผะต ัะฟัะตะผะธััะฐ
+visibility=ะะธะดัะธะฒะพัั
+fork_repo=ะัะตะธัะฐั ะพะณัะฐะฝะฐะบ ัะฟัะตะผะธััะฐ
+fork_from=ะะณัะฐะฝะฐะบ ะพะด
+repo_desc=ะะฟะธั
+repo_lang=ะะตะทะธะบ
+license=ะะธัะตะฝัะฐ
+create_repo=ะะพะฒะพ ัะฟัะตะผะธััะต
+default_branch=ะะปะฐะฒะฝะฐ ะณัะฐะฝะฐ
+mirror_prune=ะัะธััะธ
+watchers=ะะพัะผะฐััะฐัะธ
+stargazers=ะัะฐัะธะพัะธ
+forks=ะะณัะฐะฝัะธ
+
+
+
+
+
+
+migrate_repo=ะะธะณัะธัะฐััะต ัะฟัะตะผะธััะต
+migrate.permission_denied=ะะตะผะฐัะต ะฟัะฐะฒะฐ ะฝะฐ ัะฒะตะทะตัะต ะปะพะบะฐะปะฝะพ ัะฟัะตะผะธััะต.
+migrate.failed=ะะธะณัะฐัะธัะฐ ะฝะธัะต ััะฟะตะปะฐ: %v
+
+mirror_from=ะพะณะปะตะดะฐะปะพ ะพะด
+forked_from=ะธะทะดะฐะฝะฐะบ ะพะด
+unwatch=ะัะตััะฐะฝะธ ะฟัะฐัะธัะธ
+watch=ะัะฐัะธ
+unstar=ะฃะปะบะพะฝะธ ะทะฒะตะทะดั
+star=ะะพะปะธะผ
+fork=ะัะตะธัะฐั ะพะณัะฐะฝะฐะบ
+
+no_desc=ะะตะผะฐ ะพะฟะธัะฐ
+quick_guide=ะัะฐัะฐะบ ะฒะพะดะธั
+clone_this_repo=ะะปะพะฝะธัะฐั ัะฟัะตะผะธััะต
+
+code=ะะพะด
+branch=ะัะฐะฝะฐ
+tree=ะัะฒะพ
+filter_branch_and_tag=ะัะพัะธะปััะธัะฐั ะฟะพ ะณัะฐะฝะธ ะธะปะธ ะพะทะฝะฐัะธ
+branches=ะัะฐะฝะต
+tags=ะะทะฝะฐะบะต
+issues=ะะธัะบััะธัะต
+pulls=ะะฐั
ัะตะฒะธ ะทะฐ ัะฟะฐัะฐัะต
+labels=ะะฐะฑะตะปะต
+
+milestones=ะคะฐะทะต
+commits=ะะพะผะธัะธ
+releases=ะะทะดะฐัะฐ
+file_raw=ะะฐัะพัะตะบะฐ
+file_history=ะััะพัะธัะฐ
+file_view_raw=ะัะตะณะปะตะดะฐั ัะฐะผั ะดะฐัะพัะตะบั
+file_permalink=ะะตัะผะฐะปะธะฝะบ
+
+
+editor.preview_changes=ะัะตะณะปะตะด ะฟัะพะผะตะฝะฐ
+editor.or=ะธะปะธ
+editor.commit_changes=ะะทะฒััะธ ะบะพะผะธั ะฟัะพะผะตะฝะฐ
+editor.add=ะะพะดะฐั '%s'
+editor.update=ะะถััะธัะฐั '%s'
+editor.delete=ะฃะบะปะพะฝะธ '%s'
+editor.commit_directly_to_this_branch=ะะทะฒััะธ ะบะพะผะธั ะดะธัะตะบัะฝะพ ะฝะฐ %[1]s ะณัะฐะฝั.
+editor.create_new_branch=ะัะตะธัะฐั ะฝะพะฒั ะณัะฐะฝั ะทะฐ ะพะฒะฐั ะบะพะผะธั ะธ ะฟะพะดะฝะตัะธ ะทะฐั
ัะตะฒ ะทะฐ ัะฟะฐัะฐัะต.
+editor.cancel=ะัะบะฐะถะธ
+editor.branch_already_exists=ะัะฐะฝะฐ '%s' ะฒะตั ะฟะพััะพัะธ ะทะฐ ะพะฒะพ ัะฟัะตะผะธััะต.
+editor.no_changes_to_show=ะะตะผะฐ ะฝะธะบะฐะบะฒะธั
ะฟัะพะผะตะฝะฐ.
+editor.unable_to_upload_files=ะฃัะธัะฐัะต ะดะฐัะพัะตะบะต '%s' ะฝะธัะต ััะฟะตะปะพ ัะฐ ะณัะตัะบะฝะพะผ: %v
+editor.upload_files_to_dir=ะะพัะฐัะธ ะดะฐัะพัะตะบะต ะฝะฐ '%s'
+
+commits.commits=ะะพะผะธัะธ
+commits.author=ะััะพั
+commits.message=ะะพััะบะฐ
+commits.date=ะะฐััะผ
+commits.older=ะกัะฐัะธัะต
+commits.newer=ะะพะฒะธัะต
+
+
+
+issues.new=ะะพะฒะธ ะทะฐะดะฐัะฐะบ
+issues.new.labels=ะะฐะฒะตะปะต
+issues.new.no_label=ะะตะผะฐ ะปะฐะฑะตะปะต
+issues.new.clear_labels=ะฃะบะปะพะฝะธ ะปะฐะฑะตะปะต
+issues.new.milestone=ะคะฐะทะฐ
+issues.new.no_milestone=ะะตะผะฐ ัะฐะทะต
+issues.new.clear_milestone=ะฃะบะปะพะฝะธ ัะฐะทั
+issues.new.open_milestone=ะัะฒะพัะตะฝะต ัะฐะทะต
+issues.new.closed_milestone=ะะฐัะฒะพัะตะฝะต ัะฐะทะต
+issues.create=ะะพะดะฐั ะทะฐะดะฐัะฐะบ
+issues.new_label=ะะพะฒะฐ ะปะฐะฑะตะปะฐ
+issues.create_label=ะัะตะธัะฐั ะปะฐะฑะตะปั
+issues.label_templates.title=ะัะตัะทะผะธัะต ัะฝะฐะฟัะตะด ะดะตัะธะฝะธัะฐะฝะธ ัะบัะฟ ะปะฐะฑะตะปะฐ
+issues.label_templates.helper=ะะทะฐะฑะตัะธัะต ัะบัะฟ ะปะฐะฑะตะปะฐ
+issues.label_templates.fail_to_load_file=ะะธัะต ะผะพะณััะต ะฟัะตัะทะตัะธ ะดะฐัะพัะตะบั '%s': %v
+issues.open_tab=%d ะพัะฒะพัะตะฝะพ
+issues.close_tab=%d ะทะฐัะฒะพัะตะฝะพ
+issues.filter_label=ะะฐะฑะตะปะฐ
+issues.filter_milestone=ะคะฐะทะฐ
+issues.filter_assignee=ะะดะณะพะฒะพัะฝะธ
+issues.filter_type=ะขะธะฟ
+issues.filter_type.all_issues=ะกะฒะธ ะทะฐะดะฐัะธ
+issues.filter_type.assigned_to_you=ะะฐะบะฐะทะฐะฝะพ ะฒะฐะผะฐ
+issues.filter_type.created_by_you=ะบัะตะธัะฐะฝะพ ะพะด ะฒะฐั
+issues.filter_type.mentioning_you=ะะพะผะตัััะต ะฒะฐั
+issues.filter_sort=ะกะพััะธัะฐั
+issues.filter_sort.latest=ะะฐัะฝะพะฒะธัะต
+issues.filter_sort.oldest=ะะฐัััะฐัะธัะต
+issues.filter_sort.recentupdate=ะะตะดะฐะฒะฝะพ ะฐะถััะธัะฐะฝะพ
+issues.filter_sort.leastupdate=ะะฐะฒะฝะพ ะฐะถััะธะฐะฝะพ
+issues.filter_sort.mostcomment=ะะฐัะฒะธัะต ะบะพะผะตะฝัะฐัะฐ
+issues.filter_sort.leastcomment=ะะฐัะผะฐัะต ะบะพะผะตะฝัะฐัะฐ
+issues.opened_by=ะพัะฒะพัะตะฝะพ %[1]s ะพะด %[3]s
+issues.previous=ะัะตัั
ะพะดะฝะฐ
+issues.next=ะกะปะตะดะตัะต
+issues.open_title=ะัะฒะพัะตะฝะพ
+issues.closed_title=ะะฐัะฒะพัะตะฝะพ
+issues.num_comments=%d ะบะพะผะตะฝัะฐัะฐ
+issues.commented_at=`ะบะพะผะตะฝัะธัะธัะฐ %s `
+issues.delete_comment_confirm=ะะฐ ะปะธ ะถะตะปะธัะต ะดะฐ ะธะทะฑัะธัะตัะต ะพะฒะฐั ะบะพะผะตะฝัะฐั?
+issues.no_content=ะะพั ะฝะตะผะฐ ัะฐะดัะถะฐัะฐ.
+issues.close_issue=ะะฐัะฒะพัะธ
+issues.reopen_issue=ะะพะฝะพะฒะพ ะพัะฒะพัะธ
+issues.create_comment=ะะพะผะตะฝัะธัะฐั
+issues.commit_ref_at=`ะฟะพะผะตะฝัะพ ะพะฒะฐั ะทะฐะดะฐัะฐะบ ั ะบะพะผะธั %[2]s `
+issues.poster=ะััะพั
+issues.collaborator=ะะพะฐััะพั
+issues.owner=ะะปะฐัะฝะธะบ
+issues.sign_in_require_desc=ะัะธัะฐะฒะธัะต ัะต ะดะฐ ัะต ะฟัะธะบัััะต ั ะพะฒะพะผ ัะฐะทะณะพะฒะพัั.
+issues.edit=ะฃัะตะดะธ
+issues.cancel=ะัะบะฐะถะธ
+issues.save=ะกะฐััะฒะฐั
+issues.label_title=ะะผะต ะปะฐะฑะตะปะต
+issues.label_color=ะะพัะฐ ะปะฐะฑะตะปะต
+issues.label_count=%d ะปะฐะฑะตะปะฐ
+issues.label_open_issues=%d ะพัะฒะพัะตะฝะธั
ะทะฐะดะฐัะฐะบะฐ
+issues.label_edit=ะฃัะตะดะธ
+issues.label_delete=ะฃะบะปะพะฝะธ
+issues.num_participants=%d ััะตัะฝะธะบะฐ
+issues.attachment.open_tab=`ะะปะธะบะฝะธัะต "%s" ะดะฐ ะฒะธะดะธัะต ั ะฝะพะฒะพะผ ะฟัะพะทะพัั`
+issues.attachment.download=`ะะปะธะบะฝะธัะต ะดะฐ ะฟัะตัะทะผะตัะต "%s"`
+
+
+pulls.new=ะะพะฒะธ ะทะฐั
ัะตะฒ ะทะฐ ัะฟะฐัะฐัะต
+pulls.filter_branch=ะคะธะปัะตั ะฟะพ ะณัะฐะฝะธ
+pulls.no_results=ะะตะผะฐ ัะตะทัะปัะฐัะฐ.
+pulls.create=ะะพะดะฝะตัะธ ะทะฐั
ัะตะฒ ะทะฐ ัะฟะฐัะฐัะต
+pulls.merged_title_desc=ัะฟะพัะธ(ะปะฐ) %[1]d ะบะพะผะธั(ะต) ะธะท %[2]s
ั %[3]s
%[4]s
+pulls.tab_conversation=ะะธัะบััะธัะฐ
+pulls.tab_commits=ะะพะผะธัะธ
+pulls.merged=ะกะฟะพัะตะฝะพ
+pulls.can_auto_merge_desc=ะะฒะฐั ะทะฐั
ัะตะฒ ะทะฐ ัะฟะฐัะฐัะต ะผะพะถะต ะฑะธัะธ ะพะฑะฐะฒัะตะฝ ะฐััะพะผะฐััะบะธ.
+
+milestones.new=ะะพะฒะฐ ัะฐะทะฐ
+milestones.open_tab=%d ะพัะฒะพัะตะฝะพ
+milestones.close_tab=%d ะทะฐัะฒะพัะตะฝะพ
+milestones.closed=ะะฐัะฒะพัะตะฝะพ %s
+milestones.no_due_date=ะ ะพะบ ะฝะธัะต ะฝะฐะฒะตะดะตะฝ
+milestones.open=ะัะฒะพัะธ
+milestones.close=ะะฐัะฒะพัะธ
+milestones.create=ะัะตะธัะฐั ัะฐะทั
+milestones.title=ะะฐัะปะพะฒ
+milestones.desc=ะะฟะธั
+milestones.due_date=ะะฐััะผ ะทะฐะฒััะตัะบะฐ (ะพะฟัะธะพะฝะพ)
+milestones.clear=ะฃะบะปะพะฝะธ
+milestones.edit=ะะถััะธัะฐั ัะฐะทั
+milestones.cancel=ะัะบะฐะถะธ
+
+
+
+wiki=ะะธะบะธ
+wiki.page=ะกััะฐะฝะธัะฐ
+wiki.filter_page=ะคะธะปัะตั ัััะฐะฝะธัะต
+wiki.save_page=ะกะฐััะฒะฐั ัััะฐะฝะธัั
+wiki.last_commit_info=%s ััะตัะธะฒะฐะพ ะพะฒั ัััะฐะฝะธัั %s
+wiki.edit_page_button=ะฃัะตะดะธ
+wiki.new_page_button=ะะพะฒะฐ ัััะฐะฝะธัะฐ
+wiki.delete_page_button=ะฃะบะปะพะฝะธ ัััะฐะฝะธัั
+wiki.page_already_exists=ะกััะฐะฝะธัะฐ ัะฐ ะพะฒะธะผ ะธะผะตะฝะพะผ ะฒะตั ะฟะพััะพัะธ.
+wiki.pages=ะกััะฐะฝะธัะต
+wiki.last_updated=ะะพัะปะตะดัะต ะฐะถััะธัะฐะฝะพ %s
+
+
+
+settings=ะะพะดะตัะฐะฒะฐัะฐ
+settings.collaboration.write=ะะฐ ะฟะธัะฐัะต
+settings.collaboration.read=ะงะธัะฐัะต
+settings.collaboration.undefined=ะะธัะต ะดะตัะธะฝะธัะฐะฝะพ
+settings.githooks=Git ั
ัะบะธ
+settings.basic_settings=ะัะฝะพะฒะฝะฐ ะฟะพะดะตัะฐะฒะฐัะฐ
+settings.mirror_settings=ะะพะดะตัะฐะฒะฐัะฐ ะพะณะปะตะดะฐะปะฐ
+settings.update_settings=ะัะธะผะตะฝะธ ะฟัะพะผะตะฝะต
+settings.advanced_settings=ะะฐะฟัะตะดะฝะฐ ะฟะพะดะตัะฐะฒะฐัะฐ
+settings.external_wiki_url=URL ะฐะดัะตัะฐ ัะฟะพัะฝะพะณ ะะธะบะธ
+settings.tracker_url_format=ะกะฟะพัะฝะธ ัะพัะผะฐั ะฒะตะทะต ัะธััะตะผะฐ ะทะฐ ะฟัะฐัะตัะต ะณัะตัะฐะบะฐ
+settings.tracker_issue_style.numeric=ะัะผะตัะธัะฝะพ
+settings.tracker_issue_style.alphanumeric=ะะปัะฐะฝัะผะตัะธัะฝะพ
+settings.danger_zone=ะะฟะฐัะฝะฐ ะทะพะฝะฐ
+settings.new_owner_has_same_repo=ะะพะฒะธ ะฒะปะฐัะฝะธะบ ะฒะตั ะธะผะฐ ัะฟัะตะผะธััะต ะฟะพ ะธััะธะผ ะฝะฐะทะธะฒะพะผ. ะะพะปะธะผะพ ะฒะฐั ะธะทะฐะฑะตัะธัะต ะดััะณะพ ะธะผะต.
+settings.transfer=ะัะตะฝะตัะธ ะฒะปะฐัะฝะธััะฒะพ
+settings.transfer_owner=ะะพะฒะธ ะฒะปะฐัะฝะธะบ
+settings.delete=ะฃะบะปะพะฝะธ ะพะฒะพ ัะฟัะตะผะธััะต
+settings.delete_notices_1=- ะะฒะฐ ะพะฟะตัะฐัะธัะฐ ะะะะ ะะะงะ ะฑะธัะธ ัะบะธะฝััะฐ.
+settings.add_webhook=ะะพะดะฐั Webhook
+settings.webhook.test_delivery=ะัะพะฒะตัะธ ะธัะฟะพััะบั
+settings.webhook.request=ะะฐั
ัะตะฒ
+settings.webhook.response=ะะดะณะพะฒะพั
+settings.webhook.headers=ะะฐัะปะพะฒะธ
+settings.webhook.body=ะขะตะปะพ
+settings.githook_edit_desc=Aะบะพ Webhook ะฝะธัะต ะฐะบัะธะฒะฐะฝ, ะฟัะธะผะตัะฝะธ ัะฐะดัะถะฐั ัะต ะฑะธัะธ ะฟัะตะดััะฐะฒัะตะฝ. ะะบะพ ะพััะฐะฒะธัะต ะฟัะฐะทะฝะพ, Webhook ัะต ะฑะธัะธ ะพะฝะตะผะพะณััะตะฝ.
+settings.githook_name=ะะผะต Hook-ะฐ
+settings.githook_content=ะกะฐะดัะถะฐั Hook-ะฐ
+settings.update_githook=ะะถััะธัะฐั Hook
+settings.secret=ะขะฐัะฝะฐ
+settings.slack_username=ะะพัะธัะฝะธัะบะพ ะธะผะต
+settings.slack_icon_url=URL ะฐะดัะตัะฐ ะธะบะพะฝะธัะต
+settings.event_create=ะัะตะธัะฐั
+settings.event_pull_request=ะะฐั
ัะตะฒ ะทะฐ ัะฟะฐัะฐัะต
+settings.update_webhook=ะะถััะธัะฐั Webhook
+settings.recent_deliveries=ะะตะดะฐะฒะฝะต ะธัะฟะพััะบะต
+settings.hook_type=ะขะธะฟ Hook-ะฐ
+settings.slack_token=ะขะพะบะตะฝ
+settings.slack_domain=ะะพะผะตะฝ
+settings.slack_channel=ะะฐะฝะฐะป
+settings.deploy_keys=ะัััะตะฒะธ ะทะฐ ัะฐัะฟะพัะตัะธะฒะฐัะต
+settings.add_deploy_key=ะะพะดะฐั ะบััั ะทะฐ ัะฐัะฟะพัะตัะธะฒะฐัะต
+settings.title=ะะฐัะปะพะฒ
+settings.deploy_key_content=ะกะฐะดัะถะฐั
+
+diff.browse_source=ะัะตะณะปะตะด ะธะทะฒะพัะฝะธ ะบะพะดะฐ
+diff.parent=ัะพะดะธัะตั
+diff.commit=ะบะพะผะธั
+diff.show_split_view=ะะพะดะตัะตะฝ ะฟะพะณะปะตะด
+diff.show_unified_view=ะะตะดะฐะฝ ะฟะพะณะปะตะด
+diff.stats_desc= %d ะธะทะผะตัะตะฝะธั
ัะฐัะปะพะฒะฐ ัะฐ %d ะดะพะดะฐัะพ ะธ %d ัะบะปะพัะตะฝะพ
+diff.view_file=ะัะตะณะปะตะดะฐั ะดะฐัะพัะตะบั
+diff.file_suppressed=ะ ะฐะทะปะธะบะฐ ะธะทะผะตัั ะดะฐัะพัะตะบะต ะฝะธัะต ะฟัะธะบะฐะทะฐะฝ ะทะฑะพะณ ัะฒะพัะต ะฒะตะปะธะบะต ะฒะตะปะธัะธะฝะต
+
+release.releases=ะะทะดะฐัะฐ
+release.new_release=ะะพะฒะพ ะธะทะดะฐัะต
+release.draft=ะะฐััั
+release.prerelease=ะัะตะด-ะฒะตัะทะธัะฐ
+release.stable=ะกัะฐะฑะธะปะฝะพ
+release.edit=ััะตะดะธ
+release.source_code=ะะทะฒะพัะฝะธ ะบะพะด
+release.tag_name=ะะผะต ะพะทะฝะฐะบะต
+release.target=ะฆะธั
+release.title=ะะฐัะปะพะฒ
+release.content=ะกะฐะดัะถะฐั
+release.cancel=ะัะบะฐะถะธ
+release.publish=ะะฑัะฐะฒะธ ะธะทะดะฐัะต
+release.save_draft=ะกะฐััะฒะฐั ะฝะฐััั
+release.downloads=ะัะตัะทะธะผะฐัะฐ
+
+
+
+
+
+[org]
+org_name_holder=ะะผะต ะพัะณะฐะฝะธะทะฐัะธัะต
+org_full_name_holder=ะัะฝ ะฝะฐะทะธะฒ ะพัะณะฐะฝะธะทะฐัะธัะต
+create_org=ะกัะฒะพัะธ ะัะณะฐะฝะธะทะฐัะธัั
+repo_updated=ะะถััะธัะฐะฝะพ
+people=ะัะพะฑะต
+teams=ะขะธะผะพะฒะธ
+lower_members=ัะปะฐะฝะพะฒะธ
+lower_repositories=ัะฟัะตะผะธััะฐ
+org_desc=ะะฟะธั
+team_name=ะะผะต ัะธะผะฐ
+team_desc=ะะฟะธั
+
+
+settings=ะะพะดะตัะฐะฒะฐัะฐ
+settings.full_name=ะัะฝะพ ะธะผะต
+settings.website=ะกะฐะธั
+settings.location=ะะพะบะฐัะธัะฐ
+
+settings.update_settings=ะะถััะธัะฐั ะฟะพะดะตัะฐะฒะฐัะฐ
+settings.delete=ะฃะบะปะพะฝะธ ะพัะณะฐะฝะธะทะฐัะธัั
+settings.delete_account=ะฃะบะปะพะฝะธ ะพะฒั ะพัะณะฐะฝะธะทะฐัะธัั
+settings.confirm_delete_account=ะะพัะฒัะดะธ ะฑัะธัะฐัะต
+
+
+members.membership_visibility=ะะธะดัะธะฒะพัั:
+members.member_role=ะฃะปะพะณะฐ ััะตัะฝะธะบะฐ:
+members.owner=ะะปะฐัะฝะธะบ
+members.member=ะงะปะฐะฝ
+members.remove=ะฃะบะปะพะฝะธ
+members.leave=ะะทะฐัะธ
+members.invite_desc=ะะพะดัะฐ ะฝะพะฒะพะณ ัะปะฐะฝะฐ %s:
+members.invite_now=ะะพะทะพะฒะธัะต ัะฐะดะฐ
+
+teams.join=ะัะธะดััะถะธ ัะต
+teams.leave=ะะทะฐัะธ
+teams.no_desc=ะะฒะฐั ัะธะผ ะฝะตะผะฐ ะพะฟะธัะฐ
+teams.settings=ะะพะดะตัะฐะฒะฐัะฐ
+teams.members=ะงะปะฐะฝะพะฒะธ ัะธะผะฐ
+teams.update_settings=ะัะธะผะตะฝะธ ะฟัะพะผะตะฝะต
+teams.add_team_member=ะะพะดะฐั ัะปะฐะฝ ัะธะผั
+teams.repositories=ะขะธะผัะบะฐ ัะฟัะตะผะธััะฐ
+teams.add_nonexistent_repo=ะะฒะฐะบะฒะพ ัะฟัะตะผะธััะต ะฝะต ะฟะพััะพัะธ, ะผะพะปะธะผ ะฒะฐั ะฟัะฒะพ ะดะฐ ะณะฐ ะฝะฐะฟัะฐะฒะธัะต.
+
+[admin]
+dashboard=ะะพะฝััะพะปะฝะธ ะฟะฐะฝะตะป
+organizations=ะัะณะฐะฝะธะทะฐัะธัะต
+repositories=ะกะฟัะตะผะธััะฐ
+config=ะะพะดะตัะฐะฒะฐัะฐ
+notices=ะกะธััะตะผัะบะฐ ะพะฑะฐะฒะตััะตัะฐ
+monitor=ะัะฐัะตัะต
+first_page=ะัะฒะธ
+last_page=ะะพัะปะตะดัะธ
+total=ะฃะบัะฟะฝะพ: %d
+
+dashboard.operation_name=ะะผะต ะพะฟะตัะฐัะธัะต
+dashboard.operation_switch=ะัะตะฑะฐัะธ
+dashboard.operation_run=ะะพะบัะตะฝะธ
+dashboard.server_uptime=ะัะตะผะต ะฝะตะฟัะตะบะธะดะฝะพะณ ัะฐะดะฐ ัะตัะฒะตัะฐ
+dashboard.current_goroutine=ะขัะตะฝััะฝe Goroutine
+dashboard.current_memory_usage=ะขัะตะฝััะฝะฐ ัะฟะพััะตะฑะฐ ะผะตะผะพัะธัะต
+dashboard.total_memory_allocated=ะฃะบัะฟะฝะพ ะผะตะผะพัะธัะต ะฐะปะพัะธัะฐะฝะพ
+dashboard.memory_obtained=ะะพัะธััะตะฝะฐ ะผะตะผะพัะธัะฐ
+dashboard.pointer_lookup_times=ะะฐั
ัะตะฒะฐ ะฟะพะบะฐะทะธะฒะฐัะฐ
+dashboard.current_heap_usage=ะขัะตะฝััะฝะฐ ัะฟะพััะตะฑะฐ ะดะธะฝะฐะผะธัะบะต ะผะตะผะพัะธัะต
+dashboard.heap_memory_obtained=ะกะปะพะฑะพะดะฝะพ ะดะธะฝะฐะผะธัะบะต ะผะตะผะพัะธัะต
+dashboard.heap_memory_idle=ะะตะฐะบัะธะฒะพ ะดะธะฝะฐะผะธัะบะต ะผะตะผะพัะธัะต
+dashboard.heap_memory_in_use=ะะธะฝะฐะผะธัะบะฐ ะผะตะผะพัะธัะฐ ั ัะฟะพััะตะฑะธ
+dashboard.heap_memory_released=ะัะปะพะฑะพัะตะฝะพ ะดะธะฝะฐะผะธัะบะต ะผะตะผะพัะธัะต
+dashboard.heap_objects=ะะฑัะตะบัะธ ะดะธะฝะฐะผะธัะบะต ะผะตะผะพัะธัะต
+dashboard.bootstrap_stack_usage=ะะพัะธััะตัะต ััะตะบ ะผะตะผะพัะธัะต
+dashboard.stack_memory_obtained=ะกะปะพะฑะพะดะฝะพ ััะตะบ ะผะตะผะพัะธัะต
+dashboard.mspan_structures_usage=ะฃะฟะพััะตะฑะฐ ััััะบัััะต MSpan
+dashboard.mspan_structures_obtained=ะะพะฑะธัะตะฝะพ ััััะบัััะต MSpan
+dashboard.mcache_structures_usage=ะฃะฟะพััะตะฑะฐ ััััะบัััa MCache
+dashboard.mcache_structures_obtained=ะะพะฑะธัะตะฝะพ ััััะบัััa MCache
+dashboard.profiling_bucket_hash_table_obtained=ะฅะตั-ัะฐะฑะปะตะฐ ะฟะพััะธะณะฝััะพ ะทะฐ Profiling Bucket
+dashboard.gc_metadata_obtained=ะะพะฑะธัะตะฝะธั
ะผะตัะฐะฟะพะดะฐัะฐะบะฐ cะฐะบัะฟัะฐัั ัะผะตัะฐ
+dashboard.other_system_allocation_obtained=ะะพะฑะธัะตะฝะพ ะดััะณะฐ ัะธััะตะผัะบะฐ ะผะตะผะพัะธัะฐ
+dashboard.next_gc_recycle=ะกะปะตะดะตัะฐ ัะตัะธะบะปะฐะถะฐ cะฐะบัะฟัะฐัั ัะผะตัะฐ
+dashboard.last_gc_time=ะัะตะผะตะฝะฐ ะพะด ะฟัะพัะปะพะณ cะฐะบัะฟัะฐัั ัะผะตัะฐ
+dashboard.total_gc_time=ะฃะบัะฟะฝะพ ะฒัะตะผะต cะฐะบัะฟัะฐัั ัะผะตัะฐ
+dashboard.total_gc_pause=ะฃะบัะฟะฝะพ ะฒัะตะผะต cะฐะบัะฟัะฐัั ัะผะตัะฐ
+dashboard.last_gc_pause=ะะฐะดัะฐ ะฟะฐัะทะฐ ั cะฐะบัะฟัะฐัั ัะผะตัะฐ
+dashboard.gc_times=ะัะตะผะตะฝะฐ cะฐะบัะฟัะฐัั ัะผะตัะฐ
+
+users.activated=ะะบัะธะฒะธัะฐะฝ
+users.admin=ะะดะผะธะฝะธัััะฐัะพั
+users.repos=ะกะฟัะตะผะธััะฐ
+users.created=ะัะตะธัะฐะฝะพ
+users.edit=ะฃัะตะดะธ
+users.auth_source=ะะทะฒะพั ะฐััะตะฝัะธะบะฐัะธัะต
+users.local=ะะพะบะฐะปะฝะพ
+
+
+orgs.name=ะะผะต
+orgs.teams=ะขะธะผะพะฒะธ
+orgs.members=ะงะปะฐะฝะพะฒะธ
+
+repos.owner=ะะปะฐัะฝะธะบ
+repos.name=ะะผะต
+repos.private=ะัะธะฒะฐัะฝะพ
+repos.stars=ะคะฐะฒะพัะธัะธ
+repos.issues=ะะฐะดะฐัะธ
+
+
+
+auths.name=ะะผะต
+auths.type=ะขะธะฟ
+auths.enabled=ะะผะพะณััะตะฝะพ
+auths.updated=ะะถััะธัะฐะฝะพ
+auths.auth_type=ะัััะฐ ะฟัะพะฒะตัะต ะฐััะตะฝัะธัะฝะพััะธ
+auths.auth_name=ะะผะต ะฟัะพะฒะตัะต ะฐััะตะฝัะธัะฝะพััะธ
+auths.security_protocol=ะัะพัะพะบะพะป ะฑะตะทะฑะตะดะฝะพััะธ
+auths.domain=ะะพะผะตะฝ
+auths.host=ะฅะพัั
+auths.port=ะะพัั
+auths.bind_password=Bind ะปะพะทะธะฝะบa
+auths.user_base=ะะฐะทะฐ ะฟัะตััะฐะถะธะฒะฐัะต ะบะพัะธัะฝะธะบะฐ
+auths.user_dn=DN ะบะพัะธัะฝะธะบะฐ
+auths.filter=ะคะธะปัะตั ะบะพัะธัะฝะธะบะฐ
+auths.admin_filter=ะคะธะปัะตั ะฐะดะผะธะฝะธัััะฐัะพัะฐ
+auths.smtp_auth=ะขะธะฟ SMTP ะฐััะตะฝัะธะบะฐัะธัะต
+auths.smtphost=SMTP ั
ะพัั
+auths.smtpport=SMTP ะฟะพัั
+auths.allowed_domains=ะะพะทะฒะพัะตะฝะธ ะดะพะผะตะฝะธ
+auths.skip_tls_verify=ะัะตัะบะพัะธ TLS ะฟัะพะฒะตัั
+auths.pam_service_name=ะะฐะทะธะฒ PAM ัะตัะฒะธัะฐ
+auths.enable_auto_register=ะะผะพะณััะธ ะฐััะพะผะฐััะบั ัะตะณะธัััะฐัะธัั
+auths.tips=ะกะฐะฒะตัะธ
+
+config.server_config=ะะพะฝัะธะณััะฐัะธัะฐ ัะตัะฒะตัะฐ
+config.disable_router_log=ะะฝะตะผะพะณััะธ ะถััะฝะฐะป ัััะตัะฐ
+config.run_mode=ะ ะตะถะธะผ ะธะทะฒััะฐะฒะฐัะฐ
+config.repo_root_path=ะัั ะดะพ ะบะพัะตะฝะฐ ัะฟัะตะผะธััะฐ
+config.static_file_root_path=ะัั ะดะพ ััะฐัะธัะบะต ะดะฐัะพัะตะบะต
+config.script_type=ะัััะฐ ัะบัะธะฟัะฐ
+config.reverse_auth_user=ะะพัะธัะฝะธัะบะพ ะธะผะต ะฟัะธ ะพะฑัะฝััั ะฐััะตะฝัะธะบะฐัะธัั
+
+config.ssh_config=SSH ะบะพะฝัะธะณััะฐัะธัะฐ
+config.ssh_enabled=ะะผะพะณััะตะฝะพ
+config.ssh_port=ะะพัั
+config.ssh_listen_port=ะะพัั ะทะฐ ัะปััะฐัะต
+config.ssh_root_path=ะัะฝะพะฒะฝะธ ะฟัั
+config.ssh_key_test_path=ะัั ะดะพ ะบัััั
+config.ssh_keygen_path=ะัั ะดะพ ะณะตะฝะตัะฐัะพั ะบัััะตะฒะฐ ('ssh-keygen')
+config.ssh_minimum_key_size_check=ะะธะฝะธะผะฐะปะฝะฐ ะฒะตะปะธัะธะฝะฐ ะฟัะพะฒะตัะฐ ะบัััะฐ
+config.ssh_minimum_key_sizes=ะะธะฝะธะผะฐะปะฝะฐ ะฒะตะปะธัะธะฝะฐ ะบัััะตะฒะฐ
+
+
+config.db_config=ะะพะฝัะธะณััะฐัะธัะฐ ะฑะฐะทะต ะฟะพะดะฐัะฐะบะฐ
+config.db_type=ะขะธะฟ
+config.db_host=ะฅะพัั
+config.db_name=ะะผะต
+config.db_path=ะัั
+
+config.service_config=ะะพะดะตัะฐะฒะฐัะฐ ัะตัะฒะธัะฐ
+config.show_registration_button=ะัะธะบะฐะถะธ ะดัะณะผะต ะทะฐ ัะตะณะธัััะฐัะธัั
+config.disable_key_size_check=ะะฝะตะผะพะณััะธ ะฟัะพะฒะตัั ะฝะฐ ะผะธะฝะธะผะฐะปะฝะพั ะฒะตะปะธัะธะฝะธ ะบัััะฐ
+config.active_code_lives=ะัะถะธะฝะฐ ะถะธะฒะพัะฐ ะฐะบัะธะฒะฝะธั
ะบะพะดะพะฒะฐ
+
+config.webhook_config=ะะพะดะตัะฐะฒะฐัะฐ Webhook
+config.queue_length=ะัะถะธะฝะฐ ัะตะดะฐ
+config.deliver_timeout=ะัะตะผะต ะดะพ ะพัะบะฐะทะธะฒะฐัะต ัะปะฐัะฐ
+
+config.mailer_enabled=ะะผะพะณััะตะฝะพ
+config.mailer_disable_helo=ะะฝะตะผะพะณััะธ HELO
+config.mailer_name=ะะผะต
+config.mailer_host=ะฅะพัั
+config.mailer_user=ะะพัะธัะฝะธะบ
+
+config.oauth_config=ะะพะดะตัะฐะฒะฐัะฐ OAuth
+config.oauth_enabled=ะฃะบัััะตะฝะพ
+
+config.cache_config=ะะพะดะตัะฐะฒะฐัะฐ ะบะตัะฐ
+config.cache_adapter=ะะตั ะฐะดะฐะฟัะตั
+config.cache_interval=ะะตั ะธะฝัะตัะฒะฐะป
+config.cache_conn=ะะตั ะฝะฐ ะฒะตะทะธ
+
+config.session_config=ะะพะดะตัะฐะฒะฐัะฐ ัะตัะธัะต
+config.session_provider=ะะพะฑะฐะฒัะฐั ัะตัะธัะฐ
+config.provider_config=ะะพะฝัะธะณััะฐัะธัะฐ ะฝะฐ ะดะพะฑะฐะฒัะฐัั
+config.cookie_name=ะะผะต ะดะฐัะพัะตะบะต cookie
+config.gc_interval_time=ะะฝัะตัะฒะฐะป cะฐะบัะฟัะฐัะฐ ัะผะตัะฐ
+config.session_life_time=ะัะถะธะฝะฐ ะถะธะฒะพัะฐ ัะตััะธะต
+config.https_only=ะกะฐะผะพ HTTPS
+config.cookie_life_time=ะัะถะธะฝะฐ ะถะธะฒะพัะฐ ะดะฐัะพัะตะบะต cookie
+
+config.picture_service=ะฃัะปัะณะฐ ะทะฐ ัะปะธะบะต
+config.disable_gravatar=ะะฝะตะผะพะณััะธ Gravatar
+config.enable_federated_avatar=ะะผะพะณััะธ Federated Avatars
+
+config.git_config=Git ะบะพะฝัะธะณััะฐัะธัะฐ
+config.git_disable_diff_highlight=ะะฝะตะผะพะณััะธ ะฑะพัะตัะต ัะธะฝัะฐะบัะต ะบะฐะดะฐ ะณะปะตะดะฐัะต ัะฐะทะปะธะบะต
+config.git_max_diff_lines=ะะฐะบัะธะผะฐะปะฐะฝ ะฑัะพั ัะฐะทะปะธัะธัะธั
ัะตะดะพะฒะฐ (ั ะดะฐัะพัะตัะธ)
+config.git_max_diff_line_characters=ะะฐะบัะธะผะฐะปะฐะฝ ะฑัะพั ัะฐะทะปะธัะธัะธั
ะบะฐัะฐะบัะตัะฐ (ั ัะตะดั)
+config.git_max_diff_files=ะะฐะบัะธะผะฐะปะฐะฝ ะฑัะพั ะธะทะผะตัะตะฝะธั
ะดะฐัะพัะตะบะฐ (ะฟัะธะบะฐะทะฐะฝะธั
)
+config.git_gc_args=ะัะณัะผะตะฝัะธ ะฝะฐ cะฐะบัะฟัะฐัะต ัะผะตัะฐ
+config.git_migrate_timeout=ะัะตะผะต ะดะพ ะพัะบะฐะทะฐัะฐ ะผะธะณัะฐัะธัะต
+config.git_mirror_timeout=ะัะตะผะต ะดะพ ะพัะฐะทะฐัะต ัะธะฝั
ัะพะฝะธะทะฐัะธัะธ ะพะณะปะตะดะฐะปะฐ
+config.git_clone_timeout=ะัะตะผะต ะดะพ ะพัะบะฐะทะธะฒะฐัะฐ ะบะปะพะฝะธัะฐัะตะผ
+config.git_pull_timeout=ะัะตะผะต ะดะพ ะพัะบะฐะทะธะฒะฐัะฐ pull ะพะฟะตัะฐัะธัะธ
+config.git_gc_timeout=ะัะตะผะต ะดะพ ะพัะบะฐะทะธะฒะฐัะฐ cะฐะบัะฟัะฐัะต ัะผะตัะฐ
+
+config.log_config=Kะพะฝัะธะณััะฐัะธัะฐ ะถััะฝะฐะปะฐ
+config.log_mode=ะ ะตะถะธะผ ะถััะฝะฐะปะพะฒะฐัะฐ
+
+monitor.cron=Cron ะทะฐะดะฐัะธ
+monitor.name=ะะผะต
+monitor.schedule=ะ ะฐัะฟะพัะตะด
+monitor.next=ะกะปะตะดะตัะธ ะฟัั
+monitor.previous=ะัะตัั
ะพะดะฝะธ ะฟัั
+monitor.process=ะะพะบัะตะฝััะธ ะฟัะพัะตัะธ
+monitor.desc=ะะฟะธั
+monitor.start=ะะพัะตัะฝะพ ะฒัะตะผะต
+monitor.execute_time=ะัะตะผะต ะธะทะฒััะธะฒะฐัะฐ
+
+
+
+notices.system_notice_list=ะกะธััะตะผัะบะฐ ะพะฑะฐะฒะตััะฐะฒะฐัะฐ
+notices.actions=ะะบัะธัะต
+notices.select_all=ะะทะฐะฑะตัะธ ัะฒะต
+notices.deselect_all=ะฃะบะปะพะฝะธัะต ะธะทะฑะพั ัะฒะธั
+notices.inverse_selection=ะะฑัะฝะฐ ัะตะปะตะบัะธัะฐ
+notices.delete_selected=ะะทะฑัะธัะธ ะธะทะฐะฑัะฐะฝะต
+notices.delete_all=ะฃะบะปะพะฝะธ ัะฒะฐ ะพะฑะฐะฒะตััะตัะฐ
+notices.type=ะขะธะฟ
+notices.type_1=ะกะฟัะตะผะธััะต
+notices.desc=ะะฟะธั
+notices.op=Oะฟ.
+
+[action]
+create_repo=ะบัะตะธัะฐ ัะฟัะตะผะธััะต %s
+rename_repo=ะฟัะตะธะผะตะฝะทัะต ัะฟัะตะผะธััะต ะพะด %[1]s
ะฝะฐ %[3]s
+transfer_repo=ะฟัะตะฝะพัะธ ัะฟัะตะผะธััะต %s
ะฝะฐ %s
+
+[tool]
+ago=ะฟัะต %s
+from_now=ะพะด ัะฐะดะฐ %s
+now=ัะฐะดะฐ
+1s=1 ัะตะบัะฝะด
+1m=1 ะผะธะฝัั
+1h=1 ัะฐั
+1d=1 ะดะฐะฝ
+1w=1 ะฝะตะดะตัะฐ
+1mon=1 ะผะตัะตั
+1y=1 ะณะพะดะธะฝะฐ
+seconds=%d ัะตะบัะฝะดะธ
+minutes=%d ะผะธะฝััะฐ
+hours=%d ัะฐัะฐ
+days=%d ะดะฐะฝะฐ
+weeks=%d ะฝะตะดะตัะฐ
+months=%d ะผะตัะตัะธ
+years=%d ะณะพะดะธะฝะฐ
+raw_seconds=ัะตะบัะฝะดะธ
+raw_minutes=ะผะธะฝััะฐ
+
+[dropzone]
+remove_file=ะฃะบะปะพะฝะธ ะดะฐัะพัะตะบั
+
+[notification]
+
+[gpg]
+
+[units]
\ No newline at end of file
diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini
index 8e9727deef..23544b782b 100644
--- a/options/locale/locale_sv-SE.ini
+++ b/options/locale/locale_sv-SE.ini
@@ -16,7 +16,7 @@ template=Mall
language=Sprรฅk
notifications=Notiser
create_new=Skapaโฆ
-user_profile_and_more=Profil och Instรคllningarโฆ
+user_profile_and_more=Profil och instรคllningarโฆ
signed_in_as=Inloggad som
toc=Innehรฅllsfรถrteckning
licenses=Licenser
@@ -38,7 +38,7 @@ organization=Organisation
mirror=Spegel
new_repo=Ny utvecklingskatalog
new_migrate=Ny migrering
-new_mirror=Ny Spegling
+new_mirror=Ny spegling
new_fork=Ny fรถrgrening av utvecklingskatalog
new_org=Ny organisation
new_project=Nytt projekt
@@ -57,7 +57,7 @@ collaborative=Kollaborativa
forks=Forks
activities=Aktiviteter
-pull_requests=Pull fรถrfrรฅgningar
+pull_requests=Pull-fรถrfrรฅgningar
issues=รrenden
milestones=Milstolpar
@@ -77,7 +77,7 @@ write=Skriv
preview=Fรถrhandsgranska
loading=Laddarโฆ
-error404=Sidan du fรถrsรถker nรฅ finns inte eller sรฅ har du inte behรถrighet att se den.
+error404=Sidan du fรถrsรถker nรฅ finns inte , har tagits bort eller sรฅ har du inte behรถrighet att se den.
@@ -94,26 +94,131 @@ name=Namn
logo = Logotyp
sign_in_with_provider = Logga in med %s
enable_javascript = Denna webbplats krรคver JavaScript.
+ok = OK
+more_items = Fler saker
+webauthn_sign_in = Tryck pรฅ knappen pรฅ din sรคkerhetsnyckel. Om din sรคkerhetsnyckel inte har en knapp, dra ut den och sรคtt in den igen.
+new_project_column = Ny kolumn
+copy_type_unsupported = Den hรคr filtypen kan inte kopieras
+error = Fel
+retry = Fรถrsรถk igen
+rerun_all = Kรถr om alla jobb
+copy_success = Kopierad!
+locked = Lรฅst
+copy = Kopiera
+copy_url = Kopiera URL
+copy_error = Kopiering misslyckades
+copy_content = Kopiera innehรฅll
+webauthn_insert_key = Skriv in din sรคkerhetsnyckel
+webauthn_press_button = Var god tryck pรฅ knappen pรฅ din sรคkerhetsnyckelโฆ
+webauthn_error = Kunde inte lรคsa din sรคkerhetsnyckel.
+webauthn_unsupported_browser = Din webblรคsare har inte รคnnu stรถd fรถr WebAuthn.
+webauthn_error_unknown = Ett okรคnt fel har intrรคffat. Var god fรถrsรถk igen.
+webauthn_error_empty = Du mรฅste ange ett namn fรถr den hรคr nyckeln.
+new_org.title = Ny organisation
+new_org.link = Ny organisation
+test = Test
+concept_system_global = Global
+concept_user_individual = Individuell
+rss_feed = RSS-flรถde
+never = Aldrig
+unknown = Okรคnd
+confirm_delete_artifact = รr du sรคker pรฅ att du vill ta bort artefakten "%s"?
+artifacts = Artefakter
+show_timestamps = Visa tidsstรคmpel
+show_full_screen = Visa i fullskรคrm
+download_logs = Ladda ner loggar
+go_back = Gรฅ tillbaka
+show_log_seconds = Visa sekunder
+rerun = Kรถr om
+filter = Filter
+filter.is_archived = Arkiverade
+filter.clear = Rensa filter
+filter.is_mirror = Speglar
+copy_path = Kopiera sรถkvรคg
+unpin = Lossa
+value = Vรคrde
+filter.not_archived = Inte arkiverade
+error413 = Du har anvรคnt upp din kvot.
+invalid_data = Ogiltig data: %v
+filter.not_template = Inte mallar
+copy_hash = Kopiera hash
+view = Se
+copy_branch = Kopiera grennamn
+pin = Fรคst
+filter.public = Publika
+new_repo.title = Ny utvecklingskatalog
+new_migrate.title = Ny migrering
+new_repo.link = Ny utvecklingskatalog
+new_migrate.link = Ny migrering
+filter.not_mirror = Inte speglar
+filter.is_template = Mallar
+filter.private = Privata
+active_stopwatch = Spรฅrning av aktiv tid
+tracked_time_summary = Sammanfattning av spรฅrad tid baserat pรฅ filter av รคrendelistan
+toggle_menu = Visningsmeny
+confirm_delete_selected = Bekrรคfta fรถr att ta bort alla valda objekt?
+webauthn_error_timeout = Timeout uppnรฅddes innan din nyckel kan lรคsas. Vรคnligen ladda om denna sida och fรถrsรถk igen.
+filter.is_fork = Fรถrgreningar
+webauthn_error_duplicated = Sรคkerhetsnyckeln รคr inte tillรฅten fรถr denna begรคran. Se till att nyckeln inte redan รคr registrerad.
+filter.not_fork = Inte fรถrgrenade
+remove_label_str = Ta bort objektet "%"
+webauthn_use_twofa = Anvรคnd en tvรฅfaktorskod frรฅn din telefon
+webauthn_error_insecure = WebAuthn stรถder endast sรคkra anslutningar. Fรถr testning รถver HTTP kan du anvรคnda "localhost" eller "127.0.0.1"
+webauthn_error_unable_to_process = Servern kunde inte hantera din begรคran.
+copy_generic = Kopiera till urklipp
[aria]
+footer.software = Om den hรคr mjukvaran
+footer.links = Lรคnkar
+footer = Sidfot
+navbar = Navigeringsfรคlt
[heatmap]
+contributions_one = bidrag
+contributions_zero = Inga bidrag
+contributions_format = {contributions} pรฅ {day} {month}, {year}
+contributions_few = bidrag
+less = Mindre
+more = Mer
+number_of_contributions_in_the_last_12_months = %s bidrag under de senaste 12 mรฅnaderna
[editor]
+buttons.quote.tooltip = Citera text
+buttons.code.tooltip = Lรคgg till kod
+buttons.link.tooltip = Lรคgg till en lรคnk
+buttons.heading.tooltip = Lรคgg till rubrik
+buttons.bold.tooltip = Lรคgg till fetstilt text
+buttons.italic.tooltip = Lรคgg till kursiv text
+buttons.list.unordered.tooltip = Lรคgg till en punktlista
+buttons.list.ordered.tooltip = Lรคgg till en numrerad lista
+buttons.list.task.tooltip = Lรคgg till en lista med sysslor
+buttons.mention.tooltip = Nรคmn en anvรคndare eller ett team
+buttons.ref.tooltip = Hรคnvisa till ett รคrende eller en pull request
+buttons.new_table.tooltip = Lรคgg till tabell
+table_modal.header = Lรคgg till tabell
+table_modal.placeholder.header = Sidhuvud
+table_modal.placeholder.content = Innehรฅll
+table_modal.label.rows = Rader
+table_modal.label.columns = Kolumner
[filter]
+string.asc = A - ร
[error]
+occurred = Ett fel har intrรคffat
+server_internal = Internt serverfel
+network_error = Nรคtverksfel
+report_message = Om du tror att detta รคr en Forgejo-bugg, sรถk efter รคrenden pรฅ Codeberg eller รถppna ett nytt รคrende om det behรถvs.
[startpage]
app_desc=En smidig, sjรคlvhostad Git-tjรคnst
install=Lรคtt att installera
platform=Plattformsoberoende
-platform_desc=Forgejo kan kรถra รถverallt dรคr Go kan kompileras: Windows, macOS, Linux, ARM, etc. Vรคlj den du gillar!
+platform_desc=Forgejo har bekrรคftats kรถrbart pรฅ libre-operativsystem sรฅ som Linux och FreeBSD, samt pรฅ olika CPU-arkitekturer. Vรคlj den du รคlskar!
lightweight=Lรคttviktig
lightweight_desc=Forgejo har lรฅga minimum-krav och kan kรถras pรฅ en billig Rasperry Pi. Spara pรฅ din maskins kraft!
license=รppen kรคllkod
-license_desc=Hรคmta Forgejo ! Gรฅ med oss genom att bidra fรถr att gรถra projektet รคnnu bรคttre. Var inte blyg fรถr att bli en medarbetare!
+license_desc=Hรคmta Forgejo ! Gรฅ med oss genom att bidra fรถr att gรถra projektet รคnnu bรคttre. Var inte blyg fรถr att bli en medarbetare!
[install]
install=Installation
@@ -139,85 +244,103 @@ err_admin_name_pattern_not_allowed=Administratรถrens anvรคndarnamn รคr ogiltigt,
err_admin_name_is_invalid=Administratรถrsanvรคndarnamnet รคr ogiltigt
general_title=Allmรคnna instรคllningar
-app_name=Sajtens namn
-app_name_helper=Du kan ange ditt fรถretagsnamn hรคr.
+app_name=Instansens titel
+app_name_helper=Skriv in din instans namn hรคr. Det kommer att visas pรฅ varje sida.
repo_path=Rotsรถkvรคg fรถr utvecklingskatalog
repo_path_helper=Fjรคrrutvecklingskataloger kommer att sparas i denna katalog.
-lfs_path=LFS Rotsรถkvรคg
+lfs_path=LFS rotsรถkvรคg
lfs_path_helper=Filer hanterade av Git LFS kommer att sparas i denna mapp. Lรคmna tom fรถr att avaktivera.
-run_user=Kรถr som anvรคndarnamn
+run_user=Anvรคndare att kรถra som
ssh_port=SSH-serverport
-ssh_port_helper=Portnumret som din SSH-server lyssnar pรฅ. Lรคmna tom fรถr att inaktivera.
-http_port=Forgejo HTTP-lyssningsport
-http_port_helper=Portnumret som Forgejos webbserver kommer lyssna pรฅ.
-app_url=Forgejo URL
+ssh_port_helper=Portnumret som din SSH-server anvรคnder. Lรคmna tom fรถr att inaktivera SSH-server.
+http_port=HTTP-lyssningsport
+http_port_helper=Portnumret som kommer att anvรคndas av Forgejos webbserver.
+app_url=Bas-URL
app_url_helper=Basadressen fรถr HTTP(S)-kloningslรคnkar och mejlnotifikationer.
log_root_path=Loggsรถkvรคg
log_root_path_helper=Loggfiler kommer skrivas till denna katalog.
optional_title=รvriga instรคllningar
-email_title=Mejlinstรคllningar
+email_title=E-postinstรคllningar
smtp_addr=SMTP-server
smtp_port=SMTP-port
-smtp_from=Skicka Mejl Som
+smtp_from=Skicka E-post som
smtp_from_helper=Mejladress som Forgejo kommer att anvรคnda. Anges i simpelt ('email@example.com') eller fullstรคndigt ('Name ') format.
-mailer_user=SMTP-Anvรคndarnamn
-mailer_password=SMTP-Lรถsenord
-register_confirm=Krรคv Bekrรคftelse Via Mejl Fรถr Att Registrera
-mail_notify=Aktivera Mejlnotifikationer
-server_service_title=Instรคllningar fรถr Server- och Tredjepartstjรคnster
-offline_mode=Aktivera Lokalt Lรคge
+mailer_user=SMTP-anvรคndarnamn
+mailer_password=SMTP-lรถsenord
+register_confirm=Krรคv bekrรคftelse via E-post fรถr att registrera
+mail_notify=Aktivera E-postnotifikationer
+server_service_title=Instรคllningar fรถr server- och tredjepartstjรคnster
+offline_mode=Aktivera lokalt lรคge
offline_mode.description=Inaktivera CDN frรฅn tredjepart och distribuera samtliga resurser lokalt istรคllet.
disable_gravatar=Inaktivera Gravatar
-disable_gravatar.description=Inaktivera Gravatar- och avatarskรคllor frรฅn tredjepart. Om anvรคndaren inte laddar upp en avatar sรฅ kommer en standardavatar att anvรคndas.
-federated_avatar_lookup=Aktivera Federerade Avatarer
-federated_avatar_lookup.description=Anvรคnd libravatar vid fรถrenad uppslagning av avatarer.
-disable_registration=Inaktivera Sjรคlvregistrering
-disable_registration.description=Inaktivera sjรคlvregistrering av anvรคndare. Endast administratรถrer kommer kunna skapa nya konton.
-allow_only_external_registration.description=Tillรฅt registrering endast via externa tjรคnster
+disable_gravatar.description=Inaktivera Gravatar- och avatarskรคllor frรฅn tredjepart. Standardbilder kommer att anvรคndas fรถr anvรคndaravatarer om dom inte laddar upp en egen avatar till instansen.
+federated_avatar_lookup=Aktivera federerade avatarer
+federated_avatar_lookup.description=Anvรคnd Libavatar fรถr uppslagning av avatarer.
+disable_registration=Inaktivera sjรคlvregistrering
+disable_registration.description=Endast instansens administratรถrer kommer kunna skapa nya konton. Det rekommenderas starkt att inaktivera sjรคlvregistrering av anvรคndare om du inte tรคnker driva en publik instans fรถr alla och รคr redo att hantera en stor mรคngd spam-konton.
+allow_only_external_registration.description=Anvรคndare kommer endast kunna skapa nya konton genom att anvรคnda konfigurerade externa tjรคnster.
openid_signin=Aktivera OpenID-inloggning
-openid_signin.description=Aktivera anvรคndarinloggning via OpenID.
+openid_signin.description=Tillรฅt anvรคndare att logga in via OpenID.
openid_signup=Aktivera sjรคlvregistrering genom OpenID
-openid_signup.description=Aktivera OpenID-baserad sjรคlvregistrering av anvรคndare.
+openid_signup.description=Tillรฅt anvรคndare att skapa konton via OpenID om sjรคlvregistrering รคr aktiverad.
enable_captcha=Aktivera CAPTCHA registrering
-enable_captcha.description=Krรคv captcha fรถr anvรคndarregistrering.
-require_sign_in_view=Krรคv Inloggning Fรถr Att Visa Sidor
-admin_setting.description=Skapandet av administratรถrskonto รคr frivilligt. Den fรถrsta anvรคndaren som registreras blir automatiskt administratรถr.
-admin_title=Instรคllningar fรถr Administratรถrskonto
-admin_name=Anvรคndarnamn fรถr Administratรถr
+enable_captcha.description=Krรคv att anvรคndare klarar CAPTCHA fรถr att registrera konton.
+require_sign_in_view=Krรคv inloggning fรถr att visa instansens innehรฅll
+admin_setting.description=Skapandet av ett administratรถrskonto รคr frivilligt. Den fรถrsta anvรคndaren som registreras blir automatiskt administratรถr.
+admin_title=Instรคllningar fรถr administratรถrskonto
+admin_name=Anvรคndarnamn fรถr administratรถr
admin_password=Lรถsenord
confirm_password=Bekrรคfta lรถsenord
-admin_email=Mejladress
+admin_email=E-postadress
install_btn_confirm=Installera Forgejo
-test_git_failed=Misslyckades att testa 'git' kommando: %v
-sqlite3_not_available=Denna version av Forgejo stรถdjer ej SQLite3. Ladda ner den officiella binรคren frรฅn %s (inte 'gobuild' versionen).
+test_git_failed=Misslyckades att testa "git" kommando: %v
+sqlite3_not_available=Denna version av Forgejo stรถdjer inte SQLite3. Ladda ner den officiella binรคren frรฅn %s (inte "gobuild" versionen).
invalid_db_setting=Databasinstรคllningarna รคr ogiltiga: %v
invalid_repo_path=Utvecklingskatalogens rotsรถkvรคg รคr ogiltig: %v
run_user_not_match=Systemtjรคnstanvรคndaren รคr inte den nuvarande anvรคndaren: %s -> %s
save_config_failed=Misslyckades att spara konfigurationen: %v
invalid_admin_setting=Instรคllning fรถr administartรถrskontot รคr ogiltig: %v
invalid_log_root_path=Sรถkvรคgen fรถr loggar รคr ogiltig: %v
-default_keep_email_private=Dรถlj mailadresser som standard
-default_keep_email_private.description=Dรถlj mailadresser fรถr nya anvรคndarkonton som standard.
+default_keep_email_private=Dรถlj e-postadresser som standard
+default_keep_email_private.description=Dรถlj e-postadress fรถr nya anvรคndarkonton som standard sรฅ att den informationen inte omedelbart lรคcker efter registrering.
default_allow_create_organization=Tillรฅt skapandet utav organisationer som standard
-default_allow_create_organization.description=Tillรฅt nya anvรคndarkonton att skapa organisationer som standard.
-default_enable_timetracking=Aktivera tidredovisning som Standard
+default_allow_create_organization.description=Tillรฅt nya anvรคndarkonton att skapa organisationer som standard. Nรคr detta alternativt ej รคr aktivt sรฅ behรถver en administratรถr tilldela rรคttigheter att skapa organisationer till nya anvรคndare.
+default_enable_timetracking=Aktivera tidredovisning som standard
default_enable_timetracking.description=Aktivera tidsredovisning fรถr nya utvecklingskataloger som standard.
-no_reply_address=Dold mejldomรคn
-no_reply_address_helper=Domรคnnamn fรถr anvรคndare med en dold mailadress. Exempelvis kommer anvรคndarnamnet 'joe' att loggas i Git som 'joe@noreply.example.org' om dold maildomรคn รคr satt till 'noreply.example.org'.
+no_reply_address=Dold e-postdomรคn
+no_reply_address_helper=Domรคnnamn fรถr anvรคndare med en dold e-postadress. Exempelvis kommer anvรคndarnamnet "joe" att loggas i Git som "joe@noreply.example.org" om den dolda e-postdomรคnen รคr satt till "noreply.example.org".
+require_db_desc = Forgejo krรคver MySQL, PostgreSQL, SQLite3 eller TiDB (MySQL-protokoll).
+allow_only_external_registration = Tillรฅt registrering endast via externa tjรคnster
+app_slogan = Instansslogan
+app_slogan_helper = Skriv in din slogan hรคr. Lรคmna tom fรถr att stรคnga av.
+domain = Serverdomรคn
+domain_helper = Domรคn eller vรคrdadress fรถr servern.
+reinstall_error = Du fรถrsรถker att installera i en existerande Forgejo-databas
+password_algorithm_helper = Stรคll in hashalgoritmen fรถr lรถsenord. Algoritmer har olika krav och styrka. Argon2-algoritmen รคr ganska sรคker men anvรคnder mycket minne och kan vara olรคmplig fรถr smรฅ system.
+config_location_hint = Dessa konfigurationsinstรคllningar kommer att sparas i:
+invalid_db_table = Databastabellen "%s" รคr ogiltig: %v
+secret_key_failed = Misslyckades att generera hemlig nyckel: %v
+allow_dots_in_usernames = Tillรฅt anvรคndare att anvรคnda punkter i sina anvรคndarnamn. Pรฅverkar inte befintliga anvรคndare.
+reinstall_confirm_message = Ominstallation med en befintlig Forgejo-databas kan orsaka flera problem. I de flesta fall bรถr du anvรคnda din befintliga "app.ini" fรถr att kรถra Forgejo. Om du vet vad du hรฅller pรฅ med, bekrรคfta fรถljande:
+require_sign_in_view.description = Begrรคnsa รฅtkomst till innehรฅll till inloggade anvรคndare. Gรคster kommer endast att kunna besรถka autentiseringssidorna.
+invalid_app_data_path = Sรถkvรคgen fรถr appdata รคr ogiltig: %v
+internal_token_failed = Misslyckades att generera intern token: %v
+password_algorithm = Hashalgoritm fรถr lรถsenord
+invalid_password_algorithm = Ogiltig hashalgoritm fรถr lรถsenord
[home]
-uname_holder=Anvรคndarnamn eller Mejladress
+uname_holder=Anvรคndarnamn eller e-postadress
password_holder=Lรถsenord
-switch_dashboard_context=Vรคxla Visad Instrumentpanel
+switch_dashboard_context=Vรคxla visad instrumentpanel
my_repos=Utvecklingskataloger
show_more_repos=Visa flera utvecklingskatalogerโฆ
collaborative_repos=Kollaborativa Utvecklingskataloger
-my_orgs=Mina organisationer
+my_orgs=Organisationer
my_mirrors=Mina speglar
view_home=Visa %s
search_repos=Hitta en utvecklingskatalogโฆ
-filter=รvriga Filter
+filter=รvriga filter
show_archived=Arkiverade
show_both_archived_unarchived=Visar bรฅde arkiverade och icke arkiverade
@@ -230,6 +353,7 @@ show_only_private=Visar endast privata
show_only_public=Visar endast publika
issues.in_your_repos=I dina utvecklingskataloger
+filter_by_team_repositories = Filtrera efter lagutvecklingskataloger
[explore]
repos=Utvecklingskataloger
@@ -242,9 +366,13 @@ user_no_results=Inga matchande anvรคndare hittades.
org_no_results=Inga matchande organisationer hittades.
code_no_results=Ingen kรคllkod hittades som matchar din sรถkterm.
code_last_indexed_at=Indexerades senast %s
+stars_one = %d stjรคrna
+go_to = Gรฅ till
+relevant_repositories = Endast relevanta utvecklingskataloger visas, visa ofiltrerade resultat .
+stars_few = %d stjรคrnor
[auth]
-create_new_account=Registrera Konto
+create_new_account=Registrera konto
register_helper_msg=Har du redan ett konto? Logga in nu!
social_register_helper_msg=Har du redan ett konto? Lรคnka det nu!
disable_register_prompt=Registrering inaktiverad. Vรคnligen kontakta din sidadministratรถr.
@@ -253,18 +381,18 @@ remember_me=Kom ihรฅg denna enhet
forgot_password_title=Glรถmt lรถsenord
forgot_password=Glรถmt lรถsenord?
sign_up_now=Behรถver du ett konto? Registrera nu.
-confirmation_mail_sent_prompt=Ett nytt bekrรคftelsemail has skickats till %s . Vรคnligen kolla din inkorg inom dom kommande %s fรถr att slutfรถra registreringsprocessen.
+confirmation_mail_sent_prompt=Ett nytt bekrรคftelsemejl has skickats till %s . Fรถr att slutfรถra registreringsprocessen, vรคnligen kolla din inkorg inom dom kommande %s. Om e-postadressen รคr felaktig sรฅ kan du logga in och begรคra att fรฅ ett nytt bekrรคftelsemejlet skickat till en annan e-postadressen.
must_change_password=รndra ditt lรถsenord
allow_password_change=Krรคv att anvรคndaren byter lรถsenord (rekommenderas)
-reset_password_mail_sent_prompt=Ett nytt bekrรคftelsemail has skickats till %s . Vรคnligen kontrollera din inkorg inom de kommande %s fรถr att slutfรถra รฅterstรคllning av ditt konto.
+reset_password_mail_sent_prompt=Ett nytt bekrรคftelsemail has skickats till %s . Fรถr att slutfรถra รฅterstรคllning av ditt konto, kontrollera din inkorg och gรฅ till den bifogade lรคnken inom de kommande %s.
active_your_account=Aktivera ditt konto
account_activated=Kontot har aktiverats
-prohibit_login=Inloggning otillรฅten
+prohibit_login=Kontot รคr avstรคngd
resent_limit_prompt=Du har redan begรคrt ett aktiveringsmejl nyligen. Vรคnligen vรคnta 3 minuter och fรถrsรถk igen.
has_unconfirmed_mail=Hej %s, du har en obekrรคftad epostaddress (%s ). Om du inte har fรฅtt ett bekrรคftelsemail eller behรถver ett nytt, klicka pรฅ knappen nedan.
resend_mail=Klicka hรคr fรถr att skicka ditt aktiveringsmejl igen
email_not_associate=Denna e-postadress รคr inte knutet till nรฅgot konto.
-send_reset_mail=Skicka mail fรถr kontoรฅterstรคllning
+send_reset_mail=Skicka mejl fรถr kontoรฅterstรคllning
reset_password=Kontoรฅterstรคllning
invalid_code=Din bekrรคftelsekod รคr ogiltig eller har lรถpt ut.
reset_password_helper=ร
terstรคll konto
@@ -298,18 +426,41 @@ authorize_title=Ge "%s" tillgรฅng till ditt konto?
authorization_failed=Auktorisering misslyckades
sspi_auth_failed=SSPI-autentisering misslyckades
password_pwned_err=Kunde inte slutfรถra begรคran till HaveIBeenPwned
+reset_password_wrong_user = Du รคr inloggad som %s, men kontoรฅterstรคllningslรคnken รคr avsedd fรถr %s
+invalid_code_forgot_password = Din bekrรคftelsekod รคr ogiltig eller har gรฅtt ut. Klicka pรฅ hรคr fรถr att pรฅbรถrja en ny session.
+invalid_password = Ditt lรถsenord matchar inte lรถsenordet som anvรคndes fรถr att skapa kontot.
+openid_signin_desc = Ange din OpenID URI. Till exempel: alice.openid.example.org eller https://openid.example.org/alice.
+sign_in_openid = Fortsรคtt med OpenID
+hint_login = Har du redan ett konto? Logga in nu!
+change_unconfirmed_email_summary = รndra e-postadressen som aktiveringsmejl skickas till.
+change_unconfirmed_email_error = Det gรฅr inte att รคndra e-postadressen: %v
+use_onetime_code = Anvรคnde en engรฅngskod
+last_admin = Du kan inte ta bort den sista administratรถren. Det mรฅste finnas minst en administratรถr.
+back_to_sign_in = Tillbaka till Logga in
+hint_register = Behรถver du ett konto? Registrera ett nu.
+prohibit_login_desc = Ditt konto har blivit avstรคngt frรฅn att interagera med instansen. Kontakta instansadministratรถren fรถr att รฅterfรฅ tillgรฅng.
+password_pwned = Lรถsenordet du valde finns pรฅ en lista รถver stulna lรถsenord som tidigare exponerats i offentliga dataintrรฅng. Fรถrsรถk igen med ett annat lรถsenord och รถvervรคg att รคndra detta lรถsenord pรฅ annat hรฅll ocksรฅ.
+sign_up_button = Registrera dig.
+sign_up_successful = Kontot skapades. Vรคlkommen!
[mail]
-
activate_account=Vรคnligen aktivera ditt konto
activate_email=Verifiera din epostaddress
-register_notify=Vรคlkommen till Forgejo
+register_notify=Vรคlkommen till %s
reset_password=ร
terstรคll ditt konto
register_success=Registreringen lyckades
+password_change.subject = Ditt lรถsenord har uppdaterats
+password_change.text_1 = Lรถsenordet fรถr ditt konto รคndrades just.
+primary_mail_change.subject = Din primรคra e-postadress har รคndrats
+activate_account.text_1 = Hej %[1]s , tack fรถr att du registrerat dig hos %[2]s!
+reply = eller svara pรฅ detta e-postmeddelande direkt
+hi_user_x = Hej %s ,
+admin.new_user.user_info = Anvรคndarinformation
+admin.new_user.text = Vรคnligen klicka hรคr fรถr att hantera denna anvรคndare frรฅn administratรถrspanelen.
@@ -347,8 +498,8 @@ SSPISeparatorReplacement=Avgrรคnsare
SSPIDefaultLanguage=Standardsprรฅk
require_error=fรฅr inte vara tomt
-alpha_dash_error=` bรถr endast innehรฅlla alfanumeriska tecken, bindestreck ('-') och understreck ('_').`
-alpha_dash_dot_error=` bรถr endast innehรฅlla alfanumeriska tecken, bindestreck ('-'), understreck ('_') och punkter ('.').`
+alpha_dash_error=` bรถr endast innehรฅlla alfanumeriska tecken, bindestreck ("-") och understreck ("_").`
+alpha_dash_dot_error=` bรถr endast innehรฅlla alfanumeriska tecken, bindestreck ("-"), understreck ("_") och punkter (".").`
git_ref_name_error=mรฅste vara ett fรถr Git vรคlformaterat referensnamn.
size_error=` mรฅste vara av storleken %s`
min_size_error=` mรฅste innehรฅlla minst %s tecken.`
@@ -384,7 +535,7 @@ enterred_invalid_owner_name=Det nya namnet pรฅ รคgaren รคr ogiltligt.
enterred_invalid_password=Det angivna lรถsenordet รคr felaktigt.
user_not_exist=Anvรคndaren finns inte.
team_not_exist=Teamet finns inte.
-last_org_owner=Du kan inte ta bort den sista anvรคndaren frรฅn 'owners' teamet. Det mรฅste finnas minst en รคgare fรถr en organisation.
+last_org_owner=Du kan inte ta bort den sista anvรคndaren frรฅn "owners" teamet. Det mรฅste finnas minst en รคgare fรถr en organisation.
cannot_add_org_to_team=En organisation kan inte lรคggas till som teammedlem.
invalid_ssh_key=Kunde inte verifiera din SSH-nyckel: %s
@@ -398,9 +549,9 @@ target_branch_not_exist=Mรฅlgrenen finns inte.
[user]
change_avatar=Byt din avatarโฆ
repositories=Utvecklingskataloger
-activity=Offentlig Aktivitet
+activity=Offentlig aktivitet
followers_few=%d fรถljare
-starred=Stjรคrnmรคrkta Utvecklingskataloger
+starred=Stjรคrnmรคrkta utvecklingskataloger
projects=Projekt
overview=รversikt
following_few=%d fรถljer
@@ -416,13 +567,13 @@ account=Konto
password=Lรถsenord
security=Sรคkerhet
avatar=Visningsbild
-ssh_gpg_keys=SSH / GPG-nycklar
+ssh_gpg_keys=SSH/GPG-nycklar
social=Sociala konton
applications=Applikationer
-orgs=Hantera Organisationer
+orgs=Organisationer
repos=Utvecklingskataloger
delete=Radera konto
-twofa=Tvรฅfaktorsautentisering
+twofa=Tvรฅfaktorsautentisering (TOTP)
account_link=Lรคnkade Konton
organization=Organisationer
@@ -443,16 +594,16 @@ comment_type_group_title=Titel
privacy=Sekretess
keep_activity_private_popup=Gรถr aktiviteten endast synlig fรถr dig och administratรถrerna
-lookup_avatar_by_mail=Slรฅ upp avatarer med hjรคlp utav mejladress
+lookup_avatar_by_mail=Slรฅ upp avatar efter e-postadress
federated_avatar_lookup=Fรถrenad uppslagning av avatar
-enable_custom_avatar=Aktivera Egen Avatar
+enable_custom_avatar=Anvรคnd anpassad avatar
choose_new_avatar=Vรคlj ny avatar
-update_avatar=Uppdatera Avatar
-delete_current_avatar=Tag bort aktuell avatar
+update_avatar=Uppdatera avatar
+delete_current_avatar=Ta bort aktuell avatar
uploaded_avatar_not_a_image=Den uppladdade filen รคr inte en bild.
update_avatar_success=Din avatar har blivit uppdaterad.
-update_password=รndra Lรถsenordet
+update_password=รndra lรถsenord
old_password=Nuvarande lรถsenord
new_password=Nytt lรถsenord
password_incorrect=Det nuvarande lรถsenordet รคr felaktigt.
@@ -460,18 +611,18 @@ change_password_success=Ditt lรถsenord har uppdaterats. Logga in med ditt nya l
password_change_disabled=Externa anvรคndare kan inte รคndra sitt lรถsenord genom Forgejos webbgrรคnssnitt.
emails=E-postadresser
-manage_emails=Hantera mejladresser
-manage_themes=Vรคlj standardtema
-manage_openid=Hantera OpenID-adresser
-theme_desc=Detta kommer att vara ditt standardtema pรฅ webbplatsen.
+manage_emails=Hantera e-postadresser
+manage_themes=Standardtema
+manage_openid=OpenID-adresser
+theme_desc=Detta tema kommer att anvรคndas fรถr webbgrรคnssnittet nรคr du รคr inloggad.
primary=Primรคr
activated=Aktiverad
requires_activation=Aktivering krรคvs
-primary_email=Sรคtt Som Primรคr
+primary_email=Gรถr primรคr
activate_email=Skicka aktivering
activations_pending=Vรคntar pรฅ aktivering
delete_email=Ta Bort
-email_deletion=Ta Bort mejladress
+email_deletion=Ta bort e-postadress
email_deletion_desc=Mejladressen och relaterad information kommer tas bort frรฅn ditt konto. Git-commits med denna mejladress fรถrblir ofรถrรคndrade. Vill du fortsรคtta?
email_deletion_success=Mejladressen har tagits bort.
theme_update_success=Ditt tema รคndrades.
@@ -479,26 +630,26 @@ theme_update_error=Det valda temat finns inte.
openid_deletion=Ta bort OpenID-adress
openid_deletion_desc=Borttagning av denna OpenID-adress frรฅn ditt konto kommer fรถrhindra framtida inloggningar med den. Vill du fortsรคtta?
openid_deletion_success=OpenID-adressen har tagits bort.
-add_new_email=Lรคgg till ny mejladress
-add_new_openid=Lรคgg till ny OpenID URI
-add_email=Lรคgg till mejladress
+add_new_email=Lรคgg till ny e-postadress
+add_new_openid=Lรคgg till ny OpenID-URI
+add_email=Lรคgg till e-postadress
add_openid=Lรคgg till OpenID URI
add_email_success=Den nya mejladressen har lagts till.
email_preference_set_success=E-postinstรคllningen har uppdaterats.
add_openid_success=Den nya OpenID-adressen har lagts till.
-keep_email_private=Gรถm mejladress
+keep_email_private=Gรถm e-postadress
openid_desc=OpenID lรฅter dig delegera autentiseringen till en extern leverantรถr.
manage_ssh_keys=Hantera SSH-nycklar
manage_gpg_keys=Hantera GPG-nycklar
add_key=Lรคgg till nyckel
-ssh_desc=Dessa publika SSH nycklar รคr associerade med ditt konto. De motsvarande privata nycklarna tillรฅter full รฅtkomst till dina utvecklingskataloger.
+ssh_desc=Dessa publika SSH nycklar รคr associerade med ditt konto. De motsvarande privata nycklarna tillรฅter full รฅtkomst till dina utvecklingskataloger. SSH-nycklar som har blivit verifierade kan anvรคndas fรถr att verifiera SSH-signerade Git-commiter.
gpg_desc=Dessa publika GPG nycklar รคr associerade med ditt konto. Hรฅll dina privata nycklar sรคkra dรฅ de tillรฅter att commits kan verifieras.
ssh_helper=Behรถver du hjรคlp? Kolla in Github's guide fรถr att skapa din egen SSH-nycklar eller lรถsa vanliga problem som kan uppstรฅ med SSH.
gpg_helper=Behรถver du hjรคlp? Ta en titt pรฅ Github's guide om GPG .
add_new_key=Lรคgg till SSH-nyckel
add_new_gpg_key=Lรคgg till GPG-nyckel
-key_content_gpg_placeholder=Bรถrjar med '-----BEGIN PGP PUBLIC KEY BLOCK-----'
+key_content_gpg_placeholder=Bรถrjar med "-----BEGIN PGP PUBLIC KEY BLOCK-----"
ssh_key_been_used=Denna SSH-nyckel har redan lagts till pรฅ servern.
gpg_key_id_used=En publik GPG-nyckel med samma ID existerar redan.
gpg_key_verify=Verifiera
@@ -530,15 +681,15 @@ ssh_disabled=SSH รคr inaktiverat
manage_social=Hantera lรคnkade sociala konton
unbind=Koppla frรฅn
-manage_access_token=Hantera รฅtkomst-tokens
-generate_new_token=Generera Nya Tokens
+manage_access_token=ร
tkomsttokens
+generate_new_token=Generera ny token
tokens_desc=Dessa tokens tillรฅter รฅtkomst till ditt konto via Forgejo API.
token_name=Tokennamn
-generate_token=Generera Token
+generate_token=Generera token
generate_token_success=Din nya token har genererats. Kopiera nu dรฅ den inte kommer visas igen.
generate_token_name_duplicate=%s finns redan som programnamn. Vรคlj ett annat.
delete_token=Radera
-access_token_deletion=Ta bort รฅtkomst token
+access_token_deletion=Ta bort รฅtkomsttoken
access_token_deletion_cancel_action=Avbryt
access_token_deletion_confirm_action=Radera
delete_token_success=Token har tagits bort. Applikationer som anvรคnder den kommer inte lรคngre ha รฅtkomst till ditt konto.
@@ -563,7 +714,7 @@ oauth2_application_create_description=OAuth2-applikationer ger tredjepartsapplik
authorized_oauth2_applications=Auktoriserade OAuth2-appar
revoke_key=Upphรคv
-revoke_oauth2_grant=Upphรคv รฅtkomst
+revoke_oauth2_grant=Dra in รฅtkomst
revoke_oauth2_grant_description=ร
terkallning av รฅtkomst fรถr detta tredjepartsprogram kommer att hindra programmet frรฅn att komma รฅt dina data. รr du sรคker?
twofa_desc=Tvรฅfaktorsautentisering fรถrbรคttrar sรคkerheten pรฅ ditt konto.
@@ -583,30 +734,31 @@ passcode_invalid=Koden รคr ogiltig. Fรถrsรถk igen.
twofa_enrolled=Tvรฅfaktorsautentisering har aktiverats fรถr ditt konto. Fรถrvara din skrapkod (%s) pรฅ en sรคker plats eftersom den bara visas en gรฅng!
-manage_account_links=Hantera Lรคnkade Konton
+manage_account_links=Lรคnkade konton
manage_account_links_desc=Dessa externa konton รคr lรคnkade till ditt Forgejo-konto.
account_links_not_available=Det finns fรถr nรคrvarande inga externa konton lรคnkade till ditt Forgejo-konto.
link_account=Lรคnka konto
-remove_account_link=Ta Bort Lรคnkat Konto
+remove_account_link=Ta bort lรคnkat konto
remove_account_link_desc=Borttagning av lรคnkade konton kommer hรคva dess รฅtkomst till ditt Forgejo-konto. Vill du fortsรคtta?
remove_account_link_success=Det lรคnkade konton har tagits bort.
orgs_none=Du รคr inte en medlem i nรฅgon organisation.
-delete_account=Radera ditt konto
+delete_account=Ta bort ditt konto
delete_prompt=Denna รฅtgรคrd kommer ta bort ditt konto permanent. Det KAN INTE รฅngras.
-confirm_delete_account=Bekrรคfta Borttagelsen
-delete_account_title=Ta Bort Anvรคndarkonto
+confirm_delete_account=Bekrรคfta borttagelse
+delete_account_title=Ta bort anvรคndarkonto
delete_account_desc=รr du sรคker pรฅ att du vill ta bort ditt konto permanent?
-email_notifications.enable=Aktivera notiser via mejl
+email_notifications.enable=Aktivera notiser via e-post
email_notifications.onmention=Endast e-post vid omnรคmnanden
-email_notifications.disable=Inaktivera notiser via mejl
-email_notifications.submit=Stรคll in e-post instรคllningar
+email_notifications.disable=Inaktivera notiser via e-post
+email_notifications.submit=Stรคll in e-postpreferenser
visibility.public=Offentlig
visibility.private=Privat
+change_password = Byt lรถsenord
[repo]
owner=รgare
@@ -614,31 +766,31 @@ repo_name=Utvecklingskatalogens namn
repo_name_helper=Bra namn pรฅ utvecklingskataloger bestรฅr utav korta, unika nyckelord som รคr enkla att komma ihรฅg.
repo_size=Utvecklingskatalogens storlek
template=Mall
-template_select=Vรคlj mall.
+template_select=Vรคlj en mall
template_helper=Gรถr utvecklingskatalog till mall
template_description=Utvecklingskatalogmallar lรฅter anvรคndare skapa nya utvecklingskataloger med samma filstruktur, filer, och valda instรคllningar.
visibility=Synligt fรถr
visibility_description=Bara รคgaren eller medlemmar i organisationen med rรคtt rรคttigheter kommer kunna se det.
visibility_helper_forced=Din tjรคnstadministratรถr pรฅtvingar privata utvecklingskataloger.
-visibility_fork_helper=(รndring av detta kommer pรฅverka alla forkar.)
+visibility_fork_helper=(Att รคndra detta kommer att pรฅverka alla forkar.)
clone_helper=Hjรคlp med kloning? Se hjรคlp .
-fork_repo=Forka Repo
-fork_from=Forka Frรฅn
+fork_repo=Forka utveckligskatalog
+fork_from=Forka frรฅn
fork_visibility_helper=Synligheten av en forkad utvecklingskatalog kan inte รคndras.
use_template=Vรคlj den hรคr mallen
-generate_repo=Skapa utvecklingskatalog
+generate_repo=Generera utvecklingskatalog
generate_from=Generera frรฅn
repo_desc=Beskrivning
repo_lang=Sprรฅk
-repo_gitignore_helper=Vรคlj .gitignore-mallar.
+repo_gitignore_helper=Vรคlj .gitignore-mallar
repo_gitignore_helper_desc=Vรคlj vilka filer som inte ska spรฅras frรฅn en lista med mallar fรถr vanliga sprรฅk. Typiska artefakter som genereras av varje sprรฅk byggverktyg ingรฅr i .gitignore som standard.
-issue_labels=รrendeetiketter
-issue_labels_helper=Vรคlj en grupp av รคrendeetiketter.
+issue_labels=Etiketter
+issue_labels_helper=Vรคlj en uppsรคttning av etiketter
license=Licens
-license_helper=Vรคlj licensfil.
-license_helper_desc=En licens styr vad andra kan och inte kan gรถra med din kod. Inte sรคker pรฅ vilken som รคr rรคtt fรถr ditt projekt? Se Vรคlj en licens.
+license_helper=Vรคlj en licensfil
+license_helper_desc=En licens styr vad andra kan och inte kan gรถra med din kod. Inte sรคker pรฅ vilken som รคr rรคtt fรถr ditt projekt? Se Vรคlj en licens .
readme=README
-readme_helper=Vรคlj en mall fรถr README-filen.
+readme_helper=Vรคlj en mall fรถr README-filen
readme_helper_desc=Hรคr kan du skriva en fullstรคndig beskrivning fรถr ditt projekt.
auto_init=Initiera utvecklingskatalog (Lรคgger till .gitignore, License and README)
create_repo=Skapa utvecklingskatalog
@@ -647,8 +799,8 @@ default_branch_helper=Den fรถrvalda grenen รคr bas-gren fรถr pull requests och k
mirror_prune=Rensa
mirror_prune_desc=Ta bort fรถrlegade fjรคrrfรถljande referenser
mirror_interval_invalid=Speglingsintervallen รคr inte giltig.
-mirror_address=Klona Frรฅn URL
-mirror_last_synced=Senaste Synkronisering
+mirror_address=Klona frรฅn URL
+mirror_last_synced=Synkroniserad senast
watchers=Observerare
stargazers=Stjรคrnmรคrkare
forks=Fรถrgreningar
@@ -669,7 +821,7 @@ desc.internal=Intern
desc.archived=Arkiverade
template.items=Mallobjekt
-template.git_content=Git innehรฅll (Default branch)
+template.git_content=Git-innehรฅll (standardgren)
template.git_hooks=Githookar
template.webhooks=Webbhookar
template.topics=รmnen
@@ -682,7 +834,7 @@ archive.issue.nocomment=Den hรคr utvecklingskatalogen รคr arkiverad. Du kan inte
archive.pull.nocomment=Den hรคr utvecklingskatalogen รคr arkiverad. Du kan inte kommentera pรฅ pull-fรถrfrรฅgningar.
-migrate_options=Migrationsalternativ
+migrate_options=Migreringsalternativ
migrate_service=Migreringstjรคnst
migrate_items=Migrationsobjekt
migrate_items_wiki=Wiki
@@ -692,9 +844,9 @@ migrate_items_issues=รrenden
migrate_items_pullrequests=Pull Requester
migrate_items_merge_requests=Begรคran om sammanslagning
migrate_items_releases=Releaser
-migrate_repo=Migrera Repot
-migrate.clone_address=Migrera Eller Klona Frรฅn URL
-migrate.clone_address_desc=HTTP(S)- eller Git 'clone' lรคnken fรถr en existerande utvecklingskatalog
+migrate_repo=Migrera utvecklingskatalog
+migrate.clone_address=Migrera eller klona frรฅn URL
+migrate.clone_address_desc=HTTP(S)- eller Git "clone" lรคnk fรถr en existerande utvecklingskatalog
migrate.clone_local_path=eller en lokal serversรถkvรคg
migrate.permission_denied=Du fรฅr inte importera lokala repon.
migrate.failed=Migrering misslyckades: %v
@@ -704,7 +856,7 @@ migrated_from_fake=Migrerad frรฅn %[1]s
migrate.migrate=Migrera frรฅn %s
migrate.migrating=Migrerar frรฅn %s ...
migrate.migrating_failed=Migrering frรฅn %s misslyckades.
-migrate.migrating_issues=Migrerar รrenden
+migrate.migrating_issues=Migrerar รคrenden
mirror_from=spegling av
forked_from=forkad frรฅn
@@ -718,7 +870,7 @@ watch=Bevaka
unstar=Ta bort stjรคrnmรคrkning
star=Stjรคrnmรคrk
fork=Fรถrgrening
-download_archive=Ladda Ned Utvecklingskatalogen
+download_archive=Ladda ner utvecklingskatalogen
no_desc=Ingen beskrivning
quick_guide=Snabbguide
@@ -752,38 +904,40 @@ file_view_raw=Visa i rรฅformat
file_permalink=Permalรคnk
file_too_large=Filen รคr fรถr stor fรถr att visas.
-video_not_supported_in_browser=Din webblรคsare stรถdjer ej HTML5-taggen 'video'.
-audio_not_supported_in_browser=Din webblรคsare stรถder inte taggen 'audio' i HTML5.
+video_not_supported_in_browser=Din webblรคsare stรถdjer ej HTML5-taggen "video".
+audio_not_supported_in_browser=Din webblรคsare stรถdjer ej HTML5-taggen "audio".
stored_lfs=Sparad med Git LFS
+stored_annex=Sparad med Git Annex
symbolic_link=Symbolisk lรคnk
-commit_graph=Commit-Graf
+commit_graph=Commitgraf
commit_graph.monochrome=Mono
blame=Blame
normal_view=Normal vy
line=rad
lines=rader
-editor.new_file=Ny Fil
-editor.upload_file=Ladda Upp Fil
-editor.edit_file=Redigera Fil
+editor.new_file=Ny fil
+editor.upload_file=Ladda upp fil
+editor.edit_file=Redigera fil
editor.preview_changes=Fรถrhandsgranska รคndringar
editor.cannot_edit_lfs_files=LFS-filer kan inte redigeras i webbgrรคnssnittet.
+editor.cannot_edit_annex_files=Annex-filer kan inte redigeras i webbgrรคnssnittet.
editor.cannot_edit_non_text_files=Binรคra filer kan inte redigeras genom webbgrรคnssnittet.
-editor.edit_this_file=Redigera Fil
+editor.edit_this_file=Redigera fil
editor.this_file_locked=Filen รคr lรฅst
editor.must_be_on_a_branch=Du mรฅste vara pรฅ en branch fรถr att gรถra eller fรถreslรฅ รคndringar i denna fil.
editor.fork_before_edit=Du mรฅste forka denna utvecklingskatalog fรถr att gรถra eller fรถreslรฅ fรถrรคndringar pรฅ denna fil.
editor.delete_this_file=Ta bort fil
editor.must_have_write_access=Du mรฅste ha skrivรฅtkomst fรถr att gรถra eller fรถreslรฅ รคndringar av denna fil.
editor.name_your_file=Namnge din filโฆ
-editor.filename_help=Lรคgg till en katalog genom att skriva dess namn fรถljt utav en slash ('/'). Ta bort katalog genom att sudda i bรถrjan utav fรคltet.
+editor.filename_help=Lรคgg till en katalog genom att skriva dess namn fรถljt utav ett snedstreck ("/"). Ta bort katalog genom att sudda i bรถrjan utav fรคltet.
editor.or=eller
editor.cancel_lower=Avbryt
editor.commit_signed_changes=Committa signerade รคndringar
editor.commit_changes=Checka in รคndringar
-editor.add_tmpl=Lรคgg till ''
+editor.add_tmpl=Lรคgg till '<%s>'
editor.commit_message_desc=Lรคgg till en valfri utรถkad beskrivningโฆ
-editor.commit_directly_to_this_branch=Checka in direkt till grenen %s .
+editor.commit_directly_to_this_branch=Checka in direkt till grenen %[1]s .
editor.create_new_branch=Skapa en ny gren fรถr denna incheckning och pรฅbรถrja en hรคmtningsbegรคran.
editor.create_new_branch_np=Skapa en ny branch fรถr den hรคr committen.
editor.propose_file_change=Fรถreslรฅ filรคndring
@@ -804,7 +958,7 @@ commits.desc=Blรคddra i kรคllkodens fรถrรคndringshistorik.
commits.commits=Incheckningar
commits.search=Sรถk commitsโฆ
commits.find=Sรถk
-commits.search_all=Alla brancher
+commits.search_all=Alla grenar
commits.author=Upphovsman
commits.message=Meddelande
commits.date=Datum
@@ -813,7 +967,7 @@ commits.newer=Nyare
commits.signed_by=Signerad av
commits.signed_by_untrusted_user=Signerad av opรฅlitlig anvรคndare
commits.signed_by_untrusted_user_unmatched=Signerad av opรฅlitlig anvรคndare som inte matchar den som committat
-commits.gpg_key_id=GPG-nyckel ID
+commits.gpg_key_id=GPG-nyckel-ID
commitstatus.pending=Vรคntande
@@ -828,7 +982,7 @@ projects.new=Nytt projekt
projects.deletion=Ta bort projekt
projects.deletion_success=Projektet har tagits bort.
projects.edit=Redigera projekt
-projects.modify=Uppdatera projekt
+projects.modify=Redigera projekt
projects.type.none=Ingen
projects.template.desc=Projektmall
projects.type.uncategorized=Okatergoriserad
@@ -843,10 +997,10 @@ issues.filter_milestones=Filtrera milstolpe
issues.filter_projects=Filtrera projekt
issues.filter_labels=Filtrera etikett
issues.filter_reviewers=Filtrera granskare
-issues.new=Nytt รrende
+issues.new=Nytt รคrende
issues.new.title_empty=Titeln kan inte vara tom
issues.new.labels=Etiketter
-issues.new.no_label=Ingen Etikett
+issues.new.no_label=Inga etiketter
issues.new.clear_labels=Rensa etiketter
issues.new.projects=Projekt
issues.new.clear_projects=Rensa projekt
@@ -855,26 +1009,26 @@ issues.new.open_projects=รppna projekt
issues.new.closed_projects=Stรคngda projekt
issues.new.no_items=Inga objekt
issues.new.milestone=Milsten
-issues.new.no_milestone=Ingen Milsten
+issues.new.no_milestone=Ingen milstolpe
issues.new.clear_milestone=Rensa milstenar
-issues.new.open_milestone=รppna Milstenar
-issues.new.closed_milestone=Stรคngda Milstenar
+issues.new.open_milestone=รppna milstolpar
+issues.new.closed_milestone=Stรคngda milstolpar
issues.new.assignees=Tilldelade
issues.new.clear_assignees=Rensa tilldelade
-issues.new.no_assignees=Ingen tilldelad
+issues.new.no_assignees=Inga tilldelade
issues.new.no_reviewers=Inga granskare
issues.choose.get_started=Kom igรฅng
issues.choose.open_external_link=รppna
issues.choose.blank=Standard
issues.choose.blank_about=Skapa ett รคrende frรฅn standardmall.
-issues.no_ref=Ingen Branch/Tag specificerad
-issues.create=Skapa รrende
+issues.no_ref=Ingen gren/etikett specificerad
+issues.create=Skapa รคrende
issues.new_label=Ny etikett
issues.new_label_placeholder=Etikettsnamn
issues.new_label_desc_placeholder=Beskrivning
-issues.create_label=Skapa Etikett
+issues.create_label=Skapa etikett
issues.label_templates.title=Ladda en fรถrdefinierad uppsรคttning etiketter
-issues.label_templates.info=Inga etiketter finns รคnnu. Skapa en etikett med 'Ny etikett' eller anvรคnd fรถrdefinierade etiketter:
+issues.label_templates.info=Inga etiketter finns รคnnu. Skapa en etikett med "Ny etikett" eller anvรคnd fรถrdefinierade etiketter:
issues.label_templates.helper=Markera en uppsรคttning etiketter
issues.label_templates.use=Anvรคnd etikettsamling
issues.add_milestone_at=`lade till denna till milstolpe %s %s`
@@ -934,20 +1088,20 @@ issues.commented_at=`kommenterad %s `
issues.delete_comment_confirm=รr du sรคker pรฅ att du vill ta bort den hรคr kommentaren?
issues.context.copy_link=Kopiera lรคnk
issues.context.quote_reply=Citerat svar
-issues.context.reference_issue=Referens i nytt รคrende
+issues.context.reference_issue=Hรคnvisa till i nytt รคrende
issues.context.edit=Redigera
issues.context.delete=Ta bort
-issues.close_comment_issue=Kommentera och stรคng
+issues.close_comment_issue=Stรคng med kommentar
issues.reopen_issue=ร
terรถppna
-issues.reopen_comment_issue=Kommentera och รฅterรถppna
+issues.reopen_comment_issue=รppna igen med kommentar
issues.create_comment=Kommentera
issues.closed_at=`stรคngde รคrendet %[2]s `
issues.reopened_at=`รฅterรถppnade detta รคrende %[2]s `
issues.commit_ref_at=`refererade till detta รคrende frรฅn en incheckning %[2]s `
issues.ref_issue_from=`refererade till detta รคrende %[4]s %[2]s `
issues.ref_pull_from=`refererade till denna pull-fรถrfrรฅgan %[4]s %[2]s `
-issues.ref_closing_from=`refererade till en pull-fรถrfrรฅgan %[4]s som kommer att stรคnga detta รคrende %[2]s `
-issues.ref_reopening_from=`refererade till en pull-fรถrfrรฅgan %[4]s som kommer att รถppna รคrendet pรฅ nytt %[2]s `
+issues.ref_closing_from=`hรคnvisade till detta รคrende frรฅn en pull-fรถrfrรฅgan %[4]s som kommer att stรคnga det %[2]s `
+issues.ref_reopening_from=`hรคnvisade till detta รคrende frรฅn en pull-fรถrfrรฅgan %[4]s som kommer att รถppna รคrendet pรฅ nytt %[2]s `
issues.ref_closed_from=`stรคngde detta รคrende %[4]s %[2]s `
issues.ref_reopened_from=`รถpnnade detta รคrende igen %[4]s %[2]s `
issues.ref_from=`frรฅn %[1]s`
@@ -986,11 +1140,11 @@ issues.lock.unknown_reason=Kan inte lรฅsa รคrende utan angiven anledning.
issues.lock_duplicate=Ett รคrende kan inte lรฅsas tvรฅ gรฅnger.
issues.unlock_error=Kan inte lรฅsa upp ett olรฅst รคrende.
issues.lock_with_reason=lรฅst som %s och begrรคnsad konversation till medarbetare %s
-issues.lock_no_reason=lรฅst och begrรคnsat konversation till kollaboratรถrer %s
+issues.lock_no_reason=lรฅst och begrรคnsat konversation till medarbetare %s
issues.unlock_comment=lรฅs upp denna konversation %s
issues.lock_confirm=Lรฅs
issues.unlock_confirm=Lรฅs upp
-issues.lock.notice_1=- Andra anvรคndare kan inte kommentera detta รคrende.
+issues.lock.notice_1=- Andra anvรคndare kan inte kommentera pรฅ detta รคrende.
issues.lock.notice_2=- Du och andra kollaboratรถrer med tillgรฅng till denna utvecklingskatalog kan fortfarande skriva kommentarer som andra kan se.
issues.lock.notice_3=- Du kan alltid lรฅsa upp detta รคrende senare.
issues.unlock.notice_1=- Alla kommer kunna kommentera detta รคrende en gรฅng till.
@@ -1016,7 +1170,7 @@ issues.del_time_history=`raderade tillbringad tid %s`
issues.add_time_hours=Timmar
issues.add_time_minutes=Minuter
issues.add_time_sum_to_small=Inge tid har angivits.
-issues.time_spent_total=Total Tid Spenderad
+issues.time_spent_total=Total tid spenderad
issues.time_spent_from_all_authors=`Total Tid Spenderad: %s`
issues.due_date=Fรถrfallodatum
issues.invalid_due_date_format=Datumsformatet fรถr fรถrfallodatum mรฅste fรถlja 'yyyy-MM-dd'.
@@ -1033,7 +1187,7 @@ issues.due_date_not_set=Inget fรถrfallodatum satt.
issues.due_date_added=lade till fรถrfallodatumet %s %s
issues.due_date_remove=tog bort fรถrfallodatumet %s %s
issues.due_date_overdue=Fรถrsenad
-issues.due_date_invalid=Fรถrfallodatumet รคr ogiltigt eller utanfรถr grรคnserna. Anvรคnd formatet 'รฅรฅรฅรฅ-mm-dd'.
+issues.due_date_invalid=Fรถrfallodatumet รคr ogiltigt eller utanfรถr grรคnserna. Anvรคnd formatet "รฅรฅรฅรฅ-mm-dd".
issues.dependency.title=Beroenden
issues.dependency.add=Lรคgg till beroendeโฆ
issues.dependency.cancel=Avbryt
@@ -1063,10 +1217,10 @@ issues.review.approve=godkรคnde dessa รคndringar %s
issues.review.comment=granskad av %s
issues.review.left_comment=lรคmnade en kommentar
issues.review.content.empty=Du mรฅste skriva en kommentar som anger de รถnskade รคndringarna.
-issues.review.reject=begรคrda รคndringar %s
-issues.review.wait=begรคrdes fรถr granskning %s
-issues.review.add_review_request=begรคrde granskning frรฅn %s %s
-issues.review.remove_review_request=tog bort granskningsbegรคran fรถr %s %s
+issues.review.reject=efterfrรฅgade รคndringar %s
+issues.review.wait=efterfrรฅgades fรถr granskning %s
+issues.review.add_review_request=efterfrรฅgade granskning frรฅn %[1]s %[2]s
+issues.review.remove_review_request=tog bort granskningsfรถrfrรฅgan fรถr %[1]s %[2]s
issues.review.remove_review_request_self=vรคgrade att granska %s
issues.review.pending=Vรคntande
issues.review.review=Granska
@@ -1082,21 +1236,21 @@ issues.content_history.options=Alternativ
pulls.desc=Aktivera pull-fรถrfrรฅgningar och kodgranskning.
-pulls.new=Ny Pull-Fรถrfrรฅgan
-pulls.compare_changes=Ny Pull-Request
+pulls.new=Ny pull-fรถrfrรฅgan
+pulls.compare_changes=Ny pull-fรถrfrรฅgan
pulls.compare_changes_desc=Vรคlj branchen att merga in i, och ifrรฅn.
pulls.compare_base=merga in i
pulls.compare_compare=pulla frรฅn
pulls.filter_branch=Filtrera gren
pulls.no_results=Inga resultat hittades.
pulls.nothing_to_compare=Dessa brancher รคr ekvivalenta. Det finns ingen anledning att skapa en pull-request.
-pulls.create=Skapa Pullfรถrfrรฅgan
-pulls.title_desc_few=vill sammanfoga %[1]d incheckningar frรฅn s[2]s
in i %[3]s
+pulls.create=Skapa pull-fรถrfrรฅgan
+pulls.title_desc_few=vill sammanfoga %[1]d incheckningar frรฅn s[2]s
in i %[3]s
pulls.merged_title_desc_few=sammanfogade %[1]d incheckningar frรฅn %[2]s
in i %[3]s
%[4]s
pulls.change_target_branch_at=`รคndrade mรฅl-branch frรฅn %s till %s %s`
pulls.tab_conversation=Konversation
pulls.tab_commits=Incheckningar
-pulls.tab_files=รndrade Filer
+pulls.tab_files=รndrade filer
pulls.reopen_to_merge=Vรคnligen รฅterรถppna denna Pull-fรถrfrรฅgan igen fรถr att utfรถra sammanfogningen.
pulls.cant_reopen_deleted_branch=Denna pull-fรถrfrรฅgan kan inte รถppnas igen eftersom branchen tagits bort.
pulls.merged=Sammanfogat
@@ -1133,12 +1287,12 @@ milestones.no_due_date=Inget fรถrfallodatum
milestones.open=รppna
milestones.close=Stรคng
milestones.completeness=%d%% Slutfรถrd
-milestones.create=Skapa Milstolpe
+milestones.create=Skapa milstolpe
milestones.title=Titel
milestones.desc=Beskrivning
milestones.due_date=Fรถrfallodatum (valfritt)
milestones.clear=Rensa
-milestones.invalid_due_date_format=Fรถrfallodatumsformatet mรฅste vara 'yyyy-MM-dd'.
+milestones.invalid_due_date_format=Fรถrfallodatumsformatet mรฅste vara "รฅรฅรฅรฅ-mm-dd".
milestones.edit=Redigera milstolpe
milestones.edit_subheader=Milstolpar organiserar รคrenden och fรถljer utvecklingens fortskridande.
milestones.cancel=Avbryt
@@ -1166,7 +1320,7 @@ wiki.default_commit_message=Skriv en anteckning om den hรคr uppdateringen (valfr
wiki.save_page=Spara sidan
wiki.last_commit_info=%s redigerade denna sida %s
wiki.edit_page_button=Redigera
-wiki.new_page_button=Ny Sida
+wiki.new_page_button=Ny sida
wiki.back_to_wiki=Tillbaka till wikisidan
wiki.delete_page_button=Tag bort sida
wiki.page_already_exists=Wiki-sida med samma namn finns redan.
@@ -1183,39 +1337,39 @@ activity.period.quarterly=3 mรฅnader
activity.period.semiyearly=6 mรฅnader
activity.period.yearly=1 รฅr
activity.overview=รversikt
-activity.active_prs_count_1=%d Aktiv Pull begรคran
-activity.active_prs_count_n=%d Aktiva Pull begรคrelser
+activity.active_prs_count_1=%d aktiv pull-fรถrfrรฅgan
+activity.active_prs_count_n=%d aktiva pull-fรถrfrรฅgningar
activity.merged_prs_count_1=Sammanfogad Pull-fรถrfrรฅgan
activity.merged_prs_count_n=Sammanfogade Pull-fรถrfrรฅgningar
-activity.opened_prs_count_1=Fรถreslagen Pull begรคran
-activity.opened_prs_count_n=Fรถreslagna Pull-fรถrfrรฅgningar
+activity.opened_prs_count_1=Fรถreslagen pull-fรถrfrรฅgan
+activity.opened_prs_count_n=Fรถreslagna pull-fรถrfrรฅgningar
activity.title.user_1=%d anvรคndare
activity.title.user_n=%d anvรคndare
-activity.title.prs_1=%d Pull-begรคran
-activity.title.prs_n=%d Pull begรคrelser
+activity.title.prs_1=%d pull-fรถrfrรฅgningar
+activity.title.prs_n=%d pull-fรถrfrรฅgningar
activity.title.prs_merged_by=%s sammanfogad av %s
activity.title.prs_opened_by=%s fรถreslรฅs av %s
activity.merged_prs_label=Sammanfogad
activity.opened_prs_label=Fรถreslagen
-activity.active_issues_count_1=%d Aktivt รคrende
-activity.active_issues_count_n=%d Aktiva รคrenden
+activity.active_issues_count_1=%d aktivt รคrende
+activity.active_issues_count_n=%d aktiva รคrenden
activity.closed_issues_count_1=Stรคngt รคrende
activity.closed_issues_count_n=Stรคngda รคrenden
activity.title.issues_1=%d รคrende
-activity.title.issues_n=%d รrenden
+activity.title.issues_n=%d รคrenden
activity.title.issues_created_by=%s skapad av %s
activity.closed_issue_label=Stรคngd
activity.new_issues_count_1=Nytt รคrende
activity.new_issues_count_n=Nya รคrenden
activity.new_issue_label=รppnad
-activity.title.unresolved_conv_1=%d Olรถst konversation
-activity.title.unresolved_conv_n=%d Olรถsta konversationer
+activity.title.unresolved_conv_1=%d olรถst konversation
+activity.title.unresolved_conv_n=%d olรถsta konversationer
activity.unresolved_conv_desc=De nyligen fรถrรคndrade รคrendena och pull-requesterna har inte blivit lรถsta รคnnu.
activity.unresolved_conv_label=รppna
-activity.title.releases_1=%d release
-activity.title.releases_n=%d releaser
+activity.title.releases_1=%d utgรฅva
+activity.title.releases_n=%d utgรฅvor
activity.title.releases_published_by=%s publicerad av %s
-activity.published_release_label=Publicerad
+activity.published_release_label=Utgรฅva
activity.no_git_activity=Det har inte gjorts nรฅgra commit under den hรคr perioden.
activity.git_stats_exclude_merges=Exkludera merger,
activity.git_stats_author_1=%d fรถrfattare
@@ -1255,34 +1409,34 @@ settings.mirror_settings=Instรคllningar fรถr spegling
settings.sync_mirror=Synkronisera nu
settings.site=Webbplats
-settings.update_settings=Uppdatera instรคllningar
-settings.advanced_settings=Advancerade Instรคllningar
+settings.update_settings=Spara instรคllningar
+settings.advanced_settings=Avancerade Instรคllningar
settings.wiki_desc=Aktivera wiki fรถr utvecklingskatalog
-settings.use_internal_wiki=Anvรคnd inbyggd Wiki
-settings.use_external_wiki=Anvรคnd extern Wiki
-settings.external_wiki_url=Extern Wiki-URL
+settings.use_internal_wiki=Anvรคnd inbyggd wiki
+settings.use_external_wiki=Anvรคnd extern wiki
+settings.external_wiki_url=URL till extern wiki
settings.external_wiki_url_error=Den externa wiki-lรคnken รคr inte giltig.
settings.external_wiki_url_desc=Besรถkare omdirigeras till den externa wiki-lรคnken nรคr de trycker pรฅ wiki-tabben.
settings.issues_desc=Aktivera รคrendehantering fรถr utvecklingskatalogen
settings.use_internal_issue_tracker=Anvรคnd inbyggt รคrendehanteringssystem
settings.use_external_issue_tracker=Anvรคnd externt รคrendehanteringssystem
-settings.external_tracker_url=URL Fรถr Extern รrendehanterare
+settings.external_tracker_url=URL fรถr externt รคrendehanteringssystem
settings.external_tracker_url_error=Lรคnken fรถr รคrendehanteringsystemet รคr inte en giltig lรคnk.
settings.external_tracker_url_desc=Besรถkare dirigeras om till lรคnken fรถr det externa รคrendehanteringssystemet nรคr de trycker pรฅ รคrende-tabben.
-settings.tracker_url_format=URL-Format Fรถr Extern รrendehanterare
+settings.tracker_url_format=URL-format fรถr externt รคrendehanteringssystem
settings.tracker_url_format_error=URL-formatet fรถr den extern รคrendehanterare รคr inte en giltig URL.
-settings.tracker_issue_style=Externt รคrendenummersformat
+settings.tracker_issue_style=Externt รคrendenummerformat
settings.tracker_issue_style.numeric=Numerisk
settings.tracker_issue_style.alphanumeric=Alfanumerisk
settings.tracker_url_format_desc=Anvรคnd variablerna {user}
, {repo}
och {index}
fรถr anvรคndarnamn, utvecklingskatalogsnamn och รคrenderegister.
settings.enable_timetracker=Aktivera tidsredovisning
-settings.allow_only_contributors_to_track_time=Lรฅt endast medarbetare spรฅra tidsredovisning
-settings.pulls_desc=Aktivera Pull Requests fรถr utvecklingskatalog
+settings.allow_only_contributors_to_track_time=Lรฅt endast medarbetare spรฅra tid
+settings.pulls_desc=Aktivera pull-fรถrfrรฅgningar fรถr utvecklingskatalog
settings.pulls.ignore_whitespace=Ignorera blanksteg vid konflikter
settings.admin_settings=Administratรถrsinstรคllningar
settings.admin_enable_health_check=Aktivera hรคlsokontroll fรถr utvecklingskataloger (git fsck)
settings.admin_enable_close_issues_via_commit_in_any_branch=Stรคng ett รคrende via en commit gjord i en icke standard-gren
-settings.danger_zone=Hรถgrisksomrรฅde
+settings.danger_zone=Farozon
settings.new_owner_has_same_repo=Den nya รคgaren har redan ett repo med det namnet. Vรคnligen vรคlj ett annat namn.
settings.convert=Konvertera till vanlig utvecklingskatalog
settings.convert_desc=Du kan konvertera denna spegling till en vanlig utvecklingskatalog. Detta kan ej รฅngras.
@@ -1296,15 +1450,15 @@ settings.transfer_desc=รverfรถr denna utvecklingskatalog till en anvรคndare ell
settings.transfer_form_title=Ange utvecklingskatalogens namn fรถr att bekrรคfta:
settings.transfer_notices_1=- Du kommer fรถrlora รฅtkomst till denna utvecklingskatalog om du fรถr รถver den till en individuell anvรคndare.
settings.transfer_notices_2=- Du kommer behรฅlla รฅtkomst till utvecklingskatalogen om du fรถr รถver den till en organisation som du antingen รคger eller รคr delรคgare i.
-settings.transfer_owner=Ny รgare
+settings.transfer_owner=Ny รคgare
settings.transfer_succeed=Utvecklingskatalogen har flyttats รถver.
settings.trust_model.collaborator=Medarbetare
-settings.wiki_delete=Ta bort wiki-data
+settings.wiki_delete=Ta bort wikidata
settings.wiki_delete_desc=Borttagning av utvecklingskatalogens wiki-data รคr permanent och kan ej รฅngras.
settings.wiki_delete_notices_1=- Detta kommer permanent ta bort och inaktivera utvecklingskatalogens wiki fรถr %s.
-settings.confirm_wiki_delete=Ta bort wiki-data
+settings.confirm_wiki_delete=Ta bort wikidata
settings.wiki_deletion_success=Utvecklingskatalogens wiki-data har blivit borttaget.
-settings.delete=Ta Bort Detta Repo
+settings.delete=Ta bort denna utvecklingskatalog
settings.delete_desc=Borttagning av en utvecklingskatalog รคr permanent och kan ej รฅngras.
settings.delete_notices_1=- Denna รฅtgรคrd kan INTE รฅngras.
settings.delete_notices_2=- Denna รฅtgรคrd kommer permanent ta bort utvecklingskatalogen %s inklusive kod, รคrenden, kommentarer, wiki-data samt medarbetarinstรคllningar.
@@ -1327,12 +1481,12 @@ settings.teams=Grupper
settings.add_team_duplicate=Teamet har redan utvecklingskatalogen
settings.add_team_success=Teamet har nu tillgรฅng till utvecklingskatalogen.
settings.remove_team_success=Teamets รฅtkomst till utvecklingskatalogen har tagits bort.
-settings.add_webhook=Lรคgg Till Webbhook
+settings.add_webhook=Lรคgg till webbhook
settings.hooks_desc=Webhooks gรถr automatiskt ett HTTP POST anrop mot en server nรคr vissa Forgejo events triggas. Lรคs mer om detta i webhooks guiden .
-settings.webhook_deletion=Ta bort Webhook
+settings.webhook_deletion=Ta bort webbhook
settings.webhook_deletion_desc=Borttagning utav en webhook tar รคven bort dess instรคllningar och leveranshistorik. Vill du fortsรคtta?
settings.webhook_deletion_success=Webhooken har blivit borttagen.
-settings.webhook.test_delivery=Testa Leverans
+settings.webhook.test_delivery=Testa leverans
settings.webhook.test_delivery_desc=Testa webhooken genom ett testevent.
settings.webhook.request=Begรคran
settings.webhook.response=Svar
@@ -1343,19 +1497,19 @@ settings.githook_edit_desc=Om kroken รคr inaktiv visas exempelinnehรฅll. Inaktiv
settings.githook_name=Kroknamn
settings.githook_content=Krokinnehรฅll
settings.update_githook=Uppdatera krok
-settings.add_webhook_desc=Forgejo kommer skicka ett POST
anrop med en specificerad Content-Type till mรฅladressen. Lรคs mer om detta i webhook guiden .
+settings.add_webhook_desc=Forgejo kommer skicka ett POST
anrop med en specificerad Content-Type till mรฅladressen. Lรคs mer om detta i webhook-guiden .
settings.payload_url=Mรฅl-URL
settings.http_method=HTTP-metod
-settings.content_type=POST Content Type
+settings.content_type=POST content type
settings.secret=Hemlighet
settings.slack_username=Anvรคndarnamn
settings.slack_icon_url=URL fรถr ikon
settings.discord_username=Anvรคndarnamn
settings.discord_icon_url=URL fรถr ikon
settings.event_desc=Trigga vid:
-settings.event_push_only=Push Events
-settings.event_send_everything=Alla events
-settings.event_choose=Anpassade eventsโฆ
+settings.event_push_only=Push-hรคndelser
+settings.event_send_everything=Alla hรคndelser
+settings.event_choose=Anpassade hรคndelserโฆ
settings.event_header_repository=Hรคndelser i utvecklingskatalogen
settings.event_create=Skapa
settings.event_create_desc=Branch eller tagg skapad.
@@ -1395,62 +1549,62 @@ settings.title=Titel
settings.deploy_key_content=Innehรฅll
settings.key_been_used=En distributionsnyckel med identiskt innehรฅller anvรคnds redan.
settings.key_name_used=En distributionsnyckel med samma namn finns redan.
-settings.deploy_key_deletion=Ta bort distributionsnyckel
+settings.deploy_key_deletion=Ta bort driftsรคttningsnyckel
settings.deploy_key_deletion_desc=Borttagning utav en distributionsnyckel kommer att รฅterkalla dess รฅtkomst till utvecklingskatalogen. Vill du fortsรคtta?
settings.deploy_key_deletion_success=Distributionsnyckeln har blivit borttagen.
settings.branches=Brancher
-settings.protected_branch=Branchskydd
+settings.protected_branch=Grenskydd
settings.protected_branch_can_push=Tillรฅt push?
settings.protected_branch_can_push_yes=Du kan pusha
settings.protected_branch_can_push_no=Du kan inte pusha
-settings.branch_protection=Branchskydd fรถr '%s '
+settings.branch_protection=Skyddsregler fรถr gren "%s "
settings.protect_this_branch=Aktivera branchskydd
-settings.protect_disable_push=Inaktivera Push
+settings.protect_disable_push=Inaktivera push
settings.protect_disable_push_desc=Inga push-fรถrfrรฅgningar kommer att tillรฅtas till denna branch.
-settings.protect_enable_push=Aktivera Push
+settings.protect_enable_push=Aktivera push
settings.protect_enable_push_desc=Alla med skrivrรคttigheter kommer att kunna pusha till denna branch (men inte force-pusha).
settings.protect_whitelist_deploy_keys=Vitlista deploy-nyckar med skrivรฅtkomst till push.
-settings.protect_whitelist_users=Vitlistade anvรคndare fรถr pushning:
+settings.protect_whitelist_users=Vitlistade anvรคndare fรถr pushning
settings.protect_whitelist_search_users=Sรถk anvรคndareโฆ
-settings.protect_whitelist_teams=Vitlistade team fรถr pushning:
+settings.protect_whitelist_teams=Vitlistade team fรถr pushning
settings.protect_whitelist_search_teams=Sรถk teamโฆ
settings.protect_merge_whitelist_committers=Aktivera vitlista fรถr sammanfogning
settings.protect_merge_whitelist_committers_desc=Tillรฅt endast vitlistade anvรคndare eller team att sammanfoga pull requests i denna branch.
-settings.protect_merge_whitelist_users=Vitlistade anvรคndare fรถr sammanfogning:
-settings.protect_merge_whitelist_teams=Vitlistade teams fรถr sammanfogning:
+settings.protect_merge_whitelist_users=Vitlistade anvรคndare fรถr sammanfogning
+settings.protect_merge_whitelist_teams=Vitlistade teams fรถr sammanfogning
settings.protect_check_status_contexts=Aktivera statuskontroller
settings.protect_check_status_contexts_desc=Krรคv godkรคnda statuskontroller innan merge. Vรคlj vilka statuskontroller som godkรคnnas innan grenar kan slรฅs samman till en gren som matchar denna regel. Nรคr aktiverad, mรฅste committer fรถrst pushas till en annan gren, sedan mergas eller pushas direkt till en gren som matchar denna regel efter statuskontroll har har godkรคnnts. Om inga context vรคljs mรฅste den sista committen vara framgรฅngsrik oavsett context.
settings.protect_check_status_contexts_list=Statuskontroller funna under senaste veckan fรถr denna utvecklingskatalog
-settings.protect_required_approvals=Godkรคnnanden som krรคvs:
-settings.protect_approvals_whitelist_users=Vitlistade granskare:
-settings.protect_approvals_whitelist_teams=Vitlistade team fรถr granskning:
-settings.require_signed_commits=Krรคv signerade commits
+settings.protect_required_approvals=Godkรคnnanden som krรคvs
+settings.protect_approvals_whitelist_users=Vitlistade granskare
+settings.protect_approvals_whitelist_teams=Vitlistade team fรถr granskning
+settings.require_signed_commits=Krรคv signerade commiter
settings.require_signed_commits_desc=Avvisa pushar till den hรคr grenen om dom รคr osignerade eller inte verifierbara.
settings.add_protected_branch=Aktivera skydd
settings.delete_protected_branch=Inaktivera skydd
-settings.protected_branch_deletion=Inaktivera skydd fรถr branch
+settings.protected_branch_deletion=Inaktivera grenskydd
settings.protected_branch_deletion_desc=Genom att inaktivera branchskyddet tillรฅts anvรคndare med skrivrรคttigheter att pusha till branchen. Vill du fortsรคtta?
settings.default_branch_desc=Vรคlj en standard branch fรถr Pull Requests och Code Commits:
settings.choose_branch=Vรคlj en branchโฆ
settings.no_protected_branch=Det finns inga skyddade brancher.
settings.edit_protected_branch=รndra
settings.protected_branch_required_approvals_min=Antal erforderliga godkรคnnanden kan inte vara negativa.
-settings.bot_token=Bot Token
+settings.bot_token=Bottoken
settings.chat_id=Chatt-ID
settings.matrix.room_id=Rum-ID
settings.matrix.message_type=Typ av meddelande
-settings.archive.button=Arkivera fรถrrรฅd
-settings.archive.header=Arkivera detta fรถrrรฅd
+settings.archive.button=Arkivera utvecklingskatalog
+settings.archive.header=Arkivera denna utvecklingskatalog
settings.archive.success=Fรถrrรฅdet arkiverades.
settings.archive.error=Ett fel uppstod nรคr utvecklingskatalogen arkiverades. Se loggen fรถr fler detaljer.
settings.archive.error_ismirror=Du kan inte arkivera ett speglat fรถrrรฅd.
-settings.archive.branchsettings_unavailable=Instรคllningar fรถr grenar รคr inte tillgรคngliga om fรถrrรฅdet arkiverats.
+settings.archive.branchsettings_unavailable=Instรคllningar fรถr grenar รคr inte tillgรคngliga fรถr arkiverade utvecklingskataloger.
settings.update_avatar_success=Utvecklingskatalogens avatar har uppdaterats.
settings.lfs=LFS
settings.lfs_filelist=LFS filer lagrade i denna utvecklingskatalog
settings.lfs_no_lfs_files=Inga LFS filer รคr lagrade i denna utvecklingskatalog
settings.lfs_findcommits=Hitta commits
-settings.lfs_lfs_file_no_commits=Ingen commit hittad fรถr denna LFS fil
+settings.lfs_lfs_file_no_commits=Ingen commit hittad fรถr denna LFS-fil
settings.lfs_locks=Lรฅs
settings.lfs_invalid_locking_path=Ogiltig sรถkvรคg: %s
settings.lfs_invalid_lock_directory=Kan inte lรฅsa katalog: %s
@@ -1459,18 +1613,18 @@ settings.lfs_lock=Lรฅs
settings.lfs_lock_path=Filvรคg att lรฅsa...
settings.lfs_locks_no_locks=Inga lรฅs
settings.lfs_force_unlock=Tvinga upplรฅsning
-settings.lfs_pointers.sha=Blob SHA
+settings.lfs_pointers.sha=Blobhash
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=I utvecklingskatalogen
settings.rename_branch_failed_not_exist=Kan inte byta namn pรฅ branchen %s eftersom den inte finns.
-diff.browse_source=Blรคddra i kรคllkod
+diff.browse_source=Blรคddra kรคllkod
diff.parent=fรถrรคlder
diff.commit=incheckning
diff.git-notes=Anteckningar
-diff.data_not_available=Diff Content ej tillgรคnglig
-diff.show_split_view=Delad Vy
-diff.show_unified_view=Unifierad Vy
+diff.data_not_available=Diff-innehรฅll ej tillgรคnglig
+diff.show_split_view=Delad vy
+diff.show_unified_view=Unifierad vy
diff.whitespace_button=Blanksteg
diff.whitespace_show_everything=Visa alla รคndringar
diff.whitespace_ignore_all_whitespace=Ignorera blanksteg nรคr rader jรคmfรถrs
@@ -1486,12 +1640,12 @@ diff.file_image_height=Hรถjd
diff.file_byte_size=Storlek
diff.file_suppressed=Filskillnaden har hรฅllits tillbaka eftersom den รคr fรถr stor
diff.comment.placeholder=Lรคmna en kommentar
-diff.comment.markdown_info=Styling med markdown stรถds.
+diff.comment.markdown_info=Stilisering med Markdown stรถds.
diff.comment.add_single_comment=Lรคgg till en kommentar
diff.comment.add_review_comment=Lรคgg till kommentar
diff.comment.start_review=Starta granskning
diff.comment.reply=Svara
-diff.review=Granska
+diff.review=Slutfรถr granskning
diff.review.placeholder=Granskningskommentar
diff.review.comment=Kommentar
diff.review.approve=Godkรคnn
@@ -1500,12 +1654,12 @@ diff.committed_by=committad av
releases.desc=Fรถlj projektversioner och nerladdningar.
release.releases=Slรคpp
-release.new_release=Nytt Slรคpp
+release.new_release=Ny utgรฅva
release.draft=Utkast
-release.prerelease=Fรถrslรคpp
+release.prerelease=Fรถrutgรฅva
release.stable=Stabil
release.compare=Jรคmfรถr
-release.edit=redigera
+release.edit=Redigera
release.ahead.commits=%d committer
release.ahead.target=till %s sedan denna utgรฅva
release.source_code=Kรคllkod
@@ -1514,24 +1668,24 @@ release.edit_subheader=Releaser organiserar projektversioner.
release.tag_name=Taggnamn
release.target=Mรฅl
release.tag_helper=Vรคlj en existerande tagg eller skapa en ny tagg.
-release.prerelease_desc=Markera som en Pre-Release
+release.prerelease_desc=Markera som en fรถrutgรฅva
release.prerelease_helper=Markera denna Release olรคmpliga fรถr anvรคndning i produktion.
release.cancel=Avbryt
-release.publish=Publicera Slรคpp
-release.save_draft=Spara Utkast
-release.edit_release=Uppdatera Release
-release.delete_release=Ta bort Release
-release.deletion=Ta bort Release
+release.publish=Publicera utgรฅva
+release.save_draft=Spara utkast
+release.edit_release=Uppdatera utgรฅva
+release.delete_release=Ta bort utgรฅva
+release.deletion=Ta bort utgรฅva
release.deletion_success=Releasen har blivit raderad.
release.tag_name_already_exist=En release med denna tagg existerar redan.
release.tag_name_invalid=Taggnamnet รคr inte giltigt.
release.downloads=Nedladdningar
release.download_count=Nedladdningar: %s
-branch.name=Branch namn
+branch.name=Grennamn
branch.delete_head=Radera
-branch.delete_html=Radera branch
-branch.create_branch=Skapa branchen %s
+branch.delete_html=Ta borg gren
+branch.create_branch=Skapa branchen %s
branch.deleted_by=Raderad av %s
@@ -1539,6 +1693,7 @@ branch.deleted_by=Raderad av %s
topic.manage_topics=Hantera รคmnen
topic.done=Klar
topic.count_prompt=Du kan inte vรคlja fler รคn 25 รคmnen
+settings.enter_repo_name = Ange รคgar- och utvecklingskatalog-namnet exakt som det visas:
@@ -1546,7 +1701,7 @@ topic.count_prompt=Du kan inte vรคlja fler รคn 25 รคmnen
[org]
org_name_holder=Organisationsnamn
-org_full_name_holder=Organisationens Fullstรคndiga Namn
+org_full_name_holder=Fullstรคndigt organisationsnamn
org_name_helper=Organisationsnamn bรถr vara korta och enkla att komma ihรฅg.
create_org=Skapa organisation
repo_updated=Uppdaterad %s
@@ -1554,10 +1709,10 @@ members=Medlemmar
teams=Grupper
lower_members=medlemmar
lower_repositories=utvecklingskataloger
-create_new_team=Nytt Team
-create_team=Skapa Team
+create_new_team=Nytt lag
+create_team=Skapa lag
org_desc=Beskrivning
-team_name=Gruppnamn
+team_name=Lagnamn
team_desc=Beskrivning
team_name_helper=Teamnamn bรถr vara korta och lรคtta att komma ihรฅg.
team_desc_helper=Beskriv syftet eller rollen fรถr teamet.
@@ -1584,7 +1739,7 @@ settings.update_settings=Uppdatera instรคllningar
settings.update_setting_success=Organisationsinstรคllningarna har uppdaterats.
settings.update_avatar_success=Organisationens avatar har uppdateras.
settings.delete=Tag bort organisation
-settings.delete_account=Tag bort denna organisation
+settings.delete_account=Ta bort denna organisationen
settings.delete_prompt=Organisationen kommer tas bort permanent, och det gรฅr INTE att รฅngra detta!
settings.confirm_delete_account=Bekrรคfta borttagning
settings.delete_org_title=Ta bort organisation
@@ -1595,9 +1750,9 @@ settings.labels_desc=Lรคgg till etiketter som kan anvรคndas till รคrenden fรถr <
members.membership_visibility=Synlighet fรถr medlemskap:
members.public=Synlig
-members.public_helper=gรถr dold
+members.public_helper=Gรถr dold
members.private=Dold
-members.private_helper=gรถr synlig
+members.private_helper=Gรถr synlig
members.member_role=Medlemsroll:
members.owner=รgare
members.member=Medlem
@@ -1618,18 +1773,18 @@ teams.admin_access_helper=Medlemmar kan pulla och pusha till teamets utvecklings
teams.no_desc=Detta team har ingen beskrivning
teams.settings=Instรคllningar
teams.owners_permission_desc=รgare har full รฅtkomst till alla utvecklingskataloger och har administratรถrsรฅtkomst till organisationen.
-teams.members=Teammedlemmar
+teams.members=Lagmedlemmar
teams.update_settings=Uppdatera instรคllningar
-teams.delete_team=Ta bort team
-teams.add_team_member=Lรคgg till teammedlem
-teams.delete_team_title=Ta bort team
+teams.delete_team=Ta bort lag
+teams.add_team_member=Lรคgg till lagmedlem
+teams.delete_team_title=Ta bort lag
teams.delete_team_desc=Borttagning av ett team รฅterkallar รฅtkomsten till utvecklingskatalogen fรถr dess medlemmar. Vill du fortsรคtta?
teams.delete_team_success=Teamet har blivit borttaget.
teams.read_permission_desc=Medlemskap i detta team ger lรคsrรคttigheter : medlemmar kan se och klona teamets utvecklingskataloger.
teams.write_permission_desc=Medlemskap i detta team ger skrivrรคttigheter : medlemmar kan lรคsa och pusha till teamets utvecklingskataloger.
-teams.admin_permission_desc=Medlemskap i detta team ger administratรถrsrรคttigheter : medlemmar kan lรคsa, pusha och lรคgga till medarbetare till teamets utvecklingskataloger.
+teams.admin_permission_desc=Medlemskap i detta lag ger administratรถrsrรคttigheter : medlemmar kan lรคsa frรฅn, pusha till och lรคgga till medarbetare till lagets utvecklingskataloger.
teams.create_repo_permission_desc=Vidare sรฅ ger detta team Skapa utvecklingskatalog rรคttigheten: medlemmar can skapa nya utvecklingskataloger i organisationen.
-teams.repositories=Teamfรถrrรฅd
+teams.repositories=Lagets utvecklingskataloger
teams.search_repo_placeholder=Sรถk utvecklingskatalogโฆ
teams.remove_all_repos_title=Ta bort alla utvecklingskataloger fรถr teamet
teams.remove_all_repos_desc=Detta kommer att ta bort alla utvecklingskataloger frรฅn teamet.
@@ -1648,10 +1803,10 @@ teams.all_repositories_admin_permission_desc=Detta team beviljar Admin
[admin]
dashboard=Instrumentpanel
-users=Anvรคndarkonto
+users=Anvรคndarkonton
organizations=Organisationer
repositories=Utvecklingskataloger
-authentication=Autentiseringskรคlla
+authentication=Autentiseringskรคllor
config=Konfiguration
notices=Systemaviseringar
monitor=รvervakning
@@ -1661,7 +1816,7 @@ total=Totalt: %d
dashboard.statistic=รversikt
dashboard.operations=Operationer fรถr underhรฅll
-dashboard.system_status=Status
+dashboard.system_status=Systemstatus
dashboard.operation_name=Operationsnamn
dashboard.operation_switch=Byt till
dashboard.operation_run=Kรถr
@@ -1670,23 +1825,23 @@ dashboard.clean_unbind_oauth_success=Alla obundna OAuth anslutningar har raderat
dashboard.delete_missing_repos=Ta bort alla utvecklingskataloger som saknar filer specifika fรถr Git
dashboard.delete_generated_repository_avatars=Ta bort genererade avatarer fรถr utvecklingskatalogen
dashboard.git_gc_repos=Rensa skrรคpfiler pรฅ samtliga utvecklingskataloger
-dashboard.resync_all_hooks=ร
tersynkronisera pre-recieve, update och post-receive hooks fรถr alla utvecklingskataloger.
+dashboard.resync_all_hooks=ร
tersynkronisera pre-recieve, update och post-receive hooks fรถr alla utvecklingskataloger
dashboard.reinit_missing_repos=ร
terinitialisera alla saknade utvecklingskataloger som vi kรคnner till
dashboard.sync_external_users=Synkronisera extern anvรคndardata
dashboard.server_uptime=Serverns upptid
-dashboard.current_goroutine=Aktuella Goroutiner
-dashboard.current_memory_usage=Nuvarande Minnesanvรคndning
-dashboard.total_memory_allocated=Total Minnesanvรคndning
+dashboard.current_goroutine=Aktuella gorutiner
+dashboard.current_memory_usage=Nuvarande minnesanvรคndning
+dashboard.total_memory_allocated=Total minnesanvรคndning
dashboard.memory_obtained=Minnesรฅtgรฅng
dashboard.pointer_lookup_times=Pekaruppslagstider
dashboard.memory_allocate_times=Minneallokeringar
dashboard.memory_free_times=Minnesfrigรถrelser
-dashboard.current_heap_usage=Nuvarande Heap anvรคndning
-dashboard.heap_memory_obtained=Heap-minne som erhรฅllits
-dashboard.heap_memory_idle=Heap-minne som รคr inaktivt
-dashboard.heap_memory_in_use=Heap-minne som anvรคnds
-dashboard.heap_memory_released=Heap-minne som har slรคppts
-dashboard.heap_objects=Heap objekt
+dashboard.current_heap_usage=Nuvarande heapanvรคndning
+dashboard.heap_memory_obtained=Heapminne som erhรฅllits
+dashboard.heap_memory_idle=Heapminne som รคr inaktivt
+dashboard.heap_memory_in_use=Heapminne som anvรคnds
+dashboard.heap_memory_released=Heapminne som har slรคppts
+dashboard.heap_objects=Heapobjekt
dashboard.bootstrap_stack_usage=Bootstrap Stack-anvรคndning
dashboard.stack_memory_obtained=Stackminne som erhรฅlls
dashboard.mspan_structures_usage=MSpan strukturanvรคndning
@@ -1703,7 +1858,7 @@ dashboard.total_gc_pause=Total tid fรถr pauser vid skrรคpsamling
dashboard.last_gc_pause=Senaste paus vid skrรคpsamling
dashboard.gc_times=Skrรคpsamlingstider
-users.user_manage_panel=Hantering av anvรคndarkonton
+users.user_manage_panel=Hantera anvรคndarkonton
users.new_account=Skapa anvรคndarkonto
users.name=Anvรคndarnamn
users.full_name=Fullstรคndigt namn
@@ -1712,8 +1867,8 @@ users.admin=Administratรถr
users.repos=Utvecklingskataloger
users.created=Skapad
users.last_login=Senaste inloggning
-users.never_login=Aldrig varit inloggad
-users.send_register_notify=Skicka notifiering vid anvรคndarregistrering
+users.never_login=Aldrig loggat in
+users.send_register_notify=Notifiera om registrering via e-post
users.edit=Redigera
users.auth_source=Autentiseringskรคlla
users.local=Lokal
@@ -1723,10 +1878,10 @@ users.update_profile_success=Anvรคndarkontot har blivit uppdaterat.
users.edit_account=Redigera anvรคndarkontot
users.max_repo_creation=Maximalt antal utvecklingskataloger
users.max_repo_creation_desc=(Ange -1 fรถr att anvรคnda global satt grรคns.)
-users.is_activated=Anvรคndarkontot รคr aktiverat
-users.prohibit_login=Inaktivera inloggning
-users.is_admin=รr administratรถr
-users.allow_git_hook=Kan skapa Git hooks
+users.is_activated=Aktiverat konto
+users.prohibit_login=Avstรคngt konto
+users.is_admin=Administratรถrkonto
+users.allow_git_hook=Kan skapa Git-hooks
users.allow_import_local=Kan importera lokala utvecklingskataloger
users.allow_create_organization=Kan skapa organisationer
users.update_profile=Uppdatera anvรคndarkonto
@@ -1742,15 +1897,15 @@ emails.activated=Aktiverad
emails.filter_sort.email=E-post
emails.filter_sort.email_reverse=E-post (omvรคnd)
emails.filter_sort.name=Anvรคndarnamn
-emails.filter_sort.name_reverse=Anvรคndarnamn (omvรคnd)
+emails.filter_sort.name_reverse=Anvรคndarnamn (omvรคnt)
-orgs.org_manage_panel=Organisationshantering
+orgs.org_manage_panel=Hantera organisationer
orgs.name=Namn
orgs.teams=Team
orgs.members=Medlemmar
orgs.new_orga=Ny organisation
-repos.repo_manage_panel=Utvecklingskatalogshantering
+repos.repo_manage_panel=Hantera utvecklingskataloger
repos.owner=รgare
repos.name=Namn
repos.private=Privat
@@ -1769,7 +1924,7 @@ packages.size=Storlek
systemhooks=Systemets webbhooks
-auths.auth_manage_panel=Hantering av autentiseringkรคlla
+auths.auth_manage_panel=Hantera autentiseringkรคllor
auths.new=Lรคgg till autensieringskรคlla
auths.name=Namn
auths.type=Typ
@@ -1783,29 +1938,29 @@ auths.domain=Domรคn
auths.host=Vรคrd
auths.port=Port
auths.bind_dn=Bind DN
-auths.bind_password=Bind Lรถsenord
+auths.bind_password=Bind lรถsenord
auths.user_base=Anvรคndarsรถkbas
auths.user_dn=Anvรคndarnas DN
auths.attribute_username=Anvรคndarnamnsattribut
auths.attribute_username_placeholder=Lรคmna tomt om du vill anvรคnda det anvรคndarnamn som angivits i Forgejo.
auths.attribute_name=Fรถrnamnsattribut
auths.attribute_surname=Efternamnsattribut
-auths.attribute_mail=Mejlattribut
+auths.attribute_mail=E-postattribut
auths.attribute_ssh_public_key=Attribut fรถr offentlig SSH-nyckel
-auths.attributes_in_bind=Hรคmta attribut ur Bind DN Context
+auths.attributes_in_bind=Hรคmta attribut ur bind DN context
auths.use_paged_search=Anvรคnd paginerad sรถkning
auths.search_page_size=Sidstorlek
auths.filter=Anvรคndarfilter
auths.admin_filter=Administratรถrsfilter
auths.ms_ad_sa=MS AD sรถkattribut
-auths.smtp_auth=SMTP Autentiseringstyp
+auths.smtp_auth=SMTP autentiseringstyp
auths.smtphost=SMTP-server
auths.smtpport=SMTP-port
-auths.allowed_domains=Tillรฅtna Domรคner
-auths.allowed_domains_helper=Lรคmna tomt om du vill tillรฅta alla domรคner. Separera flera domรคner med ett kommatecken (',').
-auths.skip_tls_verify=Skippa verifikation av TLS
-auths.pam_service_name=PAM Tjรคnstnamn
-auths.oauth2_provider=OAuth2 leverantรถr
+auths.allowed_domains=Tillรฅtna domรคner
+auths.allowed_domains_helper=Lรคmna tomt om du vill tillรฅta alla domรคner. Separera flera domรคner med ett kommatecken (",").
+auths.skip_tls_verify=Skippa TLS-verifikation
+auths.pam_service_name=PAM-tjรคnstnamn
+auths.oauth2_provider=OAuth2-leverantรถr
auths.oauth2_clientID=Klient ID (Nyckel)
auths.oauth2_clientSecret=Klienthemlighet
auths.openIdConnectAutoDiscoveryURL=OpenID Connect Auto Discovery lรคnk
@@ -1816,51 +1971,51 @@ auths.oauth2_profileURL=Profil-URL
auths.oauth2_emailURL=E-post URL
auths.enable_auto_register=Aktivera Automatisk Registrering
auths.tips=Tips
-auths.tips.oauth2.general=OAuth2 Autensiering
-auths.tip.oauth2_provider=OAuth2 leverantรถr
-auths.tip.bitbucket=Registrera en ny OAuth konsument pรฅ https://bitbucket.org/account/user//oauth-consumers/new och lรคgg till behรถrighet 'Account' - 'Read'
-auths.tip.dropbox=Skapa en ny applikation pรฅ https://www.dropbox.com/developers/apps
-auths.tip.facebook=Registrera en ny appliaktion pรฅ https://developers.facebook.com/apps och lรคgg till produkten โFacebook-inloggningโ
-auths.tip.github=Registrera en ny OAuth applikation pรฅ https://github.com/settings/applications/new
+auths.tips.oauth2.general=OAuth2-autensiering
+auths.tip.oauth2_provider=OAuth2-leverantรถr
+auths.tip.bitbucket=Registrera en ny OAuth konsument pรฅ %s
+auths.tip.dropbox=Skapa en ny applikation pรฅ %s
+auths.tip.facebook=Registrera en ny appliaktion pรฅ %s och lรคgg till produkten โFacebook-inloggningโ
+auths.tip.github=Registrera en ny OAuth applikation pรฅ %s
auths.tip.gitlab=Registrera en ny applikation pรฅ https://gitlab.com/profile/applications
-auths.tip.google_plus=Erhรฅll inloggningsuppgifter fรถr OAuth2 frรฅn Google API-konsolen pรฅ https://console.developers.google.com/
+auths.tip.google_plus=Erhรฅll inloggningsuppgifter fรถr OAuth2 frรฅn Google API-konsolen pรฅ %s
auths.tip.openid_connect=Anvรคnd OpenID Connect Discovery lรคnken (/.well-known/openid-configuration) fรถr att ange slutpunkterna
-auths.tip.twitter=Gรฅ till https://dev.twitter.com/app, skapa en applikation och fรถrsรคkra att alternativet "Allow this application to be used to Sign in with Twitter" รคr aktiverat
-auths.tip.discord=Registrera en ny applikation pรฅ https://discordapp.com/developers/applications/me
-auths.edit=Redigera autensieringskรคlla
+auths.tip.twitter=Gรฅ till %s, skapa en applikation och fรถrsรคkra att alternativet "Allow this application to be used to Sign in with Twitter" รคr aktiverat
+auths.tip.discord=Registrera en ny applikation pรฅ %s
+auths.edit=Redigera autentiseringskรคlla
auths.activated=Denna autentiseringskรคlla รคr aktiverad
auths.update_success=Autentiseringskรคllan har uppdaterats.
-auths.update=Uppdatera autensieringskรคlla
+auths.update=Uppdatera autentiseringskรคlla
auths.delete=Ta bort autentiseringskรคlla
-auths.delete_auth_title=Tag bort denna autentisering
+auths.delete_auth_title=Tag bort autentiseringskรคlla
auths.delete_auth_desc=Borttagning av en autensieringskรคlla fรถrhindrar anvรคndare frรฅn att anvรคnda den fรถr inloggning. Vill du fortsรคtta?
auths.still_in_used=Autentiseringskรคllan รคr fortfarande i bruk. Konvertera eller ta bort alla anvรคndare som anvรคnder denna autentiseringskรคlla fรถrst.
auths.deletion_success=Autentiseringskรคllan har tagits bort.
-config.server_config=Server-konfiguration
-config.app_name=Sajtens namn
-config.app_ver=Forgejo Version
-config.app_url=Forgejo Bas-URL
-config.custom_conf=Konfigurationsfil
-config.offline_mode=Offlinelรคge
-config.disable_router_log=Avaktivera Router Loggning
-config.run_user=Kรถr som anvรคndarnamn
+config.server_config=Serverkonfiguration
+config.app_name=Instansnamn
+config.app_ver=Forgejo-version
+config.app_url=Bas-URL fรถr Forgejo
+config.custom_conf=Sรถkvรคg fรถr konfigurationsfil
+config.offline_mode=Lokalt lรคge
+config.disable_router_log=Inaktivera routerloggning
+config.run_user=Anvรคndare att kรถra som
config.run_mode=Exekveringslรคge
-config.git_version=Git version
+config.git_version=Git-version
config.repo_root_path=Rotsรถkvรคg fรถr utvecklingskatalog
-config.lfs_root_path=LFS Rotsรถkvรคg
+config.lfs_root_path=LFS rotsรถkvรคg
config.log_file_root_path=Sรถkvรคg fรถr loggar
-config.script_type=Script-typ
-config.reverse_auth_user=Motsatt autentiserings anvรคndare
+config.script_type=Skripttyp
+config.reverse_auth_user=Autentiseringsanvรคndare fรถr omvรคnd proxy
config.ssh_config=SSH-konfiguration
config.ssh_enabled=Aktiverad
-config.ssh_start_builtin_server=Anvรคnd inbyggd Server
+config.ssh_start_builtin_server=Anvรคnd inbyggd server
config.ssh_port=Port
config.ssh_listen_port=Lyssningsport
config.ssh_root_path=Rotsรถkvรคg
config.ssh_key_test_path=Testsรถkvรคg fรถr nyckel
-config.ssh_keygen_path=Sรถkvรคg fรถr nyckelgenerator ('ssh-keygen')
+config.ssh_keygen_path=Sรถkvรคg fรถr nyckelgenerator ("ssh-keygen")
config.ssh_minimum_key_size_check=Kontroll av minsta tillรฅtna nyckelstorlek
config.ssh_minimum_key_sizes=Minsta tillรฅtna nyckelstorlek
@@ -1876,48 +2031,48 @@ config.db_ssl_mode=SSL
config.db_path=Sรถkvรคg
config.service_config=Tjรคnstkonfiguration
-config.register_email_confirm=Krรคv mejlbekrรคftelse fรถr att registrera
+config.register_email_confirm=Krรคv e-postbekrรคftelse fรถr att registrera
config.disable_register=Inaktivera sjรคlvregistrering
config.enable_openid_signup=Aktivera sjรคlvregistrering genom OpenID
config.enable_openid_signin=Aktivera OpenID-inloggning
config.show_registration_button=Visa registreringsknapp
-config.require_sign_in_view=Krรคv inloggning fรถr att visa sidor
-config.mail_notify=Aktivera Mejlnotifikationer
+config.require_sign_in_view=Krรคv inloggning fรถr att visa innehรฅll
+config.mail_notify=Aktivera e-postnotiser
config.enable_captcha=Aktivera CAPTCHA
-config.active_code_lives=Aktivera livstid fรถr koder
-config.default_keep_email_private=Dรถlj mejladresser som standard
+config.active_code_lives=Livstid fรถr aktiveringskoder
+config.default_keep_email_private=Dรถlj e-postadresser som standard
config.default_allow_create_organization=Tillรฅt skapandet utav organisationer som standard
config.enable_timetracking=Aktivera tidsredovisning
-config.default_enable_timetracking=Aktivera tidredovisning som Standard
-config.default_allow_only_contributors_to_track_time=Lรฅt endast medarbetare spรฅra tidsredovisning
-config.no_reply_address=Dold mejldomรคn
+config.default_enable_timetracking=Aktivera tidredovisning som standard
+config.default_allow_only_contributors_to_track_time=Lรฅt endast bidragsgivare spรฅra tid
+config.no_reply_address=Dold e-postdomรคn
config.webhook_config=Webbkrokskonfiguration
config.queue_length=Kรถlรคngd
config.deliver_timeout=Tidsfrist fรถr leverans
-config.skip_tls_verify=Skippa TLS verifiering
+config.skip_tls_verify=Skippa TLS-verifiering
config.mailer_enabled=Aktiverad
config.mailer_name=Namn
config.mailer_smtp_port=SMTP-port
config.mailer_user=Anvรคndare
config.mailer_use_sendmail=Anvรคnd Sendmail
-config.mailer_sendmail_path=Sendmail sรถkvรคg
+config.mailer_sendmail_path=Sรถkvรคg fรถr sendmail
config.mailer_sendmail_args=Extra argument till sendmail
-config.send_test_mail=Skicka testmeddelande
+config.send_test_mail=Skicka testmejl
config.oauth_config=OAuth-konfiguration
config.oauth_enabled=Aktiverad
-config.cache_config=Mellanlagringskonfiguration
-config.cache_adapter=Mellanlagringsadapter
-config.cache_interval=Mellanlagringsintervall
-config.cache_conn=Mellanlagringsanslutning
+config.cache_config=Cachekonfiguration
+config.cache_adapter=Cacheadapter
+config.cache_interval=Cacheintervall
+config.cache_conn=Cacheanslutning
config.session_config=Sessionskonfiguration
config.session_provider=Sessionsleverantรถr
config.provider_config=Leverantรถrskonfiguration
-config.cookie_name=Cookie-namn
+config.cookie_name=Cookienamn
config.gc_interval_time=Tidsintervall fรถr skrรคpsamling
config.session_life_time=Livstid fรถr session
config.https_only=Endast HTTPS
@@ -1926,21 +2081,21 @@ config.cookie_life_time=Livstid fรถr kaka
config.picture_config=Konfiguration fรถr bild och avatar
config.picture_service=Bildtjรคnst
config.disable_gravatar=Inaktivera Gravatar
-config.enable_federated_avatar=Aktivera Fรถrenad Uppslaging av Profilbilder
+config.enable_federated_avatar=Aktivera federerade avatarer
config.git_config=Git-konfiguration
-config.git_disable_diff_highlight=Inaktivera Diff Syntax Highlight
-config.git_max_diff_lines=Max Diff-rader (per fil)
-config.git_max_diff_line_characters=Max Diff-tecken (per rad)
-config.git_max_diff_files=Max Diff-filer (att visa)
+config.git_disable_diff_highlight=Inaktivera syntaxmarkering i diffar
+config.git_max_diff_lines=Maximalt antal diff-rader per fil
+config.git_max_diff_line_characters=Maximalt antal diff-karaktรคrer per rad
+config.git_max_diff_files=Maximalt antal diff-filer att visa
config.git_gc_args=Skrรคpsamlarargument
config.git_migrate_timeout=Migreringstimeout
-config.git_mirror_timeout=Spelgingsuppdateringstimeout
-config.git_clone_timeout=Klonoperationstimeout
-config.git_pull_timeout=Klonoperationstimeout
-config.git_gc_timeout=GC-operationstimeout
+config.git_mirror_timeout=Tidsfrist fรถr spegeluppdatering
+config.git_clone_timeout=Tidsfrist fรถr kloning
+config.git_pull_timeout=Tidsfrist fรถr pull
+config.git_gc_timeout=Tidsfrist fรถr skrรคpsamling
-config.log_config=Logg-konfiguration
+config.log_config=Loggkonfiguration
config.disabled_logger=Inaktiverad
config.xorm_log_sql=Logga SQL
@@ -1967,18 +2122,26 @@ monitor.queue.settings.submit=Uppdatera instรคllningar
monitor.queue.settings.changed=Instรคllningar uppdaterade
notices.system_notice_list=Systemnotiser
-notices.view_detail_header=Visa notisdetaljer
-notices.select_all=Markera Alla
+notices.view_detail_header=Notisdetaljer
+notices.select_all=Markera alla
notices.deselect_all=Avmarkera alla
-notices.inverse_selection=Invertera Markeringar
-notices.delete_selected=Ta Bort Markerade
-notices.delete_all=Ta Bort Alla Notiser
+notices.inverse_selection=Invertera markeringar
+notices.delete_selected=Ta bort markerade
+notices.delete_all=Ta bort alla notiser
notices.type=Typ
notices.type_1=Utvecklingskatalog
notices.type_2=Uppgift
notices.desc=Beskrivning
notices.op=Op.
notices.delete_success=Systemnotifikationer har blivit raderade.
+users.2fa = 2FA
+users.reserved = Reserverad
+self_check.database_fix_mysql = Fรถr MySQL/MariaDB-anvรคndare sรฅ kan du anvรคnda kommandot โforgejo doctor convertโ fรถr att รฅtgรคrda problemet med kollateringen, eller sรฅ du รฅtgรคrda det genom att manuellt anvรคnda SQL "ALTER ... COLLATE ...".
+users.bot = Bott
+users.remote = Fjรคrrรฅtkomst
+users.restricted.description = Tillรฅt endast interaktion med utvecklingskataloger och organisationer dรคr den hรคr anvรคndaren finns tillagd som medarbetare. Det fรถrhindrar tillgรฅng till allmรคnna utvecklingskataloger i den hรคr instansen.
+users.is_restricted = Begrรคnsat konto
+self_check.database_inconsistent_collation_columns = Databasen anvรคnder kollateringen %s, men dessa kolumner anvรคnder felanpassade kollateringar. Det kan komma att orsaka ovรคntade problem.
[action]
@@ -1991,6 +2154,10 @@ compare_branch=Jรคmfรถr
compare_commits=Jรคmfรถr %d commits
compare_commits_general=Jรคmfรถr commits
mirror_sync_delete=synkade och raderade referens %[2]s
pรฅ %[3]s frรฅn spegel
+approve_pull_request = `godkรคnde %[3]s#%[2]s `
+create_branch = skapade grenen %[3]s i %[4]s
+starred_repo = stjรคrnmรคrkte %[2]s
+watched_repo = bรถrjade fรถlja %[2]s
[tool]
now=nu
@@ -2054,9 +2221,6 @@ owner.settings.cleanuprules.enabled=Aktiv
[secrets]
[actions]
-
-
-
runners.name=Namn
runners.owner_type=Typ
runners.description=Beskrivning
@@ -2073,6 +2237,39 @@ runs.commit=Commit
[projects]
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=Symbolisk lรคnk
+
+
+[search]
+milestone_kind = Sรถk milstolpar...
+exact = Exakt
+exact_tooltip = Inkludera bara resultat som exakt matchar sรถktermen
+repo_kind = Sรถk reponโฆ
+user_kind = Sรถk anvรคndareโฆ
+code_kind = Sรถk kod...
+package_kind = Sรถk paket...
+runner_kind = Sรถk exekutorer...
+branch_kind = Sรถk grenar...
+commit_kind = Sรถk commiter...
+project_kind = Sรถk projekt...
+search = Sรถkโฆ
+type_tooltip = Sรถktyp
+team_kind = Sรถk lag...
+org_kind = Sรถk organisationer...
+issue_kind = Sรถk รคrenden...
+regexp_tooltip = Tolka sรถktermen som ett reguljรคrt uttryck
+code_search_unavailable = Kodsรถkning รคr fรถr nรคrvarande inte tillgรคnglig. Vรคnligen kontakta webbplatsadministratรถren.
+fuzzy_tooltip = Inkludera resultat som รคr nรคrliggande till sรถktermen
+no_results = Inga matchande resultat hittades.
+code_search_by_git_grep = Nuvarande kodsรถkningsresultat gjordes med "git grep". Det kan finnas bรคttre resultat om webbplatsadministratรถren mรถjliggรถr indexering av kod.
+fuzzy = Ungefรคrlig
+union = Nyckelord
+union_tooltip = Inkludera resultat som matchar nรฅgot av de med mellanslag separerade sรถkorden
+pull_kind = Sรถk รคndringsfรถrslagโฆ
+regexp = RegExp
+keyword_search_unavailable = Sรถkning pรฅ nyckelord รคr fรถr nรคrvarande inte tillgรคngligt. Vรคnligen kontakta webbplatsadministratรถren.
+
+
+[translation_meta]
+test = Det hรคr รคr en teststrรคng. Den visas inte i Forgejo UI men anvรคnds vid testtillfรคlle. Vรคnligen skriv in "ok" fรถr att spara tid (eller en intressant fakta du sjรคlv vรคljer) fรถr att nรฅ upp till 100% komplett :)
\ No newline at end of file
diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini
index f3acf9e4da..fc13786cdd 100644
--- a/options/locale/locale_tr-TR.ini
+++ b/options/locale/locale_tr-TR.ini
@@ -17,10 +17,10 @@ page=Sayfa
template=ลablon
language=Dil
notifications=Bildirimler
-active_stopwatch=Etkin Zaman Takibi
+active_stopwatch=Etkin Zaman Takipรงisi
tracked_time_summary=Konu listesi sรผzgeรงlerine dayanan takip edilen zamanฤฑn รถzeti
create_new=Oluลturโฆ
-user_profile_and_more=Profil ve Ayarlarโฆ
+user_profile_and_more=Profil ve ayarlarโฆ
signed_in_as=Giriล yapan:
enable_javascript=Bu web sitesinin รงalฤฑลmasฤฑ iรงin JavaScript gereklidir.
toc=ฤฐรงindekiler Tablosu
@@ -28,12 +28,12 @@ licenses=Lisanslar
return_to_forgejo=Forgejo'ya Dรถn
username=Kullanฤฑcฤฑ Adฤฑ
-email=E-posta Adresi
+email=E-posta adresi
password=Parola
access_token=Eriลim Kodu
-re_type=Parolayฤฑ Doฤrula
+re_type=Parolayฤฑ doฤrula
captcha=CAPTCHA
-twofa=ฤฐki Aลamalฤฑ Doฤrulama
+twofa=ฤฐki aลamalฤฑ doฤrulama
twofa_scratch=ฤฐki aลamalฤฑ kazฤฑnmฤฑล kod
passcode=ลifre
@@ -56,13 +56,13 @@ organization=Organizasyon
mirror=Yansฤฑ
new_repo=Yeni Depo
new_migrate=Yeni Gรถรง
-new_mirror=Yeni Yansฤฑ
+new_mirror=Yeni yansฤฑma
new_fork=Yeni Depo รatalฤฑ
new_org=Yeni Organizasyon
-new_project=Yeni Proje
-new_project_column=Yeni Sรผtun
+new_project=Yeni proje
+new_project_column=Yeni sรผtun
manage_org=Organizasyonlarฤฑ Yรถnet
-admin_panel=Site Yรถnetimi
+admin_panel=Site yรถnetimi
account_settings=Hesap Ayarlarฤฑ
settings=Ayarlar
your_profile=Profil
@@ -76,7 +76,7 @@ collaborative=ฤฐลbirlikรงi
forks=รatallar
activities=Etkinlikler
-pull_requests=Deฤiลiklik ฤฐstekleri
+pull_requests=Deฤiลiklik istekleri
issues=Konular
milestones=Kilometre Taลlarฤฑ
@@ -87,9 +87,9 @@ rerun=Yeniden รงalฤฑลtฤฑr
rerun_all=Tรผm gรถrevleri yeniden รงalฤฑลtฤฑr
save=Kaydet
add=Ekle
-add_all=Tรผmรผnรผ Ekle
+add_all=Tรผmรผnรผ ekle
remove=Kaldฤฑr
-remove_all=Tรผmรผnรผ Kaldฤฑr
+remove_all=Tรผmรผnรผ kaldฤฑr
remove_label_str=`"%s" รถฤesini kaldฤฑr`
edit=Dรผzenle
view=Gรถrรผntรผle
@@ -112,13 +112,13 @@ preview=รnizleme
loading=Yรผkleniyorโฆ
error=Hata
-error404=Ulaลmaya รงalฤฑลtฤฑฤฤฑnฤฑz sayfa mevcut deฤil veya gรถrรผntรผleme yetkiniz yok .
+error404=Ulaลmaya รงalฤฑลtฤฑฤฤฑnฤฑz sayfa mevcut deฤil ,kaldฤฑrฤฑlmฤฑล veya gรถrรผntรผleme yetkiniz yok .
go_back=Geri Git
never=Asla
unknown=Bilinmiyor
-rss_feed=RSS Beslemesi
+rss_feed=RSS yayฤฑnฤฑ
pin=Sabitle
unpin=Sabitlemeyi kaldฤฑr
@@ -141,26 +141,38 @@ confirm_delete_selected=Tรผm seรงili รถฤeleri gerรงekten silmek istiyor musunuz
name=ฤฐsim
value=Deฤer
-copy_generic = Kopyala
+copy_generic = Panoya kopyala
filter = Filtrele
filter.not_archived = Arลivlenmemiล
filter.clear = Filtreleri Temizle
filter.is_archived = Arลivlenmiล
-filter.is_mirror = Yansฤฑlaลtฤฑrฤฑlmฤฑล
-filter.is_fork = รatallanmฤฑล
-filter.not_fork = รatallanmamฤฑล
+filter.is_mirror = Yansฤฑlar
+filter.is_fork = รatallar
+filter.not_fork = รatallanmayanlar
filter.not_mirror = Yansฤฑlanmamฤฑล
filter.is_template = ลablon
-filter.not_template = ลablon deฤil
+filter.not_template = ลablon olmayan
filter.public = Herkese aรงฤฑk
filter.private = Gizli
more_items = Daha fazla รถฤe
invalid_data = Geรงersiz veri: %v
+test = Test
+new_repo.title = Yeni depo
+new_org.title = Yeni organizasyon
+new_repo.link = Yeni depo
+new_org.link = Yeni organizasyon
+error413 = Kotanฤฑzฤฑ doldurdunuz.
+toggle_menu = Menรผyรผ aรง-kapa
+new_migrate.title = Yeni geรงiล
+new_migrate.link = Yeni geรงiล
+copy_path = Dizini kopyala
+
+confirm_delete_artifact = "%s" adlฤฑ รถฤeyi silmek istediฤinizden emin misiniz?
[aria]
-navbar=Gezinti รubuฤu
+navbar=Gezinti รงubuฤu
footer=Alt Bilgi
-footer.software=Yazฤฑlฤฑm Hakkฤฑnda
+footer.software=Bu yazฤฑlฤฑm hakkฤฑnda
footer.links=Baฤlantฤฑlar
[heatmap]
@@ -168,6 +180,8 @@ number_of_contributions_in_the_last_12_months=son 12 ayda %s katkฤฑ
contributions_zero=Katkฤฑ yapฤฑlmamฤฑล
less=Daha az
more=Daha Fazla
+contributions_one = katฤฑlฤฑm
+contributions_few = katฤฑlฤฑmlar
[editor]
buttons.heading.tooltip=Baลlฤฑk ekle
@@ -184,6 +198,12 @@ buttons.ref.tooltip=Bir konuya veya deฤiลiklik isteฤine deฤin
buttons.switch_to_legacy.tooltip=Eski dรผzenleyiciyi kullan
buttons.enable_monospace_font=Eลaralฤฑklฤฑ yazฤฑtipini etkinleลtir
buttons.disable_monospace_font=Eลaralฤฑklฤฑ yazฤฑtipini devre dฤฑลฤฑ bฤฑrak
+buttons.new_table.tooltip = Tablo ekle
+table_modal.header = Tablo ekle
+table_modal.placeholder.header = Baลlฤฑk
+table_modal.placeholder.content = ฤฐรงerik
+table_modal.label.rows = Satฤฑrlar
+table_modal.label.columns = Sรผtunlar
[filter]
string.asc=A - Z
@@ -191,34 +211,34 @@ string.desc=Z - A
[error]
occurred=Bir hata oluลtu
-report_message=Bunun bir Forgejo hatasฤฑ olduฤunu dรผลรผnรผyorsanฤฑz, lรผtfen GitHub sayfasฤฑnda sorunu arayฤฑn veya gerekiyorsa yeni bir sorun oluลturun.
+report_message=Bunun bir Forgejo hatasฤฑ olduฤunu dรผลรผnรผyorsanฤฑz, lรผtfen Codeberg sayfasฤฑnda sorunu arayฤฑn veya gerekiyorsa yeni bir sorun oluลturun.
missing_csrf=Hatalฤฑ ฤฐstek: CSRF anahtarฤฑ yok
invalid_csrf=Hatalฤฑ ฤฐstek: geรงersiz CSRF eriลim anahtarฤฑ
not_found=Hedef bulunamadฤฑ.
network_error=Aฤ hatasฤฑ
+server_internal = ฤฐรง sunucu hatasฤฑ
[startpage]
app_desc=Zahmetsiz, kendi sunucunuzda barฤฑndฤฑrabileceฤiniz Git servisi
install=Kurulumu kolay
-install_desc=Platformunuz iรงin ikili dosyayฤฑ รงalฤฑลtฤฑrฤฑn , Docker ile yรผkleyin veya paket olarak edinin.
+install_desc=Platformunuz iรงin ikili dosyayฤฑ รงalฤฑลtฤฑrฤฑn , Docker ile yรผkleyin veya paket olarak edinin.
platform=Farklฤฑ platformlarda รงalฤฑลablir
-platform_desc=Forgejo Go ile derleme yapฤฑlabilecek her yerde รงalฤฑลmaktadฤฑr: Windows, macOS, Linux, ARM, vb. Hangisini seviyorsanฤฑz onu seรงin!
lightweight=Hafif
lightweight_desc=Forgejo'nฤฑn minimal gereksinimleri รงok dรผลรผktรผr ve ucuz bir Raspberry Pi รผzerinde รงalฤฑลabilmektedir. Makine enerjinizden tasarruf edin!
license=Aรงฤฑk Kaynak
-license_desc=Gidin ve Forgejo 'yฤฑ edinin! Bu projeyi daha da iyi yapmak iรงin katkฤฑda bulunarak bize katฤฑlฤฑn. Katkฤฑda bulunmaktan รงekinmeyin!
+license_desc=Gidin ve Forgejo 'yฤฑ edinin! Bu projeyi daha da iyi yapmak iรงin katkฤฑda bulunarak bize katฤฑlฤฑn. Katkฤฑda bulunmaktan รงekinmeyin!
[install]
install=Kurulum
title=Baลlangฤฑรง Yapฤฑlandฤฑrmasฤฑ
docker_helper=Eฤer Forgejo'yฤฑ Docker iรงerisinde รงalฤฑลtฤฑrฤฑyorsanฤฑz, lรผtfen herhangi bir deฤiลiklik yapmadan รถnce belgeleri okuyun.
require_db_desc=Forgejo MySQL, PostgreSQL, SQLite3 veya TiDB (MySQL protokolรผ) gerektirir.
-db_title=Veritabanฤฑ Ayarlarฤฑ
-db_type=Veritabanฤฑ Tรผrรผ
+db_title=Veritabanฤฑ ayarlarฤฑ
+db_type=Veritabanฤฑ tipi
host=Sunucu
user=Kullanฤฑcฤฑ adฤฑ
password=Parola
-db_name=Veritabanฤฑ Adฤฑ
+db_name=Veritabanฤฑ adฤฑ
db_schema=ลema
db_schema_helper=Veritabanฤฑ varsayฤฑlanฤฑ iรงin boล bฤฑrakฤฑn ("genel").
ssl_mode=SSL
@@ -237,16 +257,16 @@ err_admin_name_is_reserved=Yรถnetici Kullanฤฑcฤฑ Adฤฑ geรงersiz, bu kullanฤฑcฤฑ
err_admin_name_pattern_not_allowed=Yรถnetici kullanฤฑcฤฑ adฤฑ geรงersiz, kullanฤฑcฤฑ adฤฑ ayrฤฑlmฤฑล bir desenle eลleลiyor
err_admin_name_is_invalid=Yรถnetici Kullanฤฑcฤฑ Adฤฑ geรงersiz
-general_title=Genel Ayarlar
+general_title=Genel ayarlar
app_name=Site Baลlฤฑฤฤฑ
app_name_helper=ลirket adฤฑnฤฑzฤฑ buraya girebilirsiniz.
-repo_path=Depo Kรถk Yolu
+repo_path=Depo kรถk dizini
repo_path_helper=Tรผm uzak Git depolarฤฑ bu dizine kaydedilecektir.
-lfs_path=Git LFS Kรถk Yolu
+lfs_path=Git LFS kรถk dizini
lfs_path_helper=Git LFS tarafฤฑndan izlenen dosyalar bu dizinde saklanacaktฤฑr. LFS'yi devre dฤฑลฤฑ bฤฑrakmak iรงin boล bฤฑrakฤฑn.
run_user=ลu Kullanฤฑcฤฑ Olarak รalฤฑลtฤฑr
run_user_helper=Forgejo'nin รงalฤฑลacaฤฤฑ iลletim sistemi kullanฤฑcฤฑ adฤฑ. Bu kullanฤฑcฤฑnฤฑn depo kรถk yoluna eriลiminin olmasฤฑ gerektiฤini unutmayฤฑn.
-domain=Sunucu Alan Adฤฑ
+domain=Sunucu alan adฤฑ
domain_helper=Sunucu iรงin alan adฤฑ veya ana bilgisayar adresi.
ssh_port=SSH Sunucu Portu
ssh_port_helper=SSH sunucusunun dinleyeceฤi port numarasฤฑ. Etkisizleลtimek iรงin boล bฤฑrakฤฑn.
@@ -258,25 +278,25 @@ log_root_path=Gรผnlรผk Dosyalarฤฑ Yolu
log_root_path_helper=Gรผnlรผk dosyalarฤฑ bu dizine kaydedilecektir.
optional_title=ฤฐsteฤe Baฤlฤฑ Ayarlar
-email_title=E-posta Ayarlarฤฑ
-smtp_addr=SMTP Sunucusu
-smtp_port=SMTP Portu
+email_title=E-posta ayarlarฤฑ
+smtp_addr=SMTP sunucusu
+smtp_port=SMTP portu
smtp_from=E-posta Gรถnderen
smtp_from_helper=Forgejo'nฤฑn kullanacaฤฤฑ e-posta adresi. Yalฤฑn bir e-posta adresi girin veya "ฤฐsim" biรงimini kullanฤฑn.
-mailer_user=SMTP Kullanฤฑcฤฑ Adฤฑ
-mailer_password=SMTP Parolasฤฑ
+mailer_user=SMTP kullanฤฑcฤฑ adฤฑ
+mailer_password=SMTP parolasฤฑ
register_confirm=Kayฤฑt iรงin E-posta Doฤrulamasฤฑ Gereksin
-mail_notify=E-Posta Bildirimlerini Etkinleลtir
+mail_notify=E-Posta bildirimlerini etkinleลtir
server_service_title=Sunucu ve Diฤer Servis Ayarlarฤฑ
offline_mode=Yerel Kipi Etkinleลtir
offline_mode.description=รรงรผncรผ parti iรงerik teslim aฤlarฤฑnฤฑ etkisizleลtirin ve bรผtรผn kaynaklarฤฑ yerelden sunun.
disable_gravatar=Gravatar'ฤฑ Devre Dฤฑลฤฑ Bฤฑrak
-disable_gravatar.description=Gravatar ve รผรงรผncรผ parti avatar kaynaklarฤฑnฤฑ iptal edin. Kullanฤฑcฤฑ bir avatar yรผklemediฤi zaman varsayฤฑlan bir avatar kullanฤฑlacaktฤฑr.
+disable_gravatar.description=Gravatar ve diฤer รผรงรผncรผ parti profil resmi kaynaklarฤฑnฤฑ kullanma. Kullanฤฑcฤฑ bir profil resmi yรผklemediฤi zaman varsayฤฑlan bir resim kullanฤฑlacaktฤฑr.
federated_avatar_lookup=Birleลtirilmiล Avatarlarฤฑ Etkinleลtir
-federated_avatar_lookup.description=Libravatar kullanarak federe avatar aramasฤฑnฤฑ etkinleลtirin.
+federated_avatar_lookup.description=Libravatar kullanarak federe profil resmi aramasฤฑnฤฑ etkinleลtirin.
disable_registration=Kendi Kendine Kaydolmayฤฑ Devre Dฤฑลฤฑ Bฤฑrak
disable_registration.description=Kullanฤฑcฤฑnฤฑn kendi kendine kaydolmasฤฑnฤฑ devre dฤฑลฤฑ bฤฑrak. Yalnฤฑzca yรถneticiler yeni hesaplar oluลturabilecek.
-allow_only_external_registration.description=Sadece dฤฑล hizmetler aracฤฑlฤฑฤฤฑyla kullanฤฑcฤฑ kaydฤฑna izin ver
+allow_only_external_registration.description=Sadece belirlenen dฤฑล hizmetler aracฤฑlฤฑฤฤฑyla kullanฤฑcฤฑ kaydฤฑna izin ver.
openid_signin=OpenID Oturum Aรงmayฤฑ Etkinleลtiriniz
openid_signin.description=OpenID ile kullanฤฑcฤฑ giriลini etkinleลtir.
openid_signup=OpenID ile Kendi Kendine Kaydฤฑ Etkinleลtir
@@ -285,12 +305,12 @@ enable_captcha=CAPTCHA kaydฤฑnฤฑ etkinleลtir
enable_captcha.description=Kullanฤฑcฤฑnฤฑn kendi kendine kaydolmasฤฑ iรงin captcha doฤrulamasฤฑ gereksin.
require_sign_in_view=Sayfalarฤฑ Gรถrรผntรผlemek iรงin Giriล Yapmak Gereksin
require_sign_in_view.description=Sayfa eriลimini giriล yapmฤฑล kullanฤฑcฤฑlarla sฤฑnฤฑrlandฤฑr. Ziyaretรงiler sadece oturum aรงma ve kayฤฑt sayfalarฤฑnฤฑ gรถrecektir.
-admin_setting.description=Bir yรถnetici hesabฤฑ aรงmak isteฤe baฤlฤฑdฤฑr. ฤฐlk kayฤฑtlฤฑ kullanฤฑcฤฑ kendiliฤinden yรถnetici olmaktadฤฑr.
-admin_title=Yรถnetici Hesabฤฑ Ayarlarฤฑ
-admin_name=Yรถnetici Kullanฤฑcฤฑ Adฤฑ
+admin_setting.description=Bir yรถnetici hesabฤฑ aรงmak isteฤe baฤlฤฑdฤฑr. ฤฐlk kayฤฑt olan kullanฤฑcฤฑ kendiliฤinden yรถnetici olacaktฤฑr.
+admin_title=Yรถnetici hesabฤฑ ayarlarฤฑ
+admin_name=Yรถnetici kullanฤฑcฤฑ adฤฑ
admin_password=Parola
-confirm_password=Parolayฤฑ Doฤrula
-admin_email=E-posta Adresi
+confirm_password=Parolayฤฑ doฤrula
+admin_email=E-posta adresi
install_btn_confirm=Forgejo'u Kur
test_git_failed='git' komut testi baลarฤฑsฤฑz: %v
sqlite3_not_available=Bu Gieta sรผrรผmรผ SQLite3 desteklemiyor. Lรผtfen %s adresinden resmi รงalฤฑลฤฑr sรผrรผmรผ ('gobuild' sรผrรผmรผnรผ deฤil) indirin.
@@ -305,7 +325,7 @@ save_config_failed=%v Yapฤฑlandฤฑrmasฤฑ kaydedilirken hata oluลtu
invalid_admin_setting=Yรถnetici hesap ayarlarฤฑ geรงersiz: %v
invalid_log_root_path=Log dosya yolu geรงersiz: %v
default_keep_email_private=E-posta adreslerini varsayฤฑlan olarak gizle
-default_keep_email_private.description=Yeni kullanฤฑcฤฑ hesaplarฤฑnฤฑn e-posta adreslerini varsayฤฑlan olarak gizle.
+default_keep_email_private.description=Kayฤฑt olunduktan hemen sonra bilgi sฤฑzฤฑntฤฑsฤฑ olmamasฤฑ iรงin yeni kullanฤฑcฤฑ hesaplarฤฑnฤฑn e-posta adreslerini varsayฤฑlan olarak gizle.
default_allow_create_organization=Varsayฤฑlan Olarak Organizasyon Oluลturmaya ฤฐzin Ver
default_allow_create_organization.description=Varsayฤฑlan olarak yeni kullanฤฑcฤฑ hesaplarฤฑnฤฑn organizasyon oluลturmasฤฑna izin ver.
default_enable_timetracking=Varsayฤฑlan Olarak Zaman Takibini Etkinleลtir
@@ -315,12 +335,19 @@ no_reply_address_helper=Gizlenmiล e-posta adresine sahip kullanฤฑcฤฑlar iรงin a
password_algorithm=Parola Hash Algoritmasฤฑ
invalid_password_algorithm=Hatalฤฑ parola hash algoritmasฤฑ
password_algorithm_helper=Parola hash algoritmasฤฑnฤฑ ayarlayฤฑn. Algoritmalar deฤiลen gereksinimlere ve gรผce sahiptirler. argon2 algoritmasฤฑ iyi รถzelliklere sahip olmasฤฑna raฤmen fazla miktarda bellek kullanฤฑr ve kรผรงรผk sistemler iรงin uygun olmayabilir.
-enable_update_checker=Gรผncelleme Denetleyicisini Etkinleลtir
+enable_update_checker=Gรผncelleme denetleyicisini etkinleลtir
env_config_keys=Ortam Yapฤฑlandฤฑrma
env_config_keys_prompt=Aลaฤฤฑdaki ortam deฤiลkenleri de yapฤฑlandฤฑrma dosyanฤฑza eklenecektir:
+allow_only_external_registration = Sadece dฤฑล hizmetler aracฤฑlฤฑฤฤฑyla kullanฤฑcฤฑ kaydฤฑna izin ver
+app_slogan = Oluลum sloganฤฑ
+app_slogan_helper = Oluลum sloganฤฑnฤฑzฤฑ giriniz. Devre dฤฑลฤฑ bฤฑrakmak iรงin boล bฤฑrakฤฑnฤฑz.
+enable_update_checker_helper_forgejo = release.forgejo.org adresindeki TXT DNS kayฤฑdฤฑ kullanฤฑlarak yeni Forgejo sรผrรผmleri dรผzenli olarak kontrol edilecektir.
+allow_dots_in_usernames = Kullanฤฑcฤฑ isimlerinde noktaya izin ver. Var olan kullanฤฑcฤฑlarฤฑ etkilemez.
+
+smtp_from_invalid = `"E-posta Olarak Gรถnder" adresi geรงersiz`
[home]
-uname_holder=Kullanฤฑcฤฑ Adฤฑ veya E-Posta Adresi
+uname_holder=Kullanฤฑcฤฑ adฤฑ veya e-posta adresi
password_holder=Parola
switch_dashboard_context=Panoya Geรงiล Yap
my_repos=Depolar
@@ -367,15 +394,19 @@ code_search_results=`"%s" iรงin sonuรงlarฤฑ ara`
code_last_indexed_at=Son dizinlenen %s
relevant_repositories_tooltip=รatal olan veya konusu, simgesi veya aรงฤฑklamasฤฑ olmayan depolar gizlenmiลtir.
relevant_repositories=Sadece iliลkili depolar gรถsteriliyor, sรผzรผlmemiล sonuรงlarฤฑ gรถster .
+stars_one = %d yฤฑldฤฑz
+stars_few = %d yฤฑldฤฑz
+forks_one = %d รงatal
+forks_few = %d รงatal
[auth]
-create_new_account=Hesap Oluลtur
+create_new_account=Hesap oluลtur
register_helper_msg=Bir hesabฤฑnฤฑz var mฤฑ? ลimdi giriล yapฤฑn!
social_register_helper_msg=Hesabฤฑnฤฑz var mฤฑ? Hemen baฤlayฤฑn!
disable_register_prompt=Kayฤฑt iลlemi devre dฤฑลฤฑdฤฑr. Lรผtfen site yรถneticinizle iletiลim kurun.
disable_register_mail=Kayฤฑt iรงin e-posta doฤrulama devre dฤฑลฤฑdฤฑr.
manual_activation_only=Etkinleลtirmeyi tamamlamak iรงin site yรถneticinizle baฤlantฤฑya geรงin.
-remember_me=Bu Aygฤฑtฤฑ hatฤฑrla
+remember_me=Bu cihazฤฑ hatฤฑrla
remember_me.compromised=Oturum aรงma tokeni artฤฑk geรงerli deฤil, bu ele geรงirilmiล bir hesaba iลaret ediyor olabilir. Lรผtfen hesabฤฑnฤฑzda olaฤandฤฑลฤฑ faaliyet olup olmadฤฑฤฤฑnฤฑ denetleyin.
forgot_password_title=ลifremi unuttum
forgot_password=ลifrenizi mi unuttunuz?
@@ -394,7 +425,7 @@ has_unconfirmed_mail=Merhaba %s, doฤrulanmamฤฑล bir e-posta adresin var (%s
resend_mail=Etkinleลtirme e-postasฤฑnฤฑ tekrar almak iรงin buraya tฤฑklayฤฑn
email_not_associate=Bu e-posta adresi hiรงbir hesap ile iliลkilendirilmemiลtir.
send_reset_mail=Hesap Kurtarma E-postasฤฑ Gรถnder
-reset_password=Hesap Kurtarma
+reset_password=Hesap kurtarma
invalid_code=Doฤrulama kodunuz geรงersiz veya sรผresi dolmuล.
invalid_code_forgot_password=Onay kodunuz hatalฤฑ veya sรผresi geรงmiล. Yeni bir oturum baลlatmak iรงin buraya tฤฑklayฤฑn.
invalid_password=Parolanฤฑz hesap oluลturulurken kullanฤฑlan parolayla eลleลmiyor.
@@ -408,9 +439,9 @@ use_scratch_code=Bir รงizgi kodu kullanฤฑnฤฑz
twofa_scratch_used=Geรงici kodunuzu kullandฤฑnฤฑz. ฤฐki aลamalฤฑ ayarlar sayfasฤฑna yรถnlendirildiniz, burada aygฤฑt kaydฤฑnฤฑzฤฑ kaldฤฑrabilir veya yeni bir geรงici kod oluลturabilirsiniz.
twofa_passcode_incorrect=ลifreniz yanlฤฑล. Aygฤฑtฤฑnฤฑzฤฑ yanlฤฑล yerleลtirdiyseniz, oturum aรงmak iรงin รงizgi kodunuzu kullanฤฑn.
twofa_scratch_token_incorrect=รizgi kodunuz doฤru deฤildir.
-login_userpass=Oturum Aรง
+login_userpass=Oturum aรง
tab_openid=Aรงฤฑk Kimlik
-oauth_signup_tab=Yeni Hesap Oluลtur
+oauth_signup_tab=Yeni hesap oluลtur
oauth_signup_title=Yeni Hesabฤฑ Tamamla
oauth_signup_submit=Hesabฤฑ Tamamla
oauth_signin_tab=Mevcut Hesaba Baฤla
@@ -436,8 +467,17 @@ authorize_title=Hesabฤฑnฤฑza eriลmesi iรงin "%s" yetkilendirilsin mi?
authorization_failed=Yetkilendirme baลarฤฑsฤฑz oldu
authorization_failed_desc=Geรงersiz bir istek tespit ettiฤimiz iรงin yetkilendirme baลarฤฑsฤฑz oldu. Lรผtfen izin vermeye รงalฤฑลtฤฑฤฤฑnฤฑz uygulamanฤฑn saฤlayฤฑcฤฑsฤฑ ile iletiลim kurun.
sspi_auth_failed=SSPI kimlik doฤrulamasฤฑ baลarฤฑsฤฑz oldu
-password_pwned=Seรงtiฤiniz parola, daha รถnce herkese aรงฤฑk veri ihlallerinde aรงฤฑฤa รงฤฑkan bir รงalฤฑnan parola listesindedir . Lรผtfen farklฤฑ bir parola ile tekrar deneyin ve baลka yerlerde de bu parolayฤฑ deฤiลtirmeyi dรผลรผnรผn.
+password_pwned=Seรงtiฤiniz parola, daha รถnce herkese aรงฤฑk veri ihlallerinde aรงฤฑฤa รงฤฑkan bir รงalฤฑnan parola listesindedir . Lรผtfen farklฤฑ bir parola ile tekrar deneyin ve baลka yerlerde de bu parolayฤฑ deฤiลtirmeyi dรผลรผnรผn.
password_pwned_err=HaveIBeenPwned'e yapฤฑlan istek tamamlanamadฤฑ
+change_unconfirmed_email_summary = Aktivasyon e-postasฤฑnฤฑn geldiฤi adresi deฤiลtir.
+change_unconfirmed_email_error = E-posta adresi deฤiลtirilemedi: %v
+last_admin = Son yรถneticiyi kaldฤฑrmazsฤฑnฤฑz. En az bir yรถnetici olmalฤฑdฤฑr.
+back_to_sign_in = Giriล yapa dรถn
+sign_up_button = Hemen kaydol.
+hint_register = Hesaba ihtiyacฤฑn var mฤฑ? Hemen kaydol.
+sign_in_openid = OpenID ile giriล yap
+hint_login = Mevcut hesabฤฑn var mฤฑ? Hemen giriล yap!
+use_onetime_code = Tek kullanฤฑmlฤฑk kod kullan
[mail]
view_it_on=%s รผzerinde gรถrรผntรผle
@@ -454,7 +494,7 @@ activate_email=E-posta adresinizi doฤrulayฤฑn
activate_email.title=%s, lรผtfen e-posta adresinizi doฤrulayฤฑn
activate_email.text=E posta adresinizi doฤrulamak iรงin lรผtfen %s iรงinde linke tฤฑklayฤฑn:
-register_notify=Forgejo'ya Hoล Geldiniz
+register_notify=%s'ya Hoล Geldiniz
register_notify.title=%[1]s, %[2]s e hoลgeldiniz
register_notify.text_1=bu %s iรงin kayฤฑt onay e postanฤฑzdฤฑr!
register_notify.text_2=Artฤฑk %s kullanฤฑcฤฑ adฤฑ ile oturum aรงabilirsiniz.
@@ -504,6 +544,18 @@ team_invite.subject=%[1]s sizi %[2]s organizasyonuna katฤฑlmaya davet etti
team_invite.text_1=%[1]s sizi %[3]s organizasyonundaki %[2]s takฤฑmฤฑna katฤฑlmaya davet etti.
team_invite.text_2=Takฤฑma katฤฑlmak lรผtfen aลaฤฤฑdaki baฤlantฤฑya tฤฑklayฤฑn:
team_invite.text_3=Not: Bu davet %[1]s iรงindi. Bu daveti beklemiyorsanฤฑz, e-postayฤฑ yok sayabilirsiniz.
+totp_disabled.text_1 = Hesabฤฑnฤฑzdaki zaman-tabanlฤฑ tek kullanฤฑmlฤฑk ลifre/iki faktรถrlรผ doฤrulama (TOTP) devre dฤฑลฤฑ bฤฑrakฤฑldฤฑ.
+removed_security_key.subject = Bir gรผvenlik anahtarฤฑ kaldฤฑrฤฑldฤฑ
+primary_mail_change.subject = Ana e-posta adresiniz deฤiลti
+totp_disabled.subject = TOTP devre dฤฑลฤฑ bฤฑrakฤฑldฤฑ
+removed_security_key.text_1 = Gรผvenlik anahtarฤฑ "%[1]s" hesabฤฑnฤฑzdan kaldฤฑrฤฑldฤฑ.
+account_security_caution.text_2 = Eฤer bu siz deฤilseniz hesabฤฑnฤฑz ele geรงirilmiล demektir. Lรผtfen site yรถneticileri ile iletiลime geรงiniz.
+admin.new_user.subject = Yeni kullanฤฑcฤฑ %s kayฤฑt oldu
+account_security_caution.text_1 = Eฤer bu sizseniz bu e-postayฤฑ gรถrmezden gelebilirsiniz.
+password_change.subject = Parolanฤฑz deฤiลti
+admin.new_user.user_info = Kullanฤฑcฤฑ bilgisi
+admin.new_user.text = Lรผtfen bu kullanฤฑcฤฑyฤฑ admin panelinden yรถnetmek iรงin buraya tฤฑklayฤฑn .
+password_change.text_1 = Hesabฤฑnฤฑzฤฑn parolasฤฑ deฤiลti.
[modal]
yes=Evet
@@ -602,8 +654,22 @@ org_still_own_repo=Bu organizasyon hala bir veya daha fazla depoya sahip, รถnce
org_still_own_packages=Bu organizasyon hala bir veya daha fazla pakete sahip, รถnce onlarฤฑ silin.
target_branch_not_exist=Hedef dal mevcut deฤil.
+To = Dal adฤฑ
+Description = Aรงฤฑklama
+Pronouns = Adฤฑllar
+FullName = Tam isim
+required_prefix = Girdi "%s" ile baลlamalฤฑdฤฑr
+Biography = Biyografi
+AccessToken = Eriลim jetonu
+Location = Konum
+Website = Websitesi
+admin_cannot_delete_self = Yรถneticiyken kullanฤฑcฤฑnฤฑzฤฑ silemezsiniz. Lรผtfen รถnce yรถnetici yetkilerinizi kaldฤฑrฤฑn.
+username_error_no_dots = ` sadece alfanumerik karakterler ("0-9","a-z","A-Z"), tire ("-") ve alt tire ("-") iรงerebilir. Alfanumerik olmayan karakterlerle baลlayamaz ve bitemez, ayrฤฑca ardฤฑลฤฑk alfanumerik olmayan karakterler de kullanฤฑlamaz.`
+unset_password = Oturum aรงma kullanฤฑcฤฑsฤฑ parola belirlemedi.
+unsupported_login_type = Oturum aรงma tรผrรผ hesap silmeyi desteklemiyor.
+
[user]
change_avatar=Profil resmini deฤiลtirโฆ
joined_on=%s tarihinde katฤฑldฤฑ
@@ -628,6 +694,23 @@ settings=Kullanฤฑcฤฑ Ayarlarฤฑ
form.name_reserved=`"%s" kullanฤฑcฤฑ adฤฑ rezerve edilmiล.`
form.name_pattern_not_allowed=Kullanฤฑcฤฑ adฤฑnda "%s" deseni kullanฤฑlamaz.
form.name_chars_not_allowed=`"%s" kullanฤฑcฤฑ adฤฑ geรงersiz karakterler iรงeriyor.`
+following.title.few = Takip edilenler
+public_activity.visibility_hint.admin_private = Bu aktivite yรถnetici olduฤunuz iรงin aรงฤฑktฤฑr ama kullanฤฑcฤฑ gizli kalmasฤฑnฤฑ tercih etmiลtir.
+block_user = Kullanฤฑcฤฑyฤฑ engelle
+public_activity.visibility_hint.self_public = Gizli alanlar haricindeki aktiviteleriniz herkese aรงฤฑktฤฑr. Deฤiลtir .
+public_activity.visibility_hint.admin_public = Bu aktivite herkese aรงฤฑktฤฑr ama bir yรถnetici olarak gizli alanlardaki etkileลimleri de gรถrebilirsiniz.
+unblock = Engeli kaldฤฑr
+following_one = %d takipรงi
+follow_blocked_user = Bu kullanฤฑcฤฑyฤฑ takip edemezsiniz รงรผnkรผ bu kullanฤฑcฤฑyฤฑ engellediniz veya bu kullanฤฑcฤฑ tarafฤฑndan engellendiniz.
+followers.title.few = Takipรงiler
+following.title.one = Takip edilenler
+followers.title.one = Takipรงi
+block = Engelle
+public_activity.visibility_hint.self_private = Aktiviteniz sadece size ve oluลum yรถneticilerine aรงฤฑktฤฑr. Deฤiลtir .
+followers_one = %d takipรงi
+block_user.detail_2 = Bu kullanฤฑcฤฑ sahip olduฤunuz depolar, aรงtฤฑฤฤฑnฤฑz sorunlar ve yaptฤฑฤฤฑnฤฑz yorumlar ile etkileลime geรงemeyecek.
+block_user.detail_1 = Birbirinizden takipten รงฤฑkacak ve birbirinizi takip edemeyeceksiniz.
+block_user.detail = Bu kullanฤฑcฤฑyฤฑ engellediฤinizde:
[settings]
profile=Profil
@@ -845,7 +928,7 @@ select_permissions=ฤฐzinleri seรงin
permission_no_access=Eriลim Yok
permission_read=Okunmuล
permission_write=Okuma ve Yazma
-access_token_desc=Seรงili token izinleri, yetkilendirmeyi ilgili API yollarฤฑyla sฤฑnฤฑrlandฤฑracaktฤฑr. Daha fazla bilgi iรงin belgeleri okuyun.
+access_token_desc=Seรงili token izinleri, yetkilendirmeyi ilgili API yollarฤฑyla sฤฑnฤฑrlandฤฑracaktฤฑr. Daha fazla bilgi iรงin belgeleri okuyun.
at_least_one_permission=Bir token oluลturmak iรงin en azฤฑndan bir izin seรงmelisiniz
permissions_list=ฤฐzinler:
@@ -899,7 +982,7 @@ passcode_invalid=ลifre geรงersiz. Tekrar deneyin.
twofa_enrolled=Hesabฤฑnฤฑz iki faktรถrlรผ kimlik doฤrulamasฤฑna kaydedildi. Kazฤฑma belirtecini (%s) yalnฤฑzca bir kez gรถsterdiฤi gibi gรผvenli bir yerde saklayฤฑn!
twofa_failed_get_secret=Gizlilik elde edilemedi.
-webauthn_desc=Gรผvenlik anahtarlarฤฑ, ลifreleme anahtarlarฤฑnฤฑ iรงeren donanฤฑm aygฤฑtlarฤฑdฤฑr. ฤฐki aลamalฤฑ kimlik doฤrulama iรงin kullanฤฑlabilirler. Gรผvenlik anahtarlarฤฑ WebAuthn Authenticator standardฤฑnฤฑ desteklemelidir.
+webauthn_desc=Gรผvenlik anahtarlarฤฑ, ลifreleme anahtarlarฤฑnฤฑ iรงeren donanฤฑm aygฤฑtlarฤฑdฤฑr. ฤฐki aลamalฤฑ kimlik doฤrulama iรงin kullanฤฑlabilirler. Gรผvenlik anahtarlarฤฑ WebAuthn Authenticator standardฤฑnฤฑ desteklemelidir.
webauthn_register_key=Gรผvenlik Anahtarฤฑ Ekle
webauthn_nickname=Takma Ad
webauthn_delete_key=Gรผvenlik Anahtarฤฑnฤฑ Kaldฤฑr
@@ -940,6 +1023,16 @@ visibility.limited=Sฤฑnฤฑrlฤฑ
visibility.limited_tooltip=Sadece oturum aรงmฤฑล kullanฤฑcฤฑlar tarafฤฑndan gรถrรผnรผr
visibility.private=รzel
visibility.private_tooltip=Sadece katฤฑldฤฑฤฤฑnฤฑz organizasyonlarฤฑn รผyeleri tarafฤฑndan gรถrรผnรผr
+user_unblock_success = Kullanฤฑcฤฑnฤฑn engeli baลarฤฑlฤฑ bir ลekilde kaldฤฑrฤฑldฤฑ.
+user_block_success = Kullanฤฑcฤฑ baลarฤฑlฤฑ bir ลekilde engellendi.
+language.title = Varsayฤฑlan dil
+change_password = Parolayฤฑ gรผncelle
+pronouns = Adฤฑllar
+blocked_users = Engelli kullanฤฑcฤฑlar
+pronouns_unspecified = Belirtilmemiล
+hints = ฤฐpuรงlarฤฑ
+language.description = Bu dil giriล yaptฤฑฤฤฑnฤฑzda varsayฤฑlan dil olarak kullanฤฑlmak รผzere hesabฤฑnฤฑza kaydedilecektir.
+keep_activity_private.description = ลu anki halka aรงฤฑk aktiviteniz sadece size ve oluลum yรถneticilerine aรงฤฑk olacaktฤฑr.
[repo]
new_repo_helper=Bir depo, sรผrรผm geรงmiลi dahil tรผm proje dosyalarฤฑnฤฑ iรงerir. Zaten baลka bir yerde mi barฤฑndฤฑrฤฑyorsunuz? Depoyu taลฤฑyฤฑn.
@@ -1034,9 +1127,9 @@ blame.ignore_revs=.git-blame-ignore-revs dosyasฤฑndaki sรผrรผml
blame.ignore_revs.failed=.git-blame-ignore-revs dosyasฤฑndaki sรผrรผmler yok sayฤฑlamadฤฑ.
author_search_tooltip=En fazla 30 kullanฤฑcฤฑ gรถrรผntรผler
-tree_path_not_found_commit=%[1] yolu, %[2]s iลlemesinde mevcut deฤil
-tree_path_not_found_branch=%[1] yolu, %[2]s dalฤฑnda mevcut deฤil
-tree_path_not_found_tag=%[1] yolu, %[2]s etiketinde mevcut deฤil
+tree_path_not_found_commit=%[1]s yolu, %[2]s iลlemesinde mevcut deฤil
+tree_path_not_found_branch=%[1]s yolu, %[2]s dalฤฑnda mevcut deฤil
+tree_path_not_found_tag=%[1]s yolu, %[2]s etiketinde mevcut deฤil
transfer.accept=Aktarฤฑmฤฑ Kabul Et
transfer.accept_desc=`"%s" tarafฤฑna aktar`
@@ -1110,7 +1203,7 @@ migrate.migrating_failed_no_addr=Gรถรง baลarฤฑsฤฑz oldu.
migrate.github.description=Github.com veya diฤer Github sunucularฤฑndan veri aktar.
migrate.git.description=Herhangi bir Git hizmetinden sadece bir depoyu aktar.
migrate.gitlab.description=Gitlab.com veya diฤer Gitlab sunucularฤฑndan veri aktar.
-migrate.gitea.description=Gitea.com veya diฤer Gitea/Forgejo sunucularฤฑndan veri aktar.
+migrate.gitea.description=Gitea.com veya diฤer Gitea sunucularฤฑndan veri aktar.
migrate.gogs.description=Notabug.org veya diฤer Gogs sunucularฤฑndan veri aktar.
migrate.onedev.description=Code.onedev.io ve diฤer OneDev sunucularฤฑndan veri aktar.
migrate.codebase.description=Codebasehq.com sitesinden veri aktar.
@@ -1198,6 +1291,7 @@ view_git_blame=Git Suรง Gรถrรผntรผle
video_not_supported_in_browser=Tarayฤฑcฤฑnฤฑz HTML5 'video' etiketini desteklemiyor.
audio_not_supported_in_browser=Tarayฤฑcฤฑnฤฑz HTML5 'audio' etiketini desteklemiyor.
stored_lfs=Git LFS ile depolandฤฑ
+stored_annex=Git Annex ile depolandฤฑ
symbolic_link=Sembolik Baฤlantฤฑ
executable_file=รalฤฑลtฤฑrฤฑlabilir Dosya
commit_graph=ฤฐลleme Grafiฤi
@@ -1221,6 +1315,7 @@ editor.upload_file=Dosya Yรผkle
editor.edit_file=Dosyayฤฑ Dรผzenle
editor.preview_changes=Deฤiลiklikleri รnizle
editor.cannot_edit_lfs_files=LFS dosyalarฤฑ web arayรผzรผnde dรผzenlenemez.
+editor.cannot_edit_annex_files=Annex dosyalarฤฑ web arayรผzรผnde dรผzenlenemez.
editor.cannot_edit_non_text_files=Bu tรผr dosyalar web arayรผzรผnden dรผzenlenemez.
editor.edit_this_file=Dosyayฤฑ Dรผzenle
editor.this_file_locked=Dosya kilitlendi
@@ -1235,7 +1330,8 @@ editor.or=veya
editor.cancel_lower=ฤฐptal
editor.commit_signed_changes=ฤฐmzalฤฑ Deฤiลiklikleri ฤฐลle
editor.commit_changes=Deฤiลiklikleri Uygula
-editor.add_tmpl='' eklendi
+editor.add_tmpl='<%s>' eklendi
+editor.add_tmpl.filename = dosyaadi
editor.add=%s Ekle
editor.update=%s Gรผncelle
editor.delete=%s Sil
@@ -1245,7 +1341,7 @@ editor.fail_to_apply_patch=`"%s" yamasฤฑ uygulanamฤฑyor`
editor.new_patch=Yeni Yama
editor.commit_message_desc=ฤฐsteฤe baฤlฤฑ uzun bir aรงฤฑklama ekleyinโฆ
editor.signoff_desc=ฤฐลleme gรผnlรผฤรผ mesajฤฑnฤฑn sonuna iลleyen tarafฤฑndan imzalanan bir fragman ekleyin.
-editor.commit_directly_to_this_branch=Doฤrudan %s bรถlรผmรผne uygula.
+editor.commit_directly_to_this_branch=Doฤrudan %[1]s bรถlรผmรผne uygula.
editor.create_new_branch=Bu iลleme iรงin yeni bir dal oluลturun ve bir deฤiลiklik isteฤi baลlatฤฑn.
editor.create_new_branch_np=Bu iลleme iรงin yeni bir dal oluลtur.
editor.propose_file_change=Dosya deฤiลikliฤi รถner
@@ -1611,7 +1707,7 @@ issues.error_modifying_due_date=Bitiล tarihi deฤiลtirilemedi.
issues.error_removing_due_date=Bitiล tarihi silinemedi.
issues.push_commit_1=%d iลlemeyi %s ekledi
issues.push_commits_n=%d iลlemeyi %s ekledi
-issues.force_push_codes=`%[1]s %[2]s
hedefinden %[4]s
hedefine zorla gรถnderildi %[6]s`
+issues.force_push_codes=`%[1]s %[2]s
hedefinden %[4]s
hedefine zorla gรถnderildi %[6]s`
issues.force_push_compare=Karลฤฑlaลtฤฑr
issues.due_date_form=yyyy-aa-gg
issues.due_date_form_add=Bitiล tarihi ekle
@@ -1726,7 +1822,7 @@ pulls.nothing_to_compare=Bu dallar eลit. Deฤiลiklik isteฤi oluลturmaya gere
pulls.nothing_to_compare_and_allow_empty_pr=Bu dallar eลittir. Bu Dฤฐ boล olacak.
pulls.has_pull_request=`Bu dallar arasฤฑnda zaten bir deฤiลiklik isteฤi var: %[2]s#%[3]d `
pulls.create=Deฤiลiklik ฤฐsteฤi Oluลtur
-pulls.title_desc_few=%[2]s
iรงindeki %[1]d iลlemeyi %[3]s
ile birleลtirmek istiyor
+pulls.title_desc_few=%[2]s
iรงindeki %[1]d iลlemeyi %[3]s
ile birleลtirmek istiyor
pulls.merged_title_desc_few=%[4]s %[2]s
iรงindeki %[1]d iลlemeyi %[3]s
ile birleลtirdi
pulls.change_target_branch_at='hedef dal %s adresinden %s %s adresine deฤiลtirildi'
pulls.tab_conversation=Sohbet
@@ -1815,11 +1911,11 @@ pulls.outdated_with_base_branch=Bu dal, temel dal ile gรผncel deฤil
pulls.close=Deฤiลiklik ฤฐsteฤini Kapat
pulls.closed_at=`%[2]s deฤiลiklik isteฤini kapattฤฑ`
pulls.reopened_at=`%[2]s deฤiลiklik isteฤini yeniden aรงtฤฑ`
-pulls.cmd_instruction_hint=`Komut satฤฑrฤฑ talimatlarฤฑnฤฑ gรถrรผntรผleyin.`
+pulls.cmd_instruction_hint=`Komut satฤฑrฤฑ talimatlarฤฑnฤฑ gรถrรผntรผleyin.`
pulls.cmd_instruction_checkout_title=รekme
pulls.cmd_instruction_checkout_desc=Proje deponuzdan yeni bir dalฤฑ รงekin ve deฤiลiklikleri test edin.
pulls.cmd_instruction_merge_title=Birleลtir
-pulls.cmd_instruction_merge_desc=Deฤiลiklikleri birleลtirin ve Gitea'da gรผncelleyin.
+pulls.cmd_instruction_merge_desc=Deฤiลiklikleri birleลtirin ve Forgejo gรผncelleyin.
pulls.clear_merge_message=Birleลtirme iletilerini temizle
pulls.clear_merge_message_hint=Birleลtirme iletisini temizlemek sadece iลleme ileti iรงeriฤini kaldฤฑrฤฑr ama รผretilmiล "Co-Authored-By โฆ" gibi git fragmanlarฤฑnฤฑ korur.
@@ -2242,7 +2338,7 @@ settings.event_pull_request_merge=Deฤiลiklik ฤฐsteฤi Birleลtirme
settings.event_package=Paket
settings.event_package_desc=Bir depoda paket oluลturuldu veya silindi.
settings.branch_filter=Dal filtresi
-settings.branch_filter_desc=Gรถnderme, dal oluลturma ve dal silme olaylarฤฑ iรงin glob deseni olarak belirtilen dal beyaz listesi. Boลsa veya *
ise, tรผm dallar iรงin olaylar raporlanฤฑr. Sรถzdizimi iรงin github.com/gobwas/glob belgelerine bakฤฑn. รrnekler: master
, {master,release*}
.
+settings.branch_filter_desc=Gรถnderme, dal oluลturma ve dal silme olaylarฤฑ iรงin glob deseni olarak belirtilen dal beyaz listesi. Boลsa veya *
ise, tรผm dallar iรงin olaylar raporlanฤฑr. Sรถzdizimi iรงin %[2]s belgelerine bakฤฑn. รrnekler: master
, {master,release*}
.
settings.authorization_header=Yetkilendirme Baลlฤฑฤฤฑ
settings.authorization_header_desc=Mevcutsa isteklere yetkilendirme baลlฤฑฤฤฑ olarak eklenecektir. รrnekler: %s.
settings.active=Etkin
@@ -2334,12 +2430,12 @@ settings.dismiss_stale_approvals_desc=Deฤiลiklik isteฤinin iรงeriฤini deฤi
settings.require_signed_commits=ฤฐmzalฤฑ ฤฐลleme Gerekli
settings.require_signed_commits_desc=Reddetme, onlar imzasฤฑzsa veya doฤrulanamazsa bu dala gรถnderir.
settings.protect_branch_name_pattern=Korunmuล Dal Adฤฑ Deseni
-settings.protect_branch_name_pattern_desc=Korunmuล dal isim desenleri. Desen sรถzdizimi iรงin belgelere bakabilirsiniz. รrnekler: main, release/**
+settings.protect_branch_name_pattern_desc=Korunmuล dal isim desenleri. Desen sรถzdizimi iรงin belgelere bakabilirsiniz. รrnekler: main, release/**
settings.protect_patterns=Desenler
settings.protect_protected_file_patterns=Korumalฤฑ dosya kalฤฑplarฤฑ (noktalฤฑ virgรผlle ayrฤฑlmฤฑล ';'):
-settings.protect_protected_file_patterns_desc=Kullanฤฑcฤฑnฤฑn bu dalda dosya ekleme, dรผzenleme veya silme haklarฤฑ olsa bile doฤrudan deฤiลtirilmesine izin verilmeyen korumalฤฑ dosyalar. Birden รงok desen noktalฤฑ virgรผl (';') kullanฤฑlarak ayrฤฑlabilir. Desen sรถzdizimi iรงin github.com/gobwas/glob belgelerine bakฤฑn. รrnekler: .drone.yml
, /docs/**/*.txt
.
+settings.protect_protected_file_patterns_desc=Kullanฤฑcฤฑnฤฑn bu dalda dosya ekleme, dรผzenleme veya silme haklarฤฑ olsa bile doฤrudan deฤiลtirilmesine izin verilmeyen korumalฤฑ dosyalar. Birden รงok desen noktalฤฑ virgรผl (';') kullanฤฑlarak ayrฤฑlabilir. Desen sรถzdizimi iรงin %[2]s belgelerine bakฤฑn. รrnekler: .drone.yml
, /docs/**/*.txt
.
settings.protect_unprotected_file_patterns=Korunmasฤฑz dosya desenleri (noktalฤฑ virgรผlle ayrฤฑlmฤฑล ';'):
-settings.protect_unprotected_file_patterns_desc=Kullanฤฑcฤฑnฤฑn yazma eriลimi, itme kฤฑsฤฑtlamasฤฑnฤฑ atlama hakkฤฑ olduฤunda doฤrudan deฤiลtirmesine izin verilen korunmasฤฑz dosyalar. Birden รงok desen noktalฤฑ virgรผl (';') kullanฤฑlarak ayrฤฑlabilir. Desen sรถz dizimi iรงin github.com/gobwas/glob belgelerine bakฤฑn. รrnekler: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns_desc=Kullanฤฑcฤฑnฤฑn yazma eriลimi, itme kฤฑsฤฑtlamasฤฑnฤฑ atlama hakkฤฑ olduฤunda doฤrudan deฤiลtirmesine izin verilen korunmasฤฑz dosyalar. Birden รงok desen noktalฤฑ virgรผl (';') kullanฤฑlarak ayrฤฑlabilir. Desen sรถz dizimi iรงin %[2]s belgelerine bakฤฑn. รrnekler: .drone.yml
, /docs/**/*.txt
.
settings.add_protected_branch=Korumayฤฑ etkinleลtir
settings.delete_protected_branch=Korumayฤฑ devre dฤฑลฤฑ bฤฑrak
settings.update_protect_branch_success=Dal koruma kuralฤฑ "%s" gรผncellendi.
@@ -2371,7 +2467,7 @@ settings.tags.protection.allowed.teams=ฤฐzin verilen takฤฑmlar
settings.tags.protection.allowed.noone=Hiรง kimse
settings.tags.protection.create=Etiketi Koru
settings.tags.protection.none=Korumalฤฑ etiket yok.
-settings.tags.protection.pattern.description=Birden รงok etiketi eลleลtirmek iรงin tek bir ad, glob deseni veya normal ifade kullanabilirsiniz. Daha fazlasฤฑ iรงin korumalฤฑ etiketler rehberini okuyun.
+settings.tags.protection.pattern.description=Birden รงok etiketi eลleลtirmek iรงin tek bir ad, glob deseni veya normal ifade kullanabilirsiniz. Daha fazlasฤฑ iรงin korumalฤฑ etiketler rehberini okuyun.
settings.bot_token=Bot Jetonu
settings.chat_id=Sohbet Kimliฤi
settings.thread_id=ฤฐล Parรงacฤฑฤฤฑ ID
@@ -2538,7 +2634,7 @@ branch.delete_desc=Bir dalฤฑ silmek kalฤฑcฤฑdฤฑr. Her ne kadar silinen dal tamam
branch.deletion_success=`"%s" dalฤฑ silindi.`
branch.deletion_failed=`"%s" dalฤฑ silinemedi.`
branch.delete_branch_has_new_commits=`"%s" dalฤฑ silinemedi รงรผnkรผ birleลtirme sonrasฤฑnda yeni iลlemeler eklendi.`
-branch.create_branch=%s dalฤฑ oluลtur
+branch.create_branch=%s dalฤฑ oluลtur
branch.create_from=`"%s"den`
branch.create_success=`"%s" dalฤฑ oluลturuldu.`
branch.branch_already_exists=Bu depoda "%s" dalฤฑ zaten var.
@@ -2565,7 +2661,7 @@ branch.new_branch=Yeni dal oluลtur
branch.new_branch_from=`"%s" dalฤฑndan yeni dal oluลtur`
branch.renamed=%s dalฤฑnฤฑn adฤฑ %s olarak deฤiลtirildi.
-tag.create_tag=%s etiketi oluลtur
+tag.create_tag=%s etiketi oluลtur
tag.create_tag_operation=Etiket oluลtur
tag.confirm_create_tag=Etiket oluลtur
tag.create_tag_from=`"%s" kullanarak yeni etiket oluลtur`
@@ -2583,8 +2679,59 @@ find_file.no_matching=Eลleลen dosya bulunamadฤฑ
error.csv.too_large=Bu dosya รงok bรผyรผk olduฤu iรงin iลlenemiyor.
error.csv.unexpected=%d satฤฑrฤฑ ve %d sรผtununda beklenmeyen bir karakter iรงerdiฤinden bu dosya iลlenemiyor.
error.csv.invalid_field_count=%d satฤฑrฤฑnda yanlฤฑล sayฤฑda alan olduฤundan bu dosya iลlenemiyor.
+admin.enabled_flags = Etiketler ลu depo iรงin etkinleลti:
+admin.update_flags = Etiketleri gรผncelle
+admin.failed_to_replace_flags = Depo etiketleri deฤiลtirilemedi
+admin.manage_flags = Etiketleri yรถnet
+admin.flags_replaced = Depo etiketleri deฤiลtirildi
+rss.must_be_on_branch = RSS akฤฑลฤฑ iรงin bir dalda olmalฤฑsฤฑnฤฑz.
+settings.transfer_quota_exceeded = Yeni sahip (%s) kotayฤฑ aลmฤฑล. Depo aktarฤฑlamadฤฑ.
+contributors.contribution_type.filter_label = Katฤฑlฤฑm tipi:
+settings.enter_repo_name = Sahibi ve depo adฤฑnฤฑ tam olarak ลu ลekilde girin:
+contributors.contribution_type.additions = Eklemeler
+settings.units.overview = Genel Bakฤฑล
+settings.federation_settings = Federasyon Ayarlarฤฑ
+wiki.cancel = ฤฐptal
+settings.transfer.button = Sahipliฤi aktar
+settings.transfer.modal.title = Sahipliฤi aktar
+wiki.no_search_results = Sonuรง yok
+settings.federation_not_enabled = Oluลumunuz federasyona aรงฤฑk deฤildir.
+settings.pull_mirror_sync_quota_exceeded = Kota aลฤฑldฤฑ, deฤiลiklikler รงekilmeyecek.
+activity.navbar.contributors = Katฤฑlฤฑmcฤฑlar
+contributors.contribution_type.deletions = รฤฑkarmalar
+settings.new_owner_blocked_doer = Yeni sahip sizi engelledi.
+
+open_with_editor = %s ile aรง
+object_format = Nesne Biรงimi
+mirror_sync = eลitlendi
+stars = Yฤฑldฤฑzlar
+desc.sha256 = SHA256
+vendored = Saฤlanmฤฑล
+generated = รretilmiล
+editor.push_out_of_date = ฤฐtme eskimiล.
+commits.search_branch = Bu Dal
+issues.edit.already_changed = Konuya yapฤฑlan deฤiลiklikler kaydedilemiyor. ฤฐรงerik baลka kullanฤฑcฤฑ tarafฤฑndan deฤiลtirilmiล gรถzรผkรผyor. Diฤerlerinin deฤiลikliklerinin รผzerine yazmamak iรงin lรผtfen sayfayฤฑ yenileyin ve tekrar dรผzenlemeye รงalฤฑลฤฑn
+pulls.edit.already_changed = Deฤiลiklik isteฤine yapฤฑlan deฤiลiklikler kaydedilemiyor. ฤฐรงerik baลka kullanฤฑcฤฑ tarafฤฑndan deฤiลtirilmiล gรถzรผkรผyor. Diฤerlerinin deฤiลikliklerinin รผzerine yazmamak iรงin lรผtfen sayfayฤฑ yenileyin ve tekrar dรผzenlemeye รงalฤฑลฤฑn
+pulls.nothing_to_compare_have_tag = Seรงili dal/etiket aynฤฑ.
+pulls.fast_forward_only_merge_pull_request = Sadece ileri sarma
+comments.edit.already_changed = Yoruma yapฤฑlan deฤiลiklikler kaydedilemiyor. ฤฐรงerik baลka kullanฤฑcฤฑ tarafฤฑndan deฤiลtirilmiล gรถzรผkรผyor. Diฤerlerinin deฤiลikliklerinin รผzerine yazmamak iรงin lรผtfen sayfayฤฑ yenileyin ve tekrar dรผzenlemeye รงalฤฑลฤฑn
+milestones.filter_sort.name = Ad
+activity.navbar.pulse = Eฤilim
+activity.navbar.code_frequency = Kod Frekansฤฑ
+activity.navbar.recent_commits = Son ฤฐลlemeler
+settings.mirror_settings.pushed_repository = ฤฐtilmiล depo
+settings.ignore_stale_approvals = Eskimiล onaylarฤฑ yoksay
+settings.ignore_stale_approvals_desc = Daha eski iลlemelere (eski incelemelere) yapฤฑlmฤฑล olan onaylarฤฑ, Dฤฐ'nin kaรง onayฤฑ olduฤunu belirlerken sayma. Eskimiล incelemeler atฤฑldฤฑysa bu ilgisizdir.
+error.broken_git_hook = Bu deponun Git ฤฐstemcileri bozuk gibi gรถzรผkรผyor. Onarmak iรงin lรผtfen belgelere bakฤฑn, daha sonra durumu yenilemek iรงin bazฤฑ iลlemeler itin.
[graphs]
+component_loading = %s yรผkleniyor...
+component_loading_failed = %s yรผklenemedi
+component_loading_info = Bu biraz sรผrebilirโฆ
+component_failed_to_load = Beklenmedik bir hata oluลtu.
+code_frequency.what = kod frekansฤฑ
+contributors.what = katkฤฑlar
+recent_commits.what = son iลlemeler
[org]
org_name_holder=Organizasyon Adฤฑ
@@ -2729,7 +2876,7 @@ last_page=Son
total=Toplam: %d
settings=Yรถnetici Ayarlarฤฑ
-dashboard.new_version_hint=Forgejo %s ลimdi hazฤฑr, %s รงalฤฑลtฤฑrฤฑyorsunuz. Ayrฤฑntฤฑlar iรงin blog 'a bakabilirsiniz.
+dashboard.new_version_hint=Forgejo %s ลimdi hazฤฑr, %s รงalฤฑลtฤฑrฤฑyorsunuz. Ayrฤฑntฤฑlar iรงin blog 'a bakabilirsiniz.
dashboard.statistic=รzet
dashboard.operations=Bakฤฑm ฤฐลlemleri
dashboard.system_status=Sistem Durumu
@@ -2918,12 +3065,12 @@ packages.size=Boyut
packages.published=Yayฤฑnlandฤฑ
defaulthooks=Varsayฤฑlan Web ฤฐstemcileri
-defaulthooks.desc=Web ฤฐstemcileri, belirli Gitea olaylarฤฑ tetiklendiฤinde otomatik olarak HTTP POST isteklerini sunucuya yapar. Burada tanฤฑmlanan Web ฤฐstemcileri varsayฤฑlandฤฑr ve tรผm yeni depolara kopyalanฤฑr. web istemcileri kฤฑlavuzunda daha fazla bilgi edinin.
+defaulthooks.desc=Web ฤฐstemcileri, belirli Forgejo olaylarฤฑ tetiklendiฤinde otomatik olarak HTTP POST isteklerini sunucuya yapar. Burada tanฤฑmlanan Web ฤฐstemcileri varsayฤฑlandฤฑr ve tรผm yeni depolara kopyalanฤฑr. web istemcileri kฤฑlavuzunda daha fazla bilgi edinin.
defaulthooks.add_webhook=Varsayฤฑlan Web ฤฐstemcisi Ekle
defaulthooks.update_webhook=Varsayฤฑlan Web ฤฐstemcisini Gรผncelle
systemhooks=Sistem Web ฤฐstemcileri
-systemhooks.desc=Belirli Gitea olaylarฤฑ tetiklendiฤinde Web istemcileri otomatik olarak bir sunucuya HTTP POST istekleri yapar. Burada tanฤฑmlanan web istemcileri sistemdeki tรผm depolar รผzerinde รงalฤฑลฤฑr, bu yรผzden lรผtfen bunun olabilecek tรผm performans sonuรงlarฤฑnฤฑ gรถz รถnรผnde bulundurun. web istemcileri kฤฑlavuzunda daha fazla bilgi edinin.
+systemhooks.desc=Belirli Forgejo olaylarฤฑ tetiklendiฤinde Web istemcileri otomatik olarak bir sunucuya HTTP POST istekleri yapar. Burada tanฤฑmlanan web istemcileri sistemdeki tรผm depolar รผzerinde รงalฤฑลฤฑr, bu yรผzden lรผtfen bunun olabilecek tรผm performans sonuรงlarฤฑnฤฑ gรถz รถnรผnde bulundurun. web istemcileri kฤฑlavuzunda daha fazla bilgi edinin.
systemhooks.add_webhook=Sistem Web ฤฐstemcisi Ekle
systemhooks.update_webhook=Sistem Web ฤฐstemcisi Gรผncelle
@@ -3018,18 +3165,18 @@ auths.tips=ฤฐpuรงlarฤฑ
auths.tips.oauth2.general=OAuth2 Kimlik Doฤrulama
auths.tips.oauth2.general.tip=Yeni bir OAuth2 kimlik doฤrulama kaydederken, geri รงaฤฤฑrma/yรถnlendirme URL'si ลu olmalฤฑdฤฑr:
auths.tip.oauth2_provider=OAuth2 Saฤlayฤฑcฤฑsฤฑ
-auths.tip.bitbucket=https://bitbucket.org/account/user//oauth-consumers/new adฤฑnda yeni bir OAuth tรผketicisi kaydedin ve 'Hesap' - 'Oku' iznini ekleyin
+auths.tip.bitbucket=%s
auths.tip.nextcloud=Aลaฤฤฑdaki "Ayarlar -> Gรผvenlik -> OAuth 2.0 istemcisi" menรผsรผnรผ kullanarak รถrneฤinize yeni bir OAuth tรผketicisi kaydedin
-auths.tip.dropbox=https://www.dropbox.com/developers/apps adresinde yeni bir uygulama oluลtur
-auths.tip.facebook=https://developers.facebook.com/apps adresinde yeni bir uygulama kaydedin ve "Facebook Giriล" รผrรผnรผnรผ ekleyin
-auths.tip.github=https://github.com/settings/applications/new adresinde yeni bir OAuth uygulamasฤฑ kaydedin
+auths.tip.dropbox=%s adresinde yeni bir uygulama oluลtur
+auths.tip.facebook=%s adresinde yeni bir uygulama kaydedin ve "Facebook Giriล" รผrรผnรผnรผ ekleyin
+auths.tip.github=%s adresinde yeni bir OAuth uygulamasฤฑ kaydedin
auths.tip.gitlab=https://gitlab.com/profile/applications adresinde yeni bir uygulama kaydedin
-auths.tip.google_plus=OAuth2 istemci kimlik bilgilerini https://console.developers.google.com/ adresindeki Google API konsolundan edinin
+auths.tip.google_plus=OAuth2 istemci kimlik bilgilerini %s adresindeki Google API konsolundan edinin
auths.tip.openid_connect=Bitiล noktalarฤฑnฤฑ belirlemek iรงin OpenID Connect Discovery URL'sini kullanฤฑn (/.well-known/openid-configuration)
-auths.tip.twitter=https://dev.twitter.com/apps adresine gidin, bir uygulama oluลturun ve โBu uygulamanฤฑn Twitter ile oturum aรงmak iรงin kullanฤฑlmasฤฑna izin verโ seรงeneฤinin etkin olduฤundan emin olun
-auths.tip.discord=https://discordapp.com/developers/applications/me adresinde yeni bir uygulama kaydedin
-auths.tip.gitea=Yeni bir OAuth2 uygulamasฤฑ kaydedin. Rehber https://forgejo.org/docs/latest/user/oauth2-provider adresinde bulunabilir
-auths.tip.yandex=`https://oauth.yandex.com/client/new adresinde yeni bir uygulama oluลturun. "Yandex.Passport API'sฤฑ" bรถlรผmรผnden aลaฤฤฑdaki izinleri seรงin: "E-posta adresine eriลim", "Kullanฤฑcฤฑ avatarฤฑna eriลim" ve "Kullanฤฑcฤฑ adฤฑna, ad ve soyadฤฑna, cinsiyete eriลim"`
+auths.tip.twitter=%s adresine gidin, bir uygulama oluลturun ve โBu uygulamanฤฑn Twitter ile oturum aรงmak iรงin kullanฤฑlmasฤฑna izin verโ seรงeneฤinin etkin olduฤundan emin olun
+auths.tip.discord=%s adresinde yeni bir uygulama kaydedin
+auths.tip.gitea=Yeni bir OAuth2 uygulamasฤฑ kaydedin. Rehber %s adresinde bulunabilir
+auths.tip.yandex=`%s adresinde yeni bir uygulama oluลturun. "Yandex.Passport API'sฤฑ" bรถlรผmรผnden aลaฤฤฑdaki izinleri seรงin: "E-posta adresine eriลim", "Kullanฤฑcฤฑ avatarฤฑna eriลim" ve "Kullanฤฑcฤฑ adฤฑna, ad ve soyadฤฑna, cinsiyete eriลim"`
auths.tip.mastodon=Kimlik doฤrulamasฤฑ yapmak istediฤiniz mastodon รถrneฤi iรงin รถzel bir รถrnek URL girin (veya varsayฤฑlan olanฤฑ kullanฤฑn)
auths.edit=Kimlik Doฤrulama Kaynaฤฤฑ Dรผzenle
auths.activated=Bu Kimlik Doฤrulama Kaynaฤฤฑ Etkinleลtirildi
@@ -3238,6 +3385,23 @@ notices.op=ฤฐลlem
notices.delete_success=Sistem bildirimleri silindi.
+self_check = รz Denetim
+config_summary = รzet
+config_settings = Ayarlar
+dashboard.sync_repo_tags = Etiketleri git verisinden veritabanฤฑna eลitle
+emails.delete = E-postayฤฑ Sil
+emails.delete_desc = Bu e-posta adresini silmek istediฤinizden emin misiniz?
+emails.deletion_success = E-posta adresi silindi.
+emails.delete_primary_email_error = Ana e-posta adresini silemezsiniz.
+config.cache_test = รnbelleฤi Sฤฑna
+config.cache_test_failed = รnbelleฤin incelenmesi baลarฤฑsฤฑz oldu: %v.
+config.cache_test_slow = รnbellek sฤฑnamasฤฑ baลarฤฑlฤฑ, ancak yanฤฑt yavaล: %s.
+config.cache_test_succeeded = รnbellek sฤฑnamasฤฑ baลarฤฑlฤฑ, %s sรผrede bir yanฤฑt alฤฑndฤฑ.
+config.open_with_editor_app_help = Klon menรผsรผ iรงin "Birlikte aรง" dรผzenleyicileri. Boล bฤฑrakฤฑlฤฑrsa, varsayฤฑlan kullanฤฑlacaktฤฑr. Varsayฤฑlanฤฑ gรถrmek iรงin geniลletin.
+self_check.no_problem_found = Henรผz bir sorun bulunmadฤฑ.
+self_check.database_collation_mismatch = Veritabanฤฑnฤฑn ลu harmanlamayฤฑ kullanmasฤฑnฤฑ bekle: %s
+self_check.database_inconsistent_collation_columns = Veritabanฤฑ %s harmanlamasฤฑnฤฑ kullanฤฑyor, ancak bu sรผtunlar uyumsuz harmanlamalar kullanฤฑyor. Bu beklenmedik sorunlar oluลturabilir.
+
[action]
create_repo=depo %s oluลturuldu
rename_repo=%[1]s
olan depo adฤฑnฤฑ %[3]s buna รงevirdi
@@ -3331,7 +3495,7 @@ error.unit_not_allowed=Bu depo bรถlรผmรผne eriลme izniniz yok.
title=Paketler
desc=Depo paketlerini yรถnet.
empty=Henรผz hiรงbir paket yok.
-empty.documentation=Paket kรผtรผฤรผ hakkฤฑnda daha fazla bilgi iรงin, belgeye bakabilirsiniz.
+empty.documentation=Paket kรผtรผฤรผ hakkฤฑnda daha fazla bilgi iรงin, belgeye bakabilirsiniz.
empty.repo=Bir paket yรผklediniz ama burada gรถsterilmiyor mu? Paket ayarlarฤฑ na gidin ve bu depoya baฤlantฤฑ verin.
registry.documentation=%s kรผtรผฤรผ hakkฤฑnda daha fazla bilgi iรงin, belgeye bakabilirsiniz.
filter.type=Tรผr
@@ -3478,6 +3642,9 @@ owner.settings.chef.title=Chef Kรผtรผฤรผ
owner.settings.chef.keypair=Anahtar รงifti รผret
owner.settings.chef.keypair.description=Chef kรผtรผฤรผnde kimlik doฤrulamasฤฑ iรงin bir anahtar รงifti gereklidir. Eฤer daha รถnce bir anahtar รงifti รผrettiyseniz, yeni bir anahtar รงifti รผretmek eski anahtar รงiftini ฤฑskartaya รงฤฑkartacaktฤฑr.
+npm.dependencies.bundle = Paketlenmiล Baฤฤฑmlฤฑlฤฑklar
+rpm.repository.multiple_groups = Bu paket birรงok grupta mevcut.
+
[secrets]
secrets=Gizlilikler
description=Gizlilikler belirli iลlemlere aktarฤฑlacaktฤฑr, bunun dฤฑลฤฑnda okunamaz.
@@ -3569,7 +3736,7 @@ need_approval_desc=Deฤiลiklik isteฤi รงatalฤฑnda iล akฤฑลฤฑ รงalฤฑลtฤฑrmak
variables=Deฤiลkenler
variables.management=Deฤiลken Yรถnetimi
-variables.creation=Deฤiลken Ekle
+variables.creation=Deฤiลken ekle
variables.none=Henรผz hiรงbir deฤiลken yok.
variables.deletion=Deฤiลkeni kaldฤฑr
variables.deletion.description=Bir deฤiลkeni kaldฤฑrma kalฤฑcฤฑdฤฑr ve geri alฤฑnamaz. Devam edilsin mi?
@@ -3585,17 +3752,48 @@ runs.no_workflows.documentation = Gitea ฤฐลlem'i hakkฤฑnda daha fazla bilgi iรง
variables.id_not_exist = %d kimlikli deฤiลken mevcut deฤil.
runs.no_workflows.quick_start = Gitea ฤฐลlem'i nasฤฑl baลlatacaฤฤฑnฤฑzฤฑ bilmiyor musunuz? Hฤฑzlฤฑ baลlangฤฑรง rehberine bakabilirsiniz.
+runs.no_job_without_needs = ฤฐล akฤฑลฤฑ en azฤฑndan baฤฤฑmlฤฑlฤฑฤฤฑ olmayan bir gรถrev iรงermelidir.
+runs.no_job = ฤฐล akฤฑลฤฑ en azฤฑndan bir gรถrev iรงermelidir
+runs.expire_log_message = Gรผnlรผkler, รงok eski olduklarฤฑ iรงin temizlendiler.
+
[projects]
type-1.display_name=Kiลisel Proje
type-2.display_name=Depo Projesi
type-3.display_name=Organizasyon Projesi
+deleted.display_name = Silinmiล proje
[git.filemode]
changed_filemode=%[1]s โ %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=Dizin
normal_file=Normal dosya
executable_file=รalฤฑลtฤฑrฤฑlabilir dosya
symbolic_link=Sembolik Baฤlantฤฑ
submodule=Alt modรผl
+
+
+[search]
+project_kind = Projeleri ara...
+org_kind = Organizasyonlarฤฑ araโฆ
+team_kind = Takฤฑmlarฤฑ araโฆ
+search = Araโฆ
+code_kind = Kod araโฆ
+type_tooltip = Arama tรผrรผ
+repo_kind = Depolarฤฑ ara...
+user_kind = Kullanฤฑcฤฑlarฤฑ araโฆ
+milestone_kind = Kilometre taลlarฤฑnฤฑ ara...
+branch_kind = Dallarฤฑ ara...
+package_kind = Paketleri ara...
+commit_kind = Katkฤฑlarฤฑ ara...
+runner_kind = รalฤฑลtฤฑrฤฑcฤฑlarฤฑ ara...
+no_results = Eลleลen sonuรง bulunamadฤฑ.
+code_search_unavailable = Kod aramasฤฑ ลu anda kullanฤฑma aรงฤฑk deฤildir. Lรผtfen site yรถneticisi ile iletiลime geรงin.
+issue_kind = Sorunlarฤฑ ara...
+pull_kind = Birleลtirme isteklerini ara...
+code_search_by_git_grep = Anlฤฑk kod aramasฤฑ sonuรงlarฤฑ "git grep" komutu tarafฤฑndan saฤlanmaktadฤฑr. Site yรถneticisinin kod endekslemesini aรงmasฤฑ durumunda daha iyi sonuรงlar verilmesi mรผmkรผn olabilir.
+keyword_search_unavailable = Anahtar kelime ile arama ลu anda kullanฤฑma aรงฤฑk deฤildir. Lรผtfen site yรถneticisi ile iletiลime geรงin.
+fuzzy_tooltip = Arama terimine yakฤฑn olan eลleลmeleri dahil et
+union_tooltip = Boลlukla ayrฤฑlmฤฑล anahtar kelime eลleลmelerini dahil et
+exact_tooltip = Sadece arama terimiyle tam uyuลan sonuรงlarฤฑ dahit et.
+fuzzy = Bulanฤฑk
+exact = Tam
diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini
index 6334bcf469..bb80e54914 100644
--- a/options/locale/locale_uk-UA.ini
+++ b/options/locale/locale_uk-UA.ini
@@ -23,10 +23,10 @@ toc=ะะผััั
licenses=ะััะตะฝะทัั
return_to_forgejo=ะะพะฒะตัะฝััะธัั ะดะพ Forgejo
-username=ะะผ'ั ะบัะธัััะฒะฐัะฐ
+username=ะะผ'ั ะบะพัะธัััะฒะฐั_ะบะธ
email=ะะดัะตัะฐ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
password=ะะฐัะพะปั
-access_token=ะขะพะบะตะฝ ะะพัััะฟั
+access_token=ะขะพะบะตะฝ ะดะพัััะฟั
re_type=ะัะดัะฒะตัะดะถะตะฝะฝั ะฟะฐัะพะปั
captcha=CAPTCHA
twofa=ะะฒะพัะฐะบัะพัะฝะฐ ะฐะฒัะพัะธะทะฐััั
@@ -41,11 +41,11 @@ mirror=ะะทะตัะบะฐะปะพ
new_repo=ะะพะฒะธะน ัะตะฟะพะทะธัะพััะน
new_migrate=ะะพะฒะฐ ะผัะณัะฐััั
new_mirror=ะะพะฒะต ะดะทะตัะบะฐะปะพ
-new_fork=ะะพะฒะธะน ัะตะฟะพะทะธัะพััะน - ะบะพะฟัั
+new_fork=ะะพะฒะธะน ัะพัะบ ัะตะฟะพะทะธัะพััั
new_org=ะะพะฒะฐ ะพัะณะฐะฝัะทะฐััั
new_project=ะะพะฒะธะน ะฟัะพัะบั
manage_org=ะะตััะฒะฐะฝะฝั ะพัะณะฐะฝัะทะฐัััะผะธ
-admin_panel=ะะฐะฝะตะปั ะะดะผัะฝััััะฐัะพัะฐ
+admin_panel=ะะฐะฝะตะปั ะฐะดะผัะฝััััะฐััั
account_settings=ะะฐะปะฐัััะฒะฐะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
settings=ะะฐะปะฐัััะฒะฐะฝะฝั
your_profile=ะัะพััะปั
@@ -86,7 +86,7 @@ preview=ะะพะฟะตัะตะดะฝัะน ะฟะตัะตะณะปัะด
loading=ะะฐะฒะฐะฝัะฐะถะตะฝะฝัโฆ
error=ะะพะผะธะปะบะฐ
-error404=ะกัะพััะฝะบะฐ, ะดะพ ัะบะพั ะฒะธ ะฝะฐะผะฐะณะฐััะตัั ะทะฒะตัะฝััะธัั ะฐะฑะพ ะดะพ , ะฝะต ััะฝัั ะฐะฑะพ ะะธ ะฝะต ะผะฐััะต ะฟัะฐะฒะฐ ะฝะฐ ัั ะฟะตัะตะณะปัะด.
+error404=ะกัะพััะฝะบะฐ, ะดะพ ัะบะพั ะฒะธ ะฝะฐะผะฐะณะฐััะตัั ะทะฒะตัะฝััะธัั, ะฝะต ััะฝัั , ัั ะฑัะปะพ ะฒะธะดะฐะปะตะฝะพ ะฐะฑะพ ะฒะธ ะฝะต ะผะฐััะต ะฟัะฐะฒะฐ ะฝะฐ ัั ะฟะตัะตะณะปัะด.
never=ะัะบะพะปะธ
@@ -104,11 +104,11 @@ name=ะะฐะทะฒะฐ
logo = ะะพะณะพัะธะฟ
sign_in_with_provider = ะฃะฒัะนัะธ ัะตัะตะท %s
tracked_time_summary = ะัะดััะผะพะบ ะฒัะดััะตะถะตะฝะพะณะพ ัะฐัั ะท ััะฐั
ัะฒะฐะฝะฝัะผ ััะปััััะฒ ัะฟะธัะบั ะทะฐะดะฐั
-enable_javascript = ะกะฐะนัั ััะตะฑะฐ JavaScript.
+enable_javascript = ะฆะตะน ะฒะตะฑัะฐะนั ะฟะพััะตะฑัั JavaScript.
webauthn_press_button = ะะฐัะธัะฝััั ะบะฝะพะฟะบั ะฝะฐ ะบะปััั ะฑะตะทะฟะตะบะธโฆ
webauthn_use_twofa = ะะฒะตะดััั ะบะพะด ะฟัะดัะฒะตัะดะถะตะฝะฝั ะท ัะตะปะตัะพะฝั
webauthn_error = ะะต ะฒะดะฐะปะพัั ัะพะทะฟัะทะฝะฐัะธ ะบะปัั ะฑะตะทะฟะตะบะธ.
-webauthn_error_unknown = ะขัะฐะฟะธะปะฐัั ะฝะตะฒัะดะพะผะฐ ะฟะพะผะธะปะบะฐ. ะัะดั ะปะฐัะบะฐ, ะฟะพะฒัะพัััั ัะฟัะพะฑั.
+webauthn_error_unknown = ะกัะฐะปะฐัั ะฝะตะฒัะดะพะผะฐ ะฟะพะผะธะปะบะฐ. ะัะดั ะปะฐัะบะฐ, ะฟะพะฒัะพัััั ัะฟัะพะฑั.
webauthn_error_unable_to_process = ะกะตัะฒะตั ะฝะต ะทะผัะณ ะพะฑัะพะฑะธัะธ ะทะฐะฟะธั.
webauthn_error_duplicated = ะะฐะฟะธั ัะท ะฝะฐะดะฐะฝะธะผ ะบะปััะตะผ ะฑะตะทะฟะตะบะธ ะฒัะดั
ะธะปะตะฝะพ. ะะฟะตะฒะฝััััั, ัะพ ััะพะณะพ ะบะปััะฐ ัะต ะฝะต ะทะฐัะตััััะพะฒะฐะฝะพ.
webauthn_error_empty = ะะปัั ัะปัะด ัะบะพัั ะฝะฐะทะฒะฐัะธ.
@@ -132,18 +132,56 @@ value = ะะฝะฐัะตะฝะฝั
webauthn_insert_key = ะัะด'ัะดะฝะฐะนัะต ะบะปัั ะฑะตะทะฟะตะบะธ
download_logs = ะะฐะฒะฐะฝัะฐะถะธัะธ ะถััะฝะฐะปะธ
webauthn_sign_in = ะะฐัะธัะฝััั ะบะฝะพะฟะบั ะฝะฐ ะบะปััั ะฑะตะทะฟะตะบะธ. ะฏะบัะพ ะบะปัั ะฑะตะทะฟะตะบะธ ะฝะต ะผะฐั ะบะฝะพะฟะบะธ, ะฒัะด'ัะดะฝะฐะนัะต ะนะพะณะพ ะน ะฟัะด'ัะดะฝะฐะนัะต ัะต ัะฐะท.
-webauthn_unsupported_browser = ะะฐั ะพะณะปัะดะฐั ะฝะฐัะฐะทั ะฝะต ะฟัะดััะธะผัั WebAuthn.
+webauthn_unsupported_browser = ะะฐั ะฑัะฐัะทะตั ะฝะฐัะฐะทั ะฝะต ะฟัะดััะธะผัั WebAuthn.
webauthn_error_insecure = WebAuthn ะฟัะดััะธะผัั ะปะธัะต ะทะฐั
ะธัะตะฝั ะท'ัะดะฝะฐะฝะฝั. ะะปั ัะตัััะฒะฐะฝะฝั ัะตัะตะท HTTP ะผะพะถะตัะต ะฒะธะบะพัะธััะฐัะธ origin-ััะดะพะบ ยซlocalhostยป ัะธ ยซ127.0.0.1ยป
webauthn_error_timeout = ะะปัั ะฝะต ะฒััะธะณ ะทัะธัะฐัะธัั ะฟัะพััะณะพะผ ะฒัะดะฒะตะดะตะฝะพะณะพ ัะตัะผัะฝั. ะัะดั ะปะฐัะบะฐ, ะฟะตัะตะทะฐะฒะฐะฝัะฐะถัะต ััะพััะฝะบั ะน ะฟะพะฒัะพัััั ัะฟัะพะฑั.
locked = ะะฐะฑะปะพะบะพะฒะฐะฝะพ
+filter.is_template = ะจะฐะฑะปะพะฝะธ
+test = ะขะตัั
+show_timestamps = ะะพะบะฐะทัะฒะฐัะธ ะฒัะดะผััะบะธ ัะฐัั
+filter.clear = ะัะธััะธัะธ ััะปัััะธ
+filter.is_archived = ะัั
ัะฒะพะฒะฐะฝะพ
+filter = ะคัะปัััะธ
+toggle_menu = ะะตัะตะผะบะฝััะธ ะฒะธะดะธะผัััั ะผะตะฝั
+confirm_delete_artifact = ะะธ ะฒะฟะตะฒะฝะตะฝั, ัะพ ั
ะพัะตัะต ะฒะธะดะฐะปะธัะธ ะฐััะตัะฐะบั ยซ%sยป?
+artifacts = ะััะตัะฐะบัะธ
+filter.not_archived = ะะต ะฐัั
ัะฒะพะฒะฐะฝะพ
+filter.public = ะะฐะณะฐะปัะฝะพะดะพัััะฟะฝั
+filter.private = ะัะธะฒะฐัะฝั
+more_items = ะัะปััะต ะฟัะฝะบััะฒ
+remove_label_str = ะะธะดะฐะปะธัะธ ะพะฑ'ัะบั ยซ%sยป
+new_repo.title = ะะพะฒะธะน ัะตะฟะพะทะธัะพััะน
+new_migrate.title = ะะพะฒะฐ ะผัะณัะฐััั
+new_org.title = ะะพะฒะฐ ะพัะณะฐะฝัะทะฐััั
+new_repo.link = ะะพะฒะธะน ัะตะฟะพะทะธัะพััะน
+new_migrate.link = ะะพะฒะฐ ะผัะณัะฐััั
+new_org.link = ะะพะฒะฐ ะพัะณะฐะฝัะทะฐััั
+copy_generic = ะกะบะพะฟััะฒะฐัะธ ะดะพ ะฑััะตัะฐ ะพะฑะผัะฝั
+show_log_seconds = ะะพะบะฐะทัะฒะฐัะธ ัะตะบัะฝะดะธ
+show_full_screen = ะะพะบะฐะทัะฒะฐัะธ ั ะฟะพะฒะฝะพะตะบัะฐะฝะฝะพะผั ัะตะถะธะผั
+filter.is_fork = ะคะพัะบะธ
+filter.not_fork = ะะต ัะพัะบะธ
+filter.is_mirror = ะะทะตัะบะฐะปะฐ
+filter.not_mirror = ะะต ะดะทะตัะบะฐะปะฐ
+filter.not_template = ะะต ัะฐะฑะปะพะฝะธ
+error413 = ะะธ ะฒะธัะตัะฟะฐะปะธ ัะฒะพั ะบะฒะพัั.
+invalid_data = ะะตะดัะนัะฝั ะดะฐะฝั: %v
+copy_path = ะะพะฟััะฒะฐัะธ ัะปัั
[aria]
-footer.software = ะัะพ ะฟัะพะณัะฐะผั
+footer.software = ะัะพ ะทะฐััะพััะฝะพะบ
footer.links = ะะพัะธะปะฐะฝะฝั
+footer = ะะธะถะฝัะน ะบะพะปะพะฝัะธััะป
+navbar = ะะฐะฝะตะปั ะฝะฐะฒัะณะฐััั
[heatmap]
less = ะะตะฝัะต
more = ะัะปััะต
+contributions_one = ะฒะฝะตัะพะบ
+number_of_contributions_in_the_last_12_months = %s ะฒะฝะตัะบัะฒ ะทะฐ ะพััะฐะฝะฝั 12 ะผัััััะฒ
+contributions_zero = ะะตะผะฐ ะฒะฝะตัะบัะฒ
+contributions_format = {contributions} ะทะฐ {month} {day}, {year}
+contributions_few = ะฒะฝะตัะบะธ
[editor]
buttons.bold.tooltip = ะะพะดะฐัะธ ะณััะฑะธะน ััะธัั
@@ -155,24 +193,46 @@ buttons.list.unordered.tooltip = ะะพะดะฐัะธ ะผะฐัะบะพะฒะฐะฝะธะน ัะฟะธัะพะบ
buttons.list.ordered.tooltip = ะะพะดะฐัะธ ะฝัะผะตัะพะฒะฐะฝะธะน ัะฟะธัะพะบ
buttons.list.task.tooltip = ะะพะดะฐัะธ ัะฟะธัะพะบ ะทะฐะฒะดะฐะฝั
buttons.heading.tooltip = ะะพะดะฐัะธ ะทะฐะณะพะปะพะฒะพะบ
+buttons.switch_to_legacy.tooltip = ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะทะฐััะฐััะปะธะน ัะตะดะฐะบัะพั ะทะฐะผัััั ะฟะพัะพัะฝะพะณะพ
+buttons.disable_monospace_font = ะะธะผะบะฝััะธ ะผะพะฝะพัะธัะธะฝะฝะธะน ััะธัั
+buttons.indent.tooltip = ะะบะปะฐััะธ ะฟัะตะดะผะตั ะฝะฐ ะพะดะธะฝ ััะฒะตะฝั
+buttons.unindent.tooltip = ะะธะบะปะฐััะธ ะพะฑ'ัะบั ะฝะฐ ะพะดะธะฝ ััะฒะตะฝั
+buttons.mention.tooltip = ะะณะฐะดะฐัะธ ะบะพัะธัััะฒะฐัะฐ ัะธ ะบะพะผะฐะฝะดั
+buttons.ref.tooltip = ะะพัะปะฐัะธัั ะฝะฐ ะทะฐะดะฐัั ัะธ ะฝะฐ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั
+buttons.enable_monospace_font = ะฃะฒัะผะบะฝััะธ ะผะพะฝะพัะธัะธะฝะฝะธะน ััะธัั
+buttons.new_table.tooltip = ะะพะดะฐัะธ ัะฐะฑะปะธัั
+table_modal.label.columns = ะกัะพะฒะฟัั
+table_modal.header = ะะพะดะฐัะธ ัะฐะฑะปะธัั
+table_modal.placeholder.header = ะะฐะณะพะปะพะฒะพะบ
+table_modal.placeholder.content = ะะผััั
+table_modal.label.rows = ะ ัะดะบะธ
+link_modal.description = ะะฟะธั
+link_modal.url = URL
+link_modal.header = ะะพะดะฐัะธ ะฟะพัะธะปะฐะฝะฝั
+link_modal.paste_reminder = ะัะดะบะฐะทะบะฐ: ัะบัะพ ัะบะพะฟััะฒะฐัะธ URL-ะฐะดัะตัั ะฒ ะฑััะตั ะพะฑะผัะฝั, ะผะพะถะฝะฐ ััะฒะพััะฒะฐัะธ ะฟะพัะธะปะฐะฝะฝั, ะฒััะฐะฒะปัััะธ ัั ะฑะตะทะฟะพัะตัะตะดะฝัะพ ะฒ ัะตะดะฐะบัะพัั.
[filter]
+string.asc = ะ - ะฏ
+string.desc = ะฏ - ะ
[error]
occurred=ะกัะฐะปะฐัั ะฟะพะผะธะปะบะฐ
missing_csrf=ะะตะบะพัะตะบัะฝะธะน ะทะฐะฟะธั: ัะพะบะตะฝ CSRF ะฝะต ะทะฐะดะฐะฝะพ
network_error=ะะพะผะธะปะบะฐ ะผะตัะตะถั
+server_internal = ะะฝัััััะฝั ะฟะพะผะธะปะบะฐ ัะตัะฒะตัะฐ
+report_message = ะฏะบัะพ ะฒะธ ะดัะผะฐััะต, ัะพ ัะต ะฒะฐะดะฐ Forgejo, ะฑัะดั ะปะฐัะบะฐ, ะฟะพััะบะฐะนัะต ัั ั ัะฟะธัะบั ะทะฐะดะฐั ะฝะฐ Codeberg ัะธ ััะฒะพัััั ะฝะพะฒั ะทะฐะดะฐัั, ัะบัะพ ะฝะตะพะฑั
ัะดะฝะพ.
+not_found = ะฆัะปั ะฝะต ะฑัะปะฐ ะทะฝะฐะนะดะตะฝะฐ.
[startpage]
app_desc=ะัััะฝะธะน ะฒะปะฐัะฝะธะน ัะตัะฒัั ั
ะพััะธะฝะณั ัะตะฟะพะทะธัะพัััะฒ Git
install=ะะตะณะบะพ ะฒััะฐะฝะพะฒะธัะธ
platform=ะะปะฐััะพัะผะพะฝะตะทะฐะปะตะถะฝัััั
-platform_desc=Forgejo ะฒะธะบะพะฝัััััั ะฝะฐ ะฟะปะฐััะพัะผั, ะดะปั ัะบะพั ะผะพะถะปะธะฒะพ ัะบะพะผะฟัะปัะฒะฐัะธ Go : Windows, macOS, Linux, ARM, ัะฐ ัะฝัะธั
. ะะฑะตัััั ัั, ัะบะฐ ะฒะฐะผ ะดะพ ะฒะฟะพะดะพะฑะธ!
+platform_desc=Forgejo ะฟัะดัะฒะตัะดะถะตะฝะพ ะฟัะฐััั ะฝะฐ ะฒัะปัะฝะธั
ะพะฟะตัะฐััะนะฝะธั
ัะธััะตะผะฐั
, ัะบ-ะพั Linux ั FreeBSD, ัะฐะบ ัะฐะผะพ ะน ะฝะฐ ััะทะฝะธั
ะฐัั
ััะตะบัััะฐั
ะฆะ. ะะฑะตัััั, ัะบะฐ ะฒะฐะผ ะดะพ ะฒะฟะพะดะพะฑะธ!
lightweight=ะะตะฒะธะฑะฐะณะปะธะฒัััั
lightweight_desc=Forgejo ะผะฐั ะฝะธะทัะบั ะฒะธะผะพะณะธ ะดะพ ัะตัััััะฒ ัะฐ ะผะพะถะต ะฟัะฐััะฒะฐัะธ ะฝะฐ ะฝะตะดะพัะพะณะพะผั Raspberry Pi. ะะฐะพัะฐะดััะต ะตะฝะตัะณัั ัะฒะพะณะพ ะบะพะผะฟ'ััะตัะฐ!
license=ะัะดะบัะธัะธะน ะฒะธั
ัะดะฝะธะน ะบะพะด
-license_desc=ะัะดะฒัะดะฐะนัะต Forgejo ! ะัะธัะดะฝะฐะนัะตัั ะดะพ ะฝะฐั ัะฐ ะทัะพะฑััั ัะฒัะน ะฒะฝะตัะพะบ ะดะพ ะฟัะพัะบัั, ัะพะฑ ะทัะพะฑะธัะธ ะนะพะณะพ ัะต ะบัะฐัะต. ะะต ะฑัะนัะตัั ะดะพะปััะธัะธัั!
-install_desc = ะัะพััะพ ะทะฐะฟัััััั ัะถะต ะทัะฑัะฐะฝั ะฟัะพะณัะฐะผั ะดะปั ัะฒะพัั ะฟะปะฐััะพัะผะธ, ัะพะทะณะพัะฝััั ัั ะทะฐ ะดะพะฟะพะผะพะณะพั Docker ะฐะฑะพ ะฒััะฐะฝะพะฒััั ะฟะฐะบัะฝะพะบ .
+license_desc=ะัะดะฒัะดะฐะนัะต Forgejo ! ะัะธัะดะฝัะนัะตัั ะดะพ ะฝะฐั ั ะทัะพะฑััั ัะฒัะน ะฒะฝะตัะพะบ , ัะพะฑ ะฟะพะบัะฐัะธัะธ ะฟัะพัะบั ัะต ะฑัะปััะต. ะะต ะฑัะนัะตัั ะดะพะปััะธัะธัั!
+install_desc = ะัะพััะพ ะทะฐะฟัััััั ัะถะต ะทัะฑัะฐะฝั ะฟัะพะณัะฐะผั ะดะปั ัะฒะพัั ะฟะปะฐััะพัะผะธ, ัะพะทะณะพัะฝััั ัั ะทะฐ ะดะพะฟะพะผะพะณะพั Docker ะฐะฑะพ ะฒััะฐะฝะพะฒััั ะฟะฐะบัะฝะพะบ .
[install]
install=ะััะฐะฝะพะฒะปะตะฝะฝั
@@ -183,7 +243,7 @@ db_type=ะขะธะฟ ะฑะฐะทะธ ะดะฐะฝะธั
host=ะฅะพัั
user=ะะผ'ั ะบัะธัััะฒะฐัะฐ
password=ะะฐัะพะปั
-db_name=ะะผ'ั ะฑะฐะทะธ ะดะฐะฝะธั
+db_name=ะะฐะทะฒะฐ ะฑะฐะทะธ ะดะฐะฝะธั
db_schema=ะกั
ะตะผะฐ
db_schema_helper=ะะฐะปะธััะต ะฟัััะธะผ ะดะปั ะฑะฐะทะธ ะดะฐะฝะธั
ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ("ะฟัะฑะปััะฝะฐ").
ssl_mode=SSL
@@ -198,92 +258,108 @@ err_empty_db_path=ะจะปัั
ะดะพ ัะฐะนะปั ะฑะฐะทะธ ะดะฐะฝะธั
SQLite3 ะฝะต ะผะพ
no_admin_and_disable_registration=ะะธ ะฝะต ะผะพะถะตัะต ะฒะธะผะบะฝััะธ ัะตััััะฐััั ะดะพ ััะฒะพัะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะฐะดะผัะฝััััะฐัะพัะฐ.
err_empty_admin_password=ะะฐัะพะปั ะฐะดะผัะฝััััะฐัะพัะฐ ะฝะต ะผะพะถะต ะฑััะธ ะฟะพัะพะถะฝัะผ.
err_empty_admin_email=ะะปะตะบััะพะฝะฝะฐ ะฐะดัะตัะฐ ะฐะดะผัะฝััััะฐัะพัะฐ ะฝะต ะผะพะถะต ะฑััะธ ะฟะพัะพะถะฝัะพั.
-err_admin_name_is_reserved=ะะตะฟัะฐะฒะธะปัะฝะต ัะผ'ั ะบะพัะธัััะฒะฐัะฐ-ะฐะดะผัะฝััััะฐัะพัะฐ - ัะผ'ั ะทะฐัะตะทะตัะฒะพะฒะฐะฝะต
+err_admin_name_is_reserved=ะะตะฟัะฐะฒะธะปัะฝะต ัะผ'ั ะบะพัะธัััะฒะฐัะฐ-ะฐะดะผัะฝััััะฐัะพัะฐ โ ัะผ'ั ะทะฐัะตะทะตัะฒะพะฒะฐะฝะต
err_admin_name_pattern_not_allowed=ะะผ'ั ะฐะดะผัะฝััััะฐัะพัะฐ ะฝะตะดัะนัะฝะต, ัะต ัะผ'ั ะฟัะดะฟะฐะดะฐั ะฟัะด ะทะฐัะตะทะตัะฒะพะฒะฐะฝะธะน ัะฐะฑะปะพะฝ
err_admin_name_is_invalid=ะะตะฟัะฐะฒะธะปัะฝะต ัะผ'ั ะบะพัะธัััะฒะฐัะฐ-ะฐะดะผัะฝััััะฐัะพัะฐ
general_title=ะะฐะณะฐะปัะฝั ะฝะฐะปะฐัััะฒะฐะฝะฝั
-app_name=ะะฐะทะฒะฐ ัะฐะนัั
-app_name_helper=ะขัั ะฒะธ ะผะพะถะตัะต ะฒะฒะตััะธ ะฝะฐะทะฒั ัะฒะพัั ะบะพะผะฟะฐะฝัั.
-repo_path=ะะพัะตะฝะตะฒะธะน ัะปัั
ัะตะฟะพะทะธัะพััั
+app_name=ะะฐะทะฒะฐ ะตะบะทะตะผะฟะปััะฐ
+app_name_helper=ะฃะฒะตะดััั ััั ะฝะฐะทะฒั ัะฒะพะณะพ ะตะบะทะตะผะฟะปััะฐ. ะะพะฝะฐ ะฒัะดะพะฑัะฐะถะฐัะธะผะตัััั ะฝะฐ ะบะพะถะฝัะน ััะพััะฝัั.
+repo_path=ะะพัะตะฝะตะฒะฐ ัะตะบะฐ ัะตะฟะพะทะธัะพััั
repo_path_helper=ะัั ะฒะธะปััะตะฝั Git ัะตะฟะพะทะธัะพััั ะฑัะดััั ะทะฑะตัะตะถะตะฝั ะฒ ัะตะน ะบะฐัะฐะปะพะณ.
-lfs_path=ะะพัะตะฝะตะฒะพั ัะปัั
Git LFS
+lfs_path=ะะพัะตะฝะตะฒะธะน ัะปัั
Git LFS
lfs_path_helper=ะฃ ััะน ะฟะฐะฟัั ะฑัะดััั ะทะฑะตััะณะฐัะธัั ัะฐะนะปะธ Git LFS. ะะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ัะพะฑ ะฒะธะผะบะฝััะธ LFS.
-run_user=ะะฐะฟััะบ ะฒัะด ัะผะตะฝั ะะพัะธัััะฒะฐัะฐ
+run_user=ะะพัะธัััะฒะฐั, ะฒัะด ัะบะพะณะพ ะทะฐะฟัััะธัะธ
domain=ะะพะผะตะฝ ัะตัะฒะตัะฐ
domain_helper=ะะพะผะตะฝ ะฐะฑะพ ะฐะดัะตัะฐ ั
ะพััะฐ ัะตัะฒะตัะฐ.
-ssh_port=ะะพัั SSH ัะตัะฒะตัะฐ
-ssh_port_helper=ะะพะผะตั ะฟะพััั, ัะบะธะน ะฒะธะบะพัะธััะพะฒัั SSH ัะตัะฒะตั. ะะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ัะพะฑ ะฒะธะผะบะฝััะธ SSH.
-http_port=Forgejo HTTP ะฟะพัั
-http_port_helper=ะะพะผะตั ะฟะพััั, ัะบะธะน ะฑัะดะต ะฟัะพัะปัั
ะพะฒัะฒะฐัะธัั Forgejos ะฒะตะฑ-ัะตัะฒะตัะพะผ.
-app_url=ะะฐะทะพะฒะฐ URL-ะฐะดัะตัะฐ Forgejo
+ssh_port=ะะพัั SSH-ัะตัะฒะตัะฐ
+ssh_port_helper=ะะพะผะตั ะฟะพััั, ัะพ ะฒะธะบะพัะธััะพะฒัั SSH ัะตัะฒะตั. ะะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ะฐะฑะธ ะฒะธะผะบะฝััะธ SSH.
+http_port=HTTP-ะฟะพัั ะดะปั ะฟัะพัะปัั
ะพะฒัะฒะฐะฝะฝั
+http_port_helper=ะะพะผะตั ะฟะพััั, ัะพ ะฑัะดะต ะฟัะพัะปัั
ะพะฒัะฒะฐัะธัั ะฒะตะฑัะตัะฒะตัะพะผ Forgejo.
+app_url=ะะฐะทะพะฒะฐ URL-ะฐะดัะตัะฐ
app_url_helper=ะะฐะทะพะฒะฐ ะฐะดัะตัะฐ ะดะปั HTTP(S) ะบะปะพะฝัะฒะฐะฝะฝั ัะตัะตะท URL ัะฐ ะฟะพะฒัะดะพะผะปะตะฝั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ.
-log_root_path=ะจะปัั
ะดะพ ะปะพะณ ัะฐะนะปั
+log_root_path=ะจะปัั
ะดะพ ัะฐะนะปั ะถััะฝะฐะปั
log_root_path_helper=ะคะฐะนะปะธ ะถััะฝะฐะปั ะฑัะดััั ะทะฐะฟะธัะฐะฝั ะฒ ัะตะน ะบะฐัะฐะปะพะณ.
optional_title=ะะพะดะฐัะบะพะฒั ะฝะฐะปะฐัััะฒะฐะฝะฝั
-email_title=ะะฐะปะฐัััะฒะฐะฝะฝั Email
-smtp_addr=SMTP ั
ะพัั
-smtp_port=SMTP ะฟะพัั
-smtp_from=ะัะดะฟัะฐะฒะปััะธ Email ะฒัะด ัะผะตะฝั
+email_title=ะะฐะปะฐัััะฒะฐะฝะฝั email
+smtp_addr=ะะดัะตัะฐ SMTP
+smtp_port=ะะพัั SMTP
+smtp_from=ะัะดะฟัะฐะฒะปััะธ email ะฒัะด ัะผะตะฝั
smtp_from_helper=ะะปะตะบััะพะฝะฝะฐ ะฟะพััะฐ ะดะปั ะฒะธะบะพัะธััะฐะฝะฝั ะฒ Gัtea. ะะฒะตะดััั ะทะฒะธัะฐะนะฝั ะตะปะตะบััะพะฝะฝั ะฐะดัะตัั ะฐะฑะพ ะฒะธะบะพัะธััะพะฒัะนัะต ัะพัะผะฐั: "ะะผ'ั" .
-mailer_user=SMTP ะะผ'ั ะบัะธัััะฒะฐัะฐ
-mailer_password=SMTP ะะฐัะพะปั
+mailer_user=SMTP ะะผ'ั ะบะพัะธัััะฒะฐัะฐ
+mailer_password=SMTP ะฟะฐัะพะปั
register_confirm=ะะพัััะฑะฝะพ ะฟัะดัะฒะตัะดะธัะธ ะตะปะตะบััะพะฝะฝั ะฟะพััั ะดะปั ัะตััััะฐััั
mail_notify=ะฃะฒัะผะบะฝััะธ ัะฟะพะฒััะตะฝะฝั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะพั
server_service_title=ะกะตัะฒะตั ั ะฝะฐะปะฐัััะฒะฐะฝะฝั ะทะพะฒะฝััะฝัั
ัะปัะถะฑ
offline_mode=ะฃะฒัะผะบะฝััะธ ะปะพะบะฐะปัะฝะธะน ัะตะถะธะผ
-offline_mode.description=ะัะดะบะปััะธัะธ ััะพัะพะฝะฝั ะผะตัะตะถั ะดะพััะฐะฒะบะธ ะบะพะฝัะตะฝัั ั ะพะฑัะปัะณะพะฒัะฒะฐัะธ ะฒัั ัะตััััะธ ะปะพะบะฐะปัะฝะพ.
+offline_mode.description=ะัะดะบะปััะธัะธ ะฟะพััะฐัะฐะฝะฝั ะบะพะฝัะตะฝัั ะทั ััะพัะพะฝะฝัั
ะผะตัะตะถ ะน ะพะฑัะปัะณะพะฒัะฒะฐัะธ ะฒัั ัะตััััะธ ะปะพะบะฐะปัะฝะพ.
disable_gravatar=ะะธะผะบะฝััะธ Gravatar
-disable_gravatar.description=ะัะดะบะปััะธัะธ Gravatar ั ััะพัะพะฝะฝั ะดะถะตัะตะปะฐ ะฐะฒะฐัะฐััะฒ. ะฏะบัะพ ะบะพัะธัััะฒะฐั ะฝะต ะทะฐะฒะฐะฝัะฐะถะธัั ะฐะฒะฐัะฐั ะปะพะบะฐะปัะฝะพ ัะพ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ะฑัะดะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธัั ััะฐะฝะดะฐััะฝะธะน ะฐะฒะฐัะฐั.
-federated_avatar_lookup=ะฃะฒัะผะบะฝััะธ ัะตะดะตัะฐัะธะฒะฝั ะฐะฒะฐัะฐัะธ
-federated_avatar_lookup.description=ะฃะฒัะผะบะฝััะธ ะทะพะฒะฝััะฝะธะน ะะฒะฐัะฐั ะทะฐ ะดะพะฟะพะผะพะณะพั Libravatar.
+disable_gravatar.description=ะะธะผะบะฝััะธ Gravatar ะฐะฑะพ ัะฝัั ััะพัะพะฝะฝั ะดะถะตัะตะปะฐ ะฐะฒะฐัะฐััะฒ. ะฏะบัะพ ะบะพัะธัััะฒะฐั ะฝะต ะทะฐะฒะฐะฝัะฐะถะธัั ะฒะปะฐัะฝะธะน ะฐะฒะฐัะฐั ะปะพะบะฐะปัะฝะพ, ัะพ ะฑัะดะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธัั ะทะพะฑัะฐะถะตะฝะฝั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ.
+federated_avatar_lookup=ะฃะฒัะผะบะฝััะธ ัะตะดะตัะพะฒะฐะฝั ะฐะฒะฐัะฐัะธ
+federated_avatar_lookup.description=ะฃะฒัะผะบะฝััะธ ะทะพะฒะฝััะฝั ะฐะฒะฐัะฐัะธ ะทะฐ ะดะพะฟะพะผะพะณะพั Libravatar.
disable_registration=ะะธะผะบะฝััะธ ัะฐะผะพัััะนะฝั ัะตััััะฐััั
-disable_registration.description=ะะธะผะบะฝััะธ ัะฐะผะพัััะนะฝั ัะตััััะฐััั ะบะพัะธัััะฒะฐััะฒ, ััะปัะบะธ ะฐะดะผัะฝััััะฐัะพั ะผะพะถะต ััะฒะพััะฒะฐัะธ ะฝะพะฒั ะพะฑะปัะบะพะฒั ะทะฐะฟะธัะธ.
-allow_only_external_registration.description=ะะพะทะฒะพะปะธัะธ ัะตััััะฐััั ััะปัะบะธ ัะตัะตะท ััะพัะพะฝะฝั ัะตัะฒััะธ
+disable_registration.description=ะขัะปัะบะธ ะฐะดะผัะฝััััะฐัะพั ะผะพะถะต ััะฒะพััะฒะฐัะธ ะฝะพะฒั ะพะฑะปัะบะพะฒั ะทะฐะฟะธัะธ. ะะฐัััะนะฝะพ ัะตะบะพะผะตะฝะดััะผะพ ะทะฐะปะธัะธัะธ ัะตััััะฐััั ะฒะธะผะบะฝะตะฝะพั, ัะบัะพ ะฒะธ ะฝะต ะทะฑะธัะฐััะตัั ัะพะทะผัััะฒะฐัะธ ะทะฐะณะฐะปัะฝะพะดะพัััะฟะฝะธะน ะตะบะทะตะผะฟะปัั ัะฐ ัะฟัะธััะธ ะฟะพัะฒั ะฒะตะปะธัะตะทะฝะพั ะบัะปัะบะพััั ัะฟะฐะผ-ะฐะบะฐัะฝััะฒ.
+allow_only_external_registration.description=ะะพัะธัััะฒะฐัะฐะผ ะฑัะดะต ะดะพะทะฒะพะปะตะฝะพ ัะตัััััะฒะฐัะธัั ะปะธัะต ัะตัะตะท ะฝะฐะปะฐััะพะฒะฐะฝั ััะพัะพะฝะฝั ัะตัะฒััะธ.
openid_signin=ะฃะฒัะผะบะฝััะธ ัะตััััะฐััั ะทะฐ ะดะพะฟะพะผะพะณะพั OpenID
openid_signin.description=ะฃะฒัะผะบะฝััะธ ะฒั
ัะด ะทะฐ ะดะพะฟะพะผะพะณะพั OpenID.
openid_signup=ะฃะฒัะผะบะฝััะธ ัะฐะผะพัััะนะฝั ัะตััััะฐััั ะทะฐ ะดะพะฟะพะผะพะณะพั OpenID
-openid_signup.description=ะฃะฒัะผะบะฝััะธ ัะฐะผะพัะตััััะฐััั ะบะพัะธัััะฒะฐััะฒ ะฝะฐ ะพัะฝะพะฒั OpenID.
+openid_signup.description=ะฃะฒัะผะบะฝััะธ ัะฐะผะพัะตััััะฐััั ะบะพัะธัััะฒะฐััะฒ ััะปัะบะธ ัะตัะตะท OpenID.
enable_captcha=ะฃะฒัะผะบะฝััะธ CAPTCHA ะฟัะธ ัะตััััะฐััั
-enable_captcha.description=ะะธะผะฐะณะฐัะธ ะฟะตัะตะฒััะบั CAPTCHA ะฟัะธ ัะฐะผะพัััะนะฝัะน ัะตััััะฐััั ะบะพัะธัััะฒะฐัะฐ.
-require_sign_in_view=ะะธะผะฐะณะฐัะธ ะฐะฒัะพัะธะทะฐััั ะดะปั ะฟะตัะตะณะปัะดั ััะพััะฝะพะบ
-admin_setting.description=ะกัะฒะพัะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะฐะดะผัะฝััััะฐัะพัะฐ ะฝะตะพะฑะพะฒ'ัะทะบะพะฒะพ. ะะตััะธะน ะทะฐัะตััััะพะฒะฐะฝะธะน ะบะพัะธัััะฒะฐั ะฐะฒัะพะผะฐัะธัะฝะพ ััะฐั ะฐะดะผัะฝััััะฐัะพัะพะผ.
+enable_captcha.description=ะะธะผะฐะณะฐัะธ ะฟะตัะตะฒััะบั CAPTCHA ะดะปั ััะฒะพัะตะฝะฝั ะพะฑะปัะบะพะฒะธั
ะทะฐะฟะธััะฒ.
+require_sign_in_view=ะะธะผะฐะณะฐัะธ ะฐะฒัะพัะธะทะฐััั ะดะปั ะฟะตัะตะณะปัะดั ะฒะผัััั ะตะบะทะตะผะฟะปััะฐ
+admin_setting.description=ะกัะฒะพััะฒะฐัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฐะดะผัะฝััััะฐัะพัะฐ ะฝะตะพะฑะพะฒ'ัะทะบะพะฒะพ. ะะตััะธะน ะทะฐัะตััััะพะฒะฐะฝะธะน ะบะพัะธัััะฒะฐั ะฐะฒัะพะผะฐัะธัะฝะพ ััะฐั ะฐะดะผัะฝััััะฐัะพัะพะผ.
admin_title=ะะฐะปะฐัััะฒะฐะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะฐะดะผัะฝััััะฐัะพัะฐ
-admin_name=ะะผ'ั ะบัะธัััะฒะฐัะฐ ะะดะผัะฝััััะฐัะพัะฐ
+admin_name=ะะผ'ั ะบะพัะธัััะฒะฐัะฐ-ะฐะดะผัะฝััััะฐัะพัะฐ
admin_password=ะะฐัะพะปั
confirm_password=ะัะดัะฒะตัะดะถะตะฝะฝั ะฟะฐัะพะปั
admin_email=ะะดัะตัะฐ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
install_btn_confirm=ะััะฐะฝะพะฒะปะตะฝะฝั Forgejo
-test_git_failed=ะะต ะฒ ะทะผะพะทั ะฟะตัะตะฒััะธัะธ 'git' ะบะพะผะฐะฝะดั: %v
-sqlite3_not_available=ะฆั ะฒะตัััั Forgejo ะฝะต ะฟัะดััะธะผัั SQLite3. ะัะดั ะปะฐัะบะฐ, ะทะฐะฒะฐะฝัะฐะถัะต ะพััััะนะฝั ะฑัะฝะฐัะฝั ะฒะตัััั ะท %s (ะฝะต ะฒะตัััั gobuild).
+test_git_failed=ะะต ะฒะดะฐะปะพัั ะฟะตัะตะฒััะธัะธ ะบะพะผะฐะฝะดั ยซgitยป: %v
+sqlite3_not_available=ะฆั ะฒะตัััั Forgejo ะฝะต ะฟัะดััะธะผัั SQLite3. ะัะดั ะปะฐัะบะฐ, ะทะฐะฒะฐะฝัะฐะถัะต ะพััััะนะฝั ะฑัะฝะฐัะฝั ะฒะตัััั ะท %s (ะฝะต ะฒะตัััั ยซgobuildยป).
invalid_db_setting=ะะฐะปะฐัััะฒะฐะฝะฝั ะฑะฐะทะธ ะดะฐะฝะธั
ั ะฝะตะบะพัะตะบัะฝะธะผะธ: %v
invalid_repo_path=ะะพะผะธะปะบะพะฒะธะน ัะปัั
ะดะพ ะบะพัะตะฝั ัะตะฟะพะทะธัะพััั: %v
invalid_app_data_path=ะะตะบะพัะตะบัะฝะธะน ัะปัั
ะดะพ ะดะฐะฝะธั
ะฟัะพะณัะฐะผะธ: %v
-run_user_not_match=ะะผ'ั ะบะพัะธัััะฒะฐัะฐ 'run as' ะฝะต ั ะฟะพัะพัะฝะธะผ ัะผ'ัะผ ะบะพัะธัััะฒะฐัะฐ: %s -> %s
+run_user_not_match=ะะผ'ั ะฒ ยซะะพัะธัััะฒะฐั, ะฒัะด ัะบะพะณะพ ะทะฐะฟัััะธัะธยป ะฝะต ั ัะผ'ัะผ ะฟะพัะพัะฝะพะณะพ ะบะพัะธัััะฒะฐัะฐ: %s -> %s
internal_token_failed=ะะต ะฒะดะฐะปะพัั ะทะณะตะฝะตััะฒะฐัะธ ะฒะฝัััััะฝัะน ัะพะบะตะฝ: %v
secret_key_failed=ะะต ะฒะดะฐะปะพัั ะทะณะตะฝะตััะฒะฐัะธ ัะตะบัะตัะฝะธะน ะบะปัั: %v
save_config_failed=ะะต ะฒ ะทะผะพะทั ะทะฑะตัะตะณัะธ ะบะพะฝััะณััะฐััั: %v
invalid_admin_setting=ะะตะฟัะธะฟัััะธะผั ะฝะฐะปะฐัััะฒะฐะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะฐะดะผัะฝััััะฐัะพัะฐ: %v
invalid_log_root_path=ะะตะฟัะธะฟัััะธะผะธะน ัะปัั
ะดะปั ะปะพะณัะฒ: %v
-default_keep_email_private=ะัะธั
ะพะฒะฐัะธ ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
-default_keep_email_private.description=ะัะธั
ะพะฒะฐัะธ ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะฝะพะฒะธั
ะพะฑะปัะบะพะฒะธั
ะทะฐะฟะธััะฒ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ.
+default_keep_email_private=ะัะธั
ะพะฒะฐัะธ ะฐะดัะตัะธ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
+default_keep_email_private.description=ะะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ะฟัะธั
ะพะฒะฐัะธ ะฐะดัะตัะธ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะฝะพะฒะธั
ะพะฑะปัะบะพะฒะธั
ะทะฐะฟะธััะฒ, ัะพะฑ ัั ัะฝัะพัะผะฐััั ะฝะต ยซะฒะธััะบะฐะปะฐยป ะพะดัะฐะทั ะฟััะปั ัะตััััะฐััั.
default_allow_create_organization=ะะพะทะฒะพะปะธัะธ ััะฒะพัะตะฝะฝั ะพัะณะฐะฝัะทะฐััะน ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
-default_allow_create_organization.description=ะะพะทะฒะพะปะธัะธ ะฝะพะฒะธะผ ะพะฑะปัะบะพะฒะธะผ ะทะฐะฟะธัะฐะผ ะบะพัะธัััะฒะฐััะฒ ััะฒะพััะฒะฐัะธ ะพัะณะฐะฝัะทะฐััั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ.
+default_allow_create_organization.description=ะะพะทะฒะพะปะธัะธ ะฝะพะฒะธะผ ะบะพัะธัััะฒะฐัะฐะผ ััะฒะพััะฒะฐัะธ ะพัะณะฐะฝัะทะฐััั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ. ะฏะบัะพ ัั ะพะฟััั ะฒะธะผะบะฝะตะฝะพ, ะดะพะทะฒัะป ะฝะฐ ััะฒะพัะตะฝะฝั ะพัะณะฐะฝัะทะฐััะน ะฝะพะฒะธะผ ะบะพัะธัััะฒะฐัะฐะผ ะฝะฐะดะฐั ะฐะดะผัะฝััััะฐัะพั.
default_enable_timetracking=ะฃะฒัะผะบะฝััะธ ะฒัะดััะตะถะตะฝะฝั ัะฐัั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
-default_enable_timetracking.description=ะะบะปััะธัะธ ะฒัะดััะตะถะตะฝะฝั ัะฐัั ะดะปั ะฝะพะฒะธั
ัะตะฟะพะทะธัะพัััะฒ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ.
+default_enable_timetracking.description=ะะพะทะฒะพะปะธัะธ ะฒะธะบะพัะธััะฐะฝะฝั ััะฝะบััั ะฒัะดััะตะถะตะฝะฝั ัะฐัั ะดะปั ะฝะพะฒะธั
ัะตะฟะพะทะธัะพัััะฒ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ.
no_reply_address=ะัะธั
ะพะฒะฐะฝะธะน ะฟะพััะพะฒะธะน ะดะพะผะตะฝ
-no_reply_address_helper=ะะพะผะตะฝะฝะต ัะผ'ั ะดะปั ะบะพัะธัััะฒะฐััะฒ ัะท ะฟัะธั
ะพะฒะฐะฝะพั ะตะปะตะบััะพะฝะฝะพั ะฐะดัะตัะพั. ะะฐะฟัะธะบะปะฐะด, ัะผ'ั ะบะพัะธัััะฒะฐัะฐ 'joe' ะฑัะดะต ะฒั
ะพะดะธัะธ ะฒ Git ัะบ 'joe@noreply.example.org', ัะบัะพ ะดะปั ะฟัะธั
ะพะฒะฐะฝะพะณะพ ะดะพะผะตะฝั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะฒััะฐะฝะพะฒะปะตะฝะพ 'noreply.example.org'.
+no_reply_address_helper=ะะพะผะตะฝะฝะต ัะผ'ั ะดะปั ะบะพัะธัััะฒะฐััะฒ ัะท ะฟัะธั
ะพะฒะฐะฝะพั ะตะปะตะบััะพะฝะฝะพั ะฐะดัะตัะพั. ะะฐะฟัะธะบะปะฐะด, ะบะพัะธัััะฒะฐั ยซjoeยป ะฑัะดะต ะฒั
ะพะดะธัะธ ะฒ Git ัะบ ยซjoe@noreply.example.orgยป, ัะบัะพ ะดะปั ะฟัะธั
ะพะฒะฐะฝะพะณะพ ะดะพะผะตะฝั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะฒััะฐะฝะพะฒะปะตะฝะพ ยซnoreply.example.orgยป.
password_algorithm=ะะปะณะพัะธัะผ ั
ะตััะฒะฐะฝะฝั ะฟะฐัะพะปั
+config_location_hint = ะฆั ะพะฟััั ะฝะฐะปะฐัััะฒะฐะฝั ะฑัะดััั ะทะฑะตัะตะถะตะฝั ะฒ:
+env_config_keys = ะะพะฝััะณััะฐััั ัะตัะตะดะพะฒะธัะฐ
+env_config_keys_prompt = ะฆั ะทะผัะฝะฝั ัะตัะตะดะพะฒะธัะฐ ะฑัะดััั ัะฐะบะพะถ ะทะฐััะพัะพะฒะฐะฝั ะดะพ ะฒะฐัะพะณะพ ัะฐะนะปั ะบะพะฝััะณััะฐััั:
+invalid_db_table = ะะฐะทะฐ ะดะฐะฝะธั
ยซ%sยป ะฝะตะดัะนัะฝะฐ: %v
+enable_update_checker = ะฃะฒัะผะบะฝััะธ ะฟะตัะตะฒััะบั ะพะฝะพะฒะปะตะฝั
+require_db_desc = Forgejo ะฒะธะผะฐะณะฐั MySQL, PostgreSQL, SQLite3 ัะธ TiDB (ะฟัะพัะพะบะพะป MySQL).
+allow_only_external_registration = ะะพะทะฒะพะปะธัะธ ัะตััััะฐััั ััะปัะบะธ ัะตัะตะท ะทะพะฒะฝััะฝั ัะตัะฒััะธ
+require_sign_in_view.description = ะะฑะผะตะถะธัะธ ะดะพัััะฟ ะดะพ ะบะพะฝัะตะฝัั ะปะธัะต ะบะพัะธัััะฒะฐัะฐะผ, ัะพ ัะฒัะนัะปะธ. ะะพััั ะทะผะพะถััั ะปะธัะต ะฒัะดะฒัะดัะฒะฐัะธ ััะพััะฝะบะธ ะฐะฒัะตะฝัะธััะบะฐััั.
+password_algorithm_helper = ะััะฐะฝะพะฒะธัะธ ะฐะปะณะพัะธัะผ ั
ะตััะฒะฐะฝะฝั ะฟะฐัะพะปัะฒ. ะะปะณะพัะธัะผะธ ะผะฐััั ััะทะฝั ะฒะธะผะพะณะธ ัะฐ ัะธะปั. ะะปะณะพัะธัะผ argon2 ั ะดะพัะธัั ะฑะตะทะฟะตัะฝะธะผ, ะฟัะพัะต ัะฟะพะถะธะฒะฐั ะฑะฐะณะฐัะพ ะฟะฐะผสผััั ัะฐ ั ะฝะตะดะพัะตัะฝะธะผ ะดะปั ะผะฐะปะธั
ัะธััะตะผ.
+app_slogan = ะะฐัะปะพ ะตะบะทะตะผะฟะปััะฐ
+app_slogan_helper = ะฃะฒะตะดััั ะณะฐัะปะพ ะฒะฐัะพะณะพ ะตะบะทะตะผะฟะปััะฐ ััั. ะะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ะฐะฑะธ ะฒะธะผะบะฝััะธ.
+run_user_helper = ะะผสผั ะบะพัะธัััะฒะฐัะฐ ะพะฟะตัะฐััะนะฝะพั ัะธััะตะผะธ, ะฒัะด ัะบะพะณะพ ะทะฐะฟััะตะฝะพ Forgejo. ะะฐัะฒะฐะถัะต, ัะพ ัะตะน ะบะพัะธัััะฒะฐั ะฟะพะฒะธะฝะตะฝ ะผะฐัะธ ะดะพัััะฟ ะดะพ ะบะพัะตะฝะตะฒะพั ัะตะบะธ ัะตะฟะพะทะธัะพััั.
+smtp_from_invalid = ะะดัะตัะฐ ะท ยซะัะดะฟัะฐะฒะปััะธ email ะฒัะด ัะผะตะฝัยป ะฝะตะดัะนัะฝะฐ
+allow_dots_in_usernames = ะะพะทะฒะพะปะธัะธ ะบะพัะธัััะฒะฐัะฐะผ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะบัะฐะฟะบะธ ั ัะฒะพัั
ัะผะตะฝะฐั
. ะะต ะฒะฟะปะธะฒะฐั ะฝะฐ ะพะฑะปัะบะพะฒั ะทะฐะฟะธัะธ, ัะพ ะฒะถะต ััะฝัััั.
+invalid_password_algorithm = ะะตะดัะนัะฝะธะน ะฒะฐััะฐะฝั ะฐะปะณะพัะธัะผั ั
ะตััะฒะฐะฝะฝั ะฟะฐัะพะปัะฒ
+enable_update_checker_helper_forgejo = ะะฐัะฒะฝัััั ะฝะพะฒะธั
ะฒะตัััะน Forgejo ะฟะตััะพะดะธัะฝะพ ะฟะตัะตะฒััััะธะผะตัััั ัะตัะตะท ะฟะตัะตะฒััะบั ะทะฐะฟะธัั TXT DNS ะฝะฐ release.forgejo.org.
[home]
-uname_holder=ะะผ'ั ะบะพัะธัััะฒะฐัะฐ ะฐะฑะพ ะะป. ะฟะพััะฐ
+uname_holder=ะะผ'ั ะบะพัะธัััะฒะฐัะฐ ะฐะฑะพ ะตะป. ะฟะพััะฐ
password_holder=ะะฐัะพะปั
switch_dashboard_context=ะะตัะตะบะปััะธัะธ ะบะพะฝัะตะบัั ะฟะฐะฝะตะปั ัะฟัะฐะฒะปัะฝะฝั
my_repos=ะ ะตะฟะพะทะธัะพััั
show_more_repos=ะะพะบะฐะทะฐัะธ ะฑัะปััะต ัะตะฟะพะทะธัะพัััะฒโฆ
collaborative_repos=ะกะฟัะปัะฝั ัะตะฟะพะทะธัะพััั
-my_orgs=ะะพั ะพัะณะฐะฝัะทะฐััั
+my_orgs=ะัะณะฐะฝัะทะฐััั
my_mirrors=ะะพั ะดะทะตัะบะฐะปะฐ
view_home=ะะตัะตะณะปัะฝััะธ %s
search_repos=ะจัะบะฐัะธ ัะตะฟะพะทะธัะพััะนโฆ
@@ -317,7 +393,12 @@ org_no_results=ะัะดะฟะพะฒัะดะฝะธั
ะพัะณะฐะฝัะทะฐััะน ะฝะต ะทะฝะฐะนะดะตะฝ
code_no_results=ะัะดะฟะพะฒัะดะฝะธะน ะฟะพััะบะพะฒะพะผั ะทะฐะฟะธัะฐะฝะฝั ะบะพะด ะฝะต ะทะฝะฐะนะดะตะฝะพ.
code_last_indexed_at=ะััะฐะฝะฝั ัะฝะดะตะบัะพะฒะฐะฝั %s
relevant_repositories = ะัะดะพะฑัะฐะถะฐััััั ะปะธัะต ัะตะปะตะฒะฐะฝัะฝั ัะตะฟะพะทะธัะพััั, ะฟะตัะตะณะปัะฝััะธ ัะตะทัะปััะฐัะธ ะฑะตะท ััะปัััั .
-relevant_repositories_tooltip = ะัะธั
ะพะฒะฐะฝะพ ัะพัะบะธ, ะฐ ัะฐะบะพะถ ัั
ะพะฒะธัะฐ ะฑะตะท ัะตะผะธ, ะทะฝะฐัะบะฐ ะน ะพะฟะธัั.
+relevant_repositories_tooltip = ะัะธั
ะพะฒะฐะฝะพ ัะพัะบะธ, ะฐ ัะฐะบะพะถ ัะตะฟะพะทะธัะพััั ะฑะตะท ัะตะผะธ, ะทะฝะฐัะบะฐ ะน ะพะฟะธัั.
+go_to = ะะตัะตะนัะธ ะดะพ
+stars_one = %d ะทััะบะฐ
+stars_few = %d ะทััะพะบ
+forks_one = %d ัะพัะบ
+forks_few = %d ัะพัะบัะฒ
[auth]
create_new_account=ะ ะตััััะฐััั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
@@ -325,22 +406,22 @@ register_helper_msg=ะะถะต ะทะฐัะตััััะพะฒะฐะฝั? ะฃะฒัะนะดััั ะทะฐัะฐ
social_register_helper_msg=ะะถะต ั ะฐะบะบะฐัะฝั? ะะฒ'ัะถััั ะนะพะณะพ ะทะฐัะฐะท!
disable_register_prompt=ะะธะฑะฐััะต, ะผะพะถะปะธะฒัััั ัะตััััะฐััั ะฒัะดะบะปััะตะฝะฐ. ะัะดั ะปะฐัะบะฐ, ะทะฒ'ัะถััััั ะท ะฐะดะผัะฝััััะฐัะพัะพะผ ัะฐะนัั.
disable_register_mail=ะัะดัะฒะตัะดะถะตะฝะฝั ัะตััััะฐััั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะพั ะฒะธะผะบะฝะตะฝะพ.
-remember_me=ะะฐะฟะฐะผโััะฐัะธ ัะตะน ะฟัะธััััะน
-forgot_password_title=ะะฐะฑัะฒ ะฟะฐัะพะปั
+remember_me=ะะฐะฟะฐะผ'ััะฐัะธ ัะตะน ะฟัะธััััะน
+forgot_password_title=ะะฐะฑัะปะธ ะฟะฐัะพะปั
forgot_password=ะะฐะฑัะปะธ ะฟะฐัะพะปั?
sign_up_now=ะะพัััะฑะตะฝ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั? ะะฐัะตัััััะนัะตัั ะทะฐัะฐะท.
-confirmation_mail_sent_prompt=ะะพะฒะธะน ะปะธัั ะดะปั ะฟัะดัะฒะตัะดะถะตะฝะฝั ะฑัะปะพ ะฒัะดะฟัะฐะฒะปะตะฝะพ ะฝะฐ %s , ะฑัะดั ะปะฐัะบะฐ, ะฟะตัะตะฒัััะต ะฒะฐัั ะฟะพััะพะฒั ัะบัะธะฝัะบั ะฟัะพััะณะพะผ %s ะดะปั ะทะฐะฒะตััะตะฝะฝั ัะตััััะฐััั.
+confirmation_mail_sent_prompt=ะะพะฒะธะน ะปะธัั ะฟัะดัะฒะตัะดะถะตะฝะฝั ะฑัะปะพ ะฝะฐะดััะปะฐะฝะพ %s . ะฉะพะฑ ะทะฐะฒะตััะธัะธ ัะตััััะฐััั, ะฟะตัะตะฒัััะต ะฒั
ัะดะฝั ะน ะฟะตัะตะนะดััั ะทะฐ ะฝะฐะฒะตะดะตะฝะธะผ ะฟะพัะธะปะฐะฝะฝัะผ (ะฝะฐ ัะต ะผะฐััะต %s). ะฏะบัะพ ะตะปะตะบััะพะฝะฝั ะฐะดัะตัั ะฒะบะฐะทะฐะฝะพ ะฝะตะฟัะฐะฒะธะปัะฝะพ, ะฒะธ ะผะพะถะตัะต ะฒะฒัะนัะธ ั ััะฒะพัะธัะธ ะทะฐะฟะธั ะดะปั ะฝะฐะดัะธะปะฐะฝะฝั ัะต ะพะดะฝะพะณะพ ะปะธััะฐ ะฟัะดัะฒะตัะดะถะตะฝะฝั ะฝะฐ ัะฝัั ะฐะดัะตัั.
must_change_password=ะะฝะพะฒััั ัะฒัะน ะฟะฐัะพะปั
allow_password_change=ะะธะผะฐะณะฐัะธ ะฒ ะบะพัะธัััะฒะฐัะฐ ะทะผัะฝะธัะธ ะฟะฐัะพะปั (ัะตะบะพะผะตะฝะดัััััั)
-reset_password_mail_sent_prompt=ะะปะตะบััะพะฝะฝะธะน ะปะธัั ัะท ะฟัะดัะฒะตัะดะถะตะฝะฝัะผ ะฝะฐะดััะปะฐะฝะพ %s . ะะตัะตะฒัััะต ะฟะฐะฟะบั 'ะั
ัะดะฝั' ะฒ ะผะตะถะฐั
ะฝะฐัััะฟะฝะธั
%s, ัะพะฑ ะทะฐะฒะตััะธัะธ ะฟัะพัะตั ะฒัะดะฝะพะฒะปะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั.
+reset_password_mail_sent_prompt=ะะธัั ะฟัะดัะฒะตัะดะถะตะฝะฝั ะฑัะปะพ ะฝะฐะดััะปะฐะฝะพ %s . ะฉะพะฑ ะทะฐะฒะตััะธัะธ ะฒัะดะฝะพะฒะปะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั, ะฟะตัะตะฒัััะต ะฒั
ัะดะฝั ะน ะฟะตัะตะนะดััั ะทะฐ ะฝะฐะฒะตะดะตะฝะธะผ ะฟะพัะธะปะฐะฝะฝัะผ (ะฝะฐ ัะต ะผะฐััะต %s).
active_your_account=ะะบัะธะฒัะฒะฐัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
account_activated=ะะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฐะบัะธะฒะพะฒะฐะฝะพ
-prohibit_login=ะั
ัะด ะทะฐะฑะพัะพะฝะตะฝะธะน
+prohibit_login=ะะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะทะฐะฑะปะพะบะพะฒะฐะฝะพ
resent_limit_prompt=ะะธะฑะฐััะต, ะฒะธ ะฒะถะต ะทะฐะฟัะพัะธะปะธ ะฐะบัะธะฒะฐััั ะฟะพ ะตะปะตะบััะพะฝะฝัะน ะฟะพััั ะฝะตัะพะดะฐะฒะฝะพ. ะัะดั ะปะฐัะบะฐ, ะทะฐัะตะบะฐะนัะต 3 ั
ะฒะธะปะธะฝะธ, ะฐ ะฟะพััะผ ัะฟัะพะฑัะนัะต ัะต ัะฐะท.
has_unconfirmed_mail=ะัะธะฒัั %s, ั ะฒะฐั ั ะฝะตะฟัะดัะฒะตัะดะถะตะฝะฐ ะตะปะตะบััะพะฝะฝะฐ ะฐะดัะตัะฐ (%s ). ะฏะบัะพ ะฒะธ ะฝะต ะพััะธะผะฐะปะธ ะตะปะตะบััะพะฝะฝะธะน ะปะธัั ัะท ะฟัะดัะฒะตัะดะถะตะฝะฝัะผ ะฐะฑะพ ะฒะฐะผ ะฟะพัััะฑะฝะพ ะฝะฐะดััะปะฐัะธ ะฝะพะฒะธะน, ะฝะฐัะธัะฝััั ะฝะฐ ะบะฝะพะฟะบั ะฝะธะถัะต.
resend_mail=ะะฐัะธัะฝััั ััั, ัะพะฑ ะฒะธัะปะฐัะธ ะปะธัั ะฐะบัะธะฒะฐััั ะทะฝะพะฒั
email_not_associate=ะฆั ะตะปะตะบััะพะฝะฝะฐ ะฟะพััะฐ ะฝะต ะฟะพะฒ'ัะทะฐะฝะฐ ะฝั ะท ะพะดะฝะธะผ ะพะฑะปัะบะพะฒะธะผ ะทะฐะฟะธัะพะผ.
-send_reset_mail=ะะฐะดััะปะฐัะธ ะตะปะตะบััะพะฝะฝะธะน ะปะธัั ะดะปั ะฒัะดะฝะพะฒะปะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
+send_reset_mail=ะะฐะดััะปะฐัะธ ะปะธััะฐ ะดะปั ะฒัะดะฝะพะฒะปะตะฝะฝั
reset_password=ะัะดะฝะพะฒะปะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
invalid_code=ะฆะตะน ะบะพะด ะฟัะดัะฒะตัะดะถะตะฝะฝั ะฝะตะดัะนัะฝะธะน ะฐะฑะพ ะทะฐะบัะฝัะธะฒัั.
reset_password_helper=ะัะดะฝะพะฒะธัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
@@ -355,10 +436,10 @@ twofa_scratch_token_incorrect=ะะตะฒััะฝะธะน ะพะดะฝะพัะฐะทะพะฒะธะน ะฟะฐัะพะป
login_userpass=ะฃะฒัะนัะธ
tab_openid=OpenID
oauth_signup_tab=ะะฐัะตัััััะฒะฐัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
-oauth_signup_title=ะะพะฒะฝะธะน ะฝะพะฒะธะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
-oauth_signup_submit=ะะพะฒะฝะธะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
+oauth_signup_title=ะะฐะฒะตััะธัะธ ัะตััััะฐััั
+oauth_signup_submit=ะะฐะฒะตััะธัะธ
oauth_signin_tab=ะะพัะธะปะฐะฝะฝั ะฝะฐ ััะฝัััะธะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
-oauth_signin_title=ะฃะฒัะนะดััั ัะพะฑ ะฐะฒัะพัะธะทัะฒะฐัะธ ะฟะพะฒ'ัะทะฐะฝะธะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
+oauth_signin_title=ะฃะฒัะนะดััั, ัะพะฑ ะฐะฒัะพัะธะทัะฒะฐัะธ ะฟะพะฒ'ัะทะฐะฝะธะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
oauth_signin_submit=ะัะธะฒ'ัะทะฐัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
openid_connect_submit=ะัะดโัะดะฝะฐัะธัั
openid_connect_title=ะัะดะบะปััะธัะธัั ะดะพ ััะฝัััะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
@@ -371,15 +452,38 @@ email_domain_blacklisted=ะ ะฒะบะฐะทะฐะฝะธะผ email ัะตััััะฐััั ะฝะตะผะพ
authorize_application=ะะฒัะพัะธะทัะฒะฐัะธ ะฟัะพะณัะฐะผั
authorize_redirect_notice=ะะฐั ะฑัะดะต ะฟะตัะตะฐะดัะตัะพะฒะฐะฝะพ ะดะพ %s, ัะบัะพ ะฒะธ ะฐะฒัะพัะธะทัััะต ัั ะฟัะพะณัะฐะผั.
authorize_application_created_by=ะฆั ะฟัะพะณัะฐะผะฐ ััะฒะพัะตะฝะฐ %s.
-authorize_application_description=ะฏะบัะพ ะฒะธ ะฝะฐะดะฐััะต ัะตะน ะดะพัััะฟ, ัะพ ะฒัะฝ ะผะฐัะธะผะต ะดะพัััะฟ ะดะพ ะฒััั
ะฒะฐัะธั
ะดะฐะฝะธั
ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั, ะฒะบะปััะฐััะธ ะฟัะธะฒะฐัะฝั ัะตะฟะพะทะธัะพััั ัะฐ ะพัะณะฐะฝัะทะฐััั.
-authorize_title=ะะฒัะพัะธะทัะนะฒะฐัะธ "%s" ะดะปั ะดะพัััะฟั ะดะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั?
+authorize_application_description=ะฏะบัะพ ะฒะธ ะฝะฐะดะฐััะต ะดะพะทะฒัะป, ัะพ ะฟัะพะณัะฐะผะฐ ะพััะธะผะฐั ะดะพัััะฟ ะดะพ ะฒััั
ะดะฐะฝะธั
ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั, ะฒะบะปััะฝะพ ะท ะฟัะธะฒะฐัะฝะธะผะธ ัะตะฟะพะทะธัะพัััะผะธ ัะฐ ะพัะณะฐะฝัะทะฐัััะผะธ.
+authorize_title=ะะพะทะฒะพะปะธัะธ ยซ%sยป ะดะพัััะฟ ะดะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั?
authorization_failed=ะะพะผะธะปะบะฐ ะฐะฒัะพัะธะทะฐััั
sspi_auth_failed=ะะพะผะธะปะบะฐ SSPI-ะฐะฒัะตะฝัะธััะบะฐััั
password_pwned_err=ะะต ะฒะดะฐะปะพัั ะฒะธะบะพะฝะฐัะธ ะทะฐะฟะธั ะดะพ HaveIBeenPwed
+change_unconfirmed_email_summary = ะะผัะฝะธัะธ ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ, ะฝะฐ ัะบั ะฝะฐะดั
ะพะดััั ะฐะบัะธะฒะฐััะนะฝั ะปะธััะธ.
+oauth.signin.error.temporarily_unavailable = ะะฒัะพัะธะทะฐััั ะฝะต ะฒะดะฐะปะฐัั, ะพัะบัะปัะบะธ ัะตัะฒะตั ะฐะฒัะตะฝัะธััะบะฐััั ัะธะผัะฐัะพะฒะพ ะฝะตะดะพัััะฟะฝะธะน. ะัะดั ะปะฐัะบะฐ, ัะฟัะพะฑัะนัะต ะฟัะทะฝััะต.
+change_unconfirmed_email = ะฏะบัะพ ะฟัะด ัะฐั ัะตััััะฐััั ะฒะธ ะฒะบะฐะทะฐะปะธ ะฝะตะฟัะฐะฒะธะปัะฝั ะตะปะตะบััะพะฝะฝั ะฐะดัะตัั, ะฒะธ ะผะพะถะตัะต ะทะผัะฝะธัะธ ัั ะฝะธะถัะต. ะัะดัะฒะตัะดะถะตะฝะฝั ะฑัะดะต ะฝะฐะดััะปะฐะฝะพ ะฝะฐ ะฝะพะฒั ะฐะดัะตัั.
+last_admin = ะะธ ะฝะต ะผะพะถะตัะต ะฒะธะดะฐะปะธัะธ ะพััะฐะฝะฝัะพะณะพ ะฐะดะผัะฝััััะฐัะพัะฐ. ะะฐั ะฑััะธ ั
ะพัะฐ ะฑ ะพะดะธะฝ ะฐะดะผัะฝััััะฐัะพั.
+oauth.signin.error.access_denied = ะะฐะฟะธั ะฝะฐ ะฐะฒัะพัะธะทะฐััั ะฑัะปะพ ะฒัะดั
ะธะปะตะฝะพ.
+change_unconfirmed_email_error = ะะต ะฒะดะฐะปะพัั ะทะผัะฝะธัะธ ะตะปะตะบััะพะฝะฝั ะฐะดัะตัั: %v
+manual_activation_only = ะะฒ'ัะถััััั ะท ะฐะดะผัะฝััััะฐัะพัะพะผ ัะฐะนัั, ะฐะฑะธ ะทะฐะฒะตััะธัะธ ะฐะบัะธะฒะฐััั.
+prohibit_login_desc = ะะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฑัะปะพ ะฒัะดัะทะฒะฐะฝะพ ะฒัะด ะฒะทะฐัะผะพะดัั ะท ะตะบะทะตะผะฟะปััะพะผ. ะะฒสผัะถััััั ะท ะฐะดะผัะฝััััะฐัะพัะพะผ ะตะบะทะตะผะฟะปััะฐ, ัะพะฑ ะพััะธะผะฐัะธ ะดะพัััะฟ ะทะฝะพะฒั.
+invalid_code_forgot_password = ะะฐั ะบะพะด ะฟัะดัะฒะตัะดะถะตะฝะฝั ะฝะตะดัะนัะฝะธะน. ะะฐัะธัะฝััั ััั , ะฐะฑะธ ะฟะพัะฐัะธ ะฝะพะฒั ัะตััั.
+reset_password_wrong_user = ะะธ ะฒะฒัะนัะปะธ ัะบ %s, ะฐะปะต ะฟะพัะธะปะฐะฝะฝั ะฝะฐ ะฒัะดะฝะพะฒะปะตะฝะฝั ะฑัะปะพ ะฟะตัะตะดะฑะฐัะตะฝะต ะดะปั %s
+back_to_sign_in = ะะฐะทะฐะด ะดะพ ะฒั
ะพะดั
+sign_in_openid = ะัะพะดะพะฒะถะธัะธ ะท OpenID
+openid_signin_desc = ะะฒะตะดััั ะฒะฐัะต ะฟะพัะธะปะฐะฝะฝั OpenID. ะะฐะฟัะธะบะปะฐะด: alice.openid.example.org ัะธ https://openid.example.org/alice.
+invalid_password = ะะฐั ะฟะฐัะพะปั ะฝะต ะฒัะดะฟะพะฒัะดะฐั ัะพะผั, ัะพ ะฑัะฒ ะทะฐะดะฐะฝะธะน ะฟัะธ ััะฒะพัะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั.
+hint_login = ะะถะต ะผะฐััะต ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั? ะฃะฒัะนะดััั ะทะฐัะฐะท!
+hint_register = ะะพัััะฑะตะฝ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั? ะะฐัะตัััััะนัะตัั ะทะฐัะฐะท.
+sign_up_button = ะะฐัะตัััััะฒะฐัะธัั.
+sign_up_successful = ะะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ััะฟััะฝะพ ััะฒะพัะตะฝะธะน. ะััะฐัะผะพ!
+unauthorized_credentials = ะฅะธะฑะฝั ะฐะฑะพ ะฟัะพัััะพัะตะฝั ะดะฐะฝั ะดะปั ะฒั
ะพะดั. ะกะฟัะพะฑัะนัะต ัะต ัะฐะท ะฐะฑะพ ะฟะตัะตะนะดััั ะดะพ %s ะฟะพ ะดะพะบะปะฐะดะฝััั ัะฝัะพัะผะฐััั
+use_onetime_code = ะะธะบะพัะธััะฐัะธ ะพะดะฝะพัะฐะทะพะฒะธะน ะบะพะด
+oauth.signin.error = ะะธะฝะธะบะปะฐ ะฟะพะผะธะปะบะฐ ะฟัะธ ะพะฑัะพะฑัั ะทะฐะฟะธัั ะฝะฐ ะฐะฒัะพัะธะทะฐััั. ะฏะบัะพ ัั ะฟะพะผะธะปะบะฐ ะฑัะดะต ะฟะพะฒัะพััะฒะฐัะธัั, ะทะฒะตัะฝััััั ะดะพ ะฐะดะผัะฝััััะฐัะพัะฐ ัะฐะนัั.
+authorization_failed_desc = ะะฒัะพัะธะทะฐััั ะฝะต ะฒัะดะฑัะปะฐัั: ะฒะธัะฒะปะตะฝะพ ะฝะตะดัะนัะฝะธะน ะทะฐะฟะธั. ะัะดั ะปะฐัะบะฐ, ะทะฒะตัะฝััััั ะดะพ ัะพะทัะพะฑะฝะธะบะฐ ะฟัะพะณัะฐะผะธ, ัะบั ะฒะธ ะฝะฐะผะฐะณะฐะปะธัั ะฐะฒัะพัะธะทัะฒะฐัะธ.
+password_pwned = ะะธะฑัะฐะฝะธะน ะฒะฐะผะธ ะฟะฐัะพะปั ั ั ัะฟะธัะบั ะฒะธะบัะฐะดะตะฝะธั
ะฟะฐัะพะปัะฒ , ะฒะธัะฒะปะตะฝะธั
ะฟัะด ัะฐั ะฒะธัะพะบัะฒ ะดะฐะฝะธั
. ะัะดั ะปะฐัะบะฐ, ัะฟัะพะฑัะนัะต ัะต ัะฐะท ะท ัะฝัะธะผ ะฟะฐัะพะปะตะผ. ะะฐััะพ ัะฐะบะพะถ ะทะผัะฝะธัะธ ัะตะน ะฟะฐัะพะปั ะฒ ัะฝัะธั
ะผััััั
.
[mail]
view_it_on=ะะตัะตะณะปัะฝััะธ ะฝะฐ %s
-link_not_working_do_paste=ะะต ะฟัะฐััั? ะกะฟัะพะฑัะนัะต ัะบะพะฟััะฒะฐัะธ ัะฐ ะฒััะฐะฒะธัะธ ะนะพะณะพ ะฒ ัะฒัะน ะฑัะฐัะทะตั.
+link_not_working_do_paste=ะะพัะธะปะฐะฝะฝั ะฝะต ะฟัะฐััั? ะกะฟัะพะฑัะนัะต ะนะพะณะพ ัะบะพะฟััะฒะฐัะธ ัะฐ ะฒััะฐะฒะธัะธ ั ัะฒัะน ะฑัะฐัะทะตั.
hi_user_x=ะัะธะฒัั %s ,
activate_account=ะัะดั ะปะฐัะบะฐ, ะฐะบัะธะฒัะนัะต ะฒะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
@@ -390,15 +494,15 @@ activate_account.text_2=ะะตัะตะนะดััั ะทะฐ ัะธะผ ะฟะพัะธะปะฐะฝะฝัะผ, ั
activate_email=ะัะดัะฒะตัะดะธัั ะฒะฐัั ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
activate_email.text=ะะตัะตะนะดััั ะทะฐ ัะธะผ ะฟะพัะธะปะฐะฝะฝัะผ, ัะพะฑ ะฟัะดัะฒะตัะดะธัะธ ะฒะฐัั ะตะปะตะบััะพะฝะฝั ะฐะดัะตัั ะฒ %s :
-register_notify=ะะฐัะบะฐะฒะพ ะฟัะพัะธะผะพ ั Forgejo
+register_notify=ะััะฐัะผะพ ั %s
register_notify.title=%[1]s, ะปะฐัะบะฐะฒะพ ะฟัะพัะธะผะพ ะดะพ %[2]s
register_notify.text_1=ัะต ะฒะฐัะฐ ะต-ะฟะพััะฐ ะดะปั ะฟัะดัะฒะตัะดะถะตะฝะฝั ัะตััััะฐััั ะดะปั %s!
-register_notify.text_2=ะขะตะฟะตั ะฒะธ ะผะพะถะตัะต ัะฒัะนัะธ ัะบ: %s.
-register_notify.text_3=ะฏะบัะพ ัะตะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฑัะปะพ ััะฒะพัะตะฝะพ ะดะปั ะฒะฐั, ะฑัะดั ะปะฐัะบะฐ, ัะฟะพัะฐัะบั ะฒััะฐะฝะพะฒััั ัะฒัะน ะฟะฐัะพะปั .
+register_notify.text_2=ะะธ ะผะพะถะตัะต ะฒะฒัะนัะธ ะดะพ ัะฒะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั, ะฒะธะบะพัะธััะพะฒัััะธ ัะผ'ั: %s
+register_notify.text_3=ะฏะบัะพ ัะตะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฑัะปะพ ััะฒะพัะตะฝะพ ะฝะต ะฒะฐะผะธ, ะฑัะดั ะปะฐัะบะฐ, ัะฟะพัะฐัะบั ะฒััะฐะฝะพะฒััั ัะฒัะน ะฟะฐัะพะปั .
reset_password=ะัะดะฝะพะฒะปะตะฝะฝั ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
reset_password.title=%s, ะฒะธ ะฒัะดะฟัะฐะฒะธะปะธ ะทะฐะฟะธั ะฝะฐ ะฒัะดะฝะพะฒะปะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
-reset_password.text=ะะตัะตะนะดััั ะทะฐ ัะธะผ ะฟะพัะธะปะฐะฝะฝัะผ, ัะพะฑ ะฒัะดะฝะพะฒะธัะธ ะฒะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฒ %s :
+reset_password.text=ะะตัะตะนะดััั ะทะฐ ัะธะผ ะฟะพัะธะปะฐะฝะฝัะผ, ัะพะฑ ะฒัะดะฝะพะฒะธัะธ ัะฒัะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฒ %s :
register_success=ะ ะตััััะฐััั ััะฟััะฝะฐ
@@ -428,13 +532,36 @@ release.downloads=ะะฒะฐะฝัะฐะถะตะฝะฝั:
release.download.zip=ะะธั
ัะดะฝะธะน ะบะพะด (ZIP)
release.download.targz=ะะธั
ัะดะฝะธะน ะบะพะด (TAR.GZ)
-repo.transfer.subject_to=%s ะฑะฐะถะฐั ะฟะตัะตะดะฐัะธ"%s" ะฒ %s
-repo.transfer.subject_to_you=%s ะฑะฐะถะฐั ะฟะตัะตะดะฐัะธ"%s" ะฒะฐะผ
+repo.transfer.subject_to=%s ะฑะฐะถะฐั ะฟะตัะตะดะฐัะธ ัะตะฟะพะทะธัะพััะน ยซ%sยป ะฒ %s
+repo.transfer.subject_to_you=%s ะฑะฐะถะฐั ะฟะตัะตะดะฐัะธ ะฒะฐะผ ัะตะฟะพะทะธัะพััะน ยซ%sยป
repo.transfer.to_you=ะฒะฐะผ
repo.transfer.body=ะฉะพะฑ ะฟัะธะนะฝััะธ ะฐะฑะพ ะฒัะดั
ะธะปะธัะธ ะฟะตัะตะนะดััั ะดะพ %s ะฐะฑะพ ะฟัะพััะพ ัะณะฝะพััะนัะต.
-repo.collaborator.added.subject=%s ะดะพะดะฐะฒ ะฒะฐั ะดะพ %s
-repo.collaborator.added.text=ะะธ ะฑัะปะธ ะดะพะดะฐะฝั ะฒ ัะบะพััั ัะฟัะฒะฐะฒัะพัะฐ ัะตะฟะพะทะธัะพััั:
+repo.collaborator.added.subject=%s ะดะพะดะฐะฒ ะฒะฐั ะดะพ %s ะฒ ัะบะพััั ัะฟัะฒะฐะฒัะพัะฐ
+repo.collaborator.added.text=ะะฐั ะดะพะดะฐะฝะพ ะฒ ัะบะพััั ัะฟัะฒะฐะฒัะพัะฐ ัะตะฟะพะทะธัะพััั:
+primary_mail_change.subject = ะะฐัะฐ ะพัะฝะพะฒะฝะฐ ะฟะพััะฐ ะฑัะปะฐ ะทะผัะฝะตะฝะฐ
+totp_disabled.subject = TOTP ะฑัะปะพ ะฒะธะผะบะฝะตะฝะพ
+totp_disabled.text_1 = ะขะธะผัะฐัะพะฒะธะน ะพะดะฝะพัะฐะทะพะฒะธะน ะฟะฐัะพะปั (TOTP) ะฝะฐ ะฒะฐัะพะผั ะพะฑะปัะบะพะฒะพะผั ะทะฐะฟะธัั ะฑัะปะพ ะฒะธะผะบะฝะตะฝะพ.
+password_change.subject = ะะฐั ะฟะฐัะพะปั ััะฟััะฝะพ ะทะผัะฝะตะฝะพ
+password_change.text_1 = ะะฐัะพะปั ะดะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะฑัะปะพ ัะพะนะฝะพ ะทะผัะฝะตะฝะพ.
+reply = ัะธ ะฒัะดะฟะพะฒัััะธ ะฝะฐะฟััะผั ะท ะตะปะตะบััะพะฝะฝะพั ะฐะดัะตัะธ
+admin.new_user.user_info = ะะฝัะพัะผะฐััั ะบะพัะธัััะฒะฐัะฐ
+admin.new_user.text = ะัะดั ะปะฐัะบะฐ, ะฝะฐัะธัะฝััั ััั , ัะพะฑ ะบะตััะฒะฐัะธ ัะธะผ ะบะพัะธัััะฒะฐัะตะผ ัะท ะฟะฐะฝะตะปั ะฐะดะผัะฝััััะฐััั.
+admin.new_user.subject = ะะพะฒะธะน ะบะพัะธัััะฒะฐั %s ัะพะนะฝะพ ะฒะฒัะนัะพะฒ
+removed_security_key.text_1 = ะะปัั ะฑะตะทะฟะตะบะธ ยซ%[1]sยป ะฑัะปะพ ัะพะนะฝะพ ะฒะธะดะฐะปะตะฝะพ ะท ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั.
+removed_security_key.subject = ะะปัั ะฑะตะทะฟะตะบะธ ะฒะธะดะฐะปะตะฝะพ
+team_invite.text_2 = ะฉะพะฑ ะฟัะธัะดะฝะฐัะธัั ะดะพ ะบะพะผะฐะฝะดะธ, ะฑัะดั ะปะฐัะบะฐ, ะฟะตัะตะนะดััั ะทะฐ ะฟะพัะธะปะฐะฝะฝัะผ:
+team_invite.subject = %[1]s ะทะฐะฟัะพััั ะะฐั ะฟัะธัะดะฝะฐัะธัั ะดะพ ะพัะณะฐะฝัะทะฐััั %[2]s
+team_invite.text_3 = ะัะธะผััะบะฐ: ะฆะต ะทะฐะฟัะพัะตะฝะฝั ะฟัะธะทะฝะฐัะตะฝะต ะดะปั %[1]s. ะฏะบัะพ ะะธ ะฝะต ะพััะบัะฒะฐะปะธ ััะพะณะพ ะทะฐะฟัะพัะตะฝะฝั, ะผะพะถะตัะต ะฟัะพัะณะฝะพััะฒะฐัะธ ัะตะน ะปะธัั.
+team_invite.text_1 = %[1]s ะทะฐะฟัะพััั ะะฐั ะฟัะธัะดะฝะฐัะธัั ะดะพ ะบะพะผะฐะฝะดะธ %[2]s ะฒ ะพัะณะฐะฝัะทะฐััั %[3]s.
+primary_mail_change.text_1 = ะัะฝะพะฒะฝั ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะฑัะปะพ ะทะผัะฝะตะฝะพ ะฝะฐ %[1]s. ะฆะต ะพะทะฝะฐัะฐั, ัะพ ัั ะฐะดัะตัะฐ ะฑัะปััะต ะฝะต ะพััะธะผัะฒะฐัะธะผะต ัะฟะพะฒััะตะฝะฝั ะดะปั ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั.
+account_security_caution.text_1 = ะฏะบัะพ ัะต ะฑัะปะธ ะฒะธ, ะผะพะถะตัะต ัะผัะปะธะฒะพ ะทะฝะตั
ััะฒะฐัะธ ัะธะผ ะปะธััะพะผ.
+account_security_caution.text_2 = ะฏะบัะพ ัะต ะฑัะปะธ ะฝะต ะฒะธ, ะฒะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะทะฝะฐั
ะพะดะธัััั ะฟัะด ะทะฐะณัะพะทะพั. ะัะดั ะปะฐัะบะฐ, ะทะฒสผัะถััััั ะท ะฐะดะผัะฝััััะฐัะพัะฐะผะธ ััะพะณะพ ัะฐะนัั.
+totp_enrolled.subject = ะะธ ะทะฐะดััะปะธ TOTP ัะบ ะทะฐััะฑ ะดะฒะพัะฐะบัะพัะฝะพั ะฐะฒัะตะฝัะธััะบะฐััั
+totp_enrolled.text_1.has_webauthn = ะะธ ัะพะนะฝะพ ะทะฐะดััะปะธ TOTP ะดะปั ัะฒะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั. ะัั ะฝะฐัััะฟะฝั ัะฟัะพะฑะธ ะฒั
ะพะดั ะฒะธะผะฐะณะฐัะธะผััั ะฒะธะบะพัะธััะฐะฝะฝั TOTP ัะบ ะทะฐัะพะฑั ะดะฒะพัะฐะบัะพัะฝะพั ะฐะฒัะตะฝัะธััะบะฐััั ะฐะฑะพ ะฑัะดั-ัะบะพะณะพ ะท ะฒะฐัะธั
ะบะปัััะฒ ะฑะตะทะฟะตะบะธ.
+totp_enrolled.text_1.no_webauthn = ะะธ ัะพะนะฝะพ ะทะฐะดััะปะธ TOTP ะดะปั ัะฒะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั. ะัั ะฝะฐัััะฟะฝั ัะฟัะพะฑะธ ะฒั
ะพะดั ะฒะธะผะฐะณะฐัะธะผััั ะฒะธะบะพัะธััะฐะฝะฝั TOTP ัะบ ะทะฐัะพะฑั ะดะฒะพัะฐะบัะพัะฝะพั ะฐะฒัะตะฝัะธััะบะฐััั.
+totp_disabled.no_2fa = ะะต ะฝะฐะปะฐััะพะฒะฐะฝะพ ะถะพะดะฝะพะณะพ ะทะฐัะพะฑั ะดะฒะพัะฐะบัะพัะฝะพั ะฐะฒัะตะฝัะธััะบะฐััั. ะฆะต ะพะทะฝะฐัะฐั, ัะพ ะฒะธ ะผะพะถะตัะต ะฒั
ะพะดะธัะธ ั ัะฒัะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฑะตะท ะฝะตะพะฑั
ัะดะฝะพััั ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะดะฒะพัะฐะบัะพัะฝั ะฐะฒัะตะฝัะธััะบะฐััั.
+removed_security_key.no_2fa = ะะต ะฝะฐะปะฐััะพะฒะฐะฝะพ ะถะพะดะฝะพะณะพ ะทะฐัะพะฑั ะดะฒะพัะฐะบัะพัะฝะพั ะฐะฒัะตะฝัะธััะบะฐััั. ะฆะต ะพะทะฝะฐัะฐั, ัะพ ะฒะธ ะผะพะถะตัะต ะฒั
ะพะดะธัะธ ั ัะฒัะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฑะตะท ะฝะตะพะฑั
ัะดะฝะพััั ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะดะฒะพัะฐะบัะพัะฝั ะฐะฒัะตะฝัะธััะบะฐััั.
[modal]
@@ -442,6 +569,7 @@ yes=ะขะฐะบ
no=ะั
cancel=ะัะดะผัะฝะธัะธ
modify=ะะฝะพะฒะปะตะฝะฝั
+confirm = ะัะดัะฒะตัะดะธัะธ
[form]
UserName=ะะผโั ะบะพัะธัััะฒะฐัะฐ
@@ -467,8 +595,8 @@ SSPISeparatorReplacement=ะ ะพะทะดัะปัะฒะฐั
SSPIDefaultLanguage=ะขะธะฟะพะฒะฐ ะผะพะฒะฐ
require_error=` ะฝะต ะผะพะถะต ะฑััะธ ะฟัััะธะผ.`
-alpha_dash_error=` ะฟะพะฒะธะฝะตะฝ ะผัััะธัะธ ััะปัะบะธ ะปััะตัะฝะพ-ัะธััะพะฒั ัะธะผะฒะพะปะธ, ะดะตััั ('-') ัะฐ ะฟัะดะบัะตัะปะตะฝะฝั ('_'). `
-alpha_dash_dot_error=` ะฟะพะฒะธะฝะตะฝ ะผัััะธัะธ ััะปัะบะธ ะปััะตัะฝะพ-ัะธััะพะฒั ัะธะผะฒะพะปะธ, ะดะตััั ('-') , ะฟัะดะบัะตัะปะตะฝะฝั ('_') ัะฐ ัะพัะบะธ ('.'). `
+alpha_dash_error=` ะฟะพะฒะธะฝะตะฝ ะผัััะธัะธ ััะปัะบะธ ะปััะตัะฝะพ-ัะธััะพะฒั ัะธะผะฒะพะปะธ, ะดะตััั (ยซ-ยป) ัะฐ ะฟัะดะบัะตัะปะตะฝะฝั (ยซ_ยป).`
+alpha_dash_dot_error=` ะฟะพะฒะธะฝะตะฝ ะผัััะธัะธ ััะปัะบะธ ะปััะตัะฝะพ-ัะธััะพะฒั ัะธะผะฒะพะปะธ, ะดะตััั (ยซ-ยป) , ะฟัะดะบัะตัะปะตะฝะฝั (ยซ_ยป) ัะฐ ะบัะฐะฟะบะธ (ยซ.ยป).`
git_ref_name_error=` ะฟะพะฒะธะฝะตะฝ ะฑััะธ ะฟัะฐะฒะธะปัะฝะธะผ ะฟะพัะธะปะฐะปัะฝะธะผ ัะผ'ัะผ Git.`
size_error=` ะฟะพะฒะธะฝะตะฝ ะฑััะธ ัะพะทะผัั %s.`
min_size_error=` ะฟะพะฒะธะฝะตะฝ ะฑััะธ ะฟัะธะฝะฐะนะผะฝั %s ัะธะผะฒะพะปัะฒ.`
@@ -507,7 +635,7 @@ enterred_invalid_owner_name=ะะผ'ั ะฝะพะฒะพะณะพ ะฒะปะฐัะฝะธะบะฐ ะฝะต ั ะดัะน
enterred_invalid_password=ะะฒะตะดะตะฝะธะน ะฒะฐะผะธ ะฟะฐัะพะปั ะฝะตะบะพัะตะบัะฝะธะน.
user_not_exist=ะะฐะฝะธะน ะบะพัะธัััะฒะฐั ะฝะต ััะฝัั.
team_not_exist=ะะพะผะฐะฝะดะฐ ะฝะต ััะฝัั.
-last_org_owner=ะะธ ะฝะต ะผะพะถะตัะต ะฒะธะดะฐะปะธัะธ ะพััะฐะฝะฝัะพะณะพ ะบะพัะธัััะฒะฐัะฐ ะท ะบะพะผะฐะฝะดะธ 'ะฒะปะฐัะฝะธะบะธ'. ะฃ ะบะพะถะฝัะน ะบะพะผะฐะฝะดั ะผะฐั ะฑััะธ ะฟัะธะฝะฐะนะผะฝั ะพะดะธะฝ ะฒะปะฐัะฝะธะบ.
+last_org_owner=ะะธ ะฝะต ะผะพะถะตัะต ะฒะธะดะฐะปะธัะธ ะพััะฐะฝะฝัะพะณะพ ะบะพัะธัััะฒะฐัะฐ ะท ะบะพะผะฐะฝะดะธ ยซะะปะฐัะฝะธะบะธยป. ะ ะพัะณะฐะฝัะทะฐััั ะผะฐั ะฑััะธ ะฟัะธะฝะฐะนะผะฝั ะพะดะธะฝ ะฒะปะฐัะฝะธะบ.
cannot_add_org_to_team=ะัะณะฐะฝัะทะฐััั ะฝะตะผะพะถะปะธะฒะพ ะดะพะดะฐัะธ ัะบ ััะฐัะฝะธะบะฐ ะบะพะผะฐะฝะดะธ.
invalid_ssh_key=ะะตะผะพะถะปะธะฒะพ ะฟะตัะตะฒััะธัะธ ะฒะฐั SSH ะบะปัั: %s
@@ -517,18 +645,48 @@ auth_failed=ะะพะผะธะปะบะฐ ะฐะฒัะตะฝัะธััะบะฐััั: %v
target_branch_not_exist=ะฆัะปัะพะฒะพั ะณัะปะบะธ ะฝะต ััะฝัั.
+still_own_packages = ะะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฒะพะปะพะดัั ะพะดะฝะธะผ ัะธ ะฑัะปััะต ะฟะฐะบัะฝะบะฐะผะธ, ัะฟะพัะฐัะบั ะฒะธะดะฐะปััั ัั
.
+org_still_own_packages = ะัะณะฐะฝัะทะฐััั ะฒัะต ัะต ะฒะพะปะพะดัั ะพะดะฝะธะผ ัะธ ะฑัะปััะต ะฟะฐะบัะฝะบะฐะผะธ, ัะฟะพัะฐัะบั ะฒะธะดะฐะปััั ัั
.
+username_error_no_dots = ` ะผะพะถะต ะผัััะธัะธ ััะปัะบะธ ะปััะตัะฝะพ-ัะธััะพะฒั ัะธะผะฒะพะปะธ (ยซ0-9ยป, ยซa-zยป, ยซA-Zยป), ะดะตััั (ยซ-ยป) ัะฐ ะฟัะดะบัะตัะปะตะฝะฝั (ยซ_ยป). ะะต ะผะพะถะต ะฟะพัะธะฝะฐัะธัั ะฐะฑะพ ะทะฐะบัะฝััะฒะฐัะธัั ะฝะตะปััะตัะฝะธะผะธ ัะธะผะฒะพะปะฐะผะธ; ะฝะตะปััะตัะฝั ัะธะผะฒะพะปะธ ะฟัะดััะด ัะฐะบะพะถ ะทะฐะฑะพัะพะฝะตะฝั.`
+username_error = ` ะผะพะถะต ะผัััะธัะธ ััะปัะบะธ ะปััะตัะฝะพ-ัะธััะพะฒั ัะธะผะฒะพะปะธ (ยซ0-9ยป, ยซa-zยป, ยซA-Zยป), ะดะตััั (ยซ-ยป), ะฟัะดะบัะตัะปะตะฝะฝั (ยซ_ยป) ัะฐ ะบัะฐะฟะบะธ (ยซ.ยป). ะะต ะผะพะถะต ะฟะพัะธะฝะฐัะธัั ะฐะฑะพ ะทะฐะบัะฝััะฒะฐัะธัั ะฝะตะปััะตัะฝะธะผะธ ัะธะผะฒะพะปะฐะผะธ; ะฝะตะปััะตัะฝั ัะธะผะฒะพะปะธ ะฟัะดััะด ัะฐะบะพะถ ะทะฐะฑะพัะพะฝะตะฝั.`
+Description = ะะฟะธั
+Pronouns = ะะฐะนะผะตะฝะฝะธะบะธ
+Biography = ะัะพ ัะตะฑะต
+FullName = ะะพะฒะฝะต ัะผ'ั
+Website = ะะตะฑัะฐะนั
+url_error = `ยซ%sยป ั ะฝะตะดัะนัะฝะธะผ ะฟะพัะธะปะฐะฝะฝัะผ.`
+To = ะะฐะทะฒะฐ ะณัะปะบะธ
+Location = ะ ะพะทัะฐััะฒะฐะฝะฝั
+AccessToken = ะขะพะบะตะฝ ะดะพัััะฟั
+unable_verify_ssh_key = ะะต ะฒะดะฐะปะพัั ะฟะตัะตะฒััะธัะธ ะบะปัั SSH, ะฟะตัะตะฒัััะต ะนะพะณะพ ะฝะฐ ะฝะฐัะฒะฝัััั ะฟะพะผะธะปะพะบ.
+repository_force_private = ะฃะฒัะผะบะฝะตะฝะพ ะฟัะธะผััะพะฒั ะฟัะธะฒะฐัะฝัััั: ะฟัะธะฒะฐัะฝั ัะตะฟะพะทะธัะพััั ะฝะต ะผะพะถะฝะฐ ะทัะพะฑะธัะธ ะฟัะฑะปััะฝะธะผะธ.
+must_use_public_key = ะะปัั, ัะบะธะน ะฒะธ ะฝะฐะดะฐะปะธ, ั ะฟัะธะฒะฐัะฝะธะผ. ะัะดั ะปะฐัะบะฐ, ะฝัะบัะดะธ ะฝะต ะทะฐะฒะฐะฝัะฐะถัะนัะต ัะฒัะน ะฟัะธะฒะฐัะฝะธะน ะบะปัั. ะะธะบะพัะธััะพะฒัะนัะต ะทะฐะผัััั ะฝัะพะณะพ ะฟัะฑะปััะฝะธะน ะบะปัั.
+openid_been_used = ะะดัะตัะฐ OpenID ยซ%sยป ะฒะถะต ะฒะธะบะพัะธััะพะฒัััััั.
+still_has_org = ะะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ั ััะฐัะฝะธะบะพะผ ะพะดะฝััั ะฐะฑะพ ะดะตะบัะปัะบะพั
ะพัะณะฐะฝัะทะฐััะน, ัะฟะพัะฐัะบั ะฟะพะบะธะฝััะต ัั
.
+duplicate_invite_to_team = ะฆัะพะณะพ ะบะพัะธัััะฒะฐัะฐ ะฒะถะต ะทะฐะฟัะพัะตะฝะพ ัะบ ััะฐัะฝะธะบะฐ ะบะพะผะฐะฝะดะธ.
+organization_leave_success = ะะธ ััะฟััะฝะพ ะฟะพะบะธะฝัะปะธ ะพัะณะฐะฝัะทะฐััั %s.
+include_error = ` ะผะฐั ะผัััะธัะธ ะฟัะดััะดะพะบ ยซ%sยป.`
+invalid_group_team_map_error = ` ะฟัะธะทะฝะฐัะตะฝะฝั ะฝะตะดัะนัะฝะต: %s`
+unsupported_login_type = ะฆะตะน ัะธะฟ ะฒั
ะพะดั ะฝะต ะฟัะดััะธะผัั ะฒะธะดะฐะปะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั.
+admin_cannot_delete_self = ะะธ ะฝะต ะผะพะถะตัะต ะฒะธะดะฐะปะธัะธ ัะตะฑะต, ัะบัะพ ะฒะธ ั ะฐะดะผัะฝััััะฐัะพัะพะผ. ะกะฟะพัะฐัะบั ะทะฝัะผััั ัะท ัะตะฑะต ะฟัะฐะฒะฐ ะฐะดะผัะฝััััะฐัะพัะฐ.
+unset_password = ะะปั ะบะพัะธัััะฒะฐัะฐ ะฝะต ะฒััะฐะฝะพะฒะปะตะฝะพ ะฟะฐัะพะปั.
+username_claiming_cooldown = ะฆะต ัะผ'ั ะบะพัะธัััะฒะฐัะฐ ะฝะต ะผะพะถะฝะฐ ะฟัะธัะฒะพััะธ, ะพัะบัะปัะบะธ ะนะพะณะพ ะฟะตััะพะด ะทะฐั
ะธััั ัะต ะฝะต ะทะฐะบัะฝัะธะฒัั. ะะผ'ั ะผะพะถะฝะฐ ะฑัะดะต ะฟัะธัะฒะพััะธ %[1]s.
+email_domain_is_not_allowed = ะะพะผะตะฝ ะฐะดัะตัะธ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ %s ะบะพะฝัะปัะบััั ะท EMAIL_DOMAIN_ALLOWLIST ะฐะฑะพ EMAIL_DOMAIN_BLOCKLIST. ะะตัะตะฒัััะต, ัะธ ะฒะธ ะฟัะฐะฒะธะปัะฝะพ ะฒะบะฐะทะฐะปะธ ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ.
+still_own_repo = ะะฐัะพะผั ะพะฑะปัะบะพะฒะพะผั ะทะฐะฟะธัั ะฝะฐะปะตะถะฐัั ะพะดะธะฝ ัะธ ะฑัะปััะต ัะตะฟะพะทะธัะพัััะฒ. ะกะฟะตััั ะฒะธะดะฐะปััั ะฐะฑะพ ะฟะตัะตะดะฐะนัะต ัั
.
+org_still_own_repo = ะฆัะน ะพัะณะฐะฝัะทะฐััั ะดะพัั ะฝะฐะปะตะถะฐัั ะพะดะธะฝ ัะธ ะฑัะปััะต ัะตะฟะพะทะธัะพัััะฒ. ะกะฟะตััั ะฒะธะดะฐะปััั ะฐะฑะพ ะฟะตัะตะดะฐะนัะต ัั
.
+required_prefix = ะะพัััะฑะฝะพ ะฟะพัะฐัะธ ะท ยซ%sยป
[user]
change_avatar=ะะผัะฝะธัะธ ัะฒัะน ะฐะฒะฐัะฐัโฆ
repositories=ะ ะตะฟะพะทะธัะพััั
activity=ะัะฑะปััะฝะฐ ะฐะบัะธะฒะฝัััั
-followers_few=%d ัะธัะฐัั
-starred=ะะฑัะฐะฝั ะ ะตะฟะพะทะธัะพััั
+followers_few=%d cัะตะถะฐัั
+starred=ะะฑัะฐะฝั ัะตะฟะพะทะธัะพััั
watched=ะัะดััะตะถัะฒะฐะฝั ัะตะฟะพะทะธัะพััั
projects=ะัะพัะบั
overview=ะะณะปัะด
-following_few=%d ัะธัะฐั
+following_few=%d ะฒัะดััะตะถัะฒะฐะฝะธั
follow=ะัะดะฟะธัะฐัะธัั
unfollow=ะัะดะฟะธัะฐัะธัั
user_bio=ะัะพะณัะฐััั
@@ -537,6 +695,30 @@ joined_on = ะ ะตััััะฐััั %s
email_visibility.private = ะะฐั email ะฒะธะดะฝะพ ะปะธัะต ะฒะฐะผ ั ะฐะดะผัะฝััััะฐัะพัะฐะผ
email_visibility.limited = ะะฐัั ะต-ะฟะพััั ะฒะธะดะฝะพ ะฒััะผ ะฐะฒัะพัะธะทะพะฒะฐะฝะธะผ
settings = ะะพัะธัััะฒะฐััะบั ะฟะฐัะฐะผะตััะธ
+block_user.detail_3 = ะะธ ะฝะต ะทะผะพะถะตัะต ะดะพะดะฐัะธ ะพะดะธะฝ ะพะดะฝะพะณะพ ะฒ ัะบะพััั ัะฟัะฒะฐะฒัะพัะฐ ัะตะฟะพะทะธัะพััั.
+show_on_map = ะะพะบะฐะทะฐัะธ ัะต ะผัััะต ะฝะฐ ะผะฐะฟั
+block_user.detail_2 = ะฆะตะน ะบะพัะธัััะฒะฐั ะฝะต ะทะผะพะถะต ะฒะทะฐัะผะพะดัััะธ ะท ัะตะฟะพะทะธัะพัััะผะธ, ะฒะปะฐัะฝะธะบะพะผ ัะบะธั
ั ะฒะธ, ะฐ ัะฐะบะพะถ ัะท ะทะฐะดะฐัะฐะผะธ ัะฐ ะบะพะผะตะฝัะฐััะผะธ, ัะบั ะฒะธ ััะฒะพัะธะปะธ.
+block_user.detail_1 = ะะธ ะฟัะธะฟะธะฝะธัะต ััะตะถะธัะธ ะพะดะธะฝ ะทะฐ ะพะดะฝะธะผ ั ะฝะต ะทะผะพะถะตัะต ะฟัะดะฟะธัะฐัะธัั ะพะดะธะฝ ะฝะฐ ะพะดะฝะพะณะพ.
+block = ะะฐะฑะปะพะบัะฒะฐัะธ
+unblock = ะ ะพะทะฑะปะพะบัะฒะฐัะธ
+code = ะะพะด
+block_user = ะะฐะฑะปะพะบัะฒะฐัะธ ะบะพัะธัััะฒะฐัะฐ
+block_user.detail = ะะฒะตัะฝััั ัะฒะฐะณั, ัะพ ะฑะปะพะบัะฒะฐะฝะฝั ะบะพัะธัััะฒะฐัะฐ ะผะฐั ัะฐะบั ะฝะฐัะปัะดะบะธ:
+follow_blocked_user = ะะธ ะฝะต ะผะพะถะตัะต ััะตะถะธัะธ ะทะฐ ัะธะผ ะบะพัะธัััะฒะฐัะตะผ, ัะพะผั ัะพ ะฒะธ ะนะพะณะพ ะทะฐะฑะปะพะบัะฒะฐะปะธ ะฐะฑะพ ะฒัะฝ ะทะฐะฑะปะพะบัะฒะฐะฒ ะฒะฐั.
+following_one = %d ะฒัะดััะตะถัะฒะฐะฝะธะน
+followers_one = %d cัะตะถะธัั
+followers.title.one = Cัะตะถะธัั
+followers.title.few = Cัะตะถะฐัั
+following.title.one = ะัะดััะตะถัะฒะฐะฝะธะน
+following.title.few = ะัะดััะตะถัะฒะฐะฝั
+form.name_reserved = ะะผ'ั ะบะพัะธัััะฒะฐัะฐ ยซ%sยป ะทะฐัะตะทะตัะฒะพะฒะฐะฝะพ.
+form.name_chars_not_allowed = ะะผ'ั ะบะพัะธัััะฒะฐัะฐ ยซ%sยป ะผัััะธัั ะฝะตะฟัะธะฟัััะธะผั ัะธะผะฒะพะปะธ.
+public_activity.visibility_hint.self_private = ะะฐัั ะดััะปัะฝัััั ะฑะฐัะธัะธะผะตัะต ะปะธัะต ะฒะธ ะน ะฐะดะผัะฝััััะฐััั ัะตัะฒะตัะฐ. ะะฐะปะฐัััะฒะฐัะธ .
+public_activity.visibility_hint.admin_private = ะฆั ะดัั ะฒะธะดะฝะพ ะฐะดะผัะฝััััะฐััั, ะทะพะบัะตะผะฐ ะฒะฐะผ, ะฐะปะต ะบะพัะธัััะฒะฐั_ะบะฐ ะฑะฐะถะฐั ะทะฐะปะธัะธัะธ ัั ะฟัะธะฒะฐัะฝะพั.
+public_activity.visibility_hint.self_private_profile = ะะฐัั ะดััะปัะฝัััั ะฒะธะดะฝะพ ะปะธัะต ะฒะฐะผ ั ะฐะดะผัะฝััััะฐััั ัะตัะฒะตัะฐ, ะพัะบัะปัะบะธ ะฒะฐั ะฟัะพััะปั ะฟัะธะฒะฐัะฝะธะน. ะะฐะปะฐัััะฒะฐัะธ .
+public_activity.visibility_hint.self_public = ะะฐัั ะดััะปัะฝัััั ะฑะฐัะธัะธะผััั ััั, ะทะฐ ะฒะธะฝััะบะพะผ ะฒะทะฐัะผะพะดัะน ั ะฟัะธะฒะฐัะฝะธั
ะฟัะพััะพัะฐั
. ะะฐะปะฐัััะฒะฐัะธ .
+form.name_pattern_not_allowed = ะะธัะฐะท ยซ%sยป ะฝะต ะผะพะถะต ะฑััะธ ัะฐััะธะฝะพั ะบะพัะธัััะฒะฐััะบะพะณะพ ัะผะตะฝั.
+public_activity.visibility_hint.admin_public = ะฆั ะดัั ะฒะธะดะฝะพ ะฒััะผ, ะฐะปะต ะฐะดะผัะฝััััะฐััั (ะทะพะบัะตะผะฐ ะน ะฒะธ) ะผะพะถะต ะฑะฐัะธัะธ ัะต ะน ะฒะทะฐัะผะพะดัั ะฒ ะฟัะธะฒะฐัะฝะธั
ะฟัะพััะพัะฐั
.
[settings]
@@ -546,13 +728,13 @@ appearance=ะะพะฒะฝััะฝัะน ะฒะธะณะปัะด
password=ะะฐัะพะปั
security=ะะตะทะฟะตะบะฐ
avatar=ะะฒะฐัะฐั
-ssh_gpg_keys=SSH / GPG ะบะปััั
+ssh_gpg_keys=ะะปััั SSH / GPG
social=ะกะพััะฐะปัะฝั ะพะฑะปัะบะพะฒั ะทะฐะฟะธัะธ
applications=ะะพะดะฐัะบะธ
-orgs=ะะตััะฒะฐะฝะฝั ะพัะณะฐะฝัะทะฐัััะผะธ
+orgs=ะัะณะฐะฝัะทะฐััั
repos=ะ ะตะฟะพะทะธัะพััั
delete=ะะธะดะฐะปะธัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
-twofa=ะะฒะพัะฐะบัะพัะฝะฐ ะฐะฒัะพัะธะทะฐััั
+twofa=ะะฒะพัะฐะบัะพัะฝะฐ ะฐะฒัะพัะธะทะฐััั (TOTP)
account_link=ะัะธะฒ'ัะทะฐะฝั ะพะฑะปัะบะพะฒั ะทะฐะฟะธัะธ
organization=ะัะณะฐะฝัะทะฐััั
@@ -561,9 +743,9 @@ password_username_disabled=ะะตะปะพะบะฐะปัะฝะธะผ ะบะพัะธัััะฒะฐัะฐะผ ะทะฐ
full_name=ะะพะฒะฝะต ัะผ'ั
website=ะะตะฑ-ัะฐะนั
location=ะัััะตะทะฝะฐั
ะพะดะถะตะฝะฝั
-update_theme=ะะฝะพะฒะธัะธ ัะตะผั
+update_theme=ะะผัะฝะธัะธ ัะตะผั
update_profile=ะะฝะพะฒะธัะธ ะฟัะพััะปั
-update_language=ะะฝะพะฒะธัะธ ะผะพะฒั
+update_language=ะะผัะฝะธัะธ ะผะพะฒั
update_language_success=ะะพะฒั ะพะฝะพะฒะปะตะฝะพ.
update_profile_success=ะัะพััะปั ััะฟััะฝะพ ะพะฝะพะฒะปะตะฝะพ.
change_username=ะะฐัะต ะะผ'ั ะบัะธัััะฒะฐัะฐ ะฑัะปะพ ะทะผัะฝะตะฝะพ.
@@ -580,7 +762,7 @@ comment_type_group_project=ะัะพัะบั
privacy=ะัะธะฒะฐัะฝัััั
keep_activity_private_popup=ะะพะบะฐะทัะฒะฐัะธ ะฒะฐัั ะฐะบัะธะฒะฝัััั ะปะธัะต ะะฐะผ ัะฐ ะฐะดะผัะฝััััะฐัะพัะฐะผ
-lookup_avatar_by_mail=ะะฝะฐะนัะธ ะะฒะฐัะฐั ะทะฐ ะฐะดัะตัะพั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
+lookup_avatar_by_mail=ะะฝะฐะนัะธ ะฐะฒะฐัะฐั ะทะฐ ะฐะดัะตัะพั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
federated_avatar_lookup=ะะฝะฐะนัะธ ะทะพะฒะฝััะฝัะน ะฐะฒะฐัะฐั
enable_custom_avatar=ะฃะฒัะผะบะฝััะธ ะบะพัะธัััะฒะฐััะบั ะฐะฒะฐัะฐัะธ
choose_new_avatar=ะะฑะตัััั ะฝะพะฒะธะน ะฐะฒะฐัะฐั
@@ -594,14 +776,14 @@ update_password=ะะฝะพะฒะธัะธ ะฟะฐัะพะปั
old_password=ะะพัะพัะฝะธะน ะฟะฐัะพะปั
new_password=ะะพะฒะธะน ะฟะฐัะพะปั
password_incorrect=ะะพัะพัะฝะธะน ะฟะฐัะพะปั ะฝะตะฟัะฐะฒะธะปัะฝะธะน.
-change_password_success=ะะฐั ะฟะฐัะพะปั ะฑัะฒ ะพะฝะพะฒะปะตะฝะธะน. ะขะตะฟะตั ัะฒัะนะดััั ะฒ ัะธััะตะผั, ะฒะธะบะพัะธััะพะฒัััะธ ะฝะพะฒะธะน ะฟะฐัะพะปั.
+change_password_success=ะะฐั ะฟะฐัะพะปั ะพะฝะพะฒะปะตะฝะพ. ะัะดัะตะฟะตั ะฒั
ะพะดััะต ะฒ ัะธััะตะผั, ะฒะธะบะพัะธััะพะฒัััะธ ะฝะพะฒะธะน ะฟะฐัะพะปั.
password_change_disabled=ะะตะปะพะบะฐะปัะฝั ะฐะบะฐัะฝัะธ ะฝะต ะผะพะถััั ะทะผัะฝะธัะธ ะฟะฐัะพะปั ัะตัะตะท Forgejo.
emails=ะะดัะตัะฐ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
manage_emails=ะะตััะฒะฐะฝะฝั ะฐะดัะตัะฐะผะธ ะตะป. ะฟะพััะธ
-manage_themes=ะะธะฑะตัััั ัะตะผั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
-manage_openid=ะะตััะฒะฐะฝะฝั OpenID
-theme_desc=ะฆั ัะตะผะฐ ะฑัะดะต ัะธะฟะพะฒะพั ะดะปั ะฒััะพะณะพ ัะฐะนัั.
+manage_themes=ะขะตะผะฐ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
+manage_openid=ะะดัะตัะธ OpenID
+theme_desc=ะฆั ัะตะผะฐ ะฑัะดะต ัะธะฟะพะฒะพั ะดะปั ะฒะตะฑ-ัะฝัะตััะตะนัั, ะบะพะปะธ ะฒะธ ะฒะฒัะนะดะตัะต ะฒ ัะธััะตะผั.
primary=ะัะฝะพะฒะฝะธะน
activated=ะะบัะธะฒะพะฒะฐะฝะพ
requires_activation=ะะพัััะฑะฝะฐ ะฐะบัะธะฒะฐััั
@@ -617,8 +799,8 @@ theme_update_error=ะะธะฑัะฐะฝะฐ ัะตะผะฐ ะฝะต ััะฝัั.
openid_deletion=ะะธะดะฐะปะธัะธ ะฐะดัะตัั OpenID
openid_deletion_desc=ะะธะดะฐะปะตะฝะฝั ัััั OpenID-ะฐะดัะตัะธ ะท ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะทะฐะฑะพัะพะฝัั ะฒะฐะผ ะฒั
ะพะดะธัะธ ะท ะฝะธะผ. ะัะพะดะพะฒะถะธัะธ?
openid_deletion_success=ะะดัะตัะฐ OpenID ะฑัะปะฐ ะฒะธะดะฐะปะตะฝะฐ.
-add_new_email=ะะพะดะฐัะธ ะฝะพะฒั ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
-add_new_openid=ะะพะดะฐัะธ ะฝะพะฒะธะน OpenID URI
+add_new_email=ะะพะดะฐัะธ ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
+add_new_openid=ะะพะดะฐัะธ ะฝะพะฒะธะน URI OpenID
add_email=ะะพะดะฐัะธ ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
add_openid=ะะพะดะฐัะธ OpenID URI
add_email_success=ะะพะดะฐะฝะพ ะฝะพะฒั ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ.
@@ -627,20 +809,20 @@ add_openid_success=ะะพะฒะฐ ะฐะดัะตัะฐ OpenID ะฑัะปะฐ ะดะพะดะฐะฝะฐ.
keep_email_private=ะัะธั
ะพะฒะฐัะธ ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
openid_desc=OpenID ะดะพะทะฒะพะปัั ะดะตะปะตะณัะฒะฐัะธ ะฐััะตะฝัะธััะบะฐััั ะทะพะฒะฝััะฝัะพะผั ะฟะพััะฐัะฐะปัะฝะธะบั ะฟะพัะปัะณ.
-manage_ssh_keys=ะะตััะฒะฐัะธ SSH ะบะปััะฐะผะธ
+manage_ssh_keys=ะะตััะฒะฐะฝะฝั ะบะปััะฐะผะธ SSH
manage_ssh_principals=ะฃะฟัะฐะฒะปัะฝะฝั SSH ัะตััะธััะบะฐัะฐะผะธ ะบะพัะธัััะฒะฐััะฒ
-manage_gpg_keys=ะะตััะฒะฐัะธ GPG ะบะปััะฐะผะธ
+manage_gpg_keys=ะะตััะฒะฐะฝะฝั ะบะปััะฐะผะธ GPG
add_key=ะะพะดะฐัะธ ะบะปัั
-ssh_desc=ะฆั ะฒัะดะบัะธัั SSH-ะบะปััั ะฟะพะฒ'ัะทะฐะฝั ะท ะฒะฐัะธะผ ะพะฑะปัะบะพะฒะธะผ ะทะฐะฟะธัะพะผ. ะัะดะฟะพะฒัะดะฝั ะฟัะธะฒะฐัะฝั ะบะปััั ะดะพะทะฒะพะปัััั ะพััะธะผะฐัะธ ะฟะพะฒะฝะธะน ะดะพัััะฟ ะดะพ ะฒะฐัะธั
ัะตะฟะพะทะธัะพัััะฒ.
+ssh_desc=ะฆั ะฒัะดะบัะธัั ะบะปััั SSH ะฟะพะฒสผัะทะฐะฝั ะท ะฒะฐัะธะผ ะพะฑะปัะบะพะฒะธะผ ะทะฐะฟะธัะพะผ. ะัะดะฟะพะฒัะดะฝั ะฟัะธะฒะฐัะฝั ะบะปััั ะดะพะทะฒะพะปัััั ะพััะธะผะฐัะธ ะฟะพะฒะฝะธะน ะดะพัััะฟ ะดะพ ะฒะฐัะธั
ัะตะฟะพะทะธัะพัััะฒ. ะัะดัะฒะตัะดะถะตะฝั ะบะปััั ะผะพะถะฝะฐ ะฒะธะบะพัะธััะฐัะธ ะดะปั ะฟัะดัะฒะตัะดะถะตะฝะฝั ะบะพะผัััะฒ Git, ะฟัะดะฟะธัะฐะฝั ะท SSH.
principal_desc=ะฆั ะฝะฐัััะพะนะบะธ SSH ัะตััะธััะบะฐััะฒ ะฒะบะฐะทะฐะฝั ั ะฒะฐัะพะผั ะพะฑะปัะบะพะฒะพะผั ะทะฐะฟะธัั ัะฐ ะฝะฐะดะฐััั ะฟะพะฒะฝะธะน ะดะพัััะฟ ะดะพ ะฒะฐัะธั
ัะตะฟะพะทะธัะพัััะฒ.
gpg_desc=ะฆั ะฟัะฑะปััะฝั ะบะปััั GPG ะฟะพะฒ'ัะทะฐะฝั ะท ะฒะฐัะธะผ ะพะฑะปัะบะพะฒะธะผ ะทะฐะฟะธัะพะผ. ะขัะธะผะฐะนัะต ัะฒะพั ะฟัะธะฒะฐัะฝั ะบะปััั ะฒ ะฑะตะทะฟะตัั, ะพัะบัะปัะบะธ ะฒะพะฝะธ ะดะพะทะฒะพะปัััั ะทะดัะนัะฝัะฒะฐัะธ ะฟะตัะตะฒััะบั ะบะพะผัััะฒ.
ssh_helper=ะะพัััะฑะฝะฐ ะดะพะฟะพะผะพะณะฐ? ะะธะฒััััั ะณัะด ะฝะฐ GitHub ะท ะณะตะฝะตัะฐััั ะบะปัััะฒ SSH ะฐะฑะพ ะฒะธะฟัะฐะฒะปะตะฝะฝั ัะธะฟะพะฒะธั
ะฝะตะฟะพะปะฐะดะพะบ SSH .
gpg_helper= ะะพัััะฑะฝะฐ ะดะพะฟะพะผะพะณะฐ? ะะตัะตะณะปัะฝััะต ะฟะพััะฑะฝะธะบ GitHub ะฟัะพ GPG .
add_new_key=ะะพะดะฐัะธ SSH ะบะปัั
add_new_gpg_key=ะะพะดะฐัะธ GPG ะบะปัั
-key_content_ssh_placeholder=ะะพัะธะฝะฐััััั ะท 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', ะฐะฑะพ 'sk-ssh-ed25519@openssh.com'
-key_content_gpg_placeholder=ะะพัะธะฝะฐััััั ะท '-----BEGIN PGP PUBLIC KEY BLOCK-----'
-add_new_principal=ะะพะดะฐัะธ ะบะพัะธัััะฒะฐัะฐ
+key_content_ssh_placeholder=ะะพัะธะฝะฐััััั ะท ยซssh-ed25519ยป, ยซssh-rsaยป, ยซecdsa-sha2-nistp256ยป, ยซecdsa-sha2-nistp384ยป, ยซecdsa-sha2-nistp521ยป, ยซsk-ecdsa-sha2-nistp256@openssh.comยป ะฐะฑะพ ยซsk-ssh-ed25519@openssh.comยป
+key_content_gpg_placeholder=ะะพัะธะฝะฐััััั ะท ยซ-----BEGIN PGP PUBLIC KEY BLOCK-----ยป
+add_new_principal=ะะพะดะฐัะธ ะฟัะธะฝัะธะฟะฐะป
ssh_key_been_used=ะฆะตะน SSH ะบะปัั ะฒะถะต ะฑัะฒ ะดะพะดะฐะฝะพ ะดะพ ัะตัะฒะตัะฐ.
ssh_key_name_used=ะะปัั SSH ะท ัะฐะบะธะผ ัะผ'ัะผ ะฒะถะต ััะฝัั ั ะฒะฐัะพะผั ะพะฑะปัะบะพะฒะพะผั ะทะฐะฟะธัั.
ssh_principal_been_used=ะฆะตะน ะบะพัะธัััะฒะฐั ะฒะถะต ะฑัะฒ ะดะพะดะฐะฝะธะน ะฝะฐ ัะตัะฒะตั.
@@ -657,7 +839,7 @@ gpg_token=ะขะพะบะตะฝ
gpg_token_help=ะะธ ะผะพะถะตัะต ััะฒะพัะธัะธ ะฟัะดะฟะธั ะทะฐ ะดะพะฟะพะผะพะณะพั:
gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
gpg_token_signature=ะขะตะบััะพะฒะธะน (armored) ะฟัะดะฟะธั GPG
-key_signature_gpg_placeholder=`ะะพัะธะฝะฐััััั ะท "-----BEGIN PGP SIGNATURE-----"`
+key_signature_gpg_placeholder=ะะพัะธะฝะฐััััั ะท ยซ-----BEGIN PGP SIGNATURE-----ยป
ssh_key_verified=ะะตัะตะฒััะตะฝะธะน ะบะปัั
ssh_key_verify=ะัะดัะฒะตัะดะธัะธ
ssh_token_required=ะะฐะผ ะฟะพัััะฑะฝะพ ะฝะฐะดะฐัะธ ะฟัะดะฟะธั ะดะปั ะฝะธะถัะตะฒะบะฐะทะฐะฝะพะณะพ ัะพะบะตะฝะฐ
@@ -669,8 +851,8 @@ key_name=ะะผ'ั ะบะปััะฐ
key_content=ะะผััั
principal_content=ะะผััั
delete_key=ะะธะดะฐะปะธัะธ
-ssh_key_deletion=ะะธะดะฐะปะธัะธ SSH ะบะปัั
-gpg_key_deletion=ะะธะดะฐะปะธัะธ GPG ะบะปัั
+ssh_key_deletion=ะะธะดะฐะปะธัะธ ะบะปัั SSH
+gpg_key_deletion=ะะธะดะฐะปะธัะธ ะบะปัั GPG
ssh_principal_deletion=ะะธะดะฐะปะธัะธ SSH ัะตััะธััะบะฐั ะบะพัะธัััะฒะฐัะฐ
ssh_key_deletion_desc=ะะธะดะฐะปะตะฝะฝั ะบะปััะฐ SSH ัะบะฐัะพะฒัั ะดะพัััะฟ ะดะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั. ะัะพะดะพะฒะถะธัะธ?
gpg_key_deletion_desc=ะะธะดะฐะปะตะฝะฝั GPG ะบะปััะฐ ัะบะฐัะพะฒัั ะฟะตัะตะฒััะบั ะฟัะดะฟะธัะฐะฝะธั
ะฝะธะผ ะบะพะผัััะฒ. ะัะพะดะพะฒะถะธัะธ?
@@ -693,10 +875,10 @@ ssh_externally_managed=ะฆะตะน ะบะปัั SSH ะผะฐั ะทะพะฒะฝััะฝั ัะฟัะฐะฒะป
manage_social=ะะตััะฒะฐัะธ ะทะฒ'ัะทะฐะฝะธะผะธ ะพะฑะปัะบะพะฒะธะผะธ ะทะฐะฟะธัะฐะผะธ ัะพััะฐะปัะฝะธั
ะผะตัะตะถ
unbind=ะัะด'ัะดะฝะฐัะธ
-manage_access_token=ะะตััะฒะฐะฝะฝั ัะพะบะตะฝะฐะผะธ ะดะพัััะฟั
+manage_access_token=ะขะพะบะตะฝะธ ะดะพัััะฟั
generate_new_token=ะะณะตะฝะตััะฒะฐัะธ ะฝะพะฒะธะน ัะพะบะตะฝ
tokens_desc=ะฆั ัะพะบะตะฝะธ ะฝะฐะดะฐััั ะดะพัััะฟ ะดะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะทะฐ ะดะพะฟะพะผะพะณะพั Forgejo API.
-token_name=ะะผ'ั ัะพะบะตะฝั
+token_name=ะะผ'ั ัะพะบะตะฝะฐ
generate_token=ะะณะตะฝะตััะฒะฐัะธ ัะพะบะตะฝ
generate_token_success=ะะฐั ะฝะพะฒะธะน ัะพะบะตะฝ ะฑัะฒ ััะฒะพัะตะฝะธะน. ะกะบะพะฟััะนัะต ะนะพะณะพ ะทะฐัะฐะท, ะพัะบัะปัะบะธ ะฒัะฝ ะฝะต ะฑัะดะต ะฟะพะบะฐะทะฐะฝะธะน ะทะฝะพะฒั.
generate_token_name_duplicate=ะะฐะทะฒะฐ ะฟัะพะณัะฐะผะธ %s ะฒะถะต ะฒะธะบะพัะธััะพะฒัััััั. ะัะดั ะปะฐัะบะฐ, ะฒะธะบะพัะธััะฐะนัะต ะฝะพะฒั.
@@ -713,13 +895,13 @@ oauth2_applications_desc=ะัะพะณัะฐะผะธ OAuth2 ะดะฐััั ะผะพะถะปะธะฒัััั
remove_oauth2_application=ะะธะดะฐะปะธัะธ ะฟัะพะณัะฐะผั OAuth2
remove_oauth2_application_desc=ะะธะดะฐะปะตะฝะฝั ะฟัะพะณัะฐะผะธ OAuth2 ัะบะฐัะพะฒัั ะดะพัััะฟ ะดะพ ะฒััั
ะฟัะดะฟะธัะฐะฝะธั
ะผะฐัะบะตััะฒ ะดะพัััะฟั. ะัะพะดะพะฒะถะธัะธ?
remove_oauth2_application_success=ะัะพะณัะฐะผั ะฒะธะดะฐะปะตะฝะพ.
-create_oauth2_application=ะกัะฒะพัะธัะธ ะฝะพะฒั ะฟัะพะณัะฐะผั OAuth2
+create_oauth2_application=ะกัะฒะพัะธัะธ ะฝะพะฒะธะน ะดะพะดะฐัะพะบ OAuth2
create_oauth2_application_button=ะกัะฒะพัะธัะธ ะฟัะพะณัะฐะผั
oauth2_application_name=ะะฐะทะฒะฐ ะฟัะพะณัะฐะผะธ
save_application=ะะฑะตัะตะณัะธ
oauth2_client_id=ID ะะปััะฝัะฐ
oauth2_client_secret=ะะปัั ะบะปััะฝัะฐ
-oauth2_regenerate_secret=ะัะดะฝะพะฒะธัะธ ะบะปัั
+oauth2_regenerate_secret=ะะณะตะฝะตััะฒะฐัะธ ะฝะพะฒะธะน ะบะปัั
oauth2_regenerate_secret_hint=ะะธ ะฒััะฐัะธะปะธ ัะฒัะน ะบะปัั?
oauth2_application_edit=ะ ะตะดะฐะณัะฒะฐัะธ
oauth2_application_create_description=ะัะพะณัะฐะผะธ OAuth2 ะฝะฐะดะฐััั ะฒะฐัะธะผ ััะพัะพะฝะฝัะผ ะฟัะพะณัะฐะผะฐะผ ะดะพัััะฟ ะดะพ ะพะฑะปัะบะพะฒะธั
ะทะฐะฟะธััะฒ ะบะพัะธัััะฒะฐััะฒ ั ััะพะผั ะตะบะทะตะผะฟะปััั.
@@ -731,9 +913,9 @@ revoke_oauth2_grant_description=ะกะบะฐััะฒะฐะฝะฝั ะดะพัััะฟั ะดะปั ัั
twofa_desc=ะะฒะพัะฐะบัะพัะฝะฐ ะฐะฒัะตะฝัะธััะบะฐััั ะฟัะดะฒะธััั ะฑะตะทะฟะตะบั ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั.
twofa_is_enrolled=ะะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฝะฐ ะดะฐะฝะธะน ัะฐั ะฒะธะบะพัะธััะพะฒัั ะดะฒะพัะฐะบัะพัะฝั ะฐะฒัะตะฝัะธััะบะฐััั.
-twofa_not_enrolled=ะะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฝะฐัะฐะทั ะฝะต ะฒะธะบะพัะธััะพะฒัั ะดะฒะพัะฐะบัะพัะฝั ะฐะฒัะตะฝัะธััะบะฐัััั.
+twofa_not_enrolled=ะะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฝะฐัะฐะทั ะฝะต ะฒะธะบะพัะธััะพะฒัั ะดะฒะพัะฐะบัะพัะฝั ะฐะฒัะตะฝัะธััะบะฐััั.
twofa_disable=ะะธะผะบะฝััะธ ะดะฒะพัะฐะบัะพัะฝั ะฐะฒัะตะฝัะธััะบะฐััั
-twofa_scratch_token_regenerate=ะะตัะตััะฒะพัะธัะธ ัะพะบะตะฝ ะพะดะฝะพัะฐะทะพะฒะพะณะพ ะฟะฐัะพะปั
+twofa_scratch_token_regenerate=ะะณะตะฝะตััะฒะฐัะธ ะฝะพะฒะธะน ะพะดะฝะพัะฐะทะพะฒะธะน ะบะปัั ะฒัะดะฝะพะฒะปะตะฝะฝั
twofa_enroll=ะฃะฒัะผะบะฝััะธ ะดะฒะพัะฐะบัะพัะฝั ะฐะฒัะตะฝัะธััะบะฐััั
twofa_disable_note=ะัะธ ะฝะตะพะฑั
ัะดะฝะพััั ะผะพะถะฝะฐ ะฒัะดะบะปััะธัะธ ะดะฒะพัะฐะบัะพัะฝั ะฐะฒัะตะฝัะธััะบะฐััั.
twofa_disable_desc=ะะธะผะบะฝะตะฝะฝั ะดะฒะพัะฐะบัะพัะฝะพั ะฐะฒัะตะฝัะธััะบะฐััั ะทัะพะฑะธัั ะฒะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะผะตะฝั ะฑะตะทะฟะตัะฝะธะผ. ะัะพะดะพะฒะถะธัะธ?
@@ -747,28 +929,28 @@ twofa_enrolled=ะะปั ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะฑัะปะพ ะฒ
twofa_failed_get_secret=ะะต ะฒะดะฐะปะพัั ะพััะธะผะฐัะธ ัะตะบัะตั.
-manage_account_links=ะะตััะฒะฐะฝะฝั ะพะฑะปัะบะพะฒะธะผะธ ะทะฐะฟะธัะฐะผะธ
+manage_account_links=ะะพะฒ'ัะทะฐะฝั ะพะฑะปัะบะพะฒั ะทะฐะฟะธัะธ
manage_account_links_desc=ะฆั ะทะพะฒะฝััะฝั ะฐะบะฐัะฝัะธ ะฟัะธะฒ'ัะทะฐะฝั ะดะพ ะฒะฐัะพะณะพ ะฐะบะบะฐัะฝัั Forgejo.
account_links_not_available=ะะฐัะฐะทั ะฝะตะผะฐั ะทะพะฒะฝััะฝัั
ะพะฑะปัะบะพะฒะธั
ะทะฐะฟะธััะฒ, ะฟะพะฒ'ัะทะฐะฝะธั
ัะท ะฒะฐัะธะผ ะพะฑะปัะบะพะฒะธะผ ะทะฐะฟะธัะพะผ Forgejo.
link_account=ะัะธะฒ'ัะทะฐัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
-remove_account_link=ะะธะดะฐะปะธัะธ ะพะฑะปัะบะพะฒั ะทะฐะฟะธัะธ
+remove_account_link=ะะธะดะฐะปะธัะธ ะฟะพะฒ'ัะทะฐะฝะธะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
remove_account_link_desc=ะะธะดะฐะปะตะฝะฝั ะฟะพะฒ'ัะทะฐะฝะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะฒัะดะบะปะธะบะฐั ะนะพะณะพ ะดะพัััะฟ ะดะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั Forgejo. ะัะพะดะพะฒะถะธัะธ?
remove_account_link_success=ะะฒ'ัะทะฐะฝะธะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฒะธะดะฐะปะตะฝะพ.
orgs_none=ะะธ ะฝะต ั ััะฐัะฝะธะบะพะผ ะฑัะดั-ัะบะพั ะพัะณะฐะฝัะทะฐััั.
-delete_account=ะะธะดะฐะปะธัะธ ะฒะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
+delete_account=ะะธะดะฐะปะธัะธ ัะฒัะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
delete_prompt=ะฆั ะพะฟะตัะฐััั ะพััะฐัะพัะฝะพ ะฒะธะดะฐะปะธัั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะบะพัะธัััะฒะฐัะฐ. ะฆะต ะะ ะะะะะะะ ะฒัะดะผัะฝะธัะธ.
delete_with_all_comments=ะะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะผะพะปะพะดัะธะน ะทะฐ %s ะดะฝัะฒ. ะฉะพะฑ ัะฝะธะบะฝััะธ ะบะพะผะตะฝัะฐััะฒ-ะฟัะธะฒะธะดัะฒ, ะฒัั ะทะฐะฟะธัะธ/PR ะบะพะผะตะฝััะฐัั ะฑัะดััั ะฒะธะดะฐะปะตะฝั ะท ะฝะธะผ.
-confirm_delete_account=ะัะดัะฒะตัะดะถะตะฝะฝั ะฒะธะดะฐะปะตะฝะฝั
-delete_account_title=ะะธะดะฐะปะธัะธ ัะตะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
+confirm_delete_account=ะัะดัะฒะตัะดะธัะธ ะฒะธะดะฐะปะตะฝะฝั
+delete_account_title=ะะธะดะฐะปะธัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
delete_account_desc=ะะธ ะฒะฟะตะฒะฝะตะฝั, ัะพ ั
ะพัะตัะต ะพััะฐัะพัะฝะพ ะฒะธะดะฐะปะธัะธ ัะตะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั?
-email_notifications.enable=ะฃะฒัะผะบะฝััะธ ัะฟะพะฒััะตะฝะฝั email
-email_notifications.onmention=ะะพะฒัะดะพะผะปะตะฝะฝั email ััะปัะบะธ ะบะพะปะธ ะทะณะฐะดัััั
-email_notifications.disable=ะะธะผะบะฝััะธ email ัะฟะพะฒััะตะฝะฝั
-email_notifications.submit=ะะฐะปะฐัััะฒะฐัะธ ะฟะฐัะฐะผะตััะธ email
+email_notifications.enable=ะฃะฒัะผะบะฝััะธ email-ัะฟะพะฒััะตะฝะฝั
+email_notifications.onmention=Email ััะปัะบะธ ะบะพะปะธ ะทะณะฐะดัััั
+email_notifications.disable=ะะธะผะบะฝััะธ email-ัะฟะพะฒััะตะฝะฝั
+email_notifications.submit=ะะฑะตัะตะณัะธ ะฟะฐัะฐะผะตััะธ email
visibility=ะะธะดะธะผัััั ะบะพัะธัััะฒะฐัะฐ
visibility.public=ะัะฑะปััะฝะธะน
@@ -777,16 +959,124 @@ visibility.private=ะัะธะฒะฐัะฝะธะน
saved_successfully = ะะฐะปะฐัััะฒะฐะฝะฝั ััะฟััะฝะพ ะทะฑะตัะตะถะตะฝะพ.
comment_type_group_time_tracking = ะะฑะปัะบ ัะฐัั
location_placeholder = ะะพะดัะปััััั ะท ัะฝัะธะผะธ, ะดะต ะฟัะธะฑะปะธะทะฝะพ ะฒะธ ะทะฝะฐั
ะพะดะธัะตัั
-biography_placeholder = ะ ะพะทะบะฐะถััั ััะพั
ะธ ะฟัะพ ัะตะฑะต! (ะะพะถะตัะต ะฒะธะบะพัะธััะฐัะธ Markdown)
+biography_placeholder = ะ ะพะทะบะฐะถััั ััะพั
ะธ ะฟัะพ ัะตะฑะต! (ะัะดััะธะผัััััั Markdown)
hidden_comment_types = ะัะธั
ะพะฒะฐะฝั ัะธะฟะธ ะบะพะผะตะฝัะฐััะฒ
-keep_activity_private = ะัะธั
ะพะฒะฐัะธ ะะบัะธะฒะฝัััั ะทั ััะพััะฝะบะธ ะฟัะพััะปั
+keep_activity_private = ะัะธั
ะพะฒะฐัะธ ะฐะบัะธะฒะฝัััั ะทั ััะพััะฝะบะธ ะฟัะพััะปั
blocked_users = ะะฐะฑะปะพะบะพะฒะฐะฝั ะบะพัะธัััะฒะฐัั
-blocked_users_none = ะะธ ะฝะต ะทะฐะฑะปะพะบัะฒะฐะปะธ ะถะพะดะฝะพะณะพ ะบะพัะธัััะฒะฐัะฐ.
-profile_desc = ะะตััะนัะต ัะธะผ, ัะบ ะฒะฐั ะฟัะพััะปั ะฒัะดะพะฑัะฐะถะฐััััั ัะฝัะธะผ ะบะพัะธัััะฒะฐัะฐะผ. ะะฐัะฐ ะพัะฝะพะฒะฝะฐ ะฐะดัะตัะฐ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะฑัะดะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธัั ะดะปั ัะฟะพะฒััะตะฝั, ะฒัะดะฝะพะฒะปะตะฝะฝั ะฟะฐัะพะปั ัะฐ ะพะฟะตัะฐััะน ะท Git ัะตัะตะท ะฒะตะฑ-ัะฝัะตััะตะนั.
+blocked_users_none = ะะตะผะฐั ะทะฐะฑะปะพะบะพะฒะฐะฝะธั
ะบะพัะธัััะฒะฐััะฒ.
+profile_desc = ะัะพ ัะตะฑะต
retype_new_password = ะัะดัะฒะตัะดััั ะฝะพะฒะธะน ะฟะฐัะพะปั
email_desc = ะะฐัะฐ ะพัะฝะพะฒะฝะฐ ะฐะดัะตัะฐ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะฑัะดะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธัั ะดะปั ัะฟะพะฒััะตะฝั, ะฒัะดะฝะพะฒะปะตะฝะฝั ะฟะฐัะพะปั ั, ะทะฐ ัะผะพะฒะธ, ัะพ ะฒะพะฝะฐ ะฝะต ะฟัะธั
ะพะฒะฐะฝะฐ, ะดะปั ะพะฟะตัะฐััะน ะท Git ัะตัะตะท ะฒะตะฑ-ัะฝัะตััะตะนั.
visibility.limited_tooltip = ะะธะดะธะผะธะน(ะฐ) ััะปัะบะธ ะดะปั ะฐะฒัะพัะธะทะพะฒะฐะฝะธั
ะบะพัะธัััะฒะฐััะฒ
visibility.private_tooltip = ะะธะดะธะผะธะน(ะฐ) ััะปัะบะธ ะดะปั ััะฐัะฝะธะบัะฒ ะพัะณะฐะฝัะทะฐััะน, ะดะพ ัะบะธั
ะฒะธ ะฟัะธัะดะฝะฐะปะธัั
+twofa_scratch_token_regenerated = ะะฐั ะพะดะฝะพัะฐะทะพะฒะธะน ะบะปัั ะฒัะดะฝะพะฒะปะตะฝะฝั: %s. ะะฑะตัะตะถััั ะนะพะณะพ ั ะฑะตะทะฟะตัะฝะพะผั ะผัััั, ะฑะพ ะฒัะฝ ะฝะต ะฑัะดะต ะฟะพะบะฐะทะฐะฝะธะน ะทะฝะพะฒั.
+authorized_oauth2_applications_description = ะะธ ะฝะฐะดะฐะปะธ ัะธะผ ััะพัะพะฝะฝัะผ ะทะฐััะพััะฝะบะฐะผ ะดะพัััะฟ ะดะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั Forgejo. ะัะดั ะปะฐัะบะฐ, ะฒัะดะบะปะธััะต ะดะพัััะฟ ัะท ะทะฐััะพััะฝะบัะฒ, ัะพ ะฑัะปััะต ะฝะต ะฒะธะบะพัะธััะพะฒัััััั.
+webauthn_delete_key = ะะธะดะฐะปะธัะธ ะบะปัั ะฑะตะทะฟะตะบะธ
+webauthn_key_loss_warning = ะฏะบัะพ ะฒะธ ะฒััะฐัะธัะต ะบะปัั ะฑะตะทะฟะตะบะธ, ัะพ ะฒััะฐัะธัะต ะดะพัััะฟ ะดะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั.
+webauthn_register_key = ะะพะดะฐัะธ ะบะปัั ะฑะตะทะฟะตะบะธ
+webauthn_nickname = ะัะตะฒะดะพะฝัะผ
+webauthn_desc = ะะปััั ะฑะตะทะฟะตะบะธ โ ัะต ะฐะฟะฐัะฐัะฝั ะฟัะธัััะพั, ัะพ ะผัััััั ะบัะธะฟัะพะณัะฐัััะฝั ะบะปััั. ะะพะฝะธ ะผะพะถััั ะฒะธะบะพัะธััะพะฒัะฒะฐัะธัั ะดะปั ะดะฒะพัะฐะบัะพัะฝะพั ะฐะฒัะตะฝัะธััะบะฐััั. ะะปััั ะฑะตะทะฟะตะบะธ ะผะฐััั ะฟัะดััะธะผัะฒะฐัะธ ััะฐะฝะดะฐัั WebAuthn Authenticator .
+revoke_oauth2_grant_success = ะะพัััะฟ ะฒัะดะบะปะธะบะฐะฝะพ ััะฟััะฝะพ.
+twofa_recovery_tip = ะฏะบัะพ ะฒะธ ะฒััะฐัะธัะต ะฒะฐั ะฟัะธััััะน, ะฒะธ ะทะผะพะถะตัะต ะฒะธะบะพัะธััะฐัะธ ะพะดะฝะพัะฐะทะพะฒะธะน ะบะปัั ะฒัะดะฝะพะฒะปะตะฝะฝั, ัะพะฑ ะทะฝะพะฒั ะพััะธะผะฐัะธ ะดะพัััะฟ ะดะพ ัะฒะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั.
+webauthn_delete_key_desc = ะฏะบัะพ ะฒะธ ะฒะธะดะฐะปะธัะต ะบะปัั ะฑะตะทะฟะตะบะธ, ะฒะธ ะฑัะปััะต ะฝะต ะทะผะพะถะตัะต ะท ะฝะธะผ ะทะฐะนัะธ. ะัะพะดะพะฒะถะธัะธ?
+change_password = ะะผัะฝะฐ ะฟะฐัะพะปั
+email_notifications.andyourown = ะ ะฒะฐัั ะฒะปะฐัะฝั ัะฟะพะฒััะตะฝะฝั
+visibility.public_tooltip = ะะธะดะธะผะธะน(ะฐ) ะดะปั ะฒััั
+update_language_not_found = ะะพะฒะฐ ยซ%sยป ะฝะตะดะพัััะฟะฝะฐ.
+pronouns = ะะฐะนะผะตะฝะฝะธะบะธ
+pronouns_unspecified = ะะต ะฒะบะฐะทะฐะฝั
+hints = ะัะดะบะฐะทะบะธ
+language.title = ะะพะฒะฐ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
+update_hints = ะะฝะพะฒะธัะธ ะฟัะดะบะฐะทะบะธ
+update_hints_success = ะัะดะบะฐะทะบะธ ะพะฝะพะฒะปะตะฝะพ.
+additional_repo_units_hint = ะัะพะฟะพะฝัะฒะฐัะธ ัะฒัะผะบะฝััะธ ะดะพะดะฐัะบะพะฒั ัะพะทะดัะปะธ ัะตะฟะพะทะธัะพััั
+additional_repo_units_hint_description = ะะพะบะฐะทัะฒะฐัะธ ะฟัะดะบะฐะทะบั ยซะฃะฒัะผะบะฝััะธ ัะตยป ะดะปั ัะตะฟะพะทะธัะพัััะฒ, ั ัะบะธั
ัะฒัะผะบะฝะตะฝะพ ะฝะต ะฒัั ะดะพัััะฟะฝั ัะพะทะดัะปะธ.
+language.description = ะฆั ะผะพะฒั ะฑัะดะต ะทะฑะตัะตะถะตะฝะพ ั ะฒะฐัะพะผั ะพะฑะปัะบะพะฒะพะผั ะทะฐะฟะธัั, ะฒะพะฝะฐ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธะผะตัััั ะฟััะปั ัะพะณะพ, ัะบ ะฒะธ ะฒะฒัะนะดะตัะต ะฒ ัะธััะตะผั.
+language.localization_project = ะะพะฟะพะผะพะถััั ะฝะฐะผ ะฟะตัะตะบะปะฐััะธ Forgejo ะฒะฐัะพั ะผะพะฒะพั! ะัะทะฝะฐัะธัั ะฑัะปััะต .
+permissions_list = ะะพะทะฒะพะปะธ:
+comment_type_group_dependency = ะะฐะปะตะถะฝัััั
+comment_type_group_pull_request_push = ะะพะดะฐะฝั ะบะพะผััะธ
+permissions_public_only = ะขัะปัะบะธ ะฟัะฑะปััะฝั
+select_permissions = ะะธะฑะตัััั ะดะพะทะฒะพะปะธ
+permissions_access_all = ะฃัั (ะฟัะฑะปััะฝั, ะฟัะธะฒะฐัะฝั ะน ะพะฑะผะตะถะตะฝั)
+create_oauth2_application_success = ะะธ ััะฟััะฝะพ ััะฒะพัะธะปะธ ะฝะพะฒะธะน ะดะพะดะฐัะพะบ OAuth2.
+keep_email_private_popup = ะะฐัะฐ ะฐะดัะตัะฐ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะฝะต ะฑัะดะต ะฒัะดะพะฑัะฐะถะฐัะธัั ั ะฒะฐัะพะผั ะฟัะพััะปั ั ะฝะต ะฑัะดะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธัั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ะดะปั ะบะพะผัััะฒ, ะทัะพะฑะปะตะฝะธั
ัะตัะตะท ะฒะตะฑ-ัะฝัะตััะตะนั, ัะฐะบะธั
ัะบ ะทะฐะฒะฐะฝัะฐะถะตะฝะฝั ัะฐะนะปัะฒ, ัะตะดะฐะณัะฒะฐะฝะฝั ั ะพะฑ'ัะดะฝะฐะฝะฝั ะบะพะผัััะฒ. ะะฐัะพะผัััั ะฒะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ัะฟะตััะฐะปัะฝั ะฐะดัะตัั %s ะดะปั ะฟัะธะฒ'ัะทะบะธ ะบะพะผัััะฒ ะดะพ ัะฒะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั. ะฆั ะพะฟััั ะฝะต ะฒะฟะปะธะฝะต ะฝะฐ ััะฝัััั ะบะพะผััะธ.
+blocked_since = ะะฐะฑะปะพะบะพะฒะฐะฝะธะน ะท %s
+can_not_add_email_activations_pending = ะััะบัััััั ะฐะบัะธะฒะฐััั, ัะฟัะพะฑัะนัะต ัะต ัะฐะท ะทะฐ ะบัะปัะบะฐ ั
ะฒะธะปะธะฝ, ัะบัะพ ั
ะพัะตัะต ะดะพะดะฐัะธ ะฝะพะฒั ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ.
+ssh_signonly = SSH ะฝะฐัะฐะทั ะฒะธะผะบะฝะตะฝะพ, ัะพะผั ัั ะบะปััั ะฒะธะบะพัะธััะพะฒัััััั ะปะธัะต ะดะปั ะฟะตัะตะฒััะบะธ ะฟัะดะฟะธัั ะบะพะผัััะฒ.
+uid = UID
+at_least_one_permission = ะะปั ััะฒะพัะตะฝะฝั ัะพะบะตะฝะฐ ะฝะตะพะฑั
ัะดะฝะพ ะฒะธะฑัะฐัะธ ั
ะพัะฐ ะฑ ะพะดะธะฝ ะดะพะทะฒัะป
+verify_gpg_key_success = ะะปัั GPG ยซ%sยป ะฟะตัะตะฒััะตะฝะพ.
+repos_none = ะะธ ะฝะต ั ะฒะปะฐัะฝะธะบะพะผ ะถะพะดะฝะพะณะพ ัะตะฟะพะทะธัะพััั.
+add_gpg_key_success = ะะปัั GPG ยซ%sยป ะดะพะดะฐะฝะพ.
+add_key_success = ะะปัั SSH ยซ%sยป ะดะพะดะฐะฝะพ.
+permission_no_access = ะะตะผะฐั ะดะพัััะฟั
+permission_write = ะงะธัะฐะฝะฝั ั ะทะฐะฟะธั
+uploaded_avatar_is_too_big = ะ ะพะทะผัั ะทะฐะฒะฐะฝัะฐะถะตะฝะพะณะพ ัะฐะนะปั (%d ะัะ) ะฟะตัะตะฒะธััั ะผะฐะบัะธะผะฐะปัะฝะธะน ัะพะทะผัั (%d ะัะ).
+verify_ssh_key_success = ะะปัั SSH ยซ%sยป ะฟะตัะตะฒััะตะฝะพ.
+ssh_invalid_token_signature = ะะฐะดะฐะฝะธะน SSH-ะบะปัั, ะฟัะดะฟะธั ะฐะฑะพ ัะพะบะตะฝ ะฝะต ะทะฑัะณะฐััััั ะฐะฑะพ ัะพะบะตะฝ ะทะฐััะฐััะฒ.
+valid_until_date = ะัะนัะฝะธะน ะดะพ %s
+added_on = ะะพะดะฐะฝะพ %s
+key_signature_ssh_placeholder = ะะพัะธะฝะฐััััั ะท ยซ-----BEGIN SSH SIGNATURE-----ยป
+user_block_yourself = ะะธ ะฝะต ะผะพะถะตัะต ะทะฐะฑะปะพะบัะฒะฐัะธ ัะตะฑะต.
+pronouns_custom_label = ะะฝัั ะทะฐะนะผะตะฝะฝะธะบะธ
+repo_and_org_access = ะะพัััะฟ ะดะพ ัะตะฟะพะทะธัะพััั ัะฐ ะพัะณะฐะฝัะทะฐััั
+change_username_redirect_prompt.with_cooldown.few = ะกัะฐัะต ัะผ'ั ะบะพัะธัััะฒะฐัะฐ ะฑัะดะต ะดะพัััะฟะฝะต ะฒััะผ ะฟััะปั ะฟะตััะพะดั ะทะฐั
ะธััั, ัะบะธะน ััะธะฒะฐัะธะผะต %[1]d ะดะฝัะฒ. ะัะพััะณะพะผ ะฟะตััะพะดั ะทะฐั
ะธััั ะฒะธ ัะต ะผะพะถะตัะต ะฟะพะฒะตัะฝััะธ ัะพะฑั ััะฐัะต ัะผ'ั.
+change_username_redirect_prompt.with_cooldown.one = ะกัะฐัะต ัะผ'ั ะบะพัะธัััะฒะฐัะฐ ะฑัะดะต ะดะพัััะฟะฝะต ะฒััะผ ะฟััะปั ะฟะตััะพะดั ะทะฐั
ะธััั, ัะบะธะน ััะธะฒะฐัะธะผะต %[1]d ะดะตะฝั. ะัะพััะณะพะผ ะฟะตััะพะดั ะทะฐั
ะธััั ะฒะธ ัะต ะผะพะถะตัะต ะฟะพะฒะตัะฝััะธ ัะพะฑั ััะฐัะต ัะผ'ั.
+change_username_redirect_prompt = ะกัะฐัะต ัะผ'ั ะบะพัะธัััะฒะฐัะฐ ะฑัะดะต ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝะฝัะผ, ะฟะพะบะธ ั
ัะพัั ะฝะต ะฟัะธัะฒะพััั ัะผ'ั ัะพะฑั.
+comment_type_group_lock = ะกัะฐะฝ ะฑะปะพะบัะฒะฐะฝะฝั
+webauthn_alternative_tip = ะะพะถะปะธะฒะพ, ะฒะธ ะฑะฐะถะฐััะต ะฝะฐะปะฐัััะฒะฐัะธ ะดะพะดะฐัะบะพะฒะธะน ัะฟะพััะฑ ะฒั
ะพะดั.
+user_unblock_success = ะะพัะธัััะฒะฐั_ะบั ััะฟััะฝะพ ัะพะทะฑะปะพะบะพะฒะฐะฝะพ.
+webauthn = ะะฒะพัะฐะบัะพัะฝะธะน ะฒั
ัะด (ะบะปััั ะฑะตะทะฟะตะบะธ)
+keep_activity_private.description = ะะฐัั ะทะฐะณะฐะปัะฝะพะดะพัััะฟะฝั ะดััะปัะฝัััั ะฑัะดะต ะฒะธะดะฝะพ ะปะธัะต ะฒะฐะผ ั ะฐะดะผัะฝััััะฐััั ัะตัะฒะตัะฐ.
+hidden_comment_types_description = ะะพะทะฝะฐัะตะฝั ััั ัะธะฟะธ ะบะพะผะตะฝัะฐััะฒ ะฝะต ะฑัะดะต ะฟะพะบะฐะทะฐะฝะพ ะฝะฐ ััะพััะฝะบะฐั
ะทะฐะฒะดะฐะฝั. ะะฐะฟัะธะบะปะฐะด, ัะบัะพ ััั ะฟะพะทะฝะฐัะตะฝะฐ ยซะััะบะฐยป, ัะพ ะฒัั ะบะพะผะตะฝัะฐัั ยซ ะดะพะดะฐั/ะฒะธะปััะฐั ยป ะฑัะดะต ะฒะธะปััะตะฝะพ.
+comment_type_group_deadline = ะัะฐะนะฝัะน ัะตัะผัะฝ
+oauth2_redirect_uris = URI-ะฐะดัะตัะธ ะฟะตัะตัะฟััะผัะฒะฐะฝั. ะะธัััั ะบะพะถะฝั ะท ะฝะพะฒะพะณะพ ััะดะบะฐ.
+user_block_success = ะะพัะธัััะฒะฐั_ะบั ััะฟััะฝะพ ะทะฐะฑะปะพะบะพะฒะฐะฝะพ.
+change_username_prompt = ะะฐัะฒะฐะถัะต, ะทะผัะฝะฐ ะบะพัะธัััะฒะฐััะบะพะณะพ ัะผะตะฝั ัะฐะบะพะถ ะทะผัะฝัั URL-ะฐะดัะตัั ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั.
+oauth2_confidential_client = ะะพะฝััะดะตะฝััะนะฝะธะน ะบะปััะฝั. ะะฑะตัััั, ัะบัะพ ะฟัะพะณัะฐะผะฐ ะทะฑะตััะณะฐั ัะตะบัะตั ะบะพะฝััะดะตะฝััะนะฝะธะผ, ะฝะฐะฟัะธะบะปะฐะด ัะบัะพ ัะต ะฒะตะฑะทะฐััะพััะฝะพะบ. ะะต ะพะฑะธัะฐะนัะต ะดะปั ัััะปัะฝะธัะฝะธั
ั ะผะพะฑัะปัะฝะธั
ะฟัะพะณัะฐะผ.
+keep_pronouns_private = ะะพะบะฐะทัะฒะฐัะธ ะทะฐะนะผะตะฝะฝะธะบะธ ะปะธัะต ะฐะฒัะพัะธะทะพะฒะฐะฝะธะผ ะบะพัะธัััะฒะฐัะฐะผ
+keep_pronouns_private.description = ะะฐัั ะทะฐะนะผะตะฝะฝะธะบะธ ะฝะต ะฑัะดะต ะฟะพะบะฐะทะฐะฝะพ ะฒัะดะฒัะดัะฒะฐัะฐะผ, ัะบั ะฝะต ะฒะฒัะนัะปะธ ะฒ ัะธััะตะผั.
+hidden_comment_types.ref_tooltip = ะะพะผะตะฝัะฐัั, ะฒ ัะบะธั
ะฝะฐ ัั ะทะฐะดะฐัั ะฟะพัะปะฐะปะธัั ะท ัะฝัะพั ะทะฐะดะฐัั, ะบะพะผััั ัะพัะพ
+hidden_comment_types.issue_ref_tooltip = ะะพะผะตะฝัะฐัั, ะฒ ัะบะธั
ะบะพัะธัััะฒะฐั_ะบะฐ ะทะผัะฝัั ะณัะปะบั ัะธ ัะตะณ, ะฟะพะฒ'ัะทะฐะฝั ะท ะทะฐะดะฐัะตั
+comment_type_group_review_request = ะะฐะฟะธั ะฝะฐ ะฒัะดะณัะบ
+access_token_desc = ะัะธ ะพะฑัะฐะฝะธั
ะดะปั ัะพะบะตะฝะฐ ะดะพะทะฒะพะปะฐั
ะฑัะดััั ะฐะฒัะพัะธะทะพะฒะฐะฝั ะปะธัะต ะฒัะดะฟะพะฒัะดะฝั API -ัะพััะธ. ะะพะบะปะฐะดะฝััะต ะฒ ะดะพะบัะผะตะฝัะฐััั .
+update_oauth2_application_success = ะัะพะณัะฐะผั OAuth2 ััะฟััะฝะพ ะพะฝะพะฒะปะตะฝะพ.
+oauth2_client_secret_hint = ะะปัั ะฑัะปััะต ะฝะต ะฑัะดะต ะฟะพะบะฐะทะฐะฝะพ ะฟััะปั ะทะฐะบัะธััั ัะธ ะพะฝะพะฒะปะตะฝะฝั ััะพััะฝะบะธ. ะะฑะพะฒ'ัะทะบะพะฒะพ ะนะพะณะพ ะทะฑะตัะตะถััั.
+oauth2_application_remove_description = ะะธะดะฐะปะตะฝะฐ ะฟัะพะณัะฐะผะฐ OAuth2 ะฝะต ะทะผะพะถะต ะดะพัััะฟะฐัะธัั ะฐะฒัะพัะธะทะพะฒะฐะฝะธั
ะบะพัะธัััะฒะฐััะบะธั
ะพะฑะปัะบะพะฒะธั
ะทะฐะฟะธััะฒ ะฝะฐ ััะพะผั ัะตัะฒะตัั. ะัะพะดะพะฒะถะธัะธ?
+add_principal_success = ะัะธะฝัะธะฟะฐะป SSH-ัะตััะธััะบะฐัะฐ ยซ%sยป ะดะพะดะฐะฝะพ.
+hooks.desc = ะะพะดะฐะนัะต ะฒะตะฑั
ัะบะธ, ัะบั ัะฟัะฐััะพะฒัะฒะฐัะธะผััั ะดะปั ะฒััั
ัะตะฟะพะทะธัะพัััะฒ ั ะฒะฐััะน ะฒะปะฐัะฝะพััั.
+ssh_token_signature = SSH-ะฟัะดะฟะธั ั ะบะพะดัะฒะฐะฝะฝั Base64
+pronouns_custom = ะะปะฐัะฝั
+comment_type_group_issue_ref = ะะพัะธะปะฐะฝะฝั ะฝะฐ ะทะฐะดะฐัั
+add_email_confirmation_sent = ะะธัั ะฟัะดัะฒะตัะดะถะตะฝะฝั ะฑัะปะพ ะฝะฐะดััะปะฐะฝะพ ยซ%sยป. ะฉะพะฑ ะฟัะดัะฒะตัะดะธัะธ ะตะปะตะบััะพะฝะฝั ะฟะพััั, ะฟะตัะตะฒัััะต ะฒั
ัะดะฝั ะน ะฟะตัะตะนะดััั ะทะฐ ะฝะฐะฒะตะดะตะฝะธะผ ะฟะพัะธะปะฐะฝะฝัะผ (ะฝะฐ ัะต ะผะฐััะต %s).
+comment_type_group_reference = ะะพัะธะปะฐะฝะฝั
+ssh_key_verified_long = ะะปัั ะฟะตัะตะฒััะตะฝะธะน ะทะฐ ะดะพะฟะพะผะพะณะพั ัะพะบะตะฝะฐ ะน ะผะพะถะต ะฟัะดัะฒะตัะดะถัะฒะฐัะธ ะบะพะผััะธ ะท ะฑัะดั-ัะบะธั
ะฐะบัะธะฒะพะฒะฐะฝะธั
ะฐะดัะตั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะบะพัะธัััะฒะฐั_ะบะธ.
+access_token_deletion_desc = ะะธะดะฐะปะตะฝะฝั ัะพะบะตะฝะฐ ัะบะฐััั ะดะพัััะฟ ะฟัะพะณัะฐะผ, ัะบั ะฒะธะบะพัะธััะพะฒัััั ัะตะน ัะพะบะตะฝ, ะดะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั. ะฆะต ะฝะตะทะฒะพัะพัะฝะฐ ะดัั. ะัะพะดะพะฒะถะธัะธ?
+oauth2_application_locked = Forgejo ะฟะพะฟะตัะตะดะฝัะพ ัะตัััััั ะดะตัะบั ะฟัะพะณัะฐะผะธ OAuth2 ะฟัะธ ะทะฐะฟััะบั, ัะบัะพ ัะต ัะฒัะผะบะฝะตะฝะพ ะฒ ะบะพะฝััะณััะฐััั. ะฉะพะฑ ะทะฐะฟะพะฑัะณัะธ ะฝะตะพััะบัะฒะฐะฝัะน ะฟะพะฒะตะดัะฝัั, ัั
ะฝะต ะผะพะถะฝะฐ ัะตะดะฐะณัะฒะฐัะธ ัะธ ะฒะธะดะฐะปััะธ. ะะพะบะปะฐะดะฝััะต โ ะฒ ะดะพะบัะผะตะฝัะฐััั OAuth2.
+quota.rule.exceeded.helper = ะะฐะณะฐะปัะฝะธะน ัะพะทะผัั ะพะฑ'ัะบััะฒ ะทะฐ ัะธะผ ะฟัะฐะฒะธะปะพะผ ะฟะตัะตะฒะธััั ะบะฒะพัั.
+quota = ะะฒะพัะฐ
+quota.sizes.repos.private = ะัะธะฒะฐัะฝั ัะตะฟะพะทะธัะพััั
+quota.sizes.repos.public = ะัะฑะปััะฝั ัะตะฟะพะทะธัะพััั
+quota.sizes.git.all = ะะผััั Git
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.packages.all = ะะฐะบัะฝะบะธ
+quota.sizes.assets.artifacts = ะััะตัะฐะบัะธ
+quota.sizes.assets.attachments.issues = ะะบะปะฐะดะตะฝะฝั ะทะฐะดะฐั
+quota.sizes.assets.attachments.releases = ะะบะปะฐะดะตะฝะฝั ะฒะธะฟััะบัะฒ
+quota.sizes.wiki = ะัะบั
+quota.rule.no_limit = ะะต ะพะฑะผะตะถะตะฝะพ
+storage_overview = ะะณะปัะด ัั
ะพะฒะธัะฐ
+quota.sizes.all = ะฃัะต
+quota.sizes.repos.all = ะ ะตะฟะพะทะธัะพััั
+quota.applies_to_user = ะะพ ะฒะฐัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั ะทะฐััะพัะพะฒะฐะฝะพ ัะฐะบั ะบะฒะพัะธ
+quota.sizes.assets.attachments.all = ะะบะปะฐะดะตะฝะฝั
+quota.applies_to_org = ะะพ ัััั ะพัะณะฐะฝัะทะฐััั ะทะฐััะพัะพะฒะฐะฝะพ ัะฐะบั ะบะฒะพัะธ
+quota.rule.exceeded = ะะตัะตะฒะธัะตะฝะพ
+regenerate_token = ะะณะตะฝะตััะฒะฐัะธ ะทะฝะพะฒั
+access_token_regeneration = ะะณะตะฝะตััะฒะฐัะธ ะฝะพะฒะธะน ัะพะบะตะฝ ะดะพัััะฟั
+
+quota.sizes.assets.all = ะ ะตััััะธ
[repo]
owner=ะะปะฐัะฝะธะบ
@@ -795,7 +1085,7 @@ repo_name=ะะฐะทะฒะฐ ัะตะฟะพะทะธัะพััั
repo_name_helper=ะฅะพัะพัั ะฝะฐะทะฒะธ ัะตะฟะพะทะธัะพัััะฒ ะฒะธะบะพัะธััะพะฒัััั ะบะพัะพัะบั, ัะฝัะบะฐะปัะฝั ะบะปััะพะฒั ัะปะพะฒะฐ ัะพ ะปะตะณะบะพ ะทะฐะฟะฐะผ'ััะฐัะธ.
repo_size=ะ ะพะทะผัั ัะตะฟะพะทะธัะพััั
template=ะจะฐะฑะปะพะฝ
-template_select=ะะฑะตัััั ัะฐะฑะปะพะฝ.
+template_select=ะะธะฑะตัััั ัะฐะฑะปะพะฝ
template_helper=ะัะพะฑะธัะธ ัะตะฟะพะทะธัะพััะน ัะฐะฑะปะพะฝะพะผ
template_description=ะจะฐะฑะปะพะฝะฝั ัะตะฟะพะทะธัะพััั ะดะพะทะฒะพะปัััั ะบะพัะธัััะฒะฐัะฐะผ ะณะตะฝะตััะฒะฐัะธ ะฝะพะฒั ัะตะฟะพะทะธัะพััั ัะท ัะฐะบะพั ะถ ััััะบัััะพั ะดะธัะตะบัะพััะน, ัะฐะนะปะฐะผะธ ัะฐ ะดะพะดะฐัะบะพะฒะธะผะธ ะฝะฐะปะฐัััะฒะฐะฝะฝัะผะธ.
visibility=ะะธะดะธะผัััั
@@ -803,7 +1093,7 @@ visibility_description=ะขัะปัะบะธ ะฒะปะฐัะฝะธะบ ะฐะฑะพ ัะปะตะฝะธ ะพัะณะฐะฝ
visibility_helper_forced=ะะดะผัะฝััััะฐัะพั ะฒะฐัะพะณะพ ัะฐะนัั ะฝะฐะปะฐัััะฒะฐะฒ ะฟะฐัะฐะผะตััะธ: ะฒัั ะฝะพะฒั ัะตะฟะพะทะธัะพััั ะฑัะดััั ะฟัะธะฒะฐัะฝะธะผะธ.
visibility_fork_helper=(ะฆั ะทะผัะฝะธ ะฒะฟะปะธะฝััั ะฝะฐ ะฒัั ัะพัะบะธ.)
clone_helper=ะะพัััะฑะฝะฐ ะดะพะฟะพะผะพะณะฐ ั ะบะปะพะฝัะฒะฐะฝะฝั? ะัะดะฒัะดะฐะนัะต ััะพััะฝะบั ะะพะฟะพะผะพะณะฐ .
-fork_repo=ะคะพัะบะฝััะธ ัะตะฟะพะทะธัะพััะน
+fork_repo=ะกัะฒะพัะธัะธ ัะพัะบ ัะตะฟะพะทะธัะพััั
fork_from=ะคะพัะบ ะท
fork_visibility_helper=ะะตะผะพะถะปะธะฒะพ ะทะผัะฝะธัะธ ะฒะธะดะธะผัััั ัะพัะบะฝััะพะณะพ ัะตะฟะพะทะธัะพััั.
use_template=ะะฐััะพััะฒะฐัะธ ัะตะน ัะฐะฑะปะพะฝ
@@ -816,24 +1106,24 @@ generate_from=ะะตะฝะตััะฒะฐัะธ ะท
repo_desc=ะะฟะธั
repo_desc_helper=ะะฒะตะดััั ะบะพัะพัะบะธะน ะพะฟะธั (ะพะฟััะพะฝะฐะปัะฝะพ)
repo_lang=ะะพะฒะฐ
-repo_gitignore_helper=ะะธะฑะตัััั ัะฐะฑะปะพะฝ .gitignore.
+repo_gitignore_helper=ะะธะฑะตัััั ัะฐะฑะปะพะฝะธ .gitignore
repo_gitignore_helper_desc=ะะฑะตัััั ะท ัะฟะธัะบั ะผะพะฒะฝะธั
ัะฐะฑะปะพะฝัะฒ ัะฐะนะปะธ, ัะบั ะฝะต ะฑัะดััั ะฒัะดััะตะถัะฒะฐัะธัั. ะขะธะฟะพะฒั ะฐััะตัะฐะบัะธ, ัะบั ะณะตะฝะตััััััั ะทะฐ ะดะพะฟะพะผะพะณะพั ัะฝััััะผะตะฝััะฒ ะฟะพะฑัะดะพะฒะธ ะบะพะถะฝะพั ะผะพะฒะธ, ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ะฒะบะปััะตะฝั ะดะพ .gitignor.
-issue_labels=ะััะบะธ ะทะฐะดะฐัั
-issue_labels_helper=ะะธะฑัะฐัะธ ะผััะบั ะดะปั ะทะฐะดะฐัั.
+issue_labels=ะััะบะธ
+issue_labels_helper=ะะธะฑะตัััั ะฝะฐะฑัั ะผััะพะบ
license=ะััะตะฝะทัั
-license_helper=ะะธะฑะตัััั ะปััะตะฝะทัะนะฝะธะน ัะฐะนะป.
-license_helper_desc=ะััะตะฝะทัั ัะตะณัะปัั ัะต, ัะพ ัะฝัั ะผะพะถััั ั ะฝะต ะผะพะถััั ัะพะฑะธัะธ ะท ะฒะฐัะธะผ ะบะพะดะพะผ. ะะต ะฒะฟะตะฒะฝะตะฝั, ัะพ ัะฐะผะต ะฟัะดั
ะพะดะธัั ะดะปั ะฒะฐัะพะณะพ ะฟัะพัะบัั? ะะธะฒััััั ะะธะฑะตัััั ะปััะตะฝะทัั.
+license_helper=ะะธะฑะตัััั ัะฐะนะป ะปััะตะฝะทัั
+license_helper_desc=ะััะตะฝะทัั ัะตะณัะปัั ัะต, ัะพ ัะฝัั ะผะพะถััั ั ะฝะต ะผะพะถััั ัะพะฑะธัะธ ะท ะฒะฐัะธะผ ะบะพะดะพะผ. ะะต ะฒะฟะตะฒะฝะตะฝั, ัะพ ัะฐะผะต ะฟัะดั
ะพะดะธัั ะดะปั ะฒะฐัะพะณะพ ะฟัะพัะบัั? ะะธะฒััััั ะะธะฑะตัััั ะปััะตะฝะทัั .
readme=README
-readme_helper=ะะธะฑะตัััั ัะฐะฑะปะพะฝ README.
+readme_helper=ะะธะฑะตัััั ัะฐะฑะปะพะฝ README
readme_helper_desc=ะฆะต ะผัััะต, ะดะต ะฒะธ ะผะพะถะตัะต ะฝะฐะฟะธัะฐัะธ ะฟะพะฒะฝะธะน ะพะฟะธั ะฒะฐัะพะณะพ ะฟัะพัะบัั.
-auto_init=ะะฝัััะฐะปัะทัะฒะฐัะธ ัะตะฟะพะทะธัะพััะน (ะะพะดะฐั .gitignore, LICENSE ัะฐ README)
+auto_init=ะะฝัััะฐะปัะทัะฒะฐัะธ ัะตะฟะพะทะธัะพััะน
trust_model_helper=ะะธะฑะตัััั ะผะพะดะตะปั ะดะพะฒััะธ ะดะปั ะฟัะดัะฒะตัะดะถะตะฝะฝั ะฟัะดะฟะธัั. ะะพะถะปะธะฒั ะฒะฐััะฐะฝัะธ:
trust_model_helper_collaborator=ะกะฟัะฒะฐะฒัะพั: ะฟัะดะฟะธัะธ ะดะพะฒััะธ ะฒัะด ัะฟัะฒะฐะฒัะพััะฒ
trust_model_helper_committer=ะฃัะฐัะฝะธะบ: ะดะพะฒััะตะฝั ะฟัะดะฟะธัะธ ััะฐััะฝะธะบัะฒ
trust_model_helper_collaborator_committer=ะกะฟัะฒะฐะฒัะพั+ะะพะผััะตั: ะดะพะฒัััั ะฟัะดะฟะธัะธ ะฒัะด ัะฟัะฒะฐะฒัะพััะฒ, ัะบั ะฒัะดะฟะพะฒัะดะฐััั ะบะพะผััะตัั
trust_model_helper_default=ะะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ: ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ััะฐะฝะดะฐััะฝั ะผะพะดะตะปั ะดะพะฒััะธ ะดะปั ัััั ัััะฐะฝะพะฒะบะธ
create_repo=ะกัะฒะพัะธัะธ ัะตะฟะพะทะธัะพััะน
-default_branch=ะะพะปะพะฒะฝะฐ ะณัะปะบะฐ
+default_branch=ะขะธะฟะพะฒะฐ ะณัะปะบะฐ
default_branch_helper=ะัะปะบะฐ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ั ะฑะฐะทะพะฒะพั ะณัะปะบะพั ะดะปั ะทะฐะฟะธััะฒ ะฝะฐ ะทะปะธััั ัะฐ ะบะพะผัััะฒ ะบะพะดั.
mirror_prune=ะัะธััะธัะธ
mirror_prune_desc=ะะธะดะฐะปะตะฝะฝั ะทะฐััะฐััะปะธั
ะฟะพัะธะปะฐะฝั ัะบั ะฒะธ ะฒัะดัะปัะดะบะพะฒัััะต
@@ -854,7 +1144,7 @@ forks=ะคะพัะบะธ
reactions_more=ะดะพะดะฐัะธ %d ะฑัะปััะต
unit_disabled=ะะดะผัะฝััััะฐัะพั ัะฐะนัั ะฒะธะผะบะฝัะฒ ัะตะน ัะพะทะดัะป ัะตะฟะพะทะธัะพััั.
language_other=ะะฝัั
-adopt_search=ะะฒะตะดััั ัะผ'ั ะบะพัะธัััะฒะฐัะฐ ะดะปั ะฟะพััะบั ะฝะตะฟัะธะนะฝััะฝะธั
ัะตะฟะพะทะธัะพัััะฒ... (ะทะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ัะพะฑ ะทะฝะฐะนัะธ ะฒัั)
+adopt_search=ะะฒะตะดััั ัะผ'ั ะบะพัะธัััะฒะฐั_ะบะธ ะดะปั ะฟะพััะบั ะฝะตะฟัะธะนะฝััะธั
ัะตะฟะพะทะธัะพัััะฒโฆ (ะทะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ัะพะฑ ะทะฝะฐะนัะธ ะฒัั)
adopt_preexisting_label=ะัะธะนะฝััั ัะฐะนะปะธ
adopt_preexisting=ะัะธะนะฝััะธ ะฒะถะต ััะฝัััั ัะฐะนะปะธ
adopt_preexisting_content=ะกัะฒะพัะธัะธ ัะตะฟะพะทะธัะพััะน ะท %s
@@ -883,12 +1173,12 @@ template.git_hooks=ะะตัะตั
ะพะฟะปัะฒะฐัั Git
template.webhooks=Webhook'ะธ
template.topics=ะขะตะผะธ
template.avatar=ะะฒะฐัะฐั
-template.issue_labels=ะััะบะธ ะทะฐะดะฐัั
+template.issue_labels=ะััะบะธ ะทะฐะดะฐั
template.one_item=ะกะปัะด ะพะฑัะฐัะธ ั
ะพัะฐ ะฑ ะพะดะธะฝ ะตะปะตะผะตะฝั ัะฐะฑะปะพะฝั
template.invalid=ะกะปัะด ะพะฑัะฐัะธ ัะฐะฑะปะพะฝะฝะธะน ัะตะฟะพะทะธัะพััะน
archive.issue.nocomment=ะฆะตะน ัะตะฟะพะทะธัะพััะน ะฐัั
ัะฒะพะฒะฐะฝะพ. ะะธ ะฝะต ะผะพะถะตัะต ะบะพะผะตะฝััะฒะฐัะธ ะทะฐะดะฐัั.
-archive.pull.nocomment=ะฆะต ะฐัั
ัะฒะฝะธะน ัะตะฟะพะทะธัะฐััะน. ะะธ ะฝะต ะผะพะถะตัะต ะบะพะผะตะฝััะฒะฐัะธ ะฟัะปะป-ัะตะบะฒะตััะธ.
+archive.pull.nocomment=ะฆะตะน ัะตะฟะพะทะธัะพััะน ะฐัั
ัะฒะพะฒะฐะฝะพ. ะะธ ะฝะต ะผะพะถะตัะต ะบะพะผะตะฝััะฒะฐัะธ ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั.
form.reach_limit_of_creation_1=ะะธ ะฒะถะต ะดะพััะณะปะธ ะปัะผััั ะฒ %d ัะตะฟะพะทะธัะพัััะฒ.
form.reach_limit_of_creation_n=ะะธ ะดะพััะณะปะธ ะผะฐะบัะธะผะฐะปัะฝะพั ะบัะปัะบะพััั %d ััะฒะพัะตะฝะธั
ัะตะฟะพะทะธัะพัััะฒ.
@@ -906,11 +1196,11 @@ migrate_items_milestones=ะัะฐะฟะธ
migrate_items_labels=ะััะบะธ
migrate_items_issues=ะะฐะดะฐัั
migrate_items_pullrequests=ะะฐะฟะธัะธ ะฝะฐ ะทะปะธััั
-migrate_items_merge_requests=ะะฐะฟะธัะธ ะฝะฐ ะทะปะธััั
+migrate_items_merge_requests=ะะฐะฟะธัะธ ะฝะฐ ะพะฑ'ัะดะฝะฐะฝะฝั
migrate_items_releases=ะ ะตะปัะทะธ
migrate_repo=ะะตัะตะฝะตััะธ ัะตะฟะพะทะธัะพััะน
migrate.clone_address=ะัะณัะฐััั / ะบะปะพะฝัะฒะฐัะธ ะท URL-ะฐะดัะตัะธ
-migrate.clone_address_desc=URL-ะฐะดัะตัะฐ HTTP(S) ะฐะฑะพ Git "clone" ััะฝัััะพะณะพ ัะตะฟะพะทะธัะพััั
+migrate.clone_address_desc=URL-ะฐะดัะตัะฐ HTTP(S) ะฐะฑะพ Git ยซcloneยป ััะฝัััะพะณะพ ัะตะฟะพะทะธัะพััั
migrate.clone_local_path=ะฐะฑะพ ัะปัั
ะดะพ ะปะพะบะฐะปัะฝะพะณะพ ัะตัะฒะตัั
migrate.permission_denied=ะะฐะผ ะฝะต ะดะพะทะฒะพะปะตะฝะพ ัะผะฟะพัััะฒะฐัะธ ะปะพะบะฐะปัะฝั ัะตะฟะพะทะธัะพััั.
migrate.permission_denied_blocked=ะะธ ะฝะต ะผะพะถะตัะต ัะผะฟะพัััะฒะฐัะธ ะท ะทะฐะฑะพัะพะฝะตะฝะธั
ะฒัะทะปัะฒ, ะฑัะดั ะปะฐัะบะฐ, ะฟะพะฟัะพัััั ะฐะดะผัะฝััััะฐัะพัะฐ ะฟะตัะตะฒััะธัะธ ะฝะฐะปะฐัััะฒะฐะฝะฝั ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS.
@@ -920,12 +1210,12 @@ migrate.migrate_items_options=ะะปั ะฟะตัะตะฝะตัะตะฝะฝั ะดะพะดะฐัะบะพะฒะธั
migrated_from=ะะตัะตะฝะตัะตะฝะพ ะท %[2]s
migrated_from_fake=ะะตัะตะฝะตัะตะฝะพ ะท %[1]s
migrate.migrate=ะัะณัะฐััั ะท %s
-migrate.migrating=ะัะณัะฐััั ัะท %s ...
+migrate.migrating=ะัะณัะฐััั ะท %s โฆ
migrate.migrating_failed=ะัะณัะฐััั ัะท %s ะฝะต ะฒะดะฐะปะฐัั.
migrate.migrating_failed_no_addr=ะัะณัะฐััั ะฝะต ะฒะดะฐะปะฐัั.
migrate.git.description=ะะตัะตะฝะตัะตะฝะฝั ะปะธัะต ัะตะฟะพะทะธัะพััั ะท ะฑัะดั-ัะบะพั ัะปัะถะฑะธ Git.
migrate.gitlab.description=ะะตัะตะฝะตััะธ ะดะฐะฝั ะท gitlab.com ัะฐ ัะฝัะธั
ะตะบะทะตะผะฟะปัััะฒ GitLab.
-migrate.gitea.description=ะะตัะตะฝะตััะธ ะดะฐะฝั ะท gitea.com ัะฐ ัะฝัะธั
ะตะบะทะตะผะฟะปัััะฒ Gitea/Forgejo.
+migrate.gitea.description=ะะตัะตะฝะตััะธ ะดะฐะฝั ะท gitea.com ัะฐ ัะฝัะธั
ะตะบะทะตะผะฟะปัััะฒ Gitea.
migrate.gogs.description=ะะตัะตะฝะตััะธ ะดะฐะฝั ะท notabug.org ัะฐ ัะฝัะธั
ะตะบะทะตะผะฟะปัััะฒ Gogs.
migrate.onedev.description=ะะตัะตะฝะตััะธ ะดะฐะฝั ะท code.onedev.io ัะฐ ัะฝัะธั
ะตะบะทะตะผะฟะปัััะฒ OneDev.
migrate.codebase.description=ะะตัะตะฝะตััะธ ะดะฐะฝั ะท codebasehq.com.
@@ -992,9 +1282,10 @@ file_permalink=ะะพัััะนะฝะต ะฟะพัะธะปะฐะฝะฝั
file_too_large=ะฆะตะน ัะฐะนะป ะทะฐะฒะตะปะธะบะธะน ัะพะฑ ะฑััะธ ะฟะพะบะฐะทะฐะฝะธะผ.
file_copy_permalink=ะะพะฟััะฒะฐัะธ ะฟะพัััะนะฝะต ะฟะพัะธะปะฐะฝะฝั
-video_not_supported_in_browser=ะะฐั ะฑัะฐัะทะตั ะฝะต ะฟัะดััะธะผัั ัะตะณ 'video' HTML5.
-audio_not_supported_in_browser=ะะฐั ะฑัะฐัะทะตั ะฝะต ะฟัะดััะธะผัั ัะตะณ HTML5 'audio'.
+video_not_supported_in_browser=ะะฐั ะฑัะฐัะทะตั ะฝะต ะฟัะดััะธะผัั ัะตะณ HTML5 ยซvideoยป.
+audio_not_supported_in_browser=ะะฐั ะฑัะฐัะทะตั ะฝะต ะฟัะดััะธะผัั ัะตะณ HTML5 ยซaudioยป.
stored_lfs=ะะฑะตัะตะถะตะฝะพ ะท Git LFS
+stored_annex=ะะฑะตัะตะถะตะฝะพ ะท Git Annex
symbolic_link=ะกะธะผะฒะพะปััะฝะต ะฟะพัะธะปะฐะฝะฝั
commit_graph=ะัะฐััะบ ะบะพะผัััะฒ
commit_graph.select=ะะธะฑะตัััั ะณัะปะบะธ
@@ -1009,9 +1300,10 @@ lines=ััะดะบะธ
editor.new_file=ะะพะฒะธะน ัะฐะนะป
editor.upload_file=ะะฐะฒะฐะฝัะฐะถะธัะธ ัะฐะนะป
-editor.edit_file=ะ ะตะดะฐะณัะฒะฐะฝะฝั ัะฐะนะปั
+editor.edit_file=ะ ะตะดะฐะณัะฒะฐัะธ ัะฐะนะป
editor.preview_changes=ะะพะฟะตัะตะดะฝัะน ะฟะตัะตะณะปัะด ะทะผัะฝ
editor.cannot_edit_lfs_files=ะคะฐะนะปะธ LFS ะฝะต ะผะพะถะฝะฐ ัะตะดะฐะณัะฒะฐัะธ ะฒ ะฒะตะฑ-ัะฝัะตััะตะนัั.
+editor.cannot_edit_annex_files=ะคะฐะนะปะธ Annex ะฝะต ะผะพะถะฝะฐ ัะตะดะฐะณัะฒะฐัะธ ะฒ ะฒะตะฑ-ัะฝัะตััะตะนัั.
editor.cannot_edit_non_text_files=ะัะฝะฐัะฝั ัะฐะนะปะธ ะฝะต ะผะพะถะปะธะฒะพ ัะตะดะฐะณัะฒะฐัะธ ั ะฒะตะฑ-ัะฝัะตััะตะนัั.
editor.edit_this_file=ะ ะตะดะฐะณัะฒะฐัะธ ัะฐะนะป
editor.this_file_locked=ะคะฐะนะป ะทะฐะฑะปะพะบะพะฒะฐะฝะพ
@@ -1020,27 +1312,27 @@ editor.fork_before_edit=ะะตะพะฑั
ัะดะฝะพ ะทัะพะฑะธัะธ ัะพัะบ ััะพะณะพ ั
editor.delete_this_file=ะะธะดะฐะปะธัะธ ัะฐะนะป
editor.must_have_write_access=ะะธ ะฟะพะฒะธะฝะฝั ะผะฐัะธ ะดะพัััะฟ ะฝะฐ ะทะฐะฟะธั ัะพะฑ ะทะฐะฟัะพะฟะพะฝัะฒะฐัะธ ะทะผัะฝะธ ะดะพ ััะพะณะพ ัะฐะนะปั.
editor.name_your_file=ะะฐะนัะต ะฝะฐะทะฒั ัะฐะนะปัโฆ
-editor.filename_help=ะฉะพะฑ ะดะพะดะฐัะธ ะบะฐัะฐะปะพะณ, ะฝะฐะฑะตัััั ะนะพะณะพ ะฝะฐะทะฒั, ะฐ ะฟะพััะผ - ะบะพัั ัะธัะบั ('/'). ะฉะพะฑ ะฒะธะดะฐะปะธัะธ ะบะฐัะฐะปะพะณ, ะฟะตัะตะนะดััั ะดะพ ะฟะพัะฐัะบั ะฟะพะปั ั ะฝะฐัะธัะฝััั backspace.
+editor.filename_help=ะฉะพะฑ ะดะพะดะฐัะธ ะบะฐัะฐะปะพะณ, ะฝะฐะฑะตัััั ะนะพะณะพ ะฝะฐะทะฒั, ะฐ ะฟะพััะผ โ ะบะพัั ัะธัะบั ยซ/ยป. ะฉะพะฑ ะฒะธะดะฐะปะธัะธ ะบะฐัะฐะปะพะณ, ะฟะตัะตะนะดััั ะดะพ ะฟะพัะฐัะบั ะฟะพะปั ั ะฝะฐัะธัะฝััั Backspace.
editor.or=ะฐะฑะพ
editor.cancel_lower=ะกะบะฐััะฒะฐัะธ
editor.commit_signed_changes=ะะฝะตััะธ ะฟัะดะฟะธัะฐะฝั ะทะผัะฝะธ
editor.commit_changes=ะะฐะบะพะผััะธัะธ ะทะผัะฝะธ
-editor.add_tmpl=ะะพะดะฐัะธ ''
+editor.add_tmpl=ะะพะดะฐัะธ ยซ<%s>ยป
editor.commit_message_desc=ะะพะดะฐัะธ ะฝะตะพะฑะพะฒ'ัะทะบะพะฒะธะน ัะพะทัะธัะตะฝะธะน ะพะฟะธัโฆ
editor.signoff_desc=ะะพะดะฐัะธ ะฟะพะฒัะดะพะผะปะตะฝะฝั ะฒ ะถััะฝะฐะปั ะบะพะผัััะฒ ััะดะพะบ Signed-off-by ะฒัะด ัะฒะพะณะพ ัะผะตะฝั.
-editor.commit_directly_to_this_branch=ะัะพะฑััั ะบะพะผัั ะฟััะผะพ ะฒ ะณัะปะบั %s .
+editor.commit_directly_to_this_branch=ะัะพะฑััั ะบะพะผัั ะฟััะผะพ ะฒ ะณัะปะบั %[1]s .
editor.create_new_branch=ะกัะฒะพัะธัะธ ะฝะพะฒั ะณัะปะบั ะดะปั ััะพะณะพ ะบะพะผััั ัะฐ ะฒัะดะบัะธัะธ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั.
editor.create_new_branch_np=ะกัะฒะพัะธัะธ ะฝะพะฒั ะณัะปะบั ะดะปั ััะพะณะพ ะบะพะผััั.
editor.propose_file_change=ะะฐะฟัะพะฟะพะฝัะฒะฐัะธ ะทะผัะฝั ัะฐะนะปั
editor.new_branch_name_desc=ะะผ'ั ะฝะพะฒะพั ะณัะปะบะธโฆ
editor.cancel=ะัะดะผัะฝะธัะธ
editor.filename_cannot_be_empty=ะะผ'ั ัะฐะนะปั ะฝะต ะผะพะถะต ะฑััะธ ะฟะพัะพะถะฝัะผ.
-editor.file_changed_while_editing=ะะผััั ัะฐะนะปั ะทะผัะฝะธะฒัั ะท ะผะพะผะตะฝัั ะฟะพัะฐัะบั ัะตะดะฐะณัะฒะฐะฝะฝั. ะะฐัะธัะฝััั ััั , ัะพะฑ ะฟะตัะตะณะปัะฝััะธ ัะพ ะฑัะปะพ ะทะผัะฝะตะฝะพ, ะฐะฑะพ ะทะฐะบะพะผััััะต ะทะผัะฝะธ ัะต ัะฐะท , ัะพะฑ ะฟะตัะตะฟะธัะฐัะธ ัั
.
+editor.file_changed_while_editing=ะะผััั ัะฐะนะปั ะทะผัะฝะธะฒัั ะฒัะดัะพะดั, ัะบ ะฒะธ ะนะพะณะพ ะฒัะดะบัะธะปะธ. ะะฐัะธัะฝััั ััั , ัะพะฑ ะฟะตัะตะณะปัะฝััะธ, ัะพ ะฑัะปะพ ะทะผัะฝะตะฝะพ, ะฐะฑะพ ะทะฐะบะพะผััััะต ะทะผัะฝะธ ัะต ัะฐะท , ัะพะฑ ะฟะตัะตะฟะธัะฐัะธ ัั
.
editor.commit_empty_file_header=ะะฐะบะพะผััะธัะธ ะฟะพัะพะถะฝัะน ัะฐะนะป
editor.commit_empty_file_text=ะคะฐะนะป, ะฒ ะบะพะผะผััั ะฟะพัะพะถะฝัะน. ะัะพะดะพะฒะถะธัะธ?
editor.no_changes_to_show=ะะตะผะฐ ะทะผัะฝ ะดะปั ะฟะพะบะฐะทั.
editor.fail_to_update_file_summary=ะะพะผะธะปะบะฐ:
-editor.push_rejected_summary=ะะพะฒะฝะต ะฟะพะฒัะดะพะผะปะตะฝะฝั ะฟัะพ ะฒัะดะผะพะฒั:
+editor.push_rejected_summary=ะะพะฒะฝะต ะฟะพะฒัะดะพะผะปะตะฝะฝั ะฟัะพ ะฒัะดั
ะธะปะตะฝะฝั:
editor.add_subdir=ะะพะดะฐัะธ ะบะฐัะฐะปะพะณโฆ
editor.no_commit_to_branch=ะะต ะฒะดะฐะปะพัั ะฒะฝะตััะธ ะบะพะผัั ะฑะตะทะฟะพัะตัะตะดะฝัะพ ะดะพ ะณัะปะบะธ, ัะพะผั ัะพ:
editor.user_no_push_to_branch=ะะพัะธัััะฒะฐั ะฝะต ะผะพะถะต ะทะดัะนัะฝะธัะธ ะฟัั ะดะพ ะณัะปะบะธ
@@ -1051,7 +1343,7 @@ commits.commits=ะะพะผััะธ
commits.nothing_to_compare=ะฆั ะณัะปะบะธ ะพะดะฝะฐะบะพะฒั.
commits.search=ะะฝะฐะนัะธ ะบะพะผััโฆ
commits.find=ะะพััะบ
-commits.search_all=ะฃัั ะณัะปะบะธ
+commits.search_all=ะฃ ะฒััั
ะณัะปะบะฐั
commits.author=ะะฒัะพั
commits.message=ะะพะฒัะดะพะผะปะตะฝะฝั
commits.date=ะะฐัะฐ
@@ -1060,13 +1352,13 @@ commits.newer=ะะพะฒััะต
commits.signed_by=ะัะดะฟะธัะฐะฝะพ
commits.signed_by_untrusted_user=ะัะดะฟะธัะฐะฝะธะน ะฝะตะดะพะฒััะตะฝะธะผ ะบะพัะธัััะฒะฐัะตะผ
commits.signed_by_untrusted_user_unmatched=ะัะดะฟะธัะฐะฝะธะน ะฝะตะดะพะฒััะตะฝะธะผ ะบะพัะธัััะฒะฐัะตะผ, ัะบะธะน ะฝะต ะฒัะดะฟะพะฒัะดะฐั ะบะพะผััะตัั
-commits.gpg_key_id=ะะดะตะฝัะธััะบะฐัะพั GPG ะบะปััะฐ
+commits.gpg_key_id=ะะดะตะฝัะธััะบะฐัะพั ะบะปััะฐ GPG
commitstatus.error=ะะพะผะธะปะบะฐ
commitstatus.pending=ะััะบัะฒะฐะฝะฝั
-ext_issues=ะะพัััะฟ ะดะพ ะทะพะฒะฝััะฝัั
ะทะฐะดะฐั
+ext_issues=ะะพะฒะฝััะฝั ะทะฐะดะฐัั
ext_issues.desc=ะะพัะธะปะฐะฝะฝั ะฝะฐ ะทะพะฒะฝััะฝั ัะธััะตะผั ะฒัะดััะตะถะตะฝะฝั ะทะฐะดะฐั.
projects=ะัะพัะบัะธ
@@ -1080,14 +1372,14 @@ projects.new_subheader=ะะพะพัะดะธะฝัะนัะต, ะฒัะดััะตะถัะนัะต ัะฐ ะพะฝ
projects.deletion=ะะธะดะฐะปะธัะธ ะฟัะพัะบั
projects.deletion_desc=ะะธะดะฐะปะตะฝะฝั ะฟัะพัะบัั ะฒะธะดะฐะปัั ะนะพะณะพ ะท ัััั
ะฟะพะฒ'ัะทะฐะฝะธั
ะทะฐะดะฐั. ะัะพะดะพะฒะถะธัะธ?
projects.deletion_success=ะัะพัะบั ะฒะธะดะฐะปะตะฝะพ.
-projects.edit=ะ ะตะดะฐะณัะฒะฐัะธ ะฟัะพัะบัะธ
+projects.edit=ะ ะตะดะฐะณัะฒะฐัะธ ะฟัะพัะบั
projects.edit_subheader=ะัะพัะบัะธ ะพัะณะฐะฝัะทะพะฒัััั ะทะฐะดะฐัั ัะฐ ะฒัะดััะตะถัััั ะฟัะพะณัะตั.
projects.modify=ะะฝะพะฒะธัะธ ะฟัะพัะบั
-projects.type.none=ะัะดัััะฝัะน
+projects.type.none=ะะตะผะฐั
projects.type.basic_kanban=ะกะฟัะพัะตะฝะธะน ะบะฐะฝะฑะฐะฝ
projects.type.bug_triage=ะกะพัััะฒะฐะฝะฝั ะฟะพะผะธะปะพะบ
-projects.template.desc=ะจะฐะฑะปะพะฝ ะฟัะพัะบัั
-projects.template.desc_helper=ะะฑะตัััั ัะฐะฑะปะพะฝ ะฟัะพัะบัั, ะฐะฑะธ ะฟะพัะฐัะธ
+projects.template.desc=ะจะฐะฑะปะพะฝ
+projects.template.desc_helper=ะะธะฑะตัััั ัะฐะฑะปะพะฝ ะฟัะพัะบัั, ะฐะฑะธ ะฟะพัะฐัะธ
projects.type.uncategorized=ะะตะท ะบะฐัะตะณะพััั
projects.column.edit_title=ะะฐะทะฒะฐ
projects.column.new_title=ะะฐะทะฒะฐ
@@ -1104,7 +1396,7 @@ issues.filter_reviewers=ะคัะปััั ัะตัะตะฝะทะตะฝััะฒ
issues.new=ะะพะฒะฐ ะทะฐะดะฐัะฐ
issues.new.title_empty=ะะฐะณะพะปะพะฒะพะบ ะฝะต ะผะพะถะต ะฑััะธ ะฟัััะธะผ
issues.new.labels=ะััะบะธ
-issues.new.no_label=ะะตะท ะผััะบะธ
+issues.new.no_label=ะะตะท ะผััะพะบ
issues.new.clear_labels=ะัะธััะธัะธ ะผััะบะธ
issues.new.projects=ะัะพัะบัะธ
issues.new.clear_projects=ะกะบะธะฝััะธ ะฟัะพัะบัะธ
@@ -1119,7 +1411,7 @@ issues.new.open_milestone=ะะบัะธะฒะฝั ะตัะฐะฟะธ
issues.new.closed_milestone=ะะฐะบัะธัั ะตัะฐะฟะธ
issues.new.assignees=ะะธะบะพะฝะฐะฒัั
issues.new.clear_assignees=ะัะธะฑัะฐัะธ ะฒะธะบะพะฝะฐะฒััะฒ
-issues.new.no_assignees=ะะตะผะฐั ะฒะธะบะพะฝะฐะฒัั
+issues.new.no_assignees=ะะตะผะฐั ะฒะธะบะพะฝะฐะฒััะฒ
issues.new.no_reviewers=ะะตะผะฐั ัะตัะตะฝะทะตะฝััะฒ
issues.choose.get_started=ะะพัะฐัะพะบ ัะพะฑะพัะธ
issues.choose.open_external_link=ะัะดะบัะธัะธ
@@ -1132,7 +1424,7 @@ issues.new_label_placeholder=ะะฐะทะฒะฐ ะผััะบะธ
issues.new_label_desc_placeholder=ะะฟะธั
issues.create_label=ะกัะฒะพัะธัะธ ะผััะบั
issues.label_templates.title=ะะฐะฒะฐะฝัะฐะถะธัะธ ะฒะธะทะฝะฐัะตะฝะธะน ะฝะฐะฑัั ะผััะพะบ
-issues.label_templates.info=ะฉะต ะฝะตะผะฐั ะผััะพะบ. ะะฐัะธัะฝััั 'ะะพะฒะฐ ะผััะบะฐ' ะฐะฑะพ ะฒะธะบะพัะธััะพะฒัะนัะต ะฟะพะฟะตัะตะดะฝัะพ ะฒะธะทะฝะฐัะตะฝะธะน ะฝะฐะฑัั ะผััะพะบ:
+issues.label_templates.info=ะฉะต ะฝะตะผะฐั ะผััะพะบ. ะะฐัะธัะฝััั ยซะะพะฒะฐ ะผััะบะฐยป ะฐะฑะพ ะฒะธะบะพัะธััะพะฒัะนัะต ะฟะพะฟะตัะตะดะฝัะพ ะฒะธะทะฝะฐัะตะฝะธะน ะฝะฐะฑัั ะผััะพะบ:
issues.label_templates.helper=ะะฑะตัััั ะฝะฐะฑัั ะผััะพะบ
issues.label_templates.use=ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะฝะฐะฑัั ะผััะพะบ
issues.add_label=ะดะพะดะฐะฝะพ %s ะท ะผััะบะพั %s
@@ -1204,7 +1496,7 @@ issues.commented_at=`ะฟัะพะบะพะผะตะฝััะฒะฐะฒ(ะปะฐ) %s `
issues.delete_comment_confirm=ะะธ ะฒะฟะตะฒะฝะตะฝั, ัะพ ั
ะพัะตัะต ะฒะธะดะฐะปะธัะธ ัะตะน ะบะพะผะตะฝัะฐั?
issues.context.copy_link=ะกะบะพะฟััะฒะฐัะธ ะฟะพัะธะปะฐะฝะฝั
issues.context.quote_reply=ะฆะธััะฒะฐัะธ ะฒัะดะฟะพะฒัะดั
-issues.context.reference_issue=ะะพัะธะปะฐะฝะฝั ะฒ ะฝะพะฒัะน ะทะฐะดะฐัั
+issues.context.reference_issue=ะะพัะปะฐัะธัั ะฒ ะฝะพะฒัะน ะทะฐะดะฐัั
issues.context.edit=ะ ะตะดะฐะณัะฒะฐัะธ
issues.context.delete=ะะธะดะฐะปะธัะธ
issues.close_comment_issue=ะัะพะบะพะผะตะฝััะฒะฐัะธ ั ะทะฐะบัะธัะธ
@@ -1214,7 +1506,7 @@ issues.create_comment=ะะพะผะตะฝัะฐั
issues.closed_at=`ะทะฐะบัะธะฒ ัั ะทะฐะดะฐัั %[2]s `
issues.reopened_at=`ะฟะพะฒัะพัะฝะพ ะฒัะดะบัะธะฒ ัั ะทะฐะดะฐัั %[2]s `
issues.commit_ref_at=`ะทะณะฐะดะฐะฝะพ ัั ะทะฐะดะฐัั ะฒ ะบะพะผััั %[2]s `
-issues.ref_issue_from=`ะฟะพัะธะปะฐะฝะฝั ะฝะฐ ัั ะทะฐะดะฐัั %[4]s %[2]s `
+issues.ref_issue_from=`ะฟะพัะธะปะฐััััั ะฝะฐ ัั ะทะฐะดะฐัั %[4]s %[2]s `
issues.ref_pull_from=`ะฟะพัะปะฐะฒัั ะฝะฐ ัะตะน ะทะฐะฟะธั ะทะปะธััั %[4]s %[2]s `
issues.ref_closing_from=`ะทะณะฐะดะฐะฒ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั %[4]s, ัะบั ะทะฐะบัะธััั ัั ะทะฐะดะฐัั %[2]s `
issues.ref_reopening_from=`ะทะณะฐะดะฐะฒ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั %[4]s, ัะบั ะฟะพะฒัะพัะฝะพ ะฒัะดะบัะธััั ัั ะทะฐะดะฐัั %[2]s `
@@ -1227,7 +1519,7 @@ issues.re_request_review=ะะพะฒัะพัะฝะพ ะฟะพะฟัะพัะธัะธ ัะตัะตะฝะทัั
issues.is_stale=ะ ัะฐัั ะพััะฐะฝะฝัะพั ะฟะตัะตะฒััะบะธ ะฒ ัะตะน PR ะฑัะปะพ ะฒะฝะตัะตะฝะพ ะดะตัะบั ะทะผัะฝะธ
issues.remove_request_review=ะะธะดะฐะปะธัะธ ะทะฐะฟะธั ัะตัะตะฝะทัะฒะฐะฝะฝั
issues.remove_request_review_block=ะะตะผะพะถะปะธะฒะพ ะฒะธะดะฐะปะธัะธ ะทะฐะฟะธั ัะตัะตะฝะทัะฒะฐะฝะฝั
-issues.dismiss_review=ะัะดั
ะธะปะธัะธ ัะตัะตะฝะทiั
+issues.dismiss_review=ะัะดั
ะธะปะธัะธ ะฒัะดะณัะบ
issues.dismiss_review_warning=ะะธ ะฒะฟะตะฒะฝะตะฝั, ัะพ ั
ะพัะตัะต ะฒัะดั
ะธะปะธัะธ ัะตะน ะฒัะดะณัะบ?
issues.sign_in_require_desc=ะัะดะฟะธัััััั ัะพะฑ ะฟัะธัะดะฝะฐัะธัั ะดะพ ะพะฑะณะพะฒะพัะตะฝะฝั.
issues.edit=ะ ะตะดะฐะณัะฒะฐัะธ
@@ -1297,19 +1589,19 @@ issues.due_date=ะะฐัะฐ ะทะฐะฒะตััะตะฝะฝั
issues.invalid_due_date_format=ะะฐัะฐ ะทะฐะบัะฝัะตะฝะฝั ะผะฐั ะฑััะธ ะฒ ัะพัะผะฐัั 'ััั-ะผะผ-ะดะด'.
issues.error_modifying_due_date=ะะต ะฒะดะฐะปะพัั ะทะผัะฝะธัะธ ะดะฐัั ะทะฐะฒะตััะตะฝะฝั.
issues.error_removing_due_date=ะะต ะฒะดะฐะปะพัั ะฒะธะดะฐะปะธัะธ ะดะฐัั ะทะฐะฒะตััะตะฝะฝั.
-issues.push_commit_1=ะดะพะดะฐะฒ %d ะบะพะผัั %s
-issues.push_commits_n=ะดะพะดะฐะฒ %d ะบะพะผััะธ(-ัะฒ) %s
-issues.force_push_codes=`ะฟัะธะผััะพะฒะพ ะทะฐะปะธัะพ %[1]s ะท %[2]s
ะดะพ %[4]s
%[6]s`
+issues.push_commit_1=ะดะพะดะฐั %d ะบะพะผัั %s
+issues.push_commits_n=ะดะพะดะฐั %d ะบะพะผััะธ(-ัะฒ) %s
+issues.force_push_codes=`ะฟัะธะผััะพะฒะพ ะทะฐะปะธัะพ %[1]s ะท %[2]s
ะดะพ %[4]s
%[6]s`
issues.force_push_compare=ะะพััะฒะฝััะธ
issues.due_date_form=ัััั-ะผะผ-ะดะด
issues.due_date_form_add=ะะพะดะฐัะธ ะดะฐัั ะทะฐะฒะตััะตะฝะฝั
issues.due_date_form_edit=ะ ะตะดะฐะณัะฒะฐัะธ
issues.due_date_form_remove=ะะธะดะฐะปะธัะธ
-issues.due_date_not_set=ะขะตัะผัะฝ ะฒะธะบะพะฝะฐะฝะฝั ะฝะต ะฒััะฐะฝะพะฒะปะตะฝะธะน.
+issues.due_date_not_set=ะขะตัะผัะฝ ะฒะธะบะพะฝะฐะฝะฝั ะฝะต ะฒััะฐะฝะพะฒะปะตะฝะพ.
issues.due_date_added=ะดะพะดะฐะฒ(ะปะฐ) ะดะฐัั ะทะฐะฒะตััะตะฝะฝั %s %s
issues.due_date_remove=ะฒะธะดะฐะปะธะฒ(ะปะฐ) ะดะฐัั ะทะฐะฒะตััะตะฝะฝั %s %s
issues.due_date_overdue=ะัะพัััะพัะตะฝะพ
-issues.due_date_invalid=ะขะตัะผัะฝ ะดัั ะฝะต ะดัะนัะฝะธะน ะฐะฑะพ ะทะฝะฐั
ะพะดะธัััั ะทะฐ ะผะตะถะฐะผะธ ะดะพะฟัััะธะผะพะณะพ ะดัะฐะฟะฐะทะพะฝั. ะัะดั ะปะฐัะบะฐ ะฒะธะบะพัะธััะพะฒัะนัะต ัะพัะผะฐั 'yyyy-mm-dd'.
+issues.due_date_invalid=ะขะตัะผัะฝ ะดัั ะฝะตะดัะนัะฝะธะน ะฐะฑะพ ะทะฝะฐั
ะพะดะธัััั ะทะฐ ะผะตะถะฐะผะธ ะดะพะฟัััะธะผะพะณะพ ะดัะฐะฟะฐะทะพะฝั. ะัะดั ะปะฐัะบะฐ, ะฒะธะบะพัะธััะพะฒัะนัะต ัะพัะผะฐั ยซัััั-ะผะผ-ะดะดยป.
issues.dependency.title=ะะฐะปะตะถะฝะพััั
issues.dependency.add=ะะพะดะฐัะธ ะทะฐะปะตะถะฝััััโฆ
issues.dependency.cancel=ะัะดะผัะฝะธัะธ
@@ -1385,8 +1677,8 @@ pulls.nothing_to_compare=ะฆั ะณัะปะบะธ ะพะดะฝะฐะบะพะฒั. ะะตะผะฐั ะฝะตะพะฑั
pulls.nothing_to_compare_and_allow_empty_pr=ะะดะธะฝะฐะบะพะฒั ะณัะปะบะธ. ะฆะตะน PR ะฑัะดะต ะฟะพัะพะถะฝัะผ.
pulls.has_pull_request=`ะะฐะฟะธั ะทะปะธััั ะดะปั ัะธั
ะณัะปะพะบ ะฒะถะต ััะฝัั: %[2]s#%[3]d `
pulls.create=ะกัะฒะพัะธัะธ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั
-pulls.title_desc_few=ั
ะพัะต ะทะปะธัะธ %[1]d ะบะพะผัััะฒ ะท %[2]s
ะฒ %[3]s
-pulls.merged_title_desc_few=ะทะปะธัะพ %[1]d ะบะพะผัััะฒ ะท %[2]s
ะดะพ %[3]s
%[4]s
+pulls.title_desc_few=ั
ะพัะต ะพะฑ'ัะดะฝะฐัะธ %[1]d ะบะพะผัััะฒ ะท %[2]s
ะฒ %[3]s
+pulls.merged_title_desc_few=ะพะฑ'ัะดะฝะฐะฒ %[1]d ะบะพะผัััะฒ ะท %[2]s
ะฒ %[3]s
%[4]s
pulls.change_target_branch_at=`ะทะผัะฝะตะฝะฐ ััะปัะพะฒะฐ ะณัะปะบะฐ ะท %s ะฝะฐ %s %s`
pulls.tab_conversation=ะะฑะณะพะฒะพัะตะฝะฝั
pulls.tab_commits=ะะพะผััะธ
@@ -1403,7 +1695,7 @@ pulls.add_prefix=ะะพะดะฐัะธ ะฟัะตััะบั %s
pulls.remove_prefix=ะะธะดะฐะปะธัะธ ะฟัะตััะบั %s
pulls.data_broken=ะะผััั ััะพะณะพ ะทะฐะฟะธัั ะฑัะปะพ ะฟะพัััะตะฝะพ ะฒะฝะฐัะปัะดะพะบ ะฒะธะดะฐะปะตะฝะฝั ัะฝัะพัะผะฐััั ะคะพัะบะพะผ. ะฆะตะน ะทะฐะฟะธั ััะณะฝะตัััั ัะตัะตะท ะฒัะดัััะฝัััั ัะฝัะพัะผะฐััั ะฟัะพ ะฒะธะปััะตะฝะฝั.
pulls.files_conflicted=ะฆะตะน ะทะฐะฟะธั ะผะฐั ะทะผัะฝะธ, ัะพ ะบะพะฝัะปัะบััััั ะท ััะปัะพะฒะพั ะณัะปะบะพั.
-pulls.is_checking=ะขัะธะฒะฐั ะฟะตัะตะฒััะบะฐ ะบะพะฝัะปัะบััะฒ, ะฑัะดั ะปะฐัะบะฐ ะพะฑะฝะพะฒััั ััะพััะฝะบั ะดะตัะพ ะฟัะทะฝััะต.
+pulls.is_checking=ะขัะธะฒะฐั ะฟะตัะตะฒััะบะฐ ะบะพะฝัะปัะบััะฒ. ะะฝะพะฒััั ััะพััะฝะบั ะดะตัะพ ะฟัะทะฝััะต.
pulls.required_status_check_failed=ะะตัะบั ะฝะตะพะฑั
ัะดะฝั ะฟะตัะตะฒััะบะธ ะฒะธะบะพะฝะฐะฝั ะท ะฟะพะผะธะปะบะฐะผะธ.
pulls.required_status_check_missing=ะะตะบัะปัะบะฐ ะท ะฝะตะพะฑั
ัะดะฝะธั
ะฟะตัะตะฒััะพะบ ะฒัะดัััะฝั.
pulls.required_status_check_administrator=ะฏะบ ะฐะดะผัะฝััััะฐัะพั ะฒะธ ะฒัะต ะพะดะฝะพ ะผะพะถะตัะต ะพะฑ'ัะดะฝะฐัะธ ัะตะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั.
@@ -1418,7 +1710,7 @@ pulls.reject_count_1=%d ะทะฐะฟะธั ะฝะฐ ะทะผัะฝั
pulls.reject_count_n=%d ะทะฐะฟะธัะธ ะฝะฐ ะทะผัะฝั
pulls.waiting_count_1=ะพััะบัััััั %d ัะตัะตะฝะทัั
pulls.waiting_count_n=ะพััะบัััััั %d ัะตัะตะฝะทัั(ะน)
-pulls.wrong_commit_id=id ะบะพะผััั ะฟะพะฒะธะฝะตะฝ ะฑััะธ id ะบะพะผััั ะฒ ััะปัะพะฒัะน ะณัะปัั
+pulls.wrong_commit_id=ID ะบะพะผััะฐ ะฟะพะฒะธะฝะตะฝ ะฑััะธ ID ะบะพะผััะฐ ะฒ ััะปัะพะฒัะน ะณัะปัั
pulls.no_merge_desc=ะฆะตะน ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั ะฝะตะผะพะถะปะธะฒะพ ะทะปะธัะธ, ะพัะบัะปัะบะธ ะฒัั ะฟะฐัะฐะผะตััะธ ะพะฑ'ัะดะฝะฐะฝะฝั ัะตะฟะพะทะธัะพััั ะฒะธะผะบะฝะตะฝะพ.
pulls.no_merge_helper=ะฃะฒัะผะบะฝััั ะฟะฐัะฐะผะตััะธ ะทะปะธััั ะฒ ะฝะฐะปะฐัััะฒะฐะฝะฝัั
ัะตะฟะพะทะธัะพััั ะฐะฑะพ ะทะปะธะนัะต ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั ะฒัััะฝั.
@@ -1434,13 +1726,13 @@ pulls.merge_commit_id=ID ะบะพะผััั ะทะปะธััั
pulls.require_signed_wont_sign=ะัะปะบะฐ ะฒะธะผะฐะณะฐั ะฟัะดะฟะธัะฐะฝะธั
ะบะพะผัััะฒ, ะฐะปะต ัะต ะทะปะธััั ะฝะต ะฑัะดะต ะฟัะดะฟะธัะฐะฝะพ
pulls.invalid_merge_option=ะฆะตะน ะฟะฐัะฐะผะตัั ะทะปะธััั ะฝะต ะผะพะถะฝะฐ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะดะปั ััะพะณะพ Pull Request'ะฐ.
-pulls.merge_conflict=ะะปะธััั ะฝะต ะฒะดะฐะปะพัั: ะัะฒ ะบะพะฝัะปัะบั ะฟัะธ ะทะปะธััั. ะัะดะบะฐะทะบะฐ: ัะฟัะพะฑัะนัะต ัะฝัั ัััะฐัะตะณัั
-pulls.merge_conflict_summary=ะะพะผะธะปะบะฐ
-pulls.rebase_conflict=ะะปะธััั ะฝะต ะฒะดะฐะปะพัั: ะฒัะดะฑัะฒัั ะบะพะฝัะปัะบั ะฟัะด ัะฐั ะทะปะธััั: %[1]s. ะัะดะบะฐะทะบะฐ: ัะฟัะพะฑัะนัะต ัะฝัั ัััะฐัะตะณัั
-pulls.rebase_conflict_summary=ะะพะผะธะปะบะฐ
-pulls.unrelated_histories=ะะพะผะธะปะบะฐ ะทะปะธััั: head ัะฐ base ะทะปะธััั ะฝะต ะผะฐััั ัะฟัะปัะฝะพั ัััะพััั. ะัะดะบะฐะทะบะฐ: ัะฟัะพะฑัะนัะต ัะฝัั ัััะฐัะตะณัั
-pulls.merge_out_of_date=ะะพะผะธะปะบะฐ ะทะปะธััั: base ะฑัะปะพ ะพะฝะพะฒะปะตะฝะพ, ะฟะพะบะธ ะฒัะดะฑัะฒะฐะปะพัั ะทะปะธััั. ะัะดะบะฐะทะบะฐ: ัะฟัะพะฑัะนัะต ะทะฝะพะฒั.
-pulls.push_rejected_summary=ะะพะฒะฝะต ะฟะพะฒัะดะพะผะปะตะฝะฝั ะฟัะพ ะฒัะดะผะพะฒั
+pulls.merge_conflict=ะะต ะฒะดะฐะปะพัั ะพะฑ'ัะดะฝะฐัะธ: ะฟัะธ ะพะฑ'ัะดะฝะฐะฝะฝั ะฒะธะฝะธะบ ะบะพะฝัะปัะบั. ะัะดะบะฐะทะบะฐ: ัะฟัะพะฑัะนัะต ัะฝัั ัััะฐัะตะณัั
+pulls.merge_conflict_summary=ะะพะฒัะดะพะผะปะตะฝะฝั ะฟัะพ ะฟะพะผะธะปะบั
+pulls.rebase_conflict=ะะต ะฒะดะฐะปะพัั ะพะฑ'ัะดะฝะฐัะธ: ะฒะธะฝะธะบ ะบะพะฝัะปัะบั ะฟัะด ัะฐั ะฟะตัะตะฑะฐะทัะฒะฐะฝะฝั ะบะพะผััะฐ: %[1]s. ะัะดะบะฐะทะบะฐ: ัะฟัะพะฑัะนัะต ัะฝัั ัััะฐัะตะณัั
+pulls.rebase_conflict_summary=ะะพะฒัะดะพะผะปะตะฝะฝั ะฟัะพ ะฟะพะผะธะปะบั
+pulls.unrelated_histories=ะะต ะฒะดะฐะปะพัั ะพะฑ'ัะดะฝะฐัะธ: head ัะฐ base ะทะปะธััั ะฝะต ะผะฐััั ัะฟัะปัะฝะพั ัััะพััั. ะัะดะบะฐะทะบะฐ: ัะฟัะพะฑัะนัะต ัะฝัั ัััะฐัะตะณัั
+pulls.merge_out_of_date=ะะต ะฒะดะฐะปะพัั ะพะฑ'ัะดะฝะฐัะธ: base ะฑัะปะพ ะพะฝะพะฒะปะตะฝะพ, ะฟะพะบะธ ะฒัะดะฑัะฒะฐะปะพัั ะพะฑ'ัะดะฝะฐะฝะฝั. ะัะดะบะฐะทะบะฐ: ัะฟัะพะฑัะนัะต ะทะฝะพะฒั.
+pulls.push_rejected_summary=ะะพะฒะฝะต ะฟะพะฒัะดะพะผะปะตะฝะฝั ะฟัะพ ะฒัะดั
ะธะปะตะฝะฝั
pulls.open_unmerged_pull_exists=`ะะธ ะฝะต ะผะพะถะตัะต ะทะฝะพะฒั ะฒัะดะบัะธัะธ, ะพัะบัะปัะบะธ ะฒะถะต ััะฝัั ะทะฐะฟะธั ะฝะฐ ะทะปะธััั (%d) ะท ัะพะณะพ ะถ ัะตะฟะพะทะธัะพััั ะท ัััั ะถ ัะฝัะพัะผะฐัััั ะฟัะพ ะทะปะธััั ั ะฒ ะพััะบัะฒะฐะฝะฝั.`
pulls.status_checking=ะะตัะบั ะฟะตัะตะฒััะบะธ ะทะฝะฐั
ะพะดััััั ะฝะฐ ัะพะทะณะปัะดั
pulls.status_checks_success=ะัั ะฟะตัะตะฒััะบะธ ะฑัะปะธ ััะฟััะฝะธะผะธ
@@ -1474,7 +1766,7 @@ milestones.title=ะะฐะณะพะปะพะฒะพะบ
milestones.desc=ะะฟะธั
milestones.due_date=ะะฐัะฐ ะทะฐะฒะตััะตะฝะฝั (ะพะฟััะพะฝะฐะปัะฝะพ)
milestones.clear=ะัะธััะธัะธ
-milestones.invalid_due_date_format=ะะฐัะฐ ะทะฐะฒะตััะตะฝะฝั ะผะฐั ะฑััะธ ะฒ ัะพัะผะฐัั 'ัััั-ะผะผ-ะดะด'.
+milestones.invalid_due_date_format=ะขะตัะผัะฝ ะฒะธะบะพะฝะฐะฝะฝั ะผะฐั ะฑััะธ ั ัะพัะผะฐัั ยซัััั-ะผะผ-ะดะดยป.
milestones.edit=ะ ะตะดะฐะณัะฒะฐัะธ ะตัะฐะฟ
milestones.edit_subheader=ะกัะฒะพััะนัะต ะตัะฐะฟะธ ะดะปั ะพัะณะฐะฝัะทะฐััั ะฒะฐัะธั
ะทะฐะดะฐั.
milestones.cancel=ะัะดะผัะฝะธัะธ
@@ -1503,14 +1795,14 @@ wiki.save_page=ะะฑะตัะตะณัะธ ััะพััะฝะบั
wiki.last_commit_info=%s ัะตะดะฐะณัะฒะฐะฒ ัั ััะพััะฝะบั %s
wiki.edit_page_button=ะ ะตะดะฐะณัะฒะฐัะธ
wiki.new_page_button=ะะพะฒะฐ ััะพััะฝะบะฐ
-wiki.file_revision=ะ ะตะฒัะทัั ััะพััะฝะบะธ
-wiki.wiki_page_revisions=ะ ะตะฒัะทัั ะฒัะบั ััะพััะฝะพะบ
+wiki.file_revision=ะะตัััั ััะพััะฝะบะธ
+wiki.wiki_page_revisions=ะะตัััั ััะพััะฝะพะบ
wiki.back_to_wiki=ะะพะฒะตัะฝััะธัั ะฝะฐ ััะพััะฝะบั ะัะบั
wiki.delete_page_button=ะะธะดะฐะปะธัะธ ััะพััะฝะบั
wiki.page_already_exists=ะัะบั-ััะพััะฝะบะฐ ะท ัะฐะบะธะผ ัะฐะผะธะผ ัะผ'ัะผ ะฒะถะต ััะฝัั.
wiki.pages=ะกัะพััะฝะบะธ
wiki.last_updated=ะััะฐะฝะฝั ะพะฝะพะฒะปะตะฝะฝั %s
-wiki.page_name_desc=ะะฒะตะดััั ะฝะฐะทะฒั ะฒัะบั-ััะพััะฝะบะธ. ะะตัะบั ัะท ัะฟะตััะฐะปัะฝะธั
ัะผะตะฝ: 'Home', '_Sidebar' ัะฐ '_Footer'.
+wiki.page_name_desc=ะะฒะตะดััั ะฝะฐะทะฒั ะฒัะบั-ััะพััะฝะบะธ. ะะตัะบั ะทั ัะฟะตััะฐะปัะฝะธั
ัะผะตะฝ: ยซHomeยป, ยซ_Sidebarยป ัะฐ ยซ_Footerยป.
activity=ะะบัะธะฒะฝัััั
activity.period.filter_label=ะะตััะพะด:
@@ -1522,38 +1814,38 @@ activity.period.quarterly=3 ะผััััั
activity.period.semiyearly=6 ะผัััััะฒ
activity.period.yearly=1 ััะบ
activity.overview=ะะณะปัะด
-activity.active_prs_count_1=%d ะะบัะธะฒะฝะธะน ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั
-activity.active_prs_count_n=%d ะะบัะธะฒะฝั ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั
-activity.merged_prs_count_1=ะะปะธัะธะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั
-activity.merged_prs_count_n=ะะปะธัั ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั
+activity.active_prs_count_1=%d ะฐะบัะธะฒะฝะธะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั
+activity.active_prs_count_n=%d ะฐะบัะธะฒะฝะธั
ะทะฐะฟะธััะฒ ะฝะฐ ะทะปะธััั
+activity.merged_prs_count_1=ะะฑ'ัะดะฝะฐะฝะธะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั
+activity.merged_prs_count_n=ะะฑ'ัะดะฝะฐะฝั ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั
activity.opened_prs_count_1=ะะฐะฟัะพะฟะพะฝะพะฒะฐะฝะธะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั
activity.opened_prs_count_n=ะะฐะฟัะพะฟะพะฝะพะฒะฐะฝะธั
ะทะฐะฟะธััะฒ ะฝะฐ ะทะปะธััั
activity.title.user_1=%d ะบะพัะธัััะฒะฐัะตะผ
activity.title.user_n=%d ะบะพัะธัััะฒะฐัะฐะผะธ
-activity.title.prs_1=%d ะะฐะฟะธั ะฝะฐ ะทะปะธััั
-activity.title.prs_n=%d ะะฐะฟะธััะฒ ะฝะฐ ะทะปะธััั
+activity.title.prs_1=%d ะทะฐะฟะธั ะฝะฐ ะทะปะธััั
+activity.title.prs_n=%d ะทะฐะฟะธััะฒ ะฝะฐ ะทะปะธััั
activity.title.prs_merged_by=%s ะทะปะธัะพ %s
activity.title.prs_opened_by=%s ะทะฐะฟัะพะฟะพะฝะพะฒะฐะฝะพ %s
activity.merged_prs_label=ะะปะธัะพ
activity.opened_prs_label=ะะฐะฟัะพะฟะพะฝะพะฒะฐะฝะพ
-activity.active_issues_count_1=%d ะะบัะธะฒะฝะฐ ะทะฐะดะฐัะฐ
-activity.active_issues_count_n=%d ะะบัะธะฒะฝั ะทะฐะดะฐัั
+activity.active_issues_count_1=%d ะฐะบัะธะฒะฝะฐ ะทะฐะดะฐัะฐ
+activity.active_issues_count_n=%d ะฐะบัะธะฒะฝะธั
ะทะฐะดะฐั
activity.closed_issues_count_1=ะะฐะบัะธัะฐ ะทะฐะดะฐัะฐ
activity.closed_issues_count_n=ะะฐะบัะธัั ะทะฐะดะฐัั
-activity.title.issues_1=%d ะะฐะดะฐั
-activity.title.issues_n=%d ะะฐะดะฐั
+activity.title.issues_1=%d ะทะฐะดะฐัะฐ
+activity.title.issues_n=%d ะทะฐะดะฐั
activity.title.issues_closed_from=%s ะทะฐะบัะธัะพ %s
activity.title.issues_created_by=%s ััะฒะพัะตะฝะฐ(ั) %s
activity.closed_issue_label=ะะฐะบัะธัะพ
activity.new_issues_count_1=ะะพะฒะฐ ะทะฐะดะฐัะฐ
-activity.new_issues_count_n=ะะพะฒั ะะฐะดะฐัั
+activity.new_issues_count_n=ะะพะฒั ะทะฐะดะฐัั
activity.new_issue_label=ะัะดะบัะธัั
activity.title.unresolved_conv_1=%d ะะตะทะฐะฒะตััะตะฝะต ะพะฑะณะพะฒะพัะตะฝะฝั
activity.title.unresolved_conv_n=%d ะะตะทะฐะฒะตััะตะฝะธั
ะพะฑะณะพะฒะพัะตะฝั
activity.unresolved_conv_desc=ะกะฟะธัะพะบ ะฒััั
ััะฐัะธั
ะทะฐะดะฐั ั Pull Request'ัะฒ ะท ะฝะตะดะฐะฒะฝัะพั ะฐะบัะธะฒะฝัััั, ะฐะปะต ัะต ะฝะต ะทะฐะบัะธัะธั
ะฐะฑะพ ะฟัะธะนะฝััะธั
.
activity.unresolved_conv_label=ะัะดะบัะธัะธ
-activity.title.releases_1=%d ะ ะตะปัะท
-activity.title.releases_n=%d ะ ะตะปัะทัะฒ
+activity.title.releases_1=%d ะฒะธะฟััะบ
+activity.title.releases_n=%d ะฒะธะฟััะบัะฒ
activity.title.releases_published_by=%s ะพะฟัะฑะปัะบะพะฒะฐะฝะพ %s
activity.published_release_label=ะะฟัะฑะปัะบะพะฒะฐะฝะพ
activity.no_git_activity=ะฃ ัะตะน ะฟะตััะพะด ะฝะต ะฑัะปะพ ะทะดัะนัะฝะตะฝะพ ะถะพะดะฝะธั
ะดัะน.
@@ -1606,17 +1898,17 @@ settings.mirror_settings.direction.pull=Pull
settings.mirror_settings.direction.push=Push
settings.mirror_settings.last_update=ะััะฐะฝะฝั ะพะฝะพะฒะปะตะฝะฝั
settings.mirror_settings.push_mirror.none=ะะต ะฝะฐะปะฐััะพะฒะฐะฝะพ ะดะทะตัะบะฐะปะพ push
-settings.mirror_settings.push_mirror.remote_url=URL ะฒัะดะดะฐะปะตะฝะพะณะพ ัะตะฟะพะทะธัะฐััั git
+settings.mirror_settings.push_mirror.remote_url=URL ะฒัะดะดะฐะปะตะฝะพะณะพ ัะตะฟะพะทะธัะพััั Git
settings.mirror_settings.push_mirror.add=ะะพะดะฐัะธ Push ะดะทะตัะบะฐะปะพ
settings.sync_mirror=ะกะธะฝั
ัะพะฝัะทัะฒะฐัะธ ะทะฐัะฐะท
settings.site=ะะตะฑ-ัะฐะนั
-settings.update_settings=ะะฝะพะฒะธัะธ ะฝะฐะปะฐัััะฒะฐะฝะฝั
-settings.branches.update_default_branch=ะะฝะพะฒะธัะธ ะณัะปะบั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
+settings.update_settings=ะะฑะตัะตะณัะธ ะฝะฐะปะฐัััะฒะฐะฝะฝั
+settings.branches.update_default_branch=ะะฝะพะฒะธัะธ ัะธะฟะพะฒั ะณัะปะบั
settings.advanced_settings=ะะพะดะฐัะบะพะฒั ะฝะฐะปะฐัััะฒะฐะฝะฝั
-settings.wiki_desc=ะฃะฒัะผะบะฝััะธ ัะตะฟะพะทะธัะพััั ะัะบั
-settings.use_internal_wiki=ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะฒะฑัะดะพะฒะฐะฝั ะัะบั
-settings.use_external_wiki=ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะทะพะฒะฝััะฝั ะัะบั
+settings.wiki_desc=ะฃะฒัะผะบะฝััะธ ะฒัะบั ัะตะฟะพะทะธัะพััั
+settings.use_internal_wiki=ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะฒะฑัะดะพะฒะฐะฝั ะฒัะบั
+settings.use_external_wiki=ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะทะพะฒะฝััะฝั ะฒัะบั
settings.external_wiki_url=URL ะทะพะฒะฝััะฝัะพั ะฒัะบั
settings.external_wiki_url_error=ะะพะฒะฝััะฝั URL-ะฐะดัะตัะฐ wiki ะฝะต ั ะดะพะฟัััะธะผะพั URL-ะฐะดัะตัะพั.
settings.external_wiki_url_desc=ะัะดะฒัะดัะฒะฐัั ะฑัะดััั ะฟะตัะตะฝะฐะฟัะฐะฒะปะตะฝั ะฝะฐ URL-ะฐะดัะตัั, ะบะพะปะธ ะฒะพะฝะธ ะบะปะฐัะฐััั ะฟะพ ะฒะบะปะฐะดัั.
@@ -1628,7 +1920,7 @@ settings.external_tracker_url_error=URL ะทะพะฒะฝััะฝัะพะณะพ ะฑะฐะณ-ััะตะบะต
settings.external_tracker_url_desc=ะัะดะฒัะดัะฒะฐัั ะฟะตัะตะฝะฐะฟัะฐะฒะปัััััั ะฝะฐ ะทะพะฒะฝััะฝั URL-ะฐะดัะตัั, ะบะพะปะธ ะฝะฐัะธัะบะฐััั ะฒะบะปะฐะดะบั 'ะะฐะดะฐัั'.
settings.tracker_url_format=ะคะพัะผะฐั URL ะทะพะฒะฝััะฝัะพะณะพ ััะตะบะตัะฐ ะทะฐะดะฐั
settings.tracker_url_format_error=ะะตะฟัะฐะฒะธะปัะฝะธะน ัะพัะผะฐั URL-ะฐะดัะตัะธ ะทะพะฒะฝััะฝัะพะณะพ ะฑะฐะณ-ััะตะบะตัะฐ.
-settings.tracker_issue_style=ะคะพัะผะฐั ะฝะพะผะตัั ะดะปั ะทะพะฒะฝััะฝัะพั ัะธััะตะผะธ ะพะฑะปัะบั ะทะฐะดะฐั
+settings.tracker_issue_style=ะคะพัะผะฐั ะฝะพะผะตัะฐ ะดะปั ะทะพะฒะฝััะฝัะพั ัะธััะตะผะธ ะพะฑะปัะบั ะทะฐะดะฐั
settings.tracker_issue_style.numeric=ะฆะธััะพะฒะธะน
settings.tracker_issue_style.alphanumeric=ะัะบะฒะตะฝะพ-ัะธััะพะฒะธะน
settings.tracker_url_format_desc=ะะธะบะพัะธััะพะฒัะนัะต ัะฐะฑะปะพะฝะธ {user}
, {repo}
ัะฐ {index}
ะดะปั ัะผะตะฝั ะบะพัะธัััะฒะฐัะฐ, ัะตะฟะพะทะธัะพััั ัะฐ ะฝะพะผะตัั ะทะฐะดััั.
@@ -1666,7 +1958,7 @@ settings.transfer_notices_1=- ะะธ ะฒััะฐัะธัะต ะดะพัััะฟ ะดะพ ัะตะฟะพะท
settings.transfer_notices_2=- ะะธ ะทะฑะตัะตะถะตัะต ะดะพัััะฟ, ัะบัะพ ะฝะพะฒะธะผ ะฒะปะฐัะฝะธะบะพะผ ััะฐะฝะต ะพัะณะฐะฝัะทะฐััั, ะฒะปะฐัะฝะธะบะพะผ ัะบะพั ะฒะธ ั.
settings.transfer_notices_3=- ะฏะบัะพ ัะตะฟะพะทะธัะพััะน ั ะฟัะธะฒะฐัะฝะธะผ ั ะฟะตัะตะดะฐััััั ะพะบัะตะผะพะผั ะบะพัะธัััะฒะฐัะตะฒั, ัั ะดัั ะณะฐัะฐะฝััั, ัะพ ะบะพัะธัััะฒะฐั ะผะฐั ั
ะพัะฐ ะฑ ะดะพะทะฒัะป ะฝะฐ ัะธัะฐะฝั ัะตะฟะพะทะธัะฐััั (ั ะฟัะธ ะฝะตะพะฑั
ัะดะฝะพััั ะทะผัะฝัั ะฟัะฐะฒะฐ ะดะพะทะฒะพะปัะฒ).
settings.transfer_owner=ะะพะฒะธะน ะฒะปะฐัะฝะธะบ
-settings.transfer_perform=ะะดััะฝะธัะธ ะฟะตัะตะฝะตัะตะฝะฝั
+settings.transfer_perform=ะะดัะนัะฝะธัะธ ะฟะตัะตะฝะตัะตะฝะฝั
settings.transfer_started=`ะฆะตะน ัะตะฟะพะทะธัะพััะน ัะตะบะฐั ะฟัะดัะฒะตัะดะถะตะฝะฝั ะฟะตัะตะฝะตัะตะฝะฝั ะฒัะด "%s"`
settings.transfer_succeed=ะ ะตะฟะพะทะธัะพััะน ะฑัะฒ ะฟะตัะตะฝะตัะตะฝะธะน.
settings.signing_settings=ะะฐัะฐะผะตััะธ ะฟะตัะตะฒััะบะธ ะฟัะดะฟะธัั
@@ -1684,7 +1976,7 @@ settings.trust_model.collaboratorcommitter.desc=ะะพะฟัััะธะผั ะฟัะดะฟะธั
settings.wiki_delete=ะะธะดะฐะปะธัะธ ะฒัะบั-ะดะฐะฝั
settings.wiki_delete_desc=ะัะดััะต ัะฒะฐะถะฝั! ะฏะบ ััะปัะบะธ ะฒะธ ะฒะธะดะฐะปะธัะต ะัะบั - ัะปัั
ั ะฝะฐะทะฐะด ะฝะต ะฑัะดะต.
settings.wiki_delete_notices_1=- ะฆะต ะฝะฐะทะฐะฒะถะดะธ ะทะฝะธัะธัั ั ะฒัะดะบะปััะธัั wiki ะดะปั %s.
-settings.confirm_wiki_delete=ะะธะดะฐะปะธัะธ ะัะบั-ะดะฐะฝั
+settings.confirm_wiki_delete=ะะธะดะฐะปะธัะธ ะฒัะบั-ะดะฐะฝั
settings.wiki_deletion_success=ะะฐะฝั wiki ะฑัะปะธ ะฒะธะดะฐะปะตะฝั.
settings.delete=ะะธะดะฐะปะธัะธ ัะตะน ัะตะฟะพะทะธัะพััะน
settings.delete_desc=ะัะดััะต ัะฒะฐะถะฝั! ะฏะบ ััะปัะบะธ ะฒะธ ะฒะธะดะฐะปะธัะต ัะตะฟะพะทะธัะพััะน - ัะปัั
ั ะฝะฐะทะฐะด ะฝะต ะฑัะดะต.
@@ -1707,17 +1999,17 @@ settings.org_not_allowed_to_be_collaborator=ะัะณะฐะฝัะทะฐััั ะฝะต ะผะพะถั
settings.change_team_access_not_allowed=ะะผัะฝะฐ ะดะพัััะฟั ะบะพะผะฐะฝะดะธ ะดะพ ัะตะฟะพะทะธัะฐััั ะพะฑะผะตะถะตะฝะฐ ะฒะปะฐัะฝะธะบะพะผ ะพัะณะฐะฝัะทะฐััั
settings.team_not_in_organization=ะะพะผะฐะฝะดะฐ ัะฐ ัะตะฟะพะทะธัะฐััะน ะผะฐััั ะฟัะธะฒัะทะบะธ ะดะพ ััะทะฝะธั
ะพัะณะฐะฝัะทะฐััะน
settings.teams=ะะพะผะฐะฝะดะธ
-settings.add_team=ะะพะดะฐัะธ ะะพะผะฐะฝะดั
+settings.add_team=ะะพะดะฐัะธ ะบะพะผะฐะฝะดั
settings.add_team_duplicate=ะะพะผะฐะฝะดะฐ ะฒะถะต ะผะฐั ะฟัะธะฒัะทะบั ะดะพ ัะตะฟะพะทะธัะฐััั
settings.add_team_success=ะะพะผะฐะฝะดะฐ ะพััะธะผะฐะปะฐ ะดะพัััะฟ ะดะพ ัะตะฟะพะทะธัะพััั.
settings.search_team=ะะฝะฐะนัะธ ะบะพะผะฐะฝะดัโฆ
settings.change_team_permission_tip=ะะพะทะฒะพะปะธ ะบะพะผะฐะฝะดะธ ะฒััะฐะฝะพะฒะปัััััั ะฝะฐ ััะพััะฝัั ะฝะฐะปะฐัััะฒะฐะฝั ะบะพะผะฐะฝะดะธ ัะฐ ะฝะต ะผะพะถััั ะฑััะธ ะทะฐะดะฐะฝะธะผะธ ะดะปั ะบะพะถะฝะพะณะพ ะท ัะตะฟะพะทะธัะพัััะฒ ะพะบัะตะผะพ
settings.delete_team_tip=ะฆั ะบะพะผะฐะฝะดะฐ ะผะฐั ะดะพัััะฟ ะดะพ ะฒััั
ัะตะฟะพะทะธัะพัััะฒ ัะฐ ะฝะต ะผะพะถะต ะฑััะธ ะฒะธะดะฐะปะตะฝะฐ
settings.remove_team_success=ะะพัััะฟ ะบะพะผะฐะฝะดะธ ะดะพ ัะตะฟะพะทะธัะพััั ะฒะธะดะฐะปะตะฝะธะน.
-settings.add_webhook=ะะพะดะฐัะธ ะฒะตะฑ-ั
ัะบ
+settings.add_webhook=ะะพะดะฐัะธ ะฒะตะฑั
ัะบ
settings.add_webhook.invalid_channel_name=ะะฐะทะฒะฐ ะบะฐะฝะฐะปั Webhook ะฝะต ะผะพะถะต ะฑััะธ ะฟะพัะพะถะฝัะพั ั ะฝะต ะผะพะถะต ะผัััะธัะธ ะปะธัะต ัะธะผะฒะพะป #.
settings.hooks_desc=ะะตะฑ-ั
ัะบะธ ะฐะฒัะพะผะฐัะธัะฝะพ ัะพะฑะธัั HTTP POST-ะทะฐะฟะธัะธ ะฝะฐ ัะตัะฒะตั, ะบะพะปะธ ะฒัะดะฑัะฒะฐััััั ะฟะตะฒะฝั ะฟะพะดัั Forgejo. ะัะทะฝะฐะนัะตัั ะฑัะปััะต ะฒ ัะฝััััะบััั ะฟะพ ะฒะธะบะพัะธััะฐะฝะฝั web-ั
ัะบัะฒ .
-settings.webhook_deletion=ะะธะดะฐะปะธัะธ ะฒะตะฑ-ั
ัะบ
+settings.webhook_deletion=ะะธะดะฐะปะธัะธ ะฒะตะฑั
ัะบ
settings.webhook_deletion_desc=ะะธะดะฐะปะตะฝะฝั ััะพะณะพ ะฒะตะฑ-ั
ัะบะฐ ะฟัะธะทะฒะตะดะต ะดะพ ะฒะธะดะฐะปะตะฝะฝั ะฒัััั ะฟะพะฒ'ัะทะฐะฝะพั ะท ะฝะธะผ ัะฝัะพัะผะฐััั, ะฒะบะปััะฐััะธ ัััะพััั. ะะฐะถะฐััะต ะฟัะพะดะพะฒะถะธัะธ?
settings.webhook_deletion_success=Webhook ะฒะธะดะฐะปะตะฝะพ.
settings.webhook.test_delivery=ะะตัะตะฒััะธัะธ ะดะพััะฐะฒะบั
@@ -1734,7 +2026,7 @@ settings.update_githook=ะะฝะพะฒะธัะธ ั
ัะบ
settings.add_webhook_desc=Forgejo ะฑัะดะต ะฒัะดะฟัะฐะฒะปััะธ POST
ะทะฐะฟะธัะธ ะฝะฐ ะฒะบะฐะทะฐะฝั URL ะฐะดัะตัั, ะท ัะฝัะพัะผะฐัััั ะฟัะพ ะฟะพะดัั, ัะพ ะฒัะดะฑัะฒะฐััััั. ะะพะดัะพะฑะธัั ะฝะฐ ััะพััะฝัั ัะฝััััะบััั ะฟะพ ะฒะธะบะพัะธััะฐะฝะฝั web-ั
ัะบัะฒ .
settings.payload_url=ะฆัะปัะพะฒะฐ URL-ะฐะดัะตัะฐ
settings.http_method=ะะตัะพะด HTTP
-settings.content_type=ะขะธะฟ ะทะผัััั
+settings.content_type=ะขะธะฟ ะฒะผัััั POST
settings.secret=ะกะตะบัะตั
settings.slack_username=ะะผ'ั ะบัะธัััะฒะฐัะฐ
settings.slack_icon_url=URL ัะบะพะฝะบะธ
@@ -1743,13 +2035,13 @@ settings.discord_username=ะะผ'ั ะบัะธัััะฒะฐัะฐ
settings.discord_icon_url=URL ัะบะพะฝะบะธ
settings.event_desc=ะขัะธะณะตั:
settings.event_push_only=Push ะฟะพะดัั
-settings.event_send_everything=ะัั ะฟะพะดัั
+settings.event_send_everything=ะฃัั ะฟะพะดัั
settings.event_choose=ะะปะฐัะฝั ะฟะพะดััโฆ
settings.event_header_repository=ะะพะดัั ัะตะฟะพะทะธัะพััั
settings.event_create=ะกัะฒะพัะธัะธ
settings.event_create_desc=ะัะปะบั ะฐะฑะพ ัะตะณ ััะฒะพัะตะฝะพ.
settings.event_delete=ะะธะดะฐะปะธัะธ
-settings.event_delete_desc=ะัะปะบั ะฐะฑะพ ะผััะบั ะฑัะปะพ ะฒะธะดะฐะปะตะฝะพ.
+settings.event_delete_desc=ะัะปะบั ะฐะฑะพ ัะตะณ ะฒะธะดะฐะปะตะฝะพ.
settings.event_fork=ะคะพัะบ
settings.event_fork_desc=ะ ะตะฟะพะทะธัะพััะน ะฑัะปะพ ัะพัะบะฝััะพ.
settings.event_wiki=ะัะบั
@@ -1760,55 +2052,55 @@ settings.event_push_desc=Git push ะดะพ ัะตะฟะพะทะธัะพััั.
settings.event_repository=ะ ะตะฟะพะทะธัะพััะน
settings.event_repository_desc=ะ ะตะฟะพะทะธัะพััะน ััะฒะพัะตะฝะธะน ะฐะฑะพ ะฒะธะดะฐะปะตะฝะพ.
settings.event_header_issue=ะะพะดัั ะทะฐะดะฐัั
-settings.event_issues=ะะฐะดะฐัั
+settings.event_issues=ะะผัะฝะฐ
settings.event_issues_desc=ะะฐะดะฐัะฐ ะฒัะดะบัะธัะฐ, ะทะฐะบัะธัะฐ, ะฟะพะฒัะพัะฝะพ ะฒัะดะบัะธัะฐ ะฐะฑะพ ะฒัะดัะตะดะฐะณะพะฒะฐะฝะฐ.
-settings.event_issue_assign=ะะฐะดะฐัะฐ ะฟัะธะฒ'ัะทะฐะฝะฐ
+settings.event_issue_assign=ะัะธะทะฝะฐัะตะฝะฝั
settings.event_issue_assign_desc=ะะฐะดะฐัั ะฟัะธะทะฝะฐัะตะฝะพ ะฐะฑะพ ัะบะฐัะพะฒะฐะฝะพ.
-settings.event_issue_label=ะะฐะดะฐัะฐ ะท ะผััะบะพั
-settings.event_issue_label_desc=ะััะบะธ ะทะฐะดะฐัั ะพะฝะพะฒะปะตะฝะพ ะฐะฑะพ ะฒะธะดะฐะปะตะฝะพ.
+settings.event_issue_label=ะััะบะธ
+settings.event_issue_label_desc=ะะพะดะฐะฒะฐะฝะฝั ะฐะฑะพ ะฒะธะดะฐะปะตะฝะฝั ะผััะพะบ ะทะฐะดะฐั.
settings.event_issue_milestone=ะะฐะดะฐัะฐ ะท ะตัะฐะฟะพะผ
-settings.event_issue_milestone_desc=ะะฐะดะฐัะฐ ะฟัะธะทะฝะฐัะตะฝะฐ ะฝะฐ ะตัะฐะฟ ะฐะฑะพ ะฒะธะดะฐะปะตะฝะฐ ะท ะตัะฐะฟั.
-settings.event_issue_comment=ะะพะผะตะฝัะฐั ะทะฐะดะฐัั
+settings.event_issue_milestone_desc=ะัะฐะฟ ะฟัะธะทะฝะฐัะตะฝะพ, ะฒะธะดะฐะปะตะฝะพ ะฐะฑะพ ะทะผัะฝะตะฝะพ.
+settings.event_issue_comment=ะะพะผะตะฝัะฐัั
settings.event_issue_comment_desc=ะะพะผะตะฝัะฐั ะทะฐะดะฐัั ััะฒะพัะตะฝะพ, ะฒะธะดะฐะปะตะฝะพ ัะธ ะฒัะดัะตะดะฐะณะพะฒะฐะฝะพ.
-settings.event_header_pull_request=ะะพะดัั ะทะฐะฟะธัั ะทะปะธััั
+settings.event_header_pull_request=ะะพะดัั ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั
settings.event_pull_request=ะะฐะฟะธัะธ ะดะพ ะทะปะธััั
settings.event_pull_request_desc=ะะฐะฟะธั ะดะพ ะทะปะธััั ะฒัะดะบัะธัะพ, ะทะฐะบัะธัะพ, ะฟะตัะตะฒัะดะบัะธัะพ ะฐะฑะพ ะฒัะดัะตะดะฐะณะพะฒะฐะฝะพ.
-settings.event_pull_request_assign=ะะฐะฟะธั ะฝะฐ ะทะปะธััั ะฟัะธะทะฝะฐัะตะฝะพ
+settings.event_pull_request_assign=ะัะธะทะฝะฐัะตะฝะฝั
settings.event_pull_request_assign_desc=ะะฐะฟะธั ะฟัะพ ะทะปะธััั ะฟัะธะทะฝะฐัะตะฝะพ ะฐะฑะพ ัะบะฐัะพะฒะฐะฝะพ.
-settings.event_pull_request_label=ะะฐะฟะธัั ะฝะฐ ะทะปะธััั ะฟัะธะทะฝะฐัะตะฝะฐ ะผััะบะฐ
-settings.event_pull_request_label_desc=ะััะบะฐ ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั ะพะฝะพะฒะปะตะฝะฐ ะฐะฑะพ ะพัะธัะตะฝะฐ.
-settings.event_pull_request_milestone=ะะฐะฟะธั ะฝะฐ ะทะปะธััั ะฟัะธะทะฝะฐัะตะฝะธะน ะฝะฐ ะตัะฐะฟ
-settings.event_pull_request_milestone_desc=ะะฐะฟะธั ะฝะฐ ะทะปะธััั ะฟัะธะทะฝะฐัะตะฝะธะน ะฝะฐ ะตัะฐะฟ ะฐะฑะพ ะฒะธะดะฐะปะตะฝะธะน ะท ะตัะฐะฟั.
-settings.event_pull_request_comment=ะะฐะฟะธั ะฝะฐ ะทะปะธััั ะฟัะพะบะพะผะตะฝัะพะฒะฐะฝะธะน
+settings.event_pull_request_label=ะััะบะธ
+settings.event_pull_request_label_desc=ะััะบะธ ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั ะพะฝะพะฒะปะตะฝะพ ะฐะฑะพ ะพัะธัะตะฝะพ.
+settings.event_pull_request_milestone=ะัะฐะฟะธ
+settings.event_pull_request_milestone_desc=ะัะฐะฟ ะฟัะธะทะฝะฐัะตะฝะพ, ะฒะธะดะฐะปะตะฝะพ ะฐะฑะพ ะทะผัะฝะตะฝะพ.
+settings.event_pull_request_comment=ะะพะผะตะฝัะฐัั
settings.event_pull_request_comment_desc=ะะพะผะตะฝัะฐั ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั ััะฒะพัะตะฝะพ, ะฒัะดัะตะดะฐะณะพะฒะฐะฝะพ ัะธ ะฒะธะดะฐะปะตะฝะพ.
-settings.event_pull_request_review=ะะฐะฟะธั ะฝะฐ ะทะปะธััั ัะตัะตะฝะทะพะฒะฐะฝะพ
-settings.event_pull_request_review_desc=ะะพะผะตะฝัะฐั ะทะฐะฟะธัั ะดะพ ะทะปะธััั ะฟัะดัะฒะตัะดะถะตะฝะธะน, ะฒัะดั
ะธะปะตะฝะธะน ะฐะฑะพ ัะตัะตะฝะทะพะฒะฐะฝะธะน.
-settings.event_pull_request_sync=ะะฐะฟะธั ะฝะฐ ะทะปะธััั ัะธะฝั
ัะพะฝัะทัััััั
-settings.event_pull_request_sync_desc=ะะฐะฟะธั ะดะพ ะทะปะธััั ัะธะฝั
ัะพะฝัะทะพะฒะฐะฝะพ.
+settings.event_pull_request_review=ะัะดะณัะบะธ
+settings.event_pull_request_review_desc=ะะฐะฟะธั ะฝะฐ ะทะปะธััั ัั
ะฒะฐะปะตะฝะพ, ะฒัะดั
ะธะปะตะฝะพ ะฐะฑะพ ะฟัะพะบะพะผะตะฝัะพะฒะฐะฝะพ.
+settings.event_pull_request_sync=ะกะธะฝั
ัะพะฝัะทะพะฒะฐะฝะพ
+settings.event_pull_request_sync_desc=ะัะปะบั ะฐะฒัะพะผะฐัะธัะฝะพ ะพะฝะพะฒะปะตะฝะพ ััะปัะพะฒะพั ะณัะปะบะพั.
settings.branch_filter=ะคัะปััั ะณัะปะพะบ
-settings.branch_filter_desc=ะัะปะธะน ัะฟะธัะพะบ ะฟะพะฒัะดะพะผะปะตะฝั ะดะปั push, ััะฒะพัะตะฝะฝั ะณัะปะพะบ ัะฐ ะฒะธะดะฐะปะตะฝะฝั ะณัะปะพะบ, ะฒะธะทะฝะฐัะฐััััั ัะบ glob ัะฐะฑะปะพะฝ. ะฏะบัะพ ะฒัะฝ ะฟัััะธะน ะฐะฑะพ ะผัััะธัั *
, ะฟะพะฒัะดะพะผะปะตะฝะฝั ะดะปั ะฒัััั
ะณัะปะพะบ ะฒะฒัะผะบะฝะตะฝั. ะัะฒััััั github.com/gobwas/glob ะดะพะบัะผะตะฝัะฐััั ะฝะฐ ัะธะฝัะฐะบัะธั. ะะฐะฟัะธะบะปะฐะด: master
, {master,release*}
.
+settings.branch_filter_desc=ะัะปะธะน ัะฟะธัะพะบ ะณัะปะพะบ ะดะปั push, ััะฒะพัะตะฝะฝั ะณัะปะพะบ ัะฐ ะฒะธะดะฐะปะตะฝะฝั ะณัะปะพะบ, ะฒะธะทะฝะฐัะฐััััั ัะบ ัะฐะฑะปะพะฝ glob. ะฏะบัะพ ะฒัะฝ ะฟะพัะพะถะฝัะน ะฐะฑะพ ะผัััะธัั *
, ัะพ ัะตัััััััััั ะฟะพะดัั ะดะปั ะฒััั
ะณัะปะพะบ. ะะธะฒััััั ัะธะฝัะฐะบัะธั ั ะดะพะบัะผะตะฝัะฐััั ะฝะฐ %[2]s . ะะฐะฟัะธะบะปะฐะด: master
, {master,release*}
.
settings.active=ะะบัะธะฒะฝะธะน
settings.active_helper=ะะฝัะพัะผะฐััั ะฟัะพ ะฒะธะบะปะธะบะฐะฝั ะฟะพะดัั ะฑัะดะต ะฝะฐะดััะปะฐะฝะพ ะทะฐ ัััั ะฒะตะฑ-ั
ัะบ URL-ะฐะดัะตัะพั.
settings.add_hook_success=ะะตะฑ-ั
ัะบ ะฑัะปะพ ะดะพะดะฐะฝะพ.
-settings.update_webhook=ะะฝะพะฒะธัะธ ะฒะตะฑ-ั
ัะบ
+settings.update_webhook=ะะฝะพะฒะธัะธ ะฒะตะฑั
ัะบ
settings.update_hook_success=ะะตะฑ-ั
ัะบ ะฑัะปะพ ะพะฝะพะฒะปะตะฝะพ.
-settings.delete_webhook=ะะธะดะฐะปะธัะธ ะฒะตะฑ-ั
ัะบ
+settings.delete_webhook=ะะธะดะฐะปะธัะธ ะฒะตะฑั
ัะบ
settings.recent_deliveries=ะะตะดะฐะฒะฝั ัะพะทัะธะปะบะธ
settings.hook_type=ะขะธะฟ ั
ัะบะฐ
settings.slack_token=ะขะพะบะตะฝ
settings.slack_domain=ะะพะผะตะฝ
settings.slack_channel=ะะฐะฝะฐะป
-settings.deploy_keys=ะะปััั ะดะปั ัะพะทะณะพัััะฒะฐะฝะฝั
-settings.add_deploy_key=ะะพะดะฐัะธ ะบะปัั ะดะปั ัะพะทะณะพัััะฒะฐะฝะฝั
+settings.deploy_keys=ะะปััั ะดะปั ัะพะทะณะพััะฐะฝะฝั
+settings.add_deploy_key=ะะพะดะฐัะธ ะบะปัั ะดะปั ัะพะทะณะพััะฐะฝะฝั
settings.deploy_key_desc=ะะปััั ัะพะทะณะพััะฐะฝะฝั ะดะพัััะฟะฝั ััะปัะบะธ ะดะปั ัะธัะฐะฝะฝั. ะฆะต ะฝะต ัะต ะถ ัะฐะผะต ัะพ ั SSH-ะบะปััั ะฐะบะบะฐัะฝัะฐ.
-settings.is_writable=ะฃะฒัะผะบะฝััะธ ะดะพัััะฟ ะดะปั ะทะฐะฟะธัั
+settings.is_writable=ะฃะฒัะผะบะฝััะธ ะดะพัััะฟ ะฝะฐ ะทะฐะฟะธั
settings.is_writable_info=ะงะธ ะผะพะถะต ัะตะน ะบะปัั ะฑััะธ ะฒะธะบะพัะธััะฐะฝะธะน ะดะปั ะฒะธะบะพะฝะฐะฝะฝั push ะฒ ัะตะฟะพะทะธัะพััะน? ะะปััั ัะพะทะณะพััะฐะฝะฝั ะทะฐะฒะถะดะธ ะผะฐััั ะดะพัััะฟ ะฝะฐ pull.
settings.no_deploy_keys=ะะธ ะฝะต ะดะพะดะฐะฒะฐะปะธ ะบะปััั ัะพะทะณะพััะฐะฝะฝั.
settings.title=ะะฐะณะพะปะพะฒะพะบ
settings.deploy_key_content=ะะผััั
settings.key_been_used=ะะผััั ะบะปััะฐ ัะพะทะณะพััะฐะฝะฝั ะฒะถะต ะฒะธะบะพัะธััะพะฒัััััั.
settings.key_name_used=ะะปัั ัะพะทะณะพััะฐะฝะฝั ะท ัะฐะบะธะผ ะทะฐะณะพะปะพะฒะบะพะผ ะฒะถะต ััะฝัั.
-settings.deploy_key_deletion=ะะธะดะฐะปะธัะธ ะบะปัั ะดะปั ัะพะทะณะพัััะฒะฐะฝะฝั
+settings.deploy_key_deletion=ะะธะดะฐะปะธัะธ ะบะปัั ะดะปั ัะพะทะณะพััะฐะฝะฝั
settings.deploy_key_deletion_desc=ะะธะดะฐะปะตะฝะฝั ะบะปััะฐ ัะพะทะณะพััะบะธ ัะฝะตะผะพะถะปะธะฒะธัั ะดะพัััะฟ ะดะพ ัะตะฟะพะทะธัะพััั ะท ะนะพะณะพ ะดะพะฟะพะผะพะณะพั. ะะธ ะฒะฟะตะฒะฝะตะฝั?
settings.deploy_key_deletion_success=ะะปััั ัะพะทะณะพััะฐะฝะฝั ะฑัะปะพ ะฒะธะดะฐะปะตะฝะพ.
settings.branches=ะัะปะบะธ
@@ -1816,40 +2108,40 @@ settings.protected_branch=ะะฐั
ะธัั ะณัะปะบะธ
settings.protected_branch_can_push=ะะพะทะฒะพะปะธัะธ push?
settings.protected_branch_can_push_yes=ะะธ ะผะพะถะตัะต ะฒะธะบะพะฝัะฒะฐัะธ push
settings.protected_branch_can_push_no=ะะธ ะฝะต ะผะพะถะตัะต ะฒะธะบะพะฝัะฒะฐัะธ push
-settings.branch_protection=ะะฐั
ะธัั ะณัะปะบะธ %s
+settings.branch_protection=ะัะฐะฒะธะปะฐ ะทะฐั
ะธััั ะดะปั ะณัะปะบะธ ยซ%s ยป
settings.protect_this_branch=ะะฐั
ะธััะธัะธ ัั ะณัะปะบั
settings.protect_this_branch_desc=ะะฐะฟะพะฑัะณะฐั ะฒะธะดะฐะปะตะฝะฝั ะณัะปะบะธ ัะฐ ะพะฑะผะตะถัั ะฒะธะบะพะฝะฐะฝะฝั ะฒ ะฝัะน push ัะฐ ะทะปะธััั.
-settings.protect_disable_push=ะะฐะฑะพัะพะฝะธัะธ Push
+settings.protect_disable_push=ะะฐะฑะพัะพะฝะธัะธ push
settings.protect_disable_push_desc=ะะปั ัััั ะณัะปะบะธ ะฑัะดะต ะทะฐะฑะพัะพะฝะตะฝะพ ะฒะธะบะพะฝะฐะฝะฝั push.
-settings.protect_enable_push=ะะพะทะฒะพะปะธัะธ Push
+settings.protect_enable_push=ะะพะทะฒะพะปะธัะธ push
settings.protect_enable_push_desc=ะัะดั-ั
ัะพ ัะท ะฟัะฐะฒะพะผ ะทะฐะฟะธัั ะทะผะพะถะต ะฒะธะบะพะฝัะฒะฐัะธ push ะดะปั ัััั ะณัะปะบะธ (ะทะฐ ะฒะธะบะปััะตะฝะฝัะผ force push).
settings.protect_whitelist_committers=ะัะปะธะน ัะฟะธัะพะบ ะพะฑะผะตะถะตะฝะฝั Push
settings.protect_whitelist_committers_desc=ะะธัะต ะบะพัะธัััะฒะฐัั ัะฐ ะบะพะผะฐะฝะดะธ ะท ะฑัะปะพะณะพ ัะฟะธัะบั ะทะผะพะถััั ะฒะธะบะพะฝัะฒะฐัะธ push ะฒ ััะน ะณัะปัั (ะทะฐ ะฒะธะบะปััะตะฝัะผ force push).
settings.protect_whitelist_deploy_keys=ะัะปะธะน ัะฟะธัะพะบ ะบะปัััะฒ ัะพะทะณะพััะฐะฝะฝั ะท ะฟัะฐะฒะพะผ ะฝะฐ ะทะฐะฟะธั.
-settings.protect_whitelist_users=ะะพัะธัััะฒะฐัั, ัะบั ะผะพะถััั ัะพะฑะธัะธ push ะฒ ัั ะณัะปะบั:
+settings.protect_whitelist_users=ะะพัะธัััะฒะฐัั, ัะบั ะผะพะถััั ัะพะฑะธัะธ push ะฒ ัั ะณัะปะบั
settings.protect_whitelist_search_users=ะะพััะบ ะบะพัะธัััะฒะฐััะฒโฆ
-settings.protect_whitelist_teams=ะะพะผะฐะฝะดะธ, ััะฐัะฝะธะบะธ ัะบะธั
ะผะพะถััั ัะพะฑะธัะธ push ะฒ ัั ะณัะปะบั:
+settings.protect_whitelist_teams=ะะพะผะฐะฝะดะธ, ััะฐัะฝะธะบะธ ัะบะธั
ะผะพะถััั ัะพะฑะธัะธ push ะฒ ัั ะณัะปะบั
settings.protect_whitelist_search_teams=ะะพััะบ ะบะพะผะฐะฝะดโฆ
-settings.protect_merge_whitelist_committers=ะะฑะผะตะถะธัะธ ะฟัะฐะฒะพ ะฝะฐ ะฟัะธะนะฝัััั Pull Request'ัะฒ ะฒ ัั ะณัะปะบั ัะฟะธัะบะพะผ
+settings.protect_merge_whitelist_committers=ะะฑะผะตะถะธัะธ ะฟัะฐะฒะพ ะฝะฐ ะพะฑ'ัะดะฝะฐะฝะฝั ัะฟะธัะบะพะผ
settings.protect_merge_whitelist_committers_desc=ะะธ ะผะพะถะตัะต ะดะพะดะฐะฒะฐัะธ ะบะพัะธัััะฒะฐััะฒ ะฐะฑะพ ััะปั ะบะพะผะฐะฝะดะธ ะฒ 'ะฑัะปะธะน' ัะฟะธัะพะบ ัััั ะณัะปะบะธ. ะขัะปัะบะธ ะฟัะธัััะฝั ะฒ ัะฟะธัะบั ะทะผะพะถััั ะฟัะธะนะผะฐัะธ ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั. ะ ัะฝัะพะผั ะฒะธะฟะฐะดะบั ะฑัะดั-ั
ัะพ ะท ะฟัะฐะฒะฐะผะธ ะทะฐะฟะธัั ะดะพ ะณะพะปะพะฒะฝะพะณะพ ัะตะฟะพะทะธัะพััั ะฑัะดะต ะฒะพะปะพะดััะธ ัะฐะบะพั ะผะพะถะปะธะฒัััั.
-settings.protect_merge_whitelist_users=ะะพัะธัััะฒะฐัั ะท ะฟัะฐะฒะพะผ ะฝะฐ ะฟัะธะนะฝัััั Pull Request'ัะฒ ะฒ ัั ะณัะปะบั:
-settings.protect_merge_whitelist_teams=ะะพะผะฐะฝะดะธ, ัะบะธะผ ะดะพะทะฒะพะปะตะฝะพ ะทะปะธััั:
+settings.protect_merge_whitelist_users=ะะพัะธัััะฒะฐัั ะท ะฟัะฐะฒะพะผ ะฝะฐ ะพะฑ'ัะดะฝะฐะฝะฝั
+settings.protect_merge_whitelist_teams=ะะพะผะฐะฝะดะธ, ัะบะธะผ ะดะพะทะฒะพะปะตะฝะพ ะพะฑ'ัะดะฝะฐะฝะฝั
settings.protect_check_status_contexts=ะฃะฒัะผะบะฝััะธ ะฟะตัะตะฒััะบั ััะฐะฝั
settings.protect_check_status_contexts_desc=ะะธะผะฐะณะฐัะธ ััะฟััะฝะพะณะพ ะฟัะพั
ะพะดะถะตะฝะฝั ะฟะตัะตะฒััะพะบ ััะฐะฝั ะฟะตัะตะด ะทะปะธัััะผ. ะะฑะตัััั ะฟะตัะตะฒััะบะธ ััะฐะฝั, ัะบั ัะปัะด ะฟัะพะฒะตััะธ ะดะปั ะณัะปะพะบ, ะฟะตัะตะด ัั
ะพะฑ'ัะดะฝะฐะฝะฝัะผ ะท ะณัะปะบะพั, ัะพ ะฒัะดะฟะพะฒัะดะฐั ััะพะผั ะฟัะฐะฒะธะปั. ะะพะปะธ ัะตะน ะฟัะฝะบั ัะฒัะผะบะฝะตะฝะพ, ะบะพะผััะธ ัะฟะตััั ะฝะฐะดัะธะปะฐััััั ะดะพ ัะฝัะพั ะณัะปะบะธ, ะฐ ะฟะพััะผ ะทะปะธะฒะฐััััั ะฐะฑะพ ะฝะฐะดัะธะปะฐััััั ะฑะตะทะฟะพัะตัะตะดะฝัะพ ะดะพ ะณัะปะบะธ, ัะบะฐ ะฒัะดะฟะพะฒัะดะฐั ััะพะผั ะฟัะฐะฒะธะปั ะฟััะปั ััะฟััะฝะพะณะพ ะฟัะพั
ะพะดะถะตะฝะฝั ะฟะตัะตะฒััะพะบ ััะฐะฝั. ะฏะบัะพ ะฝะต ะฒะธะฑัะฐะฝะพ ะบะพะฝัะตะบัั, ะพััะฐะฝะฝัะน ะบะพะผัั ะผะฐั ััะฟััะฝะพ ะฟัะพั
ะพะดะธัะธ ะฟะตัะตะฒััะบะธ, ะฝะตะทะฐะปะตะถะฝะพ ะฒัะด ะบะพะฝัะตะบััั.
settings.protect_check_status_contexts_list=ะะตัะตะฒััะบะธ ััะฐัััั ะทะฝะฐะนะดะตะฝะพ ะดะปั ัะตะฟะพะทะธัะฐััั ะทะฐ ะผะธะฝัะปะธะน ัะธะถะดะตะฝั
-settings.protect_required_approvals=ะะตะพะฑั
ัะดะฝะพ ัั
ะฒะฐะปะตะฝะฝั:
+settings.protect_required_approvals=ะะตะพะฑั
ัะดะฝะพ ัั
ะฒะฐะปะตะฝะฝั
settings.protect_required_approvals_desc=ะะพะทะฒะพะปะธัะธ ะพะฑ'ัะดะฝะฐะฝะฝั ะทะฐะฟะธััะฒ ะฝะฐ ะทะปะธััั ะปะธัะต ัะท ะดะพััะฐัะฝัะพั ะบัะปัะบัััั ะฟะพะทะธัะธะฒะฝะธั
ัะตัะตะฝะทัะน.
settings.protect_approvals_whitelist_enabled=ะะฑะผะตะถะธัะธ ัั
ะฒะฐะปะตะฝะฝั ะบะพัะธัััะฒะฐัะฐะผะธ ัะฐ ะบะพะผะฐะฝะดะฐะผะธ ะท ะฑัะปะพะณะพ ัะฟะธัะบั
settings.protect_approvals_whitelist_enabled_desc=ะะธัะต ัะตัะตะฝะทัั ะบะพัะธัััะฒะฐััะฒ ัะฐ ะบะพะผะฐะฝะด ะฒ ะฑัะปะพะผั ัะฟะธัะบั ะฒะฟะปะธะฒะฐััั ะฝะฐ ัะธัะปะพ ะพััะธะผะฐะฝะธั
ะทะฐัะฒะตัะดะถะตะฝั. ะะตะท ะฑัะปะพะณะพ ัะฟะธัะบั ะฑัะดััั ะฒัะฐั
ะพะฒะฐะฝั ัะตัะตะฝะทัั ะฑัะดั-ะบะพะณะพ ัะท ะดะพัััะฟะพะผ ะฝะฐ ะทะฐะฟะธั.
-settings.protect_approvals_whitelist_users=ะัะปะธะน ัะฟะธัะพะบ ัะตัะตะฝะทะตะฝััะฒ:
-settings.protect_approvals_whitelist_teams=ะัะปะธะน ัะฟะธัะพะบ ะบะพะผะฐะฝะด ัะตัะตะฝะทะตะฝััะฒ:
+settings.protect_approvals_whitelist_users=ะัะปะธะน ัะฟะธัะพะบ ัะตัะตะฝะทะตะฝััะฒ
+settings.protect_approvals_whitelist_teams=ะัะปะธะน ัะฟะธัะพะบ ะบะพะผะฐะฝะด ัะตัะตะฝะทะตะฝััะฒ
settings.dismiss_stale_approvals=ะัะดั
ะธะปะธัะธ ะทะฐััะฐััะปั ะฟะพะณะพะดะถะตะฝะฝั
settings.dismiss_stale_approvals_desc=ะะพะปะธ ะฝะพะฒั ะบะพะผััะธ ัะพ ะทะผัะฝัััั ะฒะผััั ะฟัะปะป-ะทะฐะฟะธัั ะฒัะดะฟัะฐะฒะปัััััั ะฒ ะณัะปะบั, ััะฐัั ะฟะพะณะพะดะถะตะฝะฝั ะฑัะดััั ะฒัะดั
ะธะปะตะฝั.
-settings.require_signed_commits=ะะพัััะฑะฝะพ ะฟัะดะฟะธัะฐะฝั ะบะพะผััะธ
+settings.require_signed_commits=ะะธะผะฐะณะฐัะธ ะฟัะดะฟะธั ะบะพะผัััะฒ
settings.require_signed_commits_desc=ะัะดั
ะธะปััะธ push ะดะพ ัััั ะณัะปะบะธ, ัะบัะพ ะฒะพะฝะธ ะฝะต ะฟัะดะฟะธัะฐะฝั ะฐะฑะพ ะฟัะดะฟะธั ะฝะตะผะพะถะปะธะฒะพ ะฟะตัะตะฒััะธัะธ.
settings.add_protected_branch=ะฃะฒัะผะบะฝััะธ ะทะฐั
ะธัั
settings.delete_protected_branch=ะะธะผะบะฝััะธ ะทะฐั
ะธัั
-settings.protected_branch_deletion=ะัะดะบะปััะธัะธ ะทะฐั
ะธัั ะณัะปะบะธ
+settings.protected_branch_deletion=ะะธะผะบะฝััะธ ะทะฐั
ะธัั ะณัะปะบะธ
settings.protected_branch_deletion_desc=ะัะดั-ัะบะธะน ะบะพัะธัััะฒะฐั ะท ะดะพะทะฒะพะปะฐะผะธ ะฝะฐ ะทะฐะฟะธั ะทะผะพะถะต ะฒะธะบะพะฝัะฒะฐัะธ push ะฒ ัั ะณัะปะบั. ะะธ ะฒะฟะตะฒะฝะตะฝั?
settings.block_rejected_reviews=ะะปะพะบัะฒะฐัะธ ะทะปะธััั ะฟัะธ ะฒัะดะบะธะดะฐััะธั
ัะตัะตะฝะทััั
settings.block_rejected_reviews_desc=ะะปะธััั ะฑัะดะต ะฝะตะดะพัััะฟะฝะธะผ, ัะบัะพ ั ะทะฐะฟะธั ะทะผัะฝ ะฒัะด ะพััััะนะฝะธั
ัะตัะตะฝะทะตะฝััะฒ, ะฝะฐะฒััั ะทะฐ ะฝะฐัะฒะฝะพััั ะดะพััะฐัะฝัะพั ะบัะปัะบะพััั ัั
ะฒะฐะปะตะฝั.
@@ -1858,32 +2150,32 @@ settings.block_on_official_review_requests_desc=ะะฑโัะดะฝะฐะฝะฝั ะฝะตะผะพะถ
settings.block_outdated_branch=ะะปะพะบัะฒะฐัะธ ะทะปะธััั, ัะบัะพ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั ะทะฐััะฐััะฒ
settings.block_outdated_branch_desc=ะะปะธััั ะฑัะดะต ะฝะตะผะพะถะปะธะฒะธะผ, ะบะพะปะธ ะณะพะปะพะฒะฝะฐ ะณัะปะบะฐ ะฟะพะทะฐะดั ะพัะฝะพะฒะฝะพั.
settings.default_branch_desc=ะะพะปะพะฒะฝะฐ ะณัะปะบะฐ ั 'ะฑะฐะทะพะฒะพั' ะดะปั ะฒะฐัะพะณะพ ัะตะฟะพะทะธัะพััั, ะฝะฐ ัะบั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ัะฟััะผะพะฒะฐะฝั ะฒัั ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั ั ัะบะฐ ั ะพะฑะปะธัััะผ ะฒะฐัะพะณะพ ัะตะฟะพะทะธัะพััั. ะะตััะต, ัะพ ะฟะพะฑะฐัะธัั ะฒัะดะฒัะดัะฒะฐั - ัะต ะทะผััั ะณะพะปะพะฒะฝะพั ะณัะปะบะธ. ะะธะฑะตัััั ัั ะท ัะถะต ััะฝัััะธั
:
-settings.default_merge_style_desc=ะกัะธะปั ะทะปะธััั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ:
+settings.default_merge_style_desc=ะกัะธะปั ะพะฑ'ัะดะฝะฐะฝะฝั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
settings.choose_branch=ะะฑะตัััั ะณัะปะบัโฆ
settings.no_protected_branch=ะะตะผะฐั ะทะฐั
ะธัะตะฝะธั
ะณัะปะพะบ.
settings.edit_protected_branch=ะ ะตะดะฐะณัะฒะฐัะธ
settings.protected_branch_required_approvals_min=ะงะธัะปะพ ะฝะตะพะฑั
ัะดะฝะธั
ัั
ะฒะฐะปะตะฝั ะฝะต ะผะพะถะต ะฑััะธ ะฒัะด'ัะผะฝะธะผ.
-settings.tags=ะััะบะธ
-settings.tags.protection=ะะฐั
ะธัั ะผััะบะธ
+settings.tags=ะขะตะณะธ
+settings.tags.protection=ะะฐั
ะธัั ัะตะณั
settings.tags.protection.pattern=ะจะฐะฑะปะพะฝ ัะตะณะฐ
settings.tags.protection.allowed=ะะพะทะฒะพะปะตะฝะพ
settings.tags.protection.allowed.users=ะะพะทะฒะพะปะตะฝั ะบะพัะธัััะฒะฐัั
settings.tags.protection.allowed.teams=ะะพะทะฒะพะปะตะฝั ะบะพะผะฐะฝะดะธ
settings.tags.protection.allowed.noone=ะัั
ัะพ
-settings.tags.protection.create=ะะฐั
ะธััะฝะฐ ะผััะบะฐ
+settings.tags.protection.create=ะะพะดะฐัะธ ะฟัะฐะฒะธะปะพ
settings.tags.protection.none=ะขะฐะผ ะฝะต ะฝะตะผะฐั ะทะฐั
ะธัะตะฝะธั
ะผััะพะบ.
settings.bot_token=ะขะพะบะตะฝ ะดะปั ะฑะพัะฐ
settings.chat_id=ะงะฐั ID
settings.matrix.homeserver_url=URL ะดะพะผะฐัะฝัะพั ััะพััะฝะบะธ
settings.matrix.room_id=ะะพะผะตั ะบัะผะฝะฐัะธ
settings.matrix.message_type=ะขะธะฟ ะฟะพะฒัะดะพะผะปะตะฝะฝั
-settings.archive.button=ะัั
ัะฒะฝะธะน ัะตะฟะพะทะธัะพััะน
-settings.archive.header=ะัะดะฟัะฐะฒะธัะธ ัะตะฟะพะทะธัะพััะน ะฒ ะฐัั
ัะฒ
+settings.archive.button=ะัั
ัะฒัะฒะฐัะธ ัะตะฟะพะทะธัะพััะน
+settings.archive.header=ะัั
ัะฒัะฒะฐัะธ ัะตะน ัะตะฟะพะทะธัะพััะน
settings.archive.success=ะ ะตะฟะพะทะธัะพััั ััะฟััะฝะพ ะฟัะธัะฒะพัะฝะพ ััะฐััั ะฐัั
ัะฒะฝะพะณะพ.
settings.archive.error=ะกัะฐะปะฐัั ะฟะพะผะธะปะบะฐ ะฟัะธ ัะฟัะพะฑั ะฐัั
ัะฒัะฒะฐัะธ ัะตะฟะพะทะธัะพััะน. ะะพะบะปะฐะดะฝััั ัะฝัะพัะผะฐััั ะดะธะฒ. ั ะถััะฝะฐะปั.
settings.archive.error_ismirror=ะะตะผะพะถะปะธะฒะพ ะฐัั
ัะฒัะฒะฐัะธ ะดะทะตัะบะฐะปัะฝะธะน ัะตะฟะพะทะธัะพัััะน.
-settings.archive.branchsettings_unavailable=ะะฐัะฐะผะตััะธ ะณัะปะบะธ ะฝะต ะดะพัััะฟะฝั, ัะบัะพ ัะตะฟะพะทะธัะพััะน ะฐัั
ัะฒะฝะธะน.
-settings.archive.tagsettings_unavailable=ะะฐัะฐะผะตััะธ ะผััะพะบ ะฝะตะดะพัััะฟะฝั, ัะบัะพ ัะตะฟะพะทะธัะพััะน ะฐัั
ัะฒะฝะธะน.
+settings.archive.branchsettings_unavailable=ะะฐัะฐะผะตััะธ ะณัะปะบะธ ะฝะตะดะพัััะฟะฝั ะฒ ะฐัั
ัะฒะพะฒะฐะฝะธั
ัะตะฟะพะทะธัะพัััั
.
+settings.archive.tagsettings_unavailable=ะะฐัะฐะผะตััะธ ัะตะณัะฒ ะฝะตะดะพัััะฟะฝั ะฒ ะฐัั
ัะฒะพะฒะฐะฝะธั
ัะตะฟะพะทะธัะพัััั
.
settings.update_avatar_success=ะะฒะฐัะฐั ัะตะฟะพะทะธัะพััั ะพะฝะพะฒะปะตะฝะธะน.
settings.lfs=LFS
settings.lfs_filelist=ะคะฐะนะปะธ LFS, ัะบั ะทะฑะตััะณะฐััััั ะฒ ััะพะผั ัะตะฟะพะทะธัะพััั
@@ -1892,21 +2184,21 @@ settings.lfs_findcommits=ะะฝะฐะนัะธ ะบะพะผััะธ
settings.lfs_lfs_file_no_commits=ะะต ะทะฝะฐะนะดะตะฝะพ ะบะพะผัััะฒ ะดะปั ััะพะณะพ ัะฐะนะปั LFS
settings.lfs_noattribute=ะฆะตะน ัะปัั
ะฝะต ะผะฐั ะฐััะธะฑััั ะฑะปะพะบัะฒะฐะฝะฝั ะฒ ะณัะปัั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
settings.lfs_delete=ะะธะดะฐะปะธัะธ ัะฐะนะป LFS ะท OID %s
-settings.lfs_delete_warning=ะะธะดะฐะปะตะฝะฝั ัะฐะนะปั LFS ะผะพะถะต ัะฟัะธัะธะฝะธัะธ ะฟะพะผะธะปะบะธ "ะะฑ'ัะบั ะฝะต ััะฝัั" ะฟัะด ัะฐั ะฟะตัะตะฒััะบะธ. ะะธ ะฒะฟะตะฒะฝะตะฝั?
+settings.lfs_delete_warning=ะะธะดะฐะปะตะฝะฝั ัะฐะนะปั LFS ะผะพะถะต ัะฟัะธัะธะฝะธัะธ ะฟะพะผะธะปะบะธ ยซะะฑ'ัะบั ะฝะต ััะฝััยป ะฟัะด ัะฐั ะฟะตัะตะฒััะบะธ. ะะธ ะฒะฟะตะฒะฝะตะฝั?
settings.lfs_findpointerfiles=ะะฝะฐะนัะธ ัะฐะนะปะธ-ะฟะพัะธะปะฐะฝะฝั
settings.lfs_locks=ะะปะพะบัะฒะฐะฝะฝั
settings.lfs_invalid_locking_path=ะะตะฟัะธะฟัััะธะผะธะน ัะปัั
: %s
settings.lfs_invalid_lock_directory=ะะต ะผะพะถะปะธะฒะพ ะทะฐะฑะปะพะบัะฒะฐัะธ ะบะฐัะฐะปะพะณ: %s
settings.lfs_lock_already_exists=ะะปะพะบัะฒะฐะฝะฝั ะฒะถะต ะฒะธะบะพัะธััะพะฒัััััั: %s
settings.lfs_lock=ะะปะพะบัะฒะฐัะธ
-settings.lfs_lock_path=ะจะปัั
ะดะพ ัะฐะนะปั ะดะปั ะฑะปะพะบัะฒะฐะฝะฝั...
-settings.lfs_locks_no_locks=ะัะดัััะฝั ะฑะปะพะบัะฒะฐะฝะฝั
+settings.lfs_lock_path=ะจะปัั
ะดะพ ัะฐะนะปั ะดะปั ะฑะปะพะบัะฒะฐะฝะฝัโฆ
+settings.lfs_locks_no_locks=ะะตะผะฐั ะฑะปะพะบัะฒะฐะฝั
settings.lfs_lock_file_no_exist=ะะฐะฑะปะพะบะพะฒะฐะฝะธะน ัะฐะนะป ะฝะต ััะฝัั ั ะณัะปัั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
settings.lfs_force_unlock=ะัะธะผััะพะฒะต ัะพะทะฑะปะพะบัะฒะฐะฝะฝั
settings.lfs_pointers.found=ะะฝะฐะนะดะตะฝะพ %d ะฟะพัะธะปะฐะฝั ะฝะฐ blob - %d ะฟะพะฒ'ัะทะฐะฝะธั
, %d ะฝะตะฟะพะฒ'ัะทะฐะฝะธั
(%d ะฒัะดัััะฝั ั ัั
ะพะฒะธัั)
settings.lfs_pointers.sha=Blob SHA
settings.lfs_pointers.oid=OID
-settings.lfs_pointers.inRepo=ะ ัะตะฟะพะทะธัะพััั
+settings.lfs_pointers.inRepo=ะฃ ัะตะฟะพะทะธัะพััั
settings.lfs_pointers.exists=ะะฐัะฒะฝะธะน ั ัั
ะพะฒะธัั
settings.lfs_pointers.accessible=ะะพัััะฟะฝะธะน ะดะปั ะบะพัะธัััะฒะฐัะฐ
settings.lfs_pointers.associateAccessible=ะะพะฒ'ัะทะฐัะธ ะดะพัััะฟะฝั %d OID
@@ -1951,12 +2243,12 @@ diff.load=ะะฐะฒะฐะฝัะฐะถะธัะธ ััะทะฝะธัั
diff.generated=ะทะณะตะฝะตัะพะฒะฐะฝะธะน
diff.vendored=ััะพัะพะฝะฝัะน
diff.comment.placeholder=ะะฐะปะธัะธัะธ ะบะพะผะตะฝัะฐั
-diff.comment.markdown_info=ะกัะธะปัะทะฐััั ะท markdown ะฟัะดััะธะผัััััั.
+diff.comment.markdown_info=ะัะดััะธะผัััััั ัะพะทะผััะบะฐ Markdown.
diff.comment.add_single_comment=ะะพะดะฐัะธ ะฟัะพััะธะน ะบะพะผะตะฝัะฐั
diff.comment.add_review_comment=ะะพะดะฐัะธ ะบะพะผะตะฝัะฐั
diff.comment.start_review=ะ ะพะทะฟะพัะฐัะธ ัะตัะตะฝะทัั
diff.comment.reply=ะัะดะฟะพะฒัะดั
-diff.review=ะ ะตัะตะฝะทัั
+diff.review=ะะฐะฒะตััะธัะธ ะฒัะดะณัะบ
diff.review.header=ะะฐะดััะปะฐัะธ ัะตัะตะฝะทัั
diff.review.placeholder=ะ ะตัะตะฝะทัะนะพะฒะฐะฝะธะน ะบะพะผะตะฝัะฐััะน
diff.review.comment=ะะพะผะตะฝัะฐั
@@ -1972,15 +2264,15 @@ releases.desc=ะัะดัะปัะดะบะพะฒัะฒะฐัะธ ะฒะตัััั ะฟัะพัะบัั ั ะทะฐ
release.releases=ะ ะตะปัะทะธ
release.detail=ะะตัะฐะปั ัะตะปัะทั
release.tags=ะขะตะณะธ
-release.new_release=ะะพะฒะธะน ัะตะปัะท
+release.new_release=ะะพะฒะธะน ะฒะธะฟััะบ
release.draft=ะงะตัะฝะตัะบะฐ
release.prerelease=ะัะต-ัะตะปัะท
release.stable=ะกัะฐะฑัะปัะฝะธะน
release.compare=ะะพััะฒะฝััะธ
-release.edit=ัะตะดะฐะณัะฒะฐัะธ
+release.edit=ะ ะตะดะฐะณัะฒะฐัะธ
release.ahead.commits=%d ะบะพะผัั(ัะฒ)
release.ahead.target=ะดะพ %s ะท ะผะพะผะตะฝัั ััะพะณะพ ะฒะธะฟััะบั
-release.source_code=ะะพะด
+release.source_code=ะะธั
ัะดะฝะธะน ะบะพะด
release.new_subheader=ะัะฑะปัะบะฐััั ัะตะปัะทัะฒ ะดะพะฟะพะผะพะถะต ะฒะฐะผ ะพัะณะฐะฝัะทัะฒะฐัะธ ะฒะตัััั ะฟัะพัะบัั.
release.edit_subheader=ะัะฑะปัะบะฐััั ัะตะปัะทัะฒ ะดะพะฟะพะผะพะถะต ะฒะฐะผ ะพัะณะฐะฝัะทัะฒะฐัะธ ะฒะตัััั ะฟัะพัะบัั.
release.tag_name=ะะฐะทะฒะฐ ัะตะณั
@@ -1997,20 +2289,20 @@ release.delete_tag=ะะธะดะฐะปะธัะธ ัะตะณ
release.deletion=ะะธะดะฐะปะธัะธ ัะตะปัะท
release.deletion_success=ะ ะตะปัะท, ะฑัะปะพ ะฒะธะดะฐะปะตะฝะพ.
release.deletion_tag_desc=ะัะดะต ะฒะธะดะฐะปะตะฝะพ ัะตะน ัะตะณ ัะท ัะตะฟะพะทะธัะพััั. ะะผััั ัะตะฟะพะทะธัะพััั ัะฐ ัััะพััั ะทะฐะปะธัะฐัััั ะฝะตะทะผัะฝะฝะธะผะธ. ะัะพะดะพะฒะถะธัะธ?
-release.deletion_tag_success=ะััะบะฐ ะฒะธะดะฐะปะตะฝะฐ.
-release.tag_name_already_exist=ะ ะตะปัะท ะท ัะธะผ ัะผ'ัะผ ะผััะบะธ ะฒะถะต ััะฝัั.
+release.deletion_tag_success=ะขะตะณ ะฒะธะดะฐะปะตะฝะพ.
+release.tag_name_already_exist=ะะธะฟััะบ ัะท ัะฐะบะพั ะฝะฐะทะฒะพั ัะตะณั ะฒะถะต ััะฝัั.
release.tag_name_invalid=ะะตะฟัะธะฟัััะธะผะต ัะผ'ั ัะตะณะฐ.
release.tag_name_protected=ะะผ'ั ัะตะณะฐ ะทะฐั
ะธัะตะฝะต.
release.tag_already_exist=ะฆะตะน ัะตะณ ะฒะถะต ะฒะธะบะพัะธััะพะฒัััััั.
release.downloads=ะะฐะฒะฐะฝัะฐะถะธัะธ
release.download_count=ะะฐะฒะฐะฝัะฐะถะตะฝะฝั: %s
release.add_tag_msg=ะะธะบะพัะธััะพะฒัะนัะต ะทะฐะณะพะปะพะฒะพะบ ั ะทะผััั ัะตะปัะทั ัะบ ะฟะพะฒัะดะพะผะปะตะฝะฝั ัะบ ัะตะณ ะฟะพะฒัะดะพะผะปะตะฝะฝั.
-release.add_tag=ะกัะฒะพัะธัะธ ััะปัะบะธ ะผััะบั
+release.add_tag=ะกัะฒะพัะธัะธ ัะตะณ
-branch.name=ะะผ'ั ะณัะปะบะธ
+branch.name=ะะฐะทะฒะฐ ะณัะปะบะธ
branch.delete_head=ะะธะดะฐะปะธัะธ
branch.delete_html=ะะธะดะฐะปะธัะธ ะณัะปะบั
-branch.create_branch=ะกัะฒะพัะธัะธ ะณัะปะบั %s
+branch.create_branch=ะกัะฒะพัะธัะธ ะณัะปะบั %s
branch.deleted_by=ะะธะดะฐะปะตะฝะพ %s
branch.included_desc=ะฆั ะณัะปะบะฐ ั ัะฐััะธะฝะพั ัะธะฟะพะฒะพั ะณัะปะบะธ
branch.included=ะะบะปััะตะฝะพ
@@ -2021,7 +2313,7 @@ branch.create_branch_operation=ะกัะฒะพัะธัะธ ะณัะปะบั
branch.new_branch=ะกัะฒะพัะธัะธ ะฝะพะฒั ะณัะปะบั
branch.renamed=ะัะปะบั %s ะฟะตัะตะนะผะตะฝะพะฒะฐะฝะพ ะฝะฐ %s.
-tag.create_tag=ะกัะฒะพัะธัะธ ัะตะณ %s
+tag.create_tag=ะกัะฒะพัะธัะธ ัะตะณ %s
topic.manage_topics=ะะตััะฒะฐัะธ ัะตะผะฐัะธัะฝะธะผะธ ะผััะบะฐะผะธ
@@ -2040,9 +2332,9 @@ issues.filter_milestone_open = ะัะดะบัะธัั ะตัะฐะฟะธ
issues.filter_milestone_closed = ะะฐะบัะธัั ะตัะฐะฟะธ
issues.filter_milestone_all = ะฃัั ะตัะฐะฟะธ
issues.filter_milestone_none = ะะตะท ะตัะฐะฟั
-issues.filter_poster_no_select = ะัั ะฐะฒัะพัะธ
+issues.filter_poster_no_select = ะฃัั ะฐะฒัะพัะธ
pulls.merged_info_text = ะัะปะบั %s ัะตะฟะตั ะผะพะถะฝะฐ ะฒะธะดะฐะปะธัะธ.
-find_file.go_to_file = ะะตัะตะนัะธ ะดะพ ัะฐะนะปั
+find_file.go_to_file = ะะฝะฐะนัะธ ัะฐะนะป
visibility_helper = ะัะพะฑะธัะธ ัะตะฟะพะทะธัะพััะน ะฟัะธะฒะฐัะฝะธะผ
projects.card_type.desc = ะะพะฟะตัะตะดะฝัะน ะฒะธะณะปัะด ะบะฐััะพะบ
projects.card_type.text_only = ะะธัะต ัะตะบัั
@@ -2053,7 +2345,7 @@ issues.author_helper = ะฆะตะน ะบะพัะธัััะฒะฐั - ะฐะฒัะพั.
issues.close = ะะฐะบัะธัะธ ะทะฐะดะฐัั
issues.role.owner_helper = ะฆะตะน ะบะพัะธัััะฒะฐั ั ะฒะปะฐัะฝะธะบะพะผ ััะพะณะพ ัะตะฟะพะทะธัะพััั.
settings.mirror_settings.docs.more_information_if_disabled = ะะพะบะปะฐะดะฝััะต ะฟัะพ push ัะฐ pull ะดะทะตัะบะฐะปะฐ ะผะพะถะฝะฐ ะดัะทะฝะฐัะธัั ััั:
-issues.comment.blocked_by_user = ะะธ ะฝะต ะผะพะถะตัะต ััะฒะพัะธัะธ ะบะพะผะตะฝัะฐั ะดะพ ัััั ะทะฐะดะฐัั, ะพัะบัะปัะบะธ ะฒะฐั ะทะฐะฑะปะพะบัะฒะฐะฒ ะฒะปะฐัะฝะธะบ ัะตะฟะพะทะธัะพััั ะฐะฑะพ ะฐะฒัะพั ัััั ะทะฐะดะฐัั.
+issues.comment.blocked_by_user = ะะธ ะฝะต ะผะพะถะตัะต ะบะพะผะตะฝััะฒะฐัะธ ัั ะทะฐะดะฐัั, ะพัะบัะปัะบะธ ะฒะฐั ะทะฐะฑะปะพะบัะฒะฐะฒ ะฒะปะฐัะฝะธะบ ัะตะฟะพะทะธัะพััั ะฐะฑะพ ะฐะฒัะพั ัััั ะทะฐะดะฐัั.
editor.add_file = ะะพะดะฐัะธ ัะฐะนะป
from_comment = (ะบะพะผะตะฝัะฐั)
editor.add = ะะพะดะฐัะธ %s
@@ -2070,8 +2362,315 @@ commit.cherry-pick-header = ะะธัะผะธะบะฝััะธ: %s
commit.cherry-pick-content = ะะฑะตัััั ะณัะปะบั, ะฝะฐ ัะบั ะฒะธัะผะธะบะฝััะธ:
pulls.expand_files = ะ ะพะทะณะพัะฝััะธ ะฒัั ัะฐะนะปะธ
pulls.collapse_files = ะะณะพัะฝััะธ ะฒัั ัะฐะนะปะธ
+settings.packages_desc = ะฃะฒัะผะบะฝััะธ ัะตัััั ะฟะฐะบัะฝะบัะฒ ัะตะฟะพะทะธัะพััั
+issues.role.contributor_helper = ะฃ ััะพะผั ัะตะฟะพะทะธัะพััั ั ะบะพะผััะธ ััะพะณะพ ะบะพัะธัััะฒะฐัะฐ.
+contributors.contribution_type.deletions = ะะธะดะฐะปะตะฝะฝั
+contributors.contribution_type.filter_label = ะะธะด ะฒะฝะตัะบั:
+issues.role.contributor = ะฃัะฐัะฝะธะบ ัะพะทัะพะฑะบะธ
+activity.navbar.contributors = ะฃัะฐัะฝะธะบะธ ัะพะทัะพะฑะบะธ
+settings.protected_branch.save_rule = ะะฑะตัะตะณัะธ ะฟัะฐะฒะธะปะพ
+release.tags_for = ะขะตะณะธ %s
+editor.file_is_a_symlink = `ยซ%sยป โ ัะธะผะฒะพะปัะฝะต ะฟะพัะธะปะฐะฝะฝั. ะกะธะผะฒะพะปัะฝั ะฟะพัะธะปะฐะฝะฝั ะฝะต ะผะพะถะฝะฐ ัะตะดะฐะณัะฒะฐัะธ ั ะฒะตะฑัะตะดะฐะบัะพัั`
+settings.sourcehut_builds.secrets = ะกะตะบัะตัะธ
+settings.web_hook_name_feishu_only = Feishu
+settings.web_hook_name_gogs = Gogs
+settings.web_hook_name_dingtalk = DingTalk
+settings.web_hook_name_feishu = Feishu / Lark Suite
+settings.web_hook_name_gitea = Gitea
+issues.dependency.no_permission.can_remove = ะฃ ะฒะฐั ะฝะตะผะฐั ะดะพะทะฒะพะปั ัะธัะฐัะธ ัั ะทะฐะปะตะถะฝัััั, ะฐะปะต ะฒะธ ะผะพะถะตัะต ัั ะฒะธะดะฐะปะธัะธ
+issues.filter_label_select_no_label = ะะตะท ะผััะบะธ
+settings.web_hook_name_msteams = Microsoft Teams
+issues.all_title = ะฃัั
+settings.web_hook_name_packagist = Packagist
+settings.packagist_username = ะะผ'ั ะบะพัะธัััะฒะฐัะฐ Packagist
+settings.web_hook_name_matrix = Matrix
+issues.dependency.issue_no_dependencies = ะะฐะปะตะถะฝะพััะตะน ะฝะต ะฒััะฐะฝะพะฒะปะตะฝะพ.
+issues.dependency.pr_no_dependencies = ะะฐะปะตะถะฝะพััะตะน ะฝะต ะฒััะฐะฝะพะฒะปะตะฝะพ.
+issues.dependency.no_permission_1 = ะฃ ะฒะฐั ะฝะตะผะฐั ะดะพะทะฒะพะปั ัะธัะฐัะธ ะทะฐะปะตะถะฝัััั %d
+issues.dependency.no_permission_n = ะฃ ะฒะฐั ะฝะตะผะฐั ะดะพะทะฒะพะปั ัะธัะฐัะธ ะทะฐะปะตะถะฝะพััั %d
+settings.web_hook_name_larksuite_only = Lark Suite
+issues.filter_project_all = ะฃัั ะฟัะพัะบัะธ
+issues.num_comments_1 = %d ะบะพะผะตะฝัะฐั
+settings.web_hook_name_sourcehut_builds = ะะฑััะบะธ SourceHut
+settings.web_hook_name_slack = Slack
+settings.web_hook_name_discord = ะะธัะบะพัะด
+settings.web_hook_name_forgejo = Forgejo
+settings.web_hook_name_wechatwork = WeCom (Wechat Work)
+migrate.migrating_failed.error = ะัะณัะฐััั ะฝะต ะฒะดะฐะปะฐัั: %s
+all_branches = ะฃัั ะณัะปะบะธ
+migrate.forgejo.description = ะะตัะตะฝะตััะธ ะดะฐะฝั ะท codeberg.org ะฐะฑะพ ัะฝัะธั
ะตะบะทะตะผะฟะปัััะฒ Forgejo.
+settings.tracker_issue_style.regexp_pattern = ะจะฐะฑะปะพะฝ ัะตะณัะปััะฝะพะณะพ ะฒะธัะฐะทั
+settings.tracker_issue_style.regexp = ะ ะตะณัะปััะฝะธะน ะฒะธัะฐะท
+release.download_count_one = %s ะทะฐะฒะฐะฝัะฐะถะตะฝะฝั
+release.download_count_few = %s ะทะฐะฒะฐะฝัะฐะถะตะฝั
+release.invalid_external_url = ะะตะฟัะฐะฒะธะปัะฝะฐ ะทะพะฒะฝััะฝั URL-ะฐะดัะตัะฐ: ยซ%sยป
+issues.role.collaborator_helper = ะฆัะพะณะพ ะบะพัะธัััะฒะฐัะฐ ะทะฐะฟัะพัะตะฝะพ ะดะพ ัะฟัะฒะฟัะฐัั ะฝะฐะด ัะตะฟะพะทะธัะพัััะผ.
+settings.add_collaborator_owner = ะะตะผะพะถะปะธะฒะพ ะดะพะดะฐัะธ ะฒะปะฐัะฝะธะบะฐ ะฒ ัะบะพััั ัะฟัะฒะฐะฒัะพัะฐ.
+settings.protect_status_check_patterns = ะจะฐะฑะปะพะฝะธ ะฟะตัะตะฒััะบะธ ััะฐะฝั
+issues.role.collaborator = ะกะฟัะฒะฐะฒัะพั
+pulls.auto_merge_cancel_schedule = ะกะบะฐััะฒะฐัะธ ะฐะฒัะพะผะฐัะธัะฝะต ะพะฑ'ัะดะฝะฐะฝะฝั
+issues.comment_pull_merged_at = ะพะฑ'ัะดะฝะฐะฒ ะบะพะผัั %[1]s ะฒ %[2]s %[3]s
+pulls.title_desc_one = ั
ะพัะต ะพะฑ'ัะดะฝะฐัะธ %[1]d ะบะพะผัั ะท %[2]s
ะฒ %[3]s
+settings.merge_style_desc = ะกัะธะปั ะพะฑ'ัะดะฝะฐะฝะฝั
+pulls.auto_merge_when_succeed = ะะฑ'ัะดะฝัะฒะฐัะธ ะฐะฒัะพะผะฐัะธัะฝะพ, ัะบัะพ ะฒัั ะฟะตัะตะฒััะบะธ ะฟัะพั
ะพะดััั ััะฟััะฝะพ
+pulls.cmd_instruction_merge_title = ะะฑ'ัะดะฝะฐะฝะฝั
+settings.protect_enable_merge = ะฃะฒัะผะบะฝััะธ ะพะฑ'ัะดะฝะฐะฝะฝั
+pulls.merged_success = ะะฐะฟะธั ะฝะฐ ะทะปะธััั ััะฟััะฝะพ ะพะฑ'ัะดะฝะฐะฝะพ ั ะทะฐะบัะธัะพ
+pulls.auto_merge_button_when_succeed = (ะฏะบัะพ ะฟะตัะตะฒััะบะธ ะฟัะพั
ะพะดััั ััะฟััะฝะพ)
+editor.commit_id_not_matching = ะคะฐะนะป ะฑัะปะพ ะทะผัะฝะตะฝะพ, ะฟะพะบะธ ะฒะธ ะนะพะณะพ ัะตะดะฐะณัะฒะฐะปะธ. ะัะพะฑััั ะบะพะผัั ั ะฝะพะฒั ะณัะปะบั, ะฐ ะฟะพััะผ ะพะฑ'ัะดะฝะฐะนัะต.
+settings.event_pull_request_merge = ะะฑ'ัะดะฝะฐะฝะฝั ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั
+pulls.auto_merge_canceled_schedule = ะะฒัะพะผะฐัะธัะฝะต ะพะฑ'ัะดะฝะฐะฝะฝั ัะบะฐัะพะฒะฐะฝะพ ะดะปั ััะพะณะพ ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั.
+pulls.auto_merge_not_scheduled = ะฆะตะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั ะฝะต ะทะฐะฟะปะฐะฝะพะฒะฐะฝะพ ะดะปั ะฐะฒัะพะผะฐัะธัะฝะพะณะพ ะพะฑ'ัะดะฝะฐะฝะฝั.
+pulls.merged_title_desc_one = ะพะฑ'ัะดะฝะฐะฒ %[1]d ะบะพะผัั ะท %[2]s
ะฒ %[3]s
%[4]s
+pulls.fast_forward_only_merge_pull_request = ะขัะปัะบะธ fast-forward
+pulls.merged_by = ะฒัะด %[3]s ะพะฑ'ัะดะฝะฐะฝะพ %[1]s
+issues.comment_manually_pull_merged_at = ะฒัััะฝั ะพะฑ'ัะดะฝะฐะฒ ะบะพะผัั %[1]s ะฒ %[2]s %[3]s
+pulls.merged_by_fake = ะฒัะด %[2]s ะพะฑ'ัะดะฝะฐะฝะพ %[1]s
+pulls.clear_merge_message = ะัะธััะธัะธ ะฟะพะฒัะดะพะผะปะตะฝะฝั ะฟัะพ ะพะฑ'ัะดะฝะฐะฝะฝั
+pulls.cmd_instruction_merge_desc = ะะฑ'ัะดะฝะฐะนัะต ะทะผัะฝะธ ะน ะพะฝะพะฒััั ัั
ะฝะฐ Forgejo.
+pulls.is_ancestor = ะฆั ะณัะปะบั ะฒะถะต ะฒะบะปััะตะฝะพ ะฒ ััะปัะพะฒั ะณัะปะบั. ะััะพะณะพ ะพะฑ'ัะดะฝัะฒะฐัะธ.
+pulls.has_merged = ะะพะผะธะปะบะฐ: ะทะฐะฟะธั ะฝะฐ ะทะปะธััั ะฒะถะต ะพะฑ'ัะดะฝะฐะฝะพ, ะฝะตะผะพะถะปะธะฒะพ ะพะฑ'ัะดะฝะฐัะธ ะทะฝะพะฒั ัะธ ะทะผัะฝะธัะธ ััะปัะพะฒั ะณัะปะบั.
+pulls.head_out_of_date = ะะต ะฒะดะฐะปะพัั ะพะฑ'ัะดะฝะฐัะธ: head ะฑัะปะพ ะพะฝะพะฒะปะตะฝะพ, ะฟะพะบะธ ะฒัะดะฑัะฒะฐะปะพัั ะพะฑ'ัะดะฝะฐะฝะฝั. ะัะดะบะฐะทะบะฐ: ัะฟัะพะฑัะนัะต ะทะฝะพะฒั.
+no_eol.tooltip = ะฃ ััะพะผั ัะฐะนะปั ะฒัะดัััะฝัะน ัะธะผะฒะพะป ะทะฐะบัะฝัะตะฝะฝั ััะดะบะฐ (EOL) ั ะบัะฝัั.
+settings.trust_model.committer.desc = ะะพะฟัััะธะผั ะฟัะดะฟะธัะธ ะฑัะดััั ะฟะพะทะฝะฐัะฐัะธัั ัะบ ยซะดะพะฒััะตะฝัยป, ััะปัะบะธ ัะบัะพ ะฒะพะฝะธ ะฒัะดะฟะพะฒัะดะฐััั ะฐะฒัะพัั ะบะพะผััะฐ, ะฒ ัะฝัะพะผั ะฒะธะฟะฐะดะบั ะฒะพะฝะธ ะฟะพะทะฝะฐัะฐัะธะผััััั ัะบ ยซะฝะตะฒัะดะฟะพะฒัะดะฝัยป. ะฆะต ะทะผััะธัั Forgejo ะฑััะธ ะฐะฒัะพัะพะผ ะฟัะดะฟะธัะฐะฝะธั
ะบะพะผัััะฒ, ะฐ ัะฐะบัะธัะฝะพะณะพ ะฐะฒัะพัะฐ ะทะฐะทะฝะฐัะฐัะธ ะฒ ััะตะนะปะตัะฐั
ยซCo-authored-byยป ั ยซCo-committed-byยป ะฒ ะพะฟะธัั ะบะพะผััะฐ. ะขะธะฟะพะฒะธะน ะบะปัั Forgejo ะฟะพะฒะธะฝะตะฝ ะฒัะดะฟะพะฒัะดะฐัะธ ะบะพัะธัััะฒะฐัั ะฒ ะฑะฐะทั ะดะฐะฝะธั
.
+pulls.clear_merge_message_hint = ะัะธัะตะฝะฝั ะฟะพะฒัะดะพะผะปะตะฝะฝั ะฟัะพ ะพะฑ'ัะดะฝะฐะฝะฝั ะฒะธะดะฐะปะธัั ะปะธัะต ะฒะผััั ะฟะพะฒัะดะพะผะปะตะฝะฝั ะบะพะผััั ั ะทะฑะตัะตะถะต ะทะณะตะฝะตัะพะฒะฐะฝั git-ััะตะนะปะตัะธ, ัะฐะบั ัะบ ยซCo-Authored-Byโฆยป.
+branch.delete_branch_has_new_commits = ะัะปะบั ยซ%sยป ะฝะต ะผะพะถะฝะฐ ะฒะธะดะฐะปะธัะธ, ะพัะบัะปัะบะธ ะฟััะปั ะพะฑ'ัะดะฝะฐะฝะฝั ะฑัะปะพ ะดะพะดะฐะฝะพ ะฝะพะฒั ะบะพะผััะธ.
+settings.graphql_url = ะะพัะธะปะฐะฝะฝั GraphQL
+settings.packagist_api_token = ะขะพะบะตะฝ API
+settings.archive.text = ะัั
ัะฒัะฒะฐะฝะฝั ัะตะฟะพะทะธัะพััั ะทัะพะฑะธัั ะนะพะณะพ ะดะพัััะฟะฝะธะผ ััะปัะบะธ ะดะปั ัะธัะฐะฝะฝั. ะัะฝ ะฑัะดะต ะฟัะธั
ะพะฒะฐะฝะธะน ะท ะฟะฐะฝะตะปั ัะฟัะฐะฒะปัะฝะฝั. ะัั
ัะพ (ะฝะฐะฒััั ะฒะธ!) ะฝะต ะทะผะพะถะต ัะพะฑะธัะธ ะฝะพะฒั ะบะพะผััะธ, ััะฒะพััะฒะฐัะธ ะทะฐะดะฐัั ัะธ ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั.
+settings.protected_branch.delete_rule = ะะธะดะฐะปะธัะธ ะฟัะฐะฒะธะปะพ
+settings.branches.add_new_rule = ะะพะดะฐัะธ ะฝะพะฒะต ะฟัะฐะฒะธะปะพ
+settings.add_key_success = ะะปัั ะดะปั ัะพะทะณะพััะฐะฝะฝั ยซ%sยป ััะฟััะฝะพ ะดะพะดะฐะฝะพ.
+settings.update_settings_no_unit = ะ ะตะฟะพะทะธัะพััะน ะฟะพะฒะธะฝะตะฝ ะดะพะทะฒะพะปััะธ ั
ะพัะฐ ะฑ ัะบััั ะฒะทะฐัะผะพะดัั.
+settings.packagist_package_url = ะะพัะธะปะฐะฝะฝั ะฝะฐ ะฟะฐะบัะฝะพะบ Packagist
+settings.transfer.modal.title = ะะตัะตะดะฐัะธ ะฝะพะฒะพะผั ะฒะปะฐัะฝะธะบั
+settings.transfer.button = ะะตัะตะดะฐัะธ ะฝะพะฒะพะผั ะฒะปะฐัะฝะธะบั
+settings.event_package = ะะฐะบัะฝะพะบ
+settings.event_package_desc = ะะฐะบัะฝะพะบ ั ัะตะฟะพะทะธัะพััั ััะฒะพัะตะฝะพ ะฐะฑะพ ะฒะธะดะฐะปะตะฝะพ.
+settings.new_owner_blocked_doer = ะะพะฒะธะน ะฒะปะฐัะฝะธะบ ะทะฐะฑะปะพะบัะฒะฐะฒ ะฒะฐั.
+settings.transfer_quota_exceeded = ะะพะฒะธะน ะฒะปะฐัะฝะธะบ (%s) ะฟะตัะตะฒะธัะธะฒ ะบะฒะพัั. ะ ะตะฟะพะทะธัะพััะน ะฝะต ะฟะตัะตะดะฐะฝะพ.
+release.title_empty = ะะฐะณะพะปะพะฒะพะบ ะฝะต ะผะพะถะต ะฑััะธ ะฟะพัะพะถะฝัะผ.
+issues.role.member_helper = ะฆะตะน ะบะพัะธัััะฒะฐั ั ัะปะตะฝะพะผ ะพัะณะฐะฝัะทะฐััั, ัะพ ะฒะพะปะพะดัั ัะธะผ ัะตะฟะพะทะธัะพัััะผ.
+wiki.page_content = ะะผััั ััะพััะฝะบะธ
+wiki.page_title = ะะฐะณะพะปะพะฒะพะบ ััะพััะฝะบะธ
+pulls.close = ะะฐะบัะธัะธ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั
+branch.delete = ะะธะดะฐะปะธัะธ ะณัะปะบั ยซ%sยป
+diff.comment.add_line_comment = ะะพะดะฐัะธ ะบะพะผะตะฝัะฐั ะดะพ ััะดะบะฐ
+issues.review.option.hide_outdated_comments = ะัะธั
ะพะฒะฐัะธ ะทะฐััะฐััะปั ะบะพะผะตะฝัะฐัั
+issues.num_participants_one = %d ััะฐัะฝะธะบ
+issues.review.option.show_outdated_comments = ะะพะบะฐะทะฐัะธ ะทะฐััะฐััะปั ะบะพะผะตะฝัะฐัั
+pulls.delete.title = ะะธะดะฐะปะธัะธ ัะตะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั?
+issues.author.tooltip.pr = ะะฒัะพั ััะพะณะพ ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั.
+branch.deletion_failed = ะะต ะฒะดะฐะปะพัั ะฒะธะดะฐะปะธัะธ ะณัะปะบั ยซ%sยป.
+pulls.status_checks_show_all = ะะพะบะฐะทะฐัะธ ะฒัั ะฟะตัะตะฒััะบะธ
+wiki.cancel = ะกะบะฐััะฒะฐัะธ
+issues.role.first_time_contributor_helper = ะฆะต ะฟะตััะธะน ะฒะฝะตัะพะบ ััะพะณะพ ะบะพัะธัััะฒะฐัะฐ ะดะพ ัะตะฟะพะทะธัะพััั.
+pulls.filter_changes_by_commit = ะคัะปััััะฒะฐัะธ ะทะฐ ะบะพะผััะพะผ
+pulls.is_empty = ะะผัะฝะธ ะท ัััั ะณัะปะบะธ ะฒะถะต ั ะฒ ััะปัะพะฒัะน ะณัะปัั. ะะพะผัั ะฑัะดะต ะฟะพัะพะถะฝัะน.
+issues.author.tooltip.issue = ะะฒัะพั ัััั ะทะฐะดะฐัั.
+pulls.made_using_agit = AGit
+activity.navbar.recent_commits = ะะตัะพะดะฐะฒะฝั ะบะพะผััะธ
+branch.deletion_success = ะัะปะบั ยซ%sยป ะฒะธะดะฐะปะตะฝะพ.
+pulls.show_all_commits = ะะพะบะฐะทะฐัะธ ะฒัั ะบะพะผััะธ
+pull.deleted_branch = (ะฒะธะดะฐะปะตะฝะพ): %s
+milestones.update_ago = ะะฝะพะฒะปะตะฝะพ %s
+size_format = %[1]s: %[2]s; %[3]s: %[4]s
+settings.units.add_more = ะฃะฒัะผะบะฝััะธ ัะต
+migrate.cancel_migrating_title = ะกะบะฐััะฒะฐัะธ ะฟะตัะตะฝะตัะตะฝะฝั
+settings.units.units = ะ ะพะทะดัะปะธ
+settings.units.overview = ะะณะปัะด
+projects.create_success = ะัะพัะบั ยซ%sยป ััะฒะพัะตะฝะพ.
+issues.no_content = ะะตะผะฐั ะพะฟะธัั.
+settings.mirror_settings.docs.doc_link_title = ะฏะบ ะดะทะตัะบะฐะปัะฒะฐัะธ ัะตะฟะพะทะธัะพััั?
+n_commit_one = %s ะบะพะผัั
+n_commit_few = %s ะบะพะผัััะฒ
+signing.will_sign = ะะพะผัั ะฑัะดะต ะฟัะดะฟะธัะฐะฝะพ ะบะปััะตะผ ยซ%sยป.
+signing.wont_sign.error = ะัะด ัะฐั ะฟะตัะตะฒััะบะธ ะผะพะถะปะธะฒะพััั ะฟัะดะฟะธัะฐัะธ ะบะพะผัั ััะฐะปะฐัั ะฟะพะผะธะปะบะฐ.
+commits.search_branch = ะฃ ััะน ะณัะปัั
+ext_wiki = ะะพะฒะฝััะฝั ะฒัะบั
+pulls.commit_ref_at = `ะฟะพัะธะปะฐััััั ะฝะฐ ัะตะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั ะฒ ะบะพะผััั %[2]s `
+pulls.cmd_instruction_hint = ะะตัะตะณะปัะฝััะธ ัะฝััััะบััั ะดะปั ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ
+issues.max_pinned = ะะตะผะพะถะปะธะฒะพ ะทะฐะบััะฟะธัะธ ะฑัะปััะต ะทะฐะดะฐั
+issues.unpin_comment = ะฒัะดะบััะฟะธะฒ %s
+issues.pin_comment = ะทะฐะบััะฟะธะฒ %s
+project = ะัะพัะบัะธ
+issues.review.outdated_description = ะะผััั ะทะผัะฝะธะฒัั ะท ะผะพะผะตะฝัั ะฝะฐะฟะธัะฐะฝะฝั ััะพะณะพ ะบะพะผะตะฝัะฐัั
+commits.browse_further = ะะธะฒะธัะธัั ะดะฐะปั
+issues.unpin_issue = ะัะดะบััะฟะธัะธ ะทะฐะดะฐัั
+n_branch_one = %s ะณัะปะบะฐ
+n_branch_few = %s ะณัะปะพะบ
+executable_file = ะะธะบะพะฝัะฒะฐะฝะธะน ัะฐะนะป
+migrate_options_mirror_helper = ะฆะตะน ัะตะฟะพะทะธัะพััะน ะฑัะดะต ะดะทะตัะบะฐะปะพะผ
+projects.edit_success = ะัะพัะบั ยซ%sยป ะพะฝะพะฒะปะตะฝะพ.
+wiki.search = ะะพััะบ ะฟะพ ะฒัะบั
+wiki.no_search_results = ะััะพะณะพ ะฝะต ะทะฝะฐะนะดะตะฝะพ
+pulls.closed = ะะฐะฟะธั ะฝะฐ ะทะปะธััั ะทะฐะบัะธัะพ
+signing.wont_sign.not_signed_in = ะะธ ะฝะต ะฒะฒัะนัะปะธ ะฒ ัะธััะตะผั.
+settings.wiki_globally_editable = ะะพะทะฒะพะปะธัะธ ะฒััะผ ะบะพัะธัััะฒะฐัะฐะผ ัะตะดะฐะณัะฒะฐัะธ ะฒัะบั
+settings.reindex_button = ะะพะดะฐัะธ ะฒ ัะตัะณั ะฝะฐ ะฟะตัะตัะฝะดะตะบัะฐััั
+settings.reindex_requested = ะะพัััะฑะฝะฐ ะฟะตัะตัะฝะดะตะบัะฐััั
+editor.file_delete_success = ะคะฐะนะป ยซ%sยป ะฒะธะดะฐะปะตะฝะพ.
+file_follow = ะกะปัะดัะฒะฐัะธ ะทะฐ ัะธะผะฒะพะปัะฝะธะผ ะฟะพัะธะปะฐะฝะฝัะผ
+projects.column.set_default = ะฃััะฐะฝะพะฒะธัะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
+settings.federation_following_repos = URL-ะฐะดัะตัะธ ะฒัะดััะตะถัะฒะฐะฝะธั
ัะตะฟะพะทะธัะพัััะฒ. ะงะตัะตะท ยซ;ยป, ะฑะตะท ะฟัะพะฑัะปัะฒ.
+settings.federation_not_enabled = ะคะตะดะตัะฐััั ะฒะธะผะบะฝะตะฝะพ ั ะฒะฐัะพะผั ะตะบะทะตะผะฟะปััั.
+settings.federation_settings = ะะฐะปะฐัััะฒะฐะฝะฝั ัะตะดะตัะฐััั
+signing.wont_sign.nokey = ะฆะตะน ะตะบะทะตะผะฟะปัั ะฝะต ะผะฐั ะบะปััะฐ ะดะปั ะฟัะดะฟะธัะฐะฝะฝั ััะพะณะพ ะบะพะผััะฐ.
+settings.federation_apapiurl = URL ัะตะดะตัะฐััั ััะพะณะพ ัะตะฟะพะทะธัะพััั. ะกะบะพะฟััะนัะต ัั ัะฐ ะฒััะฐะฒัะต ะฒ ะฝะฐะปะฐัััะฒะฐะฝะฝั ัะตะดะตัะฐััั ัะฝัะพะณะพ ัะตะฟะพะทะธัะพััั ัะบ URL-ะฐะดัะตัั ะฒัะดััะตะถัะฒะฐะฝะพะณะพ ัะตะฟะพะทะธัะพััั.
+fork_branch = ะัะปะบะฐ, ัะบั ะฑัะดะต ะบะปะพะฝะพะฒะฐะฝะพ ั ัะพัะบ
+already_forked = ะะธ ะฒะถะต ััะฒะพัะธะปะธ ัะพัะบ %s
+fork_to_different_account = ะกัะฒะพัะธัะธ ัะพัะบ ะดะพ ัะฝัะพะณะพ ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
+fork_no_valid_owners = ะะตะผะพะถะปะธะฒะพ ััะฒะพัะธัะธ ัะพัะบ ััะพะณะพ ัะตะฟะพะทะธัะพััั, ะพัะบัะปัะบะธ ััั ะฝะตะผะฐั ะดัะนัะฝะธั
ะฒะปะฐัะฝะธะบัะฒ.
+pulls.agit_explanation = ะกัะฒะพัะตะฝะพ ัะตัะตะท ัะพะฑะพัะธะน ะฟะพััะบ AGit. AGit ะดะพะทะฒะพะปัั ััะฐัะฝะธะบะฐะผ ะฟัะพะฟะพะฝัะฒะฐัะธ ะทะผัะฝะธ ะทะฐ ะดะพะฟะพะผะพะณะพั ยซgit pushยป ะฑะตะท ััะฒะพัะตะฝะฝั ัะพัะบั ะฐะฑะพ ะฝะพะฒะพั ะณัะปะบะธ.
+diff.review.self_approve = ะะฒัะพัะธ ะทะฐะฟะธััะฒ ะฝะฐ ะทะปะธััั ะฝะต ะผะพะถััั ัั
ะฒะฐะปัะฒะฐัะธ ะฒะปะฐัะฝั ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั
+settings.event_pull_request_approvals = ะกั
ะฒะฐะปะตะฝะฝั ะทะฐะฟะธััะฒ ะฝะฐ ะทะปะธััั
+diff.git-notes.add = ะะพะดะฐัะธ ะฟัะธะผััะบั
+diff.git-notes.remove-header = ะะธะดะฐะปะธัะธ ะฟัะธะผััะบั
+projects.column.assigned_to = ะัะธะทะฝะฐัะตะฝะพ ะฝะฐ
+issues.new.assign_to_me = ะัะธะทะฝะฐัะธัะธ ัะพะฑั
+contributors.contribution_type.additions = ะะพะดะฐะฒะฐะฝะฝั
+settings.add_web_hook_desc = ะะฝัะตะณััะฒะฐัะธ %s ั ัะตะน ัะตะฟะพะทะธัะพััะน.
+settings.event_wiki_desc = ะัะบั-ััะพััะฝะบั ััะฒะพัะตะฝะพ, ะฟะตัะตะนะผะตะฝะพะฒะฐะฝะพ, ะฒัะดัะตะดะฐะณะพะฒะฐะฝะพ ะฐะฑะพ ะฒะธะดะฐะปะตะฝะพ.
+settings.mirror_settings.push_mirror.copy_public_key = ะะพะฟััะฒะฐัะธ ะฟัะฑะปััะฝะธะน ะบะปัั
+editor.add_tmpl.filename = ะฝะฐะทะฒะฐ ัะฐะนะปั
+settings.unarchive.button = ะ ะพะทะฐัั
ัะฒัะฒะฐัะธ ัะตะฟะพะทะธัะพััะน
+object_format = ะคะพัะผะฐั ะพะฑ'ัะบัะฐ
+settings.archive.mirrors_unavailable = ะะทะตัะบะฐะปะฐ ะฝะตะดะพัััะฟะฝั ะฒ ะฐัั
ัะฒะพะฒะฐะฝะธั
ัะตะฟะพะทะธัะพัััั
.
+pulls.sign_in_require = ะฃะฒัะนะดััั , ัะพะฑ ััะฒะพัะธัะธ ะฝะพะฒะธะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั.
+new_advanced_expand = ะะฐัะธัะฝััั, ัะพะฑ ัะพะทะณะพัะฝััะธ
+new_from_template = ะะธะบะพัะธััะฐัะธ ัะฐะฑะปะพะฝ
+new_advanced = ะะพะดะฐัะบะพะฒั ะฝะฐะปะฐัััะฒะฐะฝะฝั
+auto_init_description = ะะพัะฝััั ัััะพััั Git ะท README ั ะทะฐ ะฑะฐะถะฐะฝะฝัะผ ะดะพะดะฐะนัะต ัะฐะนะปะธ License ัะฐ .gitignore.
+new_from_template_description = ะะพะถะตัะต ะฒะธะฑัะฐัะธ ะฝะฐัะฒะฝะธะน ัะฐะฑะปะพะฝ ัะตะฟะพะทะธัะพััั ะฝะฐ ััะพะผั ะตะบะทะตะผะฟะปััั ั ะทะฐััะพััะฒะฐัะธ ะนะพะณะพ ะฝะฐะปะฐัััะฒะฐะฝะฝั.
+form.string_too_long = ะะพะฒะถะธะฝะฐ ะฒะฒะตะดะตะฝะพะณะพ ััะดะบะฐ ะฑัะปััะฐ ะทะฐ %d ัะธะผะฒะพะปัะฒ.
+form.name_reserved = ะะฐะทะฒั ัะตะฟะพะทะธัะพััั ยซ%sยป ะทะฐัะตะทะตัะฒะพะฒะฐะฝะพ.
+form.name_pattern_not_allowed = ะจะฐะฑะปะพะฝ ยซ%sยป ะฝะต ะดะพะฟััะบะฐััััั ั ะฝะฐะทะฒั ัะตะฟะพะทะธัะพััั.
+settings.wiki_rename_branch_main_desc = ะะตัะตะนะผะตะฝัะฒะฐัะธ ะฒะฝัััััะฝั ะณัะปะบั, ัะบะฐ ะฒะธะบะพัะธััะพะฒัััััั ั ะฒัะบั, ะฝะฐ ยซ%sยป. ะฆั ะทะผัะฝะฐ ั ะพััะฐัะพัะฝะพั ั ัั ะฝะตะผะพะถะปะธะฒะพ ัะบะฐััะฒะฐัะธ.
+wiki.reserved_page = ะะฐะทะฒั ะฒัะบั-ััะพััะฝะบะธ ยซ%sยป ะทะฐัะตะทะตัะฒะพะฒะฐะฝะพ.
+stars = ะััะบะธ
+mirror_public_key = ะัะดะบัะธัะธะน SSH-ะบะปัั
+mirror_use_ssh.text = ะั
ะพะดะธัะธ ัะตัะตะท SSH
+activity.navbar.code_frequency = ะงะฐััะพัะฐ ะบะพะดัะฒะฐะฝะฝั
+activity.navbar.pulse = ะัะปัั
+open_with_editor = ะัะดะบัะธัะธ ะฒ %s
+commits.view_single_diff = ะะตัะตะณะปัะฝััะธ ะทะผัะฝะธ ะดะพ ััะพะณะพ ัะฐะนะปั, ะฒะฝะตัะตะฝั ั ััะพะผั ะบะพะผััั
+pulls.editable = ะ ะตะดะฐะณะพะฒะฐะฝะต
+pulls.editable_explanation = ะฆะตะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั ะดะพะทะฒะพะปัั ัะตะดะฐะณัะฒะฐะฝะฝั ะฒัะด ัะพะทัะพะฑะฝะธะบัะฒ. ะะธ ะผะพะถะตัะต ะทัะพะฑะธัะธ ัะฒัะน ะฒะฝะตัะพะบ ะฑะตะทะฟะพัะตัะตะดะฝัะพ ะดะพ ะฝัะพะณะพ.
+admin.failed_to_replace_flags = ะะต ะฒะดะฐะปะพัั ะทะฐะผัะฝะธัะธ ะฟัะฐะฟะพััั ัะตะฟะพะทะธัะพััั
+admin.enabled_flags = ะะปั ัะตะฟะพะทะธัะพััั ะฒะฒัะผะบะฝะตะฝะพ ะฟัะฐะฟะพััั:
+admin.flags_replaced = ะัะฐะฟะพััั ัะตะฟะพะทะธัะพััั ะทะฐะผัะฝะตะฝะพ
+admin.update_flags = ะะฝะพะฒะธัะธ ะฟัะฐะฟะพััั
+admin.manage_flags = ะะตััะฒะฐะฝะฝั ะฟัะฐะฟะพัััะผะธ
+settings.rename_branch_failed_protected = ะะตะผะพะถะปะธะฒะพ ะฟะตัะตะนะผะตะฝัะฒะฐัะธ ะณัะปะบั %s, ะพัะบัะปัะบะธ ัั ะณัะปะบะฐ ะทะฐั
ะธัะตะฝะฐ.
+desc.sha256 = SHA256
+rss.must_be_on_branch = ะฉะพะฑ ะผะฐัะธ RSS-ัััััะบั, ะฒะฐะผ ะฟะพัััะฑะฝะพ ะฑััะธ ะฒ ะณัะปัั.
+default_branch_label = ัะธะฟะพะฒะฐ
+mirror_sync_on_commit = ะกะธะฝั
ัะพะฝัะทัะฒะฐัะธ ะฟัะธ ะฒะธะฒะฐะฝัะฐะถะตะฝะฝั ะบะพะผัััะฒ
+mirror_sync = ัะธะฝั
ัะพะฝัะทะพะฒะฐะฝะพ
+mirror_use_ssh.helper = Forgejo ะผะพะถะต ะฒัะดะดะทะตัะบะฐะปัะฒะฐัะธ ัะตะฟะพะทะธัะพััะน ะทะฐ ะดะพะฟะพะผะพะณะพั Git ัะตัะตะท SSH, ะทะณะตะฝะตััะฒะฐะฒัะธ ะฒะฐะผ ะฟะฐัั ะบะปัััะฒ. ะะพะทะฒะพะปััะต ะฒัะดะบัะธัะพะผั ะบะปััั ะฒะธะฒะฐะฝัะฐะถัะฒะฐัะธ ะทะผัะฝะธ ะฒ ััะปัะพะฒะธะน ัะตะฟะพะทะธัะพััะน. ะัะธ ะฒะธะฑะพัั ัััั ะพะฟััั ะฒั
ัะด ะฟะฐัะพะปะตะผ ะฝะตะผะพะถะปะธะฒะธะน.
+mirror_denied_combination = ะะตะผะพะถะปะธะฒะพ ะฒะพะดะฝะพัะฐั ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะฒั
ัะด ะฒัะดะบัะธัะธะผ ะบะปััะตะผ ั ะฟะฐัะพะปะตะผ.
+new_repo_helper = ะ ะตะฟะพะทะธัะพััะน ะผัััะธัั ััั ัะฐะนะปะธ ะฟัะพัะบัั, ะทะพะบัะตะผะฐ ัััะพััั ะทะผัะฝ. ะฃ ะฒะฐั ะฒัะฝ ัะถะต ะดะตัั ั? ะัะณััะนัะต ัะตะฟะพะทะธัะพััะน .
+issues.reference_link = ะะพัะธะปะฐะฝะฝั: %s
+object_format_helper = ะคะพัะผะฐั ะพะฑ'ัะบััะฒ ัะตะฟะพะทะธัะพััั. ะะผัะฝะธัะธ ะฟะพััะผ ะฝะตะผะพะถะปะธะฒะพ. SHA1 โ ะฝะฐะนััะผััะฝััะธะน.
+mirror_interval = ะะฝัะตัะฒะฐะป ัะธะฝั
ัะพะฝัะทะฐััั ะดะทะตัะบะฐะปะฐ (ัะฐัะพะฒั ะพะดะธะฝะธัั โ ยซhยป, ยซmยป, ยซsยป). 0 ะฒะธะผะธะบะฐั ัะธะฝั
ัะพะฝัะทะฐััั. (ะัะฝัะผะฐะปัะฝะธะน ัะฝัะตัะฒะฐะป: %s)
+mirror_address_url_invalid = ะะบะฐะทะฐะฝะพ ั
ะธะฑะฝั URL-ะฐะดัะตัั. ะะฐะผัะฝััั escape-ะฟะพัะปัะดะพะฒะฝะพัััะผะธ ะฒัั ะฝะตะพะดะฝะพะทะฝะฐัะฝั ัะบะปะฐะดะฝะธะบะธ ะฐะดัะตัะธ.
+mirror_address_protocol_invalid = ะฅะธะฑะฝะฐ URL-ะฐะดัะตัะฐ. ะะธัะต ะฐะดัะตัะธ http(s):// ัะธ git:// ะผะพะถะฝะฐ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะดะปั ะฒัะดะดะทะตัะบะฐะปะตะฝะฝั.
+stars_remove_warning = ะฆะต ะฒะธะปััะธัั ััั ะทััะบะธ ัะตะฟะพะทะธัะพััั.
+mirror_use_ssh.not_available = SSH-ะฒั
ัะด ะฝะตะดะพัััะฟะฝะธะน.
+issues.num_reviews_one = %d ะฒัะดะณัะบ
+archive.title = ะฆะตะน ัะตะฟะพะทะธัะพััะน ะฐัั
ัะฒะพะฒะฐะฝะพ. ะะธ ะผะพะถะตัะต ะฟะตัะตะณะปัะดะฐัะธ ัะฐะนะปะธ ั ะบะปะพะฝัะฒะฐัะธ ะนะพะณะพ, ะฐะปะต ะฝะต ะผะพะถะตัะต ะฒะฝะพัะธัะธ ะถะพะดะฝะธั
ะทะผัะฝ ั ะนะพะณะพ ััะฐะฝ, ะทะพะบัะตะผะฐ ัะพะฑะธัะธ push ั ััะฒะพััะฒะฐัะธ ะฝะพะฒั ะทะฐะดะฐัั, ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั ัะธ ะบะพะผะตะฝัะฐัั.
+settings.event_pull_request_review_request = ะะฐะฟะธัะธ ะฝะฐ ะฒัะดะณัะบ
+archive.title_date = ะฆะตะน ัะตะฟะพะทะธัะพััะน ะฐัั
ัะฒะพะฒะฐะฝะพ %s. ะะธ ะผะพะถะตัะต ะฟะตัะตะณะปัะดะฐัะธ ัะฐะนะปะธ ั ะบะปะพะฝัะฒะฐัะธ ะนะพะณะพ, ะฐะปะต ะฝะต ะผะพะถะตัะต ะฒะฝะพัะธัะธ ะถะพะดะฝะธั
ะทะผัะฝ ั ะนะพะณะพ ััะฐะฝ, ะทะพะบัะตะผะฐ ัะพะฑะธัะธ push ั ััะฒะพััะฒะฐัะธ ะฝะพะฒั ะทะฐะดะฐัั, ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั ัะธ ะบะพะผะตะฝัะฐัั.
+settings.event_pull_request_review_request_desc = ะกัะฒะพัะตะฝะพ ะฐะฑะพ ะฒะธะดะฐะปะตะฝะพ ะทะฐะฟะธั ะฝะฐ ะฒัะดะณัะบ ะดะพ ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั.
+archive.pull.noreview = ะฆะตะน ัะตะฟะพะทะธัะพััะน ะฐัั
ัะฒะพะฒะฐะฝะพ. ะะธ ะฝะต ะผะพะถะตัะต ัะตัะตะฝะทัะฒะฐัะธ ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั.
+issues.num_reviews_few = %d ะฒัะดะณัะบัะฒ
+n_release_few = %s ะฒะธะฟััะบัะฒ
+release.releases_for = ะะธะฟััะบะธ %s
+release.type_attachment = ะะบะปะฐะดะตะฝะฝั
+n_release_one = %s ะฒะธะฟััะบ
+pulls.comment.blocked_by_user = ะะธ ะฝะต ะผะพะถะตัะต ะบะพะผะตะฝััะฒะฐัะธ ัะตะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั, ะพัะบัะปัะบะธ ะฒะฐั ะทะฐะฑะปะพะบัะฒะฐะฒ ะฒะปะฐัะฝะธะบ ัะตะฟะพะทะธัะพััั ะฐะฑะพ ะฐะฒัะพั ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั.
+issues.reopen.blocked_by_user = ะะธ ะฝะต ะผะพะถะตัะต ะทะฝะพะฒั ะฒัะดะบัะธัะธ ัั ะทะฐะดะฐัั, ะพัะบัะปัะบะธ ะฒะฐั ะทะฐะฑะปะพะบัะฒะฐะฒ ะฒะปะฐัะฝะธะบ ัะตะฟะพะทะธัะพััั ะฐะฑะพ ะฐะฒัะพั ะทะฐะดะฐัั.
+settings.actions_desc = ะฃะฒัะผะบะฝััะธ ะฒะฑัะดะพะฒะฐะฝั ะบะพะฝะฒะตััะธ CI/CD ะท ะััะผะธ Forgejo
+tree_path_not_found_commit = ะจะปัั
%[1]s ะฝะต ััะฝัั ะฒ ะบะพะผััั %[2]s
+pulls.blocked_by_user = ะะธ ะฝะต ะผะพะถะตัะต ััะฒะพัะธัะธ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั ะฒ ััะพะผั ัะตะฟะพะทะธัะพััั, ะพัะบัะปัะบะธ ะฒะฐั ะทะฐะฑะปะพะบัะฒะฐะฒ ะฒะปะฐัะฝะธะบ ัะตะฟะพะทะธัะพััั.
+issues.blocked_by_user = ะะธ ะฝะต ะผะพะถะตัะต ััะฒะพััะฒะฐัะธ ะทะฐะดะฐัั ะฒ ััะพะผั ัะตะฟะพะทะธัะพััั, ะพัะบัะปัะบะธ ะฒะฐั ะทะฐะฑะปะพะบัะฒะฐะฒ ะฒะปะฐัะฝะธะบ ัะตะฟะพะทะธัะพััั.
+activity.commit = ะ-ัั ะบะพะผัััะฒ
+issues.filter_no_results_placeholder = ะกะฟัะพะฑัะนัะต ะทะผัะฝะธัะธ ะฟะพััะบะพะฒั ััะปัััะธ.
+issues.filter_no_results = ะััะพะณะพ ะฝะต ะทะฝะฐะนะดะตะฝะพ
+generated = ะะณะตะฝะตัะพะฒะฐะฝะธะน
+tag.create_tag_operation = ะกัะฒะพัะธัะธ ัะตะณ
+branch.restore_failed = ะะต ะฒะดะฐะปะพัั ะฒัะดะฝะพะฒะธัะธ ะณัะปะบั ยซ%sยป.
+release.tag_helper_existing = ะะฐัะฒะฝะธะน ัะตะณ.
+editor.fail_to_update_file = ะะต ะฒะดะฐะปะพัั ะพะฝะพะฒะธัะธ/ััะฒะพัะธัะธ ัะฐะนะป ยซ%sยป.
+release.tag_helper_new = ะะพะฒะธะน ัะตะณ. ะฆะตะน ัะตะณ ะฑัะดะต ััะฒะพัะตะฝะพ ะท ััะปั.
+tag.create_tag_from = ะกัะฒะพัะธัะธ ะฝะพะฒะธะน ัะตะณ ัะท ยซ%sยป
+tag.confirm_create_tag = ะกัะฒะพัะธัะธ ัะตะณ
+settings.mirror_settings.docs.can_still_use = ะฅะพัะฐ ะฒะธ ะฝะต ะผะพะถะตัะต ะทะผัะฝัะฒะฐัะธ ะฝะฐัะฒะฝั ะดะทะตัะบะฐะปะฐ ะฐะฑะพ ััะฒะพััะฒะฐัะธ ะฝะพะฒั, ะฒะธ ะผะพะถะตัะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะฝะฐัะฒะฝะต ะดะทะตัะบะฐะปะพ.
+branch.new_branch_from = ะกัะฒะพัะธัะธ ะฝะพะฒั ะณัะปะบั ะท ยซ%sยป
+settings.confirmation_string = ะ ัะดะพะบ ะฟัะดัะฒะตัะดะถะตะฝะฝั
+milestones.edit_success = ะัะฐะฟ ยซ%sยป ะพะฝะพะฒะปะตะฝะพ.
+tree_path_not_found_tag = ะจะปัั
%[1]s ะฝะต ััะฝัั ะฒ ัะตะณั %[2]s
+tag.create_success = ะขะตะณ ยซ%sยป ััะฒะพัะตะฝะพ.
+tree_path_not_found_branch = ะจะปัั
%[1]s ะฝะต ััะฝัั ะฒ ะณัะปัั %[2]s
+branch.create_success = ะัะปะบั ยซ%sยป ััะฒะพัะตะฝะพ.
+pulls.view = ะะตัะตะณะปัะฝััะธ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั
+pulls.allow_edits_from_maintainers_desc = ะะพัะธัััะฒะฐัั ะท ะดะพัััะฟะพะผ ะฝะฐ ะทะฐะฟะธั ั ะฑะฐะทะพะฒั ะณัะปะบั ะผะพะถััั ัะฐะบะพะถ ะฒะธะบะพะฝัะฒะฐัะธ push ั ัั ะณัะปะบั
+settings.protect_enable_merge_desc = ะัะดั-ั
ัะพ ะท ะดะพัััะฟะพะผ ะฝะฐ ะทะฐะฟะธั ะทะผะพะถะต ะพะฑ'ัะดะฝัะฒะฐัะธ ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั ั ัั ะณัะปะบั.
+commit.contained_in = ะฆะตะน ะบะพะผัั ะผัััะธัััั ะฒ:
+pulls.reopen_failed.head_branch = ะะธ ะฝะต ะผะพะถะตัะต ะทะฝะพะฒั ะฒัะดะบัะธัะธ ัะตะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั, ะพัะบัะปัะบะธ ะณะพะปะพะฒะฝะฐ ะณัะปะบะฐ ะฑัะปััะต ะฝะต ััะฝัั.
+settings.protect_new_rule = ะกัะฒะพัะธัะธ ะฝะพะฒะต ะฟัะฐะฒะธะปะพ ะทะฐั
ะธััั ะณัะปะพะบ
+issues.reaction.alt_few = %[1]s ัะตะฐะณัั %[2]s.
+issues.context.menu = ะะตะฝั ะบะพะผะตะฝัะฐัั
+editor.branch_does_not_exist = ะฃ ััะพะผั ัะตะฟะพะทะธัะพััั ะฝะตะผะฐั ะณัะปะบะธ ยซ%sยป.
+pulls.nothing_to_compare_have_tag = ะะธะฑัะฐะฝั ะณัะปะบะธ/ัะตะณะธ ะพะดะฝะฐะบะพะฒั.
+pulls.delete_after_merge.head_branch.is_protected = ะะพะปะพะฒะฝะฐ ะณัะปะบะฐ, ัะบั ะฒะธ ะฝะฐะผะฐะณะฐััะตัั ะฒะธะดะฐะปะธัะธ, ั ะทะฐั
ะธัะตะฝะพั ั ัั ะฝะตะผะพะถะปะธะฒะพ ะฒะธะดะฐะปะธัะธ.
+settings.default_update_style_desc = ะขะธะฟะพะฒะธะน ััะธะปั ะพะฝะพะฒะปะตะฝะฝั ะดะปั ะทะฐะฟะธััะฒ ะฝะฐ ะทะปะธััั, ัะพ ะทะฝะฐั
ะพะดััััั ะฟะพะทะฐะดั ะฑะฐะทะพะฒะพั ะณัะปะบะธ.
+commit.load_referencing_branches_and_tags = ะะฐะฒะฐะฝัะฐะถะธัะธ ะณัะปะบะธ ั ัะตะณะธ, ัะบั ะฟะพัะธะปะฐััััั ะฝะฐ ัะตะน ะบะพะผัั
+n_tag_few = %s ัะตะณัะฒ
+n_tag_one = %s ัะตะณ
+settings.branches.switch_default_branch = ะะผัะฝะธัะธ ัะธะฟะพะฒั ะณัะปะบั
+branch.branch_already_exists = ะัะปะบะฐ ยซ%sยป ะฒะถะต ั ั ััะพะผั ัะตะฟะพะทะธัะพััั.
+commit.contained_in_default_branch = ะฆะตะน ะบะพะผัั โ ัะฐััะธะฝะฐ ัะธะฟะพะฒะพั ะณัะปะบะธ
+editor.upload_file_is_locked = ะคะฐะนะป ยซ%sยป ะทะฐะฑะปะพะบะพะฒะฐะฝะพ %s.
+commits.no_commits = ะะตะผะฐั ัะฟัะปัะฝะธั
ะบะพะผัััะฒ. ะฃ ยซ%sยป ั ยซ%sยป ะทะพะฒััะผ ััะทะฝั ัััะพััั.
+release.message = ะะฟะธัััั ัะตะน ะฒะธะฟััะบ
+branch.restore_success = ะัะปะบั ยซ%sยป ะฒัะดะฝะพะฒะปะตะฝะพ.
+branch.create_from = ะท ยซ%sยป
+branch.restore = ะัะดะฝะพะฒะธัะธ ะณัะปะบั ยซ%sยป
+editor.branch_already_exists = ะัะปะบะฐ ยซ%sยป ะฒะถะต ั ั ััะพะผั ัะตะฟะพะทะธัะพััั.
+pulls.select_commit_hold_shift_for_range = ะะธะฑะตัััั ะบะพะผัั. ะะปะฐัะฝััั, ัััะธะผัััะธ Shift, ัะพะฑ ะฒะธะฑัะฐัะธ ะดัะฐะฟะฐะทะพะฝ
+settings.confirm_wiki_branch_rename = ะะตัะตะนะผะตะฝัะฒะฐัะธ ะณัะปะบั ะฒัะบั
+branch.already_exists = ะัะปะบะฐ ะท ะฝะฐะทะฒะพั ยซ%sยป ะฒะถะต ััะฝัั.
+branch.protected_deletion_failed = ะัะปะบั ยซ%sยป ะทะฐั
ะธัะตะฝะพ. ะั ะฝะตะผะพะถะปะธะฒะพ ะฒะธะดะฐะปะธัะธ.
+branch.default_deletion_failed = ะัะปะบะฐ ยซ%sยป ั ัะธะฟะพะฒะพั. ะั ะฝะตะผะพะถะปะธะฒะพ ะฒะธะดะฐะปะธัะธ.
+pulls.reopen_failed.base_branch = ะะธ ะฝะต ะผะพะถะตัะต ะทะฝะพะฒั ะฒัะดะบัะธัะธ ัะตะน ะทะฐะฟะธั ะฝะฐ ะทะปะธััั, ะพัะบัะปัะบะธ ะฑะฐะทะพะฒะฐ ะณัะปะบะฐ ะฑัะปััะต ะฝะต ััะฝัั.
+milestones.create_success = ะัะฐะฟ ยซ%sยป ััะฒะพัะตะฝะพ.
+branch.rename = ะะตัะตะนะผะตะฝัะฒะฐัะธ ะณัะปะบั ยซ%sยป
+branch.warning_rename_default_branch = ะะธ ะทะฑะธัะฐััะตัั ะฟะตัะตะนะผะตะฝัะฒะฐัะธ ัะธะฟะพะฒั ะณัะปะบั.
+branch.rename_branch_to = ะะตัะตะนะผะตะฝัะฒะฐัะธ ยซ%sยป ะฝะฐ:
+pulls.delete_after_merge.head_branch.is_default = ะะพะปะพะฒะฝะฐ ะณัะปะบะฐ, ัะบั ะฒะธ ะฝะฐะผะฐะณะฐััะตัั ะฒะธะดะฐะปะธัะธ, ั ัะธะฟะพะฒะพั ะณัะปะบะพั. ะั ะฝะตะผะพะถะปะธะฒะพ ะฒะธะดะฐะปะธัะธ.
+issues.delete.title = ะะธะดะฐะปะธัะธ ัั ะทะฐะดะฐัั?
+release.asset_external_url = ะะพะฒะฝััะฝั URL-ะฐะดัะตัะฐ
+branch.download = ะะฐะฒะฐะฝัะฐะถะธัะธ ะณัะปะบั ยซ%sยป
+pulls.delete_after_merge.head_branch.insufficient_branch = ะฃ ะฒะฐั ะฝะตะผะฐั ะดะพะทะฒะพะปั ะฒะธะดะฐะปััะธ ะณะพะปะพะฒะฝั ะณัะปะบั.
+activity.published_tag_label = ะขะตะณ
+
+commits.search.tooltip = ะะพ ะบะปััะพะฒะธั
ัะปัะฒ ะผะพะถะฝะฐ ะดะพะดะฐะฒะฐัะธ ะฟัะตััะบัะธ ยซauthor:ยป, ยซcommitter:ยป, ยซafter:ยป ะฐะฑะพ ยซbefore:ยป, ะฝะฐะฟัะธะบะปะฐะด, ยซrevert author:Alice before:2019-01-13ยป.
+release.type_external_asset = ะะพะฒะฝััะฝัะน ัะตัััั
+release.asset_name = ะะฐะทะฒะฐ ัะตััััั
+release.add_external_asset = ะะพะดะฐัะธ ะทะพะฒะฝััะฝัะน ัะตัััั
+find_file.no_matching = ะะต ะทะฝะฐะนะดะตะฝะพ ะฒัะดะฟะพะฒัะดะฝะพะณะพ ัะฐะนะปั
+
+issues.role.first_time_contributor = ะะพะฒะธะน ััะฐัะฝะธะบ
[graphs]
+contributors.what = ะฒะฝะตัะบะธ
+component_loading_info = ะฆะต ะผะพะถะต ะทะฐะนะฝััะธ ะดะตัะบะธะน ัะฐัโฆ
+component_loading = ะะฐะฒะฐะฝัะฐะถะตะฝะฝั %sโฆ
+component_loading_failed = ะะต ะฒะดะฐะปะพัั ะทะฐะฒะฐะฝัะฐะถะธัะธ %s
+recent_commits.what = ะฝะตัะพะดะฐะฒะฝั ะบะพะผััะธ
+component_failed_to_load = ะกัะฐะปะฐัั ะฝะตัะฟะพะดัะฒะฐะฝะฐ ะฟะพะผะธะปะบะฐ.
+code_frequency.what = ัะฐััะพัะฐ ะบะพะดัะฒะฐะฝะฝั
[org]
org_name_holder=ะะฐะทะฒะฐ ะพัะณะฐะฝัะทะฐััั
@@ -2126,22 +2725,22 @@ settings.labels_desc=ะะพะดะฐัะธ ะผััะบะธ, ัะบั ะผะพะถััั ะฑััะธ ะฒะธ
members.membership_visibility=ะะธะดะธะผัััั ััะฐัะฝะธะบะฐ:
members.public=ะะพะบะฐะทัะฒะฐัะธ
-members.public_helper=ะทัะพะฑะธัะธ ะฟัะธั
ะพะฒะฐะฝะธะผ
+members.public_helper=ะัะพะฑะธัะธ ะฟัะธั
ะพะฒะฐะฝะธะผ
members.private=ะัะธั
ะพะฒะฐะฝะธะน
-members.private_helper=ะทัะพะฑะธัะธ ะฒะธะดะธะผะธะผ
+members.private_helper=ะัะพะฑะธัะธ ะฒะธะดะธะผะธะผ
members.member_role=ะ ะพะปั ััะฐัะฝะธะบะฐ:
members.owner=ะะปะฐัะฝะธะบ
members.member=ะฃัะฐัะฝะธะบ
members.remove=ะะธะดะฐะปะธัะธ
members.remove.detail=ะะธะปััะธัะธ %[1]s ะท %[2]s?
members.leave=ะะพะบะธะฝััะธ
-members.leave.detail=ะะพะบะธะฝััะธ %s?
+members.leave.detail=ะะธ ะฒะฟะตะฒะฝะตะฝั, ัะพ ั
ะพัะตัะต ะฟะพะบะธะฝััะธ ะพัะณะฐะฝัะทะฐััั ยซ%sยป?
members.invite_desc=ะะพะดะฐัะธ ะฝะพะฒะพะณะพ ััะฐัะฝะธะบะฐ ะดะพ %s:
members.invite_now=ะะฐะฟัะพัะธัะธ ะทะฐัะฐะท
teams.join=ะัะธัะดะฝะฐัะธัั
teams.leave=ะะพะบะธะฝััะธ
-teams.leave.detail=ะะพะบะธะฝััะธ %s?
+teams.leave.detail=ะะธ ะฒะฟะตะฒะฝะตะฝั, ัะพ ั
ะพัะตัะต ะฟะพะบะธะฝััะธ ะบะพะผะฐะฝะดั ยซ%sยป?
teams.can_create_org_repo=ะกัะฒะพัะธัะธ ัะตะฟะพะทะธัะพััั
teams.can_create_org_repo_helper=ะฃัะฐัะฝะธะบะธ ะผะพะถััั ััะฒะพััะฒะฐัะธ ะฝะพะฒั ัะตะฟะพะทะธัะพััั ะฒ ะพัะณะฐะฝัะทะฐััั. ะะฒัะพั ะพััะธะผะฐั ะดะพัััะฟ ะฐะดะผัะฝััััะฐัะพัะฐ ะดะพ ะฝะพะฒะพะณะพ ัะตะฟะพะทะธัะพััั.
teams.read_access=ะัะพัะธัะฐะฝั
@@ -2161,7 +2760,7 @@ teams.delete_team_desc=ะะธะดะฐะปะตะฝะฝั ะบะพะผะฐะฝะดะธ ัะบะฐัะพะฒัั ะดะพั
teams.delete_team_success=ะะพะผะฐะฝะดั ะฑัะปะพ ะฒะธะดะฐะปะตะฝะพ.
teams.read_permission_desc=ะฆั ะบะพะผะฐะฝะดะฐ ะผะฐั ะดะพัััะฟ ะดะปั ัะธัะฐะฝะฝั : ััะฐัะฝะธะบะธ ะผะพะถััั ะฟะตัะตะณะปัะดะฐัะธ ัะฐ ะบะปะพะฝัะฒะฐัะธ ัะตะฟะพะทะธัะพััั.
teams.write_permission_desc=ะฆั ะบะพะผะฐะฝะดะฐ ะฝะฐะดะฐั ะดะพัััะฟ ะฝะฐ ะทะฐะฟะธั : ััะฐัะฝะธะบะธ ะผะพะถััั ะพััะธะผัะฒะฐัะธ ะน ะฒะธะบะพะฝัะฒะฐัะธ push ะบะพะผะฐะฝะดะธ ะดะพ ัะตะฟะพะทะธัััั.
-teams.admin_permission_desc=ะฆั ะบะพะผะฐะฝะดะฐ ะฝะฐะดะฐั ะฐะดะผัะฝััััะฐัะพัััะบะธะน ะดะพัััะฟ: ััะฐัะฝะธะบะธ ะผะพะถััั ัะธัะฐัะธ, ะฒะธะบะพะฝัะฒะฐัะธ push ะบะพะผะฐะฝะดะธ ัะฐ ะดะพะดะฐะฒะฐัะธ ัะฟัะฒัะพะฑััะฝะธะบัะฒ ะดะพ ัะตะฟะพะทะธัะพััั.
+teams.admin_permission_desc=ะฆั ะบะพะผะฐะฝะดะฐ ะฝะฐะดะฐั ะฐะดะผัะฝััััะฐัะพัััะบะธะน ะดะพัััะฟ: ััะฐัะฝะธะบะธ ะผะพะถััั ัะธัะฐัะธ, ะฒะธะบะพะฝัะฒะฐัะธ push ัะฐ ะดะพะดะฐะฒะฐัะธ ัะฟัะฒะฐะฒัะพััะฒ ะดะพ ัั ัะตะฟะพะทะธัะพัััะฒ.
teams.create_repo_permission_desc=ะััะผ ัะพะณะพ, ัั ะบะพะผะฐะฝะดะฐ ะฝะฐะดะฐั ะดะพะทะฒัะป ะกัะฒะพัะธัะธ ัะตะฟะพะทะธัะพััะน : ััะฐัะฝะธะบะธ ะผะพะถััั ััะฒะพััะฒะฐัะธ ะฝะพะฒั ัะตะฟะพะทะธัะพััั ะฒ ะพัะณะฐะฝัะทะฐััั.
teams.repositories=ะ ะตะฟะพะทะธัะพััั ะบะพะผะฐะฝะดะธ
teams.search_repo_placeholder=ะะพััะบ ัะตะฟะพะทะธัะพัััโฆ
@@ -2179,6 +2778,20 @@ teams.all_repositories_helper=ะะพะผะฐะฝะดะฐ ะผะฐั ะดะพัััะฟ ะดะพ ะฒััั
teams.all_repositories_read_permission_desc=ะฆั ะบะพะผะฐะฝะดะฐ ะฝะฐะดะฐั ะดะพะทะฒัะป ะะตัะตะณะปัะด ะดะปั ะฒััั
ัะตะฟะพะทะธัะพัััะฒ : ััะฐัะฝะธะบะธ ะผะพะถััั ะฟะตัะตะณะปัะดะฐัะธ ัะฐ ะบะปะพะฝัะฒะฐัะธ ัั
.
teams.all_repositories_write_permission_desc=ะฆั ะบะพะผะฐะฝะดะฐ ะฝะฐะดะฐั ะดะพะทะฒัะป ะะฐะฟะธั ะดะปั ะฒััั
ัะตะฟะพะทะธัะพัััะฒ : ััะฐัะฝะธะบะธ ะผะพะถััั ะฟะตัะตะณะปัะดะฐัะธ ัะฐ ะฒะธะบะพะฝัะฒะฐัะธ push ะฒ ัะตะฟะพะทะธัะพัััั
.
teams.all_repositories_admin_permission_desc=ะฆั ะบะพะผะฐะฝะดะฐ ะฝะฐะดะฐั ะดะพะทะฒัะป ะะดะผัะฝัััััะฒะฐะฝะฝั ะดะปั ะฒััั
ัะตะฟะพะทะธัะพัััะฒ : ััะฐัะฝะธะบะธ ะผะพะถััั ะฟะตัะตะณะปัะดะฐัะธ, ะฒะธะบะพะฝัะฒะฐัะธ push ัะฐ ะดะพะดะฐะฒะฐัะธ ัะฟัะฒัะพะฑััะฝะธะบัะฒ.
+code = ะะพะด
+open_dashboard = ะัะดะบัะธัะธ ะฟะฐะฝะตะปั ัะฟัะฐะฒะปัะฝะฝั
+follow_blocked_user = ะะธ ะฝะต ะผะพะถะตัะต ััะตะถะธัะธ ะทะฐ ัััั ะพัะณะฐะฝัะทะฐัััั, ัะพะผั ัะพ ะฒะฐั ั ะฝัะน ะทะฐะฑะปะพะบัะฒะฐะปะธ.
+teams.invite.description = ะฉะพะฑ ะฟัะธัะดะฝะฐัะธัั ะดะพ ะบะพะผะฐะฝะดะธ, ะฝะฐัะธัะฝััั ะบะฝะพะฟะบั ะฝะธะถัะต.
+teams.invite.title = ะะฐั ะทะฐะฟัะพัะตะฝะพ ะฟัะธัะดะฝะฐัะธัั ะดะพ ะบะพะผะฐะฝะดะธ %s ะฒ ะพัะณะฐะฝัะทะฐััั %s .
+form.name_reserved = ะะฐะทะฒั ะพัะณะฐะฝัะทะฐััั ยซ%sยป ะทะฐัะตะทะตัะฒะพะฒะฐะฝะพ.
+settings.change_orgname_redirect_prompt.with_cooldown.one = ะกัะฐัะฐ ะฝะฐะทะฒะฐ ะฑัะดะต ะดะพัััะฟะฝะฐ ะฒััะผ ะฟััะปั ะฟะตััะพะดั ะทะฐั
ะธััั, ัะบะธะน ััะธะฒะฐัะธะผะต %[1]d ะดะตะฝั. ะัะพััะณะพะผ ะฟะตััะพะดั ะทะฐั
ะธััั ะฒะธ ัะต ะผะพะถะตัะต ะฟะพะฒะตัะฝััะธ ััะฐัั ะฝะฐะทะฒั.
+settings.change_orgname_redirect_prompt.with_cooldown.few = ะกัะฐัะฐ ะฝะฐะทะฒะฐ ะฑัะดะต ะดะพัััะฟะฝะฐ ะฒััะผ ะฟััะปั ะฟะตััะพะดั ะทะฐั
ะธััั, ัะบะธะน ััะธะฒะฐัะธะผะต %[1]d ะดะฝัะฒ. ะัะพััะณะพะผ ะฟะตััะพะดั ะทะฐั
ะธััั ะฒะธ ัะต ะผะพะถะตัะต ะฟะพะฒะตัะฝััะธ ััะฐัั ะฝะฐะทะฒั.
+teams.none_access = ะะตะผะฐั ะดะพัััะฟั
+teams.invite_team_member = ะะฐะฟัะพัะธัะธ ะดะพ %s
+teams.write_access = ะะฐะฟะธั
+
+teams.invite_team_member.list = ะะฐะฟัะพัะตะฝะฝั ะฒ ะพััะบัะฒะฐะฝะฝั
+teams.invite.by = ะะฐั ะทะฐะฟัะพััั %s
[admin]
dashboard=ะะฐะฝะตะปั ัะฟัะฐะฒะปัะฝะฝั
@@ -2187,7 +2800,7 @@ organizations=ะัะณะฐะฝัะทะฐััั
repositories=ะ ะตะฟะพะทะธัะพััั
hooks=ะะตะฑ-ั
ัะบะธ
authentication=ะะถะตัะตะปะฐ ะฐะฒัะตะฝัะธััะบะฐััั
-emails=ะะปะตะบััะพะฝะฝั ะฐะดัะตัะธ ะะพัะธัััะฒะฐัะฐ
+emails=ะะปะตะบััะพะฝะฝั ะฐะดัะตัะธ
config=ะะพะฝััะณััะฐััั
notices=ะกะฟะพะฒััะตะฝะฝั ัะธััะตะผะธ
monitor=ะะพะฝััะพัะธะฝะณ
@@ -2197,7 +2810,7 @@ total=ะ ะฐะทะพะผ: %d
dashboard.statistic=ะัะดััะผะพะบ
dashboard.operations=ะขะตั
ะฝััะฝะต ะพะฑัะปัะณะพะฒัะฒะฐะฝะฝั
-dashboard.system_status=ะกัะฐััั ัะธััะตะผะธ
+dashboard.system_status=ะกัะฐะฝ ัะธััะตะผะธ
dashboard.operation_name=ะะฐะทะฒะฐ ะพะฟะตัะฐััั
dashboard.operation_switch=ะะตัะตะผะบะฝััะธ
dashboard.operation_run=ะะฐะฟัััะธัะธ
@@ -2214,7 +2827,7 @@ dashboard.cron.error=ะะพะผะธะปะบะฐ ะฒ Cron: %s: %[3]s
dashboard.cron.finished=Cron: %[1]s ะทะฐะฒะตััะตะฝะพ
dashboard.delete_inactive_accounts=ะะธะดะฐะปะธัะธ ะฒัั ะฝะตะฐะบัะธะฒะพะฒะฐะฝั ะพะฑะปัะบะพะฒั ะทะฐะฟะธัะธ
dashboard.delete_inactive_accounts.started=ะะฐะฟััะตะฝะพ ะทะฐะฒะดะฐะฝะฝั ะฒะธะดะฐะปะตะฝะฝั ะฒัั ะฝะตะฐะบัะธะฒะพะฒะฐะฝะธั
ะพะฑะปัะบะพะฒะธั
ะทะฐะฟะธััะฒ.
-dashboard.delete_repo_archives=ะะธะดะฐะปะธัะธ ะฒัั ะฐัั
ัะฒะธ ัะตะฟะพะทะธัะพัััะฒ (ZIP, TAR.GZ, ั ั. ะด..)
+dashboard.delete_repo_archives=ะะธะดะฐะปะธัะธ ะฒัั ะฐัั
ัะฒะธ ัะตะฟะพะทะธัะพัััะฒ (ZIP, TAR.GZ ัะพัะพ)
dashboard.delete_repo_archives.started=ะะฐะฟััะตะฝะพ ะทะฐะฒะดะฐะฝะฝั ะฒะธะดะฐะปะตะฝะฝั ะฒััั
ะฐัั
ัะฒัะฒ ัะตะฟะพะทะธัะพัััะฒ.
dashboard.delete_missing_repos=ะะธะดะฐะปะธัะธ ะฒัั ะทะฐะฟะธัะธ ะฟัะพ ัะตะฟะพะทะธัะพััั ะท ะฒัะดัััะฝัะผะธ ัะฐะนะปะฐะผะธ Git
dashboard.delete_missing_repos.started=ะะฐะฟััะตะฝะพ ะทะฐะฒะดะฐะฝะฝั ะฒะธะดะฐะปะตะฝะฝั ะฒััั
ัะตะฟะพะทะธัะพัััะฒ, ะฒ ัะบะธั
ะฒัะดัััะฝั ัะฐะนะปะธ Git.
@@ -2226,13 +2839,13 @@ dashboard.archive_cleanup=ะะธะดะฐะปะธัะธ ััะฐัั ะฐัั
ัะฒะธ ัะตะฟะพะทะธ
dashboard.deleted_branches_cleanup=ะัะธะฑัะฐัะธ ะฒะธะดะฐะปะตะฝั ะณัะปะบะธ
dashboard.update_migration_poster_id=ะะฝะพะฒะธัะธ ะผัะณัะพะฒะฐะฝั ID ะฐะฒัะพััะฒ
dashboard.git_gc_repos=ะะธะบะพะฝะฐัะธ ะพัะธััะบั ัะผัััั ะดะปั ะฒััั
ัะตะฟะพะทะธัะพัััะฒ
-dashboard.resync_all_sshkeys=ะะฝะพะฒะธัะธ ัะฐะนะป '.ssh/authorized_keys' ะท SSH ะบะปััะฐะผะธ Forgejo.
-dashboard.resync_all_sshprincipals=ะะฝะพะฒััั ัะฐะนะป '.ssh/authorized_princัipals' ะท SSH ะดะฐะฝะธะผะธ ะบะพัะธัััะฒะฐัะฐ Forgejo.
-dashboard.resync_all_hooks=ะะตัะตัะธะฝั
ัะพะฝัะทัะฒะฐัะธ ะฟะตัะตะด-ะฟัะธะนะฝััะฝั, ะพะฝะพะฒะปัััั ัะฐ ะฟะพัั-ะฟัะธะนะฝััะฝั ั
ัะบะธ ะฒ ัััั
ัะตะฟะพะทะธัะพัััั
.
+dashboard.resync_all_sshkeys=ะะฝะพะฒะธัะธ ัะฐะนะป ยซ.ssh/authorized_keysยป ะท SSH-ะบะปััะฐะผะธ Forgejo.
+dashboard.resync_all_sshprincipals=ะะฝะพะฒะธัะธ ัะฐะนะป ยซ.ssh/authorized_principalsยป ะท SSH ะดะฐะฝะธะผะธ ะบะพัะธัััะฒะฐัะฐ Forgejo.
+dashboard.resync_all_hooks=ะะตัะตัะธะฝั
ัะพะฝัะทัะฒะฐัะธ ะฟะตัะตะด-ะฟัะธะนะฝััะฝั, ะพะฝะพะฒะปัััั ัะฐ ะฟะพัั-ะฟัะธะนะฝััะฝั ั
ัะบะธ ะฒ ัััั
ัะตะฟะพะทะธัะพัััั
dashboard.reinit_missing_repos=ะะตัะตัะฝัััะฐะปัะทัะฒะฐัะธ ััั ัะตะฟะพะทะธัััั git-ัะฐะนะปะธ ัะบะธั
ะฒััะฐัะตะฝะพ
dashboard.sync_external_users=ะกะธะฝั
ัะพะฝัะทัะฒะฐัะธ ะดะฐะฝั ะทะพะฒะฝััะฝัั
ะบะพัะธัััะฒะฐััะฒ
dashboard.cleanup_hook_task_table=ะัะธััะธัะธ hook_task ัะฐะฑะปะธัั
-dashboard.server_uptime=Uptime ัะตัะฒะตัั
+dashboard.server_uptime=ะงะฐั ัะพะฑะพัะธ ัะตัะฒะตัะฐ
dashboard.current_goroutine=ะะพัะพัะฝะฐ ะบัะปัะบัััั Goroutines
dashboard.current_memory_usage=ะะพัะพัะฝะต ะฒะธะบะพัะธััะฐะฝะฝั ะฟะฐะผ'ััั
dashboard.total_memory_allocated=ะะธะดัะปะตะฝะพ ะฟะฐะผ'ััั ะทะฐะณะฐะปะพะผ
@@ -2264,7 +2877,7 @@ dashboard.gc_times=ะัะปัะบัััั ะทะฐะฟััะบัะฒ ะทะฑะธัะฐัะฐ ัะผััั
dashboard.delete_old_actions=ะะธะดะฐะปะธัะธ ะฒัั ััะฐัั ะดัั ะท ะฑะฐะทะธ ะดะฐะฝะธั
dashboard.delete_old_actions.started=ะะธะดะฐะปะตะฝะฝั ะฒััั
ััะฐัั ะดัั ะท ะฑะฐะทะธ ะดะฐะฝะธั
ัะพะทะฟะพัะฐัะพ.
-users.user_manage_panel=ะะตััะฒะฐะฝะฝั ะพะฑะปัะบะพะฒะธะผะธ ะทะฐะฟะธัะฐะผะธ ะบะพัะธัััะฒะฐััะฒ
+users.user_manage_panel=ะะตััะฒะฐะฝะฝั ะพะฑะปัะบะพะฒะธะผะธ ะทะฐะฟะธัะฐะผะธ
users.new_account=ะกัะฒะพัะธัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
users.name=ะะผ'ั ะบัะธัััะฒะฐัะฐ
users.full_name=ะะพะฒะฝะต ัะผ'ั
@@ -2276,7 +2889,7 @@ users.repos=ะ ะตะฟะพะทะธัะพััั
users.created=ะกัะฒะพัะตะฝะพ
users.last_login=ะััะฐะฝะฝัะน ะฒั
ัะด
users.never_login=ะัะบะพะปะธ ะฝะต ะฒั
ะพะดะธะฒ
-users.send_register_notify=ะะฐะดััะปะฐัะธ ะฟะพะฒัะดะพะผะปะตะฝะฝั ะฟัะพ ัะตััััะฐััั ะบะพัะธัััะฒะฐัะฐ
+users.send_register_notify=ะะพะฒัะดะพะผะธัะธ ะฟัะพ ัะตััััะฐััั ะฝะฐ ะตะปะตะบััะพะฝะฝั ะฟะพััั
users.edit=ะ ะตะดะฐะณัะฒะฐัะธ
users.auth_source=ะะถะตัะตะปะพ ะฐะฒัะตะฝัะธััะบะฐััั
users.local=ะะพะบะฐะปัะฝั
@@ -2284,18 +2897,18 @@ users.auth_login_name=ะะพะณัะฝ ะดะปั ะฐะฒัะพัะธะทะฐััั
users.password_helper=ะะฐะปะธััะต ะฟะฐัะพะปั ะฟะพัะพะถะฝัะผ, ัะพะฑ ะฝะต ะทะผัะฝัะฒะฐัะธ ะนะพะณะพ.
users.update_profile_success=ะะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะบะพัะธัััะฒะฐัะฐ ะฑัะปะพ ะพะฝะพะฒะปะตะฝะพ.
users.edit_account=ะ ะตะดะฐะณัะฒะฐัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
-users.max_repo_creation=ะะฐะบัะธะผะฐะปัะฝะต ัะธัะปะพ ัะตะฟะพะทะธัะพัััะฒ
+users.max_repo_creation=ะะฐะบัะธะผะฐะปัะฝะฐ ะบัะปัะบัััั ัะตะฟะพะทะธัะพัััะฒ
users.max_repo_creation_desc=(ะะฒะตะดััั -1, ัะพะฑ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะณะปะพะฑะฐะปัะฝะธะน ะปัะผัั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ.)
users.is_activated=ะะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะบะพัะธัััะฒะฐัะฐ ัะฒัะผะบะฝะตะฝะพ
users.prohibit_login=ะะธะผะบะฝััะธ ะฒั
ัะด
-users.is_admin=ะะดะผัะฝััััะฐัะพั
+users.is_admin=ะะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฐะดะผัะฝััััะฐัะพัะฐ
users.is_restricted=ะะฑะผะตะถะตะฝะธะน
users.allow_git_hook=ะะพะถะต ััะฒะพััะฒะฐัะธ Git ั
ัะบะธ
users.allow_git_hook_tooltip=Git ั
ัะบะธ ะฒะธะบะพะฝัััััั ะฒัะด ัะผะตะฝั ะบะพัะธัััะฒะฐัะฐ OS ัะตัะฒััั Forgejo ั ะผะฐััั ะพะดะฝะฐะบะพะฒะธะน ััะฒะตะฝั ะดะพัััะฟั ะดะพ ั
ะพััะฐ. ะฏะบ ัะตะทัะปััะฐั, ะบะพัะธัััะฒะฐัั ะท ะดะพัััะฟะพะผ ะดะพ Git-ั
ัะบัะฒ ะผะพะถััั ะพััะธะผะฐัะธ ะดะพัััะฟ ั ะทะผัะฝัะฒะฐัะธ ะฒัั ัะตะฟะพะทะธัะพััั Forgejo, ะฐ ัะฐะบะพะถ ะฑะฐะทั ะดะฐะฝะธั
, ัะพ ะฒะธะบะพัะธััะพะฒัััััั ะฒ Forgejo. ะัะถะต, ะฒะพะฝะธ ัะฐะบะพะถ ะทะดะฐัะฝั ะพััะธะผะฐัะธ ะฟัะฐะฒะฐ ะฐะดะผัะฝััััะฐัะพัะฐ Forgejo.
users.allow_import_local=ะะพะถะต ัะผะฟะพัััะฒะฐัะธ ะปะพะบะฐะปัะฝั ัะตะฟะพะทะธัะพััั
-users.allow_create_organization=ะะพะถะต ััะฒะพััะฒะฐัะธ ะพัะณะฐะฝัะทะฐััะน
+users.allow_create_organization=ะะพะถะต ััะฒะพััะฒะฐัะธ ะพัะณะฐะฝัะทะฐััั
users.update_profile=ะะฝะพะฒะธัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
-users.delete_account=ะะธะดะฐะปะธัะธ ัะตะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
+users.delete_account=ะะธะดะฐะปะธัะธ ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั
users.still_own_repo=ะะฐั ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฒัะต ัะต ะฒะพะปะพะดัั ะพะดะฝะธะผ ะฐะฑะพ ะบัะปัะบะพะผะฐ ัะตะฟะพะทะธัะพัััะผะธ, ัะฟะพัะฐัะบั ะฒะฐะผ ะฟะพัััะฑะฝะพ ะฒะธะดะฐะปะธัะธ ะฐะฑะพ ะฟะตัะตะดะฐัะธ ัั
.
users.still_has_org=ะฆะตะน ะพะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะฒัะต ัะต ั ััะฐัะฝะธะบะพะผ ะพะดะฝััั ะฐะฑะพ ะดะตะบัะปัะบะพั
ะพัะณะฐะฝัะทะฐััะน. ะะปั ะฟัะพะดะพะฒะถะตะฝะฝั, ะฟะพะบะธะฝััะต ะฐะฑะพ ะฒะธะดะฐะปััั ะพัะณะฐะฝัะทะฐััั.
users.deletion_success=ะะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ะบะพัะธัััะฒะฐัะฐ ะฑัะปะพ ะฒะธะดะฐะปะตะฝะพ.
@@ -2310,10 +2923,10 @@ users.list_status_filter.is_restricted=ะ ะพะฑะผะตะถะตะฝะฝัะผะธ
users.list_status_filter.not_restricted=ะะตะท ะพะฑะผะตะถะตะฝั
users.list_status_filter.is_prohibit_login=ะั
ัะด ะทะฐะฑะพัะพะฝะตะฝะพ
users.list_status_filter.not_prohibit_login=ะั
ัะด ะดะพะทะฒะพะปะตะฝะพ
-users.list_status_filter.is_2fa_enabled=2FA ัะฒัะผะบะฝะตะฝะฐ
-users.list_status_filter.not_2fa_enabled=2FA ะฒะธะผะบะฝะตะฝะฐ
+users.list_status_filter.is_2fa_enabled=2FA ัะฒัะผะบะฝะตะฝะพ
+users.list_status_filter.not_2fa_enabled=2FA ะฒะธะผะบะฝะตะฝะพ
-emails.email_manage_panel=ะฃะฟัะฐะฒะปัะฝะฝั ะฟะพััะพั ะบะพัะธัััะฒะฐัะฐ
+emails.email_manage_panel=ะะตััะฒะฐะฝะฝั ะตะปะตะบััะพะฝะฝะธะผะธ ะฐะดัะตัะฐะผะธ ะบะพัะธัััะฒะฐััะฒ
emails.primary=ะะพะปะพะฒะฝะธะน
emails.activated=ะะบัะธะฒะพะฒะฐะฝะพ
emails.filter_sort.email=ะะปะตะบััะพะฝะฝะฐ ะฟะพััะฐ
@@ -2333,7 +2946,7 @@ orgs.new_orga=ะะพะฒะฐ ะพัะณะฐะฝัะทะฐััั
repos.repo_manage_panel=ะะตััะฒะฐะฝะฝั ัะตะฟะพะทะธัะพัััะผะธ
repos.unadopted=ะะตะฟัะธะนะฝััั ัะตะฟะพะทะธัะพััั
-repos.unadopted.no_more=ะะต ะทะฝะฐะนะดะตะฝะพ ะฑัะปััะต ะฝะตะฟัะธะนะฝััะธั
ัะตะฟะพะทะธัะพัััะฒ
+repos.unadopted.no_more=ะะต ะทะฝะฐะนะดะตะฝะพ ะฝะตะฟัะธะนะฝััะธั
ัะตะฟะพะทะธัะพัััะฒ.
repos.owner=ะะปะฐัะฝะธะบ
repos.name=ะะฐะทะฒะฐ
repos.private=ะัะธะฒะฐัะฝะธะน
@@ -2349,7 +2962,7 @@ packages.type=ะขะธะฟ
packages.repository=ะ ะตะฟะพะทะธัะพััะน
packages.size=ะ ะพะทะผัั
-defaulthooks=ะะตะฑ-ั
ัะบะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
+defaulthooks=ะะตะฑั
ัะบะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
defaulthooks.add_webhook=ะะพะดะฐัะธ ะฒะตะฑ-ั
ัะบ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
defaulthooks.update_webhook=ะะผัะฝะธัะธ ะฒะตะฑ-ั
ัะบ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
@@ -2357,12 +2970,12 @@ systemhooks=ะกะธััะตะผะฝั ะฒะตะฑั
ัะบะธ
systemhooks.add_webhook=ะะพะดะฐัะธ ัะธััะตะผะฝะธะน ะฒะตะฑั
ัะบ
systemhooks.update_webhook=ะะฝะพะฒะธัะธ ัะธััะตะผะฝะธะน ะฒะตะฑั
ัะบ
-auths.auth_manage_panel=ะะตััะฒะฐะฝะฝั ะดะถะตัะตะปะพะผ ะฐะฒัะตะฝัะธััะบะฐััั
+auths.auth_manage_panel=ะะตััะฒะฐะฝะฝั ะดะถะตัะตะปะฐะผะธ ะฐะฒัะตะฝัะธััะบะฐััั
auths.new=ะะพะดะฐัะธ ะดะถะตัะตะปะพ ะฐะฒัะตะฝัะธััะบะฐััั
auths.name=ะะผ'ั
auths.type=ะขะธะฟ
auths.enabled=ะฃะฒัะผะบะฝะตะฝะพ
-auths.syncenabled=ะฃะฒัะผะบะฝััะธ ัะธะฝั
ัะพะฝัะทะฐััั ะบะพัะธัััะฒะฐัะฐ
+auths.syncenabled=ะฃะฒัะผะบะฝััะธ ัะธะฝั
ัะพะฝัะทะฐััั ะบะพัะธัััะฒะฐััะฒ
auths.updated=ะะฝะพะฒะปะตะฝะพ
auths.auth_type=ะขะธะฟ ะฐะฒัะตะฝัะธััะบะฐััั
auths.auth_name=ะะฐะทะฒะฐ ะฐะฒัะตะฝัะธััะบะฐััั
@@ -2384,23 +2997,23 @@ auths.attributes_in_bind=ะะธััะณัะฒะฐัะธ ะฐััะธะฑััะธ ะฒ ะบะพะฝัะตะบั
auths.allow_deactivate_all=ะะพะทะฒะพะปะธัะธ ะฟะพัะพะถะฝัะพะผั ัะตะทัะปััะฐัั ะฟะพััะบั ะฒัะดะบะปััะธัะธ ะฒััั
ะบะพัะธัััะฒะฐััะฒ
auths.use_paged_search=ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะฟะพััะพััะฝะบะพะฒะธะน ะฟะพััะบ
auths.search_page_size=ะ ะพะทะผัั ััะพััะฝะบะธ
-auths.filter=ะะพัะธัััะฒะฐััะบะธะน ััะปััั
+auths.filter=ะคัะปััั ะบะพัะธัััะฒะฐััะฒ
auths.admin_filter=ะคัะปััั ะฐะดะผัะฝััััะฐัะพัะฐ
-auths.restricted_filter=ะะฑะผะตะถัััะธะน ััะปััั
-auths.restricted_filter_helper=ะะฐะปะธััะต ะฟัััะธะผ, ัะพะฑ ะฝะต ะฒััะฐะฝะพะฒะปัะฒะฐัะธ ะพะฑะผะตะถะตะฝะฝั ะฝะฐ ะถะพะดะฝะพะณะพ ะท ะบะพัะธัััะฒะฐััะฒ. ะะธะบะพัะธััะพะฒัะนัะต ะทััะพัะบั ('*') ัะพะฑ ะฒััะฐะฝะพะฒะธัะธ ะพะฑะผะตะถะตะฝะฝั ะฝะฐ ะฒััั
ะบะพัะธัััะฒะฐััะฒ, ัะบั ะฝะต ะฒัะดะฟะพะฒัะดะฐััั ััะปัััั ะะดะผัะฝััััะฐัะพัะฐ.
+auths.restricted_filter=ะคัะปััั ะพะฑะผะตะถะตะฝะธั
+auths.restricted_filter_helper=ะะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ัะพะฑ ะฝะต ะฒััะฐะฝะพะฒะปัะฒะฐัะธ ะพะฑะผะตะถะตะฝะฝั ะฝะฐ ะถะพะดะฝะพะณะพ ะท ะบะพัะธัััะฒะฐััะฒ. ะะธะบะพัะธััะพะฒัะนัะต ะทััะพัะบั (ยซ*ยป), ัะพะฑ ัััะฐะฝะพะฒะธัะธ ะพะฑะผะตะถะตะฝะฝั ะฝะฐ ะฒััั
ะบะพัะธัััะฒะฐััะฒ, ัะบั ะฝะต ะฒัะดะฟะพะฒัะดะฐััั ะคัะปัััั ะฐะดะผัะฝััััะฐัะพัะฐ.
auths.group_search_base=ะะพััะบะพะฒะฐ ะฑะฐะทะฐ ะณััะฟ DN
auths.group_attribute_list_users=ะััะธะฑัั ะณััะฟะธ ะทั ัะฟะธัะบะพะผ ะบะพัะธัััะฒะฐััะฒ
-auths.user_attribute_in_group=ะััะธะฑััะธ ะบะพัะธัััะฒะฐัะฐ ะฒ ะณััะฟั
+auths.user_attribute_in_group=ะััะธะฑัั ะบะพัะธัััะฒะฐัะฐ ะฒ ะณััะฟั
auths.ms_ad_sa=ะััะธะฑััะธ ะฟะพััะบั MS AD
auths.smtp_auth=ะขะธะฟ ะฐะฒัะตะฝัะธััะบะฐััั SMTP
-auths.smtphost=SMTP ั
ะพัั
-auths.smtpport=SMTP ะฟะพัั
+auths.smtphost=ะะดัะตัะฐ SMTP
+auths.smtpport=ะะพัั SMTP
auths.allowed_domains=ะะพะทะฒะพะปะตะฝั ะดะพะผะตะฝะธ
-auths.allowed_domains_helper=ะะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ัะพะฑ ะดะพะทะฒะพะปะธัะธ ะฒัั ะดะพะผะตะฝะธ. ะ ะพะทะดัะปััั ะบัะปัะบะฐ ะดะพะผะตะฝัะฒ ะทะฐ ะดะพะฟะพะผะพะณะพั ะบะพะผะธ (',').
+auths.allowed_domains_helper=ะะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ัะพะฑ ะดะพะทะฒะพะปะธัะธ ะฒัั ะดะพะผะตะฝะธ. ะ ะพะทะดัะปัะนัะต ะบัะปัะบะฐ ะดะพะผะตะฝัะฒ ะทะฐ ะดะพะฟะพะผะพะณะพั ะบะพะผะธ (ยซ,ยป).
auths.skip_tls_verify=ะัะพะฟัััะธัะธ ะฟะตัะตะฒััะบั TLS
auths.force_smtps=ะัะธะผััะพะฒะพ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ SMTPS
auths.force_smtps_helper=SMTPS ะทะฐะฒะถะดะธ ะฒะธะบะพัะธััะพะฒัััััั ะฝะฐ ะฟะพััั 465. ะััะฐะฝะพะฒััั ัะตะน ะฟัะฐะฟะพัะตัั ะดะปั ะฟัะธะผััะพะฒะพะณะพ ะฒะธะบะพัะธััะฐะฝะฝั SMTPS ะฝะฐ ัะฝัะธั
ะฟะพััะฐั
. (ะ ัะฝัะพะผั ะฒะธะฟะฐะดะบั STARTTLS ะฑัะดะต ะฒะธะบะพัะธััะพะฒัะฒะฐัะธัั ะดะปั ัะฝัะธั
ะฟะพัััะฒ, ัะบัะพ ั
ะพัั ะนะพะณะพ ะฟัะดััะธะผัั.)
-auths.helo_hostname=HELO Hostname
+auths.helo_hostname=ะะผ'ั ั
ะพััั HELO
auths.helo_hostname_helper=ะะผ'ั ั
ะพััะฐ, ัะบะต ะฑัะดะต ะฝะฐะดััะปะฐะฝะพ ะท HELO. ะะฐะปะธััะต ะฟะพัะพะถะฝัะผ, ะฐะฑะธ ะฝะฐะดัะธะปะฐัะธ ะฟะพัะพัะฝะต ัะผ'ั ั
ะพััะฐ.
auths.disable_helo=ะะธะผะบะฝััะธ HELO
auths.pam_service_name=ะะผ'ั ัะปัะถะฑะธ PAM
@@ -2430,22 +3043,22 @@ auths.sspi_separator_replacement_helper=ะกะธะผะฒะพะป, ัะบะธะน ะทะฐะผัะฝัั ั
auths.sspi_default_language=ะขะธะฟะพะฒะฐ ะผะพะฒะฐ ะบะพัะธัััะฒะฐัะฐ
auths.sspi_default_language_helper=ะขะธะฟะพะฒะฐ ะผะพะฒะฐ ะดะปั ะบะพัะธัััะฒะฐััะฒ, ัะบั ััะฒะพััััััั ะฐะฒัะพะผะฐัะธัะฝะพ ะฟัะธ SSPI-ะฐะฒัะตะฝัะธััะบะฐััั. ะะฐะปะธััะต ะฝะต ะฒะบะฐะทะฐะฝะธะผ, ัะบัะพ ะฝะฐะดะฐััะต ะฟะตัะตะฒะฐะณั ะฐะฒัะพะผะฐัะธัะฝะพะผั ะฒะธะทะฝะฐัะตะฝะฝั ะผะพะฒะธ.
auths.tips=ะะพัะฐะดะธ
-auths.tips.oauth2.general=OAuth2 ะฐะฒัะตะฝัะธััะบะฐััั
+auths.tips.oauth2.general=ะะฒัะตะฝัะธััะบะฐััั OAuth2
auths.tip.oauth2_provider=ะะพััะฐัะฐะปัะฝะธะบ OAuth2
-auths.tip.bitbucket=ะกัะฒะพัััั OAuth URI ะฝะฐ ััะพััะฝัั https://bitbucket.org/account/user//oauth-consumers/new ั ะดะพะดะฐะนัะต ะฟัะฐะฒะฐ 'Account' - 'Read'
+auths.tip.bitbucket=ะกัะฒะพัััั OAuth URI ะฝะฐ ััะพััะฝัั %s
auths.tip.nextcloud=`ะะฐัะตัััััะนัะต ะฝะพะฒะพะณะพ ัะฟะพะถะธะฒะฐัะฐ OAuth ั ะฒะฐัะพะผั ะตะบะทะตะผะฟะปััั ะทะฐ ะดะพะฟะพะผะพะณะพั ะฝะฐัััะฟะฝะพะณะพ ะผะตะฝั "ะะฐะปะฐัััะฒะฐะฝะฝั -> ะะตะทะฟะตะบะฐ -> ะบะปััะฝั OAuth 2.0"`
-auths.tip.dropbox=ะะพะดะฐะนัะต ะฝะพะฒะธะน ะดะพะดะฐัะพะบ ะฝะฐ https://www.dropbox.com/developers/apps
-auths.tip.facebook=`ะกัะฒะพัััั ะฝะพะฒะธะน ะดะพะดะฐัะพะบ ะฝะฐ https://developers.facebook.com/apps ั ะดะพะดะฐะนัะต ะผะพะดัะปั "Facebook Login"`
-auths.tip.github=ะะพะดะฐะนัะต OAuth ะดะพะดะฐัะพะบ ะฝะฐ https://github.com/settings/applications/new
+auths.tip.dropbox=ะกัะฒะพัััั ะฝะพะฒะธะน ะดะพะดะฐัะพะบ ะฝะฐ %s
+auths.tip.facebook=ะะฐัะตัััััะนัะต ะฝะพะฒะธะน ะดะพะดะฐัะพะบ ะฝะฐ %s ั ะดะพะดะฐะนัะต ะผะพะดัะปั ยซFacebook Loginยป
+auths.tip.github=ะะฐัะตัััััะนัะต ะฝะพะฒะธะน ะดะพะดะฐัะพะบ OAuth ะฝะฐ %s
auths.tip.gitlab=ะะพะดะฐะนัะต ะฝะพะฒะธะน ะดะพะดะฐัะพะบ ะฝะฐ https://gitlab.com/profile/applications
-auths.tip.google_plus=ะััะธะผะฐะนัะต ะพะฑะปัะบะพะฒั ะดะฐะฝั ะบะปััะฝัะฐ OAuth2 ะฒ ะบะพะฝัะพะปั Google API ะฝะฐ ััะพััะฝัั https://console.developers.google.com/
+auths.tip.google_plus=ะััะธะผะฐะนัะต ะพะฑะปัะบะพะฒั ะดะฐะฝั ะบะปััะฝัะฐ OAuth2 ะฒ ะบะพะฝัะพะปั Google API ะฝะฐ ััะพััะฝัั %s
auths.tip.openid_connect=ะะธะบะพัะธััะพะฒัะนัะต OpenID Connect Discovery URL (/.well-known/openid-configuration) ะดะปั ะฐะฒัะพะผะฐัะธัะฝะพั ะฝะฐัััะพะนะบะธ ะฒั
ะพะดั OAuth
-auths.tip.twitter=ะะตัะตะนะดััั ะฝะฐ https://dev.twitter.com/apps, ััะฒะพัััั ะฟัะพะณัะฐะผั ั ะฟะตัะตะบะพะฝะฐะนัะตัั, ัะพ ะฒะบะปััะตะฝะฐ ะพะฟััั ยซะะพะทะฒะพะปะธัะธ ัั ะฟัะพะณัะฐะผั ะดะปั ะฒั
ะพะดั ะฒ ัะธััะตะผั ะทะฐ ะดะพะฟะพะผะพะณะพั Twitterยป
-auths.tip.discord=ะะฐัะตัััััะนัะต ะฝะพะฒะธะน ะดะพะดะฐัะพะบ ะฝะฐ https://discordapp.com/developers/applications/me
-auths.tip.yandex=`ะกัะฒะพัััั ะฝะพะฒั ะฟัะพะณัะฐะผั ะฒ https://oauth.yandex.com/client/new. ะะธะฑะตัััั ะฝะฐัััะฟะฝั ะดะพะทะฒะพะปะธ ะท "Yandex. assport API": "ะะพัััะฟ ะดะพ ะฐะดัะตัะธ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ", "ะะพัััะฟ ะดะพ ะฐะฒะฐัะฐัะฐ" ั "ะะพัััะฟ ะดะพ ัะผะตะฝั ะบะพัะธัััะฒะฐัะฐ, ัะผะตะฝั ัะฐ ะฟััะทะฒะธัะฐ, ััะฐัั"`
+auths.tip.twitter=ะะตัะตะนะดััั ะฝะฐ %s, ััะฒะพัััั ะฟัะพะณัะฐะผั ั ะฟะตัะตะบะพะฝะฐะนัะตัั, ัะพ ะฒะบะปััะตะฝะฐ ะพะฟััั ยซะะพะทะฒะพะปะธัะธ ัั ะฟัะพะณัะฐะผั ะดะปั ะฒั
ะพะดั ะฒ ัะธััะตะผั ะทะฐ ะดะพะฟะพะผะพะณะพั Twitterยป
+auths.tip.discord=ะะฐัะตัััััะนัะต ะฝะพะฒะธะน ะดะพะดะฐัะพะบ ะฝะฐ %s
+auths.tip.yandex=ะกัะฒะพัััั ะฝะพะฒะธะน ะดะพะดะฐัะพะบ ะฝะฐ %s. ะฃ ัะพะทะดัะปั ยซYandex.Passport APIยป ะฒะธะฑะตัััั ัะฐะบั ะดะพะทะฒะพะปะธ: ยซะะพัััะฟ ะดะพ ะฐะดัะตัะธ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธยป, ยซะะพัััะฟ ะดะพ ะฐะฒะฐัะฐัะฐยป ั ยซะะพัััะฟ ะดะพ ัะผะตะฝั ะบะพัะธัััะฒะฐัะฐ, ัะผะตะฝั ัะฐ ะฟััะทะฒะธัะฐ, ััะฐััยป
auths.tip.mastodon=ะะฒะตะดััั URL ัะฟะตััะฐะปัะฝะพะณะพ ะตะบะทะตะผะฟะปััะฐ ะดะปั ะตะบะทะตะผะฟะปััะฐ mastodon, ัะบะธะน ะฒะธ ั
ะพัะตัะต ะฐะฒัะตะฝัะธััะบัะฒะฐัะธ ะทะฐ ะดะพะฟะพะผะพะณะพั (ะฐะฑะพ ะฒะธะบะพัะธััะพะฒัะฒะฐัะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ)
auths.edit=ะ ะตะดะฐะณัะฒะฐัะธ ะดะถะตัะตะปะพ ะฐะฒัะตะฝัะธััะบะฐััั
-auths.activated=ะฆั ะฐััะตะฝัะธััะบะฐััั ะฐะบัะธะฒะพะฒะฐะฝะฐ
+auths.activated=ะฆะต ะดะถะตัะตะปะพ ะฐะฒัะพัะธะทะฐััั ะฐะบัะธะฒะพะฒะฐะฝะต
auths.update_success=ะะฐัะฐะผะตััะธ ะฐััะตะฝัะธััะบะฐััั ะพะฝะพะฒะปะตะฝั.
auths.update=ะะฝะพะฒะธัะธ ะดะถะตัะตะปะพ ะฐะฒัะตะฝัะธััะบะฐััั
auths.delete=ะะธะดะฐะปะธัะธ ะดะถะตัะตะปะพ ะฐะฒัะตะฝัะธััะบะฐััั
@@ -2456,19 +3069,19 @@ auths.deletion_success=ะะฐะฝะฐะป ะฐััะตะฝัะธััะบะฐััั ััะฟััะฝะพ ะท
auths.login_source_of_type_exist=ะะถะตัะตะปะพ ะฐะฒัะตะฝัะธััะบะฐััั ัะฐะบะพะณะพ ัะธะฟั ะฒะถะต ะฝะฐัะฒะฝะต.
config.server_config=ะะพะฝััะณััะฐััั ัะตัะฒะตัะฐ
-config.app_name=ะะฐะทะฒะฐ ัะฐะนัั
+config.app_name=ะะฐะทะฒะฐ ะตะบะทะตะผะฟะปััะฐ
config.app_ver=ะะตัััั Forgejo
-config.app_url=ะะฐะทะพะฒะฐ URL-ะฐะดัะตัะฐ Forgejo
+config.app_url=ะะฐะทะพะฒะฐ URL-ะฐะดัะตัะฐ
config.custom_conf=ะจะปัั
ะดะพ ัะฐะนะปั ะบะพะฝััะณััะฐััั
config.custom_file_root_path=ะจะปัั
ะดะพ ัะฐะนะปั ะบะพัะธัััะฒะฐัะฐ
config.domain=ะะพะผะตะฝ ัะตัะฒะตัะฐ
config.offline_mode=ะะพะบะฐะปัะฝะธะน ัะตะถะธะผ
config.disable_router_log=ะะธะผะบะฝััะธ ะปะพะณัะฒะฐะฝะฝั ัะพััะตัั
-config.run_user=ะะฐะฟััะบ ะฒัะด ัะผะตะฝั ะะพัะธัััะฒะฐัะฐ
+config.run_user=ะะพัะธัััะฒะฐั, ะฒัะด ัะบะพะณะพ ะทะฐะฟัััะธัะธ
config.run_mode=ะ ะตะถะธะผ ะฒะธะบะพะฝะฐะฝะฝั
config.git_version=ะะตัััั Git
-config.repo_root_path=ะะพัะตะฝะตะฒะธะน ัะปัั
ัะตะฟะพะทะธัะพััั
-config.lfs_root_path=ะะพัะตะฝะตะฒะพั ัะปัั
LFS
+config.repo_root_path=ะจะปัั
ะดะพ ะบะพัะตะฝั ัะตะฟะพะทะธัะพััั
+config.lfs_root_path=ะะพัะตะฝะตะฒะธะน ัะปัั
LFS
config.log_file_root_path=ะจะปัั
ะดะพ ะปะพะณ ัะฐะนะปั
config.script_type=ะขะธะฟ ัะบัะธะฟัะฐ
config.reverse_auth_user=ะะผ'ั ะบะพัะธัััะฒะฐัะฐ ะดะปั ะฐะฒัะพัะธะทะฐััั ะฝะฐ reverse proxy
@@ -2476,19 +3089,19 @@ config.reverse_auth_user=ะะผ'ั ะบะพัะธัััะฒะฐัะฐ ะดะปั ะฐะฒัะพัะธะทะฐ
config.ssh_config=ะะพะฝััะณััะฐััั SSH
config.ssh_enabled=ะฃะฒัะผะบะฝะตะฝะพ
config.ssh_start_builtin_server=ะะธะบะพัะธััะพะฒัะฒะฐัะธ ะฒะฑัะดะพะฒะฐะฝะธะน ัะตัะฒะตั
-config.ssh_domain=ะะพะผะตะฝ SSH ัะตัะฒะตัะฐ
+config.ssh_domain=ะะพะผะตะฝ ัะตัะฒะตัะฐ SSH
config.ssh_port=ะะพัั
-config.ssh_listen_port=ะะพัั ัะพ ะฟัะพัะปัั
ะพะฒัััััั
-config.ssh_root_path=ะจะปัั
ะดะพ ะบะพัะตะฝั
+config.ssh_listen_port=ะะพัั, ัะพ ะฟัะพัะปัั
ะพะฒัััััั
+config.ssh_root_path=ะจะปัั
ะดะพ ะบะพัะตะฝั
config.ssh_key_test_path=ะจะปัั
ะดะพ ัะตััะพะฒะพะณะพ ะบะปััะฐ
-config.ssh_keygen_path=ะจะปัั
ะดะพ ะณะตะฝะตัะฐัะพัะฐ ะบะปัััะฒ ('ssh-keygen')
-config.ssh_minimum_key_size_check=ะัะฝัะผะฐะปัะฝะธะน ัะพะทะผัั ะบะปััะฐ ะฟะตัะตะฒััะบะธ
+config.ssh_keygen_path=ะจะปัั
ะดะพ ะณะตะฝะตัะฐัะพัะฐ ะบะปัััะฒ (ยซssh-keygenยป)
+config.ssh_minimum_key_size_check=ะะตัะตะฒััะบะฐ ะผัะฝัะผะฐะปัะฝะพะณะพ ัะพะทะผััั ะบะปััะฐ
config.ssh_minimum_key_sizes=ะัะฝัะผะฐะปัะฝั ัะพะทะผััะธ ะบะปัััะฒ
config.lfs_config=ะะพะฝััะณััะฐััั LFS
config.lfs_enabled=ะฃะฒัะผะบะฝะตะฝะพ
-config.lfs_content_path=ะจะปัั
ะดะพ ะบะพะฝัะตะฝัั LFS
-config.lfs_http_auth_expiry=ะะฐััะฐััะปะฐ LFS HTTP ะฐัะฝัะธััะบะฐััั
+config.lfs_content_path=ะจะปัั
ะดะพ ะฒะผัััั LFS
+config.lfs_http_auth_expiry=ะขะตัะผัะฝ ะดัั LFS HTTP-ะฐะฒัะตะฝัะธััะบะฐััั
config.db_config=ะะพะฝััะณััะฐััั ะฑะฐะทะธ ะดะฐะฝะธั
config.db_type=ะขะธะฟ
@@ -2500,42 +3113,42 @@ config.db_ssl_mode=SSL
config.db_path=ะจะปัั
config.service_config=ะะพะฝััะณััะฐััั ัะตัะฒััั
-config.register_email_confirm=ะะพัััะฑะฝะพ ะฟัะดัะฒะตัะดะธัะธ ะตะปะตะบััะพะฝะฝั ะฟะพััั ะดะปั ัะตััััะฐััั
+config.register_email_confirm=ะะธะผะฐะณะฐัะธ ะฟัะดัะฒะตัะดะธัะธ ะตะปะตะบััะพะฝะฝั ะฟะพััั ะดะปั ัะตััััะฐััั
config.disable_register=ะะธะผะบะฝััะธ ัะฐะผะพัััะนะฝั ัะตััััะฐััั
config.allow_only_internal_registration=ะะพะทะฒะพะปะธัะธ ัะตััััะฐััั ััะปัะบะธ ัะตัะตะท Forgejo
config.allow_only_external_registration=ะะพะทะฒะพะปะธัะธ ัะตััััะฐััั ััะปัะบะธ ัะตัะตะท ััะพัะพะฝะฝั ัะตัะฒััะธ
config.enable_openid_signup=ะฃะฒัะผะบะฝััะธ ัะฐะผะพัััะนะฝั ัะตััััะฐััั ะทะฐ ะดะพะฟะพะผะพะณะพั OpenID
config.enable_openid_signin=ะฃะฒัะผะบะฝััะธ ัะตััััะฐััั ะทะฐ ะดะพะฟะพะผะพะณะพั OpenID
-config.show_registration_button=`ะะพะบะฐะทัะฒะฐัะธ ะบะฝะพะฟะบั "ะ ะตััััะฐััั"`
-config.require_sign_in_view=ะะธะผะฐะณะฐัะธ ะฐะฒัะพัะธะทะฐััั ะดะปั ะฟะตัะตะณะปัะดั ััะพััะฝะพะบ
+config.show_registration_button=ะะพะบะฐะทัะฒะฐัะธ ะบะฝะพะฟะบั ยซะ ะตััััะฐัััยป
+config.require_sign_in_view=ะะธะผะฐะณะฐัะธ ะฐะฒัะพัะธะทะฐััั ะดะปั ะฟะตัะตะณะปัะดั ะฒะผัััั
config.mail_notify=ะฃะฒัะผะบะฝััะธ ัะฟะพะฒััะตะฝะฝั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะพั
config.enable_captcha=ะฃะฒัะผะบะฝััะธ CAPTCHA
-config.active_code_lives=ะงะฐั ะฐะบััะฐะปัะฝะพััั ะบะพะดะฐ ะฟัะดัะฒะตัะดะถะตะฝะฝั
-config.reset_password_code_lives=ะัะดะฝะพะฒะปะตะฝะฝั ัะฐัั ะทะฐะบัะฝัะตะฝะฝั ัะตัะผัะฝั ะดัั ะบะพะดั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
-config.default_keep_email_private=ะัะธั
ะพะฒะฐัะธ ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
+config.active_code_lives=ะขะตัะผัะฝ ะดัั ะบะพะดั ะฐะบัะธะฒะฐััั
+config.reset_password_code_lives=ะขะตัะผัะฝ ะดัั ะบะพะดั ะฒัะดะฝะพะฒะปะตะฝะฝั ะพะฑะปัะบะพะฒะพะณะพ ะทะฐะฟะธัั
+config.default_keep_email_private=ะัะธั
ะพะฒัะฒะฐัะธ ะฐะดัะตัะธ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
config.default_allow_create_organization=ะะพะทะฒะพะปะธัะธ ััะฒะพัะตะฝะฝั ะพัะณะฐะฝัะทะฐััะน ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
config.enable_timetracking=ะฃะฒัะผะบะฝััะธ ะฒัะดััะตะถะตะฝะฝั ัะฐัั
config.default_enable_timetracking=ะฃะฒัะผะบะฝััะธ ะฒัะดััะตะถะตะฝะฝั ัะฐัั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
config.default_allow_only_contributors_to_track_time=ะัะฐั
ะพะฒัะฒะฐัะธ ััะปัะบะธ ััะฐัะฝะธะบัะฒ ัะพะทัะพะฑะบะธ ะฒ ะฟัะดัะฐั
ัะฝะบั ัะฐัั
-config.no_reply_address=ะัะธั
ะพะฒะฐะฝะธะน ะดะพะผะตะฝ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
+config.no_reply_address=ะะพะผะตะฝ ะฟัะธั
ะพะฒะฐะฝะธั
ะฐะดัะตั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
config.default_visibility_organization=ะะธะดะธะผัััั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ะดะปั ะฝะพะฒะธั
ะพัะณะฐะฝัะทะฐััะน
config.default_enable_dependencies=ะฃะฒัะผะบะฝััะธ ะทะฐะปะตะถะฝะพััั ะทะฐะดะฐัั ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ
-config.webhook_config=ะะพะฝััะณััะฐััั web-ั
ัะบัะฒ
+config.webhook_config=ะะพะฝััะณััะฐััั ะฒะตะฑั
ัะบัะฒ
config.queue_length=ะะพะฒะถะธะฝะฐ ัะตัะณะธ
config.deliver_timeout=ะะฐััะธะผะบะฐ ะดะพััะฐะฒะบะธ
config.skip_tls_verify=ะัะพะฟัััะธัะธ ะฟะตัะตะฒััะบั TLS
config.mailer_enabled=ะฃะฒัะผะบะฝะตะฝะพ
config.mailer_name=ะะผ'ั
-config.mailer_smtp_port=SMTP ะฟะพัั
+config.mailer_smtp_port=ะะพัั SMTP
config.mailer_user=ะะพัะธัััะฒะฐั
config.mailer_use_sendmail=ะะธะบะพัะธััะพะฒัะฒะฐัะธ Sendmail
config.mailer_sendmail_path=ะจะปัั
ะดะพ Sendmail
config.mailer_sendmail_args=ะะพะดะฐัะบะพะฒั ะฐัะณัะผะตะฝัะธ ะดะพ Sendmail
config.mailer_sendmail_timeout=ะขะฐะนะผ-ะฐัั Sendmail
config.test_email_placeholder=ะะดัะตัะฐ ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ (ะฝะฐะฟัะธะบะปะฐะด, test@example.com)
-config.send_test_mail=ะัะดะฟัะฐะฒะธัะธ ัะตััะพะฒะพะณะพ ะปะธััะฐ
+config.send_test_mail=ะะฐะดััะปะฐัะธ ัะตััะพะฒะพะณะพ ะปะธััะฐ
config.oauth_config=ะะพะฝััะณััะฐััั OAuth
config.oauth_enabled=ะฃะฒัะผะบะฝะตะฝะพ
@@ -2549,18 +3162,18 @@ config.cache_item_ttl=ะงะฐั ะทะฑะตััะณะฐะฝะฝั ะดะฐะฝะธั
ะบะตัั
config.session_config=ะะพะฝััะณััะฐััั ัะตััั
config.session_provider=ะัะพะฒะฐะนะดะตั ัะตััั
config.provider_config=ะะพะฝััะณััะฐััั ะฟะพััะฐัะฐะปัะฝะธะบะฐ
-config.cookie_name=ะะผ'ั ัะฐะนะปั cookie
+config.cookie_name=ะะฐะทะฒะฐ ัะฐะนะปั cookie
config.gc_interval_time=ะะฝัะตัะฒะฐะป ะทะฐะฟััะบั ะทะฑะธัะฐัะฐ ัะผัััั (GC)
config.session_life_time=ะงะฐั ะถะธััั ัะตััั
config.https_only=ะขัะปัะบะธ HTTPS
-config.cookie_life_time=ะงะฐั ะถะธััั cookie-ัะฐะนะปั
+config.cookie_life_time=ะงะฐั ะถะธััั ัะฐะนะปั cookie
-config.picture_config=ะะฐะปะฐัััะฒะฐะฝะฝั ัะพัะพะณัะฐััั ะฐะฑะพ ะฐะฒะฐัะฐัะธ
+config.picture_config=ะะฐะปะฐัััะฒะฐะฝะฝั ัะพัะพะณัะฐััั ะฐะฑะพ ะฐะฒะฐัะฐัะฐ
config.picture_service=ะกะตัะฒัั ะทะพะฑัะฐะถะตะฝั
config.disable_gravatar=ะะธะผะบะฝััะธ Gravatar
-config.enable_federated_avatar=ะฃะฒัะผะบะฝััะธ ะทะพะฒะฝััะฝั ะฐะฒะฐัะฐัะธ
+config.enable_federated_avatar=ะฃะฒัะผะบะฝััะธ ัะตะดะตัะพะฒะฐะฝั ะฐะฒะฐัะฐัะธ
-config.git_config=ะะพะฝััะณััะฐััั git
+config.git_config=ะะพะฝััะณััะฐััั Git
config.git_disable_diff_highlight=ะะธะผะบะฝััะธ ะฟัะดัะฒััะบั ัะธะฝัะฐะบัะธัั diff
config.git_max_diff_lines=ะะฐะบัะธะผัะผ ััะดะบัะฒ ะฝะฐ diff (ะฝะฐ ะพะดะธะฝ ัะฐะนะป)
config.git_max_diff_line_characters=ะะฐะบัะธะผัะผ ัะธะผะฒะพะปัะฒ ะฝะฐ diff (ะฝะฐ ะพะดะฝั ัััะพะบั)
@@ -2590,7 +3203,7 @@ monitor.desc=ะะฟะธั
monitor.start=ะงะฐั ะฟะพัะฐัะบั
monitor.execute_time=ะงะฐั ะฒะธะบะพะฝะฐะฝะฝั
monitor.process.cancel=ะัะฟะธะฝะธัะธ ะฟัะพัะตั
-monitor.process.cancel_desc=ะัะฟะธะฝะบะฐ ะฟัะพัะตัั ะผะพะถะต ะฟัะธะทะฒะตััะธ ะดะพ ะฒััะฐัะธ ะดะฐะฝะธั
+monitor.process.cancel_desc=ะกะบะฐััะฒะฐะฝะฝั ะฟัะพัะตัั ะผะพะถะต ะฟัะธะทะฒะตััะธ ะดะพ ะฒััะฐัะธ ะดะฐะฝะธั
monitor.process.cancel_notices=ะัะฟะธะฝะธัะธ: %s ?
monitor.process.children=ะะพัััะฝั ะฟัะพัะตัะธ
@@ -2599,8 +3212,8 @@ monitor.queue=ะงะตัะณะฐ: %s
monitor.queue.name=ะะฐะทะฒะฐ
monitor.queue.type=ะขะธะฟ
monitor.queue.exemplar=ะัะธะบะปะฐะด ัะธะฟั
-monitor.queue.numberworkers=ะัะปัะบัััั ัะพะฑะพัะธั
ะฟะพัะพะบัะฒ
-monitor.queue.maxnumberworkers=ะะฐะบัะธะผะฐะปัะฝะฐ ะบัะปัะบัััั ัะพะฑะพัะธั
ะฟะพัะพะบัะฒ
+monitor.queue.numberworkers=ะัะปัะบัััั ะพะฑัะพะฑะฝะธะบัะฒ
+monitor.queue.maxnumberworkers=ะะฐะบัะธะผะฐะปัะฝะฐ ะบัะปัะบัััั ะพะฑัะพะฑะฝะธะบัะฒ
monitor.queue.settings.title=ะะฐะปะฐัััะฒะฐะฝะฝั ะฟัะปั
monitor.queue.settings.maxnumberworkers=ะะฐะบัะธะผะฐะปัะฝะฐ ะบัะปัะบัััั ัะพะฑะพัะธั
ะฟะพัะพะบัะฒ
monitor.queue.settings.maxnumberworkers.placeholder=ะะพัะพัะฝะธะน %[1]d
@@ -2614,7 +3227,7 @@ notices.select_all=ะะธะฑัะฐัะธ ะฒัะต
notices.deselect_all=ะกะบะฐััะฒะฐัะธ ะฒะธะดัะปะตะฝะฝั
notices.inverse_selection=ะะฝะฒะตัััะฒะฐัะธ ะฒะธะดัะปะตะฝะต
notices.delete_selected=ะะธะดะฐะปะธัะธ ะพะฑัะฐะฝะต
-notices.delete_all=ะะธะดะฐะปะธัะธ ััั cะฟะพะฒััะตะฝะฝั
+notices.delete_all=ะะธะดะฐะปะธัะธ ะฒัั cะฟะพะฒััะตะฝะฝั
notices.type=ะขะธะฟ
notices.type_1=ะ ะตะฟะพะทะธัะพััะน
notices.type_2=ะะฐะฒะดะฐะฝะฝั
@@ -2627,11 +3240,67 @@ packages.total_size = ะะฐะณะฐะปัะฝะธะน ัะพะทะผัั: %s
packages.unreferenced_size = ะ ะพะทะผัั ะฑะตะท ะฟะพัะธะปะฐะฝั: %s
packages.creator = ะขะฒะพัะตัั
packages.version = ะะตัััั
-packages.package_manage_panel = ะะตะฝะตะดะถะผะตะฝั ะะฐะบัะฝะบัะฒ
+packages.package_manage_panel = ะะตััะฒะฐะฝะฝั ะฟะฐะบัะฝะบะฐะผะธ
packages.published = ะะฟัะฑะปัะบะพะฒะฐะฝะพ
notices.operations = ะัั
+packages.cleanup = ะัะธััะธัะธ ะฝะตะดัะนัะฝั ะดะฐะฝั
+packages.cleanup.success = ะฃัะฟััะฝะพ ะพัะธัะตะฝะพ ะฝะตะดัะนัะฝั ะดะฐะฝั
+users.still_own_packages = ะฆะตะน ะบะพัะธัััะฒะฐั ะดะพัั ะฒะพะปะพะดัั ะพะดะฝะธะผ ัะธ ะฑัะปััะต ะฟะฐะบัะฝะบะฐะผะธ, ัะฟะพัะฐัะบั ะฒะธะดะฐะปััั ัั ะฟะฐะบัะฝะบะธ.
+users.purge_help = ะัะธะผััะพะฒะพ ะฒะธะดะฐะปะธัะธ ะบะพัะธัััะฒะฐัะฐ ั ะฑัะดั-ัะบั ัะตะฟะพะทะธัะพััั, ะพัะณะฐะฝัะทะฐััั ัะฐ ะฟะฐะบัะฝะบะธ, ัะบะธะผะธ ะฒัะฝ ะฒะพะปะพะดัั. ะัั ะบะพะผะตะฝัะฐัั ัะฐ ะทะฐะดะฐัั, ััะฒะพัะตะฝั ัะธะผ ะบะพัะธัััะฒะฐัะตะผ, ัะฐะบะพะถ ะฑัะดััั ะฒะธะดะฐะปะตะฝั.
+dashboard.cleanup_packages = ะัะธััะธัะธ ะฝะตะฟัะธะดะฐัะฝั ะฟะฐะบัะฝะบะธ
+monitor.last_execution_result = ะ ะตะทัะปััะฐั
+repos.lfs_size = ะ ะพะทะผัั LFS
+config.allow_dots_in_usernames = ะะพะทะฒะพะปะธัะธ ะฒะธะบะพัะธััะฐะฝะฝั ะบัะฐะฟะบะธ ะฒ ัะผะตะฝะฐั
ะบะพัะธัััะฒะฐััะฒ. ะะต ะฒะฟะปะธะฒะฐั ะฝะฐ ััะฝัััั ะพะฑะปัะบะพะฒั ะทะฐะฟะธัะธ.
+config.mailer_enable_helo = ะฃะฒัะผะบะฝััะธ HELO
+users.organization_creation.description = ะะพะทะฒะพะปะธัะธ ััะฒะพัะตะฝะฝั ะฝะพะฒะธั
ะพัะณะฐะฝัะทะฐััะน.
+users.cannot_delete_self = ะะธ ะฝะต ะผะพะถะตัะต ะฒะธะดะฐะปะธัะธ ัะตะฑะต
+monitor.processes_count = %d ะฟัะพัะตััะฒ
+monitor.stacktrace = ะขัะฐัะฐ ััะตะบะฐ
+config.send_test_mail_submit = ะะฐะดััะปะฐัะธ
+users.bot = ะะพั
+monitor.stats = ะกัะฐัะธััะธะบะฐ
+users.new_success = ะะฑะปัะบะพะฒะธะน ะทะฐะฟะธั ยซ%sยป ััะฒะพัะตะฝะพ.
+config_settings = ะะฐะปะฐัััะฒะฐะฝะฝั
+self_check.no_problem_found = ะัะพะฑะปะตะผ ะฟะพะบะธ ัะพ ะฝะต ะฒะธัะฒะปะตะฝะพ.
+config_summary = ะัะดััะผะพะบ
+monitor.queue.review_add = ะะตัะตะณะปัะฝััะธ / ะดะพะดะฐัะธ ะพะฑัะพะฑะฝะธะบะธ
+monitor.queue.activeworkers = ะะบัะธะฒะฝั ะพะฑัะพะฑะฝะธะบะธ
+monitor.queue.numberinqueue = ะะพะผะตั ั ัะตัะทั
+monitor.queue.settings.desc = ะัะปะธ ะดะธะฝะฐะผััะฝะพ ะทัะพััะฐััั ั ะฒัะดะฟะพะฒัะดั ะฝะฐ ะฑะปะพะบัะฒะฐะฝะฝั ัั
ะฝัั
ัะตัะณ ะพะฑัะพะฑะฝะธะบัะฒ.
+monitor.queue.settings.remove_all_items_done = ะฃัั ะตะปะตะผะตะฝัะธ ะฒ ัะตัะทั ะฒะธะดะฐะปะตะฝะพ.
+monitor.queue.settings.remove_all_items = ะะธะดะฐะปะธัะธ ะฒัั
+config.app_slogan = ะะฐัะปะพ ะตะบะทะตะผะฟะปััะฐ
+auths.tip.gitea = ะะฐัะตัััััะนัะต ะฝะพะฒะธะน ะดะพะดะฐัะพะบ OAuth. ะะฝััััะบััั ะผะพะถะฝะฐ ะทะฝะฐะนัะธ ะฝะฐ %s
+auths.tip.gitlab_new = ะะฐัะตัััััะนัะต ะฝะพะฒะธะน ะดะพะดะฐัะพะบ ะฝะฐ %s
+monitor.duration = ะขัะธะฒะฐะปัััั (ั)
+users.reserved = ะะฐัะตะทะตัะฒะพะฒะฐะฝะพ
+systemhooks.desc = ะะตะฑั
ัะบะธ ะฐะฒัะพะผะฐัะธัะฝะพ ัะฟะพะฒััะฐััั HTTP-ัะตัะฒะตั POST-ะทะฐะฟะธัะฐะผะธ, ะบะพะปะธ ะฒ Forgejo ะฒัะดะฑัะฒะฐััััั ะฟะตะฒะฝั ะฟะพะดัั. ะะบะฐะทะฐะฝั ััั ะฒะตะฑั
ัะบะธ ัะฟัะฐััะพะฒัะฒะฐัะธะผััั ะดะปั ะฒััั
ัะตะฟะพะทะธัะพัััะฒ ัะธััะตะผะธ, ัะพะถ ะฒัะฐั
ัะนัะต ะฒัั ะนะผะพะฒััะฝั ะฝะฐัะปัะดะบะธ ะดะปั ัะฒะธะดะบะพะดัั. ะะพะบะปะฐะดะฝััะต โ ะฒ ะฟะพััะฑะฝะธะบั ะท ะฒะตะฑั
ัะบัะฒ .
+dashboard.cleanup_actions = ะัะธััะธัะธ ะฟัะพัััะพัะตะฝั ะถััะฝะฐะปะธ ะน ะฐััะตัะฐะบัะธ ะฒัะด ะดัะน
+dashboard.gc_lfs = ะะธะบะพะฝะฐัะธ ะพัะธััะบั ัะผัััั ะผะตัะฐะพะฑ'ัะบััะฒ LFS
+dashboard.new_version_hint = ะะธะนัะปะฐ %s ะฒะตัััั Forgejo, ะฒะธ ะฒะธะบะพัะธััะพะฒัััะต %s. ะะพะบะปะฐะดะฝััะต ัะธัะฐะนัะต ั ะฑะปะพะทั .
+self_check.database_collation_case_insensitive = ะะฐะทะฐ ะดะฐะฝะธั
ะฒะธะบะพัะธััะพะฒัั ะทัััะฐะฒะปะตะฝะฝั %s, ัะบะต ั ะฝะตัััะปะธะฒะธะผ ะดะพ ัะตะณััััั. Forgejo ะผะพะถะต ะฟัะฐััะฒะฐัะธ ะท ะฝะธะผ, ะพะดะฝะฐะบ ะผะพะถะปะธะฒั ััะดะบััะฝั ะฒะธะฟะฐะดะบะธ, ะบะพะปะธ ัะพัั ะฟัะฐััะฒะฐัะธะผะต ะฝะต ัะฐะบ, ัะบ ะพััะบัะฒะฐะปะพัั.
+self_check.database_inconsistent_collation_columns = ะะฐะทะฐ ะดะฐะฝะธั
ะฒะธะบะพัะธััะพะฒัั ะทัััะฐะฒะปะตะฝะฝั %s, ะฐะปะต ัั ััะพะฒะฟัะธะบะธ ะฒะธะบะพัะธััะพะฒัััั ะฝะตะฒัะดะฟะพะฒัะดะฝั ะทัััะฐะฒะปะตะฝะฝั. ะฆะต ะผะพะถะต ัะฟัะธัะธะฝะธัะธ ะดะตัะบั ะฝะตัะฟะพะดัะฒะฐะฝั ะฟัะพะฑะปะตะผะธ.
+self_check.database_fix_mysql = ะะพัะธัััะฒะฐัั MySQL ัะฐ MariaDB ะผะพะถััั ัะบะพัะธััะฐัะธัั ะบะพะผะฐะฝะดะพั ยซforgejo doctor convertยป, ัะพะฑ ะฒะธะฟัะฐะฒะธัะธ ะฟัะพะฑะปะตะผะธ ะทัััะฐะฒะปะตะฝะฝั, ะฐะฑะพ ะฒะธะฟัะฐะฒะธัะธ ะฟัะพะฑะปะตะผั ะฒัััะฝั ะทะฐ ะดะพะฟะพะผะพะณะพั ยซALTER ... COLLATE ...ยป SQL.
+self_check.database_collation_mismatch = ะััะบัััััั, ัะพ ะฑะฐะทะฐ ะดะฐะฝะธั
ะฒะธะบะพัะธััะพะฒัั ะทัััะฐะฒะปะตะฝะฝั: %s
+config.test_mail_failed = ะะต ะฒะดะฐะปะพัั ะฝะฐะดััะปะฐัะธ ัะตััะพะฒะพะณะพ ะปะธััะฐ ยซ%sยป: %v
+emails.delete = ะะธะดะฐะปะธัะธ ะตะปะตะบััะพะฝะฝั ะฐะดัะตัั
+emails.delete_desc = ะะธ ะฒะฟะตะฒะฝะตะฝั, ัะพ ั
ะพัะตัะต ะฒะธะดะฐะปะธัะธ ัั ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ?
+auths.default_domain_name = ะะพะผะตะฝ ะทะฐ ะทะฐะผะพะฒััะฒะฐะฝะฝัะผ ะดะปั ะฐะดัะตั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ
+config.test_mail_sent = ะขะตััะพะฒะพะณะพ ะปะธััะฐ ะฝะฐะดััะปะฐะฝะพ ยซ%sยป.
+emails.deletion_success = ะะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ ะฒะธะดะฐะปะตะฝะพ.
+emails.delete_primary_email_error = ะะธ ะฝะต ะผะพะถะตัะต ะฒะธะดะฐะปะธัะธ ะพัะฝะพะฒะฝั ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ.
+emails.change_email_text = ะะธ ะฒะฟะตะฒะฝะตะฝั, ัะพ ั
ะพัะตัะต ะพะฝะพะฒะธัะธ ัั ะฐะดัะตัั ะตะปะตะบััะพะฝะฝะพั ะฟะพััะธ?
+dashboard.sync_branch.started = ะ ะพะทะฟะพัะฐัะพ ัะธะฝั
ัะพะฝัะทะฐััั ะณัะปะพะบ
+dashboard.sync_tag.started = ะ ะพะทะฟะพัะฐัะพ ัะธะฝั
ัะพะฝัะทะฐััั ัะตะณัะฒ
+auths.tips.gmail_settings = ะะฐะปะฐัััะฒะฐะฝะฝั Gmail:
+dashboard.task.cancelled = ะะฐะฒะดะฐะฝะฝั: %[1]s ัะบะฐัะพะฒะฐะฝะพ: %[3]s
+config.mailer_protocol = ะัะพัะพะบะพะป
+dashboard.cron.cancelled = Cron: %[1]s ัะบะฐัะพะฒะฐะฝะพ: %[3]s
+defaulthooks.desc = ะะตะฑั
ัะบะธ ะฐะฒัะพะผะฐัะธัะฝะพ ัะฟะพะฒััะฐััั HTTP-ัะตัะฒะตั POST-ะทะฐะฟะธัะฐะผะธ, ะบะพะปะธ ะฒ Forgejo ะฒัะดะฑัะฒะฐััััั ะฟะตะฒะฝั ะฟะพะดัั. ะะบะฐะทะฐะฝั ััั ะฒะตะฑั
ัะบะธ ั ัะธะฟะพะฒะธะผะธ ั ะฑัะดััั ัะบะพะฟัะนะพะฒะฐะฝั ะดะพ ะฒััั
ะฝะพะฒะธั
ัะตะฟะพะทะธัะพัััะฒ. ะะพะบะปะฐะดะฝััะต โ ะฒ ะฟะพััะฑะฝะธะบั ะท ะฒะตะฑั
ัะบัะฒ .
+assets = ะ ะตััััะธ ะบะพะดั
+
[action]
create_repo=ััะฒะพัะธะฒ(ะปะฐ) ัะตะฟะพะทะธัะพััะน %s
rename_repo=ัะตะฟะพะทะธัะพััะน ะฟะตัะตะนะผะตะฝะพะฒะฐะฝะพ ะท %[1]s
ะฝะฐ %[3]s
@@ -2646,8 +3315,8 @@ comment_issue=`ะฟัะพะบะพะผะตะฝััะฒะฐะฒ ะทะฐะดะฐัั %[3]s#%[2
comment_pull=`ะฟัะพะบะพะผะตะฝััะฒะฐะฒ ะทะฐะฟะธั ะทะปะธััั %[3]s#%[2]s `
merge_pull_request=`ะฟัะธะนะฝัะฒ ะทะฐะฟะธั ะทะปะธััั %[3]s#%[2]s `
transfer_repo=ะฟะตัะตะฝะตัะตะฝะพ ัะตะฟะพะทะธัะพััะน %s
ั %s
-push_tag=ััะฒะพัะธะฒ ะผััะบั %[3]s ะฒ %[4]s
-delete_tag=ะฒะธะดะฐะปะตะฝะพ ะผััะบั %[2]s ะท %[3]s
+push_tag=ะฝะฐะดัะธะปะฐั ัะตะณ %[3]s ะฒ %[4]s
+delete_tag=ะฒะธะดะฐะปัั ัะตะณ %[2]s ัะท %[3]s
delete_branch=ะฒะธะดะฐะปะตะฝะพ ะณัะปะบั %[2]s ะท %[3]s
compare_branch=ะะพััะฒะฝััะธ
compare_commits=ะะพััะฒะฝััะธ %d ะบะพะผัััะฒ
@@ -2657,12 +3326,13 @@ mirror_sync_create=ัะธะฝั
ัะพะฝัะทัะฒะฐะฒ ะฝะพะฒะต ะฟะพัะธะปะฐะฝะฝั %[2]s
ะฝะฐ %[3]s ัะท ะดะทะตัะบะฐะปะฐ
approve_pull_request=`ัั
ะฒะฐะปะธะฒ %[3]s#%[2]s `
reject_pull_request=`ะทะฐะฟัะพะฟะพะฝัะฒะฐะฒ ะทะผัะฝะธ ะดะพ %[3]s#%[2]s `
-publish_release=`ะพะฟัะฑะปัะบัะฒะฐะฒ ะฒะธะฟััะบ "%[4]s" ะท %[3]s `
+publish_release=`ะฟัะฑะปัะบัั ะฒะธะฟััะบ %[4]s ะท %[3]s `
review_dismissed=`ะฒัะดั
ะธะปะธะฒ ะฒัะดะณัะบ ะฒัะด %[4]s ะดะปั %[3]s#%[2]s `
review_dismissed_reason=ะัะธัะธะฝะฐ:
create_branch=ััะฒะพัะธะฒ ะณัะปะบั %[3]s ะฒ %[4]s
starred_repo=ะดะพะดะฐะฒ %[2]s ั ะพะฑัะฐะฝะต
watched_repo=ะฟะพัะฐะฒ ัะปัะดะบัะฒะฐัะธ ะทะฐ %[2]s
+auto_merge_pull_request = `ะฐะฒัะพะผะฐัะธัะฝะพ ะพะฑ'ัะดะฝะฐะฒ ะทะฐะฟะธั ะฝะฐ ะทะปะธััั %[3]s#%[2]s `
[tool]
now=ะทะฐัะฐะท
@@ -2709,11 +3379,11 @@ default_key=ะัะดะฟะธัะฐะฝะพ ัะธะฟะพะฒะธะผ ะบะปััะตะผ
error.extract_sign=ะะต ะฒะดะฐะปะพัั ะฒะธััะณัะธ ะฟัะดะฟะธั
error.generate_hash=ะะต ะฒะดะฐะปะพัั ะทะณะตะฝะตััะฒะฐัะธ ั
ะตั ะบะพะผััั
error.no_committer_account=ะะบะบะฐัะฝั ะบะพัะธัััะฒะฐัะฐ ะท ัะฐะบะธะผ Email ะฝะต ะทะฝะฐะนะดะตะฝะพ
-error.no_gpg_keys_found=ะะต ะฒะดะฐะปะพัั ะทะฝะฐะนัะธ GPG ะบะปัั ัะพ ะฒัะดะฟะพะฒัะดะฐั ะดะฐะฝะพะผั ะฟัะดะฟะธัั
+error.no_gpg_keys_found=ะะต ะฒะดะฐะปะพัั ะทะฝะฐะนัะธ GPG-ะบะปัั, ัะพ ะฒัะดะฟะพะฒัะดะฐั ะดะฐะฝะพะผั ะฟัะดะฟะธัั
error.not_signed_commit=ะะตะฟัะดะฟะธัะฐะฝะธะน ะบะพะผัั
-error.failed_retrieval_gpg_keys=ะะต ะฒะดะฐะปะพัั ะพััะธะผะฐัะธ ะฒัะดะฟะพะฒัะดะฝะธะน GPG ะบะปัั ะบะพัะธัััะฒะฐัะฐ
-error.probable_bad_signature=ะฃะะะะ! ะฅะพัะฐ ะบะปัั ะท ัะฐะบะธะผ ID ั ั ะฒ ะฑะฐะทั, ะบะพะผัั ะฝะต ะผะพะถะต ะฑััะธ ะฝะธะผ ะฟะตัะตะฒััะตะฝะพ! ะฆะตะน ะบะพะผัั ะะะะะะ ะะะะ.
-error.probable_bad_default_signature=ะฃะะะะ! ะฅะพัะฐ ัะธะฟะพะฒะธะน ะบะปัั ะผะฐั ัะตะน ID, ะบะพะผัั ะฝะต ะผะพะถะต ะฑััะธ ะฝะธะผ ะฟะตัะตะฒััะตะฝะพ! ะฆะตะน ะบะพะผัั ะะะะะะ ะะะะ.
+error.failed_retrieval_gpg_keys=ะะต ะฒะดะฐะปะพัั ะพััะธะผะฐัะธ ะบะปัั, ะฟะพะฒ'ัะทะฐะฝะธะน ะท ะพะฑะปัะบะพะฒะธะผ ะทะฐะฟะธัะพะผ ะบะพะผััะตัะฐ
+error.probable_bad_signature=ะฃะะะะ! ะฅะพัะฐ ะบะปัั ัะท ัะฐะบะธะผ ID ั ั ะฒ ะฑะฐะทั, ะบะพะผัั ะฝะตะผะพะถะปะธะฒะพ ะฝะธะผ ะฟะตัะตะฒััะธัะธ! ะฆะตะน ะบะพะผัั ะะะะะะ ะะะะ.
+error.probable_bad_default_signature=ะฃะะะะ! ะฅะพัะฐ ัะธะฟะพะฒะธะน ะบะปัั ะผะฐั ัะตะน ID, ะบะพะผัั ะฝะตะผะพะถะปะธะฒะพ ะฝะธะผ ะฟะตัะตะฒััะธัะธ! ะฆะตะน ะบะพะผัั ะะะะะะ ะะะะ.
[units]
error.no_unit_allowed_repo=ะฃ ะฒะฐั ะฝะตะผะฐั ะดะพัััะฟั ะดะพ ะถะพะดะฝะพะณะพ ัะพะทะดัะปั ััะพะณะพ ัะตะฟะพะทะธัะพัะธั.
@@ -2725,19 +3395,148 @@ alpine.repository.branches=ะัะปะบะธ
alpine.repository.repositories=ะ ะตะฟะพะทะธัะพััั
conan.details.repository=ะ ะตะฟะพะทะธัะพััะน
owner.settings.cleanuprules.enabled=ะฃะฒัะผะบะฝะตะฝะพ
-about = ะัะพ ัะตะน ะฟะฐะบะตั
+about = ะัะพ ัะตะน ะฟะฐะบัะฝะพะบ
empty = ะะพะบะธ ัะพ ััั ะฝะตะผะฐั ะฟะฐะบัะฝะบัะฒ.
-empty.documentation = ะะปั ะพััะธะผะฐะฝะฝั ะดะพะดะฐัะบะพะฒะพั ัะฝัะพัะผะฐััั ัะพะดะพ ัะตััััั ะฟะฐะบัะฝะบัะฒ, ะฟะตัะตะณะปัะฝััะต ะดะพะบัะผะตะฝัะฐััั .
-registry.documentation = ะะปั ะพััะธะผะฐะฝะฝั ะดะพะดะฐัะบะพะฒะพั ัะฝัะพัะผะฐััั ัะพะดะพ ัะตััััั %s, ะฟะตัะตะณะปัะฝััะต ะดะพะบัะผะตะฝัะฐััั .
-settings.delete.notice = ะะธ ะทะฑะธัะฐััะตัั ะฒะธะดะฐะปะธัะธ %s (%s). ะฆั ะพะฟะตัะฐััั ะฝะต ะผะพะถะฝะฐ ะฒัะดะผัะฝะธัะธ, ะฒะธ ะฒะฟะตะฒะฝะตะฝั?
+empty.documentation = ะะพะบะปะฐะดะฝััะต ะฟัะพ ัะตัััั ะฟะฐะบัะฝะบัะฒ ัะธัะฐะนัะต ะฒ ะดะพะบัะผะตะฝัะฐััั .
+registry.documentation = ะะพะบะปะฐะดะฝััะต ะฟัะพ ัะตัััั %s ัะธัะฐะนัะต ะฒ ะดะพะบัะผะตะฝัะฐััั .
+settings.delete.notice = ะะธ ะทะฑะธัะฐััะตัั ะฒะธะดะฐะปะธัะธ %s (%s). ะฆั ะพะฟะตัะฐััั ะฝะต ะผะพะถะฝะฐ ัะบะฐััะฒะฐัะธ, ะฒะธ ะฒะฟะตะฒะฝะตะฝั?
details.author = ะะฒัะพั
+title = ะะฐะบัะฝะบะธ
+arch.version.backup = ะ ะตะทะตัะฒะฝะต ะบะพะฟััะฒะฐะฝะฝั
+arch.version.conflicts = ะกัะฟะตัะตัะบะธ
+arch.version.replaces = ะะฐะผัะฝะธ
+arch.version.provides = ะะฐะดะฐั
+arch.version.groups = ะััะฟะฐ
+conda.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพัะธััะพะฒัััะธ Conda, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+cargo.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพัะธััะพะฒัััะธ Cargo, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+versions.view_all = ะะตัะตะณะปัะฝััะธ ะฒัั
+generic.download = ะะฐะฒะฐะฝัะฐะถัะต ะฟะฐะบัะฝะพะบ ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+details = ะะพะดัะพะฑะธัั
+arch.version.optdepends = ะะตะพะฑะพะฒสผัะทะบะพะฒะพ ะทะฐะปะตะถะธัั
+installation = ะฃััะฐะฝะพะฒะปะตะฝะฝั
+details.license = ะััะตะฝะทัั
+filter.type.all = ะฃัั
+conan.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพัะธััะพะฒัััะธ Conan, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+container.layers = ะจะฐัะธ ะพะฑัะฐะทั
+details.project_site = ะะตะฑััะพััะฝะบะฐ ะฟัะพัะบัั
+details.documentation_site = ะะตะฑััะพััะฝะบะฐ ะดะพะบัะผะตะฝัะฐััั
+desc = ะะตััะฒะฐะฝะฝั ะฟะฐะบัะฝะบะฐะผะธ ัะตะฟะพะทะธัะพััั.
+requirements = ะะธะผะพะณะธ
+dependencies = ะะฐะปะตะถะฝะพััั
+empty.repo = ะะธ ะพะฟัะฑะปัะบัะฒะฐะปะธ ะฟะฐะบัะฝะพะบ, ะฐะปะต ะฒัะฝ ะฝะต ะฟะพะบะฐะทะฐะฝะธะน ััั? ะะตัะตะนะดััั ะดะพ ะฝะฐะปะฐัััะฒะฐะฝั ะฟะฐะบัะฝะบัะฒ ัะฐ ะฟัะธะฒสผัะถััั ะนะพะณะพ ะดะพ ััะพะณะพ ัะตะฟะพะทะธัะพััั.
+alpine.repository = ะัะพ ัะตะฟะพะทะธัะพััะน
+alpine.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ัะตะน ะฟะฐะบัะฝะพะบ, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+cran.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+composer.dependencies.development = ะะฐะปะตะถะฝะพััั ัะพะทัะพะฑะบะธ
+container.labels.key = ะะปัั
+container.labels.value = ะะฝะฐัะตะฝะฝั
+composer.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพัะธััะพะฒัััะธ Composer, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+debian.repository.components = ะกะบะปะฐะดะพะฒั
+filter.container.tagged = ะัะดะผััะตะฝะธะน
+filter.container.untagged = ะะตะฒัะดะผััะตะฝะธะน
+container.multi_arch = ะะก / ะัั
ััะตะบัััะฐ
+arch.pacman.helper.gpg = ะะพะดะฐะนัะต ัะตััะธััะบะฐั ะดะพะฒััะตะฝะพััั ะดะพ pacman:
+arch.pacman.sync = ะกะธะฝั
ัะพะฝัะทัะนัะต ะฟะฐะบัะฝะพะบ ะท pacman:
+arch.pacman.conf = ะะพะดะฐะนัะต ัะตัะฒะตั ะท ะฟะพะฒสผัะทะฐะฝะธะผ ะดะพัััะธะฑััะธะฒะพะผ ัะฐ ะฐัั
ััะตะบัััะพั ะดะพ /etc/pacman.conf
:
+arch.version.properties = ะะปะฐััะธะฒะพััั ะฒะตัััั
+arch.version.description = ะะฟะธั
+chef.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+container.details.platform = ะะปะฐััะพัะผะฐ
+container.details.type = ะขะธะฟ ะพะฑัะฐะทั
+container.pull = ะะฐะฒะฐะฝัะฐะถะธัะธ ะพะฑัะฐะท ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+details.repository_site = ะะตะฑััะพััะฝะบะฐ ัะตะฟะพะทะธัะพััั
+composer.dependencies = ะะฐะปะตะถะฝะพััั
+debian.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+debian.repository = ะัะพ ัะตะฟะพะทะธัะพััะน
+debian.repository.distributions = ะะธัััะธะฑััะธะฒะธ
+alpine.repository.architectures = ะัั
ััะตะบัััะธ
+arch.version.depends = ะะฐะปะตะถะธัั
+go.install = ะััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+debian.repository.architectures = ะัั
ััะตะบัััะธ
+helm.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+keywords = ะะปััะพะฒั ัะปะพะฒะฐ
+assets = ะ ะตััััะธ
+versions = ะะตัััั
+dependency.version = ะะตัััั
+container.labels = ะััะบะธ
+filter.no_result = ะะฐั ััะปััั ะฝะต ะฒะธะดะฐะฒ ะถะพะดะฝะธั
ัะตะทัะปััะฐััะฒ.
+dependency.id = ID
+rpm.repository = ะัะพ ัะตะฟะพะทะธัะพััะน
+rpm.repository.architectures = ะัั
ััะตะบัััะธ
+settings.delete.error = ะะต ะฒะดะฐะปะพัั ะฒะธะดะฐะปะธัะธ ะฟะฐะบัะฝะพะบ.
+settings.delete.success = ะะฐะบัะฝะพะบ ะฒะธะดะฐะปะตะฝะพ.
+npm.dependencies = ะะฐะปะตะถะฝะพััั
+settings.delete = ะะธะดะฐะปะธัะธ ะฟะฐะบัะฝะพะบ
+npm.dependencies.development = ะะฐะปะตะถะฝะพััั ัะพะทัะพะฑะบะธ
+rubygems.dependencies.development = ะะฐะปะตะถะฝะพััั ัะพะทัะพะฑะบะธ
+npm.dependencies.optional = ะะตะพะฑะพะฒ'ัะทะบะพะฒั ะทะฐะปะตะถะฝะพััั
+container.images.title = ะะฑัะฐะทะธ
+search_in_external_registry = ะจัะบะฐัะธ ะฒ %s
+owner.settings.cleanuprules.keep.count.n = %d ะฒะตัััะน ะฝะฐ ะฟะฐะบัะฝะพะบ
+settings.delete.description = ะะธะดะฐะปะตะฝะฝั ะฟะฐะบัะฝะบะฐ ั ะพััะฐัะพัะฝะธะผ ั ะนะพะณะพ ะฝะตะผะพะถะปะธะฒะพ ัะบะฐััะฒะฐัะธ.
+owner.settings.cleanuprules.keep.count.1 = 1 ะฒะตัััั ะฝะฐ ะฟะฐะบัะฝะพะบ
+rpm.repository.multiple_groups = ะฆะตะน ะฟะฐะบัะฝะพะบ ะดะพัััะฟะฝะธะน ั ะบัะปัะบะพั
ะณััะฟะฐั
.
+helm.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+rpm.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+conan.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+nuget.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+swift.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+alt.repository.architectures = ะัั
ััะตะบัััะธ
+alt.repository = ะัะพ ัะตะฟะพะทะธัะพััะน
+alt.repository.multiple_groups = ะฆะตะน ะฟะฐะบัะฝะพะบ ะดะพัััะฟะฝะธะน ั ะบัะปัะบะพั
ะณััะฟะฐั
.
+alt.install = ะััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ
+alt.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+debian.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ัะท ะบะพะผะฐะฝะดะฝะพะณะพ ััะดะบะฐ:
+debian.registry.info = ะะธะฑะตัััั $distribution ั $component ะทั ัะฟะธัะบั ะฝะธะถัะต.
+npm.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพัะธััะพะฒัััะธ npm, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+alt.registry.install = ะฉะพะฑ ัััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+swift.install2 = ั ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+rubygems.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพัะธััะพะฒัััะธ gem, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+alt.setup = ะะพะดะฐะนัะต ัะตะฟะพะทะธัะพััะน ะดะพ ัะฟะธัะบั ะฟัะดะบะปััะตะฝะธั
ัะตะฟะพะทะธัะพัััะฒ (ะฒะธะฑะตัััั ะฟะพัััะฑะฝั ะฐัั
ััะตะบัััั ะทะฐะผัััั ยซ_arch_ยป):
+pypi.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพัะธััะพะฒัััะธ pip, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+nuget.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพัะธััะพะฒัััะธ NuGet, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+pub.install = ะะฑะธ ะฒััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพัะธััะพะฒัััะธ Dart, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+rpm.install = ะฉะพะฑ ัััะฐะฝะพะฒะธัะธ ะฟะฐะบัะฝะพะบ, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+maven.install = ะะปั ะฒะธะบะพัะธััะฐะฝะฝั ะฟะฐะบัะฝะบะฐ ะฒะบะปััััั ั ะฑะปะพะบ dependencies
ั ัะฐะนะปั pom.xml
ัะฐะบะต:
+vagrant.install = ะฉะพะฑ ะดะพะดะฐัะธ ัะบัะธะฝัะบั Vagrant, ะฒะธะบะพะฝะฐะนัะต ะบะพะผะฐะฝะดั:
+owner.settings.chef.keypair = ะะณะตะฝะตััะฒะฐัะธ ะฟะฐัั ะบะปัััะฒ
+published_by_in = %[1]s ะพะฟัะฑะปัะบะพะฒะฐะฝะพ %[3]s ะฒ %[5]s
+npm.install2 = ะฐะฑะพ ะดะพะดะฐะนัะต ะนะพะณะพ ั ัะฐะนะป package.json:
+npm.details.tag = ะขะตะณ
+rubygems.install2 = ะฐะฑะพ ะดะพะดะฐะนัะต ะนะพะณะพ ั Gemfile:
+published_by = %[1]s ะพะฟัะฑะปัะบะพะฒะฐะฝะพ %[3]s
+swift.install = ะะพะดะฐะนัะต ะฟะฐะบัะฝะพะบ ั ัะฒัะน ัะฐะนะป Package.swift
:
+settings.link.select = ะะธะฑะตัััั ัะตะฟะพะทะธัะพััะน
+alpine.registry.info = ะะธะฑะตัััั $branch ั $repository ะทั ัะฟะธัะบั ะฝะธะถัะต.
+
+alpine.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั, ะดะพะดะฐะฒัะธ URL ั ัะฐะนะป /etc/apk/repositories
:
+arch.pacman.repo.multi.item = ะะพะฝััะณััะฐััั %s
+cargo.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ั ัะฐะนะปั ะบะพะฝััะณััะฐััั Cargo (ะฝะฐะฟัะธะบะปะฐะด, ~/.cargo/config.toml
):
+chef.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ั ัะฐะนะปั ~/.chef/config.rb
:
+composer.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ั ัะฐะนะปั ~/.composer/config.json
:
+conda.registry = ะััะฐะฝะพะฒััั ัะตะน ัะตัััั ัะบ ัะตะฟะพะทะธัะพััะน Conda ั ัะฒะพัะผั ัะฐะนะปั .condarc
:
+cran.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ั ัะฐะนะปั Rprofile.site
:
+maven.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ั ัะฐะนะปั pom.xml
ัะฒะพะณะพ ะฟัะพัะบัั:
+npm.registry = ะะฐะปะฐัััะนัะต ัะตะน ัะตัััั ั ัะฐะนะปั .npmrc
ัะฒะพะณะพ ะฟัะพัะบัั:
+owner.settings.chef.title = ะ ะตัััั Chef
[secrets]
+deletion = ะะธะดะฐะปะธัะธ ัะตะบัะตั
+creation.success = ะกะตะบัะตั ยซ%sยป ะดะพะดะฐะฝะพ.
+creation.failed = ะะต ะฒะดะฐะปะพัั ะดะพะดะฐัะธ ัะตะบัะตั.
+management = ะะตััะฒะฐะฝะฝั ัะตะบัะตัะฐะผะธ
+deletion.success = ะกะตะบัะตั ะฒะธะดะฐะปะตะฝะพ.
+deletion.failed = ะะต ะฒะดะฐะปะพัั ะฒะธะดะฐะปะธัะธ ัะตะบัะตั.
+deletion.description = ะะธะดะฐะปะตะฝะฝั ัะตะบัะตัั ั ะพััะฐัะพัะฝะธะผ ั ะนะพะณะพ ะฝะตะผะพะถะปะธะฒะพ ัะบะฐััะฒะฐัะธ. ะัะพะดะพะฒะถะธัะธ?
+creation = ะะพะดะฐัะธ ัะตะบัะตั
+none = ะกะตะบัะตััะฒ ัะต ะฝะตะผะฐั.
+creation.name_placeholder = ะฑะตะท ััะฐั
ัะฒะฐะฝะฝั ัะตะณััััั, ััะปัะบะธ ะปััะตัะฝะพ-ัะธััะพะฒั ัะธะผะฒะพะปะธ ะฐะฑะพ ะฟัะดะบัะตัะปะตะฝะฝั, ะฝะต ะผะพะถะต ะฟะพัะธะฝะฐัะธัั ะท GITEA_ ะฐะฑะพ GITHUB_
+secrets = ะกะตะบัะตัะธ
+creation.value_placeholder = ะฃะฒะตะดััั ะดะพะฒัะปัะฝะธะน ะฒะผััั. ะัะพะฑัะปะธ ะฝะฐ ะฟะพัะฐัะบั ัะฐ ะฒ ะบัะฝัั ะฑัะดััั ะฟัะพะฟััะตะฝั.
+
+description = ะกะตะบัะตัะธ ะฟะตัะตะดะฐััััั ะฟะตะฒะฝะธะผ ะดััะผ ั ะฝะต ะผะพะถััั ะฑััะธ ะฟัะพัะธัะฐะฝั ัะฝะฐะบัะต.
[actions]
-
-
-
runners.name=ะะฐะทะฒะฐ
runners.owner_type=ะขะธะฟ
runners.description=ะะฟะธั
@@ -2747,13 +3546,156 @@ runners.task_list.commit=ะะพะผัั
runners.status.active=ะะบัะธะฒะฝะธะน
runs.commit=ะะพะผัั
+variables.update.failed = ะะต ะฒะดะฐะปะพัั ะทะผัะฝะธัะธ ะทะผัะฝะฝั.
+variables.update.success = ะะผัะฝะฝั ะทะผัะฝะตะฝะพ.
+variables.creation = ะะพะดะฐัะธ ะทะผัะฝะฝั
+variables.none = ะะผัะฝะฝะธั
ัะต ะฝะตะผะฐั.
+variables.deletion = ะะธะดะฐะปะธัะธ ะทะผัะฝะฝั
+variables = ะะผัะฝะฝั
+runs.scheduled = ะะฐะฟะปะฐะฝะพะฒะฐะฝะพ
+actions = ะัั
+variables.deletion.success = ะะผัะฝะฝั ะฒะธะดะฐะปะตะฝะพ.
+runners.id = ID
+runners.update_runner = ะะฝะพะฒะธัะธ ะทะผัะฝะธ
+variables.creation.failed = ะะต ะฒะดะฐะปะพัั ะดะพะดะฐัะธ ะทะผัะฝะฝั.
+variables.deletion.failed = ะะต ะฒะดะฐะปะพัั ะฒะธะดะฐะปะธัะธ ะทะผัะฝะฝั.
+status.waiting = ะััะบัั
+variables.creation.success = ะะผัะฝะฝั ยซ%sยป ะดะพะดะฐะฝะพ.
+runners.labels = ะััะบะธ
+status.unknown = ะะตะฒัะดะพะผะพ
+runners.task_list.no_tasks = ะะฐะฒะดะฐะฝั ะฟะพะบะธ ัะพ ะฝะตะผะฐั.
+runners.version = ะะตัััั
+status.blocked = ะะฐะฑะปะพะบะพะฒะฐะฝะพ
+status.cancelled = ะกะบะฐัะพะฒะฐะฝะพ
+variables.description = ะะผัะฝะฝั ะฟะตัะตะดะฐััััั ะฟะตะฒะฝะธะผ ะดััะผ ั ะฝะต ะผะพะถััั ะฑััะธ ะฟัะพัะธัะฐะฝั ัะฝะฐะบัะต.
+variables.deletion.description = ะะธะดะฐะปะตะฝะฝั ะทะผัะฝะฝะพั ั ะพััะฐัะพัะฝะธะผ ั ะนะพะณะพ ะฝะตะผะพะถะปะธะฒะพ ัะบะฐััะฒะฐัะธ. ะัะพะดะพะฒะถะธัะธ?
+variables.management = ะะตััะฒะฐะฝะฝั ะทะผัะฝะฝะธะผะธ
+variables.id_not_exist = ะะผัะฝะฝะพั ะท ัะดะตะฝัะธััะบะฐัะพัะพะผ %d ะฝะต ััะฝัั.
+variables.edit = ะ ะตะดะฐะณัะฒะฐัะธ ะทะผัะฝะฝั
+runs.expire_log_message = ะััะฝะฐะปะธ ะพัะธัะตะฝะพ, ัะพะผั ัะพ ะฒะพะฝะธ ะฑัะปะธ ะทะฐะฝะฐะดัะพ ััะฐัั.
+runs.empty_commit_message = (ะฟะพัะพะถะฝั ะฟะพะฒัะดะพะผะปะตะฝะฝั ะบะพะผััะฐ)
+runners.status.unspecified = ะะตะฒัะดะพะผะพ
+runs.status_no_select = ะฃัั ััะฐะฝะธ
+runs.status = ะกัะฐะฝ
+runners.task_list.status = ะกัะฐะฝ
+runners.status = ะกัะฐะฝ
+runs.no_workflows.documentation = ะะพะบะปะฐะดะฝััะต ะฟัะพ ะัั Forgejo ัะธัะฐะนัะต ะฒ ะดะพะบัะผะตะฝัะฐััั .
+runners.reset_registration_token = ะกะบะธะฝััะธ ัะพะบะตะฝ ัะตััััะฐััั
+workflow.enable_success = ะ ะพะฑะพัะธะน ะฟะพััะบ ยซ%sยป ััะฟััะฝะพ ะฒะฒัะผะบะฝะตะฝะพ.
+runs.workflow = ะ ะพะฑะพัะธะน ะฟะพััะบ
+workflow.disable = ะะธะผะบะฝััะธ ัะพะฑะพัะธะน ะฟะพััะบ
+workflow.disable_success = ะ ะพะฑะพัะธะน ะฟะพััะบ ยซ%sยป ััะฟััะฝะพ ะฒะธะผะบะฝะตะฝะพ.
+workflow.disabled = ะ ะพะฑะพัะธะน ะฟะพััะบ ะฒะธะผะบะฝะตะฝะพ.
+workflow.enable = ะฃะฒัะผะบะฝััะธ ัะพะฑะพัะธะน ะฟะพััะบ
+runs.no_workflows = ะ ะพะฑะพัะธั
ะฟะพัะพะบัะฒ ัะต ะฝะตะผะฐั.
+runs.all_workflows = ะฃัั ัะพะฑะพัั ะฟะพัะพะบะธ
+runs.no_results = ะะต ะทะฝะฐะนะดะตะฝะพ ะฒัะดะฟะพะฒัะดะฝะธั
ัะตะทัะปััะฐััะฒ.
+status.failure = ะะพะผะธะปะบะฐ
+status.running = ะัะฐััั
+status.success = ะฃัะฟัั
+status.skipped = ะัะพะฟััะตะฝะพ
+need_approval_desc = ะะพัััะฑะฝะต ัั
ะฒะฐะปะตะฝะฝั ะดะปั ะทะฐะฟััะบั ัะพะฑะพัะธั
ะฟะพัะพะบัะฒ ะดะปั ะทะฐะฟะธัั ะฝะฐ ะทะปะธััั.
+variables.not_found = ะะต ะฒะดะฐะปะพัั ะทะฝะฐะนัะธ ะทะผัะฝะฝั.
+runners.task_list.done_at = ะะฐะฒะตััะตะฝะพ
+runners.last_online = ะะพััะฐะฝะฝั ะฒ ะผะตัะตะถั
+runs.no_workflows.help_no_write_access = ะฉะพะฑ ะดัะทะฝะฐัะธัั ะฑัะปััะต ะฟัะพ ะัั Forgejo, ัะธัะฐะนัะต ะดะพะบัะผะตะฝัะฐััั .
+runs.no_workflows.help_write_access = ะะต ะทะฝะฐััะต, ัะบ ะฟะพัะฐัะธ ัะพะฑะพัั ะท ะััะผะธ Forgejo? ะะตัะตะณะปัะฝััะต ะฟะพััะฑะฝะธะบ ะดะปั ะฟะพัะฐัะบัะฒััะฒ ั ะดะพะบัะผะตะฝัะฐััั , ัะพะฑ ะฝะฐะฟะธัะฐัะธ ัะฒัะน ะฟะตััะธะน ัะพะฑะพัะธะน ะฟะพััะบ, ะฐ ะฟะพััะผ ะฝะฐะปะฐัััะนัะต ัะฐะฝะตั Forgejo ะดะปั ะฒะธะบะพะฝะฐะฝะฝั ะทะฐะฒะดะฐะฝั.
+unit.desc = ะะตััะฒะฐะฝะฝั ะฒะฑัะดะพะฒะฐะฝะธะผะธ ะบะพะฝะฒะตััะฐะผะธ CI/CD ะท ะััะผะธ Forgejo.
+runners.delete_runner_failed = ะะต ะฒะดะฐะปะพัั ะฒะธะดะฐะปะธัะธ ัะฐะฝะตั
+runners.new_notice = ะฏะบ ะทะฐะฟัััะธัะธ ัะฐะฝะตั
+runners.update_runner_failed = ะะต ะฒะดะฐะปะพัั ะพะฝะพะฒะธัะธ ัะฐะฝะตั
+runners.delete_runner_success = ะ ะฐะฝะตั ััะฟััะฝะพ ะฒะธะดะฐะปะตะฝะพ
+runners.none = ะะตะผะฐั ะดะพัััะฟะฝะธั
ัะฐะฝะตััะฒ
+runners.delete_runner_notice = ะฏะบัะพ ะฝะฐ ััะพะผั ัะฐะฝะตัั ะฒะธะบะพะฝัััััั ะทะฐะฒะดะฐะฝะฝั, ะนะพะณะพ ะฑัะดะต ะทะฐะฒะตััะตะฝะพ ั ะฟะพะทะฝะฐัะตะฝะพ ัะบ ะฝะตะฒะดะฐะปะต. ะฆะต ะผะพะถะต ะฟะพัััะธัะธ ัะพะฑะพัะธะน ะฟะพััะบ ะทะฑััะบะธ.
+workflow.dispatch.run = ะะฐะฟัััะธัะธ ัะพะฑะพัะธะน ะฟะพััะบ
+runners.edit_runner = ะ ะตะดะฐะณัะฒะฐัะธ ัะฐะฝะตั
+runs.no_runs = ะ ะพะฑะพัะธะน ะฟะพััะบ ัะต ะฝะต ะทะฐะฟััะบะฐะฒัั.
+runners = ะ ะฐะฝะตัะธ
+runners.runner_manage_panel = ะะตััะฒะฐะฝะฝั ัะฐะฝะตัะฐะผะธ
+workflow.dispatch.success = ะะฐะฟะธั ะฝะฐ ะทะฐะฟััะบ ัะพะฑะพัะพะณะพ ะฟะพัะพะบั ััะฟััะฝะพ ััะฒะพัะตะฝะพ.
+runs.no_matching_online_runner_helper = ะะต ะทะฝะฐะนะดะตะฝะพ ัะฐะฝะตัะฐ ะฒ ะผะตัะตะถั ะท ะผััะบะพั: %s
+runners.reset_registration_token_success = ะขะพะบะตะฝ ัะตััััะฐััั ัะฐะฝะตัะฐ ััะฟััะฝะพ ัะบะธะฝััะพ
+runners.new = ะกัะฒะพัะธัะธ ะฝะพะฒะธะน ัะฐะฝะตั
+runners.delete_runner = ะะธะดะฐะปะธัะธ ัะตะน ัะฐะฝะตั
+runners.runner_title = ะ ะฐะฝะตั
+runners.task_list = ะะตัะพะดะฐะฒะฝั ะทะฐะฒะดะฐะฝะฝั ัะฐะฝะตัะฐ
+runners.update_runner_success = ะ ะฐะฝะตั ะพะฝะพะฒะปะตะฝะพ
+runners.delete_runner_header = ะัะดัะฒะตัะดััั ะฒะธะดะฐะปะตะฝะฝั ัะฐะฝะตัะฐ
[projects]
+type-3.display_name = ะัะพัะบั ะพัะณะฐะฝัะทะฐััั
+type-2.display_name = ะัะพัะบั ัะตะฟะพะทะธัะพััั
+type-1.display_name = ะัะพะฑะธััะธะน ะฟัะพัะบั
+deleted.display_name = ะะธะดะฐะปะตะฝะธะน ะฟัะพัะบั
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=ะกะธะผะฒะพะปััะฝะต ะฟะพัะธะปะฐะฝะฝั
+directory = ะขะตะบะฐ
+submodule = ะัะดะผะพะดัะปั
+normal_file = ะะฒะธัะฐะนะฝะธะน ัะฐะนะป
+executable_file = ะะธะบะพะฝัะฒะฐะฝะธะน ัะฐะนะป
+changed_filemode = %[1]s โ %[2]s
+
+
+[search]
+code_kind = ะจัะบะฐัะธ ะบะพะดโฆ
+code_search_unavailable = ะะพััะบ ะบะพะดั ะฝะฐัะฐะทั ะฝะตะดะพัััะฟะฝะธะน. ะัะดั ะปะฐัะบะฐ, ะทะฒสผัะถััััั ะท ะฐะดะผัะฝััััะฐัะพัะพะผ ัะฐะนัั.
+user_kind = ะจัะบะฐัะธ ะบะพัะธัััะฒะฐััะฒโฆ
+repo_kind = ะจัะบะฐัะธ ัะตะฟะพะทะธัะพัััโฆ
+search = ะะพััะบโฆ
+type_tooltip = ะะธะด ะฟะพััะบั
+fuzzy = ะะตัััะบะธะน
+fuzzy_tooltip = ะะบะปััะฐัะธ ัะตะทัะปััะฐัะธ, ัะพ ะฟะพะดัะฑะฝั ะฟะพััะบะพะฒะพะผั ะทะฐะฟะธัั
+union_tooltip = ะะบะปััะฐัะธ ัะตะทัะปััะฐัะธ, ัะพ ะฒัะดะฟะพะฒัะดะฐััั ะฑัะดั-ัะบะพะผั ะท ะบะปััะพะฒะธั
ัะปัะฒ, ัะพะทะดัะปะตะฝะธั
ะฟัะพะฑัะปะฐะผะธ
+union = ะะปััะพะฒั ัะปะพะฒะฐ
+exact = ะขะพัะฝะธะน
+exact_tooltip = ะะบะปััะฐัะธ ะปะธัะต ัะตะทัะปััะฐัะธ, ัะพ ัััะบะพ ะฒัะดะฟะพะฒัะดะฐััั ะทะฐะฟะธัั
+regexp = ะ ะตะณัะปััะฝั ะฒะธัะฐะทะธ
+regexp_tooltip = ะะฟัะฐััะพะฒัะฒะฐัะธ ะฟะพััะบะพะฒะธะน ะทะฐะฟะธั ัะบ ัะตะณัะปััะฝะธะน ะฒะธัะฐะท
+org_kind = ะจัะบะฐัะธ ะพัะณะฐะฝัะทะฐัััโฆ
+team_kind = ะจัะบะฐัะธ ะบะพะผะฐะฝะดะธโฆ
+milestone_kind = ะจัะบะฐัะธ ะฒัั
ะธ...
+commit_kind = ะจัะบะฐัะธ ะบะพะผะตะฝัะฐััโฆ
+no_results = ะะต ะทะฝะฐะนะดะตะฝะพ ะฒัะดะฟะพะฒัะดะฝะธั
ัะตะทัะปััะฐััะฒ.
+keyword_search_unavailable = ะะพััะบ ะทะฐ ะบะปััะพะฒะธะผะธ ัะปะพะฒะฐะผะธ ะฝะฐัะฐะทั ะฝะตะดะพัััะฟะฝะธะน. ะัะดั ะปะฐัะบะฐ, ะทะฒ'ัะถััััั ะท ะฐะดะผัะฝััััะฐัะพัะพะผ ัะฐะนัั.
+code_search_by_git_grep = ะะพัะพัะฝั ัะตะทัะปััะฐัะธ ะฟะพััะบั ะบะพะดั ะฝะฐะดะฐััััั ะท ยซgit grepยป. ะขัั ะผะพะถััั ะฑััะธ ะบัะฐัั ัะตะทัะปััะฐัะธ, ัะบัะพ ะฐะดะผัะฝััััะฐัะพั ัะฐะนัั ะฒะฒัะผะบะฝัะฒ ัะฝะดะตะบัะฐััั ะบะพะดั.
+package_kind = ะจัะบะฐัะธ ะฟะฐะบัะฝะบะธโฆ
+project_kind = ะจัะบะฐัะธ ะฟัะพัะบัะธโฆ
+branch_kind = ะจัะบะฐัะธ ะณัะปะบะธโฆ
+issue_kind = ะจัะบะฐัะธ ะทะฐะดะฐััโฆ
+pull_kind = ะจัะบะฐัะธ ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธัััโฆ
+runner_kind = ะจัะบะฐัะธ ัะฐะฝะตัะธโฆ
+
+[markup]
+filepreview.truncated = ะะตัะตะณะปัะด ะฑัะปะพ ัััะทะฐะฝะพ
+filepreview.line = ะ ัะดะพะบ %[1]d ะฒ %[2]s
+filepreview.lines = ะ ัะดะบะธ ะท %[1]d ะฟะพ %[2]d ะฒ %[3]s
+
+[translation_meta]
+test = ะฆะต ัะตััะพะฒะธะน ัะตะบัั. ะัะฝ ะฝะต ะฒัะดะพะฑัะฐะถะฐััััั ะฒ ัะฝัะตััะตะนัั ะบะพัะธัััะฒะฐัะฐ Forgejo, ะฐ ะฒะธะบะพัะธััะพะฒัััััั ะท ะผะตัะพั ัะตัััะฒะฐะฝะฝั
+
+[repo.permissions]
+packages.read = ะงะธัะฐัะธ: ะดะธะฒะธัะธัั ัะฐ ะทะฐะฒะฐะฝัะฐะถะธัะธ ะฟะฐะบัะฝะบะธ, ะฟัะธะทะฝะฐัะตะฝั ะดะพ ัะตะฟะพะทะธัะพััั.
+packages.write = ะะธัะฐัะธ: ะฟัะฑะปัะบัะฒะฐัะธ ัะฐ ะฒะธะดะฐะปััะธ ะฟะฐะบัะฝะบะธ, ะฟัะธะทะฝะฐัะตะฝั ะดะพ ัะตะฟะพะทะธัะพััั.
+
+issues.read = ะงะธัะฐัะธ: ะดะธะฒะธัะธัั ั ััะฒะพััะฒะฐัะธ ะทะฐะดะฐัั ัะฐ ะบะพะผะตะฝัะฐัั.
+pulls.read = ะงะธัะฐัะธ: ะดะธะฒะธัะธัั ั ััะฒะพััะฒะฐัะธ ะทะฐะฟะธัะธ ะฝะฐ ะทะปะธััั.
+releases.read = ะงะธัะฐัะธ: ะดะธะฒะธัะธัั ั ะทะฐะฒะฐะฝัะฐะถัะฒะฐัะธ ะฒะธะฟััะบะธ.
+releases.write = ะะธัะฐัะธ: ะฟัะฑะปัะบัะฒะฐัะธ, ะทะผัะฝัะฒะฐัะธ ั ะฒะธะดะฐะปััะธ ะฒะธะฟััะบะธ ัะฐ ัั
ะฝั ัะตััััะธ.
+wiki.read = ะงะธัะฐัะธ: ะฟะตัะตะณะปัะดะฐัะธ ะฒะฑัะดะพะฒะฐะฝั ะฒัะบั ัะฐ ัั ัััะพััั.
+wiki.write = ะะธัะฐัะธ: ััะฒะพััะฒะฐัะธ, ะพะฝะพะฒะปัะฒะฐัะธ ัะฐ ะฒะธะดะฐะปััะธ ััะพััะฝะบะธ ะฒะฑัะดะพะฒะฐะฝะพั ะฒัะบั.
+actions.read = ะงะธัะฐัะธ: ะดะธะฒะธัะธัั ะฒะฑัะดะพะฒะฐะฝั ะบะพะฝะฒะตััะธ CI/CD ัะฐ ัั
ะฝั ะถััะฝะฐะปะธ.
+actions.write = ะะธัะฐัะธ: ะฒัััะฝั ะทะฐะฟััะบะฐัะธ, ะฟะตัะตะทะฐะฟััะบะฐัะธ, ัะบะฐัะพะฒัะฒะฐัะธ ะฐะฑะพ ัั
ะฒะฐะปัะฒะฐัะธ ะบะพะฝะฒะตััะธ CI/CD ะฒ ะพััะบัะฒะฐะฝะฝั.
+
+[munits.data]
+pib = ะัะ
+eib = ะัะ
+kib = ะัะ
+mib = ะัะ
+gib = ะัะ
+tib = ะขัะ
+b = ะ
diff --git a/options/locale/locale_vi.ini b/options/locale/locale_vi.ini
new file mode 100644
index 0000000000..57e592a209
--- /dev/null
+++ b/options/locale/locale_vi.ini
@@ -0,0 +1,86 @@
+[common]
+home = Trang chแปง
+explore = Khรกm phรก
+help = Trแปฃ giรบp
+sign_in = ฤฤng nhแบญp
+sign_in_or = hoแบทc
+sign_out = ฤฤng xuแบฅt
+sign_up = ฤฤng kรฝ
+link_account = Liรชn kแบฟt tร i khoแบฃn
+register = ฤฤng kรฝ
+version = Phiรชn bแบฃn
+powered_by = Sแปญ dแปฅng %s
+page = Trang
+template = Mแบซu
+language = Ngรดn ngแปฏ
+notifications = Thรดng bรกo
+create_new = Tแบกoโฆ
+enable_javascript = Trang nร y cแบงn JavaScript.
+licenses = Giแบฅy phรฉp
+return_to_forgejo = Quay lแบกi Forgejo
+username = Tรชn ngฦฐแปi dรนng
+email = ฤแปa chแป thฦฐ ฤiแปn tแปญ
+password = Mแบญt khแบฉu
+access_token = Mรฃ truy cแบญp
+captcha = CAPTCHA
+twofa = Xรกc thแปฑc hai lแปp
+webauthn_insert_key = Cแบฏm khรณa bแบฃo mแบญt cแปงa bแบกn vร o
+copy_hash = Chรฉp chuแปi bฤm
+sign_in_with_provider = ฤฤng nhแบญp bแบฑng %s
+webauthn_press_button = Hรฃy nhแบฅn nรบt trรชn khรณa bแบฃo mแบญtโฆ
+webauthn_use_twofa = Dรนng mรฃ xรกc thแปฑc hai lแปp แป trรชn ฤiแปn thoแบกi
+webauthn_error = Khรดng thแป ฤแปc khรณa bแบฃo mแบญt cแปงa bแบกn.
+webauthn_unsupported_browser = Trรฌnh duyแปt cแปงa bแบกn hiแปn khรดng hแป trแปฃ WebAuthn.
+webauthn_error_unknown = Cรณ lแปi xแบฃy ra. Vui lรฒng thแปญ lแบกi.
+webauthn_error_insecure = WebAuthn chแป hแป trแปฃ kแบฟt nแปi mรฃ hรณa. Nแบฟu ฤang thแปญ nghiแปm, bแบกn cรณ thแป dรนng "localhost" hoแบทc "127.0.0.1"
+webauthn_error_unable_to_process = Mรกy chแปง khรดng thแป xแปญ lรฝ yรชu cแบงu cแปงa bแบกn.
+webauthn_error_empty = Bแบกn phแบฃi ฤแบทt tรชn cho khรณa nร y.
+webauthn_error_timeout = Hแบฟt thแปi gian ฤแปc khรณa mแบฅt rแปi. Hรฃy tแบฃi lแบกi trang vร thแปญ lแบกi.
+copy_type_unsupported = Khรดng chรฉp ฤฦฐแปฃc
+repository = Kho mรฃ
+organization = Tแป chแปฉc
+new_fork = Tแบกo mแปt nhรกnh mแปi
+new_project = Tแบกo dแปฑ รกn
+new_project_column = Thรชm cแปt
+admin_panel = Quแบฃn trแป trang
+settings = Cร i ฤแบทt
+your_profile = Hแป sฦก
+your_settings = Cร i ฤแบทt
+new_repo.title = Tแบกo kho mรฃ
+new_migrate.title = Chuyแปn kho mรฃ
+new_org.title = Tแบกo tแป chแปฉc
+new_repo.link = Tแบกo kho mรฃ
+new_migrate.link = Chuyแปn kho mรฃ
+all = Tแบฅt cแบฃ
+sources = Nguแปn
+forks = Cรกc phรขn nhรกnh
+activities = Hoแบกt ฤแปng
+pull_requests = Yรชu cแบงu thรชm mรฃ
+save = Lฦฐu
+issues =
+enabled = Bแบญt
+disabled = Tแบฏt
+copy = Chรฉp
+copy_generic = Chรฉp vร o bแป nhแป tแบกm
+copy_url = Chรฉp URL
+copy_content = Chรฉp nแปi dung
+copy_success = ฤรฃ chรฉp!
+copy_error = Khรดng chรฉp ฤฦฐแปฃc
+write = Viแบฟt
+preview = Xem trฦฐแปc
+error = Lแปi
+error413 = Bแบกn ฤรฃ dรนng hแบฟt ฤแปnh mแปฉc.
+go_back = Quay lแบกi
+invalid_data = Dแปฏ liแปu khรดng hแปฃp lแป: %v
+never = Khรดng bao giแป
+unknown = Khรดng biแบฟt
+unpin = Bแป ghim
+pin = Ghim
+archived = ฤรฃ lฦฐu trแปฏ
+signed_in_as = ฤฤng nhแบญp bแบฑng
+re_type = Xรกc nhแบญn mแบญt khแบฉu
+webauthn_sign_in = Nhแบฅn nรบt trรชn khรณa bแบฃo mแบญt, nแบฟu khรดng cรณ nรบt thรฌ bแบกn hรฃy rรบt ra rแปi cแบฏm lแบกi.
+new_org.link = Tแบกo tแป chแปฉc
+error404 = Trang bแบกn ฤang tรฌm khรดng tแปn tแบกi hoแบทc bแบกn khรดng cรณ quyแปn xem .
+edit = Chแปnh sแปญa
+filter = Lแปc
\ No newline at end of file
diff --git a/options/locale/locale_yi.ini b/options/locale/locale_yi.ini
new file mode 100644
index 0000000000..9340e3ef0a
--- /dev/null
+++ b/options/locale/locale_yi.ini
@@ -0,0 +1 @@
+[common]
\ No newline at end of file
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index 9dc86d07ee..9ec958d7b2 100644
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -1,6 +1,6 @@
[common]
home=้ฆ้กต
-dashboard=้ฆ้กต
+dashboard=ๆงๅถ้ขๆฟ
explore=ๆข็ดข
help=ๅธฎๅฉ
logo=ๅพฝๆ
@@ -12,15 +12,15 @@ sign_up=ๆณจๅ
link_account=้พๆฅ่ดฆๆท
register=ๆณจๅ
version=ๅฝๅ็ๆฌ
-powered_by=Powered by %s
+powered_by=็ฑ %s ๆไพๆฏๆ
page=้กต้ข
template=ๆจกๆฟ
language=่ฏญ่จ้้กน
notifications=้็ฅ
-active_stopwatch=ๆดปๅจๆถ้ด่ท่ธชๅจ
-tracked_time_summary=ๅบไบ้ฎ้ขๅ่กจ่ฟๆปคๅจ็่ท่ธชๆถ้ดๆฆ่ฆ
+active_stopwatch=ๆดป่ทๆถ้ด่ท่ธชๅจ
+tracked_time_summary=ๅบไบๅทฅๅๅ่กจ่ฟๆปคๅจ็่ท่ธชๆถ้ดๆฆ่ฆ
create_new=ๅๅปบโฆ
-user_profile_and_more=ไธชไบบไฟกๆฏๅ่ฎพ็ฝฎโฆ
+user_profile_and_more=ไธชไบบไฟกๆฏไธ่ฎพ็ฝฎโฆ
signed_in_as=ๅทฒ็ปๅฝ็จๆท
enable_javascript=ๆญค็ฝ็ซ้่ฆ JavaScriptใ
toc=็ฎๅฝ
@@ -30,11 +30,11 @@ return_to_forgejo=่ฟๅ Forgejo
username=็จๆทๅ
email=็ตๅญ้ฎไปถๅฐๅ
password=ๅฏ็
-access_token=่ฎฟ้ฎไปค็๏ผAccess Token๏ผ
+access_token=่ฎฟ้ฎไปค็
re_type=็กฎ่ฎคๅฏ็
captcha=้ช่ฏ็
twofa=ไธคๆญฅ้ช่ฏ
-twofa_scratch=ไธคๆญฅ้ช่ฏๅฃไปค
+twofa_scratch=ไธคๆญฅ้ช่ฏๅค็จ้ช่ฏ็
passcode=้ช่ฏ็
webauthn_insert_key=ๆๅ
ฅๅฎๅ
จๅฏ้ฅ
@@ -56,28 +56,28 @@ organization=็ป็ป
mirror=้ๅ
new_repo=ๅๅปบไปๅบ
new_migrate=่ฟ็งปๅค้จไปๅบ
-new_mirror=ๅๅปบๆฐ็้ๅ
-new_fork=ๆฐ็ๆดพ็ไปๅบ
+new_mirror=ๅๅปบ้ๅ
+new_fork=ๅๅปบๆดพ็ไปๅบ
new_org=ๅๅปบ็ป็ป
new_project=ๅๅปบ้กน็ฎ
new_project_column=ๅๅปบๅ
manage_org=็ฎก็ๆ็็ป็ป
-admin_panel=็ฎก็ๅๅฐ
+admin_panel=็ฝ็ซ็ฎก็
account_settings=ๅธๆท่ฎพ็ฝฎ
settings=่ฎพ็ฝฎ
your_profile=ไธชไบบไฟกๆฏ
-your_starred=ๅทฒ็น่ต
+your_starred=็น่ต
your_settings=่ฎพ็ฝฎ
all=ๆๆ
-sources=่ชๅปบ
+sources=ๆฅๆบ
mirrors=้ๅ
collaborative=ๅไฝ
forks=ๆดพ็
activities=ๆ่ฟๆดปๅจ
pull_requests=ๅๅนถ่ฏทๆฑ
-issues=ๅทฅๅ็ฎก็
+issues=ๅทฅๅ
milestones=้็จ็ข
ok=็กฎๅฎ
@@ -87,10 +87,10 @@ rerun=้ๆฐ่ฟ่ก
rerun_all=้ๆฐ่ฟ่กๆๆไปปๅก
save=ไฟๅญ
add=ๆทปๅ
-add_all=ๆทปๅ ๆๆ
+add_all=ๅ
จ้จๆทปๅ
remove=็งป้ค
-remove_all=็งป้คๆๆ
-remove_label_str=ๅ ้คๆ ็ญพ "%s"
+remove_all=ๅ
จ้จ็งป้ค
+remove_label_str=ๅ ้คๆ ็ญพโ%sโ
edit=็ผ่พ
view=ๆฅ็
@@ -109,24 +109,24 @@ copy_type_unsupported=ๆ ๆณๅคๅถๆญค็ฑปๅ็ๆไปถๅ
ๅฎน
write=ๆฐๅ
preview=้ข่ง
-loading=ๆญฃๅจๅ ่ฝฝ...
+loading=ๆญฃๅจๅ ่ฝฝโฆ
error=้่ฏฏ
-error404=ๆจๆญฃๅฐ่ฏ่ฎฟ้ฎ็้กต้ข ไธๅญๅจ ๆ ๆจๅฐๆช่ขซๆๆ ๆฅ็่ฏฅ้กต้ขใ
+error404=ๆจๅฐ่ฏ่ฎฟ้ฎ็้กต้ขไธๅญๅจ ใๅทฒ่ขซ็งป้ค ๆๆจๆ ๆๆฅ็ ใ
go_back=่ฟๅ
-never=ไปไธ
+never=ไปๆช
unknown=ๆช็ฅ
rss_feed=RSS ่ฎข้
ๆบ
-pin=ๅบๅฎ
+pin=็ฝฎ้กถ
unpin=ๅๆถ็ฝฎ้กถ
artifacts=ๅถๅ
confirm_delete_artifact=ๆจ็กฎๅฎ่ฆๅ ้คๅถๅโ%sโๅ๏ผ
-archived=ๅทฒๅฝๆกฃ
+archived=ๅทฒๅญๆกฃ
concept_system_global=ๅ
จๅฑ
concept_user_individual=ไธชไบบ
@@ -143,21 +143,30 @@ confirm_delete_selected=็กฎ่ฎคๅ ้คๆๆ้ไธญ้กน็ฎ๏ผ
name=ๅ็งฐ
value=ๅผ
filter = ็ญ้
-filter.clear = ๆธ
้ค็ญ้ๆกไปถ
-filter.is_archived = ๅทฒๅฝๆกฃ
-filter.not_archived = ๆชๅฝๆกฃ
-filter.is_fork = ๅทฒๆดพ็
-filter.not_fork = ๆชๆดพ็
-filter.is_mirror = ๅทฒ้ๅ
-filter.not_mirror = ๆช้ๅ
-filter.is_template = ๆจกๆฟ
-filter.not_template = ้ๆจกๆฟ
+filter.clear = ๆธ
้คๆกไปถ
+filter.is_archived = ๅทฒๅญๆกฃ
+filter.not_archived = ๆชๅญๆกฃ
+filter.is_fork = ๆฏๆดพ็
+filter.not_fork = ไธๆฏๆดพ็
+filter.is_mirror = ๆฏ้ๅ
+filter.not_mirror = ไธๆฏ้ๅ
+filter.is_template = ๆฏๆจกๆฟ
+filter.not_template = ไธๆฏๆจกๆฟ
filter.public = ๅ
ฌๅผ
filter.private = ็งๆ
toggle_menu = ๅๆข่ๅ
invalid_data = ๆ ๆๆฐๆฎ๏ผ%v
more_items = ๆพ็คบๆดๅค
copy_generic = ๅคๅถๅฐๅช่ดดๆฟ
+test = ๆต่ฏ
+error413 = ๆจๅทฒ็จๅฐฝๆจ็้
้ขใ
+new_repo.title = ๅๅปบไปๅบ
+new_migrate.title = ๅผๅง่ฟ็งป
+new_org.title = ๅๅปบ็ป็ป
+new_repo.link = ๅๅปบไปๅบ
+new_migrate.link = ๅผๅง่ฟ็งป
+new_org.link = ๅๅปบ็ป็ป
+copy_path = ๅคๅถ่ทฏๅพ
[aria]
navbar=ๅฏผ่ชๆ
@@ -166,12 +175,12 @@ footer.software=ๅ
ณไบ่ฝฏไปถ
footer.links=้พๆฅ
[heatmap]
-number_of_contributions_in_the_last_12_months=ไธๅนดๅ
%s ๆฌก่ดก็ฎ
-contributions_zero=็ฎๅ่ฟๆฒกๆ่ดก็ฎ
-less=ๆดๅฐ็
-more=ๆดๅค็
-contributions_format = {year}{month}{day} ๅฝๆฅๆ {contributions}
-contributions_few = ้กน่ดก็ฎ
+number_of_contributions_in_the_last_12_months=่ฟๅป็ไธๅนดๅ
ๆ %s ๆฌก่ดก็ฎ
+contributions_zero=ๆฒกๆ่ดก็ฎ
+less=่พๅฐ
+more=่พๅค
+contributions_format = {year}ๅนด{month}{day}ๆฅๆ{contributions}
+contributions_few = ่ดก็ฎ
contributions_one = ่ดก็ฎ
[editor]
@@ -189,6 +198,18 @@ buttons.ref.tooltip=ๅผ็จไธไธช้ฎ้ขๆๆๅ่ฏทๆฑ
buttons.switch_to_legacy.tooltip=ไฝฟ็จๆง็็ผ่พๅจ
buttons.enable_monospace_font=ๅฏ็จ็ญๅฎฝๅญไฝ
buttons.disable_monospace_font=็ฆ็จ็ญๅฎฝๅญไฝ
+buttons.unindent.tooltip = ่งฃ้คไธ็บงๅตๅฅๆก็ฎ
+buttons.indent.tooltip = ๅตๅฅไธ็บงๆก็ฎ
+table_modal.header = ๆทปๅ ่กจๆ ผ
+table_modal.placeholder.header = ๆ ้ข
+table_modal.label.columns = ๅๆฐ
+table_modal.label.rows = ่กๆฐ
+buttons.new_table.tooltip = ๆทปๅ ่กจๆ ผ
+table_modal.placeholder.content = ๅ
ๅฎน
+link_modal.header = ๆทปๅ ้พๆฅ
+link_modal.url = URL
+link_modal.description = ๆ่ฟฐ
+link_modal.paste_reminder = ๆ็คบ๏ผๆจๅฏไปฅๅฐๅช่ดดๆฟไธญ็ URL ็ดๆฅ็ฒ่ดดๅฐ็ผ่พๅจๅๅปบ้พๆฅใ
[filter]
string.asc=A - Z
@@ -196,7 +217,7 @@ string.desc=Z - A
[error]
occurred=ๅ็ไบไธไธช้่ฏฏ
-report_message=ๅฆๆๆจ็กฎๅฎ่ฟๆฏไธไธช Forgejo bug๏ผ่ฏทๅจ Codeberg ไธๆ็ดข้ฎ้ข๏ผๆๅจๅฟ
่ฆๆถๅๅปบไธไธชๆฐๅทฅๅใ
+report_message=ๅฆๆๆจ็กฎๅฎ่ฟๆฏไธไธช Forgejo ็ bug๏ผ่ฏทๅจ Codeberg ไธๆ็ดข็ธๅ
ณ้ฎ้ขๆๅจๅฟ
่ฆๆถๅๅปบไธไธชๆฐๅทฅๅใ
missing_csrf=้่ฏฏ็่ฏทๆฑ๏ผๆฒกๆ CSRF ไปค็
invalid_csrf=้่ฏฏ็่ฏทๆฑ๏ผๆ ๆ็ CSRF ไปค็
not_found=ๆพไธๅฐ็ฎๆ ใ
@@ -206,13 +227,13 @@ server_internal = ๆๅกๅจๅ
้จ้่ฏฏ
[startpage]
app_desc=ไธๆฌพๆๆๆญๅปบ็่ชๅฉ Git ๆๅก
install=ๆๅฎ่ฃ
-install_desc=้่ฟ ไบ่ฟๅถ ๆฅ่ฟ่ก๏ผๆ่
้่ฟ docker ๆฅ่ฟ่ก๏ผๆ่
้่ฟ ๅฎ่ฃ
ๅ
ๆฅ่ฟ่ก
+install_desc=้่ฟไบ่ฟๅถ ๆฅ่ฟ่ก๏ผๆ่
้่ฟDocker ๆฅ่ฟ่ก๏ผๆ่
้่ฟๅฎ่ฃ
ๅ
ๆฅ่ฟ่กใ
platform=่ทจๅนณๅฐ
-platform_desc=ไปปไฝ Go ่ฏญ่จ ๆฏๆ็ๅนณๅฐ้ฝๅฏไปฅ่ฟ่ก Forgejo๏ผๅ
ๆฌ WindowsใMacใLinux ไปฅๅ ARMใๆไธไธชๆจๅๆฌข็ๅฐฑ่ก๏ผ
+platform_desc=ๅทฒ่ฏๅฎๅฏไปฅๅจ Linux ๅ FreeBSD ็ญ่ช็ฑๆไฝ็ณป็ปไปฅๅไธๅ็ CPU ๆถๆไธ่ฟ่ก Forgejoใๆไธไธชๆจๅๆฌข็ๅฐฑ่ก๏ผ
lightweight=่ฝป้็บง
lightweight_desc=ไธไธชๅปไปท็ๆ ่ๆดพ็้
็ฝฎ่ถณไปฅๆปก่ถณ Forgejo ็ๆไฝ็ณป็ป็กฌไปถ่ฆๆฑใๆๅคง็จๅบฆไธ่็ๆจ็ๆๅกๅจ่ตๆบ๏ผ
license=ๅผๆบๅ
-license_desc=ๆๆ็ไปฃ็ ้ฝๅผๆบๅจ Forgejo ไธ๏ผ่ตถๅฟซๅ ๅ
ฅๆไปฌๆฅๅ
ฑๅๅๅฑ่ฟไธชไผๅคง็้กน็ฎ๏ผ่ฟ็ญไปไน๏ผๆไธบ่ดก็ฎ่
ๅง๏ผ
+license_desc=ๅๅพ Forgejo ๏ผ่ตถๅฟซๅ ๅ
ฅๆไปฌ ๆฅๅ
ฑๅๅๅฑ่ฟไธชไผๅคง็้กน็ฎ๏ผ่ฟ็ญไปไน๏ผๆไธบ่ดก็ฎ่
ๅง๏ผ
[install]
install=ๅฎ่ฃ
้กต้ข
@@ -225,8 +246,8 @@ host=ๆฐๆฎๅบไธปๆบ
user=็จๆทๅ
password=ๆฐๆฎๅบ็จๆทๅฏ็
db_name=ๆฐๆฎๅบๅ็งฐ
-db_schema=Schema
-db_schema_helper=็็ฉบๅๆฐๆฎๅบไธญ้ป่ฎคๅผไธบ("public")ใ
+db_schema=ๆถๆๆจกๅผ
+db_schema_helper=็็ฉบๅๆฐๆฎๅบไธญ้ป่ฎคๅผไธบ๏ผ"public"๏ผใ
ssl_mode=SSL
path=ๆฐๆฎๅบๆไปถ่ทฏๅพ
sqlite_helper=SQLite3 ๆฐๆฎๅบ็ๆไปถ่ทฏๅพใ ๅฆๆไปฅๆๅก็ๆนๅผ่ฟ่ก Forgejo๏ผ่ฏท่พๅ
ฅ็ปๅฏน่ทฏๅพใ
@@ -236,7 +257,7 @@ reinstall_confirm_check_1=ไฝฟ็จ app.ini ไธญ SECRET KEY ๅ ๅฏ็ๆฐๆฎๅฏ่ฝไผ
reinstall_confirm_check_2=ไปฃ็ ไปๅบๅ่ฎพ็ฝฎๅฏ่ฝ้่ฆ้ๆฐๅๆญฅใๅพ้ๆญคๆก๏ผ่กจ็คบๆจ็กฎ่ฎคๅฐๆๅจ้ๆฐๅๆญฅไปๅบๅ SSH authorized_keys ็้ฉๅญใๆจ็กฎ่ฎคๆจๅฐ็กฎไฟไปฃ็ ไปๅบๅ้ๅ่ฎพ็ฝฎๆฏๆญฃ็กฎ็ใ
reinstall_confirm_check_3=ไฝ ็กฎ่ฎคไฝ ็ปๅฏน่ฏๅฎ่ฟไธช Forgejo ๅจๆญฃ็กฎ็ app.ini ไฝ็ฝฎไธ่ฟ่ก๏ผ่ไธไฝ ็กฎๅฎไฝ ๅฟ
้กป้ๆฐๅฎ่ฃ
ใไฝ ็กฎ่ฎคไฝ ็ฅๆไธ่ฟฐ้ฃ้ฉใ
err_empty_db_path=SQLite ๆฐๆฎๅบๆไปถ่ทฏๅพไธ่ฝไธบ็ฉบใ
-no_admin_and_disable_registration=ๆจไธ่ฝๅคๅจๆชๅๅปบ็ฎก็ๅ็จๆท็ๆ
ๅตไธ็ฆๆญขๆณจๅใ
+no_admin_and_disable_registration=ๆจไธ่ฝๅคๅจๆชๅๅปบ็ฎก็ๅ่ดฆๅท็ๆ
ๅตไธ็ฆๆญขๆณจๅใ
err_empty_admin_password=็ฎก็ๅๅฏ็ ไธ่ฝไธบ็ฉบใ
err_empty_admin_email=็ฎก็ๅ็ตๅญ้ฎไปถไธ่ฝไธบ็ฉบใ
err_admin_name_is_reserved=็ฎก็ๅ็จๆทๅๆ ๆ๏ผ็จๆทๅๆฏไฟ็็
@@ -249,8 +270,8 @@ app_name_helper=ๅจๆญคๅค่พๅ
ฅๆจ็ๅฎไพๅ็งฐใๅฎๅฐๆพ็คบๅจๆๆ้กต้ข
repo_path=ไปๅบๆ น็ฎๅฝ
repo_path_helper=ๆๆ่ฟ็จ Git ไปๅบๅฐไฟๅญๅฐๆญค็ฎๅฝใ
lfs_path=LFS ๆ น็ฎๅฝ
-lfs_path_helper=ๅญๅจไธบGit LFS็ๆไปถๅฐ่ขซๅญๅจๅจๆญค็ฎๅฝใ็็ฉบ็ฆ็จLFS
-run_user=ไปฅ็จๆท่ฟ่ก
+lfs_path_helper=ๅญๅจไธบGit LFS็ๆไปถๅฐ่ขซๅญๅจๅจๆญค็ฎๅฝใ็็ฉบไปฅ็ฆ็จLFSใ
+run_user=่ฆไฝฟ็จ็็จๆท่บซไปฝ
run_user_helper=่พๅ
ฅ Forgejo ่ฟ่ก็ๆไฝ็ณป็ป็จๆทๅใ่ฏทๆณจๆ๏ผๆญค็จๆทๅฟ
้กปๅ
ทๆๅฏนไปๅบๆ น่ทฏๅพ็่ฎฟ้ฎๆ้ใ
domain=ๆๅกๅจๅๅ
domain_helper=ๆๅกๅจ็ๅๅๆไธปๆบๅฐๅใ
@@ -259,16 +280,16 @@ ssh_port_helper=SSH ๆๅกๅจ็็ซฏๅฃๅท๏ผไธบ็ฉบๅ็ฆ็จๅฎใ
http_port=HTTP ๆๅก็ซฏๅฃ
http_port_helper=Forgejos web ๆๅกๅจๅฐไพฆๅฌ็็ซฏๅฃๅทใ
app_url=ๅบ็กURL
-app_url_helper=็จไบ HTTP (S) ๅ
้ๅ็ตๅญ้ฎไปถ้็ฅ็ๅบๆฌๅฐๅใ
+app_url_helper=็จไบ HTTP(S) ๅ
้ๅ็ตๅญ้ฎไปถ้็ฅ็ๅบ็กURLใ
log_root_path=ๆฅๅฟ่ทฏๅพ
log_root_path_helper=ๆฅๅฟๆไปถๅฐๅๅ
ฅๆญค็ฎๅฝใ
optional_title=ๅฏ้่ฎพ็ฝฎ
-email_title=็ตๅญ้ฎ็ฎฑ่ฎพ็ฝฎ
+email_title=็ตๅญ้ฎไปถ่ฎพ็ฝฎ
smtp_addr=SMTP ไธปๆบๅฐๅ
smtp_port=SMTP ็ซฏๅฃ
smtp_from=็ตๅญ้ฎไปถๅไปถไบบ
-smtp_from_helper=่ฏท่พๅ
ฅไธไธช็จไบ Forgejo ็็ตๅญ้ฎไปถๅฐๅ๏ผๆ่
ไฝฟ็จๅฎๆดๆ ผๅผ๏ผ"ๅ็งฐ"
+smtp_from_helper=Forgejo ไฝฟ็จ็็ตๅญ้ฎไปถๅฐๅใ็ดๆฅ่พๅ
ฅ้ฎไปถๅฐๅๆไฝฟ็จๅฎๆดๆ ผๅผ๏ผ"ๅ็งฐ" ใ
mailer_user=SMTP ็จๆทๅ
mailer_password=SMTP ๅฏ็
register_confirm=้่ฆๅ็ตๅญ้ฎไปถ็กฎ่ฎคๆณจๅ
@@ -278,17 +299,17 @@ offline_mode=ๅฏ็จๆฌๅฐๆจกๅผ
offline_mode.description=็ฆ็จ็ฌฌไธๆน CDN ๅนถๅจๆฌๅฐๆไพๆๆ่ตๆบใ
disable_gravatar=็ฆ็จ Gravatar ๅคดๅ
disable_gravatar.description=็ฆ็จ Gravatar ๅ็ฌฌไธๆนๅคดๅๆบใ้ค้็จๆทๅจๅฎไพไธไผ ๅคดๅ, ๅฆๅๅฐไฝฟ็จ้ป่ฎค็ๅคดๅใ
-federated_avatar_lookup=ๅฏ็จ Federated ๅคดๅ
+federated_avatar_lookup=ๅฏ็จ่้ฆๅคดๅ
federated_avatar_lookup.description=ไฝฟ็จ Libravatar ๆฅๆพๅคดๅใ
disable_registration=็ฆๆญข็จๆท่ชๅฉๆณจๅ
-disable_registration.description=ๅชๆๅฎไพ็ฎก็ๅๆ่ฝๅๅปบๆฐ็็จๆทๅธๆทใๅผบ็ๅปบ่ฎฎไฟๆๆณจๅ็ฆ็จ๏ผ้ค้ๆจๆ็ฎไธบๆๆไบบๆ็ฎกไธไธชๅ
ฌๅ
ฑๅฎไพๅนถๅๅคๅฅฝๅค็ๅคง้ๅๅพๅธๆทใ
+disable_registration.description=ๅชๆๅฎไพ็ฎก็ๅๆ่ฝๅๅปบๆฐ็ๅธๆทใๅผบ็ๅปบ่ฎฎไฟๆๆณจๅ็ฆ็จ๏ผ้ค้ๆจๆ็ฎไธบๆๆไบบๆ็ฎกไธไธชๅ
ฌๅ
ฑๅฎไพๅนถๅๅคๅฅฝๅค็ๅคง้ๅๅพๅธๆทใ
allow_only_external_registration.description=ไป
ๅ
่ฎธไฝฟ็จๅทฒ้
็ฝฎ็ๅค้จๆๅกๆฅๅๅปบๆฐๅธๆทใ
openid_signin=ๅฏ็จ OpenID ็ปๅฝ
openid_signin.description=ๅ
่ฎธ็จๆท้่ฟ OpenID ็ปๅฝใ
openid_signup=ๅฏ็จ OpenID ่ชๅฉๆณจๅ
openid_signup.description=ๅฆๆๅฏ็จไบ่ชๅฉๆณจๅ๏ผๅๅ
่ฎธ็จๆท้่ฟ OpenID ๅๅปบๅธๆทใ
enable_captcha=ๅฏ็จๆณจๅ้ช่ฏ็
-enable_captcha.description=่ฆๆฑ็จๆท้่ฟ CAPTCHA ้ช่ฏๆ่ฝๅๅปบๅธๆทใ
+enable_captcha.description=่ฆๆฑ็จๆท้่ฟ้ช่ฏ็ ๆ่ฝๅๅปบๅธๆทใ
require_sign_in_view=ๅฏ็จ้กต้ข่ฎฟ้ฎ้ๅถ
require_sign_in_view.description=ไป
ๅ
่ฎธๅทฒ็ปๅฝ็จๆท่ฎฟ้ฎ้กต้ขใ่ฎฟๅฎขๅช่ฝ็ๅฐๆณจๅๅ็ปๅฝ้กตใ
admin_setting.description=ๅๅปบ็ฎก็ๅๅธๆทๆฏๅฏ้็ใ็ฌฌไธไธชๆณจๅ็จๆทๅฐ่ชๅจๆไธบ็ฎก็ๅใ
@@ -300,22 +321,22 @@ admin_email=็ตๅญ้ฎไปถๅฐๅ
install_btn_confirm=็ซๅณๅฎ่ฃ
test_git_failed=ๆ ๆณ่ฏๅซ โgitโ ๅฝไปค๏ผ%v
sqlite3_not_available=ๅฝๅ Forgejo ็ๆฌไธๆฏๆ SQLite3ใ่ฏทไป %s ไธ่ฝฝๅฎๆนๆๅปบ็๏ผๆณจ๏ผ่ฏทๅฟไธ่ฝฝๆ ๆ โgobuildโ ็็ๆฌ๏ผใ
-invalid_db_setting=ๆฐๆฎๅบ่ฎพ็ฝฎๆ ๆ: %v
-invalid_db_table=ๆฐๆฎๅบ่กจ '%s' ๆ ๆ๏ผ %v
+invalid_db_setting=ๆฐๆฎๅบ่ฎพ็ฝฎๆ ๆ๏ผ%v
+invalid_db_table=ๆฐๆฎๅบ่กจ '%s' ๆ ๆ๏ผ%v
invalid_repo_path=ไปๅบๆ น็ฎๅฝ่ฎพ็ฝฎๆ ๆ๏ผ%v
-invalid_app_data_path=ๅบ็จๆฐๆฎ่ทฏๅพๆ ๆ๏ผ %v
+invalid_app_data_path=ๅบ็จๆฐๆฎ่ทฏๅพๆ ๆ๏ผ%v
run_user_not_match=่ฟ่ก็จๆทๅไธๆฏๅฝๅ็็จๆทๅ๏ผ%s -> %s
-internal_token_failed=็ๆๅ
้จไปค็ๅคฑ่ดฅ๏ผ %v
-secret_key_failed=็ๆๅฏ้ฅๅคฑ่ดฅ๏ผ %v
+internal_token_failed=็ๆๅ
้จไปค็ๅคฑ่ดฅ๏ผ%v
+secret_key_failed=็ๆๅฏ้ฅๅคฑ่ดฅ๏ผ%v
save_config_failed=ๅบ็จ้
็ฝฎไฟๅญๅคฑ่ดฅ๏ผ%v
-invalid_admin_setting=็ฎก็ๅๅธๆท่ฎพ็ฝฎๆ ๆ: %v
-invalid_log_root_path=ๆฅๅฟ่ทฏๅพๆ ๆ: %v
+invalid_admin_setting=็ฎก็ๅๅธๆท่ฎพ็ฝฎๆ ๆ๏ผ%v
+invalid_log_root_path=ๆฅๅฟ่ทฏๅพๆ ๆ๏ผ%v
default_keep_email_private=้ป่ฎคๆ
ๅตไธ้่็ตๅญ้ฎไปถๅฐๅ
default_keep_email_private.description=้ป่ฎคไธบๆฐ็จๆทๅฏ็จ็ตๅญ้ฎไปถๅฐๅ้่๏ผ้ฒๆญข่ฟไบไฟกๆฏๅจๆณจๅๅ็ซๅณๆณ้ฒใ
default_allow_create_organization=้ป่ฎคๆ
ๅตไธๅ
่ฎธๅๅปบ็ป็ป
default_allow_create_organization.description=้ป่ฎคๅ
่ฎธๆฐ็จๆทๅๅปบ็ป็ปใ็ฆ็จๆญค้้กนๆถ๏ผ็ฎก็ๅๅฟ
้กปๅๆฐ็จๆทๆไบๅๅปบ็ป็ป็ๆ้ใ
default_enable_timetracking=้ป่ฎคๆ
ๅตไธๅฏ็จๆถ้ด่ท่ธช
-default_enable_timetracking.description=้ป่ฎคๅ
่ฎธๆฐๅญๅจๅบไฝฟ็จๆถ้ด่ท่ธชๅ่ฝใ
+default_enable_timetracking.description=้ป่ฎคๅ
่ฎธๆฐไปๅบไฝฟ็จๆถ้ด่ท่ธชๅ่ฝใ
no_reply_address=้่็ตๅญ้ฎไปถ
no_reply_address_helper=็จไบ่ฎพ็ฝฎ้่็ตๅญ้ฎไปถๅฐๅ็็จๆทไฝฟ็จ็็ตๅญ้ฎไปถๅๅใไพๅฆ๏ผๅฆๆ็จไบ้่็ตๅญ้ฎไปถๅฐๅ็ๅๅ่ฎพไธบโnoreply.example.orgโ๏ผๅ็จๆทๅ โjoeโ ๅจ Git ไธญๅฐไปฅ โjoe@noreply.example.orgโ ่กจ็คบใ
password_algorithm=ๅฏ็ ๅๅธ็ฎๆณ
@@ -333,7 +354,7 @@ app_slogan = ๅฎไพๆ ่ฏญ
app_slogan_helper = ๅจๆญคๅค่พๅ
ฅๆจ็ๅฎไพๆ ่ฏญใ็็ฉบๅ็ฆ็จใ
[home]
-uname_holder=็จๆทๅๆ็ตๅญ้ฎ็ฎฑ
+uname_holder=็จๆทๅๆ็ตๅญ้ฎไปถๅฐๅ
password_holder=ๅฏ็
switch_dashboard_context=ๅๆขๆงๅถ้ขๆฟ็จๆท
my_repos=ไปๅบๅ่กจ
@@ -347,12 +368,12 @@ filter=ๅ
ถไป่ฟๆปคๅจ
filter_by_team_repositories=ๆๅข้ไปๅบ็ญ้
feed_of=`"%s"็ๆบ`
-show_archived=ๅทฒๅฝๆกฃ
-show_both_archived_unarchived=ๆพ็คบๅทฒๅฝๆกฃๅๆชๅฝๆกฃ็
-show_only_archived=ๅชๆพ็คบๅทฒๅฝๆกฃ็
-show_only_unarchived=ๅชๆพ็คบๆชๅฝๆกฃ็
+show_archived=ๅทฒๅญๆกฃ
+show_both_archived_unarchived=ๆพ็คบๅทฒๅญๆกฃๅๆชๅญๆกฃ็
+show_only_archived=ๅชๆพ็คบๅทฒๅญๆกฃ็
+show_only_unarchived=ๅชๆพ็คบๆชๅญๆกฃ็
-show_private=็งๆๅบ
+show_private=็งๆ
show_both_private_public=ๅๆถๆพ็คบๅ
ฌๅผ็ๅ็งๆ็
show_only_private=ๅชๆพ็คบ็งๆ็
show_only_public=ๅชๆพ็คบๅ
ฌๅผ็
@@ -378,7 +399,7 @@ org_no_results=ๆชๆพๅฐๅน้
็็ป็ปใ
code_no_results=ๆชๆพๅฐไธๆ็ดขๅญ่ฏๅน้
็ๆบไปฃ็ ใ
code_search_results=โ%sโ ็ๆ็ดข็ปๆๆฏ
code_last_indexed_at=ๆๅ็ดขๅผไบ %s
-relevant_repositories_tooltip=ๆดพ็็ไปๅบ๏ผไปฅๅ็ผบๅฐไธป้ขใๅพๆ ๅๆ่ฟฐ็ไปๅบๅฐ่ขซ้่ใ
+relevant_repositories_tooltip=ๆดพ็็ใ็ผบๅฐไธป้ขใๅพๆ ๅๆ่ฟฐ็ไปๅบๅทฒ่ขซ้่ใ
relevant_repositories=ๅชๆพ็คบ็ธๅ
ณ็ไปๅบ๏ผ ๆพ็คบๆช่ฟๆปค็ปๆ ใ
stars_one = %d ็น่ต
stars_few = %d ็น่ต
@@ -398,15 +419,15 @@ forgot_password_title=ๅฟ่ฎฐๅฏ็
forgot_password=ๅฟ่ฎฐๅฏ็ ๏ผ
sign_up_now=่ฟๆฒกๅธๆท๏ผ้ฉฌไธๆณจๅใ
sign_up_successful=ๅธๆทๅๅปบๆๅใๆฌข่ฟ๏ผ
-confirmation_mail_sent_prompt=ไธๅฐๆฐ็็กฎ่ฎค้ฎไปถๅทฒ็ป่ขซๅ้่ณ %s ๏ผ่ฏทๆฃๆฅๆจ็ๆถไปถ็ฎฑๅนถๅจ %s ๅ
ๅฎๆ็กฎ่ฎคๆณจๅๆไฝใ
+confirmation_mail_sent_prompt=ๆฐ็็กฎ่ฎค้ฎไปถๅทฒๅ้่ณ %s ใ่ฏทๆฃๆฅๆจ็ๆถไปถ็ฎฑๅนถๅจๆฅไธๆฅ็ %s ๅ
็นๅปๆไพ็้พๆฅไปฅๅฎๆๆณจๅ่ฟ็จใๅฆๆ็ตๅญ้ฎไปถไธๆญฃ็กฎ๏ผๆจๅฏไปฅ็ปๅฝๅนถ่ฏทๆฑๅฐๅฆไธๅฐ็กฎ่ฎค้ฎไปถๅ้ๅฐๅ
ถไปๅฐๅใ
must_change_password=ๆดๆฐๆจ็ๅฏ็
allow_password_change=่ฆๆฑ็จๆทๆดๆนๅฏ็ ๏ผๆจ่๏ผ
-reset_password_mail_sent_prompt=็กฎ่ฎค็ตๅญ้ฎไปถๅทฒ่ขซๅ้ๅฐ %s ใ่ฏทๆจๅจ %s ๅ
ๆฃๆฅๆจ็ๆถไปถ็ฎฑ ๏ผๅฎๆๅฏ็ ้็ฝฎ่ฟ็จใ
+reset_password_mail_sent_prompt=็กฎ่ฎค้ฎไปถๅทฒๅ้่ณ %s ใ่ฏทๆฃๆฅๆจ็ๆถไปถ็ฎฑๅนถๅจๆฅไธๆฅ็ %s ๅ
็นๅปๆไพ็้พๆฅไปฅๅฎๆ่ดฆๅทๆขๅค่ฟ็จใ
active_your_account=ๆฟๆดปๆจ็ๅธๆท
account_activated=ๅธๆทๅทฒๆฟๆดป
-prohibit_login=็ฆๆญข็ปๅฝ
-prohibit_login_desc=ๆจ็ๅธๆท่ขซ็ฆๆญข็ปๅฝ๏ผ่ฏทไธ็ฝ็ซ็ฎก็ๅ่็ณปใ
-resent_limit_prompt=ๆจ่ฏทๆฑๅ้ๆฟๆดป้ฎไปถ่ฟไบ้ข็น๏ผ่ฏท็ญๅพ
3 ๅ้ๅๅ่ฏ๏ผ
+prohibit_login=่ดฆๅทๅทฒๆๅ
+prohibit_login_desc=ๆจ็่ดฆๅทๅทฒๆๅไธๅฎไพไบคไบใ่ฏทไธๅฎไพ็ฎก็ๅ่็ณปไปฅ้ๆฐ่ทๅพ่ฎฟ้ฎๆ้ใ
+resent_limit_prompt=ๆจ่ฏทๆฑๅ้ๆฟๆดป้ฎไปถ่ฟไบ้ข็น๏ผ่ฏท็ญๅพ
3 ๅ้ๅๅ่ฏใ
has_unconfirmed_mail=%s ๆจๅฅฝ๏ผ็ณป็ปๆฃๆตๅฐๆจๆไธๅฐๅ้่ณ %s ไฝๆช่ขซ็กฎ่ฎค็้ฎไปถใๅฆๆๆจๆชๆถๅฐๆฟๆดป้ฎไปถ๏ผๆ้่ฆ้ๆฐๅ้๏ผ่ฏทๅๅปไธๆน็ๆ้ฎใ
resend_mail=ๅๅปๆญคๅค้ๆฐๅ้็กฎ่ฎค้ฎไปถ
email_not_associate=ๆจ่พๅ
ฅ็้ฎ็ฎฑๅฐๅๆช่ขซๅ
ณ่ๅฐไปปไฝๅธๅท๏ผ
@@ -416,7 +437,7 @@ invalid_code=ๆญค็กฎ่ฎคๅฏ้ฅๆ ๆๆๅทฒ่ฟๆใ
invalid_code_forgot_password=ไฝ ็็กฎ่ฎค็ ๆ ๆๆ่
ๅทฒ่ฟๆ๏ผ็นๅป ่ฟ้ ๅผๅงๆฐ็ไผ่ฏใ
invalid_password=ๆจ็ๅฏ็ ไธ็จไบๅๅปบ่ดฆๆท็ๅฏ็ ไธๅน้
ใ
reset_password_helper=ๆขๅค่ดฆๆท
-reset_password_wrong_user=ๆจไปฅ %s ็ปๅฝ๏ผไฝๆขๅค่ดฆๅท้พๆฅๆฏ็จไบ %sใ
+reset_password_wrong_user=ๆจไปฅ %s ็ปๅฝ๏ผไฝๆขๅค่ดฆๅท้พๆฅ้็จไบ %s
password_too_short=ๅฏ็ ้ฟๅบฆไธ่ฝๅฐไบ %d ไฝใ
non_local_account=้ๆฌๅฐๅธๆทไธ่ฝ้่ฟ Forgejo ็ web ็้ขๆดๆนๅฏ็ ใ
verify=้ช่ฏ
@@ -433,7 +454,7 @@ oauth_signup_submit=ๅฎๆ่ดฆๅท
oauth_signin_tab=็ปๅฎๅฐ็ฐๆๅธๅท
oauth_signin_title=็ปๅฝไปฅๆๆ็ปๅฎๅธๆท
oauth_signin_submit=็ปๅฎ่ดฆๅท
-oauth.signin.error=ๅค็ๆๆ่ฏทๆฑๆถๅบ้ใ ๅฆๆๆญค้่ฏฏไป็ถๅญโโๅจ๏ผ่ฏท่็ณป็ซ็น็ฎก็ๅใ
+oauth.signin.error=ๅค็ๆๆ่ฏทๆฑๆถๅบ้ใๅฆๆๆญค้่ฏฏไป็ถๅญๅจ๏ผ่ฏท่็ณป็ซ็น็ฎก็ๅใ
oauth.signin.error.access_denied=ๆๆ่ฏทๆฑ่ขซๆ็ปใ
oauth.signin.error.temporarily_unavailable=ๆๆๅคฑ่ดฅ๏ผๅ ไธบ่ฎค่ฏๆๅกๅจๆๆถไธๅฏ็จใ่ฏท็จๅๅ่ฏใ
openid_connect_submit=่ฟๆฅ
@@ -447,20 +468,27 @@ disable_forgot_password_mail_admin=ๅธๆทๆขๅคไป
ๅจ่ฎพ็ฝฎ็ตๅญ้ฎไปถๅๅฏ็จ
email_domain_blacklisted=ๆจไธ่ฝไฝฟ็จๆจ็็ตๅญ้ฎไปถๅฐๅๆณจๅใ
authorize_application=ๅบ็จๆๆ
authorize_redirect_notice=ๅฆๆๆจๆๆๆญคๅบ็จ๏ผๆจๅฐไผ่ขซ้ๅฎๅๅฐ %sใ
-authorize_application_created_by=ๆญคๅบ็จ็ฑ%sๅๅปบใ
+authorize_application_created_by=ๆญคๅบ็จ็ฑ %s ๅๅปบใ
authorize_application_description=ๅฆๆๆจๅ
่ฎธ๏ผๅฎๅฐ่ฝๅค่ฏปๅๅไฟฎๆนๆจ็ๆๆๅธๆทไฟกๆฏ๏ผๅ
ๆฌ็งไบบไปๅบๅ็ป็ปใ
authorize_title=ๆๆ %s ่ฎฟ้ฎๆจ็ๅธๆท๏ผ
authorization_failed=ๆๆๅคฑ่ดฅ
authorization_failed_desc=ๅ ไธบๆฃๆตๅฐๆ ๆ่ฏทๆฑ๏ผๆๆๅคฑ่ดฅใ่ฏทๅฐ่ฏ่็ณปๆจๆๆๅบ็จ็็ฎก็ๅใ
sspi_auth_failed=SSPI ่ฎค่ฏๅคฑ่ดฅ
-password_pwned=ๆญคๅฏ็ ๅบ็ฐๅจ ่ขซ็ๅฏ็ ๅ่กจไธๅนถไธๆพ็ป่ขซๅ
ฌๅผใ ่ฏทไฝฟ็จๅฆไธไธชๅฏ็ ๅ่ฏไธๆฌกใ
+password_pwned=ๆญคๅฏ็ ๅบ็ฐๅจ ่ขซ็ๅฏ็ ๅ่กจไธๅนถไธๆพ็ป่ขซๅ
ฌๅผใ ่ฏทไฝฟ็จๅฆไธไธชๅฏ็ ๅ่ฏไธๆฌกใ
password_pwned_err=ๆ ๆณๅฎๆๅฏน HaveIBeenPwned ็่ฏทๆฑ
last_admin=ๆจไธ่ฝๅ ้คๆๅไธไธช็ฎก็ๅใๅฟ
้กป่ณๅฐไฟ็ไธไธช็ฎก็ๅใ
change_unconfirmed_email = ๅฆๆๆจๅจๆณจๅๆถๆไพไบ้่ฏฏ็้ฎ็ฎฑๅฐๅ๏ผๆจๅฏไปฅๅจไธๆนไฟฎๆน๏ผๆฟๆดป้ฎไปถไผๅ้ๅฐไฟฎๆนๅ็้ฎ็ฎฑๅฐๅใ
change_unconfirmed_email_summary = ไฟฎๆน็จๆฅๆฅๆถๆฟๆดป้ฎไปถ็้ฎ็ฎฑๅฐๅใ
-change_unconfirmed_email_error = ๆ ๆณไฟฎๆน้ฎ็ฎฑๅฐๅ๏ผ %v
+change_unconfirmed_email_error = ๆ ๆณไฟฎๆน้ฎ็ฎฑๅฐๅ๏ผ%v
tab_signin = ็ปๅฝ
tab_signup = ๆณจๅ
+hint_login = ๅทฒ็ปๆ่ดฆๆทไบๅ๏ผ็ซๅณ็ปๅฝ๏ผ
+back_to_sign_in = ่ฟๅ็ปๅฝ
+sign_in_openid = ็ปง็ปญไฝฟ็จ OpenID
+sign_up_button = ็ซๅณๆณจๅใ
+hint_register = ้่ฆ่ดฆๅท๏ผ็ซๅณๆณจๅใ
+unauthorized_credentials = ๅญๆฎไธๆญฃ็กฎๆๅทฒ่ฟๆใ่ฏท้่ฏๆจ็ๅฝไปค๏ผๆๆฅ็ %s ไปฅ่ทๅๆดๅคไฟกๆฏ
+use_onetime_code = ไฝฟ็จไธๆฌกๆงไปฃ็
[mail]
view_it_on=ๅจ %s ไธๆฅ็
@@ -477,7 +505,7 @@ activate_email=่ฏท้ช่ฏๆจ็้ฎ็ฎฑๅฐๅ
activate_email.title=%s๏ผ่ฏท้ช่ฏๆจ็้ฎ็ฎฑ
activate_email.text=่ฏทๅจ %s ๆถ้ดๅ
๏ผ็นๅปไปฅไธ้พๆฅ๏ผไปฅ้ช่ฏไฝ ็็ตๅญ้ฎไปถๅฐๅ๏ผ
-register_notify=ๆฌข่ฟๆฅๅฐ Forgejo
+register_notify=ๆฌข่ฟๆฅๅฐ %s
register_notify.title=%[1]s๏ผๆฌข่ฟๆฅๅฐ %[2]s
register_notify.text_1=่ฟๆฏๆจ็ %s ๆณจๅ็กฎ่ฎค็ตๅญ้ฎไปถ ๏ผ
register_notify.text_2=ๆจ็ฐๅจๅฏไปฅไปฅ็จๆทๅ %s ็ปๅฝ
@@ -489,8 +517,8 @@ reset_password.text=ๅฆๆๆญค่ฏทๆฑๆฏๆจๆฌไบบไฝๅบ็๏ผๅ่ฏทๅจ %s
register_success=ๆณจๅๆๅ
-issue_assigned.pull=@%[1]s ๅทฒๅฐไปๅบ %[3]s ไธญ็ๅๅนถ่ฏทๆฑ %[2]s ๆๆดพ็ปๆจ
-issue_assigned.issue=@%[1]s ๅทฒๅฐไปๅบ %[3]s ไธญ็ๅทฅๅ %[2]s ๆๆดพ็ปๆจ
+issue_assigned.pull=@%[1]s ๅทฒๅฐไปๅบ %[3]s ไธญ็ๅๅนถ่ฏทๆฑ %[2]s ๆๆดพ็ปๆจใ
+issue_assigned.issue=@%[1]s ๅทฒๅฐไปๅบ %[3]s ไธญ็ๅทฅๅ %[2]s ๆๆดพ็ปๆจใ
issue.x_mentioned_you=@%s ๆๅฐไบๆจ๏ผ
issue.action.force_push=%[1]s ๅผบๅถไป %[3]s ๆจ้ %[2]s ่ณ [4]sใ
@@ -502,18 +530,18 @@ issue.action.merge=@%[1]s ๅฐ #%[2]d ๅๅนถๅฐ #%[3]sใ
issue.action.approve=@%[1]s ๆนๅไบๆญคๅๅนถ่ฏทๆฑใ
issue.action.reject=@%[1]s ่ฏทๆฑๆดๆนๆญคๅๅนถ่ฏทๆฑใ
issue.action.review=@%[1]s ่ฏ่ฎบไบ่ฟไธชๅๅนถ่ฏทๆฑใ
-issue.action.review_dismissed=@%[1]s ๆ็ปไบ %[2]s ๅฏนๆญคๅๅนถ่ฏทๆฑ็ไธไธชๅฎกๆ ธใ
-issue.action.ready_for_review=@%[1]s ๆ ่ฎฐๆญคๅๅนถ่ฏทๆฑๅทฒ่ฏๅฎก้่ฟใ
+issue.action.review_dismissed=@%[1]s ๅๆถไบ %[2]s ๅฏนๆญคๅๅนถ่ฏทๆฑ็ไธไธไธช่ฏๅฎกใ
+issue.action.ready_for_review=@%[1]s ๆ ่ฎฐไบๆญคๅๅนถ่ฏทๆฑไธบๅทฒๅๅคๅฅฝๆฅๅ่ฏๅฎกใ
issue.action.new=@%[1]s ๅๅปบไบ #%[2]d.
issue.in_tree_path=ๅจ %s ไธญ๏ผ
release.new.subject=%[2]s ไธญ็ %[1]s ๅๅธไบ
release.new.text=@%[1]s ไบ %[3]s ๅๅธไบ %[2]s
-release.title=ๆ ้ข๏ผ %s
+release.title=ๆ ้ข๏ผ%s
release.note=ๆณจ้๏ผ
release.downloads=ไธ่ฝฝ๏ผ
-release.download.zip=ๆบไปฃ็ (ZIP)
-release.download.targz=ๆบไปฃ็ (TAR.GZ)
+release.download.zip=ๆบไปฃ็ ๏ผZIP๏ผ
+release.download.targz=ๆบไปฃ็ ๏ผTAR.GZ๏ผ
repo.transfer.subject_to=%s ๆณ่ฆๅฐ "%s" ไปๅบ่ฝฌ่ฎฉ็ป %s
repo.transfer.subject_to_you=%s ๆณ่ฆๅฐ "%s" ไปๅบ่ฝฌ่ฎฉ็ปไฝ
@@ -530,6 +558,21 @@ team_invite.text_3=ๆณจๆ๏ผ่ฟๆฏๅ้็ป %[1]s ็้่ฏทใๅฆๆๆจๆชๆพๆถ
admin.new_user.subject = ๆฐ็จๆท %s ๅๅๅฎๆๆณจๅ
admin.new_user.user_info = ็จๆทไฟกๆฏ
admin.new_user.text = ่ฏท ็นๅป่ฟ้ ไปฅๅจ็ฎก็ๅ้ขๆฟไธญ็ฎก็ๆญค็จๆทใ
+removed_security_key.no_2fa = ไธๅ้
็ฝฎๅ
ถไป 2FA ๆนๆณ๏ผ่ฟๆๅณ็ไธๅ้่ฆไฝฟ็จ 2FA ็ปๅฝๆจ็่ดฆๅทใ
+account_security_caution.text_2 = ๅฆๆ่ฟไธๆฏๆจๆฌไบบๆไธบ๏ผๅๆจ็่ดฆๅทๅทฒ็็จใ่ฏท่็ณปๆฌ็ฝ็ซ็ฎก็ๅใ
+totp_enrolled.text_1.no_webauthn = ๆจๅๅไธบๆจ็่ดฆๅทๅฏ็จไบ TOTPใ่ฟๆๅณ็๏ผๅจๅฐๆฅ็ปๅฝๆจ็่ดฆๅทๅฟ
้กปไฝฟ็จ TOTP ไฝไธบ 2FA ๆนๆณใ
+totp_enrolled.subject = ๆจๅทฒๅฐ TOTP ๆฟๆดปไธบ 2FA ๆนๆณ
+totp_enrolled.text_1.has_webauthn = ๆจๅๅไธบๆจ็่ดฆๅทๅฏ็จไบ TOTPใ่ฟๆๅณ็๏ผๅจๅฐๆฅ็ปๅฝๆจ็่ดฆๅท๏ผๆจๅฏไปฅไฝฟ็จ TOTP ไฝไธบ 2FA ๆนๆณๆๆจไฝฟ็จ็ไปปไฝๅฎๅ
จๅฏ้ฅใ
+password_change.text_1 = ๆจ็่ดฆๅทๅฏ็ ๅๅๆดๆนใ
+primary_mail_change.subject = ๆจ็ไธป่ฆ้ฎไปถๅฐๅๅทฒๆดๆน
+primary_mail_change.text_1 = ๆจ่ดฆๅท็ไธป่ฆ้ฎไปถๅฐๅๅๅๆดๆนไธบ %[1]sใ่ฟๆๅณ็ๆญค็ตๅญ้ฎไปถๅฐๅๅฐไธๅๆถๅฐๆจ่ดฆๅท็็ตๅญ้ฎไปถ้็ฅใ
+totp_disabled.subject = TOTP ๅทฒ็ฆ็จ
+totp_disabled.text_1 = ๆจ่ดฆๅทไธ็ๅบไบๆถ้ด็ไธๆฌกๆงๅฏ็ ๏ผTOTP๏ผๅๅ็ฆ็จใ
+password_change.subject = ๆจ็ๅฏ็ ๅทฒๆดๆน
+totp_disabled.no_2fa = ไธๅ้
็ฝฎๅ
ถไป 2FA ๆนๆณ๏ผ่ฟๆๅณ็ไธๅ้่ฆไฝฟ็จ 2FA ็ปๅฝๆจ็่ดฆๅทใ
+removed_security_key.subject = ๅฎๅ
จๅฏ้ฅๅทฒ็งป้ค
+removed_security_key.text_1 = ๅฎๅ
จๅฏ้ฅโ%[1]sโๅๅไปๆจ็่ดฆๅทไธญ็งป้คใ
+account_security_caution.text_1 = ๅฆๆ่ฟๆฏๆจ๏ผ้ฃไนๆจๅฏไปฅๆพๅฟๅฐๅฟฝ็ฅ่ฟๅฐ้ฎไปถใ
[modal]
yes=็กฎ่ฎคๆไฝ
@@ -561,24 +604,24 @@ Content=ๅ
ๅฎน
SSPISeparatorReplacement=ๅ้็ฌฆ
SSPIDefaultLanguage=้ป่ฎค่ฏญ่จ
-require_error=ไธ่ฝไธบ็ฉบใ
-alpha_dash_error=` ๅชๅ
่ฎธๅ
ๅซๅญๆฏๆฐๅญใ็ ดๆๅท๏ผโ-โ๏ผๅไธๅ็บฟ๏ผโ_โ๏ผๅญ็ฌฆใ
+require_error=` ไธ่ฝไธบ็ฉบใ`
+alpha_dash_error=` ๅบๅชๅ
ๅซๅญๆฏๆฐๅญใ็ ดๆๅท๏ผโ-โ๏ผๅไธๅ็บฟ๏ผโ_โ๏ผๅญ็ฌฆใ`
alpha_dash_dot_error=` ๅบ่ฏฅๅชๅ
ๅซๅ่งๅญๆฏใๆฐๅญใ็ ดๆๅท๏ผโ-โ๏ผใไธๅ็บฟ๏ผโ_โ๏ผๅๅ่งๅฅๅท๏ผโ.โ๏ผ ใ`
git_ref_name_error=` ๅฟ
้กปๆฏๆ ผๅผ่ฏๅฅฝ็ git ๅผ็จๅ็งฐใ`
-size_error=้ฟๅบฆๅฟ
้กปไธบ %sใ
-min_size_error=้ฟๅบฆๆๅฐไธบ %s ไธชๅญ็ฌฆใ
-max_size_error=้ฟๅบฆๆๅคงไธบ %s ไธชๅญ็ฌฆใ
-email_error=ไธๆฏไธไธชๆๆ็้ฎ็ฎฑๅฐๅใ
+size_error=`้ฟๅบฆๅฟ
้กปไธบ %sใ`
+min_size_error=`้ฟๅบฆๆๅฐไธบ %s ไธชๅญ็ฌฆใ`
+max_size_error=`้ฟๅบฆๆๅคงไธบ %s ไธชๅญ็ฌฆใ`
+email_error=`ไธๆฏไธไธชๆๆ็้ฎ็ฎฑๅฐๅใ`
url_error=`'%s' ไธๆฏไธไธชๆๆ็ URLใ`
include_error=`ๅฟ
้กปๅ
ๅซๅญๅญ็ฌฆไธฒ "%s"ใ`
glob_pattern_error=`ๅน้
ๆจกๅผๆ ๆ๏ผ%s.`
regex_pattern_error=`ๆญฃๅ่กจ่พพๅผๆ ๆ๏ผ%s.`
username_error=` ๅชๅ
่ฎธๅ
ๅซๅญๆฏๆฐๅญๅญ็ฌฆ๏ผโ0-9โใโa-zโใโA-Zโ๏ผใ็ ดๆๅท๏ผโ-โ๏ผใไธๅ็บฟ๏ผโ_โ๏ผๅ็น๏ผโ.โ๏ผใไธ่ฝไปฅ้ๅญๆฏๆฐๅญๅญ็ฌฆๅผๅคดๆ็ปๅฐพ๏ผๅนถไธไธๅ
่ฎธ่ฟ็ปญ็้ๅญๆฏๆฐๅญๅญ็ฌฆใ`
-invalid_group_team_map_error=`ๆ ๅฐๆ ๆ๏ผ %s`
+invalid_group_team_map_error=`ๆ ๅฐๆ ๆ๏ผ%s`
unknown_error=ๆช็ฅ้่ฏฏ๏ผ
captcha_incorrect=้ช่ฏ็ ไธๆญฃ็กฎใ
password_not_match=ๅฏ็ ไธๅน้
ใ
-lang_select_error=ไปๅ่กจไธญ้ๅบ่ฏญ่จ
+lang_select_error=ไปๅ่กจไธญ้ๆฉไธไธช่ฏญ่จใ
username_been_taken=็จๆทๅๅทฒ่ขซไฝฟ็จใ
username_change_not_local_user=้ๆฌๅฐ็จๆทไธๅ
่ฎธๆดๆน็จๆทๅใ
@@ -602,21 +645,21 @@ password_complexity=ๅฏ็ ๆช่พพๅฐๅคๆ็จๅบฆ่ฆๆฑ:
password_lowercase_one=่ณๅฐไธไธชๅฐๅๅญ็ฌฆ
password_uppercase_one=่ณๅฐไธไธชๅคงๅๅญ็ฌฆ
password_digit_one=่ณๅฐไธไธชๆฐๅญ
-password_special_one=่ณๅฐไธไธช็นๆฎๅญ็ฌฆ(ๆ ็น็ฌฆๅท๏ผๆฌๅท๏ผๅผๅท็ญ)
-enterred_invalid_repo_name=่พๅ
ฅ็ไปๅบๅ็งฐไธๆญฃ็กฎ
+password_special_one=่ณๅฐไธไธช็นๆฎๅญ็ฌฆ๏ผๆ ็น็ฌฆๅท๏ผๆฌๅท๏ผๅผๅท็ญ๏ผ
+enterred_invalid_repo_name=่พๅ
ฅ็ไปๅบๅ็งฐไธๆญฃ็กฎใ
enterred_invalid_org_name=ๆจ่พๅ
ฅ็็ป็ปๅ็งฐไธๆญฃ็กฎใ
enterred_invalid_owner_name=ๆฐ็ๆๆ่
ๅ็งฐๆ ๆใ
-enterred_invalid_password=่พๅ
ฅ็ๅฏ็ ไธๆญฃ็กฎ
-user_not_exist=่ฏฅ็จๆทไธๅญๅจ
-team_not_exist=ๅข้ไธๅญๅจ
+enterred_invalid_password=่พๅ
ฅ็ๅฏ็ ไธๆญฃ็กฎใ
+user_not_exist=่ฏฅ็จๆทไธๅญๅจใ
+team_not_exist=ๅข้ไธๅญๅจใ
last_org_owner=ๆจไธ่ฝไปโๆๆ่
โๅข้ไธญๅ ้คๆๅไธไธช็จๆทใ็ป็ปไธญๅฟ
้กป่ณๅฐๆไธไธชๆๆ่
ใ
cannot_add_org_to_team=็ป็ปไธ่ฝ่ขซๅ ๅ
ฅๅฐๅข้ไธญใ
duplicate_invite_to_team=ๆญค็จๆทๅทฒ่ขซ้่ฏทไธบๅข้ๆๅใ
organization_leave_success=ๆจๅทฒๆๅ็ฆปๅผ็ป็ป %sใ
-invalid_ssh_key=ๆ ๆณ้ช่ฏๆจ็ SSH ๅฏ้ฅ: %s
-invalid_gpg_key=ๆ ๆณ้ช่ฏๆจ็ GPG ๅฏ้ฅ: %s
-invalid_ssh_principal=ๆ ๆ็่งๅ๏ผ %s
+invalid_ssh_key=ๆ ๆณ้ช่ฏๆจ็ SSH ๅฏ้ฅ๏ผ%s
+invalid_gpg_key=ๆ ๆณ้ช่ฏๆจ็ GPG ๅฏ้ฅ๏ผ%s
+invalid_ssh_principal=ๆ ๆ็่งๅ๏ผ%s
must_use_public_key=ๆจๆไพ็ๅฏ้ฅๆฏ็ง้ฅใไธ่ฆๅจไปปไฝๅฐๆนไธไผ ๆจ็็ง้ฅ๏ผ่ฏทๆน็จๆจ็ๅ
ฌ้ฅใ
unable_verify_ssh_key=ๆ ๆณ้ช่ฏ SSH ๅฏ้ฅ๏ผ่ฏทไป็ปๆฃๆฅๆฏๅฆๆ้่ฏฏใ
auth_failed=ๆๆ้ช่ฏๅคฑ่ดฅ๏ผ%v
@@ -629,9 +672,7 @@ org_still_own_packages=่ฏฅ็ป็ปไธไปๆ่ฝฏไปถๅ
๏ผ่ฏทๅ
ๅ ้คๅฎไปฌใ
target_branch_not_exist=็ฎๆ ๅๆฏไธๅญๅจใ
username_error_no_dots = ` ๅช่ฝๅ
ๅซ่ฑๆๅญๆฏไธๆฐๅญ๏ผโ0-9โใโa-zโใโA-Zโ๏ผใๆจชๆ ๏ผโ-โ๏ผ ไธไธๅ็บฟ๏ผโ_โ๏ผใ ๅผๅคดไธ็ปๅฐพ็ๅญ็ฌฆๅช่ฝไฝฟ็จ่ฑๆๅญๆฏๆๆฐๅญ๏ผไธไธ่ฝๅ
ๅซ่ฟ็ปญ็้ๅญๆฏ้ๆฐๅญๅญ็ฌฆใ`
-admin_cannot_delete_self = ๆจๆ ๆณไปฅ็ฎก็ๅ็่บซไปฝๅ ้ค่ชๅทฑใ่ฏทๅ
็งป้คๆจ็็ฎก็ๅๆ้ใ
-
-admin_cannot_delete_self=ๅฝๆจๆฏ็ฎก็ๅๆถ๏ผๆจไธ่ฝๅ ้ค่ชๅทฑใ่ฏทๅ
็งป้คๆจ็็ฎก็ๅๆ้
+admin_cannot_delete_self=ๅฝๆจๆฏ็ฎก็ๅๆถ๏ผๆจไธ่ฝๅ ้ค่ชๅทฑใ่ฏทๅ
็งป้คๆจ็็ฎก็ๅๆ้ใ
unsupported_login_type = ่ฏฅ่ดฆๅทไฝฟ็จ็็ปๅฝๆนๅผไธๆฏๆๅ ้คๆญค่ดฆๆทใ
unset_password = ๅฝๅ็ปๅฝ็จๆทๅฐๆช่ฎพ็ฝฎๅฏ็ ใ
required_prefix = ่พๅ
ฅๅฟ
้กปไปฅโ%sโๅผๅคด
@@ -642,20 +683,22 @@ To = ๅๆฏๅ
AccessToken = ่ฎฟ้ฎไปค็
Description = ๆ่ฟฐ
Pronouns = ไปฃ็งฐ
-Biography = ็ฎๅ
+Biography = ็ฎไป
+username_claiming_cooldown = ็จๆทๅไธ่ฝ่ขซ่ฎค้ข๏ผๅ ไธบๅ
ถไปๅคไบไฟๆคๆใๅ
ถๅฏไปฅๅจ%[1]sๅ่ขซ่ฎค้ขใ
+email_domain_is_not_allowed = ็จๆท็ตๅญ้ฎไปถๅฐๅ็ๅๅ%s ไธEMAIL_DOMAIN_ALLOWLISTๆEMAIL_DOMAIN_BLOCKLISTๅฒ็ชใ่ฏท็กฎไฟๆจๆญฃ็กฎ่ฎพ็ฝฎไบ็ตๅญ้ฎไปถๅฐๅใ
[user]
-change_avatar=ไฟฎๆนๅคดๅ
+change_avatar=ไฟฎๆนๅคดๅโฆ
joined_on=ๅ ๅ
ฅไบ %s
repositories=ไปๅบๅ่กจ
activity=ๅ
ฌๅผๆดปๅจ
-followers_few=%d ๅ
ณๆณจ่
+followers_few=%d ไฝๅ
ณๆณจ่
starred=ๅทฒ็น่ต
watched=ๅทฒๅ
ณๆณจไปๅบ
code=ไปฃ็
projects=้กน็ฎ
overview=ๆฆ่ง
-following_few=%d ๅ
ณๆณจไธญ
+following_few=%d ๅ
ณๆณจ
follow=ๅ
ณๆณจ
unfollow=ๅๆถๅ
ณๆณจ
user_bio=็ฎๅ
@@ -669,15 +712,24 @@ form.name_reserved=็จๆทๅ "%s" ่ขซไฟ็ใ
form.name_pattern_not_allowed=็จๆทๅไธญไธๅ
่ฎธไฝฟ็จ "%s" ๆ ผๅผใ
form.name_chars_not_allowed=็จๆทๅ "%s" ๅ
ๅซๆ ๆๅญ็ฌฆใ
block_user = ๅฑ่ฝ็จๆท
-block_user.detail = ่ฏทๆณจๆ๏ผๅฑ่ฝ่ฏฅ็จๆทไผไบง็ๅ
ถไปๅๆใไพๅฆ๏ผ
-block_user.detail_1 = ๆจๅทฒ่ขซ่ฏฅ็จๆทๅๆถๅ
ณๆณจใ
-block_user.detail_2 = ่ฏฅ็จๆทไธ่ฝๅฏนๆจ็ไปฃ็ ๅบใๆไบค็้ฎ้ขๅ่ฏ่ฎบๅๅบไปปไฝๆไฝใ
+block_user.detail = ่ฏทๆณจๆ๏ผๅฑ่ฝ็จๆท่ฟๆๅ
ถไปๅฝฑๅ๏ผไพๅฆ๏ผ
+block_user.detail_1 = ๅฐไผๅๆญขไบ็ธๅ
ณๆณจๅฏนๆน๏ผไนๆ ๆณๅไบ็ธๅ
ณๆณจๅฏนๆนใ
+block_user.detail_2 = ๆญค็จๆทๅฐๆ ๆณๅฏนๆจ็ไปๅบๆๅๅปบ็้ฎ้ขๅ่ฏ่ฎบๅๅบไปปไฝๆไฝใ
follow_blocked_user = ๆจไธ่ฝๅ
ณๆณจ่ฏฅ็จๆท๏ผๅ ไธบๆจๅทฒๅฑ่ฝ่ฏฅ็จๆทๆ่ฏฅ็จๆทๅทฒๅฑ่ฝๆจใ
block = ๅฑ่ฝ
unblock = ่งฃ้คๅฑ่ฝ
-block_user.detail_3 = ่ฏฅ็จๆทๆ ๆณๅฐๆจๆทปๅ ไธบๅไฝ่
๏ผๆจไนๆ ๆณๅฐๅ
ถๆทปๅ ไธบๅไฝ่
ใ
-followers_one = %d ไบบๅ
ณๆณจ
-following_one = %d ไบบ่ขซ่ฏฅ็จๆทๅ
ณๆณจ
+block_user.detail_3 = ๆจๅฐๆ ๆณๅฐๅฝผๆญคๆทปๅ ไธบไปๅบๅไฝ่
ใ
+followers_one = %d ๅ
ณๆณจ่
+following_one = %d ๅ
ณๆณจ
+public_activity.visibility_hint.self_public = ๆจ็ๆดปๅจๅฏนๆๆไบบ้ฝๆฏๅฏ่ง็๏ผไฝๅจ็งไบบ็ฉบ้ดไธญ็ไบคไบ้คๅคใ้
็ฝฎ ใ
+public_activity.visibility_hint.admin_public = ๆญคๆดปๅจๅฏนๆๆไบบๅฏ่ง๏ผไฝไฝไธบ็ฎก็ๅ๏ผๆจ่ฟๅฏไปฅ็ๅฐ็งไบบ็ฉบ้ดไธญ็ไบคไบใ
+public_activity.visibility_hint.self_private = ๆจ็ๆดปๅจไป
ๅฏนๆจๅๅฎไพ็ฎก็ๅๅฏ่งใ้
็ฝฎ ใ
+public_activity.visibility_hint.admin_private = ๆญคๆดปๅจๅฏนๆจๅฏ่ง๏ผๅ ไธบๆจๆฏ็ฎก็ๅ๏ผไฝ็จๆทๅธๆๅฎไฟๆ็งๆใ
+followers.title.one = ๅ
ณๆณจ่
+followers.title.few = ๅ
ณๆณจ่
+following.title.one = ๅ
ณๆณจ
+following.title.few = ๅ
ณๆณจ
+public_activity.visibility_hint.self_private_profile = ็ฑไบๆจ็ไธชไบบ่ตๆๆฏ็งๆ็๏ผๅ ๆญคๆจ็ๆดปๅจๅชๆๆจๅๅฎไพ็ฎก็ๅๅฏ่งใ้
็ฝฎ ใ
[settings]
profile=ไธชไบบไฟกๆฏ
@@ -692,16 +744,16 @@ applications=ๅบ็จ
orgs=็ป็ป
repos=ไปๅบๅ่กจ
delete=ๅ ้คๅธๆท
-twofa=ไธคๆญฅ้ช่ฏ
+twofa=ไธคๆญฅ้ช่ฏ๏ผTOTP๏ผ
account_link=ๅทฒ็ปๅฎ็ๅธๆท
organization=็ป็ป
uid=UID
-webauthn=ๅฎๅ
จๅฏ้ฅ
+webauthn=ไธคๆญฅ้ช่ฏ๏ผๅฎๅ
จๅฏ้ฅ๏ผ
public_profile=ๅ
ฌๅผไฟกๆฏ
-biography_placeholder=ๅ่ฏๆไปฌไธ็นๆจ่ชๅทฑ๏ผ (ๆจๅฏไปฅไฝฟ็จMarkdown)
+biography_placeholder=ๅไปไบบไป็ปไธไธไฝ ่ชๅทฑ๏ผ๏ผๆฏๆ Markdown๏ผ
location_placeholder=ไธไปไบบๅไบซไฝ ็ๅคงๆฆไฝ็ฝฎ
-profile_desc=ๆงๅถๆจ็ไธชไบบ่ตๆๅฏนๅ
ถไป็จๆท็ๆพ็คบๆนๅผใๆจ็ไธป่ฆ็ตๅญ้ฎไปถๅฐๅๅฐ็จไบ้็ฅใๅฏ็ ๆขๅคๅๅบไบ็ฝ้กต็้ข็ Git ๆไฝใ
+profile_desc=ๅ
ณไบๆจ
password_username_disabled=ไธๅ
่ฎธ้ๆฌๅฐ็จๆทๆดๆนไปไปฌ็็จๆทๅใๆดๅค่ฏฆๆ
่ฏท่็ณปๆจ็็ณป็ป็ฎก็ๅใ
full_name=ๅ
จๅ
website=ไธชไบบ็ฝ็ซ
@@ -711,17 +763,17 @@ update_profile=ๆดๆฐไธชไบบ่ตๆ
update_language=ๆดๆน่ฏญ่จ
update_language_not_found=่ฏญ่จ %s ไธๅฏ็จใ
update_language_success=่ฏญ่จๅทฒๆดๆฐใ
-update_profile_success=ๆจ็่ตๆไฟกๆฏๅทฒ็ปๆดๆฐ
+update_profile_success=ๆจ็ไธชไบบ่ตๆๅทฒ็ปๆดๆฐใ
change_username=ๆจ็็จๆทๅๅทฒๆดๆนใ
change_username_prompt=ๆณจๆ๏ผๆดๆนๆจ็็จๆทๅไนๆดๆนๆจ็ๅธๆท URLใ
-change_username_redirect_prompt=ๅจๅ
ถไป็จๆทไฝฟ็จๆจ็ๆง็จๆทๅๆณจๅๅ๏ผๆญคๆง็จๆทๅๅฐไผ้ๅฎๅๅฐๆจ็ๆฐ็จๆทๅ
+change_username_redirect_prompt=ๅจๅ
ถไป็จๆทไฝฟ็จๆจ็ๆง็จๆทๅๆณจๅๅ๏ผๆญคๆง็จๆทๅๅฐไผ้ๅฎๅๅฐๆจ็ๆฐ็จๆทๅใ
continue=็ปง็ปญๆไฝ
cancel=ๅๆถๆไฝ
language=็้ข่ฏญ่จ
ui=ไธป้ข
-hidden_comment_types=้่็่ฏ่ฎบ็ฑปๅ
-hidden_comment_types_description=ๆญคๅค้ไธญ็ๆณจ้็ฑปๅไธไผๆพ็คบๅจ้ฎ้ข้กต้ขไธญใๆฏๅฆ๏ผๅพ้โๆ ็ญพโๅ ้คๆๆ " ๆทปๅ /ๅ ้ค็ " ๆณจ้ใ
-hidden_comment_types.ref_tooltip=ๆณจ้ๆญค้ฎ้ขๅจไฝๅค่ขซๆๅ่ฟ๏ผๅฆๅฆไธไธช้ฎ้ขใไปฃ็ ๆไบค็ญ
+hidden_comment_types=้่็ๆณจ้็ฑปๅ
+hidden_comment_types_description=ๆญคๅค้ไธญ็ๆณจ้็ฑปๅไธไผๆพ็คบๅจๅทฅๅ้กต้ขไธญใไพๅฆ๏ผๅพ้โๆ ็ญพโๅฐ็งป้คๆๆโ<็จๆท>ๆทปๅ /ๅ ้คไบ<ๆ ็ญพ>โๆณจ้ใ
+hidden_comment_types.ref_tooltip=ๆณจ้ๆญค้ฎ้ขๅจไฝๅค่ขซๆๅ่ฟ๏ผๅฆๅฆไธไธช้ฎ้ขใไปฃ็ ๆไบค็ญโฆ
hidden_comment_types.issue_ref_tooltip=ๆณจ้็จๆทๅจไฝๅคๆดๆนไบไธๆญค้ฎ้ข็ธๅ
ณ่็ๅๆฏ/ๆ ็ญพ
comment_type_group_reference=ๅผ็จ
comment_type_group_label=ๆ ็ญพ
@@ -733,7 +785,7 @@ comment_type_group_time_tracking=ๆถ้ด่ท่ธช
comment_type_group_deadline=ๆชๆญขๆฅๆ
comment_type_group_dependency=ไพ่ต้กน
comment_type_group_lock=้ๅฎ็ถๆ
-comment_type_group_review_request=ๅฎกๆ ธ่ฏทๆฑ
+comment_type_group_review_request=่ฏๅฎก่ฏทๆฑ
comment_type_group_pull_request_push=ๆทปๅ ็ๆไบค
comment_type_group_project=้กน็ฎ
comment_type_group_issue_ref=ๅทฅๅๅผ็จ
@@ -742,14 +794,14 @@ privacy=้็ง่ฎพ็ฝฎ
keep_activity_private=้่ไธชไบบ่ตๆ้กต้ขไธญ็ๆดปๅจ
keep_activity_private_popup=ๆจ็ๆดปๅจๅฐๅชๅฏนๆจ่ชๅทฑๅๆฌๅฎไพ็็ฎก็ๅๅฏ่ง
-lookup_avatar_by_mail=ไฝฟ็จ็ตๅญ้ฎ็ฎฑๅฐๅๆฅๆพๅคดๅ
+lookup_avatar_by_mail=ไฝฟ็จ็ตๅญ้ฎไปถๅฐๅๆฅๆพๅคดๅ
federated_avatar_lookup=ๆฅๆพ่ๅๅคดๅ
-enable_custom_avatar=ๅฏๅจ่ชๅฎไนๅคดๅ
+enable_custom_avatar=ไฝฟ็จ่ชๅฎไนๅคดๅ
choose_new_avatar=้ๆฉๆฐ็ๅคดๅ
update_avatar=ๆดๆฐๅคดๅ
delete_current_avatar=ๅ ้คๅฝๅๅคดๅ
uploaded_avatar_not_a_image=ไธไผ ็ๆไปถไธๆฏไธๅผ ๅพ็ใ
-uploaded_avatar_is_too_big=ไธไผ ็ๆไปถๅคงๅฐ(%d KiB) ่ถ
่ฟๆๅคง้ๅถ(%d KiB)ใ
+uploaded_avatar_is_too_big=ไธไผ ็ๆไปถๅคงๅฐ๏ผ%d KiB๏ผ ่ถ
่ฟๆๅคง้ๅถ๏ผ%d KiB๏ผใ
update_avatar_success=ๆจ็ๅคดๅๅทฒๆดๆฐใ
update_user_avatar_success=็จๆทๅคดๅๅทฒๆดๆฐใ
@@ -757,16 +809,16 @@ update_password=ๆดๆฐๅฏ็
old_password=ๅฝๅๅฏ็
new_password=ๆฐ็ๅฏ็
retype_new_password=็กฎ่ฎคๆฐๅฏ็
-password_incorrect=ๅฝๅๅฏ็ ไธๆญฃ็กฎ๏ผ
-change_password_success=ๆจ็ๅฏ็ ๅทฒๆดๆฐใไป็ฐๅจๅผๅงไฝฟ็จๆจ็ๆฐๅฏ็ ็ปๅฝใ
+password_incorrect=ๅฝๅๅฏ็ ไธๆญฃ็กฎใ
+change_password_success=ๆจ็ๅฏ็ ๅทฒๆดๆฐใไป็ฐๅจๅผๅง่ฏทไฝฟ็จๆจ็ๆฐๅฏ็ ็ปๅฝใ
password_change_disabled=้ๆฌๅฐๅธๆทไธ่ฝ้่ฟ Forgejo ็ web ็้ขๆดๆนๅฏ็ ใ
emails=้ฎ็ฎฑๅฐๅ
manage_emails=็ฎก็้ฎ็ฎฑๅฐๅ
manage_themes=้ป่ฎคไธป้ข
manage_openid=OpenID ๅฐๅ
-email_desc=ๆจ็ไธป่ฆ็ตๅญ้ฎไปถๅฐๅๅฐ็จไบ้็ฅใๅฏ็ ๆขๅค๏ผๅบไบ็ฝ้กต็้ข็Gitๆไฝ(ๅช่ฆๅฎไธๆฏ่ฎพ็ฝฎไธบ้่็)ใ
-theme_desc=่ฟๅฐๆฏๆจๅจๆดไธช็ฝ็ซไธ็้ป่ฎคไธป้ขใ
+email_desc=ๆจ็ไธป่ฆ็ตๅญ้ฎไปถๅฐๅๅฐ็จไบ้็ฅใๅฏ็ ๆขๅค๏ผๅบไบ็ฝ้กต็้ข็Gitๆไฝ๏ผๅช่ฆๅฎไธๆฏ่ฎพ็ฝฎไธบ้่็๏ผใ
+theme_desc=ๆญคไธป้ขๅฐๅจๆจๅทฒ็ปๅฝๆถ่ขซ็จไบ็ฝ้กต็้ขใ
primary=ไธป่ฆ
activated=ๅทฒๆฟๆดป
requires_activation=้่ฆๆฟๆดป
@@ -776,8 +828,8 @@ activations_pending=็ญๅพ
ๆฟๆดป
can_not_add_email_activations_pending=ๆไธไธชๅพ
ๅค็็ๆฟๆดป่ฏทๆฑ๏ผ่ฏท็จ็ญๅ ๅ้ๅๅๅฐ่ฏๆทปๅ ๆฐ็็ตๅญ้ฎไปถๅฐๅใ
delete_email=็งป้ค
email_deletion=็งป้ค็ตๅญ้ฎไปถๅฐๅ
-email_deletion_desc=็ตๅญ้ฎ็ฎฑๅฐๅๅ็ธๅ
ณไฟกๆฏๅฐไผ่ขซๅ ้คใไฝฟ็จๆญค็ตๅญ้ฎ็ฎฑๅฐๅๅ้็Gitๆไบคๅฐไผไฟ็๏ผ็ปง็ปญ๏ผ
-email_deletion_success=ๆจ็็ตๅญ้ฎ็ฎฑๅฐๅๅทฒ่ขซ็งป้คใ
+email_deletion_desc=็ตๅญ้ฎไปถๅฐๅๅ็ธๅ
ณไฟกๆฏๅฐไผ่ขซๅ ้คใไฝฟ็จๆญค็ตๅญ้ฎไปถๅฐๅๅ้็Gitๆไบคๅฐไผไฟ็๏ผ็ปง็ปญ๏ผ
+email_deletion_success=ๆจ็็ตๅญ้ฎไปถๅฐๅๅทฒ่ขซ็งป้คใ
theme_update_success=ๆจ็ไธป้ขๅทฒๆดๆฐใ
theme_update_error=ๆ้ไธป้ขไธๅญๅจใ
openid_deletion=็งป้ค OpenID ๅฐๅ
@@ -787,12 +839,12 @@ add_new_email=ๆทปๅ ้ฎ็ฎฑๅฐๅ
add_new_openid=ๆทปๅ ๆฐ็ OpenID URI
add_email=ๅขๅ ็ตๅญ้ฎไปถๅฐๅ
add_openid=ๆทปๅ OpenID URI
-add_email_confirmation_sent=ไธๅฐ็กฎ่ฎค้ฎไปถๅทฒ็ป่ขซๅ้่ณ %s๏ผ่ฏทๆฃๆฅๆจ็ๆถไปถ็ฎฑๅนถๅจ %s ๅ
ๅฎๆ็กฎ่ฎคๆณจๅๆไฝใ
+add_email_confirmation_sent=็กฎ่ฎค้ฎไปถๅทฒๅ้่ณโ%sโใ่ฏทๆฃๆฅๆจ็ๆถไปถ็ฎฑๅนถๅจๆฅไธๆฅ็ %s ๅ
็นๅปๆไพ็้พๆฅไปฅ็กฎ่ฎคๆจ็็ตๅญ้ฎไปถๅฐๅใ
add_email_success=ๆฐ็็ตๅญ้ฎไปถๅฐๅๅทฒๆทปๅ ใ
email_preference_set_success=็ตๅญ้ฎไปถ้ฆ้้กนๅทฒๆๅ่ฎพ็ฝฎใ
add_openid_success=ๆฐ็ OpenID ๅฐๅๅทฒๆทปๅ ใ
keep_email_private=้่้ฎ็ฎฑๅฐๅ
-keep_email_private_popup=่ฟๅฐไผ้่ๆจ็็ตๅญ้ฎไปถๅฐๅ๏ผไธไป
ๅจๆจ็ไธชไบบ่ตๆไธญ๏ผ่ฟๅจๆจไฝฟ็จWeb็้ขๅๅปบๆๅ่ฏทๆฑๆ็ผ่พๆไปถๆถใๅทฒๆจ้็ๆไบคๅฐไธไผ่ขซไฟฎๆนใ
+keep_email_private_popup=ๆจ็้ฎไปถๅฐๅไธไผๅจไธชไบบ่ตๆไธญๆพ็คบ๏ผไนไธไผๆไธบ้่ฟ็ฝ้กต็้ขๆไบค็้ป่ฎคๅฐๅ๏ผไพๅฆๆไปถไธไผ ใ็ผ่พๅๅๅนถๆไบคใ็ธๅ๏ผๅฏไปฅไฝฟ็จ็นๆฎๅฐๅ %s ๅฐๆไบค้พๆฅๅฐๆจ็่ดฆๅทใๆญค้้กนไธไผๅฝฑๅ็ฐๆๆไบคใ
openid_desc=OpenID ่ฎฉไฝ ๅฏไปฅๅฐ่ฎค่ฏ่ฝฌๅๅฐๅค้จๆๅกใ
manage_ssh_keys=็ฎก็ SSH ๅฏ้ฅ
@@ -803,16 +855,16 @@ ssh_desc=่ฟไบ SSH ๅ
ฌ้ฅๅทฒ็ปๅ
ณ่ๅฐไฝ ็่ดฆๅทใ็ธๅบ็็ง้ฅๆฅๆๅฎ
principal_desc=่ฟไบSSH่ฏไนฆ่งๅๅทฒๅ
ณ่ๅฐไฝ ็่ดฆๅทๅฐๅ
่ฎธๅฎๅ
จ่ฎฟ้ฎไฝ ็ๆๆไปๅบใ
gpg_desc=่ฟไบ GPG ๅ
ฌ้ฅๅทฒ็ปๅ
ณ่ๅฐไฝ ็่ดฆๅท๏ผๅนถ็จไบ้ช่ฏๆจ็ๆไบคใ่ฏทๅฆฅๅไฟ็ฎกไฝ ็็ง้ฅ๏ผๅ ไธบ่ฟไบ็ง้ฅๅฏไปฅ็จไบไปฅไฝ ็่บซไปฝ็ญพๅๆไบคใ
ssh_helper=้่ฆๅธฎๅฉ๏ผ ่ฏทๆฅ็ๆๅ
ณ ๅฆไฝ็ๆ SSH ๅฏ้ฅ ๆ ๅธธ่ง SSH ้ฎ้ข ๅฏปๆพ็ญๆกใ
-gpg_helper=้่ฆๅธฎๅฉๅ๏ผ ็ไธ็ GitHub ๅ
ณไบGPG ็ๆๅฏผใ
+gpg_helper=้่ฆๅธฎๅฉๅ๏ผ ๅปบ่ฎฎ็ไธ็ GitHub ็ ๅ
ณไบGPG ็ๆๅฏผใ
add_new_key=ๅขๅ SSH ๅฏ้ฅ
add_new_gpg_key=ๆทปๅ ็ GPG ๅฏ้ฅ
key_content_ssh_placeholder=ไปฅโssh-ed25519โใโssh-rsaโใโecdsa-sha2-nistp256โใโecdsa-sha2-nistp384โใโecdsa-sha2-nistp521โใโsk-ecdsa-sha2-nistp256@openssh.comโ ๆ โsk-ssh-ed25519@openssh.comโ ๅผๅคด
key_content_gpg_placeholder=ไปฅ โ-----BEGIN PGP PUBLIC KEY BLOCK-----โ ๅผๅคด
add_new_principal=ๆทปๅ ่งๅ
ssh_key_been_used=ๆญค SSH ๅฏ้ฅๅทฒๆทปๅ ๅฐๆๅกๅจใ
-ssh_key_name_used=ไฝฟ็จ็ธๅๅ็งฐ็SSHๅ
ฌ้ฅๅทฒ็ปๅญๅจ๏ผ
+ssh_key_name_used=ไฝฟ็จ็ธๅๅ็งฐ็SSHๅ
ฌ้ฅๅทฒๅญๅจใ
ssh_principal_been_used=ๆญค่งๅๅทฒ็ปๅ ๅ
ฅๅฐไบๆๅกๅจใ
-gpg_key_id_used=ไฝฟ็จ็ธๅๅ็งฐ็GPGๅ
ฌ้ฅๅทฒ็ปๅญๅจ๏ผ
+gpg_key_id_used=ๅ
ทๆ็ธๅ ID ็ GPG ๅ
ฌ้ฅๅทฒๅญๅจใ
gpg_no_key_email_found=ๆญค GPG ๅฏ้ฅไธๆจๅธๆทๅ
ณ่็ไปปไฝๅทฒๆฟๆดป็ตๅญ้ฎไปถๅฐๅๅไธๅน้
ใๅฆๆๆจๅจๆไพ็ไปค็ไธ็ญพๅ๏ผๅฎไป็ถๅฏไปฅ่ขซๆทปๅ ใ
gpg_key_matched_identities=ๅน้
็่บซไปฝ๏ผ
gpg_key_matched_identities_long=ๆญคๅฏ้ฅไธญๅ
ๅซ็่บซไปฝไฟกๆฏไธไธ้ข่ฟไธช่ฏฅ็จๆทๅทฒๆฟๆดป็ตๅญ้ฎไปถๅฐๅๆฏ็ธๅน้
็ใๅ ๆญค๏ผ่ฝไธ่ฟไบ็ตๅญ้ฎไปถๅฐๅ็ธๅน้
็ๆไบคๅฏไปฅ้่ฟๆญคๅฏ้ฅ่ฟ่ก้ช่ฏใ
@@ -852,7 +904,7 @@ ssh_principal_deletion=ๅ ้ค SSH ่ฏไนฆ่งๅ
ssh_key_deletion_desc=ๅ ้ค SSH ๅ
ฌ้ฅๅฐๅๆถๅฏนๅบ็็ง้ฅๅฏนๆจ็ Forgejo ๅธๆท็่ฎฟ้ฎๆ้ใ็ปง็ปญ๏ผ
gpg_key_deletion_desc=ๅ ้ค GPG ๅ
ฌ้ฅๅฐๆ ๆณ่ฎค็ฅไฝฟ็จๅฏนๅบ็ง้ฅ็ญพๅ็ๆไบค๏ผ็ปง็ปญ๏ผ
ssh_principal_deletion_desc=ๅ ้คๆญค SSH ่ฏไนฆ่งๅๅฐๅๆถๅฎๅฏนๆจ็่ดฆๆท็่ฎฟ้ฎๆ้ใ็ปง็ปญ๏ผ
-ssh_key_deletion_success=GPG ๅฏ้ฅๅทฒ่ขซๅ ้คใ
+ssh_key_deletion_success=SSH ๅฏ้ฅๅทฒ่ขซๅ ้คใ
gpg_key_deletion_success=GPG ๅฏ้ฅๅทฒ่ขซๅ ้คใ
ssh_principal_deletion_success=ๆญค่งๅๅ ้คๆๅใ
added_on=ๆทปๅ ไบ %s
@@ -890,12 +942,12 @@ access_token_deletion_desc=ๅ ้คไปค็ๅฐๆค้็จๅบๅฏนๆจ่ดฆๆท็่ฎฟ้ฎๆ
delete_token_success=ไปค็ๅทฒ็ป่ขซๅ ้คใไฝฟ็จ่ฏฅไปค็็ๅบ็จๅฐไธๅ่ฝๅค่ฎฟ้ฎไฝ ็่ดฆๅทใ
repo_and_org_access=ไปๅบๅ็ป็ป่ฎฟ้ฎๆ้
permissions_public_only=ไป
ๅ
ฌๅผ
-permissions_access_all=ๅ
จ้จ(ๅ
ฌๅผใ็งๆๅๅ้)
+permissions_access_all=ๅ
จ้จ๏ผๅ
ฌๅผใ็งๆๅๅ้๏ผ
select_permissions=้ๆฉๆ้
permission_no_access=ๆ ่ฎฟ้ฎๆ้
permission_read=ๅฏ่ฏป
permission_write=่ฏปๅ
-access_token_desc=ๆ้ไปค็ๆ้ไป
้ไบๅฏนๅบ็ API ่ทฏ็ฑ็ๆๆใ้
่ฏป ๆๆกฃ ไปฅ่ทๅๆดๅคไฟกๆฏใ
+access_token_desc=ๆ้ไปค็ๆ้ไป
้ไบๅฏนๅบ็ API ่ทฏ็ฑ็ๆๆใ้
่ฏป ๆๆกฃ ไปฅ่ทๅๆดๅคไฟกๆฏใ
at_least_one_permission=ไฝ ้่ฆ้ๆฉ่ณๅฐไธไธชๆ้ๆ่ฝๅๅปบไปค็
permissions_list=ๆ้๏ผ
@@ -926,7 +978,7 @@ oauth2_application_locked=ๅฆๆ้
็ฝฎๅฏ็จ๏ผForgejo้ขๆณจๅไธไบOAuth2ๅบ
authorized_oauth2_applications=ๅทฒๆๆ็ OAuth2 ๅบ็จ
authorized_oauth2_applications_description=ๆจๅทฒๆไบ่ฟไบ็ฌฌไธๆนๅบ็จ็จๅบ่ฎฟ้ฎๆจ็ไธชไบบ Forgejo ่ดฆๆท็ๆ้ใ่ฏทๆค้้ฃไบๆจไธๅไฝฟ็จ็ๅบ็จ็จๅบ็่ฎฟ้ฎๆ้ใ
revoke_key=ๆค้
-revoke_oauth2_grant=ๆคๅๆ้
+revoke_oauth2_grant=ๆค้่ฎฟ้ฎๆ้
revoke_oauth2_grant_description=็กฎๅฎๆค้ๆญคไธๆนๅบ็จ็จๅบ็ๆๆ๏ผๅนถ้ปๆญขๆญคๅบ็จ็จๅบ่ฎฟ้ฎๆจ็ๆฐๆฎ๏ผ
revoke_oauth2_grant_success=ๆๅๆค้ไบ่ฎฟ้ฎๆ้ใ
@@ -934,7 +986,7 @@ twofa_desc=ไธคๆญฅ้ช่ฏๅฏไปฅๅ ๅผบไฝ ็่ดฆๅทๅฎๅ
จๆงใ
twofa_recovery_tip=ๅฆๆๆจไธขๅคฑไบๆจ็่ฎพๅค๏ผๆจๅฐ่ฝๅคไฝฟ็จไธๆฌกๆงๆขๅคๅฏ้ฅๆฅ้ๆฐ่ทๅพๅฏนๆจ่ดฆๆท็่ฎฟ้ฎใ
twofa_is_enrolled=ไฝ ็่ดฆๅทๅทฒๅฏ็จ ไบไธคๆญฅ้ช่ฏใ
twofa_not_enrolled=ไฝ ็่ดฆๅทๆชๅผๅฏไธคๆญฅ้ช่ฏใ
-twofa_disable=็ฆ็จไธคๆญฅ่ฎค่ฏ
+twofa_disable=็ฆ็จไธคๆญฅ้ช่ฏ
twofa_scratch_token_regenerate=้ๆฐ็ๆไธๆฌกๆงๆขๅคไปค็
twofa_scratch_token_regenerated=ๆจ็ไธดๆถไปค็็ฐๅจๆฏ %sใๅฐๅ
ถๅญๆพๅจๅฎๅ
จ็ๅฐๆน๏ผๅฎๅฐไธไผๅๆฌกๆพ็คบใ
twofa_enroll=ๅฏ็จไธคๆญฅ้ช่ฏ
@@ -949,7 +1001,7 @@ passcode_invalid=ๅฏ็ ไธๆญฃ็กฎใๅ่ฏไธๆฌกใ
twofa_enrolled=ไฝ ็่ดฆๅทๅทฒ็ปๅฏ็จไบไธคๆญฅ้ช่ฏใ่ฏทไฟๅญๅๅงไปค็๏ผ%s๏ผๅฐไธไธชๅฎๅ
จ็ๅฐๆน๏ผๆญคไปค็ไป
ๅฝๅๆพ็คบไธๆฌกใ
twofa_failed_get_secret=่ทๅ secret ๅคฑ่ดฅใ
-webauthn_desc=ๅฎๅ
จๅฏ้ฅๆฏๅ
ๅซๅ ๅฏๅฏ้ฅ็็กฌไปถ่ฎพๅคใๅฎไปฌๅฏไปฅ็จไบๅๅ ็ด ่บซไปฝ้ช่ฏใๅฎๅ
จๅฏ้ฅๅฟ
้กปๆฏๆ WebAuthn ่บซไปฝ้ช่ฏๅจ ๆ ๅใ
+webauthn_desc=ๅฎๅ
จๅฏ้ฅๆฏๅ
ๅซๅ ๅฏๅฏ้ฅ็็กฌไปถ่ฎพๅคใๅฎไปฌๅฏไปฅ็จไบๅๅ ็ด ่บซไปฝ้ช่ฏใๅฎๅ
จๅฏ้ฅๅฟ
้กปๆฏๆ WebAuthn ่บซไปฝ้ช่ฏๅจ ๆ ๅใ
webauthn_register_key=ๆทปๅ ๅฎๅ
จๅฏ้ฅ
webauthn_nickname=ๆต็งฐ
webauthn_delete_key=็งป้คๅฎๅ
จๅฏ้ฅ
@@ -965,7 +1017,7 @@ remove_account_link=ๅ ้คๅทฒ็ปๅฎ็่ดฆๅท
remove_account_link_desc=ๅ ้คๅทฒ็ปๅฎๅธๆทๅฐๅ้ๅ
ถๅฏนๆจ็ Forgejo ๅธๆท็่ฎฟ้ฎๆ้ใ็ปง็ปญ๏ผ
remove_account_link_success=ๅทฒๅๆถ็ปๅฎๅธๆทใ
-hooks.desc=ๆทปๅ Webhooks๏ผๅฎไปฌๅฐไผๅจๆจๆฅๆ็ๆๆไปๅบ ไธ่งฆๅ
+hooks.desc=ๆทปๅ ไผๅจๆจๆฅๆ็ๆๆไปๅบ ไธ่งฆๅ็ Web ้ฉๅญใ
orgs_none=ๆจ็ฐๅจ่ฟไธๆฏไปปไฝ็ป็ป็ๆๅใ
repos_none=ไฝ ๅนถไธๆฅๆไปปไฝไปๅบใ
@@ -980,34 +1032,67 @@ delete_account_desc=็กฎๅฎ่ฆๆฐธไน
ๅ ้คๆญค็จๆทๅธๆทๅ๏ผ
email_notifications.enable=ๅฏ็จ้ฎไปถ้็ฅ
email_notifications.onmention=ๅชๅจ่ขซๆๅฐๆถ้ฎไปถ้็ฅ
email_notifications.disable=ๅ็จ้ฎไปถ้็ฅ
-email_notifications.submit=้ฎไปถ้็ฅ่ฎพ็ฝฎ
+email_notifications.submit=่ฎพ็ฝฎ้ฎไปถๅๅฅฝ
email_notifications.andyourown=ๅๆจ่ชๅทฑ็้็ฅ
visibility=็จๆทๅฏ่งๆง
visibility.public=ๅ
ฌๅผ
visibility.public_tooltip=ๅฏนๆๆไบบๅฏ่ง
visibility.limited=ๅ้
-visibility.limited_tooltip=ไป
ๅฏนๅทฒ่ฎค่ฏ็็จๆทๅฏ่ง
+visibility.limited_tooltip=ไป
ๅฏน็ปๅฝ็จๆทๅฏ่ง
visibility.private=็งๆ
-visibility.private_tooltip=ไป
ๅฏนๆจๅทฒๅ ๅ
ฅ็็ป็ป็ๆๅๅฏ่งใ
+visibility.private_tooltip=ไป
ๅฏนๆจๅทฒๅ ๅ
ฅ็็ป็ป็ๆๅๅฏ่ง
blocked_users = ๅทฒๅฑ่ฝ็็จๆท
blocked_users_none = ้ปๅๅไธญๆฒกๆ็จๆทใ
blocked_since = ่ช %s ่ตท่ขซๅฑ่ฝ
user_unblock_success = ๅทฒๆๅๅๆถๅฏน่ฏฅ็จๆท็ๅฑ่ฝใ
user_block_success = ๅทฒๆๅๅฑ่ฝ่ฏฅ็จๆทใ
change_password = ๆดๆนๅฏ็
-additional_repo_units_hint = ๅปบ่ฎฎไปๅบๅฏ็จๆดๅคๅ่ฝ
+additional_repo_units_hint = ๅปบ่ฎฎๅฏ็จๆดๅคไปๅบๅ่ฝ
hints = ๆ็คบ
update_hints = ๆดๆฐๆ็คบ
-additional_repo_units_hint_description = ๅจๆๆๅญๅจๆชๅฏ็จ็ๅ่ฝ็ไปๅบๅ
ๆพ็คบไธไธชโ้ๆฉๆดๅคๅ่ฝโฆโๆ้ฎใ
+additional_repo_units_hint_description = ๅจๆๆๅญๅจๆชๅฏ็จ็ๅ่ฝ็ไปๅบๅ
ๆพ็คบโๅฏ็จๆดๅคโๆ็คบใ
update_hints_success = ๆ็คบๆดๆนๆๅใ
pronouns_custom = ่ชๅฎไน
pronouns = ไปฃ่ฏ
-pronouns_unspecified = ไธๆๅฎ
+pronouns_unspecified = ๆชๆๅฎ
language.title = ้ป่ฎค่ฏญ่จ
+keep_activity_private.description = ๆจ็ๅ
ฌๅผๆดปๅจ ๅฐไป
ๅฏนๆจๅๅฎไพ็ฎก็ๅๅฏ่งใ
+language.description = ๆญค่ฏญ่จๅฐไฟๅญๅฐๆจ็่ดฆๅทไธญ๏ผๅนถๅจๆจ็ปๅฝๅ็จไฝ้ป่ฎค่ฏญ่จใ
+language.localization_project = ๅธฎๅฉๆไปฌๅฐ Forgejo ็ฟป่ฏๆๆจ็่ฏญ่จ๏ผไบ่งฃๆดๅค ใ
+user_block_yourself = ๆจไธ่ฝๅฑ่ฝ่ชๅทฑใ
+pronouns_custom_label = ่ชๅฎไนไปฃ่ฏ
+change_username_redirect_prompt.with_cooldown.one = ๆง็็จๆทๅๅฐๅจ%[1]dๅคฉ็ไฟๆคๆๅๅฏนๆๆไบบๅฏ็จ๏ผๆจไปๅฏไปฅๅจๆญคๆ้ด้ๆฐ่ฎค้ขๆง็็จๆทๅใ
+change_username_redirect_prompt.with_cooldown.few = ๆง็็จๆทๅๅฐๅจ%[1]dๅคฉ็ไฟๆคๆๅๅฏนๆๆไบบๅฏ็จ๏ผๆจไปๅฏไปฅๅจๆญคๆ้ด้ๆฐ่ฎค้ขๆง็็จๆทๅใ
+keep_pronouns_private = ไป
ๅๅทฒ่ฎค่ฏ็จๆทๆพ็คบไปฃ่ฏ
+keep_pronouns_private.description = ่ฟๅฐๅฏนๆช็ปๅฝ็่ฎฟ้ฎ่
้่ๆจ็ไปฃ่ฏใ
+quota = ้
้ข
+quota.applies_to_org = ไปฅไธ้
้ข่งๅ้็จไบๆญค็ป็ป
+quota.rule.exceeded = ๅทฒ่ถ
ๅบ
+quota.rule.exceeded.helper = ๆญค่งๅ็ๅฏน่ฑกๆปๅคงๅฐ่ถ
ๅบไบ้
้ขใ
+quota.rule.no_limit = ๆ ้ๅถ
+quota.sizes.all = ๅ
จ้จ
+quota.sizes.repos.all = ไปๅบ
+quota.sizes.repos.private = ็งๆไปๅบ
+quota.sizes.git.all = Git ๅ
ๅฎน
+quota.sizes.git.lfs = Git LFS
+quota.sizes.assets.all = ่ตๆบ
+quota.sizes.assets.attachments.all = ้ไปถ
+quota.sizes.assets.attachments.issues = ๅทฅๅ้ไปถ
+quota.sizes.assets.attachments.releases = ็ๆฌๅๅธ้ไปถ
+quota.sizes.assets.artifacts = ๅถๅ
+quota.sizes.assets.packages.all = ่ฝฏไปถๅ
+quota.sizes.wiki = ็พ็ง
+storage_overview = ๅญๅจๆฆ่ง
+quota.applies_to_user = ไปฅไธ้
้ข่งๅ้็จไบๆจ็่ดฆๅท
+quota.sizes.repos.public = ๅ
ฌๅผไปๅบ
+regenerate_token_success = ๅทฒ้ๆฐ็ๆไปค็ใไฝฟ็จๆงไปค็็ๅบ็จ็จๅบไธๅๅฏไปฅ่ฎฟ้ฎๆจ็่ดฆๅท๏ผๅฟ
้กปไฝฟ็จๆฐไปค็ๆดๆฐใ
+regenerate_token = ้ๆฐ็ๆ
+access_token_regeneration = ้ๆฐ็ๆ่ฎฟ้ฎไปค็
+access_token_regeneration_desc = ้ๆฐ็ๆไปค็ๅฐๆค้ไฝฟ็จ่ฏฅไปค็็ๅบ็จ็จๅบๅฏนๆจ็่ดฆๅท็่ฎฟ้ฎๆ้ใๆญคๆไฝๆ ๆณๆค้ใ็ปง็ปญ๏ผ
[repo]
-new_repo_helper=ไปฃ็ ไปๅบๅ
ๅซไบๆๆ็้กน็ฎๆไปถ๏ผๅ
ๆฌ็ๆฌๅๅฒ่ฎฐๅฝใๅทฒ็ปๅจๅ
ถไปๅฐๆนๆ็ฎกไบ๏ผ่ฟ็งปไปๅบใ
+new_repo_helper=ไปฃ็ ไปๅบๅ
ๅซไบๆๆ็้กน็ฎๆไปถ๏ผๅ
ๆฌ็ๆฌๅๅฒ่ฎฐๅฝใๅทฒ็ปๅจๅ
ถไปๅฐๆนๆ็ฎกไบ๏ผ่ฟ็งปไปๅบ ใ
owner=ๆฅๆ่
owner_helper=็ฑไบๆๅคงไปๅบๆฐ้้ๅถ๏ผไธไบ็ป็ปๅฏ่ฝไธไผๆพ็คบๅจไธๆๅ่กจไธญใ
repo_name=ไปๅบๅ็งฐ
@@ -1028,7 +1113,7 @@ fork_from=ๆดพ็่ช
already_forked=ไฝ ๅทฒ็ปๆดพ็่ฟ %s
fork_to_different_account=ๆดพ็ๅฐๅ
ถไป่ดฆๅท
fork_visibility_helper=ๆ ๆณๆดๆนๆดพ็ไปๅบ็ๅฏ่งๆงใ
-fork_branch=่ฆๅ
้ๅฐ Fork ็ๅๆฏ
+fork_branch=่ฆๅคๅถๅฐๆดพ็็ๅๆฏ
all_branches=ๆๆๅๆฏ
fork_no_valid_owners=่ฟไธชไปฃ็ ไปๅบๆ ๆณ่ขซๆดพ็๏ผๅ ไธบๆฒกๆๆๆ็ๆๆ่
ใ
use_template=ไฝฟ็จๆญคๆจกๆฟ
@@ -1039,21 +1124,21 @@ download_bundle=ไธ่ฝฝ BUNDLE
generate_repo=็ๆไปๅบ
generate_from=็ๆ่ช
repo_desc=ไปๅบๆ่ฟฐ
-repo_desc_helper=่พๅ
ฅ็ฎ่ฆๆ่ฟฐ (ๅฏ้)
+repo_desc_helper=่พๅ
ฅ็ฎ่ฆๆ่ฟฐ๏ผๅฏ้๏ผ
repo_lang=ไปๅบ่ฏญ่จ
-repo_gitignore_helper=้ๆฉ .gitignore ๆจกๆฟใ
+repo_gitignore_helper=้ๆฉ .gitignore ๆจกๆฟ
repo_gitignore_helper_desc=ไปๅธธ่ง่ฏญ่จ็ๆจกๆฟๅ่กจไธญ้ๆฉๅฟฝ็ฅ่ท่ธช็ๆไปถใ้ป่ฎคๆ
ๅตไธ๏ผ็ฑๅผๅๆๆๅปบๅทฅๅ
ท็ๆ็็นๆฎๆไปถ้ฝๅ
ๅซๅจ .gitignore ไธญใ
-issue_labels=ๅทฅๅๆ ็ญพ
-issue_labels_helper=้ๆฉไธไธชๅทฅๅๆ ็ญพ้
+issue_labels=ๆ ็ญพ
+issue_labels_helper=้ๆฉๆ ็ญพ้
license=ๆๆ่ฎธๅฏ
-license_helper=้ๆฉๆๆ่ฎธๅฏๆไปถใ
-license_helper_desc=่ฎธๅฏ่ฏ่ฏดๆไบๅ
ถไปไบบๅฏไปฅๅไธๅฏไปฅ็จๆจ็ไปฃ็ ๅไปไนใไธ็กฎๅฎๅชไธไธช้ๅไฝ ็้กน็ฎ๏ผ่ง ้ๆฉไธไธช่ฎธๅฏ่ฏ
-object_format=ๅฏน่ฑกๆ ผๅผ
-object_format_helper=ไปๅบ็ๅฏน่ฑกๆ ผๅผใไนๅๆ ๆณๆดๆนใSHA1 ๆฏๆๅ
ผๅฎน็ใ
+license_helper=้ๆฉๆๆ่ฎธๅฏๆไปถ
+license_helper_desc=่ฎธๅฏ่ฏ่ฏดๆไบๅ
ถไปไบบๅฏไปฅๅไธๅฏไปฅ็จๆจ็ไปฃ็ ๅไปไนใไธ็กฎๅฎๅชไธไธช้ๅไฝ ็้กน็ฎ๏ผ่ฏท่ง ้ๆฉไธไธช่ฎธๅฏ่ฏ ใ
+object_format = ๅฏน่ฑกๆ ผๅผ
+object_format_helper = ไปๅบ็ๅฏน่ฑกๆ ผๅผ๏ผไธๆฆ่ฎพ็ฝฎๆ ๆณๆดๆนใSHA1 ็ๅ
ผๅฎนๆงๆๅผบใ
readme=่ช่ฟฐ
-readme_helper=้ๆฉ่ช่ฟฐๆไปถๆจกๆฟใ
+readme_helper=้ๆฉ่ช่ฟฐๆไปถๆจกๆฟ
readme_helper_desc=่ฟๆฏๆจๅฏไปฅไธบๆจ็้กน็ฎๆฐๅๅฎๆดๆ่ฟฐ็ๅฐๆนใ
-auto_init=ๅๅงๅไปๅบ(ๆทปๅ . gitignoreใ่ฎธๅฏ่ฏๅ่ช่ฟฐๆไปถ)
+auto_init=ๅๅงๅไปๅบ
trust_model_helper=้ๆฉ็ญพๅ้ช่ฏ็โไฟกไปปๆจกๅโใๅฏ่ฝ็้้กนๆฏ:
trust_model_helper_collaborator=ๅไฝ่
๏ผไฟกไปปๅไฝ่
็็ญพๅ
trust_model_helper_committer=ๆไบค่
๏ผไฟกไปปไธๆไบค่
็ธ็ฌฆ็็ญพๅ
@@ -1067,19 +1152,19 @@ mirror_prune=ไฟฎๅช
mirror_prune_desc=ๅ ้ค่ฟๆถ็่ฟ็จ่ท่ธชๅผ็จ
mirror_interval=้ๅ้ด้๏ผๆๆ็ๆถ้ดๅไฝๆฏ โh"ใโmโใโsโ๏ผใๅกซ 0 ็ฆ็จ่ชๅจๅฎๆๅๆญฅใ๏ผๆ็ญ้ด้๏ผ%s๏ผ
mirror_interval_invalid=้ๅ้ด้ๆ ๆใ
-mirror_sync=ๅทฒๅๆญฅ
+mirror_sync = ๅทฒๅๆญฅ
mirror_sync_on_commit=ๆจ้ๆไบคๆถๅๆญฅ
mirror_address=ไป URL ๅ
้
mirror_address_desc=ๅจๆๆๆกไธญ่พๅ
ฅๅฟ
่ฆ็ๅญๆฎใ
mirror_address_url_invalid=URLๆ ๆใ่ฏทๆฃๆฅๆจๆ่พๅ
ฅ็URLๆฏๅฆๆญฃ็กฎใ
-mirror_address_protocol_invalid=ๆไพ็URLๆ ๆใๅช่ฝไฝฟ็จhttp(s)://ๆgit://ๅฐๅ่ฟ่ก้ๅๆไฝใ
-mirror_lfs=ๅคงๆไปถๅญๅจ (LFS)
+mirror_address_protocol_invalid=ๆไพ็URLๆ ๆใๅช่ฝไฝฟ็จhttp๏ผs๏ผ://ๆgit://ๅฐๅ่ฟ่ก้ๅๆไฝใ
+mirror_lfs=ๅคงๆไปถๅญๅจ๏ผLFS๏ผ
mirror_lfs_desc=้ๅ LFS ๆฐๆฎใ
mirror_lfs_endpoint=LFS ็ฝๅ
mirror_lfs_endpoint_desc=ๅๆญฅๅฐๅฐ่ฏไฝฟ็จๅ
้็ฝๅๆฅ ็กฎๅฎ LFS ๆๅกๅจ ใๅฆๆไปๅบ LFS ๆฐๆฎๅญๅจๅจๅ
ถไปไฝ็ฝฎ๏ผไฝ ่ฟๅฏไปฅๆๅฎ่ชๅฎไน็ฝๅใ
mirror_last_synced=ไธๆฌกๅๆญฅ
-mirror_password_placeholder=(ๆชๆดๆน)
-mirror_password_blank_placeholder=(ๆช่ฎพ็ฝฎ)
+mirror_password_placeholder=๏ผๆชๆดๆน๏ผ
+mirror_password_blank_placeholder=๏ผๆช่ฎพ็ฝฎ๏ผ
mirror_password_help=ๆดๆน็จๆทๅไปฅๅ ้คๅทฒๅจๅญ็ๅฏ็ ใ
watchers=ๅ
ณๆณจ่
stargazers=็งฐ่ต่
@@ -1088,12 +1173,12 @@ forks=ๆดพ็ไปๅบ
reactions_more=ๅๅ ่ฝฝ %d
unit_disabled=็ซ็น็ฎก็ๅๅทฒ็ฆ็จๆญคไปๅบๅๅ
ใ
language_other=ๅ
ถๅฎ
-adopt_search=่พๅ
ฅ็จๆทๅไปฅๆ็ดขๆช่ขซๆถๅฝ็ไปๅบ... (็็ฉบไปฅๆฅๆพๅ
จ้จ)
+adopt_search=่พๅ
ฅ็จๆทๅไปฅๆ็ดขๆช่ขซๆถๅฝ็ไปๅบโฆ๏ผ็็ฉบไปฅๆฅๆพๅ
จ้จ๏ผ
adopt_preexisting_label=ๆถๅฝๆไปถ
adopt_preexisting=ๆถๅฝๅทฒๅญๅจ็ไปๅบ
adopt_preexisting_content=ไป %s ๅๅปบไปๅบ
adopt_preexisting_success=ไป %s ๆถๅฝไปๅบๆๅ
-delete_preexisting_label=ๅช้ค
+delete_preexisting_label=ๅ ้ค
delete_preexisting=ๅ ้คๅทฒๅญๅจ็ๆไปถ
delete_preexisting_content=ๅ ้ค %s ไธญ็ๆไปถ
delete_preexisting_success=ๅ ้ค %s ไธญๆชๆถๅฝ็ๆไปถ
@@ -1113,15 +1198,14 @@ transfer.reject_desc=`ๅๆถ่ฝฌ็งปๅฐ "%s"`
transfer.no_permission_to_accept=ๆจๆฒกๆๆ้ๆฅๅๆญค่ฝฌ่ฎฉใ
transfer.no_permission_to_reject=ๆจๆฒกๆๆ้ๆ็ปๆญค่ฝฌ่ฎฉใ
-desc.private=็งๆๅบ
+desc.private=็งๆ
desc.public=ๅ
ฌๅผ
desc.template=ๆจกๆฟ
desc.internal=ๅ
้จ
desc.archived=ๅทฒๅญๆกฃ
-desc.sha256=SHA256
-
+desc.sha256 = SHA256
template.items=ๆจกๆฟ้้กน
-template.git_content=Gitๆฐๆฎ(้ป่ฎคๅๆฏ)
+template.git_content=Gitๆฐๆฎ๏ผ้ป่ฎคๅๆฏ๏ผ
template.git_hooks=Git ้ฉๅญ
template.git_hooks_tooltip=ไฝ ็ฎๅๆ ๆณไฟฎๆนๆๅ ้ค่ขซๆทปๅ ่ฟ็ Git Hookใไป
ๅฝไฝ ไฟกไปปๆจกๆฟไปๅบๆถๆๅฏไปฅ้ๆฉๆญค้กนใ
template.webhooks=Web ้ฉๅญ
@@ -1131,10 +1215,10 @@ template.issue_labels=ๅทฅๅๆ ็ญพ
template.one_item=ๅฟ
้กป่ณๅฐ้ๆฉไธไธชๆจกๆฟ้กน
template.invalid=ๅฟ
้กป้ๆฉไธไธชๆจกๆฟไปๅบ
-archive.title=่ฏฅไปๅบๅทฒ่ขซๅฝๆกฃใๆจๅฏไปฅๆฅ็ๆไปถๅๅ
้ๅฎ๏ผไฝไธ่ฝๆจ้ใๅๅปบๅทฅๅๆๅๅนถ่ฏทๆฑใ
-archive.title_date=่ฏฅไปๅบๅทฒไบ %s ๅฝๆกฃใๆจๅฏไปฅๆฅ็ๆไปถๆๅ
้ๅฎ๏ผไฝไธ่ฝๆจ้ใๅๅปบๅทฅๅๆๅๅนถ่ฏทๆฑใ
-archive.issue.nocomment=ๆญคไปๅบๅทฒๅญๆกฃ๏ผๆจไธ่ฝๅจๆญคๅทฅๅๆทปๅ ่ฏ่ฎบใ
-archive.pull.nocomment=ๆญคไปๅบๅทฒๅญๆกฃ๏ผๆจไธ่ฝๅจๆญคๅๅนถ่ฏทๆฑๆทปๅ ่ฏ่ฎบใ
+archive.title=ๆญคไปๅบๅทฒๅญๆกฃใๆจๅฏไปฅๆฅ็ๆไปถๅๅ
้ไปๅบ๏ผไฝๆ ๆณๅฏนๅ
ถ็ถๆ่ฟ่กไปปไฝๆดๆน๏ผไพๅฆๆจ้ๅๅๅปบๆฐๅทฅๅใๅๅนถ่ฏทๆฑๆ่ฏ่ฎบใ
+archive.title_date=ๆญคไปๅบๅทฒไบ %s ๅญๆกฃใๆจๅฏไปฅๆฅ็ๆไปถๆๅ
้ๅฎ๏ผไฝๆ ๆณๅฏนๅ
ถ็ถๆ่ฟ่กไปปไฝๆดๆน๏ผไพๅฆๆจ้ๅๅๅปบๆฐๅทฅๅใๅๅนถ่ฏทๆฑๆ่ฏ่ฎบใ
+archive.issue.nocomment=ๆญคไปๅบๅทฒๅญๆกฃ๏ผๆจไธ่ฝๅจๅทฅๅๆทปๅ ่ฏ่ฎบใ
+archive.pull.nocomment=ๆญคไปๅบๅทฒๅญๆกฃ๏ผๆจไธ่ฝๅจๅๅนถ่ฏทๆฑๆทปๅ ่ฏ่ฎบใ
form.reach_limit_of_creation_1=ไฝ ๅทฒ็ป่พพๅฐไบ %d ไปๅบ็ไธ้ใ
form.reach_limit_of_creation_n=ไฝ ๅทฒ็ป่พพๅฐไบ %d ไธชไปๅบ็ไธ้ใ
@@ -1160,7 +1244,7 @@ migrate_items_merge_requests=ๅๅนถ่ฏทๆฑ
migrate_items_releases=็ๆฌๅๅธ
migrate_repo=่ฟ็งปไปๅบ
migrate.clone_address=ไป URL ่ฟ็งป/ๅ
้
-migrate.clone_address_desc=็ฐๆไปๅบ็ HTTP(s) ๆ Git โcloneโ URL
+migrate.clone_address_desc=็ฐๆไปๅบ็ HTTP๏ผs๏ผ ๆ Git โcloneโ URL
migrate.github_token_desc=็ฑไบ GitHub API ้็้ๅถ๏ผๆจๅฏไปฅๅจๆญคๅคๆพ็ฝฎไธไธชๆๅคไธชไปฅ้ๅทๅ้็ไปค็๏ผไปฅๅ ๅฟซ่ฟ็งป้ๅบฆใ ่ญฆๅ๏ผๆปฅ็จๆญคๅ่ฝๅฏ่ฝไผ่ฟๅๆๅกๆไพๅ็ๆฟ็ญๅนถๅฏผ่ดๅธๆท่ขซๅฐใ
migrate.clone_local_path=ๆๆๅกๅจๆฌๅฐ่ทฏๅพ
migrate.permission_denied=ๆจๆฒกๆ่ทๅพๅฏผๅ
ฅๆฌๅฐไปๅบ็ๆ้ใ
@@ -1172,18 +1256,18 @@ migrate.migrate_items_options=้่ฆ่ฎฟ้ฎไปค็ๆฅ่ฟ็งป้ขๅค็ๅ
ๅฎน
migrated_from=ไป %[2]s ่ฟ็งป
migrated_from_fake=ไป %[1]s ่ฟ็งปๆๅ
migrate.migrate=ไป %s ่ฟ็งป
-migrate.migrating=ๆญฃๅจไป %s ่ฟ็งป...
+migrate.migrating=ๆญฃๅจไป %s ่ฟ็งปโฆ
migrate.migrating_failed=ไป %s ่ฟ็งปๅคฑ่ดฅใ
migrate.migrating_failed.error=่ฟ็งปๅคฑ่ดฅ๏ผ%s
migrate.migrating_failed_no_addr=่ฟ็งปๅคฑ่ดฅใ
-migrate.github.description=ไป github.com ๆๅ
ถไป GitHub ๅฎไพ่ฟ็งปๆฐๆฎ
+migrate.github.description=ไป github.com ๆ GitHub Enterprise ๆๅกๅจ่ฟ็งปๆฐๆฎใ
migrate.git.description=ไปไปปๆ Git ๆๅก่ฟ็งปไปๅบใ
-migrate.gitlab.description=ไป gitlab.com ๆๅ
ถไป GitLab ๅฎไพ่ฟ็งปๆฐๆฎ
-migrate.gitea.description=ไป gitea.com ๆๅ
ถไป Gitea/Forgejo ๅฎไพ่ฟ็งปๆฐๆฎ
+migrate.gitlab.description=ไป gitlab.com ๆๅ
ถไป GitLab ๅฎไพ่ฟ็งปๆฐๆฎใ
+migrate.gitea.description=ไป gitea.com ๆๅ
ถไป Gitea ๅฎไพ่ฟ็งปๆฐๆฎใ
migrate.gogs.description=ไป notabug.org ๆๅ
ถไป Gogs ๅฎไพ่ฟ็งปๆฐๆฎใ
-migrate.onedev.description=ไป code.onedev.io ๆๅ
ถไป OneDev ๅฎไพ่ฟ็งปๆฐๆฎ
-migrate.codebase.description=ไป codebasehq.com ่ฟ็งปๆฐๆฎ
-migrate.gitbucket.description=ไป GitBucket ๅฎไพ่ฟ็งปๆฐๆฎ
+migrate.onedev.description=ไป code.onedev.io ๆๅ
ถไป OneDev ๅฎไพ่ฟ็งปๆฐๆฎใ
+migrate.codebase.description=ไป codebasehq.com ่ฟ็งปๆฐๆฎใ
+migrate.gitbucket.description=ไป GitBucket ๅฎไพ่ฟ็งปๆฐๆฎใ
migrate.migrating_git=่ฟ็งปGitๆฐๆฎ
migrate.migrating_topics=ๆญฃๅจ่ฟ็งปไธป้ข
migrate.migrating_milestones=ๆญฃๅจ่ฟ็งป้็จ็ข
@@ -1197,10 +1281,10 @@ migrate.cancel_migrating_confirm=ๆจๆณ่ฆๅๆถๆญคๆฌก่ฟ็งปๅ๏ผ
mirror_from=้ๅ่ชๅฐๅ
forked_from=ๆดพ็่ช
generated_from=็ๆ่ช
-fork_from_self=ๆ ๆณๆดพ็ๅทฒ็ปๆฅๆ็ไปๅบ๏ผ
-fork_guest_user=็ปๅฝๅนถ ๆดพ็ ่ฟไธชไปๅบใ
-watch_guest_user=่ฏท็ปๅฝๅๅๅ
ณๆณจๆญคไปๅบ
-star_guest_user=่ฏท็ปๅฝๅๅ็น่ตๆญคไปๅบ
+fork_from_self=ๆ ๆณๆดพ็ๆจๆฅๆ็ไปๅบใ
+fork_guest_user=่ฏทๅ
็ปๅฝๅๆดพ็ๆญคไปๅบใ
+watch_guest_user=่ฏท็ปๅฝๅๅๅ
ณๆณจๆญคไปๅบใ
+star_guest_user=่ฏท็ปๅฝๅๅ็น่ตๆญคไปๅบใ
unwatch=ๅๆถๅ
ณๆณจ
watch=ๅ
ณๆณจ
unstar=ๅๆถ็น่ต
@@ -1267,24 +1351,25 @@ view_git_blame=ๆฅ็ Git Blame
video_not_supported_in_browser=ๆจ็ๆต่งๅจไธๆฏๆ HTML5 โvideoโ ๆ ็ญพใ
audio_not_supported_in_browser=ๆจ็ๆต่งๅจไธๆฏๆ HTML5 โaudioโ ๆ ็ญพใ
stored_lfs=ๅญๅจๅฐGit LFS
+stored_annex=ๅญๅจๅฐGit Annex
symbolic_link=็ฌฆๅท้พๆฅ
executable_file=ๅฏๆง่กๆไปถ
-vendored=่ขซไพๅบ็
-generated=ๅทฒ็ๆ็
+vendored = Vendored
+generated = ๅทฒ็ๆ
commit_graph=ๆไบคๅพ
commit_graph.select=้ๆฉๅๆฏ
commit_graph.hide_pr_refs=้่ๅๅนถ่ฏทๆฑ
commit_graph.monochrome=้ป็ฝ
commit_graph.color=ๅฝฉ่ฒ
-commit.contained_in=่ฟไธชๆไบคๅ
ๅซๅจ๏ผ
+commit.contained_in=่ฟไธชๆไบคๅญๅจไบ๏ผ
commit.contained_in_default_branch=ๆญคๆไบคๆฏ้ป่ฎคๅๆฏ็ไธ้จๅ
commit.load_referencing_branches_and_tags=ๅ ่ฝฝๅผ็จ่ฏฅๆไบค็ๅๆฏๅๆ ็ญพ
-blame=Blame
+blame=่ดฃไปปๅฝๅฑ
download_file=ไธ่ฝฝๆไปถ
normal_view=ๆฎ้่งๅพ
line=่ก
lines=่ก
-from_comment=(่ฏ่ฎบ)
+from_comment=๏ผ่ฏ่ฎบ๏ผ
editor.add_file=ๆทปๅ ๆไปถ
editor.new_file=ๆฐๅปบๆไปถ
@@ -1292,21 +1377,22 @@ editor.upload_file=ไธไผ ๆไปถ
editor.edit_file=็ผ่พๆไปถ
editor.preview_changes=้ข่งๅๆด
editor.cannot_edit_lfs_files=ๆ ๆณๅจ web ็้ขไธญ็ผ่พ lfs ๆไปถใ
+editor.cannot_edit_annex_files=ๆ ๆณๅจ web ็้ขไธญ็ผ่พ lfs ๆไปถใ
editor.cannot_edit_non_text_files=็ฝ้กตไธ่ฝ็ผ่พไบ่ฟๅถๆไปถใ
editor.edit_this_file=็ผ่พๆไปถ
editor.this_file_locked=ๆไปถๅทฒ้ๅฎ
editor.must_be_on_a_branch=ๆจๅฟ
้กปๅจๆไธชๅๆฏไธๆ่ฝๅฏนๆญคๆไปถ่ฟ่กไฟฎๆนๆไฝใ
-editor.fork_before_edit=ๆจๅฟ
้กปๅจๆดพ็่ฟไธชไปๅบๆ่ฝๅฏนๆญคๆไปถ่ฟ่กไฟฎๆนๆไฝ
+editor.fork_before_edit=ๆจๅฟ
้กปๅ
ๆดพ็่ฟไธชไปๅบๆ่ฝๅฏนๆญคๆไปถ่ฟ่กไฟฎๆนๆไฝใ
editor.delete_this_file=ๅ ้คๆไปถ
editor.must_have_write_access=ๆจๅฟ
้กปๅ
ทๆๅๆ้ๆ่ฝๅฏนๆญคๆไปถ่ฟ่กไฟฎๆนๆไฝใ
editor.file_delete_success=ๆไปถ %s ๅทฒ่ขซๅ ้คใ
-editor.name_your_file=ๅฝๅๆไปถ...
+editor.name_your_file=ๅฝๅๆไปถโฆ
editor.filename_help=้่ฟ้ฎๅ
ฅๅ็งฐๅ่ทๅ่งๆๆ ๏ผโ/โ๏ผๆฅๆทปๅ ็ฎๅฝใๅจ่พๅ
ฅๆก็ๅผๅคด้ๆ ผๆฅๅ ้ค็ฎๅฝใ
editor.or=ๆ
editor.cancel_lower=ๅๆถ
editor.commit_signed_changes=ๆไบคๅทฒ็ญพๅ็ๆดๆน
editor.commit_changes=ๆไบคๅๆด
-editor.add_tmpl=ๆทปๅ โโ
+editor.add_tmpl=ๆทปๅ โ<%s>โ
editor.add=ๆทปๅ %s
editor.update=ๆดๆฐ %s
editor.delete=ๅ ้ค %s
@@ -1314,17 +1400,17 @@ editor.patch=ๅบ็จ่กฅไธ
editor.patching=ๆ่กฅไธ๏ผ
editor.fail_to_apply_patch=ๆ ๆณๅบ็จ่กฅไธ %s
editor.new_patch=ๆฐ่กฅไธ
-editor.commit_message_desc=ๆทปๅ ไธไธชๅฏ้็ๆฉๅฑๆ่ฟฐ...
+editor.commit_message_desc=ๆทปๅ ไธไธชๅฏ้็ๆฉๅฑๆ่ฟฐโฆ
editor.signoff_desc=ๅจๆไบคๆฅๅฟๆถๆฏๆซๅฐพๆทปๅ ็ญพ็ฝฒไบบไฟกๆฏใ
-editor.commit_directly_to_this_branch=็ดๆฅๆไบค่ณ %s ๅๆฏใ
+editor.commit_directly_to_this_branch=็ดๆฅๆไบค่ณ %[1]s ๅๆฏใ
editor.create_new_branch=ไธบๆญคๆไบคๅๅปบไธไธช ๆฐ็ๅๆฏ ๅนถๅ่ตทๅๅนถ่ฏทๆฑใ
editor.create_new_branch_np=ไธบๆญคๆไบคๅๅปบ ๆฐๅๆฏ ใ
editor.propose_file_change=ๆ่ฎฎๆไปถๆดๆน
editor.new_branch_name=ไธบ่ฟๆฌกๆไบค็ๆฐๅๆฏๅฝๅ
-editor.new_branch_name_desc=ๆฐ็ๅๆฏๅ็งฐ...
+editor.new_branch_name_desc=ๆฐ็ๅๆฏๅ็งฐโฆ
editor.cancel=ๅๆถ
editor.filename_cannot_be_empty=ๆไปถๅไธ่ฝไธบ็ฉบใ
-editor.filename_is_invalid=ๆไปถๅ %s ๆ ๆ
+editor.filename_is_invalid=ๆไปถๅ %s ๆ ๆใ
editor.branch_does_not_exist=ๆญคไปๅบไธญไธๅญๅจๅไธบ %s ็ๅๆฏใ
editor.branch_already_exists=ๆญคไปๅบๅทฒๅญๅจๅไธบ %s ็ๅๆฏใ
editor.directory_is_a_file=%s ๅทฒ็ปไฝไธบๆไปถๅๅจๆญคไปๅบไธญๅญๅจใ
@@ -1332,7 +1418,7 @@ editor.file_is_a_symlink=`"%s" ๆฏไธไธช็ฌฆๅท้พๆฅ๏ผๆ ๆณๅจ web ็ผ่พๅจ
editor.filename_is_a_directory=ๆญคไปๅบไธญๅทฒๅญๅจๅไธบโ%sโ ็็ฎๅฝใ
editor.file_editing_no_longer_exists=ๆญฃๅจ็ผ่พ็ๆไปถ %s ๅทฒไธๅญๅจใ
editor.file_deleting_no_longer_exists=ๆญฃๅจๅ ้ค็ๆไปถ %s ๅทฒไธๅญๅจใ
-editor.file_changed_while_editing=ๆไปถๅ
ๅฎนๅจๆจ่ฟ่ก็ผ่พๆถ่ขซๆดๆนใๅๅปๆญคๅค ๆฅ็ๅ
ทไฝ่ขซๆดๆน็ๅ
ๅฎน๏ผๆ่
ๅๆฌกๆไบค ่ฆ็ๅ
ถๅฎๅจ็ผ่พๆถไบง็็ๆดๆนใ
+editor.file_changed_while_editing=ๆไปถๅ
ๅฎนๅจๆจๆๅผๆไปถๅ่ขซๆดๆนใๅๅปๆญคๅค ๆฅ็ๅ
ทไฝ่ขซๆดๆน็ๅ
ๅฎน๏ผๆ่
ๅๆฌกๆไบค ่ฆ็ๅ
ถๅฎๅจ็ผ่พๆถไบง็็ๆดๆนใ
editor.file_already_exists=ๆญคไปๅบๅทฒ็ปๅญๅจๅไธบ %s ็ๆไปถใ
editor.commit_empty_file_header=ๆไบคไธไธช็ฉบๆไปถ
editor.commit_empty_file_text=ๆจ่ฆๆไบค็ๆไปถๆฏ็ฉบ็๏ผ็ปง็ปญๅ๏ผ
@@ -1342,7 +1428,7 @@ editor.fail_to_update_file_summary=้่ฏฏไฟกๆฏ๏ผ
editor.push_rejected_no_message=ๆญคไฟฎๆน่ขซๆๅกๅจๆ็ปๅนถไธๆฒกๆๅ้ฆๆถๆฏใ่ฏทๆฃๆฅ Git Hookใ
editor.push_rejected=ๆญคไฟฎๆน่ขซๆๅกๅจๆ็ปใ่ฏทๆฃๆฅ Git Hookใ
editor.push_rejected_summary=่ฏฆ็ปๆ็ปไฟกๆฏ๏ผ
-editor.add_subdir=ๆทปๅ ็ฎๅฝ
+editor.add_subdir=ๆทปๅ ็ฎๅฝโฆ
editor.unable_to_upload_files=ไธไผ ๆไปถ่ณ %s ๆถๅ็้่ฏฏ๏ผ%v
editor.upload_file_is_locked=ๆไปถ %s ่ขซ %s ้ๅฎใ
editor.upload_files_to_dir=ไธไผ ๆไปถ่ณ %s
@@ -1353,12 +1439,12 @@ editor.require_signed_commit=ๅๆฏ้่ฆ็ญพๅๆไบค
editor.cherry_pick=Cherry-pick %s ๅฐ๏ผ
editor.revert=ๅฐ %s ่ฟๅๅฐ๏ผ
-commits.desc=ๆต่งไปฃ็ ไฟฎๆนๅๅฒ
+commits.desc=ๆต่งไปฃ็ ไฟฎๆนๅๅฒใ
commits.commits=ๆฌกไปฃ็ ๆไบค
commits.no_commits=ๆฒกๆๅ
ฑๅ็ๆไบคใ%s ๅ %s ็ๅๅฒๅฎๅ
จไธๅใ
commits.nothing_to_compare=่ฟไบๅๆฏๆฏ็ธๅ็ใ
commits.search=ๆ็ดขๆไบคๅๅฒ
-commits.search.tooltip=`ๆจๅฏไปฅๅจๅ
ณ้ฎ่ฏๅๅ ไธๅ็ผ๏ผๅฆ"author:", "committer:", "after:", ๆ"before:", ไพๅฆ "retrin author:Alice before:2019-01-13"`
+commits.search.tooltip=ๆจๅฏไปฅๅจๅ
ณ้ฎ่ฏๅๅ ไธๅ็ผ๏ผๅฆ"author:", "committer:", "after:", ๆ"before:", ไพๅฆ "retrin author:Alice before:2019-01-13"ใ
commits.find=ๆ็ดข
commits.search_all=ๆๆๅๆฏ
commits.author=ไฝ่
@@ -1366,7 +1452,7 @@ commits.message=ๅคๆณจ
commits.date=ๆไบคๆฅๆ
commits.older=ๆดๆง็ๆไบค
commits.newer=ๆดๆฐ็ๆไบค
-commits.signed_by=็ญพ็ฝฒไบบ:
+commits.signed_by=็ญพ็ฝฒไบบ
commits.signed_by_untrusted_user=็ฑๆชๆไฟก็็จๆท็ญพๅ
commits.signed_by_untrusted_user_unmatched=็ฑไธๆไบค่
ไธๅน้
็ๆชๆไฟก็็จๆท็ญพๅ
commits.gpg_key_id=GPG ๅฏ้ฅ ID
@@ -1375,10 +1461,10 @@ commits.view_path=ๅจๅๅฒ่ฎฐๅฝไธญ็ๆญคๅคๆฅ็
commit.operations=ๆไฝ
commit.revert=่ฟๅ
-commit.revert-header=่ฟๅ๏ผ %s
+commit.revert-header=่ฟๅ๏ผ%s
commit.revert-content=้ๆฉ่ฆ่ฟๅ็ๅๆฏ๏ผ
-commit.cherry-pick=Cherry-pick
-commit.cherry-pick-header=Cherry-pick: %s
+commit.cherry-pick=ๆฃ้
+commit.cherry-pick-header=Cherry-pick๏ผ%s
commit.cherry-pick-content=้ๆฉ cherry-pick ็็ฎๆ ๅๆฏ๏ผ
commitstatus.error=้่ฏฏ
@@ -1386,12 +1472,12 @@ commitstatus.failure=ๅคฑ่ดฅ
commitstatus.pending=ๅพ
ๅฎ
commitstatus.success=ๆๅ
-ext_issues=่ฎฟ้ฎๅค้จๅทฅๅ
+ext_issues=ๅค้จๅทฅๅ
ext_issues.desc=้พๆฅๅฐๅค้จๅทฅๅ่ท่ธช็ณป็ปใ
projects=้กน็ฎ
projects.desc=ๅจ้กน็ฎ็ๆฟไธญ็ฎก็ๅทฅๅๅๅๅนถ่ฏทๆฑใ
-projects.description=ๆ่ฟฐ(ๅฏ้)
+projects.description=ๆ่ฟฐ๏ผๅฏ้๏ผ
projects.description_placeholder=ๆ่ฟฐ
projects.create=ๅๅปบ้กน็ฎ
projects.title=ๆ ้ข
@@ -1423,7 +1509,7 @@ projects.column.unset_default_desc=ๅๆถๆญคๅไธบ้ป่ฎคๅผ
projects.column.delete=ๅ ้คๅ
projects.column.deletion_desc=ๅ ้ค้กน็ฎๅไผๅฐๆๆ็ธๅ
ณๅทฅๅ็งปๅฐ้ป่ฎค็ๅใๆฏๅฆ็ปง็ปญ๏ผ
projects.column.color=้ข่ฒ
-projects.open=ๅผๅฏ
+projects.open=ๅผๆพไธญ
projects.close=ๅ
ณ้ญ
projects.column.assigned_to=ๆๆดพ็ป
projects.card_type.desc=ๅก็้ข่ง
@@ -1435,27 +1521,27 @@ issues.filter_assignees=็ญ้ๆๆดพไบบ
issues.filter_milestones=็ญ้้็จ็ข
issues.filter_projects=็ญ้้กน็ฎ
issues.filter_labels=็ญ้ๆ ็ญพ
-issues.filter_reviewers=็ญ้ๅฎกๆ ธ่
+issues.filter_reviewers=็ญ้่ฏๅฎกๅ
issues.new=ๅๅปบๅทฅๅ
issues.new.title_empty=ๆ ้ขไธ่ฝไธบ็ฉบ
issues.new.labels=ๆ ็ญพ
issues.new.no_label=ๆช้ๆฉๆ ็ญพ
-issues.new.clear_labels=ๆธ
้ค้ไธญๆ ็ญพ
+issues.new.clear_labels=ๆธ
้ค้ไธญ็ๆ ็ญพ
issues.new.projects=้กน็ฎ
-issues.new.clear_projects=ๆธ
้ค้กน็ฎ
+issues.new.clear_projects=ๆธ
้ค้ไธญ็้กน็ฎ
issues.new.no_projects=ๆๆ ้กน็ฎ
-issues.new.open_projects=ๅผๅฏไธญ็้กน็ฎ
+issues.new.open_projects=ๅผๆพไธญ็้กน็ฎ
issues.new.closed_projects=ๅทฒๅ
ณ้ญ็้กน็ฎ
issues.new.no_items=ๆ ๅฏ้้กน
issues.new.milestone=้็จ็ข
issues.new.no_milestone=ๆช้ๆฉ้็จ็ข
-issues.new.clear_milestone=ๅๆถ้ไธญ้็จ็ข
-issues.new.open_milestone=ๅผๅฏไธญ็้็จ็ข
+issues.new.clear_milestone=ๆธ
้ค้ไธญ็้็จ็ข
+issues.new.open_milestone=ๅผๆพไธญ็้็จ็ข
issues.new.closed_milestone=ๅทฒๅ
ณ้ญ็้็จ็ข
issues.new.assignees=ๆๆดพๆๅ
issues.new.clear_assignees=ๅๆถๆๆดพๆๅ
issues.new.no_assignees=ๆชๆๆดพๆๅ
-issues.new.no_reviewers=ๆ ๅฎกๆ ธ่
+issues.new.no_reviewers=ๆ ่ฏๅฎกๅ
issues.choose.get_started=ๅผๅง
issues.choose.open_external_link=ๅผๅฏ
issues.choose.blank=้ป่ฎคๆจกๆฟ
@@ -1486,7 +1572,7 @@ issues.change_project_at=ไฟฎๆน้กน็ฎไป %s ๅฐ %s %s
issues.remove_milestone_at=`%[2]s ๅ ้คไบ้็จ็ข %[1]s `
issues.remove_project_at=`ไป %s ้กน็ฎ %s ไธญๅ ้ค`
issues.deleted_milestone=๏ผๅทฒๅ ้ค๏ผ
-issues.deleted_project=`(ๅทฒๅ ้ค)`
+issues.deleted_project=`๏ผๅทฒๅ ้ค๏ผ`
issues.self_assign_at=`ไบ %s ๆๆดพ็ป่ชๅทฑ`
issues.add_assignee_at=`ไบ %[2]s ่ขซ %[1]s ๆๆดพ`
issues.remove_assignee_at=`%s ๅๆถไบๆๆดพๅจ %s`
@@ -1534,7 +1620,7 @@ issues.filter_sort.feweststars=็น่ต็ฑๅฐๅฐๅค
issues.filter_sort.mostforks=ๆดพ็็ฑๅคๅฐๅฐ
issues.filter_sort.fewestforks=ๆดพ็็ฑๅฐๅฐๅค
issues.keyword_search_unavailable=ๅ
ณ้ฎ่ฏๆ็ดข็ฎๅไธๅฏ็จใ่ฏท่็ณป็ฝ็ซ็ฎก็ๅใ
-issues.action_open=ๅผๅฏ
+issues.action_open=ๅผๆพ
issues.action_close=ๅ
ณ้ญ
issues.action_label=ๆ ็ญพ
issues.action_milestone=้็จ็ข
@@ -1551,7 +1637,7 @@ issues.opened_by_fake=็ฑ %[2]s ไบ %[1]s ๆๅผ
issues.closed_by_fake=็ฑ %[2]s ๅๅปบ๏ผ่ขซๅ
ณ้ญไบ %[1]s
issues.previous=ไธไธ้กต
issues.next=ไธไธ้กต
-issues.open_title=ๅผๅฏไธญ
+issues.open_title=ๅผๆพไธญ
issues.closed_title=ๅทฒๅ
ณ้ญ
issues.draft_title=่็จฟ
issues.num_comments_1=%d ่ฏ่ฎบ
@@ -1559,24 +1645,24 @@ issues.num_comments=%d ๆก่ฏ่ฎบ
issues.commented_at=`่ฏ่ฎบไบ %s `
issues.delete_comment_confirm=ๆจ็กฎๅฎ่ฆๅ ้ค่ฏฅๆก่ฏ่ฎบๅ๏ผ
issues.context.copy_link=ๅคๅถ้พๆฅ
-issues.context.quote_reply=ๅผ็จๅๅค
+issues.context.quote_reply=ๅๅค
issues.context.reference_issue=ๅจๆฐๅทฅๅไธญๅผ็จ
issues.context.edit=็ผ่พ
-issues.context.delete=ๅช้ค
+issues.context.delete=ๅ ้ค
issues.no_content=ๆฒกๆๆไพ่ฏดๆใ
-issues.close=ๅ
ณ้ญๅทฅๅ
+issues.close=ๅ
ณ้ญ
issues.comment_pull_merged_at=ๅทฒๅๅนถๆไบค %[1]s ๅฐ %[2]s %[3]s
issues.comment_manually_pull_merged_at=ๆๅจๅๅนถๆไบค %[1]s ๅฐ %[2]s %[3]s
issues.close_comment_issue=่ฏ่ฎบๅนถๅ
ณ้ญ
-issues.reopen_issue=้ๆฐๅผๅฏ
-issues.reopen_comment_issue=่ฏ่ฎบๅนถ้ๆฐๅผๅฏ
+issues.reopen_issue=้ๆฐๅผๆพ
+issues.reopen_comment_issue=้ๆฐๆๅผ่ฏ่ฎบ
issues.create_comment=่ฏ่ฎบ
-issues.closed_at=`ไบ %[2]s ๅ
ณ้ญๆญคๅทฅๅ`
+issues.closed_at=`ไบ%[2]s ๅ
ณ้ญๆญคๅทฅๅ`
issues.reopened_at=`้ๆฐๆๅผๆญค้ฎ้ข %[2]s `
-issues.commit_ref_at=`ไบ %[2]s ๅจไปฃ็ ๆไบคไธญๅผ็จไบ่ฏฅๅทฅๅ`
-issues.ref_issue_from=`ไบ %[2]s ๅผ็จไบๅทฅๅ %[4]s `
-issues.ref_pull_from=`ไบ %[2]s ๅผ็จไบๅๅนถ่ฏทๆฑ %[4]s `
-issues.ref_closing_from=`ไบ %[2]s ๅผ็จไบๅๅนถ่ฏทๆฑ %[4]s ๅฐๅ
ณ้ญๆญคๅทฅๅ `
+issues.commit_ref_at=`ไบ%[2]s ๅจไปฃ็ ๆไบคไธญๅผ็จไบ่ฏฅๅทฅๅ`
+issues.ref_issue_from=`ๅผ็จไบๅทฅๅ %[4]s %[2]s `
+issues.ref_pull_from=`ๅผ็จไบๅๅนถ่ฏทๆฑ %[4]s %[2]s `
+issues.ref_closing_from=`ไบ %[2]s ไปๅๅนถ่ฏทๆฑ %[4]sๅผ็จไบๆญคๅทฅๅ๏ผๅฐๅ
ณ้ญๆญคๅทฅๅ `
issues.ref_reopening_from=`ไบ %[2]s ๅผ็จไบๅๅนถ่ฏทๆฑ %[4]s ๅฐ้ๆฐ่ฎจ่ฎบๆญคๅทฅๅ `
issues.ref_closed_from=`ๅ
ณ้ญไบ่ฟไธชๅทฅๅ %[4]s %[2]s `
issues.ref_reopened_from=`้ๆฐๆๅผ่ฟไธชๅทฅๅ %[4]s %[2]s `
@@ -1585,7 +1671,7 @@ issues.author=ไฝ่
issues.author_helper=ๆญค็จๆทๆฏไฝ่
ใ
issues.role.owner=็ฎก็ๅ
issues.role.owner_helper=่ฏฅ็จๆทๆฏ่ฏฅไปๅบ็ๆๆ่
ใ
-issues.role.member=ๆฎ้ๆๅ
+issues.role.member=ๆๅ
issues.role.member_helper=่ฏฅ็จๆทๆฏๆฅๆ่ฏฅไปๅบ็็ป็ปๆๅใ
issues.role.collaborator=ๅไฝ่
issues.role.collaborator_helper=่ฏฅ็จๆทๅทฒ่ขซ้่ฏทๅจไปๅบไธ่ฟ่กๅไฝใ
@@ -1593,10 +1679,10 @@ issues.role.first_time_contributor=้ฆๆฌก่ดก็ฎ่
issues.role.first_time_contributor_helper=่ฟๆฏ่ฏฅ็จๆทๅฏนไปๅบ็็ฌฌไธๆฌก่ดก็ฎใ
issues.role.contributor=่ดก็ฎ่
issues.role.contributor_helper=่ฏฅ็จๆทไนๅๅทฒๆไบค่ณ่ฏฅไปๅบใ
-issues.re_request_review=ๅๆฌก่ฏทๆฑๅฎกๆ ธ
+issues.re_request_review=ๅๆฌก่ฏทๆฑ่ฏๅฎก
issues.is_stale=ๆญค่ฏๅฎกไนๅไปฃ็ ๆๆดๆฐ
-issues.remove_request_review=็งป้คๅฎกๆ ธ่ฏทๆฑ
-issues.remove_request_review_block=ๆ ๆณ็งป้คๅฎกๆ ธ่ฏทๆฑ
+issues.remove_request_review=็งป้ค่ฏๅฎก่ฏทๆฑ
+issues.remove_request_review_block=ๆ ๆณ็งป้ค่ฏๅฎก่ฏทๆฑ
issues.dismiss_review=ๅๆถ่ฏๅฎก
issues.dismiss_review_warning=ๆจ็กฎๅฎ่ฆๅๆถๆญค่ฏๅฎกๅ๏ผ
issues.sign_in_require_desc=็ปๅฝ ๅนถๅไธๅฐๅฏน่ฏไธญใ
@@ -1607,13 +1693,13 @@ issues.label_title=ๆ ็ญพๅ็งฐ
issues.label_description=ๆ ็ญพๆ่ฟฐ
issues.label_color=ๆ ็ญพ้ข่ฒ
issues.label_exclusive=็ฌๆ
-issues.label_archive=ๅฝๆกฃๆ ็ญพ
+issues.label_archive=ๅญๆกฃๆ ็ญพ
issues.label_archived_filter=ๆพ็คบๅญๆกฃๆ ็ญพ
issues.label_archive_tooltip=ๅจๆ ็ญพๆ็ดขๆถ๏ผ้ป่ฎคๆ
ๅตไธๅญๆกฃๆ ็ญพๅฐ่ขซๆ้คๅจๅคใ
issues.label_exclusive_desc=ๅฝๅๆ ็ญพไธบ scope/item
ไปฅไฝฟๅ
ถไธๅ
ถไปไปฅ scope/
ๅผๅคด็ๆ ็ญพไบๆฅใ
issues.label_exclusive_warning=ๅจ็ผ่พๅทฅๅๆๅๅนถ่ฏทๆฑ็ๆ ็ญพๆถ๏ผไปปไฝๅฒ็ช็่ๅดๆ ็ญพ้ฝๅฐ่ขซๅ ้คใ
issues.label_count=%d ไธชๆ ็ญพ
-issues.label_open_issues=%d ไธชๅผๅฏ็ๅทฅๅ
+issues.label_open_issues=%d ไธชๅผๆพไธญ็ๅทฅๅ
issues.label_edit=็ผ่พ
issues.label_delete=ๅ ้ค
issues.label_modify=็ผ่พๆ ็ญพ
@@ -1642,7 +1728,7 @@ issues.lock_with_reason=ไบ %[2]s ไปฅ %[1]s ้ๅฎๆฌๅทฅๅ๏ผ
issues.lock_no_reason=ไบ %s ้ๅฎๆฌ่ฎฎ้ขๅนถ้ๅถไป
ๅไฝ่
ๅฏๅ่จ
issues.unlock_comment=ไบ %s ่งฃ้ๆญค่ฎฎ้ข
issues.lock_confirm=้ๅฎ
-issues.unlock_confirm=่งฃ้โโโโ
+issues.unlock_confirm=่งฃ้
issues.lock.notice_1=- ๅ
ถไป็จๆทไธ่ฝ่ฏ่ฎบๆญคๅทฅๅใ
issues.lock.notice_2=- ๆจๅไปๅบๅ
ถไปๅไฝ่
ไปๅฏ่ฏ่ฎบๅนถๅฏ่งใ
issues.lock.notice_3=- ๆจๅฏไปฅๅจๆชๆฅๅๆฌก่งฃ้่ฟไธชๅทฅๅใ
@@ -1654,7 +1740,7 @@ issues.unlock.title=่งฃ้ๆๅ
ณๆญค้ฎ้ข็ๅฏน่ฏใ
issues.comment_on_locked=ๆจไธ่ฝๅฏน้ๅฎ็้ฎ้ขๅ่กจ่ฏ่ฎบใ
issues.delete=ๅ ้ค
issues.delete.title=ๆฏๅฆๅ ้คๅทฅๅ?
-issues.delete.text=ๆจ็็่ฆๅ ้ค่ฟไธชๅทฅๅๅ๏ผ(่ฏฅๆไฝๅฐไผๆฐธไน
ๅ ้คๆๆๅ
ๅฎนใๅฆๆๆจ้่ฆไฟ็๏ผ่ฏทๅ
ณ้ญๅฎ)
+issues.delete.text=ๆจ็็่ฆๅ ้ค่ฟไธชๅทฅๅๅ๏ผ๏ผ่ฏฅๆไฝๅฐไผๆฐธไน
ๅ ้คๆๆๅ
ๅฎนใๅฆๆๆจ้่ฆไฟ็๏ผ่ฏทๅ
ณ้ญๅฎ๏ผ
issues.tracker=ๆถ้ด่ท่ธช
issues.start_tracking_short=ๅฏๅจ่ฎกๆถๅจ
issues.start_tracking=ๅผๅงๆถ้ด่ท่ธช
@@ -1682,7 +1768,7 @@ issues.error_modifying_due_date=ไฟฎๆนๅฐๆๆถ้ดๅคฑ่ดฅใ
issues.error_removing_due_date=ๅ ้คๅฐๆๆถ้ดๅคฑ่ดฅใ
issues.push_commit_1=ไบ %[2]s ๆจ้ไบ %[1]d ไธชๆไบค
issues.push_commits_n=ไบ %[2]s ๆจ้ไบ %[1]d ไธชๆไบค
-issues.force_push_codes=`ไบ %[6]s ๅผบๅถๆจ้ %[1]s๏ผไป %[2]s
๏ผ่ณ %[4]s
`
+issues.force_push_codes=`ไบ %[6]s ๅผบๅถๆจ้ %[1]s๏ผไป %[2]s
๏ผ่ณ %[4]s
`
issues.force_push_compare=ๆฏ่พ
issues.due_date_form=yyyy-mm-dd
issues.due_date_form_add=่ฎพ็ฝฎๅฐๆๆถ้ด
@@ -1696,12 +1782,12 @@ issues.due_date_remove=ไบ %[2]s ๅ ้คไบๅฐๆๆถ้ด %[1]s
issues.due_date_overdue=่ถ
ๆ
issues.due_date_invalid=ๅฐๆๆฅๆๆ ๆๆ่ถ
ๅบ่ๅดใ่ฏทไฝฟ็จโyyyy-mm-ddโๆ ผๅผใ
issues.dependency.title=ไพ่ตๅทฅๅ
-issues.dependency.issue_no_dependencies=ๆฒกๆ่ฎพ็ฝฎไพ่ต้กนใ
+issues.dependency.issue_no_dependencies=ๆช่ฎพ็ฝฎไพ่ต้กนใ
issues.dependency.pr_no_dependencies=ๆฒกๆ่ฎพ็ฝฎไพ่ต้กนใ
issues.dependency.no_permission_1=ๆจๆฒกๆ่ฏปๅ %d ไพ่ตๅ
ณ็ณป็ๆ้
issues.dependency.no_permission_n=ๆจๆฒกๆ่ฏปๅ %d ไพ่ตๅ
ณ็ณป็ๆ้
issues.dependency.no_permission.can_remove=ๆจๆฒกๆ่ฏปๅๆญคไพ่ตๅ
ณ็ณป็ๆ้๏ผไฝๅฏไปฅๅ ้คๆญคไพ่ตๅ
ณ็ณป
-issues.dependency.add=ๆทปๅ ไพ่ตๅทฅๅ...
+issues.dependency.add=ๆทปๅ ไพ่ตๅทฅๅโฆ
issues.dependency.cancel=ๅๆถ
issues.dependency.remove=ๅ ้ค
issues.dependency.remove_info=ๅ ้คๆญคไพ่ต้กน
@@ -1734,16 +1820,16 @@ issues.review.dismissed=ไบ %[2]s ๅๆถไบ %[1]s ็่ฏๅฎก
issues.review.dismissed_label=ๅทฒๅๆถ
issues.review.left_comment=็ไธไบไธๆก่ฏ่ฎบ
issues.review.content.empty=ๆจ้่ฆ็ไธไธไธชๆณจ้๏ผ่กจๆ้่ฆ็ๆดๆนใ
-issues.review.reject=ไบ %s ่ฏทๆฑๅๆด
-issues.review.wait=ไบ %s ่ฏทๆฑๅฎกๆ ธ
+issues.review.reject=ไบ %s ่ฏทๆฑๆดๆน
+issues.review.wait=ไบ %s ่ฏทๆฑ่ฏๅฎก
issues.review.add_review_request=ไบ %[2]s ่ฏทๆฑ %[1]s ่ฏๅฎก
issues.review.remove_review_request=ไบ %[2]s ๅๆถๅฏน %[1]s ็่ฏๅฎก่ฏทๆฑ
-issues.review.remove_review_request_self=ไบ %s ๆ็ปๅฎกๆ ธ
+issues.review.remove_review_request_self=ไบ %s ๆ็ป่ฏๅฎก
issues.review.pending=ๅพ
ๅฎ
issues.review.pending.tooltip=ๆญค่ฏ่ฎบ็ฎๅๅฏนๅ
ถไป็จๆทไธๅฏ่งใ ่ฅ่ฆๆไบคๆจ็ๅพ
ๅฎ่ฏ่ฎบ๏ผ่ฏทๅจ้กต้ข้กถ้จ้ๆฉ %s -> %s/%s/%sใ
issues.review.review=่ฏๅฎก
issues.review.reviewers=่ฏๅฎกไบบ
-issues.review.outdated=ๅทฒ่ฟๆ
+issues.review.outdated=ๅทฒ่ฟๆถ
issues.review.outdated_description=่ฏ่ฎบๅๅธๅๅ
ๅฎนๅทฒ็ปไฟฎๆน
issues.review.option.show_outdated_comments=ๆพ็คบ่ฟๆถ็่ฏ่ฎบ
issues.review.option.hide_outdated_comments=้่่ฟๆถ็่ฏ่ฎบ
@@ -1751,8 +1837,8 @@ issues.review.show_outdated=ๆพ็คบ่ฟๆถ็
issues.review.hide_outdated=้่่ฟๆถ็
issues.review.show_resolved=ๆพ็คบๅทฒ่งฃๅณ็
issues.review.hide_resolved=้่ๅทฒ่งฃๅณ็
-issues.review.resolve_conversation=ๅทฒ่งฃๅณ้ฎ้ข
-issues.review.un_resolve_conversation=ๆช่งฃๅณ้ฎ้ข
+issues.review.resolve_conversation=ๅทฒ่งฃๅณ
+issues.review.un_resolve_conversation=ๆช่งฃๅณ
issues.review.resolved_by=ๆ ่ฎฐ้ฎ้ขไธบๅทฒ่งฃๅณ
issues.assignee.error=ๅ ไธบๆช็ฅๅๅ ๏ผๅนถ้ๆๆ็ๆๆดพ้ฝๆๅใ
issues.reference_issue.body=ๅ
ๅฎน
@@ -1762,9 +1848,9 @@ issues.content_history.created=ๅๅปบไบ
issues.content_history.delete_from_history=ไปๅๅฒ่ฎฐๅฝไธญๅ ้ค
issues.content_history.delete_from_history_confirm=ไปๅๅฒ่ฎฐๅฝไธญๅ ้คๅ๏ผ
issues.content_history.options=้้กน
-issues.reference_link=ๅ่๏ผ%s
+issues.reference_link=ๅผ็จ๏ผ%s
-compare.compare_base=ๅบๅๅๆฏ
+compare.compare_base=ๅบๅ
compare.compare_head=ๆฏ่พ
pulls.desc=ๅฏ็จๅๅนถ่ฏทๆฑๅไปฃ็ ่ฏๅฎกใ
@@ -1776,8 +1862,8 @@ pulls.allow_edits_from_maintainers_desc=ๅฏนๅบ็กๅๆฏๆๅๅ
ฅๆ้็็จๆท
pulls.allow_edits_from_maintainers_err=ๆดๆฐๅคฑ่ดฅ
pulls.compare_changes_desc=้ๆฉๅๅนถ็็ฎๆ ๅๆฏๅๆบๅๆฏใ
pulls.has_viewed_file=ๅทฒๆฅ็
-pulls.has_changed_since_last_review=่ชๆจไธๆฌกๅฎกๆ ธไปฅๆฅๅทฒๆดๆน
-pulls.viewed_files_label=%[1]d / %[2]d ๆไปถๅทฒๆฅ็
+pulls.has_changed_since_last_review=่ชๆจไธๆฌก่ฏๅฎกไปฅๆฅๅทฒๆๆดๆน
+pulls.viewed_files_label=ๅทฒๆฅ็ %[1]d / %[2]d ไธชๆไปถ
pulls.expand_files=ๅฑๅผๆๆๆไปถ
pulls.collapse_files=ๆๅ ๆๆๆไปถ
pulls.compare_base=ๅๅนถๅฐ
@@ -1785,23 +1871,23 @@ pulls.compare_compare=ๆๅไป
pulls.switch_comparison_type=ๅๆขๆฏ่พ็ฑปๅ
pulls.switch_head_and_base=ๅๆข head ๅ base
pulls.filter_branch=่ฟๆปคๅๆฏ
-pulls.no_results=ๆชๆพๅฐ็ปๆ
+pulls.no_results=ๆชๆพๅฐ็ปๆใ
pulls.show_all_commits=ๆพ็คบๆๆๆไบค
-pulls.show_changes_since_your_last_review=ๆพ็คบ่ชๆจไธๆฌกๅฎกๆ ธไปฅๆฅ็ๆดๆน
+pulls.show_changes_since_your_last_review=ๆพ็คบ่ชๆจไธๆฌก่ฏๅฎกไปฅๆฅ็ๆดๆน
pulls.showing_only_single_commit=ไป
ๆพ็คบๆไบค %[1]s ็ๆดๆน
pulls.showing_specified_commit_range=ไป
ๆพ็คบ %[1]s...%[2]s ไน้ด็ๆดๆน
pulls.select_commit_hold_shift_for_range=้ๆฉๆไบคใๆไฝ Shift + ๅๅป้ๆฉไธไธช่ๅด
-pulls.review_only_possible_for_full_diff=ๅชๆๅจๆฅ็ๅ
จ้จๅทฎๅผๆถๆ่ฝ่ฟ่กๅฎกๆ ธ
+pulls.review_only_possible_for_full_diff=ๅชๆๅจๆฅ็ๅ
จ้จๅทฎๅผๆถๆ่ฝ่ฟ่ก่ฏๅฎก
pulls.filter_changes_by_commit=ๆๆไบค็ญ้
pulls.nothing_to_compare=ๅๆฏๅ
ๅฎน็ธๅ๏ผๆ ้ๅๅปบๅๅนถ่ฏทๆฑใ
-pulls.nothing_to_compare_have_tag=ๆ้ๅๆฏ/ๆ ็ญพ็ธๅใ
+pulls.nothing_to_compare_have_tag = ๆ้ๅๆฏ/ๆ ็ญพ็ธๅใ
pulls.nothing_to_compare_and_allow_empty_pr=่ฟไบๅๆฏๆฏ็ธ็ญ็๏ผๆญคๅๅนถ่ฏทๆฑๅฐไธบ็ฉบใ
-pulls.has_pull_request=่ฟไบๅๆฏไน้ด็ๅๅนถ่ฏทๆฑๅทฒๅญๅจ: %[2]s#%[3]d
+pulls.has_pull_request=่ฟไบๅๆฏไน้ด็ๅๅนถ่ฏทๆฑๅทฒๅญๅจ๏ผ%[2]s#%[3]d
pulls.create=ๅๅปบๅๅนถ่ฏทๆฑ
-pulls.title_desc_few=่ฏทๆฑๅฐ %[1]d ๆฌกไปฃ็ ๆไบคไป %[2]s
ๅๅนถ่ณ %[3]s
+pulls.title_desc_few=่ฏทๆฑๅฐ %[1]d ๆฌกไปฃ็ ๆไบคไป %[2]s
ๅๅนถ่ณ %[3]s
pulls.merged_title_desc_few=ไบ %[4]s ๅฐ %[1]d ๆฌกไปฃ็ ๆไบคไป %[2]s
ๅๅนถ่ณ %[3]s
pulls.change_target_branch_at=ๅฐ็ฎๆ ๅๆฏไป %s ๆดๆนไธบ %s %s
-pulls.tab_conversation=ๅฏน่ฏๅ
ๅฎน
+pulls.tab_conversation=ๅฏน่ฏ
pulls.tab_commits=ไปฃ็ ๆไบค
pulls.tab_files=ๆไปถๅๅจ
pulls.reopen_to_merge=่ฏท้ๆฐๅๅปบๆญคๅๅนถ่ฏทๆฑใ
@@ -1822,32 +1908,32 @@ pulls.files_conflicted=ๆญคๅๅนถ่ฏทๆฑๆๅๆดไธ็ฎๆ ๅๆฏๅฒ็ชใ
pulls.is_checking=ๆญฃๅจ่ฟ่กๅๅนถๅฒ็ชๆฃๆต๏ผ่ฏท็จๅๅ่ฏใ
pulls.is_ancestor=ๆญคๅๆฏๅทฒ็ปๅ
ๅซๅจ็ฎๆ ๅๆฏไธญ๏ผๆฒกๆๆดๆนๅฏไปฅๅๅนถใ
pulls.is_empty=ๆญคๅๆฏไธ็ๆดๆนๅทฒ็ปๅจ็ฎๆ ๅๆฏไธใ่ฟๅฐๆฏไธไธช็ฉบๆไบคใ
-pulls.required_status_check_failed=ไธไบๅฟ
่ฆ็ๆฃๆฅๆฒกๆๆๅ
+pulls.required_status_check_failed=ไธไบๅฟ
่ฆ็ๆฃๆฅๆฒกๆๆๅใ
pulls.required_status_check_missing=็ผบๅฐไธไบๅฟ
่ฆ็ๆฃๆฅใ
-pulls.required_status_check_administrator=ไฝไธบ็ฎก็ๅ๏ผๆจไปๅฏๅๅนถๆญคๅๅนถ่ฏทๆฑ
+pulls.required_status_check_administrator=ไฝไธบ็ฎก็ๅ๏ผๆจไปๅฏๅๅนถๆญคๅๅนถ่ฏทๆฑใ
pulls.blocked_by_approvals=ๆญคๅๅนถ่ฏทๆฑๅฝๅ่ฟๆฒกๆ้่ฟๅฎกๆนใๅทฒ่ทๅๅฎกๆนๆฐ%dไธช๏ผๅ
ฑ้่ฆๅฎกๆนๆฐ%dไธชใ
-pulls.blocked_by_rejection=ๆญคๅๅนถ่ฏทๆฑๆๅฎๆนๅฎกๆ ธๅ่ฏทๆฑ็ๆดๆนใ
-pulls.blocked_by_official_review_requests=ๆญคๅๅนถ่ฏทๆฑ้่ฆไธๅๆๅคๅๅฎกๆ ธๅๅฎก้
ๆนๅใ
+pulls.blocked_by_rejection=ๆญคๅๅนถ่ฏทๆฑๆๅฎๆน่ฏๅฎกๅ่ฏทๆฑ็ๆดๆนใ
+pulls.blocked_by_official_review_requests=ๆญคๅๅนถ่ฏทๆฑ้่ฆไธๅๆๅคๅ่ฏๅฎกๅๅฎก้
ๆนๅใ
pulls.blocked_by_outdated_branch=ๆญคๅๅนถ่ฏทๆฑๅ ่ฟๆ่่ขซ้ปๆญขใ
pulls.blocked_by_changed_protected_files_1=ๆญคๅๅนถ่ฏทๆฑๅ ไฟฎๆนไบไธๅ่ขซไฟๆค็ๆไปถ่่ขซ้ปๆญข๏ผ
pulls.blocked_by_changed_protected_files_n=ๆญคๅๅนถ่ฏทๆฑๅ ไฟฎๆนไบไธๅ่ขซไฟๆค็ๆไปถ่่ขซ้ปๆญข๏ผ
pulls.can_auto_merge_desc=่ฏฅๅๅนถ่ฏทๆฑๅฏไปฅ่ฟ่ก่ชๅจๅๅนถๆไฝใ
pulls.cannot_auto_merge_desc=่ฏฅๅๅนถ่ฏทๆฑๅญๅจๅฒ็ช๏ผๆ ๆณ่ฟ่ก่ชๅจๅๅนถๆไฝใ
-pulls.cannot_auto_merge_helper=ๆๅจๅๅนถ่งฃๅณๆญคๅฒ็ช
+pulls.cannot_auto_merge_helper=ๆๅจๅๅนถไปฅ่งฃๅณๅฒ็ชใ
pulls.num_conflicting_files_1=%d ไธชๅฒ็ชๆไปถ
pulls.num_conflicting_files_n=%d ไธชๅฒ็ชๆไปถ
pulls.approve_count_1=%d ้กนๆนๅ
pulls.approve_count_n=%d ้กนๆนๅ
pulls.reject_count_1=%d ๅๆด่ฏทๆฑ
pulls.reject_count_n=%d ๅๆด่ฏทๆฑ
-pulls.waiting_count_1=%d ไธชๆญฃๅจ็ญๅพ
ๅฎกๆ ธ
-pulls.waiting_count_n=%d ไธชๆญฃๅจ็ญๅพ
ๅฎกๆ ธ
+pulls.waiting_count_1=%d ไธชๆญฃๅจ็ญๅพ
่ฏๅฎก
+pulls.waiting_count_n=%d ไธชๆญฃๅจ็ญๅพ
่ฏๅฎก
pulls.wrong_commit_id=ๆไบค ID ๅฟ
้กปๆฏ็ฎๆ ๅๆฏไธ็ๆไบค็ ID
pulls.no_merge_desc=็ฑไบๆชๅฏ็จๅๅนถ้้กน๏ผๆญคๅๅนถ่ฏทๆฑๆ ๆณ่ขซๅๅนถใ
pulls.no_merge_helper=ๅจไปๅบ่ฎพ็ฝฎไธญๅฏ็จๅๅนถ้้กนๆ่
ๆๅทฅๅๅนถ่ฏทๆฑใ
pulls.no_merge_wip=่ฟไธชๅๅนถ่ฏทๆฑๆ ๆณๅๅนถ๏ผๅ ไธบ่ขซๆ ่ฎฐไธบๅฐๆชๅฎๆ็ๅทฅไฝใ
-pulls.no_merge_not_ready=ๆญคๆๅ่ฏทๆฑๅฐๆชๅๅคๅฅฝๅๅนถ๏ผ่ฏทๆฃๆฅๅฎกๆ ธ็ถๆๅ็ถๆๆฃๆฅใ
+pulls.no_merge_not_ready=ๆญคๆๅ่ฏทๆฑๅฐๆชๅๅคๅฅฝ่ขซๅๅนถ๏ผ่ฏทๆฃๆฅ่ฏๅฎก็ถๆๅ็ถๆๆฃๆฅใ
pulls.no_merge_access=ๆจๆ ๆๅๅนถๆญคๆๅ่ฏทๆฑใ
pulls.merge_pull_request=ๅๅปบๅๅนถๆไบค
pulls.rebase_merge_pull_request=ๅๅบๅๅฟซ่ฟ
@@ -1869,7 +1955,7 @@ pulls.has_merged=ๅคฑ่ดฅ๏ผๅๅนถ่ฏทๆฑๅทฒ็ป่ขซๅๅนถ๏ผๆจไธ่ฝๅๆฌกๅๅนถๆ
pulls.push_rejected=ๅๅนถๅคฑ่ดฅ๏ผๆจ้่ขซๆ็ปใ่ฏทๆฅ็ๆญคไปๅบ็ Git ้ฉๅญใ
pulls.push_rejected_summary=่ฏฆ็ปๆ็ปไฟกๆฏ
pulls.push_rejected_no_message=ๆจ้ๅคฑ่ดฅ๏ผๆญคๆจ้่ขซๆ็ปไฝๆชๆไพๅ
ถไปไฟกๆฏใ่ฏทๆฃๆฅๆญคไปๅบ็ Git ้ฉๅญ
-pulls.open_unmerged_pull_exists=`ๆจไธ่ฝๆง่ก้ๆฐๆๅผๆไฝ, ๅ ไธบๅทฒ็ปๅญๅจ็ธๅ็ๅๅนถ่ฏทๆฑ (#%d)ใ`
+pulls.open_unmerged_pull_exists=`ๆจไธ่ฝๆง่ก้ๆฐๆๅผๆไฝ, ๅ ไธบๅทฒ็ปๅญๅจ็ธๅ็ๅๅนถ่ฏทๆฑ๏ผ#%d๏ผใ`
pulls.status_checking=ไธไบๆฃๆตไปๅจ็ญๅพ
่ฟ่ก
pulls.status_checks_success=ๆๆๆฃๆตๅๆๅ
pulls.status_checks_warning=ไธไบๆฃๆฅๆฅๅไบ่ญฆๅ
@@ -1884,18 +1970,18 @@ pulls.update_branch_rebase=้่ฟๅๅบๆดๆฐๅๆฏ
pulls.update_branch_success=ๅๆฏๆดๆฐๆๅ
pulls.update_not_allowed=ๆจๆ ๆๆดๆฐๅๆฏ
pulls.outdated_with_base_branch=ๆญคๅๆฏ็ธๆฏๅบ็กๅๆฏๅทฒ่ฟๆ
-pulls.close=ๅ
ณ้ญๅๅนถ่ฏทๆฑ
-pulls.closed_at=`ไบ %[2]s ๅ
ณ้ญๆญคๅๅนถ่ฏทๆฑ `
+pulls.close=ๅ
ณ้ญ
+pulls.closed_at=`ไบ%[2]s ๅ
ณ้ญๆญคๅๅนถ่ฏทๆฑ `
pulls.reopened_at=`้ๆฐๆๅผๆญคๅๅนถ่ฏทๆฑ %[2]s `
-pulls.cmd_instruction_hint=`ๆฅ็ ๅฝไปค่กๆ็คบ ใ`
+pulls.cmd_instruction_hint=ๆฅ็ๅฝไปค่ก่ฏดๆ
pulls.cmd_instruction_checkout_title=ๆฃๅบ
pulls.cmd_instruction_checkout_desc=ไปไฝ ็ไปๅบไธญๆฃๅบไธไธชๆฐ็ๅๆฏๅนถๆต่ฏๅๆดใ
pulls.cmd_instruction_merge_title=ๅๅนถ
-pulls.cmd_instruction_merge_desc=ๅๅนถๅๆดๅนถๆดๆฐๅฐ Gitea ไธ
+pulls.cmd_instruction_merge_desc=ๅๅนถๆดๆนๅนถๅจ Forgejo ไธๆดๆฐใ
pulls.clear_merge_message=ๆธ
้คๅๅนถไฟกๆฏ
pulls.clear_merge_message_hint=ๆธ
้คๅๅนถๆถๆฏๅชไผๅ ้คๆไบคๆถๆฏๅ
ๅฎน๏ผๅนถไฟ็็ๆ็ git ้ๅ ๅ
ๅฎน๏ผๅฆโCo-Authored-By โฆโใ
-pulls.auto_merge_button_when_succeed=(ๅฝๆฃๆฅๆๅๆถ)
+pulls.auto_merge_button_when_succeed=๏ผๅฝๆฃๆฅๆๅๆถ๏ผ
pulls.auto_merge_when_succeed=ๅจๆๆๆฃๆฅๆๅๅ่ชๅจๅๅนถ
pulls.auto_merge_newly_scheduled=ๅๅนถ่ฏทๆฑ่ฎกๅๅจๆๆๆฃๆฅๆๅๅๅๅนถใ
pulls.auto_merge_has_pending_schedule=%[1]s ๅฎๆๆญคๆๅ่ฏทๆฑๅจๆๆๆฃๆฅๆๅๆถ่ชๅจๅๅนถ %[2]sใ
@@ -1908,20 +1994,20 @@ pulls.auto_merge_newly_scheduled_comment=`ๅทฒๅฎๆๆญคๆๅ่ฏทๆฑๅจๆๆๆฃ
pulls.auto_merge_canceled_schedule_comment=`ๅทฒๅๆถๅฝๆๆๆฃๆฅๆๅๅ่ชๅจๅๅนถๆญคๆๅ่ฏทๆฑ %[1]s`
pulls.delete.title=ๅ ้คๆญคๆๅ่ฏทๆฑ๏ผ
-pulls.delete.text=ไฝ ็็่ฆๅ ้ค่ฟไธชๆๅ่ฏทๆฑๅ๏ผ (่ฟๅฐๆฐธไน
ๅ ้คๆๆๅ
ๅฎนใๅฆๆไฝ ๆ็ฎๅฐๅ
ๅฎนๅญๆกฃ๏ผ่ฏท่่ๅ
ณ้ญๅฎ)
+pulls.delete.text=ไฝ ็็่ฆๅ ้ค่ฟไธชๆๅ่ฏทๆฑๅ๏ผ๏ผ่ฟๅฐๆฐธไน
ๅ ้คๆๆๅ
ๅฎนใๅฆๆไฝ ๆ็ฎๅฐๅ
ๅฎนๅญๆกฃ๏ผ่ฏท่่ๅ
ณ้ญๅฎ๏ผ
-pulls.recently_pushed_new_branches=ๆจๅทฒ็ปไบ%[2]sๆจ้ไบๅๆฏ %[1]s
+pulls.recently_pushed_new_branches=ๆจๅทฒไบ%[2]sๆจ้ไบๅๆฏ %[1]s
-pull.deleted_branch=(ๅทฒๅ ้ค): %s
+pull.deleted_branch=๏ผๅทฒๅ ้ค๏ผ๏ผ%s
milestones.new=ๆฐ็้็จ็ข
milestones.closed=ไบ %sๅ
ณ้ญ
milestones.update_ago=ๅทฒๆดๆฐ %s
milestones.no_due_date=ๆๆ ๆชๆญขๆฅๆ
-milestones.open=ๅผๅฏไธญ
+milestones.open=ๅผๆพไธญ
milestones.close=ๅ
ณ้ญ
milestones.new_subheader=้็จ็ขๅฏไปฅๅธฎๅฉๆจ็ป็ปๅทฅๅๅนถ่ท่ธชๅ
ถ่ฟๅบฆใ
-milestones.completeness=%d%% ๅฎๆ
+milestones.completeness=%d%% ๅทฒๅฎๆ
milestones.create=ๅๅปบ้็จ็ข
milestones.title=ๆ ้ข
milestones.desc=ๆ่ฟฐ
@@ -1958,13 +2044,13 @@ signing.wont_sign.commitssigned=ๅๅนถๅฐไธไผ่ขซ็ญพๅ๏ผๅ ไธบๆๆ็ธๅ
ณ็
signing.wont_sign.approved=ๅๅนถๅฐไธไผ่ขซ็ญพๅ๏ผๅ ไธบๅๅนถ่ฏทๆฑๆช่ขซๆนๅใ
signing.wont_sign.not_signed_in=ๆจ่ฟๆฒกๆ็ปๅฝใ
-ext_wiki=่ฎฟ้ฎๅค้จ็พ็ง
+ext_wiki=ๅค้จ็พ็ง
ext_wiki.desc=้พๆฅๅฐๅค้จ wikiใ
wiki=็พ็ง
-wiki.welcome=ๆฌข่ฟๆฅๅฐ็พ็ง!
-wiki.welcome_desc=็พ็งๅ
่ฎธไฝ ๆฐๅๅไธๅไฝ่
ๅไบซๆๆกฃ
-wiki.desc=ๆฐๅๅไธๅไฝ่
ๅไบซๆๆกฃ
+wiki.welcome=ๆฌข่ฟๆฅๅฐ็พ็งใ
+wiki.welcome_desc=็พ็งๅ
่ฎธไฝ ๆฐๅๅนถไธๅไฝ่
ๅไบซๆๆกฃใ
+wiki.desc=ๆฐๅๅนถไธๅไฝ่
ๅ
ฑไบซๆๆกฃใ
wiki.create_first_page=ๅๅปบ็ฌฌไธไธช้กต้ข
wiki.page=้กต้ข
wiki.filter_page=่ฟๆปค้กต้ข
@@ -2005,12 +2091,12 @@ activity.merged_prs_count_1=ๅทฒๅๅนถ็ๅๅนถ่ฏทๆฑ
activity.merged_prs_count_n=ๅทฒๅๅนถ็ๅๅนถ่ฏทๆฑ
activity.opened_prs_count_1=ๆฐๅๅนถ่ฏทๆฑ
activity.opened_prs_count_n=ๆฐๅๅนถ่ฏทๆฑ
-activity.title.user_1=%d ็จๆท
-activity.title.user_n=%d ็จๆท
+activity.title.user_1=%d ๅ็จๆท
+activity.title.user_n=%d ๅ็จๆท
activity.title.prs_1=%d ไธชๅๅนถ่ฏทๆฑ
activity.title.prs_n=%d ไธชๅๅนถ่ฏทๆฑ
-activity.title.prs_merged_by=%[2]s ็ฑ %[1]s ๅๅนถ
-activity.title.prs_opened_by=%[2]s ๅๅปบไบ %[1]s
+activity.title.prs_merged_by=%[2]s ๅ
ฑๅๅนถไบ %[1]s
+activity.title.prs_opened_by=%[2]s ๅ
ฑๅๅปบไบ %[1]s
activity.merged_prs_label=ๅทฒๅๅนถ
activity.opened_prs_label=ๅทฒๅๅปบ
activity.active_issues_count_1=%d ้กนๆดปๅจ็ๅทฅๅ
@@ -2019,8 +2105,8 @@ activity.closed_issues_count_1=ๅทฒๅ
ณ้ญ็ๅทฅๅ
activity.closed_issues_count_n=ๅทฒๅ
ณ้ญ็ๅทฅๅ
activity.title.issues_1=%d ้กนๅทฅๅ
activity.title.issues_n=%d ้กนๅทฅๅ
-activity.title.issues_closed_from=%s ไป %s ่ขซๅ
ณ้ญ
-activity.title.issues_created_by=%[2]s ๅๅปบไบ %[1]s
+activity.title.issues_closed_from=%[2]s ๅ
ฑๅ
ณ้ญไบ %[1]s
+activity.title.issues_created_by=%[2]s ๅ
ฑๅๅปบไบ %[1]s
activity.closed_issue_label=ๅทฒๅ
ณ้ญ
activity.new_issues_count_1=ๆฐๅทฅๅ
activity.new_issues_count_n=ๆฐๅทฅๅ
@@ -2031,33 +2117,33 @@ activity.unresolved_conv_desc=่ฟไบๆ่ฟๆดๆฐ็ๅทฅๅๅๅๅนถ่ฏทๆฑ่ฟๆฒก
activity.unresolved_conv_label=ๆๅผ
activity.title.releases_1=%d ไธช็ๆฌๅๅธ
activity.title.releases_n=%d ไธช็ๆฌๅๅธ
-activity.title.releases_published_by=%[2]s ๅๅธไบ %[1]s
-activity.published_release_label=ๅทฒๅๅธ
+activity.title.releases_published_by=%[2]s ๅ
ฑๅๅธไบ %[1]s
+activity.published_release_label=็ๆฌๅๅธ
activity.no_git_activity=ๅจๆญคๆ้ดๆฒกๆไปปไฝๆไบคๆดปๅจใ
-activity.git_stats_exclude_merges=ๆ้คๅๅนถ๏ผ
-activity.git_stats_author_1=%d ไฝ่
-activity.git_stats_author_n=%d ไฝ่
-activity.git_stats_pushed_1=ๅทฒ็ปๆจ้
-activity.git_stats_pushed_n=ๅทฒ็ปๆจ้
-activity.git_stats_commit_1=%d ๆไบค
-activity.git_stats_commit_n=%d ๆไบค
+activity.git_stats_exclude_merges=้คๅปๅๅนถๆไบคไปฅๅค๏ผ
+activity.git_stats_author_1=%d ๅไฝ่
+activity.git_stats_author_n=%d ๅไฝ่
+activity.git_stats_pushed_1=ๆปๅ
ฑๆจ้ไบ
+activity.git_stats_pushed_n=ๆปๅ
ฑๆจ้ไบ
+activity.git_stats_commit_1=%d ไธชๆไบค
+activity.git_stats_commit_n=%d ไธชๆไบค
activity.git_stats_push_to_branch=ๅฐ %s ๅ
activity.git_stats_push_to_all_branches=ๅฐๆๆๅๆฏใ
-activity.git_stats_on_default_branch=ๅจ %s ไธ๏ผ
-activity.git_stats_file_1=%d ๆไปถ
-activity.git_stats_file_n=%d ๆไปถ
-activity.git_stats_files_changed_1=ๅทฒ็ปๆนๅ
-activity.git_stats_files_changed_n=ๅทฒ็ปๆนๅ
-activity.git_stats_additions=่ไธ
-activity.git_stats_addition_1=ๆฐๅข %d ่ก
-activity.git_stats_addition_n=ๆฐๅข %d ่ก
-activity.git_stats_and_deletions=ๅ
-activity.git_stats_deletion_1=ๅ ้ค %d ่ก
-activity.git_stats_deletion_n=ๅ ้ค %d ่ก
+activity.git_stats_on_default_branch=ๅจ %s ๅๆฏไธ๏ผ
+activity.git_stats_file_1=%d ไธชๆไปถ
+activity.git_stats_file_n=%d ไธชๆไปถ
+activity.git_stats_files_changed_1=่ขซๆนๅจ
+activity.git_stats_files_changed_n=่ขซๆนๅจ
+activity.git_stats_additions=๏ผๆปๅ
ฑ
+activity.git_stats_addition_1=ๆฐๅขไบ %d ่ก
+activity.git_stats_addition_n=ๆฐๅขไบ %d ่ก
+activity.git_stats_and_deletions=ๅนถๆ
+activity.git_stats_deletion_1=%d ่ก่ขซๅ ้ค
+activity.git_stats_deletion_n=%d ่ก่ขซๅ ้ค
contributors.contribution_type.filter_label=่ดก็ฎ็ฑปๅ๏ผ
contributors.contribution_type.commits=ๆไบค
-contributors.contribution_type.additions=ๆดๅค
+contributors.contribution_type.additions=ๅขๅ
contributors.contribution_type.deletions=ๅ ้ค
search=ๆ็ดข
@@ -2097,7 +2183,7 @@ settings.mirror_settings.docs.doc_link_title=ๅฆไฝ้ๅไปๅบ๏ผ
settings.mirror_settings.docs.doc_link_pull_section=ๆๆกฃไธญ็ โไป่ฟ็จไปๅบๆๅโ ้จๅใ
settings.mirror_settings.docs.pulling_remote_title=ไป่ฟ็จไปๅบๆๅไปฃ็
settings.mirror_settings.mirrored_repository=้ๅๅบ
-settings.mirror_settings.pushed_repository=ๆจ้ไปๅบ
+settings.mirror_settings.pushed_repository = ๆจ้ๅฐ็ไปๅบ
settings.mirror_settings.direction=ๆนๅ
settings.mirror_settings.direction.pull=ๆๅ
settings.mirror_settings.direction.push=ๆจ้
@@ -2121,17 +2207,17 @@ settings.wiki_desc=ๅฏ็จไปๅบ็พ็ง
settings.use_internal_wiki=ไฝฟ็จๅ
็ฝฎ็พ็ง
settings.use_external_wiki=ไฝฟ็จๅค้จ็พ็ง
settings.external_wiki_url=ๅค้จ็พ็ง้พๆฅ
-settings.external_wiki_url_error=ๅค้จ็พ็ง้พๆฅๆ ๆ
+settings.external_wiki_url_error=ๅค้จ็พ็ง้พๆฅไธๆฏๆๆ็ URLใ
settings.external_wiki_url_desc=ๅฝ็นๅป็พ็งๆ ็ญพๆถ๏ผ่ฎฟ้ฎ่
ๅฐ่ขซ้ๅฎๅๅฐๅค้จ็พ็ง็ณป็ป็URLใ
settings.issues_desc=ๅฏ็จไปๅบๅทฅๅ็ณป็ป
-settings.use_internal_issue_tracker=ไฝฟ็จๅ
็ฝฎ็ๅทฅๅ็ฎก็็ณป็ป
-settings.use_external_issue_tracker=ไฝฟ็จๅค้จ็ๅทฅๅ็ฎก็็ณป็ป
+settings.use_internal_issue_tracker=ไฝฟ็จๅ
็ฝฎ็ๅทฅๅ็ณป็ป
+settings.use_external_issue_tracker=ไฝฟ็จๅค้จ็ๅทฅๅ็ณป็ป
settings.external_tracker_url=ๅค้จๅทฅๅ็ณป็ป URL
-settings.external_tracker_url_error=ๅค้จ็พ็ง้พๆฅๆ ๆ
+settings.external_tracker_url_error=ๅค้จ็พ็ง้พๆฅๆ ๆใ
settings.external_tracker_url_desc=ๅฝ็นๅปๅทฅๅๆ ็ญพๆถ๏ผ่ฎฟ้ฎ่
ๅฐ่ขซ้ๅฎๅๅฐๅค้จๅทฅๅ็ณป็ป็URLใ
-settings.tracker_url_format=ๅค้จๅทฅๅ็ฎก็็ณป็ป็ URL ๆ ผๅผ
-settings.tracker_url_format_error=ๅค้จๅทฅๅ้พๆฅๆ ๆ
-settings.tracker_issue_style=ๅค้จๅทฅๅ็ฎก็็ณป็ป็็ผๅทๆ ผๅผ
+settings.tracker_url_format=ๅค้จๅทฅๅ็ณป็ป็ URL ๆ ผๅผ
+settings.tracker_url_format_error=ๅค้จๅทฅๅ่ฟฝ่ธชๅจ้พๆฅๆ ๆใ
+settings.tracker_issue_style=ๅค้จๅทฅๅ็ณป็ป็็ผๅทๆ ผๅผ
settings.tracker_issue_style.numeric=็บฏๆฐๅญๅฝขๅผ
settings.tracker_issue_style.alphanumeric=่ฑๆๅญๆฏๆฐๅญ็ปๅๅฝขๅผ
settings.tracker_issue_style.regexp=ๆญฃๅ่กจ่พพๅผ
@@ -2142,7 +2228,7 @@ settings.enable_timetracker=ๅฏ็จๆถ้ด่ท่ธช
settings.allow_only_contributors_to_track_time=ไป
ๅ
่ฎธๆๅ่ท่ธชๆถ้ด
settings.pulls_desc=ๅฏ็จๅๅนถ่ฏทๆฑ
settings.pulls.ignore_whitespace=ๅฟฝ็ฅ็ฉบๆ ผๅฒ็ช
-settings.pulls.enable_autodetect_manual_merge=ๅฏ็จ่ชๅจๆฃๆตๆๅจๅๅนถ (ๆณจๆ๏ผๅจๆไบ็นๆฎๆ
ๅตไธๅฏ่ฝๅ็้่ฏฏๅคๆญ)
+settings.pulls.enable_autodetect_manual_merge=ๅฏ็จ่ชๅจๆฃๆตๆๅจๅๅนถ๏ผๆณจๆ๏ผๅจๆไบ็นๆฎๆ
ๅตไธๅฏ่ฝๅ็้่ฏฏๅคๆญ๏ผ
settings.pulls.allow_rebase_update=ๅ
่ฎธ้่ฟๅๅบๆดๆฐๆๅ่ฏทๆฑๅๆฏ
settings.pulls.default_delete_branch_after_merge=้ป่ฎคๅๅนถๅๅ ้คๅๅนถ่ฏทๆฑๅๆฏ
settings.pulls.default_allow_edits_from_maintainers=้ป่ฎคๅผๅฏๅ
่ฎธ็ปดๆค่
็ผ่พ
@@ -2151,7 +2237,7 @@ settings.packages_desc=ๅฏ็จไปๅบ่ฝฏไปถๅ
ๆณจๅไธญๅฟ
settings.projects_desc=ๅฏ็จไปๅบ้กน็ฎ
settings.actions_desc=ไฝฟ็จ Forgejo Actions ๅฏ็จ้ๆ CI/CD ็ฎก้
settings.admin_settings=็ฎก็ๅ่ฎพ็ฝฎ
-settings.admin_enable_health_check=ๅฏ็จไปๅบๅฅๅบทๆฃๆฅ (git fsck)
+settings.admin_enable_health_check=ๅฏ็จไปๅบๅฅๅบทๆฃๆฅ๏ผgit fsck๏ผ
settings.admin_code_indexer=ไปฃ็ ็ดขๅผๅจ
settings.admin_stats_indexer=ไปฃ็ ็ป่ฎก็ดขๅผๅจ
settings.admin_indexer_commit_sha=ไธๆฌก็ดขๅผ็ๆไบค
@@ -2160,7 +2246,7 @@ settings.reindex_button=ๆทปๅ ๅฐ้ๆฐ็ดขๅผ้ๅ
settings.reindex_requested=ๅทฒ่ฏทๆฑ้ๆฐ็ดขๅผ
settings.admin_enable_close_issues_via_commit_in_any_branch=้่ฟๅจ้้ป่ฎคๅๆฏไธญๆไบคๆฅๅ
ณ้ญๅทฅๅ
settings.danger_zone=ๅฑ้ฉๆไฝๅบ
-settings.new_owner_has_same_repo=ๆฐ็ไปๅบๆฅๆ่
ๅทฒ็ปๅญๅจๅๅไปๅบ๏ผ
+settings.new_owner_has_same_repo=ๆฐ็ไปๅบๆฅๆ่
ๅทฒ็ปๅญๅจๅๅไปๅบใ่ฏท้ๆฉๅฆไธไธชๅๅญใ
settings.convert=่ฝฌๆขไธบๆฎ้ไปๅบ
settings.convert_desc=ๆจๅฏไปฅๅฐ่ฏฅ้ๅไปๅบ่ฝฌๆขไธบๆฎ้ไปๅบ๏ผไฝๆญคๆไฝไธๅฏๆขๅคใ
settings.convert_notices_1=่ฏฅๆไฝไผๅฐ้ๅไปๅบ่ฝฌๆขไธบๆฎ้ไปๅบ๏ผไฝ่ฏฅๆไฝไธๅฏๆขๅคใ
@@ -2181,8 +2267,8 @@ settings.transfer_desc=ๆจๅฏไปฅๅฐไปๅบ่ฝฌ็งป่ณๆจๆฅๆ็ฎก็ๅๆ้็ๅธ
settings.transfer_form_title=่พๅ
ฅไปๅบๅ็งฐไปฅๅ็กฎ่ฎค:
settings.transfer_in_progress=ๅฝๅๆญฃๅจ่ฟ่ก่ฝฌ่ฎฉใ ๅฆๆไฝ ๆณๅฐๆญคไปฃ็ ๅบ่ฝฌ่ฎฉ็ปๅฆไธไธช็จๆท๏ผ่ฏทๅๆถๅฎใ
settings.transfer_notices_1=- ๅฆๆๅฐๆญคไปๅบ่ฝฌ็งป็ปๅ
ถไป็จๆท, ๆจๅฐๅคฑๅปๅฏนๆญคไปๅบ็่ฎฟ้ฎๆ้ใ
-settings.transfer_notices_2=-ๅฆๆๅฐๅ
ถ่ฝฌ็งปๅฐๆจ (ๅ
ฑๅ) ๆฅๆ็็ป็ป๏ผๆจๅฏไปฅ็ปง็ปญ่ฎฟ้ฎ่ฏฅไปๅบใ
-settings.transfer_notices_3=- ๅฆๆไปๅบๆฏ็งๆ็ๅนถไธ่ขซ่ฝฌ็งป็ปๆไธช็จๆท๏ผ้ฃไนๆญคๆไฝๅฏไปฅ็กฎไฟ่ฏฅ็จๆท่ณๅฐๅ
ทๆ่ฏปๆ้(ไปฅๅๅฟ
่ฆๆถ็ๆดๆนๆ้)ใ
+settings.transfer_notices_2=-ๅฆๆๅฐๅ
ถ่ฝฌ็งปๅฐๆจ๏ผๅ
ฑๅ๏ผ ๆฅๆ็็ป็ป๏ผๆจๅฏไปฅ็ปง็ปญ่ฎฟ้ฎ่ฏฅไปๅบใ
+settings.transfer_notices_3=- ๅฆๆไปๅบๆฏ็งๆ็ๅนถไธ่ขซ่ฝฌ็งป็ปๆไธช็จๆท๏ผ้ฃไนๆญคๆไฝๅฏไปฅ็กฎไฟ่ฏฅ็จๆท่ณๅฐๅ
ทๆ่ฏปๆ้๏ผไปฅๅๅฟ
่ฆๆถ็ๆดๆนๆ้๏ผใ
settings.transfer_owner=ๆฐๆฅๆ่
settings.transfer_perform=ๆง่ก่ฝฌ่ฎฉ
settings.transfer_started=่ฏฅไปฃ็ ๅบๅทฒ่ขซๆ ่ฎฐไธบ่ฝฌ่ฎฉๅนถ็ญๅพ
ๆฅ่ช %s ็็กฎ่ฎค
@@ -2193,10 +2279,10 @@ settings.trust_model.default=้ป่ฎคไฟกไปปๆจกๅ
settings.trust_model.default.desc=ไธบๆญคๅฎ่ฃ
ไฝฟ็จ้ป่ฎคไปๅบไฟกไปปๆจกๅใ
settings.trust_model.collaborator=ๅไฝ่
settings.trust_model.collaborator.long=ๅไฝ่
๏ผไฟกไปปๅไฝ่
็็ญพๅ
-settings.trust_model.collaborator.desc=ๆญคไปๅบไธญๅไฝ่
็ๆๆ็ญพๅๅฐ่ขซๆ ่ฎฐไธบใๅฏไฟกใ(ๆ ่ฎบๅฎไปฌๆฏๅฆๆฏๆไบค่
)๏ผ็ญพๅๅช็ฌฆๅๆไบค่
ๆถๅฐๆ ่ฎฐไธบใไธๅฏไฟกใ๏ผ้ฝไธๅน้
ๆถๆ ่ฎฐไธบใไธๅน้
ใใ
+settings.trust_model.collaborator.desc=ๆญคไปๅบไธญๅไฝ่
็ๆๆ็ญพๅๅฐ่ขซๆ ่ฎฐไธบใๅฏไฟกใ๏ผๆ ่ฎบๅฎไปฌๆฏๅฆๆฏๆไบค่
๏ผ๏ผ็ญพๅๅช็ฌฆๅๆไบค่
ๆถๅฐๆ ่ฎฐไธบใไธๅฏไฟกใ๏ผ้ฝไธๅน้
ๆถๆ ่ฎฐไธบใไธๅน้
ใใ
settings.trust_model.committer=ๆไบค่
-settings.trust_model.committer.long=ๆไบค่
๏ผ ไฟกไปปไธๆไบค่
็ธ็ฌฆ็็ญพๅ (ๆญค็นๆง็ฑปไผผ GitHub๏ผ่ฟไผๅผบๅถ้็จ Forgejo ไฝไธบๆไบค่
ๅ็ญพๅ่
)
-settings.trust_model.committer.desc=ๆๆ็ญพๅๅชๆๅๆไบค่
็ธๅน้
ๆไผ่ขซๆ ่ฎฐไธบโๅไฟกไปปโ๏ผๅฆๅๅฎไปฌๅฐ่ขซๆ ่ฎฐไธบโไธๅน้
โใ่ฟๅผบๅถ Forgejo ๆไธบ็ญพๅๆไบค็ๆไบค่
๏ผ่ๅฎ้
ๆไบค่
่ขซๅ ไธ Co-authored-by: ๅ Co-committed-by: ็ๆ ่ฎฐใ ้ป่ฎค็ Forgejo ๅฏ้ฅๅฟ
้กปๅน้
ๆฐๆฎๅบไธญ็ไธๅ็จๆทใ
+settings.trust_model.committer.long=ๆไบค่
๏ผไฟกไปปไธๆไบค่
็ธ็ฌฆ็็ญพๅ๏ผๆญค็นๆง็ฑปไผผ GitHub๏ผ่ฟไผๅผบๅถ้็จ Forgejo ไฝไธบๆไบค่
ๅ็ญพๅ่
๏ผ
+settings.trust_model.committer.desc=ๆๆ็ญพๅๅชๆๅๆไบค่
็ธๅน้
ๆไผ่ขซๆ ่ฎฐไธบโๅไฟกไปปโ๏ผๅฆๅๅฎไปฌๅฐ่ขซๆ ่ฎฐไธบโไธๅน้
โใ่ฟๅผบๅถ Forgejo ๆไธบ็ญพๅๆไบค็ๆไบค่
๏ผ่ๅฎ้
ๆไบค่
่ขซๅ ไธ Co-authored-by๏ผๅ Co-committed-by๏ผ็ๆ ่ฎฐใ ้ป่ฎค็ Forgejo ๅฏ้ฅๅฟ
้กปๅน้
ๆฐๆฎๅบไธญ็ไธๅ็จๆทใ
settings.trust_model.collaboratorcommitter=ๅไฝ่
+ๆไบค่
settings.trust_model.collaboratorcommitter.long=ๅไฝ่
+ๆไบค่
๏ผไฟกไปปๅไฝ่
ๅๆถๆฏๆไบค่
็็ญพๅ
settings.trust_model.collaboratorcommitter.desc=ๆญคไปๅบไธญๅไฝ่
็ๆๆ็ญพๅๅจไปๅๆถๆฏๆไบค่
ๆถๅฐ่ขซๆ ่ฎฐไธบใๅฏไฟกใ๏ผ็ญพๅๅชๅน้
ไบๆไบค่
ๆถๅฐๆ ่ฎฐไธบใไธๅฏไฟกใ๏ผ้ฝไธๅน้
ๆถๆ ่ฎฐไธบใไธๅน้
ใใ่ฟไผๅผบๅถ Forgejo ๆไธบ็ญพๅ่
ๅๆไบค่
๏ผๅฎ้
็ๆไบค่
ๅฐ่ขซๆ ่ฎฐไบๆไบคๆถๆฏ็ปๅฐพๅค็ใCo-Authored-By:ใๅใCo-Committed-By:ใใ้ป่ฎค็ Forgejo ็ญพๅๅฏ้ฅๅฟ
้กปๅน้
ๆฐๆฎๅบไธญ็ไธไธช็จๆทๅฏ้ฅใ
@@ -2204,10 +2290,10 @@ settings.wiki_delete=ๅ ้ค็พ็งๆฐๆฎ
settings.wiki_delete_desc=ๅ ้คไปๅบ็พ็งๆฐๆฎๆฏๆฐธไน
ๆง็๏ผๆ ๆณๆคๆถใ
settings.wiki_delete_notices_1=- ่ฟๅฐๆฐธไน
ๅ ้คๅ็ฆ็จ %s ็็พ็งใ
settings.confirm_wiki_delete=ๅ ้ค็พ็งๆฐๆฎ
-settings.wiki_deletion_success=ไปๅบ็พ็งๆฐๆฎๅ ้คๆๅ๏ผ
+settings.wiki_deletion_success=ๅทฒๆๅๅ ้คไปๅบ็พ็งๆฐๆฎใ
settings.delete=ๅ ้คๆฌไปๅบ
settings.delete_desc=ๅ ้คไปๅบๆฏๆฐธไน
ๆง็, ๆ ๆณๆคๆถใ
-settings.delete_notices_1=- ๆญคๆไฝ ไธๅฏไปฅ ่ขซๅๆปใ
+settings.delete_notices_1=- ๆญคๆไฝไธๅฏ ่ขซๅๆปใ
settings.delete_notices_2=- ๆญคๆไฝๅฐๆฐธไน
ๅ ้คไปๅบ %s ๏ผๅ
ๆฌ Git ๆฐๆฎใ ๅทฅๅใ่ฏ่ฎบใ็พ็งๅๅไฝ่
็ๆไฝๆ้ใ
settings.delete_notices_fork_1=- ๅจๆญคไปๅบๅ ้คๅ๏ผๅฎ็ๆดพ็ไปๅบๅฐๅๆ็ฌ็ซไปๅบใ
settings.deletion_success=ไปๅบๅทฒ่ขซๅ ้คใ
@@ -2215,16 +2301,16 @@ settings.update_settings_success=ไปๅบ่ฎพ็ฝฎๅทฒๆดๆฐใ
settings.update_settings_no_unit=่ฏฅไปฃ็ ๅบๅบ่ฏฅ่ณๅฐๅ
่ฎธๆ็งๅฝขๅผ็ไบคไบใ
settings.confirm_delete=ๅ ้คไปๅบ
settings.add_collaborator=ๅขๅ ๅไฝ่
-settings.add_collaborator_success=ๅไฝ่
ๆทปๅ ๆๅ๏ผ
+settings.add_collaborator_success=ๅทฒๆๅๆทปๅ ๅไฝ่
ใ
settings.add_collaborator_inactive_user=ๆ ๆณๆทปๅ ๆชๆฟๆดป็็จๆทไฝไธบๅไฝ่
ใ
settings.add_collaborator_owner=ไธ่ฝๅฐๆๆ่
ๆทปๅ ไธบๅไฝ่
ใ
settings.add_collaborator_duplicate=ๅไฝ่
ๅทฒ็ป่ขซๆทปๅ ๅฐๆฌไปๅบใ
settings.delete_collaborator=ๅ ้ค
settings.collaborator_deletion=ๅ ้คๅไฝ่
settings.collaborator_deletion_desc=ๅ ้คๅไฝ่
ๅไปๅฐๆ ๆณๅๅฏนๆญคไปๅบ็่ฎฟ้ฎใ็ปง็ปญ๏ผ
-settings.remove_collaborator_success=ๅไฝ่
ๅ ้คๆๅ๏ผ
+settings.remove_collaborator_success=ๅทฒๆๅๅ ้คๅไฝ่
ใ
settings.search_user_placeholder=ๆ็ดข็จๆท...
-settings.org_not_allowed_to_be_collaborator=็ป็ปไธๅ
่ฎธ่ขซๆทปๅ ไธบไปๅบๅไฝ่
๏ผ
+settings.org_not_allowed_to_be_collaborator=็ป็ปไธๅฏ่ขซๆทปๅ ไธบไปๅบๅไฝ่
ใ
settings.change_team_access_not_allowed=ๆดๆนไปๅบ็ๅข้่ฎฟ้ฎๆ้ไป
้ไบ็ป็ปๆๆ่
settings.team_not_in_organization=ๅข้ไธๅจไธไปๅบ็ธๅ็็ป็ปไธญ
settings.teams=ๅข้
@@ -2240,7 +2326,7 @@ settings.add_webhook.invalid_channel_name=Webhook ้้ๅ็งฐไธ่ฝไธบ็ฉบไธไธ
settings.hooks_desc=ๅฝForgejoไบไปถๅ็ๆถ๏ผWeb้ฉๅญ่ชๅจๅๅบHTTP POST่ฏทๆฑใๅจ ๆๅ ไธญ้
่ฏปๆดๅคๅ
ๅฎนใ
settings.webhook_deletion=ๅ ้ค Web ้ฉๅญ
settings.webhook_deletion_desc=ๅ ้ค web้ฉๅญ ๅฐๅ ้คๅ
ถ่ฎพ็ฝฎๅๅๅฒ่ฎฐๅฝใ็ปง็ปญ๏ผ
-settings.webhook_deletion_success=Web ้ฉๅญๅ ้คๆๅ๏ผ
+settings.webhook_deletion_success=Web ้ฉๅญๅทฒ็งป้คใ
settings.webhook.test_delivery=ๆต่ฏๆจ้
settings.webhook.test_delivery_desc=็จๅไบไปถๆต่ฏ่ฟไธช web้ฉๅญใ
settings.webhook.test_delivery_desc_disabled=่ฆ็จ ่ๅไบไปถ ๆต่ฏ่ฟไธชWebhook๏ผ่ฏทๆฟๆดปๅฎใ
@@ -2273,8 +2359,8 @@ settings.event_send_everything=ๆๆไบไปถ
settings.event_choose=่ชๅฎไนไบไปถโฆ
settings.event_header_repository=ไปๅบไบไปถ
settings.event_create=ๅๅปบ
-settings.event_create_desc=ๅๅปบๅๆฏๆๆ ็ญพ
-settings.event_delete=ๅช้ค
+settings.event_create_desc=ๅๅปบๅๆฏๆๆ ็ญพใ
+settings.event_delete=ๅ ้ค
settings.event_delete_desc=ๅๆฏๆๆ ็ญพๅทฒๅ ้คใ
settings.event_fork=ๆดพ็
settings.event_fork_desc=ไปๅบ่ขซๆดพ็ใ
@@ -2283,50 +2369,50 @@ settings.event_wiki_desc=ๅๅปบใ้ๅฝๅใ็ผ่พๆๅ ้คไบ็พ็ง้กต้ขใ
settings.event_release=็ๆฌๅๅธ
settings.event_release_desc=ๅๅธใๆดๆฐๆๅ ้ค็ๆฌๆถใ
settings.event_push=ๆจ้
-settings.event_push_desc=Git ไปๅบๆจ้
+settings.event_push_desc=ๆจ้ๅฐ Git ไปๅบใ
settings.event_repository=ไปๅบ
-settings.event_repository_desc=ๅๅปบๆๅ ้คไปๅบ
+settings.event_repository_desc=ๅๅปบๆๅ ้คไปๅบใ
settings.event_header_issue=ๅทฅๅไบไปถ
-settings.event_issues=ๅทฅๅ
+settings.event_issues=ไฟฎๆน
settings.event_issues_desc=ๅทฅๅๅทฒๆๅผใๅทฒๅ
ณ้ญใๅทฒ้ๆฐๆๅผๆๅทฒ็ผ่พใ
-settings.event_issue_assign=ๅทฅๅๅทฒๅ้
+settings.event_issue_assign=ๆๆดพ
settings.event_issue_assign_desc=ๅทฅๅๅทฒ่ขซๆๆดพๆๅๆถๆๆดพใ
-settings.event_issue_label=ๅทฅๅๅทฒๅ็ฑป
-settings.event_issue_label_desc=ๅทฅๅๆ ็ญพ่ขซๆดๆฐๆๆธ
้คใ
-settings.event_issue_milestone=ๅทฅๅๅทฒ่ขซๆถๅ
ฅ้็จ็ขไธญ
-settings.event_issue_milestone_desc=ๅทฅๅ่ขซๆถๅ
ฅๆๅๆถๆถๅ
ฅ้็จ็ขไธญใ
-settings.event_issue_comment=ๅทฅๅ่ฏ่ฎบ
-settings.event_issue_comment_desc=ๅทฅๅ่ฏ่ฎบ่ขซๅๅปบใ็ผ่พๆๅ ้ค
+settings.event_issue_label=ๆ ็ญพ
+settings.event_issue_label_desc=ๅทฅๅๆ ็ญพ่ขซๆทปๅ ๆ็งป้คใ
+settings.event_issue_milestone=้็จ็ข
+settings.event_issue_milestone_desc=้็จ็ข่ขซๆทปๅ ใ็งป้คๆไฟฎๆนใ
+settings.event_issue_comment=่ฏ่ฎบ
+settings.event_issue_comment_desc=ๅทฅๅ่ฏ่ฎบ่ขซๅๅปบใ็ผ่พๆๅ ้คใ
settings.event_header_pull_request=ๅๅนถ่ฏทๆฑไบไปถ
-settings.event_pull_request=ๅๅนถ่ฏทๆฑ
+settings.event_pull_request=ไฟฎๆน
settings.event_pull_request_desc=ๅๅนถ่ฏทๆฑ่ขซๆๅผใ่ขซๅ
ณ้ญใ่ขซ้ๆฐๆๅผๆ่ขซ็ผ่พใ
-settings.event_pull_request_assign=ๅๅนถ่ฏทๆฑ่ขซๆๆดพ
+settings.event_pull_request_assign=ๆๆดพ
settings.event_pull_request_assign_desc=ๅๅนถ่ฏทๆฑ่ขซๆๆดพๆๅๆถๆๆดพใ
-settings.event_pull_request_label=ๅๅนถ่ฏทๆฑ่ขซ่ดดไธๆ ็ญพ
-settings.event_pull_request_label_desc=ๅๅนถ่ฏทๆฑ็ๆ ็ญพ่ขซๆดๆฐๆๆธ
้คใ
-settings.event_pull_request_milestone=ๅๅนถ่ฏทๆฑ่ขซ่ฎฐๅฝไบ้็จ็ขไธญ
-settings.event_pull_request_milestone_desc=ๅๅนถ่ฏทๆฑ่ขซ่ฎฐๅฝๆๅๆถ่ฎฐๅฝไบ้็จ็ขไธญใ
-settings.event_pull_request_comment=ๅๅนถ่ฏทๆฑ่ขซ่ฏ่ฎบ
+settings.event_pull_request_label=ๆ ็ญพ
+settings.event_pull_request_label_desc=ๅๅนถ่ฏทๆฑ็ๆ ็ญพ่ขซๆทปๅ ๆ็งป้คใ
+settings.event_pull_request_milestone=้็จ็ข
+settings.event_pull_request_milestone_desc=้็จ็ข่ขซๆทปๅ ใ็งป้คๆไฟฎๆนใ
+settings.event_pull_request_comment=่ฏ่ฎบ
settings.event_pull_request_comment_desc=ๅๅนถ่ฏทๆฑ่ฏ่ฎบ่ขซๅๅปบใ็ผ่พๆๅ ้คใ
-settings.event_pull_request_review=ๅทฒๅฎกๆ ธ็ๅๅนถ่ฏทๆฑ
-settings.event_pull_request_review_desc=ๅๅนถ่ฏทๆฑ่ขซๆนๅใๆ็ปๆๆๅบๅฎกๆฅๆ่ง
-settings.event_pull_request_sync=ๅๅนถ่ฏทๆฑ่ขซๅๆญฅ
-settings.event_pull_request_sync_desc=ๅๅนถ่ฏทๆฑ่ขซๅๆญฅใ
-settings.event_pull_request_review_request=ๅ่ตทๅๅนถ่ฏทๆฑ่ฏๅฎก
-settings.event_pull_request_review_request_desc=ๅๅนถ่ฏทๆฑ่ฏๅฎกๅทฒ่ฏทๆฑๆๅทฒๅๆถ
+settings.event_pull_request_review=่ฏๅฎก
+settings.event_pull_request_review_desc=ๅๅนถ่ฏทๆฑ่ขซๆนๅใๆ็ปๆๆๅบ่ฏๅฎกๆ่งใ
+settings.event_pull_request_sync=่ขซๅๆญฅ
+settings.event_pull_request_sync_desc=ๅๆฏ่ชๅจๆดๆฐไธบ็ฎๆ ๅๆฏใ
+settings.event_pull_request_review_request=่ฏๅฎก่ฏทๆฑ
+settings.event_pull_request_review_request_desc=ๅๅนถ่ฏทๆฑ่ฏๅฎก่ขซ่ฏทๆฑๆ่ขซๅๆถใ
settings.event_pull_request_approvals=ๅๅนถ่ฏทๆฑๆนๅ
settings.event_pull_request_merge=ๅๅนถ่ฏทๆฑๅๅนถ
settings.event_package=่ฝฏไปถๅ
settings.event_package_desc=่ฝฏไปถๅ
ๅทฒๅจไปๅบไธญ่ขซๅๅปบๆๅ ้คใ
settings.branch_filter=ๅๆฏ่ฟๆปค
-settings.branch_filter_desc=ๆจ้ใๅๅปบ๏ผๅ ้คๅๆฏไบไปถ็ๅๆฏ็ฝๅๅ๏ผไฝฟ็จ glob ๆจกๅผๅน้
ๆๅฎใ่ฅไธบ็ฉบๆ *
๏ผๅๅฐๆฅๅๆๆๅๆฏ็ไบไปถใ่ฏญๆณๆๆกฃ่ง github.com/gobwas/glob ใ็คบไพ๏ผmaster
,{master,release*}
ใ
+settings.branch_filter_desc=ๆจ้ใๅๅปบ๏ผๅ ้คๅๆฏไบไปถ็ๅๆฏ็ฝๅๅ๏ผไฝฟ็จ glob ๆจกๅผๅน้
ๆๅฎใ่ฅไธบ็ฉบๆ *
๏ผๅๅฐๆฅๅๆๆๅๆฏ็ไบไปถใ่ฏญๆณๆๆกฃ่ง %[2]s ใ็คบไพ๏ผmaster
,{master,release*}
ใ
settings.authorization_header=ๆๆๆ ๅคด
-settings.authorization_header_desc=ๅฝๅญๅจๆถๅฐ่ขซไฝไธบๆๆๆ ๅคดๅ
ๅซๅจๅ
ใไพๅฆ: %sใ
+settings.authorization_header_desc=ๅฝๅญๅจๆถๅฐ่ขซไฝไธบๆๆๆ ๅคดๅ
ๅซๅจๅ
ใไพๅฆ๏ผ%sใ
settings.active=ๆฟๆดป
settings.active_helper=่งฆๅไบไปถ็ไฟกๆฏๅฐๅ้ๅฐๆญค webhook ็ฝๅใ
-settings.add_hook_success=Web ้ฉๅญๆทปๅ ๆๅ๏ผ
+settings.add_hook_success=Web ้ฉๅญๅทฒๆทปๅ ใ
settings.update_webhook=ๆดๆฐ Web ้ฉๅญ
-settings.update_hook_success=Web ้ฉๅญๆดๆฐๆๅ๏ผ
+settings.update_hook_success=Web ้ฉๅญๅทฒๆดๆฐใ
settings.delete_webhook=ๅ ้ค Web ้ฉๅญ
settings.recent_deliveries=ๆ่ฟๆจ้่ฎฐๅฝ
settings.hook_type=้ฉๅญ็ฑปๅ
@@ -2360,7 +2446,7 @@ settings.no_deploy_keys=ๆฒกๆ้จ็ฝฒๅฏ้ฅใ
settings.title=ๆ ้ข
settings.deploy_key_content=ๅฏ้ฅๆๆฌ
settings.key_been_used=ๅ
ทๆ็ธๅๅ
ๅฎน็้จ็ฝฒๅฏ้ฅๅทฒๅจไฝฟ็จไธญใ
-settings.key_name_used=ไฝฟ็จ็ธๅๅ็งฐ็้จ็ฝฒๅฏ้ฅๅทฒ็ปๅญๅจ๏ผ
+settings.key_name_used=ไฝฟ็จ็ธๅๅ็งฐ็้จ็ฝฒๅฏ้ฅๅทฒ็ปๅญๅจใ
settings.add_key_success=้จ็ฝฒๅฏ้ฅ %s ๆทปๅ ๆๅใ
settings.deploy_key_deletion=ๅ ้ค้จ็ฝฒๅฏ้ฅ
settings.deploy_key_deletion_desc=ๅ ้ค้จ็ฝฒๅฏ้ฅๅฐๅๆถๆญคๅฏ้ฅๅฏนๆญคไปๅบ็่ฎฟ้ฎๆ้ใ็ปง็ปญ๏ผ
@@ -2378,47 +2464,47 @@ settings.protect_this_branch_desc=้ปๆญขๅ ้คๅนถ้ๅถGitๆจ้ๅๅๅนถๅฐๅ
settings.protect_disable_push=็ฆ็จๆจ้
settings.protect_disable_push_desc=ๆญคๅๆฏไธๅ
่ฎธๆจ้ใ
settings.protect_enable_push=ๅฏ็จๆจ้
-settings.protect_enable_push_desc=ไปปไฝๆฅๆๅ่ฎฟ้ฎๆ้็ไบบๅฐ่ขซๅ
่ฎธๆจ้ๅฐๆญคๅๆฏ(ไฝไธ่ฝๅผบ่กๆจ้)ใ
+settings.protect_enable_push_desc=ไปปไฝๆฅๆๅ่ฎฟ้ฎๆ้็ไบบๅฐ่ขซๅ
่ฎธๆจ้ๅฐๆญคๅๆฏ๏ผไฝไธ่ฝๅผบ่กๆจ้๏ผใ
settings.protect_enable_merge=ๅฏ็จๅๅนถ
settings.protect_enable_merge_desc=ไปปไฝๅ
ทๆๅๅ
ฅๆ้็ไบบ้ฝๅฏไปฅๅฐๅๅนถ่ฏทๆฑๅๅนถๅฐๆญคๅๆฏไธญใ
settings.protect_whitelist_committers=ๅ็ฝๅๅ้ๅถ็ๆจ้
-settings.protect_whitelist_committers_desc=ๅชๆๅๅ
ฅ็ฝๅๅ็็จๆทๆๅข้ๆ่ฝ่ขซๅ
่ฎธๆจ้ๅฐๆญคๅๆฏ(ไฝไธ่ฝๅผบ่กๆจ้)ใ
-settings.protect_whitelist_deploy_keys=ๅ
ทๆๆจ้ๆ้็้จ็ฝฒๅฏ้ฅ็ฝๅๅใ
-settings.protect_whitelist_users=ๆจ้็ฝๅๅ็จๆท๏ผ
+settings.protect_whitelist_committers_desc=ๅชๆๅๅ
ฅ็ฝๅๅ็็จๆทๆๅข้ๆ่ฝ่ขซๅ
่ฎธๆจ้ๅฐๆญคๅๆฏ๏ผไฝไธ่ฝๅผบ่กๆจ้๏ผใ
+settings.protect_whitelist_deploy_keys=ๅฐๅ
ทๆๆจ้ๆ้็้จ็ฝฒๅฏ้ฅๅ ๅ
ฅ็ฝๅๅใ
+settings.protect_whitelist_users=ๆจ้็ฝๅๅ็จๆท
settings.protect_whitelist_search_users=ๆ็ดข็จๆท...
-settings.protect_whitelist_teams=ๆจ้็ฝๅๅๅข้๏ผ
+settings.protect_whitelist_teams=ๆจ้็ฝๅๅๅข้
settings.protect_whitelist_search_teams=ๆ็ดขๅข้...
settings.protect_merge_whitelist_committers=ๅฏ็จๅๅนถ็ฝๅๅ
settings.protect_merge_whitelist_committers_desc=ไป
ๅ
่ฎธ็ฝๅๅ็จๆทๆๅข้ๅๅนถๅๅนถ่ฏทๆฑๅฐๆญคๅๆฏใ
-settings.protect_merge_whitelist_users=ๅๅนถ็ฝๅๅ็จๆท๏ผ
-settings.protect_merge_whitelist_teams=ๅๅนถ็ฝๅๅๅข้๏ผ
+settings.protect_merge_whitelist_users=ๅๅนถ็ฝๅๅ็จๆท
+settings.protect_merge_whitelist_teams=ๅๅนถ็ฝๅๅๅข้
settings.protect_check_status_contexts=ๅฏ็จ็ถๆๆฃๆฅ
-settings.protect_status_check_patterns=็ถๆๆฃๆฅๆจกๅผ๏ผ
+settings.protect_status_check_patterns=็ถๆๆฃๆฅๆจกๅผ
settings.protect_status_check_patterns_desc=่พๅ
ฅๆจกๅผ๏ผๆๅฎๅชไบ็ถๆๆฃๆฅๅฟ
้กป้่ฟ๏ผๆ่ฝๅฐๅๆฏๅๅนถๅฐ็ฌฆๅๆญค่งๅ็ๅๆฏไธญๅปใๆฏไธ่กๆๅฎไธไธชๆจกๅผ๏ผๆจกๅผไธ่ฝไธบ็ฉบใ
settings.protect_check_status_contexts_desc=่ฆๆฑ็ถๆๆฃๆฅ้่ฟๆ่ฝๅๅนถ๏ผ้ๆฉๅฟ
้กปๅ
้่ฟๅชไบ็ถๆๆฃๆฅๆ่ฝๅๅนถใๅฆๆๅฏ็จ๏ผๆจ้็ๅๅนถ่ฏทๆฑๅฟ
้กปๅ
้่ฟ็ถๆๆฃๆฅๆ่ฝๅคๅๅนถๅฐๅฏนๅบ็ๅๆฏใๅฆๆๆฒกๆ้ๆฉๅ
ทไฝ็็ถๆๆฃๆฅไธไธๆ๏ผๅๆๆ็็ถๆๆฃๆฅ้ฝ้่ฟๆ่ฝๅๅนถใ
settings.protect_check_status_contexts_list=ๆญคไปๅบไธๅจ่ฟ่ก่ฟ็็ถๆๆฃๆฅ
settings.protect_status_check_matched=ๅน้
settings.protect_invalid_status_check_pattern=ๆ ๆ็็ถๆๆฃๆฅ่งๅ๏ผโ%sโใ
settings.protect_no_valid_status_check_patterns=ๆฒกๆๆๆ็็ถๆๆฃๆฅ่งๅใ
-settings.protect_required_approvals=ๆ้็ๆนๅ๏ผ
-settings.protect_required_approvals_desc=ๅชๅ
่ฎธๅๅนถๆ่ถณๅคๅฎกๆ ธไบบๆฐ็ๆๅ่ฏทๆฑใ
+settings.protect_required_approvals=ๆ้็ๆนๅ
+settings.protect_required_approvals_desc=ๅชๅ
่ฎธๅๅนถๆ่ถณๅค่ฏๅฎกไบบๆฐ็ๆๅ่ฏทๆฑใ
settings.protect_approvals_whitelist_enabled=ๆนๅไป
้ๅๅ
ฅ็ฝๅๅ็็จๆทๆๅข้
-settings.protect_approvals_whitelist_enabled_desc=ๅชๆ็ฝๅๅ็จๆทๆๅข้็ๅฎกๆ ธๆ่ฝ่ฎกๆฐใ ๆฒกๆๆนๅ็็ฝๅๅ๏ผๆฅ่ชไปปไฝๆๅ่ฎฟ้ฎๆ้็ไบบ็ๅฎกๆ ธ้ฝๅฐ่ฎกๆฐใ
-settings.protect_approvals_whitelist_users=ๅฎกๆฅ่
็ฝๅๅ๏ผ
-settings.protect_approvals_whitelist_teams=ๅฎกๆฅๅข้็ฝๅๅ๏ผ
+settings.protect_approvals_whitelist_enabled_desc=ๅชๆ็ฝๅๅ็จๆทๆๅข้็่ฏๅฎกๆ่ฝ่ขซ่ฎกๅ
ฅ้่ฆ็ๆนๅๆฐ้ใ ๆฒกๆ็ฝๅๅๆถ๏ผๆฅ่ชไปปไฝๆๅๅ
ฅๆ้็ไบบ็่ฏๅฎก้ฝๅฐ่ฎกๆฐใ
+settings.protect_approvals_whitelist_users=ๅฎกๆฅ่
็ฝๅๅ
+settings.protect_approvals_whitelist_teams=ๅฎกๆฅๅข้็ฝๅๅ
settings.dismiss_stale_approvals=ๅๆถ่ฟๆถ็ๆนๅ
settings.dismiss_stale_approvals_desc=ๅฝๆฐ็ๆไบคๆดๆนๅๅนถ่ฏทๆฑๅ
ๅฎน่ขซๆจ้ๅฐๅๆฏๆถ๏ผๆง็ๆนๅๅฐ่ขซๆค้ใ
-settings.ignore_stale_approvals=ๅฟฝ็ฅ่ฟๆๆนๅ
-settings.ignore_stale_approvals_desc=ๅฏนๆงๆไบค๏ผ่ฟๆๅฎกๆ ธ๏ผ็ๆนๅๅฐไธ่ฎกๅ
ฅ PR ็ๆนๅๆฐใๅฆๆ่ฟๆๅฎกๆฅๅทฒ่ขซ้ฉณๅ๏ผๅไธๆญคๆ ๅ
ณใ
+settings.ignore_stale_approvals = ๅฟฝ็ฅ่ฟๆถ็ๆนๅ
+settings.ignore_stale_approvals_desc = ไธๅฐๆง็ๆไบค๏ผ้ๆง็่ฏๅฎก๏ผ่ฎกๅ
ฅๅทฒๆนๅ็ๅๅนถ่ฏทๆฑๆฐ้ใๆณจ๏ผๅฆ่ฟๆ็่ฏๅฎกๅทฒ่ขซๅๆถ๏ผๅๆ ้่ฎพ็ฝฎใ
settings.require_signed_commits=้่ฆ็ญพๅๆไบค
-settings.require_signed_commits_desc=ๆ็ปๆจ้ๆช็ญพๅๆๆ ๆณ้ช่ฏ็ๆไบคๅฐๅๆฏ
+settings.require_signed_commits_desc=ๆ็ปๆจ้ๆช็ญพๅๆๆ ๆณ้ช่ฏ็ๆไบคๅฐๆญคๅๆฏใ
settings.protect_branch_name_pattern=ๅไฟๆค็ๅๆฏๅ็งฐๆญฃๅ
-settings.protect_branch_name_pattern_desc=ๅๆฏไฟๆค็ๅ็งฐๅน้
่งๅใ่ฏญๆณ่ฏทๅ้
ๆๆกฃ ใๅฆ๏ผmain, release/**
+settings.protect_branch_name_pattern_desc=ๅไฟๆค็ๅๆฏๅ็งฐๆญฃๅใ่ฏญๆณ่ฏทๅ้
ๆๆกฃ ใๅฆ๏ผmain, release/**
settings.protect_patterns=่งๅ
-settings.protect_protected_file_patterns=ๅไฟๆค็ๆไปถๆจกๅผ๏ผไฝฟ็จๅ่งๅๅทโ;โๅ้๏ผ๏ผ
-settings.protect_protected_file_patterns_desc=ๅณไฝฟ็จๆทๆๆๆทปๅ ใ็ผ่พๆๅ ้คๆญคๅๆฏไธญ็ๆไปถ๏ผไนไธๅ
่ฎธ็ดๆฅๆดๆนๅไฟๆค็ๆไปถใ ๅฏไปฅไฝฟ็จๅ่งๅๅท๏ผโ;โ๏ผๅ้ๅคไธชๆจกๅผใ ่งgithub.com/gobwas/glob ๆๆกฃไบ่งฃๆจกๅผ่ฏญๆณใไพๅฆ๏ผ .drone.yml
, /docs/**/*.txt
ใ
-settings.protect_unprotected_file_patterns=ไธๅไฟๆค็ๆไปถๆจกๅผ๏ผไฝฟ็จๅ่งๅๅทโ;โๅ้๏ผ๏ผ
-settings.protect_unprotected_file_patterns_desc=ๅจ็จๆทๆๅๆ้็ๆ
ๅตไธๅ
่ฎธ็ป่ฟ้ๅถ๏ผ็ดๆฅไฟฎๆน่ฎพไธบไธไฟๆค็ๆไปถใๅฆๆๅคไธชๅน้
ๆจกๅผ๏ผๅๅฏ็จๅ่งๅๅท๏ผโ;โ๏ผๅ้ๅผใ่ง github.com/gobwas/glob ็ๆๆกฃไปฅไบ่งฃๅน้
ๆจกๅผ็ๆ ผๅผใไพๅญ๏ผ .drone.yml
ใ/docs/**/*.txt
ใ
+settings.protect_protected_file_patterns=ๅไฟๆค็ๆไปถๆจกๅผ๏ผไฝฟ็จๅ่งๅๅทโ;โๅ้๏ผ
+settings.protect_protected_file_patterns_desc=ๅณไฝฟ็จๆทๆๆๆทปๅ ใ็ผ่พๆๅ ้คๆญคๅๆฏไธญ็ๆไปถ๏ผไนไธๅ
่ฎธ็ดๆฅๆดๆนๅไฟๆค็ๆไปถใ ๅฏไปฅไฝฟ็จๅ่งๅๅท๏ผโ;โ๏ผๅ้ๅคไธชๆจกๅผใ ่ง%[2]s ๆๆกฃไบ่งฃๆจกๅผ่ฏญๆณใไพๅฆ๏ผ.drone.yml
, /docs/**/*.txt
ใ
+settings.protect_unprotected_file_patterns=ไธๅไฟๆค็ๆไปถๆจกๅผ๏ผไฝฟ็จๅ่งๅๅทโ;โๅ้๏ผ
+settings.protect_unprotected_file_patterns_desc=ๅจ็จๆทๆๅๆ้็ๆ
ๅตไธๅ
่ฎธ็ป่ฟ้ๅถ๏ผ็ดๆฅไฟฎๆน่ฎพไธบไธไฟๆค็ๆไปถใๅฆๆๅคไธชๅน้
ๆจกๅผ๏ผๅๅฏ็จๅ่งๅๅท๏ผโ;โ๏ผๅ้ๅผใ่ง %[2]s ็ๆๆกฃไปฅไบ่งฃๅน้
ๆจกๅผ็ๆ ผๅผใไพๅญ๏ผ.drone.yml
ใ/docs/**/*.txt
ใ
settings.add_protected_branch=ๅฏ็จไฟๆค
settings.delete_protected_branch=็ฆ็จไฟๆค
settings.update_protect_branch_success=ๅๆฏไฟๆค่งๅ %s ๆดๆฐๆๅใ
@@ -2426,17 +2512,17 @@ settings.remove_protected_branch_success=็งป้คๅๆฏไฟๆค่งๅ"%s"ๆๅใ
settings.remove_protected_branch_failed=็งป้คๅๆฏไฟๆค่งๅ"%s"ๅคฑ่ดฅใ
settings.protected_branch_deletion=็ฆ็จๅๆฏไฟๆค
settings.protected_branch_deletion_desc=็ฆ็จๅๆฏไฟๆคๅ
่ฎธๅ
ทๆๅๅ
ฅๆ้็็จๆทๆจ้ๆไบคๅฐๆญคๅๆฏใ็ปง็ปญ๏ผ
-settings.block_rejected_reviews=ๆ็ปๅฎกๆ ธ้ปๆญขไบๆญคๅๅนถ
+settings.block_rejected_reviews=ๆๆ็ป่ฏๅฎกๆถ้ปๆญขๅๅนถ
settings.block_rejected_reviews_desc=ๅฆๆๅฎๆนๅฎกๆฅไบบๅ่ฆๆฑไฝๅบๆนๅจ๏ผๅณไฝฟๆ่ถณๅค็ๆนๅ๏ผๅๅนถไนไธๅ
่ฎธใ
-settings.block_on_official_review_requests=ๆๅฎๆนๅฎกๆ ธ้ปๆญขไบไปฃ็ ๅๅนถ
+settings.block_on_official_review_requests=ๆๅฎๆน่ฏๅฎก่ฏทๆฑๆถ้ปๆญขไปฃ็ ๅๅนถ
settings.block_on_official_review_requests_desc=ๅคไบ่ฏๅฎก็ถๆๆถ๏ผๅณไฝฟๆ่ถณๅค็ๆนๅ๏ผไนไธ่ฝๅๅนถใ
settings.block_outdated_branch=ๅฆๆๆๅ่ฏทๆฑๅทฒ็ป่ฟๆถ๏ผ้ปๆญขๅๅนถ
settings.block_outdated_branch_desc=ๅฝๅคด้จๅๆฏ่ฝๅๅบ็กๅๆฏๆถ๏ผไธ่ฝๅๅนถใ
settings.default_branch_desc=่ฏท้ๆฉไธไธช้ป่ฎค็ๅๆฏ็จไบๅๅนถ่ฏทๆฑๅๆไบค๏ผ
settings.merge_style_desc=ๅๅนถๆนๅผ
settings.default_merge_style_desc=้ป่ฎคๅๅนถๆนๅผ
-settings.choose_branch=้ๆฉไธไธชๅๆฏ...
-settings.no_protected_branch=ๆฒกๆๅไฟๆค็ๅๆฏ
+settings.choose_branch=้ๆฉไธไธชๅๆฏโฆ
+settings.no_protected_branch=ๆฒกๆๅๆฏๅๅฐไฟๆคใ
settings.edit_protected_branch=็ผ่พ
settings.protected_branch_required_rule_name=ๅฟ
้กปๅกซๅ่งๅๅ็งฐ
settings.protected_branch_duplicate_rule_name=่ฟไบๅๆฏๅทฒ่ฎพๆ่งๅ
@@ -2448,29 +2534,29 @@ settings.tags.protection.allowed=ๅ
่ฎธๅ่กจ
settings.tags.protection.allowed.users=ๅ
่ฎธ็่ดฆๅท
settings.tags.protection.allowed.teams=ๅ
่ฎธ็ๅข้
settings.tags.protection.allowed.noone=ๆ
-settings.tags.protection.create=ๆฐๅปบ่งๅ
-settings.tags.protection.none=ๆฒกๆๅไฟๆค็Gitๆ ็ญพ
-settings.tags.protection.pattern.description=ไฝ ๅฏไปฅไฝฟ็จๅไธชๅ็งฐๆ glob ๆจกๅผๅน้
ๆๆญฃๅ่กจ่พพๅผๆฅๅน้
ๅคไธชๆ ็ญพใไบ่งฃ่ฏฆๆ
่ฏท่ฎฟ้ฎ ๅไฟๆคGitๆ ็ญพๆๅ ใ
+settings.tags.protection.create=ๆทปๅ ่งๅ
+settings.tags.protection.none=ๆฒกๆGitๆ ็ญพๅๅฐไฟๆคใ
+settings.tags.protection.pattern.description=ไฝ ๅฏไปฅไฝฟ็จๅไธชๅ็งฐๆ glob ๆจกๅผๅน้
ๆๆญฃๅ่กจ่พพๅผๆฅๅน้
ๅคไธชๆ ็ญพใไบ่งฃ่ฏฆๆ
่ฏท่ฎฟ้ฎ ๅไฟๆคGitๆ ็ญพๆๅ ใ
settings.bot_token=ๆบๅจไบบไปค็
settings.chat_id=่ๅคฉ ID
settings.thread_id=็บฟ็จ ID
settings.matrix.homeserver_url=ไธปๆๅกๅจ็ฝๅ
settings.matrix.room_id=ๆฟ้ดID
settings.matrix.message_type=ๆถๆฏ็ฑปๅ
-settings.archive.button=ๅฝๆกฃไปๅบ
-settings.archive.header=ๅฝๆกฃๆญคไปๅบ
-settings.archive.text=ๅฝๆกฃไปๅบๅฐไฝฟๅ
ถๅฎๅ
จๅช่ฏปใๅฎๅฐๅจ้ฆ้กต้่ใๆฒกๆไบบ๏ผ็่ณไฝ ๏ผ๏ผ่ฝๅค่ฟ่กๆฐ็ๆไบค๏ผๆๆๅผๅทฅๅๅๅๅนถ่ฏทๆฑใ
-settings.archive.success=ไปๅบๅทฒๆๅๅฝๆกฃใ
-settings.archive.error=ไปๅบๅจๅฝๆกฃๆถๅบ็ฐๅผๅธธใ่ฏท้่ฟๆฅๅฟ่ทๅ่ฏฆ็ปไฟกๆฏใ
-settings.archive.error_ismirror=่ฏทไธ่ฆๅฏน้ๅไปๅบๅฝๆกฃ๏ผ่ฐข่ฐข๏ผ
-settings.archive.branchsettings_unavailable=ๅทฒๅฝๆกฃไปๅบๆ ๆณ่ฟ่กๅๆฏ่ฎพ็ฝฎใ
-settings.archive.tagsettings_unavailable=ๅทฒๅฝๆกฃไปๅบ็Gitๆ ็ญพ่ฎพ็ฝฎไธๅฏ็จใ
-settings.archive.mirrors_unavailable=ๅฆๆไปๅบๅทฒ่ขซๅฝๆกฃ๏ผ้ๅๅฐไธๅฏ็จใ
-settings.unarchive.button=ๆค้ไปๅบๅฝๆกฃ
-settings.unarchive.header=ๆค้ๆญคไปๅบๅฝๆกฃ
-settings.unarchive.text=ๆค้ๅฝๆกฃๅฐๆขๅคไปๅบๆฅๆถๆไบคใๆจ้๏ผไปฅๅๆฐๅทฅๅๅๅๅนถ่ฏทๆฑ็่ฝๅใ
-settings.unarchive.success=ไปๅบๅทฒๆๅๆค้ๅฝๆกฃใ
-settings.unarchive.error=ไปๅบๅจๅๆถๅฝๆกฃๆถๅบ็ฐๅผๅธธใ่ฏท้่ฟๆฅๅฟ่ทๅ่ฏฆ็ปไฟกๆฏใ
+settings.archive.button=ๅญๆกฃไปๅบ
+settings.archive.header=ๅญๆกฃๆญคไปๅบ
+settings.archive.text=ๅญๆกฃไปๅบๅฐไฝฟๅ
ถๅฎๅ
จๅช่ฏปใๅฎๅฐๅจ้ฆ้กต้่ใๆฒกๆไบบ๏ผ็่ณๅ
ๆฌไฝ ๏ผ๏ผ่ฝๅค่ฟ่กๆฐ็ๆไบค๏ผๆๆๅผๅทฅๅๅๅๅนถ่ฏทๆฑใ
+settings.archive.success=ไปๅบๅทฒๆๅๅญๆกฃใ
+settings.archive.error=ไปๅบๅจๅญๆกฃๆถๅบ็ฐๅผๅธธใ่ฏท้่ฟๆฅๅฟ่ทๅ่ฏฆ็ปไฟกๆฏใ
+settings.archive.error_ismirror=ไธ่ฝๅญๆกฃ้ๅไปๅบใ
+settings.archive.branchsettings_unavailable=ๅๆฏ่ฎพ็ฝฎๅฏนๅทฒๅญๆกฃ็ไปๅบไธๅฏ็จใ
+settings.archive.tagsettings_unavailable=ๆ ็ญพ่ฎพ็ฝฎๅฏนๅทฒๅญๆกฃ็ไปๅบไธๅฏ็จใ
+settings.archive.mirrors_unavailable = ้ๅๅฏนๅทฒๅญๆกฃ็ไปๅบไธๅฏ็จใ
+settings.unarchive.button=ๆค้ไปๅบๅญๆกฃ
+settings.unarchive.header=ๆค้ๆญคไปๅบๅญๆกฃ
+settings.unarchive.text=ๆค้ๅญๆกฃๅฐๆขๅคไปๅบๆฅๆถๆไบคใๆจ้๏ผไปฅๅๆฐๅทฅๅๅๅๅนถ่ฏทๆฑ็่ฝๅใ
+settings.unarchive.success=ไปๅบๅทฒๆๅๆค้ๅญๆกฃใ
+settings.unarchive.error=ไปๅบๅจๅๆถๅญๆกฃๆถๅบ็ฐๅผๅธธใ่ฏท้่ฟๆฅๅฟ่ทๅ่ฏฆ็ปไฟกๆฏใ
settings.update_avatar_success=ไปๅบๅคดๅๅทฒ็ปๆดๆฐใ
settings.lfs=LFS
settings.lfs_filelist=ๅญๅจๅจๆญคไปๅบไธญ็ LFS ๆไปถ
@@ -2486,11 +2572,11 @@ settings.lfs_invalid_locking_path=ๆ ๆ่ทฏๅพ๏ผ%s
settings.lfs_invalid_lock_directory=ๆ ๆณ้ๅฎ็ฎๅฝ๏ผ%s
settings.lfs_lock_already_exists=้ๅทฒ็ปๅญๅจ๏ผ%s
settings.lfs_lock=้ๅฎ
-settings.lfs_lock_path=่ฆ้ๅฎ็ๆไปถ่ทฏๅพ...
+settings.lfs_lock_path=่ฆ้ๅฎ็ๆไปถ่ทฏๅพโฆ
settings.lfs_locks_no_locks=ๆ ้ๅฎ
settings.lfs_lock_file_no_exist=้ๅฎ็ๆไปถๅจ้ป่ฎคๅๆฏไธญไธๅญๅจ
settings.lfs_force_unlock=ๅผบๅถ่งฃ้
-settings.lfs_pointers.found=ๆพๅฐ %d ไธชๅๆ้ - %d ไธชๅ
ณ่๏ผ %d ไธชๆชๅ
ณ่(%d ไธชไปไปๅบไธขๅคฑ)
+settings.lfs_pointers.found=ๆพๅฐ %d ไธชๅๆ้ - %d ไธชๅ
ณ่๏ผ %d ไธชๆชๅ
ณ่๏ผ%d ไธชไปไปๅบไธขๅคฑ๏ผ
settings.lfs_pointers.sha=Blob SHA
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=ๅจไปๅบไธญ
@@ -2507,7 +2593,7 @@ settings.rename_branch=้ๅฝๅๅๆฏ
diff.browse_source=ๆต่งไปฃ็
diff.parent=็ถ่็น
diff.commit=ๅฝๅๆไบค
-diff.git-notes=Notes
+diff.git-notes=ๆณจ้
diff.data_not_available=ๆฏ่พๅ
ๅฎนไธๅฏ็จ
diff.options_button=Diff ้้กน
diff.show_diff_stats=ๆพ็คบ็ป่ฎกไฟกๆฏ
@@ -2521,7 +2607,7 @@ diff.whitespace_ignore_all_whitespace=ๆฏ่พ่กๆถๅฟฝ็ฅ็ฉบ็ฝ็ฌฆๅท
diff.whitespace_ignore_amount_changes=ๅฟฝ็ฅ็ฉบ็ฝ็ฌฆๅทๆฐ้็ๅๅ
diff.whitespace_ignore_at_eol=ๅฟฝ็ฅ่กๆซ็ฉบ็ฝ็ฌฆๅท็ๆดๆน
diff.stats_desc=ๅ
ฑๆ %d ไธชๆไปถ่ขซๆดๆน ๏ผๅ
ๆฌ %d ๆฌกๆๅ
ฅ ๅ %d ๆฌกๅ ้ค
-diff.stats_desc_file=ๅๆด %d ่ก๏ผๆฐๅข %d ่ก๏ผๅ ้ค %d ่ก
+diff.stats_desc_file=ๆดๆน %d ่ก๏ผๆฐๅข %d ่ก๏ผๅ ้ค %d ่ก
diff.bin=ไบ่ฟๅถ
diff.bin_not_shown=ไบ่ฟๅถๆไปถๆชๆพ็คบใ
diff.view_file=ๆฅ็ๆไปถ
@@ -2535,22 +2621,22 @@ diff.file_suppressed_line_too_long=ๆไปถๅทฎๅผๅ ไธ่กๆๅค่ก่ฟ้ฟ่้่
diff.too_many_files=ๆไบๆไปถๆชๆพ็คบ๏ผๅ ไธบๆญค diff ไธญๆดๆน็ๆไปถๅคชๅค
diff.show_more=ๆพ็คบๆดๅค
diff.load=ๅ ่ฝฝๅทฎๅผ
-diff.generated=่ชๅจ็ๆ็
-diff.vendored=vendored
+diff.generated=่ชๅจ็ๆ
+diff.vendored=Vendored
diff.comment.add_line_comment=ๆทปๅ ่กๅ
่ฏ่ฎบ
diff.comment.placeholder=็ไธ่ฏ่ฎบ
-diff.comment.markdown_info=ๆฏๆไฝฟ็จMarkdownๆ ผๅผใ
+diff.comment.markdown_info=ๆฏๆไฝฟ็จ Markdown ๆ ผๅผใ
diff.comment.add_single_comment=ๆทปๅ ๅๆก่ฏ่ฎบ
diff.comment.add_review_comment=ๆทปๅ ่ฏ่ฎบ
diff.comment.start_review=ๅผๅง่ฏๅฎก
diff.comment.reply=ๅๅค
-diff.review=ๅฎๆๅฎกๆ ธ
+diff.review=ๅฎๆ่ฏๅฎก
diff.review.header=ๆไบค่ฏๅฎก
diff.review.placeholder=่ฏๅฎกๆ่ง
diff.review.comment=่ฏ่ฎบ
-diff.review.approve=้่ฟ
+diff.review.approve=ๆนๅ
diff.review.self_reject=ๅๅนถ่ฏทๆฑไฝ่
ไธ่ฝๅฏน่ชๅทฑ็ๅๅนถ่ฏทๆฑๆดๆน
-diff.review.reject=่ฏทๆฑๅๆด
+diff.review.reject=่ฏทๆฑๆดๆน
diff.review.self_approve=ๅๅนถ่ฏทๆฑไฝ่
ไธ่ฝๆนๅ่ชๅทฑ็ๅๅนถ่ฏทๆฑ
diff.committed_by=ๆไบค่
diff.protected=ๅไฟๆค็
@@ -2597,11 +2683,11 @@ release.deletion=ๅ ้คๅๅธ
release.deletion_desc=ๅ ้ค็ๆฌๅๅธๅชไผไป Forgejo ไธญ็งป้คใ่ฟไธไผๅฝฑๅ Git ็ๆ ็ญพไปฅๅๆจไปๅบ็ๅ
ๅฎนๅๅๅฒใๆฏๅฆ็ปง็ปญ๏ผ
release.deletion_success=Releaseๅทฒ่ขซๅ ้คใ
release.deletion_tag_desc=ๅฐไปไปๅบไธญๅ ้คๆญค Gitๆ ็ญพใไปๅบๅ
ๅฎนๅๅๅฒ่ฎฐๅฝไฟๆไธๅใ็ปง็ปญๅ๏ผ
-release.deletion_tag_success=่ฏฅ Gitๆ ็ญพ ๅทฒ็ป่ขซๅ ้ค
+release.deletion_tag_success=่ฏฅ Git ๆ ็ญพๅทฒ่ขซๅ ้คใ
release.tag_name_already_exist=ไฝฟ็จๆญคๆ ็ญพๅ็งฐ็ๅๅธ็ๆฌๅทฒ็ปๅญๅจใ
release.tag_name_invalid=ๆ ็ญพๅ็งฐๆ ๆใ
release.tag_name_protected=Gitๆ ็ญพๅ็งฐๅทฒๅไฟๆคใ
-release.tag_already_exist=ๆญค Gitๆ ็ญพ ๅ็งฐๅทฒๅญๅจ
+release.tag_already_exist=ๆญค Git ๆ ็ญพๅทฒๅญๅจใ
release.downloads=ไธ่ฝฝ้ไปถ
release.download_count=ไธ่ฝฝ๏ผ%s
release.add_tag_msg=ไฝฟ็จๅๅธ็ๆ ้ขๅๅ
ๅฎนไฝไธบๆ ็ญพๆถๆฏใ
@@ -2611,14 +2697,14 @@ release.tags_for=%s ็ๆ ็ญพ
branch.name=ๅๆฏๅ็งฐ
branch.already_exists=ๅไธบ %s ็ๅๆฏๅทฒๅญๅจใ
-branch.delete_head=ๅช้ค
+branch.delete_head=ๅ ้ค
branch.delete=ๅ ้คๅๆฏ "%s"
branch.delete_html=ๅ ้คๅๆฏ
branch.delete_desc=ๅ ้คๅๆฏๆฏๆฐธไน
็ใ่ฝ็ถๅทฒๅ ้ค็ๅๆฏๅจๅฎ้
่ขซๅ ้คๅๆๅฏ่ฝไผ็ญๆถ้ดๅญๅจ๏ผไฝ่ฟๅจๅคงๅคๆฐๆ
ๅตไธๆ ๆณๆค้ใๆฏๅฆ็ปง็ปญ๏ผ
branch.deletion_success=ๅๆฏ %s ๅทฒ่ขซๅ ้คใ
branch.deletion_failed=ๅ ้คๅๆฏ %s ๅคฑ่ดฅใ
branch.delete_branch_has_new_commits=ๅ ไธบๅๅนถไนๅๆๆฐ็ๆไบค๏ผๅๆฏ %s ๆ ๆณ่ขซๅ ้คใ
-branch.create_branch=ๅๅปบๅๆฏ %s
+branch.create_branch=ๅๅปบๅๆฏ %s
branch.create_from=ไป %s
branch.create_success=ๅๆฏ '%s' ๅทฒๅๅปบใ
branch.branch_already_exists=ๆญคไปๅบๅทฒๅญๅจๅไธบ %s ็ๅๆฏใ
@@ -2645,19 +2731,19 @@ branch.new_branch=ๅๅปบๆฐๅๆฏ
branch.new_branch_from=ๅบไบ"%s"ๅๅปบๆฐๅๆฏ
branch.renamed=ๅๆฏ %s ่ขซ้ๅฝๅไธบ %sใ
-tag.create_tag=ๅๅปบๆ ็ญพ %s
+tag.create_tag=ๅๅปบๆ ็ญพ %s
tag.create_tag_operation=ๅๅปบๆ ็ญพ
tag.confirm_create_tag=ๅๅปบๆ ็ญพ
tag.create_tag_from=ๅบไบ"%s"ๅๅปบๆฐๆ ็ญพ
-tag.create_success=ๆ ็ญพ"%s"ๅทฒๅญๅจ
+tag.create_success=ๅทฒๅๅปบๆ ็ญพโ%sโใ
topic.manage_topics=็ฎก็ไธป้ข
topic.done=ไฟๅญ
topic.count_prompt=ๆจๆๅค้ๆฉ25ไธชไธป้ข
topic.format_prompt=ไธป้ขๅฟ
้กปไปฅๅญๆฏๆๆฐๅญๅผๅคด๏ผๅฏไปฅๅ
ๅซๅ่ง่ฟๅญ็ฌฆ๏ผโ-โ๏ผๅๅฅ็น๏ผโ.โ๏ผ๏ผ้ฟๅบฆไธๅพ่ถ
่ฟ35ไธชๅญ็ฌฆใๅญ็ฌฆๅฟ
้กปไธบๅฐๅใ
-find_file.go_to_file=่ฝฌๅฐๆไปถ
+find_file.go_to_file=ๆฅๆพๆไปถ
find_file.no_matching=ๆฒกๆๆพๅฐๅน้
็ๆไปถ
error.csv.too_large=ๆ ๆณๆธฒๆๆญคๆไปถ๏ผๅ ไธบๅฎๅคชๅคงไบใ
@@ -2670,23 +2756,16 @@ rss.must_be_on_branch = ๆจๅฟ
้กปๅคไบไธไธชๅๆฏไธๆ่ฝๆฅๆไธไธชRSS่ฎข
admin.manage_flags = ็ฎก็ๆ ๅฟ
admin.failed_to_replace_flags = ๆฟๆขไปๅบๆ ๅฟๅคฑ่ดฅ
clone_in_vscodium = ๅจ VSCodium ไธญๅ
้
-object_format_helper = ไปๅบ็ๅฏน่ฑกๆ ผๅผ๏ผไธๆฆ่ฎพ็ฝฎๆ ๆณๆดๆนใSHA1็ๅ
ผๅฎนๆงๆๅผบใ
-object_format = ๅฏน่ฑกๆ ผๅผ
-mirror_sync = ๅทฒๅๆญฅ
-vendored = Vendored
-issues.blocked_by_user = ไฝ ๆ ๆณๅจๆญคไปๅบๅๅปบๅทฅๅ๏ผๅ ไธบไฝ ๅทฒ่ขซไปๅบๆๆ่
ๅฑ่ฝใ
-issues.comment.blocked_by_user = ไฝ ๆ ๆณๅฏนๆญคๅทฅๅ่ฟ่ก่ฏ่ฎบ๏ผๅ ไธบไฝ ๅทฒ่ขซไปๅบๆๆ่
ๆๆญคๅทฅๅ็ๅๅธ่
ๅฑ่ฝใ
-settings.wiki_rename_branch_main_desc = ๅฐ็พ็งๅ
้จไฝฟ็จ็ๅๆฏ้ๅฝๅไธบโ%sโใ ๆญคๆไฝๆฏๆฐธไน
ๆง็ไธไธๅฏๆคๆถใ
-generated = ๅทฒ็ๆ
+issues.blocked_by_user = ็ฑไบไฝ ๅทฒ่ขซไปๅบๆๆ่
ๅฑ่ฝ๏ผไฝ ๆ ๆณๅจๆญคไปๅบๅๅปบๅทฅๅใ
+issues.comment.blocked_by_user = ๅ ไธบไฝ ๅทฒ่ขซไปๅบๆๆ่
ๆๅทฅๅไฝ่
ๅฑ่ฝ๏ผไฝ ๆ ๆณๅฏนๆญคๅทฅๅ่ฟ่ก่ฏ่ฎบใ
+settings.wiki_rename_branch_main_desc = ๅฐ็พ็งๅ
้จไฝฟ็จ็ๅๆฏ้ๅฝๅไธบโ%sโใๆญคๆดๆนๆฏๆฐธไน
ๆง็ไธไธๅฏๆค้ใ
editor.invalid_commit_mail = ็จไบๅๅปบๆไบค็้ฎไปถๅฐๅๆ ๆใ
-pulls.blocked_by_user = ไฝ ๆ ๆณๅจๆญคๅญๅจๅบไธๅๅปบๅๅนถ่ฏทๆฑ๏ผๅ ไธบๆจๅทฒ่ขซไปๅบๆๆ่
ๅฑ่ฝใ
+pulls.blocked_by_user = ไฝ ๆ ๆณๅจๆญคไปๅบไธๅๅปบๅๅนถ่ฏทๆฑ๏ผๅ ไธบๆจๅทฒ่ขซไปๅบๆๆ่
ๅฑ่ฝใ
migrate.forgejo.description = ไป codeberg.org ๆๅ
ถไป Forgejo ๅฎไพ่ฟ็งปๆฐๆฎใ
commits.browse_further = ๆต่งๆดๅค
commits.renamed_from = ้ๅฝๅ่ช %s
-pulls.nothing_to_compare_have_tag = ๆ้ๅๆฏ/ๆ ็ญพ็ธๅใ
wiki.cancel = ๅๆถ
settings.wiki_globally_editable = ๅ
่ฎธไปปไฝไบบ็ผ่พ็พ็ง
-settings.mirror_settings.pushed_repository = ๅทฒๆจ้็ไปๅบ
settings.new_owner_blocked_doer = ๆฐๆๆ่
ๅทฒๅฐไฝ ๆ้ปใ
settings.enter_repo_name = ่พๅ
ฅๆๆ่
ๅไปๅบ็ๅ็งฐ๏ผ
settings.wiki_rename_branch_main = ๆ ๅๅ็พ็งๅๆฏๅ็งฐ
@@ -2694,18 +2773,14 @@ settings.wiki_rename_branch_main_notices_1 = ๆญคๆไฝๆ ๆณ ๆค
settings.wiki_branch_rename_success = ็พ็งไปๅบ็ๅๆฏๅ็งฐๅทฒๆๅ่ง่ๅใ
settings.confirm_wiki_branch_rename = ้ๅฝๅ็พ็งๅๆฏ
pulls.commit_ref_at = `ๅจๆไบค %[2]s ไธญๅผ็จไบๆญคๅๅนถ่ฏทๆฑ`
-desc.sha256 = SHA256
-settings.ignore_stale_approvals = ๅฟฝ็ฅ่ฟๆถ็ๆนๅ
-settings.ignore_stale_approvals_desc = ไธๅฏนๆง็ๆไบค๏ผ่ฟๆถ็ๅฎกๆฅ๏ผ่ฎกๅ
ฅๅทฒๆนๅ็ๅๅนถ่ฏทๆฑๆฐ้ใๆณจ๏ผๅฆ่ฟๆ็ๅฎกๆ ธๅทฒ่ขซๅๆถ๏ผๅๆ ้่ฎพ็ฝฎใ
-settings.archive.mirrors_unavailable = ไธ่ฝ้ๅๅทฒๅฝๆกฃ็ไปๅบใ
-settings.wiki_rename_branch_main_notices_2 = ่ฟๅฐ้ขๅ
้ๅฝๅ %s ็ๅญๅจๅบ็พ็ง็ๅ
้จๅๆฏใ ็ฐๅญ็ๆฃๅบๆนๅผ้่ฆๆดๆฐใ
-settings.wiki_branch_rename_failure = ๆ ๆณๆ ๅๅๅญๅจๅบ็พ็ง็ๅๆฏๅ็งฐใ
+settings.wiki_rename_branch_main_notices_2 = ่ฟๅฐๆฐธไน
้ๅฝๅ %s ็ไปๅบ็พ็ง็ๅ
้จๅๆฏใ็ฐๅญ็ๆฃๅบๆนๅผ้่ฆๆดๆฐใ
+settings.wiki_branch_rename_failure = ๆ ๆณๆ ๅๅไปๅบ็พ็ง็ๅๆฏๅ็งฐใ
settings.add_collaborator_blocked_our = ๅ ไปๅบๆๆ่
ๅทฒๅฐๅ
ถๆ้ป๏ผไธ่ฝๆทปๅ ่ฏฅ็จๆทไธบๅไฝ่
ใ
settings.add_collaborator_blocked_them = ๅ ่ฏฅ็จๆทๅทฒๅฐไปๅบๆๆ่
ๆ้ป๏ผไธ่ฝๆทปๅ ่ฏฅ็จๆทไธบๅไฝ่
ใ
settings.units.units = ไปๅบๅ่ฝ
pulls.fast_forward_only_merge_pull_request = ไป
ๅฟซ้ๅๅ
settings.units.overview = ๆฆ่ง
-settings.units.add_more = ๆทปๅ ๆดๅคโฆ
+settings.units.add_more = ๅฏ็จๆดๅค
file_follow = ่ท้็ฌฆๅท้พๆฅ
pulls.reopen_failed.head_branch = ๅ ๅคด้จๅๆฏไธๅๅญๅจ๏ผ่ฏฅๅๅนถ่ฏทๆฑไธ่ฝๅ่ขซ้ๆฐๆๅผใ
pulls.reopen_failed.base_branch = ๅ ๅบ็กๅๆฏไธๅๅญๅจ๏ผ่ฏฅๅๅนถ่ฏทๆฑไธ่ฝๅ่ขซ้ๆฐๆๅผใ
@@ -2713,12 +2788,12 @@ pulls.made_using_agit = AGit
activity.navbar.pulse = ๅจๆ
activity.navbar.code_frequency = ไปฃ็ ้ข็
activity.navbar.recent_commits = ่ฟๆๆไบค
-pulls.agit_explanation = ่ฏฅๅๅนถ่ฏทๆฑๆฏ็จ AGit ๅๅปบ็ใAGit ๆฏไธ็งๅฏไปฅ่ฎฉ่ดก็ฎ่
็ดๆฅ้่ฟ โgit pushโ ๆๅบๆดๆนไปฃ็ ่ไธ้่ฆๆดพ็ๆๅปบ็ซๆฐๅๆฏใ
+pulls.agit_explanation = ่ฏฅๅๅนถ่ฏทๆฑๆฏ็จ AGit ๅทฅไฝๆตๅๅปบ็ใไฝฟ็จ AGit๏ผ่ดก็ฎ่
ๆ ้ๆดพ็ๆๅๅปบๅๆฏๅฐฑๅฏไปฅ็ดๆฅ้่ฟ โgit pushโ ๆๅบๆดๆนไปฃ็ ใ
error.broken_git_hook = ่ฏฅไปๅบ็ Git ้ฉๅญไผผไนๅทฒ็ปๆๅ๏ผ่ฏทๆ็
ง ๆญคๆๆกฃ ๆฅไฟฎๅค่ฟไบ้ฎ้ข๏ผ็ถๅๆจ้ไธไบๆไบคๆฅๅทๆฐ็ถๆใ
pulls.merged_title_desc_one = ๅทฒๅฐๆฅ่ช %[2]s
็ %[1]d ๆไบคๅๅนถๅ
ฅ %[3]s
%[4]s
commits.search_branch = ๆญคๅๆฏ
open_with_editor = ไฝฟ็จ %s ๆๅผ
-pulls.title_desc_one = ๆณ่ฆๅฐๆฅ่ช %[2]s
็ %[1]d ๆไบคๅๅนถๅฐ %[3]s
+pulls.title_desc_one = ๆณ่ฆๅฐๆฅ่ช %[2]s
็ %[1]d ็ฌๆไบคๅๅนถๅฐ %[3]s
settings.rename_branch_failed_protected = ๆ ๆณ้ๅฝๅๅไฟๆค็ๅๆฏ %sใ
stars = ็น่ต
settings.confirmation_string = ็กฎ่ฎค่พๅ
ฅ
@@ -2729,13 +2804,13 @@ n_branch_few = %s ๅๆฏ
n_tag_one = %s ๆ ็ญพ
n_tag_few = %s ๆ ็ญพ
editor.commit_id_not_matching = ๆจๅจ็ผ่พๆไปถๆถ่ฏฅๆไปถๅทฒ่ขซๆดๆนใ่ฏทๆไบคๅฐไธไธชๆฐ็ๅๆฏ๏ผ็ถๅๅๅฐ่ฟไธชๆฐ็ๅๆฏๅๅนถๅๅฝๅๅๆฏใ
-issues.num_participants_one = %d ไธชๅไธ่
-issues.archived_label_description = ๏ผๅทฒๅฝๆกฃ๏ผ%s
+issues.num_participants_one = %d ไฝๅไธ่
+issues.archived_label_description = ๏ผๅทฒๅญๆกฃ๏ผ%s
editor.push_out_of_date = ๆจ้ไผผไนๅทฒ่ฟๆใ
settings.enforce_on_admins = ๅฏนไปๅบ็็ฎก็ๅ้็จ่ฏฅ่งๅ
settings.enforce_on_admins_desc = ไฝฟไปๅบ็ฎก็ๅไน้กป้ตๅฎๆญค่งๅใ
settings.sourcehut_builds.secrets = ๅฏ้ฅ
-size_format = %[1]s: %[2]s, %[3]s: %[4]s
+size_format = %[1]s๏ผ%[2]s, %[3]s๏ผ%[4]s
settings.sourcehut_builds.graphql_url = GraphQL URL (ไพๅฆ๏ผ https://builds.sr.ht/query)
settings.add_webhook.invalid_path = ่ทฏๅพไธญไธ่ฝๅ
ๅซโ.โๆโ..โ๏ผไนไธ่ฝๅจๅผๅคดๆ็ปๅฐพไธญไฝฟ็จๆๆ ใ
settings.sourcehut_builds.secrets_helper = ็ปไบไปปๅก่ฎฟ้ฎๆๅปบๅฏ้ฅ็ๆ้๏ผ้่ฆ SECRETS:RO ๆ้๏ผ
@@ -2743,7 +2818,7 @@ release.download_count_one = %s ไธ่ฝฝ
release.download_count_few = %s ไธ่ฝฝ
release.system_generated = ๆญค้ไปถๆฏ่ชๅจ็ๆ็ใ
pulls.ready_for_review = ๅๅคๅฅฝๆฅๅ่ฏๅฎกไบๅ๏ผ
-settings.web_hook_name_sourcehut_builds = SourceHut ๆๅปบ
+settings.web_hook_name_sourcehut_builds = SourceHut Builds
settings.graphql_url = GraphQL URL ้พๆฅ
settings.sourcehut_builds.access_token_helper = ๅทฒๆไบ JOBS:RW ๆ้็่ฎฟ้ฎไปค็ใๅฏๅจ meta.sr.ht ไธ็ๆๆ ๅ็ builds.sr.ht ไปค็ ๆๅธฆๆๅฏๅ่ฎฟ้ฎๆ้็ builds.sr.ht ไปค็ ใ
settings.matrix.access_token_helper = ๆจ่ไธบๆญค่ฎพ็ซไธ้จ็ Matrix ่ดฆๆทใ่ฎฟ้ฎไปค็ๅฏไป Element Web ๅฎขๆท็ซฏ๏ผๅจ้็ง/ๆ ็ๆจกๅผ้้กนๅกไธญๆๅผ๏ผ> ็จๆท่ๅ๏ผๅทฆไธ่ง๏ผ> ๆๆ่ฎพ็ฝฎ > ๅธฎๅฉๅๅ
ณไบ > ้ซ็บง > ่ฎฟ้ฎไปค็๏ผๅจไธปๆๅกๅจ URL ไธๆน๏ผๆฃ็ดขใ่ทๅๅฎๆๅ๏ผ่ฏท็ดๆฅๅ
ณ้ญ้็ง/ๆ ็้้กนๅก๏ผๆณจ้ไผไฝฟไปค็ๅคฑๆ๏ผใ
@@ -2765,14 +2840,80 @@ issues.edit.already_changed = ๆ ๆณไฟๅญๅฏนๅทฅๅ็ๆดๆนใๅทฅๅไผผไนๅทฒ
pulls.edit.already_changed = ๆ ๆณไฟๅญๅฏนๅๅนถ่ฏทๆฑ็ๆดๆนใๅ
ๅฎนไผผไนๅทฒ็ป่ขซๅฆไธไธช็จๆทไฟฎๆนไบ๏ผไธบไบ้ฒๆญขไฟฎๆน่ขซ่ฆ็๏ผ่ฏทๅทๆฐ้กต้ขๅๅๆฌกๅฐ่ฏ็ผ่พ
comments.edit.already_changed = ๆ ๆณไฟๅญๅฏน่ฏ่ฎบ็ๆดๆนใๅ
ๅฎนไผผไนๅทฒ็ป่ขซๅฆไธไธช็จๆทไฟฎๆนไบ๏ผไธบไบ้ฒๆญขไฟฎๆน่ขซ่ฆ็๏ผ่ฏทๅทๆฐ้กต้ขๅๅๆฌกๅฐ่ฏ็ผ่พ
subscribe.issue.guest.tooltip = ็ปๅฝไปฅ่ฎข้
ๅทฅๅใ
-subscribe.pull.guest.tooltip = ็ปๅฝไปฅ่ฎข้
ๆญคๆๅ่ฏทๆฑใ
-settings.federation_following_repos = ๅ
ณๆณจไปๅบ็ URLใไปฅโ;โๅ้๏ผๆ ็ฉบๆ ผใ
+subscribe.pull.guest.tooltip = ็ปๅฝไปฅ่ฎข้
ๆญคๅๅนถ่ฏทๆฑใ
+settings.federation_following_repos = ๅ
ณๆณจ็ไปๅบURLๅฐๅ๏ผๅคไธชๅฐๅไปฅ โ;โ ๅ้๏ผไธ้่ฆๅๅ็ฉบๆ ผใ
settings.federation_settings = ้ฆ่่ฎพ็ฝฎ
settings.federation_apapiurl = ๆญคไปๅบ็้ฆ่URLๅฐๅใๅฐๅ
ถไฝไธบๅ
ณๆณจ็ไปๅบURLๅฐๅๅกซๅๅฐๅฆไธไธชไปๅบ็้ฆ่่ฎพ็ฝฎไธญใ
settings.federation_not_enabled = ๅฝๅๅฎไพๆชๅฏ็จ้ฆ่ๅ่ฝใ
+issues.author.tooltip.issue = ๆญค็จๆทๆฏๆฌๅทฅๅ็ไฝ่
ใ
+issues.author.tooltip.pr = ๆญค็จๆทๆฏๆญคๅๅนถ่ฏทๆฑ็ไฝ่
ใ
+release.type_attachment = ้ไปถ
+release.type_external_asset = ๅค้จ่ตๆบ
+release.asset_name = ่ตๆบๅ็งฐ
+release.asset_external_url = ๅค้จ URL
+release.add_external_asset = ๆทปๅ ๅค้จ่ตๆบ
+release.invalid_external_url = ๆ ๆ็ๅค้จ URL๏ผโ%sโ
+milestones.filter_sort.name = ๅ็งฐ
+settings.pull_mirror_sync_quota_exceeded = ่ถ
ๅบ้
้ข๏ผๆชๆๅๆดๆนใ
+settings.transfer_quota_exceeded = ๆฐๆๆ่
๏ผ%s๏ผๅทฒ่ถ
ๅบ้
้ขใไปๅบๅฐๆช่ฝฌ็งปใ
+no_eol.tooltip = ๆญคๆไปถไธๅ
ๅซ่กๅฐพๅญ็ฌฆใ
+no_eol.text = ๆ ่กๅฐพ
+activity.published_tag_label = ๆ ็ญพ
+activity.published_prerelease_label = ้ขๅ่ก
+activity.commit = ๆไบคๆดปๅจ
+pulls.cmd_instruction_merge_warning = ่ญฆๅ๏ผ ๆชๅฏ็จๆญคไปๅบ็โ่ชๅจๆฃๆตๆๅจๅๅนถโ่ฎพ็ฝฎ๏ผๆจไนๅๅฟ
้กปๅฐๆญคๅๅนถ่ฏทๆฑๆ ่ฎฐไธบๆๅจๅๅนถใ
+settings.protect_new_rule = ๅๅปบๆฐ็ๅๆฏไฟๆค่งๅ
+mirror_denied_combination = ไธ่ฝๅๆถไฝฟ็จๅ
ฌ้ฅๅๅบไบๅฏ็ ็้ช่ฏใ
+mirror_public_key = ๅ
ฌๅ
ฑ SSH ๅฏ้ฅ
+mirror_use_ssh.text = ไฝฟ็จ SSH ้ช่ฏ
+mirror_use_ssh.helper = ้ๆฉๆญค้้กนๅ๏ผForgejo ๅฐ้่ฟ SSH ไปฅ Git ๆนๅผ้ๅไปๅบ๏ผๅนถไธบๆจๅๅปบไธไธชๅฏ้ฅๅฏนใๆจๅฟ
้กป็กฎไฟๅทฒๆๆ็ๆ็ๅ
ฌ้ฅๆจ้ๅฐ็ฎๆ ไปๅบใ้ๆฉๆญค้้กนๆถ๏ผไธ่ฝไฝฟ็จๅบไบๅฏ็ ็ๆๆใ
+settings.mirror_settings.push_mirror.copy_public_key = ๅคๅถๅ
ฌ้ฅ
+settings.mirror_settings.push_mirror.none_ssh = ๆ
+mirror_use_ssh.not_available = SSH ้ช่ฏไธๅฏ็จใ
+issues.new.assign_to_me = ๆๆดพ็ปๆ
+issues.all_title = ๅ
จ้จ
+settings.discord_icon_url.exceeds_max_length = ๅพๆ URL ๅฟ
้กปๅฐไบๆ็ญไบ 2048 ไธชๅญ็ฌฆ
+issues.review.remove_review_requests = ไบ %[2]s ๅๆถๅฏน %[1]s ็่ฏๅฎก่ฏทๆฑ
+issues.review.add_review_requests = ไบ %[2]s ่ฏทๆฑ %[1]s ่ฏๅฎก
+issues.review.add_remove_review_requests = ไบ %[3]s ่ฏทๆฑ %[1]s ่ฏๅฎก๏ผๅนถๅๆถๅฏน %[2]s ็่ฏๅฎก่ฏทๆฑ
+pulls.delete_after_merge.head_branch.is_protected = ๆจ่ฆๅ ้ค็ๅคด้จๅๆฏๆฏๅไฟๆค็ๅๆฏ๏ผๆ ๆณๅ ้คใ
+pulls.delete_after_merge.head_branch.insufficient_branch = ๆจๆฒกๆๆ้ๅ ้คๅคด้จๅๆฏใ
+pulls.delete_after_merge.head_branch.is_default = ๆจ่ฆๅ ้ค็ๅคด้จๅๆฏๆฏ้ป่ฎคๅๆฏ๏ผๆ ๆณๅ ้คใ
+issues.filter_sort.relevance = ็ธๅ
ณๆง
+diff.git-notes.add = ๆทปๅ ๆณจ้
+diff.git-notes.remove-header = ็งป้คๆณจ้
+diff.git-notes.remove-body = ๆญคๆณจ้ๅฐ่ขซ็งป้คใ
+issues.num_reviews_one = %d ่ฏๅฎก
+issues.num_reviews_few = %d ่ฏๅฎก
+issues.summary_card_alt = ไปๅบ %[2]s ไธญๆ ้ขไธบ %[1]s ็ๅทฅๅ็ๆ่ฆๅก็
+editor.add_tmpl.filename = ๆไปถๅ
+settings.default_update_style_desc = ็จไบๆดๆฐ่ฝๅไบๅบ็กๅๆฏ็ๅๅนถ่ฏทๆฑ็้ป่ฎคๆดๆฐๆ ทๅผใ
+pulls.sign_in_require = ็ปๅฝ ไปฅๅๅปบๆฐ็ๅๅนถ่ฏทๆฑใ
+new_from_template = ไฝฟ็จๆจกๆฟ
+new_from_template_description = ๆจๅฏไปฅ้ๆฉๆญคๅฎไพไธ็ฐๆไปๅบๆจกๆฟๅนถๅบ็จๅ
ถ่ฎพ็ฝฎใ
+new_advanced = ้ซ็บง่ฎพ็ฝฎ
+new_advanced_expand = ๅๅปๅฑๅผ
+auto_init_description = ไปฅไธไธช่ช่ฟฐๆไปถใๅฏ้็่ฎธๅฏ่ฏไธ .gitignore ๆไปถๅผๅงGitๅๅฒใ
+issues.reaction.add = ๆทปๅ ๅๅบ
+issues.reaction.alt_few = %[1]s ๅๅบไบ %[2]sใ
+issues.reaction.alt_many = %[1]s ๅๅฆๅค %[2]d ไบบๅๅบไบ %[3]sใ
+issues.reaction.alt_remove = ไป่ฏ่ฎบไธญ็งป้ค %[1] ๅๅบใ
+issues.context.menu = ่ฏ่ฎบ่ๅ
+issues.reaction.alt_add = ๅฏน่ฏ่ฎบๆทปๅ %[1]s ๅๅบใ
+release.summary_card_alt = ไปๅบ %[2]s ไธญๆ ้ขไธบ %[1]s ็็ๆฌๅๅธ็ๆ่ฆๅก็
+summary_card_alt = ไปๅบ %s ็ๆ่ฆๅก็
+editor.commit_email = ๆไบค็ตๅญ้ฎไปถ
+archive.pull.noreview = ๆญคไปๅบๅทฒๅญๆกฃ๏ผๆจๆ ๆณ่ฏๅฎกๅๅนถ่ฏทๆฑใ
+commits.view_single_diff = ๆฅ็่ฏฅๆไบคๅฏนๆฌๆไปถ็ๆดๆน
+pulls.editable = ๅฏ็ผ่พ
+pulls.editable_explanation = ๆญคๅๅนถ่ฏทๆฑๅ
่ฎธ็ปดๆค่
่ฟ่ก็ผ่พใไฝ ๅฏไปฅ็ดๆฅๅๅ
ถ่ดก็ฎใ
+issues.reopen.blocked_by_user = ็ฑไบไฝ ๅทฒ่ขซไปๅบๆๆ่
ๆๅทฅๅไฝ่
ๅฑ่ฝ๏ผไฝ ไธ่ฝ้ๆฐๆๅผๆญคๅทฅๅใ
+pulls.comment.blocked_by_user = ็ฑไบไฝ ๅทฒ่ขซไปๅบๆๆ่
ๆๅๅนถ่ฏทๆฑไฝ่
ๅฑ่ฝ๏ผไฝ ไธ่ฝๅจๆญคๅๅนถ่ฏทๆฑๅ่กจ่ฏ่ฎบใ
+issues.filter_no_results = ๆ ็ปๆ
+issues.filter_no_results_placeholder = ๅฐ่ฏ่ฐๆดๆ็ดข็ญ้ๆกไปถใ
[graphs]
-component_loading=ๆญฃๅจๅ ่ฝฝ %s...
+component_loading=ๆญฃๅจๅ ่ฝฝ %sโฆ
component_loading_failed=ๆ ๆณๅ ่ฝฝ %s
component_loading_info=่ฟๅฏ่ฝ้่ฆไธ็นโฆ
component_failed_to_load=ๆๅค็้่ฏฏๅ็ไบใ
@@ -2791,7 +2932,7 @@ teams=ๅข้
code=ไปฃ็
lower_members=ๅๆๅ
lower_repositories=ไธชไปๅบ
-create_new_team=ๆฐๅปบๅข้
+create_new_team=ๅๅปบๅข้
create_team=ๅๅปบๅข้
org_desc=็ป็ปๆ่ฟฐ
team_name=ๅข้ๅ็งฐ
@@ -2801,11 +2942,11 @@ team_desc_helper=ๆ่ฟฐๅข้็็ฎ็ๆไฝ็จใ
team_access_desc=ไปๅบๆ้
team_permission_desc=ๆ้
team_unit_desc=ๅ
่ฎธ่ฎฟ้ฎไปๅบๅๅ
-team_unit_disabled=(ๅทฒ็ฆ็จ)
+team_unit_disabled=๏ผๅทฒ็ฆ็จ๏ผ
form.name_reserved=็ป็ปๅ็งฐ '%s' ๆฏ่ขซไฟ็็ใ
form.name_pattern_not_allowed=ไปๅบๅ็งฐไธญไธๅ
่ฎธไฝฟ็จ "%s"ใ
-form.create_org_not_allowed=ๆญค่ดฆๅท็ฆๆญขๅๅปบ็ป็ป
+form.create_org_not_allowed=ๆจไธ่ฝๅๅปบ็ป็ปใ
settings=็ป็ป่ฎพ็ฝฎ
settings.options=็ป็ป
@@ -2817,9 +2958,9 @@ settings.permission=ๆ้
settings.repoadminchangeteam=ไปๅบ็ฎก็ๅๅฏไปฅๆทปๅ ๆ็งป้คๅข้็่ฎฟ้ฎๆ้
settings.visibility=ๅฏ่งๆง
settings.visibility.public=ๅ
ฌๅผ
-settings.visibility.limited=ๅ้ (ไป
ๅฏน่ฎค่ฏ็จๆทๅฏ่ง)
+settings.visibility.limited=ๅ้๏ผไป
ๅฏน็ปๅฝ็จๆทๅฏ่ง๏ผ
settings.visibility.limited_shortname=ๅ้
-settings.visibility.private=็งๆ (ไป
ๅฏน็ป็ปๆๅๅฏ่ง)
+settings.visibility.private=็งๆ๏ผไป
ๅฏน็ป็ปๆๅๅฏ่ง๏ผ
settings.visibility.private_shortname=็งๆ
settings.update_settings=ๆดๆฐ่ฎพ็ฝฎ
@@ -2844,22 +2985,22 @@ members.private=้่
members.private_helper=ๆพ็คบ
members.member_role=ๆๅ่ง่ฒ๏ผ
members.owner=็ฎก็ๅ
-members.member=ๆฎ้ๆๅ
+members.member=ๆๅ
members.remove=็งป้คๆๅ
members.remove.detail=ไป %[2]s ไธญ็งป้ค %[1]s ๅ๏ผ
members.leave=็ฆปๅผ็ป็ป
-members.leave.detail=็ฆปๅผ %s๏ผ
+members.leave.detail=ๆฏๅฆ็กฎๅฎ่ฆ็ฆปๅผ็ป็ปโ%sโ๏ผ
members.invite_desc=้่ฏทๆฐ็็จๆทๅ ๅ
ฅ %s๏ผ
members.invite_now=็ซๅณ้่ฏท
teams.join=ๅ ๅ
ฅๅข้
teams.leave=็ฆปๅผๅข้
-teams.leave.detail=็ฆปๅผ %s๏ผ
+teams.leave.detail=ๆฏๅฆ็กฎๅฎ่ฆ็ฆปๅผๅข้โ%sโ๏ผ
teams.can_create_org_repo=ๅๅปบไปๅบ
teams.can_create_org_repo_helper=ๆๅๅฏไปฅๅจ็ป็ปไธญๅๅปบไปๅบใๅๅปบ่
ๅฐ่ชๅจ่ทๅพๅๅปบ็ไปๅบ็็ฎก็ๅๆ้ใ
-teams.none_access=ๆ ่ฎฟ้ฎๆ้
-teams.none_access_helper=ๆๅๆ ๆณๆฅ็ๆญคๅๅ
ๆๅฏนๅ
ถๆง่กไปปไฝๅ
ถไปๆไฝใ
-teams.general_access=ๅธธ่ง่ฎฟ้ฎ
+teams.none_access=็ฆๆญข่ฎฟ้ฎ
+teams.none_access_helper=โ็ฆๆญข่ฎฟ้ฎโ้้กนไป
ๅฏน็งๆไปๅบๆๆใ
+teams.general_access=่ชๅฎไน่ฎฟ้ฎ
teams.general_access_helper=ๆๅๆ้ๅฐ็ฑไปฅไธๆ้่กจๅณๅฎใ
teams.read_access=ๅฏ่ฏป
teams.read_access_helper=ๆๅๅฏไปฅๆฅ็ๅๅ
้ๅข้ไปๅบใ
@@ -2880,8 +3021,8 @@ teams.delete_team_title=ๅ ้คๅข้
teams.delete_team_desc=ๅ ้คไธไธชๅข้ๅฐๅ ้คๅข้ๆๅ็่ฎฟ้ฎๆ้๏ผ็ปง็ปญ๏ผ
teams.delete_team_success=่ฏฅๅข้ๅทฒ่ขซๅ ้คใ
teams.read_permission_desc=่ฏฅๅข้ๆฅๆๅฏนๆๅฑไปๅบ็ ่ฏปๅ ๆ้๏ผๅข้ๆๅๅฏไปฅ่ฟ่กๆฅ็ๅๅ
้็ญๅช่ฏปๆไฝใ
-teams.write_permission_desc=่ฏฅๅข้ๆฅๆๅฏนๆๅฑไปๅบ็ ่ฏปๅ ๅ ๅๅ
ฅ ็ๆ้ใ
-teams.admin_permission_desc=่ฏฅๅข้ๆฅๆไธๅฎ็ ็ฎก็ ๆ้๏ผๅข้ๆๅๅฏไปฅ่ฏปๅใๅ
้ใๆจ้ไปฅๅๆทปๅ ๅ
ถๅฎไปๅบๅไฝ่
ใ
+teams.write_permission_desc=่ฏฅๅข้ๆฅๆๅฏนๆๅฑไปๅบ็ๅๅ
ฅ ๆ้๏ผๆๅๅฏไปฅๆฅ็ๅๆจ้่ณๅข้ไปๅบใ
+teams.admin_permission_desc=ๆญคๅข้ๆไบ็ฎก็ๅ ่ฎฟ้ฎๆ้๏ผๆๅๅฏไปๅข้ไปๅบไธญ่ฏปๅใๆจ้ๅๆทปๅ ๅไฝ่
ใ
teams.create_repo_permission_desc=ๆญคๅค๏ผ่ฏฅๅข้ๆฅๆไบ ๅๅปบไปๅบ ็ๆ้๏ผๆๅๅฏไปฅๅจ็ป็ปไธญๅๅปบๆฐ็ไปๅบใ
teams.repositories=ๅข้ไปๅบ
teams.search_repo_placeholder=ๆ็ดขไปๅบ...
@@ -2894,7 +3035,7 @@ teams.add_duplicate_users=็จๆทๅทฒ็ปๆฏๅข้ๆๅใ
teams.repos.none=ๆญคๅข้ๆ ๆณ่ฎฟ้ฎไปปไฝไปๅบใ
teams.members.none=ๅข้ไธญๆฒกๆๆๅใ
teams.specific_repositories=ๆๅฎไปๅบ
-teams.specific_repositories_helper=ๅข้ๆๅๅฐๅช่ฝ่ฎฟ้ฎๆทปๅ ๅฐๅข้็ไปๅบใ ้ๆฉๆญค้กน ๅฐไธไผ ่ชๅจๅ ้คๅทฒ็ปๆทปๅ ็ไปๅบใ
+teams.specific_repositories_helper=ๅข้ๆๅๅฐๅช่ฝ่ฎฟ้ฎๆทปๅ ๅฐๅข้็ไปๅบใ ้ๆฉๆญค้กนๅฐไธไผ ่ชๅจๅ ้ค้่ฟๆๆไปๅบ ๆทปๅ ็ไปๅบใ
teams.all_repositories=ๆๆไปๅบ
teams.all_repositories_helper=ๅข้ๅฏไปฅ่ฎฟ้ฎๆๆไปๅบใ้ๆฉๆญค้้กนๅฐ ๆทปๅ ๆๆ็ฐๆ็ ไปๅบๅฐๆๅฎๅข้ใ
teams.all_repositories_read_permission_desc=ๆญคๅข้ๆไบ่ฏปๅ ๆๆไปๅบ ็่ฎฟ้ฎๆ้: ๆๅๅฏไปฅๆฅ็ๅๅ
้ไปๅบใ
@@ -2905,14 +3046,16 @@ teams.invite.by=้่ฏทไบบ %s
teams.invite.description=่ฏท็นๅปไธ้ข็ๆ้ฎๅ ๅ
ฅๅข้ใ
follow_blocked_user = ไฝ ๆ ๆณๅ
ณๆณจๆญค็ป็ป๏ผๅ ไธบๆญค็ป็ปๅทฒๅฑ่ฝไฝ ใ
open_dashboard = ๆๅผไปช่กจ็
+settings.change_orgname_redirect_prompt.with_cooldown.one = ๆง็็ป็ปๅๅฐๅจ%[1]dๅคฉ็ไฟๆคๆๅๅฏนๆๆไบบๅฏ็จ๏ผๆจไปๅฏไปฅๅจๆญคๆ้ด้ๆฐ่ฎค้ขๆง็ๅๅญใ
+settings.change_orgname_redirect_prompt.with_cooldown.few = ๆง็็ป็ปๅๅฐๅจ%[1]dๅคฉ็ไฟๆคๆๅๅฏนๆๆไบบๅฏ็จ๏ผๆจไปๅฏไปฅๅจๆญคๆ้ด้ๆฐ่ฎค้ขๆงๅๅญใ
[admin]
dashboard=็ฎก็้ขๆฟ
-self_check=่ชๆๆฃๆฅ
+self_check = ่ชๆฃ
identity_access=่บซไปฝๅ่ฎค่ฏ
users=็จๆทๅธๆท
organizations=็ป็ป็ฎก็
-assets=ไปฃ็ ่ตไบง
+assets=ไปฃ็ ่ตๆบ
repositories=ไปๅบ็ฎก็
hooks=Web ้ฉๅญ
integrations=้ๆ
@@ -2926,7 +3069,7 @@ last_page=ๆซ้กต
total=ๆป่ฎก๏ผ%d
settings=็ฎก็่ฎพ็ฝฎ
-dashboard.new_version_hint=Forgejo %s ็ฐๅทฒๅฏ็จ๏ผๆจๆญฃๅจ่ฟ่ก %sใๆฅ็ ๅๅฎข ไบ่งฃ่ฏฆๆ
ใ
+dashboard.new_version_hint=Forgejo %s ็ฐๅทฒๅฏ็จ๏ผๆจๆญฃๅจ่ฟ่ก %sใๆฅ็ ๅๅฎข ไบ่งฃ่ฏฆๆ
ใ
dashboard.statistic=ๆ่ฆ
dashboard.operations=็ปดๆคๆไฝ
dashboard.system_status=็ณป็ป็ถๆ
@@ -2936,15 +3079,15 @@ dashboard.operation_run=ๆง่ก
dashboard.clean_unbind_oauth=ๆธ
็ๆช็ปๅฎ็ OAuth ่ฟๆฅ
dashboard.clean_unbind_oauth_success=ๆๆๆช็ปๅฎ็ OAuth ่ฟๆฅๅทฒ่ขซๅ ้คใ
dashboard.task.started=ๅทฒๅผๅงไปปๅก๏ผ%[1]s
-dashboard.task.process=ไปปๅก: %[1]s
-dashboard.task.cancelled=ไปปๅก: %[1]s ๅทฒๅๆถ: %[3]s
-dashboard.task.error=ไปปๅกไธญ็้่ฏฏ: %[1]s: %[3]s
-dashboard.task.finished=ไปปๅก: %[2]s ๅฏๅจ็ %[1]s ๅทฒๅฎๆ
-dashboard.task.unknown=ๆช็ฅไปปๅก๏ผ %[1]s
+dashboard.task.process=ไปปๅก๏ผ%[1]s
+dashboard.task.cancelled=ไปปๅก๏ผ%[1]s ๅทฒๅๆถ๏ผ%[3]s
+dashboard.task.error=ไปปๅกไธญ็้่ฏฏ๏ผ%[1]s๏ผ%[3]s
+dashboard.task.finished=ไปปๅก๏ผ%[2]s ๅฏๅจ็ %[1]s ๅทฒๅฎๆ
+dashboard.task.unknown=ๆช็ฅไปปๅก๏ผ%[1]s
dashboard.cron.started=ๅทฒๅผๅง่ฎกๅไปปๅก๏ผ%[1]s
dashboard.cron.process=่ฎกๅไปปๅก๏ผ%[1]s
-dashboard.cron.cancelled=ๅฎๆถไปปๅก: %[1]s ๅทฒๅๆถ: %[3]s
-dashboard.cron.error=ไปปๅกไธญ็้่ฏฏ๏ผ %s: %[3]s
+dashboard.cron.cancelled=ๅฎๆถไปปๅก๏ผ%[1]s ๅทฒๅๆถ๏ผ%[3]s
+dashboard.cron.error=ไปปๅกไธญ็้่ฏฏ๏ผ%s๏ผ%[3]s
dashboard.cron.finished=ไปปๅก๏ผ%[1]s ๅทฒ็ปๅฎๆ
dashboard.delete_inactive_accounts=ๅ ้คๆๆๆชๆฟๆดป็ๅธๆท
dashboard.delete_inactive_accounts.started=ๅ ้คๆๆๆชๆฟๆดป็่ดฆๆทไปปๅกๅทฒๅฏๅจใ
@@ -2954,7 +3097,7 @@ dashboard.delete_missing_repos=ๅ ้คๆๆไธขๅคฑ Git ๆไปถ็ไปๅบ
dashboard.delete_missing_repos.started=ๅ ้คๆๆไธขๅคฑ Git ๆไปถ็ไปๅบไปปๅกๅทฒๅฏๅจใ
dashboard.delete_generated_repository_avatars=ๅ ้ค็ๆ็ไปๅบๅคดๅ
dashboard.sync_repo_branches=ๅฐ็ผบๅฐ็ๅๆฏไป Git ๆฐๆฎๅๆญฅๅฐๆฐๆฎๅบ
-dashboard.sync_repo_tags=ไป git ๆฐๆฎๅๆญฅๆ ็ญพๅฐๆฐๆฎๅบ
+dashboard.sync_repo_tags = ๅฐ git ๆฐๆฎไธญ็ๆ ็ญพๅๆญฅๅฐๆฐๆฎๅบ
dashboard.update_mirrors=ๆดๆฐ้ๅไปๅบ
dashboard.repo_health_check=ๅฅๅบทๆฃๆฅๆๆไปๅบ
dashboard.check_repo_stats=ๆฃๆฅๆๆไปๅบ็ป่ฎก
@@ -3004,12 +3147,12 @@ dashboard.delete_old_actions.started=ๅทฒๅผๅงไปๆฐๆฎๅบไธญๅ ้คๆๆๆงๆ
dashboard.update_checker=ๆดๆฐๆฃๆฅๅจ
dashboard.delete_old_system_notices=ไปๆฐๆฎๅบไธญๅ ้คๆๆๆง็ณป็ป้็ฅ
dashboard.gc_lfs=ๅๅพๅๆถ LFS ๅ
ๆฐๆฎ
-dashboard.stop_zombie_tasks=ๅๆญขๅตๅฐธไปปๅก
-dashboard.stop_endless_tasks=ๅๆญขๆฐธไธๅๆญข็ไปปๅก
-dashboard.cancel_abandoned_jobs=ๅๆถไธขๅผ็ไปปๅก
-dashboard.start_schedule_tasks=ๅผๅง่ฐๅบฆไปปๅก
+dashboard.stop_zombie_tasks=ๅๆญขๅตๅฐธๆไฝไปปๅก
+dashboard.stop_endless_tasks=ๅๆญขๆ ไผๆญข็ๆไฝไปปๅก
+dashboard.cancel_abandoned_jobs=ๅๆถๆพๅผ็ๆไฝไปปๅก
+dashboard.start_schedule_tasks=ๅผๅงๅฎๆๆไฝไปปๅก
dashboard.sync_branch.started=ๅๆฏๅๆญฅๅทฒๅผๅง
-dashboard.sync_tag.started=ๆ ็ญพๅๆญฅๅทฒๅผๅง
+dashboard.sync_tag.started = ๆ ็ญพๅๆญฅๅทฒๅผๅง
dashboard.rebuild_issue_indexer=้ๅปบๅทฅๅ็ดขๅผ
users.user_manage_panel=็ฎก็็จๆทๅธๆท
@@ -3038,10 +3181,10 @@ users.update_profile_success=่ฏฅๅธๆทๅทฒ่ขซๆดๆฐใ
users.edit_account=็ผ่พๅธๅท
users.max_repo_creation=ๆๅคงไปๅบๆฐ
users.max_repo_creation_desc=๏ผ่ฎพ็ฝฎไธบ -1 ่กจ็คบไฝฟ็จๅ
จๅฑ้ป่ฎคๅผ๏ผ
-users.is_activated=่ฏฅ็จๆทๅทฒ่ขซๆฟๆดป
-users.prohibit_login=็ฆ็จ็ปๅฝ
-users.is_admin=ๆฏ็ฎก็ๅ
-users.is_restricted=ๅ้
+users.is_activated=ๅทฒๆฟๆดป่ดฆๅท
+users.prohibit_login=ๅทฒๆๅ่ดฆๅท
+users.is_admin=็ฎก็ๅ่ดฆๅท
+users.is_restricted=ๅ้่ดฆๅท
users.allow_git_hook=ๅ
่ฎธๅๅปบ Git ้ฉๅญ
users.allow_git_hook_tooltip=Git ้ฉๅญๅฐไผ่ขซไปฅๆไฝ็ณป็ป็จๆท่ฟ่ก๏ผๅฐไผๆฅๆๅๆ ท็ไธปๆบ่ฎฟ้ฎๆ้ใๅ ๆญค๏ผๆฅๆๆญค็นๆฎ็Git ้ฉๅญๆ้ๅฐ่ฝๅค่ฎฟ้ฎๅไฟฎๆนๆๆ็ Forgejo ไปๅบๆ่
Forgejo็ๆฐๆฎๅบใๅๆถไน่ฝ่ทๅพForgejo็็ฎก็ๅๆ้ใ
users.allow_import_local=ๅ
่ฎธๅฏผๅ
ฅๆฌๅฐไปๅบ
@@ -3074,11 +3217,11 @@ emails.email_manage_panel=็ฎก็็จๆท้ฎไปถๅฐๅ
emails.primary=ไธป่ฆ็
emails.activated=ๅทฒๆฟๆดป
emails.filter_sort.email=็ตๅญ้ฎไปถ
-emails.filter_sort.email_reverse=็ตๅญ้ฎไปถ(้ๅบ)
+emails.filter_sort.email_reverse=็ตๅญ้ฎไปถ๏ผ้ๅบ๏ผ
emails.filter_sort.name=็จๆทๅ
-emails.filter_sort.name_reverse=็จๆทๅ(ๅๅบ)
+emails.filter_sort.name_reverse=็จๆทๅ๏ผๅๅบ๏ผ
emails.updated=็ตๅญ้ฎไปถๅทฒๆดๆฐ
-emails.not_updated=ๆ ๆณๆดๆฐ่ฏทๆฑ็็ตๅญ้ฎไปถๅฐๅ๏ผ %v
+emails.not_updated=ๆ ๆณๆดๆฐ่ฏทๆฑ็็ตๅญ้ฎไปถๅฐๅ๏ผ%v
emails.duplicate_active=ๆญค็ตๅญ้ฎไปถๅฐๅๅทฒ่ขซๅฆไธไธช็จๆทๆฟๆดปไฝฟ็จใ
emails.change_email_header=ๆดๆฐ็ตๅญ้ฎไปถๅฑๆง
emails.change_email_text=ๆจ็กฎๅฎ่ฆๆดๆฐ่ฏฅ็ตๅญ้ฎไปถๅฐๅๅ๏ผ
@@ -3091,10 +3234,10 @@ orgs.new_orga=ๅๅปบๆฐ็็ป็ป
repos.repo_manage_panel=ไปๅบ็ฎก็
repos.unadopted=ๆชๆถๅฝไปๅบ
-repos.unadopted.no_more=ๆพไธๅฐๆดๅคๆช่ขซๆถๅฝ็ไปๅบ
+repos.unadopted.no_more=ๆพไธๅฐๆดๅคๆช่ขซๆถๅฝ็ไปๅบใ
repos.owner=ๆๆ่
repos.name=ๅ็งฐ
-repos.private=็งๆๅบ
+repos.private=็งๆ
repos.watches=ๅ
ณๆณจๆฐ
repos.stars=็น่ตๆฐ
repos.forks=ๆดพ็ๆฐ
@@ -3104,7 +3247,7 @@ repos.lfs_size=LFS ๅคงๅฐ
packages.package_manage_panel=่ฝฏไปถๅ
็ฎก็
packages.total_size=ๆปๅคงๅฐ๏ผ%s
-packages.unreferenced_size=ๆชๅผ็จๅคงๅฐ๏ผ %s
+packages.unreferenced_size=ๆชๅผ็จๅคงๅฐ๏ผ%s
packages.cleanup=ๆธ
็่ฟๆๆฐๆฎ
packages.cleanup.success=ๆธ
็่ฟๆๆฐๆฎๆๅ
packages.owner=ๆๆ่
@@ -3117,12 +3260,12 @@ packages.size=ๅคงๅฐ
packages.published=ๅทฒๅๅธ
defaulthooks=้ป่ฎคWeb้ฉๅญ
-defaulthooks.desc=ๅฝๆไบ Forgejo ไบไปถ่งฆๅๆถ๏ผWeb ้ฉๅญ่ชๅจๅๆๅกๅจๅๅบ HTTP POST ่ฏทๆฑใ่ฟ้ๅฎไน็ Web ้ฉๅญๆฏ้ป่ฎค้
็ฝฎ๏ผๅฐ่ขซๅคๅถๅฐๆๆๆฐ็ไปๅบไธญใ่ฏฆๆ
่ฏท่ฎฟ้ฎ Web ้ฉๅญๆๅ ใ
+defaulthooks.desc=ๅฝๆไบ Forgejo ไบไปถ่งฆๅๆถ๏ผWeb ้ฉๅญ่ชๅจๅๆๅกๅจๅๅบ HTTP POST ่ฏทๆฑใ่ฟ้ๅฎไน็ Web ้ฉๅญๆฏ้ป่ฎค้
็ฝฎ๏ผๅฐ่ขซๅคๅถๅฐๆๆๆฐ็ไปๅบไธญใ่ฏฆๆ
่ฏท่ฎฟ้ฎ Web ้ฉๅญๆๅ ใ
defaulthooks.add_webhook=ๆทปๅ ้ป่ฎคWeb ้ฉๅญ
defaulthooks.update_webhook=ๆดๆฐ้ป่ฎคโWebโ้ฉๅญ
systemhooks=็ณป็ป Web ้ฉๅญ
-systemhooks.desc=ๅฝๆไบ Forgejo ไบไปถ่งฆๅๆถ๏ผWeb ้ฉๅญ่ชๅจๅๆๅกๅจๅๅบHTTP POST่ฏทๆฑใ่ฟ้ๅฎไน็ Web ้ฉๅญๅฐไฝ็จไบ็ณป็ปไธ็ๆๆไปๅบ๏ผๆไปฅ่ฏท่่่ฟๅฏ่ฝๅธฆๆฅ็ไปปไฝๆง่ฝๅฝฑๅใไบ่งฃ่ฏฆๆ
่ฏท่ฎฟ้ฎ Web ้ฉๅญๆๅ ใ
+systemhooks.desc=ๅฝๆไบ Forgejo ไบไปถ่งฆๅๆถ๏ผWeb ้ฉๅญ่ชๅจๅๆๅกๅจๅๅบHTTP POST่ฏทๆฑใ่ฟ้ๅฎไน็ Web ้ฉๅญๅฐไฝ็จไบ็ณป็ปไธ็ๆๆไปๅบ๏ผๆไปฅ่ฏท่่่ฟๅฏ่ฝๅธฆๆฅ็ไปปไฝๆง่ฝๅฝฑๅใไบ่งฃ่ฏฆๆ
่ฏท่ฎฟ้ฎ Web ้ฉๅญๆๅ ใ
systemhooks.add_webhook=ๆทปๅ ็ณป็ป Web ้ฉๅญ
systemhooks.update_webhook=ๆดๆฐ็ณป็ป Web ้ฉๅญ
@@ -3147,7 +3290,7 @@ auths.attribute_username=็จๆทๅๅฑๆง
auths.attribute_username_placeholder=็ฝฎ็ฉบๅฐไฝฟ็จForgejo็็จๆทๅใ
auths.attribute_name=ๅๅญๅฑๆง
auths.attribute_surname=ๅงๆฐๅฑๆง
-auths.attribute_mail=็ตๅญ้ฎ็ฎฑๅฑๆง
+auths.attribute_mail=็ตๅญ้ฎไปถๅฐๅๅฑๆง
auths.attribute_ssh_public_key=SSHๅ
ฌ้ฅๅฑๆง
auths.attribute_avatar=ๅคดๅๅฑๆง
auths.attributes_in_bind=ไป bind DN ไธญๆๅๅฑๆงไฟกๆฏ
@@ -3157,12 +3300,12 @@ auths.search_page_size=ๅ้กตๅคงๅฐ
auths.filter=็จๆท่ฟๆปค่งๅ
auths.admin_filter=็ฎก็ๅ่ฟๆปค่งๅ
auths.restricted_filter=ๅ้็่ฟๆปคๅจ
-auths.restricted_filter_helper=็็ฉบๅไธๅฐไปปไฝ็จๆท่ฎพ็ฝฎไธบๅ้ใไฝฟ็จๆๅท('*') ๅฐๆๆไธๅน้
็ฎก็่ฟๆปคๅจ็็จๆท่ฎพ็ฝฎไธบๅ้็จๆทใ
-auths.verify_group_membership=้ช่ฏ LDAP ็ปๆๅ่ตๆ ผ (็็ฉบ่ฟๆปคๅจ่ทณ่ฟ)
+auths.restricted_filter_helper=็็ฉบๅไธๅฐไปปไฝ็จๆท่ฎพ็ฝฎไธบๅ้ใไฝฟ็จๆๅท๏ผ'*'๏ผ ๅฐๆๆไธๅน้
็ฎก็่ฟๆปคๅจ็็จๆท่ฎพ็ฝฎไธบๅ้็จๆทใ
+auths.verify_group_membership=้ช่ฏ LDAP ็ปๆๅ่ตๆ ผ๏ผ็็ฉบ่ฟๆปคๅจ่ทณ่ฟ๏ผ
auths.group_search_base=็พค็ปๆ็ดขๅบ็ก DN
auths.group_attribute_list_users=ๅ
ๅซ็จๆทๅ่กจ็็พค็ปๅฑๆง
auths.user_attribute_in_group=็พค็ปไธญๅๅบ็็จๆทๅฑๆง
-auths.map_group_to_team=ๅฐ LDAP ็ปๆ ๅฐๅฐ็ป็ปๅข้ (็็ฉบๅญๆฎตๅ่ทณ่ฟ)
+auths.map_group_to_team=ๅฐ LDAP ็ปๆ ๅฐๅฐ็ป็ปๅข้๏ผ็็ฉบๅญๆฎตๅ่ทณ่ฟ๏ผ
auths.map_group_to_team_removal=ๅฆๆ็จๆทไธๅฑไบ็ธๅบ็ LDAP ็ป๏ผไปๅทฒๅๆญฅๅข้ไธญ็งป้ค็จๆท
auths.enable_ldap_groups=ๅฏ็จ LDAP ็ป
auths.ms_ad_sa=MS AD ๆ็ดขๅฑๆง
@@ -3173,12 +3316,12 @@ auths.allowed_domains=ๅๅ็ฝๅๅ
auths.allowed_domains_helper=ๆฏไธชๅๅ็จ้ๅทๅ้๏ผๅฆ่ฆๅ
่ฎธไปปๆๅๅๅ็็ฉบใ
auths.skip_tls_verify=ๅฟฝ็ฅ TLS ้ช่ฏ
auths.force_smtps=ๅผบๅถ SMTPS
-auths.force_smtps_helper=SMTPS ๅง็ป็จไบ 465 ็ซฏๅฃใ่ฎพ็ฝฎๆญค้กนไผๅผบๅถๅ
ถไป็ซฏๅฃไนไฝฟ็จ SMTPSใ(ๅฆๅ๏ผๅฆๆไธปๆบๆฏๆ๏ผๅฐๅจๅ
ถไป็ซฏๅฃไธไฝฟ็จ STARTTLSใ)
+auths.force_smtps_helper=SMTPS ๅง็ป็จไบ 465 ็ซฏๅฃใ่ฎพ็ฝฎๆญค้กนไผๅผบๅถๅ
ถไป็ซฏๅฃไนไฝฟ็จ SMTPSใ๏ผๅฆๅ๏ผๅฆๆไธปๆบๆฏๆ๏ผๅฐๅจๅ
ถไป็ซฏๅฃไธไฝฟ็จ STARTTLSใ๏ผ
auths.helo_hostname=HELO ไธปๆบๅ
auths.helo_hostname_helper=็จ HELO ๅ้็ไธปๆบๅใ ็็ฉบๅ้ๅฝๅไธปๆบๅใ
auths.disable_helo=็ฆ็จ HELO
auths.pam_service_name=PAM ๆๅกๅ็งฐ
-auths.pam_email_domain=PAM ็ตๅญ้ฎไปถๅ(ๅฏ้)
+auths.pam_email_domain=PAM ็ตๅญ้ฎไปถๅ๏ผๅฏ้๏ผ
auths.oauth2_provider=OAuth2 ๆไพ็จๅบ
auths.oauth2_icon_url=ๅพๆ URL
auths.oauth2_clientID=ๅฎขๆท็ซฏ ID ๏ผ้ฎ๏ผ
@@ -3187,7 +3330,7 @@ auths.openIdConnectAutoDiscoveryURL=OpenID ่ฟๆฅ่ชๅจๅ็ฐ URL
auths.oauth2_use_custom_url=ไฝฟ็จ่ชๅฎไน็ URL ่ไธๆฏ้ป่ฎค็ URL
auths.oauth2_tokenURL=ไปค็ URL
auths.oauth2_authURL=ๆๆ URL
-auths.oauth2_profileURL=Profile URL
+auths.oauth2_profileURL=ไธชไบบไฟกๆฏ URL
auths.oauth2_emailURL=็ตๅญ้ฎไปถ URL
auths.skip_local_two_fa=่ทณ่ฟๆฌๅฐไธคๆญฅ้ช่ฏ
auths.skip_local_two_fa_helper=ไธ่ฎพ็ฝฎๆๅณ็่ฎพ็ฝฎไบไธคๆญฅ้ช่ฏ็ๆฌๅฐ็จๆทไป็ถ้่ฆ้่ฟไธคๆญฅ้ช่ฏๆ่ฝ็ปๅฝ
@@ -3197,39 +3340,39 @@ auths.oauth2_required_claim_name=ๅฟ
้กปๅกซๅ Claim ๅฃฐๆ็ๅ็งฐ
auths.oauth2_required_claim_name_helper=่ฎพ็ฝฎๆญคๅ็งฐ๏ผๅชๆๅ
ทๆๆญคๅ็งฐ็ๅฃฐๆ๏ผClaim๏ผ็็จๆทๅฏไปๆญคๆบ็ปๅฝ
auths.oauth2_required_claim_value=ๅฟ
้กปๅกซๅ Claim ๅฃฐๆ็ๅผ
auths.oauth2_required_claim_value_helper=่ฎพ็ฝฎๆญคๅผ๏ผๅชๆๆฅๆๅฏนๅบ็ๅฃฐๆ๏ผClaim๏ผ็ๅ็งฐๅๅผ็็จๆทๆ่ขซๅ
่ฎธไปๆญคๆบ็ปๅฝ
-auths.oauth2_group_claim_name=็จไบๆไพ็จๆท็ปๅ็งฐ็ Claim ๅฃฐๆๅ็งฐใ(ๅฏ้)
-auths.oauth2_admin_group=็ฎก็ๅ็จๆท็ป็ Claim ๅฃฐๆๅผใ(ๅฏ้ - ้่ฆไธ้ข็ๅฃฐๆๅ็งฐ)
-auths.oauth2_restricted_group=ๅ้็จๆท็ป็ Claim ๅฃฐๆๅผใ(ๅฏ้ - ้่ฆไธ้ข็ๅฃฐๆๅ็งฐ)
+auths.oauth2_group_claim_name=็จไบๆไพ็จๆท็ปๅ็งฐ็ Claim ๅฃฐๆๅ็งฐใ๏ผๅฏ้๏ผ
+auths.oauth2_admin_group=็ฎก็ๅ็จๆท็ป็ Claim ๅฃฐๆๅผใ๏ผๅฏ้ - ้่ฆไธ้ข็ๅฃฐๆๅ็งฐ๏ผ
+auths.oauth2_restricted_group=ๅ้็จๆท็ป็ Claim ๅฃฐๆๅผใ๏ผๅฏ้ - ้่ฆไธ้ข็ๅฃฐๆๅ็งฐ๏ผ
auths.oauth2_map_group_to_team=ๆ ๅฐๅฃฐๆ็็ปๅฐ็ป็ปๅข้ใ๏ผๅฏ้ - ่ฆๆฑๅจไธ้ขๅกซๅๅฃฐๆ็ๅๅญ๏ผ
-auths.oauth2_map_group_to_team_removal=ๅฆๆ็จๆทไธๅฑไบ็ธๅบ็็ป๏ผไปๅทฒๅๆญฅๅข้ไธญ็งป้ค็จๆท
+auths.oauth2_map_group_to_team_removal=ๅฆๆ็จๆทไธๅฑไบ็ธๅบ็็ป๏ผๅไปๅๆญฅ็ๅข้ไธญ็งป้ค็จๆทใ
auths.enable_auto_register=ๅ
่ฎธ่ชๅจๆณจๅ
auths.sspi_auto_create_users=่ชๅจๅๅปบ็จๆท
auths.sspi_auto_create_users_helper=ๅ
่ฎธ SSPI ่ฎค่ฏๅจ็จๆท็ฌฌไธๆฌก็ปๅฝๆถ่ชๅจๅๅปบๆฐ่ดฆๅท
auths.sspi_auto_activate_users=่ชๅจๆฟๆดป็จๆท
auths.sspi_auto_activate_users_helper=ๅ
่ฎธ SSPI ่ฎค่ฏ่ชๅจๆฟๆดปๆฐ็จๆท
auths.sspi_strip_domain_names=ไป็จๆทๅไธญๅ ้คๅๅ้จๅ
-auths.sspi_strip_domain_names_helper=ๅฆๆ้ไธญๆญค้กน๏ผๅๅๅฐไป็ปๅฝๅไธญๅ ้ค(ไพๅฆ๏ผ"DOMAIN\user"ๅ"user@example.org"๏ผไธค่
้ฝๅฐๅๆๅชๆฏโ็จๆทโ)ใ
+auths.sspi_strip_domain_names_helper=ๅฆๆ้ไธญๆญค้กน๏ผๅๅๅฐไป็ปๅฝๅไธญๅ ้ค๏ผไพๅฆ๏ผ"DOMAIN\user"ๅ"user@example.org"๏ผไธค่
้ฝๅฐๅๆๅชๆฏ "user"๏ผใ
auths.sspi_separator_replacement=่ฆไฝฟ็จ็ๅ้็ฌฆไปฃๆฟ\, / ๅ @
-auths.sspi_separator_replacement_helper=็จไบๆฟๆขไธ็บง็ปๅฝๅ็งฐๅ้็ฌฆ็ๅญ็ฌฆ (ไพๅฆ "DOMAIN\user") ไธญ็ \ ๅ็จๆทไธปๅๅญ(ๅฆ"user@example.org"ไธญ็ @)ใ
+auths.sspi_separator_replacement_helper=็จไบๆฟๆขไธ็บง็ปๅฝๅ็งฐๅ้็ฌฆ็ๅญ็ฌฆ๏ผไพๅฆ "DOMAIN\user"๏ผ ไธญ็ \ ๅ็จๆทไธปๅๅญ๏ผๅฆ"user@example.org"ไธญ็ @๏ผใ
auths.sspi_default_language=้ป่ฎค่ฏญ่จ
auths.sspi_default_language_helper=SSPI ่ฎค่ฏๆนๆณไธบ็จๆท่ชๅจๅๅปบ็้ป่ฎค่ฏญ่จใๅฆๆๆจๆณ่ฆ่ชๅจๆฃๆตๅฐ่ฏญ่จ๏ผ่ฏท็็ฉบใ
auths.tips=ๅธฎๅฉๆ็คบ
auths.tips.oauth2.general=OAuth2 ่ฎค่ฏ
auths.tips.oauth2.general.tip=ๅฝๆณจๅๆฐ็ OAuth2 ่บซไปฝ้ช่ฏๆถ๏ผๅ่ฐ/้ๅฎๅ URL ๅบ่ฏฅๆฏ๏ผ
auths.tip.oauth2_provider=OAuth2 ๆไพ็จๅบ
-auths.tip.bitbucket=`ๅจ https://bitbucket.org/account/user//oauth-consumers/new ๆณจๅๆฐ็ OAuth consumer ๅนถๆทปๅ ๆ้โAccountโ ๅ โReadโ`
-auths.tip.nextcloud=ไฝฟ็จไธ้ข็่ๅโ่ฎพ็ฝฎ๏ผSettings๏ผ -> ๅฎๅ
จ๏ผSecurity๏ผ -> OAuth 2.0 clientโๅจๆจ็ๅฎไพไธๆณจๅไธไธชๆฐ็ OAuth ๅฎขๆท็ซฏใ
-auths.tip.dropbox=ๅจ https://www.dropbox.com/developers/apps ไธๅๅปบไธไธชๆฐ็ๅบ็จ็จๅบ
-auths.tip.facebook=`ๅจ https://developers.facebook.com/apps ๆณจๅไธไธชๆฐ็ๅบ็จ๏ผๅนถๆทปๅ ไบงๅ"Facebook ็ปๅฝ"`
-auths.tip.github=ๅจ https://github.com/settings/applications/new ๆณจๅไธไธช OAuth ๅบ็จ็จๅบ
+auths.tip.bitbucket=`ๅจ %s
+auths.tip.nextcloud=ไฝฟ็จ่ๅโ่ฎพ็ฝฎ->ๅฎๅ
จ->OAuth 2.0ๅฎขๆท็ซฏโๅจๆจ็ๅฎไพไธๆณจๅไธไธชๆฐ็ OAuth ๅฎขๆท็ซฏ
+auths.tip.dropbox=ๅจ %s ไธๅๅปบไธไธชๆฐ็ๅบ็จ็จๅบ
+auths.tip.facebook=`ๅจ %s ๆณจๅไธไธชๆฐ็ๅบ็จ๏ผๅนถๆทปๅ ไบงๅ"Facebook ็ปๅฝ"`
+auths.tip.github=ๅจ %s ๆณจๅไธไธช OAuth ๅบ็จ็จๅบ
auths.tip.gitlab=ๅจ https://gitlab.com/profile/applications ไธๆณจๅๆฐๅบ็จ็จๅบ
-auths.tip.google_plus=ไป่ฐทๆญ API ๆงๅถๅฐ (https://console.developers.google.com/) ่ทๅพ OAuth2 ๅฎขๆท็ซฏๅญๆฎ
-auths.tip.openid_connect=ไฝฟ็จ OpenID ่ฟๆฅๅ็ฐ URL (/.well-known/openid-configuration) ๆฅๆๅฎ็ป็น
-auths.tip.twitter=่ฎฟ้ฎ https://dev.twitter.com/apps๏ผๅๅปบๅบ็จๅนถ็กฎไฟๅฏ็จไบ"ๅ
่ฎธๆญคๅบ็จ็จๅบ็จไบ็ปๅฝ Twitter"็้้กนใ
-auths.tip.discord=ๅจ https://discordapp.com/developers/applications/me ไธๆณจๅๆฐๅบ็จ็จๅบ
-auths.tip.gitea=ๆณจๅไธไธชๆฐ็ OAuth2 ๅบ็จ็จๅบใๅฏไปฅ่ฎฟ้ฎ https://forgejo.org/docs/latest/user/oauth2-provider ๆฅ็ๅธฎๅฉ
-auths.tip.yandex=ๅจ https://oauth.yandex.com/client/new ไธๅๅปบไธไธชๆฐ็ๅบ็จ็จๅบใๅจโ Yandex.Passport APIโ่ฟ้จๅไธญ้ๆฉไปฅไธๆ้๏ผโ่ฎฟ้ฎ็ตๅญ้ฎไปถๅฐๅ๏ผAccess to email address๏ผโ๏ผโ่ฎฟ้ฎ็จๆทๅคดๅ๏ผAccess to user avatar๏ผโๅโ่ฎฟ้ฎ็จๆทๅ๏ผๅๅญๅๅงๆฐ๏ผๆงๅซ๏ผAccess to username, first name and surname, genderAccess to username, first name and surname, gender๏ผโ
-auths.tip.mastodon=่พๅ
ฅๆจๆณ่ฆ่ฎค่ฏ็ mastodon ๅฎไพ็่ชๅฎไน URL (ๆไฝฟ็จ้ป่ฎคๅผ)
+auths.tip.google_plus=ไป่ฐทๆญ API ๆงๅถๅฐ๏ผ%s๏ผ ่ทๅพ OAuth2 ๅฎขๆท็ซฏๅญๆฎ
+auths.tip.openid_connect=ไฝฟ็จ OpenID ่ฟๆฅๅ็ฐ URL๏ผ/.well-known/openid-configuration๏ผ ๆฅๆๅฎ็ป็น
+auths.tip.twitter=ๅๅพ %s๏ผๅๅปบไธไธชๅบ็จ็จๅบๅนถ็กฎไฟๅฏ็จไบโๅ
่ฎธๆญคๅบ็จ็จๅบ็จไบไฝฟ็จ Twitter ็ปๅฝโ้้กน
+auths.tip.discord=ๅจ %s ไธๆณจๅๆฐๅบ็จ็จๅบ
+auths.tip.gitea=ๆณจๅไธไธชๆฐ็ OAuth2 ๅบ็จ็จๅบใๅฏไปฅ่ฎฟ้ฎ %s ๆฅ็ๅธฎๅฉ
+auths.tip.yandex=ๅจ %s ไธๅๅปบไธไธชๆฐ็ๅบ็จ็จๅบใๅจโ Yandex.Passport APIโ่ฟ้จๅไธญ้ๆฉไปฅไธๆ้๏ผโ่ฎฟ้ฎ็ตๅญ้ฎไปถๅฐๅ๏ผAccess to email address๏ผโ๏ผโ่ฎฟ้ฎ็จๆทๅคดๅ๏ผAccess to user avatar๏ผโๅโ่ฎฟ้ฎ็จๆทๅ๏ผๅๅญๅๅงๆฐ๏ผๆงๅซ๏ผAccess to username, first name and surname, genderAccess to username, first name and surname, gender๏ผโ
+auths.tip.mastodon=่พๅ
ฅๆจๆณ่ฆ่ฎค่ฏ็ mastodon ๅฎไพ็่ชๅฎไน URL๏ผๆไฝฟ็จ้ป่ฎคๅผ๏ผ
auths.edit=ไฟฎๆน่ฎค่ฏๆบ
auths.activated=่ฏฅ่ฎค่ฏๆบๅทฒ็ปๅฏ็จ
auths.new_success=ๅทฒๆทปๅ ่บซไปฝ้ช่ฏ '%s'ใ
@@ -3242,8 +3385,8 @@ auths.still_in_used=่ฎค่ฏๆบไปๅจไฝฟ็จใ่ฏทๅ
่งฃ้คๆ่
ๅ ้คไฝฟ็จๆญค่ฎค
auths.deletion_success=่ฎค่ฏๆบๅทฒ็ปๆดๆฐใ
auths.login_source_exist=่ฎค่ฏๆบ '%s' ๅทฒ็ปๅญๅจใ
auths.login_source_of_type_exist=ๆญค็ฑปๅ็่ฎค่ฏๆบๅทฒๅญๅจใ
-auths.unable_to_initialize_openid=ๆ ๆณๅๅงๅ OpenID Connect ๆไพๅ๏ผ %s
-auths.invalid_openIdConnectAutoDiscoveryURL=ๆ ๆ็ Auto Discovery URL (่ฟๅฟ
้กปๆฏไธไธชไปฅ http:// ๆ https://ๅผๅคด็ๆๆ็ URL)
+auths.unable_to_initialize_openid=ๆ ๆณๅๅงๅ OpenID Connect ๆไพๅ๏ผ%s
+auths.invalid_openIdConnectAutoDiscoveryURL=ๆ ๆ็ Auto Discovery URL๏ผ่ฟๅฟ
้กปๆฏไธไธชไปฅ http:// ๆ https://ๅผๅคด็ๆๆ็ URL๏ผ
config.server_config=ๆๅกๅจ้
็ฝฎ
config.app_name=ๅฎไพๅ็งฐ
@@ -3331,7 +3474,7 @@ config.mailer_sendmail_path=Sendmail ่ทฏๅพ
config.mailer_sendmail_args=Sendmail ็้ขๅคๅๆฐ
config.mailer_sendmail_timeout=Sendmail ่ถ
ๆถ
config.mailer_use_dummy=Dummy
-config.test_email_placeholder=็ตๅญ้ฎๅ (ไพๅฆ๏ผtest@example.com)
+config.test_email_placeholder=็ตๅญ้ฎๅ๏ผไพๅฆ๏ผtest@example.com๏ผ
config.send_test_mail=ๅ้ๆต่ฏ้ฎไปถ
config.send_test_mail_submit=ๅ้
config.test_mail_failed=ๅ้ๆต่ฏ้ฎไปถ่ณ "%s" ๆถๅคฑ่ดฅ๏ผ%v
@@ -3358,7 +3501,7 @@ config.cookie_life_time=Cookie ็ๅฝๅจๆ
config.picture_config=ๅพ็ๅๅคดๅ้
็ฝฎ
config.picture_service=ๅพ็ๆๅก
config.disable_gravatar=็ฆ็จ Gravatar ๅคดๅ
-config.enable_federated_avatar=ๅฏ็จ federated avatars
+config.enable_federated_avatar=ๅฏ็จ่้ฆๅคดๅ
config.git_config=Git ้
็ฝฎ
config.git_disable_diff_highlight=็ฆ็จๅทฎๅผๅฏนๆฏ่ฏญๆณ้ซไบฎ
@@ -3403,7 +3546,7 @@ monitor.process.cancel_notices=ไธญๆญข๏ผ%s ๏ผ
monitor.process.children=ๅญ่ฟ็จ
monitor.queues=้ๅ
-monitor.queue=้ๅ๏ผ %s
+monitor.queue=้ๅ๏ผ%s
monitor.queue.name=ๅ็งฐ
monitor.queue.type=็ฑปๅ
monitor.queue.exemplar=ๆฐๆฎ็ฑปๅ
@@ -3436,27 +3579,33 @@ notices.type_2=ไปปๅก
notices.desc=ๆ็คบๆ่ฟฐ
notices.op=ๆไฝ
notices.delete_success=็ณป็ป้็ฅๅทฒ่ขซๅ ้คใ
-dashboard.sync_repo_tags = ๅฐ git ๆฐๆฎไธญ็ๆ ็ญพๅๆญฅๅฐๆฐๆฎๅบ
-dashboard.sync_tag.started = ๆ ็ญพๅๆญฅๅทฒๅผๅง
-self_check = ่ชๆฃ
-self_check.no_problem_found = ๆชๆพๅฐ้ฎ้ขใ
-self_check.database_collation_mismatch = ๆๆๆฐๆฎๅบไฝฟ็จๆๅบ่งๅ๏ผ%s
-self_check.database_collation_case_insensitive = ๆฐๆฎๅบๆญฃๅจไฝฟ็จ %s ๆๅบ่งๅ๏ผ่ฟๆฏไธ็งไธๆๆ็ๆๅบ่งๅใ ๅฐฝ็ฎก Forgejo ๅฏไปฅไฝฟ็จๅฎ๏ผไฝๅจๆๅฐๆฐๆ
ๅตไธๅฏ่ฝๆ ๆณๆ็
ง้ขๆๅทฅไฝใ
-self_check.database_inconsistent_collation_columns = ๆฐๆฎๅบๆญฃๅจไฝฟ็จ %s ๆๅบ่งๅ๏ผไฝไธ่ฟไบๅไฝฟ็จ็ๆๅบ่งๅไธๅน้
ใ ่ฟๅฏ่ฝไผๅฏผ่ดไธไบๆๆณไธๅฐ็้ฎ้ขใ
-self_check.database_fix_mysql = ๅฏนไบ MySQL/MariaDB ็จๆท๏ผๆจๅฏไปฅไฝฟ็จ "gitea doctor convert" ๅฝไปคๆฅไฟฎๅคๆๅบ่งๅ้ฎ้ข๏ผไนๅฏไปฅ้่ฟSQLๅฝไปค "ALTER ... COLLATE ..." ๆฅๆๅจไฟฎๅค้ฎ้ขใ
-
self_check.no_problem_found=ๅฐๆชๅ็ฐ้ฎ้ขใ
self_check.database_collation_mismatch=ๆๆๆฐๆฎๅบไฝฟ็จ็ๆ ก้ชๆนๅผ๏ผ%s
-self_check.database_collation_case_insensitive=ๆฐๆฎๅบๆญฃๅจไฝฟ็จไธไธชๆ ก้ช %s, ่ฟๆฏไธไธชไธๆๆ็ๆ ก้ช. ่ฝ็ถGiteaๅฏไปฅไธๅฎๅไฝ๏ผไฝๅฏ่ฝๆไธไบ็ฝ่ง็ๆ
ๅตไธๅฆ้ขๆ็้ฃๆ ท่ตทไฝ็จใ
+self_check.database_collation_case_insensitive=ๆฐๆฎๅบๆญฃๅจไฝฟ็จๆๅบ่งๅ%s๏ผ่ฟๆฏไธไธชไธๆๆ็ๆๅบ่งๅใ่ฝ็ถForgejoๅฏไปฅไธๅ
ถไธๅๅทฅไฝ๏ผไฝๅฏ่ฝๆไธไบ็ฝ่ง็ๆ
ๅตๅญๅจ้ฎ้ขใ
self_check.database_inconsistent_collation_columns=ๆฐๆฎๅบๆญฃๅจไฝฟ็จ%s็ๆๅบ่งๅ๏ผไฝๆฏ่ฟไบๅไฝฟ็จไบไธๅน้
็ๆๅบ่งๅใ่ฟๅฏ่ฝไผ้ ๆไธไบๆๅค้ฎ้ขใ
-self_check.database_fix_mysql=ๅฏนไบMySQL/MariaDB็จๆท๏ผๆจๅฏไปฅไฝฟ็จโgitea doctor convertโๅฝไปคๆฅ่งฃๅณๆ ก้ช้ฎ้ขใ ๆ่
ๆจไนๅฏไปฅ้่ฟ "ALTER ... COLLATE ..." ่ฟๆ ท็SQL ๆฅๆๅจ่งฃๅณ่ฟไธช้ฎ้ขใ
+self_check.database_fix_mysql=ๅฏนไบ MySQL/MariaDB ็จๆท๏ผๆจๅฏไปฅไฝฟ็จโforgejo doctor convertโๅฝไปคๆฅไฟฎๅคๆๅบ่งๅ้ฎ้ข๏ผๆ่
ๆจไนๅฏไปฅๆๅจ้่ฟโALTER ... COLLATE ...โ SQL ไฟฎๅค่ฏฅ้ฎ้ขใ
auths.tips.gmail_settings = Gmail ่ฎพ็ฝฎ๏ผ
-auths.tip.gitlab_new = ๅจ https://gitlab.com/-/profile/applications ไธๆณจๅๆฐๅบ็จ
+auths.tip.gitlab_new = ๅจ %s ไธๆณจๅๆฐๅบ็จ
config_settings = ่ฎพ็ฝฎ
config_summary = ๆฆๅต
auths.default_domain_name = ็จไบ็ตๅญ้ฎไปถๅฐๅ็้ป่ฎคๅๅ
config.open_with_editor_app_help = ๅ
้่ๅไธญ็โๆๅผๆนๅผโๆ็จ็็ผ่พๅจใๅฆๆ็็ฉบ๏ผๅฐไฝฟ็จ้ป่ฎคๅผใๅฑๅผไปฅๆฅ็้ป่ฎคๅผใ
config.app_slogan = ๅฎไพๆ ่ฏญ
+config.cache_test_slow = ็ผๅญๆต่ฏๆๅ๏ผไฝๅๅบ็ผๆ
ข๏ผ%sใ
+config.cache_test_failed = ๆขๆต็ผๅญๅคฑ่ดฅ๏ผ%vใ
+config.cache_test = ๆต่ฏ็ผๅญ
+emails.delete = ๅ ้ค็ตๅญ้ฎไปถ
+emails.delete_desc = ๆฏๅฆ็กฎๅฎ่ฆๅ ้คๆญค็ตๅญ้ฎไปถๅฐๅ๏ผ
+emails.deletion_success = ๅทฒๅ ้คๆญค็ตๅญ้ฎไปถๅฐๅใ
+emails.delete_primary_email_error = ๆจๆ ๆณๅ ้คไธป่ฆ็ตๅญ้ฎไปถใ
+config.cache_test_succeeded = ็ผๅญๆต่ฏๆๅ๏ผๅจ %s ไธญๆถๅฐๅๅบใ
+users.activated.description = ๅฎๆ็ตๅญ้ฎไปถ้ช่ฏใๅจ็ตๅญ้ฎไปถ้ช่ฏๅฎๆไนๅ๏ผๆชๆฟๆดป่ดฆๅท็ๆๆ่
ๅฐๆ ๆณ็ปๅฝใ
+users.block.description = ้ปๆญขๆญค็จๆท้่ฟๅ
ถ่ดฆๅทไธๆญคๆๅกไบคไบ๏ผๅนถ็ฆๆญข็ปๅฝใ
+users.admin.description = ๆไบๆญค็จๆทๅฏน้่ฟ Web UI ๅ API ๆไพ็ๆๆ็ฎก็ๅ่ฝ็ๅฎๅ
จ่ฎฟ้ฎๆ้ใ
+users.restricted.description = ไป
ๅ
่ฎธไธๆทปๅ ๆญค็จๆทไฝไธบๅไฝ่
็ไปๅบๅ็ป็ป่ฟ่กไบคไบใ่ฟๅฐ้ปๆญข่ฎฟ้ฎๆญคๅฎไพไธ็ๅ
ฌๅผไปๅบใ
+users.local_import.description = ๅ
่ฎธไปๆๅกๅจ็ๆฌๅฐๆไปถ็ณป็ปๅฏผๅ
ฅไปๅบใ่ฟๅฏ่ฝๆฏไธไธชๅฎๅ
จ้ฎ้ขใ
+users.organization_creation.description = ๅ
่ฎธๅๅปบๆฐ็ป็ปใ
+monitor.duration = ๆถ้ฟ๏ผ็ง๏ผ
[action]
create_repo=ๅๅปบไบไปๅบ %s
@@ -3464,10 +3613,10 @@ rename_repo=้ๅฝๅไปๅบ %[1]s
ไธบ %[3]s
commit_repo=ๆจ้ๅฐไบไปๅบ %[4]s ็ %[3]s ๅๆฏ
create_issue=`ๅๅปบไบๅทฅๅ %[3]s#%[2]s `
close_issue=`ๅ
ณ้ญไบๅทฅๅ %[3]s#%[2]s `
-reopen_issue=`้ๆฐๅผๅฏไบๅทฅๅ %[3]s#%[2]s `
+reopen_issue=`้ๆฐๅผๆพไบๅทฅๅ %[3]s#%[2]s `
create_pull_request=`ๅๅปบไบๅๅนถ่ฏทๆฑ %[3]s#%[2]s `
close_pull_request=`ๅ
ณ้ญไบๅๅนถ่ฏทๆฑ %[3]s#%[2]s `
-reopen_pull_request=`้ๆฐๅผๅฏไบๅๅนถ่ฏทๆฑ %[3]s#%[2]s `
+reopen_pull_request=`้ๆฐๅผๆพไบๅๅนถ่ฏทๆฑ %[3]s#%[2]s `
comment_issue=`่ฏ่ฎบไบๅทฅๅ %[3]s#%[2]s `
comment_pull=`่ฏ่ฎบไบๅๅนถ่ฏทๆฑ %[3]s#%[2]s `
merge_pull_request=`ๅๅนถไบๅๅนถ่ฏทๆฑ %[3]s#%[2]s `
@@ -3498,9 +3647,9 @@ future=ๅฐๆฅ
1m=1ๅ้
1h=1 ๅฐๆถ
1d=1 ๅคฉ
-1w=1ๅจ
+1w=1 ๅจ
1mon=1 ไธชๆ
-1y=1ๅนด
+1y=1 ๅนด
seconds=%d ็ง
minutes=%d ๅ้
hours=%d ๅฐๆถ
@@ -3512,17 +3661,17 @@ raw_seconds=็ง
raw_minutes=ๅ้
[dropzone]
-default_message=ๆๅจๆไปถๆ่
็นๅปๆญคๅคไธไผ ใ
-invalid_input_type=ๆจไธ่ฝไธไผ ่ฏฅ็ฑปๅ็ๆไปถ
-file_too_big=ๆไปถไฝ็งฏ๏ผ{{filesize}} MB๏ผ่ถ
่ฟไบๆๅคงๅ
่ฎธไฝ็งฏ๏ผ{{maxFilesize}} MB๏ผ
+default_message=ๆๆพๆไปถๆ็นๅปๆญคๅคไธไผ ใ
+invalid_input_type=ๆจไธ่ฝไธไผ ่ฏฅ็ฑปๅ็ๆไปถใ
+file_too_big=ๆไปถไฝ็งฏ๏ผ{{filesize}} MB๏ผ่ถ
่ฟไบๆๅคงๅ
่ฎธไฝ็งฏ๏ผ{{maxFilesize}} MB๏ผใ
remove_file=็งป้คๆไปถ
[notification]
notifications=้็ฅ
-unread=ๆช่ฏปๆถๆฏ
-read=ๅทฒ่ฏปๆถๆฏ
+unread=ๆช่ฏป
+read=ๅทฒ่ฏป
no_unread=ๆฒกๆๆช่ฏป้็ฅใ
-no_read=ๆฒกๆๆช่ฏป้็ฅใ
+no_read=ๆฒกๆๅทฒ่ฏป้็ฅใ
pin=Pin ้็ฅ
mark_as_read=ๆ ่ฎฐไธบๅทฒ่ฏป
mark_as_unread=ๆ ่ฎฐไธบๆช่ฏป
@@ -3545,7 +3694,7 @@ error.probable_bad_default_signature=่ญฆๅ๏ผ่ฝ็ถ้ป่ฎคๅฏ้ฅๆฅๆๆญคID๏ผ
[units]
unit=ๅๅ
error.no_unit_allowed_repo=ๆจๆฒกๆ่ขซๅ
่ฎธ่ฎฟ้ฎๆญคไปๅบ็ไปปไฝๅๅ
ใ
-error.unit_not_allowed=ๆจๆฒกๆๆ้่ฎฟ้ฎๆญคไปๅบๅๅ
+error.unit_not_allowed=ๆจๆฒกๆๆ้่ฎฟ้ฎๆญคไปๅบๅๅ
ใ
[packages]
title=่ฝฏไปถๅ
@@ -3569,10 +3718,10 @@ keywords=ๅ
ณ้ฎ่ฏ
details=่ฏฆๆ
details.author=ไฝ่
details.project_site=้กน็ฎ็ซ็น
-details.repository_site=ไปๅบ็ซ็น
+details.repository_site=ไปๅบ็ฝ็ซ
details.documentation_site=ๆๆกฃ็ซ็น
details.license=่ฎธๅฏๅ่ฎฎ
-assets=ๆไปถ
+assets=่ตๆบ
versions=็ๆฌ
versions.view_all=ๆฅ็ๅ
จ้จ
dependency.id=ID
@@ -3585,7 +3734,7 @@ alpine.repository=ไปๅบไฟกๆฏ
alpine.repository.branches=ๅๆฏ
alpine.repository.repositories=ไปๅบ็ฎก็
alpine.repository.architectures=ๆถๆ
-cargo.registry=ๅจ Cargo ้
็ฝฎๆไปถไธญ่ฎพ็ฝฎๆญคๆณจๅไธญๅฟ(ไพๅฆ๏ผ~/.cargo/config.toml
)๏ผ
+cargo.registry=ๅจ Cargo ้
็ฝฎๆไปถไธญ่ฎพ็ฝฎๆญคๆณจๅไธญๅฟ๏ผไพๅฆ๏ผ~/.cargo/config.toml
๏ผ๏ผ
cargo.install=่ฆไฝฟ็จ Cargo ๅฎ่ฃ
่ฝฏไปถๅ
๏ผ่ฏท่ฟ่กไปฅไธๅฝไปค๏ผ
chef.registry=ๅจๆจ็ ~/.chef/config.rb
ๆไปถไธญ่ฎพ็ฝฎๆญคๆณจๅไธญๅฟ๏ผ
chef.install=่ฆๅฎ่ฃ
ๅ
๏ผ่ฏท่ฟ่กไปฅไธๅฝไปค๏ผ
@@ -3601,9 +3750,9 @@ conda.install=่ฆไฝฟ็จ Conda ๅฎ่ฃ
่ฝฏไปถๅ
๏ผ่ฏท่ฟ่กไปฅไธๅฝไปค๏ผ
container.details.type=้ๅ็ฑปๅ
container.details.platform=ๅนณๅฐ
container.pull=ไปๅฝไปค่กๆๅ้ๅ๏ผ
-container.digest=ๆ่ฆ๏ผ
-container.multi_arch=OS / Arch
-container.layers=้ๅๅฑ
+container.digest=ๆ่ฆ
+container.multi_arch=ๆไฝ็ณป็ป / ๆถๆ
+container.layers=้ๅๅๅฑ
container.labels=ๆ ็ญพ
container.labels.key=้ฎ
container.labels.value=ๅผ
@@ -3632,7 +3781,7 @@ npm.install=่ฆไฝฟ็จ npm ๅฎ่ฃ
่ฝฏไปถๅ
๏ผ่ฏท่ฟ่กไปฅไธๅฝไปค๏ผ
npm.install2=ๆๅฐๅ
ถๆทปๅ ๅฐ package.json ๆไปถ๏ผ
npm.dependencies=ไพ่ต้กน
npm.dependencies.development=ๅผๅไพ่ต
-npm.dependencies.peer=Peer ไพ่ต
+npm.dependencies.peer=ๅ็ญไพ่ต
npm.dependencies.optional=ๅฏ้ไพ่ต
npm.details.tag=ๆ ็ญพ
pub.install=่ฆไฝฟ็จ Dart ๅฎ่ฃ
่ฝฏไปถๅ
๏ผ่ฏท่ฟ่กไปฅไธๅฝไปค๏ผ
@@ -3642,9 +3791,9 @@ rpm.registry=ไปๅฝไปค่ก่ฎพ็ฝฎๆญคๆณจๅไธญๅฟ๏ผ
rpm.distros.redhat=ๅจๅบไบ RedHat ็ๅ่ก็
rpm.distros.suse=ๅจๅบไบ SUSE ็ๅ่ก็
rpm.install=่ฆๅฎ่ฃ
ๅ
๏ผ่ฏท่ฟ่กไปฅไธๅฝไปค๏ผ
-rpm.repository=ไปๅบไฟกๆฏ
-rpm.repository.architectures=ๆถๆ
-rpm.repository.multiple_groups=ๆญค่ฝฏไปถๅ
ๅฏๅจๅคไธช็ปไธญไฝฟ็จใ
+rpm.repository = ไปๅบไฟกๆฏ
+rpm.repository.architectures = ๆถๆ
+rpm.repository.multiple_groups = ่ฏฅ่ฝฏไปถๅ
ๅฏๅจๅคไธช็ปไธญไฝฟ็จใ
rubygems.install=่ฆไฝฟ็จ gem ๅฎ่ฃ
่ฝฏไปถๅ
๏ผ่ฏท่ฟ่กไปฅไธๅฝไปค๏ผ
rubygems.install2=ๆๅฐๅฎๆทปๅ ๅฐ Gemfile๏ผ
rubygems.dependencies.runtime=่ฟ่กๆถไพ่ต
@@ -3663,17 +3812,17 @@ settings.link.success=ไปๅบ้พๆฅๅทฒๆๅๆดๆฐใ
settings.link.error=ๆดๆฐไปๅบ้พๆฅๅคฑ่ดฅใ
settings.delete=ๅ ้ค่ฝฏไปถๅ
settings.delete.description=ๅ ้ค่ฝฏไปถๅ
ๆฏๆฐธไน
ๆง็๏ผๆ ๆณๆคๆถใ
-settings.delete.notice=ๆจๅฐ่ฆๅ ้ค %s (%s)ใๆญคๆไฝๆฏไธๅฏ้็๏ผๆจ็กฎๅฎๅ๏ผ
+settings.delete.notice=ๆจๅฐ่ฆๅ ้ค %s๏ผ%s๏ผใๆญคๆไฝๆฏไธๅฏ้็๏ผๆจ็กฎๅฎๅ๏ผ
settings.delete.success=่ฝฏไปถๅ
ๅทฒ่ขซๅ ้คใ
settings.delete.error=ๅ ้ค่ฝฏไปถๅ
ๅคฑ่ดฅใ
owner.settings.cargo.title=Cargo ๆณจๅไธญๅฟ็ดขๅผ
owner.settings.cargo.initialize=ๅๅงๅ็ดขๅผ
-owner.settings.cargo.initialize.description=ไฝฟ็จ Cargo ๆณจๅไธญๅฟๆถ้่ฆไธไธช็นๆฎ็ดขๅผ็ Git ไปๅบใไฝฟ็จๆญค้้กนๅฐ๏ผ้ๆฐ๏ผๅๅปบๅญๅจๅบๅนถ่ชๅจ้
็ฝฎๅฎใ
-owner.settings.cargo.initialize.error=ๅๅงๅCargo็ดขๅผๅคฑ่ดฅ๏ผ %v
+owner.settings.cargo.initialize.description=ไฝฟ็จ Cargo ๆณจๅไธญๅฟๆถ้่ฆไธไธช็นๆฎ็ดขๅผ็ Git ไปๅบใไฝฟ็จๆญค้้กนๅฐ๏ผ้ๆฐ๏ผๅๅปบไปๅบๅนถ่ชๅจ้
็ฝฎๅฎใ
+owner.settings.cargo.initialize.error=ๅๅงๅCargo็ดขๅผๅคฑ่ดฅ๏ผ%v
owner.settings.cargo.initialize.success=Cargo็ดขๅผๅทฒ็ปๆๅๅๅปบใ
owner.settings.cargo.rebuild=้ๅปบ็ดขๅผ
owner.settings.cargo.rebuild.description=ๅฆๆ็ดขๅผไธๅญๅจ็ Cargo ๅ
ไธๅๆญฅ๏ผ้ๅปบๅฏ่ฝไผๆ็จใ
-owner.settings.cargo.rebuild.error=ๆ ๆณ้ๅปบ Cargo ็ดขๅผ: %v
+owner.settings.cargo.rebuild.error=ๆ ๆณ้ๅปบ Cargo ็ดขๅผ๏ผ%v
owner.settings.cargo.rebuild.success=Cargo ็ดขๅผๅทฒๆๅ้ๅปบใ
owner.settings.cleanuprules.title=ๆธ
็่งๅ
owner.settings.cleanuprules.add=ๆทปๅ ๆธ
็่งๅ
@@ -3689,7 +3838,7 @@ owner.settings.cleanuprules.keep.count=ไฟ็ๆๆฐ็
owner.settings.cleanuprules.keep.count.1=ๆฏไธช่ฝฏไปถๅ
1ไธช็ๆฌ
owner.settings.cleanuprules.keep.count.n=ๆฏไธช่ฝฏไปถๅ
%d ไธช็ๆฌ
owner.settings.cleanuprules.keep.pattern=ไฟๆ็ๆฌๅน้
-owner.settings.cleanuprules.keep.pattern.container=ๅฎนๅจๅ
็ ๆๆฐ็ๆฌ
ๆปๆฏไผไฟ็ใ
+owner.settings.cleanuprules.keep.pattern.container=ๅฎนๅจ็latest
็ๆฌๆปๆฏไผ่ขซไฟ็ใ
owner.settings.cleanuprules.remove.title=ไธ่ฟไบ่งๅ็ธๅน้
็็ๆฌๅฐ่ขซๅ ้ค๏ผ้ค้ๅ
ถไธญๅญๅจๆไธชไฟ็ๅฎไปฌ็่งๅใ
owner.settings.cleanuprules.remove.days=็งป้คๆงไบๅคฉๆฐ็็ๆฌ
owner.settings.cleanuprules.remove.pattern=ๅ ้คๅน้
็็ๆฌ
@@ -3698,19 +3847,41 @@ owner.settings.cleanuprules.success.delete=ๆธ
็่งๅๅทฒๅ ้คใ
owner.settings.chef.title=Chef ๆณจๅไธญๅฟ
owner.settings.chef.keypair=็ๆๅฏ้ฅๅฏน
owner.settings.chef.keypair.description=้่ฆๅฏ้ฅๅฏนๆ่ฝๅ Chef ๆณจๅไธญๅฟ่ฟ่ก่บซไปฝ้ช่ฏใๅฆๆๆจไนๅๅทฒ็ป็ๆ่ฟๅฏ้ฅๅฏน๏ผ็ๆๆฐ็ๅฏ้ฅๅฏนๅฐไธขๅผๆง็ๅฏ้ฅๅฏนใ
-rpm.repository = ไปๅบไฟกๆฏ
-rpm.repository.architectures = ๆถๆ
-rpm.repository.multiple_groups = ่ฏฅ่ฝฏไปถๅ
ๅฏๅจๅคไธช็ปไธญไฝฟ็จใ
owner.settings.cargo.rebuild.no_index = ๆ ๆณ้ๅปบ๏ผๆชๅๅงๅไปปไฝ็ดขๅผใ
-npm.dependencies.bundle = ๆ็ปไพ่ต้กน
+npm.dependencies.bundle = ๆ็ป็ไพ่ต้กน
+arch.pacman.helper.gpg = ไธบ pacman ๆทปๅ ไฟกไปป่ฏไนฆ๏ผ
+arch.pacman.repo.multi = %s ๅจไธๅ็ๅ่ก็ไธญๆ็ธๅ็็ๆฌใ
+arch.pacman.repo.multi.item = %s ็้
็ฝฎ
+arch.pacman.conf = ๅฐๅ
ทๆ็ธๅ
ณๅ่ก็ๅๆถๆ็ๆๅกๅจๆทปๅ ๅฐ /etc/pacman.conf
ไธญ๏ผ
+arch.pacman.sync = ๅจ pacman ไธๅๆญฅ่ฝฏไปถๅ
๏ผ
+arch.version.properties = ็ๆฌๅฑๆง
+arch.version.description = ่ฏดๆ
+arch.version.provides = ๆไพ
+arch.version.groups = ็ป
+arch.version.depends = ไพ่ต
+arch.version.optdepends = ๅฏ้ไพ่ต
+arch.version.conflicts = ๅฒ็ช
+arch.version.replaces = ๆฟๆข
+arch.version.backup = ๅคไปฝ
+arch.version.checkdepends = ๆฃๆฅไพ่ต
+arch.version.makedepends = ็ผ่ฏไพ่ต
+container.images.title = ้ๅ
+search_in_external_registry = ๅจ %s ไธญๆ็ดข
+alt.registry.install = ่ฆๅฎ่ฃ
ๆญค่ฝฏไปถๅ
๏ผ่ฏท่ฟ่กไปฅไธๅฝไปค๏ผ
+alt.install = ๅฎ่ฃ
่ฝฏไปถๅ
+alt.registry = ้่ฟๅฝไปค่ก้
็ฝฎๆญคๆณจๅ่กจ๏ผ
+alt.setup = ๆทปๅ ไธไธชไปๅบๅฐ่ฟๆฅ็ไปๅบๅ่กจ๏ผ้ๆฉๅฟ
่ฆ็ๆถๆ่้โ_arch_โ๏ผ๏ผ
+alt.repository = ไปๅบไฟกๆฏ
+alt.repository.architectures = ๆถๆ
+alt.repository.multiple_groups = ๆญค่ฝฏไปถๅ
ๅจๅคไธช็ปไธญๅฏ็จใ
[secrets]
secrets=ๅฏ้ฅ
-description=Secrets ๅฐ่ขซไผ ็ป็นๅฎ็ Actions๏ผๅ
ถๅฎๆ
ๅตๅฐไธ่ฝ่ฏปๅ
+description=ๆบๅฏๅฐ่ขซไผ ็ป็นๅฎ็ Action๏ผๅ
ถๅฎๆ
ๅตๅฐไธ่ฝ่ขซ่ฏปๅใ
none=่ฟๆฒกๆๅฏ้ฅใ
creation=ๆทปๅ ๅฏ้ฅ
-creation.name_placeholder=ไธๅบๅๅคงๅฐๅ๏ผๅญๆฏๆฐๅญๆไธๅ็บฟไธ่ฝไปฅGITEA_ ๆ GITHUB_ ๅผๅคดใ
-creation.value_placeholder=่พๅ
ฅไปปไฝๅ
ๅฎน๏ผๅผๅคดๅ็ปๅฐพ็็ฉบ็ฝ้ฝไผ่ขซ็็ฅ
+creation.name_placeholder=ไธๅบๅๅคงๅฐๅ๏ผๅช่ฝๅ
ๅซ่ฑๆๅญๆฏใๆฐๅญๆไธๅ็บฟ๏ผไธ่ฝไปฅ GITEA_ ๆ GITHUB_ ๅผๅคด
+creation.value_placeholder=่พๅ
ฅไปปไฝๅ
ๅฎนใๅผๅคดๅ็ปๅฐพ็็ฉบๆ ผ้ฝไผ่ขซ็็ฅใ
creation.success=ๆจ็ๅฏ้ฅ '%s' ๆทปๅ ๆๅใ
creation.failed=ๆทปๅ ๅฏ้ฅๅคฑ่ดฅใ
deletion=ๅ ้คๅฏ้ฅ
@@ -3722,7 +3893,7 @@ management=ๅฏ้ฅ็ฎก็
[actions]
actions=Actions
-unit.desc=ไฝฟ็จ Forgejo Actions ็ฎก็้ๆ็ CI/CD ็ฎก้
+unit.desc=ไฝฟ็จ Forgejo Actions ็ฎก็้ๆ็ CI/CD ็ฎก้ใ
status.unknown=ๆช็ฅ
status.waiting=็ญๅพ
ไธญ
@@ -3733,9 +3904,9 @@ status.cancelled=ๅทฒๅๆถ
status.skipped=ๅทฒๅฟฝ็ฅ
status.blocked=้ปๅกไธญ
-runners=Runners
-runners.runner_manage_panel=็ฎก็ Runners
-runners.new=ๅๅปบ Runner
+runners=่ฟ่กๅจ
+runners.runner_manage_panel=็ฎก็่ฟ่กๅจ
+runners.new=ๅๅปบๆฐ่ฟ่กๅจ
runners.new_notice=ๅฆไฝๅฏๅจไธไธช่ฟ่กๅจ
runners.status=็ถๆ
runners.id=ID
@@ -3744,8 +3915,8 @@ runners.owner_type=็ฑปๅ
runners.description=็ป็ปๆ่ฟฐ
runners.labels=ๆ ็ญพ
runners.last_online=ไธๆฌกๅจ็บฟๆถ้ด
-runners.runner_title=Runner
-runners.task_list=ๆ่ฟๅจๆญคrunnerไธ็ไปปๅก
+runners.runner_title=่ฟ่กๅจ
+runners.task_list=ๆ่ฟๅจๆญค่ฟ่กๅจไธ็ไปปๅก
runners.task_list.no_tasks=่ฟๆฒกๆไปปๅกใ
runners.task_list.run=ๆง่ก
runners.task_list.status=็ถๆ
@@ -3761,7 +3932,7 @@ runners.delete_runner_success=่ฟ่กๅจๅ ้คๆๅ
runners.delete_runner_failed=ๅ ้ค่ฟ่กๅจๅคฑ่ดฅ
runners.delete_runner_header=็กฎ่ฎค่ฆๅ ้คๆญค่ฟ่กๅจ
runners.delete_runner_notice=ๅฆๆไธไธชไปปๅกๆญฃๅจ่ฟ่กๅจๆญค่ฟ่กๅจไธ๏ผๅฎๅฐ่ขซ็ปๆญขๅนถๆ ่ฎฐไธบๅคฑ่ดฅใๅฎๅฏ่ฝไผๆๆญๆญฃๅจๆๅปบ็ๅทฅไฝๆตใ
-runners.none=ๆ ๅฏ็จ็ Runner
+runners.none=ๆ ๅฏ็จ็่ฟ่กๅจ
runners.status.unspecified=ๆช็ฅ
runners.status.idle=็ฉบ้ฒ
runners.status.active=ๆฟๆดป
@@ -3774,8 +3945,8 @@ runs.all_workflows=ๆๆๅทฅไฝๆต
runs.commit=ๆไบค
runs.scheduled=ๅทฒ่ฎกๅ็
runs.pushed_by=ๆจ้่
-runs.invalid_workflow_helper=ๅทฅไฝๆต้
็ฝฎๆไปถๆ ๆใ่ฏทๆฃๆฅๆจ็้
็ฝฎๆไปถ๏ผ %s
-runs.no_matching_online_runner_helper=ๆฒกๆๅน้
ๆ ็ญพ็ๅจ็บฟ runner๏ผ %s
+runs.invalid_workflow_helper=ๅทฅไฝๆต้
็ฝฎๆไปถๆ ๆใ่ฏทๆฃๆฅๆจ็้
็ฝฎๆไปถ๏ผ%s
+runs.no_matching_online_runner_helper=ๆฒกๆๅน้
ๆ ็ญพ็ๅจ็บฟ่ฟ่กๅจ๏ผ%s
runs.actor=ๆไฝ่
runs.status=็ถๆ
runs.actors_no_select=ๆๆๆไฝ่
@@ -3785,7 +3956,7 @@ runs.no_workflows=็ฎๅ่ฟๆฒกๆๅทฅไฝๆตใ
runs.no_workflows.quick_start=ไธ็ฅ้ๅฆไฝไฝฟ็จ Forgejo Actionsๅ๏ผ่ฏทๆฅ็ ๅฟซ้ๅฏๅจๆๅ ใ
runs.no_workflows.documentation=ๅ
ณไบForgejo Actions็ๆดๅคไฟกๆฏ๏ผ่ฏทๅ้
ๆๆกฃ ใ
runs.no_runs=ๅทฅไฝๆตๅฐๆช่ฟ่ก่ฟใ
-runs.empty_commit_message=(็ฉบ็ฝ็ๆไบคๆถๆฏ)
+runs.empty_commit_message=๏ผ็ฉบ็ฝ็ๆไบคๆถๆฏ๏ผ
workflow.disable=็ฆ็จๅทฅไฝๆต
workflow.disable_success=ๅทฅไฝๆต "%s" ๅทฒๆๅ็ฆ็จใ
@@ -3801,7 +3972,7 @@ variables.creation=ๆทปๅ ๅ้
variables.none=็ฎๅ่ฟๆฒกๆๅ้ใ
variables.deletion=ๅ ้คๅ้
variables.deletion.description=ๅ ้คๅ้ๆฏๆฐธไน
ๆง็๏ผๆ ๆณๆคๆถใ็ปง็ปญๅ๏ผ
-variables.description=ๅ้ๅฐ่ขซไผ ็ป็นๅฎ็ Actions๏ผๅ
ถๅฎๆ
ๅตๅฐไธ่ฝ่ฏปๅ
+variables.description=ๅ้ๅฐ่ขซไผ ็ป็นๅฎ็ Action๏ผๅ
ถๅฎๆ
ๅตๅฐไธ่ฝ่ขซ่ฏปๅใ
variables.id_not_exist=IDไธบ %d ็ๅ้ไธๅญๅจใ
variables.edit=็ผ่พๅ้
variables.deletion.failed=ๅ ้คๅ้ๅคฑ่ดฅใ
@@ -3813,15 +3984,26 @@ variables.update.success=่ฏฅๅ้ๅทฒ่ขซ็ผ่พใ
runs.workflow = ๅทฅไฝๆต
runs.no_job_without_needs = ๅทฅไฝๆตๅฟ
้กป่ณๅฐๅ
ๅซไธ็ปๆฒกๆไพ่ต็ไฝไธใ
runs.no_job = ๅทฅไฝๆตๅฟ
้กป่ณๅฐๅ
ๅซไธไธชไฝไธ
+workflow.dispatch.trigger_found = ๆญคๅทฅไฝๆตๆ workflow_dispatch ไบไปถ่งฆๅๅจใ
+workflow.dispatch.use_from = ไฝฟ็จๅทฅไฝๆต
+workflow.dispatch.invalid_input_type = ่พๅ
ฅ็ฑปๅโ%sโๆ ๆใ
+workflow.dispatch.warn_input_limit = ไป
ๆพ็คบๅ %d ไธช่พๅ
ฅใ
+workflow.dispatch.run = ่ฟ่กๅทฅไฝๆต
+workflow.dispatch.success = ๅทฒๆๅ่ฏทๆฑๅทฅไฝๆต่ฟ่กใ
+workflow.dispatch.input_required = ้่ฆ่พๅ
ฅโ%sโ็ๅผใ
+runs.expire_log_message = ๅทฒๆธ
้คๆฅๅฟ๏ผๅ ไธบๅฎไปฌๅคชๆงไบใ
+runs.no_workflows.help_write_access = ไธ็ฅ้ๅฆไฝไธๆ Forgejo Actions๏ผๆฅ็็จๆทๆๆกฃ็ๅฟซ้ไธๆ้จๅ ๆฅ็ผๅไฝ ็็ฌฌไธไธชๅทฅไฝๆต๏ผ็ถๅ้
็ฝฎไธไธชForgejo่ฟ่กๅจ ๆฅ่ฟ่กไฝ ็ไปปๅกใ
+runs.no_workflows.help_no_write_access = ๆฌฒไบ่งฃๅ
ณไบForgejo Actions็ๆดๅคไฟกๆฏ๏ผ่ฏทๅ่งๆๆกฃ ใ
+variables.not_found = ๆพไธๅฐๅ้ใ
[projects]
type-1.display_name=ไธชไบบ้กน็ฎ
type-2.display_name=ไปๅบ้กน็ฎ
type-3.display_name=็ป็ป้กน็ฎ
+deleted.display_name = ๅทฒๅ ้ค้กน็ฎ
[git.filemode]
changed_filemode=%[1]s -> %[2]s
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
directory=็ฎๅฝ
normal_file=ๆฎ้ๆไปถ
executable_file=ๅฏๆง่กๆไปถ
@@ -3831,30 +4013,35 @@ submodule=ๅญๆจกๅ
[search]
-keyword_search_unavailable = ๅ
ณ้ฎ่ฏๆ็ดข็ฎๅไธๅฏ็จ๏ผ่ฏท่็ณป็ซ็น็ฎก็ๅใ
-search = ๆ็ดข...
-repo_kind = ๆ็ดขไปๅบ...
-user_kind = ๆ็ดข็จๆท...
-org_kind = ๆ็ดข็ป็ป...
-team_kind = ๆ็ดขๅข้...
-code_kind = ๆ็ดขไปฃ็ ...
-code_search_unavailable = ไปฃ็ ๆ็ดข็ฎๅไธๅฏ็จ๏ผ่ฏท่็ณป็ซ็น็ฎก็ๅใ
-package_kind = ๆ็ดข่ฝฏไปถๅ
...
-project_kind = ๆ็ดข้กน็ฎ...
-branch_kind = ๆ็ดขๅๆฏ...
-commit_kind = ๆ็ดขๆไบค...
-runner_kind = ๆ็ดขRunners...
+keyword_search_unavailable = ๅ
ณ้ฎ่ฏๆ็ดข็ฎๅไธๅฏ็จใ่ฏท่็ณป็ซ็น็ฎก็ๅใ
+search = ๆ็ดขโฆ
+repo_kind = ๆ็ดขไปๅบโฆ
+user_kind = ๆ็ดข็จๆทโฆ
+org_kind = ๆ็ดข็ป็ปโฆ
+team_kind = ๆ็ดขๅข้โฆ
+code_kind = ๆ็ดขไปฃ็ โฆ
+code_search_unavailable = ไปฃ็ ๆ็ดข็ฎๅไธๅฏ็จใ่ฏท่็ณป็ซ็น็ฎก็ๅใ
+package_kind = ๆ็ดข่ฝฏไปถๅ
โฆ
+project_kind = ๆ็ดข้กน็ฎโฆ
+branch_kind = ๆ็ดขๅๆฏโฆ
+commit_kind = ๆ็ดขๆไบคโฆ
+runner_kind = ๆ็ดข่ฟ่กๅจโฆ
no_results = ๆชๆพๅฐๅน้
็็ปๆใ
type_tooltip = ๆ็ดข็ฑปๅ
fuzzy = ๆจก็ณ
code_search_by_git_grep = ๅฝๅๆ็ดข็ปๆ็ฑ git grep ๆไพ๏ผๅฆๆ็ซ็น็ฎก็ๅๅฏ็จไบไปฃ็ ็ดขๅผๅฏ่ฝไผๆๆดๅฅฝ็็ปๆใ
match = ๅน้
match_tooltip = ไป
ๅ
ๅซไธๆ็ดข่ฏๅฎๅ
จๅน้
็็ปๆ
-fuzzy_tooltip = ๅจๆ็ดข็ปๆไธญๅ
ๅซไธๆ็ดข่ฏ็ธ่ฟ็้กน็ฎ
+fuzzy_tooltip = ๅ
ๅซไธๆ็ดข่ฏ็ธ่ฟ็็ปๆ
exact = ็ฒพ็กฎ
-issue_kind = ๆ็ดขๅทฅๅ...
-pull_kind = ๆ็ดขๆๅ...
-exact_tooltip = ไป
ๅ
ๅซไธ็ฒพ็กฎๆ็ดข่ฏๅน้
็็ปๆ
+issue_kind = ๆ็ดขๅทฅๅโฆ
+pull_kind = ๆ็ดขๅๅนถ่ฏทๆฑโฆ
+exact_tooltip = ไป
ๅ
ๅซไธๆ็ดข่ฏ็ฒพ็กฎๅน้
็็ปๆ
+milestone_kind = ๆ็ดข้็จ็ขโฆ
+union_tooltip = ๅ
ๆฌไธไปฅ็ฉบๆ ผๅ้็ๅ
ณ้ฎๅญไธญไปปๆไธไธช็ธๅน้
็็ปๆ
+union = ๅ
ณ้ฎๅญ
+regexp = ๆญฃๅ่กจ่พพๅผ
+regexp_tooltip = ๅฐๆ็ดขๅ
ๅฎน่งฃ้ไธบๆญฃๅ่กจ่พพๅผ
[munits.data]
@@ -3869,4 +4056,27 @@ mib = MiB
[markup]
filepreview.line = %[2]s ไธญ็็ฌฌ %[1]d ่ก
filepreview.lines = %[3]s ไธญ็็ฌฌ %[1]d ๅฐ %[2]d ่ก
-filepreview.truncated = ้ข่งๅทฒ่ขซๆชๆญ
\ No newline at end of file
+filepreview.truncated = ้ข่งๅทฒ่ขซๆชๆญ
+
+[translation_meta]
+test = ๅฅฝ็
+
+[repo.permissions]
+code.write = ๅๅ
ฅ๏ผ ๆจ้ๅฐไปๅบ๏ผๅๅปบๅๆฏๅๆ ็ญพใ
+code.read = ่ฏปๅ๏ผ ่ฎฟ้ฎๅนถๅ
้ไปๅบ็ไปฃ็ ใ
+actions.read = ่ฏปๅ๏ผ ๆฅ็้ๆ็ CI/CD ็ฎก้ๅๅ
ถๆฅๅฟใ
+issues.write = ๅๅ
ฅ๏ผ ๅ
ณ้ญๅทฅๅๅนถ็ฎก็ๅ
ๆฐๆฎ๏ผๅฆๆ ็ญพใ้็จ็ขใๆๆดพๆๅใๆชๆญขๆฅๆๅไพ่ตใ
+releases.write = ๅๅ
ฅ๏ผ ๅๅธใ็ผ่พๅๅ ้ค็ๆฌๅๅธๅๅ
ถ่ตๆบใ
+issues.read = ่ฏปๅ๏ผ ้
่ฏปๅนถๅๅปบๅทฅๅๅ่ฏ่ฎบใ
+pulls.read = ่ฏปๅ๏ผ ้
่ฏปๅนถๅๅปบๅๅนถ่ฏทๆฑใ
+releases.read = ่ฏปๅ๏ผ ๆฅ็ๅนถไธ่ฝฝ็ๆฌๅๅธใ
+wiki.read = ่ฏปๅ๏ผ ้
่ฏป้ๆ็็พ็งๅๅ
ถๅๅฒใ
+wiki.write = ๅๅ
ฅ๏ผ ๅจ้ๆ็็พ็งไธญๅๅปบใๆดๆฐๅๅ ้ค้กต้ขใ
+projects.read = ่ฏปๅ๏ผ ่ฎฟ้ฎไปๅบ้กน็ฎ็ๆฟใ
+packages.read = ่ฏปๅ๏ผ ๆฅ็ๅนถไธ่ฝฝๆๆดพ็ปไปๅบ็่ฝฏไปถๅ
ใ
+packages.write = ๅๅ
ฅ๏ผ ๅๅธๅนถๅ ้คๆๆดพ็ปไปๅบ็่ฝฏไปถๅ
ใ
+actions.write = ๅๅ
ฅ๏ผ ๆๅจ่งฆๅใ้ๅฏใๅๆถๆๆนๅๅพ
ๅค็็ CI/CD ็ฎก้ใ
+ext_issues = ่ฎฟ้ฎๅค้จๅทฅๅ็ณป็ป็้พๆฅใๆ้็ฑๅค้จ็ฎก็ใ
+ext_wiki = ่ฎฟ้ฎๅค้จ็พ็ง็้พๆฅใๆ้็ฑๅค้จ็ฎก็ใ
+projects.write = ๅๅ
ฅ๏ผ ๅๅปบ้กน็ฎๅๅๅนถ่ฟ่ก็ผ่พใ
+pulls.write = ๅๅ
ฅ๏ผ ๅ
ณ้ญๅๅนถ่ฏทๆฑๅนถ็ฎก็ๅ
ๆฐๆฎ๏ผๅฆๆ ็ญพใ้็จ็ขใๆๆดพๆๅใๆชๆญขๆฅๆๅไพ่ตใ
diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini
index 941f93bfc3..93744cbbcf 100644
--- a/options/locale/locale_zh-HK.ini
+++ b/options/locale/locale_zh-HK.ini
@@ -24,8 +24,8 @@ organization=็ต็น
mirror=้กๅ
new_repo=ๆฐๅขๅฒๅญๅบซ
new_migrate=้ท็งปๅค้จๅฒๅญๅบซ
-new_mirror=ๆฐ้กๅ
-new_fork=Fork ๆฐ็ๅฒๅญๅบซ
+new_mirror=ๆฐๅข้กๅ
+new_fork=ๆฐๅขๅฒๅญๅบซๅๅ
new_org=ๆฐๅข็ต็น
manage_org=็ฎก็็ต็น
account_settings=ๅธณ่่จญๅฎ
@@ -67,7 +67,7 @@ email = ้ปๅญไฟก็ฎฑ
access_token = ่จชๅไปค็
powered_by = ็ฑ %s ๆไพ
create_new = ๅปบ็ซโฆ
-user_profile_and_more = ๅไบบ่ณๆๅๅ่จญๅฎโฆ
+user_profile_and_more = ๅไบบ่ณๆๅ่จญๅฎโฆ
signed_in_as = ๅทฒ็ถ็ปๅ
ฅ
toc = ็ฎ้
licenses = ่ปไปถๆๆฌ
@@ -88,10 +88,61 @@ webauthn_error_unable_to_process = ไผบๆๅจๅๅฏไปฅๅท่กไฝ ๅ
่ซๆฑใ
logo = ๆจ่ญ
enable_javascript = ๆฌ็ถฒ็ซ้่ฆ JavaScriptใ
webauthn_error_empty = ไฝ ่ฆ่ตทๅๅขๆข้ๅใ
+your_starred = ๅทฒๅ ๆ่
+active_stopwatch = ๆดปๅๆ้่ฟฝ่นคๅจ
+rerun = ้ๆฐๅท่ก
+save = ๅฒๅญ
+retry = ้่ฉฆ
+add = ๆฐๅข
+locked = ๅทฒ้ๅฎ
+disabled = ๅทฒๅ็จ
+copy = ่ค่ฃฝ
+preview = ้ ่ฆฝ
+value = ๅผ
+webauthn_reload = ้ๆฐ่ผๅ
ฅ
+your_profile = ๅไบบ่ณๆ
+milestones = ้็จ็ข
+ok = ๅฅฝ็
+view = ๆชข่ฆ
+copy_success = ๅทฒ่ค่ฃฝ๏ผ
+loading = ่ผๅ
ฅไธญโฆ
+error = ้ฏ่ชค
+never = ๅพไธ
+unknown = ๆช็ฅ
+concept_user_organization = ็ต็น
+pin = ้้ธ
+unpin = ๅๆถ้้ธ
+artifacts = ่ฃฝๅ
+archived = ๅทฒๅฐๅญ
+concept_system_global = ๅ
จๅ
+concept_user_individual = ๅไบบ
+new_project = ๆฐๅขๅฐๆก
+new_project_column = ๆฐๅขๆฌไฝ
+filter.public = ๅ
ฌ้
+remove_all = ็งป้คๅ
จ้จ
+admin_panel = ็ถฒ็ซ็ฎก็
+add_all = ๆฐๅขๅ
จ้จ
+remove_label_str = ็งป้ค้
็ฎใ%sใ
+test = ๆธฌ่ฉฆ
+new_repo.title = ๆฐๅฒๅญๅบซ
+new_migrate.title = ๆฐ้ท็งป
+new_org.title = ๆฐ็ต็น
+new_repo.link = ๆฐๅฒๅญๅบซ
+new_migrate.link = ๆฐ้ท็งป
+new_org.link = ๆฐ็ต็น
+copy_generic = ่ค่ฃฝๅฐๅช่ฒผ็ฐฟ
+copy_url = ่ค่ฃฝ็ถฒๅ
+copy_hash = ่ค่ฃฝ้ๆนๅผ
+
+filter.private = ็งๆๅบซ
[aria]
+footer = ้ ๅฐพ
+footer.links = ้ฃ็ต
[heatmap]
+more = ่ผๅค
+less = ่ผๅฐ
[editor]
@@ -100,6 +151,8 @@ webauthn_error_empty = ไฝ ่ฆ่ตทๅๅขๆข้ๅใ
[error]
[startpage]
+platform = ่ทจๅนณๅฐ
+lightweight = ่ผ้็ด
[install]
install=ๅฎ่ฃ้ ้ข
@@ -125,13 +178,16 @@ confirm_password=็ขบ่ชๅฏ็ขผ
install_btn_confirm=็ซๅณๅฎ่ฃ
test_git_failed=็กๆณ่ญๅฅ 'git' ๅฝไปค๏ผ%v
save_config_failed=ๅฒๅญ่จญๅฎๅคฑๆ๏ผ%v
+user = ไฝฟ็จ่
ๅ็จฑ
+db_schema = ่ณๆ็ตๆง
+ssl_mode = SSL
[home]
password_holder=ๅฏ็ขผ
switch_dashboard_context=ๅๆๆงๅถ้ข็็จๆถ
my_repos=ๅฒๅญๅบซ็ฎก็
collaborative_repos=ๅ่ๅไฝ็ๅฒๅญๅบซ
-my_orgs=ๆ็็ต็น
+my_orgs=็ต็น
my_mirrors=ๆ็้กๅ
view_home=่จชๅ %s
@@ -139,12 +195,14 @@ view_home=่จชๅ %s
show_private=็งๆๅบซ
issues.in_your_repos=ๅฑฌๆผ่ฉฒ็จๆถๅฒๅญๅบซ็
+show_archived = ๅทฒๅฐๅญ
[explore]
repos=ๅฒๅญๅบซ
users=ไฝฟ็จ่
organizations=็ต็น
search=ๆๅฐ
+code = ็จๅผ็ขผ
[auth]
register_helper_msg=ๅทฒ็ถ่จปๅ๏ผ็ซๅณ็ป้๏ผ
@@ -165,17 +223,23 @@ oauth_signin_submit=้ฃ็ตๅธณๆถ
openid_connect_submit=้ฃๆฅ
openid_connect_title=้ฃๆฅๅฐ็พๆๅธณๆถ
openid_register_title=ๅปบ็ซๆฐๅธณๆถ
+oauth_signup_submit = ๅฎๆๅธณๆถ
+reset_password_helper = ๅพฉๅๅธณๆถ
+create_new_account = ่จปๅๅธณๆถ
+reset_password = ๅธณๆถๅพฉๅ
[mail]
-
activate_account=่ซๅ็จๆจ็ๅธณๆถ
activate_email=่ซ้ฉ่ญๆจ็้ต็ฎฑๅฐๅ
-register_notify=ๆญก่ฟไพๅฐ Forgejo
+register_notify=ๆญก่ฟไพๅฐ %s
register_success=่จปๅๆๅ
+release.note = ่ชชๆ๏ผ
+release.downloads = ไธ่ผ๏ผ
+repo.transfer.to_you = ไฝ
@@ -187,6 +251,8 @@ register_success=่จปๅๆๅ
yes=็ขบ่ชๆไฝ
no=ๅๆถๆไฝ
cancel=ๅๆถ
+confirm = ็ขบๅฎ
+modify = ๆดๆฐ
[form]
UserName=ไฝฟ็จ่
ๅ็จฑ
@@ -222,6 +288,8 @@ auth_failed=ๆๆฌ้ฉ่ญๅคฑๆ๏ผ%v
target_branch_not_exist=็ฎๆจๅๆฏไธๅญๅจ
+SSPISeparatorReplacement = ๅ้็ฌฆ
+SSPIDefaultLanguage = ้ ่จญ่ช่จ
[user]
@@ -231,6 +299,10 @@ followers_few=%d ้่จป่
following_few=%d ้่จปไธญ
follow=้ๆณจ
unfollow=ๅๆถ้ๆณจ
+code = ็จๅผ็ขผ
+projects = ๅฐๆก
+overview = ๆฆ่ฆฝ
+user_bio = ๅไบบ็ฐกไป
[settings]
@@ -238,8 +310,8 @@ profile=ๅไบบ่จๆฏ
password=ไฟฎๆนๅฏ็ขผ
avatar=้ ญๅ
ssh_gpg_keys=SSH / GPG ้้ฐ
-social=็คพไบคๅธณ่็ถๅฎ
-orgs=็ฎก็็ต็น
+social=็คพไบคๅธณๆถ
+orgs=็ต็น
repos=ๅฒๅญๅบซ็ฎก็
delete=ๅช้คๅธณๆถ
twofa=ๅ
ฉๆญฅ้ฉ้ฉ่ญ
@@ -321,10 +393,34 @@ link_account=้ฃ็ตๅธณๆถ
orgs_none=ๆจๅฐๆชๆ็บไปปไธ็ต็น็ๆๅกใ
delete_account=ๅช้ค็ถๅๅธณๆถ
-confirm_delete_account=็ขบ่ชๅช้คๅธณๆถ
+confirm_delete_account=็ขบ่ชๅช้ค
visibility.private=็งๆๅบซ
+applications = ๆ็จ็จๅผ
+uid = UID
+appearance = ๅค่ง
+security = ๅฎๅ
จๆง
+manage_themes = ้ ่จญไธป้ก
+account_link = ๅทฒ้ฃ็ต็ๅธณๆถ
+access_token_deletion_confirm_action = ๅช้ค
+permissions_list = ๆฌ้๏ผ
+ui = ไธป้ก
+privacy = ็ง้ฑ
+account = ๅธณๆถ
+visibility.public = ๅ
ฌ้
+unbind = ่งฃ้ค้ฃ็ต
+visibility.limited = ๅ้
+comment_type_group_reference = ๅ่
+comment_type_group_label = ๆจ็ฑค
+comment_type_group_milestone = ้็จ็ข
+language.title = ้ ่จญ่ช่จ
+comment_type_group_branch = ๅๆฏ
+webauthn_nickname = ๆฑ็จฑ
+save_application = ๅฒๅญ
+manage_account_links = ๅทฒ้ฃ็ต็ๅธณๆถ
+revoke_key = ๆค้ท
+comment_type_group_project = ๅฐๆก
[repo]
owner=ๆๆ่
@@ -337,7 +433,7 @@ repo_desc=ๅฒๅญๅบซๆ่ฟฐ
repo_lang=ๅฒๅญๅบซ่ช่จ
license=ๆๆฌ่จฑๅฏ
create_repo=ๅปบ็ซๅฒๅญๅบซ
-default_branch=้ป่ชๅๆฏ
+default_branch=้ ่จญๅๆฏ
mirror_prune=่ฃๆธ
watchers=้ๆณจ่
stargazers=็จฑ่ฎ่
@@ -392,12 +488,13 @@ file_view_raw=ๆฅ็ๅๅงๆไปถ
file_permalink=ๆฐธไน
้ฃ็ต
stored_lfs=ๅฒๅญๅฐๅฐ Git LFS
+stored_annex=ๅฒๅญๅฐๅฐ Git Annex
editor.preview_changes=้ ่ฆฝๆดๆน
editor.or=ๆ
editor.cancel_lower=ๅๆถ
editor.commit_changes=ๆไบคๆดๆนๅ๏ผ
-editor.commit_directly_to_this_branch=็ดๆฅๆไบคๅฐ %s ๅๆฏใ
+editor.commit_directly_to_this_branch=็ดๆฅๆไบคๅฐ %[1]s ๅๆฏใ
editor.create_new_branch=ๅปบ็ซ ๆฐ็ๅๆฏ ็บๆญคๆไบคๅ้ๅงๅไฝต่ซๆฑใ
editor.cancel=ๅๆถ
editor.no_changes_to_show=ๆฒๆๅฏไปฅ้กฏ็คบ็่ฎๆดใ
@@ -417,8 +514,8 @@ commits.signed_by=็ฐฝ็ฝฒไบบ
projects.description_placeholder=็ต็นๆ่ฟฐ
projects.title=ๆจ้ก
projects.template.desc=ๆจฃๆฟ
-projects.column.edit_title=็ต็นๅ็จฑ
-projects.column.new_title=็ต็นๅ็จฑ
+projects.column.edit_title=ๅ็จฑ
+projects.column.new_title=ๅ็จฑ
issues.new=ๅปบ็ซๅ้ก
issues.new.labels=ๆจ็ฑค
@@ -501,7 +598,7 @@ issues.subscribe=่จ้ฑ
issues.unsubscribe=ๅๆถ่จ้ฑ
issues.add_time_cancel=ๅๆถ
issues.due_date_form_edit=็ทจ่ผฏ
-issues.due_date_form_remove=็งป้คๆๅก
+issues.due_date_form_remove=็งป้ค
issues.dependency.cancel=ๅๆถ
issues.dependency.remove=็งป้คๆๅก
@@ -663,6 +760,33 @@ release.publish=็ผไฝ็ๆฌ
release.save_draft=ๅฒๅญ่็จฟ
release.deletion_success=ๅทฒๅช้คๆญค็ๆฌ็ผไฝใ
release.downloads=ไธ่ผ้ไปถ
+mirror_password_blank_placeholder = ๏ผๆช่จญๅฎ๏ผ
+settings.trust_model.default = ้ ่จญไฟกไปปๆจกๅ
+issue_labels = ๆจ็ฑค
+migrate_items_milestones = ้็จ็ข
+settings.default_merge_style_desc = ้ ่จญๅไฝตๆนๅผ
+language_other = ๅ
ถไป
+delete_preexisting_label = ๅช้ค
+desc.internal = ๅ
ง้จ
+desc.archived = ๅทฒๅฐๅญ
+issues.choose.blank = ้ ่จญ
+desc.public = ๅ
ฌ้
+desc.sha256 = SHA256
+template.webhooks = Webhook
+template.topics = ไธป้ก
+projects.column.set_default = ่จญ็บ้ ่จญ
+org_labels_desc_manage = ็ฎก็
+mirror_password_placeholder = ๏ผๆช่ฎๆด๏ผ
+readme = ่ฎๆๆชๆก
+release = ็ผไฝ
+commit = ๆไบค
+migrate_items_wiki = ็ถญๅบ
+migrate_items_labels = ๆจ็ฑค
+tag = ๆจ็ฑค
+settings.branches.switch_default_branch = ๅๆ้ ่จญๅๆฏ
+mirror_sync = ๅทฒๅๆญฅ
+default_branch_label = ้ ่จญ
+settings.branches.update_default_branch = ๆดๆฐ้ ่จญๅๆฏ
@@ -670,6 +794,8 @@ release.downloads=ไธ่ผ้ไปถ
+milestones.filter_sort.name = ็ต็นๅ็จฑ
+
[graphs]
[org]
@@ -696,7 +822,7 @@ settings.update_settings=ๆดๆฐ็ต็น่จญๅฎ
settings.update_setting_success=็ต็น่จญๅฎๅทฒๆดๆฐใ
settings.delete=ๅช้ค็ต็น
settings.delete_account=ๅช้ค็ถๅ็ต็น
-settings.confirm_delete_account=็ขบ่ชๅช้ค็ต็น
+settings.confirm_delete_account=็ขบ่ชๅช้ค
settings.delete_org_title=ๅช้ค็ต็น
settings.hooks_desc=ๆฐๅข webhooks ๅฐ่งธ็ผๅจ้ๅ็ต็นไธ ๅ
จ้จ็ๅฒๅญๅบซ ใ
@@ -720,6 +846,7 @@ teams.update_settings=ๆดๆฐๅ้่จญๅฎ
teams.add_team_member=ๆฐๅขๅ้ๆๅก
teams.delete_team_success=่ฉฒๅ้ๅทฒ่ขซๅช้คใ
teams.repositories=ๅ้ๅฒๅญๅบซ
+settings.visibility.public = ๅ
ฌ้
[admin]
dashboard=ๆงๅถ้ข็
@@ -834,9 +961,9 @@ auths.enable_auto_register=ๅ
่จฑๆๆฌ็จๆถ่ชๅ่จปๅ
auths.tips=ๅนซๅฉๆ็คบ
auths.tips.oauth2.general=OAuth2 ่ช่ญ
auths.tip.oauth2_provider=OAuth2 ๆไพ่
-auths.tip.dropbox=ๅปบ็ซๆฐ App ๅจ https://www.dropbox.com/developers/apps
-auths.tip.facebook=`ๅจ https://developers.facebook.com/apps ่จปๅไธๅๆฐ็ๆ็จ๏ผไธฆไธๆฐๅขไธๅ็ขๅ "Facebook Login"`
-auths.tip.github=ๅจ https://github.com/settings/applications/new ่จปๅไธๅๆฐ็ OAuth ๆ็จ็จๅผ
+auths.tip.dropbox=ๅปบ็ซๆฐ App ๅจ %s
+auths.tip.facebook=`ๅจ %s ่จปๅไธๅๆฐ็ๆ็จ๏ผไธฆไธๆฐๅขไธๅ็ขๅ "Facebook Login"`
+auths.tip.github=ๅจ %s ่จปๅไธๅๆฐ็ OAuth ๆ็จ็จๅผ
auths.tip.gitlab=ๅจ https://gitlab.com/profile/applications ่จปๅไธๅๆฐ็ๆ็จ็จๅผ
auths.tip.openid_connect=ไฝฟ็จ OpenID ้ฃๆฅๆข็ดข URL (/.well-known/openid-configuration) ไพๆๅฎ็ฏ้ป
auths.delete=ๅช้ค่ช่ญไพๆบ
@@ -947,8 +1074,15 @@ notices.type_1=ๅฒๅญๅบซ
notices.desc=ๆ่ฟฐ
notices.op=ๆไฝ
notices.delete_success=ๅทฒๅช้ค็ณป็ตฑๆ็คบใ
+defaulthooks.update_webhook = ๆดๆฐ้ ่จญ Webhook
+defaulthooks.add_webhook = ๆฐๅข้ ่จญ Webhook
+auths.sspi_default_language = ้ ่จญไฝฟ็จ่
่ช่จ
+users = ไฝฟ็จ่
ๅธณๆถ
+defaulthooks = ้ ่จญ Webhook
+config_settings = ็ต็น่จญๅฎ
+
[action]
create_repo=ๅปบ็ซไบๅฒๅญๅบซ %s
rename_repo=้ๆฐๅฝๅๅฒๅญๅบซ %[1]s
็บ %[3]s
@@ -1001,18 +1135,17 @@ alpine.repository.branches=ๅๆฏๅ่กจ
alpine.repository.repositories=ๅฒๅญๅบซ็ฎก็
conan.details.repository=ๅฒๅญๅบซ
owner.settings.cleanuprules.enabled=ๅทฒๅ็จ
+container.labels = ๆจ็ฑค
[secrets]
[actions]
-
-
-
runners.name=็ต็นๅ็จฑ
runners.owner_type=่ช่ญ้กๅ
runners.description=็ต็นๆ่ฟฐ
runners.task_list.run=ๅท่ก
runners.task_list.repository=ๅฒๅญๅบซ
+runners.labels = ๆจ็ฑค
@@ -1021,5 +1154,5 @@ runners.task_list.repository=ๅฒๅญๅบซ
[projects]
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
+[search]
diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini
index fd73d62c1a..33f535c2fc 100644
--- a/options/locale/locale_zh-TW.ini
+++ b/options/locale/locale_zh-TW.ini
@@ -16,7 +16,7 @@ page=้ ้ข
template=ๆจกๆฟ
language=่ช่จ
notifications=้็ฅ
-active_stopwatch=ๆญฃๅจ้ฒ่ก็ๆ้่ฟฝ่นค
+active_stopwatch=ๅๅ็ๆ้่ฟฝ่นคๅจ
create_new=ๅปบ็ซโฆ
user_profile_and_more=ๅไบบ่ณๆๅ่จญๅฎโฆ
signed_in_as=ๅทฒ็ปๅ
ฅ็บ
@@ -83,7 +83,7 @@ cancel=ๅๆถ
retry=้่ฉฆ
save=ๅฒๅญ
add=ๆฐๅข
-add_all=ๅ
จ้จๆฐๅข
+add_all=ๆฐๅขๅ
จ้จ
remove=็งป้ค
remove_all=ๅ
จ้จ็งป้ค
remove_label_str=็งป้ค้
็ฎใ%sใ
@@ -105,7 +105,7 @@ preview=้ ่ฆฝ
loading=่ผๅ
ฅไธญโฆ
error=้ฏ่ชค
-error404=ๆจๅ่ฉฆ้ ่จช็้ ้ข ไธๅญๅจ ๆ ๆจๆฒๆๆฌ้ ๆชข่ฆ่ฉฒ้ ้ขใ
+error404=ๆจๅ่ฉฆ้ ่จช็้ ้ขไธๅญๅจ ใๅทฒ่ขซ็งป้ค ๏ผๆๆจๆฒๆๆฌ้ ๆชข่ฆ่ฉฒ้ ้ขใ
never=ๅพไพๆฒๆ
unknown=ๆช็ฅ
@@ -158,11 +158,20 @@ confirm_delete_artifact = ๆจ็ขบๅฎ่ฆๅช้ค่ฃฝๅใ%sใๅ๏ผ
more_items = ้กฏ็คบๆดๅค
invalid_data = ็กๆ่ณๆ๏ผ%v
copy_generic = ่ค่ฃฝๅฐๅช่ฒผ็ฐฟ
+error413 = ๆจๅทฒ็จ็กๆจ็้กๅบฆใ
+test = ๆธฌ่ฉฆ
+new_migrate.title = ๆฐ้ท็งป
+new_org.title = ๆฐ็ต็น
+new_repo.link = ๆฐๅฒๅญๅบซ
+new_org.link = ๆฐ็ต็น
+new_repo.title = ๆฐๅฒๅญๅบซ
+new_migrate.link = ๆฐ้ท็งป
+copy_path = ่ค่ฃฝ่ทฏๅพ
[aria]
navbar=ๅฐ่ชๅ
footer=้ ๅฐพ
-footer.software=้ๆผ่ป้ซ
+footer.software=้ๆผๆญค่ป้ซ
footer.links=้ฃ็ต
[heatmap]
@@ -189,6 +198,16 @@ buttons.ref.tooltip=ๅผ็จๅ้กๆๅไฝต่ซๆฑ
buttons.enable_monospace_font=ๅ็จ็ญๅฏฌๅญๅ
buttons.disable_monospace_font=ๅ็จ็ญๅฏฌๅญๅ
buttons.switch_to_legacy.tooltip = ไฝฟ็จ่็็ทจ่ผฏๅจ
+table_modal.placeholder.header = ่กจ้ ญ
+table_modal.placeholder.content = ๅ
งๅฎน
+table_modal.label.rows = ๅ
+table_modal.label.columns = ๆฌ
+buttons.new_table.tooltip = ๆฐๅข่กจๆ ผ
+table_modal.header = ๆฐๅข่กจๆ ผ
+buttons.indent.tooltip = ไฝฟ้
็ฎ็ธฎๆไธๅฑค
+buttons.unindent.tooltip = ไฝฟ้
็ฎๅๆถ็ธฎๆไธๅฑค
+
+link_modal.header = ๆฐๅข้ฃ็ต
[filter]
string.asc=A - Z
@@ -200,19 +219,19 @@ missing_csrf=้ฏ่ชค็่ซๆฑ๏ผๆชๆไพ CSRF ็ฌฆ่จ
invalid_csrf=้ฏ่ชค็่ซๆฑ๏ผ็กๆ็ CSRF ็ฌฆ่จ
not_found=ๆพไธๅฐ็ฎๆจใ
network_error=็ถฒ่ทฏ้ฏ่ชค
-report_message = ๅฆๆๆจ็ธไฟก้ๆฏไธๅ Forgejo ็้ฏ่ชค๏ผ่ซๅจ Codeberg ไธๆๅฐ็ธ้ๅ้ก๏ผๆๅจๅฟ
่ฆๆๆๅบไธๅๅ้กใ
+report_message = ๅฆๆๆจ็ธไฟก้ๆฏไธๅ Forgejo ็้ฏ่ชค๏ผ่ซๅจ Codeberg ไธๆๅฐ็ธ้ๅ้ก๏ผๆๅจๅฟ
่ฆๆๆๅบไธๅๆฐๅ้กใ
server_internal = ไผบๆๅจๅ
ง้จ้ฏ่ชค
[startpage]
app_desc=ไธๅฅๆฅตๆๆถ่จญ็ Git ๆๅ
install=ๅฎ่ฃๅฎนๆ
platform=่ทจๅนณๅฐ
-platform_desc=Forgejo ๅฏไปฅๅจๆๆ่ฝ็ทจ่ญฏ Go ่ช่จ ็ๅนณๅฐไธๅท่ก๏ผWindows๏ผmacOS๏ผLinux๏ผARM ็ญใๆไธๅๆจๅๆญก็ๅง๏ผ
lightweight=่ผ้็ด
lightweight_desc=ไธ็ไพฟๅฎ็ Raspberry Pi ๅฐฑๅฏไปฅๆปฟ่ถณ Forgejo ็ๆไฝ้ๆฑใ็ฏ็ๆจ็ๆฉๅจ่ณๆบ๏ผ
license=้ๆพๅๅง็ขผ
-license_desc=ๅๅพ Forgejo ๏ผๆ็บไธๅ่ฒข็ป่
ๅๆๅไธ่ตท่ฎ Forgejo ๆดๅฅฝ๏ผๅฟซ้ปๅ ๅ
ฅๆๅๅง๏ผ
-install_desc = ่ผ้ฌไฝฟ็จๆจๅนณๅฐ็ๅฏๅท่กๆช ๏ผไฝฟ็จ Docker ้จ็ฝฒ ๏ผๆๆๆฏ่ป้ซๅ
ใ
+license_desc=ๅๅพ Forgejo ๏ผๆ็บไธๅ่ฒข็ป่
ๅๆๅไธ่ตท่ฎ Forgejo ๆดๅฅฝ๏ผๅฟซ้ปๅ ๅ
ฅๆๅๅง๏ผ
+install_desc = ่ผ้ฌไฝฟ็จๆจๅนณๅฐ็ๅฏๅท่กๆช ๏ผไฝฟ็จ Docker ้จ็ฝฒ ๏ผๆๆๆฏ่ป้ซๅ
ใ
+platform_desc = Forgejo ๅทฒ็ขบ่ชๅฏไปฅๅจ Linux ๅ FreeBSD ็ญ่ช็ฑไฝๆฅญ็ณป็ตฑๅไธๅ็ไธญๅคฎ่็ๅจๆถๆงไธ้ไฝใ้ธๆไฝ ๆๆ็๏ผ
[install]
install=ๅฎ่ฃ้ ้ข
@@ -239,13 +258,13 @@ err_empty_db_path=SQLite3 ่ณๆๅบซ่ทฏๅพไธๅฏไปฅ็บ็ฉบใ
no_admin_and_disable_registration=ๆจไธ่ฝๅค ๅจๆชๅปบ็ซ็ฎก็ๅกๅธณ่็ๆ
ๆณไธ็ฆๆญข่ชๅฉ่จปๅใ
err_empty_admin_password=็ฎก็ๅกๅฏ็ขผไธ่ฝ็บ็ฉบใ
err_empty_admin_email=็ฎก็ๅกไฟก็ฎฑไธ่ฝ็บ็ฉบใ
-err_admin_name_is_reserved=็กๆ็็ฎก็ๅกๅธณ่ๅ็จฑ๏ผๅธณ่ๅ็จฑๅทฒ่ขซไฟ็
+err_admin_name_is_reserved=็กๆ็็ฎก็ๅกไฝฟ็จ่
ๅ็จฑ๏ผไฝฟ็จ่
ๅ็จฑๅทฒไฟ็
err_admin_name_pattern_not_allowed=็กๆ็็ฎก็ๅกๅธณ่ๅ็จฑ๏ผ่ฉฒๅ็จฑ็ฌฆๅ่ขซไฟ็ๅผๆจฃ
-err_admin_name_is_invalid=็กๆ็็ฎก็ๅกๅธณ่ๅ็จฑ
+err_admin_name_is_invalid=็กๆ็็ฎก็ๅกไฝฟ็จ่
ๅ็จฑ
general_title=ไธ่ฌ่จญๅฎ
app_name=็ซ้ปๆจ้ก
-app_name_helper=ๆจๅฏไปฅๅจๆญค่ผธๅ
ฅๆจ็ๅ
ฌๅธๅ็จฑใ
+app_name_helper=ๅจๆญค่ผธๅ
ฅไฝ ็็ซ้ปๅ็จฑใๅฎๅฐ้กฏ็คบๅจๆฏๅ้ ้ขไธใ
repo_path=ๅฒๅญๅบซๆ น็ฎ้
repo_path_helper=ๆๆ้ ็ซฏ Git ๅฒๅญๅบซๆๅฒๅญๅฐๆญค็ฎ้ใ
lfs_path=Git LFS ๆ น็ฎ้
@@ -274,23 +293,23 @@ register_confirm=่ฆๆฑ่จปๅๆ็ขบ่ช้ปๅญ้ตไปถ
mail_notify=ๅ็จ้ตไปถ้็ฅ
server_service_title=ไผบๆๅจๅ็ฌฌไธๆนๆๅ่จญๅฎ
offline_mode=ๅ็จๆฌๅฐๆจกๅผ
-offline_mode.description=ๅ็จๅ
ถไปๆๅไธฆๅจๆฌๅฐๆไพๆๆ่ณๆบใ
+offline_mode.description=ๅ็จ็ฌฌไธๆนๅ
งๅฎนๅณ้็ถฒ่ทฏไธฆๅจๆฌๅฐๆไพๆๆ่ณๆบใ
disable_gravatar=ๅ็จ Gravatar
-disable_gravatar.description=ๅ็จ Gravatar ๅ็ฌฌไธๆนๅคง้ ญ่ฒผๆๅใ่ฅไฝฟ็จ่
ๅจๆชๆฌๅฐไธๅณๅคง้ ญ่ฒผ๏ผๅฐไฝฟ็จ้ ่จญ็ๅคง้ ญ่ฒผใ
+disable_gravatar.description=ๅ็จ Gravatar ๆๅ
ถไป็ฌฌไธๆนๅคง้ ญ่ฒผไพๆบใ้ค้ไฝฟ็จ่
ๅฐ่ชๅทฑ็ๅคง้ ญ่ฒผไธๅณ่ณ็ซ้ป๏ผๅฆๅๅฐไฝฟ็จ้ ่จญ็ๅคง้ ญ่ฒผไฝ็บไฝฟ็จ่
็ๅคง้ ญ่ฒผใ
federated_avatar_lookup=ๅ็จ่ฏ้ฆๅผๅคง้ ญ่ฒผ
-federated_avatar_lookup.description=ๅ็จ Libravatar ๆไพ็่ฏ้ฆๅผๅคง้ ญ่ฒผๆฅ่ฉขๆๅใ
+federated_avatar_lookup.description=ไฝฟ็จ Libravatar ๅฐๆพๅคง้ ญ่ฒผใ
disable_registration=ๅ็จ่ชๅฉ่จปๅ
-disable_registration.description=็ฆๆญขไฝฟ็จ่
่ชๅฉ่จปๅ๏ผๅชๆ็ฎก็ๅกๅฏไปฅๆฐๅขๅธณ่ใ
-allow_only_external_registration.description=ๅชๅ
่จฑๅพๅค้จๆๅ่จปๅ
+disable_registration.description=ๅชๆ็ซ้ป็ฎก็ๅกๆ่ฝๅปบ็ซๆฐ็ไฝฟ็จ่
ๅธณ่ใๅผท็ๅปบ่ญฐไฟๆ่จปๅ่ๆผๅ็จ็ๆ
๏ผ้ค้ไฝ ๆ็ฎ้ไฝๅ
ฌๅ
ฑ็ซ้ปไธฆๆบๅ่็ๅคง้ๅๅพๅธณ่ใ
+allow_only_external_registration.description=ไฝฟ็จ่
ๅช่ฝไฝฟ็จ้
็ฝฎ็ๅค้จๆๅไพๅปบ็ซๆฐๅธณ่ใ
openid_signin=ๅ็จ OpenID ็ปๅ
ฅ
-openid_signin.description=ๅ็จ OpenID ็ปๅ
ฅใ
+openid_signin.description=ๅ
่จฑไฝฟ็จ่
้้ OpenID ็ปๅ
ฅใ
openid_signup=ๅ็จ OpenID ่ชๅฉ่จปๅ
-openid_signup.description=ๅ็จไฝฟ็จ OpenID ็่ชๅฉ่จปๅใ
+openid_signup.description=ๅฆๆๅ็จไบ่ชๅฉ่จปๅ๏ผๅๅ
่จฑไฝฟ็จ่
้้ OpenID ๅปบ็ซๅธณ่ใ
enable_captcha=ๅ็จ่จปๅ้ฉ่ญ็ขผ
-enable_captcha.description=่ฆๆฑๅจ็จๆถ่จปๅๆ่ผธๅ
ฅ้ฉ่ญ็ขผใ
+enable_captcha.description=่ฆๆฑไฝฟ็จ่
้้ CAPTCHA ๆ่ฝๅปบ็ซๅธณ่ใ
require_sign_in_view=้่ฆ็ปๅ
ฅๆ่ฝ็่ฆฝ็ซ้ปๅ
งๅฎน
-require_sign_in_view.description=ๅ
ๆๅทฒ็ปๅ
ฅ็ไฝฟ็จ่
่ฝๅญๅ้ ้ขใ่จชๅฎขๅชๆ็ๅฐ็ปๅ
ฅๅ่จปๅ้ ้ขใ
-admin_setting.description=ๆจไธ้่ฆๅปบ็ซ็ฎก็ๅกๅธณ่ใ ็ฌฌไธๅ่จปๅ็ไฝฟ็จ่
ๅฐ่ชๅๆ็บ็ฎก็ๅกใ
+require_sign_in_view.description=ๅฐๅ
งๅฎนๅญๅ้ๅถ็บๅทฒ็ปๅ
ฅ็ไฝฟ็จ่
ใ่จชๅฎขๅช่ฝๅญๅ้ฉ่ญ้ ้ขใ
+admin_setting.description=ๅปบ็ซ็ฎก็ๅกๅธณ่ๆฏ้ธๆๆง็ใ็ฌฌไธๅ่จปๅ็ไฝฟ็จ่
ๅฐ่ชๅๆ็บ็ฎก็ๅกใ
admin_title=็ฎก็ๅกๅธณ่่จญๅฎ
admin_name=็ฎก็ๅกๅธณ่ๅ็จฑ
admin_password=ๅฏ็ขผ
@@ -310,11 +329,11 @@ save_config_failed=ๅฒๅญ่จญๅฎๅคฑๆ๏ผ%v
invalid_admin_setting=็ฎก็ๅกๅธณ่่จญๅฎ็กๆ๏ผ%v
invalid_log_root_path=ๆฅ่ชๆ น็ฎ้่จญๅฎ็กๆ๏ผ%v
default_keep_email_private=้ ่จญ้ฑ่้ปๅญไฟก็ฎฑ
-default_keep_email_private.description=้ ่จญ้ฑ่ๆฐไฝฟ็จ่
ๅธณ่็้ปๅญไฟก็ฎฑใ
+default_keep_email_private.description=้ ่จญ็บๆฐไฝฟ็จ่
ๅ็จ้ปๅญ้ตไปถๅฐๅ้ฑ่๏ผไปฅไฝฟ้ไบ่ณ่จไธๆๅจ่จปๅๅพ็ซๅณๆดฉ้ฒใ
default_allow_create_organization=้ ่จญๅ
่จฑๅปบ็ซ็ต็น
-default_allow_create_organization.description=้ ่จญๅ
่จฑๆฐไฝฟ็จ่
ๅธณ่ๅปบ็ซ็ต็นใ
+default_allow_create_organization.description=้ ่จญๅ
่จฑๆฐไฝฟ็จ่
ๅปบ็ซ็ต็นใ็ถๆญค้ธ้
ๅ็จๆ๏ผ็ฎก็ๅกๅฟ
้ ๆไบๆฐไฝฟ็จ่
ๅปบ็ซ็ต็น็ๆฌ้ใ
default_enable_timetracking=้ ่จญๅ็จๆ้่ฟฝ่นค
-default_enable_timetracking.description=้ ่จญๅ็จๆฐๅญๅฒๅบซ็ๆ้่ฟฝ่นคใ
+default_enable_timetracking.description=้ ่จญๅ
่จฑๆฐๅฒๅญๅบซไฝฟ็จๆ้่ฟฝ่นคๅ่ฝใ
no_reply_address=้ฑ่้ปๅญไฟก็ฎฑๅๅ
no_reply_address_helper=้ฑ่้ปๅญไฟก็ฎฑ็ๅๅใไพๅฆ๏ผๅฆๆ้ฑ่็้ปๅญไฟก็ฎฑๅๅ่จญๅฎ็บใnoreply.example.orgใ๏ผๅธณ่ใjoeใๅฐไปฅใjoe@noreply.example.orgใ็่บซๅ็ปๅ
ฅๅฐ Git ไธญใ
password_algorithm=ๅฏ็ขผ้ๆนๆผ็ฎๆณ
@@ -328,11 +347,14 @@ smtp_from_invalid = ้ตไปถๅฏไปถไบบ็ๅฐๅ็กๆ
config_location_hint = ้ไบ่จญๅฎๅฐ่ขซๅฒๅญๅจ๏ผ
allow_dots_in_usernames = ๅ
่จฑไฝฟ็จ่
ๅจไฝฟ็จ่
ๅ็จฑไธญไฝฟ็จ่ฑๆๅฅ้ปใไธๅฝฑ้ฟๆขๆๅธณ่ใ
enable_update_checker_helper_forgejo = ้้ๆชขๆฅ release.forgejo.org ็ DNS TXT ่จ้ไพๅฎๆๆชขๆฅๆฐ็ Forgejo ็ๆฌใ
+app_slogan = ็ซ้ปๆจ่ช
+app_slogan_helper = ๅจ้่ฃก่ผธๅ
ฅๆจ็ซ้ป็ๆจ่ชใ็็ฉบไพๅ็จใ
+allow_only_external_registration = ๅ
ๅ
่จฑ้้ๅค้จๆๅ่จปๅ
[home]
uname_holder=ๅธณ่ๅ็จฑๆ้ปๅญไฟก็ฎฑ
password_holder=ๅฏ็ขผ
-switch_dashboard_context=ๅๆๅ้ถ็ๅธณ่
+switch_dashboard_context=ๅๆๅ้ถๆฟๅ
งๅฎน
my_repos=ๅฒๅญๅบซ
show_more_repos=้กฏ็คบๆดๅคๅฒๅญๅบซโฆ
collaborative_repos=ๅ่ๅไฝ็ๅฒๅญๅบซ
@@ -393,13 +415,13 @@ remember_me=่จไฝ้ๅฐ่ฃ็ฝฎ
forgot_password_title=ๅฟ่จๅฏ็ขผ
forgot_password=ๅฟ่จๅฏ็ขผ๏ผ
sign_up_now=้ๆฒๆๅธณ่๏ผ้ฆฌไธ่จปๅใ
-confirmation_mail_sent_prompt=ๅทฒๅฏ้ๆฐ็็ขบ่ชไฟก่ณ %s ใ่ซๅจ %s ๅ
งๆชขๆฅๆจ็ๆถไปถๅฃไธฆๅฎๆ่จปๅๆ็บใๅฆๆ่ฉฒ email ไธๆญฃ็ขบ๏ผๆจๅฏไปฅๅจ็ปๅ
ฅๅพๅ่ซๆฑไธๅฐๆฐ็็ขบ่ชไฟกๅฐๅฆไธๅๅฐๅใ
+confirmation_mail_sent_prompt=ๆฐ็็ขบ่ช้ปๅญ้ตไปถๅทฒๅณ้่ณ %s ใ่ฆๅฎๆ่จปๅ้็จ๏ผ่ซๆชขๆฅไฝ ็ๆถไปถๅฃไธฆๅจๆฅไธไพ็ %s ๅ
งๆ็
งๆไพ็้ฃ็ตๅฎๆ่จปๅๆ็บใๅฆๆ้ปๅญ้ตไปถไธๆญฃ็ขบ๏ผไฝ ๅฏไปฅๅ็ปๅ
ฅไธฆ่ซๆฑๅฆไธๅฐๆฐ็็ขบ่ช้ปๅญ้ตไปถๅณ้่ณๅ
ถไป้ปๅญไฟก็ฎฑใ
must_change_password=ๆดๆฐๆจ็ๅฏ็ขผ
allow_password_change=่ฆๆฑไฝฟ็จ่
ๆดๆนๅฏ็ขผ๏ผๅปบ่ญฐ๏ผ
-reset_password_mail_sent_prompt=ๅทฒ็ผ้็ขบ่ชไฟก่ณ %s ใ่ซๅจ %s ๅ
งๆชขๆฅๆจ็ๆถไปถๅฃไธฆๅฎๆๅธณ่ๅพฉๅๆ็บใ
+reset_password_mail_sent_prompt=็ขบ่ช้ปๅญ้ตไปถๅทฒๅณ้่ณ %s ใ่ฆๅฎๆๅธณ่ๅพฉๅๆญฅ้ฉ๏ผ่ซๆชขๆฅไฝ ็ๆถไปถๅฃไธฆๅจๆฅไธไพ็ %s ๅ
งๆ็
งๆไพ็้ฃ็ต้ฒ่กๆไฝใ
active_your_account=ๅ็จๆจ็ๅธณ่
account_activated=ๅธณ่ๅทฒๅ็จ
-prohibit_login=ๅทฒ่ขซ็ฆๆญข็ปๅ
ฅ
+prohibit_login=ๅธณ่ๅทฒๅๆฌ
resent_limit_prompt=ๆจๅๅๅทฒ็ถ่ซๆฑ็ผ้้ฉ่ญ้ปๅญ้ตไปถ๏ผ่ซ็ญๅพ
3 ๅ้ๅพๅ่ฉฆไธๆฌกใ
has_unconfirmed_mail=%s ๆจๅฅฝ๏ผๆจๆไธๅๅฐๆช่ขซ็ขบ่ช็ไฟก็ฎฑๅฐๅ๏ผ%s ๏ผใๅฆๆๆจ้ๆฒๆถๅฐ็ขบ่ชไฟกๆ้่ฆไธๅฐๆฐ็๏ผ่ซ้ปๆไธๆน็ๆ้ใ
resend_mail=้ปๆๆญค่ไพ้ๆฐ็ผ้็ขบ่ช้ตไปถ
@@ -437,9 +459,9 @@ disable_forgot_password_mail=็ฑๆผๆช่จญๅฎ้ปๅญ้ตไปถๅ่ฝ๏ผๅธณ่ๅพฉๅๅ
disable_forgot_password_mail_admin=ๅธณ่ๅพฉๅๅ่ฝ้่ฆ่จญๅฎ้ปๅญ้ตไปถๅ่ฝๆ่ฝไฝฟ็จใ่ซ่จญๅฎ้ปๅญ้ตไปถๅ่ฝไปฅๅ็จๅธณ่ๅพฉๅใ
email_domain_blacklisted=ๆจ็กๆณไฝฟ็จๆจ็้ปๅญไฟก็ฎฑ่จปๅๅธณ่ใ
authorize_application=ๆๆฌๆ็จ็จๅผ
-authorize_redirect_notice=ๅฆๆๆจๆๆฌๆญคๆ็จ็จๅผ๏ผๆจๅฐๆ่ขซ้ๆฐๅฐๅ่ณ %sใ
+authorize_redirect_notice=ๅฆๆๆจๆๆฌๆญคๆ็จ็จๅผ๏ผๆจๅฐๆ่ขซ่ฝๅ่ณ %sใ
authorize_application_created_by=ๆญคๆ็จ็จๅผๆฏ็ฑ %s ๅปบ็ซ็ใ
-authorize_application_description=ๅฆๆๆจๅ
่จฑ๏ผๅฎๅฐ่ฝๅค ่ฎๅๅไฟฎๆนๆจ็ๆๆๅธณ่่ณ่จ๏ผๅ
ๆฌ็งๆๅฒๅญๅบซๅ็ต็นใ
+authorize_application_description=ๅฆๆไฝ ๆไบๅญๅๆฌ้๏ผๅฎๅฐ่ฝๅค ๅญๅๅๅฏซๅ
ฅไฝ ็ๆๆๅธณ่่ณ่จ๏ผๅ
ๆฌ็งไบบๅฒๅญๅบซๅ็ต็นใ
authorize_title=ๆๆฌใ%sใๅญๅๆจ็ๅธณ่๏ผ
authorization_failed=ๆๆฌๅคฑๆ
sspi_auth_failed=SSPI ่ช่ญๅคฑๆ
@@ -450,14 +472,21 @@ change_unconfirmed_email = ๅฆๆๆจๅจ่จปๅๅธณ่ๆๅฏซ้ฏไบไฟก็ฎฑๅฐๅ๏ผ
change_unconfirmed_email_error = ็กๆณๆดๆนไฟก็ฎฑๅฐๅ๏ผ%v
tab_signup = ่จปๅ
last_admin = ๆจ็กๆณๅช้คๆๅพไธๅ็ฎก็ๅกใๅฟ
้ ่ณๅฐๆไธๅ็ฎก็ๅกใ
-prohibit_login_desc = ๆจ็ๅธณ่่ขซ็ฆๆญข็ปๅ
ฅ๏ผ่ซ้ฃ็ตก็ถฒ็ซ็ฎก็ๅกใ
+prohibit_login_desc = ไฝ ็ๅธณ่ๅทฒ่ขซๆซๅ่็ซ้ปไบๅใ่ฏ็ตก็ซ้ป็ฎก็ๅกไปฅ้ๆฐ็ฒๅพๅญๅๆฌ้ใ
sign_up_successful = ๅทฒๆๅๅปบ็ซๅธณ่ใๆญก่ฟ๏ผ
invalid_code_forgot_password = ๆจ็็ขบ่ชไปฃ็ขผ็กๆๆๅทฒ้ๆใ้ปๆ้่ฃก ไพ้ๅงไธๅๆฐ็้ฃ็ท้ๆฎตใ
reset_password_wrong_user = ๆจไปฅ %s ็ปๅ
ฅ๏ผไฝๆฏๅธณ่ๅพฉๅ้ฃ็ตๆฏ็ตฆ %s ็
-password_pwned = ่ฉฒๅฏ็ขผๅบ็พๅจๅ
ๅ่ณๆๆดฉ้ฒ็่ขซ็ๅฏ็ขผๆธ
ๅฎ ไธญใ่ซ็จไธๅไธๅ็ๅฏ็ขผๅ่ฉฆไธๆฌก๏ผไธฆ่ๆ
ฎๅจๅ
ถไปๅฐๆนไนๆดๆๆญคๅฏ็ขผใ
+password_pwned = ่ฉฒๅฏ็ขผๅบ็พๅจๅ
ๅ่ณๆๆดฉ้ฒ็่ขซ็ๅฏ็ขผๆธ
ๅฎ ไธญใ่ซ็จไธๅไธๅ็ๅฏ็ขผๅ่ฉฆไธๆฌก๏ผไธฆ่ๆ
ฎๅจๅ
ถไปๅฐๆนไนๆดๆๆญคๅฏ็ขผใ
authorization_failed_desc = ๅ ็บๅตๆธฌๅฐ็กๆ่ซๆฑ๏ผๆๆฌๅคฑๆใ่ซ้ฃ็ตกๆจๅ่ฉฆๆๆฌ็ๆ็จ็็ถญ่ญท่
ใ
openid_signin_desc = ่ผธๅ
ฅๆจ็ OpenID URIใไพๅฆ๏ผalice.openid.example.org ๆๆฏ https://openid.example.org/aliceใ
remember_me.compromised = ๆญค็ปๅ
ฅ็ฌฆ่จๅทฒ็ถ็กๆ๏ผ้ๅฏ่ฝๆฏๅ ็บๆจ็ๅธณ่่ขซ็็จไบใ่ซๆชขๆฅๆจ็ๅธณ่ๆฏๅฆๆ็ฐๅธธๆดปๅใ
+hint_login = ๅทฒ็ถๆๅธณ่ไบๅ๏ผ้ฆฌไธ็ปๅ
ฅ๏ผ
+hint_register = ้่ฆไธๅๅธณ่ๅ๏ผ้ฆฌไธ่จปๅใ
+sign_up_button = ้ฆฌไธ่จปๅใ
+sign_in_openid = ไฝฟ็จ OpenID ็นผ็บ
+back_to_sign_in = ่ฟๅ็ปๅ
ฅ้ ้ข
+use_onetime_code = ไฝฟ็จไธๆฌกๆงไปฃ็ขผ
+unauthorized_credentials = ๆ่ญไธๆญฃ็ขบๆๅทฒ้ๆใ้่ฉฆไฝ ็ๅฝไปคๆๆฅ็ %s ไปฅ็ฒๅๆดๅค่ณ่จ
[mail]
view_it_on=ๅจ %s ไธๆฅ็
@@ -473,7 +502,7 @@ activate_account.text_2=่ซๅจ%s ๅ
ง้ปๆไธๅ้ฃ็ตไปฅๅ็จๆจ็ๅธณ
activate_email=่ซ้ฉ่ญๆจ็้ปๅญไฟก็ฎฑ
activate_email.text=่ซๅจ%s ๅ
ง้ปๆไธๅ้ฃ็ตไปฅ้ฉ่ญๆจ็้ปๅญไฟก็ฎฑ๏ผ
-register_notify=ๆญก่ฟไพๅฐ Forgejo
+register_notify=ๆญก่ฟไพๅฐ %s
register_notify.title=%[1]s๏ผๆญก่ฟไพๅฐ %[2]s
register_notify.text_1=้ๆฏๆจๅจ %s ็่จปๅ็ขบ่ชไฟก๏ผ
register_notify.text_2=ๆจ็พๅจๅฏไปฅไฝฟ็จๆจ็ไฝฟ็จ่
ๅ็จฑ็ปๅ
ฅ๏ผ%s
@@ -527,6 +556,21 @@ activate_email.title = %s๏ผ่ซ้ฉ่ญไฝ ็ไฟก็ฎฑๅฐๅ
admin.new_user.subject = ๆฐไฝฟ็จ่
%s ๅๅๅฎๆ่จปๅ
admin.new_user.user_info = ไฝฟ็จ่
่ณ่จ
admin.new_user.text = ่ซ้ปๆ้่ฃก ไปฅๅจ็ฎก็ๅกๆงๅถๅฐ็ฎก็ๆญคไฝฟ็จ่
ใ
+password_change.subject = ๅทฒๆดๆนๆจ็ๅฏ็ขผ
+password_change.text_1 = ๆจๅธณ่็ๅฏ่ๅ่ขซๆดๆนไบใ
+totp_disabled.subject = ๅทฒๅ็จ TOTP
+primary_mail_change.text_1 = ๆจๅธณ่็ไธป่ฆไฟก็ฎฑๅ่ขซๆดๆน็บ %[1]sใ้่กจ็คบ้ๅไฟก็ฎฑๅฐๅๅฐไธๅๆถๅฐ้ๆผๆจๅธณ่็้ปๅญไฟก็ฎฑ้็ฅใ
+primary_mail_change.subject = ๅทฒๆดๆนๆจ็ไธป่ฆไฟก็ฎฑ
+removed_security_key.subject = ๅทฒ็งป้คไธๆๅฎๅ
จ้้ฐ
+removed_security_key.text_1 = ๅพๆจ็ๅธณ่็งป้คไบๅฎๅ
จ้้ฐใ%[1]sใใ
+account_security_caution.text_1 = ๅฆๆ้ๆฏๆจ๏ผ้ฃๆจๅฏไปฅๅฎๅ
จ็ๅฟฝ็ฅ้ๅ้ปๅญ้ตไปถใ
+account_security_caution.text_2 = ๅฆๆ้ไธๆฏๆจ๏ผๆจ็ๅธณ่ๅทฒ่ขซ็็จใ่ซ้ฃ็ตก็ถฒ็ซ็ฎก็ๅกใ
+totp_disabled.text_1 = ไฝ ๅธณ่ไธ็ๅบๆผๆ้็ไธๆฌกๆงๅฏ็ขผ๏ผTOTP๏ผๅๅๅทฒๅ็จใ
+totp_enrolled.text_1.no_webauthn = ไฝ ๅๅ็บไฝ ็ๅธณ่ๅ็จไบ TOTPใ้ๆๅณ่ๅฐไพๆฏๆฌก็ปๅ
ฅไฝ ็ๅธณ่ๆ๏ผไฝ ้ฝๅฟ
้ ไฝฟ็จ TOTP ไฝ็บ 2FA ๆนๆณใ
+totp_enrolled.text_1.has_webauthn = ไฝ ๅๅ็บไฝ ็ๅธณ่ๅ็จไบ TOTPใ้ๆๅณ่ๅฐไพๆฏๆฌก็ปๅ
ฅไฝ ็ๅธณ่ๆ๏ผไฝ ๅฏไปฅไฝฟ็จ TOTP ไฝ็บ 2FA ๆนๆณๆไฝฟ็จไปปไฝๅฎๅ
จ้้ฐใ
+totp_enrolled.subject = ไฝ ๅทฒๅๅ TOTP ไฝ็บ 2FA ๆนๆณ
+removed_security_key.no_2fa = ๆฒๆๅ้
็ฝฎๅ
ถไป 2FA ๆนๆณ๏ผ้่กจ็คบไธๅ้่ฆไฝฟ็จ 2FA ็ปๅ
ฅไฝ ็ๅธณ่ใ
+totp_disabled.no_2fa = ๆฒๆๅ้
็ฝฎๅ
ถไป 2FA ๆนๆณ๏ผ้่กจ็คบไธๅ้่ฆไฝฟ็จ 2FA ็ปๅ
ฅไฝ ็ๅธณ่ใ
[modal]
yes=ๆฏ
@@ -617,10 +661,10 @@ must_use_public_key=ๆจๆไพ็้้ฐๆฏ็งๆ้้ฐ๏ผ่ซๅฟไธๅณๆจ็็งๆ
unable_verify_ssh_key=็กๆณ้ฉ่ญ SSH ้้ฐ๏ผ่ซๅๆฌกๆชขๆฅๆฏๅฆๆ้ฏ่ชคใ
auth_failed=ๆๆฌ่ช่ญๅคฑๆ๏ผ%v
-still_own_repo=ๆจ็ๅธณ่ๆๆ่ณๅฐไธๅๅฒๅญๅบซ๏ผ่ซๅ
ๅช้คๆ่ฝ็งปๅฎๅใ
-still_has_org=ๆจ็ๅธณ่ๆฏ่ณๅฐไธๅ็ต็น็ๆๅก๏ผ่ซๅ
้ข้ๅฎๅใ
+still_own_repo=ๆจ็ๅธณ่ๆๆไธๅๆๅคๅๅฒๅญๅบซ๏ผ่ซๅ
ๅช้คๆ่ฝ็งปๅฎๅใ
+still_has_org=ๆจ็ๅธณ่ๆฏไธๅๆๅคๅ็ต็น็ๆๅก๏ผ่ซๅ
้ข้ๅฎๅใ
still_own_packages=ๆจ็ๅธณ่ๆๆ่ณๅฐไธๅ่ป้ซๅ
๏ผ่ซๅ
ๅช้คๅฎๅใ
-org_still_own_repo=ๆญค็ต็นไป็ถๆๆไธๅไปฅไธ็ๅฒๅญๅบซ๏ผ่ซๅ
ๅช้คๆ่ฝ็งปๅฎๅใ
+org_still_own_repo=ๆญค็ต็นไป็ถๆๆไธๅๆๅคๅ็ๅฒๅญๅบซ๏ผ่ซๅ
ๅช้คๆ่ฝ็งปๅฎๅใ
org_still_own_packages=ๆญค็ต็นไป็ถๆๆ่ณๅฐไธๅ่ป้ซๅ
๏ผ่ซๅ
ๅช้คๅฎๅใ
target_branch_not_exist=็ฎๆจๅๆฏไธๅญๅจใ
@@ -638,19 +682,21 @@ username_has_not_been_changed = ๅธณ่ๅ็จฑๆช่ขซๆดๆน
admin_cannot_delete_self = ็ถๆจๆฏ็ฎก็ๅกๆ๏ผๆจไธ่ฝๅช้ค่ชๅทฑใ่ซๅ
็งป้คๆจ็็ฎก็ๅกๆฌ้ใ
username_error_no_dots = ` ๅช่ฝๅ
ๅซ่ฑๆธๅญ็ฌฆ๏ผ"0-9","a-z","A-Z"๏ผ๏ผ็ ดๆ่๏ผ"-"๏ผๅๅบ็ท๏ผ"_"๏ผใๅช่ฝไปฅ่ฑๆธๅญๅ
้้ ญๆ็ตๅฐพ๏ผ้ฃ็บ็้่ฑๆธๅญๅ
ไนไธ่ขซๅ
่จฑใ`
required_prefix = ่ผธๅ
ฅๆๅญๅฟ
้ ไปฅใ%sใ้้ ญ
+username_claiming_cooldown =ไฝฟ็จ่
ๅ็จฑ็กๆณ่ขซ่ช้ ๏ผๅ ็บๅ
ถๅทๅปๆๅฐๆช็ตๆใๅฏไปฅๅจ %[1]s ๅพ่ขซ่ช้ ใ
+email_domain_is_not_allowed = ไฝฟ็จ่
้ปๅญ้ตไปถๅฐๅ %s ็็ถฒๅ่ EMAIL_DOMAIN_ALLOWLIST ๆ EMAIL_DOMAIN_BLOCKLIST ่ก็ชใ็ขบไฟไฝ ๅทฒๆญฃ็ขบ่จญๅฎ้ปๅญ้ตไปถๅฐๅใ
[user]
change_avatar=ๆดๆนๅคง้ ญ่ฒผโฆ
repositories=ๅฒๅญๅบซ
activity=ๅ
ฌ้ๅๆ
-followers_few=%d ่ฟฝ่นค่
+followers_few=%d ไฝ่ฟฝ่นค่
starred=ๅทฒๅ ๆ่็ๅฒๅญๅบซ
watched=้ๆณจ็ๅฒๅญๅบซ
code=็จๅผ็ขผ
projects=ๅฐๆก
overview=ๆฆ่ฆฝ
-following_few=%d ่ฟฝ่นคไธญ
+following_few=่ฟฝ่นค %d ๅไบบ
follow=่ฟฝ่นค
unfollow=ๅๆถ่ฟฝ่นค
user_bio=ๅไบบ็ฐกไป
@@ -665,15 +711,24 @@ joined_on = ๆผ %s ่จปๅ
show_on_map = ๅจๅฐๅไธ้กฏ็คบ้ๅๅฐ้ป
settings = ไฝฟ็จ่
่จญๅฎ
block_user = ๅฐ้ไฝฟ็จ่
-block_user.detail_1 = ่ฉฒไฝฟ็จ่
ๅทฒๅๆญข่ฟฝ่ธชๆจใ
-block_user.detail_2 = ้ๅไฝฟ็จ่
็กๆณๅฐๆจ็ๅฒๅญๅบซใๆจๆๅบ็ๅ้กๆ็ผ่กจ็็่จๅๅบไปปไฝๆไฝใ
-followers_one = %d ๅ่ฟฝ่ธช่
-following_one = ่ฟฝ่ธช %d ๅไบบ
-block_user.detail_3 = ่ฉฒไฝฟ็จ่
็กๆณๅฐๆจๅ ็บๅไฝ่
๏ผๆจไน็กๆณๅฐๅ
ถๅ ็บๅไฝ่
ใ
+block_user.detail_1 = ไฝ ๅๅฐๅๆญขไบ็ธ้ๆณจ๏ผไธฆไธ็กๆณไบ็ธ้ๆณจใ
+block_user.detail_2 = ๆญคไฝฟ็จ่
ๅฐ็กๆณ่ไฝ ๆๆ็ๅฒๅญๅบซๆ็ฑไฝ ๅปบ็ซ็ๅ้กๅ่ฉ่ซ้ฒ่กไบๅใ
+followers_one = %d ไฝ่ฟฝ่นค่
+following_one = ่ฟฝ่นค %d ๅไบบ
+block_user.detail_3 = ไฝ ๅๅฐ็กๆณไบ็ธๆฐๅข็บๅฒๅญๅบซๅไฝ่
ใ
follow_blocked_user = ๅ ็บ้ๅไฝฟ็จ่
ๅฐ้ๆจๆ่ขซๆจๅฐ้๏ผๆจไธ่ฝ่ฟฝ่นคๆญคไฝฟ็จ่
ใ
block = ๅฐ้
unblock = ่งฃ้คๅฐ้
-block_user.detail = ่ซๆณจๆ๏ผๅฐ้ๆญคไฝฟ็จ่
ๅฐๆๅฐ่ดไปฅไธ็ตๆใไพๅฆ๏ผ
+block_user.detail = ่ซๆณจๆ๏ผๅฐ้ไฝฟ็จ่
้ๆๅ
ถๅฎๅฝฑ้ฟ๏ผไพๅฆ๏ผ
+followers.title.one = ไฝ่ฟฝ่นค่
+followers.title.few = ไฝ่ฟฝ่นค่
+following.title.one = ้ๆณจไธญ
+following.title.few = ้ๆณจไธญ
+public_activity.visibility_hint.admin_private = ็ฑๆผไฝ ๆฏ็ฎก็ๅก๏ผๅ ๆญคไฝ ๅฏไปฅ็ๅฐๆญคๆดปๅ๏ผไฝไฝฟ็จ่
ๅธๆๅฐๅ
ถไฟๆ็งๅฏใ
+public_activity.visibility_hint.self_private_profile = ็ฑๆผไฝ ็ๅไบบ่ณๆๆฏ็งๅฏ็๏ผๅ ๆญคๅชๆไฝ ๅ็ซ้ป็ฎก็ๅกๅฏไปฅ็ๅฐไฝ ็ๆดปๅใ้
็ฝฎ ใ
+public_activity.visibility_hint.self_public = ้ค็งไบบ็ฉบ้็ไบๅๅค๏ผไฝ ็ๆดปๅๅฐๆๆไบบ้ฝๅฏ่ฆใ้
็ฝฎ ใ
+public_activity.visibility_hint.admin_public = ๆฏๅไบบ้ฝๅฏไปฅ็ๅฐๆญคๆดปๅ๏ผไฝไฝ็บ็ฎก็ๅก๏ผไฝ ้ๅฏไปฅ็ๅฐ็งไบบ็ฉบ้ไธญ็ไบๅใ
+public_activity.visibility_hint.self_private = ไฝ ็ๆดปๅๅ
ๅฐไฝ ๅ็ซ้ป็ฎก็ๅกๅฏ่ฆใ้
็ฝฎ ใ
[settings]
profile=ๅไบบ่ณๆ
@@ -743,14 +798,14 @@ old_password=็ฎๅ็ๅฏ็ขผ
new_password=ๆฐ็ๅฏ็ขผ
retype_new_password=็ขบ่ชๆฐๅฏ็ขผ
password_incorrect=่ผธๅ
ฅ็ๅฏ็ขผไธๆญฃ็ขบใ
-change_password_success=ๆจ็ๅฏ็ขผๅทฒๆดๆฐใ ๅพ็พๅจ่ตทไฝฟ็จๆจ็ๆฐๅฏ็ขผ็ปๅ
ฅใ
+change_password_success=ๆจ็ๅฏ็ขผๅทฒๆดๆฐใ ๅพ็พๅจ้ๅง๏ผไฝฟ็จๆจ็ๆฐๅฏ็ขผ็ปๅ
ฅใ
password_change_disabled=้ๆฌๅฐๅธณ่็กๆณ้้ Forgejo ็็ถฒ้ ไป้ขๆดๆนๅฏ็ขผใ
emails=้ปๅญไฟก็ฎฑ
manage_emails=็ฎก็้ปๅญไฟก็ฎฑ
manage_themes=้ ่จญไฝๆฏไธป้ก
manage_openid=OpenID ๅฐๅ
-theme_desc=้ๅฐๆฏๆจๅจๆดๅ็ถฒ็ซไธ็้ ่จญไฝๆฏไธป้กใ
+theme_desc=ๆญคไธป้กๅฐๅจๆจๅทฒ็ปๅ
ฅๆๅฅ็จๆผ็ถฒ็ซไป้ขใ
primary=ไธป่ฆ
activated=ๅทฒๅ็จ
requires_activation=้่ฆๅๅ
@@ -787,7 +842,7 @@ ssh_helper=้่ฆๅๅฉๅ๏ผ ๅปบ่ญฐๅฏ็็ GitHub ็ๆไปถ
gpg_helper=้่ฆๅๅฉๅ๏ผ ๅปบ่ญฐๅฏ็็ GitHub ็ about GPG ๆไปถใ
add_new_key=ๆฐๅข SSH ้้ฐ
add_new_gpg_key=ๆฐๅข GPG ้้ฐ
-key_content_ssh_placeholder=ไปฅ ใssh-ed25519ใใใssh-rsaใใใecdsa-sha2-nistp256ใใใecdsa-sha2-nistp384ใใใecdsa-sha2-nistp521ใใใsk-ecdsa-sha2-nistp256@openssh.comใใๆ ใsk-ssh-ed25519@openssh.comใ ้้ ญ
+key_content_ssh_placeholder=ไปฅ ใssh-ed25519ใใใssh-rsaใใใecdsa-sha2-nistp256ใใใecdsa-sha2-nistp384ใใใecdsa-sha2-nistp521ใใใsk-ecdsa-sha2-nistp256@openssh.comใๆ ใsk-ssh-ed25519@openssh.comใ ้้ ญ
key_content_gpg_placeholder=ไปฅ ใ-----BEGIN PGP PUBLIC KEY BLOCK-----ใ ้้ ญ
add_new_principal=ๆฐๅขไธป้ซ
ssh_key_been_used=ๆญค SSH ้้ฐๆฉๅทฒๅ ๅ
ฅๆฌไผบๆๅจใ
@@ -853,7 +908,7 @@ unbind=่งฃ้ค้ฃ็ต
manage_access_token=็ฎก็ๅญๅ็ฌฆ่จ
generate_new_token=็ข็ๆฐ็็ฌฆ่จ
-tokens_desc=้ไบ็ฌฆ่จ้้ Forgejo API ็ฒๅพๅญๅๆจๅธณ่็ๆฌ้ใ
+tokens_desc=้ไบ็ฌฆ่จ้้ Forgejo API ๆไบๅญๅๆจๅธณ่็ๆฌ้ใ
token_name=็ฌฆ่จๅ็จฑ
generate_token=็ข็็ฌฆ่จ
generate_token_success=ๅทฒ็ถ็ข็ๆฐ็็ฌฆ่จใ่ซ็ซๅป่ค่ฃฝๅฎ๏ผๅ ็บๅฎๅฐไธๆ่ขซๅๆฌก้กฏ็คบใ
@@ -870,10 +925,10 @@ permission_read=่ฎๅ
manage_oauth2_applications=็ฎก็ OAuth2 ๆ็จ็จๅผ
edit_oauth2_application=็ทจ่ผฏ OAuth2 ๆ็จ็จๅผ
oauth2_applications_desc=OAuth2 ๆ็จ็จๅผ่ฎๆจ็็ฌฌไธๆนๆ็จ็จๅผๅฎๅ
จๅฐ้ฉ่ญๆญค Forgejo ็ซ้ปไธญ็ไฝฟ็จ่
ใ
-remove_oauth2_application=ๅช้ค OAuth2 ๆ็จ็จๅผ
+remove_oauth2_application=็งป้ค OAuth2 ๆ็จ็จๅผ
remove_oauth2_application_desc=ๅช้ค OAuth2 ๆ็จ็จๅผๅฐๆๆค้ทๆๆๅทฒ็ฐฝ็ฝฒ็ๅญๅ็ฌฆ่จไนๅญๅๆฌใๆฏๅฆ็นผ็บ๏ผ
-remove_oauth2_application_success=ๅทฒๅช้คๆ็จ็จๅผใ
-create_oauth2_application=ๆฐๅข OAuth2 ๆ็จ็จๅผ
+remove_oauth2_application_success=ๅทฒ็งป้คๆ็จ็จๅผใ
+create_oauth2_application=ๅปบ็ซๆฐ็ OAuth2 ๆ็จ็จๅผ
create_oauth2_application_button=ๅปบ็ซๆ็จ็จๅผ
oauth2_application_name=ๆ็จ็จๅผๅ็จฑ
oauth2_confidential_client=ๆฉๅฏๅฎขๆถ็ซฏ (Confidential Client)ใ่ซ็บ่ฝไฟๆๆฉๅฏๆง็็จๅผๅพ้ธ๏ผไพๅฆ็ถฒ้ ๆ็จ็จๅผใไฝฟ็จๅ็็จๅผๆไธ่ฆๅพ้ธ๏ผๅ
ๅซๆก้ขใ่กๅๆ็จ็จๅผใ
@@ -907,7 +962,7 @@ passcode_invalid=็กๆ็้ฉ่ญ็ขผ๏ผ่ซ้่ฉฆใ
twofa_enrolled=ๆจ็ๅธณ่ๅทฒ็ถๅ็จไบๅ
ฉๆญฅ้ฉ้ฉ่ญใ่ซๅฐๅ็จ้ฉ่ญ็ขผ๏ผ%s๏ผไฟๅญๅฐๅฎๅ
จ็ๅฐๆน๏ผๅฎๅชๆ่ขซ้กฏ็คบไธๆฌกใ
twofa_failed_get_secret=ๅๅพๅฏ้ฐ (Secret) ๅคฑๆใ
-webauthn_desc=ๅฎๅ
จ้้ฐๆฏๅ
ๅซๅ ๅฏๅฏ้ฐ็็กฌ้ซ่จญๅ๏ผๅฎๅๅฏไปฅ็จๆผๅ
ฉๆญฅ้ฉ้ฉ่ญใๅฎๅ
จ้้ฐๅฟ
้ ๆฏๆด WebAuthn Authenticator ๆจๆบใ
+webauthn_desc=ๅฎๅ
จ้้ฐๆฏๅ
ๅซๅ ๅฏๅฏ้ฐ็็กฌ้ซ่จญๅ๏ผๅฎๅๅฏไปฅ็จๆผๅ
ฉๆญฅ้ฉ้ฉ่ญใๅฎๅ
จ้้ฐๅฟ
้ ๆฏๆด WebAuthn Authenticator ๆจๆบใ
webauthn_register_key=ๆฐๅขๅฎๅ
จ้้ฐ
webauthn_nickname=ๆฑ็จฑ
webauthn_delete_key=็งป้คๅฎๅ
จ้้ฐ
@@ -915,10 +970,10 @@ webauthn_delete_key_desc=ๅฆๆๆจ็งป้คๅฎๅ
จ้้ฐ๏ผๅฐไธ่ฝๅไฝฟ็จๅฎ็ป
manage_account_links=้ฃ็ต็ๅธณ่
manage_account_links_desc=้ไบๅค้จๅธณ่ๅทฒ้ฃ็ต่ณๆจ็ Forgejo ๅธณ่ใ
-account_links_not_available=็ฎๅๆฒๆๅค้จๅธณ่้ฃ็ตๅฐๆจ็ Forgejo ๅธณ่ใ
+account_links_not_available=็ฎๅๆฒๆๅค้จๅธณ่้ฃ็ต่ณๆจ็ Forgejo ๅธณ่ใ
link_account=้ฃ็ตๅธณ่
remove_account_link=ๅช้ค้ฃ็ต็ๅธณ่
-remove_account_link_desc=็งป้ค้ฃ็ตๅธณ่ๅฐๆค้ทๅ
ถๅฐ Forgejo ๅธณ่็ๅญๅๆฌ้ใๆฏๅฆ็นผ็บ๏ผ
+remove_account_link_desc=็งป้ค้ฃ็ตๅธณ่ๅฐๆค้ทๅ
ถๅฐ Forgejo ๅธณ่็ๅญๅๆฌ้ใ่ฆ็นผ็บๅ๏ผ
remove_account_link_success=ๅทฒ็งป้ค้ฃ็ต็ๅธณ่ใ
@@ -942,18 +997,18 @@ visibility.public=ๅ
ฌ้
visibility.public_tooltip=ๆๆไบบ้ฝๅฏไปฅ็ๅฐ
visibility.limited=ๅ้
visibility.private=็งๆ
-blocked_users_none = ๆจๆฒๆๅฐ้ไปปไฝไฝฟ็จ่
ใ
+blocked_users_none = ๆฒๆไปปไฝ่ขซๅฐ้็ไฝฟ็จ่
ใ
blocked_users = ๅฐ้็ไฝฟ็จ่
hints = ๆ็คบ
update_hints = ๆดๆฐๆ็คบ
update_hints_success = ๆ็คบๅทฒ่ขซๆดๆนใ
added_on = ๆผ %s ๆฐๅข
-biography_placeholder = ๅๆๅไป็ดนไธไธๆจ่ชๅทฑๅง๏ผ๏ผๆจๅฏไปฅไฝฟ็จ Markdown๏ผ
-location_placeholder = ่ๅ
ถไปไบบๅไบซๆจ็ๅฐ็ไฝ็ฝฎ
-profile_desc = ็ฎก็ๅ
ถไปไบบๅฆไฝ็ๅฐๆจ็ๅไบบ่ณๆใ้็ฅใๅฏ็ขผๅพฉๅๅ็ถฒ้ ไธ็ Git ๆไฝๆไฝฟ็จๆจ็ไธป่ฆ้ปๅญไฟก็ฎฑใ
+biography_placeholder = ๅๅฅไบบ็ฐกๅฎไป็ดนไธไธ่ชๅทฑ๏ผ๏ผๆฏๆด Markdown๏ผ
+location_placeholder = ่ๅ
ถไปไบบๅไบซๆจ็ฒ็ฅ็ๅฐ็ไฝ็ฝฎ
+profile_desc = ้ๆผไฝ
hidden_comment_types.ref_tooltip = ่จป่จๅชไบๅ้ก๏ผๆไบค๏ผโฆ ๆๅไบๆญคๅ้ก
keep_activity_private = ้ฑ่ๅไบบ้ ้ขไธญ็ๆดปๅ่ณๆ
-uploaded_avatar_is_too_big = ไธๅณๆชๆก็ๅคงๅฐ ๏ผ%d KiB๏ผ่ถ
้ไบไธ้ (%d KiB ๏ผใ
+uploaded_avatar_is_too_big = ไธๅณๆชๆก็ๅคงๅฐ ๏ผ%d KiB๏ผ่ถ
้ไบไธ้ ๏ผ%d KiB ๏ผใ
select_permissions = ้ธๆๆฌ้
permission_write = ่ฎๅฏซ
permissions_list = ๆฌ้๏ผ
@@ -970,7 +1025,7 @@ social_desc = ้ไบ็คพ็พคๅธณ่ๅฏไปฅ่ขซ็จไพ็ปๅ
ฅๆจ็ๅธณ่ใ่ซ็ขบไฟๆจ
unbind_success = ๅทฒๆๅ็งป้ค่ฉฒ็คพ็พคๅธณ่ใ
create_oauth2_application_success = ๆจๅทฒๆๅๅปบ็ซไธๅๆฐ็ OAuth2 ๆ็จ็จๅผใ
change_username_prompt = ่จป๏ผๆดๆนๆจ็ไฝฟ็จ่
ๅ็จฑไนๆๆดๆนๆจ็ๅธณ่ URLใ
-change_username_redirect_prompt = ่็ไฝฟ็จ่
ๅ็จฑๅจๅ
ถไปไฝฟ็จ่
่ช้ ไนๅๅฐๆ่ฝๅๅฐๆฐ็ไฝฟ็จ่
ๅ็จฑใ
+change_username_redirect_prompt = ่็ไฝฟ็จ่
ๅ็จฑๅจ่ขซๅ
ถไปไฝฟ็จ่
่ช้ ไนๅๅฐๆ่ฝๅๅฐๆฐ็ไฝฟ็จ่
ๅ็จฑใ
visibility.limited_tooltip = ๅชๆๅทฒ็ปๅ
ฅ็ไฝฟ็จ่
่ฝ็่ฆ
visibility.private_tooltip = ๅชๆๆจๅ ๅ
ฅ็็ต็นไนๆๅก่ฝ็่ฆ
keep_email_private_popup = ้ๅฐๅจๆจ็ๅไบบ่ณๆ้ ้ขใๅไฝต่ซๆฑๆ็ถฒ้ ๆชๆก็ทจ่ผฏๅจไธญ้ฑ่ๆจ็้ปๅญไฟก็ฎฑๅฐๅใๅทฒๆจ้็ๆไบคไธๆ่ขซไฟฎๆนใๅจๆไบคไธญไฝฟ็จ %s ไพๅฐๅ
ถ้ฃ็ต่ณๆจ็ๅธณ่ใ
@@ -978,9 +1033,9 @@ ssh_signonly = ๅ ็บ็ฎๅ SSH ๅทฒ่ขซๅ็จ๏ผ้ๅ้้ฐๅช่ขซ็จไพๆ ก้ฉๆ
email_desc = ๆจ็ไธป่ฆ้ปๅญไฟก็ฎฑๅฐ่ขซ็จๆผ้็ฅใๅฏ็ขผๅพฉๅใๅ็ถฒ้ Git ๆไฝ๏ผๅฆๆๆจ็ไฟก็ฎฑไธๆฏ้ฑ่็๏ผใ
pronouns_custom = ่ช่จ
oauth2_client_secret_hint = ้ๆๅฏ้ฐๅจๆจ้ข้ๆ้ๆฐๆด็ๆญค้ ้ขๅพๅฐไธๅ่ขซ้กฏ็คบใ่ซ็ขบไฟๆจๅทฒๅฒๅญๅฎใ
-additional_repo_units_hint_description = ๅจๆฒๆๅ็จๆๆๆจก็ต็ๅฒๅญๅบซไธญ้กฏ็คบใๆฐๅขๆดๅคๆจก็ตโฆใๆ้ใ
+additional_repo_units_hint_description = ๅฐๆผๆชๅ็จๆๆๅฏ็จๅ่ฝ็ๅฒๅญๅบซ้กฏ็คบใๅ็จๆดๅคใๆ็คบใ
hidden_comment_types.issue_ref_tooltip = ไฝฟ็จ่
ๆดๆน่ๅ้ก็ธ้ๅๆฏ๏ผๆจ็ฑค็็่จ
-pronouns = ไปฃๅ่ฉ
+pronouns = ็จฑ่ฌ่ช
update_oauth2_application_success = ๆจๅทฒๆๅๆดๆฐ่ฉฒ OAuth2 ๆ็จ็จๅผใ
oauth2_redirect_uris = ่ฝๅ URIใๆฏๅ URI ๆๅไฝไธ่กใ
pronouns_unspecified = ๆชๆๅฎ
@@ -997,10 +1052,17 @@ webauthn_key_loss_warning = ๅฆๆๆจๅผไธไบๆจ็ๅฎๅ
จ้้ฐ๏ผๆจๅฐ็กๆณ
user_unblock_success = ๅทฒๆๅ่งฃ้คๅฐๆญคไฝฟ็จ่
็ๅฐ้ใ
webauthn_alternative_tip = ๆจๅฏ่ฝๆณๆฐๅขไธๅ้กๅค็้ฉ่ญๆนๆณใ
user_block_success = ๅทฒๆๅๅฐ้ๆญคไฝฟ็จ่
ใ
-access_token_desc = ๅทฒ้ธๆ็็ฌฆ่จๅ
ๆๆฌ็ธๅฐๆ็ API ่ทฏๅพใ่ซๅ้ฑๆไปถ ไพไบ่งฃๆดๅคใ
+access_token_desc = ้ธๆ็็ฌฆ่จๅ
ๆๆฌ็ธๅฐๆ็ API่ทฏๅพ ใ่ซๅ้ฑๆไปถ ไพไบ่งฃๆดๅคใ
oauth2_application_locked = ๅฏไปฅๅจ็ตๆ
ไธญ่จญๅฎ Forgejo ้ ๅ
่จปๅไธไบ OAuth2 ๆ็จ็จๅผใ็บไบ้ฟๅ
ไธๅฏ้ ๆ็ๆ
ๆณ๏ผๅฎๅ็กๆณ่ขซ็ทจ่ผฏๆๆฏ็งป้คใ่ซๅ้ฑ OAuth2 ๆไปถไพไบ่งฃๆดๅคใ
hidden_comment_types_description = ๅจ้่ฃก้ธๅ็็่จ็จฎ้กๅฐไธๆ้กฏ็คบๆผๅ้ก้ ้ขไธญใ่ไพไพ่ชช๏ผๆ ธๅใๆจ็ฑคใๅฐ้ฑ่ๆๆใไฝฟ็จ่
ๆฐๅข๏ผ็งป้คไบ<ๆจ็ฑค>ใ็่จใ
authorized_oauth2_applications_description = ๆจๅทฒๆๆฌ็ตฆ้ไบ็ฌฌไธๆนๆ็จ็จๅผๅ็จๆจ็ Forgejo ๅไบบๅธณ่็ๆฌ้ใ่ซๆค้ทๆจไธๅไฝฟ็จ็ๆ็จ็จๅผ็ๆฌ้ใ
+language.localization_project = ๅนซๅฉๆๅ็ฟป่ญฏ Forgejo ่ณๆจ็่ช่จ๏ผไบ่งฃๆดๅค ใ
+language.description = ้ๅ่ช่จๆ่ขซๅฒๅญ่ณๆจ็ๅธณ่๏ผไธฆ่ขซ็จไฝๆจ็ปๅ
ฅๅพ็้ ่จญ่ช่จใ
+user_block_yourself = ไฝ ไธ่ฝๅฐ้่ชๅทฑใ
+pronouns_custom_label = ่ช่จไปฃๅ่ฉ
+change_username_redirect_prompt.with_cooldown.one = ่็ไฝฟ็จ่
ๅ็จฑๅฐๅจ %[1]d ๅคฉ็ๅทๅปๆๅพๅฐๆๆไบบ้ๆพ๏ผไฝ ไป็ถๅฏไปฅๅจๅทๅปๆๅ
ง้ๆฐ็ฒๅพ่็ไฝฟ็จ่
ๅ็จฑใ
+change_username_redirect_prompt.with_cooldown.few = ่็ไฝฟ็จ่
ๅ็จฑๅฐๅจ %[1]d ๅคฉ็ๅทๅปๆๅพๅฐๆๆไบบ้ๆพ๏ผไฝ ไป็ถๅฏไปฅๅจๅทๅปๆๅ
ง้ๆฐ็ฒๅพ่็ไฝฟ็จ่
ๅ็จฑใ
+keep_activity_private.description = ไฝ ็ๅ
ฌ้ๆดปๅ ๅชๆไฝ ๅ็ซ้ป็ฎก็ๅกๅฏ่ฆใ
[repo]
owner=ๆๆ่
@@ -1009,7 +1071,7 @@ repo_name=ๅฒๅญๅบซๅ็จฑ
repo_name_helper=ๅฅฝ็ๅฒๅญๅบซๅ็จฑ้ๅธธๆฏ็ฐก็ญ็ใๅฅฝ่จ็ใไธ็จ็น็ใ
repo_size=ๅฒๅญๅบซๅคงๅฐ
template=็ฏๆฌ
-template_select=้ธๆ็ฏๆฌใ
+template_select=้ธๆ็ฏๆฌ
template_helper=ๅฐๅฒๅญๅบซ่จญ็บ็ฏๆฌ
template_description=ๅฒๅญๅบซ็ฏๆฌ่ฎไฝฟ็จ่
ๅฏๆฐๅข็ธๅ็ฎ้็ตๆงใๆชๆกไปฅๅ่จญๅฎ็ๅฒๅญๅบซใ
visibility=็่ฆฝๆฌ้
@@ -1032,17 +1094,17 @@ generate_from=็ข็่ช
repo_desc=ๆ่ฟฐ
repo_desc_helper=่ผธๅ
ฅ็ฐกไป (้ธ็จ)
repo_lang=ๅฒๅญๅบซ่ช่จ
-repo_gitignore_helper=้ธๆ .gitignore ็ฏๆฌใ
+repo_gitignore_helper=้ธๆ .gitignore ็ฏๆฌ
repo_gitignore_helper_desc=ๅพๅธธ่ฆ่ช่จ็ฏๆฌๆธ
ๅฎไธญๆ้ธๅฟฝ็ฅ่ฟฝ่นค็ๆชๆกใ้ ่จญๆ
ๆณไธๅ็จฎ่ช่จๅปบ็ฝฎๅทฅๅ
ท็ข็็็นๆฎๆชๆก้ฝๅ
ๅซๅจ .gitignore ไธญใ
-issue_labels=ๅ้กๆจ็ฑค
-issue_labels_helper=้ธๆๅ้กๆจ็ฑค้ใ
+issue_labels=ๆจ็ฑค
+issue_labels_helper=้ธๆๆจ็ฑค้
license=ๆๆฌๆขๆฌพ
-license_helper=่ซ้ธๆๆๆฌๆขๆฌพๆชๆกใ
-license_helper_desc=ๆๆฌๆขๆฌพๅฎ็พฉไบไปไบบไฝฟ็จๆจๅๅง็ขผ็ๅ
่จฑๅ็ฆๆญขไบ้
ใไธ็ขบๅฎๅชๅ้ฉ็จๆผๆจ็ๅฐๆก๏ผๆฅ็้ธๆๆๆฌๆขๆฌพใ
+license_helper=้ธๆๆๆฌๆขๆฌพๆชๆก
+license_helper_desc=ๆๆฌๆขๆฌพๅฎ็พฉไบไปไบบไฝฟ็จๆจๅๅง็ขผ็ๅ
่จฑๅ็ฆๆญขไบ้
ใไธ็ขบๅฎๅชๅ้ฉ็จๆผๆจ็ๅฐๆก๏ผๆฅ็้ธๆๆๆฌๆขๆฌพ ใ
readme=่ฎๆๆชๆก
-readme_helper=้ธๆ่ฎๆๆชๆก็ฏๆฌใ
+readme_helper=้ธๆ่ฎๆๆชๆก็ฏๆฌ
readme_helper_desc=้ๆฏๆจ่ฝ็บๅฐๆกๆฐๅฏซๅฎๆดๆ่ฟฐ็ๅฐๆนใ
-auto_init=ๅๅงๅๅฒๅญๅบซ (ๅ ๅ
ฅ .gitignoreใๆๆฌๆขๆฌพใ่ฎๆๆชๆก)
+auto_init=ๅๅงๅๅฒๅญๅบซ
trust_model_helper=้ธๆ็ฐฝ็ฝฒ้ฉ่ญ็ไฟกไปปๆจกๅใๅฏ็จ็้ธ้
:
trust_model_helper_collaborator=ๅไฝ่
: ไฟกไปปๅไฝ่
็็ฐฝ็ฝฒ
trust_model_helper_committer=ๆไบค่
: ไฟกไปป่ๆไบค่
็ธ็ฌฆ็็ฐฝ็ฝฒ
@@ -1053,12 +1115,12 @@ default_branch=้ ่จญๅๆฏ
default_branch_helper=้ ่จญๅๆฏๆฏๅไฝต่ซๆฑๅๆไบค็จๅผ็ขผ็ๅบๅบๅๆฏใ
mirror_prune=่ฃๆธ
mirror_prune_desc=ๅช้ค้ๆ็้ ็ซฏ่ฟฝ่นคๅ่
-mirror_interval=้กๅ้ฑๆ๏ผๆๆๆ้ๅฎไฝ็บใhใใใmใใใsใ๏ผ๏ผ่จญ็บ 0 ไปฅๅ็จๅฎๆๅๆญฅใ๏ผๆๅฐๅผ็บ๏ผ%s๏ผ
+mirror_interval=้กๅ้ฑๆ๏ผๆๆๆ้ๅฎไฝ็บใhใใใmใใใsใ๏ผใ่จญ็บ 0 ไปฅๅ็จๅฎๆๅๆญฅใ๏ผๆๅฐๅผ็บ๏ผ%s๏ผ
mirror_interval_invalid=้กๅ้ฑๆ็กๆใ
mirror_sync_on_commit=ๆจ้ๆไบคๅพ้ฒ่กๅๆญฅ
-mirror_address=ๅพ URL Clone
+mirror_address=ๅพ URL ๆ่ฃฝ
mirror_address_desc=ๅจๆๆฌ่ณ่จไธญๅกซๅ
ฅๅฟ
่ฆ็่ณๆใ
-mirror_lfs=Large File Storage (LFS)
+mirror_lfs=ๅคงๆชๆกๅฒๅญ๏ผLFS๏ผ
mirror_lfs_desc=ๅๅ LFS ๆชๆก็้กๅๅ่ฝใ
mirror_lfs_endpoint=LFS ็ซฏ้ป
mirror_lfs_endpoint_desc=ๅๆญฅๅฐๆๅ่ฉฆไฝฟ็จ Clone URL ไพ็ขบ่ช LFS ไผบๆๅจ ใๅฆๆๅญๅฒๅบซ็ LFS ่ณๆๆพๅจๅ
ถไปๅฐๆน๏ผๆจไนๅฏไปฅๆๅฎ่ช่จ็็ซฏ้ปใ
@@ -1144,7 +1206,7 @@ migrate.migrate_items_options=้ท็งปๅ
ถไป้
็ฎ้่ฆๅญๅ็ฌฆ่จ
migrated_from=ๅทฒๅพ %[2]s ้ท็งป
migrated_from_fake=ๅทฒๅพ %[1]s ้ท็งป
migrate.migrate=ๅพ %s ้ท็งป
-migrate.migrating=ๆญฃๅจๅพ %s ้ท็งป...
+migrate.migrating=ๆญฃๅจๅพ %s ้ท็งปโฆ
migrate.migrating_failed=ๅพ %s ้ท็งปๅคฑๆใ
migrate.migrating_failed_no_addr=้ท็งปๅคฑๆใ
migrate.github.description=ๅพ github.com ๆ GitHub Enterprise ไผบๆๅจ้ท็งป่ณๆใ
@@ -1226,12 +1288,13 @@ ambiguous_runes_line=`้ไธ่กๆๆๆททๆท็ Unicode ๅญๅ
`
ambiguous_character=`%[1]c [U+%04[1]X] ๅฎนๆ่ %[2]c [U+%04[2]X] ๆททๆท`
escape_control_characters=Escape
-unescape_control_characters=Unescape
+unescape_control_characters=ๅๆถ่ฝ็พฉ
file_copy_permalink=่ค่ฃฝๆฐธไน
้ฃ็ต
view_git_blame=ๆชข่ฆ Git Blame
video_not_supported_in_browser=ๆจ็็่ฆฝๅจไธๆฏๆด HTML5 ็ใvideoใๆจ็ฑคใ
audio_not_supported_in_browser=ๆจ็็่ฆฝๅจไธๆฏๆด HTML5 ็ใaudioใๆจ็ฑคใ
stored_lfs=ๅทฒไฝฟ็จ Git LFS ๅฒๅญ
+stored_annex=ๅทฒไฝฟ็จ Git Annex ๅฒๅญ
symbolic_link=็ฌฆ่้ฃ็ต
commit_graph=ๆไบค็ทๅ
commit_graph.select=้ธๆๅๆฏ
@@ -1249,8 +1312,9 @@ editor.add_file=ๆฐๅขๆชๆก
editor.new_file=ๅปบ็ซๆฐๆชๆก
editor.upload_file=ไธๅณๆชๆก
editor.edit_file=็ทจ่ผฏๆชๆก
-editor.preview_changes=้ ่ฆฝๆดๆน
+editor.preview_changes=้ ่ฆฝ่ฎๆด
editor.cannot_edit_lfs_files=็กๆณๅจ web ไป้ขไธญ็ทจ่ผฏ LFS ๆชใ
+editor.cannot_edit_annex_files=็กๆณๅจ web ไป้ขไธญ็ทจ่ผฏ Annex ๆชใ
editor.cannot_edit_non_text_files=็ถฒ็ซไป้ขไธ่ฝ็ทจ่ผฏไบ้ฒไฝๆชๆกใ
editor.edit_this_file=็ทจ่ผฏๆชๆก
editor.this_file_locked=ๆชๆกๅทฒ่ขซ้ๅฎ
@@ -1260,12 +1324,13 @@ editor.delete_this_file=ๅช้คๆชๆก
editor.must_have_write_access=ๆจๅฟ
้ ๆๆๅฏซๅ
ฅๆฌ้ๆ่ฝๅฐๆญคๆชๆก้ฒ่กไฟฎๆนๆๆๅบ่ฎๆดใ
editor.file_delete_success=ๅทฒๅช้คๆไปถใ%sใใ
editor.name_your_file=ๅฝๅๆจ็ๆชๆกโฆ
-editor.filename_help=่ผธๅ
ฅๅ็จฑๅๆ็ท๏ผ"/"๏ผ ไปฅๆฐๅข็ฎ้ใๅจๆๅญๆก้ๅง่่ผธๅ
ฅ้ๆ ผ้ตไปฅ็งป้ค็ฎ้ใ
+editor.filename_help=่ผธๅ
ฅไปฅๆ็ท๏ผ"/"๏ผ็ตๅฐพ็ๅ็จฑไพๆฐๅข็ฎ้ใๅจๆๅญๆก้ๅง่่ผธๅ
ฅ้ๆ ผ้ตไปฅ็งป้ค็ฎ้ใ
editor.or=ๆ
editor.cancel_lower=ๅๆถ
-editor.commit_signed_changes=ๆไบค็ฐฝ็ฝฒ้็่ฎๆด
+editor.commit_signed_changes=ๆไบค็ฐฝ็ฝฒ็่ฎๆด
editor.commit_changes=ๆไบค่ฎๆด
-editor.add_tmpl=ๆฐๅขใใ
+editor.add_tmpl=ๆฐๅขใ<%s>ใ
+editor.add_tmpl.filename = ๆชๆก
editor.add=ๆฐๅข %s
editor.update=ๆดๆฐ %s
editor.delete=ๅช้ค %s
@@ -1275,7 +1340,7 @@ editor.fail_to_apply_patch=็กๆณๅฅ็จ่ฃ็ถดใ%sใ
editor.new_patch=ๆฐๅข่ฃ็ถด
editor.commit_message_desc=๏ผ้ธๅกซ๏ผๅ ๅ
ฅ่ฉณ็ดฐ่ชชๆโฆ
editor.signoff_desc=ๅจๆไบค่จๆฏๅบ้จๅ ๅ
ฅๆไบค่
็ใSigned-off-byใ่ณ่จใ
-editor.commit_directly_to_this_branch=็ดๆฅๆไบคๅฐ %s ๅๆฏใ
+editor.commit_directly_to_this_branch=็ดๆฅๆไบคๅฐ %[1]s ๅๆฏใ
editor.create_new_branch=็บๆญคๆไบคๅปบ็ซๆฐๅๆฏ ไธฆๆๅบๅไฝต่ซๆฑใ
editor.create_new_branch_np=็บๆฌๆฌกๆไบคๅปบ็ซๆฐๅๆฏ ใ
editor.propose_file_change=ๆๅบๆชๆก่ฎๆด
@@ -1286,14 +1351,14 @@ editor.filename_cannot_be_empty=ๆชๆกๅ็จฑไธ่ฝ็บ็ฉบใ
editor.filename_is_invalid=ๆชๅ็กๆ๏ผใ%sใใ
editor.branch_does_not_exist=ๆญคๅฒๅญๅบซๆฒๆๅ็บใ%sใ็ๅๆฏใ
editor.branch_already_exists=ๆญคๅฒๅญๅบซๅทฒๆๅ็บใ%sใ็ๅๆฏใ
-editor.file_changed_while_editing=ๆชๆกๅ
งๅฎนๅจๆจ็ทจ่ผฏๆๅทฒ่ขซ่ฎๆดใๆไธไธๆญค่ ๆฅ็่ขซๆดๅ็ๅฐๆนๆๅๆฌกๆไบค ไปฅ่ฆ่้ไบ่ฎๆดใ
+editor.file_changed_while_editing=ๆชๆกๅ
งๅฎนๅจๆจ็ทจ่ผฏๆๅทฒ่ขซๆดๆนใๆไธไธๆญค่ ไพๆชข่ฆ่ขซๆดๆน็ๅฐๆนๆๅๆฌกๆไบค ไปฅ่ฆ่้ไบ่ฎๆดใ
editor.file_already_exists=ๆญคๅฒๅญๅบซๅทฒๆๅ็บใ%sใ็ๆชๆกใ
editor.commit_empty_file_header=ๆไบค็ฉบ็ฝๆชๆก
editor.commit_empty_file_text=ไฝ ๆบๅๆไบค็ๆชๆกๆฏ็ฉบ็ฝ็๏ผๆฏๅฆ็นผ็บ๏ผ
editor.no_changes_to_show=ๆฒๆๅฏไปฅ้กฏ็คบ็่ฎๆดใ
editor.fail_to_update_file=ๆดๆฐ/ๅปบ็ซๆชๆกใ%sใๅคฑๆใ
editor.fail_to_update_file_summary=้ฏ่ชค่จๆฏ๏ผ
-editor.push_rejected_no_message=่ฉฒ่ฎๆด่ขซไผบๆๅจๆ็ต๏ผๅฎๆชๆไพๅ
ถไป่ณ่จใ่ซๆชขๆฅ Git Hookใ
+editor.push_rejected_no_message=่ฉฒ่ฎๆด่ขซไผบๆๅจๆ็ต๏ผๅฎๆชๆไพๅ
ถไป่จๆฏใ่ซๆชขๆฅ Git Hookใ
editor.push_rejected=่ฉฒ่ฎๆด่ขซไผบๆๅจๆ็ตใ่ซๆชขๆฅ Git Hookใ
editor.push_rejected_summary=ๅฎๆด็ๆ็ต่จๆฏ๏ผ
editor.add_subdir=ๅ ๅ
ฅ็ฎ้โฆ
@@ -1339,7 +1404,7 @@ commitstatus.failure=ๅคฑๆ
commitstatus.pending=ๅพ
่็
commitstatus.success=ๆๅ
-ext_issues=ๅญๅๅค้จๅ้ก
+ext_issues=ๅค้จๅ้ก
ext_issues.desc=้ฃ็ตๅฐๅค้จๅ้ก่ฟฝ่นคๅจใ
projects=ๅฐๆก
@@ -1554,15 +1619,15 @@ issues.label.filter_sort.alphabetically=ๆๅญๆฏ้ ๅบๆๅบ
issues.label.filter_sort.reverse_alphabetically=ๆๅญๆฏๅๅๆๅบ
issues.label.filter_sort.by_size=ๆชๆก็ฑๅฐๅฐๅคง
issues.label.filter_sort.reverse_by_size=ๆชๆก็ฑๅคงๅฐๅฐ
-issues.num_participants_few=%d ๅ่่
+issues.num_participants_few=%d ไฝๅ่่
issues.attachment.open_tab=`ๅจๆฐๅ้ ไธญๆฅ็ใ%sใ`
issues.attachment.download=`้ปๆไธ่ผใ%sใ`
issues.subscribe=่จ้ฑ
issues.unsubscribe=ๅๆถ่จ้ฑ
-issues.unpin_issue=ๅๆถๅบๅฎๅ้ก
-issues.max_pinned=ๆจไธ่ฝๅบๅฎๆดๅคๅ้ก
-issues.pin_comment=ๅบๅฎๆผ %s
-issues.unpin_comment=ๅๆถๅบๅฎๆผ %s
+issues.unpin_issue=ๅๆถ้้ธๅ้ก
+issues.max_pinned=ๆจไธ่ฝ้้ธๆดๅคๅ้ก
+issues.pin_comment=้้ธๆผ %s
+issues.unpin_comment=ๅๆถ้้ธๆผ %s
issues.lock=้ๅฎๅฐ่ฉฑ
issues.unlock=่งฃ้ๅฐ่ฉฑ
issues.lock.unknown_reason=็ฑๆผๆช็ฅ็ๅๅ ่็กๆณ้ๅฎๅ้กใ
@@ -1585,13 +1650,13 @@ issues.comment_on_locked=ๆจ็กๆณๅจๅทฒ้ๅฎ็ๅ้กไธ็่จใ
issues.delete=ๅช้ค
issues.delete.title=ๅช้คๆญคๅ้ก๏ผ
issues.delete.text=ๆจ็็่ฆๅช้คๆญคๅ้กๅ๏ผ(้ๅฐๆๆฐธไน
็งป้คๆๆๅ
งๅฎนใ่ฅๆจ้ๆณไฟ็๏ผ่ซ่ๆ
ฎๆน็บ้้ๅฎใ)
-issues.tracker=ๆ้่ฟฝ่นค
-issues.start_tracking_short=้ๅง่จๆ
+issues.tracker=ๆ้่ฟฝ่นคๅจ
+issues.start_tracking_short=้ๅง่จๆๅจ
issues.start_tracking=้ๅงๆ้่ฟฝ่นค
issues.start_tracking_history=`้ๅงๅทฅไฝ %s`
issues.tracker_auto_close=็ถ้ๅๅ้ก่ขซ้้ๆ๏ผ่ชๅๅๆญข่จๆๅจ
issues.tracking_already_started=`ๆจๅทฒๅจๅฆไธๅๅ้ก ไธ้ๅงๆ้่ฟฝ่นค๏ผ`
-issues.stop_tracking=ๅๆญข่จๆ
+issues.stop_tracking=ๅๆญข่จๆๅจ
issues.stop_tracking_history=`็ตๆๅทฅไฝ %s`
issues.cancel_tracking=ๆจๆฃ
issues.add_time=ๆๅๆฐๅขๆ้
@@ -1605,22 +1670,22 @@ issues.add_time_minutes=ๅ้
issues.add_time_sum_to_small=ๆฒๆ่ผธๅ
ฅๆ้ใ
issues.time_spent_total=็ธฝ่ฑ่ฒปๆ้
issues.time_spent_from_all_authors=`็ธฝ่ฑ่ฒปๆ้๏ผ%s`
-issues.due_date=ๆชๆญขๆฅๆ
+issues.due_date=ๅฐๆๆฅ
issues.invalid_due_date_format=ๆชๆญขๆฅๆ็ๆ ผๅผๅฟ
้ ็บใyyyy-mm-ddใใ
issues.error_modifying_due_date=็กๆณไฟฎๆนๆชๆญขๆฅๆใ
issues.error_removing_due_date=็กๆณ็งป้คๆชๆญขๆฅๆใ
issues.push_commit_1=ๅ ๅ
ฅไบ %d ๅๆไบค %s
issues.push_commits_n=ๅ ๅ
ฅไบ %d ๅๆไบค %s
-issues.force_push_codes=`ๅผทๅถๆจ้ไบ %[1]s ่ช %[2]s
่ณ %[4]s
%[6]s`
+issues.force_push_codes=`ๅผทๅถๆจ้ไบ %[1]s ่ช %[2]s
่ณ %[4]s
%[6]s`
issues.force_push_compare=ๆฏ่ผ
issues.due_date_form=yyyyๅนดmmๆddๆฅ
issues.due_date_form_add=ๆฐๅขๆชๆญขๆฅๆ
issues.due_date_form_edit=็ทจ่ผฏ
issues.due_date_form_remove=็งป้ค
-issues.due_date_not_set=ๆช่จญๅฎๆชๆญขๆฅๆใ
-issues.due_date_added=ๆฐๅขไบๆชๆญขๆฅๆ %s %s
+issues.due_date_not_set=ๆช่จญๅฎๅฐๆๆฅใ
+issues.due_date_added=ๆฐๅขไบๅฐๆๆฅ %s %s
issues.due_date_modified=ๅฐๆชๆญขๆฅๆๅพ %[2]s ไฟฎๆน็บ %[1]s %[3]s
-issues.due_date_remove=็งป้คไบๆชๆญขๆฅๆ %s %s
+issues.due_date_remove=็งป้คไบๅฐๆๆฅ %s %s
issues.due_date_overdue=้พๆ
issues.due_date_invalid=ๆชๆญขๆฅๆ็กๆๆ่ถ
ๅบ็ฏๅ๏ผ่ซไฝฟ็จใyyyy-mm-ddใ็ๆ ผๅผใ
issues.dependency.title=ๅ
ๆฑบๆขไปถ
@@ -1691,9 +1756,9 @@ compare.compare_base=ๅบๅบๅๆฏ
compare.compare_head=ๆฏ่ผ
pulls.desc=ๅ็จๅไฝต่ซๆฑๅ็จๅผ็ขผๅฏฉๆ ธใ
-pulls.new=ๅปบ็ซๅไฝต่ซๆฑ
+pulls.new=ๆฐๅไฝต่ซๆฑ
pulls.view=ๆชข่ฆๅไฝต่ซๆฑ
-pulls.compare_changes=ๅปบ็ซๅไฝต่ซๆฑ
+pulls.compare_changes=ๆฐๅไฝต่ซๆฑ
pulls.allow_edits_from_maintainers=ๅ
่จฑ็ถญ่ญท่
็ทจ่ผฏ
pulls.allow_edits_from_maintainers_desc=ๅฐๅบๅบๅๆฏๆๅฏซๅ
ฅๆฌ้็ไฝฟ็จ่
ไนๅฏไปฅๆจ้ๅฐๆญคๅๆฏ
pulls.allow_edits_from_maintainers_err=ๆดๆฐๅคฑๆ
@@ -1713,7 +1778,7 @@ pulls.nothing_to_compare=้ไบๅๆฏ็ๅ
งๅฎน็ธๅ๏ผ็ก้ๅปบ็ซๅไฝต่ซๆฑ
pulls.nothing_to_compare_and_allow_empty_pr=้ไบๅๆฏ็ๅ
งๅฎน็ธๅ๏ผๆญคๅไฝต่ซๆฑๅฐๆๆฏ็ฉบ็ฝ็ใ
pulls.has_pull_request=`ๅทฒๆไปๆผ้ไบๅๆฏ้็ๅไฝต่ซๆฑ๏ผ%[2]s#%[3]d `
pulls.create=ๅปบ็ซๅไฝต่ซๆฑ
-pulls.title_desc_few=่ซๆฑๅฐ %[1]d ๆฌก็จๅผ็ขผๆไบคๅพ %[2]s
ๅไฝต่ณ %[3]s
+pulls.title_desc_few=่ซๆฑๅฐ %[1]d ๆฌก็จๅผ็ขผๆไบคๅพ %[2]s
ๅไฝต่ณ %[3]s
pulls.merged_title_desc_few=ๅฐ %[1]d ๆฌกๆไบคๅพ %[2]s
ๅไฝต่ณ %[3]s
%[4]s
pulls.change_target_branch_at=`ๅฐ็ฎๆจๅๆฏๅพ %s ๆดๆน็บ %s %s`
pulls.tab_conversation=ๅฐ่ฉฑๅ
งๅฎน
@@ -1744,10 +1809,10 @@ pulls.num_conflicting_files_1=%d ๅ่ก็ช็ๆชๆก
pulls.num_conflicting_files_n=%d ๅ่ก็ช็ๆชๆก
pulls.approve_count_1=%d ๅๆ ธๅฏ
pulls.approve_count_n=%d ๅๆ ธๅฏ
-pulls.reject_count_1=%d ่ฎๆด่ซๆฑ
-pulls.reject_count_n=%d ่ฎๆด่ซๆฑ
-pulls.waiting_count_1=%d ็ญๅพ
ๅฏฉๆ ธ
-pulls.waiting_count_n=%d ็ญๅพ
ๅฏฉๆ ธ
+pulls.reject_count_1=%d ๅ่ฎๆด่ซๆฑ
+pulls.reject_count_n=%d ๅ่ฎๆด่ซๆฑ
+pulls.waiting_count_1=%d ๅๆญฃๅจ็ญๅพ
ๅฏฉๆ ธ
+pulls.waiting_count_n=%d ๅๆญฃๅจ็ญๅพ
ๅฏฉๆ ธ
pulls.wrong_commit_id=ๆไบค id ๅฟ
้ ๅญๅจๆผ็ฎๆจๅๆฏไธ
pulls.no_merge_desc=็กๆณ้ฒ่กๅไฝต๏ผๅ ็บๆๆๅฒๅญๅบซ็ๅไฝต้ธ้
ๅทฒ่ขซๅ็จใ
@@ -1820,9 +1885,9 @@ milestones.completeness=%d%% ๅทฒๅฎๆ
milestones.create=ๅปบ็ซ้็จ็ข
milestones.title=ๆจ้ก
milestones.desc=ๆ่ฟฐ
-milestones.due_date=ๆชๆญขๆฅๆ (้ธ็จ)
+milestones.due_date=ๅฐๆๆฅ๏ผ้ธ็จ๏ผ
milestones.clear=ๆธ
้ค
-milestones.invalid_due_date_format=ๆชๆญขๆฅๆ็ๆ ผๅผๅฟ
้ ็บใyyyy-mm-ddใใ
+milestones.invalid_due_date_format=ๅฐๆๆฅ็ๆ ผๅผๅฟ
้ ็บใyyyy-mm-ddใใ
milestones.create_success=ๅทฒๅปบ็ซ้็จ็ขใ%sใใ
milestones.edit=็ทจ่ผฏ้็จ็ข
milestones.edit_subheader=้็จ็ขๅฏ็จไพ็ต็นๅ้กๅ่ฟฝ่นค้ฒๅบฆใ
@@ -1838,7 +1903,7 @@ milestones.filter_sort.most_issues=ๅ้ก็ฑๅคๅฐๅฐ
milestones.filter_sort.least_issues=ๅ้ก็ฑๅฐๅฐๅค
-ext_wiki=ๅญๅๅค้จ Wiki
+ext_wiki=ๅค้จ Wiki
ext_wiki.desc=้ฃ็ตๅค้จ Wikiใ
wiki=Wiki
@@ -1855,9 +1920,9 @@ wiki.default_commit_message=้ๆผๆญคๆฌก้ ้ขไฟฎๆน็่ชชๆ(้ๅฟ
่ฆ)ใ
wiki.save_page=ๅฒๅญ้ ้ข
wiki.last_commit_info=%s ๆผ %s ไฟฎๆนไบๆญค้ ้ข
wiki.edit_page_button=ไฟฎๆน
-wiki.new_page_button=ๆฐ็้ ้ข
+wiki.new_page_button=ๆฐ้ ้ข
wiki.file_revision=้ ้ขไฟฎ่จ่จ้
-wiki.wiki_page_revisions=Wiki ้ ้ขไฟฎ่จ่จ้
+wiki.wiki_page_revisions=้ ้ขไฟฎ่จ่จ้
wiki.back_to_wiki=ๅๅฐ Wiki ้ ้ข
wiki.delete_page_button=ๅช้ค้ ้ข
wiki.delete_page_notice_1=ๅช้ค Wiki ้ ้ขใ%sใๅฐไธๅฏ้ๅใๆฏๅฆ็นผ็บ๏ผ
@@ -1879,10 +1944,10 @@ activity.period.yearly=1 ๅนด
activity.overview=ๆฆ่ฆฝ
activity.active_prs_count_1=%d ๅๅไฝต่ซๆฑ
activity.active_prs_count_n=%d ๅๅไฝต่ซๆฑ
-activity.merged_prs_count_1=ๅไฝต
-activity.merged_prs_count_n=ๅไฝต
-activity.opened_prs_count_1=ๆๅบๅไฝต่ซๆฑ
-activity.opened_prs_count_n=ๆๅบๅไฝต่ซๆฑ
+activity.merged_prs_count_1=ๅทฒๅไฝตๅไฝต่ซๆฑ
+activity.merged_prs_count_n=ๅทฒๅไฝตๅไฝต่ซๆฑ
+activity.opened_prs_count_1=ๅทฒๆๅบๅไฝต่ซๆฑ
+activity.opened_prs_count_n=ๅทฒๆๅบๅไฝต่ซๆฑ
activity.title.user_1=%d ไฝไฝฟ็จ่
activity.title.user_n=%d ไฝไฝฟ็จ่
activity.title.prs_1=%d ๅๅไฝต่ซๆฑ
@@ -1907,10 +1972,10 @@ activity.title.unresolved_conv_1=%d ๅๆช่งฃๆฑบ็ๅฐ่ฉฑ
activity.title.unresolved_conv_n=%d ๅๆช่งฃๆฑบ็ๅฐ่ฉฑ
activity.unresolved_conv_desc=้ไบๆ่ฟๆดๆน็ๅ้กๅๅไฝต่ซๆฑๅฐๆช่งฃๆฑบใ
activity.unresolved_conv_label=้ๆพ
-activity.title.releases_1=%d ๅ็ๆฌ
-activity.title.releases_n=%d ๅ็ๆฌ
+activity.title.releases_1=%d ๅ็ผ่ก
+activity.title.releases_n=%d ๅ็ผ่ก
activity.title.releases_published_by=%[2]s็ผๅธไบ %[1]s
-activity.published_release_label=ๅทฒ็ผๅธ
+activity.published_release_label=็ผ่ก
activity.no_git_activity=ๅจๆญคๆ้ๅ
งๆฒๆไปปไฝๆไบคๅๆ
ใ
activity.git_stats_exclude_merges=ไธ่จๅไฝต๏ผ
activity.git_stats_author_1=%d ไฝไฝ่
@@ -1965,28 +2030,28 @@ settings.mirror_settings.direction.pull=ๆๅ
settings.mirror_settings.direction.push=ๆจ้
settings.mirror_settings.last_update=ๆ่ฟๆดๆฐๆ้
settings.mirror_settings.push_mirror.none=ๆช่จญๅฎๆจ้้กๅ
-settings.mirror_settings.push_mirror.remote_url=Git ้ ็ซฏๅฒๅญๅบซ URL
+settings.mirror_settings.push_mirror.remote_url=Git ้ ็ซฏๅฒๅญๅบซ็ถฒๅ
settings.mirror_settings.push_mirror.add=ๆฐๅขๆจ้้กๅ
settings.sync_mirror=็ซๅณๅๆญฅ
settings.site=็ถฒ็ซ
-settings.update_settings=ๆดๆฐ่จญๅฎ
+settings.update_settings=ๅฒๅญ่จญๅฎ
settings.branches.update_default_branch=ๆดๆฐ้ ่จญๅๆฏ
-settings.branches.add_new_rule=ๅ ๅ
ฅๆฐ่ฆๅ
+settings.branches.add_new_rule=ๅขๅ ๆฐ่ฆๅ
settings.advanced_settings=้ฒ้่จญๅฎ
settings.wiki_desc=ๅ็จๅฒๅญๅบซ Wiki
settings.use_internal_wiki=ไฝฟ็จๅ
งๅปบ Wiki
settings.use_external_wiki=ไฝฟ็จๅค้จ Wiki
-settings.external_wiki_url=ๅค้จ Wiki ้ฃ็ต
+settings.external_wiki_url=ๅค้จ Wiki ็ถฒๅ
settings.external_wiki_url_error=ๅค้จ Wiki ็ถฒๅไธๆฏๆๆ็็ถฒๅใ
-settings.external_wiki_url_desc=้ปๆๅ้กๆจ็ฑคๆ๏ผไฝฟ็จ่
ๆ่ขซๅฐๅๅฐๅค้จ Wiki URLใ
+settings.external_wiki_url_desc=้ปๆ็พ็งๅ้ ๆ๏ผไฝฟ็จ่
ๆ่ขซ่ฝๅ่ณๅค้จ็พ็ง็ URLใ
settings.issues_desc=ๅ็จๅฒๅญๅบซๅ้ก่ฟฝ่นคๅจ
settings.use_internal_issue_tracker=ไฝฟ็จๅ
งๅปบๅ้ก่ฟฝ่นคๅจ
settings.use_external_issue_tracker=ไฝฟ็จๅค้จๅ้ก่ฟฝ่นคๅจ
-settings.external_tracker_url=ๅค้จๅ้ก่ฟฝ่นคๅจ URL
+settings.external_tracker_url=ๅค้จๅ้ก่ฟฝ่นคๅจ็ถฒๅ
settings.external_tracker_url_error=่ฉฒๅค้จๅ้ก่ฟฝ่นคๅจ URL ็กๆใ
-settings.external_tracker_url_desc=้ปๆๅ้ก้ ็ฑคๆ๏ผไฝฟ็จ่
ๆ่ขซๅฐๅ่ณๅค้จๅ้ก่ฟฝ่นคๅจ URLใ
-settings.tracker_url_format=ๅค้จๅ้ก่ฟฝ่นคๅจ็ URL ๆ ผๅผ
+settings.external_tracker_url_desc=้ปๆๅ้ก้ ็ฑคๆ๏ผไฝฟ็จ่
ๆ่ขซ่ฝๅ่ณๅค้จๅ้ก่ฟฝ่นคๅจ URLใ
+settings.tracker_url_format=ๅค้จๅ้ก่ฟฝ่นคๅจ็็ถฒๅๆ ผๅผ
settings.tracker_url_format_error=่ฉฒๅค้จๅ้ก่ฟฝ่นคๅจ URL ๆ ผๅผ็กๆใ
settings.tracker_issue_style=ๅค้จๅ้ก่ฟฝ่นคๅจ็็ทจ่ๆ ผๅผ
settings.tracker_issue_style.numeric=ๆธๅญ
@@ -2004,14 +2069,14 @@ settings.pulls.allow_rebase_update=ๅ็จ้้่ฎๅบๆดๆฐๅไฝต่ซๆฑๅๆฏ
settings.pulls.default_delete_branch_after_merge=้ ่จญๅจๅไฝตๅพๅช้คๅไฝต่ซๆฑๅๆฏ
settings.pulls.default_allow_edits_from_maintainers=้ ่จญๅ
่จฑ็ถญ่ญท่
้ฒ่ก็ทจ่ผฏ
settings.releases_desc=ๅ็จๅฒๅญๅบซ็ๆฌ็ผไฝ
-settings.packages_desc=ๅ็จๅฒๅญๅบซ่ป้ซ่จปๅไธญๅฟ
+settings.packages_desc=ๅ็จๅฒๅญๅบซ่ป้ซๅ
่จปๅไธญๅฟ
settings.projects_desc=ๅ็จๅฒๅญๅบซๅฐๆก
settings.actions_desc=ๅ็จๅฒๅญๅบซ Actions
settings.admin_settings=็ฎก็ๅก่จญๅฎ
-settings.admin_enable_health_check=ๅ็จๅฒๅญๅบซ็ๅฅๅบทๆชขๆฅ (git fsck)
+settings.admin_enable_health_check=ๅ็จๅฒๅญๅบซ็ๅฅๅบทๆชขๆฅ๏ผgit fsck๏ผ
settings.admin_code_indexer=็จๅผ็ขผ็ดขๅผๅจ
settings.admin_stats_indexer=็จๅผ็ขผ็ตฑ่จๆธๆ็ดขๅผๅจ
-settings.admin_indexer_commit_sha=ๆๅพ็ดขๅผ็ SHA
+settings.admin_indexer_commit_sha=ๆๅพ็ดขๅผ็ๆไบค
settings.admin_indexer_unindexed=ๆช็ดขๅผ
settings.reindex_button=ๅ ๅ
ฅๅฐ้ๆฐ็ดขๅผไฝๅ
settings.reindex_requested=ๅทฒ่ซๆฑ้ๆฐ็ดขๅผ
@@ -2044,8 +2109,8 @@ settings.transfer_perform=้ฒ่ก่ฝ็งป
settings.transfer_started=ๆญคๅฒๅญๅบซๅทฒ่ขซๆจ่จ็บๅพ
่ฝ็งปไธๆญฃๅจ็ญๅพ
ใ%sใ็็ขบ่ช
settings.transfer_succeed=ๅทฒ่ฝ็งปๅฒๅญๅบซใ
settings.signing_settings=็ฐฝ็ฝฒ้ฉ่ญ่จญๅฎ
-settings.trust_model=็ฐฝ็ฝฒไฟกไปปๆจกๅผ
-settings.trust_model.default=้ ่จญไฟกไปปๆจกๅผ
+settings.trust_model=็ฐฝ็ฝฒไฟกไปปๆจกๅ
+settings.trust_model.default=้ ่จญไฟกไปปๆจกๅ
settings.trust_model.default.desc=ไฝฟ็จๆญค Forgejo ็้ ่จญๅฒๅญๅบซไฟกไปปๆจกๅผใ
settings.trust_model.collaborator=ๅไฝ่
settings.trust_model.collaborator.long=ๅไฝ่
๏ผไฟกไปปๅไฝ่
็็ฐฝ็ฝฒ
@@ -2061,7 +2126,7 @@ settings.wiki_delete_desc=ๅช้คๅฒๅญๅบซ Wiki ่ณๆๆฏๆฐธไน
็ไธไธๅฏ้ๅ
settings.wiki_delete_notices_1=- ้ๅฐๆๆฐธไน
ๅช้ค่ๅ็จ %s ็ๅฒๅญๅบซ Wikiใ
settings.confirm_wiki_delete=ๅช้ค Wiki ่ณๆ
settings.wiki_deletion_success=ๅทฒๅช้คๅฒๅญๅบซ็ Wiki ่ณๆใ
-settings.delete=ๅช้คๆฌๅฒๅญๅบซ
+settings.delete=ๅช้คๆญคๅฒๅญๅบซ
settings.delete_desc=ๅช้คๅฒๅญๅบซๆฏๆฐธไน
็ไธไธๅฏ้ๅใ
settings.delete_notices_1=- ๆญคๅไฝไธๅฏ ้ๅใ
settings.delete_notices_2=- ๆญคๆไฝๅฐๆฐธไน
ๅช้ค %s ๅฒๅญๅบซ๏ผๅ
ๆฌ็จๅผ็ขผใๅ้กใ็่จใWiki ่ณๆๅๅไฝ่
่จญๅฎใ
@@ -2090,13 +2155,13 @@ settings.search_team=ๆๅฐๅ้...
settings.change_team_permission_tip=ๅ้ๆฌ้ๅช่ฝๆผๅ้่จญๅฎ้ ้ขไฟฎๆน๏ผไธ่ฝ้ๅฐๅฒๅญๅบซๅๅฅ่ชฟๆด
settings.delete_team_tip=ๆญคๅ้ๅฏๅญๅๆๆๅฒๅญๅบซ๏ผ็กๆณ็งป้ค
settings.remove_team_success=ๅทฒ็งป้คๅ้ๅญๅๅฒๅญๅบซ็ๆฌ้ใ
-settings.add_webhook=ๅปบ็ซ Webhook
+settings.add_webhook=ๅขๅ Webhook
settings.add_webhook.invalid_channel_name=Webhook ้ ป้ๅ็จฑไธๅฏ็็ฝ๏ผไธไธ่ฝๅ
ๆ # ๅญ่ใ
settings.hooks_desc=็ถ่งธ็ผๆไบ Forgejo ไบไปถๆ๏ผWebhook ๆ่ชๅ็ผๅบ HTTP POST ่ซๆฑๅฐๆๅฎ็ไผบๆๅจใๅจ Webhook ๆๅ ้ฑ่ฎๆดๅคๅ
งๅฎนใ
settings.webhook_deletion=็งป้ค Webhook
settings.webhook_deletion_desc=็งป้ค Webhook ๅฐๅช้คๅฎ็่จญๅฎๅๅณ้่จ้๏ผๆฏๅฆ็นผ็บ๏ผ
settings.webhook_deletion_success=Webhook ๅทฒ็งป้คใ
-settings.webhook.test_delivery=ๅณ้ๆธฌ่ฉฆ่ณๆ
+settings.webhook.test_delivery=ๆธฌ่ฉฆไบคไป
settings.webhook.test_delivery_desc=ไฝฟ็จๅไบไปถๆธฌ่ฉฆๆญค Webhookใ
settings.webhook.request=่ซๆฑ
settings.webhook.response=ๅๆ
@@ -2113,7 +2178,7 @@ settings.update_githook=ๆดๆฐ Hook
settings.add_webhook_desc=Forgejo ๆ็ผ้ๅซๆๆๅฎ Content Type ็ POST
่ซๆฑๅฐ็ฎๆจ URLใ ๅจ Webhook ๆๅ ้ฑ่ฎๆดๅคๅ
งๅฎนใ
settings.payload_url=็ฎๆจ URL
settings.http_method=HTTP ่ซๆฑๆนๆณ
-settings.content_type=POST Content Type
+settings.content_type=POST ๅ
งๅฎน้กๅ
settings.secret=Secret
settings.slack_username=ๆๅๅ็จฑ
settings.slack_icon_url=ๅ็คบ URL
@@ -2140,35 +2205,35 @@ settings.event_push_desc=ๆจ้ๅฐๅฒๅญๅบซใ
settings.event_repository=ๅฒๅญๅบซ
settings.event_repository_desc=ๅปบ็ซๆๅช้คๅฒๅญๅบซใ
settings.event_header_issue=ๅ้กไบไปถ
-settings.event_issues=ๅ้ก
+settings.event_issues=ไฟฎๆน
settings.event_issues_desc=ๅปบ็ซใ็ทจ่ผฏใ้้ๅ้ๆฐ้ๆพๅ้กใ
-settings.event_issue_assign=ๆๆดพๅ้ก
+settings.event_issue_assign=ๆๆดพ
settings.event_issue_assign_desc=ๆๆดพๆๅๆถๆๆดพๅ้กใ
settings.event_issue_label=ๆจ็ฑค
-settings.event_issue_label_desc=ๆดๆฐๆๆธ
้คๅ้กๆจ็ฑคใ
+settings.event_issue_label_desc=ๅ้กๆจ็ฑคๅทฒๆฐๅขๆๅทฒๅช้คใ
settings.event_issue_milestone=้็จ็ข
-settings.event_issue_milestone_desc=่จญๅฎๆๅๆถ่จญๅฎๅ้ก้็จ็ขใ
-settings.event_issue_comment=ๅ้ก็่จ
+settings.event_issue_milestone_desc=้็จ็ขๅทฒๆฐๅขใๅทฒ็งป้คๆๅทฒไฟฎๆนใ
+settings.event_issue_comment=่ฉ่จป
settings.event_issue_comment_desc=ๅทฒ็ถๅปบ็ซใ็ทจ่ผฏๆๅช้ค็ๅ้ก็่จใ
settings.event_header_pull_request=ๅไฝต่ซๆฑไบไปถ
-settings.event_pull_request=ๅไฝต่ซๆฑ
+settings.event_pull_request=ไฟฎๆน
settings.event_pull_request_desc=ๅปบ็ซใ็ทจ่ผฏใ้้ๅ้ๆฐ้ๆพๅไฝต่ซๆฑใ
-settings.event_pull_request_assign=ๆๆดพๅไฝต่ซๆฑ
+settings.event_pull_request_assign=ๆๆดพ
settings.event_pull_request_assign_desc=ๆๆดพๆๅๆถๆๆดพๅไฝต่ซๆฑใ
-settings.event_pull_request_label=ๅไฝต่ซๆฑๆจ็ฑค
+settings.event_pull_request_label=ๆจ็ฑค
settings.event_pull_request_label_desc=ๆดๆฐๆๆธ
้คๅไฝต่ซๆฑๆจ็ฑคใ
-settings.event_pull_request_milestone=ๅไฝต่ซๆฑ้็จ็ข
-settings.event_pull_request_milestone_desc=่จญๅฎๆๅๆถ่จญๅฎๅไฝต่ซๆฑ้็จ็ขใ
-settings.event_pull_request_comment=ๅไฝต่ซๆฑ็่จ
+settings.event_pull_request_milestone=้็จ็ข
+settings.event_pull_request_milestone_desc=้็จ็ขๅทฒๆฐๅขใๅทฒ็งป้คๆๅทฒไฟฎๆนใ
+settings.event_pull_request_comment=่ฉ่จป
settings.event_pull_request_comment_desc=ๅปบ็ซใ็ทจ่ผฏๆๅช้คๅไฝต่ซๆฑ็็่จใ
-settings.event_pull_request_review=ๅไฝต่ซๆฑๅฏฉๆ ธ
+settings.event_pull_request_review=ๅฏฉๆ ธ
settings.event_pull_request_review_desc=ๆ ธๅใ้ๅๆๆๅบๅฏฉๆ ธ็่จใ
-settings.event_pull_request_sync=ๅไฝต่ซๆฑๅๆญฅ
+settings.event_pull_request_sync=ๅๆญฅ
settings.event_pull_request_sync_desc=ๅไฝต่ซๆฑๅๆญฅใ
settings.event_package=่ป้ซๅ
settings.event_package_desc=ๅทฒๅจๅฒๅญๅบซไธญๅปบ็ซๆๅช้ค่ป้ซๅ
ใ
settings.branch_filter=ๅๆฏ็ฏฉ้ธ
-settings.branch_filter_desc=ๆจ้ใๅปบ็ซๅๆฏใๅช้คๅๆฏไบไปถ็็ฝๅๅฎ๏ผ่ซไฝฟ็จ glob ๆฏๅฐๅผๆจฃใๅฆๆ็็ฝๆ่ผธๅ
ฅ*
๏ผๆๆๅๆฏ็ไบไปถ้ฝๆ่ขซๅๅ ฑใ่ชๆณๅ่ฆ github.com/gobwas/glob ใ็ฏไพ๏ผmaster
, {master,release*}
ใ
+settings.branch_filter_desc=ๆจ้ใๅปบ็ซๅๆฏใๅช้คๅๆฏไบไปถ็็ฝๅๅฎ๏ผ่ซไฝฟ็จ glob ๆฏๅฐๅผๆจฃใๅฆๆ็็ฝๆ่ผธๅ
ฅ*
๏ผๆๆๅๆฏ็ไบไปถ้ฝๆ่ขซๅๅ ฑใ่ชๆณๅ่ฆ %[2]s ใ็ฏไพ๏ผmaster
, {master,release*}
ใ
settings.authorization_header=Authorization ๆจ้ ญ
settings.authorization_header_desc=ๅญๅจๆๅฐๅฐๅ
ๅซๆญค Authorization ๆจ้ ญๅจ่ซๆฑไธญใไพ: %sใ
settings.active=ๅ็จ
@@ -2177,7 +2242,7 @@ settings.add_hook_success=Webhook ๆฐๅขๆๅใ
settings.update_webhook=ๆดๆฐ Webhook
settings.update_hook_success=ๅทฒๆๅๆดๆฐ Webhook ใ
settings.delete_webhook=็งป้ค Webhook
-settings.recent_deliveries=ๆ่ฟๅณ้่จ้
+settings.recent_deliveries=ๆ่ฟไบคไป
settings.hook_type=Hook ้กๅ
settings.slack_token=็ฌฆ่จ
settings.slack_domain=ๅๅ
@@ -2211,7 +2276,7 @@ settings.deploy_key_content=ๅ
งๅฎน
settings.key_been_used=ๅ
ทๆ็ธๅๅ
งๅฎน็้จ็ฝฒ้้ฐๅทฒๅจไฝฟ็จไธญใ
settings.key_name_used=ๅทฒๆ็ธๅๅ็จฑ็้จ็ฝฒ้้ฐใ
settings.add_key_success=ๅทฒๆฐๅข้จ็ฝฒ้้ฐใ%sใใ
-settings.deploy_key_deletion=ๅช้ค้จ็ฝฒ้้ฐ
+settings.deploy_key_deletion=็งป้ค้จ็ฝฒ้้ฐ
settings.deploy_key_deletion_desc=็งป้ค้จ็ฝฒ้้ฐๅฐๆ็ตๅฎๅญๅๆญคๅฒๅญๅบซใๆฏๅฆ็นผ็บ๏ผ
settings.deploy_key_deletion_success=้จ็ฝฒ้้ฐๅทฒ็งป้คใ
settings.branches=ๅๆฏ
@@ -2221,7 +2286,7 @@ settings.protected_branch.delete_rule=ๅช้ค่ฆๅ
settings.protected_branch_can_push=ๅ
่จฑๆจ้๏ผ
settings.protected_branch_can_push_yes=ไฝ ๅฏไปฅๆจ้
settings.protected_branch_can_push_no=ไฝ ไธ่ฝๆจ้
-settings.branch_protection=%s ็ๅๆฏไฟ่ญท
+settings.branch_protection=ๅๆฏใ%s ใ็ไฟ่ญท่ฆๅ
settings.protect_this_branch=ๅ็จๅๆฏไฟ่ญท
settings.protect_this_branch_desc=้ฒๆญขๅช้คๅๆฏ๏ผไธฆ้ๅถ Git ๆจ้่ๅไฝตๅฐๅๆฏใ
settings.protect_disable_push=ๅ็จๆจ้
@@ -2233,35 +2298,35 @@ settings.protect_enable_merge_desc=ไปปไฝๆๅฏซๅ
ฅๆฌ้็ไบบ้ฝๅฏๅฐๅไฝต่ซ
settings.protect_whitelist_committers=ไฝฟ็จ็ฝๅๅฎๆง็ฎกๆจ้
settings.protect_whitelist_committers_desc=ๅ
ๅ
่จฑ็ฝๅๅฎๅ
ง็ไฝฟ็จ่
ๆๅ้ๆจ้่ณ่ฉฒๅๆฏ(ไฝไธๅฏไฝฟ็จforce push)ใ
settings.protect_whitelist_deploy_keys=ๅฐๆๆๅฏซๅ
ฅๆฌ้็้จ็ฝฒ้้ฐๅ ๅ
ฅ็ฝๅๅฎใ
-settings.protect_whitelist_users=ๅ
่จฑๆจ้็ไฝฟ็จ่
๏ผ
+settings.protect_whitelist_users=ๅ
่จฑๆจ้็ไฝฟ็จ่
settings.protect_whitelist_search_users=ๆๅฐไฝฟ็จ่
...
-settings.protect_whitelist_teams=ๅ
่จฑๆจ้็ๅ้๏ผ
+settings.protect_whitelist_teams=ๅ
่จฑๆจ้็ๅ้
settings.protect_whitelist_search_teams=ๆๅฐๅ้...
settings.protect_merge_whitelist_committers=ๅ็จๅไฝต็ฝๅๅฎ
settings.protect_merge_whitelist_committers_desc=ๅ
ๅ
่จฑ็ฝๅๅฎๅ
ง็ไฝฟ็จ่
ๆๅ้ๅฐๅไฝต่ซๆฑๅไฝต่ณ่ฉฒๅๆฏใ
-settings.protect_merge_whitelist_users=ๅ
่จฑๅไฝต็ไฝฟ็จ่
๏ผ
-settings.protect_merge_whitelist_teams=ๅ
่จฑๅไฝต็ๅ้๏ผ
+settings.protect_merge_whitelist_users=ๅ
่จฑๅไฝต็ไฝฟ็จ่
+settings.protect_merge_whitelist_teams=ๅ
่จฑๅไฝต็ๅ้
settings.protect_check_status_contexts=ๅ็จ็ๆ
ๆชขๆฅ
settings.protect_check_status_contexts_desc=ๅไฝตๅๅฟ
้ ๅ
้้็ๆ
ๆชขๆฅใ้ธๆๅไฝตๅๅฟ
้ ้้็ๆชขๆฅใๅ็จๆ๏ผๅฟ
้ ๅ
ๅฐๆไบคๆจ้ๅฐๅฆไธๅๅๆฏ๏ผ้้็ๆ
ๆชขๆฅๅพๅๅไฝตๆ็ดๆฅๆจ้ๅฐ็ฌฆๅ่ฆๅ็ๅๆฏใๅฆๆๆช้ธๆไปปไฝ้
็ฎ๏ผๆไธๅๆไบคๅฟ
ๅฐๆๅ้้็ๆ
ๆชขๆฅใ
settings.protect_check_status_contexts_list=ๆญคๅฒๅญๅบซไธ้ฑๅ
งๆพ้ฒ่ก้็ๆ
ๆชขๆฅ
-settings.protect_required_approvals=้่ฆ็ๆ ธๅฏๆธ้๏ผ
+settings.protect_required_approvals=้่ฆ็ๆ ธๅฏๆธ้
settings.protect_required_approvals_desc=ๅชๆๅจ็ฒๅพ่ถณๅค ๆธ้็ๆ ธๅฏๅพๆ่ฝ้ฒ่กๅไฝตใ
settings.protect_approvals_whitelist_enabled=ไฝฟ็จ็ฝๅๅฎๆง็ฎกๅฏฉๆ ธไบบๅก่ๅ้
settings.protect_approvals_whitelist_enabled_desc=ๅชๆ็ฝๅๅฎๅ
ง็ไฝฟ็จ่
่ๅ้ๆ่ขซ่จๅ
ฅ้่ฆ็ๆ ธๅฏๆธ้ใๆชไฝฟ็จ็ฝๅๅฎๆ๏ผๅฐ่จ็ฎไปปไฝๆๅฏซๅ
ฅๆฌ้ไนไบบ็ๆ ธๅฏใ
-settings.protect_approvals_whitelist_users=ๅฏฉๆ ธ่
็ฝๅๅฎ๏ผ
-settings.protect_approvals_whitelist_teams=ๅฏฉๆ ธๅ้็ฝๅๅฎ๏ผ
+settings.protect_approvals_whitelist_users=ๅ
่จฑ็ๅฏฉๆ ธ่
+settings.protect_approvals_whitelist_teams=ๅ
่จฑ็ๅฏฉๆ ธๅ้
settings.dismiss_stale_approvals=ๆจๆฃ้ๆ็ๆ ธๅฏ
settings.dismiss_stale_approvals_desc=็ถๆฐ็ๆไบคๆไฟฎๆนๅฐๅไฝต่ซๆฑ็ๅ
งๅฎน๏ผไธฆ่ขซๆจ้ๅฐๆญคๅๆฏๆ๏ผๅฐๆจๆฃ่็ๆ ธๅฏใ
settings.require_signed_commits=ๅ
ๆฅๅ็ถ็ฐฝ็ฝฒ็ๆไบค
settings.require_signed_commits_desc=ๆ็ตๆช็ถ็ฐฝ็ฝฒๆๆช็ถ้ฉ่ญ็ๆไบคๆจ้ๅฐๆญคๅๆฏใ
settings.protect_branch_name_pattern=ๅไฟ่ญท็ๅๆฏๅ็จฑๅผๆจฃ
-settings.protect_protected_file_patterns=ๅไฟ่ญท็ๆชๆกๅผๆจฃ (ไปฅๅ่ๅ้ใ;ใ)๏ผ
-settings.protect_protected_file_patterns_desc=ๅณไพฟไฝฟ็จ่
ๆๆฌ้ๆฐๅขใไฟฎๆนใๅช้คๆญคๅๆฏ็ๆชๆก๏ผไปไธๅ
่จฑ็ดๆฅไฟฎๆนๅไฟ่ญท็ๆชๆกใๅฏไปฅ็จๅๅฝขๅ่ใ;ใๅ้ๅคๅๅผๆจฃใ่ซๆผ github.com/gobwas/glob ๆไปถๆฅ็ๆจกๅผๆ ผๅผใ็ฏไพ: .drone.yml
, /docs/**/*.txt
ใ
-settings.protect_unprotected_file_patterns=ๆชๅไฟ่ญท็ๆชๆกๆจกๅผ (ไปฅๅ่ๅ้ใ;ใ):
-settings.protect_unprotected_file_patterns_desc=็ถไฝฟ็จ่
ๆๅฏซๅ
ฅๆฌ้ๆ๏ผๅฏ็น้ๆจ้้ๅถ๏ผ็ดๆฅไฟฎๆนๆชๅไฟ่ญท็ๆชๆกใๅฏไปฅ็จๅๅฝขๅ่ใ;ใๅ้ๅคๅๆจกๅผใ่ซๆผ github.com/gobwas/glob ๆไปถๆฅ็ๆจกๅผๆ ผๅผใ็ฏไพ: .drone.yml
, /docs/**/*.txt
ใ
+settings.protect_protected_file_patterns=ๅไฟ่ญทๆชๆก็ๅผๆจฃ๏ผไปฅๅๅฝขๅ่ๅ้ใ;ใ๏ผ
+settings.protect_protected_file_patterns_desc=ๅณไพฟไฝฟ็จ่
ๆๆฌ้ๆฐๅขใไฟฎๆนใๅช้คๆญคๅๆฏ็ๆชๆก๏ผไปไธๅ
่จฑ็ดๆฅไฟฎๆนๅไฟ่ญท็ๆชๆกใๅฏไปฅ็จๅๅฝขๅ่ใ;ใๅ้ๅคๅๅผๆจฃใ่ซๆผ %[2]s ๆไปถๆฅ็ๆจกๅผๆ ผๅผใ็ฏไพ: .drone.yml
, /docs/**/*.txt
ใ
+settings.protect_unprotected_file_patterns=ๆชๅไฟ่ญทๆชๆก็ๅผๆจฃ๏ผไปฅๅๅฝขๅ่ๅ้ใ;ใ๏ผ
+settings.protect_unprotected_file_patterns_desc=็ถไฝฟ็จ่
ๆๅฏซๅ
ฅๆฌ้ๆ๏ผๅฏ็น้ๆจ้้ๅถ๏ผ็ดๆฅไฟฎๆนๆชๅไฟ่ญท็ๆชๆกใๅฏไปฅ็จๅๅฝขๅ่ใ;ใๅ้ๅคๅๆจกๅผใ่ซๆผ %[2]s ๆไปถๆฅ็ๆจกๅผๆ ผๅผใ็ฏไพ: .drone.yml
, /docs/**/*.txt
ใ
settings.add_protected_branch=ๅ็จไฟ่ญท
settings.delete_protected_branch=ๅ็จไฟ่ญท
-settings.protected_branch_deletion=ๅ็จๅๆฏไฟ่ญท
+settings.protected_branch_deletion=ๅช้คๅๆฏไฟ่ญท
settings.protected_branch_deletion_desc=ๅ็จๅๆฏไฟ่ญทๅฐๅ
่จฑๆๅฏซๅ
ฅๆฌ้็ไฝฟ็จ่
ๆจ้่ณ่ฉฒๅๆฏ๏ผๆฏๅฆ็นผ็บ๏ผ
settings.block_rejected_reviews=ๆ้ๅ็ๅฏฉๆ ธๆ้ปๆๅไฝต
settings.block_rejected_reviews_desc=ๅฆๆๅฎๆนๅฏฉๆ ธไบบๅกๆๅบ่ฎๆด่ซๆฑ๏ผๅณไฝฟๆ่ถณๅค ็ๆ ธๅฏไนไธๅ
่จฑ้ฒ่กๅไฝตใ
@@ -2280,12 +2345,12 @@ settings.protected_branch_duplicate_rule_name=่ฆๅๅ็จฑๅทฒๅญๅจ
settings.protected_branch_required_approvals_min=้่ฆ็ๆ ธๅฏๆธ้ไธ่ฝ็บ่ฒ ๆธใ
settings.tags=ๆจ็ฑค
settings.tags.protection=ๆจ็ฑคไฟ่ญท
-settings.tags.protection.pattern=ๆจ็ฑคๆ ผๅผ
+settings.tags.protection.pattern=ๆจ็ฑคๅผๆจฃ
settings.tags.protection.allowed=ๅ
่จฑ็
settings.tags.protection.allowed.users=ๅ
่จฑ็ไฝฟ็จ่
settings.tags.protection.allowed.teams=ๅ
่จฑ็ๅ้
-settings.tags.protection.allowed.noone=็ก
-settings.tags.protection.create=ไฟ่ญทๆจ็ฑค
+settings.tags.protection.allowed.noone=ๆฒๆไบบ
+settings.tags.protection.create=ๆฐๅข่ฆๅ
settings.tags.protection.none=ๆฒๆๅไฟ่ญท็ๆจ็ฑคใ
settings.bot_token=Bot ็ฌฆ่จ
settings.chat_id=Chat ID
@@ -2293,7 +2358,7 @@ settings.matrix.homeserver_url=Homeserver ็ถฒๅ
settings.matrix.room_id=่ๅคฉๅฎค ID
settings.matrix.message_type=่จๆฏ้กๅ
settings.archive.button=ๅฐๅญๅฒๅญๅบซ
-settings.archive.header=ๅฐๅญๆฌๅฒๅญๅบซ
+settings.archive.header=ๅฐๅญๆญคๅฒๅญๅบซ
settings.archive.success=ๆญคๅฒๅญๅบซๅทฒ่ขซๅฐๅญใ
settings.archive.error=ๅ่ฉฆๅฐๅญๅฒๅญๅบซๆ็ผ็้ฏ่ชคใๆฅ็ๆฅ่ชๆชไปฅ็ฒๅพๆดๅค่ณ่จใ
settings.archive.error_ismirror=็กๆณๅฐๅญ้กๅๅฒๅญๅบซใ
@@ -2307,19 +2372,19 @@ settings.lfs_findcommits=ๅฐๆพๆไบค
settings.lfs_lfs_file_no_commits=ๆพไธๅฐๅๆญค LFS ๆชๆก้่ฏ็ๆไบค
settings.lfs_noattribute=ๆญค่ทฏๅพๅจ้ ่จญๅๆฏไธญๆฒๆๅฏ้ๅฎ็ๅฑฌๆง
settings.lfs_delete=ๅช้ค OID ็บ %s ็ LFS ๆชๆก
-settings.lfs_delete_warning=ๅช้ค LFS ๆชๆกๅฏ่ฝๆ้ ๆ Checkout ๆ็ผ็ใ็ฉไปถไธๅญๅจใ็้ฏ่ชค๏ผๆจ็ขบๅฎๅ๏ผ
+settings.lfs_delete_warning=ๅช้ค LFS ๆชๆกๅฏ่ฝๆๅฐ่ด็ฐฝๅบๆ็ผ็ใ็ฉไปถไธๅญๅจใ็้ฏ่ชคใไฝ ็ขบๅฎๅ๏ผ
settings.lfs_findpointerfiles=ๅฐๆพๆๆจๆชๆก
settings.lfs_locks=้ๅฎ
settings.lfs_invalid_locking_path=็กๆ็่ทฏๅพ๏ผ %s
settings.lfs_invalid_lock_directory=็กๆณ้ๅฎ็ฎ้: %s
settings.lfs_lock_already_exists=้ๅฎๅทฒๅญๅจ๏ผ%s
settings.lfs_lock=้ๅฎ
-settings.lfs_lock_path=่ฆ้ๅฎ็ๆชๆก่ทฏๅพ...
+settings.lfs_lock_path=่ฆ้ๅฎ็ๆชๆก่ทฏๅพโฆ
settings.lfs_locks_no_locks=ๆฒๆ้ๅฎ
settings.lfs_lock_file_no_exist=ๅทฒ้ๅฎ็ๆชๆกไธๅญๅจๆผ้ ่จญๅๆฏ
settings.lfs_force_unlock=ๅผทๅถ่งฃ้
settings.lfs_pointers.found=ๆพๅฐ %d ๅ blob ๆๆจ - %d ๅๅทฒ้่ฏ, %d ๅๆช้่ฏ (%d ๅๅพๅญๆพๅ้บๅคฑ)
-settings.lfs_pointers.sha=Blob SHA
+settings.lfs_pointers.sha=Blob ้ๆนๅผ
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=ๅจๅฒๅญๅบซไธญ
settings.lfs_pointers.exists=ๅญๅจๆผๅญๆพๅ
@@ -2340,7 +2405,7 @@ diff.data_not_available=ๆฒๆๅ
งๅฎนๆฏ่ผๅฏไปฅไฝฟ็จ
diff.options_button=ๅทฎ็ฐ้ธ้
diff.show_diff_stats=้กฏ็คบ็ตฑ่จ่ณๆ
diff.download_patch=ไธ่ผ่ฃ็ถดๆชๆก
-diff.download_diff=ไธ่ผๅทฎ็ฐๆช
+diff.download_diff=ไธ่ผๅทฎ็ฐๆชๆก
diff.show_split_view=ๅๅฒๆชข่ฆ
diff.show_unified_view=ๅไฝตๆชข่ฆ
diff.whitespace_button=็ฉบ็ฝ็ฌฆ่
@@ -2352,7 +2417,7 @@ diff.stats_desc=ๅ
ฑๆ %d ๅๆชๆก่ขซๆดๆน ๏ผๅ
ๆฌ
diff.stats_desc_file=่ฎๆด %d ่ก๏ผๆฐๅข %d ่ก๏ผๅ ้ค %d ่ก
diff.bin=ไบ้ฒๅถ
diff.bin_not_shown=ๆช้กฏ็คบไบ้ฒไฝๆชๆกใ
-diff.view_file=ๆฅ็ๆไปถ
+diff.view_file=ๆชข่ฆๆชๆก
diff.file_before=ไนๅ
diff.file_after=ไนๅพ
diff.file_image_width=ๅฏฌๅบฆ
@@ -2366,12 +2431,12 @@ diff.load=่ผๅ
ฅๅทฎ็ฐ
diff.generated=่ชๅ็ข็็
diff.vendored=vendored
diff.comment.placeholder=็่จ
-diff.comment.markdown_info=ๆฏๆด markdown ๆ ผๅผใ
+diff.comment.markdown_info=ๆฏๆด Markdown ๆ ผๅผใ
diff.comment.add_single_comment=ๅ ๅ
ฅๅฎ็จ็็่จ
diff.comment.add_review_comment=ๆฐๅข็่จ
diff.comment.start_review=้ๅงๅฏฉๆ ธ
diff.comment.reply=ๅ่ฆ
-diff.review=ๅฏฉๆ ธ
+diff.review=ๅฎๆๅฏฉๆ ธ
diff.review.header=้ๅบๅฏฉๆ ธ
diff.review.placeholder=ๅฏฉๆ ธๆ่ฆ
diff.review.comment=็่จ
@@ -2381,7 +2446,7 @@ diff.review.reject=่ซๆฑ่ฎๆด
diff.review.self_approve=ๅไฝต่ซๆฑ็ไฝ่
ไธ่ฝๆ ธๅฏ่ชๅทฑ็ๅไฝต่ซๆฑ
diff.committed_by=ๆไบค่
diff.protected=ๅไฟ่ญท
-diff.image.side_by_side=ไธฆๅ
+diff.image.side_by_side=ไธฆๆ
diff.image.swipe=ๆปๅ
diff.image.overlay=้็
diff.has_escaped=้ไธ่กๆ้ฑ่็ Unicode ๅญๅ
@@ -2392,9 +2457,9 @@ releases.desc=่ฟฝ่นคๅฐๆก็ๆฌๅๆชๆกไธ่ผใ
release.releases=็ๆฌ็ผๅธ
release.detail=็ๆฌ่ฉณๆ
release.tags=ๆจ็ฑค
-release.new_release=็ผๅธๆฐ็ๆฌ
+release.new_release=ๆฐ็ผ่ก
release.draft=่็จฟ
-release.prerelease=้ ็ผๅธ็ๆฌ
+release.prerelease=้ ็ผ่ก
release.stable=็ฉฉๅฎ
release.compare=ๆฏ่ผ
release.edit=็ทจ่ผฏ
@@ -2413,12 +2478,12 @@ release.title_empty=ๆจ้กไธๅฏ็บ็ฉบใ
release.prerelease_desc=ๆจ่จ็บ Pre-Release
release.prerelease_helper=ๆจ่จๆญค็ๆฌไธ้ฉๅ็็ขไฝฟ็จใ
release.cancel=ๅๆถ
-release.publish=็ผๅธ็ๆฌ
+release.publish=็ผไฝ็ผ่ก
release.save_draft=ๅฒๅญ่็จฟ
-release.edit_release=ๆดๆฐ็ผๅธ
-release.delete_release=ๅช้ค็ผๅธ
+release.edit_release=ๆดๆฐ็ผ่ก
+release.delete_release=ๅช้ค็ผ่ก
release.delete_tag=ๅช้คๆจ็ฑค
-release.deletion=ๅช้ค็ผๅธ
+release.deletion=ๅช้ค็ผ่ก
release.deletion_success=ๅทฒๅช้คๆญค็ๆฌ็ผๅธใ
release.deletion_tag_desc=ๅณๅฐๅพๅฒๅญๅบซ็งป้คๆญคๆจ็ฑคใๅฒๅญๅบซๅ
งๅฎนๅๆญทๅฒๅฐไฟๆไธ่ฎ๏ผๆฏๅฆ็นผ็บ๏ผ
release.deletion_tag_success=ๅทฒๅช้คๆญคๆจ็ฑคใ
@@ -2429,7 +2494,7 @@ release.tag_already_exist=ๆญคๆจ็ฑคๅ็จฑๅทฒๅญๅจใ
release.downloads=ไธ่ผ้ไปถ
release.download_count=ไธ่ผๆฌกๆธ๏ผ%s
release.add_tag_msg=ไฝฟ็จๆญค็ๆฌ็ๆจ้กๅๅ
งๅฎนไฝ็บๆจ็ฑค่จๆฏใ
-release.add_tag=ๅชๅปบ็ซๆจ็ฑค
+release.add_tag=ๅปบ็ซๆจ็ฑค
release.releases_for=%s ็็ๆฌ็ผไฝ
release.tags_for=%s ็ๆจ็ฑค
@@ -2441,7 +2506,7 @@ branch.delete_html=ๅช้คๅๆฏ
branch.deletion_success=ๅทฒๅช้คๅๆฏใ%sใใ
branch.deletion_failed=ๅช้คๅๆฏใ%sใๅคฑๆใ
branch.delete_branch_has_new_commits=ๅ ็บๅไฝตๅพๅทฒๅ ๅ
ฅไบๆฐ็ๆไบค๏ผใ%sใๅๆฏ็กๆณ่ขซๅช้คใ
-branch.create_branch=ๅปบ็ซๅๆฏ %s
+branch.create_branch=ๅปบ็ซๅๆฏ %s
branch.create_from=ๅพใ%sใ
branch.create_success=ๅทฒๅปบ็ซๅๆฏใ%sใใ
branch.branch_already_exists=ๆญคๅฒๅญๅบซๅทฒๆๅ็บใ%sใ็ๅๆฏใ
@@ -2463,7 +2528,7 @@ branch.new_branch=ๅปบ็ซๆฐๅๆฏ
branch.new_branch_from=ๅพใ%sใๅปบ็ซๆฐๅๆฏ
branch.renamed=ๅๆฏ %s ่ขซ้ๆฐๅฝๅ็บ %sใ
-tag.create_tag=ๅปบ็ซๆจ็ฑค %s
+tag.create_tag=ๅปบ็ซๆจ็ฑค %s
tag.create_tag_operation=ๅปบ็ซๆจ็ฑค
tag.confirm_create_tag=ๅปบ็ซๆจ็ฑค
tag.create_tag_from=ๅพใ%sใๅปบ็ซๆฐๆจ็ฑค
@@ -2474,7 +2539,7 @@ topic.manage_topics=็ฎก็ไธป้ก
topic.done=ๅฎๆ
topic.count_prompt=ๆจๆๅค่ฝ้ธๆ 25 ๅไธป้ก
-find_file.go_to_file=็งป่ณๆชๆก
+find_file.go_to_file=ๅฐๆพๆชๆก
find_file.no_matching=ๆพไธๅฐ็ฌฆๅ็ๆชๆก
error.csv.too_large=็กๆณๆธฒๆๆญคๆชๆก๏ผๅ ็บๅฎๅคชๅคงไบใ
@@ -2487,8 +2552,8 @@ mirror_sync = ๅทฒๅๆญฅ
commit.contained_in_default_branch = ้ๅๆไบคๆฏ้ ่จญๅๆฏ็ไธ้จๅ
editor.invalid_commit_mail = ็จๆผๅปบ็ซๆไบค็ไฟก็ฎฑ็กๆใ
admin.update_flags = ๆดๆฐๆๆจ
-admin.failed_to_replace_flags = ๅฒๅญๅบซๆๆจๆดๆฐๅคฑๆ
-admin.flags_replaced = ๅฒๅญๅบซๆๆจๅทฒ่ขซๆดๆ
+admin.failed_to_replace_flags = ๅฒๅญๅบซๆๆจๆฟๆๅคฑๆ
+admin.flags_replaced = ๅทฒๆฟๆๅฒๅญๅบซๆๆจ
default_branch_label = ้ ่จญ
tree_path_not_found_tag = ่ทฏๅพ %[1]s ไธๅญๅจๆผๆจ็ฑค %[2]s ไธญ
tree_path_not_found_commit = ่ทฏๅพ %[1]s ไธๅญๅจๆผๆไบค %[2]s ไธญ
@@ -2513,7 +2578,7 @@ migrate.cancel_migrating_confirm = ๆจ็ขบๅฎ่ฆๅๆถ้ๆฌก็้ท็งปๅ๏ผ
invisible_runes_header = `ๆญคๆชๆกๅ
งๅซไธๅฏ่ฆ็ Unicode ๅญๅ
`
ambiguous_runes_header = `้ๅๆชๆกๅ
งๅซๆจกๆฃฑๅ
ฉๅฏ็ Unicode ๅญๅ
`
rss.must_be_on_branch = ๆจๅฟ
้ ๅจไธๅๅๆฏไธๆ่ฝ่จ้ฑ RSSใ
-admin.enabled_flags = ่ฉฒๅฒๅญๅบซ็ๆๆจ๏ผ
+admin.enabled_flags = ่ฉฒๅฒๅญๅบซๅ็จ็ๆๆจ๏ผ
mirror_address_protocol_invalid = ่ผธๅ
ฅ็ URL ็กๆใๅชๆ https(s):// ๆ git:// ้ฃ็ตๅฏไปฅ่ขซ่จญๅฎ็บ้กๅไพๆบใ
ambiguous_runes_description = `้ๅๆชๆกๅ
งๅซๅฎนๆ้ ๆๆททๆท็ Unicode ๅญๅ
ใๅฆๆๆจ่ฆบๅพ้ๆฏๆชๆกไฝ่
็ๆฌๆ๏ผๆจๅฏไปฅๅฎๅ
จ็ๅฟฝ็ฅ้ๅ่จๆฏใๆไธ Escape ๅฏไปฅ้กฏ็คบ้ไบๅญๅ
ใ`
commit.contained_in = ้ๅๆไบคๅญๅจๆผ๏ผ
@@ -2594,7 +2659,7 @@ signing.wont_sign.approved = ๅ ็บๅไฝต่ซๆฑๆฒๆ่ขซๆ ธๅฏ๏ผ้ๅๅไฝตไธ
activity.navbar.recent_commits = ๆ่ฟ็ๆไบค
issues.comment.blocked_by_user = ๅ ็บๆจ่ขซ่ฉฒๅฒๅญๅบซ็ๆๆ่
ๆๅ้ก็ๆๅบ่
ๅฐ้๏ผๆจไธ่ฝๅจ้ๅๅ้กไธ็่จใ
pulls.closed = ๅไฝต่ซๆฑๅทฒ้้
-pulls.title_desc_one = ๆณๅพ %[2]s
ๅไฝต %[1]d ๅๆไบค่ณ %[3]s
+pulls.title_desc_one = ๆณๅพ %[2]s
ๅไฝต %[1]d ๅๆไบค่ณ %[3]s
pulls.merged_title_desc_one = ๆผ %[4]s ่ช %[2]s
ๅไฝตไบ %[1]d ๅๆไบค่ณ %[3]s
issues.archived_label_description = ๏ผๅทฒๅฐๅญ๏ผ%s
signing.wont_sign.always = ๆฐธ้ ็ฐฝ็ฝฒๆไบคใ
@@ -2606,7 +2671,7 @@ pulls.commit_ref_at = `ๅจๆไบค %[2]s ๅผ็จไบ
pulls.cmd_instruction_checkout_desc = ๅพๆจ็ๅฐๆกๅฒๅญๅบซ checkout ไธๅๆฐ็ๅๆฏไพๆธฌ่ฉฆ้ไบๆดๆนใ
pulls.cmd_instruction_merge_title = ๅไฝต
pulls.ready_for_review = ๅฏไปฅ้ๅงๅฏฉ้ฑไบๅ๏ผ
-pulls.cmd_instruction_hint = `ๆชข่ฆๅฝไปคๅๆ็คบ `
+pulls.cmd_instruction_hint = `ๆชข่ฆๅฝไปคๅๆ็คบ`
file_follow = ่ท้จ่ฑกๅพตๅผ้ฃ็ต
milestones.filter_sort.earliest_due_data = ๆๆฉๅฐๆๆฅ
size_format = %[1]s๏ผ%[2]s๏ผ%[3]s๏ผ%[4]s
@@ -2629,7 +2694,7 @@ pulls.blocked_by_changed_protected_files_n = ้ๅๅไฝต่ซๆฑ่ขซๆซๆญข๏ผๅ
pulls.status_checks_hide_all = ้ฑ่ๆๆๆชขๆฅ
pulls.status_checks_show_all = ้กฏ็คบๆๆๆชขๆฅ
pulls.reopen_failed.head_branch = ๅ ็บ้ๅๅไฝต่ซๆฑ็ head ๅๆฏไธๅญๅจ๏ผๅฎ็กๆณ่ขซ้ๅใ
-activity.navbar.pulse = ่ๆ
+activity.navbar.pulse = ๅๆ
signing.will_sign = ๅฐไปฅ้้ฐใ%sใ็ฐฝ็ฝฒ้ๅๆไบคใ
signing.wont_sign.headsigned = ๅ ็บ head ๆไบคๆฒๆ่ขซ็ฐฝ็ฝฒ๏ผ้ๅๅไฝตไธๆ่ขซ็ฐฝ็ฝฒใ
signing.wont_sign.commitssigned = ๅ ็บๆๆ็ธ้็ๆไบค้ฝๆฒๆ่ขซ็ฐฝ็ฝฒ๏ผ้ๅๅไฝตไธๆ่ขซ็ฐฝ็ฝฒใ
@@ -2648,8 +2713,163 @@ wiki.original_git_entry_tooltip = ่ๅ
ถไฝฟ็จๅๅ้ฃ็ต๏ผๆชข่ฆๅๅง Git
settings.mirror_settings.docs.more_information_if_disabled = ๆจๅฏไปฅๅจ้่ฃกๆพๅฐๆดๅค้ๆผ push ๅ pull ้กๅ็่ณ่จ๏ผ
settings.mirror_settings.docs.doc_link_title = ๅฆไฝๅปบ็ซๅฒๅญๅบซ้กๅ๏ผ
settings.mirror_settings.docs.pulling_remote_title = ๅพ้ ็ซฏๅฒๅญๅบซๆๅ
+issues.author.tooltip.pr = ๆญคไฝฟ็จ่
ๆฏ้ๅๅไฝต่ซๆฑ็ไฝ่
ใ
+form.string_too_long = ๆไพ็ๅญไธฒ่ถ
้ไบ %d ๅๅญๆฏใ
+subscribe.issue.guest.tooltip = ็ปๅ
ฅไพ่ฟฝ่นค้ๅๅ้กใ
+subscribe.pull.guest.tooltip = ็ปๅ
ฅไพ่ฟฝ่นค้ๅๅไฝต่ซๆฑใ
+milestones.filter_sort.name = ๅ็จฑ
+settings.units.overview = ๆฆ่ฆฝ
+settings.federation_settings = ่ฏ้ฆ่จญๅฎ
+issues.author.tooltip.issue = ้ๅไฝฟ็จ่
ๆฏ้ๅๅ้ก็ไฝ่
ใ
+settings.units.add_more = ๅ็จๆดๅค
+release.download_count_one = %s ๆฌกไธ่ผ
+release.download_count_few = %s ๆฌกไธ่ผ
+pulls.cmd_instruction_checkout_title = ็ฐฝๅบ
+pulls.made_using_agit = AGit
+branch.rename = ้ๆฐๅฝๅๅๆฏใ%sใ
+release.type_attachment = ้ไปถ
+release.asset_external_url = ๅค้จ็ถฒๅ
+settings.mirror_settings.pushed_repository = ๅทฒๆจ้็ๅฒๅญๅบซ
+project = ๅฐๆก
+issues.filter_milestone_open = ้ๆพไธญ็้็จ็ข
+issues.filter_milestone_closed = ๅทฒ้้็้็จ็ข
+settings.sourcehut_builds.secrets = ็งๅฏ
+settings.ignore_stale_approvals = ๅฟฝ็ฅ้ๆ็ๆนๅ
+settings.unarchive.button = ๅๆถๅฐๅญๅฒๅญๅบซ
+branch.rename_branch_to = ้ๆฐๅฝๅใ%sใ่ณ๏ผ
+activity.published_tag_label = ๆจ็ฑค
+settings.event_pull_request_merge = ๅไฝต่ซๆฑๅไฝต
+settings.update_mirror_settings = ๆดๆฐ้กๅ่จญๅฎ
+settings.protect_status_check_matched = ๅทฒๅน้
+settings.unarchive.header = ๅๆถๅฐๅญๆญคๅฒๅญๅบซ
+settings.branches.switch_default_branch = ๅๆ้ ่จญๅๆฏ
+settings.graphql_url = GraphQL ็ถฒๅ
+activity.commit = ๆไบคๆดปๅ
+settings.event_pull_request_approvals = ๅไฝต่ซๆฑๆนๅ
+issues.dependency.issue_batch_close_blocked = ็กๆณๆนๆฌก้้้ธๅฎ็ๅ้ก๏ผๅ ็บๅ้ก #%d ไป็ถๅ
ทๆ้ๆพ็ไพ่ณด้
+milestones.new_subheader = ้็จ็ขๅฏไปฅๅนซๅฉไฝ ็ต็นๅ้กไธฆ่ฟฝ่นคๅ
ถ้ฒๅบฆใ
+comments.edit.already_changed = ็กๆณๅฒๅญๅฐ่ฉ่ซ็่ฎๆดใๅ
งๅฎนไผผไนๅทฒ่ขซๅ
ถไปไฝฟ็จ่
่ฎๆดใ่ซ้ๆฐๆด็้ ้ขไธฆๅๆฌกๅ่ฉฆ็ทจ่ผฏไปฅ้ฟๅ
่ฆ่ๅ
ถ่ฎๆด
+activity.published_prerelease_label = ้ ็ผ่ก
+no_eol.tooltip = ๆญคๆชๆกไธๅ
ๅซ่กๅฐพๅญๅ
ใ
+n_release_one = %s ็ผ่ก
+n_release_few = %s ็ผ่ก
+no_eol.text = ็กๆชๆก็ตๅฐพ็ฌฆ
+issues.all_title = ๅ
จ้จ
+mirror_public_key = ๅ
ฌๅ
ฑ SSH ้้ฐ
+mirror_use_ssh.text = ไฝฟ็จ SSH ้ฉ่ญ
+issues.filter_sort.relevance = ้่ฏๆง
+settings.mirror_settings.push_mirror.none_ssh = ็ก
+mirror_use_ssh.not_available = SSH ้ฉ่ญไธๅฏ็จใ
+new_from_template = ไฝฟ็จ็ฏๆฌ
+new_advanced = ้ฒ้่จญๅฎ
+new_advanced_expand = ้ปๆไปฅๅฑ้
+editor.commit_email = ๆไบค้ปๅญไฟก็ฎฑ
+archive.pull.noreview = ๆญคๅฒๅญๅบซๅทฒๅฐๅญใไฝ ไธ่ฝๅฏฉ้ฑๅไฝต่ซๆฑใ
+settings.matrix.access_token_helper = ๅปบ่ญฐ็บๆญค่จญๅฎไธๅๅฐ็จ็ Matrix ๅธณ่ใๅญๅ็ฌฆ่จๅฏไปฅๅพ Element ็ถฒ่ทฏไฝฟ็จ่
็ซฏ๏ผๆผ็งไบบ๏ผ้ฑ่บซๅ้ ๏ผ> ไฝฟ็จ่
้ธๅฎ๏ผๅทฆไธ่ง๏ผ> ๆๆ่จญๅฎ > ๅนซๅฉๅ้ๆผ > ้ฒ้ > ๅญๅ็ฌฆ่จ๏ผไฝๆผ Homeserver ็ถฒๅๆญฃไธๆน๏ผๆชข็ดขใ้้็งไบบ๏ผ้ฑ่บซๅ้ ๏ผ็ปๅบๅฐไฝฟๅญๅ็ฌฆ่จๅคฑๆ๏ผใ
+release.title = ็ผ่กๆจ้ก
+settings.protect_patterns = ๅผๆจฃ
+mirror_use_ssh.helper = ็ถไฝ ้ธๆๆญค้ธ้
ๆ๏ผForgejo ๅฐ้้ Git SSH ้กๅๅฒๅญๅบซไธฆ็บไฝ ๅปบ็ซ้้ฐๅฐใไฝ ๅฟ
้ ็ขบไฟๅทฒ็ข็็ๅ
ฌ้ฐๅทฒๆๆๆฌๆ่ฝๆจ้่ณ็ฎๆจๅฒๅญๅบซใ้ธๆๆญค้ธ้
ๆ๏ผไฝ ไธ่ฝไฝฟ็จๅบๆผๅฏ็ขผ็ๆๆฌใ
+settings.event_pull_request_review_request = ๅฏฉๆ ธ่ซๆฑ
+settings.protect_new_rule = ๅปบ็ซๆฐ็ๅๆฏไฟ่ญท่ฆๅ
+settings.remove_protected_branch_success = ๅๆฏไฟ่ญท่ฆๅใ%sใๅทฒ่ขซ็งป้คใ
+release.hide_archive_links_helper = ้ฑ่ๆญค็ผ่ก่ชๅ็ข็็ๅๅง็ขผๅฐๅญใไพๅฆ๏ผๅฆๆไฝ ๆญฃๅจ่ช่กไธ่ผใ
+settings.enforce_on_admins_desc = ๅฒๅญๅบซ็ฎก็ๅกไธ่ฝ็น้ๆญค่ฆๅใ
+release.message = ๆ่ฟฐๆญค็ผ่ก
+release.deletion_desc = ๅช้ค็ผ่กๅชๆๅฐๅ
ถๅพ Forgejo ไธญ็งป้คใๅฎไธๆๅฝฑ้ฟ Git ๆจ็ฑคใๅฒๅญๅบซ็ๅ
งๅฎนๆๅ
ถๆญทๅฒ่จ้ใ็นผ็บ๏ผ
+settings.unarchive.error = ๅ่ฉฆๅๆถๅฐๅญๅฒๅญๅบซๆ็ผ็้ฏ่ชคใ่ซๅ้ฑๆฅ่ชไปฅไบ่งฃๆดๅค่ฉณ็ดฐ่ณ่จใ
+release.invalid_external_url = ็กๆ็ๅค้จ็ถฒๅ๏ผ%s
+release.add_external_asset = ๆฐๅขๅค้จ่ณ็ข
+release.asset_name = ่ณ็ขๅ็จฑ
+release.type_external_asset = ๅค้จ่ณ็ข
+branch.tag_collision = ็กๆณๅปบ็ซๅๆฏใ%sใ๏ผๅ ็บๅฒๅญๅบซไธญๅทฒๅญๅจๅๅๆจ็ฑคใ
+settings.protect_status_check_patterns = ็ๆ
ๆชขๆฅๅผๆจฃ
+branch.delete_desc = ๅช้คๅๆฏๆฏๆฐธไน
ๆง็ใ้็ถ่ขซๅช้ค็ๅๆฏๅจๅฏฆ้่ขซ็งป้คไนๅๅฏ่ฝๆ็นผ็บๅญๅจไธๅฐๆฎตๆ้๏ผไฝๆฏๅคงๅคๆธๆ
ๆณไธๅฎๆฏ็กๆณๆค้ท็ใ็นผ็บ๏ผ
+release.system_generated = ๆญค้ไปถๆฏ่ชๅ็ข็็ใ
+topic.format_prompt = ไธป้กๅฟ
้ ไปฅๅญๆฏๆๆธๅญ้้ ญ๏ผๅฏไปฅๅ
ๅซๅๅฝข็ ดๆ่๏ผ-๏ผๅ้ป๏ผ.๏ผ๏ผๆ้ท 35 ๅๅญๅ
ใๅญๆฏๅฟ
้ ๆฏๅฐๅฏซใ
+settings.remove_protected_branch_failed = ็งป้คๅๆฏไฟ่ญท่ฆๅใ%sใๅคฑๆใ
+branch.warning_rename_default_branch = ไฝ ๆญฃๅจ้ๆฐๅฝๅ้ ่จญๅๆฏใ
+settings.rename_branch_failed_protected = ็กๆณ้ๆฐๅฝๅๅๆฏ %s๏ผๅ ็บๅฎๆฏๅไฟ่ญท็ๅๆฏใ
+settings.unarchive.success = ๆญคๅฒๅญๅบซๅทฒๆๅๅๆถๅฐๅญใ
+settings.unarchive.text = ๅๆถๅฐๅญๅฒๅญๅบซๅฐๆขๅพฉๅ
ถๆฅๆถๆไบคๅๆจ้๏ผไปฅๅๆฐๅ้กๅๅไฝต่ซๆฑ็่ฝๅใ
+release.hide_archive_links = ้ฑ่่ชๅ็ข็็ๅฐๅญ
+settings.protect_no_valid_status_check_patterns = ๆฒๆๆๆ็็ๆ
ๆชขๆฅๅผๆจฃใ
+settings.enforce_on_admins = ็บๅฒๅญๅบซ็ฎก็ๅกๅผทๅถๅท่กๆญค่ฆๅ
+settings.wiki_rename_branch_main_notices_2 = ้ๅฐๆฐธไน
้ๆฐๅฝๅๅฒๅญๅบซ %s ็ Wiki ็ๅ
ง้จๅๆฏใ็พๆ็็ฐฝๅบๅฐ้่ฆๆดๆฐใ
+settings.discord_icon_url.exceeds_max_length = ๅ็คบ็ถฒๅ้ทๅบฆๅฟ
้ ๅฐๆผๆ็ญๆผ 2048 ๅๅญ็ฌฆ
+settings.wiki_branch_rename_success = ๅฒๅญๅบซ Wiki ็ๅๆฏๅ็จฑๅทฒๆๅ่ฆ็ฏๅใ
+commits.view_single_diff = ๆฅ็ๆญคๆไบคไธญๅฐๆญคๆไบค็่ฎๆด
+issues.new.assign_to_me = ๆๆดพ็ตฆๆ
+mirror_denied_combination = ไธ่ฝ็ตๅไฝฟ็จๅ
ฌ้ฐๅๅบๆผๅฏ็ขผ็้ฉ่ญใ
+settings.update_settings_no_unit = ๅฒๅญๅบซ่ณๅฐๆ่ฉฒๅ
่จฑๆ็จฎๅฝขๅผ็ไบคไบใ
+pulls.edit.already_changed = ็กๆณๅฒๅญๅฐๅไฝต่ซๆฑ็่ฎๆดใ็่ตทไพๅ
งๅฎนๅทฒ่ขซๅฆไธๅไฝฟ็จ่
่ฎๆดใ่ซ้ๆฐๆด็้ ้ขไธฆๅ่ฉฆๅๆฌก็ทจ่ผฏไปฅ้ฟๅ
่ฆ่ๅ
ถ่ฎๆด
+settings.add_collaborator_blocked_our = ็กๆณๆฐๅขๅไฝ่
๏ผๅ ็บๅฒๅญๅบซๆๆ่
ๅทฒๅฐ้ไปๅใ
+issues.edit.already_changed = ็กๆณๅฒๅญๅฐๅ้ก็่ฎๆดใ็่ตทไพๅ
งๅฎนๅทฒ่ขซๅฆไธๅไฝฟ็จ่
่ฎๆดใ่ซ้ๆฐๆด็้ ้ขไธฆๅ่ฉฆๅๆฌก็ทจ่ผฏไปฅ้ฟๅ
่ฆ่ๅ
ถ่ฎๆด
+settings.federation_following_repos = ้ๆณจๅฒๅญๅบซ็็ถฒๅใไปฅๅๅฝขๅ่ใ;ใๅ้๏ผๆฒๆ็ฉบๆ ผใ
+settings.federation_not_enabled = ไฝ ็็ซ้ปไธๆชๅ็จ่ฏ้ฆใ
+settings.federation_apapiurl = ๆญคๅฒๅญๅบซ็่ฏ้ฆ็ถฒๅใๅฐๅ
ถ่ค่ฃฝไธฆ่ฒผไธ่ณๅฆไธๅๅฒๅญๅบซ็่ฏ้ฆ่จญๅฎไธญไฝ็บ้ๆณจๅฒๅญๅบซ็็ถฒๅใ
+settings.enter_repo_name = ๆบ็ขบ่ผธๅ
ฅๆๆ่
ๅๅฒๅญๅบซๅ็จฑ๏ผๅฆไธๆ็คบ๏ผ
+settings.wiki_rename_branch_main = ่ฆ็ฏๅ Wiki ๅๆฏๅ็จฑ
+settings.wiki_branch_rename_failure = ็กๆณ่ฆ็ฏๅๅฒๅญๅบซ Wiki ็ๅๆฏๅ็จฑใ
+settings.confirm_wiki_branch_rename = ้ๆฐๅฝๅ Wiki ๅๆฏ
+settings.transfer_quota_exceeded = ๆฐๆๆ่
๏ผ%s๏ผๅทฒ่ถ
ๅบ้
้กใๅฒๅญๅบซๅฐๆช่ฝ็งปใ
+settings.wiki_rename_branch_main_notices_1 = ๆญคๆไฝ็กๆณ ๆค้ทใ
+settings.push_mirror_sync_in_progress = ็ฎๅๆญฃๅจๅฐ่ฎๆดๆจ้่ณ้ ็ซฏ %sใ
+settings.confirmation_string = ็ขบ่ชๅญไธฒ
+issues.review.pending.tooltip = ๅ
ถไปไฝฟ็จ่
็ฎๅ็ไธๅฐๆญค็่จใ่ฆๆไบคไฝ ็ๅพ
่็็่จ๏ผ่ซ้ธๆ้ ้ข้ ้จ็ใ%sใ->ใ%s/%s/%sใใ
+pulls.delete_after_merge.head_branch.is_default = ไฝ ่ฆๅช้ค็้ ญๅๆฏๆฏ้ ่จญๅๆฏ๏ผ็กๆณๅช้คใ
+pulls.delete_after_merge.head_branch.is_protected = ไฝ ่ฆๅช้ค็้ ญๅๆฏๆฏๅไฟ่ญท็ๅๆฏ๏ผ็กๆณๅช้คใ
+pulls.delete_after_merge.head_branch.insufficient_branch = ไฝ ๆฒๆๆฌ้ๅช้ค้ ญๅๆฏใ
+settings.pull_mirror_sync_in_progress = ็ฎๅๆญฃๅจๅพ้ ็ซฏ %s ๆๅ่ฎๆดใ
+settings.pull_mirror_sync_quota_exceeded = ้
้กๅทฒ่ถ
ๅบ๏ผไธๆๅ่ฎๆดใ
+settings.wiki_globally_editable = ๅ
่จฑไปปไฝไบบ็ทจ่ผฏ Wiki
+settings.transfer_abort_success = ่ฝ็งปๅฒๅญๅบซ่ณ %s ๅทฒๆๅๅๆถใ
+settings.add_collaborator_blocked_them = ็กๆณๆฐๅขๅไฝ่
๏ผๅ ็บไปๅๅทฒๅฐ้ๅฒๅญๅบซๆๆ่
ใ
+settings.add_webhook.invalid_path = ่ทฏๅพไธ่ฝๅ
ๅซใ.ใใใ..ใๆ็ฉบๅญไธฒใๅฎไธ่ฝไปฅๆ็ท้้ ญๆ็ตๅฐพใ
+settings.webhook.test_delivery_desc_disabled = ่ฆไฝฟ็จ่ๅไบไปถๆธฌ่ฉฆๆญค Webhook๏ผ่ซๅๅๅฎใ
+settings.webhook.replay.description_disabled = ่ฆ้ๆญๆญค Webhook๏ผ่ซๅๅๅฎใ
+settings.wiki_rename_branch_main_desc = ๅฐ Wiki ๅ
ง้จไฝฟ็จ็ๅๆฏ้ๆฐๅฝๅ็บใ%sใใๆญค่ฎๆดๆฏๆฐธไน
ๆง็๏ผ็กๆณๆคๆถใ
+settings.mirror_settings.push_mirror.copy_public_key = ่ค่ฃฝๅ
ฌ้ฐ
+settings.default_update_style_desc = ็จๆผๆดๆฐ่ฝๅพๆผๅบ็คๅๆฏ็ๅไฝต่ซๆฑ็้ ่จญๆดๆฐๆจกๅผใ
+summary_card_alt = ๅฒๅญๅบซ %s ็ๆ่ฆๅก
+pulls.recently_pushed_new_branches = ไฝ ๅทฒๆผ %[2]s ๆจ้ๅๆฏ %[1]s
+pulls.sign_in_require = ็ปๅ
ฅ ไปฅๅปบ็ซๆฐ็ๅไฝต่ซๆฑใ
+issues.num_reviews_one = %d ๅๅฏฉ้ฑ
+issues.num_reviews_few = %d ๅๅฏฉ้ฑ
+new_from_template_description = ไฝ ๅฏไปฅ้ธๆๆญค็ซ้ปไธ็พๆ็ๅฒๅญๅบซ็ฏๆฌไธฆๅฅ็จๅ
ถ่จญๅฎใ
+auto_init_description = ไฝฟ็จ README ้ๅง Git ๆญทๅฒ่จ้ไธฆๅฏ้ธๆๆฐๅข License ๅ .gitignore ๆชๆกใ
+issues.reaction.add = ๆฐๅขๅๆ
+issues.reaction.alt_few = %[1]s ๅฐ %[2]s ๅๅบไบๅๆใ
+issues.reaction.alt_many = %[1]s ๅๅฆๅค %[2]d ไบบๅฐ %[3]s ๅๅบไบๅๆใ
+issues.context.menu = ็่จ้ธๅฎ
+issues.summary_card_alt = ๅฒๅญๅบซ %[2]s ไธญๆจ้ก็บใ%[1]sใ็ๅ้กๆ่ฆๅก
+release.summary_card_alt = ๅฒๅญๅบซ %[2]s ไธญๅ็บใ%[1]sใ็็ผ่กๆ่ฆๅก
+error.broken_git_hook = ๆญคๅฒๅญๅบซ็ Git ้คๅญไผผไนๅทฒๆๅฃใ่ซๆ็
งๆไปถ ไฟฎๅพฉๅฎๅ๏ผ็ถๅพๆจ้ไธไบๆไบคไปฅ้ๆฐๆด็็ๆ
ใ
+issues.reaction.alt_remove = ๅพ็่จไธญ็งป้ค %[1]s ็ๅๆใ
+
+vendored = ๅทฒไพๆ
+settings.mirror_settings.docs.doc_link_pull_section = ๆไปถไธญ็ใๅพ้ ็ซฏๅฒๅญๅบซๆๅใ้จๅใ
+settings.event_pull_request_review_request_desc = ๅไฝต่ซๆฑๅฏฉๆ ธ่ซๆฑๆๅฏฉๆ ธ่ซๆฑๅทฒ็งป้คใ
+settings.protect_status_check_patterns_desc = ่ผธๅ
ฅๆจกๅผไปฅๆๅฎๅ
ถไปๅๆฏๅจๅไฝตๅฐๅๆญค่ฆๅไฟ่ญท็ๅๆฏๅๅฟ
้ ้้็็ๆ
ๆชขๆฅใๆฏ่กๆๅฎไธๅๆจกๅผ๏ผๆจกๅผไธๅพ็บ็ฉบ็ฝใ
+settings.protect_invalid_status_check_pattern = ็ๆ
ๆชขๆฅๆจกๅผ็กๆ: ใ%sใใ
+settings.ignore_stale_approvals_desc = ไธ่จ็ฎๅจ่ผ่ๆไบคไธ้ฒ่ก็ๆ ธๅฏ๏ผ้ๆ็ๅฏฉๆ ธ๏ผไฝ็บๅไฝต่ซๆฑ็ๆ ธๅฏๆธ้ใๅฆๆ้ๆ็ๅฏฉๆ ธๅทฒ็ถ่ขซๆจๆฃ๏ผๅ็ก้็ท่ฆใ
+settings.tags.protection.pattern.description = ๆจๅฏไปฅไฝฟ็จๅฎไธๅ็จฑๆ glob ๆจกๅผๆๆญฃๅ่กจ้ๅผไพๅน้
ๅคๅๆจ็ฑคใ่ฉณๆ
่ซๅ้ฑ ๅไฟ่ญทๆจ็ฑคๆๅ ใ
+settings.thread_id = ็ท็จ ID
+settings.archive.text = ๅฐๅญๅฒๅญๅบซๅฐไฝฟๅ
ถๅฎๅ
จ่ฎ็บๅฏ่ฎใๅฎๅฐๅพๅ่กจๆฟไธญ้ฑ่ใๆฒๆไบบ๏ผ็่ณๅ
ๆฌๆจ๏ผ๏ผๅฐ่ฝๅค ้ฒ่กๆฐ็ๆไบค๏ผๆๆ้ไปปไฝๅ้กๆๅไฝต่ซๆฑใ
+diff.comment.add_line_comment = ๆฐๅข่ก่ฉ่ซ
+pulls.editable = ๅฏไปฅ็ทจ่ผฏ
+settings.units.units = ๅ่ฝ
+diff.git-notes.add = ๅขๅ ่จป้
+diff.git-notes.remove-header = ็งป้ค่จป้
+settings.event_pull_request_enforcement = ๅท่ก
[graphs]
+component_loading = %s่ผๅ
ฅไธญโฆ
+code_frequency.what = ๅฏซ็จๅผ้ ป็
+recent_commits.what = ๆ่ฟ็ๆไบค
+contributors.what = ่ฒข็ป
+component_loading_info = ้ๅฏ่ฝ้่ฆไธ้ปๆ้โฆ
+component_loading_failed = ็กๆณ่ผๅ
ฅ %s
+component_failed_to_load = ็ผ็ไบๆๅค้ฏ่ชคใ
[org]
org_name_holder=็ต็นๅ็จฑ
@@ -2662,8 +2882,8 @@ teams=ๅ้
code=็จๅผ็ขผ
lower_members=ๅๆๅก
lower_repositories=ๅๅฒๅญๅบซ
-create_new_team=ๅปบ็ซๅ้
-create_team=ๅปบ็ซๆฐ็ๅ้
+create_new_team=ๆฐๅ้
+create_team=ๅปบ็ซๅ้
org_desc=ๆ่ฟฐ
team_name=ๅ้ๅ็จฑ
team_desc=ๆ่ฟฐ
@@ -2679,7 +2899,7 @@ form.create_org_not_allowed=ๆญคๅธณ่็ฆๆญขๅปบ็ซ็ต็นใ
settings=่จญๅฎ
settings.options=็ต็น
-settings.full_name=็ต็นๅ
จๅ
+settings.full_name=ๅ
จๅ
settings.website=ๅฎๆน็ถฒ็ซ
settings.location=ๆๅจๅฐๅ
settings.permission=ๆฌ้
@@ -2693,10 +2913,10 @@ settings.visibility.private_shortname=็งๆ
settings.update_settings=ๆดๆฐ่จญๅฎ
settings.update_setting_success=็ต็น่จญๅฎๅทฒๆดๆฐใ
-settings.change_orgname_redirect_prompt=่็ๅ็จฑ่ขซ้ ็จๅ๏ผๆ้ๆฐๅฐๅๆฐๅ็จฑใ
+settings.change_orgname_redirect_prompt=่็ๅ็จฑ่ขซ้ ็จๅๅฐๆ่ฝๅ่ณๆฐๅ็จฑใ
settings.update_avatar_success=ๅทฒๆดๆฐ็ต็น็ๅคง้ ญ่ฒผใ
settings.delete=ๅช้ค็ต็น
-settings.delete_account=ๅช้ค้ๅ็ต็น
+settings.delete_account=ๅช้คๆญค็ต็น
settings.delete_prompt=่ฉฒ็ต็นๅฐ่ขซๆฐธไน
ๅช้คใๆญคๅไฝไธๅฏ ้ๅ๏ผ
settings.confirm_delete_account=็ขบ่ชๅช้ค
settings.delete_org_title=ๅช้ค็ต็น
@@ -2707,27 +2927,27 @@ settings.labels_desc=ๅจๆญค่ๆฐๅข็ๆจ็ฑคๅฏ็จๆผๆญค็ต็นไธ็ๆ
members.membership_visibility=ๆๅก็่ฆฝๆฌ้๏ผ
members.public=ๅฏ่ฆ
-members.public_helper=้ฑ่
+members.public_helper=่จญ็บ้ฑ่
members.private=้ฑ่
-members.private_helper=้กฏ็คบ
+members.private_helper=่จญ็บ้กฏ็คบ
members.member_role=ๆๅก่ง่ฒ๏ผ
members.owner=ๆๆ่
members.member=ๆฎ้ๆๅก
members.remove=็งป้ค
members.remove.detail=็ขบๅฎ่ฆๅพ %[2]s ไธญๅช้ค %[1]s ๅ๏ผ
members.leave=้ข้
-members.leave.detail=็ขบๅฎ่ฆ้ข้ %s ๅ๏ผ
+members.leave.detail=ไฝ ็ขบๅฎไฝ ่ฆ้ข้็ต็นใ%sใๅ๏ผ
members.invite_desc=้่ซๆฐ็็จๆถๅ ๅ
ฅ %s๏ผ
members.invite_now=็ซๅณ้่ซ
teams.join=ๅ ๅ
ฅ
teams.leave=้ข้
-teams.leave.detail=็ขบๅฎ่ฆ้ข้ %s ๅ๏ผ
+teams.leave.detail=ไฝ ็ขบๅฎไฝ ่ฆ้ข้ๅ้ใ%sใๅ๏ผ
teams.can_create_org_repo=ๅปบ็ซๅฒๅญๅบซ
teams.can_create_org_repo_helper=ๆๅกๅฏไปฅๅจ็ต็นไธญๆฐๅขๅฒๅญๅบซใๅปบ็ซ่
ๅฐ่ชๅๅๅพๆฐๅฒๅญๅบซ็็ฎก็ๅกๆฌ้ใ
-teams.none_access=ๆฒๆๆฌ้
-teams.none_access_helper=ๆๅก็กๆณๆชข่ฆๆญคๅฎๅ
ๆๅฐๅ
ถๅท่กๅ
ถไปๅไฝ๏ผ้ๅฐๅ
ฌ้ๅฒๅญๅบซๆฒๆๅฝฑ้ฟใ
-teams.general_access=ไธ่ฌๆฌ้
+teams.none_access=็กๆฌๅญๅ
+teams.none_access_helper=ใ็กๆฌๅญๅใ้ธ้
ๅ
ๅฐ็งไบบๅฒๅญๅบซๆๆใ
+teams.general_access=่ช่จๅญๅ
teams.general_access_helper=ๆๅกๆฌ้ๅฐ็ฑไธๅๆฌ้่กจๆฑบๅฎใ
teams.read_access=่ฎๅ
teams.read_access_helper=ๆๅกๅฏไปฅๆฅ็ๅ Clone ๅ้ๅฒๅญๅบซใ
@@ -2770,6 +2990,14 @@ teams.all_repositories_write_permission_desc=้ๅๅ้ๆๆๆๆๅฒ
teams.all_repositories_admin_permission_desc=้ๅๅ้ๆๆๆๆๅฒๅญๅบซ ็็ฎก็ๅก ๆฌ้๏ผๆๅกๅฏไปฅ่ฎๅใๆจ้ๅๅขๅ ๅไฝ่
ๅฐๅฒๅญๅบซใ
teams.invite.by=้่ซไบบ %s
teams.invite.description=่ซ้ปๆไธๆนๆ้ๅ ๅ
ฅๅ้ใ
+open_dashboard = ้ๅๅ้ถๆฟ
+settings.email = ่ฏ็ตก้ปๅญ้ตไปถ
+form.name_pattern_not_allowed = ็ต็นๅ็จฑไธญไธๅ
่จฑไฝฟ็จๅผๆจฃใ%sใใ
+follow_blocked_user = ไฝ ็กๆณ้ๆณจๆญค็ต็น๏ผๅ ็บๆญค็ต็นๅทฒๅฐ้ไฝ ใ
+teams.invite.title = ไฝ ๅทฒ่ขซ้่ซๅ ๅ
ฅ็ต็น %[2]s ไธญ็ๅ้ %[1]s ใ
+settings.change_orgname_prompt = ๆณจๆ๏ผ่ฎๆด็ต็นๅ็จฑไนๆ่ฎๆดไฝ ็ต็น็็ถฒๅไธฆ้ๆพ่ๅ็จฑใ
+settings.change_orgname_redirect_prompt.with_cooldown.few = ่็็ต็นๅ็จฑๅฐๅจ %[1]d ๅคฉ็ๅทๅปๆๅพๅฐๆๆไบบๅฏ็จ๏ผไฝ ไป็ถๅฏไปฅๅจๅทๅปๆๅ
ง้ๆฐไฝฟ็จ่ๅ็จฑใ
+settings.change_orgname_redirect_prompt.with_cooldown.one = ่็็ต็นๅ็จฑๅฐๅจ %[1]d ๅคฉ็ๅทๅปๆๅพๅฐๆๆไบบๅฏ็จ๏ผๆจไป็ถๅฏไปฅๅจๅทๅปๆๅ
ง้ๆฐไฝฟ็จ่ๅ็จฑใ
[admin]
dashboard=่ณ่จไธป้
@@ -2786,7 +3014,7 @@ first_page=้ฆ้
last_page=ๆซ้
total=็ธฝ่จ๏ผ%d
-dashboard.new_version_hint=็พๅทฒๆจๅบ Forgejo %s๏ผๆจๆญฃๅจๅท่ก %sใ่ฉณๆ
่ซๅ้ฑ้จ่ฝๆ ผ ็่ชชๆใ
+dashboard.new_version_hint=็พๅทฒๆจๅบ Forgejo %s๏ผๆจๆญฃๅจๅท่ก %sใ่ฉณๆ
่ซๅ้ฑ้จ่ฝๆ ผ ็่ชชๆใ
dashboard.statistic=ๆ่ฆ
dashboard.operations=็ถญ่ญทไฝๆฅญ
dashboard.system_status=็ณป็ตฑ็ๆ
@@ -2824,9 +3052,9 @@ dashboard.resync_all_hooks=้ๆฐๅๆญฅๆๆๅฒๅญๅบซ็ pre-receiveใupdate
dashboard.reinit_missing_repos=้ๆฐๅๅงๅๆๆ่จ้ๅญๅจไฝ้บๅคฑ็ Git ๅฒๅญๅบซ
dashboard.sync_external_users=ๅๆญฅๅค้จไฝฟ็จ่
่ณๆ
dashboard.cleanup_hook_task_table=ๆธ
็ hook_task ่ณๆ่กจ
-dashboard.cleanup_packages=ๆธ
็ๅทฒ้ๆ็่ป้ซๅ
+dashboard.cleanup_packages=ๆธ
็้ๆ็่ป้ซๅ
dashboard.server_uptime=ไผบๆๅจ้ไฝๆ้
-dashboard.current_goroutine=็ฎๅ็ Goroutines ๆธ้
+dashboard.current_goroutine=็ฎๅ็ Goroutines
dashboard.current_memory_usage=็ฎๅ่จๆถ้ซไฝฟ็จ้
dashboard.total_memory_allocated=ๆๆ่ขซๅ้
็่จๆถ้ซ
dashboard.memory_obtained=็ฒๅพ็่จๆถ้ซ
@@ -2859,9 +3087,9 @@ dashboard.delete_old_actions.started=ๅพ่ณๆๅบซๅช้คๆๆ่่ก็บ็ไปปๅ
dashboard.update_checker=ๆดๆฐๆชขๆฅๅจ
dashboard.delete_old_system_notices=ๅพ่ณๆๅบซๅช้คๆๆ่็ณป็ตฑๆ็คบ
dashboard.gc_lfs=ๅฐ LFS meta objects ้ฒ่กๅๅพๅๆถ
-dashboard.stop_zombie_tasks=ๅๆญขๆฎญๅฑไปปๅ
-dashboard.stop_endless_tasks=ๅๆญขๆฐธไธๅๆญข็ไปปๅ
-dashboard.cancel_abandoned_jobs=ๅๆถๅทฒๆพๆฃ็ไฝๆฅญ
+dashboard.stop_zombie_tasks=ๅๆญขๆฎญๅฑ Actions ไปปๅ
+dashboard.stop_endless_tasks=ๅๆญขๆฐธไธๅๆญข็ Actions ไปปๅ
+dashboard.cancel_abandoned_jobs=ๅๆถๅทฒๆพๆฃ็ Actions ไฝๆฅญ
users.user_manage_panel=ไฝฟ็จ่
ๅธณ่็ฎก็
users.new_account=ๅปบ็ซไฝฟ็จ่
ๅธณ่
@@ -2886,10 +3114,10 @@ users.update_profile_success=ๅทฒๆดๆฐไฝฟ็จ่
ๅธณ่ใ
users.edit_account=็ทจ่ผฏไฝฟ็จ่
ๅธณ่
users.max_repo_creation=ๆๅคงๅฒๅญๅบซๆธ้
users.max_repo_creation_desc=(่จญๅฎ -1 ไฝฟ็จๅ
จๅ้ ่จญ้ๅถ)
-users.is_activated=ไฝฟ็จ่
ๅธณ่ๅทฒๅ็จ
-users.prohibit_login=็ฆๆญข็ปๅ
ฅ
-users.is_admin=ๆฏ็ฎก็ๅก
-users.is_restricted=ๅ้ๅถ็
+users.is_activated=ๅทฒๅ็จ็ๅธณ่
+users.prohibit_login=ๅทฒๅๆฌๅธณ่
+users.is_admin=็ฎก็ๅกๅธณ่
+users.is_restricted=ๅ้ๅถ็ๅธณ่
users.allow_git_hook=ๅฏไปฅๅปบ็ซ Git Hook
users.allow_git_hook_tooltip=Git Hook ๅฐไปฅๅ Forgejo ็ธๅ็ไฝๆฅญ็ณป็ตฑไฝฟ็จ่
ๅท่ก๏ผไธฆๆๆๅ็ญ็ไธปๆฉๅญๅๆฌ้ใๅ ๆญคๆๆๆญค็นๆฎ Git Hook ๆฌ้็ไฝฟ็จ่
ๅฏๅญๅๅไฟฎๆนๆๆ็ Forgejo ๅฒๅญๅบซๅ Forgejo ็่ณๆๅบซใไปๅ็่ณ่ฝๅๅพ Forgejo ็็ฎก็ๅกๆฌ้ใ
users.allow_import_local=ๅฏไปฅๅฏๅ
ฅๆฌๅฐๅฒๅญๅบซ
@@ -2937,7 +3165,7 @@ orgs.new_orga=ๆฐๅข็ต็น
repos.repo_manage_panel=ๅฒๅญๅบซ็ฎก็
repos.unadopted=ๆชๆฅ็ฎก็ๅฒๅญๅบซ
-repos.unadopted.no_more=ๆพไธๅฐๅ
ถไปๆชๆฅ็ฎก็ๅฒๅญๅบซ
+repos.unadopted.no_more=ๆพไธๅฐๆชๆฅ็ฎก็ๅฒๅญๅบซใ
repos.owner=ๆๆ่
repos.name=ๅ็จฑ
repos.private=็งๆ
@@ -2948,8 +3176,8 @@ repos.issues=ๅ้กๆธ
repos.size=ๅคงๅฐ
packages.package_manage_panel=่ป้ซๅ
็ฎก็
-packages.total_size=็ธฝๅคงๅฐ: %s
-packages.unreferenced_size=ๆชๅ่ๅคงๅฐ: %s
+packages.total_size=็ธฝๅคงๅฐ๏ผ%s
+packages.unreferenced_size=ๆชๅ่ๅคงๅฐ๏ผ%s
packages.owner=ๆๆ่
packages.creator=ๅปบ็ซ่
packages.name=ๅ็จฑ
@@ -2982,7 +3210,7 @@ auths.host=ไธปๆฉๅฐๅ
auths.port=้ฃๆฅๅ
auths.bind_dn=Bind DN
auths.bind_password=Bind ๅฏ็ขผ
-auths.user_base=็จๆถๆๅฐๅบๆบ
+auths.user_base=ไฝฟ็จ่
ๆๅฐๅบๆบ
auths.user_dn=็จๆถ DN
auths.attribute_username=ๅธณ่ๅฑฌๆง
auths.attribute_username_placeholder=็็ฉบๅฐไฝฟ็จๆผ Forgejo ่ผธๅ
ฅ็ๅธณ่ใ
@@ -2993,12 +3221,12 @@ auths.attribute_ssh_public_key=SSH ๅ
ฌ้ฐๅฑฌๆง
auths.attribute_avatar=ๅคง้ ญ่ฒผๅฑฌๆง
auths.attributes_in_bind=ๅพ Bind DN ไธญๅๅพๅฑฌๆง่ณ่จ
auths.allow_deactivate_all=ๅ
่จฑๅจๆๅฐ็ตๆ็บ็ฉบ็ฝๆๅ็จๆๆไฝฟ็จ่
ๅธณ่
-auths.use_paged_search=ไฝฟ็จๅ้ ๆฅ่ฉข
+auths.use_paged_search=ไฝฟ็จๅ้ ๆๅฐ
auths.search_page_size=้ ้ขๅคงๅฐ
auths.filter=ไฝฟ็จ่
็ฏฉ้ธๅจ
auths.admin_filter=็ฎก็่
็ฏฉ้ธๅจ
auths.restricted_filter=ๅ้ๅถ็็ฏฉ้ธๅจ
-auths.restricted_filter_helper=็็ฝๅไธ้ๅถไปปไฝไฝฟ็จ่
ใไฝฟ็จ็ฑณๅญใ*ใๅฐๆๆไธ็ฌฆๅ็ฎก็ๅก็ฏฉ้ธๆขไปถ็ไฝฟ็จ่
่จญๅฎ็บๅ้ใ
+auths.restricted_filter_helper=็็ฝไปฅไธ้ๅถไปปไฝไฝฟ็จ่
ใไฝฟ็จๅๅฝขๆ่ใ*ใไปฅๅฐๆๆไธ็ฌฆๅ็ฎก็ๅก็ฏฉ้ธๆขไปถ็ไฝฟ็จ่
่จญๅฎ็บๅ้ใ
auths.verify_group_membership=้ฉ่ญ LDAP ็พค็ตๆๅก่ณๆ ผ (็ฏฉ้ธๅจ็็ฉบไปฅ่ทณ้)
auths.group_search_base=็พค็ตๆๅฐ็ Base DN
auths.group_attribute_list_users=ๅ
ๅซไฝฟ็จ่
ๆธ
ๅฎ็็พค็ตๅฑฌๆง
@@ -3010,16 +3238,16 @@ auths.ms_ad_sa=MS AD ๆๅฐๅฑฌๆง
auths.smtp_auth=SMTP ้ฉ่ญ้กๅ
auths.smtphost=SMTP ไธปๆฉๅฐๅ
auths.smtpport=SMTP ้ฃๆฅๅ
-auths.allowed_domains=ๅๅ็ฝๅๅฎ
-auths.allowed_domains_helper=็็ฝไปฅๅ
่จฑๆๆๅๅใไปฅๅๅฝข้่ใ,ใๅ้ๅคๅๅๅใ
-auths.skip_tls_verify=ๅฟฝ็ฅ TLS ้ฉ่ญ
+auths.allowed_domains=ๅ
่จฑ็ๅๅ
+auths.allowed_domains_helper=็็ฝไปฅๅ
่จฑๆๆๅๅใไปฅๅๅฝข้่๏ผ,๏ผๅ้ๅคๅๅๅใ
+auths.skip_tls_verify=็ฅ้ TLS ้ฉ่ญ
auths.force_smtps=ๅผทๅถ SMTPS
auths.force_smtps_helper=SMTPS ็ธฝๆฏไฝฟ็จ 465 ๅ ใ่จญๅฎๆญค้ธ้
ไปฅๅผทๅถ SMTPS ไฝฟ็จๅ
ถไปๅ ใ(้คๆญคไนๅค่ฅไธปๆฉๆฏๆด็่ฉฑ STARTTLS ไนๆไฝฟ็จ่ฉฒๅ ใ)
auths.helo_hostname=HELO ไธปๆฉๅ็จฑ
auths.helo_hostname_helper=็จ HELO ๅณ้็ไธปๆฉๅ็จฑใ็็ฉบไปฅๅณ้็ฎๅ็ไธปๆฉๅ็จฑใ
auths.disable_helo=ๅ็จ HELO
auths.pam_service_name=PAM ๆๅๅ็จฑ
-auths.pam_email_domain=PAM ้ปๅญไฟก็ฎฑๅๅ (้ธ็จ)
+auths.pam_email_domain=PAM ้ปๅญไฟก็ฎฑๅๅ๏ผ้ธ็จ๏ผ
auths.oauth2_provider=OAuth2 ๆไพ่
auths.oauth2_icon_url=ๅ็คบ URL
auths.oauth2_clientID=ๅฎขๆถ็ซฏ ID (้้ฐ)
@@ -3033,7 +3261,7 @@ auths.oauth2_emailURL=้ปๅญ้ตไปถ URL
auths.skip_local_two_fa=่ทณ้ๆฌๅฐๅ
ฉๆญฅ้ฉ้ฉ่ญ
auths.skip_local_two_fa_helper=ไฟๆๆช่จญๅฎไปฃ่กจไฝฟ็จๅ
ฉๆญฅ้ฉ้ฉ่ญ็ๆฌๅฐไฝฟ็จ่
ไป็ถ้่ฆ้้ๅ
ฉๆญฅ้ฉ้ฉ่ญๆ่ฝ็ปๅ
ฅ
auths.oauth2_tenant=็งๆถ
-auths.oauth2_scopes=้กๅค็ๆๆฌ็ฏๅ (Scope)
+auths.oauth2_scopes=้กๅค็็ฏๅ
auths.oauth2_required_claim_name=ๅฟ
้ ๅกซๅฏซ Claim ๅ็จฑ
auths.oauth2_required_claim_name_helper=ๅกซๅฏซๆญคๅ็จฑไปฅ้ๅถ Claim ไธญๆๆญคๅ็จฑ็ไฝฟ็จ่
ๆ่ฝๅพๆญคไพๆบ็ปๅ
ฅ
auths.oauth2_required_claim_value=ๅฟ
้ ๅกซๅฏซ Claim ๅผ
@@ -3057,19 +3285,19 @@ auths.sspi_default_language_helper=SSPI ่ช่ญๆนๆณ่ชๅๅปบ็ซไนไฝฟ็จ่
็
auths.tips=ๅนซๅฉๆ็คบ
auths.tips.oauth2.general=OAuth2 ่ช่ญ
auths.tip.oauth2_provider=OAuth2 ๆไพ่
-auths.tip.bitbucket=่จปๅๆฐ็ OAuth ็จๆถ็ซฏไธฆๅ ๅ
ฅๆฌ้ใAccount - Readใใ็ถฒๅ๏ผhttps://bitbucket.org/account/user//oauth-consumers/new
+auths.tip.bitbucket=่จปๅๆฐ็ OAuth ไฝฟ็จ่
็ซฏไธฆๅ ๅ
ฅๆฌ้ใAccount - Readใใ็ถฒๅ๏ผ%s
auths.tip.nextcloud=ๅจๆจ็็ซ้ปไธ๏ผๆผ้ธๅฎใ่จญๅฎ -> ๅฎๅ
จๆง -> OAuth 2.0 ๅฎขๆถ็ซฏใ่จปๅๆฐ็ OAuth ๅฎขๆถ็ซฏ
-auths.tip.dropbox=ๅปบ็ซๆฐ็ Appใ็ถฒๅ๏ผhttps://www.dropbox.com/developers/apps
-auths.tip.facebook=่จปๅๆฐ็ๆ็จ็จๅผไธฆๆฐๅข็ขๅใFacebook ็ปๅ
ฅใใ็ถฒๅ๏ผhttps://developers.facebook.com/apps
-auths.tip.github=่จปๅๆฐ็ OAuth ๆ็จ็จๅผใ็ถฒๅ๏ผhttps://github.com/settings/applications/new
+auths.tip.dropbox=ๅปบ็ซๆฐ็ Appใ็ถฒๅ๏ผ%s
+auths.tip.facebook=่จปๅๆฐ็ๆ็จ็จๅผไธฆๆฐๅข็ขๅใFacebook ็ปๅ
ฅใใ็ถฒๅ๏ผ%s
+auths.tip.github=่จปๅๆฐ็ OAuth ๆ็จ็จๅผใ็ถฒๅ๏ผ%s
auths.tip.gitlab=่จปๅๆฐ็ๆ็จ็จๅผใ็ถฒๅ๏ผhttps://gitlab.com/profile/applications
-auths.tip.google_plus=ๅพ Google API ๆงๅถๅฐๅๅพ OAuth2 ็จๆถ็ซฏๆ่ญใ็ถฒๅ๏ผhttps://console.developers.google.com/
+auths.tip.google_plus=ๅพ Google API ๆงๅถๅฐๅๅพ OAuth2 ไฝฟ็จ่
็ซฏๆ่ญใ็ถฒๅ๏ผ%s
auths.tip.openid_connect=ไฝฟ็จ OpenID ้ฃๆฅๆข็ดข URL (/.well-known/openid-configuration) ไพๆๅฎ็ฏ้ป
-auths.tip.twitter=ๅปบ็ซๆ็จ็จๅผไธฆ็ขบไฟๆๅ็จใAllow this application to be used to Sign in with Twitterใใ็ถฒๅ๏ผhttps://dev.twitter.com/apps
-auths.tip.discord=่จปๅๆฐ็ๆ็จ็จๅผใ็ถฒๅ๏ผhttps://discordapp.com/developers/applications/me
-auths.tip.yandex=ๅจ https://oauth.yandex.com/client/new ๅปบ็ซๆฐ็ๆ็จ็จๅผใ่ซๅจใYandex.Passport APIใๅๅก้ธๆ้ธๆไธๅๆฌ้๏ผใAccess to email addressใใใAccess to user avatarใๅใAccess to username, first name and surname, genderใ
+auths.tip.twitter=ๅๅพ %s๏ผๅปบ็ซๆ็จ็จๅผไธฆ็ขบไฟๅ็จไบใๅ
่จฑๆญคๆ็จ็จๅผ็จๆผไฝฟ็จ Twitter ็ปๅ
ฅใ้ธ้
+auths.tip.discord=ๅจ %s ไธ่จปๅๆฐๆ็จ็จๅผ
+auths.tip.yandex=ๅจ %s ๅปบ็ซๆฐ็ๆ็จ็จๅผใ่ซๅจใYandex.Passport APIใๅๅก้ธๆ้ธๆไธๅๆฌ้๏ผใAccess to email addressใใใAccess to user avatarใๅใAccess to username, first name and surname, genderใ
auths.tip.mastodon=่ผธๅ
ฅๆจๆณ็จไพ่ช่ญ็ Mastodon ็ซ้ป็่ช่จ็ถฒๅ๏ผๆไฝฟ็จ้ ่จญๅผ๏ผ
-auths.edit=ไฟฎๆน่ช่ญไพๆบ
+auths.edit=็ทจ่ผฏ่ช่ญไพๆบ
auths.activated=่ฉฒ่ช่ญไพๆบๅทฒๅ็จ
auths.new_success=ๅทฒๆฐๅข่ช่ญใ%sใใ
auths.update_success=ๅทฒๆดๆฐ่ช่ญไพๆบใ
@@ -3089,28 +3317,28 @@ config.app_name=็ซ้ปๆจ้ก
config.app_ver=Forgejo ็ๆฌ
config.app_url=Forgejo ๅบๅบ URL
config.custom_conf=่จญๅฎๆช่ทฏๅพ
-config.custom_file_root_path=่ช่จๆชๆกๆ น็ฎ้
+config.custom_file_root_path=่ช่จๆชๆกๆ น่ทฏๅพ
config.domain=ไผบๆๅจๅๅ
config.offline_mode=ๆฌๅฐๆจกๅผ
-config.disable_router_log=้้่ทฏ็ฑๆฅ่ช
+config.disable_router_log=ๅ็จ่ทฏ็ฑๆฅ่ช
config.run_user=ไปฅไฝฟ็จ่
ๅ็จฑๅท่ก
config.run_mode=ๅท่กๆจกๅผ
config.git_version=Git ็ๆฌ
-config.repo_root_path=ๅฒๅญๅบซ็ฎ้
-config.lfs_root_path=LFS ๆ น็ฎ้
+config.repo_root_path=ๅฒๅญๅบซๆ น่ทฏๅพ
+config.lfs_root_path=LFS ๆ น่ทฏๅพ
config.log_file_root_path=ๆฅ่ช่ทฏๅพ
config.script_type=่
ณๆฌ้กๅ
-config.reverse_auth_user=ๅๅไปฃ็่ช่ญ
+config.reverse_auth_user=ๅๅไปฃ็่ช่ญไฝฟ็จ่
config.ssh_config=SSH ่จญๅฎ
config.ssh_enabled=ๅทฒๅ็จ
-config.ssh_start_builtin_server=ไฝฟ็จๅ
งๅปบ็ไผบๆๅจ
+config.ssh_start_builtin_server=ไฝฟ็จๅ
งๅปบไผบๆๅจ
config.ssh_domain=SSH ไผบๆๅจๅๅ
config.ssh_port=้ฃๆฅๅ
config.ssh_listen_port=็ฃ่ฝๅ
config.ssh_root_path=ๆ น่ทฏๅพ
config.ssh_key_test_path=้้ฐๆธฌ่ฉฆ่ทฏๅพ
-config.ssh_keygen_path=้้ฐ็ข็ (' ssh-keygen ') ่ทฏๅพ
+config.ssh_keygen_path=้้ฐ็ข็๏ผssh-keygen๏ผ่ทฏๅพ
config.ssh_minimum_key_size_check=้้ฐๆๅฐๅคงๅฐๆชขๆฅ
config.ssh_minimum_key_sizes=้้ฐๆๅฐๅคงๅฐ
@@ -3119,7 +3347,7 @@ config.lfs_enabled=ๅทฒๅ็จ
config.lfs_content_path=LFS ๅ
งๅฎน่ทฏๅพ
config.lfs_http_auth_expiry=LFS HTTP ้ฉ่ญๆๆๆ้
-config.db_config=่ณๆๅบซ่จญๅฎ
+config.db_config=่ณๆๅบซ็ตๆ
config.db_type=่ณๆๅบซ้กๅ
config.db_host=ไธปๆฉๅฐๅ
config.db_name=ๅ็จฑ
@@ -3130,19 +3358,19 @@ config.db_path=่ณๆๅบซ่ทฏๅพ
config.service_config=ๆๅ่จญๅฎ
config.register_email_confirm=่ฆๆฑ่จปๅๆ็ขบ่ช้ปๅญ้ตไปถ
-config.disable_register=้้่จปๅๅ่ฝ
+config.disable_register=ๅ็จ่ชๅฉ่จปๅ
config.allow_only_internal_registration=ๅชๅ
่จฑๅพ Forgejo ่จปๅ
config.allow_only_external_registration=ๅชๅ
่จฑๅพๅค้จๆๅ่จปๅ
-config.enable_openid_signup=ๅ็จ OpenID ่จปๅ
+config.enable_openid_signup=ๅ็จ OpenID ่ชๅฉ่จปๅ
config.enable_openid_signin=ๅ็จ OpenID ็ปๅ
ฅ
config.show_registration_button=้กฏ็คบ่จปๅๆ้
-config.require_sign_in_view=้่ฆ็ปๅ
ฅๆ่ฝ็่ฆฝ้ ้ข
-config.mail_notify=ๅ็จ้ตไปถ้็ฅ
+config.require_sign_in_view=้่ฆ็ปๅ
ฅๆ่ฝ็่ฆฝๅ
งๅฎน
+config.mail_notify=ๅ็จ้ปๅญ้ตไปถ้็ฅ
config.enable_captcha=ๅ็จ้ฉ่ญ็ขผ
-config.active_code_lives=ๅ็จ็จๆถ้ฃ็ตๆๆๆ
+config.active_code_lives=ๅๅ็ขผ้ๆๆ้
config.reset_password_code_lives=ๅธณ่ๅพฉๅ็ขผๆๆๆ้
config.default_keep_email_private=้ ่จญ้ฑ่้ปๅญไฟก็ฎฑ
-config.default_allow_create_organization=้ ่จญๅ
่จฑๆฐๅข็ต็น
+config.default_allow_create_organization=้ ่จญๅ
่จฑๅปบ็ซ็ต็น
config.enable_timetracking=ๅ็จๆ้่ฟฝ่นค
config.default_enable_timetracking=้ ่จญๅ็จๆ้่ฟฝ่นค
config.default_allow_only_contributors_to_track_time=ๅช่ฎ่ฒข็ป่
่ฟฝ่นคๆ้
@@ -3171,7 +3399,7 @@ config.mailer_use_dummy=Dummy
config.test_email_placeholder=้ปๅญไฟก็ฎฑ (ไพ๏ผtest@example.com)
config.send_test_mail=ๅฏ้ๆธฌ่ฉฆ้ตไปถ
config.test_mail_failed=ๅณ้ๆธฌ่ฉฆ้ตไปถ่ณใ%sใๆๅคฑๆ๏ผ %v
-config.test_mail_sent=ๆธฌ่ฉฆ้ตไปถๅทฒๅณ้่ณใ%sใใ
+config.test_mail_sent=ๅทฒๅณ้ๆธฌ่ฉฆ้ตไปถ่ณใ%sใใ
config.oauth_config=OAuth ่จญๅฎ
config.oauth_enabled=ๅ็จๆๅ
@@ -3179,7 +3407,7 @@ config.oauth_enabled=ๅ็จๆๅ
config.cache_config=ๅฟซๅ่จญๅฎ
config.cache_adapter=ๅฟซๅ่ฝๆฅๅจ๏ผadapter๏ผ
config.cache_interval=ๅฟซๅ้ฑๆ
-config.cache_conn=Cache ้ฃๆฅๅญ็ฌฆไธฒ
+config.cache_conn=ๅฟซๅ้ฃๆฅ
config.cache_item_ttl=ๅฟซๅ้
็ฎ TTL
config.session_config=Session ่จญๅฎ
@@ -3204,7 +3432,7 @@ config.git_max_diff_files=ๅทฎ็ฐๆฏ่ผๆ้กฏ็คบ็ๆๅคๆชๆกๆธ
config.git_gc_args=GC ๅๆธ
config.git_migrate_timeout=้ท็งป้พๆ
config.git_mirror_timeout=้กๅๆดๆฐ้พๆ
-config.git_clone_timeout=Clone ไฝๆฅญ้พๆ
+config.git_clone_timeout=ๆ่ฃฝ้พๆ
config.git_pull_timeout=Pull ไฝๆฅญ้พๆ
config.git_gc_timeout=GC ไฝๆฅญ้พๆ
@@ -3216,7 +3444,7 @@ config.xorm_log_sql=่จ้ SQL
config.set_setting_failed=ๅฏซๅ
ฅ่จญๅฎๅผ %s ๅคฑๆ
-monitor.cron=Cron ไปปๅ
+monitor.cron=ๅฎๆไปปๅ
monitor.name=ๅ็จฑ
monitor.schedule=ไปปๅๅฎๆ
monitor.next=ไธๆฌกๅท่กๆ้
@@ -3249,7 +3477,7 @@ monitor.queue.settings.submit=ๆดๆฐ่จญๅฎ
monitor.queue.settings.changed=ๅทฒๆดๆฐ่จญๅฎ
notices.system_notice_list=็ณป็ตฑๆ็คบ
-notices.view_detail_header=ๆฅ็ๆ็คบ็ดฐ็ฏ
+notices.view_detail_header=ๆ็คบ่ฉณๆ
notices.operations=ๆไฝ
notices.select_all=ๅ
จ้จ้ธๅ
notices.deselect_all=ๅๆถๆๆ้ธๅ
@@ -3276,17 +3504,61 @@ monitor.stats = ็ตฑ่จ่ณๆ
self_check.no_problem_found = ๆช็ผ็พไปปไฝๅ้กใ
config.send_test_mail_submit = ๅฏ้
users.details = ไฝฟ็จ่
่ฉณ็ดฐ่ณ่จ
-assets = ็จๅผ็ขผ่ณๆ
-dashboard.sync_branch.started = ๅทฒ้ๅงๅๆญฅๅๆฏ
+assets = ็จๅผ็ขผ่ณ็ข
+dashboard.sync_branch.started = ๅๆฏๅๆญฅๅทฒ้ๅง
dashboard.rebuild_issue_indexer = ้ๅปบๅ้ก็ดขๅผ
repos.lfs_size = LFS ๅคงๅฐ
-packages.cleanup = ๆธ
้ค้ๆ่ณๆ
+packages.cleanup = ๆธ
้ค้ๆ็่ณๆ
packages.cleanup.success = ๅทฒๆๅๆธ
้ค้ๆ่ณๆ
monitor.processes_count = %d ๅ็จๅบ
monitor.queue.settings.remove_all_items = ๅ
จ้จ็งป้ค
-identity_access = ่บซๅๅๅญๅๆฌ้
+identity_access = ่บซๅๅๅญๅ
+config.cache_test = ๆธฌ่ฉฆๅฟซๅ
+config_settings = ่จญๅฎ
+config_summary = ๆฆ่ฆ
+emails.delete = ๅช้ค้ปๅญ้ตไปถ
+dashboard.sync_tag.started = ๆจ็ฑคๅๆญฅๅทฒ้ๅง
+users.reserved = ๅทฒไฟ็
+auths.tips.gmail_settings = Gmail ่จญๅฎ๏ผ
+config.app_data_path = ๆ็จ็จๅผ่ณๆ่ทฏๅพ
+integrations = ๆดๅ
+emails.delete_primary_email_error = ไฝ ็กๆณๅช้คไธป่ฆ้ปๅญ้ตไปถใ
+emails.deletion_success = ่ฉฒ้ปๅญ้ตไปถๅฐๅๅทฒ่ขซๅช้คใ
+emails.delete_desc = ไฝ ็ขบๅฎไฝ ่ฆๅช้คๆญค้ปๅญ้ตไปถๅฐๅๅ๏ผ
+dashboard.start_schedule_tasks = ้ๅง่จๅ Actions ไปปๅ
+auths.default_domain_name = ็จๆผ้ปๅญ้ตไปถๅฐๅ็้ ่จญๅๅ
+users.organization_creation.description = ๅ
่จฑๅปบ็ซๆฐ็ต็นใ
+config.app_slogan = ็ซ้ปๅฃ่
+self_check = ่ชๅฉๆชขๆฅ
+config.logger_name_fmt = ๆฅ่ช๏ผ%s
+monitor.queue.review_add = ๅฏฉ้ฑ๏ผๅขๅ Worker
+self_check.database_fix_mysql = ๅฐๆผ MySQL๏ผMariaDB ็ไฝฟ็จ่
๏ผไฝ ๅฏไปฅไฝฟ็จๅฝไปคใforgejo doctor convertใไพไฟฎๅพฉๆๅบ่ฆๅๅ้ก๏ผๆ่
ไฝ ไนๅฏไปฅๆๅ้้ใALTER ... COLLATE ...ใSQL ไฟฎๅพฉๅ้กใ
+monitor.duration = ๆ็บๆ้๏ผ็ง๏ผ
+systemhooks.desc = ็ถๆไบ Forgejo ไบไปถ่งธ็ผๆ๏ผWebhook ๆ่ชๅๅไผบๆๅจ็ผๅบ HTTP POST ่ซๆฑใๆญค่ๅฎ็พฉ็ Webhook ๅฐไฝ็จๆผ็ณป็ตฑไธ็ๆๆๅฒๅญๅบซ๏ผๅ ๆญค่ซ่ๆ
ฎ้ๅฏ่ฝ็ข็็ไปปไฝๆ่ฝๅฝฑ้ฟใๆดๅค่ณ่จ่ซๅ่Webhook ๆๅ ใ
+self_check.database_inconsistent_collation_columns = ่ณๆๅบซๆญฃๅจไฝฟ็จๆๅบ่ฆๅ %s๏ผไฝๆฏ้ไบๆฌไฝฟ็จ็ๆๅบ่ฆๅไธ็ธ็ฌฆใ้ๅฏ่ฝๆๅผ่ตทไธไบๆๆณไธๅฐ็ๅ้กใ
+users.block.description = ้ปๆญขๆญคไฝฟ็จ่
้้ๅ
ถๅธณ่่ๆญคๆๅไบๅไธฆ็ฆๆญข็ปๅ
ฅใ
+auths.tip.gitlab_new = ๅจ %s ไธ่จปๅๆฐๆ็จ็จๅผ
+config.cache_test_succeeded = ๅฟซๅๆธฌ่ฉฆๆๅ๏ผๅจ %s ๅ
งๆถๅฐๅๆใ
+config.cache_test_failed = ็กๆณๆขๆธฌๅฟซๅ๏ผ%vใ
+self_check.database_collation_case_insensitive = ่ณๆๅบซๆญฃๅจไฝฟ็จๆๅบ่ฆๅ %s๏ผ้ๆฏไธ็จฎไธๆๆ็ๆๅบ่ฆๅใ้็ถ Forgejo ๅฏไปฅ่ๅ
ถ้
ๅไฝฟ็จ๏ผไฝๆฏๅจไธไบ็ฝ่ฆๆ
ๆณไธๅฏ่ฝๆๅบ็พ็กๆณๅฆ้ ๆ้ไฝ็ๆ
ๆณใ
+config.open_with_editor_app_help = ๆ่ฃฝ้ธๅฎไธญ็ใ้ๅๆนๅผใ็ทจ่ผฏๅจใๅฆๆ็็ฉบๅๅฐไฝฟ็จ้ ่จญๅผใๅฑ้ไปฅๆฅ็้ ่จญๅผใ
+dashboard.sync_repo_tags = ๅฐๆจ็ฑคๅพ Git ่ณๆๅๆญฅ่ณ่ณๆๅบซ
+self_check.database_collation_mismatch = ๆๆ่ณๆๅบซไฝฟ็จ็ๆๅบ่ฆๅ๏ผ%s
+config.allow_dots_in_usernames = ๅ
่จฑไฝฟ็จ่
ๅจไฝฟ็จ่
ๅ็จฑไธญไฝฟ็จ้ปใไธๆๅฝฑ้ฟ็พๆๅธณ่ใ
+dashboard.sync_repo_branches = ๅฐ็ผบๅฐ็ๅๆฏๅพ Git ่ณๆๅๆญฅ่ณ่ณๆๅบซ
+defaulthooks.desc = ็ถๆไบ Forgejo ไบไปถ่งธ็ผๆ๏ผWebhook ๆ่ชๅๅไผบๆๅจ็ผๅบ HTTP POST ่ซๆฑใๆญค่ๅฎ็พฉ็ Webhook ๆฏ้ ่จญ็๏ผๅฐ่ค่ฃฝ่ณๆๆๆฐ็ๅฒๅญๅบซไธญใๆดๅค่ณ่จ่ซๅ่Webhook ๆๅ ใ
+users.local_import.description = ๅ
่จฑๅพไผบๆๅจ็ๆฌๆฉๆชๆก็ณป็ตฑๅฏๅ
ฅๅฒๅญๅบซใ้ๅฏ่ฝๆฏๅๅฎๅ
จๅ้กใ
+config.cache_test_slow = ๅฟซๅๆธฌ่ฉฆๆๅ๏ผไฝๆฏๅๆๅพๆ
ข๏ผ%sใ
+users.activated.description = ๅฎๆ้ปๅญ้ตไปถ้ฉ่ญใๆชๅๅๅธณ่็ๆๆ่
ๅฐ็กๆณ็ปๅ
ฅ๏ผ็ด่ณ้ปๅญ้ตไปถ้ฉ่ญๅฎๆใ
+auths.tips.oauth2.general.tip = ็ถ่จปๅๆฐ็ OAuth2 ้ฉ่ญๆ๏ผๅๅผ๏ผ้ๆฐๅฐๅ็ถฒๅๆ่ฉฒๆฏ๏ผ
+users.restricted.description = ๅ
ๅ
่จฑ่ๅฐๆญคไฝฟ็จ่
ๆฐๅข็บๅไฝ่
็ๅฒๅญๅบซๅ็ต็น้ฒ่กไบๅใ้ๆ้ปๆญขๅญๅๆญค็ซ้ปไธ็ๅ
ฌๅ
ฑๅฒๅญๅบซใ
+users.admin.description = ๆไบๆญคไฝฟ็จ่
้้็ถฒ้ ไป้ขๅ API ๆไพ็ๆๆ็ฎก็ๅ่ฝ็ๅฎๅ
จๅญๅๆฌใ
+auths.tip.gitea = ่จปๅไธๅๆฐ็ OAuth2 ๆ็จ็จๅผใๆๅๅฏๅจ %s ๆพๅฐ
+monitor.queue.activeworkers = ๆดป่บๅทฅไฝ่
+monitor.queue.settings.desc = ้ๅๆๆ นๆๅทฅไฝ่
ไฝๅ็้ปๅกๆ
ๆณๅๆ
ๅข้ทใ
+
[action]
create_repo=ๅปบ็ซไบๅฒๅญๅบซ %s
rename_repo=้ๆฐๅฝๅๅฒๅญๅบซ %[1]s
็บ %[3]s
@@ -3310,7 +3582,7 @@ compare_commits=ๆฏ่ผ %d ๅๆไบค
compare_commits_general=ๆฏ่ผๆไบค
mirror_sync_push=ๅพ้กๅๅๆญฅไบๆไบคๅฐ %[4]s ็ %[3]s
mirror_sync_create=ๅพ้กๅๅๆญฅไบๆฐๅ่ %[3]s ๅฐ %[4]s
-mirror_sync_delete=ๅพ้กๅๅๆญฅไธฆๅพ %[3]s ๅช้คไบๅ่ %[2]s
+mirror_sync_delete=ๅทฒๅพ้กๅๅๆญฅไธฆๅพ %[3]s ๅช้คไบๅ่ %[2]s
approve_pull_request=`ๆ ธๅฏไบ %[3]s#%[2]s `
reject_pull_request=`ๆๅบไบไฟฎๆนๅปบ่ญฐ %[3]s#%[2]s `
publish_release=`็ผๅธไบ %[3]s ็ "%[4]s" `
@@ -3380,7 +3652,7 @@ error.unit_not_allowed=ๆจๆช่ขซๅ
่จฑๅญๅๆญคๅฒๅญๅบซๅๅใ
title=่ป้ซๅ
desc=็ฎก็ๅฒๅญๅบซ่ป้ซๅ
ใ
empty=็ฎๅ้ๆฒๆ่ป้ซๅ
ใ
-empty.documentation=้ๆผ่ป้ซๅ
่จปๅไธญๅฟ็่ฉณๆ
่ซๅ้ฑ่ชชๆๆไปถ ใ
+empty.documentation=้ๆผ่ป้ซๅ
่จปๅไธญๅฟ็่ฉณๆ
่ซๅ้ฑๆไปถ ใ
empty.repo=ๅทฒ็ถไธๅณไบไธๅ่ป้ซๅ
๏ผไฝๆฏๅฎไธๅจ้่ฃกๅ๏ผ้ ่จช่ป้ซๅ
่จญๅฎ ไธฆๅฐๅ
ถ้ฃ็ตๅฐ้ๅๅฒๅญๅบซใ
filter.type=้กๅ
filter.type.all=ๆๆ
@@ -3429,9 +3701,9 @@ conda.install=ๅท่กไธๅๅฝไปคไปฅไฝฟ็จ Conda ๅฎ่ฃๆญค่ป้ซๅ
๏ผ
container.details.type=ๆ ๅๆช้กๅ
container.details.platform=ๅนณๅฐ
container.pull=้้ไธๅๅฝไปคๆๅๆ ๅๆช๏ผ
-container.digest=ๆ่ฆ:
+container.digest=ๆ่ฆ
container.multi_arch=ไฝๆฅญ็ณป็ตฑ / ๆถๆง
-container.layers=ๆ ๅๆช Layers
+container.layers=ๆ ๅๆชๅๅฑค
container.labels=ๆจ็ฑค
container.labels.key=้ต
container.labels.value=ๅผ
@@ -3455,7 +3727,7 @@ npm.install=ๅท่กไธๅๅฝไปคไปฅไฝฟ็จ npm ๅฎ่ฃๆญค่ป้ซๅ
๏ผ
npm.install2=ๆๅฐๅฎๅ ๅฐ package.json ๆช๏ผ
npm.dependencies=็ธไพๆง
npm.dependencies.development=้็ผ็ธไพๆง
-npm.dependencies.peer=Peer ็ธไพๆง
+npm.dependencies.peer=ๅ่ก็ธไพๆง
npm.dependencies.optional=้ธ็จ็ธไพๆง
npm.details.tag=ๆจ็ฑค
pub.install=ๅท่กไธๅๅฝไปคไปฅไฝฟ็จ Dart ๅฎ่ฃๆญค่ป้ซๅ
๏ผ
@@ -3493,7 +3765,7 @@ owner.settings.cargo.initialize.success=ๆๅๅปบ็ซไบ Cargo ็ดขๅผใ
owner.settings.cargo.rebuild=้ๅปบ็ดขๅผ
owner.settings.cargo.rebuild.error=้ๅปบ Cargo ็ดขๅผๅคฑๆ: %v
owner.settings.cargo.rebuild.success=ๆๅ้ๅปบไบ Cargo ็ดขๅผใ
-owner.settings.cleanuprules.title=็ฎก็ๆธ
็่ฆๅ
+owner.settings.cleanuprules.title=ๆธ
็่ฆๅ
owner.settings.cleanuprules.add=ๅ ๅ
ฅๆธ
็่ฆๅ
owner.settings.cleanuprules.edit=็ทจ่ผฏๆธ
็่ฆๅ
owner.settings.cleanuprules.preview=้ ่ฆฝๆธ
็่ฆๅ
@@ -3517,6 +3789,42 @@ owner.settings.chef.keypair=็ข็ๅฏ้ฐ็ต
debian.repository.components = ๅ
ไปถ
go.install = ไฝฟ็จๅฝไปคๅๅฎ่ฃ่ป้ซๅ
๏ผ
owner.settings.cleanuprules.none = ็ฎๅๆฒๆไปปไฝๆธ
็่ฆๅใ
+arch.version.description = ๆ่ฟฐ
+arch.version.properties = ็ๆฌๅฑฌๆง
+arch.version.backup = ๅไปฝ
+arch.version.conflicts = ่ก็ช
+npm.dependencies.bundle = ๅทฒๆ็ถ็ธไพๆง
+arch.version.provides = ๆไพ
+arch.pacman.repo.multi.item = %s ็็ตๆ
+arch.version.replaces = ๅไปฃ
+arch.version.checkdepends = ๆชขๆฅไพ่ณด
+arch.version.optdepends = ้ธๆๆงไพ่ณด
+arch.version.depends = ไพ่ณด
+owner.settings.cargo.rebuild.no_index = ็กๆณ้ๅปบ๏ผๆชๅๅงๅไปปไฝ็ดขๅผใ
+cran.registry = ๅจไฝ ็ Rprofile.site
ๆชๆกไธญ่จญๅฎๆญค่จปๅ่กจ๏ผ
+debian.repository.distributions = ็ผ่ก็
+owner.settings.chef.keypair.description = ้่ฆ้้ฐๅฐๆ่ฝๅ Chef ่จปๅ่กจ้ฒ่ก่บซไปฝ้ฉ่ญใๅฆๆไฝ ไนๅๅทฒ็ถ็ข็้้้ฐๅฐ๏ผ็ข็ๆฐ็้้ฐๅฐๅฐๆไธๆฃ่็้้ฐๅฐใ
+owner.settings.cargo.initialize.description = ไฝฟ็จ Cargo ่จปๅ่กจ้่ฆไธๅ็นๆฎ็็ดขๅผ Git ๅฒๅญๅบซใไฝฟ็จๆญค้ธ้
ๅฐๆ๏ผ้ๆฐ๏ผๅปบ็ซๅฒๅญๅบซไธฆ่ชๅ้
็ฝฎๅฎใ
+rpm.repository.multiple_groups = ๆญคๅฅไปถๅฏไปฅๅจๅคๅ็พค็ตไธญไฝฟ็จใ
+rpm.distros.suse = ๅจๅบๆผ SUSE ็็ผ่ก็ไธ
+rpm.distros.redhat = ๅจๅบๆผ RedHat ็็ผ่ก็ไธ
+owner.settings.cargo.rebuild.description = ๅฆๆ็ดขๅผ่ๅฒๅญ็ Cargo ๅฅไปถไธๅๆญฅ๏ผ้ๅปบๅฏ่ฝๆๅพๆ็จใ
+arch.version.groups = ็พค็ต
+alt.repository.architectures = ๆถๆง
+alt.repository = ๅฒๅญๅบซ่ณ่จ
+arch.pacman.helper.gpg = ็บ pacman ๆฐๅขไฟกไปปๆ่ญ๏ผ
+search_in_external_registry = ๅจ %s ไธญๆๅฐ
+debian.registry.info = ๅพไธ้ข็ๆธ
ๅฎไธญ้ธๆ $distribution ๅ $componentใ
+arch.pacman.conf = ๅฐ็ธ้็ผ่ก็ๅๆถๆง็ไผบๆๅจๆฐๅข่ณ /etc/pacman.conf
๏ผ
+arch.pacman.sync = ไฝฟ็จ pacman ๅๆญฅ่ป้ซๅ
๏ผ
+arch.pacman.repo.multi = %s ๅจไธๅ็็ผ่ก็ไธญๅ
ทๆ็ธๅ็็ๆฌใ
+container.images.title = ๆ ๅๆช
+alt.registry = ๅพๅฝไปคๅ่จญๅฎๆญค่จปๅ่กจ๏ผ
+alt.install = ๅฎ่ฃ่ป้ซๅ
+registry.documentation = ๆ้ %s ่จปๅ่กจ็ๆดๅค่ณ่จ๏ผ่ซๅ้ฑๆไปถ ใ
+alt.registry.install = ่ฅ่ฆๅฎ่ฃ่ป้ซๅ
๏ผๅท่กไปฅไธๅฝไปค๏ผ
+alt.repository.multiple_groups = ๆญค่ป้ซๅ
ๅจๅคๅ็พค็ตไธญๅฏ็จใ
+alt.setup = ๆฐๅขๅฒๅญๅบซ่ณๅทฒ้ฃๆฅ็ๅฒๅญๅบซๆธ
ๅฎ๏ผ้ธๆๅฟ
่ฆ็ๆถๆง็ตๆง่้ใ_arch_ใ๏ผ๏ผ
[secrets]
secrets=Secret
@@ -3531,11 +3839,12 @@ deletion=็งป้ค Secret
deletion.description=็งป้ค Secret ๆฏๆฐธไน
็ไธไธๅฏ้ๅ๏ผๆฏๅฆ็นผ็บ๏ผ
deletion.success=ๅทฒ็งป้คๆญค Secretใ
deletion.failed=็งป้ค Secret ๅคฑๆใ
+management = ็ฎก็็งๅฏ
[actions]
actions=Actions
-unit.desc=็ฎก็ Actions
+unit.desc=ไฝฟ็จ Forgejo Actions ็ฎก็ๆดๅ็ CI/CD ็ฎก้ใ
status.unknown=ๆช็ฅ็
status.waiting=็ญๅพ
ไธญ
@@ -3543,10 +3852,10 @@ status.running=ๅท่กไธญ
status.success=ๆๅ
status.failure=ๅคฑๆ
status.skipped=ๅทฒ็ฅ้
-status.blocked=ๅทฒ้ปๅก
+status.blocked=ๅทฒ้ปๆญข
runners=Runner
-runners.runner_manage_panel=Runner ็ฎก็
+runners.runner_manage_panel=็ฎก็ Runner
runners.new=ๅปบ็ซ Runner
runners.new_notice=ๅฆไฝๅๅ Runner
runners.status=็ๆ
@@ -3605,7 +3914,7 @@ variables.creation = ๆฐๅข่ฎๆธ
variables.none = ็ฎๅๆฒๆ่ฎๆธใ
variables.deletion = ๅช้ค่ฎๆธ
variables.deletion.description = ๅช้ค่ฎๆธๆฏๆฐธไน
ไธไธๅฏๅๆถ็ใ่ฆ็นผ็บๅ๏ผ
-variables.creation.success = ่ฎๆธ ใ%sใๅทฒๆๅ่ขซๆฐๅขใ
+variables.creation.success = ๅทฒๆฐๅข่ฎๆธ ใ%sใใ
variables.update.failed = ็ทจ่ผฏ่ฎๆธๅคฑๆใ
runs.no_results = ๆฒๆ็ธ็ฌฆ็็ตๆใ
runs.no_workflows = ็ฎๅๆฒๆไปปไฝๅทฅไฝๆต็จใ
@@ -3616,20 +3925,40 @@ runs.empty_commit_message = ๏ผ็ฉบ็ฝ็ๆไบค่จๆฏ๏ผ
runners.task_list.no_tasks = ็ฎๅๆฒๆไปปไฝๅทฅไฝใ
workflow.disabled = ๅทฅไฝๆต็จๅทฒ่ขซๅ็จใ
status.cancelled = ๅทฒๅๆถ
+runs.workflow = ๅทฅไฝๆต็จ
+runs.actors_no_select = ๆๆๆไฝ่
+runs.actor = ๆไฝ่
+workflow.dispatch.input_required = ้่ฆ่ผธๅ
ฅใ%sใ็ๅผใ
+workflow.dispatch.run = ๅท่กๅทฅไฝๆต็จ
+workflow.dispatch.trigger_found = ๆญคๅทฅไฝๆต็จๆไธๅ workflow_dispatch ไบไปถ่งธ็ผๅจใ
+workflow.dispatch.invalid_input_type = ็กๆ็่ผธๅ
ฅ้กๅใ%sใใ
+workflow.dispatch.warn_input_limit = ๅ
้กฏ็คบๅ %d ๅ่ผธๅ
ฅใ
+runs.no_job = ๅทฅไฝๆต็จๅฟ
้ ๅ
ๅซ่ณๅฐไธ้
ไฝๆฅญ
+runs.expire_log_message = ๆฅ่ชๅทฒ่ขซๆธ
้ค๏ผๅ ็บๅฎๅๅคช่ไบใ
+runs.no_job_without_needs = ๅทฅไฝๆต็จๅฟ
้ ๅ
ๅซ่ณๅฐไธ้
ๆฒๆไพ่ณดๆง็ไฝๆฅญใ
+runs.no_matching_online_runner_helper = ๆฒๆๅจ็ท็ๅท่กๅจไธๅน้
ๆจ็ฑค๏ผ%s
+workflow.dispatch.success = ๅทฒๆๅ่ซๆฑๅทฅไฝๆต็จ้่กใ
+runs.no_workflows.documentation = ๆ้ Forgejo Actions ็ๆดๅค่ณ่จ๏ผ่ซๅ้ฑๆไปถ ใ
+runners.reset_registration_token = ้็ฝฎ่จปๅ็ฌฆ่จ
+workflow.dispatch.use_from = ไฝฟ็จๅทฅไฝๆต็จ่ช
+runs.no_workflows.help_no_write_access = ่ฆไบ่งฃ Forgejo Actions๏ผ่ซๅ้ฑๆไปถ ใ
+runs.no_workflows.help_write_access = ไธ็ฅ้ๅฆไฝ้ๅงไฝฟ็จ Forgejo Actions๏ผๆฅ็ไฝฟ็จ่
ๆไปถไธญ็ๅฟซ้ๅ
ฅ้ ไพ็ทจๅฏซไฝ ็็ฌฌไธๅๅทฅไฝๆต็จ๏ผ็ถๅพ่จญๅฎ Forgejo Runner ไพๅท่กไฝ ็ๅทฅไฝใ
+variables.not_found = ๆพไธๅฐ่ฎๆธใ
[projects]
type-2.display_name = ๅฒๅญๅบซๅฐๆก
type-1.display_name = ๅไบบๅฐๆก
type-3.display_name = ็ต็นๅฐๆก
+deleted.display_name = ๅทฒๅช้ค็ๅฐๆก
[git.filemode]
-; Ordered by git filemode value, ascending. E.g. directory has "040000", normal file has "100644", โฆ
symbolic_link=็ฌฆ่้ฃ็ต
changed_filemode = %[1]s โ %[2]s
submodule = ๅญๆจก็ต
normal_file = ไธ่ฌๆชๆก
executable_file = ๅฏๅท่กๆช
+directory = ็ฎ้
@@ -3653,4 +3982,35 @@ runner_kind = ๆๅฐ Runners โฆ
project_kind = ๆๅฐๅฐๆกโฆ
branch_kind = ๆๅฐๅๆฏโฆ
commit_kind = ๆๅฐๆไบคโฆ
-code_search_by_git_grep = ็ฎๅๆๅฐ็ตๆ็ฑใgit grepใๆไพใๅฆๆ็ถฒ็ซ็ฎก็ๅกๅ็จ็จๅผ็ขผ็ดขๅผ๏ผๅฏ่ฝๆๆๆดๅฅฝ็็ตๆใ
\ No newline at end of file
+code_search_by_git_grep = ็ฎๅๆๅฐ็ตๆ็ฑใgit grepใๆไพใๅฆๆ็ถฒ็ซ็ฎก็ๅกๅ็จ็จๅผ็ขผ็ดขๅผ๏ผๅฏ่ฝๆๆๆดๅฅฝ็็ตๆใ
+exact = ็ฒพ็ขบ
+milestone_kind = ๆๅฐ้็จ็ข...
+issue_kind = ๆๅฐๅ้กโฆ
+exact_tooltip = ๅชๅ
ๅซ่ๆๅฐ่ฉๅฎๅ
จ็ธ็ฌฆ็็ตๅ
+pull_kind = ๆๅฐๆๅโฆ
+regexp = ๆญฃ่ฆ่กจ็คบๅผ
+regexp_tooltip = ๅฐๆๅฐ่ฉ่งฃ้็บๆญฃ่ฆ่กจ็คบๅผ
+union = ้้ตๅญ
+union_tooltip = ๅ
ๅซ่ไปปไฝ็ฉบๆ ผๅ้็้้ตๅญ็ธ็ฌฆ็็ตๆ
+
+[munits.data]
+eib = EiB
+b = B
+kib = KiB
+mib = MiB
+gib = GiB
+tib = TiB
+pib = PiB
+
+[markup]
+filepreview.truncated = ้ ่ฆฝๅทฒ่ขซๆชๆท
+filepreview.lines = %[3]s ไธญ็็ฌฌ %[1]d ่ณ %[2]d ่ก
+filepreview.line = %[2]s ไธญ็็ฌฌ %[1]d ่ก
+
+[translation_meta]
+test = ๅฅฝ็
+
+
+[repo.permissions]
+ext_issues = ๅญๅๅค้จๅ้ก่ฟฝ่นคๅจ็้ฃ็ตใๆฌ้็ฑๅค้จ็ฎก็ใ
+ext_wiki = ๅญๅๅค้จ Wiki ็้ฃ็ตใๆฌ้็ฑๅค้จ็ฎก็ใ
\ No newline at end of file
diff --git a/options/locale/readme.md b/options/locale/readme.md
new file mode 100644
index 0000000000..f6f198a936
--- /dev/null
+++ b/options/locale/readme.md
@@ -0,0 +1,26 @@
+# Forgejo translations
+
+This directory contains all .INI translations.
+
+## Working on base language
+
+When you work on Forgejo features, you should only modify `locale_en-US.ini`.
+
+* consult https://forgejo.org/docs/next/contributor/localization-english/
+* add strings when your change requires doing so
+* remove strings when your change renders them unused
+
+## Working on other languages
+
+Translations are done on Codeberg Translate and not via individual pull requests.
+
+* consult https://forgejo.org/docs/next/contributor/localization/
+* see the project: https://translate.codeberg.org/projects/forgejo/forgejo/
+
+## Attribution
+
+Forgejo translators are attributed in commit messages and in monthly updates on the website.
+
+Gitea translators are mostly not attributed in this repository because Gitea translation commits are lacking attribution, but it may be preserved on Crowdin.
+
+This directory contains a legacy `TRANSLATORS` file from the Gogs era. It is opt-in and is not actively maintained.
diff --git a/options/locale_next/locale_ar.json b/options/locale_next/locale_ar.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_ar.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_be.json b/options/locale_next/locale_be.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_be.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_bg.json b/options/locale_next/locale_bg.json
new file mode 100644
index 0000000000..02144c8b38
--- /dev/null
+++ b/options/locale_next/locale_bg.json
@@ -0,0 +1,10 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "ัะปั %[1]d ะฟะพะดะฐะฒะฐะฝะต ะพั %[2]s
ะฒ %[3]s
%[4]s",
+ "other": "ัะปั %[1]d ะฟะพะดะฐะฒะฐะฝะธั ะพั %[2]s
ะฒ %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": "ะธัะบะฐ ะดะฐ ัะปะตะต %[1]d ะฟะพะดะฐะฒะฐะฝะต ะพั %[2]s
ะฒ %[3]s
",
+ "other": "ะธัะบะฐ ะดะฐ ัะปะตะต %[1]d ะฟะพะดะฐะฒะฐะฝะธั ะพั %[2]s
ะฒ %[3]s
"
+ }
+}
diff --git a/options/locale_next/locale_bn.json b/options/locale_next/locale_bn.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_bn.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_bs.json b/options/locale_next/locale_bs.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_bs.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_ca.json b/options/locale_next/locale_ca.json
new file mode 100644
index 0000000000..8eefc65a1a
--- /dev/null
+++ b/options/locale_next/locale_ca.json
@@ -0,0 +1,3 @@
+{
+ "search.milestone_kind": "Cerca fites..."
+}
diff --git a/options/locale_next/locale_cs-CZ.json b/options/locale_next/locale_cs-CZ.json
new file mode 100644
index 0000000000..6e1f48b82f
--- /dev/null
+++ b/options/locale_next/locale_cs-CZ.json
@@ -0,0 +1,23 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "slouฤil/a %[1]d revizi z vฤtve %[2]s
do vฤtve %[3]s
%[4]s",
+ "few": "slouฤil/a %[1]d revize z vฤtve %[2]s
do vฤtve %[3]s
pลed %[4]s",
+ "other": "slouฤil/a %[1]d revizรญ z vฤtve %[2]s
do vฤtve %[3]s
pลed %[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": "ลพรกdรก o slouฤenรญ %[1]d revize z vฤtve %[2]s
do vฤtve %[3]s
",
+ "few": "ลพรกdรก o slouฤenรญ %[1]d revizรญ z vฤtve %[2]s
do vฤtve %[3]s
",
+ "other": "ลพรกdรก o slouฤenรญ %[1]d revizรญ z vฤtve %[2]s
do vฤtve %[3]s
"
+ },
+ "search.milestone_kind": "Hledat milnรญkyโฆ",
+ "home.welcome.no_activity": "ลฝรกdnรก aktivita",
+ "home.welcome.activity_hint": "Vรกลก feed je zatรญm prรกzdnรฝ. Zde se budou zobrazovat vaลกe akce a aktivity z repozitรกลลฏ, kterรฉ sledujete.",
+ "home.explore_repos": "Prochรกzet repozitรกลe",
+ "home.explore_users": "Prochรกzet uลพivatele",
+ "home.explore_orgs": "Prochรกzet organizace",
+ "incorrect_root_url": "Tato instance Forgejo je nastavena tak, aby bฤลพela na adrese โ%sโ. Vy si momentรกlnฤ prohlรญลพรญte Forgejo na jinรฉ adrese, coลพ mลฏลพe zpลฏsobit rozbitรญ nฤkterรฝch ฤรกstรญ aplikace. Sprรกvnรก adresa je ovlรกdรกna sprรกvci Forgejo pomocรญ nastavenรญ ROOT_URL v souboru app.ini.",
+ "themes.names.forgejo-auto": "Forgejo (podle motivu systรฉmu)",
+ "themes.names.forgejo-light": "Forgejo โ svฤtlรฉ",
+ "themes.names.forgejo-dark": "Forgejo โ tmavรฉ",
+ "install.invalid_lfs_path": "Nepodaลilo se vytvoลit koลen LFS na zvolenรฉ cestฤ: %[1]s"
+}
diff --git a/options/locale_next/locale_da.json b/options/locale_next/locale_da.json
new file mode 100644
index 0000000000..2a9381e290
--- /dev/null
+++ b/options/locale_next/locale_da.json
@@ -0,0 +1,23 @@
+{
+ "search.milestone_kind": "Sรธg milepรฆleโฆ",
+ "repo.pulls.title_desc": {
+ "one": "รธnsker at flette %[1]d commit fra %[2]s
til %[3]s
",
+ "other": "รธnsker at flette %[1]d commits fra %[2]s
til %[3]s
"
+ },
+ "repo.pulls.merged_title_desc": {
+ "one": "flettet %[1]d commit fra %[2]s
til %[3]s
%[4]s",
+ "other": "flettet %[1]d commits fra %[2]s
til %[3]s
%[4]s"
+ },
+ "incorrect_root_url": "Denne Forgejo-instans er konfigureret til at blive serveret pรฅ \"%s\". Du ser i รธjeblikket Forgejo gennem en anden URL, hvilket kan fรฅ dele af applikationen til at gรฅ i stykker. Den kanoniske URL styres af Forgejo-administratorer via indstillingen ROOT_URL i app.ini.",
+ "home.welcome.no_activity": "Ingen aktivitet",
+ "home.welcome.activity_hint": "Der er intet i dit feed endnu. Dine handlinger og aktivitet fra depoterne, som du ser, vises her.",
+ "home.explore_repos": "Udforsk depoter",
+ "home.explore_users": "Udforsk brugere",
+ "home.explore_orgs": "Udforsk organisationer",
+ "themes.names.forgejo-light": "Forgejo lys",
+ "themes.names.forgejo-dark": "Forgejo mรธrk",
+ "themes.names.forgejo-auto": "Forgejo (fรธlg systemtema)",
+ "settings.adopt": "Adoptere",
+ "install.invalid_lfs_path": "Kan ikke oprette LFS-roden pรฅ den angivne sti: %[1]s",
+ "install.lfs_jwt_secret_failed": "Kan ikke generere en LFS JWT-hemmelighed: %[1]s"
+}
diff --git a/options/locale_next/locale_de-DE.json b/options/locale_next/locale_de-DE.json
new file mode 100644
index 0000000000..82e0b309e2
--- /dev/null
+++ b/options/locale_next/locale_de-DE.json
@@ -0,0 +1,21 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "hat %[1]d Commit von %[2]s
nach %[3]s
%[4]s zusammengefรผhrt",
+ "other": "hat %[1]d Commits von %[2]s
nach %[3]s
%[4]s zusammengefรผhrt"
+ },
+ "repo.pulls.title_desc": {
+ "one": "mรถchte %[1]d Commit von %[2]s
nach %[3]s
zusammenfรผhren",
+ "other": "mรถchte %[1]d Commits von %[2]s
nach %[3]s
zusammenfรผhren"
+ },
+ "search.milestone_kind": "Meilensteine suchen โฆ",
+ "home.welcome.no_activity": "Keine Aktivitรคt",
+ "home.explore_repos": "Repositorys erkunden",
+ "home.explore_users": "Benutzer erkunden",
+ "home.explore_orgs": "Organisationen erkunden",
+ "home.welcome.activity_hint": "Es gibt noch nichts in deinem Feed. Deine Aktionen und Aktivitรคten aus Repositorys, die du beobachtest, werden hier auftauchen.",
+ "incorrect_root_url": "Diese Forgejo-Instanz ist konfiguriert, auf โ%sโ bereitgestellt zu werden. Du rufst Forgejo รผber einen anderen URL auf, was dazu fรผhren kรถnnte, dass einige Bereiche nicht funktionieren. Der anerkannte URL wird durch die Forgejo-Admins mittels der Einstellung ROOT_URL in der app.ini kontrolliert.",
+ "themes.names.forgejo-auto": "Forgejo (folge Systemthema)",
+ "themes.names.forgejo-light": "Forgejo hell",
+ "themes.names.forgejo-dark": "Forgejo dunkel",
+ "install.invalid_lfs_path": "Der LFS-Root konnte nicht am angegebenen Pfad erstellt werden: %[1]s"
+}
diff --git a/options/locale_next/locale_el-GR.json b/options/locale_next/locale_el-GR.json
new file mode 100644
index 0000000000..3cc62b4a43
--- /dev/null
+++ b/options/locale_next/locale_el-GR.json
@@ -0,0 +1,11 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮต %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮฑฯฯ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[2]s
ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[3]s
%[4]s",
+ "other": "ฯฯ
ฮณฯฯฮฝฮตฯ
ฯฮต %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮฑฯฯ %[2]s
ฯฮต %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": ": ฮธฮฑ ฮฎฮธฮตฮปฮต ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฮน %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮฎ ฮฑฯฯ ฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[2]s
ฯฯฮฟฮฝ ฮบฮปฮฌฮดฮฟ %[3]s
",
+ "other": "ฮธฮญฮปฮตฮน ฮฝฮฑ ฯฯ
ฮณฯฯฮฝฮตฯฯฮตฮน %[1]d ฯ
ฯฮฟฮฒฮฟฮปฮญฯ ฮฑฯฯ %[2]s
ฯฮต %[3]s
"
+ },
+ "search.milestone_kind": "ฮฮฝฮฑฮถฮฎฯฮทฯฮท ฮฟฯฯฯฮทฮผฯฮฝ..."
+}
diff --git a/options/locale_next/locale_en-US.json b/options/locale_next/locale_en-US.json
new file mode 100644
index 0000000000..4f3c65a68f
--- /dev/null
+++ b/options/locale_next/locale_en-US.json
@@ -0,0 +1,23 @@
+{
+ "home.welcome.no_activity": "No activity",
+ "home.welcome.activity_hint": "There is nothing in your feed yet. Your actions and activity from repositories that you watch will show up here.",
+ "home.explore_repos": "Explore repositories",
+ "home.explore_users": "Explore users",
+ "home.explore_orgs": "Explore organizations",
+ "repo.pulls.merged_title_desc": {
+ "one": "merged %[1]d commit from %[2]s
into %[3]s
%[4]s",
+ "other": "merged %[1]d commits from %[2]s
into %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": "wants to merge %[1]d commit from %[2]s
into %[3]s
",
+ "other": "wants to merge %[1]d commits from %[2]s
into %[3]s
"
+ },
+ "search.milestone_kind": "Search milestonesโฆ",
+ "incorrect_root_url": "This Forgejo instance is configured to be served on \"%s\". You are currently viewing Forgejo through a different URL, which may cause parts of the application to break. The canonical URL is controlled by Forgejo admins via the ROOT_URL setting in the app.ini.",
+ "themes.names.forgejo-auto": "Forgejo (follow system theme)",
+ "themes.names.forgejo-light": "Forgejo light",
+ "themes.names.forgejo-dark": "Forgejo dark",
+ "settings.adopt": "Adopt",
+ "install.invalid_lfs_path": "Unable to create the LFS root at the specified path: %[1]s",
+ "install.lfs_jwt_secret_failed": "Unable to generate a LFS JWT secret: %[1]s"
+}
diff --git a/options/locale_next/locale_eo.json b/options/locale_next/locale_eo.json
new file mode 100644
index 0000000000..1f4124b2ea
--- /dev/null
+++ b/options/locale_next/locale_eo.json
@@ -0,0 +1,3 @@
+{
+ "search.milestone_kind": "Serฤi celojn..."
+}
diff --git a/options/locale_next/locale_es-ES.json b/options/locale_next/locale_es-ES.json
new file mode 100644
index 0000000000..57753089ca
--- /dev/null
+++ b/options/locale_next/locale_es-ES.json
@@ -0,0 +1,17 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "fusionรณ %[1]d commit de %[2]s
en %[3]s
%[4]s",
+ "many": "fusionรณ %[1]d commits de %[2]s
en %[3]s
%[4]s",
+ "other": ""
+ },
+ "repo.pulls.title_desc": {
+ "one": "quiere fusionar %[1]d commit de %[2]s
en %[3]s
",
+ "many": "quiere fusionar %[1]d commits de %[2]s
en %[3]s
",
+ "other": ""
+ },
+ "search.milestone_kind": "Buscar hitosโฆ",
+ "home.welcome.no_activity": "Sin actividad",
+ "themes.names.forgejo-auto": "Forgejo (seguir el tema del sistema)",
+ "themes.names.forgejo-light": "Forgejo claro",
+ "themes.names.forgejo-dark": "Forgejo oscuro"
+}
diff --git a/options/locale_next/locale_et.json b/options/locale_next/locale_et.json
new file mode 100644
index 0000000000..a10447fa98
--- /dev/null
+++ b/options/locale_next/locale_et.json
@@ -0,0 +1,3 @@
+{
+ "search.milestone_kind": "Otsi verstapostid..."
+}
diff --git a/options/locale_next/locale_fa-IR.json b/options/locale_next/locale_fa-IR.json
new file mode 100644
index 0000000000..78d6944203
--- /dev/null
+++ b/options/locale_next/locale_fa-IR.json
@@ -0,0 +1,16 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "ูุงฺฉุด %[1]d ุณูพุฑุฏู ุงุฒ %[2]s
ุจู %[3]s
%[4]s",
+ "other": "ูุงฺฉุด %[1]d ุณูพุฑุฏูโูุง ุงุฒ %[2]s
ุจู %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": "ุฎูุงุณุช ูุงฺฉุด %[1]d ุณูพุฑุฏู ุฑุง ุงุฒ %[2]s
ุจู %[3]s
ุฏุงุฑุฏ",
+ "other": "ุฎูุงุณุช ูุงฺฉุด %[1]d ุณูพุฑุฏูโูุง ุฑุง ุงุฒ %[2]s
ุจู %[3]s
ุฏุงุฑุฏ"
+ },
+ "home.welcome.activity_hint": "ูููุฒ ฺุฒ ุฏุฑ ุขุฒูุบู ุดู
ุง ูุณุช. ุฏุฑ ุงูุฌุง ฺฉูุดโูุง ู ฺฉูุดุดโูุง ุดู
ุง ุฏุฑ ู
ุฎุงุฒู ฺฉู ฺูฏุงูโุจุงู ู
โฺฉูุฏ ูู
ุงุด ุฏุงุฏู ุฎูุงูุฏ ุดุฏ.",
+ "search.milestone_kind": "ุฌุณุชุฌู ููุงุท ุนุทู...",
+ "home.welcome.no_activity": "ุจุฏูู ฺฉูุดุด",
+ "home.explore_repos": "ฺฉุงูุด ู
ุฎุงุฒู",
+ "home.explore_users": "ฺฉุงูุด ฺฉุงุฑุจุฑุงู",
+ "home.explore_orgs": "ฺฉุงูุด ุณุงุฒู
ุงูโูุง"
+}
diff --git a/options/locale_next/locale_fi-FI.json b/options/locale_next/locale_fi-FI.json
new file mode 100644
index 0000000000..324ca5e6b3
--- /dev/null
+++ b/options/locale_next/locale_fi-FI.json
@@ -0,0 +1,15 @@
+{
+ "repo.pulls.merged_title_desc": "yhdistetty %[1]d committia lรคhteestรค %[2]s
kohteeseen %[3]s
%[4]s",
+ "repo.pulls.title_desc": "haluaa yhdistรครค %[1]d committia lรคhteestรค %[2]s
kohteeseen %[3]s
",
+ "search.milestone_kind": "Etsi merkkipaalujaโฆ",
+ "home.welcome.no_activity": "Ei toimintaa",
+ "incorrect_root_url": "Tรคmรค Forgejo-instanssi on mรครคritetty toimimaan osoitteessa \"%s\". Tarkastelet tรคllรค hetkellรค Forgejoa eri URL-osoitteen kautta, mikรค saattaa aiheuttaa sovelluksen osien toimimattomuutta. Virallinen URL-osoite on Forgejo-yllรคpitรคjien hallinnoima ROOT_URL-asetus app.ini -tiedostossa.",
+ "themes.names.forgejo-auto": "Forgejo (kรคyttรถjรคrjestelmรคn mรครคrittelemรค teema)",
+ "home.welcome.activity_hint": "Syรถtteellรคsi ei ole vielรค mitรครคn. Toimintasi ja toiminta repositorioissa joita seuraat ilmaantuu tรคlle sivulle.",
+ "home.explore_repos": "Tutki repositorioita",
+ "home.explore_users": "Tutki kรคyttรคjiรค",
+ "home.explore_orgs": "Tutki organisaatioita",
+ "themes.names.forgejo-light": "Forgejo, vaalea",
+ "themes.names.forgejo-dark": "Forgejo, tumma",
+ "install.invalid_lfs_path": "LFS juurta ei voitu luoda polkuun: %[1]s"
+}
diff --git a/options/locale_next/locale_fil.json b/options/locale_next/locale_fil.json
new file mode 100644
index 0000000000..578c0f480b
--- /dev/null
+++ b/options/locale_next/locale_fil.json
@@ -0,0 +1,21 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "isinali ang %[1]d commit mula%[2]s
patungong %[3]s
%[4]s",
+ "other": "isinali ang %[1]d mga commit mula sa %[2]s
patungong %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": "hinihiling na isama ang %[1]d commit mula %[2]s
patungong %[3]s
",
+ "other": "hiniling na isama ang %[1]d mga commit mula sa %[2]s
patungong %[3]s
"
+ },
+ "search.milestone_kind": "Maghanap ng mga milestoneโฆ",
+ "incorrect_root_url": "Ang Forgejo instance na ito ay naka-configure na ma-serve sa \"%s\". Kasalukuyan mong tinitignan ang Forgejo sa pamamagitan ng ibang URL, na maaaring magdulot na ang mga ibang bahagi ng application na masira. Ang canonical URL ay kino-control ng mga tagapangasiwa ng Forgejo sa pamamagitan ng ROOT_URL setting sa app.ini.",
+ "themes.names.forgejo-auto": "Forgejo (sundan ang tema ng sistema)",
+ "themes.names.forgejo-light": "Maliwanag na Forgejo",
+ "themes.names.forgejo-dark": "Madilim na Forgejo",
+ "home.welcome.no_activity": "Walang aktibidad",
+ "home.welcome.activity_hint": "Wala pang laman ang iyong feed. Makikita dito ang iyong mga aksyon at aktibidad mula sa mga repositoryo na pinapanood mo.",
+ "home.explore_repos": "Tuklasin ang mga repositoryo",
+ "home.explore_users": "Tuklasin ang mga user",
+ "home.explore_orgs": "Tuklasin ang mga organisasyon",
+ "install.invalid_lfs_path": "Nabigong gawin ang LFS root sa tinakdang path: %[1]s"
+}
diff --git a/options/locale_next/locale_fr-FR.json b/options/locale_next/locale_fr-FR.json
new file mode 100644
index 0000000000..8575e6d55f
--- /dev/null
+++ b/options/locale_next/locale_fr-FR.json
@@ -0,0 +1,13 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "fusionnรฉ %[1]d commit depuis %[2]s
vers %[3]s
%[4]s",
+ "many": "a fusionnรฉ %[1]d rรฉvision(s) ร partir de %[2]s
vers %[3]s
%[4]s",
+ "other": ""
+ },
+ "repo.pulls.title_desc": {
+ "one": "veut fusionner %[1]d commit depuis %[2]s
vers %[3]s
",
+ "many": "souhaite fusionner %[1]d rรฉvision(s) depuis %[2]s
vers %[3]s
",
+ "other": ""
+ },
+ "search.milestone_kind": "Recherche dans les jalons..."
+}
diff --git a/options/locale_next/locale_gl.json b/options/locale_next/locale_gl.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_gl.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_hi.json b/options/locale_next/locale_hi.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_hi.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_hu-HU.json b/options/locale_next/locale_hu-HU.json
new file mode 100644
index 0000000000..9d52509102
--- /dev/null
+++ b/options/locale_next/locale_hu-HU.json
@@ -0,0 +1,5 @@
+{
+ "repo.pulls.merged_title_desc": "egyesรญtve %[1]d vรกltozรกs(ok) a %[2]s
-bรณl %[3]s
-ba %[4]s",
+ "repo.pulls.title_desc": "egyesรญteni szeretnรฉ %[1]d vรกltozรกs(oka)t a(z) %[2]s
-bรณl %[3]s
-ba",
+ "search.milestone_kind": "Mรฉrfรถldkรถvek keresรฉse..."
+}
diff --git a/options/locale_next/locale_id-ID.json b/options/locale_next/locale_id-ID.json
new file mode 100644
index 0000000000..f2dac8114f
--- /dev/null
+++ b/options/locale_next/locale_id-ID.json
@@ -0,0 +1,8 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "other": "commit %[1]d telah digabungkan dari %[2]s
menjadi %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "other": "ingin menggabungkan komit %[1]d dari %[2]s
menuju %[3]s
"
+ }
+}
diff --git a/options/locale_next/locale_is-IS.json b/options/locale_next/locale_is-IS.json
new file mode 100644
index 0000000000..a92d924232
--- /dev/null
+++ b/options/locale_next/locale_is-IS.json
@@ -0,0 +1,5 @@
+{
+ "repo.pulls.title_desc": {
+ "other": "vill sameina %[1]d framlรถg frรก %[2]s
รญ %[3]s
"
+ }
+}
diff --git a/options/locale_next/locale_it-IT.json b/options/locale_next/locale_it-IT.json
new file mode 100644
index 0000000000..50cc736634
--- /dev/null
+++ b/options/locale_next/locale_it-IT.json
@@ -0,0 +1,19 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "ha fuso %[1]d commit da %[2]s
in %[3]s
%[4]s",
+ "many": "ha unito %[1]d commit da %[2]s
a %[3]s
%[4]s",
+ "other": ""
+ },
+ "repo.pulls.title_desc": {
+ "one": "vuole fondere %[1]d commit da %[2]s
in %[3]s
",
+ "many": "vuole unire %[1]d commit da %[2]s
a %[3]s
",
+ "other": ""
+ },
+ "search.milestone_kind": "Ricerca traguardiโฆ",
+ "home.welcome.no_activity": "Nessun'attivitร ",
+ "home.explore_repos": "Esplora i repositori",
+ "home.explore_users": "Esplora l'utenza",
+ "home.explore_orgs": "Esplora le organizzazioni",
+ "themes.names.forgejo-light": "Forgejo chiaro",
+ "themes.names.forgejo-dark": "Forgejo scuro"
+}
diff --git a/options/locale_next/locale_ja-JP.json b/options/locale_next/locale_ja-JP.json
new file mode 100644
index 0000000000..40edf8cb90
--- /dev/null
+++ b/options/locale_next/locale_ja-JP.json
@@ -0,0 +1,5 @@
+{
+ "repo.pulls.merged_title_desc": "ใ %[1]d ๅใฎใณใใใใ %[2]s
ใใ %[3]s
ใธใใผใธ %[4]s",
+ "repo.pulls.title_desc": "ใ %[2]s
ใใ %[3]s
ใธใฎ %[1]d ใณใใใใฎใใผใธใๅธๆใใฆใใพใ",
+ "search.milestone_kind": "ใใคใซในใใผใณใๆค็ดข..."
+}
diff --git a/options/locale_next/locale_ko-KR.json b/options/locale_next/locale_ko-KR.json
new file mode 100644
index 0000000000..ac61066356
--- /dev/null
+++ b/options/locale_next/locale_ko-KR.json
@@ -0,0 +1,9 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "other": "๋์ด %[2]s
์์ %[3]s
๋ก %[1]d ์ปค๋ฐ์ %[4]s ๋ณํฉํจ"
+ },
+ "repo.pulls.title_desc": {
+ "other": "%[2]s
์์ %[3]s
๋ก %[1]d๊ฐ์ ์ปค๋ฐ๋ค์ ๋ณํฉํ๋ คํจ"
+ },
+ "home.welcome.no_activity": "ํ๋ ์์"
+}
diff --git a/options/locale_next/locale_lt.json b/options/locale_next/locale_lt.json
new file mode 100644
index 0000000000..9f97587b09
--- /dev/null
+++ b/options/locale_next/locale_lt.json
@@ -0,0 +1,3 @@
+{
+ "search.milestone_kind": "Ieลกkoti gairiลณ..."
+}
diff --git a/options/locale_next/locale_lv-LV.json b/options/locale_next/locale_lv-LV.json
new file mode 100644
index 0000000000..1287ddbf49
--- /dev/null
+++ b/options/locale_next/locale_lv-LV.json
@@ -0,0 +1,23 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "zero": "iekฤผฤva %[1]d iesลซtฤซjumu no %[2]s
%[3]s
%[4]s",
+ "one": "Iekฤผฤva %[1]d iesลซtฤซjumu no %[2]s
zarฤ %[3]s
%[4]s",
+ "other": "Iekฤผฤva %[1]d iesลซtฤซjumus no %[2]s
zarฤ %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "zero": "vฤlas iekฤผaut %[1]d iesลซtฤซjumu no %[2]s
%[3]s
",
+ "one": "vฤlas iekฤผaut %[1]d iesลซtฤซjumu no %[2]s
zarฤ %[3]s
",
+ "other": "vฤlas iekฤผaut %[1]d iesลซtฤซjumus no %[2]s
zarฤ %[3]s
"
+ },
+ "search.milestone_kind": "Meklฤt atskaites punktusโฆ",
+ "home.welcome.no_activity": "Nav darbฤซbu",
+ "home.welcome.activity_hint": "Barotnฤ pagaidฤm nekฤ nav. ล eit parฤdฤซsies darbฤซbas un vฤroto glabฤtavu notikumi.",
+ "home.explore_repos": "Izpฤtฤซt glabฤtavas",
+ "home.explore_users": "Izpฤtฤซt lietotฤjus",
+ "home.explore_orgs": "Izpฤtฤซt apvienฤซbas",
+ "incorrect_root_url": "ล is Forgejo serveris ir konfigurฤts darboties \"%s\". Paลกlaik Forgejo tiek apmeklฤta ar atลกฤทirฤซgu URL, kas var radฤซt atseviลกฤทu lietotnes daฤผu salลซลกanu. Kanonisko URL pฤrrauga Forgejo pฤrvaldฤซtฤji ar app.ini iestatฤซjumu ROOT_URL.",
+ "themes.names.forgejo-auto": "Forgejo (ievฤrot sistฤmas izskatu)",
+ "themes.names.forgejo-light": "Forgejo gaiลกais",
+ "themes.names.forgejo-dark": "Forgejo tumลกais",
+ "install.invalid_lfs_path": "Nav iespฤjams izveidot LFS pamatmapi norฤdฤซtajฤ ceฤผฤ: %[1]s"
+}
diff --git a/options/locale_next/locale_ml-IN.json b/options/locale_next/locale_ml-IN.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_ml-IN.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_nb_NO.json b/options/locale_next/locale_nb_NO.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_nb_NO.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_nds.json b/options/locale_next/locale_nds.json
new file mode 100644
index 0000000000..7d3b5bcd82
--- /dev/null
+++ b/options/locale_next/locale_nds.json
@@ -0,0 +1,23 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "hett %[4]s %[1]d Kommitteren vun %[2]s
na %[3]s
tosamenfรถhrt",
+ "other": "hett %[4]s %[1]d Kommitterens vun %[2]s
na %[3]s
tosamenfรถhrt"
+ },
+ "repo.pulls.title_desc": {
+ "one": "will %[1]d Kommitteren vun %[2]s
na %[3]s
tosamenfรถhren",
+ "other": "will %[1]d Kommitterens vun %[2]s
na %[3]s
tosamenfรถhren"
+ },
+ "search.milestone_kind": "In Markstenen sรถken โฆ",
+ "home.explore_users": "Brukers utfรถrsken",
+ "home.explore_orgs": "Vereenigungen utfรถrsken",
+ "home.explore_repos": "Repositoriums utfรถrsken",
+ "home.welcome.no_activity": "Keen Doon",
+ "home.welcome.activity_hint": "In dienem Schuuv is noch nix. Dien Doon un dat Doon vun Repositoriums, wat du beluurst, word hier wiest worden.",
+ "incorrect_root_url": "Deese Forgejo-Instanz is inricht, unner ยป%sยซ besรถcht to worden. Du bekiekst Forgejo jรผรผst dรถr een anner URL, wat daarto fรถhren kann, dat โt deelwies nich richtig warkt. De kanonisk URL word vun de Forgejo-Chefs รถver de ROOT_URL-Instellen in de app.ini kuntrolleert.",
+ "themes.names.forgejo-light": "Forgejo Hell",
+ "themes.names.forgejo-dark": "Forgejo Dunker",
+ "themes.names.forgejo-auto": "Forgejo (Systeem-Thema nagahn)",
+ "settings.adopt": "รvernehmen",
+ "install.invalid_lfs_path": "Kunn de LFS-Ruut an de angeven Padd nich maken: %[1]s",
+ "install.lfs_jwt_secret_failed": "Kunn dat LFS-JWT-Geheemst nich maken: %[1]s"
+}
diff --git a/options/locale_next/locale_nl-NL.json b/options/locale_next/locale_nl-NL.json
new file mode 100644
index 0000000000..49de90b0eb
--- /dev/null
+++ b/options/locale_next/locale_nl-NL.json
@@ -0,0 +1,23 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "heeft %[1]d commit van %[2]s
samengevoegd in %[3]s
%[4]s",
+ "other": "heeft %[1]d commits samengevoegd van %[2]s
naar %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": "wil %[1]d commit van %[2]s
samenvoegen in %[3]s
",
+ "other": "wil %[1]d commits van %[2]s
samenvoegen met %[3]s
"
+ },
+ "search.milestone_kind": "Zoek mijlpalenโฆ",
+ "home.welcome.no_activity": "Geen activiteit",
+ "home.welcome.activity_hint": "Er staat nog niets in uw feed. Uw acties en activiteiten van repositories die u monitort zullen hier verschijnen.",
+ "home.explore_repos": "Verken repositories",
+ "home.explore_users": "Verken gebruikers",
+ "home.explore_orgs": "Verken organisaties",
+ "incorrect_root_url": "Deze Forgejo-instantie is geconfigureerd om geserveerd te worden op \"%s\". U bekijkt Forgejo momenteel via een andere URL, waardoor onderdelen van de applicatie kunnen breken. De canonieke URL kan worden gewijzigd door Forgejo admins via de ROOT_URL instelling in de app.ini.",
+ "themes.names.forgejo-auto": "Forgejo (volg het systeemthema)",
+ "themes.names.forgejo-light": "Forgejo licht",
+ "themes.names.forgejo-dark": "Forgejo donker",
+ "settings.adopt": "Adopteer",
+ "install.invalid_lfs_path": "Kan de LFS-root niet aanmaken op het opgegeven pad: %[1]s",
+ "install.lfs_jwt_secret_failed": "Kan geen LFS JWT-geheim genereren: %[1]s"
+}
diff --git a/options/locale_next/locale_pl-PL.json b/options/locale_next/locale_pl-PL.json
new file mode 100644
index 0000000000..8f9eea2302
--- /dev/null
+++ b/options/locale_next/locale_pl-PL.json
@@ -0,0 +1,6 @@
+{
+ "repo.pulls.merged_title_desc": "scala %[1]d commity/รณw z %[2]s
do %[3]s
%[4]s",
+ "repo.pulls.title_desc": "chce scaliฤ %[1]d commity/รณw z %[2]s
do %[3]s
",
+ "search.milestone_kind": "Wyszukaj kamienie milowe...",
+ "incorrect_root_url": "Ta instancja Forgejo jest skonfigurowana do korzystania z \"%s\". Obecnie oglฤ
dasz Forgejo za pomocฤ
innego URL, co moลผe powodowaฤ bลฤdne dziaลanie tej aplikacji. URL kanoniczny jest kontrolowany przez administratorรณw Forgejo za pomocฤ
ROOT_URL w app.ini."
+}
diff --git a/options/locale_next/locale_pt-BR.json b/options/locale_next/locale_pt-BR.json
new file mode 100644
index 0000000000..85282b101d
--- /dev/null
+++ b/options/locale_next/locale_pt-BR.json
@@ -0,0 +1,23 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "mesclou %[1]d commit de %[2]s
em %[3]s
%[4]s",
+ "many": "mesclou %[1]d commits de %[2]s
em %[3]s
%[4]s",
+ "other": ""
+ },
+ "repo.pulls.title_desc": {
+ "one": "quer mesclar %[1]d commit de %[2]s
em %[3]s
",
+ "many": "quer mesclar %[1]d commits de %[2]s
em %[3]s
",
+ "other": ""
+ },
+ "search.milestone_kind": "Pesquisar marcosโฆ",
+ "home.welcome.no_activity": "Sem atividade",
+ "home.welcome.activity_hint": "Ainda nรฃo tem nada no seu feed. Suas aรงรตes e atividade dos seus repositรณrios vigiados aparecerรฃo aqui.",
+ "home.explore_repos": "Explorar repositรณrios",
+ "home.explore_users": "Explorar usuรกrios",
+ "home.explore_orgs": "Explorar organizaรงรตes",
+ "incorrect_root_url": "Esta instรขncia do Forgejo estรก configurada para o endereรงo \"%s\". Vocรช estรก atualmente vendo o Forgejo atravรฉs de uma URL diferente, o que pode causar erros em algumas partes da aplicaรงรฃo. A URL oficial รฉ controlada pela administraรงรฃo do Forgejo atravรฉs da configuraรงรฃo ROOT_URL no arquivo app.ini.",
+ "themes.names.forgejo-auto": "Forgejo (usar o tema do sistema)",
+ "themes.names.forgejo-light": "Forgejo claro",
+ "themes.names.forgejo-dark": "Forgejo escuro",
+ "install.invalid_lfs_path": "Nรฃo foi possรญvel criar um root LFS no caminho especificado: %[1]s"
+}
diff --git a/options/locale_next/locale_pt-PT.json b/options/locale_next/locale_pt-PT.json
new file mode 100644
index 0000000000..4c24ed5ea6
--- /dev/null
+++ b/options/locale_next/locale_pt-PT.json
@@ -0,0 +1,23 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "integrou %[1]d cometimento do ramo %[2]s
no ramo %[3]s
%[4]s",
+ "many": "integrou %[1]d cometimentos do ramo %[2]s
no ramo %[3]s
%[4]s",
+ "other": ""
+ },
+ "repo.pulls.title_desc": {
+ "one": "quer integrar %[1]d cometimento do ramo %[2]s
no ramo %[3]s
",
+ "many": "quer integrar %[1]d cometimentos do ramo %[2]s
no ramo %[3]s
",
+ "other": ""
+ },
+ "search.milestone_kind": "Procurar etapasโฆ",
+ "home.welcome.no_activity": "Sem atividade",
+ "home.welcome.activity_hint": "Ainda nรฃo hรก nada no seu feed. As suas operaรงรตes e a atividade dos repositรณrios que vigia aparecerรฃo aqui.",
+ "home.explore_repos": "Explorar repositรณrios",
+ "home.explore_users": "Explorar utilizadores",
+ "home.explore_orgs": "Explorar organizaรงรตes",
+ "incorrect_root_url": "Esta instรขncia do Forgejo estรก configurada para ser servida em โ%sโ. Atualmente, estรก a visualizar o Forgejo atravรฉs de um URL diferente, o que pode causar a quebra de partes da aplicaรงรฃo. O URL official รฉ controlado pelos administradores do Forgejo atravรฉs da configuraรงรฃo ROOT_URL no ficheiro app.ini.",
+ "themes.names.forgejo-auto": "Forgejo (segue o tema do sistema)",
+ "themes.names.forgejo-light": "Forgejo claro",
+ "themes.names.forgejo-dark": "Forgejo escuro",
+ "install.invalid_lfs_path": "Nรฃo foi possรญvel criar a raiz LFS no caminho especificado: %[1]s"
+}
diff --git a/options/locale_next/locale_ru-RU.json b/options/locale_next/locale_ru-RU.json
new file mode 100644
index 0000000000..88bbe18b09
--- /dev/null
+++ b/options/locale_next/locale_ru-RU.json
@@ -0,0 +1,23 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "ัะปะธั %[1]d ะบะพะผะผะธั ะธะท %[2]s
ะฒ %[3]s
%[4]s",
+ "few": "ัะปะธัะพ %[1]d ะบะพะผะผะธัะฐ ะธะท %[2]s
ะฒ %[3]s
%[4]s",
+ "many": "ัะปะธัะพ %[1]d ะบะพะผะผะธัะพะฒ ะธะท %[2]s
ะฒ %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": "ั
ะพัะตั ะฒะปะธัั %[1]d ะบะพะผะผะธั ะธะท %[2]s
ะฒ %[3]s
",
+ "few": "ั
ะพัะตั ะฒะปะธัั %[1]d ะบะพะผะผะธัะฐ ะธะท %[2]s
ะฒ %[3]s
",
+ "many": "ั
ะพัะตั ะฒะปะธัั %[1]d ะบะพะผะผะธัะพะฒ ะธะท %[2]s
ะฒ %[3]s
"
+ },
+ "search.milestone_kind": "ะะฐะนัะธ ััะฐะฟัโฆ",
+ "home.explore_repos": "ะะฐัะฐะปะพะณ ัะตะฟะพะทะธัะพัะธะตะฒ",
+ "home.explore_users": "ะะฐัะฐะปะพะณ ะฟะพะปัะทะพะฒะฐัะตะปะตะน",
+ "home.explore_orgs": "ะะฐัะฐะปะพะณ ะพัะณะฐะฝะธะทะฐัะธะน",
+ "home.welcome.activity_hint": "ะ ะฒะฐัะตะน ะปะตะฝัะต ะฟะพะบะฐ ะฝะธัะตะณะพ ะฝะตั. ะะฐัะธ ะดะตะนััะฒะธั ะธ ะฐะบัะธะฒะฝะพััั ะธะท ะพััะปะตะถะธะฒะฐะตะผัั
ะฒะฐะผะธ ัะตะฟะพะทะธัะพัะธะตะฒ ะฑัะดัั ะพัะพะฑัะฐะถะตะฝั ะทะดะตัั.",
+ "home.welcome.no_activity": "ะะตั ัะพะฑััะธะน",
+ "incorrect_root_url": "ะญัะพั ัะตัะฒะตั Forgejo ัะฐัะฟะพะปะพะถะตะฝ ะฟะพ ะฐะดัะตัั ยซ%sยป, ะฝะพ ะฒั ะฟัะพัะผะฐััะธะฒะฐะตัะต ัััะฐะฝะธัั ั ะดััะณะพะณะพ ะฐะดัะตัะฐ. ะญัะพ ะผะพะถะตั ะฟัะธะฒะพะดะธัั ะบ ะฟะพะปะพะผะบะฐะผ ัะฐััะตะน ะฟัะธะปะพะถะตะฝะธั. ะะฐะฝะพะฝะธัะตัะบะธะน ะฐะดัะตั ัะบะฐะทัะฒะฐะตััั ะฐะดะผะธะฝะธัััะฐัะพัะพะผ ัะตัะฒะตัะฐ ะฒ ัะฐะนะปะต ะบะพะฝัะธะณััะฐัะธะธ app.ini - ROOT_URL.",
+ "themes.names.forgejo-light": "Forgejo โ ัะฒะตัะปะฐั",
+ "themes.names.forgejo-auto": "Forgejo โ ะบะฐะบ ะฒ ัะธััะตะผะต",
+ "themes.names.forgejo-dark": "Forgejo โ ััะผะฝะฐั",
+ "install.invalid_lfs_path": "ะะต ัะดะฐะปะพัั ัะฐัะฟะพะปะพะถะธัั ะบะพัะตะฝั LFS ะฟะพ ัะบะฐะทะฐะฝะฝะพะผั ะฟััะธ: %[1]s"
+}
diff --git a/options/locale_next/locale_si-LK.json b/options/locale_next/locale_si-LK.json
new file mode 100644
index 0000000000..0cdd44acd0
--- /dev/null
+++ b/options/locale_next/locale_si-LK.json
@@ -0,0 +1,8 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "other": "เถธเถปเทเถขเท%[1]d เทเทเถง %[2]s
เถฏเถเทเทเท %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "other": "%[1]d เทเทเถง %[2]s
เถฏเถเทเทเท %[3]s
"
+ }
+}
diff --git a/options/locale_next/locale_sk-SK.json b/options/locale_next/locale_sk-SK.json
new file mode 100644
index 0000000000..953a7511db
--- /dev/null
+++ b/options/locale_next/locale_sk-SK.json
@@ -0,0 +1,13 @@
+{
+ "home.welcome.no_activity": "ลฝiadna aktivita",
+ "home.welcome.activity_hint": "Vo vaลกom kanรกli zatiaฤพ niฤ nie je. Tu sa budรบ zobrazovaลฅ vaลกe akcie a aktivity z repozitรกrov, ktorรฉ sledujete.",
+ "home.explore_repos": "Preskรบmajte repozitรกre",
+ "home.explore_users": "Preskรบmajte pouลพรญvateฤพov",
+ "home.explore_orgs": "Preskรบmajte organizรกcie",
+ "search.milestone_kind": "Hฤพadaลฅ v mรญฤพnikochโฆ",
+ "incorrect_root_url": "Tรกto inลกtancia Forgejo je nakonfigurovanรก tak, aby bola obsluhovanรก na โ%sโ. Momentรกlne zobrazujete Forgejo prostrednรญctvom inej adresy URL, ฤo mรดลพe spรดsobiลฅ poruchu niektorรฝch ฤastรญ aplikรกcie. Kanonickรบ adresu URL kontrolujรบ sprรกvcovia aplikรกcie Forgejo prostrednรญctvom nastavenia ROOT_URL v sรบbore app.ini.",
+ "themes.names.forgejo-auto": "Forgejo (sleduj systรฉmovรบ tรฉmu)",
+ "themes.names.forgejo-light": "Forgejo svetlรฉ",
+ "themes.names.forgejo-dark": "Forgejo tmavรฉ",
+ "install.invalid_lfs_path": "Nie je moลพnรฉ vytvoriลฅ koreลovรฝ systรฉm LFS na zadanej ceste: %[1]s"
+}
diff --git a/options/locale_next/locale_sl.json b/options/locale_next/locale_sl.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_sl.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_sr-SP.json b/options/locale_next/locale_sr-SP.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_sr-SP.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_sv-SE.json b/options/locale_next/locale_sv-SE.json
new file mode 100644
index 0000000000..dc41e4d6e1
--- /dev/null
+++ b/options/locale_next/locale_sv-SE.json
@@ -0,0 +1,5 @@
+{
+ "repo.pulls.merged_title_desc": "sammanfogade %[1]d incheckningar frรฅn %[2]s
in i %[3]s
%[4]s",
+ "repo.pulls.title_desc": "vill sammanfoga %[1]d incheckningar frรฅn s[2]s
in i %[3]s
",
+ "search.milestone_kind": "Sรถk milstolpar..."
+}
diff --git a/options/locale_next/locale_tr-TR.json b/options/locale_next/locale_tr-TR.json
new file mode 100644
index 0000000000..b0e34e677f
--- /dev/null
+++ b/options/locale_next/locale_tr-TR.json
@@ -0,0 +1,5 @@
+{
+ "repo.pulls.merged_title_desc": "%[4]s %[2]s
iรงindeki %[1]d iลlemeyi %[3]s
ile birleลtirdi",
+ "repo.pulls.title_desc": "%[2]s
iรงindeki %[1]d iลlemeyi %[3]s
ile birleลtirmek istiyor",
+ "search.milestone_kind": "Kilometre taลlarฤฑnฤฑ ara..."
+}
diff --git a/options/locale_next/locale_uk-UA.json b/options/locale_next/locale_uk-UA.json
new file mode 100644
index 0000000000..8e45bfd5c7
--- /dev/null
+++ b/options/locale_next/locale_uk-UA.json
@@ -0,0 +1,25 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "one": "ะพะฑ'ัะดะฝัั %[1]d ะบะพะผัั ะท %[2]s
ะฒ %[3]s
%[4]s",
+ "few": "ะพะฑ'ัะดะฝัั %[1]d ะบะพะผััะธ ะท %[2]s
ะฒ %[3]s
%[4]s",
+ "many": "ะพะฑ'ัะดะฝัั %[1]d ะบะพะผัััะฒ ะท %[2]s
ะฒ %[3]s
%[4]s"
+ },
+ "repo.pulls.title_desc": {
+ "one": "ั
ะพัะต ะพะฑ'ัะดะฝะฐัะธ %[1]d ะบะพะผัั ะท %[2]s
ะฒ %[3]s
",
+ "few": "ั
ะพัะต ะพะฑ'ัะดะฝะฐัะธ %[1]d ะบะพะผััะธ ะท %[2]s
ะฒ %[3]s
",
+ "many": "ั
ะพัะต ะพะฑ'ัะดะฝะฐัะธ %[1]d ะบะพะผัััะฒ ะท %[2]s
ะฒ %[3]s
"
+ },
+ "search.milestone_kind": "ะจัะบะฐัะธ ะตัะฐะฟะธโฆ",
+ "home.welcome.activity_hint": "ะฃ ะฒะฐััะน ััััััั ัะต ะฝััะพะณะพ ะฝะตะผะฐั. ะขัั ะท'ัะฒะปััะธะผััััั ะฒะฐัั ะดัั ัะฐ ะฐะบัะธะฒะฝัััั ัะท ะฒัะดััะตะถัะฒะฐะฝะธั
ัะตะฟะพะทะธัะพัััะฒ.",
+ "home.welcome.no_activity": "ะะตะผะฐั ะฟะพะดัะน",
+ "home.explore_repos": "ะะณะปัะด ัะตะฟะพะทะธัะพัััะฒ",
+ "home.explore_users": "ะะณะปัะด ะบะพัะธัััะฒะฐััะฒ",
+ "home.explore_orgs": "ะะณะปัะด ะพัะณะฐะฝัะทะฐััะน",
+ "incorrect_root_url": "ะฆะตะน ะตะบะทะตะผะฟะปัั Forgejo ะฝะฐะปะฐััะพะฒะฐะฝะพ ะฝะฐ ะฒัะดะฒัะดัะฒะฐะฝะฝั ะท ยซ%sยป. ะะฐัะฐะท ะฒะธ ะฟะตัะตะณะปัะดะฐััะต Forgejo ะทะฐ ัะฝัะพั URL-ะฐะดัะตัะพั, ัะพ ะผะพะถะต ะฟัะธะทะฒะตััะธ ะดะพ ะทะฑะพัะฒ ะดะตัะบะธั
ัะฐััะธะฝ ะฟัะพะณัะฐะผะธ. ะะฐะฝะพะฝััะฝะฐ URL-ะฐะดัะตัะฐ ะฒััะฐะฝะพะฒะปัััััั ะฐะดะผัะฝััััะฐัะพัะฐะผะธ Forgejo ะทะฐ ะดะพะฟะพะผะพะณะพั ะฟะฐัะฐะผะตััะฐ ROOT_URL ั ัะฐะนะปั app.ini.",
+ "themes.names.forgejo-light": "Forgejo ัะฒััะปะฐ",
+ "themes.names.forgejo-dark": "Forgejo ัะตะผะฝะฐ",
+ "themes.names.forgejo-auto": "Forgejo (ัะบ ั ัะธััะตะผั)",
+ "settings.adopt": "ะัะธะนะฝััะธ",
+ "install.invalid_lfs_path": "ะะต ะฒะดะฐะปะพัั ััะฒะพัะธัะธ ะบะพััะฝั LFS ะทะฐ ะฒะบะฐะทะฐะฝะธะผ ัะปัั
ะพะผ: %[1]s",
+ "install.lfs_jwt_secret_failed": "ะะต ะฒะดะฐะปะพัั ััะฒะพัะธัะธ ัะตะบัะตั LFS JWT: %[1]s"
+}
diff --git a/options/locale_next/locale_vi.json b/options/locale_next/locale_vi.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_vi.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_yi.json b/options/locale_next/locale_yi.json
new file mode 100644
index 0000000000..0967ef424b
--- /dev/null
+++ b/options/locale_next/locale_yi.json
@@ -0,0 +1 @@
+{}
diff --git a/options/locale_next/locale_zh-CN.json b/options/locale_next/locale_zh-CN.json
new file mode 100644
index 0000000000..fd7a9b357e
--- /dev/null
+++ b/options/locale_next/locale_zh-CN.json
@@ -0,0 +1,16 @@
+{
+ "repo.pulls.merged_title_desc": "ไบ %[4]s ๅฐ %[1]d ๆฌกไปฃ็ ๆไบคไป %[2]s
ๅๅนถ่ณ %[3]s
",
+ "repo.pulls.title_desc": "่ฏทๆฑๅฐ %[1]d ๆฌกไปฃ็ ๆไบคไป %[2]s
ๅๅนถ่ณ %[3]s
",
+ "search.milestone_kind": "ๆ็ดข้็จ็ขโฆ",
+ "home.welcome.no_activity": "ๆ ๆดปๅจ",
+ "home.welcome.activity_hint": "ๆจ็่ฎข้
ไธญ่ฟๆฒกๆไปปไฝๅ
ๅฎนใๆจๅ
ณๆณจ็ไปๅบไธญ็ๆไฝๅๆดปๅจๅฐๆพ็คบๅจๆญคๅคใ",
+ "home.explore_repos": "ๆข็ดขไปๅบ",
+ "home.explore_users": "ๆข็ดข็จๆท",
+ "home.explore_orgs": "ๆข็ดข็ป็ป",
+ "incorrect_root_url": "ๆญค Forgejo ๅฎไพ้
็ฝฎไธบๅจโ%sโไธๆไพๆๅกใๆจๅฝๅๆญฃๅจ้่ฟไธๅ็็ฝๅๆฅ็ Forgejo๏ผ่ฟๅฏ่ฝไผๅฏผ่ดๅบ็จ็จๅบ็ๆไบ้จๅๆๅใForgejo ็ฎก็ๅๅฏไปฅ้่ฟ app.ini ไธญ็ ROOT_URL ่ฎพ็ฝฎๆงๅถ่ง่็ฝๅใ",
+ "themes.names.forgejo-auto": "Forgejo๏ผ้ตๅพช็ณป็ปไธป้ข๏ผ",
+ "themes.names.forgejo-light": "Forgejo ๆต
่ฒ",
+ "themes.names.forgejo-dark": "Forgejo ๆทฑ่ฒ",
+ "install.invalid_lfs_path": "ๆ ๆณๅจๆๅฎ่ทฏๅพๅๅปบ LFS ๆ น็ฎๅฝ๏ผ%[1]s",
+ "install.lfs_jwt_secret_failed": "ๆ ๆณ็ๆ LFS JWT ๅฏ้ฅ๏ผ%[1]s"
+}
diff --git a/options/locale_next/locale_zh-HK.json b/options/locale_next/locale_zh-HK.json
new file mode 100644
index 0000000000..6baf89e022
--- /dev/null
+++ b/options/locale_next/locale_zh-HK.json
@@ -0,0 +1,5 @@
+{
+ "repo.pulls.merged_title_desc": {
+ "other": "ๆผ %[4]s ๅฐ %[1]d ๆฌกไปฃ็ขผๆไบคๅพ %[2]s
ๅไฝต่ณ %[3]s
"
+ }
+}
diff --git a/options/locale_next/locale_zh-TW.json b/options/locale_next/locale_zh-TW.json
new file mode 100644
index 0000000000..222e8bb332
--- /dev/null
+++ b/options/locale_next/locale_zh-TW.json
@@ -0,0 +1,5 @@
+{
+ "repo.pulls.merged_title_desc": "ๅฐ %[1]d ๆฌกๆไบคๅพ %[2]s
ๅไฝต่ณ %[3]s
%[4]s",
+ "repo.pulls.title_desc": "่ซๆฑๅฐ %[1]d ๆฌก็จๅผ็ขผๆไบคๅพ %[2]s
ๅไฝต่ณ %[3]s
",
+ "search.milestone_kind": "ๆๅฐ้็จ็ขโฆ"
+}
diff --git a/package-lock.json b/package-lock.json
index 6c628bd836..6099e39ad6 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,52 +1,50 @@
{
- "name": "forgejo",
+ "name": "forgejo-aneksajo",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
+ "name": "forgejo-aneksajo",
"dependencies": {
- "@citation-js/core": "0.7.11",
- "@citation-js/plugin-bibtex": "0.7.11",
- "@citation-js/plugin-csl": "0.7.11",
+ "@citation-js/core": "0.7.14",
+ "@citation-js/plugin-bibtex": "0.7.16",
"@citation-js/plugin-software-formats": "0.6.1",
"@github/markdown-toolbar-element": "2.2.3",
- "@github/relative-time-element": "4.4.2",
- "@github/text-expander-element": "2.7.1",
+ "@github/quote-selection": "2.1.0",
+ "@github/relative-time-element": "4.4.5",
+ "@github/text-expander-element": "2.8.0",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
- "@primer/octicons": "19.9.0",
- "add-asset-webpack-plugin": "2.0.1",
+ "@primer/octicons": "19.14.0",
"ansi_up": "6.0.2",
- "asciinema-player": "3.8.0",
- "chart.js": "4.4.2",
+ "asciinema-player": "3.8.2",
+ "chart.js": "4.4.5",
"chartjs-adapter-dayjs-4": "1.0.4",
- "chartjs-plugin-zoom": "2.0.1",
+ "chartjs-plugin-zoom": "2.2.0",
"clippie": "4.1.1",
"css-loader": "7.0.0",
- "dayjs": "1.11.11",
+ "dayjs": "1.11.12",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
- "esbuild-loader": "4.1.0",
+ "esbuild-loader": "4.3.0",
"escape-goat": "4.0.0",
- "fast-glob": "3.3.2",
+ "fast-glob": "3.3.3",
"htmx.org": "1.9.12",
"idiomorph": "0.3.0",
"jquery": "3.7.1",
- "katex": "0.16.10",
- "license-checker-webpack-plugin": "0.2.1",
- "mermaid": "10.9.1",
- "mini-css-extract-plugin": "2.9.0",
- "minimatch": "9.0.5",
- "monaco-editor": "0.47.0",
+ "katex": "0.16.21",
+ "mermaid": "11.5.0",
+ "mini-css-extract-plugin": "2.9.2",
+ "minimatch": "10.0.1",
+ "monaco-editor": "0.52.2",
"monaco-editor-webpack-plugin": "7.1.0",
"pdfobject": "2.3.0",
- "postcss": "8.4.38",
+ "postcss": "8.5.2",
"postcss-loader": "8.1.1",
- "postcss-nesting": "12.1.5",
+ "postcss-nesting": "13.0.1",
"pretty-ms": "9.0.0",
- "sortablejs": "1.15.2",
+ "sortablejs": "1.15.6",
"swagger-ui-dist": "5.17.14",
- "tailwindcss": "3.4.4",
- "temporal-polyfill": "0.2.4",
+ "tailwindcss": "3.4.17",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",
@@ -54,52 +52,57 @@
"tributejs": "5.1.3",
"uint8-to-base64": "0.2.0",
"vanilla-colorful": "0.7.2",
- "vue": "3.4.31",
- "vue-bar-graph": "2.0.0",
+ "vue": "3.5.13",
"vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5",
- "webpack": "5.92.1",
- "webpack-cli": "5.1.4",
+ "webpack": "5.98.0",
+ "webpack-cli": "6.0.1",
"wrap-ansi": "9.0.0"
},
"devDependencies": {
- "@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
- "@playwright/test": "1.45.0",
- "@stoplight/spectral-cli": "6.11.1",
- "@stylistic/eslint-plugin-js": "1.8.1",
- "@stylistic/stylelint-plugin": "2.1.2",
- "@vitejs/plugin-vue": "5.0.4",
- "@vitest/coverage-v8": "1.6.0",
+ "@axe-core/playwright": "4.10.1",
+ "@eslint-community/eslint-plugin-eslint-comments": "4.4.1",
+ "@playwright/test": "1.51.0",
+ "@stoplight/spectral-cli": "6.14.3",
+ "@stylistic/eslint-plugin-js": "4.2.0",
+ "@stylistic/stylelint-plugin": "3.1.2",
+ "@vitejs/plugin-vue": "5.2.3",
+ "@vitest/coverage-v8": "3.0.8",
+ "@vitest/eslint-plugin": "1.1.25",
"@vue/test-utils": "2.4.6",
- "eslint": "8.57.0",
- "eslint-plugin-array-func": "4.0.0",
- "eslint-plugin-github": "4.10.2",
- "eslint-plugin-i": "2.29.1",
- "eslint-plugin-jquery": "1.5.1",
- "eslint-plugin-no-jquery": "2.7.0",
- "eslint-plugin-no-use-extend-native": "0.5.0",
- "eslint-plugin-regexp": "2.6.0",
- "eslint-plugin-sonarjs": "0.25.1",
- "eslint-plugin-unicorn": "52.0.0",
- "eslint-plugin-vitest": "0.5.4",
+ "eslint": "9.22.0",
+ "eslint-import-resolver-typescript": "4.1.1",
+ "eslint-plugin-array-func": "5.0.2",
+ "eslint-plugin-import-x": "4.7.0",
+ "eslint-plugin-no-jquery": "3.1.1",
+ "eslint-plugin-no-use-extend-native": "0.7.2",
+ "eslint-plugin-playwright": "2.2.0",
+ "eslint-plugin-regexp": "2.7.0",
+ "eslint-plugin-sonarjs": "3.0.2",
+ "eslint-plugin-toml": "0.12.0",
+ "eslint-plugin-unicorn": "57.0.0",
"eslint-plugin-vitest-globals": "1.5.0",
- "eslint-plugin-vue": "9.26.0",
- "eslint-plugin-vue-scoped-css": "2.8.1",
- "eslint-plugin-wc": "2.1.0",
- "happy-dom": "14.12.3",
- "markdownlint-cli": "0.41.0",
- "postcss-html": "1.7.0",
- "stylelint": "16.6.1",
+ "eslint-plugin-vue": "10.0.0",
+ "eslint-plugin-vue-scoped-css": "2.9.0",
+ "eslint-plugin-wc": "2.2.1",
+ "globals": "16.0.0",
+ "happy-dom": "17.4.4",
+ "license-checker-rseidelsohn": "4.4.2",
+ "markdownlint-cli": "0.44.0",
+ "postcss-html": "1.8.0",
+ "stylelint": "16.16.0",
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
- "stylelint-declaration-strict-value": "1.10.4",
+ "stylelint-declaration-strict-value": "1.10.11",
"stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "3.2.0",
+ "typescript": "5.7.3",
+ "typescript-eslint": "8.26.1",
"vite-string-plugin": "1.3.4",
- "vitest": "1.6.0"
+ "vitest": "3.0.8"
},
"engines": {
- "node": ">= 18.0.0"
+ "node": ">= 20.0.0"
}
},
"node_modules/@alloc/quick-lru": {
@@ -128,56 +131,58 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@antfu/install-pkg": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-1.0.0.tgz",
+ "integrity": "sha512-xvX6P/lo1B3ej0OsaErAjqgFYzYVcJpamjLAFLYh9vRJngBrMoUG7aVnrGTeqM7yxbyTD5p3F2+0/QUEh8Vzhw==",
+ "license": "MIT",
+ "dependencies": {
+ "package-manager-detector": "^0.2.8",
+ "tinyexec": "^0.3.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/@antfu/utils": {
+ "version": "8.1.1",
+ "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz",
+ "integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
"node_modules/@asyncapi/specs": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-4.3.1.tgz",
- "integrity": "sha512-EfexhJu/lwF8OdQDm28NKLJHFkx0Gb6O+rcezhZYLPIoNYKXJMh2J1vFGpwmfAcTTh+ffK44Oc2Hs1Q4sLBp+A==",
+ "version": "6.8.1",
+ "resolved": "https://registry.npmjs.org/@asyncapi/specs/-/specs-6.8.1.tgz",
+ "integrity": "sha512-czHoAk3PeXTLR+X8IUaD+IpT+g+zUvkcgMDJVothBsan+oHN3jfcFcFUNdOPAAFoUCQN1hXF1dWuphWy05THlA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@types/json-schema": "^7.0.11"
}
},
- "node_modules/@babel/code-frame": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
- "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==",
- "license": "MIT",
- "dependencies": {
- "@babel/highlight": "^7.24.7",
- "picocolors": "^1.0.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helper-string-parser": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz",
- "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==",
+ "node_modules/@axe-core/playwright": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/@axe-core/playwright/-/playwright-4.10.1.tgz",
+ "integrity": "sha512-EV5t39VV68kuAfMKqb/RL+YjYKhfuGim9rgIaQ6Vntb2HgaCaau0h98Y3WEUqW1+PbdzxDtDNjFAipbtZuBmEA==",
"dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
+ "license": "MPL-2.0",
+ "dependencies": {
+ "axe-core": "~4.10.2"
+ },
+ "peerDependencies": {
+ "playwright-core": ">= 1.0.0"
}
},
- "node_modules/@babel/helper-validator-identifier": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz",
- "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==",
- "license": "MIT",
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/highlight": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz",
- "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==",
+ "node_modules/@babel/code-frame": {
+ "version": "7.26.2",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz",
+ "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.24.7",
- "chalk": "^2.4.2",
+ "@babel/helper-validator-identifier": "^7.25.9",
"js-tokens": "^4.0.0",
"picocolors": "^1.0.0"
},
@@ -185,88 +190,38 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/highlight/node_modules/ansi-styles": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
- "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
- "license": "MIT",
- "dependencies": {
- "color-convert": "^1.9.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/highlight/node_modules/chalk": {
- "version": "2.4.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
- "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^3.2.1",
- "escape-string-regexp": "^1.0.5",
- "supports-color": "^5.3.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/highlight/node_modules/color-convert": {
- "version": "1.9.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
- "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
- "license": "MIT",
- "dependencies": {
- "color-name": "1.1.3"
- }
- },
- "node_modules/@babel/highlight/node_modules/color-name": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
- "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
- "license": "MIT"
- },
- "node_modules/@babel/highlight/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "license": "MIT",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/@babel/highlight/node_modules/has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/@babel/highlight/node_modules/js-tokens": {
+ "node_modules/@babel/code-frame/node_modules/js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"license": "MIT"
},
- "node_modules/@babel/highlight/node_modules/supports-color": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
- "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz",
+ "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==",
"license": "MIT",
- "dependencies": {
- "has-flag": "^3.0.0"
- },
"engines": {
- "node": ">=4"
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.25.9",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz",
+ "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz",
- "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz",
+ "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==",
"license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.26.10"
+ },
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -275,9 +230,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.7.tgz",
- "integrity": "sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz",
+ "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==",
"license": "MIT",
"dependencies": {
"regenerator-runtime": "^0.14.0"
@@ -287,37 +242,77 @@
}
},
"node_modules/@babel/types": {
- "version": "7.24.7",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz",
- "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==",
- "dev": true,
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
+ "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
"license": "MIT",
"dependencies": {
- "@babel/helper-string-parser": "^7.24.7",
- "@babel/helper-validator-identifier": "^7.24.7",
- "to-fast-properties": "^2.0.0"
+ "@babel/helper-string-parser": "^7.25.9",
+ "@babel/helper-validator-identifier": "^7.25.9"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@bcoe/v8-coverage": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
- "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
"dev": true,
- "license": "MIT"
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
},
"node_modules/@braintree/sanitize-url": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz",
- "integrity": "sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==",
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-7.1.1.tgz",
+ "integrity": "sha512-i1L7noDNxtFyL5DmZafWy1wRVhGehQmzZaz1HiN5e7iylJMSZR7ekOV7NsIqa5qBldlLrsKv4HbgFUVlQrz8Mw==",
"license": "MIT"
},
+ "node_modules/@chevrotain/cst-dts-gen": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz",
+ "integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@chevrotain/gast": "11.0.3",
+ "@chevrotain/types": "11.0.3",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@chevrotain/gast": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz",
+ "integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@chevrotain/types": "11.0.3",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/@chevrotain/regexp-to-ast": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz",
+ "integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@chevrotain/types": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz",
+ "integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==",
+ "license": "Apache-2.0"
+ },
+ "node_modules/@chevrotain/utils": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz",
+ "integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==",
+ "license": "Apache-2.0"
+ },
"node_modules/@citation-js/core": {
- "version": "0.7.11",
- "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.11.tgz",
- "integrity": "sha512-evQtyzeW+Gbmq+xWciIq9sbcvXXDbm8q32orD/HDd5ay6RQFKoW/BKxBLp+Nmpxgspb9sxTJn3iFK7+jxOTNTw==",
+ "version": "0.7.14",
+ "resolved": "https://registry.npmjs.org/@citation-js/core/-/core-0.7.14.tgz",
+ "integrity": "sha512-dgeGqYDSQmn2MtnWZkwPGpJQPh43yr1lAAr9jl1NJ9pIY1RXUQxtlAUZVur0V9PHdbfQC+kkvB1KC3VpgVV3MA==",
"license": "MIT",
"dependencies": {
"@citation-js/date": "^0.5.0",
@@ -348,9 +343,9 @@
}
},
"node_modules/@citation-js/plugin-bibtex": {
- "version": "0.7.11",
- "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.11.tgz",
- "integrity": "sha512-G4vEmLjrQUxgBIp3ffWN5dDOlwjPsrRSi/uTyxDJuFgKBD8GR1eO7Y/ZcePNAOHMqUxG7lxhhBbZJwcJZNVHYw==",
+ "version": "0.7.16",
+ "resolved": "https://registry.npmjs.org/@citation-js/plugin-bibtex/-/plugin-bibtex-0.7.16.tgz",
+ "integrity": "sha512-Udeli19VAoFjOw0H1bB1KgmekRoW6XP5cdR3OQF5c2Mt1tZatXWcSQVdq+FeLKzodRocZXG5NFRvjyUZjVbV6A==",
"license": "MIT",
"dependencies": {
"@citation-js/date": "^0.5.0",
@@ -377,22 +372,6 @@
"node": ">=14.0.0"
}
},
- "node_modules/@citation-js/plugin-csl": {
- "version": "0.7.11",
- "resolved": "https://registry.npmjs.org/@citation-js/plugin-csl/-/plugin-csl-0.7.11.tgz",
- "integrity": "sha512-4OGZ9wHZDfpgiPU2cOXWGuKt7P+ndGWAeLG95nOG+DXe5U+f9EEZTXfaM4C99x8Ri+g6JklR96A3kuYZxYLllg==",
- "license": "MIT",
- "dependencies": {
- "@citation-js/date": "^0.5.0",
- "citeproc": "^2.4.6"
- },
- "engines": {
- "node": ">=16.0.0"
- },
- "peerDependencies": {
- "@citation-js/core": "^0.7.0"
- }
- },
"node_modules/@citation-js/plugin-github": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/@citation-js/plugin-github/-/plugin-github-0.6.1.tgz",
@@ -461,9 +440,9 @@
}
},
"node_modules/@csstools/css-parser-algorithms": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.0.tgz",
- "integrity": "sha512-qvBMcOU/uWFCH/VO0MYe0AMs0BGMWAt6FTryMbFIKYtZtVnqTZtT8ktv5o718llkaGZWomJezJZjq3vJDHeJNQ==",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz",
+ "integrity": "sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==",
"dev": true,
"funding": [
{
@@ -477,16 +456,16 @@
],
"license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "@csstools/css-tokenizer": "^2.3.2"
+ "@csstools/css-tokenizer": "^3.0.3"
}
},
"node_modules/@csstools/css-tokenizer": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.3.2.tgz",
- "integrity": "sha512-0xYOf4pQpAaE6Sm2Q0x3p25oRukzWQ/O8hWVvhIt9Iv98/uu053u2CGm/g3kJ+P0vOYTAYzoU8Evq2pg9ZPXtw==",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz",
+ "integrity": "sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==",
"dev": true,
"funding": [
{
@@ -500,13 +479,13 @@
],
"license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
}
},
"node_modules/@csstools/media-query-list-parser": {
- "version": "2.1.12",
- "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.12.tgz",
- "integrity": "sha512-t1/CdyVJzOQUiGUcIBXRzTAkWTFPxiPnoKwowKW2z9Uj78c2bBWI/X94BeVfUwVq1xtCjD7dnO8kS6WONgp8Jw==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-3.0.1.tgz",
+ "integrity": "sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==",
"dev": true,
"funding": [
{
@@ -520,64 +499,20 @@
],
"license": "MIT",
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
- "@csstools/css-parser-algorithms": "^2.7.0",
- "@csstools/css-tokenizer": "^2.3.2"
- }
- },
- "node_modules/@csstools/selector-resolve-nested": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-1.1.0.tgz",
- "integrity": "sha512-uWvSaeRcHyeNenKg8tp17EVDRkpflmdyvbE0DHo6D/GdBb6PDnCYYU6gRpXhtICMGMcahQmj2zGxwFM/WC8hCg==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "license": "MIT-0",
- "engines": {
- "node": "^14 || ^16 || >=18"
- },
- "peerDependencies": {
- "postcss-selector-parser": "^6.0.13"
- }
- },
- "node_modules/@csstools/selector-specificity": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz",
- "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/csstools"
- },
- {
- "type": "opencollective",
- "url": "https://opencollective.com/csstools"
- }
- ],
- "license": "MIT-0",
- "engines": {
- "node": "^14 || ^16 || >=18"
- },
- "peerDependencies": {
- "postcss-selector-parser": "^6.0.13"
+ "@csstools/css-parser-algorithms": "^3.0.1",
+ "@csstools/css-tokenizer": "^3.0.1"
}
},
"node_modules/@discoveryjs/json-ext": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
- "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==",
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz",
+ "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==",
"license": "MIT",
"engines": {
- "node": ">=10.0.0"
+ "node": ">=14.17.0"
}
},
"node_modules/@dual-bundle/import-meta-resolve": {
@@ -591,10 +526,44 @@
"url": "https://github.com/sponsors/wooorm"
}
},
+ "node_modules/@emnapi/core": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.3.1.tgz",
+ "integrity": "sha512-pVGjBIt1Y6gg3EJN8jTcfpP/+uuRksIo055oE/OBkDNcjZqVbfkWCksG1Jp4yZnj3iKWyWX8fdG/j6UDYPbFog==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.0.1",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
+ "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.1.tgz",
+ "integrity": "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@esbuild/aix-ppc64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
- "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.1.tgz",
+ "integrity": "sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==",
"cpu": [
"ppc64"
],
@@ -604,13 +573,13 @@
"aix"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
- "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.1.tgz",
+ "integrity": "sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==",
"cpu": [
"arm"
],
@@ -620,13 +589,13 @@
"android"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
- "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.1.tgz",
+ "integrity": "sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==",
"cpu": [
"arm64"
],
@@ -636,13 +605,13 @@
"android"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
- "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.1.tgz",
+ "integrity": "sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==",
"cpu": [
"x64"
],
@@ -652,13 +621,13 @@
"android"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
- "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.1.tgz",
+ "integrity": "sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==",
"cpu": [
"arm64"
],
@@ -668,13 +637,13 @@
"darwin"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
- "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.1.tgz",
+ "integrity": "sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==",
"cpu": [
"x64"
],
@@ -684,13 +653,13 @@
"darwin"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
- "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.1.tgz",
+ "integrity": "sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==",
"cpu": [
"arm64"
],
@@ -700,13 +669,13 @@
"freebsd"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
- "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.1.tgz",
+ "integrity": "sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==",
"cpu": [
"x64"
],
@@ -716,13 +685,13 @@
"freebsd"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
- "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.1.tgz",
+ "integrity": "sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==",
"cpu": [
"arm"
],
@@ -732,13 +701,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
- "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.1.tgz",
+ "integrity": "sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==",
"cpu": [
"arm64"
],
@@ -748,13 +717,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
- "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.1.tgz",
+ "integrity": "sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==",
"cpu": [
"ia32"
],
@@ -764,13 +733,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
- "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.1.tgz",
+ "integrity": "sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==",
"cpu": [
"loong64"
],
@@ -780,13 +749,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
- "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.1.tgz",
+ "integrity": "sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==",
"cpu": [
"mips64el"
],
@@ -796,13 +765,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
- "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.1.tgz",
+ "integrity": "sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==",
"cpu": [
"ppc64"
],
@@ -812,13 +781,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
- "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.1.tgz",
+ "integrity": "sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==",
"cpu": [
"riscv64"
],
@@ -828,13 +797,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
- "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.1.tgz",
+ "integrity": "sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==",
"cpu": [
"s390x"
],
@@ -844,13 +813,13 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
- "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.1.tgz",
+ "integrity": "sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==",
"cpu": [
"x64"
],
@@ -860,13 +829,29 @@
"linux"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.1.tgz",
+ "integrity": "sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
- "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.1.tgz",
+ "integrity": "sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==",
"cpu": [
"x64"
],
@@ -876,13 +861,29 @@
"netbsd"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.1.tgz",
+ "integrity": "sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==",
+ "cpu": [
+ "arm64"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
- "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.1.tgz",
+ "integrity": "sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==",
"cpu": [
"x64"
],
@@ -892,13 +893,13 @@
"openbsd"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
- "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.1.tgz",
+ "integrity": "sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==",
"cpu": [
"x64"
],
@@ -908,13 +909,13 @@
"sunos"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
- "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.1.tgz",
+ "integrity": "sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==",
"cpu": [
"arm64"
],
@@ -924,13 +925,13 @@
"win32"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
- "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.1.tgz",
+ "integrity": "sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==",
"cpu": [
"ia32"
],
@@ -940,13 +941,13 @@
"win32"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
- "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.1.tgz",
+ "integrity": "sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==",
"cpu": [
"x64"
],
@@ -956,13 +957,13 @@
"win32"
],
"engines": {
- "node": ">=12"
+ "node": ">=18"
}
},
"node_modules/@eslint-community/eslint-plugin-eslint-comments": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.3.0.tgz",
- "integrity": "sha512-6e93KtgsndNkvwCCa07LOQJSwzzLLxwrFll3+huyFoiiQXWG0KBcmo0Q1bVgYQQDLfWOOZl2VPBsXqZL6vHIBQ==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.4.1.tgz",
+ "integrity": "sha512-lb/Z/MzbTf7CaVYM9WCFNQZ4L1yi3ev2fsFPF99h31ljhSEyUoyEsKsNWiU+qD1glbYTDJdqgyaLKtyTkkqtuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -972,47 +973,128 @@
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
"peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
}
},
"node_modules/@eslint-community/eslint-utils": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
- "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+ "version": "4.5.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz",
+ "integrity": "sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "eslint-visitor-keys": "^3.3.0"
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
"peerDependencies": {
"eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
}
},
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
"node_modules/@eslint-community/regexpp": {
- "version": "4.11.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz",
- "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==",
+ "version": "4.12.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+ "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
+ "node_modules/@eslint/config-array": {
+ "version": "0.19.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
+ "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.6",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/@eslint/config-array/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.1.0.tgz",
+ "integrity": "sha512-kLrdPDJE1ckPo94kmPPf9Hfd0DU0Jw6oKYrhe+pwSC0iTUInmTa+w6fw8sGgcfkFJGNdWOUeOaDM4quW4a7OkA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
+ "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
"node_modules/@eslint/eslintrc": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
- "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz",
+ "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ajv": "^6.12.4",
"debug": "^4.3.2",
- "espree": "^9.6.0",
- "globals": "^13.19.0",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
"ignore": "^5.2.0",
"import-fresh": "^3.2.1",
"js-yaml": "^4.1.0",
@@ -1020,7 +1102,7 @@
"strip-json-comments": "^3.1.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
@@ -1054,6 +1136,19 @@
"concat-map": "0.0.1"
}
},
+ "node_modules/@eslint/eslintrc/node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
@@ -1075,21 +1170,38 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
- "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
+ "version": "9.22.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.22.0.tgz",
+ "integrity": "sha512-vLFajx9o8d1/oL2ZkpMYbkLv8nDB6yaIwFNt7nI4+I80U/z03SxmfOMsLbvWr3p7C+Wnoh//aOu2pQW8cS0HCQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
- "node_modules/@github/browserslist-config": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@github/browserslist-config/-/browserslist-config-1.0.0.tgz",
- "integrity": "sha512-gIhjdJp/c2beaIWWIlsXdqXVRUz3r2BxBCpfz/F3JXHvSAQ1paMYjLH+maEATtENg+k5eLV7gA+9yPp762ieuw==",
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+ "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
"dev": true,
- "license": "MIT"
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz",
+ "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.12.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
},
"node_modules/@github/combobox-nav": {
"version": "2.3.1",
@@ -1103,60 +1215,64 @@
"integrity": "sha512-AlquKGee+IWiAMYVB0xyHFZRMnu4n3X4HTvJHu79GiVJ1ojTukCWyxMlF5NMsecoLcBKsuBhx3QPv2vkE/zQ0A==",
"license": "MIT"
},
+ "node_modules/@github/quote-selection": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@github/quote-selection/-/quote-selection-2.1.0.tgz",
+ "integrity": "sha512-zyTvG6GpfWuVrRnxa/JpWPlTyj8ItTCMHXNrdXrvNPrSFCsDAiqEaxTW+644lwxXNfzTPQeN11paR9SRRvE2zg==",
+ "license": "MIT"
+ },
"node_modules/@github/relative-time-element": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.4.2.tgz",
- "integrity": "sha512-wTXunu3hmuGljA5CHaaoUIKV0oI35wno0FKJl2yqKplTRnsCA5bPNj4bDeVIubkuskql6jwionWLlGM1Y6QLaw==",
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/@github/relative-time-element/-/relative-time-element-4.4.5.tgz",
+ "integrity": "sha512-9ejPtayBDIJfEU8x1fg/w2o5mahHkkp1SC6uObDtoKs4Gn+2a1vNK8XIiNDD8rMeEfpvDjydgSZZ+uk+7N0VsQ==",
"license": "MIT"
},
"node_modules/@github/text-expander-element": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.7.1.tgz",
- "integrity": "sha512-CWxfYxJRkeWVCUhJveproLs6pHsPrWtK8TsjL8ByYVcSCs8CJmNzF8b7ZawrUgfai0F2jb4aIdw2FoBTykj9XA==",
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/@github/text-expander-element/-/text-expander-element-2.8.0.tgz",
+ "integrity": "sha512-kkS2rZ/CG8HGKblpLDQ8vcK/K7l/Jsvzi/N4ovwPAsFSOImcIbJh2MgCv9tzqE3wAm/qXlscvh3Ms4Hh1vtZvw==",
"license": "MIT",
"dependencies": {
"@github/combobox-nav": "^2.0.2",
- "dom-input-range": "^1.1.6"
+ "dom-input-range": "^1.2.0"
}
},
- "node_modules/@humanwhocodes/config-array": {
- "version": "0.11.14",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
- "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
- "deprecated": "Use @eslint/config-array instead",
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.6",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
+ "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@humanwhocodes/object-schema": "^2.0.2",
- "debug": "^4.3.1",
- "minimatch": "^3.0.5"
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.3.0"
},
"engines": {
- "node": ">=10.10.0"
+ "node": ">=18.18.0"
}
},
- "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
+ "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
+ "license": "Apache-2.0",
"engines": {
- "node": "*"
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
}
},
"node_modules/@humanwhocodes/module-importer": {
@@ -1173,13 +1289,53 @@
"url": "https://github.com/sponsors/nzakas"
}
},
- "node_modules/@humanwhocodes/object-schema": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
- "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
- "deprecated": "Use @eslint/object-schema instead",
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz",
+ "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==",
"dev": true,
- "license": "BSD-3-Clause"
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@iconify/types": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
+ "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==",
+ "license": "MIT"
+ },
+ "node_modules/@iconify/utils": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz",
+ "integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==",
+ "license": "MIT",
+ "dependencies": {
+ "@antfu/install-pkg": "^1.0.0",
+ "@antfu/utils": "^8.1.0",
+ "@iconify/types": "^2.0.0",
+ "debug": "^4.4.0",
+ "globals": "^15.14.0",
+ "kolorist": "^1.8.0",
+ "local-pkg": "^1.0.0",
+ "mlly": "^1.7.4"
+ }
+ },
+ "node_modules/@iconify/utils/node_modules/globals": {
+ "version": "15.15.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
+ "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
},
"node_modules/@isaacs/cliui": {
"version": "8.0.2",
@@ -1199,9 +1355,9 @@
}
},
"node_modules/@isaacs/cliui/node_modules/ansi-regex": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
- "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -1222,6 +1378,12 @@
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "license": "MIT"
+ },
"node_modules/@isaacs/cliui/node_modules/string-width": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
@@ -1281,23 +1443,10 @@
"node": ">=8"
}
},
- "node_modules/@jest/schemas": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
- "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@sinclair/typebox": "^0.27.8"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/@jridgewell/gen-mapping": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
- "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
+ "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
@@ -1337,9 +1486,9 @@
}
},
"node_modules/@jridgewell/sourcemap-codec": {
- "version": "1.4.15",
- "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
- "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
@@ -1352,10 +1501,23 @@
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
+ "node_modules/@jsep-plugin/assignment": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz",
+ "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.16.0"
+ },
+ "peerDependencies": {
+ "jsep": "^0.4.0||^1.0.0"
+ }
+ },
"node_modules/@jsep-plugin/regex": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.3.tgz",
- "integrity": "sha512-XfZgry4DwEZvSFtS/6Y+R48D7qJYJK6R9/yJFyUFHCIUMEEHuJ4X95TDgJp5QkmzfLYvapMPzskV5HpIDrREug==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz",
+ "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1366,9 +1528,9 @@
}
},
"node_modules/@jsep-plugin/ternary": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.3.tgz",
- "integrity": "sha512-qtLGzCNzPVJ3kdH6/zoLWDPjauHIKiLSBAR71Wa0+PWvGA8wODUQvRgxtpUA5YqAYL3CQ8S4qXhd/9WuWTZirg==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@jsep-plugin/ternary/-/ternary-1.1.4.tgz",
+ "integrity": "sha512-ck5wiqIbqdMX6WRQztBL7ASDty9YLgJ3sSAK5ZpBzXeySvFGCzIvM6UiAI4hTZ22fEcYQVV/zhUbNscggW+Ukg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -1378,10 +1540,45 @@
"jsep": "^0.4.0||^1.0.0"
}
},
+ "node_modules/@keyv/serialize": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.0.3.tgz",
+ "integrity": "sha512-qnEovoOp5Np2JDGonIDL6Ayihw0RhnRh6vxPuHo4RDn1UOzwEo4AeIfpL6UGIrsceWrCMiVPgwRjbHu4vYFc3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "buffer": "^6.0.3"
+ }
+ },
+ "node_modules/@keyv/serialize/node_modules/buffer": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+ "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.2.1"
+ }
+ },
"node_modules/@kurkle/color": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz",
- "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==",
+ "version": "0.3.4",
+ "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz",
+ "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==",
"license": "MIT"
},
"node_modules/@mcaptcha/core-glue": {
@@ -1435,6 +1632,28 @@
"@mcaptcha/core-glue": "^0.1.0-alpha-5"
}
},
+ "node_modules/@mermaid-js/parser": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.3.0.tgz",
+ "integrity": "sha512-HsvL6zgE5sUPGgkIDlmAWR1HTNHz2Iy11BAWPTa4Jjabkpguy4Ze2gzfLrg6pdRuBvFwgUYyxiaNqZwrEEXepA==",
+ "license": "MIT",
+ "dependencies": {
+ "langium": "3.0.0"
+ }
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.7.tgz",
+ "integrity": "sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "^1.3.1",
+ "@emnapi/runtime": "^1.3.1",
+ "@tybys/wasm-util": "^0.9.0"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -1470,6 +1689,19 @@
"node": ">= 8"
}
},
+ "node_modules/@npmcli/fs": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz",
+ "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
"node_modules/@one-ini/wasm": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
@@ -1477,6 +1709,163 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@oxc-resolver/binding-darwin-arm64": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-arm64/-/binding-darwin-arm64-5.0.1.tgz",
+ "integrity": "sha512-lY5mi+6ztYGM9tiyMhHbzZteE7LFaexu9PjDL2N0stCNuGkSHO1eeeabi2ckxGWBbu9EW01XovbQqir12NbA6A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@oxc-resolver/binding-darwin-x64": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-darwin-x64/-/binding-darwin-x64-5.0.1.tgz",
+ "integrity": "sha512-wHKdPB2Q0dMVQy6b5depG8IGI0Y37CIUTZYrZDYEGMT3X481DAJjp6AIVVHQeolEZzy+lWrpUQdGPy0dQnt7IA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@oxc-resolver/binding-freebsd-x64": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-freebsd-x64/-/binding-freebsd-x64-5.0.1.tgz",
+ "integrity": "sha512-TchNkHMASh2vZ2/FH71zqgAUNYuAlP8Bm1ocSnt7UVV43jZ9kG8HtQFc3AsYeVGzw06LZoeE3mVdSQVXUZhgzA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@oxc-resolver/binding-linux-arm-gnueabihf": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-5.0.1.tgz",
+ "integrity": "sha512-JhqYi6uTSYflXSDNG/ZPTvBUcvcPR+vr/09XLdWJpZfEYzpPEEr7YQ2ogiOfZVUmCZOJWVOP8jJdv735j46a5w==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@oxc-resolver/binding-linux-arm64-gnu": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-5.0.1.tgz",
+ "integrity": "sha512-W2OXq25tYiFVhi0Eioc9b+KWnaK2Hj7x/eW2u6r6u4afd1cQ09U+o5u98jrj1rxowSOTfFyiKqMqQOrS4PAlFg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@oxc-resolver/binding-linux-arm64-musl": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-arm64-musl/-/binding-linux-arm64-musl-5.0.1.tgz",
+ "integrity": "sha512-dYaXmy90L5fTpH0mWmWvsf5PC9me5Lyjcj5vOQYNVedSQUavGMbQ+sKOWOTAFIpS8xzzIhYRdLI7oj4WV9S2bQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@oxc-resolver/binding-linux-x64-gnu": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-gnu/-/binding-linux-x64-gnu-5.0.1.tgz",
+ "integrity": "sha512-lOgcxgtV7nM4TjolWgW9qk05iDQE2GGZTx2Zr+Jj+4GqdIhkkGpbqyGPJx2FRsY6kXhyaA9eOad4Bldfo8vAaw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@oxc-resolver/binding-linux-x64-musl": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-linux-x64-musl/-/binding-linux-x64-musl-5.0.1.tgz",
+ "integrity": "sha512-3Pg8eSolVs3hy3xoqkjCgoIC1uHKPAUY0rs4QX+KtsPMOZ7iO5b3JBbJHl+ZDIeuzE8dkSRG7aIuCNVonp5G1Q==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@oxc-resolver/binding-wasm32-wasi": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-wasm32-wasi/-/binding-wasm32-wasi-5.0.1.tgz",
+ "integrity": "sha512-rBEgV5AW5obb6ATeNUSUouW0FzpoADOweTYblprko+Cv6rW1NSQGzGxD6o6jhIk4yV7/CZBwBWAkz9xpL5JSUQ==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^0.2.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@oxc-resolver/binding-win32-arm64-msvc": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-5.0.1.tgz",
+ "integrity": "sha512-okHg9C+z+2tCGKPszYVJDTZKhPHta7xKvhw0WMWPLTz9wbBMmHTuY9vVpgvFGhTU3N5iQ56LPollnSPtjvObCw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@oxc-resolver/binding-win32-x64-msvc": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-5.0.1.tgz",
+ "integrity": "sha512-ODlCn4Pbd0HEWMixonax1uJtNCG4lEne6Jq98iUsmwSibQYcBzutxPed1qhLKur6KtCsYYa4LtRxys7e/5lZwQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
"node_modules/@pkgjs/parseargs": {
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@@ -1487,27 +1876,14 @@
"node": ">=14"
}
},
- "node_modules/@pkgr/core": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz",
- "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.20.0 || ^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/unts"
- }
- },
"node_modules/@playwright/test": {
- "version": "1.45.0",
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.45.0.tgz",
- "integrity": "sha512-TVYsfMlGAaxeUllNkywbwek67Ncf8FRGn8ZlRdO291OL3NjG9oMbfVhyP82HQF0CZLMrYsvesqoUekxdWuF9Qw==",
+ "version": "1.51.0",
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.51.0.tgz",
+ "integrity": "sha512-dJ0dMbZeHhI+wb77+ljx/FeC8VBP6j/rj9OAojO08JI80wTZy6vRk9KvHKiDCUh4iMpEiseMgqRBIeW+eKX6RA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "playwright": "1.45.0"
+ "playwright": "1.51.0"
},
"bin": {
"playwright": "cli.js"
@@ -1527,9 +1903,9 @@
}
},
"node_modules/@primer/octicons": {
- "version": "19.9.0",
- "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-19.9.0.tgz",
- "integrity": "sha512-uAZa9cMgWkzbEsZnYWB7tg0vt7QprubD7ljtprz2fBJ8CjyqoxFRRsFvH4UiJdjK/3o87ODgDkhiflyJXDh+Lg==",
+ "version": "19.14.0",
+ "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-19.14.0.tgz",
+ "integrity": "sha512-9Ovw/xcUFHC/zbsNhr/Hkp1+m9XnNeQvnGHDHrI5vhlf6PRZVzSsdMnesV2xCzQh7jXP3EVRcaeXsUGlsZrfcA==",
"license": "MIT",
"dependencies": {
"object-assign": "^4.1.1"
@@ -1583,9 +1959,9 @@
"license": "MIT"
},
"node_modules/@rollup/rollup-android-arm-eabi": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz",
- "integrity": "sha512-Tya6xypR10giZV1XzxmH5wr25VcZSncG0pZIjfePT0OVBvqNEurzValetGNarVrGiq66EBVAFn15iYX4w6FKgQ==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.37.0.tgz",
+ "integrity": "sha512-l7StVw6WAa8l3vA1ov80jyetOAEo1FtHvZDbzXDO/02Sq/QVvqlHkYoFwDJPIMj0GKiistsBudfx5tGFnwYWDQ==",
"cpu": [
"arm"
],
@@ -1597,9 +1973,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.0.tgz",
- "integrity": "sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.37.0.tgz",
+ "integrity": "sha512-6U3SlVyMxezt8Y+/iEBcbp945uZjJwjZimu76xoG7tO1av9VO691z8PkhzQ85ith2I8R2RddEPeSfcbyPfD4hA==",
"cpu": [
"arm64"
],
@@ -1611,9 +1987,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.0.tgz",
- "integrity": "sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.37.0.tgz",
+ "integrity": "sha512-+iTQ5YHuGmPt10NTzEyMPbayiNTcOZDWsbxZYR1ZnmLnZxG17ivrPSWFO9j6GalY0+gV3Jtwrrs12DBscxnlYA==",
"cpu": [
"arm64"
],
@@ -1625,9 +2001,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.0.tgz",
- "integrity": "sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.37.0.tgz",
+ "integrity": "sha512-m8W2UbxLDcmRKVjgl5J/k4B8d7qX2EcJve3Sut7YGrQoPtCIQGPH5AMzuFvYRWZi0FVS0zEY4c8uttPfX6bwYQ==",
"cpu": [
"x64"
],
@@ -1638,10 +2014,38 @@
"darwin"
]
},
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.37.0.tgz",
+ "integrity": "sha512-FOMXGmH15OmtQWEt174v9P1JqqhlgYge/bUjIbiVD1nI1NeJ30HYT9SJlZMqdo1uQFyt9cz748F1BHghWaDnVA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.37.0.tgz",
+ "integrity": "sha512-SZMxNttjPKvV14Hjck5t70xS3l63sbVwl98g3FlVVx2YIDmfUIy29jQrsw06ewEYQ8lQSuY9mpAPlmgRD2iSsA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.0.tgz",
- "integrity": "sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.37.0.tgz",
+ "integrity": "sha512-hhAALKJPidCwZcj+g+iN+38SIOkhK2a9bqtJR+EtyxrKKSt1ynCBeqrQy31z0oWU6thRZzdx53hVgEbRkuI19w==",
"cpu": [
"arm"
],
@@ -1653,9 +2057,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.0.tgz",
- "integrity": "sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.37.0.tgz",
+ "integrity": "sha512-jUb/kmn/Gd8epbHKEqkRAxq5c2EwRt0DqhSGWjPFxLeFvldFdHQs/n8lQ9x85oAeVb6bHcS8irhTJX2FCOd8Ag==",
"cpu": [
"arm"
],
@@ -1667,9 +2071,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.0.tgz",
- "integrity": "sha512-rJ5D47d8WD7J+7STKdCUAgmQk49xuFrRi9pZkWoRD1UeSMakbcepWXPF8ycChBoAqs1pb2wzvbY6Q33WmN2ftw==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.37.0.tgz",
+ "integrity": "sha512-oNrJxcQT9IcbcmKlkF+Yz2tmOxZgG9D9GRq+1OE6XCQwCVwxixYAa38Z8qqPzQvzt1FCfmrHX03E0pWoXm1DqA==",
"cpu": [
"arm64"
],
@@ -1681,9 +2085,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.0.tgz",
- "integrity": "sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.37.0.tgz",
+ "integrity": "sha512-pfxLBMls+28Ey2enpX3JvjEjaJMBX5XlPCZNGxj4kdJyHduPBXtxYeb8alo0a7bqOoWZW2uKynhHxF/MWoHaGQ==",
"cpu": [
"arm64"
],
@@ -1694,10 +2098,24 @@
"linux"
]
},
+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.37.0.tgz",
+ "integrity": "sha512-yCE0NnutTC/7IGUq/PUHmoeZbIwq3KRh02e9SfFh7Vmc1Z7atuJRYWhRME5fKgT8aS20mwi1RyChA23qSyRGpA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.0.tgz",
- "integrity": "sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.37.0.tgz",
+ "integrity": "sha512-NxcICptHk06E2Lh3a4Pu+2PEdZ6ahNHuK7o6Np9zcWkrBMuv21j10SQDJW3C9Yf/A/P7cutWoC/DptNLVsZ0VQ==",
"cpu": [
"ppc64"
],
@@ -1709,9 +2127,23 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.0.tgz",
- "integrity": "sha512-ROCM7i+m1NfdrsmvwSzoxp9HFtmKGHEqu5NNDiZWQtXLA8S5HBCkVvKAxJ8U+CVctHwV2Gb5VUaK7UAkzhDjlg==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.37.0.tgz",
+ "integrity": "sha512-PpWwHMPCVpFZLTfLq7EWJWvrmEuLdGn1GMYcm5MV7PaRgwCEYJAwiN94uBuZev0/J/hFIIJCsYw4nLmXA9J7Pw==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.37.0.tgz",
+ "integrity": "sha512-DTNwl6a3CfhGTAOYZ4KtYbdS8b+275LSLqJVJIrPa5/JuIufWWZ/QFvkxp52gpmguN95eujrM68ZG+zVxa8zHA==",
"cpu": [
"riscv64"
],
@@ -1723,9 +2155,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.0.tgz",
- "integrity": "sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.37.0.tgz",
+ "integrity": "sha512-hZDDU5fgWvDdHFuExN1gBOhCuzo/8TMpidfOR+1cPZJflcEzXdCy1LjnklQdW8/Et9sryOPJAKAQRw8Jq7Tg+A==",
"cpu": [
"s390x"
],
@@ -1737,9 +2169,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz",
- "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.37.0.tgz",
+ "integrity": "sha512-pKivGpgJM5g8dwj0ywBwe/HeVAUSuVVJhUTa/URXjxvoyTT/AxsLTAbkHkDHG7qQxLoW2s3apEIl26uUe08LVQ==",
"cpu": [
"x64"
],
@@ -1751,9 +2183,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.0.tgz",
- "integrity": "sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.37.0.tgz",
+ "integrity": "sha512-E2lPrLKE8sQbY/2bEkVTGDEk4/49UYRVWgj90MY8yPjpnGBQ+Xi1Qnr7b7UIWw1NOggdFQFOLZ8+5CzCiz143w==",
"cpu": [
"x64"
],
@@ -1765,9 +2197,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.0.tgz",
- "integrity": "sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.37.0.tgz",
+ "integrity": "sha512-Jm7biMazjNzTU4PrQtr7VS8ibeys9Pn29/1bm4ph7CP2kf21950LgN+BaE2mJ1QujnvOc6p54eWWiVvn05SOBg==",
"cpu": [
"arm64"
],
@@ -1779,9 +2211,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.0.tgz",
- "integrity": "sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.37.0.tgz",
+ "integrity": "sha512-e3/1SFm1OjefWICB2Ucstg2dxYDkDTZGDYgwufcbsxTHyqQps1UQf33dFEChBNmeSsTOyrjw2JJq0zbG5GF6RA==",
"cpu": [
"ia32"
],
@@ -1793,9 +2225,9 @@
]
},
"node_modules/@rollup/rollup-win32-x64-msvc": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.0.tgz",
- "integrity": "sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.37.0.tgz",
+ "integrity": "sha512-LWbXUBwn/bcLx2sSsqy7pK5o+Nr+VCoRoAohfJ5C/aBio9nfJmGQqHAhU6pwxV/RmyTk5AqdySma7uwWGlmeuA==",
"cpu": [
"x64"
],
@@ -1806,13 +2238,6 @@
"win32"
]
},
- "node_modules/@sinclair/typebox": {
- "version": "0.27.8",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
- "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/@stoplight/better-ajv-errors": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@stoplight/better-ajv-errors/-/better-ajv-errors-1.0.3.tgz",
@@ -1831,9 +2256,9 @@
}
},
"node_modules/@stoplight/json": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.0.tgz",
- "integrity": "sha512-5O0apqJ/t4sIevXCO3SBN9AHCEKKR/Zb4gaj7wYe5863jme9g02Q0n/GhM7ZCALkL+vGPTe4ZzTETP8TFtsw3g==",
+ "version": "3.21.7",
+ "resolved": "https://registry.npmjs.org/@stoplight/json/-/json-3.21.7.tgz",
+ "integrity": "sha512-xcJXgKFqv/uCEgtGlPxy3tPA+4I+ZI4vAuMJ885+ThkTHFVkC+0Fm58lA9NlsyjnkpxFh4YiQWpH+KefHdbA0A==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -1912,20 +2337,20 @@
}
},
"node_modules/@stoplight/spectral-cli": {
- "version": "6.11.1",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.11.1.tgz",
- "integrity": "sha512-1zqsQ0TOuVSnxxZ9mHBfC0IygV6ex7nAY6Mp59mLmw5fW103U9yPVK5ZcX9ZngCmr3PdteAnMDUIIaoDGso6nA==",
+ "version": "6.14.3",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.14.3.tgz",
+ "integrity": "sha512-vKy7d2yqBfOf94uB6KXzujDl6/qjXa8mCQ6cfsQ8xYsoArZN9iBHpS3271hR5IyTm3R1GwMgaSZ1h0sfZjZrZw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@stoplight/json": "~3.21.0",
"@stoplight/path": "1.3.2",
- "@stoplight/spectral-core": "^1.18.3",
- "@stoplight/spectral-formatters": "^1.3.0",
- "@stoplight/spectral-parsers": "^1.0.3",
+ "@stoplight/spectral-core": "^1.19.5",
+ "@stoplight/spectral-formatters": "^1.4.1",
+ "@stoplight/spectral-parsers": "^1.0.4",
"@stoplight/spectral-ref-resolver": "^1.0.4",
- "@stoplight/spectral-ruleset-bundler": "^1.5.2",
- "@stoplight/spectral-ruleset-migrator": "^1.9.5",
+ "@stoplight/spectral-ruleset-bundler": "^1.6.0",
+ "@stoplight/spectral-ruleset-migrator": "^1.11.0",
"@stoplight/spectral-rulesets": ">=1",
"@stoplight/spectral-runtime": "^1.1.2",
"@stoplight/types": "^13.6.0",
@@ -1933,16 +2358,16 @@
"fast-glob": "~3.2.12",
"hpagent": "~1.2.0",
"lodash": "~4.17.21",
- "pony-cause": "^1.0.0",
- "stacktracey": "^2.1.7",
- "tslib": "^2.3.0",
+ "pony-cause": "^1.1.1",
+ "stacktracey": "^2.1.8",
+ "tslib": "^2.8.1",
"yargs": "~17.7.2"
},
"bin": {
"spectral": "dist/index.js"
},
"engines": {
- "node": "^12.20 || >= 14.13"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-cli/node_modules/fast-glob": {
@@ -1976,9 +2401,9 @@
}
},
"node_modules/@stoplight/spectral-core": {
- "version": "1.18.3",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.18.3.tgz",
- "integrity": "sha512-YY8x7X2SWJIhGTLPol+eFiQpWPz0D0mJdkK2i4A0QJG68KkNhypP6+JBC7/Kz3XWjqr0L/RqAd+N5cQLPOKZGQ==",
+ "version": "1.19.5",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.19.5.tgz",
+ "integrity": "sha512-i+njdliW7bAHGsHEgDvH0To/9IxiYiBELltkZ7ASVy4i+WXtZ40lQXpeRQRwePrBcSgQl0gcZFuKX10nmSHtbw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -1986,26 +2411,26 @@
"@stoplight/json": "~3.21.0",
"@stoplight/path": "1.3.2",
"@stoplight/spectral-parsers": "^1.0.0",
- "@stoplight/spectral-ref-resolver": "^1.0.0",
- "@stoplight/spectral-runtime": "^1.0.0",
+ "@stoplight/spectral-ref-resolver": "^1.0.4",
+ "@stoplight/spectral-runtime": "^1.1.2",
"@stoplight/types": "~13.6.0",
"@types/es-aggregate-error": "^1.0.2",
"@types/json-schema": "^7.0.11",
- "ajv": "^8.6.0",
+ "ajv": "^8.17.1",
"ajv-errors": "~3.0.0",
- "ajv-formats": "~2.1.0",
+ "ajv-formats": "~2.1.1",
"es-aggregate-error": "^1.0.7",
- "jsonpath-plus": "7.1.0",
+ "jsonpath-plus": "^10.3.0",
"lodash": "~4.17.21",
"lodash.topath": "^4.5.2",
"minimatch": "3.1.2",
- "nimma": "0.2.2",
- "pony-cause": "^1.0.0",
- "simple-eval": "1.0.0",
- "tslib": "^2.3.0"
+ "nimma": "0.2.3",
+ "pony-cause": "^1.1.1",
+ "simple-eval": "1.0.1",
+ "tslib": "^2.8.1"
},
"engines": {
- "node": "^12.20 || >= 14.13"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-core/node_modules/@stoplight/types": {
@@ -2047,81 +2472,83 @@
}
},
"node_modules/@stoplight/spectral-formats": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.6.0.tgz",
- "integrity": "sha512-X27qhUfNluiduH0u/QwJqhOd8Wk5YKdxVmKM03Aijlx0AH1H5mYt3l9r7t2L4iyJrsBaFPnMGt7UYJDGxszbNA==",
+ "version": "1.8.2",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-formats/-/spectral-formats-1.8.2.tgz",
+ "integrity": "sha512-c06HB+rOKfe7tuxg0IdKDEA5XnjL2vrn/m/OVIIxtINtBzphZrOgtRn7epQ5bQF5SWp84Ue7UJWaGgDwVngMFw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@stoplight/json": "^3.17.0",
- "@stoplight/spectral-core": "^1.8.0",
+ "@stoplight/spectral-core": "^1.19.2",
"@types/json-schema": "^7.0.7",
- "tslib": "^2.3.1"
+ "tslib": "^2.8.1"
},
"engines": {
- "node": ">=12"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-formatters": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-formatters/-/spectral-formatters-1.3.0.tgz",
- "integrity": "sha512-ryuMwlzbPUuyn7ybSEbFYsljYmvTaTyD51wyCQs4ROzgfm3Yo5QDD0IsiJUzUpKK/Ml61ZX8ebgiPiRFEJtBpg==",
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-formatters/-/spectral-formatters-1.4.3.tgz",
+ "integrity": "sha512-03Nc6nhjMO9aHhJPgBH4zDwMPklKLWEMtvx+PMmzfStCndMjJkf8ki7O/55u3myZ1TwxBzln9z9tXPLSL3KKhw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@stoplight/path": "^1.3.2",
- "@stoplight/spectral-core": "^1.15.1",
- "@stoplight/spectral-runtime": "^1.1.0",
+ "@stoplight/spectral-core": "^1.19.4",
+ "@stoplight/spectral-runtime": "^1.1.2",
"@stoplight/types": "^13.15.0",
+ "@types/markdown-escape": "^1.1.3",
"chalk": "4.1.2",
"cliui": "7.0.4",
"lodash": "^4.17.21",
+ "markdown-escape": "^2.0.0",
"node-sarif-builder": "^2.0.3",
"strip-ansi": "6.0",
"text-table": "^0.2.0",
- "tslib": "^2.5.0"
+ "tslib": "^2.8.1"
},
"engines": {
- "node": "^12.20 || >=14.13"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-functions": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.8.0.tgz",
- "integrity": "sha512-ZrAkYA/ZGbuQ6EyG1gisF4yQ5nWP/+glcqVoGmS6kH6ekaynz2Yp6FL0oIamWj3rWedFUN7ppwTRUdo+9f/uCw==",
+ "version": "1.9.4",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.9.4.tgz",
+ "integrity": "sha512-+dgu7QQ1JIZFsNLhNbQLPA9tniIT3KjOc9ORv0LYSCLvZjkWT2bN7vgmathbXsbmhnmhvl15H9sRqUIqzi+qoQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@stoplight/better-ajv-errors": "1.0.3",
"@stoplight/json": "^3.17.1",
- "@stoplight/spectral-core": "^1.7.0",
- "@stoplight/spectral-formats": "^1.0.0",
- "@stoplight/spectral-runtime": "^1.1.0",
- "ajv": "^8.6.3",
+ "@stoplight/spectral-core": "^1.19.4",
+ "@stoplight/spectral-formats": "^1.8.1",
+ "@stoplight/spectral-runtime": "^1.1.2",
+ "ajv": "^8.17.1",
"ajv-draft-04": "~1.0.0",
"ajv-errors": "~3.0.0",
- "ajv-formats": "~2.1.0",
+ "ajv-formats": "~2.1.1",
"lodash": "~4.17.21",
- "tslib": "^2.3.0"
+ "tslib": "^2.8.1"
},
"engines": {
- "node": ">=12"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-parsers": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.4.tgz",
- "integrity": "sha512-nCTVvtX6q71M8o5Uvv9kxU31Gk1TRmgD6/k8HBhdCmKG6FWcwgjiZouA/R3xHLn/VwTI/9k8SdG5Mkdy0RBqbQ==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-parsers/-/spectral-parsers-1.0.5.tgz",
+ "integrity": "sha512-ANDTp2IHWGvsQDAY85/jQi9ZrF4mRrA5bciNHX+PUxPr4DwS6iv4h+FVWJMVwcEYdpyoIdyL+SRmHdJfQEPmwQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@stoplight/json": "~3.21.0",
"@stoplight/types": "^14.1.1",
"@stoplight/yaml": "~4.3.0",
- "tslib": "^2.3.1"
+ "tslib": "^2.8.1"
},
"engines": {
- "node": "^12.20 || >=14.13"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-parsers/node_modules/@stoplight/types": {
@@ -2139,9 +2566,9 @@
}
},
"node_modules/@stoplight/spectral-ref-resolver": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-ref-resolver/-/spectral-ref-resolver-1.0.4.tgz",
- "integrity": "sha512-5baQIYL0NJTSVy8v6RxOR4U51xOUYM8wJri1YvlAT6bPN8m0EIxMwfVYi0xUZEMVeHcWx869nIkoqyWmOutF2A==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-ref-resolver/-/spectral-ref-resolver-1.0.5.tgz",
+ "integrity": "sha512-gj3TieX5a9zMW29z3mBlAtDOCgN3GEc1VgZnCVlr5irmR4Qi5LuECuFItAq4pTn5Zu+sW5bqutsCH7D4PkpyAA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -2149,64 +2576,64 @@
"@stoplight/json-ref-resolver": "~3.1.6",
"@stoplight/spectral-runtime": "^1.1.2",
"dependency-graph": "0.11.0",
- "tslib": "^2.3.1"
+ "tslib": "^2.8.1"
},
"engines": {
- "node": ">=12"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-ruleset-bundler": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.5.2.tgz",
- "integrity": "sha512-4QUVUFAU+S7IQ9XeCu+0TQMYxKFpKnkOAfa9unRQ1iPL2cviaipEN6witpbAptdHJD3UUjx4OnwlX8WwmXSq9w==",
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.6.2.tgz",
+ "integrity": "sha512-Tg7y/0e/6yY4hiebh9YLUGa/fHcgI6RyjfBcRGipYU7QDcJUn2UZYSzeC9hggMwT0UiRzdQlch0aEl7L4VL1GQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@rollup/plugin-commonjs": "~22.0.2",
"@stoplight/path": "1.3.2",
"@stoplight/spectral-core": ">=1",
- "@stoplight/spectral-formats": ">=1",
+ "@stoplight/spectral-formats": "^1.8.1",
"@stoplight/spectral-functions": ">=1",
"@stoplight/spectral-parsers": ">=1",
- "@stoplight/spectral-ref-resolver": ">=1",
- "@stoplight/spectral-ruleset-migrator": "^1.7.4",
+ "@stoplight/spectral-ref-resolver": "^1.0.4",
+ "@stoplight/spectral-ruleset-migrator": "^1.9.6",
"@stoplight/spectral-rulesets": ">=1",
- "@stoplight/spectral-runtime": "^1.1.0",
+ "@stoplight/spectral-runtime": "^1.1.2",
"@stoplight/types": "^13.6.0",
"@types/node": "*",
"pony-cause": "1.1.1",
- "rollup": "~2.79.0",
- "tslib": "^2.3.1",
+ "rollup": "~2.79.2",
+ "tslib": "^2.8.1",
"validate-npm-package-name": "3.0.0"
},
"engines": {
- "node": "^12.20 || >= 14.13"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-ruleset-migrator": {
- "version": "1.9.5",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-migrator/-/spectral-ruleset-migrator-1.9.5.tgz",
- "integrity": "sha512-76n/HETr3UinVl/xLNldrH9p0JNoD8Gz4K75J6E4OHp4xD0P+BA2e8+W30HjIvqm1LJdLU2BNma0ioy+q3B9RA==",
+ "version": "1.11.2",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-migrator/-/spectral-ruleset-migrator-1.11.2.tgz",
+ "integrity": "sha512-6r5i4hrDmppspSSxdUKKNHc07NGSSIkvwKNk3M5ukCwvSslImvDEimeWAhPBryhmSJ82YAsKr8erZZpKullxWw==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@stoplight/json": "~3.21.0",
"@stoplight/ordered-object-literal": "~1.0.4",
"@stoplight/path": "1.3.2",
- "@stoplight/spectral-functions": "^1.0.0",
- "@stoplight/spectral-runtime": "^1.1.0",
+ "@stoplight/spectral-functions": "^1.9.1",
+ "@stoplight/spectral-runtime": "^1.1.2",
"@stoplight/types": "^13.6.0",
"@stoplight/yaml": "~4.2.3",
"@types/node": "*",
- "ajv": "^8.6.0",
+ "ajv": "^8.17.1",
"ast-types": "0.14.2",
- "astring": "^1.7.5",
+ "astring": "^1.9.0",
"reserved": "0.1.2",
- "tslib": "^2.3.1",
+ "tslib": "^2.8.1",
"validate-npm-package-name": "3.0.0"
},
"engines": {
- "node": ">=12"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-ruleset-migrator/node_modules/@stoplight/yaml": {
@@ -2233,63 +2660,49 @@
"license": "Apache-2.0"
},
"node_modules/@stoplight/spectral-rulesets": {
- "version": "1.19.1",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.19.1.tgz",
- "integrity": "sha512-rfGK87Y1JJCEeLC8MVdLkjUkRH+Y6VnSF388D+UWihfU9xuq2eNB9phWpTFkG+AG4HLRyGx963BmO6PyM9dBag==",
+ "version": "1.21.4",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.21.4.tgz",
+ "integrity": "sha512-F03Uf+Rb9FnxfjNeIeB0B/dGDJ+NozRkQZtZ/jryoOu+7Qp7rI1e/BkFWEM3y4Fr0zcNEkpS7bjkXnW4frHPcA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@asyncapi/specs": "^4.1.0",
+ "@asyncapi/specs": "^6.8.0",
"@stoplight/better-ajv-errors": "1.0.3",
"@stoplight/json": "^3.17.0",
- "@stoplight/spectral-core": "^1.8.1",
- "@stoplight/spectral-formats": "^1.5.0",
- "@stoplight/spectral-functions": "^1.5.1",
- "@stoplight/spectral-runtime": "^1.1.1",
+ "@stoplight/spectral-core": "^1.19.4",
+ "@stoplight/spectral-formats": "^1.8.1",
+ "@stoplight/spectral-functions": "^1.9.1",
+ "@stoplight/spectral-runtime": "^1.1.2",
"@stoplight/types": "^13.6.0",
"@types/json-schema": "^7.0.7",
- "ajv": "^8.12.0",
- "ajv-formats": "~2.1.0",
+ "ajv": "^8.17.1",
+ "ajv-formats": "~2.1.1",
"json-schema-traverse": "^1.0.0",
"leven": "3.1.0",
"lodash": "~4.17.21",
- "tslib": "^2.3.0"
+ "tslib": "^2.8.1"
},
"engines": {
- "node": ">=12"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/spectral-runtime": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-runtime/-/spectral-runtime-1.1.2.tgz",
- "integrity": "sha512-fr5zRceXI+hrl82yAVoME+4GvJie8v3wmOe9tU+ZLRRNonizthy8qDi0Z/z4olE+vGreSDcuDOZ7JjRxFW5kTw==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-runtime/-/spectral-runtime-1.1.4.tgz",
+ "integrity": "sha512-YHbhX3dqW0do6DhiPSgSGQzr6yQLlWybhKwWx0cqxjMwxej3TqLv3BXMfIUYFKKUqIwH4Q2mV8rrMM8qD2N0rQ==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@stoplight/json": "^3.17.0",
+ "@stoplight/json": "^3.20.1",
"@stoplight/path": "^1.3.2",
- "@stoplight/types": "^12.3.0",
+ "@stoplight/types": "^13.6.0",
"abort-controller": "^3.0.0",
"lodash": "^4.17.21",
- "node-fetch": "^2.6.7",
- "tslib": "^2.3.1"
+ "node-fetch": "^2.7.0",
+ "tslib": "^2.8.1"
},
"engines": {
- "node": ">=12"
- }
- },
- "node_modules/@stoplight/spectral-runtime/node_modules/@stoplight/types": {
- "version": "12.5.0",
- "resolved": "https://registry.npmjs.org/@stoplight/types/-/types-12.5.0.tgz",
- "integrity": "sha512-dwqYcDrGmEyUv5TWrDam5TGOxU72ufyQ7hnOIIDdmW5ezOwZaBFoR5XQ9AsH49w7wgvOqB2Bmo799pJPWnpCbg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "@types/json-schema": "^7.0.4",
- "utility-types": "^3.10.0"
- },
- "engines": {
- "node": ">=8"
+ "node": "^16.20 || ^18.18 || >= 20.17"
}
},
"node_modules/@stoplight/types": {
@@ -2344,46 +2757,43 @@
}
},
"node_modules/@stylistic/eslint-plugin-js": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.8.1.tgz",
- "integrity": "sha512-c5c2C8Mos5tTQd+NWpqwEu7VT6SSRooAguFPMj1cp2RkTYl1ynKoXo8MWy3k4rkbzoeYHrqC2UlUzsroAN7wtQ==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-4.2.0.tgz",
+ "integrity": "sha512-MiJr6wvyzMYl/wElmj8Jns8zH7Q1w8XoVtm+WM6yDaTrfxryMyb8n0CMxt82fo42RoLIfxAEtM6tmQVxqhk0/A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/eslint": "^8.56.10",
- "acorn": "^8.11.3",
- "escape-string-regexp": "^4.0.0",
- "eslint-visitor-keys": "^3.4.3",
- "espree": "^9.6.1"
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"peerDependencies": {
- "eslint": ">=8.40.0"
+ "eslint": ">=9.0.0"
}
},
"node_modules/@stylistic/stylelint-plugin": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-2.1.2.tgz",
- "integrity": "sha512-JsSqu0Y3vsX+PBl+DwULxC0cIv9C1yIcq1MXkx7pBOGtTqU26a75I8MPYMiEYvrsXgsKLi65xVgy1iLVSZquJA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@stylistic/stylelint-plugin/-/stylelint-plugin-3.1.2.tgz",
+ "integrity": "sha512-tylFJGMQo62alGazK74MNxFjMagYOHmBZiePZFOJK2n13JZta0uVkB3Bh5qodUmOLtRH+uxH297EibK14UKm8g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@csstools/css-parser-algorithms": "^2.6.1",
- "@csstools/css-tokenizer": "^2.2.4",
- "@csstools/media-query-list-parser": "^2.1.9",
+ "@csstools/css-parser-algorithms": "^3.0.1",
+ "@csstools/css-tokenizer": "^3.0.1",
+ "@csstools/media-query-list-parser": "^3.0.1",
"is-plain-object": "^5.0.0",
- "postcss-selector-parser": "^6.0.16",
+ "postcss-selector-parser": "^6.1.2",
"postcss-value-parser": "^4.2.0",
"style-search": "^0.1.0",
- "stylelint": "^16.4.0"
+ "stylelint": "^16.8.2"
},
"engines": {
"node": "^18.12 || >=20.9"
},
"peerDependencies": {
- "stylelint": "^16.0.2"
+ "stylelint": "^16.8.0"
}
},
"node_modules/@swc/helpers": {
@@ -2402,6 +2812,17 @@
"node": ">=10.13.0"
}
},
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz",
+ "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
"node_modules/@types/codemirror": {
"version": "5.60.15",
"resolved": "https://registry.npmjs.org/@types/codemirror/-/codemirror-5.60.15.tgz",
@@ -2411,36 +2832,276 @@
"@types/tern": "*"
}
},
+ "node_modules/@types/d3": {
+ "version": "7.4.3",
+ "resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",
+ "integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-array": "*",
+ "@types/d3-axis": "*",
+ "@types/d3-brush": "*",
+ "@types/d3-chord": "*",
+ "@types/d3-color": "*",
+ "@types/d3-contour": "*",
+ "@types/d3-delaunay": "*",
+ "@types/d3-dispatch": "*",
+ "@types/d3-drag": "*",
+ "@types/d3-dsv": "*",
+ "@types/d3-ease": "*",
+ "@types/d3-fetch": "*",
+ "@types/d3-force": "*",
+ "@types/d3-format": "*",
+ "@types/d3-geo": "*",
+ "@types/d3-hierarchy": "*",
+ "@types/d3-interpolate": "*",
+ "@types/d3-path": "*",
+ "@types/d3-polygon": "*",
+ "@types/d3-quadtree": "*",
+ "@types/d3-random": "*",
+ "@types/d3-scale": "*",
+ "@types/d3-scale-chromatic": "*",
+ "@types/d3-selection": "*",
+ "@types/d3-shape": "*",
+ "@types/d3-time": "*",
+ "@types/d3-time-format": "*",
+ "@types/d3-timer": "*",
+ "@types/d3-transition": "*",
+ "@types/d3-zoom": "*"
+ }
+ },
+ "node_modules/@types/d3-array": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz",
+ "integrity": "sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-axis": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz",
+ "integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-selection": "*"
+ }
+ },
+ "node_modules/@types/d3-brush": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz",
+ "integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-selection": "*"
+ }
+ },
+ "node_modules/@types/d3-chord": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz",
+ "integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-color": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
+ "integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-contour": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz",
+ "integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-array": "*",
+ "@types/geojson": "*"
+ }
+ },
+ "node_modules/@types/d3-delaunay": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
+ "integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-dispatch": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz",
+ "integrity": "sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-drag": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz",
+ "integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-selection": "*"
+ }
+ },
+ "node_modules/@types/d3-dsv": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz",
+ "integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-ease": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
+ "integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-fetch": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz",
+ "integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-dsv": "*"
+ }
+ },
+ "node_modules/@types/d3-force": {
+ "version": "3.0.10",
+ "resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz",
+ "integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-format": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz",
+ "integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-geo": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz",
+ "integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/geojson": "*"
+ }
+ },
+ "node_modules/@types/d3-hierarchy": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz",
+ "integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-interpolate": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
+ "integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-color": "*"
+ }
+ },
+ "node_modules/@types/d3-path": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
+ "integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-polygon": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz",
+ "integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-quadtree": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz",
+ "integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-random": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz",
+ "integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==",
+ "license": "MIT"
+ },
"node_modules/@types/d3-scale": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.8.tgz",
- "integrity": "sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==",
+ "version": "4.0.9",
+ "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
+ "integrity": "sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==",
"license": "MIT",
"dependencies": {
"@types/d3-time": "*"
}
},
"node_modules/@types/d3-scale-chromatic": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.3.tgz",
- "integrity": "sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
+ "integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==",
"license": "MIT"
},
- "node_modules/@types/d3-time": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.3.tgz",
- "integrity": "sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==",
+ "node_modules/@types/d3-selection": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz",
+ "integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==",
"license": "MIT"
},
+ "node_modules/@types/d3-shape": {
+ "version": "3.1.7",
+ "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
+ "integrity": "sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-path": "*"
+ }
+ },
+ "node_modules/@types/d3-time": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.4.tgz",
+ "integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-time-format": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz",
+ "integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-timer": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
+ "integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
+ "license": "MIT"
+ },
+ "node_modules/@types/d3-transition": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz",
+ "integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-selection": "*"
+ }
+ },
+ "node_modules/@types/d3-zoom": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz",
+ "integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/d3-interpolate": "*",
+ "@types/d3-selection": "*"
+ }
+ },
"node_modules/@types/debug": {
"version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
"integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"@types/ms": "*"
}
},
+ "node_modules/@types/doctrine": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz",
+ "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/es-aggregate-error": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.6.tgz",
@@ -2452,9 +3113,9 @@
}
},
"node_modules/@types/eslint": {
- "version": "8.56.10",
- "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz",
- "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==",
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz",
+ "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
"license": "MIT",
"dependencies": {
"@types/estree": "*",
@@ -2477,16 +3138,35 @@
"integrity": "sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==",
"license": "MIT"
},
+ "node_modules/@types/geojson": {
+ "version": "7946.0.16",
+ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
+ "integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
+ "license": "MIT"
+ },
+ "node_modules/@types/hammerjs": {
+ "version": "2.0.46",
+ "resolved": "https://registry.npmjs.org/@types/hammerjs/-/hammerjs-2.0.46.tgz",
+ "integrity": "sha512-ynRvcq6wvqexJ9brDMS4BnBLzmr0e14d6ZJTEShTBWKymQiHwlAyGu0ZPEFI2Fh1U53F7tN9ufClWM5KvqkKOw==",
+ "license": "MIT"
+ },
"node_modules/@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"license": "MIT"
},
- "node_modules/@types/json5": {
- "version": "0.0.29",
- "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
- "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
+ "node_modules/@types/katex": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz",
+ "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/markdown-escape": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@types/markdown-escape/-/markdown-escape-1.1.3.tgz",
+ "integrity": "sha512-JIc1+s3y5ujKnt/+N+wq6s/QdL2qZ11fP79MijrVXsAAnzSxCbT2j/3prHRouJdZ2yFLN3vkP0HytfnoCczjOw==",
"dev": true,
"license": "MIT"
},
@@ -2496,28 +3176,20 @@
"integrity": "sha512-a79Yc3TOk6dGdituy8hmTTJXjOkZ7zsFYV10L337ttq/rec8lRMDBpV7fL3uLx6TgbFCa5DU/h8FmIBQPSbU0w==",
"license": "MIT"
},
- "node_modules/@types/mdast": {
- "version": "3.0.15",
- "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz",
- "integrity": "sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==",
- "license": "MIT",
- "dependencies": {
- "@types/unist": "^2"
- }
- },
"node_modules/@types/ms": {
- "version": "0.7.34",
- "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz",
- "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
+ "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
- "version": "20.14.9",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.9.tgz",
- "integrity": "sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==",
+ "version": "22.13.11",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.11.tgz",
+ "integrity": "sha512-iEUCUJoU0i3VnrCmgoWCXttklWcvoCIx4jzcP22fioIVSdTmjgoEvmAO/QPw6TcS9k5FrNgn4w7q5lGOd1CT5g==",
"license": "MIT",
"dependencies": {
- "undici-types": "~5.26.4"
+ "undici-types": "~6.20.0"
}
},
"node_modules/@types/normalize-package-data": {
@@ -2543,10 +3215,18 @@
"@types/estree": "*"
}
},
+ "node_modules/@types/trusted-types": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz",
+ "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==",
+ "license": "MIT",
+ "optional": true
+ },
"node_modules/@types/unist": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz",
- "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==",
+ "version": "2.0.11",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz",
+ "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==",
+ "dev": true,
"license": "MIT"
},
"node_modules/@types/urijs": {
@@ -2557,80 +3237,72 @@
"license": "MIT"
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.14.1.tgz",
- "integrity": "sha512-aAJd6bIf2vvQRjUG3ZkNXkmBpN+J7Wd0mfQiiVCJMu9Z5GcZZdcc0j8XwN/BM97Fl7e3SkTXODSk4VehUv7CGw==",
+ "version": "8.26.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.26.1.tgz",
+ "integrity": "sha512-2X3mwqsj9Bd3Ciz508ZUtoQQYpOhU/kWoUqIf49H8Z0+Vbh6UF/y0OEYp0Q0axOGzaBGs7QxRwq0knSQ8khQNA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/regexpp": "^4.10.0",
- "@typescript-eslint/scope-manager": "7.14.1",
- "@typescript-eslint/type-utils": "7.14.1",
- "@typescript-eslint/utils": "7.14.1",
- "@typescript-eslint/visitor-keys": "7.14.1",
+ "@typescript-eslint/scope-manager": "8.26.1",
+ "@typescript-eslint/type-utils": "8.26.1",
+ "@typescript-eslint/utils": "8.26.1",
+ "@typescript-eslint/visitor-keys": "8.26.1",
"graphemer": "^1.4.0",
"ignore": "^5.3.1",
"natural-compare": "^1.4.0",
- "ts-api-utils": "^1.3.0"
+ "ts-api-utils": "^2.0.1"
},
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^7.0.0",
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.14.1.tgz",
- "integrity": "sha512-8lKUOebNLcR0D7RvlcloOacTOWzOqemWEWkKSVpMZVF/XVcwjPR+3MD08QzbW9TCGJ+DwIc6zUSGZ9vd8cO1IA==",
+ "version": "8.26.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.26.1.tgz",
+ "integrity": "sha512-w6HZUV4NWxqd8BdeFf81t07d7/YV9s7TCWrQQbG5uhuvGUAW+fq1usZ1Hmz9UPNLniFnD8GLSsDpjP0hm1S4lQ==",
"dev": true,
- "license": "BSD-2-Clause",
+ "license": "MIT",
"dependencies": {
- "@typescript-eslint/scope-manager": "7.14.1",
- "@typescript-eslint/types": "7.14.1",
- "@typescript-eslint/typescript-estree": "7.14.1",
- "@typescript-eslint/visitor-keys": "7.14.1",
+ "@typescript-eslint/scope-manager": "8.26.1",
+ "@typescript-eslint/types": "8.26.1",
+ "@typescript-eslint/typescript-estree": "8.26.1",
+ "@typescript-eslint/visitor-keys": "8.26.1",
"debug": "^4.3.4"
},
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.14.1.tgz",
- "integrity": "sha512-gPrFSsoYcsffYXTOZ+hT7fyJr95rdVe4kGVX1ps/dJ+DfmlnjFN/GcMxXcVkeHDKqsq6uAcVaQaIi3cFffmAbA==",
+ "version": "8.26.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.26.1.tgz",
+ "integrity": "sha512-6EIvbE5cNER8sqBu6V7+KeMZIC1664d2Yjt+B9EWUXrsyWpxx4lEZrmvxgSKRC6gX+efDL/UY9OpPZ267io3mg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "7.14.1",
- "@typescript-eslint/visitor-keys": "7.14.1"
+ "@typescript-eslint/types": "8.26.1",
+ "@typescript-eslint/visitor-keys": "8.26.1"
},
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
@@ -2638,41 +3310,37 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.14.1.tgz",
- "integrity": "sha512-/MzmgNd3nnbDbOi3LfasXWWe292+iuo+umJ0bCCMCPc1jLO/z2BQmWUUUXvXLbrQey/JgzdF/OV+I5bzEGwJkQ==",
+ "version": "8.26.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.26.1.tgz",
+ "integrity": "sha512-Kcj/TagJLwoY/5w9JGEFV0dclQdyqw9+VMndxOJKtoFSjfZhLXhYjzsQEeyza03rwHx2vFEGvrJWJBXKleRvZg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/typescript-estree": "7.14.1",
- "@typescript-eslint/utils": "7.14.1",
+ "@typescript-eslint/typescript-estree": "8.26.1",
+ "@typescript-eslint/utils": "8.26.1",
"debug": "^4.3.4",
- "ts-api-utils": "^1.3.0"
+ "ts-api-utils": "^2.0.1"
},
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.56.0"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/@typescript-eslint/types": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.14.1.tgz",
- "integrity": "sha512-mL7zNEOQybo5R3AavY+Am7KLv8BorIv7HCYS5rKoNZKQD9tsfGUpO4KdAn3sSUvTiS4PQkr2+K0KJbxj8H9NDg==",
+ "version": "8.26.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.26.1.tgz",
+ "integrity": "sha512-n4THUQW27VmQMx+3P+B0Yptl7ydfceUj4ON/AQILAASwgYdZ/2dhfymRMh5egRUrvK5lSmaOm77Ry+lmXPOgBQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
@@ -2680,255 +3348,376 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.14.1.tgz",
- "integrity": "sha512-k5d0VuxViE2ulIO6FbxxSZaxqDVUyMbXcidC8rHvii0I56XZPv8cq+EhMns+d/EVIL41sMXqRbK3D10Oza1bbA==",
- "dev": true,
- "license": "BSD-2-Clause",
- "dependencies": {
- "@typescript-eslint/types": "7.14.1",
- "@typescript-eslint/visitor-keys": "7.14.1",
- "debug": "^4.3.4",
- "globby": "^11.1.0",
- "is-glob": "^4.0.3",
- "minimatch": "^9.0.4",
- "semver": "^7.6.0",
- "ts-api-utils": "^1.3.0"
- },
- "engines": {
- "node": "^18.18.0 || >=20.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/typescript-eslint"
- },
- "peerDependenciesMeta": {
- "typescript": {
- "optional": true
- }
- }
- },
- "node_modules/@typescript-eslint/utils": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.14.1.tgz",
- "integrity": "sha512-CMmVVELns3nak3cpJhZosDkm63n+DwBlDX8g0k4QUa9BMnF+lH2lr3d130M1Zt1xxmB3LLk3NV7KQCq86ZBBhQ==",
+ "version": "8.26.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.26.1.tgz",
+ "integrity": "sha512-yUwPpUHDgdrv1QJ7YQal3cMVBGWfnuCdKbXw1yyjArax3353rEJP1ZA+4F8nOlQ3RfS2hUN/wze3nlY+ZOhvoA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@eslint-community/eslint-utils": "^4.4.0",
- "@typescript-eslint/scope-manager": "7.14.1",
- "@typescript-eslint/types": "7.14.1",
- "@typescript-eslint/typescript-estree": "7.14.1"
+ "@typescript-eslint/types": "8.26.1",
+ "@typescript-eslint/visitor-keys": "8.26.1",
+ "debug": "^4.3.4",
+ "fast-glob": "^3.3.2",
+ "is-glob": "^4.0.3",
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^2.0.1"
},
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^8.56.0"
+ "typescript": ">=4.8.4 <5.9.0"
}
},
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.14.1.tgz",
- "integrity": "sha512-Crb+F75U1JAEtBeQGxSKwI60hZmmzaqA3z9sYsVm8X7W5cwLEm5bRe0/uXS6+MR/y8CVpKSR/ontIAIEPFcEkA==",
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.26.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.26.1.tgz",
+ "integrity": "sha512-V4Urxa/XtSUroUrnI7q6yUTD3hDtfJ2jzVfeT3VK0ciizfK2q/zGC0iDh1lFMUZR8cImRrep6/q0xd/1ZGPQpg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@typescript-eslint/types": "7.14.1",
- "eslint-visitor-keys": "^3.4.3"
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@typescript-eslint/scope-manager": "8.26.1",
+ "@typescript-eslint/types": "8.26.1",
+ "@typescript-eslint/typescript-estree": "8.26.1"
},
"engines": {
- "node": "^18.18.0 || >=20.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.26.1",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.26.1.tgz",
+ "integrity": "sha512-AjOC3zfnxd6S4Eiy3jwktJPclqhFHNyd8L6Gycf9WUPoKZpgM5PjkxY1X7uSy61xVpiJDhhk7XT2NVsN3ALTWg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.26.1",
+ "eslint-visitor-keys": "^4.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
- "node_modules/@ungap/structured-clone": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
- "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
+ "node_modules/@unrs/rspack-resolver-binding-darwin-arm64": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-darwin-arm64/-/rspack-resolver-binding-darwin-arm64-1.2.2.tgz",
+ "integrity": "sha512-i7z0B+C0P8Q63O/5PXJAzeFtA1ttY3OR2VSJgGv18S+PFNwD98xHgAgPOT1H5HIV6jlQP8Avzbp09qxJUdpPNw==",
+ "cpu": [
+ "arm64"
+ ],
"dev": true,
- "license": "ISC"
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/rspack-resolver-binding-darwin-x64": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-darwin-x64/-/rspack-resolver-binding-darwin-x64-1.2.2.tgz",
+ "integrity": "sha512-YEdFzPjIbDUCfmehC6eS+AdJYtFWY35YYgWUnqqTM2oe/N58GhNy5yRllxYhxwJ9GcfHoNc6Ubze1yjkNv+9Qg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@unrs/rspack-resolver-binding-freebsd-x64": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-freebsd-x64/-/rspack-resolver-binding-freebsd-x64-1.2.2.tgz",
+ "integrity": "sha512-TU4ntNXDgPN2giQyyzSnGWf/dVCem5lvwxg0XYvsvz35h5H19WrhTmHgbrULMuypCB3aHe1enYUC9rPLDw45mA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@unrs/rspack-resolver-binding-linux-arm-gnueabihf": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-arm-gnueabihf/-/rspack-resolver-binding-linux-arm-gnueabihf-1.2.2.tgz",
+ "integrity": "sha512-ik3w4/rU6RujBvNWiDnKdXi1smBhqxEDhccNi/j2rHaMjm0Fk49KkJ6XKsoUnD2kZ5xaMJf9JjailW/okfUPIw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/rspack-resolver-binding-linux-arm64-gnu": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-arm64-gnu/-/rspack-resolver-binding-linux-arm64-gnu-1.2.2.tgz",
+ "integrity": "sha512-fp4Azi8kHz6TX8SFmKfyScZrMLfp++uRm2srpqRjsRZIIBzH74NtSkdEUHImR4G7f7XJ+sVZjCc6KDDK04YEpQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/rspack-resolver-binding-linux-arm64-musl": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-arm64-musl/-/rspack-resolver-binding-linux-arm64-musl-1.2.2.tgz",
+ "integrity": "sha512-gMiG3DCFioJxdGBzhlL86KcFgt9HGz0iDhw0YVYPsShItpN5pqIkNrI+L/Q/0gfDiGrfcE0X3VANSYIPmqEAlQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/rspack-resolver-binding-linux-x64-gnu": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-x64-gnu/-/rspack-resolver-binding-linux-x64-gnu-1.2.2.tgz",
+ "integrity": "sha512-n/4n2CxaUF9tcaJxEaZm+lqvaw2gflfWQ1R9I7WQgYkKEKbRKbpG/R3hopYdUmLSRI4xaW1Cy0Bz40eS2Yi4Sw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/rspack-resolver-binding-linux-x64-musl": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-linux-x64-musl/-/rspack-resolver-binding-linux-x64-musl-1.2.2.tgz",
+ "integrity": "sha512-cHyhAr6rlYYbon1L2Ag449YCj3p6XMfcYTP0AQX+KkQo025d1y/VFtPWvjMhuEsE2lLvtHm7GdJozj6BOMtzVg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@unrs/rspack-resolver-binding-wasm32-wasi": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-wasm32-wasi/-/rspack-resolver-binding-wasm32-wasi-1.2.2.tgz",
+ "integrity": "sha512-eogDKuICghDLGc32FtP+WniG38IB1RcGOGz0G3z8406dUdjJvxfHGuGs/dSlM9YEp/v0lEqhJ4mBu6X2nL9pog==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@napi-rs/wasm-runtime": "^0.2.7"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@unrs/rspack-resolver-binding-win32-arm64-msvc": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-win32-arm64-msvc/-/rspack-resolver-binding-win32-arm64-msvc-1.2.2.tgz",
+ "integrity": "sha512-7sWRJumhpXSi2lccX8aQpfFXHsSVASdWndLv8AmD8nDRA/5PBi8IplQVZNx2mYRx6+Bp91Z00kuVqpXO9NfCTg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@unrs/rspack-resolver-binding-win32-x64-msvc": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/@unrs/rspack-resolver-binding-win32-x64-msvc/-/rspack-resolver-binding-win32-x64-msvc-1.2.2.tgz",
+ "integrity": "sha512-hewo/UMGP1a7O6FG/ThcPzSJdm/WwrYDNkdGgWl6M18H6K6MSitklomWpT9MUtT5KGj++QJb06va/14QBC4pvw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
},
"node_modules/@vitejs/plugin-vue": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz",
- "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==",
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.3.tgz",
+ "integrity": "sha512-IYSLEQj4LgZZuoVpdSUCw3dIynTWQgPlaRP6iAvMle4My0HdYwr5g5wQAfwOeHQBmYwEkqF70nRpSilr6PoUDg==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.0.0 || >=20.0.0"
},
"peerDependencies": {
- "vite": "^5.0.0",
+ "vite": "^5.0.0 || ^6.0.0",
"vue": "^3.2.25"
}
},
"node_modules/@vitest/coverage-v8": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.6.0.tgz",
- "integrity": "sha512-KvapcbMY/8GYIG0rlwwOKCVNRc0OL20rrhFkg/CHNzncV03TE2XWvO5w9uZYoxNiMEBacAJt3unSOiZ7svePew==",
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.8.tgz",
+ "integrity": "sha512-y7SAKsQirsEJ2F8bulBck4DoluhI2EEgTimHd6EEUgJBGKy9tC25cpywh1MH4FvDGoG2Unt7+asVd1kj4qOSAw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@ampproject/remapping": "^2.2.1",
- "@bcoe/v8-coverage": "^0.2.3",
- "debug": "^4.3.4",
+ "@ampproject/remapping": "^2.3.0",
+ "@bcoe/v8-coverage": "^1.0.2",
+ "debug": "^4.4.0",
"istanbul-lib-coverage": "^3.2.2",
"istanbul-lib-report": "^3.0.1",
- "istanbul-lib-source-maps": "^5.0.4",
- "istanbul-reports": "^3.1.6",
- "magic-string": "^0.30.5",
- "magicast": "^0.3.3",
- "picocolors": "^1.0.0",
- "std-env": "^3.5.0",
- "strip-literal": "^2.0.0",
- "test-exclude": "^6.0.0"
+ "istanbul-lib-source-maps": "^5.0.6",
+ "istanbul-reports": "^3.1.7",
+ "magic-string": "^0.30.17",
+ "magicast": "^0.3.5",
+ "std-env": "^3.8.0",
+ "test-exclude": "^7.0.1",
+ "tinyrainbow": "^2.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
- "vitest": "1.6.0"
+ "@vitest/browser": "3.0.8",
+ "vitest": "3.0.8"
+ },
+ "peerDependenciesMeta": {
+ "@vitest/browser": {
+ "optional": true
+ }
}
},
"node_modules/@vitest/coverage-v8/node_modules/magic-string": {
- "version": "0.30.10",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
- "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.15"
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/@vitest/eslint-plugin": {
+ "version": "1.1.25",
+ "resolved": "https://registry.npmjs.org/@vitest/eslint-plugin/-/eslint-plugin-1.1.25.tgz",
+ "integrity": "sha512-u8DpDnMbPcqBmJOB4PeEtn6q7vKmLVTLFMpzoxSAo0hjYdl4iYSHRleqwPQo0ywc7UV0S6RKIahYRQ3BnZdMVw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@typescript-eslint/utils": ">= 8.0",
+ "eslint": ">= 8.57.0",
+ "typescript": ">= 5.0.0",
+ "vitest": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ },
+ "vitest": {
+ "optional": true
+ }
}
},
"node_modules/@vitest/expect": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.6.0.tgz",
- "integrity": "sha512-ixEvFVQjycy/oNgHjqsL6AZCDduC+tflRluaHIzKIsdbzkLn2U/iBnVeJwB6HsIjQBdfMR8Z0tRxKUsvFJEeWQ==",
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.0.8.tgz",
+ "integrity": "sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/spy": "1.6.0",
- "@vitest/utils": "1.6.0",
- "chai": "^4.3.10"
+ "@vitest/spy": "3.0.8",
+ "@vitest/utils": "3.0.8",
+ "chai": "^5.2.0",
+ "tinyrainbow": "^2.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
- "node_modules/@vitest/runner": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-1.6.0.tgz",
- "integrity": "sha512-P4xgwPjwesuBiHisAVz/LSSZtDjOTPYZVmNAnpHHSR6ONrf8eCJOFRvUwdHn30F5M1fxhqtl7QZQUk2dprIXAg==",
+ "node_modules/@vitest/mocker": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.0.8.tgz",
+ "integrity": "sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/utils": "1.6.0",
- "p-limit": "^5.0.0",
- "pathe": "^1.1.1"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/runner/node_modules/p-limit": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-5.0.0.tgz",
- "integrity": "sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "yocto-queue": "^1.0.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@vitest/runner/node_modules/yocto-queue": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz",
- "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12.20"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/@vitest/snapshot": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-1.6.0.tgz",
- "integrity": "sha512-+Hx43f8Chus+DCmygqqfetcAZrDJwvTj0ymqjQq4CvmpKFSTVteEOBzCusu1x2tt4OJcvBflyHUE0DZSLgEMtQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "magic-string": "^0.30.5",
- "pathe": "^1.1.1",
- "pretty-format": "^29.7.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/snapshot/node_modules/magic-string": {
- "version": "0.30.10",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
- "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.15"
- }
- },
- "node_modules/@vitest/spy": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-1.6.0.tgz",
- "integrity": "sha512-leUTap6B/cqi/bQkXUu6bQV5TZPx7pmMBKBQiI0rJA8c3pB56ZsaTbREnF7CJfmvAS4V2cXIBAh/3rVwrrCYgw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "tinyspy": "^2.2.0"
- },
- "funding": {
- "url": "https://opencollective.com/vitest"
- }
- },
- "node_modules/@vitest/utils": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-1.6.0.tgz",
- "integrity": "sha512-21cPiuGMoMZwiOHa2i4LXkMkMkCGzA+MVFV70jRwHo95dL4x/ts5GZhML1QWuy7yfp3WzK3lRvZi3JnXTYqrBw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "diff-sequences": "^29.6.3",
+ "@vitest/spy": "3.0.8",
"estree-walker": "^3.0.3",
- "loupe": "^2.3.7",
- "pretty-format": "^29.7.0"
+ "magic-string": "^0.30.17"
},
"funding": {
"url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^5.0.0 || ^6.0.0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
}
},
- "node_modules/@vitest/utils/node_modules/@types/estree": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
- "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "node_modules/@vitest/mocker/node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"dev": true,
"license": "MIT"
},
- "node_modules/@vitest/utils/node_modules/estree-walker": {
+ "node_modules/@vitest/mocker/node_modules/estree-walker": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
@@ -2938,113 +3727,203 @@
"@types/estree": "^1.0.0"
}
},
- "node_modules/@vue/compiler-core": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.31.tgz",
- "integrity": "sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==",
+ "node_modules/@vitest/mocker/node_modules/magic-string": {
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.24.7",
- "@vue/shared": "3.4.31",
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.0.8.tgz",
+ "integrity": "sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.0.8.tgz",
+ "integrity": "sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "3.0.8",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.0.8.tgz",
+ "integrity": "sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.0.8",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot/node_modules/magic-string": {
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.0.8.tgz",
+ "integrity": "sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^3.0.2"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.0.8.tgz",
+ "integrity": "sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.0.8",
+ "loupe": "^3.1.3",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vue/compiler-core": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.13.tgz",
+ "integrity": "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.25.3",
+ "@vue/shared": "3.5.13",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-dom": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.31.tgz",
- "integrity": "sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.13.tgz",
+ "integrity": "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==",
"license": "MIT",
"dependencies": {
- "@vue/compiler-core": "3.4.31",
- "@vue/shared": "3.4.31"
+ "@vue/compiler-core": "3.5.13",
+ "@vue/shared": "3.5.13"
}
},
"node_modules/@vue/compiler-sfc": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.31.tgz",
- "integrity": "sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.13.tgz",
+ "integrity": "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==",
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.24.7",
- "@vue/compiler-core": "3.4.31",
- "@vue/compiler-dom": "3.4.31",
- "@vue/compiler-ssr": "3.4.31",
- "@vue/shared": "3.4.31",
+ "@babel/parser": "^7.25.3",
+ "@vue/compiler-core": "3.5.13",
+ "@vue/compiler-dom": "3.5.13",
+ "@vue/compiler-ssr": "3.5.13",
+ "@vue/shared": "3.5.13",
"estree-walker": "^2.0.2",
- "magic-string": "^0.30.10",
- "postcss": "^8.4.38",
+ "magic-string": "^0.30.11",
+ "postcss": "^8.4.48",
"source-map-js": "^1.2.0"
}
},
"node_modules/@vue/compiler-sfc/node_modules/magic-string": {
- "version": "0.30.10",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
- "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
"license": "MIT",
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.15"
+ "@jridgewell/sourcemap-codec": "^1.5.0"
}
},
"node_modules/@vue/compiler-ssr": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.31.tgz",
- "integrity": "sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.13.tgz",
+ "integrity": "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==",
"license": "MIT",
"dependencies": {
- "@vue/compiler-dom": "3.4.31",
- "@vue/shared": "3.4.31"
+ "@vue/compiler-dom": "3.5.13",
+ "@vue/shared": "3.5.13"
}
},
"node_modules/@vue/reactivity": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.31.tgz",
- "integrity": "sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.13.tgz",
+ "integrity": "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==",
"license": "MIT",
"dependencies": {
- "@vue/shared": "3.4.31"
+ "@vue/shared": "3.5.13"
}
},
"node_modules/@vue/runtime-core": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.31.tgz",
- "integrity": "sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.13.tgz",
+ "integrity": "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==",
"license": "MIT",
"dependencies": {
- "@vue/reactivity": "3.4.31",
- "@vue/shared": "3.4.31"
+ "@vue/reactivity": "3.5.13",
+ "@vue/shared": "3.5.13"
}
},
"node_modules/@vue/runtime-dom": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.31.tgz",
- "integrity": "sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.13.tgz",
+ "integrity": "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==",
"license": "MIT",
"dependencies": {
- "@vue/reactivity": "3.4.31",
- "@vue/runtime-core": "3.4.31",
- "@vue/shared": "3.4.31",
+ "@vue/reactivity": "3.5.13",
+ "@vue/runtime-core": "3.5.13",
+ "@vue/shared": "3.5.13",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.31.tgz",
- "integrity": "sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.13.tgz",
+ "integrity": "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==",
"license": "MIT",
"dependencies": {
- "@vue/compiler-ssr": "3.4.31",
- "@vue/shared": "3.4.31"
+ "@vue/compiler-ssr": "3.5.13",
+ "@vue/shared": "3.5.13"
},
"peerDependencies": {
- "vue": "3.4.31"
+ "vue": "3.5.13"
}
},
"node_modules/@vue/shared": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.31.tgz",
- "integrity": "sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==",
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.13.tgz",
+ "integrity": "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==",
"license": "MIT"
},
"node_modules/@vue/test-utils": {
@@ -3059,188 +3938,188 @@
}
},
"node_modules/@webassemblyjs/ast": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz",
- "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
+ "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
"license": "MIT",
"dependencies": {
- "@webassemblyjs/helper-numbers": "1.11.6",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6"
+ "@webassemblyjs/helper-numbers": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2"
}
},
"node_modules/@webassemblyjs/floating-point-hex-parser": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz",
- "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
+ "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-api-error": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz",
- "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
+ "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-buffer": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz",
- "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
+ "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-numbers": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz",
- "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
+ "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
"license": "MIT",
"dependencies": {
- "@webassemblyjs/floating-point-hex-parser": "1.11.6",
- "@webassemblyjs/helper-api-error": "1.11.6",
+ "@webassemblyjs/floating-point-hex-parser": "1.13.2",
+ "@webassemblyjs/helper-api-error": "1.13.2",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/helper-wasm-bytecode": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz",
- "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
+ "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
"license": "MIT"
},
"node_modules/@webassemblyjs/helper-wasm-section": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz",
- "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
+ "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
"license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-buffer": "1.12.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/wasm-gen": "1.12.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/wasm-gen": "1.14.1"
}
},
"node_modules/@webassemblyjs/ieee754": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz",
- "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
+ "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
"license": "MIT",
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
},
"node_modules/@webassemblyjs/leb128": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz",
- "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
+ "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
"license": "Apache-2.0",
"dependencies": {
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webassemblyjs/utf8": {
- "version": "1.11.6",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz",
- "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
+ "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
"license": "MIT"
},
"node_modules/@webassemblyjs/wasm-edit": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz",
- "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
+ "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
"license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-buffer": "1.12.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/helper-wasm-section": "1.12.1",
- "@webassemblyjs/wasm-gen": "1.12.1",
- "@webassemblyjs/wasm-opt": "1.12.1",
- "@webassemblyjs/wasm-parser": "1.12.1",
- "@webassemblyjs/wast-printer": "1.12.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/helper-wasm-section": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-opt": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1",
+ "@webassemblyjs/wast-printer": "1.14.1"
}
},
"node_modules/@webassemblyjs/wasm-gen": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz",
- "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
+ "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
"license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/ieee754": "1.11.6",
- "@webassemblyjs/leb128": "1.11.6",
- "@webassemblyjs/utf8": "1.11.6"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"node_modules/@webassemblyjs/wasm-opt": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz",
- "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
+ "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
"license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-buffer": "1.12.1",
- "@webassemblyjs/wasm-gen": "1.12.1",
- "@webassemblyjs/wasm-parser": "1.12.1"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-buffer": "1.14.1",
+ "@webassemblyjs/wasm-gen": "1.14.1",
+ "@webassemblyjs/wasm-parser": "1.14.1"
}
},
"node_modules/@webassemblyjs/wasm-parser": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz",
- "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
+ "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
"license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
- "@webassemblyjs/helper-api-error": "1.11.6",
- "@webassemblyjs/helper-wasm-bytecode": "1.11.6",
- "@webassemblyjs/ieee754": "1.11.6",
- "@webassemblyjs/leb128": "1.11.6",
- "@webassemblyjs/utf8": "1.11.6"
+ "@webassemblyjs/ast": "1.14.1",
+ "@webassemblyjs/helper-api-error": "1.13.2",
+ "@webassemblyjs/helper-wasm-bytecode": "1.13.2",
+ "@webassemblyjs/ieee754": "1.13.2",
+ "@webassemblyjs/leb128": "1.13.2",
+ "@webassemblyjs/utf8": "1.13.2"
}
},
"node_modules/@webassemblyjs/wast-printer": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz",
- "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
+ "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
"license": "MIT",
"dependencies": {
- "@webassemblyjs/ast": "1.12.1",
+ "@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
}
},
"node_modules/@webpack-cli/configtest": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz",
- "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-3.0.1.tgz",
+ "integrity": "sha512-u8d0pJ5YFgneF/GuvEiDA61Tf1VDomHHYMjv/wc9XzYj7nopltpG96nXN5dJRstxZhcNpV1g+nT6CydO7pHbjA==",
"license": "MIT",
"engines": {
- "node": ">=14.15.0"
+ "node": ">=18.12.0"
},
"peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
+ "webpack": "^5.82.0",
+ "webpack-cli": "6.x.x"
}
},
"node_modules/@webpack-cli/info": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz",
- "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-3.0.1.tgz",
+ "integrity": "sha512-coEmDzc2u/ffMvuW9aCjoRzNSPDl/XLuhPdlFRpT9tZHmJ/039az33CE7uH+8s0uL1j5ZNtfdv0HkfaKRBGJsQ==",
"license": "MIT",
"engines": {
- "node": ">=14.15.0"
+ "node": ">=18.12.0"
},
"peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
+ "webpack": "^5.82.0",
+ "webpack-cli": "6.x.x"
}
},
"node_modules/@webpack-cli/serve": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz",
- "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-3.0.1.tgz",
+ "integrity": "sha512-sbgw03xQaCLiT6gcY/6u3qBDn01CWw/nbaXl3gTdTFuJJ75Gffv3E3DBpgvY2fkkrdS1fpjaXNOmJlnbtKauKg==",
"license": "MIT",
"engines": {
- "node": ">=14.15.0"
+ "node": ">=18.12.0"
},
"peerDependencies": {
- "webpack": "5.x.x",
- "webpack-cli": "5.x.x"
+ "webpack": "^5.82.0",
+ "webpack-cli": "6.x.x"
},
"peerDependenciesMeta": {
"webpack-dev-server": {
@@ -3284,9 +4163,9 @@
}
},
"node_modules/acorn": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz",
- "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
+ "version": "8.14.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
+ "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
@@ -3295,15 +4174,6 @@
"node": ">=0.4.0"
}
},
- "node_modules/acorn-import-attributes": {
- "version": "1.9.5",
- "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz",
- "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==",
- "license": "MIT",
- "peerDependencies": {
- "acorn": "^8"
- }
- },
"node_modules/acorn-jsx": {
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
@@ -3314,44 +4184,16 @@
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
}
},
- "node_modules/acorn-walk": {
- "version": "8.3.3",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz",
- "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "acorn": "^8.11.0"
- },
- "engines": {
- "node": ">=0.4.0"
- }
- },
- "node_modules/add-asset-webpack-plugin": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/add-asset-webpack-plugin/-/add-asset-webpack-plugin-2.0.1.tgz",
- "integrity": "sha512-Hx9EKnirCUfdh684y1yhx8QOFolpkIG2VRHHgNm8wFy1Cf7P3RGwS678hoN7Y1XvZRPpVXWa+6QnfL/2i0CMCA==",
- "license": "MIT",
- "engines": {
- "node": ">=10.13.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- },
- "peerDependencies": {
- "webpack": ">=5"
- }
- },
"node_modules/ajv": {
- "version": "8.16.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz",
- "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==",
+ "version": "8.17.1",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
+ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"license": "MIT",
"dependencies": {
"fast-deep-equal": "^3.1.3",
+ "fast-uri": "^3.0.1",
"json-schema-traverse": "^1.0.0",
- "require-from-string": "^2.0.2",
- "uri-js": "^4.4.1"
+ "require-from-string": "^2.0.2"
},
"funding": {
"type": "github",
@@ -3476,25 +4318,15 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"license": "Python-2.0"
},
- "node_modules/aria-query": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
- "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "dequal": "^2.0.3"
- }
- },
"node_modules/array-buffer-byte-length": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz",
- "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz",
+ "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.5",
- "is-array-buffer": "^3.0.4"
+ "call-bound": "^1.0.3",
+ "is-array-buffer": "^3.0.5"
},
"engines": {
"node": ">= 0.4"
@@ -3507,6 +4339,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
"integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -3543,18 +4376,16 @@
"node": ">=8"
}
},
- "node_modules/array.prototype.findlastindex": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz",
- "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==",
+ "node_modules/array.prototype.flat": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz",
+ "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
"define-properties": "^1.2.1",
- "es-abstract": "^1.23.2",
- "es-errors": "^1.3.0",
- "es-object-atoms": "^1.0.0",
+ "es-abstract": "^1.23.5",
"es-shim-unscopables": "^1.0.2"
},
"engines": {
@@ -3564,59 +4395,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/array.prototype.flat": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz",
- "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "es-shim-unscopables": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/array.prototype.flatmap": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz",
- "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "es-shim-unscopables": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/arraybuffer.prototype.slice": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz",
- "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz",
+ "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"array-buffer-byte-length": "^1.0.1",
- "call-bind": "^1.0.5",
+ "call-bind": "^1.0.8",
"define-properties": "^1.2.1",
- "es-abstract": "^1.22.3",
- "es-errors": "^1.2.1",
- "get-intrinsic": "^1.2.3",
- "is-array-buffer": "^3.0.4",
- "is-shared-array-buffer": "^1.0.2"
+ "es-abstract": "^1.23.5",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "is-array-buffer": "^3.0.4"
},
"engines": {
"node": ">= 0.4"
@@ -3636,9 +4428,9 @@
}
},
"node_modules/asciinema-player": {
- "version": "3.8.0",
- "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.8.0.tgz",
- "integrity": "sha512-yFoAcjFK9WJ0D+aagkT0YXOWRbyXoOe/TQHq07oQP6prItXQkWn46fdvUb6zqJu2AywmY8VjBEwZ6ciL8IbezQ==",
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/asciinema-player/-/asciinema-player-3.8.2.tgz",
+ "integrity": "sha512-Lgcnj9u/H6sRpGRX1my7Azcay6llLmB/GVkCGcDbPwdTVTisS1ir8SQ9jRWRvjlLUjpSJkN0euruvy3sLRM8tw==",
"license": "Apache-2.0",
"dependencies": {
"@babel/runtime": "^7.21.0",
@@ -3646,13 +4438,13 @@
}
},
"node_modules/assertion-error": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
- "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": "*"
+ "node": ">=12"
}
},
"node_modules/ast-types": {
@@ -3668,13 +4460,6 @@
"node": ">=4"
}
},
- "node_modules/ast-types-flow": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz",
- "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/astral-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
@@ -3686,15 +4471,25 @@
}
},
"node_modules/astring": {
- "version": "1.8.6",
- "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz",
- "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==",
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz",
+ "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==",
"dev": true,
"license": "MIT",
"bin": {
"astring": "bin/astring"
}
},
+ "node_modules/async-function": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz",
+ "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/atob": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
@@ -3725,25 +4520,15 @@
}
},
"node_modules/axe-core": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.9.1.tgz",
- "integrity": "sha512-QbUdXJVTpvUTHU7871ppZkdOLBeGUKBQWHkHrvN2V9IQWGMt61zf3B45BtzjxEJzYuj0JBjBZP/hmYS/R9pmAw==",
+ "version": "4.10.3",
+ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz",
+ "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==",
"dev": true,
"license": "MPL-2.0",
"engines": {
"node": ">=4"
}
},
- "node_modules/axobject-query": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz",
- "integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "deep-equal": "^2.0.5"
- }
- },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -3820,9 +4605,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.23.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz",
- "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==",
+ "version": "4.24.4",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.4.tgz",
+ "integrity": "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==",
"funding": [
{
"type": "opencollective",
@@ -3839,10 +4624,10 @@
],
"license": "MIT",
"dependencies": {
- "caniuse-lite": "^1.0.30001629",
- "electron-to-chromium": "^1.4.796",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.16"
+ "caniuse-lite": "^1.0.30001688",
+ "electron-to-chromium": "^1.5.73",
+ "node-releases": "^2.0.19",
+ "update-browserslist-db": "^1.1.1"
},
"bin": {
"browserslist": "cli.js"
@@ -3901,6 +4686,16 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -3911,18 +4706,69 @@
"node": ">=8"
}
},
- "node_modules/call-bind": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
- "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
+ "node_modules/cacheable": {
+ "version": "1.8.9",
+ "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-1.8.9.tgz",
+ "integrity": "sha512-FicwAUyWnrtnd4QqYAoRlNs44/a1jTL7XDKqm5gJ90wz1DQPlC7U2Rd1Tydpv+E7WAr4sQHuw8Q8M3nZMAyecQ==",
"dev": true,
"license": "MIT",
"dependencies": {
+ "hookified": "^1.7.1",
+ "keyv": "^5.3.1"
+ }
+ },
+ "node_modules/cacheable/node_modules/keyv": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.3.2.tgz",
+ "integrity": "sha512-Lji2XRxqqa5Wg+CHLVfFKBImfJZ4pCSccu9eVWK6w4c2SDFLd8JAn1zqTuSFnsxb7ope6rMsnIHfp+eBbRBRZQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@keyv/serialize": "^1.0.3"
+ }
+ },
+ "node_modules/call-bind": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz",
+ "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.0",
"es-define-property": "^1.0.0",
- "es-errors": "^1.3.0",
- "function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
- "set-function-length": "^1.2.1"
+ "set-function-length": "^1.2.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
@@ -3950,9 +4796,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001639",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001639.tgz",
- "integrity": "sha512-eFHflNTBIlFwP2AIKaYuBQN/apnUoKNhBdza8ZnW/h2di4LCZ4xFqYlxUxo+LQ76KFI1PGcC1QDxMbxTZpSCAg==",
+ "version": "1.0.30001707",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz",
+ "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==",
"funding": [
{
"type": "opencollective",
@@ -3970,22 +4816,20 @@
"license": "CC-BY-4.0"
},
"node_modules/chai": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz",
- "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz",
+ "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "assertion-error": "^1.1.0",
- "check-error": "^1.0.3",
- "deep-eql": "^4.1.3",
- "get-func-name": "^2.0.2",
- "loupe": "^2.3.6",
- "pathval": "^1.1.1",
- "type-detect": "^4.0.8"
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=12"
}
},
"node_modules/chalk": {
@@ -4008,6 +4852,29 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz",
"integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-entities-legacy": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz",
+ "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/character-reference-invalid": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz",
+ "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==",
+ "dev": true,
"license": "MIT",
"funding": {
"type": "github",
@@ -4015,9 +4882,9 @@
}
},
"node_modules/chart.js": {
- "version": "4.4.2",
- "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.2.tgz",
- "integrity": "sha512-6GD7iKwFpP5kbSD4MeRRRlTnQvxfQREy36uEtm1hzHzcOqwWx0YEHuspuoNlslu+nciLIB7fjjsHkUv/FzFcOg==",
+ "version": "4.4.5",
+ "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.5.tgz",
+ "integrity": "sha512-CVVjg1RYTJV9OCC8WeJPMx8gsV8K6WIyIEQUE3ui4AR9Hfgls9URri6Ja3hyMVBbTF8Q2KFa19PE815gWcWhng==",
"license": "MIT",
"dependencies": {
"@kurkle/color": "^0.3.0"
@@ -4040,11 +4907,12 @@
}
},
"node_modules/chartjs-plugin-zoom": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-2.0.1.tgz",
- "integrity": "sha512-ogOmLu6e+Q7E1XWOCOz9YwybMslz9qNfGV2a+qjfmqJYpsw5ZMoRHZBUyW+NGhkpQ5PwwPA/+rikHpBZb7PZuA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/chartjs-plugin-zoom/-/chartjs-plugin-zoom-2.2.0.tgz",
+ "integrity": "sha512-in6kcdiTlP6npIVLMd4zXZ08PDUXC52gZ4FAy5oyjk1zX3gKarXMAof7B9eFiisf9WOC3bh2saHg+J5WtLXZeA==",
"license": "MIT",
"dependencies": {
+ "@types/hammerjs": "^2.0.45",
"hammerjs": "^2.0.8"
},
"peerDependencies": {
@@ -4052,16 +4920,39 @@
}
},
"node_modules/check-error": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz",
- "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
+ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "get-func-name": "^2.0.2"
- },
"engines": {
- "node": "*"
+ "node": ">= 16"
+ }
+ },
+ "node_modules/chevrotain": {
+ "version": "11.0.3",
+ "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz",
+ "integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@chevrotain/cst-dts-gen": "11.0.3",
+ "@chevrotain/gast": "11.0.3",
+ "@chevrotain/regexp-to-ast": "11.0.3",
+ "@chevrotain/types": "11.0.3",
+ "@chevrotain/utils": "11.0.3",
+ "lodash-es": "4.17.21"
+ }
+ },
+ "node_modules/chevrotain-allstar": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/chevrotain-allstar/-/chevrotain-allstar-0.3.1.tgz",
+ "integrity": "sha512-b7g+y9A0v4mxCW1qUhf3BSVPg+/NvGErk/dOkrDaHA0nQIQGAtrOjlX//9OQtRlSCy+x9rfB5N8yC71lH1nvMw==",
+ "license": "MIT",
+ "dependencies": {
+ "lodash-es": "^4.17.21"
+ },
+ "peerDependencies": {
+ "chevrotain": "^11.0.0"
}
},
"node_modules/chokidar": {
@@ -4110,9 +5001,9 @@
}
},
"node_modules/ci-info": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz",
- "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz",
+ "integrity": "sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==",
"dev": true,
"funding": [
{
@@ -4125,12 +5016,6 @@
"node": ">=8"
}
},
- "node_modules/citeproc": {
- "version": "2.4.63",
- "resolved": "https://registry.npmjs.org/citeproc/-/citeproc-2.4.63.tgz",
- "integrity": "sha512-68F95Bp4UbgZU/DBUGQn0qV3HDZLCdI9+Bb2ByrTaNJDL5VEm9LqaiNaxljsvoaExSLEXe1/r6n2Z06SCzW3/Q==",
- "license": "CPAL-1.0 OR AGPL-1.0"
- },
"node_modules/clean-regexp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz",
@@ -4217,9 +5102,9 @@
}
},
"node_modules/codemirror": {
- "version": "5.65.16",
- "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.16.tgz",
- "integrity": "sha512-br21LjYmSlVL0vFCPWPfhzUCT34FM/pAdK7rRIZwa0rrtrIdotvP4Oh4GUHsu2E3IrQMCfRkL/fN3ytMNxVQvg==",
+ "version": "5.65.19",
+ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.19.tgz",
+ "integrity": "sha512-+aFkvqhaAVr1gferNMuN8vkTSrWIFvzlMV9I2KBLCWS2WpZ2+UAkZjlMZmEuT+gcXTi6RrGQCkWq1/bDtGqhIA==",
"license": "MIT"
},
"node_modules/codemirror-spell-checker": {
@@ -4266,6 +5151,7 @@
"version": "10.0.1",
"resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
"integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=14"
@@ -4292,13 +5178,13 @@
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
"license": "MIT"
},
"node_modules/confbox": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz",
- "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==",
- "dev": true,
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.1.tgz",
+ "integrity": "sha512-hkT3yDPFbs95mNCy1+7qNKC6Pro+/ibzYxtM2iqEigpf0sVw+bg4Zh9/snjsBcf990vfIsg5+1U7VyiyBb3etg==",
"license": "MIT"
},
"node_modules/config-chain": {
@@ -4313,13 +5199,13 @@
}
},
"node_modules/core-js-compat": {
- "version": "3.37.1",
- "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz",
- "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==",
+ "version": "3.41.0",
+ "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz",
+ "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "browserslist": "^4.23.0"
+ "browserslist": "^4.24.4"
},
"funding": {
"type": "opencollective",
@@ -4362,9 +5248,9 @@
}
},
"node_modules/cross-spawn": {
- "version": "7.0.3",
- "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
- "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"dependencies": {
"path-key": "^3.1.0",
@@ -4388,9 +5274,9 @@
}
},
"node_modules/css-functions-list": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz",
- "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==",
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.3.tgz",
+ "integrity": "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==",
"dev": true,
"license": "MIT",
"engines": {
@@ -4450,13 +5336,13 @@
}
},
"node_modules/css-tree": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
- "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz",
+ "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "mdn-data": "2.0.30",
+ "mdn-data": "2.12.2",
"source-map-js": "^1.0.1"
},
"engines": {
@@ -4531,9 +5417,9 @@
"license": "MIT"
},
"node_modules/cytoscape": {
- "version": "3.30.0",
- "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.30.0.tgz",
- "integrity": "sha512-l590mjTHT6/Cbxp13dGPC2Y7VXdgc+rUeF8AnF/JPzhjNevbDJfObnJgaSjlldOgBQZbue+X6IUZ7r5GAgvauQ==",
+ "version": "3.31.1",
+ "resolved": "https://registry.npmjs.org/cytoscape/-/cytoscape-3.31.1.tgz",
+ "integrity": "sha512-Hx5Mtb1+hnmAKaZZ/7zL1Y5HTFYOjdDswZy/jD+1WINRU8KVi1B7+vlHdsTwY+VCFucTreoyu1RDzQJ9u0d2Hw==",
"license": "MIT",
"engines": {
"node": ">=0.10"
@@ -4551,6 +5437,33 @@
"cytoscape": "^3.2.0"
}
},
+ "node_modules/cytoscape-fcose": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz",
+ "integrity": "sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ==",
+ "license": "MIT",
+ "dependencies": {
+ "cose-base": "^2.2.0"
+ },
+ "peerDependencies": {
+ "cytoscape": "^3.2.0"
+ }
+ },
+ "node_modules/cytoscape-fcose/node_modules/cose-base": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz",
+ "integrity": "sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g==",
+ "license": "MIT",
+ "dependencies": {
+ "layout-base": "^2.0.0"
+ }
+ },
+ "node_modules/cytoscape-fcose/node_modules/layout-base": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz",
+ "integrity": "sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==",
+ "license": "MIT"
+ },
"node_modules/d3": {
"version": "7.9.0",
"resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz",
@@ -4996,22 +5909,15 @@
}
},
"node_modules/dagre-d3-es": {
- "version": "7.0.10",
- "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz",
- "integrity": "sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==",
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz",
+ "integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==",
"license": "MIT",
"dependencies": {
- "d3": "^7.8.2",
+ "d3": "^7.9.0",
"lodash-es": "^4.17.21"
}
},
- "node_modules/damerau-levenshtein": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
- "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==",
- "dev": true,
- "license": "BSD-2-Clause"
- },
"node_modules/data-uri-to-buffer": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-2.0.2.tgz",
@@ -5020,15 +5926,15 @@
"license": "MIT"
},
"node_modules/data-view-buffer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz",
- "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz",
+ "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.6",
+ "call-bound": "^1.0.3",
"es-errors": "^1.3.0",
- "is-data-view": "^1.0.1"
+ "is-data-view": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -5038,31 +5944,31 @@
}
},
"node_modules/data-view-byte-length": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz",
- "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz",
+ "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bound": "^1.0.3",
"es-errors": "^1.3.0",
- "is-data-view": "^1.0.1"
+ "is-data-view": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "url": "https://github.com/sponsors/inspect-js"
}
},
"node_modules/data-view-byte-offset": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz",
- "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz",
+ "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.6",
+ "call-bound": "^1.0.2",
"es-errors": "^1.3.0",
"is-data-view": "^1.0.1"
},
@@ -5074,18 +5980,18 @@
}
},
"node_modules/dayjs": {
- "version": "1.11.11",
- "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz",
- "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==",
+ "version": "1.11.12",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.12.tgz",
+ "integrity": "sha512-Rt2g+nTbLlDWZTwwrIXjy9MeiZmSDI375FvZs72ngxx8PDC6YXOeR3q5LAuPzjZQxhiWdRKac7RKV+YyQYfYIg==",
"license": "MIT"
},
"node_modules/debug": {
- "version": "4.3.5",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz",
- "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
"license": "MIT",
"dependencies": {
- "ms": "2.1.2"
+ "ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
@@ -5097,9 +6003,10 @@
}
},
"node_modules/decode-named-character-reference": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz",
- "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.1.0.tgz",
+ "integrity": "sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"character-entities": "^2.0.0"
@@ -5120,51 +6027,15 @@
}
},
"node_modules/deep-eql": {
- "version": "4.1.4",
- "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.4.tgz",
- "integrity": "sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "type-detect": "^4.0.0"
- },
"engines": {
"node": ">=6"
}
},
- "node_modules/deep-equal": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.3.tgz",
- "integrity": "sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-buffer-byte-length": "^1.0.0",
- "call-bind": "^1.0.5",
- "es-get-iterator": "^1.1.3",
- "get-intrinsic": "^1.2.2",
- "is-arguments": "^1.1.1",
- "is-array-buffer": "^3.0.2",
- "is-date-object": "^1.0.5",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.2",
- "isarray": "^2.0.5",
- "object-is": "^1.1.5",
- "object-keys": "^1.1.1",
- "object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.5.1",
- "side-channel": "^1.0.4",
- "which-boxed-primitive": "^1.0.2",
- "which-collection": "^1.0.1",
- "which-typed-array": "^1.1.13"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@@ -5241,36 +6112,32 @@
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
+ "node_modules/devlop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz",
+ "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dequal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/didyoumean": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
"integrity": "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==",
"license": "Apache-2.0"
},
- "node_modules/diff": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz",
- "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "node_modules/diff-sequences": {
- "version": "29.6.3",
- "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz",
- "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -5304,9 +6171,9 @@
}
},
"node_modules/dom-input-range": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/dom-input-range/-/dom-input-range-1.1.6.tgz",
- "integrity": "sha512-4o/SkTpscD0n81BeErrrtmE58lG8vTks++92vk//ld0NmkQTb4AVJ2rexh2yor6rtBf5IMte26u+fF3EgCppPQ==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/dom-input-range/-/dom-input-range-1.2.0.tgz",
+ "integrity": "sha512-8HVA5Oy5Vt872S7IXsjjp6/5Hqsm5YZLhurxwwQXp80T9qVsj8/mEUH3sQlFujLLUoWfxiaThHHuJ3/q1MHVuA==",
"license": "MIT",
"workspaces": [
"demos"
@@ -5357,15 +6224,18 @@
}
},
"node_modules/dompurify": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.1.5.tgz",
- "integrity": "sha512-lwG+n5h8QNpxtyrJW/gJWckL+1/DQiYMX8f7t8Z2AZTPw1esVrqjI63i7Zc2Gz0aKzLVMYC1V1PL/ky+aY/NgA==",
- "license": "(MPL-2.0 OR Apache-2.0)"
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.2.4.tgz",
+ "integrity": "sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==",
+ "license": "(MPL-2.0 OR Apache-2.0)",
+ "optionalDependencies": {
+ "@types/trusted-types": "^2.0.7"
+ }
},
"node_modules/domutils": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
- "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -5387,6 +6257,21 @@
"just-extend": "^5.0.0"
}
},
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/eastasianwidth": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -5442,21 +6327,15 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.815",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.815.tgz",
- "integrity": "sha512-OvpTT2ItpOXJL7IGcYakRjHCt8L5GrrN/wHCQsRB4PQa1X9fe+X9oen245mIId7s14xvArCGSTIq644yPUKKLg==",
+ "version": "1.5.123",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.123.tgz",
+ "integrity": "sha512-refir3NlutEZqlKaBLK0tzlVLe5P2wDKS7UQt/3SpibizgsRAPOsqQC3ffw1nlv3ze5gjRQZYHoPymgVZkplFA==",
"license": "ISC"
},
- "node_modules/elkjs": {
- "version": "0.9.3",
- "resolved": "https://registry.npmjs.org/elkjs/-/elkjs-0.9.3.tgz",
- "integrity": "sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==",
- "license": "EPL-2.0"
- },
"node_modules/emoji-regex": {
- "version": "9.2.2",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
- "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"license": "MIT"
},
"node_modules/emojis-list": {
@@ -5469,9 +6348,9 @@
}
},
"node_modules/enhanced-resolve": {
- "version": "5.17.0",
- "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.0.tgz",
- "integrity": "sha512-dwDPwZL0dmye8Txp2gzFmA6sxALaSvdRDjPH0viLcKrtlOL3tw62nWWweVD1SdILDTJrbrL6tdWVN58Wo6U3eA==",
+ "version": "5.18.1",
+ "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz",
+ "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==",
"license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.4",
@@ -5503,9 +6382,9 @@
}
},
"node_modules/envinfo": {
- "version": "7.13.0",
- "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz",
- "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==",
+ "version": "7.14.0",
+ "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz",
+ "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==",
"license": "MIT",
"bin": {
"envinfo": "dist/cli.js"
@@ -5524,58 +6403,63 @@
}
},
"node_modules/es-abstract": {
- "version": "1.23.3",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz",
- "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==",
+ "version": "1.23.9",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.9.tgz",
+ "integrity": "sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "array-buffer-byte-length": "^1.0.1",
- "arraybuffer.prototype.slice": "^1.0.3",
+ "array-buffer-byte-length": "^1.0.2",
+ "arraybuffer.prototype.slice": "^1.0.4",
"available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.7",
- "data-view-buffer": "^1.0.1",
- "data-view-byte-length": "^1.0.1",
- "data-view-byte-offset": "^1.0.0",
- "es-define-property": "^1.0.0",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "data-view-buffer": "^1.0.2",
+ "data-view-byte-length": "^1.0.2",
+ "data-view-byte-offset": "^1.0.1",
+ "es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.0.0",
- "es-set-tostringtag": "^2.0.3",
- "es-to-primitive": "^1.2.1",
- "function.prototype.name": "^1.1.6",
- "get-intrinsic": "^1.2.4",
- "get-symbol-description": "^1.0.2",
- "globalthis": "^1.0.3",
- "gopd": "^1.0.1",
+ "es-set-tostringtag": "^2.1.0",
+ "es-to-primitive": "^1.3.0",
+ "function.prototype.name": "^1.1.8",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.0",
+ "get-symbol-description": "^1.1.0",
+ "globalthis": "^1.0.4",
+ "gopd": "^1.2.0",
"has-property-descriptors": "^1.0.2",
- "has-proto": "^1.0.3",
- "has-symbols": "^1.0.3",
+ "has-proto": "^1.2.0",
+ "has-symbols": "^1.1.0",
"hasown": "^2.0.2",
- "internal-slot": "^1.0.7",
- "is-array-buffer": "^3.0.4",
+ "internal-slot": "^1.1.0",
+ "is-array-buffer": "^3.0.5",
"is-callable": "^1.2.7",
- "is-data-view": "^1.0.1",
- "is-negative-zero": "^2.0.3",
- "is-regex": "^1.1.4",
- "is-shared-array-buffer": "^1.0.3",
- "is-string": "^1.0.7",
- "is-typed-array": "^1.1.13",
- "is-weakref": "^1.0.2",
- "object-inspect": "^1.13.1",
+ "is-data-view": "^1.0.2",
+ "is-regex": "^1.2.1",
+ "is-shared-array-buffer": "^1.0.4",
+ "is-string": "^1.1.1",
+ "is-typed-array": "^1.1.15",
+ "is-weakref": "^1.1.0",
+ "math-intrinsics": "^1.1.0",
+ "object-inspect": "^1.13.3",
"object-keys": "^1.1.1",
- "object.assign": "^4.1.5",
- "regexp.prototype.flags": "^1.5.2",
- "safe-array-concat": "^1.1.2",
- "safe-regex-test": "^1.0.3",
- "string.prototype.trim": "^1.2.9",
- "string.prototype.trimend": "^1.0.8",
+ "object.assign": "^4.1.7",
+ "own-keys": "^1.0.1",
+ "regexp.prototype.flags": "^1.5.3",
+ "safe-array-concat": "^1.1.3",
+ "safe-push-apply": "^1.0.0",
+ "safe-regex-test": "^1.1.0",
+ "set-proto": "^1.0.0",
+ "string.prototype.trim": "^1.2.10",
+ "string.prototype.trimend": "^1.0.9",
"string.prototype.trimstart": "^1.0.8",
- "typed-array-buffer": "^1.0.2",
- "typed-array-byte-length": "^1.0.1",
- "typed-array-byte-offset": "^1.0.2",
- "typed-array-length": "^1.0.6",
- "unbox-primitive": "^1.0.2",
- "which-typed-array": "^1.1.15"
+ "typed-array-buffer": "^1.0.3",
+ "typed-array-byte-length": "^1.0.3",
+ "typed-array-byte-offset": "^1.0.4",
+ "typed-array-length": "^1.0.7",
+ "unbox-primitive": "^1.1.0",
+ "which-typed-array": "^1.1.18"
},
"engines": {
"node": ">= 0.4"
@@ -5608,14 +6492,11 @@
}
},
"node_modules/es-define-property": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
- "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "get-intrinsic": "^1.2.4"
- },
"engines": {
"node": ">= 0.4"
}
@@ -5630,63 +6511,16 @@
"node": ">= 0.4"
}
},
- "node_modules/es-get-iterator": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
- "integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.1.3",
- "has-symbols": "^1.0.3",
- "is-arguments": "^1.1.1",
- "is-map": "^2.0.2",
- "is-set": "^2.0.2",
- "is-string": "^1.0.7",
- "isarray": "^2.0.5",
- "stop-iteration-iterator": "^1.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/es-iterator-helpers": {
- "version": "1.0.19",
- "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz",
- "integrity": "sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.3",
- "es-errors": "^1.3.0",
- "es-set-tostringtag": "^2.0.3",
- "function-bind": "^1.1.2",
- "get-intrinsic": "^1.2.4",
- "globalthis": "^1.0.3",
- "has-property-descriptors": "^1.0.2",
- "has-proto": "^1.0.3",
- "has-symbols": "^1.0.3",
- "internal-slot": "^1.0.7",
- "iterator.prototype": "^1.1.2",
- "safe-array-concat": "^1.1.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
"node_modules/es-module-lexer": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz",
- "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz",
+ "integrity": "sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==",
"license": "MIT"
},
"node_modules/es-object-atoms": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz",
- "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5697,40 +6531,44 @@
}
},
"node_modules/es-set-tostringtag": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz",
- "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "get-intrinsic": "^1.2.4",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
- "hasown": "^2.0.1"
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-shim-unscopables": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz",
- "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz",
+ "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "hasown": "^2.0.0"
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
}
},
"node_modules/es-to-primitive": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
- "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz",
+ "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "is-callable": "^1.1.4",
- "is-date-object": "^1.0.1",
- "is-symbol": "^1.0.2"
+ "is-callable": "^1.2.7",
+ "is-date-object": "^1.0.5",
+ "is-symbol": "^1.0.4"
},
"engines": {
"node": ">= 0.4"
@@ -5740,50 +6578,52 @@
}
},
"node_modules/esbuild": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
- "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz",
+ "integrity": "sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==",
"hasInstallScript": true,
"license": "MIT",
"bin": {
"esbuild": "bin/esbuild"
},
"engines": {
- "node": ">=12"
+ "node": ">=18"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.20.2",
- "@esbuild/android-arm": "0.20.2",
- "@esbuild/android-arm64": "0.20.2",
- "@esbuild/android-x64": "0.20.2",
- "@esbuild/darwin-arm64": "0.20.2",
- "@esbuild/darwin-x64": "0.20.2",
- "@esbuild/freebsd-arm64": "0.20.2",
- "@esbuild/freebsd-x64": "0.20.2",
- "@esbuild/linux-arm": "0.20.2",
- "@esbuild/linux-arm64": "0.20.2",
- "@esbuild/linux-ia32": "0.20.2",
- "@esbuild/linux-loong64": "0.20.2",
- "@esbuild/linux-mips64el": "0.20.2",
- "@esbuild/linux-ppc64": "0.20.2",
- "@esbuild/linux-riscv64": "0.20.2",
- "@esbuild/linux-s390x": "0.20.2",
- "@esbuild/linux-x64": "0.20.2",
- "@esbuild/netbsd-x64": "0.20.2",
- "@esbuild/openbsd-x64": "0.20.2",
- "@esbuild/sunos-x64": "0.20.2",
- "@esbuild/win32-arm64": "0.20.2",
- "@esbuild/win32-ia32": "0.20.2",
- "@esbuild/win32-x64": "0.20.2"
+ "@esbuild/aix-ppc64": "0.25.1",
+ "@esbuild/android-arm": "0.25.1",
+ "@esbuild/android-arm64": "0.25.1",
+ "@esbuild/android-x64": "0.25.1",
+ "@esbuild/darwin-arm64": "0.25.1",
+ "@esbuild/darwin-x64": "0.25.1",
+ "@esbuild/freebsd-arm64": "0.25.1",
+ "@esbuild/freebsd-x64": "0.25.1",
+ "@esbuild/linux-arm": "0.25.1",
+ "@esbuild/linux-arm64": "0.25.1",
+ "@esbuild/linux-ia32": "0.25.1",
+ "@esbuild/linux-loong64": "0.25.1",
+ "@esbuild/linux-mips64el": "0.25.1",
+ "@esbuild/linux-ppc64": "0.25.1",
+ "@esbuild/linux-riscv64": "0.25.1",
+ "@esbuild/linux-s390x": "0.25.1",
+ "@esbuild/linux-x64": "0.25.1",
+ "@esbuild/netbsd-arm64": "0.25.1",
+ "@esbuild/netbsd-x64": "0.25.1",
+ "@esbuild/openbsd-arm64": "0.25.1",
+ "@esbuild/openbsd-x64": "0.25.1",
+ "@esbuild/sunos-x64": "0.25.1",
+ "@esbuild/win32-arm64": "0.25.1",
+ "@esbuild/win32-ia32": "0.25.1",
+ "@esbuild/win32-x64": "0.25.1"
}
},
"node_modules/esbuild-loader": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.1.0.tgz",
- "integrity": "sha512-543TtIvqbqouEMlOHg4xKoDQkmdImlwIpyAIgpUtDPvMuklU/c2k+Qt2O3VeDBgAwozxmlEbjOzV+F8CZ0g+Bw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.3.0.tgz",
+ "integrity": "sha512-D7HeJNdkDKKMarPQO/3dlJT6RwN2YJO7ENU6RPlpOz5YxSHnUNi2yvW41Bckvi1EVwctIaLzlb0ni5ag2GINYA==",
"license": "MIT",
"dependencies": {
- "esbuild": "^0.20.0",
+ "esbuild": "^0.25.0",
"get-tsconfig": "^4.7.0",
"loader-utils": "^2.0.4",
"webpack-sources": "^1.4.3"
@@ -5796,9 +6636,9 @@
}
},
"node_modules/escalade": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
- "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"license": "MIT",
"engines": {
"node": ">=6"
@@ -5830,65 +6670,70 @@
}
},
"node_modules/eslint": {
- "version": "8.57.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
- "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
+ "version": "9.22.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.22.0.tgz",
+ "integrity": "sha512-9V/QURhsRN40xuHXWjV64yvrzMjcz7ZyNoF2jJFmy9j/SLk0u1OLSZgXi28MrXjymnjEGSR80WCdab3RGMDveQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.4",
- "@eslint/js": "8.57.0",
- "@humanwhocodes/config-array": "^0.11.14",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.19.2",
+ "@eslint/config-helpers": "^0.1.0",
+ "@eslint/core": "^0.12.0",
+ "@eslint/eslintrc": "^3.3.0",
+ "@eslint/js": "9.22.0",
+ "@eslint/plugin-kit": "^0.2.7",
+ "@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1",
- "@nodelib/fs.walk": "^1.2.8",
- "@ungap/structured-clone": "^1.2.0",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "@types/json-schema": "^7.0.15",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
- "cross-spawn": "^7.0.2",
+ "cross-spawn": "^7.0.6",
"debug": "^4.3.2",
- "doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.2.2",
- "eslint-visitor-keys": "^3.4.3",
- "espree": "^9.6.1",
- "esquery": "^1.4.2",
+ "eslint-scope": "^8.3.0",
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.5.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
- "file-entry-cache": "^6.0.1",
+ "file-entry-cache": "^8.0.0",
"find-up": "^5.0.0",
"glob-parent": "^6.0.2",
- "globals": "^13.19.0",
- "graphemer": "^1.4.0",
"ignore": "^5.2.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
- "is-path-inside": "^3.0.3",
- "js-yaml": "^4.1.0",
"json-stable-stringify-without-jsonify": "^1.0.1",
- "levn": "^0.4.1",
"lodash.merge": "^4.6.2",
"minimatch": "^3.1.2",
"natural-compare": "^1.4.0",
- "optionator": "^0.9.3",
- "strip-ansi": "^6.0.1",
- "text-table": "^0.2.0"
+ "optionator": "^0.9.3"
},
"bin": {
"eslint": "bin/eslint.js"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
- "url": "https://opencollective.com/eslint"
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
}
},
"node_modules/eslint-compat-utils": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz",
- "integrity": "sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==",
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/eslint-compat-utils/-/eslint-compat-utils-0.6.4.tgz",
+ "integrity": "sha512-/u+GQt8NMfXO8w17QendT4gvO5acfxQsAKirAt0LVxDnr2N8YLCVbregaNc/Yhp7NM128DwCaRvr8PLDfeNkQw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -5901,19 +6746,6 @@
"eslint": ">=6.0.0"
}
},
- "node_modules/eslint-config-prettier": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz",
- "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "eslint-config-prettier": "bin/cli.js"
- },
- "peerDependencies": {
- "eslint": ">=7.0.0"
- }
- },
"node_modules/eslint-import-resolver-node": {
"version": "0.3.9",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz",
@@ -5936,438 +6768,166 @@
"ms": "^2.1.1"
}
},
- "node_modules/eslint-module-utils": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz",
- "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==",
+ "node_modules/eslint-import-resolver-typescript": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.1.1.tgz",
+ "integrity": "sha512-91As8PwH6xjPwndAbvhTuZ3DUfdl4HttocWRyaLOd5T4uUo6km8EDO7Sve4jzH50V1wbgql2nOFbE3GGfARJag==",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
"dependencies": {
- "debug": "^3.2.7"
+ "debug": "^4.4.0",
+ "get-tsconfig": "^4.10.0",
+ "is-bun-module": "^1.3.0",
+ "rspack-resolver": "^1.1.2",
+ "stable-hash": "^0.0.5",
+ "tinyglobby": "^0.2.12"
},
"engines": {
- "node": ">=4"
+ "node": "^16.17.0 || >=18.6.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "eslint-plugin-import": "*",
+ "eslint-plugin-import-x": "*"
},
"peerDependenciesMeta": {
- "eslint": {
+ "eslint-plugin-import": {
+ "optional": true
+ },
+ "eslint-plugin-import-x": {
"optional": true
}
}
},
- "node_modules/eslint-module-utils/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.1"
- }
- },
"node_modules/eslint-plugin-array-func": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-array-func/-/eslint-plugin-array-func-4.0.0.tgz",
- "integrity": "sha512-p3NY2idNIvgmQLF2/62ZskYt8gOuUgQ51smRc3Lh7FtSozpNc2sg+lniz9VaCagLZHEZTl8qGJKqE7xy8O/D/g==",
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-array-func/-/eslint-plugin-array-func-5.0.2.tgz",
+ "integrity": "sha512-iyLex2+pTcxHZ6OLL80oMy+CtffpJ9j6A/57VQi1VN5bK1IS/0o+mWvezDHeAlwXjn6ksRO9L5SGU329BBuY8A==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"peerDependencies": {
- "eslint": ">=8.40.0"
+ "eslint": ">=8.51.0"
}
},
- "node_modules/eslint-plugin-escompat": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-escompat/-/eslint-plugin-escompat-3.4.0.tgz",
- "integrity": "sha512-ufTPv8cwCxTNoLnTZBFTQ5SxU2w7E7wiMIS7PSxsgP1eAxFjtSaoZ80LRn64hI8iYziE6kJG6gX/ZCJVxh48Bg==",
+ "node_modules/eslint-plugin-import-x": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.7.0.tgz",
+ "integrity": "sha512-LHxq8V6SJ99hSFYAexxUKk3gVsjb8fuNRGsbMinwlJGvcuREP9SVzCCNKJ3POdDowEHdExy/bPN6YfjraueIXA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "browserslist": "^4.21.0"
- },
- "peerDependencies": {
- "eslint": ">=5.14.1"
- }
- },
- "node_modules/eslint-plugin-eslint-comments": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz",
- "integrity": "sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "escape-string-regexp": "^1.0.5",
- "ignore": "^5.0.5"
- },
- "engines": {
- "node": ">=6.5.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/mysticatea"
- },
- "peerDependencies": {
- "eslint": ">=4.19.1"
- }
- },
- "node_modules/eslint-plugin-eslint-comments/node_modules/escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=0.8.0"
- }
- },
- "node_modules/eslint-plugin-filenames": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-filenames/-/eslint-plugin-filenames-1.3.2.tgz",
- "integrity": "sha512-tqxJTiEM5a0JmRCUYQmxw23vtTxrb2+a3Q2mMOPhFxvt7ZQQJmdiuMby9B/vUAuVMghyP7oET+nIf6EO6CBd/w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "lodash.camelcase": "4.3.0",
- "lodash.kebabcase": "4.1.1",
- "lodash.snakecase": "4.1.1",
- "lodash.upperfirst": "4.3.1"
- },
- "peerDependencies": {
- "eslint": "*"
- }
- },
- "node_modules/eslint-plugin-github": {
- "version": "4.10.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-github/-/eslint-plugin-github-4.10.2.tgz",
- "integrity": "sha512-F1F5aAFgi1Y5hYoTFzGQACBkw5W1hu2Fu5FSTrMlXqrojJnKl1S2pWO/rprlowRQpt+hzHhqSpsfnodJEVd5QA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@github/browserslist-config": "^1.0.0",
- "@typescript-eslint/eslint-plugin": "^7.0.1",
- "@typescript-eslint/parser": "^7.0.1",
- "aria-query": "^5.3.0",
- "eslint-config-prettier": ">=8.0.0",
- "eslint-plugin-escompat": "^3.3.3",
- "eslint-plugin-eslint-comments": "^3.2.0",
- "eslint-plugin-filenames": "^1.3.2",
- "eslint-plugin-i18n-text": "^1.0.1",
- "eslint-plugin-import": "^2.25.2",
- "eslint-plugin-jsx-a11y": "^6.7.1",
- "eslint-plugin-no-only-tests": "^3.0.0",
- "eslint-plugin-prettier": "^5.0.0",
- "eslint-rule-documentation": ">=1.0.0",
- "jsx-ast-utils": "^3.3.2",
- "prettier": "^3.0.0",
- "svg-element-attributes": "^1.3.1"
- },
- "bin": {
- "eslint-ignore-errors": "bin/eslint-ignore-errors.js"
- },
- "peerDependencies": {
- "eslint": "^8.0.1"
- }
- },
- "node_modules/eslint-plugin-i": {
- "version": "2.29.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-i/-/eslint-plugin-i-2.29.1.tgz",
- "integrity": "sha512-ORizX37MelIWLbMyqI7hi8VJMf7A0CskMmYkB+lkCX3aF4pkGV7kwx5bSEb4qx7Yce2rAf9s34HqDRPjGRZPNQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "debug": "^4.3.4",
+ "@types/doctrine": "^0.0.9",
+ "@typescript-eslint/utils": "^8.26.1",
+ "debug": "^4.4.0",
"doctrine": "^3.0.0",
"eslint-import-resolver-node": "^0.3.9",
- "eslint-module-utils": "^2.8.0",
- "get-tsconfig": "^4.7.2",
+ "get-tsconfig": "^4.10.0",
"is-glob": "^4.0.3",
- "minimatch": "^3.1.2",
- "semver": "^7.5.4"
+ "minimatch": "^10.0.1",
+ "oxc-resolver": "^5.0.0",
+ "semver": "^7.7.1",
+ "stable-hash": "^0.0.5",
+ "tslib": "^2.8.1"
},
"engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://opencollective.com/unts"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"peerDependencies": {
- "eslint": "^7.2.0 || ^8"
- }
- },
- "node_modules/eslint-plugin-i/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/eslint-plugin-i/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/eslint-plugin-i18n-text": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-i18n-text/-/eslint-plugin-i18n-text-1.0.1.tgz",
- "integrity": "sha512-3G3UetST6rdqhqW9SfcfzNYMpQXS7wNkJvp6dsXnjzGiku6Iu5hl3B0kmk6lIcFPwYjhQIY+tXVRtK9TlGT7RA==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "eslint": ">=5.0.0"
- }
- },
- "node_modules/eslint-plugin-import": {
- "version": "2.29.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz",
- "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "array-includes": "^3.1.7",
- "array.prototype.findlastindex": "^1.2.3",
- "array.prototype.flat": "^1.3.2",
- "array.prototype.flatmap": "^1.3.2",
- "debug": "^3.2.7",
- "doctrine": "^2.1.0",
- "eslint-import-resolver-node": "^0.3.9",
- "eslint-module-utils": "^2.8.0",
- "hasown": "^2.0.0",
- "is-core-module": "^2.13.1",
- "is-glob": "^4.0.3",
- "minimatch": "^3.1.2",
- "object.fromentries": "^2.0.7",
- "object.groupby": "^1.0.1",
- "object.values": "^1.1.7",
- "semver": "^6.3.1",
- "tsconfig-paths": "^3.15.0"
- },
- "engines": {
- "node": ">=4"
- },
- "peerDependencies": {
- "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8"
- }
- },
- "node_modules/eslint-plugin-import/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/eslint-plugin-import/node_modules/debug": {
- "version": "3.2.7",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
- "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ms": "^2.1.1"
- }
- },
- "node_modules/eslint-plugin-import/node_modules/doctrine": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
- "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "esutils": "^2.0.2"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/eslint-plugin-import/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/eslint-plugin-import/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/eslint-plugin-jquery": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-jquery/-/eslint-plugin-jquery-1.5.1.tgz",
- "integrity": "sha512-L7v1eaK5t80C0lvUXPFP9MKnBOqPSKhCOYyzy4LZ0+iK+TJwN8S9gAkzzP1AOhypRIwA88HF6phQ9C7jnOpW8w==",
- "dev": true,
- "license": "MIT",
- "peerDependencies": {
- "eslint": ">=5.4.0"
- }
- },
- "node_modules/eslint-plugin-jsx-a11y": {
- "version": "6.9.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.9.0.tgz",
- "integrity": "sha512-nOFOCaJG2pYqORjK19lqPqxMO/JpvdCZdPtNdxY3kvom3jTvkAbOvQvD8wuD0G8BYR0IGAGYDlzqWJOh/ybn2g==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "aria-query": "~5.1.3",
- "array-includes": "^3.1.8",
- "array.prototype.flatmap": "^1.3.2",
- "ast-types-flow": "^0.0.8",
- "axe-core": "^4.9.1",
- "axobject-query": "~3.1.1",
- "damerau-levenshtein": "^1.0.8",
- "emoji-regex": "^9.2.2",
- "es-iterator-helpers": "^1.0.19",
- "hasown": "^2.0.2",
- "jsx-ast-utils": "^3.3.5",
- "language-tags": "^1.0.9",
- "minimatch": "^3.1.2",
- "object.fromentries": "^2.0.8",
- "safe-regex-test": "^1.0.3",
- "string.prototype.includes": "^2.0.0"
- },
- "engines": {
- "node": ">=4.0"
- },
- "peerDependencies": {
- "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
- }
- },
- "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
- "integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
- "dev": true,
- "license": "Apache-2.0",
- "dependencies": {
- "deep-equal": "^2.0.5"
- }
- },
- "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
+ "eslint": "^8.57.0 || ^9.0.0"
}
},
"node_modules/eslint-plugin-no-jquery": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-2.7.0.tgz",
- "integrity": "sha512-Aeg7dA6GTH1AcWLlBtWNzOU9efK5KpNi7b0EhBO0o0M+awyzguUUo8gF6hXGjQ9n5h8/uRtYv9zOqQkeC5CG0w==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-no-jquery/-/eslint-plugin-no-jquery-3.1.1.tgz",
+ "integrity": "sha512-LTLO3jH/Tjr1pmxCEqtV6qmt+OChv8La4fwgG470JRpgxyFF4NOzoC9CRy92GIWD3Yjl0qLEgPmD2FLQWcNEjg==",
"dev": true,
"license": "MIT",
"peerDependencies": {
- "eslint": ">=2.3.0"
- }
- },
- "node_modules/eslint-plugin-no-only-tests": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz",
- "integrity": "sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=5.0.0"
+ "eslint": ">=8.0.0"
}
},
"node_modules/eslint-plugin-no-use-extend-native": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.5.0.tgz",
- "integrity": "sha512-dBNjs8hor8rJgeXLH4HTut5eD3RGWf9JUsadIfuL7UosVQ/dnvOKwxEcRrXrFxrMZ8llUVWT+hOimxJABsAUzQ==",
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.7.2.tgz",
+ "integrity": "sha512-hUBlwaTXIO1GzTwPT6pAjvYwmSHe4XduDhAiQvur4RUujmBUFjd8Nb2+e7WQdsQ+nGHWGRlogcUWXJRGqizTWw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "is-get-set-prop": "^1.0.0",
- "is-js-type": "^2.0.0",
- "is-obj-prop": "^1.0.0",
- "is-proto-prop": "^2.0.0"
+ "is-get-set-prop": "^2.0.0",
+ "is-js-type": "^3.0.0",
+ "is-obj-prop": "^2.0.0",
+ "is-proto-prop": "^3.0.1"
},
"engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/eslint-plugin-prettier": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz",
- "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "prettier-linter-helpers": "^1.0.0",
- "synckit": "^0.8.6"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/eslint-plugin-prettier"
+ "node": ">=18.18.0"
},
"peerDependencies": {
- "@types/eslint": ">=8.0.0",
- "eslint": ">=8.0.0",
- "eslint-config-prettier": "*",
- "prettier": ">=3.0.0"
+ "eslint": "^9.3.0"
+ }
+ },
+ "node_modules/eslint-plugin-playwright": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-2.2.0.tgz",
+ "integrity": "sha512-qSQpAw7RcSzE3zPp8FMGkthaCWovHZ/BsXtpmnGax9vQLIovlh1bsZHEa2+j2lv9DWhnyeLM/qZmp7ffQZfQvg==",
+ "dev": true,
+ "license": "MIT",
+ "workspaces": [
+ "examples"
+ ],
+ "dependencies": {
+ "globals": "^13.23.0"
},
- "peerDependenciesMeta": {
- "@types/eslint": {
- "optional": true
- },
- "eslint-config-prettier": {
- "optional": true
- }
+ "engines": {
+ "node": ">=16.6.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=8.40.0"
+ }
+ },
+ "node_modules/eslint-plugin-playwright/node_modules/globals": {
+ "version": "13.24.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+ "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "type-fest": "^0.20.2"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint-plugin-playwright/node_modules/type-fest": {
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
+ "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "dev": true,
+ "license": "(MIT OR CC0-1.0)",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint-plugin-regexp": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.6.0.tgz",
- "integrity": "sha512-FCL851+kislsTEQEMioAlpDuK5+E5vs0hi1bF8cFlPlHcEjeRhuAzEsGikXRreE+0j4WhW2uO54MqTjXtYOi3A==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-regexp/-/eslint-plugin-regexp-2.7.0.tgz",
+ "integrity": "sha512-U8oZI77SBtH8U3ulZ05iu0qEzIizyEDXd+BWHvyVxTOjGwcDcvy/kEpgFG4DYca2ByRLiVPFZ2GeH7j1pdvZTA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.9.1",
+ "@eslint-community/regexpp": "^4.11.0",
"comment-parser": "^1.4.0",
"jsdoc-type-pratt-parser": "^4.0.0",
"refa": "^0.12.1",
@@ -6382,75 +6942,109 @@
}
},
"node_modules/eslint-plugin-sonarjs": {
- "version": "0.25.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.25.1.tgz",
- "integrity": "sha512-5IOKvj/GMBNqjxBdItfotfRHo7w48496GOu1hxdeXuD0mB1JBlDCViiLHETDTfA8pDAVSBimBEQoetRXYceQEw==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-3.0.2.tgz",
+ "integrity": "sha512-LxjbfwI7ypENeTmGyKmDyNux3COSkMi7H/6Cal5StSLQ6edf0naP45SZR43OclaNR7WfhVTZdhOn63q3/Y6puQ==",
"dev": true,
"license": "LGPL-3.0-only",
- "engines": {
- "node": ">=16"
+ "dependencies": {
+ "@eslint-community/regexpp": "4.12.1",
+ "builtin-modules": "3.3.0",
+ "bytes": "3.1.2",
+ "functional-red-black-tree": "1.0.1",
+ "jsx-ast-utils": "3.3.5",
+ "minimatch": "9.0.5",
+ "scslre": "0.3.0",
+ "semver": "7.7.1",
+ "typescript": "^5"
},
"peerDependencies": {
- "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+ "eslint": "^8.0.0 || ^9.0.0"
}
},
- "node_modules/eslint-plugin-unicorn": {
- "version": "52.0.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-52.0.0.tgz",
- "integrity": "sha512-1Yzm7/m+0R4djH0tjDjfVei/ju2w3AzUGjG6q8JnuNIL5xIwsflyCooW5sfBvQp2pMYQFSWWCFONsjCax1EHng==",
+ "node_modules/eslint-plugin-sonarjs/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/eslint-plugin-toml": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-toml/-/eslint-plugin-toml-0.12.0.tgz",
+ "integrity": "sha512-+/wVObA9DVhwZB1nG83D2OAQRrcQZXy+drqUnFJKymqnmbnbfg/UPmEMCKrJNcEboUGxUjYrJlgy+/Y930mURQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/helper-validator-identifier": "^7.22.20",
- "@eslint-community/eslint-utils": "^4.4.0",
- "@eslint/eslintrc": "^2.1.4",
- "ci-info": "^4.0.0",
- "clean-regexp": "^1.0.0",
- "core-js-compat": "^3.34.0",
- "esquery": "^1.5.0",
- "indent-string": "^4.0.0",
- "is-builtin-module": "^3.2.1",
- "jsesc": "^3.0.2",
- "pluralize": "^8.0.0",
- "read-pkg-up": "^7.0.1",
- "regexp-tree": "^0.1.27",
- "regjsparser": "^0.10.0",
- "semver": "^7.5.4",
- "strip-indent": "^3.0.0"
+ "debug": "^4.1.1",
+ "eslint-compat-utils": "^0.6.0",
+ "lodash": "^4.17.19",
+ "toml-eslint-parser": "^0.10.0"
},
"engines": {
- "node": ">=16"
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ota-meshi"
+ },
+ "peerDependencies": {
+ "eslint": ">=6.0.0"
+ }
+ },
+ "node_modules/eslint-plugin-unicorn": {
+ "version": "57.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-57.0.0.tgz",
+ "integrity": "sha512-zUYYa6zfNdTeG9BISWDlcLmz16c+2Ck2o5ZDHh0UzXJz3DEP7xjmlVDTzbyV0W+XksgZ0q37WEWzN2D2Ze+g9Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.25.9",
+ "@eslint-community/eslint-utils": "^4.4.1",
+ "ci-info": "^4.1.0",
+ "clean-regexp": "^1.0.0",
+ "core-js-compat": "^3.40.0",
+ "esquery": "^1.6.0",
+ "globals": "^15.15.0",
+ "indent-string": "^5.0.0",
+ "is-builtin-module": "^4.0.0",
+ "jsesc": "^3.1.0",
+ "pluralize": "^8.0.0",
+ "read-package-up": "^11.0.0",
+ "regexp-tree": "^0.1.27",
+ "regjsparser": "^0.12.0",
+ "semver": "^7.7.1",
+ "strip-indent": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18.18"
},
"funding": {
"url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1"
},
"peerDependencies": {
- "eslint": ">=8.56.0"
+ "eslint": ">=9.20.0"
}
},
- "node_modules/eslint-plugin-vitest": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vitest/-/eslint-plugin-vitest-0.5.4.tgz",
- "integrity": "sha512-um+odCkccAHU53WdKAw39MY61+1x990uXjSPguUCq3VcEHdqJrOb8OTMrbYlY6f9jAKx7x98kLVlIe3RJeJqoQ==",
+ "node_modules/eslint-plugin-unicorn/node_modules/globals": {
+ "version": "15.15.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
+ "integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@typescript-eslint/utils": "^7.7.1"
- },
"engines": {
- "node": "^18.0.0 || >= 20.0.0"
+ "node": ">=18"
},
- "peerDependencies": {
- "eslint": "^8.57.0 || ^9.0.0",
- "vitest": "*"
- },
- "peerDependenciesMeta": {
- "@typescript-eslint/eslint-plugin": {
- "optional": true
- },
- "vitest": {
- "optional": true
- }
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/eslint-plugin-vitest-globals": {
@@ -6461,37 +7055,36 @@
"license": "MIT"
},
"node_modules/eslint-plugin-vue": {
- "version": "9.26.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.26.0.tgz",
- "integrity": "sha512-eTvlxXgd4ijE1cdur850G6KalZqk65k1JKoOI2d1kT3hr8sPD07j1q98FRFdNnpxBELGPWxZmInxeHGF/GxtqQ==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-10.0.0.tgz",
+ "integrity": "sha512-XKckedtajqwmaX6u1VnECmZ6xJt+YvlmMzBPZd+/sI3ub2lpYZyFnsyWo7c3nMOQKJQudeyk1lw/JxdgeKT64w==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "globals": "^13.24.0",
"natural-compare": "^1.4.0",
"nth-check": "^2.1.1",
"postcss-selector-parser": "^6.0.15",
- "semver": "^7.6.0",
- "vue-eslint-parser": "^9.4.2",
+ "semver": "^7.6.3",
"xml-name-validator": "^4.0.0"
},
"engines": {
- "node": "^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"peerDependencies": {
- "eslint": "^6.2.0 || ^7.0.0 || ^8.0.0 || ^9.0.0"
+ "eslint": "^8.57.0 || ^9.0.0",
+ "vue-eslint-parser": "^10.0.0"
}
},
"node_modules/eslint-plugin-vue-scoped-css": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue-scoped-css/-/eslint-plugin-vue-scoped-css-2.8.1.tgz",
- "integrity": "sha512-V6B+zZE60ykYvHTDzdhJ3xa4C83ntmGXqFsylc8l1jdVR9PSgod2+bGFNL7OwRKgZj82ij/o904xa04z1bfCRA==",
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue-scoped-css/-/eslint-plugin-vue-scoped-css-2.9.0.tgz",
+ "integrity": "sha512-zXeKtEUpfk3PlsgKnr9/2U8K2xcsCV1M9hXWRhKbl3wipVowGXfHrhqUzHFVWNAHzEQv0DCDXGFWrmsGFqhGGA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "eslint-compat-utils": "^0.5.0",
+ "eslint-compat-utils": "^0.6.0",
"lodash": "^4.17.21",
"postcss": "^8.4.31",
"postcss-safe-parser": "^6.0.0",
@@ -6511,9 +7104,9 @@
}
},
"node_modules/eslint-plugin-wc": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.1.0.tgz",
- "integrity": "sha512-s/BGOtmpgQ2yifR6EC1OM9t0DwYLgg4ZAL07Kw4eXvBb5TYaPafI+65tswvnZvhH8FqcjERLbBZPPvYsvinkfg==",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-wc/-/eslint-plugin-wc-2.2.1.tgz",
+ "integrity": "sha512-KstLqGmyQz088DvFlDYHg0sHih+w2QeulreCi1D1ftr357klO2zqHdG/bbnNMmuQdVFDuNkopNIyNhmG0XCT/g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6521,23 +7114,13 @@
"js-levenshtein-esm": "^1.2.0"
},
"peerDependencies": {
- "eslint": ">=5"
- }
- },
- "node_modules/eslint-rule-documentation": {
- "version": "1.0.23",
- "resolved": "https://registry.npmjs.org/eslint-rule-documentation/-/eslint-rule-documentation-1.0.23.tgz",
- "integrity": "sha512-pWReu3fkohwyvztx/oQWWgld2iad25TfUdi6wvhhaDPIQjHU/pyvlKgXFw1kX31SQK2Nq9MH+vRDWB0ZLy8fYw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4.0.0"
+ "eslint": ">=8.40.0"
}
},
"node_modules/eslint-scope": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
- "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.3.0.tgz",
+ "integrity": "sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
@@ -6545,25 +7128,32 @@
"estraverse": "^5.2.0"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-visitor-keys": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
- "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+ "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
"dev": true,
"license": "Apache-2.0",
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/eslint/node_modules/@types/estree": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/eslint/node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -6613,27 +7203,27 @@
}
},
"node_modules/espree": {
- "version": "9.6.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
- "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
+ "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "acorn": "^8.9.0",
+ "acorn": "^8.14.0",
"acorn-jsx": "^5.3.2",
- "eslint-visitor-keys": "^3.4.1"
+ "eslint-visitor-keys": "^4.2.0"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/esquery": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
- "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+ "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -6699,30 +7289,22 @@
"node": ">=0.8.x"
}
},
- "node_modules/execa": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
- "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "node_modules/expect-type": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.0.tgz",
+ "integrity": "sha512-80F22aiJ3GLyVnS/B3HzgR6RelZVumzj9jkL0Rhz4h0xYbNW9PjlQz5h3J/SShErbXBc295vseR4/MIbVmUbeA==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "cross-spawn": "^7.0.3",
- "get-stream": "^8.0.1",
- "human-signals": "^5.0.0",
- "is-stream": "^3.0.0",
- "merge-stream": "^2.0.0",
- "npm-run-path": "^5.1.0",
- "onetime": "^6.0.0",
- "signal-exit": "^4.1.0",
- "strip-final-newline": "^3.0.0"
- },
+ "license": "Apache-2.0",
"engines": {
- "node": ">=16.17"
- },
- "funding": {
- "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ "node": ">=12.0.0"
}
},
+ "node_modules/exsolve": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.4.tgz",
+ "integrity": "sha512-xsZH6PXaER4XoV+NiT7JHp1bJodJVT+cxeSH1G0f0tlT0lJqYuHUP3bUx2HtfTDvOagMINYp8rsqusxud3RXhw==",
+ "license": "MIT"
+ },
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -6737,16 +7319,16 @@
"license": "Apache-2.0"
},
"node_modules/fast-glob": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+ "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
"@nodelib/fs.walk": "^1.2.3",
"glob-parent": "^5.1.2",
"merge2": "^1.3.0",
- "micromatch": "^4.0.4"
+ "micromatch": "^4.0.8"
},
"engines": {
"node": ">=8.6.0"
@@ -6768,6 +7350,7 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
"license": "MIT"
},
"node_modules/fast-levenshtein": {
@@ -6784,6 +7367,22 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/fast-uri": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz",
+ "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/fastest-levenshtein": {
"version": "1.0.16",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
@@ -6794,9 +7393,9 @@
}
},
"node_modules/fastq": {
- "version": "1.17.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
- "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
+ "version": "1.19.1",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
+ "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
"license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
@@ -6811,17 +7410,37 @@
"node-fetch": "~2.6.1"
}
},
+ "node_modules/fetch-ponyfill/node_modules/node-fetch": {
+ "version": "2.6.13",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz",
+ "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==",
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
"node_modules/file-entry-cache": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
- "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "flat-cache": "^3.0.4"
+ "flat-cache": "^4.0.0"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": ">=16.0.0"
}
},
"node_modules/fill-range": {
@@ -6853,6 +7472,19 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/find-up-simple": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz",
+ "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/flat": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
@@ -6863,44 +7495,49 @@
}
},
"node_modules/flat-cache": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
- "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
"dev": true,
"license": "MIT",
"dependencies": {
"flatted": "^3.2.9",
- "keyv": "^4.5.3",
- "rimraf": "^3.0.2"
+ "keyv": "^4.5.4"
},
"engines": {
- "node": "^10.12.0 || >=12.0.0"
+ "node": ">=16"
}
},
"node_modules/flatted": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
- "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+ "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
"dev": true,
"license": "ISC"
},
"node_modules/for-each": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
- "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz",
+ "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "is-callable": "^1.1.3"
+ "is-callable": "^1.2.7"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/foreground-child": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz",
- "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"license": "ISC",
"dependencies": {
- "cross-spawn": "^7.0.0",
+ "cross-spawn": "^7.0.6",
"signal-exit": "^4.0.1"
},
"engines": {
@@ -6929,6 +7566,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
+ "dev": true,
"license": "ISC"
},
"node_modules/fsevents": {
@@ -6955,16 +7593,18 @@
}
},
"node_modules/function.prototype.name": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz",
- "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==",
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz",
+ "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "define-properties": "^1.2.0",
- "es-abstract": "^1.22.1",
- "functions-have-names": "^1.2.3"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "define-properties": "^1.2.1",
+ "functions-have-names": "^1.2.3",
+ "hasown": "^2.0.2",
+ "is-callable": "^1.2.7"
},
"engines": {
"node": ">= 0.4"
@@ -6973,6 +7613,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/functions-have-names": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz",
@@ -6994,9 +7641,9 @@
}
},
"node_modules/get-east-asian-width": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz",
- "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz",
+ "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==",
"license": "MIT",
"engines": {
"node": ">=18"
@@ -7005,28 +7652,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/get-func-name": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz",
- "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "*"
- }
- },
"node_modules/get-intrinsic": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
- "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"dev": true,
"license": "MIT",
"dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
- "has-proto": "^1.0.1",
- "has-symbols": "^1.0.3",
- "hasown": "^2.0.0"
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -7035,14 +7677,28 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/get-set-props": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz",
- "integrity": "sha512-7oKuKzAGKj0ag+eWZwcGw2fjiZ78tXnXQoBgY0aU7ZOxTu4bB7hSuQSDgtKy978EDH062P5FmD2EWiDpQS9K9Q==",
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.2.0.tgz",
+ "integrity": "sha512-YCmOj+4YAeEB5Dd9jfp6ETdejMet4zSxXjNkgaa4npBEKRI9uDOGB5MmAdAgi2OoFGAKshYhCbmLq2DS03CgVA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=18.0.0"
}
},
"node_modules/get-source": {
@@ -7056,42 +7712,16 @@
"source-map": "^0.6.1"
}
},
- "node_modules/get-stdin": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
- "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/get-stream": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
- "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/get-symbol-description": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz",
- "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz",
+ "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.5",
+ "call-bound": "^1.0.3",
"es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.4"
+ "get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
@@ -7101,9 +7731,9 @@
}
},
"node_modules/get-tsconfig": {
- "version": "4.7.5",
- "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.5.tgz",
- "integrity": "sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==",
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.0.tgz",
+ "integrity": "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==",
"license": "MIT",
"dependencies": {
"resolve-pkg-maps": "^1.0.0"
@@ -7117,6 +7747,7 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"deprecated": "Glob versions prior to v9 are no longer supported",
+ "dev": true,
"license": "ISC",
"dependencies": {
"fs.realpath": "^1.0.0",
@@ -7155,6 +7786,7 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
@@ -7165,6 +7797,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
@@ -7215,16 +7848,13 @@
}
},
"node_modules/globals": {
- "version": "13.24.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
- "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+ "version": "16.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-16.0.0.tgz",
+ "integrity": "sha512-iInW14XItCXET01CQFqudPOWP2jYMl7T+QRQT+UNcR/iQncN/F0UNpgd76iFkBPgNQb4+X3LV9tLJYzwh+Gl3A==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "type-fest": "^0.20.2"
- },
"engines": {
- "node": ">=8"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -7276,13 +7906,13 @@
"license": "MIT"
},
"node_modules/gopd": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
- "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "get-intrinsic": "^1.1.3"
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -7301,11 +7931,11 @@
"dev": true,
"license": "MIT"
},
- "node_modules/gsap": {
- "version": "3.12.5",
- "resolved": "https://registry.npmjs.org/gsap/-/gsap-3.12.5.tgz",
- "integrity": "sha512-srBfnk4n+Oe/ZnMIOXt3gT605BX9x5+rh/prT2F1SsNJsU1XuMiP0E2aptW481OnonOGACZWBqseH5Z7csHxhQ==",
- "license": "Standard 'no charge' license: https://gsap.com/standard-license. Club GSAP members get more: https://gsap.com/licensing/. Why GreenSock doesn't employ an MIT license: https://gsap.com/why-license/"
+ "node_modules/hachure-fill": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/hachure-fill/-/hachure-fill-0.5.2.tgz",
+ "integrity": "sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==",
+ "license": "MIT"
},
"node_modules/hammerjs": {
"version": "2.0.8",
@@ -7317,26 +7947,28 @@
}
},
"node_modules/happy-dom": {
- "version": "14.12.3",
- "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-14.12.3.tgz",
- "integrity": "sha512-vsYlEs3E9gLwA1Hp+w3qzu+RUDFf4VTT8cyKqVICoZ2k7WM++Qyd2LwzyTi5bqMJFiIC/vNpTDYuxdreENRK/g==",
+ "version": "17.4.4",
+ "resolved": "https://registry.npmjs.org/happy-dom/-/happy-dom-17.4.4.tgz",
+ "integrity": "sha512-/Pb0ctk3HTZ5xEL3BZ0hK1AqDSAUuRQitOmROPHhfUYEWpmTImwfD8vFDGADmMAX0JYgbcgxWoLFKtsWhcpuVA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "entities": "^4.5.0",
"webidl-conversions": "^7.0.0",
"whatwg-mimetype": "^3.0.0"
},
"engines": {
- "node": ">=16.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/has-bigints": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz",
- "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz",
+ "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==",
"dev": true,
"license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -7364,11 +7996,14 @@
}
},
"node_modules/has-proto": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
- "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz",
+ "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.0"
+ },
"engines": {
"node": ">= 0.4"
},
@@ -7377,9 +8012,9 @@
}
},
"node_modules/has-symbols": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
- "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7423,12 +8058,25 @@
"node": ">= 0.4"
}
},
- "node_modules/hosted-git-info": {
- "version": "2.8.9",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
- "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
+ "node_modules/hookified": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.8.1.tgz",
+ "integrity": "sha512-GrO2l93P8xCWBSTBX9l2BxI78VU/MAAYag+pG8curS3aBGy0++ZlxrQ7PdUOUVMbn5BwkGb6+eRrnf43ipnFEA==",
"dev": true,
- "license": "ISC"
+ "license": "MIT"
+ },
+ "node_modules/hosted-git-info": {
+ "version": "6.1.3",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-6.1.3.tgz",
+ "integrity": "sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^7.5.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
},
"node_modules/hpagent": {
"version": "1.2.0",
@@ -7486,16 +8134,6 @@
"integrity": "sha512-VZAohXyF7xPGS52IM8d1T1283y+X4D+Owf3qY1NZ9RuBypyu9l8cGsxUMAG5fEAb/DhT7rDoJ9Hpu5/HxFD3cw==",
"license": "0BSD"
},
- "node_modules/human-signals": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
- "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
- "dev": true,
- "license": "Apache-2.0",
- "engines": {
- "node": ">=16.17.0"
- }
- },
"node_modules/iconv-lite": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
@@ -7547,9 +8185,9 @@
"license": "BSD-3-Clause"
},
"node_modules/ignore": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
- "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -7568,9 +8206,9 @@
}
},
"node_modules/import-fresh": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
- "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
@@ -7584,9 +8222,9 @@
}
},
"node_modules/import-local": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz",
- "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz",
+ "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==",
"license": "MIT",
"dependencies": {
"pkg-dir": "^4.2.0",
@@ -7613,13 +8251,29 @@
}
},
"node_modules/indent-string": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
- "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
+ "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=8"
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/index-to-position": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.0.0.tgz",
+ "integrity": "sha512-sCO7uaLVhRJ25vz1o8s9IFM3nVS4DkuQnyjMwiQPKvQuBYBDmb8H7zx8ki7nVh4HJQOdVWebyvLE0qt+clruxA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/inflight": {
@@ -7627,6 +8281,7 @@
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
+ "dev": true,
"license": "ISC",
"dependencies": {
"once": "^1.3.0",
@@ -7637,6 +8292,7 @@
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/ini": {
@@ -7647,15 +8303,15 @@
"license": "ISC"
},
"node_modules/internal-slot": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz",
- "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz",
+ "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==",
"dev": true,
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
- "hasown": "^2.0.0",
- "side-channel": "^1.0.4"
+ "hasown": "^2.0.2",
+ "side-channel": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -7676,32 +8332,42 @@
"node": ">=10.13.0"
}
},
- "node_modules/is-arguments": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
- "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
+ "node_modules/is-alphabetical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz",
+ "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/is-alphanumerical": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz",
+ "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
+ "is-alphabetical": "^2.0.0",
+ "is-decimal": "^2.0.0"
},
"funding": {
- "url": "https://github.com/sponsors/ljharb"
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
}
},
"node_modules/is-array-buffer": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz",
- "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz",
+ "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "get-intrinsic": "^1.2.1"
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
@@ -7717,13 +8383,17 @@
"license": "MIT"
},
"node_modules/is-async-function": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz",
- "integrity": "sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz",
+ "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "async-function": "^1.0.0",
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.1",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -7733,13 +8403,16 @@
}
},
"node_modules/is-bigint": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
- "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz",
+ "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "has-bigints": "^1.0.1"
+ "has-bigints": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -7758,14 +8431,14 @@
}
},
"node_modules/is-boolean-object": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz",
- "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz",
+ "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -7775,21 +8448,44 @@
}
},
"node_modules/is-builtin-module": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
- "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-4.0.0.tgz",
+ "integrity": "sha512-rWP3AMAalQSesXO8gleROyL2iKU73SX5Er66losQn9rWOWL4Gef0a/xOEOVqjWGMuR2vHG3FJ8UUmT700O8oFg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "builtin-modules": "^3.3.0"
+ "builtin-modules": "^4.0.0"
},
"engines": {
- "node": ">=6"
+ "node": ">=18.20"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/is-builtin-module/node_modules/builtin-modules": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-4.0.0.tgz",
+ "integrity": "sha512-p1n8zyCkt1BVrKNFymOHjcDSAl7oq/gUvfgULv2EblgpPVQlQr9yHnWjg9IJ2MhfwPqiYqMMrr01OY7yQoK2yA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-bun-module": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz",
+ "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.6.3"
+ }
+ },
"node_modules/is-callable": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
@@ -7804,9 +8500,9 @@
}
},
"node_modules/is-core-module": {
- "version": "2.14.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.14.0.tgz",
- "integrity": "sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A==",
+ "version": "2.16.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz",
+ "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==",
"license": "MIT",
"dependencies": {
"hasown": "^2.0.2"
@@ -7819,12 +8515,14 @@
}
},
"node_modules/is-data-view": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz",
- "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz",
+ "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==",
"dev": true,
"license": "MIT",
"dependencies": {
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
"is-typed-array": "^1.1.13"
},
"engines": {
@@ -7835,13 +8533,14 @@
}
},
"node_modules/is-date-object": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz",
- "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz",
+ "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.2",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -7850,6 +8549,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-decimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz",
+ "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
@@ -7860,13 +8570,16 @@
}
},
"node_modules/is-finalizationregistry": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz",
- "integrity": "sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz",
+ "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2"
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -7882,13 +8595,16 @@
}
},
"node_modules/is-generator-function": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
- "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz",
+ "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.3",
+ "get-proto": "^1.0.0",
+ "has-tostringtag": "^1.0.2",
+ "safe-regex-test": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -7898,14 +8614,17 @@
}
},
"node_modules/is-get-set-prop": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz",
- "integrity": "sha512-DvAYZ1ZgGUz4lzxKMPYlt08qAUqyG9ckSg2pIjfvcQ7+pkVNUHk8yVLXOnCLe5WKXhLop8oorWFBJHpwWQpszQ==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-2.0.0.tgz",
+ "integrity": "sha512-C32bqXfHJfRwa0U5UIMqSGziZhALszXDJZ8n8mz8WZ6c6V7oYGHEWwJvftliBswypY3P3EQqdY5lpDSEKvTS1Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "get-set-props": "^0.1.0",
- "lowercase-keys": "^1.0.0"
+ "get-set-props": "^0.2.0",
+ "lowercase-keys": "^3.0.0"
+ },
+ "engines": {
+ "node": "> 18.0.0"
}
},
"node_modules/is-glob": {
@@ -7920,14 +8639,28 @@
"node": ">=0.10.0"
}
},
+ "node_modules/is-hexadecimal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz",
+ "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/is-js-type": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz",
- "integrity": "sha512-Aj13l47+uyTjlQNHtXBV8Cji3jb037vxwMWCgopRR8h6xocgBGW3qG8qGlIOEmbXQtkKShKuBM9e8AA1OeQ+xw==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-3.0.0.tgz",
+ "integrity": "sha512-IbPf3g3vxm1D902xaBaYp2TUHiXZWwWRu5bM9hgKN9oAQcFaKALV6Gd13PGhXjKE5u2n8s1PhLhdke/E1fchxQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "js-types": "^1.0.0"
+ "js-types": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/is-map": {
@@ -7943,19 +8676,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-negative-zero": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz",
- "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -7966,13 +8686,14 @@
}
},
"node_modules/is-number-object": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz",
- "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz",
+ "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -7982,24 +8703,17 @@
}
},
"node_modules/is-obj-prop": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz",
- "integrity": "sha512-5Idb61slRlJlsAzi0Wsfwbp+zZY+9LXKUAZpvT/1ySw+NxKLRWfa0Bzj+wXI3fX5O9hiddm5c3DAaRSNP/yl2w==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-2.0.0.tgz",
+ "integrity": "sha512-2/VFrbzXSZVJIscazpxoB+pOQx2jBOAAL9Gui4cRKxflznUNBpsr8IDvBA4UGol3e40sltLNiY3qnZv/7qSUxA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "lowercase-keys": "^1.0.0",
- "obj-props": "^1.0.0"
- }
- },
- "node_modules/is-path-inside": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
- "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
- "dev": true,
- "license": "MIT",
+ "lowercase-keys": "^3.0.0",
+ "obj-props": "^2.0.0"
+ },
"engines": {
- "node": ">=8"
+ "node": ">=18.0.0"
}
},
"node_modules/is-plain-object": {
@@ -8020,14 +8734,17 @@
"license": "MIT"
},
"node_modules/is-proto-prop": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz",
- "integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-3.0.1.tgz",
+ "integrity": "sha512-S8xSxNMGJO4eZD86kO46zrq2gLIhA+rN9443lQEvt8Mz/l8cxk72p/AWFmofY6uL9g9ILD6cXW6j8QQj4F3Hcw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "lowercase-keys": "^1.0.0",
- "proto-props": "^2.0.0"
+ "lowercase-keys": "^3.0.0",
+ "prototype-properties": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18.0.0"
}
},
"node_modules/is-reference": {
@@ -8041,14 +8758,16 @@
}
},
"node_modules/is-regex": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
- "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz",
+ "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.2",
+ "gopd": "^1.2.0",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -8071,13 +8790,13 @@
}
},
"node_modules/is-shared-array-buffer": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz",
- "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz",
+ "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7"
+ "call-bound": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
@@ -8086,27 +8805,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/is-stream": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
- "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/is-string": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
- "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz",
+ "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "has-tostringtag": "^1.0.0"
+ "call-bound": "^1.0.3",
+ "has-tostringtag": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -8116,13 +8823,15 @@
}
},
"node_modules/is-symbol": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz",
- "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz",
+ "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==",
"dev": true,
"license": "MIT",
"dependencies": {
- "has-symbols": "^1.0.2"
+ "call-bound": "^1.0.2",
+ "has-symbols": "^1.1.0",
+ "safe-regex-test": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
@@ -8132,13 +8841,13 @@
}
},
"node_modules/is-typed-array": {
- "version": "1.1.13",
- "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz",
- "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==",
+ "version": "1.1.15",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz",
+ "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "which-typed-array": "^1.1.14"
+ "which-typed-array": "^1.1.16"
},
"engines": {
"node": ">= 0.4"
@@ -8171,27 +8880,30 @@
}
},
"node_modules/is-weakref": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
- "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz",
+ "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2"
+ "call-bound": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-weakset": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.3.tgz",
- "integrity": "sha512-LvIm3/KWzS9oRFHugab7d+M/GcBXuXX5xZkzPmN+NxihdQlZUQ4dWuSV1xR/sq6upL1TJEDrfBgRepHFdBtSNQ==",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz",
+ "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
- "get-intrinsic": "^1.2.4"
+ "call-bound": "^1.0.3",
+ "get-intrinsic": "^1.2.6"
},
"engines": {
"node": ">= 0.4"
@@ -8248,9 +8960,9 @@
}
},
"node_modules/istanbul-lib-source-maps": {
- "version": "5.0.4",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.4.tgz",
- "integrity": "sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==",
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
+ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -8276,31 +8988,14 @@
"node": ">=8"
}
},
- "node_modules/iterator.prototype": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz",
- "integrity": "sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-properties": "^1.2.1",
- "get-intrinsic": "^1.2.1",
- "has-symbols": "^1.0.3",
- "reflect.getprototypeof": "^1.0.4",
- "set-function-name": "^2.0.1"
- }
- },
"node_modules/jackspeak": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz",
- "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==",
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
},
- "engines": {
- "node": ">=14"
- },
"funding": {
"url": "https://github.com/sponsors/isaacs"
},
@@ -8338,9 +9033,9 @@
}
},
"node_modules/jiti": {
- "version": "1.21.6",
- "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz",
- "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==",
+ "version": "1.21.7",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
+ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
@@ -8353,17 +9048,17 @@
"license": "MIT"
},
"node_modules/js-beautify": {
- "version": "1.15.1",
- "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.1.tgz",
- "integrity": "sha512-ESjNzSlt/sWE8sciZH8kBF8BPlwXPwhR6pWKAw8bw4Bwj+iZcnKW6ONWUutJ7eObuBZQpiIb8S7OYspWrKt7rA==",
+ "version": "1.15.4",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz",
+ "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==",
"dev": true,
"license": "MIT",
"dependencies": {
"config-chain": "^1.1.13",
"editorconfig": "^1.0.4",
- "glob": "^10.3.3",
+ "glob": "^10.4.2",
"js-cookie": "^3.0.5",
- "nopt": "^7.2.0"
+ "nopt": "^7.2.1"
},
"bin": {
"css-beautify": "js/bin/css-beautify.js",
@@ -8375,9 +9070,9 @@
}
},
"node_modules/js-beautify/node_modules/glob": {
- "version": "10.4.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
- "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -8391,8 +9086,21 @@
"bin": {
"glob": "dist/esm/bin.mjs"
},
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/js-beautify/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
"engines": {
- "node": ">=16 || 14 >=14.18"
+ "node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -8416,20 +9124,23 @@
"license": "MIT"
},
"node_modules/js-tokens": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.0.tgz",
- "integrity": "sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==",
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
"dev": true,
"license": "MIT"
},
"node_modules/js-types": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz",
- "integrity": "sha512-bfwqBW9cC/Lp7xcRpug7YrXm0IVw+T9e3g4mCYnv0Pjr3zIzU9PCQElYU9oSGAWzXlbdl9X5SAMPejO9sxkeUw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-types/-/js-types-4.0.0.tgz",
+ "integrity": "sha512-/c+n06zvqFQGxdz1BbElF7S3nEghjNchLN1TjQnk2j10HYDaUc57rcvl6BbnziTx8NQmrg0JOs/iwRpvcYaxjQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=18.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/js-yaml": {
@@ -8445,9 +9156,9 @@
}
},
"node_modules/jsdoc-type-pratt-parser": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz",
- "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.1.0.tgz",
+ "integrity": "sha512-Hicd6JK5Njt2QB6XYFS7ok9e37O8AYk3jTcppG4YVQnYjOemymvTcmc7OWsmq/Qqj5TdRFO5/x/tIPmBeRtGHg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8455,9 +9166,9 @@
}
},
"node_modules/jsep": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.3.8.tgz",
- "integrity": "sha512-qofGylTGgYj9gZFsHuyWAN4jr35eJ66qJCK4eKDnldohuUoQFbU3iZn2zjvEbd9wOAhP9Wx5DsAAduTyE1PSWQ==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz",
+ "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -8465,9 +9176,9 @@
}
},
"node_modules/jsesc": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
- "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"dev": true,
"license": "MIT",
"bin": {
@@ -8536,13 +9247,22 @@
}
},
"node_modules/jsonpath-plus": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-7.1.0.tgz",
- "integrity": "sha512-gTaNRsPWO/K2KY6MrqaUFClF9kmuM6MFH5Dhg1VYDODgFbByw1yb7xu3hrViE/sz+dGOeMWgCzwUwQtAnCTE9g==",
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz",
+ "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@jsep-plugin/assignment": "^1.3.0",
+ "@jsep-plugin/regex": "^1.0.4",
+ "jsep": "^1.4.0"
+ },
+ "bin": {
+ "jsonpath": "bin/jsonpath-cli.js",
+ "jsonpath-plus": "bin/jsonpath-cli.js"
+ },
"engines": {
- "node": ">=12.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/jsonpointer": {
@@ -8578,9 +9298,9 @@
"license": "MIT"
},
"node_modules/katex": {
- "version": "0.16.10",
- "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz",
- "integrity": "sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA==",
+ "version": "0.16.21",
+ "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.21.tgz",
+ "integrity": "sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==",
"funding": [
"https://opencollective.com/katex",
"https://github.com/sponsors/katex"
@@ -8626,40 +9346,33 @@
"node": ">=0.10.0"
}
},
- "node_modules/kleur": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz",
- "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==",
- "license": "MIT",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/known-css-properties": {
- "version": "0.31.0",
- "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.31.0.tgz",
- "integrity": "sha512-sBPIUGTNF0czz0mwGGUoKKJC8Q7On1GPbCSFPfyEsfHb2DyBG0Y4QtV+EVWpINSaiGKZblDNuF5AezxSgOhesQ==",
+ "version": "0.35.0",
+ "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.35.0.tgz",
+ "integrity": "sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==",
"dev": true,
"license": "MIT"
},
- "node_modules/language-subtag-registry": {
- "version": "0.3.23",
- "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz",
- "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==",
- "dev": true,
- "license": "CC0-1.0"
+ "node_modules/kolorist": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
+ "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
+ "license": "MIT"
},
- "node_modules/language-tags": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz",
- "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==",
- "dev": true,
+ "node_modules/langium": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/langium/-/langium-3.0.0.tgz",
+ "integrity": "sha512-+Ez9EoiByeoTu/2BXmEaZ06iPNXM6thWJp02KfBO/raSMyCJ4jw7AkWWa+zBCTm0+Tw1Fj9FOxdqSskyN5nAwg==",
"license": "MIT",
"dependencies": {
- "language-subtag-registry": "^0.3.20"
+ "chevrotain": "~11.0.3",
+ "chevrotain-allstar": "~0.3.0",
+ "vscode-languageserver": "~9.0.1",
+ "vscode-languageserver-textdocument": "~1.0.11",
+ "vscode-uri": "~3.0.8"
},
"engines": {
- "node": ">=0.10"
+ "node": ">=16.0.0"
}
},
"node_modules/layout-base": {
@@ -8692,78 +9405,43 @@
"node": ">= 0.8.0"
}
},
- "node_modules/license-checker-webpack-plugin": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/license-checker-webpack-plugin/-/license-checker-webpack-plugin-0.2.1.tgz",
- "integrity": "sha512-rX8B+mH6fk1vxbnIu/UztqTEonQw95xwOkoRjX3TSrRZA/pbG9CWa3wnSo89KY/ej379JQoq050fsuthy6AU+A==",
- "license": "MIT",
+ "node_modules/license-checker-rseidelsohn": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/license-checker-rseidelsohn/-/license-checker-rseidelsohn-4.4.2.tgz",
+ "integrity": "sha512-Sf8WaJhd2vELvCne+frS9AXqnY/vv591s2/nZcJDwTnoNgltG4mAmoenffVb8L2YPRYbxARLyrHJBC38AVfpuA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
"dependencies": {
- "glob": "^7.1.6",
- "lodash.template": "^4.5.0",
- "minimatch": "^3.0.4",
- "semver": "^6.3.0",
- "spdx-expression-validate": "^2.0.0",
- "spdx-satisfies": "^5.0.0",
- "superstruct": "^0.10.12",
- "webpack-sources": "^1.4.3",
- "wrap-ansi": "^6.1.0"
+ "chalk": "4.1.2",
+ "debug": "^4.3.4",
+ "lodash.clonedeep": "^4.5.0",
+ "mkdirp": "^1.0.4",
+ "nopt": "^7.2.0",
+ "read-installed-packages": "^2.0.1",
+ "semver": "^7.3.5",
+ "spdx-correct": "^3.1.1",
+ "spdx-expression-parse": "^3.0.1",
+ "spdx-satisfies": "^5.0.1",
+ "treeify": "^1.1.0"
},
- "peerDependencies": {
- "webpack": "^4.4.0 || ^5.4.0"
- }
- },
- "node_modules/license-checker-webpack-plugin/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/license-checker-webpack-plugin/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
- "license": "ISC",
- "dependencies": {
- "brace-expansion": "^1.1.7"
- },
- "engines": {
- "node": "*"
- }
- },
- "node_modules/license-checker-webpack-plugin/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "license": "ISC",
"bin": {
- "semver": "bin/semver.js"
- }
- },
- "node_modules/license-checker-webpack-plugin/node_modules/wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "license": "MIT",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
+ "license-checker-rseidelsohn": "bin/license-checker-rseidelsohn.js"
},
"engines": {
- "node": ">=8"
+ "node": ">=18",
+ "npm": ">=8"
}
},
"node_modules/lilconfig": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
- "integrity": "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
+ "integrity": "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==",
"license": "MIT",
"engines": {
- "node": ">=10"
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antonk52"
}
},
"node_modules/lines-and-columns": {
@@ -8806,14 +9484,14 @@
}
},
"node_modules/local-pkg": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz",
- "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==",
- "dev": true,
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz",
+ "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==",
"license": "MIT",
"dependencies": {
- "mlly": "^1.4.2",
- "pkg-types": "^1.0.3"
+ "mlly": "^1.7.4",
+ "pkg-types": "^2.0.1",
+ "quansync": "^0.2.8"
},
"engines": {
"node": ">=14"
@@ -8851,23 +9529,10 @@
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
"license": "MIT"
},
- "node_modules/lodash._reinterpolate": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
- "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==",
- "license": "MIT"
- },
- "node_modules/lodash.camelcase": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
- "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/lodash.kebabcase": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
- "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==",
+ "node_modules/lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
"dev": true,
"license": "MIT"
},
@@ -8878,13 +9543,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/lodash.snakecase": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
- "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/lodash.sortedlastindex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/lodash.sortedlastindex/-/lodash.sortedlastindex-4.1.0.tgz",
@@ -8892,25 +9550,6 @@
"dev": true,
"license": "MIT"
},
- "node_modules/lodash.template": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
- "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==",
- "license": "MIT",
- "dependencies": {
- "lodash._reinterpolate": "^3.0.0",
- "lodash.templatesettings": "^4.0.0"
- }
- },
- "node_modules/lodash.templatesettings": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz",
- "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==",
- "license": "MIT",
- "dependencies": {
- "lodash._reinterpolate": "^3.0.0"
- }
- },
"node_modules/lodash.topath": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz",
@@ -8925,40 +9564,34 @@
"dev": true,
"license": "MIT"
},
- "node_modules/lodash.upperfirst": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
- "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==",
+ "node_modules/loupe": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz",
+ "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==",
"dev": true,
"license": "MIT"
},
- "node_modules/loupe": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz",
- "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "get-func-name": "^2.0.1"
- }
- },
"node_modules/lowercase-keys": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
- "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz",
+ "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=0.10.0"
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lru-cache": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz",
- "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==",
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "dev": true,
"license": "ISC",
"engines": {
- "node": "14 || >=16.14"
+ "node": ">=12"
}
},
"node_modules/magic-string": {
@@ -8972,14 +9605,14 @@
}
},
"node_modules/magicast": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz",
- "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
+ "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.24.4",
- "@babel/types": "^7.24.0",
+ "@babel/parser": "^7.25.4",
+ "@babel/types": "^7.25.4",
"source-map-js": "^1.2.0"
}
},
@@ -8999,6 +9632,13 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/markdown-escape": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/markdown-escape/-/markdown-escape-2.0.0.tgz",
+ "integrity": "sha512-Trz4v0+XWlwy68LJIyw3bLbsJiC8XAbRCKF9DbEtZjyndKOGVx6n+wNB0VfoRmY2LKboQLeniap3xrb6LGSJ8A==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/markdown-it": {
"version": "14.1.0",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
@@ -9018,14 +9658,21 @@
}
},
"node_modules/markdownlint": {
- "version": "0.34.0",
- "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.34.0.tgz",
- "integrity": "sha512-qwGyuyKwjkEMOJ10XN6OTKNOVYvOIi35RNvDLNxTof5s8UmyGHlCdpngRHoRGNvQVGuxO3BJ7uNSgdeX166WXw==",
+ "version": "0.37.4",
+ "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.37.4.tgz",
+ "integrity": "sha512-u00joA/syf3VhWh6/ybVFkib5Zpj2e5KB/cfCei8fkSRuums6nyisTWGqjTWIOFoFwuXoTBQQiqlB4qFKp8ncQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"markdown-it": "14.1.0",
- "markdownlint-micromark": "0.1.9"
+ "micromark": "4.0.1",
+ "micromark-core-commonmark": "2.0.2",
+ "micromark-extension-directive": "3.0.2",
+ "micromark-extension-gfm-autolink-literal": "2.1.0",
+ "micromark-extension-gfm-footnote": "2.1.0",
+ "micromark-extension-gfm-table": "2.1.0",
+ "micromark-extension-math": "3.1.0",
+ "micromark-util-types": "2.0.1"
},
"engines": {
"node": ">=18"
@@ -9035,23 +9682,22 @@
}
},
"node_modules/markdownlint-cli": {
- "version": "0.41.0",
- "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.41.0.tgz",
- "integrity": "sha512-kp29tKrMKdn+xonfefjp3a/MsNzAd9c5ke0ydMEI9PR98bOjzglYN4nfMSaIs69msUf1DNkgevAIAPtK2SeX0Q==",
+ "version": "0.44.0",
+ "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.44.0.tgz",
+ "integrity": "sha512-ZJTAONlvF9NkrIBltCdW15DxN9UTbPiKMEqAh2EU2gwIFlrCMavyCEPPO121cqfYOrLUJWW8/XKWongstmmTeQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "commander": "~12.1.0",
- "get-stdin": "~9.0.0",
- "glob": "~10.4.1",
- "ignore": "~5.3.1",
- "js-yaml": "^4.1.0",
- "jsonc-parser": "~3.2.1",
- "jsonpointer": "5.0.1",
- "markdownlint": "~0.34.0",
- "minimatch": "~9.0.4",
+ "commander": "~13.1.0",
+ "glob": "~10.4.5",
+ "ignore": "~7.0.3",
+ "js-yaml": "~4.1.0",
+ "jsonc-parser": "~3.3.1",
+ "jsonpointer": "~5.0.1",
+ "markdownlint": "~0.37.4",
+ "minimatch": "~9.0.5",
"run-con": "~1.3.2",
- "smol-toml": "~1.2.0"
+ "smol-toml": "~1.3.1"
},
"bin": {
"markdownlint": "markdownlint.js"
@@ -9061,9 +9707,9 @@
}
},
"node_modules/markdownlint-cli/node_modules/commander": {
- "version": "12.1.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
- "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+ "version": "13.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz",
+ "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -9071,9 +9717,9 @@
}
},
"node_modules/markdownlint-cli/node_modules/glob": {
- "version": "10.4.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
- "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"license": "ISC",
"dependencies": {
@@ -9087,31 +9733,41 @@
"bin": {
"glob": "dist/esm/bin.mjs"
},
- "engines": {
- "node": ">=16 || 14 >=14.18"
- },
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/markdownlint-cli/node_modules/jsonc-parser": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz",
- "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==",
- "dev": true,
- "license": "MIT"
- },
- "node_modules/markdownlint-micromark": {
- "version": "0.1.9",
- "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.9.tgz",
- "integrity": "sha512-5hVs/DzAFa8XqYosbEAEg6ok6MF2smDj89ztn9pKkCtdKHVdPQuGMH7frFfYL9mLkvfFe4pTyAMffLbjf3/EyA==",
+ "node_modules/markdownlint-cli/node_modules/ignore": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz",
+ "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=18"
+ "node": ">= 4"
+ }
+ },
+ "node_modules/markdownlint-cli/node_modules/jsonc-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+ "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/markdownlint-cli/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
},
"funding": {
- "url": "https://github.com/sponsors/DavidAnson"
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/marked": {
@@ -9126,6 +9782,16 @@
"node": ">= 12"
}
},
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/mathml-tag-names": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz",
@@ -9137,47 +9803,10 @@
"url": "https://github.com/sponsors/wooorm"
}
},
- "node_modules/mdast-util-from-markdown": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz",
- "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==",
- "license": "MIT",
- "dependencies": {
- "@types/mdast": "^3.0.0",
- "@types/unist": "^2.0.0",
- "decode-named-character-reference": "^1.0.0",
- "mdast-util-to-string": "^3.1.0",
- "micromark": "^3.0.0",
- "micromark-util-decode-numeric-character-reference": "^1.0.0",
- "micromark-util-decode-string": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "unist-util-stringify-position": "^3.0.0",
- "uvu": "^0.5.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
- "node_modules/mdast-util-to-string": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz",
- "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==",
- "license": "MIT",
- "dependencies": {
- "@types/mdast": "^3.0.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
- }
- },
"node_modules/mdn-data": {
- "version": "2.0.30",
- "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
- "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
+ "version": "2.12.2",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz",
+ "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==",
"dev": true,
"license": "CC0-1.0"
},
@@ -9217,37 +9846,56 @@
}
},
"node_modules/mermaid": {
- "version": "10.9.1",
- "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-10.9.1.tgz",
- "integrity": "sha512-Mx45Obds5W1UkW1nv/7dHRsbfMM1aOKA2+Pxs/IGHNonygDHwmng8xTHyS9z4KWVi0rbko8gjiBmuwwXQ7tiNA==",
+ "version": "11.5.0",
+ "resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.5.0.tgz",
+ "integrity": "sha512-IYhyukID3zzDj1EihKiN1lp+PXNImoJ3Iyz73qeDAgnus4BNGsJV1n471P4PyeGxPVONerZxignwGxGTSwZnlg==",
"license": "MIT",
"dependencies": {
- "@braintree/sanitize-url": "^6.0.1",
- "@types/d3-scale": "^4.0.3",
- "@types/d3-scale-chromatic": "^3.0.0",
- "cytoscape": "^3.28.1",
+ "@braintree/sanitize-url": "^7.0.4",
+ "@iconify/utils": "^2.1.33",
+ "@mermaid-js/parser": "^0.3.0",
+ "@types/d3": "^7.4.3",
+ "cytoscape": "^3.29.3",
"cytoscape-cose-bilkent": "^4.1.0",
- "d3": "^7.4.0",
+ "cytoscape-fcose": "^2.2.0",
+ "d3": "^7.9.0",
"d3-sankey": "^0.12.3",
- "dagre-d3-es": "7.0.10",
- "dayjs": "^1.11.7",
- "dompurify": "^3.0.5",
- "elkjs": "^0.9.0",
+ "dagre-d3-es": "7.0.11",
+ "dayjs": "^1.11.13",
+ "dompurify": "^3.2.4",
"katex": "^0.16.9",
- "khroma": "^2.0.0",
+ "khroma": "^2.1.0",
"lodash-es": "^4.17.21",
- "mdast-util-from-markdown": "^1.3.0",
- "non-layered-tidy-tree-layout": "^2.0.2",
- "stylis": "^4.1.3",
+ "marked": "^15.0.7",
+ "roughjs": "^4.6.6",
+ "stylis": "^4.3.6",
"ts-dedent": "^2.2.0",
- "uuid": "^9.0.0",
- "web-worker": "^1.2.0"
+ "uuid": "^11.1.0"
+ }
+ },
+ "node_modules/mermaid/node_modules/dayjs": {
+ "version": "1.11.13",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
+ "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==",
+ "license": "MIT"
+ },
+ "node_modules/mermaid/node_modules/marked": {
+ "version": "15.0.7",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-15.0.7.tgz",
+ "integrity": "sha512-dgLIeKGLx5FwziAnsk4ONoGwHwGPJzselimvlVskE9XLN4Orv9u2VA3GWw/lYUqjfA0rUT/6fqKwfZJapP9BEg==",
+ "license": "MIT",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 18"
}
},
"node_modules/micromark": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz",
- "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.1.tgz",
+ "integrity": "sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9263,26 +9911,27 @@
"@types/debug": "^4.0.0",
"debug": "^4.0.0",
"decode-named-character-reference": "^1.0.0",
- "micromark-core-commonmark": "^1.0.1",
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-combine-extensions": "^1.0.0",
- "micromark-util-decode-numeric-character-reference": "^1.0.0",
- "micromark-util-encode": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-resolve-all": "^1.0.0",
- "micromark-util-sanitize-uri": "^1.0.0",
- "micromark-util-subtokenize": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.1",
- "uvu": "^0.5.0"
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-combine-extensions": "^2.0.0",
+ "micromark-util-decode-numeric-character-reference": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-core-commonmark": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz",
- "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.2.tgz",
+ "integrity": "sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9296,27 +9945,124 @@
"license": "MIT",
"dependencies": {
"decode-named-character-reference": "^1.0.0",
- "micromark-factory-destination": "^1.0.0",
- "micromark-factory-label": "^1.0.0",
- "micromark-factory-space": "^1.0.0",
- "micromark-factory-title": "^1.0.0",
- "micromark-factory-whitespace": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-classify-character": "^1.0.0",
- "micromark-util-html-tag-name": "^1.0.0",
- "micromark-util-normalize-identifier": "^1.0.0",
- "micromark-util-resolve-all": "^1.0.0",
- "micromark-util-subtokenize": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.1",
- "uvu": "^0.5.0"
+ "devlop": "^1.0.0",
+ "micromark-factory-destination": "^2.0.0",
+ "micromark-factory-label": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-title": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-classify-character": "^2.0.0",
+ "micromark-util-html-tag-name": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-resolve-all": "^2.0.0",
+ "micromark-util-subtokenize": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ }
+ },
+ "node_modules/micromark-extension-directive": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz",
+ "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-factory-whitespace": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0",
+ "parse-entities": "^4.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-autolink-literal": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz",
+ "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-footnote": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz",
+ "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-core-commonmark": "^2.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-normalize-identifier": "^2.0.0",
+ "micromark-util-sanitize-uri": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-gfm-table": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz",
+ "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "devlop": "^1.0.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
+ }
+ },
+ "node_modules/micromark-extension-math": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz",
+ "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/katex": "^0.16.0",
+ "devlop": "^1.0.0",
+ "katex": "^0.16.0",
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/unified"
}
},
"node_modules/micromark-factory-destination": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz",
- "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz",
+ "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9329,15 +10075,16 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-factory-label": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz",
- "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz",
+ "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9350,16 +10097,17 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
+ "devlop": "^1.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-factory-space": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz",
- "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz",
+ "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9372,14 +10120,15 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-types": "^1.0.0"
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-factory-title": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz",
- "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz",
+ "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9392,16 +10141,17 @@
],
"license": "MIT",
"dependencies": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-factory-whitespace": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz",
- "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz",
+ "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9414,16 +10164,17 @@
],
"license": "MIT",
"dependencies": {
- "micromark-factory-space": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
+ "micromark-factory-space": "^2.0.0",
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-character": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz",
- "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz",
+ "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9436,14 +10187,15 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-chunked": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz",
- "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz",
+ "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9456,13 +10208,14 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-symbol": "^1.0.0"
+ "micromark-util-symbol": "^2.0.0"
}
},
"node_modules/micromark-util-classify-character": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz",
- "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz",
+ "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9475,15 +10228,16 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0"
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-combine-extensions": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz",
- "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz",
+ "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9496,14 +10250,15 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-types": "^1.0.0"
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-decode-numeric-character-reference": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz",
- "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz",
+ "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9516,35 +10271,14 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-symbol": "^1.0.0"
- }
- },
- "node_modules/micromark-util-decode-string": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz",
- "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==",
- "funding": [
- {
- "type": "GitHub Sponsors",
- "url": "https://github.com/sponsors/unifiedjs"
- },
- {
- "type": "OpenCollective",
- "url": "https://opencollective.com/unified"
- }
- ],
- "license": "MIT",
- "dependencies": {
- "decode-named-character-reference": "^1.0.0",
- "micromark-util-character": "^1.0.0",
- "micromark-util-decode-numeric-character-reference": "^1.0.0",
- "micromark-util-symbol": "^1.0.0"
+ "micromark-util-symbol": "^2.0.0"
}
},
"node_modules/micromark-util-encode": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz",
- "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz",
+ "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9558,9 +10292,10 @@
"license": "MIT"
},
"node_modules/micromark-util-html-tag-name": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz",
- "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz",
+ "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9574,9 +10309,10 @@
"license": "MIT"
},
"node_modules/micromark-util-normalize-identifier": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz",
- "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz",
+ "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9589,13 +10325,14 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-symbol": "^1.0.0"
+ "micromark-util-symbol": "^2.0.0"
}
},
"node_modules/micromark-util-resolve-all": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz",
- "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz",
+ "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9608,13 +10345,14 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-types": "^1.0.0"
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-sanitize-uri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz",
- "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz",
+ "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9627,15 +10365,16 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-character": "^1.0.0",
- "micromark-util-encode": "^1.0.0",
- "micromark-util-symbol": "^1.0.0"
+ "micromark-util-character": "^2.0.0",
+ "micromark-util-encode": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0"
}
},
"node_modules/micromark-util-subtokenize": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz",
- "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz",
+ "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9648,16 +10387,17 @@
],
"license": "MIT",
"dependencies": {
- "micromark-util-chunked": "^1.0.0",
- "micromark-util-symbol": "^1.0.0",
- "micromark-util-types": "^1.0.0",
- "uvu": "^0.5.0"
+ "devlop": "^1.0.0",
+ "micromark-util-chunked": "^2.0.0",
+ "micromark-util-symbol": "^2.0.0",
+ "micromark-util-types": "^2.0.0"
}
},
"node_modules/micromark-util-symbol": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz",
- "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz",
+ "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9671,9 +10411,10 @@
"license": "MIT"
},
"node_modules/micromark-util-types": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz",
- "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz",
+ "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==",
+ "dev": true,
"funding": [
{
"type": "GitHub Sponsors",
@@ -9687,9 +10428,9 @@
"license": "MIT"
},
"node_modules/micromatch": {
- "version": "4.0.7",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz",
- "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==",
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
+ "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
@@ -9720,19 +10461,6 @@
"node": ">= 0.6"
}
},
- "node_modules/mimic-fn": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
- "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/min-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
@@ -9744,9 +10472,9 @@
}
},
"node_modules/mini-css-extract-plugin": {
- "version": "2.9.0",
- "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.0.tgz",
- "integrity": "sha512-Zs1YsZVfemekSZG+44vBsYTLQORkPMwnlv+aehcxK/NLKC+EGhDB39/YePYYqx/sTk6NnYpuqikhSn7+JIevTA==",
+ "version": "2.9.2",
+ "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz",
+ "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==",
"license": "MIT",
"dependencies": {
"schema-utils": "^4.0.0",
@@ -9764,15 +10492,15 @@
}
},
"node_modules/minimatch": {
- "version": "9.0.5",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
- "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
+ "integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
- "node": ">=16 || 14 >=14.17"
+ "node": "20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -9797,23 +10525,52 @@
"node": ">=16 || 14 >=14.17"
}
},
- "node_modules/mlly": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz",
- "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==",
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
"dev": true,
"license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mlly": {
+ "version": "1.7.4",
+ "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz",
+ "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==",
+ "license": "MIT",
"dependencies": {
- "acorn": "^8.11.3",
- "pathe": "^1.1.2",
- "pkg-types": "^1.1.1",
- "ufo": "^1.5.3"
+ "acorn": "^8.14.0",
+ "pathe": "^2.0.1",
+ "pkg-types": "^1.3.0",
+ "ufo": "^1.5.4"
+ }
+ },
+ "node_modules/mlly/node_modules/confbox": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
+ "integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
+ "license": "MIT"
+ },
+ "node_modules/mlly/node_modules/pkg-types": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
+ "integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
+ "license": "MIT",
+ "dependencies": {
+ "confbox": "^0.1.8",
+ "mlly": "^1.7.4",
+ "pathe": "^2.0.1"
}
},
"node_modules/monaco-editor": {
- "version": "0.47.0",
- "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.47.0.tgz",
- "integrity": "sha512-VabVvHvQ9QmMwXu4du008ZDuyLnHs9j7ThVFsiJoXSOQk18+LF89N4ADzPbFenm0W4V2bGHnFBztIRQTgBfxzw==",
+ "version": "0.52.2",
+ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.2.tgz",
+ "integrity": "sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==",
"license": "MIT"
},
"node_modules/monaco-editor-webpack-plugin": {
@@ -9835,19 +10592,10 @@
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==",
"license": "BSD-3-Clause"
},
- "node_modules/mri": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
- "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/mz": {
@@ -9862,9 +10610,9 @@
}
},
"node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
"funding": [
{
"type": "github",
@@ -9893,9 +10641,9 @@
"license": "MIT"
},
"node_modules/nimma": {
- "version": "0.2.2",
- "resolved": "https://registry.npmjs.org/nimma/-/nimma-0.2.2.tgz",
- "integrity": "sha512-V52MLl7BU+tH2Np9tDrIXK8bql3MVUadnMIl/0/oZSGC9keuro0O9UUv9QKp0aMvtN8HRew4G7byY7H4eWsxaQ==",
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/nimma/-/nimma-0.2.3.tgz",
+ "integrity": "sha512-1ZOI8J+1PKKGceo/5CT5GfQOG6H8I2BencSK06YarZ2wXwH37BSSUWldqJmMJYA5JfqDqffxDXynt6f11AyKcA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -9908,25 +10656,14 @@
"node": "^12.20 || >=14.13"
},
"optionalDependencies": {
- "jsonpath-plus": "^6.0.1",
+ "jsonpath-plus": "^6.0.1 || ^10.1.0",
"lodash.topath": "^4.5.2"
}
},
- "node_modules/nimma/node_modules/jsonpath-plus": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-6.0.1.tgz",
- "integrity": "sha512-EvGovdvau6FyLexFH2OeXfIITlgIbgZoAZe3usiySeaIDm5QS+A10DKNpaPBBqqRSZr2HN6HVNXxtwUAr2apEw==",
- "dev": true,
- "license": "MIT",
- "optional": true,
- "engines": {
- "node": ">=10.0.0"
- }
- },
"node_modules/node-fetch": {
- "version": "2.6.13",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.13.tgz",
- "integrity": "sha512-StxNAxh15zr77QvvkmveSQ8uCQ4+v5FkvNTj0OESmiHu+VRi/gXArXtkWMElOsOUNLtUEvI4yS+rdtOHZTwlQA==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"
@@ -9944,9 +10681,9 @@
}
},
"node_modules/node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
+ "version": "2.0.19",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
+ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"license": "MIT"
},
"node_modules/node-sarif-builder": {
@@ -9963,12 +10700,6 @@
"node": ">=14"
}
},
- "node_modules/non-layered-tidy-tree-layout": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz",
- "integrity": "sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==",
- "license": "MIT"
- },
"node_modules/nopt": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
@@ -9986,26 +10717,19 @@
}
},
"node_modules/normalize-package-data": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
- "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-5.0.0.tgz",
+ "integrity": "sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "hosted-git-info": "^2.1.4",
- "resolve": "^1.10.0",
- "semver": "2 || 3 || 4 || 5",
- "validate-npm-package-license": "^3.0.1"
- }
- },
- "node_modules/normalize-package-data/node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
- "dev": true,
- "license": "ISC",
- "bin": {
- "semver": "bin/semver"
+ "hosted-git-info": "^6.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/normalize-path": {
@@ -10017,33 +10741,14 @@
"node": ">=0.10.0"
}
},
- "node_modules/npm-run-path": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz",
- "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==",
+ "node_modules/npm-normalize-package-bin": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz",
+ "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==",
"dev": true,
- "license": "MIT",
- "dependencies": {
- "path-key": "^4.0.0"
- },
+ "license": "ISC",
"engines": {
- "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/npm-run-path/node_modules/path-key": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
- "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/nth-check": {
@@ -10060,13 +10765,13 @@
}
},
"node_modules/obj-props": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz",
- "integrity": "sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-2.0.0.tgz",
+ "integrity": "sha512-Q/uLAAfjdhrzQWN2czRNh3fDCgXjh7yRIkdHjDgIHTwpFP0BsshxTA3HRNffHR7Iw/XGTH30u8vdMXQ+079urA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=0.10.0"
+ "node": ">=18.0.0"
}
},
"node_modules/object-assign": {
@@ -10088,9 +10793,9 @@
}
},
"node_modules/object-inspect": {
- "version": "1.13.2",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
- "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
"dev": true,
"license": "MIT",
"engines": {
@@ -10100,23 +10805,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/object-is": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.6.tgz",
- "integrity": "sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
"node_modules/object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
@@ -10128,15 +10816,17 @@
}
},
"node_modules/object.assign": {
- "version": "4.1.5",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz",
- "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==",
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz",
+ "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.5",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
"define-properties": "^1.2.1",
- "has-symbols": "^1.0.3",
+ "es-object-atoms": "^1.0.0",
+ "has-symbols": "^1.1.0",
"object-keys": "^1.1.1"
},
"engines": {
@@ -10146,48 +10836,15 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/object.fromentries": {
- "version": "2.0.8",
- "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz",
- "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.2",
- "es-object-atoms": "^1.0.0"
- },
- "engines": {
- "node": ">= 0.4"
- },
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/object.groupby": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz",
- "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "call-bind": "^1.0.7",
- "define-properties": "^1.2.1",
- "es-abstract": "^1.23.2"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
"node_modules/object.values": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz",
- "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz",
+ "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.3",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
},
@@ -10202,27 +10859,12 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
"license": "ISC",
"dependencies": {
"wrappy": "1"
}
},
- "node_modules/onetime": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
- "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "mimic-fn": "^4.0.0"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/optionator": {
"version": "0.9.4",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
@@ -10241,6 +10883,47 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/own-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz",
+ "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-intrinsic": "^1.2.6",
+ "object-keys": "^1.1.1",
+ "safe-push-apply": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/oxc-resolver": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/oxc-resolver/-/oxc-resolver-5.0.1.tgz",
+ "integrity": "sha512-BbclyCSxgnqO5mo05RGcwp8rkVdZL7sf0ugEnFWK67DIBAMq5wR0/GQlQCdPiPkpiv9GESAVX2cbh1DMFux/TQ==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ },
+ "optionalDependencies": {
+ "@oxc-resolver/binding-darwin-arm64": "5.0.1",
+ "@oxc-resolver/binding-darwin-x64": "5.0.1",
+ "@oxc-resolver/binding-freebsd-x64": "5.0.1",
+ "@oxc-resolver/binding-linux-arm-gnueabihf": "5.0.1",
+ "@oxc-resolver/binding-linux-arm64-gnu": "5.0.1",
+ "@oxc-resolver/binding-linux-arm64-musl": "5.0.1",
+ "@oxc-resolver/binding-linux-x64-gnu": "5.0.1",
+ "@oxc-resolver/binding-linux-x64-musl": "5.0.1",
+ "@oxc-resolver/binding-wasm32-wasi": "5.0.1",
+ "@oxc-resolver/binding-win32-arm64-msvc": "5.0.1",
+ "@oxc-resolver/binding-win32-x64-msvc": "5.0.1"
+ }
+ },
"node_modules/p-limit": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
@@ -10283,11 +10966,20 @@
}
},
"node_modules/package-json-from-dist": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
- "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"license": "BlueOak-1.0.0"
},
+ "node_modules/package-manager-detector": {
+ "version": "0.2.11",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.11.tgz",
+ "integrity": "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ==",
+ "license": "MIT",
+ "dependencies": {
+ "quansync": "^0.2.7"
+ }
+ },
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@@ -10300,6 +10992,26 @@
"node": ">=6"
}
},
+ "node_modules/parse-entities": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz",
+ "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/unist": "^2.0.0",
+ "character-entities-legacy": "^3.0.0",
+ "character-reference-invalid": "^2.0.0",
+ "decode-named-character-reference": "^1.0.0",
+ "is-alphanumerical": "^2.0.0",
+ "is-decimal": "^2.0.0",
+ "is-hexadecimal": "^2.0.0"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
"node_modules/parse-json": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
@@ -10330,6 +11042,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/path-data-parser": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/path-data-parser/-/path-data-parser-0.1.0.tgz",
+ "integrity": "sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==",
+ "license": "MIT"
+ },
"node_modules/path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -10343,6 +11061,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@@ -10379,6 +11098,12 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
"node_modules/path-type": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
@@ -10390,20 +11115,19 @@
}
},
"node_modules/pathe": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz",
- "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==",
- "dev": true,
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"license": "MIT"
},
"node_modules/pathval": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz",
- "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
+ "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
"dev": true,
"license": "MIT",
"engines": {
- "node": "*"
+ "node": ">= 14.16"
}
},
"node_modules/pdfobject": {
@@ -10413,9 +11137,9 @@
"license": "MIT"
},
"node_modules/picocolors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
- "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"license": "ISC"
},
"node_modules/picomatch": {
@@ -10513,25 +11237,24 @@
}
},
"node_modules/pkg-types": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.1.1.tgz",
- "integrity": "sha512-ko14TjmDuQJ14zsotODv7dBlwxKhUKQEhuhmbqo1uCi9BB0Z2alo/wAXg6q1dTR5TyuqYyWhjtfe/Tsh+X28jQ==",
- "dev": true,
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.1.0.tgz",
+ "integrity": "sha512-wmJwA+8ihJixSoHKxZJRBQG1oY8Yr9pGLzRmSsNms0iNWyHHAlZCa7mmKiFR10YPZuz/2k169JiS/inOjBCZ2A==",
"license": "MIT",
"dependencies": {
- "confbox": "^0.1.7",
- "mlly": "^1.7.0",
- "pathe": "^1.1.2"
+ "confbox": "^0.2.1",
+ "exsolve": "^1.0.1",
+ "pathe": "^2.0.3"
}
},
"node_modules/playwright": {
- "version": "1.45.0",
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.0.tgz",
- "integrity": "sha512-4z3ac3plDfYzGB6r0Q3LF8POPR20Z8D0aXcxbJvmfMgSSq1hkcgvFRXJk9rUq5H/MJ0Ktal869hhOdI/zUTeLA==",
+ "version": "1.51.0",
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.0.tgz",
+ "integrity": "sha512-442pTfGM0xxfCYxuBa/Pu6B2OqxqqaYq39JS8QDMGThUvIOCd6s0ANDog3uwA0cHavVlnTQzGCN7Id2YekDSXA==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "playwright-core": "1.45.0"
+ "playwright-core": "1.51.0"
},
"bin": {
"playwright": "cli.js"
@@ -10544,9 +11267,9 @@
}
},
"node_modules/playwright-core": {
- "version": "1.45.0",
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.45.0.tgz",
- "integrity": "sha512-lZmHlFQ0VYSpAs43dRq1/nJ9G/6SiTI7VPqidld9TDefL9tX87bTKExWZZUF5PeRyqtXqd8fQi2qmfIedkwsNQ==",
+ "version": "1.51.0",
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.0.tgz",
+ "integrity": "sha512-x47yPE3Zwhlil7wlNU/iktF7t2r/URR3VLbH6EknJd/04Qc/PSJ0EY3CMXipmglLG+zyRxW6HNo2EGbKLHPWMg==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@@ -10566,6 +11289,22 @@
"node": ">=4"
}
},
+ "node_modules/points-on-curve": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/points-on-curve/-/points-on-curve-0.2.0.tgz",
+ "integrity": "sha512-0mYKnYYe9ZcqMCWhUjItv/oHjvgEsfKvnUTg8sAtnHr3GVy7rGkXCb6d5cSyqrWqL4k81b9CPg3urd+T7aop3A==",
+ "license": "MIT"
+ },
+ "node_modules/points-on-path": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/points-on-path/-/points-on-path-0.2.1.tgz",
+ "integrity": "sha512-25ClnWWuw7JbWZcgqY/gJ4FQWadKxGWk+3kR/7kD0tCaDtPPMj7oHu2ToLaVhfpnHrZzYby2w6tUA0eOIuUg8g==",
+ "license": "MIT",
+ "dependencies": {
+ "path-data-parser": "0.1.0",
+ "points-on-curve": "0.2.0"
+ }
+ },
"node_modules/pony-cause": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/pony-cause/-/pony-cause-1.1.1.tgz",
@@ -10577,9 +11316,9 @@
}
},
"node_modules/possible-typed-array-names": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz",
- "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz",
+ "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==",
"dev": true,
"license": "MIT",
"engines": {
@@ -10587,9 +11326,9 @@
}
},
"node_modules/postcss": {
- "version": "8.4.38",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
- "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
+ "version": "8.5.2",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz",
+ "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==",
"funding": [
{
"type": "opencollective",
@@ -10606,24 +11345,24 @@
],
"license": "MIT",
"dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.2.0"
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss-html": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.7.0.tgz",
- "integrity": "sha512-MfcMpSUIaR/nNgeVS8AyvyDugXlADjN9AcV7e5rDfrF1wduIAGSkL4q2+wgrZgA3sHVAHLDO9FuauHhZYW2nBw==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-1.8.0.tgz",
+ "integrity": "sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"htmlparser2": "^8.0.0",
"js-tokens": "^9.0.0",
- "postcss": "^8.4.0",
+ "postcss": "^8.5.0",
"postcss-safe-parser": "^6.0.0"
},
"engines": {
@@ -10701,18 +11440,6 @@
}
}
},
- "node_modules/postcss-load-config/node_modules/lilconfig": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz",
- "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==",
- "license": "MIT",
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
- }
- },
"node_modules/postcss-loader": {
"version": "8.1.1",
"resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz",
@@ -10757,13 +11484,13 @@
}
},
"node_modules/postcss-modules-local-by-default": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.5.tgz",
- "integrity": "sha512-6MieY7sIfTK0hYfafw1OMEG+2bg8Q1ocHCpoWLqOKj3JXlKu4G7btkmM/B7lFubYkYWmRSPLZi5chid63ZaZYw==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz",
+ "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==",
"license": "MIT",
"dependencies": {
"icss-utils": "^5.0.0",
- "postcss-selector-parser": "^6.0.2",
+ "postcss-selector-parser": "^7.0.0",
"postcss-value-parser": "^4.1.0"
},
"engines": {
@@ -10773,13 +11500,26 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/postcss-modules-local-by-default/node_modules/postcss-selector-parser": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-modules-scope": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.0.tgz",
- "integrity": "sha512-oq+g1ssrsZOsx9M96c5w8laRmvEu9C3adDSjI8oTcbfkrTE8hx/zfyobUoWIxaKPO8bt6S62kxpw5GqypEw1QQ==",
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz",
+ "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==",
"license": "ISC",
"dependencies": {
- "postcss-selector-parser": "^6.0.4"
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
"node": "^10 || ^12 || >= 14"
@@ -10788,6 +11528,19 @@
"postcss": "^8.1.0"
}
},
+ "node_modules/postcss-modules-scope/node_modules/postcss-selector-parser": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-modules-values": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
@@ -10804,28 +11557,34 @@
}
},
"node_modules/postcss-nested": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz",
- "integrity": "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==",
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz",
+ "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==",
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
"license": "MIT",
"dependencies": {
- "postcss-selector-parser": "^6.0.11"
+ "postcss-selector-parser": "^6.1.1"
},
"engines": {
"node": ">=12.0"
},
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
"peerDependencies": {
"postcss": "^8.2.14"
}
},
"node_modules/postcss-nesting": {
- "version": "12.1.5",
- "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-12.1.5.tgz",
- "integrity": "sha512-N1NgI1PDCiAGWPTYrwqm8wpjv0bgDmkYHH72pNsqTCv9CObxjxftdYu6AKtGN+pnJa7FQjMm3v4sp8QJbFsYdQ==",
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-nesting/-/postcss-nesting-13.0.1.tgz",
+ "integrity": "sha512-VbqqHkOBOt4Uu3G8Dm8n6lU5+9cJFxiuty9+4rcoyRPO9zZS1JIs6td49VIoix3qYqELHlJIn46Oih9SAKo+yQ==",
"funding": [
{
"type": "github",
@@ -10838,21 +11597,78 @@
],
"license": "MIT-0",
"dependencies": {
- "@csstools/selector-resolve-nested": "^1.1.0",
- "@csstools/selector-specificity": "^3.1.1",
- "postcss-selector-parser": "^6.1.0"
+ "@csstools/selector-resolve-nested": "^3.0.0",
+ "@csstools/selector-specificity": "^5.0.0",
+ "postcss-selector-parser": "^7.0.0"
},
"engines": {
- "node": "^14 || ^16 || >=18"
+ "node": ">=18"
},
"peerDependencies": {
"postcss": "^8.4"
}
},
+ "node_modules/postcss-nesting/node_modules/@csstools/selector-resolve-nested": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-resolve-nested/-/selector-resolve-nested-3.0.0.tgz",
+ "integrity": "sha512-ZoK24Yku6VJU1gS79a5PFmC8yn3wIapiKmPgun0hZgEI5AOqgH2kiPRsPz1qkGv4HL+wuDLH83yQyk6inMYrJQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.0.0"
+ }
+ },
+ "node_modules/postcss-nesting/node_modules/@csstools/selector-specificity": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz",
+ "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.0.0"
+ }
+ },
+ "node_modules/postcss-nesting/node_modules/postcss-selector-parser": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/postcss-resolve-nested-selector": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
- "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==",
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz",
+ "integrity": "sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==",
"dev": true,
"license": "MIT"
},
@@ -10901,9 +11717,9 @@
}
},
"node_modules/postcss-selector-parser": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz",
- "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==",
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz",
+ "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==",
"license": "MIT",
"dependencies": {
"cssesc": "^3.0.0",
@@ -10949,63 +11765,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/prettier": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz",
- "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==",
- "dev": true,
- "license": "MIT",
- "bin": {
- "prettier": "bin/prettier.cjs"
- },
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/prettier/prettier?sponsor=1"
- }
- },
- "node_modules/prettier-linter-helpers": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
- "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "fast-diff": "^1.1.2"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/pretty-format": {
- "version": "29.7.0",
- "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
- "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@jest/schemas": "^29.6.3",
- "ansi-styles": "^5.0.0",
- "react-is": "^18.0.0"
- },
- "engines": {
- "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
- }
- },
- "node_modules/pretty-format/node_modules/ansi-styles": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
"node_modules/pretty-ms": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.0.0.tgz",
@@ -11035,20 +11794,24 @@
"dev": true,
"license": "ISC"
},
- "node_modules/proto-props": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz",
- "integrity": "sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==",
+ "node_modules/prototype-properties": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/prototype-properties/-/prototype-properties-5.0.0.tgz",
+ "integrity": "sha512-uCWE2QqnGlwvvJXTwiHTPTyHE62+zORO5hpFWhAwBGDtEtTmNZZleNLJDoFsqHCL4p/CeAP2Q1uMKFUKALuRGQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=4"
+ "node": ">=18.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -11064,6 +11827,22 @@
"node": ">=6"
}
},
+ "node_modules/quansync": {
+ "version": "0.2.10",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.10.tgz",
+ "integrity": "sha512-t41VRkMYbkHyCYmOvx/6URnN80H7k4X0lLdBMGsz+maAwrJQYB1djpV6vHrQIBE0WBSGqhtEHrK9U3DWWH8v7A==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT"
+ },
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -11093,13 +11872,6 @@
"safe-buffer": "^5.1.0"
}
},
- "node_modules/react-is": {
- "version": "18.3.1",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==",
- "dev": true,
- "license": "MIT"
- },
"node_modules/read-cache": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -11109,116 +11881,181 @@
"pify": "^2.3.0"
}
},
+ "node_modules/read-installed-packages": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/read-installed-packages/-/read-installed-packages-2.0.1.tgz",
+ "integrity": "sha512-t+fJOFOYaZIjBpTVxiV8Mkt7yQyy4E6MSrrnt5FmPd4enYvpU/9DYGirDmN1XQwkfeuWIhM/iu0t2rm6iSr0CA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/fs": "^3.1.0",
+ "debug": "^4.3.4",
+ "read-package-json": "^6.0.0",
+ "semver": "2 || 3 || 4 || 5 || 6 || 7",
+ "slide": "~1.1.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.2"
+ }
+ },
+ "node_modules/read-package-json": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-6.0.4.tgz",
+ "integrity": "sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==",
+ "deprecated": "This package is no longer supported. Please use @npmcli/package-json instead.",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^10.2.2",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^5.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/read-package-json/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/read-package-json/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz",
+ "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/read-package-json/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/read-package-up": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz",
+ "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up-simple": "^1.0.0",
+ "read-pkg": "^9.0.0",
+ "type-fest": "^4.6.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/read-pkg": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
- "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz",
+ "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/normalize-package-data": "^2.4.0",
- "normalize-package-data": "^2.5.0",
- "parse-json": "^5.0.0",
- "type-fest": "^0.6.0"
+ "@types/normalize-package-data": "^2.4.3",
+ "normalize-package-data": "^6.0.0",
+ "parse-json": "^8.0.0",
+ "type-fest": "^4.6.0",
+ "unicorn-magic": "^0.1.0"
},
"engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
- "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "find-up": "^4.1.0",
- "read-pkg": "^5.2.0",
- "type-fest": "^0.8.1"
- },
- "engines": {
- "node": ">=8"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/read-pkg-up/node_modules/find-up": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
- "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "node_modules/read-pkg/node_modules/hosted-git-info": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz",
+ "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==",
"dev": true,
- "license": "MIT",
+ "license": "ISC",
"dependencies": {
- "locate-path": "^5.0.0",
- "path-exists": "^4.0.0"
+ "lru-cache": "^10.0.1"
},
"engines": {
- "node": ">=8"
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "node_modules/read-pkg-up/node_modules/locate-path": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
- "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "node_modules/read-pkg/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
- "license": "MIT",
+ "license": "ISC"
+ },
+ "node_modules/read-pkg/node_modules/normalize-package-data": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz",
+ "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
"dependencies": {
- "p-locate": "^4.1.0"
+ "hosted-git-info": "^7.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
},
"engines": {
- "node": ">=8"
+ "node": "^16.14.0 || >=18.0.0"
}
},
- "node_modules/read-pkg-up/node_modules/p-limit": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
- "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "node_modules/read-pkg/node_modules/parse-json": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.2.0.tgz",
+ "integrity": "sha512-eONBZy4hm2AgxjNFd8a4nyDJnzUAH0g34xSQAwWEVGCjdZ4ZL7dKZBfq267GWP/JaS9zW62Xs2FeAdDvpHHJGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "p-try": "^2.0.0"
+ "@babel/code-frame": "^7.26.2",
+ "index-to-position": "^1.0.0",
+ "type-fest": "^4.37.0"
},
"engines": {
- "node": ">=6"
+ "node": ">=18"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/read-pkg-up/node_modules/p-locate": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
- "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "p-limit": "^2.2.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg-up/node_modules/type-fest": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
- "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
- "dev": true,
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/read-pkg/node_modules/type-fest": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
- "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
- "dev": true,
- "license": "(MIT OR CC0-1.0)",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -11257,19 +12094,20 @@
}
},
"node_modules/reflect.getprototypeof": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.6.tgz",
- "integrity": "sha512-fmfw4XgoDke3kdI6h4xcUz1dG8uaiv5q9gcEwLS4Pnth2kxT+GZ7YehS1JTMGBQmtV7Y4GFGbs2re2NqhdozUg==",
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
+ "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
"define-properties": "^1.2.1",
- "es-abstract": "^1.23.1",
+ "es-abstract": "^1.23.9",
"es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.4",
- "globalthis": "^1.0.3",
- "which-builtin-type": "^1.1.3"
+ "es-object-atoms": "^1.0.0",
+ "get-intrinsic": "^1.2.7",
+ "get-proto": "^1.0.1",
+ "which-builtin-type": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
@@ -11309,16 +12147,18 @@
}
},
"node_modules/regexp.prototype.flags": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
- "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==",
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz",
+ "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.6",
+ "call-bind": "^1.0.8",
"define-properties": "^1.2.1",
"es-errors": "^1.3.0",
- "set-function-name": "^2.0.1"
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "set-function-name": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -11328,25 +12168,29 @@
}
},
"node_modules/regjsparser": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz",
- "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==",
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz",
+ "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
- "jsesc": "~0.5.0"
+ "jsesc": "~3.0.2"
},
"bin": {
"regjsparser": "bin/parser"
}
},
"node_modules/regjsparser/node_modules/jsesc": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
- "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz",
+ "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==",
"dev": true,
+ "license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
}
},
"node_modules/require-directory": {
@@ -11378,18 +12222,21 @@
}
},
"node_modules/resolve": {
- "version": "1.22.8",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
- "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
+ "version": "1.22.10",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz",
+ "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==",
"license": "MIT",
"dependencies": {
- "is-core-module": "^2.13.0",
+ "is-core-module": "^2.16.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
"bin": {
"resolve": "bin/resolve"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -11434,32 +12281,15 @@
}
},
"node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
+ "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"license": "MIT",
"engines": {
"iojs": ">=1.0.0",
"node": ">=0.10.0"
}
},
- "node_modules/rimraf": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
- "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "deprecated": "Rimraf versions prior to v4 are no longer supported",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"node_modules/robust-predicates": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz",
@@ -11467,9 +12297,9 @@
"license": "Unlicense"
},
"node_modules/rollup": {
- "version": "2.79.1",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.1.tgz",
- "integrity": "sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==",
+ "version": "2.79.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.79.2.tgz",
+ "integrity": "sha512-fS6iqSPZDs3dr/y7Od6y5nha8dW1YnbgtsyotCVvoFGKbERG++CVRFv1meyGDE1SNItQA8BrnCw7ScdAhRJ3XQ==",
"dev": true,
"license": "MIT",
"bin": {
@@ -11482,6 +12312,41 @@
"fsevents": "~2.3.2"
}
},
+ "node_modules/roughjs": {
+ "version": "4.6.6",
+ "resolved": "https://registry.npmjs.org/roughjs/-/roughjs-4.6.6.tgz",
+ "integrity": "sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==",
+ "license": "MIT",
+ "dependencies": {
+ "hachure-fill": "^0.5.2",
+ "path-data-parser": "^0.1.0",
+ "points-on-curve": "^0.2.0",
+ "points-on-path": "^0.2.1"
+ }
+ },
+ "node_modules/rspack-resolver": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/rspack-resolver/-/rspack-resolver-1.2.2.tgz",
+ "integrity": "sha512-Fwc19jMBA3g+fxDJH2B4WxwZjE0VaaOL7OX/A4Wn5Zv7bOD/vyPZhzXfaO73Xc2GAlfi96g5fGUa378WbIGfFw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/JounQin"
+ },
+ "optionalDependencies": {
+ "@unrs/rspack-resolver-binding-darwin-arm64": "1.2.2",
+ "@unrs/rspack-resolver-binding-darwin-x64": "1.2.2",
+ "@unrs/rspack-resolver-binding-freebsd-x64": "1.2.2",
+ "@unrs/rspack-resolver-binding-linux-arm-gnueabihf": "1.2.2",
+ "@unrs/rspack-resolver-binding-linux-arm64-gnu": "1.2.2",
+ "@unrs/rspack-resolver-binding-linux-arm64-musl": "1.2.2",
+ "@unrs/rspack-resolver-binding-linux-x64-gnu": "1.2.2",
+ "@unrs/rspack-resolver-binding-linux-x64-musl": "1.2.2",
+ "@unrs/rspack-resolver-binding-wasm32-wasi": "1.2.2",
+ "@unrs/rspack-resolver-binding-win32-arm64-msvc": "1.2.2",
+ "@unrs/rspack-resolver-binding-win32-x64-msvc": "1.2.2"
+ }
+ },
"node_modules/run-con": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz",
@@ -11537,28 +12402,17 @@
"integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==",
"license": "BSD-3-Clause"
},
- "node_modules/sade": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
- "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
- "license": "MIT",
- "dependencies": {
- "mri": "^1.1.0"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/safe-array-concat": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz",
- "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
+ "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
- "get-intrinsic": "^1.2.4",
- "has-symbols": "^1.0.3",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "get-intrinsic": "^1.2.6",
+ "has-symbols": "^1.1.0",
"isarray": "^2.0.5"
},
"engines": {
@@ -11588,16 +12442,33 @@
],
"license": "MIT"
},
- "node_modules/safe-regex-test": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz",
- "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==",
+ "node_modules/safe-push-apply": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
+ "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.6",
"es-errors": "^1.3.0",
- "is-regex": "^1.1.4"
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/safe-regex-test": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz",
+ "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "is-regex": "^1.2.1"
},
"engines": {
"node": ">= 0.4"
@@ -11627,9 +12498,9 @@
"license": "ISC"
},
"node_modules/schema-utils": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.2.0.tgz",
- "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==",
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.0.tgz",
+ "integrity": "sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==",
"license": "MIT",
"dependencies": {
"@types/json-schema": "^7.0.9",
@@ -11638,7 +12509,7 @@
"ajv-keywords": "^5.1.0"
},
"engines": {
- "node": ">= 12.13.0"
+ "node": ">= 10.13.0"
},
"funding": {
"type": "opencollective",
@@ -11661,9 +12532,9 @@
}
},
"node_modules/semver": {
- "version": "7.6.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
- "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
+ "version": "7.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -11682,18 +12553,18 @@
}
},
"node_modules/seroval": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.0.7.tgz",
- "integrity": "sha512-n6ZMQX5q0Vn19Zq7CIKNIo7E75gPkGCFUEqDpa8jgwpYr/vScjqnQ6H09t1uIiZ0ZSK0ypEGvrYK2bhBGWsGdw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.2.1.tgz",
+ "integrity": "sha512-yBxFFs3zmkvKNmR0pFSU//rIsYjuX418TnlDmc2weaq5XFDqDIV/NOMPBoLrbxjLH42p4UzRuXHryXh9dYcKcw==",
"license": "MIT",
"engines": {
"node": ">=10"
}
},
"node_modules/seroval-plugins": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.0.7.tgz",
- "integrity": "sha512-GO7TkWvodGp6buMEX9p7tNyIkbwlyuAWbI6G9Ec5bhcm7mQdu3JOK1IXbEUwb3FVzSc363GraG/wLW23NSavIw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.2.1.tgz",
+ "integrity": "sha512-H5vs53+39+x4Udwp4J5rNZfgFuA+Lt+uU+09w1gYBVWomtAl98B+E9w7yC05Xc81/HgLvJdlyqJbU0fJCKCmdw==",
"license": "MIT",
"engines": {
"node": ">=10"
@@ -11736,6 +12607,21 @@
"node": ">= 0.4"
}
},
+ "node_modules/set-proto": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz",
+ "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/shallow-clone": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
@@ -11770,16 +12656,73 @@
}
},
"node_modules/side-channel": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
- "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
"es-errors": "^1.3.0",
- "get-intrinsic": "^1.2.4",
- "object-inspect": "^1.13.1"
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
},
"engines": {
"node": ">= 0.4"
@@ -11808,13 +12751,13 @@
}
},
"node_modules/simple-eval": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/simple-eval/-/simple-eval-1.0.0.tgz",
- "integrity": "sha512-kpKJR+bqTscgC0xuAl2xHN6bB12lHjC2DCUfqjAx19bQyO3R2EVLOurm3H9AUltv/uFVcSCVNc6faegR+8NYLw==",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/simple-eval/-/simple-eval-1.0.1.tgz",
+ "integrity": "sha512-LH7FpTAkeD+y5xQC4fzS+tFtaNlvt3Ib1zKzvhjv/Y+cioV4zIuw4IZr2yhRLu67CWL7FR9/6KXKnjRoZTvGGQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "jsep": "^1.1.2"
+ "jsep": "^1.3.6"
},
"engines": {
"node": ">=12"
@@ -11848,31 +12791,44 @@
"url": "https://github.com/chalk/slice-ansi?sponsor=1"
}
},
+ "node_modules/slide": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
+ "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "*"
+ }
+ },
"node_modules/smol-toml": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.2.2.tgz",
- "integrity": "sha512-fVEjX2ybKdJKzFL46VshQbj9PuA4IUKivalgp48/3zwS9vXzyykzQ6AX92UxHSvWJagziMRLeHMgEzoGO7A8hQ==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.1.tgz",
+ "integrity": "sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">= 18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/cyyynthia"
}
},
"node_modules/solid-js": {
- "version": "1.8.18",
- "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.18.tgz",
- "integrity": "sha512-cpkxDPvO/AuKBugVv6xKFd1C9VC0XZMu4VtF56IlHoux8HgyW44uqNSWbozMnVcpIzHIhS3vVXPAVZYM26jpWw==",
+ "version": "1.9.5",
+ "resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.9.5.tgz",
+ "integrity": "sha512-ogI3DaFcyn6UhYhrgcyRAMbu/buBJitYQASZz5WzfQVPP10RD2AbCoRZ517psnezrasyCbWzIxZ6kVqet768xw==",
"license": "MIT",
"dependencies": {
"csstype": "^3.1.0",
- "seroval": "^1.0.4",
- "seroval-plugins": "^1.0.3"
+ "seroval": "^1.1.0",
+ "seroval-plugins": "^1.1.0"
}
},
"node_modules/sortablejs": {
- "version": "1.15.2",
- "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.2.tgz",
- "integrity": "sha512-FJF5jgdfvoKn1MAKSdGs33bIqLi3LmsgVTliuX6iITj834F+JRQZN90Z93yql8h0K2t0RwDPBmxwlbZfDcxNZA==",
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.6.tgz",
+ "integrity": "sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==",
"license": "MIT"
},
"node_modules/source-list-map": {
@@ -11891,9 +12847,9 @@
}
},
"node_modules/source-map-js": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
- "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
@@ -11933,6 +12889,7 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/spdx-compare/-/spdx-compare-1.0.0.tgz",
"integrity": "sha512-C1mDZOX0hnu0ep9dfmuoi03+eOdDoz2yvK79RxbcrVEG1NO1Ph35yW102DHWKN4pk80nwCgeMmSY5L25VE4D9A==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"array-find-index": "^1.0.2",
@@ -11955,43 +12912,39 @@
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz",
"integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==",
+ "dev": true,
"license": "CC-BY-3.0"
},
"node_modules/spdx-expression-parse": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
"integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"spdx-exceptions": "^2.1.0",
"spdx-license-ids": "^3.0.0"
}
},
- "node_modules/spdx-expression-validate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/spdx-expression-validate/-/spdx-expression-validate-2.0.0.tgz",
- "integrity": "sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==",
- "license": "(MIT AND CC-BY-3.0)",
- "dependencies": {
- "spdx-expression-parse": "^3.0.0"
- }
- },
"node_modules/spdx-license-ids": {
- "version": "3.0.18",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz",
- "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==",
+ "version": "3.0.21",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz",
+ "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==",
+ "dev": true,
"license": "CC0-1.0"
},
"node_modules/spdx-ranges": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/spdx-ranges/-/spdx-ranges-2.1.1.tgz",
"integrity": "sha512-mcdpQFV7UDAgLpXEE/jOMqvK4LBoO0uTQg0uvXUewmEFhpiZx5yJSZITHB8w1ZahKdhfZqP5GPEOKLyEq5p8XA==",
+ "dev": true,
"license": "(MIT AND CC-BY-3.0)"
},
"node_modules/spdx-satisfies": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/spdx-satisfies/-/spdx-satisfies-5.0.1.tgz",
"integrity": "sha512-Nwor6W6gzFp8XX4neaKQ7ChV4wmpSh2sSDemMFSzHxpTw460jxFYeOn+jq4ybnSSw/5sc3pjka9MQPouksQNpw==",
+ "dev": true,
"license": "MIT",
"dependencies": {
"spdx-compare": "^1.0.0",
@@ -11999,6 +12952,13 @@
"spdx-ranges": "^2.0.0"
}
},
+ "node_modules/stable-hash": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz",
+ "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/stackback": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
@@ -12018,25 +12978,12 @@
}
},
"node_modules/std-env": {
- "version": "3.7.0",
- "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz",
- "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==",
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.8.1.tgz",
+ "integrity": "sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==",
"dev": true,
"license": "MIT"
},
- "node_modules/stop-iteration-iterator": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz",
- "integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "internal-slot": "^1.0.4"
- },
- "engines": {
- "node": ">= 0.4"
- }
- },
"node_modules/string-width": {
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
@@ -12066,40 +13013,20 @@
"node": ">=8"
}
},
- "node_modules/string-width-cjs/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
- "node_modules/string-width/node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "license": "MIT"
- },
- "node_modules/string.prototype.includes": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.0.tgz",
- "integrity": "sha512-E34CkBgyeqNDcrbU76cDjL5JLcVrtSdYq0MEh/B10r17pRP4ciHLwTgnuLV8Ay6cgEMLkcBkFCKyFZ43YldYzg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "define-properties": "^1.1.3",
- "es-abstract": "^1.17.5"
- }
- },
"node_modules/string.prototype.trim": {
- "version": "1.2.9",
- "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz",
- "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==",
+ "version": "1.2.10",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz",
+ "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
+ "define-data-property": "^1.1.4",
"define-properties": "^1.2.1",
- "es-abstract": "^1.23.0",
- "es-object-atoms": "^1.0.0"
+ "es-abstract": "^1.23.5",
+ "es-object-atoms": "^1.0.0",
+ "has-property-descriptors": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
@@ -12109,16 +13036,20 @@
}
},
"node_modules/string.prototype.trimend": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz",
- "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==",
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz",
+ "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.2",
"define-properties": "^1.2.1",
"es-object-atoms": "^1.0.0"
},
+ "engines": {
+ "node": ">= 0.4"
+ },
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@@ -12166,22 +13097,15 @@
"node": ">=8"
}
},
- "node_modules/strip-bom": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
- "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/strip-final-newline": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
- "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "node_modules/strip-indent": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-4.0.0.tgz",
+ "integrity": "sha512-mnVSV2l+Zv6BLpSD/8V87CW/y9EmmbYzGCIavsnsI6/nwn26DwffM/yztm30Z/I2DY9wdS3vXVCMnHDgZaVNoA==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "min-indent": "^1.0.1"
+ },
"engines": {
"node": ">=12"
},
@@ -12189,19 +13113,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/strip-indent": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
- "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "min-indent": "^1.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -12215,19 +13126,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/strip-literal": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-2.1.0.tgz",
- "integrity": "sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "js-tokens": "^9.0.0"
- },
- "funding": {
- "url": "https://github.com/sponsors/antfu"
- }
- },
"node_modules/style-search": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
@@ -12236,9 +13134,9 @@
"license": "ISC"
},
"node_modules/stylelint": {
- "version": "16.6.1",
- "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.6.1.tgz",
- "integrity": "sha512-yNgz2PqWLkhH2hw6X9AweV9YvoafbAD5ZsFdKN9BvSDVwGvPh+AUIrn7lYwy1S7IHmtFin75LLfX1m0D2tHu8Q==",
+ "version": "16.16.0",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.16.0.tgz",
+ "integrity": "sha512-40X5UOb/0CEFnZVEHyN260HlSSUxPES+arrUphOumGWgXERHfwCD0kNBVILgQSij8iliYVwlc0V7M5bcLP9vPg==",
"dev": true,
"funding": [
{
@@ -12252,44 +13150,43 @@
],
"license": "MIT",
"dependencies": {
- "@csstools/css-parser-algorithms": "^2.6.3",
- "@csstools/css-tokenizer": "^2.3.1",
- "@csstools/media-query-list-parser": "^2.1.11",
- "@csstools/selector-specificity": "^3.1.1",
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3",
+ "@csstools/media-query-list-parser": "^4.0.2",
+ "@csstools/selector-specificity": "^5.0.0",
"@dual-bundle/import-meta-resolve": "^4.1.0",
"balanced-match": "^2.0.0",
"colord": "^2.9.3",
"cosmiconfig": "^9.0.0",
- "css-functions-list": "^3.2.2",
- "css-tree": "^2.3.1",
- "debug": "^4.3.4",
- "fast-glob": "^3.3.2",
+ "css-functions-list": "^3.2.3",
+ "css-tree": "^3.1.0",
+ "debug": "^4.3.7",
+ "fast-glob": "^3.3.3",
"fastest-levenshtein": "^1.0.16",
- "file-entry-cache": "^9.0.0",
+ "file-entry-cache": "^10.0.7",
"global-modules": "^2.0.0",
"globby": "^11.1.0",
"globjoin": "^0.1.4",
"html-tags": "^3.3.1",
- "ignore": "^5.3.1",
+ "ignore": "^7.0.3",
"imurmurhash": "^0.1.4",
"is-plain-object": "^5.0.0",
- "known-css-properties": "^0.31.0",
+ "known-css-properties": "^0.35.0",
"mathml-tag-names": "^2.1.3",
"meow": "^13.2.0",
- "micromatch": "^4.0.7",
+ "micromatch": "^4.0.8",
"normalize-path": "^3.0.0",
- "picocolors": "^1.0.1",
- "postcss": "^8.4.38",
- "postcss-resolve-nested-selector": "^0.1.1",
- "postcss-safe-parser": "^7.0.0",
- "postcss-selector-parser": "^6.1.0",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.5.3",
+ "postcss-resolve-nested-selector": "^0.1.6",
+ "postcss-safe-parser": "^7.0.1",
+ "postcss-selector-parser": "^7.1.0",
"postcss-value-parser": "^4.2.0",
"resolve-from": "^5.0.0",
"string-width": "^4.2.3",
- "strip-ansi": "^7.1.0",
- "supports-hyperlinks": "^3.0.0",
+ "supports-hyperlinks": "^3.2.0",
"svg-tags": "^1.0.0",
- "table": "^6.8.2",
+ "table": "^6.9.0",
"write-file-atomic": "^5.0.1"
},
"bin": {
@@ -12313,9 +13210,9 @@
}
},
"node_modules/stylelint-declaration-strict-value": {
- "version": "1.10.4",
- "resolved": "https://registry.npmjs.org/stylelint-declaration-strict-value/-/stylelint-declaration-strict-value-1.10.4.tgz",
- "integrity": "sha512-unOEftKCOb78Zr+WStqyVj9V1rCdUo+PJI3vFPiHPdu+O9o71K9Mu+txc6VDF7gBXyTTMHbbjIvHk3VNzuixzQ==",
+ "version": "1.10.11",
+ "resolved": "https://registry.npmjs.org/stylelint-declaration-strict-value/-/stylelint-declaration-strict-value-1.10.11.tgz",
+ "integrity": "sha512-oVQvhZlFZAiDz9r2BPFZLtTGm1A2JVhdKObKAJoTjFfR4F/NpApC4bMBTxf4sZS76Na3njYKVOaAaKSZ4+FU+g==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12342,17 +13239,51 @@
"stylelint": ">=16"
}
},
- "node_modules/stylelint/node_modules/ansi-regex": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
- "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "node_modules/stylelint/node_modules/@csstools/media-query-list-parser": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.2.tgz",
+ "integrity": "sha512-EUos465uvVvMJehckATTlNqGj4UJWkTmdWuDMjqvSUkjGpmOyFZBVwb4knxCm/k2GMTXY+c/5RkdndzFYWeX5A==",
"dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
"license": "MIT",
"engines": {
- "node": ">=12"
+ "node": ">=18"
},
- "funding": {
- "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ "peerDependencies": {
+ "@csstools/css-parser-algorithms": "^3.0.4",
+ "@csstools/css-tokenizer": "^3.0.3"
+ }
+ },
+ "node_modules/stylelint/node_modules/@csstools/selector-specificity": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz",
+ "integrity": "sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/csstools"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/csstools"
+ }
+ ],
+ "license": "MIT-0",
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "postcss-selector-parser": "^7.0.0"
}
},
"node_modules/stylelint/node_modules/balanced-match": {
@@ -12363,36 +13294,70 @@
"license": "MIT"
},
"node_modules/stylelint/node_modules/file-entry-cache": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz",
- "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==",
+ "version": "10.0.7",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-10.0.7.tgz",
+ "integrity": "sha512-txsf5fu3anp2ff3+gOJJzRImtrtm/oa9tYLN0iTuINZ++EyVR/nRrg2fKYwvG/pXDofcrvvb0scEbX3NyW/COw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "flat-cache": "^5.0.0"
- },
- "engines": {
- "node": ">=18"
+ "flat-cache": "^6.1.7"
}
},
"node_modules/stylelint/node_modules/flat-cache": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz",
- "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==",
+ "version": "6.1.7",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.7.tgz",
+ "integrity": "sha512-qwZ4xf1v1m7Rc9XiORly31YaChvKt6oNVHuqqZcoED/7O+ToyNVGobKsIAopY9ODcWpEDKEBAbrSOCBHtNQvew==",
"dev": true,
"license": "MIT",
"dependencies": {
- "flatted": "^3.3.1",
- "keyv": "^4.5.4"
+ "cacheable": "^1.8.9",
+ "flatted": "^3.3.3",
+ "hookified": "^1.7.1"
+ }
+ },
+ "node_modules/stylelint/node_modules/ignore": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz",
+ "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/stylelint/node_modules/postcss": {
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
},
"engines": {
- "node": ">=18"
+ "node": "^10 || ^12 || >=14"
}
},
"node_modules/stylelint/node_modules/postcss-safe-parser": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz",
- "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz",
+ "integrity": "sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==",
"dev": true,
"funding": [
{
@@ -12416,6 +13381,20 @@
"postcss": "^8.4.31"
}
},
+ "node_modules/stylelint/node_modules/postcss-selector-parser": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz",
+ "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/stylelint/node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -12426,26 +13405,10 @@
"node": ">=8"
}
},
- "node_modules/stylelint/node_modules/strip-ansi": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
- "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "ansi-regex": "^6.0.1"
- },
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/chalk/strip-ansi?sponsor=1"
- }
- },
"node_modules/stylis": {
- "version": "4.3.2",
- "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
- "integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg==",
+ "version": "4.3.6",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.6.tgz",
+ "integrity": "sha512-yQ3rwFWRfwNUY7H5vpU0wfdkNSnvnJinhF9830Swlaxl03zsOjCfmX0ugac+3LtK0lYSgwL/KXc8oYL3mG4YFQ==",
"license": "MIT"
},
"node_modules/stylus": {
@@ -12511,9 +13474,9 @@
}
},
"node_modules/sucrase/node_modules/glob": {
- "version": "10.4.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
- "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
@@ -12526,18 +13489,24 @@
"bin": {
"glob": "dist/esm/bin.mjs"
},
- "engines": {
- "node": ">=16 || 14 >=14.18"
- },
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
- "node_modules/superstruct": {
- "version": "0.10.13",
- "resolved": "https://registry.npmjs.org/superstruct/-/superstruct-0.10.13.tgz",
- "integrity": "sha512-W4SitSZ9MOyMPbHreoZVEneSZyPEeNGbdfJo/7FkJyRs/M3wQRFzq+t3S/NBwlrFSWdx1ONLjLb9pB+UKe4IqQ==",
- "license": "MIT"
+ "node_modules/sucrase/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
},
"node_modules/supports-color": {
"version": "7.2.0",
@@ -12552,9 +13521,9 @@
}
},
"node_modules/supports-hyperlinks": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz",
- "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz",
+ "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -12563,6 +13532,9 @@
},
"engines": {
"node": ">=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1"
}
},
"node_modules/supports-preserve-symlinks-flag": {
@@ -12577,17 +13549,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/svg-element-attributes": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/svg-element-attributes/-/svg-element-attributes-1.3.1.tgz",
- "integrity": "sha512-Bh05dSOnJBf3miNMqpsormfNtfidA/GxQVakhtn0T4DECWKeXQRQUceYjJ+OxYiiLdGe4Jo9iFV8wICFapFeIA==",
- "dev": true,
- "license": "MIT",
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/wooorm"
- }
- },
"node_modules/svg-tags": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
@@ -12630,6 +13591,27 @@
"node": ">= 10"
}
},
+ "node_modules/svgo/node_modules/css-tree": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
+ "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mdn-data": "2.0.30",
+ "source-map-js": "^1.0.1"
+ },
+ "engines": {
+ "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
+ }
+ },
+ "node_modules/svgo/node_modules/mdn-data": {
+ "version": "2.0.30",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
+ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
+ "dev": true,
+ "license": "CC0-1.0"
+ },
"node_modules/swagger-ui-dist": {
"version": "5.17.14",
"resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-5.17.14.tgz",
@@ -12649,27 +13631,10 @@
"node": ">=14"
}
},
- "node_modules/synckit": {
- "version": "0.8.8",
- "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz",
- "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@pkgr/core": "^0.1.0",
- "tslib": "^2.6.2"
- },
- "engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/unts"
- }
- },
"node_modules/table": {
- "version": "6.8.2",
- "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz",
- "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==",
+ "version": "6.9.0",
+ "resolved": "https://registry.npmjs.org/table/-/table-6.9.0.tgz",
+ "integrity": "sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==",
"dev": true,
"license": "BSD-3-Clause",
"dependencies": {
@@ -12684,33 +13649,33 @@
}
},
"node_modules/tailwindcss": {
- "version": "3.4.4",
- "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.4.tgz",
- "integrity": "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A==",
+ "version": "3.4.17",
+ "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.4.17.tgz",
+ "integrity": "sha512-w33E2aCvSDP0tW9RZuNXadXlkHXqFzSkQew/aIa2i/Sj8fThxwovwlXHSPXTbAHwEIhBFXAedUhP2tueAKP8Og==",
"license": "MIT",
"dependencies": {
"@alloc/quick-lru": "^5.2.0",
"arg": "^5.0.2",
- "chokidar": "^3.5.3",
+ "chokidar": "^3.6.0",
"didyoumean": "^1.2.2",
"dlv": "^1.1.3",
- "fast-glob": "^3.3.0",
+ "fast-glob": "^3.3.2",
"glob-parent": "^6.0.2",
"is-glob": "^4.0.3",
- "jiti": "^1.21.0",
- "lilconfig": "^2.1.0",
- "micromatch": "^4.0.5",
+ "jiti": "^1.21.6",
+ "lilconfig": "^3.1.3",
+ "micromatch": "^4.0.8",
"normalize-path": "^3.0.0",
"object-hash": "^3.0.0",
- "picocolors": "^1.0.0",
- "postcss": "^8.4.23",
+ "picocolors": "^1.1.1",
+ "postcss": "^8.4.47",
"postcss-import": "^15.1.0",
"postcss-js": "^4.0.1",
- "postcss-load-config": "^4.0.1",
- "postcss-nested": "^6.0.1",
- "postcss-selector-parser": "^6.0.11",
- "resolve": "^1.22.2",
- "sucrase": "^3.32.0"
+ "postcss-load-config": "^4.0.2",
+ "postcss-nested": "^6.2.0",
+ "postcss-selector-parser": "^6.1.2",
+ "resolve": "^1.22.8",
+ "sucrase": "^3.35.0"
},
"bin": {
"tailwind": "lib/cli.js",
@@ -12729,25 +13694,10 @@
"node": ">=6"
}
},
- "node_modules/temporal-polyfill": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.2.4.tgz",
- "integrity": "sha512-WA5p0CjQTkMjF9m8sP4wSYgpqI8m2d4q7wPUyaJOWhy4bI9mReLb2yGvTV4qf/DPMTe6H6M/Dig5KmTMB7ev6Q==",
- "license": "MIT",
- "dependencies": {
- "temporal-spec": "^0.2.4"
- }
- },
- "node_modules/temporal-spec": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.2.4.tgz",
- "integrity": "sha512-lDMFv4nKQrSjlkHKAlHVqKrBG4DyFfa9F74cmBZ3Iy3ed8yvWnlWSIdi4IKfSqwmazAohBNwiN64qGx4y5Q3IQ==",
- "license": "ISC"
- },
"node_modules/terser": {
- "version": "5.31.1",
- "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.1.tgz",
- "integrity": "sha512-37upzU1+viGvuFtBo9NPufCb9dwM0+l9hMxYyWfBA+fbwrPqNJAhbZ6W47bBFnZHKHTUBnMvi87434qq+qnxOg==",
+ "version": "5.39.0",
+ "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz",
+ "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==",
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
@@ -12763,16 +13713,16 @@
}
},
"node_modules/terser-webpack-plugin": {
- "version": "5.3.10",
- "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz",
- "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==",
+ "version": "5.3.14",
+ "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz",
+ "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==",
"license": "MIT",
"dependencies": {
- "@jridgewell/trace-mapping": "^0.3.20",
+ "@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
- "schema-utils": "^3.1.1",
- "serialize-javascript": "^6.0.1",
- "terser": "^5.26.0"
+ "schema-utils": "^4.3.0",
+ "serialize-javascript": "^6.0.2",
+ "terser": "^5.31.1"
},
"engines": {
"node": ">= 10.13.0"
@@ -12796,55 +13746,6 @@
}
}
},
- "node_modules/terser-webpack-plugin/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "license": "MIT",
- "peerDependencies": {
- "ajv": "^6.9.1"
- }
- },
- "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "license": "MIT"
- },
- "node_modules/terser-webpack-plugin/node_modules/schema-utils": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
- "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
- "license": "MIT",
- "dependencies": {
- "@types/json-schema": "^7.0.8",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -12852,42 +13753,55 @@
"license": "MIT"
},
"node_modules/test-exclude": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
- "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.1.tgz",
+ "integrity": "sha512-pFYqmTw68LXVjeWJMST4+borgQP2AyMNbg1BpZh9LbyhUeNkeaPF9gzfPGUAnSMV3qPYdWUwDIjjCLiSDOl7vg==",
"dev": true,
"license": "ISC",
"dependencies": {
"@istanbuljs/schema": "^0.1.2",
- "glob": "^7.1.4",
- "minimatch": "^3.0.4"
+ "glob": "^10.4.1",
+ "minimatch": "^9.0.4"
},
"engines": {
- "node": ">=8"
+ "node": ">=18"
}
},
- "node_modules/test-exclude/node_modules/brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "node_modules/test-exclude/node_modules/minimatch": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
- "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "node_modules/test-exclude/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"license": "ISC",
"dependencies": {
- "brace-expansion": "^1.1.7"
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/test-exclude/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
},
"engines": {
- "node": "*"
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/text-table": {
@@ -12928,9 +13842,9 @@
}
},
"node_modules/tinybench": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.8.0.tgz",
- "integrity": "sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==",
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
"dev": true,
"license": "MIT"
},
@@ -12940,10 +13854,71 @@
"integrity": "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==",
"license": "MIT"
},
+ "node_modules/tinyexec": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
+ "license": "MIT"
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.12",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz",
+ "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.4.3",
+ "picomatch": "^4.0.2"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinyglobby/node_modules/fdir": {
+ "version": "6.4.3",
+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz",
+ "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tinyglobby/node_modules/picomatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
"node_modules/tinypool": {
- "version": "0.8.4",
- "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.8.4.tgz",
- "integrity": "sha512-i11VH5gS6IFeLY3gMBQ00/MmLncVP7JLXOw1vlgkytLmJK7QnEr7NXf0LBdxfmNPAeyetukOk0bOYrJrFGjYJQ==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.2.tgz",
+ "integrity": "sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
+ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12951,9 +13926,9 @@
}
},
"node_modules/tinyspy": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz",
- "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz",
+ "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==",
"dev": true,
"license": "MIT",
"engines": {
@@ -12969,16 +13944,6 @@
"@popperjs/core": "^2.9.0"
}
},
- "node_modules/to-fast-properties": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
- "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
@@ -12997,12 +13962,51 @@
"integrity": "sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ==",
"license": "MIT"
},
+ "node_modules/toml-eslint-parser": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/toml-eslint-parser/-/toml-eslint-parser-0.10.0.tgz",
+ "integrity": "sha512-khrZo4buq4qVmsGzS5yQjKe/WsFvV8fGfOjDQN0q4iy9FjRfPWRgTFrU8u1R2iu/SfWLhY9WnCi4Jhdrcbtg+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.0.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ota-meshi"
+ }
+ },
+ "node_modules/toml-eslint-parser/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
"node_modules/tr46": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
"license": "MIT"
},
+ "node_modules/treeify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz",
+ "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
"node_modules/tributejs": {
"version": "5.1.3",
"resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz",
@@ -13010,16 +14014,16 @@
"license": "MIT"
},
"node_modules/ts-api-utils": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
- "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz",
+ "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
"dev": true,
"license": "MIT",
"engines": {
- "node": ">=16"
+ "node": ">=18.12"
},
"peerDependencies": {
- "typescript": ">=4.2.0"
+ "typescript": ">=4.8.4"
}
},
"node_modules/ts-dedent": {
@@ -13037,36 +14041,10 @@
"integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==",
"license": "Apache-2.0"
},
- "node_modules/tsconfig-paths": {
- "version": "3.15.0",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
- "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@types/json5": "^0.0.29",
- "json5": "^1.0.2",
- "minimist": "^1.2.6",
- "strip-bom": "^3.0.0"
- }
- },
- "node_modules/tsconfig-paths/node_modules/json5": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
- "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "minimist": "^1.2.0"
- },
- "bin": {
- "json5": "lib/cli.js"
- }
- },
"node_modules/tslib": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
- "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==",
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD"
},
@@ -13083,56 +14061,46 @@
"node": ">= 0.8.0"
}
},
- "node_modules/type-detect": {
- "version": "4.0.8",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
- "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
- "dev": true,
- "license": "MIT",
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/type-fest": {
- "version": "0.20.2",
- "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
- "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.37.0.tgz",
+ "integrity": "sha512-S/5/0kFftkq27FPNye0XM1e2NsnoD/3FS+pBmbjmmtLT6I+i344KoOf7pvXreaFsDamWeaJX55nczA1m5PsBDg==",
"dev": true,
"license": "(MIT OR CC0-1.0)",
"engines": {
- "node": ">=10"
+ "node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typed-array-buffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz",
- "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz",
+ "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bound": "^1.0.3",
"es-errors": "^1.3.0",
- "is-typed-array": "^1.1.13"
+ "is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-length": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz",
- "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz",
+ "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
"for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-proto": "^1.0.3",
- "is-typed-array": "^1.1.13"
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.14"
},
"engines": {
"node": ">= 0.4"
@@ -13142,18 +14110,19 @@
}
},
"node_modules/typed-array-byte-offset": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz",
- "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==",
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz",
+ "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.7",
+ "call-bind": "^1.0.8",
"for-each": "^0.3.3",
- "gopd": "^1.0.1",
- "has-proto": "^1.0.3",
- "is-typed-array": "^1.1.13"
+ "gopd": "^1.2.0",
+ "has-proto": "^1.2.0",
+ "is-typed-array": "^1.1.15",
+ "reflect.getprototypeof": "^1.0.9"
},
"engines": {
"node": ">= 0.4"
@@ -13163,18 +14132,18 @@
}
},
"node_modules/typed-array-length": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz",
- "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz",
+ "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==",
"dev": true,
"license": "MIT",
"dependencies": {
"call-bind": "^1.0.7",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
- "has-proto": "^1.0.3",
"is-typed-array": "^1.1.13",
- "possible-typed-array-names": "^1.0.0"
+ "possible-typed-array-names": "^1.0.0",
+ "reflect.getprototypeof": "^1.0.6"
},
"engines": {
"node": ">= 0.4"
@@ -13184,12 +14153,11 @@
}
},
"node_modules/typescript": {
- "version": "5.5.2",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
- "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
+ "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
"devOptional": true,
"license": "Apache-2.0",
- "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -13198,10 +14166,33 @@
"node": ">=14.17"
}
},
+ "node_modules/typescript-eslint": {
+ "version": "8.26.1",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.26.1.tgz",
+ "integrity": "sha512-t/oIs9mYyrwZGRpDv3g+3K6nZ5uhKEMt2oNmAPwaY4/ye0+EH4nXIPYNtkYFS6QHm+1DFg34DbglYBz5P9Xysg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.26.1",
+ "@typescript-eslint/parser": "8.26.1",
+ "@typescript-eslint/utils": "8.26.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0",
+ "typescript": ">=4.8.4 <5.9.0"
+ }
+ },
"node_modules/typo-js": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.4.tgz",
- "integrity": "sha512-Oy/k+tFle5NAA3J/yrrYGfvEnPVrDZ8s8/WCwjUE75k331QyKIsFss7byQ/PzBmXLY6h1moRnZbnaxWBe3I3CA==",
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.5.tgz",
+ "integrity": "sha512-F45vFWdGX8xahIk/sOp79z2NJs8ETMYsmMChm9D5Hlx3+9j7VnCyQyvij5MOCrNY3NNe8noSyokRjQRfq+Bc7A==",
"license": "BSD-3-Clause"
},
"node_modules/uc.micro": {
@@ -13212,10 +14203,9 @@
"license": "MIT"
},
"node_modules/ufo": {
- "version": "1.5.3",
- "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.3.tgz",
- "integrity": "sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==",
- "dev": true,
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz",
+ "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==",
"license": "MIT"
},
"node_modules/uint8-to-base64": {
@@ -13225,38 +14215,41 @@
"license": "ISC"
},
"node_modules/unbox-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
- "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
+ "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "call-bind": "^1.0.2",
+ "call-bound": "^1.0.3",
"has-bigints": "^1.0.2",
- "has-symbols": "^1.0.3",
- "which-boxed-primitive": "^1.0.2"
+ "has-symbols": "^1.1.0",
+ "which-boxed-primitive": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/undici-types": {
- "version": "5.26.5",
- "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
- "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "version": "6.20.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+ "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
"license": "MIT"
},
- "node_modules/unist-util-stringify-position": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz",
- "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==",
+ "node_modules/unicorn-magic": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
+ "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
+ "dev": true,
"license": "MIT",
- "dependencies": {
- "@types/unist": "^2.0.0"
+ "engines": {
+ "node": ">=18"
},
"funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/unified"
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/universalify": {
@@ -13270,9 +14263,9 @@
}
},
"node_modules/update-browserslist-db": {
- "version": "1.0.16",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz",
- "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
+ "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
"funding": [
{
"type": "opencollective",
@@ -13289,8 +14282,8 @@
],
"license": "MIT",
"dependencies": {
- "escalade": "^3.1.2",
- "picocolors": "^1.0.1"
+ "escalade": "^3.2.0",
+ "picocolors": "^1.1.1"
},
"bin": {
"update-browserslist-db": "cli.js"
@@ -13303,6 +14296,7 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"punycode": "^2.1.0"
@@ -13332,34 +14326,16 @@
}
},
"node_modules/uuid": {
- "version": "9.0.1",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
- "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz",
+ "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"license": "MIT",
"bin": {
- "uuid": "dist/bin/uuid"
- }
- },
- "node_modules/uvu": {
- "version": "0.5.6",
- "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz",
- "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==",
- "license": "MIT",
- "dependencies": {
- "dequal": "^2.0.0",
- "diff": "^5.0.0",
- "kleur": "^4.0.3",
- "sade": "^1.7.3"
- },
- "bin": {
- "uvu": "bin.js"
- },
- "engines": {
- "node": ">=8"
+ "uuid": "dist/esm/bin/uuid"
}
},
"node_modules/validate-npm-package-license": {
@@ -13390,21 +14366,21 @@
"license": "MIT"
},
"node_modules/vite": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.2.tgz",
- "integrity": "sha512-6lA7OBHBlXUxiJxbO5aAY2fsHHzDr1q7DvXYnyZycRs2Dz+dXBWuhpWHvmljTRTpQC2uvGmUFFkSHF2vGo90MA==",
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.2.tgz",
+ "integrity": "sha512-yW7PeMM+LkDzc7CgJuRLMW2Jz0FxMOsVJ8Lv3gpgW9WLcb9cTW+121UEr1hvmfR7w3SegR5ItvYyzVz1vxNJgQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "esbuild": "^0.21.3",
- "postcss": "^8.4.38",
- "rollup": "^4.13.0"
+ "esbuild": "^0.25.0",
+ "postcss": "^8.5.3",
+ "rollup": "^4.30.1"
},
"bin": {
"vite": "bin/vite.js"
},
"engines": {
- "node": "^18.0.0 || >=20.0.0"
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
},
"funding": {
"url": "https://github.com/vitejs/vite?sponsor=1"
@@ -13413,18 +14389,25 @@
"fsevents": "~2.3.3"
},
"peerDependencies": {
- "@types/node": "^18.0.0 || >=20.0.0",
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "jiti": ">=1.21.0",
"less": "*",
"lightningcss": "^1.21.0",
"sass": "*",
+ "sass-embedded": "*",
"stylus": "*",
"sugarss": "*",
- "terser": "^5.4.0"
+ "terser": "^5.16.0",
+ "tsx": "^4.8.1",
+ "yaml": "^2.4.2"
},
"peerDependenciesMeta": {
"@types/node": {
"optional": true
},
+ "jiti": {
+ "optional": true
+ },
"less": {
"optional": true
},
@@ -13434,6 +14417,9 @@
"sass": {
"optional": true
},
+ "sass-embedded": {
+ "optional": true
+ },
"stylus": {
"optional": true
},
@@ -13442,27 +14428,33 @@
},
"terser": {
"optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
}
}
},
"node_modules/vite-node": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-1.6.0.tgz",
- "integrity": "sha512-de6HJgzC+TFzOu0NTC4RAIsyf/DY/ibWDYQUcuEA84EMHhcefTUGkjFHKKEJhQN4A+6I0u++kr3l36ZF2d7XRw==",
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.0.8.tgz",
+ "integrity": "sha512-6PhR4H9VGlcwXZ+KWCdMqbtG649xCPZqfI9j2PsK1FcXgEzro5bGHcVKFCTqPLaNKZES8Evqv4LwvZARsq5qlg==",
"dev": true,
"license": "MIT",
"dependencies": {
"cac": "^6.7.14",
- "debug": "^4.3.4",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "vite": "^5.0.0"
+ "debug": "^4.4.0",
+ "es-module-lexer": "^1.6.0",
+ "pathe": "^2.0.3",
+ "vite": "^5.0.0 || ^6.0.0"
},
"bin": {
"vite-node": "vite-node.mjs"
},
"engines": {
- "node": "^18.0.0 || >=20.0.0"
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
@@ -13475,443 +14467,13 @@
"dev": true,
"license": "BSD-2-Clause"
},
- "node_modules/vite/node_modules/@esbuild/aix-ppc64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",
- "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "aix"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/android-arm": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz",
- "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/android-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz",
- "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/android-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz",
- "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "android"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/darwin-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz",
- "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/darwin-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz",
- "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/freebsd-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz",
- "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/freebsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz",
- "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "freebsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-arm": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz",
- "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==",
- "cpu": [
- "arm"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz",
- "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-ia32": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz",
- "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-loong64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz",
- "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==",
- "cpu": [
- "loong64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-mips64el": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz",
- "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==",
- "cpu": [
- "mips64el"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-ppc64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz",
- "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==",
- "cpu": [
- "ppc64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-riscv64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz",
- "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==",
- "cpu": [
- "riscv64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-s390x": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz",
- "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==",
- "cpu": [
- "s390x"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/linux-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz",
- "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "linux"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/netbsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz",
- "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "netbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/openbsd-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz",
- "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "openbsd"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/sunos-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz",
- "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "sunos"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/win32-arm64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz",
- "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==",
- "cpu": [
- "arm64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/win32-ia32": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz",
- "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==",
- "cpu": [
- "ia32"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/vite/node_modules/@esbuild/win32-x64": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz",
- "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==",
- "cpu": [
- "x64"
- ],
- "dev": true,
- "license": "MIT",
- "optional": true,
- "os": [
- "win32"
- ],
- "engines": {
- "node": ">=12"
- }
- },
"node_modules/vite/node_modules/@types/estree": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
- "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"dev": true,
"license": "MIT"
},
- "node_modules/vite/node_modules/esbuild": {
- "version": "0.21.5",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz",
- "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==",
- "dev": true,
- "hasInstallScript": true,
- "license": "MIT",
- "bin": {
- "esbuild": "bin/esbuild"
- },
- "engines": {
- "node": ">=12"
- },
- "optionalDependencies": {
- "@esbuild/aix-ppc64": "0.21.5",
- "@esbuild/android-arm": "0.21.5",
- "@esbuild/android-arm64": "0.21.5",
- "@esbuild/android-x64": "0.21.5",
- "@esbuild/darwin-arm64": "0.21.5",
- "@esbuild/darwin-x64": "0.21.5",
- "@esbuild/freebsd-arm64": "0.21.5",
- "@esbuild/freebsd-x64": "0.21.5",
- "@esbuild/linux-arm": "0.21.5",
- "@esbuild/linux-arm64": "0.21.5",
- "@esbuild/linux-ia32": "0.21.5",
- "@esbuild/linux-loong64": "0.21.5",
- "@esbuild/linux-mips64el": "0.21.5",
- "@esbuild/linux-ppc64": "0.21.5",
- "@esbuild/linux-riscv64": "0.21.5",
- "@esbuild/linux-s390x": "0.21.5",
- "@esbuild/linux-x64": "0.21.5",
- "@esbuild/netbsd-x64": "0.21.5",
- "@esbuild/openbsd-x64": "0.21.5",
- "@esbuild/sunos-x64": "0.21.5",
- "@esbuild/win32-arm64": "0.21.5",
- "@esbuild/win32-ia32": "0.21.5",
- "@esbuild/win32-x64": "0.21.5"
- }
- },
"node_modules/vite/node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
@@ -13927,14 +14489,43 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
+ "node_modules/vite/node_modules/postcss": {
+ "version": "8.5.3",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz",
+ "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.8",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
"node_modules/vite/node_modules/rollup": {
- "version": "4.18.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.0.tgz",
- "integrity": "sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==",
+ "version": "4.37.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.37.0.tgz",
+ "integrity": "sha512-iAtQy/L4QFU+rTJ1YUjXqJOJzuwEghqWzCEYD2FEghT7Gsy1VdABntrO4CLopA5IkflTyqNiLNwPcOJ3S7UKLg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@types/estree": "1.0.5"
+ "@types/estree": "1.0.6"
},
"bin": {
"rollup": "dist/bin/rollup"
@@ -13944,67 +14535,72 @@
"npm": ">=8.0.0"
},
"optionalDependencies": {
- "@rollup/rollup-android-arm-eabi": "4.18.0",
- "@rollup/rollup-android-arm64": "4.18.0",
- "@rollup/rollup-darwin-arm64": "4.18.0",
- "@rollup/rollup-darwin-x64": "4.18.0",
- "@rollup/rollup-linux-arm-gnueabihf": "4.18.0",
- "@rollup/rollup-linux-arm-musleabihf": "4.18.0",
- "@rollup/rollup-linux-arm64-gnu": "4.18.0",
- "@rollup/rollup-linux-arm64-musl": "4.18.0",
- "@rollup/rollup-linux-powerpc64le-gnu": "4.18.0",
- "@rollup/rollup-linux-riscv64-gnu": "4.18.0",
- "@rollup/rollup-linux-s390x-gnu": "4.18.0",
- "@rollup/rollup-linux-x64-gnu": "4.18.0",
- "@rollup/rollup-linux-x64-musl": "4.18.0",
- "@rollup/rollup-win32-arm64-msvc": "4.18.0",
- "@rollup/rollup-win32-ia32-msvc": "4.18.0",
- "@rollup/rollup-win32-x64-msvc": "4.18.0",
+ "@rollup/rollup-android-arm-eabi": "4.37.0",
+ "@rollup/rollup-android-arm64": "4.37.0",
+ "@rollup/rollup-darwin-arm64": "4.37.0",
+ "@rollup/rollup-darwin-x64": "4.37.0",
+ "@rollup/rollup-freebsd-arm64": "4.37.0",
+ "@rollup/rollup-freebsd-x64": "4.37.0",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.37.0",
+ "@rollup/rollup-linux-arm-musleabihf": "4.37.0",
+ "@rollup/rollup-linux-arm64-gnu": "4.37.0",
+ "@rollup/rollup-linux-arm64-musl": "4.37.0",
+ "@rollup/rollup-linux-loongarch64-gnu": "4.37.0",
+ "@rollup/rollup-linux-powerpc64le-gnu": "4.37.0",
+ "@rollup/rollup-linux-riscv64-gnu": "4.37.0",
+ "@rollup/rollup-linux-riscv64-musl": "4.37.0",
+ "@rollup/rollup-linux-s390x-gnu": "4.37.0",
+ "@rollup/rollup-linux-x64-gnu": "4.37.0",
+ "@rollup/rollup-linux-x64-musl": "4.37.0",
+ "@rollup/rollup-win32-arm64-msvc": "4.37.0",
+ "@rollup/rollup-win32-ia32-msvc": "4.37.0",
+ "@rollup/rollup-win32-x64-msvc": "4.37.0",
"fsevents": "~2.3.2"
}
},
"node_modules/vitest": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/vitest/-/vitest-1.6.0.tgz",
- "integrity": "sha512-H5r/dN06swuFnzNFhq/dnz37bPXnq8xB2xB5JOVk8K09rUtoeNN+LHWkoQ0A/i3hvbUKKcCei9KpbxqHMLhLLA==",
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz",
+ "integrity": "sha512-dfqAsNqRGUc8hB9OVR2P0w8PZPEckti2+5rdZip0WIz9WW0MnImJ8XiR61QhqLa92EQzKP2uPkzenKOAHyEIbA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@vitest/expect": "1.6.0",
- "@vitest/runner": "1.6.0",
- "@vitest/snapshot": "1.6.0",
- "@vitest/spy": "1.6.0",
- "@vitest/utils": "1.6.0",
- "acorn-walk": "^8.3.2",
- "chai": "^4.3.10",
- "debug": "^4.3.4",
- "execa": "^8.0.1",
- "local-pkg": "^0.5.0",
- "magic-string": "^0.30.5",
- "pathe": "^1.1.1",
- "picocolors": "^1.0.0",
- "std-env": "^3.5.0",
- "strip-literal": "^2.0.0",
- "tinybench": "^2.5.1",
- "tinypool": "^0.8.3",
- "vite": "^5.0.0",
- "vite-node": "1.6.0",
- "why-is-node-running": "^2.2.2"
+ "@vitest/expect": "3.0.8",
+ "@vitest/mocker": "3.0.8",
+ "@vitest/pretty-format": "^3.0.8",
+ "@vitest/runner": "3.0.8",
+ "@vitest/snapshot": "3.0.8",
+ "@vitest/spy": "3.0.8",
+ "@vitest/utils": "3.0.8",
+ "chai": "^5.2.0",
+ "debug": "^4.4.0",
+ "expect-type": "^1.1.0",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3",
+ "std-env": "^3.8.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^0.3.2",
+ "tinypool": "^1.0.2",
+ "tinyrainbow": "^2.0.0",
+ "vite": "^5.0.0 || ^6.0.0",
+ "vite-node": "3.0.8",
+ "why-is-node-running": "^2.3.0"
},
"bin": {
"vitest": "vitest.mjs"
},
"engines": {
- "node": "^18.0.0 || >=20.0.0"
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
"@edge-runtime/vm": "*",
- "@types/node": "^18.0.0 || >=20.0.0",
- "@vitest/browser": "1.6.0",
- "@vitest/ui": "1.6.0",
+ "@types/debug": "^4.1.12",
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "@vitest/browser": "3.0.8",
+ "@vitest/ui": "3.0.8",
"happy-dom": "*",
"jsdom": "*"
},
@@ -14012,6 +14608,9 @@
"@edge-runtime/vm": {
"optional": true
},
+ "@types/debug": {
+ "optional": true
+ },
"@types/node": {
"optional": true
},
@@ -14030,26 +14629,75 @@
}
},
"node_modules/vitest/node_modules/magic-string": {
- "version": "0.30.10",
- "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz",
- "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==",
+ "version": "0.30.17",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@jridgewell/sourcemap-codec": "^1.4.15"
+ "@jridgewell/sourcemap-codec": "^1.5.0"
}
},
- "node_modules/vue": {
- "version": "3.4.31",
- "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.31.tgz",
- "integrity": "sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==",
+ "node_modules/vscode-jsonrpc": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
+ "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/vscode-languageserver": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz",
+ "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==",
"license": "MIT",
"dependencies": {
- "@vue/compiler-dom": "3.4.31",
- "@vue/compiler-sfc": "3.4.31",
- "@vue/runtime-dom": "3.4.31",
- "@vue/server-renderer": "3.4.31",
- "@vue/shared": "3.4.31"
+ "vscode-languageserver-protocol": "3.17.5"
+ },
+ "bin": {
+ "installServerIntoExtension": "bin/installServerIntoExtension"
+ }
+ },
+ "node_modules/vscode-languageserver-protocol": {
+ "version": "3.17.5",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
+ "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
+ "license": "MIT",
+ "dependencies": {
+ "vscode-jsonrpc": "8.2.0",
+ "vscode-languageserver-types": "3.17.5"
+ }
+ },
+ "node_modules/vscode-languageserver-textdocument": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz",
+ "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==",
+ "license": "MIT"
+ },
+ "node_modules/vscode-languageserver-types": {
+ "version": "3.17.5",
+ "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
+ "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==",
+ "license": "MIT"
+ },
+ "node_modules/vscode-uri": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
+ "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==",
+ "license": "MIT"
+ },
+ "node_modules/vue": {
+ "version": "3.5.13",
+ "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.13.tgz",
+ "integrity": "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==",
+ "license": "MIT",
+ "dependencies": {
+ "@vue/compiler-dom": "3.5.13",
+ "@vue/compiler-sfc": "3.5.13",
+ "@vue/runtime-dom": "3.5.13",
+ "@vue/server-renderer": "3.5.13",
+ "@vue/shared": "3.5.13"
},
"peerDependencies": {
"typescript": "*"
@@ -14060,16 +14708,6 @@
}
}
},
- "node_modules/vue-bar-graph": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/vue-bar-graph/-/vue-bar-graph-2.0.0.tgz",
- "integrity": "sha512-IoYP+r5Ggjys6QdUNYFPh7qD41wi/uDOJj9nMawvDgvV6niOz3Dw8O2/98ZnUgjTpcgcGFDaaAaK6qa9x1jgpw==",
- "license": "MIT",
- "dependencies": {
- "gsap": "^3.10.4",
- "vue": "^3.2.37"
- }
- },
"node_modules/vue-chartjs": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.1.tgz",
@@ -14081,35 +14719,36 @@
}
},
"node_modules/vue-component-type-helpers": {
- "version": "2.0.24",
- "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.0.24.tgz",
- "integrity": "sha512-Jr5N8QVYEcbQuMN1LRgvg61758G8HTnzUlQsAFOxx6Y6X8kmhJ7C+jOvWsQruYxi3uHhhS6BghyRlyiwO99DBg==",
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/vue-component-type-helpers/-/vue-component-type-helpers-2.2.8.tgz",
+ "integrity": "sha512-4bjIsC284coDO9om4HPA62M7wfsTvcmZyzdfR0aUlFXqq4tXxM1APyXpNVxPC8QazKw9OhmZNHBVDA6ODaZsrA==",
"dev": true,
"license": "MIT"
},
"node_modules/vue-eslint-parser": {
- "version": "9.4.3",
- "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.4.3.tgz",
- "integrity": "sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-10.1.1.tgz",
+ "integrity": "sha512-bh2Z/Au5slro9QJ3neFYLanZtb1jH+W2bKqGHXAoYD4vZgNG3KeotL7JpPv5xzY4UXUXJl7TrIsnzECH63kd3Q==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
- "debug": "^4.3.4",
- "eslint-scope": "^7.1.1",
- "eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.1",
- "esquery": "^1.4.0",
+ "debug": "^4.4.0",
+ "eslint-scope": "^8.2.0",
+ "eslint-visitor-keys": "^4.2.0",
+ "espree": "^10.3.0",
+ "esquery": "^1.6.0",
"lodash": "^4.17.21",
- "semver": "^7.3.6"
+ "semver": "^7.6.3"
},
"engines": {
- "node": "^14.17.0 || >=16.0.0"
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"url": "https://github.com/sponsors/mysticatea"
},
"peerDependencies": {
- "eslint": ">=6.0.0"
+ "eslint": "^8.57.0 || ^9.0.0"
}
},
"node_modules/vue-loader": {
@@ -14148,9 +14787,9 @@
}
},
"node_modules/watchpack": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.1.tgz",
- "integrity": "sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==",
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz",
+ "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==",
"license": "MIT",
"dependencies": {
"glob-to-regexp": "^0.4.1",
@@ -14160,12 +14799,6 @@
"node": ">=10.13.0"
}
},
- "node_modules/web-worker": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.3.0.tgz",
- "integrity": "sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==",
- "license": "Apache-2.0"
- },
"node_modules/webidl-conversions": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
@@ -14177,21 +14810,20 @@
}
},
"node_modules/webpack": {
- "version": "5.92.1",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.92.1.tgz",
- "integrity": "sha512-JECQ7IwJb+7fgUFBlrJzbyu3GEuNBcdqr1LD7IbSzwkSmIevTm8PF+wej3Oxuz/JFBUZ6O1o43zsPkwm1C4TmA==",
+ "version": "5.98.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz",
+ "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==",
"license": "MIT",
"dependencies": {
- "@types/eslint-scope": "^3.7.3",
- "@types/estree": "^1.0.5",
- "@webassemblyjs/ast": "^1.12.1",
- "@webassemblyjs/wasm-edit": "^1.12.1",
- "@webassemblyjs/wasm-parser": "^1.12.1",
- "acorn": "^8.7.1",
- "acorn-import-attributes": "^1.9.5",
- "browserslist": "^4.21.10",
+ "@types/eslint-scope": "^3.7.7",
+ "@types/estree": "^1.0.6",
+ "@webassemblyjs/ast": "^1.14.1",
+ "@webassemblyjs/wasm-edit": "^1.14.1",
+ "@webassemblyjs/wasm-parser": "^1.14.1",
+ "acorn": "^8.14.0",
+ "browserslist": "^4.24.0",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.17.0",
+ "enhanced-resolve": "^5.17.1",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
@@ -14201,9 +14833,9 @@
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
"neo-async": "^2.6.2",
- "schema-utils": "^3.2.0",
+ "schema-utils": "^4.3.0",
"tapable": "^2.1.1",
- "terser-webpack-plugin": "^5.3.10",
+ "terser-webpack-plugin": "^5.3.11",
"watchpack": "^2.4.1",
"webpack-sources": "^3.2.3"
},
@@ -14224,42 +14856,39 @@
}
},
"node_modules/webpack-cli": {
- "version": "5.1.4",
- "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz",
- "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-6.0.1.tgz",
+ "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==",
"license": "MIT",
"dependencies": {
- "@discoveryjs/json-ext": "^0.5.0",
- "@webpack-cli/configtest": "^2.1.1",
- "@webpack-cli/info": "^2.0.2",
- "@webpack-cli/serve": "^2.0.5",
+ "@discoveryjs/json-ext": "^0.6.1",
+ "@webpack-cli/configtest": "^3.0.1",
+ "@webpack-cli/info": "^3.0.1",
+ "@webpack-cli/serve": "^3.0.1",
"colorette": "^2.0.14",
- "commander": "^10.0.1",
+ "commander": "^12.1.0",
"cross-spawn": "^7.0.3",
- "envinfo": "^7.7.3",
+ "envinfo": "^7.14.0",
"fastest-levenshtein": "^1.0.12",
"import-local": "^3.0.2",
"interpret": "^3.1.1",
"rechoir": "^0.8.0",
- "webpack-merge": "^5.7.3"
+ "webpack-merge": "^6.0.1"
},
"bin": {
"webpack-cli": "bin/cli.js"
},
"engines": {
- "node": ">=14.15.0"
+ "node": ">=18.12.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
- "webpack": "5.x.x"
+ "webpack": "^5.82.0"
},
"peerDependenciesMeta": {
- "@webpack-cli/generators": {
- "optional": true
- },
"webpack-bundle-analyzer": {
"optional": true
},
@@ -14268,18 +14897,27 @@
}
}
},
+ "node_modules/webpack-cli/node_modules/commander": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+ "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/webpack-merge": {
- "version": "5.10.0",
- "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz",
- "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz",
+ "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==",
"license": "MIT",
"dependencies": {
"clone-deep": "^4.0.1",
"flat": "^5.0.2",
- "wildcard": "^2.0.0"
+ "wildcard": "^2.0.1"
},
"engines": {
- "node": ">=10.0.0"
+ "node": ">=18.0.0"
}
},
"node_modules/webpack-sources": {
@@ -14293,36 +14931,11 @@
}
},
"node_modules/webpack/node_modules/@types/estree": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
- "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+ "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
"license": "MIT"
},
- "node_modules/webpack/node_modules/ajv": {
- "version": "6.12.6",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
- "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
- "license": "MIT",
- "dependencies": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- },
- "funding": {
- "type": "github",
- "url": "https://github.com/sponsors/epoberezkin"
- }
- },
- "node_modules/webpack/node_modules/ajv-keywords": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
- "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
- "license": "MIT",
- "peerDependencies": {
- "ajv": "^6.9.1"
- }
- },
"node_modules/webpack/node_modules/eslint-scope": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
@@ -14345,30 +14958,6 @@
"node": ">=4.0"
}
},
- "node_modules/webpack/node_modules/json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
- "license": "MIT"
- },
- "node_modules/webpack/node_modules/schema-utils": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz",
- "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
- "license": "MIT",
- "dependencies": {
- "@types/json-schema": "^7.0.8",
- "ajv": "^6.12.5",
- "ajv-keywords": "^3.5.2"
- },
- "engines": {
- "node": ">= 10.13.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/webpack"
- }
- },
"node_modules/webpack/node_modules/webpack-sources": {
"version": "3.2.3",
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
@@ -14420,41 +15009,45 @@
}
},
"node_modules/which-boxed-primitive": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz",
- "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz",
+ "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "is-bigint": "^1.0.1",
- "is-boolean-object": "^1.1.0",
- "is-number-object": "^1.0.4",
- "is-string": "^1.0.5",
- "is-symbol": "^1.0.3"
+ "is-bigint": "^1.1.0",
+ "is-boolean-object": "^1.2.1",
+ "is-number-object": "^1.1.1",
+ "is-string": "^1.1.1",
+ "is-symbol": "^1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/which-builtin-type": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz",
- "integrity": "sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz",
+ "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "function.prototype.name": "^1.1.5",
- "has-tostringtag": "^1.0.0",
+ "call-bound": "^1.0.2",
+ "function.prototype.name": "^1.1.6",
+ "has-tostringtag": "^1.0.2",
"is-async-function": "^2.0.0",
- "is-date-object": "^1.0.5",
- "is-finalizationregistry": "^1.0.2",
+ "is-date-object": "^1.1.0",
+ "is-finalizationregistry": "^1.1.0",
"is-generator-function": "^1.0.10",
- "is-regex": "^1.1.4",
+ "is-regex": "^1.2.1",
"is-weakref": "^1.0.2",
"isarray": "^2.0.5",
- "which-boxed-primitive": "^1.0.2",
- "which-collection": "^1.0.1",
- "which-typed-array": "^1.1.9"
+ "which-boxed-primitive": "^1.1.0",
+ "which-collection": "^1.0.2",
+ "which-typed-array": "^1.1.16"
},
"engines": {
"node": ">= 0.4"
@@ -14483,16 +15076,18 @@
}
},
"node_modules/which-typed-array": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz",
- "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==",
+ "version": "1.1.19",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz",
+ "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==",
"dev": true,
"license": "MIT",
"dependencies": {
"available-typed-arrays": "^1.0.7",
- "call-bind": "^1.0.7",
- "for-each": "^0.3.3",
- "gopd": "^1.0.1",
+ "call-bind": "^1.0.8",
+ "call-bound": "^1.0.4",
+ "for-each": "^0.3.5",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
"has-tostringtag": "^1.0.2"
},
"engines": {
@@ -14503,9 +15098,9 @@
}
},
"node_modules/why-is-node-running": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz",
- "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==",
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -14571,9 +15166,9 @@
}
},
"node_modules/wrap-ansi/node_modules/ansi-regex": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
- "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
"license": "MIT",
"engines": {
"node": ">=12"
@@ -14595,9 +15190,9 @@
}
},
"node_modules/wrap-ansi/node_modules/emoji-regex": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz",
- "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
+ "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
"license": "MIT"
},
"node_modules/wrap-ansi/node_modules/string-width": {
@@ -14636,6 +15231,7 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true,
"license": "ISC"
},
"node_modules/write-file-atomic": {
@@ -14673,9 +15269,9 @@
}
},
"node_modules/yaml": {
- "version": "2.4.5",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz",
- "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==",
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz",
+ "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==",
"license": "ISC",
"bin": {
"yaml": "bin.mjs"
diff --git a/package.json b/package.json
index 3c4d79f6a1..6c37136cd1 100644
--- a/package.json
+++ b/package.json
@@ -1,51 +1,49 @@
{
+ "name": "forgejo-aneksajo",
"type": "module",
"engines": {
- "node": ">= 18.0.0"
+ "node": ">= 20.0.0"
},
"dependencies": {
- "@citation-js/core": "0.7.11",
- "@citation-js/plugin-bibtex": "0.7.11",
- "@citation-js/plugin-csl": "0.7.11",
+ "@citation-js/core": "0.7.14",
+ "@citation-js/plugin-bibtex": "0.7.16",
"@citation-js/plugin-software-formats": "0.6.1",
"@github/markdown-toolbar-element": "2.2.3",
- "@github/relative-time-element": "4.4.2",
- "@github/text-expander-element": "2.7.1",
+ "@github/quote-selection": "2.1.0",
+ "@github/relative-time-element": "4.4.5",
+ "@github/text-expander-element": "2.8.0",
"@mcaptcha/vanilla-glue": "0.1.0-alpha-3",
- "@primer/octicons": "19.9.0",
- "add-asset-webpack-plugin": "2.0.1",
+ "@primer/octicons": "19.14.0",
"ansi_up": "6.0.2",
- "asciinema-player": "3.8.0",
- "chart.js": "4.4.2",
+ "asciinema-player": "3.8.2",
+ "chart.js": "4.4.5",
"chartjs-adapter-dayjs-4": "1.0.4",
- "chartjs-plugin-zoom": "2.0.1",
+ "chartjs-plugin-zoom": "2.2.0",
"clippie": "4.1.1",
"css-loader": "7.0.0",
- "dayjs": "1.11.11",
+ "dayjs": "1.11.12",
"dropzone": "6.0.0-beta.2",
"easymde": "2.18.0",
- "esbuild-loader": "4.1.0",
+ "esbuild-loader": "4.3.0",
"escape-goat": "4.0.0",
- "fast-glob": "3.3.2",
+ "fast-glob": "3.3.3",
"htmx.org": "1.9.12",
"idiomorph": "0.3.0",
"jquery": "3.7.1",
- "katex": "0.16.10",
- "license-checker-webpack-plugin": "0.2.1",
- "mermaid": "10.9.1",
- "mini-css-extract-plugin": "2.9.0",
- "minimatch": "9.0.5",
- "monaco-editor": "0.47.0",
+ "katex": "0.16.21",
+ "mermaid": "11.5.0",
+ "mini-css-extract-plugin": "2.9.2",
+ "minimatch": "10.0.1",
+ "monaco-editor": "0.52.2",
"monaco-editor-webpack-plugin": "7.1.0",
"pdfobject": "2.3.0",
- "postcss": "8.4.38",
+ "postcss": "8.5.2",
"postcss-loader": "8.1.1",
- "postcss-nesting": "12.1.5",
+ "postcss-nesting": "13.0.1",
"pretty-ms": "9.0.0",
- "sortablejs": "1.15.2",
+ "sortablejs": "1.15.6",
"swagger-ui-dist": "5.17.14",
- "tailwindcss": "3.4.4",
- "temporal-polyfill": "0.2.4",
+ "tailwindcss": "3.4.17",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tippy.js": "6.3.7",
@@ -53,49 +51,56 @@
"tributejs": "5.1.3",
"uint8-to-base64": "0.2.0",
"vanilla-colorful": "0.7.2",
- "vue": "3.4.31",
- "vue-bar-graph": "2.0.0",
+ "vue": "3.5.13",
"vue-chartjs": "5.3.1",
"vue-loader": "17.4.2",
"vue3-calendar-heatmap": "2.0.5",
- "webpack": "5.92.1",
- "webpack-cli": "5.1.4",
+ "webpack": "5.98.0",
+ "webpack-cli": "6.0.1",
"wrap-ansi": "9.0.0"
},
"devDependencies": {
- "@eslint-community/eslint-plugin-eslint-comments": "4.3.0",
- "@playwright/test": "1.45.0",
- "@stoplight/spectral-cli": "6.11.1",
- "@stylistic/eslint-plugin-js": "1.8.1",
- "@stylistic/stylelint-plugin": "2.1.2",
- "@vitejs/plugin-vue": "5.0.4",
- "@vitest/coverage-v8": "1.6.0",
+ "@axe-core/playwright": "4.10.1",
+ "@eslint-community/eslint-plugin-eslint-comments": "4.4.1",
+ "@playwright/test": "1.51.0",
+ "@stoplight/spectral-cli": "6.14.3",
+ "@stylistic/eslint-plugin-js": "4.2.0",
+ "@stylistic/stylelint-plugin": "3.1.2",
+ "@vitejs/plugin-vue": "5.2.3",
+ "@vitest/coverage-v8": "3.0.8",
+ "@vitest/eslint-plugin": "1.1.25",
"@vue/test-utils": "2.4.6",
- "eslint": "8.57.0",
- "eslint-plugin-array-func": "4.0.0",
- "eslint-plugin-github": "4.10.2",
- "eslint-plugin-i": "2.29.1",
- "eslint-plugin-jquery": "1.5.1",
- "eslint-plugin-no-jquery": "2.7.0",
- "eslint-plugin-no-use-extend-native": "0.5.0",
- "eslint-plugin-regexp": "2.6.0",
- "eslint-plugin-sonarjs": "0.25.1",
- "eslint-plugin-unicorn": "52.0.0",
- "eslint-plugin-vitest": "0.5.4",
+ "eslint": "9.22.0",
+ "eslint-import-resolver-typescript": "4.1.1",
+ "eslint-plugin-array-func": "5.0.2",
+ "eslint-plugin-import-x": "4.7.0",
+ "eslint-plugin-no-jquery": "3.1.1",
+ "eslint-plugin-no-use-extend-native": "0.7.2",
+ "eslint-plugin-playwright": "2.2.0",
+ "eslint-plugin-regexp": "2.7.0",
+ "eslint-plugin-sonarjs": "3.0.2",
+ "eslint-plugin-unicorn": "57.0.0",
+ "eslint-plugin-toml": "0.12.0",
"eslint-plugin-vitest-globals": "1.5.0",
- "eslint-plugin-vue": "9.26.0",
- "eslint-plugin-vue-scoped-css": "2.8.1",
- "eslint-plugin-wc": "2.1.0",
- "happy-dom": "14.12.3",
- "markdownlint-cli": "0.41.0",
- "postcss-html": "1.7.0",
- "stylelint": "16.6.1",
+ "eslint-plugin-vue": "10.0.0",
+ "eslint-plugin-vue-scoped-css": "2.9.0",
+ "eslint-plugin-wc": "2.2.1",
+ "globals": "16.0.0",
+ "happy-dom": "17.4.4",
+ "license-checker-rseidelsohn": "4.4.2",
+ "markdownlint-cli": "0.44.0",
+ "postcss-html": "1.8.0",
+ "stylelint": "16.16.0",
"stylelint-declaration-block-no-ignored-properties": "2.8.0",
- "stylelint-declaration-strict-value": "1.10.4",
+ "stylelint-declaration-strict-value": "1.10.11",
"stylelint-value-no-unknown-custom-properties": "6.0.1",
"svgo": "3.2.0",
+ "typescript": "5.7.3",
+ "typescript-eslint": "8.26.1",
"vite-string-plugin": "1.3.4",
- "vitest": "1.6.0"
+ "vitest": "3.0.8"
},
- "browserslist": ["defaults"]
+ "browserslist": [
+ "defaults"
+ ]
}
diff --git a/playwright.config.js b/playwright.config.ts
similarity index 71%
rename from playwright.config.js
rename to playwright.config.ts
index fdf6514f26..3906232abc 100644
--- a/playwright.config.js
+++ b/playwright.config.ts
@@ -1,7 +1,6 @@
-// @ts-check
-import {devices} from '@playwright/test';
+import {devices, type PlaywrightTestConfig} from '@playwright/test';
-const BASE_URL = process.env.GITEA_URL?.replace?.(/\/$/g, '') || 'http://localhost:3000';
+const BASE_URL = process.env.GITEA_URL?.replace?.(/\/$/g, '') || 'http://localhost:3003';
/**
* @see https://playwright.dev/docs/test-configuration
@@ -9,32 +8,30 @@ const BASE_URL = process.env.GITEA_URL?.replace?.(/\/$/g, '') || 'http://localho
*/
export default {
testDir: './tests/e2e/',
- testMatch: /.*\.test\.e2e\.js/, // Match any .test.e2e.js files
+ testMatch: /.*\.test\.e2e\.ts/, // Match any .test.e2e.js files
- /**
- * Only run one test at a time, running multiple could lead to a inconsistent
- * database state.
- */
- fullyParallel: false,
+ // you can adjust this value locally to match your machine's power,
+ // or pass `--workers x` to playwright
workers: 1,
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
-
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
- timeout: 2000,
+ timeout: 3000,
},
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: Boolean(process.env.CI),
/* Retry on CI only */
- retries: process.env.CI ? 2 : 0,
+ retries: process.env.CI ? 1 : 0,
+ /* fail fast */
+ maxFailures: process.env.CI ? 1 : 0,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: process.env.CI ? 'list' : [['list'], ['html', {outputFolder: 'tests/e2e/reports/', open: 'never'}]],
@@ -46,10 +43,10 @@ export default {
locale: 'en-US',
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
- actionTimeout: 1000,
+ actionTimeout: 3000,
/* Maximum time allowed for navigation, such as `page.goto()`. */
- navigationTimeout: 5 * 1000,
+ navigationTimeout: 10 * 1000,
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: BASE_URL,
@@ -68,6 +65,7 @@ export default {
/* Project-specific settings. */
use: {
...devices['Desktop Chrome'],
+ permissions: ['clipboard-read', 'clipboard-write'],
},
},
@@ -90,6 +88,7 @@ export default {
name: 'Mobile Chrome',
use: {
...devices['Pixel 5'],
+ permissions: ['clipboard-read', 'clipboard-write'],
},
},
{
@@ -100,8 +99,9 @@ export default {
},
],
- /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ /* Folder for test artifacts created during test execution such as screenshots, traces, etc. */
outputDir: 'tests/e2e/test-artifacts/',
- /* Folder for test artifacts such as screenshots, videos, traces, etc. */
+ /* Folder for explicit snapshots for visual testing */
snapshotDir: 'tests/e2e/test-snapshots/',
-};
+ snapshotPathTemplate: '{snapshotDir}/snapshots/{testFilePath}/{projectName}_{arg}{ext}',
+} satisfies PlaywrightTestConfig;
diff --git a/poetry.lock b/poetry.lock
index 7fe261074f..5cda33c903 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -2,13 +2,13 @@
[[package]]
name = "click"
-version = "8.1.7"
+version = "8.1.8"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
- {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
- {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
+ {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"},
+ {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"},
]
[package.dependencies]
@@ -16,13 +16,13 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "codespell"
-version = "2.3.0"
-description = "Codespell"
+version = "2.4.1"
+description = "Fix common misspellings in text files"
optional = false
python-versions = ">=3.8"
files = [
- {file = "codespell-2.3.0-py3-none-any.whl", hash = "sha256:a9c7cef2501c9cfede2110fd6d4e5e62296920efe9abfb84648df866e47f58d1"},
- {file = "codespell-2.3.0.tar.gz", hash = "sha256:360c7d10f75e65f67bad720af7007e1060a5d395670ec11a7ed1fed9dd17471f"},
+ {file = "codespell-2.4.1-py3-none-any.whl", hash = "sha256:3dadafa67df7e4a3dbf51e0d7315061b80d265f9552ebd699b3dd6834b47e425"},
+ {file = "codespell-2.4.1.tar.gz", hash = "sha256:299fcdcb09d23e81e35a671bbe746d5ad7e8385972e65dbb833a2eaac33c01e5"},
]
[package.extras]
@@ -44,12 +44,13 @@ files = [
[[package]]
name = "cssbeautifier"
-version = "1.15.1"
+version = "1.15.4"
description = "CSS unobfuscator and beautifier."
optional = false
python-versions = "*"
files = [
- {file = "cssbeautifier-1.15.1.tar.gz", hash = "sha256:9f7064362aedd559c55eeecf6b6bed65e05f33488dcbe39044f0403c26e1c006"},
+ {file = "cssbeautifier-1.15.4-py3-none-any.whl", hash = "sha256:78c84d5e5378df7d08622bbd0477a1abdbd209680e95480bf22f12d5701efc98"},
+ {file = "cssbeautifier-1.15.4.tar.gz", hash = "sha256:9bb08dc3f64c101a01677f128acf01905914cf406baf87434dcde05b74c0acf5"},
]
[package.dependencies]
@@ -59,69 +60,68 @@ six = ">=1.13.0"
[[package]]
name = "djlint"
-version = "1.34.1"
+version = "1.36.4"
description = "HTML Template Linter and Formatter"
optional = false
-python-versions = ">=3.8.0,<4.0.0"
+python-versions = ">=3.9"
files = [
- {file = "djlint-1.34.1-py3-none-any.whl", hash = "sha256:96ff1c464fb6f061130ebc88663a2ea524d7ec51f4b56221a2b3f0320a3cfce8"},
- {file = "djlint-1.34.1.tar.gz", hash = "sha256:db93fa008d19eaadb0454edf1704931d14469d48508daba2df9941111f408346"},
+ {file = "djlint-1.36.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a2dfb60883ceb92465201bfd392291a7597c6752baede6fbb6f1980cac8d6c5c"},
+ {file = "djlint-1.36.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4bc6a1320c0030244b530ac200642f883d3daa451a115920ef3d56d08b644292"},
+ {file = "djlint-1.36.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3164a048c7bb0baf042387b1e33f9bbbf99d90d1337bb4c3d66eb0f96f5400a1"},
+ {file = "djlint-1.36.4-cp310-cp310-win_amd64.whl", hash = "sha256:3196d5277da5934962d67ad6c33a948ba77a7b6eadf064648bef6ee5f216b03c"},
+ {file = "djlint-1.36.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d68da0ed10ee9ca1e32e225cbb8e9b98bf7e6f8b48a8e4836117b6605b88cc7"},
+ {file = "djlint-1.36.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c0478d5392247f1e6ee29220bbdbf7fb4e1bc0e7e83d291fda6fb926c1787ba7"},
+ {file = "djlint-1.36.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:962f7b83aee166e499eff916d631c6dde7f1447d7610785a60ed2a75a5763483"},
+ {file = "djlint-1.36.4-cp311-cp311-win_amd64.whl", hash = "sha256:53cbc450aa425c832f09bc453b8a94a039d147b096740df54a3547fada77ed08"},
+ {file = "djlint-1.36.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ff9faffd7d43ac20467493fa71d5355b5b330a00ade1c4d1e859022f4195223b"},
+ {file = "djlint-1.36.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:79489e262b5ac23a8dfb7ca37f1eea979674cfc2d2644f7061d95bea12c38f7e"},
+ {file = "djlint-1.36.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e58c5fa8c6477144a0be0a87273706a059e6dd0d6efae01146ae8c29cdfca675"},
+ {file = "djlint-1.36.4-cp312-cp312-win_amd64.whl", hash = "sha256:bb6903777bf3124f5efedcddf1f4716aef097a7ec4223fc0fa54b865829a6e08"},
+ {file = "djlint-1.36.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ead475013bcac46095b1bbc8cf97ed2f06e83422335734363f8a76b4ba7e47c2"},
+ {file = "djlint-1.36.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6c601dfa68ea253311deb4a29a7362b7a64933bdfcfb5a06618f3e70ad1fa835"},
+ {file = "djlint-1.36.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bda5014f295002363381969864addeb2db13955f1b26e772657c3b273ed7809f"},
+ {file = "djlint-1.36.4-cp313-cp313-win_amd64.whl", hash = "sha256:16ce37e085afe5a30953b2bd87cbe34c37843d94c701fc68a2dda06c1e428ff4"},
+ {file = "djlint-1.36.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:89678661888c03d7bc6cadd75af69db29962b5ecbf93a81518262f5c48329f04"},
+ {file = "djlint-1.36.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b01a98df3e1ab89a552793590875bc6e954cad661a9304057db75363d519fa0"},
+ {file = "djlint-1.36.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dabbb4f7b93223d471d09ae34ed515fef98b2233cbca2449ad117416c44b1351"},
+ {file = "djlint-1.36.4-cp39-cp39-win_amd64.whl", hash = "sha256:7a483390d17e44df5bc23dcea29bdf6b63f3ed8b4731d844773a4829af4f5e0b"},
+ {file = "djlint-1.36.4-py3-none-any.whl", hash = "sha256:e9699b8ac3057a6ed04fb90835b89bee954ed1959c01541ce4f8f729c938afdd"},
+ {file = "djlint-1.36.4.tar.gz", hash = "sha256:17254f218b46fe5a714b224c85074c099bcb74e3b2e1f15c2ddc2cf415a408a1"},
]
[package.dependencies]
-click = ">=8.0.1,<9.0.0"
-colorama = ">=0.4.4,<0.5.0"
-cssbeautifier = ">=1.14.4,<2.0.0"
-html-tag-names = ">=0.1.2,<0.2.0"
-html-void-elements = ">=0.1.0,<0.2.0"
-jsbeautifier = ">=1.14.4,<2.0.0"
-json5 = ">=0.9.11,<0.10.0"
-pathspec = ">=0.12.0,<0.13.0"
-PyYAML = ">=6.0,<7.0"
-regex = ">=2023.0.0,<2024.0.0"
-tomli = {version = ">=2.0.1,<3.0.0", markers = "python_version < \"3.11\""}
-tqdm = ">=4.62.2,<5.0.0"
+click = ">=8.0.1"
+colorama = ">=0.4.4"
+cssbeautifier = ">=1.14.4"
+jsbeautifier = ">=1.14.4"
+json5 = ">=0.9.11"
+pathspec = ">=0.12"
+pyyaml = ">=6"
+regex = ">=2023"
+tomli = {version = ">=2.0.1", markers = "python_version < \"3.11\""}
+tqdm = ">=4.62.2"
+typing-extensions = {version = ">=3.6.6", markers = "python_version < \"3.11\""}
[[package]]
name = "editorconfig"
-version = "0.12.4"
+version = "0.17.0"
description = "EditorConfig File Locator and Interpreter for Python"
optional = false
python-versions = "*"
files = [
- {file = "EditorConfig-0.12.4.tar.gz", hash = "sha256:24857fa1793917dd9ccf0c7810a07e05404ce9b823521c7dce22a4fb5d125f80"},
-]
-
-[[package]]
-name = "html-tag-names"
-version = "0.1.2"
-description = "List of known HTML tag names"
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
- {file = "html-tag-names-0.1.2.tar.gz", hash = "sha256:04924aca48770f36b5a41c27e4d917062507be05118acb0ba869c97389084297"},
- {file = "html_tag_names-0.1.2-py3-none-any.whl", hash = "sha256:eeb69ef21078486b615241f0393a72b41352c5219ee648e7c61f5632d26f0420"},
-]
-
-[[package]]
-name = "html-void-elements"
-version = "0.1.0"
-description = "List of HTML void tag names."
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
- {file = "html-void-elements-0.1.0.tar.gz", hash = "sha256:931b88f84cd606fee0b582c28fcd00e41d7149421fb673e1e1abd2f0c4f231f0"},
- {file = "html_void_elements-0.1.0-py3-none-any.whl", hash = "sha256:784cf39db03cdeb017320d9301009f8f3480f9d7b254d0974272e80e0cb5e0d2"},
+ {file = "EditorConfig-0.17.0-py3-none-any.whl", hash = "sha256:fe491719c5f65959ec00b167d07740e7ffec9a3f362038c72b289330b9991dfc"},
+ {file = "editorconfig-0.17.0.tar.gz", hash = "sha256:8739052279699840065d3a9f5c125d7d5a98daeefe53b0e5274261d77cb49aa2"},
]
[[package]]
name = "jsbeautifier"
-version = "1.15.1"
+version = "1.15.4"
description = "JavaScript unobfuscator and beautifier."
optional = false
python-versions = "*"
files = [
- {file = "jsbeautifier-1.15.1.tar.gz", hash = "sha256:ebd733b560704c602d744eafc839db60a1ee9326e30a2a80c4adb8718adc1b24"},
+ {file = "jsbeautifier-1.15.4-py3-none-any.whl", hash = "sha256:72f65de312a3f10900d7685557f84cb61a9733c50dcc27271a39f5b0051bf528"},
+ {file = "jsbeautifier-1.15.4.tar.gz", hash = "sha256:5bb18d9efb9331d825735fbc5360ee8f1aac5e52780042803943aa7f854f7592"},
]
[package.dependencies]
@@ -130,15 +130,18 @@ six = ">=1.13.0"
[[package]]
name = "json5"
-version = "0.9.25"
+version = "0.10.0"
description = "A Python implementation of the JSON5 data format."
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.8.0"
files = [
- {file = "json5-0.9.25-py3-none-any.whl", hash = "sha256:34ed7d834b1341a86987ed52f3f76cd8ee184394906b6e22a1e0deb9ab294e8f"},
- {file = "json5-0.9.25.tar.gz", hash = "sha256:548e41b9be043f9426776f05df8635a00fe06104ea51ed24b67f908856e151ae"},
+ {file = "json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa"},
+ {file = "json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559"},
]
+[package.extras]
+dev = ["build (==1.2.2.post1)", "coverage (==7.5.3)", "mypy (==1.13.0)", "pip (==24.3.1)", "pylint (==3.2.3)", "ruff (==0.7.3)", "twine (==5.1.1)", "uv (==0.5.1)"]
+
[[package]]
name = "pathspec"
version = "0.12.1"
@@ -152,217 +155,262 @@ files = [
[[package]]
name = "pyyaml"
-version = "6.0.1"
+version = "6.0.2"
description = "YAML parser and emitter for Python"
optional = false
-python-versions = ">=3.6"
+python-versions = ">=3.8"
files = [
- {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
- {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
- {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
- {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
- {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
- {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
- {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
- {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
- {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
- {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
- {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
- {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
- {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
- {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
- {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
- {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
- {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
- {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
- {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
- {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
- {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
- {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
- {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
- {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
- {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
- {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
- {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
- {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
- {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
- {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
- {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
- {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
- {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
- {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
- {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
- {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
- {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
- {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
- {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
- {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
- {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
- {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
- {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
- {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
- {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
- {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
- {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
- {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
- {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
+ {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
+ {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
+ {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
+ {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
+ {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
+ {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
+ {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
+ {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
+ {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
+ {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
+ {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
+ {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
+ {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
+ {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
+ {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
+ {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
+ {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
+ {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
+ {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
+ {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
+ {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
+ {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
+ {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
+ {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
+ {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
+ {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
+ {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
+ {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
+ {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
+ {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
+ {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
+ {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
+ {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
+ {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
+ {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
+ {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
+ {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
+ {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
+ {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
+ {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
+ {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
+ {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
+ {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
+ {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
+ {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
+ {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
+ {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
+ {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
+ {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
+ {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
+ {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
+ {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
+ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
]
[[package]]
name = "regex"
-version = "2023.12.25"
+version = "2024.11.6"
description = "Alternative regular expression module, to replace re."
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"},
- {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"},
- {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"},
- {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"},
- {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"},
- {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"},
- {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"},
- {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"},
- {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"},
- {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"},
- {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"},
- {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"},
- {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"},
- {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"},
- {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"},
- {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"},
- {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"},
- {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"},
- {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"},
- {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"},
- {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"},
- {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"},
- {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"},
- {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"},
- {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"},
- {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"},
- {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"},
- {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"},
- {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"},
- {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"},
- {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"},
- {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"},
- {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"},
- {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"},
- {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"},
- {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"},
- {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"},
- {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"},
- {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"},
- {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"},
- {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"},
- {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"},
- {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"},
- {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"},
- {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"},
- {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"},
- {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"},
- {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"},
- {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"},
- {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"},
- {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"},
- {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"},
- {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"},
- {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"},
- {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"},
- {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"},
- {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"},
- {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"},
- {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"},
- {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"},
- {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"},
- {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"},
- {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"},
- {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"},
- {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"},
- {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"},
- {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"},
- {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"},
- {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"},
- {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"},
- {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"},
- {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"},
- {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"},
- {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"},
- {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"},
- {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"},
- {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"},
- {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"},
- {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"},
- {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"},
- {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"},
- {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"},
- {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"},
- {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"},
- {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"},
- {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"},
- {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"},
- {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"},
- {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"},
- {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"},
- {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"},
- {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"},
- {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"},
+ {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"},
+ {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"},
+ {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"},
+ {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"},
+ {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"},
+ {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"},
+ {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"},
+ {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"},
+ {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"},
+ {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"},
+ {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"},
+ {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"},
+ {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"},
+ {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"},
+ {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"},
+ {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"},
+ {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"},
+ {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"},
+ {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"},
+ {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"},
+ {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"},
+ {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"},
+ {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"},
+ {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"},
+ {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"},
+ {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"},
+ {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"},
+ {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"},
+ {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"},
+ {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"},
+ {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"},
+ {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"},
+ {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"},
+ {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"},
+ {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"},
+ {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"},
+ {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"},
+ {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"},
+ {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"},
+ {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"},
+ {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"},
+ {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"},
+ {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"},
+ {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"},
+ {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"},
+ {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"},
+ {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"},
+ {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"},
+ {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"},
+ {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"},
+ {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"},
+ {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"},
+ {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"},
+ {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"},
+ {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"},
+ {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"},
+ {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"},
+ {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"},
+ {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"},
+ {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"},
+ {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"},
+ {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"},
+ {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"},
+ {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"},
+ {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"},
+ {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"},
+ {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"},
+ {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"},
+ {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"},
+ {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"},
+ {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"},
+ {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"},
+ {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"},
+ {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"},
+ {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"},
+ {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"},
+ {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"},
+ {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"},
+ {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"},
+ {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"},
+ {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"},
+ {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"},
+ {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"},
+ {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"},
+ {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"},
+ {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"},
+ {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"},
+ {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"},
+ {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"},
+ {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"},
+ {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"},
+ {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"},
+ {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"},
+ {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"},
]
[[package]]
name = "six"
-version = "1.16.0"
+version = "1.17.0"
description = "Python 2 and 3 compatibility utilities"
optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
files = [
- {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
- {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
+ {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
]
[[package]]
name = "tomli"
-version = "2.0.1"
+version = "2.2.1"
description = "A lil' TOML parser"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.8"
files = [
- {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
- {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
+ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"},
+ {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"},
+ {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"},
+ {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"},
+ {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"},
+ {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"},
+ {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"},
+ {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"},
+ {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"},
+ {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"},
+ {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"},
+ {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"},
+ {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"},
+ {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"},
+ {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"},
+ {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"},
+ {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"},
+ {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"},
+ {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"},
+ {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"},
+ {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"},
+ {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"},
+ {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"},
+ {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"},
+ {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"},
+ {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"},
+ {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"},
+ {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"},
+ {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"},
+ {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"},
+ {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"},
+ {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"},
]
[[package]]
name = "tqdm"
-version = "4.66.4"
+version = "4.67.1"
description = "Fast, Extensible Progress Meter"
optional = false
python-versions = ">=3.7"
files = [
- {file = "tqdm-4.66.4-py3-none-any.whl", hash = "sha256:b75ca56b413b030bc3f00af51fd2c1a1a5eac6a0c1cca83cbb37a5c52abce644"},
- {file = "tqdm-4.66.4.tar.gz", hash = "sha256:e4d936c9de8727928f3be6079590e97d9abfe8d39a590be678eb5919ffc186bb"},
+ {file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"},
+ {file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[package.extras]
-dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"]
+dev = ["nbval", "pytest (>=6)", "pytest-asyncio (>=0.24)", "pytest-cov", "pytest-timeout"]
+discord = ["requests"]
notebook = ["ipywidgets (>=6)"]
slack = ["slack-sdk"]
telegram = ["requests"]
[[package]]
-name = "yamllint"
-version = "1.35.1"
-description = "A linter for YAML files."
+name = "typing-extensions"
+version = "4.12.2"
+description = "Backported and Experimental Type Hints for Python 3.8+"
optional = false
python-versions = ">=3.8"
files = [
- {file = "yamllint-1.35.1-py3-none-any.whl", hash = "sha256:2e16e504bb129ff515b37823b472750b36b6de07963bd74b307341ef5ad8bdc3"},
- {file = "yamllint-1.35.1.tar.gz", hash = "sha256:7a003809f88324fd2c877734f2d575ee7881dd9043360657cc8049c809eba6cd"},
+ {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
+ {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
+]
+
+[[package]]
+name = "yamllint"
+version = "1.36.2"
+description = "A linter for YAML files."
+optional = false
+python-versions = ">=3.9"
+files = [
+ {file = "yamllint-1.36.2-py3-none-any.whl", hash = "sha256:6ba19800513d86c987ed3cf48c0aba4e82b3624596e1dab55723b3733e11f35c"},
+ {file = "yamllint-1.36.2.tar.gz", hash = "sha256:c9ccc818659736e7b13f7e2f9c3c9bb9ac77445be13e789e7d843e92cb8428ef"},
]
[package.dependencies]
@@ -375,4 +423,4 @@ dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"]
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
-content-hash = "758325127b0a863bf7d1f0dbc50e3740c47ffe0073ff60fc6d7dce9759879125"
+content-hash = "6e4e2a74db7e165f0aa8cae9bb8932cbe1e84ea9bef64db42371e6d620d77c93"
diff --git a/public/.well-known/security.txt b/public/.well-known/security.txt
index f301a00542..0ac9f09d34 100644
--- a/public/.well-known/security.txt
+++ b/public/.well-known/security.txt
@@ -1,8 +1,8 @@
# This site is running a Forgejo instance.
# Forgejo-related security problems should be reported to the Forgejo security team.
-# Site-related security problems should be reported to this site's admin.
-Policy: https://codeberg.org/forgejo/forgejo/src/branch/forgejo/CONTRIBUTING.md
+# Security problems related to this instance should be reported to its administration.
+Policy: https://codeberg.org/forgejo/governance/src/commit/5c07b3801537212ed6be1edfec298d7b004ce92d/SECURITY-POLICY.md
Contact: mailto:security@forgejo.org
Encryption: https://keys.openpgp.org/vks/v1/by-fingerprint/1B638BDF10969D627926B8D9F585D0F99E1FB56F
Preferred-Languages: en
-Expires: 2025-06-25T00:00:00Z
+Expires: 2026-07-16T23:59:59.000Z
diff --git a/public/assets/img/forgejo-loading.svg b/public/assets/img/forgejo-loading.svg
index 919552ebb5..f85fb37c8d 100644
--- a/public/assets/img/forgejo-loading.svg
+++ b/public/assets/img/forgejo-loading.svg
@@ -1,6 +1,6 @@
diff --git a/public/assets/img/svg/gitea-alt.svg b/public/assets/img/svg/gitea-alt.svg
new file mode 100644
index 0000000000..53e3f17c13
--- /dev/null
+++ b/public/assets/img/svg/gitea-alt.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/gitea-arch.svg b/public/assets/img/svg/gitea-arch.svg
new file mode 100644
index 0000000000..943a92c579
--- /dev/null
+++ b/public/assets/img/svg/gitea-arch.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-accessibility-inset.svg b/public/assets/img/svg/octicon-accessibility-inset.svg
index 2a728a9cf7..1ace41537d 100644
--- a/public/assets/img/svg/octicon-accessibility-inset.svg
+++ b/public/assets/img/svg/octicon-accessibility-inset.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-ai-model.svg b/public/assets/img/svg/octicon-ai-model.svg
new file mode 100644
index 0000000000..57d127bfaa
--- /dev/null
+++ b/public/assets/img/svg/octicon-ai-model.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-bookmark-filled.svg b/public/assets/img/svg/octicon-bookmark-filled.svg
new file mode 100644
index 0000000000..3ac73a5113
--- /dev/null
+++ b/public/assets/img/svg/octicon-bookmark-filled.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-bookmark-slash-fill.svg b/public/assets/img/svg/octicon-bookmark-slash-fill.svg
new file mode 100644
index 0000000000..bce2a0f0fe
--- /dev/null
+++ b/public/assets/img/svg/octicon-bookmark-slash-fill.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-file-media.svg b/public/assets/img/svg/octicon-file-media.svg
new file mode 100644
index 0000000000..6ee50b4d3e
--- /dev/null
+++ b/public/assets/img/svg/octicon-file-media.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-home-fill.svg b/public/assets/img/svg/octicon-home-fill.svg
new file mode 100644
index 0000000000..c030a0fddf
--- /dev/null
+++ b/public/assets/img/svg/octicon-home-fill.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-sparkles-fill.svg b/public/assets/img/svg/octicon-sparkles-fill.svg
new file mode 100644
index 0000000000..0ca70c1d39
--- /dev/null
+++ b/public/assets/img/svg/octicon-sparkles-fill.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-tab.svg b/public/assets/img/svg/octicon-tab.svg
new file mode 100644
index 0000000000..71de3e1c35
--- /dev/null
+++ b/public/assets/img/svg/octicon-tab.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-thumbsdown.svg b/public/assets/img/svg/octicon-thumbsdown.svg
index f64457ec51..76a6c072b7 100644
--- a/public/assets/img/svg/octicon-thumbsdown.svg
+++ b/public/assets/img/svg/octicon-thumbsdown.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/assets/img/svg/octicon-thumbsup.svg b/public/assets/img/svg/octicon-thumbsup.svg
index 1afc4ba99b..64f5cf9d71 100644
--- a/public/assets/img/svg/octicon-thumbsup.svg
+++ b/public/assets/img/svg/octicon-thumbsup.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index cfcc44c4c3..eb3b338794 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,23 +5,22 @@ package-mode = false
python = "^3.10"
[tool.poetry.group.dev.dependencies]
-djlint = "1.34.1"
-yamllint = "1.35.1"
-codespell = "^2.2.6"
+djlint = "1.36.4"
+yamllint = "1.36.2"
+codespell = "2.4.1"
[tool.djlint]
profile="golang"
ignore="H005,H006,H013,H016,H020,H021,H030,H031"
[tool.codespell]
-skip = '.git,*.pdf,*.svg,package-lock.json,go.mod,locale,license,*.git,objects,*.fr-fr.*,*.de-de.*,*.css,go.sum,*.key,gitignore,pyproject.toml,diff_test.go,go-licenses.json,pyproject.toml,*.lock,venvs'
+skip = '.git,*.pdf,*.svg,package-lock.json,go.mod,locale,locale_next,license,*.git,objects,*.fr-fr.*,*.de-de.*,*.css,go.sum,*.key,gitignore,pyproject.toml,diff_test.go,go-licenses.json,pyproject.toml,*.lock,venvs,node_modules,plural_rules.go,testdata,disposable_email_domain_data.go'
# precise hits for CamelCased words,various other curious cases which require regex to ignore
# entire line or some portion of it
# TODO: Resolve Treshold typo in API and remove from here
-ignore-regex = '(\b(Treshold|mx claus|commitT|ReadBy|#afile|respOne|commitI|[cC]rossReference)\b|shouldbe\.|womenโs.*womens|"emoji":.*|,bu,|assert\.Equal.*"fo\b|github\.com/unknwon|Copyright 2014 Unknwon|allowed\.noone|[hH]eadErr|atLeast|{"\\U.*)|Iif|FilterIn|.*codespell-ignore.*'
-#|.*(Maskenpflicht|Geimpft),.*)'
+ignore-regex = '(\b(Treshold|mx claus|commitT|ReadBy|#afile|respOne|commitI|[cC]rossReference|SMove|reVer|CheckIn|NotIn)\b|shouldbe\.|womenโs.*womens|"emoji":.*|,bu,|assert\.Equal.*"fo\b|github\.com/unknwon|Copyright 2014 Unknwon|allowed\.noone|[hH]eadErr|atLeast|{"\\U.*)|Iif|FilterIn|ZiSe'
# te - TreeEntry variable
# commiter - wrong spelling but seems used in API
# ALLWAYS - is a config var
# infact - other variable(s)
-ignore-words-list = 'crate,te,commiter,befores,allways,infact,startd,unknow'
+ignore-words-list = 'bleve,crate,te,commiter,befores,allways,infact,startd,unknow'
diff --git a/release-notes-assistant.sh b/release-notes-assistant.sh
new file mode 100755
index 0000000000..89fd0833f5
--- /dev/null
+++ b/release-notes-assistant.sh
@@ -0,0 +1,305 @@
+#!/bin/bash
+# Copyright twenty-panda
+# SPDX-License-Identifier: MIT
+
+label_worth=worth
+label_bug=bug
+label_feature=feature
+label_ui=forgejo/ui
+label_breaking=breaking
+label_security=security
+label_localization=forgejo/i18n
+
+payload=$(mktemp)
+pr=$(mktemp)
+trap "rm $payload $pr" EXIT
+
+function test_main() {
+ set -ex
+ PS4='${BASH_SOURCE[0]}:$LINENO: ${FUNCNAME[0]}: '
+
+ test_payload_labels $label_worth $label_breaking $label_security $label_bug
+ test "$(categorize)" = 'AA Breaking security bug fixes'
+
+ test_payload_labels $label_worth $label_security $label_bug
+ test "$(categorize)" = 'AB Security bug fixes'
+
+ test_payload_labels $label_worth $label_breaking $label_security $label_feature
+ test "$(categorize)" = 'AC Breaking security features'
+
+ test_payload_labels $label_worth $label_security $label_feature
+ test "$(categorize)" = 'AD Security features'
+
+ test_payload_labels $label_worth $label_security
+ test "$(categorize)" = 'ZA Security changes without a feature or bug label'
+
+ test_payload_labels $label_worth $label_breaking $label_feature
+ test "$(categorize)" = 'BA Breaking features'
+
+ test_payload_labels $label_worth $label_breaking $label_bug
+ test "$(categorize)" = 'BB Breaking bug fixes'
+
+ test_payload_labels $label_worth $label_breaking
+ test "$(categorize)" = 'ZB Breaking changes without a feature or bug label'
+
+ test_payload_labels $label_worth $label_ui $label_feature
+ test "$(categorize)" = 'CA User Interface features'
+
+ test_payload_labels $label_worth $label_ui $label_bug
+ test "$(categorize)" = 'CB User Interface bug fixes'
+
+ test_payload_labels $label_worth $label_ui
+ test "$(categorize)" = 'ZC User Interface changes without a feature or bug label'
+
+ test_payload_labels $label_worth $label_localization
+ test "$(categorize)" = 'DA Localization'
+
+ test_payload_labels $label_worth $label_feature
+ test "$(categorize)" = 'EA Features'
+
+ test_payload_labels $label_worth $label_bug
+ test "$(categorize)" = 'EB Bug fixes'
+
+ test_payload_labels $label_worth
+ test "$(categorize)" = 'ZE Other changes without a feature or bug label'
+
+ test_payload_labels
+ test "$(categorize)" = 'ZF Included for completeness but not worth a release note'
+
+ test_payload_draft "fix(security)!: breaking security bug fix"
+ test "$(categorize)" = 'AA Breaking security bug fixes'
+
+ test_payload_draft "fix(security): security bug fix"
+ test "$(categorize)" = 'AB Security bug fixes'
+
+ test_payload_draft "feat!: breaking feature"
+ test "$(categorize)" = 'BA Breaking features'
+
+ test_payload_draft "fix!: breaking bug fix"
+ test "$(categorize)" = 'BB Breaking bug fixes'
+
+ test_payload_draft "feat: feature"
+ test "$(categorize)" = 'EA Features'
+
+ test_payload_draft "fix: bug fix"
+ test "$(categorize)" = 'EB Bug fixes'
+
+ test_payload_draft "something with no prefix"
+ test "$(categorize)" = 'ZE Other changes without a feature or bug label'
+}
+
+function main() {
+ cat >$payload
+ categorize
+}
+
+function categorize() {
+ #
+ # If this is a backport, refer to the original PR to figure
+ # out the classification.
+ #
+ if $(jq --raw-output .IsBackportedFrom <$payload); then
+ jq --raw-output '.BackportedFrom[0]' <$payload >$pr
+ else
+ jq --raw-output '.Pr' <$payload >$pr
+ fi
+
+ labels=$(jq --raw-output '.labels[].name' <$pr)
+
+ #
+ # Was this PR labeled `worth a release note`?
+ #
+ if echo "$labels" | grep --quiet $label_worth; then
+ worth=true
+ else
+ worth=false
+ fi
+
+ #
+ # If there was no release-notes/N.md file and it is not
+ # worth a release note, just forget about it.
+ #
+ if test -z "$(jq --raw-output .Draft <$payload)"; then
+ if ! $worth; then
+ echo -n ZF Included for completeness but not worth a release note
+ exit 0
+ fi
+ fi
+
+ is_ui=false
+ is_bug=false
+ is_feature=false
+ is_localization=false
+ is_breaking=false
+ is_security=false
+
+ #
+ # first try to figure out the category from the labels
+ #
+ case "$labels" in
+ *$label_bug*)
+ is_bug=true
+ ;;
+ *$label_feature*)
+ is_feature=true
+ ;;
+ *$label_localization*)
+ is_localization=true
+ ;;
+ esac
+
+ case "$labels" in
+ *$label_security*)
+ is_security=true
+ ;;
+ esac
+
+ case "$labels" in
+ *$label_breaking*)
+ is_breaking=true
+ ;;
+ esac
+
+ case "$labels" in
+ *$label_ui*)
+ is_ui=true
+ ;;
+ esac
+
+ #
+ # then try the prefix of the release note
+ #
+ if ! $is_bug && ! $is_feature; then
+ draft="$(jq --raw-output .Draft <$payload)"
+ case "$draft" in
+ fix\(security\)!:*)
+ is_bug=true
+ is_breaking=true
+ is_security=true
+ ;;
+ fix\(security\):*)
+ is_bug=true
+ is_security=true
+ ;;
+ fix!:*)
+ is_bug=true
+ is_breaking=true
+ ;;
+ fix:*)
+ is_bug=true
+ ;;
+ feat!:*)
+ is_feature=true
+ is_breaking=true
+ ;;
+ feat:*)
+ is_feature=true
+ ;;
+ esac
+ fi
+
+ if $is_bug; then
+ if $(jq --raw-output .IsBackportedTo <$payload); then
+ #
+ # if it has been backported, it was in the release notes of an older stable release
+ # and does not need to be in this more recent release notes
+ #
+ echo -n ZG Already announced in the release notes of an older stable release
+ exit 0
+ fi
+ fi
+
+ if $is_security; then
+ if $is_bug; then
+ if $is_breaking; then
+ echo -n AA Breaking security bug fixes
+ else
+ echo -n AB Security bug fixes
+ fi
+ elif $is_feature; then
+ if $is_breaking; then
+ echo -n AC Breaking security features
+ else
+ echo -n AD Security features
+ fi
+ else
+ echo -n ZA Security changes without a feature or bug label
+ fi
+ elif $is_breaking; then
+ if $is_feature; then
+ echo -n BA Breaking features
+ elif $is_bug; then
+ echo -n BB Breaking bug fixes
+ else
+ echo -n ZB Breaking changes without a feature or bug label
+ fi
+ elif $is_ui; then
+ if $is_feature; then
+ echo -n CA User Interface features
+ elif $is_bug; then
+ echo -n CB User Interface bug fixes
+ else
+ echo -n ZC User Interface changes without a feature or bug label
+ fi
+ elif $is_localization; then
+ echo -n DA Localization
+ else
+ if $is_feature; then
+ echo -n EA Features
+ elif $is_bug; then
+ echo -n EB Bug fixes
+ else
+ echo -n ZE Other changes without a feature or bug label
+ fi
+ fi
+}
+
+function test_payload_labels() {
+ local label1="$1"
+ local label2="$2"
+ local label3="$3"
+ local label4="$4"
+
+ cat >$payload <$payload <
+
+## Release notes
+
+- Security bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): fix(security): [commit](https://codeberg.org/forgejo/forgejo/commit/45435a8789f8ff69603799a9031246d2d621d139) Fix and refactor markdown rendering
+- Security features
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6074): migrate TOTP secrets to `keying`
+- Breaking bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6240): Ensure `source_id` parameter is not skipped when set to 0 and correctly filter users in `/api/v1/admin/users` endpoint
+- User Interface features
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6407) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6423)): Rework user profile settings
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6386) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6399)): Rework new repository dialog
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6344): Show repository size on mobile
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6274): Add links to commit lists in contributors graph page
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6079): Add copy path button to file view
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6044): Put issue actions in a single row on mobile
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6018): Don't display email in profile settings when hidden
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5899): Highlight user mention in comments and commit messages
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5819): When [bleve is used for issue search](https://forgejo.org/docs/next/admin/config-cheat-sheet/#indexer-indexer), a `fuzzy` search now applies to each word instead of all of them, as if they were a phrase. For instance, searching for `activitypub spam moderation` previously [returned no result in Forgejo discussions](https://v9.next.forgejo.org/snematoda/forgejo-discussions/issues?state=open&type=all&q=activitypub+spam+moderation&fuzzy=true) and now returns the [relevant issues](https://codeberg.org/forgejo/discussions/issues?state=open&type=all&q=activitypub+spam+moderation&fuzzy=true). If the search results are too broad, or for searching exact phrases prefer using an `exact` search. Sorting by newest is still available as a non default option under `Sort`. The query was also reworked to improve performances. It makes a significant difference for large instances such as Codeberg.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5777): Add search to releases page
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5695): Combine review requests comments
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5677): If you select a portion of a comment and use the 'Quote reply' feature in the context menu, only that portion will be quoted. The markdown syntax is preserved.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5593): Set "your repositories" as the default filter for org dashboards
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5589): Add button to create a Markdown table in a comment
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5518): Add a bullet symbol between author and committer
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4125): Added link to show all Issues/PullRequests
+- User Interface bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6122): Fix Action log UI race condition that occasionally prevents logs from loading
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6063): Fix wiki search overflowing on wide screens
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5838): Move "forgot_password"-link to fix login tab order
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5697): Update help links on page with no workflows
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6072): Add Low German to list of default languages
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5786): i18n: Add dummy language for checking translation keys (#5785)
+ - Updates from Codeberg Translate: [[1]](https://codeberg.org/forgejo/forgejo/pulls/6566), [[2]](https://codeberg.org/forgejo/forgejo/pulls/6514), [[3]](https://codeberg.org/forgejo/forgejo/pulls/6378) ([backport](https://codeberg.org/forgejo/forgejo/pulls/6450)), [[4]](https://codeberg.org/forgejo/forgejo/pulls/6331) ([backport](https://codeberg.org/forgejo/forgejo/pulls/6377)), [[5]](https://codeberg.org/forgejo/forgejo/pulls/6242), [[6]](https://codeberg.org/forgejo/forgejo/pulls/6161), [[7]](https://codeberg.org/forgejo/forgejo/pulls/6091), [[8]](https://codeberg.org/forgejo/forgejo/pulls/6041), [[9]](https://codeberg.org/forgejo/forgejo/pulls/5960), [[10]](https://codeberg.org/forgejo/forgejo/pulls/5845), [[11]](https://codeberg.org/forgejo/forgejo/pulls/5754), [[12]](https://codeberg.org/forgejo/forgejo/pulls/5681), [[13]](https://codeberg.org/forgejo/forgejo/pulls/5583)
+
+- Features
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6448): Add summary card for repos and releases
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6271): [commit](https://codeberg.org/forgejo/forgejo/commit/b0d6a7f07bff836190a8e87fe5645d5557893e32) Implement update branch API
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6265): Allow changing default branch update style
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6228): Add sorting functionality to `/api/v1/admin/users` endpoint
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6200): [commit](https://codeberg.org/forgejo/forgejo/commit/0786ddc5de37a01d1c3e3bf99b794665341b3c12) Add Swift login endpoint
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6180): Add support for `pacman -F` in Arch package
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6170): Make LFS http_client parallel within a batch
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6146): Improve performance of notifications page for MySQL
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6143): Filepath filter for code search
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6112): Add option to disable builtin authentication
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6110): [commit](https://codeberg.org/forgejo/forgejo/commit/3973f1022d57a3134e8f775e1c1cc6d398681bb4) Add github compatible tarball download API endpoints
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6100): Improve performance of allowed org repo creation query
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6062): [commit](https://codeberg.org/forgejo/forgejo/commit/ddabba5f89c4b196daeeb2af17de9ec2cec14b63) Allow the actions user to login via the jwt token
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6053): Add a "summary card" to issues & PRs for consumption by OpenGraph clients
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/dd3c4d7096cff91854bcc6641f55d9d093e5c86e) Add a doctor check to disable the "Actions" unit for mirrors
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5940): Make AVIF Images work with Forgejo
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5822): Trim spaces from repo names on form submission
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/1e595979625e54d375a0eaa440b84ef5e17af160) Add new [lfs_client].BATCH_SIZE and [server].LFS_MAX_BATCH_SIZE config settings.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5787): Add setting to block disposable emails
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5751): mermaid: [Add the Kanban board diagram type](https://github.com/mermaid-js/mermaid/pull/5999).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5751): mermaid: [Class diagram includes a new "classBox" shape, classDef statement, support for styling the default class and lollipop interfaces](https://github.com/mermaid-js/mermaid/pull/5880).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5714): [commit](https://codeberg.org/forgejo/forgejo/commit/ab660c5944d59cdb4ecc071401445ac9f53cee45) Add `DISABLE_ORGANIZATIONS_PAGE` and `DISABLE_CODE_PAGE` settings for explore pages
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5689): Add branch deletion for scheduled PRs
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/c3741d7fb0114691da73f00ae0ac9dced87e884d) The `requested_reviewers` data is included in more webhook events.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/89446e60a6e7ec3441f0c480164c09851ae54ce7) Support migrating GitHub/GitLab PR draft status.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5601): Language detection in the repository learned about the following languages: [Java Template Engine](https://github.com/github-linguist/linguist/pull/6610), [Noir](https://github.com/github-linguist/linguist/pull/6432), [Cylc](https://github.com/github-linguist/linguist/pull/6832), [iCalendar](https://github.com/github-linguist/linguist/pull/6940), [vCard (aka. VCF: Virtual Contact File) and Variant Call Format (VCF)](https://github.com/github-linguist/linguist/pull/6941), [B4X](https://github.com/github-linguist/linguist/pull/6965), [Carbon](https://github.com/github-linguist/linguist/pull/7011), [LiveCode Script](https://github.com/github-linguist/linguist/pull/6833), [Dune (OCaml build system)](https://github.com/github-linguist/linguist/pull/6814).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5601): The following extensions or filenames in a repository are associated with the matching language: [deno.lock](https://github.com/github-linguist/linguist/pull/6885), [uv.lock](https://github.com/github-linguist/linguist/pull/7006), [HOSTS.TXT](https://github.com/github-linguist/linguist/pull/7014), [.peggy](https://github.com/github-linguist/linguist/pull/7017), [.resource](https://github.com/github-linguist/linguist/pull/6500).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5543): [commit](https://codeberg.org/forgejo/forgejo/commit/d0af8fe4dc7b294fe5409b2271468494267d5a7d) Allow filtering pull requests by poster in the API.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5477): [commit](https://codeberg.org/forgejo/forgejo/commit/af901ac7bb03d27f175f2292581fc67fa9c8d567) Add support for searching users by email.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5459): New mermaid [flowchart shapes](https://mermaid.js.org/syntax/flowchart.html#complete-list-of-new-shapes).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5416): [commit](https://codeberg.org/forgejo/forgejo/commit/8178d6eaba64d05799fd3b62fa889bd13bee07c7) Code search results when using the bleve indexer are sorted by relevance.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/9d3473119893ffde0ab36d98e7a0e41c5d0ba9a3) Add bin to Composer Metadata.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4968): Support regexp in git-grep search
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4753): Git notes can be modified via the API or the UI
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6343): avoid Gitea migration warnings
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6329): maven package where actual pom has no group-id defined, fallback to parent group-id
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6271): [commit](https://codeberg.org/forgejo/forgejo/commit/96a7f0a3f065c5db8fdf352c93c8367e24d259de) Fix missing outputs for jobs with matrix
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6271): [commit](https://codeberg.org/forgejo/forgejo/commit/2b5c69c451a684b20119e2521dc23734c7869241) Detect whether action view branch was deleted
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6271): [commit](https://codeberg.org/forgejo/forgejo/commit/bf934c96c92d643678ac7a18697b6563bc9d20a5) Add standard-compliant route to serve outdated R packages
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6105): Fix unconditional DB queries in commit status fetches
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6062): [commit](https://codeberg.org/forgejo/forgejo/commit/32a91add34519ef7768ec907888ed837ad0dde2f) Fix GetInactiveUsers
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6062): [commit](https://codeberg.org/forgejo/forgejo/commit/64824290912b6300ede2b2f95ff77d55dde9859b) Fix submodule parsing
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6062): [commit](https://codeberg.org/forgejo/forgejo/commit/ddabba5f89c4b196daeeb2af17de9ec2cec14b63) allow the actions user to login via the jwt token
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/a8f2002a9b061ec1092df67c6f05e30aa7d2e2d2) Remove transaction for archive download
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/96ee0f56475204b2bbdc7f2aeb35b1c32eac469c) Fix oauth2 error handle not return immediately
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/c2e8790df37a14b4d2f72c7377db75309e0ebf1d) Trim title before insert/update to database to match the size requirements of database
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/03ab73d92eabaf774278effe3332623b1dc3580a) Fix nil panic if repo doesn't exist
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/56971f9ed90a01fd74a634b7496593e6f62ac260) Disable Oauth check if oauth disabled
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5997): [commit](https://codeberg.org/forgejo/forgejo/commit/56971f9ed90a01fd74a634b7496593e6f62ac260) Disable OAuth check if OAuth disabled
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5988): [commit](https://codeberg.org/forgejo/forgejo/commit/fc26becba4b08877a726f2e7e453992310245fe5) When a tag was removed and a release existed for that tag, it would be broken. The release is no longer broken the tag can be added again.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5811): Escaping specific markdown in commit messages on Discord-type embeds
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/362ad0ba39bdbc87202e349678e21fc2a75ff7cb) Update force-pushed tags too when syncing mirrors
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/4c5bdddf7751a35985c08ba6506f1f30103749d6) Fix `missing signature key` error when pulling Docker images with `SERVE_DIRECT` enabled
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/2c5fdb108ff9e23e8f907fb6afe59177c6bb202e) Fix the missing menu in organization project view page
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): [commit](https://codeberg.org/forgejo/forgejo/commit/2358c0d899faec8311e46dcb0550041496bcd532) Properly clean temporary index files
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5781): Preview picture not visible on Markdown file
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5714): [commit](https://codeberg.org/forgejo/forgejo/commit/d13a4ab5632d6a9697bd0907f9c69ed57d949340) Fixed a bug related to disabling two-factor authentication
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/f3f386545ee97b91f1aaac4142480e70a443c655) Always update expiration time when creating an artifact, so that artifacts from re-ran jobs do not get lost.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/c163bf6fb55c922ab0cf552b47475fc8fc8b99d9) Remove the button toolbar when deleting a diff comment.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5621): [commit](https://codeberg.org/forgejo/forgejo/commit/e8700cee612f0aa769dc6929772d9b04c6c21807) Run scheduled tasks against the latest commit.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5517): Allow Organisations to remove the Email Address
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5477): [commit](https://codeberg.org/forgejo/forgejo/commit/1dfe58ad11bc6fdc73a2b5ffb3c1481fbddbf46b) PR creation on forked repositories.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5477): [commit](https://codeberg.org/forgejo/forgejo/commit/b67b7c12385059898fc8cb7997755a88b3afa483) The logic of finding the latest pull review commit ID is incorrect.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5416): [commit](https://codeberg.org/forgejo/forgejo/commit/b496317b5a2aea970bc94ccf6fcde35cd417ec20) After migrating a repository that contains merged pull requests, the branch is missing and cannot be deleted.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5416): [commit](https://codeberg.org/forgejo/forgejo/commit/a226064711899da07d6b1455a68ef758f2f3e7e0) Forgejo Actions artifact v4 upload above 8MB.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5307): Don't allow modification to internal reference
+- Other changes without a feature or bug label
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5789): chore: [commit](https://codeberg.org/forgejo/forgejo/commit/b308bcca7c950b7f0d127ee4282019c2a9923299) Improved diff view performance
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5714): chore: [commit](https://codeberg.org/forgejo/forgejo/commit/ab26d880932dbc116c43ea277029984c7a6d4e94) Emit a log message when failing to delete an inactive user
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6553): Update module github.com/alecthomas/chroma/v2 to v2.15.0 (v10.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6513) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6517)): Add lock for parallel maven upload
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6496): Update module github.com/go-git/go-git/v5 to v5.13.1 (v10.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6491) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6493)): fix: upgrade gof3 package and driver
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6488) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6492)): chore: remove illegal git usage
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6463) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6465)): fix(ui): show oauth divider on signup page
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6432) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6444)): Fix editing pr review
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6441) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6442)): fix(code search): empty mode dropdown when keyword is empty
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6427) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6430)): fix(ui): use primary color for button in table modal
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6421) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6426)): Fix edit cancel button
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6419) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6424)): Fix issue/comment menus
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6403) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6420)): chore(branding): strip metadata information from the footer
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6410) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6418)): fix: use DateUtils for blocked users list
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6391) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6416)): [gitea] week 2024-53 cherry pick (gitea/main -> forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6405) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6406)): fix: xorm needs to be lowercase otherwise it is ignored
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6401) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6402)): Cosmetic changes and fixes around repo homepage
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6286) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6398)): feat: When comparing in repos, mention that pull request creation requires sign-in
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6390) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6392)): Fix overflow in git notes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6372) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6382)): Revert "Update dependency idiomorph to v0.4.0"
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6375) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6376)): chore(i18n): user/label translations in danish/latvian
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6368): harden keying implementation
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6367): Update dependency webpack-cli to v6 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6366): Update linters (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6365): Update dependency djlint to v1.36.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6364): Update dependency @vitest/eslint-plugin to v1.1.20 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6363): Update github.com/shurcooL/vfsgen digest to 0000e14 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6357): chore(docs): explain vars.SKIP_END_TO_END when building a release
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6355): Update dependency idiomorph to v0.4.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6354): Update module google.golang.org/protobuf to v1.36.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6349): Lock file maintenance (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6348): Update module github.com/go-testfixtures/testfixtures/v3 to v3.14.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6347): Update renovate Docker tag to v39.82.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6342): [gitea] week 2024-52 cherry pick (gitea/main -> forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6339): repo avatar generating (#6338)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6337): keep commit count limit in file history pagination static and not increase with every page
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6335): template config path (#2836)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6330): branding: update contrib/legal
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6324): chore(release): link to the standalone release notes file
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6322): Update module google.golang.org/grpc to v1.69.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6321): Update dependency globals to v15.14.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6320): Update actions/cascading-pr action to v2.2.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6319): Update dependency katex to v0.16.18 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6316): Update module golang.org/x/net to v0.33.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6313): actions move to data.forgejo.org
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6311): chore: avoid using gock
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6310): chore: remove unused dependency from build.go
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6309): Update dependency markdownlint-cli to v0.43.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6308): Update dependency @playwright/test to v1.49.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6307): Update vitest monorepo to v2.1.8 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6306): Update module github.com/blevesearch/bleve/v2 to v2.4.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6305): Update dependency tailwindcss to v3.4.17 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6304): Update dependency katex to v0.16.17 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6303): Update dependency eslint-plugin-import-x to v4.5.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6301): Replace actions/cascading-pr action with actions/cascading-pr v2.1.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6299): chore: Make Forgejo build with go1.24
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6298): Update actions/setup-forgejo action to v2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6296): Add readme to locale folder
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6295): Update module google.golang.org/protobuf to v1.36.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6293): Update dependency eslint-plugin-sonarjs to v3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6292): Update linters (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6291): Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v1.62.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6290): Update dependency @vitest/eslint-plugin to v1.1.16 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6288): Some improvements to base locale
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6287): Don't notify when a user self-request as reviewer
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6282): Update module github.com/go-chi/chi/v5 to v5.2.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6281): Update actions/cascading-pr action to v2.2.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6278): Update renovate to v39.69.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6264): Update forgejo/forgejo-build-publish action to v5.2.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6260): Update module golang.org/x/tools/gopls to v0.17.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6259): Update dependency @primer/octicons to v19.14.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6258): Update module github.com/gliderlabs/ssh to v0.3.8 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6256): chore(release-notes): Forgejo v9.0.3 [skip ci]
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6255): chore(release-notes): Forgejo v7.0.12 [skip ci]
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6254): Use correct title for container images
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6245): Adjust MySQL instruction
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6243): Update module golang.org/x/crypto to v0.31.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6237): Avoid having to store i18n linter exceptions for
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6234): Update github.com/grafana/go-json digest to a119ee5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6233): Add missing automerge feed message
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6229): Update dependency katex to v0.16.15 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6227): Replace actions/setup-forgejo action with actions/setup-forgejo v1.0.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6226): Replace actions/cascading-pr action with actions/cascading-pr v2.1.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6223): chore(ci): set the milestone when a pull request is closed (take 4)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6222): Clipboard read permission for Chromium
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6221): Add `-` as reserved user
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6219): chore(ci): set the milestone when a pull request is open (take 3)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6213): chore(ci): set the milestone when a pull request is open (take 2)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6211): chore(ci): set the milestone when a pull request is open [skip ci]
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6210): Update dependency forgejo-lxc to v12 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6206): Cleanup `package/arch` route
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6205): Update dependency katex to v0.16.14 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6204): Update renovate to v39.57.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6202): nix-dev-improvements
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6201): Simplify main-attribute labels
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6199): feat(secret): generate FORGEJO_TOKEN for all tasks
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6196): Rebrand help text in `forgejo migrate` #6194
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6191): Do not offer duplicating a PR for a recently pushed branch
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6190): Update x/tools to v0.28.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6188): don't specify FOR clause for index hint
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6182): chore(ci): common issue-labels name for all related workflows
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6178): Revert "chore(ci): merge jobs in issue-labels.yml in one workflow"
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6177): chore(ci): docker-runner-one is not a known label
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6175): Update module golang.org/x/net to v0.32.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6172): Update dependency webpack to v5.97.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6171): Update dependency @github/relative-time-element to v4.4.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6165): chore(release-notes): keep release notes in release-notes-published
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6160): Update module golang.org/x/image to v0.23.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6159): Update module golang.org/x/crypto to v0.30.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6157): Update dependency @primer/octicons to v19.13.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6153): highlight Gradle Kotlin as Kotlin
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6152): remove softbreak from github legacy callout
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6151): build: only require go minor
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6150): Update module code.forgejo.org/go-chi/session to v1.0.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6148): Update module code.forgejo.org/go-chi/captcha to v1.0.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6145): Update dependency go to v1.23.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6144): correct permission loading for limited organisation
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6140): Update dependency webpack to v5.97.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6139): Update dependency tailwindcss to v3.4.16 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6137): Update fnetx/setup-cache-go digest to 4b50dd2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6136): build: relax required go version for local development
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6130): avoid sorting for `MakeSelfOnTop`
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6128): clean up log files that no longer exist
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6120): chore(ci): run merge conditions when a new commit is pushed
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6119): Lock file maintenance (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6118): Update dependency globals to v15.13.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6117): Regular visual regression testing
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6115): Update renovate to v39.42.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6114): return correct type in `GetSubModule`
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6113): Rework GetLatestCommitStatusForPairs query using a subquery for PG compatibility
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6109): Update dependency happy-dom to v15.11.7 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6108): Update dependency djlint to v1.36.3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6107): Update dependency @vitest/eslint-plugin to v1.1.13 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6106): Update dependency @stoplight/spectral-cli to v6.14.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6095): Update dependency sortablejs to v1.15.6 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6090): chore(i18): cleanup locales
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6089): typos, mostly from `codespell`, others just by eyeballing
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6088): Update dependency sortablejs to v1.15.5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6087): Update dependency mermaid to v11.4.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6084): normalize guessed languages from enry
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6083): improve wording of limited visibility
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6082): Update dependency chartjs-plugin-zoom to v2.2.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6071): Use user.FullName in Oauth2 id_token response
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6067): Lock file maintenance (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6066): Update dependency sortablejs to v1.15.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6065): Update renovate to v39.28.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6059): Improve colors used by colorblind-friendly forgejo themes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6058): Update module github.com/stretchr/testify to v1.10.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6052): Show page titles in wiki search results (#6048)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6050): Improve Swagger documentation for user endpoints
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6049): Update dependency typescript to v5.7.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6046): ci: use more `tmpfs` and `noatime` for faster CI
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6045): test: fix e2e test
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6034): chore(ci): remove unused experimental DNS updates
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6029): bug: git notes edit/remove button displayed to anonymous visitors
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6027): Apply smaller padding to comment headers
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6025): Improve git notes UI
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6023): Update dependency chartjs-plugin-zoom to v2.1.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6021): chore(ci): merge jobs issue label jobs in one workflow
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6020): chore(ci): make release-notes-assistant job copy/pastable (part two)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6019): chore(ci): make release-notes-assistant job copy/pastable
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6013): fix(test): TestGitAttributeCheckerError must allow broken pipe
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6010): Lock file maintenance (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6008): Update renovate to v39.19.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6006): vertical center the date on GPG keys
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6003): chore(release-notes-assistant): security fix / features come first
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6002): chore(ci): make backporting job copy/pastable
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6001): chore(ci): make merge-conditions job copy/pastable
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6000): chore(ci): make end-to-end job copy/pastable
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5996): check read permissions for code owner review requests
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5995): remember fuzzy for open/close state
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5994): Revert defaulting to EdDSA
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5991): api repo compare with commit hashes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5989): use better code to group UID and stopwatches
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5987): Default to generating EdDSA for OAuth JWT signing key
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5986): bug: correctly generate oauth2 jwt signing key
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5984): extend `forgejo_auth_token` table (part two)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5983): improve `GetLatestCommitStatusForPairs`
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5981): Update dependency vue to v3.5.13 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5980): Update github.com/grafana/go-json digest to f14426c (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5978): chore(release-notes): fix the v9.0.2 links
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5977): chore: fix e2e
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5973): ci: upload all e2e artifacts
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5969): Update module google.golang.org/grpc to v1.68.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5968): test: fix e2e tests
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5966): Update dependency tailwindcss to v3.4.15 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5965): use oci mirror for `tonistiigi/xx` image
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5964): ci: proper job name
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5963): ci: use oci mirror images
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5962): ci: disable postgresql fsync
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5958): ci: use tmpfs for service storage
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5957): ci: disable mysql binlog
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5956): test: use sqlite in-memory db for integration
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5955): test: add trailing newline to `testlogger.go:recordError` message
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5954): chore: improve slow tests
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5951): chore(i18n): allow datnes nosaukums for filename (Latvian)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5949): Update module code.forgejo.org/forgejo/act to v1.22.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5948): chore: improve preparing tests
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5946): Update module github.com/blevesearch/bleve/v2 to v2.4.3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5944): chore(ci): ROLE forgejo-coding & forgejo-testing (part two)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5943): chore(release-notes): update the v9.0.2 & v7.0.11 links
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5942): chore(ci): ROLE forgejo-coding & forgejo-testing
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5935): chore(renovate): throttle down upgrade of linters & test packages
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5934): Update linters (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5933): Update dependency @stoplight/spectral-cli to v6.14.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5932): Update dependency happy-dom to v15.11.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5931): Update dependency @vitest/eslint-plugin to v1.1.10 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5929): tests(e2e): Refactor various tests
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5928): chore(lint): Ignore playwright reports for linting
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5924): fix(ci): synchronize updates the commit status asynchronously
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5923): chore(renovate): always set the test/not-needed label
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5922): Update module github.com/buildkite/terminal-to-html/v3 to v3.16.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5921): Update dependency postcss to v8.4.49 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5920): Update dependency happy-dom to v15.11.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5919): Update dependency @axe-core/playwright to v4.10.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5916): chore(e2e): Update global patterns
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5913): chore: set recommend vscode settings for golangci-lint
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5912): test: fix test linting
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5911): Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v1.62.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5910): Update dependency @vitejs/plugin-vue to v5.1.5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5909): Re-add least recently updated as sort order
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5908): Update dependency postcss to v8.4.48 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5907): Update renovate to v39.9.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5906): chore: improve database docker instructions
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5904): chore: improve test quality
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5903): chore: simplify CopyDir
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5896): fix(ci): only trigger end-to-end tests when the label is set
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5892): Proper parsing of date for git commits
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5890): Update module golang.org/x/net to v0.31.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5888): chore: lazy-loaded version of goccy/go-json
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5886): chore(ci): Enforce test label with CI check
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5885): fix(ui): Details icon in repo settings sidebar
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5883): Update module golang.org/x/crypto to v0.29.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5881): [THEME] Copy ansi terminal colours from gitea to forgejo themes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5878): fix(ci): slow runners may need more than 50 minutes for a test
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5869): bug: require.Eventually must not test with assert
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5865): Update module code.forgejo.org/go-chi/session to v1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5864): Update module code.forgejo.org/go-chi/captcha to v1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5863): Update module code.forgejo.org/go-chi/cache to v1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5862): Update module code.forgejo.org/go-chi/binding to v1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5858): chore(renovate): only run if renovate workflow changed
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5857): chore(renovate): update settings
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5843): issue labels are not set after deleting one label
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5840): Update dependency happy-dom to v15.11.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5837): Update dependency eslint-plugin-playwright to v2.0.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5836): Update dependency go to v1.23.3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5835): Make direnv optional to let developers use their own direnv configuration
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5832): chore(renovate): fix regex
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5830): chore(renovate): use squash for automerge
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5829): Update renovate to v39 (forgejo) (major)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5825): Update dependency happy-dom to v15.10.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5824): Update dependency djlint to v1.36.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5820): chore(ci): deprecate legacy infrastructure supporting v*.next
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5817): test: enable gitea migration tests
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5816): test: enable github migration tests
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5815): Update linters to v8.13.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5814): Update dependency globals to v15.12.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5813): Update dependency happy-dom to v15.9.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5804): Lock file maintenance (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5803): Update dependency happy-dom to v15.8.3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5802): Update renovate to v38.142.5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5796): [PORT] Replace DateTime with proper functions (gitea#32402)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5795): support `www.github.com` for migrations
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5794): [PORT] Fix git error handling (gitea#32401)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5793): [PORT] Refactor the DB migration system slightly (gitea#32344)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5792): [PORT] Fix toAbsoluteLocaleDate and add more tests (gitea#32387)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5791): [PORT] Fix a number of typescript issues (gitea#32308)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5790): [PORT] Refactor tests to prevent from unnecessary preparations (gitea#32398)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5788): chore(cleanup): remove unused TestCreateFile
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5784): Update dependency eslint-plugin-array-func to v5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5783): Update module github.com/gorilla/sessions to v1.4.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5782): Update actions/git-backporting action to v4.8.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5780): Update module github.com/yuin/goldmark to v1.7.8 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5779): support color dots for 4 character hex.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5775): Update module github.com/fsnotify/fsnotify to v1.8.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5774): Update linters (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5773): Update dependency happy-dom to v15.8.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5772): Update dependency djlint to v1.35.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5771): tests: improve actvititypub integration test code
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5769): Revert: chore(ci): Enforce test label with CI check
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5768): chore(renovate): explicit base branches
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5767): Improvements to some English strings
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5766): Update infrastructure/next-digest action to v1.1.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5764): Update dependency webpack to v5.96.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5763): Update dependency mini-css-extract-plugin to v2.9.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5762): Update module code.forgejo.org/forgejo/act to v1.21.5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5756): chore(ci): Enforce test label with CI check
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5755): chore(ci): use rootless for the container images sent to k8s
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5750): Update dependency djlint to v1.35.3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5747): chore(ci): notify the k8s cluster about experimental releases
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5738): Update module github.com/meilisearch/meilisearch-go to v0.29.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5737): Update vitest monorepo to v2.1.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5734): refactor: Migrate playwright to typescript
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5732): chore(release): also copy the release to code.forgejo.org
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5729): docs: add links to the v7.0.10 & v9.0.1 release notes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5717): Lock file maintenance (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5716): Update renovate to v38.133.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5713): i18n: fix placeholders in string for refusing to review
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5712): Link back to one-time code page from scratch code page
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5705): Update linters (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5704): Update dependency @playwright/test to v1.48.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5703): harden localization against malicious HTML
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5702): use buffered iterate for debian searchpackages
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5698): Update internationalization label in release-notes-assistant
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5692): tests(e2e): skip browser downloads
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5690): Add typescript support
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5688): make branch protection work for new branches
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5685): chore: output playwright directly to std{out,err}
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5684): reset `history.scrollRestoration` if set to `manual` and no issue anchor in url
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5678): Update dependency postcss-nesting to v13.0.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5669): Update dependency eslint-plugin-playwright to v2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5668): chore: remove eslint v9 restriction in renovate
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5665): Update module github.com/jhillyerd/enmime to v2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5664): Update dependency postcss-nesting to v13 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5663): Update dependency eslint-plugin-unicorn to v56 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5662): chore: move to Eslint flat config
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5657): use combo markdown editor for milestone description
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5653): don't show truncated comments in RSS/Atom feeds
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5652): typo on releases for source code downloads
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5651): link to security policy in security.txt
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5646): chore(release-notes): no need to specify they are draft
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5644): conf: Improve delete_old_actions description
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5641): make synchronize tags to database handle annotated tags
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5640): Revert "add gap between branch dropdown and PR button"
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5638): Better messages for cases of private profiles
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5637): feat(ci): allow manual triggering of the test suite
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5633): Lock file maintenance (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5632): Update renovate to v38.128.6 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5625): fix(i18n): edit should not be lowercase here
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5617): Create temporary user helper function
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5615): Don't double escape delete branch text
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5608): Update code.forgejo.org/go-chi/session digest to 2a99226 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5595): Add server logging for OAuth server errors
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5592): forgejo-cli is now a symlink and cannot be used for sanity checks
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5591): Update dependency @primer/octicons to v19.12.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5590): Update dependency @playwright/test to v1.48.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5578): Update module github.com/buildkite/terminal-to-html/v3 to v3.16.3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5576): Update dependency chart.js to v4.4.5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5569): Update vitest monorepo to v2.1.3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5568): Update module github.com/redis/go-redis/v9 to v9.6.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5563): Update security option in issue template
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5561): Fix typo in English locale file
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5560): regression from #4125
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5555): i18n: update of translations from Codeberg Translate
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5554): Fix typo in #5537
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5550): Update module github.com/urfave/cli/v2 to v2.27.5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5549): Update renovate to v38.121.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5541): Update module github.com/minio/minio-go/v7 to v7.0.78 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5540): Update module github.com/klauspost/compress to v1.17.11 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5539): Update dependency vue to v3.5.12 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5537): i18n: Improve translation strings for webhook events
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5536): use column flex on mobile to prevent project title from wrapping
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5533): i18n: remove unnecessary variable
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5530): Make chroma match case-insensitive
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5523): i18n: Fine tune language for units
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5522): Update dependency @github/text-expander-element to v2.8.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5514): i18n: update of translations from Codeberg Translate
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5511): Update x/tools to v0.26.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5510): Update module google.golang.org/protobuf to v1.35.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5509): Update module golang.org/x/sys to v0.26.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5508): Update module golang.org/x/net to v0.30.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5506): Do not change stroke size in the loading animation
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5505): Small fixes and rename for #5482
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5503): update git book link to v2
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5502): Update module golang.org/x/image to v0.21.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5501): Update dependency @playwright/test to v1.48.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5498): Update actions/cache action to v4.1.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5495): Update dependency eslint-plugin-wc to v2.2.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5494): Update dependency @vitest/eslint-plugin to v1.1.7 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5493): Update actions/git-backporting action to v4.8.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5491): correct documentation for non 200 responses in swagger
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5485): chore(ci): update changed-files actions URL for consistency
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5483): Update renovate to v38.110.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5482): "Assign to me" button on PR and Issues #5215
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5479): Improve 'Verify' error message, stopgap for #2809
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5476): Update dependency @stylistic/eslint-plugin-js to v2.9.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5474): Update actions/cache action to v4.1.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5473): Update module github.com/mattn/go-sqlite3 to v1.14.24 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5472): "forked from" note alignment on 404 error pages #5324
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5471): i18n: update of translations from Codeberg Translate
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5467): Update dependency @vitest/eslint-plugin to v1.1.6 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5466): Update dependency @stylistic/stylelint-plugin to v3.1.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5458): Update dependency vue to v3.5.11 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5456): log concise repo names in lfs doctor
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5454): Update vitest monorepo to v2.1.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5453): Update module github.com/caddyserver/certmagic to v0.21.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5452): Update dependency @vitest/eslint-plugin to v1.1.5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5450): ci/tests(e2e): always run e2e tests, but only on changed files
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5449): Update dependency go to v1.23.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5441): Update actions/setup-go action to v5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5437): Update ghcr.io/devcontainers/features/git-lfs Docker tag to v1.2.3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5436): Update dependency eslint-plugin-sonarjs to v2.0.3 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5435): Update github.com/google/pprof digest to 017d972 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5434): chore: remove spurious comment in tests
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5430): referenced sha256:* container images may be deleted
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5428): Update actions/setup-node action to v4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5427): Update actions/checkout action to v4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5426): Update actions/cache action to v4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5424): Lock file maintenance (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5422): Update renovate to v38.101.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5421): ci: move composite workflow location
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5415): document sqlite3 as suggested database
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5413): i18n: update of translations from Codeberg Translate
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5411): Update dependency webpack to v5.95.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5410): ci: Move preparations to local actions
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5405): Update dependency markdownlint-cli to v0.42.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5404): Update dependency @vitest/eslint-plugin to v1.1.4 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5403): Update dependency @stylistic/stylelint-plugin to v3.1.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5402): Update dependency vue to v3.5.10 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5398): Update module github.com/minio/minio-go/v7 to v7.0.77 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5397): Update module github.com/klauspost/compress to v1.17.10 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5396): Update dependency @github/text-expander-element to v2.7.2 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5395): Update citation-js monorepo (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5391): docs: add link to the v9.0.0 release notes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5389): mail issue: Display issue type in email header
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5374): Update dependency monaco-editor to v0.51.0 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5370): Update module google.golang.org/grpc to v1.67.1 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5355): i18n: update of translations from Codeberg Translate
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5353): Remove some Windows-specific files
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5351): Add architecture-specific removal support for arch package
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5328): ci: use custom action for Go caching
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5294): tests(e2e): Refactor branch protection test
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5249): Makefile: support gotestsum
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5240): Update module github.com/prometheus/client_golang to v1.20.5 (forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5158): use ValidateEmail as binding across web forms
+- Already announced in the release notes of an older stable release
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6249): Revert "allow synchronizing user status from OAuth2 login providers (#31572)"
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6248): ensure correct ssh public key is used for authentication
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6124): doctor fails with pq: syntax error at or near "." whilst counting Authorization token without existing User
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6097): Do not rewrite ssh keys files when deleting a user without one
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6054): Do not delete global Oauth2 applications
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/1ce33aa38d1d258d14523ff2c7c2dbf339f22b74) it was possible to use a token sent via email for secondary email validation to reset the password instead. In other words, a token sent for a given action (registration, password reset or secondary email validation) could be used to perform a different action. It is no longer possible to use a token for an action that is different from its original purpose.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/061abe60045212acf8c3f5c49b5cc758b4cbcde9) a fork of a public repository would show in the list of forks, even if its owner was not a public user or organization. Such a fork is now hidden from the list of forks of the public repository.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/3e3ef76808100cb1c853378733d0f6a910324ac6) the members of an organization team with read access to a repository (e.g. to read issues) but no read access to the code could read the RSS or atom feeds which include the commit activity. Reading the RSS or atom feeds is now denied unless the team has read permissions on the code.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/9508aa7713632ed40124a933d91d5766cf2369c2) the tokens used when [replying by email to issues or pull requests](https://forgejo.org/docs/v9.0/user/incoming/) were weaker than the [rfc2104 recommendations](https://datatracker.ietf.org/doc/html/rfc2104#section-5). The tokens are now truncated to 128 bits instead of 80 bits. It is no longer possible to reply to emails sent before the upgrade because the weaker tokens are invalid.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/786dfc7fb81ee76d4292ca5fcb33e6ea7bdccc29) a registered user could modify the update frequency of any push mirror (e.g. every 4h instead of every 8h). They are now only able to do that if they have administrative permissions on the repository.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/e6bbecb02d47730d3cc630d419fe27ef2fb5cb39) it was possible to use basic authorization (i.e. user:password) for requests to the API even when security keys were enrolled for a user. It is no longer possible, an application token must be used instead.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/7067cc7da4f144cc8a2fd2ae6e5307e0465ace7f) some markup sanitation rules were not as strong as they could be (e.g. allowing `emoji somethingelse` as well as `emoji`). The rules are now stricter and do not allow for such cases.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974): [commit](https://codeberg.org/forgejo/forgejo/commit/b70196653f9d7d3b9d4e72d114e5cc6f472988c4) when Forgejo is configured to enable instance wide search (e.g. with [bleve](https://blevesearch.com/)), results found in the repositories of private or limited users were displayed to anonymous visitors. The results found in private or limited organizations were not displayed. The search results found in the repositories of private or limited user are no longer displayed to anonymous visitors.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5941): handle renamed dependency for cargo registry
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5850): [PORT] Fix code owners will not be mentioned when a pull request comes from a forked repository (gitea#30476)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5831): labels are missing in the pull request payload removing a label
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5778): In a Forgejo Actions workflow, the `unlabeled` event type for pull requests was incorrectly mapped to the labeled event type.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5778): When a Forgejo Actions issue or pull request workflow is triggered by an `labeled` or `unlabeled` event type, it misses information about the label added or removed. It is now available in the `label` data member of the event payload.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5778): The pull request workflow must always update the head SHA commit status. Not just when the PR is synchronized, opened or closed. Otherwise it makes it impossible to define a job to be a required check (for instance a job that is triggered when labels are modified and verifies that a given combination is present).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5746): git-grep for code search when git version is below 2.38
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5719): Forgejo generates a token which is used to authenticate web endpoints that are only meant to be used internally, for instance when the SSH daemon is used to push a commit with Git. The verification of this token was not done in constant time and was susceptible to [timing attacks](https://en.wikipedia.org/wiki/Timing_attack). A pre-condition for such an attack is the precise measurements of the time for each operation. Since it requires observing the timing of network operations, the issue is mitigated when a Forgejo instance is accessed over the internet because the ISP introduce unpredictable random delays.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5718): Because of a missing permission check, the branch used to propose a pull request to a repository can always be deleted by the user performing the merge. It was fixed so that such a deletion is only allowed if the user performing the merge has write permission to the repository from which the pull request was made.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5634): package arch database not updating when uploading "any" architecture
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5627): correct SQL query for active issues
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5626): specify default value for `EXPLORE_DEFAULT_SORT`.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5613): Add `recentupdated` as recognized sort option
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5587): Dockerfile: use alpine:3.20 instead of golang:1.23-alpine3.20
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5585): Dockerfile: unnecessary container image layer duplication
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5529): Don't allow owner team with incorrect unit access (includes doctor fix)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5515): **Fixing this bug is a breaking change because existing tokens with a public scope will no longer return private resources. They have to be deleted and re-created without the public scope to restore their original behavior**. The public scope of an application token does not filter out private repositories, organizations or packages in some cases. This scope is not the default, it has to be manually set via the web UI or the API. When the public scope is explicitly added to an application token that is allowed to list the repositories and packages of a user or an organization, it is meant as a restriction. For instance if a user has two repositories, one private and the other publicly visible, a token with the public scope used with the API endpoint listing the repositories that belong to this user must only return the publicly visible one and not reveal the existence of the private one.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5492): correct Discord webhook JSON for issue events
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5470): don't cancel schedule workflows on push to main branch
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5439): Fix boolean inputs in workflow_dispatch
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/f709de24039ab7e605d3e09e3b61240836381603) Fix wrong last modify time.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/2675a24649af2fff34f5c7e416d6ff78591d8d9c) Repo Activity: count new issues that were closed.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/526054332acb221e061d3900bba2dc6e012da52d) Fix incorrect /tokens api.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372): [commit](https://codeberg.org/forgejo/forgejo/commit/0cafec4c7a2faf810953e9d522faf5dc019e1522) Do not escape relative path in RPM primary index.
+
diff --git a/release-notes-published/10.0.1.md b/release-notes-published/10.0.1.md
new file mode 100644
index 0000000000..f8f47433f8
--- /dev/null
+++ b/release-notes-published/10.0.1.md
@@ -0,0 +1,44 @@
+See also the [dedicated blog post](https://forgejo.org/2025-02-release-v10-0-1/).
+
+
+
+## Release notes
+
+- Security bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6839): Verify the ID of Forgejo Actions web endpoints belongs to the repository to prevent the deletion of runners or variables or the modification of variables. [Read more in the dedicated blog post](https://forgejo.org/2025-02-release-v10-0-1/).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6838): Enforce permissions on publicly available user or organizations projects to not leak information from issues and pull requests that belong to private repositories. [Read more in the dedicated blog post](https://forgejo.org/2025-02-release-v10-0-1/).
+- User Interface bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6803) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6833)): fix(ui): display verified icon for default gpg key
+- Localization
+ - Updates from Codeberg Translate: [[1]](https://codeberg.org/forgejo/forgejo/pulls/6764), [[2]](https://codeberg.org/forgejo/forgejo/pulls/6834)
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6674) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6678)): fix: load settings for valid user and email check
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6639) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6651)): Teach the doctor to remove orphaned two_factor with `forgejo doctor check --run check-db-consistency --fix`. Such rows may contain invalid data and [block the migration to v10](https://codeberg.org/forgejo/forgejo/issues/6637) with a message such as `failed: AesDecrypt invalid decrypted base64 string: illegal base64 data at input byte 0`.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6633) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6643)): fix: listing tokens must not require basic auth
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6817) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6832)): fix: avoid y-axis clipping for branch name
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6646) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6810)): ci: fix go version check
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6808) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6809)): chore(i18n): lint errors
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6782) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6783)): fix: make author search case insensitive
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6620) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6770)): fix(ui): add triangle down octicon to code search options dropdown
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6708) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6749)): Set explore pages to configurable default sort
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6734) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6748)): Disable autofocus on the dashboard repository search box
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6525) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6739)): fix inline file preview for files with encoded URL, fix #5069
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6726) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6730)): fix: check for webauthn in 2fa user search
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6716) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6720)): fix: disallow blame on directories
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6701) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6718)): fix(i18n): add forgotten translatable string
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6715) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6717)): fix: render issue titles consistently
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6704): chore: consistent docker image and action references
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6694): Update dependency katex to v0.16.21 [SECURITY] (v10.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6572) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6685)): Fix inline file preview for rendered files
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6677) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6684)): fix: add non allowed domain translation
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6655) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6668)): chore(security): update security.txt with new expiration date
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6644): Update dependency go to v1.23.5 (v10.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6617) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6636)): fix(ui): prevent overflow of branch selector in commit graph
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6597) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6632)): Fix mention and emoji expansion & Improve leaving list completion
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6613) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6614)): Hide git note add button for commit, if commit already has a note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6595) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6601)): fix: Reset content of comment edit field on cancel
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6591) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6594)): fix: reduce noise for the v303 migration
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6569) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6587)): tests(e2e): Various fixes to visual testing
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6400) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6585)): Refactor e2e tests to simplify authentication setup
+
diff --git a/release-notes-published/10.0.2.md b/release-notes-published/10.0.2.md
new file mode 100644
index 0000000000..594614a790
--- /dev/null
+++ b/release-notes-published/10.0.2.md
@@ -0,0 +1,37 @@
+
+
+
+
+## Release notes
+
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7277): update of translations from Codeberg Translate
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7067): update of translations from multiple sources
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7251) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7255)): When migrating from a Forgejo version lower than v10, the TOTP secrets found to be corrupted are now transparently removed from the database instead of failing the migration. TOTP is no longer required to login with the associated users. They should be informed because they will need to visit their security settings and configure TOTP again. No other action is required.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7167) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7178)): replies to pending review comments no longer generate a notification, this was caused by an incomplete determination if the comment was part of the pending review or not
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7143) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7144)): consider public issues for project boards
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7038) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7046)): the rootless Forgejo image version label is not set
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7004) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7018)): do not allow SSH url for migration
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6680) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6930)): `setting.Service.EnableInternalSignIn = false` is disabling forgotten password
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6920) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6929)): show internal login prompt for account linking
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6896) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6915)): enable ssh mirrors in rootless Forgejo images
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6853) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6859)): render link in heading correctly in wiki TOC
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7284): Update module github.com/redis/go-redis/v9 to v9.7.3 (v10.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7270) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7272)): fix: consider issues in repository accessible via `access` table
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7199) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7202)): fix(api): miss-spelled description, corrected to `public`
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7171) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7177)): fix: revert issue rendering for `` element
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7078) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7079)): chore(ci): ensure the manually cached Go can be run
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6590) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7073)): chore(ci): Get Go binary from GOROOT instead of hardcoded path
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7072): Update module golang.org/x/crypto to v0.35.0 (v10.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7052): Update https://data.forgejo.org/forgejo/forgejo-build-publish action to v5.3.4 (v10.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7003) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7014)): fix: return 404 for empty repositories
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6937) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6976)): fix: delay deleting authorization token
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6953) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6954)): fix: native parsing of ssh certificate key
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6898) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6905)): fix(ui): hide extra PR property labels on title edit
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6866) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6884)): fix: always set stripped slashes on http request
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6851) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6860)): fix(ui): hide 'New migration' button on org pages with migrations disabled (#6850)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6700) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6854)): ui: update language stats layout and click behavior
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6812): Update dependency go to v1.23.6 (v10.0/forgejo)
+
diff --git a/release-notes-published/10.0.3.md b/release-notes-published/10.0.3.md
new file mode 100644
index 0000000000..16c6ad872b
--- /dev/null
+++ b/release-notes-published/10.0.3.md
@@ -0,0 +1,13 @@
+
+
+
+
+## Release notes
+
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7295) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7306)): fixes a [regression introduced in Forgejo v10.0.2](https://codeberg.org/forgejo/forgejo/pulls/6866/files) which caused unnecessary escaping of URLs. The symptoms were, for instance, a [failure to access theme files when they contain a space](https://codeberg.org/forgejo/forgejo/issues/7294) or [double escaping of links](https://codeberg.org/forgejo/forgejo/issues/7292).
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7304): Update module golang.org/x/oauth2 to v0.27.0
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7303): Update module golang.org/x/net to v0.36.0
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7302): Update module github.com/golang-jwt/jwt/v5 to v5.2.2
+
diff --git a/release-notes-published/7.0.10.md b/release-notes-published/7.0.10.md
new file mode 100644
index 0000000000..bbdc413a44
--- /dev/null
+++ b/release-notes-published/7.0.10.md
@@ -0,0 +1,13 @@
+
+
+## Release notes
+
+- Security bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5719) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5723)): Forgejo generates a token which is used to authenticate web endpoints that are only meant to be used internally, for instance when the SSH daemon is used to push a commit with Git. The verification of this token was not done in constant time and was susceptible to [timing attacks](https://en.wikipedia.org/wiki/Timing_attack). A pre-condition for such an attack is the precise measurements of the time for each operation. Since it requires observing the timing of network operations, the issue is mitigated when a Forgejo instance is accessed over the internet because the ISP introduce unpredictable random delays.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5718) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5720)): Because of a missing permission check, the branch used to propose a pull request to a repository can always be deleted by the user performing the merge. It was fixed so that such a deletion is only allowed if the user performing the merge has write permission to the repository from which the pull request was made.
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5182) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5401)): Translation backports to v7
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5725): Update dependency mermaid to v10.9.3 [SECURITY] (v7.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5241): Update dependency go to v1.22.7 (v7.0/forgejo)
+
diff --git a/release-notes-published/7.0.11.md b/release-notes-published/7.0.11.md
new file mode 100644
index 0000000000..16a2b1ecc9
--- /dev/null
+++ b/release-notes-published/7.0.11.md
@@ -0,0 +1,14 @@
+
+
+## Release notes
+
+- Security bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5976)): [commit](https://codeberg.org/forgejo/forgejo/commit/1ce33aa38d1d258d14523ff2c7c2dbf339f22b74) it was possible to use a token sent via email for secondary email validation to reset the password instead. In other words, a token sent for a given action (registration, password reset or secondary email validation) could be used to perform a different action. It is no longer possible to use a token for an action that is different from its original purpose.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5976)): [commit](https://codeberg.org/forgejo/forgejo/commit/061abe60045212acf8c3f5c49b5cc758b4cbcde9) a fork of a public repository would show in the list of forks, even if its owner was not a public user or organization. Such a fork is now hidden from the list of forks of the public repository.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5976)): [commit](https://codeberg.org/forgejo/forgejo/commit/3e3ef76808100cb1c853378733d0f6a910324ac6) the members of an organization team with read access to a repository (e.g. to read issues) but no read access to the code could read the RSS or atom feeds which include the commit activity. Reading the RSS or atom feeds is now denied unless the team has read permissions on the code.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5976)): [commit](https://codeberg.org/forgejo/forgejo/commit/9508aa7713632ed40124a933d91d5766cf2369c2) the tokens used when [replying by email to issues or pull requests](https://forgejo.org/docs/v9.0/user/incoming/) were weaker than the [rfc2104 recommendations](https://datatracker.ietf.org/doc/html/rfc2104#section-5). The tokens are now truncated to 128 bits instead of 80 bits. It is no longer possible to reply to emails sent before the upgrade because the weaker tokens are invalid.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5976)): [commit](https://codeberg.org/forgejo/forgejo/commit/786dfc7fb81ee76d4292ca5fcb33e6ea7bdccc29) a registered user could modify the update frequency of any push mirror (e.g. every 4h instead of every 8h). They are now only able to do that if they have administrative permissions on the repository.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5976)): [commit](https://codeberg.org/forgejo/forgejo/commit/e6bbecb02d47730d3cc630d419fe27ef2fb5cb39) it was possible to use basic authorization (i.e. user:password) for requests to the API even when security keys were enrolled for a user. It is no longer possible, an application token must be used instead.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5976)): [commit](https://codeberg.org/forgejo/forgejo/commit/7067cc7da4f144cc8a2fd2ae6e5307e0465ace7f) some markup sanitation rules were not as strong as they could be (e.g. allowing `emoji somethingelse` as well as `emoji`). The rules are now stricter and do not allow for such cases.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5976)): [commit](https://codeberg.org/forgejo/forgejo/commit/b70196653f9d7d3b9d4e72d114e5cc6f472988c4) when Forgejo is configured to enable instance wide search (e.g. with [bleve](https://blevesearch.com/)), results found in the repositories of private or limited users were displayed to anonymous visitors. The results found in private or limited organizations were not displayed. The search results found in the repositories of private or limited user are no longer displayed to anonymous visitors.
+
diff --git a/release-notes-published/7.0.12.md b/release-notes-published/7.0.12.md
new file mode 100644
index 0000000000..b382d82bbe
--- /dev/null
+++ b/release-notes-published/7.0.12.md
@@ -0,0 +1,18 @@
+
+
+
+
+## Release notes
+
+- Security bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6248) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6252)): When Forgejo is configured to run the internal ssh server with `[server].START_SSH_SERVER=true`, it was possible for a registered user to impersonate another user. The rootless container image uses the internal ssh server by default and was vulnerable. A Forgejo instance running from a binary or from a root container image does not use the internal ssh server by default and was not vulnerable. The incorrect use of the crypto package is the root cause of the vulnerability and was fixed for the internal ssh server.
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6124) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6132)): fix: doctor fails with pq: syntax error at or near "." whilst counting Authorization token without existing User
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6054) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6056)): fix: Do not delete global Oauth2 applications
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6246): Update module golang.org/x/crypto to v0.31.0 (v7.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6223) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6230)): chore(ci): set the milestone when a pull request is closed (take 4)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6219) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6224)): chore(ci): set the milestone when a pull request is open (take 3)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6211) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6216)): chore(ci): set the milestone when a pull request is open
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6034) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6036)): chore(ci): remove unused experimental DNS updates
+
diff --git a/release-notes-published/7.0.13.md b/release-notes-published/7.0.13.md
new file mode 100644
index 0000000000..484bbc4afa
--- /dev/null
+++ b/release-notes-published/7.0.13.md
@@ -0,0 +1,19 @@
+See also the [dedicated blog post](https://forgejo.org/2025-02-release-v10-0-1/).
+
+
+
+## Release notes
+
+- Security bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6845): Verify the ID of Forgejo Actions web endpoints belongs to the repository to prevent the deletion of runners or variables or the modification of variables. [Read more in the dedicated blog post](https://forgejo.org/2025-02-release-v10-0-1/).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6846): Enforce permissions on publicly available user or organizations projects to not leak information from issues and pull requests that belong to private repositories. [Read more in the dedicated blog post](https://forgejo.org/2025-02-release-v10-0-1/).
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6674) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6679)): fix: load settings for valid user and email check
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6693): Update dependency katex to v0.16.21 [SECURITY] (v7.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6655) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6669)): chore(security): update security.txt with new expiration date
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6501): chore: remove illegal git usage
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6483): Update module github.com/go-git/go-git/v5 to v5.13.1 (v7.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6324) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6325)): chore(release): link to the standalone release notes file
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6317): Update module golang.org/x/net to v0.33.0 (v7.0/forgejo)
+
diff --git a/release-notes-published/7.0.14.md b/release-notes-published/7.0.14.md
new file mode 100644
index 0000000000..b7e85d8184
--- /dev/null
+++ b/release-notes-published/7.0.14.md
@@ -0,0 +1,14 @@
+
+
+
+
+## Release notes
+
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7143) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7145)): consider public issues for project boards
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7038) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7049)): the rootless image version label is not set
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6299) ([backported](https://codeberg.org/forgejo/forgejo/pulls/7233)): chore: Make Forgejo build with go1.24
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7081): Update golang packages to v1.23 (v7.0/forgejo) (minor)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/7051): Update https://code.forgejo.org/forgejo/forgejo-build-publish action to v5.3.4 (v7.0/forgejo)
+
diff --git a/release-notes-published/7.0.7.md b/release-notes-published/7.0.7.md
new file mode 100644
index 0000000000..310d430304
--- /dev/null
+++ b/release-notes-published/7.0.7.md
@@ -0,0 +1,13 @@
+This is a security release. See the documentation for more information on the [upgrade procedure](https://forgejo.org/docs/v7.0/admin/upgrade/).
+
+- Security
+ A [change introduced in Forgejo v1.21](https://codeberg.org/forgejo/forgejo/pulls/1433) allows a Forgejo user with write permission on a repository description to [inject a client-side script into the web page viewed by the visitor](https://en.wikipedia.org/wiki/Cross-site_scripting). This XSS allows for `href` in anchor elements to be set to a `javascript:` URI in the repository description, which will execute the specified script upon clicking (and not upon loading). [`AllowStandardURLs`](https://pkg.go.dev/github.com/microcosm-cc/bluemonday#Policy.AllowStandardURLs) is now called for the repository description policy, which ensures that URIs in anchor elements are `mailto:`, `http://` or `https://` and thereby disallowing the `javascript:` URI.
+
+
+
+
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4896) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4900)): disallow javascript: URI in the repository description
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4568) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4882)): i18n: backport of #4568 #4668 and #4783 to v7
+
diff --git a/release-notes-published/7.0.8.md b/release-notes-published/7.0.8.md
new file mode 100644
index 0000000000..a679b0131c
--- /dev/null
+++ b/release-notes-published/7.0.8.md
@@ -0,0 +1,18 @@
+This is a security release. See the documentation for more information on the [upgrade procedure](https://forgejo.org/docs/v7.0/admin/upgrade/).
+
+- Security bug fixes
+ [The scope of application tokens was not verified](https://codeberg.org/forgejo/forgejo/pulls/5149) when writing containers or Conan packages. This is of no consequence when the user associated with the application token does not have write access to packages. If the user has write access to packages, such a token can be used to write containers and Conan packages. An application token that was used to write containers or Conan packages without the `package:write` scope will now fail with an unauthorized error. It must be re-created to include the `package:write` scope.
+
+
+
+
+
+- User Interface bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5029) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5033)): Overflow for images on project cards.
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5149) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5150)): The scope of application tokens is not verified when writing containers or Conan packages.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4885) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4950)): Run full PR checks on AGit push.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/3264) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4999)): - [commit](https://codeberg.org/forgejo/forgejo/commit/364922c6e4f28264add9e2501a352c25ad6a0993) When a repository is adopted, its object format is not set in the database.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/3264) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4999)): - [commit](https://codeberg.org/forgejo/forgejo/commit/e7f332a55d6a48a3f3b4f2bfa43d18455ac00acc) During a migration from bitbucket, LFS downloads fail.
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4889) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5138)): Backports of #4889 and #4984 to v7
diff --git a/release-notes-published/7.0.9.md b/release-notes-published/7.0.9.md
new file mode 100644
index 0000000000..2cfa328162
--- /dev/null
+++ b/release-notes-published/7.0.9.md
@@ -0,0 +1,9 @@
+
+
+
+- Security
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5244) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5246)): replace v-html with v-text in branch search inputbox for XSS protection
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5201): Upgrade [webpack to v5.94.0](https://github.com/webpack/webpack/releases/tag/v5.94.0) as a precaution to mitigate [CVE-2024-43788](https://github.com/advisories/GHSA-4vvj-4cpr-p986), although we were not yet able to confirm that this can be exploited in Forgejo.
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5070) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5181)): i18n: update of translations from Codeberg Translate
+
diff --git a/release-notes-published/8.0.1.md b/release-notes-published/8.0.1.md
new file mode 100644
index 0000000000..a1877f4597
--- /dev/null
+++ b/release-notes-published/8.0.1.md
@@ -0,0 +1,20 @@
+This is a security release. See the documentation for more information on the [upgrade procedure](https://forgejo.org/docs/v8.0/admin/upgrade/).
+
+- Security bug fixes
+ A [change introduced in Forgejo v1.21](https://codeberg.org/forgejo/forgejo/pulls/1433) allows a Forgejo user with write permission on a repository description to [inject a client-side script into the web page viewed by the visitor](https://en.wikipedia.org/wiki/Cross-site_scripting). This XSS allows for `href` in anchor elements to be set to a `javascript:` URI in the repository description, which will execute the specified script upon clicking (and not upon loading). [`AllowStandardURLs`](https://pkg.go.dev/github.com/microcosm-cc/bluemonday#Policy.AllowStandardURLs) is now called for the repository description policy, which ensures that URIs in anchor elements are `mailto:`, `http://` or `https://` and thereby disallowing the `javascript:` URI.
+
+
+
+
+- User Interface bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4835) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4848)): Do not include trailing EOL character when counting lines
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4836) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4847)): Add background to reactions on hover
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4806) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4807)): Prevent uppercase in header of dashboard context selector
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4754) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4756)): Fix page layout in admin settings
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4896) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4901)): disallow javascript: URI in the repository description
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4852) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4865)): Ensure all filters are persistent in issue filters
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4828) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4840)): Allow 4 character SHA in `/src/commit`
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4668) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4881)): i18n: backport of #4668 and #4783 to v8
+
diff --git a/release-notes-published/8.0.2.md b/release-notes-published/8.0.2.md
new file mode 100644
index 0000000000..52f0783ad1
--- /dev/null
+++ b/release-notes-published/8.0.2.md
@@ -0,0 +1,24 @@
+This is a security release. See the documentation for more information on the [upgrade procedure](https://forgejo.org/docs/v8.0/admin/upgrade/).
+
+- Security
+ [The scope of application tokens was not verified](https://codeberg.org/forgejo/forgejo/pulls/5149) when writing containers or Conan packages. This is of no consequence when the user associated with the application token does not have write access to packages. If the user has write access to packages, such a token can be used to write containers and Conan packages. An application token that was used to write containers or Conan packages without the `package:write` scope will now fail with an unauthorized error. It must be re-created to include the `package:write` scope.
+
+
+
+
+- User Interface bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5029) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5032)): Overflow for images on project cards.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4798) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4919)): Allow unreacting from comment popover.
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5149) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5151)): The scope of application tokens is not verified when writing containers or Conan packages.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5065) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5080)): When a Forgejo Actions workflow includes a `workflow_dispatch` with `inputs` and other events (for instance `push`), it is silently ignored because of a parsing error.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5053): Automerge on AGit pull requests is ignored.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4998) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5050)): [commit](https://codeberg.org/forgejo/forgejo/commit/7f1db1df3ee8d620f997b8e70a40c2f48ae96c0f) Show lock owner instead of repo owner on LFS setting page.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4998) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5050)): [commit](https://codeberg.org/forgejo/forgejo/commit/ebfdc659d814561f8783094e2eb26738a5500e55) Render plain text file if the LFS object doesn't exist.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4998) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5050)): [commit](https://codeberg.org/forgejo/forgejo/commit/9e066c3cad7bb1b30e2def34bd0608aac825cf58) Panic of ssh public key page after deletion of an auth source.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4998) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5050)): [commit](https://codeberg.org/forgejo/forgejo/commit/a8e25e907c66140961f28ba92403176c816dfb60) Add missing repository type filter parameters to pager.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4907) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4965)): Reverted a change from Gitea which prevented allow/reject reviews on merged or closed PRs. This change was not considered by the Forgejo UI team and there is a consensus that it feels like a regression, since it interferes with workflows known to be used by Forgejo users without providing a tangible benefit.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4885) ([backported](https://codeberg.org/forgejo/forgejo/pulls/4951)): Run full PR checks on AGit push.
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4984) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5116)): i18n: update of translations from Codeberg Translate
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4889) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5114)): i18n: update of translations from Codeberg Translate
diff --git a/release-notes-published/8.0.3.md b/release-notes-published/8.0.3.md
new file mode 100644
index 0000000000..5dea61f08a
--- /dev/null
+++ b/release-notes-published/8.0.3.md
@@ -0,0 +1,10 @@
+
+
+
+- Security
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5244) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5247)): replace v-html with v-text in branch search inputbox for XSS protection
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5202): Upgrade [webpack to v5.94.0](https://github.com/webpack/webpack/releases/tag/v5.94.0) as a precaution to mitigate [CVE-2024-43788](https://github.com/advisories/GHSA-4vvj-4cpr-p986), although we were not yet able to confirm that this can be exploited in Forgejo.
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5182) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5230)): i18n: update of translations from Codeberg Translate
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5070) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5161)): i18n: update of translations from Codeberg Translate
+
diff --git a/release-notes-published/9.0.0.md b/release-notes-published/9.0.0.md
new file mode 100644
index 0000000000..9fca889b79
--- /dev/null
+++ b/release-notes-published/9.0.0.md
@@ -0,0 +1,114 @@
+A [companion blog post](https://forgejo.org/2024-10-release-v9-0/) provides additional context on this major release.
+
+
+
+
+- Breaking changes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4724): OIDC integrations that POST to `/login/oauth/introspect` without sending HTTP basic authentication will now fail with a 401 HTTP Unauthorized error. To fix the error, the client must begin sending HTTP basic authentication with a valid client ID and secret. This endpoint was previously authenticated via the introspection token itself, which is less secure.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5515) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5526)): **Fixing this bug is a breaking change because existing tokens with a public scope will no longer return private resources. They have to be deleted and re-created without the public scope to restore their original behavior**. The public scope of an application token does not filter out private repositories, organizations or packages in some cases. This scope is not the default, it has to be manually set via the web UI or the API. When the public scope is explicitly added to an application token that is allowed to list the repositories and packages of a user or an organization, it is meant as a restriction. For instance if a user has two repositories, one private and the other publicly visible, a token with the public scope used with the API endpoint listing the repositories that belong to this user must only return the publicly visible one and not reveal the existence of the private one.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4941): Drop support to build Forgejo with the optional go-git Git backend. It only affects users who built Forgejo manually using `TAGS=gogits`, which no longer has any effect. Moving forward, we only support the default backend using the git binary. Please get in touch if you used the go-git backend and require any assistance moving away from it.
+- User Interface features
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5286): Set created_by as the default filter for /issues and /pulls.
+ Note that this also affects /org/*/pulls and /org/*/issues, but for them this default might be reverted back in the future releases.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5270): Set fuzzy as default for issue search.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5214): Improve commit graph layout.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5205): mermaid: [Add support for iconify icons](https://github.com/mermaid-js/mermaid/pull/5793).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5205): mermaid: [Allow multi-line relationship labels](https://github.com/mermaid-js/mermaid/pull/5711).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5205): mermaid: [Adds architecture diagrams which allows users to show relations between services](https://github.com/mermaid-js/mermaid/pull/5452).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5110): Improve diffs generated by Forgejo.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5002): Add `rel="nofollow"` to in-list labels.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4782): Distinguish between new tags, releases and pre-releases on activity page.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4749): Highlighted code search results.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4710): Refactor repo migration items.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4697): Add package counter to repo/user/org overview pages.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4571): Replace `vue-bar-graph` with `chart.js`.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4541): Add more emoji and code block rendering in issues.
+- User Interface bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5261): Bad spacing on new release page.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5180): Milestone assignment in new issue.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4928): git-grep: ensure bounded default for MatchesPerFile.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4597): Incorrect go to citation button.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4538): Incorrect HTMX support for profile card.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4490): Accessibility keyboard support for test actions.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4455): Update pull request icons.
+- Features
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5482) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5524)): "Assign to me" button on PR and Issues.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5351) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5407)): Add architecture-specific removal support for arch package.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5406)): [commit](https://codeberg.org/forgejo/forgejo/commit/9d3473119893ffde0ab36d98e7a0e41c5d0ba9a3) Add bin to Composer Metadata.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5383): Internationalization user experience improvements on team permissions and issue closing.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5325): [commit](https://codeberg.org/forgejo/forgejo/commit/2da0ebbd2314f12b287694c378a888311dd337bc) Support allowed hosts for migrations to work with proxy.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5125): Trivial default quota configuration.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5120): Language detection in the repository learned about the following languages: [Luau](https://github.com/github-linguist/linguist/pull/6612), [BQN](https://github.com/github-linguist/linguist/pull/6623), [Cron table](https://github.com/github-linguist/linguist/pull/6759), [NMODL](https://github.com/github-linguist/linguist/pull/6776), [Pkl](https://github.com/github-linguist/linguist/pull/6730), [templ](https://github.com/github-linguist/linguist/pull/6798), [FIRRTL](https://github.com/github-linguist/linguist/pull/6848), [Julia REPL](https://github.com/github-linguist/linguist/pull/6859), [Caddyfile](https://github.com/github-linguist/linguist/pull/6862).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5120): The following extensions or filenames in a repository are associated with the matching language: [.sublime-color-scheme](https://github.com/github-linguist/linguist/pull/6758), [MODULE.bazel.lock](https://github.com/github-linguist/linguist/pull/6783), [Cargo.toml.orig](https://github.com/github-linguist/linguist/pull/6787), [tsx](https://github.com/github-linguist/linguist/pull/6788), [justfile](https://github.com/github-linguist/linguist/pull/6795), [.zig.zon](https://github.com/github-linguist/linguist/pull/6820), [.envrc](https://github.com/github-linguist/linguist/pull/6865).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5090): Remove support for Couchbase as a session provider; it instead will now fallback to the file provider. The rationale for removing Couchbase support is that it's not free software, https://www.couchbase.com/blog/couchbase-adopts-bsl-license/, and therefore cannot be tested in Forgejo and neither should be supported.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4967): git-grep: allow searching for words with initial dashes.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4927): git-grep: skip binary files.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4924): [commit](https://codeberg.org/forgejo/forgejo/commit/bf7373a2520ae56a1dc00416efa02de9749b63d3) Forgejo Actions logs are compressed by default. It can be disabled by setting `[actions].LOG_COMPRESSION=none`.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4903): Support grouping by any path for arch package.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4891): Remove expensive nearest branch calculatations (`$.BranchName`) from commit diff view (`/:owner/:repo/commit/:commit`).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4819): Allow push mirrors to use a SSH key as the authentication method for the mirroring action instead of using user:password authentication. The SSH keypair is created by Forgejo and the destination repository must be configured with the public key to allow for push over SSH.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4801): [commit](https://codeberg.org/forgejo/forgejo/commit/11b6253e7532ba11dee8bc31d4c262b102674a4d) Use UTC as a timezone when running scheduled actions tasks.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4801): [commit](https://codeberg.org/forgejo/forgejo/commit/feb43b2584b7f64ec7f9952af2b50b2210e6e6cf) The actions logs older than `[actions].LOG_RETENTION_DAYS` days are removed (the default is 365).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4780): Add signature support for the RPM module.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4766): Allow color and background-color style properties for table cells.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4716): [commit](https://codeberg.org/forgejo/forgejo/commit/8d23433dab08fcbb8043e5d239171fba59c53108): support pull_request_target event for commit status.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4716): [commit](https://codeberg.org/forgejo/forgejo/commit/cb9071bbf433715f0e16e39cb60126b65f8236a0): support delete user email in admin panel.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4704): Notify owner about TOTP enrollment.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4635): Email notifications are now sent when account security changes are made: password changed, primary email changed (email sent to old primary mail), TOTP disabled or a security key removed.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4633): Enable `INVALIDATE_REFRESH_TOKENS`.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4625): Sort milestones by name by default instead of the due date.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4607): [commit](https://codeberg.org/forgejo/forgejo/commit/21fdd28f084e7f1aef309c9ebd7599ffa6986453) allow synchronizing user status from OAuth2 login providers.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4607): [commit](https://codeberg.org/forgejo/forgejo/commit/004cc6dc0ab7cc9c324ccb4ecd420c6aeeb20500) add option to change mail from user display name.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4607): [commit](https://codeberg.org/forgejo/forgejo/commit/d0227c236aa195bd03990210f968b8e52eb20b79) issue Templates: add option to have dropdown printed list.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4605): the default setting attachment.ALLOWED_TYPES was adjusted to allow .webp attachments in issues - a more efficient format for images like screenshots. All attachments are treated as normal files and are not re-encoded by Forgejo. If you have customized this setting, you may also want to add .webp to it for the benefit of your users, as well as to reduce server traffic and storage usage.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4542): Convert milestone to HTMX.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4516): Use the full user name in emails to address the recipient, when available.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4449): Enhancing OAuth2 Provider with Granular Scopes for Resource Access.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4429): [Display URLs in .sh-session files](https://github.com/buildkite/terminal-to-html/pull/163).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4367): The caching of contributor stats was improved (the data used by `///activity/recent-commits`) to use the configured cache TTL from the config (`[cache].ITEM_TTL`) instead of a hardcoded TTL of ten minutes. The computation of this operation is computationally heavy and makes a lot of requests to the database and Git on repositories with a lot of commits. It should be cached for longer than what was previously hardcoded, ten minutes.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4266): Add support for LFS server implementations which have batch API responses in an older/deprecated schema.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4218): [Forgejo Actions artifacts](https://forgejo.org/docs/next/user/actions/#artifacts) support [range requests](https://en.wikipedia.org/wiki/Byte_serving) to resume a download.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4212): Added the foundations of a flexible, configurable quota system.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/2869): Logs journald integration.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/1445): A release asset can be a URL instead of a file.
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5529) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5565)): Don't allow owner team with incorrect unit access (includes doctor fix).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5470) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5547)): Schedule workflows are canceled when pushing to the default branch.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5492) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5507)): Incorrect Discord webhook JSON for issue events.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5406)): [commit](https://codeberg.org/forgejo/forgejo/commit/f709de24039ab7e605d3e09e3b61240836381603) wrong last modify time.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5406)): [commit](https://codeberg.org/forgejo/forgejo/commit/2675a24649af2fff34f5c7e416d6ff78591d8d9c) Repo Activity: count new issues that were closed.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5406)): [commit](https://codeberg.org/forgejo/forgejo/commit/526054332acb221e061d3900bba2dc6e012da52d) incorrect /tokens API.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5372) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5406)): [commit](https://codeberg.org/forgejo/forgejo/commit/0cafec4c7a2faf810953e9d522faf5dc019e1522) Do not escape relative path in RPM primary index.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5325): [commit](https://codeberg.org/forgejo/forgejo/commit/eb765dabfd43e353bd2208e8375b102935d0f103) Handle invalid target when creating releases using API.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5325): [commit](https://codeberg.org/forgejo/forgejo/commit/5af168fb92e5dd3b0c81d97ba27a6f19739bef18) /repos/{owner}/{repo}/pulls/{index}/files endpoint not populating previous_filename.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5269): Improve textarea paste.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5195): [commit](https://codeberg.org/forgejo/forgejo/commit/196907e359420f63003f884d1cf827b4a4d7a4e5) Handle "close" actionable references for manual merges.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5195): [commit](https://codeberg.org/forgejo/forgejo/commit/46b1f2e7e4e795331f28f74666094c9416499e03) Team admins are allowed to search team members via the API.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5109): [commit](https://codeberg.org/forgejo/forgejo/commit/3ade4d9b2bfa6ae84a1ded932907a53060565575) Don't return 500 if mirror url contains special chars.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5109): [commit](https://codeberg.org/forgejo/forgejo/commit/dda53569b1b70507469fc296881eec89606ab9c3) Agit automerge is not working properly.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5075): Improve the display of PR & issue short links.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4978): Migrate scoped GitLab labels as scoped Forgejo labels.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4924): [commit](https://codeberg.org/forgejo/forgejo/commit/9812b7af91b69386c5d4c08982aece7bd8f9a174) /repos/{owner}/{repo}/pulls/{index} [requested_reviewers contains null for teams](https://codeberg.org/forgejo/forgejo/issues/4108).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4809): Validate title length when updating an issue.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4801): [commit](https://codeberg.org/forgejo/forgejo/commit/0dbc6230286e113accbc6d5e829ce8dae1d1f5d4) Hide the "Details" link of commit status when the user cannot access actions.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4801): [commit](https://codeberg.org/forgejo/forgejo/commit/6e63afe31f43eaf5ff7c8595ddeaf8515c2dc0c0) The API endpoint to get the actions registration token is GET /repos/{owner}/{repo}/actions/runners/registration-token and not GET /repos/{owner}/{repo}/runners/registration-token.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4801): [commit](https://codeberg.org/forgejo/forgejo/commit/6e63afe31f43eaf5ff7c8595ddeaf8515c2dc0c0) Runner registration token via API is broken for repo level runners.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4801): [commit](https://codeberg.org/forgejo/forgejo/commit/c784a5874066ca1a1fd518408d5767b4eb57bd69) Deleted projects causes bad popover text on issues.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4801): [commit](https://codeberg.org/forgejo/forgejo/commit/42bb51af9b8283071e15ac6470ada9824d87cd40) Distinguish LFS object errors to ignore missing objects during migration.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4801): [commit](https://codeberg.org/forgejo/forgejo/commit/6328f648decc2754ef10ee5ca6ca9785a156614c) When viewing the revision history of wiki pages, the pagination links are broken: instead of org/repo/wiki/Page?action=_revision&page=2, the link is only org/repo/wiki/Page?page=2, thus bringing the user back to the wiki page.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4801): [commit](https://codeberg.org/forgejo/forgejo/commit/2310556158d70bf1dbfca96dc928e1be3d3f41be) Also rename the head branch of open pull requests when renaming a branch.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4716): [commit](https://codeberg.org/forgejo/forgejo/commit/ee11a263f8c9de33d42fc117443f4054a311c875): add return type to GetRawFileOrLFS and GetRawFile.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4716): [commit](https://codeberg.org/forgejo/forgejo/commit/f61873c7e42b613405d367421ad19db80f831053): properly filter issue list given no assignees filter.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4698): Cron task to cleanup dangling container images with version sha256:*.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4619): Allow updates to runners' secrets.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4487): Do not fire webhook notifications for updates and deletions of comments that are part of an ongoing review (a review that is still in draft). Also, content history will not be saved for such comments, to avoid exposing fixing embarrassing typos you've have made while the review was still pending.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4427): Fixed social media previews for links to wiki pages.
+- Localization
+ - Updates of translations from [Codeberg Translate](https://translate.codeberg.org/projects/forgejo/forgejo/).
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4980): Improve the clarity of confirmation in email messages.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5523) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5534)): Fine tune language for units.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5537) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5538)): Improve translation strings for webhook events.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4829): Allow different translations of creation links and titles.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4599): English strings improvements for internationalization.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/4596): Encourage participation in the localization of Forgejo in language settings.
+
diff --git a/release-notes-published/9.0.1.md b/release-notes-published/9.0.1.md
new file mode 100644
index 0000000000..1cd9a56170
--- /dev/null
+++ b/release-notes-published/9.0.1.md
@@ -0,0 +1,33 @@
+
+
+## Release notes
+
+- Security bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5719) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5724)): Forgejo generates a token which is used to authenticate web endpoints that are only meant to be used internally, for instance when the SSH daemon is used to push a commit with Git. The verification of this token was not done in constant time and was susceptible to [timing attacks](https://en.wikipedia.org/wiki/Timing_attack). A pre-condition for such an attack is the precise measurements of the time for each operation. Since it requires observing the timing of network operations, the issue is mitigated when a Forgejo instance is accessed over the internet because the ISP introduce unpredictable random delays.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5718) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5721)): Because of a missing permission check, the branch used to propose a pull request to a repository can always be deleted by the user performing the merge. It was fixed so that such a deletion is only allowed if the user performing the merge has write permission to the repository from which the pull request was made.
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5439) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5708)): Fix boolean inputs in workflow_dispatch
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5634) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5636)): package arch database not updating when uploading "any" architecture
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5627) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5631)): correct SQL query for active issues
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5626) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5629)): specify default value for `EXPLORE_DEFAULT_SORT`.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5613) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5624)): fix: Add `recentupdated` as recognized sort option
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5616): Update dependency mermaid to v11.3.0 (v9.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5587) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5588)): Dockerfile: use alpine:3.20 instead of golang:1.23-alpine3.20
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5585) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5586)): Dockerfile: unnecessary container image layer duplication
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5647): [commit](https://codeberg.org/forgejo/forgejo/commit/1913399d8176944f170d4f1c032dc37003aaafc0) Always update expiration time when creating an artifact
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5647): [commit](https://codeberg.org/forgejo/forgejo/commit/4fe311e7c0292e3ac79f8bc063f1bcacef4494f0) Update scheduled tasks even if changes are pushed by "ActionsUser"
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5715): [commit](https://codeberg.org/forgejo/forgejo/commit/768402c8841db5e8acc97919149ba329d5124e17) Fix disable 2fa bug
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5583) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5680)): i18n: update of translations from Codeberg Translate
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5702) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5710)): fix: use buffered iterate for debian searchpackages
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5688) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5691)): fix: make branch protection work for new branches
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5651) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5656)): link to security policy in security.txt
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5653) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5655)): fix: don't show truncated comments in RSS/Atom feeds
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5652) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5654)): fix: typo on releases for source code downloads
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5640) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5645)): Revert "add gap between branch dropdown and PR button"
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5615) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5618)): fix: Don't double escape delete branch text
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5595) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5596)): fix: Add server logging for OAuth server errors
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5592) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5594)): forgejo-cli is now a symlink and cannot be used for sanity checks
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5491) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5575)): fix: correct documentation for non 200 responses in swagger
+
diff --git a/release-notes-published/9.0.2.md b/release-notes-published/9.0.2.md
new file mode 100644
index 0000000000..4a10e4981c
--- /dev/null
+++ b/release-notes-published/9.0.2.md
@@ -0,0 +1,26 @@
+
+
+## Release notes
+
+- Security bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5975)): [commit](https://codeberg.org/forgejo/forgejo/commit/1ce33aa38d1d258d14523ff2c7c2dbf339f22b74) it was possible to use a token sent via email for secondary email validation to reset the password instead. In other words, a token sent for a given action (registration, password reset or secondary email validation) could be used to perform a different action. It is no longer possible to use a token for an action that is different from its original purpose.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5975)): [commit](https://codeberg.org/forgejo/forgejo/commit/061abe60045212acf8c3f5c49b5cc758b4cbcde9) a fork of a public repository would show in the list of forks, even if its owner was not a public user or organization. Such a fork is now hidden from the list of forks of the public repository.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5975)): [commit](https://codeberg.org/forgejo/forgejo/commit/3e3ef76808100cb1c853378733d0f6a910324ac6) the members of an organization team with read access to a repository (e.g. to read issues) but no read access to the code could read the RSS or atom feeds which include the commit activity. Reading the RSS or atom feeds is now denied unless the team has read permissions on the code.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5975)): [commit](https://codeberg.org/forgejo/forgejo/commit/9508aa7713632ed40124a933d91d5766cf2369c2) the tokens used when [replying by email to issues or pull requests](https://forgejo.org/docs/v9.0/user/incoming/) were weaker than the [rfc2104 recommendations](https://datatracker.ietf.org/doc/html/rfc2104#section-5). The tokens are now truncated to 128 bits instead of 80 bits. It is no longer possible to reply to emails sent before the upgrade because the weaker tokens are invalid.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5975)): [commit](https://codeberg.org/forgejo/forgejo/commit/786dfc7fb81ee76d4292ca5fcb33e6ea7bdccc29) a registered user could modify the update frequency of any push mirror (e.g. every 4h instead of every 8h). They are now only able to do that if they have administrative permissions on the repository.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5975)): [commit](https://codeberg.org/forgejo/forgejo/commit/e6bbecb02d47730d3cc630d419fe27ef2fb5cb39) it was possible to use basic authorization (i.e. user:password) for requests to the API even when security keys were enrolled for a user. It is no longer possible, an application token must be used instead.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5975)): [commit](https://codeberg.org/forgejo/forgejo/commit/7067cc7da4f144cc8a2fd2ae6e5307e0465ace7f) some markup sanitation rules were not as strong as they could be (e.g. allowing `emoji somethingelse` as well as `emoji`). The rules are now stricter and do not allow for such cases.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5974) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5975)): [commit](https://codeberg.org/forgejo/forgejo/commit/b70196653f9d7d3b9d4e72d114e5cc6f472988c4) when Forgejo is configured to enable instance wide search (e.g. with [bleve](https://blevesearch.com/)), results found in the repositories of private or limited users were displayed to anonymous visitors. The results found in private or limited organizations were not displayed. The search results found in the repositories of private or limited user are no longer displayed to anonymous visitors.
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5941) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5945)): fix: handle renamed dependency for cargo registry.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5795) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5800)): support `www.github.com` for migrations.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5887): move forgot_password-link to fix login tab order.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5850) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5879)): code owners will not be mentioned when a pull request comes from a forked repository.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5831) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5834)): labels are missing in the pull request payload removing a label.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5778) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5810)): in a Forgejo Actions workflow, the `unlabeled` event type for pull requests was incorrectly mapped to the labeled event type.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5778) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5810)): when a Forgejo Actions issue or pull request workflow is triggered by an `labeled` or `unlabeled` event type, it misses information about the label added or removed. It is now available in the `label` data member of the event payload.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5778) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5810)): the pull request workflow must always update the head SHA commit status. Not just when the PR is synchronized, opened or closed. Otherwise, a job that is run more often than on commits (e.g. checking for specific labels or approvals) cannot be defined as a required check.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5746) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5759)): fix git-grep for code search when git version is below 2.38.
+- Localization
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5681) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5748)): i18n: update of translations from Codeberg Translate.
+
diff --git a/release-notes-published/9.0.3.md b/release-notes-published/9.0.3.md
new file mode 100644
index 0000000000..06ab9f152a
--- /dev/null
+++ b/release-notes-published/9.0.3.md
@@ -0,0 +1,39 @@
+
+
+
+
+## Release notes
+
+- Security bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6248) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6253)): When Forgejo is configured to run the internal ssh server with `[server].START_SSH_SERVER=true`, it was possible for a registered user to impersonate another user. The rootless container image uses the internal ssh server by default and was vulnerable. A Forgejo instance running from a binary or from a root container image does not use the internal ssh server by default and was not vulnerable. The incorrect use of the crypto package is the root cause of the vulnerability and was fixed for the internal ssh server.
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6249) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6251)): Revert "allow synchronizing user status from OAuth2 login providers"
+- User Interface bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6104): Fix wiki search overflowing on wide screens (#6047)
+- Bug fixes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6097) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6168)): Do not rewrite ssh keys files when deleting a user without one
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6124) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6129)): fix: doctor fails with pq: syntax error at or near "." whilst counting Authorization token without existing User
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6054) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6057)): fix: Do not delete global Oauth2 applications
+- Other changes without a feature or bug label
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6064): [gitea] week 2024-48-v9.0 cherry pick (gitea/main -> v9.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5998): [commit](https://codeberg.org/forgejo/forgejo/commit/53c546951115d9e269a2778f90e43b0cb413eab6) Strict matching of allowed content for sanitizer for asciicast and csv rendering
+- Included for completeness but not worth a release note
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6247): Update module golang.org/x/crypto to v0.31.0 (v9.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6223) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6231)): chore(ci): set the milestone when a pull request is closed (take 4)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6219) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6225)): chore(ci): set the milestone when a pull request is open (take 3)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6211) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6217)): chore(ci): set the milestone when a pull request is open
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6176): Update dependency @github/relative-time-element to v4.4.4 (v9.0/forgejo)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6152) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6155)): fix: remove softbreak from github legacy callout
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6144) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6149)): fix: correct permission loading for limited organisation
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6128) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6131)): fix: clean up log files that no longer exist
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6114) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6127)): fix: return correct type in `GetSubModule`
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6050) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6092)): Improve Swagger documentation for user endpoints
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6084) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6085)): fix: normalize guessed languages from enry
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6052) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6070)): Show page titles in wiki search results (#6048)
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6060): i18n: backport of translation updates 5754, 5845, 5960
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6034) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6035)): chore(ci): remove unused experimental DNS updates
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/6013) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6016)): fix(test): TestGitAttributeCheckerError must allow broken pipe
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5996) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6005)): fix: check read permissions for code owner review requests
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5989) ([backported](https://codeberg.org/forgejo/forgejo/pulls/6004)): fix: use better code to group UID and stopwatches
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5991) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5993)): fix: api repo compare with commit hashes
+ - [PR](https://codeberg.org/forgejo/forgejo/pulls/5986) ([backported](https://codeberg.org/forgejo/forgejo/pulls/5992)): bug: correctly generate oauth2 jwt signing key
+
diff --git a/release-notes-published/up-to-and-including-8.0.0.md b/release-notes-published/up-to-and-including-8.0.0.md
new file mode 120000
index 0000000000..a2fdedd0e1
--- /dev/null
+++ b/release-notes-published/up-to-and-including-8.0.0.md
@@ -0,0 +1 @@
+../RELEASE-NOTES.md
\ No newline at end of file
diff --git a/release-notes/8.0.0/3139.md b/release-notes/3139.md
similarity index 100%
rename from release-notes/8.0.0/3139.md
rename to release-notes/3139.md
diff --git a/release-notes/8.0.0/3285.md b/release-notes/3285.md
similarity index 100%
rename from release-notes/8.0.0/3285.md
rename to release-notes/3285.md
diff --git a/release-notes/8.0.0/feat/3307.md b/release-notes/3307.md
similarity index 100%
rename from release-notes/8.0.0/feat/3307.md
rename to release-notes/3307.md
diff --git a/release-notes/8.0.0/3334.md b/release-notes/3334.md
similarity index 100%
rename from release-notes/8.0.0/3334.md
rename to release-notes/3334.md
diff --git a/release-notes/8.0.0/feat/3337.md b/release-notes/3337.md
similarity index 100%
rename from release-notes/8.0.0/feat/3337.md
rename to release-notes/3337.md
diff --git a/release-notes/3363.md b/release-notes/3363.md
new file mode 100644
index 0000000000..426a44ac08
--- /dev/null
+++ b/release-notes/3363.md
@@ -0,0 +1 @@
+Reverted the rootless container image path in `GITEA_APP_INI` from `/etc/gitea/app.ini` to its default value of `/var/lib/gitea/custom/conf/app.ini`. This allows container users to not have to mount two separate volumes (one for the configuration data and one for the configuration `.ini` file). A warning is issued for users with the legacy configuration on how to update to the new path.
diff --git a/release-notes/8.0.0/3383.md b/release-notes/3383.md
similarity index 100%
rename from release-notes/8.0.0/3383.md
rename to release-notes/3383.md
diff --git a/release-notes/8.0.0/3414.md b/release-notes/3414.md
similarity index 100%
rename from release-notes/8.0.0/3414.md
rename to release-notes/3414.md
diff --git a/release-notes/8.0.0/fix/3430.md b/release-notes/3430.md
similarity index 100%
rename from release-notes/8.0.0/fix/3430.md
rename to release-notes/3430.md
diff --git a/release-notes/8.0.0/feat/3434.md b/release-notes/3434.md
similarity index 100%
rename from release-notes/8.0.0/feat/3434.md
rename to release-notes/3434.md
diff --git a/release-notes/8.0.0/fix/3442.md b/release-notes/3442.md
similarity index 100%
rename from release-notes/8.0.0/fix/3442.md
rename to release-notes/3442.md
diff --git a/release-notes/8.0.0/feat/3642.md b/release-notes/3642.md
similarity index 100%
rename from release-notes/8.0.0/feat/3642.md
rename to release-notes/3642.md
diff --git a/release-notes/8.0.0/feat/3654.md b/release-notes/3654.md
similarity index 100%
rename from release-notes/8.0.0/feat/3654.md
rename to release-notes/3654.md
diff --git a/release-notes/8.0.0/feat/3723.md b/release-notes/3723.md
similarity index 100%
rename from release-notes/8.0.0/feat/3723.md
rename to release-notes/3723.md
diff --git a/release-notes/8.0.0/3724.md b/release-notes/3724.md
similarity index 86%
rename from release-notes/8.0.0/3724.md
rename to release-notes/3724.md
index 8af3bc893c..5cc96f761e 100644
--- a/release-notes/8.0.0/3724.md
+++ b/release-notes/3724.md
@@ -1,6 +1,6 @@
- [CERT management was improved](https://codeberg.org/forgejo/forgejo/pulls/3724) when [`ENABLE_ACME=true`](https://forgejo.org/docs/v7.0/admin/config-cheat-sheet/#server-server)
- Draft support for draft-03 of [ACME Renewal Information (ARI)](https://datatracker.ietf.org/doc/draft-ietf-acme-ari/) which assists with deciding when to renew certificates. This augments CertMagic's already-advanced logic using cert lifetime and OCSP/revocation status.
- - New [`ZeroSSLIssuer`](https://pkg.go.dev/github.com/caddyserver/certmagic@v0.21.0#ZeroSSLIssuer) uses the [ZeroSSL API](https://zerossl.com/documentation/api/) to get certificates. ZeroSSL also has an ACME endpoint, which can still be accesed using the existing ACMEIssuer, as always. Their proprietary API is paid, but has extra features like IP certificates, better reliability, and support.
+ - New [`ZeroSSLIssuer`](https://pkg.go.dev/github.com/caddyserver/certmagic@v0.21.0#ZeroSSLIssuer) uses the [ZeroSSL API](https://zerossl.com/documentation/api/) to get certificates. ZeroSSL also has an ACME endpoint, which can still be accessed using the existing ACMEIssuer, as always. Their proprietary API is paid, but has extra features like IP certificates, better reliability, and support.
- DNS challenges should be smoother in some cases as we've improved propagation checking.
- In the odd case your ACME account disappears from the ACME server, CertMagic will automatically retry with a new account. (This happens in some test/dev environments.)
- ACME accounts are identified only by their public keys, but CertMagic maps accounts by CA+email for practical/storage reasons. So now you can "pin" an account key to use by specifying your email and the account public key in your config, which is useful if you need to absolutely be sure to use a specific account (like if you get rate limit exemptions from a CA).
diff --git a/release-notes/3729.md b/release-notes/3729.md
new file mode 100644
index 0000000000..6074f0e850
--- /dev/null
+++ b/release-notes/3729.md
@@ -0,0 +1,2 @@
+- feat: [commit](https://codeberg.org/forgejo/forgejo/commit/7028fe0b4d89c045b64ae891d2716e89965bc012): add actions-artifacts to the [storage migrate CLI](https://forgejo.org/docs/v8.0/admin/command-line/#migrate).
+- fix: [commit](https://codeberg.org/forgejo/forgejo/commit/8f0f6bf89cdcd12cd4daa761aa259fdba7e32b50): pull request search shows closed pull requests in the open tab.
diff --git a/release-notes/3752.md b/release-notes/3752.md
new file mode 100644
index 0000000000..358b31a7c7
--- /dev/null
+++ b/release-notes/3752.md
@@ -0,0 +1 @@
+There are a couple of new configs to define the name of the instance. The more important is `APP_SLOGAN`. It permits to configure a slogan for the site and it is optional. The other is `APP_DISPLAY_NAME_FORMAT` and permits to customize the aspect of the full display name for the instance used in some parts of the UI as: (i) Title page, (ii) Homepage head title (ii) Open Graph site and title meta tags. Its default value is `APP_NAME: APP_SLOGAN`. The config `APP_DISPLAY_NAME_FORMAT` is used only if `APP_SLOGAN` is set otherwise the full display name shows only `APP_NAME` value.
diff --git a/release-notes/8.0.0/feat/3791.md b/release-notes/3791.md
similarity index 100%
rename from release-notes/8.0.0/feat/3791.md
rename to release-notes/3791.md
diff --git a/release-notes/8.0.0/feat/3808.md b/release-notes/3808.md
similarity index 100%
rename from release-notes/8.0.0/feat/3808.md
rename to release-notes/3808.md
diff --git a/release-notes/8.0.0/3811.md b/release-notes/3811.md
similarity index 100%
rename from release-notes/8.0.0/3811.md
rename to release-notes/3811.md
diff --git a/release-notes/8.0.0/3830.md b/release-notes/3830.md
similarity index 100%
rename from release-notes/8.0.0/3830.md
rename to release-notes/3830.md
diff --git a/release-notes/8.0.0/feat/3836.md b/release-notes/3836.md
similarity index 100%
rename from release-notes/8.0.0/feat/3836.md
rename to release-notes/3836.md
diff --git a/release-notes/8.0.0/feat/3838.md b/release-notes/3838.md
similarity index 100%
rename from release-notes/8.0.0/feat/3838.md
rename to release-notes/3838.md
diff --git a/release-notes/3847.md b/release-notes/3847.md
new file mode 100644
index 0000000000..8467a72271
--- /dev/null
+++ b/release-notes/3847.md
@@ -0,0 +1 @@
+Basic wiki content search using git-grep. The search results include the first ten matched files. Only the first three matches per file are displayed.
diff --git a/release-notes/8.0.0/feat/3870.md b/release-notes/3870.md
similarity index 100%
rename from release-notes/8.0.0/feat/3870.md
rename to release-notes/3870.md
diff --git a/release-notes/8.0.0/feat/3886.md b/release-notes/3886.md
similarity index 100%
rename from release-notes/8.0.0/feat/3886.md
rename to release-notes/3886.md
diff --git a/release-notes/3917.md b/release-notes/3917.md
new file mode 100644
index 0000000000..4e551adf83
--- /dev/null
+++ b/release-notes/3917.md
@@ -0,0 +1 @@
+support [setting the default attribute of the issue template dropdown field](https://codeberg.org/forgejo/forgejo/commit/df15abd07264138fd07e003d0cf056f7da514b8f)
diff --git a/release-notes/3922.md b/release-notes/3922.md
new file mode 100644
index 0000000000..d05a78dd8e
--- /dev/null
+++ b/release-notes/3922.md
@@ -0,0 +1,5 @@
+- feat: [`1e983e7`](https://github.com/alecthomas/chroma/commit/1e983e7) lexers/cue: support CUE attributes ([#961](https://github.com/alecthomas/chroma/issues/961))
+- feat: [`9347b55`](https://github.com/alecthomas/chroma/commit/9347b55) Add Gleam syntax highlighting ([#959](https://github.com/alecthomas/chroma/issues/959))
+- feat: [`2580aaa`](https://github.com/alecthomas/chroma/commit/2580aaa) Add Bazel bzlmod support into Python lexer ([#947](https://github.com/alecthomas/chroma/issues/947))
+- fix: [`736c0ea`](https://github.com/alecthomas/chroma/commit/736c0ea) Typescript: Several fixes ([#952](https://github.com/alecthomas/chroma/issues/952))
+- fix: [`e5c25d0`](https://github.com/alecthomas/chroma/commit/e5c25d0) Org: Keep all newlines ([#951](https://github.com/alecthomas/chroma/issues/951))
diff --git a/release-notes/8.0.0/3934.md b/release-notes/3934.md
similarity index 100%
rename from release-notes/8.0.0/3934.md
rename to release-notes/3934.md
diff --git a/release-notes/8.0.0/feat/3985.md b/release-notes/3985.md
similarity index 100%
rename from release-notes/8.0.0/feat/3985.md
rename to release-notes/3985.md
diff --git a/release-notes/3989.md b/release-notes/3989.md
new file mode 100644
index 0000000000..005729690e
--- /dev/null
+++ b/release-notes/3989.md
@@ -0,0 +1,4 @@
+- feat: API endpoints that return a repository now [also include the topics](https://codeberg.org/forgejo/forgejo/commit/ee2247d77c0b13b0b45df704d7589b541db03899).
+- feat: display an error when an issue comment is [edited simultaneously by two users](https://codeberg.org/forgejo/forgejo/commit/ca0921a95aa9a37d8820538458c15fd0a3b0c97c) instead of silently overriding one of them.
+- feat: add [support for a credentials chain for minio](https://codeberg.org/forgejo/forgejo/commit/73706ae26d138684ef9da9e1164846a040fd4a7d).
+- feat(perf): improve performances when [retrieving pull requests via the API](https://codeberg.org/forgejo/forgejo/commit/47a2102694c47bc30a2a7c673c328471839ef206).
diff --git a/release-notes/8.0.0/fix/4026.md b/release-notes/4026.md
similarity index 100%
rename from release-notes/8.0.0/fix/4026.md
rename to release-notes/4026.md
diff --git a/release-notes/4027.md b/release-notes/4027.md
new file mode 100644
index 0000000000..710f827706
--- /dev/null
+++ b/release-notes/4027.md
@@ -0,0 +1 @@
+- Gitea/Forgejo webhook payload include additional fields (`html_url`, `additions`, `deletions`, `review_comments`...) for better compatibility with [OpenProject](https://www.openproject.org/), ported from [gitea#28435](https://github.com/go-gitea/gitea/pull/28435).
diff --git a/release-notes/4072.md b/release-notes/4072.md
new file mode 100644
index 0000000000..8e28b73b31
--- /dev/null
+++ b/release-notes/4072.md
@@ -0,0 +1,2 @@
+- Added Enter key handling to the new Markdown editor: Pressing Enter while in a list, quote or code block will copy the prefix to the new line - Ordered list index will be increased for the new line, and task list "checkbox" will be unchecked.
+- Added indent/unindent function for a line or selection. Currently available as toolbar buttons ([#4263](https://codeberg.org/forgejo/forgejo/pulls/4263)).
diff --git a/release-notes/4083.md b/release-notes/4083.md
new file mode 100644
index 0000000000..0a9e3b3c91
--- /dev/null
+++ b/release-notes/4083.md
@@ -0,0 +1,3 @@
+- feat: add [Reviewed-on and Reviewed-by variables](https://codeberg.org/forgejo/forgejo/commit/4ddd9af50fbfcfb2ebf629697a803b3bce56c4af) to the merge template.
+- feat(perf): [add the `[ui.csv].MAX_ROWS` setting](https://codeberg.org/forgejo/forgejo/commit/433b6c6910f8699dc41787ef8f5148b122b4677e) to avoid displaying a large number of lines (defaults to 2500).
+- feat: [add a setting to override or add headers of all outgoing emails](https://codeberg.org/forgejo/forgejo/commit/1d4bff4f65d5e4a3969871ef91d3612daf272b45), for instance `Reply-To` or `In-Reply-To`.
diff --git a/release-notes/8.0.0/4095.md b/release-notes/4095.md
similarity index 100%
rename from release-notes/8.0.0/4095.md
rename to release-notes/4095.md
diff --git a/release-notes/4125.md b/release-notes/4125.md
new file mode 100644
index 0000000000..4e1e401285
--- /dev/null
+++ b/release-notes/4125.md
@@ -0,0 +1 @@
+Added link to show all Issues/PullRequests
diff --git a/release-notes/8.0.0/feat/4134.md b/release-notes/4134.md
similarity index 100%
rename from release-notes/8.0.0/feat/4134.md
rename to release-notes/4134.md
diff --git a/release-notes/8.0.0/feat/4136.md b/release-notes/4136.md
similarity index 100%
rename from release-notes/8.0.0/feat/4136.md
rename to release-notes/4136.md
diff --git a/release-notes/4139.md b/release-notes/4139.md
new file mode 100644
index 0000000000..a85aac90e0
--- /dev/null
+++ b/release-notes/4139.md
@@ -0,0 +1 @@
+reorder repo tabs for better UX: (i) `Actions` is now the last tab (ii) `Packages` are located after Releases (iii) this puts Projects after Pull requests. (tab positions may depend on which units are enabled in the repo).
diff --git a/release-notes/8.0.0/feat/4143.md b/release-notes/4143.md
similarity index 100%
rename from release-notes/8.0.0/feat/4143.md
rename to release-notes/4143.md
diff --git a/release-notes/4145.md b/release-notes/4145.md
new file mode 100644
index 0000000000..77eb126bb9
--- /dev/null
+++ b/release-notes/4145.md
@@ -0,0 +1,6 @@
+- feat(perf): [commit](https://codeberg.org/forgejo/forgejo/commit/358cd67c4f316f2d4f1d3be6dcb891dc04a2ff07) reduce memory usage for chunked artifact uploads to S3.
+- feat: [commit](https://codeberg.org/forgejo/forgejo/commit/b60e3ac7b4aeeb9b8760f43eea9576c0e23309e9) allow downloading draft releases assets.
+- feat: [commit](https://codeberg.org/forgejo/forgejo/commit/1fca15529ac8fefb60d86b0c1f4bec8dae9a8566) API endpoints for managing tag protection.
+- feat: [commit](https://codeberg.org/forgejo/forgejo/commit/4334c705b5f9388b16af23c7e75a69d027d07d5e) extract and display readme and comments for Composer packages.
+- fix: [commit](https://codeberg.org/forgejo/forgejo/commit/364922c6e4f28264add9e2501a352c25ad6a0993) when a repository is adopted, its object format is not set in the database.
+- fix: [commit](https://codeberg.org/forgejo/forgejo/commit/e7f332a55d6a48a3f3b4f2bfa43d18455ac00acc) during a migration from bitbucket, LFS downloads fail.
diff --git a/release-notes/4160.md b/release-notes/4160.md
new file mode 100644
index 0000000000..9a6bf64674
--- /dev/null
+++ b/release-notes/4160.md
@@ -0,0 +1 @@
+Added support for fuzzy searching issues and pulls - support for `/issues` and `/pulls` were ported from [`gitea#be5be0ac81`](https://github.com/go-gitea/gitea/commit/be5be0ac81ce50ad5adb079af6ca4e8c396aaece) - support for `/user/repo/issues` and `/user/repo/pulls` were added
diff --git a/release-notes/8.0.0/4189.md b/release-notes/4189.md
similarity index 100%
rename from release-notes/8.0.0/4189.md
rename to release-notes/4189.md
diff --git a/release-notes/8.0.0/4201.md b/release-notes/4201.md
similarity index 100%
rename from release-notes/8.0.0/4201.md
rename to release-notes/4201.md
diff --git a/release-notes/4212.md b/release-notes/4212.md
new file mode 100644
index 0000000000..92fc9e9de1
--- /dev/null
+++ b/release-notes/4212.md
@@ -0,0 +1 @@
+Added the foundations of a flexible, configurable quota system
diff --git a/release-notes/4218.md b/release-notes/4218.md
new file mode 100644
index 0000000000..88591edf37
--- /dev/null
+++ b/release-notes/4218.md
@@ -0,0 +1 @@
+[Forgejo Actions artifacts](https://forgejo.org/docs/next/user/actions/#artifacts) support [range requests](https://en.wikipedia.org/wiki/Byte_serving) to resume a download
diff --git a/release-notes/8.0.0/fix/4222.md b/release-notes/4222.md
similarity index 100%
rename from release-notes/8.0.0/fix/4222.md
rename to release-notes/4222.md
diff --git a/release-notes/8.0.0/fix/4240.md b/release-notes/4240.md
similarity index 100%
rename from release-notes/8.0.0/fix/4240.md
rename to release-notes/4240.md
diff --git a/release-notes/4253.md b/release-notes/4253.md
new file mode 100644
index 0000000000..1533c2a734
--- /dev/null
+++ b/release-notes/4253.md
@@ -0,0 +1 @@
+- unknown git push options are rejected instead of being ignored
diff --git a/release-notes/8.0.0/feat/4262.md b/release-notes/4262.md
similarity index 100%
rename from release-notes/8.0.0/feat/4262.md
rename to release-notes/4262.md
diff --git a/release-notes/4266.md b/release-notes/4266.md
new file mode 100644
index 0000000000..3c9baf5d70
--- /dev/null
+++ b/release-notes/4266.md
@@ -0,0 +1 @@
+- add support for LFS server implementations which have batch API responses in an older/deprecated schema
diff --git a/release-notes/4291.md b/release-notes/4291.md
new file mode 100644
index 0000000000..58c17c41b5
--- /dev/null
+++ b/release-notes/4291.md
@@ -0,0 +1 @@
+add support for \emph when rendering KaTeX
diff --git a/release-notes/4367.md b/release-notes/4367.md
new file mode 100644
index 0000000000..b5528617f0
--- /dev/null
+++ b/release-notes/4367.md
@@ -0,0 +1 @@
+The caching of contributor stats was improved (the data used by `///activity/recent-commits`) to use the configured cache TTL from the config (`[cache].ITEM_TTL`) instead of a hardcoded TTL of ten minutes. The computation of this operation is computationally heavy and makes a lot of requests to the database and Git on repositories with a lot of commits. It should be cached for longer than what was previously hardcoded, ten minutes.
diff --git a/release-notes/4375.md b/release-notes/4375.md
new file mode 100644
index 0000000000..b0c5654037
--- /dev/null
+++ b/release-notes/4375.md
@@ -0,0 +1 @@
+the "View command line instructions" link in pull requests and the "Copy content" button in file editor are not accessible
diff --git a/release-notes/4400.md b/release-notes/4400.md
new file mode 100644
index 0000000000..b8976a5ce5
--- /dev/null
+++ b/release-notes/4400.md
@@ -0,0 +1 @@
+the user interface of the login page is modified
diff --git a/release-notes/4427.md b/release-notes/4427.md
new file mode 100644
index 0000000000..3556a8f13d
--- /dev/null
+++ b/release-notes/4427.md
@@ -0,0 +1 @@
+Fixed social media previews for links to wiki pages.
diff --git a/release-notes/4429.md b/release-notes/4429.md
new file mode 100644
index 0000000000..b8d6e1cf57
--- /dev/null
+++ b/release-notes/4429.md
@@ -0,0 +1 @@
+[display URLs in .sh-session files](https://github.com/buildkite/terminal-to-html/pull/163)
diff --git a/release-notes/4439.md b/release-notes/4439.md
new file mode 100644
index 0000000000..60b9539a64
--- /dev/null
+++ b/release-notes/4439.md
@@ -0,0 +1 @@
+Make descriptions of user privacy settings more visible and clear
diff --git a/release-notes/4487.md b/release-notes/4487.md
new file mode 100644
index 0000000000..3c2767a427
--- /dev/null
+++ b/release-notes/4487.md
@@ -0,0 +1 @@
+Do not fire webhook notifications for updates and deletions of comments that are part of an ongoing review (a review that is still in draft). Also, content history will not be saved for such comments, to avoid exposing fixing embarrassing typos you've have made while the review was still pending.
diff --git a/release-notes/4506.md b/release-notes/4506.md
new file mode 100644
index 0000000000..b402494bb9
--- /dev/null
+++ b/release-notes/4506.md
@@ -0,0 +1 @@
+Replaced the openpgp library to use a maintained version, github.com/ProtonMail/go-crypto. This change also went hand in hand with doing correct revocation checks (instead of merely checking if a revocation signature existed) and using the expiration of a subkey if one existed instead of always using the expiration of the default key.
diff --git a/release-notes/4547.md b/release-notes/4547.md
new file mode 100644
index 0000000000..08f131fccd
--- /dev/null
+++ b/release-notes/4547.md
@@ -0,0 +1 @@
+The milestone section in the sidebar on the issue and pull request page now uses HTMX. If you update the milestone of a issue or pull request it will no longer reload the whole page and instead update the current page with the new information about the milestone update. This should provide a smoother user experience.
diff --git a/release-notes/4595.md b/release-notes/4595.md
new file mode 100644
index 0000000000..8bfffc83be
--- /dev/null
+++ b/release-notes/4595.md
@@ -0,0 +1 @@
+Repository citation: Removed the ability to export citations in APA format. [Read more in the companion blog post](https://forgejo.org/2024-07-non-free-dependency-found/)
diff --git a/release-notes/4605.md b/release-notes/4605.md
new file mode 100644
index 0000000000..90d0ed5456
--- /dev/null
+++ b/release-notes/4605.md
@@ -0,0 +1 @@
+feat: the default setting attachment.ALLOWED_TYPES was adjusted to allow .webp attachments in issues - a more efficient format for images like screenshots. All attachments are treated as normal files and are not re-encoded by Forgejo. If you have customized this setting, you may also want to add .webp to it for the benefit of your users, as well as to reduce server traffic and storage usage.
diff --git a/release-notes/4607.md b/release-notes/4607.md
new file mode 100644
index 0000000000..586225bcde
--- /dev/null
+++ b/release-notes/4607.md
@@ -0,0 +1,3 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/21fdd28f084e7f1aef309c9ebd7599ffa6986453) allow synchronizing user status from OAuth2 login providers.
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/004cc6dc0ab7cc9c324ccb4ecd420c6aeeb20500) add option to change mail from user display name.
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/d0227c236aa195bd03990210f968b8e52eb20b79) issue Templates: add option to have dropdown printed list.
diff --git a/release-notes/4635.md b/release-notes/4635.md
new file mode 100644
index 0000000000..42ace0c2f9
--- /dev/null
+++ b/release-notes/4635.md
@@ -0,0 +1 @@
+Email notifications are now sent when account security changes are made: password changed, primary email changed (email sent to old primary mail), TOTP disabled or a security key removed.
diff --git a/release-notes/4684.md b/release-notes/4684.md
new file mode 100644
index 0000000000..497d580642
--- /dev/null
+++ b/release-notes/4684.md
@@ -0,0 +1 @@
+Forgejo v9.0 is GPLv3+. Read more in [the companion blog post](https://forgejo.org/2024-08-gpl/).
diff --git a/release-notes/4716.md b/release-notes/4716.md
new file mode 100644
index 0000000000..e47f43ce16
--- /dev/null
+++ b/release-notes/4716.md
@@ -0,0 +1,4 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/8d23433dab08fcbb8043e5d239171fba59c53108): support pull_request_target event for commit status.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/ee11a263f8c9de33d42fc117443f4054a311c875): add return type to GetRawFileOrLFS and GetRawFile.
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/cb9071bbf433715f0e16e39cb60126b65f8236a0): support delete user email in admin panel.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/f61873c7e42b613405d367421ad19db80f831053): properly filter issue list given no assignees filter.
diff --git a/release-notes/4724.md b/release-notes/4724.md
new file mode 100644
index 0000000000..4037c710b0
--- /dev/null
+++ b/release-notes/4724.md
@@ -0,0 +1 @@
+OIDC integrations that POST to `/login/oauth/introspect` without sending HTTP basic authentication will now fail with a 401 HTTP Unauthorized error. To fix the error, the client must begin sending HTTP basic authentication with a valid client ID and secret. This endpoint was previously authenticated via the introspection token itself, which is less secure.
diff --git a/release-notes/4801.md b/release-notes/4801.md
new file mode 100644
index 0000000000..c0f7b0d278
--- /dev/null
+++ b/release-notes/4801.md
@@ -0,0 +1,9 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/0dbc6230286e113accbc6d5e829ce8dae1d1f5d4) Hide the "Details" link of commit status when the user cannot access actions.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/6e63afe31f43eaf5ff7c8595ddeaf8515c2dc0c0) The API endpoint to get the actions registration token is GET /repos/{owner}/{repo}/actions/runners/registration-token and not GET /repos/{owner}/{repo}/runners/registration-token.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/6e63afe31f43eaf5ff7c8595ddeaf8515c2dc0c0) Runner registration token via API is broken for repo level runners.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/c784a5874066ca1a1fd518408d5767b4eb57bd69) Deleted projects causes bad popover text on issues.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/42bb51af9b8283071e15ac6470ada9824d87cd40) Distinguish LFS object errors to ignore missing objects during migration.
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/11b6253e7532ba11dee8bc31d4c262b102674a4d) Use UTC as a timezone when running scheduled actions tasks.
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/feb43b2584b7f64ec7f9952af2b50b2210e6e6cf) The actions logs older than `[actions].LOG_RETENTION_DAYS` days are removed (the default is 365).
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/6328f648decc2754ef10ee5ca6ca9785a156614c) When viewing the revision history of wiki pages, the pagination links are broken: instead of org/repo/wiki/Page?action=_revision&page=2, the link is only org/repo/wiki/Page?page=2, thus bringing the user back to the wiki page.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/2310556158d70bf1dbfca96dc928e1be3d3f41be) Also rename the head branch of open pull requests when renaming a branch.
diff --git a/release-notes/4819.md b/release-notes/4819.md
new file mode 100644
index 0000000000..88c3f77326
--- /dev/null
+++ b/release-notes/4819.md
@@ -0,0 +1 @@
+Allow push mirrors to use a SSH key as the authentication method for the mirroring action instead of using user:password authentication. The SSH keypair is created by Forgejo and the destination repository must be configured with the public key to allow for push over SSH.
diff --git a/release-notes/4907.md b/release-notes/4907.md
new file mode 100644
index 0000000000..7c6cbdd7fc
--- /dev/null
+++ b/release-notes/4907.md
@@ -0,0 +1 @@
+Reverted a change from Gitea which prevented allow/reject reviews on merged or closed PRs. This change was not considered by the Forgejo UI team and there is a consensus that it feels like a regression, since it interferes with workflows known to be used by Forgejo users without providing a tangible benefit.
diff --git a/release-notes/4924.md b/release-notes/4924.md
new file mode 100644
index 0000000000..6ef951be6d
--- /dev/null
+++ b/release-notes/4924.md
@@ -0,0 +1,2 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/9812b7af91b69386c5d4c08982aece7bd8f9a174) /repos/{owner}/{repo}/pulls/{index} [requested_reviewers contains null for teams](https://codeberg.org/forgejo/forgejo/issues/4108).
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/bf7373a2520ae56a1dc00416efa02de9749b63d3) Forgejo Actions logs are compressed by default. It can be disabled by setting `[actions].LOG_COMPRESSION=none`.
diff --git a/release-notes/4941.md b/release-notes/4941.md
new file mode 100644
index 0000000000..85b896a8d3
--- /dev/null
+++ b/release-notes/4941.md
@@ -0,0 +1 @@
+Drop support to build Forgejo with the optional go-git Git backend. It only affects users who built Forgejo manually using `TAGS=gogits`, which no longer has any effect. Moving forward, we only support the default backend using the git binary. Please get in touch if you used the go-git backend and require any assistance moving away from it.
diff --git a/release-notes/4998.md b/release-notes/4998.md
new file mode 100644
index 0000000000..436d5201f1
--- /dev/null
+++ b/release-notes/4998.md
@@ -0,0 +1,4 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/7f1db1df3ee8d620f997b8e70a40c2f48ae96c0f) Show lock owner instead of repo owner on LFS setting page.
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/ebfdc659d814561f8783094e2eb26738a5500e55) Render plain text file if the LFS object doesn't exist.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/9e066c3cad7bb1b30e2def34bd0608aac825cf58) Fix panic of ssh public key page after deletion of auth source.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/a8e25e907c66140961f28ba92403176c816dfb60) Add missing repository type filter parameters to pager.
diff --git a/release-notes/5065.md b/release-notes/5065.md
new file mode 100644
index 0000000000..9399d681f5
--- /dev/null
+++ b/release-notes/5065.md
@@ -0,0 +1 @@
+when a Forgejo Actions workflow includes a `workflow_dispatch` with `inputs` and other events (for instance `push`), it is silently ignored because of a parsing error.
diff --git a/release-notes/5090.md b/release-notes/5090.md
new file mode 100644
index 0000000000..dba7855147
--- /dev/null
+++ b/release-notes/5090.md
@@ -0,0 +1 @@
+Remove support for Couchbase as a session provider; it instead will now fallback to the file provider. The rationale for removing Couchbase support is that it's not free software, https://www.couchbase.com/blog/couchbase-adopts-bsl-license/, and therefore cannot be tested in Forgejo and neither should be supported.
diff --git a/release-notes/5109.md b/release-notes/5109.md
new file mode 100644
index 0000000000..b3aecd8100
--- /dev/null
+++ b/release-notes/5109.md
@@ -0,0 +1,2 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/3ade4d9b2bfa6ae84a1ded932907a53060565575) Don't return 500 if mirror url contains special chars
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/dda53569b1b70507469fc296881eec89606ab9c3) Fix agit automerge
diff --git a/release-notes/5120.md b/release-notes/5120.md
new file mode 100644
index 0000000000..d502b21874
--- /dev/null
+++ b/release-notes/5120.md
@@ -0,0 +1,2 @@
+feat: Language detection in the repository learned about the following languages: [Luau](https://github.com/github-linguist/linguist/pull/6612), [BQN](https://github.com/github-linguist/linguist/pull/6623), [Cron table](https://github.com/github-linguist/linguist/pull/6759), [NMODL](https://github.com/github-linguist/linguist/pull/6776), [Pkl](https://github.com/github-linguist/linguist/pull/6730), [templ](https://github.com/github-linguist/linguist/pull/6798), [FIRRTL](https://github.com/github-linguist/linguist/pull/6848), [Julia REPL](https://github.com/github-linguist/linguist/pull/6859), [Caddyfile](https://github.com/github-linguist/linguist/pull/6862).
+feat: The following extensions or filenames in a repository are associated with the matching language: [.sublime-color-scheme](https://github.com/github-linguist/linguist/pull/6758), [MODULE.bazel.lock](https://github.com/github-linguist/linguist/pull/6783), [Cargo.toml.orig](https://github.com/github-linguist/linguist/pull/6787), [tsx](https://github.com/github-linguist/linguist/pull/6788), [justfile](https://github.com/github-linguist/linguist/pull/6795), [.zig.zon](https://github.com/github-linguist/linguist/pull/6820), [.envrc](https://github.com/github-linguist/linguist/pull/6865).
diff --git a/release-notes/5149.md b/release-notes/5149.md
new file mode 100644
index 0000000000..1f508d282c
--- /dev/null
+++ b/release-notes/5149.md
@@ -0,0 +1 @@
+The scope of application tokens is not verified when writing containers or Conan packages. This is of no consequence when the user associated with the application token does not have write access to packages. If the user has write access to packages, such a token can be used to write containers and Conan packages.
diff --git a/release-notes/5195.md b/release-notes/5195.md
new file mode 100644
index 0000000000..3c4990ccfa
--- /dev/null
+++ b/release-notes/5195.md
@@ -0,0 +1,2 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/196907e359420f63003f884d1cf827b4a4d7a4e5) Handle "close" actionable references for manual merges.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/46b1f2e7e4e795331f28f74666094c9416499e03) Team admins are allowed to search team members via the API.
diff --git a/release-notes/5205.md b/release-notes/5205.md
new file mode 100644
index 0000000000..f98e32ab63
--- /dev/null
+++ b/release-notes/5205.md
@@ -0,0 +1,3 @@
+feat: mermaid: [Add support for iconify icons](https://github.com/mermaid-js/mermaid/pull/5793).
+feat: mermaid: [Allow multi-line relationship labels](https://github.com/mermaid-js/mermaid/pull/5711).
+feat: mermaid: [Adds architecture diagrams which allows users to show relations between services](https://github.com/mermaid-js/mermaid/pull/5452).
diff --git a/release-notes/5325.md b/release-notes/5325.md
new file mode 100644
index 0000000000..497944bdf4
--- /dev/null
+++ b/release-notes/5325.md
@@ -0,0 +1,3 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/eb765dabfd43e353bd2208e8375b102935d0f103) Handle invalid target when creating releases using API.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/5af168fb92e5dd3b0c81d97ba27a6f19739bef18) /repos/{owner}/{repo}/pulls/{index}/files endpoint not populating previous_filename.
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/2da0ebbd2314f12b287694c378a888311dd337bc) Support allowed hosts for migrations to work with proxy.
diff --git a/release-notes/5372.md b/release-notes/5372.md
new file mode 100644
index 0000000000..fccb305f34
--- /dev/null
+++ b/release-notes/5372.md
@@ -0,0 +1,5 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/9d3473119893ffde0ab36d98e7a0e41c5d0ba9a3) Add bin to Composer Metadata.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/f709de24039ab7e605d3e09e3b61240836381603) Fix wrong last modify time.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/2675a24649af2fff34f5c7e416d6ff78591d8d9c) Repo Activity: count new issues that were closed.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/526054332acb221e061d3900bba2dc6e012da52d) Fix incorrect /tokens api.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/0cafec4c7a2faf810953e9d522faf5dc019e1522) Do not escape relative path in RPM primary index.
diff --git a/release-notes/5416.md b/release-notes/5416.md
new file mode 100644
index 0000000000..1368b952ae
--- /dev/null
+++ b/release-notes/5416.md
@@ -0,0 +1,3 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/8178d6eaba64d05799fd3b62fa889bd13bee07c7) Code search results when using the bleve indexer are sorted by relevance.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/b496317b5a2aea970bc94ccf6fcde35cd417ec20) After migrating a repository that contains merged pull requests, the branch is missing and cannot be deleted.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/a226064711899da07d6b1455a68ef758f2f3e7e0) Forgejo Actions artifact v4 upload above 8MB.
diff --git a/release-notes/5459.md b/release-notes/5459.md
new file mode 100644
index 0000000000..fb1c5b873c
--- /dev/null
+++ b/release-notes/5459.md
@@ -0,0 +1 @@
+feat: New mermaid [flowchart shapes](https://mermaid.js.org/syntax/flowchart.html#complete-list-of-new-shapes).
diff --git a/release-notes/5477.md b/release-notes/5477.md
new file mode 100644
index 0000000000..3f735e043f
--- /dev/null
+++ b/release-notes/5477.md
@@ -0,0 +1,3 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/af901ac7bb03d27f175f2292581fc67fa9c8d567) Add support for searching users by email.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/1dfe58ad11bc6fdc73a2b5ffb3c1481fbddbf46b) PR creation on forked repositories.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/b67b7c12385059898fc8cb7997755a88b3afa483) the logic of finding the latest pull review commit ID is incorrect.
diff --git a/release-notes/5515.md b/release-notes/5515.md
new file mode 100644
index 0000000000..46671195e1
--- /dev/null
+++ b/release-notes/5515.md
@@ -0,0 +1 @@
+**Fixing this bug is a breaking change because existing tokens with a public scope will no longer return private resources. They have to be deleted and re-created without the public scope to restore their original behavior**. The public scope of an application token does not filter out private repositories, organizations or packages in some cases. This scope is not the default, it has to be manually set via the web UI or the API. When the public scope is explicitly added to an application token that is allowed to list the repositories and packages of a user or an organization, it is meant as a restriction. For instance if a user has two repositories, one private and the other publicly visible, a token with the public scope used with the API endpoint listing the repositories that belong to this user must only return the publicly visible one and not reveal the existence of the private one.
diff --git a/release-notes/5543.md b/release-notes/5543.md
new file mode 100644
index 0000000000..5218deddc5
--- /dev/null
+++ b/release-notes/5543.md
@@ -0,0 +1 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/d0af8fe4dc7b294fe5409b2271468494267d5a7d) Allow filtering pull requests by poster in the API.
diff --git a/release-notes/5601.md b/release-notes/5601.md
new file mode 100644
index 0000000000..9a186e880f
--- /dev/null
+++ b/release-notes/5601.md
@@ -0,0 +1,2 @@
+feat: Language detection in the repository learned about the following languages: [Java Template Engine](https://github.com/github-linguist/linguist/pull/6610), [Noir](https://github.com/github-linguist/linguist/pull/6432), [Cylc](https://github.com/github-linguist/linguist/pull/6832), [iCalendar](https://github.com/github-linguist/linguist/pull/6940), [vCard (aka. VCF: Virtual Contact File) and Variant Call Format (VCF)](https://github.com/github-linguist/linguist/pull/6941), [B4X](https://github.com/github-linguist/linguist/pull/6965), [Carbon](https://github.com/github-linguist/linguist/pull/7011), [LiveCode Script](https://github.com/github-linguist/linguist/pull/6833), [Dune (OCaml build system)](https://github.com/github-linguist/linguist/pull/6814).
+feat: The following extensions or filenames in a repository are associated with the matching language: [deno.lock](https://github.com/github-linguist/linguist/pull/6885), [uv.lock](https://github.com/github-linguist/linguist/pull/7006), [HOSTS.TXT](https://github.com/github-linguist/linguist/pull/7014), [.peggy](https://github.com/github-linguist/linguist/pull/7017), [.resource](https://github.com/github-linguist/linguist/pull/6500).
diff --git a/release-notes/5621.md b/release-notes/5621.md
new file mode 100644
index 0000000000..973c6f880d
--- /dev/null
+++ b/release-notes/5621.md
@@ -0,0 +1,5 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/f3f386545ee97b91f1aaac4142480e70a443c655) Always update expiration time when creating an artifact, so that artifacts from re-ran jobs do not get lost.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/c163bf6fb55c922ab0cf552b47475fc8fc8b99d9) Remove the button toolbar when deleting a diff comment.
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/c3741d7fb0114691da73f00ae0ac9dced87e884d) The `requested_reviewers` data is included in more webhook events.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/e8700cee612f0aa769dc6929772d9b04c6c21807) Run scheduled tasks against the latest commit.
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/89446e60a6e7ec3441f0c480164c09851ae54ce7) Support migrating GitHub/GitLab PR draft status.
diff --git a/release-notes/5677.md b/release-notes/5677.md
new file mode 100644
index 0000000000..d089cbf01a
--- /dev/null
+++ b/release-notes/5677.md
@@ -0,0 +1 @@
+If you select a portion of a comment and use the 'Quote reply' feature in the context menu, only that portion will be quoted. The markdown syntax is preserved.
diff --git a/release-notes/5714.md b/release-notes/5714.md
new file mode 100644
index 0000000000..968ad8bb51
--- /dev/null
+++ b/release-notes/5714.md
@@ -0,0 +1,3 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/d13a4ab5632d6a9697bd0907f9c69ed57d949340) Fixed a bug related to disabling two-factor authentication
+chore: [commit](https://codeberg.org/forgejo/forgejo/commit/ab26d880932dbc116c43ea277029984c7a6d4e94) Emit a log message when failing to delete an inactive user
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/ab660c5944d59cdb4ecc071401445ac9f53cee45) Add `DISABLE_ORGANIZATIONS_PAGE` and `DISABLE_CODE_PAGE` settings for explore pages
diff --git a/release-notes/5718.md b/release-notes/5718.md
new file mode 100644
index 0000000000..f44178d1fe
--- /dev/null
+++ b/release-notes/5718.md
@@ -0,0 +1 @@
+Because of a missing permission check, the branch used to propose a pull request to a repository can always be deleted by the user performing the merge. It was fixed so that such a deletion is only allowed if the user performing the merge has write permission to the repository from which the pull request was made.
diff --git a/release-notes/5719.md b/release-notes/5719.md
new file mode 100644
index 0000000000..19a74825e4
--- /dev/null
+++ b/release-notes/5719.md
@@ -0,0 +1 @@
+Forgejo generates a token which is used to authenticate web endpoints that are only meant to be used internally, for instance when the SSH daemon is used to push a commit with Git. The verification of this token was not done in constant time and was susceptible to [timing attacks](https://en.wikipedia.org/wiki/Timing_attack). A pre-condition for such an attack is the precise measurements of the time for each operation. Since it requires observing the timing of network operations, the issue is mitigated when a Forgejo instance is accessed over the internet because the ISP introduce unpredictable random delays.
diff --git a/release-notes/5751.md b/release-notes/5751.md
new file mode 100644
index 0000000000..b9666b7282
--- /dev/null
+++ b/release-notes/5751.md
@@ -0,0 +1,2 @@
+feat: mermaid: [Add the Kanban board diagram type](https://github.com/mermaid-js/mermaid/pull/5999).
+feat: mermaid: [Class diagram includes a new "classBox" shape, classDef statement, support for styling the default class and lollipop interfaces](https://github.com/mermaid-js/mermaid/pull/5880).
diff --git a/release-notes/5778.md b/release-notes/5778.md
new file mode 100644
index 0000000000..a3c6305c57
--- /dev/null
+++ b/release-notes/5778.md
@@ -0,0 +1,3 @@
+fix: In a Forgejo Actions workflow, the `unlabeled` event type for pull requests was incorrectly mapped to the labeled event type.
+fix: When a Forgejo Actions issue or pull request workflow is triggered by an `labeled` or `unlabeled` event type, it misses information about the label added or removed. It is now available in the `label` data member of the event payload.
+fix: The pull request workflow must always update the head SHA commit status. Not just when the PR is synchronized, opened or closed. Otherwise it makes it impossible to define a job to be a required check (for instance a job that is triggered when labels are modified and verifies that a given combination is present).
diff --git a/release-notes/5789.md b/release-notes/5789.md
new file mode 100644
index 0000000000..0c0763a46e
--- /dev/null
+++ b/release-notes/5789.md
@@ -0,0 +1,6 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/362ad0ba39bdbc87202e349678e21fc2a75ff7cb) Update force-pushed tags too when syncing mirrors
+chore: [commit](https://codeberg.org/forgejo/forgejo/commit/b308bcca7c950b7f0d127ee4282019c2a9923299) Improved diff view performance
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/4c5bdddf7751a35985c08ba6506f1f30103749d6) Fix `missing signature key` error when pulling Docker images with `SERVE_DIRECT` enabled
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/2c5fdb108ff9e23e8f907fb6afe59177c6bb202e) Fix the missing menu in organization project view page
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/1e595979625e54d375a0eaa440b84ef5e17af160) Add new [lfs_client].BATCH_SIZE and [server].LFS_MAX_BATCH_SIZE config settings.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/2358c0d899faec8311e46dcb0550041496bcd532) Properly clean temporary index files
diff --git a/release-notes/5974.md b/release-notes/5974.md
new file mode 100644
index 0000000000..2f78d4733f
--- /dev/null
+++ b/release-notes/5974.md
@@ -0,0 +1,8 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/1ce33aa38d1d258d14523ff2c7c2dbf339f22b74) it was possible to use a token sent via email for secondary email validation to reset the password instead. In other words, a token sent for a given action (registration, password reset or secondary email validation) could be used to perform a different action. It is no longer possible to use a token for an action that is different from its original purpose.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/061abe60045212acf8c3f5c49b5cc758b4cbcde9) a fork of a public repository would show in the list of forks, even if its owner was not a public user or organization. Such a fork is now hidden from the list of forks of the public repository.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/3e3ef76808100cb1c853378733d0f6a910324ac6) the members of an organization team with read access to a repository (e.g. to read issues) but no read access to the code could read the RSS or atom feeds which include the commit activity. Reading the RSS or atom feeds is now denied unless the team has read permissions on the code.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/9508aa7713632ed40124a933d91d5766cf2369c2) the tokens used when [replying by email to issues or pull requests](https://forgejo.org/docs/v9.0/user/incoming/) were weaker than the [rfc2104 recommendations](https://datatracker.ietf.org/doc/html/rfc2104#section-5). The tokens are now truncated to 128 bits instead of 80 bits. It is no longer possible to reply to emails sent before the upgrade because the weaker tokens are invalid.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/786dfc7fb81ee76d4292ca5fcb33e6ea7bdccc29) a registered user could modify the update frequency of any push mirror (e.g. every 4h instead of every 8h). They are now only able to do that if they have administrative permissions on the repository.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/e6bbecb02d47730d3cc630d419fe27ef2fb5cb39) it was possible to use basic authorization (i.e. user:password) for requests to the API even when security keys were enrolled for a user. It is no longer possible, an application token must be used instead.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/7067cc7da4f144cc8a2fd2ae6e5307e0465ace7f) some markup sanitation rules were not as strong as they could be (e.g. allowing `emoji somethingelse` as well as `emoji`). The rules are now stricter and do not allow for such cases.
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/b70196653f9d7d3b9d4e72d114e5cc6f472988c4) when Forgejo is configured to enable instance wide search (e.g. with [bleve](https://blevesearch.com/)), results found in the repositories of private or limited users were displayed to anonymous visitors. The results found in private or limited organizations were not displayed. The search results found in the repositories of private or limited user are no longer displayed to anonymous visitors.
diff --git a/release-notes/5988.md b/release-notes/5988.md
new file mode 100644
index 0000000000..52add6347e
--- /dev/null
+++ b/release-notes/5988.md
@@ -0,0 +1 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/fc26becba4b08877a726f2e7e453992310245fe5) when a tag was removed and a release existed for that tag, it would be broken. The release is no longer broken the tag can be added again.
diff --git a/release-notes/5997.md b/release-notes/5997.md
new file mode 100644
index 0000000000..9597da9e79
--- /dev/null
+++ b/release-notes/5997.md
@@ -0,0 +1,8 @@
+fix(security): [commit](https://codeberg.org/forgejo/forgejo/commit/45435a8789f8ff69603799a9031246d2d621d139) Fix and refactor markdown rendering
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/a8f2002a9b061ec1092df67c6f05e30aa7d2e2d2) Remove transaction for archive download
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/96ee0f56475204b2bbdc7f2aeb35b1c32eac469c) Fix oauth2 error handle not return immediately
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/c2e8790df37a14b4d2f72c7377db75309e0ebf1d) Trim title before insert/update to database to match the size requirements of database
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/03ab73d92eabaf774278effe3332623b1dc3580a) Fix nil panic if repo doesn't exist
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/56971f9ed90a01fd74a634b7496593e6f62ac260) Disable Oauth check if oauth disabled
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/7f51210672031aee7a790455d51a17ce11a70559) Harden runner updateTask and updateLog api
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/dd3c4d7096cff91854bcc6641f55d9d093e5c86e) Add a doctor check to disable the "Actions" unit for mirrors
diff --git a/release-notes/6062.md b/release-notes/6062.md
new file mode 100644
index 0000000000..7ae7f87548
--- /dev/null
+++ b/release-notes/6062.md
@@ -0,0 +1,4 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/32a91add34519ef7768ec907888ed837ad0dde2f) Fix GetInactiveUsers
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/64824290912b6300ede2b2f95ff77d55dde9859b) Fix submodule parsing
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/ddabba5f89c4b196daeeb2af17de9ec2cec14b63) allow the actions user to login via the jwt token
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/262c48409b1224e3f6dc63c8d1e04fef0e0cf2c0) Support HTTP POST requests to `/userinfo`, aligning to OpenID Core specification
diff --git a/release-notes/6110.md b/release-notes/6110.md
new file mode 100644
index 0000000000..b87ec44882
--- /dev/null
+++ b/release-notes/6110.md
@@ -0,0 +1 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/3973f1022d57a3134e8f775e1c1cc6d398681bb4) Add github compatible tarball download API endpoints
diff --git a/release-notes/6200.md b/release-notes/6200.md
new file mode 100644
index 0000000000..f7cf8de471
--- /dev/null
+++ b/release-notes/6200.md
@@ -0,0 +1 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/0786ddc5de37a01d1c3e3bf99b794665341b3c12) Add Swift login endpoint
diff --git a/release-notes/6271.md b/release-notes/6271.md
new file mode 100644
index 0000000000..4a4821682f
--- /dev/null
+++ b/release-notes/6271.md
@@ -0,0 +1,4 @@
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/96a7f0a3f065c5db8fdf352c93c8367e24d259de) Fix missing outputs for jobs with matrix
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/2b5c69c451a684b20119e2521dc23734c7869241) Detect whether action view branch was deleted
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/b0d6a7f07bff836190a8e87fe5645d5557893e32) Implement update branch API
+fix: [commit](https://codeberg.org/forgejo/forgejo/commit/bf934c96c92d643678ac7a18697b6563bc9d20a5) Add standard-compliant route to serve outdated R packages
diff --git a/release-notes/6351.md b/release-notes/6351.md
new file mode 100644
index 0000000000..b87427724b
--- /dev/null
+++ b/release-notes/6351.md
@@ -0,0 +1 @@
+feat: [Alt Linux Apt-Rpm](https://en.altlinux.org/RPM) repository [support for Forgejo packages](https://forgejo.org/docs/next/user/packages/alt/).
\ No newline at end of file
diff --git a/release-notes/6445.md b/release-notes/6445.md
new file mode 100644
index 0000000000..d3755701b2
--- /dev/null
+++ b/release-notes/6445.md
@@ -0,0 +1 @@
+feat: webhook: sourcehut: submit SSH URL for private repository or when pre-filled
diff --git a/release-notes/6471.md b/release-notes/6471.md
new file mode 100644
index 0000000000..4e70286eee
--- /dev/null
+++ b/release-notes/6471.md
@@ -0,0 +1 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/76a85d26c8576fc410dc6494f2907ffc2b353c39) Use `Project-URL` metadata field to get a PyPI package's homepage URL
diff --git a/release-notes/6523.md b/release-notes/6523.md
new file mode 100644
index 0000000000..96a1fe0cf3
--- /dev/null
+++ b/release-notes/6523.md
@@ -0,0 +1 @@
+Reduce noise in the timeline of issues and pull requests. If certain timeline events are performed within a certain timeframe of each other with no other events in between, they will be combined into a single timeline event, and any contradictory actions will be canceled and not displayed. The older the events, the wider the timeframe will become.
diff --git a/release-notes/6639.md b/release-notes/6639.md
new file mode 100644
index 0000000000..1bc01c12a3
--- /dev/null
+++ b/release-notes/6639.md
@@ -0,0 +1 @@
+Teach the doctor to remove orphaned two_factor with `forgejo doctor check --run check-db-consistency --fix`. Such rows may contain invalid data and [block the migration to v10](https://codeberg.org/forgejo/forgejo/issues/6637) with a message such as `failed: AesDecrypt invalid decrypted base64 string: illegal base64 data at input byte 0`.
diff --git a/release-notes/6763.md b/release-notes/6763.md
new file mode 100644
index 0000000000..cb5ec172c7
--- /dev/null
+++ b/release-notes/6763.md
@@ -0,0 +1 @@
+feat: [commit](https://codeberg.org/forgejo/forgejo/commit/689fb82a7043fdb2fee02195701b0bc728e99709) API endpoint to rename an organization
diff --git a/release-notes/7.0.5/fix/4059.md b/release-notes/7.0.5/fix/4059.md
deleted file mode 100644
index 359e517506..0000000000
--- a/release-notes/7.0.5/fix/4059.md
+++ /dev/null
@@ -1 +0,0 @@
-Authentication Source Administration page wrongfully handled the "Custom URLs Instead of Default URLs" checkbox (missing checkbox, irrelevant fields) [#4059](https://codeberg.org/forgejo/forgejo/pulls/4059) [#4194](https://codeberg.org/forgejo/forgejo/pulls/4194)
\ No newline at end of file
diff --git a/release-notes/7251.md b/release-notes/7251.md
new file mode 100644
index 0000000000..9c35603981
--- /dev/null
+++ b/release-notes/7251.md
@@ -0,0 +1 @@
+When migrating from a Forgejo version lower than v10, the TOTP secrets found to be corrupted are now transparently removed from the database instead of failing the migration. TOTP is no longer required to login with the associated users. They should be informed because they will need to visit their security settings and configure TOTP again. No other action is required.
diff --git a/release-notes/8.0.0/3616.md b/release-notes/8.0.0/3616.md
deleted file mode 100644
index fdeb470cf0..0000000000
--- a/release-notes/8.0.0/3616.md
+++ /dev/null
@@ -1,10 +0,0 @@
-There are a couple of new configs to define the name of the instance.
-The more important is `APP_SLOGAN`. It permits to configure a slogan for the site and it is optional.
-The other is `APP_DISPLAY_NAME_FORMAT` and permits to customize the aspect of the full display name for the instance used in some parts of the UI as:
-
-- Title page.
-- Homepage head title.
-- Open Graph site and title meta tags.
-
-Its default value is `APP_NAME: APP_SLOGAN`.
-The config `APP_DISPLAY_NAME_FORMAT` is used only if `APP_SLOGAN` is set otherwise the full display name shows only `APP_NAME` value.
diff --git a/release-notes/8.0.0/4139.md b/release-notes/8.0.0/4139.md
deleted file mode 100644
index 116a36d881..0000000000
--- a/release-notes/8.0.0/4139.md
+++ /dev/null
@@ -1,5 +0,0 @@
-Reorder repo tabs for better UX:
-- Actions is now the last tab
-- Packages are located after Releases
-- This puts Projects after Pull requests
-(tab positions may depend on which units are enabled in the repo)
diff --git a/release-notes/8.0.0/feat/3729.md b/release-notes/8.0.0/feat/3729.md
deleted file mode 100644
index bc76e24bd5..0000000000
--- a/release-notes/8.0.0/feat/3729.md
+++ /dev/null
@@ -1 +0,0 @@
-- [PR](https://github.com/go-gitea/gitea/pull/30874): add actions-artifacts to the [storage migrate CLI](https://forgejo.org/docs/v8.0/admin/command-line/#migrate).
diff --git a/release-notes/8.0.0/feat/3847.md b/release-notes/8.0.0/feat/3847.md
deleted file mode 100644
index 3ff9e872d7..0000000000
--- a/release-notes/8.0.0/feat/3847.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Basic wiki content search using git-grep
- - The search results include the first ten matched files
- - Only the first three matches per file are displayed
diff --git a/release-notes/8.0.0/feat/3917.md b/release-notes/8.0.0/feat/3917.md
deleted file mode 100644
index 535fbab224..0000000000
--- a/release-notes/8.0.0/feat/3917.md
+++ /dev/null
@@ -1,2 +0,0 @@
-- Support [setting the default attribute of the issue template dropdown field](https://codeberg.org/forgejo/forgejo/commit/df15abd07264138fd07e003d0cf056f7da514b8f)
-- [Return access_denied error when an OAuth2 request is denied](https://codeberg.org/forgejo/forgejo/commit/886a675f62233dcde3ac0d7b2181484f29344f26)
diff --git a/release-notes/8.0.0/feat/3922.md b/release-notes/8.0.0/feat/3922.md
deleted file mode 100644
index bd79f2adb3..0000000000
--- a/release-notes/8.0.0/feat/3922.md
+++ /dev/null
@@ -1,3 +0,0 @@
-- [`1e983e7`](https://github.com/alecthomas/chroma/commit/1e983e7) lexers/cue: support CUE attributes ([#961](https://github.com/alecthomas/chroma/issues/961))
-- [`9347b55`](https://github.com/alecthomas/chroma/commit/9347b55) Add Gleam syntax highlighting ([#959](https://github.com/alecthomas/chroma/issues/959))
-- [`2580aaa`](https://github.com/alecthomas/chroma/commit/2580aaa) Add Bazel bzlmod support into Python lexer ([#947](https://github.com/alecthomas/chroma/issues/947))
diff --git a/release-notes/8.0.0/feat/3989.md b/release-notes/8.0.0/feat/3989.md
deleted file mode 100644
index 228c4e9bce..0000000000
--- a/release-notes/8.0.0/feat/3989.md
+++ /dev/null
@@ -1,4 +0,0 @@
-- API endpoints that return a repository now [also include the topics](https://codeberg.org/forgejo/forgejo/commit/ee2247d77c0b13b0b45df704d7589b541db03899)
-- Display an error when an issue comment is [edited simultaneously by two users](https://codeberg.org/forgejo/forgejo/commit/ca0921a95aa9a37d8820538458c15fd0a3b0c97c) instead of silently overriding one of them
-- Add [support for a credentials chain for minio](https://codeberg.org/forgejo/forgejo/commit/73706ae26d138684ef9da9e1164846a040fd4a7d)
-- [Rename project board into column](https://codeberg.org/forgejo/forgejo/commit/a7591f9738dbefb2dcddeb2d45175abee3d03c1f) because it was confusing to users
diff --git a/release-notes/8.0.0/feat/4027.md b/release-notes/8.0.0/feat/4027.md
deleted file mode 100644
index bdae695679..0000000000
--- a/release-notes/8.0.0/feat/4027.md
+++ /dev/null
@@ -1 +0,0 @@
-- Gitea/Forgejo webhook payload include additional fields (`html_url`, `additions`, `deletions`, `review_comments`...) for better compatbility with [OpenProject](https://www.openproject.org/), ported from [gitea#28435](https://github.com/go-gitea/gitea/pull/28435).
diff --git a/release-notes/8.0.0/feat/4072.md b/release-notes/8.0.0/feat/4072.md
deleted file mode 100644
index 1f14830575..0000000000
--- a/release-notes/8.0.0/feat/4072.md
+++ /dev/null
@@ -1,5 +0,0 @@
-- Added Enter key handling to the new Markdown editor ([#4072](https://codeberg.org/forgejo/forgejo/pulls/4072)):
- - Pressing Enter while in a list, quote or code block will copy the prefix to the new line.
- - Ordered list index will be increased for the new line, and task list "checkbox" will be unchecked.
-- Added indent/unindent function for a line or selection.
- - Currently available as toolbar buttons ([#4263](https://codeberg.org/forgejo/forgejo/pulls/4263))
diff --git a/release-notes/8.0.0/feat/4083.md b/release-notes/8.0.0/feat/4083.md
deleted file mode 100644
index ab7501dd43..0000000000
--- a/release-notes/8.0.0/feat/4083.md
+++ /dev/null
@@ -1,3 +0,0 @@
-- add [Reviewed-on and Reviewed-by variables](https://codeberg.org/forgejo/forgejo/commit/4ddd9af50fbfcfb2ebf629697a803b3bce56c4af) to the merge template
-- [add the `[ui.csv].MAX_ROWS` setting](https://codeberg.org/forgejo/forgejo/commit/433b6c6910f8699dc41787ef8f5148b122b4677e) to avoid displaying a large number of lines (defaults to 2500)
-- [add a setting to override or add headers of all outgoing emails](https://codeberg.org/forgejo/forgejo/commit/1d4bff4f65d5e4a3969871ef91d3612daf272b45), for instance `Reply-To` or `In-Reply-To`
diff --git a/release-notes/8.0.0/feat/4145.md b/release-notes/8.0.0/feat/4145.md
deleted file mode 100644
index 872e5d4683..0000000000
--- a/release-notes/8.0.0/feat/4145.md
+++ /dev/null
@@ -1,3 +0,0 @@
-- [commit](https://codeberg.org/forgejo/forgejo/commit/b60e3ac7b4aeeb9b8760f43eea9576c0e23309e9) allow downloading draft releases assets.
-- [commit](https://codeberg.org/forgejo/forgejo/commit/1fca15529ac8fefb60d86b0c1f4bec8dae9a8566) API endpoints for managing tag protection
-- [commit](https://codeberg.org/forgejo/forgejo/commit/4334c705b5f9388b16af23c7e75a69d027d07d5e) extract and display readme and comments for Composer packages
diff --git a/release-notes/8.0.0/feat/4160.md b/release-notes/8.0.0/feat/4160.md
deleted file mode 100644
index c8b7bdf47e..0000000000
--- a/release-notes/8.0.0/feat/4160.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Added support for fuzzy searching issues and pulls
-- support for `/issues` and `/pulls` were ported from [`gitea#be5be0ac81`](https://github.com/go-gitea/gitea/commit/be5be0ac81ce50ad5adb079af6ca4e8c396aaece)
-- support for `/user/repo/issues` and `/user/repo/pulls` were added
diff --git a/release-notes/8.0.0/fix/3363.md b/release-notes/8.0.0/fix/3363.md
deleted file mode 100644
index 65b516cabc..0000000000
--- a/release-notes/8.0.0/fix/3363.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Reverted the rootless container image path in `GITEA_APP_INI` from
-`/etc/gitea/app.ini` to its default value of
-`/var/lib/gitea/custom/conf/app.ini`. This allows container users to not have
-to mount two separate volumes (one for the configuration data and one for the
-configuration `.ini` file). A warning is issued for users with the legacy
-configuration on how to update to the new path.
diff --git a/release-notes/8.0.0/fix/3729.md b/release-notes/8.0.0/fix/3729.md
deleted file mode 100644
index 9123c4a08f..0000000000
--- a/release-notes/8.0.0/fix/3729.md
+++ /dev/null
@@ -1 +0,0 @@
-- [PR](https://github.com/go-gitea/gitea/pull/30715): pull request search shows closed pull requests in the open tab
diff --git a/release-notes/8.0.0/fix/3922.md b/release-notes/8.0.0/fix/3922.md
deleted file mode 100644
index e507cea4d3..0000000000
--- a/release-notes/8.0.0/fix/3922.md
+++ /dev/null
@@ -1,2 +0,0 @@
-- [`736c0ea`](https://github.com/alecthomas/chroma/commit/736c0ea) Typescript: Several fixes ([#952](https://github.com/alecthomas/chroma/issues/952))
-- [`e5c25d0`](https://github.com/alecthomas/chroma/commit/e5c25d0) Org: Keep all newlines ([#951](https://github.com/alecthomas/chroma/issues/951))
diff --git a/release-notes/8.0.0/fix/4124.md b/release-notes/8.0.0/fix/4124.md
deleted file mode 100644
index 47c65e2ce9..0000000000
--- a/release-notes/8.0.0/fix/4124.md
+++ /dev/null
@@ -1 +0,0 @@
-Fixed bug in `GetIssueStats`
diff --git a/release-notes/8.0.0/fix/4145.md b/release-notes/8.0.0/fix/4145.md
deleted file mode 100644
index c993fcc517..0000000000
--- a/release-notes/8.0.0/fix/4145.md
+++ /dev/null
@@ -1,2 +0,0 @@
-- [commit](https://codeberg.org/forgejo/forgejo/commit/364922c6e4f28264add9e2501a352c25ad6a0993) when a repository is adopted, its object format is not set in the database
-- [commit](https://codeberg.org/forgejo/forgejo/commit/e7f332a55d6a48a3f3b4f2bfa43d18455ac00acc) during a migration from bitbucket, LFS downloads fail
diff --git a/release-notes/8.0.0/fix/4149.md b/release-notes/8.0.0/fix/4149.md
deleted file mode 100644
index 0947df11a0..0000000000
--- a/release-notes/8.0.0/fix/4149.md
+++ /dev/null
@@ -1 +0,0 @@
-git push to an adopted repository fails
diff --git a/release-notes/8.0.0/fix/4258.md b/release-notes/8.0.0/fix/4258.md
deleted file mode 100644
index c8f7646d91..0000000000
--- a/release-notes/8.0.0/fix/4258.md
+++ /dev/null
@@ -1 +0,0 @@
-Fix wrong placeholder text in the form for adding repository collaborator
diff --git a/release-notes/8.0.0/perf/3989.md b/release-notes/8.0.0/perf/3989.md
deleted file mode 100644
index d3d77695e2..0000000000
--- a/release-notes/8.0.0/perf/3989.md
+++ /dev/null
@@ -1 +0,0 @@
-- improve performances when [retrieving pull requests via the API](https://codeberg.org/forgejo/forgejo/commit/47a2102694c47bc30a2a7c673c328471839ef206)
diff --git a/release-notes/8.0.0/perf/4145.md b/release-notes/8.0.0/perf/4145.md
deleted file mode 100644
index bb59fd1dc6..0000000000
--- a/release-notes/8.0.0/perf/4145.md
+++ /dev/null
@@ -1 +0,0 @@
-- [commit](https://codeberg.org/forgejo/forgejo/commit/358cd67c4f316f2d4f1d3be6dcb891dc04a2ff07) reduce memory usage for chunked artifact uploads to S3
diff --git a/renovate.json b/renovate.json
index 4f032edd3f..7ea5e9d6b9 100644
--- a/renovate.json
+++ b/renovate.json
@@ -1,45 +1,33 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
- "extends": [
- "config:best-practices",
- ":approveMajorUpdates",
- ":maintainLockFilesWeekly",
- "group:postcss",
- "group:linters",
- "schedule:daily",
- "schedule:automergeDaily",
- "local>forgejo-contrib/forgejo-renovate//go.json"
- ],
+ "extends": ["local>forgejo/renovate-config"],
"ignorePresets": [
":semanticPrefixFixDepsChoreOthers",
"docker:pinDigests",
"helpers:pinGitHubActionDigests"
],
- "semanticCommits": "disabled",
- "automergeStrategy": "merge-commit",
+ "baseBranches": [
+ "$default",
+ "/^v7\\.\\d+/forgejo$/",
+ "/^v10\\.\\d+/forgejo$/",
+ "/^v11\\.\\d+/forgejo$/"
+ ],
"postUpdateOptions": ["gomodTidy", "gomodUpdateImportPaths", "npmDedupe"],
"prConcurrentLimit": 10,
- "internalChecksFilter": "strict",
"osvVulnerabilityAlerts": true,
- "labels": ["dependency-upgrade"],
+ "automergeStrategy": "squash",
+ "labels": ["dependency-upgrade","test/not-needed"],
"packageRules": [
{
- "description": "Require approval for go and python minor version",
- "matchDepNames": [
- "go",
- "python",
- "golang",
- "docker.io/golang",
- "docker.io/library/golang",
- "mcr.microsoft.com/devcontainers/go"
- ],
+ "description": "Require approval for python minor version",
+ "matchPackageNames": ["containerbase/python-prebuild", "python"],
"matchUpdateTypes": ["minor"],
"dependencyDashboardApproval": true
},
{
"description": "Require dashboard approval for some deps",
- "matchDepNames": [
- "bitnami/minio",
+ "matchPackageNames": [
+ "docker.io/bitnami/minio",
"github.com/go-ap/activitypub",
"github.com/nektos/act",
"gitea.com/gitea/act"
@@ -48,7 +36,8 @@
},
{
"description": "Schedule some deps less frequently",
- "matchDepNames": [
+ "matchPackageNames": [
+ "code.forgejo.org/f3/gof3/v3",
"github.com/google/pprof",
"github.com/golangci/misspell/cmd/misspell"
],
@@ -56,54 +45,43 @@
},
{
"description": "elasticsearch CI images are published about once a month and do not use semantic versioning or short tags",
- "matchDepNames": [
- "elasticsearch"
- ],
+ "matchPackageNames": ["elasticsearch"],
"extends": ["schedule:quarterly"]
},
{
"description": "devcontainer is an optional tool used by some Forgejo contributors when working on the codebase",
- "matchPackagePrefixes": [
- "ghcr.io/devcontainers/features/",
- "ghcr.io/devcontainers-contrib/features/"
- ],
"groupName": "devcontainer packages",
"extends": ["schedule:quarterly"],
- "automerge": true
+ "automerge": true,
+ "matchPackageNames": [
+ "ghcr.io/devcontainers/features/**",
+ "ghcr.io/devcontainers-contrib/features/**"
+ ]
},
{
- "description": "Group golang packages",
- "matchDepNames": [
- "go",
- "golang",
- "docker.io/golang",
- "docker.io/library/golang"
- ],
- "groupName": "golang packages"
- },
- {
- "description": "Group nodejs packages",
- "matchDepNames": ["node", "docker.io/node", "docker.io/library/node"],
- "groupName": "nodejs packages",
- "versionCompatibility": "^(?[^-]+)(?-.*)?$",
- "versioning": "node"
- },
- {
- "description": "Automerge renovate updates",
- "matchDatasources": ["docker"],
- "matchPackageNames": ["ghcr.io/visualon/renovate"],
+ "description": "x/tools/* are used in the CI only and upgraded together",
"matchUpdateTypes": ["minor", "patch", "digest"],
"automerge": true,
- "groupName": "renovate"
+ "groupName": "x/tools",
+ "matchPackageNames": ["golang.org/x/tools{/,}**"]
+ },
+ {
+ "description": "Group postcss minor and patch updates",
+ "extends": ["packages:postcss"],
+ "matchUpdateTypes": ["minor", "patch"],
+ "groupName": "postcss"
+ },
+ {
+ "description": "Group Forgejo go-chi packages",
+ "matchUpdateTypes": ["minor", "patch", "digest"],
+ "matchPackageNames": ["code.forgejo.org/go-chi/**"],
+ "groupName": "forgejo go-chi packages"
},
{
"description": "Split minor and patch updates",
- "matchDepNames": [
- "docker.io/golang",
- "docker.io/library/golang",
+ "matchPackageNames": [
+ "containerbase/python-prebuild",
"github.com/urfave/cli/v2",
- "go",
- "golang",
"python",
"swagger-ui-dist",
"vue"
@@ -112,90 +90,70 @@
},
{
"description": "Automerge patch updates",
- "matchDepNames": ["vue", "github.com/urfave/cli/v2", "swagger-ui-dist"],
+ "matchPackageNames": [
+ "vue",
+ "github.com/urfave/cli/v2",
+ "swagger-ui-dist"
+ ],
"matchUpdateTypes": ["patch"],
"automerge": true
},
{
- "description": "Update renovate with higher prio to come through rate limit",
+ "description": "Add reviewer and additional labels to renovate PRs",
"matchDatasources": ["docker"],
- "matchDepNames": ["ghcr.io/visualon/renovate"],
- "extends": ["schedule:weekly"],
- "prPriority": 10
+ "matchPackageNames": ["data.forgejo.org/renovate/renovate"],
+ "reviewers": ["viceice"],
+ "addLabels": ["forgejo/ci"]
},
{
- "description": "Update go patch with higher prio to come through rate limit",
- "matchDepNames": [
- "go",
- "golang",
- "docker.io/golang",
- "docker.io/library/golang"
+ "description": "Disable renovate self-updates for release branches",
+ "matchBaseBranches": ["/^v\\d+\\.\\d+\\/forgejo$/"],
+ "matchPackageNames": [
+ "code.forgejo.org/forgejo-contrib/renovate",
+ "data.forgejo.org/renovate/renovate",
+ "ghcr.io/visualon/renovate"
],
- "matchUpdateTypes": ["patch"],
- "prPriority": 10,
- "schedule": ["at any time"]
- },
- {
- "description": "Disable actions/cascading-pr for now ",
- "matchDepNames": ["actions/cascading-pr"],
- "matchManagers": ["github-actions"],
"enabled": false
},
{
"description": "Automerge some packages when CI succeeds",
- "extends": ["packages:linters", "packages:test"],
- "matchDepNames": [
+ "extends": ["packages:linters", "packages:test", "schedule:monthly"],
+ "matchPackageNames": [
+ "@axe-core/playwright",
+ "@eslint-community/**",
+ "@playwright/**",
+ "@stoplight/spectral-cli",
+ "@stylistic/**",
+ "@vitejs/plugin-vue",
+ "@vue/test-utils",
+ "djlint",
"github.com/editorconfig-checker/editorconfig-checker/v2/cmd/editorconfig-checker",
"github.com/golangci/golangci-lint/cmd/golangci-lint",
"github.com/go-testfixtures/testfixtures",
"github.com/PuerkitoBio/goquery",
- "golang.org/x/tools/cmd/deadcode",
- "golang.org/x/tools/gopls",
"happy-dom",
"markdownlint-cli",
+ "mcr.microsoft.com/devcontainers/**",
"mvdan.cc/gofumpt",
"updates",
"vite-string-plugin",
- "@vue/test-utils"
- ],
- "matchPackagePrefixes": [
- "@eslint-community/",
- "@playwright/",
- "@stoplight/spectral-cli",
- "@stylistic/",
- "mcr.microsoft.com/devcontainers/"
+ "yamllint"
],
"automerge": true
},
{
"description": "Hold back on some package updates for a few days",
- "matchDepNames": ["monaco-editor"],
+ "matchPackageNames": ["monaco-editor"],
"minimumReleaseAge": "30 days"
},
{
- "description": "disallow `eslint-plugin-no-use-extend-native` v0.6.0+, requires eslint v9",
- "matchDepNames": ["eslint-plugin-no-use-extend-native"],
- "allowedVersions": "<0.6.0"
+ "description": "Require approval for stable branches (must be last rule to override all others)",
+ "matchBaseBranches": ["/^v\\d+\\.\\d+\\/forgejo$/"],
+ "dependencyDashboardApproval": true,
+ "schedule": ["at any time"]
}
],
"customManagers": [
- {
- "description": "Update go-version in forgejo workflows",
- "customType": "regex",
- "fileMatch": ["^.forgejo/workflows/.+\\.yml$"],
- "matchStrings": ["\\s+go-version: ['\"]?(?.+?)['\"]?\\s"],
- "depNameTemplate": "go",
- "datasourceTemplate": "golang-version",
- "versioningTemplate": "go-mod-directive"
- },
- {
- "description": "Update node-version in forgejo workflows",
- "customType": "regex",
- "fileMatch": ["^.forgejo/workflows/.+\\.yml$"],
- "matchStrings": ["\\s+node-version: ['\"]?(?.+?)['\"]?\\s"],
- "depNameTemplate": "node",
- "datasourceTemplate": "node-version"
- },
{
"description": "Update deps inside Makefile",
"customType": "regex",
diff --git a/routers/api/actions/actions.go b/routers/api/actions/actions.go
index a418b3a1c4..70158c4e18 100644
--- a/routers/api/actions/actions.go
+++ b/routers/api/actions/actions.go
@@ -6,9 +6,9 @@ package actions
import (
"net/http"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/actions/ping"
- "code.gitea.io/gitea/routers/api/actions/runner"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/actions/ping"
+ "forgejo.org/routers/api/actions/runner"
)
func Routes(prefix string) *web.Route {
diff --git a/routers/api/actions/artifacts.go b/routers/api/actions/artifacts.go
index 6aa0ecaaec..85a1f5f5be 100644
--- a/routers/api/actions/artifacts.go
+++ b/routers/api/actions/artifacts.go
@@ -69,17 +69,18 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- web_types "code.gitea.io/gitea/modules/web/types"
- actions_service "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ web_types "forgejo.org/modules/web/types"
+ actions_service "forgejo.org/services/actions"
+ "forgejo.org/services/context"
)
const artifactRouteBase = "/_apis/pipelines/workflows/{run_id}/artifacts"
@@ -240,6 +241,18 @@ func (ar artifactRoutes) uploadArtifact(ctx *ArtifactContext) {
return
}
+ // check the owner's quota
+ ok, err := quota_model.EvaluateForUser(ctx, ctx.ActionTask.OwnerID, quota_model.LimitSubjectSizeAssetsArtifacts)
+ if err != nil {
+ log.Error("quota_model.EvaluateForUser: %v", err)
+ ctx.Error(http.StatusInternalServerError, "Error checking quota")
+ return
+ }
+ if !ok {
+ ctx.Error(http.StatusRequestEntityTooLarge, "Quota exceeded")
+ return
+ }
+
// get upload file size
fileRealTotalSize, contentLength := getUploadFileSize(ctx)
@@ -415,8 +428,8 @@ func (ar artifactRoutes) getDownloadArtifactURL(ctx *ArtifactContext) {
}
if itemPath != artifacts[0].ArtifactName {
- log.Error("Error dismatch artifact name, itemPath: %v, artifact: %v", itemPath, artifacts[0].ArtifactName)
- ctx.Error(http.StatusBadRequest, "Error dismatch artifact name")
+ log.Error("Error mismatch artifact name, itemPath: %v, artifact: %v", itemPath, artifacts[0].ArtifactName)
+ ctx.Error(http.StatusBadRequest, "Error mismatch artifact name")
return
}
@@ -424,7 +437,7 @@ func (ar artifactRoutes) getDownloadArtifactURL(ctx *ArtifactContext) {
for _, artifact := range artifacts {
var downloadURL string
if setting.Actions.ArtifactStorage.MinioConfig.ServeDirect {
- u, err := ar.fs.URL(artifact.StoragePath, artifact.ArtifactName)
+ u, err := ar.fs.URL(artifact.StoragePath, artifact.ArtifactName, nil)
if err != nil && !errors.Is(err, storage.ErrURLNotSupported) {
log.Error("Error getting serve direct url: %v", err)
}
diff --git a/routers/api/actions/artifacts_chunks.go b/routers/api/actions/artifacts_chunks.go
index b0c96585cb..a15fa4fd1e 100644
--- a/routers/api/actions/artifacts_chunks.go
+++ b/routers/api/actions/artifacts_chunks.go
@@ -17,10 +17,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/storage"
+ "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/storage"
)
func saveUploadChunkBase(st storage.ObjectStorage, ctx *ArtifactContext,
@@ -123,6 +123,54 @@ func listChunksByRunID(st storage.ObjectStorage, runID int64) (map[int64][]*chun
return chunksMap, nil
}
+func listChunksByRunIDV4(st storage.ObjectStorage, runID, artifactID int64, blist *BlockList) ([]*chunkFileItem, error) {
+ storageDir := fmt.Sprintf("tmpv4%d", runID)
+ var chunks []*chunkFileItem
+ chunkMap := map[string]*chunkFileItem{}
+ dummy := &chunkFileItem{}
+ for _, name := range blist.Latest {
+ chunkMap[name] = dummy
+ }
+ if err := st.IterateObjects(storageDir, func(fpath string, obj storage.Object) error {
+ baseName := filepath.Base(fpath)
+ if !strings.HasPrefix(baseName, "block-") {
+ return nil
+ }
+ // when read chunks from storage, it only contains storage dir and basename,
+ // no matter the subdirectory setting in storage config
+ item := chunkFileItem{Path: storageDir + "/" + baseName, ArtifactID: artifactID}
+ var size int64
+ var b64chunkName string
+ if _, err := fmt.Sscanf(baseName, "block-%d-%d-%s", &item.RunID, &size, &b64chunkName); err != nil {
+ return fmt.Errorf("parse content range error: %v", err)
+ }
+ rchunkName, err := base64.URLEncoding.DecodeString(b64chunkName)
+ if err != nil {
+ return fmt.Errorf("failed to parse chunkName: %v", err)
+ }
+ chunkName := string(rchunkName)
+ item.End = item.Start + size - 1
+ if _, ok := chunkMap[chunkName]; ok {
+ chunkMap[chunkName] = &item
+ }
+ return nil
+ }); err != nil {
+ return nil, err
+ }
+ for i, name := range blist.Latest {
+ chunk, ok := chunkMap[name]
+ if !ok || chunk.Path == "" {
+ return nil, fmt.Errorf("missing Chunk (%d/%d): %s", i, len(blist.Latest), name)
+ }
+ chunks = append(chunks, chunk)
+ if i > 0 {
+ chunk.Start = chunkMap[blist.Latest[i-1]].End + 1
+ chunk.End += chunk.Start
+ }
+ }
+ return chunks, nil
+}
+
func mergeChunksForRun(ctx *ArtifactContext, st storage.ObjectStorage, runID int64, artifactName string) error {
// read all db artifacts by name
artifacts, err := db.Find[actions.ActionArtifact](ctx, actions.FindArtifactsOptions{
@@ -230,7 +278,7 @@ func mergeChunksForArtifact(ctx *ArtifactContext, chunks []*chunkFileItem, st st
rawChecksum := hash.Sum(nil)
actualChecksum := hex.EncodeToString(rawChecksum)
if !strings.HasSuffix(checksum, actualChecksum) {
- return fmt.Errorf("update artifact error checksum is invalid")
+ return fmt.Errorf("update artifact error checksum is invalid %v vs %v", checksum, actualChecksum)
}
}
diff --git a/routers/api/actions/artifacts_utils.go b/routers/api/actions/artifacts_utils.go
index db602f1e14..18c8e3fbed 100644
--- a/routers/api/actions/artifacts_utils.go
+++ b/routers/api/actions/artifacts_utils.go
@@ -10,9 +10,9 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/actions"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
const (
diff --git a/routers/api/actions/artifactsv4.go b/routers/api/actions/artifactsv4.go
index 5a251e2ef9..c6bc39e7d2 100644
--- a/routers/api/actions/artifactsv4.go
+++ b/routers/api/actions/artifactsv4.go
@@ -24,8 +24,15 @@ package actions
// PUT: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75&comp=block
// 1.3. Continue Upload Zip Content to Blobstorage (unauthenticated request), repeat until everything is uploaded
// PUT: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75&comp=appendBlock
-// 1.4. Unknown xml payload to Blobstorage (unauthenticated request), ignored for now
+// 1.4. BlockList xml payload to Blobstorage (unauthenticated request)
+// Files of about 800MB are parallel in parallel and / or out of order, this file is needed to enshure the correct order
// PUT: http://localhost:3000/twirp/github.actions.results.api.v1.ArtifactService/UploadArtifact?sig=mO7y35r4GyjN7fwg0DTv3-Fv1NDXD84KLEgLpoPOtDI=&expires=2024-01-23+21%3A48%3A37.20833956+%2B0100+CET&artifactName=test&taskID=75&comp=blockList
+// Request
+//
+//
+// blockId1
+// blockId2
+//
// 1.5. FinalizeArtifact
// Post: /twirp/github.actions.results.api.v1.ArtifactService/FinalizeArtifact
// Request
@@ -82,6 +89,7 @@ import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
+ "encoding/xml"
"fmt"
"io"
"net/http"
@@ -90,14 +98,16 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/context"
"google.golang.org/protobuf/encoding/protojson"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
@@ -151,31 +161,34 @@ func ArtifactsV4Routes(prefix string) *web.Route {
return m
}
-func (r artifactV4Routes) buildSignature(endp, expires, artifactName string, taskID int64) []byte {
+func (r artifactV4Routes) buildSignature(endp, expires, artifactName string, taskID, artifactID int64) []byte {
mac := hmac.New(sha256.New, setting.GetGeneralTokenSigningSecret())
mac.Write([]byte(endp))
mac.Write([]byte(expires))
mac.Write([]byte(artifactName))
mac.Write([]byte(fmt.Sprint(taskID)))
+ mac.Write([]byte(fmt.Sprint(artifactID)))
return mac.Sum(nil)
}
-func (r artifactV4Routes) buildArtifactURL(endp, artifactName string, taskID int64) string {
+func (r artifactV4Routes) buildArtifactURL(endp, artifactName string, taskID, artifactID int64) string {
expires := time.Now().Add(60 * time.Minute).Format("2006-01-02 15:04:05.999999999 -0700 MST")
uploadURL := strings.TrimSuffix(setting.AppURL, "/") + strings.TrimSuffix(r.prefix, "/") +
- "/" + endp + "?sig=" + base64.URLEncoding.EncodeToString(r.buildSignature(endp, expires, artifactName, taskID)) + "&expires=" + url.QueryEscape(expires) + "&artifactName=" + url.QueryEscape(artifactName) + "&taskID=" + fmt.Sprint(taskID)
+ "/" + endp + "?sig=" + base64.URLEncoding.EncodeToString(r.buildSignature(endp, expires, artifactName, taskID, artifactID)) + "&expires=" + url.QueryEscape(expires) + "&artifactName=" + url.QueryEscape(artifactName) + "&taskID=" + fmt.Sprint(taskID) + "&artifactID=" + fmt.Sprint(artifactID)
return uploadURL
}
func (r artifactV4Routes) verifySignature(ctx *ArtifactContext, endp string) (*actions.ActionTask, string, bool) {
rawTaskID := ctx.Req.URL.Query().Get("taskID")
+ rawArtifactID := ctx.Req.URL.Query().Get("artifactID")
sig := ctx.Req.URL.Query().Get("sig")
expires := ctx.Req.URL.Query().Get("expires")
artifactName := ctx.Req.URL.Query().Get("artifactName")
dsig, _ := base64.URLEncoding.DecodeString(sig)
taskID, _ := strconv.ParseInt(rawTaskID, 10, 64)
+ artifactID, _ := strconv.ParseInt(rawArtifactID, 10, 64)
- expecedsig := r.buildSignature(endp, expires, artifactName, taskID)
+ expecedsig := r.buildSignature(endp, expires, artifactName, taskID, artifactID)
if !hmac.Equal(dsig, expecedsig) {
log.Error("Error unauthorized")
ctx.Error(http.StatusUnauthorized, "Error unauthorized")
@@ -270,6 +283,8 @@ func (r *artifactV4Routes) createArtifact(ctx *ArtifactContext) {
return
}
artifact.ContentEncoding = ArtifactV4ContentEncoding
+ artifact.FileSize = 0
+ artifact.FileCompressedSize = 0
if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil {
log.Error("Error UpdateArtifactByID: %v", err)
ctx.Error(http.StatusInternalServerError, "Error UpdateArtifactByID")
@@ -278,7 +293,7 @@ func (r *artifactV4Routes) createArtifact(ctx *ArtifactContext) {
respData := CreateArtifactResponse{
Ok: true,
- SignedUploadUrl: r.buildArtifactURL("UploadArtifact", artifactName, ctx.ActionTask.ID),
+ SignedUploadUrl: r.buildArtifactURL("UploadArtifact", artifactName, ctx.ActionTask.ID, artifact.ID),
}
r.sendProtbufBody(ctx, &respData)
}
@@ -289,41 +304,92 @@ func (r *artifactV4Routes) uploadArtifact(ctx *ArtifactContext) {
return
}
+ // check the owner's quota
+ ok, err := quota_model.EvaluateForUser(ctx, task.OwnerID, quota_model.LimitSubjectSizeAssetsArtifacts)
+ if err != nil {
+ log.Error("quota_model.EvaluateForUser: %v", err)
+ ctx.Error(http.StatusInternalServerError, "Error checking quota")
+ return
+ }
+ if !ok {
+ ctx.Error(http.StatusRequestEntityTooLarge, "Quota exceeded")
+ return
+ }
+
comp := ctx.Req.URL.Query().Get("comp")
switch comp {
case "block", "appendBlock":
- // get artifact by name
- artifact, err := r.getArtifactByName(ctx, task.Job.RunID, artifactName)
- if err != nil {
- log.Error("Error artifact not found: %v", err)
- ctx.Error(http.StatusNotFound, "Error artifact not found")
- return
- }
+ blockid := ctx.Req.URL.Query().Get("blockid")
+ if blockid == "" {
+ // get artifact by name
+ artifact, err := r.getArtifactByName(ctx, task.Job.RunID, artifactName)
+ if err != nil {
+ log.Error("Error artifact not found: %v", err)
+ ctx.Error(http.StatusNotFound, "Error artifact not found")
+ return
+ }
- if comp == "block" {
- artifact.FileSize = 0
- artifact.FileCompressedSize = 0
+ _, err = appendUploadChunk(r.fs, ctx, artifact, artifact.FileSize, ctx.Req.ContentLength, artifact.RunID)
+ if err != nil {
+ log.Error("Error runner api getting task: task is not running")
+ ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running")
+ return
+ }
+ artifact.FileCompressedSize += ctx.Req.ContentLength
+ artifact.FileSize += ctx.Req.ContentLength
+ if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil {
+ log.Error("Error UpdateArtifactByID: %v", err)
+ ctx.Error(http.StatusInternalServerError, "Error UpdateArtifactByID")
+ return
+ }
+ } else {
+ _, err := r.fs.Save(fmt.Sprintf("tmpv4%d/block-%d-%d-%s", task.Job.RunID, task.Job.RunID, ctx.Req.ContentLength, base64.URLEncoding.EncodeToString([]byte(blockid))), ctx.Req.Body, -1)
+ if err != nil {
+ log.Error("Error runner api getting task: task is not running")
+ ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running")
+ return
+ }
}
-
- _, err = appendUploadChunk(r.fs, ctx, artifact, artifact.FileSize, ctx.Req.ContentLength, artifact.RunID)
+ ctx.JSON(http.StatusCreated, "appended")
+ case "blocklist":
+ rawArtifactID := ctx.Req.URL.Query().Get("artifactID")
+ artifactID, _ := strconv.ParseInt(rawArtifactID, 10, 64)
+ _, err := r.fs.Save(fmt.Sprintf("tmpv4%d/%d-%d-blocklist", task.Job.RunID, task.Job.RunID, artifactID), ctx.Req.Body, -1)
if err != nil {
log.Error("Error runner api getting task: task is not running")
ctx.Error(http.StatusInternalServerError, "Error runner api getting task: task is not running")
return
}
- artifact.FileCompressedSize += ctx.Req.ContentLength
- artifact.FileSize += ctx.Req.ContentLength
- if err := actions.UpdateArtifactByID(ctx, artifact.ID, artifact); err != nil {
- log.Error("Error UpdateArtifactByID: %v", err)
- ctx.Error(http.StatusInternalServerError, "Error UpdateArtifactByID")
- return
- }
- ctx.JSON(http.StatusCreated, "appended")
- case "blocklist":
ctx.JSON(http.StatusCreated, "created")
}
}
+type BlockList struct {
+ Latest []string `xml:"Latest"`
+}
+
+type Latest struct {
+ Value string `xml:",chardata"`
+}
+
+func (r *artifactV4Routes) readBlockList(runID, artifactID int64) (*BlockList, error) {
+ blockListName := fmt.Sprintf("tmpv4%d/%d-%d-blocklist", runID, runID, artifactID)
+ s, err := r.fs.Open(blockListName)
+ if err != nil {
+ return nil, err
+ }
+
+ xdec := xml.NewDecoder(s)
+ blockList := &BlockList{}
+ err = xdec.Decode(blockList)
+
+ delerr := r.fs.Delete(blockListName)
+ if delerr != nil {
+ log.Warn("Failed to delete blockList %s: %v", blockListName, delerr)
+ }
+ return blockList, err
+}
+
func (r *artifactV4Routes) finalizeArtifact(ctx *ArtifactContext) {
var req FinalizeArtifactRequest
@@ -342,18 +408,34 @@ func (r *artifactV4Routes) finalizeArtifact(ctx *ArtifactContext) {
ctx.Error(http.StatusNotFound, "Error artifact not found")
return
}
- chunkMap, err := listChunksByRunID(r.fs, runID)
+
+ var chunks []*chunkFileItem
+ blockList, err := r.readBlockList(runID, artifact.ID)
if err != nil {
- log.Error("Error merge chunks: %v", err)
- ctx.Error(http.StatusInternalServerError, "Error merge chunks")
- return
- }
- chunks, ok := chunkMap[artifact.ID]
- if !ok {
- log.Error("Error merge chunks")
- ctx.Error(http.StatusInternalServerError, "Error merge chunks")
- return
+ log.Warn("Failed to read BlockList, fallback to old behavior: %v", err)
+ chunkMap, err := listChunksByRunID(r.fs, runID)
+ if err != nil {
+ log.Error("Error merge chunks: %v", err)
+ ctx.Error(http.StatusInternalServerError, "Error merge chunks")
+ return
+ }
+ chunks, ok = chunkMap[artifact.ID]
+ if !ok {
+ log.Error("Error merge chunks")
+ ctx.Error(http.StatusInternalServerError, "Error merge chunks")
+ return
+ }
+ } else {
+ chunks, err = listChunksByRunIDV4(r.fs, runID, artifact.ID, blockList)
+ if err != nil {
+ log.Error("Error merge chunks: %v", err)
+ ctx.Error(http.StatusInternalServerError, "Error merge chunks")
+ return
+ }
+ artifact.FileSize = chunks[len(chunks)-1].End + 1
+ artifact.FileCompressedSize = chunks[len(chunks)-1].End + 1
}
+
checksum := ""
if req.Hash != nil {
checksum = req.Hash.Value
@@ -448,13 +530,13 @@ func (r *artifactV4Routes) getSignedArtifactURL(ctx *ArtifactContext) {
respData := GetSignedArtifactURLResponse{}
if setting.Actions.ArtifactStorage.MinioConfig.ServeDirect {
- u, err := storage.ActionsArtifacts.URL(artifact.StoragePath, artifact.ArtifactPath)
+ u, err := storage.ActionsArtifacts.URL(artifact.StoragePath, artifact.ArtifactPath, nil)
if u != nil && err == nil {
respData.SignedUrl = u.String()
}
}
if respData.SignedUrl == "" {
- respData.SignedUrl = r.buildArtifactURL("DownloadArtifact", artifactName, ctx.ActionTask.ID)
+ respData.SignedUrl = r.buildArtifactURL("DownloadArtifact", artifactName, ctx.ActionTask.ID, artifact.ID)
}
r.sendProtbufBody(ctx, &respData)
}
@@ -473,9 +555,14 @@ func (r *artifactV4Routes) downloadArtifact(ctx *ArtifactContext) {
return
}
- file, _ := r.fs.Open(artifact.StoragePath)
+ file, err := r.fs.Open(artifact.StoragePath)
+ if err != nil {
+ log.Error("Error artifact could not be opened: %v", err)
+ ctx.Error(http.StatusInternalServerError, err.Error())
+ return
+ }
- _, _ = io.Copy(ctx.Resp, file)
+ common.ServeContentByReadSeeker(ctx.Base, artifactName, util.ToPointer(artifact.UpdatedUnix.AsTime()), file)
}
func (r *artifactV4Routes) deleteArtifact(ctx *ArtifactContext) {
diff --git a/routers/api/actions/ping/ping.go b/routers/api/actions/ping/ping.go
index 13985c93a3..6b3378b72e 100644
--- a/routers/api/actions/ping/ping.go
+++ b/routers/api/actions/ping/ping.go
@@ -8,7 +8,7 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/log"
pingv1 "code.gitea.io/actions-proto-go/ping/v1"
"code.gitea.io/actions-proto-go/ping/v1/pingv1connect"
diff --git a/routers/api/actions/ping/ping_test.go b/routers/api/actions/ping/ping_test.go
index 098b003ea2..98d2dcb820 100644
--- a/routers/api/actions/ping/ping_test.go
+++ b/routers/api/actions/ping/ping_test.go
@@ -4,7 +4,6 @@
package ping
import (
- "context"
"net/http"
"net/http/httptest"
"testing"
@@ -51,7 +50,7 @@ func MainServiceTest(t *testing.T, h http.Handler) {
clients := []pingv1connect.PingServiceClient{connectClient, grpcClient, grpcWebClient}
t.Run("ping request", func(t *testing.T) {
for _, client := range clients {
- result, err := client.Ping(context.Background(), connect.NewRequest(&pingv1.PingRequest{
+ result, err := client.Ping(t.Context(), connect.NewRequest(&pingv1.PingRequest{
Data: "foobar",
}))
require.NoError(t, err)
diff --git a/routers/api/actions/runner/interceptor.go b/routers/api/actions/runner/interceptor.go
index 521ba910e3..be83af6997 100644
--- a/routers/api/actions/runner/interceptor.go
+++ b/routers/api/actions/runner/interceptor.go
@@ -9,15 +9,13 @@ import (
"errors"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
+ actions_model "forgejo.org/models/actions"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
"connectrpc.com/connect"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/status"
)
const (
@@ -37,12 +35,12 @@ var withRunner = connect.WithInterceptors(connect.UnaryInterceptorFunc(func(unar
runner, err := actions_model.GetRunnerByUUID(ctx, uuid)
if err != nil {
if errors.Is(err, util.ErrNotExist) {
- return nil, status.Error(codes.Unauthenticated, "unregistered runner")
+ return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("unregistered runner"))
}
- return nil, status.Error(codes.Internal, err.Error())
+ return nil, connect.NewError(connect.CodeInternal, err)
}
if subtle.ConstantTimeCompare([]byte(runner.TokenHash), []byte(auth_model.HashToken(token, runner.TokenSalt))) != 1 {
- return nil, status.Error(codes.Unauthenticated, "unregistered runner")
+ return nil, connect.NewError(connect.CodeUnauthenticated, errors.New("unregistered runner"))
}
cols := []string{"last_online"}
diff --git a/routers/api/actions/runner/main_test.go b/routers/api/actions/runner/main_test.go
new file mode 100644
index 0000000000..112ebe3cb6
--- /dev/null
+++ b/routers/api/actions/runner/main_test.go
@@ -0,0 +1,16 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package runner
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+
+ _ "forgejo.org/models/forgefed"
+)
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m)
+}
diff --git a/routers/api/actions/runner/runner.go b/routers/api/actions/runner/runner.go
index 017bdf6324..8aae69f463 100644
--- a/routers/api/actions/runner/runner.go
+++ b/routers/api/actions/runner/runner.go
@@ -6,22 +6,21 @@ package runner
import (
"context"
"errors"
+ "fmt"
"net/http"
- actions_model "code.gitea.io/gitea/models/actions"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
- actions_service "code.gitea.io/gitea/services/actions"
+ actions_model "forgejo.org/models/actions"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/actions"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
+ actions_service "forgejo.org/services/actions"
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
"code.gitea.io/actions-proto-go/runner/v1/runnerv1connect"
"connectrpc.com/connect"
gouuid "github.com/google/uuid"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/status"
)
func NewRunnerServiceHandler() (string, http.Handler) {
@@ -44,27 +43,27 @@ func (s *Service) Register(
req *connect.Request[runnerv1.RegisterRequest],
) (*connect.Response[runnerv1.RegisterResponse], error) {
if req.Msg.Token == "" || req.Msg.Name == "" {
- return nil, errors.New("missing runner token, name")
+ return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("missing runner token, name"))
}
runnerToken, err := actions_model.GetRunnerToken(ctx, req.Msg.Token)
if err != nil {
- return nil, errors.New("runner registration token not found")
+ return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("runner registration token not found"))
}
if !runnerToken.IsActive {
- return nil, errors.New("runner registration token has been invalidated, please use the latest one")
+ return nil, connect.NewError(connect.CodeInvalidArgument, errors.New("runner registration token has been invalidated, please use the latest one"))
}
if runnerToken.OwnerID > 0 {
if _, err := user_model.GetUserByID(ctx, runnerToken.OwnerID); err != nil {
- return nil, errors.New("owner of the token not found")
+ return nil, connect.NewError(connect.CodeInternal, errors.New("owner of the token not found"))
}
}
if runnerToken.RepoID > 0 {
if _, err := repo_model.GetRepositoryByID(ctx, runnerToken.RepoID); err != nil {
- return nil, errors.New("repository of the token not found")
+ return nil, connect.NewError(connect.CodeInternal, errors.New("repository of the token not found"))
}
}
@@ -81,18 +80,18 @@ func (s *Service) Register(
AgentLabels: labels,
}
if err := runner.GenerateToken(); err != nil {
- return nil, errors.New("can't generate token")
+ return nil, connect.NewError(connect.CodeInternal, errors.New("can't generate token"))
}
// create new runner
if err := actions_model.CreateRunner(ctx, runner); err != nil {
- return nil, errors.New("can't create new runner")
+ return nil, connect.NewError(connect.CodeInternal, errors.New("can't create new runner"))
}
// update token status
runnerToken.IsActive = true
if err := actions_model.UpdateRunnerToken(ctx, runnerToken, "is_active"); err != nil {
- return nil, errors.New("can't update runner token status")
+ return nil, connect.NewError(connect.CodeInternal, errors.New("can't update runner token status"))
}
res := connect.NewResponse(&runnerv1.RegisterResponse{
@@ -117,7 +116,7 @@ func (s *Service) Declare(
runner.AgentLabels = req.Msg.Labels
runner.Version = req.Msg.Version
if err := actions_model.UpdateRunner(ctx, runner, "agent_labels", "version"); err != nil {
- return nil, status.Errorf(codes.Internal, "update runner: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("update runner: %w", err))
}
return connect.NewResponse(&runnerv1.DeclareResponse{
@@ -143,10 +142,10 @@ func (s *Service) FetchTask(
tasksVersion := req.Msg.TasksVersion // task version from runner
latestVersion, err := actions_model.GetTasksVersionByScope(ctx, runner.OwnerID, runner.RepoID)
if err != nil {
- return nil, status.Errorf(codes.Internal, "query tasks version failed: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("query tasks version failed: %w", err))
} else if latestVersion == 0 {
if err := actions_model.IncreaseTaskVersion(ctx, runner.OwnerID, runner.RepoID); err != nil {
- return nil, status.Errorf(codes.Internal, "fail to increase task version: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("fail to increase task version: %w", err))
}
// if we don't increase the value of `latestVersion` here,
// the response of FetchTask will return tasksVersion as zero.
@@ -158,9 +157,9 @@ func (s *Service) FetchTask(
// if the task version in request is not equal to the version in db,
// it means there may still be some tasks not be assigned.
// try to pick a task for the runner that send the request.
- if t, ok, err := pickTask(ctx, runner); err != nil {
+ if t, ok, err := actions_service.PickTask(ctx, runner); err != nil {
log.Error("pick task failed: %v", err)
- return nil, status.Errorf(codes.Internal, "pick task: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("pick task: %w", err))
} else if ok {
task = t
}
@@ -177,9 +176,11 @@ func (s *Service) UpdateTask(
ctx context.Context,
req *connect.Request[runnerv1.UpdateTaskRequest],
) (*connect.Response[runnerv1.UpdateTaskResponse], error) {
- task, err := actions_model.UpdateTaskByState(ctx, req.Msg.State)
+ runner := GetRunner(ctx)
+
+ task, err := actions_model.UpdateTaskByState(ctx, runner.ID, req.Msg.State)
if err != nil {
- return nil, status.Errorf(codes.Internal, "update task: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("update task: %w", err))
}
for k, v := range req.Msg.Outputs {
@@ -208,10 +209,10 @@ func (s *Service) UpdateTask(
}
if err := task.LoadJob(ctx); err != nil {
- return nil, status.Errorf(codes.Internal, "load job: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("load job: %w", err))
}
if err := task.Job.LoadRun(ctx); err != nil {
- return nil, status.Errorf(codes.Internal, "load run: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("load run: %w", err))
}
// don't create commit status for cron job
@@ -239,11 +240,15 @@ func (s *Service) UpdateLog(
ctx context.Context,
req *connect.Request[runnerv1.UpdateLogRequest],
) (*connect.Response[runnerv1.UpdateLogResponse], error) {
+ runner := GetRunner(ctx)
+
res := connect.NewResponse(&runnerv1.UpdateLogResponse{})
task, err := actions_model.GetTaskByID(ctx, req.Msg.TaskId)
if err != nil {
- return nil, status.Errorf(codes.Internal, "get task: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("get task: %w", err))
+ } else if runner.ID != task.RunnerID {
+ return nil, connect.NewError(connect.CodeInternal, errors.New("invalid runner for task"))
}
ack := task.LogLength
@@ -253,13 +258,13 @@ func (s *Service) UpdateLog(
}
if task.LogInStorage {
- return nil, status.Errorf(codes.AlreadyExists, "log file has been archived")
+ return nil, connect.NewError(connect.CodeAlreadyExists, errors.New("log file has been archived"))
}
rows := req.Msg.Rows[ack-req.Msg.Index:]
ns, err := actions.WriteLogs(ctx, task.LogFilename, task.LogSize, rows)
if err != nil {
- return nil, status.Errorf(codes.Internal, "write logs: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("write logs: %w", err))
}
task.LogLength += int64(len(rows))
for _, n := range ns {
@@ -274,12 +279,12 @@ func (s *Service) UpdateLog(
task.LogInStorage = true
remove, err = actions.TransferLogs(ctx, task.LogFilename)
if err != nil {
- return nil, status.Errorf(codes.Internal, "transfer logs: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("transfer logs: %w", err))
}
}
if err := actions_model.UpdateTask(ctx, task, "log_indexes", "log_length", "log_size", "log_in_storage"); err != nil {
- return nil, status.Errorf(codes.Internal, "update task: %v", err)
+ return nil, connect.NewError(connect.CodeInternal, fmt.Errorf("update task: %w", err))
}
if remove != nil {
remove()
diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go
deleted file mode 100644
index ff6ec5bd54..0000000000
--- a/routers/api/actions/runner/utils.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright 2022 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package runner
-
-import (
- "context"
- "fmt"
-
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- secret_model "code.gitea.io/gitea/models/secret"
- actions_module "code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/actions"
-
- runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
- "google.golang.org/protobuf/types/known/structpb"
-)
-
-func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv1.Task, bool, error) {
- t, ok, err := actions_model.CreateTaskForRunner(ctx, runner)
- if err != nil {
- return nil, false, fmt.Errorf("CreateTaskForRunner: %w", err)
- }
- if !ok {
- return nil, false, nil
- }
-
- secrets, err := secret_model.GetSecretsOfTask(ctx, t)
- if err != nil {
- return nil, false, fmt.Errorf("GetSecretsOfTask: %w", err)
- }
-
- vars, err := actions_model.GetVariablesOfRun(ctx, t.Job.Run)
- if err != nil {
- return nil, false, fmt.Errorf("GetVariablesOfRun: %w", err)
- }
-
- actions.CreateCommitStatus(ctx, t.Job)
-
- task := &runnerv1.Task{
- Id: t.ID,
- WorkflowPayload: t.Job.WorkflowPayload,
- Context: generateTaskContext(t),
- Secrets: secrets,
- Vars: vars,
- }
-
- if needs, err := findTaskNeeds(ctx, t); err != nil {
- log.Error("Cannot find needs for task %v: %v", t.ID, err)
- // Go on with empty needs.
- // If return error, the task will be wild, which means the runner will never get it when it has been assigned to the runner.
- // In contrast, missing needs is less serious.
- // And the task will fail and the runner will report the error in the logs.
- } else {
- task.Needs = needs
- }
-
- return task, true, nil
-}
-
-func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct {
- event := map[string]any{}
- _ = json.Unmarshal([]byte(t.Job.Run.EventPayload), &event)
-
- // TriggerEvent is added in https://github.com/go-gitea/gitea/pull/25229
- // This fallback is for the old ActionRun that doesn't have the TriggerEvent field
- // and should be removed in 1.22
- eventName := t.Job.Run.TriggerEvent
- if eventName == "" {
- eventName = t.Job.Run.Event.Event()
- }
-
- baseRef := ""
- headRef := ""
- ref := t.Job.Run.Ref
- sha := t.Job.Run.CommitSHA
- if pullPayload, err := t.Job.Run.GetPullRequestEventPayload(); err == nil && pullPayload.PullRequest != nil && pullPayload.PullRequest.Base != nil && pullPayload.PullRequest.Head != nil {
- baseRef = pullPayload.PullRequest.Base.Ref
- headRef = pullPayload.PullRequest.Head.Ref
-
- // if the TriggerEvent is pull_request_target, ref and sha need to be set according to the base of pull request
- // In GitHub's documentation, ref should be the branch or tag that triggered workflow. But when the TriggerEvent is pull_request_target,
- // the ref will be the base branch.
- if t.Job.Run.TriggerEvent == actions_module.GithubEventPullRequestTarget {
- ref = git.BranchPrefix + pullPayload.PullRequest.Base.Name
- sha = pullPayload.PullRequest.Base.Sha
- }
- }
-
- refName := git.RefName(ref)
-
- giteaRuntimeToken, err := actions.CreateAuthorizationToken(t.ID, t.Job.RunID, t.JobID)
- if err != nil {
- log.Error("actions.CreateAuthorizationToken failed: %v", err)
- }
-
- taskContext, err := structpb.NewStruct(map[string]any{
- // standard contexts, see https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
- "action": "", // string, The name of the action currently running, or the id of a step. GitHub removes special characters, and uses the name __run when the current step runs a script without an id. If you use the same action more than once in the same job, the name will include a suffix with the sequence number with underscore before it. For example, the first script you run will have the name __run, and the second script will be named __run_2. Similarly, the second invocation of actions/checkout will be actionscheckout2.
- "action_path": "", // string, The path where an action is located. This property is only supported in composite actions. You can use this path to access files located in the same repository as the action.
- "action_ref": "", // string, For a step executing an action, this is the ref of the action being executed. For example, v2.
- "action_repository": "", // string, For a step executing an action, this is the owner and repository name of the action. For example, actions/checkout.
- "action_status": "", // string, For a composite action, the current result of the composite action.
- "actor": t.Job.Run.TriggerUser.Name, // string, The username of the user that triggered the initial workflow run. If the workflow run is a re-run, this value may differ from github.triggering_actor. Any workflow re-runs will use the privileges of github.actor, even if the actor initiating the re-run (github.triggering_actor) has different privileges.
- "api_url": setting.AppURL + "api/v1", // string, The URL of the GitHub REST API.
- "base_ref": baseRef, // string, The base_ref or target branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target.
- "env": "", // string, Path on the runner to the file that sets environment variables from workflow commands. This file is unique to the current step and is a different file for each step in a job. For more information, see "Workflow commands for GitHub Actions."
- "event": event, // object, The full event webhook payload. You can access individual properties of the event using this context. This object is identical to the webhook payload of the event that triggered the workflow run, and is different for each event. The webhooks for each GitHub Actions event is linked in "Events that trigger workflows." For example, for a workflow run triggered by the push event, this object contains the contents of the push webhook payload.
- "event_name": eventName, // string, The name of the event that triggered the workflow run.
- "event_path": "", // string, The path to the file on the runner that contains the full event webhook payload.
- "graphql_url": "", // string, The URL of the GitHub GraphQL API.
- "head_ref": headRef, // string, The head_ref or source branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target.
- "job": fmt.Sprint(t.JobID), // string, The job_id of the current job.
- "ref": ref, // string, The fully-formed ref of the branch or tag that triggered the workflow run. For workflows triggered by push, this is the branch or tag ref that was pushed. For workflows triggered by pull_request, this is the pull request merge branch. For workflows triggered by release, this is the release tag created. For other triggers, this is the branch or tag ref that triggered the workflow run. This is only set if a branch or tag is available for the event type. The ref given is fully-formed, meaning that for branches the format is refs/heads/, for pull requests it is refs/pull//merge, and for tags it is refs/tags/. For example, refs/heads/feature-branch-1.
- "ref_name": refName.ShortName(), // string, The short ref name of the branch or tag that triggered the workflow run. This value matches the branch or tag name shown on GitHub. For example, feature-branch-1.
- "ref_protected": false, // boolean, true if branch protections are configured for the ref that triggered the workflow run.
- "ref_type": refName.RefType(), // string, The type of ref that triggered the workflow run. Valid values are branch or tag.
- "path": "", // string, Path on the runner to the file that sets system PATH variables from workflow commands. This file is unique to the current step and is a different file for each step in a job. For more information, see "Workflow commands for GitHub Actions."
- "repository": t.Job.Run.Repo.OwnerName + "/" + t.Job.Run.Repo.Name, // string, The owner and repository name. For example, Codertocat/Hello-World.
- "repository_owner": t.Job.Run.Repo.OwnerName, // string, The repository owner's name. For example, Codertocat.
- "repositoryUrl": t.Job.Run.Repo.HTMLURL(), // string, The Git URL to the repository. For example, git://github.com/codertocat/hello-world.git.
- "retention_days": "", // string, The number of days that workflow run logs and artifacts are kept.
- "run_id": fmt.Sprint(t.Job.RunID), // string, A unique number for each workflow run within a repository. This number does not change if you re-run the workflow run.
- "run_number": fmt.Sprint(t.Job.Run.Index), // string, A unique number for each run of a particular workflow in a repository. This number begins at 1 for the workflow's first run, and increments with each new run. This number does not change if you re-run the workflow run.
- "run_attempt": fmt.Sprint(t.Job.Attempt), // string, A unique number for each attempt of a particular workflow run in a repository. This number begins at 1 for the workflow run's first attempt, and increments with each re-run.
- "secret_source": "Actions", // string, The source of a secret used in a workflow. Possible values are None, Actions, Dependabot, or Codespaces.
- "server_url": setting.AppURL, // string, The URL of the GitHub server. For example: https://github.com.
- "sha": sha, // string, The commit SHA that triggered the workflow. The value of this commit SHA depends on the event that triggered the workflow. For more information, see "Events that trigger workflows." For example, ffac537e6cbbf934b08745a378932722df287a53.
- "token": t.Token, // string, A token to authenticate on behalf of the GitHub App installed on your repository. This is functionally equivalent to the GITHUB_TOKEN secret. For more information, see "Automatic token authentication."
- "triggering_actor": "", // string, The username of the user that initiated the workflow run. If the workflow run is a re-run, this value may differ from github.actor. Any workflow re-runs will use the privileges of github.actor, even if the actor initiating the re-run (github.triggering_actor) has different privileges.
- "workflow": t.Job.Run.WorkflowID, // string, The name of the workflow. If the workflow file doesn't specify a name, the value of this property is the full path of the workflow file in the repository.
- "workspace": "", // string, The default working directory on the runner for steps, and the default location of your repository when using the checkout action.
-
- // additional contexts
- "gitea_default_actions_url": setting.Actions.DefaultActionsURL.URL(),
- "gitea_runtime_token": giteaRuntimeToken,
- })
- if err != nil {
- log.Error("structpb.NewStruct failed: %v", err)
- }
-
- return taskContext
-}
-
-func findTaskNeeds(ctx context.Context, task *actions_model.ActionTask) (map[string]*runnerv1.TaskNeed, error) {
- if err := task.LoadAttributes(ctx); err != nil {
- return nil, fmt.Errorf("LoadAttributes: %w", err)
- }
- if len(task.Job.Needs) == 0 {
- return nil, nil
- }
- needs := container.SetOf(task.Job.Needs...)
-
- jobs, err := db.Find[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{RunID: task.Job.RunID})
- if err != nil {
- return nil, fmt.Errorf("FindRunJobs: %w", err)
- }
-
- ret := make(map[string]*runnerv1.TaskNeed, len(needs))
- for _, job := range jobs {
- if !needs.Contains(job.JobID) {
- continue
- }
- if job.TaskID == 0 || !job.Status.IsDone() {
- // it shouldn't happen, or the job has been rerun
- continue
- }
- outputs := make(map[string]string)
- got, err := actions_model.FindTaskOutputByTaskID(ctx, job.TaskID)
- if err != nil {
- return nil, fmt.Errorf("FindTaskOutputByTaskID: %w", err)
- }
- for _, v := range got {
- outputs[v.OutputKey] = v.OutputValue
- }
- ret[job.JobID] = &runnerv1.TaskNeed{
- Outputs: outputs,
- Result: runnerv1.Result(job.Status),
- }
- }
-
- return ret, nil
-}
diff --git a/routers/api/forgejo/v1/api.go b/routers/api/forgejo/v1/api.go
index 88c7502e66..dfc5a29d05 100644
--- a/routers/api/forgejo/v1/api.go
+++ b/routers/api/forgejo/v1/api.go
@@ -4,8 +4,8 @@
package v1
import (
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/shared"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/shared"
)
func Routes() *web.Route {
diff --git a/routers/api/forgejo/v1/forgejo.go b/routers/api/forgejo/v1/forgejo.go
index 0f1f4f1932..b63db6fb9a 100644
--- a/routers/api/forgejo/v1/forgejo.go
+++ b/routers/api/forgejo/v1/forgejo.go
@@ -5,8 +5,8 @@ package v1
import (
"net/http"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
)
type Forgejo struct{}
diff --git a/routers/api/packages/alpine/alpine.go b/routers/api/packages/alpine/alpine.go
index 481cf70d33..dc992ebb5a 100644
--- a/routers/api/packages/alpine/alpine.go
+++ b/routers/api/packages/alpine/alpine.go
@@ -13,16 +13,16 @@ import (
"net/http"
"strings"
- packages_model "code.gitea.io/gitea/models/packages"
- alpine_model "code.gitea.io/gitea/models/packages/alpine"
- "code.gitea.io/gitea/modules/json"
- packages_module "code.gitea.io/gitea/modules/packages"
- alpine_module "code.gitea.io/gitea/modules/packages/alpine"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
- alpine_service "code.gitea.io/gitea/services/packages/alpine"
+ packages_model "forgejo.org/models/packages"
+ alpine_model "forgejo.org/models/packages/alpine"
+ "forgejo.org/modules/json"
+ packages_module "forgejo.org/modules/packages"
+ alpine_module "forgejo.org/modules/packages/alpine"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
+ alpine_service "forgejo.org/services/packages/alpine"
)
func apiError(ctx *context.Context, status int, obj any) {
@@ -120,7 +120,7 @@ func GetRepositoryFile(ctx *context.Context) {
ctx,
pv,
&packages_service.PackageFileInfo{
- Filename: alpine_service.IndexFilename,
+ Filename: alpine_service.IndexArchiveFilename,
CompositeKey: fmt.Sprintf("%s|%s|%s", ctx.Params("branch"), ctx.Params("repository"), ctx.Params("architecture")),
},
)
@@ -217,17 +217,23 @@ func UploadPackageFile(ctx *context.Context) {
}
func DownloadPackageFile(ctx *context.Context) {
- pfs, _, err := packages_model.SearchFiles(ctx, &packages_model.PackageFileSearchOptions{
+ branch := ctx.Params("branch")
+ repository := ctx.Params("repository")
+ architecture := ctx.Params("architecture")
+
+ opts := &packages_model.PackageFileSearchOptions{
OwnerID: ctx.Package.Owner.ID,
PackageType: packages_model.TypeAlpine,
Query: ctx.Params("filename"),
- CompositeKey: fmt.Sprintf("%s|%s|%s", ctx.Params("branch"), ctx.Params("repository"), ctx.Params("architecture")),
- })
+ CompositeKey: fmt.Sprintf("%s|%s|%s", branch, repository, architecture),
+ }
+
+ pfs, _, err := packages_model.SearchFiles(ctx, opts)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
}
- if len(pfs) != 1 {
+ if len(pfs) == 0 {
apiError(ctx, http.StatusNotFound, nil)
return
}
diff --git a/routers/api/packages/alt/alt.go b/routers/api/packages/alt/alt.go
new file mode 100644
index 0000000000..a118459ce3
--- /dev/null
+++ b/routers/api/packages/alt/alt.go
@@ -0,0 +1,260 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package alt
+
+import (
+ stdctx "context"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "strings"
+
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/json"
+ packages_module "forgejo.org/modules/packages"
+ rpm_module "forgejo.org/modules/packages/rpm"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ notify_service "forgejo.org/services/notify"
+ packages_service "forgejo.org/services/packages"
+ alt_service "forgejo.org/services/packages/alt"
+)
+
+func apiError(ctx *context.Context, status int, obj any) {
+ helper.LogAndProcessError(ctx, status, obj, func(message string) {
+ ctx.PlainText(status, message)
+ })
+}
+
+func GetRepositoryConfig(ctx *context.Context) {
+ group := ctx.Params("group")
+
+ var groupParts []string
+ if group != "" {
+ groupParts = strings.Split(group, "/")
+ }
+
+ url := fmt.Sprintf("%sapi/packages/%s/alt", setting.AppURL, ctx.Package.Owner.Name)
+
+ ctx.PlainText(http.StatusOK, `[gitea-`+strings.Join(append([]string{ctx.Package.Owner.LowerName}, groupParts...), "-")+`]
+name=`+strings.Join(append([]string{ctx.Package.Owner.Name, setting.AppName}, groupParts...), " - ")+`
+baseurl=`+strings.Join(append([]string{url}, groupParts...), "/")+`
+enabled=1`)
+}
+
+// Gets a pre-generated repository metadata file
+func GetRepositoryFile(ctx *context.Context, arch string) {
+ pv, err := alt_service.GetOrCreateRepositoryVersion(ctx, ctx.Package.Owner.ID)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ s, u, pf, err := packages_service.GetFileStreamByPackageVersion(
+ ctx,
+ pv,
+ &packages_service.PackageFileInfo{
+ Filename: ctx.Params("filename"),
+ CompositeKey: arch + "__" + ctx.Params("group"),
+ },
+ )
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ apiError(ctx, http.StatusNotFound, err)
+ } else {
+ apiError(ctx, http.StatusInternalServerError, err)
+ }
+ return
+ }
+
+ helper.ServePackageFile(ctx, s, u, pf)
+}
+
+func UploadPackageFile(ctx *context.Context) {
+ upload, needToClose, err := ctx.UploadStream()
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ if needToClose {
+ defer upload.Close()
+ }
+
+ buf, err := packages_module.CreateHashedBufferFromReader(upload)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ defer buf.Close()
+
+ pck, err := rpm_module.ParsePackage(buf, "alt")
+ if err != nil {
+ if errors.Is(err, util.ErrInvalidArgument) {
+ apiError(ctx, http.StatusBadRequest, err)
+ } else {
+ apiError(ctx, http.StatusInternalServerError, err)
+ }
+ return
+ }
+ if _, err := buf.Seek(0, io.SeekStart); err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ fileMetadataRaw, err := json.Marshal(pck.FileMetadata)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ group := ctx.Params("group")
+ _, _, err = packages_service.CreatePackageOrAddFileToExisting(
+ ctx,
+ &packages_service.PackageCreationInfo{
+ PackageInfo: packages_service.PackageInfo{
+ Owner: ctx.Package.Owner,
+ PackageType: packages_model.TypeAlt,
+ Name: pck.Name,
+ Version: pck.Version,
+ },
+ Creator: ctx.Doer,
+ Metadata: pck.VersionMetadata,
+ },
+ &packages_service.PackageFileCreationInfo{
+ PackageFileInfo: packages_service.PackageFileInfo{
+ Filename: fmt.Sprintf("%s-%s.%s.rpm", pck.Name, pck.Version, pck.FileMetadata.Architecture),
+ CompositeKey: group,
+ },
+ Creator: ctx.Doer,
+ Data: buf,
+ IsLead: true,
+ Properties: map[string]string{
+ rpm_module.PropertyGroup: group,
+ rpm_module.PropertyArchitecture: pck.FileMetadata.Architecture,
+ rpm_module.PropertyMetadata: string(fileMetadataRaw),
+ },
+ },
+ )
+ if err != nil {
+ switch err {
+ case packages_model.ErrDuplicatePackageVersion, packages_model.ErrDuplicatePackageFile:
+ apiError(ctx, http.StatusConflict, err)
+ case packages_service.ErrQuotaTotalCount, packages_service.ErrQuotaTypeSize, packages_service.ErrQuotaTotalSize:
+ apiError(ctx, http.StatusForbidden, err)
+ default:
+ apiError(ctx, http.StatusInternalServerError, err)
+ }
+ return
+ }
+
+ if err := alt_service.BuildSpecificRepositoryFiles(ctx, ctx.Package.Owner.ID, group); err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ ctx.Status(http.StatusCreated)
+}
+
+func DownloadPackageFile(ctx *context.Context) {
+ name := ctx.Params("name")
+ version := ctx.Params("version")
+
+ s, u, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
+ ctx,
+ &packages_service.PackageInfo{
+ Owner: ctx.Package.Owner,
+ PackageType: packages_model.TypeAlt,
+ Name: name,
+ Version: version,
+ },
+ &packages_service.PackageFileInfo{
+ Filename: fmt.Sprintf("%s-%s.%s.rpm", name, version, ctx.Params("architecture")),
+ CompositeKey: ctx.Params("group"),
+ },
+ )
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ apiError(ctx, http.StatusNotFound, err)
+ } else {
+ apiError(ctx, http.StatusInternalServerError, err)
+ }
+ return
+ }
+
+ helper.ServePackageFile(ctx, s, u, pf)
+}
+
+func DeletePackageFile(webctx *context.Context) {
+ group := webctx.Params("group")
+ name := webctx.Params("name")
+ version := webctx.Params("version")
+ architecture := webctx.Params("architecture")
+
+ var pd *packages_model.PackageDescriptor
+
+ err := db.WithTx(webctx, func(ctx stdctx.Context) error {
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx,
+ webctx.Package.Owner.ID,
+ packages_model.TypeAlt,
+ name,
+ version,
+ )
+ if err != nil {
+ return err
+ }
+
+ pf, err := packages_model.GetFileForVersionByName(
+ ctx,
+ pv.ID,
+ fmt.Sprintf("%s-%s.%s.rpm", name, version, architecture),
+ group,
+ )
+ if err != nil {
+ return err
+ }
+
+ if err := packages_service.DeletePackageFile(ctx, pf); err != nil {
+ return err
+ }
+
+ has, err := packages_model.HasVersionFileReferences(ctx, pv.ID)
+ if err != nil {
+ return err
+ }
+ if !has {
+ pd, err = packages_model.GetPackageDescriptor(ctx, pv)
+ if err != nil {
+ return err
+ }
+
+ if err := packages_service.DeletePackageVersionAndReferences(ctx, pv); err != nil {
+ return err
+ }
+ }
+
+ return nil
+ })
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ apiError(webctx, http.StatusNotFound, err)
+ } else {
+ apiError(webctx, http.StatusInternalServerError, err)
+ }
+ return
+ }
+
+ if pd != nil {
+ notify_service.PackageDelete(webctx, webctx.Doer, pd)
+ }
+
+ if err := alt_service.BuildSpecificRepositoryFiles(webctx, webctx.Package.Owner.ID, group); err != nil {
+ apiError(webctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ webctx.Status(http.StatusNoContent)
+}
diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go
index 79285783b9..ebd081ae77 100644
--- a/routers/api/packages/api.go
+++ b/routers/api/packages/api.go
@@ -8,34 +8,37 @@ import (
"regexp"
"strings"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/packages/alpine"
- "code.gitea.io/gitea/routers/api/packages/cargo"
- "code.gitea.io/gitea/routers/api/packages/chef"
- "code.gitea.io/gitea/routers/api/packages/composer"
- "code.gitea.io/gitea/routers/api/packages/conan"
- "code.gitea.io/gitea/routers/api/packages/conda"
- "code.gitea.io/gitea/routers/api/packages/container"
- "code.gitea.io/gitea/routers/api/packages/cran"
- "code.gitea.io/gitea/routers/api/packages/debian"
- "code.gitea.io/gitea/routers/api/packages/generic"
- "code.gitea.io/gitea/routers/api/packages/goproxy"
- "code.gitea.io/gitea/routers/api/packages/helm"
- "code.gitea.io/gitea/routers/api/packages/maven"
- "code.gitea.io/gitea/routers/api/packages/npm"
- "code.gitea.io/gitea/routers/api/packages/nuget"
- "code.gitea.io/gitea/routers/api/packages/pub"
- "code.gitea.io/gitea/routers/api/packages/pypi"
- "code.gitea.io/gitea/routers/api/packages/rpm"
- "code.gitea.io/gitea/routers/api/packages/rubygems"
- "code.gitea.io/gitea/routers/api/packages/swift"
- "code.gitea.io/gitea/routers/api/packages/vagrant"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/context"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/perm"
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/packages/alpine"
+ "forgejo.org/routers/api/packages/alt"
+ "forgejo.org/routers/api/packages/arch"
+ "forgejo.org/routers/api/packages/cargo"
+ "forgejo.org/routers/api/packages/chef"
+ "forgejo.org/routers/api/packages/composer"
+ "forgejo.org/routers/api/packages/conan"
+ "forgejo.org/routers/api/packages/conda"
+ "forgejo.org/routers/api/packages/container"
+ "forgejo.org/routers/api/packages/cran"
+ "forgejo.org/routers/api/packages/debian"
+ "forgejo.org/routers/api/packages/generic"
+ "forgejo.org/routers/api/packages/goproxy"
+ "forgejo.org/routers/api/packages/helm"
+ "forgejo.org/routers/api/packages/maven"
+ "forgejo.org/routers/api/packages/npm"
+ "forgejo.org/routers/api/packages/nuget"
+ "forgejo.org/routers/api/packages/pub"
+ "forgejo.org/routers/api/packages/pypi"
+ "forgejo.org/routers/api/packages/rpm"
+ "forgejo.org/routers/api/packages/rubygems"
+ "forgejo.org/routers/api/packages/swift"
+ "forgejo.org/routers/api/packages/vagrant"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/context"
)
func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
@@ -63,6 +66,20 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
ctx.Error(http.StatusUnauthorized, "reqPackageAccess", "user should have specific permission or be a site admin")
return
}
+
+ // check if scope only applies to public resources
+ publicOnly, err := scope.PublicOnly()
+ if err != nil {
+ ctx.Error(http.StatusForbidden, "tokenRequiresScope", "parsing public resource scope failed: "+err.Error())
+ return
+ }
+
+ if publicOnly {
+ if ctx.Package != nil && ctx.Package.Owner.Visibility.IsPrivate() {
+ ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public packages")
+ return
+ }
+ }
}
}
@@ -74,6 +91,21 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.Context) {
}
}
+func enforcePackagesQuota() func(ctx *context.Context) {
+ return func(ctx *context.Context) {
+ ok, err := quota_model.EvaluateForUser(ctx, ctx.Doer.ID, quota_model.LimitSubjectSizeAssetsPackagesAll)
+ if err != nil {
+ log.Error("quota_model.EvaluateForUser: %v", err)
+ ctx.Error(http.StatusInternalServerError, "Error checking quota")
+ return
+ }
+ if !ok {
+ ctx.Error(http.StatusRequestEntityTooLarge, "enforcePackagesQuota", "quota exceeded")
+ return
+ }
+ }
+}
+
func verifyAuth(r *web.Route, authMethods []auth.Method) {
if setting.Service.EnableReverseProxyAuth {
authMethods = append(authMethods, &auth.ReverseProxy{})
@@ -111,7 +143,7 @@ func CommonRoutes() *web.Route {
r.Group("/alpine", func() {
r.Get("/key", alpine.GetRepositoryKey)
r.Group("/{branch}/{repository}", func() {
- r.Put("", reqPackageAccess(perm.AccessModeWrite), alpine.UploadPackageFile)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), alpine.UploadPackageFile)
r.Group("/{architecture}", func() {
r.Get("/APKINDEX.tar.gz", alpine.GetRepositoryFile)
r.Group("/{filename}", func() {
@@ -121,15 +153,21 @@ func CommonRoutes() *web.Route {
})
})
}, reqPackageAccess(perm.AccessModeRead))
+ r.Group("/arch", func() {
+ r.Methods("HEAD,GET", "/repository.key", arch.GetRepositoryKey)
+ r.Methods("HEAD,GET", "*", arch.GetPackageOrDB)
+ r.Methods("PUT", "*", reqPackageAccess(perm.AccessModeWrite), arch.PushPackage)
+ r.Methods("DELETE", "*", reqPackageAccess(perm.AccessModeWrite), arch.RemovePackage)
+ }, reqPackageAccess(perm.AccessModeRead))
r.Group("/cargo", func() {
r.Group("/api/v1/crates", func() {
r.Get("", cargo.SearchPackages)
- r.Put("/new", reqPackageAccess(perm.AccessModeWrite), cargo.UploadPackage)
+ r.Put("/new", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), cargo.UploadPackage)
r.Group("/{package}", func() {
r.Group("/{version}", func() {
r.Get("/download", cargo.DownloadPackageFile)
r.Delete("/yank", reqPackageAccess(perm.AccessModeWrite), cargo.YankPackage)
- r.Put("/unyank", reqPackageAccess(perm.AccessModeWrite), cargo.UnyankPackage)
+ r.Put("/unyank", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), cargo.UnyankPackage)
})
r.Get("/owners", cargo.ListOwners)
})
@@ -147,7 +185,7 @@ func CommonRoutes() *web.Route {
r.Get("/search", chef.EnumeratePackages)
r.Group("/cookbooks", func() {
r.Get("", chef.EnumeratePackages)
- r.Post("", reqPackageAccess(perm.AccessModeWrite), chef.UploadPackage)
+ r.Post("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), chef.UploadPackage)
r.Group("/{name}", func() {
r.Get("", chef.PackageMetadata)
r.Group("/versions/{version}", func() {
@@ -167,7 +205,7 @@ func CommonRoutes() *web.Route {
r.Get("/p2/{vendorname}/{projectname}~dev.json", composer.PackageMetadata)
r.Get("/p2/{vendorname}/{projectname}.json", composer.PackageMetadata)
r.Get("/files/{package}/{version}/{filename}", composer.DownloadPackageFile)
- r.Put("", reqPackageAccess(perm.AccessModeWrite), composer.UploadPackage)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), composer.UploadPackage)
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/conan", func() {
r.Group("/v1", func() {
@@ -183,14 +221,14 @@ func CommonRoutes() *web.Route {
r.Delete("", reqPackageAccess(perm.AccessModeWrite), conan.DeleteRecipeV1)
r.Get("/search", conan.SearchPackagesV1)
r.Get("/digest", conan.RecipeDownloadURLs)
- r.Post("/upload_urls", reqPackageAccess(perm.AccessModeWrite), conan.RecipeUploadURLs)
+ r.Post("/upload_urls", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), conan.RecipeUploadURLs)
r.Get("/download_urls", conan.RecipeDownloadURLs)
r.Group("/packages", func() {
r.Post("/delete", reqPackageAccess(perm.AccessModeWrite), conan.DeletePackageV1)
r.Group("/{package_reference}", func() {
r.Get("", conan.PackageSnapshot)
r.Get("/digest", conan.PackageDownloadURLs)
- r.Post("/upload_urls", reqPackageAccess(perm.AccessModeWrite), conan.PackageUploadURLs)
+ r.Post("/upload_urls", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), conan.PackageUploadURLs)
r.Get("/download_urls", conan.PackageDownloadURLs)
})
})
@@ -199,11 +237,11 @@ func CommonRoutes() *web.Route {
r.Group("/files/{name}/{version}/{user}/{channel}/{recipe_revision}", func() {
r.Group("/recipe/{filename}", func() {
r.Get("", conan.DownloadRecipeFile)
- r.Put("", reqPackageAccess(perm.AccessModeWrite), conan.UploadRecipeFile)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), conan.UploadRecipeFile)
})
r.Group("/package/{package_reference}/{package_revision}/{filename}", func() {
r.Get("", conan.DownloadPackageFile)
- r.Put("", reqPackageAccess(perm.AccessModeWrite), conan.UploadPackageFile)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), conan.UploadPackageFile)
})
}, conan.ExtractPathParameters)
})
@@ -228,7 +266,7 @@ func CommonRoutes() *web.Route {
r.Get("", conan.ListRecipeRevisionFiles)
r.Group("/{filename}", func() {
r.Get("", conan.DownloadRecipeFile)
- r.Put("", reqPackageAccess(perm.AccessModeWrite), conan.UploadRecipeFile)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), conan.UploadRecipeFile)
})
})
r.Group("/packages", func() {
@@ -244,7 +282,7 @@ func CommonRoutes() *web.Route {
r.Get("", conan.ListPackageRevisionFiles)
r.Group("/{filename}", func() {
r.Get("", conan.DownloadPackageFile)
- r.Put("", reqPackageAccess(perm.AccessModeWrite), conan.UploadPackageFile)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), conan.UploadPackageFile)
})
})
})
@@ -281,7 +319,7 @@ func CommonRoutes() *web.Route {
conda.DownloadPackageFile(ctx)
}
})
- r.Put("/*", reqPackageAccess(perm.AccessModeWrite), func(ctx *context.Context) {
+ r.Put("/*", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), func(ctx *context.Context) {
m := uploadPattern.FindStringSubmatch(ctx.Params("*"))
if len(m) == 0 {
ctx.Status(http.StatusNotFound)
@@ -300,8 +338,9 @@ func CommonRoutes() *web.Route {
r.Get("/PACKAGES", cran.EnumerateSourcePackages)
r.Get("/PACKAGES{format}", cran.EnumerateSourcePackages)
r.Get("/{filename}", cran.DownloadSourcePackageFile)
+ r.Get("/Archive/{packagename}/{filename}", cran.DownloadSourcePackageFile)
})
- r.Put("", reqPackageAccess(perm.AccessModeWrite), cran.UploadSourcePackageFile)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), cran.UploadSourcePackageFile)
})
r.Group("/bin", func() {
r.Group("/{platform}/contrib/{rversion}", func() {
@@ -309,7 +348,7 @@ func CommonRoutes() *web.Route {
r.Get("/PACKAGES{format}", cran.EnumerateBinaryPackages)
r.Get("/{filename}", cran.DownloadBinaryPackageFile)
})
- r.Put("", reqPackageAccess(perm.AccessModeWrite), cran.UploadBinaryPackageFile)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), cran.UploadBinaryPackageFile)
})
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/debian", func() {
@@ -325,13 +364,13 @@ func CommonRoutes() *web.Route {
r.Group("/pool/{distribution}/{component}", func() {
r.Get("/{name}_{version}_{architecture}.deb", debian.DownloadPackageFile)
r.Group("", func() {
- r.Put("/upload", debian.UploadPackageFile)
+ r.Put("/upload", enforcePackagesQuota(), debian.UploadPackageFile)
r.Delete("/{name}/{version}/{architecture}", debian.DeletePackageFile)
}, reqPackageAccess(perm.AccessModeWrite))
})
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/go", func() {
- r.Put("/upload", reqPackageAccess(perm.AccessModeWrite), goproxy.UploadPackage)
+ r.Put("/upload", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), goproxy.UploadPackage)
r.Get("/sumdb/sum.golang.org/supported", func(ctx *context.Context) {
ctx.Status(http.StatusNotFound)
})
@@ -394,7 +433,7 @@ func CommonRoutes() *web.Route {
r.Group("/{filename}", func() {
r.Get("", generic.DownloadPackageFile)
r.Group("", func() {
- r.Put("", generic.UploadPackage)
+ r.Put("", enforcePackagesQuota(), generic.UploadPackage)
r.Delete("", generic.DeletePackageFile)
}, reqPackageAccess(perm.AccessModeWrite))
})
@@ -403,10 +442,10 @@ func CommonRoutes() *web.Route {
r.Group("/helm", func() {
r.Get("/index.yaml", helm.Index)
r.Get("/{filename}", helm.DownloadPackageFile)
- r.Post("/api/charts", reqPackageAccess(perm.AccessModeWrite), helm.UploadPackage)
+ r.Post("/api/charts", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), helm.UploadPackage)
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/maven", func() {
- r.Put("/*", reqPackageAccess(perm.AccessModeWrite), maven.UploadPackageFile)
+ r.Put("/*", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), maven.UploadPackageFile)
r.Get("/*", maven.DownloadPackageFile)
r.Head("/*", maven.ProvidePackageFileHeader)
}, reqPackageAccess(perm.AccessModeRead))
@@ -427,8 +466,8 @@ func CommonRoutes() *web.Route {
r.Get("/{version}/{filename}", nuget.DownloadPackageFile)
})
r.Group("", func() {
- r.Put("/", nuget.UploadPackage)
- r.Put("/symbolpackage", nuget.UploadSymbolPackage)
+ r.Put("/", enforcePackagesQuota(), nuget.UploadPackage)
+ r.Put("/symbolpackage", enforcePackagesQuota(), nuget.UploadSymbolPackage)
r.Delete("/{id}/{version}", nuget.DeletePackage)
}, reqPackageAccess(perm.AccessModeWrite))
r.Get("/symbols/{filename}/{guid:[0-9a-fA-F]{32}[fF]{8}}/{filename2}", nuget.DownloadSymbolFile)
@@ -450,7 +489,7 @@ func CommonRoutes() *web.Route {
r.Group("/npm", func() {
r.Group("/@{scope}/{id}", func() {
r.Get("", npm.PackageMetadata)
- r.Put("", reqPackageAccess(perm.AccessModeWrite), npm.UploadPackage)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), npm.UploadPackage)
r.Group("/-/{version}/{filename}", func() {
r.Get("", npm.DownloadPackageFile)
r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion)
@@ -463,7 +502,7 @@ func CommonRoutes() *web.Route {
})
r.Group("/{id}", func() {
r.Get("", npm.PackageMetadata)
- r.Put("", reqPackageAccess(perm.AccessModeWrite), npm.UploadPackage)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), npm.UploadPackage)
r.Group("/-/{version}/{filename}", func() {
r.Get("", npm.DownloadPackageFile)
r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion)
@@ -496,7 +535,7 @@ func CommonRoutes() *web.Route {
r.Group("/api/packages", func() {
r.Group("/versions/new", func() {
r.Get("", pub.RequestUpload)
- r.Post("/upload", pub.UploadPackageFile)
+ r.Post("/upload", enforcePackagesQuota(), pub.UploadPackageFile)
r.Get("/finalize/{id}/{version}", pub.FinalizePackage)
}, reqPackageAccess(perm.AccessModeWrite))
r.Group("/{id}", func() {
@@ -507,7 +546,7 @@ func CommonRoutes() *web.Route {
})
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/pypi", func() {
- r.Post("/", reqPackageAccess(perm.AccessModeWrite), pypi.UploadPackageFile)
+ r.Post("/", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), pypi.UploadPackageFile)
r.Get("/files/{id}/{version}/{filename}", pypi.DownloadPackageFile)
r.Get("/simple/{id}", pypi.PackageMetadata)
}, reqPackageAccess(perm.AccessModeRead))
@@ -556,6 +595,10 @@ func CommonRoutes() *web.Route {
if ctx.Written() {
return
}
+ enforcePackagesQuota()(ctx)
+ if ctx.Written() {
+ return
+ }
ctx.SetParams("group", strings.Trim(m[1], "/"))
rpm.UploadPackageFile(ctx)
return
@@ -582,6 +625,73 @@ func CommonRoutes() *web.Route {
ctx.Status(http.StatusNotFound)
})
}, reqPackageAccess(perm.AccessModeRead))
+ r.Group("/alt", func() {
+ var (
+ baseURLPattern = regexp.MustCompile(`\A(.*?)\.repo\z`)
+ uploadPattern = regexp.MustCompile(`\A(.*?)/upload\z`)
+ baseRepoPattern = regexp.MustCompile(`(\S+)\.repo/(\S+)\/base/(\S+)`)
+ rpmsRepoPattern = regexp.MustCompile(`(\S+)\.repo/(\S+)\.(\S+)\/([a-zA-Z0-9_-]+)-([\d.]+-[a-zA-Z0-9_-]+)\.(\S+)\.rpm`)
+ )
+
+ r.Methods("HEAD,GET,PUT,DELETE", "*", func(ctx *context.Context) {
+ path := ctx.Params("*")
+ isGetHead := ctx.Req.Method == "HEAD" || ctx.Req.Method == "GET"
+ isPut := ctx.Req.Method == "PUT"
+ isDelete := ctx.Req.Method == "DELETE"
+
+ m := baseURLPattern.FindStringSubmatch(path)
+ if len(m) == 2 && isGetHead {
+ ctx.SetParams("group", strings.Trim(m[1], "/"))
+ alt.GetRepositoryConfig(ctx)
+ return
+ }
+
+ m = baseRepoPattern.FindStringSubmatch(path)
+ if len(m) == 4 {
+ if strings.Trim(m[1], "/") != "alt" {
+ ctx.SetParams("group", strings.Trim(m[1], "/"))
+ }
+ ctx.SetParams("filename", m[3])
+ if isGetHead {
+ alt.GetRepositoryFile(ctx, m[2])
+ }
+ return
+ }
+
+ m = uploadPattern.FindStringSubmatch(path)
+ if len(m) == 2 && isPut {
+ reqPackageAccess(perm.AccessModeWrite)(ctx)
+ if ctx.Written() {
+ return
+ }
+ ctx.SetParams("group", strings.Trim(m[1], "/"))
+ alt.UploadPackageFile(ctx)
+ return
+ }
+
+ m = rpmsRepoPattern.FindStringSubmatch(path)
+ if len(m) == 7 && (isGetHead || isDelete) {
+ if strings.Trim(m[1], "/") != "alt" {
+ ctx.SetParams("group", strings.Trim(m[1], "/"))
+ }
+ ctx.SetParams("name", m[4])
+ ctx.SetParams("version", m[5])
+ ctx.SetParams("architecture", m[6])
+ if isGetHead {
+ alt.DownloadPackageFile(ctx)
+ } else {
+ reqPackageAccess(perm.AccessModeWrite)(ctx)
+ if ctx.Written() {
+ return
+ }
+ alt.DeletePackageFile(ctx)
+ }
+ return
+ }
+
+ ctx.Status(http.StatusNotFound)
+ })
+ }, reqPackageAccess(perm.AccessModeRead))
r.Group("/rubygems", func() {
r.Get("/specs.4.8.gz", rubygems.EnumeratePackages)
r.Get("/latest_specs.4.8.gz", rubygems.EnumeratePackagesLatest)
@@ -591,45 +701,51 @@ func CommonRoutes() *web.Route {
r.Get("/quick/Marshal.4.8/{filename}", rubygems.ServePackageSpecification)
r.Get("/gems/{filename}", rubygems.DownloadPackageFile)
r.Group("/api/v1/gems", func() {
- r.Post("/", rubygems.UploadPackageFile)
+ r.Post("/", enforcePackagesQuota(), rubygems.UploadPackageFile)
r.Delete("/yank", rubygems.DeletePackage)
}, reqPackageAccess(perm.AccessModeWrite))
}, reqPackageAccess(perm.AccessModeRead))
r.Group("/swift", func() {
- r.Group("/{scope}/{name}", func() {
- r.Group("", func() {
- r.Get("", swift.EnumeratePackageVersions)
- r.Get(".json", swift.EnumeratePackageVersions)
- }, swift.CheckAcceptMediaType(swift.AcceptJSON))
- r.Group("/{version}", func() {
- r.Get("/Package.swift", swift.CheckAcceptMediaType(swift.AcceptSwift), swift.DownloadManifest)
- r.Put("", reqPackageAccess(perm.AccessModeWrite), swift.CheckAcceptMediaType(swift.AcceptJSON), swift.UploadPackageFile)
- r.Get("", func(ctx *context.Context) {
- // Can't use normal routes here: https://github.com/go-chi/chi/issues/781
+ r.Group("", func() { // Needs to be unauthenticated.
+ r.Post("", swift.CheckAuthenticate)
+ r.Post("/login", swift.CheckAuthenticate)
+ })
+ r.Group("", func() {
+ r.Group("/{scope}/{name}", func() {
+ r.Group("", func() {
+ r.Get("", swift.EnumeratePackageVersions)
+ r.Get(".json", swift.EnumeratePackageVersions)
+ }, swift.CheckAcceptMediaType(swift.AcceptJSON))
+ r.Group("/{version}", func() {
+ r.Get("/Package.swift", swift.CheckAcceptMediaType(swift.AcceptSwift), swift.DownloadManifest)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), swift.CheckAcceptMediaType(swift.AcceptJSON), enforcePackagesQuota(), swift.UploadPackageFile)
+ r.Get("", func(ctx *context.Context) {
+ // Can't use normal routes here: https://github.com/go-chi/chi/issues/781
- version := ctx.Params("version")
- if strings.HasSuffix(version, ".zip") {
- swift.CheckAcceptMediaType(swift.AcceptZip)(ctx)
- if ctx.Written() {
- return
+ version := ctx.Params("version")
+ if strings.HasSuffix(version, ".zip") {
+ swift.CheckAcceptMediaType(swift.AcceptZip)(ctx)
+ if ctx.Written() {
+ return
+ }
+ ctx.SetParams("version", version[:len(version)-4])
+ swift.DownloadPackageFile(ctx)
+ } else {
+ swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx)
+ if ctx.Written() {
+ return
+ }
+ if strings.HasSuffix(version, ".json") {
+ ctx.SetParams("version", version[:len(version)-5])
+ }
+ swift.PackageVersionMetadata(ctx)
}
- ctx.SetParams("version", version[:len(version)-4])
- swift.DownloadPackageFile(ctx)
- } else {
- swift.CheckAcceptMediaType(swift.AcceptJSON)(ctx)
- if ctx.Written() {
- return
- }
- if strings.HasSuffix(version, ".json") {
- ctx.SetParams("version", version[:len(version)-5])
- }
- swift.PackageVersionMetadata(ctx)
- }
+ })
})
})
- })
- r.Get("/identifiers", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.LookupPackageIdentifiers)
- }, reqPackageAccess(perm.AccessModeRead))
+ r.Get("/identifiers", swift.CheckAcceptMediaType(swift.AcceptJSON), swift.LookupPackageIdentifiers)
+ }, reqPackageAccess(perm.AccessModeRead))
+ })
r.Group("/vagrant", func() {
r.Group("/authenticate", func() {
r.Get("", vagrant.CheckAuthenticate)
@@ -639,7 +755,7 @@ func CommonRoutes() *web.Route {
r.Get("", vagrant.EnumeratePackageVersions)
r.Group("/{version}/{provider}", func() {
r.Get("", vagrant.DownloadPackageFile)
- r.Put("", reqPackageAccess(perm.AccessModeWrite), vagrant.UploadPackageFile)
+ r.Put("", reqPackageAccess(perm.AccessModeWrite), enforcePackagesQuota(), vagrant.UploadPackageFile)
})
})
}, reqPackageAccess(perm.AccessModeRead))
diff --git a/routers/api/packages/arch/arch.go b/routers/api/packages/arch/arch.go
new file mode 100644
index 0000000000..a45f38dd08
--- /dev/null
+++ b/routers/api/packages/arch/arch.go
@@ -0,0 +1,296 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package arch
+
+import (
+ "encoding/base64"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "path/filepath"
+ "regexp"
+ "strings"
+
+ packages_model "forgejo.org/models/packages"
+ packages_module "forgejo.org/modules/packages"
+ arch_module "forgejo.org/modules/packages/arch"
+ "forgejo.org/modules/sync"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
+ arch_service "forgejo.org/services/packages/arch"
+)
+
+var (
+ archPkgOrSig = regexp.MustCompile(`^.*\.pkg\.tar\.\w+(\.sig)*$`)
+ archDBOrSig = regexp.MustCompile(`^.*.(db|files)(\.tar\.gz)*(\.sig)*$`)
+
+ locker = sync.NewExclusivePool()
+)
+
+func apiError(ctx *context.Context, status int, obj any) {
+ helper.LogAndProcessError(ctx, status, obj, func(message string) {
+ ctx.PlainText(status, message)
+ })
+}
+
+func refreshLocker(ctx *context.Context, group string) func() {
+ key := fmt.Sprintf("pkg_%d_arch_pkg_%s", ctx.Package.Owner.ID, group)
+ locker.CheckIn(key)
+ return func() {
+ locker.CheckOut(key)
+ }
+}
+
+func GetRepositoryKey(ctx *context.Context) {
+ _, pub, err := arch_service.GetOrCreateKeyPair(ctx, ctx.Package.Owner.ID)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ ctx.ServeContent(strings.NewReader(pub), &context.ServeHeaderOptions{
+ ContentType: "application/pgp-keys",
+ Filename: "repository.key",
+ })
+}
+
+func PushPackage(ctx *context.Context) {
+ group := strings.Trim(ctx.Params("*"), "/")
+ releaser := refreshLocker(ctx, group)
+ defer releaser()
+ upload, needToClose, err := ctx.UploadStream()
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ if needToClose {
+ defer upload.Close()
+ }
+
+ buf, err := packages_module.CreateHashedBufferFromReader(upload)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ defer buf.Close()
+
+ p, err := arch_module.ParsePackage(buf)
+ if err != nil {
+ apiError(ctx, http.StatusBadRequest, err)
+ return
+ }
+
+ _, err = buf.Seek(0, io.SeekStart)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ sign, err := arch_service.NewFileSign(ctx, ctx.Package.Owner.ID, buf)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ defer sign.Close()
+ _, err = buf.Seek(0, io.SeekStart)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ // update gpg sign
+ pgp, err := io.ReadAll(sign)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ p.FileMetadata.PgpSigned = base64.StdEncoding.EncodeToString(pgp)
+ _, err = sign.Seek(0, io.SeekStart)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ properties := map[string]string{
+ arch_module.PropertyDescription: p.Desc(),
+ arch_module.PropertyFiles: p.Files(),
+ arch_module.PropertyArch: p.FileMetadata.Arch,
+ arch_module.PropertyDistribution: group,
+ }
+
+ version, _, err := packages_service.CreatePackageOrAddFileToExisting(
+ ctx,
+ &packages_service.PackageCreationInfo{
+ PackageInfo: packages_service.PackageInfo{
+ Owner: ctx.Package.Owner,
+ PackageType: packages_model.TypeArch,
+ Name: p.Name,
+ Version: p.Version,
+ },
+ Creator: ctx.Doer,
+ Metadata: p.VersionMetadata,
+ },
+ &packages_service.PackageFileCreationInfo{
+ PackageFileInfo: packages_service.PackageFileInfo{
+ Filename: fmt.Sprintf("%s-%s-%s.pkg.tar.%s", p.Name, p.Version, p.FileMetadata.Arch, p.CompressType),
+ CompositeKey: group,
+ },
+ OverwriteExisting: false,
+ IsLead: true,
+ Creator: ctx.ContextUser,
+ Data: buf,
+ Properties: properties,
+ },
+ )
+ if err != nil {
+ switch {
+ case errors.Is(err, packages_model.ErrDuplicatePackageVersion), errors.Is(err, packages_model.ErrDuplicatePackageFile):
+ apiError(ctx, http.StatusConflict, err)
+ case errors.Is(err, packages_service.ErrQuotaTotalCount), errors.Is(err, packages_service.ErrQuotaTypeSize), errors.Is(err, packages_service.ErrQuotaTotalSize):
+ apiError(ctx, http.StatusForbidden, err)
+ default:
+ apiError(ctx, http.StatusInternalServerError, err)
+ }
+ return
+ }
+ // add sign file
+ _, err = packages_service.AddFileToPackageVersionInternal(ctx, version, &packages_service.PackageFileCreationInfo{
+ PackageFileInfo: packages_service.PackageFileInfo{
+ CompositeKey: group,
+ Filename: fmt.Sprintf("%s-%s-%s.pkg.tar.%s.sig", p.Name, p.Version, p.FileMetadata.Arch, p.CompressType),
+ },
+ OverwriteExisting: true,
+ IsLead: false,
+ Creator: ctx.Doer,
+ Data: sign,
+ })
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ if err = arch_service.BuildPacmanDB(ctx, ctx.Package.Owner.ID, group, p.FileMetadata.Arch); err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ if p.FileMetadata.Arch == "any" {
+ if err = arch_service.BuildCustomRepositoryFiles(ctx, ctx.Package.Owner.ID, group); err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ }
+ ctx.Status(http.StatusCreated)
+}
+
+func GetPackageOrDB(ctx *context.Context) {
+ pathGroups := strings.Split(strings.Trim(ctx.Params("*"), "/"), "/")
+ groupLen := len(pathGroups)
+ if groupLen < 2 {
+ ctx.Status(http.StatusNotFound)
+ return
+ }
+ var file, group, arch string
+ if groupLen == 2 {
+ arch = pathGroups[0]
+ file = pathGroups[1]
+ } else {
+ group = strings.Join(pathGroups[:groupLen-2], "/")
+ arch = pathGroups[groupLen-2]
+ file = pathGroups[groupLen-1]
+ }
+ if archPkgOrSig.MatchString(file) {
+ pkg, u, pf, err := arch_service.GetPackageFile(ctx, group, file, ctx.Package.Owner.ID)
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ apiError(ctx, http.StatusNotFound, err)
+ } else {
+ apiError(ctx, http.StatusInternalServerError, err)
+ }
+ return
+ }
+ helper.ServePackageFile(ctx, pkg, u, pf)
+ return
+ }
+
+ if archDBOrSig.MatchString(file) {
+ pkg, u, pf, err := arch_service.GetPackageDBFile(ctx, ctx.Package.Owner.ID, group, arch, strings.HasSuffix(file, ".sig"))
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ apiError(ctx, http.StatusNotFound, err)
+ } else {
+ apiError(ctx, http.StatusInternalServerError, err)
+ }
+ return
+ }
+ helper.ServePackageFile(ctx, pkg, u, pf)
+ return
+ }
+
+ ctx.Status(http.StatusNotFound)
+}
+
+func RemovePackage(ctx *context.Context) {
+ pathGroups := strings.Split(strings.Trim(ctx.Params("*"), "/"), "/")
+ groupLen := len(pathGroups)
+ if groupLen < 3 {
+ ctx.Status(http.StatusBadRequest)
+ return
+ }
+ var group, pkg, ver, pkgArch string
+ if groupLen == 3 {
+ pkg = pathGroups[0]
+ ver = pathGroups[1]
+ pkgArch = pathGroups[2]
+ } else {
+ group = strings.Join(pathGroups[:groupLen-3], "/")
+ pkg = pathGroups[groupLen-3]
+ ver = pathGroups[groupLen-2]
+ pkgArch = pathGroups[groupLen-1]
+ }
+ releaser := refreshLocker(ctx, group)
+ defer releaser()
+ pv, err := packages_model.GetVersionByNameAndVersion(
+ ctx, ctx.Package.Owner.ID, packages_model.TypeArch, pkg, ver,
+ )
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ apiError(ctx, http.StatusNotFound, err)
+ } else {
+ apiError(ctx, http.StatusInternalServerError, err)
+ }
+ return
+ }
+ files, err := packages_model.GetFilesByVersionID(ctx, pv.ID)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ deleted := false
+ for _, file := range files {
+ extName := fmt.Sprintf("-%s.pkg.tar%s", pkgArch, filepath.Ext(file.LowerName))
+ if strings.HasSuffix(file.LowerName, ".sig") {
+ extName = fmt.Sprintf("-%s.pkg.tar%s.sig", pkgArch,
+ filepath.Ext(strings.TrimSuffix(file.LowerName, filepath.Ext(file.LowerName))))
+ }
+ if file.CompositeKey == group &&
+ strings.HasSuffix(file.LowerName, extName) {
+ deleted = true
+ err := packages_service.RemovePackageFileAndVersionIfUnreferenced(ctx, ctx.ContextUser, file)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ }
+ }
+ if deleted {
+ err = arch_service.BuildCustomRepositoryFiles(ctx, ctx.Package.Owner.ID, group)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ ctx.Status(http.StatusNoContent)
+ } else {
+ ctx.Error(http.StatusNotFound)
+ }
+}
diff --git a/routers/api/packages/cargo/cargo.go b/routers/api/packages/cargo/cargo.go
index 140e532efd..50dc8d1c3d 100644
--- a/routers/api/packages/cargo/cargo.go
+++ b/routers/api/packages/cargo/cargo.go
@@ -10,20 +10,20 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- packages_module "code.gitea.io/gitea/modules/packages"
- cargo_module "code.gitea.io/gitea/modules/packages/cargo"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- packages_service "code.gitea.io/gitea/services/packages"
- cargo_service "code.gitea.io/gitea/services/packages/cargo"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ packages_module "forgejo.org/modules/packages"
+ cargo_module "forgejo.org/modules/packages/cargo"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ packages_service "forgejo.org/services/packages"
+ cargo_service "forgejo.org/services/packages/cargo"
)
// https://doc.rust-lang.org/cargo/reference/registries.html#web-api
diff --git a/routers/api/packages/chef/auth.go b/routers/api/packages/chef/auth.go
index a790e9a363..fc552c1f1b 100644
--- a/routers/api/packages/chef/auth.go
+++ b/routers/api/packages/chef/auth.go
@@ -23,10 +23,10 @@ import (
"strings"
"time"
- user_model "code.gitea.io/gitea/models/user"
- chef_module "code.gitea.io/gitea/modules/packages/chef"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/auth"
+ user_model "forgejo.org/models/user"
+ chef_module "forgejo.org/modules/packages/chef"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/auth"
)
const (
diff --git a/routers/api/packages/chef/chef.go b/routers/api/packages/chef/chef.go
index b49f4e9d0a..909817861e 100644
--- a/routers/api/packages/chef/chef.go
+++ b/routers/api/packages/chef/chef.go
@@ -13,16 +13,16 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/optional"
- packages_module "code.gitea.io/gitea/modules/packages"
- chef_module "code.gitea.io/gitea/modules/packages/chef"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/optional"
+ packages_module "forgejo.org/modules/packages"
+ chef_module "forgejo.org/modules/packages/chef"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
)
func apiError(ctx *context.Context, status int, obj any) {
diff --git a/routers/api/packages/composer/api.go b/routers/api/packages/composer/api.go
index a3bcf80417..dc491ea8a8 100644
--- a/routers/api/packages/composer/api.go
+++ b/routers/api/packages/composer/api.go
@@ -8,8 +8,8 @@ import (
"net/url"
"time"
- packages_model "code.gitea.io/gitea/models/packages"
- composer_module "code.gitea.io/gitea/modules/packages/composer"
+ packages_model "forgejo.org/models/packages"
+ composer_module "forgejo.org/modules/packages/composer"
)
// ServiceIndexResponse contains registry endpoints
@@ -66,6 +66,7 @@ type PackageMetadataResponse struct {
}
// PackageVersionMetadata contains package metadata
+// https://getcomposer.org/doc/05-repositories.md#package
type PackageVersionMetadata struct {
*composer_module.Metadata
Name string `json:"name"`
@@ -73,6 +74,7 @@ type PackageVersionMetadata struct {
Type string `json:"type"`
Created time.Time `json:"time"`
Dist Dist `json:"dist"`
+ Source Source `json:"source"`
}
// Dist contains package download information
@@ -82,6 +84,13 @@ type Dist struct {
Checksum string `json:"shasum"`
}
+// Source contains package source information
+type Source struct {
+ URL string `json:"url"`
+ Type string `json:"type"`
+ Reference string `json:"reference"`
+}
+
func createPackageMetadataResponse(registryURL string, pds []*packages_model.PackageDescriptor) *PackageMetadataResponse {
versions := make([]*PackageVersionMetadata, 0, len(pds))
@@ -94,7 +103,7 @@ func createPackageMetadataResponse(registryURL string, pds []*packages_model.Pac
}
}
- versions = append(versions, &PackageVersionMetadata{
+ pkg := PackageVersionMetadata{
Name: pd.Package.Name,
Version: pd.Version.Version,
Type: packageType,
@@ -105,7 +114,16 @@ func createPackageMetadataResponse(registryURL string, pds []*packages_model.Pac
URL: fmt.Sprintf("%s/files/%s/%s/%s", registryURL, url.PathEscape(pd.Package.LowerName), url.PathEscape(pd.Version.LowerVersion), url.PathEscape(pd.Files[0].File.LowerName)),
Checksum: pd.Files[0].Blob.HashSHA1,
},
- })
+ }
+ if pd.Repository != nil {
+ pkg.Source = Source{
+ URL: pd.Repository.HTMLURL(),
+ Type: "git",
+ Reference: pd.Version.Version,
+ }
+ }
+
+ versions = append(versions, &pkg)
}
return &PackageMetadataResponse{
diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go
index a045da40de..9e67d419ec 100644
--- a/routers/api/packages/composer/composer.go
+++ b/routers/api/packages/composer/composer.go
@@ -12,17 +12,17 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/optional"
- packages_module "code.gitea.io/gitea/modules/packages"
- composer_module "code.gitea.io/gitea/modules/packages/composer"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/optional"
+ packages_module "forgejo.org/modules/packages"
+ composer_module "forgejo.org/modules/packages/composer"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ packages_service "forgejo.org/services/packages"
"github.com/hashicorp/go-version"
)
diff --git a/routers/api/packages/conan/auth.go b/routers/api/packages/conan/auth.go
index 521fa12372..1f5af77304 100644
--- a/routers/api/packages/conan/auth.go
+++ b/routers/api/packages/conan/auth.go
@@ -6,10 +6,10 @@ package conan
import (
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/packages"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/packages"
)
var _ auth.Method = &Auth{}
@@ -22,7 +22,7 @@ func (a *Auth) Name() string {
// Verify extracts the user from the Bearer token
func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) {
- uid, err := packages.ParseAuthorizationToken(req)
+ uid, scope, err := packages.ParseAuthorizationToken(req)
if err != nil {
log.Trace("ParseAuthorizationToken: %v", err)
return nil, err
@@ -32,6 +32,12 @@ func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataS
return nil, nil
}
+ // Propagate scope of the authorization token.
+ if scope != "" {
+ store.GetData()["IsApiToken"] = true
+ store.GetData()["ApiTokenScope"] = scope
+ }
+
u, err := user_model.GetUserByID(req.Context(), uid)
if err != nil {
log.Error("GetUserByID: %v", err)
diff --git a/routers/api/packages/conan/conan.go b/routers/api/packages/conan/conan.go
index 07ea3eda34..927d131309 100644
--- a/routers/api/packages/conan/conan.go
+++ b/routers/api/packages/conan/conan.go
@@ -11,19 +11,20 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- conan_model "code.gitea.io/gitea/models/packages/conan"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- conan_module "code.gitea.io/gitea/modules/packages/conan"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- notify_service "code.gitea.io/gitea/services/notify"
- packages_service "code.gitea.io/gitea/services/packages"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ conan_model "forgejo.org/models/packages/conan"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ conan_module "forgejo.org/modules/packages/conan"
+ "forgejo.org/modules/setting"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ notify_service "forgejo.org/services/notify"
+ packages_service "forgejo.org/services/packages"
)
const (
@@ -117,7 +118,10 @@ func Authenticate(ctx *context.Context) {
return
}
- token, err := packages_service.CreateAuthorizationToken(ctx.Doer)
+ // If there's an API scope, ensure it propagates.
+ scope, _ := ctx.Data.GetData()["ApiTokenScope"].(auth_model.AccessTokenScope)
+
+ token, err := packages_service.CreateAuthorizationToken(ctx.Doer, scope)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
diff --git a/routers/api/packages/conan/search.go b/routers/api/packages/conan/search.go
index 7370c702cd..afc94afef5 100644
--- a/routers/api/packages/conan/search.go
+++ b/routers/api/packages/conan/search.go
@@ -7,11 +7,11 @@ import (
"net/http"
"strings"
- conan_model "code.gitea.io/gitea/models/packages/conan"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- conan_module "code.gitea.io/gitea/modules/packages/conan"
- "code.gitea.io/gitea/services/context"
+ conan_model "forgejo.org/models/packages/conan"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/json"
+ conan_module "forgejo.org/modules/packages/conan"
+ "forgejo.org/services/context"
)
// SearchResult contains the found recipe names
diff --git a/routers/api/packages/conda/conda.go b/routers/api/packages/conda/conda.go
index c7e4544d52..52872d2543 100644
--- a/routers/api/packages/conda/conda.go
+++ b/routers/api/packages/conda/conda.go
@@ -10,16 +10,16 @@ import (
"net/http"
"strings"
- packages_model "code.gitea.io/gitea/models/packages"
- conda_model "code.gitea.io/gitea/models/packages/conda"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- conda_module "code.gitea.io/gitea/modules/packages/conda"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ conda_model "forgejo.org/models/packages/conda"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ conda_module "forgejo.org/modules/packages/conda"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
"github.com/dsnet/compress/bzip2"
)
diff --git a/routers/api/packages/container/auth.go b/routers/api/packages/container/auth.go
index 1c7afa95ff..71c237326e 100644
--- a/routers/api/packages/container/auth.go
+++ b/routers/api/packages/container/auth.go
@@ -6,10 +6,10 @@ package container
import (
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/packages"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/packages"
)
var _ auth.Method = &Auth{}
@@ -23,7 +23,7 @@ func (a *Auth) Name() string {
// Verify extracts the user from the Bearer token
// If it's an anonymous session a ghost user is returned
func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) (*user_model.User, error) {
- uid, err := packages.ParseAuthorizationToken(req)
+ uid, scope, err := packages.ParseAuthorizationToken(req)
if err != nil {
log.Trace("ParseAuthorizationToken: %v", err)
return nil, err
@@ -33,6 +33,12 @@ func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataS
return nil, nil
}
+ // Propagate scope of the authorization token.
+ if scope != "" {
+ store.GetData()["IsApiToken"] = true
+ store.GetData()["ApiTokenScope"] = scope
+ }
+
u, err := user_model.GetPossibleUserByID(req.Context(), uid)
if err != nil {
log.Error("GetPossibleUserByID: %v", err)
diff --git a/routers/api/packages/container/blob.go b/routers/api/packages/container/blob.go
index 9e3a47076c..0e07b03c0c 100644
--- a/routers/api/packages/container/blob.go
+++ b/routers/api/packages/container/blob.go
@@ -12,14 +12,14 @@ import (
"strings"
"sync"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- container_model "code.gitea.io/gitea/models/packages/container"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- container_module "code.gitea.io/gitea/modules/packages/container"
- "code.gitea.io/gitea/modules/util"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ container_model "forgejo.org/models/packages/container"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ container_module "forgejo.org/modules/packages/container"
+ "forgejo.org/modules/util"
+ packages_service "forgejo.org/services/packages"
)
var uploadVersionMutex sync.Mutex
@@ -193,7 +193,7 @@ func deleteBlob(ctx context.Context, ownerID int64, image, digest string) error
}
func digestFromHashSummer(h packages_module.HashSummer) string {
- _, _, hashSHA256, _ := h.Sums()
+ _, _, hashSHA256, _, _ := h.Sums()
return "sha256:" + hex.EncodeToString(hashSHA256)
}
diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go
index 2cb16daebc..5276dd5706 100644
--- a/routers/api/packages/container/container.go
+++ b/routers/api/packages/container/container.go
@@ -14,19 +14,20 @@ import (
"strconv"
"strings"
- packages_model "code.gitea.io/gitea/models/packages"
- container_model "code.gitea.io/gitea/models/packages/container"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- container_module "code.gitea.io/gitea/modules/packages/container"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
- container_service "code.gitea.io/gitea/services/packages/container"
+ auth_model "forgejo.org/models/auth"
+ packages_model "forgejo.org/models/packages"
+ container_model "forgejo.org/models/packages/container"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ container_module "forgejo.org/modules/packages/container"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
+ container_service "forgejo.org/services/packages/container"
digest "github.com/opencontainers/go-digest"
)
@@ -154,7 +155,10 @@ func Authenticate(ctx *context.Context) {
u = user_model.NewGhostUser()
}
- token, err := packages_service.CreateAuthorizationToken(u)
+ // If there's an API scope, ensure it propagates.
+ scope, _ := ctx.Data["ApiTokenScope"].(auth_model.AccessTokenScope)
+
+ token, err := packages_service.CreateAuthorizationToken(u, scope)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
@@ -685,7 +689,9 @@ func DeleteManifest(ctx *context.Context) {
}
func serveBlob(ctx *context.Context, pfd *packages_model.PackageFileDescriptor) {
- s, u, _, err := packages_service.GetPackageBlobStream(ctx, pfd.File, pfd.Blob)
+ serveDirectReqParams := make(url.Values)
+ serveDirectReqParams.Set("response-content-type", pfd.Properties.GetByName(container_module.PropertyMediaType))
+ s, u, _, err := packages_service.GetPackageBlobStream(ctx, pfd.File, pfd.Blob, serveDirectReqParams)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
diff --git a/routers/api/packages/container/manifest.go b/routers/api/packages/container/manifest.go
index 4a79a58f51..428e7605a6 100644
--- a/routers/api/packages/container/manifest.go
+++ b/routers/api/packages/container/manifest.go
@@ -11,17 +11,17 @@ import (
"os"
"strings"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- container_model "code.gitea.io/gitea/models/packages/container"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- container_module "code.gitea.io/gitea/modules/packages/container"
- "code.gitea.io/gitea/modules/util"
- notify_service "code.gitea.io/gitea/services/notify"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ container_model "forgejo.org/models/packages/container"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ container_module "forgejo.org/modules/packages/container"
+ "forgejo.org/modules/util"
+ notify_service "forgejo.org/services/notify"
+ packages_service "forgejo.org/services/packages"
digest "github.com/opencontainers/go-digest"
oci "github.com/opencontainers/image-spec/specs-go/v1"
diff --git a/routers/api/packages/cran/cran.go b/routers/api/packages/cran/cran.go
index f1d616724a..f73111278f 100644
--- a/routers/api/packages/cran/cran.go
+++ b/routers/api/packages/cran/cran.go
@@ -11,14 +11,14 @@ import (
"net/http"
"strings"
- packages_model "code.gitea.io/gitea/models/packages"
- cran_model "code.gitea.io/gitea/models/packages/cran"
- packages_module "code.gitea.io/gitea/modules/packages"
- cran_module "code.gitea.io/gitea/modules/packages/cran"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ cran_model "forgejo.org/models/packages/cran"
+ packages_module "forgejo.org/modules/packages"
+ cran_module "forgejo.org/modules/packages/cran"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
)
func apiError(ctx *context.Context, status int, obj any) {
diff --git a/routers/api/packages/debian/debian.go b/routers/api/packages/debian/debian.go
index 8c05476cbc..fd64e35657 100644
--- a/routers/api/packages/debian/debian.go
+++ b/routers/api/packages/debian/debian.go
@@ -11,16 +11,16 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- packages_module "code.gitea.io/gitea/modules/packages"
- debian_module "code.gitea.io/gitea/modules/packages/debian"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- notify_service "code.gitea.io/gitea/services/notify"
- packages_service "code.gitea.io/gitea/services/packages"
- debian_service "code.gitea.io/gitea/services/packages/debian"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ packages_module "forgejo.org/modules/packages"
+ debian_module "forgejo.org/modules/packages/debian"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ notify_service "forgejo.org/services/notify"
+ packages_service "forgejo.org/services/packages"
+ debian_service "forgejo.org/services/packages/debian"
)
func apiError(ctx *context.Context, status int, obj any) {
diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go
index e66f3ee676..6e116e050d 100644
--- a/routers/api/packages/generic/generic.go
+++ b/routers/api/packages/generic/generic.go
@@ -10,12 +10,12 @@ import (
"strings"
"unicode"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
)
var (
diff --git a/routers/api/packages/goproxy/goproxy.go b/routers/api/packages/goproxy/goproxy.go
index 56a07dbd43..488850ecbf 100644
--- a/routers/api/packages/goproxy/goproxy.go
+++ b/routers/api/packages/goproxy/goproxy.go
@@ -11,14 +11,14 @@ import (
"sort"
"time"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/optional"
- packages_module "code.gitea.io/gitea/modules/packages"
- goproxy_module "code.gitea.io/gitea/modules/packages/goproxy"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/optional"
+ packages_module "forgejo.org/modules/packages"
+ goproxy_module "forgejo.org/modules/packages/goproxy"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
)
func apiError(ctx *context.Context, status int, obj any) {
diff --git a/routers/api/packages/helm/helm.go b/routers/api/packages/helm/helm.go
index efdb83ec0e..1d8efb8d68 100644
--- a/routers/api/packages/helm/helm.go
+++ b/routers/api/packages/helm/helm.go
@@ -12,17 +12,17 @@ import (
"strings"
"time"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- packages_module "code.gitea.io/gitea/modules/packages"
- helm_module "code.gitea.io/gitea/modules/packages/helm"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ packages_module "forgejo.org/modules/packages"
+ helm_module "forgejo.org/modules/packages/helm"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
"gopkg.in/yaml.v3"
)
diff --git a/routers/api/packages/helper/helper.go b/routers/api/packages/helper/helper.go
index cdb64109ad..99c0867bbb 100644
--- a/routers/api/packages/helper/helper.go
+++ b/routers/api/packages/helper/helper.go
@@ -9,10 +9,10 @@ import (
"net/http"
"net/url"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
// LogAndProcessError logs an error and calls a custom callback with the processed error message.
diff --git a/routers/api/packages/maven/api.go b/routers/api/packages/maven/api.go
index 167fe42b56..21d2aaa100 100644
--- a/routers/api/packages/maven/api.go
+++ b/routers/api/packages/maven/api.go
@@ -7,8 +7,8 @@ import (
"encoding/xml"
"strings"
- packages_model "code.gitea.io/gitea/models/packages"
- maven_module "code.gitea.io/gitea/modules/packages/maven"
+ packages_model "forgejo.org/models/packages"
+ maven_module "forgejo.org/modules/packages/maven"
)
// MetadataResponse https://maven.apache.org/ref/3.2.5/maven-repository-metadata/repository-metadata.html
diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go
index 58271e1d43..ea04a7b42e 100644
--- a/routers/api/packages/maven/maven.go
+++ b/routers/api/packages/maven/maven.go
@@ -19,14 +19,15 @@ import (
"strconv"
"strings"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- maven_module "code.gitea.io/gitea/modules/packages/maven"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ maven_module "forgejo.org/modules/packages/maven"
+ "forgejo.org/modules/sync"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
)
const (
@@ -117,7 +118,9 @@ func serveMavenMetadata(ctx *context.Context, params parameters) {
xmlMetadataWithHeader := append([]byte(xml.Header), xmlMetadata...)
latest := pds[len(pds)-1]
- ctx.Resp.Header().Set("Last-Modified", latest.Version.CreatedUnix.Format(http.TimeFormat))
+ // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat
+ lastModifed := latest.Version.CreatedUnix.AsTime().UTC().Format(http.TimeFormat)
+ ctx.Resp.Header().Set("Last-Modified", lastModifed)
ext := strings.ToLower(filepath.Ext(params.Filename))
if isChecksumExtension(ext) {
@@ -215,7 +218,7 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool
return
}
- s, u, _, err := packages_service.GetPackageBlobStream(ctx, pf, pb)
+ s, u, _, err := packages_service.GetPackageBlobStream(ctx, pf, pb, nil)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
return
@@ -226,6 +229,8 @@ func servePackageFile(ctx *context.Context, params parameters, serveContent bool
helper.ServePackageFile(ctx, s, u, pf, opts)
}
+var mavenUploadLock = sync.NewExclusivePool()
+
// UploadPackageFile adds a file to the package. If the package does not exist, it gets created.
func UploadPackageFile(ctx *context.Context) {
params, err := extractPathParameters(ctx)
@@ -244,6 +249,9 @@ func UploadPackageFile(ctx *context.Context) {
packageName := params.GroupID + "-" + params.ArtifactID
+ mavenUploadLock.CheckIn(packageName)
+ defer mavenUploadLock.CheckOut(packageName)
+
buf, err := packages_module.CreateHashedBufferFromReader(ctx.Req.Body)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
diff --git a/routers/api/packages/npm/api.go b/routers/api/packages/npm/api.go
index b4379f3f49..e610c29b4d 100644
--- a/routers/api/packages/npm/api.go
+++ b/routers/api/packages/npm/api.go
@@ -10,9 +10,9 @@ import (
"net/url"
"sort"
- packages_model "code.gitea.io/gitea/models/packages"
- npm_module "code.gitea.io/gitea/modules/packages/npm"
- "code.gitea.io/gitea/modules/setting"
+ packages_model "forgejo.org/models/packages"
+ npm_module "forgejo.org/modules/packages/npm"
+ "forgejo.org/modules/setting"
)
func createPackageMetadataResponse(registryURL string, pds []*packages_model.PackageDescriptor) *npm_module.PackageMetadata {
diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go
index 84acfffae2..bf9d247b30 100644
--- a/routers/api/packages/npm/npm.go
+++ b/routers/api/packages/npm/npm.go
@@ -12,19 +12,19 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/optional"
- packages_module "code.gitea.io/gitea/modules/packages"
- npm_module "code.gitea.io/gitea/modules/packages/npm"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/optional"
+ packages_module "forgejo.org/modules/packages"
+ npm_module "forgejo.org/modules/packages/npm"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
"github.com/hashicorp/go-version"
)
diff --git a/routers/api/packages/nuget/api_v2.go b/routers/api/packages/nuget/api_v2.go
index a726065ad0..13c93316d5 100644
--- a/routers/api/packages/nuget/api_v2.go
+++ b/routers/api/packages/nuget/api_v2.go
@@ -8,8 +8,8 @@ import (
"strings"
"time"
- packages_model "code.gitea.io/gitea/models/packages"
- nuget_module "code.gitea.io/gitea/modules/packages/nuget"
+ packages_model "forgejo.org/models/packages"
+ nuget_module "forgejo.org/modules/packages/nuget"
)
type AtomTitle struct {
@@ -249,6 +249,9 @@ type FeedEntryProperties struct {
Version string `xml:"d:Version"`
NormalizedVersion string `xml:"d:NormalizedVersion"`
Authors string `xml:"d:Authors"`
+ Owners string `xml:"d:Owners,omitempty"`
+ Copyright string `xml:"d:Copyright,omitempty"`
+ Language string `xml:"d:Language,omitempty"`
Dependencies string `xml:"d:Dependencies"`
Description string `xml:"d:Description"`
VersionDownloadCount TypedValue[int64] `xml:"d:VersionDownloadCount"`
@@ -258,9 +261,15 @@ type FeedEntryProperties struct {
LastUpdated TypedValue[time.Time] `xml:"d:LastUpdated"`
Published TypedValue[time.Time] `xml:"d:Published"`
ProjectURL string `xml:"d:ProjectUrl,omitempty"`
+ LicenseURL string `xml:"d:LicenseUrl,omitempty"`
+ IconURL string `xml:"d:IconUrl,omitempty"`
ReleaseNotes string `xml:"d:ReleaseNotes,omitempty"`
RequireLicenseAcceptance TypedValue[bool] `xml:"d:RequireLicenseAcceptance"`
- Title string `xml:"d:Title"`
+ DevelopmentDependency TypedValue[bool] `xml:"d:DevelopmentDependency"`
+ Title string `xml:"d:Title,omitempty"`
+ MinClientVersion string `xml:"d:MinClientVersion,omitempty"`
+ Tags string `xml:"d:Tags,omitempty"`
+ ID string `xml:"d:Id,omitempty"`
}
type FeedEntry struct {
@@ -356,6 +365,9 @@ func createEntry(l *linkBuilder, pd *packages_model.PackageDescriptor, withNames
Version: pd.Version.Version,
NormalizedVersion: pd.Version.Version,
Authors: metadata.Authors,
+ Owners: metadata.Owners,
+ Copyright: metadata.Copyright,
+ Language: metadata.Language,
Dependencies: buildDependencyString(metadata),
Description: metadata.Description,
VersionDownloadCount: TypedValue[int64]{Type: "Edm.Int64", Value: pd.Version.DownloadCount},
@@ -365,9 +377,15 @@ func createEntry(l *linkBuilder, pd *packages_model.PackageDescriptor, withNames
LastUpdated: createdValue,
Published: createdValue,
ProjectURL: metadata.ProjectURL,
+ LicenseURL: metadata.LicenseURL,
+ IconURL: metadata.IconURL,
ReleaseNotes: metadata.ReleaseNotes,
RequireLicenseAcceptance: TypedValue[bool]{Type: "Edm.Boolean", Value: metadata.RequireLicenseAcceptance},
- Title: pd.Package.Name,
+ DevelopmentDependency: TypedValue[bool]{Type: "Edm.Boolean", Value: metadata.DevelopmentDependency},
+ Title: metadata.Title,
+ MinClientVersion: metadata.MinClientVersion,
+ Tags: metadata.Tags,
+ ID: pd.Package.Name,
},
}
diff --git a/routers/api/packages/nuget/api_v3.go b/routers/api/packages/nuget/api_v3.go
index 2fe25dc0f8..f1f5300523 100644
--- a/routers/api/packages/nuget/api_v3.go
+++ b/routers/api/packages/nuget/api_v3.go
@@ -7,8 +7,8 @@ import (
"sort"
"time"
- packages_model "code.gitea.io/gitea/models/packages"
- nuget_module "code.gitea.io/gitea/modules/packages/nuget"
+ packages_model "forgejo.org/models/packages"
+ nuget_module "forgejo.org/modules/packages/nuget"
"golang.org/x/text/collate"
"golang.org/x/text/language"
diff --git a/routers/api/packages/nuget/auth.go b/routers/api/packages/nuget/auth.go
index 1bb68d059b..bab08bb1b8 100644
--- a/routers/api/packages/nuget/auth.go
+++ b/routers/api/packages/nuget/auth.go
@@ -6,11 +6,11 @@ package nuget
import (
"net/http"
- auth_model "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/services/auth"
+ auth_model "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/services/auth"
)
var _ auth.Method = &Auth{}
diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go
index 0d7212d7f7..254f4311c1 100644
--- a/routers/api/packages/nuget/nuget.go
+++ b/routers/api/packages/nuget/nuget.go
@@ -14,18 +14,18 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- nuget_model "code.gitea.io/gitea/models/packages/nuget"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- packages_module "code.gitea.io/gitea/modules/packages"
- nuget_module "code.gitea.io/gitea/modules/packages/nuget"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ nuget_model "forgejo.org/models/packages/nuget"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ packages_module "forgejo.org/modules/packages"
+ nuget_module "forgejo.org/modules/packages/nuget"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
)
func apiError(ctx *context.Context, status int, obj any) {
diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go
index f87df52a29..1a1343083f 100644
--- a/routers/api/packages/pub/pub.go
+++ b/routers/api/packages/pub/pub.go
@@ -13,16 +13,16 @@ import (
"strings"
"time"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- pub_module "code.gitea.io/gitea/modules/packages/pub"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ pub_module "forgejo.org/modules/packages/pub"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
)
func jsonResponse(ctx *context.Context, status int, obj any) {
diff --git a/routers/api/packages/pypi/pypi.go b/routers/api/packages/pypi/pypi.go
index 7824db1823..360632570e 100644
--- a/routers/api/packages/pypi/pypi.go
+++ b/routers/api/packages/pypi/pypi.go
@@ -10,15 +10,16 @@ import (
"regexp"
"sort"
"strings"
+ "unicode"
- packages_model "code.gitea.io/gitea/models/packages"
- packages_module "code.gitea.io/gitea/modules/packages"
- pypi_module "code.gitea.io/gitea/modules/packages/pypi"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/validation"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ packages_module "forgejo.org/modules/packages"
+ pypi_module "forgejo.org/modules/packages/pypi"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/validation"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
)
// https://peps.python.org/pep-0426/#name
@@ -120,7 +121,7 @@ func UploadPackageFile(ctx *context.Context) {
}
defer buf.Close()
- _, _, hashSHA256, _ := buf.Sums()
+ _, _, hashSHA256, _, _ := buf.Sums()
if !strings.EqualFold(ctx.Req.FormValue("sha256_digest"), hex.EncodeToString(hashSHA256)) {
apiError(ctx, http.StatusBadRequest, "hash mismatch")
@@ -139,9 +140,30 @@ func UploadPackageFile(ctx *context.Context) {
return
}
- projectURL := ctx.Req.FormValue("home_page")
- if !validation.IsValidURL(projectURL) {
- projectURL = ""
+ // Ensure ctx.Req.Form exists.
+ _ = ctx.Req.ParseForm()
+
+ var homepageURL string
+ projectURLs := ctx.Req.Form["project_urls"]
+ for _, purl := range projectURLs {
+ label, url, found := strings.Cut(purl, ",")
+ if !found {
+ continue
+ }
+ if normalizeLabel(label) != "homepage" {
+ continue
+ }
+ homepageURL = strings.TrimSpace(url)
+ break
+ }
+
+ if len(homepageURL) == 0 {
+ // TODO: Home-page is a deprecated metadata field. Remove this branch once it's no longer apart of the spec.
+ homepageURL = ctx.Req.FormValue("home_page")
+ }
+
+ if !validation.IsValidURL(homepageURL) {
+ homepageURL = ""
}
_, _, err = packages_service.CreatePackageOrAddFileToExisting(
@@ -160,7 +182,7 @@ func UploadPackageFile(ctx *context.Context) {
Description: ctx.Req.FormValue("description"),
LongDescription: ctx.Req.FormValue("long_description"),
Summary: ctx.Req.FormValue("summary"),
- ProjectURL: projectURL,
+ ProjectURL: homepageURL,
License: ctx.Req.FormValue("license"),
RequiresPython: ctx.Req.FormValue("requires_python"),
},
@@ -189,6 +211,23 @@ func UploadPackageFile(ctx *context.Context) {
ctx.Status(http.StatusCreated)
}
+// Normalizes a Project-URL label.
+// See https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization.
+func normalizeLabel(label string) string {
+ var builder strings.Builder
+
+ // "A label is normalized by deleting all ASCII punctuation and whitespace, and then converting the result
+ // to lowercase."
+ for _, r := range label {
+ if unicode.IsPunct(r) || unicode.IsSpace(r) {
+ continue
+ }
+ builder.WriteRune(unicode.ToLower(r))
+ }
+
+ return builder.String()
+}
+
func isValidNameAndVersion(packageName, packageVersion string) bool {
return nameMatcher.MatchString(packageName) && versionMatcher.MatchString(packageVersion)
}
diff --git a/routers/api/packages/pypi/pypi_test.go b/routers/api/packages/pypi/pypi_test.go
index 3023692177..786105693f 100644
--- a/routers/api/packages/pypi/pypi_test.go
+++ b/routers/api/packages/pypi/pypi_test.go
@@ -36,3 +36,13 @@ func TestIsValidNameAndVersion(t *testing.T) {
assert.False(t, isValidNameAndVersion("test-name", "1.0.1aa"))
assert.False(t, isValidNameAndVersion("test-name", "1.0.0-alpha.beta"))
}
+
+func TestNormalizeLabel(t *testing.T) {
+ // Cases fetched from https://packaging.python.org/en/latest/specifications/well-known-project-urls/#label-normalization.
+ assert.Equal(t, "homepage", normalizeLabel("Homepage"))
+ assert.Equal(t, "homepage", normalizeLabel("Home-page"))
+ assert.Equal(t, "homepage", normalizeLabel("Home page"))
+ assert.Equal(t, "changelog", normalizeLabel("Change_Log"))
+ assert.Equal(t, "whatsnew", normalizeLabel("What's New?"))
+ assert.Equal(t, "github", normalizeLabel("github"))
+}
diff --git a/routers/api/packages/rpm/rpm.go b/routers/api/packages/rpm/rpm.go
index c59366992c..cdbf893183 100644
--- a/routers/api/packages/rpm/rpm.go
+++ b/routers/api/packages/rpm/rpm.go
@@ -11,18 +11,18 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/json"
- packages_module "code.gitea.io/gitea/modules/packages"
- rpm_module "code.gitea.io/gitea/modules/packages/rpm"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- notify_service "code.gitea.io/gitea/services/notify"
- packages_service "code.gitea.io/gitea/services/packages"
- rpm_service "code.gitea.io/gitea/services/packages/rpm"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/json"
+ packages_module "forgejo.org/modules/packages"
+ rpm_module "forgejo.org/modules/packages/rpm"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ notify_service "forgejo.org/services/notify"
+ packages_service "forgejo.org/services/packages"
+ rpm_service "forgejo.org/services/packages/rpm"
)
func apiError(ctx *context.Context, status int, obj any) {
@@ -132,8 +132,24 @@ func UploadPackageFile(ctx *context.Context) {
return
}
defer buf.Close()
+ // if rpm sign enabled
+ if setting.Packages.DefaultRPMSignEnabled || ctx.FormBool("sign") {
+ pri, _, err := rpm_service.GetOrCreateKeyPair(ctx, ctx.Package.Owner.ID)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ signedBuf, err := rpm_service.NewSignedRPMBuffer(buf, pri)
+ if err != nil {
+ // Not in rpm format, parsing failed.
+ apiError(ctx, http.StatusBadRequest, err)
+ return
+ }
+ defer signedBuf.Close()
+ buf = signedBuf
+ }
- pck, err := rpm_module.ParsePackage(buf)
+ pck, err := rpm_module.ParsePackage(buf, "rpm")
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
apiError(ctx, http.StatusBadRequest, err)
diff --git a/routers/api/packages/rubygems/rubygems.go b/routers/api/packages/rubygems/rubygems.go
index dfefe2c4fb..eed19467ff 100644
--- a/routers/api/packages/rubygems/rubygems.go
+++ b/routers/api/packages/rubygems/rubygems.go
@@ -13,14 +13,14 @@ import (
"net/http"
"strings"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/optional"
- packages_module "code.gitea.io/gitea/modules/packages"
- rubygems_module "code.gitea.io/gitea/modules/packages/rubygems"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/optional"
+ packages_module "forgejo.org/modules/packages"
+ rubygems_module "forgejo.org/modules/packages/rubygems"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
)
const (
@@ -105,9 +105,11 @@ func ServePackageInfo(ctx *context.Context) {
ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems, packageName)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
+ return
}
if len(versions) == 0 {
apiError(ctx, http.StatusNotFound, fmt.Sprintf("Could not find package %s", packageName))
+ return
}
result, err := buildInfoFileForPackage(ctx, versions)
@@ -135,6 +137,7 @@ func ServeVersionsFile(ctx *context.Context) {
ctx, ctx.Package.Owner.ID, packages_model.TypeRubyGems, pack.Name)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
+ return
}
if len(versions) == 0 {
// No versions left for this package, we should continue.
@@ -144,6 +147,20 @@ func ServeVersionsFile(ctx *context.Context) {
fmt.Fprintf(result, "%s ", pack.Name)
for i, v := range versions {
result.WriteString(v.Version)
+
+ pd, err := packages_model.GetPackageDescriptor(ctx, v)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ metadata := pd.Metadata.(*rubygems_module.Metadata)
+
+ if metadata.Platform != "ruby" {
+ result.WriteString("_")
+ result.WriteString(metadata.Platform)
+ }
+
if i != len(versions)-1 {
result.WriteString(",")
}
@@ -152,6 +169,7 @@ func ServeVersionsFile(ctx *context.Context) {
info, err := buildInfoFileForPackage(ctx, versions)
if err != nil {
apiError(ctx, http.StatusInternalServerError, err)
+ return
}
checksum := md5.Sum([]byte(*info))
@@ -413,6 +431,11 @@ func buildRequirementStringFromVersion(ctx *context.Context, version *packages_m
additionalRequirements.WriteString(",rubygems:")
writeRequirements(metadata.RequiredRubygemsVersion, additionalRequirements)
}
+
+ if metadata.Platform != "ruby" {
+ return fmt.Sprintf("%s-%s %s|%s", version.Version, metadata.Platform, dependencyRequirements, additionalRequirements), nil
+ }
+
return fmt.Sprintf("%s %s|%s", version.Version, dependencyRequirements, additionalRequirements), nil
}
diff --git a/routers/api/packages/swift/swift.go b/routers/api/packages/swift/swift.go
index a9da3ea9c2..304230a85e 100644
--- a/routers/api/packages/swift/swift.go
+++ b/routers/api/packages/swift/swift.go
@@ -12,22 +12,22 @@ import (
"sort"
"strings"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- packages_module "code.gitea.io/gitea/modules/packages"
- swift_module "code.gitea.io/gitea/modules/packages/swift"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ packages_module "forgejo.org/modules/packages"
+ swift_module "forgejo.org/modules/packages/swift"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
"github.com/hashicorp/go-version"
)
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning
const (
AcceptJSON = "application/vnd.swift.registry.v1+json"
AcceptSwift = "application/vnd.swift.registry.v1+swift"
@@ -35,9 +35,9 @@ const (
)
var (
- // https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#361-package-scope
+ // https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#361-package-scope
scopePattern = regexp.MustCompile(`\A[a-zA-Z0-9][a-zA-Z0-9-]{0,38}\z`)
- // https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#362-package-name
+ // https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#362-package-name
namePattern = regexp.MustCompile(`\A[a-zA-Z0-9][a-zA-Z0-9-_]{0,99}\z`)
)
@@ -49,7 +49,7 @@ type headers struct {
Link string
}
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning
func setResponseHeaders(resp http.ResponseWriter, h *headers) {
if h.ContentType != "" {
resp.Header().Set("Content-Type", h.ContentType)
@@ -69,7 +69,7 @@ func setResponseHeaders(resp http.ResponseWriter, h *headers) {
}
}
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#33-error-handling
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#33-error-handling
func apiError(ctx *context.Context, status int, obj any) {
// https://www.rfc-editor.org/rfc/rfc7807
type Problem struct {
@@ -91,7 +91,7 @@ func apiError(ctx *context.Context, status int, obj any) {
})
}
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#35-api-versioning
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#35-api-versioning
func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context) {
return func(ctx *context.Context) {
accept := ctx.Req.Header.Get("Accept")
@@ -101,6 +101,16 @@ func CheckAcceptMediaType(requiredAcceptHeader string) func(ctx *context.Context
}
}
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/PackageRegistryUsage.md#registry-authentication
+func CheckAuthenticate(ctx *context.Context) {
+ if ctx.Doer == nil {
+ apiError(ctx, http.StatusUnauthorized, nil)
+ return
+ }
+
+ ctx.Status(http.StatusOK)
+}
+
func buildPackageID(scope, name string) string {
return scope + "." + name
}
@@ -113,7 +123,7 @@ type EnumeratePackageVersionsResponse struct {
Releases map[string]Release `json:"releases"`
}
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#41-list-package-releases
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#41-list-package-releases
func EnumeratePackageVersions(ctx *context.Context) {
packageScope := ctx.Params("scope")
packageName := ctx.Params("name")
@@ -170,7 +180,7 @@ type PackageVersionMetadataResponse struct {
Metadata *swift_module.SoftwareSourceCode `json:"metadata"`
}
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-2
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-2
func PackageVersionMetadata(ctx *context.Context) {
id := buildPackageID(ctx.Params("scope"), ctx.Params("name"))
@@ -228,7 +238,7 @@ func PackageVersionMetadata(ctx *context.Context) {
})
}
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#43-fetch-manifest-for-a-package-release
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#43-fetch-manifest-for-a-package-release
func DownloadManifest(ctx *context.Context) {
packageScope := ctx.Params("scope")
packageName := ctx.Params("name")
@@ -280,7 +290,7 @@ func DownloadManifest(ctx *context.Context) {
})
}
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-6
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-6
func UploadPackageFile(ctx *context.Context) {
packageScope := ctx.Params("scope")
packageName := ctx.Params("name")
@@ -379,7 +389,7 @@ func UploadPackageFile(ctx *context.Context) {
ctx.Status(http.StatusCreated)
}
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-4
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-4
func DownloadPackageFile(ctx *context.Context) {
pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeSwift, buildPackageID(ctx.Params("scope"), ctx.Params("name")), ctx.Params("version"))
if err != nil {
@@ -420,7 +430,7 @@ type LookupPackageIdentifiersResponse struct {
Identifiers []string `json:"identifiers"`
}
-// https://github.com/apple/swift-package-manager/blob/main/Documentation/Registry.md#endpoint-5
+// https://github.com/swiftlang/swift-package-manager/blob/main/Documentation/PackageRegistry/Registry.md#endpoint-5
func LookupPackageIdentifiers(ctx *context.Context) {
url := ctx.FormTrim("url")
if url == "" {
diff --git a/routers/api/packages/vagrant/vagrant.go b/routers/api/packages/vagrant/vagrant.go
index 98a81da368..26131c2cf2 100644
--- a/routers/api/packages/vagrant/vagrant.go
+++ b/routers/api/packages/vagrant/vagrant.go
@@ -11,13 +11,13 @@ import (
"sort"
"strings"
- packages_model "code.gitea.io/gitea/models/packages"
- packages_module "code.gitea.io/gitea/modules/packages"
- vagrant_module "code.gitea.io/gitea/modules/packages/vagrant"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/routers/api/packages/helper"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
+ packages_model "forgejo.org/models/packages"
+ packages_module "forgejo.org/modules/packages"
+ vagrant_module "forgejo.org/modules/packages/vagrant"
+ "forgejo.org/modules/setting"
+ "forgejo.org/routers/api/packages/helper"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
"github.com/hashicorp/go-version"
)
diff --git a/routers/api/shared/middleware.go b/routers/api/shared/middleware.go
index e2ff004024..f56acbe1bf 100644
--- a/routers/api/shared/middleware.go
+++ b/routers/api/shared/middleware.go
@@ -6,13 +6,11 @@ package shared
import (
"net/http"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/context"
"github.com/go-chi/cors"
)
@@ -51,10 +49,6 @@ func buildAuthGroup() *auth.Group {
group.Add(&auth.ReverseProxy{})
}
- if setting.IsWindows && auth_model.IsSSPIEnabled(db.DefaultContext) {
- group.Add(&auth.SSPI{}) // it MUST be the last, see the comment of SSPI
- }
-
return group
}
diff --git a/routers/api/v1/activitypub/actor.go b/routers/api/v1/activitypub/actor.go
new file mode 100644
index 0000000000..7568a2a7c8
--- /dev/null
+++ b/routers/api/v1/activitypub/actor.go
@@ -0,0 +1,83 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package activitypub
+
+import (
+ "net/http"
+
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/activitypub"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+
+ ap "github.com/go-ap/activitypub"
+ "github.com/go-ap/jsonld"
+)
+
+// Actor function returns the instance's Actor
+func Actor(ctx *context.APIContext) {
+ // swagger:operation GET /activitypub/actor activitypub activitypubInstanceActor
+ // ---
+ // summary: Returns the instance's Actor
+ // produces:
+ // - application/json
+ // responses:
+ // "200":
+ // "$ref": "#/responses/ActivityPub"
+
+ link := user_model.APActorUserAPActorID()
+ actor := ap.ActorNew(ap.IRI(link), ap.ApplicationType)
+
+ actor.PreferredUsername = ap.NaturalLanguageValuesNew()
+ err := actor.PreferredUsername.Set("en", ap.Content(setting.Domain))
+ if err != nil {
+ ctx.ServerError("PreferredUsername.Set", err)
+ return
+ }
+
+ actor.URL = ap.IRI(setting.AppURL)
+
+ actor.Inbox = ap.IRI(link + "/inbox")
+ actor.Outbox = ap.IRI(link + "/outbox")
+
+ actor.PublicKey.ID = ap.IRI(link + "#main-key")
+ actor.PublicKey.Owner = ap.IRI(link)
+
+ publicKeyPem, err := activitypub.GetPublicKey(ctx, user_model.NewAPActorUser())
+ if err != nil {
+ ctx.ServerError("GetPublicKey", err)
+ return
+ }
+ actor.PublicKey.PublicKeyPem = publicKeyPem
+
+ binary, err := jsonld.WithContext(
+ jsonld.IRI(ap.ActivityBaseURI),
+ jsonld.IRI(ap.SecurityContextURI),
+ ).Marshal(actor)
+ if err != nil {
+ ctx.ServerError("MarshalJSON", err)
+ return
+ }
+ ctx.Resp.Header().Add("Content-Type", activitypub.ActivityStreamsContentType)
+ ctx.Resp.WriteHeader(http.StatusOK)
+ if _, err = ctx.Resp.Write(binary); err != nil {
+ log.Error("write to resp err: %v", err)
+ }
+}
+
+// ActorInbox function handles the incoming data for the instance Actor
+func ActorInbox(ctx *context.APIContext) {
+ // swagger:operation POST /activitypub/actor/inbox activitypub activitypubInstanceActorInbox
+ // ---
+ // summary: Send to the inbox
+ // produces:
+ // - application/json
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+
+ ctx.Status(http.StatusNoContent)
+}
diff --git a/routers/api/v1/activitypub/person.go b/routers/api/v1/activitypub/person.go
index 995a148f0b..1da7933418 100644
--- a/routers/api/v1/activitypub/person.go
+++ b/routers/api/v1/activitypub/person.go
@@ -8,10 +8,10 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/modules/activitypub"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/activitypub"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
ap "github.com/go-ap/activitypub"
"github.com/go-ap/jsonld"
diff --git a/routers/api/v1/activitypub/repository.go b/routers/api/v1/activitypub/repository.go
index bc6e7905a6..c506840f1c 100644
--- a/routers/api/v1/activitypub/repository.go
+++ b/routers/api/v1/activitypub/repository.go
@@ -8,12 +8,12 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/modules/forgefed"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/federation"
+ "forgejo.org/modules/forgefed"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/federation"
ap "github.com/go-ap/activitypub"
)
@@ -70,8 +70,8 @@ func RepositoryInbox(ctx *context.APIContext) {
repository := ctx.Repo.Repository
log.Info("RepositoryInbox: repo: %v", repository)
-
form := web.GetForm(ctx)
+ // TODO: Decide between like/undo{like} activity
httpStatus, title, err := federation.ProcessLikeActivity(ctx, form, repository.ID)
if err != nil {
ctx.Error(httpStatus, title, err)
diff --git a/routers/api/v1/activitypub/repository_test.go b/routers/api/v1/activitypub/repository_test.go
index acd588d99b..8d448a4356 100644
--- a/routers/api/v1/activitypub/repository_test.go
+++ b/routers/api/v1/activitypub/repository_test.go
@@ -6,22 +6,22 @@ package activitypub
import (
"testing"
- "code.gitea.io/gitea/models/user"
+ "forgejo.org/modules/validation"
)
func Test_UserEmailValidate(t *testing.T) {
sut := "ab@cd.ef"
- if err := user.ValidateEmail(sut); err != nil {
+ if err := validation.ValidateEmail(sut); err != nil {
t.Errorf("sut should be valid, %v, %v", sut, err)
}
sut = "83ce13c8-af0b-4112-8327-55a54e54e664@code.cartoon-aa.xyz"
- if err := user.ValidateEmail(sut); err != nil {
+ if err := validation.ValidateEmail(sut); err != nil {
t.Errorf("sut should be valid, %v, %v", sut, err)
}
sut = "1"
- if err := user.ValidateEmail(sut); err == nil {
+ if err := validation.ValidateEmail(sut); err == nil {
t.Errorf("sut should not be valid, %v", sut)
}
}
diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go
index 6003f664a0..a9bb4bd868 100644
--- a/routers/api/v1/activitypub/reqsignature.go
+++ b/routers/api/v1/activitypub/reqsignature.go
@@ -12,14 +12,14 @@ import (
"net/http"
"net/url"
- "code.gitea.io/gitea/modules/activitypub"
- "code.gitea.io/gitea/modules/httplib"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- gitea_context "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/activitypub"
+ "forgejo.org/modules/httplib"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ gitea_context "forgejo.org/services/context"
+ "github.com/42wim/httpsig"
ap "github.com/go-ap/activitypub"
- "github.com/go-fed/httpsig"
)
func getPublicKeyFromResponse(b []byte, keyID *url.URL) (p crypto.PublicKey, err error) {
diff --git a/routers/api/v1/activitypub/response.go b/routers/api/v1/activitypub/response.go
index 42ef375f12..a97f363cc2 100644
--- a/routers/api/v1/activitypub/response.go
+++ b/routers/api/v1/activitypub/response.go
@@ -6,10 +6,10 @@ package activitypub
import (
"net/http"
- "code.gitea.io/gitea/modules/activitypub"
- "code.gitea.io/gitea/modules/forgefed"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/activitypub"
+ "forgejo.org/modules/forgefed"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/context"
ap "github.com/go-ap/activitypub"
"github.com/go-ap/jsonld"
diff --git a/routers/api/v1/admin/adopt.go b/routers/api/v1/admin/adopt.go
index a4708fe032..082411f2bc 100644
--- a/routers/api/v1/admin/adopt.go
+++ b/routers/api/v1/admin/adopt.go
@@ -6,12 +6,12 @@ package admin
import (
"net/http"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- repo_service "code.gitea.io/gitea/services/repository"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ repo_service "forgejo.org/services/repository"
)
// ListUnadoptedRepositories lists the unadopted repositories that match the provided names
diff --git a/routers/api/v1/admin/cron.go b/routers/api/v1/admin/cron.go
index e1ca6048c9..5d68ab2dce 100644
--- a/routers/api/v1/admin/cron.go
+++ b/routers/api/v1/admin/cron.go
@@ -6,12 +6,12 @@ package admin
import (
"net/http"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/cron"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/cron"
)
// ListCronTasks api for getting cron tasks
diff --git a/routers/api/v1/admin/email.go b/routers/api/v1/admin/email.go
index ba963e9f69..906780a44b 100644
--- a/routers/api/v1/admin/email.go
+++ b/routers/api/v1/admin/email.go
@@ -6,11 +6,11 @@ package admin
import (
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// GetAllEmails
diff --git a/routers/api/v1/admin/hooks.go b/routers/api/v1/admin/hooks.go
index b246cb61b1..b3db2eb5e3 100644
--- a/routers/api/v1/admin/hooks.go
+++ b/routers/api/v1/admin/hooks.go
@@ -7,14 +7,14 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ "forgejo.org/models/webhook"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ webhook_service "forgejo.org/services/webhook"
)
// ListHooks list system's webhooks
diff --git a/routers/api/v1/admin/org.go b/routers/api/v1/admin/org.go
index a5c299bbf0..d3a5cea056 100644
--- a/routers/api/v1/admin/org.go
+++ b/routers/api/v1/admin/org.go
@@ -7,14 +7,14 @@ package admin
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// CreateOrg api for create organization
diff --git a/routers/api/v1/admin/quota.go b/routers/api/v1/admin/quota.go
new file mode 100644
index 0000000000..c7da0e6398
--- /dev/null
+++ b/routers/api/v1/admin/quota.go
@@ -0,0 +1,53 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package admin
+
+import (
+ "net/http"
+
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+)
+
+// GetUserQuota return information about a user's quota
+func GetUserQuota(ctx *context.APIContext) {
+ // swagger:operation GET /admin/users/{username}/quota admin adminGetUserQuota
+ // ---
+ // summary: Get the user's quota info
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: username
+ // in: path
+ // description: username of user to query
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaInfo"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ used, err := quota_model.GetUsedForUser(ctx, ctx.ContextUser.ID)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.GetUsedForUser", err)
+ return
+ }
+
+ groups, err := quota_model.GetGroupsForUser(ctx, ctx.ContextUser.ID)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.GetGroupsForUser", err)
+ return
+ }
+
+ result := convert.ToQuotaInfo(used, groups, true)
+ ctx.JSON(http.StatusOK, &result)
+}
diff --git a/routers/api/v1/admin/quota_group.go b/routers/api/v1/admin/quota_group.go
new file mode 100644
index 0000000000..afe33b639c
--- /dev/null
+++ b/routers/api/v1/admin/quota_group.go
@@ -0,0 +1,436 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package admin
+
+import (
+ go_context "context"
+ "net/http"
+
+ "forgejo.org/models/db"
+ quota_model "forgejo.org/models/quota"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+)
+
+// ListQuotaGroups returns all the quota groups
+func ListQuotaGroups(ctx *context.APIContext) {
+ // swagger:operation GET /admin/quota/groups admin adminListQuotaGroups
+ // ---
+ // summary: List the available quota groups
+ // produces:
+ // - application/json
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaGroupList"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+
+ groups, err := quota_model.ListGroups(ctx)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.ListGroups", err)
+ return
+ }
+ for _, group := range groups {
+ if err = group.LoadRules(ctx); err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.group.LoadRules", err)
+ return
+ }
+ }
+
+ ctx.JSON(http.StatusOK, convert.ToQuotaGroupList(groups, true))
+}
+
+func createQuotaGroupWithRules(ctx go_context.Context, opts *api.CreateQuotaGroupOptions) (*quota_model.Group, error) {
+ ctx, committer, err := db.TxContext(ctx)
+ if err != nil {
+ return nil, err
+ }
+ defer committer.Close()
+
+ group, err := quota_model.CreateGroup(ctx, opts.Name)
+ if err != nil {
+ return nil, err
+ }
+
+ for _, rule := range opts.Rules {
+ exists, err := quota_model.DoesRuleExist(ctx, rule.Name)
+ if err != nil {
+ return nil, err
+ }
+ if !exists {
+ var limit int64
+ if rule.Limit != nil {
+ limit = *rule.Limit
+ }
+
+ subjects, err := toLimitSubjects(rule.Subjects)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = quota_model.CreateRule(ctx, rule.Name, limit, *subjects)
+ if err != nil {
+ return nil, err
+ }
+ }
+ if err = group.AddRuleByName(ctx, rule.Name); err != nil {
+ return nil, err
+ }
+ }
+
+ if err = group.LoadRules(ctx); err != nil {
+ return nil, err
+ }
+
+ return group, committer.Commit()
+}
+
+// CreateQuotaGroup creates a new quota group
+func CreateQuotaGroup(ctx *context.APIContext) {
+ // swagger:operation POST /admin/quota/groups admin adminCreateQuotaGroup
+ // ---
+ // summary: Create a new quota group
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: group
+ // in: body
+ // description: Definition of the quota group
+ // schema:
+ // "$ref": "#/definitions/CreateQuotaGroupOptions"
+ // required: true
+ // responses:
+ // "201":
+ // "$ref": "#/responses/QuotaGroup"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "409":
+ // "$ref": "#/responses/error"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ form := web.GetForm(ctx).(*api.CreateQuotaGroupOptions)
+
+ group, err := createQuotaGroupWithRules(ctx, form)
+ if err != nil {
+ if quota_model.IsErrGroupAlreadyExists(err) {
+ ctx.Error(http.StatusConflict, "", err)
+ } else if quota_model.IsErrParseLimitSubjectUnrecognized(err) {
+ ctx.Error(http.StatusUnprocessableEntity, "", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "quota_model.CreateGroup", err)
+ }
+ return
+ }
+ ctx.JSON(http.StatusCreated, convert.ToQuotaGroup(*group, true))
+}
+
+// ListUsersInQuotaGroup lists all the users in a quota group
+func ListUsersInQuotaGroup(ctx *context.APIContext) {
+ // swagger:operation GET /admin/quota/groups/{quotagroup}/users admin adminListUsersInQuotaGroup
+ // ---
+ // summary: List users in a quota group
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotagroup
+ // in: path
+ // description: quota group to list members of
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/UserList"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ users, err := quota_model.ListUsersInGroup(ctx, ctx.QuotaGroup.Name)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.ListUsersInGroup", err)
+ return
+ }
+ ctx.JSON(http.StatusOK, convert.ToUsers(ctx, ctx.Doer, users))
+}
+
+// AddUserToQuotaGroup adds a user to a quota group
+func AddUserToQuotaGroup(ctx *context.APIContext) {
+ // swagger:operation PUT /admin/quota/groups/{quotagroup}/users/{username} admin adminAddUserToQuotaGroup
+ // ---
+ // summary: Add a user to a quota group
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotagroup
+ // in: path
+ // description: quota group to add the user to
+ // type: string
+ // required: true
+ // - name: username
+ // in: path
+ // description: username of the user to add to the quota group
+ // type: string
+ // required: true
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "409":
+ // "$ref": "#/responses/error"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ err := ctx.QuotaGroup.AddUserByID(ctx, ctx.ContextUser.ID)
+ if err != nil {
+ if quota_model.IsErrUserAlreadyInGroup(err) {
+ ctx.Error(http.StatusConflict, "", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "quota_group.group.AddUserByID", err)
+ }
+ return
+ }
+ ctx.Status(http.StatusNoContent)
+}
+
+// RemoveUserFromQuotaGroup removes a user from a quota group
+func RemoveUserFromQuotaGroup(ctx *context.APIContext) {
+ // swagger:operation DELETE /admin/quota/groups/{quotagroup}/users/{username} admin adminRemoveUserFromQuotaGroup
+ // ---
+ // summary: Remove a user from a quota group
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotagroup
+ // in: path
+ // description: quota group to remove a user from
+ // type: string
+ // required: true
+ // - name: username
+ // in: path
+ // description: username of the user to remove from the quota group
+ // type: string
+ // required: true
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ err := ctx.QuotaGroup.RemoveUserByID(ctx, ctx.ContextUser.ID)
+ if err != nil {
+ if quota_model.IsErrUserNotInGroup(err) {
+ ctx.NotFound()
+ } else {
+ ctx.Error(http.StatusInternalServerError, "quota_model.group.RemoveUserByID", err)
+ }
+ return
+ }
+ ctx.Status(http.StatusNoContent)
+}
+
+// SetUserQuotaGroups moves the user to specific quota groups
+func SetUserQuotaGroups(ctx *context.APIContext) {
+ // swagger:operation POST /admin/users/{username}/quota/groups admin adminSetUserQuotaGroups
+ // ---
+ // summary: Set the user's quota groups to a given list.
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: username
+ // in: path
+ // description: username of the user to modify the quota groups from
+ // type: string
+ // required: true
+ // - name: groups
+ // in: body
+ // description: list of groups that the user should be a member of
+ // schema:
+ // "$ref": "#/definitions/SetUserQuotaGroupsOptions"
+ // required: true
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ form := web.GetForm(ctx).(*api.SetUserQuotaGroupsOptions)
+
+ err := quota_model.SetUserGroups(ctx, ctx.ContextUser.ID, form.Groups)
+ if err != nil {
+ if quota_model.IsErrGroupNotFound(err) {
+ ctx.Error(http.StatusUnprocessableEntity, "", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "quota_model.SetUserGroups", err)
+ }
+ return
+ }
+
+ ctx.Status(http.StatusNoContent)
+}
+
+// DeleteQuotaGroup deletes a quota group
+func DeleteQuotaGroup(ctx *context.APIContext) {
+ // swagger:operation DELETE /admin/quota/groups/{quotagroup} admin adminDeleteQuotaGroup
+ // ---
+ // summary: Delete a quota group
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotagroup
+ // in: path
+ // description: quota group to delete
+ // type: string
+ // required: true
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ err := quota_model.DeleteGroupByName(ctx, ctx.QuotaGroup.Name)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.DeleteGroupByName", err)
+ return
+ }
+
+ ctx.Status(http.StatusNoContent)
+}
+
+// GetQuotaGroup returns information about a quota group
+func GetQuotaGroup(ctx *context.APIContext) {
+ // swagger:operation GET /admin/quota/groups/{quotagroup} admin adminGetQuotaGroup
+ // ---
+ // summary: Get information about the quota group
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotagroup
+ // in: path
+ // description: quota group to query
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaGroup"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ ctx.JSON(http.StatusOK, convert.ToQuotaGroup(*ctx.QuotaGroup, true))
+}
+
+// AddRuleToQuotaGroup adds a rule to a quota group
+func AddRuleToQuotaGroup(ctx *context.APIContext) {
+ // swagger:operation PUT /admin/quota/groups/{quotagroup}/rules/{quotarule} admin adminAddRuleToQuotaGroup
+ // ---
+ // summary: Adds a rule to a quota group
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotagroup
+ // in: path
+ // description: quota group to add a rule to
+ // type: string
+ // required: true
+ // - name: quotarule
+ // in: path
+ // description: the name of the quota rule to add to the group
+ // type: string
+ // required: true
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "409":
+ // "$ref": "#/responses/error"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ err := ctx.QuotaGroup.AddRuleByName(ctx, ctx.QuotaRule.Name)
+ if err != nil {
+ if quota_model.IsErrRuleAlreadyInGroup(err) {
+ ctx.Error(http.StatusConflict, "", err)
+ } else if quota_model.IsErrRuleNotFound(err) {
+ ctx.Error(http.StatusUnprocessableEntity, "", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "quota_model.group.AddRuleByName", err)
+ }
+ return
+ }
+ ctx.Status(http.StatusNoContent)
+}
+
+// RemoveRuleFromQuotaGroup removes a rule from a quota group
+func RemoveRuleFromQuotaGroup(ctx *context.APIContext) {
+ // swagger:operation DELETE /admin/quota/groups/{quotagroup}/rules/{quotarule} admin adminRemoveRuleFromQuotaGroup
+ // ---
+ // summary: Removes a rule from a quota group
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotagroup
+ // in: path
+ // description: quota group to remove a rule from
+ // type: string
+ // required: true
+ // - name: quotarule
+ // in: path
+ // description: the name of the quota rule to remove from the group
+ // type: string
+ // required: true
+ // responses:
+ // "201":
+ // "$ref": "#/responses/empty"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ err := ctx.QuotaGroup.RemoveRuleByName(ctx, ctx.QuotaRule.Name)
+ if err != nil {
+ if quota_model.IsErrRuleNotInGroup(err) {
+ ctx.NotFound()
+ } else {
+ ctx.Error(http.StatusInternalServerError, "quota_model.group.RemoveRuleByName", err)
+ }
+ return
+ }
+ ctx.Status(http.StatusNoContent)
+}
diff --git a/routers/api/v1/admin/quota_rule.go b/routers/api/v1/admin/quota_rule.go
new file mode 100644
index 0000000000..ea188107fa
--- /dev/null
+++ b/routers/api/v1/admin/quota_rule.go
@@ -0,0 +1,219 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package admin
+
+import (
+ "fmt"
+ "net/http"
+
+ quota_model "forgejo.org/models/quota"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+)
+
+func toLimitSubjects(subjStrings []string) (*quota_model.LimitSubjects, error) {
+ subjects := make(quota_model.LimitSubjects, len(subjStrings))
+ for i := range len(subjStrings) {
+ subj, err := quota_model.ParseLimitSubject(subjStrings[i])
+ if err != nil {
+ return nil, err
+ }
+ subjects[i] = subj
+ }
+
+ return &subjects, nil
+}
+
+// ListQuotaRules lists all the quota rules
+func ListQuotaRules(ctx *context.APIContext) {
+ // swagger:operation GET /admin/quota/rules admin adminListQuotaRules
+ // ---
+ // summary: List the available quota rules
+ // produces:
+ // - application/json
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaRuleInfoList"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+
+ rules, err := quota_model.ListRules(ctx)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.ListQuotaRules", err)
+ return
+ }
+
+ result := make([]api.QuotaRuleInfo, len(rules))
+ for i := range len(rules) {
+ result[i] = convert.ToQuotaRuleInfo(rules[i], true)
+ }
+
+ ctx.JSON(http.StatusOK, result)
+}
+
+// CreateQuotaRule creates a new quota rule
+func CreateQuotaRule(ctx *context.APIContext) {
+ // swagger:operation POST /admin/quota/rules admin adminCreateQuotaRule
+ // ---
+ // summary: Create a new quota rule
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: rule
+ // in: body
+ // description: Definition of the quota rule
+ // schema:
+ // "$ref": "#/definitions/CreateQuotaRuleOptions"
+ // required: true
+ // responses:
+ // "201":
+ // "$ref": "#/responses/QuotaRuleInfo"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "409":
+ // "$ref": "#/responses/error"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ form := web.GetForm(ctx).(*api.CreateQuotaRuleOptions)
+
+ if form.Limit == nil {
+ ctx.Error(http.StatusUnprocessableEntity, "quota_model.ParseLimitSubject", fmt.Errorf("[Limit]: Required"))
+ return
+ }
+
+ subjects, err := toLimitSubjects(form.Subjects)
+ if err != nil {
+ ctx.Error(http.StatusUnprocessableEntity, "quota_model.ParseLimitSubject", err)
+ return
+ }
+
+ rule, err := quota_model.CreateRule(ctx, form.Name, *form.Limit, *subjects)
+ if err != nil {
+ if quota_model.IsErrRuleAlreadyExists(err) {
+ ctx.Error(http.StatusConflict, "", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "quota_model.CreateRule", err)
+ }
+ return
+ }
+ ctx.JSON(http.StatusCreated, convert.ToQuotaRuleInfo(*rule, true))
+}
+
+// GetQuotaRule returns information about the specified quota rule
+func GetQuotaRule(ctx *context.APIContext) {
+ // swagger:operation GET /admin/quota/rules/{quotarule} admin adminGetQuotaRule
+ // ---
+ // summary: Get information about a quota rule
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotarule
+ // in: path
+ // description: quota rule to query
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaRuleInfo"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ ctx.JSON(http.StatusOK, convert.ToQuotaRuleInfo(*ctx.QuotaRule, true))
+}
+
+// EditQuotaRule changes an existing quota rule
+func EditQuotaRule(ctx *context.APIContext) {
+ // swagger:operation PATCH /admin/quota/rules/{quotarule} admin adminEditQuotaRule
+ // ---
+ // summary: Change an existing quota rule
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotarule
+ // in: path
+ // description: Quota rule to change
+ // type: string
+ // required: true
+ // - name: rule
+ // in: body
+ // schema:
+ // "$ref": "#/definitions/EditQuotaRuleOptions"
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaRuleInfo"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ form := web.GetForm(ctx).(*api.EditQuotaRuleOptions)
+
+ var subjects *quota_model.LimitSubjects
+ if form.Subjects != nil {
+ subjs := make(quota_model.LimitSubjects, len(*form.Subjects))
+ for i := range len(*form.Subjects) {
+ subj, err := quota_model.ParseLimitSubject((*form.Subjects)[i])
+ if err != nil {
+ ctx.Error(http.StatusUnprocessableEntity, "quota_model.ParseLimitSubject", err)
+ return
+ }
+ subjs[i] = subj
+ }
+ subjects = &subjs
+ }
+
+ rule, err := ctx.QuotaRule.Edit(ctx, form.Limit, subjects)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.rule.Edit", err)
+ return
+ }
+
+ ctx.JSON(http.StatusOK, convert.ToQuotaRuleInfo(*rule, true))
+}
+
+// DeleteQuotaRule deletes a quota rule
+func DeleteQuotaRule(ctx *context.APIContext) {
+ // swagger:operation DELETE /admin/quota/rules/{quotarule} admin adminDEleteQuotaRule
+ // ---
+ // summary: Deletes a quota rule
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: quotarule
+ // in: path
+ // description: quota rule to delete
+ // type: string
+ // required: true
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ err := quota_model.DeleteRuleByName(ctx, ctx.QuotaRule.Name)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.DeleteRuleByName", err)
+ return
+ }
+
+ ctx.Status(http.StatusNoContent)
+}
diff --git a/routers/api/v1/admin/repo.go b/routers/api/v1/admin/repo.go
index c119d5390a..9f9118e0ab 100644
--- a/routers/api/v1/admin/repo.go
+++ b/routers/api/v1/admin/repo.go
@@ -4,10 +4,10 @@
package admin
import (
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/repo"
- "code.gitea.io/gitea/services/context"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/repo"
+ "forgejo.org/services/context"
)
// CreateRepo api for creating a repository
diff --git a/routers/api/v1/admin/runners.go b/routers/api/v1/admin/runners.go
index 329242d9f6..e459b947ff 100644
--- a/routers/api/v1/admin/runners.go
+++ b/routers/api/v1/admin/runners.go
@@ -4,8 +4,8 @@
package admin
import (
- "code.gitea.io/gitea/routers/api/v1/shared"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/routers/api/v1/shared"
+ "forgejo.org/services/context"
)
// https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization
@@ -24,3 +24,23 @@ func GetRegistrationToken(ctx *context.APIContext) {
shared.GetRegistrationToken(ctx, 0, 0)
}
+
+// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters
+func SearchActionRunJobs(ctx *context.APIContext) {
+ // swagger:operation GET /admin/runners/jobs admin adminSearchRunJobs
+ // ---
+ // summary: Search action jobs according filter conditions
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: labels
+ // in: query
+ // description: a comma separated list of run job labels to search for
+ // type: string
+ // responses:
+ // "200":
+ // "$ref": "#/responses/RunJobList"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ shared.GetActionRunJobs(ctx, 0, 0)
+}
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
index 9ea210ee4e..32e1dd414d 100644
--- a/routers/api/v1/admin/user.go
+++ b/routers/api/v1/admin/user.go
@@ -8,26 +8,28 @@ import (
"errors"
"fmt"
"net/http"
+ "strconv"
- "code.gitea.io/gitea/models"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/password"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/user"
- "code.gitea.io/gitea/routers/api/v1/utils"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/mailer"
- user_service "code.gitea.io/gitea/services/user"
+ "forgejo.org/models"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/password"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/user"
+ "forgejo.org/routers/api/v1/utils"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/mailer"
+ user_service "forgejo.org/services/user"
)
func parseAuthSource(ctx *context.APIContext, u *user_model.User, sourceID int64) {
@@ -138,8 +140,8 @@ func CreateUser(ctx *context.APIContext) {
user_model.IsErrEmailAlreadyUsed(err) ||
db.IsErrNameReserved(err) ||
db.IsErrNameCharsNotAllowed(err) ||
- user_model.IsErrEmailCharIsNotSupported(err) ||
- user_model.IsErrEmailInvalid(err) ||
+ validation.IsErrEmailCharIsNotSupported(err) ||
+ validation.IsErrEmailInvalid(err) ||
db.IsErrNamePatternNotAllowed(err) {
ctx.Error(http.StatusUnprocessableEntity, "", err)
} else {
@@ -148,7 +150,7 @@ func CreateUser(ctx *context.APIContext) {
return
}
- if !user_model.IsEmailDomainAllowed(u.Email) {
+ if !validation.IsEmailDomainAllowed(u.Email) {
ctx.Resp.Header().Add("X-Gitea-Warning", fmt.Sprintf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", u.Email))
}
@@ -224,7 +226,7 @@ func EditUser(ctx *context.APIContext) {
if form.Email != nil {
if err := user_service.AdminAddOrSetPrimaryEmailAddress(ctx, ctx.ContextUser, *form.Email); err != nil {
switch {
- case user_model.IsErrEmailCharIsNotSupported(err), user_model.IsErrEmailInvalid(err):
+ case validation.IsErrEmailCharIsNotSupported(err), validation.IsErrEmailInvalid(err):
ctx.Error(http.StatusBadRequest, "EmailInvalid", err)
case user_model.IsErrEmailAlreadyUsed(err):
ctx.Error(http.StatusBadRequest, "EmailUsed", err)
@@ -234,7 +236,7 @@ func EditUser(ctx *context.APIContext) {
return
}
- if !user_model.IsEmailDomainAllowed(*form.Email) {
+ if !validation.IsEmailDomainAllowed(*form.Email) {
ctx.Resp.Header().Add("X-Gitea-Warning", fmt.Sprintf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", *form.Email))
}
}
@@ -414,6 +416,11 @@ func SearchUsers(ctx *context.APIContext) {
// in: query
// description: user's login name to search for
// type: string
+ // - name: sort
+ // in: query
+ // description: sort order of results
+ // type: string
+ // enum: [oldest, newest, alphabetically, reversealphabetically, recentupdate, leastupdate]
// - name: page
// in: query
// description: page number of results to return (1-based)
@@ -430,12 +437,40 @@ func SearchUsers(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx)
+ sort := ctx.FormString("sort")
+ var orderBy db.SearchOrderBy
+
+ switch sort {
+ case "oldest":
+ orderBy = db.SearchOrderByOldest
+ case "newest":
+ orderBy = db.SearchOrderByNewest
+ case "alphabetically":
+ orderBy = db.SearchOrderByAlphabetically
+ case "reversealphabetically":
+ orderBy = db.SearchOrderByAlphabeticallyReverse
+ case "recentupdate":
+ orderBy = db.SearchOrderByRecentUpdated
+ case "leastupdate":
+ orderBy = db.SearchOrderByLeastUpdated
+ default:
+ orderBy = db.SearchOrderByAlphabetically
+ }
+
+ intSource, err := strconv.ParseInt(ctx.FormString("source_id"), 10, 64)
+ var sourceID optional.Option[int64]
+ if ctx.FormString("source_id") == "" || err != nil {
+ sourceID = optional.None[int64]()
+ } else {
+ sourceID = optional.Some(intSource)
+ }
+
users, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
Actor: ctx.Doer,
Type: user_model.UserTypeIndividual,
LoginName: ctx.FormTrim("login_name"),
- SourceID: ctx.FormInt64("source_id"),
- OrderBy: db.SearchOrderByAlphabetically,
+ SourceID: sourceID,
+ OrderBy: orderBy,
ListOptions: listOptions,
})
if err != nil {
@@ -488,7 +523,7 @@ func RenameUser(ctx *context.APIContext) {
newName := web.GetForm(ctx).(*api.RenameUserOption).NewName
// Check if user name has been changed
- if err := user_service.RenameUser(ctx, ctx.ContextUser, newName); err != nil {
+ if err := user_service.AdminRenameUser(ctx, ctx.ContextUser, newName); err != nil {
switch {
case user_model.IsErrUserAlreadyExist(err):
ctx.Error(http.StatusUnprocessableEntity, "", ctx.Tr("form.username_been_taken"))
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index 7757f401a7..2eb1ee4229 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -1,6 +1,6 @@
// Copyright 2015 The Gogs Authors. All rights reserved.
// Copyright 2016 The Gitea Authors. All rights reserved.
-// Copyright 2023 The Forgejo Authors. All rights reserved.
+// Copyright 2023-2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
// Package v1 Gitea API
@@ -71,38 +71,39 @@ import (
"net/http"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- auth_model "code.gitea.io/gitea/models/auth"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/forgefed"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/shared"
- "code.gitea.io/gitea/routers/api/v1/activitypub"
- "code.gitea.io/gitea/routers/api/v1/admin"
- "code.gitea.io/gitea/routers/api/v1/misc"
- "code.gitea.io/gitea/routers/api/v1/notify"
- "code.gitea.io/gitea/routers/api/v1/org"
- "code.gitea.io/gitea/routers/api/v1/packages"
- "code.gitea.io/gitea/routers/api/v1/repo"
- "code.gitea.io/gitea/routers/api/v1/settings"
- "code.gitea.io/gitea/routers/api/v1/user"
- "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ actions_model "forgejo.org/models/actions"
+ auth_model "forgejo.org/models/auth"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/forgefed"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/shared"
+ "forgejo.org/routers/api/v1/activitypub"
+ "forgejo.org/routers/api/v1/admin"
+ "forgejo.org/routers/api/v1/misc"
+ "forgejo.org/routers/api/v1/notify"
+ "forgejo.org/routers/api/v1/org"
+ "forgejo.org/routers/api/v1/packages"
+ "forgejo.org/routers/api/v1/repo"
+ "forgejo.org/routers/api/v1/settings"
+ "forgejo.org/routers/api/v1/user"
+ "forgejo.org/services/actions"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
- _ "code.gitea.io/gitea/routers/api/v1/swagger" // for swagger generation
+ _ "forgejo.org/routers/api/v1/swagger" // for swagger generation
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
func sudo() func(ctx *context.APIContext) {
@@ -273,6 +274,62 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext)
}
}
+func checkTokenPublicOnly() func(ctx *context.APIContext) {
+ return func(ctx *context.APIContext) {
+ if !ctx.PublicOnly {
+ return
+ }
+
+ requiredScopeCategories, ok := ctx.Data["requiredScopeCategories"].([]auth_model.AccessTokenScopeCategory)
+ if !ok || len(requiredScopeCategories) == 0 {
+ return
+ }
+
+ // public Only permission check
+ switch {
+ case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryRepository):
+ if ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate {
+ ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public repos")
+ return
+ }
+ case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryIssue):
+ if ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate {
+ ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public issues")
+ return
+ }
+ case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryOrganization):
+ if ctx.Org.Organization != nil && ctx.Org.Organization.Visibility != api.VisibleTypePublic {
+ ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public orgs")
+ return
+ }
+ if ctx.ContextUser != nil && ctx.ContextUser.IsOrganization() && ctx.ContextUser.Visibility != api.VisibleTypePublic {
+ ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public orgs")
+ return
+ }
+ case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryUser):
+ if ctx.ContextUser != nil && ctx.ContextUser.IsUser() && ctx.ContextUser.Visibility != api.VisibleTypePublic {
+ ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public users")
+ return
+ }
+ case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryActivityPub):
+ if ctx.ContextUser != nil && ctx.ContextUser.IsUser() && ctx.ContextUser.Visibility != api.VisibleTypePublic {
+ ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public activitypub")
+ return
+ }
+ case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryNotification):
+ if ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate {
+ ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public notifications")
+ return
+ }
+ case auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryPackage):
+ if ctx.Package != nil && ctx.Package.Owner.Visibility.IsPrivate() {
+ ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public packages")
+ return
+ }
+ }
+ }
+}
+
// if a token is being used for auth, we check that it contains the required scope
// if a token is not being used, reqToken will enforce other sign in methods
func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeCategory) func(ctx *context.APIContext) {
@@ -288,9 +345,6 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC
return
}
- ctx.Data["ApiTokenScopePublicRepoOnly"] = false
- ctx.Data["ApiTokenScopePublicOrgOnly"] = false
-
// use the http method to determine the access level
requiredScopeLevel := auth_model.Read
if ctx.Req.Method == "POST" || ctx.Req.Method == "PUT" || ctx.Req.Method == "PATCH" || ctx.Req.Method == "DELETE" {
@@ -299,6 +353,18 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC
// get the required scope for the given access level and category
requiredScopes := auth_model.GetRequiredScopes(requiredScopeLevel, requiredScopeCategories...)
+ allow, err := scope.HasScope(requiredScopes...)
+ if err != nil {
+ ctx.Error(http.StatusForbidden, "tokenRequiresScope", "checking scope failed: "+err.Error())
+ return
+ }
+
+ if !allow {
+ ctx.Error(http.StatusForbidden, "tokenRequiresScope", fmt.Sprintf("token does not have at least one of required scope(s): %v", requiredScopes))
+ return
+ }
+
+ ctx.Data["requiredScopeCategories"] = requiredScopeCategories
// check if scope only applies to public resources
publicOnly, err := scope.PublicOnly()
@@ -307,21 +373,8 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC
return
}
- // this context is used by the middleware in the specific route
- ctx.Data["ApiTokenScopePublicRepoOnly"] = publicOnly && auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryRepository)
- ctx.Data["ApiTokenScopePublicOrgOnly"] = publicOnly && auth_model.ContainsCategory(requiredScopeCategories, auth_model.AccessTokenScopeCategoryOrganization)
-
- allow, err := scope.HasScope(requiredScopes...)
- if err != nil {
- ctx.Error(http.StatusForbidden, "tokenRequiresScope", "checking scope failed: "+err.Error())
- return
- }
-
- if allow {
- return
- }
-
- ctx.Error(http.StatusForbidden, "tokenRequiresScope", fmt.Sprintf("token does not have at least one of required scope(s): %v", requiredScopes))
+ // assign to true so that those searching should only filter public repositories/users/organizations
+ ctx.PublicOnly = publicOnly
}
}
@@ -333,25 +386,6 @@ func reqToken() func(ctx *context.APIContext) {
return
}
- if true == ctx.Data["IsApiToken"] {
- publicRepo, pubRepoExists := ctx.Data["ApiTokenScopePublicRepoOnly"]
- publicOrg, pubOrgExists := ctx.Data["ApiTokenScopePublicOrgOnly"]
-
- if pubRepoExists && publicRepo.(bool) &&
- ctx.Repo.Repository != nil && ctx.Repo.Repository.IsPrivate {
- ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public repos")
- return
- }
-
- if pubOrgExists && publicOrg.(bool) &&
- ctx.Org.Organization != nil && ctx.Org.Organization.Visibility != api.VisibleTypePublic {
- ctx.Error(http.StatusForbidden, "reqToken", "token scope is limited to public orgs")
- return
- }
-
- return
- }
-
if ctx.IsSigned {
return
}
@@ -361,12 +395,20 @@ func reqToken() func(ctx *context.APIContext) {
func reqExploreSignIn() func(ctx *context.APIContext) {
return func(ctx *context.APIContext) {
- if setting.Service.Explore.RequireSigninView && !ctx.IsSigned {
+ if (setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView) && !ctx.IsSigned {
ctx.Error(http.StatusUnauthorized, "reqExploreSignIn", "you must be signed in to search for users")
}
}
}
+func reqUsersExploreEnabled() func(ctx *context.APIContext) {
+ return func(ctx *context.APIContext) {
+ if setting.Service.Explore.DisableUsersPage {
+ ctx.NotFound()
+ }
+ }
+}
+
func reqBasicOrRevProxyAuth() func(ctx *context.APIContext) {
return func(ctx *context.APIContext) {
if ctx.IsSigned && setting.Service.EnableReverseProxyAuthAPI && ctx.Data["AuthedMethod"].(string) == auth.ReverseProxyMethodName {
@@ -780,6 +822,7 @@ func Routes() *web.Route {
m.Group("/runners", func() {
m.Get("/registration-token", reqToken(), reqChecker, act.GetRegistrationToken)
+ m.Get("/jobs", reqToken(), reqChecker, act.SearchActionRunJobs)
})
})
}
@@ -799,11 +842,15 @@ func Routes() *web.Route {
m.Group("/user/{username}", func() {
m.Get("", activitypub.Person)
m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox)
- }, context.UserAssignmentAPI())
+ }, context.UserAssignmentAPI(), checkTokenPublicOnly())
m.Group("/user-id/{user-id}", func() {
m.Get("", activitypub.Person)
m.Post("/inbox", activitypub.ReqHTTPSignature(), activitypub.PersonInbox)
- }, context.UserIDAssignmentAPI())
+ }, context.UserIDAssignmentAPI(), checkTokenPublicOnly())
+ m.Group("/actor", func() {
+ m.Get("", activitypub.Actor)
+ m.Post("/inbox", activitypub.ActorInbox)
+ })
m.Group("/repository-id/{repository-id}", func() {
m.Get("", activitypub.Repository)
m.Post("/inbox",
@@ -849,7 +896,7 @@ func Routes() *web.Route {
// Users (requires user scope)
m.Group("/users", func() {
- m.Get("/search", reqExploreSignIn(), user.Search)
+ m.Get("/search", reqExploreSignIn(), reqUsersExploreEnabled(), user.Search)
m.Group("/{username}", func() {
m.Get("", reqExploreSignIn(), user.GetInfo)
@@ -861,12 +908,12 @@ func Routes() *web.Route {
m.Get("/repos", tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository), reqExploreSignIn(), user.ListUserRepos)
m.Group("/tokens", func() {
m.Combo("").Get(user.ListAccessTokens).
- Post(bind(api.CreateAccessTokenOption{}), reqToken(), user.CreateAccessToken)
- m.Combo("/{id}").Delete(reqToken(), user.DeleteAccessToken)
- }, reqSelfOrAdmin(), reqBasicOrRevProxyAuth())
+ Post(bind(api.CreateAccessTokenOption{}), reqBasicOrRevProxyAuth(), reqToken(), user.CreateAccessToken)
+ m.Combo("/{id}").Delete(reqBasicOrRevProxyAuth(), reqToken(), user.DeleteAccessToken)
+ }, reqSelfOrAdmin())
m.Get("/activities/feeds", user.ListUserActivityFeeds)
- }, context.UserAssignmentAPI(), individualPermsChecker)
+ }, context.UserAssignmentAPI(), checkTokenPublicOnly(), individualPermsChecker)
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser))
// Users (requires user scope)
@@ -886,12 +933,21 @@ func Routes() *web.Route {
}
m.Get("/subscriptions", user.GetWatchedRepos)
- }, context.UserAssignmentAPI())
+ }, context.UserAssignmentAPI(), checkTokenPublicOnly())
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser), reqToken())
// Users (requires user scope)
m.Group("/user", func() {
m.Get("", user.GetAuthenticatedUser)
+ if setting.Quota.Enabled {
+ m.Group("/quota", func() {
+ m.Get("", user.GetQuota)
+ m.Get("/check", user.CheckQuota)
+ m.Get("/attachments", user.ListQuotaAttachments)
+ m.Get("/packages", user.ListQuotaPackages)
+ m.Get("/artifacts", user.ListQuotaArtifacts)
+ })
+ }
m.Group("/settings", func() {
m.Get("", user.GetUserSettings)
m.Patch("", bind(api.UserSettingsOptions{}), user.UpdateUserSettings)
@@ -920,6 +976,7 @@ func Routes() *web.Route {
m.Group("/runners", func() {
m.Get("/registration-token", reqToken(), user.GetRegistrationToken)
+ m.Get("/jobs", reqToken(), user.SearchActionRunJobs)
})
})
@@ -964,7 +1021,7 @@ func Routes() *web.Route {
// (repo scope)
m.Combo("/repos", tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)).Get(user.ListMyRepos).
- Post(bind(api.CreateRepoOption{}), repo.Create)
+ Post(bind(api.CreateRepoOption{}), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetUser), repo.Create)
// (repo scope)
if !setting.Repository.DisableStars {
@@ -974,7 +1031,7 @@ func Routes() *web.Route {
m.Get("", user.IsStarring)
m.Put("", user.Star)
m.Delete("", user.Unstar)
- }, repoAssignment())
+ }, repoAssignment(), checkTokenPublicOnly())
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository))
}
m.Get("/times", repo.ListMyTrackedTimes)
@@ -1005,12 +1062,14 @@ func Routes() *web.Route {
// Repositories (requires repo scope, org scope)
m.Post("/org/{org}/repos",
+ // FIXME: we need org in context
tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization, auth_model.AccessTokenScopeCategoryRepository),
reqToken(),
bind(api.CreateRepoOption{}),
repo.CreateOrgRepoDeprecated)
// requires repo scope
+ // FIXME: Don't expose repository id outside of the system
m.Combo("/repositories/{id}", reqToken(), tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository)).Get(repo.GetByID)
// Repos (requires repo scope)
@@ -1095,7 +1154,8 @@ func Routes() *web.Route {
m.Get("", repo.ListBranches)
m.Get("/*", repo.GetBranch)
m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.DeleteBranch)
- m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateBranchRepoOption{}), repo.CreateBranch)
+ m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateBranchRepoOption{}), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeGitAll, context.QuotaTargetRepo), repo.CreateBranch)
+ m.Patch("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.UpdateBranchRepoOption{}), repo.UpdateBranch)
}, context.ReferencesGitRepo(), reqRepoReader(unit.TypeCode))
m.Group("/branch_protections", func() {
m.Get("", repo.ListBranchProtections)
@@ -1109,7 +1169,7 @@ func Routes() *web.Route {
m.Group("/tags", func() {
m.Get("", repo.ListTags)
m.Get("/*", repo.GetTag)
- m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateTagOption{}), repo.CreateTag)
+ m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, bind(api.CreateTagOption{}), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.CreateTag)
m.Delete("/*", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.DeleteTag)
}, reqRepoReader(unit.TypeCode), context.ReferencesGitRepo(true))
m.Group("/tag_protections", func() {
@@ -1143,10 +1203,10 @@ func Routes() *web.Route {
m.Group("/wiki", func() {
m.Combo("/page/{pageName}").
Get(repo.GetWikiPage).
- Patch(mustNotBeArchived, reqToken(), reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.EditWikiPage).
+ Patch(mustNotBeArchived, reqToken(), reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeWiki, context.QuotaTargetRepo), repo.EditWikiPage).
Delete(mustNotBeArchived, reqToken(), reqRepoWriter(unit.TypeWiki), repo.DeleteWikiPage)
m.Get("/revisions/{pageName}", repo.ListPageRevisions)
- m.Post("/new", reqToken(), mustNotBeArchived, reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), repo.NewWikiPage)
+ m.Post("/new", reqToken(), mustNotBeArchived, reqRepoWriter(unit.TypeWiki), bind(api.CreateWikiPageOptions{}), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeWiki, context.QuotaTargetRepo), repo.NewWikiPage)
m.Get("/pages", repo.ListWikiPages)
}, mustEnableWiki)
m.Post("/markup", reqToken(), bind(api.MarkupOption{}), misc.Markup)
@@ -1163,15 +1223,15 @@ func Routes() *web.Route {
}, reqToken())
m.Group("/releases", func() {
m.Combo("").Get(repo.ListReleases).
- Post(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), repo.CreateRelease)
+ Post(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.CreateReleaseOption{}), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.CreateRelease)
m.Combo("/latest").Get(repo.GetLatestRelease)
m.Group("/{id}", func() {
m.Combo("").Get(repo.GetRelease).
- Patch(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), repo.EditRelease).
+ Patch(reqToken(), reqRepoWriter(unit.TypeReleases), context.ReferencesGitRepo(), bind(api.EditReleaseOption{}), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.EditRelease).
Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteRelease)
m.Group("/assets", func() {
m.Combo("").Get(repo.ListReleaseAttachments).
- Post(reqToken(), reqRepoWriter(unit.TypeReleases), repo.CreateReleaseAttachment)
+ Post(reqToken(), reqRepoWriter(unit.TypeReleases), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeAssetsAttachmentsReleases, context.QuotaTargetRepo), repo.CreateReleaseAttachment)
m.Combo("/{attachment_id}").Get(repo.GetReleaseAttachment).
Patch(reqToken(), reqRepoWriter(unit.TypeReleases), bind(api.EditAttachmentOptions{}), repo.EditReleaseAttachment).
Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseAttachment)
@@ -1183,7 +1243,7 @@ func Routes() *web.Route {
Delete(reqToken(), reqRepoWriter(unit.TypeReleases), repo.DeleteReleaseByTag)
})
}, reqRepoReader(unit.TypeReleases))
- m.Post("/mirror-sync", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, repo.MirrorSync)
+ m.Post("/mirror-sync", reqToken(), reqRepoWriter(unit.TypeCode), mustNotBeArchived, context.EnforceQuotaAPI(quota_model.LimitSubjectSizeGitAll, context.QuotaTargetRepo), repo.MirrorSync)
m.Post("/push_mirrors-sync", reqAdmin(), reqToken(), mustNotBeArchived, repo.PushMirrorSync)
m.Group("/push_mirrors", func() {
m.Combo("").Get(repo.ListPushMirrors).
@@ -1202,11 +1262,11 @@ func Routes() *web.Route {
m.Combo("").Get(repo.GetPullRequest).
Patch(reqToken(), bind(api.EditPullRequestOption{}), repo.EditPullRequest)
m.Get(".{diffType:diff|patch}", repo.DownloadPullDiffOrPatch)
- m.Post("/update", reqToken(), repo.UpdatePullRequest)
+ m.Post("/update", reqToken(), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeGitAll, context.QuotaTargetRepo), repo.UpdatePullRequest)
m.Get("/commits", repo.GetPullRequestCommits)
m.Get("/files", repo.GetPullRequestFiles)
m.Combo("/merge").Get(repo.IsPullRequestMerged).
- Post(reqToken(), mustNotBeArchived, bind(forms.MergePullRequestForm{}), repo.MergePullRequest).
+ Post(reqToken(), mustNotBeArchived, bind(forms.MergePullRequestForm{}), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeGitAll, context.QuotaTargetRepo), repo.MergePullRequest).
Delete(reqToken(), mustNotBeArchived, repo.CancelScheduledAutoMerge)
m.Group("/reviews", func() {
m.Combo("").
@@ -1259,17 +1319,21 @@ func Routes() *web.Route {
m.Get("/trees/{sha}", repo.GetTree)
m.Get("/blobs/{sha}", repo.GetBlob)
m.Get("/tags/{sha}", repo.GetAnnotatedTag)
- m.Get("/notes/{sha}", repo.GetNote)
+ m.Group("/notes/{sha}", func() {
+ m.Get("", repo.GetNote)
+ m.Post("", reqToken(), reqRepoWriter(unit.TypeCode), bind(api.NoteOptions{}), repo.SetNote)
+ m.Delete("", reqToken(), reqRepoWriter(unit.TypeCode), repo.RemoveNote)
+ })
}, context.ReferencesGitRepo(true), reqRepoReader(unit.TypeCode))
- m.Post("/diffpatch", reqRepoWriter(unit.TypeCode), reqToken(), bind(api.ApplyDiffPatchFileOptions{}), mustNotBeArchived, repo.ApplyDiffPatch)
+ m.Post("/diffpatch", reqRepoWriter(unit.TypeCode), reqToken(), bind(api.ApplyDiffPatchFileOptions{}), mustNotBeArchived, context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.ApplyDiffPatch)
m.Group("/contents", func() {
m.Get("", repo.GetContentsList)
- m.Post("", reqToken(), bind(api.ChangeFilesOptions{}), reqRepoBranchWriter, mustNotBeArchived, repo.ChangeFiles)
+ m.Post("", reqToken(), bind(api.ChangeFilesOptions{}), reqRepoBranchWriter, mustNotBeArchived, context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.ChangeFiles)
m.Get("/*", repo.GetContents)
m.Group("/*", func() {
- m.Post("", bind(api.CreateFileOptions{}), reqRepoBranchWriter, mustNotBeArchived, repo.CreateFile)
- m.Put("", bind(api.UpdateFileOptions{}), reqRepoBranchWriter, mustNotBeArchived, repo.UpdateFile)
- m.Delete("", bind(api.DeleteFileOptions{}), reqRepoBranchWriter, mustNotBeArchived, repo.DeleteFile)
+ m.Post("", bind(api.CreateFileOptions{}), reqRepoBranchWriter, mustNotBeArchived, context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.CreateFile)
+ m.Put("", bind(api.UpdateFileOptions{}), reqRepoBranchWriter, mustNotBeArchived, context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.UpdateFile)
+ m.Delete("", bind(api.DeleteFileOptions{}), reqRepoBranchWriter, mustNotBeArchived, context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.DeleteFile)
}, reqToken())
}, reqRepoReader(unit.TypeCode))
m.Get("/signing-key.gpg", misc.SigningKey)
@@ -1291,7 +1355,9 @@ func Routes() *web.Route {
m.Post("", bind(api.UpdateRepoAvatarOption{}), repo.UpdateAvatar)
m.Delete("", repo.DeleteAvatar)
}, reqAdmin(), reqToken())
- }, repoAssignment())
+
+ m.Get("/{ball_type:tarball|zipball|bundle}/*", reqRepoReader(unit.TypeCode), repo.DownloadArchive)
+ }, repoAssignment(), checkTokenPublicOnly())
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryRepository))
// Notifications (requires notifications scope)
@@ -1300,7 +1366,7 @@ func Routes() *web.Route {
m.Combo("/notifications", reqToken()).
Get(notify.ListRepoNotifications).
Put(notify.ReadRepoNotifications)
- }, repoAssignment())
+ }, repoAssignment(), checkTokenPublicOnly())
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryNotification))
// Issue (requires issue scope)
@@ -1326,7 +1392,7 @@ func Routes() *web.Route {
m.Group("/assets", func() {
m.Combo("").
Get(repo.ListIssueCommentAttachments).
- Post(reqToken(), mustNotBeArchived, repo.CreateIssueCommentAttachment)
+ Post(reqToken(), mustNotBeArchived, context.EnforceQuotaAPI(quota_model.LimitSubjectSizeAssetsAttachmentsIssues, context.QuotaTargetRepo), repo.CreateIssueCommentAttachment)
m.Combo("/{attachment_id}").
Get(repo.GetIssueCommentAttachment).
Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueCommentAttachment).
@@ -1378,7 +1444,7 @@ func Routes() *web.Route {
m.Group("/assets", func() {
m.Combo("").
Get(repo.ListIssueAttachments).
- Post(reqToken(), mustNotBeArchived, repo.CreateIssueAttachment)
+ Post(reqToken(), mustNotBeArchived, context.EnforceQuotaAPI(quota_model.LimitSubjectSizeAssetsAttachmentsIssues, context.QuotaTargetRepo), repo.CreateIssueAttachment)
m.Combo("/{attachment_id}").
Get(repo.GetIssueAttachment).
Patch(reqToken(), mustNotBeArchived, bind(api.EditAttachmentOptions{}), repo.EditIssueAttachment).
@@ -1414,33 +1480,40 @@ func Routes() *web.Route {
Patch(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), bind(api.EditMilestoneOption{}), repo.EditMilestone).
Delete(reqToken(), reqRepoWriter(unit.TypeIssues, unit.TypePullRequests), repo.DeleteMilestone)
})
- }, repoAssignment())
+ }, repoAssignment(), checkTokenPublicOnly())
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryIssue))
// NOTE: these are Gitea package management API - see packages.CommonRoutes and packages.DockerContainerRoutes for endpoints that implement package manager APIs
m.Group("/packages/{username}", func() {
- m.Group("/{type}/{name}/{version}", func() {
- m.Get("", reqToken(), packages.GetPackage)
- m.Delete("", reqToken(), reqPackageAccess(perm.AccessModeWrite), packages.DeletePackage)
- m.Get("/files", reqToken(), packages.ListPackageFiles)
+ m.Group("/{type}/{name}", func() {
+ m.Group("/{version}", func() {
+ m.Get("", packages.GetPackage)
+ m.Delete("", reqPackageAccess(perm.AccessModeWrite), packages.DeletePackage)
+ m.Get("/files", packages.ListPackageFiles)
+ })
+
+ m.Post("/-/link/{repo_name}", reqPackageAccess(perm.AccessModeWrite), packages.LinkPackage)
+ m.Post("/-/unlink", reqPackageAccess(perm.AccessModeWrite), packages.UnlinkPackage)
})
- m.Get("/", reqToken(), packages.ListPackages)
- }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryPackage), context.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqPackageAccess(perm.AccessModeRead))
+
+ m.Get("/", packages.ListPackages)
+ }, reqToken(), tokenRequiresScopes(auth_model.AccessTokenScopeCategoryPackage), context.UserAssignmentAPI(), context.PackageAssignmentAPI(), reqPackageAccess(perm.AccessModeRead), checkTokenPublicOnly())
// Organizations
m.Get("/user/orgs", reqToken(), tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser, auth_model.AccessTokenScopeCategoryOrganization), org.ListMyOrgs)
m.Group("/users/{username}/orgs", func() {
m.Get("", reqToken(), org.ListUserOrgs)
m.Get("/{org}/permissions", reqToken(), org.GetUserOrgsPermissions)
- }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser, auth_model.AccessTokenScopeCategoryOrganization), context.UserAssignmentAPI())
+ }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryUser, auth_model.AccessTokenScopeCategoryOrganization), context.UserAssignmentAPI(), checkTokenPublicOnly())
m.Post("/orgs", tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), reqToken(), bind(api.CreateOrgOption{}), org.Create)
m.Get("/orgs", org.GetAll, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization))
m.Group("/orgs/{org}", func() {
m.Combo("").Get(org.Get).
Patch(reqToken(), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit).
Delete(reqToken(), reqOrgOwnership(), org.Delete)
+ m.Post("/rename", reqToken(), reqOrgOwnership(), bind(api.RenameOrgOption{}), org.Rename)
m.Combo("/repos").Get(user.ListOrgRepos).
- Post(reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo)
+ Post(reqToken(), bind(api.CreateRepoOption{}), context.EnforceQuotaAPI(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetOrg), repo.CreateOrgRepo)
m.Group("/members", func() {
m.Get("", reqToken(), org.ListMembers)
m.Combo("/{username}").Get(reqToken(), org.IsMember).
@@ -1482,6 +1555,16 @@ func Routes() *web.Route {
}, reqToken(), reqOrgOwnership())
m.Get("/activities/feeds", org.ListOrgActivityFeeds)
+ if setting.Quota.Enabled {
+ m.Group("/quota", func() {
+ m.Get("", org.GetQuota)
+ m.Get("/check", org.CheckQuota)
+ m.Get("/attachments", org.ListQuotaAttachments)
+ m.Get("/packages", org.ListQuotaPackages)
+ m.Get("/artifacts", org.ListQuotaArtifacts)
+ }, reqToken(), reqOrgOwnership())
+ }
+
m.Group("", func() {
m.Get("/list_blocked", org.ListBlockedUsers)
m.Group("", func() {
@@ -1489,7 +1572,7 @@ func Routes() *web.Route {
m.Put("/unblock/{username}", org.UnblockUser)
}, context.UserAssignmentAPI())
}, reqToken(), reqOrgOwnership())
- }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true))
+ }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(true), checkTokenPublicOnly())
m.Group("/teams/{teamid}", func() {
m.Combo("").Get(reqToken(), org.GetTeam).
Patch(reqToken(), reqOrgOwnership(), bind(api.EditTeamOption{}), org.EditTeam).
@@ -1509,7 +1592,7 @@ func Routes() *web.Route {
Get(reqToken(), org.GetTeamRepo)
})
m.Get("/activities/feeds", org.ListTeamActivityFeeds)
- }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(false, true), reqToken(), reqTeamMembership())
+ }, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryOrganization), orgAssignment(false, true), reqToken(), reqTeamMembership(), checkTokenPublicOnly())
m.Group("/admin", func() {
m.Group("/cron", func() {
@@ -1531,6 +1614,12 @@ func Routes() *web.Route {
m.Post("/orgs", bind(api.CreateOrgOption{}), admin.CreateOrg)
m.Post("/repos", bind(api.CreateRepoOption{}), admin.CreateRepo)
m.Post("/rename", bind(api.RenameUserOption{}), admin.RenameUser)
+ if setting.Quota.Enabled {
+ m.Group("/quota", func() {
+ m.Get("", admin.GetUserQuota)
+ m.Post("/groups", bind(api.SetUserQuotaGroupsOptions{}), admin.SetUserQuotaGroups)
+ })
+ }
}, context.UserAssignmentAPI())
})
m.Group("/emails", func() {
@@ -1551,7 +1640,39 @@ func Routes() *web.Route {
})
m.Group("/runners", func() {
m.Get("/registration-token", admin.GetRegistrationToken)
+ m.Get("/jobs", admin.SearchActionRunJobs)
})
+ if setting.Quota.Enabled {
+ m.Group("/quota", func() {
+ m.Group("/rules", func() {
+ m.Combo("").Get(admin.ListQuotaRules).
+ Post(bind(api.CreateQuotaRuleOptions{}), admin.CreateQuotaRule)
+ m.Combo("/{quotarule}", context.QuotaRuleAssignmentAPI()).
+ Get(admin.GetQuotaRule).
+ Patch(bind(api.EditQuotaRuleOptions{}), admin.EditQuotaRule).
+ Delete(admin.DeleteQuotaRule)
+ })
+ m.Group("/groups", func() {
+ m.Combo("").Get(admin.ListQuotaGroups).
+ Post(bind(api.CreateQuotaGroupOptions{}), admin.CreateQuotaGroup)
+ m.Group("/{quotagroup}", func() {
+ m.Combo("").Get(admin.GetQuotaGroup).
+ Delete(admin.DeleteQuotaGroup)
+ m.Group("/rules", func() {
+ m.Combo("/{quotarule}", context.QuotaRuleAssignmentAPI()).
+ Put(admin.AddRuleToQuotaGroup).
+ Delete(admin.RemoveRuleFromQuotaGroup)
+ })
+ m.Group("/users", func() {
+ m.Get("", admin.ListUsersInQuotaGroup)
+ m.Combo("/{username}", context.UserAssignmentAPI()).
+ Put(admin.AddUserToQuotaGroup).
+ Delete(admin.RemoveUserFromQuotaGroup)
+ })
+ }, context.QuotaGroupAssignmentAPI())
+ })
+ })
+ }
}, tokenRequiresScopes(auth_model.AccessTokenScopeCategoryAdmin), reqToken(), reqSiteAdmin())
m.Group("/topics", func() {
diff --git a/routers/api/v1/misc/gitignore.go b/routers/api/v1/misc/gitignore.go
index dffd771752..ec57038a9b 100644
--- a/routers/api/v1/misc/gitignore.go
+++ b/routers/api/v1/misc/gitignore.go
@@ -6,11 +6,11 @@ package misc
import (
"net/http"
- "code.gitea.io/gitea/modules/options"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/options"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
)
// Shows a list of all Gitignore templates
diff --git a/routers/api/v1/misc/label_templates.go b/routers/api/v1/misc/label_templates.go
index cc11f37626..dad5ee34c1 100644
--- a/routers/api/v1/misc/label_templates.go
+++ b/routers/api/v1/misc/label_templates.go
@@ -6,10 +6,10 @@ package misc
import (
"net/http"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// Shows a list of all Label templates
diff --git a/routers/api/v1/misc/licenses.go b/routers/api/v1/misc/licenses.go
index 2a980f5084..c9b657a890 100644
--- a/routers/api/v1/misc/licenses.go
+++ b/routers/api/v1/misc/licenses.go
@@ -8,12 +8,12 @@ import (
"net/http"
"net/url"
- "code.gitea.io/gitea/modules/options"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/options"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
)
// Returns a list of all License templates
diff --git a/routers/api/v1/misc/markup.go b/routers/api/v1/misc/markup.go
index 9699c79368..e9f03fdd5c 100644
--- a/routers/api/v1/misc/markup.go
+++ b/routers/api/v1/misc/markup.go
@@ -6,12 +6,12 @@ package misc
import (
"net/http"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/context"
)
// Markup render markup document to HTML
@@ -41,7 +41,16 @@ func Markup(ctx *context.APIContext) {
return
}
- common.RenderMarkup(ctx.Base, ctx.Repo, form.Mode, form.Text, form.Context, form.FilePath, form.Wiki)
+ re := common.Renderer{
+ Mode: form.Mode,
+ Text: form.Text,
+ URLPrefix: form.Context,
+ FilePath: form.FilePath,
+ BranchPath: form.BranchPath,
+ IsWiki: form.Wiki,
+ }
+
+ re.RenderMarkup(ctx.Base, ctx.Repo)
}
// Markdown render markdown document to HTML
@@ -76,7 +85,14 @@ func Markdown(ctx *context.APIContext) {
mode = form.Mode
}
- common.RenderMarkup(ctx.Base, ctx.Repo, mode, form.Text, form.Context, "", form.Wiki)
+ re := common.Renderer{
+ Mode: mode,
+ Text: form.Text,
+ URLPrefix: form.Context,
+ IsWiki: form.Wiki,
+ }
+
+ re.RenderMarkup(ctx.Base, ctx.Repo)
}
// MarkdownRaw render raw markdown HTML
diff --git a/routers/api/v1/misc/markup_test.go b/routers/api/v1/misc/markup_test.go
index 5236fd06ae..3335199e12 100644
--- a/routers/api/v1/misc/markup_test.go
+++ b/routers/api/v1/misc/markup_test.go
@@ -10,11 +10,11 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/contexttest"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
)
@@ -76,7 +76,7 @@ func TestAPI_RenderGFM(t *testing.T) {
`,
// Guard wiki sidebar: special syntax
@@ -112,7 +112,7 @@ Here are some links to the most important topics. You can find the full list of
Quick Links
Here are some links to the most important topics. You can find the full list of pages at the sidebar.
Configuration
-
+
`,
}
diff --git a/routers/api/v1/misc/nodeinfo.go b/routers/api/v1/misc/nodeinfo.go
index 9c2a0db8d2..9631de7edd 100644
--- a/routers/api/v1/misc/nodeinfo.go
+++ b/routers/api/v1/misc/nodeinfo.go
@@ -7,20 +7,20 @@ import (
"net/http"
"time"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
)
const cacheKeyNodeInfoUsage = "API_NodeInfoUsage"
-// NodeInfo returns the NodeInfo for the Gitea instance to allow for federation
+// NodeInfo returns the NodeInfo for the Forgejo instance to allow for federation
func NodeInfo(ctx *context.APIContext) {
// swagger:operation GET /nodeinfo miscellaneous getNodeInfo
// ---
- // summary: Returns the nodeinfo of the Gitea application
+ // summary: Returns the nodeinfo of the Forgejo application
// produces:
// - application/json
// responses:
diff --git a/routers/api/v1/misc/signing.go b/routers/api/v1/misc/signing.go
index 24a46c1e70..945df6068f 100644
--- a/routers/api/v1/misc/signing.go
+++ b/routers/api/v1/misc/signing.go
@@ -7,8 +7,8 @@ import (
"fmt"
"net/http"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/context"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/context"
)
// SigningKey returns the public key of the default signing key if it exists
diff --git a/routers/api/v1/misc/version.go b/routers/api/v1/misc/version.go
index e3b43a0e6b..5802c12462 100644
--- a/routers/api/v1/misc/version.go
+++ b/routers/api/v1/misc/version.go
@@ -6,16 +6,16 @@ package misc
import (
"net/http"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
)
// Version shows the version of the Gitea server
func Version(ctx *context.APIContext) {
// swagger:operation GET /version miscellaneous getVersion
// ---
- // summary: Returns the version of the Gitea application
+ // summary: Returns the version of the running application
// produces:
// - application/json
// responses:
diff --git a/routers/api/v1/notify/notifications.go b/routers/api/v1/notify/notifications.go
index 46b3c7f5e7..2e19fa0b9c 100644
--- a/routers/api/v1/notify/notifications.go
+++ b/routers/api/v1/notify/notifications.go
@@ -7,11 +7,11 @@ import (
"net/http"
"strings"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
)
// NewAvailable check if unread notifications exist
diff --git a/routers/api/v1/notify/repo.go b/routers/api/v1/notify/repo.go
index 1744426ee8..64a9654d48 100644
--- a/routers/api/v1/notify/repo.go
+++ b/routers/api/v1/notify/repo.go
@@ -8,11 +8,11 @@ import (
"strings"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
func statusStringToNotificationStatus(status string) activities_model.NotificationStatus {
diff --git a/routers/api/v1/notify/threads.go b/routers/api/v1/notify/threads.go
index 8e12d359cb..57c78f5f15 100644
--- a/routers/api/v1/notify/threads.go
+++ b/routers/api/v1/notify/threads.go
@@ -7,11 +7,11 @@ import (
"fmt"
"net/http"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// GetThread get notification by ID
diff --git a/routers/api/v1/notify/user.go b/routers/api/v1/notify/user.go
index 879f484cce..2b8cc8c112 100644
--- a/routers/api/v1/notify/user.go
+++ b/routers/api/v1/notify/user.go
@@ -7,11 +7,11 @@ import (
"net/http"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListNotifications list users's notification threads
diff --git a/routers/api/v1/org/action.go b/routers/api/v1/org/action.go
index 03a1fa8ccc..0d8550a019 100644
--- a/routers/api/v1/org/action.go
+++ b/routers/api/v1/org/action.go
@@ -7,17 +7,17 @@ import (
"errors"
"net/http"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- secret_model "code.gitea.io/gitea/models/secret"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/shared"
- "code.gitea.io/gitea/routers/api/v1/utils"
- actions_service "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/services/context"
- secret_service "code.gitea.io/gitea/services/secrets"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ secret_model "forgejo.org/models/secret"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/shared"
+ "forgejo.org/routers/api/v1/utils"
+ actions_service "forgejo.org/services/actions"
+ "forgejo.org/services/context"
+ secret_service "forgejo.org/services/secrets"
)
// ListActionsSecrets list an organization's actions secrets
@@ -189,6 +189,31 @@ func (Action) GetRegistrationToken(ctx *context.APIContext) {
shared.GetRegistrationToken(ctx, ctx.Org.Organization.ID, 0)
}
+// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters
+func (Action) SearchActionRunJobs(ctx *context.APIContext) {
+ // swagger:operation GET /orgs/{org}/actions/runners/jobs organization orgSearchRunJobs
+ // ---
+ // summary: Search for organization's action jobs according filter conditions
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: org
+ // in: path
+ // description: name of the organization
+ // type: string
+ // required: true
+ // - name: labels
+ // in: query
+ // description: a comma separated list of run job labels to search for
+ // type: string
+ // responses:
+ // "200":
+ // "$ref": "#/responses/RunJobList"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ shared.GetActionRunJobs(ctx, ctx.Org.Organization.ID, 0)
+}
+
// ListVariables list org-level variables
func (Action) ListVariables(ctx *context.APIContext) {
// swagger:operation GET /orgs/{org}/actions/variables organization getOrgVariablesList
@@ -450,7 +475,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
if opt.Name == "" {
opt.Name = ctx.Params("variablename")
}
- if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value); err != nil {
+ if _, err := actions_service.UpdateVariable(ctx, v.ID, ctx.Org.Organization.ID, 0, opt.Name, opt.Value); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "UpdateVariable", err)
} else {
diff --git a/routers/api/v1/org/avatar.go b/routers/api/v1/org/avatar.go
index f11eb6c1cd..824a9f3495 100644
--- a/routers/api/v1/org/avatar.go
+++ b/routers/api/v1/org/avatar.go
@@ -7,10 +7,10 @@ import (
"encoding/base64"
"net/http"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- user_service "code.gitea.io/gitea/services/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ user_service "forgejo.org/services/user"
)
// UpdateAvatarupdates the Avatar of an Organisation
diff --git a/routers/api/v1/org/hook.go b/routers/api/v1/org/hook.go
index c1dc0519ea..2877acd3c7 100644
--- a/routers/api/v1/org/hook.go
+++ b/routers/api/v1/org/hook.go
@@ -6,11 +6,11 @@ package org
import (
"net/http"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ webhook_service "forgejo.org/services/webhook"
)
// ListHooks list an organziation's webhooks
diff --git a/routers/api/v1/org/label.go b/routers/api/v1/org/label.go
index b5ec54ccf4..172d531229 100644
--- a/routers/api/v1/org/label.go
+++ b/routers/api/v1/org/label.go
@@ -8,13 +8,13 @@ import (
"strconv"
"strings"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/label"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/label"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListLabels list all the labels of an organization
diff --git a/routers/api/v1/org/member.go b/routers/api/v1/org/member.go
index fb66d4c3f5..c6e67b2ab9 100644
--- a/routers/api/v1/org/member.go
+++ b/routers/api/v1/org/member.go
@@ -7,22 +7,23 @@ import (
"net/http"
"net/url"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/user"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models"
+ "forgejo.org/models/organization"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/user"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// listMembers list an organization's members
-func listMembers(ctx *context.APIContext, publicOnly bool) {
+func listMembers(ctx *context.APIContext, isMember bool) {
opts := &organization.FindOrgMembersOpts{
- OrgID: ctx.Org.Organization.ID,
- PublicOnly: publicOnly,
- ListOptions: utils.GetListOptions(ctx),
+ Doer: ctx.Doer,
+ IsDoerMember: isMember,
+ OrgID: ctx.Org.Organization.ID,
+ ListOptions: utils.GetListOptions(ctx),
}
count, err := organization.CountOrgMembers(ctx, opts)
@@ -73,16 +74,19 @@ func ListMembers(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- publicOnly := true
+ var (
+ isMember bool
+ err error
+ )
+
if ctx.Doer != nil {
- isMember, err := ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID)
+ isMember, err = ctx.Org.Organization.IsOrgMember(ctx, ctx.Doer.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "IsOrgMember", err)
return
}
- publicOnly = !isMember && !ctx.Doer.IsAdmin
}
- listMembers(ctx, publicOnly)
+ listMembers(ctx, isMember)
}
// ListPublicMembers list an organization's public members
@@ -112,7 +116,7 @@ func ListPublicMembers(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- listMembers(ctx, true)
+ listMembers(ctx, false)
}
// IsMember check if a user is a member of an organization
diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go
index 9f9483d4ff..fcf2c6b412 100644
--- a/routers/api/v1/org/org.go
+++ b/routers/api/v1/org/org.go
@@ -8,20 +8,21 @@ import (
"fmt"
"net/http"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/optional"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/user"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/org"
- user_service "code.gitea.io/gitea/services/user"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/user"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/org"
+ user_service "forgejo.org/services/user"
)
func listUserOrgs(ctx *context.APIContext, u *user_model.User) {
@@ -68,6 +69,10 @@ func ListMyOrgs(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/OrganizationList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -192,7 +197,7 @@ func GetAll(ctx *context.APIContext) {
// "$ref": "#/responses/OrganizationList"
vMode := []api.VisibleType{api.VisibleTypePublic}
- if ctx.IsSigned {
+ if ctx.IsSigned && !ctx.PublicOnly {
vMode = append(vMode, api.VisibleTypeLimited)
if ctx.Doer.IsAdmin {
vMode = append(vMode, api.VisibleTypePrivate)
@@ -315,6 +320,44 @@ func Get(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, org)
}
+func Rename(ctx *context.APIContext) {
+ // swagger:operation POST /orgs/{org}/rename organization renameOrg
+ // ---
+ // summary: Rename an organization
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: org
+ // in: path
+ // description: existing org name
+ // type: string
+ // required: true
+ // - name: body
+ // in: body
+ // required: true
+ // schema:
+ // "$ref": "#/definitions/RenameOrgOption"
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ form := web.GetForm(ctx).(*api.RenameOrgOption)
+ orgUser := ctx.Org.Organization.AsUser()
+ if err := user_service.RenameUser(ctx, orgUser, form.NewName); err != nil {
+ if user_model.IsErrUserAlreadyExist(err) || db.IsErrNameReserved(err) || db.IsErrNamePatternNotAllowed(err) || db.IsErrNameCharsNotAllowed(err) {
+ ctx.Error(http.StatusUnprocessableEntity, "RenameOrg", err)
+ } else {
+ ctx.ServerError("RenameOrg", err)
+ }
+ return
+ }
+ ctx.Status(http.StatusNoContent)
+}
+
// Edit change an organization's information
func Edit(ctx *context.APIContext) {
// swagger:operation PATCH /orgs/{org} organization orgEdit
@@ -340,13 +383,28 @@ func Edit(ctx *context.APIContext) {
// "$ref": "#/responses/Organization"
// "404":
// "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/error"
form := web.GetForm(ctx).(*api.EditOrgOption)
- if form.Email != "" {
- if err := user_service.ReplacePrimaryEmailAddress(ctx, ctx.Org.Organization.AsUser(), form.Email); err != nil {
- ctx.Error(http.StatusInternalServerError, "ReplacePrimaryEmailAddress", err)
- return
+ if form.Email != nil {
+ if *form.Email == "" {
+ err := user_model.DeletePrimaryEmailAddressOfUser(ctx, ctx.Org.Organization.ID)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "DeletePrimaryEmailAddressOfUser", err)
+ return
+ }
+ ctx.Org.Organization.Email = ""
+ } else {
+ if err := user_service.ReplacePrimaryEmailAddress(ctx, ctx.Org.Organization.AsUser(), *form.Email); err != nil {
+ if validation.IsErrEmailInvalid(err) || validation.IsErrEmailCharIsNotSupported(err) {
+ ctx.Error(http.StatusUnprocessableEntity, "ReplacePrimaryEmailAddress", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "ReplacePrimaryEmailAddress", err)
+ }
+ return
+ }
}
}
diff --git a/routers/api/v1/org/quota.go b/routers/api/v1/org/quota.go
new file mode 100644
index 0000000000..f4f89b0aaf
--- /dev/null
+++ b/routers/api/v1/org/quota.go
@@ -0,0 +1,155 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package org
+
+import (
+ "forgejo.org/routers/api/v1/shared"
+ "forgejo.org/services/context"
+)
+
+// GetQuota returns the quota information for a given organization
+func GetQuota(ctx *context.APIContext) {
+ // swagger:operation GET /orgs/{org}/quota organization orgGetQuota
+ // ---
+ // summary: Get quota information for an organization
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: org
+ // in: path
+ // description: name of the organization
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaInfo"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ shared.GetQuota(ctx, ctx.Org.Organization.ID)
+}
+
+// CheckQuota returns whether the organization in context is over the subject quota
+func CheckQuota(ctx *context.APIContext) {
+ // swagger:operation GET /orgs/{org}/quota/check organization orgCheckQuota
+ // ---
+ // summary: Check if the organization is over quota for a given subject
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: org
+ // in: path
+ // description: name of the organization
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/boolean"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ shared.CheckQuota(ctx, ctx.Org.Organization.ID)
+}
+
+// ListQuotaAttachments lists attachments affecting the organization's quota
+func ListQuotaAttachments(ctx *context.APIContext) {
+ // swagger:operation GET /orgs/{org}/quota/attachments organization orgListQuotaAttachments
+ // ---
+ // summary: List the attachments affecting the organization's quota
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: org
+ // in: path
+ // description: name of the organization
+ // type: string
+ // required: true
+ // - name: page
+ // in: query
+ // description: page number of results to return (1-based)
+ // type: integer
+ // - name: limit
+ // in: query
+ // description: page size of results
+ // type: integer
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaUsedAttachmentList"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ shared.ListQuotaAttachments(ctx, ctx.Org.Organization.ID)
+}
+
+// ListQuotaPackages lists packages affecting the organization's quota
+func ListQuotaPackages(ctx *context.APIContext) {
+ // swagger:operation GET /orgs/{org}/quota/packages organization orgListQuotaPackages
+ // ---
+ // summary: List the packages affecting the organization's quota
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: org
+ // in: path
+ // description: name of the organization
+ // type: string
+ // required: true
+ // - name: page
+ // in: query
+ // description: page number of results to return (1-based)
+ // type: integer
+ // - name: limit
+ // in: query
+ // description: page size of results
+ // type: integer
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaUsedPackageList"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ shared.ListQuotaPackages(ctx, ctx.Org.Organization.ID)
+}
+
+// ListQuotaArtifacts lists artifacts affecting the organization's quota
+func ListQuotaArtifacts(ctx *context.APIContext) {
+ // swagger:operation GET /orgs/{org}/quota/artifacts organization orgListQuotaArtifacts
+ // ---
+ // summary: List the artifacts affecting the organization's quota
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: org
+ // in: path
+ // description: name of the organization
+ // type: string
+ // required: true
+ // - name: page
+ // in: query
+ // description: page number of results to return (1-based)
+ // type: integer
+ // - name: limit
+ // in: query
+ // description: page size of results
+ // type: integer
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaUsedArtifactList"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ shared.ListQuotaArtifacts(ctx, ctx.Org.Organization.ID)
+}
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index da4fc13ea1..680cc19ce8 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -8,22 +8,22 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/models"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- unit_model "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/user"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- org_service "code.gitea.io/gitea/services/org"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/user"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ org_service "forgejo.org/services/org"
+ repo_service "forgejo.org/services/repository"
)
// ListTeams list all the teams of an organization
@@ -91,6 +91,10 @@ func ListUserTeams(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/TeamList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
teams, count, err := organization.SearchTeam(ctx, &organization.SearchTeamOptions{
ListOptions: utils.GetListOptions(ctx),
diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go
index b38aa13167..03057c4feb 100644
--- a/routers/api/v1/packages/package.go
+++ b/routers/api/v1/packages/package.go
@@ -4,15 +4,18 @@
package packages
import (
+ "errors"
"net/http"
- "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/optional"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/packages"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/optional"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ packages_service "forgejo.org/services/packages"
)
// ListPackages gets all packages of an owner
@@ -213,3 +216,122 @@ func ListPackageFiles(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, apiPackageFiles)
}
+
+// LinkPackage sets a repository link for a package
+func LinkPackage(ctx *context.APIContext) {
+ // swagger:operation POST /packages/{owner}/{type}/{name}/-/link/{repo_name} package linkPackage
+ // ---
+ // summary: Link a package to a repository
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the package
+ // type: string
+ // required: true
+ // - name: type
+ // in: path
+ // description: type of the package
+ // type: string
+ // required: true
+ // - name: name
+ // in: path
+ // description: name of the package
+ // type: string
+ // required: true
+ // - name: repo_name
+ // in: path
+ // description: name of the repository to link.
+ // type: string
+ // required: true
+ // responses:
+ // "201":
+ // "$ref": "#/responses/empty"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ pkg, err := packages.GetPackageByName(ctx, ctx.ContextUser.ID, packages.Type(ctx.PathParamRaw("type")), ctx.PathParamRaw("name"))
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ ctx.Error(http.StatusNotFound, "GetPackageByName", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "GetPackageByName", err)
+ }
+ return
+ }
+
+ repo, err := repo_model.GetRepositoryByName(ctx, ctx.ContextUser.ID, ctx.PathParamRaw("repo_name"))
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ ctx.Error(http.StatusNotFound, "GetRepositoryByName", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "GetRepositoryByName", err)
+ }
+ return
+ }
+
+ err = packages_service.LinkToRepository(ctx, pkg, repo, ctx.Doer)
+ if err != nil {
+ switch {
+ case errors.Is(err, util.ErrInvalidArgument):
+ ctx.Error(http.StatusBadRequest, "LinkToRepository", err)
+ case errors.Is(err, util.ErrPermissionDenied):
+ ctx.Error(http.StatusForbidden, "LinkToRepository", err)
+ default:
+ ctx.Error(http.StatusInternalServerError, "LinkToRepository", err)
+ }
+ return
+ }
+ ctx.Status(http.StatusCreated)
+}
+
+// UnlinkPackage sets a repository link for a package
+func UnlinkPackage(ctx *context.APIContext) {
+ // swagger:operation POST /packages/{owner}/{type}/{name}/-/unlink package unlinkPackage
+ // ---
+ // summary: Unlink a package from a repository
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the package
+ // type: string
+ // required: true
+ // - name: type
+ // in: path
+ // description: type of the package
+ // type: string
+ // required: true
+ // - name: name
+ // in: path
+ // description: name of the package
+ // type: string
+ // required: true
+ // responses:
+ // "201":
+ // "$ref": "#/responses/empty"
+ // "404":
+ // "$ref": "#/responses/notFound"
+
+ pkg, err := packages.GetPackageByName(ctx, ctx.ContextUser.ID, packages.Type(ctx.PathParamRaw("type")), ctx.PathParamRaw("name"))
+ if err != nil {
+ if errors.Is(err, util.ErrNotExist) {
+ ctx.Error(http.StatusNotFound, "GetPackageByName", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "GetPackageByName", err)
+ }
+ return
+ }
+
+ err = packages_service.UnlinkFromRepository(ctx, pkg, ctx.Doer)
+ if err != nil {
+ switch {
+ case errors.Is(err, util.ErrPermissionDenied):
+ ctx.Error(http.StatusForbidden, "UnlinkFromRepository", err)
+ case errors.Is(err, util.ErrInvalidArgument):
+ ctx.Error(http.StatusBadRequest, "UnlinkFromRepository", err)
+ default:
+ ctx.Error(http.StatusInternalServerError, "UnlinkFromRepository", err)
+ }
+ return
+ }
+ ctx.Status(http.StatusNoContent)
+}
diff --git a/routers/api/v1/repo/action.go b/routers/api/v1/repo/action.go
index 3e25327ccb..a39d4836e1 100644
--- a/routers/api/v1/repo/action.go
+++ b/routers/api/v1/repo/action.go
@@ -7,18 +7,18 @@ import (
"errors"
"net/http"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- secret_model "code.gitea.io/gitea/models/secret"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/shared"
- "code.gitea.io/gitea/routers/api/v1/utils"
- actions_service "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- secret_service "code.gitea.io/gitea/services/secrets"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ secret_model "forgejo.org/models/secret"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/shared"
+ "forgejo.org/routers/api/v1/utils"
+ actions_service "forgejo.org/services/actions"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ secret_service "forgejo.org/services/secrets"
)
// ListActionsSecrets list an repo's actions secrets
@@ -117,12 +117,11 @@ func (Action) CreateOrUpdateSecret(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- owner := ctx.Repo.Owner
repo := ctx.Repo.Repository
opt := web.GetForm(ctx).(*api.CreateOrUpdateSecretOption)
- _, created, err := secret_service.CreateOrUpdateSecret(ctx, owner.ID, repo.ID, ctx.Params("secretname"), opt.Data)
+ _, created, err := secret_service.CreateOrUpdateSecret(ctx, 0, repo.ID, ctx.Params("secretname"), opt.Data)
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "CreateOrUpdateSecret", err)
@@ -174,10 +173,9 @@ func (Action) DeleteSecret(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- owner := ctx.Repo.Owner
repo := ctx.Repo.Repository
- err := secret_service.DeleteSecretByName(ctx, owner.ID, repo.ID, ctx.Params("secretname"))
+ err := secret_service.DeleteSecretByName(ctx, 0, repo.ID, ctx.Params("secretname"))
if err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "DeleteSecret", err)
@@ -416,7 +414,7 @@ func (Action) UpdateVariable(ctx *context.APIContext) {
if opt.Name == "" {
opt.Name = ctx.Params("variablename")
}
- if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value); err != nil {
+ if _, err := actions_service.UpdateVariable(ctx, v.ID, 0, ctx.Repo.Repository.ID, opt.Name, opt.Value); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "UpdateVariable", err)
} else {
@@ -486,7 +484,7 @@ func (Action) ListVariables(ctx *context.APIContext) {
// GetRegistrationToken returns the token to register repo runners
func (Action) GetRegistrationToken(ctx *context.APIContext) {
- // swagger:operation GET /repos/{owner}/{repo}/runners/registration-token repository repoGetRunnerRegistrationToken
+ // swagger:operation GET /repos/{owner}/{repo}/actions/runners/registration-token repository repoGetRunnerRegistrationToken
// ---
// summary: Get a repository's actions runner registration token
// produces:
@@ -506,7 +504,37 @@ func (Action) GetRegistrationToken(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/RegistrationToken"
- shared.GetRegistrationToken(ctx, ctx.Repo.Repository.OwnerID, ctx.Repo.Repository.ID)
+ shared.GetRegistrationToken(ctx, 0, ctx.Repo.Repository.ID)
+}
+
+// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters
+func (Action) SearchActionRunJobs(ctx *context.APIContext) {
+ // swagger:operation GET /repos/{owner}/{repo}/actions/runners/jobs repository repoSearchRunJobs
+ // ---
+ // summary: Search for repository's action jobs according filter conditions
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: labels
+ // in: query
+ // description: a comma separated list of run job labels to search for
+ // type: string
+ // responses:
+ // "200":
+ // "$ref": "#/responses/RunJobList"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ shared.GetActionRunJobs(ctx, 0, ctx.Repo.Repository.ID)
}
var _ actions_service.API = new(Action)
@@ -612,6 +640,8 @@ func DispatchWorkflow(ctx *context.APIContext) {
// schema:
// "$ref": "#/definitions/DispatchWorkflowOption"
// responses:
+ // "201":
+ // "$ref": "#/responses/DispatchWorkflowRun"
// "204":
// "$ref": "#/responses/empty"
// "404":
@@ -621,10 +651,10 @@ func DispatchWorkflow(ctx *context.APIContext) {
name := ctx.Params("workflowname")
if len(opt.Ref) == 0 {
- ctx.Error(http.StatusBadRequest, "ref", nil)
+ ctx.Error(http.StatusBadRequest, "ref", "ref is empty")
return
} else if len(name) == 0 {
- ctx.Error(http.StatusBadRequest, "workflowname", nil)
+ ctx.Error(http.StatusBadRequest, "workflowname", "workflow name is empty")
return
}
@@ -642,7 +672,8 @@ func DispatchWorkflow(ctx *context.APIContext) {
return opt.Inputs[key]
}
- if err := workflow.Dispatch(ctx, inputGetter, ctx.Repo.Repository, ctx.Doer); err != nil {
+ run, jobs, err := workflow.Dispatch(ctx, inputGetter, ctx.Repo.Repository, ctx.Doer)
+ if err != nil {
if actions_service.IsInputRequiredErr(err) {
ctx.Error(http.StatusBadRequest, "workflow.Dispatch", err)
} else {
@@ -651,5 +682,15 @@ func DispatchWorkflow(ctx *context.APIContext) {
return
}
- ctx.JSON(http.StatusNoContent, nil)
+ workflowRun := &api.DispatchWorkflowRun{
+ ID: run.ID,
+ RunNumber: run.Index,
+ Jobs: jobs,
+ }
+
+ if opt.ReturnRunInfo {
+ ctx.JSON(http.StatusCreated, workflowRun)
+ } else {
+ ctx.JSON(http.StatusNoContent, nil)
+ }
}
diff --git a/routers/api/v1/repo/avatar.go b/routers/api/v1/repo/avatar.go
index 698337ffd2..84aafe764d 100644
--- a/routers/api/v1/repo/avatar.go
+++ b/routers/api/v1/repo/avatar.go
@@ -7,10 +7,10 @@ import (
"encoding/base64"
"net/http"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- repo_service "code.gitea.io/gitea/services/repository"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ repo_service "forgejo.org/services/repository"
)
// UpdateVatar updates the Avatar of an Repo
diff --git a/routers/api/v1/repo/blob.go b/routers/api/v1/repo/blob.go
index 3b116666ea..8ed57d4787 100644
--- a/routers/api/v1/repo/blob.go
+++ b/routers/api/v1/repo/blob.go
@@ -6,8 +6,8 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/services/context"
- files_service "code.gitea.io/gitea/services/repository/files"
+ "forgejo.org/services/context"
+ files_service "forgejo.org/services/repository/files"
)
// GetBlob get the blob of a repository file.
diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go
index 852b7a2ee0..6263360a8e 100644
--- a/routers/api/v1/repo/branch.go
+++ b/routers/api/v1/repo/branch.go
@@ -9,22 +9,22 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/optional"
- repo_module "code.gitea.io/gitea/modules/repository"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- pull_service "code.gitea.io/gitea/services/pull"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/optional"
+ repo_module "forgejo.org/modules/repository"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ pull_service "forgejo.org/services/pull"
+ repo_service "forgejo.org/services/repository"
)
// GetBranch get a branch of a repository
@@ -133,11 +133,6 @@ func DeleteBranch(ctx *context.APIContext) {
branchName := ctx.Params("*")
- if ctx.Repo.Repository.IsEmpty {
- ctx.Error(http.StatusForbidden, "", "Git Repository is empty.")
- return
- }
-
// check whether branches of this repository has been synced
totalNumOfBranches, err := db.Count[git_model.Branch](ctx, git_model.FindBranchOptions{
RepoID: ctx.Repo.Repository.ID,
@@ -210,6 +205,8 @@ func CreateBranch(ctx *context.APIContext) {
// description: The old branch does not exist.
// "409":
// description: The branch with the same name already exists.
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "423":
// "$ref": "#/responses/repoArchivedError"
@@ -396,6 +393,77 @@ func ListBranches(ctx *context.APIContext) {
ctx.JSON(http.StatusOK, apiBranches)
}
+// UpdateBranch updates a repository's branch.
+func UpdateBranch(ctx *context.APIContext) {
+ // swagger:operation PATCH /repos/{owner}/{repo}/branches/{branch} repository repoUpdateBranch
+ // ---
+ // summary: Update a branch
+ // consumes:
+ // - application/json
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: branch
+ // in: path
+ // description: name of the branch
+ // type: string
+ // required: true
+ // - name: body
+ // in: body
+ // schema:
+ // "$ref": "#/definitions/UpdateBranchRepoOption"
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ opt := web.GetForm(ctx).(*api.UpdateBranchRepoOption)
+
+ oldName := ctx.Params("*")
+ repo := ctx.Repo.Repository
+
+ if repo.IsEmpty {
+ ctx.Error(http.StatusNotFound, "", "Git Repository is empty.")
+ return
+ }
+
+ if repo.IsMirror {
+ ctx.Error(http.StatusForbidden, "", "Git Repository is a mirror.")
+ return
+ }
+
+ msg, err := repo_service.RenameBranch(ctx, repo, ctx.Doer, ctx.Repo.GitRepo, oldName, opt.Name)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "RenameBranch", err)
+ return
+ }
+ if msg == "target_exist" {
+ ctx.Error(http.StatusUnprocessableEntity, "", "Cannot rename a branch using the same name or rename to a branch that already exists.")
+ return
+ }
+ if msg == "from_not_exist" {
+ ctx.Error(http.StatusNotFound, "", "Branch doesn't exist.")
+ return
+ }
+
+ ctx.Status(http.StatusNoContent)
+}
+
// GetBranchProtection gets a branch protection
func GetBranchProtection(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/branch_protections/{name} repository repoGetBranchProtection
diff --git a/routers/api/v1/repo/collaborators.go b/routers/api/v1/repo/collaborators.go
index a43a21a88e..3ef7721ef5 100644
--- a/routers/api/v1/repo/collaborators.go
+++ b/routers/api/v1/repo/collaborators.go
@@ -8,18 +8,18 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- repo_module "code.gitea.io/gitea/modules/repository"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ repo_module "forgejo.org/modules/repository"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ repo_service "forgejo.org/services/repository"
)
// ListCollaborators list a repository's collaborators
@@ -82,6 +82,7 @@ func IsCollaborator(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/collaborators/{collaborator} repository repoCheckCollaborator
// ---
// summary: Check if a user is a collaborator of a repository
+ // description: If the user is a collaborator, return 204. If the user is not a collaborator, return 404.
// produces:
// - application/json
// parameters:
@@ -281,11 +282,6 @@ func GetRepoPermissions(ctx *context.APIContext) {
// "403":
// "$ref": "#/responses/forbidden"
- if !ctx.Doer.IsAdmin && ctx.Doer.LoginName != ctx.Params(":collaborator") && !ctx.IsUserRepoAdmin() {
- ctx.Error(http.StatusForbidden, "User", "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own")
- return
- }
-
collaborator, err := user_model.GetUserByName(ctx, ctx.Params(":collaborator"))
if err != nil {
if user_model.IsErrUserNotExist(err) {
@@ -296,6 +292,15 @@ func GetRepoPermissions(ctx *context.APIContext) {
return
}
+ // Only allow the request in any of the following situations:
+ // - The user is the instance admin.
+ // - The user is the repository admin.
+ // - The user is querying the permissions of themselves.
+ if !ctx.IsUserSiteAdmin() && ctx.Doer.ID != collaborator.ID && !ctx.IsUserRepoAdmin() {
+ ctx.Error(http.StatusForbidden, "User", "Only admins can query all permissions, repo admins can query all repo permissions, collaborators can query only their own")
+ return
+ }
+
permission, err := access_model.GetUserRepoPermission(ctx, ctx.Repo.Repository, collaborator)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetUserRepoPermission", err)
diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go
index d06a3b4e49..4221e59f17 100644
--- a/routers/api/v1/repo/commits.go
+++ b/routers/api/v1/repo/commits.go
@@ -10,14 +10,14 @@ import (
"net/http"
"strconv"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// GetSingleCommit get a commit via sha
@@ -195,7 +195,7 @@ func GetAllCommits(ctx *context.APIContext) {
// get commit specified by sha
baseCommit, err = ctx.Repo.GitRepo.GetCommit(sha)
if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetCommit", err)
+ ctx.NotFoundOrServerError("GetCommit", git.IsErrNotExist, err)
return
}
}
@@ -354,7 +354,7 @@ func GetCommitPullRequest(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- pr, err := issues_model.GetPullRequestByMergedCommit(ctx, ctx.Repo.Repository.ID, ctx.Params(":sha"))
+ pr, err := issues_model.GetPullRequestByMergedCommit(ctx, ctx.Repo.Repository.ID, ctx.Params("ref"))
if err != nil {
if issues_model.IsErrPullRequestNotExist(err) {
ctx.Error(http.StatusNotFound, "GetPullRequestByMergedCommit", err)
diff --git a/routers/api/v1/repo/compare.go b/routers/api/v1/repo/compare.go
index 429145c714..9c941ea07f 100644
--- a/routers/api/v1/repo/compare.go
+++ b/routers/api/v1/repo/compare.go
@@ -7,11 +7,11 @@ import (
"net/http"
"strings"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/gitrepo"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/gitrepo"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// CompareDiff compare two branches or commits
@@ -77,6 +77,7 @@ func CompareDiff(ctx *context.APIContext) {
files := ctx.FormString("files") == "" || ctx.FormBool("files")
apiCommits := make([]*api.Commit, 0, len(ci.Commits))
+ apiFiles := []*api.CommitAffectedFiles{}
userCache := make(map[string]*user_model.User)
for i := 0; i < len(ci.Commits); i++ {
apiCommit, err := convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ci.Commits[i], userCache,
@@ -90,10 +91,12 @@ func CompareDiff(ctx *context.APIContext) {
return
}
apiCommits = append(apiCommits, apiCommit)
+ apiFiles = append(apiFiles, apiCommit.Files...)
}
ctx.JSON(http.StatusOK, &api.Compare{
TotalCommits: len(ci.Commits),
Commits: apiCommits,
+ Files: apiFiles,
})
}
diff --git a/routers/api/v1/repo/download.go b/routers/api/v1/repo/download.go
new file mode 100644
index 0000000000..86910123e6
--- /dev/null
+++ b/routers/api/v1/repo/download.go
@@ -0,0 +1,53 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package repo
+
+import (
+ "fmt"
+ "net/http"
+
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/services/context"
+ archiver_service "forgejo.org/services/repository/archiver"
+)
+
+func DownloadArchive(ctx *context.APIContext) {
+ var tp git.ArchiveType
+ switch ballType := ctx.Params("ball_type"); ballType {
+ case "tarball":
+ tp = git.TARGZ
+ case "zipball":
+ tp = git.ZIP
+ case "bundle":
+ tp = git.BUNDLE
+ default:
+ ctx.Error(http.StatusBadRequest, "", fmt.Sprintf("Unknown archive type: %s", ballType))
+ return
+ }
+
+ if ctx.Repo.GitRepo == nil {
+ gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "OpenRepository", err)
+ return
+ }
+ ctx.Repo.GitRepo = gitRepo
+ defer gitRepo.Close()
+ }
+
+ r, err := archiver_service.NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, ctx.Params("*"), tp)
+ if err != nil {
+ ctx.ServerError("NewRequest", err)
+ return
+ }
+
+ archive, err := r.Await(ctx)
+ if err != nil {
+ ctx.ServerError("archive.Await", err)
+ return
+ }
+
+ download(ctx, r.GetArchiveName(), archive)
+}
diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go
index 34ccc929a5..fb71d76388 100644
--- a/routers/api/v1/repo/file.go
+++ b/routers/api/v1/repo/file.go
@@ -11,27 +11,26 @@ import (
"fmt"
"io"
"net/http"
- "path"
"strings"
"time"
- "code.gitea.io/gitea/models"
- git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/services/context"
- archiver_service "code.gitea.io/gitea/services/repository/archiver"
- files_service "code.gitea.io/gitea/services/repository/files"
+ "forgejo.org/models"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/context"
+ archiver_service "forgejo.org/services/repository/archiver"
+ files_service "forgejo.org/services/repository/files"
)
const (
@@ -45,7 +44,7 @@ func GetRawFile(ctx *context.APIContext) {
// ---
// summary: Get a file from a repository
// produces:
- // - application/json
+ // - application/octet-stream
// parameters:
// - name: owner
// in: path
@@ -70,6 +69,8 @@ func GetRawFile(ctx *context.APIContext) {
// responses:
// 200:
// description: Returns raw file content.
+ // schema:
+ // type: file
// "404":
// "$ref": "#/responses/notFound"
@@ -96,6 +97,8 @@ func GetRawFileOrLFS(ctx *context.APIContext) {
// swagger:operation GET /repos/{owner}/{repo}/media/{filepath} repository repoGetRawFileOrLFS
// ---
// summary: Get a file or it's LFS object from a repository
+ // produces:
+ // - application/octet-stream
// parameters:
// - name: owner
// in: path
@@ -120,6 +123,8 @@ func GetRawFileOrLFS(ctx *context.APIContext) {
// responses:
// 200:
// description: Returns raw file content.
+ // schema:
+ // type: file
// "404":
// "$ref": "#/responses/notFound"
@@ -208,7 +213,7 @@ func GetRawFileOrLFS(ctx *context.APIContext) {
if setting.LFS.Storage.MinioConfig.ServeDirect {
// If we have a signed url (S3, object storage), redirect to this directly.
- u, err := storage.LFS.URL(pointer.RelativePath(), blob.Name())
+ u, err := storage.LFS.URL(pointer.RelativePath(), blob.Name(), nil)
if u != nil && err == nil {
ctx.Redirect(u.String())
return
@@ -241,19 +246,14 @@ func getBlobForEntry(ctx *context.APIContext) (blob *git.Blob, entry *git.TreeEn
return nil, nil, nil
}
- info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:])
+ latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath)
if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetCommitsInfo", err)
+ ctx.Error(http.StatusInternalServerError, "GetTreePathLatestCommit", err)
return nil, nil, nil
}
+ when := &latestCommit.Committer.When
- if len(info) == 1 {
- // Not Modified
- lastModified = &info[0].Commit.Committer.When
- }
- blob = entry.Blob()
-
- return blob, entry, lastModified
+ return entry.Blob(), entry, when
}
// GetArchive get archive of a repository
@@ -302,7 +302,13 @@ func GetArchive(ctx *context.APIContext) {
func archiveDownload(ctx *context.APIContext) {
uri := ctx.Params("*")
- aReq, err := archiver_service.NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
+ ext, tp, err := archiver_service.ParseFileName(uri)
+ if err != nil {
+ ctx.Error(http.StatusBadRequest, "ParseFileName", err)
+ return
+ }
+
+ aReq, err := archiver_service.NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp)
if err != nil {
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
ctx.Error(http.StatusBadRequest, "unknown archive format", err)
@@ -328,14 +334,17 @@ func download(ctx *context.APIContext, archiveName string, archiver *repo_model.
// Add nix format link header so tarballs lock correctly:
// https://github.com/nixos/nix/blob/56763ff918eb308db23080e560ed2ea3e00c80a7/doc/manual/src/protocols/tarball-fetcher.md
- ctx.Resp.Header().Add("Link", fmt.Sprintf("<%s/archive/%s.tar.gz?rev=%s>; rel=\"immutable\"",
+ ctx.Resp.Header().Add("Link", fmt.Sprintf(`<%s/archive/%s.%s?rev=%s>; rel="immutable"`,
ctx.Repo.Repository.APIURL(),
- archiver.CommitID, archiver.CommitID))
+ archiver.CommitID,
+ archiver.Type.String(),
+ archiver.CommitID,
+ ))
rPath := archiver.RelativePath()
if setting.RepoArchive.Storage.MinioConfig.ServeDirect {
// If we have a signed url (S3, object storage), redirect to this directly.
- u, err := storage.RepoArchives.URL(rPath, downloadName)
+ u, err := storage.RepoArchives.URL(rPath, downloadName, nil)
if u != nil && err == nil {
ctx.Redirect(u.String())
return
@@ -471,6 +480,8 @@ func ChangeFiles(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/error"
// "423":
@@ -573,6 +584,8 @@ func CreateFile(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/error"
// "423":
@@ -671,6 +684,8 @@ func UpdateFile(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/error"
// "423":
@@ -836,6 +851,8 @@ func DeleteFile(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "404":
// "$ref": "#/responses/error"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "423":
// "$ref": "#/responses/repoArchivedError"
diff --git a/routers/api/v1/repo/flags.go b/routers/api/v1/repo/flags.go
index ac5cb2e6d6..46af528f0f 100644
--- a/routers/api/v1/repo/flags.go
+++ b/routers/api/v1/repo/flags.go
@@ -6,9 +6,9 @@ package repo
import (
"net/http"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
)
func ListFlags(ctx *context.APIContext) {
diff --git a/routers/api/v1/repo/fork.go b/routers/api/v1/repo/fork.go
index 212cc7a93b..edb85cf54f 100644
--- a/routers/api/v1/repo/fork.go
+++ b/routers/api/v1/repo/fork.go
@@ -9,18 +9,19 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ repo_service "forgejo.org/services/repository"
)
// ListForks list a repository's forks
@@ -55,7 +56,7 @@ func ListForks(ctx *context.APIContext) {
// "404":
// "$ref": "#/responses/notFound"
- forks, err := repo_model.GetForks(ctx, ctx.Repo.Repository, utils.GetListOptions(ctx))
+ forks, total, err := repo_model.GetForks(ctx, ctx.Repo.Repository, ctx.Doer, utils.GetListOptions(ctx))
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetForks", err)
return
@@ -70,7 +71,7 @@ func ListForks(ctx *context.APIContext) {
apiForks[i] = convert.ToRepo(ctx, fork, permission)
}
- ctx.SetTotalCountHeader(int64(ctx.Repo.Repository.NumForks))
+ ctx.SetTotalCountHeader(total)
ctx.JSON(http.StatusOK, apiForks)
}
@@ -105,6 +106,8 @@ func CreateFork(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
// "409":
// description: The repository with the same name already exists.
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
@@ -134,6 +137,10 @@ func CreateFork(ctx *context.APIContext) {
forker = org.AsUser()
}
+ if !ctx.CheckQuota(quota_model.LimitSubjectSizeReposAll, forker.ID, forker.Name) {
+ return
+ }
+
var name string
if form.Name == nil {
name = repo.Name
@@ -141,16 +148,16 @@ func CreateFork(ctx *context.APIContext) {
name = *form.Name
}
- fork, err := repo_service.ForkRepository(ctx, ctx.Doer, forker, repo_service.ForkRepoOptions{
+ fork, err := repo_service.ForkRepositoryAndUpdates(ctx, ctx.Doer, forker, repo_service.ForkRepoOptions{
BaseRepo: repo,
Name: name,
Description: repo.Description,
})
if err != nil {
if errors.Is(err, util.ErrAlreadyExist) || repo_model.IsErrReachLimitOfRepo(err) {
- ctx.Error(http.StatusConflict, "ForkRepository", err)
+ ctx.Error(http.StatusConflict, "ForkRepositoryAndUpdates", err)
} else {
- ctx.Error(http.StatusInternalServerError, "ForkRepository", err)
+ ctx.Error(http.StatusInternalServerError, "ForkRepositoryAndUpdates", err)
}
return
}
diff --git a/routers/api/v1/repo/git_hook.go b/routers/api/v1/repo/git_hook.go
index 26ae84d08d..31957c8b4d 100644
--- a/routers/api/v1/repo/git_hook.go
+++ b/routers/api/v1/repo/git_hook.go
@@ -6,11 +6,11 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/modules/git"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/modules/git"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListGitHooks list all Git hooks of a repository
diff --git a/routers/api/v1/repo/git_ref.go b/routers/api/v1/repo/git_ref.go
index 54da5eeaa7..b2e52ad95d 100644
--- a/routers/api/v1/repo/git_ref.go
+++ b/routers/api/v1/repo/git_ref.go
@@ -7,10 +7,10 @@ import (
"net/http"
"net/url"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
)
// GetGitAllRefs get ref or an list all the refs of a repository
diff --git a/routers/api/v1/repo/hook.go b/routers/api/v1/repo/hook.go
index ffd2313591..5d277604b8 100644
--- a/routers/api/v1/repo/hook.go
+++ b/routers/api/v1/repo/hook.go
@@ -7,19 +7,19 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- webhook_module "code.gitea.io/gitea/modules/webhook"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ "forgejo.org/models/webhook"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ webhook_module "forgejo.org/modules/webhook"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ webhook_service "forgejo.org/services/webhook"
)
// ListHooks list all hooks of a repository
diff --git a/routers/api/v1/repo/hook_test.go b/routers/api/v1/repo/hook_test.go
index 37cf61c1ed..77c86388f5 100644
--- a/routers/api/v1/repo/hook_test.go
+++ b/routers/api/v1/repo/hook_test.go
@@ -7,9 +7,9 @@ import (
"net/http"
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/services/contexttest"
+ "forgejo.org/models/unittest"
+ "forgejo.org/models/webhook"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
)
@@ -19,9 +19,11 @@ func TestTestHook(t *testing.T) {
ctx, _ := contexttest.MockAPIContext(t, "user2/repo1/wiki/_pages")
ctx.SetParams(":id", "1")
- contexttest.LoadRepo(t, ctx, 1)
- contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
+ contexttest.LoadRepo(t, ctx, 1)
+ contexttest.LoadGitRepo(t, ctx)
+ defer ctx.Repo.GitRepo.Close()
+ contexttest.LoadRepoCommit(t, ctx)
TestHook(ctx)
assert.EqualValues(t, http.StatusNoContent, ctx.Resp.Status())
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index 8f9b598c0b..5495c4a6ba 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -12,23 +12,23 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- issue_service "code.gitea.io/gitea/services/issue"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ issue_indexer "forgejo.org/modules/indexer/issues"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ issue_service "forgejo.org/services/issue"
)
// SearchIssues searches for issues across the repositories that the user has access to
@@ -41,80 +41,93 @@ func SearchIssues(ctx *context.APIContext) {
// parameters:
// - name: state
// in: query
- // description: whether issue is open or closed
+ // description: State of the issue
// type: string
+ // enum: [open, closed, all]
+ // default: open
// - name: labels
// in: query
- // description: comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded
+ // description: Comma-separated list of label names. Fetch only issues that have any of these labels. Non existent labels are discarded.
// type: string
// - name: milestones
// in: query
- // description: comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded
+ // description: Comma-separated list of milestone names. Fetch only issues that have any of these milestones. Non existent milestones are discarded.
// type: string
// - name: q
// in: query
- // description: search string
+ // description: Search string
// type: string
// - name: priority_repo_id
// in: query
- // description: repository to prioritize in the results
+ // description: Repository ID to prioritize in the results
// type: integer
// format: int64
// - name: type
// in: query
- // description: filter by type (issues / pulls) if set
+ // description: Filter by issue type
// type: string
+ // enum: [issues, pulls]
// - name: since
// in: query
- // description: Only show notifications updated after the given time. This is a timestamp in RFC 3339 format
+ // description: Only show issues updated after the given time (RFC 3339 format)
// type: string
// format: date-time
- // required: false
// - name: before
// in: query
- // description: Only show notifications updated before the given time. This is a timestamp in RFC 3339 format
+ // description: Only show issues updated before the given time (RFC 3339 format)
// type: string
// format: date-time
- // required: false
// - name: assigned
// in: query
- // description: filter (issues / pulls) assigned to you, default is false
+ // description: Filter issues or pulls assigned to the authenticated user
// type: boolean
+ // default: false
// - name: created
// in: query
- // description: filter (issues / pulls) created by you, default is false
+ // description: Filter issues or pulls created by the authenticated user
// type: boolean
+ // default: false
// - name: mentioned
// in: query
- // description: filter (issues / pulls) mentioning you, default is false
+ // description: Filter issues or pulls mentioning the authenticated user
// type: boolean
+ // default: false
// - name: review_requested
// in: query
- // description: filter pulls requesting your review, default is false
+ // description: Filter pull requests where the authenticated user's review was requested
// type: boolean
+ // default: false
// - name: reviewed
// in: query
- // description: filter pulls reviewed by you, default is false
+ // description: Filter pull requests reviewed by the authenticated user
// type: boolean
+ // default: false
// - name: owner
// in: query
- // description: filter by owner
+ // description: Filter by repository owner
// type: string
// - name: team
// in: query
- // description: filter by team (requires organization owner parameter to be provided)
+ // description: Filter by team (requires organization owner parameter)
// type: string
// - name: page
// in: query
- // description: page number of results to return (1-based)
+ // description: Page number of results to return (1-based)
// type: integer
+ // minimum: 1
+ // default: 1
// - name: limit
// in: query
- // description: page size of results
+ // description: Number of items per page
// type: integer
+ // minimum: 0
// responses:
// "200":
// "$ref": "#/responses/IssueList"
+ // "400":
+ // "$ref": "#/responses/error"
+ // "422":
+ // "$ref": "#/responses/validationError"
before, since, err := context.GetQueryBeforeSince(ctx.Base)
if err != nil {
@@ -149,7 +162,7 @@ func SearchIssues(ctx *context.APIContext) {
Actor: ctx.Doer,
}
if ctx.IsSigned {
- opts.Private = true
+ opts.Private = !ctx.PublicOnly
opts.AllLimited = true
}
if ctx.FormString("owner") != "" {
@@ -384,6 +397,12 @@ func ListIssues(ctx *context.APIContext) {
// in: query
// description: page size of results
// type: integer
+ // - name: sort
+ // in: query
+ // description: Type of sort
+ // type: string
+ // enum: [relevance, latest, oldest, recentupdate, leastupdate, mostcomment, leastcomment, nearduedate, farduedate]
+ // default: latest
// responses:
// "200":
// "$ref": "#/responses/IssueList"
@@ -497,7 +516,7 @@ func ListIssues(ctx *context.APIContext) {
RepoIDs: []int64{ctx.Repo.Repository.ID},
IsPull: isPull,
IsClosed: isClosed,
- SortBy: issue_indexer.SortByCreatedDesc,
+ SortBy: issue_indexer.ParseSortBy(ctx.FormString("sort"), issue_indexer.SortByCreatedDesc),
}
if since != 0 {
searchOpt.UpdatedAfterUnix = optional.Some(since)
@@ -839,10 +858,16 @@ func EditIssue(ctx *context.APIContext) {
if (form.Deadline != nil || form.RemoveDeadline != nil) && canWrite {
var deadlineUnix timeutil.TimeStamp
- if (form.RemoveDeadline == nil || !*form.RemoveDeadline) && !form.Deadline.IsZero() {
- deadline := time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(),
- 23, 59, 59, 0, form.Deadline.Location())
- deadlineUnix = timeutil.TimeStamp(deadline.Unix())
+ if form.RemoveDeadline == nil || !*form.RemoveDeadline {
+ if form.Deadline == nil {
+ ctx.Error(http.StatusBadRequest, "", "The due_date cannot be empty")
+ return
+ }
+ if !form.Deadline.IsZero() {
+ deadline := time.Date(form.Deadline.Year(), form.Deadline.Month(), form.Deadline.Day(),
+ 23, 59, 59, 0, form.Deadline.Location())
+ deadlineUnix = timeutil.TimeStamp(deadline.Unix())
+ }
}
if err := issues_model.UpdateIssueDeadline(ctx, issue, deadlineUnix, ctx.Doer); err != nil {
@@ -893,13 +918,16 @@ func EditIssue(ctx *context.APIContext) {
return
}
}
- if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", api.StateClosed == api.StateType(*form.State)); err != nil {
- if issues_model.IsErrDependenciesLeft(err) {
- ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
+ isClosed := api.StateClosed == api.StateType(*form.State)
+ if issue.IsClosed != isClosed {
+ if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", isClosed); err != nil {
+ if issues_model.IsErrDependenciesLeft(err) {
+ ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this issue because it still has open dependencies")
+ return
+ }
+ ctx.Error(http.StatusInternalServerError, "ChangeStatus", err)
return
}
- ctx.Error(http.StatusInternalServerError, "ChangeStatus", err)
- return
}
}
diff --git a/routers/api/v1/repo/issue_attachment.go b/routers/api/v1/repo/issue_attachment.go
index 70613529c8..0cb1875af1 100644
--- a/routers/api/v1/repo/issue_attachment.go
+++ b/routers/api/v1/repo/issue_attachment.go
@@ -7,17 +7,17 @@ import (
"net/http"
"time"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/attachment"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- "code.gitea.io/gitea/services/convert"
- issue_service "code.gitea.io/gitea/services/issue"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/attachment"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ "forgejo.org/services/convert"
+ issue_service "forgejo.org/services/issue"
)
// GetIssueAttachment gets a single attachment of the issue
@@ -160,6 +160,8 @@ func CreateIssueAttachment(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "404":
// "$ref": "#/responses/error"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
// "423":
@@ -269,6 +271,8 @@ func EditIssueAttachment(ctx *context.APIContext) {
// "$ref": "#/responses/Attachment"
// "404":
// "$ref": "#/responses/error"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "423":
// "$ref": "#/responses/repoArchivedError"
diff --git a/routers/api/v1/repo/issue_comment.go b/routers/api/v1/repo/issue_comment.go
index fbd37e00cb..1b98c154c8 100644
--- a/routers/api/v1/repo/issue_comment.go
+++ b/routers/api/v1/repo/issue_comment.go
@@ -9,18 +9,18 @@ import (
"errors"
"net/http"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/optional"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- issue_service "code.gitea.io/gitea/services/issue"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ issue_service "forgejo.org/services/issue"
)
// ListIssueComments list all the comments of an issue
@@ -62,6 +62,10 @@ func ListIssueComments(ctx *context.APIContext) {
// "$ref": "#/responses/CommentList"
// "404":
// "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+ // "500":
+ // "$ref": "#/responses/internalServerError"
before, since, err := context.GetQueryBeforeSince(ctx.Base)
if err != nil {
@@ -70,6 +74,10 @@ func ListIssueComments(ctx *context.APIContext) {
}
issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
if err != nil {
+ if issues_model.IsErrIssueNotExist(err) {
+ ctx.NotFound("IsErrIssueNotExist", err)
+ return
+ }
ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err)
return
}
@@ -166,6 +174,10 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) {
// "$ref": "#/responses/TimelineList"
// "404":
// "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+ // "500":
+ // "$ref": "#/responses/internalServerError"
before, since, err := context.GetQueryBeforeSince(ctx.Base)
if err != nil {
@@ -174,6 +186,10 @@ func ListIssueCommentsAndTimeline(ctx *context.APIContext) {
}
issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
if err != nil {
+ if issues_model.IsErrIssueNotExist(err) {
+ ctx.NotFound("IsErrIssueNotExist", err)
+ return
+ }
ctx.Error(http.StatusInternalServerError, "GetRawIssueByIndex", err)
return
}
@@ -271,6 +287,10 @@ func ListRepoIssueComments(ctx *context.APIContext) {
// "$ref": "#/responses/CommentList"
// "404":
// "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+ // "500":
+ // "$ref": "#/responses/internalServerError"
before, since, err := context.GetQueryBeforeSince(ctx.Base)
if err != nil {
@@ -378,9 +398,16 @@ func CreateIssueComment(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
// "423":
// "$ref": "#/responses/repoArchivedError"
+ // "500":
+ // "$ref": "#/responses/internalServerError"
+
form := web.GetForm(ctx).(*api.CreateIssueCommentOption)
issue, err := issues_model.GetIssueByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
if err != nil {
+ if issues_model.IsErrIssueNotExist(err) {
+ ctx.NotFound("IsErrIssueNotExist", err)
+ return
+ }
ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err)
return
}
@@ -449,6 +476,8 @@ func GetIssueComment(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
+ // "500":
+ // "$ref": "#/responses/internalServerError"
comment := ctx.Comment
@@ -462,6 +491,11 @@ func GetIssueComment(ctx *context.APIContext) {
return
}
+ if err := comment.LoadAttachments(ctx); err != nil {
+ ctx.Error(http.StatusInternalServerError, "LoadAttachments", err)
+ return
+ }
+
ctx.JSON(http.StatusOK, convert.ToAPIComment(ctx, ctx.Repo.Repository, comment))
}
@@ -506,6 +540,9 @@ func EditIssueComment(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
// "423":
// "$ref": "#/responses/repoArchivedError"
+ // "500":
+ // "$ref": "#/responses/internalServerError"
+
form := web.GetForm(ctx).(*api.EditIssueCommentOption)
editIssueComment(ctx, *form)
}
@@ -555,6 +592,8 @@ func EditIssueCommentDeprecated(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
+ // "500":
+ // "$ref": "#/responses/internalServerError"
form := web.GetForm(ctx).(*api.EditIssueCommentOption)
editIssueComment(ctx, *form)
@@ -621,8 +660,8 @@ func DeleteIssueComment(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
- // "404":
- // "$ref": "#/responses/notFound"
+ // "500":
+ // "$ref": "#/responses/internalServerError"
deleteIssueComment(ctx, issues_model.CommentTypeComment)
}
@@ -660,8 +699,8 @@ func DeleteIssueCommentDeprecated(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "403":
// "$ref": "#/responses/forbidden"
- // "404":
- // "$ref": "#/responses/notFound"
+ // "500":
+ // "$ref": "#/responses/internalServerError"
deleteIssueComment(ctx, issues_model.CommentTypeComment)
}
diff --git a/routers/api/v1/repo/issue_comment_attachment.go b/routers/api/v1/repo/issue_comment_attachment.go
index 4c8516ec83..9edc9a3cb1 100644
--- a/routers/api/v1/repo/issue_comment_attachment.go
+++ b/routers/api/v1/repo/issue_comment_attachment.go
@@ -7,17 +7,17 @@ import (
"net/http"
"time"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/attachment"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- "code.gitea.io/gitea/services/convert"
- issue_service "code.gitea.io/gitea/services/issue"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/attachment"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ "forgejo.org/services/convert"
+ issue_service "forgejo.org/services/issue"
)
// GetIssueCommentAttachment gets a single attachment of the comment
@@ -157,6 +157,8 @@ func CreateIssueCommentAttachment(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "404":
// "$ref": "#/responses/error"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
// "423":
@@ -274,6 +276,8 @@ func EditIssueCommentAttachment(ctx *context.APIContext) {
// "$ref": "#/responses/Attachment"
// "404":
// "$ref": "#/responses/error"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "423":
// "$ref": "#/responses/repoArchivedError"
attach := getIssueCommentAttachmentSafeWrite(ctx)
diff --git a/routers/api/v1/repo/issue_dependency.go b/routers/api/v1/repo/issue_dependency.go
index c40e92c01b..bed1e7ecf9 100644
--- a/routers/api/v1/repo/issue_dependency.go
+++ b/routers/api/v1/repo/issue_dependency.go
@@ -7,15 +7,15 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// GetIssueDependencies list an issue's dependencies
diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go
index ae05544365..85af1149ff 100644
--- a/routers/api/v1/repo/issue_label.go
+++ b/routers/api/v1/repo/issue_label.go
@@ -9,12 +9,12 @@ import (
"net/http"
"reflect"
- issues_model "code.gitea.io/gitea/models/issues"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- issue_service "code.gitea.io/gitea/services/issue"
+ issues_model "forgejo.org/models/issues"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ issue_service "forgejo.org/services/issue"
)
// ListIssueLabels list all the labels of an issue
@@ -350,6 +350,9 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption)
labelIDs = append(labelIDs, int64(rv.Float()))
case reflect.String:
labelNames = append(labelNames, rv.String())
+ default:
+ ctx.Error(http.StatusBadRequest, "InvalidLabel", "a label must be an integer or a string")
+ return nil, nil, fmt.Errorf("invalid label")
}
}
if len(labelIDs) > 0 && len(labelNames) > 0 {
@@ -357,11 +360,20 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption)
return nil, nil, fmt.Errorf("invalid labels")
}
if len(labelNames) > 0 {
- labelIDs, err = issues_model.GetLabelIDsInRepoByNames(ctx, ctx.Repo.Repository.ID, labelNames)
+ repoLabelIDs, err := issues_model.GetLabelIDsInRepoByNames(ctx, ctx.Repo.Repository.ID, labelNames)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetLabelIDsInRepoByNames", err)
return nil, nil, err
}
+ labelIDs = append(labelIDs, repoLabelIDs...)
+ if ctx.Repo.Owner.IsOrganization() {
+ orgLabelIDs, err := issues_model.GetLabelIDsInOrgByNames(ctx, ctx.Repo.Owner.ID, labelNames)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetLabelIDsInOrgByNames", err)
+ return nil, nil, err
+ }
+ labelIDs = append(labelIDs, orgLabelIDs...)
+ }
}
labels, err := issues_model.GetLabelsByIDs(ctx, labelIDs, "id", "repo_id", "org_id", "name", "exclusive")
diff --git a/routers/api/v1/repo/issue_pin.go b/routers/api/v1/repo/issue_pin.go
index af3e06332a..84079ed452 100644
--- a/routers/api/v1/repo/issue_pin.go
+++ b/routers/api/v1/repo/issue_pin.go
@@ -6,10 +6,10 @@ package repo
import (
"net/http"
- issues_model "code.gitea.io/gitea/models/issues"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ issues_model "forgejo.org/models/issues"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// PinIssue pins a issue
diff --git a/routers/api/v1/repo/issue_reaction.go b/routers/api/v1/repo/issue_reaction.go
index c395255c13..2d6218bf46 100644
--- a/routers/api/v1/repo/issue_reaction.go
+++ b/routers/api/v1/repo/issue_reaction.go
@@ -7,14 +7,14 @@ import (
"errors"
"net/http"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- issue_service "code.gitea.io/gitea/services/issue"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ issue_service "forgejo.org/services/issue"
)
// GetIssueCommentReactions list reactions of a comment from an issue
diff --git a/routers/api/v1/repo/issue_stopwatch.go b/routers/api/v1/repo/issue_stopwatch.go
index d9054e8f77..83bcabbe15 100644
--- a/routers/api/v1/repo/issue_stopwatch.go
+++ b/routers/api/v1/repo/issue_stopwatch.go
@@ -7,10 +7,10 @@ import (
"errors"
"net/http"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// StartIssueStopwatch creates a stopwatch for the given issue.
@@ -217,6 +217,10 @@ func GetStopwatches(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/StopWatchList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
sws, err := issues_model.GetUserStopwatches(ctx, ctx.Doer.ID, utils.GetListOptions(ctx))
if err != nil {
diff --git a/routers/api/v1/repo/issue_subscription.go b/routers/api/v1/repo/issue_subscription.go
index 6b29218575..33654dc136 100644
--- a/routers/api/v1/repo/issue_subscription.go
+++ b/routers/api/v1/repo/issue_subscription.go
@@ -7,12 +7,12 @@ import (
"fmt"
"net/http"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// AddIssueSubscription Subscribe user to issue
diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go
index f83855efac..7d88b1b2cd 100644
--- a/routers/api/v1/repo/issue_tracked_time.go
+++ b/routers/api/v1/repo/issue_tracked_time.go
@@ -8,15 +8,15 @@ import (
"net/http"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListTrackedTimes list all the tracked times of an issue
@@ -599,6 +599,10 @@ func ListMyTrackedTimes(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/TrackedTimeList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
opts := &issues_model.FindTrackedTimesOptions{
ListOptions: utils.GetListOptions(ctx),
diff --git a/routers/api/v1/repo/key.go b/routers/api/v1/repo/key.go
index 88444a2625..2abf95a189 100644
--- a/routers/api/v1/repo/key.go
+++ b/routers/api/v1/repo/key.go
@@ -10,18 +10,18 @@ import (
"net/http"
"net/url"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// appendPrivateInformation appends the owner and key type information to api.PublicKey
diff --git a/routers/api/v1/repo/label.go b/routers/api/v1/repo/label.go
index b6eb51fd20..bf722ace34 100644
--- a/routers/api/v1/repo/label.go
+++ b/routers/api/v1/repo/label.go
@@ -8,13 +8,13 @@ import (
"net/http"
"strconv"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/label"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/label"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListLabels list all the labels of a repository
diff --git a/routers/api/v1/repo/language.go b/routers/api/v1/repo/language.go
index f1d5bbe45f..498aac3447 100644
--- a/routers/api/v1/repo/language.go
+++ b/routers/api/v1/repo/language.go
@@ -8,9 +8,9 @@ import (
"net/http"
"strconv"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/context"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/context"
)
type languageResponse []*repo_model.LanguageStat
diff --git a/routers/api/v1/repo/main_test.go b/routers/api/v1/repo/main_test.go
index 451f34d72f..a3655fb76b 100644
--- a/routers/api/v1/repo/main_test.go
+++ b/routers/api/v1/repo/main_test.go
@@ -6,9 +6,9 @@ package repo
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ webhook_service "forgejo.org/services/webhook"
)
func TestMain(m *testing.M) {
diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go
index 14c8c01f4e..75e772dfe2 100644
--- a/routers/api/v1/repo/migrate.go
+++ b/routers/api/v1/repo/migrate.go
@@ -10,27 +10,28 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/migrations"
- notify_service "code.gitea.io/gitea/services/notify"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/migrations"
+ notify_service "forgejo.org/services/notify"
+ repo_service "forgejo.org/services/repository"
)
// Migrate migrate remote git repository to gitea
@@ -54,6 +55,8 @@ func Migrate(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "409":
// description: The repository with the same name already exists.
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
@@ -85,6 +88,10 @@ func Migrate(ctx *context.APIContext) {
return
}
+ if !ctx.CheckQuota(quota_model.LimitSubjectSizeReposAll, repoOwner.ID, repoOwner.Name) {
+ return
+ }
+
if !ctx.Doer.IsAdmin {
if !repoOwner.IsOrganization() && ctx.Doer.ID != repoOwner.ID {
ctx.Error(http.StatusForbidden, "", "Given user is not an organization.")
@@ -211,6 +218,17 @@ func Migrate(ctx *context.APIContext) {
return
}
+ if opts.Releases || opts.Wiki {
+ repoOpt := api.EditRepoOption{
+ HasReleases: &opts.Releases,
+ HasWiki: &opts.Wiki,
+ }
+
+ if err = updateRepoUnits(ctx, repoOwner.Name, repo, repoOpt); err != nil {
+ log.Error("Failed to update units on %s/%s repo. %w", repoOwner.Name, form.RepoName, err)
+ }
+ }
+
log.Trace("Repository migrated: %s/%s", repoOwner.Name, form.RepoName)
ctx.JSON(http.StatusCreated, convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm.AccessModeAdmin}))
}
diff --git a/routers/api/v1/repo/milestone.go b/routers/api/v1/repo/milestone.go
index b9534016e4..7aa9881bc4 100644
--- a/routers/api/v1/repo/milestone.go
+++ b/routers/api/v1/repo/milestone.go
@@ -9,15 +9,15 @@ import (
"strconv"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/optional"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/optional"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListMilestones list milestones for a repository
diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go
index eddd449206..bc48c6acb7 100644
--- a/routers/api/v1/repo/mirror.go
+++ b/routers/api/v1/repo/mirror.go
@@ -9,20 +9,21 @@ import (
"net/http"
"time"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/migrations"
- mirror_service "code.gitea.io/gitea/services/mirror"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/migrations"
+ mirror_service "forgejo.org/services/mirror"
)
// MirrorSync adds a mirrored repository to the sync queue
@@ -50,6 +51,8 @@ func MirrorSync(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
repo := ctx.Repo.Repository
@@ -103,6 +106,8 @@ func PushMirrorSync(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
if !setting.Mirror.Enabled {
ctx.Error(http.StatusBadRequest, "PushMirrorSync", "Mirror feature is disabled")
@@ -279,6 +284,8 @@ func AddPushMirror(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
if !setting.Mirror.Enabled {
ctx.Error(http.StatusBadRequest, "AddPushMirror", "Mirror feature is disabled")
@@ -344,9 +351,19 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro
return
}
+ if mirrorOption.UseSSH && !git.HasSSHExecutable {
+ ctx.Error(http.StatusBadRequest, "CreatePushMirror", "SSH authentication not available.")
+ return
+ }
+
+ if mirrorOption.UseSSH && (mirrorOption.RemoteUsername != "" || mirrorOption.RemotePassword != "") {
+ ctx.Error(http.StatusBadRequest, "CreatePushMirror", "'use_ssh' is mutually exclusive with 'remote_username' and 'remote_passoword'")
+ return
+ }
+
address, err := forms.ParseRemoteAddr(mirrorOption.RemoteAddress, mirrorOption.RemoteUsername, mirrorOption.RemotePassword)
if err == nil {
- err = migrations.IsMigrateURLAllowed(address, ctx.ContextUser)
+ err = migrations.IsPushMirrorURLAllowed(address, ctx.ContextUser)
}
if err != nil {
HandleRemoteAddressError(ctx, err)
@@ -359,7 +376,7 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro
return
}
- remoteAddress, err := util.SanitizeURL(mirrorOption.RemoteAddress)
+ remoteAddress, err := util.SanitizeURL(address)
if err != nil {
ctx.ServerError("SanitizeURL", err)
return
@@ -374,11 +391,29 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro
RemoteAddress: remoteAddress,
}
+ var plainPrivateKey []byte
+ if mirrorOption.UseSSH {
+ publicKey, privateKey, err := util.GenerateSSHKeypair()
+ if err != nil {
+ ctx.ServerError("GenerateSSHKeypair", err)
+ return
+ }
+ plainPrivateKey = privateKey
+ pushMirror.PublicKey = string(publicKey)
+ }
+
if err = db.Insert(ctx, pushMirror); err != nil {
ctx.ServerError("InsertPushMirror", err)
return
}
+ if mirrorOption.UseSSH {
+ if err = pushMirror.SetPrivatekey(ctx, plainPrivateKey); err != nil {
+ ctx.ServerError("SetPrivatekey", err)
+ return
+ }
+ }
+
// if the registration of the push mirrorOption fails remove it from the database
if err = mirror_service.AddPushMirrorRemote(ctx, pushMirror, address); err != nil {
if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: pushMirror.ID, RepoID: pushMirror.RepoID}); err != nil {
diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go
index a4a1d4eab7..87903d9f36 100644
--- a/routers/api/v1/repo/notes.go
+++ b/routers/api/v1/repo/notes.go
@@ -7,10 +7,11 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/modules/git"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/modules/git"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// GetNote Get a note corresponding to a single commit from a repository
@@ -102,3 +103,107 @@ func getNote(ctx *context.APIContext, identifier string) {
apiNote := api.Note{Message: string(note.Message), Commit: cmt}
ctx.JSON(http.StatusOK, apiNote)
}
+
+// SetNote Sets a note corresponding to a single commit from a repository
+func SetNote(ctx *context.APIContext) {
+ // swagger:operation POST /repos/{owner}/{repo}/git/notes/{sha} repository repoSetNote
+ // ---
+ // summary: Set a note corresponding to a single commit from a repository
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: sha
+ // in: path
+ // description: a git ref or commit sha
+ // type: string
+ // required: true
+ // - name: body
+ // in: body
+ // schema:
+ // "$ref": "#/definitions/NoteOptions"
+ // responses:
+ // "200":
+ // "$ref": "#/responses/Note"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+ sha := ctx.Params(":sha")
+ if !git.IsValidRefPattern(sha) {
+ ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha))
+ return
+ }
+
+ form := web.GetForm(ctx).(*api.NoteOptions)
+
+ err := git.SetNote(ctx, ctx.Repo.GitRepo, sha, form.Message, ctx.Doer.Name, ctx.Doer.GetEmail())
+ if err != nil {
+ if git.IsErrNotExist(err) {
+ ctx.NotFound(sha)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "SetNote", err)
+ }
+ return
+ }
+
+ getNote(ctx, sha)
+}
+
+// RemoveNote Removes a note corresponding to a single commit from a repository
+func RemoveNote(ctx *context.APIContext) {
+ // swagger:operation DELETE /repos/{owner}/{repo}/git/notes/{sha} repository repoRemoveNote
+ // ---
+ // summary: Removes a note corresponding to a single commit from a repository
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: sha
+ // in: path
+ // description: a git ref or commit sha
+ // type: string
+ // required: true
+ // responses:
+ // "204":
+ // "$ref": "#/responses/empty"
+ // "404":
+ // "$ref": "#/responses/notFound"
+ // "422":
+ // "$ref": "#/responses/validationError"
+ sha := ctx.Params(":sha")
+ if !git.IsValidRefPattern(sha) {
+ ctx.Error(http.StatusUnprocessableEntity, "no valid ref or sha", fmt.Sprintf("no valid ref or sha: %s", sha))
+ return
+ }
+
+ err := git.RemoveNote(ctx, ctx.Repo.GitRepo, sha)
+ if err != nil {
+ if git.IsErrNotExist(err) {
+ ctx.NotFound(sha)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "RemoveNote", err)
+ }
+ return
+ }
+
+ ctx.Status(http.StatusNoContent)
+}
diff --git a/routers/api/v1/repo/patch.go b/routers/api/v1/repo/patch.go
index 0e0601b7d9..6f35891627 100644
--- a/routers/api/v1/repo/patch.go
+++ b/routers/api/v1/repo/patch.go
@@ -7,14 +7,14 @@ import (
"net/http"
"time"
- "code.gitea.io/gitea/models"
- git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/repository/files"
+ "forgejo.org/models"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/repository/files"
)
// ApplyDiffPatch handles API call for applying a patch
@@ -47,6 +47,8 @@ func ApplyDiffPatch(ctx *context.APIContext) {
// "$ref": "#/responses/FileResponse"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "423":
// "$ref": "#/responses/repoArchivedError"
apiOpts := web.GetForm(ctx).(*api.ApplyDiffPatchFileOptions)
diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go
index 725a33929f..25c85e7531 100644
--- a/routers/api/v1/repo/pull.go
+++ b/routers/api/v1/repo/pull.go
@@ -12,34 +12,35 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models"
- activities_model "code.gitea.io/gitea/models/activities"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- pull_model "code.gitea.io/gitea/models/pull"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/automerge"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/gitdiff"
- issue_service "code.gitea.io/gitea/services/issue"
- notify_service "code.gitea.io/gitea/services/notify"
- pull_service "code.gitea.io/gitea/services/pull"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models"
+ activities_model "forgejo.org/models/activities"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ pull_model "forgejo.org/models/pull"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/automerge"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/gitdiff"
+ issue_service "forgejo.org/services/issue"
+ notify_service "forgejo.org/services/notify"
+ pull_service "forgejo.org/services/pull"
+ repo_service "forgejo.org/services/repository"
)
// ListPullRequests returns a list of all PRs
@@ -52,56 +53,79 @@ func ListPullRequests(ctx *context.APIContext) {
// parameters:
// - name: owner
// in: path
- // description: owner of the repo
+ // description: Owner of the repo
// type: string
// required: true
// - name: repo
// in: path
- // description: name of the repo
+ // description: Name of the repo
// type: string
// required: true
// - name: state
// in: query
- // description: "State of pull request: open or closed (optional)"
+ // description: State of pull request
// type: string
- // enum: [closed, open, all]
+ // enum: [open, closed, all]
+ // default: open
// - name: sort
// in: query
- // description: "Type of sort"
+ // description: Type of sort
// type: string
// enum: [oldest, recentupdate, leastupdate, mostcomment, leastcomment, priority]
// - name: milestone
// in: query
- // description: "ID of the milestone"
+ // description: ID of the milestone
// type: integer
// format: int64
// - name: labels
// in: query
- // description: "Label IDs"
+ // description: Label IDs
// type: array
// collectionFormat: multi
// items:
// type: integer
// format: int64
+ // - name: poster
+ // in: query
+ // description: Filter by pull request author
+ // type: string
// - name: page
// in: query
- // description: page number of results to return (1-based)
+ // description: Page number of results to return (1-based)
// type: integer
+ // minimum: 1
+ // default: 1
// - name: limit
// in: query
- // description: page size of results
+ // description: Page size of results
// type: integer
+ // minimum: 0
// responses:
// "200":
// "$ref": "#/responses/PullRequestList"
// "404":
// "$ref": "#/responses/notFound"
+ // "500":
+ // "$ref": "#/responses/error"
labelIDs, err := base.StringsToInt64s(ctx.FormStrings("labels"))
if err != nil {
ctx.Error(http.StatusInternalServerError, "PullRequests", err)
return
}
+ var posterID int64
+ if posterStr := ctx.FormString("poster"); posterStr != "" {
+ poster, err := user_model.GetUserByName(ctx, posterStr)
+ if err != nil {
+ if user_model.IsErrUserNotExist(err) {
+ ctx.Error(http.StatusBadRequest, "Poster not found", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "GetUserByName", err)
+ }
+ return
+ }
+ posterID = poster.ID
+ }
listOptions := utils.GetListOptions(ctx)
prs, maxResults, err := issues_model.PullRequests(ctx, ctx.Repo.Repository.ID, &issues_model.PullRequestsOptions{
ListOptions: listOptions,
@@ -109,6 +133,7 @@ func ListPullRequests(ctx *context.APIContext) {
SortType: ctx.FormTrim("sort"),
Labels: labelIDs,
MilestoneID: ctx.FormInt64("milestone"),
+ PosterID: posterID,
})
if err != nil {
ctx.Error(http.StatusInternalServerError, "PullRequests", err)
@@ -387,6 +412,8 @@ func CreatePullRequest(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
// "409":
// "$ref": "#/responses/error"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
// "423":
@@ -711,13 +738,16 @@ func EditPullRequest(ctx *context.APIContext) {
ctx.Error(http.StatusPreconditionFailed, "MergedPRState", "cannot change state of this pull request, it was already merged")
return
}
- if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", api.StateClosed == api.StateType(*form.State)); err != nil {
- if issues_model.IsErrDependenciesLeft(err) {
- ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this pull request because it still has open dependencies")
+ isClosed := api.StateClosed == api.StateType(*form.State)
+ if issue.IsClosed != isClosed {
+ if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", isClosed); err != nil {
+ if issues_model.IsErrDependenciesLeft(err) {
+ ctx.Error(http.StatusPreconditionFailed, "DependenciesLeft", "cannot close this pull request because it still has open dependencies")
+ return
+ }
+ ctx.Error(http.StatusInternalServerError, "ChangeStatus", err)
return
}
- ctx.Error(http.StatusInternalServerError, "ChangeStatus", err)
- return
}
}
@@ -747,7 +777,7 @@ func EditPullRequest(ctx *context.APIContext) {
// update allow edits
if form.AllowMaintainerEdit != nil {
if err := pull_service.SetAllowEdits(ctx, ctx.Doer, pr, *form.AllowMaintainerEdit); err != nil {
- if errors.Is(pull_service.ErrUserHasNoPermissionForAction, err) {
+ if errors.Is(err, pull_service.ErrUserHasNoPermissionForAction) {
ctx.Error(http.StatusForbidden, "SetAllowEdits", fmt.Sprintf("SetAllowEdits: %s", err))
return
}
@@ -854,6 +884,8 @@ func MergePullRequest(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "409":
// "$ref": "#/responses/error"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "423":
// "$ref": "#/responses/repoArchivedError"
@@ -957,7 +989,7 @@ func MergePullRequest(ctx *context.APIContext) {
}
if form.MergeWhenChecksSucceed {
- scheduled, err := automerge.ScheduleAutoMerge(ctx, ctx.Doer, pr, repo_model.MergeStyle(form.Do), message)
+ scheduled, err := automerge.ScheduleAutoMerge(ctx, ctx.Doer, pr, repo_model.MergeStyle(form.Do), message, form.DeleteBranchAfterMerge)
if err != nil {
if pull_model.IsErrAlreadyScheduledToAutoMerge(err) {
ctx.Error(http.StatusConflict, "ScheduleAutoMerge", err)
@@ -1003,17 +1035,6 @@ func MergePullRequest(ctx *context.APIContext) {
log.Trace("Pull request merged: %d", pr.ID)
if form.DeleteBranchAfterMerge {
- // Don't cleanup when there are other PR's that use this branch as head branch.
- exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch)
- if err != nil {
- ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err)
- return
- }
- if exist {
- ctx.Status(http.StatusOK)
- return
- }
-
var headRepo *git.Repository
if ctx.Repo != nil && ctx.Repo.Repository != nil && ctx.Repo.Repository.ID == pr.HeadRepoID && ctx.Repo.GitRepo != nil {
headRepo = ctx.Repo.GitRepo
@@ -1025,27 +1046,20 @@ func MergePullRequest(ctx *context.APIContext) {
}
defer headRepo.Close()
}
- if err := pull_service.RetargetChildrenOnMerge(ctx, ctx.Doer, pr); err != nil {
- ctx.Error(http.StatusInternalServerError, "RetargetChildrenOnMerge", err)
- return
- }
- if err := repo_service.DeleteBranch(ctx, ctx.Doer, pr.HeadRepo, headRepo, pr.HeadBranch); err != nil {
+
+ if err := repo_service.DeleteBranchAfterMerge(ctx, ctx.Doer, pr, headRepo); err != nil {
switch {
- case git.IsErrBranchNotExist(err):
- ctx.NotFound(err)
case errors.Is(err, repo_service.ErrBranchIsDefault):
- ctx.Error(http.StatusForbidden, "DefaultBranch", fmt.Errorf("can not delete default branch"))
+ ctx.Error(http.StatusForbidden, "DefaultBranch", fmt.Errorf("the head branch is the default branch"))
case errors.Is(err, git_model.ErrBranchIsProtected):
- ctx.Error(http.StatusForbidden, "IsProtectedBranch", fmt.Errorf("branch protected"))
+ ctx.Error(http.StatusForbidden, "IsProtectedBranch", fmt.Errorf("the head branch is protected"))
+ case errors.Is(err, util.ErrPermissionDenied):
+ ctx.Error(http.StatusForbidden, "HeadBranch", fmt.Errorf("insufficient permission to delete head branch"))
default:
- ctx.Error(http.StatusInternalServerError, "DeleteBranch", err)
+ ctx.Error(http.StatusInternalServerError, "DeleteBranchAfterMerge", err)
}
return
}
- if err := issues_model.AddDeletePRBranchComment(ctx, ctx.Doer, pr.BaseRepo, pr.Issue.ID, pr.HeadBranch); err != nil {
- // Do not fail here as branch has already been deleted
- log.Error("DeleteBranch: %v", err)
- }
}
ctx.Status(http.StatusOK)
@@ -1096,18 +1110,38 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
ctx.Repo.PullRequest.SameRepo = isSameRepo
log.Trace("Repo path: %q, base branch: %q, head branch: %q", ctx.Repo.GitRepo.Path, baseBranch, headBranch)
+
// Check if base branch is valid.
- if !ctx.Repo.GitRepo.IsBranchExist(baseBranch) && !ctx.Repo.GitRepo.IsTagExist(baseBranch) {
- ctx.NotFound("BaseNotExist")
- return nil, nil, nil, "", ""
+ baseIsCommit := ctx.Repo.GitRepo.IsCommitExist(baseBranch)
+ baseIsBranch := ctx.Repo.GitRepo.IsBranchExist(baseBranch)
+ baseIsTag := ctx.Repo.GitRepo.IsTagExist(baseBranch)
+ if !baseIsCommit && !baseIsBranch && !baseIsTag {
+ // Check for short SHA usage
+ if baseCommit, _ := ctx.Repo.GitRepo.GetCommit(baseBranch); baseCommit != nil {
+ baseBranch = baseCommit.ID.String()
+ } else {
+ ctx.NotFound("BaseNotExist")
+ return nil, nil, nil, "", ""
+ }
}
// Check if current user has fork of repository or in the same repository.
headRepo := repo_model.GetForkedRepo(ctx, headUser.ID, baseRepo.ID)
if headRepo == nil && !isSameRepo {
- log.Trace("parseCompareInfo[%d]: does not have fork or in same repository", baseRepo.ID)
- ctx.NotFound("GetForkedRepo")
- return nil, nil, nil, "", ""
+ err := baseRepo.GetBaseRepo(ctx)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetBaseRepo", err)
+ return nil, nil, nil, "", ""
+ }
+
+ // Check if baseRepo's base repository is the same as headUser's repository.
+ if baseRepo.BaseRepo == nil || baseRepo.BaseRepo.OwnerID != headUser.ID {
+ log.Trace("parseCompareInfo[%d]: does not have fork or in same repository", baseRepo.ID)
+ ctx.NotFound("GetBaseRepo")
+ return nil, nil, nil, "", ""
+ }
+ // Assign headRepo so it can be used below.
+ headRepo = baseRepo.BaseRepo
}
var headGitRepo *git.Repository
@@ -1161,13 +1195,34 @@ func parseCompareInfo(ctx *context.APIContext, form api.CreatePullRequestOption)
}
// Check if head branch is valid.
- if !headGitRepo.IsBranchExist(headBranch) && !headGitRepo.IsTagExist(headBranch) {
- headGitRepo.Close()
- ctx.NotFound()
- return nil, nil, nil, "", ""
+ headIsCommit := headGitRepo.IsBranchExist(headBranch)
+ headIsBranch := headGitRepo.IsTagExist(headBranch)
+ headIsTag := headGitRepo.IsCommitExist(baseBranch)
+ if !headIsCommit && !headIsBranch && !headIsTag {
+ // Check if headBranch is short sha commit hash
+ if headCommit, _ := headGitRepo.GetCommit(headBranch); headCommit != nil {
+ headBranch = headCommit.ID.String()
+ } else {
+ headGitRepo.Close()
+ ctx.NotFound("IsRefExist", nil)
+ return nil, nil, nil, "", ""
+ }
}
- compareInfo, err := headGitRepo.GetCompareInfo(repo_model.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranch, headBranch, false, false)
+ baseBranchRef := baseBranch
+ if baseIsBranch {
+ baseBranchRef = git.BranchPrefix + baseBranch
+ } else if baseIsTag {
+ baseBranchRef = git.TagPrefix + baseBranch
+ }
+ headBranchRef := headBranch
+ if headIsBranch {
+ headBranchRef = headBranch
+ } else if headIsTag {
+ headBranchRef = headBranch
+ }
+
+ compareInfo, err := headGitRepo.GetCompareInfo(repo_model.RepoPath(baseRepo.Owner.Name, baseRepo.Name), baseBranchRef, headBranchRef, false, false)
if err != nil {
headGitRepo.Close()
ctx.Error(http.StatusInternalServerError, "GetCompareInfo", err)
@@ -1215,6 +1270,8 @@ func UpdatePullRequest(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
// "409":
// "$ref": "#/responses/error"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go
index 6799e43c73..aa4c7318a2 100644
--- a/routers/api/v1/repo/pull_review.go
+++ b/routers/api/v1/repo/pull_review.go
@@ -4,23 +4,22 @@
package repo
import (
- "errors"
"fmt"
"net/http"
"strings"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/gitrepo"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- issue_service "code.gitea.io/gitea/services/issue"
- pull_service "code.gitea.io/gitea/services/pull"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/gitrepo"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ issue_service "forgejo.org/services/issue"
+ pull_service "forgejo.org/services/pull"
)
// ListPullReviews lists all reviews of a pull request
@@ -83,7 +82,6 @@ func ListPullReviews(ctx *context.APIContext) {
opts := issues_model.FindReviewOptions{
ListOptions: utils.GetListOptions(ctx),
- Type: issues_model.ReviewTypeUnknown,
IssueID: pr.IssueID,
}
@@ -520,11 +518,7 @@ func CreatePullReview(ctx *context.APIContext) {
// create review and associate all pending review comments
review, _, err := pull_service.SubmitReview(ctx, ctx.Doer, ctx.Repo.GitRepo, pr.Issue, reviewType, opts.Body, opts.CommitID, nil)
if err != nil {
- if errors.Is(err, pull_service.ErrSubmitReviewOnClosedPR) {
- ctx.Error(http.StatusUnprocessableEntity, "", err)
- } else {
- ctx.Error(http.StatusInternalServerError, "SubmitReview", err)
- }
+ ctx.Error(http.StatusInternalServerError, "SubmitReview", err)
return
}
@@ -612,11 +606,7 @@ func SubmitPullReview(ctx *context.APIContext) {
// create review and associate all pending review comments
review, _, err = pull_service.SubmitReview(ctx, ctx.Doer, ctx.Repo.GitRepo, pr.Issue, reviewType, opts.Body, headCommitID, nil)
if err != nil {
- if errors.Is(err, pull_service.ErrSubmitReviewOnClosedPR) {
- ctx.Error(http.StatusUnprocessableEntity, "", err)
- } else {
- ctx.Error(http.StatusInternalServerError, "SubmitReview", err)
- }
+ ctx.Error(http.StatusInternalServerError, "SubmitReview", err)
return
}
diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go
index 1544a64273..68254a530a 100644
--- a/routers/api/v1/repo/release.go
+++ b/routers/api/v1/repo/release.go
@@ -7,17 +7,18 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- release_service "code.gitea.io/gitea/services/release"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/git"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ release_service "forgejo.org/services/release"
)
// GetRelease get a single release of a repository
@@ -135,6 +136,10 @@ func ListReleases(ctx *context.APIContext) {
// in: query
// description: filter (exclude / include) pre-releases
// type: boolean
+ // - name: q
+ // in: query
+ // description: Search string
+ // type: string
// - name: page
// in: query
// description: page number of results to return (1-based)
@@ -157,6 +162,7 @@ func ListReleases(ctx *context.APIContext) {
IsDraft: ctx.FormOptionalBool("draft"),
IsPreRelease: ctx.FormOptionalBool("pre-release"),
RepoID: ctx.Repo.Repository.ID,
+ Keyword: ctx.FormTrim("q"),
}
releases, err := db.Find[repo_model.Release](ctx, opts)
@@ -247,11 +253,13 @@ func CreateRelease(ctx *context.APIContext) {
IsTag: false,
Repo: ctx.Repo.Repository,
}
- if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, nil, ""); err != nil {
+ if err := release_service.CreateRelease(ctx.Repo.GitRepo, rel, "", nil); err != nil {
if repo_model.IsErrReleaseAlreadyExist(err) {
ctx.Error(http.StatusConflict, "ReleaseAlreadyExist", err)
} else if models.IsErrProtectedTagName(err) {
ctx.Error(http.StatusUnprocessableEntity, "ProtectedTagName", err)
+ } else if git.IsErrNotExist(err) {
+ ctx.Error(http.StatusNotFound, "ErrNotExist", fmt.Errorf("target \"%v\" not found: %w", rel.Target, err))
} else {
ctx.Error(http.StatusInternalServerError, "CreateRelease", err)
}
@@ -274,7 +282,7 @@ func CreateRelease(ctx *context.APIContext) {
rel.Publisher = ctx.Doer
rel.Target = form.Target
- if err = release_service.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, nil, nil, nil, true); err != nil {
+ if err = release_service.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, true, nil); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateRelease", err)
return
}
@@ -351,7 +359,7 @@ func EditRelease(ctx *context.APIContext) {
if form.HideArchiveLinks != nil {
rel.HideArchiveLinks = *form.HideArchiveLinks
}
- if err := release_service.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, nil, nil, nil, false); err != nil {
+ if err := release_service.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, false, nil); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateRelease", err)
return
}
diff --git a/routers/api/v1/repo/release_attachment.go b/routers/api/v1/repo/release_attachment.go
index 59fd83e3a2..ba273a8d2a 100644
--- a/routers/api/v1/repo/release_attachment.go
+++ b/routers/api/v1/repo/release_attachment.go
@@ -5,18 +5,21 @@ package repo
import (
"io"
+ "mime/multipart"
"net/http"
+ "net/url"
+ "path"
"strings"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/attachment"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- "code.gitea.io/gitea/services/convert"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/attachment"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ "forgejo.org/services/convert"
)
func checkReleaseMatchRepo(ctx *context.APIContext, releaseID int64) bool {
@@ -179,11 +182,18 @@ func CreateReleaseAttachment(ctx *context.APIContext) {
// description: name of the attachment
// type: string
// required: false
+ // # There is no good way to specify "either 'attachment' or 'external_url' is required" with OpenAPI
+ // # https://github.com/OAI/OpenAPI-Specification/issues/256
// - name: attachment
// in: formData
- // description: attachment to upload
+ // description: attachment to upload (this parameter is incompatible with `external_url`)
// type: file
// required: false
+ // - name: external_url
+ // in: formData
+ // description: url to external asset (this parameter is incompatible with `attachment`)
+ // type: string
+ // required: false
// responses:
// "201":
// "$ref": "#/responses/Attachment"
@@ -191,6 +201,8 @@ func CreateReleaseAttachment(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// Check if attachments are enabled
if !setting.Attachment.Enabled {
@@ -205,51 +217,96 @@ func CreateReleaseAttachment(ctx *context.APIContext) {
}
// Get uploaded file from request
- var content io.ReadCloser
- var filename string
- var size int64 = -1
+ var isForm, hasAttachmentFile, hasExternalURL bool
+ externalURL := ctx.FormString("external_url")
+ hasExternalURL = externalURL != ""
+ filename := ctx.FormString("name")
+ isForm = strings.HasPrefix(strings.ToLower(ctx.Req.Header.Get("Content-Type")), "multipart/form-data")
- if strings.HasPrefix(strings.ToLower(ctx.Req.Header.Get("Content-Type")), "multipart/form-data") {
- file, header, err := ctx.Req.FormFile("attachment")
- if err != nil {
- ctx.Error(http.StatusInternalServerError, "GetFile", err)
- return
- }
- defer file.Close()
-
- content = file
- size = header.Size
- filename = header.Filename
- if name := ctx.FormString("name"); name != "" {
- filename = name
- }
+ if isForm {
+ _, _, err := ctx.Req.FormFile("attachment")
+ hasAttachmentFile = err == nil
} else {
- content = ctx.Req.Body
- filename = ctx.FormString("name")
+ hasAttachmentFile = ctx.Req.Body != nil
}
- if filename == "" {
- ctx.Error(http.StatusBadRequest, "CreateReleaseAttachment", "Could not determine name of attachment.")
- return
- }
+ if hasAttachmentFile && hasExternalURL {
+ ctx.Error(http.StatusBadRequest, "DuplicateAttachment", "'attachment' and 'external_url' are mutually exclusive")
+ } else if hasAttachmentFile {
+ var content io.ReadCloser
+ var size int64 = -1
- // Create a new attachment and save the file
- attach, err := attachment.UploadAttachment(ctx, content, setting.Repository.Release.AllowedTypes, size, &repo_model.Attachment{
- Name: filename,
- UploaderID: ctx.Doer.ID,
- RepoID: ctx.Repo.Repository.ID,
- ReleaseID: releaseID,
- })
- if err != nil {
- if upload.IsErrFileTypeForbidden(err) {
- ctx.Error(http.StatusBadRequest, "DetectContentType", err)
+ if isForm {
+ var header *multipart.FileHeader
+ content, header, _ = ctx.Req.FormFile("attachment")
+ size = header.Size
+ defer content.Close()
+ if filename == "" {
+ filename = header.Filename
+ }
+ } else {
+ content = ctx.Req.Body
+ defer content.Close()
+ }
+
+ if filename == "" {
+ ctx.Error(http.StatusBadRequest, "MissingName", "Missing 'name' parameter")
return
}
- ctx.Error(http.StatusInternalServerError, "NewAttachment", err)
- return
- }
- ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach))
+ // Create a new attachment and save the file
+ attach, err := attachment.UploadAttachment(ctx, content, setting.Repository.Release.AllowedTypes, size, &repo_model.Attachment{
+ Name: filename,
+ UploaderID: ctx.Doer.ID,
+ RepoID: ctx.Repo.Repository.ID,
+ ReleaseID: releaseID,
+ })
+ if err != nil {
+ if upload.IsErrFileTypeForbidden(err) {
+ ctx.Error(http.StatusBadRequest, "DetectContentType", err)
+ return
+ }
+ ctx.Error(http.StatusInternalServerError, "NewAttachment", err)
+ return
+ }
+
+ ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach))
+ } else if hasExternalURL {
+ url, err := url.Parse(externalURL)
+ if err != nil {
+ ctx.Error(http.StatusBadRequest, "InvalidExternalURL", err)
+ return
+ }
+
+ if filename == "" {
+ filename = path.Base(url.Path)
+
+ if filename == "." {
+ // Url path is empty
+ filename = url.Host
+ }
+ }
+
+ attach, err := attachment.NewExternalAttachment(ctx, &repo_model.Attachment{
+ Name: filename,
+ UploaderID: ctx.Doer.ID,
+ RepoID: ctx.Repo.Repository.ID,
+ ReleaseID: releaseID,
+ ExternalURL: url.String(),
+ })
+ if err != nil {
+ if repo_model.IsErrInvalidExternalURL(err) {
+ ctx.Error(http.StatusBadRequest, "NewExternalAttachment", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "NewExternalAttachment", err)
+ }
+ return
+ }
+
+ ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach))
+ } else {
+ ctx.Error(http.StatusBadRequest, "MissingAttachment", "One of 'attachment' or 'external_url' is required")
+ }
}
// EditReleaseAttachment updates the given attachment
@@ -293,6 +350,8 @@ func EditReleaseAttachment(ctx *context.APIContext) {
// "$ref": "#/responses/Attachment"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
form := web.GetForm(ctx).(*api.EditAttachmentOptions)
@@ -322,8 +381,21 @@ func EditReleaseAttachment(ctx *context.APIContext) {
attach.Name = form.Name
}
+ if form.DownloadURL != "" {
+ if attach.ExternalURL == "" {
+ ctx.Error(http.StatusBadRequest, "EditAttachment", "existing attachment is not external")
+ return
+ }
+ attach.ExternalURL = form.DownloadURL
+ }
+
if err := repo_model.UpdateAttachment(ctx, attach); err != nil {
- ctx.Error(http.StatusInternalServerError, "UpdateAttachment", attach)
+ if repo_model.IsErrInvalidExternalURL(err) {
+ ctx.Error(http.StatusBadRequest, "UpdateAttachment", err)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "UpdateAttachment", err)
+ }
+ return
}
ctx.JSON(http.StatusCreated, convert.ToAPIAttachment(ctx.Repo.Repository, attach))
}
diff --git a/routers/api/v1/repo/release_tags.go b/routers/api/v1/repo/release_tags.go
index f845fad53b..b27f8584bc 100644
--- a/routers/api/v1/repo/release_tags.go
+++ b/routers/api/v1/repo/release_tags.go
@@ -6,11 +6,11 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/models"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- releaseservice "code.gitea.io/gitea/services/release"
+ "forgejo.org/models"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ releaseservice "forgejo.org/services/release"
)
// GetReleaseByTag get a single release of a repository by tag name
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 05a63bc62b..e8c3965ff3 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -11,32 +11,32 @@ import (
"strings"
"time"
- actions_model "code.gitea.io/gitea/models/actions"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- unit_model "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/label"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/validation"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- actions_service "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/issue"
- repo_service "code.gitea.io/gitea/services/repository"
- wiki_service "code.gitea.io/gitea/services/wiki"
+ actions_model "forgejo.org/models/actions"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/label"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ actions_service "forgejo.org/services/actions"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/issue"
+ repo_service "forgejo.org/services/repository"
+ wiki_service "forgejo.org/services/wiki"
)
// Search repositories via options
@@ -85,7 +85,7 @@ func Search(ctx *context.APIContext) {
// type: boolean
// - name: is_private
// in: query
- // description: show only pubic, private or all repositories (defaults to all)
+ // description: show only public, private or all repositories (defaults to all)
// type: boolean
// - name: template
// in: query
@@ -129,6 +129,11 @@ func Search(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
+ private := ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private"))
+ if ctx.PublicOnly {
+ private = false
+ }
+
opts := &repo_model.SearchRepoOptions{
ListOptions: utils.GetListOptions(ctx),
Actor: ctx.Doer,
@@ -138,7 +143,7 @@ func Search(ctx *context.APIContext) {
TeamID: ctx.FormInt64("team_id"),
TopicOnly: ctx.FormBool("topic"),
Collaborate: optional.None[bool](),
- Private: ctx.IsSigned && (ctx.FormString("private") == "" || ctx.FormBool("private")),
+ Private: private,
Template: optional.None[bool](),
StarredByID: ctx.FormInt64("starredBy"),
IncludeDescription: ctx.FormBool("includeDesc"),
@@ -197,7 +202,6 @@ func Search(ctx *context.APIContext) {
}
}
- var err error
repos, count, err := repo_model.SearchRepository(ctx, opts)
if err != nil {
ctx.JSON(http.StatusInternalServerError, api.SearchError{
@@ -300,8 +304,14 @@ func Create(ctx *context.APIContext) {
// "$ref": "#/responses/Repository"
// "400":
// "$ref": "#/responses/error"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "409":
// description: The repository with the same name already exists.
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
opt := web.GetForm(ctx).(*api.CreateRepoOption)
@@ -346,6 +356,8 @@ func Generate(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
// "409":
// description: The repository with the same name already exists.
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
form := web.GetForm(ctx).(*api.GenerateRepoOption)
@@ -412,6 +424,10 @@ func Generate(ctx *context.APIContext) {
}
}
+ if !ctx.CheckQuota(quota_model.LimitSubjectSizeReposAll, ctxUser.ID, ctxUser.Name) {
+ return
+ }
+
repo, err := repo_service.GenerateRepository(ctx, ctx.Doer, ctxUser, ctx.Repo.Repository, opts)
if err != nil {
if repo_model.IsErrRepoAlreadyExist(err) {
@@ -631,7 +647,7 @@ func Edit(ctx *context.APIContext) {
return
}
- if err := updateRepoUnits(ctx, opts); err != nil {
+ if err := updateRepoUnits(ctx, ctx.Repo.Owner.Name, ctx.Repo.Repository, opts); err != nil {
return
}
@@ -734,10 +750,8 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
if opts.DefaultBranch != nil && repo.DefaultBranch != *opts.DefaultBranch && (repo.IsEmpty || ctx.Repo.GitRepo.IsBranchExist(*opts.DefaultBranch)) {
if !repo.IsEmpty {
if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, *opts.DefaultBranch); err != nil {
- if !git.IsErrUnsupportedVersion(err) {
- ctx.Error(http.StatusInternalServerError, "SetDefaultBranch", err)
- return err
- }
+ ctx.Error(http.StatusInternalServerError, "SetDefaultBranch", err)
+ return err
}
}
repo.DefaultBranch = *opts.DefaultBranch
@@ -765,10 +779,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
}
// updateRepoUnits updates repo units: Issue settings, Wiki settings, PR settings
-func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
- owner := ctx.Repo.Owner
- repo := ctx.Repo.Repository
-
+func updateRepoUnits(ctx *context.APIContext, owner string, repo *repo_model.Repository, opts api.EditRepoOption) error {
var units []repo_model.RepoUnit
var deleteUnitTypes []unit_model.Type
@@ -923,6 +934,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
AllowRebaseUpdate: true,
DefaultDeleteBranchAfterMerge: false,
DefaultMergeStyle: repo_model.MergeStyleMerge,
+ DefaultUpdateStyle: repo_model.UpdateStyleMerge,
DefaultAllowMaintainerEdit: false,
}
} else {
@@ -962,6 +974,9 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
if opts.DefaultMergeStyle != nil {
config.DefaultMergeStyle = repo_model.MergeStyle(*opts.DefaultMergeStyle)
}
+ if opts.DefaultUpdateStyle != nil {
+ config.DefaultUpdateStyle = repo_model.UpdateStyle(*opts.DefaultUpdateStyle)
+ }
if opts.DefaultAllowMaintainerEdit != nil {
config.DefaultAllowMaintainerEdit = *opts.DefaultAllowMaintainerEdit
}
@@ -1027,7 +1042,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error {
}
}
- log.Trace("Repository advanced settings updated: %s/%s", owner.Name, repo.Name)
+ log.Trace("Repository advanced settings updated: %s/%s", owner, repo.Name)
return nil
}
@@ -1047,7 +1062,7 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e
ctx.Error(http.StatusInternalServerError, "ArchiveRepoState", err)
return err
}
- if err := actions_model.CleanRepoScheduleTasks(ctx, repo); err != nil {
+ if err := actions_model.CleanRepoScheduleTasks(ctx, repo, true); err != nil {
log.Error("CleanRepoScheduleTasks for archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
}
log.Trace("Repository was archived: %s/%s", ctx.Repo.Owner.Name, repo.Name)
diff --git a/routers/api/v1/repo/repo_test.go b/routers/api/v1/repo/repo_test.go
index 8d6ca9e3b5..69eeb1cfdf 100644
--- a/routers/api/v1/repo/repo_test.go
+++ b/routers/api/v1/repo/repo_test.go
@@ -7,11 +7,11 @@ import (
"net/http"
"testing"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/contexttest"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
)
diff --git a/routers/api/v1/repo/star.go b/routers/api/v1/repo/star.go
index 99676de119..7a836cd506 100644
--- a/routers/api/v1/repo/star.go
+++ b/routers/api/v1/repo/star.go
@@ -6,11 +6,11 @@ package repo
import (
"net/http"
- repo_model "code.gitea.io/gitea/models/repo"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ repo_model "forgejo.org/models/repo"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListStargazers list a repository's stargazers
diff --git a/routers/api/v1/repo/status.go b/routers/api/v1/repo/status.go
index 9e36ea0aed..f02150f881 100644
--- a/routers/api/v1/repo/status.go
+++ b/routers/api/v1/repo/status.go
@@ -7,14 +7,14 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ commitstatus_service "forgejo.org/services/repository/commitstatus"
)
// NewCommitStatus creates a new CommitStatus
diff --git a/routers/api/v1/repo/subscriber.go b/routers/api/v1/repo/subscriber.go
index 8584182857..37a2bef85c 100644
--- a/routers/api/v1/repo/subscriber.go
+++ b/routers/api/v1/repo/subscriber.go
@@ -6,11 +6,11 @@ package repo
import (
"net/http"
- repo_model "code.gitea.io/gitea/models/repo"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ repo_model "forgejo.org/models/repo"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListSubscribers list a repo's subscribers (i.e. watchers)
diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go
index c050883768..f53a6da811 100644
--- a/routers/api/v1/repo/tag.go
+++ b/routers/api/v1/repo/tag.go
@@ -9,17 +9,17 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- releaseservice "code.gitea.io/gitea/services/release"
+ "forgejo.org/models"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ releaseservice "forgejo.org/services/release"
)
// ListTags list all the tags of a repository
@@ -208,6 +208,8 @@ func CreateTag(ctx *context.APIContext) {
// "$ref": "#/responses/empty"
// "409":
// "$ref": "#/responses/conflict"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
// "423":
diff --git a/routers/api/v1/repo/teams.go b/routers/api/v1/repo/teams.go
index 0ecf3a39d8..4e9d3c40a9 100644
--- a/routers/api/v1/repo/teams.go
+++ b/routers/api/v1/repo/teams.go
@@ -7,11 +7,11 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- org_service "code.gitea.io/gitea/services/org"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models/organization"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ org_service "forgejo.org/services/org"
+ repo_service "forgejo.org/services/repository"
)
// ListTeams list a repository's teams
diff --git a/routers/api/v1/repo/topic.go b/routers/api/v1/repo/topic.go
index 1d8e675bde..daa637936e 100644
--- a/routers/api/v1/repo/topic.go
+++ b/routers/api/v1/repo/topic.go
@@ -7,13 +7,13 @@ import (
"net/http"
"strings"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListTopics returns list of current topics for repo
diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go
index 94c6bc6ded..3b6cb4d3f2 100644
--- a/routers/api/v1/repo/transfer.go
+++ b/routers/api/v1/repo/transfer.go
@@ -8,18 +8,19 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ repo_service "forgejo.org/services/repository"
)
// Transfer transfers the ownership of a repository
@@ -53,6 +54,8 @@ func Transfer(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "422":
// "$ref": "#/responses/validationError"
@@ -76,6 +79,10 @@ func Transfer(ctx *context.APIContext) {
}
}
+ if !ctx.CheckQuota(quota_model.LimitSubjectSizeReposAll, newOwner.ID, newOwner.Name) {
+ return
+ }
+
var teams []*organization.Team
if opts.TeamIDs != nil {
if !newOwner.IsOrganization() {
@@ -162,6 +169,8 @@ func AcceptTransfer(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
err := acceptOrRejectRepoTransfer(ctx, true)
if ctx.Written() {
@@ -233,6 +242,11 @@ func acceptOrRejectRepoTransfer(ctx *context.APIContext, accept bool) error {
}
if accept {
+ recipient := repoTransfer.Recipient
+ if !ctx.CheckQuota(quota_model.LimitSubjectSizeReposAll, recipient.ID, recipient.Name) {
+ return nil
+ }
+
return repo_service.TransferOwnership(ctx, repoTransfer.Doer, repoTransfer.Recipient, ctx.Repo.Repository, repoTransfer.Teams)
}
diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go
index 353a996d5b..af92170abb 100644
--- a/routers/api/v1/repo/tree.go
+++ b/routers/api/v1/repo/tree.go
@@ -6,8 +6,8 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/services/context"
- files_service "code.gitea.io/gitea/services/repository/files"
+ "forgejo.org/services/context"
+ files_service "forgejo.org/services/repository/files"
)
// GetTree get the tree of a repository.
diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go
index 1b92c7bceb..bb4cf0f211 100644
--- a/routers/api/v1/repo/wiki.go
+++ b/routers/api/v1/repo/wiki.go
@@ -9,17 +9,17 @@ import (
"net/http"
"net/url"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- notify_service "code.gitea.io/gitea/services/notify"
- wiki_service "code.gitea.io/gitea/services/wiki"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ notify_service "forgejo.org/services/notify"
+ wiki_service "forgejo.org/services/wiki"
)
// NewWikiPage response for wiki create request
@@ -53,6 +53,8 @@ func NewWikiPage(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "423":
// "$ref": "#/responses/repoArchivedError"
@@ -131,6 +133,8 @@ func EditWikiPage(ctx *context.APIContext) {
// "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
+ // "413":
+ // "$ref": "#/responses/quotaExceeded"
// "423":
// "$ref": "#/responses/repoArchivedError"
diff --git a/routers/api/v1/settings/settings.go b/routers/api/v1/settings/settings.go
index c422315b22..32ef50423c 100644
--- a/routers/api/v1/settings/settings.go
+++ b/routers/api/v1/settings/settings.go
@@ -6,9 +6,9 @@ package settings
import (
"net/http"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
)
// GetGeneralUISettings returns instance's global settings for ui
diff --git a/routers/api/v1/shared/quota.go b/routers/api/v1/shared/quota.go
new file mode 100644
index 0000000000..ceba9fea57
--- /dev/null
+++ b/routers/api/v1/shared/quota.go
@@ -0,0 +1,102 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package shared
+
+import (
+ "net/http"
+
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+)
+
+func GetQuota(ctx *context.APIContext, userID int64) {
+ used, err := quota_model.GetUsedForUser(ctx, userID)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.GetUsedForUser", err)
+ return
+ }
+
+ groups, err := quota_model.GetGroupsForUser(ctx, userID)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.GetGroupsForUser", err)
+ return
+ }
+
+ result := convert.ToQuotaInfo(used, groups, false)
+ ctx.JSON(http.StatusOK, &result)
+}
+
+func CheckQuota(ctx *context.APIContext, userID int64) {
+ subjectQuery := ctx.FormTrim("subject")
+
+ subject, err := quota_model.ParseLimitSubject(subjectQuery)
+ if err != nil {
+ ctx.Error(http.StatusUnprocessableEntity, "quota_model.ParseLimitSubject", err)
+ return
+ }
+
+ ok, err := quota_model.EvaluateForUser(ctx, userID, subject)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.EvaluateForUser", err)
+ return
+ }
+
+ ctx.JSON(http.StatusOK, &ok)
+}
+
+func ListQuotaAttachments(ctx *context.APIContext, userID int64) {
+ opts := utils.GetListOptions(ctx)
+ count, attachments, err := quota_model.GetQuotaAttachmentsForUser(ctx, userID, opts)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetQuotaAttachmentsForUser", err)
+ return
+ }
+
+ result, err := convert.ToQuotaUsedAttachmentList(ctx, *attachments)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "convert.ToQuotaUsedAttachmentList", err)
+ }
+
+ ctx.SetLinkHeader(int(count), opts.PageSize)
+ ctx.SetTotalCountHeader(count)
+ ctx.JSON(http.StatusOK, result)
+}
+
+func ListQuotaPackages(ctx *context.APIContext, userID int64) {
+ opts := utils.GetListOptions(ctx)
+ count, packages, err := quota_model.GetQuotaPackagesForUser(ctx, userID, opts)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetQuotaPackagesForUser", err)
+ return
+ }
+
+ result, err := convert.ToQuotaUsedPackageList(ctx, *packages)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "convert.ToQuotaUsedPackageList", err)
+ }
+
+ ctx.SetLinkHeader(int(count), opts.PageSize)
+ ctx.SetTotalCountHeader(count)
+ ctx.JSON(http.StatusOK, result)
+}
+
+func ListQuotaArtifacts(ctx *context.APIContext, userID int64) {
+ opts := utils.GetListOptions(ctx)
+ count, artifacts, err := quota_model.GetQuotaArtifactsForUser(ctx, userID, opts)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "GetQuotaArtifactsForUser", err)
+ return
+ }
+
+ result, err := convert.ToQuotaUsedArtifactList(ctx, *artifacts)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "convert.ToQuotaUsedArtifactList", err)
+ }
+
+ ctx.SetLinkHeader(int(count), opts.PageSize)
+ ctx.SetTotalCountHeader(count)
+ ctx.JSON(http.StatusOK, result)
+}
diff --git a/routers/api/v1/shared/runners.go b/routers/api/v1/shared/runners.go
index f184786d7d..a7811a95b5 100644
--- a/routers/api/v1/shared/runners.go
+++ b/routers/api/v1/shared/runners.go
@@ -6,10 +6,13 @@ package shared
import (
"errors"
"net/http"
+ "strings"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
)
// RegistrationToken is a string used to register a runner with a server
@@ -30,3 +33,40 @@ func GetRegistrationToken(ctx *context.APIContext, ownerID, repoID int64) {
ctx.JSON(http.StatusOK, RegistrationToken{Token: token.Token})
}
+
+func GetActionRunJobs(ctx *context.APIContext, ownerID, repoID int64) {
+ labels := strings.Split(ctx.FormTrim("labels"), ",")
+
+ total, err := db.Find[actions_model.ActionRunJob](ctx, &actions_model.FindTaskOptions{
+ Status: []actions_model.Status{actions_model.StatusWaiting, actions_model.StatusRunning},
+ OwnerID: ownerID,
+ RepoID: repoID,
+ })
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "CountWaitingActionRunJobs", err)
+ return
+ }
+
+ res := fromRunJobModelToResponse(total, labels)
+
+ ctx.JSON(http.StatusOK, res)
+}
+
+func fromRunJobModelToResponse(job []*actions_model.ActionRunJob, labels []string) []*structs.ActionRunJob {
+ var res []*structs.ActionRunJob
+ for i := range job {
+ if job[i].ItRunsOn(labels) {
+ res = append(res, &structs.ActionRunJob{
+ ID: job[i].ID,
+ RepoID: job[i].RepoID,
+ OwnerID: job[i].OwnerID,
+ Name: job[i].Name,
+ Needs: job[i].Needs,
+ RunsOn: job[i].RunsOn,
+ TaskID: job[i].TaskID,
+ Status: job[i].Status.String(),
+ })
+ }
+ }
+ return res
+}
diff --git a/routers/api/v1/swagger/action.go b/routers/api/v1/swagger/action.go
index 665f4d0b85..6fc58abd76 100644
--- a/routers/api/v1/swagger/action.go
+++ b/routers/api/v1/swagger/action.go
@@ -3,7 +3,7 @@
package swagger
-import api "code.gitea.io/gitea/modules/structs"
+import api "forgejo.org/modules/structs"
// SecretList
// swagger:response SecretList
@@ -32,3 +32,17 @@ type swaggerResponseVariableList struct {
// in:body
Body []api.ActionVariable `json:"body"`
}
+
+// RunJobList is a list of action run jobs
+// swagger:response RunJobList
+type swaggerRunJobList struct {
+ // in:body
+ Body []*api.ActionRunJob `json:"body"`
+}
+
+// DispatchWorkflowRun is a Workflow Run after dispatching
+// swagger:response DispatchWorkflowRun
+type swaggerDispatchWorkflowRun struct {
+ // in:body
+ Body *api.DispatchWorkflowRun `json:"body"`
+}
diff --git a/routers/api/v1/swagger/activity.go b/routers/api/v1/swagger/activity.go
index 95e1ba9035..64466e5e7b 100644
--- a/routers/api/v1/swagger/activity.go
+++ b/routers/api/v1/swagger/activity.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// ActivityFeedsList
diff --git a/routers/api/v1/swagger/activitypub.go b/routers/api/v1/swagger/activitypub.go
index 91341669da..6235009572 100644
--- a/routers/api/v1/swagger/activitypub.go
+++ b/routers/api/v1/swagger/activitypub.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// ActivityPub
diff --git a/routers/api/v1/swagger/app.go b/routers/api/v1/swagger/app.go
index 6a08b11874..7d62b6d494 100644
--- a/routers/api/v1/swagger/app.go
+++ b/routers/api/v1/swagger/app.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// OAuth2Application
diff --git a/routers/api/v1/swagger/cron.go b/routers/api/v1/swagger/cron.go
index 00cfbe0adb..2c26b22441 100644
--- a/routers/api/v1/swagger/cron.go
+++ b/routers/api/v1/swagger/cron.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// CronList
diff --git a/routers/api/v1/swagger/issue.go b/routers/api/v1/swagger/issue.go
index 62458a3424..b2b5de2228 100644
--- a/routers/api/v1/swagger/issue.go
+++ b/routers/api/v1/swagger/issue.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// Issue
diff --git a/routers/api/v1/swagger/key.go b/routers/api/v1/swagger/key.go
index 8390833589..27aa72458d 100644
--- a/routers/api/v1/swagger/key.go
+++ b/routers/api/v1/swagger/key.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// PublicKey
diff --git a/routers/api/v1/swagger/misc.go b/routers/api/v1/swagger/misc.go
index df8a813dfb..df95a94571 100644
--- a/routers/api/v1/swagger/misc.go
+++ b/routers/api/v1/swagger/misc.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// ServerVersion
@@ -62,3 +62,10 @@ type swaggerResponseLabelTemplateInfo struct {
// in:body
Body []api.LabelTemplate `json:"body"`
}
+
+// Boolean
+// swagger:response boolean
+type swaggerResponseBoolean struct {
+ // in:body
+ Body bool `json:"body"`
+}
diff --git a/routers/api/v1/swagger/nodeinfo.go b/routers/api/v1/swagger/nodeinfo.go
index 8650dfa092..227db61648 100644
--- a/routers/api/v1/swagger/nodeinfo.go
+++ b/routers/api/v1/swagger/nodeinfo.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// NodeInfo
diff --git a/routers/api/v1/swagger/notify.go b/routers/api/v1/swagger/notify.go
index 743d807a0a..cd60ef2bcb 100644
--- a/routers/api/v1/swagger/notify.go
+++ b/routers/api/v1/swagger/notify.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// NotificationThread
diff --git a/routers/api/v1/swagger/options.go b/routers/api/v1/swagger/options.go
index c34470030b..4860f10c98 100644
--- a/routers/api/v1/swagger/options.go
+++ b/routers/api/v1/swagger/options.go
@@ -5,9 +5,9 @@
package swagger
import (
- ffed "code.gitea.io/gitea/modules/forgefed"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/forms"
+ ffed "forgejo.org/modules/forgefed"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/services/forms"
)
// not actually a response, just a hack to get go-swagger to include definitions
@@ -101,6 +101,8 @@ type swaggerParameterBodies struct {
// in:body
EditRepoOption api.EditRepoOption
// in:body
+ UpdateBranchRepoOption api.UpdateBranchRepoOption
+ // in:body
TransferRepoOption api.TransferRepoOption
// in:body
CreateForkOption api.CreateForkOption
@@ -214,9 +216,27 @@ type swaggerParameterBodies struct {
// in:body
CreateVariableOption api.CreateVariableOption
+ // in:body
+ RenameOrgOption api.RenameOrgOption
+
// in:body
UpdateVariableOption api.UpdateVariableOption
// in:body
DispatchWorkflowOption api.DispatchWorkflowOption
+
+ // in:body
+ CreateQuotaGroupOptions api.CreateQuotaGroupOptions
+
+ // in:body
+ CreateQuotaRuleOptions api.CreateQuotaRuleOptions
+
+ // in:body
+ EditQuotaRuleOptions api.EditQuotaRuleOptions
+
+ // in:body
+ SetUserQuotaGroupsOptions api.SetUserQuotaGroupsOptions
+
+ // in:body
+ NoteOptions api.NoteOptions
}
diff --git a/routers/api/v1/swagger/org.go b/routers/api/v1/swagger/org.go
index 0105446b00..2d081708a8 100644
--- a/routers/api/v1/swagger/org.go
+++ b/routers/api/v1/swagger/org.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// Organization
diff --git a/routers/api/v1/swagger/package.go b/routers/api/v1/swagger/package.go
index eada12d1ea..dd1b45e9aa 100644
--- a/routers/api/v1/swagger/package.go
+++ b/routers/api/v1/swagger/package.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// Package
diff --git a/routers/api/v1/swagger/quota.go b/routers/api/v1/swagger/quota.go
new file mode 100644
index 0000000000..b2ea59fb31
--- /dev/null
+++ b/routers/api/v1/swagger/quota.go
@@ -0,0 +1,64 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package swagger
+
+import (
+ api "forgejo.org/modules/structs"
+)
+
+// QuotaInfo
+// swagger:response QuotaInfo
+type swaggerResponseQuotaInfo struct {
+ // in:body
+ Body api.QuotaInfo `json:"body"`
+}
+
+// QuotaRuleInfoList
+// swagger:response QuotaRuleInfoList
+type swaggerResponseQuotaRuleInfoList struct {
+ // in:body
+ Body []api.QuotaRuleInfo `json:"body"`
+}
+
+// QuotaRuleInfo
+// swagger:response QuotaRuleInfo
+type swaggerResponseQuotaRuleInfo struct {
+ // in:body
+ Body api.QuotaRuleInfo `json:"body"`
+}
+
+// QuotaUsedAttachmentList
+// swagger:response QuotaUsedAttachmentList
+type swaggerQuotaUsedAttachmentList struct {
+ // in:body
+ Body api.QuotaUsedAttachmentList `json:"body"`
+}
+
+// QuotaUsedPackageList
+// swagger:response QuotaUsedPackageList
+type swaggerQuotaUsedPackageList struct {
+ // in:body
+ Body api.QuotaUsedPackageList `json:"body"`
+}
+
+// QuotaUsedArtifactList
+// swagger:response QuotaUsedArtifactList
+type swaggerQuotaUsedArtifactList struct {
+ // in:body
+ Body api.QuotaUsedArtifactList `json:"body"`
+}
+
+// QuotaGroup
+// swagger:response QuotaGroup
+type swaggerResponseQuotaGroup struct {
+ // in:body
+ Body api.QuotaGroup `json:"body"`
+}
+
+// QuotaGroupList
+// swagger:response QuotaGroupList
+type swaggerResponseQuotaGroupList struct {
+ // in:body
+ Body api.QuotaGroupList `json:"body"`
+}
diff --git a/routers/api/v1/swagger/repo.go b/routers/api/v1/swagger/repo.go
index ca214b4900..445e3417fb 100644
--- a/routers/api/v1/swagger/repo.go
+++ b/routers/api/v1/swagger/repo.go
@@ -4,7 +4,7 @@
package swagger
import (
- api "code.gitea.io/gitea/modules/structs"
+ api "forgejo.org/modules/structs"
)
// Repository
diff --git a/routers/api/v1/swagger/settings.go b/routers/api/v1/swagger/settings.go
index a9466699df..3a07eaf2e0 100644
--- a/routers/api/v1/swagger/settings.go
+++ b/routers/api/v1/swagger/settings.go
@@ -3,7 +3,7 @@
package swagger
-import api "code.gitea.io/gitea/modules/structs"
+import api "forgejo.org/modules/structs"
// GeneralRepoSettings
// swagger:response GeneralRepoSettings
diff --git a/routers/api/v1/swagger/user.go b/routers/api/v1/swagger/user.go
index 37e28664fb..805cfe3df4 100644
--- a/routers/api/v1/swagger/user.go
+++ b/routers/api/v1/swagger/user.go
@@ -4,8 +4,8 @@
package swagger
import (
- activities_model "code.gitea.io/gitea/models/activities"
- api "code.gitea.io/gitea/modules/structs"
+ activities_model "forgejo.org/models/activities"
+ api "forgejo.org/modules/structs"
)
// User
diff --git a/routers/api/v1/user/action.go b/routers/api/v1/user/action.go
index bf78c2c864..dd816cb7ae 100644
--- a/routers/api/v1/user/action.go
+++ b/routers/api/v1/user/action.go
@@ -7,15 +7,15 @@ import (
"errors"
"net/http"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- actions_service "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/services/context"
- secret_service "code.gitea.io/gitea/services/secrets"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ actions_service "forgejo.org/services/actions"
+ "forgejo.org/services/context"
+ secret_service "forgejo.org/services/secrets"
)
// create or update one secret of the user scope
@@ -44,6 +44,10 @@ func CreateOrUpdateSecret(ctx *context.APIContext) {
// description: response when updating a secret
// "400":
// "$ref": "#/responses/error"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -88,6 +92,10 @@ func DeleteSecret(ctx *context.APIContext) {
// description: delete one secret of the user
// "400":
// "$ref": "#/responses/error"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -132,6 +140,10 @@ func CreateVariable(ctx *context.APIContext) {
// description: response when creating a variable
// "400":
// "$ref": "#/responses/error"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -191,6 +203,10 @@ func UpdateVariable(ctx *context.APIContext) {
// description: response when updating a variable
// "400":
// "$ref": "#/responses/error"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -212,7 +228,7 @@ func UpdateVariable(ctx *context.APIContext) {
if opt.Name == "" {
opt.Name = ctx.Params("variablename")
}
- if _, err := actions_service.UpdateVariable(ctx, v.ID, opt.Name, opt.Value); err != nil {
+ if _, err := actions_service.UpdateVariable(ctx, v.ID, ctx.Doer.ID, 0, opt.Name, opt.Value); err != nil {
if errors.Is(err, util.ErrInvalidArgument) {
ctx.Error(http.StatusBadRequest, "UpdateVariable", err)
} else {
@@ -244,6 +260,10 @@ func DeleteVariable(ctx *context.APIContext) {
// description: response when deleting a variable
// "400":
// "$ref": "#/responses/error"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -279,6 +299,10 @@ func GetVariable(ctx *context.APIContext) {
// "$ref": "#/responses/ActionVariable"
// "400":
// "$ref": "#/responses/error"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -326,6 +350,10 @@ func ListVariables(ctx *context.APIContext) {
// "$ref": "#/responses/VariableList"
// "400":
// "$ref": "#/responses/error"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
diff --git a/routers/api/v1/user/app.go b/routers/api/v1/user/app.go
index b61ebac7d0..138ad5a1d2 100644
--- a/routers/api/v1/user/app.go
+++ b/routers/api/v1/user/app.go
@@ -11,13 +11,13 @@ import (
"strconv"
"strings"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// ListAccessTokens list all the access tokens
@@ -46,6 +46,8 @@ func ListAccessTokens(ctx *context.APIContext) {
// "$ref": "#/responses/AccessTokenList"
// "403":
// "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
opts := auth_model.ListAccessTokensOptions{UserID: ctx.ContextUser.ID, ListOptions: utils.GetListOptions(ctx)}
@@ -95,6 +97,8 @@ func CreateAccessToken(ctx *context.APIContext) {
// "$ref": "#/responses/error"
// "403":
// "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
form := web.GetForm(ctx).(*api.CreateAccessTokenOption)
@@ -118,6 +122,10 @@ func CreateAccessToken(ctx *context.APIContext) {
ctx.Error(http.StatusBadRequest, "AccessTokenScope.Normalize", fmt.Errorf("invalid access token scope provided: %w", err))
return
}
+ if scope == "" {
+ ctx.Error(http.StatusBadRequest, "AccessTokenScope", "access token must have a scope")
+ return
+ }
t.Scope = scope
if err := auth_model.NewAccessToken(ctx, t); err != nil {
@@ -129,6 +137,7 @@ func CreateAccessToken(ctx *context.APIContext) {
Token: t.Token,
ID: t.ID,
TokenLastEight: t.TokenLastEight,
+ Scopes: t.Scope.StringSlice(),
})
}
@@ -219,6 +228,10 @@ func CreateOauth2Application(ctx *context.APIContext) {
// "$ref": "#/responses/OAuth2Application"
// "400":
// "$ref": "#/responses/error"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
data := web.GetForm(ctx).(*api.CreateOAuth2ApplicationOptions)
@@ -261,6 +274,10 @@ func ListOauth2Applications(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/OAuth2ApplicationList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
apps, total, err := db.FindAndCount[auth_model.OAuth2Application](ctx, auth_model.FindOAuth2ApplicationsOptions{
ListOptions: utils.GetListOptions(ctx),
@@ -298,6 +315,10 @@ func DeleteOauth2Application(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
appID := ctx.ParamsInt64(":id")
@@ -330,6 +351,10 @@ func GetOauth2Application(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/OAuth2Application"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
appID := ctx.ParamsInt64(":id")
@@ -374,6 +399,10 @@ func UpdateOauth2Application(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/OAuth2Application"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
appID := ctx.ParamsInt64(":id")
diff --git a/routers/api/v1/user/avatar.go b/routers/api/v1/user/avatar.go
index 30ccb63587..453682a37b 100644
--- a/routers/api/v1/user/avatar.go
+++ b/routers/api/v1/user/avatar.go
@@ -7,10 +7,10 @@ import (
"encoding/base64"
"net/http"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- user_service "code.gitea.io/gitea/services/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ user_service "forgejo.org/services/user"
)
// UpdateAvatar updates the Avatar of an User
@@ -28,6 +28,10 @@ func UpdateAvatar(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
form := web.GetForm(ctx).(*api.UpdateUserAvatarOption)
content, err := base64.StdEncoding.DecodeString(form.Image)
@@ -55,6 +59,10 @@ func DeleteAvatar(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
err := user_service.DeleteAvatar(ctx, ctx.Doer)
if err != nil {
ctx.Error(http.StatusInternalServerError, "DeleteAvatar", err)
diff --git a/routers/api/v1/user/email.go b/routers/api/v1/user/email.go
index 33aa851a80..7b18ea97b0 100644
--- a/routers/api/v1/user/email.go
+++ b/routers/api/v1/user/email.go
@@ -7,12 +7,13 @@ import (
"fmt"
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- user_service "code.gitea.io/gitea/services/user"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ user_service "forgejo.org/services/user"
)
// ListEmails list all of the authenticated user's email addresses
@@ -26,6 +27,10 @@ func ListEmails(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/EmailList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
emails, err := user_model.GetEmailAddresses(ctx, ctx.Doer.ID)
if err != nil {
@@ -54,6 +59,10 @@ func AddEmail(ctx *context.APIContext) {
// responses:
// '201':
// "$ref": "#/responses/EmailList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "422":
// "$ref": "#/responses/validationError"
@@ -66,12 +75,12 @@ func AddEmail(ctx *context.APIContext) {
if err := user_service.AddEmailAddresses(ctx, ctx.Doer, form.Emails); err != nil {
if user_model.IsErrEmailAlreadyUsed(err) {
ctx.Error(http.StatusUnprocessableEntity, "", "Email address has been used: "+err.(user_model.ErrEmailAlreadyUsed).Email)
- } else if user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) {
+ } else if validation.IsErrEmailCharIsNotSupported(err) || validation.IsErrEmailInvalid(err) {
email := ""
- if typedError, ok := err.(user_model.ErrEmailInvalid); ok {
+ if typedError, ok := err.(validation.ErrEmailInvalid); ok {
email = typedError.Email
}
- if typedError, ok := err.(user_model.ErrEmailCharIsNotSupported); ok {
+ if typedError, ok := err.(validation.ErrEmailCharIsNotSupported); ok {
email = typedError.Email
}
@@ -111,6 +120,10 @@ func DeleteEmail(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
diff --git a/routers/api/v1/user/follower.go b/routers/api/v1/user/follower.go
index 1ba7346b8c..643ad49b80 100644
--- a/routers/api/v1/user/follower.go
+++ b/routers/api/v1/user/follower.go
@@ -8,11 +8,11 @@ import (
"errors"
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
func responseAPIUsers(ctx *context.APIContext, users []*user_model.User) {
@@ -53,6 +53,10 @@ func ListMyFollowers(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/UserList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
listUserFollowers(ctx, ctx.Doer)
}
@@ -117,6 +121,10 @@ func ListMyFollowing(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/UserList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
listUserFollowing(ctx, ctx.Doer)
}
@@ -173,6 +181,10 @@ func CheckMyFollowing(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -222,10 +234,12 @@ func Follow(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
- // "404":
- // "$ref": "#/responses/notFound"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
+ // "404":
+ // "$ref": "#/responses/notFound"
if err := user_model.FollowUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID); err != nil {
if errors.Is(err, user_model.ErrBlockedByUser) {
@@ -252,6 +266,10 @@ func Unfollow(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go
index 5a2f995e1b..1581358b66 100644
--- a/routers/api/v1/user/gpg_key.go
+++ b/routers/api/v1/user/gpg_key.go
@@ -8,15 +8,15 @@ import (
"net/http"
"strings"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
func listGPGKeys(ctx *context.APIContext, uid int64, listOptions db.ListOptions) {
@@ -92,6 +92,10 @@ func ListMyGPGKeys(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/GPGKeyList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
listGPGKeys(ctx, ctx.Doer.ID, utils.GetListOptions(ctx))
}
@@ -113,6 +117,10 @@ func GetGPGKey(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/GPGKey"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -164,6 +172,10 @@ func GetVerificationToken(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/string"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -183,6 +195,10 @@ func VerifyUserGPGKey(ctx *context.APIContext) {
// responses:
// "201":
// "$ref": "#/responses/GPGKey"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "422":
@@ -244,6 +260,10 @@ func CreateGPGKey(ctx *context.APIContext) {
// responses:
// "201":
// "$ref": "#/responses/GPGKey"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "422":
@@ -270,6 +290,8 @@ func DeleteGPGKey(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
@@ -281,11 +303,7 @@ func DeleteGPGKey(ctx *context.APIContext) {
}
if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.ParamsInt64(":id")); err != nil {
- if asymkey_model.IsErrGPGKeyAccessDenied(err) {
- ctx.Error(http.StatusForbidden, "", "You do not have access to this key")
- } else {
- ctx.Error(http.StatusInternalServerError, "DeleteGPGKey", err)
- }
+ ctx.Error(http.StatusInternalServerError, "DeleteGPGKey", err)
return
}
@@ -295,8 +313,6 @@ func DeleteGPGKey(ctx *context.APIContext) {
// HandleAddGPGKeyError handle add GPGKey error
func HandleAddGPGKeyError(ctx *context.APIContext, err error, token string) {
switch {
- case asymkey_model.IsErrGPGKeyAccessDenied(err):
- ctx.Error(http.StatusUnprocessableEntity, "GPGKeyAccessDenied", "You do not have access to this GPG key")
case asymkey_model.IsErrGPGKeyIDAlreadyUsed(err):
ctx.Error(http.StatusUnprocessableEntity, "GPGKeyIDAlreadyUsed", "A key with the same id already exists")
case asymkey_model.IsErrGPGKeyParsing(err):
diff --git a/routers/api/v1/user/helper.go b/routers/api/v1/user/helper.go
index 8b5c64e291..fe0943091f 100644
--- a/routers/api/v1/user/helper.go
+++ b/routers/api/v1/user/helper.go
@@ -6,8 +6,8 @@ package user
import (
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/services/context"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/services/context"
)
// GetUserByParamsName get user by name
diff --git a/routers/api/v1/user/hook.go b/routers/api/v1/user/hook.go
index 9d9ca5bf01..c8cdf5040d 100644
--- a/routers/api/v1/user/hook.go
+++ b/routers/api/v1/user/hook.go
@@ -6,11 +6,11 @@ package user
import (
"net/http"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ webhook_service "forgejo.org/services/webhook"
)
// ListHooks list the authenticated user's webhooks
@@ -32,6 +32,10 @@ func ListHooks(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/HookList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
utils.ListOwnerHooks(
ctx,
@@ -56,6 +60,10 @@ func GetHook(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/Hook"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
hook, err := utils.GetOwnerHook(ctx, ctx.Doer.ID, ctx.ParamsInt64("id"))
if err != nil {
@@ -93,6 +101,10 @@ func CreateHook(ctx *context.APIContext) {
// responses:
// "201":
// "$ref": "#/responses/Hook"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
utils.AddOwnerHook(
ctx,
@@ -124,6 +136,10 @@ func EditHook(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/Hook"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
utils.EditOwnerHook(
ctx,
@@ -150,6 +166,10 @@ func DeleteHook(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
utils.DeleteOwnerHook(
ctx,
diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go
index d9456e7ec6..3aecf5fc3a 100644
--- a/routers/api/v1/user/key.go
+++ b/routers/api/v1/user/key.go
@@ -8,18 +8,18 @@ import (
"fmt"
"net/http"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/api/v1/repo"
- "code.gitea.io/gitea/routers/api/v1/utils"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/api/v1/repo"
+ "forgejo.org/routers/api/v1/utils"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// appendPrivateInformation appends the owner and key type information to api.PublicKey
@@ -121,6 +121,10 @@ func ListMyPublicKeys(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/PublicKeyList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
listPublicKeys(ctx, ctx.Doer)
}
@@ -176,6 +180,10 @@ func GetPublicKey(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/PublicKey"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -240,6 +248,10 @@ func CreatePublicKey(ctx *context.APIContext) {
// responses:
// "201":
// "$ref": "#/responses/PublicKey"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "422":
// "$ref": "#/responses/validationError"
@@ -264,6 +276,8 @@ func DeletePublicKey(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
// "403":
// "$ref": "#/responses/forbidden"
// "404":
diff --git a/routers/api/v1/user/quota.go b/routers/api/v1/user/quota.go
new file mode 100644
index 0000000000..40c8ee43e9
--- /dev/null
+++ b/routers/api/v1/user/quota.go
@@ -0,0 +1,128 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package user
+
+import (
+ "forgejo.org/routers/api/v1/shared"
+ "forgejo.org/services/context"
+)
+
+// GetQuota returns the quota information for the authenticated user
+func GetQuota(ctx *context.APIContext) {
+ // swagger:operation GET /user/quota user userGetQuota
+ // ---
+ // summary: Get quota information for the authenticated user
+ // produces:
+ // - application/json
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaInfo"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+
+ shared.GetQuota(ctx, ctx.Doer.ID)
+}
+
+// CheckQuota returns whether the authenticated user is over the subject quota
+func CheckQuota(ctx *context.APIContext) {
+ // swagger:operation GET /user/quota/check user userCheckQuota
+ // ---
+ // summary: Check if the authenticated user is over quota for a given subject
+ // produces:
+ // - application/json
+ // responses:
+ // "200":
+ // "$ref": "#/responses/boolean"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "422":
+ // "$ref": "#/responses/validationError"
+
+ shared.CheckQuota(ctx, ctx.Doer.ID)
+}
+
+// ListQuotaAttachments lists attachments affecting the authenticated user's quota
+func ListQuotaAttachments(ctx *context.APIContext) {
+ // swagger:operation GET /user/quota/attachments user userListQuotaAttachments
+ // ---
+ // summary: List the attachments affecting the authenticated user's quota
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: page
+ // in: query
+ // description: page number of results to return (1-based)
+ // type: integer
+ // - name: limit
+ // in: query
+ // description: page size of results
+ // type: integer
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaUsedAttachmentList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+
+ shared.ListQuotaAttachments(ctx, ctx.Doer.ID)
+}
+
+// ListQuotaPackages lists packages affecting the authenticated user's quota
+func ListQuotaPackages(ctx *context.APIContext) {
+ // swagger:operation GET /user/quota/packages user userListQuotaPackages
+ // ---
+ // summary: List the packages affecting the authenticated user's quota
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: page
+ // in: query
+ // description: page number of results to return (1-based)
+ // type: integer
+ // - name: limit
+ // in: query
+ // description: page size of results
+ // type: integer
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaUsedPackageList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+
+ shared.ListQuotaPackages(ctx, ctx.Doer.ID)
+}
+
+// ListQuotaArtifacts lists artifacts affecting the authenticated user's quota
+func ListQuotaArtifacts(ctx *context.APIContext) {
+ // swagger:operation GET /user/quota/artifacts user userListQuotaArtifacts
+ // ---
+ // summary: List the artifacts affecting the authenticated user's quota
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: page
+ // in: query
+ // description: page number of results to return (1-based)
+ // type: integer
+ // - name: limit
+ // in: query
+ // description: page size of results
+ // type: integer
+ // responses:
+ // "200":
+ // "$ref": "#/responses/QuotaUsedArtifactList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+
+ shared.ListQuotaArtifacts(ctx, ctx.Doer.ID)
+}
diff --git a/routers/api/v1/user/repo.go b/routers/api/v1/user/repo.go
index 9b6701b067..7b326812a7 100644
--- a/routers/api/v1/user/repo.go
+++ b/routers/api/v1/user/repo.go
@@ -6,13 +6,13 @@ package user
import (
"net/http"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// listUserRepos - List the repositories owned by the given user.
@@ -99,9 +99,20 @@ func ListMyRepos(ctx *context.APIContext) {
// in: query
// description: page size of results
// type: integer
+ // - name: order_by
+ // in: query
+ // description: order the repositories
+ // type: string
+ // enum: [name, id, newest, oldest, recentupdate, leastupdate, reversealphabetically, alphabetically, reversesize, size, reversegitsize, gitsize, reverselfssize, lfssize, moststars, feweststars, mostforks, fewestforks]
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ // "422":
+ // "$ref": "#/responses/validationError"
opts := &repo_model.SearchRepoOptions{
ListOptions: utils.GetListOptions(ctx),
@@ -110,8 +121,21 @@ func ListMyRepos(ctx *context.APIContext) {
Private: ctx.IsSigned,
IncludeDescription: true,
}
+ orderBy := ctx.FormTrim("order_by")
+ switch orderBy {
+ case "name":
+ opts.OrderBy = "name ASC"
+ case "id":
+ opts.OrderBy = "id ASC"
+ default:
+ if orderBy, ok := repo_model.OrderByFlatMap[orderBy]; ok {
+ opts.OrderBy = orderBy
+ } else if orderBy != "" {
+ ctx.Error(http.StatusUnprocessableEntity, "", "invalid order_by")
+ return
+ }
+ }
- var err error
repos, count, err := repo_model.SearchRepository(ctx, opts)
if err != nil {
ctx.Error(http.StatusInternalServerError, "SearchRepository", err)
diff --git a/routers/api/v1/user/runners.go b/routers/api/v1/user/runners.go
index 899218473e..579e3eb932 100644
--- a/routers/api/v1/user/runners.go
+++ b/routers/api/v1/user/runners.go
@@ -4,8 +4,8 @@
package user
import (
- "code.gitea.io/gitea/routers/api/v1/shared"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/routers/api/v1/shared"
+ "forgejo.org/services/context"
)
// https://docs.github.com/en/rest/actions/self-hosted-runners?apiVersion=2022-11-28#create-a-registration-token-for-an-organization
@@ -21,6 +21,32 @@ func GetRegistrationToken(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/RegistrationToken"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
shared.GetRegistrationToken(ctx, ctx.Doer.ID, 0)
}
+
+// SearchActionRunJobs return a list of actions jobs filtered by the provided parameters
+func SearchActionRunJobs(ctx *context.APIContext) {
+ // swagger:operation GET /user/actions/runners/jobs user userSearchRunJobs
+ // ---
+ // summary: Search for user's action jobs according filter conditions
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: labels
+ // in: query
+ // description: a comma separated list of run job labels to search for
+ // type: string
+ // responses:
+ // "200":
+ // "$ref": "#/responses/RunJobList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
+ shared.GetActionRunJobs(ctx, ctx.Doer.ID, 0)
+}
diff --git a/routers/api/v1/user/settings.go b/routers/api/v1/user/settings.go
index bfd24013db..134b448718 100644
--- a/routers/api/v1/user/settings.go
+++ b/routers/api/v1/user/settings.go
@@ -6,12 +6,12 @@ package user
import (
"net/http"
- "code.gitea.io/gitea/modules/optional"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- user_service "code.gitea.io/gitea/services/user"
+ "forgejo.org/modules/optional"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ user_service "forgejo.org/services/user"
)
// GetUserSettings returns user settings
@@ -24,6 +24,10 @@ func GetUserSettings(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/UserSettings"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
ctx.JSON(http.StatusOK, convert.User2UserSettings(ctx.Doer))
}
@@ -42,6 +46,10 @@ func UpdateUserSettings(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/UserSettings"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
form := web.GetForm(ctx).(*api.UserSettingsOptions)
@@ -55,6 +63,7 @@ func UpdateUserSettings(ctx *context.APIContext) {
Theme: optional.FromPtr(form.Theme),
DiffViewStyle: optional.FromPtr(form.DiffViewStyle),
KeepEmailPrivate: optional.FromPtr(form.HideEmail),
+ KeepPronounsPrivate: optional.FromPtr(form.HidePronouns),
KeepActivityPrivate: optional.FromPtr(form.HideActivity),
EnableRepoUnitHints: optional.FromPtr(form.EnableRepoUnitHints),
}
diff --git a/routers/api/v1/user/star.go b/routers/api/v1/user/star.go
index cb9e05f791..19fa49f2ad 100644
--- a/routers/api/v1/user/star.go
+++ b/routers/api/v1/user/star.go
@@ -9,15 +9,15 @@ import (
std_context "context"
"net/http"
- "code.gitea.io/gitea/models/db"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models/db"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/repository"
)
// getStarredRepos returns the repos that the user with the specified userID has
@@ -96,6 +96,10 @@ func GetMyStarredRepos(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
repos, err := getStarredRepos(ctx, ctx.Doer, true, utils.GetListOptions(ctx))
if err != nil {
@@ -125,6 +129,10 @@ func IsStarring(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -154,6 +162,10 @@ func Star(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
@@ -185,6 +197,10 @@ func Unstar(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go
index 831c1436da..5bdd56c892 100644
--- a/routers/api/v1/user/user.go
+++ b/routers/api/v1/user/user.go
@@ -8,11 +8,12 @@ import (
"fmt"
"net/http"
- activities_model "code.gitea.io/gitea/models/activities"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ activities_model "forgejo.org/models/activities"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// Search search users
@@ -68,12 +69,18 @@ func Search(ctx *context.APIContext) {
maxResults = 1
users = []*user_model.User{user_model.NewActionsUser()}
default:
+ var visible []structs.VisibleType
+ if ctx.PublicOnly {
+ visible = []structs.VisibleType{structs.VisibleTypePublic}
+ }
users, maxResults, err = user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
- Actor: ctx.Doer,
- Keyword: ctx.FormTrim("q"),
- UID: uid,
- Type: user_model.UserTypeIndividual,
- ListOptions: listOptions,
+ Actor: ctx.Doer,
+ Keyword: ctx.FormTrim("q"),
+ UID: uid,
+ Type: user_model.UserTypeIndividual,
+ SearchByEmail: true,
+ Visible: visible,
+ ListOptions: listOptions,
})
if err != nil {
ctx.JSON(http.StatusInternalServerError, map[string]any{
@@ -130,6 +137,10 @@ func GetAuthenticatedUser(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/User"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
ctx.JSON(http.StatusOK, convert.ToUser(ctx, ctx.Doer, ctx.Doer))
}
@@ -237,6 +248,10 @@ func ListBlockedUsers(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/BlockedUserList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
utils.ListUserBlockedUsers(ctx, ctx.Doer)
}
@@ -257,6 +272,10 @@ func BlockUser(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "422":
@@ -286,6 +305,10 @@ func UnblockUser(ctx *context.APIContext) {
// responses:
// "204":
// "$ref": "#/responses/empty"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
// "404":
// "$ref": "#/responses/notFound"
// "422":
diff --git a/routers/api/v1/user/watch.go b/routers/api/v1/user/watch.go
index 706f4cc66b..1358a63f51 100644
--- a/routers/api/v1/user/watch.go
+++ b/routers/api/v1/user/watch.go
@@ -7,14 +7,14 @@ import (
std_context "context"
"net/http"
- "code.gitea.io/gitea/models/db"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/api/v1/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models/db"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/routers/api/v1/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// getWatchedRepos returns the repos that the user with the specified userID is watching
@@ -91,6 +91,10 @@ func GetMyWatchedRepos(ctx *context.APIContext) {
// responses:
// "200":
// "$ref": "#/responses/RepositoryList"
+ // "401":
+ // "$ref": "#/responses/unauthorized"
+ // "403":
+ // "$ref": "#/responses/forbidden"
repos, total, err := getWatchedRepos(ctx, ctx.Doer, true, utils.GetListOptions(ctx))
if err != nil {
diff --git a/routers/api/v1/utils/block.go b/routers/api/v1/utils/block.go
index 34fad96034..a1f044d1ef 100644
--- a/routers/api/v1/utils/block.go
+++ b/routers/api/v1/utils/block.go
@@ -6,10 +6,10 @@ package utils
import (
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
- user_service "code.gitea.io/gitea/services/user"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
+ user_service "forgejo.org/services/user"
)
// ListUserBlockedUsers lists the blocked users of the provided doer.
diff --git a/routers/api/v1/utils/git.go b/routers/api/v1/utils/git.go
index 4e25137817..5359a54899 100644
--- a/routers/api/v1/utils/git.go
+++ b/routers/api/v1/utils/git.go
@@ -8,10 +8,10 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/context"
)
// ResolveRefOrSha resolve ref to sha if exist
diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go
index f1abd49a7d..d882845008 100644
--- a/routers/api/v1/utils/hook.go
+++ b/routers/api/v1/utils/hook.go
@@ -9,16 +9,16 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- webhook_module "code.gitea.io/gitea/modules/webhook"
- "code.gitea.io/gitea/services/context"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/models/webhook"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ webhook_module "forgejo.org/modules/webhook"
+ "forgejo.org/services/context"
+ webhook_service "forgejo.org/services/webhook"
)
// ListOwnerHooks lists the webhooks of the provided owner
diff --git a/routers/api/v1/utils/page.go b/routers/api/v1/utils/page.go
index 024ba7b8d9..4ab141ca64 100644
--- a/routers/api/v1/utils/page.go
+++ b/routers/api/v1/utils/page.go
@@ -4,9 +4,9 @@
package utils
import (
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models/db"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// GetListOptions returns list options using the page and limit parameters
diff --git a/routers/common/auth.go b/routers/common/auth.go
index 115d65ed10..d4b3b1fea7 100644
--- a/routers/common/auth.go
+++ b/routers/common/auth.go
@@ -4,10 +4,10 @@
package common
import (
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/web/middleware"
- auth_service "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/context"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/web/middleware"
+ auth_service "forgejo.org/services/auth"
+ "forgejo.org/services/context"
)
type AuthResult struct {
@@ -31,6 +31,7 @@ func AuthShared(ctx *context.Base, sessionStore auth_service.SessionStore, authM
ctx.Data["SignedUserID"] = ar.Doer.ID
ctx.Data["IsAdmin"] = ar.Doer.IsAdmin
} else {
+ ctx.Data["IsSigned"] = false
ctx.Data["SignedUserID"] = int64(0)
}
return ar, nil
diff --git a/routers/common/compare.go b/routers/common/compare.go
index 4d1cc2f0d8..9c158814d1 100644
--- a/routers/common/compare.go
+++ b/routers/common/compare.go
@@ -4,9 +4,9 @@
package common
import (
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
)
// CompareInfo represents the collected results from ParseCompareInfo
diff --git a/routers/common/db.go b/routers/common/db.go
index d7dcfa0122..0646071264 100644
--- a/routers/common/db.go
+++ b/routers/common/db.go
@@ -8,12 +8,12 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/migrations"
- system_model "code.gitea.io/gitea/models/system"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/setting/config"
+ "forgejo.org/models/db"
+ "forgejo.org/models/migrations"
+ system_model "forgejo.org/models/system"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/setting/config"
"xorm.io/xorm"
)
@@ -51,7 +51,7 @@ func migrateWithSetting(x *xorm.Engine) error {
} else if current < 0 {
// execute migrations when the database isn't initialized even if AutoMigration is false
return migrations.Migrate(x)
- } else if expected := migrations.ExpectedVersion(); current != expected {
+ } else if expected := migrations.ExpectedDBVersion(); current != expected {
log.Fatal(`"database.AUTO_MIGRATION" is disabled, but current database version %d is not equal to the expected version %d.`+
`You can set "database.AUTO_MIGRATION" to true or migrate manually by running "forgejo [--config /path/to/app.ini] migrate"`, current, expected)
}
diff --git a/routers/common/errpage.go b/routers/common/errpage.go
index 402ca44c12..907c278ab1 100644
--- a/routers/common/errpage.go
+++ b/routers/common/errpage.go
@@ -7,15 +7,15 @@ import (
"fmt"
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/modules/web/routing"
- "code.gitea.io/gitea/services/context"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/modules/web/routing"
+ "forgejo.org/services/context"
)
const tplStatus500 base.TplName = "status/500"
diff --git a/routers/common/errpage_test.go b/routers/common/errpage_test.go
index 4fd63ba49e..3a492ea304 100644
--- a/routers/common/errpage_test.go
+++ b/routers/common/errpage_test.go
@@ -4,16 +4,15 @@
package common
import (
- "context"
"errors"
"net/http"
"net/http/httptest"
"net/url"
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/test"
- "code.gitea.io/gitea/modules/web/middleware"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/test"
+ "forgejo.org/modules/web/middleware"
"github.com/stretchr/testify/assert"
)
@@ -21,7 +20,7 @@ import (
func TestRenderPanicErrorPage(t *testing.T) {
w := httptest.NewRecorder()
req := &http.Request{URL: &url.URL{}}
- req = req.WithContext(middleware.WithContextData(context.Background()))
+ req = req.WithContext(middleware.WithContextData(t.Context()))
RenderPanicErrorPage(w, req, errors.New("fake panic error (for test only)"))
respContent := w.Body.String()
assert.Contains(t, respContent, `class="page-content status-page-500"`)
diff --git a/routers/common/markup.go b/routers/common/markup.go
index 2d5638ef61..715d7d883f 100644
--- a/routers/common/markup.go
+++ b/routers/common/markup.go
@@ -9,35 +9,40 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
"mvdan.cc/xurls/v2"
)
+type Renderer struct {
+ Mode, Text, URLPrefix, FilePath, BranchPath string
+ IsWiki bool
+}
+
// RenderMarkup renders markup text for the /markup and /markdown endpoints
-func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPrefix, filePath string, wiki bool) {
+func (re *Renderer) RenderMarkup(ctx *context.Base, repo *context.Repository) {
var markupType string
relativePath := ""
- if len(text) == 0 {
+ if len(re.Text) == 0 {
_, _ = ctx.Write([]byte(""))
return
}
- switch mode {
+ switch re.Mode {
case "markdown":
// Raw markdown
if err := markdown.RenderRaw(&markup.RenderContext{
Ctx: ctx,
Links: markup.Links{
AbsolutePrefix: true,
- Base: urlPrefix,
+ Base: re.URLPrefix,
},
- }, strings.NewReader(text), ctx.Resp); err != nil {
+ }, strings.NewReader(re.Text), ctx.Resp); err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
}
return
@@ -50,30 +55,30 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
case "file":
// File as document based on file extension
markupType = ""
- relativePath = filePath
+ relativePath = re.FilePath
default:
- ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", mode))
+ ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", re.Mode))
return
}
- if !strings.HasPrefix(setting.AppSubURL+"/", urlPrefix) {
+ if !strings.HasPrefix(setting.AppSubURL+"/", re.URLPrefix) {
// check if urlPrefix is already set to a URL
linkRegex, _ := xurls.StrictMatchingScheme("https?://")
- m := linkRegex.FindStringIndex(urlPrefix)
+ m := linkRegex.FindStringIndex(re.URLPrefix)
if m == nil {
- urlPrefix = util.URLJoin(setting.AppURL, urlPrefix)
+ re.URLPrefix = util.URLJoin(setting.AppURL, re.URLPrefix)
}
}
meta := map[string]string{}
if repo != nil && repo.Repository != nil {
- if mode == "comment" {
+ if re.Mode == "comment" {
meta = repo.Repository.ComposeMetas(ctx)
} else {
meta = repo.Repository.ComposeDocumentMetas(ctx)
}
}
- if mode != "comment" {
+ if re.Mode != "comment" {
meta["mode"] = "document"
}
@@ -81,13 +86,14 @@ func RenderMarkup(ctx *context.Base, repo *context.Repository, mode, text, urlPr
Ctx: ctx,
Links: markup.Links{
AbsolutePrefix: true,
- Base: urlPrefix,
+ Base: re.URLPrefix,
+ BranchPath: re.BranchPath,
},
Metas: meta,
- IsWiki: wiki,
+ IsWiki: re.IsWiki,
Type: markupType,
RelativePath: relativePath,
- }, strings.NewReader(text), ctx.Resp); err != nil {
+ }, strings.NewReader(re.Text), ctx.Resp); err != nil {
if markup.IsErrUnsupportedRenderExtension(err) {
ctx.Error(http.StatusUnprocessableEntity, err.Error())
} else {
diff --git a/routers/common/middleware.go b/routers/common/middleware.go
index c7c75fb099..d44f046a1e 100644
--- a/routers/common/middleware.go
+++ b/routers/common/middleware.go
@@ -6,16 +6,17 @@ package common
import (
"fmt"
"net/http"
+ "runtime/trace"
"strings"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/modules/web/routing"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/modules/web/routing"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/session"
+ "code.forgejo.org/go-chi/session"
"github.com/chi-middleware/proxy"
chi "github.com/go-chi/chi/v5"
)
@@ -43,6 +44,8 @@ func ProtocolMiddlewares() (handlers []any) {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
ctx, _, finished := process.GetManager().AddTypedContext(req.Context(), fmt.Sprintf("%s: %s", req.Method, req.RequestURI), process.RequestProcessType, true)
defer finished()
+ trace.Log(ctx, "method", req.Method)
+ trace.Log(ctx, "url", req.RequestURI)
next.ServeHTTP(context.WrapResponseWriter(resp), req.WithContext(cache.WithCacheContext(ctx)))
})
})
@@ -74,28 +77,27 @@ func ProtocolMiddlewares() (handlers []any) {
func stripSlashesMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
- // First of all escape the URL RawPath to ensure that all routing is done using a correctly escaped URL
+ // Ensure that URL.RawPath is always set.
req.URL.RawPath = req.URL.EscapedPath()
- urlPath := req.URL.RawPath
- rctx := chi.RouteContext(req.Context())
- if rctx != nil && rctx.RoutePath != "" {
- urlPath = rctx.RoutePath
- }
-
- sanitizedPath := &strings.Builder{}
- prevWasSlash := false
- for _, chr := range strings.TrimRight(urlPath, "/") {
- if chr != '/' || !prevWasSlash {
- sanitizedPath.WriteRune(chr)
+ sanitize := func(path string) string {
+ sanitizedPath := &strings.Builder{}
+ prevWasSlash := false
+ for _, chr := range strings.TrimRight(path, "/") {
+ if chr != '/' || !prevWasSlash {
+ sanitizedPath.WriteRune(chr)
+ }
+ prevWasSlash = chr == '/'
}
- prevWasSlash = chr == '/'
+ return sanitizedPath.String()
}
- if rctx == nil {
- req.URL.Path = sanitizedPath.String()
- } else {
- rctx.RoutePath = sanitizedPath.String()
+ // Sanitize the unescaped path for application logic.
+ req.URL.Path = sanitize(req.URL.Path)
+ rctx := chi.RouteContext(req.Context())
+ if rctx != nil {
+ // Sanitize the escaped path for routing.
+ rctx.RoutePath = sanitize(req.URL.RawPath)
}
next.ServeHTTP(resp, req)
})
diff --git a/routers/common/middleware_test.go b/routers/common/middleware_test.go
index f16b9374ec..b9c1b226e8 100644
--- a/routers/common/middleware_test.go
+++ b/routers/common/middleware_test.go
@@ -7,14 +7,18 @@ import (
"net/http/httptest"
"testing"
+ "forgejo.org/modules/web"
+
+ chi "github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
)
func TestStripSlashesMiddleware(t *testing.T) {
type test struct {
- name string
- expectedPath string
- inputPath string
+ name string
+ expectedPath string
+ expectedNormalPath string
+ inputPath string
}
tests := []test{
@@ -43,28 +47,51 @@ func TestStripSlashesMiddleware(t *testing.T) {
inputPath: "/user2//repo1/",
expectedPath: "/user2/repo1",
},
+ {
+ name: "path with slashes in the beginning",
+ inputPath: "https://codeberg.org//user2/repo1/",
+ expectedPath: "/user2/repo1",
+ },
{
name: "path with slashes and query params",
inputPath: "/repo//migrate?service_type=3",
expectedPath: "/repo/migrate",
},
{
- name: "path with encoded slash",
- inputPath: "/user2/%2F%2Frepo1",
- expectedPath: "/user2/%2F%2Frepo1",
+ name: "path with encoded slash",
+ inputPath: "/user2/%2F%2Frepo1",
+ expectedPath: "/user2/%2F%2Frepo1",
+ expectedNormalPath: "/user2/repo1",
+ },
+ {
+ name: "path with space",
+ inputPath: "/assets/css/theme%20cappuccino.css",
+ expectedPath: "/assets/css/theme%20cappuccino.css",
+ expectedNormalPath: "/assets/css/theme cappuccino.css",
},
}
for _, tt := range tests {
- testMiddleware := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- assert.Equal(t, tt.expectedPath, r.URL.Path)
+ r := web.NewRoute()
+ r.Use(stripSlashesMiddleware)
+
+ called := false
+ r.Get("*", func(w http.ResponseWriter, r *http.Request) {
+ if tt.expectedNormalPath != "" {
+ assert.Equal(t, tt.expectedNormalPath, r.URL.Path)
+ } else {
+ assert.Equal(t, tt.expectedPath, r.URL.Path)
+ }
+
+ rctx := chi.RouteContext(r.Context())
+ assert.Equal(t, tt.expectedPath, rctx.RoutePath)
+
+ called = true
})
- // pass the test middleware to validate the changes
- handlerToTest := stripSlashesMiddleware(testMiddleware)
// create a mock request to use
req := httptest.NewRequest("GET", tt.inputPath, nil)
- // call the handler using a mock response recorder
- handlerToTest.ServeHTTP(httptest.NewRecorder(), req)
+ r.ServeHTTP(httptest.NewRecorder(), req)
+ assert.True(t, called)
}
}
diff --git a/routers/common/redirect.go b/routers/common/redirect.go
index 9bf2025e19..8c13911a9c 100644
--- a/routers/common/redirect.go
+++ b/routers/common/redirect.go
@@ -6,7 +6,7 @@ package common
import (
"net/http"
- "code.gitea.io/gitea/modules/httplib"
+ "forgejo.org/modules/httplib"
)
// FetchRedirectDelegate helps the "fetch" requests to redirect to the correct location
diff --git a/routers/common/serve.go b/routers/common/serve.go
index 446908db75..9d017ec5a1 100644
--- a/routers/common/serve.go
+++ b/routers/common/serve.go
@@ -7,11 +7,11 @@ import (
"io"
"time"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/httplib"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/httplib"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/context"
)
// ServeBlob download a git.Blob
diff --git a/routers/init.go b/routers/init.go
index 821a0ef38c..5f9dbbb4dd 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -8,50 +8,51 @@ import (
"reflect"
"runtime"
- "code.gitea.io/gitea/models"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- authmodel "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/eventsource"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/highlight"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/external"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/ssh"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/svg"
- "code.gitea.io/gitea/modules/system"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/web"
- actions_router "code.gitea.io/gitea/routers/api/actions"
- forgejo "code.gitea.io/gitea/routers/api/forgejo/v1"
- packages_router "code.gitea.io/gitea/routers/api/packages"
- apiv1 "code.gitea.io/gitea/routers/api/v1"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/routers/private"
- web_routers "code.gitea.io/gitea/routers/web"
- actions_service "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/oauth2"
- "code.gitea.io/gitea/services/automerge"
- "code.gitea.io/gitea/services/cron"
- feed_service "code.gitea.io/gitea/services/feed"
- indexer_service "code.gitea.io/gitea/services/indexer"
- "code.gitea.io/gitea/services/mailer"
- mailer_incoming "code.gitea.io/gitea/services/mailer/incoming"
- markup_service "code.gitea.io/gitea/services/markup"
- repo_migrations "code.gitea.io/gitea/services/migrations"
- mirror_service "code.gitea.io/gitea/services/mirror"
- pull_service "code.gitea.io/gitea/services/pull"
- release_service "code.gitea.io/gitea/services/release"
- repo_service "code.gitea.io/gitea/services/repository"
- "code.gitea.io/gitea/services/repository/archiver"
- "code.gitea.io/gitea/services/task"
- "code.gitea.io/gitea/services/uinotification"
- "code.gitea.io/gitea/services/webhook"
+ "forgejo.org/models"
+ asymkey_model "forgejo.org/models/asymkey"
+ authmodel "forgejo.org/models/auth"
+ "forgejo.org/modules/annex"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/eventsource"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/highlight"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/external"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/ssh"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/svg"
+ "forgejo.org/modules/system"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/web"
+ actions_router "forgejo.org/routers/api/actions"
+ forgejo "forgejo.org/routers/api/forgejo/v1"
+ packages_router "forgejo.org/routers/api/packages"
+ apiv1 "forgejo.org/routers/api/v1"
+ "forgejo.org/routers/common"
+ "forgejo.org/routers/private"
+ web_routers "forgejo.org/routers/web"
+ actions_service "forgejo.org/services/actions"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/oauth2"
+ "forgejo.org/services/automerge"
+ "forgejo.org/services/cron"
+ feed_service "forgejo.org/services/feed"
+ indexer_service "forgejo.org/services/indexer"
+ "forgejo.org/services/mailer"
+ mailer_incoming "forgejo.org/services/mailer/incoming"
+ markup_service "forgejo.org/services/markup"
+ repo_migrations "forgejo.org/services/migrations"
+ mirror_service "forgejo.org/services/mirror"
+ pull_service "forgejo.org/services/pull"
+ release_service "forgejo.org/services/release"
+ repo_service "forgejo.org/services/repository"
+ "forgejo.org/services/repository/archiver"
+ "forgejo.org/services/task"
+ "forgejo.org/services/uinotification"
+ "forgejo.org/services/webhook"
)
func mustInit(fn func() error) {
@@ -167,6 +168,8 @@ func InitWebInstalled(ctx context.Context) {
actions_service.Init()
+ mustInit(annex.Init)
+
// Finally start up the cron
cron.NewContext(ctx)
}
diff --git a/routers/install/install.go b/routers/install/install.go
index 140e008d9a..b9333a9e16 100644
--- a/routers/install/install.go
+++ b/routers/install/install.go
@@ -15,28 +15,27 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- db_install "code.gitea.io/gitea/models/db/install"
- "code.gitea.io/gitea/models/migrations"
- system_model "code.gitea.io/gitea/models/system"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/password/hash"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/generate"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/user"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/db"
+ db_install "forgejo.org/models/db/install"
+ "forgejo.org/models/migrations"
+ system_model "forgejo.org/models/system"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/password/hash"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/generate"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/web"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
- "gitea.com/go-chi/session"
+ "code.forgejo.org/go-chi/session"
)
const (
@@ -119,15 +118,7 @@ func Install(ctx *context.Context) {
form.AppSlogan = "Beyond coding. We Forge."
form.RepoRootPath = setting.RepoRootPath
form.LFSRootPath = setting.LFS.Storage.Path
-
- // Note(unknown): it's hard for Windows users change a running user,
- // so just use current one if config says default.
- if setting.IsWindows && setting.RunUser == "git" {
- form.RunUser = user.CurrentUsername()
- } else {
- form.RunUser = setting.RunUser
- }
-
+ form.RunUser = setting.RunUser
form.Domain = setting.Domain
form.SSHPort = setting.SSH.Port
form.HTTPPort = setting.HTTPPort
diff --git a/routers/install/routes.go b/routers/install/routes.go
index 06c9d389a6..f7fb40f688 100644
--- a/routers/install/routes.go
+++ b/routers/install/routes.go
@@ -8,12 +8,12 @@ import (
"html"
"net/http"
- "code.gitea.io/gitea/modules/public"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/routers/web/healthcheck"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/modules/public"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/common"
+ "forgejo.org/routers/web/healthcheck"
+ "forgejo.org/services/forms"
)
// Routes registers the installation routes
diff --git a/routers/install/routes_test.go b/routers/install/routes_test.go
index 2aa7f5d7b7..a504cf1baa 100644
--- a/routers/install/routes_test.go
+++ b/routers/install/routes_test.go
@@ -7,7 +7,7 @@ import (
"net/http/httptest"
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
)
diff --git a/routers/private/actions.go b/routers/private/actions.go
index 425c480b3e..441fb881ed 100644
--- a/routers/private/actions.go
+++ b/routers/private/actions.go
@@ -10,14 +10,14 @@ import (
"net/http"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ actions_model "forgejo.org/models/actions"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
)
// GenerateActionsRunnerToken generates a new runner token for a given scope
diff --git a/routers/private/default_branch.go b/routers/private/default_branch.go
index 33890be6a9..da185e1ab1 100644
--- a/routers/private/default_branch.go
+++ b/routers/private/default_branch.go
@@ -7,11 +7,10 @@ import (
"fmt"
"net/http"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/private"
- gitea_context "code.gitea.io/gitea/services/context"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/private"
+ gitea_context "forgejo.org/services/context"
)
// SetDefaultBranch updates the default branch
@@ -22,12 +21,10 @@ func SetDefaultBranch(ctx *gitea_context.PrivateContext) {
ctx.Repo.Repository.DefaultBranch = branch
if err := gitrepo.SetDefaultBranch(ctx, ctx.Repo.Repository, ctx.Repo.Repository.DefaultBranch); err != nil {
- if !git.IsErrUnsupportedVersion(err) {
- ctx.JSON(http.StatusInternalServerError, private.Response{
- Err: fmt.Sprintf("Unable to set default branch on repository: %s/%s Error: %v", ownerName, repoName, err),
- })
- return
- }
+ ctx.JSON(http.StatusInternalServerError, private.Response{
+ Err: fmt.Sprintf("Unable to set default branch on repository: %s/%s Error: %v", ownerName, repoName, err),
+ })
+ return
}
if err := repo_model.UpdateDefaultBranch(ctx, ctx.Repo.Repository); err != nil {
diff --git a/routers/private/hook_post_receive.go b/routers/private/hook_post_receive.go
index b78f19d51e..c7748b01c8 100644
--- a/routers/private/hook_post_receive.go
+++ b/routers/private/hook_post_receive.go
@@ -10,24 +10,25 @@ import (
"strconv"
"time"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- pull_model "code.gitea.io/gitea/models/pull"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- timeutil "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- gitea_context "code.gitea.io/gitea/services/context"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ pull_model "forgejo.org/models/pull"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/git/pushoptions"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ timeutil "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ gitea_context "forgejo.org/services/context"
+ repo_service "forgejo.org/services/repository"
)
// HookPostReceive updates services and users
@@ -170,7 +171,7 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
}
// Handle Push Options
- if len(opts.GitPushOptions) > 0 {
+ if !opts.GetGitPushOptions().Empty() {
// load the repository
if repo == nil {
repo = loadRepository(ctx, ownerName, repoName)
@@ -181,8 +182,8 @@ func HookPostReceive(ctx *gitea_context.PrivateContext) {
wasEmpty = repo.IsEmpty
}
- repo.IsPrivate = opts.GitPushOptions.Bool(private.GitPushOptionRepoPrivate, repo.IsPrivate)
- repo.IsTemplate = opts.GitPushOptions.Bool(private.GitPushOptionRepoTemplate, repo.IsTemplate)
+ repo.IsPrivate = opts.GetGitPushOptions().GetBool(pushoptions.RepoPrivate, repo.IsPrivate)
+ repo.IsTemplate = opts.GetGitPushOptions().GetBool(pushoptions.RepoTemplate, repo.IsTemplate)
if err := repo_model.UpdateRepositoryCols(ctx, repo, "is_private", "is_template"); err != nil {
log.Error("Failed to Update: %s/%s Error: %v", ownerName, repoName, err)
ctx.JSON(http.StatusInternalServerError, private.HookPostReceiveResult{
diff --git a/routers/private/hook_post_receive_test.go b/routers/private/hook_post_receive_test.go
index 658557d3cf..bbd0c45769 100644
--- a/routers/private/hook_post_receive_test.go
+++ b/routers/private/hook_post_receive_test.go
@@ -6,29 +6,30 @@ package private
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- pull_model "code.gitea.io/gitea/models/pull"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/private"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/services/contexttest"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ pull_model "forgejo.org/models/pull"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/private"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestHandlePullRequestMerging(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pr, err := issues_model.GetUnmergedPullRequest(db.DefaultContext, 1, 1, "branch2", "master", issues_model.PullRequestFlowGithub)
- assert.NoError(t, err)
- assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
+ require.NoError(t, err)
+ require.NoError(t, pr.LoadBaseRepo(db.DefaultContext))
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
- err = pull_model.ScheduleAutoMerge(db.DefaultContext, user1, pr.ID, repo_model.MergeStyleSquash, "squash merge a pr")
- assert.NoError(t, err)
+ err = pull_model.ScheduleAutoMerge(db.DefaultContext, user1, pr.ID, repo_model.MergeStyleSquash, "squash merge a pr", false)
+ require.NoError(t, err)
autoMerge := unittest.AssertExistsAndLoadBean(t, &pull_model.AutoMerge{PullID: pr.ID})
@@ -39,9 +40,9 @@ func TestHandlePullRequestMerging(t *testing.T) {
}, pr.BaseRepo.OwnerName, pr.BaseRepo.Name, []*repo_module.PushUpdateOptions{
{NewCommitID: "01234567"},
})
- assert.Equal(t, 0, len(resp.Body.String()))
+ assert.Empty(t, resp.Body.String())
pr, err = issues_model.GetPullRequestByID(db.DefaultContext, pr.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, pr.HasMerged)
assert.EqualValues(t, "01234567", pr.MergedCommitID)
diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go
index 456a288b00..191273209e 100644
--- a/routers/private/hook_pre_receive.go
+++ b/routers/private/hook_pre_receive.go
@@ -9,20 +9,22 @@ import (
"net/http"
"os"
- "code.gitea.io/gitea/models"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- perm_model "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/web"
- gitea_context "code.gitea.io/gitea/services/context"
- pull_service "code.gitea.io/gitea/services/pull"
+ "forgejo.org/models"
+ asymkey_model "forgejo.org/models/asymkey"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ perm_model "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ gitea_context "forgejo.org/services/context"
+ pull_service "forgejo.org/services/pull"
)
type preReceiveContext struct {
@@ -47,6 +49,8 @@ type preReceiveContext struct {
opts *private.HookOptions
+ isOverQuota bool
+
branchName string
}
@@ -123,23 +127,7 @@ func (ctx *preReceiveContext) canChangeSettings() error {
func (ctx *preReceiveContext) validatePushOptions() error {
opts := web.GetForm(ctx).(*private.HookOptions)
- if len(opts.GitPushOptions) == 0 {
- return nil
- }
-
- changesRepoSettings := false
- for key := range opts.GitPushOptions {
- switch key {
- case private.GitPushOptionRepoPrivate, private.GitPushOptionRepoTemplate:
- changesRepoSettings = true
- case "topic", "force-push", "title", "description":
- // Agit options
- default:
- return fmt.Errorf("unknown option %s", key)
- }
- }
-
- if changesRepoSettings {
+ if opts.GetGitPushOptions().ChangeRepoSettings() {
return ctx.canChangeSettings()
}
@@ -156,6 +144,36 @@ func (ctx *preReceiveContext) assertPushOptions() bool {
return true
}
+func (ctx *preReceiveContext) checkQuota() error {
+ if !setting.Quota.Enabled {
+ ctx.isOverQuota = false
+ return nil
+ }
+
+ if !ctx.loadPusherAndPermission() {
+ ctx.isOverQuota = true
+ return nil
+ }
+
+ ok, err := quota_model.EvaluateForUser(ctx, ctx.PrivateContext.Repo.Repository.OwnerID, quota_model.LimitSubjectSizeReposAll)
+ if err != nil {
+ log.Error("quota_model.EvaluateForUser: %v", err)
+ ctx.JSON(http.StatusInternalServerError, private.Response{
+ UserMsg: "Error checking user quota",
+ })
+ return err
+ }
+
+ ctx.isOverQuota = !ok
+ return nil
+}
+
+func (ctx *preReceiveContext) quotaExceeded() {
+ ctx.JSON(http.StatusRequestEntityTooLarge, private.Response{
+ UserMsg: "Quota exceeded",
+ })
+}
+
// HookPreReceive checks whether a individual commit is acceptable
func HookPreReceive(ctx *gitea_context.PrivateContext) {
opts := web.GetForm(ctx).(*private.HookOptions)
@@ -172,6 +190,10 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) {
}
log.Trace("Git push options validation succeeded")
+ if err := ourCtx.checkQuota(); err != nil {
+ return
+ }
+
// Iterate across the provided old commit IDs
for i := range opts.OldCommitIDs {
oldCommitID := opts.OldCommitIDs[i]
@@ -186,6 +208,10 @@ func HookPreReceive(ctx *gitea_context.PrivateContext) {
case git.SupportProcReceive && refFullName.IsFor():
preReceiveFor(ourCtx, oldCommitID, newCommitID, refFullName)
default:
+ if ourCtx.isOverQuota {
+ ourCtx.quotaExceeded()
+ return
+ }
ourCtx.AssertCanWriteCode()
}
if ctx.Written() {
@@ -227,6 +253,11 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r
// Allow pushes to non-protected branches
if protectBranch == nil {
+ // ...unless the user is over quota, and the operation is not a delete
+ if newCommitID != objectFormat.EmptyObjectID().String() && ctx.isOverQuota {
+ ctx.quotaExceeded()
+ }
+
return
}
protectBranch.Repo = repo
@@ -468,6 +499,15 @@ func preReceiveTag(ctx *preReceiveContext, oldCommitID, newCommitID string, refF
})
return
}
+
+ // If the user is over quota, and the push isn't a tag deletion, deny it
+ if ctx.isOverQuota {
+ objectFormat := ctx.Repo.GetObjectFormat()
+ if newCommitID != objectFormat.EmptyObjectID().String() {
+ ctx.quotaExceeded()
+ return
+ }
+ }
}
func preReceiveFor(ctx *preReceiveContext, oldCommitID, newCommitID string, refFullName git.RefName) { //nolint:unparam
diff --git a/routers/private/hook_proc_receive.go b/routers/private/hook_proc_receive.go
index e4aabd858c..cd45794261 100644
--- a/routers/private/hook_proc_receive.go
+++ b/routers/private/hook_proc_receive.go
@@ -6,13 +6,13 @@ package private
import (
"net/http"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/agit"
- gitea_context "code.gitea.io/gitea/services/context"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/agit"
+ gitea_context "forgejo.org/services/context"
)
// HookProcReceive proc-receive hook - only handles agit Proc-Receive requests at present
diff --git a/routers/private/hook_verification.go b/routers/private/hook_verification.go
index 764c976fa9..e9a1967bd2 100644
--- a/routers/private/hook_verification.go
+++ b/routers/private/hook_verification.go
@@ -10,9 +10,9 @@ import (
"io"
"os"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
)
// This file contains commit verification functions for refs passed across in hooks
diff --git a/routers/private/hook_verification_test.go b/routers/private/hook_verification_test.go
index 04445b8eaf..35458f672e 100644
--- a/routers/private/hook_verification_test.go
+++ b/routers/private/hook_verification_test.go
@@ -4,13 +4,12 @@
package private
import (
- "context"
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/git"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
var testReposDir = "tests/repos/"
@@ -18,12 +17,12 @@ var testReposDir = "tests/repos/"
func TestVerifyCommits(t *testing.T) {
unittest.PrepareTestEnv(t)
- gitRepo, err := git.OpenRepository(context.Background(), testReposDir+"repo1_hook_verification")
+ gitRepo, err := git.OpenRepository(t.Context(), testReposDir+"repo1_hook_verification")
defer gitRepo.Close()
- assert.NoError(t, err)
+ require.NoError(t, err)
objectFormat, err := gitRepo.GetObjectFormat()
- assert.NoError(t, err)
+ require.NoError(t, err)
testCases := []struct {
base, head string
@@ -38,9 +37,9 @@ func TestVerifyCommits(t *testing.T) {
for _, tc := range testCases {
err = verifyCommits(tc.base, tc.head, gitRepo, nil)
if tc.verified {
- assert.NoError(t, err)
+ require.NoError(t, err)
} else {
- assert.Error(t, err)
+ require.Error(t, err)
}
}
}
diff --git a/routers/private/internal.go b/routers/private/internal.go
index ede310113c..5e8d51d970 100644
--- a/routers/private/internal.go
+++ b/routers/private/internal.go
@@ -5,16 +5,17 @@
package private
import (
+ "crypto/subtle"
"net/http"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
chi_middleware "github.com/go-chi/chi/v5/middleware"
)
@@ -28,7 +29,7 @@ func CheckInternalToken(next http.Handler) http.Handler {
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
return
}
- if len(fields) != 2 || fields[0] != "Bearer" || fields[1] != setting.InternalToken {
+ if len(fields) != 2 || fields[0] != "Bearer" || subtle.ConstantTimeCompare([]byte(fields[1]), []byte(setting.InternalToken)) == 0 {
log.Debug("Forbidden attempt to access internal url: Authorization header: %s", tokens)
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
} else {
diff --git a/routers/private/internal_repo.go b/routers/private/internal_repo.go
index e8ee8ba8ac..f237d2c676 100644
--- a/routers/private/internal_repo.go
+++ b/routers/private/internal_repo.go
@@ -8,11 +8,11 @@ import (
"fmt"
"net/http"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- gitea_context "code.gitea.io/gitea/services/context"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ gitea_context "forgejo.org/services/context"
)
// This file contains common functions relating to setting the Repository for the internal routes
diff --git a/routers/private/key.go b/routers/private/key.go
index 5b8f238a83..2d77c9c5be 100644
--- a/routers/private/key.go
+++ b/routers/private/key.go
@@ -6,10 +6,10 @@ package private
import (
"net/http"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/services/context"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/services/context"
)
// UpdatePublicKeyInRepo update public key and deploy key updates
diff --git a/routers/private/mail.go b/routers/private/mail.go
index cf3abb31c6..2b96ce910e 100644
--- a/routers/private/mail.go
+++ b/routers/private/mail.go
@@ -9,14 +9,14 @@ import (
"net/http"
"strconv"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/mailer"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+ "forgejo.org/services/mailer"
)
// SendEmail pushes messages to mail queue
diff --git a/routers/private/main_test.go b/routers/private/main_test.go
index a6bec72b41..1b7f00f439 100644
--- a/routers/private/main_test.go
+++ b/routers/private/main_test.go
@@ -6,7 +6,7 @@ package private
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/private/manager.go b/routers/private/manager.go
index a6aa03e4ec..7ab198f71b 100644
--- a/routers/private/manager.go
+++ b/routers/private/manager.go
@@ -7,16 +7,16 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/graceful/releasereopen"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/queue"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/graceful/releasereopen"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
)
// ReloadTemplates reloads all the templates
diff --git a/routers/private/manager_process.go b/routers/private/manager_process.go
index 9a0298a37c..87447da2be 100644
--- a/routers/private/manager_process.go
+++ b/routers/private/manager_process.go
@@ -11,10 +11,10 @@ import (
"runtime"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- process_module "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ process_module "forgejo.org/modules/process"
+ "forgejo.org/services/context"
)
// Processes prints out the processes
diff --git a/routers/private/manager_unix.go b/routers/private/manager_unix.go
index 0c63ebc918..c831b44036 100644
--- a/routers/private/manager_unix.go
+++ b/routers/private/manager_unix.go
@@ -1,15 +1,13 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
-//go:build !windows
-
package private
import (
"net/http"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/services/context"
)
// Restart causes the server to perform a graceful restart
diff --git a/routers/private/manager_windows.go b/routers/private/manager_windows.go
deleted file mode 100644
index f1b9365f52..0000000000
--- a/routers/private/manager_windows.go
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build windows
-
-package private
-
-import (
- "net/http"
-
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/services/context"
-)
-
-// Restart is not implemented for Windows based servers as they can't fork
-func Restart(ctx *context.PrivateContext) {
- ctx.JSON(http.StatusNotImplemented, private.Response{
- UserMsg: "windows servers cannot be gracefully restarted - shutdown and restart manually",
- })
-}
-
-// Shutdown causes the server to perform a graceful shutdown
-func Shutdown(ctx *context.PrivateContext) {
- graceful.GetManager().DoGracefulShutdown()
- ctx.PlainText(http.StatusOK, "success")
-}
diff --git a/routers/private/restore_repo.go b/routers/private/restore_repo.go
index 4e95d3071d..6586c9bb2b 100644
--- a/routers/private/restore_repo.go
+++ b/routers/private/restore_repo.go
@@ -7,10 +7,10 @@ import (
"io"
"net/http"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/private"
- myCtx "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/migrations"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/private"
+ myCtx "forgejo.org/services/context"
+ "forgejo.org/services/migrations"
)
// RestoreRepo restore a repository from data
diff --git a/routers/private/serv.go b/routers/private/serv.go
index ef3920d359..b554afa146 100644
--- a/routers/private/serv.go
+++ b/routers/private/serv.go
@@ -8,19 +8,19 @@ import (
"net/http"
"strings"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
- repo_service "code.gitea.io/gitea/services/repository"
- wiki_service "code.gitea.io/gitea/services/wiki"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+ repo_service "forgejo.org/services/repository"
+ wiki_service "forgejo.org/services/wiki"
)
// ServNoCommand returns information about the provided keyid
@@ -81,12 +81,14 @@ func ServCommand(ctx *context.PrivateContext) {
ownerName := ctx.Params(":owner")
repoName := ctx.Params(":repo")
mode := perm.AccessMode(ctx.FormInt("mode"))
+ verbs := ctx.FormStrings("verb")
// Set the basic parts of the results to return
results := private.ServCommandResults{
RepoName: repoName,
OwnerName: ownerName,
KeyID: keyID,
+ UserMode: perm.AccessModeNone,
}
// Now because we're not translating things properly let's just default some English strings here
@@ -287,8 +289,10 @@ func ServCommand(ctx *context.PrivateContext) {
repo.IsPrivate ||
owner.Visibility.IsPrivate() ||
(user != nil && user.IsRestricted) || // user will be nil if the key is a deploykey
+ (setting.Annex.Enabled && len(verbs) > 0 && verbs[0] == "git-annex-shell") || // git-annex has its own permission enforcement, for which we expose results.UserMode
setting.Service.RequireSignInView) {
if key.Type == asymkey_model.KeyTypeDeploy {
+ results.UserMode = deployKey.Mode
if deployKey.Mode < mode {
ctx.JSON(http.StatusUnauthorized, private.Response{
UserMsg: fmt.Sprintf("Deploy Key: %d:%s is not authorized to %s %s/%s.", key.ID, key.Name, modeString, results.OwnerName, results.RepoName),
@@ -296,8 +300,14 @@ func ServCommand(ctx *context.PrivateContext) {
return
}
} else {
- // Because of the special ref "refs/for" we will need to delay write permission check
- if git.SupportProcReceive && unitType == unit.TypeCode {
+ // We don't know yet which references the Git client wants to write to,
+ // but for AGit flow we have to degrade this check to a read permission.
+ // So if we support proc-receive (needed for AGit flow) and the unit type
+ // is code and we know the Git client wants to write to us, then degrade
+ // the permission check to read. The pre-receive hook will do another
+ // permission check which ensure for non AGit flow references the write
+ // permission is checked.
+ if git.SupportProcReceive && unitType == unit.TypeCode && ctx.FormString("verb") == "git-receive-pack" {
mode = perm.AccessModeRead
}
@@ -310,9 +320,9 @@ func ServCommand(ctx *context.PrivateContext) {
return
}
- userMode := perm.UnitAccessMode(unitType)
+ results.UserMode = perm.UnitAccessMode(unitType)
- if userMode < mode {
+ if results.UserMode < mode {
log.Warn("Failed authentication attempt for %s with key %s (not authorized to %s %s/%s) from %s", user.Name, key.Name, modeString, ownerName, repoName, ctx.RemoteAddr())
ctx.JSON(http.StatusUnauthorized, private.Response{
UserMsg: fmt.Sprintf("User: %d:%s with Key: %d:%s is not authorized to %s %s/%s.", user.ID, user.Name, key.ID, key.Name, modeString, ownerName, repoName),
@@ -353,6 +363,7 @@ func ServCommand(ctx *context.PrivateContext) {
})
return
}
+ results.UserMode = perm.AccessModeWrite
results.RepoID = repo.ID
}
@@ -381,13 +392,14 @@ func ServCommand(ctx *context.PrivateContext) {
return
}
}
- log.Debug("Serv Results:\nIsWiki: %t\nDeployKeyID: %d\nKeyID: %d\tKeyName: %s\nUserName: %s\nUserID: %d\nOwnerName: %s\nRepoName: %s\nRepoID: %d",
+ log.Debug("Serv Results:\nIsWiki: %t\nDeployKeyID: %d\nKeyID: %d\tKeyName: %s\nUserName: %s\nUserID: %d\nUserMode: %d\nOwnerName: %s\nRepoName: %s\nRepoID: %d",
results.IsWiki,
results.DeployKeyID,
results.KeyID,
results.KeyName,
results.UserName,
results.UserID,
+ results.UserMode,
results.OwnerName,
results.RepoName,
results.RepoID)
diff --git a/routers/private/ssh_log.go b/routers/private/ssh_log.go
index 5bec632ead..f6974967c0 100644
--- a/routers/private/ssh_log.go
+++ b/routers/private/ssh_log.go
@@ -6,11 +6,11 @@ package private
import (
"net/http"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
)
// SSHLog hook to response ssh log
diff --git a/routers/web/admin/admin.go b/routers/web/admin/admin.go
index 067203b28b..96a714376b 100644
--- a/routers/web/admin/admin.go
+++ b/routers/web/admin/admin.go
@@ -11,20 +11,20 @@ import (
"runtime"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/updatechecker"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/cron"
- "code.gitea.io/gitea/services/forms"
- release_service "code.gitea.io/gitea/services/release"
- repo_service "code.gitea.io/gitea/services/repository"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/updatechecker"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/cron"
+ "forgejo.org/services/forms"
+ release_service "forgejo.org/services/release"
+ repo_service "forgejo.org/services/repository"
)
const (
diff --git a/routers/web/admin/admin_test.go b/routers/web/admin/admin_test.go
index 3518869ede..d0c3c2b56f 100644
--- a/routers/web/admin/admin_test.go
+++ b/routers/web/admin/admin_test.go
@@ -6,11 +6,11 @@ package admin
import (
"testing"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
- "code.gitea.io/gitea/services/contexttest"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
)
diff --git a/routers/web/admin/applications.go b/routers/web/admin/applications.go
index 8583398074..ba15e0a000 100644
--- a/routers/web/admin/applications.go
+++ b/routers/web/admin/applications.go
@@ -7,12 +7,12 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- user_setting "code.gitea.io/gitea/routers/web/user/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ user_setting "forgejo.org/routers/web/user/setting"
+ "forgejo.org/services/context"
)
var (
diff --git a/routers/web/admin/auths.go b/routers/web/admin/auths.go
index 799b7e8a84..2c6dc76305 100644
--- a/routers/web/admin/auths.go
+++ b/routers/web/admin/auths.go
@@ -4,30 +4,26 @@
package admin
import (
- "errors"
"fmt"
"net/http"
"net/url"
- "regexp"
"strconv"
"strings"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/auth/pam"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- auth_service "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/ldap"
- "code.gitea.io/gitea/services/auth/source/oauth2"
- pam_service "code.gitea.io/gitea/services/auth/source/pam"
- "code.gitea.io/gitea/services/auth/source/smtp"
- "code.gitea.io/gitea/services/auth/source/sspi"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/auth/pam"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ auth_service "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/ldap"
+ "forgejo.org/services/auth/source/oauth2"
+ pam_service "forgejo.org/services/auth/source/pam"
+ "forgejo.org/services/auth/source/smtp"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
"xorm.io/xorm/convert"
)
@@ -38,11 +34,6 @@ const (
tplAuthEdit base.TplName = "admin/auth/edit"
)
-var (
- separatorAntiPattern = regexp.MustCompile(`[^\w-\.]`)
- langCodePattern = regexp.MustCompile(`^[a-z]{2}-[A-Z]{2}$`)
-)
-
// Authentications show authentication config page
func Authentications(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.authentication")
@@ -70,7 +61,6 @@ var (
{auth.DLDAP.String(), auth.DLDAP},
{auth.SMTP.String(), auth.SMTP},
{auth.OAuth2.String(), auth.OAuth2},
- {auth.SSPI.String(), auth.SSPI},
}
if pam.Supported {
items = append(items, dropdownItem{auth.Names[auth.PAM], auth.PAM})
@@ -102,12 +92,6 @@ func NewAuthSource(ctx *context.Context) {
oauth2providers := oauth2.GetSupportedOAuth2Providers()
ctx.Data["OAuth2Providers"] = oauth2providers
- ctx.Data["SSPIAutoCreateUsers"] = true
- ctx.Data["SSPIAutoActivateUsers"] = true
- ctx.Data["SSPIStripDomainNames"] = true
- ctx.Data["SSPISeparatorReplacement"] = "_"
- ctx.Data["SSPIDefaultLanguage"] = ""
-
// only the first as default
ctx.Data["oauth2_provider"] = oauth2providers[0].Name()
@@ -197,6 +181,7 @@ func parseOAuth2Config(form forms.AuthenticationForm) *oauth2.Source {
CustomURLMapping: customURLMapping,
IconURL: form.Oauth2IconURL,
Scopes: scopes,
+ AttributeSSHPublicKey: form.Oauth2AttributeSSHPublicKey,
RequiredClaimName: form.Oauth2RequiredClaimName,
RequiredClaimValue: form.Oauth2RequiredClaimValue,
SkipLocalTwoFA: form.SkipLocalTwoFA,
@@ -208,30 +193,6 @@ func parseOAuth2Config(form forms.AuthenticationForm) *oauth2.Source {
}
}
-func parseSSPIConfig(ctx *context.Context, form forms.AuthenticationForm) (*sspi.Source, error) {
- if util.IsEmptyString(form.SSPISeparatorReplacement) {
- ctx.Data["Err_SSPISeparatorReplacement"] = true
- return nil, errors.New(ctx.Locale.TrString("form.SSPISeparatorReplacement") + ctx.Locale.TrString("form.require_error"))
- }
- if separatorAntiPattern.MatchString(form.SSPISeparatorReplacement) {
- ctx.Data["Err_SSPISeparatorReplacement"] = true
- return nil, errors.New(ctx.Locale.TrString("form.SSPISeparatorReplacement") + ctx.Locale.TrString("form.alpha_dash_dot_error"))
- }
-
- if form.SSPIDefaultLanguage != "" && !langCodePattern.MatchString(form.SSPIDefaultLanguage) {
- ctx.Data["Err_SSPIDefaultLanguage"] = true
- return nil, errors.New(ctx.Locale.TrString("form.lang_select_error"))
- }
-
- return &sspi.Source{
- AutoCreateUsers: form.SSPIAutoCreateUsers,
- AutoActivateUsers: form.SSPIAutoActivateUsers,
- StripDomainNames: form.SSPIStripDomainNames,
- SeparatorReplacement: form.SSPISeparatorReplacement,
- DefaultLanguage: form.SSPIDefaultLanguage,
- }, nil
-}
-
// NewAuthSourcePost response for adding an auth source
func NewAuthSourcePost(ctx *context.Context) {
form := *web.GetForm(ctx).(*forms.AuthenticationForm)
@@ -246,12 +207,6 @@ func NewAuthSourcePost(ctx *context.Context) {
oauth2providers := oauth2.GetSupportedOAuth2Providers()
ctx.Data["OAuth2Providers"] = oauth2providers
- ctx.Data["SSPIAutoCreateUsers"] = true
- ctx.Data["SSPIAutoActivateUsers"] = true
- ctx.Data["SSPIStripDomainNames"] = true
- ctx.Data["SSPISeparatorReplacement"] = "_"
- ctx.Data["SSPIDefaultLanguage"] = ""
-
hasTLS := false
var config convert.Conversion
switch auth.Type(form.Type) {
@@ -278,19 +233,6 @@ func NewAuthSourcePost(ctx *context.Context) {
return
}
}
- case auth.SSPI:
- var err error
- config, err = parseSSPIConfig(ctx, form)
- if err != nil {
- ctx.RenderWithErr(err.Error(), tplAuthNew, form)
- return
- }
- existing, err := db.Find[auth.Source](ctx, auth.FindSourcesOptions{LoginType: auth.SSPI})
- if err != nil || len(existing) > 0 {
- ctx.Data["Err_Type"] = true
- ctx.RenderWithErr(ctx.Tr("admin.auths.login_source_of_type_exist"), tplAuthNew, form)
- return
- }
default:
ctx.Error(http.StatusBadRequest)
return
@@ -407,12 +349,6 @@ func EditAuthSourcePost(ctx *context.Context) {
return
}
}
- case auth.SSPI:
- config, err = parseSSPIConfig(ctx, form)
- if err != nil {
- ctx.RenderWithErr(err.Error(), tplAuthEdit, form)
- return
- }
default:
ctx.Error(http.StatusBadRequest)
return
diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go
index 09f332b447..f99a193960 100644
--- a/routers/web/admin/config.go
+++ b/routers/web/admin/config.go
@@ -10,19 +10,19 @@ import (
"strconv"
"strings"
- system_model "code.gitea.io/gitea/models/system"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/setting/config"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/mailer"
+ system_model "forgejo.org/models/system"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/setting/config"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
+ "forgejo.org/services/mailer"
- "gitea.com/go-chi/session"
+ "code.forgejo.org/go-chi/session"
)
const (
diff --git a/routers/web/admin/diagnosis.go b/routers/web/admin/diagnosis.go
index 020554a35a..8b0ec45214 100644
--- a/routers/web/admin/diagnosis.go
+++ b/routers/web/admin/diagnosis.go
@@ -5,27 +5,26 @@ package admin
import (
"archive/zip"
+ "bytes"
"fmt"
+ "io"
+ "runtime"
"runtime/pprof"
+ "runtime/trace"
"time"
- "code.gitea.io/gitea/modules/httplib"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/httplib"
+ "forgejo.org/services/context"
)
func MonitorDiagnosis(ctx *context.Context) {
seconds := ctx.FormInt64("seconds")
- if seconds <= 5 {
- seconds = 5
- }
- if seconds > 300 {
- seconds = 300
- }
+ seconds = max(5, min(300, seconds))
httplib.ServeSetHeaders(ctx.Resp, &httplib.ServeHeaderOptions{
ContentType: "application/zip",
Disposition: "attachment",
- Filename: fmt.Sprintf("gitea-diagnosis-%s.zip", time.Now().Format("20060102-150405")),
+ Filename: fmt.Sprintf("forgejo-diagnosis-%s.zip", time.Now().Format("20060102-150405")),
})
zipWriter := zip.NewWriter(ctx.Resp)
@@ -44,14 +43,33 @@ func MonitorDiagnosis(ctx *context.Context) {
return
}
- err = pprof.StartCPUProfile(f)
- if err == nil {
- time.Sleep(time.Duration(seconds) * time.Second)
- pprof.StopCPUProfile()
- } else {
+ if err := pprof.StartCPUProfile(f); err != nil {
_, _ = f.Write([]byte(err.Error()))
}
+ traceBuf := &bytes.Buffer{}
+ if err := trace.Start(traceBuf); err != nil {
+ _, _ = traceBuf.Write([]byte(err.Error()))
+ }
+
+ select {
+ case <-time.After(time.Duration(seconds) * time.Second):
+ case <-ctx.Done():
+ }
+ pprof.StopCPUProfile()
+ trace.Stop()
+
+ f, err = zipWriter.CreateHeader(&zip.FileHeader{Name: "trace.dat", Method: zip.Deflate, Modified: time.Now()})
+ if err != nil {
+ ctx.ServerError("Failed to create zip file", err)
+ return
+ }
+
+ if _, err := io.Copy(f, traceBuf); err != nil {
+ ctx.ServerError("Failed to create zip file", err)
+ return
+ }
+
f, err = zipWriter.CreateHeader(&zip.FileHeader{Name: "goroutine-after.txt", Method: zip.Deflate, Modified: time.Now()})
if err != nil {
ctx.ServerError("Failed to create zip file", err)
@@ -64,5 +82,8 @@ func MonitorDiagnosis(ctx *context.Context) {
ctx.ServerError("Failed to create zip file", err)
return
}
+ // To avoid showing memory that actually can be cleaned, run the garbage
+ // collector.
+ runtime.GC()
_ = pprof.Lookup("heap").WriteTo(f, 0)
}
diff --git a/routers/web/admin/emails.go b/routers/web/admin/emails.go
index 2cf4035c6a..a4421cf495 100644
--- a/routers/web/admin/emails.go
+++ b/routers/web/admin/emails.go
@@ -8,13 +8,14 @@ import (
"net/http"
"net/url"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+ "forgejo.org/services/user"
)
const (
@@ -150,3 +151,32 @@ func ActivateEmail(ctx *context.Context) {
redirect.RawQuery = q.Encode()
ctx.Redirect(redirect.String())
}
+
+// DeleteEmail serves a POST request for delete a user's email
+func DeleteEmail(ctx *context.Context) {
+ u, err := user_model.GetUserByID(ctx, ctx.FormInt64("Uid"))
+ if err != nil || u == nil {
+ ctx.ServerError("GetUserByID", err)
+ return
+ }
+
+ email, err := user_model.GetEmailAddressByID(ctx, u.ID, ctx.FormInt64("id"))
+ if err != nil || email == nil {
+ ctx.ServerError("GetEmailAddressByID", err)
+ return
+ }
+
+ if err := user.DeleteEmailAddresses(ctx, u, []string{email.Email}); err != nil {
+ if user_model.IsErrPrimaryEmailCannotDelete(err) {
+ ctx.Flash.Error(ctx.Tr("admin.emails.delete_primary_email_error"))
+ ctx.JSONRedirect("")
+ return
+ }
+ ctx.ServerError("DeleteEmailAddresses", err)
+ return
+ }
+ log.Trace("Email address deleted: %s %s", u.Name, email.Email)
+
+ ctx.Flash.Success(ctx.Tr("admin.emails.deletion_success"))
+ ctx.JSONRedirect("")
+}
diff --git a/routers/web/admin/hooks.go b/routers/web/admin/hooks.go
index c1f42c0061..aeceffe848 100644
--- a/routers/web/admin/hooks.go
+++ b/routers/web/admin/hooks.go
@@ -6,11 +6,11 @@ package admin
import (
"net/http"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ "forgejo.org/models/webhook"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+ webhook_service "forgejo.org/services/webhook"
)
const (
@@ -34,7 +34,7 @@ func DefaultOrSystemWebhooks(ctx *context.Context) {
}
sys["Title"] = ctx.Tr("admin.systemhooks")
- sys["Description"] = ctx.Tr("admin.systemhooks.desc")
+ sys["Description"] = ctx.Tr("admin.systemhooks.desc", "https://forgejo.org/docs/latest/user/webhooks/")
sys["Webhooks"], err = webhook.GetSystemWebhooks(ctx, false)
sys["BaseLink"] = setting.AppSubURL + "/admin/hooks"
sys["BaseLinkNew"] = setting.AppSubURL + "/admin/system-hooks"
@@ -45,7 +45,7 @@ func DefaultOrSystemWebhooks(ctx *context.Context) {
}
def["Title"] = ctx.Tr("admin.defaulthooks")
- def["Description"] = ctx.Tr("admin.defaulthooks.desc")
+ def["Description"] = ctx.Tr("admin.defaulthooks.desc", "https://forgejo.org/docs/latest/user/webhooks/")
def["Webhooks"], err = webhook.GetDefaultWebhooks(ctx)
def["BaseLink"] = setting.AppSubURL + "/admin/hooks"
def["BaseLinkNew"] = setting.AppSubURL + "/admin/default-hooks"
diff --git a/routers/web/admin/main_test.go b/routers/web/admin/main_test.go
index e1294ddbb4..bccb0d7058 100644
--- a/routers/web/admin/main_test.go
+++ b/routers/web/admin/main_test.go
@@ -6,7 +6,7 @@ package admin
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/admin/notice.go b/routers/web/admin/notice.go
index 36303cbc06..8bcaadf915 100644
--- a/routers/web/admin/notice.go
+++ b/routers/web/admin/notice.go
@@ -8,12 +8,12 @@ import (
"net/http"
"strconv"
- "code.gitea.io/gitea/models/db"
- system_model "code.gitea.io/gitea/models/system"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ system_model "forgejo.org/models/system"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/admin/orgs.go b/routers/web/admin/orgs.go
index cea28f8220..6ece35dcaf 100644
--- a/routers/web/admin/orgs.go
+++ b/routers/web/admin/orgs.go
@@ -5,13 +5,13 @@
package admin
import (
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/routers/web/explore"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/routers/web/explore"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/admin/packages.go b/routers/web/admin/packages.go
index 39f064a1be..5c80a1eada 100644
--- a/routers/web/admin/packages.go
+++ b/routers/web/admin/packages.go
@@ -8,14 +8,14 @@ import (
"net/url"
"time"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
- packages_service "code.gitea.io/gitea/services/packages"
- packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+ packages_service "forgejo.org/services/packages"
+ packages_cleanup_service "forgejo.org/services/packages/cleanup"
)
const (
diff --git a/routers/web/admin/queue.go b/routers/web/admin/queue.go
index 246ab379b5..03bbfe5af4 100644
--- a/routers/web/admin/queue.go
+++ b/routers/web/admin/queue.go
@@ -7,9 +7,9 @@ import (
"net/http"
"strconv"
- "code.gitea.io/gitea/modules/queue"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
func Queues(ctx *context.Context) {
diff --git a/routers/web/admin/queue_tester.go b/routers/web/admin/queue_tester.go
index 8f713b3bb1..831947fe41 100644
--- a/routers/web/admin/queue_tester.go
+++ b/routers/web/admin/queue_tester.go
@@ -8,11 +8,11 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/queue"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/setting"
)
var testQueueOnce sync.Once
diff --git a/routers/web/admin/repos.go b/routers/web/admin/repos.go
index d0339fdd93..a94b9bb5c3 100644
--- a/routers/web/admin/repos.go
+++ b/routers/web/admin/repos.go
@@ -8,16 +8,16 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/web/explore"
- "code.gitea.io/gitea/services/context"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/web/explore"
+ "forgejo.org/services/context"
+ repo_service "forgejo.org/services/repository"
)
const (
diff --git a/routers/web/admin/runners.go b/routers/web/admin/runners.go
index d73290a8db..c6451a9329 100644
--- a/routers/web/admin/runners.go
+++ b/routers/web/admin/runners.go
@@ -4,8 +4,8 @@
package admin
import (
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
func RedirectToDefaultSetting(ctx *context.Context) {
diff --git a/routers/web/admin/stacktrace.go b/routers/web/admin/stacktrace.go
index d6def94bb4..7c6cd98a56 100644
--- a/routers/web/admin/stacktrace.go
+++ b/routers/web/admin/stacktrace.go
@@ -7,9 +7,9 @@ import (
"net/http"
"runtime"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
// Stacktrace show admin monitor goroutines page
diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go
index ddd7045eb7..f6d214d24c 100644
--- a/routers/web/admin/users.go
+++ b/routers/web/admin/users.go
@@ -11,25 +11,26 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- org_model "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/password"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/web/explore"
- user_setting "code.gitea.io/gitea/routers/web/user/setting"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/mailer"
- user_service "code.gitea.io/gitea/services/user"
+ "forgejo.org/models"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ org_model "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/password"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/web/explore"
+ user_setting "forgejo.org/routers/web/user/setting"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/mailer"
+ user_service "forgejo.org/services/user"
)
const (
@@ -82,6 +83,7 @@ func Users(ctx *context.Context) {
IsTwoFactorEnabled: util.OptionalBoolParse(statusFilterMap["is_2fa_enabled"]),
IsProhibitLogin: util.OptionalBoolParse(statusFilterMap["is_prohibit_login"]),
IncludeReserved: true, // administrator needs to list all accounts include reserved, bot, remote ones
+ Load2FAStatus: true,
ExtraParamStrings: extraParamStrings,
}, tplUsers)
}
@@ -166,7 +168,7 @@ func NewUserPost(ctx *context.Context) {
}
if err := password.IsPwned(ctx, form.Password); err != nil {
ctx.Data["Err_Password"] = true
- errMsg := ctx.Tr("auth.password_pwned")
+ errMsg := ctx.Tr("auth.password_pwned", "https://haveibeenpwned.com/Passwords")
if password.IsErrIsPwnedRequest(err) {
log.Error(err.Error())
errMsg = ctx.Tr("auth.password_pwned_err")
@@ -185,7 +187,7 @@ func NewUserPost(ctx *context.Context) {
case user_model.IsErrEmailAlreadyUsed(err):
ctx.Data["Err_Email"] = true
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplUserNew, &form)
- case user_model.IsErrEmailInvalid(err), user_model.IsErrEmailCharIsNotSupported(err):
+ case validation.IsErrEmailInvalid(err), validation.IsErrEmailCharIsNotSupported(err):
ctx.Data["Err_Email"] = true
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplUserNew, &form)
case db.IsErrNameReserved(err):
@@ -203,7 +205,7 @@ func NewUserPost(ctx *context.Context) {
return
}
- if !user_model.IsEmailDomainAllowed(u.Email) {
+ if !validation.IsEmailDomainAllowed(u.Email) {
ctx.Flash.Warning(ctx.Tr("form.email_domain_is_not_allowed", u.Email))
}
@@ -247,7 +249,7 @@ func prepareUserInfo(ctx *context.Context) *user_model.User {
}
ctx.Data["Sources"] = sources
- hasTOTP, err := auth.HasTwoFactorByUID(ctx, u.ID)
+ hasTOTP, err := auth.HasTOTPByUID(ctx, u.ID)
if err != nil {
ctx.ServerError("auth.HasTwoFactorByUID", err)
return nil
@@ -348,7 +350,7 @@ func EditUserPost(ctx *context.Context) {
}
if form.UserName != "" {
- if err := user_service.RenameUser(ctx, u, form.UserName); err != nil {
+ if err := user_service.AdminRenameUser(ctx, u, form.UserName); err != nil {
switch {
case user_model.IsErrUserIsNotLocal(err):
ctx.Data["Err_UserName"] = true
@@ -401,7 +403,7 @@ func EditUserPost(ctx *context.Context) {
ctx.RenderWithErr(password.BuildComplexityError(ctx.Locale), tplUserEdit, &form)
case errors.Is(err, password.ErrIsPwned):
ctx.Data["Err_Password"] = true
- ctx.RenderWithErr(ctx.Tr("auth.password_pwned"), tplUserEdit, &form)
+ ctx.RenderWithErr(ctx.Tr("auth.password_pwned", "https://haveibeenpwned.com/Passwords"), tplUserEdit, &form)
case password.IsErrIsPwnedRequest(err):
ctx.Data["Err_Password"] = true
ctx.RenderWithErr(ctx.Tr("auth.password_pwned_err"), tplUserEdit, &form)
@@ -414,7 +416,7 @@ func EditUserPost(ctx *context.Context) {
if form.Email != "" {
if err := user_service.AdminAddOrSetPrimaryEmailAddress(ctx, u, form.Email); err != nil {
switch {
- case user_model.IsErrEmailCharIsNotSupported(err), user_model.IsErrEmailInvalid(err):
+ case validation.IsErrEmailCharIsNotSupported(err), validation.IsErrEmailInvalid(err):
ctx.Data["Err_Email"] = true
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplUserEdit, &form)
case user_model.IsErrEmailAlreadyUsed(err):
@@ -425,7 +427,7 @@ func EditUserPost(ctx *context.Context) {
}
return
}
- if !user_model.IsEmailDomainAllowed(form.Email) {
+ if !validation.IsEmailDomainAllowed(form.Email) {
ctx.Flash.Warning(ctx.Tr("form.email_domain_is_not_allowed", form.Email))
}
}
diff --git a/routers/web/admin/users_test.go b/routers/web/admin/users_test.go
index f6f9237858..c8e6f8cb86 100644
--- a/routers/web/admin/users_test.go
+++ b/routers/web/admin/users_test.go
@@ -6,15 +6,16 @@ package admin
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/contexttest"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/contexttest"
+ "forgejo.org/services/forms"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestNewUserPost_MustChangePassword(t *testing.T) {
@@ -48,7 +49,7 @@ func TestNewUserPost_MustChangePassword(t *testing.T) {
u, err := user_model.GetUserByName(ctx, username)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, username, u.Name)
assert.Equal(t, email, u.Email)
assert.True(t, u.MustChangePassword)
@@ -85,7 +86,7 @@ func TestNewUserPost_MustChangePasswordFalse(t *testing.T) {
u, err := user_model.GetUserByName(ctx, username)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, username, u.Name)
assert.Equal(t, email, u.Email)
assert.False(t, u.MustChangePassword)
@@ -152,7 +153,7 @@ func TestNewUserPost_VisibilityDefaultPublic(t *testing.T) {
u, err := user_model.GetUserByName(ctx, username)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, username, u.Name)
assert.Equal(t, email, u.Email)
// As default user visibility
@@ -191,7 +192,7 @@ func TestNewUserPost_VisibilityPrivate(t *testing.T) {
u, err := user_model.GetUserByName(ctx, username)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, username, u.Name)
assert.Equal(t, email, u.Email)
// As default user visibility
diff --git a/routers/web/auth/2fa.go b/routers/web/auth/2fa.go
index f93177bf96..7acf9a87d3 100644
--- a/routers/web/auth/2fa.go
+++ b/routers/web/auth/2fa.go
@@ -7,14 +7,14 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/externalaccount"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/externalaccount"
+ "forgejo.org/services/forms"
)
var (
diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go
index a738de380a..64006eeae8 100644
--- a/routers/web/auth/auth.go
+++ b/routers/web/auth/auth.go
@@ -5,36 +5,36 @@
package auth
import (
- "crypto/subtle"
- "encoding/hex"
"errors"
"fmt"
"net/http"
"strings"
+ "time"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/password"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/eventsource"
- "code.gitea.io/gitea/modules/httplib"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/session"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/modules/web/middleware"
- auth_service "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/oauth2"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/externalaccount"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/mailer"
- notify_service "code.gitea.io/gitea/services/notify"
- user_service "code.gitea.io/gitea/services/user"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/password"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/eventsource"
+ "forgejo.org/modules/httplib"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/session"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ "forgejo.org/modules/web/middleware"
+ auth_service "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/oauth2"
+ "forgejo.org/services/context"
+ "forgejo.org/services/externalaccount"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/mailer"
+ notify_service "forgejo.org/services/notify"
+ user_service "forgejo.org/services/user"
"github.com/markbates/goth"
)
@@ -62,38 +62,11 @@ func autoSignIn(ctx *context.Context) (bool, error) {
return false, nil
}
- lookupKey, validator, found := strings.Cut(authCookie, ":")
- if !found {
- return false, nil
- }
-
- authToken, err := auth.FindAuthToken(ctx, lookupKey)
+ u, _, err := user_model.VerifyUserAuthorizationToken(ctx, authCookie, auth.LongTermAuthorization)
if err != nil {
- if errors.Is(err, util.ErrNotExist) {
- return false, nil
- }
- return false, err
+ return false, fmt.Errorf("VerifyUserAuthorizationToken: %w", err)
}
-
- if authToken.IsExpired() {
- err = auth.DeleteAuthToken(ctx, authToken)
- return false, err
- }
-
- rawValidator, err := hex.DecodeString(validator)
- if err != nil {
- return false, err
- }
-
- if subtle.ConstantTimeCompare([]byte(authToken.HashedValidator), []byte(auth.HashValidator(rawValidator))) == 0 {
- return false, nil
- }
-
- u, err := user_model.GetUserByID(ctx, authToken.UID)
- if err != nil {
- if !user_model.IsErrUserNotExist(err) {
- return false, fmt.Errorf("GetUserByID: %w", err)
- }
+ if u == nil {
return false, nil
}
@@ -191,12 +164,14 @@ func SignIn(ctx *context.Context) {
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsLogin"] = true
- ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
+ ctx.Data["EnableInternalSignIn"] = setting.Service.EnableInternalSignIn
if setting.Service.EnableCaptcha && setting.Service.RequireCaptchaForLogin {
context.SetCaptchaData(ctx)
}
+ ctx.Data["DisablePassword"] = !setting.Service.EnableInternalSignIn
+
ctx.HTML(http.StatusOK, tplSignIn)
}
@@ -214,7 +189,14 @@ func SignInPost(ctx *context.Context) {
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsLogin"] = true
- ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
+ ctx.Data["EnableInternalSignIn"] = setting.Service.EnableInternalSignIn
+ ctx.Data["DisablePassword"] = !setting.Service.EnableInternalSignIn
+
+ // Permission denied if EnableInternalSignIn is false
+ if !setting.Service.EnableInternalSignIn {
+ ctx.Error(http.StatusForbidden)
+ return
+ }
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplSignIn)
@@ -236,23 +218,14 @@ func SignInPost(ctx *context.Context) {
if err != nil {
if errors.Is(err, util.ErrNotExist) || errors.Is(err, util.ErrInvalidArgument) {
ctx.RenderWithErr(ctx.Tr("form.username_password_incorrect"), tplSignIn, &form)
- log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
+ log.Warn("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
} else if user_model.IsErrEmailAlreadyUsed(err) {
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSignIn, &form)
- log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
+ log.Warn("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
} else if user_model.IsErrUserProhibitLogin(err) {
- log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
+ log.Warn("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
- } else if user_model.IsErrUserInactive(err) {
- if setting.Service.RegisterEmailConfirm {
- ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
- ctx.HTML(http.StatusOK, TplActivate)
- } else {
- log.Info("Failed authentication attempt for %s from %s: %v", form.UserName, ctx.RemoteAddr(), err)
- ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
- ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
- }
} else {
ctx.ServerError("UserSignIn", err)
}
@@ -269,7 +242,7 @@ func SignInPost(ctx *context.Context) {
// If this user is enrolled in 2FA TOTP, we can't sign the user in just yet.
// Instead, redirect them to the 2FA authentication page.
- hasTOTPtwofa, err := auth.HasTwoFactorByUID(ctx, u.ID)
+ hasTOTPtwofa, err := auth.HasTOTPByUID(ctx, u.ID)
if err != nil {
ctx.ServerError("UserSignIn", err)
return
@@ -408,7 +381,7 @@ func HandleSignOut(ctx *context.Context) {
// SignOut sign out from login status
func SignOut(ctx *context.Context) {
if ctx.Doer != nil {
- eventsource.GetManager().SendMessageBlocking(ctx.Doer.ID, &eventsource.Event{
+ eventsource.GetManager().SendMessage(ctx.Doer.ID, &eventsource.Event{
Name: "logout",
Data: ctx.Session.ID(),
})
@@ -500,7 +473,7 @@ func SignUpPost(ctx *context.Context) {
return
}
if err := password.IsPwned(ctx, form.Password); err != nil {
- errMsg := ctx.Tr("auth.password_pwned")
+ errMsg := ctx.Tr("auth.password_pwned", "https://haveibeenpwned.com/Passwords")
if password.IsErrIsPwnedRequest(err) {
log.Error(err.Error())
errMsg = ctx.Tr("auth.password_pwned_err")
@@ -575,10 +548,13 @@ func createUserInContext(ctx *context.Context, tpl base.TplName, form any, u *us
case user_model.IsErrEmailAlreadyUsed(err):
ctx.Data["Err_Email"] = true
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tpl, form)
- case user_model.IsErrEmailCharIsNotSupported(err):
+ case user_model.IsErrCooldownPeriod(err):
+ ctx.Data["Err_UserName"] = true
+ ctx.RenderWithErr(ctx.Locale.Tr("form.username_claiming_cooldown", err.(user_model.ErrCooldownPeriod).ExpireTime.Format(time.RFC1123Z)), tpl, form)
+ case validation.IsErrEmailCharIsNotSupported(err):
ctx.Data["Err_Email"] = true
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tpl, form)
- case user_model.IsErrEmailInvalid(err):
+ case validation.IsErrEmailInvalid(err):
ctx.Data["Err_Email"] = true
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tpl, form)
case db.IsErrNameReserved(err):
@@ -634,7 +610,10 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.
return false
}
- mailer.SendActivateAccountMail(ctx.Locale, u)
+ if err := mailer.SendActivateAccountMail(ctx, u); err != nil {
+ ctx.ServerError("SendActivateAccountMail", err)
+ return false
+ }
ctx.Data["IsSendRegisterMail"] = true
ctx.Data["Email"] = u.Email
@@ -675,7 +654,10 @@ func Activate(ctx *context.Context) {
ctx.Data["ResendLimited"] = true
} else {
ctx.Data["ActiveCodeLives"] = timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, ctx.Locale)
- mailer.SendActivateAccountMail(ctx.Locale, ctx.Doer)
+ if err := mailer.SendActivateAccountMail(ctx, ctx.Doer); err != nil {
+ ctx.ServerError("SendActivateAccountMail", err)
+ return
+ }
if err := ctx.Cache.Put(cacheKey+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil {
log.Error("Set cache(MailResendLimit) fail: %v", err)
@@ -688,7 +670,12 @@ func Activate(ctx *context.Context) {
return
}
- user := user_model.VerifyUserActiveCode(ctx, code)
+ user, deleteToken, err := user_model.VerifyUserAuthorizationToken(ctx, code, auth.UserActivation)
+ if err != nil {
+ ctx.ServerError("VerifyUserAuthorizationToken", err)
+ return
+ }
+
// if code is wrong
if user == nil {
ctx.Data["IsCodeInvalid"] = true
@@ -704,6 +691,11 @@ func Activate(ctx *context.Context) {
return
}
+ if err := deleteToken(); err != nil {
+ ctx.ServerError("deleteToken", err)
+ return
+ }
+
handleAccountActivation(ctx, user)
}
@@ -752,7 +744,12 @@ func ActivatePost(ctx *context.Context) {
return
}
- user := user_model.VerifyUserActiveCode(ctx, code)
+ user, deleteToken, err := user_model.VerifyUserAuthorizationToken(ctx, code, auth.UserActivation)
+ if err != nil {
+ ctx.ServerError("VerifyUserAuthorizationToken", err)
+ return
+ }
+
// if code is wrong
if user == nil {
ctx.Data["IsCodeInvalid"] = true
@@ -776,6 +773,11 @@ func ActivatePost(ctx *context.Context) {
}
}
+ if err := deleteToken(); err != nil {
+ ctx.ServerError("deleteToken", err)
+ return
+ }
+
handleAccountActivation(ctx, user)
}
@@ -836,23 +838,37 @@ func ActivateEmail(ctx *context.Context) {
code := ctx.FormString("code")
emailStr := ctx.FormString("email")
- // Verify code.
- if email := user_model.VerifyActiveEmailCode(ctx, code, emailStr); email != nil {
- if err := user_model.ActivateEmail(ctx, email); err != nil {
- ctx.ServerError("ActivateEmail", err)
- return
- }
-
- log.Trace("Email activated: %s", email.Email)
- ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
-
- if u, err := user_model.GetUserByID(ctx, email.UID); err != nil {
- log.Warn("GetUserByID: %d", email.UID)
- } else {
- // Allow user to validate more emails
- _ = ctx.Cache.Delete("MailResendLimit_" + u.LowerName)
- }
+ u, deleteToken, err := user_model.VerifyUserAuthorizationToken(ctx, code, auth.EmailActivation(emailStr))
+ if err != nil {
+ ctx.ServerError("VerifyUserAuthorizationToken", err)
+ return
}
+ if u == nil {
+ ctx.Redirect(setting.AppSubURL + "/user/settings/account")
+ return
+ }
+
+ if err := deleteToken(); err != nil {
+ ctx.ServerError("deleteToken", err)
+ return
+ }
+
+ email, err := user_model.GetEmailAddressOfUser(ctx, emailStr, u.ID)
+ if err != nil {
+ ctx.ServerError("GetEmailAddressOfUser", err)
+ return
+ }
+
+ if err := user_model.ActivateEmail(ctx, email); err != nil {
+ ctx.ServerError("ActivateEmail", err)
+ return
+ }
+
+ log.Trace("Email activated: %s", email.Email)
+ ctx.Flash.Success(ctx.Tr("settings.add_email_success"))
+
+ // Allow user to validate more emails
+ _ = ctx.Cache.Delete("MailResendLimit_" + u.LowerName)
// FIXME: e-mail verification does not require the user to be logged in,
// so this could be redirecting to the login page.
diff --git a/routers/web/auth/auth_test.go b/routers/web/auth/auth_test.go
index c6afbf877c..7a33a3841c 100644
--- a/routers/web/auth/auth_test.go
+++ b/routers/web/auth/auth_test.go
@@ -8,8 +8,8 @@ import (
"net/url"
"testing"
- "code.gitea.io/gitea/modules/test"
- "code.gitea.io/gitea/services/contexttest"
+ "forgejo.org/modules/test"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
)
diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go
index f744a57a43..fbf03ca475 100644
--- a/routers/web/auth/linkaccount.go
+++ b/routers/web/auth/linkaccount.go
@@ -9,18 +9,18 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- auth_service "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/oauth2"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/externalaccount"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ auth_service "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/oauth2"
+ "forgejo.org/services/context"
+ "forgejo.org/services/externalaccount"
+ "forgejo.org/services/forms"
"github.com/markbates/goth"
)
@@ -40,9 +40,11 @@ func LinkAccount(ctx *context.Context) {
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
+ ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
ctx.Data["AllowOnlyInternalRegistration"] = setting.Service.AllowOnlyInternalRegistration
ctx.Data["ShowRegistrationButton"] = false
+ ctx.Data["EnableInternalSignIn"] = true
// use this to set the right link into the signIn and signUp templates in the link_account template
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/link_account_signin"
@@ -98,16 +100,6 @@ func handleSignInError(ctx *context.Context, userName string, ptrForm any, tmpl
log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err)
ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
- } else if user_model.IsErrUserInactive(err) {
- ctx.Data["user_exists"] = true
- if setting.Service.RegisterEmailConfirm {
- ctx.Data["Title"] = ctx.Tr("auth.active_your_account")
- ctx.HTML(http.StatusOK, TplActivate)
- } else {
- log.Info("Failed authentication attempt for %s from %s: %v", userName, ctx.RemoteAddr(), err)
- ctx.Data["Title"] = ctx.Tr("auth.prohibit_login")
- ctx.HTML(http.StatusOK, "user/auth/prohibit_login")
- }
} else {
ctx.ServerError(invoker, err)
}
@@ -128,8 +120,10 @@ func LinkAccountPostSignIn(ctx *context.Context) {
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
+ ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
ctx.Data["ShowRegistrationButton"] = false
+ ctx.Data["EnableInternalSignIn"] = true
// use this to set the right link into the signIn and signUp templates in the link_account template
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/link_account_signin"
@@ -161,15 +155,14 @@ func linkAccount(ctx *context.Context, u *user_model.User, gothUser goth.User, r
// If this user is enrolled in 2FA, we can't sign the user in just yet.
// Instead, redirect them to the 2FA authentication page.
// We deliberately ignore the skip local 2fa setting here because we are linking to a previous user here
- _, err := auth.GetTwoFactorByUID(ctx, u.ID)
+ hasTwoFactor, err := auth.HasTwoFactorByUID(ctx, u.ID)
if err != nil {
- if !auth.IsErrTwoFactorNotEnrolled(err) {
- ctx.ServerError("UserLinkAccount", err)
- return
- }
+ ctx.ServerError("UserLinkAccount", err)
+ return
+ }
- err = externalaccount.LinkAccountToUser(ctx, u, gothUser)
- if err != nil {
+ if !hasTwoFactor {
+ if err := externalaccount.LinkAccountToUser(ctx, u, gothUser); err != nil {
ctx.ServerError("UserLinkAccount", err)
return
}
@@ -215,6 +208,7 @@ func LinkAccountPostRegister(ctx *context.Context) {
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
+ ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
ctx.Data["ShowRegistrationButton"] = false
diff --git a/routers/web/auth/main_test.go b/routers/web/auth/main_test.go
index b438e5d518..a8a32b71f2 100644
--- a/routers/web/auth/main_test.go
+++ b/routers/web/auth/main_test.go
@@ -6,7 +6,7 @@ package auth
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/auth/oauth.go b/routers/web/auth/oauth.go
index d133d9dae1..aa599bd252 100644
--- a/routers/web/auth/oauth.go
+++ b/routers/web/auth/oauth.go
@@ -17,30 +17,31 @@ import (
"sort"
"strings"
- "code.gitea.io/gitea/models/auth"
- org_model "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
- auth_module "code.gitea.io/gitea/modules/auth"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/modules/web/middleware"
- auth_service "code.gitea.io/gitea/services/auth"
- source_service "code.gitea.io/gitea/services/auth/source"
- "code.gitea.io/gitea/services/auth/source/oauth2"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/externalaccount"
- "code.gitea.io/gitea/services/forms"
- remote_service "code.gitea.io/gitea/services/remote"
- user_service "code.gitea.io/gitea/services/user"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/auth"
+ org_model "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ auth_module "forgejo.org/modules/auth"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/modules/web/middleware"
+ auth_service "forgejo.org/services/auth"
+ source_service "forgejo.org/services/auth/source"
+ "forgejo.org/services/auth/source/oauth2"
+ "forgejo.org/services/context"
+ "forgejo.org/services/externalaccount"
+ "forgejo.org/services/forms"
+ remote_service "forgejo.org/services/remote"
+ user_service "forgejo.org/services/user"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
"github.com/golang-jwt/jwt/v5"
"github.com/markbates/goth"
"github.com/markbates/goth/gothic"
@@ -231,7 +232,7 @@ func newAccessTokenResponse(ctx go_context.Context, grant *auth.OAuth2Grant, ser
Nonce: grant.Nonce,
}
if grant.ScopeContains("profile") {
- idToken.Name = user.GetDisplayName()
+ idToken.Name = user.DisplayName()
idToken.PreferredUsername = user.Name
idToken.Profile = user.HTMLURL()
idToken.Picture = user.AvatarLink(ctx)
@@ -244,7 +245,9 @@ func newAccessTokenResponse(ctx go_context.Context, grant *auth.OAuth2Grant, ser
idToken.EmailVerified = user.IsActive
}
if grant.ScopeContains("groups") {
- groups, err := getOAuthGroupsForUser(ctx, user)
+ onlyPublicGroups := ifOnlyPublicGroups(grant.Scope)
+
+ groups, err := getOAuthGroupsForUser(ctx, user, onlyPublicGroups)
if err != nil {
log.Error("Error getting groups: %v", err)
return nil, &AccessTokenError{
@@ -279,7 +282,18 @@ type userInfoResponse struct {
Username string `json:"preferred_username"`
Email string `json:"email"`
Picture string `json:"picture"`
- Groups []string `json:"groups"`
+ Groups []string `json:"groups,omitempty"`
+}
+
+func ifOnlyPublicGroups(scopes string) bool {
+ scopes = strings.ReplaceAll(scopes, ",", " ")
+ scopesList := strings.Fields(scopes)
+ for _, scope := range scopesList {
+ if scope == "all" || scope == "read:organization" || scope == "read:admin" {
+ return false
+ }
+ }
+ return true
}
// InfoOAuth manages request for userinfo endpoint
@@ -292,13 +306,24 @@ func InfoOAuth(ctx *context.Context) {
response := &userInfoResponse{
Sub: fmt.Sprint(ctx.Doer.ID),
- Name: ctx.Doer.FullName,
+ Name: ctx.Doer.DisplayName(),
Username: ctx.Doer.Name,
Email: ctx.Doer.Email,
Picture: ctx.Doer.AvatarLink(ctx),
}
- groups, err := getOAuthGroupsForUser(ctx, ctx.Doer)
+ var token string
+ if auHead := ctx.Req.Header.Get("Authorization"); auHead != "" {
+ auths := strings.Fields(auHead)
+ if len(auths) == 2 && (auths[0] == "token" || strings.ToLower(auths[0]) == "bearer") {
+ token = auths[1]
+ }
+ }
+
+ _, grantScopes := auth_service.CheckOAuthAccessToken(ctx, token)
+ onlyPublicGroups := ifOnlyPublicGroups(grantScopes)
+
+ groups, err := getOAuthGroupsForUser(ctx, ctx.Doer, onlyPublicGroups)
if err != nil {
ctx.ServerError("Oauth groups for user", err)
return
@@ -310,7 +335,7 @@ func InfoOAuth(ctx *context.Context) {
// returns a list of "org" and "org:team" strings,
// that the given user is a part of.
-func getOAuthGroupsForUser(ctx go_context.Context, user *user_model.User) ([]string, error) {
+func getOAuthGroupsForUser(ctx go_context.Context, user *user_model.User, onlyPublicGroups bool) ([]string, error) {
orgs, err := org_model.GetUserOrgsList(ctx, user)
if err != nil {
return nil, fmt.Errorf("GetUserOrgList: %w", err)
@@ -318,6 +343,15 @@ func getOAuthGroupsForUser(ctx go_context.Context, user *user_model.User) ([]str
var groups []string
for _, org := range orgs {
+ if setting.OAuth2.EnableAdditionalGrantScopes {
+ if onlyPublicGroups {
+ public, err := org_model.IsPublicMembership(ctx, org.ID, user.ID)
+ if !public && err == nil {
+ continue
+ }
+ }
+ }
+
groups = append(groups, org.Name)
teams, err := org.LoadTeams(ctx)
if err != nil {
@@ -332,17 +366,37 @@ func getOAuthGroupsForUser(ctx go_context.Context, user *user_model.User) ([]str
return groups, nil
}
+func parseBasicAuth(ctx *context.Context) (username, password string, err error) {
+ authHeader := ctx.Req.Header.Get("Authorization")
+ if authType, authData, ok := strings.Cut(authHeader, " "); ok && strings.EqualFold(authType, "Basic") {
+ return base.BasicAuthDecode(authData)
+ }
+ return "", "", errors.New("invalid basic authentication")
+}
+
// IntrospectOAuth introspects an oauth token
func IntrospectOAuth(ctx *context.Context) {
- if ctx.Doer == nil {
- ctx.Resp.Header().Set("WWW-Authenticate", `Bearer realm=""`)
+ clientIDValid := false
+ if clientID, clientSecret, err := parseBasicAuth(ctx); err == nil {
+ app, err := auth.GetOAuth2ApplicationByClientID(ctx, clientID)
+ if err != nil && !auth.IsErrOauthClientIDInvalid(err) {
+ // this is likely a database error; log it and respond without details
+ log.Error("Error retrieving client_id: %v", err)
+ ctx.Error(http.StatusInternalServerError)
+ return
+ }
+ clientIDValid = err == nil && app.ValidateClientSecret([]byte(clientSecret))
+ }
+ if !clientIDValid {
+ ctx.Resp.Header().Set("WWW-Authenticate", `Basic realm=""`)
ctx.PlainText(http.StatusUnauthorized, "no valid authorization")
return
}
var response struct {
- Active bool `json:"active"`
- Scope string `json:"scope,omitempty"`
+ Active bool `json:"active"`
+ Scope string `json:"scope,omitempty"`
+ Username string `json:"username,omitempty"`
jwt.RegisteredClaims
}
@@ -359,6 +413,9 @@ func IntrospectOAuth(ctx *context.Context) {
response.Audience = []string{app.ClientID}
response.Subject = fmt.Sprint(grant.UserID)
}
+ if user, err := user_model.GetUserByID(ctx, grant.UserID); err == nil {
+ response.Username = user.Name
+ }
}
}
@@ -471,7 +528,7 @@ func AuthorizeOAuth(ctx *context.Context) {
grant, err := app.GetGrantByUserID(ctx, ctx.Doer.ID)
if err != nil {
- handleServerError(ctx, form.State, form.RedirectURI)
+ handleServerError(ctx, form.State, form.RedirectURI, err)
return
}
@@ -480,12 +537,12 @@ func AuthorizeOAuth(ctx *context.Context) {
if app.ConfidentialClient && grant != nil {
code, err := grant.GenerateNewAuthorizationCode(ctx, form.RedirectURI, form.CodeChallenge, form.CodeChallengeMethod)
if err != nil {
- handleServerError(ctx, form.State, form.RedirectURI)
+ handleServerError(ctx, form.State, form.RedirectURI, err)
return
}
redirect, err := code.GenerateRedirectURI(form.State)
if err != nil {
- handleServerError(ctx, form.State, form.RedirectURI)
+ handleServerError(ctx, form.State, form.RedirectURI, err)
return
}
// Update nonce to reflect the new session
@@ -514,19 +571,19 @@ func AuthorizeOAuth(ctx *context.Context) {
// TODO document SESSION <=> FORM
err = ctx.Session.Set("client_id", app.ClientID)
if err != nil {
- handleServerError(ctx, form.State, form.RedirectURI)
+ handleServerError(ctx, form.State, form.RedirectURI, err)
log.Error(err.Error())
return
}
err = ctx.Session.Set("redirect_uri", form.RedirectURI)
if err != nil {
- handleServerError(ctx, form.State, form.RedirectURI)
+ handleServerError(ctx, form.State, form.RedirectURI, err)
log.Error(err.Error())
return
}
err = ctx.Session.Set("state", form.State)
if err != nil {
- handleServerError(ctx, form.State, form.RedirectURI)
+ handleServerError(ctx, form.State, form.RedirectURI, err)
log.Error(err.Error())
return
}
@@ -563,7 +620,7 @@ func GrantApplicationOAuth(ctx *context.Context) {
}
grant, err := app.GetGrantByUserID(ctx, ctx.Doer.ID)
if err != nil {
- handleServerError(ctx, form.State, form.RedirectURI)
+ handleServerError(ctx, form.State, form.RedirectURI, err)
return
}
if grant == nil {
@@ -598,12 +655,12 @@ func GrantApplicationOAuth(ctx *context.Context) {
code, err := grant.GenerateNewAuthorizationCode(ctx, form.RedirectURI, codeChallenge, codeChallengeMethod)
if err != nil {
- handleServerError(ctx, form.State, form.RedirectURI)
+ handleServerError(ctx, form.State, form.RedirectURI, err)
return
}
redirect, err := code.GenerateRedirectURI(form.State)
if err != nil {
- handleServerError(ctx, form.State, form.RedirectURI)
+ handleServerError(ctx, form.State, form.RedirectURI, err)
return
}
ctx.Redirect(redirect.String(), http.StatusSeeOther)
@@ -645,9 +702,8 @@ func AccessTokenOAuth(ctx *context.Context) {
// if there is no ClientID or ClientSecret in the request body, fill these fields by the Authorization header and ensure the provided field matches the Authorization header
if form.ClientID == "" || form.ClientSecret == "" {
authHeader := ctx.Req.Header.Get("Authorization")
- authContent := strings.SplitN(authHeader, " ", 2)
- if len(authContent) == 2 && authContent[0] == "Basic" {
- payload, err := base64.StdEncoding.DecodeString(authContent[1])
+ if authType, authData, ok := strings.Cut(authHeader, " "); ok && strings.EqualFold(authType, "Basic") {
+ clientID, clientSecret, err := base.BasicAuthDecode(authData)
if err != nil {
handleAccessTokenError(ctx, AccessTokenError{
ErrorCode: AccessTokenErrorCodeInvalidRequest,
@@ -655,30 +711,23 @@ func AccessTokenOAuth(ctx *context.Context) {
})
return
}
- pair := strings.SplitN(string(payload), ":", 2)
- if len(pair) != 2 {
- handleAccessTokenError(ctx, AccessTokenError{
- ErrorCode: AccessTokenErrorCodeInvalidRequest,
- ErrorDescription: "cannot parse basic auth header",
- })
- return
- }
- if form.ClientID != "" && form.ClientID != pair[0] {
+ // validate that any fields present in the form match the Basic auth header
+ if form.ClientID != "" && form.ClientID != clientID {
handleAccessTokenError(ctx, AccessTokenError{
ErrorCode: AccessTokenErrorCodeInvalidRequest,
ErrorDescription: "client_id in request body inconsistent with Authorization header",
})
return
}
- form.ClientID = pair[0]
- if form.ClientSecret != "" && form.ClientSecret != pair[1] {
+ form.ClientID = clientID
+ if form.ClientSecret != "" && form.ClientSecret != clientSecret {
handleAccessTokenError(ctx, AccessTokenError{
ErrorCode: AccessTokenErrorCodeInvalidRequest,
ErrorDescription: "client_secret in request body inconsistent with Authorization header",
})
return
}
- form.ClientSecret = pair[1]
+ form.ClientSecret = clientSecret
}
}
@@ -840,7 +889,8 @@ func handleAccessTokenError(ctx *context.Context, acErr AccessTokenError) {
ctx.JSON(http.StatusBadRequest, acErr)
}
-func handleServerError(ctx *context.Context, state, redirectURI string) {
+func handleServerError(ctx *context.Context, state, redirectURI string, err error) {
+ log.Error("OAuth server error: %v", err)
handleAuthorizeError(ctx, AuthorizeError{
ErrorCode: ErrorCodeServerError,
ErrorDescription: "A server error occurred",
@@ -964,6 +1014,8 @@ func SignInOAuthCallback(ctx *context.Context) {
}
if err, ok := err.(*go_oauth2.RetrieveError); ok {
ctx.Flash.Error("OAuth2 RetrieveError: "+err.Error(), true)
+ ctx.Redirect(setting.AppSubURL + "/user/login")
+ return
}
ctx.ServerError("UserSignIn", err)
return
@@ -1027,7 +1079,7 @@ func SignInOAuthCallback(ctx *context.Context) {
isAdmin, isRestricted := getUserAdminAndRestrictedFromGroupClaims(source, &gothUser)
u.IsAdmin = isAdmin.ValueOrDefault(false)
- u.IsRestricted = isRestricted.ValueOrDefault(false)
+ u.IsRestricted = isRestricted.ValueOrDefault(setting.Service.DefaultUserIsRestricted)
if !createAndHandleCreatedUser(ctx, base.TplName(""), nil, u, overwriteDefault, &gothUser, setting.OAuth2Client.AccountLinking != setting.OAuth2AccountLinkingDisabled) {
// error already handled
@@ -1132,17 +1184,70 @@ func updateAvatarIfNeed(ctx *context.Context, url string, u *user_model.User) {
}
}
+func getSSHKeys(source *oauth2.Source, gothUser *goth.User) ([]string, error) {
+ key := source.AttributeSSHPublicKey
+ value, exists := gothUser.RawData[key]
+ if !exists {
+ return []string{}, nil
+ }
+
+ rawSlice, ok := value.([]any)
+ if !ok {
+ return nil, fmt.Errorf("unexpected type for SSH public key, expected []interface{} but got %T", value)
+ }
+
+ sshKeys := make([]string, 0, len(rawSlice))
+ for i, v := range rawSlice {
+ str, ok := v.(string)
+ if !ok {
+ return nil, fmt.Errorf("unexpected element type at index %d in SSH public key array, expected string but got %T", i, v)
+ }
+ sshKeys = append(sshKeys, str)
+ }
+
+ return sshKeys, nil
+}
+
+func updateSSHPubIfNeed(
+ ctx *context.Context,
+ authSource *auth.Source,
+ fetchedUser *goth.User,
+ user *user_model.User,
+) error {
+ oauth2Source := authSource.Cfg.(*oauth2.Source)
+
+ if oauth2Source.ProvidesSSHKeys() {
+ sshKeys, err := getSSHKeys(oauth2Source, fetchedUser)
+ if err != nil {
+ return err
+ }
+
+ if asymkey_model.SynchronizePublicKeys(ctx, user, authSource, sshKeys) {
+ err = asymkey_model.RewriteAllPublicKeys(ctx)
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ return nil
+}
+
func handleOAuth2SignIn(ctx *context.Context, source *auth.Source, u *user_model.User, gothUser goth.User) {
updateAvatarIfNeed(ctx, gothUser.AvatarURL, u)
+ err := updateSSHPubIfNeed(ctx, source, &gothUser, u)
+ if err != nil {
+ ctx.ServerError("updateSSHPubIfNeed", err)
+ return
+ }
needs2FA := false
if !source.Cfg.(*oauth2.Source).SkipLocalTwoFA {
- _, err := auth.GetTwoFactorByUID(ctx, u.ID)
- if err != nil && !auth.IsErrTwoFactorNotEnrolled(err) {
+ needs2FA, err = auth.HasTwoFactorByUID(ctx, u.ID)
+ if err != nil {
ctx.ServerError("UserSignIn", err)
return
}
- needs2FA = err == nil
}
oauth2Source := source.Cfg.(*oauth2.Source)
diff --git a/routers/web/auth/oauth_test.go b/routers/web/auth/oauth_test.go
index 3726daee93..6275d63382 100644
--- a/routers/web/auth/oauth_test.go
+++ b/routers/web/auth/oauth_test.go
@@ -6,20 +6,21 @@ package auth
import (
"testing"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/auth/source/oauth2"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/services/auth/source/oauth2"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func createAndParseToken(t *testing.T, grant *auth.OAuth2Grant) *oauth2.OIDCToken {
signingKey, err := oauth2.CreateJWTSigningKey("HS256", make([]byte, 32))
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.NotNil(t, signingKey)
response, terr := newAccessTokenResponse(db.DefaultContext, grant, signingKey, signingKey)
@@ -31,7 +32,7 @@ func createAndParseToken(t *testing.T, grant *auth.OAuth2Grant) *oauth2.OIDCToke
assert.Equal(t, signingKey.SigningMethod().Alg(), token.Method.Alg())
return signingKey.VerifyKey(), nil
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, parsedToken.Valid)
oidcToken, ok := parsedToken.Claims.(*oauth2.OIDCToken)
@@ -42,10 +43,10 @@ func createAndParseToken(t *testing.T, grant *auth.OAuth2Grant) *oauth2.OIDCToke
}
func TestNewAccessTokenResponse_OIDCToken(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
grants, err := auth.GetOAuth2GrantsByUserID(db.DefaultContext, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, grants, 1)
// Scopes: openid
@@ -61,42 +62,24 @@ func TestNewAccessTokenResponse_OIDCToken(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
grants, err = auth.GetOAuth2GrantsByUserID(db.DefaultContext, user.ID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, grants, 1)
// Scopes: openid profile email
oidcToken = createAndParseToken(t, grants[0])
- assert.Equal(t, user.Name, oidcToken.Name)
- assert.Equal(t, user.Name, oidcToken.PreferredUsername)
- assert.Equal(t, user.HTMLURL(), oidcToken.Profile)
- assert.Equal(t, user.AvatarLink(db.DefaultContext), oidcToken.Picture)
- assert.Equal(t, user.Website, oidcToken.Website)
- assert.Equal(t, user.UpdatedUnix, oidcToken.UpdatedAt)
- assert.Equal(t, user.Email, oidcToken.Email)
- assert.Equal(t, user.IsActive, oidcToken.EmailVerified)
-
- // set DefaultShowFullName to true
- oldDefaultShowFullName := setting.UI.DefaultShowFullName
- setting.UI.DefaultShowFullName = true
- defer func() {
- setting.UI.DefaultShowFullName = oldDefaultShowFullName
- }()
-
- // Scopes: openid profile email
- oidcToken = createAndParseToken(t, grants[0])
- assert.Equal(t, user.FullName, oidcToken.Name)
- assert.Equal(t, user.Name, oidcToken.PreferredUsername)
- assert.Equal(t, user.HTMLURL(), oidcToken.Profile)
- assert.Equal(t, user.AvatarLink(db.DefaultContext), oidcToken.Picture)
- assert.Equal(t, user.Website, oidcToken.Website)
- assert.Equal(t, user.UpdatedUnix, oidcToken.UpdatedAt)
- assert.Equal(t, user.Email, oidcToken.Email)
- assert.Equal(t, user.IsActive, oidcToken.EmailVerified)
+ assert.Equal(t, "User Five", oidcToken.Name)
+ assert.Equal(t, "user5", oidcToken.PreferredUsername)
+ assert.Equal(t, "https://try.gitea.io/user5", oidcToken.Profile)
+ assert.Equal(t, "https://try.gitea.io/assets/img/avatar_default.png", oidcToken.Picture)
+ assert.Equal(t, "", oidcToken.Website)
+ assert.Equal(t, timeutil.TimeStamp(0), oidcToken.UpdatedAt)
+ assert.Equal(t, "user5@example.com", oidcToken.Email)
+ assert.True(t, oidcToken.EmailVerified)
}
func TestEncodeCodeChallenge(t *testing.T) {
// test vector from https://datatracker.ietf.org/doc/html/rfc7636#page-18
codeChallenge, err := encodeCodeChallenge("dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM", codeChallenge)
}
diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go
index 2143b8096a..b12dea84ea 100644
--- a/routers/web/auth/openid.go
+++ b/routers/web/auth/openid.go
@@ -8,16 +8,16 @@ import (
"net/http"
"net/url"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/openid"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/openid"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
const (
@@ -307,6 +307,7 @@ func RegisterOpenID(ctx *context.Context) {
ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
+ ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
ctx.Data["OpenID"] = oid
userName, _ := ctx.Session.Get("openid_determined_username").(string)
if userName != "" {
diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go
index d15a8b814c..82c2d4e9d3 100644
--- a/routers/web/auth/password.go
+++ b/routers/web/auth/password.go
@@ -8,20 +8,20 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/password"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/mailer"
- user_service "code.gitea.io/gitea/services/user"
+ "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/password"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/web"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/mailer"
+ user_service "forgejo.org/services/user"
)
var (
@@ -86,7 +86,10 @@ func ForgotPasswdPost(ctx *context.Context) {
return
}
- mailer.SendResetPasswordMail(u)
+ if err := mailer.SendResetPasswordMail(ctx, u); err != nil {
+ ctx.ServerError("SendResetPasswordMail", err)
+ return
+ }
if err = ctx.Cache.Put("MailResendLimit_"+u.LowerName, u.LowerName, 180); err != nil {
log.Error("Set cache(MailResendLimit) fail: %v", err)
@@ -97,7 +100,7 @@ func ForgotPasswdPost(ctx *context.Context) {
ctx.HTML(http.StatusOK, tplForgotPassword)
}
-func commonResetPassword(ctx *context.Context) (*user_model.User, *auth.TwoFactor) {
+func commonResetPassword(ctx *context.Context, shouldDeleteToken bool) (*user_model.User, *auth.TwoFactor) {
code := ctx.FormString("code")
ctx.Data["Title"] = ctx.Tr("auth.reset_password")
@@ -113,12 +116,24 @@ func commonResetPassword(ctx *context.Context) (*user_model.User, *auth.TwoFacto
}
// Fail early, don't frustrate the user
- u := user_model.VerifyUserActiveCode(ctx, code)
+ u, deleteToken, err := user_model.VerifyUserAuthorizationToken(ctx, code, auth.PasswordReset)
+ if err != nil {
+ ctx.ServerError("VerifyUserAuthorizationToken", err)
+ return nil, nil
+ }
+
if u == nil {
ctx.Flash.Error(ctx.Tr("auth.invalid_code_forgot_password", fmt.Sprintf("%s/user/forgot_password", setting.AppSubURL)), true)
return nil, nil
}
+ if shouldDeleteToken {
+ if err := deleteToken(); err != nil {
+ ctx.ServerError("deleteToken", err)
+ return nil, nil
+ }
+ }
+
twofa, err := auth.GetTwoFactorByUID(ctx, u.ID)
if err != nil {
if !auth.IsErrTwoFactorNotEnrolled(err) {
@@ -145,7 +160,7 @@ func commonResetPassword(ctx *context.Context) (*user_model.User, *auth.TwoFacto
func ResetPasswd(ctx *context.Context) {
ctx.Data["IsResetForm"] = true
- commonResetPassword(ctx)
+ commonResetPassword(ctx, false)
if ctx.Written() {
return
}
@@ -155,7 +170,7 @@ func ResetPasswd(ctx *context.Context) {
// ResetPasswdPost response from account recovery request
func ResetPasswdPost(ctx *context.Context) {
- u, twofa := commonResetPassword(ctx)
+ u, twofa := commonResetPassword(ctx, true)
if ctx.Written() {
return
}
@@ -212,7 +227,7 @@ func ResetPasswdPost(ctx *context.Context) {
case errors.Is(err, password.ErrComplexity):
ctx.RenderWithErr(password.BuildComplexityError(ctx.Locale), tplResetPassword, nil)
case errors.Is(err, password.ErrIsPwned):
- ctx.RenderWithErr(ctx.Tr("auth.password_pwned"), tplResetPassword, nil)
+ ctx.RenderWithErr(ctx.Tr("auth.password_pwned", "https://haveibeenpwned.com/Passwords"), tplResetPassword, nil)
case password.IsErrIsPwnedRequest(err):
ctx.RenderWithErr(ctx.Tr("auth.password_pwned_err"), tplResetPassword, nil)
default:
@@ -295,7 +310,7 @@ func MustChangePasswordPost(ctx *context.Context) {
ctx.RenderWithErr(password.BuildComplexityError(ctx.Locale), tplMustChangePassword, &form)
case errors.Is(err, password.ErrIsPwned):
ctx.Data["Err_Password"] = true
- ctx.RenderWithErr(ctx.Tr("auth.password_pwned"), tplMustChangePassword, &form)
+ ctx.RenderWithErr(ctx.Tr("auth.password_pwned", "https://haveibeenpwned.com/Passwords"), tplMustChangePassword, &form)
case password.IsErrIsPwnedRequest(err):
ctx.Data["Err_Password"] = true
ctx.RenderWithErr(ctx.Tr("auth.password_pwned_err"), tplMustChangePassword, &form)
diff --git a/routers/web/auth/webauthn.go b/routers/web/auth/webauthn.go
index 1079f44a08..3da6199b6e 100644
--- a/routers/web/auth/webauthn.go
+++ b/routers/web/auth/webauthn.go
@@ -7,14 +7,14 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- wa "code.gitea.io/gitea/modules/auth/webauthn"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/externalaccount"
+ "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ wa "forgejo.org/modules/auth/webauthn"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+ "forgejo.org/services/externalaccount"
"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/webauthn"
@@ -36,7 +36,7 @@ func WebAuthn(ctx *context.Context) {
return
}
- hasTwoFactor, err := auth.HasTwoFactorByUID(ctx, ctx.Session.Get("twofaUid").(int64))
+ hasTwoFactor, err := auth.HasTOTPByUID(ctx, ctx.Session.Get("twofaUid").(int64))
if err != nil {
ctx.ServerError("HasTwoFactorByUID", err)
return
@@ -116,6 +116,25 @@ func WebAuthnLoginAssertionPost(ctx *context.Context) {
return
}
+ dbCred, err := auth.GetWebAuthnCredentialByCredID(ctx, user.ID, parsedResponse.RawID)
+ if err != nil {
+ ctx.ServerError("GetWebAuthnCredentialByCredID", err)
+ return
+ }
+
+ // If the credential is legacy, assume the values are correct. The
+ // specification mandates these flags don't change.
+ if dbCred.Legacy {
+ dbCred.BackupEligible = parsedResponse.Response.AuthenticatorData.Flags.HasBackupEligible()
+ dbCred.BackupState = parsedResponse.Response.AuthenticatorData.Flags.HasBackupState()
+ dbCred.Legacy = false
+
+ if err := dbCred.UpdateFromLegacy(ctx); err != nil {
+ ctx.ServerError("UpdateFromLegacy", err)
+ return
+ }
+ }
+
// Validate the parsed response.
cred, err := wa.WebAuthn.ValidateLogin((*wa.User)(user), *sessionData, parsedResponse)
if err != nil {
@@ -133,13 +152,6 @@ func WebAuthnLoginAssertionPost(ctx *context.Context) {
return
}
- // Success! Get the credential and update the sign count with the new value we received.
- dbCred, err := auth.GetWebAuthnCredentialByCredID(ctx, user.ID, cred.ID)
- if err != nil {
- ctx.ServerError("GetWebAuthnCredentialByCredID", err)
- return
- }
-
dbCred.SignCount = cred.Authenticator.SignCount
if err := dbCred.UpdateSignCount(ctx); err != nil {
ctx.ServerError("UpdateSignCount", err)
diff --git a/routers/web/base.go b/routers/web/base.go
index 78dde57fa6..c1bc7fef5e 100644
--- a/routers/web/base.go
+++ b/routers/web/base.go
@@ -11,12 +11,12 @@ import (
"path"
"strings"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web/routing"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web/routing"
)
func storageHandler(storageSetting *setting.Storage, prefix string, objStore storage.ObjectStorage) http.HandlerFunc {
@@ -39,7 +39,7 @@ func storageHandler(storageSetting *setting.Storage, prefix string, objStore sto
rPath := strings.TrimPrefix(req.URL.Path, "/"+prefix+"/")
rPath = util.PathJoinRelX(rPath)
- u, err := objStore.URL(rPath, path.Base(rPath))
+ u, err := objStore.URL(rPath, path.Base(rPath), nil)
if err != nil {
if os.IsNotExist(err) || errors.Is(err, os.ErrNotExist) {
log.Warn("Unable to find %s %s", prefix, rPath)
diff --git a/routers/web/devtest/devtest.go b/routers/web/devtest/devtest.go
index dd20663f94..37496ca117 100644
--- a/routers/web/devtest/devtest.go
+++ b/routers/web/devtest/devtest.go
@@ -9,9 +9,9 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/templates"
+ "forgejo.org/services/context"
)
// List all devtest templates, they will be used for e2e tests for the UI components
diff --git a/routers/web/events/events.go b/routers/web/events/events.go
index 52f20e07dc..1672f12bda 100644
--- a/routers/web/events/events.go
+++ b/routers/web/events/events.go
@@ -7,11 +7,11 @@ import (
"net/http"
"time"
- "code.gitea.io/gitea/modules/eventsource"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/routers/web/auth"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/eventsource"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/routers/web/auth"
+ "forgejo.org/services/context"
)
// Events listens for events
diff --git a/routers/web/explore/code.go b/routers/web/explore/code.go
index f61b832572..f0b12e9142 100644
--- a/routers/web/explore/code.go
+++ b/routers/web/explore/code.go
@@ -6,12 +6,12 @@ package explore
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/base"
- code_indexer "code.gitea.io/gitea/modules/indexer/code"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/base"
+ code_indexer "forgejo.org/modules/indexer/code"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
const (
@@ -21,12 +21,13 @@ const (
// Code render explore code page
func Code(ctx *context.Context) {
- if !setting.Indexer.RepoIndexerEnabled {
+ if !setting.Indexer.RepoIndexerEnabled || setting.Service.Explore.DisableCodePage {
ctx.Redirect(setting.AppSubURL + "/explore")
return
}
- ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
+ ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage
+ ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
ctx.Data["Title"] = ctx.Tr("explore")
ctx.Data["PageIsExplore"] = true
@@ -34,12 +35,19 @@ func Code(ctx *context.Context) {
language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q")
+ path := ctx.FormTrim("path")
- isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true)
+ mode := code_indexer.SearchModeExact
+ if m := ctx.FormTrim("mode"); m == "union" ||
+ m == "fuzzy" ||
+ ctx.FormBool("fuzzy") {
+ mode = code_indexer.SearchModeUnion
+ }
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
- ctx.Data["IsFuzzy"] = isFuzzy
+ ctx.Data["CodeSearchOptions"] = code_indexer.CodeSearchOptions
+ ctx.Data["CodeSearchMode"] = mode.String()
ctx.Data["PageIsViewCode"] = true
if keyword == "" {
@@ -78,10 +86,11 @@ func Code(ctx *context.Context) {
if (len(repoIDs) > 0) || isAdmin {
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{
- RepoIDs: repoIDs,
- Keyword: keyword,
- IsKeywordFuzzy: isFuzzy,
- Language: language,
+ RepoIDs: repoIDs,
+ Keyword: keyword,
+ Mode: mode,
+ Language: language,
+ Filename: path,
Paginator: &db.ListOptions{
Page: page,
PageSize: setting.UI.RepoSearchPagingNum,
diff --git a/routers/web/explore/org.go b/routers/web/explore/org.go
index f8fd6ec38e..6c9293e959 100644
--- a/routers/web/explore/org.go
+++ b/routers/web/explore/org.go
@@ -4,17 +4,23 @@
package explore
import (
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
)
// Organizations render explore organizations page
func Organizations(ctx *context.Context) {
- ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
+ if setting.Service.Explore.DisableOrganizationsPage {
+ ctx.Redirect(setting.AppSubURL + "/explore")
+ return
+ }
+
+ ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage
+ ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage
ctx.Data["Title"] = ctx.Tr("explore")
ctx.Data["PageIsExplore"] = true
ctx.Data["PageIsExploreOrganizations"] = true
@@ -33,7 +39,11 @@ func Organizations(ctx *context.Context) {
)
sortOrder := ctx.FormString("sort")
if sortOrder == "" {
- sortOrder = "newest"
+ if supportedSortOrders.Contains(setting.UI.ExploreDefaultSort) {
+ sortOrder = setting.UI.ExploreDefaultSort
+ } else {
+ sortOrder = "newest"
+ }
ctx.SetFormString("sort", sortOrder)
}
diff --git a/routers/web/explore/repo.go b/routers/web/explore/repo.go
index 4e880660b1..0707420a8d 100644
--- a/routers/web/explore/repo.go
+++ b/routers/web/explore/repo.go
@@ -6,15 +6,14 @@ package explore
import (
"fmt"
"net/http"
- "strings"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/sitemap"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/sitemap"
+ "forgejo.org/services/context"
)
const (
@@ -58,7 +57,7 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
orderBy db.SearchOrderBy
)
- sortOrder := strings.ToLower(ctx.FormString("sort"))
+ sortOrder := ctx.FormString("sort")
if sortOrder == "" {
sortOrder = setting.UI.ExploreDefaultSort
}
@@ -144,6 +143,21 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
pager.AddParam(ctx, "topic", "TopicOnly")
pager.AddParam(ctx, "language", "Language")
pager.AddParamString(relevantReposOnlyParam, fmt.Sprint(opts.OnlyShowRelevant))
+ if archived.Has() {
+ pager.AddParamString("archived", fmt.Sprint(archived.Value()))
+ }
+ if fork.Has() {
+ pager.AddParamString("fork", fmt.Sprint(fork.Value()))
+ }
+ if mirror.Has() {
+ pager.AddParamString("mirror", fmt.Sprint(mirror.Value()))
+ }
+ if template.Has() {
+ pager.AddParamString("template", fmt.Sprint(template.Value()))
+ }
+ if private.Has() {
+ pager.AddParamString("private", fmt.Sprint(private.Value()))
+ }
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, opts.TplName)
@@ -151,7 +165,9 @@ func RenderRepoSearch(ctx *context.Context, opts *RepoSearchOptions) {
// Repos render explore repositories page
func Repos(ctx *context.Context) {
- ctx.Data["UsersIsDisabled"] = setting.Service.Explore.DisableUsersPage
+ ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage
+ ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage
+ ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage
ctx.Data["Title"] = ctx.Tr("explore")
ctx.Data["PageIsExplore"] = true
ctx.Data["PageIsExploreRepositories"] = true
diff --git a/routers/web/explore/topic.go b/routers/web/explore/topic.go
index 95fecfe2b8..3b67bd48b1 100644
--- a/routers/web/explore/topic.go
+++ b/routers/web/explore/topic.go
@@ -6,11 +6,11 @@ package explore
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// TopicSearch search for creating topic
diff --git a/routers/web/explore/user.go b/routers/web/explore/user.go
index b79a79fb2c..e349bb1e92 100644
--- a/routers/web/explore/user.go
+++ b/routers/web/explore/user.go
@@ -7,16 +7,16 @@ import (
"bytes"
"net/http"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/sitemap"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/sitemap"
+ "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
)
const (
@@ -114,7 +114,9 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
ctx.Data["Keyword"] = opts.Keyword
ctx.Data["Total"] = count
ctx.Data["Users"] = users
- ctx.Data["UsersTwoFaStatus"] = user_model.UserList(users).GetTwoFaStatus(ctx)
+ if opts.Load2FAStatus {
+ ctx.Data["UsersTwoFaStatus"] = user_model.UserList(users).GetTwoFaStatus(ctx)
+ }
ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
@@ -131,9 +133,11 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,
// Users render explore users page
func Users(ctx *context.Context) {
if setting.Service.Explore.DisableUsersPage {
- ctx.Redirect(setting.AppSubURL + "/explore/repos")
+ ctx.Redirect(setting.AppSubURL + "/explore")
return
}
+ ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage
+ ctx.Data["CodePageIsDisabled"] = setting.Service.Explore.DisableCodePage
ctx.Data["Title"] = ctx.Tr("explore")
ctx.Data["PageIsExplore"] = true
ctx.Data["PageIsExploreUsers"] = true
@@ -147,7 +151,11 @@ func Users(ctx *context.Context) {
)
sortOrder := ctx.FormString("sort")
if sortOrder == "" {
- sortOrder = "newest"
+ if supportedSortOrders.Contains(setting.UI.ExploreDefaultSort) {
+ sortOrder = setting.UI.ExploreDefaultSort
+ } else {
+ sortOrder = "newest"
+ }
ctx.SetFormString("sort", sortOrder)
}
diff --git a/routers/web/feed/branch.go b/routers/web/feed/branch.go
index 80ce2ad198..2337b43d4c 100644
--- a/routers/web/feed/branch.go
+++ b/routers/web/feed/branch.go
@@ -8,8 +8,8 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/repo"
+ "forgejo.org/services/context"
"github.com/gorilla/feeds"
)
@@ -43,6 +43,7 @@ func ShowBranchFeed(ctx *context.Context, repo *repo.Repository, formatType stri
},
Description: commit.Message(),
Content: commit.Message(),
+ Created: commit.Committer.When,
})
}
diff --git a/routers/web/feed/convert.go b/routers/web/feed/convert.go
index 9ed57ec48c..24532334ea 100644
--- a/routers/web/feed/convert.go
+++ b/routers/web/feed/convert.go
@@ -12,14 +12,16 @@ import (
"strconv"
"strings"
- activities_model "code.gitea.io/gitea/models/activities"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ activities_model "forgejo.org/models/activities"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
"github.com/gorilla/feeds"
"github.com/jaytaylor/html2text"
@@ -84,7 +86,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
link := &feeds.Link{Href: act.GetCommentHTMLURL(ctx)}
// title
- title = act.ActUser.DisplayName() + " "
+ title = act.ActUser.GetDisplayName() + " "
var titleExtra template.HTML
switch act.OpType {
case activities_model.ActionCreateRepo:
@@ -232,6 +234,16 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
case activities_model.ActionCommentIssue, activities_model.ActionApprovePullRequest, activities_model.ActionRejectPullRequest, activities_model.ActionCommentPull:
desc = act.GetIssueTitle(ctx)
comment := act.GetIssueInfos()[1]
+ if strings.HasSuffix(comment, "โฆ") {
+ // Comment was truncated get the full content from the database.
+ // This truncation is done in `NotifyCreateIssueComment`.
+ commentModel, err := issues_model.GetCommentByID(ctx, act.CommentID)
+ if err != nil {
+ log.Error("Couldn't get comment[%d] for RSS feed: %v", act.CommentID, err)
+ } else {
+ comment = commentModel.Content
+ }
+ }
if len(comment) != 0 {
desc += "\n\n" + string(renderMarkdown(ctx, act, comment))
}
@@ -260,7 +272,7 @@ func feedActionsToFeedItems(ctx *context.Context, actions activities_model.Actio
Description: desc,
IsPermaLink: "false",
Author: &feeds.Author{
- Name: act.ActUser.DisplayName(),
+ Name: act.ActUser.GetDisplayName(),
Email: act.ActUser.GetEmail(),
},
Id: fmt.Sprintf("%v: %v", strconv.FormatInt(act.ID, 10), link.Href),
@@ -286,14 +298,14 @@ func GetFeedType(name string, req *http.Request) (bool, string, string) {
return false, name, ""
}
-// feedActionsToFeedItems convert gitea's Repo's Releases to feeds Item
-func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release) (items []*feeds.Item, err error) {
- for _, rel := range releases {
- err := rel.LoadAttributes(ctx)
- if err != nil {
- return nil, err
- }
+// feedActionsToFeedItems convert repository releases into feed items.
+func releasesToFeedItems(ctx *context.Context, releases repo_model.ReleaseList) (items []*feeds.Item, err error) {
+ if err := releases.LoadAttributes(ctx); err != nil {
+ return nil, err
+ }
+ composeCache := make(map[int64]map[string]string)
+ for _, rel := range releases {
var title string
var content template.HTML
@@ -303,13 +315,19 @@ func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release) (
title = rel.Title
}
+ metas, ok := composeCache[rel.RepoID]
+ if !ok {
+ metas = rel.Repo.ComposeMetas(ctx)
+ composeCache[rel.RepoID] = metas
+ }
+
link := &feeds.Link{Href: rel.HTMLURL()}
content, err = markdown.RenderString(&markup.RenderContext{
Ctx: ctx,
Links: markup.Links{
Base: rel.Repo.Link(),
},
- Metas: rel.Repo.ComposeMetas(ctx),
+ Metas: metas,
}, rel.Note)
if err != nil {
return nil, err
@@ -320,7 +338,7 @@ func releasesToFeedItems(ctx *context.Context, releases []*repo_model.Release) (
Link: link,
Created: rel.CreatedUnix.AsTime(),
Author: &feeds.Author{
- Name: rel.Publisher.DisplayName(),
+ Name: rel.Publisher.GetDisplayName(),
Email: rel.Publisher.GetEmail(),
},
Id: fmt.Sprintf("%v: %v", strconv.FormatInt(rel.ID, 10), link.Href),
diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go
index 1ab768ff27..45ceedac12 100644
--- a/routers/web/feed/file.go
+++ b/routers/web/feed/file.go
@@ -8,10 +8,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
"github.com/gorilla/feeds"
)
@@ -55,6 +55,7 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string
},
Description: commit.Message(),
Content: commit.Message(),
+ Created: commit.Committer.When,
})
}
diff --git a/routers/web/feed/profile.go b/routers/web/feed/profile.go
index 08cbcd9e12..dd2fec186f 100644
--- a/routers/web/feed/profile.go
+++ b/routers/web/feed/profile.go
@@ -6,10 +6,10 @@ package feed
import (
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/services/context"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/services/context"
"github.com/gorilla/feeds"
)
diff --git a/routers/web/feed/release.go b/routers/web/feed/release.go
index fb6e3add65..646241c021 100644
--- a/routers/web/feed/release.go
+++ b/routers/web/feed/release.go
@@ -6,9 +6,9 @@ package feed
import (
"time"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/services/context"
"github.com/gorilla/feeds"
)
diff --git a/routers/web/feed/render.go b/routers/web/feed/render.go
index dc99fb49ed..79681dd0fb 100644
--- a/routers/web/feed/render.go
+++ b/routers/web/feed/render.go
@@ -4,7 +4,7 @@
package feed
import (
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/services/context"
)
// RenderBranchFeed render format for branch or file
diff --git a/routers/web/feed/repo.go b/routers/web/feed/repo.go
index a0033c7d45..0d105dc3a7 100644
--- a/routers/web/feed/repo.go
+++ b/routers/web/feed/repo.go
@@ -6,9 +6,9 @@ package feed
import (
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/services/context"
+ activities_model "forgejo.org/models/activities"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/services/context"
"github.com/gorilla/feeds"
)
diff --git a/routers/web/githttp.go b/routers/web/githttp.go
index 5f1dedce76..e5ed806f2e 100644
--- a/routers/web/githttp.go
+++ b/routers/web/githttp.go
@@ -6,10 +6,10 @@ package web
import (
"net/http"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/web/repo"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/web/repo"
+ "forgejo.org/services/context"
)
func requireSignIn(ctx *context.Context) {
diff --git a/routers/web/goget.go b/routers/web/goget.go
index 8d5612ebfe..0fcd755ca1 100644
--- a/routers/web/goget.go
+++ b/routers/web/goget.go
@@ -11,10 +11,10 @@ import (
"path"
"strings"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
)
func goGet(ctx *context.Context) {
diff --git a/routers/web/healthcheck/check.go b/routers/web/healthcheck/check.go
index 83dfe62537..f0b51aa515 100644
--- a/routers/web/healthcheck/check.go
+++ b/routers/web/healthcheck/check.go
@@ -9,11 +9,11 @@ import (
"os"
"time"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
type status string
diff --git a/routers/web/home.go b/routers/web/home.go
index d4be0931e8..e0a466a81c 100644
--- a/routers/web/home.go
+++ b/routers/web/home.go
@@ -8,19 +8,19 @@ import (
"net/http"
"strconv"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/sitemap"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/routers/web/auth"
- "code.gitea.io/gitea/routers/web/user"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/sitemap"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/routers/web/auth"
+ "forgejo.org/routers/web/user"
+ "forgejo.org/services/context"
)
const (
@@ -61,6 +61,9 @@ func Home(ctx *context.Context) {
ctx.Data["PageIsHome"] = true
ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
+
+ ctx.Data["OpenGraphDescription"] = setting.UI.Meta.Description
+
ctx.HTML(http.StatusOK, tplHome)
}
diff --git a/routers/web/metrics.go b/routers/web/metrics.go
index 46c13f0a24..8c188e206e 100644
--- a/routers/web/metrics.go
+++ b/routers/web/metrics.go
@@ -7,7 +7,7 @@ import (
"crypto/subtle"
"net/http"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
diff --git a/routers/web/misc/markup.go b/routers/web/misc/markup.go
index 2dbbd6fc09..d2b67f88c8 100644
--- a/routers/web/misc/markup.go
+++ b/routers/web/misc/markup.go
@@ -5,14 +5,24 @@
package misc
import (
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/services/context"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/context"
)
// Markup render markup document to HTML
func Markup(ctx *context.Context) {
form := web.GetForm(ctx).(*api.MarkupOption)
- common.RenderMarkup(ctx.Base, ctx.Repo, form.Mode, form.Text, form.Context, form.FilePath, form.Wiki)
+
+ re := common.Renderer{
+ Mode: form.Mode,
+ Text: form.Text,
+ URLPrefix: form.Context,
+ FilePath: form.FilePath,
+ BranchPath: form.BranchPath,
+ IsWiki: form.Wiki,
+ }
+
+ re.RenderMarkup(ctx.Base, ctx.Repo)
}
diff --git a/routers/web/misc/misc.go b/routers/web/misc/misc.go
index 54c93763f6..306b15e3d5 100644
--- a/routers/web/misc/misc.go
+++ b/routers/web/misc/misc.go
@@ -7,11 +7,11 @@ import (
"net/http"
"path"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
func SSHInfo(rw http.ResponseWriter, req *http.Request) {
diff --git a/routers/web/misc/swagger-forgejo.go b/routers/web/misc/swagger-forgejo.go
index e3aff02c5f..17e3814712 100644
--- a/routers/web/misc/swagger-forgejo.go
+++ b/routers/web/misc/swagger-forgejo.go
@@ -6,8 +6,8 @@ package misc
import (
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/services/context"
)
// tplSwagger swagger page template
diff --git a/routers/web/misc/swagger.go b/routers/web/misc/swagger.go
index 5fddfa8885..226dddaff2 100644
--- a/routers/web/misc/swagger.go
+++ b/routers/web/misc/swagger.go
@@ -6,8 +6,8 @@ package misc
import (
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/services/context"
)
// tplSwagger swagger page template
diff --git a/routers/web/nodeinfo.go b/routers/web/nodeinfo.go
index f1cc7bf530..d8c1727479 100644
--- a/routers/web/nodeinfo.go
+++ b/routers/web/nodeinfo.go
@@ -7,8 +7,8 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
type nodeInfoLinks struct {
diff --git a/routers/web/org/home.go b/routers/web/org/home.go
index 71d10f3a43..a3823565ed 100644
--- a/routers/web/org/home.go
+++ b/routers/web/org/home.go
@@ -4,22 +4,23 @@
package org
import (
+ "fmt"
"net/http"
"path"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
)
const (
@@ -46,33 +47,19 @@ func Home(ctx *context.Context) {
ctx.Data["PageIsUserProfile"] = true
ctx.Data["Title"] = org.DisplayName()
+ ctx.Data["OpenGraphTitle"] = ctx.ContextUser.DisplayName()
+ ctx.Data["OpenGraphType"] = "profile"
+ ctx.Data["OpenGraphImageURL"] = ctx.ContextUser.AvatarLink(ctx)
+ ctx.Data["OpenGraphURL"] = ctx.ContextUser.HTMLURL()
+ ctx.Data["OpenGraphDescription"] = ctx.ContextUser.Description
+
var orderBy db.SearchOrderBy
- ctx.Data["SortType"] = ctx.FormString("sort")
- switch ctx.FormString("sort") {
- case "newest":
- orderBy = db.SearchOrderByNewest
- case "oldest":
- orderBy = db.SearchOrderByOldest
- case "recentupdate":
- orderBy = db.SearchOrderByRecentUpdated
- case "leastupdate":
- orderBy = db.SearchOrderByLeastUpdated
- case "reversealphabetically":
- orderBy = db.SearchOrderByAlphabeticallyReverse
- case "alphabetically":
- orderBy = db.SearchOrderByAlphabetically
- case "moststars":
- orderBy = db.SearchOrderByStarsReverse
- case "feweststars":
- orderBy = db.SearchOrderByStars
- case "mostforks":
- orderBy = db.SearchOrderByForksReverse
- case "fewestforks":
- orderBy = db.SearchOrderByForks
- default:
- ctx.Data["SortType"] = "recentupdate"
- orderBy = db.SearchOrderByRecentUpdated
+ sortOrder := ctx.FormString("sort")
+ if _, ok := repo_model.OrderByFlatMap[sortOrder]; !ok {
+ sortOrder = setting.UI.ExploreDefaultSort // TODO: add new default sort order for org home?
}
+ ctx.Data["SortType"] = sortOrder
+ orderBy = repo_model.OrderByFlatMap[sortOrder]
keyword := ctx.FormTrim("q")
ctx.Data["Keyword"] = keyword
@@ -129,10 +116,12 @@ func Home(ctx *context.Context) {
}
opts := &organization.FindOrgMembersOpts{
- OrgID: org.ID,
- PublicOnly: ctx.Org.PublicMemberOnly,
- ListOptions: db.ListOptions{Page: 1, PageSize: 25},
+ Doer: ctx.Doer,
+ OrgID: org.ID,
+ IsDoerMember: ctx.Org.IsMember,
+ ListOptions: db.ListOptions{Page: 1, PageSize: 25},
}
+
members, _, err := organization.FindOrgMembers(ctx, opts)
if err != nil {
ctx.ServerError("FindOrgMembers", err)
@@ -154,7 +143,22 @@ func Home(ctx *context.Context) {
pager := context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
pager.SetDefaultParams(ctx)
- pager.AddParam(ctx, "language", "Language")
+ pager.AddParamString("language", language)
+ if archived.Has() {
+ pager.AddParamString("archived", fmt.Sprint(archived.Value()))
+ }
+ if fork.Has() {
+ pager.AddParamString("fork", fmt.Sprint(fork.Value()))
+ }
+ if mirror.Has() {
+ pager.AddParamString("mirror", fmt.Sprint(mirror.Value()))
+ }
+ if template.Has() {
+ pager.AddParamString("template", fmt.Sprint(template.Value()))
+ }
+ if private.Has() {
+ pager.AddParamString("private", fmt.Sprint(private.Value()))
+ }
ctx.Data["Page"] = pager
ctx.Data["ShowMemberAndTeamTab"] = ctx.Org.IsMember || len(members) > 0
diff --git a/routers/web/org/main_test.go b/routers/web/org/main_test.go
index 92237d6e88..d1d4e89120 100644
--- a/routers/web/org/main_test.go
+++ b/routers/web/org/main_test.go
@@ -6,7 +6,7 @@ package org_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/org/members.go b/routers/web/org/members.go
index 9a3d60e122..51ac566e1a 100644
--- a/routers/web/org/members.go
+++ b/routers/web/org/members.go
@@ -7,13 +7,13 @@ package org
import (
"net/http"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models"
+ "forgejo.org/models/organization"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
)
const (
@@ -33,8 +33,8 @@ func Members(ctx *context.Context) {
}
opts := &organization.FindOrgMembersOpts{
- OrgID: org.ID,
- PublicOnly: true,
+ Doer: ctx.Doer,
+ OrgID: org.ID,
}
if ctx.Doer != nil {
@@ -43,9 +43,9 @@ func Members(ctx *context.Context) {
ctx.Error(http.StatusInternalServerError, "IsOrgMember")
return
}
- opts.PublicOnly = !isMember && !ctx.Doer.IsAdmin
+ opts.IsDoerMember = isMember
}
- ctx.Data["PublicOnly"] = opts.PublicOnly
+ ctx.Data["PublicOnly"] = opts.PublicOnly()
total, err := organization.CountOrgMembers(ctx, opts)
if err != nil {
diff --git a/routers/web/org/org.go b/routers/web/org/org.go
index f94dd16eae..e9907c04af 100644
--- a/routers/web/org/org.go
+++ b/routers/web/org/org.go
@@ -8,15 +8,15 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
const (
@@ -26,7 +26,7 @@ const (
// Create render the page for create organization
func Create(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("new_org")
+ ctx.Data["Title"] = ctx.Tr("new_org.title")
ctx.Data["DefaultOrgVisibilityMode"] = setting.Service.DefaultOrgVisibilityMode
if !ctx.Doer.CanCreateOrganization() {
ctx.ServerError("Not allowed", errors.New(ctx.Locale.TrString("org.form.create_org_not_allowed")))
@@ -38,7 +38,7 @@ func Create(ctx *context.Context) {
// CreatePost response for create organization
func CreatePost(ctx *context.Context) {
form := *web.GetForm(ctx).(*forms.CreateOrgForm)
- ctx.Data["Title"] = ctx.Tr("new_org")
+ ctx.Data["Title"] = ctx.Tr("new_org.title")
if !ctx.Doer.CanCreateOrganization() {
ctx.ServerError("Not allowed", errors.New(ctx.Locale.TrString("org.form.create_org_not_allowed")))
diff --git a/routers/web/org/org_labels.go b/routers/web/org/org_labels.go
index 02eae8052e..dc18c55aa3 100644
--- a/routers/web/org/org_labels.go
+++ b/routers/web/org/org_labels.go
@@ -6,13 +6,13 @@ package org
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/label"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/label"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
// RetrieveLabels find all the labels of an organization
diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go
index 64d233fc45..96bd0f1ee2 100644
--- a/routers/web/org/projects.go
+++ b/routers/web/org/projects.go
@@ -9,20 +9,20 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- project_model "code.gitea.io/gitea/models/project"
- attachment_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/web"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ project_model "forgejo.org/models/project"
+ attachment_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/web"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
const (
@@ -126,6 +126,19 @@ func Projects(ctx *context.Context) {
ctx.Data["PageIsViewProjects"] = true
ctx.Data["SortType"] = sortType
+ numOpenIssues, err := issues_model.NumIssuesInProjects(ctx, projects, ctx.Doer, ctx.Org.Organization, optional.Some(false))
+ if err != nil {
+ ctx.ServerError("NumIssuesInProjects", err)
+ return
+ }
+ numClosedIssues, err := issues_model.NumIssuesInProjects(ctx, projects, ctx.Doer, ctx.Org.Organization, optional.Some(true))
+ if err != nil {
+ ctx.ServerError("NumIssuesInProjects", err)
+ return
+ }
+ ctx.Data["NumOpenIssuesInProject"] = numOpenIssues
+ ctx.Data["NumClosedIssuesInProject"] = numClosedIssues
+
ctx.HTML(http.StatusOK, tplProjects)
}
@@ -209,7 +222,7 @@ func ChangeProjectStatus(ctx *context.Context) {
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
return
}
- ctx.JSONRedirect(fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), id))
+ ctx.JSONRedirect(project_model.ProjectLinkForOrg(ctx.ContextUser, id))
}
// DeleteProject delete a project
@@ -259,7 +272,7 @@ func RenderEditProject(ctx *context.Context) {
ctx.Data["redirect"] = ctx.FormString("redirect")
ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
ctx.Data["card_type"] = p.CardType
- ctx.Data["CancelLink"] = fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), p.ID)
+ ctx.Data["CancelLink"] = project_model.ProjectLinkForOrg(ctx.ContextUser, p.ID)
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@@ -273,7 +286,7 @@ func EditProjectPost(ctx *context.Context) {
ctx.Data["PageIsViewProjects"] = true
ctx.Data["CanWriteProjects"] = canWriteProjects(ctx)
ctx.Data["CardTypes"] = project_model.GetCardConfig()
- ctx.Data["CancelLink"] = fmt.Sprintf("%s/-/projects/%d", ctx.ContextUser.HomeLink(), projectID)
+ ctx.Data["CancelLink"] = project_model.ProjectLinkForOrg(ctx.ContextUser, projectID)
shared_user.RenderUserHeader(ctx)
@@ -332,7 +345,7 @@ func ViewProject(ctx *context.Context) {
return
}
- issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns)
+ issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns, ctx.Doer, ctx.Org.Organization, optional.None[bool]())
if err != nil {
ctx.ServerError("LoadIssuesOfColumns", err)
return
diff --git a/routers/web/org/projects_test.go b/routers/web/org/projects_test.go
index ab419cc878..dec78502f2 100644
--- a/routers/web/org/projects_test.go
+++ b/routers/web/org/projects_test.go
@@ -6,9 +6,9 @@ package org_test
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/routers/web/org"
- "code.gitea.io/gitea/services/contexttest"
+ "forgejo.org/models/unittest"
+ "forgejo.org/routers/web/org"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
)
diff --git a/routers/web/org/setting.go b/routers/web/org/setting.go
index 0be734abaf..284f406413 100644
--- a/routers/web/org/setting.go
+++ b/routers/web/org/setting.go
@@ -7,26 +7,27 @@ package org
import (
"net/http"
"net/url"
+ "time"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- user_setting "code.gitea.io/gitea/routers/web/user/setting"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- org_service "code.gitea.io/gitea/services/org"
- repo_service "code.gitea.io/gitea/services/repository"
- user_service "code.gitea.io/gitea/services/user"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/models/webhook"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ shared_user "forgejo.org/routers/web/shared/user"
+ user_setting "forgejo.org/routers/web/user/setting"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ org_service "forgejo.org/services/org"
+ repo_service "forgejo.org/services/repository"
+ user_service "forgejo.org/services/user"
+ webhook_service "forgejo.org/services/webhook"
)
const (
@@ -48,6 +49,7 @@ func Settings(ctx *context.Context) {
ctx.Data["CurrentVisibility"] = ctx.Org.Organization.Visibility
ctx.Data["RepoAdminChangeTeamAccess"] = ctx.Org.Organization.RepoAdminChangeTeamAccess
ctx.Data["ContextUser"] = ctx.ContextUser
+ ctx.Data["CooldownPeriod"] = setting.Service.UsernameCooldownPeriod
err := shared_user.LoadHeaderCount(ctx)
if err != nil {
@@ -65,6 +67,7 @@ func SettingsPost(ctx *context.Context) {
ctx.Data["PageIsOrgSettings"] = true
ctx.Data["PageIsSettingsOptions"] = true
ctx.Data["CurrentVisibility"] = ctx.Org.Organization.Visibility
+ ctx.Data["CooldownPeriod"] = setting.Service.UsernameCooldownPeriod
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplSettingsOptions)
@@ -78,6 +81,9 @@ func SettingsPost(ctx *context.Context) {
if user_model.IsErrUserAlreadyExist(err) {
ctx.Data["Err_Name"] = true
ctx.RenderWithErr(ctx.Tr("form.username_been_taken"), tplSettingsOptions, &form)
+ } else if user_model.IsErrCooldownPeriod(err) {
+ ctx.Data["Err_UserName"] = true
+ ctx.RenderWithErr(ctx.Locale.Tr("form.username_claiming_cooldown", err.(user_model.ErrCooldownPeriod).ExpireTime.Format(time.RFC1123Z)), tplSettingsOptions, form)
} else if db.IsErrNameReserved(err) {
ctx.Data["Err_Name"] = true
ctx.RenderWithErr(ctx.Tr("repo.form.name_reserved", err.(db.ErrNameReserved).Name), tplSettingsOptions, &form)
@@ -93,7 +99,13 @@ func SettingsPost(ctx *context.Context) {
ctx.Org.OrgLink = setting.AppSubURL + "/org/" + url.PathEscape(org.Name)
}
- if form.Email != "" {
+ if form.Email == "" {
+ err := user_model.DeletePrimaryEmailAddressOfUser(ctx, org.ID)
+ if err != nil {
+ ctx.ServerError("DeletePrimaryEmailAddressOfUser", err)
+ return
+ }
+ } else {
if err := user_service.ReplacePrimaryEmailAddress(ctx, org.AsUser(), form.Email); err != nil {
ctx.Data["Err_Email"] = true
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplSettingsOptions, &form)
diff --git a/routers/web/org/setting/blocked_users.go b/routers/web/org/setting/blocked_users.go
index 0c7f245c13..77b2791874 100644
--- a/routers/web/org/setting/blocked_users.go
+++ b/routers/web/org/setting/blocked_users.go
@@ -8,11 +8,11 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
- user_service "code.gitea.io/gitea/services/user"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
+ user_service "forgejo.org/services/user"
)
const tplBlockedUsers = "org/settings/blocked_users"
@@ -53,6 +53,12 @@ func BlockedUsersBlock(ctx *context.Context) {
return
}
+ if u.ID == ctx.Doer.ID {
+ ctx.Flash.Error(ctx.Tr("settings.user_block_yourself"))
+ ctx.Redirect(ctx.Org.OrgLink + "/settings/blocked_users")
+ return
+ }
+
if err := user_service.BlockUser(ctx, ctx.Org.Organization.ID, u.ID); err != nil {
ctx.ServerError("BlockUser", err)
return
diff --git a/routers/web/org/setting/runners.go b/routers/web/org/setting/runners.go
index fe05709237..8053ed7729 100644
--- a/routers/web/org/setting/runners.go
+++ b/routers/web/org/setting/runners.go
@@ -4,7 +4,7 @@
package setting
import (
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/services/context"
)
func RedirectToDefaultSetting(ctx *context.Context) {
diff --git a/routers/web/org/setting/storage_overview.go b/routers/web/org/setting/storage_overview.go
new file mode 100644
index 0000000000..5714d7ee23
--- /dev/null
+++ b/routers/web/org/setting/storage_overview.go
@@ -0,0 +1,20 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package setting
+
+import (
+ "forgejo.org/modules/base"
+ "forgejo.org/routers/web/shared"
+ "forgejo.org/services/context"
+)
+
+const (
+ tplSettingsStorageOverview base.TplName = "org/settings/storage_overview"
+)
+
+// StorageOverview render a size overview of the organization, as well as relevant
+// quota limits of the instance.
+func StorageOverview(ctx *context.Context) {
+ shared.StorageOverview(ctx, ctx.Org.Organization.ID, tplSettingsStorageOverview)
+}
diff --git a/routers/web/org/setting_oauth2.go b/routers/web/org/setting_oauth2.go
index 7f855795d3..9c31063974 100644
--- a/routers/web/org/setting_oauth2.go
+++ b/routers/web/org/setting_oauth2.go
@@ -7,13 +7,13 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- user_setting "code.gitea.io/gitea/routers/web/user/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ shared_user "forgejo.org/routers/web/shared/user"
+ user_setting "forgejo.org/routers/web/user/setting"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/org/setting_packages.go b/routers/web/org/setting_packages.go
index af9836e42c..4457c8fb0f 100644
--- a/routers/web/org/setting_packages.go
+++ b/routers/web/org/setting_packages.go
@@ -7,11 +7,11 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- shared "code.gitea.io/gitea/routers/web/shared/packages"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ shared "forgejo.org/routers/web/shared/packages"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go
index fd7486cacd..659bee469f 100644
--- a/routers/web/org/teams.go
+++ b/routers/web/org/teams.go
@@ -12,23 +12,24 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- org_model "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- unit_model "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/forms"
- org_service "code.gitea.io/gitea/services/org"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ org_model "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/forms"
+ org_service "forgejo.org/services/org"
+ repo_service "forgejo.org/services/repository"
)
const (
@@ -131,7 +132,7 @@ func TeamsAction(ctx *context.Context) {
u, err = user_model.GetUserByName(ctx, uname)
if err != nil {
if user_model.IsErrUserNotExist(err) {
- if setting.MailService != nil && user_model.ValidateEmail(uname) == nil {
+ if setting.MailService != nil && validation.ValidateEmail(uname) == nil {
if err := org_service.CreateTeamInvite(ctx, ctx.Doer, ctx.Org.Team, uname); err != nil {
if org_model.IsErrTeamInviteAlreadyExist(err) {
ctx.Flash.Error(ctx.Tr("form.duplicate_invite_to_team"))
@@ -507,21 +508,22 @@ func EditTeamPost(ctx *context.Context) {
t.IncludesAllRepositories = includesAllRepositories
}
t.CanCreateOrgRepo = form.CanCreateOrgRepo
+
+ units := make([]*org_model.TeamUnit, 0, len(unitPerms))
+ for tp, perm := range unitPerms {
+ units = append(units, &org_model.TeamUnit{
+ OrgID: t.OrgID,
+ TeamID: t.ID,
+ Type: tp,
+ AccessMode: perm,
+ })
+ }
+ t.Units = units
} else {
t.CanCreateOrgRepo = true
}
t.Description = form.Description
- units := make([]*org_model.TeamUnit, 0, len(unitPerms))
- for tp, perm := range unitPerms {
- units = append(units, &org_model.TeamUnit{
- OrgID: t.OrgID,
- TeamID: t.ID,
- Type: tp,
- AccessMode: perm,
- })
- }
- t.Units = units
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplTeamNew)
diff --git a/routers/web/repo/action_aggregator_test.go b/routers/web/repo/action_aggregator_test.go
new file mode 100644
index 0000000000..8bade074ca
--- /dev/null
+++ b/routers/web/repo/action_aggregator_test.go
@@ -0,0 +1,829 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package repo
+
+import (
+ "strings"
+ "testing"
+
+ issue_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
+
+ "github.com/stretchr/testify/assert"
+)
+
+// *************** Helper functions for the tests ***************
+
+func testComment(t int64) *issue_model.Comment {
+ return &issue_model.Comment{PosterID: 1, CreatedUnix: timeutil.TimeStamp(t)}
+}
+
+func nameToID(name string) int64 {
+ var id int64
+ for c, letter := range name {
+ id += int64((c+1)*1000) * int64(letter)
+ }
+ return id
+}
+
+func createReqReviewTarget(name string) issue_model.RequestReviewTarget {
+ if strings.HasSuffix(name, "-team") {
+ team := createTeam(name)
+ return issue_model.RequestReviewTarget{Team: &team}
+ }
+ user := createUser(name)
+ return issue_model.RequestReviewTarget{User: &user}
+}
+
+func createUser(name string) user_model.User {
+ return user_model.User{Name: name, ID: nameToID(name)}
+}
+
+func createTeam(name string) organization.Team {
+ return organization.Team{Name: name, ID: nameToID(name)}
+}
+
+func createLabel(name string) issue_model.Label {
+ return issue_model.Label{Name: name, ID: nameToID(name)}
+}
+
+func addLabel(t int64, name string) *issue_model.Comment {
+ c := testComment(t)
+ c.Type = issue_model.CommentTypeLabel
+ c.Content = "1"
+ lbl := createLabel(name)
+ c.Label = &lbl
+ c.AddedLabels = []*issue_model.Label{&lbl}
+ return c
+}
+
+func delLabel(t int64, name string) *issue_model.Comment {
+ c := addLabel(t, name)
+ c.Content = ""
+ c.RemovedLabels = c.AddedLabels
+ c.AddedLabels = nil
+ return c
+}
+
+func openOrClose(t int64, close bool) *issue_model.Comment {
+ c := testComment(t)
+ if close {
+ c.Type = issue_model.CommentTypeClose
+ } else {
+ c.Type = issue_model.CommentTypeReopen
+ }
+ return c
+}
+
+func reqReview(t int64, name string, delReq bool) *issue_model.Comment {
+ c := testComment(t)
+ c.Type = issue_model.CommentTypeReviewRequest
+ if strings.HasSuffix(name, "-team") {
+ team := createTeam(name)
+ c.AssigneeTeam = &team
+ c.AssigneeTeamID = team.ID
+ } else {
+ user := createUser(name)
+ c.Assignee = &user
+ c.AssigneeID = user.ID
+ }
+ c.RemovedAssignee = delReq
+ return c
+}
+
+func ghostReqReview(t, id int64) *issue_model.Comment {
+ c := testComment(t)
+ c.Type = issue_model.CommentTypeReviewRequest
+ c.AssigneeTeam = organization.NewGhostTeam()
+ c.AssigneeTeamID = id
+ return c
+}
+
+func reqReviewList(t int64, del bool, names ...string) *issue_model.Comment {
+ req := []issue_model.RequestReviewTarget{}
+ for _, name := range names {
+ req = append(req, createReqReviewTarget(name))
+ }
+ cmnt := testComment(t)
+ cmnt.Type = issue_model.CommentTypeReviewRequest
+ if del {
+ cmnt.RemovedRequestReview = req
+ } else {
+ cmnt.AddedRequestReview = req
+ }
+ return cmnt
+}
+
+func aggregatedComment(t int64,
+ closed bool,
+ addLabels []*issue_model.Label,
+ delLabels []*issue_model.Label,
+ addReqReview []issue_model.RequestReviewTarget,
+ delReqReview []issue_model.RequestReviewTarget,
+) *issue_model.Comment {
+ cmnt := testComment(t)
+ cmnt.Type = issue_model.CommentTypeAggregator
+ cmnt.Aggregator = &issue_model.ActionAggregator{
+ IsClosed: closed,
+ AddedLabels: addLabels,
+ RemovedLabels: delLabels,
+ AddedRequestReview: addReqReview,
+ RemovedRequestReview: delReqReview,
+ }
+ if len(addLabels) > 0 {
+ cmnt.AddedLabels = addLabels
+ }
+ if len(delLabels) > 0 {
+ cmnt.RemovedLabels = delLabels
+ }
+ if len(addReqReview) > 0 {
+ cmnt.AddedRequestReview = addReqReview
+ }
+ if len(delReqReview) > 0 {
+ cmnt.RemovedRequestReview = delReqReview
+ }
+ return cmnt
+}
+
+func commentText(t int64, text string) *issue_model.Comment {
+ c := testComment(t)
+ c.Type = issue_model.CommentTypeComment
+ c.Content = text
+ return c
+}
+
+// ****************************************************************
+
+type testCase struct {
+ name string
+ beforeCombined []*issue_model.Comment
+ afterCombined []*issue_model.Comment
+ sameAfter bool
+ timestampCombination int64
+}
+
+func (kase *testCase) doTest(t *testing.T) {
+ issue := issue_model.Issue{Comments: kase.beforeCombined}
+
+ var now int64 = -9223372036854775808
+ for c := 0; c < len(kase.beforeCombined); c++ {
+ assert.Greater(t, int64(kase.beforeCombined[c].CreatedUnix), now)
+ now = int64(kase.beforeCombined[c].CreatedUnix)
+ }
+
+ if kase.timestampCombination != 0 {
+ now = kase.timestampCombination
+ }
+
+ issue_model.CombineCommentsHistory(&issue, now)
+
+ after := kase.afterCombined
+ if kase.sameAfter {
+ after = kase.beforeCombined
+ }
+
+ if len(after) != len(issue.Comments) {
+ t.Logf("Expected %v comments, got %v", len(after), len(issue.Comments))
+ t.Logf("Comments got after combination:")
+ for c := 0; c < len(issue.Comments); c++ {
+ cmt := issue.Comments[c]
+ t.Logf("%v %v %v\n", cmt.Type, cmt.CreatedUnix, cmt.Content)
+ }
+ assert.EqualValues(t, len(after), len(issue.Comments))
+ t.Fail()
+ return
+ }
+
+ for c := 0; c < len(after); c++ {
+ l := (after)[c]
+ r := issue.Comments[c]
+
+ // Ignore some inner data of the aggregator to facilitate testing
+ if l.Type == issue_model.CommentTypeAggregator {
+ r.Aggregator.StartUnix = 0
+ r.Aggregator.PrevClosed = false
+ r.Aggregator.PosterID = 0
+ r.Aggregator.StartInd = 0
+ r.Aggregator.EndInd = 0
+ r.Aggregator.AggAge = 0
+ }
+
+ // We can safely ignore this if the rest matches
+ if l.Type == issue_model.CommentTypeLabel {
+ l.Label = nil
+ l.Content = ""
+ } else if l.Type == issue_model.CommentTypeReviewRequest {
+ l.Assignee = nil
+ l.AssigneeID = 0
+ l.AssigneeTeam = nil
+ l.AssigneeTeamID = 0
+ }
+
+ assert.EqualValues(t, (after)[c], issue.Comments[c],
+ "Comment %v is not equal", c,
+ )
+ }
+}
+
+// **************** Start of the tests ******************
+
+func TestCombineLabelComments(t *testing.T) {
+ var tmon int64 = 60 * 60 * 24 * 30
+ var tday int64 = 60 * 60 * 24
+ var thour int64 = 60 * 60
+ kases := []testCase{
+ // ADD single = normal label comment
+ {
+ name: "add_single_label",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(0, "a"),
+ commentText(10, "I'm a salmon"),
+ },
+ sameAfter: true,
+ },
+
+ // ADD then REMOVE = Nothing
+ {
+ name: "add_label_then_remove",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(0, "a"),
+ delLabel(1, "a"),
+ commentText(65, "I'm a salmon"),
+ },
+ afterCombined: []*issue_model.Comment{
+ commentText(65, "I'm a salmon"),
+ },
+ },
+
+ // ADD 1 then comment then REMOVE = separate comments
+ {
+ name: "add_label_then_comment_then_remove",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(0, "a"),
+ commentText(10, "I'm a salmon"),
+ delLabel(20, "a"),
+ },
+ sameAfter: true,
+ },
+
+ // ADD 2 = Combined labels
+ {
+ name: "combine_labels",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(0, "a"),
+ addLabel(10, "b"),
+ commentText(20, "I'm a salmon"),
+ addLabel(30, "c"),
+ addLabel(80, "d"),
+ addLabel(85, "e"),
+ delLabel(90, "c"),
+ },
+ afterCombined: []*issue_model.Comment{
+ {
+ PosterID: 1,
+ Type: issue_model.CommentTypeLabel,
+ CreatedUnix: timeutil.TimeStamp(0),
+ AddedLabels: []*issue_model.Label{
+ {Name: "a", ID: nameToID("a")},
+ {Name: "b", ID: nameToID("b")},
+ },
+ },
+ commentText(20, "I'm a salmon"),
+ {
+ PosterID: 1,
+ Type: issue_model.CommentTypeLabel,
+ CreatedUnix: timeutil.TimeStamp(30),
+ AddedLabels: []*issue_model.Label{
+ {Name: "d", ID: nameToID("d")},
+ {Name: "e", ID: nameToID("e")},
+ },
+ },
+ },
+ },
+
+ // ADD 1, then 1 later = 2 separate comments
+ {
+ name: "add_then_later_label",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(0, "a"),
+ addLabel(60, "b"),
+ addLabel(121, "c"),
+ },
+ afterCombined: []*issue_model.Comment{
+ {
+ PosterID: 1,
+ Type: issue_model.CommentTypeLabel,
+ CreatedUnix: timeutil.TimeStamp(0),
+ AddedLabels: []*issue_model.Label{
+ {Name: "a", ID: nameToID("a")},
+ {Name: "b", ID: nameToID("b")},
+ },
+ },
+ addLabel(121, "c"),
+ },
+ },
+
+ // ADD 2 then REMOVE 1 = label
+ {
+ name: "add_2_remove_1",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(0, "a"),
+ addLabel(10, "b"),
+ delLabel(20, "a"),
+ },
+ afterCombined: []*issue_model.Comment{
+ // The timestamp will be the one of the first aggregated comment
+ addLabel(0, "b"),
+ },
+ },
+
+ // ADD then REMOVE multiple = nothing
+ {
+ name: "add_multiple_remove_all",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(0, "a"),
+ addLabel(1, "b"),
+ addLabel(2, "c"),
+ addLabel(3, "d"),
+ addLabel(4, "e"),
+ delLabel(5, "d"),
+ delLabel(6, "a"),
+ delLabel(7, "e"),
+ delLabel(8, "c"),
+ delLabel(9, "b"),
+ },
+ afterCombined: nil,
+ },
+
+ // ADD 2, wait, REMOVE 2 = +2 then -2 comments
+ {
+ name: "add2_wait_rm2_labels",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(0, "a"),
+ addLabel(1, "b"),
+ delLabel(120, "a"),
+ delLabel(121, "b"),
+ },
+ afterCombined: []*issue_model.Comment{
+ {
+ PosterID: 1,
+ Type: issue_model.CommentTypeLabel,
+ CreatedUnix: timeutil.TimeStamp(0),
+ AddedLabels: []*issue_model.Label{
+ {Name: "a", ID: nameToID("a")},
+ {Name: "b", ID: nameToID("b")},
+ },
+ },
+ {
+ PosterID: 1,
+ Type: issue_model.CommentTypeLabel,
+ CreatedUnix: timeutil.TimeStamp(120),
+ RemovedLabels: []*issue_model.Label{
+ {Name: "a", ID: nameToID("a")},
+ {Name: "b", ID: nameToID("b")},
+ },
+ },
+ },
+ },
+
+ // Regression check on edge case
+ {
+ name: "regression_edgecase_finalagg",
+ beforeCombined: []*issue_model.Comment{
+ commentText(0, "hey"),
+ commentText(1, "ho"),
+ addLabel(2, "a"),
+ addLabel(3, "b"),
+ delLabel(4, "a"),
+ delLabel(5, "b"),
+
+ addLabel(120, "a"),
+
+ addLabel(220, "c"),
+ addLabel(221, "d"),
+ addLabel(222, "e"),
+ delLabel(223, "d"),
+
+ delLabel(400, "a"),
+ },
+ afterCombined: []*issue_model.Comment{
+ commentText(0, "hey"),
+ commentText(1, "ho"),
+ addLabel(120, "a"),
+ {
+ PosterID: 1,
+ Type: issue_model.CommentTypeLabel,
+ CreatedUnix: timeutil.TimeStamp(220),
+ AddedLabels: []*issue_model.Label{
+ {Name: "c", ID: nameToID("c")},
+ {Name: "e", ID: nameToID("e")},
+ },
+ },
+ delLabel(400, "a"),
+ },
+ },
+
+ {
+ name: "combine_label_high_timestamp_separated",
+ timestampCombination: tmon + 1,
+ beforeCombined: []*issue_model.Comment{
+ // 1 month old, comments separated by 1 Day + 1 sec (not agg)
+ addLabel(0, "d"),
+ delLabel(tday+1, "d"),
+
+ // 1 day old, comments separated by 1 hour + 1 sec (not agg)
+ addLabel((tmon-tday)-thour, "c"),
+ delLabel((tmon-tday)+1, "c"),
+
+ // 1 hour old, comments separated by 10 mins + 1 sec (not agg)
+ addLabel(tmon-thour, "b"),
+ delLabel((tmon-(50*60))+1, "b"),
+
+ // Else, aggregate by minute
+ addLabel(tmon-61, "a"),
+ delLabel(tmon, "a"),
+ },
+ sameAfter: true,
+ },
+
+ // Test higher timestamp diff
+ {
+ name: "combine_label_high_timestamp_merged",
+ timestampCombination: tmon + 1,
+ beforeCombined: []*issue_model.Comment{
+ // 1 month old, comments separated by 1 Day (aggregated)
+ addLabel(0, "d"),
+ delLabel(tday, "d"),
+
+ // 1 day old, comments separated by 1 hour (aggregated)
+ addLabel((tmon-tday)-thour, "c"),
+ delLabel(tmon-tday, "c"),
+
+ // 1 hour old, comments separated by 10 mins (aggregated)
+ addLabel(tmon-thour, "b"),
+ delLabel(tmon-(50*60), "b"),
+
+ addLabel(tmon-60, "a"),
+ delLabel(tmon, "a"),
+ },
+ },
+ }
+
+ for _, kase := range kases {
+ t.Run(kase.name, kase.doTest)
+ }
+}
+
+func TestCombineReviewRequests(t *testing.T) {
+ kases := []testCase{
+ // ADD single = normal request review comment
+ {
+ name: "add_single_review",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(0, "toto", false),
+ commentText(10, "I'm a salmon"),
+ reqReview(20, "toto-team", false),
+ },
+ sameAfter: true,
+ },
+
+ // ADD then REMOVE = Nothing
+ {
+ name: "add_then_remove_review",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(0, "toto", false),
+ reqReview(5, "toto", true),
+ commentText(10, "I'm a salmon"),
+ },
+ afterCombined: []*issue_model.Comment{
+ commentText(10, "I'm a salmon"),
+ },
+ },
+
+ // ADD 1 then comment then REMOVE = separate comments
+ {
+ name: "add_comment_del_review",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(0, "toto", false),
+ commentText(5, "I'm a salmon"),
+ reqReview(10, "toto", true),
+ },
+ sameAfter: true,
+ },
+
+ // ADD 2 = Combined request reviews
+ {
+ name: "combine_reviews",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(0, "toto", false),
+ reqReview(10, "tutu-team", false),
+ commentText(20, "I'm a salmon"),
+ reqReview(30, "titi", false),
+ reqReview(80, "tata", false),
+ reqReview(85, "tyty-team", false),
+ reqReview(90, "titi", true),
+ },
+ afterCombined: []*issue_model.Comment{
+ reqReviewList(0, false, "toto", "tutu-team"),
+ commentText(20, "I'm a salmon"),
+ reqReviewList(30, false, "tata", "tyty-team"),
+ },
+ },
+
+ // ADD 1, then 1 later = 2 separate comments
+ {
+ name: "add_then_later_review",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(0, "titi", false),
+ reqReview(60, "toto-team", false),
+ reqReview(121, "tutu", false),
+ },
+ afterCombined: []*issue_model.Comment{
+ reqReviewList(0, false, "titi", "toto-team"),
+ reqReviewList(121, false, "tutu"),
+ },
+ },
+
+ // ADD 2 then REMOVE 1 = single request review
+ {
+ name: "add_2_then_remove_review",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(0, "titi-team", false),
+ reqReview(59, "toto", false),
+ reqReview(60, "titi-team", true),
+ },
+ afterCombined: []*issue_model.Comment{
+ reqReviewList(0, false, "toto"),
+ },
+ },
+
+ // ADD then REMOVE multiple = nothing
+ {
+ name: "add_multiple_then_remove_all_review",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(0, "titi0-team", false),
+ reqReview(1, "toto1", false),
+ reqReview(2, "titi2", false),
+ reqReview(3, "titi3-team", false),
+ reqReview(4, "titi4", false),
+ reqReview(5, "titi5", false),
+ reqReview(6, "titi6-team", false),
+ reqReview(10, "titi0-team", true),
+ reqReview(11, "toto1", true),
+ reqReview(12, "titi2", true),
+ reqReview(13, "titi3-team", true),
+ reqReview(14, "titi4", true),
+ reqReview(15, "titi5", true),
+ reqReview(16, "titi6-team", true),
+ },
+ afterCombined: nil,
+ },
+
+ // ADD 2, wait, REMOVE 2 = +2 then -2 comments
+ {
+ name: "add2_wait_rm2_requests",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(1, "titi", false),
+ reqReview(2, "toto-team", false),
+ reqReview(121, "titi", true),
+ reqReview(122, "toto-team", true),
+ },
+ afterCombined: []*issue_model.Comment{
+ reqReviewList(1, false, "titi", "toto-team"),
+ reqReviewList(121, true, "titi", "toto-team"),
+ },
+ },
+
+ // Ghost.
+ {
+ name: "ghost reviews",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(1, "titi", false),
+ ghostReqReview(2, 50),
+ ghostReqReview(3, 51),
+ ghostReqReview(4, 50),
+ },
+ afterCombined: []*issue_model.Comment{
+ {
+ PosterID: 1,
+ Type: issue_model.CommentTypeReviewRequest,
+ CreatedUnix: timeutil.TimeStamp(1),
+ AddedRequestReview: []issue_model.RequestReviewTarget{
+ createReqReviewTarget("titi"), {Team: organization.NewGhostTeam()},
+ },
+ },
+ },
+ },
+ }
+
+ for _, kase := range kases {
+ t.Run(kase.name, kase.doTest)
+ }
+}
+
+func TestCombineOpenClose(t *testing.T) {
+ kases := []testCase{
+ // Close then open = nullified
+ {
+ name: "close_open_nullified",
+ beforeCombined: []*issue_model.Comment{
+ openOrClose(0, true),
+ openOrClose(10, false),
+ },
+ afterCombined: nil,
+ },
+
+ // Close then open later = separate comments
+ {
+ name: "close_open_later",
+ beforeCombined: []*issue_model.Comment{
+ openOrClose(0, true),
+ openOrClose(61, false),
+ },
+ sameAfter: true,
+ },
+
+ // Close then comment then open = separate comments
+ {
+ name: "close_comment_open",
+ beforeCombined: []*issue_model.Comment{
+ openOrClose(0, true),
+ commentText(1, "I'm a salmon"),
+ openOrClose(2, false),
+ },
+ sameAfter: true,
+ },
+ }
+
+ for _, kase := range kases {
+ t.Run(kase.name, kase.doTest)
+ }
+}
+
+func TestCombineMultipleDifferentComments(t *testing.T) {
+ lblA := createLabel("a")
+ kases := []testCase{
+ // Add Label + Close + ReqReview = Combined
+ {
+ name: "label_close_reqreview_combined",
+ beforeCombined: []*issue_model.Comment{
+ reqReview(1, "toto", false),
+ addLabel(2, "a"),
+ openOrClose(3, true),
+
+ reqReview(101, "toto", true),
+ openOrClose(102, false),
+ delLabel(103, "a"),
+ },
+ afterCombined: []*issue_model.Comment{
+ aggregatedComment(1,
+ true,
+ []*issue_model.Label{&lblA},
+ []*issue_model.Label{},
+ []issue_model.RequestReviewTarget{createReqReviewTarget("toto")},
+ []issue_model.RequestReviewTarget{},
+ ),
+ aggregatedComment(101,
+ false,
+ []*issue_model.Label{},
+ []*issue_model.Label{&lblA},
+ []issue_model.RequestReviewTarget{},
+ []issue_model.RequestReviewTarget{createReqReviewTarget("toto")},
+ ),
+ },
+ },
+
+ // Add Req + Add Label + Close + Del Req + Del Label = Close only
+ {
+ name: "req_label_close_dellabel_delreq",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(2, "a"),
+ reqReview(3, "titi", false),
+ openOrClose(4, true),
+ delLabel(5, "a"),
+ reqReview(6, "titi", true),
+ },
+ afterCombined: []*issue_model.Comment{
+ openOrClose(2, true),
+ },
+ },
+
+ // Close + Add Req + Add Label + Del Req + Open = Label only
+ {
+ name: "close_req_label_open_delreq",
+ beforeCombined: []*issue_model.Comment{
+ openOrClose(2, true),
+ reqReview(4, "titi", false),
+ addLabel(5, "a"),
+ reqReview(6, "titi", true),
+ openOrClose(8, false),
+ },
+ afterCombined: []*issue_model.Comment{
+ addLabel(2, "a"),
+ },
+ },
+
+ // Add Label + Close + Add ReqReview + Del Label + Open = ReqReview only
+ {
+ name: "label_close_req_dellabel_open",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(1, "a"),
+ openOrClose(2, true),
+ reqReview(4, "titi", false),
+ openOrClose(7, false),
+ delLabel(8, "a"),
+ },
+ afterCombined: []*issue_model.Comment{
+ reqReviewList(1, false, "titi"),
+ },
+ },
+
+ // Add Label + Close + ReqReview, then delete everything = nothing
+ {
+ name: "add_multiple_delete_everything",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(1, "a"),
+ openOrClose(2, true),
+ reqReview(4, "titi", false),
+ openOrClose(7, false),
+ delLabel(8, "a"),
+ reqReview(10, "titi", true),
+ },
+ afterCombined: nil,
+ },
+
+ // Add multiple, then comment, then delete everything = separate aggregation
+ {
+ name: "add_multiple_comment_delete_everything",
+ beforeCombined: []*issue_model.Comment{
+ addLabel(1, "a"),
+ openOrClose(2, true),
+ reqReview(4, "titi", false),
+
+ commentText(6, "I'm a salmon"),
+
+ openOrClose(7, false),
+ delLabel(8, "a"),
+ reqReview(10, "titi", true),
+ },
+ afterCombined: []*issue_model.Comment{
+ aggregatedComment(1,
+ true,
+ []*issue_model.Label{&lblA},
+ []*issue_model.Label{},
+ []issue_model.RequestReviewTarget{createReqReviewTarget("titi")},
+ []issue_model.RequestReviewTarget{},
+ ),
+ commentText(6, "I'm a salmon"),
+ aggregatedComment(7,
+ false,
+ []*issue_model.Label{},
+ []*issue_model.Label{&lblA},
+ []issue_model.RequestReviewTarget{},
+ []issue_model.RequestReviewTarget{createReqReviewTarget("titi")},
+ ),
+ },
+ },
+
+ {
+ name: "regression_edgecase_finalagg",
+ beforeCombined: []*issue_model.Comment{
+ commentText(0, "hey"),
+ commentText(1, "ho"),
+ addLabel(2, "a"),
+ reqReview(3, "titi", false),
+ delLabel(4, "a"),
+ reqReview(5, "titi", true),
+
+ addLabel(120, "a"),
+
+ openOrClose(220, true),
+ addLabel(221, "d"),
+ reqReview(222, "toto-team", false),
+ delLabel(223, "d"),
+
+ delLabel(400, "a"),
+ },
+ afterCombined: []*issue_model.Comment{
+ commentText(0, "hey"),
+ commentText(1, "ho"),
+ addLabel(120, "a"),
+ aggregatedComment(220,
+ true,
+ []*issue_model.Label{},
+ []*issue_model.Label{},
+ []issue_model.RequestReviewTarget{createReqReviewTarget("toto-team")},
+ []issue_model.RequestReviewTarget{},
+ ),
+ delLabel(400, "a"),
+ },
+ },
+ }
+
+ for _, kase := range kases {
+ t.Run(kase.name, kase.doTest)
+ }
+}
diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go
index 90d3226f2d..0a63f566e0 100644
--- a/routers/web/repo/actions/actions.go
+++ b/routers/web/repo/actions/actions.go
@@ -5,24 +5,27 @@ package actions
import (
"bytes"
+ stdCtx "context"
"fmt"
"net/http"
"slices"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/web/repo"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/actions"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/web/repo"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
"github.com/nektos/act/pkg/model"
)
@@ -95,6 +98,8 @@ func List(ctx *context.Context) {
allRunnerLabels.AddMultiple(r.AgentLabels...)
}
+ canRun := ctx.Repo.CanWrite(unit.TypeActions)
+
workflows = make([]Workflow, 0, len(entries))
for _, entry := range entries {
workflow := Workflow{Entry: *entry}
@@ -146,7 +151,7 @@ func List(ctx *context.Context) {
}
workflows = append(workflows, workflow)
- if workflow.Entry.Name() == curWorkflow {
+ if canRun && workflow.Entry.Name() == curWorkflow {
config := wf.WorkflowDispatchConfig()
if config != nil {
keys := util.KeysOfMap(config.Inputs)
@@ -220,6 +225,10 @@ func List(ctx *context.Context) {
return
}
+ if err := loadIsRefDeleted(ctx, ctx.Repo.Repository.ID, runs); err != nil {
+ log.Error("LoadIsRefDeleted", err)
+ }
+
ctx.Data["Runs"] = runs
ctx.Data["Repo"] = ctx.Repo
@@ -231,7 +240,7 @@ func List(ctx *context.Context) {
}
ctx.Data["Actors"] = repo.MakeSelfOnTop(ctx.Doer, actors)
- ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx)
+ ctx.Data["StatusInfoList"] = actions_model.GetStatusInfoList(ctx, ctx.Locale)
pager := context.NewPagination(int(total), opts.PageSize, opts.Page, 5)
pager.SetDefaultParams(ctx)
@@ -243,3 +252,31 @@ func List(ctx *context.Context) {
ctx.HTML(http.StatusOK, tplListActions)
}
+
+// loadIsRefDeleted loads the IsRefDeleted field for each run in the list.
+// TODO: move this function to models/actions/run_list.go but now it will result in a circular import.
+func loadIsRefDeleted(ctx stdCtx.Context, repoID int64, runs actions_model.RunList) error {
+ branches := make(container.Set[string], len(runs))
+ for _, run := range runs {
+ refName := git.RefName(run.Ref)
+ if refName.IsBranch() {
+ branches.Add(refName.ShortName())
+ }
+ }
+ if len(branches) == 0 {
+ return nil
+ }
+
+ branchInfos, err := git_model.GetBranches(ctx, repoID, branches.Values(), false)
+ if err != nil {
+ return err
+ }
+ branchSet := git_model.BranchesToNamesSet(branchInfos)
+ for _, run := range runs {
+ refName := git.RefName(run.Ref)
+ if refName.IsBranch() && !branchSet.Contains(refName.ShortName()) {
+ run.IsRefDeleted = true
+ }
+ }
+ return nil
+}
diff --git a/routers/web/repo/actions/actions_test.go b/routers/web/repo/actions/actions_test.go
new file mode 100644
index 0000000000..232aacf96b
--- /dev/null
+++ b/routers/web/repo/actions/actions_test.go
@@ -0,0 +1,33 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package actions
+
+import (
+ "testing"
+
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ unittest "forgejo.org/models/unittest"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func Test_loadIsRefDeleted(t *testing.T) {
+ unittest.PrepareTestEnv(t)
+
+ runs, total, err := db.FindAndCount[actions_model.ActionRun](db.DefaultContext,
+ actions_model.FindRunOptions{RepoID: 4, Ref: "refs/heads/test"})
+ require.NoError(t, err)
+ assert.Len(t, runs, 1)
+ assert.EqualValues(t, 1, total)
+ for _, run := range runs {
+ assert.False(t, run.IsRefDeleted)
+ }
+
+ require.NoError(t, loadIsRefDeleted(db.DefaultContext, 4, runs))
+ for _, run := range runs {
+ assert.True(t, run.IsRefDeleted)
+ }
+}
diff --git a/routers/web/repo/actions/main_test.go b/routers/web/repo/actions/main_test.go
new file mode 100644
index 0000000000..0f82a0e7ea
--- /dev/null
+++ b/routers/web/repo/actions/main_test.go
@@ -0,0 +1,14 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package actions
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+)
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m)
+}
diff --git a/routers/web/repo/actions/manual.go b/routers/web/repo/actions/manual.go
index 86a6014761..413b087e8b 100644
--- a/routers/web/repo/actions/manual.go
+++ b/routers/web/repo/actions/manual.go
@@ -1,13 +1,13 @@
-// Copyright The Forgejo Authors.
-// SPDX-License-Identifier: MIT
+// Copyright 2024 The Forgejo Authors.
+// SPDX-License-Identifier: GPL-3.0-or-later
package actions
import (
"net/url"
- actions_service "code.gitea.io/gitea/services/actions"
- context_module "code.gitea.io/gitea/services/context"
+ actions_service "forgejo.org/services/actions"
+ context_module "forgejo.org/services/context"
)
func ManualRunWorkflow(ctx *context_module.Context) {
@@ -43,10 +43,11 @@ func ManualRunWorkflow(ctx *context_module.Context) {
formKeyGetter := func(key string) string {
formKey := "inputs[" + key + "]"
- return ctx.FormString(formKey)
+ return ctx.Req.PostFormValue(formKey)
}
- if err := workflow.Dispatch(ctx, formKeyGetter, ctx.Repo.Repository, ctx.Doer); err != nil {
+ _, _, err = workflow.Dispatch(ctx, formKeyGetter, ctx.Repo.Repository, ctx.Doer)
+ if err != nil {
if actions_service.IsInputRequiredErr(err) {
ctx.Flash.Error(ctx.Locale.Tr("actions.workflow.dispatch.input_required", err.(actions_service.InputRequiredErr).Name))
ctx.Redirect(location)
diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go
index e3e0fce3b2..2d009c5720 100644
--- a/routers/web/repo/actions/view.go
+++ b/routers/web/repo/actions/view.go
@@ -10,6 +10,7 @@ import (
"context"
"errors"
"fmt"
+ "html/template"
"io"
"net/http"
"net/url"
@@ -17,19 +18,24 @@ import (
"strings"
"time"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- actions_service "code.gitea.io/gitea/services/actions"
- context_module "code.gitea.io/gitea/services/context"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/actions"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/common"
+ actions_service "forgejo.org/services/actions"
+ context_module "forgejo.org/services/context"
"xorm.io/builder"
)
@@ -107,16 +113,17 @@ type ViewRequest struct {
type ViewResponse struct {
State struct {
Run struct {
- Link string `json:"link"`
- Title string `json:"title"`
- Status string `json:"status"`
- CanCancel bool `json:"canCancel"`
- CanApprove bool `json:"canApprove"` // the run needs an approval and the doer has permission to approve
- CanRerun bool `json:"canRerun"`
- CanDeleteArtifact bool `json:"canDeleteArtifact"`
- Done bool `json:"done"`
- Jobs []*ViewJob `json:"jobs"`
- Commit ViewCommit `json:"commit"`
+ Link string `json:"link"`
+ Title string `json:"title"`
+ TitleHTML template.HTML `json:"titleHTML"`
+ Status string `json:"status"`
+ CanCancel bool `json:"canCancel"`
+ CanApprove bool `json:"canApprove"` // the run needs an approval and the doer has permission to approve
+ CanRerun bool `json:"canRerun"`
+ CanDeleteArtifact bool `json:"canDeleteArtifact"`
+ Done bool `json:"done"`
+ Jobs []*ViewJob `json:"jobs"`
+ Commit ViewCommit `json:"commit"`
} `json:"run"`
CurrentJob struct {
Title string `json:"title"`
@@ -153,8 +160,9 @@ type ViewUser struct {
}
type ViewBranch struct {
- Name string `json:"name"`
- Link string `json:"link"`
+ Name string `json:"name"`
+ Link string `json:"link"`
+ IsDeleted bool `json:"isDeleted"`
}
type ViewJobStep struct {
@@ -193,7 +201,10 @@ func ViewPost(ctx *context_module.Context) {
resp := &ViewResponse{}
+ metas := ctx.Repo.Repository.ComposeMetas(ctx)
+
resp.State.Run.Title = run.Title
+ resp.State.Run.TitleHTML = templates.RenderCommitMessage(ctx, run.Title, metas)
resp.State.Run.Link = run.Link()
resp.State.Run.CanCancel = !run.Status.IsDone() && ctx.Repo.CanWrite(unit.TypeActions)
resp.State.Run.CanApprove = run.NeedApproval && ctx.Repo.CanWrite(unit.TypeActions)
@@ -220,6 +231,16 @@ func ViewPost(ctx *context_module.Context) {
Name: run.PrettyRef(),
Link: run.RefLink(),
}
+ refName := git.RefName(run.Ref)
+ if refName.IsBranch() {
+ b, err := git_model.GetBranch(ctx, ctx.Repo.Repository.ID, refName.ShortName())
+ if err != nil && !git_model.IsErrBranchNotExist(err) {
+ log.Error("GetBranch: %v", err)
+ } else if git_model.IsErrBranchNotExist(err) || (b != nil && b.IsDeleted) {
+ branch.IsDeleted = true
+ }
+ }
+
resp.State.Run.Commit = ViewCommit{
LocaleCommit: ctx.Locale.TrString("actions.runs.commit"),
LocalePushedBy: ctx.Locale.TrString("actions.runs.pushed_by"),
@@ -270,6 +291,27 @@ func ViewPost(ctx *context_module.Context) {
step := steps[cursor.Step]
+ // if task log is expired, return a consistent log line
+ if task.LogExpired {
+ if cursor.Cursor == 0 {
+ resp.Logs.StepsLog = append(resp.Logs.StepsLog, &ViewStepLog{
+ Step: cursor.Step,
+ Cursor: 1,
+ Lines: []*ViewStepLogLine{
+ {
+ Index: 1,
+ Message: ctx.Locale.TrString("actions.runs.expire_log_message"),
+ // Timestamp doesn't mean anything when the log is expired.
+ // Set it to the task's updated time since it's probably the time when the log has expired.
+ Timestamp: float64(task.Updated.AsTime().UnixNano()) / float64(time.Second),
+ },
+ },
+ Started: int64(step.Started),
+ })
+ }
+ continue
+ }
+
logLines := make([]*ViewStepLogLine, 0) // marshal to '[]' instead of 'null' in json
index := step.LogIndex + cursor.Cursor
@@ -285,7 +327,6 @@ func ViewPost(ctx *context_module.Context) {
if validCursor {
length := step.LogLength - cursor.Cursor
offset := task.LogIndexes[index]
- var err error
logRows, err := actions.ReadLogs(ctx, task.LogInStorage, task.LogFilename, offset, length)
if err != nil {
ctx.Error(http.StatusInternalServerError, err.Error())
@@ -662,14 +703,13 @@ func ArtifactsDownloadView(ctx *context_module.Context) {
}
}
- ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.zip; filename*=UTF-8''%s.zip", url.PathEscape(artifactName), artifactName))
-
// Artifacts using the v4 backend are stored as a single combined zip file per artifact on the backend
- // The v4 backend enshures ContentEncoding is set to "application/zip", which is not the case for the old backend
+ // The v4 backend ensures ContentEncoding is set to "application/zip", which is not the case for the old backend
if len(artifacts) == 1 && artifacts[0].ArtifactName+".zip" == artifacts[0].ArtifactPath && artifacts[0].ContentEncoding == "application/zip" {
art := artifacts[0]
if setting.Actions.ArtifactStorage.MinioConfig.ServeDirect {
- u, err := storage.ActionsArtifacts.URL(art.StoragePath, art.ArtifactPath)
+ u, err := storage.ActionsArtifacts.URL(art.StoragePath, art.ArtifactPath, nil)
+
if u != nil && err == nil {
ctx.Redirect(u.String())
return
@@ -680,12 +720,13 @@ func ArtifactsDownloadView(ctx *context_module.Context) {
ctx.Error(http.StatusInternalServerError, err.Error())
return
}
- _, _ = io.Copy(ctx.Resp, f)
+ common.ServeContentByReadSeeker(ctx.Base, artifactName, util.ToPointer(art.UpdatedUnix.AsTime()), f)
return
}
// Artifacts using the v1-v3 backend are stored as multiple individual files per artifact on the backend
// Those need to be zipped for download
+ ctx.Resp.Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s.zip; filename*=UTF-8''%s.zip", url.PathEscape(artifactName), artifactName))
writer := zip.NewWriter(ctx.Resp)
defer writer.Close()
for _, art := range artifacts {
diff --git a/routers/web/repo/activity.go b/routers/web/repo/activity.go
index ba776c84d3..c9cd2c13bb 100644
--- a/routers/web/repo/activity.go
+++ b/routers/web/repo/activity.go
@@ -7,10 +7,10 @@ import (
"net/http"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/services/context"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/base"
+ "forgejo.org/services/context"
)
const (
@@ -48,8 +48,8 @@ func Activity(ctx *context.Context) {
ctx.Data["Period"] = "weekly"
timeFrom = timeUntil.Add(-time.Hour * 168)
}
- ctx.Data["DateFrom"] = timeFrom.UTC().Format(time.RFC3339)
- ctx.Data["DateUntil"] = timeUntil.UTC().Format(time.RFC3339)
+ ctx.Data["DateFrom"] = timeFrom
+ ctx.Data["DateUntil"] = timeUntil
ctx.Data["PeriodText"] = ctx.Tr("repo.activity.period." + ctx.Data["Period"].(string))
var err error
@@ -94,7 +94,6 @@ func ActivityAuthors(ctx *context.Context) {
timeFrom = timeUntil.Add(-time.Hour * 168)
}
- var err error
authors, err := activities_model.GetActivityStatsTopAuthors(ctx, ctx.Repo.Repository, timeFrom, 10)
if err != nil {
ctx.ServerError("GetActivityStatsTopAuthors", err)
diff --git a/routers/web/repo/annex.go b/routers/web/repo/annex.go
new file mode 100644
index 0000000000..e150ff70ca
--- /dev/null
+++ b/routers/web/repo/annex.go
@@ -0,0 +1,156 @@
+package repo
+
+import (
+ "context"
+ "net"
+ "net/http"
+ "net/http/httputil"
+ "net/url"
+ "os"
+ "os/exec"
+ "strings"
+ "syscall"
+ "time"
+
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/annex"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ services_context "forgejo.org/services/context"
+)
+
+type p2phttpRecordType struct {
+ CancelFunc func()
+ LastUsed time.Time
+ Port string
+}
+
+var p2phttpRecords = make(map[string]*p2phttpRecordType)
+
+// AnnexP2PHTTP implements git-annex smart HTTP support by delegating to git annex p2phttp
+func AnnexP2PHTTP(ctx *services_context.Context) {
+ uuid := ctx.Params(":uuid")
+ repoPath, err := annex.UUID2RepoPath(uuid)
+ if err != nil {
+ log.Error("%v", err)
+ ctx.PlainText(http.StatusNotFound, "Repository not found")
+ return
+ }
+
+ parts := strings.Split(repoPath, "/")
+ repoName := strings.TrimSuffix(parts[len(parts)-1], ".git")
+ owner := parts[len(parts)-2]
+ repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, owner, repoName)
+ if err != nil {
+ log.Error("%v", err)
+ ctx.PlainText(http.StatusNotFound, "Repository not found")
+ return
+ }
+
+ p, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer)
+ if err != nil {
+ log.Error("%v", err)
+ ctx.ServerError("GetUserRepoPermission", err)
+ return
+ }
+
+ if !(ctx.Req.Method == "GET" && p.CanAccess(perm.AccessModeRead, unit.TypeCode) ||
+ ctx.Req.Method == "POST" && p.CanAccess(perm.AccessModeWrite, unit.TypeCode) ||
+ ctx.Req.Method == "POST" && strings.HasSuffix(ctx.Req.URL.Path, "/checkpresent") && p.CanAccess(perm.AccessModeRead, unit.TypeCode) ||
+ ctx.Req.Method == "POST" && strings.HasSuffix(ctx.Req.URL.Path, "/keeplocked") ||
+ ctx.Req.Method == "POST" && strings.HasSuffix(ctx.Req.URL.Path, "/lockcontent")) {
+ // GET requests require at least read access; POST requests for
+ // anything but checkpresent, lockcontent, and keeplocked
+ // require write permissions; POST requests for checkpresent
+ // only require read permissions, as it really is just a read.
+ // POST requests for lockcontent and keeplocked require no
+ // authentication at all, as is also the case for the
+ // authentication in the git-annex-p2phttp server. See
+ // https://git-annex.branchable.com/bugs/p2phttp__58___drop_difference_wideopen_unauth-readonly/
+ // for reasoning.
+ ctx.Resp.WriteHeader(http.StatusUnauthorized)
+ return
+ }
+
+ p2phttpRecord, p2phttpProcessExists := p2phttpRecords[uuid]
+ if p2phttpProcessExists {
+ p2phttpRecord.LastUsed = time.Now()
+ } else {
+ // Start a new p2phttp process for the requested repository
+ // There is a race condition here with the port selection, ideally git annex p2phttp could just listen on a unix socket...
+ lis, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ log.Error("Failed to listen on a free port: %v", err)
+ ctx.Resp.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ hopefullyFreePort := strings.SplitN(lis.Addr().String(), ":", 2)[1]
+ lis.Close()
+ p2phttpCtx, p2phttpCtxCancel := context.WithCancel(context.Background())
+ go func(ctx context.Context) {
+ cmd := exec.CommandContext(ctx, "git", "-C", repoPath, "annex", "p2phttp", "-J2", "--bind", "127.0.0.1", "--wideopen", "--port", hopefullyFreePort)
+ cmd.SysProcAttr = &syscall.SysProcAttr{
+ Pdeathsig: syscall.SIGINT,
+ }
+ cmd.Cancel = func() error { return cmd.Process.Signal(os.Interrupt) }
+ cmd.Env = append(os.Environ(),
+ "GIT_AUTHOR_NAME="+setting.AppName,
+ "GIT_AUTHOR_EMAIL="+setting.RunUser+"@"+setting.Domain,
+ "GIT_COMMITTER_NAME="+setting.AppName,
+ "GIT_COMMITTER_EMAIL="+setting.RunUser+"@"+setting.Domain,
+ )
+ _ = cmd.Run()
+ }(p2phttpCtx)
+ graceful.GetManager().RunAtTerminate(p2phttpCtxCancel)
+
+ // Wait for the p2phttp server to get ready
+ start := time.Now()
+ sleepDuration := 1 * time.Millisecond
+ for {
+ if time.Since(start) > 5*time.Second {
+ p2phttpCtxCancel()
+ log.Error("Failed to start the p2phttp server in a reasonable amount of time")
+ ctx.Resp.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ conn, err := net.Dial("tcp", "127.0.0.1:"+hopefullyFreePort)
+ if err == nil {
+ conn.Close()
+ break
+ }
+ time.Sleep(sleepDuration)
+ sleepDuration *= 2
+ if sleepDuration > 1*time.Second {
+ sleepDuration = 1 * time.Second
+ }
+ }
+
+ p2phttpRecord = &p2phttpRecordType{CancelFunc: p2phttpCtxCancel, LastUsed: time.Now(), Port: hopefullyFreePort}
+ p2phttpRecords[uuid] = p2phttpRecord
+ }
+
+ // Cleanup p2phttp processes that haven't been used for a while
+ for uuid, record := range p2phttpRecords {
+ if time.Since(record.LastUsed) > 5*time.Minute {
+ record.CancelFunc()
+ delete(p2phttpRecords, uuid)
+ }
+ }
+
+ url, err := url.Parse("http://127.0.0.1:" + p2phttpRecord.Port + strings.TrimPrefix(ctx.Req.RequestURI, "/git-annex-p2phttp"))
+ if err != nil {
+ log.Error("Failed to parse URL: %v", err)
+ ctx.Resp.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ proxy := httputil.ReverseProxy{
+ Rewrite: func(r *httputil.ProxyRequest) {
+ r.Out.URL = url
+ },
+ }
+ proxy.ServeHTTP(ctx.Resp, ctx.Req)
+}
diff --git a/routers/web/repo/attachment.go b/routers/web/repo/attachment.go
index f0c5622aec..e46c08fef8 100644
--- a/routers/web/repo/attachment.go
+++ b/routers/web/repo/attachment.go
@@ -7,18 +7,18 @@ import (
"fmt"
"net/http"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/services/attachment"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- repo_service "code.gitea.io/gitea/services/repository"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/attachment"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ repo_service "forgejo.org/services/repository"
)
// UploadIssueAttachment response for Issue/PR attachments
@@ -122,6 +122,11 @@ func ServeAttachment(ctx *context.Context, uuid string) {
}
}
+ if attach.ExternalURL != "" {
+ ctx.Redirect(attach.ExternalURL)
+ return
+ }
+
if err := attach.IncreaseDownloadCount(ctx); err != nil {
ctx.ServerError("IncreaseDownloadCount", err)
return
@@ -129,7 +134,7 @@ func ServeAttachment(ctx *context.Context, uuid string) {
if setting.Attachment.Storage.MinioConfig.ServeDirect {
// If we have a signed url (S3, object storage), redirect to this directly.
- u, err := storage.Attachments.URL(attach.RelativePath(), attach.Name)
+ u, err := storage.Attachments.URL(attach.RelativePath(), attach.Name, nil)
if u != nil && err == nil {
ctx.Redirect(u.String())
diff --git a/routers/web/repo/badges/badges.go b/routers/web/repo/badges/badges.go
index a2306d5836..e623a21fc0 100644
--- a/routers/web/repo/badges/badges.go
+++ b/routers/web/repo/badges/badges.go
@@ -8,11 +8,11 @@ import (
"net/url"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/setting"
- context_module "code.gitea.io/gitea/services/context"
+ actions_model "forgejo.org/models/actions"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/setting"
+ context_module "forgejo.org/services/context"
)
func getBadgeURL(ctx *context_module.Context, label, text, color string) string {
diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go
index eea3d4dc00..ccdd59f2dd 100644
--- a/routers/web/repo/blame.go
+++ b/routers/web/repo/blame.go
@@ -10,17 +10,16 @@ import (
"net/url"
"strings"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/highlight"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
- files_service "code.gitea.io/gitea/services/repository/files"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/highlight"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
+ files_service "forgejo.org/services/repository/files"
)
type blameRow struct {
@@ -57,6 +56,11 @@ func RefBlame(ctx *context.Context) {
HandleGitError(ctx, "Repo.Commit.GetTreeEntryByPath", err)
return
}
+ if entry.IsDir() {
+ ctx.NotFound("Cannot blame directory", nil)
+ return
+ }
+
blob := entry.Blob()
ctx.Data["PageIsViewCode"] = true
@@ -254,7 +258,7 @@ func renderBlame(ctx *context.Context, blameParts []*git.BlamePart, commitNames
commitCnt++
// User avatar image
- commitSince := timeutil.TimeSinceUnix(timeutil.TimeStamp(commit.Author.When.Unix()), ctx.Locale)
+ commitSince := templates.TimeSince(commit.Author.When)
var avatar string
if commit.User != nil {
diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go
index f879a98786..af8a838fc9 100644
--- a/routers/web/repo/branch.go
+++ b/routers/web/repo/branch.go
@@ -11,23 +11,23 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/models"
- git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- release_service "code.gitea.io/gitea/services/release"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ release_service "forgejo.org/services/release"
+ repo_service "forgejo.org/services/repository"
)
const (
@@ -70,6 +70,11 @@ func Branches(ctx *context.Context) {
ctx.ServerError("LoadBranches", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for key := range commitStatuses {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key])
+ }
+ }
commitStatus := make(map[string]*git_model.CommitStatus)
for commitID, cs := range commitStatuses {
diff --git a/routers/web/repo/card.go b/routers/web/repo/card.go
new file mode 100644
index 0000000000..449e5c4890
--- /dev/null
+++ b/routers/web/repo/card.go
@@ -0,0 +1,526 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package repo
+
+import (
+ "bytes"
+ "encoding/hex"
+ "fmt"
+ "image"
+ "image/color"
+ "image/png"
+ "net/http"
+ "strconv"
+ "strings"
+ "time"
+
+ "forgejo.org/models/db"
+ issue_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/card"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/services/context"
+)
+
+// drawUser draws a user avatar in a summary card
+func drawUser(ctx *context.Context, card *card.Card, user *user_model.User) error {
+ if user.UseCustomAvatar {
+ posterAvatarPath := user.CustomAvatarRelativePath()
+ if posterAvatarPath != "" {
+ userAvatarFile, err := storage.Avatars.Open(user.CustomAvatarRelativePath())
+ if err != nil {
+ return err
+ }
+ userAvatarImage, _, err := image.Decode(userAvatarFile)
+ if err != nil {
+ return err
+ }
+ card.DrawImage(userAvatarImage)
+ }
+ } else {
+ posterAvatarLink := user.AvatarLinkWithSize(ctx, 256)
+ card.DrawExternalImage(posterAvatarLink)
+ }
+ return nil
+}
+
+// drawRepoIcon draws the repo icon in a summary card
+func drawRepoIcon(ctx *context.Context, card *card.Card, repo *repo_model.Repository) error {
+ repoAvatarPath := repo.CustomAvatarRelativePath()
+
+ if repoAvatarPath != "" {
+ repoAvatarFile, err := storage.RepoAvatars.Open(repoAvatarPath)
+ if err != nil {
+ return err
+ }
+ repoAvatarImage, _, err := image.Decode(repoAvatarFile)
+ if err != nil {
+ return err
+ }
+ card.DrawImage(repoAvatarImage)
+ return nil
+ }
+
+ // If the repo didn't have an avatar, fallback to the repo owner's avatar for the right-hand-side icon
+ err := repo.LoadOwner(ctx)
+ if err != nil {
+ return err
+ }
+ if repo.Owner != nil {
+ err = drawUser(ctx, card, repo.Owner)
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+// hexToColor converts a hex color to a go color
+func hexToColor(colorStr string) (*color.RGBA, error) {
+ colorStr = strings.TrimLeft(colorStr, "#")
+
+ b, err := hex.DecodeString(colorStr)
+ if err != nil {
+ return nil, err
+ }
+
+ if len(b) < 3 {
+ return nil, fmt.Errorf("expected at least 3 bytes from DecodeString, got %d", len(b))
+ }
+
+ color := color.RGBA{b[0], b[1], b[2], 255}
+
+ return &color, nil
+}
+
+func drawLanguagesCard(ctx *context.Context, card *card.Card) error {
+ languageList, err := repo_model.GetTopLanguageStats(ctx, ctx.Repo.Repository, 5)
+ if err != nil {
+ return err
+ }
+ if len(languageList) == 0 {
+ card.DrawRect(0, 0, card.Width, card.Height, color.White)
+ return nil
+ }
+
+ currentX := 0
+ var langColor *color.RGBA
+
+ for _, lang := range languageList {
+ langColor, err = hexToColor(lang.Color)
+ if err != nil {
+ return err
+ }
+
+ langWidth := float32(card.Width) * (lang.Percentage / 100)
+ card.DrawRect(currentX, 0, currentX+int(langWidth), card.Width, langColor)
+ currentX += int(langWidth)
+ }
+
+ if currentX < card.Width {
+ card.DrawRect(currentX, 0, card.Width, card.Height, langColor)
+ }
+
+ return nil
+}
+
+func drawRepoSummaryCard(ctx *context.Context, repo *repo_model.Repository) (*card.Card, error) {
+ width, height := card.DefaultSize()
+ mainCard, err := card.NewCard(width, height)
+ if err != nil {
+ return nil, err
+ }
+
+ contentCard, languageBarCard := mainCard.Split(false, 90)
+
+ contentCard.SetMargin(60)
+ topSection, bottomSection := contentCard.Split(false, 75)
+ issueSummary, issueIcon := topSection.Split(true, 80)
+ repoInfo, issueDescription := issueSummary.Split(false, 30)
+
+ repoInfo.SetMargin(10)
+ _, err = repoInfo.DrawText(repo.FullName(), color.Black, 56, card.Top, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ issueDescription.SetMargin(10)
+ _, err = issueDescription.DrawText(repo.Description, color.Gray{128}, 36, card.Top, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ issueIcon.SetMargin(10)
+ err = drawRepoIcon(ctx, issueIcon, repo)
+ if err != nil {
+ return nil, err
+ }
+
+ topCountCard, bottomCountCard := bottomSection.Split(false, 50)
+
+ releaseCount, err := db.Count[repo_model.Release](ctx, repo_model.FindReleasesOptions{
+ // only show draft releases for users who can write, read-only users shouldn't see draft releases.
+ IncludeDrafts: ctx.Repo.CanWrite(unit_model.TypeReleases),
+ RepoID: ctx.Repo.Repository.ID,
+ })
+ if err != nil {
+ return nil, err
+ }
+
+ starsText := ctx.Locale.TrN(
+ repo.NumStars,
+ "explore.stars_one",
+ "explore.stars_few",
+ repo.NumStars,
+ )
+ forksText := ctx.Locale.TrN(
+ repo.NumForks,
+ "explore.forks_one",
+ "explore.forks_few",
+ repo.NumForks,
+ )
+ releasesText := ctx.Locale.TrN(
+ releaseCount,
+ "repo.activity.title.releases_1",
+ "repo.activity.title.releases_n",
+ releaseCount,
+ )
+
+ topCountText := fmt.Sprintf("%s โข %s โข %s", starsText, forksText, releasesText)
+
+ topCountCard.SetMargin(10)
+ _, err = topCountCard.DrawText(topCountText, color.Gray{128}, 36, card.Top, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ issuesText := ctx.Locale.TrN(
+ repo.NumOpenIssues,
+ "repo.activity.title.issues_1",
+ "repo.activity.title.issues_n",
+ repo.NumOpenIssues,
+ )
+ pullRequestsText := ctx.Locale.TrN(
+ repo.NumOpenPulls,
+ "repo.activity.title.prs_1",
+ "repo.activity.title.prs_n",
+ repo.NumOpenPulls,
+ )
+
+ bottomCountText := fmt.Sprintf("%s โข %s", issuesText, pullRequestsText)
+
+ bottomCountCard.SetMargin(10)
+ _, err = bottomCountCard.DrawText(bottomCountText, color.Gray{128}, 36, card.Top, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ err = drawLanguagesCard(ctx, languageBarCard)
+ if err != nil {
+ return nil, err
+ }
+
+ return mainCard, nil
+}
+
+func drawIssueSummaryCard(ctx *context.Context, issue *issue_model.Issue) (*card.Card, error) {
+ width, height := card.DefaultSize()
+ mainCard, err := card.NewCard(width, height)
+ if err != nil {
+ return nil, err
+ }
+
+ mainCard.SetMargin(60)
+ topSection, bottomSection := mainCard.Split(false, 75)
+ issueSummary, issueIcon := topSection.Split(true, 80)
+ repoInfo, issueDescription := issueSummary.Split(false, 15)
+
+ repoInfo.SetMargin(10)
+ _, err = repoInfo.DrawText(fmt.Sprintf("%s - #%d", issue.Repo.FullName(), issue.Index), color.Gray{128}, 36, card.Top, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ issueDescription.SetMargin(10)
+ _, err = issueDescription.DrawText(issue.Title, color.Black, 56, card.Top, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ issueIcon.SetMargin(10)
+ err = drawRepoIcon(ctx, issueIcon, issue.Repo)
+ if err != nil {
+ return nil, err
+ }
+
+ issueStats, issueAttribution := bottomSection.Split(false, 50)
+
+ var state string
+ if issue.IsPull && issue.PullRequest.HasMerged {
+ if issue.PullRequest.Status == 3 {
+ state = ctx.Locale.TrString("repo.pulls.manually_merged")
+ } else {
+ state = ctx.Locale.TrString("repo.pulls.merged")
+ }
+ } else if issue.IsClosed {
+ state = ctx.Locale.TrString("repo.issues.closed_title")
+ } else if issue.IsPull {
+ if issue.PullRequest.IsWorkInProgress(ctx) {
+ state = ctx.Locale.TrString("repo.issues.draft_title")
+ } else {
+ state = ctx.Locale.TrString("repo.issues.open_title")
+ }
+ } else {
+ state = ctx.Locale.TrString("repo.issues.open_title")
+ }
+ state = strings.ToLower(state)
+
+ issueStats.SetMargin(10)
+ if issue.IsPull {
+ reviews := map[int64]bool{}
+ for _, comment := range issue.Comments {
+ if comment.Review != nil {
+ reviews[comment.Review.ID] = true
+ }
+ }
+ _, err = issueStats.DrawText(
+ fmt.Sprintf("%s, %s, %s",
+ ctx.Locale.TrN(
+ issue.NumComments,
+ "repo.issues.num_comments_1",
+ "repo.issues.num_comments",
+ issue.NumComments,
+ ),
+ ctx.Locale.TrN(
+ len(reviews),
+ "repo.issues.num_reviews_one",
+ "repo.issues.num_reviews_few",
+ len(reviews),
+ ),
+ state,
+ ),
+ color.Gray{128}, 36, card.Top, card.Left)
+ } else {
+ _, err = issueStats.DrawText(
+ fmt.Sprintf("%s, %s",
+ ctx.Locale.TrN(
+ issue.NumComments,
+ "repo.issues.num_comments_1",
+ "repo.issues.num_comments",
+ issue.NumComments,
+ ),
+ state,
+ ),
+ color.Gray{128}, 36, card.Top, card.Left)
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ issueAttributionIcon, issueAttributionText := issueAttribution.Split(true, 8)
+ issueAttributionText.SetMargin(5)
+ _, err = issueAttributionText.DrawText(
+ fmt.Sprintf(
+ "%s - %s",
+ issue.Poster.Name,
+ issue.Created.AsTime().Format(time.DateOnly),
+ ),
+ color.Gray{128}, 36, card.Middle, card.Left)
+ if err != nil {
+ return nil, err
+ }
+ err = drawUser(ctx, issueAttributionIcon, issue.Poster)
+ if err != nil {
+ return nil, err
+ }
+
+ return mainCard, nil
+}
+
+func drawReleaseSummaryCard(ctx *context.Context, release *repo_model.Release) (*card.Card, error) {
+ width, height := card.DefaultSize()
+ mainCard, err := card.NewCard(width, height)
+ if err != nil {
+ return nil, err
+ }
+
+ mainCard.SetMargin(60)
+ topSection, bottomSection := mainCard.Split(false, 75)
+ releaseSummary, repoIcon := topSection.Split(true, 80)
+ repoInfo, releaseDescription := releaseSummary.Split(false, 15)
+
+ repoInfo.SetMargin(10)
+ _, err = repoInfo.DrawText(release.Repo.FullName(), color.Gray{128}, 36, card.Top, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ releaseDescription.SetMargin(10)
+ _, err = releaseDescription.DrawText(release.DisplayName(), color.Black, 56, card.Top, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ repoIcon.SetMargin(10)
+ err = drawRepoIcon(ctx, repoIcon, release.Repo)
+ if err != nil {
+ return nil, err
+ }
+
+ downloadCountCard, releaseDateCard := bottomSection.Split(true, 75)
+
+ downloadCount, err := release.GetTotalDownloadCount(ctx)
+ if err != nil {
+ return nil, err
+ }
+
+ downloadCountText := ctx.Locale.TrN(
+ strconv.FormatInt(downloadCount, 10),
+ "repo.release.download_count_one",
+ "repo.release.download_count_few",
+ strconv.FormatInt(downloadCount, 10),
+ )
+
+ _, err = downloadCountCard.DrawText(string(downloadCountText), color.Gray{128}, 36, card.Bottom, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ _, err = releaseDateCard.DrawText(release.CreatedUnix.AsTime().Format(time.DateOnly), color.Gray{128}, 36, card.Bottom, card.Left)
+ if err != nil {
+ return nil, err
+ }
+
+ return mainCard, nil
+}
+
+// checkCardCache checks if a card in cache and serves it
+func checkCardCache(ctx *context.Context, cacheKey string) bool {
+ cache := cache.GetCache()
+ pngData, ok := cache.Get(cacheKey).([]byte)
+ if ok && pngData != nil && len(pngData) > 0 {
+ ctx.Resp.Header().Set("Content-Type", "image/png")
+ ctx.Resp.WriteHeader(http.StatusOK)
+ _, err := ctx.Resp.Write(pngData)
+ if err != nil {
+ ctx.ServerError("GetSummaryCard", err)
+ }
+ return true
+ }
+
+ return false
+}
+
+// serveCard server a Card to the user adds it to the cache
+func serveCard(ctx *context.Context, card *card.Card, cacheKey string) {
+ cache := cache.GetCache()
+
+ // Encode image, store in cache
+ var imageBuffer bytes.Buffer
+ err := png.Encode(&imageBuffer, card.Img)
+ if err != nil {
+ ctx.ServerError("GetSummaryCard", err)
+ return
+ }
+ imageBytes := imageBuffer.Bytes()
+ err = cache.Put(cacheKey, imageBytes, setting.CacheService.TTLSeconds())
+ if err != nil {
+ // don't abort serving the image if we just had a cache storage failure
+ log.Warn("failed to cache issue summary card: %v", err)
+ }
+
+ // Finish the uncached image response
+ ctx.Resp.Header().Set("Content-Type", "image/png")
+ ctx.Resp.WriteHeader(http.StatusOK)
+ _, err = ctx.Resp.Write(imageBytes)
+ if err != nil {
+ ctx.ServerError("GetSummaryCard", err)
+ return
+ }
+}
+
+func DrawRepoSummaryCard(ctx *context.Context) {
+ cacheKey := fmt.Sprintf("summary_card:repo:%s:%d", ctx.Locale.Language(), ctx.Repo.Repository.ID)
+
+ if checkCardCache(ctx, cacheKey) {
+ return
+ }
+
+ card, err := drawRepoSummaryCard(ctx, ctx.Repo.Repository)
+ if err != nil {
+ ctx.ServerError("drawRepoSummaryCar", err)
+ return
+ }
+
+ serveCard(ctx, card, cacheKey)
+}
+
+func DrawIssueSummaryCard(ctx *context.Context) {
+ issue, err := issue_model.GetIssueWithAttrsByIndex(ctx, ctx.Repo.Repository.ID, ctx.ParamsInt64(":index"))
+ if err != nil {
+ if issue_model.IsErrIssueNotExist(err) {
+ ctx.Error(http.StatusNotFound)
+ } else {
+ ctx.Error(http.StatusInternalServerError, "GetIssueByIndex", err.Error())
+ }
+ return
+ }
+
+ if !ctx.Repo.CanReadIssuesOrPulls(issue.IsPull) {
+ ctx.Error(http.StatusNotFound)
+ return
+ }
+
+ cacheKey := fmt.Sprintf("summary_card:issue:%s:%d", ctx.Locale.Language(), issue.ID)
+
+ if checkCardCache(ctx, cacheKey) {
+ return
+ }
+
+ card, err := drawIssueSummaryCard(ctx, issue)
+ if err != nil {
+ ctx.ServerError("drawIssueSummaryCar", err)
+ return
+ }
+
+ serveCard(ctx, card, cacheKey)
+}
+
+func DrawReleaseSummaryCard(ctx *context.Context) {
+ release, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, ctx.Params("*"))
+ if err != nil {
+ if repo_model.IsErrReleaseNotExist(err) {
+ ctx.NotFound("", nil)
+ } else {
+ ctx.ServerError("GetReleaseForRepoByID", err)
+ }
+ return
+ }
+
+ err = release.LoadRepo(ctx)
+ if err != nil {
+ ctx.ServerError("LoadRepo", err)
+ return
+ }
+
+ cacheKey := fmt.Sprintf("summary_card:release:%s:%d", ctx.Locale.Language(), release.ID)
+
+ if checkCardCache(ctx, cacheKey) {
+ return
+ }
+
+ card, err := drawReleaseSummaryCard(ctx, release)
+ if err != nil {
+ ctx.ServerError("drawRepoSummaryCar", err)
+ return
+ }
+
+ serveCard(ctx, card, cacheKey)
+}
diff --git a/routers/web/repo/cherry_pick.go b/routers/web/repo/cherry_pick.go
index 90dae704f4..0f57eb66f0 100644
--- a/routers/web/repo/cherry_pick.go
+++ b/routers/web/repo/cherry_pick.go
@@ -8,17 +8,17 @@ import (
"errors"
"strings"
- "code.gitea.io/gitea/models"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/repository/files"
+ "forgejo.org/models"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/repository/files"
)
var tplCherryPick base.TplName = "repo/editor/cherry_pick"
diff --git a/routers/web/repo/code_frequency.go b/routers/web/repo/code_frequency.go
index c76f492da0..04009b4afa 100644
--- a/routers/web/repo/code_frequency.go
+++ b/routers/web/repo/code_frequency.go
@@ -7,9 +7,9 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/services/context"
- contributors_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/modules/base"
+ "forgejo.org/services/context"
+ contributors_service "forgejo.org/services/repository"
)
const (
diff --git a/routers/web/repo/commit.go b/routers/web/repo/commit.go
index 33491ec696..3cd80a6777 100644
--- a/routers/web/repo/commit.go
+++ b/routers/web/repo/commit.go
@@ -12,23 +12,26 @@ import (
"path"
"strings"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitgraph"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/gitdiff"
- git_service "code.gitea.io/gitea/services/repository"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/gitdiff"
+ git_service "forgejo.org/services/repository"
+ "forgejo.org/services/repository/gitgraph"
)
const (
@@ -81,7 +84,7 @@ func Commits(ctx *context.Context) {
ctx.ServerError("CommitsByRange", err)
return
}
- ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository)
+ ctx.Data["Commits"] = processGitCommits(ctx, commits)
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
@@ -199,7 +202,7 @@ func SearchCommits(ctx *context.Context) {
return
}
ctx.Data["CommitCount"] = len(commits)
- ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository)
+ ctx.Data["Commits"] = processGitCommits(ctx, commits)
ctx.Data["Keyword"] = query
if all {
@@ -242,6 +245,12 @@ func FileHistory(ctx *context.Context) {
ctx.ServerError("CommitsByFileAndRange", err)
return
}
+
+ if len(commits) == 0 {
+ ctx.NotFound("CommitsByFileAndRange", nil)
+ return
+ }
+
oldestCommit := commits[len(commits)-1]
renamedFiles, err := git.GetCommitFileRenames(ctx, ctx.Repo.GitRepo.Path, oldestCommit.ID.String())
@@ -258,7 +267,7 @@ func FileHistory(ctx *context.Context) {
}
}
- ctx.Data["Commits"] = git_model.ConvertFromGitCommit(ctx, commits, ctx.Repo.Repository)
+ ctx.Data["Commits"] = processGitCommits(ctx, commits)
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
@@ -306,11 +315,7 @@ func Diff(ctx *context.Context) {
commit, err := gitRepo.GetCommit(commitID)
if err != nil {
- if git.IsErrNotExist(err) {
- ctx.NotFound("Repo.GitRepo.GetCommit", err)
- } else {
- ctx.ServerError("Repo.GitRepo.GetCommit", err)
- }
+ ctx.NotFoundOrServerError("gitRepo.GetCommit", git.IsErrNotExist, err)
return
}
if len(commitID) != commit.ID.Type().FullLength() {
@@ -331,9 +336,10 @@ func Diff(ctx *context.Context) {
MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
MaxFiles: maxFiles,
WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)),
+ FileOnly: fileOnly,
}, files...)
if err != nil {
- ctx.NotFound("GetDiff", err)
+ ctx.ServerError("GetDiff", err)
return
}
@@ -369,6 +375,9 @@ func Diff(ctx *context.Context) {
if err != nil {
log.Error("GetLatestCommitStatus: %v", err)
}
+ if !ctx.Repo.CanRead(unit_model.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, statuses)
+ }
ctx.Data["CommitStatus"] = git_model.CalcCommitStatus(statuses)
ctx.Data["CommitStatuses"] = statuses
@@ -406,11 +415,9 @@ func Diff(ctx *context.Context) {
}
}
- ctx.Data["BranchName"], err = commit.GetBranchName()
- if err != nil {
- ctx.ServerError("commit.GetBranchName", err)
- return
- }
+ ctx.Data["OpenGraphTitle"] = commit.Summary() + " ยท " + base.ShortSha(commitID)
+ ctx.Data["OpenGraphURL"] = fmt.Sprintf("%s/commit/%s", ctx.Repo.Repository.HTMLURL(), commitID)
+ _, ctx.Data["OpenGraphDescription"], _ = strings.Cut(commit.Message(), "\n")
ctx.HTML(http.StatusOK, tplCommitPage)
}
@@ -448,3 +455,43 @@ func RawDiff(ctx *context.Context) {
return
}
}
+
+func processGitCommits(ctx *context.Context, gitCommits []*git.Commit) []*git_model.SignCommitWithStatuses {
+ commits := git_model.ConvertFromGitCommit(ctx, gitCommits, ctx.Repo.Repository)
+ if !ctx.Repo.CanRead(unit_model.TypeActions) {
+ for _, commit := range commits {
+ if commit.Status == nil {
+ continue
+ }
+ commit.Status.HideActionsURL(ctx)
+ git_model.CommitStatusesHideActionsURL(ctx, commit.Statuses)
+ }
+ }
+ return commits
+}
+
+func SetCommitNotes(ctx *context.Context) {
+ form := web.GetForm(ctx).(*forms.CommitNotesForm)
+
+ commitID := ctx.Params(":sha")
+
+ err := git.SetNote(ctx, ctx.Repo.GitRepo, commitID, form.Notes, ctx.Doer.Name, ctx.Doer.GetEmail())
+ if err != nil {
+ ctx.ServerError("SetNote", err)
+ return
+ }
+
+ ctx.Redirect(fmt.Sprintf("%s/commit/%s", ctx.Repo.Repository.HTMLURL(), commitID))
+}
+
+func RemoveCommitNotes(ctx *context.Context) {
+ commitID := ctx.Params(":sha")
+
+ err := git.RemoveNote(ctx, ctx.Repo.GitRepo, commitID)
+ if err != nil {
+ ctx.ServerError("RemoveNotes", err)
+ return
+ }
+
+ ctx.Redirect(fmt.Sprintf("%s/commit/%s", ctx.Repo.Repository.HTMLURL(), commitID))
+}
diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go
index 088e5150f6..55d50c9a79 100644
--- a/routers/web/repo/compare.go
+++ b/routers/web/repo/compare.go
@@ -16,29 +16,30 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/charset"
- csv_module "code.gitea.io/gitea/modules/csv"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/typesniffer"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- "code.gitea.io/gitea/services/gitdiff"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/annex"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/charset"
+ csv_module "forgejo.org/modules/csv"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/typesniffer"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ "forgejo.org/services/gitdiff"
)
const (
@@ -51,6 +52,7 @@ const (
func setCompareContext(ctx *context.Context, before, head *git.Commit, headOwner, headName string) {
ctx.Data["BeforeCommit"] = before
ctx.Data["HeadCommit"] = head
+ ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login?redirect_to=" + url.QueryEscape(ctx.Data["Link"].(string))
ctx.Data["GetBlobByPathForCommit"] = func(commit *git.Commit, path string) *git.Blob {
if commit == nil {
@@ -71,7 +73,21 @@ func setCompareContext(ctx *context.Context, before, head *git.Commit, headOwner
return st
}
- st, err := blob.GuessContentType()
+ isAnnexed, err := annex.IsAnnexed(blob)
+ if err != nil {
+ log.Error("IsAnnexed failed: %v", err)
+ return st
+ }
+ if isAnnexed {
+ st, err = annex.GuessContentType(blob)
+ if err != nil {
+ log.Error("GuessContentType failed: %v", err)
+ return st
+ }
+ return st
+ }
+
+ st, err = blob.GuessContentType()
if err != nil {
log.Error("GuessContentType failed: %v", err)
return st
@@ -89,18 +105,18 @@ func SourceCommitURL(owner, name string, commit *git.Commit) string {
return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/src/commit/" + url.PathEscape(commit.ID.String())
}
-// RawCommitURL creates a relative URL for the raw commit in the given repository
-func RawCommitURL(owner, name string, commit *git.Commit) string {
- return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/raw/commit/" + url.PathEscape(commit.ID.String())
+// MediaCommitURL creates a relative URL for the commit media (plain git, LFS, or annex content) in the given repository
+func MediaCommitURL(owner, name string, commit *git.Commit) string {
+ return setting.AppSubURL + "/" + url.PathEscape(owner) + "/" + url.PathEscape(name) + "/media/commit/" + url.PathEscape(commit.ID.String())
}
// setPathsCompareContext sets context data for source and raw paths
func setPathsCompareContext(ctx *context.Context, base, head *git.Commit, headOwner, headName string) {
ctx.Data["SourcePath"] = SourceCommitURL(headOwner, headName, head)
- ctx.Data["RawPath"] = RawCommitURL(headOwner, headName, head)
+ ctx.Data["RawPath"] = MediaCommitURL(headOwner, headName, head)
if base != nil {
ctx.Data["BeforeSourcePath"] = SourceCommitURL(headOwner, headName, base)
- ctx.Data["BeforeRawPath"] = RawCommitURL(headOwner, headName, base)
+ ctx.Data["BeforeRawPath"] = MediaCommitURL(headOwner, headName, base)
}
}
@@ -230,6 +246,13 @@ func ParseCompareInfo(ctx *context.Context) *common.CompareInfo {
if infoPath == "" {
infos = []string{baseRepo.DefaultBranch, baseRepo.DefaultBranch}
} else {
+ infoPath, isDiff := strings.CutSuffix(infoPath, ".diff")
+ ctx.Data["ComparingDiff"] = isDiff
+ if !isDiff {
+ var isPatch bool
+ infoPath, isPatch = strings.CutSuffix(infoPath, ".patch")
+ ctx.Data["ComparingPatch"] = isPatch
+ }
infos = strings.SplitN(infoPath, "...", 2)
if len(infos) != 2 {
if infos = strings.SplitN(infoPath, "..", 2); len(infos) == 2 {
@@ -611,6 +634,8 @@ func PrepareCompareDiff(
maxLines, maxFiles = -1, -1
}
+ fileOnly := ctx.FormBool("file-only")
+
diff, err := gitdiff.GetDiff(ctx, ci.HeadGitRepo,
&gitdiff.DiffOptions{
BeforeCommitID: beforeCommitID,
@@ -621,6 +646,7 @@ func PrepareCompareDiff(
MaxFiles: maxFiles,
WhitespaceBehavior: whitespaceBehavior,
DirectComparison: ci.DirectComparison,
+ FileOnly: fileOnly,
}, ctx.FormStrings("files")...)
if err != nil {
ctx.ServerError("GetDiffRangeWithWhitespaceBehavior", err)
@@ -643,7 +669,7 @@ func PrepareCompareDiff(
return false
}
- commits := git_model.ConvertFromGitCommit(ctx, ci.CompareInfo.Commits, ci.HeadRepo)
+ commits := processGitCommits(ctx, ci.CompareInfo.Commits)
ctx.Data["Commits"] = commits
ctx.Data["CommitCount"] = len(commits)
@@ -713,6 +739,22 @@ func CompareDiff(ctx *context.Context) {
return
}
+ if ctx.Data["ComparingDiff"] != nil && ctx.Data["ComparingDiff"].(bool) {
+ err := git.GetRepoRawDiffForFile(ci.HeadGitRepo, ci.BaseBranch, ci.HeadBranch, git.RawDiffNormal, "", ctx.Resp)
+ if err != nil {
+ ctx.ServerError("ComparingDiff", err)
+ return
+ }
+ }
+
+ if ctx.Data["ComparingPatch"] != nil && ctx.Data["ComparingPatch"].(bool) {
+ err := git.GetRepoRawDiffForFile(ci.HeadGitRepo, ci.BaseBranch, ci.HeadBranch, git.RawDiffPatch, "", ctx.Resp)
+ if err != nil {
+ ctx.ServerError("ComparingPatch", err)
+ return
+ }
+ }
+
ctx.Data["PullRequestWorkInProgressPrefixes"] = setting.Repository.PullRequest.WorkInProgressPrefixes
ctx.Data["DirectComparison"] = ci.DirectComparison
ctx.Data["OtherCompareSeparator"] = ".."
@@ -798,7 +840,8 @@ func CompareDiff(ctx *context.Context) {
if ci.DirectComparison {
separator = ".."
}
- ctx.Data["Title"] = "Comparing " + base.ShortSha(beforeCommitID) + separator + base.ShortSha(afterCommitID)
+ ctx.Data["Comparing"] = base.ShortSha(beforeCommitID) + separator + base.ShortSha(afterCommitID)
+ ctx.Data["Title"] = "Comparing " + ctx.Data["Comparing"].(string)
ctx.Data["IsDiffCompare"] = true
_, templateErrs := setTemplateIfExists(ctx, pullRequestTemplateKey, pullRequestTemplateCandidates)
diff --git a/routers/web/repo/contributors.go b/routers/web/repo/contributors.go
index 762fbf9379..094d13b54b 100644
--- a/routers/web/repo/contributors.go
+++ b/routers/web/repo/contributors.go
@@ -7,9 +7,9 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/services/context"
- contributors_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/modules/base"
+ "forgejo.org/services/context"
+ contributors_service "forgejo.org/services/repository"
)
const (
diff --git a/routers/web/repo/download.go b/routers/web/repo/download.go
index c4a8baecca..50ad85735b 100644
--- a/routers/web/repo/download.go
+++ b/routers/web/repo/download.go
@@ -5,18 +5,18 @@
package repo
import (
- "path"
"time"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/services/context"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/modules/annex"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/context"
)
// ServeBlobOrLFS download a git.Blob redirecting to LFS if necessary
@@ -54,8 +54,8 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim
}
if setting.LFS.Storage.MinioConfig.ServeDirect {
- // If we have a signed url (S3, object storage), redirect to this directly.
- u, err := storage.LFS.URL(pointer.RelativePath(), blob.Name())
+ // If we have a signed url (S3, object storage, blob storage), redirect to this directly.
+ u, err := storage.LFS.URL(pointer.RelativePath(), blob.Name(), nil)
if u != nil && err == nil {
ctx.Redirect(u.String())
return nil
@@ -79,10 +79,30 @@ func ServeBlobOrLFS(ctx *context.Context, blob *git.Blob, lastModified *time.Tim
}
closed = true
+ // check for git-annex files
+ // (this code is weirdly redundant because I'm trying not to delete any lines in order to make merges easier)
+ isAnnexed, err := annex.IsAnnexed(blob)
+ if err != nil {
+ ctx.ServerError("annex.IsAnnexed", err)
+ return err
+ }
+ if isAnnexed {
+ content, err := annex.Content(blob)
+ if err != nil {
+ // XXX are there any other possible failure cases here?
+ // there are, there could be unrelated io errors; those should be ctx.ServerError()s
+ ctx.NotFound("annex.Content", err)
+ return err
+ }
+ defer content.Close()
+ common.ServeContentByReadSeeker(ctx.Base, ctx.Repo.TreePath, lastModified, content)
+ return nil
+ }
+
return common.ServeBlob(ctx.Base, ctx.Repo.TreePath, blob, lastModified)
}
-func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.Time) {
+func getBlobForEntry(ctx *context.Context) (*git.Blob, *time.Time) {
entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath)
if err != nil {
if git.IsErrNotExist(err) {
@@ -98,19 +118,14 @@ func getBlobForEntry(ctx *context.Context) (blob *git.Blob, lastModified *time.T
return nil, nil
}
- info, _, err := git.Entries([]*git.TreeEntry{entry}).GetCommitsInfo(ctx, ctx.Repo.Commit, path.Dir("/" + ctx.Repo.TreePath)[1:])
+ latestCommit, err := ctx.Repo.GitRepo.GetTreePathLatestCommit(ctx.Repo.Commit.ID.String(), ctx.Repo.TreePath)
if err != nil {
- ctx.ServerError("GetCommitsInfo", err)
+ ctx.ServerError("GetTreePathLatestCommit", err)
return nil, nil
}
+ lastModified := &latestCommit.Committer.When
- if len(info) == 1 {
- // Not Modified
- lastModified = &info[0].Commit.Committer.When
- }
- blob = entry.Blob()
-
- return blob, lastModified
+ return entry.Blob(), lastModified
}
// SingleDownload download a file by repos path
diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go
index 00c3d880a9..5114cc9c05 100644
--- a/routers/web/repo/editor.go
+++ b/routers/web/repo/editor.go
@@ -10,26 +10,26 @@ import (
"path"
"strings"
- "code.gitea.io/gitea/models"
- git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/typesniffer"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/utils"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- "code.gitea.io/gitea/services/forms"
- files_service "code.gitea.io/gitea/services/repository/files"
+ "forgejo.org/models"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/typesniffer"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/utils"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ "forgejo.org/services/forms"
+ files_service "forgejo.org/services/repository/files"
)
const (
@@ -211,6 +211,7 @@ func editFile(ctx *context.Context, isNewFile bool) {
ctx.Data["TreeNames"] = treeNames
ctx.Data["TreePaths"] = treePaths
ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL()
+ ctx.Data["BranchPath"] = ctx.Repo.BranchNameSubURL()
ctx.Data["commit_summary"] = ""
ctx.Data["commit_message"] = ""
if canCommit {
@@ -584,7 +585,7 @@ func DeleteFilePost(ctx *context.Context) {
ctx.Error(http.StatusInternalServerError, err.Error())
}
} else if models.IsErrCommitIDDoesNotMatch(err) || git.IsErrPushOutOfDate(err) {
- ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_deleting", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(ctx.Repo.CommitID)), tplDeleteFile, &form)
+ ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(form.LastCommit)+"..."+util.PathEscapeSegments(ctx.Repo.CommitID)), tplDeleteFile, &form)
} else if git.IsErrPushRejected(err) {
errPushRej := err.(*git.ErrPushRejected)
if len(errPushRej.Message) == 0 {
diff --git a/routers/web/repo/editor_test.go b/routers/web/repo/editor_test.go
index 313fcfe33a..5b893cf258 100644
--- a/routers/web/repo/editor_test.go
+++ b/routers/web/repo/editor_test.go
@@ -6,10 +6,11 @@ package repo
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/services/contexttest"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
)
@@ -45,7 +46,6 @@ func TestGetUniquePatchBranchName(t *testing.T) {
ctx, _ := contexttest.MockContext(t, "user2/repo1")
ctx.SetParams(":id", "1")
contexttest.LoadRepo(t, ctx, 1)
- contexttest.LoadRepoCommit(t, ctx)
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadGitRepo(t, ctx)
defer ctx.Repo.GitRepo.Close()
@@ -57,15 +57,7 @@ func TestGetUniquePatchBranchName(t *testing.T) {
func TestGetClosestParentWithFiles(t *testing.T) {
unittest.PrepareTestEnv(t)
- ctx, _ := contexttest.MockContext(t, "user2/repo1")
- ctx.SetParams(":id", "1")
- contexttest.LoadRepo(t, ctx, 1)
- contexttest.LoadRepoCommit(t, ctx)
- contexttest.LoadUser(t, ctx, 2)
- contexttest.LoadGitRepo(t, ctx)
- defer ctx.Repo.GitRepo.Close()
-
- repo := ctx.Repo.Repository
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
branch := repo.DefaultBranch
gitRepo, _ := gitrepo.OpenRepository(git.DefaultContext, repo)
defer gitRepo.Close()
diff --git a/routers/web/repo/find.go b/routers/web/repo/find.go
index 9da4237c1e..808323631c 100644
--- a/routers/web/repo/find.go
+++ b/routers/web/repo/find.go
@@ -6,9 +6,9 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/repo/flags/manage.go b/routers/web/repo/flags/manage.go
index 377a5c20f8..c97ef54818 100644
--- a/routers/web/repo/flags/manage.go
+++ b/routers/web/repo/flags/manage.go
@@ -6,10 +6,10 @@ package flags
import (
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go
index 9f3b63698a..ada9d350c9 100644
--- a/routers/web/repo/githttp.go
+++ b/routers/web/repo/githttp.go
@@ -10,6 +10,7 @@ import (
gocontext "context"
"fmt"
"net/http"
+ "net/url"
"os"
"path/filepath"
"regexp"
@@ -18,20 +19,20 @@ import (
"sync"
"time"
- actions_model "code.gitea.io/gitea/models/actions"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
- repo_service "code.gitea.io/gitea/services/repository"
+ actions_model "forgejo.org/models/actions"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
+ repo_service "forgejo.org/services/repository"
"github.com/go-chi/cors"
)
@@ -78,7 +79,7 @@ func httpBase(ctx *context.Context) *serviceHandler {
strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") {
isPull = true
} else {
- isPull = ctx.Req.Method == "GET"
+ isPull = ctx.Req.Method == "GET" || ctx.Req.Method == "HEAD"
}
var accessMode perm.AccessMode
@@ -242,8 +243,9 @@ func httpBase(ctx *context.Context) *serviceHandler {
}
}
+ isRequestToConfig := strings.HasSuffix(ctx.Req.URL.Path, "/config")
if !repoExist {
- if !receivePack {
+ if !receivePack && !isRequestToConfig {
ctx.PlainText(http.StatusNotFound, "Repository not found")
return nil
}
@@ -263,7 +265,7 @@ func httpBase(ctx *context.Context) *serviceHandler {
}
// Return dummy payload if GET receive-pack
- if ctx.Req.Method == http.MethodGet {
+ if ctx.Req.Method == http.MethodGet && !isRequestToConfig {
dummyInfoRefs(ctx)
return nil
}
@@ -395,7 +397,8 @@ func (h *serviceHandler) sendFile(ctx *context.Context, contentType, file string
ctx.Resp.Header().Set("Content-Type", contentType)
ctx.Resp.Header().Set("Content-Length", fmt.Sprintf("%d", fi.Size()))
- ctx.Resp.Header().Set("Last-Modified", fi.ModTime().Format(http.TimeFormat))
+ // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat
+ ctx.Resp.Header().Set("Last-Modified", fi.ModTime().UTC().Format(http.TimeFormat))
http.ServeFile(ctx.Resp, ctx.Req, reqFile)
}
@@ -466,7 +469,7 @@ func serviceRPC(ctx *context.Context, h *serviceHandler, service string) {
Stderr: &stderr,
UseContextTimeout: true,
}); err != nil {
- if err.Error() != "signal: killed" {
+ if !git.IsErrCanceledOrKilled(err) {
log.Error("Fail to serve RPC(%s) in %s: %v - %s", service, h.getRepoDir(), err, stderr.String())
}
return
@@ -544,6 +547,57 @@ func GetInfoRefs(ctx *context.Context) {
}
}
+// GetConfig implements fetching the git config of a repository
+func GetConfig(ctx *context.Context) {
+ h := httpBase(ctx)
+ if h != nil {
+ setHeaderNoCache(ctx)
+ if setting.Annex.Enabled && strings.HasPrefix(ctx.Req.UserAgent(), "git-annex/") {
+ p, err := access_model.GetUserRepoPermission(ctx, h.repo, ctx.Doer)
+ if err != nil {
+ ctx.ServerError("GetUserRepoPermission", err)
+ return
+ }
+
+ if p.CanAccess(perm.AccessModeWrite, unit.TypeCode) {
+ _, _, err := git.NewCommand(ctx, "annex", "init").RunStdString(&git.RunOpts{Dir: h.getRepoDir()})
+ if err != nil {
+ ctx.Resp.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ }
+ }
+ config, err := os.ReadFile(filepath.Join(h.getRepoDir(), "config"))
+ if err != nil {
+ log.Error("Failed to read git config file: %v", err)
+ ctx.Resp.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ if !setting.Annex.DisableP2PHTTP {
+ appURL, err := url.Parse(setting.AppURL)
+ if err != nil {
+ log.Error("Could not parse 'setting.AppURL': %v", err)
+ ctx.Resp.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ if appURL.Port() == "" {
+ // If there is no port set then set the http(s) default ports.
+ // Without this, git-annex would try its own default port (9417) and fail.
+ if appURL.Scheme == "http" {
+ appURL.Host += ":80"
+ }
+ if appURL.Scheme == "https" {
+ appURL.Host += ":443"
+ }
+ }
+ config = append(config, []byte("[annex]\n\turl = annex+"+appURL.String()+"git-annex-p2phttp\n")...)
+ }
+ ctx.Resp.Header().Set("Content-Type", "text/plain")
+ ctx.Resp.Header().Set("Content-Length", fmt.Sprintf("%d", len(config)))
+ http.ServeContent(ctx.Resp, ctx.Req, "config", time.Now(), bytes.NewReader(config))
+ }
+}
+
// GetTextFile implements Git dumb HTTP
func GetTextFile(p string) func(*context.Context) {
return func(ctx *context.Context) {
@@ -596,3 +650,34 @@ func GetIdxFile(ctx *context.Context) {
h.sendFile(ctx, "application/x-git-packed-objects-toc", "objects/pack/pack-"+ctx.Params("file")+".idx")
}
}
+
+// GetAnnexObject implements git-annex dumb HTTP
+func GetAnnexObject(ctx *context.Context) {
+ h := httpBase(ctx)
+ if h != nil {
+ // git-annex objects are stored in .git/annex/objects/{hash1}/{hash2}/{key}/{key}
+ // where key is a string containing the size and (usually SHA256) checksum of the file,
+ // and hash1+hash2 are the first few bits of the md5sum of key itself.
+ // ({hash1}/{hash2}/ is just there to avoid putting too many files in one directory)
+ // ref: https://git-annex.branchable.com/internals/hashing/
+
+ // keyDir should = key, but we don't enforce that
+ object := filepath.Join(ctx.Params("hash1"), ctx.Params("hash2"), ctx.Params("keyDir"), ctx.Params("key"))
+
+ // Sanitize the input against directory traversals.
+ //
+ // This works because at the filesystem root, "/.." = "/";
+ // So if a path starts rooted ("/"), path.Clean(), which
+ // path.Join() calls internally, removes all '..' prefixes.
+ // After, this unroots the path unconditionally ([1:]), which
+ // works because we know the input is never supposed to be rooted.
+ //
+ // The router code probably also disallows "..", so this
+ // should be redundant, but it's defensive to keep it
+ // whenever touching filesystem paths with user input.
+ object = filepath.Join(string(filepath.Separator), object)[1:]
+
+ setHeaderCacheForever(ctx)
+ h.sendFile(ctx, "application/octet-stream", "annex/objects/"+object)
+ }
+}
diff --git a/routers/web/repo/helper.go b/routers/web/repo/helper.go
index 5e1e116018..9d67f142fb 100644
--- a/routers/web/repo/helper.go
+++ b/routers/web/repo/helper.go
@@ -5,21 +5,21 @@ package repo
import (
"net/url"
- "sort"
+ "slices"
- "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/services/context"
)
func MakeSelfOnTop(doer *user.User, users []*user.User) []*user.User {
if doer != nil {
- sort.Slice(users, func(i, j int) bool {
- if users[i].ID == users[j].ID {
- return false
- }
- return users[i].ID == doer.ID // if users[i] is self, put it before others, so less=true
+ doerIndex := slices.IndexFunc(users, func(user *user.User) bool {
+ return user.ID == doer.ID
})
+ if doerIndex != -1 {
+ return slices.Insert(slices.Delete(users, doerIndex, doerIndex+1), 0, doer)
+ }
}
return users
}
diff --git a/routers/web/repo/helper_test.go b/routers/web/repo/helper_test.go
index 978758e77f..2607fd32f8 100644
--- a/routers/web/repo/helper_test.go
+++ b/routers/web/repo/helper_test.go
@@ -6,7 +6,7 @@ package repo
import (
"testing"
- "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
)
@@ -23,4 +23,15 @@ func TestMakeSelfOnTop(t *testing.T) {
users = MakeSelfOnTop(&user.User{ID: 2}, []*user.User{{ID: 2}, {ID: 1}})
assert.Len(t, users, 2)
assert.EqualValues(t, 2, users[0].ID)
+
+ users = MakeSelfOnTop(&user.User{ID: 2}, []*user.User{{ID: 1}})
+ assert.Len(t, users, 1)
+ assert.EqualValues(t, 1, users[0].ID)
+
+ users = MakeSelfOnTop(&user.User{ID: 2}, []*user.User{{ID: 1}, {ID: 2}, {ID: 3}, {ID: 4}})
+ assert.Len(t, users, 4)
+ assert.EqualValues(t, 2, users[0].ID)
+ assert.EqualValues(t, 1, users[1].ID)
+ assert.EqualValues(t, 3, users[2].ID)
+ assert.EqualValues(t, 4, users[3].ID)
}
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index e34f90c73b..ff3a903aed 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -1,5 +1,6 @@
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2018 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package repo
@@ -19,44 +20,46 @@ import (
"strings"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- project_model "code.gitea.io/gitea/models/project"
- pull_model "code.gitea.io/gitea/models/pull"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/emoji"
- "code.gitea.io/gitea/modules/git"
- issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
- issue_template "code.gitea.io/gitea/modules/issue/template"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/optional"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/templates/vars"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/utils"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/forms"
- issue_service "code.gitea.io/gitea/services/issue"
- pull_service "code.gitea.io/gitea/services/pull"
- repo_service "code.gitea.io/gitea/services/repository"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ project_model "forgejo.org/models/project"
+ pull_model "forgejo.org/models/pull"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/emoji"
+ "forgejo.org/modules/git"
+ issue_indexer "forgejo.org/modules/indexer/issues"
+ issue_template "forgejo.org/modules/issue/template"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/optional"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/templates/vars"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/utils"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/forms"
+ issue_service "forgejo.org/services/issue"
+ pull_service "forgejo.org/services/pull"
+ repo_service "forgejo.org/services/repository"
+
+ "code.forgejo.org/go-chi/binding"
)
const (
@@ -201,8 +204,6 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
keyword = ""
}
- isFuzzy := ctx.FormBool("fuzzy")
-
var mileIDs []int64
if milestoneID > 0 || milestoneID == db.NoConditionID { // -1 to get those issues which have no any milestone assigned
mileIDs = []int64{milestoneID}
@@ -223,7 +224,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
IssueIDs: nil,
}
if keyword != "" {
- allIssueIDs, err := issueIDsFromSearch(ctx, keyword, isFuzzy, statsOpts)
+ allIssueIDs, err := issueIDsFromSearch(ctx, keyword, statsOpts)
if err != nil {
if issue_indexer.IsAvailable(ctx) {
ctx.ServerError("issueIDsFromSearch", err)
@@ -291,7 +292,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
var issues issues_model.IssueList
{
- ids, err := issueIDsFromSearch(ctx, keyword, isFuzzy, &issues_model.IssuesOptions{
+ ids, err := issueIDsFromSearch(ctx, keyword, &issues_model.IssuesOptions{
Paginator: &db.ListOptions{
Page: pager.Paginater.Current(),
PageSize: setting.UI.IssuePagingNum,
@@ -346,6 +347,11 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ctx.ServerError("GetIssuesAllCommitStatus", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for key := range commitStatuses {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key])
+ }
+ }
if err := issues.LoadAttributes(ctx); err != nil {
ctx.ServerError("issues.LoadAttributes", err)
@@ -449,14 +455,15 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ctx.Data["IssueStats"] = issueStats
ctx.Data["OpenCount"] = issueStats.OpenCount
ctx.Data["ClosedCount"] = issueStats.ClosedCount
- linkStr := "%s?q=%s&type=%s&sort=%s&state=%s&labels=%s&milestone=%d&project=%d&assignee=%d&poster=%d&archived=%t"
- ctx.Data["AllStatesLink"] = fmt.Sprintf(linkStr, ctx.Link,
+ ctx.Data["AllCount"] = issueStats.AllCount
+ linkStr := "?q=%s&type=%s&sort=%s&state=%s&labels=%s&milestone=%d&project=%d&assignee=%d&poster=%d&archived=%t"
+ ctx.Data["AllStatesLink"] = fmt.Sprintf(linkStr,
url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "all", url.QueryEscape(selectLabels),
milestoneID, projectID, assigneeID, posterID, archived)
- ctx.Data["OpenLink"] = fmt.Sprintf(linkStr, ctx.Link,
+ ctx.Data["OpenLink"] = fmt.Sprintf(linkStr,
url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "open", url.QueryEscape(selectLabels),
milestoneID, projectID, assigneeID, posterID, archived)
- ctx.Data["ClosedLink"] = fmt.Sprintf(linkStr, ctx.Link,
+ ctx.Data["ClosedLink"] = fmt.Sprintf(linkStr,
url.QueryEscape(keyword), url.QueryEscape(viewType), url.QueryEscape(sortType), "closed", url.QueryEscape(selectLabels),
milestoneID, projectID, assigneeID, posterID, archived)
ctx.Data["SelLabelIDs"] = labelIDs
@@ -467,8 +474,8 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
ctx.Data["ProjectID"] = projectID
ctx.Data["AssigneeID"] = assigneeID
ctx.Data["PosterID"] = posterID
- ctx.Data["IsFuzzy"] = isFuzzy
ctx.Data["Keyword"] = keyword
+ ctx.Data["IsShowClosed"] = isShowClosed
switch {
case isShowClosed.Value():
ctx.Data["State"] = "closed"
@@ -489,17 +496,12 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt
pager.AddParam(ctx, "assignee", "AssigneeID")
pager.AddParam(ctx, "poster", "PosterID")
pager.AddParam(ctx, "archived", "ShowArchivedLabels")
- pager.AddParam(ctx, "fuzzy", "IsFuzzy")
ctx.Data["Page"] = pager
}
-func issueIDsFromSearch(ctx *context.Context, keyword string, fuzzy bool, opts *issues_model.IssuesOptions) ([]int64, error) {
- ids, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts).Copy(
- func(o *issue_indexer.SearchOptions) {
- o.IsFuzzyKeyword = fuzzy
- },
- ))
+func issueIDsFromSearch(ctx *context.Context, keyword string, opts *issues_model.IssuesOptions) ([]int64, error) {
+ ids, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts))
if err != nil {
return nil, fmt.Errorf("SearchIssues: %w", err)
}
@@ -1258,7 +1260,11 @@ func NewIssuePost(ctx *context.Context) {
if err := issue_service.NewIssue(ctx, repo, issue, labelIDs, attachments, assigneeIDs); err != nil {
if errors.Is(err, user_model.ErrBlockedByUser) {
- ctx.RenderWithErr(ctx.Tr("repo.issues.blocked_by_user"), tplIssueNew, form)
+ if issue.IsPull {
+ ctx.JSONError(ctx.Tr("repo.pulls.blocked_by_user"))
+ } else {
+ ctx.JSONError(ctx.Tr("repo.issues.blocked_by_user"))
+ }
return
} else if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error())
@@ -1282,28 +1288,41 @@ func NewIssuePost(ctx *context.Context) {
log.Trace("Issue created: %d/%d", repo.ID, issue.ID)
if ctx.FormString("redirect_after_creation") == "project" && projectID > 0 {
- ctx.JSONRedirect(ctx.Repo.RepoLink + "/projects/" + strconv.FormatInt(projectID, 10))
- } else {
- ctx.JSONRedirect(issue.Link())
+ project, err := project_model.GetProjectByID(ctx, projectID)
+ if err == nil {
+ if project.Type == project_model.TypeOrganization {
+ ctx.JSONRedirect(project_model.ProjectLinkForOrg(ctx.Repo.Owner, project.ID))
+ } else {
+ ctx.JSONRedirect(project_model.ProjectLinkForRepo(repo, project.ID))
+ }
+ return
+ }
}
+ ctx.JSONRedirect(issue.Link())
}
// roleDescriptor returns the role descriptor for a comment in/with the given repo, poster and issue
func roleDescriptor(ctx stdCtx.Context, repo *repo_model.Repository, poster *user_model.User, issue *issues_model.Issue, hasOriginalAuthor bool) (issues_model.RoleDescriptor, error) {
roleDescriptor := issues_model.RoleDescriptor{}
+ // Migrated comment with no associated local user
if hasOriginalAuthor {
return roleDescriptor, nil
}
+ // Special user that can't have associated contributions and permissions in the repo.
+ if poster.IsGhost() || poster.IsActions() || poster.IsAPActor() {
+ return roleDescriptor, nil
+ }
+
+ // If the poster is the actual poster of the issue, enable Poster role.
+ roleDescriptor.IsPoster = issue.IsPoster(poster.ID)
+
perm, err := access_model.GetUserRepoPermission(ctx, repo, poster)
if err != nil {
return roleDescriptor, err
}
- // If the poster is the actual poster of the issue, enable Poster role.
- roleDescriptor.IsPoster = issue.IsPoster(poster.ID)
-
// Check if the poster is owner of the repo.
if perm.IsOwner() {
// If the poster isn't an admin, enable the owner role.
@@ -1370,6 +1389,22 @@ func getBranchData(ctx *context.Context, issue *issues_model.Issue) {
}
}
+func prepareHiddenCommentType(ctx *context.Context) {
+ var hiddenCommentTypes *big.Int
+ if ctx.IsSigned {
+ val, err := user_model.GetUserSetting(ctx, ctx.Doer.ID, user_model.SettingsKeyHiddenCommentTypes)
+ if err != nil {
+ ctx.ServerError("GetUserSetting", err)
+ return
+ }
+ hiddenCommentTypes, _ = new(big.Int).SetString(val, 10) // we can safely ignore the failed conversion here
+ }
+
+ ctx.Data["ShouldShowCommentType"] = func(commentType issues_model.CommentType) bool {
+ return hiddenCommentTypes == nil || hiddenCommentTypes.Bit(int(commentType)) == 0
+ }
+}
+
// ViewIssue render issue view page
func ViewIssue(ctx *context.Context) {
if ctx.Params(":type") == "issues" {
@@ -1676,7 +1711,7 @@ func ViewIssue(ctx *context.Context) {
}
ghostProject := &project_model.Project{
- ID: -1,
+ ID: project_model.GhostProjectID,
Title: ctx.Locale.TrString("repo.issues.deleted_project"),
}
@@ -1761,6 +1796,15 @@ func ViewIssue(ctx *context.Context) {
ctx.ServerError("LoadPushCommits", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for _, commit := range comment.Commits {
+ if commit.Status == nil {
+ continue
+ }
+ commit.Status.HideActionsURL(ctx)
+ git_model.CommitStatusesHideActionsURL(ctx, commit.Statuses)
+ }
+ }
} else if comment.Type == issues_model.CommentTypeAddTimeManual ||
comment.Type == issues_model.CommentTypeStopTracking ||
comment.Type == issues_model.CommentTypeDeleteTimeManual {
@@ -1790,7 +1834,7 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["LatestCloseCommentID"] = latestCloseCommentID
// Combine multiple label assignments into a single comment
- combineLabelComments(issue)
+ issues_model.CombineCommentsHistory(issue, time.Now().Unix())
getBranchData(ctx, issue)
if issue.IsPull {
@@ -1851,6 +1895,8 @@ func ViewIssue(ctx *context.Context) {
}
prConfig := prUnit.PullRequestsConfig()
+ ctx.Data["AutodetectManualMerge"] = prConfig.AutodetectManualMerge
+
var mergeStyle repo_model.MergeStyle
// Check correct values and select default
if ms, ok := ctx.Data["MergeStyle"].(repo_model.MergeStyle); !ok ||
@@ -1875,6 +1921,21 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["MergeStyle"] = mergeStyle
+ var updateStyle repo_model.UpdateStyle
+ // Check correct values and select default
+ if ms, ok := ctx.Data["UpdateStyle"].(repo_model.UpdateStyle); !ok ||
+ !prConfig.IsUpdateStyleAllowed(ms) {
+ defaultUpdateStyle := prConfig.GetDefaultUpdateStyle()
+ if prConfig.IsUpdateStyleAllowed(defaultUpdateStyle) && !ok {
+ updateStyle = defaultUpdateStyle
+ } else if prConfig.AllowMerge {
+ updateStyle = repo_model.UpdateStyleMerge
+ } else if prConfig.AllowRebase {
+ updateStyle = repo_model.UpdateStyleRebase
+ }
+ }
+ ctx.Data["UpdateStyle"] = updateStyle
+
defaultMergeMessage, defaultMergeBody, err := pull_service.GetDefaultMergeMessage(ctx, ctx.Repo.GitRepo, pull, mergeStyle)
if err != nil {
ctx.ServerError("GetDefaultMergeMessage", err)
@@ -2018,22 +2079,20 @@ func ViewIssue(ctx *context.Context) {
ctx.Data["RefEndName"] = git.RefName(issue.Ref).ShortName()
ctx.Data["NewPinAllowed"] = pinAllowed
ctx.Data["PinEnabled"] = setting.Repository.Issue.MaxPinned != 0
+ ctx.Data["OpenGraphTitle"] = issue.Title
+ ctx.Data["OpenGraphURL"] = issue.HTMLURL()
+ ctx.Data["OpenGraphDescription"] = issue.Content
+ ctx.Data["OpenGraphImageURL"] = issue.SummaryCardURL()
+ ctx.Data["OpenGraphImageAltText"] = ctx.Tr("repo.issues.summary_card_alt", issue.Title, issue.Repo.FullName())
+ ctx.Data["IsBlocked"] = ctx.Doer != nil && user_model.IsBlockedMultiple(ctx, []int64{issue.PosterID, issue.Repo.OwnerID}, ctx.Doer.ID)
- var hiddenCommentTypes *big.Int
- if ctx.IsSigned {
- val, err := user_model.GetUserSetting(ctx, ctx.Doer.ID, user_model.SettingsKeyHiddenCommentTypes)
- if err != nil {
- ctx.ServerError("GetUserSetting", err)
- return
- }
- hiddenCommentTypes, _ = new(big.Int).SetString(val, 10) // we can safely ignore the failed conversion here
- }
- ctx.Data["ShouldShowCommentType"] = func(commentType issues_model.CommentType) bool {
- return hiddenCommentTypes == nil || hiddenCommentTypes.Bit(int(commentType)) == 0
+ prepareHiddenCommentType(ctx)
+ if ctx.Written() {
+ return
}
+
// For sidebar
PrepareBranchList(ctx)
-
if ctx.Written() {
return
}
@@ -2194,10 +2253,20 @@ func UpdateIssueTitle(ctx *context.Context) {
ctx.Error(http.StatusForbidden)
return
}
-
title := ctx.FormTrim("title")
- if len(title) == 0 {
- ctx.Error(http.StatusNoContent)
+ if util.IsEmptyString(title) {
+ ctx.Error(http.StatusBadRequest, "Title cannot be empty or spaces")
+ return
+ }
+
+ // Creating a CreateIssueForm with the title so that we can validate the max title length
+ i := forms.CreateIssueForm{
+ Title: title,
+ }
+
+ bindingErr := binding.RawValidate(i)
+ if bindingErr.Has(binding.ERR_MAX_SIZE) {
+ ctx.Error(http.StatusBadRequest, "Title cannot be longer than 255 characters")
return
}
@@ -2342,7 +2411,49 @@ func UpdateIssueMilestone(ctx *context.Context) {
}
}
- ctx.JSONOK()
+ if ctx.FormBool("htmx") {
+ renderMilestones(ctx)
+ if ctx.Written() {
+ return
+ }
+ prepareHiddenCommentType(ctx)
+ if ctx.Written() {
+ return
+ }
+
+ issue := issues[0]
+ var err error
+ if issue.MilestoneID > 0 {
+ issue.Milestone, err = issues_model.GetMilestoneByRepoID(ctx, ctx.Repo.Repository.ID, issue.MilestoneID)
+ if err != nil {
+ ctx.ServerError("GetMilestoneByRepoID", err)
+ return
+ }
+ } else {
+ issue.Milestone = nil
+ }
+
+ comment := &issues_model.Comment{}
+ has, err := db.GetEngine(ctx).Where("issue_id = ? AND type = ?", issue.ID, issues_model.CommentTypeMilestone).OrderBy("id DESC").Limit(1).Get(comment)
+ if !has || err != nil {
+ ctx.ServerError("GetLatestMilestoneComment", err)
+ }
+ if err := comment.LoadMilestone(ctx); err != nil {
+ ctx.ServerError("LoadMilestone", err)
+ return
+ }
+ if err := comment.LoadPoster(ctx); err != nil {
+ ctx.ServerError("LoadPoster", err)
+ return
+ }
+ issue.Comments = issues_model.CommentList{comment}
+
+ ctx.Data["Issue"] = issue
+ ctx.Data["HasIssuesOrPullsWritePermission"] = ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull)
+ ctx.HTML(http.StatusOK, "htmx/milestone_sidebar")
+ } else {
+ ctx.JSONOK()
+ }
}
// UpdateIssueAssignee change issue's or pull's assignee
@@ -3092,6 +3203,15 @@ func NewComment(ctx *context.Context) {
} else {
isClosed := form.Status == "close"
if err := issue_service.ChangeStatus(ctx, issue, ctx.Doer, "", isClosed); err != nil {
+ if errors.Is(err, user_model.ErrBlockedByUser) {
+ if issue.IsPull {
+ ctx.JSONError(ctx.Tr("repo.pulls.blocked_by_user"))
+ } else {
+ ctx.JSONError(ctx.Tr("repo.issues.blocked_by_user"))
+ }
+ return
+ }
+
log.Error("ChangeStatus: %v", err)
if issues_model.IsErrDependenciesLeft(err) {
@@ -3133,7 +3253,11 @@ func NewComment(ctx *context.Context) {
comment, err := issue_service.CreateIssueComment(ctx, ctx.Doer, ctx.Repo.Repository, issue, form.Content, attachments)
if err != nil {
if errors.Is(err, user_model.ErrBlockedByUser) {
- ctx.Flash.Error(ctx.Tr("repo.issues.comment.blocked_by_user"))
+ if issue.IsPull {
+ ctx.JSONError(ctx.Tr("repo.pulls.comment.blocked_by_user"))
+ } else {
+ ctx.JSONError(ctx.Tr("repo.issues.comment.blocked_by_user"))
+ }
} else {
ctx.ServerError("CreateIssueComment", err)
}
@@ -3299,12 +3423,6 @@ func ChangeIssueReaction(ctx *context.Context) {
log.Info("CreateIssueReaction: %s", err)
break
}
- // Reload new reactions
- issue.Reactions = nil
- if err = issue.LoadAttributes(ctx); err != nil {
- log.Info("issue.LoadAttributes: %s", err)
- break
- }
log.Trace("Reaction for issue created: %d/%d/%d", ctx.Repo.Repository.ID, issue.ID, reaction.ID)
case "unreact":
@@ -3313,19 +3431,19 @@ func ChangeIssueReaction(ctx *context.Context) {
return
}
- // Reload new reactions
- issue.Reactions = nil
- if err := issue.LoadAttributes(ctx); err != nil {
- log.Info("issue.LoadAttributes: %s", err)
- break
- }
-
log.Trace("Reaction for issue removed: %d/%d", ctx.Repo.Repository.ID, issue.ID)
default:
ctx.NotFound(fmt.Sprintf("Unknown action %s", ctx.Params(":action")), nil)
return
}
+ // Reload new reactions
+ issue.Reactions = nil
+ if err := issue.LoadAttributes(ctx); err != nil {
+ ctx.ServerError("ChangeIssueReaction.LoadAttributes", err)
+ return
+ }
+
if len(issue.Reactions) == 0 {
ctx.JSON(http.StatusOK, map[string]any{
"empty": true,
@@ -3406,12 +3524,6 @@ func ChangeCommentReaction(ctx *context.Context) {
log.Info("CreateCommentReaction: %s", err)
break
}
- // Reload new reactions
- comment.Reactions = nil
- if err = comment.LoadReactions(ctx, ctx.Repo.Repository); err != nil {
- log.Info("comment.LoadReactions: %s", err)
- break
- }
log.Trace("Reaction for comment created: %d/%d/%d/%d", ctx.Repo.Repository.ID, comment.Issue.ID, comment.ID, reaction.ID)
case "unreact":
@@ -3420,19 +3532,19 @@ func ChangeCommentReaction(ctx *context.Context) {
return
}
- // Reload new reactions
- comment.Reactions = nil
- if err = comment.LoadReactions(ctx, ctx.Repo.Repository); err != nil {
- log.Info("comment.LoadReactions: %s", err)
- break
- }
-
log.Trace("Reaction for comment removed: %d/%d/%d", ctx.Repo.Repository.ID, comment.Issue.ID, comment.ID)
default:
ctx.NotFound(fmt.Sprintf("Unknown action %s", ctx.Params(":action")), nil)
return
}
+ // Reload new reactions
+ comment.Reactions = nil
+ if err = comment.LoadReactions(ctx, ctx.Repo.Repository); err != nil {
+ ctx.ServerError("ChangeCommentReaction.LoadReactions", err)
+ return
+ }
+
if len(comment.Reactions) == 0 {
ctx.JSON(http.StatusOK, map[string]any{
"empty": true,
@@ -3597,73 +3709,6 @@ func attachmentsHTML(ctx *context.Context, attachments []*repo_model.Attachment,
return attachHTML
}
-// combineLabelComments combine the nearby label comments as one.
-func combineLabelComments(issue *issues_model.Issue) {
- var prev, cur *issues_model.Comment
- for i := 0; i < len(issue.Comments); i++ {
- cur = issue.Comments[i]
- if i > 0 {
- prev = issue.Comments[i-1]
- }
- if i == 0 || cur.Type != issues_model.CommentTypeLabel ||
- (prev != nil && prev.PosterID != cur.PosterID) ||
- (prev != nil && cur.CreatedUnix-prev.CreatedUnix >= 60) {
- if cur.Type == issues_model.CommentTypeLabel && cur.Label != nil {
- if cur.Content != "1" {
- cur.RemovedLabels = append(cur.RemovedLabels, cur.Label)
- } else {
- cur.AddedLabels = append(cur.AddedLabels, cur.Label)
- }
- }
- continue
- }
-
- if cur.Label != nil { // now cur MUST be label comment
- if prev.Type == issues_model.CommentTypeLabel { // we can combine them only prev is a label comment
- if cur.Content != "1" {
- // remove labels from the AddedLabels list if the label that was removed is already
- // in this list, and if it's not in this list, add the label to RemovedLabels
- addedAndRemoved := false
- for i, label := range prev.AddedLabels {
- if cur.Label.ID == label.ID {
- prev.AddedLabels = append(prev.AddedLabels[:i], prev.AddedLabels[i+1:]...)
- addedAndRemoved = true
- break
- }
- }
- if !addedAndRemoved {
- prev.RemovedLabels = append(prev.RemovedLabels, cur.Label)
- }
- } else {
- // remove labels from the RemovedLabels list if the label that was added is already
- // in this list, and if it's not in this list, add the label to AddedLabels
- removedAndAdded := false
- for i, label := range prev.RemovedLabels {
- if cur.Label.ID == label.ID {
- prev.RemovedLabels = append(prev.RemovedLabels[:i], prev.RemovedLabels[i+1:]...)
- removedAndAdded = true
- break
- }
- }
- if !removedAndAdded {
- prev.AddedLabels = append(prev.AddedLabels, cur.Label)
- }
- }
- prev.CreatedUnix = cur.CreatedUnix
- // remove the current comment since it has been combined to prev comment
- issue.Comments = append(issue.Comments[:i], issue.Comments[i+1:]...)
- i--
- } else { // if prev is not a label comment, start a new group
- if cur.Content != "1" {
- cur.RemovedLabels = append(cur.RemovedLabels, cur.Label)
- } else {
- cur.AddedLabels = append(cur.AddedLabels, cur.Label)
- }
- }
- }
- }
-}
-
// get all teams that current user can mention
func handleTeamMentions(ctx *context.Context) {
if ctx.Doer == nil || !ctx.Repo.Owner.IsOrganization() {
diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go
index 31d2de6d53..5c71d75f80 100644
--- a/routers/web/repo/issue_content_history.go
+++ b/routers/web/repo/issue_content_history.go
@@ -9,13 +9,12 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/avatars"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/avatars"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/services/context"
"github.com/sergi/go-diff/diffmatchpatch"
)
@@ -73,10 +72,10 @@ func GetContentHistoryList(ctx *context.Context) {
class := avatars.DefaultAvatarClass + " tw-mr-2"
name := html.EscapeString(username)
avatarHTML := string(templates.AvatarHTML(src, 28, class, username))
- timeSinceText := string(timeutil.TimeSinceUnix(item.EditedUnix, ctx.Locale))
+ timeSinceHTML := string(templates.TimeSince(item.EditedUnix))
results = append(results, map[string]any{
- "name": avatarHTML + "" + name + " " + actionText + " " + timeSinceText,
+ "name": avatarHTML + "" + name + " " + actionText + " " + timeSinceHTML,
"value": item.HistoryID,
})
}
@@ -154,6 +153,7 @@ func GetContentHistoryDetail(ctx *context.Context) {
dmp := diffmatchpatch.New()
// `checklines=false` makes better diff result
diff := dmp.DiffMain(prevHistoryContentText, history.ContentText, false)
+ diff = dmp.DiffCleanupSemantic(diff)
diff = dmp.DiffCleanupEfficiency(diff)
// use chroma to render the diff html
diff --git a/routers/web/repo/issue_dependency.go b/routers/web/repo/issue_dependency.go
index 66b38688ec..3764a6bd7e 100644
--- a/routers/web/repo/issue_dependency.go
+++ b/routers/web/repo/issue_dependency.go
@@ -6,10 +6,10 @@ package repo
import (
"net/http"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
// AddDependency adds new dependencies
diff --git a/routers/web/repo/issue_label.go b/routers/web/repo/issue_label.go
index 81bee4dbb5..74674e9550 100644
--- a/routers/web/repo/issue_label.go
+++ b/routers/web/repo/issue_label.go
@@ -6,17 +6,17 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/label"
- "code.gitea.io/gitea/modules/log"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- issue_service "code.gitea.io/gitea/services/issue"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/label"
+ "forgejo.org/modules/log"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ issue_service "forgejo.org/services/issue"
)
const (
diff --git a/routers/web/repo/issue_label_test.go b/routers/web/repo/issue_label_test.go
index 93fc72300b..406ab4918c 100644
--- a/routers/web/repo/issue_label_test.go
+++ b/routers/web/repo/issue_label_test.go
@@ -8,15 +8,16 @@ import (
"strconv"
"testing"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/test"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/contexttest"
- "code.gitea.io/gitea/services/forms"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/repository"
+ "forgejo.org/modules/test"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/contexttest"
+ "forgejo.org/services/forms"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func int64SliceToCommaSeparated(a []int64) string {
@@ -32,7 +33,7 @@ func int64SliceToCommaSeparated(a []int64) string {
func TestInitializeLabels(t *testing.T) {
unittest.PrepareTestEnv(t)
- assert.NoError(t, repository.LoadRepoConfig())
+ require.NoError(t, repository.LoadRepoConfig())
ctx, _ := contexttest.MockContext(t, "user2/repo1/labels/initialize")
contexttest.LoadUser(t, ctx, 2)
contexttest.LoadRepo(t, ctx, 2)
diff --git a/routers/web/repo/issue_lock.go b/routers/web/repo/issue_lock.go
index 1d5fc8a5f3..dea67ab996 100644
--- a/routers/web/repo/issue_lock.go
+++ b/routers/web/repo/issue_lock.go
@@ -4,10 +4,10 @@
package repo
import (
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
// LockIssue locks an issue. This would limit commenting abilities to
diff --git a/routers/web/repo/issue_pin.go b/routers/web/repo/issue_pin.go
index 365c812681..5e2075a17f 100644
--- a/routers/web/repo/issue_pin.go
+++ b/routers/web/repo/issue_pin.go
@@ -6,10 +6,10 @@ package repo
import (
"net/http"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/context"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/context"
)
// IssuePinOrUnpin pin or unpin a Issue
diff --git a/routers/web/repo/issue_stopwatch.go b/routers/web/repo/issue_stopwatch.go
index 70d42b27c0..5bc49464dd 100644
--- a/routers/web/repo/issue_stopwatch.go
+++ b/routers/web/repo/issue_stopwatch.go
@@ -7,10 +7,10 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/eventsource"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/eventsource"
+ "forgejo.org/services/context"
)
// IssueStopwatch creates or stops a stopwatch for the given issue.
diff --git a/routers/web/repo/issue_test.go b/routers/web/repo/issue_test.go
deleted file mode 100644
index f1d0aac72f..0000000000
--- a/routers/web/repo/issue_test.go
+++ /dev/null
@@ -1,375 +0,0 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package repo
-
-import (
- "testing"
-
- issues_model "code.gitea.io/gitea/models/issues"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestCombineLabelComments(t *testing.T) {
- kases := []struct {
- name string
- beforeCombined []*issues_model.Comment
- afterCombined []*issues_model.Comment
- }{
- {
- name: "kase 1",
- beforeCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeComment,
- PosterID: 1,
- Content: "test",
- CreatedUnix: 0,
- },
- },
- afterCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- CreatedUnix: 0,
- AddedLabels: []*issues_model.Label{},
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- },
- {
- Type: issues_model.CommentTypeComment,
- PosterID: 1,
- Content: "test",
- CreatedUnix: 0,
- },
- },
- },
- {
- name: "kase 2",
- beforeCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 70,
- },
- {
- Type: issues_model.CommentTypeComment,
- PosterID: 1,
- Content: "test",
- CreatedUnix: 0,
- },
- },
- afterCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- CreatedUnix: 0,
- AddedLabels: []*issues_model.Label{
- {
- Name: "kind/bug",
- },
- },
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "",
- CreatedUnix: 70,
- RemovedLabels: []*issues_model.Label{
- {
- Name: "kind/bug",
- },
- },
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- },
- {
- Type: issues_model.CommentTypeComment,
- PosterID: 1,
- Content: "test",
- CreatedUnix: 0,
- },
- },
- },
- {
- name: "kase 3",
- beforeCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 2,
- Content: "",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeComment,
- PosterID: 1,
- Content: "test",
- CreatedUnix: 0,
- },
- },
- afterCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- CreatedUnix: 0,
- AddedLabels: []*issues_model.Label{
- {
- Name: "kind/bug",
- },
- },
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 2,
- Content: "",
- CreatedUnix: 0,
- RemovedLabels: []*issues_model.Label{
- {
- Name: "kind/bug",
- },
- },
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- },
- {
- Type: issues_model.CommentTypeComment,
- PosterID: 1,
- Content: "test",
- CreatedUnix: 0,
- },
- },
- },
- {
- name: "kase 4",
- beforeCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/backport",
- },
- CreatedUnix: 10,
- },
- },
- afterCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- CreatedUnix: 10,
- AddedLabels: []*issues_model.Label{
- {
- Name: "kind/bug",
- },
- {
- Name: "kind/backport",
- },
- },
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- },
- },
- },
- {
- name: "kase 5",
- beforeCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeComment,
- PosterID: 2,
- Content: "testtest",
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- },
- afterCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- AddedLabels: []*issues_model.Label{
- {
- Name: "kind/bug",
- },
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeComment,
- PosterID: 2,
- Content: "testtest",
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "",
- RemovedLabels: []*issues_model.Label{
- {
- Name: "kind/bug",
- },
- },
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- },
- },
- {
- name: "kase 6",
- beforeCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "reviewed/confirmed",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- CreatedUnix: 0,
- },
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/feature",
- },
- CreatedUnix: 0,
- },
- },
- afterCombined: []*issues_model.Comment{
- {
- Type: issues_model.CommentTypeLabel,
- PosterID: 1,
- Content: "1",
- Label: &issues_model.Label{
- Name: "kind/bug",
- },
- AddedLabels: []*issues_model.Label{
- {
- Name: "reviewed/confirmed",
- },
- {
- Name: "kind/feature",
- },
- },
- CreatedUnix: 0,
- },
- },
- },
- }
-
- for _, kase := range kases {
- t.Run(kase.name, func(t *testing.T) {
- issue := issues_model.Issue{
- Comments: kase.beforeCombined,
- }
- combineLabelComments(&issue)
- assert.EqualValues(t, kase.afterCombined, issue.Comments)
- })
- }
-}
diff --git a/routers/web/repo/issue_timetrack.go b/routers/web/repo/issue_timetrack.go
index 241e434049..e63f7e2dc2 100644
--- a/routers/web/repo/issue_timetrack.go
+++ b/routers/web/repo/issue_timetrack.go
@@ -7,12 +7,12 @@ import (
"net/http"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
// AddTimeManually tracks time manually
diff --git a/routers/web/repo/issue_watch.go b/routers/web/repo/issue_watch.go
index 5cff9f4ddd..5af223f865 100644
--- a/routers/web/repo/issue_watch.go
+++ b/routers/web/repo/issue_watch.go
@@ -7,10 +7,10 @@ import (
"net/http"
"strconv"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/context"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/repo/main_test.go b/routers/web/repo/main_test.go
index 6e469cf2ed..8b30ad41ed 100644
--- a/routers/web/repo/main_test.go
+++ b/routers/web/repo/main_test.go
@@ -6,7 +6,7 @@ package repo
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/repo/middlewares.go b/routers/web/repo/middlewares.go
index ddda9f3ff2..9aba447433 100644
--- a/routers/web/repo/middlewares.go
+++ b/routers/web/repo/middlewares.go
@@ -7,12 +7,12 @@ import (
"fmt"
"strconv"
- system_model "code.gitea.io/gitea/models/system"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/services/context"
- user_service "code.gitea.io/gitea/services/user"
+ system_model "forgejo.org/models/system"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/optional"
+ "forgejo.org/services/context"
+ user_service "forgejo.org/services/user"
)
// SetEditorconfigIfExists set editor config as render variable
diff --git a/routers/web/repo/migrate.go b/routers/web/repo/migrate.go
index 97b0c425ea..86d2461e94 100644
--- a/routers/web/repo/migrate.go
+++ b/routers/web/repo/migrate.go
@@ -9,22 +9,23 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/models"
- admin_model "code.gitea.io/gitea/models/admin"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/migrations"
- "code.gitea.io/gitea/services/task"
+ "forgejo.org/models"
+ admin_model "forgejo.org/models/admin"
+ "forgejo.org/models/db"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/migrations"
+ "forgejo.org/services/task"
)
const (
@@ -170,6 +171,10 @@ func MigratePost(ctx *context.Context) {
tpl := base.TplName("repo/migrate/" + form.Service.Name())
+ if !ctx.CheckQuota(quota_model.LimitSubjectSizeReposAll, ctxUser.ID, ctxUser.Name) {
+ return
+ }
+
if ctx.HasError() {
ctx.HTML(http.StatusOK, tpl)
return
@@ -248,7 +253,7 @@ func MigratePost(ctx *context.Context) {
}
func setMigrationContextData(ctx *context.Context, serviceType structs.GitServiceType) {
- ctx.Data["Title"] = ctx.Tr("new_migrate")
+ ctx.Data["Title"] = ctx.Tr("new_migrate.title")
ctx.Data["LFSActive"] = setting.LFS.StartServer
ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate
@@ -260,6 +265,25 @@ func setMigrationContextData(ctx *context.Context, serviceType structs.GitServic
}
func MigrateRetryPost(ctx *context.Context) {
+ ok, err := quota_model.EvaluateForUser(ctx, ctx.Repo.Repository.OwnerID, quota_model.LimitSubjectSizeReposAll)
+ if err != nil {
+ log.Error("quota_model.EvaluateForUser: %v", err)
+ ctx.ServerError("quota_model.EvaluateForUser", err)
+ return
+ }
+ if !ok {
+ if err := task.SetMigrateTaskMessage(ctx, ctx.Repo.Repository.ID, ctx.Locale.TrString("repo.settings.pull_mirror_sync_quota_exceeded")); err != nil {
+ log.Error("SetMigrateTaskMessage failed: %v", err)
+ ctx.ServerError("task.SetMigrateTaskMessage", err)
+ return
+ }
+ ctx.JSON(http.StatusRequestEntityTooLarge, map[string]any{
+ "ok": false,
+ "error": ctx.Tr("repo.settings.pull_mirror_sync_quota_exceeded"),
+ })
+ return
+ }
+
if err := task.RetryMigrateTask(ctx, ctx.Repo.Repository.ID); err != nil {
log.Error("Retry task failed: %v", err)
ctx.ServerError("task.RetryMigrateTask", err)
diff --git a/routers/web/repo/milestone.go b/routers/web/repo/milestone.go
index 1c53f73fdb..920a9ee12a 100644
--- a/routers/web/repo/milestone.go
+++ b/routers/web/repo/milestone.go
@@ -9,18 +9,18 @@ import (
"net/url"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/issue"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/issue"
"xorm.io/builder"
)
diff --git a/routers/web/repo/packages.go b/routers/web/repo/packages.go
index 11874ab0d0..c947fb99bf 100644
--- a/routers/web/repo/packages.go
+++ b/routers/web/repo/packages.go
@@ -6,13 +6,13 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ "forgejo.org/models/packages"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/repo/patch.go b/routers/web/repo/patch.go
index d234f6c964..688ef19375 100644
--- a/routers/web/repo/patch.go
+++ b/routers/web/repo/patch.go
@@ -6,16 +6,16 @@ package repo
import (
"strings"
- "code.gitea.io/gitea/models"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/repository/files"
+ "forgejo.org/models"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/repository/files"
)
const (
diff --git a/routers/web/repo/projects.go b/routers/web/repo/projects.go
index 878b7ee699..80f699787c 100644
--- a/routers/web/repo/projects.go
+++ b/routers/web/repo/projects.go
@@ -9,22 +9,22 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/perm"
- project_model "code.gitea.io/gitea/models/project"
- attachment_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/perm"
+ project_model "forgejo.org/models/project"
+ attachment_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
const (
@@ -125,6 +125,19 @@ func Projects(ctx *context.Context) {
ctx.Data["IsProjectsPage"] = true
ctx.Data["SortType"] = sortType
+ numOpenIssues, err := issues_model.NumIssuesInProjects(ctx, projects, ctx.Doer, ctx.Org.Organization, optional.Some(false))
+ if err != nil {
+ ctx.ServerError("NumIssuesInProjects", err)
+ return
+ }
+ numClosedIssues, err := issues_model.NumIssuesInProjects(ctx, projects, ctx.Doer, ctx.Org.Organization, optional.Some(true))
+ if err != nil {
+ ctx.ServerError("NumIssuesInProjects", err)
+ return
+ }
+ ctx.Data["NumOpenIssuesInProject"] = numOpenIssues
+ ctx.Data["NumClosedIssuesInProject"] = numClosedIssues
+
ctx.HTML(http.StatusOK, tplProjects)
}
@@ -183,7 +196,7 @@ func ChangeProjectStatus(ctx *context.Context) {
ctx.NotFoundOrServerError("ChangeProjectStatusByRepoIDAndID", project_model.IsErrProjectNotExist, err)
return
}
- ctx.JSONRedirect(fmt.Sprintf("%s/projects/%d", ctx.Repo.RepoLink, id))
+ ctx.JSONRedirect(project_model.ProjectLinkForRepo(ctx.Repo.Repository, id))
}
// DeleteProject delete a project
@@ -237,7 +250,7 @@ func RenderEditProject(ctx *context.Context) {
ctx.Data["content"] = p.Description
ctx.Data["card_type"] = p.CardType
ctx.Data["redirect"] = ctx.FormString("redirect")
- ctx.Data["CancelLink"] = fmt.Sprintf("%s/projects/%d", ctx.Repo.Repository.Link(), p.ID)
+ ctx.Data["CancelLink"] = project_model.ProjectLinkForRepo(ctx.Repo.Repository, p.ID)
ctx.HTML(http.StatusOK, tplProjectsNew)
}
@@ -251,7 +264,7 @@ func EditProjectPost(ctx *context.Context) {
ctx.Data["PageIsEditProjects"] = true
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["CardTypes"] = project_model.GetCardConfig()
- ctx.Data["CancelLink"] = fmt.Sprintf("%s/projects/%d", ctx.Repo.Repository.Link(), projectID)
+ ctx.Data["CancelLink"] = project_model.ProjectLinkForRepo(ctx.Repo.Repository, projectID)
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplProjectsNew)
@@ -310,7 +323,7 @@ func ViewProject(ctx *context.Context) {
return
}
- issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns)
+ issuesMap, err := issues_model.LoadIssuesFromColumnList(ctx, columns, ctx.Doer, nil, optional.None[bool]())
if err != nil {
ctx.ServerError("LoadIssuesOfColumns", err)
return
@@ -363,6 +376,7 @@ func ViewProject(ctx *context.Context) {
return
}
+ ctx.Data["Title"] = project.Title
ctx.Data["IsProjectsPage"] = true
ctx.Data["CanWriteProjects"] = ctx.Repo.Permission.CanWrite(unit.TypeProjects)
ctx.Data["Project"] = project
diff --git a/routers/web/repo/projects_test.go b/routers/web/repo/projects_test.go
index d61230a57e..bc8b747980 100644
--- a/routers/web/repo/projects_test.go
+++ b/routers/web/repo/projects_test.go
@@ -6,8 +6,8 @@ package repo
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/services/contexttest"
+ "forgejo.org/models/unittest"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
)
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index be6511afaa..6ba1bca181 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -14,40 +14,40 @@ import (
"net/url"
"strconv"
"strings"
- "time"
- "code.gitea.io/gitea/models"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- pull_model "code.gitea.io/gitea/models/pull"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/emoji"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- issue_template "code.gitea.io/gitea/modules/issue/template"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/utils"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/automerge"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/gitdiff"
- notify_service "code.gitea.io/gitea/services/notify"
- pull_service "code.gitea.io/gitea/services/pull"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ pull_model "forgejo.org/models/pull"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/emoji"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ issue_template "forgejo.org/modules/issue/template"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/utils"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/automerge"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/gitdiff"
+ notify_service "forgejo.org/services/notify"
+ pull_service "forgejo.org/services/pull"
+ repo_service "forgejo.org/services/repository"
"github.com/gobwas/glob"
)
@@ -250,6 +250,10 @@ func ForkPost(ctx *context.Context) {
ctx.Data["ContextUser"] = ctxUser
+ if !ctx.CheckQuota(quota_model.LimitSubjectSizeReposAll, ctxUser.ID, ctxUser.Name) {
+ return
+ }
+
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplFork)
return
@@ -289,7 +293,7 @@ func ForkPost(ctx *context.Context) {
}
}
- repo, err := repo_service.ForkRepository(ctx, ctx.Doer, ctxUser, repo_service.ForkRepoOptions{
+ repo, err := repo_service.ForkRepositoryAndUpdates(ctx, ctx.Doer, ctxUser, repo_service.ForkRepoOptions{
BaseRepo: forkRepo,
Name: form.RepoName,
Description: form.Description,
@@ -510,6 +514,10 @@ func PrepareMergedViewPullInfo(ctx *context.Context, issue *issues_model.Issue)
ctx.ServerError("GetLatestCommitStatus", err)
return nil
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses)
+ }
+
if len(commitStatuses) != 0 {
ctx.Data["LatestCommitStatuses"] = commitStatuses
ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses)
@@ -572,6 +580,10 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.ServerError("GetLatestCommitStatus", err)
return nil
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses)
+ }
+
if len(commitStatuses) > 0 {
ctx.Data["LatestCommitStatuses"] = commitStatuses
ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses)
@@ -601,12 +613,12 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
var headBranchSha string
// HeadRepo may be missing
if pull.HeadRepo != nil {
- headGitRepo, err := gitrepo.OpenRepository(ctx, pull.HeadRepo)
+ headGitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, pull.HeadRepo)
if err != nil {
- ctx.ServerError("OpenRepository", err)
+ ctx.ServerError("RepositoryFromContextOrOpen", err)
return nil
}
- defer headGitRepo.Close()
+ defer closer.Close()
if pull.Flow == issues_model.PullRequestFlowGithub {
headBranchExist = headGitRepo.IsBranchExist(pull.HeadBranch)
@@ -664,6 +676,10 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.ServerError("GetLatestCommitStatus", err)
return nil
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses)
+ }
+
if len(commitStatuses) > 0 {
ctx.Data["LatestCommitStatuses"] = commitStatuses
ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(commitStatuses)
@@ -710,7 +726,7 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
ctx.Data["HeadBranchCommitID"] = headBranchSha
ctx.Data["PullHeadCommitID"] = sha
- if pull.HeadRepo == nil || !headBranchExist || (!pull.Issue.IsClosed && (headBranchSha != sha)) {
+ if pull.HeadRepo == nil || !headBranchExist || (!pull.Issue.IsClosed && !pull.IsChecking() && (headBranchSha != sha)) {
ctx.Data["IsPullRequestBroken"] = true
if pull.IsSameRepo() {
ctx.Data["HeadTarget"] = pull.HeadBranch
@@ -830,7 +846,7 @@ func ViewPullCommits(ctx *context.Context) {
ctx.Data["Username"] = ctx.Repo.Owner.Name
ctx.Data["Reponame"] = ctx.Repo.Repository.Name
- commits := git_model.ConvertFromGitCommit(ctx, prInfo.Commits, ctx.Repo.Repository)
+ commits := processGitCommits(ctx, prInfo.Commits)
ctx.Data["Commits"] = commits
ctx.Data["CommitCount"] = len(commits)
@@ -949,6 +965,7 @@ func viewPullFiles(ctx *context.Context, specifiedStartCommit, specifiedEndCommi
MaxLineCharacters: setting.Git.MaxGitDiffLineCharacters,
MaxFiles: maxFiles,
WhitespaceBehavior: gitdiff.GetWhitespaceFlag(ctx.Data["WhitespaceBehavior"].(string)),
+ FileOnly: fileOnly,
}
if !willShowSpecifiedCommit {
@@ -1189,8 +1206,6 @@ func UpdatePullRequest(ctx *context.Context) {
return
}
- time.Sleep(1 * time.Second)
-
ctx.Flash.Success(ctx.Tr("repo.pulls.update_branch_success"))
ctx.Redirect(issue.Link())
}
@@ -1285,7 +1300,7 @@ func MergePullRequest(ctx *context.Context) {
// delete all scheduled auto merges
_ = pull_model.DeleteScheduledAutoMerge(ctx, pr.ID)
// schedule auto merge
- scheduled, err := automerge.ScheduleAutoMerge(ctx, ctx.Doer, pr, repo_model.MergeStyle(form.Do), message)
+ scheduled, err := automerge.ScheduleAutoMerge(ctx, ctx.Doer, pr, repo_model.MergeStyle(form.Do), message, form.DeleteBranchAfterMerge)
if err != nil {
ctx.ServerError("ScheduleAutoMerge", err)
return
@@ -1372,21 +1387,11 @@ func MergePullRequest(ctx *context.Context) {
log.Trace("Pull request merged: %d", pr.ID)
if form.DeleteBranchAfterMerge {
- // Don't cleanup when other pr use this branch as head branch
- exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(ctx, pr.HeadRepoID, pr.HeadBranch)
- if err != nil {
- ctx.ServerError("HasUnmergedPullRequestsByHeadInfo", err)
- return
- }
- if exist {
- ctx.JSONRedirect(issue.Link())
- return
- }
-
var headRepo *git.Repository
if ctx.Repo != nil && ctx.Repo.Repository != nil && pr.HeadRepoID == ctx.Repo.Repository.ID && ctx.Repo.GitRepo != nil {
headRepo = ctx.Repo.GitRepo
} else {
+ var err error
headRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo)
if err != nil {
ctx.ServerError(fmt.Sprintf("OpenRepository[%s]", pr.HeadRepo.FullName()), err)
@@ -1394,7 +1399,22 @@ func MergePullRequest(ctx *context.Context) {
}
defer headRepo.Close()
}
- deleteBranch(ctx, pr, headRepo)
+
+ if err := repo_service.DeleteBranchAfterMerge(ctx, ctx.Doer, pr, headRepo); err != nil {
+ switch {
+ case errors.Is(err, repo_service.ErrBranchIsDefault):
+ ctx.Flash.Error(ctx.Tr("repo.pulls.delete_after_merge.head_branch.is_default"))
+ case errors.Is(err, git_model.ErrBranchIsProtected):
+ ctx.Flash.Error(ctx.Tr("repo.pulls.delete_after_merge.head_branch.is_protected"))
+ case errors.Is(err, util.ErrPermissionDenied):
+ ctx.Flash.Error(ctx.Tr("repo.pulls.delete_after_merge.head_branch.insufficient_branch"))
+ default:
+ ctx.ServerError("DeleteBranchAfterMerge", err)
+ }
+
+ ctx.JSONRedirect(issue.Link())
+ return
+ }
}
ctx.JSONRedirect(issue.Link())
@@ -1507,14 +1527,12 @@ func CompareAndPullRequestPost(ctx *context.Context) {
// instead of 500.
if err := pull_service.NewPullRequest(ctx, repo, pullIssue, labelIDs, attachments, pullRequest, assigneeIDs); err != nil {
- if errors.Is(err, user_model.ErrBlockedByUser) {
- ctx.Flash.Error(ctx.Tr("repo.pulls.blocked_by_user"))
- ctx.Redirect(ctx.Link)
- return
- } else if repo_model.IsErrUserDoesNotHaveAccessToRepo(err) {
+ switch {
+ case errors.Is(err, user_model.ErrBlockedByUser):
+ ctx.JSONError(ctx.Tr("repo.pulls.blocked_by_user"))
+ case repo_model.IsErrUserDoesNotHaveAccessToRepo(err):
ctx.Error(http.StatusBadRequest, "UserDoesNotHaveAccessToRepo", err.Error())
- return
- } else if git.IsErrPushRejected(err) {
+ case git.IsErrPushRejected(err):
pushrejErr := err.(*git.ErrPushRejected)
message := pushrejErr.Message
if len(message) == 0 {
@@ -1531,7 +1549,11 @@ func CompareAndPullRequestPost(ctx *context.Context) {
return
}
ctx.JSONError(flashError)
- return
+ default:
+ // It's an unexpected error.
+ // If it happens, we should add another case to handle it.
+ log.Error("Unexpected error of NewPullRequest: %T %s", err, err)
+ ctx.ServerError("CompareAndPullRequest", err)
}
ctx.ServerError("NewPullRequest", err)
return
@@ -1805,7 +1827,7 @@ func SetAllowEdits(ctx *context.Context) {
}
if err := pull_service.SetAllowEdits(ctx, ctx.Doer, pr, form.AllowMaintainerEdit); err != nil {
- if errors.Is(pull_service.ErrUserHasNoPermissionForAction, err) {
+ if errors.Is(err, pull_service.ErrUserHasNoPermissionForAction) {
ctx.Error(http.StatusForbidden)
return
}
diff --git a/routers/web/repo/pull_review.go b/routers/web/repo/pull_review.go
index 24763668d0..18a5b872f1 100644
--- a/routers/web/repo/pull_review.go
+++ b/routers/web/repo/pull_review.go
@@ -8,17 +8,17 @@ import (
"fmt"
"net/http"
- issues_model "code.gitea.io/gitea/models/issues"
- pull_model "code.gitea.io/gitea/models/pull"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- "code.gitea.io/gitea/services/forms"
- pull_service "code.gitea.io/gitea/services/pull"
+ issues_model "forgejo.org/models/issues"
+ pull_model "forgejo.org/models/pull"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ "forgejo.org/services/forms"
+ pull_service "forgejo.org/services/pull"
)
const (
@@ -82,6 +82,24 @@ func CreateCodeComment(ctx *context.Context) {
attachments = form.Files
}
+ // If the reply is made to a comment that is part of a pending review, then
+ // this comment also should be seen as part of that pending review. Consider
+ // it to be a pending review by default, except when `single_review` was
+ // passed.
+ pendingReview := !form.SingleReview
+ if form.Reply > 0 {
+ r, err := issues_model.GetReviewByID(ctx, form.Reply)
+ if err != nil {
+ ctx.ServerError("GetReviewByID", err)
+ return
+ }
+ if r.IssueID != issue.ID {
+ ctx.NotFound("Review does not belong to pull request", nil)
+ return
+ }
+ pendingReview = r.Type == issues_model.ReviewTypePending
+ }
+
comment, err := pull_service.CreateCodeComment(ctx,
ctx.Doer,
ctx.Repo.GitRepo,
@@ -89,7 +107,7 @@ func CreateCodeComment(ctx *context.Context) {
signedLine,
form.Content,
form.TreePath,
- !form.SingleReview,
+ pendingReview,
form.Reply,
form.LatestCommitID,
attachments,
@@ -248,8 +266,6 @@ func SubmitReview(ctx *context.Context) {
if issues_model.IsContentEmptyErr(err) {
ctx.Flash.Error(ctx.Tr("repo.issues.review.content.empty"))
ctx.JSONRedirect(fmt.Sprintf("%s/pulls/%d/files", ctx.Repo.RepoLink, issue.Index))
- } else if errors.Is(err, pull_service.ErrSubmitReviewOnClosedPR) {
- ctx.Status(http.StatusUnprocessableEntity)
} else {
ctx.ServerError("SubmitReview", err)
}
diff --git a/routers/web/repo/pull_review_test.go b/routers/web/repo/pull_review_test.go
index 70f6a0e055..14e6714a63 100644
--- a/routers/web/repo/pull_review_test.go
+++ b/routers/web/repo/pull_review_test.go
@@ -8,15 +8,16 @@ import (
"net/http/httptest"
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/contexttest"
- "code.gitea.io/gitea/services/pull"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/templates"
+ "forgejo.org/services/context"
+ "forgejo.org/services/contexttest"
+ "forgejo.org/services/pull"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRenderConversation(t *testing.T) {
@@ -42,14 +43,12 @@ func TestRenderConversation(t *testing.T) {
var preparedComment *issues_model.Comment
run("prepare", func(t *testing.T, ctx *context.Context, resp *httptest.ResponseRecorder) {
comment, err := pull.CreateCodeComment(ctx, pr.Issue.Poster, ctx.Repo.GitRepo, pr.Issue, 1, "content", "", false, 0, pr.HeadCommitID, nil)
- if !assert.NoError(t, err) {
- return
- }
+ require.NoError(t, err)
+
comment.Invalidated = true
err = issues_model.UpdateCommentInvalidate(ctx, comment)
- if !assert.NoError(t, err) {
- return
- }
+ require.NoError(t, err)
+
preparedComment = comment
})
if !assert.NotNil(t, preparedComment) {
@@ -80,9 +79,9 @@ func TestRenderConversation(t *testing.T) {
reviews, err := issues_model.FindReviews(db.DefaultContext, issues_model.FindReviewOptions{
IssueID: 2,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, r := range reviews {
- assert.NoError(t, issues_model.DeleteReview(db.DefaultContext, r))
+ require.NoError(t, issues_model.DeleteReview(db.DefaultContext, r))
}
ctx.Data["ShowOutdatedComments"] = true
renderConversation(ctx, preparedComment, "diff")
@@ -93,9 +92,9 @@ func TestRenderConversation(t *testing.T) {
reviews, err := issues_model.FindReviews(db.DefaultContext, issues_model.FindReviewOptions{
IssueID: 2,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, r := range reviews {
- assert.NoError(t, issues_model.DeleteReview(db.DefaultContext, r))
+ require.NoError(t, issues_model.DeleteReview(db.DefaultContext, r))
}
ctx.Data["ShowOutdatedComments"] = true
renderConversation(ctx, preparedComment, "timeline")
diff --git a/routers/web/repo/recent_commits.go b/routers/web/repo/recent_commits.go
index c158fb30b6..6154de7377 100644
--- a/routers/web/repo/recent_commits.go
+++ b/routers/web/repo/recent_commits.go
@@ -7,9 +7,9 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/services/context"
- contributors_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/modules/base"
+ "forgejo.org/services/context"
+ contributors_service "forgejo.org/services/repository"
)
const (
diff --git a/routers/web/repo/release.go b/routers/web/repo/release.go
index 3927e3d2d9..024dd7b62d 100644
--- a/routers/web/repo/release.go
+++ b/routers/web/repo/release.go
@@ -10,28 +10,29 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/web/feed"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/context/upload"
- "code.gitea.io/gitea/services/forms"
- releaseservice "code.gitea.io/gitea/services/release"
+ "forgejo.org/models"
+ "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/web/feed"
+ "forgejo.org/services/context"
+ "forgejo.org/services/context/upload"
+ "forgejo.org/services/forms"
+ releaseservice "forgejo.org/services/release"
)
const (
@@ -167,6 +168,10 @@ func Releases(ctx *context.Context) {
// Disable the showCreateNewBranch form in the dropdown on this page.
ctx.Data["CanCreateBranch"] = false
ctx.Data["HideBranchesInDropdown"] = true
+ ctx.Data["ShowReleaseSearch"] = true
+
+ keyword := ctx.FormTrim("q")
+ ctx.Data["Keyword"] = keyword
listOptions := db.ListOptions{
Page: ctx.FormInt("page"),
@@ -187,6 +192,7 @@ func Releases(ctx *context.Context) {
// only show draft releases for users who can write, read-only users shouldn't see draft releases.
IncludeDrafts: writeAccess,
RepoID: ctx.Repo.Repository.ID,
+ Keyword: keyword,
})
if err != nil {
ctx.ServerError("getReleaseInfos", err)
@@ -257,6 +263,10 @@ func TagsList(ctx *context.Context) {
ctx.Data["CanCreateBranch"] = false
ctx.Data["HideBranchesInDropdown"] = true
ctx.Data["CanCreateRelease"] = ctx.Repo.CanWrite(unit.TypeReleases) && !ctx.Repo.Repository.IsArchived
+ ctx.Data["ShowReleaseSearch"] = true
+
+ keyword := ctx.FormTrim("q")
+ ctx.Data["Keyword"] = keyword
listOptions := db.ListOptions{
Page: ctx.FormInt("page"),
@@ -277,6 +287,7 @@ func TagsList(ctx *context.Context) {
IncludeTags: true,
HasSha1: optional.Some(true),
RepoID: ctx.Repo.Repository.ID,
+ Keyword: keyword,
}
releases, err := db.Find[repo_model.Release](ctx, opts)
@@ -354,11 +365,7 @@ func SingleRelease(ctx *context.Context) {
addVerifyTagToContext(ctx)
ctx.Data["PageIsSingleTag"] = release.IsTag
- if release.IsTag {
- ctx.Data["Title"] = release.TagName
- } else {
- ctx.Data["Title"] = release.Title
- }
+ ctx.Data["Title"] = release.DisplayName()
err = release.LoadArchiveDownloadCount(ctx)
if err != nil {
@@ -367,6 +374,13 @@ func SingleRelease(ctx *context.Context) {
}
ctx.Data["Releases"] = releases
+
+ ctx.Data["OpenGraphTitle"] = fmt.Sprintf("%s - %s", release.DisplayName(), release.Repo.FullName())
+ ctx.Data["OpenGraphDescription"] = base.EllipsisString(release.Note, 300)
+ ctx.Data["OpenGraphURL"] = release.HTMLURL()
+ ctx.Data["OpenGraphImageURL"] = release.SummaryCardURL()
+ ctx.Data["OpenGraphImageAltText"] = ctx.Tr("repo.release.summary_card_alt", release.DisplayName(), release.Repo.FullName())
+
ctx.HTML(http.StatusOK, tplReleasesList)
}
@@ -491,9 +505,44 @@ func NewReleasePost(ctx *context.Context) {
return
}
- var attachmentUUIDs []string
+ attachmentChanges := make(container.Set[*releaseservice.AttachmentChange])
+ attachmentChangesByID := make(map[string]*releaseservice.AttachmentChange)
+
if setting.Attachment.Enabled {
- attachmentUUIDs = form.Files
+ for _, uuid := range form.Files {
+ attachmentChanges.Add(&releaseservice.AttachmentChange{
+ Action: "add",
+ Type: "attachment",
+ UUID: uuid,
+ })
+ }
+
+ const namePrefix = "attachment-new-name-"
+ const exturlPrefix = "attachment-new-exturl-"
+ for k, v := range ctx.Req.Form {
+ isNewName := strings.HasPrefix(k, namePrefix)
+ isNewExturl := strings.HasPrefix(k, exturlPrefix)
+ if isNewName || isNewExturl {
+ var id string
+ if isNewName {
+ id = k[len(namePrefix):]
+ } else if isNewExturl {
+ id = k[len(exturlPrefix):]
+ }
+ if _, ok := attachmentChangesByID[id]; !ok {
+ attachmentChangesByID[id] = &releaseservice.AttachmentChange{
+ Action: "add",
+ Type: "external",
+ }
+ attachmentChanges.Add(attachmentChangesByID[id])
+ }
+ if isNewName {
+ attachmentChangesByID[id].Name = v[0]
+ } else if isNewExturl {
+ attachmentChangesByID[id].ExternalURL = v[0]
+ }
+ }
+ }
}
rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, form.TagName)
@@ -553,7 +602,7 @@ func NewReleasePost(ctx *context.Context) {
IsTag: false,
}
- if err = releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, attachmentUUIDs, msg); err != nil {
+ if err = releaseservice.CreateRelease(ctx.Repo.GitRepo, rel, msg, attachmentChanges.Values()); err != nil {
ctx.Data["Err_TagName"] = true
switch {
case repo_model.IsErrReleaseAlreadyExist(err):
@@ -562,6 +611,8 @@ func NewReleasePost(ctx *context.Context) {
ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_invalid"), tplReleaseNew, &form)
case models.IsErrProtectedTagName(err):
ctx.RenderWithErr(ctx.Tr("repo.release.tag_name_protected"), tplReleaseNew, &form)
+ case repo_model.IsErrInvalidExternalURL(err):
+ ctx.RenderWithErr(ctx.Tr("repo.release.invalid_external_url", err.(repo_model.ErrInvalidExternalURL).ExternalURL), tplReleaseNew, &form)
default:
ctx.ServerError("CreateRelease", err)
}
@@ -583,9 +634,14 @@ func NewReleasePost(ctx *context.Context) {
rel.HideArchiveLinks = form.HideArchiveLinks
rel.IsTag = false
- if err = releaseservice.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, attachmentUUIDs, nil, nil, true); err != nil {
+ if err = releaseservice.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, true, attachmentChanges.Values()); err != nil {
ctx.Data["Err_TagName"] = true
- ctx.ServerError("UpdateRelease", err)
+ switch {
+ case repo_model.IsErrInvalidExternalURL(err):
+ ctx.RenderWithErr(ctx.Tr("repo.release.invalid_external_url", err.(repo_model.ErrInvalidExternalURL).ExternalURL), tplReleaseNew, &form)
+ default:
+ ctx.ServerError("UpdateRelease", err)
+ }
return
}
}
@@ -667,6 +723,15 @@ func EditReleasePost(ctx *context.Context) {
ctx.Data["prerelease"] = rel.IsPrerelease
ctx.Data["hide_archive_links"] = rel.HideArchiveLinks
+ rel.Repo = ctx.Repo.Repository
+ if err := rel.LoadAttributes(ctx); err != nil {
+ ctx.ServerError("LoadAttributes", err)
+ return
+ }
+ // TODO: If an error occurs, do not forget the attachment edits the user made
+ // when displaying the error message.
+ ctx.Data["attachments"] = rel.Attachments
+
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplReleaseNew)
return
@@ -674,15 +739,67 @@ func EditReleasePost(ctx *context.Context) {
const delPrefix = "attachment-del-"
const editPrefix = "attachment-edit-"
- var addAttachmentUUIDs, delAttachmentUUIDs []string
- editAttachments := make(map[string]string) // uuid -> new name
+ const newPrefix = "attachment-new-"
+ const namePrefix = "name-"
+ const exturlPrefix = "exturl-"
+ attachmentChanges := make(container.Set[*releaseservice.AttachmentChange])
+ attachmentChangesByID := make(map[string]*releaseservice.AttachmentChange)
+
if setting.Attachment.Enabled {
- addAttachmentUUIDs = form.Files
+ for _, uuid := range form.Files {
+ attachmentChanges.Add(&releaseservice.AttachmentChange{
+ Action: "add",
+ Type: "attachment",
+ UUID: uuid,
+ })
+ }
+
for k, v := range ctx.Req.Form {
if strings.HasPrefix(k, delPrefix) && v[0] == "true" {
- delAttachmentUUIDs = append(delAttachmentUUIDs, k[len(delPrefix):])
- } else if strings.HasPrefix(k, editPrefix) {
- editAttachments[k[len(editPrefix):]] = v[0]
+ attachmentChanges.Add(&releaseservice.AttachmentChange{
+ Action: "delete",
+ UUID: k[len(delPrefix):],
+ })
+ } else {
+ isUpdatedName := strings.HasPrefix(k, editPrefix+namePrefix)
+ isUpdatedExturl := strings.HasPrefix(k, editPrefix+exturlPrefix)
+ isNewName := strings.HasPrefix(k, newPrefix+namePrefix)
+ isNewExturl := strings.HasPrefix(k, newPrefix+exturlPrefix)
+
+ if isUpdatedName || isUpdatedExturl || isNewName || isNewExturl {
+ var uuid string
+
+ if isUpdatedName {
+ uuid = k[len(editPrefix+namePrefix):]
+ } else if isUpdatedExturl {
+ uuid = k[len(editPrefix+exturlPrefix):]
+ } else if isNewName {
+ uuid = k[len(newPrefix+namePrefix):]
+ } else if isNewExturl {
+ uuid = k[len(newPrefix+exturlPrefix):]
+ }
+
+ if _, ok := attachmentChangesByID[uuid]; !ok {
+ attachmentChangesByID[uuid] = &releaseservice.AttachmentChange{
+ Type: "attachment",
+ UUID: uuid,
+ }
+ attachmentChanges.Add(attachmentChangesByID[uuid])
+ }
+
+ if isUpdatedName || isUpdatedExturl {
+ attachmentChangesByID[uuid].Action = "update"
+ } else if isNewName || isNewExturl {
+ attachmentChangesByID[uuid].Action = "add"
+ }
+
+ if isUpdatedName || isNewName {
+ attachmentChangesByID[uuid].Name = v[0]
+ } else if isUpdatedExturl || isNewExturl {
+ attachmentChangesByID[uuid].ExternalURL = v[0]
+ attachmentChangesByID[uuid].Type = "external"
+ }
+ }
}
}
}
@@ -692,9 +809,13 @@ func EditReleasePost(ctx *context.Context) {
rel.IsDraft = len(form.Draft) > 0
rel.IsPrerelease = form.Prerelease
rel.HideArchiveLinks = form.HideArchiveLinks
- if err = releaseservice.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo,
- rel, addAttachmentUUIDs, delAttachmentUUIDs, editAttachments, false); err != nil {
- ctx.ServerError("UpdateRelease", err)
+ if err = releaseservice.UpdateRelease(ctx, ctx.Doer, ctx.Repo.GitRepo, rel, false, attachmentChanges.Values()); err != nil {
+ switch {
+ case repo_model.IsErrInvalidExternalURL(err):
+ ctx.RenderWithErr(ctx.Tr("repo.release.invalid_external_url", err.(repo_model.ErrInvalidExternalURL).ExternalURL), tplReleaseNew, &form)
+ default:
+ ctx.ServerError("UpdateRelease", err)
+ }
return
}
ctx.Redirect(ctx.Repo.RepoLink + "/releases")
diff --git a/routers/web/repo/release_test.go b/routers/web/repo/release_test.go
index 7ebea4c3fb..785b1fdf69 100644
--- a/routers/web/repo/release_test.go
+++ b/routers/web/repo/release_test.go
@@ -6,15 +6,16 @@ package repo
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/contexttest"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/contexttest"
+ "forgejo.org/services/forms"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestNewReleasePost(t *testing.T) {
@@ -79,12 +80,12 @@ func TestCalReleaseNumCommitsBehind(t *testing.T) {
IncludeDrafts: ctx.Repo.CanWrite(unit.TypeReleases),
RepoID: ctx.Repo.Repository.ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
countCache := make(map[string]int64)
for _, release := range releases {
err := calReleaseNumCommitsBehind(ctx.Repo, release, countCache)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
type computedFields struct {
diff --git a/routers/web/repo/render.go b/routers/web/repo/render.go
index e64db03e20..b31e2e203a 100644
--- a/routers/web/repo/render.go
+++ b/routers/web/repo/render.go
@@ -9,13 +9,13 @@ import (
"net/http"
"path"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/typesniffer"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/typesniffer"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
)
// RenderFile renders a file by repos path
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go
index 4d17be3758..53b3f34347 100644
--- a/routers/web/repo/repo.go
+++ b/routers/web/repo/repo.go
@@ -12,31 +12,32 @@ import (
"slices"
"strings"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/forms"
- repo_service "code.gitea.io/gitea/services/repository"
- archiver_service "code.gitea.io/gitea/services/repository/archiver"
- commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/forms"
+ repo_service "forgejo.org/services/repository"
+ archiver_service "forgejo.org/services/repository/archiver"
+ commitstatus_service "forgejo.org/services/repository/commitstatus"
)
const (
@@ -151,7 +152,7 @@ func getRepoPrivate(ctx *context.Context) bool {
// Create render creating repository page
func Create(ctx *context.Context) {
- ctx.Data["Title"] = ctx.Tr("new_repo")
+ ctx.Data["Title"] = ctx.Tr("new_repo.title")
// Give default value for template to render.
ctx.Data["Gitignores"] = repo_module.Gitignores
@@ -222,7 +223,7 @@ func handleCreateError(ctx *context.Context, owner *user_model.User, err error,
// CreatePost response for creating repository
func CreatePost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.CreateRepoForm)
- ctx.Data["Title"] = ctx.Tr("new_repo")
+ ctx.Data["Title"] = ctx.Tr("new_repo.title")
ctx.Data["Gitignores"] = repo_module.Gitignores
ctx.Data["LabelTemplateFiles"] = repo_module.LabelTemplateFiles
@@ -231,6 +232,8 @@ func CreatePost(ctx *context.Context) {
ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo()
ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit()
+ ctx.Data["SupportedObjectFormats"] = git.SupportedObjectFormats
+ ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat
ctxUser := checkContextUser(ctx, form.UID)
if ctx.Written() {
@@ -238,6 +241,10 @@ func CreatePost(ctx *context.Context) {
}
ctx.Data["ContextUser"] = ctxUser
+ if !ctx.CheckQuota(quota_model.LimitSubjectSizeReposAll, ctxUser.ID, ctxUser.Name) {
+ return
+ }
+
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplCreate)
return
@@ -361,49 +368,56 @@ func ActionTransfer(accept bool) func(ctx *context.Context) {
action = "reject_transfer"
}
- err := acceptOrRejectRepoTransfer(ctx, accept)
+ ok, err := acceptOrRejectRepoTransfer(ctx, accept)
if err != nil {
ctx.ServerError(fmt.Sprintf("Action (%s)", action), err)
return
}
+ if !ok {
+ return
+ }
ctx.RedirectToFirst(ctx.FormString("redirect_to"), ctx.Repo.RepoLink)
}
}
-func acceptOrRejectRepoTransfer(ctx *context.Context, accept bool) error {
+func acceptOrRejectRepoTransfer(ctx *context.Context, accept bool) (bool, error) {
repoTransfer, err := models.GetPendingRepositoryTransfer(ctx, ctx.Repo.Repository)
if err != nil {
- return err
+ return false, err
}
if err := repoTransfer.LoadAttributes(ctx); err != nil {
- return err
+ return false, err
}
if !repoTransfer.CanUserAcceptTransfer(ctx, ctx.Doer) {
- return errors.New("user does not have enough permissions")
+ return false, errors.New("user does not have enough permissions")
}
if accept {
+ if !ctx.CheckQuota(quota_model.LimitSubjectSizeReposAll, ctx.Doer.ID, ctx.Doer.Name) {
+ return false, nil
+ }
+
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
ctx.Repo.GitRepo = nil
}
if err := repo_service.TransferOwnership(ctx, repoTransfer.Doer, repoTransfer.Recipient, ctx.Repo.Repository, repoTransfer.Teams); err != nil {
- return err
+ return false, err
}
ctx.Flash.Success(ctx.Tr("repo.settings.transfer.success"))
} else {
if err := repo_service.CancelRepositoryTransfer(ctx, ctx.Repo.Repository); err != nil {
- return err
+ return false, err
}
ctx.Flash.Success(ctx.Tr("repo.settings.transfer.rejected"))
}
ctx.Redirect(ctx.Repo.Repository.Link())
- return nil
+ return true, nil
}
// RedirectDownload return a file based on the following infos:
@@ -458,7 +472,12 @@ func RedirectDownload(ctx *context.Context) {
// Download an archive of a repository
func Download(ctx *context.Context) {
uri := ctx.Params("*")
- aReq, err := archiver_service.NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
+ ext, tp, err := archiver_service.ParseFileName(uri)
+ if err != nil {
+ ctx.NotFound("ParseFileName", err)
+ return
+ }
+ aReq, err := archiver_service.NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp)
if err != nil {
if errors.Is(err, archiver_service.ErrUnknownArchiveFormat{}) {
ctx.Error(http.StatusBadRequest, err.Error())
@@ -491,7 +510,7 @@ func download(ctx *context.Context, archiveName string, archiver *repo_model.Rep
rPath := archiver.RelativePath()
if setting.RepoArchive.Storage.MinioConfig.ServeDirect {
// If we have a signed url (S3, object storage), redirect to this directly.
- u, err := storage.RepoArchives.URL(rPath, downloadName)
+ u, err := storage.RepoArchives.URL(rPath, downloadName, nil)
if u != nil && err == nil {
if archiver.ReleaseID != 0 {
err = repo_model.CountArchiveDownload(ctx, ctx.Repo.Repository.ID, archiver.ReleaseID, archiver.Type)
@@ -533,7 +552,12 @@ func download(ctx *context.Context, archiveName string, archiver *repo_model.Rep
// kind of drop it on the floor if this is the case.
func InitiateDownload(ctx *context.Context) {
uri := ctx.Params("*")
- aReq, err := archiver_service.NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, uri)
+ ext, tp, err := archiver_service.ParseFileName(uri)
+ if err != nil {
+ ctx.NotFound("ParseFileName", err)
+ return
+ }
+ aReq, err := archiver_service.NewRequest(ctx, ctx.Repo.Repository.ID, ctx.Repo.GitRepo, strings.TrimSuffix(uri, ext), tp)
if err != nil {
ctx.ServerError("archiver_service.NewRequest", err)
return
@@ -669,6 +693,9 @@ func SearchRepo(ctx *context.Context) {
ctx.JSON(http.StatusInternalServerError, nil)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, latestCommitStatuses)
+ }
results := make([]*repo_service.WebSearchRepository, len(repos))
for i, repo := range repos {
diff --git a/routers/web/repo/search.go b/routers/web/repo/search.go
index be03c7bded..1671378a3b 100644
--- a/routers/web/repo/search.go
+++ b/routers/web/repo/search.go
@@ -7,27 +7,90 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- code_indexer "code.gitea.io/gitea/modules/indexer/code"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ code_indexer "forgejo.org/modules/indexer/code"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
const tplSearch base.TplName = "repo/search"
+type searchMode int
+
+const (
+ ExactSearchMode searchMode = iota
+ UnionSearchMode
+ RegExpSearchMode
+)
+
+func searchModeFromString(s string) searchMode {
+ switch s {
+ case "fuzzy", "union":
+ return UnionSearchMode
+ case "regexp":
+ return RegExpSearchMode
+ default:
+ return ExactSearchMode
+ }
+}
+
+func (m searchMode) String() string {
+ switch m {
+ case ExactSearchMode:
+ return "exact"
+ case UnionSearchMode:
+ return "union"
+ case RegExpSearchMode:
+ return "regexp"
+ default:
+ panic("cannot happen")
+ }
+}
+
+func (m searchMode) ToIndexer() code_indexer.SearchMode {
+ if m == ExactSearchMode {
+ return code_indexer.SearchModeExact
+ }
+ return code_indexer.SearchModeUnion
+}
+
+func (m searchMode) ToGitGrep() git.GrepMode {
+ switch m {
+ case RegExpSearchMode:
+ return git.RegExpGrepMode
+ case UnionSearchMode:
+ return git.FixedAnyGrepMode
+ default:
+ return git.FixedGrepMode
+ }
+}
+
// Search render repository search page
func Search(ctx *context.Context) {
language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q")
- isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true)
+ path := ctx.FormTrim("path")
+ mode := ExactSearchMode
+ if modeStr := ctx.FormString("mode"); len(modeStr) > 0 {
+ mode = searchModeFromString(modeStr)
+ } else if ctx.FormOptionalBool("fuzzy").ValueOrDefault(true) { // for backward compatibility in links
+ mode = UnionSearchMode
+ }
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
- ctx.Data["IsFuzzy"] = isFuzzy
+ ctx.Data["CodeSearchPath"] = path
+ ctx.Data["CodeSearchMode"] = mode.String()
ctx.Data["PageIsViewCode"] = true
+ ctx.Data["CodeIndexerDisabled"] = !setting.Indexer.RepoIndexerEnabled
+ if setting.Indexer.RepoIndexerEnabled {
+ ctx.Data["CodeSearchOptions"] = code_indexer.CodeSearchOptions
+ } else {
+ ctx.Data["CodeSearchOptions"] = git.GrepSearchOptions
+ }
if keyword == "" {
ctx.HTML(http.StatusOK, tplSearch)
@@ -45,10 +108,11 @@ func Search(ctx *context.Context) {
if setting.Indexer.RepoIndexerEnabled {
var err error
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{
- RepoIDs: []int64{ctx.Repo.Repository.ID},
- Keyword: keyword,
- IsKeywordFuzzy: isFuzzy,
- Language: language,
+ RepoIDs: []int64{ctx.Repo.Repository.ID},
+ Keyword: keyword,
+ Mode: mode.ToIndexer(),
+ Language: language,
+ Filename: path,
Paginator: &db.ListOptions{
Page: page,
PageSize: setting.UI.RepoSearchPagingNum,
@@ -66,8 +130,9 @@ func Search(ctx *context.Context) {
} else {
res, err := git.GrepSearch(ctx, ctx.Repo.GitRepo, keyword, git.GrepOptions{
ContextLineNumber: 1,
- IsFuzzy: isFuzzy,
RefName: ctx.Repo.RefName,
+ Filename: path,
+ Mode: mode.ToGitGrep(),
})
if err != nil {
ctx.ServerError("GrepSearch", err)
@@ -85,12 +150,13 @@ func Search(ctx *context.Context) {
// UpdatedUnix: not supported yet
// Language: not supported yet
// Color: not supported yet
- Lines: code_indexer.HighlightSearchResultCode(r.Filename, r.LineNumbers, strings.Join(r.LineCodes, "\n")),
+ Lines: code_indexer.HighlightSearchResultCode(
+ r.Filename, r.LineNumbers, r.HighlightedRanges,
+ strings.Join(r.LineCodes, "\n")),
})
}
}
- ctx.Data["CodeIndexerDisabled"] = !setting.Indexer.RepoIndexerEnabled
ctx.Data["Repo"] = ctx.Repo.Repository
ctx.Data["SourcePath"] = ctx.Repo.Repository.Link()
ctx.Data["SearchResults"] = searchResults
diff --git a/routers/web/repo/setting/avatar.go b/routers/web/repo/setting/avatar.go
index 504f57cfc2..abbb12cacb 100644
--- a/routers/web/repo/setting/avatar.go
+++ b/routers/web/repo/setting/avatar.go
@@ -8,13 +8,13 @@ import (
"fmt"
"io"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/typesniffer"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/typesniffer"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ repo_service "forgejo.org/services/repository"
)
// UpdateAvatarSetting update repo's avatar
diff --git a/routers/web/repo/setting/collaboration.go b/routers/web/repo/setting/collaboration.go
index 75b55151e7..a816a16bc8 100644
--- a/routers/web/repo/setting/collaboration.go
+++ b/routers/web/repo/setting/collaboration.go
@@ -8,19 +8,19 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- unit_model "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/mailer"
- org_service "code.gitea.io/gitea/services/org"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+ "forgejo.org/services/mailer"
+ org_service "forgejo.org/services/org"
+ repo_service "forgejo.org/services/repository"
)
// Collaboration render a repository's collaboration page
diff --git a/routers/web/repo/setting/default_branch.go b/routers/web/repo/setting/default_branch.go
index 881d148afc..1c6033f1e4 100644
--- a/routers/web/repo/setting/default_branch.go
+++ b/routers/web/repo/setting/default_branch.go
@@ -6,12 +6,12 @@ package setting
import (
"net/http"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/routers/web/repo"
- "code.gitea.io/gitea/services/context"
- repo_service "code.gitea.io/gitea/services/repository"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/routers/web/repo"
+ "forgejo.org/services/context"
+ repo_service "forgejo.org/services/repository"
)
// SetDefaultBranchPost set default branch
diff --git a/routers/web/repo/setting/deploy_key.go b/routers/web/repo/setting/deploy_key.go
index abc3eb4af1..c59f0e90c2 100644
--- a/routers/web/repo/setting/deploy_key.go
+++ b/routers/web/repo/setting/deploy_key.go
@@ -6,14 +6,14 @@ package setting
import (
"net/http"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
// DeployKeys render the deploy keys list of a repository page
diff --git a/routers/web/repo/setting/git_hooks.go b/routers/web/repo/setting/git_hooks.go
index 217a01c90c..a50bce2a27 100644
--- a/routers/web/repo/setting/git_hooks.go
+++ b/routers/web/repo/setting/git_hooks.go
@@ -6,8 +6,8 @@ package setting
import (
"net/http"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/git"
+ "forgejo.org/services/context"
)
// GitHooks hooks of a repository
diff --git a/routers/web/repo/setting/lfs.go b/routers/web/repo/setting/lfs.go
index c18cb6a8c8..2e9c34e8a7 100644
--- a/routers/web/repo/setting/lfs.go
+++ b/routers/web/repo/setting/lfs.go
@@ -14,20 +14,20 @@ import (
"strconv"
"strings"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/git/pipeline"
- "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/typesniffer"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/git/pipeline"
+ "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/typesniffer"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
)
const (
@@ -95,6 +95,11 @@ func LFSLocks(ctx *context.Context) {
ctx.ServerError("LFSLocks", err)
return
}
+ if err := lfsLocks.LoadAttributes(ctx); err != nil {
+ ctx.ServerError("LFSLocks", err)
+ return
+ }
+
ctx.Data["LFSLocks"] = lfsLocks
if len(lfsLocks) == 0 {
diff --git a/routers/web/repo/setting/main_test.go b/routers/web/repo/setting/main_test.go
index c414b853e5..6b5a70ba08 100644
--- a/routers/web/repo/setting/main_test.go
+++ b/routers/web/repo/setting/main_test.go
@@ -6,7 +6,7 @@ package setting
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go
index b2f5798a26..18efbc37c4 100644
--- a/routers/web/repo/setting/protected_branch.go
+++ b/routers/web/repo/setting/protected_branch.go
@@ -11,17 +11,17 @@ import (
"strings"
"time"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/web/repo"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- pull_service "code.gitea.io/gitea/services/pull"
- "code.gitea.io/gitea/services/repository"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/web/repo"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ pull_service "forgejo.org/services/pull"
+ "forgejo.org/services/repository"
"github.com/gobwas/glob"
)
diff --git a/routers/web/repo/setting/protected_tag.go b/routers/web/repo/setting/protected_tag.go
index 2c25b650b9..5735149dfd 100644
--- a/routers/web/repo/setting/protected_tag.go
+++ b/routers/web/repo/setting/protected_tag.go
@@ -8,15 +8,15 @@ import (
"net/http"
"strings"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
const (
diff --git a/routers/web/repo/setting/runners.go b/routers/web/repo/setting/runners.go
index a47d3b45e2..32c8667825 100644
--- a/routers/web/repo/setting/runners.go
+++ b/routers/web/repo/setting/runners.go
@@ -8,13 +8,13 @@ import (
"net/http"
"net/url"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- actions_shared "code.gitea.io/gitea/routers/web/shared/actions"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ actions_shared "forgejo.org/routers/web/shared/actions"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
)
const (
@@ -179,7 +179,7 @@ func RunnerDeletePost(ctx *context.Context) {
ctx.ServerError("getRunnersCtx", err)
return
}
- actions_shared.RunnerDeletePost(ctx, ctx.ParamsInt64(":runnerid"), rCtx.RedirectLink, rCtx.RedirectLink+url.PathEscape(ctx.Params(":runnerid")))
+ actions_shared.RunnerDeletePost(ctx, ctx.ParamsInt64(":runnerid"), rCtx.OwnerID, rCtx.RepoID, rCtx.RedirectLink, rCtx.RedirectLink+url.PathEscape(ctx.Params(":runnerid")))
}
func RedirectToDefaultSetting(ctx *context.Context) {
diff --git a/routers/web/repo/setting/secrets.go b/routers/web/repo/setting/secrets.go
index d4d56bfc57..11c83e8bd6 100644
--- a/routers/web/repo/setting/secrets.go
+++ b/routers/web/repo/setting/secrets.go
@@ -7,11 +7,11 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- shared "code.gitea.io/gitea/routers/web/shared/secrets"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ shared "forgejo.org/routers/web/shared/secrets"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go
index 66e96b9961..083cc4ae82 100644
--- a/routers/web/repo/setting/setting.go
+++ b/routers/web/repo/setting/setting.go
@@ -13,33 +13,34 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- unit_model "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/indexer/code"
- "code.gitea.io/gitea/modules/indexer/stats"
- "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/validation"
- "code.gitea.io/gitea/modules/web"
- actions_service "code.gitea.io/gitea/services/actions"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/federation"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/migrations"
- mirror_service "code.gitea.io/gitea/services/mirror"
- repo_service "code.gitea.io/gitea/services/repository"
- wiki_service "code.gitea.io/gitea/services/wiki"
+ "forgejo.org/models"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/indexer/code"
+ "forgejo.org/modules/indexer/stats"
+ "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ actions_service "forgejo.org/services/actions"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/context"
+ "forgejo.org/services/federation"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/migrations"
+ mirror_service "forgejo.org/services/mirror"
+ repo_service "forgejo.org/services/repository"
+ wiki_service "forgejo.org/services/wiki"
)
const (
@@ -91,6 +92,7 @@ func SettingsCtxData(ctx *context.Context) {
return
}
ctx.Data["PushMirrors"] = pushMirrors
+ ctx.Data["CanUseSSHMirroring"] = git.HasSSHExecutable
}
// Units show a repositorys unit settings page
@@ -103,6 +105,10 @@ func Units(ctx *context.Context) {
func UnitsPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.RepoUnitSettingForm)
+ if ctx.HasError() {
+ ctx.Redirect(ctx.Repo.Repository.Link() + "/settings/units")
+ return
+ }
repo := ctx.Repo.Repository
@@ -260,6 +266,7 @@ func UnitsPost(ctx *context.Context) {
AllowRebaseUpdate: form.PullsAllowRebaseUpdate,
DefaultDeleteBranchAfterMerge: form.DefaultDeleteBranchAfterMerge,
DefaultMergeStyle: repo_model.MergeStyle(form.PullsDefaultMergeStyle),
+ DefaultUpdateStyle: repo_model.UpdateStyle(form.PullsDefaultUpdateStyle),
DefaultAllowMaintainerEdit: form.DefaultAllowMaintainerEdit,
},
})
@@ -477,10 +484,10 @@ func SettingsPost(ctx *context.Context) {
ctx.ServerError("UpdateAddress", err)
return
}
-
- remoteAddress, err := util.SanitizeURL(form.MirrorAddress)
+ remoteAddress, err := util.SanitizeURL(address)
if err != nil {
- ctx.ServerError("SanitizeURL", err)
+ ctx.Data["Err_MirrorAddress"] = true
+ handleSettingRemoteAddrError(ctx, err, form)
return
}
pullMirror.RemoteAddress = remoteAddress
@@ -518,6 +525,20 @@ func SettingsPost(ctx *context.Context) {
return
}
+ ok, err := quota_model.EvaluateForUser(ctx, repo.OwnerID, quota_model.LimitSubjectSizeReposAll)
+ if err != nil {
+ ctx.ServerError("quota_model.EvaluateForUser", err)
+ return
+ }
+ if !ok {
+ // This section doesn't require repo_name/RepoName to be set in the form, don't show it
+ // as an error on the UI for this action
+ ctx.Data["Err_RepoName"] = nil
+
+ ctx.RenderWithErr(ctx.Tr("repo.settings.pull_mirror_sync_quota_exceeded"), tplSettingsOptions, &form)
+ return
+ }
+
mirror_service.AddPullMirrorToQueue(repo.ID)
ctx.Flash.Info(ctx.Tr("repo.settings.pull_mirror_sync_in_progress", repo.OriginalURL))
@@ -550,21 +571,19 @@ func SettingsPost(ctx *context.Context) {
// as an error on the UI for this action
ctx.Data["Err_RepoName"] = nil
+ m, err := selectPushMirrorByForm(ctx, form, repo)
+ if err != nil {
+ ctx.NotFound("", nil)
+ return
+ }
+
interval, err := time.ParseDuration(form.PushMirrorInterval)
if err != nil || (interval != 0 && interval < setting.Mirror.MinInterval) {
ctx.RenderWithErr(ctx.Tr("repo.mirror_interval_invalid"), tplSettingsOptions, &forms.RepoSettingForm{})
return
}
- id, err := strconv.ParseInt(form.PushMirrorID, 10, 64)
- if err != nil {
- ctx.ServerError("UpdatePushMirrorIntervalPushMirrorID", err)
- return
- }
- m := &repo_model.PushMirror{
- ID: id,
- Interval: interval,
- }
+ m.Interval = interval
if err := repo_model.UpdatePushMirrorInterval(ctx, m); err != nil {
ctx.ServerError("UpdatePushMirrorInterval", err)
return
@@ -623,9 +642,20 @@ func SettingsPost(ctx *context.Context) {
return
}
+ if form.PushMirrorUseSSH && (form.PushMirrorUsername != "" || form.PushMirrorPassword != "") {
+ ctx.Data["Err_PushMirrorUseSSH"] = true
+ ctx.RenderWithErr(ctx.Tr("repo.mirror_denied_combination"), tplSettingsOptions, &form)
+ return
+ }
+
+ if form.PushMirrorUseSSH && !git.HasSSHExecutable {
+ ctx.RenderWithErr(ctx.Tr("repo.mirror_use_ssh.not_available"), tplSettingsOptions, &form)
+ return
+ }
+
address, err := forms.ParseRemoteAddr(form.PushMirrorAddress, form.PushMirrorUsername, form.PushMirrorPassword)
if err == nil {
- err = migrations.IsMigrateURLAllowed(address, ctx.Doer)
+ err = migrations.IsPushMirrorURLAllowed(address, ctx.Doer)
}
if err != nil {
ctx.Data["Err_PushMirrorAddress"] = true
@@ -639,9 +669,10 @@ func SettingsPost(ctx *context.Context) {
return
}
- remoteAddress, err := util.SanitizeURL(form.PushMirrorAddress)
+ remoteAddress, err := util.SanitizeURL(address)
if err != nil {
- ctx.ServerError("SanitizeURL", err)
+ ctx.Data["Err_PushMirrorAddress"] = true
+ handleSettingRemoteAddrError(ctx, err, form)
return
}
@@ -653,11 +684,30 @@ func SettingsPost(ctx *context.Context) {
Interval: interval,
RemoteAddress: remoteAddress,
}
+
+ var plainPrivateKey []byte
+ if form.PushMirrorUseSSH {
+ publicKey, privateKey, err := util.GenerateSSHKeypair()
+ if err != nil {
+ ctx.ServerError("GenerateSSHKeypair", err)
+ return
+ }
+ plainPrivateKey = privateKey
+ m.PublicKey = string(publicKey)
+ }
+
if err := db.Insert(ctx, m); err != nil {
ctx.ServerError("InsertPushMirror", err)
return
}
+ if form.PushMirrorUseSSH {
+ if err := m.SetPrivatekey(ctx, plainPrivateKey); err != nil {
+ ctx.ServerError("SetPrivatekey", err)
+ return
+ }
+ }
+
if err := mirror_service.AddPushMirrorRemote(ctx, m, address); err != nil {
if err := repo_model.DeletePushMirrors(ctx, repo_model.PushMirrorOptions{ID: m.ID, RepoID: m.RepoID}); err != nil {
log.Error("DeletePushMirrors %v", err)
@@ -828,6 +878,17 @@ func SettingsPost(ctx *context.Context) {
}
}
+ // Check the quota of the new owner
+ ok, err := quota_model.EvaluateForUser(ctx, newOwner.ID, quota_model.LimitSubjectSizeReposAll)
+ if err != nil {
+ ctx.ServerError("quota_model.EvaluateForUser", err)
+ return
+ }
+ if !ok {
+ ctx.RenderWithErr(ctx.Tr("repo.settings.transfer_quota_exceeded", newOwner.Name), tplSettingsOptions, &form)
+ return
+ }
+
// Close the GitRepo if open
if ctx.Repo.GitRepo != nil {
ctx.Repo.GitRepo.Close()
@@ -973,7 +1034,7 @@ func SettingsPost(ctx *context.Context) {
return
}
- if err := actions_model.CleanRepoScheduleTasks(ctx, repo); err != nil {
+ if err := actions_model.CleanRepoScheduleTasks(ctx, repo, true); err != nil {
log.Error("CleanRepoScheduleTasks for archived repo %s/%s: %v", ctx.Repo.Owner.Name, repo.Name, err)
}
diff --git a/routers/web/repo/setting/settings_test.go b/routers/web/repo/setting/settings_test.go
index b771113841..6f05953bfb 100644
--- a/routers/web/repo/setting/settings_test.go
+++ b/routers/web/repo/setting/settings_test.go
@@ -7,21 +7,22 @@ import (
"net/http"
"testing"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/contexttest"
- "code.gitea.io/gitea/services/forms"
- repo_service "code.gitea.io/gitea/services/repository"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/contexttest"
+ "forgejo.org/services/forms"
+ repo_service "forgejo.org/services/repository"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func createSSHAuthorizedKeysTmpPath(t *testing.T) func() {
@@ -126,7 +127,7 @@ func TestCollaborationPost(t *testing.T) {
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
exists, err := repo_model.IsCollaborator(ctx, re.ID, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists)
}
@@ -186,7 +187,7 @@ func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) {
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
exists, err := repo_model.IsCollaborator(ctx, re.ID, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, exists)
// Try adding the same collaborator again
diff --git a/routers/web/repo/setting/variables.go b/routers/web/repo/setting/variables.go
index 45b6c0f39a..a83d2dea6f 100644
--- a/routers/web/repo/setting/variables.go
+++ b/routers/web/repo/setting/variables.go
@@ -7,11 +7,11 @@ import (
"errors"
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- shared "code.gitea.io/gitea/routers/web/shared/actions"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ shared "forgejo.org/routers/web/shared/actions"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
)
const (
@@ -127,7 +127,7 @@ func VariableUpdate(ctx *context.Context) {
return
}
- shared.UpdateVariable(ctx, vCtx.RedirectLink)
+ shared.UpdateVariable(ctx, vCtx.OwnerID, vCtx.RepoID, vCtx.RedirectLink)
}
func VariableDelete(ctx *context.Context) {
@@ -136,5 +136,5 @@ func VariableDelete(ctx *context.Context) {
ctx.ServerError("getVariablesCtx", err)
return
}
- shared.DeleteVariable(ctx, vCtx.RedirectLink)
+ shared.DeleteVariable(ctx, vCtx.OwnerID, vCtx.RepoID, vCtx.RedirectLink)
}
diff --git a/routers/web/repo/setting/webhook.go b/routers/web/repo/setting/webhook.go
index eee493e2c2..6d4d9e47e2 100644
--- a/routers/web/repo/setting/webhook.go
+++ b/routers/web/repo/setting/webhook.go
@@ -11,24 +11,24 @@ import (
"net/url"
"path"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web/middleware"
- webhook_module "code.gitea.io/gitea/modules/webhook"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
- "code.gitea.io/gitea/services/forms"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/models/webhook"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/web/middleware"
+ webhook_module "forgejo.org/modules/webhook"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
+ "forgejo.org/services/forms"
+ webhook_service "forgejo.org/services/webhook"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
const (
diff --git a/routers/web/repo/topic.go b/routers/web/repo/topic.go
index d81a695df9..a028afb042 100644
--- a/routers/web/repo/topic.go
+++ b/routers/web/repo/topic.go
@@ -7,9 +7,9 @@ import (
"net/http"
"strings"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/context"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/context"
)
// TopicsPost response for creating repository
diff --git a/routers/web/repo/treelist.go b/routers/web/repo/treelist.go
index d11af4669f..5c37f2ebca 100644
--- a/routers/web/repo/treelist.go
+++ b/routers/web/repo/treelist.go
@@ -6,9 +6,9 @@ package repo
import (
"net/http"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/services/context"
"github.com/go-enry/go-enry/v2"
)
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 5295bfdb2a..c231b7ee6c 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -8,6 +8,7 @@ import (
"bytes"
gocontext "context"
"encoding/base64"
+ "errors"
"fmt"
"html/template"
"image"
@@ -23,34 +24,36 @@ import (
_ "image/jpeg" // for processing jpeg images
_ "image/png" // for processing png images
- activities_model "code.gitea.io/gitea/models/activities"
- admin_model "code.gitea.io/gitea/models/admin"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issue_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- unit_model "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/highlight"
- "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/svg"
- "code.gitea.io/gitea/modules/typesniffer"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/web/feed"
- "code.gitea.io/gitea/services/context"
- issue_service "code.gitea.io/gitea/services/issue"
- files_service "code.gitea.io/gitea/services/repository/files"
+ activities_model "forgejo.org/models/activities"
+ admin_model "forgejo.org/models/admin"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issue_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/actions"
+ "forgejo.org/modules/annex"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/highlight"
+ code_indexer "forgejo.org/modules/indexer/code"
+ "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/svg"
+ "forgejo.org/modules/typesniffer"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/web/feed"
+ "forgejo.org/services/context"
+ issue_service "forgejo.org/services/issue"
+ files_service "forgejo.org/services/repository/files"
"github.com/nektos/act/pkg/model"
@@ -146,7 +149,6 @@ func FindReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry, try
// this should be impossible; if subTreeEntry exists so should this.
continue
}
- var err error
childEntries, err := subTree.ListEntries()
if err != nil {
return "", nil, err
@@ -208,14 +210,59 @@ func localizedExtensions(ext, languageCode string) (localizedExts []string) {
}
type fileInfo struct {
- isTextFile bool
- isLFSFile bool
- fileSize int64
- lfsMeta *lfs.Pointer
- st typesniffer.SniffedType
+ isTextFile bool
+ isLFSFile bool
+ isAnnexFile bool
+ isAnnexFilePresent bool
+ fileSize int64
+ lfsMeta *lfs.Pointer
+ st typesniffer.SniffedType
}
func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte, io.ReadCloser, *fileInfo, error) {
+ isAnnexed, err := annex.IsAnnexed(blob)
+ if err != nil {
+ return nil, nil, nil, err
+ }
+ if isAnnexed {
+ // TODO: this code could be merged with the LFS case, especially the redundant type sniffer,
+ // but it is *currently* written this way to make merging with the non-annex upstream easier:
+ // this way, the git-annex patch is (mostly) pure additions.
+
+ annexContent, err := annex.Content(blob)
+ if err != nil {
+ // If annex.Content returns an error it can mean that the blob does not
+ // refer to an annexed file or that it is not present here. Since we already
+ // checked that it is annexed the latter must be the case. So we return the
+ // content of the blob instead and indicate that the file is indeed annexed,
+ // but not present here. The template can then communicate the situation.
+ dataRc, err := blob.DataAsync()
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ buf := make([]byte, 1024)
+ n, _ := util.ReadAtMost(dataRc, buf)
+ buf = buf[:n]
+
+ st := typesniffer.DetectContentType(buf)
+ return buf, dataRc, &fileInfo{st.IsText(), false, true, false, blob.Size(), nil, st}, nil
+ }
+
+ stat, err := annexContent.Stat()
+ if err != nil {
+ return nil, nil, nil, err
+ }
+
+ buf := make([]byte, 1024)
+ n, _ := util.ReadAtMost(annexContent, buf)
+ buf = buf[:n]
+
+ st := typesniffer.DetectContentType(buf)
+
+ return buf, annexContent, &fileInfo{st.IsText(), false, true, true, stat.Size(), nil, st}, nil
+ }
+
dataRc, err := blob.DataAsync()
if err != nil {
return nil, nil, nil, err
@@ -230,23 +277,21 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte,
// FIXME: what happens when README file is an image?
if !isTextFile || !setting.LFS.StartServer {
- return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
+ return buf, dataRc, &fileInfo{isTextFile, false, false, false, blob.Size(), nil, st}, nil
}
pointer, _ := lfs.ReadPointerFromBuffer(buf)
if !pointer.IsValid() { // fallback to plain file
- return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
+ return buf, dataRc, &fileInfo{isTextFile, false, false, false, blob.Size(), nil, st}, nil
}
meta, err := git_model.GetLFSMetaObjectByOid(ctx, repoID, pointer.Oid)
- if err != nil && err != git_model.ErrLFSObjectNotExist { // fallback to plain file
- return buf, dataRc, &fileInfo{isTextFile, false, blob.Size(), nil, st}, nil
+ if err != nil { // fallback to plain file
+ log.Warn("Unable to access LFS pointer %s in repo %d: %v", pointer.Oid, repoID, err)
+ return buf, dataRc, &fileInfo{isTextFile, false, false, false, blob.Size(), nil, st}, nil
}
dataRc.Close()
- if err != nil {
- return nil, nil, nil, err
- }
dataRc, err = lfs.ReadMetaObject(pointer)
if err != nil {
@@ -263,7 +308,7 @@ func getFileReader(ctx gocontext.Context, repoID int64, blob *git.Blob) ([]byte,
st = typesniffer.DetectContentType(buf)
- return buf, dataRc, &fileInfo{st.IsText(), true, meta.Size, &meta.Pointer, st}, nil
+ return buf, dataRc, &fileInfo{st.IsText(), true, false, false, meta.Size, &meta.Pointer, st}, nil
}
func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.TreeEntry) {
@@ -326,6 +371,7 @@ func renderReadmeFile(ctx *context.Context, subfolder string, readmeFile *git.Tr
},
Metas: ctx.Repo.Repository.ComposeDocumentMetas(ctx),
GitRepo: ctx.Repo.GitRepo,
+ Blob: target.Blob(),
}, rd)
if err != nil {
log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.Name(), ctx.Repo.Repository, err)
@@ -368,6 +414,9 @@ func loadLatestCommitData(ctx *context.Context, latestCommit *git.Commit) bool {
if err != nil {
log.Error("GetLatestCommitStatus: %v", err)
}
+ if !ctx.Repo.CanRead(unit_model.TypeActions) {
+ git_model.CommitStatusesHideActionsURL(ctx, statuses)
+ }
ctx.Data["LatestCommitStatus"] = git_model.CalcCommitStatus(statuses)
ctx.Data["LatestCommitStatuses"] = statuses
@@ -392,6 +441,10 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["FileName"] = blob.Name()
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
+ ctx.Data["OpenGraphTitle"] = ctx.Data["Title"]
+ ctx.Data["OpenGraphURL"] = fmt.Sprintf("%s%s", setting.AppURL, ctx.Data["Link"])
+ ctx.Data["OpenGraphNoDescription"] = true
+
if entry.IsLink() {
_, link, err := entry.FollowLinks()
// Errors should be allowed, because this shouldn't
@@ -445,10 +498,17 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
isDisplayingSource := ctx.FormString("display") == "source"
isDisplayingRendered := !isDisplayingSource
- if fInfo.isLFSFile {
+ if fInfo.isLFSFile || fInfo.isAnnexFile {
ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.BranchNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)
}
+ if fInfo.isAnnexFile {
+ // pre-git-annex v7, all annexed files were represented in-repo as symlinks;
+ // but we pretend they aren't, since that's a distracting quirk of git-annex
+ // and not a meaningful choice on the user's part
+ ctx.Data["FileIsSymlink"] = false
+ }
+
isRepresentableAsText := fInfo.st.IsRepresentableAsText()
if !isRepresentableAsText {
// If we can't show plain text, always try to render.
@@ -456,6 +516,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
isDisplayingRendered = true
}
ctx.Data["IsLFSFile"] = fInfo.isLFSFile
+ ctx.Data["IsAnnexFile"] = fInfo.isAnnexFile
+ ctx.Data["IsAnnexFilePresent"] = fInfo.isAnnexFilePresent
ctx.Data["FileSize"] = fInfo.fileSize
ctx.Data["IsTextFile"] = fInfo.isTextFile
ctx.Data["IsRepresentableAsText"] = isRepresentableAsText
@@ -490,6 +552,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
// Assume file is not editable first.
if fInfo.isLFSFile {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_lfs_files")
+ } else if fInfo.isAnnexFile {
+ ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_annex_files")
} else if !isRepresentableAsText {
ctx.Data["EditFileTooltip"] = ctx.Tr("repo.editor.cannot_edit_non_text_files")
}
@@ -544,6 +608,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
},
Metas: metas,
GitRepo: ctx.Repo.GitRepo,
+ Blob: entry.Blob(),
}, rd)
if err != nil {
ctx.ServerError("Render", err)
@@ -557,14 +622,22 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
// The Open Group Base Specification: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html
// empty: 0 lines; "a": 1 incomplete-line; "a\n": 1 line; "a\nb": 1 line, 1 incomplete-line;
// Forgejo uses the definition (like most modern editors):
- // empty: 0 lines; "a": 1 line; "a\n": 2 lines; "a\nb": 2 lines;
- // When rendering, the last empty line is not rendered in UI, while the line-number is still counted, to tell users that the file contains a trailing EOL.
- // To make the UI more consistent, it could use an icon mark to indicate that there is no trailing EOL, and show line-number as the rendered lines.
+ // empty: 0 lines; "a": 1 line; "a\n": 1 line; "a\nb": 2 lines;
+ // When rendering, the last empty line is not rendered in U and isn't counted towards the number of lines.
+ // To tell users that the file not contains a trailing EOL, text with a tooltip is displayed in the file header.
+ // Trailing EOL is only considered if the file has content.
// This NumLines is only used for the display on the UI: "xxx lines"
if len(buf) == 0 {
ctx.Data["NumLines"] = 0
} else {
- ctx.Data["NumLines"] = bytes.Count(buf, []byte{'\n'}) + 1
+ hasNoTrailingEOL := !bytes.HasSuffix(buf, []byte{'\n'})
+ ctx.Data["HasNoTrailingEOL"] = hasNoTrailingEOL
+
+ numLines := bytes.Count(buf, []byte{'\n'})
+ if hasNoTrailingEOL {
+ numLines++
+ }
+ ctx.Data["NumLines"] = numLines
}
ctx.Data["NumLinesSet"] = true
@@ -589,7 +662,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
ctx.Data["FileContent"] = fileContent
ctx.Data["LineEscapeStatus"] = statuses
}
- if !fInfo.isLFSFile {
+ if !fInfo.isLFSFile && !fInfo.isAnnexFile {
if ctx.Repo.CanEnableEditor(ctx, ctx.Doer) {
if lfsLock != nil && lfsLock.OwnerID != ctx.Doer.ID {
ctx.Data["CanEditFile"] = false
@@ -634,6 +707,7 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) {
},
Metas: ctx.Repo.Repository.ComposeDocumentMetas(ctx),
GitRepo: ctx.Repo.GitRepo,
+ Blob: entry.Blob(),
}, rd)
if err != nil {
ctx.ServerError("Render", err)
@@ -743,12 +817,12 @@ func checkHomeCodeViewable(ctx *context.Context) {
}
if firstUnit != nil {
- ctx.Redirect(fmt.Sprintf("%s%s", ctx.Repo.Repository.Link(), firstUnit.URI))
+ ctx.Redirect(ctx.Repo.Repository.Link() + firstUnit.URI)
return
}
}
- ctx.NotFound("Home", fmt.Errorf(ctx.Locale.TrString("units.error.no_unit_allowed_repo")))
+ ctx.NotFound("Home", errors.New(ctx.Locale.TrString("units.error.no_unit_allowed_repo")))
}
func checkCitationFile(ctx *context.Context, entry *git.TreeEntry) {
@@ -771,7 +845,8 @@ func checkCitationFile(ctx *context.Context, entry *git.TreeEntry) {
if content, err := entry.Blob().GetBlobContent(setting.UI.MaxDisplayFileSize); err != nil {
log.Error("checkCitationFile: GetBlobContent: %v", err)
} else {
- ctx.Data["CitiationExist"] = true
+ ctx.Data["CitationExist"] = true
+ ctx.Data["CitationFile"] = entry.Name()
ctx.PageData["citationFileContent"] = content
break
}
@@ -1029,7 +1104,15 @@ func renderHomeCode(ctx *context.Context) {
return
}
- if entry.IsDir() {
+ if entry.IsSubModule() {
+ subModuleURL, err := ctx.Repo.Commit.GetSubModule(entry.Name())
+ if err != nil {
+ HandleGitError(ctx, "Repo.Commit.GetSubModule", err)
+ return
+ }
+ subModuleFile := git.NewSubModuleFile(ctx.Repo.Commit, subModuleURL, entry.ID.String())
+ ctx.Redirect(subModuleFile.RefURL(setting.AppURL, ctx.Repo.Repository.FullName(), setting.SSH.Domain))
+ } else if entry.IsDir() {
renderDirectory(ctx)
} else {
renderFile(ctx, entry)
@@ -1142,6 +1225,21 @@ PostRecentBranchCheck:
ctx.Data["TreeNames"] = treeNames
ctx.Data["BranchLink"] = branchLink
ctx.Data["CodeIndexerDisabled"] = !setting.Indexer.RepoIndexerEnabled
+ if setting.Indexer.RepoIndexerEnabled {
+ ctx.Data["CodeIndexerUnavailable"] = !code_indexer.IsAvailable(ctx)
+ ctx.Data["CodeSearchOptions"] = code_indexer.CodeSearchOptions
+ } else {
+ ctx.Data["CodeSearchOptions"] = git.GrepSearchOptions
+ }
+ isAnnexFile, okAnnexFile := ctx.Data["IsAnnexFile"]
+ isAnnexFilePresent, okAnnexFilePresent := ctx.Data["IsAnnexFilePresent"]
+ if okAnnexFile && okAnnexFilePresent && isAnnexFile.(bool) && !isAnnexFilePresent.(bool) {
+ // If the file to be viewed is annexed but not present then render it normally
+ // (which will show the plain git blob content, i.e. the symlink or pointer target)
+ // but make the status code a 404.
+ ctx.HTML(http.StatusNotFound, tplRepoHome)
+ return
+ }
ctx.HTML(http.StatusOK, tplRepoHome)
}
@@ -1222,11 +1320,8 @@ func Forks(ctx *context.Context) {
page = 1
}
- pager := context.NewPagination(ctx.Repo.Repository.NumForks, setting.MaxForksPerPage, page, 5)
- ctx.Data["Page"] = pager
-
- forks, err := repo_model.GetForks(ctx, ctx.Repo.Repository, db.ListOptions{
- Page: pager.Paginater.Current(),
+ forks, total, err := repo_model.GetForks(ctx, ctx.Repo.Repository, ctx.Doer, db.ListOptions{
+ Page: page,
PageSize: setting.MaxForksPerPage,
})
if err != nil {
@@ -1234,6 +1329,9 @@ func Forks(ctx *context.Context) {
return
}
+ pager := context.NewPagination(int(total), setting.MaxForksPerPage, page, 5)
+ ctx.Data["Page"] = pager
+
for _, fork := range forks {
if err = fork.LoadOwner(ctx); err != nil {
ctx.ServerError("LoadOwner", err)
diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go
index 4911fb6452..9a21ac21a3 100644
--- a/routers/web/repo/wiki.go
+++ b/routers/web/repo/wiki.go
@@ -6,6 +6,7 @@ package repo
import (
"bytes"
+ gocontext "context"
"fmt"
"io"
"net/http"
@@ -13,25 +14,25 @@ import (
"path/filepath"
"strings"
- git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- notify_service "code.gitea.io/gitea/services/notify"
- wiki_service "code.gitea.io/gitea/services/wiki"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/routers/common"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ notify_service "forgejo.org/services/notify"
+ wiki_service "forgejo.org/services/wiki"
)
const (
@@ -396,6 +397,7 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
pager := context.NewPagination(int(commitsCount), setting.Git.CommitsRangeSize, page, 5)
pager.SetDefaultParams(ctx)
+ pager.AddParamString("action", "_revision")
ctx.Data["Page"] = pager
return wikiRepo, entry
@@ -533,6 +535,9 @@ func Wiki(ctx *context.Context) {
}
ctx.Data["Author"] = lastCommit.Author
+ ctx.Data["OpenGraphTitle"] = ctx.Data["Title"]
+ ctx.Data["OpenGraphURL"] = fmt.Sprintf("%s%s", setting.AppURL, ctx.Data["Link"])
+
ctx.HTML(http.StatusOK, tplWikiView)
}
@@ -597,22 +602,32 @@ func WikiPages(ctx *context.Context) {
}
}()
- entries, err := commit.ListEntries()
+ treePath := "" // To support list sub folders' pages in the future
+ tree, err := commit.SubTree(treePath)
+ if err != nil {
+ ctx.ServerError("SubTree", err)
+ return
+ }
+
+ allEntries, err := tree.ListEntries()
if err != nil {
ctx.ServerError("ListEntries", err)
return
}
+ allEntries.CustomSort(base.NaturalSortLess)
+
+ entries, _, err := allEntries.GetCommitsInfo(gocontext.Context(ctx), commit, treePath)
+ if err != nil {
+ ctx.ServerError("GetCommitsInfo", err)
+ return
+ }
+
pages := make([]PageMeta, 0, len(entries))
for _, entry := range entries {
- if !entry.IsRegular() {
+ if !entry.Entry.IsRegular() {
continue
}
- c, err := wikiRepo.GetCommitByPath(entry.Name())
- if err != nil {
- ctx.ServerError("GetCommit", err)
- return
- }
- wikiName, err := wiki_service.GitPathToWebPath(entry.Name())
+ wikiName, err := wiki_service.GitPathToWebPath(entry.Entry.Name())
if err != nil {
if repo_model.IsErrWikiInvalidFileName(err) {
continue
@@ -624,8 +639,8 @@ func WikiPages(ctx *context.Context) {
pages = append(pages, PageMeta{
Name: displayName,
SubURL: wiki_service.WebPathToURLPath(wikiName),
- GitEntryName: entry.Name(),
- UpdatedUnix: timeutil.TimeStamp(c.Author.When.Unix()),
+ GitEntryName: entry.Entry.Name(),
+ UpdatedUnix: timeutil.TimeStamp(entry.Commit.Author.When.Unix()),
})
}
ctx.Data["Pages"] = pages
diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go
index 719cca3049..cba416fc92 100644
--- a/routers/web/repo/wiki_test.go
+++ b/routers/web/repo/wiki_test.go
@@ -9,16 +9,17 @@ import (
"net/url"
"testing"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/contexttest"
- "code.gitea.io/gitea/services/forms"
- wiki_service "code.gitea.io/gitea/services/wiki"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/contexttest"
+ "forgejo.org/services/forms"
+ wiki_service "forgejo.org/services/wiki"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
const (
@@ -28,12 +29,12 @@ const (
func wikiEntry(t *testing.T, repo *repo_model.Repository, wikiName wiki_service.WebPath) *git.TreeEntry {
wikiRepo, err := gitrepo.OpenWikiRepository(git.DefaultContext, repo)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer wikiRepo.Close()
commit, err := wikiRepo.GetBranchCommit("master")
- assert.NoError(t, err)
+ require.NoError(t, err)
entries, err := commit.ListEntries()
- assert.NoError(t, err)
+ require.NoError(t, err)
for _, entry := range entries {
if entry.Name() == wiki_service.WebPathToGitPath(wikiName) {
return entry
@@ -48,10 +49,10 @@ func wikiContent(t *testing.T, repo *repo_model.Repository, wikiName wiki_servic
return ""
}
reader, err := entry.Blob().DataAsync()
- assert.NoError(t, err)
+ require.NoError(t, err)
defer reader.Close()
bytes, err := io.ReadAll(reader)
- assert.NoError(t, err)
+ require.NoError(t, err)
return string(bytes)
}
@@ -85,7 +86,7 @@ func TestWiki(t *testing.T) {
Wiki(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
assert.EqualValues(t, "Home", ctx.Data["Title"])
- assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
+ assertPagesMetas(t, []string{"Home", "Long Page", "Page With Image", "Page With Spaced Name", "Unescaped File", "XSS"}, ctx.Data["Pages"])
}
func TestWikiPages(t *testing.T) {
@@ -95,7 +96,7 @@ func TestWikiPages(t *testing.T) {
contexttest.LoadRepo(t, ctx, 1)
WikiPages(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
- assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"])
+ assertPagesMetas(t, []string{"Home", "Long Page", "Page With Image", "Page With Spaced Name", "Unescaped File", "XSS"}, ctx.Data["Pages"])
}
func TestNewWiki(t *testing.T) {
@@ -127,7 +128,7 @@ func TestNewWikiPost(t *testing.T) {
NewWikiPost(ctx)
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title))
- assert.Equal(t, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)), content)
+ assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)))
}
}
@@ -179,7 +180,7 @@ func TestEditWikiPost(t *testing.T) {
EditWikiPost(ctx)
assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.Status())
assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title))
- assert.Equal(t, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)), content)
+ assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)))
if title != "Home" {
assertWikiNotExists(t, ctx.Repo.Repository, "Home")
}
diff --git a/routers/web/shared/actions/fixtures/TestRunnerDetails/action_runner.yml b/routers/web/shared/actions/fixtures/TestRunnerDetails/action_runner.yml
new file mode 100644
index 0000000000..d783f83110
--- /dev/null
+++ b/routers/web/shared/actions/fixtures/TestRunnerDetails/action_runner.yml
@@ -0,0 +1,7 @@
+-
+ id: 1004
+ uuid: "fb857e63-c0ce-4571-a6c9-fde26c128073"
+ name: "Global runner"
+ owner_id: 0
+ repo_id: 0
+ deleted: 0
diff --git a/routers/web/shared/actions/fixtures/TestRunnerDetails/action_task.yml b/routers/web/shared/actions/fixtures/TestRunnerDetails/action_task.yml
new file mode 100644
index 0000000000..63a2d30deb
--- /dev/null
+++ b/routers/web/shared/actions/fixtures/TestRunnerDetails/action_task.yml
@@ -0,0 +1,160 @@
+-
+ id: 1
+ runner_id: 1004
+ token_hash: a1
+-
+ id: 2
+ runner_id: 1004
+ token_hash: a2
+-
+ id: 3
+ runner_id: 1004
+ token_hash: a3
+-
+ id: 4
+ runner_id: 1004
+ token_hash: a4
+-
+ id: 5
+ runner_id: 1004
+ token_hash: a5
+-
+ id: 6
+ runner_id: 1004
+ token_hash: a6
+-
+ id: 7
+ runner_id: 1004
+ token_hash: a7
+-
+ id: 8
+ runner_id: 1004
+ token_hash: a8
+-
+ id: 9
+ runner_id: 1004
+ token_hash: a9
+-
+ id: 10
+ runner_id: 1004
+ token_hash: a10
+-
+ id: 11
+ runner_id: 1004
+ token_hash: a11
+-
+ id: 12
+ runner_id: 1004
+ token_hash: a12
+-
+ id: 13
+ runner_id: 1004
+ token_hash: a13
+-
+ id: 14
+ runner_id: 1004
+ token_hash: a14
+-
+ id: 15
+ runner_id: 1004
+ token_hash: a15
+-
+ id: 16
+ runner_id: 1004
+ token_hash: a16
+-
+ id: 17
+ runner_id: 1004
+ token_hash: a17
+-
+ id: 18
+ runner_id: 1004
+ token_hash: a18
+-
+ id: 19
+ runner_id: 1004
+ token_hash: a19
+-
+ id: 20
+ runner_id: 1004
+ token_hash: a20
+-
+ id: 21
+ runner_id: 1004
+ token_hash: a21
+-
+ id: 22
+ runner_id: 1004
+ token_hash: a22
+-
+ id: 23
+ runner_id: 1004
+ token_hash: a23
+-
+ id: 24
+ runner_id: 1004
+ token_hash: a24
+-
+ id: 25
+ runner_id: 1004
+ token_hash: a25
+-
+ id: 26
+ runner_id: 1004
+ token_hash: a26
+-
+ id: 27
+ runner_id: 1004
+ token_hash: a27
+-
+ id: 28
+ runner_id: 1004
+ token_hash: a28
+-
+ id: 29
+ runner_id: 1004
+ token_hash: a29
+-
+ id: 30
+ runner_id: 1004
+ token_hash: a30
+-
+ id: 31
+ runner_id: 1004
+ token_hash: a31
+-
+ id: 32
+ runner_id: 1004
+ token_hash: a32
+-
+ id: 33
+ runner_id: 1004
+ token_hash: a33
+-
+ id: 34
+ runner_id: 1004
+ token_hash: a34
+-
+ id: 35
+ runner_id: 1004
+ token_hash: a35
+-
+ id: 36
+ runner_id: 1004
+ token_hash: a36
+-
+ id: 37
+ runner_id: 1004
+ token_hash: a37
+-
+ id: 38
+ runner_id: 1004
+ token_hash: a38
+-
+ id: 39
+ runner_id: 1004
+ token_hash: a39
+-
+ id: 40
+ runner_id: 1004
+ token_hash: a40
diff --git a/routers/web/shared/actions/main_test.go b/routers/web/shared/actions/main_test.go
new file mode 100644
index 0000000000..056f48b98d
--- /dev/null
+++ b/routers/web/shared/actions/main_test.go
@@ -0,0 +1,17 @@
+// Copyright 2025 The Forgejo Authors.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package actions
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/forgefed"
+)
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m)
+}
diff --git a/routers/web/shared/actions/runners.go b/routers/web/shared/actions/runners.go
index f38933226b..2ab6b2dadd 100644
--- a/routers/web/shared/actions/runners.go
+++ b/routers/web/shared/actions/runners.go
@@ -6,13 +6,13 @@ package actions
import (
"errors"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
// RunnersList prepares data for runners list
@@ -79,7 +79,6 @@ func RunnerDetails(ctx *context.Context, page int, runnerID, ownerID, repoID int
Page: page,
PageSize: 30,
},
- Status: actions_model.StatusUnknown, // Unknown means all
RunnerID: runner.ID,
}
@@ -142,10 +141,21 @@ func RunnerResetRegistrationToken(ctx *context.Context, ownerID, repoID int64, r
}
// RunnerDeletePost response for deleting a runner
-func RunnerDeletePost(ctx *context.Context, runnerID int64,
+func RunnerDeletePost(ctx *context.Context, runnerID, ownerID, repoID int64,
successRedirectTo, failedRedirectTo string,
) {
- if err := actions_model.DeleteRunner(ctx, runnerID); err != nil {
+ runner, err := actions_model.GetRunnerByID(ctx, runnerID)
+ if err != nil {
+ ctx.ServerError("GetRunnerByID", err)
+ return
+ }
+
+ if !runner.Editable(ownerID, repoID) {
+ ctx.NotFound("Editable", util.NewPermissionDeniedErrorf("no permission to edit this runner"))
+ return
+ }
+
+ if err := actions_model.DeleteRunner(ctx, runner); err != nil {
log.Warn("DeleteRunnerPost.UpdateRunner failed: %v, url: %s", err, ctx.Req.URL)
ctx.Flash.Warning(ctx.Tr("actions.runners.delete_runner_failed"))
diff --git a/routers/web/shared/actions/runners_test.go b/routers/web/shared/actions/runners_test.go
new file mode 100644
index 0000000000..ad75d34ee6
--- /dev/null
+++ b/routers/web/shared/actions/runners_test.go
@@ -0,0 +1,47 @@
+// Copyright 2025 The Forgejo Authors.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package actions
+
+import (
+ "net/http"
+ "testing"
+
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/services/contexttest"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestRunnerDetails(t *testing.T) {
+ defer unittest.OverrideFixtures("routers/web/shared/actions/fixtures/TestRunnerDetails")()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ runner := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunner{ID: 1004})
+
+ t.Run("permission denied", func(t *testing.T) {
+ ctx, resp := contexttest.MockContext(t, "/admin/actions/runners")
+ RunnerDetails(ctx, 1, runner.ID, user.ID, 0)
+ assert.Equal(t, http.StatusNotFound, resp.Code)
+ })
+
+ t.Run("first page", func(t *testing.T) {
+ ctx, resp := contexttest.MockContext(t, "/admin/actions/runners")
+ page := 1
+ RunnerDetails(ctx, page, runner.ID, 0, 0)
+ require.Equal(t, http.StatusOK, resp.Code)
+ assert.Len(t, ctx.GetData()["Tasks"], 30)
+ })
+
+ t.Run("second and last page", func(t *testing.T) {
+ ctx, resp := contexttest.MockContext(t, "/admin/actions/runners")
+ page := 2
+ RunnerDetails(ctx, page, runner.ID, 0, 0)
+ require.Equal(t, http.StatusOK, resp.Code)
+ assert.Len(t, ctx.GetData()["Tasks"], 10)
+ })
+}
diff --git a/routers/web/shared/actions/variables.go b/routers/web/shared/actions/variables.go
index 79c03e4e8c..13dff2f11a 100644
--- a/routers/web/shared/actions/variables.go
+++ b/routers/web/shared/actions/variables.go
@@ -4,13 +4,13 @@
package actions
import (
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/web"
- actions_service "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/web"
+ actions_service "forgejo.org/services/actions"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
func SetVariablesContext(ctx *context.Context, ownerID, repoID int64) {
@@ -39,25 +39,33 @@ func CreateVariable(ctx *context.Context, ownerID, repoID int64, redirectURL str
ctx.JSONRedirect(redirectURL)
}
-func UpdateVariable(ctx *context.Context, redirectURL string) {
+func UpdateVariable(ctx *context.Context, ownerID, repoID int64, redirectURL string) {
id := ctx.ParamsInt64(":variable_id")
form := web.GetForm(ctx).(*forms.EditVariableForm)
- if ok, err := actions_service.UpdateVariable(ctx, id, form.Name, form.Data); err != nil || !ok {
- log.Error("UpdateVariable: %v", err)
- ctx.JSONError(ctx.Tr("actions.variables.update.failed"))
+ if ok, err := actions_service.UpdateVariable(ctx, id, ownerID, repoID, form.Name, form.Data); err != nil || !ok {
+ if !ok {
+ ctx.JSONError(ctx.Tr("actions.variables.not_found"))
+ } else {
+ log.Error("UpdateVariable: %v", err)
+ ctx.JSONError(ctx.Tr("actions.variables.update.failed"))
+ }
return
}
ctx.Flash.Success(ctx.Tr("actions.variables.update.success"))
ctx.JSONRedirect(redirectURL)
}
-func DeleteVariable(ctx *context.Context, redirectURL string) {
+func DeleteVariable(ctx *context.Context, ownerID, repoID int64, redirectURL string) {
id := ctx.ParamsInt64(":variable_id")
- if err := actions_service.DeleteVariableByID(ctx, id); err != nil {
- log.Error("Delete variable [%d] failed: %v", id, err)
- ctx.JSONError(ctx.Tr("actions.variables.deletion.failed"))
+ if ok, err := actions_model.DeleteVariable(ctx, id, ownerID, repoID); err != nil || !ok {
+ if !ok {
+ ctx.JSONError(ctx.Tr("actions.variables.not_found"))
+ } else {
+ log.Error("Delete variable [%d] failed: %v", id, err)
+ ctx.JSONError(ctx.Tr("actions.variables.deletion.failed"))
+ }
return
}
ctx.Flash.Success(ctx.Tr("actions.variables.deletion.success"))
diff --git a/routers/web/shared/packages/packages.go b/routers/web/shared/packages/packages.go
index af960f1c0c..1d4fb1588d 100644
--- a/routers/web/shared/packages/packages.go
+++ b/routers/web/shared/packages/packages.go
@@ -9,19 +9,19 @@ import (
"net/http"
"time"
- "code.gitea.io/gitea/models/db"
- packages_model "code.gitea.io/gitea/models/packages"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- cargo_service "code.gitea.io/gitea/services/packages/cargo"
- container_service "code.gitea.io/gitea/services/packages/container"
+ "forgejo.org/models/db"
+ packages_model "forgejo.org/models/packages"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ cargo_service "forgejo.org/services/packages/cargo"
+ container_service "forgejo.org/services/packages/container"
)
func SetPackagesContext(ctx *context.Context, owner *user_model.User) {
diff --git a/routers/web/shared/project/column.go b/routers/web/shared/project/column.go
index 599842ea9e..40bb439452 100644
--- a/routers/web/shared/project/column.go
+++ b/routers/web/shared/project/column.go
@@ -4,9 +4,9 @@
package project
import (
- project_model "code.gitea.io/gitea/models/project"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/services/context"
+ project_model "forgejo.org/models/project"
+ "forgejo.org/modules/json"
+ "forgejo.org/services/context"
)
// MoveColumns moves or keeps columns in a project and sorts them inside that project
diff --git a/routers/web/shared/secrets/secrets.go b/routers/web/shared/secrets/secrets.go
index 3bd421f86a..a853598939 100644
--- a/routers/web/shared/secrets/secrets.go
+++ b/routers/web/shared/secrets/secrets.go
@@ -4,14 +4,14 @@
package secrets
import (
- "code.gitea.io/gitea/models/db"
- secret_model "code.gitea.io/gitea/models/secret"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- secret_service "code.gitea.io/gitea/services/secrets"
+ "forgejo.org/models/db"
+ secret_model "forgejo.org/models/secret"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ secret_service "forgejo.org/services/secrets"
)
func SetSecretsContext(ctx *context.Context, ownerID, repoID int64) {
diff --git a/routers/web/shared/storage_overview.go b/routers/web/shared/storage_overview.go
new file mode 100644
index 0000000000..fac4aa99e5
--- /dev/null
+++ b/routers/web/shared/storage_overview.go
@@ -0,0 +1,90 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package shared
+
+import (
+ "html/template"
+ "net/http"
+
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+)
+
+// StorageOverview render a size overview of the user, as well as relevant
+// quota limits of the instance.
+func StorageOverview(ctx *context.Context, userID int64, tpl base.TplName) {
+ if !setting.Quota.Enabled {
+ ctx.NotFound("MustEnableQuota", nil)
+ }
+ ctx.Data["Title"] = ctx.Tr("settings.storage_overview")
+ ctx.Data["PageIsStorageOverview"] = true
+
+ ctx.Data["Color"] = func(subject quota_model.LimitSubject) float64 {
+ return float64(subject) * 137.50776405003785 // Golden angle.
+ }
+
+ ctx.Data["PrettySubject"] = func(subject quota_model.LimitSubject) template.HTML {
+ switch subject {
+ case quota_model.LimitSubjectSizeAll:
+ return ctx.Locale.Tr("settings.quota.sizes.all")
+ case quota_model.LimitSubjectSizeReposAll:
+ return ctx.Locale.Tr("settings.quota.sizes.repos.all")
+ case quota_model.LimitSubjectSizeReposPublic:
+ return ctx.Locale.Tr("settings.quota.sizes.repos.public")
+ case quota_model.LimitSubjectSizeReposPrivate:
+ return ctx.Locale.Tr("settings.quota.sizes.repos.private")
+ case quota_model.LimitSubjectSizeGitAll:
+ return ctx.Locale.Tr("settings.quota.sizes.git.all")
+ case quota_model.LimitSubjectSizeGitLFS:
+ return ctx.Locale.Tr("settings.quota.sizes.git.lfs")
+ case quota_model.LimitSubjectSizeAssetsAll:
+ return ctx.Locale.Tr("settings.quota.sizes.assets.all")
+ case quota_model.LimitSubjectSizeAssetsAttachmentsAll:
+ return ctx.Locale.Tr("settings.quota.sizes.assets.attachments.all")
+ case quota_model.LimitSubjectSizeAssetsAttachmentsIssues:
+ return ctx.Locale.Tr("settings.quota.sizes.assets.attachments.issues")
+ case quota_model.LimitSubjectSizeAssetsAttachmentsReleases:
+ return ctx.Locale.Tr("settings.quota.sizes.assets.attachments.releases")
+ case quota_model.LimitSubjectSizeAssetsArtifacts:
+ return ctx.Locale.Tr("settings.quota.sizes.assets.artifacts")
+ case quota_model.LimitSubjectSizeAssetsPackagesAll:
+ return ctx.Locale.Tr("settings.quota.sizes.assets.packages.all")
+ case quota_model.LimitSubjectSizeWiki:
+ return ctx.Locale.Tr("settings.quota.sizes.wiki")
+ default:
+ panic("unrecognized subject: " + subject.String())
+ }
+ }
+
+ sizeUsed, err := quota_model.GetUsedForUser(ctx, userID)
+ if err != nil {
+ ctx.ServerError("GetUsedForUser", err)
+ return
+ }
+ ctx.Data["SizeUsed"] = sizeUsed
+
+ quotaGroups, err := quota_model.GetGroupsForUser(ctx, userID)
+ if err != nil {
+ ctx.ServerError("GetGroupsForUser", err)
+ return
+ }
+ if len(quotaGroups) == 0 {
+ quotaGroups = append(quotaGroups, "a_model.Group{
+ Name: "Global quota",
+ Rules: []quota_model.Rule{
+ {
+ Name: "Default",
+ Limit: setting.Quota.Default.Total,
+ Subjects: quota_model.LimitSubjects{quota_model.LimitSubjectSizeAll},
+ },
+ },
+ },
+ )
+ }
+ ctx.Data["QuotaGroups"] = quotaGroups
+
+ ctx.HTML(http.StatusOK, tpl)
+}
diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go
index 7d0b34cb7d..56f0de2033 100644
--- a/routers/web/shared/user/header.go
+++ b/routers/web/shared/user/header.go
@@ -1,4 +1,5 @@
// Copyright 2022 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package user
@@ -6,21 +7,22 @@ package user
import (
"net/url"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- project_model "code.gitea.io/gitea/models/project"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ packages_model "forgejo.org/models/packages"
+ access_model "forgejo.org/models/perm/access"
+ project_model "forgejo.org/models/project"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
// prepareContextForCommonProfile store some common data into context data for user's profile related pages (including the nav menu)
@@ -64,6 +66,7 @@ func PrepareContextForProfileBigAvatar(ctx *context.Context) {
showPrivate := ctx.IsSigned && (ctx.Doer.IsAdmin || ctx.Doer.ID == ctx.ContextUser.ID)
orgs, err := db.Find[organization.Organization](ctx, organization.FindOrgOptions{
UserID: ctx.ContextUser.ID,
+ IncludeLimited: ctx.IsSigned,
IncludePrivate: showPrivate,
})
if err != nil {
@@ -125,7 +128,9 @@ func RenderUserHeader(ctx *context.Context) {
func LoadHeaderCount(ctx *context.Context) error {
prepareContextForCommonProfile(ctx)
- repoCount, err := repo_model.CountRepository(ctx, &repo_model.SearchRepoOptions{
+ var err error
+
+ ctx.Data["RepoCount"], err = repo_model.CountRepository(ctx, &repo_model.SearchRepoOptions{
Actor: ctx.Doer,
OwnerID: ctx.ContextUser.ID,
Private: ctx.IsSigned,
@@ -135,7 +140,6 @@ func LoadHeaderCount(ctx *context.Context) error {
if err != nil {
return err
}
- ctx.Data["RepoCount"] = repoCount
var projectType project_model.Type
if ctx.ContextUser.IsOrganization() {
@@ -143,7 +147,7 @@ func LoadHeaderCount(ctx *context.Context) error {
} else {
projectType = project_model.TypeIndividual
}
- projectCount, err := db.Count[project_model.Project](ctx, project_model.SearchOptions{
+ ctx.Data["ProjectCount"], err = db.Count[project_model.Project](ctx, project_model.SearchOptions{
OwnerID: ctx.ContextUser.ID,
IsClosed: optional.Some(false),
Type: projectType,
@@ -151,7 +155,10 @@ func LoadHeaderCount(ctx *context.Context) error {
if err != nil {
return err
}
- ctx.Data["ProjectCount"] = projectCount
+ ctx.Data["PackageCount"], err = packages_model.CountOwnerPackages(ctx, ctx.ContextUser.ID)
+ if err != nil {
+ return err
+ }
return nil
}
diff --git a/routers/web/swagger_json.go b/routers/web/swagger_json.go
index fc39b504a9..1569600734 100644
--- a/routers/web/swagger_json.go
+++ b/routers/web/swagger_json.go
@@ -4,7 +4,7 @@
package web
import (
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/services/context"
)
// SwaggerV1Json render swagger v1 json
diff --git a/routers/web/user/avatar.go b/routers/web/user/avatar.go
index 04f510161d..76cc342770 100644
--- a/routers/web/user/avatar.go
+++ b/routers/web/user/avatar.go
@@ -7,10 +7,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/avatars"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/avatars"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/services/context"
)
func cacheableRedirect(ctx *context.Context, location string) {
diff --git a/routers/web/user/code.go b/routers/web/user/code.go
index e2e8f25661..ac1852e410 100644
--- a/routers/web/user/code.go
+++ b/routers/web/user/code.go
@@ -6,13 +6,13 @@ package user
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/base"
- code_indexer "code.gitea.io/gitea/modules/indexer/code"
- "code.gitea.io/gitea/modules/setting"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/base"
+ code_indexer "forgejo.org/modules/indexer/code"
+ "forgejo.org/modules/setting"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
)
const (
@@ -39,12 +39,19 @@ func CodeSearch(ctx *context.Context) {
language := ctx.FormTrim("l")
keyword := ctx.FormTrim("q")
+ path := ctx.FormTrim("path")
- isFuzzy := ctx.FormOptionalBool("fuzzy").ValueOrDefault(true)
+ mode := code_indexer.SearchModeExact
+ if m := ctx.FormTrim("mode"); m == "union" ||
+ m == "fuzzy" ||
+ ctx.FormBool("fuzzy") {
+ mode = code_indexer.SearchModeUnion
+ }
ctx.Data["Keyword"] = keyword
ctx.Data["Language"] = language
- ctx.Data["IsFuzzy"] = isFuzzy
+ ctx.Data["CodeSearchOptions"] = code_indexer.CodeSearchOptions
+ ctx.Data["CodeSearchMode"] = mode.String()
ctx.Data["IsCodePage"] = true
if keyword == "" {
@@ -76,10 +83,11 @@ func CodeSearch(ctx *context.Context) {
if len(repoIDs) > 0 {
total, searchResults, searchResultLanguages, err = code_indexer.PerformSearch(ctx, &code_indexer.SearchOptions{
- RepoIDs: repoIDs,
- Keyword: keyword,
- IsKeywordFuzzy: isFuzzy,
- Language: language,
+ RepoIDs: repoIDs,
+ Keyword: keyword,
+ Mode: mode,
+ Language: language,
+ Filename: path,
Paginator: &db.ListOptions{
Page: page,
PageSize: setting.UI.RepoSearchPagingNum,
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index 1a8a9a4126..9f22cebaba 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -10,33 +10,33 @@ import (
"net/http"
"regexp"
"slices"
- "sort"
"strconv"
"strings"
- activities_model "code.gitea.io/gitea/models/activities"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/container"
- issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/routers/web/feed"
- "code.gitea.io/gitea/services/context"
- issue_service "code.gitea.io/gitea/services/issue"
- pull_service "code.gitea.io/gitea/services/pull"
+ activities_model "forgejo.org/models/activities"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/container"
+ issue_indexer "forgejo.org/modules/indexer/issues"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/routers/web/feed"
+ "forgejo.org/services/context"
+ issue_service "forgejo.org/services/issue"
+ pull_service "forgejo.org/services/pull"
- "github.com/keybase/go-crypto/openpgp"
- "github.com/keybase/go-crypto/openpgp/armor"
+ "github.com/ProtonMail/go-crypto/openpgp"
+ "github.com/ProtonMail/go-crypto/openpgp/armor"
"xorm.io/builder"
)
@@ -90,6 +90,8 @@ func Dashboard(ctx *context.Context) {
cnt, _ := organization.GetOrganizationCount(ctx, ctxUser)
ctx.Data["UserOrgsCount"] = cnt
ctx.Data["MirrorsEnabled"] = setting.Mirror.Enabled
+ ctx.Data["UsersPageIsDisabled"] = setting.Service.Explore.DisableUsersPage
+ ctx.Data["OrganizationsPageIsDisabled"] = setting.Service.Explore.DisableOrganizationsPage
ctx.Data["Date"] = date
var uid int64
@@ -241,7 +243,9 @@ func Milestones(ctx *context.Context) {
ctx.ServerError("SearchRepositoryByCondition", err)
return
}
- sort.Sort(showRepos)
+ slices.SortFunc(showRepos, func(a, b *repo_model.Repository) int {
+ return strings.Compare(a.FullName(), b.FullName())
+ })
for i := 0; i < len(milestones); {
for _, repo := range showRepos {
@@ -379,9 +383,11 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
}
var (
- viewType string
- sortType = ctx.FormString("sort")
- filterMode int
+ viewType string
+ sortType = ctx.FormString("sort")
+ filterMode int
+ defaultFilterMode int
+ defaultViewType string
)
// Default to recently updated, unlike repository issues list
@@ -402,12 +408,22 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
// TODO: distinguish during routing
+ // Default to created_by on /pulls and /issues
+ // because it is most relevant to the user in the global context
+ if ctx.Org == nil || ctx.Org.Organization == nil {
+ defaultFilterMode = issues_model.FilterModeCreate
+ defaultViewType = "created_by"
+ } else {
+ // Default to your_repositories on /org/*/pulls and /org/*/issues
+ // because it is the most relevant to the user in the context of an org
+ defaultFilterMode = issues_model.FilterModeYourRepositories
+ defaultViewType = "your_repositories"
+ }
+
viewType = ctx.FormString("type")
switch viewType {
case "assigned":
filterMode = issues_model.FilterModeAssign
- case "created_by":
- filterMode = issues_model.FilterModeCreate
case "mentioned":
filterMode = issues_model.FilterModeMention
case "review_requested":
@@ -415,10 +431,12 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
case "reviewed_by":
filterMode = issues_model.FilterModeReviewed
case "your_repositories":
+ filterMode = issues_model.FilterModeYourRepositories
+ case "created_by":
fallthrough
default:
- filterMode = issues_model.FilterModeYourRepositories
- viewType = "your_repositories"
+ filterMode = defaultFilterMode
+ viewType = defaultViewType
}
// --------------------------------------------------------------------------
@@ -447,8 +465,6 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
User: ctx.Doer,
}
- isFuzzy := ctx.FormBool("fuzzy")
-
// Search all repositories which
//
// As user:
@@ -578,9 +594,7 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
// USING FINAL STATE OF opts FOR A QUERY.
var issues issues_model.IssueList
{
- issueIDs, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts).Copy(
- func(o *issue_indexer.SearchOptions) { o.IsFuzzyKeyword = isFuzzy },
- ))
+ issueIDs, _, err := issue_indexer.SearchIssues(ctx, issue_indexer.ToSearchOptions(keyword, opts))
if err != nil {
ctx.ServerError("issueIDsFromSearch", err)
return
@@ -597,13 +611,16 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
ctx.ServerError("GetIssuesLastCommitStatus", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for key := range commitStatuses {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key])
+ }
+ }
// -------------------------------
// Fill stats to post to ctx.Data.
// -------------------------------
- issueStats, err := getUserIssueStats(ctx, ctxUser, filterMode, issue_indexer.ToSearchOptions(keyword, opts).Copy(
- func(o *issue_indexer.SearchOptions) { o.IsFuzzyKeyword = isFuzzy },
- ))
+ issueStats, err := getUserIssueStats(ctx, ctxUser, filterMode, issue_indexer.ToSearchOptions(keyword, opts))
if err != nil {
ctx.ServerError("getUserIssueStats", err)
return
@@ -658,7 +675,6 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
ctx.Data["IsShowClosed"] = isShowClosed
ctx.Data["SelectLabels"] = selectedLabels
ctx.Data["PageIsOrgIssues"] = org != nil
- ctx.Data["IsFuzzy"] = isFuzzy
if isShowClosed {
ctx.Data["State"] = "closed"
@@ -674,7 +690,6 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
pager.AddParam(ctx, "labels", "SelectLabels")
pager.AddParam(ctx, "milestone", "MilestoneID")
pager.AddParam(ctx, "assignee", "AssigneeID")
- pager.AddParam(ctx, "fuzzy", "IsFuzzy")
ctx.Data["Page"] = pager
ctx.HTML(http.StatusOK, tplIssues)
@@ -755,7 +770,7 @@ func UsernameSubRoute(ctx *context.Context) {
}
// check view permissions
if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) {
- ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name))
+ ctx.NotFound("User not visible", nil)
return false
}
return true
diff --git a/routers/web/user/home_test.go b/routers/web/user/home_test.go
index a59afce12c..af9d50538d 100644
--- a/routers/web/user/home_test.go
+++ b/routers/web/user/home_test.go
@@ -7,26 +7,28 @@ import (
"net/http"
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/contexttest"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/services/context"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestArchivedIssues(t *testing.T) {
// Arrange
setting.UI.IssuePagingNum = 1
- assert.NoError(t, unittest.LoadFixtures())
+ require.NoError(t, unittest.LoadFixtures())
ctx, _ := contexttest.MockContext(t, "issues")
contexttest.LoadUser(t, ctx, 30)
ctx.Req.Form.Set("state", "open")
+ ctx.Req.Form.Set("type", "your_repositories")
// Assume: User 30 has access to two Repos with Issues, one of the Repos being archived.
repos, _, _ := repo_model.GetUserRepositories(db.DefaultContext, &repo_model.SearchRepoOptions{Actor: ctx.Doer})
@@ -53,7 +55,7 @@ func TestArchivedIssues(t *testing.T) {
func TestIssues(t *testing.T) {
setting.UI.IssuePagingNum = 1
- assert.NoError(t, unittest.LoadFixtures())
+ require.NoError(t, unittest.LoadFixtures())
ctx, _ := contexttest.MockContext(t, "issues")
contexttest.LoadUser(t, ctx, 2)
@@ -67,11 +69,12 @@ func TestIssues(t *testing.T) {
func TestPulls(t *testing.T) {
setting.UI.IssuePagingNum = 20
- assert.NoError(t, unittest.LoadFixtures())
+ require.NoError(t, unittest.LoadFixtures())
ctx, _ := contexttest.MockContext(t, "pulls")
contexttest.LoadUser(t, ctx, 2)
ctx.Req.Form.Set("state", "open")
+ ctx.Req.Form.Set("type", "your_repositories")
Pulls(ctx)
assert.EqualValues(t, http.StatusOK, ctx.Resp.Status())
@@ -80,7 +83,7 @@ func TestPulls(t *testing.T) {
func TestMilestones(t *testing.T) {
setting.UI.IssuePagingNum = 1
- assert.NoError(t, unittest.LoadFixtures())
+ require.NoError(t, unittest.LoadFixtures())
ctx, _ := contexttest.MockContext(t, "milestones")
contexttest.LoadUser(t, ctx, 2)
@@ -95,11 +98,13 @@ func TestMilestones(t *testing.T) {
assert.EqualValues(t, 1, ctx.Data["Total"])
assert.Len(t, ctx.Data["Milestones"], 1)
assert.Len(t, ctx.Data["Repos"], 2) // both repo 42 and 1 have milestones and both are owned by user 2
+ assert.EqualValues(t, "user2/glob", ctx.Data["Repos"].(repo_model.RepositoryList)[0].FullName())
+ assert.EqualValues(t, "user2/repo1", ctx.Data["Repos"].(repo_model.RepositoryList)[1].FullName())
}
func TestMilestonesForSpecificRepo(t *testing.T) {
setting.UI.IssuePagingNum = 1
- assert.NoError(t, unittest.LoadFixtures())
+ require.NoError(t, unittest.LoadFixtures())
ctx, _ := contexttest.MockContext(t, "milestones")
contexttest.LoadUser(t, ctx, 2)
@@ -123,17 +128,17 @@ func TestDashboardPagination(t *testing.T) {
setting.AppSubURL = "/SubPath"
out, err := ctx.RenderToHTML("base/paginate", map[string]any{"Link": setting.AppSubURL, "Page": page})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Contains(t, out, ``)
setting.AppSubURL = ""
out, err = ctx.RenderToHTML("base/paginate", map[string]any{"Link": setting.AppSubURL, "Page": page})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Contains(t, out, ` `)
}
func TestOrgLabels(t *testing.T) {
- assert.NoError(t, unittest.LoadFixtures())
+ require.NoError(t, unittest.LoadFixtures())
ctx, _ := contexttest.MockContext(t, "org/org3/issues")
contexttest.LoadUser(t, ctx, 2)
diff --git a/routers/web/user/main_test.go b/routers/web/user/main_test.go
index 8b6ae69296..080e3fdcfe 100644
--- a/routers/web/user/main_test.go
+++ b/routers/web/user/main_test.go
@@ -6,7 +6,7 @@ package user
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go
index 2105cfe5c5..296951b2ff 100644
--- a/routers/web/user/notification.go
+++ b/routers/web/user/notification.go
@@ -11,19 +11,21 @@ import (
"net/url"
"strings"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
- issue_service "code.gitea.io/gitea/services/issue"
- pull_service "code.gitea.io/gitea/services/pull"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
+ issue_service "forgejo.org/services/issue"
+ pull_service "forgejo.org/services/pull"
)
const (
@@ -109,20 +111,26 @@ func getNotifications(ctx *context.Context) {
return
}
- statuses := []activities_model.NotificationStatus{status, activities_model.NotificationStatusPinned}
- nls, err := db.Find[activities_model.Notification](ctx, activities_model.FindNotificationOptions{
- ListOptions: db.ListOptions{
- PageSize: perPage,
- Page: page,
- },
- UserID: ctx.Doer.ID,
- Status: statuses,
- })
- if err != nil {
- ctx.ServerError("db.Find[activities_model.Notification]", err)
- return
+ sess := db.GetEngine(ctx).Table("notification")
+ if setting.Database.Type.IsMySQL() {
+ sess = sess.IndexHint("USE", "", "IDX_notification_user_id")
+ }
+ sess.Where("user_id = ?", ctx.Doer.ID).
+ And("status = ? OR status = ?", status, activities_model.NotificationStatusPinned).
+ OrderBy("notification.updated_unix DESC")
+
+ if perPage > 0 {
+ if page == 0 {
+ page = 1
+ }
+ sess.Limit(perPage, (page-1)*perPage)
}
+ nls := make([]*activities_model.Notification, 0, perPage)
+ if err := sess.Find(&nls); err != nil {
+ ctx.ServerError("FindNotifications", err)
+ return
+ }
notifications := activities_model.NotificationList(nls)
failCount := 0
@@ -303,6 +311,11 @@ func NotificationSubscriptions(ctx *context.Context) {
ctx.ServerError("GetIssuesAllCommitStatus", err)
return
}
+ if !ctx.Repo.CanRead(unit.TypeActions) {
+ for key := range commitStatuses {
+ git_model.CommitStatusesHideActionsURL(ctx, commitStatuses[key])
+ }
+ }
ctx.Data["CommitLastStatus"] = lastStatus
ctx.Data["CommitStatuses"] = commitStatuses
ctx.Data["Issues"] = issues
@@ -439,6 +452,21 @@ func NotificationWatching(ctx *context.Context) {
// redirect to last page if request page is more than total pages
pager := context.NewPagination(total, setting.UI.User.RepoPagingNum, page, 5)
pager.SetDefaultParams(ctx)
+ if archived.Has() {
+ pager.AddParamString("archived", fmt.Sprint(archived.Value()))
+ }
+ if fork.Has() {
+ pager.AddParamString("fork", fmt.Sprint(fork.Value()))
+ }
+ if mirror.Has() {
+ pager.AddParamString("mirror", fmt.Sprint(mirror.Value()))
+ }
+ if template.Has() {
+ pager.AddParamString("template", fmt.Sprint(template.Value()))
+ }
+ if private.Has() {
+ pager.AddParamString("private", fmt.Sprint(private.Value()))
+ }
ctx.Data["Page"] = pager
ctx.Data["Status"] = 2
diff --git a/routers/web/user/package.go b/routers/web/user/package.go
index 3ecc59a2ab..2862c6684b 100644
--- a/routers/web/user/package.go
+++ b/routers/web/user/package.go
@@ -4,30 +4,32 @@
package user
import (
+ "fmt"
"net/http"
+ "slices"
- "code.gitea.io/gitea/models/db"
- org_model "code.gitea.io/gitea/models/organization"
- packages_model "code.gitea.io/gitea/models/packages"
- container_model "code.gitea.io/gitea/models/packages/container"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- alpine_module "code.gitea.io/gitea/modules/packages/alpine"
- debian_module "code.gitea.io/gitea/modules/packages/debian"
- rpm_module "code.gitea.io/gitea/modules/packages/rpm"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- packages_helper "code.gitea.io/gitea/routers/api/packages/helper"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/db"
+ org_model "forgejo.org/models/organization"
+ packages_model "forgejo.org/models/packages"
+ container_model "forgejo.org/models/packages/container"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ alpine_module "forgejo.org/modules/packages/alpine"
+ arch_model "forgejo.org/modules/packages/arch"
+ debian_module "forgejo.org/modules/packages/debian"
+ rpm_module "forgejo.org/modules/packages/rpm"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ packages_helper "forgejo.org/routers/api/packages/helper"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ packages_service "forgejo.org/services/packages"
)
const (
@@ -175,10 +177,11 @@ func ViewPackageVersion(ctx *context.Context) {
ctx.Data["Title"] = pd.Package.Name
ctx.Data["IsPackagesPage"] = true
ctx.Data["PackageDescriptor"] = pd
+ ctx.Data["PackageRegistryHost"] = setting.Packages.RegistryHost
switch pd.Package.Type {
case packages_model.TypeContainer:
- ctx.Data["RegistryHost"] = setting.Packages.RegistryHost
+
case packages_model.TypeAlpine:
branches := make(container.Set[string])
repositories := make(container.Set[string])
@@ -197,9 +200,20 @@ func ViewPackageVersion(ctx *context.Context) {
}
}
- ctx.Data["Branches"] = util.Sorted(branches.Values())
- ctx.Data["Repositories"] = util.Sorted(repositories.Values())
- ctx.Data["Architectures"] = util.Sorted(architectures.Values())
+ ctx.Data["Branches"] = slices.Sorted(branches.Seq())
+ ctx.Data["Repositories"] = slices.Sorted(repositories.Seq())
+ ctx.Data["Architectures"] = slices.Sorted(architectures.Seq())
+ case packages_model.TypeArch:
+ ctx.Data["SignMail"] = fmt.Sprintf("%s@noreply.%s", ctx.Package.Owner.Name, setting.Packages.RegistryHost)
+ groups := make(container.Set[string])
+ for _, f := range pd.Files {
+ for _, pp := range f.Properties {
+ if pp.Name == arch_model.PropertyDistribution {
+ groups.Add(pp.Value)
+ }
+ }
+ }
+ ctx.Data["Groups"] = slices.Sorted(groups.Seq())
case packages_model.TypeDebian:
distributions := make(container.Set[string])
components := make(container.Set[string])
@@ -218,10 +232,10 @@ func ViewPackageVersion(ctx *context.Context) {
}
}
- ctx.Data["Distributions"] = util.Sorted(distributions.Values())
- ctx.Data["Components"] = util.Sorted(components.Values())
- ctx.Data["Architectures"] = util.Sorted(architectures.Values())
- case packages_model.TypeRpm:
+ ctx.Data["Distributions"] = slices.Sorted(distributions.Seq())
+ ctx.Data["Components"] = slices.Sorted(components.Seq())
+ ctx.Data["Architectures"] = slices.Sorted(architectures.Seq())
+ case packages_model.TypeRpm, packages_model.TypeAlt:
groups := make(container.Set[string])
architectures := make(container.Set[string])
@@ -236,8 +250,8 @@ func ViewPackageVersion(ctx *context.Context) {
}
}
- ctx.Data["Groups"] = util.Sorted(groups.Values())
- ctx.Data["Architectures"] = util.Sorted(architectures.Values())
+ ctx.Data["Groups"] = slices.Sorted(groups.Seq())
+ ctx.Data["Architectures"] = slices.Sorted(architectures.Seq())
}
var (
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index a83d7f7333..5132b1da5c 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -11,23 +11,23 @@ import (
"path"
"strings"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/web/feed"
- "code.gitea.io/gitea/routers/web/org"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
- user_service "code.gitea.io/gitea/services/user"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/routers/web/feed"
+ "forgejo.org/routers/web/org"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
+ user_service "forgejo.org/services/user"
)
const (
@@ -56,13 +56,19 @@ func OwnerProfile(ctx *context.Context) {
func userProfile(ctx *context.Context) {
// check view permissions
if !user_model.IsUserVisibleToViewer(ctx, ctx.ContextUser, ctx.Doer) {
- ctx.NotFound("user", fmt.Errorf(ctx.ContextUser.Name))
+ ctx.NotFound("User not visible", nil)
return
}
ctx.Data["Title"] = ctx.ContextUser.DisplayName()
ctx.Data["PageIsUserProfile"] = true
+ ctx.Data["OpenGraphTitle"] = ctx.ContextUser.DisplayName()
+ ctx.Data["OpenGraphType"] = "profile"
+ ctx.Data["OpenGraphImageURL"] = ctx.ContextUser.AvatarLink(ctx)
+ ctx.Data["OpenGraphURL"] = ctx.ContextUser.HTMLURL()
+ ctx.Data["OpenGraphDescription"] = ctx.ContextUser.Description
+
// prepare heatmap data
if setting.Service.EnableUserHeatmap {
data, err := activities_model.GetUserHeatmapDataByUser(ctx, ctx.ContextUser, ctx.Doer)
@@ -112,32 +118,12 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
orderBy db.SearchOrderBy
)
- ctx.Data["SortType"] = ctx.FormString("sort")
- switch ctx.FormString("sort") {
- case "newest":
- orderBy = db.SearchOrderByNewest
- case "oldest":
- orderBy = db.SearchOrderByOldest
- case "recentupdate":
- orderBy = db.SearchOrderByRecentUpdated
- case "leastupdate":
- orderBy = db.SearchOrderByLeastUpdated
- case "reversealphabetically":
- orderBy = db.SearchOrderByAlphabeticallyReverse
- case "alphabetically":
- orderBy = db.SearchOrderByAlphabetically
- case "moststars":
- orderBy = db.SearchOrderByStarsReverse
- case "feweststars":
- orderBy = db.SearchOrderByStars
- case "mostforks":
- orderBy = db.SearchOrderByForksReverse
- case "fewestforks":
- orderBy = db.SearchOrderByForks
- default:
- ctx.Data["SortType"] = "recentupdate"
- orderBy = db.SearchOrderByRecentUpdated
+ sortOrder := ctx.FormString("sort")
+ if _, ok := repo_model.OrderByFlatMap[sortOrder]; !ok {
+ sortOrder = setting.UI.ExploreDefaultSort // TODO: add new default sort order for user home?
}
+ ctx.Data["SortType"] = sortOrder
+ orderBy = repo_model.OrderByFlatMap[sortOrder]
keyword := ctx.FormTrim("q")
ctx.Data["Keyword"] = keyword
@@ -335,13 +321,27 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileDb
if tab == "activity" {
pager.AddParam(ctx, "date", "Date")
}
+ if archived.Has() {
+ pager.AddParamString("archived", fmt.Sprint(archived.Value()))
+ }
+ if fork.Has() {
+ pager.AddParamString("fork", fmt.Sprint(fork.Value()))
+ }
+ if mirror.Has() {
+ pager.AddParamString("mirror", fmt.Sprint(mirror.Value()))
+ }
+ if template.Has() {
+ pager.AddParamString("template", fmt.Sprint(template.Value()))
+ }
+ if private.Has() {
+ pager.AddParamString("private", fmt.Sprint(private.Value()))
+ }
ctx.Data["Page"] = pager
}
// Action response for follow/unfollow user request
func Action(ctx *context.Context) {
var err error
- var redirectViaJSON bool
action := ctx.FormString("action")
if ctx.ContextUser.IsOrganization() && (action == "block" || action == "unblock") {
@@ -357,10 +357,8 @@ func Action(ctx *context.Context) {
err = user_model.UnfollowUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
case "block":
err = user_service.BlockUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
- redirectViaJSON = true
case "unblock":
err = user_model.UnblockUser(ctx, ctx.Doer.ID, ctx.ContextUser.ID)
- redirectViaJSON = true
}
if err != nil {
@@ -371,21 +369,15 @@ func Action(ctx *context.Context) {
}
if ctx.ContextUser.IsOrganization() {
- ctx.Flash.Error(ctx.Tr("org.follow_blocked_user"))
+ ctx.Flash.Error(ctx.Tr("org.follow_blocked_user"), true)
} else {
- ctx.Flash.Error(ctx.Tr("user.follow_blocked_user"))
+ ctx.Flash.Error(ctx.Tr("user.follow_blocked_user"), true)
}
}
- if redirectViaJSON {
- ctx.JSON(http.StatusOK, map[string]any{
- "redirect": ctx.ContextUser.HomeLink(),
- })
- return
- }
-
if ctx.ContextUser.IsIndividual() {
shared_user.PrepareContextForProfileBigAvatar(ctx)
+ ctx.Data["IsHTMX"] = true
ctx.HTML(http.StatusOK, tplProfileBigAvatar)
return
} else if ctx.ContextUser.IsOrganization() {
diff --git a/routers/web/user/search.go b/routers/web/user/search.go
index fb7729bbe1..411a356d9b 100644
--- a/routers/web/user/search.go
+++ b/routers/web/user/search.go
@@ -6,39 +6,26 @@ package user
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
-// Search search users
-func Search(ctx *context.Context) {
- listOptions := db.ListOptions{
- Page: ctx.FormInt("page"),
- PageSize: convert.ToCorrectPageSize(ctx.FormInt("limit")),
- }
-
- users, maxResults, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
+// SearchCandidates searches candidate users for dropdown list
+func SearchCandidates(ctx *context.Context) {
+ users, _, err := user_model.SearchUsers(ctx, &user_model.SearchUserOptions{
Actor: ctx.Doer,
Keyword: ctx.FormTrim("q"),
- UID: ctx.FormInt64("uid"),
Type: user_model.UserTypeIndividual,
- IsActive: ctx.FormOptionalBool("active"),
- ListOptions: listOptions,
+ IsActive: optional.Some(true),
+ ListOptions: db.ListOptions{PageSize: setting.UI.MembersPagingNum},
})
if err != nil {
- ctx.JSON(http.StatusInternalServerError, map[string]any{
- "ok": false,
- "error": err.Error(),
- })
+ ctx.ServerError("Unable to search users", err)
return
}
-
- ctx.SetTotalCountHeader(maxResults)
-
- ctx.JSON(http.StatusOK, map[string]any{
- "ok": true,
- "data": convert.ToUsers(ctx, ctx.Doer, users),
- })
+ ctx.JSON(http.StatusOK, map[string]any{"data": convert.ToUsers(ctx, ctx.Doer, users)})
}
diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go
index 795ee59d58..a0cdb25f44 100644
--- a/routers/web/user/setting/account.go
+++ b/routers/web/user/setting/account.go
@@ -9,22 +9,23 @@ import (
"net/http"
"time"
- "code.gitea.io/gitea/models"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/password"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/db"
- "code.gitea.io/gitea/services/auth/source/smtp"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/mailer"
- "code.gitea.io/gitea/services/user"
+ "forgejo.org/models"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/password"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/db"
+ "forgejo.org/services/auth/source/smtp"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/mailer"
+ "forgejo.org/services/user"
)
const (
@@ -72,7 +73,7 @@ func AccountPost(ctx *context.Context) {
case errors.Is(err, password.ErrComplexity):
ctx.Flash.Error(password.BuildComplexityError(ctx.Locale))
case errors.Is(err, password.ErrIsPwned):
- ctx.Flash.Error(ctx.Tr("auth.password_pwned"))
+ ctx.Flash.Error(ctx.Tr("auth.password_pwned", "https://haveibeenpwned.com/Passwords"))
case password.IsErrIsPwnedRequest(err):
ctx.Flash.Error(ctx.Tr("auth.password_pwned_err"))
default:
@@ -104,7 +105,15 @@ func EmailPost(ctx *context.Context) {
// Make emailaddress primary.
if ctx.FormString("_method") == "PRIMARY" {
- if err := user_model.MakeEmailPrimary(ctx, &user_model.EmailAddress{ID: ctx.FormInt64("id")}); err != nil {
+ id := ctx.FormInt64("id")
+ email, err := user_model.GetEmailAddressByID(ctx, ctx.Doer.ID, id)
+ if err != nil {
+ log.Error("GetEmailAddressByID(%d,%d) error: %v", ctx.Doer.ID, id, err)
+ ctx.Redirect(setting.AppSubURL + "/user/settings/account")
+ return
+ }
+
+ if err := user.MakeEmailAddressPrimary(ctx, ctx.Doer, email, true); err != nil {
ctx.ServerError("MakeEmailPrimary", err)
return
}
@@ -146,9 +155,15 @@ func EmailPost(ctx *context.Context) {
return
}
// Only fired when the primary email is inactive (Wrong state)
- mailer.SendActivateAccountMail(ctx.Locale, ctx.Doer)
+ if err := mailer.SendActivateAccountMail(ctx, ctx.Doer); err != nil {
+ ctx.ServerError("SendActivateAccountMail", err)
+ return
+ }
} else {
- mailer.SendActivateEmailMail(ctx.Doer, email.Email)
+ if err := mailer.SendActivateEmailMail(ctx, ctx.Doer, email.Email); err != nil {
+ ctx.ServerError("SendActivateEmailMail", err)
+ return
+ }
}
address = email.Email
@@ -197,7 +212,7 @@ func EmailPost(ctx *context.Context) {
loadAccountData(ctx)
ctx.RenderWithErr(ctx.Tr("form.email_been_used"), tplSettingsAccount, &form)
- } else if user_model.IsErrEmailCharIsNotSupported(err) || user_model.IsErrEmailInvalid(err) {
+ } else if validation.IsErrEmailCharIsNotSupported(err) || validation.IsErrEmailInvalid(err) {
loadAccountData(ctx)
ctx.RenderWithErr(ctx.Tr("form.email_invalid"), tplSettingsAccount, &form)
@@ -209,7 +224,10 @@ func EmailPost(ctx *context.Context) {
// Send confirmation email
if setting.Service.RegisterEmailConfirm {
- mailer.SendActivateEmailMail(ctx.Doer, form.Email)
+ if err := mailer.SendActivateEmailMail(ctx, ctx.Doer, form.Email); err != nil {
+ ctx.ServerError("SendActivateEmailMail", err)
+ return
+ }
if err := ctx.Cache.Put("MailResendLimit_"+ctx.Doer.LowerName, ctx.Doer.LowerName, 180); err != nil {
log.Error("Set cache(MailResendLimit) fail: %v", err)
}
diff --git a/routers/web/user/setting/account_test.go b/routers/web/user/setting/account_test.go
index 9fdc5e4d53..82e00bbf7c 100644
--- a/routers/web/user/setting/account_test.go
+++ b/routers/web/user/setting/account_test.go
@@ -7,11 +7,11 @@ import (
"net/http"
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/contexttest"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/contexttest"
+ "forgejo.org/services/forms"
"github.com/stretchr/testify/assert"
)
diff --git a/routers/web/user/setting/adopt.go b/routers/web/user/setting/adopt.go
index 171c1933d4..f7fd1c3803 100644
--- a/routers/web/user/setting/adopt.go
+++ b/routers/web/user/setting/adopt.go
@@ -6,12 +6,12 @@ package setting
import (
"path/filepath"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context"
- repo_service "code.gitea.io/gitea/services/repository"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/context"
+ repo_service "forgejo.org/services/repository"
)
// AdoptOrDeleteRepository adopts or deletes a repository
diff --git a/routers/web/user/setting/applications.go b/routers/web/user/setting/applications.go
index e3822ca988..631d5958ea 100644
--- a/routers/web/user/setting/applications.go
+++ b/routers/web/user/setting/applications.go
@@ -7,13 +7,14 @@ package setting
import (
"net/http"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
const (
@@ -87,6 +88,23 @@ func DeleteApplication(ctx *context.Context) {
ctx.JSONRedirect(setting.AppSubURL + "/user/settings/applications")
}
+// RegenerateApplication response for regenerating user access token
+func RegenerateApplication(ctx *context.Context) {
+ if t, err := auth_model.RegenerateAccessTokenByID(ctx, ctx.FormInt64("id"), ctx.Doer.ID); err != nil {
+ if auth_model.IsErrAccessTokenNotExist(err) {
+ ctx.Flash.Error(ctx.Tr("error.not_found"))
+ } else {
+ ctx.Flash.Error(ctx.Tr("error.server_internal"))
+ log.Error("DeleteAccessTokenByID", err)
+ }
+ } else {
+ ctx.Flash.Success(ctx.Tr("settings.regenerate_token_success"))
+ ctx.Flash.Info(t.Token)
+ }
+
+ ctx.JSONRedirect(setting.AppSubURL + "/user/settings/applications")
+}
+
func loadApplicationsData(ctx *context.Context) {
ctx.Data["AccessTokenScopePublicOnly"] = auth_model.AccessTokenScopePublicOnly
tokens, err := db.Find[auth_model.AccessToken](ctx, auth_model.ListAccessTokensOptions{UserID: ctx.Doer.ID})
@@ -110,5 +128,6 @@ func loadApplicationsData(ctx *context.Context) {
ctx.ServerError("GetOAuth2GrantsByUserID", err)
return
}
+ ctx.Data["EnableAdditionalGrantScopes"] = setting.OAuth2.EnableAdditionalGrantScopes
}
}
diff --git a/routers/web/user/setting/blocked_users.go b/routers/web/user/setting/blocked_users.go
index 3f35b2eadf..1448dc9a3c 100644
--- a/routers/web/user/setting/blocked_users.go
+++ b/routers/web/user/setting/blocked_users.go
@@ -6,11 +6,11 @@ package setting
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go
index 9462be71c2..94d32b730f 100644
--- a/routers/web/user/setting/keys.go
+++ b/routers/web/user/setting/keys.go
@@ -8,15 +8,15 @@ import (
"fmt"
"net/http"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ asymkey_service "forgejo.org/services/asymkey"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
const (
diff --git a/routers/web/user/setting/main_test.go b/routers/web/user/setting/main_test.go
index e398208d0d..38ac2842dd 100644
--- a/routers/web/user/setting/main_test.go
+++ b/routers/web/user/setting/main_test.go
@@ -6,7 +6,7 @@ package setting
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/routers/web/user/setting/oauth2.go b/routers/web/user/setting/oauth2.go
index 1f485e06c8..64b252e97f 100644
--- a/routers/web/user/setting/oauth2.go
+++ b/routers/web/user/setting/oauth2.go
@@ -4,9 +4,9 @@
package setting
import (
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/user/setting/oauth2_common.go b/routers/web/user/setting/oauth2_common.go
index 85d1e820a5..7449e45216 100644
--- a/routers/web/user/setting/oauth2_common.go
+++ b/routers/web/user/setting/oauth2_common.go
@@ -7,13 +7,13 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- shared_user "code.gitea.io/gitea/routers/web/shared/user"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/auth"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ shared_user "forgejo.org/routers/web/shared/user"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
type OAuth2CommonHandlers struct {
@@ -47,7 +47,6 @@ func (oa *OAuth2CommonHandlers) AddApp(ctx *context.Context) {
return
}
- // TODO validate redirect URI
app, err := auth.CreateOAuth2Application(ctx, auth.CreateOAuth2ApplicationOptions{
Name: form.Name,
RedirectURIs: util.SplitTrimSpace(form.RedirectURIs, "\n"),
@@ -95,11 +94,25 @@ func (oa *OAuth2CommonHandlers) EditSave(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.EditOAuth2ApplicationForm)
if ctx.HasError() {
+ app, err := auth.GetOAuth2ApplicationByID(ctx, ctx.ParamsInt64("id"))
+ if err != nil {
+ if auth.IsErrOAuthApplicationNotFound(err) {
+ ctx.NotFound("Application not found", err)
+ return
+ }
+ ctx.ServerError("GetOAuth2ApplicationByID", err)
+ return
+ }
+ if app.UID != oa.OwnerID {
+ ctx.NotFound("Application not found", nil)
+ return
+ }
+ ctx.Data["App"] = app
+
oa.renderEditPage(ctx)
return
}
- // TODO validate redirect URI
var err error
if ctx.Data["App"], err = auth.UpdateOAuth2Application(ctx, auth.UpdateOAuth2ApplicationOptions{
ID: ctx.ParamsInt64("id"),
diff --git a/routers/web/user/setting/packages.go b/routers/web/user/setting/packages.go
index 4132659495..ba739a03fc 100644
--- a/routers/web/user/setting/packages.go
+++ b/routers/web/user/setting/packages.go
@@ -7,13 +7,13 @@ import (
"net/http"
"strings"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- chef_module "code.gitea.io/gitea/modules/packages/chef"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- shared "code.gitea.io/gitea/routers/web/shared/packages"
- "code.gitea.io/gitea/services/context"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ chef_module "forgejo.org/modules/packages/chef"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ shared "forgejo.org/routers/web/shared/packages"
+ "forgejo.org/services/context"
)
const (
diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go
index 907f0f5061..173550ad19 100644
--- a/routers/web/user/setting/profile.go
+++ b/routers/web/user/setting/profile.go
@@ -12,26 +12,26 @@ import (
"net/http"
"os"
"path/filepath"
- "slices"
"strings"
+ "time"
- "code.gitea.io/gitea/models/avatars"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/typesniffer"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- user_service "code.gitea.io/gitea/services/user"
+ "forgejo.org/models/avatars"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/typesniffer"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ user_service "forgejo.org/services/user"
)
const (
@@ -41,8 +41,7 @@ const (
tplSettingsRepositories base.TplName = "user/settings/repos"
)
-// must be kept in sync with `web_src/js/features/user-settings.js`
-var recognisedPronouns = []string{"", "he/him", "she/her", "they/them", "it/its", "any pronouns"}
+var commonPronouns = []string{"he/him", "she/her", "they/them", "it/its", "any pronouns"}
// Profile render user's profile page
func Profile(ctx *context.Context) {
@@ -50,7 +49,8 @@ func Profile(ctx *context.Context) {
ctx.Data["PageIsSettingsProfile"] = true
ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice()
ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx)
- ctx.Data["PronounsAreCustom"] = !slices.Contains(recognisedPronouns, ctx.Doer.Pronouns)
+ ctx.Data["CooldownPeriod"] = setting.Service.UsernameCooldownPeriod
+ ctx.Data["CommonPronouns"] = commonPronouns
ctx.HTML(http.StatusOK, tplSettingsProfile)
}
@@ -61,7 +61,8 @@ func ProfilePost(ctx *context.Context) {
ctx.Data["PageIsSettingsProfile"] = true
ctx.Data["AllowedUserVisibilityModes"] = setting.Service.AllowedUserVisibilityModesSlice.ToVisibleTypeSlice()
ctx.Data["DisableGravatar"] = setting.Config().Picture.DisableGravatar.Value(ctx)
- ctx.Data["PronounsAreCustom"] = !slices.Contains(recognisedPronouns, ctx.Doer.Pronouns)
+ ctx.Data["CooldownPeriod"] = setting.Service.UsernameCooldownPeriod
+ ctx.Data["CommonPronouns"] = commonPronouns
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplSettingsProfile)
@@ -77,6 +78,8 @@ func ProfilePost(ctx *context.Context) {
ctx.Flash.Error(ctx.Tr("form.username_change_not_local_user"))
case user_model.IsErrUserAlreadyExist(err):
ctx.Flash.Error(ctx.Tr("form.username_been_taken"))
+ case user_model.IsErrCooldownPeriod(err):
+ ctx.Flash.Error(ctx.Tr("form.username_claiming_cooldown", err.(user_model.ErrCooldownPeriod).ExpireTime.Format(time.RFC1123Z)))
case db.IsErrNameReserved(err):
ctx.Flash.Error(ctx.Tr("user.form.name_reserved", form.Name))
case db.IsErrNamePatternNotAllowed(err):
@@ -101,6 +104,7 @@ func ProfilePost(ctx *context.Context) {
Location: optional.Some(form.Location),
Visibility: optional.Some(form.Visibility),
KeepActivityPrivate: optional.Some(form.KeepActivityPrivate),
+ KeepPronounsPrivate: optional.Some(form.KeepPronounsPrivate),
}
if err := user_service.UpdateUser(ctx, ctx.Doer, opts); err != nil {
ctx.ServerError("UpdateUser", err)
@@ -325,6 +329,14 @@ func Repos(ctx *context.Context) {
func Appearance(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("settings.appearance")
ctx.Data["PageIsSettingsAppearance"] = true
+ ctx.Data["AllThemes"] = setting.UI.Themes
+ ctx.Data["ThemeName"] = func(themeName string) string {
+ fullThemeName := "themes.names." + themeName
+ if ctx.Locale.HasKey(fullThemeName) {
+ return ctx.Locale.TrString(fullThemeName)
+ }
+ return themeName
+ }
var hiddenCommentTypes *big.Int
val, err := user_model.GetUserSetting(ctx, ctx.Doer.ID, user_model.SettingsKeyHiddenCommentTypes)
diff --git a/routers/web/user/setting/runner.go b/routers/web/user/setting/runner.go
index 2bb10cceb9..5c8bba82a1 100644
--- a/routers/web/user/setting/runner.go
+++ b/routers/web/user/setting/runner.go
@@ -4,8 +4,8 @@
package setting
import (
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
func RedirectToDefaultSetting(ctx *context.Context) {
diff --git a/routers/web/user/setting/security/2fa.go b/routers/web/user/setting/security/2fa.go
index cd09102369..f1271c8370 100644
--- a/routers/web/user/setting/security/2fa.go
+++ b/routers/web/user/setting/security/2fa.go
@@ -12,12 +12,13 @@ import (
"net/http"
"strings"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/auth"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/mailer"
"github.com/pquerna/otp"
"github.com/pquerna/otp/totp"
@@ -33,8 +34,9 @@ func RegenerateScratchTwoFactor(ctx *context.Context) {
if auth.IsErrTwoFactorNotEnrolled(err) {
ctx.Flash.Error(ctx.Tr("settings.twofa_not_enrolled"))
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
+ } else {
+ ctx.ServerError("SettingsTwoFactor: Failed to GetTwoFactorByUID", err)
}
- ctx.ServerError("SettingsTwoFactor: Failed to GetTwoFactorByUID", err)
return
}
@@ -63,8 +65,9 @@ func DisableTwoFactor(ctx *context.Context) {
if auth.IsErrTwoFactorNotEnrolled(err) {
ctx.Flash.Error(ctx.Tr("settings.twofa_not_enrolled"))
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
+ } else {
+ ctx.ServerError("SettingsTwoFactor: Failed to GetTwoFactorByUID", err)
}
- ctx.ServerError("SettingsTwoFactor: Failed to GetTwoFactorByUID", err)
return
}
@@ -73,8 +76,14 @@ func DisableTwoFactor(ctx *context.Context) {
// There is a potential DB race here - we must have been disabled by another request in the intervening period
ctx.Flash.Success(ctx.Tr("settings.twofa_disabled"))
ctx.Redirect(setting.AppSubURL + "/user/settings/security")
+ } else {
+ ctx.ServerError("SettingsTwoFactor: Failed to DeleteTwoFactorByID", err)
}
- ctx.ServerError("SettingsTwoFactor: Failed to DeleteTwoFactorByID", err)
+ return
+ }
+
+ if err := mailer.SendDisabledTOTP(ctx, ctx.Doer); err != nil {
+ ctx.ServerError("SendDisabledTOTP", err)
return
}
@@ -211,11 +220,6 @@ func EnrollTwoFactorPost(ctx *context.Context) {
t = &auth.TwoFactor{
UID: ctx.Doer.ID,
}
- err = t.SetSecret(secret)
- if err != nil {
- ctx.ServerError("SettingsTwoFactor: Failed to set secret", err)
- return
- }
token, err := t.GenerateScratchToken()
if err != nil {
ctx.ServerError("SettingsTwoFactor: Failed to generate scratch token", err)
@@ -237,7 +241,12 @@ func EnrollTwoFactorPost(ctx *context.Context) {
log.Error("Unable to save changes to the session: %v", err)
}
- if err = auth.NewTwoFactor(ctx, t); err != nil {
+ if err := mailer.SendTOTPEnrolled(ctx, ctx.Doer); err != nil {
+ ctx.ServerError("SendTOTPEnrolled", err)
+ return
+ }
+
+ if err = auth.NewTwoFactor(ctx, t, secret); err != nil {
// FIXME: We need to handle a unique constraint fail here it's entirely possible that another request has beaten us.
// If there is a unique constraint fail we should just tolerate the error
ctx.ServerError("SettingsTwoFactor: Failed to save two factor", err)
diff --git a/routers/web/user/setting/security/openid.go b/routers/web/user/setting/security/openid.go
index 8f788e1735..14660e1646 100644
--- a/routers/web/user/setting/security/openid.go
+++ b/routers/web/user/setting/security/openid.go
@@ -6,13 +6,13 @@ package security
import (
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/openid"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/openid"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
)
// OpenIDPost response for change user's openid
diff --git a/routers/web/user/setting/security/security.go b/routers/web/user/setting/security/security.go
index 8d6859ab87..8b801cfebd 100644
--- a/routers/web/user/setting/security/security.go
+++ b/routers/web/user/setting/security/security.go
@@ -8,14 +8,14 @@ import (
"net/http"
"sort"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/auth/source/oauth2"
- "code.gitea.io/gitea/services/context"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/auth/source/oauth2"
+ "forgejo.org/services/context"
)
const (
@@ -55,7 +55,7 @@ func DeleteAccountLink(ctx *context.Context) {
}
func loadSecurityData(ctx *context.Context) {
- enrolled, err := auth_model.HasTwoFactorByUID(ctx, ctx.Doer.ID)
+ enrolled, err := auth_model.HasTOTPByUID(ctx, ctx.Doer.ID)
if err != nil {
ctx.ServerError("SettingsTwoFactor", err)
return
diff --git a/routers/web/user/setting/security/webauthn.go b/routers/web/user/setting/security/webauthn.go
index e382c8b9af..a909d479c9 100644
--- a/routers/web/user/setting/security/webauthn.go
+++ b/routers/web/user/setting/security/webauthn.go
@@ -9,13 +9,14 @@ import (
"strconv"
"time"
- "code.gitea.io/gitea/models/auth"
- wa "code.gitea.io/gitea/modules/auth/webauthn"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
+ "forgejo.org/models/auth"
+ wa "forgejo.org/modules/auth/webauthn"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/mailer"
"github.com/go-webauthn/webauthn/protocol"
"github.com/go-webauthn/webauthn/webauthn"
@@ -112,9 +113,25 @@ func WebauthnRegisterPost(ctx *context.Context) {
// WebauthnDelete deletes an security key by id
func WebauthnDelete(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.WebauthnDeleteForm)
+ cred, err := auth.GetWebAuthnCredentialByID(ctx, form.ID)
+ if err != nil || cred.UserID != ctx.Doer.ID {
+ if err != nil && !auth.IsErrWebAuthnCredentialNotExist(err) {
+ log.Error("GetWebAuthnCredentialByID: %v", err)
+ }
+
+ ctx.JSONRedirect(setting.AppSubURL + "/user/settings/security")
+ return
+ }
+
if _, err := auth.DeleteCredential(ctx, form.ID, ctx.Doer.ID); err != nil {
ctx.ServerError("GetWebAuthnCredentialByID", err)
return
}
+
+ if err := mailer.SendRemovedSecurityKey(ctx, ctx.Doer, cred.Name); err != nil {
+ ctx.ServerError("SendRemovedSecurityKey", err)
+ return
+ }
+
ctx.JSONRedirect(setting.AppSubURL + "/user/settings/security")
}
diff --git a/routers/web/user/setting/storage_overview.go b/routers/web/user/setting/storage_overview.go
new file mode 100644
index 0000000000..4586600572
--- /dev/null
+++ b/routers/web/user/setting/storage_overview.go
@@ -0,0 +1,20 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package setting
+
+import (
+ "forgejo.org/modules/base"
+ "forgejo.org/routers/web/shared"
+ "forgejo.org/services/context"
+)
+
+const (
+ tplSettingsStorageOverview base.TplName = "user/settings/storage_overview"
+)
+
+// StorageOverview render a size overview of the user, as well as relevant
+// quota limits of the instance.
+func StorageOverview(ctx *context.Context) {
+ shared.StorageOverview(ctx, ctx.Doer.ID, tplSettingsStorageOverview)
+}
diff --git a/routers/web/user/setting/webhooks.go b/routers/web/user/setting/webhooks.go
index 3cc67d9def..bc07accad4 100644
--- a/routers/web/user/setting/webhooks.go
+++ b/routers/web/user/setting/webhooks.go
@@ -6,12 +6,12 @@ package setting
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
- webhook_service "code.gitea.io/gitea/services/webhook"
+ "forgejo.org/models/db"
+ "forgejo.org/models/webhook"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
+ webhook_service "forgejo.org/services/webhook"
)
const (
diff --git a/routers/web/user/stop_watch.go b/routers/web/user/stop_watch.go
index 38f74ea455..210b32d205 100644
--- a/routers/web/user/stop_watch.go
+++ b/routers/web/user/stop_watch.go
@@ -6,10 +6,10 @@ package user
import (
"net/http"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
// GetStopwatches get all stopwatches
diff --git a/routers/web/user/task.go b/routers/web/user/task.go
index 8476767e9e..296c44f809 100644
--- a/routers/web/user/task.go
+++ b/routers/web/user/task.go
@@ -7,9 +7,9 @@ import (
"net/http"
"strconv"
- admin_model "code.gitea.io/gitea/models/admin"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/services/context"
+ admin_model "forgejo.org/models/admin"
+ "forgejo.org/modules/json"
+ "forgejo.org/services/context"
)
// TaskStatus returns task's status
diff --git a/routers/web/web.go b/routers/web/web.go
index 3480a18844..2840ee419a 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -8,49 +8,48 @@ import (
"net/http"
"strings"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/metrics"
- "code.gitea.io/gitea/modules/public"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/validation"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/modules/web/routing"
- "code.gitea.io/gitea/routers/common"
- "code.gitea.io/gitea/routers/web/admin"
- "code.gitea.io/gitea/routers/web/auth"
- "code.gitea.io/gitea/routers/web/devtest"
- "code.gitea.io/gitea/routers/web/events"
- "code.gitea.io/gitea/routers/web/explore"
- "code.gitea.io/gitea/routers/web/feed"
- "code.gitea.io/gitea/routers/web/healthcheck"
- "code.gitea.io/gitea/routers/web/misc"
- "code.gitea.io/gitea/routers/web/org"
- org_setting "code.gitea.io/gitea/routers/web/org/setting"
- "code.gitea.io/gitea/routers/web/repo"
- "code.gitea.io/gitea/routers/web/repo/actions"
- "code.gitea.io/gitea/routers/web/repo/badges"
- repo_flags "code.gitea.io/gitea/routers/web/repo/flags"
- repo_setting "code.gitea.io/gitea/routers/web/repo/setting"
- "code.gitea.io/gitea/routers/web/shared/project"
- "code.gitea.io/gitea/routers/web/user"
- user_setting "code.gitea.io/gitea/routers/web/user/setting"
- "code.gitea.io/gitea/routers/web/user/setting/security"
- auth_service "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/forms"
- "code.gitea.io/gitea/services/lfs"
+ "forgejo.org/models/perm"
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/metrics"
+ "forgejo.org/modules/public"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/modules/web/routing"
+ "forgejo.org/routers/common"
+ "forgejo.org/routers/web/admin"
+ "forgejo.org/routers/web/auth"
+ "forgejo.org/routers/web/devtest"
+ "forgejo.org/routers/web/events"
+ "forgejo.org/routers/web/explore"
+ "forgejo.org/routers/web/feed"
+ "forgejo.org/routers/web/healthcheck"
+ "forgejo.org/routers/web/misc"
+ "forgejo.org/routers/web/org"
+ org_setting "forgejo.org/routers/web/org/setting"
+ "forgejo.org/routers/web/repo"
+ "forgejo.org/routers/web/repo/actions"
+ "forgejo.org/routers/web/repo/badges"
+ repo_flags "forgejo.org/routers/web/repo/flags"
+ repo_setting "forgejo.org/routers/web/repo/setting"
+ "forgejo.org/routers/web/shared/project"
+ "forgejo.org/routers/web/user"
+ user_setting "forgejo.org/routers/web/user/setting"
+ "forgejo.org/routers/web/user/setting/security"
+ auth_service "forgejo.org/services/auth"
+ "forgejo.org/services/context"
+ "forgejo.org/services/forms"
+ "forgejo.org/services/lfs"
- _ "code.gitea.io/gitea/modules/session" // to registers all internal adapters
+ _ "forgejo.org/modules/session" // to registers all internal adapters
- "gitea.com/go-chi/captcha"
+ "code.forgejo.org/go-chi/captcha"
chi_middleware "github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
"github.com/klauspost/compress/gzhttp"
@@ -109,10 +108,6 @@ func buildAuthGroup() *auth_service.Group {
}
group.Add(&auth_service.Session{})
- if setting.IsWindows && auth_model.IsSSPIEnabled(db.DefaultContext) {
- group.Add(&auth_service.SSPI{}) // it MUST be the last, see the comment of SSPI
- }
-
return group
}
@@ -121,7 +116,7 @@ func webAuth(authMethod auth_service.Method) func(*context.Context) {
ar, err := common.AuthShared(ctx.Base, ctx.Session, authMethod)
if err != nil {
log.Error("Failed to verify user: %v", err)
- ctx.Error(http.StatusUnauthorized, "Verify")
+ ctx.Error(http.StatusUnauthorized, ctx.Locale.TrString("auth.unauthorized_credentials", "https://codeberg.org/forgejo/forgejo/issues/2809"))
return
}
ctx.Doer = ar.Doer
@@ -131,6 +126,8 @@ func webAuth(authMethod auth_service.Method) func(*context.Context) {
// ensure the session uid is deleted
_ = ctx.Session.Delete("uid")
}
+
+ ctx.Csrf.PrepareForSessionUser(ctx)
}
}
@@ -253,7 +250,7 @@ func Routes() *web.Route {
if setting.Service.EnableCaptcha {
// The captcha http.Handler should only fire on /captcha/* so we can just mount this on that url
- routes.Methods("GET,HEAD", "/captcha/*", append(mid, captcha.Captchaer(context.GetImageCaptcha()))...)
+ routes.Methods("GET,HEAD", "/captcha/*", append(mid, captcha.Server(captcha.StdWidth, captcha.StdHeight).ServeHTTP)...)
}
if setting.Metrics.Enabled {
@@ -324,6 +321,13 @@ func registerRoutes(m *web.Route) {
}
}
+ oauth2Enabled := func(ctx *context.Context) {
+ if !setting.OAuth2.Enabled {
+ ctx.Error(http.StatusForbidden)
+ return
+ }
+ }
+
reqMilestonesDashboardPageEnabled := func(ctx *context.Context) {
if !setting.Service.ShowMilestonesDashboardPage {
ctx.Error(http.StatusForbidden)
@@ -346,6 +350,20 @@ func registerRoutes(m *web.Route) {
}
}
+ annexEnabled := func(ctx *context.Context) {
+ if !setting.Annex.Enabled {
+ ctx.Error(http.StatusNotFound)
+ return
+ }
+ }
+
+ annexP2PHTTPEnabled := func(ctx *context.Context) {
+ if setting.Annex.DisableP2PHTTP {
+ ctx.Error(http.StatusNotFound)
+ return
+ }
+ }
+
federationEnabled := func(ctx *context.Context) {
if !setting.Federation.Enabled {
ctx.Error(http.StatusNotFound)
@@ -513,16 +531,18 @@ func registerRoutes(m *web.Route) {
m.Any("/user/events", routing.MarkLongPolling, events.Events)
m.Group("/login/oauth", func() {
- m.Get("/authorize", web.Bind(forms.AuthorizationForm{}), auth.AuthorizeOAuth)
- m.Post("/grant", web.Bind(forms.GrantApplicationForm{}), auth.GrantApplicationOAuth)
- // TODO manage redirection
- m.Post("/authorize", web.Bind(forms.AuthorizationForm{}), auth.AuthorizeOAuth)
- }, ignSignInAndCsrf, reqSignIn)
+ m.Group("", func() {
+ m.Get("/authorize", web.Bind(forms.AuthorizationForm{}), auth.AuthorizeOAuth)
+ m.Post("/grant", web.Bind(forms.GrantApplicationForm{}), auth.GrantApplicationOAuth)
+ // TODO manage redirection
+ m.Post("/authorize", web.Bind(forms.AuthorizationForm{}), auth.AuthorizeOAuth)
+ }, ignSignInAndCsrf, reqSignIn)
- m.Methods("GET, OPTIONS", "/login/oauth/userinfo", optionsCorsHandler(), ignSignInAndCsrf, auth.InfoOAuth)
- m.Methods("POST, OPTIONS", "/login/oauth/access_token", optionsCorsHandler(), web.Bind(forms.AccessTokenForm{}), ignSignInAndCsrf, auth.AccessTokenOAuth)
- m.Methods("GET, OPTIONS", "/login/oauth/keys", optionsCorsHandler(), ignSignInAndCsrf, auth.OIDCKeys)
- m.Methods("POST, OPTIONS", "/login/oauth/introspect", optionsCorsHandler(), web.Bind(forms.IntrospectTokenForm{}), ignSignInAndCsrf, auth.IntrospectOAuth)
+ m.Methods("GET, POST, OPTIONS", "/userinfo", optionsCorsHandler(), ignSignInAndCsrf, auth.InfoOAuth)
+ m.Methods("POST, OPTIONS", "/access_token", optionsCorsHandler(), web.Bind(forms.AccessTokenForm{}), ignSignInAndCsrf, auth.AccessTokenOAuth)
+ m.Methods("GET, OPTIONS", "/keys", optionsCorsHandler(), ignSignInAndCsrf, auth.OIDCKeys)
+ m.Methods("POST, OPTIONS", "/introspect", optionsCorsHandler(), web.Bind(forms.IntrospectTokenForm{}), ignSignInAndCsrf, auth.IntrospectOAuth)
+ }, oauth2Enabled)
m.Group("/user/settings", func() {
m.Get("", user_setting.Profile)
@@ -564,17 +584,25 @@ func registerRoutes(m *web.Route) {
}, openIDSignInEnabled)
m.Post("/account_link", linkAccountEnabled, security.DeleteAccountLink)
})
- m.Group("/applications/oauth2", func() {
- m.Get("/{id}", user_setting.OAuth2ApplicationShow)
- m.Post("/{id}", web.Bind(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsEdit)
- m.Post("/{id}/regenerate_secret", user_setting.OAuthApplicationsRegenerateSecret)
- m.Post("", web.Bind(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsPost)
- m.Post("/{id}/delete", user_setting.DeleteOAuth2Application)
- m.Post("/{id}/revoke/{grantId}", user_setting.RevokeOAuth2Grant)
+
+ m.Group("/applications", func() {
+ // oauth2 applications
+ m.Group("/oauth2", func() {
+ m.Get("/{id}", user_setting.OAuth2ApplicationShow)
+ m.Post("/{id}", web.Bind(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsEdit)
+ m.Post("/{id}/regenerate_secret", user_setting.OAuthApplicationsRegenerateSecret)
+ m.Post("", web.Bind(forms.EditOAuth2ApplicationForm{}), user_setting.OAuthApplicationsPost)
+ m.Post("/{id}/delete", user_setting.DeleteOAuth2Application)
+ m.Post("/{id}/revoke/{grantId}", user_setting.RevokeOAuth2Grant)
+ }, oauth2Enabled)
+
+ // access token applications
+ m.Combo("").Get(user_setting.Applications).
+ Post(web.Bind(forms.NewAccessTokenForm{}), user_setting.ApplicationsPost)
+ m.Post("/delete", user_setting.DeleteApplication)
+ m.Post("/regenerate", user_setting.RegenerateApplication)
})
- m.Combo("/applications").Get(user_setting.Applications).
- Post(web.Bind(forms.NewAccessTokenForm{}), user_setting.ApplicationsPost)
- m.Post("/applications/delete", user_setting.DeleteApplication)
+
m.Combo("/keys").Get(user_setting.Keys).
Post(web.Bind(forms.AddKeyForm{}), user_setting.KeysPost)
m.Post("/keys/delete", user_setting.DeleteKey)
@@ -625,7 +653,8 @@ func registerRoutes(m *web.Route) {
m.Get("", user_setting.BlockedUsers)
m.Post("/unblock", user_setting.UnblockUser)
})
- }, reqSignIn, ctxDataSet("PageIsUserSettings", true, "AllThemes", setting.UI.Themes, "EnablePackages", setting.Packages.Enabled))
+ m.Get("/storage_overview", user_setting.StorageOverview)
+ }, reqSignIn, ctxDataSet("PageIsUserSettings", true, "EnablePackages", setting.Packages.Enabled, "EnableQuota", setting.Quota.Enabled))
m.Group("/user", func() {
m.Get("/activate", auth.Activate)
@@ -639,7 +668,7 @@ func registerRoutes(m *web.Route) {
m.Post("/logout", auth.SignOut)
m.Get("/task/{task}", reqSignIn, user.TaskStatus)
m.Get("/stopwatches", reqSignIn, user.GetStopwatches)
- m.Get("/search", ignExploreSignIn, user.Search)
+ m.Get("/search_candidates", ignExploreSignIn, user.SearchCandidates)
m.Group("/oauth2", func() {
m.Get("/{provider}", auth.SignInOAuth)
m.Get("/{provider}/callback", auth.SignInOAuthCallback)
@@ -696,6 +725,7 @@ func registerRoutes(m *web.Route) {
m.Group("/emails", func() {
m.Get("", admin.Emails)
m.Post("/activate", admin.ActivateEmail)
+ m.Post("/delete", admin.DeleteEmail)
})
m.Group("/orgs", func() {
@@ -751,12 +781,7 @@ func registerRoutes(m *web.Route) {
m.Post("/regenerate_secret", admin.ApplicationsRegenerateSecret)
m.Post("/delete", admin.DeleteApplication)
})
- }, func(ctx *context.Context) {
- if !setting.OAuth2.Enabled {
- ctx.Error(http.StatusForbidden)
- return
- }
- })
+ }, oauth2Enabled)
m.Group("/actions", func() {
m.Get("", admin.RedirectToDefaultSetting)
@@ -853,10 +878,15 @@ func registerRoutes(m *web.Route) {
m.Post("/teams/{team}/action/repo/{action}", org.TeamsRepoAction)
}, context.OrgAssignment(true, false, true))
+ // require admin permission
+ m.Group("/{org}", func() {
+ m.Get("/teams/-/search", org.SearchTeam)
+ }, context.OrgAssignment(true, false, false, true))
+
+ // require owner permission
m.Group("/{org}", func() {
m.Get("/teams/new", org.NewTeam)
m.Post("/teams/new", web.Bind(forms.CreateTeamForm{}), org.NewTeamPost)
- m.Get("/teams/-/search", org.SearchTeam)
m.Get("/teams/{team}/edit", org.EditTeam)
m.Post("/teams/{team}/edit", web.Bind(forms.CreateTeamForm{}), org.EditTeamPost)
m.Post("/teams/{team}/delete", org.DeleteTeam)
@@ -874,12 +904,7 @@ func registerRoutes(m *web.Route) {
m.Post("/regenerate_secret", org.OAuthApplicationsRegenerateSecret)
m.Post("/delete", org.DeleteOAuth2Application)
})
- }, func(ctx *context.Context) {
- if !setting.OAuth2.Enabled {
- ctx.Error(http.StatusForbidden)
- return
- }
- })
+ }, oauth2Enabled)
m.Group("/hooks", func() {
m.Get("", org.Webhooks)
@@ -915,6 +940,7 @@ func registerRoutes(m *web.Route) {
m.Post("/block", org_setting.BlockedUsersBlock)
m.Post("/unblock", org_setting.BlockedUsersUnblock)
})
+ m.Get("/storage_overview", org_setting.StorageOverview)
m.Group("/packages", func() {
m.Get("", org.Packages)
@@ -934,12 +960,15 @@ func registerRoutes(m *web.Route) {
m.Post("/rebuild", org.RebuildCargoIndex)
})
}, packagesEnabled)
- }, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled, "PageIsOrgSettings", true))
+ }, ctxDataSet("EnableOAuth2", setting.OAuth2.Enabled, "EnablePackages", setting.Packages.Enabled, "EnableQuota", setting.Quota.Enabled, "PageIsOrgSettings", true))
}, context.OrgAssignment(true, true))
}, reqSignIn)
// ***** END: Organization *****
// ***** START: Repository *****
+ m.Group("", func() {
+ m.Methods("GET,POST", "/git-annex-p2phttp/git-annex/{uuid}/*", repo.AnnexP2PHTTP)
+ }, ignSignInAndCsrf, annexEnabled, annexP2PHTTPEnabled)
m.Group("/repo", func() {
m.Get("/create", repo.Create)
m.Post("/create", web.Bind(forms.CreateRepoForm{}), repo.CreatePost)
@@ -1131,8 +1160,10 @@ func registerRoutes(m *web.Route) {
m.Group("/{type:issues|pulls}", func() {
m.Group("/{index}", func() {
m.Get("/info", repo.GetIssueInfo)
+ m.Get("/summary-card", repo.DrawIssueSummaryCard)
})
})
+ m.Get("/-/summary-card", repo.DrawRepoSummaryCard)
}, ignSignIn, context.RepoAssignment, context.UnitTypes()) // for "/{username}/{reponame}" which doesn't require authentication
// Grouping for those endpoints that do require authentication
@@ -1195,7 +1226,7 @@ func registerRoutes(m *web.Route) {
m.Post("/status", reqRepoIssuesOrPullsWriter, repo.UpdateIssueStatus)
m.Post("/delete", reqRepoAdmin, repo.BatchDeleteIssues)
m.Post("/resolve_conversation", reqRepoIssuesOrPullsReader, repo.SetShowOutdatedComments, repo.UpdateResolveConversation)
- m.Post("/attachments", repo.UploadIssueAttachment)
+ m.Post("/attachments", context.EnforceQuotaWeb(quota_model.LimitSubjectSizeAssetsAttachmentsIssues, context.QuotaTargetRepo), repo.UploadIssueAttachment)
m.Post("/attachments/remove", repo.DeleteAttachment)
m.Delete("/unpin/{index}", reqRepoAdmin, repo.IssueUnpin)
m.Post("/move_pin", reqRepoAdmin, repo.IssuePinMove)
@@ -1243,9 +1274,9 @@ func registerRoutes(m *web.Route) {
Post(web.Bind(forms.EditRepoFileForm{}), repo.NewDiffPatchPost)
m.Combo("/_cherrypick/{sha:([a-f0-9]{4,64})}/*").Get(repo.CherryPick).
Post(web.Bind(forms.CherryPickForm{}), repo.CherryPickPost)
- }, repo.MustBeEditable, repo.CommonEditorData)
+ }, repo.MustBeEditable, repo.CommonEditorData, context.EnforceQuotaWeb(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo))
m.Group("", func() {
- m.Post("/upload-file", repo.UploadFileToServer)
+ m.Post("/upload-file", context.EnforceQuotaWeb(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo), repo.UploadFileToServer)
m.Post("/upload-remove", web.Bind(forms.RemoveUploadFileForm{}), repo.RemoveUploadFileFromServer)
}, repo.MustBeEditable, repo.MustBeAbleToUpload)
}, context.RepoRef(), canEnableEditor, context.RepoMustNotBeArchived())
@@ -1255,7 +1286,7 @@ func registerRoutes(m *web.Route) {
m.Post("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.CreateBranch)
m.Post("/tag/*", context.RepoRefByType(context.RepoRefTag), repo.CreateBranch)
m.Post("/commit/*", context.RepoRefByType(context.RepoRefCommit), repo.CreateBranch)
- }, web.Bind(forms.NewBranchForm{}))
+ }, web.Bind(forms.NewBranchForm{}), context.EnforceQuotaWeb(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo))
m.Post("/delete", repo.DeleteBranchPost)
m.Post("/restore", repo.RestoreBranchPost)
}, context.RepoMustNotBeArchived(), reqRepoCodeWriter, repo.MustBeNotEmpty)
@@ -1282,21 +1313,23 @@ func registerRoutes(m *web.Route) {
m.Get("/latest", repo.LatestRelease)
m.Get(".rss", feedEnabled, repo.ReleasesFeedRSS)
m.Get(".atom", feedEnabled, repo.ReleasesFeedAtom)
+ m.Get("/summary-card/*", repo.DrawReleaseSummaryCard)
}, ctxDataSet("EnableFeed", setting.Other.EnableFeed),
repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefTag, true))
m.Get("/releases/attachments/{uuid}", repo.MustBeNotEmpty, repo.GetAttachment)
m.Get("/releases/download/{vTag}/{fileName}", repo.MustBeNotEmpty, repo.RedirectDownload)
m.Group("/releases", func() {
- m.Get("/new", repo.NewRelease)
- m.Post("/new", web.Bind(forms.NewReleaseForm{}), repo.NewReleasePost)
+ m.Combo("/new", context.EnforceQuotaWeb(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo)).
+ Get(repo.NewRelease).
+ Post(web.Bind(forms.NewReleaseForm{}), repo.NewReleasePost)
m.Post("/delete", repo.DeleteRelease)
- m.Post("/attachments", repo.UploadReleaseAttachment)
+ m.Post("/attachments", context.EnforceQuotaWeb(quota_model.LimitSubjectSizeAssetsAttachmentsReleases, context.QuotaTargetRepo), repo.UploadReleaseAttachment)
m.Post("/attachments/remove", repo.DeleteAttachment)
}, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, context.RepoRef())
m.Group("/releases", func() {
m.Get("/edit/*", repo.EditRelease)
m.Post("/edit/*", web.Bind(forms.EditReleaseForm{}), repo.EditReleasePost)
- }, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, repo.CommitInfoCache)
+ }, reqSignIn, repo.MustBeNotEmpty, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, repo.CommitInfoCache, context.EnforceQuotaWeb(quota_model.LimitSubjectSizeReposAll, context.QuotaTargetRepo))
}, ignSignIn, context.RepoAssignment, context.UnitTypes(), reqRepoReleaseReader)
// to maintain compatibility with old attachments
@@ -1409,10 +1442,10 @@ func registerRoutes(m *web.Route) {
m.Group("/wiki", func() {
m.Combo("/").
Get(repo.Wiki).
- Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), repo.WikiPost)
+ Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), context.EnforceQuotaWeb(quota_model.LimitSubjectSizeWiki, context.QuotaTargetRepo), repo.WikiPost)
m.Combo("/*").
Get(repo.Wiki).
- Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), repo.WikiPost)
+ Post(context.RepoMustNotBeArchived(), reqSignIn, reqRepoWikiWriter, web.Bind(forms.NewWikiForm{}), context.EnforceQuotaWeb(quota_model.LimitSubjectSizeWiki, context.QuotaTargetRepo), repo.WikiPost)
m.Get("/commit/{sha:[a-f0-9]{4,64}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
m.Get("/commit/{sha:[a-f0-9]{4,64}}.{ext:patch|diff}", repo.RawDiff)
}, repo.MustEnableWiki, func(ctx *context.Context) {
@@ -1489,7 +1522,7 @@ func registerRoutes(m *web.Route) {
m.Get("/list", context.RepoRef(), repo.GetPullCommits)
m.Get("/{sha:[a-f0-9]{4,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForSingleCommit)
})
- m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), repo.MergePullRequest)
+ m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), context.EnforceQuotaWeb(quota_model.LimitSubjectSizeGitAll, context.QuotaTargetRepo), repo.MergePullRequest)
m.Post("/cancel_auto_merge", context.RepoMustNotBeArchived(), repo.CancelAutoMergePullRequest)
m.Post("/update", repo.UpdatePullRequest)
m.Post("/set_allow_maintainer_edit", web.Bind(forms.UpdateAllowEditsForm{}), repo.SetAllowEdits)
@@ -1549,11 +1582,17 @@ func registerRoutes(m *web.Route) {
m.Get("/graph", repo.Graph)
m.Get("/commit/{sha:([a-f0-9]{4,64})$}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.Diff)
m.Get("/commit/{sha:([a-f0-9]{4,64})$}/load-branches-and-tags", repo.LoadBranchesAndTags)
+ m.Group("/commit/{sha:([a-f0-9]{4,64})$}/notes", func() {
+ m.Post("", web.Bind(forms.CommitNotesForm{}), repo.SetCommitNotes)
+ m.Post("/remove", repo.RemoveCommitNotes)
+ }, reqSignIn, reqRepoCodeWriter)
m.Get("/cherry-pick/{sha:([a-f0-9]{4,64})$}", repo.SetEditorconfigIfExists, repo.CherryPick)
}, repo.MustBeNotEmpty, context.RepoRef(), reqRepoCodeReader)
- m.Get("/rss/branch/*", repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed("rss"))
- m.Get("/atom/branch/*", repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefBranch), feedEnabled, feed.RenderBranchFeed("atom"))
+ m.Group("", func() {
+ m.Get("/rss/branch/*", feed.RenderBranchFeed("rss"))
+ m.Get("/atom/branch/*", feed.RenderBranchFeed("atom"))
+ }, repo.MustBeNotEmpty, context.RepoRefByType(context.RepoRefBranch), reqRepoCodeReader, feedEnabled)
m.Group("/src", func() {
m.Get("/branch/*", context.RepoRefByType(context.RepoRefBranch), repo.Home)
@@ -1610,6 +1649,12 @@ func registerRoutes(m *web.Route) {
})
}, ignSignInAndCsrf, lfsServerEnabled)
+ m.Group("", func() {
+ // for git-annex
+ m.Methods("GET,OPTIONS", "/config", repo.GetConfig) // needed by clients reading annex.uuid during `git annex initremote`
+ m.Methods("GET,OPTIONS", "/annex/objects/{hash1}/{hash2}/{keyDir}/{key}", repo.GetAnnexObject)
+ }, ignSignInAndCsrf, annexEnabled, context.UserAssignmentWeb())
+
gitHTTPRouters(m)
})
})
diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go
index 1f3de70db0..be3c2925fe 100644
--- a/routers/web/webfinger.go
+++ b/routers/web/webfinger.go
@@ -9,10 +9,10 @@ import (
"net/url"
"strings"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
// https://datatracker.ietf.org/doc/html/draft-ietf-appsawg-webfinger-14#section-4.4
diff --git a/services/actions/auth.go b/services/actions/auth.go
index 8e934d89a8..4dc86a35f3 100644
--- a/services/actions/auth.go
+++ b/services/actions/auth.go
@@ -9,9 +9,9 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
"github.com/golang-jwt/jwt/v5"
)
@@ -83,7 +83,12 @@ func ParseAuthorizationToken(req *http.Request) (int64, error) {
return 0, fmt.Errorf("split token failed")
}
- token, err := jwt.ParseWithClaims(parts[1], &actionsClaims{}, func(t *jwt.Token) (any, error) {
+ return TokenToTaskID(parts[1])
+}
+
+// TokenToTaskID returns the TaskID associated with the provided JWT token
+func TokenToTaskID(token string) (int64, error) {
+ parsedToken, err := jwt.ParseWithClaims(token, &actionsClaims{}, func(t *jwt.Token) (any, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
}
@@ -93,8 +98,8 @@ func ParseAuthorizationToken(req *http.Request) (int64, error) {
return 0, err
}
- c, ok := token.Claims.(*actionsClaims)
- if !token.Valid || !ok {
+ c, ok := parsedToken.Claims.(*actionsClaims)
+ if !parsedToken.Valid || !ok {
return 0, fmt.Errorf("invalid token claim")
}
diff --git a/services/actions/auth_test.go b/services/actions/auth_test.go
index 12db2bae56..93a5980bc5 100644
--- a/services/actions/auth_test.go
+++ b/services/actions/auth_test.go
@@ -7,50 +7,51 @@ import (
"net/http"
"testing"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
"github.com/golang-jwt/jwt/v5"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCreateAuthorizationToken(t *testing.T) {
var taskID int64 = 23
token, err := CreateAuthorizationToken(taskID, 1, 2)
- assert.Nil(t, err)
+ require.NoError(t, err)
assert.NotEqual(t, "", token)
claims := jwt.MapClaims{}
_, err = jwt.ParseWithClaims(token, claims, func(t *jwt.Token) (any, error) {
return setting.GetGeneralTokenSigningSecret(), nil
})
- assert.Nil(t, err)
+ require.NoError(t, err)
scp, ok := claims["scp"]
assert.True(t, ok, "Has scp claim in jwt token")
assert.Contains(t, scp, "Actions.Results:1:2")
taskIDClaim, ok := claims["TaskID"]
assert.True(t, ok, "Has TaskID claim in jwt token")
- assert.Equal(t, float64(taskID), taskIDClaim, "Supplied taskid must match stored one")
+ assert.InDelta(t, float64(taskID), taskIDClaim, 0, "Supplied taskid must match stored one")
acClaim, ok := claims["ac"]
assert.True(t, ok, "Has ac claim in jwt token")
ac, ok := acClaim.(string)
assert.True(t, ok, "ac claim is a string for buildx gha cache")
scopes := []actionsCacheScope{}
err = json.Unmarshal([]byte(ac), &scopes)
- assert.NoError(t, err, "ac claim is a json list for buildx gha cache")
+ require.NoError(t, err, "ac claim is a json list for buildx gha cache")
assert.GreaterOrEqual(t, len(scopes), 1, "Expected at least one action cache scope for buildx gha cache")
}
func TestParseAuthorizationToken(t *testing.T) {
var taskID int64 = 23
token, err := CreateAuthorizationToken(taskID, 1, 2)
- assert.Nil(t, err)
+ require.NoError(t, err)
assert.NotEqual(t, "", token)
headers := http.Header{}
headers.Set("Authorization", "Bearer "+token)
rTaskID, err := ParseAuthorizationToken(&http.Request{
Header: headers,
})
- assert.Nil(t, err)
+ require.NoError(t, err)
assert.Equal(t, taskID, rTaskID)
}
@@ -59,6 +60,6 @@ func TestParseAuthorizationTokenNoAuthHeader(t *testing.T) {
rTaskID, err := ParseAuthorizationToken(&http.Request{
Header: headers,
})
- assert.Nil(t, err)
+ require.NoError(t, err)
assert.Equal(t, int64(0), rTaskID)
}
diff --git a/services/actions/cleanup.go b/services/actions/cleanup.go
index 5376c2624c..fde5286e60 100644
--- a/services/actions/cleanup.go
+++ b/services/actions/cleanup.go
@@ -5,19 +5,32 @@ package actions
import (
"context"
+ "errors"
+ "fmt"
+ "os"
"time"
- "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/storage"
+ actions_model "forgejo.org/models/actions"
+ actions_module "forgejo.org/modules/actions"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/timeutil"
)
// Cleanup removes expired actions logs, data and artifacts
-func Cleanup(taskCtx context.Context, olderThan time.Duration) error {
- // TODO: clean up expired actions logs
-
+func Cleanup(ctx context.Context) error {
// clean up expired artifacts
- return CleanupArtifacts(taskCtx)
+ if err := CleanupArtifacts(ctx); err != nil {
+ return fmt.Errorf("cleanup artifacts: %w", err)
+ }
+
+ // clean up old logs
+ if err := CleanupLogs(ctx); err != nil {
+ return fmt.Errorf("cleanup logs: %w", err)
+ }
+
+ return nil
}
// CleanupArtifacts removes expired add need-deleted artifacts and set records expired status
@@ -29,13 +42,13 @@ func CleanupArtifacts(taskCtx context.Context) error {
}
func cleanExpiredArtifacts(taskCtx context.Context) error {
- artifacts, err := actions.ListNeedExpiredArtifacts(taskCtx)
+ artifacts, err := actions_model.ListNeedExpiredArtifacts(taskCtx)
if err != nil {
return err
}
log.Info("Found %d expired artifacts", len(artifacts))
for _, artifact := range artifacts {
- if err := actions.SetArtifactExpired(taskCtx, artifact.ID); err != nil {
+ if err := actions_model.SetArtifactExpired(taskCtx, artifact.ID); err != nil {
log.Error("Cannot set artifact %d expired: %v", artifact.ID, err)
continue
}
@@ -53,13 +66,13 @@ const deleteArtifactBatchSize = 100
func cleanNeedDeleteArtifacts(taskCtx context.Context) error {
for {
- artifacts, err := actions.ListPendingDeleteArtifacts(taskCtx, deleteArtifactBatchSize)
+ artifacts, err := actions_model.ListPendingDeleteArtifacts(taskCtx, deleteArtifactBatchSize)
if err != nil {
return err
}
log.Info("Found %d artifacts pending deletion", len(artifacts))
for _, artifact := range artifacts {
- if err := actions.SetArtifactDeleted(taskCtx, artifact.ID); err != nil {
+ if err := actions_model.SetArtifactDeleted(taskCtx, artifact.ID); err != nil {
log.Error("Cannot set artifact %d deleted: %v", artifact.ID, err)
continue
}
@@ -76,3 +89,40 @@ func cleanNeedDeleteArtifacts(taskCtx context.Context) error {
}
return nil
}
+
+const deleteLogBatchSize = 100
+
+// CleanupLogs removes logs which are older than the configured retention time
+func CleanupLogs(ctx context.Context) error {
+ olderThan := timeutil.TimeStampNow().AddDuration(-time.Duration(setting.Actions.LogRetentionDays) * 24 * time.Hour)
+
+ count := 0
+ for {
+ tasks, err := actions_model.FindOldTasksToExpire(ctx, olderThan, deleteLogBatchSize)
+ if err != nil {
+ return fmt.Errorf("find old tasks: %w", err)
+ }
+ for _, task := range tasks {
+ if err := actions_module.RemoveLogs(ctx, task.LogInStorage, task.LogFilename); err != nil && !errors.Is(err, os.ErrNotExist) {
+ log.Error("Failed to remove log %s (in storage %v) of task %v: %v", task.LogFilename, task.LogInStorage, task.ID, err)
+ // do not return error here, continue to next task
+ continue
+ }
+ task.LogIndexes = nil // clear log indexes since it's a heavy field
+ task.LogExpired = true
+ if err := actions_model.UpdateTask(ctx, task, "log_indexes", "log_expired"); err != nil {
+ log.Error("Failed to update task %v: %v", task.ID, err)
+ // do not return error here, continue to next task
+ continue
+ }
+ count++
+ log.Trace("Removed log %s of task %v", task.LogFilename, task.ID)
+ }
+ if len(tasks) < deleteLogBatchSize {
+ break
+ }
+ }
+
+ log.Info("Removed %d logs", count)
+ return nil
+}
diff --git a/services/actions/cleanup_test.go b/services/actions/cleanup_test.go
new file mode 100644
index 0000000000..67f68d4de9
--- /dev/null
+++ b/services/actions/cleanup_test.go
@@ -0,0 +1,31 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package actions
+
+import (
+ "testing"
+
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/timeutil"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestCleanup(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ t.Run("Deletes no longer existing logs", func(t *testing.T) {
+ unittest.AssertSuccessfulInsert(t, &actions_model.ActionTask{ID: 1001, LogExpired: false, LogIndexes: []int64{1, 2, 3, 4}, LogFilename: "does-not-exist", Stopped: timeutil.TimeStamp(1)})
+
+ require.NoError(t, CleanupLogs(db.DefaultContext))
+
+ task := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionTask{ID: 1001})
+ assert.EqualValues(t, "does-not-exist", task.LogFilename)
+ assert.True(t, task.LogExpired)
+ assert.Nil(t, task.LogIndexes)
+ })
+}
diff --git a/services/actions/clear_tasks.go b/services/actions/clear_tasks.go
index 67373782d5..31e15ec927 100644
--- a/services/actions/clear_tasks.go
+++ b/services/actions/clear_tasks.go
@@ -8,18 +8,18 @@ import (
"fmt"
"time"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/actions"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
)
// StopZombieTasks stops the task which have running status, but haven't been updated for a long time
func StopZombieTasks(ctx context.Context) error {
return stopTasks(ctx, actions_model.FindTaskOptions{
- Status: actions_model.StatusRunning,
+ Status: []actions_model.Status{actions_model.StatusRunning},
UpdatedBefore: timeutil.TimeStamp(time.Now().Add(-setting.Actions.ZombieTaskTimeout).Unix()),
})
}
@@ -27,7 +27,7 @@ func StopZombieTasks(ctx context.Context) error {
// StopEndlessTasks stops the tasks which have running status and continuous updates, but don't end for a long time
func StopEndlessTasks(ctx context.Context) error {
return stopTasks(ctx, actions_model.FindTaskOptions{
- Status: actions_model.StatusRunning,
+ Status: []actions_model.Status{actions_model.StatusRunning},
StartedBefore: timeutil.TimeStamp(time.Now().Add(-setting.Actions.EndlessTaskTimeout).Unix()),
})
}
diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go
index bc2905e089..1fffa6852f 100644
--- a/services/actions/commit_status.go
+++ b/services/actions/commit_status.go
@@ -8,14 +8,15 @@ import (
"fmt"
"path"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
- webhook_module "code.gitea.io/gitea/modules/webhook"
- commitstatus_service "code.gitea.io/gitea/services/repository/commitstatus"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ user_model "forgejo.org/models/user"
+ actions_module "forgejo.org/modules/actions"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
+ webhook_module "forgejo.org/modules/webhook"
+ commitstatus_service "forgejo.org/services/repository/commitstatus"
"github.com/nektos/act/pkg/jobparser"
)
@@ -52,8 +53,12 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er
return fmt.Errorf("head commit is missing in event payload")
}
sha = payload.HeadCommit.ID
- case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync:
- event = "pull_request"
+ case webhook_module.HookEventPullRequest, webhook_module.HookEventPullRequestSync, webhook_module.HookEventPullRequestLabel, webhook_module.HookEventPullRequestAssign, webhook_module.HookEventPullRequestMilestone:
+ if run.TriggerEvent == actions_module.GithubEventPullRequestTarget {
+ event = "pull_request_target"
+ } else {
+ event = "pull_request"
+ }
payload, err := run.GetPullRequestEventPayload()
if err != nil {
return fmt.Errorf("GetPullRequestEventPayload: %w", err)
diff --git a/services/actions/context.go b/services/actions/context.go
new file mode 100644
index 0000000000..bf187c56bf
--- /dev/null
+++ b/services/actions/context.go
@@ -0,0 +1,161 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package actions
+
+import (
+ "context"
+ "fmt"
+
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ actions_module "forgejo.org/modules/actions"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
+)
+
+// GenerateGiteaContext generate the gitea context without token and gitea_runtime_token
+// job can be nil when generating a context for parsing workflow-level expressions
+func GenerateGiteaContext(run *actions_model.ActionRun, job *actions_model.ActionRunJob) map[string]any {
+ event := map[string]any{}
+ _ = json.Unmarshal([]byte(run.EventPayload), &event)
+
+ baseRef := ""
+ headRef := ""
+ ref := run.Ref
+ sha := run.CommitSHA
+ if pullPayload, err := run.GetPullRequestEventPayload(); err == nil && pullPayload.PullRequest != nil && pullPayload.PullRequest.Base != nil && pullPayload.PullRequest.Head != nil {
+ baseRef = pullPayload.PullRequest.Base.Ref
+ headRef = pullPayload.PullRequest.Head.Ref
+
+ // if the TriggerEvent is pull_request_target, ref and sha need to be set according to the base of pull request
+ // In GitHub's documentation, ref should be the branch or tag that triggered workflow. But when the TriggerEvent is pull_request_target,
+ // the ref will be the base branch.
+ if run.TriggerEvent == actions_module.GithubEventPullRequestTarget {
+ ref = git.BranchPrefix + pullPayload.PullRequest.Base.Name
+ sha = pullPayload.PullRequest.Base.Sha
+ }
+ }
+
+ refName := git.RefName(ref)
+
+ gitContext := map[string]any{
+ // standard contexts, see https://docs.github.com/en/actions/learn-github-actions/contexts#github-context
+ "action": "", // string, The name of the action currently running, or the id of a step. GitHub removes special characters, and uses the name __run when the current step runs a script without an id. If you use the same action more than once in the same job, the name will include a suffix with the sequence number with underscore before it. For example, the first script you run will have the name __run, and the second script will be named __run_2. Similarly, the second invocation of actions/checkout will be actionscheckout2.
+ "action_path": "", // string, The path where an action is located. This property is only supported in composite actions. You can use this path to access files located in the same repository as the action.
+ "action_ref": "", // string, For a step executing an action, this is the ref of the action being executed. For example, v2.
+ "action_repository": "", // string, For a step executing an action, this is the owner and repository name of the action. For example, actions/checkout.
+ "action_status": "", // string, For a composite action, the current result of the composite action.
+ "actor": run.TriggerUser.Name, // string, The username of the user that triggered the initial workflow run. If the workflow run is a re-run, this value may differ from github.triggering_actor. Any workflow re-runs will use the privileges of github.actor, even if the actor initiating the re-run (github.triggering_actor) has different privileges.
+ "api_url": setting.AppURL + "api/v1", // string, The URL of the GitHub REST API.
+ "base_ref": baseRef, // string, The base_ref or target branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target.
+ "env": "", // string, Path on the runner to the file that sets environment variables from workflow commands. This file is unique to the current step and is a different file for each step in a job. For more information, see "Workflow commands for GitHub Actions."
+ "event": event, // object, The full event webhook payload. You can access individual properties of the event using this context. This object is identical to the webhook payload of the event that triggered the workflow run, and is different for each event. The webhooks for each GitHub Actions event is linked in "Events that trigger workflows." For example, for a workflow run triggered by the push event, this object contains the contents of the push webhook payload.
+ "event_name": run.TriggerEvent, // string, The name of the event that triggered the workflow run.
+ "event_path": "", // string, The path to the file on the runner that contains the full event webhook payload.
+ "graphql_url": "", // string, The URL of the GitHub GraphQL API.
+ "head_ref": headRef, // string, The head_ref or source branch of the pull request in a workflow run. This property is only available when the event that triggers a workflow run is either pull_request or pull_request_target.
+ "job": "", // string, The job_id of the current job.
+ "ref": ref, // string, The fully-formed ref of the branch or tag that triggered the workflow run. For workflows triggered by push, this is the branch or tag ref that was pushed. For workflows triggered by pull_request, this is the pull request merge branch. For workflows triggered by release, this is the release tag created. For other triggers, this is the branch or tag ref that triggered the workflow run. This is only set if a branch or tag is available for the event type. The ref given is fully-formed, meaning that for branches the format is refs/heads/, for pull requests it is refs/pull//merge, and for tags it is refs/tags/. For example, refs/heads/feature-branch-1.
+ "ref_name": refName.ShortName(), // string, The short ref name of the branch or tag that triggered the workflow run. This value matches the branch or tag name shown on GitHub. For example, feature-branch-1.
+ "ref_protected": false, // boolean, true if branch protections are configured for the ref that triggered the workflow run.
+ "ref_type": refName.RefType(), // string, The type of ref that triggered the workflow run. Valid values are branch or tag.
+ "path": "", // string, Path on the runner to the file that sets system PATH variables from workflow commands. This file is unique to the current step and is a different file for each step in a job. For more information, see "Workflow commands for GitHub Actions."
+ "repository": run.Repo.OwnerName + "/" + run.Repo.Name, // string, The owner and repository name. For example, Codertocat/Hello-World.
+ "repository_owner": run.Repo.OwnerName, // string, The repository owner's name. For example, Codertocat.
+ "repositoryUrl": run.Repo.HTMLURL(), // string, The Git URL to the repository. For example, git://github.com/codertocat/hello-world.git.
+ "retention_days": "", // string, The number of days that workflow run logs and artifacts are kept.
+ "run_id": "", // string, A unique number for each workflow run within a repository. This number does not change if you re-run the workflow run.
+ "run_number": fmt.Sprint(run.Index), // string, A unique number for each run of a particular workflow in a repository. This number begins at 1 for the workflow's first run, and increments with each new run. This number does not change if you re-run the workflow run.
+ "run_attempt": "", // string, A unique number for each attempt of a particular workflow run in a repository. This number begins at 1 for the workflow run's first attempt, and increments with each re-run.
+ "secret_source": "Actions", // string, The source of a secret used in a workflow. Possible values are None, Actions, Dependabot, or Codespaces.
+ "server_url": setting.AppURL, // string, The URL of the GitHub server. For example: https://github.com.
+ "sha": sha, // string, The commit SHA that triggered the workflow. The value of this commit SHA depends on the event that triggered the workflow. For more information, see "Events that trigger workflows." For example, ffac537e6cbbf934b08745a378932722df287a53.
+ "triggering_actor": "", // string, The username of the user that initiated the workflow run. If the workflow run is a re-run, this value may differ from github.actor. Any workflow re-runs will use the privileges of github.actor, even if the actor initiating the re-run (github.triggering_actor) has different privileges.
+ "workflow": run.WorkflowID, // string, The name of the workflow. If the workflow file doesn't specify a name, the value of this property is the full path of the workflow file in the repository.
+ "workspace": "", // string, The default working directory on the runner for steps, and the default location of your repository when using the checkout action.
+
+ // additional contexts
+ "gitea_default_actions_url": setting.Actions.DefaultActionsURL.URL(),
+ }
+
+ if job != nil {
+ gitContext["job"] = job.JobID
+ gitContext["run_id"] = fmt.Sprint(job.RunID)
+ gitContext["run_attempt"] = fmt.Sprint(job.Attempt)
+ }
+
+ return gitContext
+}
+
+type TaskNeed struct {
+ Result actions_model.Status
+ Outputs map[string]string
+}
+
+// FindTaskNeeds finds the `needs` for the task by the task's job
+func FindTaskNeeds(ctx context.Context, job *actions_model.ActionRunJob) (map[string]*TaskNeed, error) {
+ if len(job.Needs) == 0 {
+ return nil, nil
+ }
+ needs := container.SetOf(job.Needs...)
+
+ jobs, err := db.Find[actions_model.ActionRunJob](ctx, actions_model.FindRunJobOptions{RunID: job.RunID})
+ if err != nil {
+ return nil, fmt.Errorf("FindRunJobs: %w", err)
+ }
+
+ jobIDJobs := make(map[string][]*actions_model.ActionRunJob)
+ for _, job := range jobs {
+ jobIDJobs[job.JobID] = append(jobIDJobs[job.JobID], job)
+ }
+
+ ret := make(map[string]*TaskNeed, len(needs))
+ for jobID, jobsWithSameID := range jobIDJobs {
+ if !needs.Contains(jobID) {
+ continue
+ }
+ var jobOutputs map[string]string
+ for _, job := range jobsWithSameID {
+ if job.TaskID == 0 || !job.Status.IsDone() {
+ // it shouldn't happen, or the job has been rerun
+ continue
+ }
+ got, err := actions_model.FindTaskOutputByTaskID(ctx, job.TaskID)
+ if err != nil {
+ return nil, fmt.Errorf("FindTaskOutputByTaskID: %w", err)
+ }
+ outputs := make(map[string]string, len(got))
+ for _, v := range got {
+ outputs[v.OutputKey] = v.OutputValue
+ }
+ if len(jobOutputs) == 0 {
+ jobOutputs = outputs
+ } else {
+ jobOutputs = mergeTwoOutputs(outputs, jobOutputs)
+ }
+ }
+ ret[jobID] = &TaskNeed{
+ Outputs: jobOutputs,
+ Result: actions_model.AggregateJobStatus(jobsWithSameID),
+ }
+ }
+ return ret, nil
+}
+
+// mergeTwoOutputs merges two outputs from two different ActionRunJobs
+// Values with the same output name may be overridden. The user should ensure the output names are unique.
+// See https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#using-job-outputs-in-a-matrix-job
+func mergeTwoOutputs(o1, o2 map[string]string) map[string]string {
+ ret := make(map[string]string, len(o1))
+ for k1, v1 := range o1 {
+ if len(v1) > 0 {
+ ret[k1] = v1
+ } else {
+ ret[k1] = o2[k1]
+ }
+ }
+ return ret
+}
diff --git a/services/actions/context_test.go b/services/actions/context_test.go
new file mode 100644
index 0000000000..c96094ade8
--- /dev/null
+++ b/services/actions/context_test.go
@@ -0,0 +1,29 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package actions
+
+import (
+ "testing"
+
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/unittest"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestFindTaskNeeds(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ task := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionTask{ID: 51})
+ job := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRunJob{ID: task.JobID})
+
+ ret, err := FindTaskNeeds(t.Context(), job)
+ require.NoError(t, err)
+ assert.Len(t, ret, 1)
+ assert.Contains(t, ret, "job1")
+ assert.Len(t, ret["job1"].Outputs, 2)
+ assert.Equal(t, "abc", ret["job1"].Outputs["output_a"])
+ assert.Equal(t, "bbb", ret["job1"].Outputs["output_b"])
+}
diff --git a/services/actions/init.go b/services/actions/init.go
index 0f49cb6297..8f1db64e27 100644
--- a/services/actions/init.go
+++ b/services/actions/init.go
@@ -4,11 +4,11 @@
package actions
import (
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/queue"
- "code.gitea.io/gitea/modules/setting"
- notify_service "code.gitea.io/gitea/services/notify"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/setting"
+ notify_service "forgejo.org/services/notify"
)
func Init() {
diff --git a/services/actions/interface.go b/services/actions/interface.go
index d4fa782fec..54a30061bc 100644
--- a/services/actions/interface.go
+++ b/services/actions/interface.go
@@ -3,7 +3,7 @@
package actions
-import "code.gitea.io/gitea/services/context"
+import "forgejo.org/services/context"
// API for actions of a repository or organization
type API interface {
@@ -25,4 +25,6 @@ type API interface {
UpdateVariable(*context.APIContext)
// GetRegistrationToken get registration token
GetRegistrationToken(*context.APIContext)
+ // SearchActionRunJobs get pending Action run jobs
+ SearchActionRunJobs(*context.APIContext)
}
diff --git a/services/actions/job_emitter.go b/services/actions/job_emitter.go
index 1f859fcf70..d4ca029d46 100644
--- a/services/actions/job_emitter.go
+++ b/services/actions/job_emitter.go
@@ -8,10 +8,10 @@ import (
"errors"
"fmt"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/queue"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/queue"
"github.com/nektos/act/pkg/jobparser"
"xorm.io/builder"
diff --git a/services/actions/job_emitter_test.go b/services/actions/job_emitter_test.go
index 58c2dc3b24..a3e0e95d04 100644
--- a/services/actions/job_emitter_test.go
+++ b/services/actions/job_emitter_test.go
@@ -6,7 +6,7 @@ package actions
import (
"testing"
- actions_model "code.gitea.io/gitea/models/actions"
+ actions_model "forgejo.org/models/actions"
"github.com/stretchr/testify/assert"
)
diff --git a/services/actions/main_test.go b/services/actions/main_test.go
index ea37ff507a..71ec1d3426 100644
--- a/services/actions/main_test.go
+++ b/services/actions/main_test.go
@@ -6,10 +6,11 @@ package actions
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/actions/notifier.go b/services/actions/notifier.go
index 3a6dd9db5b..2d3a1d2107 100644
--- a/services/actions/notifier.go
+++ b/services/actions/notifier.go
@@ -6,20 +6,20 @@ package actions
import (
"context"
- issues_model "code.gitea.io/gitea/models/issues"
- packages_model "code.gitea.io/gitea/models/packages"
- perm_model "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- webhook_module "code.gitea.io/gitea/modules/webhook"
- "code.gitea.io/gitea/services/convert"
- notify_service "code.gitea.io/gitea/services/notify"
+ issues_model "forgejo.org/models/issues"
+ packages_model "forgejo.org/models/packages"
+ perm_model "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ webhook_module "forgejo.org/modules/webhook"
+ "forgejo.org/services/convert"
+ notify_service "forgejo.org/services/notify"
)
type actionsNotifier struct {
@@ -55,10 +55,20 @@ func (n *actionsNotifier) NewIssue(ctx context.Context, issue *issues_model.Issu
}).Notify(withMethod(ctx, "NewIssue"))
}
+func (n *actionsNotifier) IssueChangeTitle(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, _ string) {
+ ctx = withMethod(ctx, "IssueChangeTitle")
+
+ n.issueChange(ctx, doer, issue)
+}
+
// IssueChangeContent notifies change content of issue
-func (n *actionsNotifier) IssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, oldContent string) {
+func (n *actionsNotifier) IssueChangeContent(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, _ string) {
ctx = withMethod(ctx, "IssueChangeContent")
+ n.issueChange(ctx, doer, issue)
+}
+
+func (n *actionsNotifier) issueChange(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) {
var err error
if err = issue.LoadRepo(ctx); err != nil {
log.Error("LoadRepo: %v", err)
@@ -158,7 +168,7 @@ func (n *actionsNotifier) IssueChangeAssignee(ctx context.Context, doer *user_mo
hookEvent = webhook_module.HookEventPullRequestAssign
}
- notifyIssueChange(ctx, doer, issue, hookEvent, action)
+ notifyIssueChange(ctx, doer, issue, hookEvent, action, nil)
}
// IssueChangeMilestone notifies assignee to notifiers
@@ -177,11 +187,11 @@ func (n *actionsNotifier) IssueChangeMilestone(ctx context.Context, doer *user_m
hookEvent = webhook_module.HookEventPullRequestMilestone
}
- notifyIssueChange(ctx, doer, issue, hookEvent, action)
+ notifyIssueChange(ctx, doer, issue, hookEvent, action, nil)
}
func (n *actionsNotifier) IssueChangeLabels(ctx context.Context, doer *user_model.User, issue *issues_model.Issue,
- _, _ []*issues_model.Label,
+ addedLabels, removedLabels []*issues_model.Label,
) {
ctx = withMethod(ctx, "IssueChangeLabels")
@@ -190,10 +200,15 @@ func (n *actionsNotifier) IssueChangeLabels(ctx context.Context, doer *user_mode
hookEvent = webhook_module.HookEventPullRequestLabel
}
- notifyIssueChange(ctx, doer, issue, hookEvent, api.HookIssueLabelUpdated)
+ for _, added := range addedLabels {
+ notifyIssueChange(ctx, doer, issue, hookEvent, api.HookIssueLabelUpdated, added)
+ }
+ for _, removed := range removedLabels {
+ notifyIssueChange(ctx, doer, issue, hookEvent, api.HookIssueLabelCleared, removed)
+ }
}
-func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, event webhook_module.HookEventType, action api.HookIssueAction) {
+func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues_model.Issue, event webhook_module.HookEventType, action api.HookIssueAction, label *issues_model.Label) {
var err error
if err = issue.LoadRepo(ctx); err != nil {
log.Error("LoadRepo: %v", err)
@@ -205,6 +220,11 @@ func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues
return
}
+ var apiLabel *api.Label
+ if action == api.HookIssueLabelUpdated || action == api.HookIssueLabelCleared {
+ apiLabel = convert.ToLabel(label, issue.Repo, nil)
+ }
+
if issue.IsPull {
if err = issue.LoadPullRequest(ctx); err != nil {
log.Error("loadPullRequest: %v", err)
@@ -218,6 +238,7 @@ func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues
PullRequest: convert.ToAPIPullRequest(ctx, issue.PullRequest, nil),
Repository: convert.ToRepo(ctx, issue.Repo, access_model.Permission{AccessMode: perm_model.AccessModeNone}),
Sender: convert.ToUser(ctx, doer, nil),
+ Label: apiLabel,
}).
WithPullRequest(issue.PullRequest).
Notify(ctx)
@@ -232,6 +253,7 @@ func notifyIssueChange(ctx context.Context, doer *user_model.User, issue *issues
Issue: convert.ToAPIIssue(ctx, doer, issue),
Repository: convert.ToRepo(ctx, issue.Repo, permission),
Sender: convert.ToUser(ctx, doer, nil),
+ Label: apiLabel,
}).
Notify(ctx)
}
@@ -386,7 +408,7 @@ func (n *actionsNotifier) ForkRepository(ctx context.Context, doer *user_model.U
// Add to hook queue for created repo after session commit.
if u.IsOrganization() {
newNotifyInput(repo, doer, webhook_module.HookEventRepository).
- WithRef(oldRepo.DefaultBranch).
+ WithRef(git.RefNameFromBranch(oldRepo.DefaultBranch).String()).
WithPayload(&api.RepositoryPayload{
Action: api.HookRepoCreated,
Repository: convert.ToRepo(ctx, repo, access_model.Permission{AccessMode: perm_model.AccessModeOwner}),
diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go
index 4196cf7686..9de0b75ac7 100644
--- a/services/actions/notifier_helper.go
+++ b/services/actions/notifier_helper.go
@@ -11,30 +11,32 @@ import (
"slices"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- packages_model "code.gitea.io/gitea/models/packages"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- unit_model "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- actions_module "code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- webhook_module "code.gitea.io/gitea/modules/webhook"
- "code.gitea.io/gitea/services/convert"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ packages_model "forgejo.org/models/packages"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ actions_module "forgejo.org/modules/actions"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ webhook_module "forgejo.org/modules/webhook"
+ "forgejo.org/services/convert"
"github.com/nektos/act/pkg/jobparser"
"github.com/nektos/act/pkg/model"
)
-var methodCtxKey struct{}
+type methodCtx struct{}
+
+var methodCtxKey = methodCtx{}
// withMethod sets the notification method that this context currently executes.
// Used for debugging/ troubleshooting purposes.
@@ -67,7 +69,7 @@ type notifyInput struct {
Event webhook_module.HookEventType
// optional
- Ref string
+ Ref git.RefName
Payload api.Payloader
PullRequest *issues_model.PullRequest
}
@@ -91,7 +93,7 @@ func (input *notifyInput) WithDoer(doer *user_model.User) *notifyInput {
}
func (input *notifyInput) WithRef(ref string) *notifyInput {
- input.Ref = ref
+ input.Ref = git.RefName(ref)
return input
}
@@ -103,7 +105,7 @@ func (input *notifyInput) WithPayload(payload api.Payloader) *notifyInput {
func (input *notifyInput) WithPullRequest(pr *issues_model.PullRequest) *notifyInput {
input.PullRequest = pr
if input.Ref == "" {
- input.Ref = pr.GetGitRefName()
+ input.Ref = git.RefName(pr.GetGitRefName())
}
return input
}
@@ -117,18 +119,27 @@ func (input *notifyInput) Notify(ctx context.Context) {
}
func notify(ctx context.Context, input *notifyInput) error {
+ shouldDetectSchedules := input.Event == webhook_module.HookEventPush && input.Ref.BranchName() == input.Repo.DefaultBranch
if input.Doer.IsActions() {
// avoiding triggering cyclically, for example:
// a comment of an issue will trigger the runner to add a new comment as reply,
// and the new comment will trigger the runner again.
log.Debug("ignore executing %v for event %v whose doer is %v", getMethod(ctx), input.Event, input.Doer.Name)
+
+ // we should update schedule tasks in this case, because
+ // 1. schedule tasks cannot be triggered by other events, so cyclic triggering will not occur
+ // 2. some schedule tasks may update the repo periodically, so the refs of schedule tasks need to be updated
+ if shouldDetectSchedules {
+ return DetectAndHandleSchedules(ctx, input.Repo)
+ }
+
return nil
}
if input.Repo.IsEmpty || input.Repo.IsArchived {
return nil
}
if unit_model.TypeActions.UnitGlobalDisabled() {
- if err := actions_model.CleanRepoScheduleTasks(ctx, input.Repo); err != nil {
+ if err := actions_model.CleanRepoScheduleTasks(ctx, input.Repo, true); err != nil {
log.Error("CleanRepoScheduleTasks: %v", err)
}
return nil
@@ -146,20 +157,25 @@ func notify(ctx context.Context, input *notifyInput) error {
defer gitRepo.Close()
ref := input.Ref
- if ref != input.Repo.DefaultBranch && actions_module.IsDefaultBranchWorkflow(input.Event) {
+ if ref.BranchName() != input.Repo.DefaultBranch && actions_module.IsDefaultBranchWorkflow(input.Event) {
if ref != "" {
log.Warn("Event %q should only trigger workflows on the default branch, but its ref is %q. Will fall back to the default branch",
input.Event, ref)
}
- ref = input.Repo.DefaultBranch
+ ref = git.RefNameFromBranch(input.Repo.DefaultBranch)
}
if ref == "" {
log.Warn("Ref of event %q is empty, will fall back to the default branch", input.Event)
- ref = input.Repo.DefaultBranch
+ ref = git.RefNameFromBranch(input.Repo.DefaultBranch)
+ }
+
+ commitID, err := gitRepo.GetRefCommitID(ref.String())
+ if err != nil {
+ return fmt.Errorf("gitRepo.GetRefCommitID: %w", err)
}
// Get the commit object for the ref
- commit, err := gitRepo.GetCommit(ref)
+ commit, err := gitRepo.GetCommit(commitID)
if err != nil {
return fmt.Errorf("gitRepo.GetCommit: %w", err)
}
@@ -175,7 +191,6 @@ func notify(ctx context.Context, input *notifyInput) error {
var detectedWorkflows []*actions_module.DetectedWorkflow
actionsConfig := input.Repo.MustGetUnit(ctx, unit_model.TypeActions).ActionsConfig()
- shouldDetectSchedules := input.Event == webhook_module.HookEventPush && git.RefName(input.Ref).BranchName() == input.Repo.DefaultBranch
workflows, schedules, err := actions_module.DetectWorkflows(gitRepo, commit,
input.Event,
input.Payload,
@@ -233,12 +248,12 @@ func notify(ctx context.Context, input *notifyInput) error {
}
if shouldDetectSchedules {
- if err := handleSchedules(ctx, schedules, commit, input, ref); err != nil {
+ if err := handleSchedules(ctx, schedules, commit, input, ref.String()); err != nil {
return err
}
}
- return handleWorkflows(ctx, detectedWorkflows, commit, input, ref)
+ return handleWorkflows(ctx, detectedWorkflows, commit, input, ref.String())
}
func SkipPullRequestEvent(ctx context.Context, event webhook_module.HookEventType, repoID int64, commitSHA string) bool {
@@ -489,7 +504,7 @@ func handleSchedules(
log.Error("CountSchedules: %v", err)
return err
} else if count > 0 {
- if err := actions_model.CleanRepoScheduleTasks(ctx, input.Repo); err != nil {
+ if err := actions_model.CleanRepoScheduleTasks(ctx, input.Repo, false); err != nil {
log.Error("CleanRepoScheduleTasks: %v", err)
}
}
diff --git a/services/actions/notifier_helper_test.go b/services/actions/notifier_helper_test.go
index 3c23414b8e..9166dc3b95 100644
--- a/services/actions/notifier_helper_test.go
+++ b/services/actions/notifier_helper_test.go
@@ -6,16 +6,17 @@ package actions
import (
"testing"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ webhook_module "forgejo.org/modules/webhook"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func Test_SkipPullRequestEvent(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repoID := int64(1)
commitSHA := "1234"
diff --git a/services/actions/rerun.go b/services/actions/rerun.go
index 60f6650905..f6dd4af5c7 100644
--- a/services/actions/rerun.go
+++ b/services/actions/rerun.go
@@ -4,8 +4,8 @@
package actions
import (
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/modules/container"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/modules/container"
)
// GetAllRerunJobs get all jobs that need to be rerun when job should be rerun
diff --git a/services/actions/rerun_test.go b/services/actions/rerun_test.go
index a98de7b788..4b822e8da1 100644
--- a/services/actions/rerun_test.go
+++ b/services/actions/rerun_test.go
@@ -6,7 +6,7 @@ package actions
import (
"testing"
- actions_model "code.gitea.io/gitea/models/actions"
+ actions_model "forgejo.org/models/actions"
"github.com/stretchr/testify/assert"
)
diff --git a/services/actions/schedule_tasks.go b/services/actions/schedule_tasks.go
index 18f3324fd2..f66a6ca092 100644
--- a/services/actions/schedule_tasks.go
+++ b/services/actions/schedule_tasks.go
@@ -8,13 +8,13 @@ import (
"fmt"
"time"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
- webhook_module "code.gitea.io/gitea/modules/webhook"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
+ webhook_module "forgejo.org/modules/webhook"
"github.com/nektos/act/pkg/jobparser"
)
diff --git a/services/actions/task.go b/services/actions/task.go
new file mode 100644
index 0000000000..43c8deaa5f
--- /dev/null
+++ b/services/actions/task.go
@@ -0,0 +1,107 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package actions
+
+import (
+ "context"
+ "fmt"
+
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/db"
+ secret_model "forgejo.org/models/secret"
+
+ runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
+ "google.golang.org/protobuf/types/known/structpb"
+)
+
+func PickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv1.Task, bool, error) {
+ var (
+ task *runnerv1.Task
+ job *actions_model.ActionRunJob
+ )
+
+ if err := db.WithTx(ctx, func(ctx context.Context) error {
+ t, ok, err := actions_model.CreateTaskForRunner(ctx, runner)
+ if err != nil {
+ return fmt.Errorf("CreateTaskForRunner: %w", err)
+ }
+ if !ok {
+ return nil
+ }
+
+ if err := t.LoadAttributes(ctx); err != nil {
+ return fmt.Errorf("task LoadAttributes: %w", err)
+ }
+ job = t.Job
+
+ secrets, err := secret_model.GetSecretsOfTask(ctx, t)
+ if err != nil {
+ return fmt.Errorf("GetSecretsOfTask: %w", err)
+ }
+
+ vars, err := actions_model.GetVariablesOfRun(ctx, t.Job.Run)
+ if err != nil {
+ return fmt.Errorf("GetVariablesOfRun: %w", err)
+ }
+
+ needs, err := findTaskNeeds(ctx, job)
+ if err != nil {
+ return fmt.Errorf("findTaskNeeds: %w", err)
+ }
+
+ taskContext, err := generateTaskContext(t)
+ if err != nil {
+ return fmt.Errorf("generateTaskContext: %w", err)
+ }
+
+ task = &runnerv1.Task{
+ Id: t.ID,
+ WorkflowPayload: t.Job.WorkflowPayload,
+ Context: taskContext,
+ Secrets: secrets,
+ Vars: vars,
+ Needs: needs,
+ }
+
+ return nil
+ }); err != nil {
+ return nil, false, err
+ }
+
+ if task == nil {
+ return nil, false, nil
+ }
+
+ CreateCommitStatus(ctx, job)
+
+ return task, true, nil
+}
+
+func generateTaskContext(t *actions_model.ActionTask) (*structpb.Struct, error) {
+ giteaRuntimeToken, err := CreateAuthorizationToken(t.ID, t.Job.RunID, t.JobID)
+ if err != nil {
+ return nil, err
+ }
+
+ gitCtx := GenerateGiteaContext(t.Job.Run, t.Job)
+ gitCtx["token"] = t.Token
+ gitCtx["gitea_runtime_token"] = giteaRuntimeToken
+
+ return structpb.NewStruct(gitCtx)
+}
+
+func findTaskNeeds(ctx context.Context, taskJob *actions_model.ActionRunJob) (map[string]*runnerv1.TaskNeed, error) {
+ taskNeeds, err := FindTaskNeeds(ctx, taskJob)
+ if err != nil {
+ return nil, err
+ }
+ ret := make(map[string]*runnerv1.TaskNeed, len(taskNeeds))
+ for jobID, taskNeed := range taskNeeds {
+ ret[jobID] = &runnerv1.TaskNeed{
+ Outputs: taskNeed.Outputs,
+ Result: runnerv1.Result(taskNeed.Result),
+ }
+ }
+ return ret, nil
+}
diff --git a/services/actions/variables.go b/services/actions/variables.go
index 8dde9c4af5..fed1fd0890 100644
--- a/services/actions/variables.go
+++ b/services/actions/variables.go
@@ -8,10 +8,10 @@ import (
"regexp"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
- secret_service "code.gitea.io/gitea/services/secrets"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
+ secret_service "forgejo.org/services/secrets"
)
func CreateVariable(ctx context.Context, ownerID, repoID int64, name, data string) (*actions_model.ActionVariable, error) {
@@ -31,7 +31,7 @@ func CreateVariable(ctx context.Context, ownerID, repoID int64, name, data strin
return v, nil
}
-func UpdateVariable(ctx context.Context, variableID int64, name, data string) (bool, error) {
+func UpdateVariable(ctx context.Context, variableID, ownerID, repoID int64, name, data string) (bool, error) {
if err := secret_service.ValidateName(name); err != nil {
return false, err
}
@@ -41,16 +41,14 @@ func UpdateVariable(ctx context.Context, variableID int64, name, data string) (b
}
return actions_model.UpdateVariable(ctx, &actions_model.ActionVariable{
- ID: variableID,
- Name: strings.ToUpper(name),
- Data: util.ReserveLineBreakForTextarea(data),
+ ID: variableID,
+ Name: strings.ToUpper(name),
+ Data: util.ReserveLineBreakForTextarea(data),
+ OwnerID: ownerID,
+ RepoID: repoID,
})
}
-func DeleteVariableByID(ctx context.Context, variableID int64) error {
- return actions_model.DeleteVariable(ctx, variableID)
-}
-
func DeleteVariableByName(ctx context.Context, ownerID, repoID int64, name string) error {
if err := secret_service.ValidateName(name); err != nil {
return err
@@ -69,7 +67,8 @@ func DeleteVariableByName(ctx context.Context, ownerID, repoID int64, name strin
return err
}
- return actions_model.DeleteVariable(ctx, v.ID)
+ _, err = actions_model.DeleteVariable(ctx, v.ID, ownerID, repoID)
+ return err
}
func GetVariable(ctx context.Context, opts actions_model.FindVariablesOpts) (*actions_model.ActionVariable, error) {
diff --git a/services/actions/workflows.go b/services/actions/workflows.go
index 726b56f464..7ec7c3abed 100644
--- a/services/actions/workflows.go
+++ b/services/actions/workflows.go
@@ -10,18 +10,19 @@ import (
"fmt"
"strconv"
- actions_model "code.gitea.io/gitea/models/actions"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/actions"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/webhook"
- "code.gitea.io/gitea/services/convert"
+ actions_model "forgejo.org/models/actions"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/user"
+ "forgejo.org/modules/actions"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/webhook"
+ "forgejo.org/services/convert"
"github.com/nektos/act/pkg/jobparser"
act_model "github.com/nektos/act/pkg/model"
@@ -49,15 +50,15 @@ type Workflow struct {
type InputValueGetter func(key string) string
-func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGetter, repo *repo_model.Repository, doer *user.User) error {
+func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGetter, repo *repo_model.Repository, doer *user.User) (r *actions_model.ActionRun, j []string, err error) {
content, err := actions.GetContentFromEntry(entry.GitEntry)
if err != nil {
- return err
+ return nil, nil, err
}
wf, err := act_model.ReadWorkflow(bytes.NewReader(content))
if err != nil {
- return err
+ return nil, nil, err
}
fullWorkflowID := ".forgejo/workflows/" + entry.WorkflowID
@@ -79,25 +80,24 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette
if len(name) == 0 {
name = key
}
- return InputRequiredErr{Name: name}
+ return nil, nil, InputRequiredErr{Name: name}
}
continue
}
- } else {
- switch input.Type {
- case "boolean":
- // Since "boolean" inputs are rendered as a checkbox in html, the value inside the form is "on"
- val = strconv.FormatBool(val == "on")
- }
+ } else if input.Type == "boolean" {
+ // Since "boolean" inputs are rendered as a checkbox in html, the value inside the form is "on"
+ val = strconv.FormatBool(val == "on")
}
inputs[key] = val
}
}
if int64(len(inputs)) > setting.Actions.LimitDispatchInputs {
- return errors.New("to many inputs")
+ return nil, nil, errors.New("to many inputs")
}
+ jobNames := util.KeysOfMap(wf.Jobs)
+
payload := &structs.WorkflowDispatchPayload{
Inputs: inputs,
Ref: entry.Ref,
@@ -108,7 +108,7 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette
p, err := json.Marshal(payload)
if err != nil {
- return err
+ return nil, nil, err
}
run := &actions_model.ActionRun{
@@ -129,15 +129,15 @@ func (entry *Workflow) Dispatch(ctx context.Context, inputGetter InputValueGette
vars, err := actions_model.GetVariablesOfRun(ctx, run)
if err != nil {
- return err
+ return nil, nil, err
}
jobs, err := jobparser.Parse(content, jobparser.WithVars(vars))
if err != nil {
- return err
+ return nil, nil, err
}
- return actions_model.InsertRun(ctx, run, jobs)
+ return run, jobNames, actions_model.InsertRun(ctx, run, jobs)
}
func GetWorkflowFromCommit(gitRepo *git.Repository, ref, workflowID string) (*Workflow, error) {
diff --git a/services/agit/agit.go b/services/agit/agit.go
index e46a5771e1..20e87642c3 100644
--- a/services/agit/agit.go
+++ b/services/agit/agit.go
@@ -9,24 +9,25 @@ import (
"os"
"strings"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/private"
- notify_service "code.gitea.io/gitea/services/notify"
- pull_service "code.gitea.io/gitea/services/pull"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/git/pushoptions"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/private"
+ notify_service "forgejo.org/services/notify"
+ pull_service "forgejo.org/services/pull"
)
// ProcReceive handle proc receive work
func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, opts *private.HookOptions) ([]private.HookProcReceiveRefResult, error) {
results := make([]private.HookProcReceiveRefResult, 0, len(opts.OldCommitIDs))
- topicBranch := opts.GitPushOptions["topic"]
- _, forcePush := opts.GitPushOptions["force-push"]
- title, hasTitle := opts.GitPushOptions["title"]
- description, hasDesc := opts.GitPushOptions["description"]
+ topicBranch, _ := opts.GetGitPushOptions().GetString(pushoptions.AgitTopic)
+ _, forcePush := opts.GetGitPushOptions().GetString(pushoptions.AgitForcePush)
+ title, hasTitle := opts.GetGitPushOptions().GetString(pushoptions.AgitTitle)
+ description, hasDesc := opts.GetGitPushOptions().GetString(pushoptions.AgitDescription)
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
@@ -210,6 +211,8 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
return nil, fmt.Errorf("failed to update the reference of the pull request: %w", err)
}
+ // TODO: refactor to unify with `pull_service.AddTestPullRequestTask`
+
// Add the pull request to the merge conflicting checker queue.
pull_service.AddToTaskQueue(ctx, pr)
@@ -217,12 +220,19 @@ func ProcReceive(ctx context.Context, repo *repo_model.Repository, gitRepo *git.
return nil, fmt.Errorf("failed to load the issue of the pull request: %w", err)
}
+ // Validate pull request.
+ pull_service.ValidatePullRequest(ctx, pr, oldCommitID, opts.NewCommitIDs[i], pusher)
+
+ // TODO: call `InvalidateCodeComments`
+
// Create and notify about the new commits.
comment, err := pull_service.CreatePushPullComment(ctx, pusher, pr, oldCommitID, opts.NewCommitIDs[i])
if err == nil && comment != nil {
notify_service.PullRequestPushCommits(ctx, pusher, pr, comment)
}
notify_service.PullRequestSynchronized(ctx, pusher, pr)
+
+ // this always seems to be false
isForcePush := comment != nil && comment.IsForcePush
results = append(results, private.HookProcReceiveRefResult{
diff --git a/services/asymkey/deploy_key.go b/services/asymkey/deploy_key.go
index e127cbfc6e..4a2cb53eec 100644
--- a/services/asymkey/deploy_key.go
+++ b/services/asymkey/deploy_key.go
@@ -6,10 +6,10 @@ package asymkey
import (
"context"
- "code.gitea.io/gitea/models"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
)
// DeleteDeployKey deletes deploy key from its repository authorized_keys file if needed.
diff --git a/services/asymkey/main_test.go b/services/asymkey/main_test.go
index 3505b26f69..8ba76668b1 100644
--- a/services/asymkey/main_test.go
+++ b/services/asymkey/main_test.go
@@ -6,10 +6,11 @@ package asymkey
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/asymkey/sign.go b/services/asymkey/sign.go
index 8fb569939c..0030523b22 100644
--- a/services/asymkey/sign.go
+++ b/services/asymkey/sign.go
@@ -8,18 +8,18 @@ import (
"fmt"
"strings"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
)
type signingMode string
diff --git a/services/asymkey/ssh_key.go b/services/asymkey/ssh_key.go
index 83d7edafa3..f20445891d 100644
--- a/services/asymkey/ssh_key.go
+++ b/services/asymkey/ssh_key.go
@@ -6,9 +6,9 @@ package asymkey
import (
"context"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
)
// DeletePublicKey deletes SSH key information both in database and authorized_keys file.
diff --git a/services/asymkey/ssh_key_test.go b/services/asymkey/ssh_key_test.go
index fbd5d13ab2..24b28d295e 100644
--- a/services/asymkey/ssh_key_test.go
+++ b/services/asymkey/ssh_key_test.go
@@ -6,17 +6,18 @@ package asymkey
import (
"testing"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestAddLdapSSHPublicKeys(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
s := &auth.Source{ID: 1}
@@ -71,7 +72,7 @@ ssh-dss AAAAB3NzaC1kc3MAAACBAOChCC7lf6Uo9n7BmZ6M8St19PZf4Tn59NriyboW2x/DZuYAz3ib
OwnerID: user.ID,
LoginSourceID: s.ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
if err != nil {
continue
}
diff --git a/services/attachment/attachment.go b/services/attachment/attachment.go
index 4481966b4a..365bd7faf6 100644
--- a/services/attachment/attachment.go
+++ b/services/attachment/attachment.go
@@ -9,11 +9,12 @@ import (
"fmt"
"io"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/context/upload"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/validation"
+ "forgejo.org/services/context/upload"
"github.com/google/uuid"
)
@@ -43,6 +44,28 @@ func NewAttachment(ctx context.Context, attach *repo_model.Attachment, file io.R
return attach, err
}
+func NewExternalAttachment(ctx context.Context, attach *repo_model.Attachment) (*repo_model.Attachment, error) {
+ if attach.RepoID == 0 {
+ return nil, fmt.Errorf("attachment %s should belong to a repository", attach.Name)
+ }
+ if attach.ExternalURL == "" {
+ return nil, fmt.Errorf("attachment %s should have a external url", attach.Name)
+ }
+ if !validation.IsValidExternalURL(attach.ExternalURL) {
+ return nil, repo_model.ErrInvalidExternalURL{ExternalURL: attach.ExternalURL}
+ }
+
+ attach.UUID = uuid.New().String()
+
+ eng := db.GetEngine(ctx)
+ if attach.NoAutoTime {
+ eng.NoAutoTime()
+ }
+ _, err := eng.Insert(attach)
+
+ return attach, err
+}
+
// UploadAttachment upload new attachment into storage and update database
func UploadAttachment(ctx context.Context, file io.Reader, allowedTypes string, fileSize int64, attach *repo_model.Attachment) (*repo_model.Attachment, error) {
buf := make([]byte, 1024)
diff --git a/services/attachment/attachment_test.go b/services/attachment/attachment_test.go
index 142bcfe629..70b1e80d6a 100644
--- a/services/attachment/attachment_test.go
+++ b/services/attachment/attachment_test.go
@@ -8,14 +8,16 @@ import (
"path/filepath"
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
- _ "code.gitea.io/gitea/models/actions"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/forgefed"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
@@ -23,13 +25,13 @@ func TestMain(m *testing.M) {
}
func TestUploadAttachment(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
fPath := "./attachment_test.go"
f, err := os.Open(fPath)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer f.Close()
attach, err := NewAttachment(db.DefaultContext, &repo_model.Attachment{
@@ -37,10 +39,10 @@ func TestUploadAttachment(t *testing.T) {
UploaderID: user.ID,
Name: filepath.Base(fPath),
}, f, -1)
- assert.NoError(t, err)
+ require.NoError(t, err)
attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attach.UUID)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, user.ID, attachment.UploaderID)
assert.Equal(t, int64(0), attachment.DownloadCount)
}
diff --git a/services/auth/additional_scopes_test.go b/services/auth/additional_scopes_test.go
new file mode 100644
index 0000000000..9ab4e6e61f
--- /dev/null
+++ b/services/auth/additional_scopes_test.go
@@ -0,0 +1,32 @@
+package auth
+
+import (
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestGrantAdditionalScopes(t *testing.T) {
+ tests := []struct {
+ grantScopes string
+ expectedScopes string
+ }{
+ {"openid profile email", ""},
+ {"openid profile email groups", ""},
+ {"openid profile email all", "all"},
+ {"openid profile email read:user all", "read:user,all"},
+ {"openid profile email groups read:user", "read:user"},
+ {"read:user read:repository", "read:user,read:repository"},
+ {"read:user write:issue public-only", "read:user,write:issue,public-only"},
+ {"openid profile email read:user", "read:user"},
+ {"read:invalid_scope", ""},
+ {"read:invalid_scope,write:scope_invalid,just-plain-wrong", ""},
+ }
+
+ for _, test := range tests {
+ t.Run(test.grantScopes, func(t *testing.T) {
+ result := grantAdditionalScopes(test.grantScopes)
+ assert.Equal(t, test.expectedScopes, result)
+ })
+ }
+}
diff --git a/services/auth/auth.go b/services/auth/auth.go
index c10872313f..d0fa725854 100644
--- a/services/auth/auth.go
+++ b/services/auth/auth.go
@@ -10,15 +10,15 @@ import (
"regexp"
"strings"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/webauthn"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/session"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web/middleware"
- gitea_context "code.gitea.io/gitea/services/context"
- user_service "code.gitea.io/gitea/services/user"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/webauthn"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/session"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web/middleware"
+ gitea_context "forgejo.org/services/context"
+ user_service "forgejo.org/services/user"
)
// Init should be called exactly once when the application starts to allow plugins
@@ -61,6 +61,17 @@ func isArchivePath(req *http.Request) bool {
return archivePathRe.MatchString(req.URL.Path)
}
+var annexPathRe = regexp.MustCompile(`^(/git-annex-p2phttp/|/[a-zA-Z0-9_.-]+/[a-zA-Z0-9_.-]+/annex/)`)
+
+func isAnnexPath(req *http.Request) bool {
+ if setting.Annex.Enabled {
+ // "/config" is git's config, not specifically git-annex's; but the only current
+ // user of it is when git-annex downloads the annex.uuid during 'git annex init'.
+ return strings.HasSuffix(req.URL.Path, "/config") || annexPathRe.MatchString(req.URL.Path)
+ }
+ return false
+}
+
// handleSignIn clears existing session variables and stores new ones for the specified user object
func handleSignIn(resp http.ResponseWriter, req *http.Request, sess SessionStore, user *user_model.User) {
// We need to regenerate the session...
diff --git a/services/auth/auth_test.go b/services/auth/auth_test.go
index 3adaa28664..a6c6c74022 100644
--- a/services/auth/auth_test.go
+++ b/services/auth/auth_test.go
@@ -8,7 +8,7 @@ import (
"net/http"
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
)
func Test_isGitRawOrLFSPath(t *testing.T) {
diff --git a/services/auth/basic.go b/services/auth/basic.go
index c8cb1735ee..7adcd8914a 100644
--- a/services/auth/basic.go
+++ b/services/auth/basic.go
@@ -5,18 +5,19 @@
package auth
import (
+ "errors"
"net/http"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- auth_model "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web/middleware"
+ actions_model "forgejo.org/models/actions"
+ auth_model "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/util"
+ "forgejo.org/modules/web/middleware"
)
// Ensure the struct implements the interface.
@@ -42,8 +43,8 @@ func (b *Basic) Name() string {
// name/token on successful validation.
// Returns nil if header is empty or validation fails.
func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) {
- // Basic authentication should only fire on API, Download or on Git or LFSPaths
- if !middleware.IsAPIPath(req) && !isContainerPath(req) && !isAttachmentDownload(req) && !isGitRawOrAttachOrLFSPath(req) {
+ // Basic authentication should only fire on API, Download or on Git, LFSPaths or Git-Annex paths
+ if !middleware.IsAPIPath(req) && !isContainerPath(req) && !isAttachmentDownload(req) && !isGitRawOrAttachOrLFSPath(req) && !isAnnexPath(req) {
return nil, nil
}
@@ -72,7 +73,7 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore
}
// check oauth2 token
- uid := CheckOAuthAccessToken(req.Context(), authToken)
+ uid, _ := CheckOAuthAccessToken(req.Context(), authToken)
if uid != 0 {
log.Trace("Basic Authorization: Valid OAuthAccessToken for user[%d]", uid)
@@ -132,6 +133,16 @@ func (b *Basic) Verify(req *http.Request, w http.ResponseWriter, store DataStore
return nil, err
}
+ hashWebAuthn, err := auth_model.HasWebAuthnRegistrationsByUID(req.Context(), u.ID)
+ if err != nil {
+ log.Error("HasWebAuthnRegistrationsByUID: %v", err)
+ return nil, err
+ }
+
+ if hashWebAuthn {
+ return nil, errors.New("Basic authorization is not allowed while having security keys enrolled")
+ }
+
if skipper, ok := source.Cfg.(LocalTwoFASkipper); !ok || !skipper.IsSkipLocalTwoFA() {
if err := validateTOTP(req, u); err != nil {
return nil, err
diff --git a/services/auth/group.go b/services/auth/group.go
index aecf43cb24..b713301b50 100644
--- a/services/auth/group.go
+++ b/services/auth/group.go
@@ -7,7 +7,7 @@ import (
"net/http"
"strings"
- user_model "code.gitea.io/gitea/models/user"
+ user_model "forgejo.org/models/user"
)
// Ensure the struct implements the interface.
diff --git a/services/auth/httpsign.go b/services/auth/httpsign.go
index b604349f80..d3cbb8aa60 100644
--- a/services/auth/httpsign.go
+++ b/services/auth/httpsign.go
@@ -11,13 +11,13 @@ import (
"net/http"
"strings"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
- "github.com/go-fed/httpsig"
+ "github.com/42wim/httpsig"
"golang.org/x/crypto/ssh"
)
@@ -205,7 +205,7 @@ func doVerify(verifier httpsig.Verifier, sshPublicKeys []ssh.PublicKey) error {
case strings.HasPrefix(publicKey.Type(), "ssh-ed25519"):
algos = []httpsig.Algorithm{httpsig.ED25519}
case strings.HasPrefix(publicKey.Type(), "ssh-rsa"):
- algos = []httpsig.Algorithm{httpsig.RSA_SHA1, httpsig.RSA_SHA256, httpsig.RSA_SHA512}
+ algos = []httpsig.Algorithm{httpsig.RSA_SHA256, httpsig.RSA_SHA512}
}
for _, algo := range algos {
if err := verifier.Verify(cryptoPubkey, algo); err == nil {
diff --git a/services/auth/interface.go b/services/auth/interface.go
index ece28af12d..12b04a7abf 100644
--- a/services/auth/interface.go
+++ b/services/auth/interface.go
@@ -7,9 +7,9 @@ import (
"context"
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/session"
- "code.gitea.io/gitea/modules/web/middleware"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/session"
+ "forgejo.org/modules/web/middleware"
)
// DataStore represents a data store
diff --git a/services/auth/main_test.go b/services/auth/main_test.go
index b81c39a1f2..0e6315b06e 100644
--- a/services/auth/main_test.go
+++ b/services/auth/main_test.go
@@ -6,7 +6,7 @@ package auth
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/services/auth/oauth2.go b/services/auth/oauth2.go
index 46d8510143..e6d556d10b 100644
--- a/services/auth/oauth2.go
+++ b/services/auth/oauth2.go
@@ -7,17 +7,19 @@ package auth
import (
"context"
"net/http"
+ "slices"
"strings"
"time"
- actions_model "code.gitea.io/gitea/models/actions"
- auth_model "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/auth/source/oauth2"
+ actions_model "forgejo.org/models/actions"
+ auth_model "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/actions"
+ "forgejo.org/services/auth/source/oauth2"
)
// Ensure the struct implements the interface.
@@ -25,28 +27,84 @@ var (
_ Method = &OAuth2{}
)
+// grantAdditionalScopes returns valid scopes coming from grant
+func grantAdditionalScopes(grantScopes string) string {
+ // scopes_supported from templates/user/auth/oidc_wellknown.tmpl
+ scopesSupported := []string{
+ "openid",
+ "profile",
+ "email",
+ "groups",
+ }
+
+ var apiTokenScopes []string
+ for _, apiTokenScope := range strings.Split(grantScopes, " ") {
+ if slices.Index(scopesSupported, apiTokenScope) == -1 {
+ apiTokenScopes = append(apiTokenScopes, apiTokenScope)
+ }
+ }
+
+ if len(apiTokenScopes) == 0 {
+ return ""
+ }
+
+ var additionalGrantScopes []string
+ allScopes := auth_model.AccessTokenScope("all")
+
+ for _, apiTokenScope := range apiTokenScopes {
+ grantScope := auth_model.AccessTokenScope(apiTokenScope)
+ if ok, _ := allScopes.HasScope(grantScope); ok {
+ additionalGrantScopes = append(additionalGrantScopes, apiTokenScope)
+ } else if apiTokenScope == "public-only" {
+ additionalGrantScopes = append(additionalGrantScopes, apiTokenScope)
+ }
+ }
+ if len(additionalGrantScopes) > 0 {
+ return strings.Join(additionalGrantScopes, ",")
+ }
+
+ return ""
+}
+
// CheckOAuthAccessToken returns uid of user from oauth token
-func CheckOAuthAccessToken(ctx context.Context, accessToken string) int64 {
+// + non default openid scopes requested
+func CheckOAuthAccessToken(ctx context.Context, accessToken string) (int64, string) {
+ if !setting.OAuth2.Enabled {
+ return 0, ""
+ }
// JWT tokens require a "."
if !strings.Contains(accessToken, ".") {
- return 0
+ return 0, ""
}
token, err := oauth2.ParseToken(accessToken, oauth2.DefaultSigningKey)
if err != nil {
log.Trace("oauth2.ParseToken: %v", err)
- return 0
+ return 0, ""
}
var grant *auth_model.OAuth2Grant
if grant, err = auth_model.GetOAuth2GrantByID(ctx, token.GrantID); err != nil || grant == nil {
- return 0
+ return 0, ""
}
if token.Type != oauth2.TypeAccessToken {
- return 0
+ return 0, ""
}
if token.ExpiresAt.Before(time.Now()) || token.IssuedAt.After(time.Now()) {
- return 0
+ return 0, ""
}
- return grant.UserID
+ grantScopes := grantAdditionalScopes(grant.Scope)
+ return grant.UserID, grantScopes
+}
+
+// CheckTaskIsRunning verifies that the TaskID corresponds to a running task
+func CheckTaskIsRunning(ctx context.Context, taskID int64) bool {
+ // Verify the task exists
+ task, err := actions_model.GetTaskByID(ctx, taskID)
+ if err != nil {
+ return false
+ }
+
+ // Verify that it's running
+ return task.Status == actions_model.StatusRunning
}
// OAuth2 implements the Auth interface and authenticates requests
@@ -92,10 +150,24 @@ func parseToken(req *http.Request) (string, bool) {
func (o *OAuth2) userIDFromToken(ctx context.Context, tokenSHA string, store DataStore) int64 {
// Let's see if token is valid.
if strings.Contains(tokenSHA, ".") {
- uid := CheckOAuthAccessToken(ctx, tokenSHA)
+ // First attempt to decode an actions JWT, returning the actions user
+ if taskID, err := actions.TokenToTaskID(tokenSHA); err == nil {
+ if CheckTaskIsRunning(ctx, taskID) {
+ store.GetData()["IsActionsToken"] = true
+ store.GetData()["ActionsTaskID"] = taskID
+ return user_model.ActionsUserID
+ }
+ }
+
+ // Otherwise, check if this is an OAuth access token
+ uid, grantScopes := CheckOAuthAccessToken(ctx, tokenSHA)
if uid != 0 {
store.GetData()["IsApiToken"] = true
- store.GetData()["ApiTokenScope"] = auth_model.AccessTokenScopeAll // fallback to all
+ if grantScopes != "" {
+ store.GetData()["ApiTokenScope"] = auth_model.AccessTokenScope(grantScopes)
+ } else {
+ store.GetData()["ApiTokenScope"] = auth_model.AccessTokenScopeAll // fallback to all
+ }
}
return uid
}
diff --git a/services/auth/oauth2_test.go b/services/auth/oauth2_test.go
new file mode 100644
index 0000000000..d6455b33ad
--- /dev/null
+++ b/services/auth/oauth2_test.go
@@ -0,0 +1,54 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package auth
+
+import (
+ "testing"
+
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/actions"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestUserIDFromToken(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ t.Run("Actions JWT", func(t *testing.T) {
+ const RunningTaskID = 47
+ token, err := actions.CreateAuthorizationToken(RunningTaskID, 1, 2)
+ require.NoError(t, err)
+
+ ds := make(middleware.ContextData)
+
+ o := OAuth2{}
+ uid := o.userIDFromToken(t.Context(), token, ds)
+ assert.Equal(t, int64(user_model.ActionsUserID), uid)
+ assert.Equal(t, true, ds["IsActionsToken"])
+ assert.Equal(t, ds["ActionsTaskID"], int64(RunningTaskID))
+ })
+}
+
+func TestCheckTaskIsRunning(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+ cases := map[string]struct {
+ TaskID int64
+ Expected bool
+ }{
+ "Running": {TaskID: 47, Expected: true},
+ "Missing": {TaskID: 1, Expected: false},
+ "Cancelled": {TaskID: 46, Expected: false},
+ }
+
+ for name := range cases {
+ c := cases[name]
+ t.Run(name, func(t *testing.T) {
+ actual := CheckTaskIsRunning(t.Context(), c.TaskID)
+ assert.Equal(t, c.Expected, actual)
+ })
+ }
+}
diff --git a/services/auth/reverseproxy.go b/services/auth/reverseproxy.go
index b6aeb0aed2..eb9ceb8cf2 100644
--- a/services/auth/reverseproxy.go
+++ b/services/auth/reverseproxy.go
@@ -8,11 +8,11 @@ import (
"net/http"
"strings"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web/middleware"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web/middleware"
gouuid "github.com/google/uuid"
)
@@ -164,6 +164,11 @@ func (r *ReverseProxy) newUser(req *http.Request) *user_model.User {
IsActive: optional.Some(true),
}
+ // The first user created should be an admin.
+ if user_model.CountUsers(req.Context(), nil) == 0 {
+ user.IsAdmin = true
+ }
+
if err := user_model.CreateUser(req.Context(), user, &overwriteDefault); err != nil {
// FIXME: should I create a system notice?
log.Error("CreateUser: %v", err)
diff --git a/services/auth/reverseproxy_test.go b/services/auth/reverseproxy_test.go
new file mode 100644
index 0000000000..70ce1f8b0b
--- /dev/null
+++ b/services/auth/reverseproxy_test.go
@@ -0,0 +1,67 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package auth
+
+import (
+ "net/http"
+ "testing"
+
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestReverseProxyAuth(t *testing.T) {
+ defer test.MockVariableValue(&setting.Service.EnableReverseProxyEmail, true)()
+ defer test.MockVariableValue(&setting.Service.EnableReverseProxyFullName, true)()
+ defer test.MockVariableValue(&setting.Service.EnableReverseProxyFullName, true)()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{}))
+ require.EqualValues(t, 0, user_model.CountUsers(db.DefaultContext, nil))
+
+ t.Run("First user should be admin", func(t *testing.T) {
+ req, err := http.NewRequest("GET", "/", nil)
+ require.NoError(t, err)
+
+ req.Header.Add(setting.ReverseProxyAuthUser, "Edgar")
+ req.Header.Add(setting.ReverseProxyAuthFullName, "Edgar Allan Poe")
+ req.Header.Add(setting.ReverseProxyAuthEmail, "edgar@example.org")
+
+ rp := &ReverseProxy{}
+ user := rp.newUser(req)
+
+ require.EqualValues(t, 1, user_model.CountUsers(db.DefaultContext, nil))
+ unittest.AssertExistsAndLoadBean(t, &user_model.User{Email: "edgar@example.org", Name: "Edgar", LowerName: "edgar", FullName: "Edgar Allan Poe", IsAdmin: true})
+ require.EqualValues(t, "edgar@example.org", user.Email)
+ require.EqualValues(t, "Edgar", user.Name)
+ require.EqualValues(t, "edgar", user.LowerName)
+ require.EqualValues(t, "Edgar Allan Poe", user.FullName)
+ require.True(t, user.IsAdmin)
+ })
+
+ t.Run("Second user shouldn't be admin", func(t *testing.T) {
+ req, err := http.NewRequest("GET", "/", nil)
+ require.NoError(t, err)
+
+ req.Header.Add(setting.ReverseProxyAuthUser, " Gusted ")
+ req.Header.Add(setting.ReverseProxyAuthFullName, "โคโฟโค")
+ req.Header.Add(setting.ReverseProxyAuthEmail, "gusted@example.org")
+
+ rp := &ReverseProxy{}
+ user := rp.newUser(req)
+
+ require.EqualValues(t, 2, user_model.CountUsers(db.DefaultContext, nil))
+ unittest.AssertExistsAndLoadBean(t, &user_model.User{Email: "gusted@example.org", Name: "Gusted", LowerName: "gusted", FullName: "โคโฟโค"}, "is_admin = false")
+ require.EqualValues(t, "gusted@example.org", user.Email)
+ require.EqualValues(t, "Gusted", user.Name)
+ require.EqualValues(t, "gusted", user.LowerName)
+ require.EqualValues(t, "โคโฟโค", user.FullName)
+ require.False(t, user.IsAdmin)
+ })
+}
diff --git a/services/auth/session.go b/services/auth/session.go
index 35d97e42da..a15c24c940 100644
--- a/services/auth/session.go
+++ b/services/auth/session.go
@@ -6,8 +6,8 @@ package auth
import (
"net/http"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
)
// Ensure the struct implements the interface.
diff --git a/services/auth/signin.go b/services/auth/signin.go
index e116a088e0..495b3d387e 100644
--- a/services/auth/signin.go
+++ b/services/auth/signin.go
@@ -7,18 +7,17 @@ import (
"context"
"strings"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/services/auth/source/oauth2"
- "code.gitea.io/gitea/services/auth/source/smtp"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/services/auth/source/oauth2"
+ "forgejo.org/services/auth/source/smtp"
- _ "code.gitea.io/gitea/services/auth/source/db" // register the sources (and below)
- _ "code.gitea.io/gitea/services/auth/source/ldap" // register the ldap source
- _ "code.gitea.io/gitea/services/auth/source/pam" // register the pam source
- _ "code.gitea.io/gitea/services/auth/source/sspi" // register the sspi source
+ _ "forgejo.org/services/auth/source/db" // register the sources (and below)
+ _ "forgejo.org/services/auth/source/ldap" // register the ldap source
+ _ "forgejo.org/services/auth/source/pam" // register the pam source
)
// UserSignIn validates user name and password.
diff --git a/services/auth/source.go b/services/auth/source.go
index 69b71a6dea..b13554efde 100644
--- a/services/auth/source.go
+++ b/services/auth/source.go
@@ -6,9 +6,9 @@ package auth
import (
"context"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
)
// DeleteSource deletes a AuthSource record in DB.
diff --git a/services/auth/source/db/assert_interface_test.go b/services/auth/source/db/assert_interface_test.go
index 62387c78f0..1422e9693c 100644
--- a/services/auth/source/db/assert_interface_test.go
+++ b/services/auth/source/db/assert_interface_test.go
@@ -4,9 +4,9 @@
package db_test
import (
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/db"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/db"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/db/authenticate.go b/services/auth/source/db/authenticate.go
index 8160141863..7c18540a10 100644
--- a/services/auth/source/db/authenticate.go
+++ b/services/auth/source/db/authenticate.go
@@ -7,9 +7,9 @@ import (
"context"
"fmt"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
)
// ErrUserPasswordNotSet represents a "ErrUserPasswordNotSet" kind of error.
diff --git a/services/auth/source/db/source.go b/services/auth/source/db/source.go
index bb2270cbd6..d158718bb2 100644
--- a/services/auth/source/db/source.go
+++ b/services/auth/source/db/source.go
@@ -6,8 +6,8 @@ package db
import (
"context"
- "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
)
// Source is a password authentication service
diff --git a/services/auth/source/ldap/assert_interface_test.go b/services/auth/source/ldap/assert_interface_test.go
index 33347687dc..859143a3f8 100644
--- a/services/auth/source/ldap/assert_interface_test.go
+++ b/services/auth/source/ldap/assert_interface_test.go
@@ -4,9 +4,9 @@
package ldap_test
import (
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/ldap"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/ldap"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/ldap/source.go b/services/auth/source/ldap/source.go
index ba407b351a..a094c1410c 100644
--- a/services/auth/source/ldap/source.go
+++ b/services/auth/source/ldap/source.go
@@ -6,10 +6,10 @@ package ldap
import (
"strings"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/secret"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/auth"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/secret"
+ "forgejo.org/modules/setting"
)
// .____ ________ _____ __________
diff --git a/services/auth/source/ldap/source_authenticate.go b/services/auth/source/ldap/source_authenticate.go
index 68ecd16342..a2ff10cd07 100644
--- a/services/auth/source/ldap/source_authenticate.go
+++ b/services/auth/source/ldap/source_authenticate.go
@@ -8,13 +8,13 @@ import (
"fmt"
"strings"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- auth_module "code.gitea.io/gitea/modules/auth"
- "code.gitea.io/gitea/modules/optional"
- source_service "code.gitea.io/gitea/services/auth/source"
- user_service "code.gitea.io/gitea/services/user"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ auth_module "forgejo.org/modules/auth"
+ "forgejo.org/modules/optional"
+ source_service "forgejo.org/services/auth/source"
+ user_service "forgejo.org/services/user"
)
// Authenticate queries if login/password is valid against the LDAP directory pool,
diff --git a/services/auth/source/ldap/source_search.go b/services/auth/source/ldap/source_search.go
index 2a61386ae1..da7e225428 100644
--- a/services/auth/source/ldap/source_search.go
+++ b/services/auth/source/ldap/source_search.go
@@ -11,8 +11,8 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
"github.com/go-ldap/ldap/v3"
)
diff --git a/services/auth/source/ldap/source_sync.go b/services/auth/source/ldap/source_sync.go
index 1f70edaa82..cb6172ed1d 100644
--- a/services/auth/source/ldap/source_sync.go
+++ b/services/auth/source/ldap/source_sync.go
@@ -8,16 +8,16 @@ import (
"fmt"
"strings"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
- auth_module "code.gitea.io/gitea/modules/auth"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- source_service "code.gitea.io/gitea/services/auth/source"
- user_service "code.gitea.io/gitea/services/user"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/db"
+ "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ auth_module "forgejo.org/modules/auth"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ source_service "forgejo.org/services/auth/source"
+ user_service "forgejo.org/services/user"
)
// Sync causes this ldap source to synchronize its users with the db
diff --git a/services/auth/source/oauth2/assert_interface_test.go b/services/auth/source/oauth2/assert_interface_test.go
index 56fe0e4aa8..12fce257cf 100644
--- a/services/auth/source/oauth2/assert_interface_test.go
+++ b/services/auth/source/oauth2/assert_interface_test.go
@@ -4,9 +4,9 @@
package oauth2_test
import (
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/oauth2"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/oauth2"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/oauth2/init.go b/services/auth/source/oauth2/init.go
index 5c25681548..6c78a14da4 100644
--- a/services/auth/source/oauth2/init.go
+++ b/services/auth/source/oauth2/init.go
@@ -9,11 +9,11 @@ import (
"net/http"
"sync"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
"github.com/google/uuid"
"github.com/gorilla/sessions"
diff --git a/services/auth/source/oauth2/jwtsigningkey.go b/services/auth/source/oauth2/jwtsigningkey.go
index 070fffe60f..550945a812 100644
--- a/services/auth/source/oauth2/jwtsigningkey.go
+++ b/services/auth/source/oauth2/jwtsigningkey.go
@@ -18,9 +18,9 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
"github.com/golang-jwt/jwt/v5"
)
@@ -347,12 +347,30 @@ func loadOrCreateAsymmetricKey() (any, error) {
key, err := func() (any, error) {
switch {
case strings.HasPrefix(setting.OAuth2.JWTSigningAlgorithm, "RS"):
- return rsa.GenerateKey(rand.Reader, 4096)
+ var bits int
+ switch setting.OAuth2.JWTSigningAlgorithm {
+ case "RS256":
+ bits = 2048
+ case "RS384":
+ bits = 3072
+ case "RS512":
+ bits = 4096
+ }
+ return rsa.GenerateKey(rand.Reader, bits)
case setting.OAuth2.JWTSigningAlgorithm == "EdDSA":
_, pk, err := ed25519.GenerateKey(rand.Reader)
return pk, err
default:
- return ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
+ var curve elliptic.Curve
+ switch setting.OAuth2.JWTSigningAlgorithm {
+ case "ES256":
+ curve = elliptic.P256()
+ case "ES384":
+ curve = elliptic.P384()
+ case "ES512":
+ curve = elliptic.P521()
+ }
+ return ecdsa.GenerateKey(curve, rand.Reader)
}
}()
if err != nil {
diff --git a/services/auth/source/oauth2/jwtsigningkey_test.go b/services/auth/source/oauth2/jwtsigningkey_test.go
new file mode 100644
index 0000000000..7cf2833696
--- /dev/null
+++ b/services/auth/source/oauth2/jwtsigningkey_test.go
@@ -0,0 +1,116 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package oauth2
+
+import (
+ "crypto/ecdsa"
+ "crypto/ed25519"
+ "crypto/rsa"
+ "crypto/x509"
+ "encoding/pem"
+ "os"
+ "path/filepath"
+ "testing"
+
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestLoadOrCreateAsymmetricKey(t *testing.T) {
+ loadKey := func(t *testing.T) any {
+ t.Helper()
+ loadOrCreateAsymmetricKey()
+
+ fileContent, err := os.ReadFile(setting.OAuth2.JWTSigningPrivateKeyFile)
+ require.NoError(t, err)
+
+ block, _ := pem.Decode(fileContent)
+ assert.NotNil(t, block)
+ assert.EqualValues(t, "PRIVATE KEY", block.Type)
+
+ parsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
+ require.NoError(t, err)
+
+ return parsedKey
+ }
+ t.Run("RSA-2048", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningPrivateKeyFile, filepath.Join(t.TempDir(), "jwt-rsa-2048.priv"))()
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningAlgorithm, "RS256")()
+
+ parsedKey := loadKey(t)
+
+ rsaPrivateKey := parsedKey.(*rsa.PrivateKey)
+ assert.EqualValues(t, 2048, rsaPrivateKey.N.BitLen())
+
+ t.Run("Load key with differ specified algorithm", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningAlgorithm, "EdDSA")()
+
+ parsedKey := loadKey(t)
+ rsaPrivateKey := parsedKey.(*rsa.PrivateKey)
+ assert.EqualValues(t, 2048, rsaPrivateKey.N.BitLen())
+ })
+ })
+
+ t.Run("RSA-3072", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningPrivateKeyFile, filepath.Join(t.TempDir(), "jwt-rsa-3072.priv"))()
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningAlgorithm, "RS384")()
+
+ parsedKey := loadKey(t)
+
+ rsaPrivateKey := parsedKey.(*rsa.PrivateKey)
+ assert.EqualValues(t, 3072, rsaPrivateKey.N.BitLen())
+ })
+
+ t.Run("RSA-4096", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningPrivateKeyFile, filepath.Join(t.TempDir(), "jwt-rsa-4096.priv"))()
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningAlgorithm, "RS512")()
+
+ parsedKey := loadKey(t)
+
+ rsaPrivateKey := parsedKey.(*rsa.PrivateKey)
+ assert.EqualValues(t, 4096, rsaPrivateKey.N.BitLen())
+ })
+
+ t.Run("ECDSA-256", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningPrivateKeyFile, filepath.Join(t.TempDir(), "jwt-ecdsa-256.priv"))()
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningAlgorithm, "ES256")()
+
+ parsedKey := loadKey(t)
+
+ ecdsaPrivateKey := parsedKey.(*ecdsa.PrivateKey)
+ assert.EqualValues(t, 256, ecdsaPrivateKey.Params().BitSize)
+ })
+
+ t.Run("ECDSA-384", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningPrivateKeyFile, filepath.Join(t.TempDir(), "jwt-ecdsa-384.priv"))()
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningAlgorithm, "ES384")()
+
+ parsedKey := loadKey(t)
+
+ ecdsaPrivateKey := parsedKey.(*ecdsa.PrivateKey)
+ assert.EqualValues(t, 384, ecdsaPrivateKey.Params().BitSize)
+ })
+
+ t.Run("ECDSA-512", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningPrivateKeyFile, filepath.Join(t.TempDir(), "jwt-ecdsa-512.priv"))()
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningAlgorithm, "ES512")()
+
+ parsedKey := loadKey(t)
+
+ ecdsaPrivateKey := parsedKey.(*ecdsa.PrivateKey)
+ assert.EqualValues(t, 521, ecdsaPrivateKey.Params().BitSize)
+ })
+
+ t.Run("EdDSA", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningPrivateKeyFile, filepath.Join(t.TempDir(), "jwt-eddsa.priv"))()
+ defer test.MockVariableValue(&setting.OAuth2.JWTSigningAlgorithm, "EdDSA")()
+
+ parsedKey := loadKey(t)
+
+ assert.NotNil(t, parsedKey.(ed25519.PrivateKey))
+ })
+}
diff --git a/services/auth/source/oauth2/providers.go b/services/auth/source/oauth2/providers.go
index f2c1bb4894..773ce19c12 100644
--- a/services/auth/source/oauth2/providers.go
+++ b/services/auth/source/oauth2/providers.go
@@ -12,11 +12,11 @@ import (
"net/url"
"sort"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
"github.com/markbates/goth"
)
diff --git a/services/auth/source/oauth2/providers_base.go b/services/auth/source/oauth2/providers_base.go
index 9d4ab106e5..1ef8d0af72 100644
--- a/services/auth/source/oauth2/providers_base.go
+++ b/services/auth/source/oauth2/providers_base.go
@@ -6,8 +6,8 @@ package oauth2
import (
"html/template"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/svg"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/svg"
)
// BaseProvider represents a common base for Provider
@@ -48,4 +48,8 @@ func (b *BaseProvider) CustomURLSettings() *CustomURLSettings {
return nil
}
+func (b *BaseProvider) CanProvideSSHKeys() bool {
+ return false
+}
+
var _ Provider = &BaseProvider{}
diff --git a/services/auth/source/oauth2/providers_custom.go b/services/auth/source/oauth2/providers_custom.go
index 65cf538ad7..51a412e0be 100644
--- a/services/auth/source/oauth2/providers_custom.go
+++ b/services/auth/source/oauth2/providers_custom.go
@@ -4,7 +4,7 @@
package oauth2
import (
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/markbates/goth"
"github.com/markbates/goth/providers/azureadv2"
diff --git a/services/auth/source/oauth2/providers_openid.go b/services/auth/source/oauth2/providers_openid.go
index 285876d5ac..7950506ab7 100644
--- a/services/auth/source/oauth2/providers_openid.go
+++ b/services/auth/source/oauth2/providers_openid.go
@@ -6,9 +6,9 @@ package oauth2
import (
"html/template"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/svg"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/svg"
"github.com/markbates/goth"
"github.com/markbates/goth/providers/openidConnect"
@@ -51,6 +51,10 @@ func (o *OpenIDProvider) CustomURLSettings() *CustomURLSettings {
return nil
}
+func (o *OpenIDProvider) CanProvideSSHKeys() bool {
+ return true
+}
+
var _ GothProvider = &OpenIDProvider{}
func init() {
diff --git a/services/auth/source/oauth2/providers_simple.go b/services/auth/source/oauth2/providers_simple.go
index e95323a62a..8e2c0a7700 100644
--- a/services/auth/source/oauth2/providers_simple.go
+++ b/services/auth/source/oauth2/providers_simple.go
@@ -4,7 +4,7 @@
package oauth2
import (
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/markbates/goth"
"github.com/markbates/goth/providers/azuread"
diff --git a/services/auth/source/oauth2/source.go b/services/auth/source/oauth2/source.go
index 675005e55a..5245f88270 100644
--- a/services/auth/source/oauth2/source.go
+++ b/services/auth/source/oauth2/source.go
@@ -4,8 +4,10 @@
package oauth2
import (
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/json"
+ "strings"
+
+ "forgejo.org/models/auth"
+ "forgejo.org/modules/json"
)
// Source holds configuration for the OAuth2 login source.
@@ -17,15 +19,16 @@ type Source struct {
CustomURLMapping *CustomURLMapping
IconURL string
- Scopes []string
- RequiredClaimName string
- RequiredClaimValue string
- GroupClaimName string
- AdminGroup string
- GroupTeamMap string
- GroupTeamMapRemoval bool
- RestrictedGroup string
- SkipLocalTwoFA bool `json:",omitempty"`
+ Scopes []string
+ AttributeSSHPublicKey string
+ RequiredClaimName string
+ RequiredClaimValue string
+ GroupClaimName string
+ AdminGroup string
+ GroupTeamMap string
+ GroupTeamMapRemoval bool
+ RestrictedGroup string
+ SkipLocalTwoFA bool `json:",omitempty"`
// reference to the authSource
authSource *auth.Source
@@ -41,6 +44,11 @@ func (source *Source) ToDB() ([]byte, error) {
return json.Marshal(source)
}
+// ProvidesSSHKeys returns if this source provides SSH Keys
+func (source *Source) ProvidesSSHKeys() bool {
+ return len(strings.TrimSpace(source.AttributeSSHPublicKey)) > 0
+}
+
// SetAuthSource sets the related AuthSource
func (source *Source) SetAuthSource(authSource *auth.Source) {
source.authSource = authSource
diff --git a/services/auth/source/oauth2/source_authenticate.go b/services/auth/source/oauth2/source_authenticate.go
index bbda35dee0..1efd7be02a 100644
--- a/services/auth/source/oauth2/source_authenticate.go
+++ b/services/auth/source/oauth2/source_authenticate.go
@@ -6,8 +6,8 @@ package oauth2
import (
"context"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/services/auth/source/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/services/auth/source/db"
)
// Authenticate falls back to the db authenticator
diff --git a/services/auth/source/oauth2/store.go b/services/auth/source/oauth2/store.go
index 90fa965602..d52581ea2d 100644
--- a/services/auth/source/oauth2/store.go
+++ b/services/auth/source/oauth2/store.go
@@ -8,10 +8,10 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/modules/log"
- session_module "code.gitea.io/gitea/modules/session"
+ "forgejo.org/modules/log"
+ session_module "forgejo.org/modules/session"
- chiSession "gitea.com/go-chi/session"
+ chiSession "code.forgejo.org/go-chi/session"
"github.com/gorilla/sessions"
)
diff --git a/services/auth/source/oauth2/token.go b/services/auth/source/oauth2/token.go
index 3405619d3f..fba1fd8a01 100644
--- a/services/auth/source/oauth2/token.go
+++ b/services/auth/source/oauth2/token.go
@@ -7,7 +7,7 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/modules/timeutil"
"github.com/golang-jwt/jwt/v5"
)
diff --git a/services/auth/source/pam/assert_interface_test.go b/services/auth/source/pam/assert_interface_test.go
index 8e7648b8d3..8c54b7e9e2 100644
--- a/services/auth/source/pam/assert_interface_test.go
+++ b/services/auth/source/pam/assert_interface_test.go
@@ -4,9 +4,9 @@
package pam_test
import (
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/pam"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/pam"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/pam/source.go b/services/auth/source/pam/source.go
index 96b182e185..e1dc83ba43 100644
--- a/services/auth/source/pam/source.go
+++ b/services/auth/source/pam/source.go
@@ -4,8 +4,8 @@
package pam
import (
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/models/auth"
+ "forgejo.org/modules/json"
)
// __________ _____ _____
diff --git a/services/auth/source/pam/source_authenticate.go b/services/auth/source/pam/source_authenticate.go
index addd1bd2c9..6f3ffc2d9d 100644
--- a/services/auth/source/pam/source_authenticate.go
+++ b/services/auth/source/pam/source_authenticate.go
@@ -8,11 +8,12 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/auth/pam"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/auth/pam"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/validation"
"github.com/google/uuid"
)
@@ -39,13 +40,13 @@ func (source *Source) Authenticate(ctx context.Context, user *user_model.User, u
if idx > -1 {
username = pamLogin[:idx]
}
- if user_model.ValidateEmail(email) != nil {
+ if validation.ValidateEmail(email) != nil {
if source.EmailDomain != "" {
email = fmt.Sprintf("%s@%s", username, source.EmailDomain)
} else {
email = fmt.Sprintf("%s@%s", username, setting.Service.NoReplyAddress)
}
- if user_model.ValidateEmail(email) != nil {
+ if validation.ValidateEmail(email) != nil {
email = uuid.New().String() + "@localhost"
}
}
diff --git a/services/auth/source/remote/source.go b/services/auth/source/remote/source.go
index 4165858a56..effbabc7d0 100644
--- a/services/auth/source/remote/source.go
+++ b/services/auth/source/remote/source.go
@@ -4,8 +4,8 @@
package remote
import (
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/models/auth"
+ "forgejo.org/modules/json"
)
type Source struct {
diff --git a/services/auth/source/smtp/assert_interface_test.go b/services/auth/source/smtp/assert_interface_test.go
index 6c9cde66e1..6826dae873 100644
--- a/services/auth/source/smtp/assert_interface_test.go
+++ b/services/auth/source/smtp/assert_interface_test.go
@@ -4,9 +4,9 @@
package smtp_test
import (
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/auth/source/smtp"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/auth/source/smtp"
)
// This test file exists to assert that our Source exposes the interfaces that we expect
diff --git a/services/auth/source/smtp/source.go b/services/auth/source/smtp/source.go
index 2a648e421e..d44971bab0 100644
--- a/services/auth/source/smtp/source.go
+++ b/services/auth/source/smtp/source.go
@@ -4,8 +4,8 @@
package smtp
import (
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/json"
+ "forgejo.org/models/auth"
+ "forgejo.org/modules/json"
)
// _________ __________________________
diff --git a/services/auth/source/smtp/source_authenticate.go b/services/auth/source/smtp/source_authenticate.go
index 1f0a61c789..3d7ccd0669 100644
--- a/services/auth/source/smtp/source_authenticate.go
+++ b/services/auth/source/smtp/source_authenticate.go
@@ -10,10 +10,10 @@ import (
"net/textproto"
"strings"
- auth_model "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/util"
+ auth_model "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/util"
)
// Authenticate queries if the provided login/password is authenticates against the SMTP server
diff --git a/services/auth/source/source_group_sync.go b/services/auth/source/source_group_sync.go
index 3a2411ec55..46be6937fb 100644
--- a/services/auth/source/source_group_sync.go
+++ b/services/auth/source/source_group_sync.go
@@ -7,11 +7,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models"
+ "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
)
type syncType int
diff --git a/services/auth/source/sspi/assert_interface_test.go b/services/auth/source/sspi/assert_interface_test.go
deleted file mode 100644
index 03d836dd6f..0000000000
--- a/services/auth/source/sspi/assert_interface_test.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2021 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package sspi_test
-
-import (
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/services/auth/source/sspi"
-)
-
-// This test file exists to assert that our Source exposes the interfaces that we expect
-// It tightly binds the interfaces and implementation without breaking go import cycles
-
-type sourceInterface interface {
- auth.Config
-}
-
-var _ (sourceInterface) = &sspi.Source{}
diff --git a/services/auth/source/sspi/source.go b/services/auth/source/sspi/source.go
deleted file mode 100644
index bdd6ef451c..0000000000
--- a/services/auth/source/sspi/source.go
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2021 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package sspi
-
-import (
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/json"
-)
-
-// _________ ___________________.___
-// / _____// _____/\______ \ |
-// \_____ \ \_____ \ | ___/ |
-// / \/ \ | | | |
-// /_______ /_______ / |____| |___|
-// \/ \/
-
-// Source holds configuration for SSPI single sign-on.
-type Source struct {
- AutoCreateUsers bool
- AutoActivateUsers bool
- StripDomainNames bool
- SeparatorReplacement string
- DefaultLanguage string
-}
-
-// FromDB fills up an SSPIConfig from serialized format.
-func (cfg *Source) FromDB(bs []byte) error {
- return json.UnmarshalHandleDoubleEncode(bs, &cfg)
-}
-
-// ToDB exports an SSPIConfig to a serialized format.
-func (cfg *Source) ToDB() ([]byte, error) {
- return json.Marshal(cfg)
-}
-
-func init() {
- auth.RegisterTypeConfig(auth.SSPI, &Source{})
-}
diff --git a/services/auth/sspi.go b/services/auth/sspi.go
deleted file mode 100644
index 64a127e97a..0000000000
--- a/services/auth/sspi.go
+++ /dev/null
@@ -1,223 +0,0 @@
-// Copyright 2019 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package auth
-
-import (
- "context"
- "errors"
- "net/http"
- "strings"
- "sync"
-
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/auth/source/sspi"
- gitea_context "code.gitea.io/gitea/services/context"
-
- gouuid "github.com/google/uuid"
-)
-
-const (
- tplSignIn base.TplName = "user/auth/signin"
-)
-
-type SSPIAuth interface {
- AppendAuthenticateHeader(w http.ResponseWriter, data string)
- Authenticate(r *http.Request, w http.ResponseWriter) (userInfo *SSPIUserInfo, outToken string, err error)
-}
-
-var (
- sspiAuth SSPIAuth // a global instance of the websspi authenticator to avoid acquiring the server credential handle on every request
- sspiAuthOnce sync.Once
- sspiAuthErrInit error
-
- // Ensure the struct implements the interface.
- _ Method = &SSPI{}
-)
-
-// SSPI implements the SingleSignOn interface and authenticates requests
-// via the built-in SSPI module in Windows for SPNEGO authentication.
-// The SSPI plugin is expected to be executed last, as it returns 401 status code if negotiation
-// fails (or if negotiation should continue), which would prevent other authentication methods
-// to execute at all.
-type SSPI struct{}
-
-// Name represents the name of auth method
-func (s *SSPI) Name() string {
- return "sspi"
-}
-
-// Verify uses SSPI (Windows implementation of SPNEGO) to authenticate the request.
-// If authentication is successful, returns the corresponding user object.
-// If negotiation should continue or authentication fails, immediately returns a 401 HTTP
-// response code, as required by the SPNEGO protocol.
-func (s *SSPI) Verify(req *http.Request, w http.ResponseWriter, store DataStore, sess SessionStore) (*user_model.User, error) {
- sspiAuthOnce.Do(func() { sspiAuthErrInit = sspiAuthInit() })
- if sspiAuthErrInit != nil {
- return nil, sspiAuthErrInit
- }
- if !s.shouldAuthenticate(req) {
- return nil, nil
- }
-
- cfg, err := s.getConfig(req.Context())
- if err != nil {
- log.Error("could not get SSPI config: %v", err)
- return nil, err
- }
-
- log.Trace("SSPI Authorization: Attempting to authenticate")
- userInfo, outToken, err := sspiAuth.Authenticate(req, w)
- if err != nil {
- log.Warn("Authentication failed with error: %v\n", err)
- sspiAuth.AppendAuthenticateHeader(w, outToken)
-
- // Include the user login page in the 401 response to allow the user
- // to login with another authentication method if SSPI authentication
- // fails
- store.GetData()["Flash"] = map[string]string{
- "ErrorMsg": err.Error(),
- }
- store.GetData()["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn
- store.GetData()["EnableSSPI"] = true
- // in this case, the Verify function is called in Gitea's web context
- // FIXME: it doesn't look good to render the page here, why not redirect?
- gitea_context.GetWebContext(req).HTML(http.StatusUnauthorized, tplSignIn)
- return nil, err
- }
- if outToken != "" {
- sspiAuth.AppendAuthenticateHeader(w, outToken)
- }
-
- username := sanitizeUsername(userInfo.Username, cfg)
- if len(username) == 0 {
- return nil, nil
- }
- log.Info("Authenticated as %s\n", username)
-
- user, err := user_model.GetUserByName(req.Context(), username)
- if err != nil {
- if !user_model.IsErrUserNotExist(err) {
- log.Error("GetUserByName: %v", err)
- return nil, err
- }
- if !cfg.AutoCreateUsers {
- log.Error("User '%s' not found", username)
- return nil, nil
- }
- user, err = s.newUser(req.Context(), username, cfg)
- if err != nil {
- log.Error("CreateUser: %v", err)
- return nil, err
- }
- }
-
- // Make sure requests to API paths and PWA resources do not create a new session
- if !middleware.IsAPIPath(req) && !isAttachmentDownload(req) {
- handleSignIn(w, req, sess, user)
- }
-
- log.Trace("SSPI Authorization: Logged in user %-v", user)
- return user, nil
-}
-
-// getConfig retrieves the SSPI configuration from login sources
-func (s *SSPI) getConfig(ctx context.Context) (*sspi.Source, error) {
- sources, err := db.Find[auth.Source](ctx, auth.FindSourcesOptions{
- IsActive: optional.Some(true),
- LoginType: auth.SSPI,
- })
- if err != nil {
- return nil, err
- }
- if len(sources) == 0 {
- return nil, errors.New("no active login sources of type SSPI found")
- }
- if len(sources) > 1 {
- return nil, errors.New("more than one active login source of type SSPI found")
- }
- return sources[0].Cfg.(*sspi.Source), nil
-}
-
-func (s *SSPI) shouldAuthenticate(req *http.Request) (shouldAuth bool) {
- shouldAuth = false
- path := strings.TrimSuffix(req.URL.Path, "/")
- if path == "/user/login" {
- if req.FormValue("user_name") != "" && req.FormValue("password") != "" {
- shouldAuth = false
- } else if req.FormValue("auth_with_sspi") == "1" {
- shouldAuth = true
- }
- } else if middleware.IsAPIPath(req) || isAttachmentDownload(req) {
- shouldAuth = true
- }
- return shouldAuth
-}
-
-// newUser creates a new user object for the purpose of automatic registration
-// and populates its name and email with the information present in request headers.
-func (s *SSPI) newUser(ctx context.Context, username string, cfg *sspi.Source) (*user_model.User, error) {
- email := gouuid.New().String() + "@localhost.localdomain"
- user := &user_model.User{
- Name: username,
- Email: email,
- Language: cfg.DefaultLanguage,
- }
- emailNotificationPreference := user_model.EmailNotificationsDisabled
- overwriteDefault := &user_model.CreateUserOverwriteOptions{
- IsActive: optional.Some(cfg.AutoActivateUsers),
- KeepEmailPrivate: optional.Some(true),
- EmailNotificationsPreference: &emailNotificationPreference,
- }
- if err := user_model.CreateUser(ctx, user, overwriteDefault); err != nil {
- return nil, err
- }
-
- return user, nil
-}
-
-// stripDomainNames removes NETBIOS domain name and separator from down-level logon names
-// (eg. "DOMAIN\user" becomes "user"), and removes the UPN suffix (domain name) and separator
-// from UPNs (eg. "user@domain.local" becomes "user")
-func stripDomainNames(username string) string {
- if strings.Contains(username, "\\") {
- parts := strings.SplitN(username, "\\", 2)
- if len(parts) > 1 {
- username = parts[1]
- }
- } else if strings.Contains(username, "@") {
- parts := strings.Split(username, "@")
- if len(parts) > 1 {
- username = parts[0]
- }
- }
- return username
-}
-
-func replaceSeparators(username string, cfg *sspi.Source) string {
- newSep := cfg.SeparatorReplacement
- username = strings.ReplaceAll(username, "\\", newSep)
- username = strings.ReplaceAll(username, "/", newSep)
- username = strings.ReplaceAll(username, "@", newSep)
- return username
-}
-
-func sanitizeUsername(username string, cfg *sspi.Source) string {
- if len(username) == 0 {
- return ""
- }
- if cfg.StripDomainNames {
- username = stripDomainNames(username)
- }
- // Replace separators even if we have already stripped the domain name part,
- // as the username can contain several separators: eg. "MICROSOFT\useremail@live.com"
- username = replaceSeparators(username, cfg)
- return username
-}
diff --git a/services/auth/sspiauth_posix.go b/services/auth/sspiauth_posix.go
deleted file mode 100644
index 49b0ed4a52..0000000000
--- a/services/auth/sspiauth_posix.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2023 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build !windows
-
-package auth
-
-import (
- "errors"
- "net/http"
-)
-
-type SSPIUserInfo struct {
- Username string // Name of user, usually in the form DOMAIN\User
- Groups []string // The global groups the user is a member of
-}
-
-type sspiAuthMock struct{}
-
-func (s sspiAuthMock) AppendAuthenticateHeader(w http.ResponseWriter, data string) {
-}
-
-func (s sspiAuthMock) Authenticate(r *http.Request, w http.ResponseWriter) (userInfo *SSPIUserInfo, outToken string, err error) {
- return nil, "", errors.New("not implemented")
-}
-
-func sspiAuthInit() error {
- sspiAuth = &sspiAuthMock{} // TODO: we can mock the SSPI auth in tests
- return nil
-}
diff --git a/services/auth/sspiauth_windows.go b/services/auth/sspiauth_windows.go
deleted file mode 100644
index 093caaed33..0000000000
--- a/services/auth/sspiauth_windows.go
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2023 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-//go:build windows
-
-package auth
-
-import (
- "github.com/quasoft/websspi"
-)
-
-type SSPIUserInfo = websspi.UserInfo
-
-func sspiAuthInit() error {
- var err error
- config := websspi.NewConfig()
- sspiAuth, err = websspi.New(config)
- return err
-}
diff --git a/services/auth/sync.go b/services/auth/sync.go
index 7562ac812b..c594be7a24 100644
--- a/services/auth/sync.go
+++ b/services/auth/sync.go
@@ -6,9 +6,9 @@ package auth
import (
"context"
- "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
)
// SyncExternalUsers is used to synchronize users with external authorization source
diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go
index 10f3c28d56..51a14edd9a 100644
--- a/services/automerge/automerge.go
+++ b/services/automerge/automerge.go
@@ -7,37 +7,34 @@ import (
"context"
"errors"
"fmt"
- "strconv"
- "strings"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- pull_model "code.gitea.io/gitea/models/pull"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/queue"
- notify_service "code.gitea.io/gitea/services/notify"
- pull_service "code.gitea.io/gitea/services/pull"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ pull_model "forgejo.org/models/pull"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/queue"
+ notify_service "forgejo.org/services/notify"
+ pull_service "forgejo.org/services/pull"
+ repo_service "forgejo.org/services/repository"
+ shared_automerge "forgejo.org/services/shared/automerge"
)
-// prAutoMergeQueue represents a queue to handle update pull request tests
-var prAutoMergeQueue *queue.WorkerPoolQueue[string]
-
// Init runs the task queue to that handles auto merges
func Init() error {
notify_service.RegisterNotifier(NewNotifier())
- prAutoMergeQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "pr_auto_merge", handler)
- if prAutoMergeQueue == nil {
+ shared_automerge.PRAutoMergeQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "pr_auto_merge", handler)
+ if shared_automerge.PRAutoMergeQueue == nil {
return fmt.Errorf("unable to create pr_auto_merge queue")
}
- go graceful.GetManager().RunWithCancel(prAutoMergeQueue)
+ go graceful.GetManager().RunWithCancel(shared_automerge.PRAutoMergeQueue)
return nil
}
@@ -55,17 +52,10 @@ func handler(items ...string) []string {
return nil
}
-func addToQueue(pr *issues_model.PullRequest, sha string) {
- log.Trace("Adding pullID: %d to the pull requests patch checking queue with sha %s", pr.ID, sha)
- if err := prAutoMergeQueue.Push(fmt.Sprintf("%d_%s", pr.ID, sha)); err != nil {
- log.Error("Error adding pullID: %d to the pull requests patch checking queue %v", pr.ID, err)
- }
-}
-
// ScheduleAutoMerge if schedule is false and no error, pull can be merged directly
-func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest, style repo_model.MergeStyle, message string) (scheduled bool, err error) {
+func ScheduleAutoMerge(ctx context.Context, doer *user_model.User, pull *issues_model.PullRequest, style repo_model.MergeStyle, message string, deleteBranch bool) (scheduled bool, err error) {
err = db.WithTx(ctx, func(ctx context.Context) error {
- if err := pull_model.ScheduleAutoMerge(ctx, doer, pull.ID, style, message); err != nil {
+ if err := pull_model.ScheduleAutoMerge(ctx, doer, pull.ID, style, message, deleteBranch); err != nil {
return err
}
scheduled = true
@@ -90,94 +80,12 @@ func RemoveScheduledAutoMerge(ctx context.Context, doer *user_model.User, pull *
// StartPRCheckAndAutoMergeBySHA start an automerge check and auto merge task for all pull requests of repository and SHA
func StartPRCheckAndAutoMergeBySHA(ctx context.Context, sha string, repo *repo_model.Repository) error {
- pulls, err := getPullRequestsByHeadSHA(ctx, sha, repo, func(pr *issues_model.PullRequest) bool {
- return !pr.HasMerged && pr.CanAutoMerge()
- })
- if err != nil {
- return err
- }
-
- for _, pr := range pulls {
- addToQueue(pr, sha)
- }
-
- return nil
+ return shared_automerge.StartPRCheckAndAutoMergeBySHA(ctx, sha, repo)
}
// StartPRCheckAndAutoMerge start an automerge check and auto merge task for a pull request
func StartPRCheckAndAutoMerge(ctx context.Context, pull *issues_model.PullRequest) {
- if pull == nil || pull.HasMerged || !pull.CanAutoMerge() {
- return
- }
-
- if err := pull.LoadBaseRepo(ctx); err != nil {
- log.Error("LoadBaseRepo: %v", err)
- return
- }
-
- gitRepo, err := gitrepo.OpenRepository(ctx, pull.BaseRepo)
- if err != nil {
- log.Error("OpenRepository: %v", err)
- return
- }
- defer gitRepo.Close()
- commitID, err := gitRepo.GetRefCommitID(pull.GetGitRefName())
- if err != nil {
- log.Error("GetRefCommitID: %v", err)
- return
- }
-
- addToQueue(pull, commitID)
-}
-
-func getPullRequestsByHeadSHA(ctx context.Context, sha string, repo *repo_model.Repository, filter func(*issues_model.PullRequest) bool) (map[int64]*issues_model.PullRequest, error) {
- gitRepo, err := gitrepo.OpenRepository(ctx, repo)
- if err != nil {
- return nil, err
- }
- defer gitRepo.Close()
-
- refs, err := gitRepo.GetRefsBySha(sha, "")
- if err != nil {
- return nil, err
- }
-
- pulls := make(map[int64]*issues_model.PullRequest)
-
- for _, ref := range refs {
- // Each pull branch starts with refs/pull/ we then go from there to find the index of the pr and then
- // use that to get the pr.
- if strings.HasPrefix(ref, git.PullPrefix) {
- parts := strings.Split(ref[len(git.PullPrefix):], "/")
-
- // e.g. 'refs/pull/1/head' would be []string{"1", "head"}
- if len(parts) != 2 {
- log.Error("getPullRequestsByHeadSHA found broken pull ref [%s] on repo [%-v]", ref, repo)
- continue
- }
-
- prIndex, err := strconv.ParseInt(parts[0], 10, 64)
- if err != nil {
- log.Error("getPullRequestsByHeadSHA found broken pull ref [%s] on repo [%-v]", ref, repo)
- continue
- }
-
- p, err := issues_model.GetPullRequestByIndex(ctx, repo.ID, prIndex)
- if err != nil {
- // If there is no pull request for this branch, we don't try to merge it.
- if issues_model.IsErrPullRequestNotExist(err) {
- continue
- }
- return nil, err
- }
-
- if filter(p) {
- pulls[p.ID] = p
- }
- }
- }
-
- return pulls, nil
+ shared_automerge.StartPRCheckAndAutoMerge(ctx, pull)
}
// handlePullRequestAutoMerge merge the pull request if all checks are successful
@@ -245,9 +153,21 @@ func handlePullRequestAutoMerge(pullID int64, sha string) {
defer headGitRepo.Close()
}
- headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch)
- if pr.HeadRepo == nil || !headBranchExist {
- log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch)
+ switch pr.Flow {
+ case issues_model.PullRequestFlowGithub:
+ headBranchExist := headGitRepo.IsBranchExist(pr.HeadBranch)
+ if pr.HeadRepo == nil || !headBranchExist {
+ log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch: %s]", pr, pr.HeadRepoID, pr.HeadBranch)
+ return
+ }
+ case issues_model.PullRequestFlowAGit:
+ headBranchExist := git.IsReferenceExist(ctx, baseGitRepo.Path, pr.GetGitRefName())
+ if !headBranchExist {
+ log.Warn("Head branch of auto merge %-v does not exist [HeadRepoID: %d, Branch(Agit): %s]", pr, pr.HeadRepoID, pr.HeadBranch)
+ return
+ }
+ default:
+ log.Error("wrong flow type %d", pr.Flow)
return
}
@@ -276,7 +196,7 @@ func handlePullRequestAutoMerge(pullID int64, sha string) {
}
if err := pull_service.CheckPullMergeable(ctx, doer, &perm, pr, pull_service.MergeCheckTypeGeneral, false); err != nil {
- if errors.Is(pull_service.ErrUserNotAllowedToMerge, err) {
+ if errors.Is(err, pull_service.ErrUserNotAllowedToMerge) {
log.Info("%-v was scheduled to automerge by an unauthorized user", pr)
return
}
@@ -291,4 +211,11 @@ func handlePullRequestAutoMerge(pullID int64, sha string) {
// on the pull request page. But this should not be finished in a bug fix PR which will be backport to release branch.
return
}
+
+ if scheduledPRM.DeleteBranchAfterMerge {
+ err := repo_service.DeleteBranchAfterMerge(ctx, doer, pr, headGitRepo)
+ if err != nil {
+ log.Error("%d repo_service.DeleteBranchIfUnused: %v", pr.ID, err)
+ }
+ }
}
diff --git a/services/automerge/notify.go b/services/automerge/notify.go
index cb078214f6..3b5eae9d48 100644
--- a/services/automerge/notify.go
+++ b/services/automerge/notify.go
@@ -6,10 +6,10 @@ package automerge
import (
"context"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- notify_service "code.gitea.io/gitea/services/notify"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ notify_service "forgejo.org/services/notify"
)
type automergeNotifier struct {
diff --git a/services/context/access_log.go b/services/context/access_log.go
index 0926748ac5..7a54b746f6 100644
--- a/services/context/access_log.go
+++ b/services/context/access_log.go
@@ -12,10 +12,10 @@ import (
"text/template"
"time"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web/middleware"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web/middleware"
)
type routerLoggerOptions struct {
diff --git a/services/context/api.go b/services/context/api.go
index fafd49fd42..37f0e0f559 100644
--- a/services/context/api.go
+++ b/services/context/api.go
@@ -11,19 +11,20 @@ import (
"net/url"
"strings"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- mc "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/web"
- web_types "code.gitea.io/gitea/modules/web/types"
+ issues_model "forgejo.org/models/issues"
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ mc "forgejo.org/modules/cache"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/web"
+ web_types "forgejo.org/modules/web/types"
- "gitea.com/go-chi/cache"
+ "code.forgejo.org/go-chi/cache"
)
// APIContext is a specific context for API service
@@ -38,10 +39,13 @@ type APIContext struct {
ContextUser *user_model.User // the user which is being visited, in most cases it differs from Doer
- Repo *Repository
- Comment *issues_model.Comment
- Org *APIOrganization
- Package *Package
+ Repo *Repository
+ Comment *issues_model.Comment
+ Org *APIOrganization
+ Package *Package
+ QuotaGroup *quota_model.Group
+ QuotaRule *quota_model.Rule
+ PublicOnly bool // Whether the request is for a public endpoint
}
func init() {
@@ -55,40 +59,80 @@ func init() {
// if we need to indicate some errors, we should introduce some new fields like ErrorCode or ErrorType
// * url: the swagger document URL
+type APIError struct {
+ Message string `json:"message"`
+ URL string `json:"url"`
+}
+
// APIError is error format response
// swagger:response error
-type APIError struct {
+type swaggerAPIError struct {
+ // in:body
+ Body APIError `json:"body"`
+}
+
+type APIValidationError struct {
Message string `json:"message"`
URL string `json:"url"`
}
// APIValidationError is error format response related to input validation
// swagger:response validationError
-type APIValidationError struct {
- Message string `json:"message"`
- URL string `json:"url"`
+type swaggerAPIValidationError struct {
+ // in:body
+ Body APIValidationError `json:"body"`
+}
+
+type APIInvalidTopicsError struct {
+ Message string `json:"message"`
+ InvalidTopics []string `json:"invalidTopics"`
}
// APIInvalidTopicsError is error format response to invalid topics
// swagger:response invalidTopicsError
-type APIInvalidTopicsError struct {
- Message string `json:"message"`
- InvalidTopics []string `json:"invalidTopics"`
+type swaggerAPIInvalidTopicsError struct {
+ // in:body
+ Body APIInvalidTopicsError `json:"body"`
}
// APIEmpty is an empty response
// swagger:response empty
type APIEmpty struct{}
-// APIForbiddenError is a forbidden error response
-// swagger:response forbidden
+type APIUnauthorizedError struct {
+ APIError
+}
+
+// APIUnauthorizedError is a unauthorized error response
+// swagger:response unauthorized
+type swaggerAPUnauthorizedError struct {
+ // in:body
+ Body APIUnauthorizedError `json:"body"`
+}
+
type APIForbiddenError struct {
APIError
}
-// APINotFound is a not found empty response
+// APIForbiddenError is a forbidden error response
+// swagger:response forbidden
+type swaggerAPIForbiddenError struct {
+ // in:body
+ Body APIForbiddenError `json:"body"`
+}
+
+type APINotFound struct {
+ Message string `json:"message"`
+ URL string `json:"url"`
+ Errors []string `json:"errors"`
+}
+
+// APINotFound is a not found error response
// swagger:response notFound
-type APINotFound struct{}
+type swaggerAPINotFound struct {
+ // in:body
+ Body APINotFound `json:"body"`
+}
// APIConflict is a conflict empty response
// swagger:response conflict
@@ -102,12 +146,28 @@ type APIRedirect struct{}
// swagger:response string
type APIString string
-// APIRepoArchivedError is an error that is raised when an archived repo should be modified
-// swagger:response repoArchivedError
type APIRepoArchivedError struct {
APIError
}
+// APIRepoArchivedError is an error that is raised when an archived repo should be modified
+// swagger:response repoArchivedError
+type swaggerAPIRepoArchivedError struct {
+ // in:body
+ Body APIRepoArchivedError `json:"body"`
+}
+
+type APIInternalServerError struct {
+ APIError
+}
+
+// APIInternalServerError is an error that is raised when an internal server error occurs
+// swagger:response internalServerError
+type swaggerAPIInternalServerError struct {
+ // in:body
+ Body APIInternalServerError `json:"body"`
+}
+
// ServerError responds with error message, status is 500
func (ctx *APIContext) ServerError(title string, err error) {
ctx.Error(http.StatusInternalServerError, title, err)
@@ -248,7 +308,7 @@ func APIContexter() func(http.Handler) http.Handler {
// String will replace message, errors will be added to a slice
func (ctx *APIContext) NotFound(objs ...any) {
message := ctx.Locale.TrString("error.not_found")
- var errors []string
+ errors := make([]string, 0)
for _, obj := range objs {
// Ignore nil
if obj == nil {
@@ -262,10 +322,10 @@ func (ctx *APIContext) NotFound(objs ...any) {
}
}
- ctx.JSON(http.StatusNotFound, map[string]any{
- "message": message,
- "url": setting.API.SwaggerURL,
- "errors": errors,
+ ctx.JSON(http.StatusNotFound, APINotFound{
+ Message: message,
+ URL: setting.API.SwaggerURL,
+ Errors: errors,
})
}
@@ -304,6 +364,11 @@ func RepoRefForAPI(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ctx := GetAPIContext(req)
+ if ctx.Repo.Repository.IsEmpty {
+ ctx.NotFound(fmt.Errorf("repository is empty"))
+ return
+ }
+
if ctx.Repo.GitRepo == nil {
ctx.InternalServerError(fmt.Errorf("no open git repo"))
return
diff --git a/services/context/api_org.go b/services/context/api_org.go
index dad02b1719..acc9594e48 100644
--- a/services/context/api_org.go
+++ b/services/context/api_org.go
@@ -3,7 +3,7 @@
package context
-import "code.gitea.io/gitea/models/organization"
+import "forgejo.org/models/organization"
// APIOrganization contains organization and team
type APIOrganization struct {
diff --git a/services/context/api_test.go b/services/context/api_test.go
index 911a49949e..90e4d5ec65 100644
--- a/services/context/api_test.go
+++ b/services/context/api_test.go
@@ -8,9 +8,10 @@ import (
"strconv"
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGenAPILinks(t *testing.T) {
@@ -38,7 +39,7 @@ func TestGenAPILinks(t *testing.T) {
for req, response := range kases {
u, err := url.Parse(setting.AppURL + req)
- assert.NoError(t, err)
+ require.NoError(t, err)
p := u.Query().Get("page")
curPage, _ := strconv.Atoi(p)
diff --git a/services/context/base.go b/services/context/base.go
index 0259e0d806..0275ea8a99 100644
--- a/services/context/base.go
+++ b/services/context/base.go
@@ -14,12 +14,12 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/httplib"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/web/middleware"
+ "forgejo.org/modules/httplib"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/web/middleware"
"github.com/go-chi/chi/v5"
)
diff --git a/services/context/base_test.go b/services/context/base_test.go
index 823f20e00b..868ac00f8b 100644
--- a/services/context/base_test.go
+++ b/services/context/base_test.go
@@ -8,7 +8,7 @@ import (
"net/http/httptest"
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
)
diff --git a/services/context/captcha.go b/services/context/captcha.go
index fa8d779f56..8ae8bdcae3 100644
--- a/services/context/captcha.go
+++ b/services/context/captcha.go
@@ -7,32 +7,55 @@ import (
"fmt"
"sync"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/hcaptcha"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/mcaptcha"
- "code.gitea.io/gitea/modules/recaptcha"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/turnstile"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/hcaptcha"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/mcaptcha"
+ "forgejo.org/modules/recaptcha"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/turnstile"
- "gitea.com/go-chi/captcha"
+ mc "code.forgejo.org/go-chi/cache"
+ "code.forgejo.org/go-chi/captcha"
)
var (
imageCaptchaOnce sync.Once
- cpt *captcha.Captcha
+ imageCachePrefix = "captcha:"
)
-// GetImageCaptcha returns global image captcha
-func GetImageCaptcha() *captcha.Captcha {
+type imageCaptchaStore struct {
+ c mc.Cache
+}
+
+func (c *imageCaptchaStore) Set(id string, digits []byte) {
+ if err := c.c.Put(imageCachePrefix+id, string(digits), int64(captcha.Expiration.Seconds())); err != nil {
+ log.Error("Couldn't store captcha cache for %q: %v", id, err)
+ }
+}
+
+func (c *imageCaptchaStore) Get(id string, clear bool) (digits []byte) {
+ val, ok := c.c.Get(imageCachePrefix + id).(string)
+ if !ok {
+ return digits
+ }
+
+ if clear {
+ if err := c.c.Delete(imageCachePrefix + id); err != nil {
+ log.Error("Couldn't delete captcha cache for %q: %v", id, err)
+ }
+ }
+
+ return []byte(val)
+}
+
+// GetImageCaptcha returns image captcha ID.
+func GetImageCaptcha() string {
imageCaptchaOnce.Do(func() {
- cpt = captcha.NewCaptcha(captcha.Options{
- SubURL: setting.AppSubURL,
- })
- cpt.Store = cache.GetCache()
+ captcha.SetCustomStore(&imageCaptchaStore{c: cache.GetCache()})
})
- return cpt
+ return captcha.New()
}
// SetCaptchaData sets common captcha data
@@ -52,6 +75,8 @@ func SetCaptchaData(ctx *Context) {
}
const (
+ imgCaptchaIDField = "img-captcha-id"
+ imgCaptchaResponseField = "img-captcha-response"
gRecaptchaResponseField = "g-recaptcha-response"
hCaptchaResponseField = "h-captcha-response"
mCaptchaResponseField = "m-captcha-response"
@@ -69,7 +94,7 @@ func VerifyCaptcha(ctx *Context, tpl base.TplName, form any) {
var err error
switch setting.Service.CaptchaType {
case setting.ImageCaptcha:
- valid = GetImageCaptcha().VerifyReq(ctx.Req)
+ valid = captcha.VerifyString(ctx.Req.Form.Get(imgCaptchaIDField), ctx.Req.Form.Get(imgCaptchaResponseField))
case setting.ReCaptcha:
valid, err = recaptcha.Verify(ctx, ctx.Req.Form.Get(gRecaptchaResponseField))
case setting.HCaptcha:
diff --git a/services/context/context.go b/services/context/context.go
index 3e113e76ba..91484c5ba3 100644
--- a/services/context/context.go
+++ b/services/context/context.go
@@ -15,20 +15,20 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- mc "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/httpcache"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/web"
- "code.gitea.io/gitea/modules/web/middleware"
- web_types "code.gitea.io/gitea/modules/web/types"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ mc "forgejo.org/modules/cache"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/httpcache"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/web"
+ "forgejo.org/modules/web/middleware"
+ web_types "forgejo.org/modules/web/types"
- "gitea.com/go-chi/cache"
- "gitea.com/go-chi/session"
+ "code.forgejo.org/go-chi/cache"
+ "code.forgejo.org/go-chi/session"
)
// Render represents a template render
@@ -127,10 +127,8 @@ func Contexter() func(next http.Handler) http.Handler {
csrfOpts := CsrfOptions{
Secret: hex.EncodeToString(setting.GetGeneralTokenSigningSecret()),
Cookie: setting.CSRFCookieName,
- SetCookie: true,
Secure: setting.SessionConfig.Secure,
CookieHTTPOnly: setting.CSRFCookieHTTPOnly,
- Header: "X-Csrf-Token",
CookieDomain: setting.SessionConfig.Domain,
CookiePath: setting.SessionConfig.CookiePath,
SameSite: setting.SessionConfig.SameSite,
@@ -156,7 +154,7 @@ func Contexter() func(next http.Handler) http.Handler {
ctx.Base.AppendContextValue(WebContextKey, ctx)
ctx.Base.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })
- ctx.Csrf = PrepareCSRFProtector(csrfOpts, ctx)
+ ctx.Csrf = NewCSRFProtector(csrfOpts)
// Get the last flash message from cookie
lastFlashCookie := middleware.GetSiteCookie(ctx.Req, CookieNameFlash)
@@ -193,8 +191,6 @@ func Contexter() func(next http.Handler) http.Handler {
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
ctx.Data["SystemConfig"] = setting.Config()
- ctx.Data["CsrfToken"] = ctx.Csrf.GetToken()
- ctx.Data["CsrfTokenHtml"] = template.HTML(` `)
// FIXME: do we really always need these setting? There should be someway to have to avoid having to always set these
ctx.Data["DisableMigrations"] = setting.Repository.DisableMigrations
diff --git a/services/context/context_cookie.go b/services/context/context_cookie.go
index 39e3218d1b..08ef84b5eb 100644
--- a/services/context/context_cookie.go
+++ b/services/context/context_cookie.go
@@ -7,11 +7,11 @@ import (
"net/http"
"strings"
- auth_model "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/web/middleware"
+ auth_model "forgejo.org/models/auth"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/web/middleware"
)
const CookieNameFlash = "gitea_flash"
@@ -47,7 +47,7 @@ func (ctx *Context) GetSiteCookie(name string) string {
// SetLTACookie will generate a LTA token and add it as an cookie.
func (ctx *Context) SetLTACookie(u *user_model.User) error {
days := 86400 * setting.LogInRememberDays
- lookup, validator, err := auth_model.GenerateAuthToken(ctx, u.ID, timeutil.TimeStampNow().Add(int64(days)))
+ lookup, validator, err := auth_model.GenerateAuthToken(ctx, u.ID, timeutil.TimeStampNow().Add(int64(days)), auth_model.LongTermAuthorization)
if err != nil {
return err
}
diff --git a/services/context/context_model.go b/services/context/context_model.go
index 4f70aac516..1a8751ee63 100644
--- a/services/context/context_model.go
+++ b/services/context/context_model.go
@@ -4,7 +4,7 @@
package context
import (
- "code.gitea.io/gitea/models/unit"
+ "forgejo.org/models/unit"
)
// IsUserSiteAdmin returns true if current user is a site admin
diff --git a/services/context/context_response.go b/services/context/context_response.go
index f36b834a44..e20e7dd852 100644
--- a/services/context/context_response.go
+++ b/services/context/context_response.go
@@ -16,13 +16,13 @@ import (
"syscall"
"time"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/httplib"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/web/middleware"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/httplib"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/web/middleware"
)
// RedirectToUser redirect to a differently-named user
diff --git a/services/context/context_test.go b/services/context/context_test.go
index 033ce2ef0a..c2a271d2b7 100644
--- a/services/context/context_test.go
+++ b/services/context/context_test.go
@@ -8,7 +8,7 @@ import (
"net/http/httptest"
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
)
diff --git a/services/context/csrf.go b/services/context/csrf.go
index 57c55e6550..82dd9283ff 100644
--- a/services/context/csrf.go
+++ b/services/context/csrf.go
@@ -20,64 +20,43 @@
package context
import (
- "encoding/base32"
- "fmt"
+ "html/template"
"net/http"
"strconv"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/modules/web/middleware"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
+)
+
+const (
+ CsrfHeaderName = "X-Csrf-Token"
+ CsrfFormName = "_csrf"
+ CsrfErrorString = "Invalid CSRF token."
)
// CSRFProtector represents a CSRF protector and is used to get the current token and validate the token.
type CSRFProtector interface {
- // GetHeaderName returns HTTP header to search for token.
- GetHeaderName() string
- // GetFormName returns form value to search for token.
- GetFormName() string
- // GetToken returns the token.
- GetToken() string
- // Validate validates the token in http context.
+ // PrepareForSessionUser prepares the csrf protector for the current session user.
+ PrepareForSessionUser(ctx *Context)
+ // Validate validates the csrf token in http context.
Validate(ctx *Context)
- // DeleteCookie deletes the cookie
+ // DeleteCookie deletes the csrf cookie
DeleteCookie(ctx *Context)
}
type csrfProtector struct {
opt CsrfOptions
- // Token generated to pass via header, cookie, or hidden form value.
- Token string
- // This value must be unique per user.
- ID string
-}
-
-// GetHeaderName returns the name of the HTTP header for csrf token.
-func (c *csrfProtector) GetHeaderName() string {
- return c.opt.Header
-}
-
-// GetFormName returns the name of the form value for csrf token.
-func (c *csrfProtector) GetFormName() string {
- return c.opt.Form
-}
-
-// GetToken returns the current token. This is typically used
-// to populate a hidden form in an HTML template.
-func (c *csrfProtector) GetToken() string {
- return c.Token
+ // id must be unique per user.
+ id string
+ // token is the valid one which will be used by end user and passed via header, cookie, or hidden form value.
+ token string
}
// CsrfOptions maintains options to manage behavior of Generate.
type CsrfOptions struct {
// The global secret value used to generate Tokens.
Secret string
- // HTTP header used to set and get token.
- Header string
- // Form value used to set and get token.
- Form string
// Cookie value used to set and get token.
Cookie string
// Cookie domain.
@@ -87,103 +66,64 @@ type CsrfOptions struct {
CookieHTTPOnly bool
// SameSite set the cookie SameSite type
SameSite http.SameSite
- // Key used for getting the unique ID per user.
- SessionKey string
- // oldSessionKey saves old value corresponding to SessionKey.
- oldSessionKey string
- // If true, send token via X-Csrf-Token header.
- SetHeader bool
- // If true, send token via _csrf cookie.
- SetCookie bool
// Set the Secure flag to true on the cookie.
Secure bool
- // Disallow Origin appear in request header.
- Origin bool
- // Cookie lifetime. Default is 0
- CookieLifeTime int
+ // sessionKey is the key used for getting the unique ID per user.
+ sessionKey string
+ // oldSessionKey saves old value corresponding to sessionKey.
+ oldSessionKey string
}
-func prepareDefaultCsrfOptions(opt CsrfOptions) CsrfOptions {
- if opt.Secret == "" {
- randBytes, err := util.CryptoRandomBytes(8)
- if err != nil {
- // this panic can be handled by the recover() in http handlers
- panic(fmt.Errorf("failed to generate random bytes: %w", err))
- }
- opt.Secret = base32.StdEncoding.EncodeToString(randBytes)
- }
- if opt.Header == "" {
- opt.Header = "X-Csrf-Token"
- }
- if opt.Form == "" {
- opt.Form = "_csrf"
- }
- if opt.Cookie == "" {
- opt.Cookie = "_csrf"
- }
- if opt.CookiePath == "" {
- opt.CookiePath = "/"
- }
- if opt.SessionKey == "" {
- opt.SessionKey = "uid"
- }
- if opt.CookieLifeTime == 0 {
- opt.CookieLifeTime = int(CsrfTokenTimeout.Seconds())
- }
-
- opt.oldSessionKey = "_old_" + opt.SessionKey
- return opt
-}
-
-func newCsrfCookie(c *csrfProtector, value string) *http.Cookie {
+func newCsrfCookie(opt *CsrfOptions, value string) *http.Cookie {
return &http.Cookie{
- Name: c.opt.Cookie,
+ Name: opt.Cookie,
Value: value,
- Path: c.opt.CookiePath,
- Domain: c.opt.CookieDomain,
- MaxAge: c.opt.CookieLifeTime,
- Secure: c.opt.Secure,
- HttpOnly: c.opt.CookieHTTPOnly,
- SameSite: c.opt.SameSite,
+ Path: opt.CookiePath,
+ Domain: opt.CookieDomain,
+ MaxAge: int(CsrfTokenTimeout.Seconds()),
+ Secure: opt.Secure,
+ HttpOnly: opt.CookieHTTPOnly,
+ SameSite: opt.SameSite,
}
}
-// PrepareCSRFProtector returns a CSRFProtector to be used for every request.
-// Additionally, depending on options set, generated tokens will be sent via Header and/or Cookie.
-func PrepareCSRFProtector(opt CsrfOptions, ctx *Context) CSRFProtector {
- opt = prepareDefaultCsrfOptions(opt)
- x := &csrfProtector{opt: opt}
-
- if opt.Origin && len(ctx.Req.Header.Get("Origin")) > 0 {
- return x
+func NewCSRFProtector(opt CsrfOptions) CSRFProtector {
+ if opt.Secret == "" {
+ panic("CSRF secret is empty but it must be set") // it shouldn't happen because it is always set in code
}
+ opt.Cookie = util.IfZero(opt.Cookie, "_csrf")
+ opt.CookiePath = util.IfZero(opt.CookiePath, "/")
+ opt.sessionKey = "uid"
+ opt.oldSessionKey = "_old_" + opt.sessionKey
+ return &csrfProtector{opt: opt}
+}
- x.ID = "0"
- uidAny := ctx.Session.Get(opt.SessionKey)
- if uidAny != nil {
+func (c *csrfProtector) PrepareForSessionUser(ctx *Context) {
+ c.id = "0"
+ if uidAny := ctx.Session.Get(c.opt.sessionKey); uidAny != nil {
switch uidVal := uidAny.(type) {
case string:
- x.ID = uidVal
+ c.id = uidVal
case int64:
- x.ID = strconv.FormatInt(uidVal, 10)
+ c.id = strconv.FormatInt(uidVal, 10)
default:
log.Error("invalid uid type in session: %T", uidAny)
}
}
- oldUID := ctx.Session.Get(opt.oldSessionKey)
- uidChanged := oldUID == nil || oldUID.(string) != x.ID
- cookieToken := ctx.GetSiteCookie(opt.Cookie)
+ oldUID := ctx.Session.Get(c.opt.oldSessionKey)
+ uidChanged := oldUID == nil || oldUID.(string) != c.id
+ cookieToken := ctx.GetSiteCookie(c.opt.Cookie)
needsNew := true
if uidChanged {
- _ = ctx.Session.Set(opt.oldSessionKey, x.ID)
+ _ = ctx.Session.Set(c.opt.oldSessionKey, c.id)
} else if cookieToken != "" {
// If cookie token presents, reuse existing unexpired token, else generate a new one.
if issueTime, ok := ParseCsrfToken(cookieToken); ok {
dur := time.Since(issueTime) // issueTime is not a monotonic-clock, the server time may change a lot to an early time.
if dur >= -CsrfTokenRegenerationInterval && dur <= CsrfTokenRegenerationInterval {
- x.Token = cookieToken
+ c.token = cookieToken
needsNew = false
}
}
@@ -191,42 +131,33 @@ func PrepareCSRFProtector(opt CsrfOptions, ctx *Context) CSRFProtector {
if needsNew {
// FIXME: actionId.
- x.Token = GenerateCsrfToken(x.opt.Secret, x.ID, "POST", time.Now())
- if opt.SetCookie {
- cookie := newCsrfCookie(x, x.Token)
- ctx.Resp.Header().Add("Set-Cookie", cookie.String())
- }
+ c.token = GenerateCsrfToken(c.opt.Secret, c.id, "POST", time.Now())
+ cookie := newCsrfCookie(&c.opt, c.token)
+ ctx.Resp.Header().Add("Set-Cookie", cookie.String())
}
- if opt.SetHeader {
- ctx.Resp.Header().Add(opt.Header, x.Token)
- }
- return x
+ ctx.Data["CsrfToken"] = c.token
+ ctx.Data["CsrfTokenHtml"] = template.HTML(` `)
}
func (c *csrfProtector) validateToken(ctx *Context, token string) {
- if !ValidCsrfToken(token, c.opt.Secret, c.ID, "POST", time.Now()) {
+ if !ValidCsrfToken(token, c.opt.Secret, c.id, "POST", time.Now()) {
c.DeleteCookie(ctx)
- if middleware.IsAPIPath(ctx.Req) {
- // currently, there should be no access to the APIPath with CSRF token. because templates shouldn't use the `/api/` endpoints.
- http.Error(ctx.Resp, "Invalid CSRF token.", http.StatusBadRequest)
- } else {
- ctx.Flash.Error(ctx.Tr("error.invalid_csrf"))
- ctx.Redirect(setting.AppSubURL + "/")
- }
+ // currently, there should be no access to the APIPath with CSRF token. because templates shouldn't use the `/api/` endpoints.
+ // FIXME: distinguish what the response is for: HTML (web page) or JSON (fetch)
+ http.Error(ctx.Resp, CsrfErrorString, http.StatusBadRequest)
}
}
// Validate should be used as a per route middleware. It attempts to get a token from an "X-Csrf-Token"
// HTTP header and then a "_csrf" form value. If one of these is found, the token will be validated.
-// If this validation fails, custom Error is sent in the reply.
-// If neither a header nor form value is found, http.StatusBadRequest is sent.
+// If this validation fails, http.StatusBadRequest is sent.
func (c *csrfProtector) Validate(ctx *Context) {
- if token := ctx.Req.Header.Get(c.GetHeaderName()); token != "" {
+ if token := ctx.Req.Header.Get(CsrfHeaderName); token != "" {
c.validateToken(ctx, token)
return
}
- if token := ctx.Req.FormValue(c.GetFormName()); token != "" {
+ if token := ctx.Req.FormValue(CsrfFormName); token != "" {
c.validateToken(ctx, token)
return
}
@@ -234,9 +165,7 @@ func (c *csrfProtector) Validate(ctx *Context) {
}
func (c *csrfProtector) DeleteCookie(ctx *Context) {
- if c.opt.SetCookie {
- cookie := newCsrfCookie(c, "")
- cookie.MaxAge = -1
- ctx.Resp.Header().Add("Set-Cookie", cookie.String())
- }
+ cookie := newCsrfCookie(&c.opt, "")
+ cookie.MaxAge = -1
+ ctx.Resp.Header().Add("Set-Cookie", cookie.String())
}
diff --git a/services/context/org.go b/services/context/org.go
index 018b76de43..31ad60704f 100644
--- a/services/context/org.go
+++ b/services/context/org.go
@@ -7,14 +7,14 @@ package context
import (
"strings"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
)
// Organization contains organization context
@@ -26,7 +26,6 @@ type Organization struct {
Organization *organization.Organization
OrgLink string
CanCreateOrgRepo bool
- PublicMemberOnly bool // Only display public members
Team *organization.Team
Teams []*organization.Team
@@ -176,10 +175,10 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
ctx.Data["OrgLink"] = ctx.Org.OrgLink
// Member
- ctx.Org.PublicMemberOnly = ctx.Doer == nil || !ctx.Org.IsMember && !ctx.Doer.IsAdmin
opts := &organization.FindOrgMembersOpts{
- OrgID: org.ID,
- PublicOnly: ctx.Org.PublicMemberOnly,
+ Doer: ctx.Doer,
+ OrgID: org.ID,
+ IsDoerMember: ctx.Org.IsMember,
}
ctx.Data["NumMembers"], err = organization.CountOrgMembers(ctx, opts)
if err != nil {
diff --git a/services/context/package.go b/services/context/package.go
index c452c657e7..e597249e2a 100644
--- a/services/context/package.go
+++ b/services/context/package.go
@@ -7,14 +7,14 @@ import (
"fmt"
"net/http"
- "code.gitea.io/gitea/models/organization"
- packages_model "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/templates"
+ "forgejo.org/models/organization"
+ packages_model "forgejo.org/models/packages"
+ "forgejo.org/models/perm"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/templates"
)
// Package contains owner, access mode and optional the package descriptor
diff --git a/services/context/pagination.go b/services/context/pagination.go
index 655a278f9f..b826e59dea 100644
--- a/services/context/pagination.go
+++ b/services/context/pagination.go
@@ -9,7 +9,7 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/modules/paginator"
+ "forgejo.org/modules/paginator"
)
// Pagination provides a pagination via paginator.Paginator and additional configurations for the link params used in rendering
diff --git a/services/context/permission.go b/services/context/permission.go
index 14a9801dcc..b6af87f912 100644
--- a/services/context/permission.go
+++ b/services/context/permission.go
@@ -6,10 +6,10 @@ package context
import (
"net/http"
- auth_model "code.gitea.io/gitea/models/auth"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/log"
+ auth_model "forgejo.org/models/auth"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/log"
)
// RequireRepoAdmin returns a middleware for requiring repository admin permission
diff --git a/services/context/private.go b/services/context/private.go
index 8b41949f60..3d7ed694f1 100644
--- a/services/context/private.go
+++ b/services/context/private.go
@@ -9,10 +9,10 @@ import (
"net/http"
"time"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/web"
- web_types "code.gitea.io/gitea/modules/web/types"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/web"
+ web_types "forgejo.org/modules/web/types"
)
// PrivateContext represents a context for private routes
diff --git a/services/context/quota.go b/services/context/quota.go
new file mode 100644
index 0000000000..f6e79e1ebe
--- /dev/null
+++ b/services/context/quota.go
@@ -0,0 +1,200 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package context
+
+import (
+ "context"
+ "net/http"
+ "strings"
+
+ quota_model "forgejo.org/models/quota"
+ "forgejo.org/modules/base"
+)
+
+type QuotaTargetType int
+
+const (
+ QuotaTargetUser QuotaTargetType = iota
+ QuotaTargetRepo
+ QuotaTargetOrg
+)
+
+// QuotaExceeded
+// swagger:response quotaExceeded
+type APIQuotaExceeded struct {
+ Message string `json:"message"`
+ UserID int64 `json:"user_id"`
+ UserName string `json:"username,omitempty"`
+}
+
+// QuotaGroupAssignmentAPI returns a middleware to handle context-quota-group assignment for api routes
+func QuotaGroupAssignmentAPI() func(ctx *APIContext) {
+ return func(ctx *APIContext) {
+ groupName := ctx.Params("quotagroup")
+ group, err := quota_model.GetGroupByName(ctx, groupName)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.GetGroupByName", err)
+ return
+ }
+ if group == nil {
+ ctx.NotFound()
+ return
+ }
+ ctx.QuotaGroup = group
+ }
+}
+
+// QuotaRuleAssignmentAPI returns a middleware to handle context-quota-rule assignment for api routes
+func QuotaRuleAssignmentAPI() func(ctx *APIContext) {
+ return func(ctx *APIContext) {
+ ruleName := ctx.Params("quotarule")
+ rule, err := quota_model.GetRuleByName(ctx, ruleName)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "quota_model.GetRuleByName", err)
+ return
+ }
+ if rule == nil {
+ ctx.NotFound()
+ return
+ }
+ ctx.QuotaRule = rule
+ }
+}
+
+// ctx.CheckQuota checks whether the user in question is within quota limits (web context)
+func (ctx *Context) CheckQuota(subject quota_model.LimitSubject, userID int64, username string) bool {
+ ok, err := checkQuota(ctx.Base.originCtx, subject, userID, username, func(userID int64, username string) {
+ showHTML := false
+ for _, part := range ctx.Req.Header["Accept"] {
+ if strings.Contains(part, "text/html") {
+ showHTML = true
+ break
+ }
+ }
+ if !showHTML {
+ ctx.plainTextInternal(3, http.StatusRequestEntityTooLarge, []byte("Quota exceeded.\n"))
+ return
+ }
+
+ ctx.Data["IsRepo"] = ctx.Repo.Repository != nil
+ ctx.Data["Title"] = "Quota Exceeded"
+ ctx.HTML(http.StatusRequestEntityTooLarge, base.TplName("status/413"))
+ }, func(err error) {
+ ctx.Error(http.StatusInternalServerError, "quota_model.EvaluateForUser")
+ })
+ if err != nil {
+ return false
+ }
+ return ok
+}
+
+// ctx.CheckQuota checks whether the user in question is within quota limits (API context)
+func (ctx *APIContext) CheckQuota(subject quota_model.LimitSubject, userID int64, username string) bool {
+ ok, err := checkQuota(ctx.Base.originCtx, subject, userID, username, func(userID int64, username string) {
+ ctx.JSON(http.StatusRequestEntityTooLarge, APIQuotaExceeded{
+ Message: "quota exceeded",
+ UserID: userID,
+ UserName: username,
+ })
+ }, func(err error) {
+ ctx.InternalServerError(err)
+ })
+ if err != nil {
+ return false
+ }
+ return ok
+}
+
+// EnforceQuotaWeb returns a middleware that enforces quota limits on the given web route.
+func EnforceQuotaWeb(subject quota_model.LimitSubject, target QuotaTargetType) func(ctx *Context) {
+ return func(ctx *Context) {
+ ctx.CheckQuota(subject, target.UserID(ctx), target.UserName(ctx))
+ }
+}
+
+// EnforceQuotaWeb returns a middleware that enforces quota limits on the given API route.
+func EnforceQuotaAPI(subject quota_model.LimitSubject, target QuotaTargetType) func(ctx *APIContext) {
+ return func(ctx *APIContext) {
+ ctx.CheckQuota(subject, target.UserID(ctx), target.UserName(ctx))
+ }
+}
+
+// checkQuota wraps quota checking into a single function
+func checkQuota(ctx context.Context, subject quota_model.LimitSubject, userID int64, username string, quotaExceededHandler func(userID int64, username string), errorHandler func(err error)) (bool, error) {
+ ok, err := quota_model.EvaluateForUser(ctx, userID, subject)
+ if err != nil {
+ errorHandler(err)
+ return false, err
+ }
+ if !ok {
+ quotaExceededHandler(userID, username)
+ return false, nil
+ }
+ return true, nil
+}
+
+type QuotaContext interface {
+ GetQuotaTargetUserID(target QuotaTargetType) int64
+ GetQuotaTargetUserName(target QuotaTargetType) string
+}
+
+func (ctx *Context) GetQuotaTargetUserID(target QuotaTargetType) int64 {
+ switch target {
+ case QuotaTargetUser:
+ return ctx.Doer.ID
+ case QuotaTargetRepo:
+ return ctx.Repo.Repository.OwnerID
+ case QuotaTargetOrg:
+ return ctx.Org.Organization.ID
+ default:
+ return 0
+ }
+}
+
+func (ctx *Context) GetQuotaTargetUserName(target QuotaTargetType) string {
+ switch target {
+ case QuotaTargetUser:
+ return ctx.Doer.Name
+ case QuotaTargetRepo:
+ return ctx.Repo.Repository.Owner.Name
+ case QuotaTargetOrg:
+ return ctx.Org.Organization.Name
+ default:
+ return ""
+ }
+}
+
+func (ctx *APIContext) GetQuotaTargetUserID(target QuotaTargetType) int64 {
+ switch target {
+ case QuotaTargetUser:
+ return ctx.Doer.ID
+ case QuotaTargetRepo:
+ return ctx.Repo.Repository.OwnerID
+ case QuotaTargetOrg:
+ return ctx.Org.Organization.ID
+ default:
+ return 0
+ }
+}
+
+func (ctx *APIContext) GetQuotaTargetUserName(target QuotaTargetType) string {
+ switch target {
+ case QuotaTargetUser:
+ return ctx.Doer.Name
+ case QuotaTargetRepo:
+ return ctx.Repo.Repository.Owner.Name
+ case QuotaTargetOrg:
+ return ctx.Org.Organization.Name
+ default:
+ return ""
+ }
+}
+
+func (target QuotaTargetType) UserID(ctx QuotaContext) int64 {
+ return ctx.GetQuotaTargetUserID(target)
+}
+
+func (target QuotaTargetType) UserName(ctx QuotaContext) string {
+ return ctx.GetQuotaTargetUserName(target)
+}
diff --git a/services/context/repo.go b/services/context/repo.go
index e4cacbc53c..a1e1cadf6c 100644
--- a/services/context/repo.go
+++ b/services/context/repo.go
@@ -1,6 +1,6 @@
-// Copyright 2024 The Forgejo Authors. All rights reserved.
// Copyright 2014 The Gogs Authors. All rights reserved.
// Copyright 2017 The Gitea Authors. All rights reserved.
+// Copyright 2024 The Forgejo Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package context
@@ -15,24 +15,26 @@ import (
"path"
"strings"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- unit_model "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- code_indexer "code.gitea.io/gitea/modules/indexer/code"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/optional"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- asymkey_service "code.gitea.io/gitea/services/asymkey"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ packages_model "forgejo.org/models/packages"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/card"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ code_indexer "forgejo.org/modules/indexer/code"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ asymkey_service "forgejo.org/services/asymkey"
"github.com/editorconfig/editorconfig-core-go/v2"
)
@@ -412,14 +414,7 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) {
}
}
- pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{})
- if err != nil {
- ctx.ServerError("GetPushMirrorsByRepoID", err)
- return
- }
-
ctx.Repo.Repository = repo
- ctx.Data["PushMirrors"] = pushMirrors
ctx.Data["RepoName"] = ctx.Repo.Repository.Name
ctx.Data["IsEmptyRepo"] = ctx.Repo.Repository.IsEmpty
ctx.Data["DefaultWikiBranchName"] = setting.Repository.DefaultBranch
@@ -579,6 +574,11 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
ctx.ServerError("GetReleaseCountByRepoID", err)
return nil
}
+ ctx.Data["NumPackages"], err = packages_model.CountRepositoryPackages(ctx, ctx.Repo.Repository.ID)
+ if err != nil {
+ ctx.ServerError("GetPackageCountByRepoID", err)
+ return nil
+ }
ctx.Data["Title"] = owner.Name + "/" + repo.Name
ctx.Data["Repository"] = repo
@@ -633,6 +633,16 @@ func RepoAssignment(ctx *Context) context.CancelFunc {
ctx.Data["IsStaringRepo"] = repo_model.IsStaring(ctx, ctx.Doer.ID, repo.ID)
}
+ cardWidth, cardHeight := card.DefaultSize()
+ ctx.Data["OpenGraphTitle"] = repo.Name
+ ctx.Data["OpenGraphURL"] = repo.HTMLURL()
+ ctx.Data["OpenGraphType"] = "object"
+ ctx.Data["OpenGraphDescription"] = repo.Description
+ ctx.Data["OpenGraphImageURL"] = repo.SummaryCardURL()
+ ctx.Data["OpenGraphImageWidth"] = cardWidth
+ ctx.Data["OpenGraphImageHeight"] = cardHeight
+ ctx.Data["OpenGraphImageAltText"] = ctx.Tr("repo.summary_card_alt", repo.FullName())
+
if repo.IsFork {
RetrieveBaseRepo(ctx, repo)
if ctx.Written() {
@@ -897,7 +907,7 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
case RepoRefCommit:
parts := strings.Split(path, "/")
- if len(parts) > 0 && len(parts[0]) >= 7 && len(parts[0]) <= repo.GetObjectFormat().FullLength() {
+ if len(parts) > 0 && len(parts[0]) >= 4 && len(parts[0]) <= repo.GetObjectFormat().FullLength() {
repo.TreePath = strings.Join(parts[1:], "/")
return parts[0]
}
@@ -927,6 +937,9 @@ func getRefName(ctx *Base, repo *Repository, pathType RepoRefType) string {
// of repository reference
func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context) context.CancelFunc {
return func(ctx *Context) (cancel context.CancelFunc) {
+ if ctx.Repo.Repository.IsBeingCreated() {
+ return nil // no git repo, so do nothing
+ }
// Empty repository does not have reference information.
if ctx.Repo.Repository.IsEmpty {
// assume the user is viewing the (non-existent) default branch
@@ -1021,7 +1034,7 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context
return cancel
}
ctx.Repo.CommitID = ctx.Repo.Commit.ID.String()
- } else if len(refName) >= 7 && len(refName) <= ctx.Repo.GetObjectFormat().FullLength() {
+ } else if len(refName) >= 4 && len(refName) <= ctx.Repo.GetObjectFormat().FullLength() {
ctx.Repo.IsViewCommit = true
ctx.Repo.CommitID = refName
diff --git a/services/context/repository.go b/services/context/repository.go
index 422ac3f58d..7eef2c5068 100644
--- a/services/context/repository.go
+++ b/services/context/repository.go
@@ -6,7 +6,7 @@ package context
import (
"net/http"
- repo_model "code.gitea.io/gitea/models/repo"
+ repo_model "forgejo.org/models/repo"
)
// RepositoryIDAssignmentAPI returns a middleware to handle context-repo assignment for api routes
diff --git a/services/context/response.go b/services/context/response.go
index 2f271f211b..8fc631e671 100644
--- a/services/context/response.go
+++ b/services/context/response.go
@@ -6,7 +6,7 @@ package context
import (
"net/http"
- web_types "code.gitea.io/gitea/modules/web/types"
+ web_types "forgejo.org/modules/web/types"
)
// ResponseWriter represents a response writer for HTTP
diff --git a/services/context/upload/upload.go b/services/context/upload/upload.go
index 77a7eb9377..2fa177e604 100644
--- a/services/context/upload/upload.go
+++ b/services/context/upload/upload.go
@@ -11,9 +11,9 @@ import (
"regexp"
"strings"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/context"
)
// ErrFileTypeForbidden not allowed file type error
diff --git a/services/context/user.go b/services/context/user.go
index 4c9cd2928b..a82c90d7a6 100644
--- a/services/context/user.go
+++ b/services/context/user.go
@@ -8,7 +8,7 @@ import (
"net/http"
"strings"
- user_model "code.gitea.io/gitea/models/user"
+ user_model "forgejo.org/models/user"
)
// UserAssignmentWeb returns a middleware to handle context-user assignment for web routes
diff --git a/services/contexttest/context_tests.go b/services/contexttest/context_tests.go
index 073af213a2..ebab04f620 100644
--- a/services/contexttest/context_tests.go
+++ b/services/contexttest/context_tests.go
@@ -15,19 +15,20 @@ import (
"testing"
"time"
- org_model "code.gitea.io/gitea/models/organization"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/translation"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ org_model "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/translation"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
"github.com/go-chi/chi/v5"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func mockRequest(t *testing.T, reqPath string) *http.Request {
@@ -37,7 +38,7 @@ func mockRequest(t *testing.T, reqPath string) *http.Request {
path = reqPath
}
requestURL, err := url.Parse(path)
- assert.NoError(t, err)
+ require.NoError(t, err)
req := &http.Request{Method: method, URL: requestURL, Form: maps.Clone(requestURL.Query()), Header: http.Header{}}
req = req.WithContext(middleware.WithContextData(req.Context()))
return req
@@ -117,10 +118,10 @@ func LoadRepo(t *testing.T, ctx gocontext.Context, repoID int64) {
repo.Repository = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
var err error
repo.Owner, err = user_model.GetUserByID(ctx, repo.Repository.OwnerID)
- assert.NoError(t, err)
+ require.NoError(t, err)
repo.RepoLink = repo.Repository.Link()
repo.Permission, err = access_model.GetUserRepoPermission(ctx, repo.Repository, doer)
- assert.NoError(t, err)
+ require.NoError(t, err)
}
// LoadRepoCommit loads a repo's commit into a test context.
@@ -135,15 +136,16 @@ func LoadRepoCommit(t *testing.T, ctx gocontext.Context) {
assert.FailNow(t, "context is not *context.Context or *context.APIContext")
}
- gitRepo, err := gitrepo.OpenRepository(ctx, repo.Repository)
- assert.NoError(t, err)
- defer gitRepo.Close()
- branch, err := gitRepo.GetHEADBranch()
- assert.NoError(t, err)
+ if repo.GitRepo == nil {
+ assert.FailNow(t, "must call LoadGitRepo")
+ }
+
+ branch, err := repo.GitRepo.GetHEADBranch()
+ require.NoError(t, err)
assert.NotNil(t, branch)
if branch != nil {
- repo.Commit, err = gitRepo.GetBranchCommit(branch.Name)
- assert.NoError(t, err)
+ repo.Commit, err = repo.GitRepo.GetBranchCommit(branch.Name)
+ require.NoError(t, err)
}
}
@@ -175,11 +177,21 @@ func LoadOrganization(t *testing.T, ctx gocontext.Context, orgID int64) {
// LoadGitRepo load a git repo into a test context. Requires that ctx.Repo has
// already been populated.
-func LoadGitRepo(t *testing.T, ctx *context.Context) {
- assert.NoError(t, ctx.Repo.Repository.LoadOwner(ctx))
+func LoadGitRepo(t *testing.T, ctx gocontext.Context) {
+ var repo *context.Repository
+ switch ctx := ctx.(type) {
+ case *context.Context:
+ repo = ctx.Repo
+ case *context.APIContext:
+ repo = ctx.Repo
+ default:
+ assert.FailNow(t, "context is not *context.Context or *context.APIContext")
+ }
+
+ require.NoError(t, repo.Repository.LoadOwner(ctx))
var err error
- ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
- assert.NoError(t, err)
+ repo.GitRepo, err = gitrepo.OpenRepository(ctx, repo.Repository)
+ require.NoError(t, err)
}
type MockRender struct{}
diff --git a/services/convert/activity.go b/services/convert/activity.go
index 01fef73e58..213db13772 100644
--- a/services/convert/activity.go
+++ b/services/convert/activity.go
@@ -6,12 +6,12 @@ package convert
import (
"context"
- activities_model "code.gitea.io/gitea/models/activities"
- perm_model "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
+ activities_model "forgejo.org/models/activities"
+ perm_model "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
)
func ToActivity(ctx context.Context, ac *activities_model.Action, doer *user_model.User) *api.Activity {
diff --git a/services/convert/attachment.go b/services/convert/attachment.go
index 4a8f10f7b0..6617aac906 100644
--- a/services/convert/attachment.go
+++ b/services/convert/attachment.go
@@ -4,11 +4,15 @@
package convert
import (
- repo_model "code.gitea.io/gitea/models/repo"
- api "code.gitea.io/gitea/modules/structs"
+ repo_model "forgejo.org/models/repo"
+ api "forgejo.org/modules/structs"
)
func WebAssetDownloadURL(repo *repo_model.Repository, attach *repo_model.Attachment) string {
+ if attach.ExternalURL != "" {
+ return attach.ExternalURL
+ }
+
return attach.DownloadURL()
}
@@ -28,6 +32,12 @@ func ToAPIAttachment(repo *repo_model.Repository, a *repo_model.Attachment) *api
// toAttachment converts models.Attachment to api.Attachment for API usage
func toAttachment(repo *repo_model.Repository, a *repo_model.Attachment, getDownloadURL func(repo *repo_model.Repository, attach *repo_model.Attachment) string) *api.Attachment {
+ var typeName string
+ if a.ExternalURL != "" {
+ typeName = "external"
+ } else {
+ typeName = "attachment"
+ }
return &api.Attachment{
ID: a.ID,
Name: a.Name,
@@ -36,6 +46,7 @@ func toAttachment(repo *repo_model.Repository, a *repo_model.Attachment, getDown
Size: a.Size,
UUID: a.UUID,
DownloadURL: getDownloadURL(repo, a), // for web request json and api request json, return different download urls
+ Type: typeName,
}
}
diff --git a/services/convert/convert.go b/services/convert/convert.go
index d6dc3c9858..2ea24a1b51 100644
--- a/services/convert/convert.go
+++ b/services/convert/convert.go
@@ -11,24 +11,24 @@ import (
"strings"
"time"
- actions_model "code.gitea.io/gitea/models/actions"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/auth"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/gitdiff"
+ actions_model "forgejo.org/models/actions"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/auth"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/gitdiff"
)
// ToEmail convert models.EmailAddress to api.Email
@@ -480,6 +480,7 @@ func ToLFSLock(ctx context.Context, l *git_model.LFSLock) *api.LFSLock {
// ToChangedFile convert a gitdiff.DiffFile to api.ChangedFile
func ToChangedFile(f *gitdiff.DiffFile, repo *repo_model.Repository, commit string) *api.ChangedFile {
status := "changed"
+ previousFilename := ""
if f.IsDeleted {
status = "deleted"
} else if f.IsCreated {
@@ -488,23 +489,21 @@ func ToChangedFile(f *gitdiff.DiffFile, repo *repo_model.Repository, commit stri
status = "copied"
} else if f.IsRenamed && f.Type == gitdiff.DiffFileRename {
status = "renamed"
+ previousFilename = f.OldName
} else if f.Addition == 0 && f.Deletion == 0 {
status = "unchanged"
}
file := &api.ChangedFile{
- Filename: f.GetDiffFileName(),
- Status: status,
- Additions: f.Addition,
- Deletions: f.Deletion,
- Changes: f.Addition + f.Deletion,
- HTMLURL: fmt.Sprint(repo.HTMLURL(), "/src/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
- ContentsURL: fmt.Sprint(repo.APIURL(), "/contents/", util.PathEscapeSegments(f.GetDiffFileName()), "?ref=", commit),
- RawURL: fmt.Sprint(repo.HTMLURL(), "/raw/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
- }
-
- if status == "rename" {
- file.PreviousFilename = f.OldName
+ Filename: f.GetDiffFileName(),
+ Status: status,
+ Additions: f.Addition,
+ Deletions: f.Deletion,
+ Changes: f.Addition + f.Deletion,
+ PreviousFilename: previousFilename,
+ HTMLURL: fmt.Sprint(repo.HTMLURL(), "/src/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
+ ContentsURL: fmt.Sprint(repo.APIURL(), "/contents/", util.PathEscapeSegments(f.GetDiffFileName()), "?ref=", commit),
+ RawURL: fmt.Sprint(repo.HTMLURL(), "/raw/commit/", commit, "/", util.PathEscapeSegments(f.GetDiffFileName())),
}
return file
diff --git a/services/convert/git_commit.go b/services/convert/git_commit.go
index e0efcddbcb..e041361737 100644
--- a/services/convert/git_commit.go
+++ b/services/convert/git_commit.go
@@ -8,14 +8,14 @@ import (
"net/url"
"time"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
- ctx "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/gitdiff"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
+ ctx "forgejo.org/services/context"
+ "forgejo.org/services/gitdiff"
)
// ToCommitUser convert a git.Signature to an api.CommitUser
diff --git a/services/convert/git_commit_test.go b/services/convert/git_commit_test.go
index 73cb5e8c71..463b93aac3 100644
--- a/services/convert/git_commit_test.go
+++ b/services/convert/git_commit_test.go
@@ -7,17 +7,18 @@ import (
"testing"
"time"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/git"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/git"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestToCommitMeta(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
sha1 := git.Sha1ObjectFormat
signature := &git.Signature{Name: "Test Signature", Email: "test@email.com", When: time.Unix(0, 0)}
diff --git a/services/convert/issue.go b/services/convert/issue.go
index f514dc4313..c7803794d0 100644
--- a/services/convert/issue.go
+++ b/services/convert/issue.go
@@ -9,13 +9,13 @@ import (
"net/url"
"strings"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/label"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/label"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
)
func ToIssue(ctx context.Context, doer *user_model.User, issue *issues_model.Issue) *api.Issue {
diff --git a/services/convert/issue_comment.go b/services/convert/issue_comment.go
index 9ec9ac7684..9ea315aee6 100644
--- a/services/convert/issue_comment.go
+++ b/services/convert/issue_comment.go
@@ -6,12 +6,12 @@ package convert
import (
"context"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
)
// ToAPIComment converts a issues_model.Comment to the api.Comment format for API usage
diff --git a/services/convert/issue_test.go b/services/convert/issue_test.go
index 4d780f3f00..97bacfb229 100644
--- a/services/convert/issue_test.go
+++ b/services/convert/issue_test.go
@@ -8,18 +8,19 @@ import (
"testing"
"time"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestLabel_ToLabel(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: label.RepoID})
assert.Equal(t, &api.Label{
diff --git a/services/convert/main_test.go b/services/convert/main_test.go
index 363cc4a97f..5915d16be4 100644
--- a/services/convert/main_test.go
+++ b/services/convert/main_test.go
@@ -6,9 +6,10 @@ package convert
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models/actions"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/convert/mirror.go b/services/convert/mirror.go
index 249ce2f968..9e7d2659ab 100644
--- a/services/convert/mirror.go
+++ b/services/convert/mirror.go
@@ -6,8 +6,8 @@ package convert
import (
"context"
- repo_model "code.gitea.io/gitea/models/repo"
- api "code.gitea.io/gitea/modules/structs"
+ repo_model "forgejo.org/models/repo"
+ api "forgejo.org/modules/structs"
)
// ToPushMirror convert from repo_model.PushMirror and remoteAddress to api.TopicResponse
@@ -22,5 +22,6 @@ func ToPushMirror(ctx context.Context, pm *repo_model.PushMirror) (*api.PushMirr
LastError: pm.LastError,
Interval: pm.Interval.String(),
SyncOnCommit: pm.SyncOnCommit,
+ PublicKey: pm.GetPublicKey(),
}, nil
}
diff --git a/services/convert/notification.go b/services/convert/notification.go
index 41063cf399..3a4239e0fe 100644
--- a/services/convert/notification.go
+++ b/services/convert/notification.go
@@ -7,10 +7,10 @@ import (
"context"
"net/url"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- api "code.gitea.io/gitea/modules/structs"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ api "forgejo.org/modules/structs"
)
// ToNotificationThread convert a Notification to api.NotificationThread
diff --git a/services/convert/package.go b/services/convert/package.go
index b5fca21a3c..a28e60e1b1 100644
--- a/services/convert/package.go
+++ b/services/convert/package.go
@@ -6,10 +6,10 @@ package convert
import (
"context"
- "code.gitea.io/gitea/models/packages"
- access_model "code.gitea.io/gitea/models/perm/access"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/packages"
+ access_model "forgejo.org/models/perm/access"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
)
// ToPackage convert a packages.PackageDescriptor to api.Package
diff --git a/services/convert/pull.go b/services/convert/pull.go
index c214805ed5..ca965a0d18 100644
--- a/services/convert/pull.go
+++ b/services/convert/pull.go
@@ -7,15 +7,15 @@ import (
"context"
"fmt"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/cache"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/cache"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
)
// ToAPIPullRequest assumes following fields have been assigned with valid values:
@@ -29,6 +29,11 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
err error
)
+ if err = pr.LoadIssue(ctx); err != nil {
+ log.Error("pr.LoadIssue[%d]: %v", pr.ID, err)
+ return nil
+ }
+
if err = pr.Issue.LoadRepo(ctx); err != nil {
log.Error("pr.Issue.LoadRepo[%d]: %v", pr.ID, err)
return nil
@@ -61,33 +66,36 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
}
apiPullRequest := &api.PullRequest{
- ID: pr.ID,
- URL: pr.Issue.HTMLURL(),
- Index: pr.Index,
- Poster: apiIssue.Poster,
- Title: apiIssue.Title,
- Body: apiIssue.Body,
- Labels: apiIssue.Labels,
- Milestone: apiIssue.Milestone,
- Assignee: apiIssue.Assignee,
- Assignees: apiIssue.Assignees,
- State: apiIssue.State,
- Draft: pr.IsWorkInProgress(ctx),
- IsLocked: apiIssue.IsLocked,
- Comments: apiIssue.Comments,
- ReviewComments: pr.GetReviewCommentsCount(ctx),
- HTMLURL: pr.Issue.HTMLURL(),
- DiffURL: pr.Issue.DiffURL(),
- PatchURL: pr.Issue.PatchURL(),
- HasMerged: pr.HasMerged,
- MergeBase: pr.MergeBase,
- Mergeable: pr.Mergeable(ctx),
- Deadline: apiIssue.Deadline,
- Created: pr.Issue.CreatedUnix.AsTimePtr(),
- Updated: pr.Issue.UpdatedUnix.AsTimePtr(),
- PinOrder: apiIssue.PinOrder,
+ ID: pr.ID,
+ URL: pr.Issue.HTMLURL(),
+ Index: pr.Index,
+ Poster: apiIssue.Poster,
+ Title: apiIssue.Title,
+ Body: apiIssue.Body,
+ Labels: apiIssue.Labels,
+ Milestone: apiIssue.Milestone,
+ Assignee: apiIssue.Assignee,
+ Assignees: apiIssue.Assignees,
+ State: apiIssue.State,
+ Draft: pr.IsWorkInProgress(ctx),
+ IsLocked: apiIssue.IsLocked,
+ Comments: apiIssue.Comments,
+ ReviewComments: pr.GetReviewCommentsCount(ctx),
+ HTMLURL: pr.Issue.HTMLURL(),
+ DiffURL: pr.Issue.DiffURL(),
+ PatchURL: pr.Issue.PatchURL(),
+ HasMerged: pr.HasMerged,
+ MergeBase: pr.MergeBase,
+ Mergeable: pr.Mergeable(ctx),
+ Deadline: apiIssue.Deadline,
+ Created: pr.Issue.CreatedUnix.AsTimePtr(),
+ Updated: pr.Issue.UpdatedUnix.AsTimePtr(),
+ PinOrder: apiIssue.PinOrder,
+ RequestedReviewers: []*api.User{},
+ RequestedReviewersTeams: []*api.Team{},
AllowMaintainerEdit: pr.AllowMaintainerEdit,
+ Flow: int64(pr.Flow),
Base: &api.PRBranchInfo{
Name: pr.BaseBranch,
@@ -106,10 +114,25 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u
log.Error("LoadRequestedReviewers[%d]: %v", pr.ID, err)
return nil
}
+ if err = pr.LoadRequestedReviewersTeams(ctx); err != nil {
+ log.Error("LoadRequestedReviewersTeams[%d]: %v", pr.ID, err)
+ return nil
+ }
+
for _, reviewer := range pr.RequestedReviewers {
apiPullRequest.RequestedReviewers = append(apiPullRequest.RequestedReviewers, ToUser(ctx, reviewer, nil))
}
+ for _, reviewerTeam := range pr.RequestedReviewersTeams {
+ convertedTeam, err := ToTeam(ctx, reviewerTeam, true)
+ if err != nil {
+ log.Error("LoadRequestedReviewersTeams[%d]: %v", pr.ID, err)
+ return nil
+ }
+
+ apiPullRequest.RequestedReviewersTeams = append(apiPullRequest.RequestedReviewersTeams, convertedTeam)
+ }
+
if pr.Issue.ClosedUnix != 0 {
apiPullRequest.Closed = pr.Issue.ClosedUnix.AsTimePtr()
}
diff --git a/services/convert/pull_review.go b/services/convert/pull_review.go
index f7990e7a5c..08ccc0e1fc 100644
--- a/services/convert/pull_review.go
+++ b/services/convert/pull_review.go
@@ -7,9 +7,9 @@ import (
"context"
"strings"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
)
// ToPullReview convert a review to api format
diff --git a/services/convert/pull_test.go b/services/convert/pull_test.go
index 66c7313f7d..3e4875fc60 100644
--- a/services/convert/pull_test.go
+++ b/services/convert/pull_test.go
@@ -6,26 +6,27 @@ package convert
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/structs"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestPullRequest_APIFormat(t *testing.T) {
// with HeadRepo
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
- assert.NoError(t, pr.LoadAttributes(db.DefaultContext))
- assert.NoError(t, pr.LoadIssue(db.DefaultContext))
+ require.NoError(t, pr.LoadAttributes(db.DefaultContext))
+ require.NoError(t, pr.LoadIssue(db.DefaultContext))
apiPullRequest := ToAPIPullRequest(git.DefaultContext, pr, nil)
assert.NotNil(t, apiPullRequest)
assert.EqualValues(t, &structs.PRBranchInfo{
@@ -38,8 +39,8 @@ func TestPullRequest_APIFormat(t *testing.T) {
// withOut HeadRepo
pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
- assert.NoError(t, pr.LoadIssue(db.DefaultContext))
- assert.NoError(t, pr.LoadAttributes(db.DefaultContext))
+ require.NoError(t, pr.LoadIssue(db.DefaultContext))
+ require.NoError(t, pr.LoadAttributes(db.DefaultContext))
// simulate fork deletion
pr.HeadRepo = nil
pr.HeadRepoID = 100000
@@ -50,7 +51,7 @@ func TestPullRequest_APIFormat(t *testing.T) {
}
func TestPullReviewList(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
t.Run("Pending review", func(t *testing.T) {
reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -59,18 +60,18 @@ func TestPullReviewList(t *testing.T) {
t.Run("Anonymous", func(t *testing.T) {
prList, err := ToPullReviewList(db.DefaultContext, rl, nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, prList)
})
t.Run("Reviewer", func(t *testing.T) {
prList, err := ToPullReviewList(db.DefaultContext, rl, reviewer)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, prList, 1)
})
t.Run("Admin", func(t *testing.T) {
adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{IsAdmin: true}, unittest.Cond("id != ?", reviewer.ID))
prList, err := ToPullReviewList(db.DefaultContext, rl, adminUser)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, prList, 1)
})
})
diff --git a/services/convert/quota.go b/services/convert/quota.go
new file mode 100644
index 0000000000..ba729feaac
--- /dev/null
+++ b/services/convert/quota.go
@@ -0,0 +1,185 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package convert
+
+import (
+ "context"
+ "strconv"
+
+ action_model "forgejo.org/models/actions"
+ issue_model "forgejo.org/models/issues"
+ package_model "forgejo.org/models/packages"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ api "forgejo.org/modules/structs"
+)
+
+func ToQuotaRuleInfo(rule quota_model.Rule, withName bool) api.QuotaRuleInfo {
+ info := api.QuotaRuleInfo{
+ Limit: rule.Limit,
+ Subjects: make([]string, len(rule.Subjects)),
+ }
+ for i := range len(rule.Subjects) {
+ info.Subjects[i] = rule.Subjects[i].String()
+ }
+
+ if withName {
+ info.Name = rule.Name
+ }
+
+ return info
+}
+
+func toQuotaInfoUsed(used *quota_model.Used) api.QuotaUsed {
+ info := api.QuotaUsed{
+ Size: api.QuotaUsedSize{
+ Repos: api.QuotaUsedSizeRepos{
+ Public: used.Size.Repos.Public,
+ Private: used.Size.Repos.Private,
+ },
+ Git: api.QuotaUsedSizeGit{
+ LFS: used.Size.Git.LFS,
+ },
+ Assets: api.QuotaUsedSizeAssets{
+ Attachments: api.QuotaUsedSizeAssetsAttachments{
+ Issues: used.Size.Assets.Attachments.Issues,
+ Releases: used.Size.Assets.Attachments.Releases,
+ },
+ Artifacts: used.Size.Assets.Artifacts,
+ Packages: api.QuotaUsedSizeAssetsPackages{
+ All: used.Size.Assets.Packages.All,
+ },
+ },
+ },
+ }
+ return info
+}
+
+func ToQuotaInfo(used *quota_model.Used, groups quota_model.GroupList, withNames bool) api.QuotaInfo {
+ info := api.QuotaInfo{
+ Used: toQuotaInfoUsed(used),
+ Groups: ToQuotaGroupList(groups, withNames),
+ }
+
+ return info
+}
+
+func ToQuotaGroup(group quota_model.Group, withNames bool) api.QuotaGroup {
+ info := api.QuotaGroup{
+ Rules: make([]api.QuotaRuleInfo, len(group.Rules)),
+ }
+ if withNames {
+ info.Name = group.Name
+ }
+ for i := range len(group.Rules) {
+ info.Rules[i] = ToQuotaRuleInfo(group.Rules[i], withNames)
+ }
+
+ return info
+}
+
+func ToQuotaGroupList(groups quota_model.GroupList, withNames bool) api.QuotaGroupList {
+ list := make(api.QuotaGroupList, len(groups))
+
+ for i := range len(groups) {
+ list[i] = ToQuotaGroup(*groups[i], withNames)
+ }
+
+ return list
+}
+
+func ToQuotaUsedAttachmentList(ctx context.Context, attachments []*repo_model.Attachment) (*api.QuotaUsedAttachmentList, error) {
+ getAttachmentContainer := func(a *repo_model.Attachment) (string, string, error) {
+ if a.ReleaseID != 0 {
+ release, err := repo_model.GetReleaseByID(ctx, a.ReleaseID)
+ if err != nil {
+ return "", "", err
+ }
+ if err = release.LoadAttributes(ctx); err != nil {
+ return "", "", err
+ }
+ return release.APIURL(), release.HTMLURL(), nil
+ }
+ if a.CommentID != 0 {
+ comment, err := issue_model.GetCommentByID(ctx, a.CommentID)
+ if err != nil {
+ return "", "", err
+ }
+ return comment.APIURL(ctx), comment.HTMLURL(ctx), nil
+ }
+ if a.IssueID != 0 {
+ issue, err := issue_model.GetIssueByID(ctx, a.IssueID)
+ if err != nil {
+ return "", "", err
+ }
+ if err = issue.LoadRepo(ctx); err != nil {
+ return "", "", err
+ }
+ return issue.APIURL(ctx), issue.HTMLURL(), nil
+ }
+ return "", "", nil
+ }
+
+ result := make(api.QuotaUsedAttachmentList, len(attachments))
+ for i, a := range attachments {
+ capiURL, chtmlURL, err := getAttachmentContainer(a)
+ if err != nil {
+ return nil, err
+ }
+
+ apiURL := capiURL + "/assets/" + strconv.FormatInt(a.ID, 10)
+ result[i] = &api.QuotaUsedAttachment{
+ Name: a.Name,
+ Size: a.Size,
+ APIURL: apiURL,
+ }
+ result[i].ContainedIn.APIURL = capiURL
+ result[i].ContainedIn.HTMLURL = chtmlURL
+ }
+
+ return &result, nil
+}
+
+func ToQuotaUsedPackageList(ctx context.Context, packages []*package_model.PackageVersion) (*api.QuotaUsedPackageList, error) {
+ result := make(api.QuotaUsedPackageList, len(packages))
+ for i, pv := range packages {
+ d, err := package_model.GetPackageDescriptor(ctx, pv)
+ if err != nil {
+ return nil, err
+ }
+
+ var size int64
+ for _, file := range d.Files {
+ size += file.Blob.Size
+ }
+
+ result[i] = &api.QuotaUsedPackage{
+ Name: d.Package.Name,
+ Type: d.Package.Type.Name(),
+ Version: d.Version.Version,
+ Size: size,
+ HTMLURL: d.VersionHTMLURL(),
+ }
+ }
+
+ return &result, nil
+}
+
+func ToQuotaUsedArtifactList(ctx context.Context, artifacts []*action_model.ActionArtifact) (*api.QuotaUsedArtifactList, error) {
+ result := make(api.QuotaUsedArtifactList, len(artifacts))
+ for i, a := range artifacts {
+ run, err := action_model.GetRunByID(ctx, a.RunID)
+ if err != nil {
+ return nil, err
+ }
+
+ result[i] = &api.QuotaUsedArtifact{
+ Name: a.ArtifactName,
+ Size: a.FileCompressedSize,
+ HTMLURL: run.HTMLURL(),
+ }
+ }
+
+ return &result, nil
+}
diff --git a/services/convert/release.go b/services/convert/release.go
index 8c0f61b56c..7773cf3b19 100644
--- a/services/convert/release.go
+++ b/services/convert/release.go
@@ -6,8 +6,8 @@ package convert
import (
"context"
- repo_model "code.gitea.io/gitea/models/repo"
- api "code.gitea.io/gitea/modules/structs"
+ repo_model "forgejo.org/models/repo"
+ api "forgejo.org/modules/structs"
)
// ToAPIRelease convert a repo_model.Release to api.Release
diff --git a/services/convert/release_test.go b/services/convert/release_test.go
index 201b27e16d..3abd2ff3ef 100644
--- a/services/convert/release_test.go
+++ b/services/convert/release_test.go
@@ -6,15 +6,16 @@ package convert
import (
"testing"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestRelease_ToRelease(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
release1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Release{ID: 1})
diff --git a/services/convert/repository.go b/services/convert/repository.go
index 2fb6f6d7c0..1b0f46b3da 100644
--- a/services/convert/repository.go
+++ b/services/convert/repository.go
@@ -7,14 +7,14 @@ import (
"context"
"time"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- unit_model "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
)
// ToRepo converts a Repository to api.Repository
@@ -101,6 +101,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
allowRebaseUpdate := false
defaultDeleteBranchAfterMerge := false
defaultMergeStyle := repo_model.MergeStyleMerge
+ defaultUpdateStyle := repo_model.UpdateStyleMerge
defaultAllowMaintainerEdit := false
if unit, err := repo.GetUnit(ctx, unit_model.TypePullRequests); err == nil {
config := unit.PullRequestsConfig()
@@ -114,6 +115,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
allowRebaseUpdate = config.AllowRebaseUpdate
defaultDeleteBranchAfterMerge = config.DefaultDeleteBranchAfterMerge
defaultMergeStyle = config.GetDefaultMergeStyle()
+ defaultUpdateStyle = config.GetDefaultUpdateStyle()
defaultAllowMaintainerEdit = config.DefaultAllowMaintainerEdit
}
hasProjects := false
@@ -231,6 +233,7 @@ func innerToRepo(ctx context.Context, repo *repo_model.Repository, permissionInR
AllowRebaseUpdate: allowRebaseUpdate,
DefaultDeleteBranchAfterMerge: defaultDeleteBranchAfterMerge,
DefaultMergeStyle: string(defaultMergeStyle),
+ DefaultUpdateStyle: string(defaultUpdateStyle),
DefaultAllowMaintainerEdit: defaultAllowMaintainerEdit,
AvatarURL: repo.AvatarLink(ctx),
Internal: !repo.IsPrivate && repo.Owner.Visibility == api.VisibleTypePrivate,
diff --git a/services/convert/secret.go b/services/convert/secret.go
deleted file mode 100644
index dd7b9f0a6a..0000000000
--- a/services/convert/secret.go
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2023 The Gitea Authors. All rights reserved.
-// SPDX-License-Identifier: MIT
-
-package convert
-
-import (
- secret_model "code.gitea.io/gitea/models/secret"
- api "code.gitea.io/gitea/modules/structs"
-)
-
-// ToSecret converts Secret to API format
-func ToSecret(secret *secret_model.Secret) *api.Secret {
- result := &api.Secret{
- Name: secret.Name,
- }
-
- return result
-}
diff --git a/services/convert/status.go b/services/convert/status.go
index 6cef63c1cd..1a71e70a52 100644
--- a/services/convert/status.go
+++ b/services/convert/status.go
@@ -6,9 +6,9 @@ package convert
import (
"context"
- git_model "code.gitea.io/gitea/models/git"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
+ git_model "forgejo.org/models/git"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
)
// ToCommitStatus converts git_model.CommitStatus to api.CommitStatus
diff --git a/services/convert/user.go b/services/convert/user.go
index 94a400de5d..444089fd83 100644
--- a/services/convert/user.go
+++ b/services/convert/user.go
@@ -6,9 +6,9 @@ package convert
import (
"context"
- "code.gitea.io/gitea/models/perm"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/perm"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
)
// ToUser convert user_model.User to api.User
@@ -57,7 +57,7 @@ func toUser(ctx context.Context, user *user_model.User, signed, authed bool) *ap
Created: user.CreatedUnix.AsTime(),
Restricted: user.IsRestricted,
Location: user.Location,
- Pronouns: user.Pronouns,
+ Pronouns: user.GetPronouns(signed),
Website: user.Website,
Description: user.Description,
// counter's
@@ -97,6 +97,7 @@ func User2UserSettings(user *user_model.User) api.UserSettings {
Description: user.Description,
Theme: user.Theme,
HideEmail: user.KeepEmailPrivate,
+ HidePronouns: user.KeepPronounsPrivate,
HideActivity: user.KeepActivityPrivate,
DiffViewStyle: user.DiffViewStyle,
EnableRepoUnitHints: user.EnableRepoUnitHints,
diff --git a/services/convert/user_test.go b/services/convert/user_test.go
index 4b1effc7aa..01ce8101da 100644
--- a/services/convert/user_test.go
+++ b/services/convert/user_test.go
@@ -6,16 +6,17 @@ package convert
import (
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ api "forgejo.org/modules/structs"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestUser_ToUser(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1, IsAdmin: true})
diff --git a/services/convert/utils.go b/services/convert/utils.go
index fe35fd2dac..3bbd4e39bd 100644
--- a/services/convert/utils.go
+++ b/services/convert/utils.go
@@ -7,8 +7,8 @@ package convert
import (
"strings"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
)
// ToCorrectPageSize makes sure page size is in allowed range.
diff --git a/services/convert/wiki.go b/services/convert/wiki.go
index 767bfdb88d..adcbd52949 100644
--- a/services/convert/wiki.go
+++ b/services/convert/wiki.go
@@ -6,8 +6,8 @@ package convert
import (
"time"
- "code.gitea.io/gitea/modules/git"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/git"
+ api "forgejo.org/modules/structs"
)
// ToWikiCommit convert a git commit into a WikiCommit
diff --git a/services/cron/cron.go b/services/cron/cron.go
index 3c5737e371..d020f3fd6c 100644
--- a/services/cron/cron.go
+++ b/services/cron/cron.go
@@ -9,10 +9,10 @@ import (
"runtime/pprof"
"time"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/sync"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/sync"
+ "forgejo.org/modules/translation"
"github.com/go-co-op/gocron"
)
diff --git a/services/cron/setting.go b/services/cron/setting.go
index 6dad88830a..7fd4c4e1d8 100644
--- a/services/cron/setting.go
+++ b/services/cron/setting.go
@@ -6,7 +6,7 @@ package cron
import (
"time"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/modules/translation"
)
// Config represents a basic configuration interface that cron task
diff --git a/services/cron/tasks.go b/services/cron/tasks.go
index f8a7444c49..b547acdf05 100644
--- a/services/cron/tasks.go
+++ b/services/cron/tasks.go
@@ -11,14 +11,14 @@ import (
"sync"
"time"
- "code.gitea.io/gitea/models/db"
- system_model "code.gitea.io/gitea/models/system"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/models/db"
+ system_model "forgejo.org/models/system"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
)
var (
diff --git a/services/cron/tasks_actions.go b/services/cron/tasks_actions.go
index 0875792503..a7fd3cd0bc 100644
--- a/services/cron/tasks_actions.go
+++ b/services/cron/tasks_actions.go
@@ -6,9 +6,9 @@ package cron
import (
"context"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- actions_service "code.gitea.io/gitea/services/actions"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ actions_service "forgejo.org/services/actions"
)
func initActionsTasks() {
@@ -19,6 +19,7 @@ func initActionsTasks() {
registerStopEndlessTasks()
registerCancelAbandonedJobs()
registerScheduleTasks()
+ registerActionsCleanup()
}
func registerStopZombieTasks() {
@@ -63,3 +64,13 @@ func registerScheduleTasks() {
return actions_service.StartScheduleTasks(ctx)
})
}
+
+func registerActionsCleanup() {
+ RegisterTaskFatal("cleanup_actions", &BaseConfig{
+ Enabled: true,
+ RunAtStart: false,
+ Schedule: "@midnight",
+ }, func(ctx context.Context, _ *user_model.User, _ Config) error {
+ return actions_service.Cleanup(ctx)
+ })
+}
diff --git a/services/cron/tasks_basic.go b/services/cron/tasks_basic.go
index 3869382d22..5ada7a8f5c 100644
--- a/services/cron/tasks_basic.go
+++ b/services/cron/tasks_basic.go
@@ -7,19 +7,18 @@ import (
"context"
"time"
- "code.gitea.io/gitea/models"
- git_model "code.gitea.io/gitea/models/git"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/actions"
- "code.gitea.io/gitea/services/auth"
- "code.gitea.io/gitea/services/migrations"
- mirror_service "code.gitea.io/gitea/services/mirror"
- packages_cleanup_service "code.gitea.io/gitea/services/packages/cleanup"
- repo_service "code.gitea.io/gitea/services/repository"
- archiver_service "code.gitea.io/gitea/services/repository/archiver"
+ "forgejo.org/models"
+ git_model "forgejo.org/models/git"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/models/webhook"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/auth"
+ "forgejo.org/services/migrations"
+ mirror_service "forgejo.org/services/mirror"
+ packages_cleanup_service "forgejo.org/services/packages/cleanup"
+ repo_service "forgejo.org/services/repository"
+ archiver_service "forgejo.org/services/repository/archiver"
)
func registerUpdateMirrorTask() {
@@ -55,7 +54,7 @@ func registerRepoHealthCheck() {
RunAtStart: false,
Schedule: "@midnight",
},
- Timeout: 60 * time.Second,
+ Timeout: time.Duration(setting.Git.Timeout.Default) * time.Second,
Args: []string{},
}, func(ctx context.Context, _ *user_model.User, config Config) error {
rhcConfig := config.(*RepoHealthCheckConfig)
@@ -157,20 +156,6 @@ func registerCleanupPackages() {
})
}
-func registerActionsCleanup() {
- RegisterTaskFatal("cleanup_actions", &OlderThanConfig{
- BaseConfig: BaseConfig{
- Enabled: true,
- RunAtStart: true,
- Schedule: "@midnight",
- },
- OlderThan: 24 * time.Hour,
- }, func(ctx context.Context, _ *user_model.User, config Config) error {
- realConfig := config.(*OlderThanConfig)
- return actions.Cleanup(ctx, realConfig.OlderThan)
- })
-}
-
func initBasicTasks() {
if setting.Mirror.Enabled {
registerUpdateMirrorTask()
@@ -187,7 +172,4 @@ func initBasicTasks() {
if setting.Packages.Enabled {
registerCleanupPackages()
}
- if setting.Actions.Enabled {
- registerActionsCleanup()
- }
}
diff --git a/services/cron/tasks_extended.go b/services/cron/tasks_extended.go
index e1ba5274e6..322fe27ca0 100644
--- a/services/cron/tasks_extended.go
+++ b/services/cron/tasks_extended.go
@@ -7,17 +7,17 @@ import (
"context"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/models/system"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/updatechecker"
- repo_service "code.gitea.io/gitea/services/repository"
- archiver_service "code.gitea.io/gitea/services/repository/archiver"
- user_service "code.gitea.io/gitea/services/user"
+ activities_model "forgejo.org/models/activities"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/models/system"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ issue_indexer "forgejo.org/modules/indexer/issues"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/updatechecker"
+ repo_service "forgejo.org/services/repository"
+ archiver_service "forgejo.org/services/repository/archiver"
+ user_service "forgejo.org/services/user"
)
func registerDeleteInactiveUsers() {
diff --git a/services/cron/tasks_test.go b/services/cron/tasks_test.go
index 979371a022..9b969a69a9 100644
--- a/services/cron/tasks_test.go
+++ b/services/cron/tasks_test.go
@@ -9,10 +9,11 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestAddTaskToScheduler(t *testing.T) {
- assert.Len(t, scheduler.Jobs(), 0)
+ assert.Empty(t, scheduler.Jobs())
defer scheduler.Clear()
// no seconds
@@ -22,7 +23,7 @@ func TestAddTaskToScheduler(t *testing.T) {
Schedule: "5 4 * * *",
},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
jobs := scheduler.Jobs()
assert.Len(t, jobs, 1)
assert.Equal(t, "task 1", jobs[0].Tags()[0])
@@ -35,7 +36,7 @@ func TestAddTaskToScheduler(t *testing.T) {
Schedule: "30 5 4 * * *",
},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
jobs = scheduler.Jobs() // the item order is not guaranteed, so we need to sort it before "assert"
sort.Slice(jobs, func(i, j int) bool {
return jobs[i].Tags()[0] < jobs[j].Tags()[0]
diff --git a/services/doctor/actions.go b/services/doctor/actions.go
new file mode 100644
index 0000000000..c382132265
--- /dev/null
+++ b/services/doctor/actions.go
@@ -0,0 +1,70 @@
+// Copyright 2024 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package doctor
+
+import (
+ "context"
+ "fmt"
+
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ unit_model "forgejo.org/models/unit"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/optional"
+ repo_service "forgejo.org/services/repository"
+)
+
+func disableMirrorActionsUnit(ctx context.Context, logger log.Logger, autofix bool) error {
+ var reposToFix []*repo_model.Repository
+
+ for page := 1; ; page++ {
+ repos, _, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
+ ListOptions: db.ListOptions{
+ PageSize: repo_model.RepositoryListDefaultPageSize,
+ Page: page,
+ },
+ Mirror: optional.Some(true),
+ })
+ if err != nil {
+ return fmt.Errorf("SearchRepository: %w", err)
+ }
+ if len(repos) == 0 {
+ break
+ }
+
+ for _, repo := range repos {
+ if repo.UnitEnabled(ctx, unit_model.TypeActions) {
+ reposToFix = append(reposToFix, repo)
+ }
+ }
+ }
+
+ if len(reposToFix) == 0 {
+ logger.Info("Found no mirror with actions unit enabled")
+ } else {
+ logger.Warn("Found %d mirrors with actions unit enabled", len(reposToFix))
+ }
+ if !autofix || len(reposToFix) == 0 {
+ return nil
+ }
+
+ for _, repo := range reposToFix {
+ if err := repo_service.UpdateRepositoryUnits(ctx, repo, nil, []unit_model.Type{unit_model.TypeActions}); err != nil {
+ return err
+ }
+ }
+ logger.Info("Fixed %d mirrors with actions unit enabled", len(reposToFix))
+
+ return nil
+}
+
+func init() {
+ Register(&Check{
+ Title: "Disable the actions unit for all mirrors",
+ Name: "disable-mirror-actions-unit",
+ IsDefault: false,
+ Run: disableMirrorActionsUnit,
+ Priority: 9,
+ })
+}
diff --git a/services/doctor/authorizedkeys.go b/services/doctor/authorizedkeys.go
index eb6dec613f..04a3680ff5 100644
--- a/services/doctor/authorizedkeys.go
+++ b/services/doctor/authorizedkeys.go
@@ -12,10 +12,10 @@ import (
"path/filepath"
"strings"
- asymkey_model "code.gitea.io/gitea/models/asymkey"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ asymkey_model "forgejo.org/models/asymkey"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
const tplCommentPrefix = `# gitea public key`
@@ -75,9 +75,9 @@ func checkAuthorizedKeys(ctx context.Context, logger log.Logger, autofix bool) e
logger.Critical(
"authorized_keys file %q is out of date.\nRegenerate it with:\n\t\"%s\"\nor\n\t\"%s\"",
fPath,
- "gitea admin regenerate keys",
- "gitea doctor --run authorized-keys --fix")
- return fmt.Errorf(`authorized_keys is out of date and should be regenerated with "gitea admin regenerate keys" or "gitea doctor --run authorized-keys --fix"`)
+ "forgejo admin regenerate keys",
+ "forgejo doctor check --run authorized-keys --fix")
+ return fmt.Errorf(`authorized_keys is out of date and should be regenerated with "forgejo admin regenerate keys" or "forgejo doctor check --run authorized-keys --fix"`)
}
logger.Warn("authorized_keys is out of date. Attempting rewrite...")
err = asymkey_model.RewriteAllPublicKeys(ctx)
diff --git a/services/doctor/breaking.go b/services/doctor/breaking.go
index 77e3d4e8ef..339f8e847c 100644
--- a/services/doctor/breaking.go
+++ b/services/doctor/breaking.go
@@ -7,9 +7,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/validation"
"xorm.io/builder"
)
@@ -29,9 +31,11 @@ func iterateUserAccounts(ctx context.Context, each func(*user.User) error) error
// addresses would be currently facing a error due to their invalid email address.
// Ref: https://github.com/go-gitea/gitea/pull/19085 & https://github.com/go-gitea/gitea/pull/17688
func checkUserEmail(ctx context.Context, logger log.Logger, _ bool) error {
+ setting.LoadServiceSetting()
+
// We could use quirky SQL to get all users that start without a [a-zA-Z0-9], but that would mean
// DB provider-specific SQL and only works _now_. So instead we iterate through all user accounts
- // and use the user.ValidateEmail function to be future-proof.
+ // and use the validation.ValidateEmail function to be future-proof.
var invalidUserCount int64
if err := iterateUserAccounts(ctx, func(u *user.User) error {
// Only check for users, skip
@@ -39,7 +43,7 @@ func checkUserEmail(ctx context.Context, logger log.Logger, _ bool) error {
return nil
}
- if err := user.ValidateEmail(u.Email); err != nil {
+ if err := validation.ValidateEmail(u.Email); err != nil {
invalidUserCount++
logger.Warn("User[id=%d name=%q] have not a valid e-mail: %v", u.ID, u.Name, err)
}
@@ -60,6 +64,8 @@ func checkUserEmail(ctx context.Context, logger log.Logger, _ bool) error {
// are allowed for various reasons. This check helps with detecting users that, according
// to our reserved names, don't have a valid username.
func checkUserName(ctx context.Context, logger log.Logger, _ bool) error {
+ setting.LoadServiceSetting()
+
var invalidUserCount int64
if err := iterateUserAccounts(ctx, func(u *user.User) error {
if err := user.IsUsableUsername(u.Name); err != nil {
diff --git a/services/doctor/checkOldArchives.go b/services/doctor/checkOldArchives.go
index 390dfb43aa..301e99391b 100644
--- a/services/doctor/checkOldArchives.go
+++ b/services/doctor/checkOldArchives.go
@@ -8,9 +8,9 @@ import (
"os"
"path/filepath"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/util"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/util"
)
func checkOldArchives(ctx context.Context, logger log.Logger, autofix bool) error {
diff --git a/services/doctor/dbconsistency.go b/services/doctor/dbconsistency.go
index e3992a5ba5..6fcbd90940 100644
--- a/services/doctor/dbconsistency.go
+++ b/services/doctor/dbconsistency.go
@@ -6,15 +6,16 @@ package doctor
import (
"context"
- actions_model "code.gitea.io/gitea/models/actions"
- activities_model "code.gitea.io/gitea/models/activities"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/migrations"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ actions_model "forgejo.org/models/actions"
+ activities_model "forgejo.org/models/activities"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/migrations"
+ org_model "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
type consistencyCheck struct {
@@ -177,6 +178,12 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er
Fixer: auth_model.DeleteOrphanedOAuth2Applications,
FixedMessage: "Removed",
},
+ {
+ Name: "Owner teams with no admin access",
+ Counter: org_model.CountInconsistentOwnerTeams,
+ Fixer: org_model.FixInconsistentOwnerTeams,
+ FixedMessage: "Fixed",
+ },
}
// TODO: function to recalc all counters
@@ -236,6 +243,12 @@ func checkDBConsistency(ctx context.Context, logger log.Logger, autofix bool) er
// find archive download count without existing release
genericOrphanCheck("Archive download count without existing Release",
"repo_archive_download_count", "release", "repo_archive_download_count.release_id=release.id"),
+ // find authorization tokens without existing user
+ genericOrphanCheck("Authorization token without existing User",
+ "forgejo_auth_token", "user", "forgejo_auth_token.uid=`user`.id"),
+ // find two_factor without existing user
+ genericOrphanCheck("Orphaned TwoFactor without existing User",
+ "two_factor", "user", "`two_factor`.uid=`user`.id"),
)
for _, c := range consistencyChecks {
diff --git a/services/doctor/dbversion.go b/services/doctor/dbversion.go
index 2b20cb2340..9c02c732e5 100644
--- a/services/doctor/dbversion.go
+++ b/services/doctor/dbversion.go
@@ -6,13 +6,13 @@ package doctor
import (
"context"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/migrations"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ "forgejo.org/models/migrations"
+ "forgejo.org/modules/log"
)
func checkDBVersion(ctx context.Context, logger log.Logger, autofix bool) error {
- logger.Info("Expected database version: %d", migrations.ExpectedVersion())
+ logger.Info("Expected database version: %d", migrations.ExpectedDBVersion())
if err := db.InitEngineWithMigration(ctx, migrations.EnsureUpToDate); err != nil {
if !autofix {
logger.Critical("Error: %v during ensure up to date", err)
diff --git a/services/doctor/doctor.go b/services/doctor/doctor.go
index a4eb5e16b9..6d8e168bf2 100644
--- a/services/doctor/doctor.go
+++ b/services/doctor/doctor.go
@@ -10,11 +10,11 @@ import (
"sort"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
)
// Check represents a Doctor check
diff --git a/services/doctor/fix16961.go b/services/doctor/fix16961.go
index 50d9ac6621..2212d9e903 100644
--- a/services/doctor/fix16961.go
+++ b/services/doctor/fix16961.go
@@ -9,12 +9,12 @@ import (
"errors"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/timeutil"
"xorm.io/builder"
)
diff --git a/services/doctor/fix16961_test.go b/services/doctor/fix16961_test.go
index 498ed9c8d5..7a83c808c3 100644
--- a/services/doctor/fix16961_test.go
+++ b/services/doctor/fix16961_test.go
@@ -6,7 +6,7 @@ package doctor
import (
"testing"
- repo_model "code.gitea.io/gitea/models/repo"
+ repo_model "forgejo.org/models/repo"
"github.com/stretchr/testify/assert"
)
diff --git a/services/doctor/fix8312.go b/services/doctor/fix8312.go
index 4fc049873a..31cd6686d7 100644
--- a/services/doctor/fix8312.go
+++ b/services/doctor/fix8312.go
@@ -6,11 +6,11 @@ package doctor
import (
"context"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- org_model "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ org_model "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ "forgejo.org/modules/log"
"xorm.io/builder"
)
diff --git a/services/doctor/heads.go b/services/doctor/heads.go
index 41fca01d57..7f9d1c73e8 100644
--- a/services/doctor/heads.go
+++ b/services/doctor/heads.go
@@ -6,9 +6,9 @@ package doctor
import (
"context"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
)
func synchronizeRepoHeads(ctx context.Context, logger log.Logger, autofix bool) error {
diff --git a/services/doctor/lfs.go b/services/doctor/lfs.go
index 8531b7bbe8..fed127de5d 100644
--- a/services/doctor/lfs.go
+++ b/services/doctor/lfs.go
@@ -8,9 +8,9 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/repository"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/repository"
)
func init() {
diff --git a/services/doctor/mergebase.go b/services/doctor/mergebase.go
index de460c4190..bebde30bee 100644
--- a/services/doctor/mergebase.go
+++ b/services/doctor/mergebase.go
@@ -8,11 +8,11 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
"xorm.io/builder"
)
diff --git a/services/doctor/misc.go b/services/doctor/misc.go
index 9300c3a25c..9b9c96b52b 100644
--- a/services/doctor/misc.go
+++ b/services/doctor/misc.go
@@ -11,17 +11,17 @@ import (
"path"
"strings"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
lru "github.com/hashicorp/golang-lru/v2"
"xorm.io/builder"
diff --git a/services/doctor/packages_nuget.go b/services/doctor/packages_nuget.go
index 47fdb3ac12..f6a33db779 100644
--- a/services/doctor/packages_nuget.go
+++ b/services/doctor/packages_nuget.go
@@ -9,12 +9,12 @@ import (
"slices"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- nuget_module "code.gitea.io/gitea/modules/packages/nuget"
- packages_service "code.gitea.io/gitea/services/packages"
+ "forgejo.org/models/db"
+ "forgejo.org/models/packages"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ nuget_module "forgejo.org/modules/packages/nuget"
+ packages_service "forgejo.org/services/packages"
"xorm.io/builder"
)
diff --git a/services/doctor/paths.go b/services/doctor/paths.go
index 3f62d587ab..4fbe19ea04 100644
--- a/services/doctor/paths.go
+++ b/services/doctor/paths.go
@@ -8,8 +8,8 @@ import (
"fmt"
"os"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
type configurationFile struct {
@@ -60,7 +60,7 @@ func checkConfigurationFile(logger log.Logger, autofix bool, fileOpts configurat
func checkConfigurationFiles(ctx context.Context, logger log.Logger, autofix bool) error {
if fi, err := os.Stat(setting.CustomConf); err != nil || !fi.Mode().IsRegular() {
logger.Error("Failed to find configuration file at '%s'.", setting.CustomConf)
- logger.Error("If you've never ran Gitea yet, this is normal and '%s' will be created for you on first run.", setting.CustomConf)
+ logger.Error("If you've never ran Forgejo yet, this is normal and '%s' will be created for you on first run.", setting.CustomConf)
logger.Error("Otherwise check that you are running this command from the correct path and/or provide a `--config` parameter.")
logger.Critical("Cannot proceed without a configuration file")
return err
diff --git a/services/doctor/push_mirror_consistency.go b/services/doctor/push_mirror_consistency.go
index 68b96d6415..07986770b2 100644
--- a/services/doctor/push_mirror_consistency.go
+++ b/services/doctor/push_mirror_consistency.go
@@ -7,9 +7,9 @@ import (
"context"
"strings"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/log"
"xorm.io/builder"
)
diff --git a/services/doctor/repository.go b/services/doctor/repository.go
index 6c33426636..cd51483d88 100644
--- a/services/doctor/repository.go
+++ b/services/doctor/repository.go
@@ -6,11 +6,11 @@ package doctor
import (
"context"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/storage"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/storage"
+ repo_service "forgejo.org/services/repository"
"xorm.io/builder"
)
diff --git a/services/doctor/storage.go b/services/doctor/storage.go
index 3f3b562c37..7dbe475d6c 100644
--- a/services/doctor/storage.go
+++ b/services/doctor/storage.go
@@ -9,16 +9,16 @@ import (
"io/fs"
"strings"
- "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/packages"
- "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- packages_module "code.gitea.io/gitea/modules/packages"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models/git"
+ "forgejo.org/models/packages"
+ "forgejo.org/models/repo"
+ "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ packages_module "forgejo.org/modules/packages"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/util"
)
type commonStorageCheckOptions struct {
diff --git a/services/doctor/usertype.go b/services/doctor/usertype.go
index ab32b78e62..0a034d8f9d 100644
--- a/services/doctor/usertype.go
+++ b/services/doctor/usertype.go
@@ -6,8 +6,8 @@ package doctor
import (
"context"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
)
func checkUserType(ctx context.Context, logger log.Logger, autofix bool) error {
diff --git a/services/externalaccount/link.go b/services/externalaccount/link.go
index d6e2ea7e94..f5d29b5ce5 100644
--- a/services/externalaccount/link.go
+++ b/services/externalaccount/link.go
@@ -7,7 +7,7 @@ import (
"context"
"fmt"
- user_model "code.gitea.io/gitea/models/user"
+ user_model "forgejo.org/models/user"
"github.com/markbates/goth"
)
diff --git a/services/externalaccount/user.go b/services/externalaccount/user.go
index 3cfd8c81f9..68d085f6d0 100644
--- a/services/externalaccount/user.go
+++ b/services/externalaccount/user.go
@@ -8,11 +8,11 @@ import (
"strconv"
"strings"
- "code.gitea.io/gitea/models/auth"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/auth"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/structs"
"github.com/markbates/goth"
)
diff --git a/services/f3/driver/asset.go b/services/f3/driver/asset.go
index fb0cc0f21b..c9d2ecdf2f 100644
--- a/services/f3/driver/asset.go
+++ b/services/f3/driver/asset.go
@@ -12,14 +12,15 @@ import (
"io"
"os"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/services/attachment"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/services/attachment"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -87,7 +88,7 @@ func (o *asset) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
asset, err := repo_model.GetAttachmentByID(ctx, id)
if repo_model.IsErrAttachmentNotExist(err) {
@@ -131,7 +132,7 @@ func (o *asset) Patch(ctx context.Context) {
}
}
-func (o *asset) Put(ctx context.Context) generic.NodeID {
+func (o *asset) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -154,7 +155,7 @@ func (o *asset) Put(ctx context.Context) generic.NodeID {
}
o.Trace("asset created %d", o.forgejoAsset.ID)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoAsset.ID))
+ return f3_id.NewNodeID(o.forgejoAsset.ID)
}
func (o *asset) Delete(ctx context.Context) {
diff --git a/services/f3/driver/assets.go b/services/f3/driver/assets.go
index 88a3979713..106d5029f3 100644
--- a/services/f3/driver/assets.go
+++ b/services/f3/driver/assets.go
@@ -8,7 +8,7 @@ import (
"context"
"fmt"
- repo_model "code.gitea.io/gitea/models/repo"
+ repo_model "forgejo.org/models/repo"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/comment.go b/services/f3/driver/comment.go
index 67416a04ba..bd924930b5 100644
--- a/services/f3/driver/comment.go
+++ b/services/f3/driver/comment.go
@@ -8,12 +8,13 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -72,7 +73,7 @@ func (o *comment) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
comment, err := issues_model.GetCommentByID(ctx, id)
if issues_model.IsErrCommentNotExist(err) {
@@ -95,7 +96,7 @@ func (o *comment) Patch(ctx context.Context) {
}
}
-func (o *comment) Put(ctx context.Context) generic.NodeID {
+func (o *comment) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -105,7 +106,7 @@ func (o *comment) Put(ctx context.Context) generic.NodeID {
panic(err)
}
o.Trace("comment created %d", o.forgejoComment.ID)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoComment.ID))
+ return f3_id.NewNodeID(o.forgejoComment.ID)
}
func (o *comment) Delete(ctx context.Context) {
diff --git a/services/f3/driver/comments.go b/services/f3/driver/comments.go
index eb79b74066..d8c84e290c 100644
--- a/services/f3/driver/comments.go
+++ b/services/f3/driver/comments.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/common.go b/services/f3/driver/common.go
index 104f91c977..4c5dfd8b1a 100644
--- a/services/f3/driver/common.go
+++ b/services/f3/driver/common.go
@@ -7,6 +7,7 @@ package driver
import (
"context"
+ f3_kind "code.forgejo.org/f3/gof3/v3/kind"
"code.forgejo.org/f3/gof3/v3/tree/generic"
)
@@ -37,7 +38,7 @@ func (o *common) getPageSize() int {
return o.getTreeDriver().GetPageSize()
}
-func (o *common) getKind() generic.Kind {
+func (o *common) getKind() f3_kind.Kind {
return o.GetNode().GetKind()
}
diff --git a/services/f3/driver/container.go b/services/f3/driver/container.go
index 1358be45e6..1ca47ef285 100644
--- a/services/f3/driver/container.go
+++ b/services/f3/driver/container.go
@@ -8,8 +8,8 @@ import (
"context"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
- "code.forgejo.org/f3/gof3/v3/tree/generic"
)
type container struct {
@@ -30,7 +30,7 @@ func (o *container) FromFormat(content f3.Interface) {
func (o *container) Get(context.Context) bool { return true }
-func (o *container) Put(ctx context.Context) generic.NodeID {
+func (o *container) Put(ctx context.Context) f3_id.NodeID {
return o.upsert(ctx)
}
@@ -38,6 +38,6 @@ func (o *container) Patch(ctx context.Context) {
o.upsert(ctx)
}
-func (o *container) upsert(context.Context) generic.NodeID {
- return generic.NodeID(o.getKind())
+func (o *container) upsert(context.Context) f3_id.NodeID {
+ return f3_id.NewNodeID(o.getKind())
}
diff --git a/services/f3/driver/forge.go b/services/f3/driver/forge.go
index b299b98c4e..03acb41450 100644
--- a/services/f3/driver/forge.go
+++ b/services/f3/driver/forge.go
@@ -8,9 +8,11 @@ import (
"context"
"fmt"
- user_model "code.gitea.io/gitea/models/user"
+ user_model "forgejo.org/models/user"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
+ f3_kind "code.forgejo.org/f3/gof3/v3/kind"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
"code.forgejo.org/f3/gof3/v3/util"
@@ -19,16 +21,16 @@ import (
type forge struct {
generic.NullDriver
- ownersKind map[string]generic.Kind
+ ownersKind map[string]f3_kind.Kind
}
func newForge() generic.NodeDriverInterface {
return &forge{
- ownersKind: make(map[string]generic.Kind),
+ ownersKind: make(map[string]f3_kind.Kind),
}
}
-func (o *forge) getOwnersKind(ctx context.Context, id string) generic.Kind {
+func (o *forge) getOwnersKind(ctx context.Context, id string) f3_kind.Kind {
kind, ok := o.ownersKind[id]
if !ok {
user, err := user_model.GetUserByID(ctx, util.ParseInt(id))
@@ -50,7 +52,7 @@ func (o *forge) getOwnersPath(ctx context.Context, id string) f3_tree.Path {
func (o *forge) Equals(context.Context, generic.NodeInterface) bool { return true }
func (o *forge) Get(context.Context) bool { return true }
-func (o *forge) Put(context.Context) generic.NodeID { return generic.NodeID("forge") }
+func (o *forge) Put(context.Context) f3_id.NodeID { return f3_id.NewNodeID("forge") }
func (o *forge) Patch(context.Context) {}
func (o *forge) Delete(context.Context) {}
func (o *forge) NewFormat() f3.Interface { return &f3.Forge{} }
diff --git a/services/f3/driver/issue.go b/services/f3/driver/issue.go
index 13235d04ac..6308c4cc2d 100644
--- a/services/f3/driver/issue.go
+++ b/services/f3/driver/issue.go
@@ -8,15 +8,16 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/timeutil"
- issue_service "code.gitea.io/gitea/services/issue"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/timeutil"
+ issue_service "forgejo.org/services/issue"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -48,7 +49,7 @@ func (o *issue) ToFormat() f3.Interface {
return o.NewFormat()
}
- var milestone *f3.Reference
+ milestone := &f3.Reference{}
if o.forgejoIssue.Milestone != nil {
milestone = f3_tree.NewIssueMilestoneReference(o.forgejoIssue.Milestone.ID)
}
@@ -82,9 +83,11 @@ func (o *issue) ToFormat() f3.Interface {
func (o *issue) FromFormat(content f3.Interface) {
issue := content.(*f3.Issue)
var milestone *issues_model.Milestone
+ var milestoneID int64
if issue.Milestone != nil {
+ milestoneID = issue.Milestone.GetIDAsInt()
milestone = &issues_model.Milestone{
- ID: issue.Milestone.GetIDAsInt(),
+ ID: milestoneID,
}
}
o.forgejoIssue = &issues_model.Issue{
@@ -95,8 +98,9 @@ func (o *issue) FromFormat(content f3.Interface) {
ID: issue.PosterID.GetIDAsInt(),
},
Content: issue.Content,
+ MilestoneID: milestoneID,
Milestone: milestone,
- IsClosed: issue.State == "closed",
+ IsClosed: issue.State == f3.IssueStateClosed,
CreatedUnix: timeutil.TimeStamp(issue.Created.Unix()),
UpdatedUnix: timeutil.TimeStamp(issue.Updated.Unix()),
IsLocked: issue.IsLocked,
@@ -124,7 +128,7 @@ func (o *issue) Get(ctx context.Context) bool {
o.Trace("%s", node.GetID())
project := f3_tree.GetProjectID(o.GetNode())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
issue, err := issues_model.GetIssueByIndex(ctx, project, id)
if issues_model.IsErrIssueNotExist(err) {
@@ -134,7 +138,7 @@ func (o *issue) Get(ctx context.Context) bool {
panic(fmt.Errorf("issue %v %w", id, err))
}
if err := issue.LoadAttributes(ctx); err != nil {
- panic(err)
+ panic(fmt.Errorf("LoadAttributes %v %w", id, err))
}
o.forgejoIssue = issue
@@ -144,29 +148,74 @@ func (o *issue) Get(ctx context.Context) bool {
func (o *issue) Patch(ctx context.Context) {
node := o.GetNode()
project := f3_tree.GetProjectID(o.GetNode())
- id := f3_util.ParseInt(string(node.GetID()))
- o.Trace("repo_id = %d, index = %d", project, id)
- if _, err := db.GetEngine(ctx).Where("`repo_id` = ? AND `index` = ?", project, id).Cols("name", "content").Update(o.forgejoIssue); err != nil {
+ index := node.GetID().Int64()
+ id := getIssueID(ctx, project, index)
+ o.Trace("id = %d, repo_id = %d, index = %d, assignees = %v", id, project, index, o.forgejoIssue.Assignees)
+ if _, err := db.GetEngine(ctx).Where("`id` = ?", id).Cols("name", "content", "is_closed", "milestone_id", "is_locked").Update(o.forgejoIssue); err != nil {
panic(fmt.Errorf("%v %v", o.forgejoIssue, err))
}
+
+ updateIssueAssignees(ctx, id, o.forgejoIssue.Assignees)
+ updateIssueLabels(ctx, id, o.forgejoIssue.Labels)
+}
+
+func getIssueID(ctx context.Context, repoID, index int64) int64 {
+ var id int64
+ if _, err := db.GetEngine(ctx).Select("id").Table("issue").Where("`repo_id` = ? AND `index` = ?", repoID, index).Get(&id); err != nil {
+ panic(fmt.Errorf("%v %v: %w", repoID, index, err))
+ }
+ return id
+}
+
+func updateIssueAssignees(ctx context.Context, issueID int64, assignees []*user_model.User) {
+ sess := db.GetEngine(ctx)
+
+ if _, err := sess.Where("issue_id = ?", issueID).Delete(new(issues_model.IssueAssignees)); err != nil {
+ panic(fmt.Errorf("delete IssueAssignees %v %w", issueID, err))
+ }
+
+ issueAssignees := make([]issues_model.IssueAssignees, 0, len(assignees))
+ for _, assignee := range assignees {
+ issueAssignees = append(issueAssignees, issues_model.IssueAssignees{
+ IssueID: issueID,
+ AssigneeID: assignee.ID,
+ })
+ }
+
+ if len(issueAssignees) > 0 {
+ if _, err := sess.Insert(issueAssignees); err != nil {
+ panic(fmt.Errorf("Insert %v %w", issueID, err))
+ }
+ }
}
-func (o *issue) Put(ctx context.Context) generic.NodeID {
+func updateIssueLabels(ctx context.Context, issueID int64, labels []*issues_model.Label) {
+ sess := db.GetEngine(ctx)
+
+ if _, err := sess.Where("issue_id = ?", issueID).Delete(new(issues_model.IssueLabel)); err != nil {
+ panic(fmt.Errorf("delete IssueLabel %v %w", issueID, err))
+ }
+
+ issueLabels := make([]issues_model.IssueLabel, 0, len(labels))
+ for _, label := range labels {
+ issueLabels = append(issueLabels, issues_model.IssueLabel{
+ IssueID: issueID,
+ LabelID: label.ID,
+ })
+ }
+
+ if len(issueLabels) > 0 {
+ if _, err := sess.Insert(issueLabels); err != nil {
+ panic(fmt.Errorf("Insert %v %w", issueID, err))
+ }
+ }
+}
+
+func (o *issue) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
o.forgejoIssue.RepoID = f3_tree.GetProjectID(o.GetNode())
- makeLabels := func(issueID int64) []issues_model.IssueLabel {
- labels := make([]issues_model.IssueLabel, 0, len(o.forgejoIssue.Labels))
- for _, label := range o.forgejoIssue.Labels {
- o.Trace("%d with label %d", issueID, label.ID)
- labels = append(labels, issues_model.IssueLabel{
- IssueID: issueID,
- LabelID: label.ID,
- })
- }
- return labels
- }
idx, err := db.GetNextResourceIndex(ctx, "issue_index", o.forgejoIssue.RepoID)
if err != nil {
@@ -180,34 +229,11 @@ func (o *issue) Put(ctx context.Context) generic.NodeID {
panic(err)
}
- labels := makeLabels(o.forgejoIssue.ID)
- if len(labels) > 0 {
- if _, err := sess.Insert(labels); err != nil {
- panic(err)
- }
- }
-
- makeAssignees := func(issueID int64) []issues_model.IssueAssignees {
- assignees := make([]issues_model.IssueAssignees, 0, len(o.forgejoIssue.Assignees))
- for _, assignee := range o.forgejoIssue.Assignees {
- o.Trace("%d with assignee %d", issueID, assignee.ID)
- assignees = append(assignees, issues_model.IssueAssignees{
- IssueID: issueID,
- AssigneeID: assignee.ID,
- })
- }
- return assignees
- }
-
- assignees := makeAssignees(o.forgejoIssue.ID)
- if len(assignees) > 0 {
- if _, err := sess.Insert(assignees); err != nil {
- panic(err)
- }
- }
+ updateIssueAssignees(ctx, o.forgejoIssue.ID, o.forgejoIssue.Assignees)
+ updateIssueLabels(ctx, o.forgejoIssue.ID, o.forgejoIssue.Labels)
o.Trace("issue created %d/%d", o.forgejoIssue.ID, o.forgejoIssue.Index)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoIssue.Index))
+ return f3_id.NewNodeID(o.forgejoIssue.Index)
}
func (o *issue) Delete(ctx context.Context) {
diff --git a/services/f3/driver/issues.go b/services/f3/driver/issues.go
index 3a5a64e2b1..dd6828dc86 100644
--- a/services/f3/driver/issues.go
+++ b/services/f3/driver/issues.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/label.go b/services/f3/driver/label.go
index 28a254cdf5..707ac2bab3 100644
--- a/services/f3/driver/label.go
+++ b/services/f3/driver/label.go
@@ -7,11 +7,13 @@ package driver
import (
"context"
"fmt"
+ "strings"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -45,7 +47,7 @@ func (o *label) ToFormat() f3.Interface {
return &f3.Label{
Common: f3.NewCommon(fmt.Sprintf("%d", o.forgejoLabel.ID)),
Name: o.forgejoLabel.Name,
- Color: o.forgejoLabel.Color,
+ Color: strings.TrimPrefix(o.forgejoLabel.Color, "#"),
Description: o.forgejoLabel.Description,
}
}
@@ -56,7 +58,7 @@ func (o *label) FromFormat(content f3.Interface) {
ID: f3_util.ParseInt(label.GetID()),
Name: label.Name,
Description: label.Description,
- Color: label.Color,
+ Color: "#" + label.Color,
}
}
@@ -65,7 +67,7 @@ func (o *label) Get(ctx context.Context) bool {
o.Trace("%s", node.GetID())
project := f3_tree.GetProjectID(o.GetNode())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
label, err := issues_model.GetLabelInRepoByID(ctx, project, id)
if issues_model.IsErrRepoLabelNotExist(err) {
@@ -80,12 +82,12 @@ func (o *label) Get(ctx context.Context) bool {
func (o *label) Patch(ctx context.Context) {
o.Trace("%d", o.forgejoLabel.ID)
- if _, err := db.GetEngine(ctx).ID(o.forgejoLabel.ID).Cols("name", "description").Update(o.forgejoLabel); err != nil {
+ if _, err := db.GetEngine(ctx).ID(o.forgejoLabel.ID).Cols("name", "description", "color").Update(o.forgejoLabel); err != nil {
panic(fmt.Errorf("UpdateLabelCols: %v %v", o.forgejoLabel, err))
}
}
-func (o *label) Put(ctx context.Context) generic.NodeID {
+func (o *label) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -94,7 +96,7 @@ func (o *label) Put(ctx context.Context) generic.NodeID {
panic(err)
}
o.Trace("label created %d", o.forgejoLabel.ID)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoLabel.ID))
+ return f3_id.NewNodeID(o.forgejoLabel.ID)
}
func (o *label) Delete(ctx context.Context) {
diff --git a/services/f3/driver/labels.go b/services/f3/driver/labels.go
index 03f986b57a..4f705ed206 100644
--- a/services/f3/driver/labels.go
+++ b/services/f3/driver/labels.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/main.go b/services/f3/driver/main.go
index 825d456692..eb6e4a6fb6 100644
--- a/services/f3/driver/main.go
+++ b/services/f3/driver/main.go
@@ -5,7 +5,7 @@
package driver
import (
- driver_options "code.gitea.io/gitea/services/f3/driver/options"
+ driver_options "forgejo.org/services/f3/driver/options"
"code.forgejo.org/f3/gof3/v3/options"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
diff --git a/services/f3/driver/main_test.go b/services/f3/driver/main_test.go
index 0d3d3d3cec..b136fd5b23 100644
--- a/services/f3/driver/main_test.go
+++ b/services/f3/driver/main_test.go
@@ -7,21 +7,21 @@ package driver
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
- driver_options "code.gitea.io/gitea/services/f3/driver/options"
+ "forgejo.org/models/unittest"
+ driver_options "forgejo.org/services/f3/driver/options"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
- _ "code.gitea.io/gitea/models/perm/access"
- _ "code.gitea.io/gitea/services/f3/driver/tests"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/perm/access"
+ _ "forgejo.org/services/f3/driver/tests"
tests_f3 "code.forgejo.org/f3/gof3/v3/tree/tests/f3"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestF3(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
tests_f3.ForgeCompliance(t, driver_options.Name)
}
diff --git a/services/f3/driver/milestone.go b/services/f3/driver/milestone.go
index c68687ccaf..d10e6918ac 100644
--- a/services/f3/driver/milestone.go
+++ b/services/f3/driver/milestone.go
@@ -9,12 +9,13 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -89,7 +90,7 @@ func (o *milestone) FromFormat(content f3.Interface) {
ID: f3_util.ParseInt(milestone.GetID()),
Name: milestone.Title,
Content: milestone.Description,
- IsClosed: milestone.State == "closed",
+ IsClosed: milestone.State == f3.MilestoneStateClosed,
CreatedUnix: timeutil.TimeStamp(milestone.Created.Unix()),
UpdatedUnix: timeutil.TimeStamp(milestone.Updated.Unix()),
ClosedDateUnix: closed,
@@ -102,7 +103,7 @@ func (o *milestone) Get(ctx context.Context) bool {
o.Trace("%s", node.GetID())
project := f3_tree.GetProjectID(o.GetNode())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
milestone, err := issues_model.GetMilestoneByRepoID(ctx, project, id)
if issues_model.IsErrMilestoneNotExist(err) {
@@ -117,12 +118,12 @@ func (o *milestone) Get(ctx context.Context) bool {
func (o *milestone) Patch(ctx context.Context) {
o.Trace("%d", o.forgejoMilestone.ID)
- if _, err := db.GetEngine(ctx).ID(o.forgejoMilestone.ID).Cols("name", "description").Update(o.forgejoMilestone); err != nil {
+ if _, err := db.GetEngine(ctx).ID(o.forgejoMilestone.ID).Cols("name", "description", "is_closed", "deadline_unix").Update(o.forgejoMilestone); err != nil {
panic(fmt.Errorf("UpdateMilestoneCols: %v %v", o.forgejoMilestone, err))
}
}
-func (o *milestone) Put(ctx context.Context) generic.NodeID {
+func (o *milestone) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -131,7 +132,7 @@ func (o *milestone) Put(ctx context.Context) generic.NodeID {
panic(err)
}
o.Trace("milestone created %d", o.forgejoMilestone.ID)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoMilestone.ID))
+ return f3_id.NewNodeID(o.forgejoMilestone.ID)
}
func (o *milestone) Delete(ctx context.Context) {
diff --git a/services/f3/driver/milestones.go b/services/f3/driver/milestones.go
index c816903bb1..cf0b70c158 100644
--- a/services/f3/driver/milestones.go
+++ b/services/f3/driver/milestones.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/options.go b/services/f3/driver/options.go
index abc5015dd0..516f9baf7a 100644
--- a/services/f3/driver/options.go
+++ b/services/f3/driver/options.go
@@ -7,7 +7,7 @@ package driver
import (
"net/http"
- driver_options "code.gitea.io/gitea/services/f3/driver/options"
+ driver_options "forgejo.org/services/f3/driver/options"
"code.forgejo.org/f3/gof3/v3/options"
)
diff --git a/services/f3/driver/organization.go b/services/f3/driver/organization.go
index 724a33298b..af1eea4dda 100644
--- a/services/f3/driver/organization.go
+++ b/services/f3/driver/organization.go
@@ -8,11 +8,12 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- org_model "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ org_model "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -62,7 +63,7 @@ func (o *organization) FromFormat(content f3.Interface) {
func (o *organization) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
organization, err := org_model.GetOrgByID(ctx, id)
if user_model.IsErrUserNotExist(err) {
return false
@@ -81,7 +82,7 @@ func (o *organization) Patch(ctx context.Context) {
}
}
-func (o *organization) Put(ctx context.Context) generic.NodeID {
+func (o *organization) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -94,7 +95,7 @@ func (o *organization) Put(ctx context.Context) generic.NodeID {
panic(err)
}
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoOrganization.ID))
+ return f3_id.NewNodeID(o.forgejoOrganization.ID)
}
func (o *organization) Delete(ctx context.Context) {
diff --git a/services/f3/driver/organizations.go b/services/f3/driver/organizations.go
index 6eeb714e1a..eca6bfb9d4 100644
--- a/services/f3/driver/organizations.go
+++ b/services/f3/driver/organizations.go
@@ -8,10 +8,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- org_model "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ org_model "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
)
@@ -36,13 +37,13 @@ func (o *organizations) ListPage(ctx context.Context, page int) generic.Children
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(organizations...)...)
}
-func (o *organizations) GetIDFromName(ctx context.Context, name string) generic.NodeID {
+func (o *organizations) GetIDFromName(ctx context.Context, name string) f3_id.NodeID {
organization, err := org_model.GetOrgByName(ctx, name)
if err != nil {
panic(fmt.Errorf("GetOrganizationByName: %v", err))
}
- return generic.NodeID(fmt.Sprintf("%d", organization.ID))
+ return f3_id.NewNodeID(organization.ID)
}
func newOrganizations() generic.NodeDriverInterface {
diff --git a/services/f3/driver/project.go b/services/f3/driver/project.go
index d4c3b843aa..5a3ec81e40 100644
--- a/services/f3/driver/project.go
+++ b/services/f3/driver/project.go
@@ -9,11 +9,12 @@ import (
"fmt"
"strings"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- repo_service "code.gitea.io/gitea/services/repository"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ repo_service "forgejo.org/services/repository"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -96,7 +97,7 @@ func (o *project) FromFormat(content f3.Interface) {
func (o *project) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
u, err := repo_model.GetRepositoryByID(ctx, id)
if repo_model.IsErrRepoNotExist(err) {
return false
@@ -121,7 +122,7 @@ func (o *project) Patch(ctx context.Context) {
}
}
-func (o *project) Put(ctx context.Context) generic.NodeID {
+func (o *project) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -155,7 +156,7 @@ func (o *project) Put(ctx context.Context) generic.NodeID {
panic(fmt.Errorf("LoadOwner %v %w", o.forgejoProject.BaseRepo, err))
}
- repo, err := repo_service.ForkRepository(ctx, doer, owner, repo_service.ForkRepoOptions{
+ repo, err := repo_service.ForkRepositoryIfNotExists(ctx, doer, owner, repo_service.ForkRepoOptions{
BaseRepo: o.forgejoProject.BaseRepo,
Name: o.forgejoProject.Name,
Description: o.forgejoProject.Description,
@@ -166,7 +167,7 @@ func (o *project) Put(ctx context.Context) generic.NodeID {
o.forgejoProject = repo
o.Trace("project created %d", o.forgejoProject.ID)
}
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoProject.ID))
+ return f3_id.NewNodeID(o.forgejoProject.ID)
}
func (o *project) Delete(ctx context.Context) {
diff --git a/services/f3/driver/projects.go b/services/f3/driver/projects.go
index 7ce263db79..0c76854f43 100644
--- a/services/f3/driver/projects.go
+++ b/services/f3/driver/projects.go
@@ -8,30 +8,30 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
- f3_util "code.forgejo.org/f3/gof3/v3/util"
)
type projects struct {
container
}
-func (o *projects) GetIDFromName(ctx context.Context, name string) generic.NodeID {
+func (o *projects) GetIDFromName(ctx context.Context, name string) f3_id.NodeID {
owner := f3_tree.GetOwnerName(o.GetNode())
forgejoProject, err := repo_model.GetRepositoryByOwnerAndName(ctx, owner, name)
if repo_model.IsErrRepoNotExist(err) {
- return generic.NilID
+ return f3_id.NilID
}
if err != nil {
panic(fmt.Errorf("error GetRepositoryByOwnerAndName(%s, %s): %v", owner, name, err))
}
- return generic.NodeID(fmt.Sprintf("%d", forgejoProject.ID))
+ return f3_id.NewNodeID(forgejoProject.ID)
}
func (o *projects) ListPage(ctx context.Context, page int) generic.ChildrenSlice {
@@ -41,7 +41,7 @@ func (o *projects) ListPage(ctx context.Context, page int) generic.ChildrenSlice
forgejoProjects, _, err := repo_model.SearchRepository(ctx, &repo_model.SearchRepoOptions{
ListOptions: db.ListOptions{Page: page, PageSize: pageSize},
- OwnerID: f3_util.ParseInt(string(owner.GetID())),
+ OwnerID: owner.GetID().Int64(),
Private: true,
})
if err != nil {
diff --git a/services/f3/driver/pullrequest.go b/services/f3/driver/pullrequest.go
index 8f59dbfe95..664ee6b13b 100644
--- a/services/f3/driver/pullrequest.go
+++ b/services/f3/driver/pullrequest.go
@@ -9,15 +9,17 @@ import (
"fmt"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/timeutil"
- issue_service "code.gitea.io/gitea/services/issue"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/timeutil"
+ issue_service "forgejo.org/services/issue"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
+ f3_path "code.forgejo.org/f3/gof3/v3/path"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -51,7 +53,7 @@ func (o *pullRequest) repositoryToReference(ctx context.Context, repository *rep
if repository == nil {
panic("unexpected nil repository")
}
- forge := o.getTree().GetRoot().GetChild(f3_tree.KindForge).GetDriver().(*forge)
+ forge := o.getTree().GetRoot().GetChild(f3_id.NewNodeID(f3_tree.KindForge)).GetDriver().(*forge)
owners := forge.getOwnersPath(ctx, fmt.Sprintf("%d", repository.OwnerID))
return f3_tree.NewRepositoryReference(owners.String(), repository.OwnerID, repository.ID)
}
@@ -61,7 +63,7 @@ func (o *pullRequest) referenceToRepository(reference *f3.Reference) int64 {
if reference.Get() == "../../repository/vcs" {
project = f3_tree.GetProjectID(o.GetNode())
} else {
- p := f3_tree.ToPath(generic.PathAbsolute(o.GetNode().GetCurrentPath().String(), reference.Get()))
+ p := f3_tree.ToPath(f3_path.PathAbsolute(generic.NewElementNode, o.GetNode().GetCurrentPath().String(), reference.Get()))
o.Trace("%v %v", o.GetNode().GetCurrentPath().String(), p)
_, project = p.OwnerAndProjectID()
}
@@ -172,7 +174,7 @@ func (o *pullRequest) FromFormat(content f3.Interface) {
Title: pullRequest.Title,
Content: pullRequest.Content,
Milestone: milestone,
- IsClosed: pullRequest.State == "closed",
+ IsClosed: pullRequest.State == f3.PullRequestStateClosed,
CreatedUnix: timeutil.TimeStamp(pullRequest.Created.Unix()),
UpdatedUnix: timeutil.TimeStamp(pullRequest.Updated.Unix()),
IsLocked: pullRequest.IsLocked,
@@ -190,7 +192,7 @@ func (o *pullRequest) Get(ctx context.Context) bool {
o.Trace("%s", node.GetID())
project := f3_tree.GetProjectID(o.GetNode())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
issue, err := issues_model.GetIssueByIndex(ctx, project, id)
if issues_model.IsErrIssueNotExist(err) {
@@ -219,7 +221,7 @@ func (o *pullRequest) Get(ctx context.Context) bool {
func (o *pullRequest) Patch(ctx context.Context) {
node := o.GetNode()
project := f3_tree.GetProjectID(o.GetNode())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
o.Trace("repo_id = %d, index = %d", project, id)
if _, err := db.GetEngine(ctx).Where("`repo_id` = ? AND `index` = ?", project, id).Cols("name", "content").Update(o.forgejoPullRequest); err != nil {
panic(fmt.Errorf("%v %v", o.forgejoPullRequest, err))
@@ -237,7 +239,7 @@ func (o *pullRequest) GetPullRequestRef() string {
return fmt.Sprintf("refs/pull/%s/head", o.GetNativeID())
}
-func (o *pullRequest) Put(ctx context.Context) generic.NodeID {
+func (o *pullRequest) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -289,7 +291,7 @@ func (o *pullRequest) Put(ctx context.Context) generic.NodeID {
}
o.Trace("pullRequest created %d/%d", o.forgejoPullRequest.ID, o.forgejoPullRequest.Index)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoPullRequest.Index))
+ return f3_id.NewNodeID(o.forgejoPullRequest.Index)
}
func (o *pullRequest) Delete(ctx context.Context) {
diff --git a/services/f3/driver/pullrequests.go b/services/f3/driver/pullrequests.go
index e7f2910314..227171994c 100644
--- a/services/f3/driver/pullrequests.go
+++ b/services/f3/driver/pullrequests.go
@@ -8,9 +8,9 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/optional"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/optional"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/reaction.go b/services/f3/driver/reaction.go
index ce2814ee7f..74c50b9d13 100644
--- a/services/f3/driver/reaction.go
+++ b/services/f3/driver/reaction.go
@@ -8,11 +8,12 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -67,7 +68,7 @@ func (o *reaction) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
if has, err := db.GetEngine(ctx).Where("ID = ?", id).Get(o.forgejoReaction); err != nil {
panic(fmt.Errorf("reaction %v %w", id, err))
@@ -87,7 +88,7 @@ func (o *reaction) Patch(ctx context.Context) {
}
}
-func (o *reaction) Put(ctx context.Context) generic.NodeID {
+func (o *reaction) Put(ctx context.Context) f3_id.NodeID {
o.Error("%v", o.forgejoReaction.User)
sess := db.GetEngine(ctx)
@@ -115,7 +116,7 @@ func (o *reaction) Put(ctx context.Context) generic.NodeID {
panic(err)
}
o.Trace("reaction created %d", o.forgejoReaction.ID)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoReaction.ID))
+ return f3_id.NewNodeID(o.forgejoReaction.ID)
}
func (o *reaction) Delete(ctx context.Context) {
diff --git a/services/f3/driver/reactions.go b/services/f3/driver/reactions.go
index b7fd5e8f0a..a546927b92 100644
--- a/services/f3/driver/reactions.go
+++ b/services/f3/driver/reactions.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/release.go b/services/f3/driver/release.go
index d0672b8965..df38bd8bc0 100644
--- a/services/f3/driver/release.go
+++ b/services/f3/driver/release.go
@@ -9,14 +9,15 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/timeutil"
- release_service "code.gitea.io/gitea/services/release"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/timeutil"
+ release_service "forgejo.org/services/release"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -85,7 +86,7 @@ func (o *release) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
release, err := repo_model.GetReleaseByID(ctx, id)
if repo_model.IsErrReleaseNotExist(err) {
@@ -115,7 +116,7 @@ func (o *release) Patch(ctx context.Context) {
}
}
-func (o *release) Put(ctx context.Context) generic.NodeID {
+func (o *release) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -129,11 +130,11 @@ func (o *release) Put(ctx context.Context) generic.NodeID {
panic(err)
}
defer gitRepo.Close()
- if err := release_service.CreateRelease(gitRepo, o.forgejoRelease, nil, ""); err != nil {
+ if err := release_service.CreateRelease(gitRepo, o.forgejoRelease, "", nil); err != nil {
panic(err)
}
o.Trace("release created %d", o.forgejoRelease.ID)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoRelease.ID))
+ return f3_id.NewNodeID(o.forgejoRelease.ID)
}
func (o *release) Delete(ctx context.Context) {
diff --git a/services/f3/driver/releases.go b/services/f3/driver/releases.go
index 3b46bc7c54..a631c0b60e 100644
--- a/services/f3/driver/releases.go
+++ b/services/f3/driver/releases.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/repository.go b/services/f3/driver/repository.go
index 203622ad9b..e7f4e43723 100644
--- a/services/f3/driver/repository.go
+++ b/services/f3/driver/repository.go
@@ -7,10 +7,11 @@ package driver
import (
"context"
- repo_model "code.gitea.io/gitea/models/repo"
+ repo_model "forgejo.org/models/repo"
"code.forgejo.org/f3/gof3/v3/f3"
helpers_repository "code.forgejo.org/f3/gof3/v3/forges/helpers/repository"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
)
@@ -57,7 +58,7 @@ func (o *repository) Get(ctx context.Context) bool {
return o.h.Get(ctx)
}
-func (o *repository) Put(ctx context.Context) generic.NodeID {
+func (o *repository) Put(ctx context.Context) f3_id.NodeID {
return o.upsert(ctx)
}
@@ -65,13 +66,13 @@ func (o *repository) Patch(ctx context.Context) {
o.upsert(ctx)
}
-func (o *repository) upsert(ctx context.Context) generic.NodeID {
+func (o *repository) upsert(ctx context.Context) f3_id.NodeID {
o.Trace("%s", o.GetNativeID())
o.h.Upsert(ctx, o.f)
- return generic.NodeID(o.f.Name)
+ return f3_id.NewNodeID(o.f.Name)
}
-func (o *repository) SetFetchFunc(fetchFunc func(ctx context.Context, destination string)) {
+func (o *repository) SetFetchFunc(fetchFunc func(ctx context.Context, destination string, internalRefs []string)) {
o.f.FetchFunc = fetchFunc
}
@@ -92,6 +93,10 @@ func (o *repository) GetRepositoryPushURL() string {
return o.getURL()
}
+func (o *repository) GetRepositoryInternalRefs() []string {
+ return []string{}
+}
+
func newRepository(_ context.Context) generic.NodeDriverInterface {
r := &repository{
f: &f3.Repository{},
diff --git a/services/f3/driver/review.go b/services/f3/driver/review.go
index b6a02bc145..f4f5ff44b8 100644
--- a/services/f3/driver/review.go
+++ b/services/f3/driver/review.go
@@ -8,12 +8,13 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -111,7 +112,7 @@ func (o *review) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
review, err := issues_model.GetReviewByID(ctx, id)
if issues_model.IsErrReviewNotExist(err) {
@@ -134,7 +135,7 @@ func (o *review) Patch(ctx context.Context) {
}
}
-func (o *review) Put(ctx context.Context) generic.NodeID {
+func (o *review) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -153,7 +154,7 @@ func (o *review) Put(ctx context.Context) generic.NodeID {
panic(err)
}
o.Trace("review created %d", o.forgejoReview.ID)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoReview.ID))
+ return f3_id.NewNodeID(o.forgejoReview.ID)
}
func (o *review) Delete(ctx context.Context) {
diff --git a/services/f3/driver/reviewcomment.go b/services/f3/driver/reviewcomment.go
index c2a5537b28..22759b6df3 100644
--- a/services/f3/driver/reviewcomment.go
+++ b/services/f3/driver/reviewcomment.go
@@ -9,12 +9,13 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -92,7 +93,7 @@ func (o *reviewComment) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
reviewComment, err := issues_model.GetCommentByID(ctx, id)
if issues_model.IsErrCommentNotExist(err) {
@@ -115,7 +116,7 @@ func (o *reviewComment) Patch(ctx context.Context) {
}
}
-func (o *reviewComment) Put(ctx context.Context) generic.NodeID {
+func (o *reviewComment) Put(ctx context.Context) f3_id.NodeID {
node := o.GetNode()
o.Trace("%s", node.GetID())
@@ -125,7 +126,7 @@ func (o *reviewComment) Put(ctx context.Context) generic.NodeID {
panic(err)
}
o.Trace("reviewComment created %d", o.forgejoReviewComment.ID)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoReviewComment.ID))
+ return f3_id.NewNodeID(o.forgejoReviewComment.ID)
}
func (o *reviewComment) Delete(ctx context.Context) {
diff --git a/services/f3/driver/reviewcomments.go b/services/f3/driver/reviewcomments.go
index e11aaa489b..2aa4dea22c 100644
--- a/services/f3/driver/reviewcomments.go
+++ b/services/f3/driver/reviewcomments.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/reviews.go b/services/f3/driver/reviews.go
index a20d5741d1..7c3dcb37de 100644
--- a/services/f3/driver/reviews.go
+++ b/services/f3/driver/reviews.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/root.go b/services/f3/driver/root.go
index 0e8a67faf3..f4a6e6a7ca 100644
--- a/services/f3/driver/root.go
+++ b/services/f3/driver/root.go
@@ -8,6 +8,7 @@ import (
"context"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
"code.forgejo.org/f3/gof3/v3/tree/generic"
)
@@ -33,8 +34,8 @@ func (o *root) ToFormat() f3.Interface {
func (o *root) Get(context.Context) bool { return true }
-func (o *root) Put(context.Context) generic.NodeID {
- return generic.NilID
+func (o *root) Put(context.Context) f3_id.NodeID {
+ return f3_id.NilID
}
func (o *root) Patch(context.Context) {
diff --git a/services/f3/driver/tests/init.go b/services/f3/driver/tests/init.go
index d7bf23ac88..9035296dc0 100644
--- a/services/f3/driver/tests/init.go
+++ b/services/f3/driver/tests/init.go
@@ -5,7 +5,7 @@
package tests
import (
- driver_options "code.gitea.io/gitea/services/f3/driver/options"
+ driver_options "forgejo.org/services/f3/driver/options"
tests_forge "code.forgejo.org/f3/gof3/v3/tree/tests/f3/forge"
)
diff --git a/services/f3/driver/tests/new.go b/services/f3/driver/tests/new.go
index 2e3dfc3c95..2f5c6c64db 100644
--- a/services/f3/driver/tests/new.go
+++ b/services/f3/driver/tests/new.go
@@ -7,10 +7,10 @@ package tests
import (
"testing"
- driver_options "code.gitea.io/gitea/services/f3/driver/options"
+ driver_options "forgejo.org/services/f3/driver/options"
+ f3_kind "code.forgejo.org/f3/gof3/v3/kind"
"code.forgejo.org/f3/gof3/v3/options"
- "code.forgejo.org/f3/gof3/v3/tree/generic"
forge_test "code.forgejo.org/f3/gof3/v3/tree/tests/f3/forge"
)
@@ -22,8 +22,8 @@ func (o *forgeTest) NewOptions(t *testing.T) options.Interface {
return newTestOptions(t)
}
-func (o *forgeTest) GetExceptions() []generic.Kind {
- return []generic.Kind{}
+func (o *forgeTest) GetExceptions() []f3_kind.Kind {
+ return []f3_kind.Kind{}
}
func (o *forgeTest) GetNonTestUsers() []string {
diff --git a/services/f3/driver/tests/options.go b/services/f3/driver/tests/options.go
index adaa1da588..f61b10c9ef 100644
--- a/services/f3/driver/tests/options.go
+++ b/services/f3/driver/tests/options.go
@@ -7,9 +7,9 @@ package tests
import (
"testing"
- forgejo_log "code.gitea.io/gitea/modules/log"
- driver_options "code.gitea.io/gitea/services/f3/driver/options"
- "code.gitea.io/gitea/services/f3/util"
+ forgejo_log "forgejo.org/modules/log"
+ driver_options "forgejo.org/services/f3/driver/options"
+ "forgejo.org/services/f3/util"
"code.forgejo.org/f3/gof3/v3/options"
)
diff --git a/services/f3/driver/topic.go b/services/f3/driver/topic.go
index 5ea868289b..cc94aa35fa 100644
--- a/services/f3/driver/topic.go
+++ b/services/f3/driver/topic.go
@@ -8,10 +8,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -61,7 +62,7 @@ func (o *topic) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
if has, err := db.GetEngine(ctx).Where("ID = ?", id).Get(o.forgejoTopic); err != nil {
panic(fmt.Errorf("topic %v %w", id, err))
@@ -79,14 +80,14 @@ func (o *topic) Patch(ctx context.Context) {
}
}
-func (o *topic) Put(ctx context.Context) generic.NodeID {
+func (o *topic) Put(ctx context.Context) f3_id.NodeID {
sess := db.GetEngine(ctx)
if _, err := sess.Insert(o.forgejoTopic); err != nil {
panic(err)
}
o.Trace("topic created %d", o.forgejoTopic.ID)
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoTopic.ID))
+ return f3_id.NewNodeID(o.forgejoTopic.ID)
}
func (o *topic) Delete(ctx context.Context) {
diff --git a/services/f3/driver/topics.go b/services/f3/driver/topics.go
index 2685a47928..38f03dbd2d 100644
--- a/services/f3/driver/topics.go
+++ b/services/f3/driver/topics.go
@@ -8,8 +8,8 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
diff --git a/services/f3/driver/tree.go b/services/f3/driver/tree.go
index 0302ed74ae..ff927df9d4 100644
--- a/services/f3/driver/tree.go
+++ b/services/f3/driver/tree.go
@@ -8,8 +8,9 @@ import (
"context"
"fmt"
- forgejo_options "code.gitea.io/gitea/services/f3/driver/options"
+ forgejo_options "forgejo.org/services/f3/driver/options"
+ f3_kind "code.forgejo.org/f3/gof3/v3/kind"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
)
@@ -24,7 +25,7 @@ func (o *treeDriver) Init() {
o.NullTreeDriver.Init()
}
-func (o *treeDriver) Factory(ctx context.Context, kind generic.Kind) generic.NodeDriverInterface {
+func (o *treeDriver) Factory(ctx context.Context, kind f3_kind.Kind) generic.NodeDriverInterface {
switch kind {
case f3_tree.KindForge:
return newForge()
@@ -88,7 +89,7 @@ func (o *treeDriver) Factory(ctx context.Context, kind generic.Kind) generic.Nod
return newRepositories()
case f3_tree.KindRepository:
return newRepository(ctx)
- case generic.KindRoot:
+ case f3_kind.KindRoot:
return newRoot(o.GetTree().(f3_tree.TreeInterface).NewFormat(kind))
default:
panic(fmt.Errorf("unexpected kind %s", kind))
diff --git a/services/f3/driver/user.go b/services/f3/driver/user.go
index 91456b2cb8..bf8bfaf9c9 100644
--- a/services/f3/driver/user.go
+++ b/services/f3/driver/user.go
@@ -9,11 +9,12 @@ import (
"fmt"
"strings"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/optional"
- user_service "code.gitea.io/gitea/services/user"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ user_service "forgejo.org/services/user"
"code.forgejo.org/f3/gof3/v3/f3"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
f3_util "code.forgejo.org/f3/gof3/v3/util"
@@ -81,7 +82,7 @@ func (o *user) FromFormat(content f3.Interface) {
func (o *user) Get(ctx context.Context) bool {
node := o.GetNode()
o.Trace("%s", node.GetID())
- id := f3_util.ParseInt(string(node.GetID()))
+ id := node.GetID().Int64()
u, err := user_model.GetPossibleUserByID(ctx, id)
if user_model.IsErrUserNotExist(err) {
return false
@@ -96,9 +97,9 @@ func (o *user) Get(ctx context.Context) bool {
func (o *user) Patch(context.Context) {
}
-func (o *user) Put(ctx context.Context) generic.NodeID {
+func (o *user) Put(ctx context.Context) f3_id.NodeID {
if user := getSystemUserByName(o.forgejoUser.Name); user != nil {
- return generic.NodeID(fmt.Sprintf("%d", user.ID))
+ return f3_id.NewNodeID(user.ID)
}
o.forgejoUser.LowerName = strings.ToLower(o.forgejoUser.Name)
@@ -111,7 +112,7 @@ func (o *user) Put(ctx context.Context) generic.NodeID {
panic(err)
}
- return generic.NodeID(fmt.Sprintf("%d", o.forgejoUser.ID))
+ return f3_id.NewNodeID(o.forgejoUser.ID)
}
func (o *user) Delete(ctx context.Context) {
diff --git a/services/f3/driver/users.go b/services/f3/driver/users.go
index bb5240c704..cb413ae05d 100644
--- a/services/f3/driver/users.go
+++ b/services/f3/driver/users.go
@@ -8,9 +8,10 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ f3_id "code.forgejo.org/f3/gof3/v3/id"
f3_tree "code.forgejo.org/f3/gof3/v3/tree/f3"
"code.forgejo.org/f3/gof3/v3/tree/generic"
)
@@ -34,13 +35,13 @@ func (o *users) ListPage(ctx context.Context, page int) generic.ChildrenSlice {
return f3_tree.ConvertListed(ctx, o.GetNode(), f3_tree.ConvertToAny(users...)...)
}
-func (o *users) GetIDFromName(ctx context.Context, name string) generic.NodeID {
+func (o *users) GetIDFromName(ctx context.Context, name string) f3_id.NodeID {
user, err := user_model.GetUserByName(ctx, name)
if err != nil {
panic(fmt.Errorf("GetUserByName: %v", err))
}
- return generic.NodeID(fmt.Sprintf("%d", user.ID))
+ return f3_id.NewNodeID(user.ID)
}
func newUsers() generic.NodeDriverInterface {
diff --git a/services/f3/util/logger.go b/services/f3/util/logger.go
index 21d8d6bbfa..9a1409ae84 100644
--- a/services/f3/util/logger.go
+++ b/services/f3/util/logger.go
@@ -6,8 +6,8 @@ package util
import (
"fmt"
- forgejo_log "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/migration"
+ forgejo_log "forgejo.org/modules/log"
+ "forgejo.org/modules/migration"
"code.forgejo.org/f3/gof3/v3/logger"
)
diff --git a/services/f3/util/logger_test.go b/services/f3/util/logger_test.go
index d16c688bb0..4afd5dd57f 100644
--- a/services/f3/util/logger_test.go
+++ b/services/f3/util/logger_test.go
@@ -8,8 +8,8 @@ import (
"testing"
"time"
- forgejo_log "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/test"
+ forgejo_log "forgejo.org/modules/log"
+ "forgejo.org/modules/test"
"code.forgejo.org/f3/gof3/v3/logger"
"github.com/stretchr/testify/assert"
@@ -78,12 +78,12 @@ func testLoggerCase(t *testing.T, level logger.Level, loggerFunc func(logger.Mes
assert.True(t, logFiltered[i], filtered[i])
if moreVerbose != nil {
i++
- require.True(t, len(logFiltered) > i)
+ require.Greater(t, len(logFiltered), i)
assert.False(t, logFiltered[i], filtered[i])
}
if lessVerbose != nil {
i++
- require.True(t, len(logFiltered) > i)
+ require.Greater(t, len(logFiltered), i)
assert.True(t, logFiltered[i], filtered[i])
}
}
diff --git a/services/federation/federation_service.go b/services/federation/federation_service.go
index a7d9b6ef80..21c7be855b 100644
--- a/services/federation/federation_service.go
+++ b/services/federation/federation_service.go
@@ -11,15 +11,15 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/forgefed"
- "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/activitypub"
- "code.gitea.io/gitea/modules/auth/password"
- fm "code.gitea.io/gitea/modules/forgefed"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/validation"
+ "forgejo.org/models/forgefed"
+ "forgejo.org/models/repo"
+ "forgejo.org/models/user"
+ "forgejo.org/modules/activitypub"
+ "forgejo.org/modules/auth/password"
+ fm "forgejo.org/modules/forgefed"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/validation"
"github.com/google/uuid"
)
@@ -99,7 +99,11 @@ func ProcessLikeActivity(ctx context.Context, form any, repositoryID int64) (int
func CreateFederationHostFromAP(ctx context.Context, actorID fm.ActorID) (*forgefed.FederationHost, error) {
actionsUser := user.NewActionsUser()
- client, err := activitypub.NewClient(ctx, actionsUser, "no idea where to get key material.")
+ clientFactory, err := activitypub.GetClientFactory(ctx)
+ if err != nil {
+ return nil, err
+ }
+ client, err := clientFactory.WithKeys(ctx, actionsUser, "no idea where to get key material.")
if err != nil {
return nil, err
}
@@ -153,7 +157,11 @@ func GetFederationHostForURI(ctx context.Context, actorURI string) (*forgefed.Fe
func CreateUserFromAP(ctx context.Context, personID fm.PersonID, federationHostID int64) (*user.User, *user.FederatedUser, error) {
// ToDo: Do we get a publicKeyId from server, repo or owner or repo?
actionsUser := user.NewActionsUser()
- client, err := activitypub.NewClient(ctx, actionsUser, "no idea where to get key material.")
+ clientFactory, err := activitypub.GetClientFactory(ctx)
+ if err != nil {
+ return nil, nil, err
+ }
+ client, err := clientFactory.WithKeys(ctx, actionsUser, "no idea where to get key material.")
if err != nil {
return nil, nil, err
}
@@ -262,7 +270,11 @@ func SendLikeActivities(ctx context.Context, doer user.User, repoID int64) error
likeActivityList = append(likeActivityList, likeActivity)
}
- apclient, err := activitypub.NewClient(ctx, &doer, doer.APActorID())
+ apclientFactory, err := activitypub.GetClientFactory(ctx)
+ if err != nil {
+ return err
+ }
+ apclient, err := apclientFactory.WithKeys(ctx, &doer, doer.APActorID())
if err != nil {
return err
}
diff --git a/services/feed/action.go b/services/feed/action.go
index 83daaa1438..a2cd0551a3 100644
--- a/services/feed/action.go
+++ b/services/feed/action.go
@@ -9,16 +9,17 @@ import (
"path"
"strings"
- activities_model "code.gitea.io/gitea/models/activities"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/util"
- notify_service "code.gitea.io/gitea/services/notify"
+ activities_model "forgejo.org/models/activities"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ notify_service "forgejo.org/services/notify"
)
type actionNotifier struct {
@@ -319,6 +320,10 @@ func (*actionNotifier) NotifyPullRevieweDismiss(ctx context.Context, doer *user_
}
func (a *actionNotifier) PushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+ if len(commits.Commits) > setting.UI.FeedMaxCommitNum {
+ commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum]
+ }
+
data, err := json.Marshal(commits)
if err != nil {
log.Error("Marshal: %v", err)
@@ -390,6 +395,10 @@ func (a *actionNotifier) DeleteRef(ctx context.Context, doer *user_model.User, r
}
func (a *actionNotifier) SyncPushCommits(ctx context.Context, pusher *user_model.User, repo *repo_model.Repository, opts *repository.PushUpdateOptions, commits *repository.PushCommits) {
+ if len(commits.Commits) > setting.UI.FeedMaxCommitNum {
+ commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum]
+ }
+
data, err := json.Marshal(commits)
if err != nil {
log.Error("json.Marshal: %v", err)
diff --git a/services/feed/action_test.go b/services/feed/action_test.go
index e1b071d8f6..b0bbcdc3b6 100644
--- a/services/feed/action_test.go
+++ b/services/feed/action_test.go
@@ -7,15 +7,21 @@ import (
"strings"
"testing"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
- _ "code.gitea.io/gitea/models/actions"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/forgefed"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestMain(m *testing.M) {
@@ -23,7 +29,7 @@ func TestMain(m *testing.M) {
}
func TestRenameRepoAction(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID})
@@ -50,3 +56,89 @@ func TestRenameRepoAction(t *testing.T) {
unittest.AssertExistsAndLoadBean(t, actionBean)
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
+
+func pushCommits() *repository.PushCommits {
+ pushCommits := repository.NewPushCommits()
+ pushCommits.Commits = []*repository.PushCommit{
+ {
+ Sha1: "69554a6",
+ CommitterEmail: "user2@example.com",
+ CommitterName: "User2",
+ AuthorEmail: "user2@example.com",
+ AuthorName: "User2",
+ Message: "not signed commit",
+ },
+ {
+ Sha1: "27566bd",
+ CommitterEmail: "user2@example.com",
+ CommitterName: "User2",
+ AuthorEmail: "user2@example.com",
+ AuthorName: "User2",
+ Message: "good signed commit (with not yet validated email)",
+ },
+ {
+ Sha1: "5099b81",
+ CommitterEmail: "user2@example.com",
+ CommitterName: "User2",
+ AuthorEmail: "user2@example.com",
+ AuthorName: "User2",
+ Message: "good signed commit",
+ },
+ }
+ pushCommits.HeadCommit = &repository.PushCommit{Sha1: "69554a6"}
+ return pushCommits
+}
+
+func TestSyncPushCommits(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID})
+
+ t.Run("All commits", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.UI.FeedMaxCommitNum, 10)()
+
+ maxID := unittest.GetCount(t, &activities_model.Action{})
+ NewNotifier().SyncPushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("master")}, pushCommits())
+
+ newNotification := unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ActUserID: user.ID, RefName: "refs/heads/master"}, unittest.Cond("id > ?", maxID))
+ assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"27566bd","Message":"good signed commit (with not yet validated email)","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"5099b81","Message":"good signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
+ })
+
+ t.Run("Only one commit", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.UI.FeedMaxCommitNum, 1)()
+
+ maxID := unittest.GetCount(t, &activities_model.Action{})
+ NewNotifier().SyncPushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("main")}, pushCommits())
+
+ newNotification := unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ActUserID: user.ID, RefName: "refs/heads/main"}, unittest.Cond("id > ?", maxID))
+ assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
+ })
+}
+
+func TestPushCommits(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID})
+
+ t.Run("All commits", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.UI.FeedMaxCommitNum, 10)()
+
+ maxID := unittest.GetCount(t, &activities_model.Action{})
+ NewNotifier().PushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("master")}, pushCommits())
+
+ newNotification := unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ActUserID: user.ID, RefName: "refs/heads/master"}, unittest.Cond("id > ?", maxID))
+ assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"27566bd","Message":"good signed commit (with not yet validated email)","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"},{"Sha1":"5099b81","Message":"good signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
+ })
+
+ t.Run("Only one commit", func(t *testing.T) {
+ defer test.MockVariableValue(&setting.UI.FeedMaxCommitNum, 1)()
+
+ maxID := unittest.GetCount(t, &activities_model.Action{})
+ NewNotifier().PushCommits(db.DefaultContext, user, repo, &repository.PushUpdateOptions{RefFullName: git.RefNameFromBranch("main")}, pushCommits())
+
+ newNotification := unittest.AssertExistsAndLoadBean(t, &activities_model.Action{ActUserID: user.ID, RefName: "refs/heads/main"}, unittest.Cond("id > ?", maxID))
+ assert.JSONEq(t, `{"Commits":[{"Sha1":"69554a6","Message":"not signed commit","AuthorEmail":"user2@example.com","AuthorName":"User2","CommitterEmail":"user2@example.com","CommitterName":"User2","Timestamp":"0001-01-01T00:00:00Z"}],"HeadCommit":{"Sha1":"69554a6","Message":"","AuthorEmail":"","AuthorName":"","CommitterEmail":"","CommitterName":"","Timestamp":"0001-01-01T00:00:00Z"},"CompareURL":"","Len":0}`, newNotification.Content)
+ })
+}
diff --git a/services/forgejo/main_test.go b/services/forgejo/main_test.go
index e88b7d0263..5523ed1aab 100644
--- a/services/forgejo/main_test.go
+++ b/services/forgejo/main_test.go
@@ -5,11 +5,12 @@ package forgejo
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/forgejo/sanity.go b/services/forgejo/sanity.go
index 5e817d67f5..70f15889d4 100644
--- a/services/forgejo/sanity.go
+++ b/services/forgejo/sanity.go
@@ -3,9 +3,9 @@
package forgejo
import (
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
var (
diff --git a/services/forgejo/sanity_test.go b/services/forgejo/sanity_test.go
index 29ed3bbfff..065a9fda4d 100644
--- a/services/forgejo/sanity_test.go
+++ b/services/forgejo/sanity_test.go
@@ -7,25 +7,25 @@ import (
"path/filepath"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestForgejo_PreMigrationSanityChecks(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
ctx := db.DefaultContext
e := db.GetEngine(ctx)
- assert.NoError(t, PreMigrationSanityChecks(e, ForgejoV4DatabaseVersion, configFixture(t, "")))
+ require.NoError(t, PreMigrationSanityChecks(e, ForgejoV4DatabaseVersion, configFixture(t, "")))
}
func configFixture(t *testing.T, content string) setting.ConfigProvider {
config := filepath.Join(t.TempDir(), "app.ini")
- assert.NoError(t, os.WriteFile(config, []byte(content), 0o777))
+ require.NoError(t, os.WriteFile(config, []byte(content), 0o777))
cfg, err := setting.NewConfigProviderFromFile(config)
- assert.NoError(t, err)
+ require.NoError(t, err)
return cfg
}
diff --git a/services/forgejo/sanity_v1TOv5_0_1Included.go b/services/forgejo/sanity_v1TOv5_0_1Included.go
index 49de636f33..1d3f07d8e1 100644
--- a/services/forgejo/sanity_v1TOv5_0_1Included.go
+++ b/services/forgejo/sanity_v1TOv5_0_1Included.go
@@ -6,9 +6,9 @@ import (
"fmt"
"strings"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/forgejo/semver"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ "forgejo.org/models/forgejo/semver"
+ "forgejo.org/modules/setting"
"github.com/hashicorp/go-version"
)
diff --git a/services/forgejo/sanity_v1TOv5_0_1Included_test.go b/services/forgejo/sanity_v1TOv5_0_1Included_test.go
index 93bca0d2fb..2521afb496 100644
--- a/services/forgejo/sanity_v1TOv5_0_1Included_test.go
+++ b/services/forgejo/sanity_v1TOv5_0_1Included_test.go
@@ -6,16 +6,16 @@ import (
"fmt"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/forgejo/semver"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/log"
+ "forgejo.org/models/db"
+ "forgejo.org/models/forgejo/semver"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/log"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestForgejo_v1TOv5_0_1Included(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
logFatal = func(string, ...any) {}
defer func() {
@@ -71,7 +71,7 @@ func verifyForgejoV1TOv5_0_1Included(t *testing.T, config, message string) {
} {
cfg := configFixture(t, testCase.config)
semver.SetVersionString(ctx, testCase.semver)
- assert.NoError(t, v1TOv5_0_1Included(e, testCase.dbVersion, cfg))
+ require.NoError(t, v1TOv5_0_1Included(e, testCase.dbVersion, cfg))
}
for _, testCase := range []struct {
@@ -110,6 +110,6 @@ func verifyForgejoV1TOv5_0_1Included(t *testing.T, config, message string) {
} {
cfg := configFixture(t, testCase.config)
semver.SetVersionString(ctx, testCase.semver)
- assert.ErrorContains(t, v1TOv5_0_1Included(e, testCase.dbVersion, cfg), message)
+ require.ErrorContains(t, v1TOv5_0_1Included(e, testCase.dbVersion, cfg), message)
}
}
diff --git a/services/forms/admin.go b/services/forms/admin.go
index 7d46904440..5a5d46634b 100644
--- a/services/forms/admin.go
+++ b/services/forms/admin.go
@@ -6,11 +6,11 @@ package forms
import (
"net/http"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// AdminCreateUserForm form for admin to create user
@@ -18,7 +18,7 @@ type AdminCreateUserForm struct {
LoginType string `binding:"Required"`
LoginName string
UserName string `binding:"Required;Username;MaxSize(40)"`
- Email string `binding:"Required;Email;MaxSize(254)"`
+ Email string `binding:"Required;EmailForAdmin;MaxSize(254)"`
Password string `binding:"MaxSize(255)"`
SendNotify bool
MustChangePassword bool
@@ -37,7 +37,7 @@ type AdminEditUserForm struct {
UserName string `binding:"Username;MaxSize(40)"`
LoginName string
FullName string `binding:"MaxSize(100)"`
- Email string `binding:"Required;Email;MaxSize(254)"`
+ Email string `binding:"Required;EmailForAdmin;MaxSize(254)"`
Password string `binding:"MaxSize(255)"`
Website string `binding:"ValidUrl;MaxSize(255)"`
Location string `binding:"MaxSize(50)"`
diff --git a/services/forms/auth_form.go b/services/forms/auth_form.go
index a3eca9473b..e665ca0d19 100644
--- a/services/forms/auth_form.go
+++ b/services/forms/auth_form.go
@@ -6,10 +6,10 @@ package forms
import (
"net/http"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// AuthenticationForm form for authentication
@@ -75,12 +75,8 @@ type AuthenticationForm struct {
Oauth2RestrictedGroup string
Oauth2GroupTeamMap string `binding:"ValidGroupTeamMap"`
Oauth2GroupTeamMapRemoval bool
+ Oauth2AttributeSSHPublicKey string
SkipLocalTwoFA bool
- SSPIAutoCreateUsers bool
- SSPIAutoActivateUsers bool
- SSPIStripDomainNames bool
- SSPISeparatorReplacement string `binding:"AlphaDashDot;MaxSize(5)"`
- SSPIDefaultLanguage string
GroupTeamMap string `binding:"ValidGroupTeamMap"`
GroupTeamMapRemoval bool
}
diff --git a/services/forms/org.go b/services/forms/org.go
index 3677fcf429..a6e4e72c4a 100644
--- a/services/forms/org.go
+++ b/services/forms/org.go
@@ -7,11 +7,11 @@ package forms
import (
"net/http"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// ________ .__ __ .__
@@ -62,7 +62,7 @@ func (f *UpdateOrgSettingForm) Validate(req *http.Request, errs binding.Errors)
// CreateTeamForm form for creating team
type CreateTeamForm struct {
- TeamName string `binding:"Required;AlphaDashDot;MaxSize(30)"`
+ TeamName string `binding:"Required;AlphaDashDot;MaxSize(255)"`
Description string `binding:"MaxSize(255)"`
Permission string
RepoAccess string
diff --git a/services/forms/package_form.go b/services/forms/package_form.go
index cc940d42d3..82e5a09f86 100644
--- a/services/forms/package_form.go
+++ b/services/forms/package_form.go
@@ -6,16 +6,16 @@ package forms
import (
"net/http"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
type PackageCleanupRuleForm struct {
ID int64
Enabled bool
- Type string `binding:"Required;In(alpine,cargo,chef,composer,conan,conda,container,cran,debian,generic,go,helm,maven,npm,nuget,pub,pypi,rpm,rubygems,swift,vagrant)"`
+ Type string `binding:"Required;In(alpine,arch,cargo,chef,composer,conan,conda,container,cran,debian,generic,go,helm,maven,npm,nuget,pub,pypi,rpm,alt,rubygems,swift,vagrant)"`
KeepCount int `binding:"In(0,1,5,10,25,50,100)"`
KeepPattern string `binding:"RegexPattern"`
RemoveDays int `binding:"In(0,7,14,30,60,90,180)"`
diff --git a/services/forms/repo_branch_form.go b/services/forms/repo_branch_form.go
index 42e6c85c37..c34e7c6d17 100644
--- a/services/forms/repo_branch_form.go
+++ b/services/forms/repo_branch_form.go
@@ -6,10 +6,10 @@ package forms
import (
"net/http"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// NewBranchForm form for creating a new branch
diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go
index 0fd8965df9..c39c6a7b36 100644
--- a/services/forms/repo_form.go
+++ b/services/forms/repo_form.go
@@ -6,26 +6,28 @@
package forms
import (
+ "fmt"
"net/http"
"net/url"
+ "regexp"
"strings"
- "code.gitea.io/gitea/models"
- issues_model "code.gitea.io/gitea/models/issues"
- project_model "code.gitea.io/gitea/models/project"
- webhook_model "code.gitea.io/gitea/models/webhook"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/models"
+ issues_model "forgejo.org/models/issues"
+ project_model "forgejo.org/models/project"
+ webhook_model "forgejo.org/models/webhook"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// CreateRepoForm form for creating repository
type CreateRepoForm struct {
UID int64 `binding:"Required"`
- RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)"`
+ RepoName string `binding:"Required;AlphaDashDot;MaxSize(100)" preprocess:"TrimSpace"`
Private bool
Description string `binding:"MaxSize(2048)"`
DefaultBranch string `binding:"GitRefName;MaxSize(100)"`
@@ -88,6 +90,9 @@ func (f *MigrateRepoForm) Validate(req *http.Request, errs binding.Errors) bindi
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
}
+// scpRegex matches the SCP-like addresses used by Git to access repositories over SSH.
+var scpRegex = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`)
+
// ParseRemoteAddr checks if given remote address is valid,
// and returns composed URL with needed username and password.
func ParseRemoteAddr(remoteAddr, authUsername, authPassword string) (string, error) {
@@ -103,7 +108,15 @@ func ParseRemoteAddr(remoteAddr, authUsername, authPassword string) (string, err
if len(authUsername)+len(authPassword) > 0 {
u.User = url.UserPassword(authUsername, authPassword)
}
- remoteAddr = u.String()
+ return u.String(), nil
+ }
+
+ // Detect SCP-like remote addresses and return host.
+ if m := scpRegex.FindStringSubmatch(remoteAddr); m != nil {
+ // Match SCP-like syntax and convert it to a URL.
+ // Eg, "git@forgejo.org:user/repo" becomes
+ // "ssh://git@forgejo.org/user/repo".
+ return fmt.Sprintf("ssh://%s@%s/%s", url.User(m[1]), m[2], m[3]), nil
}
return remoteAddr, nil
@@ -127,6 +140,7 @@ type RepoSettingForm struct {
PushMirrorPassword string
PushMirrorSyncOnCommit bool
PushMirrorInterval string
+ PushMirrorUseSSH bool
Private bool
Template bool
EnablePrune bool
@@ -174,7 +188,8 @@ type RepoUnitSettingForm struct {
PullsAllowSquash bool
PullsAllowFastForwardOnly bool
PullsAllowManualMerge bool
- PullsDefaultMergeStyle string
+ PullsDefaultMergeStyle string `binding:"In(merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged,rebase-update-only)"`
+ PullsDefaultUpdateStyle string `binding:"In(merge,rebase)"`
EnableAutodetectManualMerge bool
PullsAllowRebaseUpdate bool
DefaultDeleteBranchAfterMerge bool
@@ -429,7 +444,7 @@ func (f *InitializeLabelsForm) Validate(req *http.Request, errs binding.Errors)
// swagger:model MergePullRequestOption
type MergePullRequestForm struct {
// required: true
- // enum: merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged
+ // enum: ["merge", "rebase", "rebase-merge", "squash", "fast-forward-only", "manually-merged"]
Do string `binding:"Required;In(merge,rebase,rebase-merge,squash,fast-forward-only,manually-merged)"`
MergeTitleField string
MergeMessageField string
@@ -725,13 +740,6 @@ type SaveTopicForm struct {
Topics []string `binding:"topics;Required;"`
}
-// DeadlineForm hold the validation rules for deadlines
-type DeadlineForm struct {
- DateString string `form:"date" binding:"Required;Size(10)"`
-}
-
-// Validate validates the fields
-func (f *DeadlineForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
- ctx := context.GetValidateContext(req)
- return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
+type CommitNotesForm struct {
+ Notes string
}
diff --git a/services/forms/repo_form_test.go b/services/forms/repo_form_test.go
index 2c5a8e2c0f..4047762096 100644
--- a/services/forms/repo_form_test.go
+++ b/services/forms/repo_form_test.go
@@ -6,7 +6,7 @@ package forms
import (
"testing"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
)
diff --git a/services/forms/repo_tag_form.go b/services/forms/repo_tag_form.go
index 0135684737..1254c84d07 100644
--- a/services/forms/repo_tag_form.go
+++ b/services/forms/repo_tag_form.go
@@ -6,10 +6,10 @@ package forms
import (
"net/http"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// ProtectTagForm form for changing protected tag settings
diff --git a/services/forms/runner.go b/services/forms/runner.go
index 6abfc66fc2..fcf6c5a694 100644
--- a/services/forms/runner.go
+++ b/services/forms/runner.go
@@ -6,10 +6,10 @@ package forms
import (
"net/http"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// EditRunnerForm form for admin to create runner
diff --git a/services/forms/user_form.go b/services/forms/user_form.go
index cc93b27e2a..dfd5b3da9b 100644
--- a/services/forms/user_form.go
+++ b/services/forms/user_form.go
@@ -9,14 +9,14 @@ import (
"net/http"
"strings"
- auth_model "code.gitea.io/gitea/models/auth"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/validation"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// InstallForm form for installation page
@@ -110,7 +110,7 @@ func (f *RegisterForm) Validate(req *http.Request, errs binding.Errors) binding.
// domains in the whitelist or if it doesn't match any of
// domains in the blocklist, if any such list is not empty.
func (f *RegisterForm) IsEmailDomainAllowed() bool {
- return user_model.IsEmailDomainAllowed(f.Email)
+ return validation.IsEmailDomainAllowed(f.Email)
}
// MustChangePasswordForm form for updating your password after account creation
@@ -224,6 +224,7 @@ type UpdateProfileForm struct {
Biography string `binding:"MaxSize(255)"`
Visibility structs.VisibleType
KeepActivityPrivate bool
+ KeepPronounsPrivate bool
}
// Validate validates the fields
@@ -258,7 +259,7 @@ const (
type AvatarForm struct {
Source string
Avatar *multipart.FileHeader
- Gravatar string `binding:"OmitEmpty;Email;MaxSize(254)"`
+ Gravatar string `binding:"OmitEmpty;EmailWithAllowedDomain;MaxSize(254)"`
Federavatar bool
}
@@ -270,7 +271,7 @@ func (f *AvatarForm) Validate(req *http.Request, errs binding.Errors) binding.Er
// AddEmailForm form for adding new email
type AddEmailForm struct {
- Email string `binding:"Required;Email;MaxSize(254)"`
+ Email string `binding:"Required;EmailWithAllowedDomain;MaxSize(254)"`
}
// Validate validates the fields
@@ -290,7 +291,7 @@ func (f *UpdateThemeForm) Validate(req *http.Request, errs binding.Errors) bindi
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
}
-// IsThemeExists checks if the theme is a theme available in the config.
+// IsThemeExists checks if the theme is available in the config.
func (f UpdateThemeForm) IsThemeExists() bool {
var exists bool
@@ -388,7 +389,7 @@ func (f *NewAccessTokenForm) GetScope() (auth_model.AccessTokenScope, error) {
// EditOAuth2ApplicationForm form for editing oauth2 applications
type EditOAuth2ApplicationForm struct {
Name string `binding:"Required;MaxSize(255)" form:"application_name"`
- RedirectURIs string `binding:"Required" form:"redirect_uris"`
+ RedirectURIs string `binding:"Required;ValidUrlList" form:"redirect_uris"`
ConfidentialClient bool `form:"confidential_client"`
}
diff --git a/services/forms/user_form_auth_openid.go b/services/forms/user_form_auth_openid.go
index ca1c77e320..02d4f873bc 100644
--- a/services/forms/user_form_auth_openid.go
+++ b/services/forms/user_form_auth_openid.go
@@ -6,10 +6,10 @@ package forms
import (
"net/http"
- "code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/services/context"
+ "forgejo.org/modules/web/middleware"
+ "forgejo.org/services/context"
- "gitea.com/go-chi/binding"
+ "code.forgejo.org/go-chi/binding"
)
// SignInOpenIDForm form for signing in with OpenID
@@ -27,7 +27,7 @@ func (f *SignInOpenIDForm) Validate(req *http.Request, errs binding.Errors) bind
// SignUpOpenIDForm form for signin up with OpenID
type SignUpOpenIDForm struct {
UserName string `binding:"Required;Username;MaxSize(40)"`
- Email string `binding:"Required;Email;MaxSize(254)"`
+ Email string `binding:"Required;EmailWithAllowedDomain;MaxSize(254)"`
}
// Validate validates the fields
diff --git a/services/forms/user_form_hidden_comments.go b/services/forms/user_form_hidden_comments.go
index b9677c1800..74a1aaccb0 100644
--- a/services/forms/user_form_hidden_comments.go
+++ b/services/forms/user_form_hidden_comments.go
@@ -6,9 +6,9 @@ package forms
import (
"math/big"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/services/context"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/log"
+ "forgejo.org/services/context"
)
type hiddenCommentTypeGroupsType map[string][]issues_model.CommentType
diff --git a/services/forms/user_form_test.go b/services/forms/user_form_test.go
index 66050187c9..67fb64cabf 100644
--- a/services/forms/user_form_test.go
+++ b/services/forms/user_form_test.go
@@ -7,8 +7,8 @@ import (
"strconv"
"testing"
- auth_model "code.gitea.io/gitea/models/auth"
- "code.gitea.io/gitea/modules/setting"
+ auth_model "forgejo.org/models/auth"
+ "forgejo.org/modules/setting"
"github.com/gobwas/glob"
"github.com/stretchr/testify/assert"
diff --git a/services/gitdiff/csv_test.go b/services/gitdiff/csv_test.go
index c006a7c2bd..9bffba33fd 100644
--- a/services/gitdiff/csv_test.go
+++ b/services/gitdiff/csv_test.go
@@ -8,11 +8,12 @@ import (
"strings"
"testing"
- "code.gitea.io/gitea/models/db"
- csv_module "code.gitea.io/gitea/modules/csv"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ csv_module "forgejo.org/modules/csv"
+ "forgejo.org/modules/setting"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCSVDiff(t *testing.T) {
@@ -212,7 +213,7 @@ c,d,e`,
}
result, err := CreateCsvDiff(diff.Files[0], baseReader, headReader)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, result, 1, "case %d: should be one section", n)
section := result[0]
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go
index e6cae04db4..2e1fecda2a 100644
--- a/services/gitdiff/gitdiff.go
+++ b/services/gitdiff/gitdiff.go
@@ -17,19 +17,19 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models/db"
- git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
- pull_model "code.gitea.io/gitea/models/pull"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/analyze"
- "code.gitea.io/gitea/modules/charset"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/highlight"
- "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/models/db"
+ git_model "forgejo.org/models/git"
+ issues_model "forgejo.org/models/issues"
+ pull_model "forgejo.org/models/pull"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/analyze"
+ "forgejo.org/modules/charset"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/highlight"
+ "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
"github.com/sergi/go-diff/diffmatchpatch"
stdcharset "golang.org/x/net/html/charset"
@@ -337,7 +337,7 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine, loc
return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content, locale)
}
- hcd := newHighlightCodeDiff()
+ hcd := NewHighlightCodeDiff()
diffRecord := hcd.diffWithHighlight(diffSection.FileName, language, diff1[1:], diff2[1:])
// it seems that Gitea doesn't need the line wrapper of Chroma, so do not add them back
// if the line wrappers are still needed in the future, it can be added back by "diffToHTML(hcd.lineWrapperTags. ...)"
@@ -379,18 +379,11 @@ func (diffFile *DiffFile) GetType() int {
}
// GetTailSection creates a fake DiffLineSection if the last section is not the end of the file
-func (diffFile *DiffFile) GetTailSection(gitRepo *git.Repository, leftCommitID, rightCommitID string) *DiffSection {
+func (diffFile *DiffFile) GetTailSection(gitRepo *git.Repository, leftCommit, rightCommit *git.Commit) *DiffSection {
if len(diffFile.Sections) == 0 || diffFile.Type != DiffFileChange || diffFile.IsBin || diffFile.IsLFSFile {
return nil
}
- leftCommit, err := gitRepo.GetCommit(leftCommitID)
- if err != nil {
- return nil
- }
- rightCommit, err := gitRepo.GetCommit(rightCommitID)
- if err != nil {
- return nil
- }
+
lastSection := diffFile.Sections[len(diffFile.Sections)-1]
lastLine := lastSection.Lines[len(lastSection.Lines)-1]
leftLineCount := getCommitFileLineCount(leftCommit, diffFile.Name)
@@ -532,11 +525,6 @@ parsingLoop:
lastFile := createDiffFile(diff, line)
diff.End = lastFile.Name
diff.IsIncomplete = true
- _, err := io.Copy(io.Discard, reader)
- if err != nil {
- // By the definition of io.Copy this never returns io.EOF
- return diff, fmt.Errorf("error during io.Copy: %w", err)
- }
break parsingLoop
}
@@ -1097,6 +1085,7 @@ type DiffOptions struct {
MaxFiles int
WhitespaceBehavior git.TrustedCmdArgs
DirectComparison bool
+ FileOnly bool
}
// GetDiff builds a Diff between two commits of a repository.
@@ -1105,12 +1094,16 @@ type DiffOptions struct {
func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, files ...string) (*Diff, error) {
repoPath := gitRepo.Path
+ var beforeCommit *git.Commit
commit, err := gitRepo.GetCommit(opts.AfterCommitID)
if err != nil {
return nil, err
}
- cmdDiff := git.NewCommand(gitRepo.Ctx)
+ cmdCtx, cmdCancel := context.WithCancel(ctx)
+ defer cmdCancel()
+
+ cmdDiff := git.NewCommand(cmdCtx)
objectFormat, err := gitRepo.GetObjectFormat()
if err != nil {
return nil, err
@@ -1124,7 +1117,10 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi
} else {
actualBeforeCommitID := opts.BeforeCommitID
if len(actualBeforeCommitID) == 0 {
- parentCommit, _ := commit.Parent(0)
+ parentCommit, err := commit.Parent(0)
+ if err != nil {
+ return nil, err
+ }
actualBeforeCommitID = parentCommit.ID.String()
}
@@ -1132,6 +1128,11 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi
AddArguments(opts.WhitespaceBehavior...).
AddDynamicArguments(actualBeforeCommitID, opts.AfterCommitID)
opts.BeforeCommitID = actualBeforeCommitID
+
+ beforeCommit, err = gitRepo.GetCommit(opts.BeforeCommitID)
+ if err != nil {
+ return nil, err
+ }
}
// In git 2.31, git diff learned --skip-to which we can use to shortcut skip to file
@@ -1159,14 +1160,16 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi
Dir: repoPath,
Stdout: writer,
Stderr: stderr,
- }); err != nil {
+ }); err != nil && !git.IsErrCanceledOrKilled(err) {
log.Error("error during GetDiff(git diff dir: %s): %v, stderr: %s", repoPath, err, stderr.String())
}
_ = writer.Close()
}()
- diff, err := ParsePatch(ctx, opts.MaxLines, opts.MaxLineCharacters, opts.MaxFiles, reader, parsePatchSkipToFile)
+ diff, err := ParsePatch(cmdCtx, opts.MaxLines, opts.MaxLineCharacters, opts.MaxFiles, reader, parsePatchSkipToFile)
+ // Ensure the git process is killed if it didn't exit already
+ cmdCancel()
if err != nil {
return nil, fmt.Errorf("unable to ParsePatch: %w", err)
}
@@ -1207,37 +1210,28 @@ func GetDiff(ctx context.Context, gitRepo *git.Repository, opts *DiffOptions, fi
diffFile.IsGenerated = analyze.IsGenerated(diffFile.Name)
}
- tailSection := diffFile.GetTailSection(gitRepo, opts.BeforeCommitID, opts.AfterCommitID)
+ tailSection := diffFile.GetTailSection(gitRepo, beforeCommit, commit)
if tailSection != nil {
diffFile.Sections = append(diffFile.Sections, tailSection)
}
}
- separator := "..."
- if opts.DirectComparison {
- separator = ".."
+ if opts.FileOnly {
+ return diff, nil
}
- diffPaths := []string{opts.BeforeCommitID + separator + opts.AfterCommitID}
- if len(opts.BeforeCommitID) == 0 || opts.BeforeCommitID == objectFormat.EmptyObjectID().String() {
- diffPaths = []string{objectFormat.EmptyTree().String(), opts.AfterCommitID}
- }
- diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
- if err != nil && strings.Contains(err.Error(), "no merge base") {
- // git >= 2.28 now returns an error if base and head have become unrelated.
- // previously it would return the results of git diff --shortstat base head so let's try that...
- diffPaths = []string{opts.BeforeCommitID, opts.AfterCommitID}
- diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
- }
+ stats, err := GetPullDiffStats(gitRepo, opts)
if err != nil {
return nil, err
}
+ diff.NumFiles, diff.TotalAddition, diff.TotalDeletion = stats.NumFiles, stats.TotalAddition, stats.TotalDeletion
+
return diff, nil
}
type PullDiffStats struct {
- TotalAddition, TotalDeletion int
+ NumFiles, TotalAddition, TotalDeletion int
}
// GetPullDiffStats
@@ -1261,12 +1255,12 @@ func GetPullDiffStats(gitRepo *git.Repository, opts *DiffOptions) (*PullDiffStat
diffPaths = []string{objectFormat.EmptyTree().String(), opts.AfterCommitID}
}
- _, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
+ diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
if err != nil && strings.Contains(err.Error(), "no merge base") {
// git >= 2.28 now returns an error if base and head have become unrelated.
// previously it would return the results of git diff --shortstat base head so let's try that...
diffPaths = []string{opts.BeforeCommitID, opts.AfterCommitID}
- _, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
+ diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(gitRepo.Ctx, repoPath, nil, diffPaths...)
}
if err != nil {
return nil, err
@@ -1387,10 +1381,8 @@ func GetWhitespaceFlag(whitespaceBehavior string) git.TrustedCmdArgs {
"ignore-eol": {"--ignore-space-at-eol"},
"show-all": nil,
}
-
if flag, ok := whitespaceFlags[whitespaceBehavior]; ok {
return flag
}
- log.Warn("unknown whitespace behavior: %q, default to 'show-all'", whitespaceBehavior)
return nil
}
diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go
index 8d6c376dce..532255fe84 100644
--- a/services/gitdiff/gitdiff_test.go
+++ b/services/gitdiff/gitdiff_test.go
@@ -5,21 +5,21 @@
package gitdiff
import (
- "fmt"
"strconv"
"strings"
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/setting"
dmp "github.com/sergi/go-diff/diffmatchpatch"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestDiffToHTML(t *testing.T) {
@@ -595,22 +595,22 @@ func setupDefaultDiff() *Diff {
}
func TestDiff_LoadCommentsNoOutdated(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
diff := setupDefaultDiff()
- assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user, false))
+ require.NoError(t, diff.LoadComments(db.DefaultContext, issue, user, false))
assert.Len(t, diff.Files[0].Sections[0].Lines[0].Conversations, 2)
}
func TestDiff_LoadCommentsWithOutdated(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
diff := setupDefaultDiff()
- assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user, true))
+ require.NoError(t, diff.LoadComments(db.DefaultContext, issue, user, true))
assert.Len(t, diff.Files[0].Sections[0].Lines[0].Conversations, 2)
assert.Len(t, diff.Files[0].Sections[0].Lines[0].Conversations[0], 2)
assert.Len(t, diff.Files[0].Sections[0].Lines[0].Conversations[1], 1)
@@ -631,9 +631,8 @@ func TestDiffLine_GetCommentSide(t *testing.T) {
func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
gitRepo, err := git.OpenRepository(git.DefaultContext, "./testdata/academic-module")
- if !assert.NoError(t, err) {
- return
- }
+ require.NoError(t, err)
+
defer gitRepo.Close()
for _, behavior := range []git.TrustedCmdArgs{{"-w"}, {"--ignore-space-at-eol"}, {"-b"}, nil} {
diffs, err := GetDiff(db.DefaultContext, gitRepo,
@@ -645,9 +644,9 @@ func TestGetDiffRangeWithWhitespaceBehavior(t *testing.T) {
MaxFiles: setting.Git.MaxGitDiffFiles,
WhitespaceBehavior: behavior,
})
- assert.NoError(t, err, fmt.Sprintf("Error when diff with %s", behavior))
+ require.NoError(t, err, "Error when diff with %s", behavior)
for _, f := range diffs.Files {
- assert.True(t, len(f.Sections) > 0, fmt.Sprintf("%s should have sections", f.Name))
+ assert.NotEmpty(t, f.Sections, "%s should have sections", f.Name)
}
}
}
diff --git a/services/gitdiff/highlightdiff.go b/services/gitdiff/highlightdiff.go
index 35d4844550..08681b8617 100644
--- a/services/gitdiff/highlightdiff.go
+++ b/services/gitdiff/highlightdiff.go
@@ -6,7 +6,7 @@ package gitdiff
import (
"strings"
- "code.gitea.io/gitea/modules/highlight"
+ "forgejo.org/modules/highlight"
"github.com/sergi/go-diff/diffmatchpatch"
)
@@ -31,17 +31,17 @@ func extractHTMLToken(s string) (before, token, after string, valid bool) {
return "", "", s, true
}
-// highlightCodeDiff is used to do diff with highlighted HTML code.
+// HighlightCodeDiff is used to do diff with highlighted HTML code.
// It totally depends on Chroma's valid HTML output and its structure, do not use these functions for other purposes.
// The HTML tags and entities will be replaced by Unicode placeholders: "{TEXT} " => "\uE000{TEXT}\uE001"
// These Unicode placeholders are friendly to the diff.
// Then after diff, the placeholders in diff result will be recovered to the HTML tags and entities.
// It's guaranteed that the tags in final diff result are paired correctly.
-type highlightCodeDiff struct {
+type HighlightCodeDiff struct {
placeholderBegin rune
placeholderMaxCount int
placeholderIndex int
- placeholderTokenMap map[rune]string
+ PlaceholderTokenMap map[rune]string
tokenPlaceholderMap map[string]rune
placeholderOverflowCount int
@@ -49,54 +49,55 @@ type highlightCodeDiff struct {
lineWrapperTags []string
}
-func newHighlightCodeDiff() *highlightCodeDiff {
- return &highlightCodeDiff{
+func NewHighlightCodeDiff() *HighlightCodeDiff {
+ return &HighlightCodeDiff{
placeholderBegin: rune(0x100000), // Plane 16: Supplementary Private Use Area B (U+100000..U+10FFFD)
placeholderMaxCount: 64000,
- placeholderTokenMap: map[rune]string{},
+ PlaceholderTokenMap: map[rune]string{},
tokenPlaceholderMap: map[string]rune{},
}
}
-// nextPlaceholder returns 0 if no more placeholder can be used
+// NextPlaceholder returns 0 if no more placeholder can be used
// the diff is done line by line, usually there are only a few (no more than 10) placeholders in one line
// so the placeholderMaxCount is impossible to be exhausted in real cases.
-func (hcd *highlightCodeDiff) nextPlaceholder() rune {
+func (hcd *HighlightCodeDiff) NextPlaceholder() rune {
for hcd.placeholderIndex < hcd.placeholderMaxCount {
r := hcd.placeholderBegin + rune(hcd.placeholderIndex)
hcd.placeholderIndex++
// only use non-existing (not used by code) rune as placeholders
- if _, ok := hcd.placeholderTokenMap[r]; !ok {
+ if _, ok := hcd.PlaceholderTokenMap[r]; !ok {
return r
}
}
return 0 // no more available placeholder
}
-func (hcd *highlightCodeDiff) isInPlaceholderRange(r rune) bool {
+func (hcd *HighlightCodeDiff) isInPlaceholderRange(r rune) bool {
return hcd.placeholderBegin <= r && r < hcd.placeholderBegin+rune(hcd.placeholderMaxCount)
}
-func (hcd *highlightCodeDiff) collectUsedRunes(code string) {
+func (hcd *HighlightCodeDiff) CollectUsedRunes(code string) {
for _, r := range code {
if hcd.isInPlaceholderRange(r) {
// put the existing rune (used by code) in map, then this rune won't be used a placeholder anymore.
- hcd.placeholderTokenMap[r] = ""
+ hcd.PlaceholderTokenMap[r] = ""
}
}
}
-func (hcd *highlightCodeDiff) diffWithHighlight(filename, language, codeA, codeB string) []diffmatchpatch.Diff {
- hcd.collectUsedRunes(codeA)
- hcd.collectUsedRunes(codeB)
+func (hcd *HighlightCodeDiff) diffWithHighlight(filename, language, codeA, codeB string) []diffmatchpatch.Diff {
+ hcd.CollectUsedRunes(codeA)
+ hcd.CollectUsedRunes(codeB)
highlightCodeA, _ := highlight.Code(filename, language, codeA)
highlightCodeB, _ := highlight.Code(filename, language, codeB)
- convertedCodeA := hcd.convertToPlaceholders(string(highlightCodeA))
- convertedCodeB := hcd.convertToPlaceholders(string(highlightCodeB))
+ convertedCodeA := hcd.ConvertToPlaceholders(string(highlightCodeA))
+ convertedCodeB := hcd.ConvertToPlaceholders(string(highlightCodeB))
diffs := diffMatchPatch.DiffMain(convertedCodeA, convertedCodeB, true)
+ diffs = diffMatchPatch.DiffCleanupSemantic(diffs)
diffs = diffMatchPatch.DiffCleanupEfficiency(diffs)
for i := range diffs {
@@ -106,7 +107,7 @@ func (hcd *highlightCodeDiff) diffWithHighlight(filename, language, codeA, codeB
}
// convertToPlaceholders totally depends on Chroma's valid HTML output and its structure, do not use these functions for other purposes.
-func (hcd *highlightCodeDiff) convertToPlaceholders(htmlCode string) string {
+func (hcd *HighlightCodeDiff) ConvertToPlaceholders(htmlCode string) string {
var tagStack []string
res := strings.Builder{}
@@ -153,10 +154,10 @@ func (hcd *highlightCodeDiff) convertToPlaceholders(htmlCode string) string {
// remember the placeholder and token in the map
placeholder, ok := hcd.tokenPlaceholderMap[tokenInMap]
if !ok {
- placeholder = hcd.nextPlaceholder()
+ placeholder = hcd.NextPlaceholder()
if placeholder != 0 {
hcd.tokenPlaceholderMap[tokenInMap] = placeholder
- hcd.placeholderTokenMap[placeholder] = tokenInMap
+ hcd.PlaceholderTokenMap[placeholder] = tokenInMap
}
}
@@ -179,12 +180,16 @@ func (hcd *highlightCodeDiff) convertToPlaceholders(htmlCode string) string {
return res.String()
}
-func (hcd *highlightCodeDiff) recoverOneDiff(diff *diffmatchpatch.Diff) {
+func (hcd *HighlightCodeDiff) recoverOneDiff(diff *diffmatchpatch.Diff) {
+ diff.Text = hcd.Recover(diff.Text)
+}
+
+func (hcd *HighlightCodeDiff) Recover(src string) string {
sb := strings.Builder{}
var tagStack []string
- for _, r := range diff.Text {
- token, ok := hcd.placeholderTokenMap[r]
+ for _, r := range src {
+ token, ok := hcd.PlaceholderTokenMap[r]
if !ok || token == "" {
sb.WriteRune(r) // if the rune is not a placeholder, write it as it is
continue
@@ -218,5 +223,5 @@ func (hcd *highlightCodeDiff) recoverOneDiff(diff *diffmatchpatch.Diff) {
}
}
- diff.Text = sb.String()
+ return sb.String()
}
diff --git a/services/gitdiff/highlightdiff_test.go b/services/gitdiff/highlightdiff_test.go
index 545a060e20..2ff4472bcc 100644
--- a/services/gitdiff/highlightdiff_test.go
+++ b/services/gitdiff/highlightdiff_test.go
@@ -13,7 +13,7 @@ import (
)
func TestDiffWithHighlight(t *testing.T) {
- hcd := newHighlightCodeDiff()
+ hcd := NewHighlightCodeDiff()
diffs := hcd.diffWithHighlight(
"main.v", "",
" run('<>')\n",
@@ -28,9 +28,9 @@ func TestDiffWithHighlight(t *testing.T) {
output = diffToHTML(nil, diffs, DiffLineAdd)
assert.Equal(t, expected, output)
- hcd = newHighlightCodeDiff()
- hcd.placeholderTokenMap['O'] = ""
- hcd.placeholderTokenMap['C'] = " "
+ hcd = NewHighlightCodeDiff()
+ hcd.PlaceholderTokenMap['O'] = ""
+ hcd.PlaceholderTokenMap['C'] = " "
diff := diffmatchpatch.Diff{}
diff.Text = "OC"
@@ -47,20 +47,20 @@ func TestDiffWithHighlight(t *testing.T) {
}
func TestDiffWithHighlightPlaceholder(t *testing.T) {
- hcd := newHighlightCodeDiff()
+ hcd := NewHighlightCodeDiff()
diffs := hcd.diffWithHighlight(
"main.js", "",
"a='\U00100000'",
"a='\U0010FFFD''",
)
- assert.Equal(t, "", hcd.placeholderTokenMap[0x00100000])
- assert.Equal(t, "", hcd.placeholderTokenMap[0x0010FFFD])
+ assert.Equal(t, "", hcd.PlaceholderTokenMap[0x00100000])
+ assert.Equal(t, "", hcd.PlaceholderTokenMap[0x0010FFFD])
expected := fmt.Sprintf(`a = ' %s '`, "\U00100000")
output := diffToHTML(hcd.lineWrapperTags, diffs, DiffLineDel)
assert.Equal(t, expected, output)
- hcd = newHighlightCodeDiff()
+ hcd = NewHighlightCodeDiff()
diffs = hcd.diffWithHighlight(
"main.js", "",
"a='\U00100000'",
@@ -72,7 +72,7 @@ func TestDiffWithHighlightPlaceholder(t *testing.T) {
}
func TestDiffWithHighlightPlaceholderExhausted(t *testing.T) {
- hcd := newHighlightCodeDiff()
+ hcd := NewHighlightCodeDiff()
hcd.placeholderMaxCount = 0
diffs := hcd.diffWithHighlight(
"main.js", "",
@@ -83,7 +83,7 @@ func TestDiffWithHighlightPlaceholderExhausted(t *testing.T) {
expected := fmt.Sprintf(`%s#39; `, "\uFFFD")
assert.Equal(t, expected, output)
- hcd = newHighlightCodeDiff()
+ hcd = NewHighlightCodeDiff()
hcd.placeholderMaxCount = 0
diffs = hcd.diffWithHighlight(
"main.js", "",
@@ -102,7 +102,7 @@ func TestDiffWithHighlightPlaceholderExhausted(t *testing.T) {
func TestDiffWithHighlightTagMatch(t *testing.T) {
totalOverflow := 0
for i := 0; i < 100; i++ {
- hcd := newHighlightCodeDiff()
+ hcd := NewHighlightCodeDiff()
hcd.placeholderMaxCount = i
diffs := hcd.diffWithHighlight(
"main.js", "",
diff --git a/services/gitdiff/main_test.go b/services/gitdiff/main_test.go
index cd9dcd8cd6..cd7a6a4a6b 100644
--- a/services/gitdiff/main_test.go
+++ b/services/gitdiff/main_test.go
@@ -6,11 +6,12 @@ package gitdiff
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
- _ "code.gitea.io/gitea/models"
- _ "code.gitea.io/gitea/models/actions"
- _ "code.gitea.io/gitea/models/activities"
+ _ "forgejo.org/models"
+ _ "forgejo.org/models/actions"
+ _ "forgejo.org/models/activities"
+ _ "forgejo.org/models/forgefed"
)
func TestMain(m *testing.M) {
diff --git a/services/indexer/indexer.go b/services/indexer/indexer.go
index 38dd012a51..92036f95c3 100644
--- a/services/indexer/indexer.go
+++ b/services/indexer/indexer.go
@@ -4,10 +4,10 @@
package indexer
import (
- code_indexer "code.gitea.io/gitea/modules/indexer/code"
- issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
- stats_indexer "code.gitea.io/gitea/modules/indexer/stats"
- notify_service "code.gitea.io/gitea/services/notify"
+ code_indexer "forgejo.org/modules/indexer/code"
+ issue_indexer "forgejo.org/modules/indexer/issues"
+ stats_indexer "forgejo.org/modules/indexer/stats"
+ notify_service "forgejo.org/services/notify"
)
// Init initialize the repo indexer
diff --git a/services/indexer/notify.go b/services/indexer/notify.go
index e2cfe477d3..ddd89f733c 100644
--- a/services/indexer/notify.go
+++ b/services/indexer/notify.go
@@ -6,16 +6,16 @@ package indexer
import (
"context"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- code_indexer "code.gitea.io/gitea/modules/indexer/code"
- issue_indexer "code.gitea.io/gitea/modules/indexer/issues"
- stats_indexer "code.gitea.io/gitea/modules/indexer/stats"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- notify_service "code.gitea.io/gitea/services/notify"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ code_indexer "forgejo.org/modules/indexer/code"
+ issue_indexer "forgejo.org/modules/indexer/issues"
+ stats_indexer "forgejo.org/modules/indexer/stats"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ notify_service "forgejo.org/services/notify"
)
type indexerNotifier struct {
diff --git a/services/issue/assignee.go b/services/issue/assignee.go
index 9c2ef74bb0..a5f9c2731f 100644
--- a/services/issue/assignee.go
+++ b/services/issue/assignee.go
@@ -6,15 +6,15 @@ package issue
import (
"context"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/organization"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- notify_service "code.gitea.io/gitea/services/notify"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/organization"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ notify_service "forgejo.org/services/notify"
)
// DeleteNotPassedAssignee deletes all assignees who aren't passed via the "assignees" array
@@ -72,7 +72,8 @@ func ReviewRequest(ctx context.Context, issue *issues_model.Issue, doer, reviewe
return nil, err
}
- if comment != nil {
+ // don't notify if the user is requesting itself as reviewer
+ if comment != nil && doer.ID != reviewer.ID {
notify_service.PullRequestReviewRequest(ctx, doer, issue, reviewer, isAdd, comment)
}
diff --git a/services/issue/assignee_test.go b/services/issue/assignee_test.go
index 38d56f9d9d..66a66459cb 100644
--- a/services/issue/assignee_test.go
+++ b/services/issue/assignee_test.go
@@ -6,42 +6,43 @@ package issue
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestDeleteNotPassedAssignee(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
// Fake issue with assignees
issue, err := issues_model.GetIssueByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = issue.LoadAttributes(db.DefaultContext)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, issue.Assignees, 1)
user1, err := user_model.GetUserByID(db.DefaultContext, 1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him
- assert.NoError(t, err)
+ require.NoError(t, err)
// Check if he got removed
isAssigned, err := issues_model.IsUserAssignedToIssue(db.DefaultContext, issue, user1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, isAssigned)
// Clean everyone
err = DeleteNotPassedAssignee(db.DefaultContext, issue, user1, []*user_model.User{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, issue.Assignees)
// Reload to check they're gone
issue.ResetAttributesLoaded()
- assert.NoError(t, issue.LoadAssignees(db.DefaultContext))
+ require.NoError(t, issue.LoadAssignees(db.DefaultContext))
assert.Empty(t, issue.Assignees)
assert.Empty(t, issue.Assignee)
}
diff --git a/services/issue/comments.go b/services/issue/comments.go
index d257c2612c..dedef6cc87 100644
--- a/services/issue/comments.go
+++ b/services/issue/comments.go
@@ -7,12 +7,12 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/timeutil"
- notify_service "code.gitea.io/gitea/services/notify"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/timeutil"
+ notify_service "forgejo.org/services/notify"
)
// CreateRefComment creates a commit reference comment to issue.
@@ -75,7 +75,12 @@ func CreateIssueComment(ctx context.Context, doer *user_model.User, repo *repo_m
// UpdateComment updates information of comment.
func UpdateComment(ctx context.Context, c *issues_model.Comment, contentVersion int, doer *user_model.User, oldContent string) error {
- needsContentHistory := c.Content != oldContent && c.Type.HasContentSupport()
+ if err := c.LoadReview(ctx); err != nil {
+ return err
+ }
+ isPartOfPendingReview := c.Review != nil && c.Review.Type == issues_model.ReviewTypePending
+
+ needsContentHistory := c.Content != oldContent && c.Type.HasContentSupport() && !isPartOfPendingReview
if needsContentHistory {
hasContentHistory, err := issues_model.HasIssueContentHistory(ctx, c.IssueID, c.ID)
if err != nil {
@@ -104,7 +109,9 @@ func UpdateComment(ctx context.Context, c *issues_model.Comment, contentVersion
}
}
- notify_service.UpdateComment(ctx, doer, c, oldContent)
+ if !isPartOfPendingReview {
+ notify_service.UpdateComment(ctx, doer, c, oldContent)
+ }
return nil
}
@@ -118,7 +125,12 @@ func DeleteComment(ctx context.Context, doer *user_model.User, comment *issues_m
return err
}
- notify_service.DeleteComment(ctx, doer, comment)
+ if err := comment.LoadReview(ctx); err != nil {
+ return err
+ }
+ if comment.Review == nil || comment.Review.Type != issues_model.ReviewTypePending {
+ notify_service.DeleteComment(ctx, doer, comment)
+ }
return nil
}
diff --git a/services/issue/comments_test.go b/services/issue/comments_test.go
new file mode 100644
index 0000000000..728af15529
--- /dev/null
+++ b/services/issue/comments_test.go
@@ -0,0 +1,147 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package issue_test
+
+import (
+ "testing"
+
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ webhook_model "forgejo.org/models/webhook"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
+ issue_service "forgejo.org/services/issue"
+ "forgejo.org/tests"
+
+ _ "forgejo.org/services/webhook"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestDeleteComment(t *testing.T) {
+ // Use the webhook notification to check if a notification is fired for an action.
+ defer test.MockVariableValue(&setting.DisableWebhooks, false)()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ t.Run("Normal comment", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
+ unittest.AssertCount(t, &issues_model.Reaction{CommentID: comment.ID}, 2)
+
+ require.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, &webhook_model.Webhook{
+ RepoID: issue.RepoID,
+ IsActive: true,
+ Events: `{"choose_events":true,"events":{"issue_comment": true}}`,
+ }))
+ hookTaskCount := unittest.GetCount(t, &webhook_model.HookTask{})
+
+ require.NoError(t, issue_service.DeleteComment(db.DefaultContext, nil, comment))
+
+ // The comment doesn't exist anymore.
+ unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID})
+ // Reactions don't exist anymore for this comment.
+ unittest.AssertNotExistsBean(t, &issues_model.Reaction{CommentID: comment.ID})
+ // Number of comments was decreased.
+ assert.EqualValues(t, issue.NumComments-1, unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).NumComments)
+ // A notification was fired for the deletion of this comment.
+ assert.EqualValues(t, hookTaskCount+1, unittest.GetCount(t, &webhook_model.HookTask{}))
+ })
+
+ t.Run("Comment of pending review", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ // We have to ensure that this comment's linked review is pending.
+ comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4}, "review_id != 0")
+ review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: comment.ReviewID})
+ assert.EqualValues(t, issues_model.ReviewTypePending, review.Type)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
+
+ require.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, &webhook_model.Webhook{
+ RepoID: issue.RepoID,
+ IsActive: true,
+ Events: `{"choose_events":true,"events":{"issue_comment": true}}`,
+ }))
+ hookTaskCount := unittest.GetCount(t, &webhook_model.HookTask{})
+
+ require.NoError(t, issue_service.DeleteComment(db.DefaultContext, nil, comment))
+
+ // The comment doesn't exist anymore.
+ unittest.AssertNotExistsBean(t, &issues_model.Comment{ID: comment.ID})
+ // Ensure that the number of comments wasn't decreased.
+ assert.EqualValues(t, issue.NumComments, unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).NumComments)
+ // No notification was fired for the deletion of this comment.
+ assert.EqualValues(t, hookTaskCount, unittest.GetCount(t, &webhook_model.HookTask{}))
+ })
+}
+
+func TestUpdateComment(t *testing.T) {
+ // Use the webhook notification to check if a notification is fired for an action.
+ defer test.MockVariableValue(&setting.DisableWebhooks, false)()
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{IsAdmin: true})
+ t.Run("Normal comment", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
+ unittest.AssertNotExistsBean(t, &issues_model.ContentHistory{CommentID: comment.ID})
+ require.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, &webhook_model.Webhook{
+ RepoID: issue.RepoID,
+ IsActive: true,
+ Events: `{"choose_events":true,"events":{"issue_comment": true}}`,
+ }))
+ hookTaskCount := unittest.GetCount(t, &webhook_model.HookTask{})
+ oldContent := comment.Content
+ comment.Content = "Hello!"
+
+ require.NoError(t, issue_service.UpdateComment(db.DefaultContext, comment, 1, admin, oldContent))
+
+ newComment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
+ // Content was updated.
+ assert.EqualValues(t, comment.Content, newComment.Content)
+ // Content version was updated.
+ assert.EqualValues(t, 2, newComment.ContentVersion)
+ // A notification was fired for the update of this comment.
+ assert.EqualValues(t, hookTaskCount+1, unittest.GetCount(t, &webhook_model.HookTask{}))
+ // Issue history was saved for this comment.
+ unittest.AssertExistsAndLoadBean(t, &issues_model.ContentHistory{CommentID: comment.ID, IsFirstCreated: true, ContentText: oldContent})
+ unittest.AssertExistsAndLoadBean(t, &issues_model.ContentHistory{CommentID: comment.ID, ContentText: comment.Content}, "is_first_created = false")
+ })
+
+ t.Run("Comment of pending review", func(t *testing.T) {
+ defer tests.PrintCurrentTest(t)()
+
+ comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4}, "review_id != 0")
+ review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: comment.ReviewID})
+ assert.EqualValues(t, issues_model.ReviewTypePending, review.Type)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
+ unittest.AssertNotExistsBean(t, &issues_model.ContentHistory{CommentID: comment.ID})
+ require.NoError(t, webhook_model.CreateWebhook(db.DefaultContext, &webhook_model.Webhook{
+ RepoID: issue.RepoID,
+ IsActive: true,
+ Events: `{"choose_events":true,"events":{"issue_comment": true}}`,
+ }))
+ hookTaskCount := unittest.GetCount(t, &webhook_model.HookTask{})
+ oldContent := comment.Content
+ comment.Content = "Hello!"
+
+ require.NoError(t, issue_service.UpdateComment(db.DefaultContext, comment, 1, admin, oldContent))
+
+ newComment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
+ // Content was updated.
+ assert.EqualValues(t, comment.Content, newComment.Content)
+ // Content version was updated.
+ assert.EqualValues(t, 2, newComment.ContentVersion)
+ // No notification was fired for the update of this comment.
+ assert.EqualValues(t, hookTaskCount, unittest.GetCount(t, &webhook_model.HookTask{}))
+ // Issue history was not saved for this comment.
+ unittest.AssertNotExistsBean(t, &issues_model.ContentHistory{CommentID: comment.ID})
+ })
+}
diff --git a/services/issue/commit.go b/services/issue/commit.go
index 8b927d52b6..1e51fb32b7 100644
--- a/services/issue/commit.go
+++ b/services/issue/commit.go
@@ -13,15 +13,15 @@ import (
"strings"
"time"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/references"
- "code.gitea.io/gitea/modules/repository"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/references"
+ "forgejo.org/modules/repository"
)
const (
diff --git a/services/issue/commit_test.go b/services/issue/commit_test.go
index 0518803683..e3a41d2305 100644
--- a/services/issue/commit_test.go
+++ b/services/issue/commit_test.go
@@ -6,20 +6,20 @@ package issue
import (
"testing"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestUpdateIssuesCommit(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef1",
@@ -61,7 +61,7 @@ func TestUpdateIssuesCommit(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
+ require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
@@ -88,7 +88,7 @@ func TestUpdateIssuesCommit(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch"))
+ require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch"))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
@@ -114,14 +114,14 @@ func TestUpdateIssuesCommit(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 1}, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
+ require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_Colon(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
pushCommits := []*repository.PushCommit{
{
Sha1: "abcdef2",
@@ -140,13 +140,13 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) {
issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4}
unittest.AssertNotExistsBean(t, &issues_model.Issue{RepoID: repo.ID, Index: 2}, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
+ require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that push to a non-default branch closes an issue.
@@ -173,14 +173,14 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch"))
+ require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, "non-existing-branch"))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that a push to default branch closes issue in another repo
@@ -208,14 +208,14 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
+ require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that a push to default branch closes issue in another repo
@@ -243,14 +243,14 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
+ require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertExistsAndLoadBean(t, commentBean)
unittest.AssertExistsAndLoadBean(t, issueBean, "is_closed=1")
unittest.CheckConsistencyFor(t, &activities_model.Action{})
}
func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10})
// Test that a push with close reference *can not* close issue
@@ -293,7 +293,7 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, commentBean2)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
- assert.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
+ require.NoError(t, UpdateIssuesCommit(db.DefaultContext, user, repo, pushCommits, repo.DefaultBranch))
unittest.AssertNotExistsBean(t, commentBean)
unittest.AssertNotExistsBean(t, commentBean2)
unittest.AssertNotExistsBean(t, issueBean, "is_closed=1")
diff --git a/services/issue/content.go b/services/issue/content.go
index 612a9a6b4c..d5c79e5fde 100644
--- a/services/issue/content.go
+++ b/services/issue/content.go
@@ -6,9 +6,9 @@ package issue
import (
"context"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- notify_service "code.gitea.io/gitea/services/notify"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ notify_service "forgejo.org/services/notify"
)
// ChangeContent changes issue content, as the given user.
diff --git a/services/issue/issue.go b/services/issue/issue.go
index 5e726176d0..f6a3e90b10 100644
--- a/services/issue/issue.go
+++ b/services/issue/issue.go
@@ -8,19 +8,19 @@ import (
"fmt"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- project_model "code.gitea.io/gitea/models/project"
- repo_model "code.gitea.io/gitea/models/repo"
- system_model "code.gitea.io/gitea/models/system"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/timeutil"
- notify_service "code.gitea.io/gitea/services/notify"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ project_model "forgejo.org/models/project"
+ repo_model "forgejo.org/models/repo"
+ system_model "forgejo.org/models/system"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/timeutil"
+ notify_service "forgejo.org/services/notify"
)
// NewIssue creates new issue with labels for repository.
diff --git a/services/issue/issue_test.go b/services/issue/issue_test.go
index 8806cec0e7..e15a0118ad 100644
--- a/services/issue/issue_test.go
+++ b/services/issue/issue_test.go
@@ -6,13 +6,14 @@ package issue
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGetRefEndNamesAndURLs(t *testing.T) {
@@ -33,10 +34,10 @@ func TestGetRefEndNamesAndURLs(t *testing.T) {
}
func TestIssue_DeleteIssue(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issueIDs, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, issueIDs, 5)
issue := &issues_model.Issue{
@@ -45,42 +46,42 @@ func TestIssue_DeleteIssue(t *testing.T) {
}
err = deleteIssue(db.DefaultContext, issue)
- assert.NoError(t, err)
+ require.NoError(t, err)
issueIDs, err = issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, issueIDs, 4)
// check attachment removal
attachments, err := repo_model.GetAttachmentsByIssueID(db.DefaultContext, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue, err = issues_model.GetIssueByID(db.DefaultContext, 4)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = deleteIssue(db.DefaultContext, issue)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, attachments, 2)
for i := range attachments {
attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attachments[i].UUID)
- assert.Error(t, err)
+ require.Error(t, err)
assert.True(t, repo_model.IsErrAttachmentNotExist(err))
assert.Nil(t, attachment)
}
// check issue dependencies
user, err := user_model.GetUserByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue1, err := issues_model.GetIssueByID(db.DefaultContext, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
issue2, err := issues_model.GetIssueByID(db.DefaultContext, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = issues_model.CreateIssueDependency(db.DefaultContext, user, issue1, issue2)
- assert.NoError(t, err)
+ require.NoError(t, err)
left, err := issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, left)
err = deleteIssue(db.DefaultContext, issue2)
- assert.NoError(t, err)
+ require.NoError(t, err)
left, err = issues_model.IssueNoDependenciesLeft(db.DefaultContext, issue1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, left)
}
diff --git a/services/issue/label.go b/services/issue/label.go
index 6b8070d8aa..bcac54272a 100644
--- a/services/issue/label.go
+++ b/services/issue/label.go
@@ -6,11 +6,11 @@ package issue
import (
"context"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- user_model "code.gitea.io/gitea/models/user"
- notify_service "code.gitea.io/gitea/services/notify"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ user_model "forgejo.org/models/user"
+ notify_service "forgejo.org/services/notify"
)
// ClearLabels clears all of an issue's labels
diff --git a/services/issue/label_test.go b/services/issue/label_test.go
index 90608c9e26..73a028684b 100644
--- a/services/issue/label_test.go
+++ b/services/issue/label_test.go
@@ -6,12 +6,12 @@ package issue
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestIssue_AddLabels(t *testing.T) {
@@ -26,14 +26,14 @@ func TestIssue_AddLabels(t *testing.T) {
{2, []int64{}, 1}, // pull-request, empty
}
for _, test := range tests {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID})
labels := make([]*issues_model.Label, len(test.labelIDs))
for i, labelID := range test.labelIDs {
labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID})
}
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID})
- assert.NoError(t, AddLabels(db.DefaultContext, issue, doer, labels))
+ require.NoError(t, AddLabels(db.DefaultContext, issue, doer, labels))
for _, labelID := range test.labelIDs {
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: labelID})
}
@@ -52,11 +52,11 @@ func TestIssue_AddLabel(t *testing.T) {
{2, 1, 2}, // pull-request, already-added label
}
for _, test := range tests {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID})
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: test.labelID})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID})
- assert.NoError(t, AddLabel(db.DefaultContext, issue, doer, label))
+ require.NoError(t, AddLabel(db.DefaultContext, issue, doer, label))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: test.labelID})
}
}
diff --git a/services/issue/main_test.go b/services/issue/main_test.go
index 5dac54183b..673ec5e4cc 100644
--- a/services/issue/main_test.go
+++ b/services/issue/main_test.go
@@ -6,11 +6,18 @@ package issue
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/webhook"
- _ "code.gitea.io/gitea/models/actions"
+ _ "forgejo.org/models/actions"
)
func TestMain(m *testing.M) {
- unittest.MainTest(m)
+ unittest.MainTest(m, &unittest.TestOptions{
+ SetUp: func() error {
+ setting.LoadQueueSettings()
+ return webhook.Init()
+ },
+ })
}
diff --git a/services/issue/milestone.go b/services/issue/milestone.go
index 31490c7b03..3fa7083812 100644
--- a/services/issue/milestone.go
+++ b/services/issue/milestone.go
@@ -7,10 +7,10 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- notify_service "code.gitea.io/gitea/services/notify"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ notify_service "forgejo.org/services/notify"
)
func updateMilestoneCounters(ctx context.Context, issue *issues_model.Issue, id int64) error {
@@ -85,6 +85,10 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *is
}
}
+ if issue.MilestoneID == 0 {
+ issue.Milestone = nil
+ }
+
return nil
}
diff --git a/services/issue/milestone_test.go b/services/issue/milestone_test.go
index 42b910166f..4123433c2a 100644
--- a/services/issue/milestone_test.go
+++ b/services/issue/milestone_test.go
@@ -6,16 +6,17 @@ package issue
import (
"testing"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestChangeMilestoneAssign(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: 1})
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NotNil(t, issue)
@@ -23,7 +24,8 @@ func TestChangeMilestoneAssign(t *testing.T) {
oldMilestoneID := issue.MilestoneID
issue.MilestoneID = 2
- assert.NoError(t, ChangeMilestoneAssign(db.DefaultContext, issue, doer, oldMilestoneID))
+ require.NoError(t, issue.LoadMilestone(db.DefaultContext))
+ require.NoError(t, ChangeMilestoneAssign(db.DefaultContext, issue, doer, oldMilestoneID))
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{
IssueID: issue.ID,
Type: issues_model.CommentTypeMilestone,
@@ -31,4 +33,11 @@ func TestChangeMilestoneAssign(t *testing.T) {
OldMilestoneID: oldMilestoneID,
})
unittest.CheckConsistencyFor(t, &issues_model.Milestone{}, &issues_model.Issue{})
+ assert.NotNil(t, issue.Milestone)
+
+ oldMilestoneID = issue.MilestoneID
+ issue.MilestoneID = 0
+ require.NoError(t, ChangeMilestoneAssign(db.DefaultContext, issue, doer, oldMilestoneID))
+ assert.EqualValues(t, 0, issue.MilestoneID)
+ assert.Nil(t, issue.Milestone)
}
diff --git a/services/issue/pull.go b/services/issue/pull.go
index c5a12ce7c4..b0a0c47d88 100644
--- a/services/issue/pull.go
+++ b/services/issue/pull.go
@@ -8,13 +8,15 @@ import (
"fmt"
"time"
- issues_model "code.gitea.io/gitea/models/issues"
- org_model "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ issues_model "forgejo.org/models/issues"
+ org_model "forgejo.org/models/organization"
+ access_model "forgejo.org/models/perm/access"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
func getMergeBase(repo *git.Repository, pr *issues_model.PullRequest, baseBranch, headBranch string) (string, error) {
@@ -51,14 +53,14 @@ func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue,
return nil, err
}
- if pr.HeadRepo.IsFork {
- return nil, nil
- }
-
if err := pr.LoadBaseRepo(ctx); err != nil {
return nil, err
}
+ if pr.BaseRepo.IsFork {
+ return nil, nil
+ }
+
repo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil {
return nil, err
@@ -117,7 +119,11 @@ func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue,
}
for _, u := range uniqUsers {
- if u.ID != issue.Poster.ID {
+ permission, err := access_model.GetUserRepoPermission(ctx, issue.Repo, u)
+ if err != nil {
+ return nil, fmt.Errorf("GetUserRepoPermission: %w", err)
+ }
+ if u.ID != issue.Poster.ID && permission.CanRead(unit.TypePullRequests) {
comment, err := issues_model.AddReviewRequest(ctx, issue, u, issue.Poster)
if err != nil {
log.Warn("Failed add assignee user: %s to PR review: %s#%d, error: %s", u.Name, pr.BaseRepo.Name, pr.ID, err)
diff --git a/services/issue/reaction.go b/services/issue/reaction.go
index dbb4735de2..c6a11aa0f0 100644
--- a/services/issue/reaction.go
+++ b/services/issue/reaction.go
@@ -5,8 +5,8 @@ package issue
import (
"context"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
)
// CreateIssueReaction creates a reaction on issue.
diff --git a/services/issue/status.go b/services/issue/status.go
index 9b6c683f4f..6664da7daa 100644
--- a/services/issue/status.go
+++ b/services/issue/status.go
@@ -6,10 +6,10 @@ package issue
import (
"context"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- notify_service "code.gitea.io/gitea/services/notify"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ notify_service "forgejo.org/services/notify"
)
// ChangeStatus changes issue status to open or closed.
diff --git a/services/issue/template.go b/services/issue/template.go
index 47633e5d85..67a01825d2 100644
--- a/services/issue/template.go
+++ b/services/issue/template.go
@@ -10,11 +10,11 @@ import (
"path"
"strings"
- "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/issue/template"
- "code.gitea.io/gitea/modules/log"
- api "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/models/repo"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/issue/template"
+ "forgejo.org/modules/log"
+ api "forgejo.org/modules/structs"
"gopkg.in/yaml.v3"
)
@@ -56,8 +56,6 @@ func GetTemplateConfig(gitRepo *git.Repository, path string, commit *git.Commit)
return GetDefaultTemplateConfig(), nil
}
- var err error
-
treeEntry, err := commit.GetTreeEntryByPath(path)
if err != nil {
return GetDefaultTemplateConfig(), err
diff --git a/services/lfs/locks.go b/services/lfs/locks.go
index 2a362b1c0d..a45b2cc93b 100644
--- a/services/lfs/locks.go
+++ b/services/lfs/locks.go
@@ -8,16 +8,16 @@ import (
"strconv"
"strings"
- auth_model "code.gitea.io/gitea/models/auth"
- git_model "code.gitea.io/gitea/models/git"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/json"
- lfs_module "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- api "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/convert"
+ auth_model "forgejo.org/models/auth"
+ git_model "forgejo.org/models/git"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/json"
+ lfs_module "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ api "forgejo.org/modules/structs"
+ "forgejo.org/services/context"
+ "forgejo.org/services/convert"
)
func handleLockListOut(ctx *context.Context, repo *repo_model.Repository, lock *git_model.LFSLock, err error) {
diff --git a/services/lfs/server.go b/services/lfs/server.go
index ace501e15f..8eef62eabe 100644
--- a/services/lfs/server.go
+++ b/services/lfs/server.go
@@ -18,20 +18,21 @@ import (
"strconv"
"strings"
- actions_model "code.gitea.io/gitea/models/actions"
- auth_model "code.gitea.io/gitea/models/auth"
- git_model "code.gitea.io/gitea/models/git"
- "code.gitea.io/gitea/models/perm"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/json"
- lfs_module "code.gitea.io/gitea/modules/lfs"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/services/context"
+ actions_model "forgejo.org/models/actions"
+ auth_model "forgejo.org/models/auth"
+ git_model "forgejo.org/models/git"
+ "forgejo.org/models/perm"
+ access_model "forgejo.org/models/perm/access"
+ quota_model "forgejo.org/models/quota"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/json"
+ lfs_module "forgejo.org/modules/lfs"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/services/context"
"github.com/golang-jwt/jwt/v5"
)
@@ -179,6 +180,23 @@ func BatchHandler(ctx *context.Context) {
return
}
+ if isUpload {
+ ok, err := quota_model.EvaluateForUser(ctx, ctx.Doer.ID, quota_model.LimitSubjectSizeGitLFS)
+ if err != nil {
+ log.Error("quota_model.EvaluateForUser: %v", err)
+ writeStatus(ctx, http.StatusInternalServerError)
+ return
+ }
+ if !ok {
+ writeStatusMessage(ctx, http.StatusRequestEntityTooLarge, "quota exceeded")
+ }
+ }
+
+ if setting.LFS.MaxBatchSize != 0 && len(br.Objects) > setting.LFS.MaxBatchSize {
+ writeStatus(ctx, http.StatusRequestEntityTooLarge)
+ return
+ }
+
contentStore := lfs_module.NewContentStore()
var responseObjects []*lfs_module.ObjectResponse
@@ -297,6 +315,18 @@ func UploadHandler(ctx *context.Context) {
return
}
+ if exists {
+ ok, err := quota_model.EvaluateForUser(ctx, ctx.Doer.ID, quota_model.LimitSubjectSizeGitLFS)
+ if err != nil {
+ log.Error("quota_model.EvaluateForUser: %v", err)
+ writeStatus(ctx, http.StatusInternalServerError)
+ return
+ }
+ if !ok {
+ writeStatusMessage(ctx, http.StatusRequestEntityTooLarge, "quota exceeded")
+ }
+ }
+
uploadOrVerify := func() error {
if exists {
accessible, err := git_model.LFSObjectAccessible(ctx, ctx.Doer, p.Oid)
@@ -455,7 +485,7 @@ func buildObjectResponse(rc *requestContext, pointer lfs_module.Pointer, downloa
var link *lfs_module.Link
if setting.LFS.Storage.MinioConfig.ServeDirect {
// If we have a signed url (S3, object storage), redirect to this directly.
- u, err := storage.LFS.URL(pointer.RelativePath(), pointer.Oid)
+ u, err := storage.LFS.URL(pointer.RelativePath(), pointer.Oid, nil)
if u != nil && err == nil {
// Presigned url does not need the Authorization header
// https://github.com/go-gitea/gitea/issues/21525
diff --git a/services/mailer/incoming/incoming.go b/services/mailer/incoming/incoming.go
index ac6f32c540..b1b9191df3 100644
--- a/services/mailer/incoming/incoming.go
+++ b/services/mailer/incoming/incoming.go
@@ -7,20 +7,22 @@ import (
"context"
"crypto/tls"
"fmt"
+ "mime"
net_mail "net/mail"
"regexp"
+ "slices"
"strings"
"time"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/services/mailer/token"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/setting"
+ "forgejo.org/services/mailer/token"
"code.forgejo.org/forgejo/reply"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
- "github.com/jhillyerd/enmime"
+ "github.com/jhillyerd/enmime/v2"
)
var (
@@ -297,6 +299,10 @@ func isAutomaticReply(env *enmime.Envelope) bool {
if autoReply == "yes" {
return true
}
+ precedence := env.GetHeader("Precedence")
+ if precedence == "auto_reply" {
+ return true
+ }
autoRespond := env.GetHeader("X-Autorespond")
return autoRespond != ""
}
@@ -370,25 +376,56 @@ type Attachment struct {
// getContentFromMailReader grabs the plain content and the attachments from the mail.
// A potential reply/signature gets stripped from the content.
func getContentFromMailReader(env *enmime.Envelope) *MailContent {
+ // get attachments
attachments := make([]*Attachment, 0, len(env.Attachments))
for _, attachment := range env.Attachments {
attachments = append(attachments, &Attachment{
- Name: attachment.FileName,
+ Name: constructFilename(attachment),
Content: attachment.Content,
})
}
+ // get inlines
inlineAttachments := make([]*Attachment, 0, len(env.Inlines))
for _, inline := range env.Inlines {
if inline.FileName != "" && inline.ContentType != "text/plain" {
inlineAttachments = append(inlineAttachments, &Attachment{
- Name: inline.FileName,
+ Name: constructFilename(inline),
Content: inline.Content,
})
}
}
+ // get other parts (mostly multipart/related files, these are for example embedded images in an html mail)
+ otherParts := make([]*Attachment, 0, len(env.Inlines))
+ for _, otherPart := range env.OtherParts {
+ otherParts = append(otherParts, &Attachment{
+ Name: constructFilename(otherPart),
+ Content: otherPart.Content,
+ })
+ }
return &MailContent{
Content: reply.FromText(env.Text),
- Attachments: append(attachments, inlineAttachments...),
+ Attachments: slices.Concat(attachments, inlineAttachments, otherParts),
}
}
+
+// constructFilename interprets the mime part as an (inline) attachment and returns its filename
+// If no filename is given it guesses a sensible filename for it based on the filetype.
+func constructFilename(part *enmime.Part) string {
+ if strings.TrimSpace(part.FileName) != "" {
+ return part.FileName
+ }
+
+ filenameWOExtension := "unnamed_file"
+ if strings.TrimSpace(part.ContentID) != "" {
+ filenameWOExtension = part.ContentID
+ }
+
+ fileExtension := ".unknown"
+ mimeExtensions, err := mime.ExtensionsByType(part.ContentType)
+ if err == nil && len(mimeExtensions) != 0 {
+ // just use the first one we find
+ fileExtension = mimeExtensions[0]
+ }
+ return filenameWOExtension + fileExtension
+}
diff --git a/services/mailer/incoming/incoming_handler.go b/services/mailer/incoming/incoming_handler.go
index c7e2193fc5..7505148978 100644
--- a/services/mailer/incoming/incoming_handler.go
+++ b/services/mailer/incoming/incoming_handler.go
@@ -8,19 +8,19 @@ import (
"context"
"fmt"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/util"
- attachment_service "code.gitea.io/gitea/services/attachment"
- "code.gitea.io/gitea/services/context/upload"
- issue_service "code.gitea.io/gitea/services/issue"
- incoming_payload "code.gitea.io/gitea/services/mailer/incoming/payload"
- "code.gitea.io/gitea/services/mailer/token"
- pull_service "code.gitea.io/gitea/services/pull"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/util"
+ attachment_service "forgejo.org/services/attachment"
+ "forgejo.org/services/context/upload"
+ issue_service "forgejo.org/services/issue"
+ incoming_payload "forgejo.org/services/mailer/incoming/payload"
+ "forgejo.org/services/mailer/token"
+ pull_service "forgejo.org/services/pull"
)
type MailHandler interface {
@@ -181,7 +181,7 @@ func (h *UnsubscribeHandler) Handle(ctx context.Context, _ *MailContent, doer *u
}
return issues_model.CreateOrUpdateIssueWatch(ctx, doer.ID, issue.ID, false)
+ default:
+ return fmt.Errorf("unsupported unsubscribe reference: %v", ref)
}
-
- return fmt.Errorf("unsupported unsubscribe reference: %v", ref)
}
diff --git a/services/mailer/incoming/incoming_test.go b/services/mailer/incoming/incoming_test.go
index 001374d371..2ffaac57ae 100644
--- a/services/mailer/incoming/incoming_test.go
+++ b/services/mailer/incoming/incoming_test.go
@@ -4,12 +4,14 @@
package incoming
import (
+ "encoding/base64"
"strings"
"testing"
"github.com/emersion/go-imap"
- "github.com/jhillyerd/enmime"
+ "github.com/jhillyerd/enmime/v2"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestNotHandleTwice(t *testing.T) {
@@ -17,12 +19,12 @@ func TestNotHandleTwice(t *testing.T) {
msg := imap.NewMessage(90, []imap.FetchItem{imap.FetchBody})
handled := isAlreadyHandled(handledSet, msg)
- assert.Equal(t, false, handled)
+ assert.False(t, handled)
handledSet.AddNum(msg.SeqNum)
handled = isAlreadyHandled(handledSet, msg)
- assert.Equal(t, true, handled)
+ assert.True(t, handled)
}
func TestIsAutomaticReply(t *testing.T) {
@@ -64,6 +66,12 @@ func TestIsAutomaticReply(t *testing.T) {
},
Expected: true,
},
+ {
+ Headers: map[string]string{
+ "Precedence": "auto_reply",
+ },
+ Expected: true,
+ },
}
for _, c := range cases {
@@ -74,9 +82,9 @@ func TestIsAutomaticReply(t *testing.T) {
b = b.Header(k, v)
}
root, err := b.Build()
- assert.NoError(t, err)
+ require.NoError(t, err)
env, err := enmime.EnvelopeFromPart(root)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, c.Expected, isAutomaticReply(env))
}
@@ -102,7 +110,7 @@ func TestGetContentFromMailReader(t *testing.T) {
"--message-boundary--\r\n"
env, err := enmime.ReadEnvelope(strings.NewReader(mailString))
- assert.NoError(t, err)
+ require.NoError(t, err)
content := getContentFromMailReader(env)
assert.Equal(t, "mail content", content.Content)
assert.Len(t, content.Attachments, 1)
@@ -139,7 +147,7 @@ func TestGetContentFromMailReader(t *testing.T) {
"--message-boundary--\r\n"
env, err = enmime.ReadEnvelope(strings.NewReader(mailString))
- assert.NoError(t, err)
+ require.NoError(t, err)
content = getContentFromMailReader(env)
assert.Equal(t, "mail content\n--\nattachment content", content.Content)
assert.Len(t, content.Attachments, 2)
@@ -161,7 +169,7 @@ func TestGetContentFromMailReader(t *testing.T) {
"--message-boundary--\r\n"
env, err = enmime.ReadEnvelope(strings.NewReader(mailString))
- assert.NoError(t, err)
+ require.NoError(t, err)
content = getContentFromMailReader(env)
assert.Equal(t, "mail content", content.Content)
assert.Empty(t, content.Attachments)
@@ -182,9 +190,196 @@ func TestGetContentFromMailReader(t *testing.T) {
"--message-boundary--\r\n"
env, err = enmime.ReadEnvelope(strings.NewReader(mailString))
- assert.NoError(t, err)
+ require.NoError(t, err)
content = getContentFromMailReader(env)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Equal(t, "mail content without signature", content.Content)
assert.Empty(t, content.Attachments)
+
+ // Some versions of Outlook send inline attachments like this, inside a multipart/related part.
+ // the attached image is from: https://openmoji.org/library/emoji-1F684
+ mailString = "Content-Type: multipart/related; boundary=\"=_related boundary=\"\r\n" +
+ "\r\n" +
+ "This text is for clients unable to decode multipart/related with multipart/alternative.\r\n" +
+ "\r\n" +
+ "--=_related boundary=\r\n" +
+ "Content-Type: multipart/alternative; boundary=\"=_alternative boundary=\"\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "--=_alternative boundary=\r\n" +
+ "Content-Type: text/plain\r\n" +
+ "\r\n" +
+ "This is the plaintext.\r\n" +
+ "\r\n" +
+ "--=_alternative boundary=\r\n" +
+ "Content-Type: text/html\r\n" +
+ "\r\n" +
+ "This is a mail with multipart/related. Here is an image sent with a filename.
\r\n" +
+ " \r\n" +
+ "\r\n" +
+ "--=_alternative boundary=--\r\n" +
+ "\r\n" +
+ "--=_related boundary=\r\n" +
+ "Content-Transfer-Encoding: base64\r\n" +
+ "Content-Type: image/png;\r\n" +
+ " name=\"image001.png\"\r\n" +
+ "Content-ID: <_1_2845>\r\n" +
+ "\r\n" +
+ "iVBORw0KGgoAAAANSUhEUgAAAEAAAAAiCAYAAADvVd+PAAAFLUlEQVRo3t2ZX0iTXxjHP3u35qvT\r\n" +
+ "6ZzhzKFuzPQq9WKQZS6FvLQf3Wh30ViBQXnViC5+LVKEiC6DjMQgCCy6NChoIKwghhcR1bJ5s5Ei\r\n" +
+ "LmtNs/05XYT7Vercaps/94Xn4uU95znvOc/3+XdehRBCsM1YXl7G6/Xi8Xh49uwZMzMzhEIhFhcX\r\n" +
+ "+fbtW87WbW1tRbVdmxZC8PTpU8bGxrh//z5fv37dcJxGo2HXrl1ZWVOhUPzybDAYUOSbAYlEgjt3\r\n" +
+ "7nD58mVmZ2cBkCSJ1tZWDhw4wP79+2lpaUGv16PX61Gr1Tm3RN7w/Plz0d7eLgABCKPRKJxOp3j/\r\n" +
+ "/r3YLuTlAD5+/ChOnDiR3HhdXZ24e/euiMfjYruRcxe4evUqV65c4fPnz6hUKrq7uzl06NA6v157\r\n" +
+ "19bWlrbueDzOq1evmJ6eJhQKZRww9+3blzsXWFpaEqdOnUpaPV2ZmJjYUveLFy+Ew+EQFRUVGev/\r\n" +
+ "WTQaTW4Y8OjRIxwOB4FAAEmS0Gq1lJWVpZwTjUaZm5vDZrPhdrs3HOP3+3E6nTx48IC1zy4uLqas\r\n" +
+ "rAy1Wr0uym8FnU6X3TT46dMnzp8/z82bNwHQarU0NTVRUlKScl44HMbn8wFQU1Oz7n0sFuP69etc\r\n" +
+ "unSJ5eVllEole/bswWAwbKk7FSRJyl4a/NnqSqWS+vp6jEZjSqskEglmZ2cJBoMIIbBYLExNTWEw\r\n" +
+ "GJJjvF4vDoeD6elpAKqrqzGbzVlJj5Ik/T0D/tTqS0tL+Hw+VlZWUKlUDAwMMDQ0RGlpKQArKyu4\r\n" +
+ "XC6uXbtGLBZDlmUaGxuprKzMajGmyrfVY7EYfr+fDx8+ANDS0sLo6ChWqzU5xu12c/r0aXw+HwqF\r\n" +
+ "gtraWkwmE0qlMutZSpVPq8/NzeH3+4lGo5SUlOByuRgcHESl+u8zLly4wMjICAClpaU0NTUlWZEL\r\n" +
+ "ZBwDfo/wDQ0NKa0ej8dZWFggEAgQiUQA6Onp4caNG5jN5l/GTk1N0dnZmTab8sqA+fl5jh07hsfj\r\n" +
+ "AUCWZXbv3g1AIBBYR/NoNEokEuHLly8kEgkATCYTQ0NDHD9+fFOGrKW2jfRmGxqNJr1CaHJyUuj1\r\n" +
+ "+j8qNiRJEp2dneL27dtidXU15TrhcFhYLJa/Km4ykeLi4tSF0O++Xl9fz5EjR9Dr9SlPtry8nKqq\r\n" +
+ "KsxmM1arFa1Wm7ZVQqEQDx8+5N27dznvTG022+YMmJycFEajUQBClmUxMjIiYrGYKDSwVQ3f3t4u\r\n" +
+ "3rx5k1LJy5cvhd1uF83NzaKoqChvFP5b6e3t/fUAMrX64uKiOHnypFAoFDtm0z9Ll14nVACRSIQz\r\n" +
+ "Z84wPj4OwMGDBxkbG6OxsXFT/7l37x6Dg4PMz89TJEn0VVXwT2U5dUVq1DlOXdmCsrwcVTQapaen\r\n" +
+ "B4/HgyzLDA8Pc+7cOSRJ2nTixYsXGR4eBsBaWsK/xmrqitTsSIyOjgpAmEwm8fbt27QCx969e3ck\r\n" +
+ "5TdyAfr6+gQgxsfH046ct27dEjqdbscfQG9vr1CtNRiZVMR2ux273U4hQOru7gbA5XLh9Xr5H/wn\r\n" +
+ "yS9WV1dFR0dHQfh0ptLR0fGjDgiHw8LpdIqGhoYdm9P/RCwWS3qXok+ePOHs2bO8fv06eZ3c39+X\r\n" +
+ "7AZ3MlK2wzMzMwwMDPD48WMAamtr6e/vo7m5uWBCwKYMWFhYoK2tjWAwiEaj4ejRXmw2W8oCqaAO\r\n" +
+ "wO1209XVhSzLHD5s+3F5UGAwGo2bt8OhUEjU1NQUdBDc8s9QMBhkYmIieVVVaLDZbHwHmmIQk3rD\r\n" +
+ "exgAAAAASUVORK5CYII=\r\n" +
+ "\r\n" +
+ "--=_related boundary=--\r\n" +
+ "\r\n"
+
+ env, err = enmime.ReadEnvelope(strings.NewReader(mailString))
+ require.NoError(t, err)
+ content = getContentFromMailReader(env)
+ assert.Equal(t, "This is the plaintext.", content.Content)
+ assert.Len(t, content.Attachments, 1)
+ assert.Equal(t, "image001.png", content.Attachments[0].Name)
+ expectedAttachment, err := base64.StdEncoding.DecodeString(
+ "iVBORw0KGgoAAAANSUhEUgAAAEAAAAAiCAYAAADvVd+PAAAFLUlEQVRo3t2ZX0iTXxjHP3u35qvT\r\n" +
+ "6ZzhzKFuzPQq9WKQZS6FvLQf3Wh30ViBQXnViC5+LVKEiC6DjMQgCCy6NChoIKwghhcR1bJ5s5Ei\r\n" +
+ "LmtNs/05XYT7Vercaps/94Xn4uU95znvOc/3+XdehRBCsM1YXl7G6/Xi8Xh49uwZMzMzhEIhFhcX\r\n" +
+ "+fbtW87WbW1tRbVdmxZC8PTpU8bGxrh//z5fv37dcJxGo2HXrl1ZWVOhUPzybDAYUOSbAYlEgjt3\r\n" +
+ "7nD58mVmZ2cBkCSJ1tZWDhw4wP79+2lpaUGv16PX61Gr1Tm3RN7w/Plz0d7eLgABCKPRKJxOp3j/\r\n" +
+ "/r3YLuTlAD5+/ChOnDiR3HhdXZ24e/euiMfjYruRcxe4evUqV65c4fPnz6hUKrq7uzl06NA6v157\r\n" +
+ "19bWlrbueDzOq1evmJ6eJhQKZRww9+3blzsXWFpaEqdOnUpaPV2ZmJjYUveLFy+Ew+EQFRUVGev/\r\n" +
+ "WTQaTW4Y8OjRIxwOB4FAAEmS0Gq1lJWVpZwTjUaZm5vDZrPhdrs3HOP3+3E6nTx48IC1zy4uLqas\r\n" +
+ "rAy1Wr0uym8FnU6X3TT46dMnzp8/z82bNwHQarU0NTVRUlKScl44HMbn8wFQU1Oz7n0sFuP69etc\r\n" +
+ "unSJ5eVllEole/bswWAwbKk7FSRJyl4a/NnqSqWS+vp6jEZjSqskEglmZ2cJBoMIIbBYLExNTWEw\r\n" +
+ "GJJjvF4vDoeD6elpAKqrqzGbzVlJj5Ik/T0D/tTqS0tL+Hw+VlZWUKlUDAwMMDQ0RGlpKQArKyu4\r\n" +
+ "XC6uXbtGLBZDlmUaGxuprKzMajGmyrfVY7EYfr+fDx8+ANDS0sLo6ChWqzU5xu12c/r0aXw+HwqF\r\n" +
+ "gtraWkwmE0qlMutZSpVPq8/NzeH3+4lGo5SUlOByuRgcHESl+u8zLly4wMjICAClpaU0NTUlWZEL\r\n" +
+ "ZBwDfo/wDQ0NKa0ej8dZWFggEAgQiUQA6Onp4caNG5jN5l/GTk1N0dnZmTab8sqA+fl5jh07hsfj\r\n" +
+ "AUCWZXbv3g1AIBBYR/NoNEokEuHLly8kEgkATCYTQ0NDHD9+fFOGrKW2jfRmGxqNJr1CaHJyUuj1\r\n" +
+ "+j8qNiRJEp2dneL27dtidXU15TrhcFhYLJa/Km4ykeLi4tSF0O++Xl9fz5EjR9Dr9SlPtry8nKqq\r\n" +
+ "KsxmM1arFa1Wm7ZVQqEQDx8+5N27dznvTG022+YMmJycFEajUQBClmUxMjIiYrGYKDSwVQ3f3t4u\r\n" +
+ "3rx5k1LJy5cvhd1uF83NzaKoqChvFP5b6e3t/fUAMrX64uKiOHnypFAoFDtm0z9Ll14nVACRSIQz\r\n" +
+ "Z84wPj4OwMGDBxkbG6OxsXFT/7l37x6Dg4PMz89TJEn0VVXwT2U5dUVq1DlOXdmCsrwcVTQapaen\r\n" +
+ "B4/HgyzLDA8Pc+7cOSRJ2nTixYsXGR4eBsBaWsK/xmrqitTsSIyOjgpAmEwm8fbt27QCx969e3ck\r\n" +
+ "5TdyAfr6+gQgxsfH046ct27dEjqdbscfQG9vr1CtNRiZVMR2ux273U4hQOru7gbA5XLh9Xr5H/wn\r\n" +
+ "yS9WV1dFR0dHQfh0ptLR0fGjDgiHw8LpdIqGhoYdm9P/RCwWS3qXok+ePOHs2bO8fv06eZ3c39+X\r\n" +
+ "7AZ3MlK2wzMzMwwMDPD48WMAamtr6e/vo7m5uWBCwKYMWFhYoK2tjWAwiEaj4ejRXmw2W8oCqaAO\r\n" +
+ "wO1209XVhSzLHD5s+3F5UGAwGo2bt8OhUEjU1NQUdBDc8s9QMBhkYmIieVVVaLDZbHwHmmIQk3rD\r\n" +
+ "exgAAAAASUVORK5CYII=\r\n")
+ require.NoError(t, err)
+ assert.Equal(t, expectedAttachment, content.Attachments[0].Content)
+
+ // HCL Notes inlines attachments like this: without a filename.
+ // the attached image is from: https://openmoji.org/library/emoji-1F684
+ mailString = "Content-Type: multipart/related; boundary=\"=_related boundary=\"\r\n" +
+ "\r\n" +
+ "This text is for clients unable to decode multipart/related with multipart/alternative.\r\n" +
+ "\r\n" +
+ "--=_related boundary=\r\n" +
+ "Content-Type: multipart/alternative; boundary=\"=_alternative boundary=\"\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "\r\n" +
+ "--=_alternative boundary=\r\n" +
+ "Content-Type: text/plain\r\n" +
+ "\r\n" +
+ "This is the plaintext.\r\n" +
+ "\r\n" +
+ "--=_alternative boundary=\r\n" +
+ "Content-Type: text/html\r\n" +
+ "\r\n" +
+ "This is a mail with multipart/related. Here is an image sent without a filename.
\r\n" +
+ " \r\n" +
+ "\r\n" +
+ "--=_alternative boundary=--\r\n" +
+ "\r\n" +
+ "--=_related boundary=\r\n" +
+ "Content-Transfer-Encoding: base64\r\n" +
+ "Content-Type: image/png\r\n" +
+ "Content-ID: <_1_2845>\r\n" +
+ "\r\n" +
+ "iVBORw0KGgoAAAANSUhEUgAAAEAAAAAiCAYAAADvVd+PAAAFLUlEQVRo3t2ZX0iTXxjHP3u35qvT\r\n" +
+ "6ZzhzKFuzPQq9WKQZS6FvLQf3Wh30ViBQXnViC5+LVKEiC6DjMQgCCy6NChoIKwghhcR1bJ5s5Ei\r\n" +
+ "LmtNs/05XYT7Vercaps/94Xn4uU95znvOc/3+XdehRBCsM1YXl7G6/Xi8Xh49uwZMzMzhEIhFhcX\r\n" +
+ "+fbtW87WbW1tRbVdmxZC8PTpU8bGxrh//z5fv37dcJxGo2HXrl1ZWVOhUPzybDAYUOSbAYlEgjt3\r\n" +
+ "7nD58mVmZ2cBkCSJ1tZWDhw4wP79+2lpaUGv16PX61Gr1Tm3RN7w/Plz0d7eLgABCKPRKJxOp3j/\r\n" +
+ "/r3YLuTlAD5+/ChOnDiR3HhdXZ24e/euiMfjYruRcxe4evUqV65c4fPnz6hUKrq7uzl06NA6v157\r\n" +
+ "19bWlrbueDzOq1evmJ6eJhQKZRww9+3blzsXWFpaEqdOnUpaPV2ZmJjYUveLFy+Ew+EQFRUVGev/\r\n" +
+ "WTQaTW4Y8OjRIxwOB4FAAEmS0Gq1lJWVpZwTjUaZm5vDZrPhdrs3HOP3+3E6nTx48IC1zy4uLqas\r\n" +
+ "rAy1Wr0uym8FnU6X3TT46dMnzp8/z82bNwHQarU0NTVRUlKScl44HMbn8wFQU1Oz7n0sFuP69etc\r\n" +
+ "unSJ5eVllEole/bswWAwbKk7FSRJyl4a/NnqSqWS+vp6jEZjSqskEglmZ2cJBoMIIbBYLExNTWEw\r\n" +
+ "GJJjvF4vDoeD6elpAKqrqzGbzVlJj5Ik/T0D/tTqS0tL+Hw+VlZWUKlUDAwMMDQ0RGlpKQArKyu4\r\n" +
+ "XC6uXbtGLBZDlmUaGxuprKzMajGmyrfVY7EYfr+fDx8+ANDS0sLo6ChWqzU5xu12c/r0aXw+HwqF\r\n" +
+ "gtraWkwmE0qlMutZSpVPq8/NzeH3+4lGo5SUlOByuRgcHESl+u8zLly4wMjICAClpaU0NTUlWZEL\r\n" +
+ "ZBwDfo/wDQ0NKa0ej8dZWFggEAgQiUQA6Onp4caNG5jN5l/GTk1N0dnZmTab8sqA+fl5jh07hsfj\r\n" +
+ "AUCWZXbv3g1AIBBYR/NoNEokEuHLly8kEgkATCYTQ0NDHD9+fFOGrKW2jfRmGxqNJr1CaHJyUuj1\r\n" +
+ "+j8qNiRJEp2dneL27dtidXU15TrhcFhYLJa/Km4ykeLi4tSF0O++Xl9fz5EjR9Dr9SlPtry8nKqq\r\n" +
+ "KsxmM1arFa1Wm7ZVQqEQDx8+5N27dznvTG022+YMmJycFEajUQBClmUxMjIiYrGYKDSwVQ3f3t4u\r\n" +
+ "3rx5k1LJy5cvhd1uF83NzaKoqChvFP5b6e3t/fUAMrX64uKiOHnypFAoFDtm0z9Ll14nVACRSIQz\r\n" +
+ "Z84wPj4OwMGDBxkbG6OxsXFT/7l37x6Dg4PMz89TJEn0VVXwT2U5dUVq1DlOXdmCsrwcVTQapaen\r\n" +
+ "B4/HgyzLDA8Pc+7cOSRJ2nTixYsXGR4eBsBaWsK/xmrqitTsSIyOjgpAmEwm8fbt27QCx969e3ck\r\n" +
+ "5TdyAfr6+gQgxsfH046ct27dEjqdbscfQG9vr1CtNRiZVMR2ux273U4hQOru7gbA5XLh9Xr5H/wn\r\n" +
+ "yS9WV1dFR0dHQfh0ptLR0fGjDgiHw8LpdIqGhoYdm9P/RCwWS3qXok+ePOHs2bO8fv06eZ3c39+X\r\n" +
+ "7AZ3MlK2wzMzMwwMDPD48WMAamtr6e/vo7m5uWBCwKYMWFhYoK2tjWAwiEaj4ejRXmw2W8oCqaAO\r\n" +
+ "wO1209XVhSzLHD5s+3F5UGAwGo2bt8OhUEjU1NQUdBDc8s9QMBhkYmIieVVVaLDZbHwHmmIQk3rD\r\n" +
+ "exgAAAAASUVORK5CYII=\r\n" +
+ "\r\n" +
+ "--=_related boundary=--\r\n" +
+ "\r\n"
+
+ env, err = enmime.ReadEnvelope(strings.NewReader(mailString))
+ require.NoError(t, err)
+ content = getContentFromMailReader(env)
+ assert.Equal(t, "This is the plaintext.", content.Content)
+ assert.Len(t, content.Attachments, 1)
+ assert.Equal(t, "_1_2845.png", content.Attachments[0].Name)
+ expectedAttachment, err = base64.StdEncoding.DecodeString(
+ "iVBORw0KGgoAAAANSUhEUgAAAEAAAAAiCAYAAADvVd+PAAAFLUlEQVRo3t2ZX0iTXxjHP3u35qvT\r\n" +
+ "6ZzhzKFuzPQq9WKQZS6FvLQf3Wh30ViBQXnViC5+LVKEiC6DjMQgCCy6NChoIKwghhcR1bJ5s5Ei\r\n" +
+ "LmtNs/05XYT7Vercaps/94Xn4uU95znvOc/3+XdehRBCsM1YXl7G6/Xi8Xh49uwZMzMzhEIhFhcX\r\n" +
+ "+fbtW87WbW1tRbVdmxZC8PTpU8bGxrh//z5fv37dcJxGo2HXrl1ZWVOhUPzybDAYUOSbAYlEgjt3\r\n" +
+ "7nD58mVmZ2cBkCSJ1tZWDhw4wP79+2lpaUGv16PX61Gr1Tm3RN7w/Plz0d7eLgABCKPRKJxOp3j/\r\n" +
+ "/r3YLuTlAD5+/ChOnDiR3HhdXZ24e/euiMfjYruRcxe4evUqV65c4fPnz6hUKrq7uzl06NA6v157\r\n" +
+ "19bWlrbueDzOq1evmJ6eJhQKZRww9+3blzsXWFpaEqdOnUpaPV2ZmJjYUveLFy+Ew+EQFRUVGev/\r\n" +
+ "WTQaTW4Y8OjRIxwOB4FAAEmS0Gq1lJWVpZwTjUaZm5vDZrPhdrs3HOP3+3E6nTx48IC1zy4uLqas\r\n" +
+ "rAy1Wr0uym8FnU6X3TT46dMnzp8/z82bNwHQarU0NTVRUlKScl44HMbn8wFQU1Oz7n0sFuP69etc\r\n" +
+ "unSJ5eVllEole/bswWAwbKk7FSRJyl4a/NnqSqWS+vp6jEZjSqskEglmZ2cJBoMIIbBYLExNTWEw\r\n" +
+ "GJJjvF4vDoeD6elpAKqrqzGbzVlJj5Ik/T0D/tTqS0tL+Hw+VlZWUKlUDAwMMDQ0RGlpKQArKyu4\r\n" +
+ "XC6uXbtGLBZDlmUaGxuprKzMajGmyrfVY7EYfr+fDx8+ANDS0sLo6ChWqzU5xu12c/r0aXw+HwqF\r\n" +
+ "gtraWkwmE0qlMutZSpVPq8/NzeH3+4lGo5SUlOByuRgcHESl+u8zLly4wMjICAClpaU0NTUlWZEL\r\n" +
+ "ZBwDfo/wDQ0NKa0ej8dZWFggEAgQiUQA6Onp4caNG5jN5l/GTk1N0dnZmTab8sqA+fl5jh07hsfj\r\n" +
+ "AUCWZXbv3g1AIBBYR/NoNEokEuHLly8kEgkATCYTQ0NDHD9+fFOGrKW2jfRmGxqNJr1CaHJyUuj1\r\n" +
+ "+j8qNiRJEp2dneL27dtidXU15TrhcFhYLJa/Km4ykeLi4tSF0O++Xl9fz5EjR9Dr9SlPtry8nKqq\r\n" +
+ "KsxmM1arFa1Wm7ZVQqEQDx8+5N27dznvTG022+YMmJycFEajUQBClmUxMjIiYrGYKDSwVQ3f3t4u\r\n" +
+ "3rx5k1LJy5cvhd1uF83NzaKoqChvFP5b6e3t/fUAMrX64uKiOHnypFAoFDtm0z9Ll14nVACRSIQz\r\n" +
+ "Z84wPj4OwMGDBxkbG6OxsXFT/7l37x6Dg4PMz89TJEn0VVXwT2U5dUVq1DlOXdmCsrwcVTQapaen\r\n" +
+ "B4/HgyzLDA8Pc+7cOSRJ2nTixYsXGR4eBsBaWsK/xmrqitTsSIyOjgpAmEwm8fbt27QCx969e3ck\r\n" +
+ "5TdyAfr6+gQgxsfH046ct27dEjqdbscfQG9vr1CtNRiZVMR2ux273U4hQOru7gbA5XLh9Xr5H/wn\r\n" +
+ "yS9WV1dFR0dHQfh0ptLR0fGjDgiHw8LpdIqGhoYdm9P/RCwWS3qXok+ePOHs2bO8fv06eZ3c39+X\r\n" +
+ "7AZ3MlK2wzMzMwwMDPD48WMAamtr6e/vo7m5uWBCwKYMWFhYoK2tjWAwiEaj4ejRXmw2W8oCqaAO\r\n" +
+ "wO1209XVhSzLHD5s+3F5UGAwGo2bt8OhUEjU1NQUdBDc8s9QMBhkYmIieVVVaLDZbHwHmmIQk3rD\r\n" +
+ "exgAAAAASUVORK5CYII=\r\n")
+ require.NoError(t, err)
+ assert.Equal(t, expectedAttachment, content.Attachments[0].Content)
}
diff --git a/services/mailer/incoming/payload/payload.go b/services/mailer/incoming/payload/payload.go
index 00ada7826b..bb7a65e3d5 100644
--- a/services/mailer/incoming/payload/payload.go
+++ b/services/mailer/incoming/payload/payload.go
@@ -6,8 +6,8 @@ package payload
import (
"context"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/util"
+ issues_model "forgejo.org/models/issues"
+ "forgejo.org/modules/util"
)
const replyPayloadVersion1 byte = 1
diff --git a/services/mailer/mail.go b/services/mailer/mail.go
index d86607295a..4269686f2d 100644
--- a/services/mailer/mail.go
+++ b/services/mailer/mail.go
@@ -16,29 +16,35 @@ import (
texttmpl "text/template"
"time"
- activities_model "code.gitea.io/gitea/models/activities"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/emoji"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/translation"
- incoming_payload "code.gitea.io/gitea/services/mailer/incoming/payload"
- "code.gitea.io/gitea/services/mailer/token"
+ activities_model "forgejo.org/models/activities"
+ auth_model "forgejo.org/models/auth"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/emoji"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/translation"
+ incoming_payload "forgejo.org/services/mailer/incoming/payload"
+ "forgejo.org/services/mailer/token"
"gopkg.in/gomail.v2"
)
const (
- mailAuthActivate base.TplName = "auth/activate"
- mailAuthActivateEmail base.TplName = "auth/activate_email"
- mailAuthResetPassword base.TplName = "auth/reset_passwd"
- mailAuthRegisterNotify base.TplName = "auth/register_notify"
+ mailAuthActivate base.TplName = "auth/activate"
+ mailAuthActivateEmail base.TplName = "auth/activate_email"
+ mailAuthResetPassword base.TplName = "auth/reset_passwd"
+ mailAuthRegisterNotify base.TplName = "auth/register_notify"
+ mailAuthPasswordChange base.TplName = "auth/password_change"
+ mailAuthPrimaryMailChange base.TplName = "auth/primary_mail_change"
+ mailAuth2faDisabled base.TplName = "auth/2fa_disabled"
+ mailAuthRemovedSecurityKey base.TplName = "auth/removed_security_key"
+ mailAuthTOTPEnrolled base.TplName = "auth/totp_enrolled"
mailNotifyCollaborator base.TplName = "notify/collaborator"
@@ -64,7 +70,7 @@ func SendTestMail(email string) error {
}
// sendUserMail sends a mail to the user
-func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, subject, info string) {
+func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, subject, info string) error {
locale := translation.NewLocale(language)
data := map[string]any{
"locale": locale,
@@ -78,47 +84,66 @@ func sendUserMail(language string, u *user_model.User, tpl base.TplName, code, s
var content bytes.Buffer
if err := bodyTemplates.ExecuteTemplate(&content, string(tpl), data); err != nil {
- log.Error("Template: %v", err)
- return
+ return err
}
- msg := NewMessage(u.Email, subject, content.String())
+ msg := NewMessage(u.EmailTo(), subject, content.String())
msg.Info = fmt.Sprintf("UID: %d, %s", u.ID, info)
SendAsync(msg)
+ return nil
}
// SendActivateAccountMail sends an activation mail to the user (new user registration)
-func SendActivateAccountMail(locale translation.Locale, u *user_model.User) {
+func SendActivateAccountMail(ctx context.Context, u *user_model.User) error {
if setting.MailService == nil {
// No mail service configured
- return
+ return nil
}
- sendUserMail(locale.Language(), u, mailAuthActivate, u.GenerateEmailActivateCode(u.Email), locale.TrString("mail.activate_account"), "activate account")
+
+ locale := translation.NewLocale(u.Language)
+ code, err := u.GenerateEmailAuthorizationCode(ctx, auth_model.UserActivation)
+ if err != nil {
+ return err
+ }
+
+ return sendUserMail(locale.Language(), u, mailAuthActivate, code, locale.TrString("mail.activate_account"), "activate account")
}
// SendResetPasswordMail sends a password reset mail to the user
-func SendResetPasswordMail(u *user_model.User) {
+func SendResetPasswordMail(ctx context.Context, u *user_model.User) error {
if setting.MailService == nil {
// No mail service configured
- return
+ return nil
}
+
locale := translation.NewLocale(u.Language)
- sendUserMail(u.Language, u, mailAuthResetPassword, u.GenerateEmailActivateCode(u.Email), locale.TrString("mail.reset_password"), "recover account")
+ code, err := u.GenerateEmailAuthorizationCode(ctx, auth_model.PasswordReset)
+ if err != nil {
+ return err
+ }
+
+ return sendUserMail(u.Language, u, mailAuthResetPassword, code, locale.TrString("mail.reset_password"), "recover account")
}
// SendActivateEmailMail sends confirmation email to confirm new email address
-func SendActivateEmailMail(u *user_model.User, email string) {
+func SendActivateEmailMail(ctx context.Context, u *user_model.User, email string) error {
if setting.MailService == nil {
// No mail service configured
- return
+ return nil
}
+
locale := translation.NewLocale(u.Language)
+ code, err := u.GenerateEmailAuthorizationCode(ctx, auth_model.EmailActivation(email))
+ if err != nil {
+ return err
+ }
+
data := map[string]any{
"locale": locale,
"DisplayName": u.DisplayName(),
"ActiveCodeLives": timeutil.MinutesToFriendly(setting.Service.ActiveCodeLives, locale),
- "Code": u.GenerateEmailActivateCode(email),
+ "Code": code,
"Email": email,
"Language": locale.Language(),
}
@@ -126,14 +151,14 @@ func SendActivateEmailMail(u *user_model.User, email string) {
var content bytes.Buffer
if err := bodyTemplates.ExecuteTemplate(&content, string(mailAuthActivateEmail), data); err != nil {
- log.Error("Template: %v", err)
- return
+ return err
}
msg := NewMessage(email, locale.TrString("mail.activate_email"), content.String())
msg.Info = fmt.Sprintf("UID: %d, activate email", u.ID)
SendAsync(msg)
+ return nil
}
// SendRegisterNotifyMail triggers a notify e-mail by admin created a account.
@@ -158,7 +183,7 @@ func SendRegisterNotifyMail(u *user_model.User) {
return
}
- msg := NewMessage(u.Email, locale.TrString("mail.register_notify"), content.String())
+ msg := NewMessage(u.EmailTo(), locale.TrString("mail.register_notify", setting.AppName), content.String())
msg.Info = fmt.Sprintf("UID: %d, registration notify", u.ID)
SendAsync(msg)
@@ -189,7 +214,7 @@ func SendCollaboratorMail(u, doer *user_model.User, repo *repo_model.Repository)
return
}
- msg := NewMessage(u.Email, subject, content.String())
+ msg := NewMessage(u.EmailTo(), subject, content.String())
msg.Info = fmt.Sprintf("UID: %d, add collaborator", u.ID)
SendAsync(msg)
@@ -313,7 +338,7 @@ func composeIssueCommentMessages(ctx *mailCommentContext, lang string, recipient
for _, recipient := range recipients {
msg := NewMessageFrom(
recipient.Email,
- ctx.Doer.GetCompleteName(),
+ fromDisplayName(ctx.Doer),
setting.MailService.FromEmail,
subject,
mailBody.String(),
@@ -545,3 +570,182 @@ func actionToTemplate(issue *issues_model.Issue, actionType activities_model.Act
}
return typeName, name, template
}
+
+func fromDisplayName(u *user_model.User) string {
+ if setting.MailService.FromDisplayNameFormatTemplate != nil {
+ var ctx bytes.Buffer
+ err := setting.MailService.FromDisplayNameFormatTemplate.Execute(&ctx, map[string]any{
+ "DisplayName": u.DisplayName(),
+ "AppName": setting.AppName,
+ "Domain": setting.Domain,
+ })
+ if err == nil {
+ return mime.QEncoding.Encode("utf-8", ctx.String())
+ }
+ log.Error("fromDisplayName: %w", err)
+ }
+ return u.GetCompleteName()
+}
+
+// SendPasswordChange informs the user on their primary email address that
+// their password was changed.
+func SendPasswordChange(u *user_model.User) error {
+ if setting.MailService == nil {
+ return nil
+ }
+ locale := translation.NewLocale(u.Language)
+
+ data := map[string]any{
+ "locale": locale,
+ "DisplayName": u.DisplayName(),
+ "Username": u.Name,
+ "Language": locale.Language(),
+ }
+
+ var content bytes.Buffer
+
+ if err := bodyTemplates.ExecuteTemplate(&content, string(mailAuthPasswordChange), data); err != nil {
+ return err
+ }
+
+ msg := NewMessage(u.EmailTo(), locale.TrString("mail.password_change.subject"), content.String())
+ msg.Info = fmt.Sprintf("UID: %d, password change notification", u.ID)
+
+ SendAsync(msg)
+ return nil
+}
+
+// SendPrimaryMailChange informs the user on their old primary email address
+// that it's no longer used as primary mail and will no longer receive
+// notification on that email address.
+func SendPrimaryMailChange(u *user_model.User, oldPrimaryEmail string) error {
+ if setting.MailService == nil {
+ return nil
+ }
+ locale := translation.NewLocale(u.Language)
+
+ data := map[string]any{
+ "locale": locale,
+ "NewPrimaryMail": u.Email,
+ "DisplayName": u.DisplayName(),
+ "Username": u.Name,
+ "Language": locale.Language(),
+ }
+
+ var content bytes.Buffer
+
+ if err := bodyTemplates.ExecuteTemplate(&content, string(mailAuthPrimaryMailChange), data); err != nil {
+ return err
+ }
+
+ msg := NewMessage(u.EmailTo(oldPrimaryEmail), locale.TrString("mail.primary_mail_change.subject"), content.String())
+ msg.Info = fmt.Sprintf("UID: %d, primary email change notification", u.ID)
+
+ SendAsync(msg)
+ return nil
+}
+
+// SendDisabledTOTP informs the user that their totp has been disabled.
+func SendDisabledTOTP(ctx context.Context, u *user_model.User) error {
+ if setting.MailService == nil {
+ return nil
+ }
+ locale := translation.NewLocale(u.Language)
+
+ hasWebAuthn, err := auth_model.HasWebAuthnRegistrationsByUID(ctx, u.ID)
+ if err != nil {
+ return err
+ }
+
+ data := map[string]any{
+ "locale": locale,
+ "HasWebAuthn": hasWebAuthn,
+ "DisplayName": u.DisplayName(),
+ "Username": u.Name,
+ "Language": locale.Language(),
+ }
+
+ var content bytes.Buffer
+
+ if err := bodyTemplates.ExecuteTemplate(&content, string(mailAuth2faDisabled), data); err != nil {
+ return err
+ }
+
+ msg := NewMessage(u.EmailTo(), locale.TrString("mail.totp_disabled.subject"), content.String())
+ msg.Info = fmt.Sprintf("UID: %d, 2fa disabled notification", u.ID)
+
+ SendAsync(msg)
+ return nil
+}
+
+// SendRemovedWebAuthn informs the user that one of their security keys has been removed.
+func SendRemovedSecurityKey(ctx context.Context, u *user_model.User, securityKeyName string) error {
+ if setting.MailService == nil {
+ return nil
+ }
+ locale := translation.NewLocale(u.Language)
+
+ hasWebAuthn, err := auth_model.HasWebAuthnRegistrationsByUID(ctx, u.ID)
+ if err != nil {
+ return err
+ }
+ hasTOTP, err := auth_model.HasTOTPByUID(ctx, u.ID)
+ if err != nil {
+ return err
+ }
+
+ data := map[string]any{
+ "locale": locale,
+ "HasWebAuthn": hasWebAuthn,
+ "HasTOTP": hasTOTP,
+ "SecurityKeyName": securityKeyName,
+ "DisplayName": u.DisplayName(),
+ "Username": u.Name,
+ "Language": locale.Language(),
+ }
+
+ var content bytes.Buffer
+
+ if err := bodyTemplates.ExecuteTemplate(&content, string(mailAuthRemovedSecurityKey), data); err != nil {
+ return err
+ }
+
+ msg := NewMessage(u.EmailTo(), locale.TrString("mail.removed_security_key.subject"), content.String())
+ msg.Info = fmt.Sprintf("UID: %d, security key removed notification", u.ID)
+
+ SendAsync(msg)
+ return nil
+}
+
+// SendTOTPEnrolled informs the user that they've been enrolled into TOTP.
+func SendTOTPEnrolled(ctx context.Context, u *user_model.User) error {
+ if setting.MailService == nil {
+ return nil
+ }
+ locale := translation.NewLocale(u.Language)
+
+ hasWebAuthn, err := auth_model.HasWebAuthnRegistrationsByUID(ctx, u.ID)
+ if err != nil {
+ return err
+ }
+
+ data := map[string]any{
+ "locale": locale,
+ "HasWebAuthn": hasWebAuthn,
+ "DisplayName": u.DisplayName(),
+ "Username": u.Name,
+ "Language": locale.Language(),
+ }
+
+ var content bytes.Buffer
+
+ if err := bodyTemplates.ExecuteTemplate(&content, string(mailAuthTOTPEnrolled), data); err != nil {
+ return err
+ }
+
+ msg := NewMessage(u.EmailTo(), locale.TrString("mail.totp_enrolled.subject"), content.String())
+ msg.Info = fmt.Sprintf("UID: %d, enrolled into TOTP notification", u.ID)
+
+ SendAsync(msg)
+ return nil
+}
diff --git a/services/mailer/mail_admin_new_user.go b/services/mailer/mail_admin_new_user.go
index 0713de8a95..ffb03197b7 100644
--- a/services/mailer/mail_admin_new_user.go
+++ b/services/mailer/mail_admin_new_user.go
@@ -7,12 +7,12 @@ import (
"context"
"strconv"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/translation"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/translation"
)
const (
diff --git a/services/mailer/mail_admin_new_user_test.go b/services/mailer/mail_admin_new_user_test.go
index 603a8b95c9..9273691792 100644
--- a/services/mailer/mail_admin_new_user_test.go
+++ b/services/mailer/mail_admin_new_user_test.go
@@ -8,15 +8,13 @@ import (
"strconv"
"testing"
- "code.gitea.io/gitea/models/db"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/models/db"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
-
- _ "github.com/mattn/go-sqlite3"
)
func getTestUsers(t *testing.T) []*user_model.User {
@@ -47,7 +45,7 @@ func cleanUpUsers(ctx context.Context, users []*user_model.User) {
}
func TestAdminNotificationMail_test(t *testing.T) {
- ctx := context.Background()
+ ctx := t.Context()
users := getTestUsers(t)
@@ -55,14 +53,14 @@ func TestAdminNotificationMail_test(t *testing.T) {
defer test.MockVariableValue(&setting.Admin.SendNotificationEmailOnNewUser, true)()
called := false
- defer mockMailSettings(func(msgs ...*Message) {
- assert.Equal(t, len(msgs), 1, "Test provides only one admin user, so only one email must be sent")
+ defer MockMailSettings(func(msgs ...*Message) {
+ assert.Len(t, msgs, 1, "Test provides only one admin user, so only one email must be sent")
assert.Equal(t, msgs[0].To, users[0].Email, "checks if the recipient is the admin of the instance")
manageUserURL := setting.AppURL + "admin/users/" + strconv.FormatInt(users[1].ID, 10)
assert.Contains(t, msgs[0].Body, manageUserURL)
assert.Contains(t, msgs[0].Body, users[1].HTMLURL())
assert.Contains(t, msgs[0].Body, users[1].Name, "user name of the newly created user")
- assertTranslatedLocale(t, msgs[0].Body, "mail.admin", "admin.users")
+ AssertTranslatedLocale(t, msgs[0].Body, "mail.admin", "admin.users")
called = true
})()
MailNewUser(ctx, users[1])
@@ -71,7 +69,7 @@ func TestAdminNotificationMail_test(t *testing.T) {
t.Run("SendNotificationEmailOnNewUser_false", func(t *testing.T) {
defer test.MockVariableValue(&setting.Admin.SendNotificationEmailOnNewUser, false)()
- defer mockMailSettings(func(msgs ...*Message) {
+ defer MockMailSettings(func(msgs ...*Message) {
assert.Equal(t, 1, 0, "this shouldn't execute. MailNewUser must exit early since SEND_NOTIFICATION_EMAIL_ON_NEW_USER is disabled")
})()
MailNewUser(ctx, users[1])
diff --git a/services/mailer/mail_auth_test.go b/services/mailer/mail_auth_test.go
new file mode 100644
index 0000000000..e40a0d6fa0
--- /dev/null
+++ b/services/mailer/mail_auth_test.go
@@ -0,0 +1,62 @@
+// Copyright 2024 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package mailer_test
+
+import (
+ "testing"
+
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
+ "forgejo.org/services/mailer"
+ user_service "forgejo.org/services/user"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+func TestPasswordChangeMail(t *testing.T) {
+ defer require.NoError(t, unittest.PrepareTestDatabase())
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ called := false
+ defer mailer.MockMailSettings(func(msgs ...*mailer.Message) {
+ assert.Len(t, msgs, 1)
+ assert.Equal(t, user.EmailTo(), msgs[0].To)
+ assert.EqualValues(t, translation.NewLocale("en-US").Tr("mail.password_change.subject"), msgs[0].Subject)
+ mailer.AssertTranslatedLocale(t, msgs[0].Body, "mail.password_change.text_1", "mail.password_change.text_2", "mail.password_change.text_3")
+ called = true
+ })()
+
+ require.NoError(t, user_service.UpdateAuth(db.DefaultContext, user, &user_service.UpdateAuthOptions{Password: optional.Some("NewPasswordYolo!")}))
+ assert.True(t, called)
+}
+
+func TestPrimaryMailChange(t *testing.T) {
+ defer require.NoError(t, unittest.PrepareTestDatabase())
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ firstEmail := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{ID: 3, UID: user.ID, IsPrimary: true})
+ secondEmail := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{ID: 35, UID: user.ID}, "is_primary = false")
+
+ called := false
+ defer mailer.MockMailSettings(func(msgs ...*mailer.Message) {
+ assert.False(t, called)
+ assert.Len(t, msgs, 1)
+ assert.Equal(t, user.EmailTo(firstEmail.Email), msgs[0].To)
+ assert.EqualValues(t, translation.NewLocale("en-US").Tr("mail.primary_mail_change.subject"), msgs[0].Subject)
+ assert.Contains(t, msgs[0].Body, secondEmail.Email)
+ assert.Contains(t, msgs[0].Body, setting.AppURL)
+ mailer.AssertTranslatedLocale(t, msgs[0].Body, "mail.primary_mail_change.text_1", "mail.primary_mail_change.text_2", "mail.primary_mail_change.text_3")
+ called = true
+ })()
+
+ require.NoError(t, user_service.MakeEmailAddressPrimary(db.DefaultContext, user, secondEmail, true))
+ assert.True(t, called)
+
+ require.NoError(t, user_service.MakeEmailAddressPrimary(db.DefaultContext, user, firstEmail, false))
+}
diff --git a/services/mailer/mail_comment.go b/services/mailer/mail_comment.go
index 1812441d5a..b4ed3145ed 100644
--- a/services/mailer/mail_comment.go
+++ b/services/mailer/mail_comment.go
@@ -6,12 +6,12 @@ package mailer
import (
"context"
- activities_model "code.gitea.io/gitea/models/activities"
- issues_model "code.gitea.io/gitea/models/issues"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ activities_model "forgejo.org/models/activities"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
// MailParticipantsComment sends new comment emails to repository watchers and mentioned people.
diff --git a/services/mailer/mail_issue.go b/services/mailer/mail_issue.go
index fab3315be2..b0329caa0b 100644
--- a/services/mailer/mail_issue.go
+++ b/services/mailer/mail_issue.go
@@ -7,19 +7,22 @@ import (
"context"
"fmt"
- activities_model "code.gitea.io/gitea/models/activities"
- issues_model "code.gitea.io/gitea/models/issues"
- access_model "code.gitea.io/gitea/models/perm/access"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
+ activities_model "forgejo.org/models/activities"
+ issues_model "forgejo.org/models/issues"
+ access_model "forgejo.org/models/perm/access"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
)
func fallbackMailSubject(issue *issues_model.Issue) string {
- return fmt.Sprintf("[%s] %s (#%d)", issue.Repo.FullName(), issue.Title, issue.Index)
+ if issue.IsPull {
+ return fmt.Sprintf("[%s] %s (PR #%d)", issue.Repo.FullName(), issue.Title, issue.Index)
+ }
+ return fmt.Sprintf("[%s] %s (Issue #%d)", issue.Repo.FullName(), issue.Title, issue.Index)
}
type mailCommentContext struct {
diff --git a/services/mailer/mail_release.go b/services/mailer/mail_release.go
index 2b0e7cfdc0..0f2ef33fe1 100644
--- a/services/mailer/mail_release.go
+++ b/services/mailer/mail_release.go
@@ -7,14 +7,14 @@ import (
"bytes"
"context"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/markup/markdown"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/markup/markdown"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
)
const (
@@ -40,10 +40,10 @@ func MailNewRelease(ctx context.Context, rel *repo_model.Release) {
return
}
- langMap := make(map[string][]string)
+ langMap := make(map[string][]*user_model.User)
for _, user := range recipients {
if user.ID != rel.PublisherID {
- langMap[user.Language] = append(langMap[user.Language], user.Email)
+ langMap[user.Language] = append(langMap[user.Language], user)
}
}
@@ -52,7 +52,7 @@ func MailNewRelease(ctx context.Context, rel *repo_model.Release) {
}
}
-func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_model.Release) {
+func mailNewRelease(ctx context.Context, lang string, tos []*user_model.User, rel *repo_model.Release) {
locale := translation.NewLocale(lang)
var err error
@@ -85,10 +85,10 @@ func mailNewRelease(ctx context.Context, lang string, tos []string, rel *repo_mo
}
msgs := make([]*Message, 0, len(tos))
- publisherName := rel.Publisher.DisplayName()
+ publisherName := fromDisplayName(rel.Publisher)
msgID := createMessageIDForRelease(rel)
for _, to := range tos {
- msg := NewMessageFrom(to, publisherName, setting.MailService.FromEmail, subject, mailBody.String())
+ msg := NewMessageFrom(to.EmailTo(), publisherName, setting.MailService.FromEmail, subject, mailBody.String())
msg.Info = subject
msg.SetHeader("Message-ID", msgID)
msgs = append(msgs, msg)
diff --git a/services/mailer/mail_repo.go b/services/mailer/mail_repo.go
index e0d55bb120..eed650f3ac 100644
--- a/services/mailer/mail_repo.go
+++ b/services/mailer/mail_repo.go
@@ -8,11 +8,11 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/organization"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/models/organization"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
)
// SendRepoTransferNotifyMail triggers a notification e-mail when a pending repository transfer was created
@@ -28,13 +28,13 @@ func SendRepoTransferNotifyMail(ctx context.Context, doer, newOwner *user_model.
return err
}
- langMap := make(map[string][]string)
+ langMap := make(map[string][]*user_model.User)
for _, user := range users {
if !user.IsActive {
// don't send emails to inactive users
continue
}
- langMap[user.Language] = append(langMap[user.Language], user.Email)
+ langMap[user.Language] = append(langMap[user.Language], user)
}
for lang, tos := range langMap {
@@ -46,11 +46,11 @@ func SendRepoTransferNotifyMail(ctx context.Context, doer, newOwner *user_model.
return nil
}
- return sendRepoTransferNotifyMailPerLang(newOwner.Language, newOwner, doer, []string{newOwner.Email}, repo)
+ return sendRepoTransferNotifyMailPerLang(newOwner.Language, newOwner, doer, []*user_model.User{newOwner}, repo)
}
// sendRepoTransferNotifyMail triggers a notification e-mail when a pending repository transfer was created for each language
-func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.User, emails []string, repo *repo_model.Repository) error {
+func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.User, emailTos []*user_model.User, repo *repo_model.Repository) error {
var (
locale = translation.NewLocale(lang)
content bytes.Buffer
@@ -78,8 +78,8 @@ func sendRepoTransferNotifyMailPerLang(lang string, newOwner, doer *user_model.U
return err
}
- for _, to := range emails {
- msg := NewMessage(to, subject, content.String())
+ for _, to := range emailTos {
+ msg := NewMessageFrom(to.EmailTo(), fromDisplayName(doer), setting.MailService.FromEmail, subject, content.String())
msg.Info = fmt.Sprintf("UID: %d, repository pending transfer notification", newOwner.ID)
SendAsync(msg)
diff --git a/services/mailer/mail_team_invite.go b/services/mailer/mail_team_invite.go
index ceecefa50f..a2a871d3c3 100644
--- a/services/mailer/mail_team_invite.go
+++ b/services/mailer/mail_team_invite.go
@@ -9,12 +9,12 @@ import (
"fmt"
"net/url"
- org_model "code.gitea.io/gitea/models/organization"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/translation"
+ org_model "forgejo.org/models/organization"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/translation"
)
const (
diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go
index 8fa45fd593..616eea2d85 100644
--- a/services/mailer/mail_test.go
+++ b/services/mailer/mail_test.go
@@ -15,17 +15,18 @@ import (
"testing"
texttmpl "text/template"
- activities_model "code.gitea.io/gitea/models/activities"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/markup"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ activities_model "forgejo.org/models/activities"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/markup"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
const subjectTpl = `
@@ -51,18 +52,18 @@ const bodyTpl = `
`
func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, comment *issues_model.Comment) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, Owner: doer})
issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1, Repo: repo, Poster: doer})
- assert.NoError(t, issue.LoadRepo(db.DefaultContext))
+ require.NoError(t, issue.LoadRepo(db.DefaultContext))
comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2, Issue: issue})
return doer, repo, issue, comment
}
func TestComposeIssueCommentMessage(t *testing.T) {
- defer mockMailSettings(nil)()
+ defer MockMailSettings(nil)()
doer, _, issue, comment := prepareMailerTest(t)
markup.Init(&markup.ProcessorHelper{
@@ -78,12 +79,12 @@ func TestComposeIssueCommentMessage(t *testing.T) {
recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}}
msgs, err := composeIssueCommentMessages(&mailCommentContext{
- Context: context.TODO(), // TODO: use a correct context
+ Context: t.Context(), // TODO: use a correct context
Issue: issue, Doer: doer, ActionType: activities_model.ActionCommentIssue,
Content: fmt.Sprintf("test @%s %s#%d body", doer.Name, issue.Repo.FullName(), issue.Index),
Comment: comment,
}, "en-US", recipients, false, "issue comment")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, msgs, 2)
gomailMsg := msgs[0].ToMessage()
replyTo := gomailMsg.GetHeader("Reply-To")[0]
@@ -105,7 +106,7 @@ func TestComposeIssueCommentMessage(t *testing.T) {
gomailMsg.WriteTo(&buf)
b, err := io.ReadAll(quotedprintable.NewReader(&buf))
- assert.NoError(t, err)
+ require.NoError(t, err)
// text/plain
assert.Contains(t, string(b), fmt.Sprintf(`( %s )`, doer.HTMLURL()))
@@ -117,16 +118,16 @@ func TestComposeIssueCommentMessage(t *testing.T) {
}
func TestComposeIssueMessage(t *testing.T) {
- defer mockMailSettings(nil)()
+ defer MockMailSettings(nil)()
doer, _, issue, _ := prepareMailerTest(t)
recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}}
msgs, err := composeIssueCommentMessages(&mailCommentContext{
- Context: context.TODO(), // TODO: use a correct context
+ Context: t.Context(), // TODO: use a correct context
Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue,
Content: "test body",
}, "en-US", recipients, false, "issue create")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, msgs, 2)
gomailMsg := msgs[0].ToMessage()
@@ -137,7 +138,7 @@ func TestComposeIssueMessage(t *testing.T) {
references := gomailMsg.GetHeader("References")
assert.Len(t, mailto, 1, "exactly one recipient is expected in the To field")
- assert.Equal(t, "[user2/repo1] issue1 (#1)", subject[0])
+ assert.Equal(t, "[user2/repo1] issue1 (Issue #1)", subject[0])
assert.Equal(t, "", inReplyTo[0], "In-Reply-To header doesn't match")
assert.Equal(t, "", references[0], "References header doesn't match")
assert.Equal(t, "", messageID[0], "Message-ID header doesn't match")
@@ -146,8 +147,8 @@ func TestComposeIssueMessage(t *testing.T) {
}
func TestMailerIssueTemplate(t *testing.T) {
- defer mockMailSettings(nil)()
- assert.NoError(t, unittest.PrepareTestDatabase())
+ defer MockMailSettings(nil)()
+ require.NoError(t, unittest.PrepareTestDatabase())
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
@@ -160,23 +161,23 @@ func TestMailerIssueTemplate(t *testing.T) {
for _, s := range expected {
assert.Contains(t, wholemsg, s)
}
- assertTranslatedLocale(t, wholemsg, "mail.issue")
+ AssertTranslatedLocale(t, wholemsg, "mail.issue")
}
testCompose := func(t *testing.T, ctx *mailCommentContext) *Message {
t.Helper()
recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}}
- ctx.Context = context.Background()
+ ctx.Context = t.Context()
fromMention := false
msgs, err := composeIssueCommentMessages(ctx, "en-US", recipients, fromMention, "TestMailerIssueTemplate")
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, msgs, 1)
return msgs[0]
}
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
- assert.NoError(t, issue.LoadRepo(db.DefaultContext))
+ require.NoError(t, issue.LoadRepo(db.DefaultContext))
msg := testCompose(t, &mailCommentContext{
Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue,
@@ -205,7 +206,7 @@ func TestMailerIssueTemplate(t *testing.T) {
expect(t, msg, issue, comment.Content)
pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
- assert.NoError(t, pull.LoadAttributes(db.DefaultContext))
+ require.NoError(t, pull.LoadAttributes(db.DefaultContext))
pullComment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull})
msg = testCompose(t, &mailCommentContext{
@@ -221,7 +222,7 @@ func TestMailerIssueTemplate(t *testing.T) {
expect(t, msg, pull, pullComment.Content, pull.PullRequest.BaseBranch)
reviewComment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 9})
- assert.NoError(t, reviewComment.LoadReview(db.DefaultContext))
+ require.NoError(t, reviewComment.LoadReview(db.DefaultContext))
approveComment := reviewComment
approveComment.Review.Type = issues_model.ReviewTypeApprove
@@ -241,7 +242,7 @@ func TestMailerIssueTemplate(t *testing.T) {
}
func TestTemplateSelection(t *testing.T) {
- defer mockMailSettings(nil)()
+ defer MockMailSettings(nil)()
doer, repo, issue, comment := prepareMailerTest(t)
recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}}
@@ -265,14 +266,14 @@ func TestTemplateSelection(t *testing.T) {
}
msg := testComposeIssueCommentMessage(t, &mailCommentContext{
- Context: context.TODO(), // TODO: use a correct context
+ Context: t.Context(), // TODO: use a correct context
Issue: issue, Doer: doer, ActionType: activities_model.ActionCreateIssue,
Content: "test body",
}, recipients, false, "TestTemplateSelection")
expect(t, msg, "issue/new/subject", "issue/new/body")
msg = testComposeIssueCommentMessage(t, &mailCommentContext{
- Context: context.TODO(), // TODO: use a correct context
+ Context: t.Context(), // TODO: use a correct context
Issue: issue, Doer: doer, ActionType: activities_model.ActionCommentIssue,
Content: "test body", Comment: comment,
}, recipients, false, "TestTemplateSelection")
@@ -281,24 +282,24 @@ func TestTemplateSelection(t *testing.T) {
pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2, Repo: repo, Poster: doer})
comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull})
msg = testComposeIssueCommentMessage(t, &mailCommentContext{
- Context: context.TODO(), // TODO: use a correct context
+ Context: t.Context(), // TODO: use a correct context
Issue: pull, Doer: doer, ActionType: activities_model.ActionCommentPull,
Content: "test body", Comment: comment,
}, recipients, false, "TestTemplateSelection")
expect(t, msg, "pull/comment/subject", "pull/comment/body")
msg = testComposeIssueCommentMessage(t, &mailCommentContext{
- Context: context.TODO(), // TODO: use a correct context
+ Context: t.Context(), // TODO: use a correct context
Issue: issue, Doer: doer, ActionType: activities_model.ActionCloseIssue,
Content: "test body", Comment: comment,
}, recipients, false, "TestTemplateSelection")
- expect(t, msg, "Re: [user2/repo1] issue1 (#1)", "issue/close/body")
+ expect(t, msg, "Re: [user2/repo1] issue1 (Issue #1)", "issue/close/body")
}
func TestTemplateServices(t *testing.T) {
- defer mockMailSettings(nil)()
+ defer MockMailSettings(nil)()
doer, _, issue, comment := prepareMailerTest(t)
- assert.NoError(t, issue.LoadRepo(db.DefaultContext))
+ require.NoError(t, issue.LoadRepo(db.DefaultContext))
expect := func(t *testing.T, issue *issues_model.Issue, comment *issues_model.Comment, doer *user_model.User,
actionType activities_model.ActionType, fromMention bool, tplSubject, tplBody, expSubject, expBody string,
@@ -308,7 +309,7 @@ func TestTemplateServices(t *testing.T) {
recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}}
msg := testComposeIssueCommentMessage(t, &mailCommentContext{
- Context: context.TODO(), // TODO: use a correct context
+ Context: t.Context(), // TODO: use a correct context
Issue: issue, Doer: doer, ActionType: actionType,
Content: "test body", Comment: comment,
}, recipients, fromMention, "TestTemplateServices")
@@ -337,22 +338,22 @@ func TestTemplateServices(t *testing.T) {
expect(t, issue, comment, doer, activities_model.ActionCommentIssue, true,
"{{.FallbackSubject}}",
"//{{.SubjectPrefix}}//",
- "Re: [user2/repo1] issue1 (#1)",
+ "Re: [user2/repo1] issue1 (Issue #1)",
"//Re: //")
}
func testComposeIssueCommentMessage(t *testing.T, ctx *mailCommentContext, recipients []*user_model.User, fromMention bool, info string) *Message {
msgs, err := composeIssueCommentMessages(ctx, "en-US", recipients, fromMention, info)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, msgs, 1)
return msgs[0]
}
func TestGenerateAdditionalHeaders(t *testing.T) {
- defer mockMailSettings(nil)()
+ defer MockMailSettings(nil)()
doer, _, issue, _ := prepareMailerTest(t)
- ctx := &mailCommentContext{Context: context.TODO() /* TODO: use a correct context */, Issue: issue, Doer: doer}
+ ctx := &mailCommentContext{Context: t.Context() /* TODO: use a correct context */, Issue: issue, Doer: doer}
recipient := &user_model.User{Name: "test", Email: "test@gitea.com"}
headers := generateAdditionalHeaders(ctx, "dummy-reason", recipient)
@@ -382,7 +383,7 @@ func TestGenerateAdditionalHeaders(t *testing.T) {
}
func Test_createReference(t *testing.T) {
- defer mockMailSettings(nil)()
+ defer MockMailSettings(nil)()
_, _, issue, comment := prepareMailerTest(t)
_, _, pullIssue, _ := prepareMailerTest(t)
pullIssue.IsPull = true
@@ -489,3 +490,59 @@ func Test_createReference(t *testing.T) {
})
}
}
+
+func TestFromDisplayName(t *testing.T) {
+ template, err := texttmpl.New("mailFrom").Parse("{{ .DisplayName }}")
+ require.NoError(t, err)
+ setting.MailService = &setting.Mailer{FromDisplayNameFormatTemplate: template}
+ defer func() { setting.MailService = nil }()
+
+ tests := []struct {
+ userDisplayName string
+ fromDisplayName string
+ }{{
+ userDisplayName: "test",
+ fromDisplayName: "test",
+ }, {
+ userDisplayName: "Hi Its ",
+ fromDisplayName: "Hi Its ",
+ }, {
+ userDisplayName: "รsir",
+ fromDisplayName: "=?utf-8?q?=C3=86sir?=",
+ }, {
+ userDisplayName: "new๐user",
+ fromDisplayName: "=?utf-8?q?new=F0=9F=98=80user?=",
+ }}
+
+ for _, tc := range tests {
+ t.Run(tc.userDisplayName, func(t *testing.T) {
+ user := &user_model.User{FullName: tc.userDisplayName, Name: "tmp"}
+ got := fromDisplayName(user)
+ assert.EqualValues(t, tc.fromDisplayName, got)
+ })
+ }
+
+ t.Run("template with all available vars", func(t *testing.T) {
+ template, err = texttmpl.New("mailFrom").Parse("{{ .DisplayName }} (by {{ .AppName }} on [{{ .Domain }}])")
+ require.NoError(t, err)
+ setting.MailService = &setting.Mailer{FromDisplayNameFormatTemplate: template}
+ oldAppName := setting.AppName
+ setting.AppName = "Code IT"
+ oldDomain := setting.Domain
+ setting.Domain = "code.it"
+ defer func() {
+ setting.AppName = oldAppName
+ setting.Domain = oldDomain
+ }()
+
+ assert.EqualValues(t, "Mister X (by Code IT on [code.it])", fromDisplayName(&user_model.User{FullName: "Mister X", Name: "tmp"}))
+ })
+}
+
+func TestFallbackSubjectType(t *testing.T) {
+ _, _, issue, _ := prepareMailerTest(t)
+ assert.Contains(t, fallbackMailSubject(issue), "Issue")
+ _, _, pr, _ := prepareMailerTest(t)
+ pr.IsPull = true
+ assert.Contains(t, fallbackMailSubject(pr), "PR")
+}
diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go
index 0a723f974a..4561240df5 100644
--- a/services/mailer/mailer.go
+++ b/services/mailer/mailer.go
@@ -18,14 +18,14 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/process"
- "code.gitea.io/gitea/modules/queue"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- notify_service "code.gitea.io/gitea/services/notify"
+ "forgejo.org/modules/base"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/process"
+ "forgejo.org/modules/queue"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ notify_service "forgejo.org/services/notify"
ntlmssp "github.com/Azure/go-ntlmssp"
"github.com/jaytaylor/html2text"
diff --git a/services/mailer/mailer_test.go b/services/mailer/mailer_test.go
index b7b4c28a3c..aef242d908 100644
--- a/services/mailer/mailer_test.go
+++ b/services/mailer/mailer_test.go
@@ -8,11 +8,12 @@ import (
"testing"
"time"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/test"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGenerateMessageID(t *testing.T) {
@@ -69,7 +70,7 @@ func TestToMessage(t *testing.T) {
buf := &strings.Builder{}
_, err := m1.ToMessage().WriteTo(buf)
- assert.NoError(t, err)
+ require.NoError(t, err)
header, _ := extractMailHeaderAndContent(t, buf.String())
assert.EqualValues(t, map[string]string{
"Content-Type": "multipart/alternative;",
@@ -89,7 +90,7 @@ func TestToMessage(t *testing.T) {
buf = &strings.Builder{}
_, err = m1.ToMessage().WriteTo(buf)
- assert.NoError(t, err)
+ require.NoError(t, err)
header, _ = extractMailHeaderAndContent(t, buf.String())
assert.EqualValues(t, map[string]string{
"Content-Type": "multipart/alternative;",
diff --git a/services/mailer/main_test.go b/services/mailer/main_test.go
index 399d05ac7b..9ef71dbdb3 100644
--- a/services/mailer/main_test.go
+++ b/services/mailer/main_test.go
@@ -7,13 +7,13 @@ import (
"context"
"testing"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/templates"
- "code.gitea.io/gitea/modules/test"
- "code.gitea.io/gitea/modules/translation"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/templates"
+ "forgejo.org/modules/test"
+ "forgejo.org/modules/translation"
- _ "code.gitea.io/gitea/models/actions"
+ _ "forgejo.org/models/actions"
"github.com/stretchr/testify/assert"
)
@@ -22,14 +22,14 @@ func TestMain(m *testing.M) {
unittest.MainTest(m)
}
-func assertTranslatedLocale(t *testing.T, message string, prefixes ...string) {
+func AssertTranslatedLocale(t *testing.T, message string, prefixes ...string) {
t.Helper()
for _, prefix := range prefixes {
assert.NotContains(t, message, prefix, "there is an untranslated locale prefix")
}
}
-func mockMailSettings(send func(msgs ...*Message)) func() {
+func MockMailSettings(send func(msgs ...*Message)) func() {
translation.InitLocales(context.Background())
subjectTemplates, bodyTemplates = templates.Mailer(context.Background())
mailService := setting.Mailer{
diff --git a/services/mailer/notify.go b/services/mailer/notify.go
index 54ab80aab9..e61ecd0511 100644
--- a/services/mailer/notify.go
+++ b/services/mailer/notify.go
@@ -7,12 +7,12 @@ import (
"context"
"fmt"
- activities_model "code.gitea.io/gitea/models/activities"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
- notify_service "code.gitea.io/gitea/services/notify"
+ activities_model "forgejo.org/models/activities"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/log"
+ notify_service "forgejo.org/services/notify"
)
type mailNotifier struct {
diff --git a/services/mailer/token/token.go b/services/mailer/token/token.go
index 8a5a762d6b..f3d7286cb0 100644
--- a/services/mailer/token/token.go
+++ b/services/mailer/token/token.go
@@ -11,8 +11,8 @@ import (
"fmt"
"time"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/util"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/util"
)
// A token is a verifiable container describing an action.
@@ -22,9 +22,16 @@ import (
//
// The payload is verifiable by the generated HMAC using the user secret. It contains:
// | Timestamp | Action/Handler Type | Action/Handler Data |
+//
+//
+// Version changelog
+//
+// v1 -> v2:
+// Use 128 instead of 80 bits of the HMAC-SHA256 output.
const (
tokenVersion1 byte = 1
+ tokenVersion2 byte = 2
tokenLifetimeInYears int = 1
)
@@ -70,7 +77,7 @@ func CreateToken(ht HandlerType, user *user_model.User, data []byte) (string, er
return "", err
}
- return encodingWithoutPadding.EncodeToString(append([]byte{tokenVersion1}, packagedData...)), nil
+ return encodingWithoutPadding.EncodeToString(append([]byte{tokenVersion2}, packagedData...)), nil
}
// ExtractToken extracts the action/user tuple from the token and verifies the content
@@ -84,7 +91,7 @@ func ExtractToken(ctx context.Context, token string) (HandlerType, *user_model.U
return UnknownHandlerType, nil, nil, &ErrToken{"no data"}
}
- if data[0] != tokenVersion1 {
+ if data[0] != tokenVersion2 {
return UnknownHandlerType, nil, nil, &ErrToken{fmt.Sprintf("unsupported token version: %v", data[0])}
}
@@ -124,5 +131,8 @@ func generateHmac(secret, payload []byte) []byte {
mac.Write(payload)
hmac := mac.Sum(nil)
- return hmac[:10] // RFC2104 recommends not using less then 80 bits
+ // RFC2104 section 5 recommends that if you do HMAC truncation, you should use
+ // the max(80, hash_len/2) of the leftmost bits.
+ // For SHA256 this works out to using 128 of the leftmost bits.
+ return hmac[:16]
}
diff --git a/services/markup/main_test.go b/services/markup/main_test.go
index 89fe3e7e34..1b085b4929 100644
--- a/services/markup/main_test.go
+++ b/services/markup/main_test.go
@@ -6,7 +6,7 @@ package markup
import (
"testing"
- "code.gitea.io/gitea/models/unittest"
+ "forgejo.org/models/unittest"
)
func TestMain(m *testing.M) {
diff --git a/services/markup/processorhelper.go b/services/markup/processorhelper.go
index 40bf1d65da..b5fcd78cb7 100644
--- a/services/markup/processorhelper.go
+++ b/services/markup/processorhelper.go
@@ -7,16 +7,16 @@ import (
"context"
"fmt"
- "code.gitea.io/gitea/models/perm/access"
- "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unit"
- "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/markup"
- gitea_context "code.gitea.io/gitea/services/context"
- file_service "code.gitea.io/gitea/services/repository/files"
+ "forgejo.org/models/perm/access"
+ "forgejo.org/models/repo"
+ "forgejo.org/models/unit"
+ "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/log"
+ "forgejo.org/modules/markup"
+ gitea_context "forgejo.org/services/context"
+ file_service "forgejo.org/services/repository/files"
)
func ProcessorHelper() *markup.ProcessorHelper {
diff --git a/services/markup/processorhelper_test.go b/services/markup/processorhelper_test.go
index 170edae0e0..8195451746 100644
--- a/services/markup/processorhelper_test.go
+++ b/services/markup/processorhelper_test.go
@@ -4,22 +4,22 @@
package markup
import (
- "context"
"net/http"
"net/http/httptest"
"testing"
- "code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/models/user"
- gitea_context "code.gitea.io/gitea/services/context"
- "code.gitea.io/gitea/services/contexttest"
+ "forgejo.org/models/db"
+ "forgejo.org/models/unittest"
+ "forgejo.org/models/user"
+ gitea_context "forgejo.org/services/context"
+ "forgejo.org/services/contexttest"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestProcessorHelper(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
userPublic := "user1"
userPrivate := "user31"
@@ -32,14 +32,14 @@ func TestProcessorHelper(t *testing.T) {
unittest.AssertCount(t, &user.User{Name: userNoSuch}, 0)
// when using general context, use user's visibility to check
- assert.True(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userPublic))
- assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userLimited))
- assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userPrivate))
- assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userNoSuch))
+ assert.True(t, ProcessorHelper().IsUsernameMentionable(t.Context(), userPublic))
+ assert.False(t, ProcessorHelper().IsUsernameMentionable(t.Context(), userLimited))
+ assert.False(t, ProcessorHelper().IsUsernameMentionable(t.Context(), userPrivate))
+ assert.False(t, ProcessorHelper().IsUsernameMentionable(t.Context(), userNoSuch))
// when using web context, use user.IsUserVisibleToViewer to check
req, err := http.NewRequest("GET", "/", nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
base, baseCleanUp := gitea_context.NewBaseContext(httptest.NewRecorder(), req)
defer baseCleanUp()
giteaCtx := gitea_context.NewWebContext(base, &contexttest.MockRender{}, nil)
@@ -48,7 +48,7 @@ func TestProcessorHelper(t *testing.T) {
assert.False(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPrivate))
giteaCtx.Doer, err = user.GetUserByName(db.DefaultContext, userPrivate)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPublic))
assert.True(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPrivate))
}
diff --git a/services/migrations/codebase.go b/services/migrations/codebase.go
index 492fc908e9..843df0f973 100644
--- a/services/migrations/codebase.go
+++ b/services/migrations/codebase.go
@@ -13,10 +13,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/proxy"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/proxy"
+ "forgejo.org/modules/structs"
)
var (
diff --git a/services/migrations/codebase_test.go b/services/migrations/codebase_test.go
index 68721e0641..315c7be709 100644
--- a/services/migrations/codebase_test.go
+++ b/services/migrations/codebase_test.go
@@ -4,15 +4,15 @@
package migrations
import (
- "context"
"net/url"
"os"
"testing"
"time"
- base "code.gitea.io/gitea/modules/migration"
+ base "forgejo.org/modules/migration"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestCodebaseDownloadRepo(t *testing.T) {
@@ -32,7 +32,7 @@ func TestCodebaseDownloadRepo(t *testing.T) {
}
factory := &CodebaseDownloaderFactory{}
- downloader, err := factory.New(context.Background(), base.MigrateOptions{
+ downloader, err := factory.New(t.Context(), base.MigrateOptions{
CloneAddr: u.String(),
AuthUsername: apiUser,
AuthPassword: apiPassword,
@@ -41,7 +41,7 @@ func TestCodebaseDownloadRepo(t *testing.T) {
t.Fatalf("Error creating Codebase downloader: %v", err)
}
repo, err := downloader.GetRepoInfo()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertRepositoryEqual(t, &base.Repository{
Name: "test",
Owner: "",
@@ -51,7 +51,7 @@ func TestCodebaseDownloadRepo(t *testing.T) {
}, repo)
milestones, err := downloader.GetMilestones()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertMilestonesEqual(t, []*base.Milestone{
{
Title: "Milestone1",
@@ -66,11 +66,11 @@ func TestCodebaseDownloadRepo(t *testing.T) {
}, milestones)
labels, err := downloader.GetLabels()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, labels, 4)
issues, isEnd, err := downloader.GetIssues(1, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, isEnd)
assertIssuesEqual(t, []*base.Issue{
{
@@ -107,7 +107,7 @@ func TestCodebaseDownloadRepo(t *testing.T) {
}, issues)
comments, _, err := downloader.GetComments(issues[0])
- assert.NoError(t, err)
+ require.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
IssueIndex: 2,
@@ -120,7 +120,7 @@ func TestCodebaseDownloadRepo(t *testing.T) {
}, comments)
prs, _, err := downloader.GetPullRequests(1, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assertPullRequestsEqual(t, []*base.PullRequest{
{
Number: 3,
@@ -145,6 +145,6 @@ func TestCodebaseDownloadRepo(t *testing.T) {
}, prs)
rvs, err := downloader.GetReviews(prs[0])
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, rvs)
}
diff --git a/services/migrations/common.go b/services/migrations/common.go
index d88518899d..ee74461447 100644
--- a/services/migrations/common.go
+++ b/services/migrations/common.go
@@ -7,10 +7,10 @@ import (
"fmt"
"strings"
- system_model "code.gitea.io/gitea/models/system"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
+ system_model "forgejo.org/models/system"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
)
// WarnAndNotice will log the provided message and send a repository notice
diff --git a/services/migrations/dump.go b/services/migrations/dump.go
index 07812002af..cbf6b87668 100644
--- a/services/migrations/dump.go
+++ b/services/migrations/dump.go
@@ -16,13 +16,13 @@ import (
"strings"
"time"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
"github.com/google/uuid"
"gopkg.in/yaml.v3"
@@ -128,6 +128,7 @@ func (g *RepositoryDumper) CreateRepo(repo *base.Repository, opts base.MigrateOp
"comments": opts.Comments,
"pulls": opts.PullRequests,
"assets": opts.ReleaseAssets,
+ "website": repo.Website,
})
if err != nil {
return err
diff --git a/services/migrations/error.go b/services/migrations/error.go
index 5e0e0742c9..a592989c91 100644
--- a/services/migrations/error.go
+++ b/services/migrations/error.go
@@ -7,7 +7,7 @@ package migrations
import (
"errors"
- "github.com/google/go-github/v57/github"
+ "github.com/google/go-github/v64/github"
)
// ErrRepoNotCreated returns the error that repository not created
diff --git a/services/migrations/forgejo_downloader.go b/services/migrations/forgejo_downloader.go
index 25dbb6ec51..5f809b82be 100644
--- a/services/migrations/forgejo_downloader.go
+++ b/services/migrations/forgejo_downloader.go
@@ -4,7 +4,7 @@
package migrations
import (
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/structs"
)
func init() {
diff --git a/services/migrations/forgejo_downloader_test.go b/services/migrations/forgejo_downloader_test.go
index 5bd37551cc..db1930ebba 100644
--- a/services/migrations/forgejo_downloader_test.go
+++ b/services/migrations/forgejo_downloader_test.go
@@ -6,7 +6,7 @@ package migrations
import (
"testing"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/structs"
"github.com/stretchr/testify/require"
)
diff --git a/services/migrations/git.go b/services/migrations/git.go
index 22ffd5e765..46710b0abe 100644
--- a/services/migrations/git.go
+++ b/services/migrations/git.go
@@ -6,7 +6,7 @@ package migrations
import (
"context"
- base "code.gitea.io/gitea/modules/migration"
+ base "forgejo.org/modules/migration"
)
var _ base.Downloader = &PlainGitDownloader{}
diff --git a/services/migrations/gitbucket.go b/services/migrations/gitbucket.go
index 4fe9e30a39..b68fc01083 100644
--- a/services/migrations/gitbucket.go
+++ b/services/migrations/gitbucket.go
@@ -9,9 +9,9 @@ import (
"net/url"
"strings"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/structs"
)
var (
diff --git a/services/migrations/gitea_downloader.go b/services/migrations/gitea_downloader.go
index 272bf02e11..133cc5c928 100644
--- a/services/migrations/gitea_downloader.go
+++ b/services/migrations/gitea_downloader.go
@@ -13,9 +13,9 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/structs"
gitea_sdk "code.gitea.io/sdk/gitea"
)
@@ -160,6 +160,7 @@ func (g *GiteaDownloader) GetRepoInfo() (*base.Repository, error) {
CloneURL: repo.CloneURL,
OriginalURL: repo.HTMLURL,
DefaultBranch: repo.DefaultBranch,
+ Website: repo.Website,
}, nil
}
@@ -503,6 +504,28 @@ func (g *GiteaDownloader) GetComments(commentable base.Commentable) ([]*base.Com
return allComments, true, nil
}
+type ForgejoPullRequest struct {
+ gitea_sdk.PullRequest
+ Flow int64 `json:"flow"`
+}
+
+// Extracted from https://gitea.com/gitea/go-sdk/src/commit/164e3358bc02213954fb4380b821bed80a14824d/gitea/pull.go#L347-L364
+func (g *GiteaDownloader) fixPullHeadSha(pr *ForgejoPullRequest) error {
+ if pr.Base != nil && pr.Base.Repository != nil && pr.Base.Repository.Owner != nil && pr.Head != nil && pr.Head.Ref != "" && pr.Head.Sha == "" {
+ owner := pr.Base.Repository.Owner.UserName
+ repo := pr.Base.Repository.Name
+ refs, _, err := g.client.GetRepoRefs(owner, repo, pr.Head.Ref)
+ if err != nil {
+ return err
+ }
+ if len(refs) == 0 {
+ return fmt.Errorf("unable to resolve PR ref %q", pr.Head.Ref)
+ }
+ pr.Head.Sha = refs[0].Object.SHA
+ }
+ return nil
+}
+
// GetPullRequests returns pull requests according page and perPage
func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullRequest, bool, error) {
if perPage > g.maxPerPage {
@@ -510,16 +533,30 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques
}
allPRs := make([]*base.PullRequest, 0, perPage)
- prs, _, err := g.client.ListRepoPullRequests(g.repoOwner, g.repoName, gitea_sdk.ListPullRequestsOptions{
+ prs := make([]*ForgejoPullRequest, 0, perPage)
+ opt := gitea_sdk.ListPullRequestsOptions{
ListOptions: gitea_sdk.ListOptions{
Page: page,
PageSize: perPage,
},
State: gitea_sdk.StateAll,
- })
+ }
+
+ link, _ := url.Parse(fmt.Sprintf("/repos/%s/%s/pulls", url.PathEscape(g.repoOwner), url.PathEscape(g.repoName)))
+ link.RawQuery = opt.QueryEncode()
+ _, err := getParsedResponse(g.client, "GET", link.String(), http.Header{"content-type": []string{"application/json"}}, nil, &prs)
if err != nil {
return nil, false, fmt.Errorf("error while listing pull requests (page: %d, pagesize: %d). Error: %w", page, perPage, err)
}
+
+ if g.client.CheckServerVersionConstraint(">= 1.14.0") != nil {
+ for i := range prs {
+ if err := g.fixPullHeadSha(prs[i]); err != nil {
+ return nil, false, fmt.Errorf("error while listing pull requests (page: %d, pagesize: %d). Error: %w", page, perPage, err)
+ }
+ }
+ }
+
for _, pr := range prs {
var milestone string
if pr.Milestone != nil {
@@ -597,6 +634,7 @@ func (g *GiteaDownloader) GetPullRequests(page, perPage int) ([]*base.PullReques
MergeCommitSHA: mergeCommitSHA,
IsLocked: pr.IsLocked,
PatchURL: pr.PatchURL,
+ Flow: pr.Flow,
Head: base.PullRequestBranch{
Ref: headRef,
SHA: headSHA,
diff --git a/services/migrations/gitea_downloader_test.go b/services/migrations/gitea_downloader_test.go
index c37c70947e..24c53af023 100644
--- a/services/migrations/gitea_downloader_test.go
+++ b/services/migrations/gitea_downloader_test.go
@@ -4,57 +4,51 @@
package migrations
import (
- "context"
- "net/http"
"os"
"sort"
"testing"
"time"
- base "code.gitea.io/gitea/modules/migration"
+ "forgejo.org/models/unittest"
+ base "forgejo.org/modules/migration"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGiteaDownloadRepo(t *testing.T) {
- // Skip tests if Gitea token is not found
giteaToken := os.Getenv("GITEA_TOKEN")
- if giteaToken == "" {
- t.Skip("skipped test because GITEA_TOKEN was not in the environment")
- }
- resp, err := http.Get("https://gitea.com/gitea")
- if err != nil || resp.StatusCode != http.StatusOK {
- t.Skipf("Can't reach https://gitea.com, skipping %s", t.Name())
- }
+ fixturePath := "./testdata/gitea/full_download"
+ server := unittest.NewMockWebServer(t, "https://gitea.com", fixturePath, giteaToken != "")
+ defer server.Close()
- downloader, err := NewGiteaDownloader(context.Background(), "https://gitea.com", "gitea/test_repo", "", "", giteaToken)
+ downloader, err := NewGiteaDownloader(t.Context(), server.URL, "gitea/test_repo", "", "", giteaToken)
if downloader == nil {
t.Fatal("NewGitlabDownloader is nil")
}
- if !assert.NoError(t, err) {
- t.Fatal("NewGitlabDownloader error occur")
- }
+ require.NoError(t, err, "NewGitlabDownloader error occur")
repo, err := downloader.GetRepoInfo()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertRepositoryEqual(t, &base.Repository{
Name: "test_repo",
Owner: "gitea",
IsPrivate: false,
Description: "Test repository for testing migration from gitea to gitea",
- CloneURL: "https://gitea.com/gitea/test_repo.git",
- OriginalURL: "https://gitea.com/gitea/test_repo",
+ CloneURL: server.URL + "/gitea/test_repo.git",
+ OriginalURL: server.URL + "/gitea/test_repo",
DefaultBranch: "master",
+ Website: "https://codeberg.org/forgejo/forgejo/",
}, repo)
topics, err := downloader.GetTopics()
- assert.NoError(t, err)
+ require.NoError(t, err)
sort.Strings(topics)
assert.EqualValues(t, []string{"ci", "gitea", "migration", "test"}, topics)
labels, err := downloader.GetLabels()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertLabelsEqual(t, []*base.Label{
{
Name: "Bug",
@@ -84,13 +78,13 @@ func TestGiteaDownloadRepo(t *testing.T) {
}, labels)
milestones, err := downloader.GetMilestones()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertMilestonesEqual(t, []*base.Milestone{
{
Title: "V2 Finalize",
Created: time.Unix(0, 0),
Deadline: timePtr(time.Unix(1599263999, 0)),
- Updated: timePtr(time.Unix(0, 0)),
+ Updated: timePtr(time.Date(2022, 11, 13, 5, 29, 15, 0, time.UTC)),
State: "open",
},
{
@@ -104,7 +98,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
}, milestones)
releases, err := downloader.GetReleases()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertReleasesEqual(t, []*base.Release{
{
Name: "Second Release",
@@ -117,7 +111,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
Published: time.Date(2020, 9, 1, 18, 2, 43, 0, time.UTC),
PublisherID: 689,
PublisherName: "6543",
- PublisherEmail: "6543@obermui.de",
+ PublisherEmail: "6543@noreply.gitea.com",
},
{
Name: "First Release",
@@ -130,18 +124,18 @@ func TestGiteaDownloadRepo(t *testing.T) {
Published: time.Date(2020, 9, 1, 17, 30, 32, 0, time.UTC),
PublisherID: 689,
PublisherName: "6543",
- PublisherEmail: "6543@obermui.de",
+ PublisherEmail: "6543@noreply.gitea.com",
},
}, releases)
issues, isEnd, err := downloader.GetIssues(1, 50)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, isEnd)
assert.Len(t, issues, 7)
assert.EqualValues(t, "open", issues[0].State)
issues, isEnd, err = downloader.GetIssues(3, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, isEnd)
assertIssuesEqual(t, []*base.Issue{
@@ -198,13 +192,13 @@ func TestGiteaDownloadRepo(t *testing.T) {
}, issues)
comments, _, err := downloader.GetComments(&base.Issue{Number: 4, ForeignIndex: 4})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
IssueIndex: 4,
PosterID: 689,
PosterName: "6543",
- PosterEmail: "6543@obermui.de",
+ PosterEmail: "6543@noreply.gitea.com",
Created: time.Unix(1598975370, 0),
Updated: time.Unix(1599070865, 0),
Content: "a really good question!\n\nIt is the used as TESTSET for gitea2gitea repo migration function",
@@ -213,7 +207,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
IssueIndex: 4,
PosterID: -1,
PosterName: "Ghost",
- PosterEmail: "",
+ PosterEmail: "ghost@noreply.gitea.com",
Created: time.Unix(1598975393, 0),
Updated: time.Unix(1598975393, 0),
Content: "Oh!",
@@ -221,11 +215,11 @@ func TestGiteaDownloadRepo(t *testing.T) {
}, comments)
prs, isEnd, err := downloader.GetPullRequests(1, 50)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, isEnd)
assert.Len(t, prs, 6)
prs, isEnd, err = downloader.GetPullRequests(1, 3)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, isEnd)
assert.Len(t, prs, 3)
assertPullRequestEqual(t, &base.PullRequest{
@@ -240,7 +234,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
IsLocked: false,
Created: time.Unix(1598982759, 0),
Updated: time.Unix(1599023425, 0),
- Closed: timePtr(time.Unix(1598982934, 0)),
+ Closed: timePtr(time.Date(2020, 9, 1, 17, 55, 33, 0, time.UTC)),
Assignees: []string{"techknowlogick"},
Base: base.PullRequestBranch{
CloneURL: "",
@@ -250,7 +244,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
OwnerName: "gitea",
},
Head: base.PullRequestBranch{
- CloneURL: "https://gitea.com/6543-forks/test_repo.git",
+ CloneURL: server.URL + "/6543-forks/test_repo.git",
Ref: "refs/pull/12/head",
SHA: "b6ab5d9ae000b579a5fff03f92c486da4ddf48b6",
RepoName: "test_repo",
@@ -259,11 +253,11 @@ func TestGiteaDownloadRepo(t *testing.T) {
Merged: true,
MergedTime: timePtr(time.Unix(1598982934, 0)),
MergeCommitSHA: "827aa28a907853e5ddfa40c8f9bc52471a2685fd",
- PatchURL: "https://gitea.com/gitea/test_repo/pulls/12.patch",
+ PatchURL: server.URL + "/gitea/test_repo/pulls/12.patch",
}, prs[1])
reviews, err := downloader.GetReviews(&base.Issue{Number: 7, ForeignIndex: 7})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
ID: 1770,
@@ -286,7 +280,7 @@ func TestGiteaDownloadRepo(t *testing.T) {
PosterID: 689,
Reactions: nil,
CreatedAt: time.Date(2020, 9, 1, 16, 12, 58, 0, time.UTC),
- UpdatedAt: time.Date(2020, 9, 1, 16, 12, 58, 0, time.UTC),
+ UpdatedAt: time.Date(2024, 6, 3, 1, 18, 36, 0, time.UTC),
},
},
},
@@ -313,3 +307,46 @@ func TestGiteaDownloadRepo(t *testing.T) {
},
}, reviews)
}
+
+func TestForgejoDownloadRepo(t *testing.T) {
+ token := os.Getenv("CODE_FORGEJO_TOKEN")
+
+ fixturePath := "./testdata/code-forgejo-org/full_download"
+ server := unittest.NewMockWebServer(t, "https://code.forgejo.org", fixturePath, token != "")
+ defer server.Close()
+
+ downloader, err := NewGiteaDownloader(t.Context(), server.URL, "Gusted/agit-test", "", "", token)
+ require.NoError(t, err)
+ require.NotNil(t, downloader)
+
+ prs, _, err := downloader.GetPullRequests(1, 50)
+ require.NoError(t, err)
+ assert.Len(t, prs, 1)
+
+ assertPullRequestEqual(t, &base.PullRequest{
+ Number: 1,
+ PosterID: 63,
+ PosterName: "Gusted",
+ PosterEmail: "postmaster@gusted.xyz",
+ Title: "Add extra information",
+ State: "open",
+ Created: time.Date(2025, time.April, 1, 20, 28, 45, 0, time.UTC),
+ Updated: time.Date(2025, time.April, 1, 20, 28, 45, 0, time.UTC),
+ Base: base.PullRequestBranch{
+ CloneURL: "",
+ Ref: "main",
+ SHA: "79ebb873a6497c8847141ba9706b3f757196a1e6",
+ RepoName: "agit-test",
+ OwnerName: "Gusted",
+ },
+ Head: base.PullRequestBranch{
+ CloneURL: server.URL + "/Gusted/agit-test.git",
+ Ref: "refs/pull/1/head",
+ SHA: "667e9317ec37b977e6d3d7d43e3440636970563c",
+ RepoName: "agit-test",
+ OwnerName: "Gusted",
+ },
+ PatchURL: server.URL + "/Gusted/agit-test/pulls/1.patch",
+ Flow: 1,
+ }, prs[0])
+}
diff --git a/services/migrations/gitea_sdk_hack.go b/services/migrations/gitea_sdk_hack.go
new file mode 100644
index 0000000000..f3959717a8
--- /dev/null
+++ b/services/migrations/gitea_sdk_hack.go
@@ -0,0 +1,16 @@
+// Copyright 2025 The Forgejo Authors. All rights reserved.
+// SPDX-License-Identifier: GPL-3.0-or-later
+
+package migrations
+
+import (
+ "io"
+ "net/http"
+
+ _ "unsafe" // Needed for go:linkname support
+
+ gitea_sdk "code.gitea.io/sdk/gitea"
+)
+
+//go:linkname getParsedResponse code.gitea.io/sdk/gitea.(*Client).getParsedResponse
+func getParsedResponse(client *gitea_sdk.Client, method, path string, header http.Header, body io.Reader, obj any) (*gitea_sdk.Response, error)
diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go
index 3ba4ca203b..55adad9685 100644
--- a/services/migrations/gitea_uploader.go
+++ b/services/migrations/gitea_uploader.go
@@ -14,26 +14,26 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/models"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- user_model "code.gitea.io/gitea/models/user"
- base_module "code.gitea.io/gitea/modules/base"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/label"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- repo_module "code.gitea.io/gitea/modules/repository"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/storage"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/timeutil"
- "code.gitea.io/gitea/modules/uri"
- "code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/services/pull"
- repo_service "code.gitea.io/gitea/services/repository"
+ "forgejo.org/models"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ user_model "forgejo.org/models/user"
+ base_module "forgejo.org/modules/base"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/label"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ repo_module "forgejo.org/modules/repository"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/storage"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/timeutil"
+ "forgejo.org/modules/uri"
+ "forgejo.org/modules/util"
+ "forgejo.org/services/pull"
+ repo_service "forgejo.org/services/repository"
"github.com/google/uuid"
)
@@ -105,6 +105,7 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
r, err = repo_service.CreateRepositoryDirectly(g.ctx, g.doer, owner, repo_service.CreateRepoOptions{
Name: g.repoName,
Description: repo.Description,
+ Website: repo.Website,
OriginalURL: repo.OriginalURL,
GitServiceType: opts.GitServiceType,
IsPrivate: opts.Private || setting.Repository.ForcePrivate,
@@ -119,20 +120,17 @@ func (g *GiteaLocalUploader) CreateRepo(repo *base.Repository, opts base.Migrate
}
r.DefaultBranch = repo.DefaultBranch
r.Description = repo.Description
+ r.Website = repo.Website
r, err = repo_service.MigrateRepositoryGitData(g.ctx, owner, r, base.MigrateOptions{
- RepoName: g.repoName,
- Description: repo.Description,
- OriginalURL: repo.OriginalURL,
- GitServiceType: opts.GitServiceType,
- Mirror: repo.IsMirror,
+ CloneAddr: repo.CloneURL, // SECURITY: we will assume that this has already been checked
LFS: opts.LFS,
LFSEndpoint: opts.LFSEndpoint,
- CloneAddr: repo.CloneURL, // SECURITY: we will assume that this has already been checked
- Private: repo.IsPrivate,
- Wiki: opts.Wiki,
- Releases: opts.Releases, // if didn't get releases, then sync them from tags
+ Mirror: repo.IsMirror,
MirrorInterval: opts.MirrorInterval,
+ Releases: opts.Releases, // if didn't get releases, then sync them from tags
+ RepoName: g.repoName,
+ Wiki: opts.Wiki,
}, NewMigrationHTTPTransport())
g.sameApp = strings.HasPrefix(repo.OriginalURL, setting.AppURL)
@@ -760,10 +758,15 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model
pr.Updated = pr.Created
}
+ prTitle := pr.Title
+ if pr.IsDraft && !issues_model.HasWorkInProgressPrefix(pr.Title) {
+ prTitle = fmt.Sprintf("%s %s", setting.Repository.PullRequest.WorkInProgressPrefixes[0], pr.Title)
+ }
+
issue := issues_model.Issue{
RepoID: g.repo.ID,
Repo: g.repo,
- Title: pr.Title,
+ Title: prTitle,
Index: pr.Number,
Content: pr.Content,
MilestoneID: milestoneID,
@@ -799,6 +802,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*issues_model
MergeBase: pr.Base.SHA,
Index: pr.Number,
HasMerged: pr.Merged,
+ Flow: issues_model.PullRequestFlow(pr.Flow),
Issue: &issue,
}
diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go
index 35da8290c8..e07c621acc 100644
--- a/services/migrations/gitea_uploader_test.go
+++ b/services/migrations/gitea_uploader_test.go
@@ -5,7 +5,6 @@
package migrations
import (
- "context"
"fmt"
"os"
"path/filepath"
@@ -13,21 +12,22 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/db"
- issues_model "code.gitea.io/gitea/models/issues"
- repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/gitrepo"
- "code.gitea.io/gitea/modules/graceful"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/optional"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/test"
+ "forgejo.org/models/db"
+ issues_model "forgejo.org/models/issues"
+ repo_model "forgejo.org/models/repo"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/gitrepo"
+ "forgejo.org/modules/graceful"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/optional"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/test"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGiteaUploadRepo(t *testing.T) {
@@ -39,7 +39,7 @@ func TestGiteaUploadRepo(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
var (
- ctx = context.Background()
+ ctx = t.Context()
downloader = NewGithubDownloaderV3(ctx, "https://github.com", "", "", "", "go-xorm", "builder")
repoName = "builder-" + time.Now().Format("2006-01-02-15-04-05")
uploader = NewGiteaLocalUploader(graceful.GetManager().HammerContext(), user, user.Name, repoName)
@@ -60,7 +60,7 @@ func TestGiteaUploadRepo(t *testing.T) {
Private: true,
Mirror: false,
}, nil)
- assert.NoError(t, err)
+ require.NoError(t, err)
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: repoName})
assert.True(t, repo.HasWiki())
@@ -70,18 +70,18 @@ func TestGiteaUploadRepo(t *testing.T) {
RepoID: repo.ID,
IsClosed: optional.Some(false),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, milestones, 1)
milestones, err = db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{
RepoID: repo.ID,
IsClosed: optional.Some(true),
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Empty(t, milestones)
labels, err := issues_model.GetLabelsByRepoID(ctx, repo.ID, "", db.ListOptions{})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, labels, 12)
releases, err := db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{
@@ -92,7 +92,7 @@ func TestGiteaUploadRepo(t *testing.T) {
IncludeTags: true,
RepoID: repo.ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, releases, 8)
releases, err = db.Find[repo_model.Release](db.DefaultContext, repo_model.FindReleasesOptions{
@@ -103,7 +103,7 @@ func TestGiteaUploadRepo(t *testing.T) {
IncludeTags: false,
RepoID: repo.ID,
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, releases, 1)
issues, err := issues_model.Issues(db.DefaultContext, &issues_model.IssuesOptions{
@@ -111,18 +111,18 @@ func TestGiteaUploadRepo(t *testing.T) {
IsPull: optional.Some(false),
SortType: "oldest",
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, issues, 15)
- assert.NoError(t, issues[0].LoadDiscussComments(db.DefaultContext))
+ require.NoError(t, issues[0].LoadDiscussComments(db.DefaultContext))
assert.Empty(t, issues[0].Comments)
pulls, _, err := issues_model.PullRequests(db.DefaultContext, repo.ID, &issues_model.PullRequestsOptions{
SortType: "oldest",
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, pulls, 30)
- assert.NoError(t, pulls[0].LoadIssue(db.DefaultContext))
- assert.NoError(t, pulls[0].Issue.LoadDiscussComments(db.DefaultContext))
+ require.NoError(t, pulls[0].LoadIssue(db.DefaultContext))
+ require.NoError(t, pulls[0].Issue.LoadDiscussComments(db.DefaultContext))
assert.Len(t, pulls[0].Issue.Comments, 2)
}
@@ -132,7 +132,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repoName := "migrated"
- uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName)
+ uploader := NewGiteaLocalUploader(t.Context(), doer, doer.Name, repoName)
// call remapLocalUser
uploader.sameApp = true
@@ -150,7 +150,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) {
target := repo_model.Release{}
uploader.userMap = make(map[int64]int64)
err := uploader.remapUser(&source, &target)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, user_model.GhostUserID, target.GetUserID())
//
@@ -161,7 +161,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) {
target = repo_model.Release{}
uploader.userMap = make(map[int64]int64)
err = uploader.remapUser(&source, &target)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, user_model.GhostUserID, target.GetUserID())
//
@@ -172,7 +172,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) {
target = repo_model.Release{}
uploader.userMap = make(map[int64]int64)
err = uploader.remapUser(&source, &target)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, user.ID, target.GetUserID())
}
@@ -181,7 +181,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
repoName := "migrated"
- uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName)
+ uploader := NewGiteaLocalUploader(t.Context(), doer, doer.Name, repoName)
uploader.gitServiceType = structs.GiteaService
// call remapExternalUser
uploader.sameApp = false
@@ -200,7 +200,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
uploader.userMap = make(map[int64]int64)
target := repo_model.Release{}
err := uploader.remapUser(&source, &target)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, user_model.GhostUserID, target.GetUserID())
//
@@ -214,7 +214,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
Provider: structs.GiteaService.Name(),
}
err = user_model.LinkExternalToUser(db.DefaultContext, linkedUser, externalLoginUser)
- assert.NoError(t, err)
+ require.NoError(t, err)
//
// When a user is linked to the external ID, it becomes the author of
@@ -223,7 +223,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
uploader.userMap = make(map[int64]int64)
target = repo_model.Release{}
err = uploader.remapUser(&source, &target)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, linkedUser.ID, target.GetUserID())
}
@@ -235,44 +235,44 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
//
fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
baseRef := "master"
- assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormatName))
+ require.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormatName))
err := git.NewCommand(git.DefaultContext, "symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(&git.RunOpts{Dir: fromRepo.RepoPath()})
- assert.NoError(t, err)
- assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", fromRepo.RepoPath())), 0o644))
- assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true))
+ require.NoError(t, err)
+ require.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", fromRepo.RepoPath())), 0o644))
+ require.NoError(t, git.AddChanges(fromRepo.RepoPath(), true))
signature := git.Signature{
Email: "test@example.com",
Name: "test",
When: time.Now(),
}
- assert.NoError(t, git.CommitChanges(fromRepo.RepoPath(), git.CommitChangesOptions{
+ require.NoError(t, git.CommitChanges(fromRepo.RepoPath(), git.CommitChangesOptions{
Committer: &signature,
Author: &signature,
Message: "Initial Commit",
}))
fromGitRepo, err := gitrepo.OpenRepository(git.DefaultContext, fromRepo)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer fromGitRepo.Close()
baseSHA, err := fromGitRepo.GetBranchCommitID(baseRef)
- assert.NoError(t, err)
+ require.NoError(t, err)
//
// fromRepo branch1
//
headRef := "branch1"
_, _, err = git.NewCommand(git.DefaultContext, "checkout", "-b").AddDynamicArguments(headRef).RunStdString(&git.RunOpts{Dir: fromRepo.RepoPath()})
- assert.NoError(t, err)
- assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("SOMETHING"), 0o644))
- assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true))
+ require.NoError(t, err)
+ require.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("SOMETHING"), 0o644))
+ require.NoError(t, git.AddChanges(fromRepo.RepoPath(), true))
signature.When = time.Now()
- assert.NoError(t, git.CommitChanges(fromRepo.RepoPath(), git.CommitChangesOptions{
+ require.NoError(t, git.CommitChanges(fromRepo.RepoPath(), git.CommitChangesOptions{
Committer: &signature,
Author: &signature,
Message: "Pull request",
}))
- assert.NoError(t, err)
+ require.NoError(t, err)
headSHA, err := fromGitRepo.GetBranchCommitID(headRef)
- assert.NoError(t, err)
+ require.NoError(t, err)
fromRepoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: fromRepo.OwnerID})
@@ -281,28 +281,28 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
//
forkHeadRef := "branch2"
forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8})
- assert.NoError(t, git.CloneWithArgs(git.DefaultContext, nil, fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{
+ require.NoError(t, git.CloneWithArgs(git.DefaultContext, nil, fromRepo.RepoPath(), forkRepo.RepoPath(), git.CloneRepoOptions{
Branch: headRef,
}))
_, _, err = git.NewCommand(git.DefaultContext, "checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(&git.RunOpts{Dir: forkRepo.RepoPath()})
- assert.NoError(t, err)
- assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# branch2 %s", forkRepo.RepoPath())), 0o644))
- assert.NoError(t, git.AddChanges(forkRepo.RepoPath(), true))
- assert.NoError(t, git.CommitChanges(forkRepo.RepoPath(), git.CommitChangesOptions{
+ require.NoError(t, err)
+ require.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# branch2 %s", forkRepo.RepoPath())), 0o644))
+ require.NoError(t, git.AddChanges(forkRepo.RepoPath(), true))
+ require.NoError(t, git.CommitChanges(forkRepo.RepoPath(), git.CommitChangesOptions{
Committer: &signature,
Author: &signature,
Message: "branch2 commit",
}))
forkGitRepo, err := gitrepo.OpenRepository(git.DefaultContext, forkRepo)
- assert.NoError(t, err)
+ require.NoError(t, err)
defer forkGitRepo.Close()
forkHeadSHA, err := forkGitRepo.GetBranchCommitID(forkHeadRef)
- assert.NoError(t, err)
+ require.NoError(t, err)
toRepoName := "migrated"
- uploader := NewGiteaLocalUploader(context.Background(), fromRepoOwner, fromRepoOwner.Name, toRepoName)
+ uploader := NewGiteaLocalUploader(t.Context(), fromRepoOwner, fromRepoOwner.Name, toRepoName)
uploader.gitServiceType = structs.GiteaService
- assert.NoError(t, uploader.CreateRepo(&base.Repository{
+ require.NoError(t, uploader.CreateRepo(&base.Repository{
Description: "description",
OriginalURL: fromRepo.RepoPath(),
CloneURL: fromRepo.RepoPath(),
@@ -503,7 +503,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
testCase.pr.EnsuredSafe = true
head, err := uploader.updateGitForPullRequest(&testCase.pr)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.EqualValues(t, testCase.head, head)
log.Info(stopMark)
diff --git a/services/migrations/github.go b/services/migrations/github.go
index 78abe9dbbb..5052a68114 100644
--- a/services/migrations/github.go
+++ b/services/migrations/github.go
@@ -14,13 +14,13 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/git"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/proxy"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/git"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/proxy"
+ "forgejo.org/modules/structs"
- "github.com/google/go-github/v57/github"
+ "github.com/google/go-github/v64/github"
"golang.org/x/oauth2"
)
@@ -45,6 +45,11 @@ func (f *GithubDownloaderV3Factory) New(ctx context.Context, opts base.MigrateOp
return nil, err
}
+ // some users are using the github redirect url for migration
+ if u.Host == "www.github.com" {
+ u.Host = "github.com"
+ }
+
baseURL := u.Scheme + "://" + u.Host
fields := strings.Split(u.Path, "/")
oldOwner := fields[1]
@@ -215,6 +220,7 @@ func (g *GithubDownloaderV3) GetRepoInfo() (*base.Repository, error) {
OriginalURL: gr.GetHTMLURL(),
CloneURL: gr.GetCloneURL(),
DefaultBranch: gr.GetDefaultBranch(),
+ Website: gr.GetHomepage(),
}, nil
}
@@ -737,6 +743,7 @@ func (g *GithubDownloaderV3) GetPullRequests(page, perPage int) ([]*base.PullReq
PatchURL: pr.GetPatchURL(), // see below for SECURITY related issues here
Reactions: reactions,
ForeignIndex: int64(*pr.Number),
+ IsDraft: pr.GetDraft(),
})
// SECURITY: Ensure that the PR is safe
diff --git a/services/migrations/github_test.go b/services/migrations/github_test.go
index 2b89e6dc0f..b1f20c4716 100644
--- a/services/migrations/github_test.go
+++ b/services/migrations/github_test.go
@@ -5,43 +5,47 @@
package migrations
import (
- "context"
"os"
"testing"
"time"
- base "code.gitea.io/gitea/modules/migration"
+ "forgejo.org/models/unittest"
+ base "forgejo.org/modules/migration"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGitHubDownloadRepo(t *testing.T) {
GithubLimitRateRemaining = 3 // Wait at 3 remaining since we could have 3 CI in //
+
token := os.Getenv("GITHUB_READ_TOKEN")
- if token == "" {
- t.Skip("Skipping GitHub migration test because GITHUB_READ_TOKEN is empty")
- }
- downloader := NewGithubDownloaderV3(context.Background(), "https://github.com", "", "", token, "go-gitea", "test_repo")
+ fixturePath := "./testdata/github/full_download"
+ server := unittest.NewMockWebServer(t, "https://api.github.com", fixturePath, token != "")
+ defer server.Close()
+
+ downloader := NewGithubDownloaderV3(t.Context(), server.URL, "", "", token, "go-gitea", "test_repo")
err := downloader.RefreshRate()
- assert.NoError(t, err)
+ require.NoError(t, err)
repo, err := downloader.GetRepoInfo()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertRepositoryEqual(t, &base.Repository{
Name: "test_repo",
Owner: "go-gitea",
Description: "Test repository for testing migration from github to gitea",
- CloneURL: "https://github.com/go-gitea/test_repo.git",
- OriginalURL: "https://github.com/go-gitea/test_repo",
+ CloneURL: server.URL + "/go-gitea/test_repo.git",
+ OriginalURL: server.URL + "/go-gitea/test_repo",
DefaultBranch: "master",
+ Website: "https://codeberg.org/forgejo/forgejo/",
}, repo)
topics, err := downloader.GetTopics()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Contains(t, topics, "gitea")
milestones, err := downloader.GetMilestones()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertMilestonesEqual(t, []*base.Milestone{
{
Title: "1.0.0",
@@ -64,7 +68,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
}, milestones)
labels, err := downloader.GetLabels()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertLabelsEqual(t, []*base.Label{
{
Name: "bug",
@@ -114,7 +118,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
}, labels)
releases, err := downloader.GetReleases()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertReleasesEqual(t, []*base.Release{
{
TagName: "v0.9.99",
@@ -130,7 +134,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
// downloader.GetIssues()
issues, isEnd, err := downloader.GetIssues(1, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, isEnd)
assertIssuesEqual(t, []*base.Issue{
{
@@ -219,7 +223,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
// downloader.GetComments()
comments, _, err := downloader.GetComments(&base.Issue{Number: 2, ForeignIndex: 2})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
IssueIndex: 2,
@@ -249,7 +253,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
// downloader.GetPullRequests()
prs, _, err := downloader.GetPullRequests(1, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assertPullRequestsEqual(t, []*base.PullRequest{
{
Number: 3,
@@ -268,10 +272,10 @@ func TestGitHubDownloadRepo(t *testing.T) {
Description: "Improvements or additions to documentation",
},
},
- PatchURL: "https://github.com/go-gitea/test_repo/pull/3.patch",
+ PatchURL: server.URL + "/go-gitea/test_repo/pull/3.patch",
Head: base.PullRequestBranch{
Ref: "master",
- CloneURL: "https://github.com/mrsdizzie/test_repo.git",
+ CloneURL: server.URL + "/mrsdizzie/test_repo.git",
SHA: "076160cf0b039f13e5eff19619932d181269414b",
RepoName: "test_repo",
@@ -306,13 +310,13 @@ func TestGitHubDownloadRepo(t *testing.T) {
Description: "Something isn't working",
},
},
- PatchURL: "https://github.com/go-gitea/test_repo/pull/4.patch",
+ PatchURL: server.URL + "/go-gitea/test_repo/pull/4.patch",
Head: base.PullRequestBranch{
Ref: "test-branch",
SHA: "2be9101c543658591222acbee3eb799edfc3853d",
RepoName: "test_repo",
OwnerName: "mrsdizzie",
- CloneURL: "https://github.com/mrsdizzie/test_repo.git",
+ CloneURL: server.URL + "/mrsdizzie/test_repo.git",
},
Base: base.PullRequestBranch{
Ref: "master",
@@ -339,7 +343,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
}, prs)
reviews, err := downloader.GetReviews(&base.PullRequest{Number: 3, ForeignIndex: 3})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
ID: 315859956,
@@ -371,7 +375,7 @@ func TestGitHubDownloadRepo(t *testing.T) {
}, reviews)
reviews, err = downloader.GetReviews(&base.PullRequest{Number: 4, ForeignIndex: 4})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
ID: 338338740,
diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go
index 065b687fa6..ac0d3bcf7a 100644
--- a/services/migrations/gitlab.go
+++ b/services/migrations/gitlab.go
@@ -15,13 +15,14 @@ import (
"strings"
"time"
- issues_model "code.gitea.io/gitea/models/issues"
- "code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/structs"
+ issues_model "forgejo.org/models/issues"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/container"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/structs"
- "github.com/xanzy/go-gitlab"
+ gitlab "gitlab.com/gitlab-org/api/client-go"
)
var (
@@ -301,9 +302,10 @@ func (g *GitlabDownloader) GetLabels() ([]*base.Label, error) {
}
for _, label := range ls {
baseLabel := &base.Label{
- Name: label.Name,
+ Name: strings.Replace(label.Name, "::", "/", 1),
Color: g.normalizeColor(label.Color),
Description: label.Description,
+ Exclusive: strings.Contains(label.Name, "::"),
}
labels = append(labels, baseLabel)
}
@@ -424,7 +426,7 @@ func (g *GitlabDownloader) GetIssues(page, perPage int) ([]*base.Issue, bool, er
labels := make([]*base.Label, 0, len(issue.Labels))
for _, l := range issue.Labels {
labels = append(labels, &base.Label{
- Name: l,
+ Name: strings.Replace(l, "::", "/", 1),
})
}
@@ -542,11 +544,19 @@ func (g *GitlabDownloader) GetComments(commentable base.Commentable) ([]*base.Co
}
for _, stateEvent := range stateEvents {
+ // If the user is deleted, then `stateEvent.User == nil` holds. Fallback
+ // to the Ghost user in that case.
+ posterID := int64(user_model.GhostUserID)
+ posterName := user_model.GhostUserName
+ if stateEvent.User != nil {
+ posterID = int64(stateEvent.User.ID)
+ posterName = stateEvent.User.Username
+ }
comment := &base.Comment{
IssueIndex: commentable.GetLocalIndex(),
Index: int64(stateEvent.ID),
- PosterID: int64(stateEvent.User.ID),
- PosterName: stateEvent.User.Username,
+ PosterID: posterID,
+ PosterName: posterName,
Content: "",
Created: *stateEvent.CreatedAt,
}
@@ -635,7 +645,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
labels := make([]*base.Label, 0, len(pr.Labels))
for _, l := range pr.Labels {
labels = append(labels, &base.Label{
- Name: l,
+ Name: strings.Replace(l, "::", "/", 1),
})
}
@@ -722,6 +732,7 @@ func (g *GitlabDownloader) GetPullRequests(page, perPage int) ([]*base.PullReque
PatchURL: pr.WebURL + ".patch",
ForeignIndex: int64(pr.IID),
Context: gitlabIssueContext{IsMergeRequest: true},
+ IsDraft: pr.Draft,
})
// SECURITY: Ensure that the PR is safe
diff --git a/services/migrations/gitlab_test.go b/services/migrations/gitlab_test.go
index 6e5ab86720..924dab5144 100644
--- a/services/migrations/gitlab_test.go
+++ b/services/migrations/gitlab_test.go
@@ -4,7 +4,6 @@
package migrations
import (
- "context"
"fmt"
"net/http"
"net/http/httptest"
@@ -13,12 +12,13 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/unittest"
- "code.gitea.io/gitea/modules/json"
- base "code.gitea.io/gitea/modules/migration"
+ "forgejo.org/models/unittest"
+ "forgejo.org/modules/json"
+ base "forgejo.org/modules/migration"
"github.com/stretchr/testify/assert"
- "github.com/xanzy/go-gitlab"
+ "github.com/stretchr/testify/require"
+ gitlab "gitlab.com/gitlab-org/api/client-go"
)
func TestGitlabDownloadRepo(t *testing.T) {
@@ -30,47 +30,47 @@ func TestGitlabDownloadRepo(t *testing.T) {
server := unittest.NewMockWebServer(t, "https://gitlab.com", fixturePath, gitlabPersonalAccessToken != "")
defer server.Close()
- downloader, err := NewGitlabDownloader(context.Background(), server.URL, "gitea/test_repo", "", "", gitlabPersonalAccessToken)
+ downloader, err := NewGitlabDownloader(t.Context(), server.URL, "forgejo/test_repo", "", "", gitlabPersonalAccessToken)
if err != nil {
t.Fatalf("NewGitlabDownloader is nil: %v", err)
}
repo, err := downloader.GetRepoInfo()
- assert.NoError(t, err)
+ require.NoError(t, err)
// Repo Owner is blank in Gitlab Group repos
assertRepositoryEqual(t, &base.Repository{
Name: "test_repo",
Owner: "",
- Description: "Test repository for testing migration from gitlab to gitea",
- CloneURL: server.URL + "/gitea/test_repo.git",
- OriginalURL: server.URL + "/gitea/test_repo",
+ Description: "Test repository for testing migration from gitlab to forgejo",
+ CloneURL: server.URL + "/forgejo/test_repo.git",
+ OriginalURL: server.URL + "/forgejo/test_repo",
DefaultBranch: "master",
}, repo)
topics, err := downloader.GetTopics()
- assert.NoError(t, err)
- assert.True(t, len(topics) == 2)
+ require.NoError(t, err)
+ assert.Len(t, topics, 2)
assert.EqualValues(t, []string{"migration", "test"}, topics)
milestones, err := downloader.GetMilestones()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertMilestonesEqual(t, []*base.Milestone{
{
- Title: "1.1.0",
- Created: time.Date(2019, 11, 28, 8, 42, 44, 575000000, time.UTC),
- Updated: timePtr(time.Date(2019, 11, 28, 8, 42, 44, 575000000, time.UTC)),
- State: "active",
+ Title: "1.0.0",
+ Created: time.Date(2024, 9, 3, 13, 53, 8, 516000000, time.UTC),
+ Updated: timePtr(time.Date(2024, 9, 3, 20, 3, 57, 786000000, time.UTC)),
+ Closed: timePtr(time.Date(2024, 9, 3, 20, 3, 57, 786000000, time.UTC)),
+ State: "closed",
},
{
- Title: "1.0.0",
- Created: time.Date(2019, 11, 28, 8, 42, 30, 301000000, time.UTC),
- Updated: timePtr(time.Date(2019, 11, 28, 15, 57, 52, 401000000, time.UTC)),
- Closed: timePtr(time.Date(2019, 11, 28, 15, 57, 52, 401000000, time.UTC)),
- State: "closed",
+ Title: "1.1.0",
+ Created: time.Date(2024, 9, 3, 13, 52, 48, 414000000, time.UTC),
+ Updated: timePtr(time.Date(2024, 9, 3, 14, 52, 14, 93000000, time.UTC)),
+ State: "active",
},
}, milestones)
labels, err := downloader.GetLabels()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertLabelsEqual(t, []*base.Label{
{
Name: "bug",
@@ -108,37 +108,47 @@ func TestGitlabDownloadRepo(t *testing.T) {
Name: "support",
Color: "f0ad4e",
},
+ {
+ Name: "test-scope/label0",
+ Color: "6699cc",
+ Description: "scoped label",
+ Exclusive: true,
+ },
+ {
+ Name: "test-scope/label1",
+ Color: "dc143c",
+ Exclusive: true,
+ },
}, labels)
releases, err := downloader.GetReleases()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertReleasesEqual(t, []*base.Release{
{
TagName: "v0.9.99",
TargetCommitish: "0720a3ec57c1f843568298117b874319e7deee75",
Name: "First Release",
Body: "A test release",
- Created: time.Date(2019, 11, 28, 9, 9, 48, 840000000, time.UTC),
- PublisherID: 1241334,
- PublisherName: "lafriks",
+ Created: time.Date(2024, 9, 3, 15, 1, 1, 513000000, time.UTC),
+ PublisherID: 548513,
+ PublisherName: "mkobel",
},
}, releases)
issues, isEnd, err := downloader.GetIssues(1, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, isEnd)
-
assertIssuesEqual(t, []*base.Issue{
{
Number: 1,
Title: "Please add an animated gif icon to the merge button",
Content: "I just want the merge button to hurt my eyes a little. :stuck_out_tongue_closed_eyes:",
Milestone: "1.0.0",
- PosterID: 1241334,
- PosterName: "lafriks",
+ PosterID: 548513,
+ PosterName: "mkobel",
State: "closed",
- Created: time.Date(2019, 11, 28, 8, 43, 35, 459000000, time.UTC),
- Updated: time.Date(2019, 11, 28, 8, 46, 23, 304000000, time.UTC),
+ Created: time.Date(2024, 9, 3, 14, 42, 34, 924000000, time.UTC),
+ Updated: time.Date(2024, 9, 3, 14, 48, 43, 756000000, time.UTC),
Labels: []*base.Label{
{
Name: "bug",
@@ -149,28 +159,28 @@ func TestGitlabDownloadRepo(t *testing.T) {
},
Reactions: []*base.Reaction{
{
- UserID: 1241334,
- UserName: "lafriks",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "thumbsup",
},
{
- UserID: 1241334,
- UserName: "lafriks",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "open_mouth",
},
},
- Closed: timePtr(time.Date(2019, 11, 28, 8, 46, 23, 275000000, time.UTC)),
+ Closed: timePtr(time.Date(2024, 9, 3, 14, 43, 10, 708000000, time.UTC)),
},
{
Number: 2,
Title: "Test issue",
Content: "This is test issue 2, do not touch!",
- Milestone: "1.1.0",
- PosterID: 1241334,
- PosterName: "lafriks",
+ Milestone: "1.0.0",
+ PosterID: 548513,
+ PosterName: "mkobel",
State: "closed",
- Created: time.Date(2019, 11, 28, 8, 44, 46, 277000000, time.UTC),
- Updated: time.Date(2019, 11, 28, 8, 45, 44, 987000000, time.UTC),
+ Created: time.Date(2024, 9, 3, 14, 42, 35, 371000000, time.UTC),
+ Updated: time.Date(2024, 9, 3, 20, 3, 43, 536000000, time.UTC),
Labels: []*base.Label{
{
Name: "duplicate",
@@ -178,37 +188,37 @@ func TestGitlabDownloadRepo(t *testing.T) {
},
Reactions: []*base.Reaction{
{
- UserID: 1241334,
- UserName: "lafriks",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "thumbsup",
},
{
- UserID: 1241334,
- UserName: "lafriks",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "thumbsdown",
},
{
- UserID: 1241334,
- UserName: "lafriks",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "laughing",
},
{
- UserID: 1241334,
- UserName: "lafriks",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "tada",
},
{
- UserID: 1241334,
- UserName: "lafriks",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "confused",
},
{
- UserID: 1241334,
- UserName: "lafriks",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "hearts",
},
},
- Closed: timePtr(time.Date(2019, 11, 28, 8, 45, 44, 959000000, time.UTC)),
+ Closed: timePtr(time.Date(2024, 9, 3, 14, 43, 10, 906000000, time.UTC)),
},
}, issues)
@@ -217,80 +227,76 @@ func TestGitlabDownloadRepo(t *testing.T) {
ForeignIndex: 2,
Context: gitlabIssueContext{IsMergeRequest: false},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
IssueIndex: 2,
- PosterID: 1241334,
- PosterName: "lafriks",
- Created: time.Date(2019, 11, 28, 8, 44, 52, 501000000, time.UTC),
+ PosterID: 548513,
+ PosterName: "mkobel",
+ Created: time.Date(2024, 9, 3, 14, 45, 20, 848000000, time.UTC),
Content: "This is a comment",
Reactions: nil,
},
{
IssueIndex: 2,
- PosterID: 1241334,
- PosterName: "lafriks",
- Created: time.Date(2019, 11, 28, 8, 45, 2, 329000000, time.UTC),
- Content: "changed milestone to %2",
- Reactions: nil,
- },
- {
- IssueIndex: 2,
- PosterID: 1241334,
- PosterName: "lafriks",
- Created: time.Date(2019, 11, 28, 8, 45, 45, 7000000, time.UTC),
- Content: "closed",
- Reactions: nil,
- },
- {
- IssueIndex: 2,
- PosterID: 1241334,
- PosterName: "lafriks",
- Created: time.Date(2019, 11, 28, 8, 45, 53, 501000000, time.UTC),
+ PosterID: 548513,
+ PosterName: "mkobel",
+ Created: time.Date(2024, 9, 3, 14, 45, 30, 59000000, time.UTC),
Content: "A second comment",
Reactions: nil,
},
+ {
+ IssueIndex: 2,
+ PosterID: 548513,
+ PosterName: "mkobel",
+ Created: time.Date(2024, 9, 3, 14, 43, 10, 947000000, time.UTC),
+ Content: "",
+ Reactions: nil,
+ CommentType: "close",
+ },
}, comments)
prs, _, err := downloader.GetPullRequests(1, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assertPullRequestsEqual(t, []*base.PullRequest{
{
- Number: 4,
+ Number: 3,
Title: "Test branch",
Content: "do not merge this PR",
- Milestone: "1.0.0",
- PosterID: 1241334,
- PosterName: "lafriks",
+ Milestone: "1.1.0",
+ PosterID: 2005797,
+ PosterName: "oliverpool",
State: "opened",
- Created: time.Date(2019, 11, 28, 15, 56, 54, 104000000, time.UTC),
+ Created: time.Date(2024, 9, 3, 7, 57, 19, 866000000, time.UTC),
Labels: []*base.Label{
{
- Name: "bug",
+ Name: "test-scope/label0",
+ },
+ {
+ Name: "test-scope/label1",
},
},
Reactions: []*base.Reaction{{
- UserID: 4575606,
- UserName: "real6543",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "thumbsup",
}, {
- UserID: 4575606,
- UserName: "real6543",
+ UserID: 548513,
+ UserName: "mkobel",
Content: "tada",
}},
- PatchURL: server.URL + "/gitea/test_repo/-/merge_requests/2.patch",
+ PatchURL: server.URL + "/forgejo/test_repo/-/merge_requests/1.patch",
Head: base.PullRequestBranch{
Ref: "feat/test",
- CloneURL: server.URL + "/gitea/test_repo/-/merge_requests/2",
+ CloneURL: server.URL + "/forgejo/test_repo/-/merge_requests/1",
SHA: "9f733b96b98a4175276edf6a2e1231489c3bdd23",
RepoName: "test_repo",
- OwnerName: "lafriks",
+ OwnerName: "oliverpool",
},
Base: base.PullRequestBranch{
Ref: "master",
SHA: "c59c9b451acca9d106cc19d61d87afe3fbbb8b83",
- OwnerName: "lafriks",
+ OwnerName: "oliverpool",
RepoName: "test_repo",
},
Closed: nil,
@@ -303,32 +309,13 @@ func TestGitlabDownloadRepo(t *testing.T) {
}, prs)
rvs, err := downloader.GetReviews(&base.PullRequest{Number: 1, ForeignIndex: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
IssueIndex: 1,
- ReviewerID: 527793,
- ReviewerName: "axifive",
- CreatedAt: time.Date(2019, 11, 28, 8, 54, 41, 34000000, time.UTC),
- State: "APPROVED",
- },
- {
- IssueIndex: 1,
- ReviewerID: 4102996,
- ReviewerName: "zeripath",
- CreatedAt: time.Date(2019, 11, 28, 8, 54, 41, 34000000, time.UTC),
- State: "APPROVED",
- },
- }, rvs)
-
- rvs, err = downloader.GetReviews(&base.PullRequest{Number: 2, ForeignIndex: 2})
- assert.NoError(t, err)
- assertReviewsEqual(t, []*base.Review{
- {
- IssueIndex: 2,
- ReviewerID: 4575606,
- ReviewerName: "real6543",
- CreatedAt: time.Date(2019, 11, 28, 15, 56, 54, 108000000, time.UTC),
+ ReviewerID: 548513,
+ ReviewerName: "mkobel",
+ CreatedAt: time.Date(2024, 9, 3, 7, 57, 19, 86600000, time.UTC),
State: "APPROVED",
},
}, rvs)
@@ -343,12 +330,12 @@ func TestGitlabSkippedIssueNumber(t *testing.T) {
server := unittest.NewMockWebServer(t, "https://gitlab.com", fixturePath, gitlabPersonalAccessToken != "")
defer server.Close()
- downloader, err := NewGitlabDownloader(context.Background(), server.URL, "troyengel/archbuild", "", "", gitlabPersonalAccessToken)
+ downloader, err := NewGitlabDownloader(t.Context(), server.URL, "troyengel/archbuild", "", "", gitlabPersonalAccessToken)
if err != nil {
t.Fatalf("NewGitlabDownloader is nil: %v", err)
}
repo, err := downloader.GetRepoInfo()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertRepositoryEqual(t, &base.Repository{
Name: "archbuild",
Owner: "troyengel",
@@ -359,20 +346,20 @@ func TestGitlabSkippedIssueNumber(t *testing.T) {
}, repo)
issues, isEnd, err := downloader.GetIssues(1, 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.True(t, isEnd)
// the only issue in this repository has number 2
- assert.EqualValues(t, 1, len(issues))
+ assert.Len(t, issues, 1)
assert.EqualValues(t, 2, issues[0].Number)
assert.EqualValues(t, "vpn unlimited errors", issues[0].Title)
prs, _, err := downloader.GetPullRequests(1, 10)
- assert.NoError(t, err)
+ require.NoError(t, err)
// the only merge request in this repository has number 1,
// but we offset it by the maximum issue number so it becomes
// pull request 3 in Forgejo
- assert.EqualValues(t, 1, len(prs))
+ assert.Len(t, prs, 1)
assert.EqualValues(t, 3, prs[0].Number)
assert.EqualValues(t, "Review", prs[0].Title)
}
@@ -466,7 +453,7 @@ func TestGitlabGetReviews(t *testing.T) {
repoID := 1324
downloader := &GitlabDownloader{
- ctx: context.Background(),
+ ctx: t.Context(),
client: client,
repoID: repoID,
}
@@ -507,7 +494,7 @@ func TestGitlabGetReviews(t *testing.T) {
id := int64(testCase.prID)
rvs, err := downloader.GetReviews(&base.Issue{Number: id, ForeignIndex: id})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertReviewsEqual(t, []*base.Review{&review}, rvs)
}
}
@@ -541,7 +528,7 @@ func TestAwardsToReactions(t *testing.T) {
]
`
var awards []*gitlab.AwardEmoji
- assert.NoError(t, json.Unmarshal([]byte(testResponse), &awards))
+ require.NoError(t, json.Unmarshal([]byte(testResponse), &awards))
reactions := downloader.awardsToReactions(awards)
assert.EqualValues(t, []*base.Reaction{
diff --git a/services/migrations/gogs.go b/services/migrations/gogs.go
index b31d05fa73..b6fb8cef0a 100644
--- a/services/migrations/gogs.go
+++ b/services/migrations/gogs.go
@@ -11,10 +11,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/proxy"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/proxy"
+ "forgejo.org/modules/structs"
"github.com/gogs/go-gogs-client"
)
@@ -151,6 +151,7 @@ func (g *GogsDownloader) GetRepoInfo() (*base.Repository, error) {
CloneURL: gr.CloneURL,
OriginalURL: gr.HTMLURL,
DefaultBranch: gr.DefaultBranch,
+ Website: gr.Website,
}, nil
}
diff --git a/services/migrations/gogs_test.go b/services/migrations/gogs_test.go
index ca02b4317b..7d7f10c2b9 100644
--- a/services/migrations/gogs_test.go
+++ b/services/migrations/gogs_test.go
@@ -4,15 +4,15 @@
package migrations
import (
- "context"
"net/http"
"os"
"testing"
"time"
- base "code.gitea.io/gitea/modules/migration"
+ base "forgejo.org/modules/migration"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestGogsDownloadRepo(t *testing.T) {
@@ -29,9 +29,9 @@ func TestGogsDownloadRepo(t *testing.T) {
return
}
- downloader := NewGogsDownloader(context.Background(), "https://try.gogs.io", "", "", gogsPersonalAccessToken, "lunnytest", "TESTREPO")
+ downloader := NewGogsDownloader(t.Context(), "https://try.gogs.io", "", "", gogsPersonalAccessToken, "lunnytest", "TESTREPO")
repo, err := downloader.GetRepoInfo()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertRepositoryEqual(t, &base.Repository{
Name: "TESTREPO",
@@ -43,7 +43,7 @@ func TestGogsDownloadRepo(t *testing.T) {
}, repo)
milestones, err := downloader.GetMilestones()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertMilestonesEqual(t, []*base.Milestone{
{
Title: "1.0",
@@ -52,7 +52,7 @@ func TestGogsDownloadRepo(t *testing.T) {
}, milestones)
labels, err := downloader.GetLabels()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertLabelsEqual(t, []*base.Label{
{
Name: "bug",
@@ -86,7 +86,7 @@ func TestGogsDownloadRepo(t *testing.T) {
// downloader.GetIssues()
issues, isEnd, err := downloader.GetIssues(1, 8)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, isEnd)
assertIssuesEqual(t, []*base.Issue{
{
@@ -111,7 +111,7 @@ func TestGogsDownloadRepo(t *testing.T) {
// downloader.GetComments()
comments, _, err := downloader.GetComments(&base.Issue{Number: 1, ForeignIndex: 1})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
IssueIndex: 1,
@@ -135,7 +135,7 @@ func TestGogsDownloadRepo(t *testing.T) {
// downloader.GetPullRequests()
_, _, err = downloader.GetPullRequests(1, 3)
- assert.Error(t, err)
+ require.Error(t, err)
}
func TestGogsDownloaderFactory_New(t *testing.T) {
@@ -206,7 +206,7 @@ func TestGogsDownloaderFactory_New(t *testing.T) {
AuthPassword: tt.args.AuthPassword,
AuthToken: tt.args.AuthToken,
}
- got, err := f.New(context.Background(), opts)
+ got, err := f.New(t.Context(), opts)
if (err != nil) != tt.wantErr {
t.Errorf("GogsDownloaderFactory.New() error = %v, wantErr %v", err, tt.wantErr)
return
diff --git a/services/migrations/http_client.go b/services/migrations/http_client.go
index 9e3caec191..26962f2976 100644
--- a/services/migrations/http_client.go
+++ b/services/migrations/http_client.go
@@ -7,9 +7,9 @@ import (
"crypto/tls"
"net/http"
- "code.gitea.io/gitea/modules/hostmatcher"
- "code.gitea.io/gitea/modules/proxy"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/modules/hostmatcher"
+ "forgejo.org/modules/proxy"
+ "forgejo.org/modules/setting"
)
// NewMigrationHTTPClient returns a HTTP client for migration
@@ -24,6 +24,6 @@ func NewMigrationHTTPTransport() *http.Transport {
return &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: setting.Migrations.SkipTLSVerify},
Proxy: proxy.Proxy(),
- DialContext: hostmatcher.NewDialContext("migration", allowList, blockList),
+ DialContext: hostmatcher.NewDialContext("migration", allowList, blockList, setting.Proxy.ProxyURLFixed),
}
}
diff --git a/services/migrations/main_test.go b/services/migrations/main_test.go
index d0ec6a3f8d..d543bd6d9c 100644
--- a/services/migrations/main_test.go
+++ b/services/migrations/main_test.go
@@ -8,8 +8,8 @@ import (
"testing"
"time"
- "code.gitea.io/gitea/models/unittest"
- base "code.gitea.io/gitea/modules/migration"
+ "forgejo.org/models/unittest"
+ base "forgejo.org/modules/migration"
"github.com/stretchr/testify/assert"
)
@@ -136,6 +136,7 @@ func assertPullRequestEqual(t *testing.T, expected, actual *base.PullRequest) {
assert.ElementsMatch(t, expected.Assignees, actual.Assignees)
assert.Equal(t, expected.IsLocked, actual.IsLocked)
assertReactionsEqual(t, expected.Reactions, actual.Reactions)
+ assert.Equal(t, expected.Flow, actual.Flow)
}
func assertPullRequestsEqual(t *testing.T, expected, actual []*base.PullRequest) {
@@ -219,6 +220,7 @@ func assertRepositoryEqual(t *testing.T, expected, actual *base.Repository) {
assert.Equal(t, expected.CloneURL, actual.CloneURL)
assert.Equal(t, expected.OriginalURL, actual.OriginalURL)
assert.Equal(t, expected.DefaultBranch, actual.DefaultBranch)
+ assert.Equal(t, expected.Website, actual.Website)
}
func assertReviewEqual(t *testing.T, expected, actual *base.Review) {
diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go
index de90c5e98f..81d1c203fe 100644
--- a/services/migrations/migrate.go
+++ b/services/migrations/migrate.go
@@ -12,16 +12,16 @@ import (
"path/filepath"
"strings"
- "code.gitea.io/gitea/models"
- repo_model "code.gitea.io/gitea/models/repo"
- system_model "code.gitea.io/gitea/models/system"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/hostmatcher"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/setting"
- "code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/util"
+ "forgejo.org/models"
+ repo_model "forgejo.org/models/repo"
+ system_model "forgejo.org/models/system"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/hostmatcher"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/setting"
+ "forgejo.org/modules/structs"
+ "forgejo.org/modules/util"
)
// MigrateOptions is equal to base.MigrateOptions
@@ -39,8 +39,17 @@ func RegisterDownloaderFactory(factory base.DownloaderFactory) {
factories = append(factories, factory)
}
-// IsMigrateURLAllowed checks if an URL is allowed to be migrated from
+// IsPushMirrorURLAllowed checks if an URL is allowed to be pushed to.
+func IsPushMirrorURLAllowed(remoteURL string, doer *user_model.User) error {
+ return isURLAllowed(remoteURL, doer, true)
+}
+
+// IsMigrateURLAllowed checks if an URL is allowed to be migrated from.
func IsMigrateURLAllowed(remoteURL string, doer *user_model.User) error {
+ return isURLAllowed(remoteURL, doer, false)
+}
+
+func isURLAllowed(remoteURL string, doer *user_model.User, isPushMirror bool) error {
// Remote address can be HTTP/HTTPS/Git URL or local path.
u, err := url.Parse(remoteURL)
if err != nil {
@@ -71,7 +80,7 @@ func IsMigrateURLAllowed(remoteURL string, doer *user_model.User) error {
return &models.ErrInvalidCloneAddr{Host: u.Host, IsURLError: true}
}
- if u.Opaque != "" || u.Scheme != "" && u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "git" {
+ if u.Opaque != "" || u.Scheme != "" && u.Scheme != "http" && u.Scheme != "https" && u.Scheme != "git" && u.Scheme != "ssh" || (!isPushMirror && u.Scheme == "ssh") {
return &models.ErrInvalidCloneAddr{Host: u.Host, IsProtocolInvalid: true, IsPermissionDenied: true, IsURLError: true}
}
@@ -506,9 +515,5 @@ func Init() error {
// TODO: at the moment, if ALLOW_LOCALNETWORKS=false, ALLOWED_DOMAINS=domain.com, and domain.com has IP 127.0.0.1, then it's still allowed.
// if we want to block such case, the private&loopback should be added to the blockList when ALLOW_LOCALNETWORKS=false
- if setting.Proxy.Enabled && setting.Proxy.ProxyURLFixed != nil {
- allowList.AppendPattern(setting.Proxy.ProxyURLFixed.Host)
- }
-
return nil
}
diff --git a/services/migrations/migrate_test.go b/services/migrations/migrate_test.go
index 03efa6185b..804d01df7a 100644
--- a/services/migrations/migrate_test.go
+++ b/services/migrations/migrate_test.go
@@ -8,69 +8,69 @@ import (
"path/filepath"
"testing"
- "code.gitea.io/gitea/models/unittest"
- user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/setting"
+ "forgejo.org/models/unittest"
+ user_model "forgejo.org/models/user"
+ "forgejo.org/modules/setting"
- "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestMigrateWhiteBlocklist(t *testing.T) {
- assert.NoError(t, unittest.PrepareTestDatabase())
+ require.NoError(t, unittest.PrepareTestDatabase())
adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
nonAdminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
setting.Migrations.AllowedDomains = "github.com"
setting.Migrations.AllowLocalNetworks = false
- assert.NoError(t, Init())
+ require.NoError(t, Init())
err := IsMigrateURLAllowed("https://gitlab.com/gitlab/gitlab.git", nonAdminUser)
- assert.Error(t, err)
+ require.Error(t, err)
err = IsMigrateURLAllowed("https://github.com/go-gitea/gitea.git", nonAdminUser)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = IsMigrateURLAllowed("https://gITHUb.com/go-gitea/gitea.git", nonAdminUser)
- assert.NoError(t, err)
+ require.NoError(t, err)
setting.Migrations.AllowedDomains = ""
setting.Migrations.BlockedDomains = "github.com"
- assert.NoError(t, Init())
+ require.NoError(t, Init())
err = IsMigrateURLAllowed("https://gitlab.com/gitlab/gitlab.git", nonAdminUser)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = IsMigrateURLAllowed("https://github.com/go-gitea/gitea.git", nonAdminUser)
- assert.Error(t, err)
+ require.Error(t, err)
err = IsMigrateURLAllowed("https://10.0.0.1/go-gitea/gitea.git", nonAdminUser)
- assert.Error(t, err)
+ require.Error(t, err)
setting.Migrations.AllowLocalNetworks = true
- assert.NoError(t, Init())
+ require.NoError(t, Init())
err = IsMigrateURLAllowed("https://10.0.0.1/go-gitea/gitea.git", nonAdminUser)
- assert.NoError(t, err)
+ require.NoError(t, err)
old := setting.ImportLocalPaths
setting.ImportLocalPaths = false
err = IsMigrateURLAllowed("/home/foo/bar/goo", adminUser)
- assert.Error(t, err)
+ require.Error(t, err)
setting.ImportLocalPaths = true
abs, err := filepath.Abs(".")
- assert.NoError(t, err)
+ require.NoError(t, err)
err = IsMigrateURLAllowed(abs, adminUser)
- assert.NoError(t, err)
+ require.NoError(t, err)
err = IsMigrateURLAllowed(abs, nonAdminUser)
- assert.Error(t, err)
+ require.Error(t, err)
nonAdminUser.AllowImportLocal = true
err = IsMigrateURLAllowed(abs, nonAdminUser)
- assert.NoError(t, err)
+ require.NoError(t, err)
setting.ImportLocalPaths = old
}
@@ -80,36 +80,51 @@ func TestAllowBlockList(t *testing.T) {
setting.Migrations.AllowedDomains = allow
setting.Migrations.BlockedDomains = block
setting.Migrations.AllowLocalNetworks = local
- assert.NoError(t, Init())
+ require.NoError(t, Init())
}
// default, allow all external, block none, no local networks
init("", "", false)
- assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
- assert.Error(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
+ require.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
+ require.Error(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
// allow all including local networks (it could lead to SSRF in production)
init("", "", true)
- assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
- assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
+ require.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
+ require.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
// allow wildcard, block some subdomains. if the domain name is allowed, then the local network check is skipped
init("*.domain.com", "blocked.domain.com", false)
- assert.NoError(t, checkByAllowBlockList("sub.domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
- assert.NoError(t, checkByAllowBlockList("sub.domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
- assert.Error(t, checkByAllowBlockList("blocked.domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
- assert.Error(t, checkByAllowBlockList("sub.other.com", []net.IP{net.ParseIP("1.2.3.4")}))
+ require.NoError(t, checkByAllowBlockList("sub.domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
+ require.NoError(t, checkByAllowBlockList("sub.domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
+ require.Error(t, checkByAllowBlockList("blocked.domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
+ require.Error(t, checkByAllowBlockList("sub.other.com", []net.IP{net.ParseIP("1.2.3.4")}))
// allow wildcard (it could lead to SSRF in production)
init("*", "", false)
- assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
- assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
+ require.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
+ require.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
// local network can still be blocked
init("*", "127.0.0.*", false)
- assert.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
- assert.Error(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
+ require.NoError(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("1.2.3.4")}))
+ require.Error(t, checkByAllowBlockList("domain.com", []net.IP{net.ParseIP("127.0.0.1")}))
// reset
init("", "", false)
}
+
+func TestURLAllowedSSH(t *testing.T) {
+ require.NoError(t, unittest.PrepareTestDatabase())
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
+ sshURL := "ssh://git@git.gay/gitgay/forgejo"
+
+ t.Run("Migrate URL", func(t *testing.T) {
+ require.Error(t, IsMigrateURLAllowed(sshURL, user))
+ })
+
+ t.Run("Pushmirror URL", func(t *testing.T) {
+ require.NoError(t, IsPushMirrorURLAllowed(sshURL, user))
+ })
+}
diff --git a/services/migrations/onedev.go b/services/migrations/onedev.go
index e2f7b771f3..a553a4d8f5 100644
--- a/services/migrations/onedev.go
+++ b/services/migrations/onedev.go
@@ -12,10 +12,10 @@ import (
"strings"
"time"
- "code.gitea.io/gitea/modules/json"
- "code.gitea.io/gitea/modules/log"
- base "code.gitea.io/gitea/modules/migration"
- "code.gitea.io/gitea/modules/structs"
+ "forgejo.org/modules/json"
+ "forgejo.org/modules/log"
+ base "forgejo.org/modules/migration"
+ "forgejo.org/modules/structs"
)
var (
diff --git a/services/migrations/onedev_test.go b/services/migrations/onedev_test.go
index 48412fec64..5bb2e2bb5c 100644
--- a/services/migrations/onedev_test.go
+++ b/services/migrations/onedev_test.go
@@ -4,15 +4,15 @@
package migrations
import (
- "context"
"net/http"
"net/url"
"testing"
"time"
- base "code.gitea.io/gitea/modules/migration"
+ base "forgejo.org/modules/migration"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
)
func TestOneDevDownloadRepo(t *testing.T) {
@@ -22,12 +22,12 @@ func TestOneDevDownloadRepo(t *testing.T) {
}
u, _ := url.Parse("https://code.onedev.io")
- downloader := NewOneDevDownloader(context.Background(), u, "", "", "go-gitea-test_repo")
+ downloader := NewOneDevDownloader(t.Context(), u, "", "", "go-gitea-test_repo")
if err != nil {
t.Fatalf("NewOneDevDownloader is nil: %v", err)
}
repo, err := downloader.GetRepoInfo()
- assert.NoError(t, err)
+ require.NoError(t, err)
assertRepositoryEqual(t, &base.Repository{
Name: "go-gitea-test_repo",
Owner: "",
@@ -37,7 +37,7 @@ func TestOneDevDownloadRepo(t *testing.T) {
}, repo)
milestones, err := downloader.GetMilestones()
- assert.NoError(t, err)
+ require.NoError(t, err)
deadline := time.Unix(1620086400, 0)
assertMilestonesEqual(t, []*base.Milestone{
{
@@ -52,11 +52,11 @@ func TestOneDevDownloadRepo(t *testing.T) {
}, milestones)
labels, err := downloader.GetLabels()
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.Len(t, labels, 6)
issues, isEnd, err := downloader.GetIssues(1, 2)
- assert.NoError(t, err)
+ require.NoError(t, err)
assert.False(t, isEnd)
assertIssuesEqual(t, []*base.Issue{
{
@@ -99,7 +99,7 @@ func TestOneDevDownloadRepo(t *testing.T) {
ForeignIndex: 398,
Context: onedevIssueContext{IsPullRequest: false},
})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertCommentsEqual(t, []*base.Comment{
{
IssueIndex: 4,
@@ -111,7 +111,7 @@ func TestOneDevDownloadRepo(t *testing.T) {
}, comments)
prs, _, err := downloader.GetPullRequests(1, 1)
- assert.NoError(t, err)
+ require.NoError(t, err)
assertPullRequestsEqual(t, []*base.PullRequest{
{
Number: 5,
@@ -137,7 +137,7 @@ func TestOneDevDownloadRepo(t *testing.T) {
}, prs)
rvs, err := downloader.GetReviews(&base.PullRequest{Number: 5, ForeignIndex: 186})
- assert.NoError(t, err)
+ require.NoError(t, err)
assertReviewsEqual(t, []*base.Review{
{
IssueIndex: 5,
diff --git a/services/migrations/restore.go b/services/migrations/restore.go
index fd337b22c7..fe2628da52 100644
--- a/services/migrations/restore.go
+++ b/services/migrations/restore.go
@@ -10,7 +10,7 @@ import (
"path/filepath"
"strconv"
- base "code.gitea.io/gitea/modules/migration"
+ base "forgejo.org/modules/migration"
"gopkg.in/yaml.v3"
)
@@ -85,6 +85,7 @@ func (r *RepositoryRestorer) GetRepoInfo() (*base.Repository, error) {
OriginalURL: opts["original_url"],
CloneURL: filepath.Join(r.baseDir, "git"),
DefaultBranch: opts["default_branch"],
+ Website: opts["website"],
}, nil
}
diff --git a/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Frepos%2FGusted%2Fagit-test%2Fpulls%3Flimit=50&page=1&state=all b/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Frepos%2FGusted%2Fagit-test%2Fpulls%3Flimit=50&page=1&state=all
new file mode 100644
index 0000000000..87095d9e24
--- /dev/null
+++ b/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Frepos%2FGusted%2Fagit-test%2Fpulls%3Flimit=50&page=1&state=all
@@ -0,0 +1,8 @@
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Content-Type: application/json;charset=utf-8
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 1
+
+[{"id":4980,"url":"https://code.forgejo.org/Gusted/agit-test/pulls/1","number":1,"user":{"id":63,"login":"Gusted","login_name":"26734","source_id":1,"full_name":"","email":"postmaster@gusted.xyz","avatar_url":"https://code.forgejo.org/avatars/4ca5ad8bc488630869fdbd2051da61cbed7241c9c066d4e5e1dd36300f887340","html_url":"https://code.forgejo.org/Gusted","language":"en-US","is_admin":false,"last_login":"2025-04-01T16:35:18Z","created":"2023-07-08T13:33:38Z","restricted":false,"active":true,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":2,"following_count":0,"starred_repos_count":0,"username":"Gusted"},"title":"Add extra information","body":"","labels":[],"milestone":null,"assignee":null,"assignees":null,"requested_reviewers":[],"requested_reviewers_teams":[],"state":"open","draft":false,"is_locked":false,"comments":0,"review_comments":0,"additions":0,"deletions":0,"changed_files":0,"html_url":"https://code.forgejo.org/Gusted/agit-test/pulls/1","diff_url":"https://code.forgejo.org/Gusted/agit-test/pulls/1.diff","patch_url":"https://code.forgejo.org/Gusted/agit-test/pulls/1.patch","mergeable":true,"merged":false,"merged_at":null,"merge_commit_sha":null,"merged_by":null,"allow_maintainer_edit":false,"base":{"label":"main","ref":"main","sha":"79ebb873a6497c8847141ba9706b3f757196a1e6","repo_id":1414,"repo":{"id":1414,"owner":{"id":63,"login":"Gusted","login_name":"","source_id":0,"full_name":"","email":"gusted@noreply.code.forgejo.org","avatar_url":"https://code.forgejo.org/avatars/4ca5ad8bc488630869fdbd2051da61cbed7241c9c066d4e5e1dd36300f887340","html_url":"https://code.forgejo.org/Gusted","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2023-07-08T13:33:38Z","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":2,"following_count":0,"starred_repos_count":0,"username":"Gusted"},"name":"agit-test","full_name":"Gusted/agit-test","description":"USED FOR FORGEJO UNIT TESTING","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":36,"language":"","languages_url":"https://code.forgejo.org/api/v1/repos/Gusted/agit-test/languages","html_url":"https://code.forgejo.org/Gusted/agit-test","url":"https://code.forgejo.org/api/v1/repos/Gusted/agit-test","link":"","ssh_url":"ssh://git@code.forgejo.org/Gusted/agit-test.git","clone_url":"https://code.forgejo.org/Gusted/agit-test.git","original_url":"","website":"","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"open_pr_counter":1,"release_counter":0,"default_branch":"main","archived":false,"created_at":"2025-04-01T20:25:03Z","updated_at":"2025-04-01T20:25:03Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":true,"push":true,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"wiki_branch":"main","globally_editable_wiki":false,"has_pull_requests":true,"has_projects":true,"has_releases":true,"has_packages":true,"has_actions":true,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":true,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"default_update_style":"merge","avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":null}},"head":{"label":"","ref":"refs/pull/1/head","sha":"667e9317ec37b977e6d3d7d43e3440636970563c","repo_id":1414,"repo":{"id":1414,"owner":{"id":63,"login":"Gusted","login_name":"","source_id":0,"full_name":"","email":"gusted@noreply.code.forgejo.org","avatar_url":"https://code.forgejo.org/avatars/4ca5ad8bc488630869fdbd2051da61cbed7241c9c066d4e5e1dd36300f887340","html_url":"https://code.forgejo.org/Gusted","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2023-07-08T13:33:38Z","restricted":false,"active":false,"prohibit_login":false,"location":"","pronouns":"","website":"","description":"","visibility":"public","followers_count":2,"following_count":0,"starred_repos_count":0,"username":"Gusted"},"name":"agit-test","full_name":"Gusted/agit-test","description":"USED FOR FORGEJO UNIT TESTING","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":36,"language":"","languages_url":"https://code.forgejo.org/api/v1/repos/Gusted/agit-test/languages","html_url":"https://code.forgejo.org/Gusted/agit-test","url":"https://code.forgejo.org/api/v1/repos/Gusted/agit-test","link":"","ssh_url":"ssh://git@code.forgejo.org/Gusted/agit-test.git","clone_url":"https://code.forgejo.org/Gusted/agit-test.git","original_url":"","website":"","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"open_pr_counter":1,"release_counter":0,"default_branch":"main","archived":false,"created_at":"2025-04-01T20:25:03Z","updated_at":"2025-04-01T20:25:03Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":true,"push":true,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"wiki_branch":"main","globally_editable_wiki":false,"has_pull_requests":true,"has_projects":true,"has_releases":true,"has_packages":true,"has_actions":true,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":true,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"default_update_style":"merge","avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":null}},"merge_base":"79ebb873a6497c8847141ba9706b3f757196a1e6","due_date":null,"created_at":"2025-04-01T20:28:45Z","updated_at":"2025-04-01T20:28:45Z","closed_at":null,"pin_order":0,"flow":1}]
diff --git a/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fsettings%2Fapi b/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fsettings%2Fapi
new file mode 100644
index 0000000000..11c4e7b8ba
--- /dev/null
+++ b/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fsettings%2Fapi
@@ -0,0 +1,7 @@
+Content-Length: 117
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Content-Type: application/json;charset=utf-8
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+
+{"max_response_items":50,"default_paging_num":30,"default_git_trees_per_page":1000,"default_max_blob_size":10485760}
diff --git a/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fversion b/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fversion
new file mode 100644
index 0000000000..411ed84e24
--- /dev/null
+++ b/services/migrations/testdata/code-forgejo-org/full_download/GET_%2Fapi%2Fv1%2Fversion
@@ -0,0 +1,7 @@
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Content-Type: application/json;charset=utf-8
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+Content-Length: 53
+
+{"version":"11.0.0-dev-617-1d1e0ced3e+gitea-1.22.0"}
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo
new file mode 100644
index 0000000000..7b4441ceae
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo
@@ -0,0 +1,7 @@
+X-Frame-Options: SAMEORIGIN
+Content-Type: application/json;charset=utf-8
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Content-Type-Options: nosniff
+
+{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F1%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F1%2Freactions
new file mode 100644
index 0000000000..d7b453f63b
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F1%2Freactions
@@ -0,0 +1,10 @@
+Access-Control-Expose-Headers: X-Total-Count
+X-Total-Count: 2
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+Content-Type: application/json;charset=utf-8
+Content-Length: 1293
+
+[{"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"content":"gitea","created_at":"2020-09-01T00:15:14Z"},{"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"content":"confused","created_at":"2020-09-01T00:15:19Z"}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F10%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F10%2Freactions
new file mode 100644
index 0000000000..a6b09b769c
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F10%2Freactions
@@ -0,0 +1,10 @@
+Content-Length: 5
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Total-Count: 0
+Content-Type: application/json;charset=utf-8
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+X-Frame-Options: SAMEORIGIN
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F11%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F11%2Freactions
new file mode 100644
index 0000000000..139c547d0a
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F11%2Freactions
@@ -0,0 +1,10 @@
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+X-Total-Count: 0
+Content-Type: application/json;charset=utf-8
+Content-Length: 5
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F12%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F12%2Freactions
new file mode 100644
index 0000000000..94b815b3a1
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F12%2Freactions
@@ -0,0 +1,10 @@
+X-Frame-Options: SAMEORIGIN
+Access-Control-Expose-Headers: X-Total-Count
+X-Content-Type-Options: nosniff
+Vary: Origin
+X-Total-Count: 0
+Content-Type: application/json;charset=utf-8
+Content-Length: 5
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F13%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F13%2Freactions
new file mode 100644
index 0000000000..95b1b871d6
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F13%2Freactions
@@ -0,0 +1,10 @@
+Content-Length: 5
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Frame-Options: SAMEORIGIN
+Content-Type: application/json;charset=utf-8
+X-Content-Type-Options: nosniff
+X-Total-Count: 0
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F2%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F2%2Freactions
new file mode 100644
index 0000000000..5d94bfa369
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F2%2Freactions
@@ -0,0 +1,10 @@
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 0
+Content-Type: application/json;charset=utf-8
+Content-Length: 5
+Vary: Origin
+X-Content-Type-Options: nosniff
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F3%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F3%2Freactions
new file mode 100644
index 0000000000..1f244a25f5
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F3%2Freactions
@@ -0,0 +1,10 @@
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+Content-Type: application/json;charset=utf-8
+Content-Length: 5
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Total-Count: 0
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F4%2Fcomments%3Flimit=50&page=1 b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F4%2Fcomments%3Flimit=50&page=1
new file mode 100644
index 0000000000..294aa749cb
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F4%2Fcomments%3Flimit=50&page=1
@@ -0,0 +1,10 @@
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 2
+Content-Type: application/json;charset=utf-8
+Access-Control-Expose-Headers: X-Total-Count
+X-Content-Type-Options: nosniff
+Content-Length: 1824
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+
+[{"id":116550,"html_url":"https://gitea.com/gitea/test_repo/issues/4#issuecomment-116550","pull_request_url":"","issue_url":"https://gitea.com/gitea/test_repo/issues/4","user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"original_author":"","original_author_id":0,"body":"a really good question!\n\nIt is the used as TESTSET for gitea2gitea repo migration function","assets":[],"created_at":"2020-09-01T15:49:30Z","updated_at":"2020-09-02T18:21:05Z"},{"id":116552,"html_url":"https://gitea.com/gitea/test_repo/issues/4#issuecomment-116552","pull_request_url":"","issue_url":"https://gitea.com/gitea/test_repo/issues/4","user":{"id":-1,"login":"Ghost","login_name":"","source_id":0,"full_name":"","email":"ghost@noreply.gitea.com","avatar_url":"https://gitea.com/assets/img/avatar_default.png","html_url":"https://gitea.com/Ghost","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"1970-01-01T00:00:00Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"Ghost"},"original_author":"","original_author_id":0,"body":"Oh!","assets":[],"created_at":"2020-09-01T15:49:53Z","updated_at":"2020-09-01T15:49:53Z"}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F4%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F4%2Freactions
new file mode 100644
index 0000000000..0300a779cb
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F4%2Freactions
@@ -0,0 +1,10 @@
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 2
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Content-Type-Options: nosniff
+Content-Type: application/json;charset=utf-8
+Content-Length: 1290
+
+[{"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"content":"gitea","created_at":"2020-09-01T19:36:40Z"},{"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"content":"laugh","created_at":"2020-09-01T19:36:45Z"}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F5%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F5%2Freactions
new file mode 100644
index 0000000000..39606a50cf
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F5%2Freactions
@@ -0,0 +1,10 @@
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+Content-Length: 1288
+Access-Control-Expose-Headers: X-Total-Count
+Vary: Origin
+Content-Type: application/json;charset=utf-8
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+X-Total-Count: 2
+
+[{"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"content":"+1","created_at":"2020-09-01T16:07:06Z"},{"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"content":"hooray","created_at":"2020-09-01T16:07:11Z"}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F6%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F6%2Freactions
new file mode 100644
index 0000000000..f25996bc6b
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F6%2Freactions
@@ -0,0 +1,10 @@
+Access-Control-Expose-Headers: X-Total-Count
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+Content-Type: application/json;charset=utf-8
+Content-Length: 5
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Total-Count: 0
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F7%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F7%2Freactions
new file mode 100644
index 0000000000..926a987090
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F7%2Freactions
@@ -0,0 +1,10 @@
+Content-Type: application/json;charset=utf-8
+Access-Control-Expose-Headers: X-Total-Count
+X-Content-Type-Options: nosniff
+X-Total-Count: 0
+Content-Length: 5
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Frame-Options: SAMEORIGIN
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F8%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F8%2Freactions
new file mode 100644
index 0000000000..abaff9c6fd
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F8%2Freactions
@@ -0,0 +1,10 @@
+Vary: Origin
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 0
+Content-Type: application/json;charset=utf-8
+Content-Length: 5
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Access-Control-Expose-Headers: X-Total-Count
+X-Content-Type-Options: nosniff
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F9%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F9%2Freactions
new file mode 100644
index 0000000000..75de9623c7
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2F9%2Freactions
@@ -0,0 +1,10 @@
+X-Total-Count: 0
+Content-Type: application/json;charset=utf-8
+Content-Length: 5
+Access-Control-Expose-Headers: X-Total-Count
+X-Frame-Options: SAMEORIGIN
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Content-Type-Options: nosniff
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2Fcomments%2F116550%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2Fcomments%2F116550%2Freactions
new file mode 100644
index 0000000000..86ac9f784f
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2Fcomments%2F116550%2Freactions
@@ -0,0 +1,8 @@
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+Content-Type: application/json;charset=utf-8
+Content-Length: 5
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2Fcomments%2F116552%2Freactions b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2Fcomments%2F116552%2Freactions
new file mode 100644
index 0000000000..94133432e8
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%2Fcomments%2F116552%2Freactions
@@ -0,0 +1,8 @@
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+Content-Type: application/json;charset=utf-8
+Content-Length: 5
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+
+null
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%3Flimit=2&page=3&state=all&type=issues b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%3Flimit=2&page=3&state=all&type=issues
new file mode 100644
index 0000000000..1e552b22d4
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%3Flimit=2&page=3&state=all&type=issues
@@ -0,0 +1,10 @@
+Link: ; rel="next",; rel="last",; rel="first",; rel="prev"
+Access-Control-Expose-Headers: Link, X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 7
+Content-Type: application/json;charset=utf-8
+Vary: Origin
+
+[{"id":30475,"url":"https://gitea.com/api/v1/repos/gitea/test_repo/issues/4","html_url":"https://gitea.com/gitea/test_repo/issues/4","number":4,"user":{"id":-1,"login":"Ghost","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/assets/img/avatar_default.png","html_url":"https://gitea.com/Ghost","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"1970-01-01T00:00:00Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"Ghost"},"original_author":"","original_author_id":0,"title":"what is this repo about?","body":"","ref":"","assets":[],"labels":[{"id":3733,"name":"Question","exclusive":false,"is_archived":false,"color":"fbca04","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3733"}],"milestone":{"id":1300,"title":"V1","description":"Generate Content","state":"closed","open_issues":0,"closed_issues":4,"created_at":"1970-01-01T00:00:00Z","updated_at":"1970-01-01T00:00:00Z","closed_at":"2020-09-01T18:36:46Z","due_on":null},"assignee":null,"assignees":null,"state":"closed","is_locked":true,"comments":2,"created_at":"2020-09-01T15:48:41Z","updated_at":"2020-09-01T15:50:00Z","closed_at":"2020-09-01T15:49:34Z","due_date":null,"pull_request":null,"repository":{"id":16268,"name":"test_repo","owner":"gitea","full_name":"gitea/test_repo"},"pin_order":0},{"id":30471,"url":"https://gitea.com/api/v1/repos/gitea/test_repo/issues/2","html_url":"https://gitea.com/gitea/test_repo/issues/2","number":2,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"original_author":"","original_author_id":0,"title":"Spam","body":":(","ref":"","assets":[],"labels":[{"id":3732,"name":"Invalid","exclusive":false,"is_archived":false,"color":"d4c5f9","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3732"}],"milestone":null,"assignee":null,"assignees":null,"state":"closed","is_locked":false,"comments":2,"created_at":"2020-09-01T00:23:00Z","updated_at":"2020-09-01T14:11:37Z","closed_at":"2020-09-01T14:11:37Z","due_date":null,"pull_request":null,"repository":{"id":16268,"name":"test_repo","owner":"gitea","full_name":"gitea/test_repo"},"pin_order":0}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%3Flimit=50&page=1&state=all&type=issues b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%3Flimit=50&page=1&state=all&type=issues
new file mode 100644
index 0000000000..6b0a6135ac
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fissues%3Flimit=50&page=1&state=all&type=issues
@@ -0,0 +1,9 @@
+Content-Type: application/json;charset=utf-8
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 7
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+
+[{"id":30481,"url":"https://gitea.com/api/v1/repos/gitea/test_repo/issues/10","html_url":"https://gitea.com/gitea/test_repo/issues/10","number":10,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"original_author":"","original_author_id":0,"title":"A'm I allowed to fork it?","body":"yes but do not create pull requests anymore","ref":"","assets":[],"labels":[{"id":3733,"name":"Question","exclusive":false,"is_archived":false,"color":"fbca04","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3733"}],"milestone":null,"assignee":null,"assignees":null,"state":"open","is_locked":false,"comments":0,"created_at":"2020-09-01T17:48:14Z","updated_at":"2020-09-01T17:48:14Z","closed_at":null,"due_date":null,"pull_request":null,"repository":{"id":16268,"name":"test_repo","owner":"gitea","full_name":"gitea/test_repo"},"pin_order":0},{"id":30480,"url":"https://gitea.com/api/v1/repos/gitea/test_repo/issues/9","html_url":"https://gitea.com/gitea/test_repo/issues/9","number":9,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"original_author":"","original_author_id":0,"title":"Idears","body":"this is an example for an open issue - they just cant be all closed ;)","ref":"","assets":[],"labels":[{"id":3735,"name":"Enhancement","exclusive":false,"is_archived":false,"color":"207de5","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3735"}],"milestone":{"id":1301,"title":"V2 Finalize","description":"","state":"open","open_issues":1,"closed_issues":2,"created_at":"1970-01-01T00:00:00Z","updated_at":"2022-11-13T05:29:15Z","closed_at":null,"due_on":"2020-09-04T23:59:59Z"},"assignee":null,"assignees":null,"state":"open","is_locked":false,"comments":0,"created_at":"2020-09-01T17:47:11Z","updated_at":"2020-09-01T17:47:17Z","closed_at":null,"due_date":null,"pull_request":null,"repository":{"id":16268,"name":"test_repo","owner":"gitea","full_name":"gitea/test_repo"},"pin_order":0},{"id":30477,"url":"https://gitea.com/api/v1/repos/gitea/test_repo/issues/6","html_url":"https://gitea.com/gitea/test_repo/issues/6","number":6,"user":{"id":9,"login":"techknowlogick","login_name":"","source_id":0,"full_name":"","email":"techknowlogick@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/9b588dd0b384d6f6ae841c5d62302033","html_url":"https://gitea.com/techknowlogick","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-01-14T06:48:35Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":11,"following_count":1,"starred_repos_count":4,"username":"techknowlogick"},"original_author":"","original_author_id":0,"title":"Please add a tag (or a release)","body":"","ref":"","assets":[],"labels":[],"milestone":null,"assignee":null,"assignees":null,"state":"closed","is_locked":false,"comments":1,"created_at":"2020-09-01T16:07:01Z","updated_at":"2020-09-01T17:26:02Z","closed_at":"2020-09-01T17:26:02Z","due_date":null,"pull_request":null,"repository":{"id":16268,"name":"test_repo","owner":"gitea","full_name":"gitea/test_repo"},"pin_order":0},{"id":30476,"url":"https://gitea.com/api/v1/repos/gitea/test_repo/issues/5","html_url":"https://gitea.com/gitea/test_repo/issues/5","number":5,"user":{"id":9,"login":"techknowlogick","login_name":"","source_id":0,"full_name":"","email":"techknowlogick@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/9b588dd0b384d6f6ae841c5d62302033","html_url":"https://gitea.com/techknowlogick","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-01-14T06:48:35Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":11,"following_count":1,"starred_repos_count":4,"username":"techknowlogick"},"original_author":"","original_author_id":0,"title":"Need more contributors to this repo","body":"I volunteer as one","ref":"","assets":[],"labels":[],"milestone":{"id":1301,"title":"V2 Finalize","description":"","state":"open","open_issues":1,"closed_issues":2,"created_at":"1970-01-01T00:00:00Z","updated_at":"2022-11-13T05:29:15Z","closed_at":null,"due_on":"2020-09-04T23:59:59Z"},"assignee":null,"assignees":null,"state":"closed","is_locked":false,"comments":1,"created_at":"2020-09-01T16:06:30Z","updated_at":"2020-09-01T17:46:09Z","closed_at":"2020-09-01T17:46:09Z","due_date":null,"pull_request":null,"repository":{"id":16268,"name":"test_repo","owner":"gitea","full_name":"gitea/test_repo"},"pin_order":0},{"id":30475,"url":"https://gitea.com/api/v1/repos/gitea/test_repo/issues/4","html_url":"https://gitea.com/gitea/test_repo/issues/4","number":4,"user":{"id":-1,"login":"Ghost","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/assets/img/avatar_default.png","html_url":"https://gitea.com/Ghost","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"1970-01-01T00:00:00Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"Ghost"},"original_author":"","original_author_id":0,"title":"what is this repo about?","body":"","ref":"","assets":[],"labels":[{"id":3733,"name":"Question","exclusive":false,"is_archived":false,"color":"fbca04","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3733"}],"milestone":{"id":1300,"title":"V1","description":"Generate Content","state":"closed","open_issues":0,"closed_issues":4,"created_at":"1970-01-01T00:00:00Z","updated_at":"1970-01-01T00:00:00Z","closed_at":"2020-09-01T18:36:46Z","due_on":null},"assignee":null,"assignees":null,"state":"closed","is_locked":true,"comments":2,"created_at":"2020-09-01T15:48:41Z","updated_at":"2020-09-01T15:50:00Z","closed_at":"2020-09-01T15:49:34Z","due_date":null,"pull_request":null,"repository":{"id":16268,"name":"test_repo","owner":"gitea","full_name":"gitea/test_repo"},"pin_order":0},{"id":30471,"url":"https://gitea.com/api/v1/repos/gitea/test_repo/issues/2","html_url":"https://gitea.com/gitea/test_repo/issues/2","number":2,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"original_author":"","original_author_id":0,"title":"Spam","body":":(","ref":"","assets":[],"labels":[{"id":3732,"name":"Invalid","exclusive":false,"is_archived":false,"color":"d4c5f9","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3732"}],"milestone":null,"assignee":null,"assignees":null,"state":"closed","is_locked":false,"comments":2,"created_at":"2020-09-01T00:23:00Z","updated_at":"2020-09-01T14:11:37Z","closed_at":"2020-09-01T14:11:37Z","due_date":null,"pull_request":null,"repository":{"id":16268,"name":"test_repo","owner":"gitea","full_name":"gitea/test_repo"},"pin_order":0},{"id":30470,"url":"https://gitea.com/api/v1/repos/gitea/test_repo/issues/1","html_url":"https://gitea.com/gitea/test_repo/issues/1","number":1,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"original_author":"","original_author_id":0,"title":"Here Is no content!","body":"","ref":"","assets":[],"labels":[{"id":3734,"name":"Valid","exclusive":false,"is_archived":false,"color":"53e917","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3734"}],"milestone":{"id":1300,"title":"V1","description":"Generate Content","state":"closed","open_issues":0,"closed_issues":4,"created_at":"1970-01-01T00:00:00Z","updated_at":"1970-01-01T00:00:00Z","closed_at":"2020-09-01T18:36:46Z","due_on":null},"assignee":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"assignees":[{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"}],"state":"closed","is_locked":false,"comments":0,"created_at":"2020-09-01T00:15:11Z","updated_at":"2020-09-01T17:26:25Z","closed_at":"2020-09-01T17:26:25Z","due_date":null,"pull_request":null,"repository":{"id":16268,"name":"test_repo","owner":"gitea","full_name":"gitea/test_repo"},"pin_order":0}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Flabels%3Flimit=50&page=1 b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Flabels%3Flimit=50&page=1
new file mode 100644
index 0000000000..0c5e5c4b37
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Flabels%3Flimit=50&page=1
@@ -0,0 +1,10 @@
+Content-Type: application/json;charset=utf-8
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 6
+Content-Length: 1026
+Access-Control-Expose-Headers: X-Total-Count
+X-Content-Type-Options: nosniff
+
+[{"id":3730,"name":"Bug","exclusive":false,"is_archived":false,"color":"e11d21","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3730"},{"id":3735,"name":"Enhancement","exclusive":false,"is_archived":false,"color":"207de5","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3735"},{"id":3731,"name":"Feature","exclusive":false,"is_archived":false,"color":"0052cc","description":"a feature request","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3731"},{"id":3732,"name":"Invalid","exclusive":false,"is_archived":false,"color":"d4c5f9","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3732"},{"id":3733,"name":"Question","exclusive":false,"is_archived":false,"color":"fbca04","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3733"},{"id":3734,"name":"Valid","exclusive":false,"is_archived":false,"color":"53e917","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3734"}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fmilestones%3Flimit=50&page=1&state=all b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fmilestones%3Flimit=50&page=1&state=all
new file mode 100644
index 0000000000..56855b5788
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fmilestones%3Flimit=50&page=1&state=all
@@ -0,0 +1,10 @@
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 2
+Content-Type: application/json;charset=utf-8
+Content-Length: 453
+Vary: Origin
+X-Content-Type-Options: nosniff
+
+[{"id":1301,"title":"V2 Finalize","description":"","state":"open","open_issues":1,"closed_issues":2,"created_at":"1970-01-01T00:00:00Z","updated_at":"2022-11-13T05:29:15Z","closed_at":null,"due_on":"2020-09-04T23:59:59Z"},{"id":1300,"title":"V1","description":"Generate Content","state":"closed","open_issues":0,"closed_issues":4,"created_at":"1970-01-01T00:00:00Z","updated_at":"1970-01-01T00:00:00Z","closed_at":"2020-09-01T18:36:46Z","due_on":null}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%2F1770%2Fcomments b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%2F1770%2Fcomments
new file mode 100644
index 0000000000..c8cb26c4d1
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%2F1770%2Fcomments
@@ -0,0 +1,8 @@
+Content-Type: application/json;charset=utf-8
+Content-Length: 1211
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+
+[{"id":116561,"body":"is one `\\newline` to less?","user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"resolver":null,"pull_request_review_id":1770,"created_at":"2020-09-01T16:12:58Z","updated_at":"2024-06-03T01:18:36Z","path":"README.md","commit_id":"187ece0cb6631e2858a6872e5733433bb3ca3b03","original_commit_id":"","diff_hunk":"@@ -2,3 +2,3 @@\n \n-Test repository for testing migration from gitea 2 gitea\n\\ No newline at end of file\n+Test repository for testing migration from gitea 2 gitea","position":4,"original_position":0,"html_url":"https://gitea.com/gitea/test_repo/pulls/7#issuecomment-116561","pull_request_url":"https://gitea.com/gitea/test_repo/pulls/7"}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%2F1771%2Fcomments b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%2F1771%2Fcomments
new file mode 100644
index 0000000000..192224be31
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%2F1771%2Fcomments
@@ -0,0 +1,8 @@
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+Content-Type: application/json;charset=utf-8
+Content-Length: 3
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+
+[]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%2F1772%2Fcomments b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%2F1772%2Fcomments
new file mode 100644
index 0000000000..5652a52001
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%2F1772%2Fcomments
@@ -0,0 +1,8 @@
+Content-Type: application/json;charset=utf-8
+Content-Length: 3
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+
+[]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%3Flimit=50&page=1 b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%3Flimit=50&page=1
new file mode 100644
index 0000000000..6aa650bd9c
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%2F7%2Freviews%3Flimit=50&page=1
@@ -0,0 +1,9 @@
+Access-Control-Expose-Headers: X-Total-Count
+X-Content-Type-Options: nosniff
+Content-Type: application/json;charset=utf-8
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 3
+
+[{"id":1770,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"team":null,"state":"COMMENT","body":"","commit_id":"187ece0cb6631e2858a6872e5733433bb3ca3b03","stale":false,"official":false,"dismissed":true,"comments_count":1,"submitted_at":"2020-09-01T16:12:58Z","updated_at":"2021-04-18T22:00:49Z","html_url":"https://gitea.com/gitea/test_repo/pulls/7#issuecomment-116562","pull_request_url":"https://gitea.com/gitea/test_repo/pulls/7"},{"id":1771,"user":{"id":9,"login":"techknowlogick","login_name":"","source_id":0,"full_name":"","email":"techknowlogick@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/9b588dd0b384d6f6ae841c5d62302033","html_url":"https://gitea.com/techknowlogick","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-01-14T06:48:35Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":11,"following_count":1,"starred_repos_count":4,"username":"techknowlogick"},"team":null,"state":"REQUEST_CHANGES","body":"I think this needs some changes","commit_id":"187ece0cb6631e2858a6872e5733433bb3ca3b03","stale":false,"official":false,"dismissed":true,"comments_count":0,"submitted_at":"2020-09-01T17:06:47Z","updated_at":"2021-04-18T22:00:49Z","html_url":"https://gitea.com/gitea/test_repo/pulls/7#issuecomment-116563","pull_request_url":"https://gitea.com/gitea/test_repo/pulls/7"},{"id":1772,"user":{"id":9,"login":"techknowlogick","login_name":"","source_id":0,"full_name":"","email":"techknowlogick@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/9b588dd0b384d6f6ae841c5d62302033","html_url":"https://gitea.com/techknowlogick","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-01-14T06:48:35Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":11,"following_count":1,"starred_repos_count":4,"username":"techknowlogick"},"team":null,"state":"APPROVED","body":"looks good","commit_id":"187ece0cb6631e2858a6872e5733433bb3ca3b03","stale":false,"official":true,"dismissed":true,"comments_count":0,"submitted_at":"2020-09-01T17:19:51Z","updated_at":"2021-04-18T22:00:49Z","html_url":"https://gitea.com/gitea/test_repo/pulls/7#issuecomment-116564","pull_request_url":"https://gitea.com/gitea/test_repo/pulls/7"}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%3Flimit=3&page=1&state=all b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%3Flimit=3&page=1&state=all
new file mode 100644
index 0000000000..256c67cc1a
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%3Flimit=3&page=1&state=all
@@ -0,0 +1,10 @@
+Access-Control-Expose-Headers: Link, X-Total-Count
+Link: ; rel="next",; rel="last"
+Vary: Origin
+Content-Type: application/json;charset=utf-8
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 6
+
+[{"id":4955,"url":"https://gitea.com/gitea/test_repo/pulls/13","number":13,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"title":"extend","body":"","labels":[],"milestone":null,"assignee":null,"assignees":null,"requested_reviewers":null,"requested_reviewers_teams":null,"state":"open","draft":false,"is_locked":true,"comments":1,"review_comments":0,"additions":1,"deletions":0,"changed_files":1,"html_url":"https://gitea.com/gitea/test_repo/pulls/13","diff_url":"https://gitea.com/gitea/test_repo/pulls/13.diff","patch_url":"https://gitea.com/gitea/test_repo/pulls/13.patch","mergeable":true,"merged":false,"merged_at":null,"merge_commit_sha":null,"merged_by":null,"allow_maintainer_edit":false,"base":{"label":"master","ref":"master","sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"head":{"label":"6543-patch-1","ref":"6543-patch-1","sha":"0ba7693bfd50d26df7f1b7414e937786c5efb05d","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"merge_base":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","due_date":null,"created_at":"2020-09-01T18:03:54Z","updated_at":"2020-09-01T18:04:26Z","closed_at":null,"pin_order":0},{"id":4954,"url":"https://gitea.com/gitea/test_repo/pulls/12","number":12,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"title":"Dont Touch","body":"\r\nadd dont touch note","labels":[],"milestone":{"id":1301,"title":"V2 Finalize","description":"","state":"open","open_issues":1,"closed_issues":2,"created_at":"1970-01-01T00:00:00Z","updated_at":"2022-11-13T05:29:15Z","closed_at":null,"due_on":"2020-09-04T23:59:59Z"},"assignee":{"id":9,"login":"techknowlogick","login_name":"","source_id":0,"full_name":"","email":"techknowlogick@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/9b588dd0b384d6f6ae841c5d62302033","html_url":"https://gitea.com/techknowlogick","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-01-14T06:48:35Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":11,"following_count":1,"starred_repos_count":4,"username":"techknowlogick"},"assignees":[{"id":9,"login":"techknowlogick","login_name":"","source_id":0,"full_name":"","email":"techknowlogick@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/9b588dd0b384d6f6ae841c5d62302033","html_url":"https://gitea.com/techknowlogick","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-01-14T06:48:35Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":11,"following_count":1,"starred_repos_count":4,"username":"techknowlogick"}],"requested_reviewers":null,"requested_reviewers_teams":null,"state":"closed","draft":false,"is_locked":false,"comments":0,"review_comments":3,"additions":1,"deletions":2,"changed_files":1,"html_url":"https://gitea.com/gitea/test_repo/pulls/12","diff_url":"https://gitea.com/gitea/test_repo/pulls/12.diff","patch_url":"https://gitea.com/gitea/test_repo/pulls/12.patch","mergeable":true,"merged":true,"merged_at":"2020-09-01T17:55:34Z","merge_commit_sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","merged_by":null,"allow_maintainer_edit":false,"base":{"label":"master","ref":"master","sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"head":{"label":"Add-Dont-Touch-Note","ref":"refs/pull/12/head","sha":"b6ab5d9ae000b579a5fff03f92c486da4ddf48b6","repo_id":16280,"repo":{"id":16280,"owner":{"id":9756,"login":"6543-forks","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/c3948ab3b9b62e070e87a22681909dee","html_url":"https://gitea.com/6543-forks","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2020-09-01T17:33:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"@6543's fork org","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"6543-forks"},"name":"test_repo","full_name":"6543-forks/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":true,"template":false,"parent":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null},"mirror":false,"size":67,"language":"","languages_url":"https://gitea.com/api/v1/repos/6543-forks/test_repo/languages","html_url":"https://gitea.com/6543-forks/test_repo","url":"https://gitea.com/api/v1/repos/6543-forks/test_repo","link":"","ssh_url":"git@gitea.com:6543-forks/test_repo.git","clone_url":"https://gitea.com/6543-forks/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"open_pr_counter":0,"release_counter":0,"default_branch":"master","archived":false,"created_at":"2020-09-01T17:39:26Z","updated_at":"2020-09-01T17:57:07Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":false,"has_wiki":false,"has_pull_requests":false,"has_projects":false,"projects_mode":"all","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":false,"allow_rebase":false,"allow_rebase_explicit":false,"allow_squash_merge":false,"allow_fast_forward_only_merge":false,"allow_rebase_update":false,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":[],"licenses":null}},"merge_base":"d9e165e4c7ab6b701f0205d0ffb637e5d2856297","due_date":null,"created_at":"2020-09-01T17:52:39Z","updated_at":"2020-09-02T05:10:25Z","closed_at":"2020-09-01T17:55:33Z","pin_order":0},{"id":4953,"url":"https://gitea.com/gitea/test_repo/pulls/11","number":11,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"title":"add-xkcd-2199","body":"","labels":[{"id":3734,"name":"Valid","exclusive":false,"is_archived":false,"color":"53e917","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3734"}],"milestone":null,"assignee":null,"assignees":null,"requested_reviewers":null,"requested_reviewers_teams":null,"state":"open","draft":false,"is_locked":false,"comments":0,"review_comments":0,"additions":0,"deletions":0,"changed_files":1,"html_url":"https://gitea.com/gitea/test_repo/pulls/11","diff_url":"https://gitea.com/gitea/test_repo/pulls/11.diff","patch_url":"https://gitea.com/gitea/test_repo/pulls/11.patch","mergeable":true,"merged":false,"merged_at":null,"merge_commit_sha":null,"merged_by":null,"allow_maintainer_edit":false,"base":{"label":"master","ref":"master","sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"head":{"label":"add-xkcd-2199","ref":"add-xkcd-2199","sha":"6bbd02573205288faa95d25e917812b2815a37e5","repo_id":16280,"repo":{"id":16280,"owner":{"id":9756,"login":"6543-forks","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/c3948ab3b9b62e070e87a22681909dee","html_url":"https://gitea.com/6543-forks","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2020-09-01T17:33:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"@6543's fork org","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"6543-forks"},"name":"test_repo","full_name":"6543-forks/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":true,"template":false,"parent":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null},"mirror":false,"size":67,"language":"","languages_url":"https://gitea.com/api/v1/repos/6543-forks/test_repo/languages","html_url":"https://gitea.com/6543-forks/test_repo","url":"https://gitea.com/api/v1/repos/6543-forks/test_repo","link":"","ssh_url":"git@gitea.com:6543-forks/test_repo.git","clone_url":"https://gitea.com/6543-forks/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"open_pr_counter":0,"release_counter":0,"default_branch":"master","archived":false,"created_at":"2020-09-01T17:39:26Z","updated_at":"2020-09-01T17:57:07Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":false,"has_wiki":false,"has_pull_requests":false,"has_projects":false,"projects_mode":"all","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":false,"allow_rebase":false,"allow_rebase_explicit":false,"allow_squash_merge":false,"allow_fast_forward_only_merge":false,"allow_rebase_update":false,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":[],"licenses":null}},"merge_base":"b6ab5d9ae000b579a5fff03f92c486da4ddf48b6","due_date":null,"created_at":"2020-09-01T17:52:28Z","updated_at":"2020-09-01T17:52:29Z","closed_at":null,"pin_order":0}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%3Flimit=50&page=1&state=all b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%3Flimit=50&page=1&state=all
new file mode 100644
index 0000000000..e3a86c5b54
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Fpulls%3Flimit=50&page=1&state=all
@@ -0,0 +1,9 @@
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Total-Count: 6
+Content-Type: application/json;charset=utf-8
+X-Frame-Options: SAMEORIGIN
+
+[{"id":4955,"url":"https://gitea.com/gitea/test_repo/pulls/13","number":13,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"title":"extend","body":"","labels":[],"milestone":null,"assignee":null,"assignees":null,"requested_reviewers":null,"requested_reviewers_teams":null,"state":"open","draft":false,"is_locked":true,"comments":1,"review_comments":0,"additions":1,"deletions":0,"changed_files":1,"html_url":"https://gitea.com/gitea/test_repo/pulls/13","diff_url":"https://gitea.com/gitea/test_repo/pulls/13.diff","patch_url":"https://gitea.com/gitea/test_repo/pulls/13.patch","mergeable":true,"merged":false,"merged_at":null,"merge_commit_sha":null,"merged_by":null,"allow_maintainer_edit":false,"base":{"label":"master","ref":"master","sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"head":{"label":"6543-patch-1","ref":"6543-patch-1","sha":"0ba7693bfd50d26df7f1b7414e937786c5efb05d","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"merge_base":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","due_date":null,"created_at":"2020-09-01T18:03:54Z","updated_at":"2020-09-01T18:04:26Z","closed_at":null,"pin_order":0},{"id":4954,"url":"https://gitea.com/gitea/test_repo/pulls/12","number":12,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"title":"Dont Touch","body":"\r\nadd dont touch note","labels":[],"milestone":{"id":1301,"title":"V2 Finalize","description":"","state":"open","open_issues":1,"closed_issues":2,"created_at":"1970-01-01T00:00:00Z","updated_at":"2022-11-13T05:29:15Z","closed_at":null,"due_on":"2020-09-04T23:59:59Z"},"assignee":{"id":9,"login":"techknowlogick","login_name":"","source_id":0,"full_name":"","email":"techknowlogick@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/9b588dd0b384d6f6ae841c5d62302033","html_url":"https://gitea.com/techknowlogick","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-01-14T06:48:35Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":11,"following_count":1,"starred_repos_count":4,"username":"techknowlogick"},"assignees":[{"id":9,"login":"techknowlogick","login_name":"","source_id":0,"full_name":"","email":"techknowlogick@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/9b588dd0b384d6f6ae841c5d62302033","html_url":"https://gitea.com/techknowlogick","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-01-14T06:48:35Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"","visibility":"public","followers_count":11,"following_count":1,"starred_repos_count":4,"username":"techknowlogick"}],"requested_reviewers":null,"requested_reviewers_teams":null,"state":"closed","draft":false,"is_locked":false,"comments":0,"review_comments":3,"additions":1,"deletions":2,"changed_files":1,"html_url":"https://gitea.com/gitea/test_repo/pulls/12","diff_url":"https://gitea.com/gitea/test_repo/pulls/12.diff","patch_url":"https://gitea.com/gitea/test_repo/pulls/12.patch","mergeable":true,"merged":true,"merged_at":"2020-09-01T17:55:34Z","merge_commit_sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","merged_by":null,"allow_maintainer_edit":false,"base":{"label":"master","ref":"master","sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"head":{"label":"Add-Dont-Touch-Note","ref":"refs/pull/12/head","sha":"b6ab5d9ae000b579a5fff03f92c486da4ddf48b6","repo_id":16280,"repo":{"id":16280,"owner":{"id":9756,"login":"6543-forks","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/c3948ab3b9b62e070e87a22681909dee","html_url":"https://gitea.com/6543-forks","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2020-09-01T17:33:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"@6543's fork org","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"6543-forks"},"name":"test_repo","full_name":"6543-forks/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":true,"template":false,"parent":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null},"mirror":false,"size":67,"language":"","languages_url":"https://gitea.com/api/v1/repos/6543-forks/test_repo/languages","html_url":"https://gitea.com/6543-forks/test_repo","url":"https://gitea.com/api/v1/repos/6543-forks/test_repo","link":"","ssh_url":"git@gitea.com:6543-forks/test_repo.git","clone_url":"https://gitea.com/6543-forks/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"open_pr_counter":0,"release_counter":0,"default_branch":"master","archived":false,"created_at":"2020-09-01T17:39:26Z","updated_at":"2020-09-01T17:57:07Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":false,"has_wiki":false,"has_pull_requests":false,"has_projects":false,"projects_mode":"all","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":false,"allow_rebase":false,"allow_rebase_explicit":false,"allow_squash_merge":false,"allow_fast_forward_only_merge":false,"allow_rebase_update":false,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":[],"licenses":null}},"merge_base":"d9e165e4c7ab6b701f0205d0ffb637e5d2856297","due_date":null,"created_at":"2020-09-01T17:52:39Z","updated_at":"2020-09-02T05:10:25Z","closed_at":"2020-09-01T17:55:33Z","pin_order":0},{"id":4953,"url":"https://gitea.com/gitea/test_repo/pulls/11","number":11,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"title":"add-xkcd-2199","body":"","labels":[{"id":3734,"name":"Valid","exclusive":false,"is_archived":false,"color":"53e917","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3734"}],"milestone":null,"assignee":null,"assignees":null,"requested_reviewers":null,"requested_reviewers_teams":null,"state":"open","draft":false,"is_locked":false,"comments":0,"review_comments":0,"additions":0,"deletions":0,"changed_files":1,"html_url":"https://gitea.com/gitea/test_repo/pulls/11","diff_url":"https://gitea.com/gitea/test_repo/pulls/11.diff","patch_url":"https://gitea.com/gitea/test_repo/pulls/11.patch","mergeable":true,"merged":false,"merged_at":null,"merge_commit_sha":null,"merged_by":null,"allow_maintainer_edit":false,"base":{"label":"master","ref":"master","sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"head":{"label":"add-xkcd-2199","ref":"add-xkcd-2199","sha":"6bbd02573205288faa95d25e917812b2815a37e5","repo_id":16280,"repo":{"id":16280,"owner":{"id":9756,"login":"6543-forks","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/c3948ab3b9b62e070e87a22681909dee","html_url":"https://gitea.com/6543-forks","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2020-09-01T17:33:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"@6543's fork org","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"6543-forks"},"name":"test_repo","full_name":"6543-forks/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":true,"template":false,"parent":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null},"mirror":false,"size":67,"language":"","languages_url":"https://gitea.com/api/v1/repos/6543-forks/test_repo/languages","html_url":"https://gitea.com/6543-forks/test_repo","url":"https://gitea.com/api/v1/repos/6543-forks/test_repo","link":"","ssh_url":"git@gitea.com:6543-forks/test_repo.git","clone_url":"https://gitea.com/6543-forks/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"open_pr_counter":0,"release_counter":0,"default_branch":"master","archived":false,"created_at":"2020-09-01T17:39:26Z","updated_at":"2020-09-01T17:57:07Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":false,"has_wiki":false,"has_pull_requests":false,"has_projects":false,"projects_mode":"all","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":false,"allow_rebase":false,"allow_rebase_explicit":false,"allow_squash_merge":false,"allow_fast_forward_only_merge":false,"allow_rebase_update":false,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":[],"licenses":null}},"merge_base":"b6ab5d9ae000b579a5fff03f92c486da4ddf48b6","due_date":null,"created_at":"2020-09-01T17:52:28Z","updated_at":"2020-09-01T17:52:29Z","closed_at":null,"pin_order":0},{"id":4952,"url":"https://gitea.com/gitea/test_repo/pulls/8","number":8,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"title":"add garbage for close pull","body":"well you'll see","labels":[],"milestone":null,"assignee":null,"assignees":null,"requested_reviewers":null,"requested_reviewers_teams":null,"state":"closed","draft":false,"is_locked":false,"comments":0,"review_comments":0,"additions":1,"deletions":2,"changed_files":1,"html_url":"https://gitea.com/gitea/test_repo/pulls/8","diff_url":"https://gitea.com/gitea/test_repo/pulls/8.diff","patch_url":"https://gitea.com/gitea/test_repo/pulls/8.patch","mergeable":true,"merged":false,"merged_at":null,"merge_commit_sha":null,"merged_by":null,"allow_maintainer_edit":false,"base":{"label":"master","ref":"master","sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"head":{"label":"garbage-patch","ref":"refs/pull/8/head","sha":"a3427235639a33d2d749e76f076e7619acc75341","repo_id":16280,"repo":{"id":16280,"owner":{"id":9756,"login":"6543-forks","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/c3948ab3b9b62e070e87a22681909dee","html_url":"https://gitea.com/6543-forks","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2020-09-01T17:33:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"","website":"https://codeberg.org/forgejo/forgejo/","description":"@6543's fork org","visibility":"public","followers_count":0,"following_count":0,"starred_repos_count":0,"username":"6543-forks"},"name":"test_repo","full_name":"6543-forks/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":true,"template":false,"parent":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null},"mirror":false,"size":67,"language":"","languages_url":"https://gitea.com/api/v1/repos/6543-forks/test_repo/languages","html_url":"https://gitea.com/6543-forks/test_repo","url":"https://gitea.com/api/v1/repos/6543-forks/test_repo","link":"","ssh_url":"git@gitea.com:6543-forks/test_repo.git","clone_url":"https://gitea.com/6543-forks/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":0,"forks_count":0,"watchers_count":1,"open_issues_count":0,"open_pr_counter":0,"release_counter":0,"default_branch":"master","archived":false,"created_at":"2020-09-01T17:39:26Z","updated_at":"2020-09-01T17:57:07Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":false,"has_wiki":false,"has_pull_requests":false,"has_projects":false,"projects_mode":"all","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":false,"allow_rebase":false,"allow_rebase_explicit":false,"allow_squash_merge":false,"allow_fast_forward_only_merge":false,"allow_rebase_update":false,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":[],"licenses":null}},"merge_base":"d9e165e4c7ab6b701f0205d0ffb637e5d2856297","due_date":null,"created_at":"2020-09-01T17:43:20Z","updated_at":"2020-09-01T17:48:41Z","closed_at":"2020-09-01T17:48:29Z","pin_order":0},{"id":4951,"url":"https://gitea.com/gitea/test_repo/pulls/7","number":7,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"title":"Prepare for Release V1","body":"@techknowlogick you might have a look at it?\n\nclose #6","labels":[{"id":3735,"name":"Enhancement","exclusive":false,"is_archived":false,"color":"207de5","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3735"}],"milestone":{"id":1300,"title":"V1","description":"Generate Content","state":"closed","open_issues":0,"closed_issues":4,"created_at":"1970-01-01T00:00:00Z","updated_at":"1970-01-01T00:00:00Z","closed_at":"2020-09-01T18:36:46Z","due_on":null},"assignee":null,"assignees":null,"requested_reviewers":null,"requested_reviewers_teams":null,"state":"closed","draft":false,"is_locked":false,"comments":1,"review_comments":3,"additions":3,"deletions":1,"changed_files":1,"html_url":"https://gitea.com/gitea/test_repo/pulls/7","diff_url":"https://gitea.com/gitea/test_repo/pulls/7.diff","patch_url":"https://gitea.com/gitea/test_repo/pulls/7.patch","mergeable":true,"merged":true,"merged_at":"2020-09-01T17:26:02Z","merge_commit_sha":"d9e165e4c7ab6b701f0205d0ffb637e5d2856297","merged_by":null,"allow_maintainer_edit":false,"base":{"label":"master","ref":"master","sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"head":{"label":"prepare-v1","ref":"refs/pull/7/head","sha":"187ece0cb6631e2858a6872e5733433bb3ca3b03","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"merge_base":"9396b697d905d1bcb5380befdf4d7e52c6a7ceb2","due_date":null,"created_at":"2020-09-01T16:10:04Z","updated_at":"2020-09-01T17:26:08Z","closed_at":"2020-09-01T17:26:02Z","pin_order":0},{"id":4949,"url":"https://gitea.com/gitea/test_repo/pulls/3","number":3,"user":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@obermui.de","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"title":"Readme: use '2'","body":"","labels":[{"id":3735,"name":"Enhancement","exclusive":false,"is_archived":false,"color":"207de5","description":"","url":"https://gitea.com/api/v1/repos/gitea/test_repo/labels/3735"}],"milestone":{"id":1300,"title":"V1","description":"Generate Content","state":"closed","open_issues":0,"closed_issues":4,"created_at":"1970-01-01T00:00:00Z","updated_at":"1970-01-01T00:00:00Z","closed_at":"2020-09-01T18:36:46Z","due_on":null},"assignee":null,"assignees":null,"requested_reviewers":null,"requested_reviewers_teams":null,"state":"closed","draft":false,"is_locked":false,"comments":0,"review_comments":0,"additions":1,"deletions":1,"changed_files":1,"html_url":"https://gitea.com/gitea/test_repo/pulls/3","diff_url":"https://gitea.com/gitea/test_repo/pulls/3.diff","patch_url":"https://gitea.com/gitea/test_repo/pulls/3.patch","mergeable":true,"merged":true,"merged_at":"2020-09-01T00:27:14Z","merge_commit_sha":"9396b697d905d1bcb5380befdf4d7e52c6a7ceb2","merged_by":null,"allow_maintainer_edit":false,"base":{"label":"master","ref":"master","sha":"827aa28a907853e5ddfa40c8f9bc52471a2685fd","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"head":{"label":"readme_nit","ref":"refs/pull/3/head","sha":"c273a16d4c3b2d745df690005dabe79cc6504ac3","repo_id":16268,"repo":{"id":16268,"owner":{"id":3,"login":"gitea","login_name":"","source_id":0,"full_name":"","email":"","avatar_url":"https://gitea.com/avatars/35dea380390772b3130aafbac7ca49e6","html_url":"https://gitea.com/gitea","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2018-11-29T03:16:17Z","restricted":false,"active":false,"prohibit_login":false,"location":"Git Universe","website":"https://codeberg.org/forgejo/forgejo/","description":"Git with a cup of tea","visibility":"public","followers_count":53,"following_count":0,"starred_repos_count":0,"username":"gitea"},"name":"test_repo","full_name":"gitea/test_repo","description":"Test repository for testing migration from gitea to gitea","empty":false,"private":false,"fork":false,"template":false,"parent":null,"mirror":false,"size":68,"language":"","languages_url":"https://gitea.com/api/v1/repos/gitea/test_repo/languages","html_url":"https://gitea.com/gitea/test_repo","url":"https://gitea.com/api/v1/repos/gitea/test_repo","link":"","ssh_url":"git@gitea.com:gitea/test_repo.git","clone_url":"https://gitea.com/gitea/test_repo.git","original_url":"","website":"https://codeberg.org/forgejo/forgejo/","stars_count":1,"forks_count":2,"watchers_count":9,"open_issues_count":2,"open_pr_counter":2,"release_counter":2,"default_branch":"master","archived":false,"created_at":"2020-09-01T00:12:27Z","updated_at":"2020-09-01T18:03:41Z","archived_at":"1970-01-01T00:00:00Z","permissions":{"admin":false,"push":false,"pull":true},"has_issues":true,"internal_tracker":{"enable_time_tracker":true,"allow_only_contributors_to_track_time":true,"enable_issue_dependencies":true},"has_wiki":true,"has_pull_requests":true,"has_projects":true,"projects_mode":"","has_releases":true,"has_packages":false,"has_actions":false,"ignore_whitespace_conflicts":false,"allow_merge_commits":true,"allow_rebase":true,"allow_rebase_explicit":true,"allow_squash_merge":true,"allow_fast_forward_only_merge":false,"allow_rebase_update":true,"default_delete_branch_after_merge":false,"default_merge_style":"merge","default_allow_maintainer_edit":false,"avatar_url":"","internal":false,"mirror_interval":"","object_format_name":"sha1","mirror_updated":"0001-01-01T00:00:00Z","repo_transfer":null,"topics":["gitea","test","migration","ci"],"licenses":null}},"merge_base":"a016fd754759b2cdfe5cad1cdf638c7e6b281940","due_date":null,"created_at":"2020-09-01T00:27:03Z","updated_at":"2020-09-01T15:54:30Z","closed_at":"2020-09-01T00:27:14Z","pin_order":0}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Freleases%3Flimit=50&page=1 b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Freleases%3Flimit=50&page=1
new file mode 100644
index 0000000000..bfd164ac2a
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Freleases%3Flimit=50&page=1
@@ -0,0 +1,9 @@
+Content-Type: application/json;charset=utf-8
+Vary: Origin
+X-Frame-Options: SAMEORIGIN
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+X-Content-Type-Options: nosniff
+X-Total-Count: 2
+
+[{"id":167250,"tag_name":"v2-rc1","target_commitish":"master","name":"Second Release","body":"this repo has:\r\n* reactions\r\n* wiki\r\n* issues (open/closed)\r\n* pulls (open/closed/merged) (external/internal)\r\n* pull reviews\r\n* projects\r\n* milestones\r\n* labels\r\n* releases\r\n\r\nto test migration against","url":"https://gitea.com/api/v1/repos/gitea/test_repo/releases/167250","html_url":"https://gitea.com/gitea/test_repo/releases/tag/v2-rc1","tarball_url":"https://gitea.com/gitea/test_repo/archive/v2-rc1.tar.gz","zipball_url":"https://gitea.com/gitea/test_repo/archive/v2-rc1.zip","upload_url":"https://gitea.com/api/v1/repos/gitea/test_repo/releases/167250/assets","draft":false,"prerelease":true,"created_at":"2020-09-01T18:02:43Z","published_at":"2020-09-01T18:02:43Z","author":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"assets":[]},{"id":167249,"tag_name":"V1","target_commitish":"master","name":"First Release","body":"as title","url":"https://gitea.com/api/v1/repos/gitea/test_repo/releases/167249","html_url":"https://gitea.com/gitea/test_repo/releases/tag/V1","tarball_url":"https://gitea.com/gitea/test_repo/archive/V1.tar.gz","zipball_url":"https://gitea.com/gitea/test_repo/archive/V1.zip","upload_url":"https://gitea.com/api/v1/repos/gitea/test_repo/releases/167249/assets","draft":false,"prerelease":false,"created_at":"2020-09-01T17:30:32Z","published_at":"2020-09-01T17:30:32Z","author":{"id":689,"login":"6543","login_name":"","source_id":0,"full_name":"","email":"6543@noreply.gitea.com","avatar_url":"https://gitea.com/avatars/aeb6c290f1988daefa7421c5409e80dc","html_url":"https://gitea.com/6543","language":"","is_admin":false,"last_login":"0001-01-01T00:00:00Z","created":"2019-07-17T21:08:41Z","restricted":false,"active":false,"prohibit_login":false,"location":"Germany","website":"https://codeberg.org/forgejo/forgejo/","description":"gitea instance: https://code.obermui.de","visibility":"public","followers_count":10,"following_count":7,"starred_repos_count":18,"username":"6543"},"assets":[]}]
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Ftopics%3Flimit=0&page=1 b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Ftopics%3Flimit=0&page=1
new file mode 100644
index 0000000000..4d1cf9e322
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Frepos%2Fgitea%2Ftest_repo%2Ftopics%3Flimit=0&page=1
@@ -0,0 +1,10 @@
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+X-Total-Count: 4
+Content-Length: 45
+Access-Control-Expose-Headers: X-Total-Count
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Content-Type: application/json;charset=utf-8
+
+{"topics":["ci","gitea","migration","test"]}
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Fsettings%2Fapi b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Fsettings%2Fapi
new file mode 100644
index 0000000000..f16a0a33c8
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Fsettings%2Fapi
@@ -0,0 +1,8 @@
+Content-Type: application/json;charset=utf-8
+Content-Length: 117
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+
+{"max_response_items":50,"default_paging_num":30,"default_git_trees_per_page":1000,"default_max_blob_size":10485760}
diff --git a/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Fversion b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Fversion
new file mode 100644
index 0000000000..739d679c0d
--- /dev/null
+++ b/services/migrations/testdata/gitea/full_download/GET_%2Fapi%2Fv1%2Fversion
@@ -0,0 +1,8 @@
+Content-Length: 41
+Cache-Control: max-age=0, private, must-revalidate, no-transform
+Vary: Origin
+X-Content-Type-Options: nosniff
+X-Frame-Options: SAMEORIGIN
+Content-Type: application/json;charset=utf-8
+
+{"version":"1.23.0+dev-608-gec2d1593c2"}
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frate_limit b/services/migrations/testdata/github/full_download/GET_%2Frate_limit
new file mode 100644
index 0000000000..74e43a0765
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frate_limit
@@ -0,0 +1,23 @@
+Cache-Control: no-cache
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Ratelimit-Reset: 1730800941
+Access-Control-Allow-Origin: *
+Content-Type: application/json; charset=utf-8
+X-Oauth-Scopes:
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Remaining: 4899
+X-Xss-Protection: 0
+Content-Security-Policy: default-src 'none'
+X-Accepted-Oauth-Scopes:
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+Vary: Accept-Encoding, Accept, X-Requested-With
+X-Github-Request-Id: C7CC:3118FC:3F6234D:4038C5B:6729E6C0
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Used: 101
+X-Ratelimit-Resource: core
+
+{"resources":{"core":{"limit":5000,"used":101,"remaining":4899,"reset":1730800941},"search":{"limit":30,"used":0,"remaining":30,"reset":1730799356},"graphql":{"limit":5000,"used":162,"remaining":4838,"reset":1730801064},"integration_manifest":{"limit":5000,"used":0,"remaining":5000,"reset":1730802896},"source_import":{"limit":100,"used":0,"remaining":100,"reset":1730799356},"code_scanning_upload":{"limit":1000,"used":0,"remaining":1000,"reset":1730802896},"actions_runner_registration":{"limit":10000,"used":0,"remaining":10000,"reset":1730802896},"scim":{"limit":15000,"used":0,"remaining":15000,"reset":1730802896},"dependency_snapshots":{"limit":100,"used":0,"remaining":100,"reset":1730799356},"audit_log":{"limit":1750,"used":0,"remaining":1750,"reset":1730802896},"audit_log_streaming":{"limit":15,"used":0,"remaining":15,"reset":1730802896},"code_search":{"limit":10,"used":0,"remaining":10,"reset":1730799356}},"rate":{"limit":5000,"used":101,"remaining":4899,"reset":1730800941}}
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo
new file mode 100644
index 0000000000..78fde4d424
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo
@@ -0,0 +1,25 @@
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
+X-Github-Request-Id: C7CC:3118FC:3F5EFD7:403585D:6729E6B3
+Cache-Control: private, max-age=60, s-maxage=60
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Media-Type: github.v3; param=scarlet-witch-preview; format=json, github.mercy-preview; param=baptiste-preview.nebula-preview; format=json
+Etag: W/"bb1c9e0186e52dbd9f2c34aaf0827517384a15fd0cee7b81ad13784901db15c0"
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+X-Ratelimit-Limit: 5000
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Last-Modified: Thu, 02 Mar 2023 14:02:26 GMT
+X-Ratelimit-Remaining: 4928
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Used: 72
+X-Frame-Options: deny
+Content-Security-Policy: default-src 'none'
+
+{"id":220672974,"node_id":"MDEwOlJlcG9zaXRvcnkyMjA2NzI5NzQ=","name":"test_repo","full_name":"go-gitea/test_repo","private":false,"owner":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/go-gitea/test_repo","description":"Test repository for testing migration from github to gitea","fork":false,"url":"https://api.github.com/repos/go-gitea/test_repo","forks_url":"https://api.github.com/repos/go-gitea/test_repo/forks","keys_url":"https://api.github.com/repos/go-gitea/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/go-gitea/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/go-gitea/test_repo/teams","hooks_url":"https://api.github.com/repos/go-gitea/test_repo/hooks","issue_events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/go-gitea/test_repo/events","assignees_url":"https://api.github.com/repos/go-gitea/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/go-gitea/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/go-gitea/test_repo/tags","blobs_url":"https://api.github.com/repos/go-gitea/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/go-gitea/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/go-gitea/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/go-gitea/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/go-gitea/test_repo/languages","stargazers_url":"https://api.github.com/repos/go-gitea/test_repo/stargazers","contributors_url":"https://api.github.com/repos/go-gitea/test_repo/contributors","subscribers_url":"https://api.github.com/repos/go-gitea/test_repo/subscribers","subscription_url":"https://api.github.com/repos/go-gitea/test_repo/subscription","commits_url":"https://api.github.com/repos/go-gitea/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/go-gitea/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/go-gitea/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/go-gitea/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/go-gitea/test_repo/merges","archive_url":"https://api.github.com/repos/go-gitea/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/go-gitea/test_repo/downloads","issues_url":"https://api.github.com/repos/go-gitea/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/go-gitea/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/go-gitea/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/go-gitea/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/go-gitea/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/go-gitea/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/go-gitea/test_repo/deployments","created_at":"2019-11-09T16:49:20Z","updated_at":"2023-03-02T14:02:26Z","pushed_at":"2019-11-12T21:54:19Z","git_url":"git://github.com/go-gitea/test_repo.git","ssh_url":"git@github.com:go-gitea/test_repo.git","clone_url":"https://github.com/go-gitea/test_repo.git","svn_url":"https://github.com/go-gitea/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":1,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":6,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":2,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["gitea"],"visibility":"public","forks":6,"open_issues":2,"watchers":3,"default_branch":"master","permissions":{"admin":false,"maintain":false,"push":false,"triage":false,"pull":true},"temp_clone_token":"","custom_properties":{},"organization":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"network_count":6,"subscribers_count":6}
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=1&per_page=2
new file mode 100644
index 0000000000..f1f9afee15
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=1&per_page=2
@@ -0,0 +1,24 @@
+Cache-Control: private, max-age=60, s-maxage=60
+X-Ratelimit-Remaining: 4923
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Accepted-Oauth-Scopes: repo
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Resource: core
+Content-Security-Policy: default-src 'none'
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Used: 77
+Access-Control-Allow-Origin: *
+X-Xss-Protection: 0
+X-Github-Request-Id: C7CC:3118FC:3F5F8DA:403618E:6729E6B6
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+Etag: W/"07b6d56c5fdc728f96fceef3d45d26b4ebac96ef5138156668055f7d496c9a75"
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+
+[{"id":55441655,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0MTY1NQ==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"+1","created_at":"2019-11-12T20:22:13Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=2&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=2&per_page=2
new file mode 100644
index 0000000000..fe993d3c3b
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F1%2Freactions%3Fpage=2&per_page=2
@@ -0,0 +1,26 @@
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Github-Api-Version-Selected: 2022-11-28
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+Content-Length: 2
+Cache-Control: private, max-age=60, s-maxage=60
+Link: ; rel="prev", ; rel="last", ; rel="first"
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4922
+X-Ratelimit-Reset: 1730800941
+X-Xss-Protection: 0
+X-Github-Request-Id: C7CC:3118FC:3F5FA7C:403633C:6729E6B6
+X-Oauth-Scopes:
+X-Ratelimit-Used: 78
+X-Frame-Options: deny
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Accepted-Oauth-Scopes: repo
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Content-Security-Policy: default-src 'none'
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Fcomments%3Fdirection=asc&per_page=100&sort=created b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Fcomments%3Fdirection=asc&per_page=100&sort=created
new file mode 100644
index 0000000000..61867c5ae6
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Fcomments%3Fdirection=asc&per_page=100&sort=created
@@ -0,0 +1,24 @@
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Remaining: 4917
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Type: application/json; charset=utf-8
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Used: 83
+X-Content-Type-Options: nosniff
+X-Github-Request-Id: C7CC:3118FC:3F60409:4036CD0:6729E6B8
+Etag: W/"5f4d715f2578719997e324fe7b29e7eeeec048288237b44d4f320666514813ad"
+X-Accepted-Oauth-Scopes:
+X-Frame-Options: deny
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Content-Security-Policy: default-src 'none'
+Cache-Control: private, max-age=60, s-maxage=60
+X-Oauth-Scopes:
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments/553111966","html_url":"https://github.com/go-gitea/test_repo/issues/2#issuecomment-553111966","issue_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2","id":553111966,"node_id":"MDEyOklzc3VlQ29tbWVudDU1MzExMTk2Ng==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"created_at":"2019-11-12T21:00:13Z","updated_at":"2019-11-12T21:00:13Z","author_association":"MEMBER","body":"This is a comment","reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments/553111966/reactions","total_count":1,"+1":1,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":null},{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments/553138856","html_url":"https://github.com/go-gitea/test_repo/issues/2#issuecomment-553138856","issue_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2","id":553138856,"node_id":"MDEyOklzc3VlQ29tbWVudDU1MzEzODg1Ng==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"created_at":"2019-11-12T22:07:14Z","updated_at":"2019-11-12T22:07:14Z","author_association":"MEMBER","body":"A second comment","reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments/553138856/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"performed_via_github_app":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=1&per_page=2
new file mode 100644
index 0000000000..bb9dea395c
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=1&per_page=2
@@ -0,0 +1,25 @@
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+X-Accepted-Oauth-Scopes: repo
+Link: ; rel="next", ; rel="last"
+X-Ratelimit-Remaining: 4921
+X-Ratelimit-Reset: 1730800941
+X-Github-Request-Id: C7CC:3118FC:3F5FC1A:40364D4:6729E6B6
+Content-Security-Policy: default-src 'none'
+X-Oauth-Scopes:
+X-Ratelimit-Used: 79
+X-Frame-Options: deny
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Api-Version-Selected: 2022-11-28
+Content-Type: application/json; charset=utf-8
+Etag: W/"27408cb5dd95878d6267de226341c84fd1d2c49695867baecf930579608e16a5"
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Content-Type-Options: nosniff
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Limit: 5000
+Access-Control-Allow-Origin: *
+
+[{"id":55445108,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTEwOA==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"heart","created_at":"2019-11-12T21:02:05Z"},{"id":55445150,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTE1MA==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"laugh","created_at":"2019-11-12T21:02:35Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=2&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=2&per_page=2
new file mode 100644
index 0000000000..e59fc93546
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=2&per_page=2
@@ -0,0 +1,25 @@
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Resource: core
+X-Frame-Options: deny
+Etag: W/"cb64a4e91ab70a1ab9fe2f77cdbf7452120169f4c2cce397014efe94cc0d60bb"
+Link: ; rel="prev", ; rel="next", ; rel="last", ; rel="first"
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Request-Id: C7CC:3118FC:3F5FDBD:4036670:6729E6B7
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Access-Control-Allow-Origin: *
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4920
+X-Ratelimit-Used: 80
+X-Accepted-Oauth-Scopes: repo
+
+[{"id":55445169,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTE2OQ==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"-1","created_at":"2019-11-12T21:02:47Z"},{"id":55445177,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTE3Nw==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"confused","created_at":"2019-11-12T21:02:52Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=3&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=3&per_page=2
new file mode 100644
index 0000000000..57f03c8a64
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=3&per_page=2
@@ -0,0 +1,25 @@
+Etag: W/"17b0dca978a885d2234548248a7d5c22264c161b73e28c5cd144e33a24dd9ed4"
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Used: 81
+Content-Security-Policy: default-src 'none'
+Content-Type: application/json; charset=utf-8
+X-Oauth-Scopes:
+Link: ; rel="prev", ; rel="first"
+X-Ratelimit-Limit: 5000
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+X-Accepted-Oauth-Scopes: repo
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+Access-Control-Allow-Origin: *
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Remaining: 4919
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Github-Request-Id: C7CC:3118FC:3F5FF70:403681F:6729E6B7
+
+[{"id":55445188,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTE4OA==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"hooray","created_at":"2019-11-12T21:02:58Z"},{"id":55445441,"node_id":"MDEzOklzc3VlUmVhY3Rpb241NTQ0NTQ0MQ==","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?u=7c1ba931adbdd9bab5be1a41d244425d463568cd&v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"+1","created_at":"2019-11-12T21:06:04Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=4&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=4&per_page=2
new file mode 100644
index 0000000000..f14d4ba904
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F2%2Freactions%3Fpage=4&per_page=2
@@ -0,0 +1,26 @@
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4918
+X-Ratelimit-Reset: 1730800941
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+X-Github-Request-Id: C7CC:3118FC:3F60229:4036AE8:6729E6B8
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+Link: ; rel="prev", ; rel="last", ; rel="first"
+X-Accepted-Oauth-Scopes: repo
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Used: 82
+X-Frame-Options: deny
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Cache-Control: private, max-age=60, s-maxage=60
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+Content-Length: 2
+Content-Security-Policy: default-src 'none'
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=1&per_page=2
new file mode 100644
index 0000000000..a7a105b3e7
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F3%2Freactions%3Fpage=1&per_page=2
@@ -0,0 +1,25 @@
+X-Ratelimit-Used: 88
+X-Ratelimit-Resource: core
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F60B4F:403741E:6729E6BA
+Content-Type: application/json; charset=utf-8
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Cache-Control: private, max-age=60, s-maxage=60
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Frame-Options: deny
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4912
+Content-Length: 2
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=1&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=1&per_page=2
new file mode 100644
index 0000000000..f5398c3a9f
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=1&per_page=2
@@ -0,0 +1,24 @@
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Etag: W/"dc9d10e1714eadc1507466c7d11d2dd84ae539a378835f8763b9948da44b22e1"
+X-Accepted-Oauth-Scopes: repo
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+Content-Type: application/json; charset=utf-8
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Remaining: 4911
+X-Ratelimit-Used: 89
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+X-Xss-Protection: 0
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F60D0F:40375F2:6729E6BB
+Cache-Control: private, max-age=60, s-maxage=60
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+
+[{"id":59496724,"node_id":"MDEzOklzc3VlUmVhY3Rpb241OTQ5NjcyNA==","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"heart","created_at":"2020-01-10T08:31:30Z"},{"id":59496731,"node_id":"MDEzOklzc3VlUmVhY3Rpb241OTQ5NjczMQ==","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"+1","created_at":"2020-01-10T08:31:39Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=2&per_page=2 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=2&per_page=2
new file mode 100644
index 0000000000..79b506ea55
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2F4%2Freactions%3Fpage=2&per_page=2
@@ -0,0 +1,26 @@
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+X-Ratelimit-Limit: 5000
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Length: 2
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+X-Ratelimit-Remaining: 4910
+X-Ratelimit-Reset: 1730800941
+X-Frame-Options: deny
+Content-Type: application/json; charset=utf-8
+Link: ; rel="prev", ; rel="last", ; rel="first"
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Request-Id: C7CC:3118FC:3F60EE6:40377B6:6729E6BB
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Used: 90
+X-Ratelimit-Resource: core
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Github-Api-Version-Selected: 2022-11-28
+Access-Control-Allow-Origin: *
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=1&per_page=100
new file mode 100644
index 0000000000..b55068a718
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=1&per_page=100
@@ -0,0 +1,24 @@
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Accepted-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Used: 84
+X-Ratelimit-Resource: core
+X-Content-Type-Options: nosniff
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"d2410fc0792a61666c06ed757aa53a273165d4f14f7d5259095b7a4f3a959121"
+X-Xss-Protection: 0
+Content-Security-Policy: default-src 'none'
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Remaining: 4916
+X-Frame-Options: deny
+X-Github-Request-Id: C7CC:3118FC:3F60583:4036E51:6729E6B9
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+
+[{"id":55446208,"node_id":"MDIwOklzc3VlQ29tbWVudFJlYWN0aW9uNTU0NDYyMDg=","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"content":"+1","created_at":"2019-11-12T21:13:22Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=2&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=2&per_page=100
new file mode 100644
index 0000000000..1e46f438e5
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553111966%2Freactions%3Fpage=2&per_page=100
@@ -0,0 +1,26 @@
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Cache-Control: private, max-age=60, s-maxage=60
+X-Ratelimit-Used: 85
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Request-Id: C7CC:3118FC:3F606F2:4036FB5:6729E6B9
+X-Xss-Protection: 0
+Content-Type: application/json; charset=utf-8
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Oauth-Scopes:
+Link: ; rel="prev", ; rel="last", ; rel="first"
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Resource: core
+X-Frame-Options: deny
+Content-Length: 2
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4915
+X-Ratelimit-Reset: 1730800941
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553138856%2Freactions%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553138856%2Freactions%3Fpage=1&per_page=100
new file mode 100644
index 0000000000..ac446b3586
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%2Fcomments%2F553138856%2Freactions%3Fpage=1&per_page=100
@@ -0,0 +1,25 @@
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Remaining: 4914
+X-Frame-Options: deny
+X-Xss-Protection: 0
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Resource: core
+X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Accepted-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+Content-Length: 2
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F60858:4037116:6729E6B9
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+X-Ratelimit-Used: 86
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%3Fdirection=asc&page=1&per_page=2&sort=created&state=all b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
new file mode 100644
index 0000000000..80d2f90dbc
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fissues%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
@@ -0,0 +1,25 @@
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+X-Xss-Protection: 0
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"40580a89c26a3f7793cea4e59315e52e1106be32ded27b3ab822b7d7f74a1ecf"
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Link: ; rel="next", ; rel="last"
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Content-Type-Options: nosniff
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Remaining: 4924
+X-Ratelimit-Used: 76
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F5F5B9:4035E6C:6729E6B5
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/1","repository_url":"https://api.github.com/repos/go-gitea/test_repo","labels_url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/comments","events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/events","html_url":"https://github.com/go-gitea/test_repo/issues/1","id":520479843,"node_id":"MDU6SXNzdWU1MjA0Nzk4NDM=","number":1,"title":"Please add an animated gif icon to the merge button","user":{"login":"guillep2k","id":18600385,"node_id":"MDQ6VXNlcjE4NjAwMzg1","avatar_url":"https://avatars.githubusercontent.com/u/18600385?v=4","gravatar_id":"","url":"https://api.github.com/users/guillep2k","html_url":"https://github.com/guillep2k","followers_url":"https://api.github.com/users/guillep2k/followers","following_url":"https://api.github.com/users/guillep2k/following{/other_user}","gists_url":"https://api.github.com/users/guillep2k/gists{/gist_id}","starred_url":"https://api.github.com/users/guillep2k/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guillep2k/subscriptions","organizations_url":"https://api.github.com/users/guillep2k/orgs","repos_url":"https://api.github.com/users/guillep2k/repos","events_url":"https://api.github.com/users/guillep2k/events{/privacy}","received_events_url":"https://api.github.com/users/guillep2k/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[{"id":1667254252,"node_id":"MDU6TGFiZWwxNjY3MjU0MjUy","url":"https://api.github.com/repos/go-gitea/test_repo/labels/bug","name":"bug","color":"d73a4a","default":true,"description":"Something isn't working"},{"id":1667254261,"node_id":"MDU6TGFiZWwxNjY3MjU0MjYx","url":"https://api.github.com/repos/go-gitea/test_repo/labels/good%20first%20issue","name":"good first issue","color":"7057ff","default":true,"description":"Good for newcomers"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1","html_url":"https://github.com/go-gitea/test_repo/milestone/1","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1/labels","id":4839941,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0MQ==","number":1,"title":"1.0.0","description":"Milestone 1.0.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":1,"state":"closed","created_at":"2019-11-12T19:37:08Z","updated_at":"2019-11-12T21:56:17Z","due_on":"2019-11-11T08:00:00Z","closed_at":"2019-11-12T19:45:49Z"},"comments":0,"created_at":"2019-11-09T17:00:29Z","updated_at":"2019-11-12T20:29:53Z","closed_at":"2019-11-12T20:22:22Z","author_association":"MEMBER","active_lock_reason":null,"body":"I just want the merge button to hurt my eyes a little. ๐ ","closed_by":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/reactions","total_count":1,"+1":1,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/go-gitea/test_repo/issues/1/timeline","performed_via_github_app":null,"state_reason":"completed"},{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/2","repository_url":"https://api.github.com/repos/go-gitea/test_repo","labels_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/labels{/name}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/comments","events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/events","html_url":"https://github.com/go-gitea/test_repo/issues/2","id":521799485,"node_id":"MDU6SXNzdWU1MjE3OTk0ODU=","number":2,"title":"Test issue","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"labels":[{"id":1667254257,"node_id":"MDU6TGFiZWwxNjY3MjU0MjU3","url":"https://api.github.com/repos/go-gitea/test_repo/labels/duplicate","name":"duplicate","color":"cfd3d7","default":true,"description":"This issue or pull request already exists"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2","html_url":"https://github.com/go-gitea/test_repo/milestone/2","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2/labels","id":4839942,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0Mg==","number":2,"title":"1.1.0","description":"Milestone 1.1.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":0,"closed_issues":2,"state":"closed","created_at":"2019-11-12T19:37:25Z","updated_at":"2019-11-12T21:39:27Z","due_on":"2019-11-12T08:00:00Z","closed_at":"2019-11-12T19:45:46Z"},"comments":2,"created_at":"2019-11-12T21:00:06Z","updated_at":"2019-11-12T22:07:14Z","closed_at":"2019-11-12T21:01:31Z","author_association":"MEMBER","active_lock_reason":null,"body":"This is test issue 2, do not touch!","closed_by":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/reactions","total_count":6,"+1":1,"-1":1,"laugh":1,"hooray":1,"confused":1,"heart":1,"rocket":0,"eyes":0},"timeline_url":"https://api.github.com/repos/go-gitea/test_repo/issues/2/timeline","performed_via_github_app":null,"state_reason":"completed"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Flabels%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Flabels%3Fpage=1&per_page=100
new file mode 100644
index 0000000000..f1d483aacb
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Flabels%3Fpage=1&per_page=100
@@ -0,0 +1,24 @@
+X-Ratelimit-Reset: 1730800941
+Access-Control-Allow-Origin: *
+Content-Security-Policy: default-src 'none'
+X-Github-Api-Version-Selected: 2022-11-28
+Etag: W/"01cc307b238564f2a086999fed53e0d5c880b8ec1d8d2256d99188ff47ff0ea0"
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Used: 74
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Ratelimit-Limit: 5000
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Cache-Control: private, max-age=60, s-maxage=60
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+X-Ratelimit-Remaining: 4926
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+X-Github-Request-Id: C7CC:3118FC:3F5F29C:4035B65:6729E6B4
+
+[{"id":1667254252,"node_id":"MDU6TGFiZWwxNjY3MjU0MjUy","url":"https://api.github.com/repos/go-gitea/test_repo/labels/bug","name":"bug","color":"d73a4a","default":true,"description":"Something isn't working"},{"id":1667254254,"node_id":"MDU6TGFiZWwxNjY3MjU0MjU0","url":"https://api.github.com/repos/go-gitea/test_repo/labels/documentation","name":"documentation","color":"0075ca","default":true,"description":"Improvements or additions to documentation"},{"id":1667254257,"node_id":"MDU6TGFiZWwxNjY3MjU0MjU3","url":"https://api.github.com/repos/go-gitea/test_repo/labels/duplicate","name":"duplicate","color":"cfd3d7","default":true,"description":"This issue or pull request already exists"},{"id":1667254260,"node_id":"MDU6TGFiZWwxNjY3MjU0MjYw","url":"https://api.github.com/repos/go-gitea/test_repo/labels/enhancement","name":"enhancement","color":"a2eeef","default":true,"description":"New feature or request"},{"id":1667254261,"node_id":"MDU6TGFiZWwxNjY3MjU0MjYx","url":"https://api.github.com/repos/go-gitea/test_repo/labels/good%20first%20issue","name":"good first issue","color":"7057ff","default":true,"description":"Good for newcomers"},{"id":1667254265,"node_id":"MDU6TGFiZWwxNjY3MjU0MjY1","url":"https://api.github.com/repos/go-gitea/test_repo/labels/help%20wanted","name":"help wanted","color":"008672","default":true,"description":"Extra attention is needed"},{"id":1667254269,"node_id":"MDU6TGFiZWwxNjY3MjU0MjY5","url":"https://api.github.com/repos/go-gitea/test_repo/labels/invalid","name":"invalid","color":"e4e669","default":true,"description":"This doesn't seem right"},{"id":1667254273,"node_id":"MDU6TGFiZWwxNjY3MjU0Mjcz","url":"https://api.github.com/repos/go-gitea/test_repo/labels/question","name":"question","color":"d876e3","default":true,"description":"Further information is requested"},{"id":1667254276,"node_id":"MDU6TGFiZWwxNjY3MjU0Mjc2","url":"https://api.github.com/repos/go-gitea/test_repo/labels/wontfix","name":"wontfix","color":"ffffff","default":true,"description":"This will not be worked on"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fmilestones%3Fpage=1&per_page=100&state=all b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fmilestones%3Fpage=1&per_page=100&state=all
new file mode 100644
index 0000000000..50b90ad4ab
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fmilestones%3Fpage=1&per_page=100&state=all
@@ -0,0 +1,24 @@
+X-Ratelimit-Remaining: 4927
+X-Ratelimit-Used: 73
+X-Frame-Options: deny
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes: repo
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+X-Github-Request-Id: C7CC:3118FC:3F5F16C:40359F7:6729E6B4
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Reset: 1730800941
+Content-Security-Policy: default-src 'none'
+X-Github-Api-Version-Selected: 2022-11-28
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"d6d673f0622636217ee3df16cdabbfea8402d3e8d1abbabe007108267b01f3e9"
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1","html_url":"https://github.com/go-gitea/test_repo/milestone/1","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1/labels","id":4839941,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0MQ==","number":1,"title":"1.0.0","description":"Milestone 1.0.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":1,"state":"closed","created_at":"2019-11-12T19:37:08Z","updated_at":"2019-11-12T21:56:17Z","due_on":"2019-11-11T08:00:00Z","closed_at":"2019-11-12T19:45:49Z"},{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2","html_url":"https://github.com/go-gitea/test_repo/milestone/2","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2/labels","id":4839942,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0Mg==","number":2,"title":"1.1.0","description":"Milestone 1.1.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":0,"closed_issues":2,"state":"closed","created_at":"2019-11-12T19:37:25Z","updated_at":"2019-11-12T21:39:27Z","due_on":"2019-11-12T08:00:00Z","closed_at":"2019-11-12T19:45:46Z"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Frequested_reviewers%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Frequested_reviewers%3Fper_page=100
new file mode 100644
index 0000000000..1b4481f890
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Frequested_reviewers%3Fper_page=100
@@ -0,0 +1,24 @@
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Etag: W/"21730161122bd4f229e886dd4a85b45fa575182d6dcef7aa0016a5d21353c9ab"
+X-Oauth-Scopes:
+X-Github-Media-Type: github.v3; format=json
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+X-Xss-Protection: 0
+X-Github-Request-Id: C7CC:3118FC:3F6187A:4038171:6729E6BD
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Content-Security-Policy: default-src 'none'
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Remaining: 4905
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Used: 95
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+
+{"users":[],"teams":[]}
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315859956%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315859956%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..435e1a0ee0
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315859956%2Fcomments%3Fper_page=100
@@ -0,0 +1,25 @@
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Used: 92
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+Content-Length: 2
+X-Oauth-Scopes:
+X-Ratelimit-Remaining: 4908
+X-Ratelimit-Reset: 1730800941
+X-Github-Request-Id: C7CC:3118FC:3F612D6:4037BAC:6729E6BC
+Etag: "450a1c087fec81e5b86092ff5372c3db8ca834c1e23c03c6b06ecca33cefd665"
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Cache-Control: private, max-age=60, s-maxage=60
+X-Accepted-Oauth-Scopes:
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Security-Policy: default-src 'none'
+Content-Type: application/json; charset=utf-8
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315860062%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315860062%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..389c1b7567
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315860062%2Fcomments%3Fper_page=100
@@ -0,0 +1,25 @@
+Content-Length: 2
+X-Frame-Options: deny
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Used: 93
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Type: application/json; charset=utf-8
+X-Accepted-Oauth-Scopes:
+X-Xss-Protection: 0
+X-Oauth-Scopes:
+X-Ratelimit-Remaining: 4907
+X-Ratelimit-Reset: 1730800941
+Access-Control-Allow-Origin: *
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Request-Id: C7CC:3118FC:3F614AA:4037DB7:6729E6BD
+X-Github-Media-Type: github.v3; format=json
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Etag: "450a1c087fec81e5b86092ff5372c3db8ca834c1e23c03c6b06ecca33cefd665"
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315861440%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315861440%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..e52428a5af
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%2F315861440%2Fcomments%3Fper_page=100
@@ -0,0 +1,25 @@
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+X-Ratelimit-Reset: 1730800941
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+X-Accepted-Oauth-Scopes:
+X-Xss-Protection: 0
+X-Github-Request-Id: C7CC:3118FC:3F61690:4037F90:6729E6BD
+Content-Length: 2
+X-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Frame-Options: deny
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Access-Control-Allow-Origin: *
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Etag: "450a1c087fec81e5b86092ff5372c3db8ca834c1e23c03c6b06ecca33cefd665"
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Remaining: 4906
+X-Ratelimit-Used: 94
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%3Fper_page=100
new file mode 100644
index 0000000000..203c363ffa
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F3%2Freviews%3Fper_page=100
@@ -0,0 +1,24 @@
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"e38ac3d6f3e77a469f9836bfa52a0b756b9ac8fdc4347530e1cb1072bbb77b46"
+X-Github-Media-Type: github.v3; format=json
+X-Frame-Options: deny
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Accepted-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Remaining: 4909
+X-Ratelimit-Reset: 1730800941
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F6108F:403797A:6729E6BC
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+X-Content-Type-Options: nosniff
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Oauth-Scopes:
+X-Ratelimit-Used: 91
+X-Xss-Protection: 0
+
+[{"id":315859956,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzE1ODU5OTU2","user":{"login":"jolheiser","id":42128690,"node_id":"MDQ6VXNlcjQyMTI4Njkw","avatar_url":"https://avatars.githubusercontent.com/u/42128690?u=0ee1052506846129445fa12a76cd9ad9d305de71&v=4","gravatar_id":"","url":"https://api.github.com/users/jolheiser","html_url":"https://github.com/jolheiser","followers_url":"https://api.github.com/users/jolheiser/followers","following_url":"https://api.github.com/users/jolheiser/following{/other_user}","gists_url":"https://api.github.com/users/jolheiser/gists{/gist_id}","starred_url":"https://api.github.com/users/jolheiser/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jolheiser/subscriptions","organizations_url":"https://api.github.com/users/jolheiser/orgs","repos_url":"https://api.github.com/users/jolheiser/repos","events_url":"https://api.github.com/users/jolheiser/events{/privacy}","received_events_url":"https://api.github.com/users/jolheiser/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"APPROVED","html_url":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315859956","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315859956"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3"}},"submitted_at":"2019-11-12T21:35:24Z","commit_id":"076160cf0b039f13e5eff19619932d181269414b"},{"id":315860062,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzE1ODYwMDYy","user":{"login":"zeripath","id":1824502,"node_id":"MDQ6VXNlcjE4MjQ1MDI=","avatar_url":"https://avatars.githubusercontent.com/u/1824502?u=fcd8a9dba8714edf6ac3f87596eb72149911c720&v=4","gravatar_id":"","url":"https://api.github.com/users/zeripath","html_url":"https://github.com/zeripath","followers_url":"https://api.github.com/users/zeripath/followers","following_url":"https://api.github.com/users/zeripath/following{/other_user}","gists_url":"https://api.github.com/users/zeripath/gists{/gist_id}","starred_url":"https://api.github.com/users/zeripath/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zeripath/subscriptions","organizations_url":"https://api.github.com/users/zeripath/orgs","repos_url":"https://api.github.com/users/zeripath/repos","events_url":"https://api.github.com/users/zeripath/events{/privacy}","received_events_url":"https://api.github.com/users/zeripath/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"APPROVED","html_url":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315860062","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3","author_association":"NONE","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315860062"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3"}},"submitted_at":"2019-11-12T21:35:36Z","commit_id":"076160cf0b039f13e5eff19619932d181269414b"},{"id":315861440,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzE1ODYxNDQw","user":{"login":"lafriks","id":165205,"node_id":"MDQ6VXNlcjE2NTIwNQ==","avatar_url":"https://avatars.githubusercontent.com/u/165205?u=efe2335d2197f524c25caa7abdfcb90b77eb8d98&v=4","gravatar_id":"","url":"https://api.github.com/users/lafriks","html_url":"https://github.com/lafriks","followers_url":"https://api.github.com/users/lafriks/followers","following_url":"https://api.github.com/users/lafriks/following{/other_user}","gists_url":"https://api.github.com/users/lafriks/gists{/gist_id}","starred_url":"https://api.github.com/users/lafriks/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lafriks/subscriptions","organizations_url":"https://api.github.com/users/lafriks/orgs","repos_url":"https://api.github.com/users/lafriks/repos","events_url":"https://api.github.com/users/lafriks/events{/privacy}","received_events_url":"https://api.github.com/users/lafriks/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"APPROVED","html_url":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315861440","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/3#pullrequestreview-315861440"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3"}},"submitted_at":"2019-11-12T21:38:00Z","commit_id":"076160cf0b039f13e5eff19619932d181269414b"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Frequested_reviewers%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Frequested_reviewers%3Fper_page=100
new file mode 100644
index 0000000000..676e326094
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Frequested_reviewers%3Fper_page=100
@@ -0,0 +1,24 @@
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4898
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F623DF:4038CEB:6729E6C0
+Etag: W/"21730161122bd4f229e886dd4a85b45fa575182d6dcef7aa0016a5d21353c9ab"
+X-Accepted-Oauth-Scopes:
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+X-Ratelimit-Used: 102
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+X-Content-Type-Options: nosniff
+
+{"users":[],"teams":[]}
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338338740%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338338740%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..48e5b2c3d9
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338338740%2Fcomments%3Fper_page=100
@@ -0,0 +1,24 @@
+Access-Control-Allow-Origin: *
+X-Content-Type-Options: nosniff
+Content-Security-Policy: default-src 'none'
+X-Ratelimit-Resource: core
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Accepted-Oauth-Scopes:
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Remaining: 4903
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Frame-Options: deny
+X-Github-Request-Id: C7CC:3118FC:3F61BAA:40384A5:6729E6BE
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"ff77892df2ec7f6eb61416e0f384ce0a6e8fbbbc1287f5d09b1980ebe9856750"
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Used: 97
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Type: application/json; charset=utf-8
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+X-Oauth-Scopes:
+
+[{"id":363017488,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDM2MzAxNzQ4OA==","url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363017488","pull_request_review_id":338338740,"diff_hunk":"@@ -1,2 +1,4 @@\n # test_repo\n Test repository for testing migration from github to gitea\n+","path":"README.md","position":3,"original_position":3,"commit_id":"2be9101c543658591222acbee3eb799edfc3853d","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"This is a good pull request.","created_at":"2020-01-04T05:33:06Z","updated_at":"2020-01-04T05:33:18Z","html_url":"https://github.com/go-gitea/test_repo/pull/4#discussion_r363017488","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363017488"},"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#discussion_r363017488"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"original_commit_id":"2be9101c543658591222acbee3eb799edfc3853d","reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363017488/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0}}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338339651%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338339651%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..4cc66424f0
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338339651%2Fcomments%3Fper_page=100
@@ -0,0 +1,25 @@
+X-Github-Api-Version-Selected: 2022-11-28
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: "450a1c087fec81e5b86092ff5372c3db8ca834c1e23c03c6b06ecca33cefd665"
+X-Github-Media-Type: github.v3; format=json
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Ratelimit-Reset: 1730800941
+X-Xss-Protection: 0
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+Access-Control-Allow-Origin: *
+Content-Length: 2
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Ratelimit-Resource: core
+Content-Security-Policy: default-src 'none'
+X-Github-Request-Id: C7CC:3118FC:3F61EBA:40387A6:6729E6BF
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Remaining: 4901
+X-Ratelimit-Used: 99
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338349019%2Fcomments%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338349019%2Fcomments%3Fper_page=100
new file mode 100644
index 0000000000..f13d4addc7
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%2F338349019%2Fcomments%3Fper_page=100
@@ -0,0 +1,24 @@
+Etag: W/"f74a383d4c87ae26d218fc087bef2c41a12637dff81fd8642f59708adca1a14e"
+X-Ratelimit-Remaining: 4900
+X-Content-Type-Options: nosniff
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Reset: 1730800941
+X-Xss-Protection: 0
+Content-Type: application/json; charset=utf-8
+X-Oauth-Scopes:
+X-Accepted-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+Access-Control-Allow-Origin: *
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Frame-Options: deny
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Used: 100
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Github-Request-Id: C7CC:3118FC:3F62065:4038955:6729E6C0
+Content-Security-Policy: default-src 'none'
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+
+[{"id":363029944,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDM2MzAyOTk0NA==","url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363029944","pull_request_review_id":338349019,"diff_hunk":"@@ -19,3 +19,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n SOFTWARE.\n+","path":"LICENSE","position":4,"original_position":4,"commit_id":"2be9101c543658591222acbee3eb799edfc3853d","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"test a single comment.","created_at":"2020-01-04T11:21:41Z","updated_at":"2020-01-04T11:21:41Z","html_url":"https://github.com/go-gitea/test_repo/pull/4#discussion_r363029944","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363029944"},"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#discussion_r363029944"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"original_commit_id":"2be9101c543658591222acbee3eb799edfc3853d","reactions":{"url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments/363029944/reactions","total_count":0,"+1":0,"-1":0,"laugh":0,"hooray":0,"confused":0,"heart":0,"rocket":0,"eyes":0}}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%3Fper_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%3Fper_page=100
new file mode 100644
index 0000000000..c4484e078a
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2F4%2Freviews%3Fper_page=100
@@ -0,0 +1,24 @@
+Cache-Control: private, max-age=60, s-maxage=60
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Xss-Protection: 0
+Content-Security-Policy: default-src 'none'
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; format=json
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Reset: 1730800941
+X-Frame-Options: deny
+X-Github-Request-Id: C7CC:3118FC:3F619C6:40382C4:6729E6BE
+Access-Control-Allow-Origin: *
+X-Content-Type-Options: nosniff
+Content-Type: application/json; charset=utf-8
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Used: 96
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Etag: W/"a47623061be83c50d3932baf8c5961386d2d45c32c42b504122c9a1359efd515"
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Remaining: 4904
+
+[{"id":338338740,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzM4MzM4NzQw","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"APPROVED","html_url":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338338740","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338338740"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"submitted_at":"2020-01-04T05:33:18Z","commit_id":"2be9101c543658591222acbee3eb799edfc3853d"},{"id":338339651,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzM4MzM5NjUx","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"Don't add more reviews","state":"CHANGES_REQUESTED","html_url":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338339651","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338339651"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"submitted_at":"2020-01-04T06:07:06Z","commit_id":"2be9101c543658591222acbee3eb799edfc3853d"},{"id":338349019,"node_id":"MDE3OlB1bGxSZXF1ZXN0UmV2aWV3MzM4MzQ5MDE5","user":{"login":"lunny","id":81045,"node_id":"MDQ6VXNlcjgxMDQ1","avatar_url":"https://avatars.githubusercontent.com/u/81045?u=99b64f0ca6ef63643c7583ab87dd31c52d28e673&v=4","gravatar_id":"","url":"https://api.github.com/users/lunny","html_url":"https://github.com/lunny","followers_url":"https://api.github.com/users/lunny/followers","following_url":"https://api.github.com/users/lunny/following{/other_user}","gists_url":"https://api.github.com/users/lunny/gists{/gist_id}","starred_url":"https://api.github.com/users/lunny/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lunny/subscriptions","organizations_url":"https://api.github.com/users/lunny/orgs","repos_url":"https://api.github.com/users/lunny/repos","events_url":"https://api.github.com/users/lunny/events{/privacy}","received_events_url":"https://api.github.com/users/lunny/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"","state":"COMMENTED","html_url":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338349019","pull_request_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","author_association":"MEMBER","_links":{"html":{"href":"https://github.com/go-gitea/test_repo/pull/4#pullrequestreview-338349019"},"pull_request":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"}},"submitted_at":"2020-01-04T11:21:41Z","commit_id":"2be9101c543658591222acbee3eb799edfc3853d"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363017488%2Freactions%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363017488%2Freactions%3Fpage=1&per_page=100
new file mode 100644
index 0000000000..748ae93381
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363017488%2Freactions%3Fpage=1&per_page=100
@@ -0,0 +1,25 @@
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Remaining: 4902
+X-Ratelimit-Reset: 1730800941
+X-Ratelimit-Resource: core
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Access-Control-Allow-Origin: *
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+X-Github-Request-Id: C7CC:3118FC:3F61D73:4038667:6729E6BF
+Content-Type: application/json; charset=utf-8
+X-Ratelimit-Limit: 5000
+Content-Length: 2
+Cache-Control: private, max-age=60, s-maxage=60
+X-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Used: 98
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+X-Xss-Protection: 0
+Content-Security-Policy: default-src 'none'
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363029944%2Freactions%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363029944%2Freactions%3Fpage=1&per_page=100
new file mode 100644
index 0000000000..0b0ae88deb
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%2Fcomments%2F363029944%2Freactions%3Fpage=1&per_page=100
@@ -0,0 +1,25 @@
+X-Accepted-Oauth-Scopes:
+X-Ratelimit-Remaining: 4899
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Length: 2
+X-Ratelimit-Used: 101
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+X-Content-Type-Options: nosniff
+X-Xss-Protection: 0
+Content-Security-Policy: default-src 'none'
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: "f87b0fd59e59458a9a808311324b873c6baf3fde861298a99de9986270dd4d79"
+X-Oauth-Scopes:
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Reset: 1730800941
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Content-Type: application/json; charset=utf-8
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Github-Media-Type: github.v3; param=squirrel-girl-preview
+X-Ratelimit-Resource: core
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Github-Request-Id: C7CC:3118FC:3F622AC:4038BA5:6729E6C0
+
+[]
\ No newline at end of file
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%3Fdirection=asc&page=1&per_page=2&sort=created&state=all b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
new file mode 100644
index 0000000000..30883cc283
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Fpulls%3Fdirection=asc&page=1&per_page=2&sort=created&state=all
@@ -0,0 +1,24 @@
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Used: 87
+X-Frame-Options: deny
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Remaining: 4913
+X-Ratelimit-Reset: 1730800941
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Security-Policy: default-src 'none'
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Oauth-Scopes:
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Resource: core
+Access-Control-Allow-Origin: *
+X-Github-Request-Id: C7CC:3118FC:3F6099B:403726B:6729E6BA
+X-Xss-Protection: 0
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+Etag: W/"fed37ab8ce0b78e713030ff3e601f540b7f71243ab788b477f6885119bd691c5"
+X-Accepted-Oauth-Scopes:
+X-Content-Type-Options: nosniff
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3","id":340118745,"node_id":"MDExOlB1bGxSZXF1ZXN0MzQwMTE4NzQ1","html_url":"https://github.com/go-gitea/test_repo/pull/3","diff_url":"https://github.com/go-gitea/test_repo/pull/3.diff","patch_url":"https://github.com/go-gitea/test_repo/pull/3.patch","issue_url":"https://api.github.com/repos/go-gitea/test_repo/issues/3","number":3,"state":"closed","locked":false,"title":"Update README.md","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"add warning to readme","created_at":"2019-11-12T21:21:43Z","updated_at":"2019-11-12T21:39:28Z","closed_at":"2019-11-12T21:39:27Z","merged_at":"2019-11-12T21:39:27Z","merge_commit_sha":"f32b0a9dfd09a60f616f29158f772cedd89942d2","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":1667254254,"node_id":"MDU6TGFiZWwxNjY3MjU0MjU0","url":"https://api.github.com/repos/go-gitea/test_repo/labels/documentation","name":"documentation","color":"0075ca","default":true,"description":"Improvements or additions to documentation"}],"milestone":{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2","html_url":"https://github.com/go-gitea/test_repo/milestone/2","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/2/labels","id":4839942,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0Mg==","number":2,"title":"1.1.0","description":"Milestone 1.1.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":0,"closed_issues":2,"state":"closed","created_at":"2019-11-12T19:37:25Z","updated_at":"2019-11-12T21:39:27Z","due_on":"2019-11-12T08:00:00Z","closed_at":"2019-11-12T19:45:46Z"},"draft":false,"commits_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3/commits","review_comments_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/3/comments","review_comment_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/issues/3/comments","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/076160cf0b039f13e5eff19619932d181269414b","head":{"label":"mrsdizzie:master","ref":"master","sha":"076160cf0b039f13e5eff19619932d181269414b","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"repo":{"id":221313794,"node_id":"MDEwOlJlcG9zaXRvcnkyMjEzMTM3OTQ=","name":"test_repo","full_name":"mrsdizzie/test_repo","private":false,"owner":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"html_url":"https://github.com/mrsdizzie/test_repo","description":"Test repository for testing migration from github to gitea","fork":true,"url":"https://api.github.com/repos/mrsdizzie/test_repo","forks_url":"https://api.github.com/repos/mrsdizzie/test_repo/forks","keys_url":"https://api.github.com/repos/mrsdizzie/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mrsdizzie/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mrsdizzie/test_repo/teams","hooks_url":"https://api.github.com/repos/mrsdizzie/test_repo/hooks","issue_events_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/mrsdizzie/test_repo/events","assignees_url":"https://api.github.com/repos/mrsdizzie/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/mrsdizzie/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/mrsdizzie/test_repo/tags","blobs_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mrsdizzie/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/mrsdizzie/test_repo/languages","stargazers_url":"https://api.github.com/repos/mrsdizzie/test_repo/stargazers","contributors_url":"https://api.github.com/repos/mrsdizzie/test_repo/contributors","subscribers_url":"https://api.github.com/repos/mrsdizzie/test_repo/subscribers","subscription_url":"https://api.github.com/repos/mrsdizzie/test_repo/subscription","commits_url":"https://api.github.com/repos/mrsdizzie/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/mrsdizzie/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/mrsdizzie/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/mrsdizzie/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mrsdizzie/test_repo/merges","archive_url":"https://api.github.com/repos/mrsdizzie/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mrsdizzie/test_repo/downloads","issues_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/mrsdizzie/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/mrsdizzie/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/mrsdizzie/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mrsdizzie/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/mrsdizzie/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/mrsdizzie/test_repo/deployments","created_at":"2019-11-12T21:17:42Z","updated_at":"2019-11-12T21:18:46Z","pushed_at":"2019-11-12T21:53:39Z","git_url":"git://github.com/mrsdizzie/test_repo.git","ssh_url":"git@github.com:mrsdizzie/test_repo.git","clone_url":"https://github.com/mrsdizzie/test_repo.git","svn_url":"https://github.com/mrsdizzie/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":3,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":[],"visibility":"public","forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"go-gitea:master","ref":"master","sha":"72866af952e98d02a73003501836074b286a78f6","user":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"repo":{"id":220672974,"node_id":"MDEwOlJlcG9zaXRvcnkyMjA2NzI5NzQ=","name":"test_repo","full_name":"go-gitea/test_repo","private":false,"owner":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/go-gitea/test_repo","description":"Test repository for testing migration from github to gitea","fork":false,"url":"https://api.github.com/repos/go-gitea/test_repo","forks_url":"https://api.github.com/repos/go-gitea/test_repo/forks","keys_url":"https://api.github.com/repos/go-gitea/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/go-gitea/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/go-gitea/test_repo/teams","hooks_url":"https://api.github.com/repos/go-gitea/test_repo/hooks","issue_events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/go-gitea/test_repo/events","assignees_url":"https://api.github.com/repos/go-gitea/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/go-gitea/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/go-gitea/test_repo/tags","blobs_url":"https://api.github.com/repos/go-gitea/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/go-gitea/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/go-gitea/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/go-gitea/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/go-gitea/test_repo/languages","stargazers_url":"https://api.github.com/repos/go-gitea/test_repo/stargazers","contributors_url":"https://api.github.com/repos/go-gitea/test_repo/contributors","subscribers_url":"https://api.github.com/repos/go-gitea/test_repo/subscribers","subscription_url":"https://api.github.com/repos/go-gitea/test_repo/subscription","commits_url":"https://api.github.com/repos/go-gitea/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/go-gitea/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/go-gitea/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/go-gitea/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/go-gitea/test_repo/merges","archive_url":"https://api.github.com/repos/go-gitea/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/go-gitea/test_repo/downloads","issues_url":"https://api.github.com/repos/go-gitea/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/go-gitea/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/go-gitea/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/go-gitea/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/go-gitea/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/go-gitea/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/go-gitea/test_repo/deployments","created_at":"2019-11-09T16:49:20Z","updated_at":"2023-03-02T14:02:26Z","pushed_at":"2019-11-12T21:54:19Z","git_url":"git://github.com/go-gitea/test_repo.git","ssh_url":"git@github.com:go-gitea/test_repo.git","clone_url":"https://github.com/go-gitea/test_repo.git","svn_url":"https://github.com/go-gitea/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":1,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":6,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":2,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["gitea"],"visibility":"public","forks":6,"open_issues":2,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3"},"html":{"href":"https://github.com/go-gitea/test_repo/pull/3"},"issue":{"href":"https://api.github.com/repos/go-gitea/test_repo/issues/3"},"comments":{"href":"https://api.github.com/repos/go-gitea/test_repo/issues/3/comments"},"review_comments":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3/comments"},"review_comment":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/3/commits"},"statuses":{"href":"https://api.github.com/repos/go-gitea/test_repo/statuses/076160cf0b039f13e5eff19619932d181269414b"}},"author_association":"MEMBER","auto_merge":null,"active_lock_reason":null},{"url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4","id":340131577,"node_id":"MDExOlB1bGxSZXF1ZXN0MzQwMTMxNTc3","html_url":"https://github.com/go-gitea/test_repo/pull/4","diff_url":"https://github.com/go-gitea/test_repo/pull/4.diff","patch_url":"https://github.com/go-gitea/test_repo/pull/4.patch","issue_url":"https://api.github.com/repos/go-gitea/test_repo/issues/4","number":4,"state":"open","locked":false,"title":"Test branch","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"body":"do not merge this PR","created_at":"2019-11-12T21:54:18Z","updated_at":"2020-01-04T11:30:01Z","closed_at":null,"merged_at":null,"merge_commit_sha":"565d1208f5fffdc1c5ae1a2436491eb9a5e4ebae","assignee":null,"assignees":[],"requested_reviewers":[],"requested_teams":[],"labels":[{"id":1667254252,"node_id":"MDU6TGFiZWwxNjY3MjU0MjUy","url":"https://api.github.com/repos/go-gitea/test_repo/labels/bug","name":"bug","color":"d73a4a","default":true,"description":"Something isn't working"}],"milestone":{"url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1","html_url":"https://github.com/go-gitea/test_repo/milestone/1","labels_url":"https://api.github.com/repos/go-gitea/test_repo/milestones/1/labels","id":4839941,"node_id":"MDk6TWlsZXN0b25lNDgzOTk0MQ==","number":1,"title":"1.0.0","description":"Milestone 1.0.0","creator":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"open_issues":1,"closed_issues":1,"state":"closed","created_at":"2019-11-12T19:37:08Z","updated_at":"2019-11-12T21:56:17Z","due_on":"2019-11-11T08:00:00Z","closed_at":"2019-11-12T19:45:49Z"},"draft":false,"commits_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4/commits","review_comments_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/4/comments","review_comment_url":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments{/number}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/issues/4/comments","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/2be9101c543658591222acbee3eb799edfc3853d","head":{"label":"mrsdizzie:test-branch","ref":"test-branch","sha":"2be9101c543658591222acbee3eb799edfc3853d","user":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"repo":{"id":221313794,"node_id":"MDEwOlJlcG9zaXRvcnkyMjEzMTM3OTQ=","name":"test_repo","full_name":"mrsdizzie/test_repo","private":false,"owner":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"html_url":"https://github.com/mrsdizzie/test_repo","description":"Test repository for testing migration from github to gitea","fork":true,"url":"https://api.github.com/repos/mrsdizzie/test_repo","forks_url":"https://api.github.com/repos/mrsdizzie/test_repo/forks","keys_url":"https://api.github.com/repos/mrsdizzie/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mrsdizzie/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mrsdizzie/test_repo/teams","hooks_url":"https://api.github.com/repos/mrsdizzie/test_repo/hooks","issue_events_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/mrsdizzie/test_repo/events","assignees_url":"https://api.github.com/repos/mrsdizzie/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/mrsdizzie/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/mrsdizzie/test_repo/tags","blobs_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mrsdizzie/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/mrsdizzie/test_repo/languages","stargazers_url":"https://api.github.com/repos/mrsdizzie/test_repo/stargazers","contributors_url":"https://api.github.com/repos/mrsdizzie/test_repo/contributors","subscribers_url":"https://api.github.com/repos/mrsdizzie/test_repo/subscribers","subscription_url":"https://api.github.com/repos/mrsdizzie/test_repo/subscription","commits_url":"https://api.github.com/repos/mrsdizzie/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/mrsdizzie/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/mrsdizzie/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/mrsdizzie/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/mrsdizzie/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mrsdizzie/test_repo/merges","archive_url":"https://api.github.com/repos/mrsdizzie/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mrsdizzie/test_repo/downloads","issues_url":"https://api.github.com/repos/mrsdizzie/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/mrsdizzie/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/mrsdizzie/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/mrsdizzie/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mrsdizzie/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/mrsdizzie/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/mrsdizzie/test_repo/deployments","created_at":"2019-11-12T21:17:42Z","updated_at":"2019-11-12T21:18:46Z","pushed_at":"2019-11-12T21:53:39Z","git_url":"git://github.com/mrsdizzie/test_repo.git","ssh_url":"git@github.com:mrsdizzie/test_repo.git","clone_url":"https://github.com/mrsdizzie/test_repo.git","svn_url":"https://github.com/mrsdizzie/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":3,"stargazers_count":0,"watchers_count":0,"language":null,"has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":0,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":0,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":[],"visibility":"public","forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"go-gitea:master","ref":"master","sha":"f32b0a9dfd09a60f616f29158f772cedd89942d2","user":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"repo":{"id":220672974,"node_id":"MDEwOlJlcG9zaXRvcnkyMjA2NzI5NzQ=","name":"test_repo","full_name":"go-gitea/test_repo","private":false,"owner":{"login":"go-gitea","id":12724356,"node_id":"MDEyOk9yZ2FuaXphdGlvbjEyNzI0MzU2","avatar_url":"https://avatars.githubusercontent.com/u/12724356?v=4","gravatar_id":"","url":"https://api.github.com/users/go-gitea","html_url":"https://github.com/go-gitea","followers_url":"https://api.github.com/users/go-gitea/followers","following_url":"https://api.github.com/users/go-gitea/following{/other_user}","gists_url":"https://api.github.com/users/go-gitea/gists{/gist_id}","starred_url":"https://api.github.com/users/go-gitea/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-gitea/subscriptions","organizations_url":"https://api.github.com/users/go-gitea/orgs","repos_url":"https://api.github.com/users/go-gitea/repos","events_url":"https://api.github.com/users/go-gitea/events{/privacy}","received_events_url":"https://api.github.com/users/go-gitea/received_events","type":"Organization","user_view_type":"public","site_admin":false},"html_url":"https://github.com/go-gitea/test_repo","description":"Test repository for testing migration from github to gitea","fork":false,"url":"https://api.github.com/repos/go-gitea/test_repo","forks_url":"https://api.github.com/repos/go-gitea/test_repo/forks","keys_url":"https://api.github.com/repos/go-gitea/test_repo/keys{/key_id}","collaborators_url":"https://api.github.com/repos/go-gitea/test_repo/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/go-gitea/test_repo/teams","hooks_url":"https://api.github.com/repos/go-gitea/test_repo/hooks","issue_events_url":"https://api.github.com/repos/go-gitea/test_repo/issues/events{/number}","events_url":"https://api.github.com/repos/go-gitea/test_repo/events","assignees_url":"https://api.github.com/repos/go-gitea/test_repo/assignees{/user}","branches_url":"https://api.github.com/repos/go-gitea/test_repo/branches{/branch}","tags_url":"https://api.github.com/repos/go-gitea/test_repo/tags","blobs_url":"https://api.github.com/repos/go-gitea/test_repo/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/go-gitea/test_repo/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/go-gitea/test_repo/git/refs{/sha}","trees_url":"https://api.github.com/repos/go-gitea/test_repo/git/trees{/sha}","statuses_url":"https://api.github.com/repos/go-gitea/test_repo/statuses/{sha}","languages_url":"https://api.github.com/repos/go-gitea/test_repo/languages","stargazers_url":"https://api.github.com/repos/go-gitea/test_repo/stargazers","contributors_url":"https://api.github.com/repos/go-gitea/test_repo/contributors","subscribers_url":"https://api.github.com/repos/go-gitea/test_repo/subscribers","subscription_url":"https://api.github.com/repos/go-gitea/test_repo/subscription","commits_url":"https://api.github.com/repos/go-gitea/test_repo/commits{/sha}","git_commits_url":"https://api.github.com/repos/go-gitea/test_repo/git/commits{/sha}","comments_url":"https://api.github.com/repos/go-gitea/test_repo/comments{/number}","issue_comment_url":"https://api.github.com/repos/go-gitea/test_repo/issues/comments{/number}","contents_url":"https://api.github.com/repos/go-gitea/test_repo/contents/{+path}","compare_url":"https://api.github.com/repos/go-gitea/test_repo/compare/{base}...{head}","merges_url":"https://api.github.com/repos/go-gitea/test_repo/merges","archive_url":"https://api.github.com/repos/go-gitea/test_repo/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/go-gitea/test_repo/downloads","issues_url":"https://api.github.com/repos/go-gitea/test_repo/issues{/number}","pulls_url":"https://api.github.com/repos/go-gitea/test_repo/pulls{/number}","milestones_url":"https://api.github.com/repos/go-gitea/test_repo/milestones{/number}","notifications_url":"https://api.github.com/repos/go-gitea/test_repo/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/go-gitea/test_repo/labels{/name}","releases_url":"https://api.github.com/repos/go-gitea/test_repo/releases{/id}","deployments_url":"https://api.github.com/repos/go-gitea/test_repo/deployments","created_at":"2019-11-09T16:49:20Z","updated_at":"2023-03-02T14:02:26Z","pushed_at":"2019-11-12T21:54:19Z","git_url":"git://github.com/go-gitea/test_repo.git","ssh_url":"git@github.com:go-gitea/test_repo.git","clone_url":"https://github.com/go-gitea/test_repo.git","svn_url":"https://github.com/go-gitea/test_repo","homepage":"https://codeberg.org/forgejo/forgejo/","size":1,"stargazers_count":3,"watchers_count":3,"language":null,"has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"has_discussions":false,"forks_count":6,"mirror_url":null,"archived":false,"disabled":false,"open_issues_count":2,"license":{"key":"mit","name":"MIT License","spdx_id":"MIT","url":"https://api.github.com/licenses/mit","node_id":"MDc6TGljZW5zZTEz"},"allow_forking":true,"is_template":false,"web_commit_signoff_required":false,"topics":["gitea"],"visibility":"public","forks":6,"open_issues":2,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4"},"html":{"href":"https://github.com/go-gitea/test_repo/pull/4"},"issue":{"href":"https://api.github.com/repos/go-gitea/test_repo/issues/4"},"comments":{"href":"https://api.github.com/repos/go-gitea/test_repo/issues/4/comments"},"review_comments":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4/comments"},"review_comment":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/go-gitea/test_repo/pulls/4/commits"},"statuses":{"href":"https://api.github.com/repos/go-gitea/test_repo/statuses/2be9101c543658591222acbee3eb799edfc3853d"}},"author_association":"MEMBER","auto_merge":null,"active_lock_reason":null}]
diff --git a/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Freleases%3Fpage=1&per_page=100 b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Freleases%3Fpage=1&per_page=100
new file mode 100644
index 0000000000..470f5c5769
--- /dev/null
+++ b/services/migrations/testdata/github/full_download/GET_%2Frepos%2Fgo-gitea%2Ftest_repo%2Freleases%3Fpage=1&per_page=100
@@ -0,0 +1,24 @@
+Access-Control-Allow-Origin: *
+X-Frame-Options: deny
+Etag: W/"2986c85fcc06cc478457abb86a88ac7f065b6861e873ae0eeb9ac16a22efca45"
+X-Github-Api-Version-Selected: 2022-11-28
+X-Ratelimit-Used: 75
+X-Ratelimit-Resource: core
+Content-Type: application/json; charset=utf-8
+Cache-Control: private, max-age=60, s-maxage=60
+Vary: Accept, Authorization, Cookie, X-GitHub-OTP,Accept-Encoding, Accept, X-Requested-With
+X-Accepted-Oauth-Scopes: repo
+X-Ratelimit-Limit: 5000
+X-Ratelimit-Reset: 1730800941
+Strict-Transport-Security: max-age=31536000; includeSubdomains; preload
+X-Xss-Protection: 0
+Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin
+Content-Security-Policy: default-src 'none'
+X-Oauth-Scopes:
+X-Github-Media-Type: github.v3; format=json
+X-Ratelimit-Remaining: 4925
+Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Used, X-RateLimit-Resource, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type, X-GitHub-SSO, X-GitHub-Request-Id, Deprecation, Sunset
+X-Content-Type-Options: nosniff
+X-Github-Request-Id: C7CC:3118FC:3F5F41A:4035CB2:6729E6B4
+
+[{"url":"https://api.github.com/repos/go-gitea/test_repo/releases/21419432","assets_url":"https://api.github.com/repos/go-gitea/test_repo/releases/21419432/assets","upload_url":"https://uploads.github.com/repos/go-gitea/test_repo/releases/21419432/assets{?name,label}","html_url":"https://github.com/go-gitea/test_repo/releases/tag/v0.9.99","id":21419432,"author":{"login":"mrsdizzie","id":1669571,"node_id":"MDQ6VXNlcjE2Njk1NzE=","avatar_url":"https://avatars.githubusercontent.com/u/1669571?v=4","gravatar_id":"","url":"https://api.github.com/users/mrsdizzie","html_url":"https://github.com/mrsdizzie","followers_url":"https://api.github.com/users/mrsdizzie/followers","following_url":"https://api.github.com/users/mrsdizzie/following{/other_user}","gists_url":"https://api.github.com/users/mrsdizzie/gists{/gist_id}","starred_url":"https://api.github.com/users/mrsdizzie/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mrsdizzie/subscriptions","organizations_url":"https://api.github.com/users/mrsdizzie/orgs","repos_url":"https://api.github.com/users/mrsdizzie/repos","events_url":"https://api.github.com/users/mrsdizzie/events{/privacy}","received_events_url":"https://api.github.com/users/mrsdizzie/received_events","type":"User","user_view_type":"public","site_admin":false},"node_id":"MDc6UmVsZWFzZTIxNDE5NDMy","tag_name":"v0.9.99","target_commitish":"master","name":"First Release","draft":false,"prerelease":false,"created_at":"2019-11-09T16:49:21Z","published_at":"2019-11-12T20:12:10Z","assets":[],"tarball_url":"https://api.github.com/repos/go-gitea/test_repo/tarball/v0.9.99","zipball_url":"https://api.github.com/repos/go-gitea/test_repo/zipball/v0.9.99","body":"A test release"}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026
deleted file mode 100644
index 81fb1f9e01..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026
+++ /dev/null
@@ -1,17 +0,0 @@
-Gitlab-Sv: api-gke-us-east1-c
-Content-Type: application/json
-Cache-Control: max-age=0, private, must-revalidate
-Content-Security-Policy: default-src 'none'
-Etag: W/"8db4917b3be5f4ca0d101a702179b75a"
-X-Content-Type-Options: nosniff
-X-Runtime: 0.150020
-Referrer-Policy: strict-origin-when-cross-origin
-Set-Cookie: _cfuvid=2JDVzeRhKxkwd0xbLccErO2vFlf0KnUzsvPv1ZY4.H4-1710504205506-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Gitlab-Meta: {"correlation_id":"fc467ca540c06233f6a25d0deae604d2","version":"1"}
-Vary: Origin, Accept-Encoding
-X-Frame-Options: SAMEORIGIN
-Strict-Transport-Security: max-age=31536000
-Gitlab-Lb: haproxy-main-01-lb-gprd
-Cf-Cache-Status: MISS
-
-{"id":15578026,"description":"Test repository for testing migration from gitlab to gitea","name":"test_repo","name_with_namespace":"gitea / test_repo","path":"test_repo","path_with_namespace":"gitea/test_repo","created_at":"2019-11-28T08:20:33.019Z","default_branch":"master","tag_list":["migration","test"],"topics":["migration","test"],"ssh_url_to_repo":"git@gitlab.com:gitea/test_repo.git","http_url_to_repo":"https://gitlab.com/gitea/test_repo.git","web_url":"https://gitlab.com/gitea/test_repo","readme_url":"https://gitlab.com/gitea/test_repo/-/blob/master/README.md","forks_count":1,"avatar_url":null,"star_count":0,"last_activity_at":"2020-04-19T19:46:04.527Z","namespace":{"id":3181312,"name":"gitea","path":"gitea","kind":"group","full_path":"gitea","parent_id":null,"avatar_url":"/uploads/-/system/group/avatar/3181312/gitea.png","web_url":"https://gitlab.com/groups/gitea"},"container_registry_image_prefix":"registry.gitlab.com/gitea/test_repo","_links":{"self":"https://gitlab.com/api/v4/projects/15578026","issues":"https://gitlab.com/api/v4/projects/15578026/issues","merge_requests":"https://gitlab.com/api/v4/projects/15578026/merge_requests","repo_branches":"https://gitlab.com/api/v4/projects/15578026/repository/branches","labels":"https://gitlab.com/api/v4/projects/15578026/labels","events":"https://gitlab.com/api/v4/projects/15578026/events","members":"https://gitlab.com/api/v4/projects/15578026/members","cluster_agents":"https://gitlab.com/api/v4/projects/15578026/cluster_agents"},"packages_enabled":true,"empty_repo":false,"archived":false,"visibility":"public","resolve_outdated_diff_discussions":false,"repository_object_format":"sha1","issues_enabled":true,"merge_requests_enabled":true,"wiki_enabled":true,"jobs_enabled":true,"snippets_enabled":true,"container_registry_enabled":true,"service_desk_enabled":true,"can_create_merge_request_in":true,"issues_access_level":"enabled","repository_access_level":"enabled","merge_requests_access_level":"enabled","forking_access_level":"enabled","wiki_access_level":"enabled","builds_access_level":"enabled","snippets_access_level":"enabled","pages_access_level":"enabled","analytics_access_level":"enabled","container_registry_access_level":"enabled","security_and_compliance_access_level":"private","releases_access_level":"enabled","environments_access_level":"enabled","feature_flags_access_level":"enabled","infrastructure_access_level":"enabled","monitor_access_level":"enabled","model_experiments_access_level":"enabled","model_registry_access_level":"enabled","emails_disabled":false,"emails_enabled":true,"shared_runners_enabled":true,"lfs_enabled":true,"creator_id":1241334,"import_status":"none","open_issues_count":0,"description_html":"\u003cp data-sourcepos=\"1:1-1:58\" dir=\"auto\"\u003eTest repository for testing migration from gitlab to gitea\u003c/p\u003e","updated_at":"2024-01-11T01:23:21.057Z","ci_config_path":null,"public_jobs":true,"shared_with_groups":[],"only_allow_merge_if_pipeline_succeeds":false,"allow_merge_on_skipped_pipeline":null,"request_access_enabled":true,"only_allow_merge_if_all_discussions_are_resolved":false,"remove_source_branch_after_merge":true,"printing_merge_request_link_enabled":true,"merge_method":"ff","squash_option":"default_off","enforce_auth_checks_on_uploads":true,"suggestion_commit_message":null,"merge_commit_template":null,"squash_commit_template":null,"issue_branch_template":null,"warn_about_potentially_unwanted_characters":true,"autoclose_referenced_issues":true,"external_authorization_classification_label":"","requirements_enabled":false,"requirements_access_level":"enabled","security_and_compliance_enabled":false,"compliance_frameworks":[],"permissions":{"project_access":null,"group_access":null}}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=1&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=1&per_page=2
deleted file mode 100644
index cbdfdde527..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=1&per_page=2
+++ /dev/null
@@ -1,24 +0,0 @@
-Vary: Origin, Accept-Encoding
-Gitlab-Sv: api-gke-us-east1-b
-X-Runtime: 0.203565
-Referrer-Policy: strict-origin-when-cross-origin
-X-Frame-Options: SAMEORIGIN
-X-Next-Page:
-X-Gitlab-Meta: {"correlation_id":"9ee8f715be2950b629eff875667dab37","version":"1"}
-X-Total-Pages: 1
-Gitlab-Lb: haproxy-main-57-lb-gprd
-Cf-Cache-Status: MISS
-Content-Type: application/json
-Cache-Control: max-age=0, private, must-revalidate
-X-Content-Type-Options: nosniff
-Strict-Transport-Security: max-age=31536000
-Etag: W/"69c922434ed11248c864d157eb8eabfc"
-X-Per-Page: 2
-X-Prev-Page:
-Set-Cookie: _cfuvid=lj07r.PfLt5YP9_Ms5dtsY_JOkTSmeFWB1sd2Z8SLuM-1710504207278-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Content-Security-Policy: default-src 'none'
-Link: ; rel="first", ; rel="last"
-X-Page: 1
-X-Total: 2
-
-[{"id":3009580,"name":"thumbsup","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:43:40.322Z","updated_at":"2019-11-28T08:43:40.322Z","awardable_id":27687675,"awardable_type":"Issue","url":null},{"id":3009585,"name":"open_mouth","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:44:01.902Z","updated_at":"2019-11-28T08:44:01.902Z","awardable_id":27687675,"awardable_type":"Issue","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=2&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=2&per_page=2
deleted file mode 100644
index 262bf891ee..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F1%2Faward_emoji%3Fpage=2&per_page=2
+++ /dev/null
@@ -1,26 +0,0 @@
-Link: ; rel="first", ; rel="last"
-X-Content-Type-Options: nosniff
-X-Page: 2
-X-Per-Page: 2
-Gitlab-Sv: api-gke-us-east1-b
-Content-Type: application/json
-Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
-X-Frame-Options: SAMEORIGIN
-X-Gitlab-Meta: {"correlation_id":"05db2c172a3be5ea9e65494882e77167","version":"1"}
-X-Next-Page:
-Set-Cookie: _cfuvid=UDvTcjnLBRvcY_axm9MwnCJ0PmPtOKE9vnIQ4uoOUGE-1710504207498-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Runtime: 0.061429
-X-Total-Pages: 1
-Strict-Transport-Security: max-age=31536000
-Gitlab-Lb: haproxy-main-51-lb-gprd
-Accept-Ranges: bytes
-Content-Length: 2
-Cf-Cache-Status: MISS
-Cache-Control: max-age=0, private, must-revalidate
-Content-Security-Policy: default-src 'none'
-Vary: Origin, Accept-Encoding
-X-Prev-Page:
-X-Total: 2
-Referrer-Policy: strict-origin-when-cross-origin
-
-[]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=1&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=1&per_page=2
deleted file mode 100644
index 52822db98b..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=1&per_page=2
+++ /dev/null
@@ -1,24 +0,0 @@
-X-Frame-Options: SAMEORIGIN
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Lb: haproxy-main-40-lb-gprd
-Content-Type: application/json
-Strict-Transport-Security: max-age=31536000
-Vary: Origin, Accept-Encoding
-X-Page: 1
-X-Runtime: 0.078016
-Link: ; rel="next", ; rel="first", ; rel="last"
-X-Prev-Page:
-X-Total: 6
-X-Total-Pages: 3
-X-Content-Type-Options: nosniff
-X-Next-Page: 2
-Gitlab-Sv: api-gke-us-east1-c
-Cache-Control: max-age=0, private, must-revalidate
-Cf-Cache-Status: MISS
-Set-Cookie: _cfuvid=YByIjysnuUyVymulLPR72WWURJsjsdM2aiUwKWAGtZI-1710504207733-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Content-Security-Policy: default-src 'none'
-Etag: W/"5fdbcbf64f34ba0e74ce9dd8d6e0efe3"
-X-Gitlab-Meta: {"correlation_id":"2c82a2ec8ad8bdd3c0d2adb0e208f69a","version":"1"}
-X-Per-Page: 2
-
-[{"id":3009627,"name":"thumbsup","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:46:42.657Z","updated_at":"2019-11-28T08:46:42.657Z","awardable_id":27687706,"awardable_type":"Issue","url":null},{"id":3009628,"name":"thumbsdown","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:46:43.471Z","updated_at":"2019-11-28T08:46:43.471Z","awardable_id":27687706,"awardable_type":"Issue","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=2&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=2&per_page=2
deleted file mode 100644
index 2ebb34db88..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=2&per_page=2
+++ /dev/null
@@ -1,24 +0,0 @@
-X-Gitlab-Meta: {"correlation_id":"3f684de509b846cafc057f0e2982ad76","version":"1"}
-X-Prev-Page: 1
-X-Total-Pages: 3
-Gitlab-Lb: haproxy-main-24-lb-gprd
-Gitlab-Sv: api-gke-us-east1-b
-Vary: Origin, Accept-Encoding
-Set-Cookie: _cfuvid=Bs.X45qZvylPDZxkoXQ0YQS72rXFkViMP2IaqBS6C0s-1710504207991-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Etag: W/"d16c513b32212d9286fce6f53340c1cf"
-X-Content-Type-Options: nosniff
-Cache-Control: max-age=0, private, must-revalidate
-X-Next-Page: 3
-Strict-Transport-Security: max-age=31536000
-Referrer-Policy: strict-origin-when-cross-origin
-Content-Type: application/json
-Content-Security-Policy: default-src 'none'
-X-Frame-Options: SAMEORIGIN
-X-Runtime: 0.098833
-Cf-Cache-Status: MISS
-Link: ; rel="prev", ; rel="next", ; rel="first", ; rel="last"
-X-Page: 2
-X-Per-Page: 2
-X-Total: 6
-
-[{"id":3009632,"name":"laughing","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:14.381Z","updated_at":"2019-11-28T08:47:14.381Z","awardable_id":27687706,"awardable_type":"Issue","url":null},{"id":3009634,"name":"tada","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:18.254Z","updated_at":"2019-11-28T08:47:18.254Z","awardable_id":27687706,"awardable_type":"Issue","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=3&per_page=2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=3&per_page=2
deleted file mode 100644
index 23da417c01..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Faward_emoji%3Fpage=3&per_page=2
+++ /dev/null
@@ -1,24 +0,0 @@
-X-Total-Pages: 3
-Content-Security-Policy: default-src 'none'
-Vary: Origin, Accept-Encoding
-X-Page: 3
-Strict-Transport-Security: max-age=31536000
-Etag: W/"165d37bf09a54bb31f4619cca8722cb4"
-X-Next-Page:
-X-Frame-Options: SAMEORIGIN
-X-Prev-Page: 2
-Cf-Cache-Status: MISS
-Set-Cookie: _cfuvid=HHUVNinfPq8fL7PXFgbDm8yTm6pwWCXctd6JjWwfzY4-1710504208221-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Runtime: 0.071448
-X-Total: 6
-Cache-Control: max-age=0, private, must-revalidate
-X-Gitlab-Meta: {"correlation_id":"886dbf65fe0de14ba39622416ae0ca1b","version":"1"}
-Referrer-Policy: strict-origin-when-cross-origin
-Link: ; rel="prev", ; rel="first", ; rel="last"
-X-Content-Type-Options: nosniff
-Content-Type: application/json
-Gitlab-Lb: haproxy-main-50-lb-gprd
-Gitlab-Sv: api-gke-us-east1-d
-X-Per-Page: 2
-
-[{"id":3009636,"name":"confused","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:27.248Z","updated_at":"2019-11-28T08:47:27.248Z","awardable_id":27687706,"awardable_type":"Issue","url":null},{"id":3009640,"name":"hearts","user":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:47:33.059Z","updated_at":"2019-11-28T08:47:33.059Z","awardable_id":27687706,"awardable_type":"Issue","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fdiscussions%3Fpage=1&per_page=100 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fdiscussions%3Fpage=1&per_page=100
deleted file mode 100644
index 6b62a85016..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fdiscussions%3Fpage=1&per_page=100
+++ /dev/null
@@ -1,24 +0,0 @@
-Strict-Transport-Security: max-age=31536000
-Gitlab-Lb: haproxy-main-32-lb-gprd
-Content-Type: application/json
-Link: ; rel="first", ; rel="last"
-Set-Cookie: _cfuvid=CZZEZqJQZ97MpqkqjenLKOUdtc5tMbwPjVBKat9VrFo-1710504208832-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Cache-Control: max-age=0, private, must-revalidate
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Sv: gke-cny-api
-X-Total-Pages: 1
-X-Page: 1
-X-Per-Page: 100
-X-Total: 4
-X-Content-Type-Options: nosniff
-X-Runtime: 0.215193
-X-Frame-Options: SAMEORIGIN
-Vary: Origin, Accept-Encoding
-X-Gitlab-Meta: {"correlation_id":"d84b389e2f5604d766104c7236dbfdf8","version":"1"}
-X-Next-Page:
-Content-Security-Policy: default-src 'none'
-Etag: W/"bcc91e8a7b2eac98b4d96ae791e0649d"
-X-Prev-Page:
-Cf-Cache-Status: MISS
-
-[{"id":"617967369d98d8b73b6105a40318fe839f931a24","individual_note":true,"notes":[{"id":251637434,"type":null,"body":"This is a comment","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:44:52.501Z","updated_at":"2019-11-28T08:44:52.501Z","system":false,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]},{"id":"b92d74daee411a17d844041bcd3c267ade58f680","individual_note":true,"notes":[{"id":251637528,"type":null,"body":"changed milestone to %2","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:45:02.329Z","updated_at":"2019-11-28T08:45:02.335Z","system":true,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]},{"id":"6010f567d2b58758ef618070372c97891ac75349","individual_note":true,"notes":[{"id":251637892,"type":null,"body":"closed","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:45:45.007Z","updated_at":"2019-11-28T08:45:45.010Z","system":true,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]},{"id":"632d0cbfd6a1a08f38aaf9ef7715116f4b188ebb","individual_note":true,"notes":[{"id":251637999,"type":null,"body":"A second comment","attachment":null,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"created_at":"2019-11-28T08:45:53.501Z","updated_at":"2019-11-28T08:45:53.501Z","system":false,"noteable_id":27687706,"noteable_type":"Issue","project_id":15578026,"resolvable":false,"confidential":false,"internal":false,"noteable_iid":2,"commands_changes":{}}]}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fresource_state_events%3Fpage=1&per_page=100 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fresource_state_events%3Fpage=1&per_page=100
deleted file mode 100644
index 33dce623cf..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%2F2%2Fresource_state_events%3Fpage=1&per_page=100
+++ /dev/null
@@ -1,26 +0,0 @@
-Cache-Control: max-age=0, private, must-revalidate
-X-Gitlab-Meta: {"correlation_id":"9564d6f62bbab2cb1f60ca66015e3840","version":"1"}
-X-Runtime: 0.091327
-X-Per-Page: 100
-X-Total: 0
-X-Total-Pages: 1
-Gitlab-Sv: api-gke-us-east1-d
-Cf-Cache-Status: MISS
-X-Prev-Page:
-Content-Length: 2
-Content-Security-Policy: default-src 'none'
-X-Content-Type-Options: nosniff
-X-Frame-Options: SAMEORIGIN
-X-Next-Page:
-Link: ; rel="first", ; rel="last"
-Vary: Origin, Accept-Encoding
-Set-Cookie: _cfuvid=JAECWgzRO1L40L3GhX4c7HSSpyYna2z1sybaZdKrJ18-1710504209104-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Strict-Transport-Security: max-age=31536000
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Lb: haproxy-main-11-lb-gprd
-Content-Type: application/json
-Etag: W/"4f53cda18c2baa0c0354bb5f9a3ecbe5"
-X-Page: 1
-Accept-Ranges: bytes
-
-[]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%3Fpage=1&per_page=2&sort=asc&state=all b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%3Fpage=1&per_page=2&sort=asc&state=all
deleted file mode 100644
index ff6128e8ac..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fissues%3Fpage=1&per_page=2&sort=asc&state=all
+++ /dev/null
@@ -1,24 +0,0 @@
-Content-Security-Policy: default-src 'none'
-Etag: W/"4c0531a3595f741f229f5a105e013b95"
-Link: ; rel="first", ; rel="last"
-X-Next-Page:
-Cf-Cache-Status: MISS
-Strict-Transport-Security: max-age=31536000
-X-Content-Type-Options: nosniff
-X-Total: 2
-X-Total-Pages: 1
-Gitlab-Lb: haproxy-main-16-lb-gprd
-Cache-Control: max-age=0, private, must-revalidate
-Vary: Origin, Accept-Encoding
-X-Runtime: 0.143514
-Gitlab-Sv: api-gke-us-east1-c
-X-Gitlab-Meta: {"correlation_id":"6e8b9d619f3148fd839ba0c5f6747df9","version":"1"}
-X-Page: 1
-Content-Type: application/json
-X-Per-Page: 2
-Referrer-Policy: strict-origin-when-cross-origin
-X-Frame-Options: SAMEORIGIN
-X-Prev-Page:
-Set-Cookie: _cfuvid=9pOTnEAVQzMgmNMabGvRXD3ad16MkUCZTAQQameWnO8-1710504206909-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-
-[{"id":27687675,"iid":1,"project_id":15578026,"title":"Please add an animated gif icon to the merge button","description":"I just want the merge button to hurt my eyes a little. :stuck_out_tongue_closed_eyes:","state":"closed","created_at":"2019-11-28T08:43:35.459Z","updated_at":"2019-11-28T08:46:23.304Z","closed_at":"2019-11-28T08:46:23.275Z","closed_by":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"labels":["bug","discussion"],"milestone":{"id":1082926,"iid":1,"project_id":15578026,"title":"1.0.0","description":"","state":"closed","created_at":"2019-11-28T08:42:30.301Z","updated_at":"2019-11-28T15:57:52.401Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/1"},"assignees":[],"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"type":"ISSUE","assignee":null,"user_notes_count":0,"merge_requests_count":0,"upvotes":1,"downvotes":0,"due_date":null,"confidential":false,"discussion_locked":null,"issue_type":"issue","web_url":"https://gitlab.com/gitea/test_repo/-/issues/1","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"task_completion_status":{"count":0,"completed_count":0},"blocking_issues_count":0,"has_tasks":true,"task_status":"0 of 0 checklist items completed","_links":{"self":"https://gitlab.com/api/v4/projects/15578026/issues/1","notes":"https://gitlab.com/api/v4/projects/15578026/issues/1/notes","award_emoji":"https://gitlab.com/api/v4/projects/15578026/issues/1/award_emoji","project":"https://gitlab.com/api/v4/projects/15578026","closed_as_duplicate_of":null},"references":{"short":"#1","relative":"#1","full":"gitea/test_repo#1"},"severity":"UNKNOWN","moved_to_id":null,"service_desk_reply_to":null},{"id":27687706,"iid":2,"project_id":15578026,"title":"Test issue","description":"This is test issue 2, do not touch!","state":"closed","created_at":"2019-11-28T08:44:46.277Z","updated_at":"2019-11-28T08:45:44.987Z","closed_at":"2019-11-28T08:45:44.959Z","closed_by":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"labels":["duplicate"],"milestone":{"id":1082927,"iid":2,"project_id":15578026,"title":"1.1.0","description":"","state":"active","created_at":"2019-11-28T08:42:44.575Z","updated_at":"2019-11-28T08:42:44.575Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/2"},"assignees":[],"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"type":"ISSUE","assignee":null,"user_notes_count":2,"merge_requests_count":0,"upvotes":1,"downvotes":1,"due_date":null,"confidential":false,"discussion_locked":null,"issue_type":"issue","web_url":"https://gitlab.com/gitea/test_repo/-/issues/2","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"task_completion_status":{"count":0,"completed_count":0},"blocking_issues_count":0,"has_tasks":true,"task_status":"0 of 0 checklist items completed","_links":{"self":"https://gitlab.com/api/v4/projects/15578026/issues/2","notes":"https://gitlab.com/api/v4/projects/15578026/issues/2/notes","award_emoji":"https://gitlab.com/api/v4/projects/15578026/issues/2/award_emoji","project":"https://gitlab.com/api/v4/projects/15578026","closed_as_duplicate_of":null},"references":{"short":"#2","relative":"#2","full":"gitea/test_repo#2"},"severity":"UNKNOWN","moved_to_id":null,"service_desk_reply_to":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Flabels%3Fpage=1&per_page=100 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Flabels%3Fpage=1&per_page=100
deleted file mode 100644
index 95924923d1..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Flabels%3Fpage=1&per_page=100
+++ /dev/null
@@ -1,24 +0,0 @@
-X-Per-Page: 100
-X-Prev-Page:
-X-Total: 9
-Content-Type: application/json
-X-Next-Page:
-X-Content-Type-Options: nosniff
-Gitlab-Lb: haproxy-main-56-lb-gprd
-Cf-Cache-Status: MISS
-Set-Cookie: _cfuvid=5K2rwnMRyftEWt3OXSN3FeV8T9nf3Cgb20WFj.p4hyw-1710504206334-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Cache-Control: max-age=0, private, must-revalidate
-X-Runtime: 0.424823
-Strict-Transport-Security: max-age=31536000
-Link: ; rel="first", ; rel="last"
-Content-Security-Policy: default-src 'none'
-Vary: Origin, Accept-Encoding
-X-Gitlab-Meta: {"correlation_id":"b02b63b76c2351a971670a8db9c57af9","version":"1"}
-X-Page: 1
-X-Total-Pages: 1
-Etag: W/"5a3fb9bc7b1018070943f4aa1353f8b6"
-X-Frame-Options: SAMEORIGIN
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Sv: api-gke-us-east1-d
-
-[{"id":12959095,"name":"bug","description":null,"description_html":"","text_color":"#FFFFFF","color":"#d9534f","subscribed":false,"priority":null,"is_project_label":true},{"id":12959097,"name":"confirmed","description":null,"description_html":"","text_color":"#FFFFFF","color":"#d9534f","subscribed":false,"priority":null,"is_project_label":true},{"id":12959096,"name":"critical","description":null,"description_html":"","text_color":"#FFFFFF","color":"#d9534f","subscribed":false,"priority":null,"is_project_label":true},{"id":12959100,"name":"discussion","description":null,"description_html":"","text_color":"#FFFFFF","color":"#428bca","subscribed":false,"priority":null,"is_project_label":true},{"id":12959098,"name":"documentation","description":null,"description_html":"","text_color":"#1F1E24","color":"#f0ad4e","subscribed":false,"priority":null,"is_project_label":true},{"id":12959554,"name":"duplicate","description":null,"description_html":"","text_color":"#FFFFFF","color":"#7F8C8D","subscribed":false,"priority":null,"is_project_label":true},{"id":12959102,"name":"enhancement","description":null,"description_html":"","text_color":"#FFFFFF","color":"#5cb85c","subscribed":false,"priority":null,"is_project_label":true},{"id":12959101,"name":"suggestion","description":null,"description_html":"","text_color":"#FFFFFF","color":"#428bca","subscribed":false,"priority":null,"is_project_label":true},{"id":12959099,"name":"support","description":null,"description_html":"","text_color":"#1F1E24","color":"#f0ad4e","subscribed":false,"priority":null,"is_project_label":true}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F1%2Fapprovals b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F1%2Fapprovals
deleted file mode 100644
index 6a16667f83..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F1%2Fapprovals
+++ /dev/null
@@ -1,17 +0,0 @@
-Gitlab-Sv: api-gke-us-east1-c
-Set-Cookie: _cfuvid=zeoNBfBKfrdVGUvp0nfh4oigIhB1U14XXmzniKufB0A-1710504211497-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Runtime: 0.137677
-Cache-Control: max-age=0, private, must-revalidate
-Vary: Origin, Accept-Encoding
-X-Frame-Options: SAMEORIGIN
-X-Gitlab-Meta: {"correlation_id":"8585fe858d5623c4d3d1b77cfcdad845","version":"1"}
-Content-Security-Policy: default-src 'none'
-Etag: W/"632b3d0f41fe1650d82b84feaa7b125d"
-Strict-Transport-Security: max-age=31536000
-Cf-Cache-Status: MISS
-Content-Type: application/json
-X-Content-Type-Options: nosniff
-Referrer-Policy: strict-origin-when-cross-origin
-Gitlab-Lb: haproxy-main-55-lb-gprd
-
-{"id":43486906,"iid":1,"project_id":15578026,"title":"Update README.md","description":"add warning to readme","state":"merged","created_at":"2019-11-28T08:54:41.034Z","updated_at":"2019-11-28T16:02:08.377Z","merge_status":"can_be_merged","approved":true,"approvals_required":0,"approvals_left":0,"require_password_to_approve":false,"approved_by":[{"user":{"id":527793,"username":"axifive","name":"Alexey Terentyev","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/b5eee878c9129969b55d221a823fd15e55aad8dc15d521f4170e3c93728e02b6?s=80\u0026d=identicon","web_url":"https://gitlab.com/axifive"}},{"user":{"id":4102996,"username":"zeripath","name":"zeripath","state":"active","locked":false,"avatar_url":"https://secure.gravatar.com/avatar/3bad2cdad37aa0bbb3ad276ce8f77e32a1a9567a7083f0866d8df8ed0e92e5b5?s=80\u0026d=identicon","web_url":"https://gitlab.com/zeripath"}}],"suggested_approvers":[],"approvers":[],"approver_groups":[],"user_has_approved":false,"user_can_approve":false,"approval_rules_left":[],"has_approval_rules":true,"merge_request_approvers_available":false,"multiple_approval_rules_available":false,"invalid_approvers_rules":[]}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2
deleted file mode 100644
index 8848af8e48..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2
+++ /dev/null
@@ -1,17 +0,0 @@
-Cache-Control: max-age=0, private, must-revalidate
-X-Content-Type-Options: nosniff
-Etag: W/"914149155d75f8d8f7ed2e5351f0fadb"
-Referrer-Policy: strict-origin-when-cross-origin
-Content-Security-Policy: default-src 'none'
-Vary: Origin, Accept-Encoding
-X-Runtime: 0.634688
-Cf-Cache-Status: MISS
-Set-Cookie: _cfuvid=Z._ut3jKk_GobWpwV3pdT8AP8FDBG3hXVJphHhFBiBg-1710504210170-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Content-Type: application/json
-X-Gitlab-Meta: {"correlation_id":"c36a4f0267a05143404246325892000a","version":"1"}
-Strict-Transport-Security: max-age=31536000
-Gitlab-Lb: haproxy-main-59-lb-gprd
-Gitlab-Sv: api-gke-us-east1-d
-X-Frame-Options: SAMEORIGIN
-
-{"id":43524600,"iid":2,"project_id":15578026,"title":"Test branch","description":"do not merge this PR","state":"opened","created_at":"2019-11-28T15:56:54.104Z","updated_at":"2020-04-19T19:24:21.108Z","merged_by":null,"merge_user":null,"merged_at":null,"closed_by":null,"closed_at":null,"target_branch":"master","source_branch":"feat/test","user_notes_count":0,"upvotes":1,"downvotes":0,"author":{"id":1241334,"username":"lafriks","name":"Lauris BH","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/1241334/avatar.png","web_url":"https://gitlab.com/lafriks"},"assignees":[],"assignee":null,"reviewers":[],"source_project_id":15578026,"target_project_id":15578026,"labels":["bug"],"draft":false,"work_in_progress":false,"milestone":{"id":1082926,"iid":1,"project_id":15578026,"title":"1.0.0","description":"","state":"closed","created_at":"2019-11-28T08:42:30.301Z","updated_at":"2019-11-28T15:57:52.401Z","due_date":null,"start_date":null,"expired":false,"web_url":"https://gitlab.com/gitea/test_repo/-/milestones/1"},"merge_when_pipeline_succeeds":false,"merge_status":"can_be_merged","detailed_merge_status":"mergeable","sha":"9f733b96b98a4175276edf6a2e1231489c3bdd23","merge_commit_sha":null,"squash_commit_sha":null,"discussion_locked":null,"should_remove_source_branch":null,"force_remove_source_branch":true,"prepared_at":"2019-11-28T15:56:54.104Z","reference":"!2","references":{"short":"!2","relative":"!2","full":"gitea/test_repo!2"},"web_url":"https://gitlab.com/gitea/test_repo/-/merge_requests/2","time_stats":{"time_estimate":0,"total_time_spent":0,"human_time_estimate":null,"human_total_time_spent":null},"squash":true,"squash_on_merge":true,"task_completion_status":{"count":0,"completed_count":0},"has_conflicts":false,"blocking_discussions_resolved":true,"approvals_before_merge":null,"subscribed":false,"changes_count":"1","latest_build_started_at":null,"latest_build_finished_at":null,"first_deployed_to_production_at":null,"pipeline":null,"head_pipeline":null,"diff_refs":{"base_sha":"c59c9b451acca9d106cc19d61d87afe3fbbb8b83","head_sha":"9f733b96b98a4175276edf6a2e1231489c3bdd23","start_sha":"c59c9b451acca9d106cc19d61d87afe3fbbb8b83"},"merge_error":null,"first_contribution":false,"user":{"can_merge":false}}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Fapprovals b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Fapprovals
deleted file mode 100644
index be119c18b7..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Fapprovals
+++ /dev/null
@@ -1,17 +0,0 @@
-Set-Cookie: _cfuvid=sImrE_lz4VAFrw_o2FHA_8y6kxUoFm4G31.BEqR9M_E-1710504211811-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Content-Type-Options: nosniff
-X-Frame-Options: SAMEORIGIN
-X-Gitlab-Meta: {"correlation_id":"cf4eeb7f9cb45f6d15ef0297231a3250","version":"1"}
-X-Runtime: 0.163465
-Content-Type: application/json
-Vary: Origin, Accept-Encoding
-Gitlab-Lb: haproxy-main-17-lb-gprd
-Gitlab-Sv: api-gke-us-east1-d
-Referrer-Policy: strict-origin-when-cross-origin
-Cf-Cache-Status: MISS
-Cache-Control: max-age=0, private, must-revalidate
-Content-Security-Policy: default-src 'none'
-Etag: W/"58109b687618e6b9e49ff812d5a911df"
-Strict-Transport-Security: max-age=31536000
-
-{"id":43524600,"iid":2,"project_id":15578026,"title":"Test branch","description":"do not merge this PR","state":"opened","created_at":"2019-11-28T15:56:54.104Z","updated_at":"2020-04-19T19:24:21.108Z","merge_status":"can_be_merged","approved":true,"approvals_required":0,"approvals_left":0,"require_password_to_approve":false,"approved_by":[{"user":{"id":4575606,"username":"real6543","name":"6543","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/4575606/avatar.png","web_url":"https://gitlab.com/real6543"}}],"suggested_approvers":[],"approvers":[],"approver_groups":[{"group":{"id":3181312,"web_url":"https://gitlab.com/groups/gitea","name":"gitea","path":"gitea","description":"Mirror of Gitea source code repositories","visibility":"public","share_with_group_lock":false,"require_two_factor_authentication":false,"two_factor_grace_period":48,"project_creation_level":"maintainer","auto_devops_enabled":null,"subgroup_creation_level":"owner","emails_disabled":false,"emails_enabled":true,"mentions_disabled":null,"lfs_enabled":true,"math_rendering_limits_enabled":true,"lock_math_rendering_limits_enabled":false,"default_branch_protection":2,"default_branch_protection_defaults":{"allowed_to_push":[{"access_level":30}],"allow_force_push":true,"allowed_to_merge":[{"access_level":30}]},"avatar_url":"https://gitlab.com/uploads/-/system/group/avatar/3181312/gitea.png","request_access_enabled":true,"full_name":"gitea","full_path":"gitea","created_at":"2018-07-04T16:32:10.176Z","parent_id":null,"organization_id":1,"shared_runners_setting":"enabled","ldap_cn":null,"ldap_access":null,"wiki_access_level":"enabled"}}],"user_has_approved":false,"user_can_approve":false,"approval_rules_left":[],"has_approval_rules":true,"merge_request_approvers_available":false,"multiple_approval_rules_available":false,"invalid_approvers_rules":[]}
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=1&per_page=1 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=1&per_page=1
deleted file mode 100644
index eb72d3fc54..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=1&per_page=1
+++ /dev/null
@@ -1,24 +0,0 @@
-Etag: W/"798718b23a2ec66b16cce20cb7155116"
-X-Gitlab-Meta: {"correlation_id":"64dce1b90fe8fbfda281a99e34d0905c","version":"1"}
-Link: ; rel="next", ; rel="first", ; rel="last"
-X-Frame-Options: SAMEORIGIN
-X-Runtime: 0.092139
-Content-Type: application/json
-X-Content-Type-Options: nosniff
-X-Prev-Page:
-Referrer-Policy: strict-origin-when-cross-origin
-X-Per-Page: 1
-X-Total: 2
-Strict-Transport-Security: max-age=31536000
-Content-Security-Policy: default-src 'none'
-Cache-Control: max-age=0, private, must-revalidate
-Vary: Origin, Accept-Encoding
-Gitlab-Lb: haproxy-main-30-lb-gprd
-Cf-Cache-Status: MISS
-Gitlab-Sv: api-gke-us-east1-b
-Set-Cookie: _cfuvid=vG12ThddZrDMG_flNdCfEfuN3Vma3YHPWrU1MJOBFhY-1710504210427-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-X-Next-Page: 2
-X-Page: 1
-X-Total-Pages: 2
-
-[{"id":5541414,"name":"thumbsup","user":{"id":4575606,"username":"real6543","name":"6543","state":"active","locked":false,"avatar_url":"https://gitlab.com/uploads/-/system/user/avatar/4575606/avatar.png","web_url":"https://gitlab.com/real6543"},"created_at":"2020-09-02T23:42:34.310Z","updated_at":"2020-09-02T23:42:34.310Z","awardable_id":43524600,"awardable_type":"MergeRequest","url":null}]
\ No newline at end of file
diff --git a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=2&per_page=1 b/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=2&per_page=1
deleted file mode 100644
index 63f7d02a17..0000000000
--- a/services/migrations/testdata/gitlab/full_download/GET_%2Fapi%2Fv4%2Fprojects%2F15578026%2Fmerge_requests%2F2%2Faward_emoji%3Fpage=2&per_page=1
+++ /dev/null
@@ -1,24 +0,0 @@
-X-Next-Page:
-Content-Type: application/json
-Vary: Origin, Accept-Encoding
-Cf-Cache-Status: MISS
-Content-Security-Policy: default-src 'none'
-X-Frame-Options: SAMEORIGIN
-X-Page: 2
-Strict-Transport-Security: max-age=31536000
-Set-Cookie: _cfuvid=VgzG7aSZyu0lycKl6YVe9GTRYeLa0XUB5lv3pROs3tk-1710504210672-0.0.1.1-604800000; path=/; domain=.gitlab.com; HttpOnly; Secure; SameSite=None
-Referrer-Policy: strict-origin-when-cross-origin
-Cache-Control: max-age=0, private, must-revalidate
-Etag: W/"e6776aaa57e6a81bf8a2d8823272cc70"
-X-Prev-Page: 1
-X-Runtime: 0.073747
-Link: ; rel="prev", ; rel="first",